import dxCommonUtils from "../../dxmodules/dxCommonUtils.js";
|
import dxos from "../../dxmodules/dxOs.js";
|
import config from "../../dxmodules/dxConfig.js";
|
import dxMap from "../../dxmodules/dxMap.js";
|
import logger from "../../dxmodules/dxLogger.js";
|
import ota from "../../dxmodules/dxOta.js";
|
import std from "../../dxmodules/dxStd.js";
|
import driver from "../driver.js";
|
import configService from "./configService.js";
|
import sqliteService from "./sqliteService.js";
|
import utils from '../common/utils/utils.js'
|
import bus from '../../dxmodules/dxEventBus.js'
|
import faceService from "./faceService.js";
|
import dxDriver from "../../dxmodules/dxDriver.js";
|
const api = {}
|
|
|
//远程控制
|
api.control = function (payload) {
|
let data = payload.data
|
switch (data.command) {
|
case 0:
|
//重启
|
dxos.asyncReboot(2)
|
break
|
case 1:
|
//远程开门
|
driver.gpio.open()
|
break
|
case 4:
|
//重置
|
dxos.systemBrief("rm -rf /app/data/config/*")
|
dxos.systemBrief("rm -rf /app/data/db/*")
|
dxos.systemBrief("rm -rf /data/*")
|
if (driver.device.finger) {
|
driver.finger.clear()
|
}
|
dxos.asyncReboot(2)
|
return
|
case 5:
|
//播放语音
|
// if (!isEmpty(payload.extra.wav) && typeof payload.extra.wav == 'string') {
|
// vf203.alsa.play("/app/code/resource/wav/" + payload.extra.wav)
|
// }
|
break
|
case 6:
|
// 6:屏幕展示图片
|
// TODO
|
break
|
case 7:
|
// 7:屏幕展示文字
|
// TODO
|
break
|
case 8:
|
// 8:抓拍人脸
|
bus.fire("resetTimers")
|
std.setTimeout(() => {
|
bus.fire("weComTackFace", payload)
|
}, 500)
|
break
|
case 10:
|
if (!isEmpty(data.extra.qrCodeBase64) && typeof data.extra.qrCodeBase64 == 'string') {
|
//base64转图片保存
|
let src = `/app/code/resource/image/app_qrcode.png`
|
std.ensurePathExists(src)
|
dxCommonUtils.fs.base64ToFile(src, data.extra.qrCodeBase64)
|
}
|
break
|
case 11:
|
// 企业微信绑定状态通知
|
bus.fire("weComIsBind", payload)
|
break
|
case 12:
|
if(!driver.device.finger){
|
return
|
}
|
if(!isEmpty(data.extra.fingerprintAction)) {
|
if (data.extra.fingerprintAction == 0) {
|
// 远程指纹录入
|
bus.fire("enrollFinger", payload)
|
} else if (data.extra.fingerprintAction == 1) {
|
// 中止录入
|
bus.fire("interruptFinger")
|
}
|
}
|
break
|
case 13:
|
if (!isEmpty(data.extra.wallpaperBase64) && typeof data.extra.wallpaperBase64 == 'string') {
|
//base64转图片保存
|
let src = `/app/code/resource/image/${dxDriver.DRIVER.MODEL}/idleImage.png`
|
std.ensurePathExists(src)
|
dxCommonUtils.fs.base64ToFile(src, data.extra.wallpaperBase64)
|
bus.fire("resetTimers")
|
}
|
break
|
}
|
return true
|
}
|
|
//查询配置
|
api.getConfig = function (data) {
|
let configAll = config.getAll()
|
let res = {}
|
// 配置分组
|
for (const key in configAll) {
|
const value = configAll[key];
|
const keys = key.split(".")
|
if (keys.length == 2) {
|
if (!res[keys[0]]) {
|
res[keys[0]] = {}
|
}
|
res[keys[0]][keys[1]] = value
|
} else {
|
res[keys[0]] = value
|
}
|
}
|
let diskStats = dxCommonUtils.getDiskStats()
|
res.sys = {
|
// 保留原有的 sysInfo 中的其他值
|
...res.sys,
|
totaldisk: diskStats.total,
|
freedisk: diskStats.free,
|
useddisk: diskStats.used
|
};
|
filterSpecificProperties(res)
|
if (isEmpty(data) || typeof data != "string" || data == "") {
|
if (res.mqtt && res.mqtt.clientId) {
|
res.mqtt.clientId = dxMap.get("CLIENT").get("CLIENT_ID")
|
}
|
// 查询全部
|
return res
|
}
|
// 单条件查询"data": "mqttInfo.clientId"
|
let keys = data.split(".")
|
let search = {}
|
if (keys.length == 2) {
|
const [group, field] = keys
|
if (res[group] && res[group][field] !== undefined) {
|
search[group] = {}
|
search[group][field] = res[group][field]
|
}
|
} else {
|
const group = keys[0]
|
if (res[group]) {
|
search[group] = res[group]
|
}
|
}
|
filterSpecificProperties(search)
|
if (search.mqtt && search.mqtt.clientId) {
|
search.mqtt.clientId = dxMap.get("CLIENT").get("CLIENT_ID")
|
}
|
return search
|
}
|
|
// 配置项过滤函数
|
function filterSpecificProperties(configObj) {
|
if (!configObj || typeof configObj !== 'object') return;
|
let propertiesToRemove = [
|
'sys.restartCount',
|
'sys.weComStatus',
|
'sys.weComMqttAddr',
|
'sys.bleKey',
|
'sys.devType'
|
];
|
if (dxDriver.DRIVER.MODEL == "vf105" || dxDriver.DRIVER.MODEL == "vf114") {
|
if (driver.device.finger) {
|
propertiesToRemove.push('sys.scanInterval')
|
}
|
} else {
|
propertiesToRemove.push('sys.scanInterval')
|
}
|
propertiesToRemove.forEach(propPath => {
|
const [group, field] = propPath.split('.');
|
if (configObj[group] && configObj[group][field] !== undefined) {
|
delete configObj[group][field];
|
}
|
});
|
}
|
|
//修改配置
|
api.setConfig = function (data) {
|
if (!data || typeof data != 'object') {
|
return "data should not be empty"
|
}
|
let res = configService.configVerifyAndSave(data)
|
if (typeof res != 'boolean') {
|
// 返回错误信息
|
return res
|
}
|
if (res) {
|
return res
|
} else {
|
return "unknown failure"
|
}
|
}
|
|
//升级固件
|
api.upgradeFirmware = function (data) {
|
if (!data || typeof data != 'object' || typeof data.type != 'number' || typeof data.url != 'string' || typeof data.md5 != 'string') {
|
return "data's params error"
|
}
|
if (data.type == 0) {
|
try {
|
driver.screen.upgrade({ title: "confirm.upgrade", content: "confirm.upgrading" })
|
ota.updateHttp(data.url, data.md5, 100)
|
driver.screen.upgrade({ title: "confirm.upgrade", content: "confirm.upgradeSuccess" })
|
} catch (error) {
|
driver.screen.upgrade({ title: "confirm.upgrade", content: "confirm.upgradeFail" })
|
return "upgrade failure"
|
}
|
dxos.asyncReboot(3)
|
return
|
}
|
}
|
|
//查询识别记录
|
api.getRecords = function (data, flag) {
|
if (typeof data.page !== 'number' || data.page < 0) {
|
return "Invalid parameter: 'page' must be a number >= 0"
|
}
|
if (typeof data.size !== 'number' || data.size <= 0 || data.size > 1000) {
|
return "Invalid parameter: 'size' must be a number between 1 and 1000";
|
}
|
if (data.startTime && typeof data.startTime != 'number') {
|
return "Invalid parameter: 'startTime' must be a number"
|
}
|
if (data.endTime && typeof data.endTime != 'number') {
|
return "Invalid parameter: 'endTime' must be a number"
|
}
|
if (data.userId && !Array.isArray(data.userId)) {
|
return "Invalid parameter: 'userId' must be an array"
|
}
|
if (data.recordId && !Array.isArray(data.recordId)) {
|
return "Invalid parameter: 'recordId' must be an array"
|
}
|
// 处理人员姓名查询条件
|
let userIds = [];
|
if (data.name) {
|
let persons = sqliteService.d1_person.findAll({ name: data.name.trim() })
|
if (persons && persons.length) {
|
userIds = persons.map(person => person.userId)
|
} else {
|
// 找不到人员直接返回空
|
return {
|
page: data.page,
|
size: data.size,
|
total: 0,
|
totalPage: 0,
|
count: 0,
|
content: []
|
}
|
}
|
}
|
// 处理人员ID查询条件
|
if (data.userId && data.userId.length > 0) {
|
if (data.userId[0] !== -1) {
|
// 如果已经通过姓名查询得到了userIds,则取交集;否则使用传入的userIds
|
if (userIds.length > 0) {
|
userIds = userIds.filter(id => data.userId.includes(id));
|
} else {
|
userIds = data.userId;
|
}
|
}
|
// 如果传入的是[-1],表示查询所有,userIds保持为空数组,表示不按userId过滤
|
}
|
|
// 构建WHERE条件数组
|
let whereConditions = [];
|
|
// 处理人员ID条件
|
if (userIds.length > 0) {
|
let userIdsStr = userIds.map(id => `'${id}'`).join(',');
|
whereConditions.push(`userId IN (${userIdsStr})`);
|
}
|
|
// 处理识别记录ID条件
|
if (data.recordId && data.recordId.length > 0) {
|
let recordIdsStr = data.recordId.map(id => `'${id}'`).join(',');
|
whereConditions.push(`id IN (${recordIdsStr})`);
|
}
|
|
// 处理时间区间查询条件
|
if (data.startTime && data.endTime) {
|
whereConditions.push(`timeStamp >= ${data.startTime} AND timeStamp <= ${data.endTime}`);
|
} else if (data.startTime) {
|
whereConditions.push(`timeStamp >= ${data.startTime}`);
|
} else if (data.endTime) {
|
whereConditions.push(`timeStamp <= ${data.endTime}`);
|
}
|
// 构建WHERE子句
|
let whereClause = whereConditions.length > 0 ? `WHERE ${whereConditions.join(' AND ')}` : '';
|
|
// 计算分页
|
let offset = data.page * data.size;
|
|
// 查询总数
|
let countSql = `SELECT COUNT(*) as total FROM d1_pass_record ${whereClause}`;
|
let countResult = sqliteService.select(countSql);
|
let totalCount = countResult && countResult[0] ? countResult[0].total : 0;
|
|
// 查询记录
|
let recordsSql = `SELECT * FROM d1_pass_record ${whereClause} ORDER BY timeStamp DESC LIMIT ${data.size} OFFSET ${offset}`;
|
let records = sqliteService.select(recordsSql);
|
if (records && records.length > 0) {
|
records.forEach(record => {
|
if (flag) {
|
if (record.type == 300 && std.exist(record.code)) {
|
if (data.size <= 50) {
|
record.code = dxCommonUtils.fs.fileToBase64(record.code)
|
}
|
}
|
}
|
// 关联人员信息
|
if (record.userId) {
|
let person = sqliteService.d1_person.findByUserId(record.userId)
|
if (person.length) {
|
record.name = person[0].name
|
record.extra = person[0].extra
|
}
|
}
|
})
|
} else {
|
records = []
|
}
|
return {
|
page: data.page,
|
size: data.size,
|
total: totalCount,
|
totalPage: Math.ceil(totalCount / data.size),
|
count: records.length,
|
content: records
|
}
|
}
|
|
//删除识别记录
|
api.delRecords = function (data) {
|
if (data.startTime && typeof data.startTime != 'number') {
|
return "Invalid parameter: 'startTime' must be a number"
|
}
|
if (data.endTime && typeof data.endTime != 'number') {
|
return "Invalid parameter: 'endTime' must be a number"
|
}
|
if (data.userId && !Array.isArray(data.userId)) {
|
return "Invalid parameter: 'userId' must be an array"
|
}
|
if (data.recordId && !Array.isArray(data.recordId)) {
|
return "Invalid parameter: 'recordId' must be an array"
|
}
|
// 构建删除条件
|
let whereConditions = [];
|
if (data.recordId && data.recordId.length > 0) {
|
let recordIdsStr = data.recordId.map(id => `'${id}'`).join(',');
|
whereConditions.push(`id IN (${recordIdsStr})`);
|
}
|
if (data.userId && data.userId.length > 0) {
|
let userIdsStr = data.userId.map(id => `'${id}'`).join(',');
|
whereConditions.push(`userId IN (${userIdsStr})`);
|
}
|
if (data.startTime && data.startTime > 0) {
|
whereConditions.push(`timeStamp >= ${data.startTime}`);
|
}
|
if (data.endTime && data.endTime > 0) {
|
whereConditions.push(`timeStamp <= ${data.endTime}`);
|
}
|
let whereClause = `WHERE ${whereConditions.join(' AND ')}`;
|
let selectSql = `SELECT code FROM d1_pass_record ${whereClause}`
|
try {
|
let records = sqliteService.select(selectSql);
|
// 删除对应的图片文件
|
if (records && records.length > 0) {
|
for (let record of records) {
|
if (record.code && record.code.startsWith('/data/passRecord/')) {
|
if (std.exist(record.code)) {
|
dxos.systemBrief(`rm -rf ${record.code}`);
|
}
|
}
|
}
|
}
|
let deleteSql = `DELETE FROM d1_pass_record ${whereClause}`;
|
let ret = sqliteService.exec(deleteSql);
|
if (ret != 0) {
|
return "SQL error ret: " + ret;
|
}
|
return true
|
} catch (error) {
|
logger.error("[delRecords]: " + error);
|
}
|
}
|
|
//添加人员
|
api.insertUser = function (data) {
|
let errors = []
|
for (let i = 0; i < data.length; i++) {
|
const person = data[i];
|
let errorItem = {
|
userId: person.userId || 'unknown',
|
errmsg: ''
|
}
|
if (!person.userId || !person.name) {
|
errorItem.errmsg = "userId or name cannot be empty"
|
errors.push(errorItem)
|
continue
|
}
|
if (person.permissionIds && !Array.isArray(person.permissionIds)) {
|
errorItem.errmsg = "permissionIds should be an array"
|
errors.push(errorItem)
|
continue
|
}
|
let record = {}
|
record.userId = person.userId
|
record.name = person.name
|
record.extra = isEmpty(person.extra) ? JSON.stringify({}) : JSON.stringify(person.extra)
|
record.permissionIds = person.permissionIds ? person.permissionIds.join(",") : ""
|
let ret = sqliteService.d1_person.save(record)
|
if (ret != 0) {
|
sqliteService.d1_person.deleteByUserId(record.userId)
|
ret = sqliteService.d1_person.save(record)
|
if (ret != 0) {
|
errorItem.errmsg = "sql error ret:" + ret
|
errors.push(errorItem)
|
continue
|
}
|
}
|
}
|
if (errors.length > 0) {
|
return errors
|
}
|
return true
|
}
|
|
//删除人员
|
api.delUser = function (data) {
|
let errors = []
|
if (data && data.length > 0) {
|
for (let i = 0; i < data.length; i++) {
|
const userId = data[i]
|
let errorItem = {
|
userId: userId || 'unknown',
|
errmsg: ''
|
}
|
// 删除指纹凭证之前需要先删除指纹库中的指纹
|
let fingerVoucher = sqliteService.d1_voucher.findByuserIdAndType(userId, "500")
|
if (fingerVoucher.length > 0) {
|
logger.info("delUser 查询到的指纹凭证: ", JSON.stringify(fingerVoucher[0]))
|
let ret = driver.finger.delete(parseInt(fingerVoucher[0].code))
|
if (ret != 0) {
|
errorItem.errmsg = "finger delete error ret:" + ret
|
errors.push(errorItem)
|
continue
|
}
|
}
|
let ret1 = sqliteService.d1_person.deleteByUserId(userId)
|
let ret3 = sqliteService.d1_voucher.deleteByUserId(userId)
|
if (ret1 != 0 || ret3 != 0) {
|
errorItem.errmsg = `sql error: person(${ret1}), voucher(${ret3})`
|
errors.push(errorItem)
|
continue
|
}
|
try {
|
driver.face.deleteFea(userId)
|
} catch (error) {
|
logger.error(`Failed to delete face feature for user ${userId}:`, error)
|
}
|
}
|
}
|
if (errors.length > 0) {
|
return errors
|
}
|
return true
|
}
|
|
//查询人员
|
api.getUser = function (data) {
|
if (typeof data.page !== 'number' || data.page < 0) {
|
return "Invalid parameter: 'page' must be a number >= 0"
|
}
|
if (typeof data.size !== 'number' || data.size <= 0 || data.size > 100) {
|
return "Invalid parameter: 'size' must be a number between 1 and 100";
|
}
|
let totalCount = sqliteService.d1_person.count(data)
|
let persons = sqliteService.d1_person.findAll(data)
|
return {
|
content: persons,
|
page: data.page,
|
size: data.size,
|
total: totalCount,
|
totalPage: Math.ceil(totalCount / data.size),
|
count: persons.length
|
}
|
}
|
|
//清空人员
|
api.clearUser = function () {
|
let ret1 = sqliteService.d1_person.deleteAll()
|
let ret2 = sqliteService.d1_permission.deleteAll()
|
let ret3 = sqliteService.d1_voucher.deleteAll()
|
if(driver.device.finger){
|
let ret4 = driver.finger.clear()
|
if (ret4 != 0) {
|
return "finger clear error ret:" + ret4
|
}
|
}
|
try {
|
driver.face.clean()
|
} catch (error) {
|
return error.message
|
}
|
if (ret1 == 0 && ret2 == 0 && ret3 == 0) {
|
return true
|
} else {
|
return "sql error"
|
}
|
}
|
|
//修改人员
|
api.modifyUser = function (data) {
|
let errors = []
|
for (let i = 0; i < data.length; i++) {
|
const person = data[i];
|
let errorItem = {
|
userId: person.userId || 'unknown',
|
errmsg: ''
|
}
|
if (!person.userId || !person.name) {
|
errorItem.errmsg = "userId or name cannot be empty"
|
errors.push(errorItem)
|
continue
|
}
|
if (person.permissionIds && !Array.isArray(person.permissionIds)) {
|
errorItem.errmsg = "permissionIds should be an array"
|
errors.push(errorItem)
|
continue
|
}
|
let record = {}
|
record.userId = person.userId
|
record.name = person.name
|
record.extra = isEmpty(person.extra) ? JSON.stringify({}) : JSON.stringify(person.extra)
|
record.permissionIds = person.permissionIds ? person.permissionIds.join(",") : ''
|
let ret = sqliteService.d1_person.updateAllByUserId(record, record.userId)
|
if (ret != 0) {
|
errorItem.errmsg = "sql error ret:" + ret
|
errors.push(errorItem)
|
continue
|
}
|
}
|
if (errors.length > 0) {
|
return errors
|
}
|
return true
|
}
|
|
//添加凭证
|
api.insertKey = function (data) {
|
let errors = []
|
for (let i = 0; i < data.length; i++) {
|
const voucher = data[i];
|
let errorItem = {
|
keyId: voucher.keyId || 'unknown',
|
errmsg: ''
|
}
|
if (!voucher.keyId || !voucher.type || !voucher.code || !voucher.userId) {
|
errorItem.errmsg = "keyId or type or code or userId cannot be empty"
|
errors.push(errorItem)
|
continue
|
}
|
// 凭证重复
|
let ret = sqliteService.d1_voucher.findByCodeAndType(voucher.code, voucher.type)
|
if (ret.length > 0 && ret[0].userId != voucher.userId) {
|
errorItem.errmsg = "Duplicate vouchers"
|
errors.push(errorItem)
|
continue
|
}
|
if (voucher.type == "200" || voucher.type == "201" || voucher.type == "202") {
|
voucher.code = voucher.code.toUpperCase()
|
}
|
if (voucher.type == "300" && voucher.extra.faceType != 0 && voucher.extra.faceType != 1) {
|
errorItem.errmsg = "faceType Incorrect format"
|
errors.push(errorItem)
|
continue
|
}
|
if (voucher.type == "400") {
|
if (voucher.code.length != 6) {
|
errorItem.errmsg = "Password length must be 6 digits"
|
errors.push(errorItem)
|
continue
|
}
|
}
|
// // 判断指纹凭证是否重复,如果没有重复就录入指纹
|
// if (voucher.type == "500") {
|
// voucher.code = parseInt(voucher.code)
|
// let index = driver.finger.insert(voucher.code)
|
// if(index < 0){
|
// errorItem.errmsg = "finger insert error ret:" + index
|
// errors.push(errorItem)
|
// continue
|
// }
|
// voucher.code = index
|
// }
|
let record = {}
|
record.keyId = voucher.keyId
|
record.type = voucher.type
|
if (voucher.type == "300") {
|
let faceRegistrationSuccess = false
|
if (voucher.extra.faceType == 0) {
|
try {
|
record.code = `/data/user/${voucher.userId}/register.jpg`
|
try {
|
// 保存base64图片
|
std.ensurePathExists(record.code)
|
dxCommonUtils.fs.base64ToFile(record.code, voucher.code)
|
} catch (error) {
|
errorItem.errmsg = "文件保存失败"
|
errors.push(errorItem)
|
continue
|
}
|
try {
|
// 提取特征值
|
let featureFile = driver.face.getFeaByFile(record.code)
|
let addFeaRes = driver.face.addFea(voucher.userId, featureFile.feature)
|
if (addFeaRes != 0) {
|
logger.info("第一次人脸注册失败")
|
// 删除重新注册
|
driver.face.deleteFea(voucher.userId)
|
let addFeaResAgain = driver.face.addFea(voucher.userId, featureFile.feature)
|
if (addFeaResAgain == 0) {
|
logger.info("第二次注册人脸成功")
|
faceRegistrationSuccess = true
|
} else {
|
errorItem.errmsg = addFeaResAgain
|
errors.push(errorItem)
|
continue
|
}
|
} else {
|
faceRegistrationSuccess = true
|
}
|
} catch (error) {
|
logger.info(error.message)
|
errorItem.errmsg = error.message
|
errors.push(errorItem)
|
continue
|
}
|
} catch (unexpectedError) {
|
errorItem.errmsg = unexpectedError.message
|
errors.push(errorItem)
|
continue
|
}
|
} else {
|
record.code = voucher.code
|
//特征值注册
|
try {
|
let addFeaRes = driver.face.addFea(voucher.userId, voucher.code)
|
if (addFeaRes != 0) {
|
logger.info("第一次人脸注册失败")
|
// 删除重新注册
|
driver.face.deleteFea(voucher.userId)
|
let addFeaResAgain = driver.face.addFea(voucher.userId, voucher.code)
|
if (addFeaResAgain == 0) {
|
logger.info("第二次注册人脸成功")
|
faceRegistrationSuccess = true
|
} else {
|
errorItem.errmsg = addFeaResAgain
|
errors.push(errorItem)
|
continue
|
}
|
} else {
|
faceRegistrationSuccess = true
|
}
|
} catch (error) {
|
errorItem.errmsg = error.message
|
errors.push(errorItem)
|
continue
|
}
|
}
|
// 如果人脸注册失败,直接继续下一个凭证
|
if (!faceRegistrationSuccess) {
|
continue
|
}
|
} else {
|
// 如果之前有同类型的指纹凭证,则需要先删除,因为一个人只能有一个指纹凭证
|
if(voucher.type == "500"){
|
let oldVoucher = sqliteService.d1_voucher.findByuserIdAndType(voucher.userId, "500");
|
if (oldVoucher.length > 0) {
|
logger.info("insertKey 删除旧指纹凭证: ", JSON.stringify(oldVoucher[0]))
|
try {
|
let ret = driver.finger.delete(parseInt(oldVoucher[0].code))
|
if (ret != 0) {
|
errorItem.errmsg = "finger delete error ret:" + ret
|
errors.push(errorItem)
|
continue
|
}
|
} catch (error) {
|
errorItem.errmsg = error.message
|
errors.push(errorItem)
|
continue
|
}
|
}
|
try {
|
let index = driver.finger.insert(voucher.code)
|
if(index < 0){
|
errorItem.errmsg = "insertKey finger insert error ret:" + index
|
errors.push(errorItem)
|
continue
|
} else{
|
voucher.code = index
|
}
|
} catch (error) {
|
errorItem.errmsg = error.message
|
errors.push(errorItem)
|
continue
|
}
|
}
|
record.code = voucher.code
|
let ret = sqliteService.d1_voucher.findAllByCodeAndType(voucher.code, voucher.type)
|
if (ret.length != 0) {
|
let ret1 = sqliteService.d1_voucher.updateAllByKeyId(record, record.keyId)
|
if (ret1 != 0) {
|
errorItem.errmsg = "sql error ret:" + ret1
|
errors.push(errorItem)
|
continue
|
}
|
continue
|
}
|
}
|
record.userId = voucher.userId
|
record.extra = isEmpty(voucher.extra) ? JSON.stringify({ type: 0 }) : JSON.stringify(voucher.extra)
|
let ret2 = sqliteService.d1_voucher.save(record)
|
if (ret2 != 0) {
|
sqliteService.d1_voucher.deleteByKeyId(record.keyId)
|
ret2 = sqliteService.d1_voucher.save(record)
|
if (ret2 != 0) {
|
// 如果是指纹,应该先把旧指纹删除,再录入新指纹
|
if (record.type == "500") {
|
driver.finger.delete(parseInt(voucher.code))
|
}
|
errorItem.errmsg = "sql error ret:" + ret2
|
errors.push(errorItem)
|
continue
|
}
|
}
|
}
|
if (errors.length > 0) {
|
return errors
|
}
|
return true
|
}
|
|
//查询凭证
|
api.getKey = function (data) {
|
if (typeof data.page !== 'number' || data.page < 0) {
|
return "Invalid parameter: 'page' must be a number >= 0"
|
}
|
if (typeof data.size !== 'number' || data.size <= 0 || data.size > 100) {
|
return "Invalid parameter: 'size' must be a number between 1 and 100";
|
}
|
let totalCount = sqliteService.d1_voucher.count(data)
|
let vouchers = sqliteService.d1_voucher.findAll(data)
|
vouchers.forEach(element => {
|
if (element.type == 300 && element.extra && JSON.parse(element.extra).faceType == 0) {
|
//人脸特殊处理一下
|
element.code = dxCommonUtils.fs.fileToBase64(element.code)
|
}
|
});
|
return {
|
content: vouchers,
|
page: data.page,
|
size: data.size,
|
total: totalCount,
|
totalPage: Math.ceil(totalCount / data.size),
|
count: vouchers.length
|
}
|
}
|
|
//删除凭证
|
api.delKey = function (data) {
|
let errors = []
|
if (data.keyIds && data.keyIds.length > 0) {
|
for (let i = 0; i < data.keyIds.length; i++) {
|
const keyId = data.keyIds[i];
|
let errorItem = {
|
keyId: keyId || 'unknown',
|
errmsg: ''
|
}
|
let res = sqliteService.d1_voucher.findAllByKeyId(keyId)
|
logger.info("delKey 要删除的凭证: ", JSON.stringify(res))
|
if (res.length <= 0) {
|
errorItem.errmsg = "voucher not found"
|
errors.push(errorItem)
|
continue
|
}
|
if (res[0].type == 300) {
|
try {
|
driver.face.deleteFea(res[0].userId)
|
dxos.systemBrief("rm -rf /data/user/" + res[0].userId)
|
} catch (error) {
|
logger.error(`Failed to delete face feature for user ${res[0].userId}:`, error)
|
}
|
}
|
if(res[0].type == "500"){
|
logger.info("delKey 要删除的指纹凭证ID: ", parseInt(res[0].code))
|
let ret = driver.finger.delete(parseInt(res[0].code))
|
if (ret != 0) {
|
errorItem.errmsg = "finger delete error ret:" + ret
|
errors.push(errorItem)
|
continue
|
}
|
}
|
let ret = sqliteService.d1_voucher.deleteByKeyId(keyId)
|
if (ret != 0) {
|
errorItem.errmsg = "sql error ret:" + ret
|
errors.push(errorItem)
|
continue
|
}
|
}
|
|
}
|
if (data.userIds && data.userIds.length > 0) {
|
for (let i = 0; i < data.userIds.length; i++) {
|
const userId = data.userIds[i];
|
let errorItem = {
|
userId: userId || 'unknown',
|
errmsg: ''
|
}
|
let oldVoucher = sqliteService.d1_voucher.findByuserIdAndType(userId, "500");
|
if (oldVoucher.length > 0) {
|
logger.info("delKey oldVoucher要删除的凭证: ", JSON.stringify(oldVoucher[0]))
|
let ret = driver.finger.delete(parseInt(oldVoucher[0].code))
|
if (ret != 0) {
|
errorItem.errmsg = "finger delete error ret:" + ret
|
errors.push(errorItem)
|
continue
|
}
|
}
|
if (sqliteService.d1_voucher.countByUserId(userId) == 0) {
|
errorItem.errmsg = "user has no vouchers"
|
errors.push(errorItem)
|
continue
|
}
|
let ret = sqliteService.d1_voucher.deleteByUserId(userId)
|
if (ret != 0) {
|
errorItem.errmsg = "sql error ret:" + ret
|
errors.push(errorItem)
|
continue
|
}
|
try {
|
driver.face.deleteFea(userId)
|
dxos.systemBrief("rm -rf /data/user/" + userId)
|
} catch (error) {
|
logger.error(`Failed to delete face feature for user ${res[0].userId}:`, error)
|
}
|
}
|
|
}
|
return true
|
}
|
|
//清空凭证
|
api.clearKey = function (data) {
|
let ret = sqliteService.d1_voucher.deleteAll()
|
try {
|
driver.face.clean()
|
} catch (error) {
|
return error.message
|
}
|
if(driver.device.finger){
|
let ret2 = driver.finger.clear()
|
if (ret2 != 0) {
|
return "finger clear error ret:" + ret2
|
}
|
}
|
if (ret == 0) {
|
return true
|
} else {
|
return "sql error "
|
}
|
}
|
|
//修改凭证
|
api.modifyKey = function (data) {
|
logger.info("modifyKey data:", JSON.stringify(data))
|
let errors = []
|
for (let i = 0; i < data.length; i++) {
|
const voucher = data[i];
|
let errorItem = {
|
keyId: voucher.keyId || 'unknown',
|
errmsg: ''
|
}
|
if (!voucher.keyId || !voucher.type || !voucher.userId) {
|
errorItem.errmsg = "keyId or type or userId cannot be empty"
|
errors.push(errorItem)
|
continue
|
}
|
let existingVouchers = sqliteService.d1_voucher.findAll({ keyId: voucher.keyId })
|
if (existingVouchers.length == 0) {
|
errorItem.errmsg = "voucher not found"
|
errors.push(errorItem)
|
continue
|
}
|
if (voucher.code && (voucher.type == "200" || voucher.type == "201" || voucher.type == "202")) {
|
voucher.code = voucher.code.toUpperCase()
|
}
|
if (voucher.type == "300" && voucher.extra.faceType != 0 && voucher.extra.faceType != 1) {
|
errorItem.errmsg = "faceType Incorrect format"
|
errors.push(errorItem)
|
continue
|
}
|
if (voucher.type == "400") {
|
if (voucher.code && voucher.code.length != 6) {
|
errorItem.errmsg = "Password length must be 6 digits"
|
errors.push(errorItem)
|
continue
|
}
|
}
|
// 无论voucher.code是否存在,都需要先删除旧指纹
|
if (voucher.type == "500") {
|
let oldVoucher = sqliteService.d1_voucher.findByuserIdAndType(voucher.userId, "500");
|
if (oldVoucher.length > 0) {
|
logger.info("modifyKey oldVoucher要删除的指纹凭证: ", JSON.stringify(oldVoucher[0]))
|
let ret = driver.finger.delete(parseInt(oldVoucher[0].code))
|
if (ret != 0) {
|
errorItem.errmsg = "finger delete error ret:" + ret
|
errors.push(errorItem)
|
continue
|
}
|
}
|
}
|
if (voucher.code) {
|
let record = {}
|
record.keyId = voucher.keyId
|
record.type = voucher.type
|
if (voucher.type == "300") {
|
let faceRegistrationSuccess = false
|
if (voucher.extra.faceType == 0) {
|
try {
|
record.code = `/data/user/${voucher.userId}/register.jpg`
|
try {
|
// 保存base64图片
|
std.ensurePathExists(record.code)
|
dxCommonUtils.fs.base64ToFile(record.code, voucher.code)
|
} catch (error) {
|
errorItem.errmsg = "文件保存失败"
|
errors.push(errorItem)
|
continue
|
}
|
try {
|
// 提取特征值
|
let featureFile = driver.face.getFeaByFile(record.code)
|
let updateFeaRes = driver.face.updateFea(voucher.userId, featureFile.feature)
|
if (updateFeaRes != 0) {
|
logger.info("第一次人脸修改失败")
|
let updateFeaResAgain = driver.face.updateFea(voucher.userId, featureFile.feature)
|
if (updateFeaResAgain == 0) {
|
logger.info("第二次人脸修改成功")
|
faceRegistrationSuccess = true
|
} else {
|
errorItem.errmsg = updateFeaResAgain
|
errors.push(errorItem)
|
continue
|
}
|
} else {
|
faceRegistrationSuccess = true
|
}
|
} catch (error) {
|
logger.info(error.message)
|
errorItem.errmsg = error.message
|
errors.push(errorItem)
|
continue
|
}
|
} catch (unexpectedError) {
|
errorItem.errmsg = unexpectedError.message
|
errors.push(errorItem)
|
continue
|
}
|
} else {
|
record.code = voucher.code
|
//特征值注册
|
try {
|
let updateFeaRes = driver.face.updateFea(voucher.userId, voucher.code)
|
if (updateFeaRes != 0) {
|
logger.info("第一次人脸修改失败")
|
let updateFeaResAgain = driver.face.updateFea(voucher.userId, voucher.code)
|
if (updateFeaResAgain == 0) {
|
logger.info("第二次人脸修改成功")
|
faceRegistrationSuccess = true
|
} else {
|
errorItem.errmsg = updateFeaResAgain
|
errors.push(errorItem)
|
continue
|
}
|
} else {
|
faceRegistrationSuccess = true
|
}
|
} catch (error) {
|
errorItem.errmsg = error.message
|
errors.push(errorItem)
|
continue
|
}
|
}
|
// 如果人脸注册失败,直接继续下一个凭证
|
if (!faceRegistrationSuccess) {
|
continue
|
}
|
} else {
|
record.code = voucher.code
|
let ret = sqliteService.d1_voucher.findAllByCodeAndType(voucher.code, voucher.type)
|
if (ret.length > 0 && ret[0].userId != voucher.userId) {
|
errorItem.errmsg = "Duplicate vouchers"
|
errors.push(errorItem)
|
continue
|
}
|
}
|
if(voucher.type == "500"){
|
logger.info("modifyKey 新增指纹凭证到指纹模组 code:", voucher.code)
|
let index = driver.finger.insert(voucher.code)
|
logger.info("modifyKey 新增指纹凭证到指纹模组的新增结果 index:", index)
|
if(index < 0){
|
errorItem.errmsg = "modifyKey finger insert error ret:" + index
|
errors.push(errorItem)
|
continue
|
}else{
|
voucher.code = index
|
record.code = index
|
}
|
}
|
record.userId = voucher.userId
|
record.extra = isEmpty(voucher.extra) ? JSON.stringify({ type: 0 }) : JSON.stringify(voucher.extra)
|
let ret2 = sqliteService.d1_voucher.updateAllByKeyId(record, record.keyId)
|
if (ret2 != 0) {
|
errorItem.errmsg = "sql error ret:" + ret2
|
errors.push(errorItem)
|
continue
|
}
|
} else {
|
let ret3 = sqliteService.d1_voucher.deleteByuserIdAndtype(voucher.userId, voucher.type)
|
if (ret3 != 0) {
|
errorItem.errmsg = "sql error ret:" + ret3
|
errors.push(errorItem)
|
continue
|
}
|
if (voucher.type == "300") {
|
try {
|
driver.face.deleteFea(voucher.userId)
|
} catch (error) {
|
logger.error(`Failed to delete face feature for user ${voucher.userId}:`, error)
|
}
|
}
|
}
|
}
|
if (errors.length > 0) {
|
return errors
|
}
|
return true
|
}
|
|
//添加权限
|
api.insertPermission = function (data) {
|
let errors = []
|
for (let i = 0; i < data.length; i++) {
|
const permission = data[i];
|
let errorItem = {
|
permissionId: permission.permissionId || 'unknown',
|
errmsg: ''
|
}
|
if (!permission.permissionId) {
|
errorItem.errmsg = "permissionId cannot be empty"
|
errors.push(errorItem)
|
continue
|
}
|
if (!permission.extra) {
|
permission.extra = ""
|
}
|
if (!permission.time) {
|
errorItem.errmsg = "time and type cannot be empty"
|
errors.push(errorItem)
|
continue
|
}
|
if (permission.time.type != 0 && permission.time.type != 1 && permission.time.type != 2 && permission.time.type != 3) {
|
errorItem.errmsg = "time type is not supported"
|
errors.push(errorItem)
|
continue
|
}
|
let record = {}
|
record.permissionId = permission.permissionId
|
record.door = isEmpty(permission.index) ? 0 : permission.index
|
record.extra = isEmpty(permission.extra) ? JSON.stringify({}) : JSON.stringify(permission.extra)
|
record.timeType = permission.time.type
|
record.beginTime = permission.time.type == 0 ? 0 : permission.time.range.beginTime
|
record.endTime = permission.time.type == 0 ? 0 : permission.time.range.endTime
|
if (permission.time.type != 2 && permission.time.type != 3) {
|
record.period = 0
|
} else if (permission.time.type == 2) {
|
record.period = permission.time.dayPeriodTime
|
} else if (permission.time.type == 3) {
|
record.period = JSON.stringify(permission.time.weekPeriodTime)
|
}
|
let ret = sqliteService.d1_permission.save(record)
|
if (ret != 0) {
|
sqliteService.d1_permission.deleteByPermissionId(record.permissionId)
|
ret = sqliteService.d1_permission.save(record)
|
if (ret != 0) {
|
errorItem.errmsg = "sql error ret:" + ret
|
errors.push(errorItem)
|
continue
|
}
|
}
|
}
|
if (errors.length > 0) {
|
return errors
|
}
|
return true
|
}
|
|
//查询权限
|
api.getPermission = function (data) {
|
if (typeof data.page !== 'number' || data.page < 0) {
|
return "Invalid parameter: 'page' must be a number >= 0"
|
}
|
if (typeof data.size !== 'number' || data.size <= 0 || data.size > 100) {
|
return "Invalid parameter: 'size' must be a number between 1 and 100";
|
}
|
let totalCount = sqliteService.d1_permission.count(data)
|
let permissions = sqliteService.d1_permission.findAll(data)
|
// 构建返回结果
|
let content = permissions.map(permission => ({
|
permissionId: permission.permissionId,
|
extra: JSON.parse(permission.extra ? permission.extra : "{}"),
|
time: {
|
type: permission.timeType,
|
range: permission.timeType === 0 ? undefined : { beginTime: permission.beginTime, endTime: permission.endTime },
|
dayPeriodTime: permission.timeType != 2 ? undefined : permission.period,
|
weekPeriodTime: permission.timeType != 3 ? undefined : JSON.parse(permission.period)
|
}
|
}))
|
return {
|
content: content,
|
page: data.page,
|
size: data.size,
|
total: totalCount,
|
totalPage: Math.ceil(totalCount / data.size),
|
count: content.length
|
}
|
}
|
|
//删除权限
|
api.delPermission = function (data) {
|
let errors = []
|
if (data.permissionIds && data.permissionIds.length > 0) {
|
for (let i = 0; i < data.permissionIds.length; i++) {
|
const permissionId = data.permissionIds[i];
|
let errorItem = {
|
permissionId: permissionId || 'unknown',
|
errmsg: ''
|
}
|
let ret = sqliteService.d1_permission.deleteByPermissionId(permissionId)
|
if (ret != 0) {
|
errorItem.errmsg = "sql error ret:" + ret
|
errors.push(errorItem)
|
continue
|
}
|
}
|
}
|
if (errors.length > 0) {
|
return errors
|
}
|
return true
|
}
|
|
//修改权限
|
api.modifyPermission = function (data) {
|
let errors = []
|
for (let i = 0; i < data.length; i++) {
|
const permission = data[i];
|
let errorItem = {
|
permissionId: permission.permissionId || 'unknown',
|
errmsg: ''
|
}
|
let permissions = sqliteService.d1_permission.findAll({ permissionId: permission.permissionId })
|
if (permissions.length == 0) {
|
errorItem.errmsg = "permission not found"
|
errors.push(errorItem)
|
continue
|
}
|
// 验证时间参数
|
if (!permission.time) {
|
errorItem.errmsg = "time and type cannot be empty"
|
errors.push(errorItem)
|
continue
|
}
|
if (permission.time.type != 0 && permission.time.type != 1 && permission.time.type != 2 && permission.time.type != 3) {
|
errorItem.errmsg = "time type is not supported"
|
errors.push(errorItem)
|
continue
|
}
|
let record = {}
|
record.permissionId = permission.permissionId
|
record.door = isEmpty(permission.index) ? 0 : permission.index
|
record.extra = isEmpty(permission.extra) ? JSON.stringify({}) : JSON.stringify(permission.extra)
|
record.timeType = permission.time.type
|
record.beginTime = permission.time.type == 0 ? 0 : permission.time.range.beginTime
|
record.endTime = permission.time.type == 0 ? 0 : permission.time.range.endTime
|
if (permission.time.type != 2 && permission.time.type != 3) {
|
record.period = 0
|
} else if (permission.time.type == 2) {
|
record.period = permission.time.dayPeriodTime
|
} else if (permission.time.type == 3) {
|
record.period = JSON.stringify(permission.time.weekPeriodTime)
|
}
|
let ret = sqliteService.d1_permission.updateAllByPermissionId(record, record.permissionId)
|
if (ret != 0) {
|
errorItem.errmsg = "sql error ret:" + ret
|
errors.push(errorItem)
|
continue
|
}
|
}
|
if (errors.length > 0) {
|
return errors
|
}
|
return true
|
}
|
|
//清空权限
|
api.clearPermission = function () {
|
let ret = sqliteService.d1_permission.deleteAll()
|
if (ret == 0) {
|
return true
|
} else {
|
return "sql error "
|
}
|
}
|
|
// 判空
|
function isEmpty(value) {
|
return value === undefined || value === null || value === ""
|
}
|
|
// 激活云证
|
api.eidActive = function (data) {
|
if (data.code && data.code.startsWith("___VBAR_ID_ACTIVE_V")) {
|
try {
|
let activeResute = driver.nfc.eidActive(data.code);
|
if (activeResute != 0) {
|
return 'Activation failed'
|
}
|
} catch (error) {
|
return error.message
|
}
|
} else {
|
return 'The key format is incorrect'
|
}
|
return true
|
}
|
|
// 新增密钥
|
api.insertSecurity = function (data) {
|
let errors = []
|
for (let i = 0; i < data.length; i++) {
|
const security = data[i];
|
let errorItem = {
|
securityId: security.securityId || 'unknown',
|
errmsg: ''
|
}
|
if (!security.securityId || !security.type || !security.key || !security.value || !security.startTime || !security.endTime) {
|
errorItem.errmsg = "securityId or type or key or value or startTime or endTime cannot be empty"
|
errors.push(errorItem)
|
continue
|
}
|
let ret = sqliteService.d1_security.save(security)
|
if (ret != 0) {
|
errorItem.errmsg = "sql error ret:" + ret
|
errors.push(errorItem)
|
continue
|
}
|
}
|
if (errors.length > 0) {
|
return errors
|
}
|
return true
|
}
|
|
// 查询密钥
|
api.getSecurity = function (data) {
|
if (typeof data.page !== 'number' || data.page < 0) {
|
return "Invalid parameter: 'page' must be a number >= 0"
|
}
|
if (typeof data.size !== 'number' || data.size <= 0 || data.size > 100) {
|
return "Invalid parameter: 'size' must be a number between 1 and 100";
|
}
|
let totalCount = sqliteService.d1_security.count(data)
|
let securities = sqliteService.d1_security.findAll(data)
|
return {
|
content: securities,
|
page: data.page,
|
size: data.size,
|
total: totalCount,
|
totalPage: Math.ceil(totalCount / data.size),
|
count: securities.length
|
}
|
}
|
|
// 删除密钥
|
api.delSecurity = function (data) {
|
let errors = []
|
if (data.length > 0) {
|
for (let i = 0; i < data.length; i++) {
|
const securityId = data[i];
|
let errorItem = {
|
securityId: securityId || 'unknown',
|
errmsg: ''
|
}
|
let ret = sqliteService.d1_security.deleteBySecurityId(securityId)
|
if (ret != 0) {
|
errorItem.errmsg = "sql error ret:" + ret
|
errors.push(errorItem)
|
continue
|
}
|
}
|
}
|
if (errors.length > 0) {
|
return errors
|
}
|
return true
|
}
|
|
// 清空密钥
|
api.clearSecurity = function () {
|
let ret = sqliteService.d1_security.deleteAll()
|
if (ret == 0) {
|
return true
|
} else {
|
return "sql error "
|
}
|
}
|
|
export default api
|