├── mock
├── parser.js
├── data.js
└── achievements.html
├── pages
├── panel
│ ├── panel.wxss
│ ├── panel.wxml
│ └── panel.js
├── elective
│ ├── elective.wxml
│ └── elective.js
├── achievement
│ ├── achievement.json
│ ├── achievement.wxml
│ ├── achievement.wxss
│ └── achievement.js
├── index
│ ├── index.wxss
│ ├── index.wxml
│ └── index.js
└── introduce
│ ├── introduce.wxml
│ └── introduce.js
├── image
├── 1.png
├── 2.png
└── arrowright.png
├── package.json
├── app.json
├── config.js
├── utils
├── util.js
├── simulator.js
└── parser.js
├── .gitignore
├── app.js
├── LICENSE
├── README.md
└── app.wxss
/mock/parser.js:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/pages/panel/panel.wxss:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/image/1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zh-h/student-information-system-wechat-applet/HEAD/image/1.png
--------------------------------------------------------------------------------
/image/2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zh-h/student-information-system-wechat-applet/HEAD/image/2.png
--------------------------------------------------------------------------------
/image/arrowright.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zh-h/student-information-system-wechat-applet/HEAD/image/arrowright.png
--------------------------------------------------------------------------------
/pages/panel/panel.wxml:
--------------------------------------------------------------------------------
1 |
| ([\w\W]+?)<\/td>/ig 7 | var szxfPattern = /(.+?)<\/font><\/span>/ 8 | var pjxfjdPattern = /(.+?)<\/font><\/span>/ 9 | var zxfjdPattern = /(.+?)<\/font>/ 10 | 11 | // ajax 访问图片/二进制 12 | var test = function (url, callback) { 13 | var xhr = new XMLHttpRequest() 14 | xhr.responseType = 'blob' 15 | xhr.onload = function () { 16 | var reader = new FileReader() 17 | var headers = xhr.getAllResponseHeaders() 18 | reader.onloadend = function () { 19 | callback(reader.result, headers) 20 | } 21 | reader.readAsDataURL(xhr.response) 22 | } 23 | xhr.open('GET', url) 24 | xhr.send() 25 | } 26 | 27 | var paseAchievement = function (html) { 28 | // match values 29 | var achievement = [] 30 | 31 | // match tables 32 | var tableMatchers = html.match(tablePattern) 33 | var table1 = tableMatchers[2] 34 | var trMatchers1 = table1.match(trPattern) 35 | // match table grids 36 | for (var i in trMatchers1) { 37 | var tr = trMatchers1[i] 38 | var tdMatchers = tr.match(tdPatterb) 39 | var row = [] 40 | for (var j in tdMatchers) { 41 | var value = tdMatchers[j].replace(/( | )/, '').replace(/(<\/td>)/, '')
42 | if (value == ' ')
43 | value = ''
44 | row.push(value)
45 | }
46 | achievement.push(row)
47 | }
48 |
49 | return achievement
50 | }
51 |
52 | var paseViewState = function (html) {
53 | var viewState = ''
54 | var viewStateMatcher = html.match(viewStatePattern)
55 | if (viewStateMatcher != null)
56 | viewState = viewStateMatcher[1]
57 | return viewState
58 | }
59 |
60 | module.exports = {
61 | 'test': test,
62 | 'paseAchievement': paseAchievement,
63 | 'paseViewState': paseViewState
64 | }
65 |
--------------------------------------------------------------------------------
/pages/index/index.js:
--------------------------------------------------------------------------------
1 | var config = require('../../config.js')
2 | var mockData = require('../../mock/data.js')
3 | var simulator = require('../../utils/simulator.js')
4 |
5 | var inputs = {}
6 |
7 | // 获取应用实例
8 | var app = getApp()
9 | Page({
10 | data: {
11 | loadingHidden: true,
12 | modalHidden: true,
13 | modalContent: '',
14 | inputs: {}
15 | },
16 |
17 | tapLoading: function () {
18 | this.setData({
19 | loadingHidden: true
20 | })
21 | },
22 |
23 | loading: function () {
24 | this.setData({
25 | loadingHidden: false
26 | })
27 | },
28 |
29 | unloading: function () {
30 | this.setData({
31 | loadingHidden: true
32 | })
33 | },
34 | inputChange: function (e) {
35 | inputs[e.currentTarget.id] = e.detail.value
36 | },
37 |
38 | formSubmit: function () {
39 | var page = this
40 | if (inputs['username'] == null || inputs['username'] == '') {
41 | page.showModal('请输入学号')
42 | return
43 | }
44 | if (inputs['password'] == null || inputs['password'] == '') {
45 | page.showModal('请输入密码')
46 | return
47 | }
48 | page.loading()
49 | // 异步请求不能
50 | simulator.login(inputs['username'], inputs['password'])
51 | simulator.getAchievement(function (data) {
52 | console.log(data)
53 | wx.setStorageSync('username', inputs['username'])
54 | wx.setStorageSync('password', inputs['password'])
55 |
56 | page.unloading()
57 | wx.hideNavigationBarLoading()
58 |
59 | wx.navigateTo({
60 | // 必须要序列化成字符串,URL编码自动完成
61 | url: '/pages/achievement/achievement?data=' + JSON.stringify(data) + '&username=' + inputs['username']
62 | })
63 | }, function (error) {
64 | console.log(error)
65 |
66 | page.unloading()
67 | page.showModal(error)
68 | })
69 | },
70 |
71 | formReset: function () {
72 | inputs = {}
73 | wx.setStorageSync('username', '')
74 | wx.setStorageSync('password', '')
75 | },
76 |
77 | modalCancel: function () {
78 | this.setData({
79 | modalHidden: true
80 | })
81 | },
82 |
83 | modalConfirm: function () {
84 | this.setData({
85 | modalHidden: true
86 | })
87 | },
88 |
89 | showModal: function (msg) {
90 | this.setData({
91 | modalHidden: false,
92 | modalContent: msg
93 | })
94 | },
95 |
96 | onLoad: function () {
97 | // 调用应用实例的方法获取全局数据
98 | var that = this
99 | inputs['username'] = wx.getStorageSync('username')
100 | inputs['password'] = wx.getStorageSync('password') // 这里没有加密安全性较低
101 | this.setData({
102 | inputs: inputs
103 | })
104 | },
105 |
106 | switchChange: function (e) {
107 | inputs[e.currentTarget.id] = e.detail.value
108 | },
109 |
110 | tapnav:function (){
111 | wx.navigateTo({
112 | url:'/pages/introduce/introduce'
113 | })
114 | }
115 | })
116 |
--------------------------------------------------------------------------------
/pages/achievement/achievement.js:
--------------------------------------------------------------------------------
1 | var mockData = require('../../mock/data.js')
2 |
3 | var data = {}
4 |
5 | Page({
6 | data: {
7 | username: 0,
8 | list: [
9 | {
10 | id: 1,
11 | years: '2016-2017',
12 | term: 1,
13 | open: false,
14 | table: []
15 | }
16 | ]
17 | },
18 |
19 | widgetsToggle: function (e) {
20 | var id = e.currentTarget.id
21 | var list = this.data.list
22 | for (var i = 0, len = list.length; i < len; ++i) {
23 | if (list[i].id == id) {
24 | list[i].open = !list[i].open
25 | } else {
26 | // list[i].open = false
27 | }
28 | }
29 | this.setData({
30 | list: list
31 | })
32 | },
33 |
34 | setCurrentTermShow: function () {
35 | var today = new Date(); // 获得当前日期
36 | var year = today.getFullYear(); // 获得年份
37 | var month = today.getMonth() + 1; // 此方法获得的月份是从0---11,所以要加1才是当前月份
38 | var day = today.getDate(); // 获得当前日期
39 | var list = this.data.list
40 | for (var i = 0, len = list.length; i < len; ++i) {
41 | if (list[i].years.indexOf(year) != -1) {
42 | if (month >= 6 && list[i].term == 2) {
43 | list[i].open = true // 上半年看第一学期,下半年第二学期成绩打开
44 | }else if (month < 6 && list[i].term == 1) {
45 | list[i].open = true
46 | }
47 | }
48 | }
49 | this.setData({
50 | list: list
51 | })
52 | },
53 |
54 | fillData: function (options) {
55 | data = JSON.parse(options['data'])
56 | data.shift() // 去掉表头
57 | var list = []
58 | var tempDiffVal = '' // 按照年份和学期分组标记
59 | var tempItem = {}
60 | for (var i = 0;i < data.length;i++) {
61 | var dataRow = data[i]
62 | var years = dataRow[0]
63 | var term = dataRow[1]
64 | diffVal = years + term
65 | if (diffVal != tempDiffVal) { // 如果下一行变了就创建新的栏目
66 | var item = {
67 | id: list.length + 1,
68 | years: years,
69 | term: term,
70 | open: false,
71 | table: []
72 | }
73 | tempItem = item
74 | list.push(item) // 把新的栏目放到列表
75 | tempDiffVal = diffVal
76 | }
77 |
78 | var tableRow = []
79 | tableRow[0] = dataRow[2] // 课程
80 | tableRow[1] = dataRow[6] // 成绩
81 | tableRow[2] = dataRow[11] // 绩点
82 | tempItem.table.push(tableRow)
83 | }
84 | this.setData({
85 | list: list,
86 | username: options.username
87 | })
88 | },
89 |
90 | onLoad: function (options) {
91 | this.fillData(options)
92 | this.setCurrentTermShow()
93 | },
94 |
95 | onShow:function(){
96 | wx.hideNavigationBarLoading()
97 | },
98 |
99 | // https://mp.weixin.qq.com/debug/wxadoc/dev/framework/app-service/page.html?t=1475052056377#生命周期函数
100 | onReady: function () {
101 | var page = this
102 | wx.setNavigationBarTitle({
103 | title: '学号 ' + page.data.username + ' 的成绩'
104 | }
105 | )
106 | }
107 | })
108 |
--------------------------------------------------------------------------------
/app.wxss:
--------------------------------------------------------------------------------
1 | page {
2 | background-color: #fbf9fe;
3 | height: 100%;
4 | }
5 | .container {
6 | display: flex;
7 | flex-direction: column;
8 | min-height: 100%;
9 | justify-content: space-between;
10 | }
11 | .page-header {
12 | display: flex;
13 | font-size: 32rpx;
14 | color: #aaa;
15 | margin-top: 50rpx;
16 | flex-direction: column;
17 | align-items: center;
18 | }
19 | .page-header-text {
20 | padding: 20rpx 40rpx;
21 | }
22 | .page-header-line {
23 | width: 150rpx;
24 | height: 1px;
25 | border-bottom: 1px solid #ccc;
26 | }
27 |
28 | .page-body {
29 | width: 100%;
30 | display: flex;
31 | flex-direction: column;
32 | align-items: center;
33 | flex-grow: 1;
34 | overflow-x: hidden;
35 | }
36 | .page-body-wrapper {
37 | margin-top: 100rpx;
38 | display: flex;
39 | flex-direction: column;
40 | align-items: center;
41 | width: 100%;
42 | }
43 | .page-body-wrapper form {
44 | width: 100%;
45 | }
46 | .page-body-wording {
47 | text-align: center;
48 | padding: 200rpx 100rpx;
49 | }
50 | .page-body-info {
51 | display: flex;
52 | flex-direction: column;
53 | align-items: center;
54 | background-color: #fff;
55 | margin-bottom: 50rpx;
56 | width: 100%;
57 | padding: 50rpx 0 150rpx 0;
58 | }
59 | .page-body-title {
60 | margin-bottom: 100rpx;
61 | font-size: 32rpx;
62 | }
63 | .page-body-text {
64 | font-size: 30rpx;
65 | line-height: 26px;
66 | color: #ccc;
67 | }
68 | .page-body-text-small {
69 | font-size: 24rpx;
70 | color: #000;
71 | margin-bottom: 100rpx;
72 | }
73 | .page-body-form {
74 | width: 100%;
75 | background-color: #fff;
76 | display: flex;
77 | flex-direction: column;
78 | width: 100%;
79 | border: 1px solid #eee;
80 | }
81 | .page-body-form-item {
82 | display: flex;
83 | align-items: center;
84 | margin-left: 30rpx;
85 | border-bottom: 1px solid #eee;
86 | height: 88rpx;
87 | font-size: 34rpx;
88 | }
89 | .page-body-form-key {
90 | width: 180rpx;
91 | color: #000;
92 | }
93 | .page-body-form-value {
94 | flex-grow: 1;
95 | }
96 | .page-body-form-value .input-placeholder {
97 | color: #b2b2b2;
98 | }
99 |
100 | .page-body-form-picker {
101 | display: flex;
102 | justify-content: space-between;
103 | height: 100rpx;
104 | align-items: center;
105 | font-size: 36rpx;
106 | margin-left: 20rpx;
107 | padding-right: 20rpx;
108 | border-bottom: 1px solid #eee;
109 | }
110 | .page-body-form-picker-value {
111 | color: #ccc;
112 | }
113 |
114 | .page-body-buttons {
115 | width: 100%;
116 | }
117 | .page-body-button {
118 | margin: 25rpx;
119 | }
120 | .page-body-button image {
121 | width: 150rpx;
122 | height: 150rpx;
123 | }
124 | .page-footer {
125 | text-align: center;
126 | color: #1aad19;
127 | font-size: 28rpx;
128 | padding: 6px;
129 | bottom: 0px;
130 | position: fixed;
131 | }
132 |
133 | .green{
134 | color: #09BB07;
135 | }
136 | .red{
137 | color: #F76260;
138 | }
139 | .blue{
140 | color: #10AEFF;
141 | }
142 | .yellow{
143 | color: #FFBE00;
144 | }
145 | .gray{
146 | color: #C9C9C9;
147 | }
148 |
149 | .strong{
150 | font-weight: bold;
151 | }
152 |
153 | .bc_green{
154 | background-color: #09BB07;
155 | }
156 | .bc_red{
157 | background-color: #F76260;
158 | }
159 | .bc_blue{
160 | background-color: #10AEFF;
161 | }
162 | .bc_yellow{
163 | background-color: #FFBE00;
164 | }
165 | .bc_gray{
166 | background-color: #C9C9C9;
167 | }
168 |
169 | .tc{
170 | text-align: center;
171 | }
172 |
173 | .page input,checkbox{
174 | padding: 20rpx 30rpx;
175 | background-color: #fff;
176 | }
177 | checkbox, radio{
178 | margin-right: 10px;
179 | }
180 |
181 | .btn-area{
182 | padding: 0 30px;
183 | }
184 | .btn-area button{
185 | margin-top: 20rpx;
186 | margin-bottom: 20rpx;
187 | }
188 |
189 | .page {
190 | min-height: 100%;
191 | flex: 1;
192 | background-color: #FBF9FE;
193 | font-size: 32rpx;
194 | font-family: -apple-system-font,Helvetica Neue,Helvetica,sans-serif;
195 | overflow: hidden;
196 | }
197 | .page__hd{
198 | padding: 50rpx 50rpx 50rpx 50rpx;
199 | text-align: center;
200 | }
201 | .page__title{
202 | display: inline-block;
203 | padding: 20rpx 40rpx;
204 | font-size: 32rpx;
205 | color: #AAAAAA;
206 | border-bottom: 1px solid #CCCCCC;
207 | }
208 | .page__info{
209 | display: inline-block;
210 | font-size: 38rpx;
211 | color: #AAAAAA;
212 | }
213 | .page__desc{
214 | display: none;
215 | margin-top: 20rpx;
216 | font-size: 26rpx;
217 | color: #BBBBBB;
218 | }
219 |
220 | .section{
221 | margin-bottom: 80rpx;
222 | }
223 | .section_gap{
224 | padding: 0 30rpx;
225 | }
226 | .section__title{
227 | margin-bottom: 16rpx;
228 | padding-left: 30rpx;
229 | padding-right: 30rpx;
230 | }
231 | .section_gap .section__title{
232 | padding-left: 0;
233 | padding-right: 0;
234 | }
235 |
236 | .shading{
237 | background-color: #eee;
238 | background-image: -moz-linear-gradient(45deg,#fff 25%, transparent 25%, transparent 50%,#fff 50%,#fff 75%, transparent 75%, transparent);
239 | background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(25%,rgba(255,255,255,0.2)),color-stop(25%,transparent),color-stop(50%,transparent),color-stop(50%,rgba(255,255,255,0.2)),color-stop(75%,rgba(255,255,255,0.2)),color-stop(75%,transparent));
240 | background-size: 16px 16px;
241 |
242 | }
243 |
--------------------------------------------------------------------------------
/mock/achievements.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | |