mm_os 2.4.4 → 2.4.6
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/core/com/cmd/config.tpl.json +1 -1
- package/core/com/cmd/index.js +1 -1
- package/core/com/component/README.md +3 -0
- package/core/com/component/com.json +4 -0
- package/core/com/component/component.html +16 -0
- package/core/com/component/config.tpl.json +26 -0
- package/core/com/component/drive.js +94 -0
- package/core/com/component/index.js +143 -0
- package/core/com/component/script.js +12 -0
- package/core/com/task/index.js +1 -1
- package/demo/app/test/mqtt/df/index.js +1 -1
- package/demo/app/test/mqtt/df/mqtt.json +2 -2
- package/demo/app/test/mqtt/zs/index.js +45 -13
- package/demo/app/test/mqtt/zs/mqtt.json +3 -1
- package/package.json +2 -2
package/core/com/cmd/index.js
CHANGED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
<div class="mm_col col-12 col-sm-6 col-md-3 col-lg-2">
|
|
2
|
+
<div class="component_demo">
|
|
3
|
+
<div class="title">示例组件标题</div>
|
|
4
|
+
<div class="description">示例组件描述</div>
|
|
5
|
+
</div>
|
|
6
|
+
</div>
|
|
7
|
+
|
|
8
|
+
<style scoped>
|
|
9
|
+
.component_demo {}
|
|
10
|
+
|
|
11
|
+
.component_demo .title {}
|
|
12
|
+
|
|
13
|
+
.component_demo .description {
|
|
14
|
+
|
|
15
|
+
}
|
|
16
|
+
</style>
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{
|
|
2
|
+
// 应用于,根据应用而判断使用
|
|
3
|
+
"app": "admin",
|
|
4
|
+
// 位置 side侧边栏、main主体、float浮动栏、header头部、footer尾部
|
|
5
|
+
"position": "main",
|
|
6
|
+
// 名称, 用于动态增删改配置
|
|
7
|
+
"name": "{0}",
|
|
8
|
+
// 标题, 用于查询时
|
|
9
|
+
"title": "示例组件(挂件)",
|
|
10
|
+
// 描述, 用于介绍该组件的作用
|
|
11
|
+
"description": "暂无描述",
|
|
12
|
+
// 时态, 分before之前、main主要、after之后三个时态,
|
|
13
|
+
"tense": "main",
|
|
14
|
+
// 执行顺序, 数值越小的越优先显示
|
|
15
|
+
"sort": 100,
|
|
16
|
+
// 分组, 可以将特有的分一个组, 方便用户查询
|
|
17
|
+
"group": "default",
|
|
18
|
+
// 分类, 例如: 查询生活类、监测类、便民类
|
|
19
|
+
"type": "监测",
|
|
20
|
+
// 脚本文件, 非必传,可和渲染文件二选一传
|
|
21
|
+
"func_file": "./component.js",
|
|
22
|
+
// 渲染, 非必传,可和脚本文件二选一传
|
|
23
|
+
"template": "./component.html",
|
|
24
|
+
// 状态, 0为未开启 1为开启
|
|
25
|
+
"state": 1
|
|
26
|
+
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
const Item = require('mm_machine').Item;
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* 指令驱动类
|
|
5
|
+
* @extends {Item}
|
|
6
|
+
* @class
|
|
7
|
+
*/
|
|
8
|
+
class Drive extends Item {
|
|
9
|
+
/**
|
|
10
|
+
* 构造函数
|
|
11
|
+
* @param {String} dir 当前目录
|
|
12
|
+
* @constructor
|
|
13
|
+
*/
|
|
14
|
+
constructor(dir) {
|
|
15
|
+
super(dir, __dirname);
|
|
16
|
+
this.default_file = "./component.json";
|
|
17
|
+
|
|
18
|
+
/* 通用项 */
|
|
19
|
+
// 配置参数
|
|
20
|
+
this.config = {
|
|
21
|
+
// 应用于,根据应用而判断使用
|
|
22
|
+
"app": "admin",
|
|
23
|
+
// 位置 side侧边栏、main主体、float浮动栏、header头部、footer尾部
|
|
24
|
+
"position": "main",
|
|
25
|
+
// 名称, 用于动态增删改配置
|
|
26
|
+
"name": "demo",
|
|
27
|
+
// 标题, 用于查询时
|
|
28
|
+
"title": "示例组件",
|
|
29
|
+
// 描述, 用于介绍该组件的作用
|
|
30
|
+
"description": "暂无描述",
|
|
31
|
+
// 时态, 分before之前、main主要、after之后三个时态,
|
|
32
|
+
"tense": "main",
|
|
33
|
+
// 执行顺序, 数值越小的越优先显示
|
|
34
|
+
"sort": 100,
|
|
35
|
+
// 分组, 可以将特有的分一个组, 方便用户查询
|
|
36
|
+
"group": "default",
|
|
37
|
+
// 分类, 例如: 查询生活类、监测类、便民类
|
|
38
|
+
"type": "监测",
|
|
39
|
+
// 脚本文件
|
|
40
|
+
"func_file": "./component.js",
|
|
41
|
+
// 渲染
|
|
42
|
+
"template": "./component.html",
|
|
43
|
+
// 状态, 0为未开启 1为开启
|
|
44
|
+
"state": 1
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* 创建一个参数模型
|
|
52
|
+
*/
|
|
53
|
+
Drive.prototype.model = function() {
|
|
54
|
+
return {
|
|
55
|
+
// 应用于,根据应用而判断使用
|
|
56
|
+
"app": "admin",
|
|
57
|
+
// 位置 side侧边栏、main主体、float浮动栏、header头部、footer尾部
|
|
58
|
+
"position": "main",
|
|
59
|
+
// 名称, 用于动态增删改配置
|
|
60
|
+
"name": "demo",
|
|
61
|
+
// 标题, 用于查询时
|
|
62
|
+
"title": "示例组件",
|
|
63
|
+
// 描述, 用于介绍该组件的作用
|
|
64
|
+
"description": "暂无描述",
|
|
65
|
+
// 时态, 分before之前、main主要、after之后三个时态,
|
|
66
|
+
"tense": "main",
|
|
67
|
+
// 执行顺序, 数值越小的越优先显示
|
|
68
|
+
"sort": 100,
|
|
69
|
+
// 分组, 可以将特有的分一个组, 方便用户查询
|
|
70
|
+
"group": "default",
|
|
71
|
+
// 分类, 例如: 查询生活类、监测类、便民类
|
|
72
|
+
"type": "监测",
|
|
73
|
+
// 脚本文件, 非必传,可和渲染文件二选一传
|
|
74
|
+
"func_file": "./component.js",
|
|
75
|
+
// 渲染, 非必传,可和脚本文件二选一传
|
|
76
|
+
"template": "./component.html",
|
|
77
|
+
// 状态, 0为未开启 1为开启
|
|
78
|
+
"state": 1
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* 组件主函数
|
|
84
|
+
* @param {Object} ctx 请求上下文
|
|
85
|
+
* @param {Object} db 数据管理器,如: { next: async function{}, ret: {} }
|
|
86
|
+
* @return {Object} 执行结果
|
|
87
|
+
*/
|
|
88
|
+
Drive.prototype.main = async function(ctx, db) {
|
|
89
|
+
var model = {};
|
|
90
|
+
var html_file = this.config.template || "./component.html";
|
|
91
|
+
return db.tpl.view(html_file.fullname(this.dir), model);
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
module.exports = Drive;
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
const Index = require('mm_machine').Index;
|
|
2
|
+
const Drive = require('./drive');
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Component组件
|
|
6
|
+
* @extends {Index}
|
|
7
|
+
* @class
|
|
8
|
+
*/
|
|
9
|
+
class Component extends Index {
|
|
10
|
+
/**
|
|
11
|
+
* 构造函数
|
|
12
|
+
* @param {Object} scope 作用域
|
|
13
|
+
* @param {String} title 标题
|
|
14
|
+
* @constructor
|
|
15
|
+
*/
|
|
16
|
+
constructor(scope, title) {
|
|
17
|
+
super(scope, __dirname);
|
|
18
|
+
this.Drive = Drive;
|
|
19
|
+
this.type = "component";
|
|
20
|
+
this.title = title;
|
|
21
|
+
this.list = [];
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* 新建脚本
|
|
27
|
+
* @param {String} file 文件
|
|
28
|
+
*/
|
|
29
|
+
Drive.prototype.new_script = function(file) {
|
|
30
|
+
var fl = __dirname + "/script.js";
|
|
31
|
+
if (fl.hasFile()) {
|
|
32
|
+
var text = fl.loadText();
|
|
33
|
+
if (text) {
|
|
34
|
+
var l = $.slash;
|
|
35
|
+
var arr = file.split(l);
|
|
36
|
+
var name = arr[arr.length - 2];
|
|
37
|
+
text = text.replaceAll('{0}', name);
|
|
38
|
+
file.saveText(text);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
var file_html = "./component.html".fullname(file.dirname());
|
|
43
|
+
if (!file_html.hasFile()) {
|
|
44
|
+
var flh = __dirname + "/component.html";
|
|
45
|
+
if (flh.hasFile()) {
|
|
46
|
+
var html = flh.loadText();
|
|
47
|
+
file_html.saveText(html);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* 加载列表
|
|
55
|
+
* @param {Array} list 文件列表
|
|
56
|
+
*/
|
|
57
|
+
Component.prototype.load_list = function(list) {
|
|
58
|
+
var _this = this;
|
|
59
|
+
// 遍历文件路径
|
|
60
|
+
list.map(function(file) {
|
|
61
|
+
var dir = file.dirname();
|
|
62
|
+
// 载入文件
|
|
63
|
+
var obj = file.loadJson(dir);
|
|
64
|
+
if (obj) {
|
|
65
|
+
if (obj.constructor == Array) {
|
|
66
|
+
obj.map(function(o) {
|
|
67
|
+
// 实例化一个驱动
|
|
68
|
+
_this.load_item(dir, o, file);
|
|
69
|
+
});
|
|
70
|
+
} else {
|
|
71
|
+
_this.load_item(dir, obj, file);
|
|
72
|
+
}
|
|
73
|
+
} else {
|
|
74
|
+
var fl = _this.dir_base + "/config.tpl.json";
|
|
75
|
+
if (fl.hasFile()) {
|
|
76
|
+
fl.copyFile(file);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* 执行渲染
|
|
84
|
+
* @param {String} app 应用
|
|
85
|
+
* @param {String} position 位置
|
|
86
|
+
* @param {String} position position
|
|
87
|
+
* @param {Object} ctx 请求上下文
|
|
88
|
+
* @param {Object} db 数据管理器,如: { next: async function{}, ret: {} }
|
|
89
|
+
* @return {String}
|
|
90
|
+
*/
|
|
91
|
+
Component.prototype.render = async function(app, position, ctx, db) {
|
|
92
|
+
var html = "";
|
|
93
|
+
var list = this.list;
|
|
94
|
+
for (var i = 0; i < list.length; i++) {
|
|
95
|
+
var o = list[i];
|
|
96
|
+
var cg = o.config;
|
|
97
|
+
if (cg.state && cg.app == app && cg.position == position) {
|
|
98
|
+
var ret;
|
|
99
|
+
try {
|
|
100
|
+
ret = await o.run('main', ctx, db);
|
|
101
|
+
} catch (error) {
|
|
102
|
+
$.log.error("组件渲染失败", o.config.name, error);
|
|
103
|
+
}
|
|
104
|
+
if (ret) {
|
|
105
|
+
html += "\n" + ret;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
return html;
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
/* 导出指令 */
|
|
113
|
+
exports.Component = Component;
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Component组件池
|
|
117
|
+
*/
|
|
118
|
+
if (!$.pool.component) {
|
|
119
|
+
$.pool.component = {};
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Component管理器,用于创建缓存
|
|
124
|
+
* @param {String} scope 作用域
|
|
125
|
+
* @param {string} title 标题
|
|
126
|
+
* @return {Object} 返回一个缓存类
|
|
127
|
+
*/
|
|
128
|
+
function component_admin(scope, title) {
|
|
129
|
+
if (!scope) {
|
|
130
|
+
scope = $.val.scope + '';
|
|
131
|
+
}
|
|
132
|
+
var obj = $.pool.component[scope];
|
|
133
|
+
if (!obj) {
|
|
134
|
+
$.pool.component[scope] = new Component(scope, title);
|
|
135
|
+
obj = $.pool.component[scope];
|
|
136
|
+
}
|
|
137
|
+
return obj;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* @module 导出Component管理器
|
|
142
|
+
*/
|
|
143
|
+
$.component_admin = component_admin;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
module.exports = {
|
|
2
|
+
/**
|
|
3
|
+
* 组件主函数
|
|
4
|
+
* @param {Object} ctx 请求上下文
|
|
5
|
+
* @param {Object} db 数据管理器,如: { next: async function{}, ret: {} }
|
|
6
|
+
* @return {Object} 执行结果
|
|
7
|
+
*/
|
|
8
|
+
async main(ctx, db) {
|
|
9
|
+
var model = {};
|
|
10
|
+
return db.tpl.view("./component.html".fullname(__dirname), model);
|
|
11
|
+
}
|
|
12
|
+
};
|
package/core/com/task/index.js
CHANGED
|
@@ -388,7 +388,7 @@ exports.init = function() {
|
|
|
388
388
|
}
|
|
389
389
|
_this.drives[clientid].online = 1;
|
|
390
390
|
_this.drives[clientid].time_last = new Date().getTime();
|
|
391
|
-
console.log("心跳", clientid, _this.drives[clientid]);
|
|
391
|
+
// console.log("心跳", clientid, _this.drives[clientid]);
|
|
392
392
|
}
|
|
393
393
|
|
|
394
394
|
/**
|
|
@@ -87,6 +87,14 @@ exports.delete_member = async function(clientid, uuid) {
|
|
|
87
87
|
return
|
|
88
88
|
}
|
|
89
89
|
|
|
90
|
+
exports.sleep = async function(longtime, param) {
|
|
91
|
+
return new Promise((resolve, reject) => {
|
|
92
|
+
setTimeout(() => {
|
|
93
|
+
resolve(param);
|
|
94
|
+
}, longtime);
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
|
|
90
98
|
/**
|
|
91
99
|
* 批量删除成员
|
|
92
100
|
* @param {String} clientid 客户端ID
|
|
@@ -97,7 +105,7 @@ exports.delete_member_batch = async function(clientid, arr, longtime) {
|
|
|
97
105
|
if (!this.drives[clientid]) {
|
|
98
106
|
this.drives[clientid] = {};
|
|
99
107
|
}
|
|
100
|
-
if (this.drives[clientid].pushing
|
|
108
|
+
if (this.drives[clientid].pushing) {
|
|
101
109
|
return {
|
|
102
110
|
detail: "busy"
|
|
103
111
|
}
|
|
@@ -117,8 +125,21 @@ exports.delete_member_batch = async function(clientid, arr, longtime) {
|
|
|
117
125
|
var res = await this.push("delete_face", clientid, {
|
|
118
126
|
"per_id": customId,
|
|
119
127
|
"type": 0
|
|
120
|
-
});
|
|
121
|
-
if (res
|
|
128
|
+
}, 10000);
|
|
129
|
+
if (!res) {
|
|
130
|
+
await this.sleep(60000);
|
|
131
|
+
res = await this.push("delete_face", clientid, {
|
|
132
|
+
"per_id": customId,
|
|
133
|
+
"type": 0
|
|
134
|
+
}, 10000);
|
|
135
|
+
}
|
|
136
|
+
if (!res) {
|
|
137
|
+
error_info.push({
|
|
138
|
+
customId,
|
|
139
|
+
errcode: -1,
|
|
140
|
+
time_create: now
|
|
141
|
+
});
|
|
142
|
+
} else if (res.message == "ACK") {
|
|
122
143
|
success++;
|
|
123
144
|
success_info.push({
|
|
124
145
|
customId,
|
|
@@ -176,10 +197,10 @@ exports.set_device_time = async function(clientid, datetime) {
|
|
|
176
197
|
"datetime": datetime
|
|
177
198
|
}
|
|
178
199
|
});
|
|
179
|
-
|
|
180
200
|
if (!res) {
|
|
181
201
|
return "请求超时!"
|
|
182
202
|
}
|
|
203
|
+
|
|
183
204
|
if (res.message !== "ACK") {
|
|
184
205
|
return res.code;
|
|
185
206
|
}
|
|
@@ -192,15 +213,15 @@ exports.set_device_time = async function(clientid, datetime) {
|
|
|
192
213
|
* @param {Boolean} member 是否恢复成员,true为恢复
|
|
193
214
|
* @param {Boolean} log 是否恢复请求日志,true为恢复
|
|
194
215
|
*/
|
|
195
|
-
exports.reset_device =
|
|
216
|
+
exports.reset_device = function(clientid, record = true, member = false, log = true) {
|
|
196
217
|
if (record) {
|
|
197
218
|
// 清空记录
|
|
198
|
-
|
|
219
|
+
this.push("delete_record", clientid, {});
|
|
199
220
|
}
|
|
200
221
|
|
|
201
222
|
if (member) {
|
|
202
223
|
// 删除所有成员
|
|
203
|
-
|
|
224
|
+
this.push("delete_face", clientid, {
|
|
204
225
|
type: 4
|
|
205
226
|
});
|
|
206
227
|
}
|
|
@@ -210,7 +231,7 @@ exports.reset_device = async function(clientid, record = true, member = false, l
|
|
|
210
231
|
* 查询下发进度(未完成)
|
|
211
232
|
* @param {String} clientid 设备sn
|
|
212
233
|
*/
|
|
213
|
-
exports.get_progress = function(clientid) {
|
|
234
|
+
exports.get_progress = async function(clientid) {
|
|
214
235
|
if (!this.drives[clientid]) {
|
|
215
236
|
this.drives[clientid] = {};
|
|
216
237
|
}
|
|
@@ -293,6 +314,9 @@ exports.get_member = async function(clientid, uuid, name) {
|
|
|
293
314
|
qy.name = name;
|
|
294
315
|
}
|
|
295
316
|
var res = await this.push("query_face", qy);
|
|
317
|
+
if (!res) {
|
|
318
|
+
return "请求超时!"
|
|
319
|
+
}
|
|
296
320
|
if (res.code) {
|
|
297
321
|
return res.pers_id;
|
|
298
322
|
}
|
|
@@ -370,7 +394,7 @@ exports.update_member_batch = async function(clientid, list, longtime = 0) {
|
|
|
370
394
|
if (!this.drives[clientid]) {
|
|
371
395
|
this.drives[clientid] = {};
|
|
372
396
|
}
|
|
373
|
-
if (this.drives[clientid].pushing
|
|
397
|
+
if (this.drives[clientid].pushing) {
|
|
374
398
|
return {
|
|
375
399
|
detail: "busy"
|
|
376
400
|
}
|
|
@@ -387,8 +411,18 @@ exports.update_member_batch = async function(clientid, list, longtime = 0) {
|
|
|
387
411
|
var now = new Date().toStr("yyyy-MM-dd hh:mm:ss");
|
|
388
412
|
for (var i = 0; i < list.length; i++) {
|
|
389
413
|
var user = list[i];
|
|
390
|
-
var res = await this.push("update_face_ex", clientid, this.member_model_out(user));
|
|
391
|
-
if (res
|
|
414
|
+
var res = await this.push("update_face_ex", clientid, this.member_model_out(user), 10000);
|
|
415
|
+
if (!res) {
|
|
416
|
+
await this.sleep(60000);
|
|
417
|
+
res = await this.push("update_face_ex", clientid, this.member_model_out(user), 10000);
|
|
418
|
+
}
|
|
419
|
+
if (!res) {
|
|
420
|
+
error_info.push({
|
|
421
|
+
customId: user.customId,
|
|
422
|
+
errcode: -1,
|
|
423
|
+
time_create: now
|
|
424
|
+
});
|
|
425
|
+
} else if (res.message == "ACK") {
|
|
392
426
|
success++;
|
|
393
427
|
success_info.push({
|
|
394
428
|
customId: user.customId,
|
|
@@ -470,7 +504,6 @@ exports.set_qrcode_mode = async function(clientid, mode = 1) {
|
|
|
470
504
|
mode
|
|
471
505
|
}
|
|
472
506
|
});
|
|
473
|
-
|
|
474
507
|
if (!res) {
|
|
475
508
|
return "请求超时!"
|
|
476
509
|
}
|
|
@@ -491,7 +524,6 @@ exports.send_led = async function(clientid, color = 1) {
|
|
|
491
524
|
color
|
|
492
525
|
}
|
|
493
526
|
});
|
|
494
|
-
|
|
495
527
|
if (!res) {
|
|
496
528
|
return "请求超时!"
|
|
497
529
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mm_os",
|
|
3
|
-
"version": "2.4.
|
|
3
|
+
"version": "2.4.6",
|
|
4
4
|
"description": "这是超级美眉服务端框架,用于快速构建应用程序。",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
"mm_redis": "^1.4.2",
|
|
49
49
|
"mm_ret": "^1.3.9",
|
|
50
50
|
"mm_session": "^1.4.8",
|
|
51
|
-
"mm_statics": "^1.4.
|
|
51
|
+
"mm_statics": "^1.4.8",
|
|
52
52
|
"mm_tpl": "^2.3.9",
|
|
53
53
|
"mm_xml": "^1.1.5",
|
|
54
54
|
"mosca": "^2.8.3",
|