chanjs 1.0.36 → 1.0.37
Sign up to get free protection for your applications and to get access to all the features.
- package/core/chan.js +16 -35
- package/core/lib/extend/cache.js +134 -0
- package/package.json +1 -1
package/core/chan.js
CHANGED
@@ -6,6 +6,7 @@ const config = require("./lib/config/config.js");
|
|
6
6
|
const {bindClass,createKnex,loadWebToEnd} = require("./lib/extend/helper.js");
|
7
7
|
const Controller = require("./lib/controller/controller.js");
|
8
8
|
const Service = require("./lib/service/service.js");
|
9
|
+
const cache = require('./lib/extend/cache.js');
|
9
10
|
const core = require("./lib/index.js");
|
10
11
|
/**
|
11
12
|
* @description 基于express封装的mvc框架,遵循约定优于配置原则
|
@@ -15,6 +16,7 @@ class Chan {
|
|
15
16
|
static modules = {};
|
16
17
|
static plugins = {};
|
17
18
|
static config = config;
|
19
|
+
static cache = cache;
|
18
20
|
static Controller = Controller;
|
19
21
|
static Service = Service;
|
20
22
|
constructor() {
|
@@ -130,30 +132,25 @@ class Chan {
|
|
130
132
|
this.loadRoutes(modules, moduleName);
|
131
133
|
}
|
132
134
|
|
135
|
+
loadFiles(modules, moduleName, type) {
|
136
|
+
const dir = path.join(Chan.config.APP_PATH, modules, moduleName, type);
|
137
|
+
if (fs.existsSync(dir)) {
|
138
|
+
const files = fs.readdirSync(dir).filter(file => file.endsWith(".js"));
|
139
|
+
files.forEach(file => {
|
140
|
+
const module = require(path.join(dir, file));
|
141
|
+
const name = file.replace(".js", "");
|
142
|
+
Chan[modules][moduleName][type][name] = { ...bindClass(module) };
|
143
|
+
});
|
144
|
+
}
|
145
|
+
}
|
146
|
+
|
133
147
|
/**
|
134
148
|
* @description 扫描模块下所有service
|
135
149
|
* @param {*} moduleDir 模块路径
|
136
150
|
* @param {*} moduleName 模块名称
|
137
151
|
*/
|
138
152
|
loadServices(modules, moduleName) {
|
139
|
-
|
140
|
-
Chan.config.APP_PATH,
|
141
|
-
modules,
|
142
|
-
moduleName,
|
143
|
-
"service"
|
144
|
-
);
|
145
|
-
if (fs.existsSync(servicesDir)) {
|
146
|
-
let services = fs
|
147
|
-
.readdirSync(servicesDir)
|
148
|
-
.filter((file) => file.endsWith(".js"));
|
149
|
-
for (let i = 0, file; i < services.length; i++) {
|
150
|
-
file = services[i];
|
151
|
-
const Service = require(path.join(servicesDir, file));
|
152
|
-
const serviceName = file.replace(".js", "");
|
153
|
-
//模块文件夹-模块文件名-服务-方法
|
154
|
-
Chan[modules][moduleName].service[serviceName] = {...bindClass(Service)};
|
155
|
-
}
|
156
|
-
}
|
153
|
+
this.loadFiles(modules, moduleName, "service");
|
157
154
|
}
|
158
155
|
|
159
156
|
/**
|
@@ -162,23 +159,7 @@ class Chan {
|
|
162
159
|
* @param {*} moduleName 模块名称
|
163
160
|
*/
|
164
161
|
loadControllers(modules, moduleName) {
|
165
|
-
|
166
|
-
Chan.config.APP_PATH,
|
167
|
-
modules,
|
168
|
-
moduleName,
|
169
|
-
"controller"
|
170
|
-
);
|
171
|
-
if (fs.existsSync(controllersDir)) {
|
172
|
-
let controllers = fs
|
173
|
-
.readdirSync(controllersDir)
|
174
|
-
.filter((file) => file.endsWith(".js"));
|
175
|
-
for (let i = 0, file; i < controllers.length; i++) {
|
176
|
-
file = controllers[i];
|
177
|
-
const controller = require(path.join(controllersDir, file));
|
178
|
-
const controllerName = file.replace(".js", "");
|
179
|
-
Chan[modules][moduleName].controller[controllerName] = {...bindClass(controller)};
|
180
|
-
}
|
181
|
-
}
|
162
|
+
this.loadFiles(modules, moduleName, "controller");
|
182
163
|
}
|
183
164
|
|
184
165
|
/**
|
@@ -0,0 +1,134 @@
|
|
1
|
+
class Cache {
|
2
|
+
constructor(maxSize = 1000) {
|
3
|
+
this.cache = new Map(); // 使用 Map 存储缓存数据
|
4
|
+
this.maxSize = maxSize; // 缓存最大容量
|
5
|
+
this.hits = 0; // 缓存命中次数
|
6
|
+
this.misses = 0; // 缓存未命中次数
|
7
|
+
}
|
8
|
+
|
9
|
+
/**
|
10
|
+
* 设置缓存
|
11
|
+
* @param {string} key - 缓存键
|
12
|
+
* @param {any} value - 缓存值
|
13
|
+
* @param {number} ttl - 缓存时间(毫秒),可选
|
14
|
+
*/
|
15
|
+
set(key, value, ttl = null) {
|
16
|
+
// 如果缓存已满,删除最早的一个缓存项
|
17
|
+
if (this.cache.size >= this.maxSize) {
|
18
|
+
const firstKey = this.cache.keys().next().value;
|
19
|
+
this.cache.delete(firstKey);
|
20
|
+
}
|
21
|
+
|
22
|
+
const cacheItem = {
|
23
|
+
value,
|
24
|
+
expires: ttl ? Date.now() + ttl : null, // 设置过期时间
|
25
|
+
updatedAt: Date.now(), // 记录更新时间
|
26
|
+
};
|
27
|
+
this.cache.set(key, cacheItem);
|
28
|
+
}
|
29
|
+
|
30
|
+
/**
|
31
|
+
* 获取缓存
|
32
|
+
* @param {string} key - 缓存键
|
33
|
+
* @returns {any} - 缓存值,如果过期或不存在则返回 null
|
34
|
+
*/
|
35
|
+
get(key) {
|
36
|
+
if (!this.cache.has(key)) {
|
37
|
+
this.misses++; // 未命中
|
38
|
+
return null;
|
39
|
+
}
|
40
|
+
|
41
|
+
const cacheItem = this.cache.get(key);
|
42
|
+
|
43
|
+
// 检查是否过期
|
44
|
+
if (cacheItem.expires && Date.now() > cacheItem.expires) {
|
45
|
+
this.cache.delete(key); // 删除过期缓存
|
46
|
+
this.misses++; // 未命中
|
47
|
+
return null;
|
48
|
+
}
|
49
|
+
|
50
|
+
this.hits++; // 命中
|
51
|
+
return cacheItem.value; // 返回缓存值
|
52
|
+
}
|
53
|
+
|
54
|
+
/**
|
55
|
+
* 清除指定缓存
|
56
|
+
* @param {string} key - 缓存键
|
57
|
+
*/
|
58
|
+
clear(key) {
|
59
|
+
this.cache.delete(key);
|
60
|
+
}
|
61
|
+
|
62
|
+
/**
|
63
|
+
* 清除所有缓存
|
64
|
+
*/
|
65
|
+
clearAll() {
|
66
|
+
this.cache.clear();
|
67
|
+
this.hits = 0;
|
68
|
+
this.misses = 0;
|
69
|
+
}
|
70
|
+
|
71
|
+
/**
|
72
|
+
* 获取缓存命中率
|
73
|
+
* @returns {number} - 命中率(0 到 1 之间)
|
74
|
+
*/
|
75
|
+
getHitRate() {
|
76
|
+
const total = this.hits + this.misses;
|
77
|
+
return total === 0 ? 0 : this.hits / total;
|
78
|
+
}
|
79
|
+
|
80
|
+
/**
|
81
|
+
* 获取缓存大小
|
82
|
+
* @returns {number} - 缓存项数量
|
83
|
+
*/
|
84
|
+
size() {
|
85
|
+
return this.cache.size;
|
86
|
+
}
|
87
|
+
|
88
|
+
/**
|
89
|
+
* 获取所有缓存键
|
90
|
+
* @returns {string[]} - 缓存键列表
|
91
|
+
*/
|
92
|
+
keys() {
|
93
|
+
return Array.from(this.cache.keys());
|
94
|
+
}
|
95
|
+
|
96
|
+
/**
|
97
|
+
* 遍历缓存项
|
98
|
+
* @param {function} callback - 回调函数,接收 key 和 value 作为参数
|
99
|
+
*/
|
100
|
+
forEach(callback) {
|
101
|
+
this.cache.forEach((cacheItem, key) => {
|
102
|
+
callback(key, cacheItem.value);
|
103
|
+
});
|
104
|
+
}
|
105
|
+
}
|
106
|
+
|
107
|
+
module.exports = new Cache();
|
108
|
+
|
109
|
+
// // 示例用法
|
110
|
+
// const cache = new SimpleCache(100); // 设置缓存最大容量为 100
|
111
|
+
|
112
|
+
// // 设置缓存,有效期为 5 秒
|
113
|
+
// cache.set('name', 'Alice', 5000);
|
114
|
+
// cache.set('name', 'Alice', 5000);
|
115
|
+
// // 获取缓存
|
116
|
+
// console.log(cache.get('name')); // 输出: Alice
|
117
|
+
|
118
|
+
// // 获取缓存命中率
|
119
|
+
// console.log(cache.getHitRate()); // 输出: 1 (100% 命中率)
|
120
|
+
|
121
|
+
// // 获取缓存大小
|
122
|
+
// console.log(cache.size()); // 输出: 1
|
123
|
+
|
124
|
+
// // 获取所有缓存键
|
125
|
+
// console.log(cache.keys()); // 输出: ['name']
|
126
|
+
|
127
|
+
// // 遍历缓存项
|
128
|
+
// cache.forEach((key, value) => {
|
129
|
+
// console.log(`Key: ${key}, Value: ${value}`);
|
130
|
+
// });
|
131
|
+
|
132
|
+
// // 清除所有缓存
|
133
|
+
// cache.clearAll();
|
134
|
+
// console.log(cache.size()); // 输出: 0
|