mm_machine 2.0.1 → 2.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +576 -210
- package/app/test1/config_demo.json +10 -0
- package/app/test1/demo.json +10 -0
- package/app/test1/index.js +30 -0
- package/app/test2/after.js +6 -0
- package/app/test2/config_demo.json +10 -0
- package/app/test2/demo.json +10 -0
- package/app/test2/main.js +18 -0
- package/demo/test1/config_demo.json +34 -0
- package/demo/test1/demo.json +33 -33
- package/demo/test1/index.js +29 -29
- package/demo/test2/after.js +14 -14
- package/demo/test2/config_demo.json +68 -0
- package/demo/test2/demo.json +67 -67
- package/demo/test2/index.js +14 -14
- package/demo/test2/main.js +15 -15
- package/demo2/test1/demo.json +33 -33
- package/demo2/test1/index.js +29 -29
- package/demo2/test2/after.js +14 -14
- package/demo2/test2/demo.json +67 -67
- package/demo2/test2/main.js +15 -15
- package/index.js +319 -324
- package/item.js +327 -240
- package/package.json +8 -5
- package/test.js +129 -129
package/item.js
CHANGED
|
@@ -1,13 +1,31 @@
|
|
|
1
|
+
require('mm_logs');
|
|
1
2
|
const util = require('util');
|
|
2
3
|
const conf = require('mm_config');
|
|
3
4
|
const Mod = require('mm_hot_reload');
|
|
4
|
-
|
|
5
|
-
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
// 初始化模块管理器
|
|
8
|
+
$.mod = $.mod || new Mod();
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* 增强require函数,支持热更新
|
|
12
|
+
* @param {String} file 文件路径
|
|
13
|
+
* @param {Function} func 回调函数
|
|
14
|
+
* @returns {Object} 加载的模块
|
|
15
|
+
*/
|
|
16
|
+
$.require = function (file, func) {
|
|
6
17
|
return $.mod.load(file, func);
|
|
7
|
-
}
|
|
8
|
-
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* 增强JSON加载函数,支持热更新
|
|
22
|
+
* @param {String} file 文件路径
|
|
23
|
+
* @param {Function} func 回调函数
|
|
24
|
+
* @returns {Object} 解析的JSON对象
|
|
25
|
+
*/
|
|
26
|
+
$.loadJson = function (file, func) {
|
|
9
27
|
return $.mod.load(file, func);
|
|
10
|
-
}
|
|
28
|
+
};
|
|
11
29
|
|
|
12
30
|
/**
|
|
13
31
|
* 驱动基础类
|
|
@@ -29,47 +47,48 @@ class Item {
|
|
|
29
47
|
/**
|
|
30
48
|
* 默认文件
|
|
31
49
|
*/
|
|
32
|
-
this.default_file =
|
|
50
|
+
this.default_file = './sys.json';
|
|
33
51
|
|
|
34
52
|
// 当前文件
|
|
35
|
-
this.filename;
|
|
53
|
+
this.filename = null;
|
|
54
|
+
|
|
36
55
|
/* 通用项 */
|
|
37
56
|
/**
|
|
38
57
|
* 配置参数
|
|
39
58
|
*/
|
|
40
59
|
this.config = {
|
|
41
60
|
/**
|
|
42
|
-
* 名称,
|
|
61
|
+
* 名称, 由中英文和下"_"组成, 用于卸载接口 例如: demo
|
|
43
62
|
*/
|
|
44
|
-
|
|
63
|
+
name: '',
|
|
45
64
|
/**
|
|
46
65
|
* 标题, 介绍作用
|
|
47
66
|
*/
|
|
48
|
-
|
|
67
|
+
title: '',
|
|
49
68
|
/**
|
|
50
69
|
* 描述, 用于描述该有什么用的
|
|
51
70
|
*/
|
|
52
|
-
|
|
71
|
+
description: '',
|
|
53
72
|
/**
|
|
54
73
|
* 文件路径, 当调用函数不存在时,会先从文件中加载
|
|
55
74
|
*/
|
|
56
|
-
|
|
75
|
+
func_file: './index.js',
|
|
57
76
|
/**
|
|
58
77
|
* 回调函数名 用于决定调用脚本的哪个函数
|
|
59
78
|
*/
|
|
60
|
-
|
|
79
|
+
func_name: '',
|
|
61
80
|
/**
|
|
62
81
|
* 排序
|
|
63
82
|
*/
|
|
64
|
-
|
|
83
|
+
sort: 10,
|
|
65
84
|
/**
|
|
66
85
|
* 状态, 0表示未启用, 1表示启用
|
|
67
86
|
*/
|
|
68
|
-
|
|
87
|
+
state: 1,
|
|
69
88
|
/**
|
|
70
89
|
* 显示, 0表示不显示, 1表示显示
|
|
71
90
|
*/
|
|
72
|
-
|
|
91
|
+
show: 0
|
|
73
92
|
};
|
|
74
93
|
|
|
75
94
|
/**
|
|
@@ -94,394 +113,462 @@ class Item {
|
|
|
94
113
|
|
|
95
114
|
/**
|
|
96
115
|
* 设置配置
|
|
97
|
-
* @param {Object} config
|
|
116
|
+
* @param {Object} config 配置对象
|
|
98
117
|
*/
|
|
99
|
-
Item.prototype.set_config = function(config) {
|
|
100
|
-
if (config
|
|
118
|
+
Item.prototype.set_config = function (config) {
|
|
119
|
+
if (!config) return;
|
|
120
|
+
|
|
121
|
+
// 如果func_file改变,重置加载状态
|
|
122
|
+
if (config.func_file !== this.config.func_file) {
|
|
101
123
|
this.complete = false;
|
|
102
124
|
}
|
|
103
|
-
|
|
104
|
-
|
|
125
|
+
|
|
126
|
+
// 合并配置并应用配置处理
|
|
127
|
+
this.config = conf(Object.assign({}, this.config, config), this.filename);
|
|
128
|
+
};
|
|
105
129
|
|
|
106
130
|
/**
|
|
107
|
-
*
|
|
131
|
+
* 设置配置后钩子方法
|
|
108
132
|
*/
|
|
109
|
-
Item.prototype.set_config_after = function() {
|
|
110
|
-
|
|
133
|
+
Item.prototype.set_config_after = function () {
|
|
134
|
+
// 空实现,供子类重写
|
|
111
135
|
};
|
|
112
136
|
|
|
113
137
|
/**
|
|
114
|
-
*
|
|
115
|
-
* @param {String} file
|
|
138
|
+
* 新建脚本文件
|
|
139
|
+
* @param {String} file 目标文件路径
|
|
116
140
|
*/
|
|
117
|
-
Item.prototype.new_script = function(file) {
|
|
118
|
-
|
|
119
|
-
if (
|
|
120
|
-
|
|
141
|
+
Item.prototype.new_script = function (file) {
|
|
142
|
+
const templateFile = `${this.dir_base}/script.js`;
|
|
143
|
+
if (templateFile.hasFile()) {
|
|
144
|
+
templateFile.copyFile(file);
|
|
121
145
|
}
|
|
122
146
|
};
|
|
123
147
|
|
|
124
148
|
/**
|
|
125
149
|
* 移除模块
|
|
126
|
-
* @param {Object}
|
|
150
|
+
* @param {Object|String} module 模块对象或路径
|
|
127
151
|
*/
|
|
128
|
-
Item.prototype.remove_module = function(
|
|
129
|
-
if (
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
152
|
+
Item.prototype.remove_module = function (module) {
|
|
153
|
+
if (!module) return;
|
|
154
|
+
|
|
155
|
+
try {
|
|
156
|
+
if (this.mode === 3 || this.mode === 4) {
|
|
157
|
+
// 移除模块和监听
|
|
158
|
+
$.mod.unload(module);
|
|
159
|
+
} else {
|
|
160
|
+
// 移除模块缓存
|
|
161
|
+
const filename = require.resolve(module);
|
|
162
|
+
if (require.cache[filename]) {
|
|
163
|
+
require.cache[filename] = null;
|
|
164
|
+
delete require.cache[filename];
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
} catch (err) {
|
|
168
|
+
$.log.error(`移除模块失败: ${err.message}`);
|
|
137
169
|
}
|
|
138
170
|
};
|
|
139
171
|
|
|
140
172
|
/**
|
|
141
173
|
* 卸载脚本
|
|
142
|
-
* @param {String} file
|
|
174
|
+
* @param {String} file 文件路径
|
|
143
175
|
*/
|
|
144
|
-
Item.prototype.unload_script = function(file) {
|
|
176
|
+
Item.prototype.unload_script = function (file) {
|
|
145
177
|
if (!file) {
|
|
146
|
-
|
|
147
|
-
if (
|
|
148
|
-
file =
|
|
178
|
+
const funcFile = this.config.func_file;
|
|
179
|
+
if (funcFile) {
|
|
180
|
+
file = funcFile.fullname(this.dir);
|
|
149
181
|
}
|
|
150
182
|
}
|
|
183
|
+
|
|
151
184
|
if (file) {
|
|
152
185
|
this.remove_module(file);
|
|
153
186
|
}
|
|
187
|
+
|
|
154
188
|
this.complete = false;
|
|
155
|
-
}
|
|
189
|
+
};
|
|
156
190
|
|
|
157
191
|
/**
|
|
158
192
|
* 重载脚本
|
|
159
|
-
* @param {String} file 文件
|
|
160
193
|
*/
|
|
161
|
-
Item.prototype.reload_script = function() {
|
|
194
|
+
Item.prototype.reload_script = function () {
|
|
162
195
|
this.unload_script();
|
|
163
196
|
this.load_script();
|
|
164
|
-
}
|
|
197
|
+
};
|
|
165
198
|
|
|
166
199
|
/**
|
|
167
|
-
*
|
|
200
|
+
* 卸载钩子方法
|
|
168
201
|
*/
|
|
169
|
-
Item.prototype.unload = async function() {
|
|
170
|
-
|
|
171
|
-
}
|
|
202
|
+
Item.prototype.unload = async function () {
|
|
203
|
+
// 空实现,供子类重写
|
|
204
|
+
};
|
|
172
205
|
|
|
173
206
|
/**
|
|
174
|
-
*
|
|
207
|
+
* 卸载之后处理
|
|
175
208
|
* @param {Boolean} remove 是否删除文件
|
|
176
209
|
*/
|
|
177
|
-
Item.prototype.unload_after = async function(remove) {
|
|
210
|
+
Item.prototype.unload_after = async function (remove) {
|
|
178
211
|
// 删除脚本
|
|
179
212
|
this.unload_script();
|
|
180
213
|
if (remove) {
|
|
181
214
|
this.remove_file();
|
|
182
215
|
}
|
|
183
|
-
}
|
|
216
|
+
};
|
|
184
217
|
|
|
185
218
|
/**
|
|
186
219
|
* 加载脚本
|
|
187
|
-
* @param {String} file
|
|
220
|
+
* @param {String} file 文件路径
|
|
188
221
|
* @param {String} name 函数名
|
|
189
|
-
* @returns {Object} 返回加载的模块对象
|
|
222
|
+
* @returns {Object|null} 返回加载的模块对象
|
|
190
223
|
*/
|
|
191
|
-
Item.prototype.load_script = function(file, name =
|
|
224
|
+
Item.prototype.load_script = function (file, name = '') {
|
|
192
225
|
if (!file) {
|
|
193
|
-
|
|
194
|
-
if (
|
|
195
|
-
file =
|
|
226
|
+
const funcFile = this.config.func_file;
|
|
227
|
+
if (funcFile) {
|
|
228
|
+
file = funcFile.fullname(this.dir);
|
|
196
229
|
if (!file.hasFile()) {
|
|
197
230
|
this.new_script(file);
|
|
198
231
|
}
|
|
199
232
|
} else {
|
|
200
|
-
return;
|
|
233
|
+
return null;
|
|
201
234
|
}
|
|
202
235
|
}
|
|
236
|
+
|
|
203
237
|
if (!name) {
|
|
204
238
|
name = this.config.func_name;
|
|
205
239
|
}
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
240
|
+
|
|
241
|
+
let cs;
|
|
242
|
+
try {
|
|
243
|
+
if (this.mode === 3 || this.mode === 4) {
|
|
244
|
+
cs = $.require(file, (loadedModule, changeType) => {
|
|
245
|
+
if (changeType === 'change' && loadedModule) {
|
|
246
|
+
if (name) {
|
|
247
|
+
if (loadedModule[name]) {
|
|
248
|
+
this.main = loadedModule[name];
|
|
249
|
+
}
|
|
250
|
+
} else if ($.push) {
|
|
251
|
+
$.push(this, loadedModule, true);
|
|
213
252
|
}
|
|
214
|
-
} else {
|
|
215
|
-
$.push(this, cs, true);
|
|
216
253
|
}
|
|
217
|
-
}
|
|
218
|
-
});
|
|
219
|
-
} else {
|
|
220
|
-
cs = require(file);
|
|
221
|
-
}
|
|
222
|
-
if (cs) {
|
|
223
|
-
if (name) {
|
|
224
|
-
if (cs[name]) {
|
|
225
|
-
this.main = cs[name];
|
|
226
|
-
}
|
|
254
|
+
});
|
|
227
255
|
} else {
|
|
228
|
-
|
|
256
|
+
cs = require(file);
|
|
229
257
|
}
|
|
258
|
+
|
|
259
|
+
if (cs) {
|
|
260
|
+
if (name) {
|
|
261
|
+
if (cs[name]) {
|
|
262
|
+
this.main = cs[name];
|
|
263
|
+
}
|
|
264
|
+
} else if ($.push) {
|
|
265
|
+
$.push(this, cs, true);
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
return cs;
|
|
270
|
+
} catch (err) {
|
|
271
|
+
$.log.error(`加载脚本失败: ${err.message}`);
|
|
272
|
+
return null;
|
|
230
273
|
}
|
|
231
|
-
|
|
232
|
-
}
|
|
274
|
+
};
|
|
233
275
|
|
|
234
276
|
/**
|
|
235
|
-
*
|
|
236
|
-
* @param {String} file
|
|
277
|
+
* 新建配置文件
|
|
278
|
+
* @param {String} file 目标文件路径
|
|
237
279
|
*/
|
|
238
|
-
Item.prototype.new_config = function(file) {
|
|
239
|
-
|
|
240
|
-
|
|
280
|
+
Item.prototype.new_config = function (file) {
|
|
281
|
+
const templateFile = `${this.dir_base}/config.tpl.json`;
|
|
282
|
+
templateFile.copyFile(file);
|
|
241
283
|
};
|
|
242
284
|
|
|
243
285
|
/**
|
|
244
286
|
* 加载配置文件
|
|
245
287
|
* @param {String} file 文件路径
|
|
246
288
|
* @param {String} name 配置项名称
|
|
247
|
-
* @return {Object} 配置对象
|
|
289
|
+
* @return {Object|null} 配置对象
|
|
248
290
|
*/
|
|
249
|
-
Item.prototype.load_file = function(file, name) {
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
291
|
+
Item.prototype.load_file = function (file, name) {
|
|
292
|
+
let config = null;
|
|
293
|
+
try {
|
|
294
|
+
const fullPath = file.fullname(this.dir);
|
|
295
|
+
let text = fullPath.loadText();
|
|
296
|
+
|
|
297
|
+
// 如果文件不存在,创建新的配置文件
|
|
298
|
+
if (!text) {
|
|
299
|
+
this.new_config(fullPath);
|
|
300
|
+
text = fullPath.loadText();
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
if (text) {
|
|
304
|
+
// 根据模式决定是否使用热更新加载
|
|
305
|
+
if (this.mode === 2 || this.mode === 3 || this.mode === 4) {
|
|
306
|
+
config = $.loadJson(fullPath, function (loadedConfig, changeType) {
|
|
307
|
+
if (changeType === 'change' && loadedConfig) {
|
|
308
|
+
try {
|
|
309
|
+
if (Array.isArray(loadedConfig)) {
|
|
310
|
+
// 在数组中查找匹配的配置项
|
|
311
|
+
const targetConfig = loadedConfig.find(item => item.name === this.config.name);
|
|
312
|
+
if (targetConfig) {
|
|
313
|
+
this.set_config(targetConfig);
|
|
314
|
+
this.set_config_after();
|
|
315
|
+
// 根据模式决定是否重新加载脚本
|
|
316
|
+
if (this.mode === 3 || this.mode === 4) {
|
|
317
|
+
this.reload_script();
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
} else {
|
|
321
|
+
this.set_config(loadedConfig);
|
|
266
322
|
this.set_config_after();
|
|
267
323
|
if (this.mode === 3 || this.mode === 4) {
|
|
268
324
|
this.reload_script();
|
|
269
325
|
}
|
|
270
|
-
break;
|
|
271
326
|
}
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
this.set_config(conf);
|
|
275
|
-
this.set_config_after();
|
|
276
|
-
if (this.mode === 3 || this.mode === 4) {
|
|
277
|
-
this.reload_script();
|
|
327
|
+
} catch (err) {
|
|
328
|
+
$.log.error(`配置热更新失败: ${err.message}`);
|
|
278
329
|
}
|
|
279
330
|
}
|
|
280
|
-
}
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
}
|
|
331
|
+
}.bind(this));
|
|
332
|
+
} else {
|
|
333
|
+
config = fullPath.loadJson();
|
|
334
|
+
}
|
|
285
335
|
|
|
286
|
-
|
|
287
|
-
if (Array.isArray(config)) {
|
|
288
|
-
|
|
289
|
-
for (var i = 0; i < list.length; i++) {
|
|
290
|
-
var o = list[i];
|
|
291
|
-
if (name === o.name) {
|
|
292
|
-
config = o;
|
|
293
|
-
break;
|
|
294
|
-
}
|
|
295
|
-
}
|
|
336
|
+
// 如果指定了名称且配置是数组,查找匹配项
|
|
337
|
+
if (name && Array.isArray(config)) {
|
|
338
|
+
config = config.find(item => item.name === name) || null;
|
|
296
339
|
}
|
|
297
340
|
}
|
|
341
|
+
|
|
342
|
+
// 更新目录和文件名引用
|
|
343
|
+
this.dir = fullPath.dirname();
|
|
344
|
+
this.filename = fullPath;
|
|
345
|
+
return config;
|
|
346
|
+
} catch (err) {
|
|
347
|
+
$.log.error(`加载配置文件失败: ${err.message}`);
|
|
348
|
+
return null;
|
|
298
349
|
}
|
|
299
|
-
this.dir = f.dirname();
|
|
300
|
-
this.filename = f;
|
|
301
|
-
return config;
|
|
302
350
|
};
|
|
303
351
|
|
|
304
352
|
/**
|
|
305
|
-
*
|
|
353
|
+
* 删除目录
|
|
306
354
|
*/
|
|
307
|
-
Item.prototype.del_dir = function() {
|
|
308
|
-
|
|
309
|
-
if (
|
|
355
|
+
Item.prototype.del_dir = function () {
|
|
356
|
+
const funcFile = this.config.func_file;
|
|
357
|
+
if (funcFile && $.dir && $.dir.del) {
|
|
310
358
|
$.dir.del(this.dir);
|
|
311
359
|
}
|
|
312
360
|
};
|
|
313
361
|
|
|
314
362
|
/**
|
|
315
363
|
* 删除配置和脚本文件
|
|
316
|
-
* @
|
|
364
|
+
* @returns {String|null} 错误消息,如果没有错误则返回null
|
|
317
365
|
*/
|
|
318
|
-
Item.prototype.remove_file = function() {
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
366
|
+
Item.prototype.remove_file = function () {
|
|
367
|
+
const name = this.config.name;
|
|
368
|
+
const file = this.filename;
|
|
369
|
+
|
|
370
|
+
let errorMessage = null;
|
|
371
|
+
try {
|
|
372
|
+
if (file && file.hasFile) {
|
|
373
|
+
if (file.hasFile()) {
|
|
374
|
+
const text = file.loadText();
|
|
375
|
+
if (text) {
|
|
376
|
+
const config = text.toJson();
|
|
377
|
+
if (Array.isArray(config)) {
|
|
378
|
+
// 在数组配置中查找并删除指定项
|
|
379
|
+
const index = config.findIndex(item => item.name === name);
|
|
380
|
+
if (index !== -1) {
|
|
381
|
+
this.del_dir();
|
|
382
|
+
config.splice(index, 1);
|
|
383
|
+
}
|
|
384
|
+
// 根据剩余配置决定保存或删除文件
|
|
385
|
+
if (config.length > 0) {
|
|
386
|
+
file.saveText(JSON.stringify(config, null, 4));
|
|
387
|
+
} else if (file.delFile) {
|
|
388
|
+
file.delFile();
|
|
389
|
+
}
|
|
390
|
+
} else {
|
|
391
|
+
// 单个配置直接删除目录
|
|
331
392
|
this.del_dir();
|
|
332
|
-
jarr.splice(i, 1);
|
|
333
|
-
break;
|
|
334
393
|
}
|
|
335
|
-
}
|
|
336
|
-
if (jarr.length) {
|
|
337
|
-
file.saveText(JSON.stringify(jarr, null, 4));
|
|
338
394
|
} else {
|
|
339
|
-
|
|
395
|
+
this.del_dir();
|
|
340
396
|
}
|
|
341
397
|
} else {
|
|
342
|
-
|
|
398
|
+
errorMessage = '配置文件不存在';
|
|
343
399
|
}
|
|
344
|
-
} else {
|
|
345
|
-
this.del_dir();
|
|
346
400
|
}
|
|
347
|
-
}
|
|
348
|
-
|
|
401
|
+
} catch (err) {
|
|
402
|
+
$.log.error(`删除文件失败: ${err.message}`);
|
|
403
|
+
errorMessage = `删除失败: ${err.message}`;
|
|
349
404
|
}
|
|
350
|
-
return
|
|
405
|
+
return errorMessage;
|
|
351
406
|
};
|
|
352
407
|
|
|
353
408
|
/**
|
|
354
409
|
* 载入配置
|
|
355
|
-
* @param {Object|String}
|
|
410
|
+
* @param {Object|String} configData 配置对象或配置路径
|
|
356
411
|
* @param {String} name 配置名称
|
|
357
412
|
*/
|
|
358
|
-
Item.prototype.load_config = function(
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
if (
|
|
362
|
-
|
|
413
|
+
Item.prototype.load_config = function (configData, name) {
|
|
414
|
+
let config;
|
|
415
|
+
try {
|
|
416
|
+
if (configData) {
|
|
417
|
+
if (typeof configData === 'string') {
|
|
418
|
+
config = this.load_file(configData, name);
|
|
419
|
+
} else {
|
|
420
|
+
config = configData;
|
|
421
|
+
}
|
|
363
422
|
} else {
|
|
364
|
-
config =
|
|
423
|
+
config = this.load_file(this.filename, name);
|
|
365
424
|
}
|
|
366
|
-
|
|
367
|
-
|
|
425
|
+
|
|
426
|
+
this.set_config(config);
|
|
427
|
+
this.set_config_after();
|
|
428
|
+
} catch (err) {
|
|
429
|
+
$.log.error(`载入配置失败: ${err.message}`);
|
|
368
430
|
}
|
|
369
|
-
this.set_config(config);
|
|
370
|
-
this.set_config_after();
|
|
371
431
|
};
|
|
372
432
|
|
|
373
433
|
/**
|
|
374
|
-
*
|
|
434
|
+
* 加载前处理
|
|
375
435
|
*/
|
|
376
|
-
Item.prototype.load_before = async function() {
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
436
|
+
Item.prototype.load_before = async function () {
|
|
437
|
+
try {
|
|
438
|
+
const module = this.load_script();
|
|
439
|
+
if (module) {
|
|
440
|
+
this.complete = true;
|
|
441
|
+
}
|
|
442
|
+
} catch (err) {
|
|
443
|
+
$.log.error(`加载前处理失败: ${err.message}`);
|
|
444
|
+
this.complete = false;
|
|
380
445
|
}
|
|
381
|
-
}
|
|
446
|
+
};
|
|
382
447
|
|
|
383
448
|
/**
|
|
384
|
-
*
|
|
449
|
+
* 加载处理
|
|
385
450
|
*/
|
|
386
|
-
Item.prototype.load = async function() {
|
|
387
|
-
//
|
|
388
|
-
}
|
|
451
|
+
Item.prototype.load = async function () {
|
|
452
|
+
// 空实现,供子类重写
|
|
453
|
+
};
|
|
389
454
|
|
|
390
455
|
/**
|
|
391
456
|
* 重载配置和脚本
|
|
392
457
|
*/
|
|
393
|
-
Item.prototype.reload = async function() {
|
|
458
|
+
Item.prototype.reload = async function () {
|
|
394
459
|
await this.run('unload');
|
|
395
460
|
await this.run('load');
|
|
396
|
-
}
|
|
461
|
+
};
|
|
397
462
|
|
|
398
463
|
/**
|
|
399
464
|
* 保存配置
|
|
400
465
|
*/
|
|
401
|
-
Item.prototype.save = function() {
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
466
|
+
Item.prototype.save = function () {
|
|
467
|
+
try {
|
|
468
|
+
if (!this.filename) return;
|
|
469
|
+
|
|
470
|
+
const fullPath = this.filename.fullname(this.dir);
|
|
471
|
+
const text = fullPath.loadText();
|
|
472
|
+
|
|
473
|
+
if (text && text.trim().startsWith('[')) {
|
|
474
|
+
// 数组格式配置
|
|
475
|
+
const configArray = text.toJson();
|
|
476
|
+
if (Array.isArray(configArray)) {
|
|
477
|
+
// 查找并更新现有配置项
|
|
478
|
+
const existingIndex = configArray.findIndex(item => item.name === this.config.name);
|
|
479
|
+
if (existingIndex !== -1) {
|
|
480
|
+
configArray[existingIndex] = this.config;
|
|
481
|
+
} else {
|
|
482
|
+
// 如果不存在,添加新配置项
|
|
483
|
+
configArray.push(this.config);
|
|
411
484
|
}
|
|
485
|
+
fullPath.saveText(JSON.stringify(configArray, null, 4));
|
|
486
|
+
return;
|
|
412
487
|
}
|
|
413
|
-
var txt = JSON.stringify(jarr, null, 4);
|
|
414
|
-
f.saveText(txt);
|
|
415
|
-
return;
|
|
416
488
|
}
|
|
489
|
+
|
|
490
|
+
// 单对象格式配置,直接保存
|
|
491
|
+
fullPath.saveText(JSON.stringify(this.config, null, 4));
|
|
492
|
+
} catch (err) {
|
|
493
|
+
$.log.error(`保存配置失败: ${err.message}`);
|
|
417
494
|
}
|
|
418
|
-
var txt = JSON.stringify(this.config, null, 4);
|
|
419
|
-
f.saveText(txt);
|
|
420
495
|
};
|
|
421
496
|
|
|
422
497
|
/**
|
|
423
498
|
* 主要执行函数
|
|
424
|
-
* @param {
|
|
499
|
+
* @param {*} params 参数集合
|
|
500
|
+
* @returns {Promise<any>} 执行结果
|
|
425
501
|
*/
|
|
426
|
-
Item.prototype.main = async function(...params) {
|
|
427
|
-
//
|
|
502
|
+
Item.prototype.main = async function (...params) {
|
|
503
|
+
// 空实现,供子类重写
|
|
428
504
|
return null;
|
|
429
505
|
};
|
|
430
506
|
|
|
431
507
|
/**
|
|
432
|
-
*
|
|
433
|
-
* @param {
|
|
508
|
+
* 运行主函数
|
|
509
|
+
* @param {*} params 参数集合
|
|
510
|
+
* @returns {Promise<any>} 执行结果
|
|
434
511
|
*/
|
|
435
|
-
Item.prototype.run = async function(...params) {
|
|
436
|
-
return await this.exec(
|
|
437
|
-
}
|
|
512
|
+
Item.prototype.run = async function (...params) {
|
|
513
|
+
return await this.exec('main', ...params);
|
|
514
|
+
};
|
|
438
515
|
|
|
439
516
|
/**
|
|
440
|
-
*
|
|
517
|
+
* 调用函数(核心执行方法)
|
|
441
518
|
* @param {String} method 函数名
|
|
442
|
-
* @param {
|
|
443
|
-
* @
|
|
519
|
+
* @param {*} params 参数集合
|
|
520
|
+
* @returns {Promise<any>} 执行结果
|
|
444
521
|
*/
|
|
445
|
-
Item.prototype.exec = async function(method, ...params) {
|
|
446
|
-
if (this[method]) {
|
|
447
|
-
|
|
448
|
-
|
|
522
|
+
Item.prototype.exec = async function (method, ...params) {
|
|
523
|
+
if (!this[method]) {
|
|
524
|
+
return null;
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
let result;
|
|
528
|
+
|
|
529
|
+
try {
|
|
530
|
+
// 执行前置钩子
|
|
531
|
+
const beforeMethod = `${method}_before`;
|
|
532
|
+
if (this[beforeMethod]) {
|
|
449
533
|
try {
|
|
450
|
-
|
|
534
|
+
result = this[beforeMethod](...params);
|
|
535
|
+
if (util.types.isPromise(result)) {
|
|
536
|
+
result = await result;
|
|
537
|
+
}
|
|
451
538
|
} catch (err) {
|
|
452
|
-
$.log.error(
|
|
539
|
+
$.log.error(`执行前置钩子 ${beforeMethod} 失败: ${err.message}`);
|
|
453
540
|
}
|
|
454
|
-
if (util.types.isPromise(ret)) {
|
|
455
|
-
ret = await ret;
|
|
456
|
-
}
|
|
457
|
-
}
|
|
458
|
-
try {
|
|
459
|
-
ret = this[method](...params);
|
|
460
|
-
} catch (err) {
|
|
461
|
-
$.log.error("执行时失败!", err);
|
|
462
|
-
}
|
|
463
|
-
if (util.types.isPromise(ret)) {
|
|
464
|
-
ret = await ret;
|
|
465
541
|
}
|
|
466
|
-
|
|
467
|
-
|
|
542
|
+
|
|
543
|
+
// 执行主方法
|
|
544
|
+
const methodResult = this[method](...params);
|
|
545
|
+
result = util.types.isPromise(methodResult) ? await methodResult : methodResult;
|
|
546
|
+
|
|
547
|
+
// 执行后置钩子
|
|
548
|
+
const afterMethod = `${method}_after`;
|
|
549
|
+
if (this[afterMethod]) {
|
|
468
550
|
try {
|
|
469
|
-
|
|
470
|
-
if (util.types.isPromise(
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
551
|
+
const afterResult = this[afterMethod](result, ...params);
|
|
552
|
+
if (util.types.isPromise(afterResult)) {
|
|
553
|
+
const resolvedAfterResult = await afterResult;
|
|
554
|
+
if (resolvedAfterResult !== undefined) {
|
|
555
|
+
result = resolvedAfterResult;
|
|
556
|
+
}
|
|
557
|
+
} else if (afterResult !== undefined) {
|
|
558
|
+
result = afterResult;
|
|
475
559
|
}
|
|
476
560
|
} catch (err) {
|
|
477
|
-
$.log.error(
|
|
561
|
+
$.log.error(`执行后置钩子 ${afterMethod} 失败: ${err.message}`);
|
|
478
562
|
}
|
|
479
563
|
}
|
|
480
|
-
|
|
564
|
+
} catch (err) {
|
|
565
|
+
$.log.error(`执行方法 ${method} 失败: ${err.message}`);
|
|
566
|
+
return null;
|
|
481
567
|
}
|
|
568
|
+
return result;
|
|
482
569
|
};
|
|
483
570
|
|
|
484
571
|
/**
|
|
485
|
-
* @module 导出
|
|
572
|
+
* @module 导出Item类
|
|
486
573
|
*/
|
|
487
574
|
module.exports = Item;
|