mm_os 2.1.9 → 2.2.1

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.
@@ -0,0 +1,447 @@
1
+ var sql = $.mysql_admin('sys');
2
+ var dbs = sql.dbs;
3
+
4
+ /**
5
+ * 服务端类
6
+ */
7
+ class Server {
8
+
9
+ }
10
+
11
+ /**
12
+ * 获取用户
13
+ * @param {String} table 数据表
14
+ * @param {Number} project_id 项目ID
15
+ * @param {String} customId 自定义身份ID
16
+ * @param {String} name 用户姓名
17
+ * @param {String} phone 用户手机号码
18
+ * @param {String} idcard 用户身份证号
19
+ * @returns {Object} 返回用户对象
20
+ */
21
+ Server.prototype.get_user_sub = async function(table, project_id, customId, name, phone, idcard) {
22
+ var db1 = dbs.new("face_" + table, "user_id");
23
+ var query = {
24
+ project_id
25
+ }
26
+ if (customId && customId !== "0") {
27
+ query.customId = customId;
28
+ } else {
29
+ query.name = name;
30
+ if (phone) {
31
+ query.phone = phone;
32
+ } else if (idcard) {
33
+ query.idcard = idcard;
34
+ }
35
+ }
36
+ // 先查询1次,看内部人员是否存在
37
+ var enter = await db2.getObj(query, "", "*", false);
38
+
39
+ if (!enter) {
40
+ // 如果不存在,则用名字再查一次,看内部人员是否存在
41
+ query = {
42
+ project_id,
43
+ name
44
+ };
45
+ enter = await db2.getObj(query, "`time_create` desc", "*", false);
46
+ }
47
+ return enter;
48
+ }
49
+
50
+ /**
51
+ * 获取用户
52
+ * @param {String} project_id 项目ID
53
+ * @param {String} table 数据表
54
+ * @param {Number} project_id 项目ID
55
+ * @param {String} customId 自定义身份ID
56
+ * @param {String} name 用户姓名
57
+ * @param {String} phone 用户手机号码
58
+ * @param {String} idcard 用户身份证号
59
+ * @returns {Object} 返回用户对象和用户类型
60
+ */
61
+ Server.prototype.get_user = async function(project_id, customId, name, phone, idcard) {
62
+ // 默认为 1内部人员类型
63
+ var user_type = 1;
64
+ var enter = await this.get_user_sub("enter", project_id, customId, name, phone, idcard);
65
+
66
+ if (!enter) {
67
+ // 2为访客
68
+ user_type = 2;
69
+ enter = await this.get_user_sub("visitor", project_id, customId, name, phone, idcard);
70
+ }
71
+
72
+ if (enter) {
73
+ var by = {};
74
+ if (!enter.customId && customId && customId !== "0") {
75
+ by.customId = customId;
76
+ }
77
+ if (!enter.phone && phone) {
78
+ by.phone = phone;
79
+ }
80
+ if (!enter.idcard && idcard && idcard !== '0') {
81
+ by.idcard = idcard;
82
+ }
83
+ if (Object.keys(by).length) {
84
+ var db3;
85
+ var qy = {};
86
+ if (user_type == 2) {
87
+ db3 = dbs.new("face_visitor", "visitor_id");
88
+ qy.visitor_id = enter.visitor_id
89
+ } else {
90
+ db3 = dbs.new("face_enter", "user_id");
91
+ qy.user_id == enter.user_id;
92
+ qy.project_id = enter.project_id;
93
+ }
94
+ await db3.set(qy, by);
95
+ enter = Object.assign({}, enter, by);
96
+ }
97
+ } else {
98
+ // 3为外部人员(非平台成员)
99
+ user_type = 3;
100
+ enter = {
101
+ department_id: 0,
102
+ team_id: 0,
103
+ job: '',
104
+ phone,
105
+ idcard
106
+ };
107
+ }
108
+ var user = Object.assign({}, enter, {
109
+ customId,
110
+ name,
111
+ phone,
112
+ idcard
113
+ })
114
+ return {
115
+ user_type,
116
+ user
117
+ }
118
+ }
119
+
120
+ /**
121
+ * 处理上传记录
122
+ * @param {String} clientid 设备ID
123
+ * @param {Object} log 记录
124
+ */
125
+ Server.prototype.exec_log = async function(clientid, log) {
126
+ var {
127
+ device,
128
+ tip
129
+ } = await this.check_device(clientid);
130
+
131
+ if (tip) {
132
+ return tip
133
+ }
134
+
135
+ var project_id = device.project_id;
136
+ var {
137
+ project,
138
+ tip
139
+ } = check_project(project_id);
140
+
141
+ if (tip) {
142
+ return tip
143
+ }
144
+
145
+ var {
146
+ customId,
147
+ name,
148
+ phone,
149
+ idcard
150
+ } = log;
151
+ // 通过项目id和用户唯一标识获取用户
152
+ var {
153
+ user,
154
+ user_type
155
+ } = await this.get_user(project_id, customId, name, phone, idcard);
156
+
157
+ // 如果不记录外部人员,则终止,不保存记录
158
+ if (!project.save_outboard && user_type === 3) {
159
+ return
160
+ }
161
+ log.user_type = user_type;
162
+ log.clientid = clientid;
163
+ log.direction = device.direction;
164
+ return this.save_log(log);
165
+ }
166
+
167
+ /**
168
+ * 检查设备
169
+ * @param {String} clientid 客户端ID
170
+ * @param {Object} key 键
171
+ */
172
+ Server.prototype.check_device = async function(clientid, key) {
173
+ var tip;
174
+ var db2 = dbs.new("face_device");
175
+ var device = await db2.getObj({
176
+ clientid
177
+ });
178
+ if (device) {
179
+ if (device.available) {
180
+ if (key && !device[key]) {
181
+ tip = "没有功能权限"
182
+ }
183
+ } else {
184
+ tip = "设备已禁用"
185
+ }
186
+ } else {
187
+ tip = "没有找到设备"
188
+ }
189
+ return {
190
+ device,
191
+ tip
192
+ };
193
+ }
194
+
195
+
196
+ /**
197
+ * 检查项目
198
+ * @param {String} project_id 项目ID
199
+ * @param {Object} key 键
200
+ */
201
+ Server.prototype.check_project = async function(project_id, key) {
202
+ var tip;
203
+ var db2 = dbs.new("face_project");
204
+ var project = await db2.getObj({
205
+ project_id
206
+ });
207
+ if (project) {
208
+ if (project.available) {
209
+ var now = new Date().getTime();
210
+ if (now > new Date(project.time_valid).getTime()) {
211
+ tip = "项目已过期"
212
+ } else if (key && !project[key]) {
213
+ tip = "没有功能权限"
214
+ }
215
+ } else {
216
+ tip = "项目已禁用"
217
+ }
218
+ } else {
219
+ tip = "没有找到项目"
220
+ }
221
+ return {
222
+ project,
223
+ tip
224
+ }
225
+ }
226
+
227
+ /**
228
+ * 保存记录
229
+ * @param {Object} log 记录
230
+ */
231
+ Server.prototype.save_log = async function(log) {
232
+ var db = dbs.new("face_log", "user_id");
233
+ var project_id = log.project_id;
234
+ var user_id = log.user_id || 0;
235
+ var time = log.time;
236
+ var count = await db.count({
237
+ project_id,
238
+ user_id,
239
+ time
240
+ });
241
+
242
+ // 如果记录已存在,则不再保存
243
+ if (count) {
244
+ return
245
+ }
246
+
247
+ // 重新定义方向
248
+ var direction = log.direction;
249
+ if (user_id && direction == "通用") {
250
+ var qy = {
251
+ user_id,
252
+ project_id,
253
+ type_has: "1,3,4",
254
+ time_min: now.toStr('yyyy-MM-dd 00:00:00')
255
+ };
256
+ var obj = await db.getObj(qy, '`time` desc');
257
+ if (obj) {
258
+ direction = obj.direction == "进" ? "出" : "进"
259
+ } else {
260
+ direction = "进"
261
+ }
262
+ }
263
+ log.direction = direction;
264
+
265
+ // 重新定义头像
266
+ var pic;
267
+ var fname = time.replace(/[-: ]/g, '_');
268
+ var avatar = log.avatar;
269
+ if (avatar) {
270
+ if (project.upload_pic) {
271
+ pic = avatar;
272
+ avatar = `/face/img/user/${user_id}/${fname}.png`;
273
+ } else {
274
+ avatar = "";
275
+ }
276
+ }
277
+
278
+ // 如果是访客则追加备注
279
+ var visitor_id = log.visitor_id;
280
+ if (visitor_id) {
281
+ var {
282
+ respondent,
283
+ date,
284
+ source
285
+ } = log;
286
+ if (typeof(date) == "string") {
287
+ date = date.toTime().toStr("yyyy-MM-dd");
288
+ } else if (typeof(date) == "object") {
289
+ date = date.toStr("yyyy-MM-dd");
290
+ } else {
291
+ date = ''
292
+ }
293
+ log.note = `${visitor_id},${source},${date},${respondent},${log.nfc}`;
294
+ delete log.visitor_id;
295
+ delete log.respondent;
296
+ delete log.date;
297
+ delete log.source;
298
+ }
299
+
300
+ // 添加新记录
301
+ var n = await db.add(log);
302
+
303
+ var bl = n > 0;
304
+ if (bl) {
305
+ // 更新用户状态
306
+ var body = {
307
+ clientid: log.clientid,
308
+ direction,
309
+ time
310
+ };
311
+ if (log.user_type == 1) {
312
+ var db4 = dbs.new("face_enter", "enter_id");
313
+ await db4.set({
314
+ user_id,
315
+ project_id
316
+ }, body);
317
+ } else if (user_type == 2) {
318
+ var db4 = dbs.new("face_visitor", "visitor_id");
319
+ await db4.set({
320
+ visitor_id
321
+ }, body);
322
+ }
323
+
324
+ if (pic) {
325
+ var file = (`/app/face/static/img/user/${user_id}/${fname}.png`).fullname();
326
+ file.addDir();
327
+ var po = pic.replace(/^data:image\/\w+;base64,/, "");
328
+ var bf = Buffer.from(po, 'base64');
329
+ fs.writeFileSync(file, bf);
330
+ }
331
+ }
332
+ return bl;
333
+ }
334
+
335
+ /**
336
+ * 处理扫描二维码开门
337
+ * @param {String} clientid 客户端ID
338
+ * @param {String} qrcode 二维码内容
339
+ */
340
+ Server.prototype.exec_qrcode = async function(clientid, qrcode = "") {
341
+ var ret;
342
+ var db = dbs.new("face_qrcode", "qrcode_id");
343
+ var now = new Date();
344
+ var time = now.toStr('yyyy-MM-dd hh:mm:ss');
345
+ var obj = await db.getObj({
346
+ qrcode,
347
+ time_end_min: time
348
+ });
349
+ if (obj) {
350
+ var {
351
+ device,
352
+ tip
353
+ } = await this.check_device(clientid, "qrcode");
354
+ if (tip) {
355
+ // 发送开门控制
356
+ ret = {
357
+ "uuid": obj.user_id,
358
+ // 0不开门,1开门
359
+ "pass": false,
360
+ "tip": tip
361
+ }
362
+ } else {
363
+ if (obj.count == 0 || obj.num < obj.count) {
364
+ var db = dbs.new("face_enter");
365
+ var user = await db.getObj({
366
+ user_id: obj.user_id,
367
+ project_id: obj.project_id,
368
+ state: 3
369
+ });
370
+ if (user) {
371
+ if (user.client && user.client.indexOf(clientid) !== -1) {
372
+ obj.num++;
373
+ // 发送开门控制
374
+ ret = {
375
+ "uuid": user.customId || user.project_id + "-" + user.user_id,
376
+ // 0不开门,1开门
377
+ "pass": true,
378
+ "tip": "请通行",
379
+ user
380
+ }
381
+ var log = {
382
+ project_id: 0,
383
+ user_id: 0,
384
+ name: "",
385
+ // 1内部人员|2访客|3非系统名单
386
+ user_type: 1,
387
+ // 1人脸验证|2远程开门|3扫码开门|4刷卡验证
388
+ type: 3,
389
+ record_type: 1,
390
+ action: "智码开门",
391
+ // 1白名单|2黑名单
392
+ person_type: 1,
393
+ department_id: 0,
394
+ team_id: 0,
395
+ job: "",
396
+ phone: "",
397
+ idcard: "",
398
+ nfc: "",
399
+ note: ""
400
+ }
401
+ $.push(u, user);
402
+ log.direction = device.direction;
403
+ log.clientid = clientid;
404
+ log.time = time;
405
+ await this.save_log(log);
406
+ } else {
407
+ // 发送开门控制
408
+ ret = {
409
+ "uuid": user.customId || user.project_id + "-" + user.user_id,
410
+ // 0不开门,1开门
411
+ "pass": false,
412
+ "tip": "没有访问权限"
413
+ }
414
+ }
415
+ } else {
416
+ // 发送开门控制
417
+ ret = {
418
+ "uuid": obj.project_id + "-" + obj.user_id,
419
+ // 0不开门,1开门
420
+ "pass": false,
421
+ "tip": "非法用户"
422
+ }
423
+ }
424
+ } else {
425
+ // 发送开门控制
426
+ ret = {
427
+ "uuid": obj.project_id + "-" + obj.user_id,
428
+ // 0不开门,1开门
429
+ "pass": false,
430
+ "tip": "使用次数超限"
431
+ }
432
+ }
433
+ }
434
+ } else {
435
+ // 发送开门控制
436
+ ret = {
437
+ "uuid": "0",
438
+ // 0不开门,1开门
439
+ "pass": false,
440
+ "tip": "非法二维码"
441
+ }
442
+ }
443
+
444
+ return ret;
445
+ }
446
+
447
+ $.server = new Server();
@@ -44,12 +44,12 @@
44
44
  },
45
45
  "mqtt": {
46
46
  // 是否启用MQTT
47
- "state": false,
47
+ "state": true,
48
48
  // mqtt访问端口号
49
49
  "socket_port": 1883,
50
50
  // websocket 访问端口
51
51
  "http_port": 8083,
52
- // 缓存方式
52
+ // 缓存方式 memory、mongodb、redis
53
53
  "cache": "memory",
54
54
  // 缓存服务器地址
55
55
  "cache_host": "mongodb://localhost:27017/mosca",
@@ -58,7 +58,7 @@
58
58
  // 协议头
59
59
  "protocol": "mqtt",
60
60
  // MQTT服务器地址
61
- "hostname": "mqtt.aieliantong.com",
61
+ "hostname": "127.0.0.1",
62
62
  // MQTT服务器用户名
63
63
  "username": "developer",
64
64
  // MQTT服务器密码
@@ -37,15 +37,15 @@
37
37
  "proxy": {}
38
38
  },
39
39
  "mqtt": {
40
- "state": false,
40
+ "state": true,
41
41
  // mqtt访问端口号
42
42
  "socket_port": 1883,
43
43
  // 服务端
44
44
  "http_host": "localhost",
45
45
  // websocket 访问端口
46
46
  "http_port": 8083,
47
- // 缓存方式
48
- "cache": "mongodb",
47
+ // 缓存方式 memory、mongodb、redis
48
+ "cache": "memory",
49
49
  // 缓存服务器地址
50
50
  "cache_host": "mongodb://localhost:27017/mosca",
51
51
  // MQTT订阅方式
@@ -57,7 +57,7 @@
57
57
  // MQTT服务器用户名
58
58
  "username": "server",
59
59
  // MQTT服务器密码
60
- "password": "df6897hu",
60
+ "password": "asd123",
61
61
  "port": 1883
62
62
  },
63
63
  "mysql": {
@@ -52,7 +52,7 @@
52
52
  // 协议头
53
53
  "protocol": "mqtt",
54
54
  // MQTT服务器地址
55
- "hostname": "mqtt.aieliantong.com",
55
+ "hostname": "127.0.0.1",
56
56
  // MQTT服务器用户名
57
57
  "username": "developer",
58
58
  // MQTT服务器密码
package/demo/index.js CHANGED
@@ -11,4 +11,13 @@ $.sql = $.mysql_admin('sys', __dirname);
11
11
  $.sql.setConfig(config.mysql);
12
12
  $.sql.open();
13
13
 
14
+ setTimeout(async () => {
15
+ var mqtt = $.mqtt_admin("sys");
16
+ mqtt.init(config.mqtt);
17
+ mqtt.start();
18
+ await mqtt.update();
19
+ mqtt.run(null, 'init');
20
+ // console.log("打印", $.eventer, mqtt);
21
+ }, 2000);
22
+
14
23
  os.run();
package/index.js CHANGED
@@ -239,7 +239,6 @@ OS.prototype.main = async function(state) {
239
239
  }
240
240
 
241
241
  if (cg.sys && cg.sys.task) {
242
- console.log('【启动定时任务】');
243
242
  $.task.update();
244
243
  $.task.run();
245
244
  }
@@ -14,13 +14,12 @@ module.exports = function(server, config) {
14
14
  // ctx.set("Access-Control-Allow-Origin", "http://localhost:8080");
15
15
 
16
16
  // 设置所允许的HTTP请求方法OPTIONS,GET,PUT,POST,DELETE
17
- ctx.set('Access-Control-Allow-Methods', 'PUT, POST, GET, DELETE, HEAD, OPTIONS')
18
-
17
+ // ctx.set('Access-Control-Allow-Methods', 'PUT,POST,GET,DELETE,HEAD,OPTIONS');
19
18
 
20
19
  // 字段是必需的。它也是一个逗号分隔的字符串,表明服务器支持的所有头信息字段.
21
- ctx.set('Access-Control-Allow-Headers',
22
- 'Content-Type, Content-Length, Authorization, Accept, X-Requested-With, x-auth-token, token, client_id, appid, apikey, user_id,x-forwarded-for,x-real-ip,user-agent,cache-control,pragma,accept-encoding,connection,host'
23
- );
20
+ // ctx.set('Access-Control-Allow-Headers',
21
+ // 'Content-Type,Content-Length,Authorization,Accept,X-Requested-With,x-auth-token,token,client_id,appid,apikey,user_id,x-forwarded-for,x-real-ip,user-agent,cache-control,pragma,accept-encoding,connection,host'
22
+ // );
24
23
 
25
24
  // 服务器收到请求以后,检查了Origin、Access-Control-Request-Method和Access-Control-Request-Headers字段以后,确认允许跨源请求,就可以做出回应。
26
25
 
@@ -29,12 +28,12 @@ module.exports = function(server, config) {
29
28
 
30
29
  // 该字段可选。它的值是一个布尔值,表示是否允许发送Cookie。默认情况下,Cookie不包括在CORS请求之中。
31
30
  // 当设置成允许请求携带cookie时,需要保证"Access-Control-Allow-Origin"是服务器有的域名,而不能是"*";
32
- ctx.set("Access-Control-Allow-Credentials", 'false');
31
+ // ctx.set("Access-Control-Allow-Credentials", 'true');
33
32
 
34
33
  // 该字段可选,用来指定本次预检请求的有效期,单位为秒。
35
34
  // 当请求方法是PUT或DELETE等特殊方法或者Content-Type字段的类型是application/json时,服务器会提前发送一次请求进行验证
36
35
  // 下面的的设置只本次验证的有效时间,即在该时间段内服务端可以不用进行验证
37
- ctx.set("Access-Control-Max-Age", '3600');
36
+ // ctx.set("Access-Control-Max-Age", '3600');
38
37
  /*
39
38
  CORS请求时,XMLHttpRequest对象的getResponseHeader()方法只能拿到6个基本字段:
40
39
  Cache-Control、
@@ -24,7 +24,8 @@ function setting_blacklist(ip) {
24
24
  var cmd;
25
25
  if (platform == "win32") {
26
26
  // window 系统
27
- cmd = `netsh advfirewall firewall add rule name="Blacklist ${ip}" dir=in action=block remoteip="${ip}" protocol=any`
27
+ cmd =
28
+ `netsh advfirewall firewall add rule name="Blacklist ${ip}" dir=in action=block remoteip="${ip}" protocol=any`
28
29
  } else {
29
30
  // linux 系统
30
31
  cmd = `sudo iptables -A INPUT -s ${ip} -j DROP`;
@@ -89,7 +90,6 @@ module.exports = function(server, config) {
89
90
  time = now.toStr('yyyy-MM-dd hh:mm:ss');
90
91
  }
91
92
  if (pass) {
92
- console.log(ip, num, time, json ? json : '');
93
93
  await $.cache.set("ip_" + ip, JSON.stringify({
94
94
  date,
95
95
  time,
@@ -5,5 +5,6 @@
5
5
  "version": "1.0",
6
6
  "type": "web",
7
7
  "process_type": "common_before",
8
- "sort": 1
8
+ "sort": 1,
9
+ "state": 0
9
10
  }
@@ -48,10 +48,12 @@ class Event {
48
48
  if (config.event && $.event_admin) {
49
49
  // 创建一个API事件
50
50
  var apis = $.event_admin('api', 'API事件');
51
- apis.update();
52
- for (var k in this.events) {
53
- this.events[k] = apis["list_" + k];
51
+ apis.update_after = () => {
52
+ for (var k in this.events) {
53
+ this.events[k] = apis["list_" + k];
54
+ }
54
55
  }
56
+ apis.update();
55
57
  };
56
58
 
57
59
  /**
package/package.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "mm_os",
3
- "version": "2.1.9",
3
+ "version": "2.2.1",
4
4
  "description": "这是超级美眉服务端框架,用于快速构建应用程序。",
5
5
  "main": "index.js",
6
6
  "scripts": {
7
7
  "test": "cross-env NODE_ENV=test node ./demo/index.js",
8
- "start": "node ./demo/index.js",
8
+ "start": "node --trace-warnings ./demo/index.js",
9
9
  "dev": "cross-env NODE_ENV=development nodemon ./demo/index.js"
10
10
  },
11
11
  "repository": {
@@ -41,7 +41,7 @@
41
41
  "mm_html": "^1.1.6",
42
42
  "mm_koa_proxy": "^1.0.0",
43
43
  "mm_logs": "^1.1.4",
44
- "mm_machine": "^1.6.5",
44
+ "mm_machine": "^1.7.2",
45
45
  "mm_mongodb": "^1.4.2",
46
46
  "mm_mqtt": "^1.0.6",
47
47
  "mm_mysql": "^1.8.0",