mm_os
Version:
MM_OS服务端架构,用于快速构建应用程序,支持网站建设、小程序后台、AI应用、物联网(IOT/AIOT)、游戏服务端等多种场景。
723 lines (670 loc) • 18 kB
JavaScript
/**
* 查询个人记录
* @param {string} clientid 客户端ID
* @param {object} param 查询参数
* @returns {object} 执行结果
*/
exports.getLog = async function(clientid, param) {
var res = await this.push('GetRecordsByPicOrID', clientid, param);
return res;
};
/**
* 考勤打卡
* @param {string} clientid 客户端ID
* @param {object} uuid 用户唯一标识
* @param {string} avatar base64头像
* @returns {object} 执行结果
*/
exports.signIn = async function(clientid, uuid, avatar) {
var res = await this.push('PullRecordOnlyPic', clientid, {
'personID': uuid,
'picinfo': avatar
});
if (!res || res.result == 'fail') {
return '打卡失败!';
}
};
/**
* 下发二维码(没用到)
* @param {string} clientid 客户端ID
* @param {object} param 二维码参数
* @returns {object} 执行结果
*/
exports.pushQrcode = function(clientid, param) {
return this.push('ShowQRCode', clientid, param);
};
/**
* 以图搜人
* @param {string} clientid 客户端ID
* @param {object} avatar 人脸照片
* @returns {object} 执行结果
*/
exports.getMemberPic = async function(clientid, avatar) {
var res = await this.push('GetPictureSearch', clientid, {
'facesluiceId': clientid,
'MaxSimilarity': 80,
'MaxNum': 1,
'picinfo': avatar
});
var user;
if (res) {
if (res.result == 'fail') {
} else {
var u = res.SearchInfo[0];
var name = u.name || u.persionName;
var custom_id = u.customId.trim();
var phone = (u.telnum || '').trim();
var idcard = (u.idCard || '').trim();
user = {
name,
custom_id,
phone,
idcard
};
}
}
return user;
};
/**
* 远程开门
* @param {string} clientid 客户端ID
* @param {string} uuid 用户唯一标识
* @param {boolean} pass 是否可通行 true为是
* @param {string} tip 提示信息
* @returns {object} 执行结果
*/
exports.unlock = async function(clientid, uuid = '0', pass = false, tip = '没有访问权限') {
var res = await this.push('Unlock', clientid, {
'uid': uuid,
// 0不开门,1开门
'openDoor': pass ? '1' : '0',
'showInfo': tip
});
if (!res || res.result == 'fail') {
return '非内部人员!';
}
};
/**
* 远程锁门(没用到)
* @param {string} clientid 客户端ID
* @param {string} uuid 用户唯一标识
* @param {boolean} pass 是否可通行 true为是
* @param {string} tip 提示信息
* @returns {object} 执行结果
*/
exports.lock = async function(clientid, uuid = '0', pass = false, tip = '没有访问权限') {
var res = await this.push('Lock', clientid, {
'uid': uuid,
'showInfo': tip
});
if (!res || res.result == 'fail') {
return '已锁门!';
}
};
/**
* 删除成员
* @param {string} clientid 客户端ID
* @param {string} uuid 用户唯一标识
* @returns {object} 执行结果
*/
exports.delMember = async function(clientid, uuid) {
var res = await this.push('DeletePersons', clientid, {
'customId': uuid
});
return res;
};
/**
* 批量删除成员
* @param {string} clientid 客户端ID
* @param {object} arr 成员列表
* @param {number} longtime 超时回馈
* @returns {object} 执行结果
*/
exports.delMemberBatch = async function(clientid, arr, longtime) {
var res = await this.push('DeletePersons', clientid, {
begin: 'BeginFlag',
end: 'EndFlag',
person_num: arr.length.toString(),
customId: arr
}, longtime);
var result;
var error = 0;
var success = 0;
var error_info = [];
var success_info = [];
if (res) {
if (res.result == 'ok') {
var now = new Date().toStr('yyyy-MM-dd hh:mm:ss');
error = number(res.DelErrNum);
success = number(res.DelSucNum);
error_info = res.DelErrInfo.map((o) => {
o.time_create = now;
return o;
});
success_info = res.DelSucInfo.map((o) => {
o.time_create = now;
return o;
});
result = res.result;
} else if (res.detail && res.detail.indexOf('busy') === -1) {
result = 'fail';
}
}
return {
error,
success,
error_info,
success_info,
result
};
return;
};
/**
* 重启设备
* @param {string} clientid 设备sn
* @returns {object} 执行结果
*/
exports.rebootDevice = async function(clientid) {
var res = await this.push('RebootDevice', clientid, {});
if (!res || res.result == 'ok') {
return;
}
return '重启设备失败';
};
/**
* 设置设备时间
* @param {string} clientid 设备sn
* @param {string} datetime 日期时间 格式为yyyy-MM-dd hh:mm:ss
* @returns {object} 执行结果
*/
exports.setDeviceTime = async function(clientid, datetime) {
var res = await this.push('SetSysTime', clientid, {
'SysTime': datetime.replace(' ', 'T')
});
if (!res || res.result == 'ok') {
return;
}
return '重置时间失败';
};
/**
* 恢复出厂设置
* @param {string} clientid 设备sn
* @param {boolean} record 是否恢复控制记录,true为恢复
* @param {boolean} member 是否恢复成员,true为恢复
* @param {boolean} log 是否恢复请求日志,true为恢复
* @returns {object} 执行结果
*/
exports.resetDevice = async function(clientid, record = true, member = false, log = true) {
var res = await this.push('SetFactoryDefault', clientid, {
defalt_record: record ? '1' : '0',
defalt_person: member ? '1' : '0',
defalt_log: log ? '1' : '0'
});
if (!res || res.result == 'ok') {
return;
}
return '恢复出厂设置失败';
};
/**
* 查询下发进度
* @param {string} clientid 设备sn
* @param {string} mode 查询方式 默认为更新
* @returns {object} 执行结果
*/
exports.getProgress = async function(clientid, mode = 'update') {
var type = '';
if (mode == 'update') {
type = 'EditPersonsNew';
} else {
type = 'DeletePersons';
}
var res = await this.push('QueryProgress', clientid, {
'QueryType': type
});
if (res) {
if (res.Status !== '0') {
return 1;
} else {
return 0;
}
}
return -1;
};
/**
* 考勤补卡
* @param {string} clientid 设备sn
* @param {string} uuid 用户唯一标识
* @param {string} time 时间
* @param {string} avatar 头像
* @returns {object} 执行结果
*/
exports.replacement = async function(clientid, uuid, time, avatar) {
var res = await this.push('PullRecordOnlyPic', clientid, {
'personID': uuid,
'time': time,
'picinfo': avatar
});
if (!res || res.result == 'fail') {
return '补卡失败!';
}
return;
};
/**
* 查询人员名单
* @param {string} clientid 客户端ID
* @param {number} longtime 超时回馈
* @returns {object} 执行结果
*/
exports.getMember = function(clientid, longtime = 0) {
return this.push('QueryPerson', clientid, longtime);
};
/**
* 查询人员名单
* @param {string} clientid 客户端ID
* @param {string} uuid 用户唯一标识
* @param {number} longtime 超时回馈
* @returns {object} 人员信息
*/
exports.getMemberOne = function(clientid, uuid, longtime = 0) {
return this.push('QueryPerson', clientid, {
'personId': uuid
}, longtime);
};
/**
* 格式化时间
* @param {*} time 时间值
* @returns {string} 格式化后的时间字符串
*/
exports._formatTime = function(time) {
if (typeof(time) == 'object') {
return time.toStr('yyyy-MM-dd hh:mm:ss');
} else {
return time.toTime().toStr('yyyy-MM-dd hh:mm:ss');
}
};
/**
* 检查时间有效性
* @param {*} time_end 结束时间
* @returns {boolean} 是否有效
*/
exports._isTimeValid = function(time_end) {
if (!time_end) {
return false;
}
var end_time = time_end.toTime();
return end_time > '2021-01-01 00:00:00'.toTime() && end_time <= '2038-01-01 00:00:00'.toTime();
};
/**
* 设置时间有效性
* @param {object} obj 目标对象
* @param {object} m 成员对象
* @returns {object} 修改后的对象
*/
exports._setTimeValidity = function(obj, m) {
var result = { ...obj };
if (this._isTimeValid(m.time_valid_end)) {
result.cardValidBegin = this._formatTime(m.time_valid_start);
result.cardValidEnd = this._formatTime(m.time_valid_end);
result.tempCardType = 1;
} else {
result.tempCardType = 0;
}
return result;
};
/**
* 创建基础成员对象
* @param {object} m 原始的成员对象
* @returns {object} 基础成员对象
*/
exports._createBaseMember = function(m) {
var nfc = m.nfc || '';
return {
'customId': m.customId,
'name': m.name,
'native': m.place || '',
'nation': m.nation || '',
'address': m.address || '',
'idCard': m.idcard || '',
'gender': m.sex - 1,
'phone': m.phone,
'birthday': m.birthday,
'cardType2': 2,
'cardNum2': nfc,
'RFCardMode': 0,
'RFIDCard': nfc,
'notes': '',
'personType': m.state == 4 ? 1 : 0,
'cardType': 0,
'picURI': this.fullUrl(m.avatar)
};
};
/**
* 成员模型
* @param {object} m 原始的成员对象
* @returns {object} 转换后的成员对象
*/
exports.memberModelOut = function(m) {
var obj = this._createBaseMember(m);
this._setTimeValidity(obj, m);
return obj;
};
/**
* 添加时间戳到信息列表
* @param {Array} list 信息列表
* @param {string} now 当前时间
* @returns {Array} 处理后的列表
*/
exports._addTimeToList = function(list, now) {
return list.map((o) => {
o.time_create = now;
return o;
});
};
/**
* 解析批量操作结果
* @param {object} res 响应结果
* @returns {object} 解析后的结果
*/
exports._parseBatch = function(res) {
var result;
var error = 0;
var success = 0;
var error_info = [];
var success_info = [];
if (res) {
if (res.result == 'ok') {
var now = new Date().toStr('yyyy-MM-dd hh:mm:ss');
error = number(res.AddErrNum);
success = number(res.AddSucNum);
error_info = this._addTimeToList(res.AddErrInfo, now);
success_info = this._addTimeToList(res.AddSucInfo, now);
result = res.result;
} else if (res.detail && res.detail.indexOf('busy') === -1) {
result = 'fail';
}
}
return {
error,
success,
error_info,
success_info,
result
};
};
/**
* 批量下发人员名单
* @param {string} clientid 客户端ID
* @param {Array} list 人员名单
* @param {number} longtime 超时回馈
* @returns {object} 执行结果
*/
exports.updateMemberBatch = async function(clientid, list, longtime = 180) {
var res = await this.pushS(clientid, {
'messageId': this.getMsgid('EditPersonsNew'),
'DataBegin': 'BeginFlag',
'DataEnd': 'EndFlag',
'operator': 'EditPersonsNew',
'PersonNum': list.length,
'info': list.map((o) => {
return this.memberModelOut(o);
})
}, longtime);
return this._parseBatch(res);
};
/**
* 下发人员名单
* @param {string} clientid 设备ID
* @param {object} user 人员信息
* @param {number} longtime 超时回馈
* @returns {object} 执行结果
*/
exports.updateMember = function(clientid, user, longtime = 0) {
return this.pushS(clientid, {
'messageId': this.getMsgid('EditPerson'),
'DataBegin': 'BeginFlag',
'DataEnd': 'EndFlag',
'method': 'EditPerson',
'info': this.memberModelOut(user)
}, longtime);
};
/**
* 初始化函数, 用于定义开放给前端的函数
*/
exports.init = function() {
var m = this.methods;
_regBasicMethods(m, this);
_regDeviceMethods(m, this);
_regRecordMethods(m, this);
};
/**
* 注册基本方法
* @param {object} m 方法对象
* @param {object} self 实例
* @private
*/
var _regBasicMethods = function(m, self) {
m['HeartBeat'] = function(clientid, params) {
if (!self.drives[clientid]) {
self.drives[clientid] = {};
}
self.drives[clientid].online = 1;
self.drives[clientid].time_last = new Date().getTime();
// console.log("心跳", clientid, self.drives[clientid]);
};
/**
* 离线通知
* @param {string} clientid 设备sn
* @param {object} params 设备信息
*/
m['Offline'] = async function(clientid, params) {
self.updateOnline(clientid, 0);
// console.log("离线", clientid, self.drives[clientid]);
};
/**
* 在线通知
* @param {string} clientid 设备sn
* @param {object} params 设备信息
* @returns {object} 执行结果
*/
m['Online'] = async function(clientid, params) {
await self.updateOnline(clientid, 1, params.ip);
return {
'facesluiceId': clientid,
'result': 'ok',
'detail': ''
};
};
};
/**
* 注册设备方法
* @param {object} m 方法对象
* @param {object} self 实例
* @private
*/
var _regDeviceMethods = function(m, self) {
/**
* 更新人体生命体征,如温度、湿度、位置、
* @param {string} clientid 设备sn
* @param {object} params 设备信息
*/
m['life'] = async function(clientid, params) {
self.updateLife(clientid, {
// 心率
heart_rate: 0,
// 睡眠状态 是深度睡眠还是浅睡眠
sleep: 0,
// 血氧饱和度
oxygen: 0,
// 行走步数
step: 0,
// 压力
pressure: 0,
// 时间戳
timestamp: 0,
// GPS横坐标,保留生命体脱下设备时的最后位置
gps_x: 0,
// GPS纵坐标,保留生命体脱下设备时的最后位置
gps_y: 0
});
// console.log("离线", clientid, _this.drives[clientid]);
};
/**
* 更新设备信息,如温度、湿度、位置
* @param {string} clientid 设备sn
* @param {object} params 设备信息
*/
m['info'] = async function(clientid, params) {
self.updateDeviceInfo(clientid, {
// 温度
temperature: 0,
// 湿度
humidity: 0,
// 氧气
oxygen: 0,
// 二氧化碳
carbon_dioxide: 0,
// 光照强度
light: 0,
// 烟雾浓度
smoke: 0,
// 压力
pressure: 0,
// 光敏
photosensitive: 0,
// 声波
acoustic_wave: 0,
// 磁力
magnetism: 0,
// 火焰
flame: 0,
// 震动
vibrate: 0,
// 时间戳
timestamp: 0,
// GPS横坐标
gps_x: 0,
// GPS纵坐标
gps_y: 0
});
// console.log("离线", clientid, _this.drives[clientid]);
};
};
/**
* 获取记录类型
* @param {string} otype 操作类型
* @returns {number} 记录类型
* @private
*/
var _getRecordType = function(otype) {
var typeMap = {
'7': 2, '27': 2,
'47': 3, '48': 3, '55': 3, '56': 3, '57': 3,
'21': 4, '22': 4, '24': 4, '25': 4
};
return typeMap[otype] || 1;
};
/**
* 发送确认消息
* @param {string} clientid 设备sn
* @param {string} record_id 记录ID
* @param {object} self 实例
* @private
*/
var _sendAck = function(clientid, record_id, self) {
self.send(`mqtt/face/${clientid}`, {
'messageId': self.getMsgid('PushAck'),
'operator': 'PushAck',
'info': {
'PushAckType': '2',
'SnapOrRecordID': record_id
}
});
};
/**
* 获取 NFC
* @param {object} params 上报参数
* @returns {string} NFC
* @private
*/
var _getNfc = function(params) {
var nfc = (params.cardNum2 || params.RFIDCard || '').trim();
return nfc == '0' ? '' : nfc;
};
/**
* 格式化时间
* @param {string|object} time 时间
* @returns {string} 格式化后的时间
* @private
*/
var _formatTime = function(time) {
if (typeof(time) == 'object') {
return time.toStr('yyyy-MM-dd hh:mm:ss');
}
return time.toTime().toStr('yyyy-MM-dd hh:mm:ss');
};
/**
* 创建日志对象
* @param {object} params 上报参数
* @param {string} clientid 设备sn
* @param {number} type 记录类型
* @returns {object} 日志对象
* @private
*/
var _createLog = function(params, clientid, type) {
var name = params.persionName || params.name;
if (!name) {
return null;
}
return {
custom_id: params.customId.trim(),
name,
phone: (params.telnum || '').trim(),
idcard: (params.idCard || '').trim(),
nfc: _getNfc(params),
clientid,
type,
person_type: params.PersonType == '1' ? 2 : 1,
record_type: params.RecordType ? number(params.RecordType) + 1 : 1,
action: '刷脸验证',
time: _formatTime(params.time),
avatar: params.pic || ''
};
};
/**
* 注册记录方法
* @param {object} m 方法对象
* @param {object} self 实例
* @private
*/
var _regRecordMethods = function(m, self) {
/**
* 上报
* @param {string} clientid 设备sn
* @param {object} params 上报参数
* @param {object} msg 上报消息
* @param {string} id 消息ID
*/
m['RecPush'] = async function(clientid, params, msg, id) {
_sendAck(clientid, params.RecordID, self);
var type = _getRecordType(params.otype);
if (type == 2) {
return;
}
var log = _createLog(params, clientid, type);
if (log) {
$.server.execLog(clientid, log);
}
};
m['QRCodePush'] = async function(clientid, params, msg, id) {
var qrcode = params.QRCodeInfo;
var {
uuid,
pass,
tip,
device
} = await $.server.execQrcode(clientid, qrcode);
if (device && device.online) {
await self.unlock(clientid, uuid, pass, tip);
}
};
};