chengjie 6 kuukautta sitten
vanhempi
commit
b94d606a73

+ 3 - 3
src/api/common/commonController.js

@@ -8,7 +8,7 @@ import gm from 'gm';
8 8
 import axios from 'axios';
9 9
 import COS from 'cos-nodejs-sdk-v5';
10 10
 import { uploadSingle } from '../../middleware/upload.js';
11
-import { globalState } from '../../util/globalState.js';
11
+import { globalCache } from '../../util/GlobalCache.js';
12 12
 
13 13
 const imageMagick = gm.subClass({ imageMagick: true });
14 14
 
@@ -228,14 +228,14 @@ export async function GetBaiduToken (ctx) {
228 228
 
229 229
     let result = 0;
230 230
     if (resultLogin.errcode === 10000) {
231
-        result = globalState.getBufferMemory('BaiduToken');
231
+        result = globalCache.get('BaiduToken');
232 232
         if (result === 0) {
233 233
             const baiduUrl = 'https://openapi.baidu.com/oauth/2.0/token?grant_type=client_credentials&client_id=9r1Idx1mgMONvElxU3KGE5Gi&client_secret=f4f606f1a5c0b4eaf800e1e046802d81';
234 234
             result = await axios.get(baiduUrl)
235 235
                 .then(response => {
236 236
                     const json = response.data;
237 237
                     if (json.access_token) {
238
-                        globalState.SetBufferMemory('BaiduToken', json.access_token, config.BufferMemoryTimeHigh);
238
+                        globalCache.set('BaiduToken', json.access_token, config.BufferMemoryTimeHigh);
239 239
                         return json.access_token;
240 240
                     }
241 241
                     return 0;

+ 6 - 5
src/api/phonics/phonicsController.js

@@ -4,10 +4,11 @@ import phonics from '../../model/phonics.js';
4 4
 import config from '../../config/index.js';
5 5
 import _ from 'lodash';
6 6
 import axios from 'axios';
7
-import { getBufferMemory, setBufferMemory } from '../../util/bufferMemory.js';
8 7
 import { Encrypt, Decrypt } from '../../util/crypto/index.js';
9 8
 import { stringUtils } from '../../util/stringClass.js';
10 9
 import WXBizDataCrypt from '../../util/WXBizDataCrypt.js';
10
+import { globalCache } from '../../util/GlobalCache.js';
11
+
11 12
 
12 13
 export async function PhonicsLogin(ctx) {
13 14
     let param = ctx.request.body;
@@ -296,7 +297,7 @@ export async function GetPhonicsAll(ctx) {
296 297
     const updateTime = moment(updateTimeList[4].UpdateTime).format('YYYY.MM.DD HH:mm:ss');
297 298
     //console.log(updateTime);
298 299
     if (param.UpdateTime != updateTime) {
299
-        let result = getBufferMemory("GetPhonicsAll");
300
+        let result = globalCache.get("GetPhonicsAll");
300 301
         if (result == 0) {
301 302
             //const arr = phonics.GetPhonicsAll();
302 303
             //for (let i = 0; i < arr.length; i++) {
@@ -307,7 +308,7 @@ export async function GetPhonicsAll(ctx) {
307 308
             const arrTemp = await phonics.GetPhonicsAllSql();
308 309
             const arr = [];
309 310
             let temp;
310
-            const cards = [];
311
+            let cards = [];
311 312
             for (let i = 0; i < arrTemp.length; i++) {
312 313
                 const item = arrTemp[i];
313 314
                 if (i > 0 && ((temp.Title + temp.Soundmark) != (item.Title + item.Soundmark) || i == arrTemp.length - 1)) {
@@ -328,7 +329,7 @@ export async function GetPhonicsAll(ctx) {
328 329
                         "Cards": cards,
329 330
                     }
330 331
                     arr.push(obj);
331
-                    cards.length = 0;
332
+                    cards = [];
332 333
                 }
333 334
                 cards.push(item.Word);
334 335
                 temp = item;
@@ -337,7 +338,7 @@ export async function GetPhonicsAll(ctx) {
337 338
             result = JSON.stringify(arr);
338 339
             result = Encrypt(result, config.urlSecrets.aes_key, config.urlSecrets.aes_iv);
339 340
 
340
-            setBufferMemory("GetPhonicsAll", result, config.BufferMemoryTimeHigh);
341
+            globalCache.set("GetPhonicsAll", result, config.BufferMemoryTimeHigh);
341 342
             console.log("缓存");
342 343
         }
343 344
 

+ 3 - 6
src/app.js

@@ -8,10 +8,8 @@ import mpsRouter from './api/mps/routes.js';
8 8
 import phonicsRouter from './api/phonics/routes.js';
9 9
 import commonRouter from './api/common/routes.js';
10 10
 import { decryptUrlMiddle } from './util/crypto/index.js';
11
-import { globalState } from './util/globalState.js';
12 11
 import { stringUtils } from './util/stringClass.js';
13 12
 
14
-// 全局状态已移至globalState模块
15 13
 const __dirname = path.dirname(fileURLToPath(import.meta.url));
16 14
 
17 15
 const app = new Koa();
@@ -33,16 +31,15 @@ app.use(async (ctx, next) => {
33 31
     }
34 32
 });
35 33
 
36
-// 注意:multer 中间件应该在具体的路由中使用,而不是全局使用
37
-// 例如:router.post('/upload', upload.single('file'), async (ctx) => { ... })
38 34
 
39 35
 app.use(decryptUrlMiddle());
40 36
 
41 37
 // 注册路由
42
-app.use(mpsRouter.routes());
43
-app.use(mpsRouter.allowedMethods());
38
+
44 39
 app.use(commonRouter.routes());
45 40
 app.use(commonRouter.allowedMethods());
41
+app.use(mpsRouter.routes());
42
+app.use(mpsRouter.allowedMethods());
46 43
 app.use(phonicsRouter.routes());
47 44
 app.use(phonicsRouter.allowedMethods());
48 45
 

+ 122 - 0
src/util/GlobalCache.js

@@ -0,0 +1,122 @@
1
+import EventEmitter from 'events';
2
+
3
+/**
4
+ * 全局缓存类
5
+ * 使用单例模式实现的带过期时间的键值对存储
6
+ */
7
+class GlobalCache extends EventEmitter {
8
+    constructor() {
9
+        super();
10
+        if (GlobalCache.instance) {
11
+            return GlobalCache.instance;
12
+        }
13
+        
14
+        // 存储数据的 Map
15
+        this.cache = new Map();
16
+        // 存储定时器的 Map
17
+        this.timers = new Map();
18
+        
19
+        GlobalCache.instance = this;
20
+    }
21
+
22
+    /**
23
+     * 设置缓存值
24
+     * @param {string} key - 键
25
+     * @param {*} value - 值
26
+     * @param {number} [expireTime=0] - 过期时间(秒),0表示永不过期
27
+     * @returns {*} 设置的值
28
+     */
29
+    set(key, value, expireTime = 0) {
30
+        if (typeof key !== 'string') {
31
+            throw new Error('Key must be a string');
32
+        }
33
+
34
+        // 如果该key已存在,清除之前的定时器
35
+        if (this.timers.has(key)) {
36
+            clearTimeout(this.timers.get(key));
37
+            this.timers.delete(key);
38
+        }
39
+
40
+        // 存储值
41
+        this.cache.set(key, value);
42
+
43
+        // 如果设置了过期时间
44
+        if (expireTime > 0) {
45
+            const timer = setTimeout(() => {
46
+                this.delete(key);
47
+                this.emit('expired', key); // 触发过期事件
48
+            }, expireTime * 1000);
49
+
50
+            // 存储定时器
51
+            this.timers.set(key, timer);
52
+        }
53
+
54
+        return value;
55
+    }
56
+
57
+    /**
58
+     * 获取缓存值
59
+     * @param {string} key - 键
60
+     * @returns {*} 值,如果不存在或已过期返回null
61
+     */
62
+    get(key) {
63
+        if (typeof key !== 'string') {
64
+            throw new Error('Key must be a string');
65
+        }
66
+
67
+        return this.cache.has(key) ? this.cache.get(key) : 0;
68
+    }
69
+
70
+    /**
71
+     * 删除缓存值
72
+     * @param {string} key - 键
73
+     * @returns {boolean} 是否成功删除
74
+     */
75
+    delete(key) {
76
+        if (this.timers.has(key)) {
77
+            clearTimeout(this.timers.get(key));
78
+            this.timers.delete(key);
79
+        }
80
+        return this.cache.delete(key);
81
+    }
82
+
83
+    /**
84
+     * 清除所有缓存
85
+     */
86
+    clear() {
87
+        // 清除所有定时器
88
+        for (const timer of this.timers.values()) {
89
+            clearTimeout(timer);
90
+        }
91
+        this.timers.clear();
92
+        this.cache.clear();
93
+    }
94
+
95
+    /**
96
+     * 获取所有缓存的键
97
+     * @returns {string[]} 键数组
98
+     */
99
+    keys() {
100
+        return Array.from(this.cache.keys());
101
+    }
102
+
103
+    /**
104
+     * 获取缓存数量
105
+     * @returns {number} 缓存数量
106
+     */
107
+    size() {
108
+        return this.cache.size;
109
+    }
110
+
111
+    /**
112
+     * 检查键是否存在
113
+     * @param {string} key - 键
114
+     * @returns {boolean} 是否存在
115
+     */
116
+    has(key) {
117
+        return this.cache.has(key);
118
+    }
119
+}
120
+
121
+// 导出单例实例
122
+export const globalCache = new GlobalCache();

+ 0 - 32
src/util/bufferMemory.js

@@ -1,32 +0,0 @@
1
-import moment from 'moment';
2
-import { globalState } from './globalState.js';
3
-
4
-export const getBufferMemory = (key) => {
5
-    //console.log("GetBufferMemory:"+key);
6
-    const value = globalState.getBufferMemory().getValue(key);
7
-
8
-    if (value) {
9
-        const a = moment(value.time);
10
-        const b = moment();
11
-        const interval = b.diff(a, 'seconds');
12
-        //console.log(key+":"+interval);
13
-        if (interval < value.duration) {
14
-            return value.value;
15
-        }
16
-        return 0;
17
-    }
18
-    return 0;
19
-};
20
-
21
-export const setBufferMemory = (key, value, duration = 5) => {
22
-    //console.log("SetBufferMemory:"+key);
23
-    const obj = {
24
-        time: new Date(),
25
-        value,
26
-        duration,
27
-    };
28
-
29
-    globalState.getBufferMemory().add(key, obj);
30
-
31
-    return value;
32
-}

+ 0 - 26
src/util/globalState.js

@@ -1,26 +0,0 @@
1
-import { stringUtils } from './stringClass.js';
2
-
3
-// 使用单例模式创建一个全局状态管理器
4
-class GlobalState {
5
-    constructor() {
6
-        this.htBufferMemory = new stringUtils.HashTable();
7
-    }
8
-
9
-    // 获取指定key的值
10
-    getBufferMemory(key) {
11
-        return this.htBufferMemory.getValue(key) || 0;
12
-    }
13
-
14
-    // 设置指定key的值,可选过期时间
15
-    SetBufferMemory(key, value, expireTime = null) {
16
-        this.htBufferMemory.add(key, value);
17
-        if (expireTime) {
18
-            setTimeout(() => {
19
-                this.htBufferMemory.remove(key);
20
-            }, expireTime);
21
-        }
22
-    }
23
-}
24
-
25
-// 导出单例实例
26
-export const globalState = new GlobalState();