import dxui from '../dxmodules/dxUi.js'
|
import dxMap from '../dxmodules/dxMap.js'
|
import common from '../dxmodules/dxCommon.js'
|
import log from '../dxmodules/dxLogger.js'
|
import viewUtils from './view/viewUtils.js'
|
import i18n from './view/i18n.js'
|
import pinyin from './view/pinyin/pinyin.js'
|
import mainView from './view/mainView.js'
|
import idleView from './view/idleView.js'
|
import topView from './view/topView.js'
|
import appView from './view/appView.js'
|
import pwdView from './view/pwdView.js'
|
import newPwdView from './view/config/newPwdView.js'
|
import identityVerificationView from './view/config/identityVerificationView.js'
|
import configView from './view/config/configView.js'
|
import doorControlView from './view/config/menu/doorControlView.js'
|
import helpView from './view/config/menu/helpView.js'
|
import networkSettingView from './view/config/menu/networkSettingView.js'
|
import systemSettingView from './view/config/menu/systemSettingView.js'
|
import deviceInfoView from './view/config/menu/deviceInfoView.js'
|
import localUserView from './view/config/menu/localUserView.js'
|
import recordQueryView from './view/config/menu/recordQueryView.js'
|
import voiceBroadcastView from './view/config/menu/voiceBroadcastView.js'
|
import localUserAddView from './view/config/menu/localUser/localUserAddView.js'
|
import faceEnterView from './view/config/menu/localUser/faceEnterView.js'
|
import fingerEnterView from './view/config/menu/localUser/fingerEnterView.js'
|
import fingerApplyView from './view/config/menu/localUser/fingerApplyView.js'
|
import displaySettingView from './view/config/menu/systemSetting/displaySettingView.js'
|
import faceRecognitionSettingView from './view/config/menu/systemSetting/faceRecognitionSettingView.js'
|
import swipeCardRecognitionSettingView from './view/config/menu/systemSetting/swipeCardRecognitionSettingView.js'
|
import passLogSettingView from './view/config/menu/systemSetting/passLogSettingView.js'
|
import passwordOpenDoorSettingView from './view/config/menu/systemSetting/passwordOpenDoorSettingView.js'
|
import passwordManagementView from './view/config/menu/systemSetting/passwordManagementView.js'
|
import timeSettingView from './view/config/menu/systemSetting/timeSettingView.js'
|
import systemInfoView from './view/config/menu/deviceInfo/systemInfoView.js'
|
import dataCapacityInfoView from './view/config/menu/deviceInfo/dataCapacityInfoView.js'
|
import recordQueryDetailView from './view/config/menu/recordQuery/recordQueryDetailView.js'
|
import cloudCertView from './view/config/menu/cloudCertView.js'
|
import developerView from './view/config/menu/developerView.js'
|
import capcalView from './view/config/menu/developer/capcalView.js'
|
import wechatNetView from './view/wechatNetView.js'
|
import wechatBindView from './view/wechatBindView.js'
|
import wechatFaceView from './view/wechatFaceView.js'
|
import std from '../dxmodules/dxStd.js'
|
import bus from '../dxmodules/dxEventBus.js'
|
import driver from './driver.js'
|
import config from '../dxmodules/dxConfig.js'
|
import dxos from '../dxmodules/dxOs.js'
|
import configService from './service/configService.js'
|
import sqliteService from './service/sqliteService.js'
|
import mqttService from './service/mqttService.js'
|
import faceService from './service/faceService.js'
|
import weComService from './service/weComService.js'
|
import fingerService from './service/fingerService.js'
|
import logger from '../dxmodules/dxLogger.js'
|
import dxDriver from '../dxmodules/dxDriver.js'
|
|
const screen = {}
|
|
screen.screenSize = {
|
width: dxDriver.DISPLAY.WIDTH,
|
height: dxDriver.DISPLAY.HEIGHT
|
}
|
|
screen.model = dxDriver.DRIVER.MODEL
|
|
screen.resourcePath = {
|
imagePath: `/app/code/resource/image/${dxDriver.DRIVER.MODEL}/`
|
}
|
|
screen.dropdownSymbol = screen.resourcePath.imagePath + '/down.png'
|
|
// ui上下文
|
const context = {}
|
|
// 初始化方法,在main.js中调用,只允许调用一次
|
screen.init = function () {
|
const loadMethod = dxui.loadMain
|
dxui.loadMain = function (view) {
|
if (screen.screenNow && view && screen.screenNow.id == view.id) {
|
return
|
}
|
screen.screenNow = view
|
pinyin.hide(true)
|
loadMethod.call(dxui, view)
|
}
|
|
dxui.init({ orientation: dxDriver.DISPLAY.ROTATION }, context);
|
// 初始化所有组件
|
pinyin.init(screen.screenSize.width, screen.screenSize.width / 2)
|
viewUtils.confirmInit()
|
mainView.init()
|
idleView.init()
|
topView.init()
|
appView.init()
|
pwdView.init()
|
newPwdView.init()
|
wechatNetView.init()
|
wechatBindView.init()
|
wechatFaceView.init()
|
identityVerificationView.init()
|
configView.init()
|
cloudCertView.init()
|
doorControlView.init()
|
helpView.init()
|
developerView.init()
|
capcalView.init()
|
networkSettingView.init()
|
systemSettingView.init()
|
deviceInfoView.init()
|
localUserView.init()
|
recordQueryView.init()
|
voiceBroadcastView.init()
|
localUserAddView.init()
|
faceEnterView.init()
|
if(driver.device.finger){
|
fingerEnterView.init()
|
fingerApplyView.init()
|
}
|
displaySettingView.init()
|
faceRecognitionSettingView.init()
|
swipeCardRecognitionSettingView.init()
|
passLogSettingView.init()
|
passwordOpenDoorSettingView.init()
|
passwordManagementView.init()
|
timeSettingView.init()
|
systemInfoView.init()
|
dataCapacityInfoView.init()
|
recordQueryDetailView.init()
|
// 设置语言
|
i18n.setLanguage(config.get("base.language"))
|
|
dxui.loadMain(mainView.screenMain)
|
|
// 如果是企业微信模式且未绑定企微,则加载企业微信网络配置和绑定设备页面
|
if (weComService.isWeCom() && weComService.getStatus() === 0) {
|
dxui.loadMain(wechatNetView.screenMain)
|
topView.changeTheme(true)
|
}
|
|
// 启动屏保计时器
|
idleTimerStart()
|
// bus事件
|
busEvents()
|
// 实时获取点击坐标
|
getClickPoint()
|
// 隐藏键盘
|
hidePinyin()
|
|
driver.display.setBacklight(screen.getConfig()['base.backlight'])
|
|
}
|
|
screen.trackingBox = function (data) {
|
try {
|
if (data && data.length > 0) {
|
data = JSON.parse(data)
|
// 最大10个人
|
if (data.length <= 10) {
|
for (let i = 0; i < data.length; i++) {
|
screen.trackUpdate({
|
w: data[i].rect[2],
|
h: data[i].rect[3],
|
x: data[i].rect[0],
|
y: data[i].rect[1]
|
}, data[i].id, (data[i].livingScore > 5))
|
}
|
}
|
}
|
} catch (error) {
|
log.error("screen.trackingBox:", error)
|
}
|
}
|
|
let changedClickPoint
|
let lastClickPoint = { x: 0, y: 0 }
|
let clickPoint
|
// 实时获取点击坐标
|
function getClickPoint() {
|
const indev = NativeObject.APP.NativeComponents.NativeIndev
|
std.setInterval(() => {
|
if (dxDriver.DRIVER.MODEL == "vf203") {
|
clickPoint = {
|
x: Math.abs(600 - indev.lvIndevGetPointVg().y),
|
y: indev.lvIndevGetPointVg().x
|
}
|
} else if (dxDriver.DRIVER.MODEL == "vf202") {
|
clickPoint = {
|
x: indev.lvIndevGetPointVg().x,
|
y: indev.lvIndevGetPointVg().y
|
}
|
} else if (dxDriver.DRIVER.MODEL == "vf114") {
|
clickPoint = {
|
x: indev.lvIndevGetPointVg().x,
|
y: indev.lvIndevGetPointVg().y
|
}
|
} else if (dxDriver.DRIVER.MODEL == "vf105") {
|
clickPoint = {
|
x: indev.lvIndevGetPointVg().x,
|
y: indev.lvIndevGetPointVg().y
|
}
|
}
|
|
if (lastClickPoint.x != clickPoint.x || lastClickPoint.y != clickPoint.y) {
|
changedClickPoint = clickPoint
|
} else {
|
changedClickPoint = null
|
}
|
|
lastClickPoint = clickPoint
|
}, 100)
|
}
|
|
function hidePinyin() {
|
let showPoint
|
const hideMethod = pinyin.hide
|
const showMethod = pinyin.show
|
// 加锁
|
let lock = false
|
pinyin.hide = function (isForce) {
|
if (isForce) {
|
hideMethod.call(pinyin)
|
lock = false
|
return
|
}
|
if (lock) {
|
return
|
}
|
lock = true
|
hideMethod.call(pinyin)
|
lock = false
|
}
|
pinyin.show = function (...args) {
|
if (lock) {
|
return
|
}
|
lock = true
|
showMethod.call(pinyin, ...args)
|
showPoint = clickPoint
|
lock = false
|
}
|
std.setInterval(() => {
|
if (showPoint && (Math.abs(showPoint.x - clickPoint.x) > 5 && Math.abs(showPoint.y - clickPoint.y) > 5)) {
|
if (clickPoint.y < (screen.screenSize.height - (pinyin.getMode() == 1 ? pinyin.container.height() + 70 : pinyin.container.height()))) {
|
let defocus = dxMap.get("INPUT_KEYBOARD").get("defocus")
|
if (defocus == "defocus") {
|
dxMap.get("INPUT_KEYBOARD").del("defocus")
|
showPoint = null
|
pinyin.hide()
|
}
|
}
|
}
|
}, 100)
|
}
|
|
class ScreenManager {
|
constructor(callbacks = {}) {
|
this.timers = {
|
screenSaver: null,
|
screenOff: null
|
};
|
|
// 默认配置
|
this.config = {
|
screenSaverDelay: 0, // 屏保延迟(毫秒)
|
screenOffDelay: 0 // 熄屏延迟(毫秒)
|
};
|
|
// 回调函数
|
this.callbacks = {
|
onScreenSaverStart: callbacks.onScreenSaverStart || (() => { }),
|
onScreenSaverEnd: callbacks.onScreenSaverEnd || (() => { }),
|
onScreenOff: callbacks.onScreenOff || (() => { }),
|
onScreenOn: callbacks.onScreenOn || (() => { })
|
};
|
|
this.resetTimers = this.resetTimers.bind(this);
|
}
|
|
// 配置时间
|
configure({ screenSaverDelay = 0, screenOffDelay = 0 }) {
|
this.config.screenSaverDelay = screenSaverDelay;
|
this.config.screenOffDelay = screenOffDelay;
|
this.resetTimers();
|
}
|
|
// 重置定时器
|
resetTimers() {
|
// 清除现有定时器
|
if (this.timers.screenSaver) {
|
std.clearTimeout(this.timers.screenSaver);
|
}
|
if (this.timers.screenOff) {
|
std.clearTimeout(this.timers.screenOff);
|
}
|
// 退出当前状态
|
this.exitScreenStates();
|
|
// 设置新的定时器
|
if (this.config.screenOffDelay > 0) {
|
this.timers.screenOff = std.setTimeout(() => {
|
this.enterScreenOff();
|
}, this.config.screenOffDelay);
|
}
|
|
// 只有当熄屏时间大于屏保时间时才设置屏保定时器
|
if (this.config.screenSaverDelay > 0 &&
|
(this.config.screenSaverDelay < this.config.screenOffDelay || this.config.screenOffDelay == 0)) {
|
this.timers.screenSaver = std.setTimeout(() => {
|
this.enterScreenSaver();
|
}, this.config.screenSaverDelay);
|
}
|
}
|
|
// 进入屏保状态
|
enterScreenSaver() {
|
const mapUI = dxMap.get("UI")
|
if (!mapUI.get("isScreenOff")) {
|
mapUI.put("isScreenSaver", true)
|
this.callbacks.onScreenSaverStart();
|
}
|
}
|
|
// 进入熄屏状态
|
enterScreenOff() {
|
const mapUI = dxMap.get("UI")
|
mapUI.put("isScreenOff", true)
|
mapUI.put("isScreenSaver", false)
|
this.callbacks.onScreenOff();
|
}
|
|
// 退出所有屏幕状态
|
exitScreenStates() {
|
const mapUI = dxMap.get("UI")
|
const previousState = { isScreenOff: mapUI.get("isScreenOff"), isScreenSaver: mapUI.get("isScreenSaver") };
|
mapUI.put("isScreenOff", false)
|
mapUI.put("isScreenSaver", false)
|
// 如果状态发生改变,触发相应回调
|
if (previousState.isScreenSaver) {
|
this.callbacks.onScreenSaverEnd();
|
}
|
if (previousState.isScreenOff) {
|
this.callbacks.onScreenOn();
|
}
|
}
|
|
// 获取当前状态
|
getState() {
|
const mapUI = dxMap.get("UI")
|
return { isScreenOff: mapUI.get("isScreenOff"), isScreenSaver: mapUI.get("isScreenSaver") };
|
}
|
|
// 清理资源
|
destroy() {
|
if (this.timers.screenSaver) {
|
std.clearTimeout(this.timers.screenSaver);
|
}
|
if (this.timers.screenOff) {
|
std.clearTimeout(this.timers.screenOff);
|
}
|
}
|
}
|
|
let screenManager
|
function idleTimerStart() {
|
// 创建实例,传入回调函数
|
screenManager = new ScreenManager({
|
onScreenSaverStart: () => {
|
screen.enterIdle()
|
},
|
onScreenSaverEnd: () => {
|
screen.exitIdle(true)
|
},
|
onScreenOff: () => {
|
dxMap.get("screenOff").put("status", 1)
|
screen.screenNow.hide()
|
topView.screenMain.hide()
|
// 熄屏时停止人脸识别
|
screen.faceRecgPause()
|
// 熄屏时关闭补光灯
|
if (driver.pwm && typeof driver.pwm.setWhitePower === 'function') {
|
driver.pwm.setWhitePower(0)
|
driver.pwm.setNirPower(0)
|
}
|
driver.display.setBacklight(0)
|
screen.enterIdle()
|
},
|
onScreenOn: () => {
|
screen.exitIdle(true)
|
std.setTimeout(() => {
|
dxMap.get("screenOff").put("status", 0)
|
screen.screenNow.show()
|
topView.screenMain.show()
|
driver.display.setBacklight(screen.getConfig()['base.backlight'])
|
// 亮屏时开启补光灯
|
if (driver.pwm && typeof driver.pwm.setWhitePower === 'function') {
|
let whiteLuminance = config.get("base.brightness")
|
let nirLuminance = config.get("base.nirBrightness")
|
driver.pwm.setWhitePower(whiteLuminance)
|
driver.pwm.setNirPower(nirLuminance)
|
}
|
// 亮屏时开启人脸识别
|
screen.faceRecgStart()
|
}, 100)
|
}
|
});
|
|
// 配置时间(毫秒)
|
screenManager.configure({
|
// screenSaverDelay: 10000, // 屏保
|
// screenOffDelay: 5000 // 熄屏
|
screenSaverDelay: config.get("base.screensaver") * 60 * 1000, // 屏保
|
screenOffDelay: config.get("base.screenOff") * 60 * 1000 // 熄屏
|
});
|
|
// 检测用户触摸
|
let touchCount = 0
|
std.setInterval(() => {
|
let count = dxui.Utils.GG.NativeDisp.lvDispGetInactiveTime()
|
if (count < touchCount) {
|
screenManager.resetTimers();
|
}
|
touchCount = count
|
}, 100);
|
}
|
|
screen.screenManagerRefresh = function () {
|
screenManager.configure({
|
screenSaverDelay: config.get("base.screensaver") * 60 * 1000, // 屏保
|
screenOffDelay: config.get("base.screenOff") * 60 * 1000 // 熄屏
|
});
|
screenManager.resetTimers();
|
}
|
|
let enterIdleTimer
|
// 进入屏保
|
screen.enterIdle = function () {
|
// 延迟1秒,防止进入屏保和退出屏保同时触发,1秒内没有触发退出屏保,则认为进入屏保
|
enterIdleTimer = std.setTimeout(() => {
|
if (idleView.screenMain.isHide()) {
|
viewUtils.confirmClose()
|
mainView.load()
|
idleView.screenMain.show()
|
topView.changeTheme(false)
|
}
|
}, 1000)
|
}
|
|
// 退出屏保
|
screen.exitIdle = function (isSelf) {
|
if (enterIdleTimer) {
|
std.clearTimeout(enterIdleTimer)
|
enterIdleTimer = null
|
}
|
if (!isSelf) {
|
screenManager.resetTimers();
|
}
|
if (!idleView.screenMain.isHide()) {
|
idleView.screenMain.hide()
|
}
|
}
|
|
screen.loop = function () {
|
return dxui.handler()
|
}
|
|
//云证激活 0 成功 非0失败
|
screen.nfcIdentityCardActivation = function (code) {
|
if (code && code.startsWith("___VBAR_ID_ACTIVE_V")) {
|
let activeResute = driver.nfc.eidActive(code);
|
if (activeResute === 0) {
|
screen.upgrade({ title: "confirm.cloudCertActive", content: "confirm.cloudCertActiveSuccess" })
|
} else {
|
screen.upgrade({ title: "confirm.cloudCertActive", content: "confirm.cloudCertActiveFail" })
|
}
|
} else {
|
screen.upgrade({ title: "confirm.cloudCertActive", content: "confirm.cloudCertKeyIncorrent" })
|
}
|
}
|
|
// 删除人员
|
screen.deleteUser = function (user) {
|
// TODO删除人员
|
sqliteService.d1_person.deleteByUserId(user.userId)
|
|
let persons = sqliteService.d1_person.findByUserId(user.userId)
|
if (persons.length > 0) {
|
if (persons[0].permissionIds) {
|
for (let i = 0; i < persons[0].permissionIds.split(',').length; i++) {
|
const permissionId = persons[0].permissionIds.split(',')[i];
|
sqliteService.d1_permission.deleteByPermissionId(permissionId)
|
}
|
}
|
}
|
let vouchers = sqliteService.d1_voucher.findByUserId(user.userId)
|
if (vouchers.length > 0) {
|
vouchers.forEach(element => {
|
sqliteService.d1_voucher.deleteByKeyId(element.keyId)
|
if(element.type == "500") {
|
log.info("deleteUser删除指纹凭证: ", parseInt(element.code))
|
driver.finger.delete(parseInt(element.code))
|
}
|
});
|
}
|
let res = driver.face.deleteFea(user.userId)
|
return true
|
}
|
screen.updateUser = function (user) {
|
//修改人员信息
|
let res = sqliteService.d1_person.updatenameAndExtraByUserId(user.userId, user.name, JSON.stringify({ type: user.type, idCard: user.idCard }))
|
if (res != 0) {
|
return false
|
}
|
//处理凭证
|
let ret
|
if (user.pwd) {
|
//判断库表是否存在这个凭证
|
let pwdData = sqliteService.d1_voucher.findByCodeAndType(user.pwd, "400");
|
if (pwdData.length > 0 && pwdData[0].userId != user.userId) {
|
//存在不能添加返回失败
|
log.info("密码重复");
|
return "localUserAddView.failPwdRepeat"
|
}
|
//查询是否有密码凭证有更新没有新增
|
let countByuserIdAndType = sqliteService.d1_voucher.findByuserIdAndType(user.userId, "400");
|
if (countByuserIdAndType.length > 0) {
|
ret = sqliteService.d1_voucher.updatecodeByuserIdAndtype(user.userId, "400", user.pwd)
|
if (ret != 0) {
|
return false
|
}
|
} else {
|
//新增一个
|
ret = sqliteService.d1_voucher.save({ keyId: std.genRandomStr(32), type: "400", code: user.pwd, userId: user.userId })
|
if (ret != 0) {
|
return false
|
}
|
}
|
} else {
|
//没有内容去数据库表删除一下
|
sqliteService.d1_voucher.deleteByuserIdAndtype(user.userId, "400")
|
}
|
if (user.card) {
|
user.card = user.card.toUpperCase()
|
//判断库表是否存在这个凭证
|
let cardData = sqliteService.d1_voucher.findByCodeAndType(user.card, "200");
|
if (cardData.length > 0 && cardData[0].userId != user.userId) {
|
//存在不能添加返回失败
|
log.info("卡重复");
|
return "localUserAddView.failCardRepeat"
|
}
|
//查询是否有密码凭证有更新没有新增
|
let countByuserIdAndType = sqliteService.d1_voucher.countByuserIdAndType(user.userId, "200");
|
if (countByuserIdAndType > 0) {
|
ret = sqliteService.d1_voucher.updatecodeByuserIdAndtype(user.userId, "200", user.card)
|
if (ret != 0) {
|
return false
|
}
|
} else {
|
//新增一个
|
ret = sqliteService.d1_voucher.save({ keyId: std.genRandomStr(32), type: "200", code: user.card, userId: user.userId })
|
|
if (ret != 0) {
|
return false
|
}
|
}
|
} else {
|
//没有内容去数据库表删除一下
|
sqliteService.d1_voucher.deleteByuserIdAndtype(user.userId, "200")
|
}
|
if (user.face && user.feature) {
|
let findByuserIdAndType = sqliteService.d1_voucher.findByuserIdAndType(user.userId, "300");
|
if (findByuserIdAndType.length <= 0) {
|
let ret = driver.face.addFea(user.userId, user.feature)
|
log.info("2注册人脸,ret:", ret)
|
if (typeof ret == 'string') {
|
return ret
|
}
|
if (ret != 0) {
|
return faceService.regErrorEnum.picture[ret + '']
|
}
|
//注册成功后需要吧原来图片移动到 user 对应目录下
|
let src = "/data/user/" + user.userId + "/register.jpg"
|
std.ensurePathExists(src)
|
dxos.systemBrief('mv ' + user.face + " " + src)
|
|
//新增一个
|
ret = sqliteService.d1_voucher.save({ keyId: std.genRandomStr(32), type: "300", code: src, userId: user.userId })
|
if (ret != 0) {
|
return false
|
}
|
} else {
|
//原来有又传入 先删除后新增
|
if (findByuserIdAndType[0].code != user.face) {
|
//删除老人脸
|
driver.face.deleteFea(user.userId)
|
//注册新人脸
|
let res = driver.face.addFea(user.userId, user.feature)
|
log.info("3注册人脸,res:", res)
|
if (typeof res == 'string') {
|
return res
|
}
|
if (res != 0) {
|
return faceService.regErrorEnum.picture[res + '']
|
}
|
let src = "/data/user/" + user.userId + "/register.jpg"
|
std.ensurePathExists(src)
|
//把临时目录人脸移动到 user 对应的文件夹中
|
dxos.systemBrief('mv ' + user.face + " " + src)
|
ret = sqliteService.d1_voucher.updatecodeAndExtraByuserIdAndtype(user.userId, "300", src, JSON.stringify({ faceType: 0 }))
|
}
|
}
|
} else {
|
// TODO 没有存储特征值,特征值字段为空,face字段没有值才是真正删除人脸
|
if (!user.face) {
|
//没有内容去数据库表删除一下
|
sqliteService.d1_voucher.deleteByuserIdAndtype(user.userId, "300")
|
driver.face.deleteFea(user.userId)
|
dxos.systemBrief("rm -rf /data/user/" + user.userId)
|
}
|
}
|
|
// 修改指纹凭证
|
if (user.fingerId != null && user.fingerId != undefined) {
|
log.info("updateUser 修改指纹凭证(code fingerId): ", parseInt(user.fingerId))
|
|
//查询是否有指纹凭证有更新没有新增
|
let countByuserIdAndType = sqliteService.d1_voucher.countByuserIdAndType(user.userId, "500");
|
if (countByuserIdAndType > 0) {
|
ret = sqliteService.d1_voucher.updatecodeByuserIdAndtype(user.userId, "500", parseInt(user.fingerId))
|
if (ret != 0) {
|
return false
|
}
|
} else {
|
//新增一个
|
ret = sqliteService.d1_voucher.save({ keyId: std.genRandomStr(32), type: "500", code: parseInt(user.fingerId), userId: user.userId })
|
|
if (ret != 0) {
|
return false
|
}
|
}
|
} else {
|
// 没有内容去数据库表删除一下
|
sqliteService.d1_voucher.deleteByuserIdAndtype(user.userId, "500")
|
}
|
|
return true
|
}
|
// 新增人员
|
screen.insertUser = async function (user) {
|
//开始处理凭证
|
const saveVoucher = async (type, code, feature) => {
|
if (type == "200") {
|
let cardData = sqliteService.d1_voucher.findByCodeAndType(code, "200");
|
if (cardData.length > 0 && cardData[0].userId != user.userId) {
|
//存在不能添加返回失败
|
log.info("卡重复");
|
return "localUserAddView.failCardRepeat"
|
}
|
}
|
// 当 type 为 "300" 时,首先调用特定方法检查是否可以继续保存凭证
|
if (type === "300") {
|
let preCheckResult = await preSaveCheck(code, feature); // 假设这是您提到的需要调用的方法
|
if (preCheckResult !== true) { // 如果预检查不通过,则直接返回 false
|
return preCheckResult;
|
}
|
code = "/data/user/" + user.userId + "/register.jpg"
|
}
|
if (type == "400") {
|
let pwdData = sqliteService.d1_voucher.findByCodeAndType(code, "400");
|
if (pwdData.length > 0 && pwdData[0].userId != user.userId) {
|
//存在不能添加返回失败
|
log.info("密码重复");
|
return "localUserAddView.failPwdRepeat"
|
}
|
}
|
|
if (type == "500") {
|
let fingerData = sqliteService.d1_voucher.findByCodeAndType(parseInt(code), "500");
|
if (fingerData.length > 0 && fingerData[0].userId != user.userId) {
|
//存在不能添加返回失败
|
log.info("指纹重复");
|
return "localUserAddView.failFingerRepeat"
|
}
|
log.info("insertUser新增指纹凭证(code fingerId): ", parseInt(code))
|
}
|
let keyId = std.genRandomStr(32);
|
let extra = type == 300 ? JSON.stringify({ faceType: 0 }) : JSON.stringify({})
|
let voucherRet = await sqliteService.d1_voucher.save({
|
keyId: keyId,
|
type: type,
|
code: type == "500" ? parseInt(code) : code,
|
userId: user.userId,
|
extra: extra
|
});
|
|
if (voucherRet != 0) {
|
// 如果凭证保存失败,则删除已保存的用户信息及可能已保存的其他凭证
|
await sqliteService.d1_person.deleteByUserId(user.userId);
|
await sqliteService.d1_voucher.deleteByUserId(user.userId);
|
return false;
|
}
|
return true;
|
};
|
async function preSaveCheck(code, feature) {
|
let ret = driver.face.addFea(user.userId, feature)
|
log.info("注册人脸,ret:", ret)
|
if (typeof ret == 'string') {
|
return ret
|
}
|
if (ret != 0) {
|
return faceService.regErrorEnum.picture[ret + '']
|
}
|
//注册成功后需要吧原来图片移动到 user 对应目录下
|
let src = "/data/user/" + user.userId + "/register.jpg"
|
std.ensurePathExists(src)
|
dxos.systemBrief('mv ' + code + " " + src)
|
return true;
|
}
|
let success = true;
|
if (success === true && user.face && user.feature && !(success = await saveVoucher("300", user.face, user.feature)));
|
if (success === true && user.pwd && !(success = await saveVoucher("400", user.pwd)));
|
if (success === true && user.card && !(success = await saveVoucher("200", user.card.toUpperCase())));
|
if (success === true && user.fingerId != null && !(success = await saveVoucher("500", user.fingerId)));
|
if (success === true) {
|
//{"id":"423","userId":"423","name":"微光互联","idCard":"123","pwd":"251574","card":"123"}
|
//保存人员信息
|
let personRet = await sqliteService.d1_person.save({
|
userId: user.userId,
|
name: user.name,
|
extra: JSON.stringify({ type: user.type == 1 ? 1 : 0, idCard: user.idCard })
|
});
|
if (personRet != 0) {
|
sqliteService.d1_voucher.deleteByUserId(user.userId);
|
return "localUserAddView.failRepeat"
|
}
|
//新增一条永久权限
|
sqliteService.d1_permission.save({ permissionId: user.userId, timeType: 0 })
|
sqliteService.d1_person.updatePermissionIdsByUserId(user.userId, user.userId)
|
} else {
|
await sqliteService.d1_voucher.deleteByUserId(user.userId);
|
}
|
return success;
|
}
|
|
// 获取本地人员信息
|
screen.getVoucher = function (userId) {
|
|
let person = sqliteService.d1_person.find({ userId: userId });
|
log.info("getVoucher 获取到的人员信息: ", JSON.stringify(person))
|
|
if (person.length < 0) {
|
return
|
}
|
let pwd_voucher = sqliteService.d1_voucher.find({ userId: userId, type: "400" })[0] || undefined
|
let card_voucher = sqliteService.d1_voucher.find({ userId: userId, type: "200" })[0] || undefined
|
let face_voucher = sqliteService.d1_voucher.find({ userId: userId, type: "300" })[0] || undefined
|
let fingerId_voucher = sqliteService.d1_voucher.find({ userId: userId, type: "500" })[0] || undefined
|
let idCard_voucher
|
try {
|
idCard_voucher = JSON.parse(person[0].extra).idCard
|
} catch (error) {
|
}
|
// log.info("getVoucher 获取到的密码凭证信息: ", JSON.stringify(pwd_voucher))
|
// log.info("getVoucher 获取到的卡凭证信息: ", JSON.stringify(card_voucher))
|
// log.info("getVoucher 获取到的人脸凭证信息: ", JSON.stringify(face_voucher))
|
// log.info("getVoucher 获取到的指纹凭证信息: ", JSON.stringify(fingerId_voucher))
|
return {
|
id: userId,
|
idCard: idCard_voucher ? idCard_voucher : undefined,
|
card: card_voucher ? card_voucher.code : undefined,
|
pwd: pwd_voucher ? pwd_voucher.code : undefined,
|
face: face_voucher ? face_voucher.code : undefined,
|
fingerId: fingerId_voucher ? fingerId_voucher.code : undefined,
|
type: JSON.parse(person[0].extra).type
|
}
|
|
}
|
screen.getUsers = function (page = 0, size = 6, name) {
|
if (name) {
|
// 用户姓名可能重复,改为模糊查询
|
let users = sqliteService.findPersonsByNameLike(name)
|
if (users && users.length > 0) {
|
users.map(v => {
|
v.id = v.userId
|
})
|
function chunkArray(arr, size) {
|
// 如果数组为空或者大小为零,返回空数组
|
if (arr.length === 0 || size <= 0) {
|
return [];
|
}
|
const result = [];
|
// 使用循环遍历数组,并按照大小切割
|
for (let i = 0; i < arr.length; i += size) {
|
result.push(arr.slice(i, i + size)); // slice 截取指定范围的元素
|
}
|
return result;
|
}
|
const chunkedArray = chunkArray(users, size);
|
return { data: chunkedArray[page], totalPage: Math.ceil(users.length / size), totalSize: users.length, currentPage: page + 1 }
|
}
|
return { data: [], totalPage: 0, totalSize: 0, currentPage: 1 }
|
}
|
let userCount = sqliteService.d1_person.count()
|
let users = sqliteService.d1_person.findOrderByUserIdAsc({ page, size })
|
if (users.length > 0) {
|
users.forEach(element => { element.id = element.userId });
|
}
|
// 总页数
|
let totalPage = Math.ceil(userCount / size)
|
return { data: users, totalPage: totalPage, totalSize: userCount, currentPage: page + 1 }
|
}
|
screen.getUserById = function(userId) {
|
let person = sqliteService.d1_person.find({ userId: userId });
|
if (person == null || person.length < 0) {
|
return null
|
}
|
return person[0]
|
}
|
// 根据人员ID和凭证类型删除凭证
|
screen.delUserVoucher = function (userId, type) {
|
sqliteService.d1_voucher.deleteByuserIdAndtype(userId, type)
|
}
|
|
// 获取通行记录
|
screen.getPassRecord = function (page = 0, size = 3) {
|
let passCount = sqliteService.d1_pass_record.count()
|
let datas = sqliteService.d1_pass_record.findOrderByTimeStampDesc({ page, size })
|
// 总页数
|
let totalPage = Math.ceil(passCount / size)
|
return { data: datas, totalPage: totalPage, totalSize: passCount, currentPage: page + 1 }
|
}
|
|
// 人脸录入开始,UI控制
|
screen.faceEnterStart = function () {
|
bus.fire("getFeaByCapStart", 10000)
|
}
|
|
// 获取卡号UI控制
|
screen.getCardStart = function () {
|
dxMap.get("UI").put("getCardStart", true)
|
}
|
// 获取卡号结束UI控制
|
screen.endCardEnd = function () {
|
dxMap.get("UI").del("getCardStart")
|
}
|
// 开启人脸识别
|
screen.faceRecgStart = function () {
|
try {
|
driver.face.status(1)
|
} catch (error) {
|
}
|
}
|
|
// 人脸识别暂停
|
screen.faceRecgPause = function () {
|
driver.face.status(0)
|
}
|
|
// 人脸录入结果
|
screen.faceEnterResult = function (facePic, feature) {
|
if (facePic) {
|
faceEnterView.successFlag = true
|
// 成功,显示人脸照片
|
localUserAddView.addFace(facePic, feature)
|
dxui.loadMain(localUserAddView.screenMain)
|
faceEnterView.backCb()
|
}
|
}
|
|
// 非识别页面人脸认证开始,UI控制
|
screen.faceAuthStart = function () {
|
dxMap.get("UI").put("faceAuthStart", "Y")
|
driver.face.status(1)
|
}
|
|
// 非识别页面人脸认证结束,UI控制
|
screen.faceAuthEnd = function () {
|
dxMap.get("UI").del("faceAuthStart")
|
driver.face.status(0)
|
}
|
|
// 非识别页面人脸认证结果
|
screen.faceAuthResult = function (bool) {
|
let language=config.get("base.language")||"CN";
|
if (bool) {
|
// 成功,进入设置菜单
|
driver.audio.play(`/app/code/resource/wav/${language}/recg_s.wav`)
|
dxui.loadMain(configView.screenMain)
|
} else {
|
driver.audio.play(`/app/code/resource/wav/${language}/recg_f.wav`)
|
// 失败,报错
|
identityVerificationView.statusPanel.fail("identityVerificationView.fail")
|
}
|
}
|
|
// 删除指定ID的指纹
|
screen.deleteFinger = function (fingerId) {
|
// 删除指纹凭证
|
return driver.finger.delete(fingerId)
|
}
|
|
// 远程录入指纹
|
screen.enrollFinger = function (payload) {
|
screenManager.resetTimers()
|
fingerApplyView.applyFinger(payload)
|
dxui.loadMain(fingerApplyView.screenMain)
|
}
|
|
// 远程录入指纹指令回复
|
screen.fingerReply = function (data) {
|
let payload = screen.mqttReply(data.serialNo, { fingerFeature: data.fingerChar }, data.code)
|
screen.driver.mqtt.send("access_device/v2/cmd/control_reply", JSON.stringify(payload))
|
}
|
|
// 缓存指纹特征
|
screen.cacheFingerChar = function (userId, fingerChar) {
|
fingerService.setFingerChar({ userId: userId, fingerChar: fingerChar })
|
}
|
|
// 中断指纹采集
|
screen.interruptFinger = function () {
|
screen.cacheFingerChar(fingerEnterView.userId, null)
|
fingerEnterView.userId = null
|
fingerApplyView.interruptFinger()
|
}
|
|
// 校验通行记录数量
|
screen.verifyPassRecords = function (num) {
|
const passCount = sqliteService.d1_pass_record.count()
|
const overCount = passCount - num
|
if (overCount <= 0) {
|
return
|
}
|
log.info(passCount,num)
|
const oldRecords = sqliteService.d1_pass_record.findAllOrderBytimeStampAsc({ page: 0, size: overCount })
|
if (!oldRecords || oldRecords.length === 0) {
|
return
|
}
|
oldRecords.forEach((record) => {
|
if (record.type == 300 && record.code) {
|
dxos.systemBrief(`rm -rf ${record.code}`)
|
}
|
sqliteService.d1_pass_record.deleteByid(record.id)
|
})
|
}
|
|
// 保存配置
|
screen.saveConfig = function (configAll) {
|
console.log('configAll', JSON.stringify(configAll));
|
if (configAll && configAll.net) {
|
// 检查 ssid 和 psk 是否都存在
|
if (configAll.net.ssid || configAll.net.psk) {
|
// 在这里添加你的额外操作
|
bus.fire("setConfig", configAll)
|
return true
|
}
|
}
|
return configService.configVerifyAndSave(configAll)
|
}
|
|
// 获取配置
|
screen.getConfig = function () {
|
let config1 = config.getAll()
|
|
return config1
|
}
|
|
// 密码通行
|
screen.pwdAccess = function (pwd) {
|
// TODO完善通行逻辑
|
bus.fire("access", { data: { type: "400", code: pwd } })
|
}
|
|
//获取 wifi 列表
|
screen.netGetWifiSsidList = function () {
|
bus.fire(driver.net.SCAN_WIFI)
|
}
|
|
screen.netWifiSsidList = function (data) {
|
log.info('screen.netWifiSsidList', data)
|
if (networkSettingView.wifiListData && networkSettingView.wifiListData.length > 0) {
|
const combined = [...networkSettingView.wifiListData, ...data]
|
const unique = [...new Set(combined)]
|
networkSettingView.wifiListData = unique
|
} else {
|
networkSettingView.wifiListData = data
|
}
|
networkSettingView.wifiList.refresh()
|
}
|
|
//获取卡号
|
screen.getCard = function (card) {
|
localUserAddView.cardBoxInput.text(card)
|
}
|
|
// bus事件
|
function busEvents() {
|
// 网络状态
|
bus.on(driver.net.CONNECTED_CHANGED, (data) => {
|
screen.updateNetStatus(data)
|
})
|
|
// mqtt连接状态
|
bus.on('mqttStatus', (data) => {
|
if (data == "connected") {
|
topView.mqttConnectState(true)
|
} else {
|
topView.mqttConnectState(false)
|
}
|
})
|
bus.on("exitIdle", screen.exitIdle)
|
bus.on("getCard", screen.getCard)
|
bus.on("faceAuthResult", screen.faceAuthResult)
|
bus.on("accessRes", screen.accessRes)
|
bus.on("showMessage", screen.showMessage)
|
bus.on("hideSn", screen.hideSn)
|
bus.on("hideIp", screen.hideIp)
|
bus.on("changeLanguage", screen.changeLanguage)
|
bus.on("screenManagerRefresh", screen.screenManagerRefresh)
|
bus.on(driver.net.WIFI_LIST, screen.netWifiSsidList)
|
bus.on("appMode", screen.appMode)
|
bus.on("upgrade", screen.upgrade)
|
bus.on("trackResult", screen.trackResult)
|
bus.on("trackingBox", screen.trackingBox)
|
bus.on("getFeaByCapEnd", screen.getFeaByCapEnd)
|
bus.on('reload', screen.reload)
|
bus.on("weComTackFace", screen.weComTackFace)
|
bus.on("resetTimers", screenManager.resetTimers)
|
bus.on("enrollFinger", screen.enrollFinger)
|
bus.on("interruptFinger", screen.interruptFinger)
|
bus.on("verifyPassRecords", screen.verifyPassRecords)
|
}
|
screen.updateNetStatus = function (data) {
|
let type = config.get("net.type")
|
let param = driver.net.getNetParam()
|
|
if (data == "connected" && param) {
|
config.setAndSave("net.ip", param.ip)
|
config.setAndSave("net.gateway", param.gateway)
|
config.setAndSave("net.mask", param.netmask)
|
config.setAndSave('net.dns', param.dns)
|
config.setAndSave('net.mac', screen.getNetMac())
|
topView.ethConnectState(true, type)
|
networkSettingView.netInfo[10].label.dataI18n = "networkSettingView.networkConnected"
|
if (mainView.ipInfoLbl) mainView.ipInfoLbl.text("IP:" + param.ip)
|
wechatBindView.wechatIpLbl.text("IP: " + param.ip)
|
wechatNetView.wechatIpLbl.text("IP: " + param.ip)
|
} else {
|
topView.ethConnectState(false, type)
|
networkSettingView.netInfo[10].label.dataI18n = "networkSettingView.networkUnconnected"
|
if (mainView.ipInfoLbl) mainView.ipInfoLbl.text(" ")
|
wechatBindView.wechatIpLbl.text(" ")
|
wechatNetView.wechatIpLbl.text(" ")
|
}
|
i18n.refreshObj(networkSettingView.netInfo[10].label)
|
networkSettingView.refresh()
|
networkSettingView.changeNetType(type)
|
}
|
|
screen.fireNetStatus = function () {
|
bus.fire(driver.mqtt.CONNECTED_CHANGED, "disconnected")
|
}
|
|
// 开始注册人脸
|
screen.getFeaByCapEnd = function (data) {
|
if (faceEnterView.screenMain.isHide()) {
|
return
|
}
|
if (!data.picPath) {
|
return screen.faceEnterResult()
|
}
|
let language=config.get("base.language")||"CN";
|
driver.audio.play(`/app/code/resource/wav/${language}/recognition_s.wav`)
|
faceEnterView.statusPanel.success("faceEnterView.recogSuccess")
|
// 保存图片到本地
|
let src = `/data/user/register.jpg`
|
dxos.systemBrief(`mv ${data.picPath} ${src}`)
|
dxos.systemBrief(`rm -rf /data/user/temp/*`)
|
screen.faceEnterResult(src, data.feature)
|
}
|
// 抓拍人脸
|
screen.tackFace = function () {
|
driver.face.status(1)
|
let res = driver.face.getFeaByCap(10000)
|
driver.face.status(0)
|
return res
|
}
|
// 接收企业微信抓拍人脸事件
|
screen.weComTackFace = function (data) {
|
driver.face.status(0)
|
wechatFaceView.weComTackFace(data)
|
// 加载到抓拍人脸页面
|
dxui.loadMain(wechatFaceView.screenMain)
|
}
|
|
// 通行成功/失败
|
screen.accessRes = function (bool) {
|
if (bool) {
|
if (mainView.smallStatusPanel && mainView.smallStatusPanel.success) {
|
mainView.smallStatusPanel.success()
|
}
|
} else {
|
if (mainView.smallStatusPanel && mainView.smallStatusPanel.fail) {
|
mainView.smallStatusPanel.fail()
|
}
|
}
|
}
|
|
// 展示成功/失败信息
|
screen.showMessage = function (data) {
|
let { status, msg } = data
|
if (status) {
|
mainView.messagePanel.success(msg)
|
} else {
|
mainView.messagePanel.fail(msg)
|
}
|
}
|
|
// 切换app模式
|
screen.appMode = function (mode) {
|
if (mode == 0) {
|
// 切换到标准模式
|
} else if (mode == 1) {
|
// 切换到简洁模式
|
}
|
}
|
|
/**
|
*
|
* @param {object} data 坐标信息
|
* @param {number} id face_id,用于关联识别姓名用
|
* @param {bool} isLiving 是否活体
|
*/
|
screen.trackUpdate = function (data, id, isLiving) {
|
let item = mainView.trackFaces[0]
|
for (let i = 0; i < 10; i++) {
|
let ele = mainView.trackFaces[i]
|
if (ele.face_id == id) {
|
item = ele
|
break
|
}
|
if (ele.face_id === undefined) {
|
item = ele
|
}
|
}
|
item.face_id = id
|
|
if (item && item.timer) {
|
std.clearTimeout(item.timer)
|
item.timer = null
|
}
|
|
item.timer = std.setTimeout(() => {
|
item.trackFace.hide()
|
if (item.timer) {
|
std.clearTimeout(item.timer)
|
item.timer = null
|
}
|
}, 300)
|
|
let edge = data.w > data.h ? data.w : data.h
|
let offset = Math.abs(data.w - data.h) / 2
|
item.trackFace.show()
|
item.trackFace.setSize(edge, edge)
|
item.trackFace.radius(edge / 2)
|
if (data.w > data.h) {
|
item.trackFace.setPos(data.x, data.y - offset)
|
} else {
|
item.trackFace.setPos(data.x - offset, data.y)
|
}
|
item.trackFaceName.text(" ")
|
if (item.result && item.result.result === true && item.result.id == id) {
|
item.trackFace.setBorderColor(viewUtils.color.success)
|
let user = sqliteService.d1_person.findByUserId(item.result.userId)[0]
|
item.trackFaceName.text(user ? user.name : "")
|
} else if (item.result && item.result.result === false && item.result.id == id) {
|
item.trackFace.setBorderColor(viewUtils.color.fail)
|
} else if (isLiving) {
|
item.trackFace.setBorderColor(0xf3e139)
|
} else {
|
item.trackFace.setBorderColor(0xffffff)
|
}
|
}
|
|
// 认证结果
|
screen.trackResult = function (data) {
|
for (let i = 0; i < 10; i++) {
|
let ele = mainView.trackFaces[i]
|
if (ele.face_id == data.id) {
|
ele.result = data
|
return
|
}
|
}
|
}
|
|
screen.hideSn = function (bool) {
|
if (bool) {
|
mainView.bottomSnBtn.show()
|
mainView.bottomBox.show()
|
} else {
|
mainView.bottomSnBtn.hide()
|
if (config.get("base.showIp") == 0) {
|
mainView.bottomBox.hide()
|
}
|
}
|
}
|
|
screen.hideIp = function (bool) {
|
if (bool) {
|
if (mainView.ipInfoLbl) mainView.ipInfoLbl.show()
|
mainView.bottomBox.show()
|
} else {
|
if (mainView.ipInfoLbl) mainView.ipInfoLbl.hide()
|
if (config.get("base.showSn") == 0) {
|
mainView.bottomBox.hide()
|
}
|
}
|
}
|
|
screen.hideBottomBox = function (bool) {
|
if (bool) {
|
mainView.bottomBox.hide()
|
} else {
|
mainView.bottomBox.show()
|
}
|
}
|
|
screen.changeLanguage = function () {
|
let language = screen.getConfig()['base.language']
|
i18n.setLanguage(language)
|
driver.screen.reload(language)
|
}
|
|
screen.upgrade = function (data) {
|
const { title, content } = data
|
viewUtils.confirmOpen(title, content)
|
}
|
|
screen.netReconnect = function () {
|
driver.net.reconnect()
|
}
|
|
screen.getSqliteService = function () {
|
return sqliteService
|
}
|
|
screen.updateFaceConfig = function (config) {
|
driver.face.setConfig(config)
|
}
|
|
screen.getCapcal = function () {
|
return driver.capcal
|
}
|
|
screen.mqttReply = function (serialNo, data, code) {
|
return mqttService.mqttReply(serialNo, data, code)
|
}
|
|
screen.MQTT_CODE = mqttService.CODE
|
|
// 删除凭证、人员、权限、人脸
|
screen.deleteAll = function () {
|
sqliteService.d1_pass_record.deleteAll()
|
sqliteService.d1_permission.deleteAll()
|
sqliteService.d1_voucher.deleteAll()
|
sqliteService.d1_person.deleteAll()
|
}
|
|
screen.getNetMac = function () {
|
return driver.net.getNetMac()
|
}
|
|
screen.reload = function () {
|
screen.screenNow.send(dxui.Utils.ENUM.LV_EVENT_SCREEN_LOADED)
|
}
|
|
screen.isInternationalVersion = function () {
|
try {
|
let savedVersion = std.loadFile('/etc/app/region.conf')
|
// 文件有内容代表国际版本,无内容代表国内版本
|
return savedVersion && savedVersion.trim() == "INTL"
|
} catch (e) {
|
// 如果文件不存在或读取失败,默认返回false(国内版本)
|
return false
|
}
|
}
|
|
|
/**
|
* 显示通行结果弹窗
|
* @param {object} data - 通行结果数据
|
* @param {boolean} data.faceAuth - 人脸识别是否通过
|
* @param {boolean} data.gasConcentration - 气体浓度是否合格
|
* @param {boolean} data.accessAllowed - 是否允许通行
|
* @param {string} data.message - 弹窗消息
|
*/
|
screen.showAccessResult = function (data) {
|
// // 显示状态面板,3秒后自动关闭
|
// if (data.accessAllowed) {
|
// mainView.statusPanel.success(data.message)
|
// } else {
|
// mainView.statusPanel.fail(data.message)
|
// }
|
|
|
// 显示小型状态面板,3秒后自动关闭
|
if (data.accessAllowed) {
|
mainView.smallStatusPanel.success(data.message)
|
} else {
|
mainView.smallStatusPanel.fail(data.message)
|
}
|
}
|
|
screen.driver = driver
|
screen.weCom = weComService
|
screen.dxDriver = dxDriver
|
|
export default screen
|