chengjie 6 月之前
父节点
当前提交
4786df9270

文件差异内容过多而无法显示
+ 645 - 1502
package-lock.json


+ 0 - 1
package.json

@@ -35,7 +35,6 @@
35 35
     "moment": "^2.30.1",
36 36
     "multer": "^1.4.5-lts.1",
37 37
     "mysql2": "^3.14.1",
38
-    "request": "^2.88.2",
39 38
     "request-promise": "^4.2.6"
40 39
   },
41 40
   "devDependencies": {

+ 2 - 2
src/api/mps/mpsSchoolController.js

@@ -34,7 +34,7 @@ export async function GetMPSSchool(ctx) {
34 34
         const cacheKey = `GetMPSSchool?SchoolType1=${param.SchoolType1}&DistrictID=${param.DistrictID}&SelectType=${param.SelectType}&Key=${param.Key}&RowCount=${param.RowCount}&Usage=${param.Usage}`;
35 35
 
36 36
         // 尝试从缓存获取
37
-        let cachedData = await BufferMemoryClass.get({ KeyName: cacheKey });
37
+        let cachedData = await BufferMemoryClass.get(cacheKey);
38 38
         let result;
39 39
 
40 40
         if (!cachedData || cachedData.length === 0) {
@@ -167,7 +167,7 @@ export async function GetMPSSchoolInfo (ctx) {
167 167
 
168 168
     let info={};
169 169
 
170
-    let list = await BufferMemoryClass.get({KeyName:url});
170
+    let list = await BufferMemoryClass.get(url);
171 171
 
172 172
     if (process.env.NODE_ENV == 'development')
173 173
         list=[];

+ 5 - 5
src/api/mps/mpsScoreController.js

@@ -69,7 +69,7 @@ export async function GetMPSDistrictPersonNum(ctx) {
69 69
 
70 70
     const url = "GetMPSDistrictPersonNum?DistrictID=" + param.DistrictID;
71 71
 
72
-    let info = await BufferMemoryClass.get({ KeyName: url });
72
+    let info = await BufferMemoryClass.get(url);
73 73
 
74 74
     if (process.env.NODE_ENV == 'development')
75 75
         info = [];
@@ -126,10 +126,10 @@ export async function GetMPSCityPersonNum(ctx) {
126 126
 
127 127
     const url = "GetMPSCityPersonNum";
128 128
 
129
-    let info = await BufferMemoryClass.get({ KeyName: url });
129
+    let info = await BufferMemoryClass.get(url);
130 130
 
131
-    if (process.env.NODE_ENV == 'development')
132
-        info = [];
131
+    // if (process.env.NODE_ENV == 'development')
132
+    //     info = [];
133 133
 
134 134
     if (!info || info.length == 0) {
135 135
         const year2 = Number(param.Year) - 1;
@@ -184,7 +184,7 @@ export async function GetMPSScore(ctx) {
184 184
 
185 185
     var url="GetMPSScore?ScoreYear="+param.ScoreYear+"&ScoreType="+param.ScoreType+"&DistrictID="+param.DistrictID;
186 186
 
187
-    var list = await BufferMemoryClass.get({KeyName:url});
187
+    var list = await BufferMemoryClass.get(url);
188 188
 
189 189
     if (process.env.NODE_ENV == 'development')
190 190
         list=[];

+ 1 - 0
src/api/mps/routes.js

@@ -9,6 +9,7 @@ const router = new Router();
9 9
 // 页面路由
10 10
 router.get('/api/Ping',mpsCommonController.Ping);
11 11
 router.get('/',mpsCommonController.MPSDefault);
12
+router.get('/mgfsx',mpsCommonController.MPSDefault);
12 13
 router.get('/mps',mpsCommonController.WebMPSHtml);
13 14
 router.get('/mpserror',mpsCommonController.WebMPSErrorHtml);
14 15
 router.get('/mpsschool',mpsCommonController.WebMPSSchoolHtml);

+ 437 - 0
src/api/phonics/phonicsController.js

@@ -0,0 +1,437 @@
1
+import moment from 'moment';
2
+import dataUpdateStatus from '../../model/dataUpdateStatus.js';
3
+import phonics from '../../model/phonics.js';
4
+import config from '../../config/index.js';
5
+import _ from 'lodash';
6
+import axios from 'axios';
7
+import { getBufferMemory, setBufferMemory } from '../../util/bufferMemory.js';
8
+import { Encrypt, Decrypt } from '../../util/crypto/index.js';
9
+import { stringUtils } from '../../util/stringClass.js';
10
+import WXBizDataCrypt from '../../util/WXBizDataCrypt.js';
11
+
12
+export async function PhonicsLogin(ctx) {
13
+    let param = ctx.request.body;
14
+    if (param.param) {
15
+        const paramStr = Decrypt(param.param, config.urlSecrets.aes_key, config.urlSecrets.aes_iv);
16
+        //console.log("paramStr:"+paramStr);
17
+        param = JSON.parse(paramStr);
18
+    }
19
+    const code = param.Code;
20
+    //console.log("code:"+code);
21
+    const url = `https://api.weixin.qq.com/sns/jscode2session?appid=${config.wx.phonics_appid}&secret=${config.wx.phonics_appsecret}&js_code=${code}&grant_type=authorization_code`;
22
+
23
+    let result = await axios.get(url)
24
+        .then(res => {
25
+            const json = res.data;
26
+            //console.log("json:"+json);
27
+            if (json && json.openid) {
28
+                param.OpenID = json.openid;
29
+                param.sessionKey = json.session_key;
30
+                if (json.unionid)
31
+                    param.UnionID = json.unionid;
32
+                return {errcode: 10000};
33
+            }
34
+            else {
35
+                return json;
36
+            }
37
+        })
38
+        .catch(err => {
39
+            return {errcode: 101, errStr: err};
40
+        });
41
+
42
+    if (result.errcode == 10000) {
43
+        delete param.Code;
44
+        if (param.sessionKey && param.iv && param.encryptedData){
45
+            //console.log("param.sessionKey:"+param.sessionKey);
46
+            const pc = new WXBizDataCrypt(config.wx.phonics_appid, param.sessionKey);
47
+            const dataUnionID = pc.decryptData(param.encryptedData , param.iv);
48
+            //console.log(dataUnionID);
49
+            param.UnionID = dataUnionID.unionId;
50
+        }
51
+
52
+        delete param.sessionKey;
53
+        delete param.iv;
54
+        delete param.encryptedData;
55
+
56
+        //todo
57
+        //param.OpenID="o4UHq4gaNlHfdTWxgl3fTgC1mFsI";
58
+
59
+        let userList = await phonics.GetUsersInfo(param);
60
+        if (userList.length > 0) {
61
+            param.LastLoginTime = new Date();
62
+            const time1 = moment(userList[0].ProductServiceTime).format('YYYY-MM-DD HH:mm:ss');
63
+            const time3 = moment().format('YYYY-MM-DD HH:mm:ss');
64
+            if (time1 < time3)
65
+                param.IsMember = 0;
66
+
67
+            delete param.Introducer;
68
+            delete param.UserSource;
69
+            delete param.SourceID;
70
+            //console.log(param.NickName);
71
+            if (param.NickName == "陌生用户") {
72
+                delete param.NickName;
73
+                delete param.AvatarUrl;
74
+                delete param.Language;
75
+                delete param.Gender;
76
+                delete param.City;
77
+                delete param.Province;
78
+                delete param.Country;
79
+            }
80
+
81
+            await phonics.UpdateUsers(param);
82
+            userList = await phonics.GetUsersInfo(param);
83
+        }
84
+        else {
85
+            param.NickName = "陌生用户";
86
+            param.AvatarUrl = "../images/userface_default.png";
87
+            param.CreateTime = new Date();
88
+            param.LastLoginTime = param.CreateTime;
89
+            param.ProductServiceTime = param.CreateTime;
90
+            const inseredID = await phonics.AddUsers(param);
91
+            userList = await phonics.GetUsersInfo(param);
92
+        }
93
+
94
+        delete userList[0].OpenID;
95
+        delete userList[0].UnionID;
96
+
97
+        result = {errcode: 10000, result: userList[0]};
98
+    }
99
+
100
+    ctx.body = result;
101
+}
102
+
103
+//新增自然拼读记录
104
+export async function AddPhonicsRecord(ctx) {
105
+    const param = ctx.request.body;
106
+    const inseredID = await phonics.AddPhonicsRecord(param);
107
+
108
+    ctx.body = {errcode: 10000, result: inseredID};
109
+}
110
+
111
+//更新自然拼读记录
112
+export async function UpdatePhonicsRecord(ctx) {
113
+    const param = ctx.request.body;
114
+    if (param.Content) {
115
+        param.Content = param.Content.replace(",undefined", "");
116
+    }
117
+    await phonics.UpdatePhonicsRecord(param);
118
+    ctx.body = {errcode: 10000};
119
+}
120
+
121
+//得到用户记录
122
+export async function GetPhonicsRecordData(ctx) {
123
+    const param = {
124
+        UserID: ctx.query.UserID || 0,
125
+        Version: ctx.query.Version || "1.0.0",
126
+    };
127
+    if (param.UserID === "undefined")
128
+        param.UserID = 0;
129
+
130
+    const result = await phonics.GetPhonicsRecordData(param);
131
+
132
+    if (param.UserID > 0 && result && result.length > 0) {
133
+        const userList = await phonics.GetUsersInfoByUserID(param);
134
+
135
+        //是否是首日
136
+        const timeCreateTime = moment(userList[0].CreateTime).format('YYYYMMDD');
137
+        const timeToday = moment().format('YYYYMMDD');
138
+        result[0].IsFirstDay = timeCreateTime === timeToday;
139
+
140
+        //得到分享新增用户数
141
+        let productServiceTime = moment(userList[0].ProductServiceTime).format('YYYYMMDD');
142
+        if (productServiceTime === "20991231") {
143
+            result[0].NewUserNumber = 999999;
144
+        } else {
145
+            const newUserNumber = await phonics.GetNewUserByUserID(param);
146
+            if (newUserNumber) {
147
+                result[0].NewUserNumber = newUserNumber.length;
148
+                //console.log("userList[0].ActivityTime:"+userList[0].ActivityTime);
149
+
150
+                productServiceTime = moment(userList[0].ProductServiceTime).format('YYYYMMDD');
151
+                const currentTime = moment().format('YYYYMMDD');
152
+
153
+                //如果推荐用户数超过6个,就改为增加3个月
154
+                if (newUserNumber.length >= 6 && !userList[0].ActivityTime && productServiceTime >= currentTime) {
155
+                    const obj = {
156
+                        ActivityTime: moment().format('YYYY-MM-DD HH:mm:ss'),
157
+                        ProductServiceTime: moment(userList[0].ProductServiceTime).add(1, 'months').format('YYYY-MM-DD HH:mm:ss'),
158
+                        OpenID: userList[0].OpenID,
159
+                    };
160
+                    await phonics.UpdateUsers(obj);
161
+                    result[0].NewUserNumber = 999999;
162
+                }
163
+            }
164
+        }
165
+
166
+        result[0].IsMember = userList[0].IsMember;
167
+
168
+        if (productServiceTime < timeToday)
169
+            result[0].IsMember = 0;
170
+
171
+        const result2 = await phonics.GetPhonicsFinishedDataCount(param);
172
+
173
+        if (result2)
174
+            result[0].FinishedCount = result2[0].count;
175
+
176
+        const list2 = await phonics.GetPhonicsReviewList(param);
177
+        if (list2)
178
+            result[0].ReviewList = list2;
179
+
180
+        result[0].TestScoreMax = 0;
181
+        const list3 = await phonics.GetPhonicsTestScoreMax(param);
182
+        if (list3 && list3.length > 0)
183
+            result[0].TestScoreMax = list3[0].Score;
184
+
185
+        const param2 = {
186
+            ProgramID: 99,
187
+            Version: param.Version,
188
+        };
189
+        const result3 = await dataUpdateStatus.GetProductVersionList(param2);
190
+        if (result3) {
191
+            if ((param.Version === result3[0].Version && result3[0].IsShowPay <= 0)
192
+                || param.Version > result3[0].Version) {
193
+                result[0].IsShow = result3[0].IsShowPay;
194
+            } else {
195
+                result[0].IsShow = 1;
196
+            }
197
+
198
+            //针对iphone测试用户,永远是无支付状态
199
+            if (userList[0].Brand === 'iPhone' && userList[0].WXLanguage === 'en-US'
200
+                && userList[0].UserSource === '1001' && userList[0].IsPay === 0) {
201
+                result[0].IsShow = 0;
202
+            }
203
+        }
204
+
205
+        ctx.body = {"errcode": 10000, result: result[0]};
206
+    } else
207
+        ctx.body = {"errcode": 10000};
208
+}
209
+
210
+//得到文章列表
211
+export async function GetArticles(ctx) {
212
+    const param = {
213
+        IsAll: ctx.query.IsAll || 0,
214
+    };
215
+    const result = await phonics.GetArticles(param);
216
+    if (result && result.length > 0) {
217
+        for (let i = 0; i < result.length; i++) {
218
+            result[i].IsLocked = false;
219
+            if (i > 2)
220
+                result[i].IsLocked = true;
221
+        }
222
+        ctx.body = {"errcode": 10000, result: result};
223
+    }
224
+    else
225
+        ctx.body = {"errcode": 10000};
226
+}
227
+
228
+//得到文章信息
229
+export async function GetArticleInfo(ctx) {
230
+    const param = {
231
+        ID: ctx.query.ID || 0,
232
+        UserID: ctx.query.UserID || 0,
233
+    };
234
+    if (param.UserID === "undefined")
235
+        param.UserID = 0;
236
+
237
+    const result = await phonics.GetArticles(param);
238
+    if (result && result.length > 0) {
239
+        const info = result[0];
240
+        info.Content = stringUtils.ReplaceAllString(info.Content, "\r", " ");
241
+        info.Content = stringUtils.ReplaceAllString(info.Content, "\n", " ");
242
+        //info.Content = stringUtils.ReplaceAllString(info.Content,".\"",".\" ");
243
+        ctx.body = {"errcode": 10000, result: info};
244
+    }
245
+    else
246
+        ctx.body = {"errcode": 10000};
247
+}
248
+
249
+//新增或删除自然拼读完成结果
250
+export async function UpdatePhonicsFinished(ctx) {
251
+    const param = ctx.request.body;
252
+    if (param.Style === "undefined")
253
+        param.Style = "";
254
+    if (param.IsFinished) {
255
+        delete param.IsFinished;
256
+        if (param.UserID && param.Title) {
257
+            if (param.Category === "basic" || param.Category === "intermediate")
258
+                param.Category = "all";
259
+            await phonics.AddPhonicsFinished(param);
260
+        }
261
+    }
262
+    else {
263
+        delete param.IsFinished;
264
+        if (param.UserID) {
265
+            await phonics.DeletePhonicsFinished(param);
266
+        }
267
+    }
268
+    ctx.body = {errcode: 10000};
269
+}
270
+
271
+//得到用户完成记录
272
+export async function GetPhonicsFinishedData(ctx) {
273
+    const param = {
274
+        UserID: ctx.query.UserID || 0,
275
+        Category: ctx.query.Category || 0,
276
+    };
277
+    if (param.UserID === "undefined")
278
+        param.UserID = 0;
279
+
280
+    if (param.Category === "basic" || param.Category === "intermediate")
281
+        param.Category = "all";
282
+    const result = await phonics.GetPhonicsFinishedData(param);
283
+    if (result && result.length > 0)
284
+        ctx.body = {"errcode": 10000, result: result};
285
+    else
286
+        ctx.body = {"errcode": 10000};
287
+}
288
+
289
+//得到全部自然拼读数据
290
+export async function GetPhonicsAll(ctx) {
291
+    const param = {
292
+        UpdateTime: ctx.query.UpdateTime,
293
+    };
294
+
295
+    const updateTimeList = await dataUpdateStatus.GetDataUpdateStatus();
296
+    const updateTime = moment(updateTimeList[4].UpdateTime).format('YYYY.MM.DD HH:mm:ss');
297
+    //console.log(updateTime);
298
+    if (param.UpdateTime != updateTime) {
299
+        let result = getBufferMemory("GetPhonicsAll");
300
+        if (result == 0) {
301
+            //const arr = phonics.GetPhonicsAll();
302
+            //for (let i = 0; i < arr.length; i++) {
303
+            //    const item = arr[i];
304
+            //    item.Style=item.Soundmark;
305
+            //}
306
+
307
+            const arrTemp = await phonics.GetPhonicsAllSql();
308
+            const arr = [];
309
+            let temp;
310
+            const cards = [];
311
+            for (let i = 0; i < arrTemp.length; i++) {
312
+                const item = arrTemp[i];
313
+                if (i > 0 && ((temp.Title + temp.Soundmark) != (item.Title + item.Soundmark) || i == arrTemp.length - 1)) {
314
+                    const islocked = temp.IsLocked == 1;
315
+
316
+                    if (i == arrTemp.length - 1)
317
+                        cards.push(item.Word);
318
+
319
+                    const obj = {
320
+                        "Title": temp.Title,
321
+                        "Category": temp.Category,
322
+                        "Category2": temp.Category2,
323
+                        "Soundmark": temp.Soundmark,
324
+                        "Style": temp.Soundmark,
325
+                        "Example": temp.Example,
326
+                        "IsLocked": islocked,
327
+                        "Level": temp.Level,
328
+                        "Cards": cards,
329
+                    }
330
+                    arr.push(obj);
331
+                    cards.length = 0;
332
+                }
333
+                cards.push(item.Word);
334
+                temp = item;
335
+            }
336
+
337
+            result = JSON.stringify(arr);
338
+            result = Encrypt(result, config.urlSecrets.aes_key, config.urlSecrets.aes_iv);
339
+
340
+            setBufferMemory("GetPhonicsAll", result, config.BufferMemoryTimeHigh);
341
+            console.log("缓存");
342
+        }
343
+
344
+        const obj = {
345
+            List: result,
346
+            UpdateTime: updateTime
347
+        }
348
+
349
+        ctx.body = {"errcode": 10000, result: obj};
350
+    }
351
+    else {
352
+        ctx.body = {"errcode": 10000};
353
+    }
354
+}
355
+
356
+//新增自然拼读复习记录
357
+export async function UpdatePhonicsReview(ctx) {
358
+    const param = ctx.request.body;
359
+    if (param.Status === "add") {
360
+        delete param.Status;
361
+        if (param.UserID && param.Word) {
362
+            await phonics.AddPhonicsReview(param);
363
+        }
364
+    }
365
+    else if (param.Status === "delete") {
366
+        delete param.Status;
367
+        if (param.UserID && param.Word) {
368
+            await phonics.DeletePhonicsReview(param);
369
+        }
370
+    }
371
+
372
+    ctx.body = {errcode: 10000};
373
+}
374
+
375
+//得到用户完成记录
376
+export async function GetPhonicsReviewList(ctx) {
377
+    const param = {
378
+        UserID: ctx.query.UserID || 0,
379
+    };
380
+    if (param.UserID === "undefined")
381
+        param.UserID = 0;
382
+
383
+    const result = await phonics.GetPhonicsReviewList(param);
384
+    if (result && result.length > 0)
385
+        ctx.body = {"errcode": 10000, result: result};
386
+    else
387
+        ctx.body = {"errcode": 10000, result: []};
388
+}
389
+
390
+//新增自然拼读测试得分记录
391
+export async function AddPhonicsTestScore(ctx) {
392
+    const param = {
393
+        UserID: ctx.query.UserID || 0,
394
+        Score: ctx.query.Score,
395
+    };
396
+    if (param.UserID === "undefined")
397
+        param.UserID = 0;
398
+
399
+    let result = {
400
+        MaxScore: param.Score,
401
+        IsRecord: 1,
402
+    };
403
+
404
+    const inseredID = await phonics.AddPhonicsTestScore(param);
405
+    let param2;
406
+
407
+    const list = await phonics.GetPhonicsTestScoreMax(param);
408
+    if (list && list.length > 0) {
409
+        if (list[0].Score < Number(param.Score)) {
410
+            param2 = {
411
+                ID: list[0].ID,
412
+                IsMax: 0,
413
+            };
414
+            await phonics.UpdatePhonicsTestScore(param2);
415
+            param2 = {
416
+                ID: inseredID.insertId,
417
+                IsMax: 1,
418
+            }
419
+            await phonics.UpdatePhonicsTestScore(param2);
420
+        }
421
+        else {
422
+            result = {
423
+                MaxScore: list[0].Score,
424
+                IsRecord: 0,
425
+            }
426
+        }
427
+    }
428
+    else {
429
+        param2 = {
430
+            ID: inseredID.insertId,
431
+            IsMax: 1,
432
+        }
433
+        await phonics.UpdatePhonicsTestScore(param2);
434
+    }
435
+
436
+    ctx.body = {errcode: 10000, result: result};
437
+}

+ 20 - 0
src/api/phonics/routes.js

@@ -0,0 +1,20 @@
1
+import Router from 'koa-router';
2
+import * as phonics from './phonicsController.js';
3
+
4
+
5
+const router = new Router();
6
+//自然拼读
7
+router.post('/api/PhonicsLogin',phonics.PhonicsLogin);
8
+router.post('/api/AddPhonicsRecord',phonics.AddPhonicsRecord);
9
+router.post('/api/UpdatePhonicsRecord',phonics.UpdatePhonicsRecord);
10
+router.get('/api/GetPhonicsRecordData',phonics.GetPhonicsRecordData);
11
+router.get('/api/GetArticles',phonics.GetArticles);
12
+router.get('/api/GetArticleInfo',phonics.GetArticleInfo);
13
+router.post('/api/UpdatePhonicsFinished',phonics.UpdatePhonicsFinished);
14
+router.get('/api/GetPhonicsFinishedData',phonics.GetPhonicsFinishedData);
15
+router.get('/api/GetPhonicsAll',phonics.GetPhonicsAll);
16
+router.post('/api/UpdatePhonicsReview',phonics.UpdatePhonicsReview);
17
+router.get('/api/GetPhonicsReviewList',phonics.GetPhonicsReviewList);
18
+router.get('/api/AddPhonicsTestScore',phonics.AddPhonicsTestScore);
19
+
20
+export default router;

+ 5 - 0
src/app.js

@@ -5,10 +5,13 @@ import path from 'path';
5 5
 import { fileURLToPath } from 'url';
6 6
 import config from './config/index.js';
7 7
 import mpsRouter from './api/mps/routes.js';
8
+import phonicsRouter from './api/phonics/routes.js';
8 9
 import commonRouter from './api/common/routes.js';
9 10
 import { decryptUrlMiddle } from './util/crypto/index.js';
11
+import { globalState } from './util/globalState.js';
10 12
 import { stringUtils } from './util/stringClass.js';
11 13
 
14
+// 全局状态已移至globalState模块
12 15
 const __dirname = path.dirname(fileURLToPath(import.meta.url));
13 16
 
14 17
 const app = new Koa();
@@ -40,6 +43,8 @@ app.use(mpsRouter.routes());
40 43
 app.use(mpsRouter.allowedMethods());
41 44
 app.use(commonRouter.routes());
42 45
 app.use(commonRouter.allowedMethods());
46
+app.use(phonicsRouter.routes());
47
+app.use(phonicsRouter.allowedMethods());
43 48
 
44 49
 // 启动服务器
45 50
 app.listen(config.port, () => {

+ 0 - 1
src/config/prod.js

@@ -12,7 +12,6 @@ export default {
12 12
         aes_key: 'kylx365_chengjie',
13 13
         aes_iv: 'kylx365hongliren'
14 14
     },
15
-    port: process.env.PORT || 3030,
16 15
     fontsPathPingFang:"/usr/share/fonts/chinese/PingFang.ttc",
17 16
     fontsPathKaiti:"/usr/share/fonts/chinese/Kaiti.ttc",
18 17
     fontsPathSFUIDisplayBlack:"/usr/share/fonts/chinese/SF-UI-Display-Black.otf",

+ 2 - 2
src/model/BufferMemoryClass.js

@@ -56,10 +56,10 @@ class BufferMemoryClass {
56 56
      * @returns {Promise} 包含查询结果的Promise
57 57
      */
58 58
     static async get(keyName) {
59
-        const sql = "SELECT * FROM BufferMemory WHERE KeyName = ? ORDER BY ID DESC LIMIT 1";
59
+        const sql = "SELECT * FROM BufferMemory WHERE KeyName = ? ORDER BY ID DESC LIMIT 1;";
60 60
         try {
61 61
             const result = await query(sql, [keyName]);
62
-            return result[0]; // 返回单个记录而不是数组
62
+            return result; // 返回单个记录而不是数组
63 63
         } catch (error) {
64 64
             console.error('Get operation failed:', error);
65 65
             throw error;

文件差异内容过多而无法显示
+ 8854 - 0
src/model/phonics.js


+ 41 - 0
src/util/WXBizDataCrypt.js

@@ -0,0 +1,41 @@
1
+/**
2
+ * 微信小程序用户数据解密工具
3
+ */
4
+
5
+import crypto from 'crypto';
6
+
7
+class WXBizDataCrypt {
8
+  constructor(appId, sessionKey) {
9
+    this.appId = appId;
10
+    this.sessionKey = sessionKey;
11
+  }
12
+
13
+  decryptData(encryptedData, iv) {
14
+    // base64 decode
15
+    const sessionKey = Buffer.from(this.sessionKey, 'base64');
16
+    encryptedData = Buffer.from(encryptedData, 'base64');
17
+    iv = Buffer.from(iv, 'base64');
18
+
19
+    try {
20
+      // 解密
21
+      const decipher = crypto.createDecipheriv('aes-128-cbc', sessionKey, iv);
22
+      // 设置自动 padding 为 true,删除填充补位
23
+      decipher.setAutoPadding(true);
24
+      let decoded = decipher.update(encryptedData, 'binary', 'utf8');
25
+      decoded += decipher.final('utf8');
26
+      
27
+      decoded = JSON.parse(decoded);
28
+
29
+    } catch (err) {
30
+      throw new Error('Illegal Buffer');
31
+    }
32
+
33
+    if (decoded.watermark.appid !== this.appId) {
34
+      throw new Error('Illegal Buffer');
35
+    }
36
+
37
+    return decoded;
38
+  }
39
+}
40
+
41
+export default WXBizDataCrypt;

+ 3 - 2
src/util/bufferMemory.js

@@ -1,8 +1,9 @@
1 1
 import moment from 'moment';
2
+import { globalState } from './globalState.js';
2 3
 
3 4
 export const getBufferMemory = (key) => {
4 5
     //console.log("GetBufferMemory:"+key);
5
-    const value = htBufferMemory.getValue(key);
6
+    const value = globalState.getBufferMemory().getValue(key);
6 7
 
7 8
     if (value) {
8 9
         const a = moment(value.time);
@@ -25,7 +26,7 @@ export const setBufferMemory = (key, value, duration = 5) => {
25 26
         duration,
26 27
     };
27 28
 
28
-    htBufferMemory.add(key, obj);
29
+    globalState.getBufferMemory().add(key, obj);
29 30
 
30 31
     return value;
31 32
 }

+ 16 - 0
src/util/globalState.js

@@ -0,0 +1,16 @@
1
+import { stringUtils } from './stringClass.js';
2
+
3
+// 使用单例模式创建一个全局状态管理器
4
+class GlobalState {
5
+    constructor() {
6
+        this.htBufferMemory = new stringUtils.HashTable();
7
+    }
8
+
9
+    // 获取HashTable实例
10
+    getBufferMemory() {
11
+        return this.htBufferMemory;
12
+    }
13
+}
14
+
15
+// 导出单例实例
16
+export const globalState = new GlobalState();

+ 44 - 42
src/util/stringClass.js

@@ -310,78 +310,80 @@ export const stringUtils = {
310 310
         }
311 311
     },
312 312
     //哈希表的类
313
-    HashTable() {
314
-        let size = 0;
315
-        let entry = {};
313
+    HashTable: class HashTable {
314
+        constructor() {
315
+            this.size = 0;
316
+            this.entry = {};
317
+        }
316 318
 
317
-        this.add = (key, value) => {
319
+        add(key, value) {
318 320
             if (!this.containsKey(key)) {
319
-                size++;
321
+                this.size++;
320 322
             }
321
-            entry[key] = value;
322
-        };
323
+            this.entry[key] = value;
324
+        }
323 325
 
324
-        this.update = (key, value) => {
326
+        update(key, value) {
325 327
             if (this.containsKey(key)) {
326
-                entry[key] = value;
328
+                this.entry[key] = value;
327 329
             }
328
-        };
330
+        }
329 331
 
330
-        this.getValue = (key) => {
331
-            return this.containsKey(key) ? entry[key] : null;
332
-        };
332
+        getValue(key) {
333
+            return this.containsKey(key) ? this.entry[key] : null;
334
+        }
333 335
 
334
-        this.remove = (key) => {
335
-            if (this.containsKey(key) && (delete entry[key])) {
336
-                size--;
336
+        remove(key) {
337
+            if (this.containsKey(key) && (delete this.entry[key])) {
338
+                this.size--;
337 339
             }
338
-        };
340
+        }
339 341
 
340
-        this.containsKey = (key) => {
341
-            return (key in entry);
342
-        };
342
+        containsKey(key) {
343
+            return (key in this.entry);
344
+        }
343 345
 
344
-        this.containsValue = (value) => {
345
-            for (const prop in entry) {
346
-                if (entry[prop] == value) {
346
+        containsValue(value) {
347
+            for (const prop in this.entry) {
348
+                if (this.entry[prop] == value) {
347 349
                     return true;
348 350
                 }
349 351
             }
350 352
             return false;
351
-        };
353
+        }
352 354
 
353
-        this.getValues = () => {
355
+        getValues() {
354 356
             const values = [];
355
-            for (const prop in entry) {
356
-                values.push(entry[prop]);
357
+            for (const prop in this.entry) {
358
+                values.push(this.entry[prop]);
357 359
             }
358 360
             return values;
359
-        };
361
+        }
360 362
 
361
-        this.getKeys = () => {
363
+        getKeys() {
362 364
             const keys = [];
363
-            for (const prop in entry) {
365
+            for (const prop in this.entry) {
364 366
                 keys.push(prop);
365 367
             }
366 368
             return keys;
367
-        };
369
+        }
368 370
 
369
-        this.getKeysAndValues = () => {
371
+        getKeysAndValues() {
370 372
             const keysValues = [];
371
-            for (const prop in entry) {
372
-                keysValues.push(prop + "###" + entry[prop]);
373
+            for (const prop in this.entry) {
374
+                keysValues.push(prop + "###" + this.entry[prop]);
373 375
             }
374 376
             return keysValues;
375
-        };
377
+        }
376 378
 
377
-        this.getSize = () => {
378
-            return size;
379
-        };
379
+        getSize() {
380
+            return this.size;
381
+        }
380 382
 
381
-        this.clear = () => {
382
-            size = 0;
383
-            entry = {};
384
-        };
383
+        clear() {
384
+            this.size = 0;
385
+            this.entry = {};
386
+        }
385 387
     },
386 388
     //将金额转换为格式化字符串(保留两位小数)
387 389
     FormatMoney: (money) => {