vf107/src/service/api.js
@@ -202,7 +202,12 @@
    if (data.type == 0) {
        try {
            driver.screen.upgrade({ title: "confirm.upgrade", content: "confirm.upgrading" })
            ota.updateHttp(data.url, data.md5,  100)
            // 确保URL包含协议前缀
            let url = data.url
            if (!url.startsWith('http://') && !url.startsWith('https://')) {
                url = 'http://' + url
            }
            ota.updateHttp(url, data.md5,  300)
            driver.screen.upgrade({ title: "confirm.upgrade", content: "confirm.upgradeSuccess" })
        } catch (error) {
            driver.screen.upgrade({ title: "confirm.upgrade", content: "confirm.upgradeFail" })
@@ -315,7 +320,18 @@
                let person = sqliteService.d1_person.findByUserId(record.userId)
                if (person.length) {
                    record.name = person[0].name
                    // 将extra字段从JSON字符串解析为JSON对象
                    if (person[0].extra && typeof person[0].extra === 'string') {
                        try {
                            record.extra = JSON.parse(person[0].extra)
                        } catch (error) {
                            // 如果解析失败,保持原样
                            console.error('解析extra字段失败:', error)
                    record.extra = person[0].extra
                        }
                    } else {
                        record.extra = person[0].extra
                    }
                }
            }
        })
@@ -396,6 +412,7 @@
            userId: person.userId || 'unknown',
            errmsg: ''
        }
        // 增强数据验证
        if (!person.userId || !person.name) {
            errorItem.errmsg = "userId or name cannot be empty"
            errors.push(errorItem)
@@ -406,11 +423,15 @@
            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)
@@ -420,6 +441,197 @@
                errors.push(errorItem)
                continue
            }
        }
        // 处理人脸信息
        if (person.face) {
            try {
                logger.info('[api] 开始处理人脸信息:', person.userId)
                let faceFilePath = person.face
                // 检查是否是base64编码的图片数据
                if (person.face.startsWith('data:image/')) {
                    logger.info('[api] 检测到base64编码的图片数据')
                    // 提取base64数据
                    let base64Data = person.face.split(',')[1]
                    // 创建临时文件
                    faceFilePath = '/data/user/temp_face_' + person.userId + '.jpg'
                    std.ensurePathExists(faceFilePath)
                    // 将base64数据转换为文件
                    dxCommonUtils.fs.base64ToFile(faceFilePath, base64Data)
                    logger.info('[api] 已将base64数据保存为文件:', faceFilePath)
                } else {
                    errorItem.errmsg = "数据格式错误,face字段必须是base64编码的图片数据"
                    errors.push(errorItem)
                    continue
                }
                // 注册人脸
                logger.info('[api] 开始注册人脸:', person.userId)
                let featureFile = driver.face.getFeaByFile(faceFilePath)
                let addFeaRes = driver.face.addFea(person.userId, featureFile.feature)
                if (addFeaRes == 0) {
                    // 注册成功后移动图片到用户目录
                    let src = "/data/user/" + person.userId + "/register.jpg"
                    std.ensurePathExists(src)
                    logger.info('[api] 移动人脸图片到用户目录:', faceFilePath, '->', src)
                    dxos.systemBrief('mv ' + faceFilePath + " " + src)
                    // 保存人脸凭证
                    logger.info('[api] 保存人脸凭证:', person.userId)
                    let voucherRet = sqliteService.d1_voucher.save({
                        keyId: std.genRandomStr(32),
                        type: "300",
                        code: src,
                        userId: person.userId,
                        extra: JSON.stringify({ faceType: 0 })
                    });
                    logger.info('[api] 保存人脸凭证结果:', voucherRet)
                } else {
                    logger.error('[api] 注册人脸失败,返回码:', addFeaRes)
                    errorItem.errmsg = "注册人脸失败,返回码:" + addFeaRes
                    errors.push(errorItem)
                    continue
                }
            } catch (error) {
                logger.error('[api] 处理人脸信息错误:', error)
                errorItem.errmsg = "处理人脸信息错误: " + error.message
                errors.push(errorItem)
                continue
            } finally {
                logger.info('[api] 人脸信息处理完成:', person.userId)
            }
        }
        // 处理指纹信息
        if (person.fingerprint) {
            try {
                logger.info('[api] 开始处理指纹信息:', person.userId)
                // 检查之前是否有指纹凭证
                let oldVoucher = sqliteService.d1_voucher.findByuserIdAndType(person.userId, "500");
                if (oldVoucher.length > 0) {
                    logger.info('[api] 删除旧指纹凭证:', 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) {
                        logger.error('[api] 删除旧指纹失败:', error)
                    }
                }
                // 录入新指纹
                logger.info('[api] 录入新指纹:', person.userId)
                let index = driver.finger.insert(person.fingerprint)
                if(index < 0){
                    errorItem.errmsg = "insertKey finger insert error ret:" + index
                    errors.push(errorItem)
                    continue
                }
                // 保存指纹凭证
                logger.info('[api] 保存指纹凭证:', person.userId)
                let voucherRet = sqliteService.d1_voucher.save({
                    keyId: std.genRandomStr(32),
                    type: "500",
                    code: index.toString(),
                    userId: person.userId,
                    extra: JSON.stringify({ type: 0 })
                });
                logger.info('[api] 保存指纹凭证结果:', voucherRet)
                logger.info('[api] 指纹信息处理完成:', person.userId)
            } catch (error) {
                logger.error('[api] 处理指纹信息错误:', error)
                errorItem.errmsg = "处理指纹信息错误: " + error.message
                errors.push(errorItem)
                continue
            }
        }
        // 处理NFC卡信息
        if (person.nfcCard) {
            try {
                logger.info('[api] 开始处理NFC卡信息:', person.userId)
                // 检查NFC卡是否重复
                let existingVoucher = sqliteService.d1_voucher.findByCodeAndType(person.nfcCard, "200")
                if (existingVoucher.length > 0 && existingVoucher[0].userId != person.userId) {
                    errorItem.errmsg = "NFC卡已被其他用户使用"
                    errors.push(errorItem)
                    continue
                }
                // 保存NFC卡凭证
                logger.info('[api] 保存NFC卡凭证:', person.userId)
                let voucherRet = sqliteService.d1_voucher.save({
                    keyId: std.genRandomStr(32),
                    type: "200",
                    code: person.nfcCard.toUpperCase(),
                    userId: person.userId,
                    extra: JSON.stringify({ type: 0 })
                });
                logger.info('[api] 保存NFC卡凭证结果:', voucherRet)
                logger.info('[api] NFC卡信息处理完成:', person.userId)
            } catch (error) {
                logger.error('[api] 处理NFC卡信息错误:', error)
                errorItem.errmsg = "处理NFC卡信息错误: " + error.message
                errors.push(errorItem)
                continue
            }
        }
        // 为用户添加权限
        try {
            // 获取用户类型
            let userType = 0
            if (person.extra) {
                try {
                    userType = person.extra.type || 0
                } catch (error) {
                    logger.error('[api] 解析用户类型失败:', error)
                }
            }
            // 只有保管员(0)和科长(1)需要添加权限
            if (userType == 0 || userType == 1) {
                // 检查是否已存在权限记录
                let existingPermissions = sqliteService.d1_permission.findByUserId(person.userId)
                if (existingPermissions && existingPermissions.length == 0) {
                    // 添加永久权限
                    let permissionId = std.genRandomStr(32)
                    let permissionRet = sqliteService.d1_permission.save({
                        permissionId: permissionId,
                        userId: person.userId,
                        door: "", // 空字符串表示所有门
                        timeType: 0, // 永久权限
                        beginTime: 0,
                        endTime: 0,
                        period: ""
                    });
                    logger.info('[api] 为用户添加权限结果:', permissionRet)
                    // 更新人员表中的permissionIds字段
                    if (permissionRet == 0) {
                        // 构建更新记录
                        let updateRecord = { permissionIds: permissionId }
                        // 使用updateAllByUserId方法更新
                        let updateRet = sqliteService.d1_person.updateAllByUserId(updateRecord, person.userId)
                        logger.info('[api] 更新人员权限ID结果:', updateRet)
                    }
                } else {
                    logger.info('[api] 用户已存在权限记录,跳过权限添加:', person.userId)
                }
            } else {
                logger.info('[api] 用户类型不需要添加权限,跳过权限添加:', person.userId)
            }
        } catch (error) {
            logger.error('[api] 添加权限时出错:', error)
        }
    }
    if (errors.length > 0) {
@@ -438,6 +650,14 @@
                userId: userId || 'unknown',
                errmsg: ''
            }
            try {
                // 删除人脸数据
                driver.face.deleteFea(userId)
                logger.info('[api] 删除人脸数据成功:', userId)
            } catch (error) {
                logger.error(`Failed to delete face feature for user ${userId}:`, error)
            }
            // 删除指纹凭证之前需要先删除指纹库中的指纹
            let fingerVoucher = sqliteService.d1_voucher.findByuserIdAndType(userId, "500")
            if (fingerVoucher.length > 0) {
@@ -448,19 +668,18 @@
                    errors.push(errorItem)
                    continue
                }
                logger.info('[api] 删除指纹数据成功:', userId)
            }
            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})`
            let ret4 = sqliteService.d1_permission.deleteByUserId(userId)
            if (ret1 != 0 || ret3 != 0 || ret4 != 0) {
                errorItem.errmsg = `sql error: person(${ret1}), voucher(${ret3}), permission(${ret4})`
                errors.push(errorItem)
                continue
            }
            try {
                driver.face.deleteFea(userId)
            } catch (error) {
                logger.error(`Failed to delete face feature for user ${userId}:`, error)
            }
            logger.info('[api] 删除人员成功:', userId)
        }
    }
    if (errors.length > 0) {
@@ -479,6 +698,19 @@
    }
    let totalCount = sqliteService.d1_person.count(data)
    let persons = sqliteService.d1_person.findAll(data)
    // 将extra字段从JSON字符串解析为JSON对象
    persons.forEach(person => {
        if (person.extra && typeof person.extra === 'string') {
            try {
                person.extra = JSON.parse(person.extra)
            } catch (error) {
                // 如果解析失败,保持原样
                console.error('解析extra字段失败:', error)
            }
        }
    })
    return {
        content: persons,
        page: data.page,
@@ -573,10 +805,18 @@
        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) {
        if (voucher.type == "300") {
            if (voucher.extra) {
                if (voucher.extra.faceType != 0 && voucher.extra.faceType != 1) {
            errorItem.errmsg = "faceType Incorrect format"
            errors.push(errorItem)
            continue
                }
            } else {
                errorItem.errmsg = "faceType is required"
                errors.push(errorItem)
                continue
            }
        }
        if (voucher.type == "400") {
            if (voucher.code.length != 6) {
@@ -585,17 +825,6 @@
                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
@@ -755,8 +984,17 @@
    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) {
        // 将extra字段从JSON字符串解析为JSON对象
        if (element.extra && typeof element.extra === 'string') {
            try {
                element.extra = JSON.parse(element.extra)
            } catch (error) {
                // 如果解析失败,保持原样
                console.error('解析extra字段失败:', error)
            }
        }
            //人脸特殊处理一下
        if (element.type == 300 && element.extra && element.extra.faceType == 0) {
            element.code = dxCommonUtils.fs.fileToBase64(element.code)
        }
    });
@@ -1227,28 +1465,6 @@
    }
}
// 判空
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 = []
@@ -1299,9 +1515,9 @@
// 删除密钥
api.delSecurity = function (data) {
    let errors = []
    if (data.length > 0) {
        for (let i = 0; i < data.length; i++) {
            const securityId = data[i];
    if (data.securityIds && data.securityIds.length > 0) {
        for (let i = 0; i < data.securityIds.length; i++) {
            const securityId = data.securityIds[i];
            let errorItem = {
                securityId: securityId || 'unknown',
                errmsg: ''
@@ -1326,8 +1542,142 @@
    if (ret == 0) {
        return true
    } else {
        return "sql error "
        return "sql error ret:" + ret
    }
}
// 添加应急开仓密码
api.insertEmergencyPassword = function (data) {
    // 应急开仓密码在设备中仅有唯一的1个,所以先清空表
    let deleteRet = sqliteService.d1_emergency_password.deleteAll()
    if (deleteRet != 0) {
        return "清空旧密码失败: " + deleteRet
    }
    // 检查密码是否有效
    if (!data.password) {
        return "password cannot be empty"
    }
    // 检查密码长度是否大于等于8位
    if (data.password.length < 8) {
        return "Password length must be at least 8 digits"
    }
    // 构建密码记录
    let record = {}
    record.id = data.id || 'emergency_' + Date.now() // 如果没有id,自动生成
    record.password = data.password
    record.description = data.description || "云端下发" // 如果没有传入description,默认为"云端下发"(MQTT和HTTP接口设置的情况)
    record.createTime = Date.now()
    record.updateTime = Date.now()
    record.status = data.status || 1
    // 保存密码
    let ret = sqliteService.d1_emergency_password.save(record)
    if (ret == 0) {
        return true
    } else {
        return "sql error ret:" + ret
    }
}
// 清空密钥
api.clearSecurity = function () {
    let ret = sqliteService.d1_security.deleteAll()
    if (ret == 0) {
        return true
    } else {
        return "sql error ret:" + ret
    }
}
// 添加应急开仓密码
api.insertEmergencyPassword = function (data) {
    // 应急开仓密码在设备中仅有唯一的1个,所以先清空表
    let deleteRet = sqliteService.d1_emergency_password.deleteAll()
    if (deleteRet != 0) {
        return "清空旧密码失败: " + deleteRet
    }
    // 检查密码是否有效
    if (!data.password) {
        return "password cannot be empty"
    }
    // 检查密码长度是否大于等于8位
    if (data.password.length < 8) {
        return "Password length must be at least 8 digits"
    }
    // 构建密码记录
    let record = {}
    record.id = data.id || 'emergency_' + Date.now() // 如果没有id,自动生成
    record.password = data.password
    record.description = data.description || "云端下发" // 如果没有传入description,默认为"云端下发"(MQTT和HTTP接口设置的情况)
    record.createTime = Date.now()
    record.updateTime = Date.now()
    record.status = data.status || 1
    // 保存密码
    let ret = sqliteService.d1_emergency_password.save(record)
    if (ret == 0) {
        return true
    } else {
        return "sql error ret:" + ret
    }
}
// 查询应急开仓密码
api.getEmergencyPassword = function () {
    let passwords = sqliteService.d1_emergency_password.findAll()
    if (passwords && passwords.length > 0) {
        let password = passwords[0];
        // 转换时间戳为字符串格式
        if (password.createTime) {
            // 尝试将createTime转换为数字
            const createTimeNum = Number(password.createTime);
            if (!isNaN(createTimeNum)) {
                password.createTime = timestampToDateString(createTimeNum);
            }
        }
        if (password.updateTime) {
            // 尝试将updateTime转换为数字
            const updateTimeNum = Number(password.updateTime);
            if (!isNaN(updateTimeNum)) {
                password.updateTime = timestampToDateString(updateTimeNum);
            }
        }
        return password;
    }
    return {};
}
// 清空应急开仓密码
api.clearEmergencyPassword = function () {
    let ret = sqliteService.d1_emergency_password.deleteAll()
    if (ret == 0) {
        return true
    } else {
        return "sql error ret:" + ret
    }
}
// 时间戳转日期字符串
function timestampToDateString(timestamp) {
    const date = new Date(timestamp);
    const year = date.getFullYear();
    const month = String(date.getMonth() + 1).padStart(2, '0');
    const day = String(date.getDate()).padStart(2, '0');
    const hours = String(date.getHours()).padStart(2, '0');
    const minutes = String(date.getMinutes()).padStart(2, '0');
    const seconds = String(date.getSeconds()).padStart(2, '0');
    return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
}
// 判空
function isEmpty(value) {
    return value === undefined || value === null || value === ""
}
export default api