import dxui from '../../dxmodules/dxUi.js' import std from '../../dxmodules/dxStd.js' import viewUtils from "./viewUtils.js" import appView from './appView.js' import topView from './topView.js' import pwdView from './pwdView.js' import emergencyPwdView from './emergencyPwdView.js' import newPwdView from './config/newPwdView.js' import screen from '../screen.js' import logger from '../../dxmodules/dxLogger.js' import config from '../../dxmodules/dxConfig.js' import bus from '../../dxmodules/dxEventBus.js' import net from '../../dxmodules/dxNet.js' import accessService from '../service/accessService.js' import grainService from '../service/grainService.js' import dxMap from '../../dxmodules/dxMap.js' import sqliteService from '../service/sqliteService.js' import driver from '../driver.js' import capturer from '../../dxmodules/dxCapturer.js' let map = dxMap.get("LOGIN") const mainView = { authComplete: false, // 认证是否完成,用于控制UI更新 verifiedUsers: {}, // 存储已核验成功的用户信息 eventListenersRegistered: false // 事件监听器是否已注册 } mainView.init = function () { logger.info('[mainView]: init函数开始执行') /**************************************************创建屏幕*****************************************************/ const screenMain = dxui.View.build('mainView', dxui.Utils.LAYER.MAIN) mainView.screenMain = screenMain screenMain.scroll(false) screenMain.bgOpa(0) // 更新设备信息(SN和IP) function updateDeviceInfo() { let config = screen.getConfig() let sn = config["sys.sn"] || "" // 直接从net模块获取IP地址,确保获取到最新的IP let ip = "" try { let netType = config["net.type"] || 1 let netMode = net.getModeByCard(netType) if (netMode && netMode.param && netMode.param.ip) { ip = netMode.param.ip } } catch (error) { // 出错时使用config中的IP ip = config["net.ip"] || "" } // 通过mainView对象访问标签 if (mainView.snInfoLbl && mainView.ipInfoLbl) { mainView.snInfoLbl.text("SN: " + sn) mainView.ipInfoLbl.text("IP: " + ip) } // 更新overlayBox中的设备信息 if (mainView.overlaySnLbl && mainView.overlayIpLbl) { mainView.overlaySnLbl.text("SN: " + sn) mainView.overlayIpLbl.text("IP: " + ip) } } // 更新库区名称和仓号(只在程序启动和配置修改时调用) function updateWarehouseInfo() { let config = screen.getConfig() // 获取仓号信息 let houseName = config["houseName"] || "01号仓" // 获取库区名称 let GranaryName = config["GranaryName"] || "中央储备粮某某直属库" logger.info(`[mainView]: 更新库区名称和仓号: 仓号=${houseName}, 库区名称=${GranaryName}`) // 更新顶部标题栏的库区名称 if (mainView.headerLbl) { mainView.headerLbl.text(GranaryName) } // 更新仓号显示 if (mainView.warehouseLbl) { logger.info(`[mainView]: 更新仓号显示为: ${houseName}`) mainView.warehouseLbl.text(houseName) } else { logger.error('[mainView]: warehouseLbl不存在') } } screenMain.on(dxui.Utils.ENUM.LV_EVENT_SCREEN_LOADED, () => { topView.changeTheme(false) // 程序启动时更新库区名称和仓号 updateWarehouseInfo() // 只注册一次事件监听器 if (!mainView.eventListenersRegistered) { logger.info('[mainView]: 开始注册事件监听器') // 网络状态监听 bus.on(net.STATUS_CHANGE, (data) => { if (data.connected) { // 网络连接时更新IP信息 updateDeviceInfo() } }) // 定期更新设备信息(每5秒) std.setInterval(() => { updateDeviceInfo() }, 5000) // 气体浓度更新事件监听 bus.on('gasConcentrationUpdated', (data) => { logger.info(`[mainView]: 气体浓度更新事件触发: ${JSON.stringify(data)}`) // 检查气体浓度数据是否存在 if (data.data && data.data.value) { const gasValue = data.data.value[0] const isO2Qualified = gasValue && gasValue.statusO2 === "0" const isCo2Qualified = gasValue && gasValue.statusCo2 === "0" const isPh3Qualified = gasValue && gasValue.statusPh3 === "0" if (mainView.oxygenValue && mainView.oxygenStatus && mainView.oxygenBox) { mainView.oxygenValue.text(gasValue ? gasValue.o2 : '未知') mainView.oxygenStatus.text(isO2Qualified ? '合格' : '不合格') // 根据状态更新背景图片 if (!isO2Qualified) { mainView.oxygenBox.source('/app/code/resource/image/o2_f.png') // 不合格背景图 } else { mainView.oxygenBox.source('/app/code/resource/image/o2_s.png') // 合格背景图 } // 刷新UI mainView.oxygenValue.update() mainView.oxygenStatus.update() mainView.oxygenBox.update() mainView.oxygenValue.invalidate() mainView.oxygenStatus.invalidate() mainView.oxygenBox.invalidate() } if (mainView.co2Value && mainView.co2Status && mainView.co2Box) { mainView.co2Value.text(gasValue ? gasValue.co2 : '未知') mainView.co2Status.text(isCo2Qualified ? '合格' : '不合格') // 根据状态更新背景图片 if (!isCo2Qualified) { mainView.co2Box.source('/app/code/resource/image/co2_f.png') // 不合格背景图 } else { mainView.co2Box.source('/app/code/resource/image/co2_s.png') // 合格背景图 } // 刷新UI mainView.co2Value.update() mainView.co2Status.update() mainView.co2Box.update() mainView.co2Value.invalidate() mainView.co2Status.invalidate() mainView.co2Box.invalidate() } if (mainView.ph3Value && mainView.ph3Status && mainView.ph3Box) { // 明确检查 ph3 是否存在,而不是使用 || 运算符 let ph3Value = '0' if (gasValue) { if (gasValue.ph3) { ph3Value = gasValue.ph3 } else if (gasValue.statusPh3) { ph3Value = gasValue.statusPh3 } } mainView.ph3Value.text(ph3Value) mainView.ph3Status.text(isPh3Qualified ? '合格' : '不合格') // 根据状态更新背景图片 if (!isPh3Qualified) { mainView.ph3Box.source('/app/code/resource/image/ph3_f.png') // 不合格背景图 } else { mainView.ph3Box.source('/app/code/resource/image/ph3_s.png') // 合格背景图 } // 刷新UI mainView.ph3Value.update() mainView.ph3Status.update() mainView.ph3Box.update() mainView.ph3Value.invalidate() mainView.ph3Status.invalidate() mainView.ph3Box.invalidate() } } else { logger.error(`[mainView]: 气体浓度数据不存在`) } }) // 库区名称和仓号更新事件监听(配置修改时触发) bus.on('warehouseInfoUpdated', () => { logger.info('[mainView]: 收到库区名称和仓号更新事件') updateWarehouseInfo() }) // 通行结果事件监听(处理成功和失败) bus.on('accessRes', (result, data) => { logger.info('[mainView]: accessRes事件触发, result=' + result + ', data=' + JSON.stringify(data)) // 清除之前的定时器 if (resetTimerId) { std.clearTimeout(resetTimerId) resetTimerId = null logger.info('[mainView]: 清除之前的重置定时器') } // 如果是通行成功,执行通行成功的逻辑 if (result) { // 检查是否是双人认证 if (data && data.data && data.data.dualAuthInfo) { // 双人认证,分别更新用户1和用户2的UI let dualAuthInfo = data.data.dualAuthInfo // 设置认证完成标志 mainView.authComplete = true // 存储已核验成功的用户信息 mainView.verifiedUsers[1] = dualAuthInfo.firstUserId mainView.verifiedUsers[2] = dualAuthInfo.secondUserId logger.info('[mainView]: 存储双人认证用户信息, user1=' + dualAuthInfo.firstUserId + ', user2=' + dualAuthInfo.secondUserId) // 只更新用户2的信息,用户1的信息已经在trackResult事件中更新 let ret2 = sqliteService.d1_person.find({ userId: dualAuthInfo.secondUserId }) if (ret2 && ret2.length > 0) { let userName2 = ret2[0].name let userType2 = 0 try { userType2 = JSON.parse(ret2[0].extra).type || 0 } catch (error) { logger.error("解析用户2类型失败") } // 检查用户2权限 let hasPermission2 = false let permissions2 = sqliteService.d1_permission.find({ userId: dualAuthInfo.secondUserId }) if (permissions2 && permissions2.length > 0) { hasPermission2 = true } // 更新用户2的UI if (mainView.user2Name) { mainView.user2Name.text(userName2) } if (mainView.user2Role) { mainView.user2Role.text(userType2 === 1 ? '科长' : '保管员') } if (mainView.user2StatusLbl) { if (hasPermission2) { mainView.user2Box.source('/app/code/resource/image/user_s.png') // 核验成功背景图 mainView.user2StatusLbl.text('核验成功') } else { mainView.user2Box.source('/app/code/resource/image/user_f.png') // 核验失败背景图 mainView.user2StatusLbl.text('核验失败') } } logger.info('[mainView]: 用户2信息已更新:' + userName2 + ', ' + (userType2 === 1 ? '科长' : '保管员') + ', ' + (hasPermission2 ? '核验成功' : '核验失败')) } } else { // 单人认证,检查用户是否已经作为第二用户进行了认证 if (data && data.data && data.data.userId) { let userId = data.data.userId // 检查用户是否已经作为第二用户进行了认证 if (mainView.verifiedUsers[2] === userId) { // 用户已经作为第二用户进行了认证,不更新用户1的UI logger.info('[mainView]: 用户已作为第二用户进行了认证,不更新用户1的UI') } else { // 存储已核验成功的用户信息 mainView.verifiedUsers[1] = userId logger.info('[mainView]: 存储单人认证用户信息, user1=' + userId) let ret = sqliteService.d1_person.find({ userId: userId }) if (ret && ret.length > 0) { let userName = ret[0].name let userType = 0 try { userType = JSON.parse(ret[0].extra).type || 0 } catch (error) { logger.error("解析用户类型失败") } // 检查用户权限 let hasPermission = false let permissions = sqliteService.d1_permission.find({ userId: userId }) if (permissions && permissions.length > 0) { hasPermission = true } // 更新用户1的UI if (mainView.user1Name) { mainView.user1Name.text(userName) } if (mainView.user1Role) { mainView.user1Role.text(userType === 1 ? '科长' : '保管员') } // 更新核验区背景色和状态文本 if (mainView.user1StatusLbl) { if (hasPermission) { mainView.user1Box.source('/app/code/resource/image/user_s.png') // 核验成功背景图 mainView.user1StatusLbl.text('核验成功') } else { mainView.user1Box.source('/app/code/resource/image/user_f.png') // 核验失败背景图 mainView.user1StatusLbl.text('核验失败') } } logger.info('[mainView]: 用户1信息已更新:' + userName + ', ' + (userType === 1 ? '科长' : '保管员') + ', ' + (hasPermission ? '核验成功' : '核验失败')) } } } } } else { // 通行失败,显示失败信息 if (mainView.smallStatusPanel && mainView.smallStatusPanel.fail) { mainView.smallStatusPanel.fail('mainView.fail') } } // 设置1分钟后重置用户UI的定时器 resetTimerId = std.setTimeout(() => { logger.info('[mainView]: 1分钟定时器触发,重置用户UI') // 触发通行解锁完成事件,通知UI重置 bus.fire("accessUnlockComplete") }, 60000) // 60000毫秒 = 1分钟 logger.info('[mainView]: 设置1分钟后重置用户UI的定时器') }) // 状态信息更新事件监听 bus.on('statusInfoUpdated', (data) => { // 只处理安全入仓控制的响应,忽略非安全入仓控制的响应 const safeInputControlFunctionId = config['functionId.safeInputControl'] || '2000' if (data.functionId && data.functionId !== safeInputControlFunctionId) { logger.info(`[mainView]: 忽略非安全入仓控制的响应,functionId=${data.functionId}`) return } // 这里可以根据实际的状态信息数据结构来更新UI logger.info(`[mainView]: 状态信息更新: ${JSON.stringify(data)}`) // 检查返回的mode和btn参数 if (data.data) { const mode = parseInt(data.data.mode) // 将字符串转换为数字 const btn = parseInt(data.data.btn) // 将字符串转换为数字 logger.info(`[mainView]: 接收到mode=${mode}, btn=${btn}`) // 重置所有按钮为蓝色背景 if (mainView.mode1Btn) mainView.mode1Btn.bgColor(0x017FEB) if (mainView.inBtn) mainView.inBtn.bgColor(0x017FEB) if (mainView.outBtn) mainView.outBtn.bgColor(0x017FEB) if (mainView.mode2Btn) mainView.mode2Btn.bgColor(0x017FEB) if (mainView.startBtn) mainView.startBtn.bgColor(0x017FEB) if (mainView.stopBtn) mainView.stopBtn.bgColor(0x017FEB) if (mainView.mode3Btn) mainView.mode3Btn.bgColor(0x017FEB) if (mainView.emergencyInBtn) mainView.emergencyInBtn.bgColor(0x017FEB) if (mainView.emergencyOutBtn) mainView.emergencyOutBtn.bgColor(0x017FEB) // 根据mode和btn更新按钮状态 if (mode === 1) { // 允许进仓模式 if (mainView.mode1Btn) mainView.mode1Btn.bgColor(0x037D41) // 允许进仓模式按钮设为绿色 if (btn === 1) { // 入仓 if (mainView.inBtn) mainView.inBtn.bgColor(0x037D41) // 入仓按钮设为绿色 } else if (btn === 2) { // 出仓 if (mainView.outBtn) mainView.outBtn.bgColor(0x037D41) // 出仓按钮设为绿色 } } else if (mode === 2) { // 冬季通风模式 if (mainView.mode2Btn) mainView.mode2Btn.bgColor(0x037D41) // 冬季通风模式按钮设为绿色 if (btn === 1) { // 启动 if (mainView.startBtn) mainView.startBtn.bgColor(0x037D41) // 启动按钮设为绿色 } else if (btn === 2) { // 关闭 if (mainView.stopBtn) mainView.stopBtn.bgColor(0x037D41) // 关闭按钮设为绿色 } } else if (mode === 3) { // 禁止进仓模式 if (mainView.mode3Btn) mainView.mode3Btn.bgColor(0x037D41) // 禁止进仓模式按钮设为绿色 if (btn === 1) { // 紧急入仓 if (mainView.emergencyInBtn) mainView.emergencyInBtn.bgColor(0x037D41) // 紧急入仓按钮设为绿色 } else if (btn === 2) { // 出仓 if (mainView.emergencyOutBtn) mainView.emergencyOutBtn.bgColor(0x037D41) // 出仓按钮设为绿色 } } } else if (data.safeInput) { // 传统方式更新按钮状态(0-蓝色,1-绿色) // 允许进仓模式相关按钮 if (mainView.mode1Btn) { mainView.mode1Btn.bgColor(data.safeInput.A === '1' ? 0x037D41 : 0x017FEB) } if (mainView.inBtn) { mainView.inBtn.bgColor(data.safeInput.A1 === '1' ? 0x037D41 : 0x017FEB) } if (mainView.outBtn) { mainView.outBtn.bgColor(data.safeInput.A2 === '1' ? 0x037D41 : 0x017FEB) } // 冬季通风模式相关按钮 if (mainView.mode2Btn) { mainView.mode2Btn.bgColor(data.safeInput.B === '1' ? 0x037D41 : 0x017FEB) } if (mainView.startBtn) { mainView.startBtn.bgColor(data.safeInput.B1 === '1' ? 0x037D41 : 0x017FEB) } if (mainView.stopBtn) { mainView.stopBtn.bgColor(data.safeInput.B2 === '1' ? 0x037D41 : 0x017FEB) } // 禁止进仓模式相关按钮 if (mainView.mode3Btn) { mainView.mode3Btn.bgColor(data.safeInput.C === '1' ? 0x037D41 : 0x017FEB) } if (mainView.emergencyInBtn) { mainView.emergencyInBtn.bgColor(data.safeInput.C1 === '1' ? 0x037D41 : 0x017FEB) } if (mainView.emergencyOutBtn) { mainView.emergencyOutBtn.bgColor(data.safeInput.C2 === '1' ? 0x037D41 : 0x017FEB) } } }) // 通行解锁完成事件监听,重置用户UI bus.on('accessUnlockComplete', () => { logger.info('[mainView]: accessUnlockComplete事件触发,重置用户UI') // 重置认证完成标志 mainView.authComplete = false // 重置已核验用户信息 mainView.verifiedUsers = {} // 重置用户1的UI if (mainView.user1Name) { mainView.user1Name.text('xx') } if (mainView.user1Role) { mainView.user1Role.text('保管员') } if (mainView.user1Box && mainView.user1StatusLbl) { mainView.user1Box.source('/app/code/resource/image/user_w.png') // 待核验背景图 mainView.user1StatusLbl.text('待核验') } // 重置用户2的UI if (mainView.user2Name) { mainView.user2Name.text('xx') } if (mainView.user2Role) { mainView.user2Role.text('保管员') } if (mainView.user2Box && mainView.user2StatusLbl) { mainView.user2Box.source('/app/code/resource/image/user_w.png') // 待核验背景图 mainView.user2StatusLbl.text('待核验') } // 恢复人脸认证功能 try { driver.face.status(true) logger.info('[mainView]: 恢复人脸认证功能') } catch (error) { logger.error('[mainView]: 恢复人脸认证功能失败: ' + error.message) } logger.info('[mainView]: 用户UI已重置') }) // 人脸识别结果事件监听(移到LV_EVENT_SCREEN_LOADED回调中) if (!mainView.trackResultListenerRegistered) { logger.info('[mainView]: 开始注册trackResult事件监听器') bus.on('trackResult', (data) => { logger.info('[mainView]: trackResult事件触发, data=' + JSON.stringify(data)) logger.info('[mainView]: authComplete=' + mainView.authComplete + ', data.result=' + data.result + ', data.userId=' + data.userId + ', data.userIndex=' + data.userIndex + ', data.fileName=' + data.fileName) // 只在人脸认证成功时存储用户信息 if (data.result === true && data.userId) { // 存储已核验成功的用户信息(无论是否有权限都存储) mainView.verifiedUsers[data.userIndex] = data.userId logger.info('[mainView]: 存储已核验成功的用户信息, userIndex=' + data.userIndex + ', userId=' + data.userId) // 调用updateUserUI方法更新用户UI,传递人脸图片路径 mainView.updateUserUI(data.userIndex, data.userId, false, data.fileName) } }) mainView.trackResultListenerRegistered = true logger.info('[mainView]: trackResult事件监听器注册完成') } mainView.eventListenersRegistered = true logger.info('[mainView]: 事件监听器注册完成') } // 存储定时器ID let resetTimerId = null // 获取气体浓度和状态信息 grainService.checkGasConcentration() grainService.checkDevConcentration() // screen.trackUpdate() screen.appMode(screen.getConfig()["base.appMode"]) // 开始人脸识别(移到屏幕加载完成后) screen.faceRecgStart() }) screenMain.on(dxui.Utils.ENUM.LV_EVENT_SCREEN_UNLOADED, () => { screen.faceRecgPause() }) mainView.trackFaces = [] for (let i = 0; i < 10; i++) { let item = {} const trackFace = dxui.View.build('trackFace' + i, screenMain) item.trackFace = trackFace viewUtils._clearStyle(trackFace) trackFace.setSize(200, 200) trackFace.borderWidth(5) trackFace.setBorderColor(0xffffff) trackFace.bgOpa(0) trackFace.hide() const trackFaceName = dxui.Label.build('trackFaceName' + i, trackFace) item.trackFaceName = trackFaceName trackFaceName.textFont(viewUtils.font(30)) trackFaceName.textColor(0xffffff) trackFaceName.text(" ") trackFaceName.align(dxui.Utils.ALIGN.BOTTOM_MID, 0, 0) // trackFaceName.hide() mainView.trackFaces.push(item) } // const trackFace = dxui.View.build('trackFace', screenMain) // mainView.trackFace = trackFace // viewUtils._clearStyle(trackFace) // trackFace.setSize(200, 200) // trackFace.borderWidth(5) // trackFace.bgOpa(0) // trackFace.hide() // const trackFaceName = dxui.Label.build('trackFaceName', trackFace) // mainView.trackFaceName = trackFaceName // trackFaceName.textFont(viewUtils.font(30)) // trackFaceName.textColor(0xffffff) // trackFaceName.text(" ") // trackFaceName.align(dxui.Utils.ALIGN.BOTTOM_MID, 0, 0) const bottomBox = dxui.Image.build('bottomBox', screenMain) mainView.bottomBox = bottomBox bottomBox.source('/app/code/resource/image/rectangle.png') bottomBox.align(dxui.Utils.ALIGN.BOTTOM_MID, 0, 0) bottomBox.hide() // 隐藏bottomBox const bottomSnBtn = dxui.Button.build('bottomSnBtn', bottomBox) mainView.bottomSnBtn = bottomSnBtn bottomSnBtn.bgColor(0xffffff) bottomSnBtn.bgOpa(20) bottomSnBtn.setSize(204, 36) bottomSnBtn.shadow(0, 0, 0, 0, 0xffffff, 100) bottomSnBtn.align(dxui.Utils.ALIGN.BOTTOM_LEFT, 13, -18) bottomSnBtn.on(dxui.Utils.EVENT.CLICK, () => { // 移除二维码显示功能 }) bottomSnBtn.flexFlow(dxui.Utils.FLEX_FLOW.ROW) bottomSnBtn.flexAlign(dxui.Utils.FLEX_ALIGN.CENTER, dxui.Utils.FLEX_ALIGN.CENTER, dxui.Utils.FLEX_ALIGN.CENTER) bottomSnBtn.obj.lvObjSetStylePadGap(5, dxui.Utils.ENUM._LV_STYLE_STATE_CMP_SAME) // 添加半透明覆盖图层 const overlayBox = dxui.View.build('overlayBox', screenMain) mainView.overlayBox = overlayBox viewUtils._clearStyle(overlayBox) overlayBox.setSize(screen.screenSize.width, screen.screenSize.height) overlayBox.align(dxui.Utils.ALIGN.TOP_MID, 0, 0) overlayBox.bgColor(0xffffff) overlayBox.bgOpa(50) // 半透明效果 overlayBox.clickable(false) // 不拦截点击事件,让点击可以穿透 overlayBox.scroll(false) // 禁用滚动功能 overlayBox.show() // 确保overlayBox显示 logger.info('[mainView]: overlayBox已创建并显示') // 在overlayBox上创建认证结果展示区域(位于userBox和controlBox之间) // 初始化小型状态面板 mainView.smallStatusPanel = viewUtils.smallStatusPanel(overlayBox, 'mainView.success', 'mainView.fail') // 调整小型状态面板位置 if (mainView.smallStatusPanel.successBg) { mainView.smallStatusPanel.successBg.align(dxui.Utils.ALIGN.TOP_MID, 0, 450) } if (mainView.smallStatusPanel.failBg) { mainView.smallStatusPanel.failBg.align(dxui.Utils.ALIGN.TOP_MID, 0, 450) } // 设备信息显示(SN和IP)- 提前定义,确保在回调中可用 const mainDeviceInfoBox = dxui.View.build('mainDeviceInfoBox', overlayBox) viewUtils._clearStyle(mainDeviceInfoBox) mainDeviceInfoBox.setSize(screen.screenSize.width, 40) mainDeviceInfoBox.align(dxui.Utils.ALIGN.BOTTOM_MID, 0, 20) // 调整位置,距离底部20px mainDeviceInfoBox.bgOpa(0) mainDeviceInfoBox.flexFlow(dxui.Utils.FLEX_FLOW.ROW) mainDeviceInfoBox.flexAlign(dxui.Utils.FLEX_ALIGN.SPACE_BETWEEN, dxui.Utils.FLEX_ALIGN.CENTER, dxui.Utils.FLEX_ALIGN.CENTER) // SN信息 const overlaySnLbl = dxui.Label.build('overlaySnLbl', mainDeviceInfoBox) overlaySnLbl.text("SN:") overlaySnLbl.textFont(viewUtils.font(16)) // 增大字体 overlaySnLbl.textColor(0x000000) overlaySnLbl.width(220) overlaySnLbl.longMode(dxui.Utils.LABEL_LONG_MODE.SCROLL_CIRCULAR) overlaySnLbl.align(dxui.Utils.ALIGN.BOTTOM_LEFT, 30, 0) // 调整位置,距离左侧30px // IP信息 const overlayIpLbl = dxui.Label.build('overlayIpLbl', mainDeviceInfoBox) mainView.overlayIpLbl = overlayIpLbl mainView.overlaySnLbl = overlaySnLbl overlayIpLbl.text("IP:") overlayIpLbl.textFont(viewUtils.font(16)) // 增大字体 overlayIpLbl.textColor(0x000000) overlayIpLbl.align(dxui.Utils.ALIGN.BOTTOM_RIGHT, -30, 0) // 调整位置,距离右侧30px // 顶部标题栏 const headerBox = dxui.View.build('headerBox', overlayBox) viewUtils._clearStyle(headerBox) headerBox.setSize(screen.screenSize.width, 63) // 增大高度 headerBox.align(dxui.Utils.ALIGN.TOP_MID, 0, 0) headerBox.bgColor(0x037D41) headerBox.flexFlow(dxui.Utils.FLEX_FLOW.ROW) headerBox.flexAlign(dxui.Utils.FLEX_ALIGN.CENTER, dxui.Utils.FLEX_ALIGN.CENTER, dxui.Utils.FLEX_ALIGN.CENTER) headerBox.obj.lvObjSetStylePadGap(10, dxui.Utils.ENUM._LV_STYLE_STATE_CMP_SAME) // 添加logo图标 const logoImg = dxui.Image.build('logoImg', headerBox) logoImg.source('/app/code/resource/image/logo.png') logoImg.setSize(34, 37) const headerLbl = dxui.Label.build('headerLbl', headerBox) mainView.headerLbl = headerLbl // 从配置中获取库区名称 const config = screen.getConfig() const GranaryName = config['GranaryName'] || '中央储备粮某某直属库' headerLbl.text(GranaryName) headerLbl.textFont(viewUtils.font(34)) // 增大字体 headerLbl.textColor(0xffffff) // 仓号显示 const warehouseLbl = dxui.Label.build('warehouseLbl', overlayBox) mainView.warehouseLbl = warehouseLbl // 从配置中获取仓号信息 const houseName = config['houseName'] || '01号仓' warehouseLbl.text(houseName) warehouseLbl.textFont(viewUtils.font(34, dxui.Utils.FONT_STYLE.BOLD)) warehouseLbl.textColor(0x000000) warehouseLbl.align(dxui.Utils.ALIGN.TOP_MID, 0, 80) // 气体浓度显示 const gasBox = dxui.View.build('gasBox', overlayBox) viewUtils._clearStyle(gasBox) gasBox.setSize(screen.screenSize.width, 180) gasBox.align(dxui.Utils.ALIGN.TOP_MID, 11, 140) gasBox.bgOpa(0) gasBox.flexFlow(dxui.Utils.FLEX_FLOW.ROW) gasBox.flexAlign(dxui.Utils.FLEX_ALIGN.FLEX_START, dxui.Utils.FLEX_ALIGN.CENTER, dxui.Utils.FLEX_ALIGN.CENTER) gasBox.obj.lvObjSetStylePadGap(30, dxui.Utils.ENUM._LV_STYLE_STATE_CMP_SAME) // 设置气体框间距 // 氧气浓度 const oxygenBox = dxui.Image.build('oxygenBox', gasBox) viewUtils._clearStyle(oxygenBox) oxygenBox.setSize(239, 166) oxygenBox.source('/app/code/resource/image/o2_s.png') // 默认使用合格背景图 mainView.oxygenBox = oxygenBox // 设置为mainView属性 const oxygenTitle = dxui.Label.build('oxygenTitle', oxygenBox) oxygenTitle.text('氧气') oxygenTitle.textFont(viewUtils.font(24)) oxygenTitle.textColor(0xffffff) oxygenTitle.align(dxui.Utils.ALIGN.TOP_MID, 0, 18) // 氧气数值和单位容器 const oxygenValueContainer = dxui.View.build('oxygenValueContainer', oxygenBox) viewUtils._clearStyle(oxygenValueContainer) oxygenValueContainer.setSize(100, 40) oxygenValueContainer.bgOpa(0) oxygenValueContainer.align(dxui.Utils.ALIGN.CENTER, 0, 0) oxygenValueContainer.flexFlow(dxui.Utils.FLEX_FLOW.ROW) oxygenValueContainer.flexAlign(dxui.Utils.FLEX_ALIGN.CENTER, dxui.Utils.FLEX_ALIGN.CENTER, dxui.Utils.FLEX_ALIGN.CENTER) oxygenValueContainer.obj.lvObjSetStylePadGap(5, dxui.Utils.ENUM._LV_STYLE_STATE_CMP_SAME) // 氧气数值部分 const oxygenValue = dxui.Label.build('oxygenValue', oxygenValueContainer) oxygenValue.text('20') oxygenValue.textFont(viewUtils.font(26, dxui.Utils.FONT_STYLE.BOLD)) oxygenValue.textColor(0xffffff) mainView.oxygenValue = oxygenValue // 设置为mainView属性 // 氧气单位部分 const oxygenUnit = dxui.Label.build('oxygenUnit', oxygenValueContainer) oxygenUnit.text('%') oxygenUnit.textFont(viewUtils.font(14)) oxygenUnit.textColor(0xffffff) mainView.oxygenUnit = oxygenUnit // 设置为mainView属性 const oxygenStatus = dxui.Label.build('oxygenStatus', oxygenBox) oxygenStatus.text('合格') oxygenStatus.textFont(viewUtils.font(24, dxui.Utils.FONT_STYLE.BOLD)) oxygenStatus.textColor(0xffffff) oxygenStatus.align(dxui.Utils.ALIGN.BOTTOM_MID, 0, -20) mainView.oxygenStatus = oxygenStatus // 设置为mainView属性 // 磷化氢浓度 const ph3Box = dxui.Image.build('ph3Box', gasBox) viewUtils._clearStyle(ph3Box) ph3Box.setSize(239, 166) ph3Box.source('/app/code/resource/image/ph3_s.png') // 默认使用合格背景图 mainView.ph3Box = ph3Box // 设置为mainView属性 const ph3Title = dxui.Label.build('ph3Title', ph3Box) ph3Title.text('磷化氢') ph3Title.textFont(viewUtils.font(24)) ph3Title.textColor(0xffffff) ph3Title.align(dxui.Utils.ALIGN.TOP_MID, 0, 18) // 磷化氢数值和单位容器 const ph3ValueContainer = dxui.View.build('ph3ValueContainer', ph3Box) viewUtils._clearStyle(ph3ValueContainer) ph3ValueContainer.setSize(100, 40) ph3ValueContainer.bgOpa(0) ph3ValueContainer.align(dxui.Utils.ALIGN.CENTER, 0, 0) ph3ValueContainer.flexFlow(dxui.Utils.FLEX_FLOW.ROW) ph3ValueContainer.flexAlign(dxui.Utils.FLEX_ALIGN.CENTER, dxui.Utils.FLEX_ALIGN.CENTER, dxui.Utils.FLEX_ALIGN.CENTER) ph3ValueContainer.obj.lvObjSetStylePadGap(5, dxui.Utils.ENUM._LV_STYLE_STATE_CMP_SAME) // 磷化氢数值部分 const ph3Value = dxui.Label.build('ph3Value', ph3ValueContainer) ph3Value.text('0') ph3Value.textFont(viewUtils.font(26, dxui.Utils.FONT_STYLE.BOLD)) ph3Value.textColor(0xffffff) mainView.ph3Value = ph3Value // 设置为mainView属性 // 磷化氢单位部分 const ph3Unit = dxui.Label.build('ph3Unit', ph3ValueContainer) ph3Unit.text('PPM') ph3Unit.textFont(viewUtils.font(14)) ph3Unit.textColor(0xffffff) mainView.ph3Unit = ph3Unit // 设置为mainView属性 const ph3Status = dxui.Label.build('ph3Status', ph3Box) ph3Status.text('合格') ph3Status.textFont(viewUtils.font(24, dxui.Utils.FONT_STYLE.BOLD)) ph3Status.textColor(0xffffff) ph3Status.align(dxui.Utils.ALIGN.BOTTOM_MID, 0, -20) mainView.ph3Status = ph3Status // 设置为mainView属性 // 二氧化碳浓度 const co2Box = dxui.Image.build('co2Box', gasBox) viewUtils._clearStyle(co2Box) co2Box.setSize(239, 166) co2Box.source('/app/code/resource/image/co2_s.png') // 默认使用合格背景图 mainView.co2Box = co2Box // 设置为mainView属性 const co2Title = dxui.Label.build('co2Title', co2Box) co2Title.text('二氧化碳') co2Title.textFont(viewUtils.font(24)) co2Title.textColor(0xffffff) co2Title.align(dxui.Utils.ALIGN.TOP_MID, 0, 18) // 二氧化碳数值和单位容器 const co2ValueContainer = dxui.View.build('co2ValueContainer', co2Box) viewUtils._clearStyle(co2ValueContainer) co2ValueContainer.setSize(100, 40) co2ValueContainer.bgOpa(0) co2ValueContainer.align(dxui.Utils.ALIGN.CENTER, 0, 0) co2ValueContainer.flexFlow(dxui.Utils.FLEX_FLOW.ROW) co2ValueContainer.flexAlign(dxui.Utils.FLEX_ALIGN.CENTER, dxui.Utils.FLEX_ALIGN.CENTER, dxui.Utils.FLEX_ALIGN.CENTER) co2ValueContainer.obj.lvObjSetStylePadGap(5, dxui.Utils.ENUM._LV_STYLE_STATE_CMP_SAME) // 二氧化碳数值部分 const co2Value = dxui.Label.build('co2Value', co2ValueContainer) co2Value.text('400') co2Value.textFont(viewUtils.font(26, dxui.Utils.FONT_STYLE.BOLD)) co2Value.textColor(0xffffff) mainView.co2Value = co2Value // 设置为mainView属性 // 二氧化碳单位部分 const co2Unit = dxui.Label.build('co2Unit', co2ValueContainer) co2Unit.text('PPM') co2Unit.textFont(viewUtils.font(14)) co2Unit.textColor(0xffffff) mainView.co2Unit = co2Unit // 设置为mainView属性 const co2Status = dxui.Label.build('co2Status', co2Box) co2Status.text('合格') co2Status.textFont(viewUtils.font(24, dxui.Utils.FONT_STYLE.BOLD)) co2Status.textColor(0xffffff) co2Status.align(dxui.Utils.ALIGN.BOTTOM_MID, 0, -20) mainView.co2Status = co2Status // 设置为mainView属性 // 时间显示 const timeLbl = dxui.Label.build('timeLbl', overlayBox) timeLbl.text('12:30:30') timeLbl.textFont(viewUtils.font(36)) timeLbl.textColor(0x000000) timeLbl.align(dxui.Utils.ALIGN.TOP_MID, 0, 310) const overlayDateLbl = dxui.Label.build('overlayDateLbl', overlayBox) overlayDateLbl.text('2026/02/01') overlayDateLbl.textFont(viewUtils.font(20)) overlayDateLbl.textColor(0x000000) overlayDateLbl.align(dxui.Utils.ALIGN.TOP_MID, 0, 360) // 实时更新时间和日期 std.setInterval(() => { const t = new Date() const pad = (n) => n < 10 ? `0${n}` : n timeLbl.text(`${pad(t.getHours())}:${pad(t.getMinutes())}:${pad(t.getSeconds())}`) overlayDateLbl.text(`${t.getFullYear()}/${pad(t.getMonth() + 1)}/${pad(t.getDate())}`) }, 1000, true) // 用户信息显示 const userBox = dxui.View.build('userBox', overlayBox) viewUtils._clearStyle(userBox) userBox.setSize(screen.screenSize.width - 40, 193) // 减去左右各20px的边距 userBox.align(dxui.Utils.ALIGN.TOP_MID, 0, 620) userBox.bgColor(0x000000) // 设置背景颜色为黑色 userBox.bgOpa(0) // 设置背景透明度 userBox.flexFlow(dxui.Utils.FLEX_FLOW.ROW) userBox.flexAlign(dxui.Utils.FLEX_ALIGN.SPACE_BETWEEN, dxui.Utils.FLEX_ALIGN.CENTER, dxui.Utils.FLEX_ALIGN.CENTER) userBox.show() // 确保用户UI显示 mainView.userBox = userBox // 设置为mainView属性 logger.info('[mainView]: userBox已创建并显示在顶部下方580像素位置') // 用户1 const user1Box = dxui.Image.build('user1Box', userBox) viewUtils._clearStyle(user1Box) user1Box.setSize(239, 193) // 使用正确的背景图片尺寸 user1Box.source('/app/code/resource/image/user_w.png') // 默认使用待核验背景图 mainView.user1Box = user1Box // 设置为mainView属性 // 姓名 const user1Name = dxui.Label.build('user1Name', user1Box) user1Name.text('xx') //姓名 user1Name.textFont(viewUtils.font(21, dxui.Utils.FONT_STYLE.BOLD)) user1Name.textColor(0xffffff) user1Name.align(dxui.Utils.ALIGN.TOP_LEFT, 122, 25) mainView.user1Name = user1Name // 设置为mainView属性 // 权限 const user1Role = dxui.Label.build('user1Role', user1Box) user1Role.text('保管员') user1Role.textFont(viewUtils.font(19)) user1Role.textColor(0xffffff) user1Role.align(dxui.Utils.ALIGN.TOP_LEFT, 122, 50) mainView.user1Role = user1Role // 设置为mainView属性 // 核验状态 const user1StatusLbl = dxui.Label.build('user1StatusLbl', user1Box) user1StatusLbl.text('待核验') user1StatusLbl.textFont(viewUtils.font(22, dxui.Utils.FONT_STYLE.BOLD)) user1StatusLbl.textColor(0xffffff) user1StatusLbl.align(dxui.Utils.ALIGN.BOTTOM_MID, 0, -45) mainView.user1StatusLbl = user1StatusLbl // 设置为mainView属性 // 用户2 const user2Box = dxui.Image.build('user2Box', userBox) viewUtils._clearStyle(user2Box) user2Box.setSize(239, 193) // 使用正确的背景图片尺寸 user2Box.source('/app/code/resource/image/user_w.png') // 默认使用待核验背景图 mainView.user2Box = user2Box // 设置为mainView属性 // 姓名 const user2Name = dxui.Label.build('user2Name', user2Box) user2Name.text('xx') user2Name.textFont(viewUtils.font(21, dxui.Utils.FONT_STYLE.BOLD)) user2Name.textColor(0xffffff) user2Name.align(dxui.Utils.ALIGN.TOP_LEFT, 122, 25) mainView.user2Name = user2Name // 设置为mainView属性 // 权限 const user2Role = dxui.Label.build('user2Role', user2Box) user2Role.text('保管员') user2Role.textFont(viewUtils.font(19)) user2Role.textColor(0xffffff) user2Role.align(dxui.Utils.ALIGN.TOP_LEFT, 122, 50) mainView.user2Role = user2Role // 设置为mainView属性 // 核验状态 const user2StatusLbl = dxui.Label.build('user2StatusLbl', user2Box) user2StatusLbl.text('待核验') user2StatusLbl.textFont(viewUtils.font(22, dxui.Utils.FONT_STYLE.BOLD)) user2StatusLbl.textColor(0xffffff) user2StatusLbl.align(dxui.Utils.ALIGN.BOTTOM_MID, 0, -45) mainView.user2StatusLbl = user2StatusLbl // 设置为mainView属性 // 更新用户UI的方法 mainView.updateUserUI = function(userIndex, userId, forceUpdate = false, fileName = null) { // 只在认证未完成或强制更新时更新用户UI if (!mainView.authComplete || forceUpdate) { logger.info('[mainView]: 准备更新用户UI, userIndex=' + userIndex + ', userId=' + userId + ', forceUpdate=' + forceUpdate + ', fileName=' + fileName) // 查询用户信息 let ret = sqliteService.d1_person.find({ userId: userId }) logger.info('[mainView]: 查询用户结果, ret=' + JSON.stringify(ret)) if (ret && ret.length > 0) { let userName = ret[0].name let userType = 0 try { userType = JSON.parse(ret[0].extra).type || 0 } catch (error) { logger.error("解析用户类型失败") } // 检查用户权限 let hasPermission = false let permissions = sqliteService.d1_permission.find({ userId: userId }) if (permissions && permissions.length > 0) { hasPermission = true } // 根据用户序号更新对应的UI if (userIndex === 1) { // 第一个用户,更新用户1的UI if (mainView.user1Name) { mainView.user1Name.text(userName) } if (mainView.user1Role) { mainView.user1Role.text(userType === 1 ? '科长' : '保管员') } if (mainView.user1StatusLbl) { if (hasPermission) { mainView.user1Box.source('/app/code/resource/image/user_s.png') // 核验成功背景图 mainView.user1StatusLbl.text('核验成功') } else { mainView.user1Box.source('/app/code/resource/image/user_f.png') // 核验失败背景图 mainView.user1StatusLbl.text('核验失败') } } // 更新用户1图标为人脸认证图片 - 已注释,使用背景图片 // if (fileName && mainView.user1Icon) { // logger.info('[mainView]: 更新用户1图标为: ' + fileName) // try { // // 先设置图标大小,确保容器准备就绪 // mainView.user1Icon.setSize(160, 160) // // 确保图片居中显示 // mainView.user1Icon.align(dxui.Utils.ALIGN.CENTER, 0, 0) // // // 先清除旧图片,确保重新加载 // mainView.user1Icon.source('') // mainView.user1Icon.update() // mainView.user1Icon.invalidate() // // // 使用capturer调整图片大小 // // 注意:为避免内存错误,暂时不销毁图像对象 // try { // // 将图片文件转换为图像对象 // const imageId = capturer.pictureFileToImage(fileName, 1) // 1表示IMAGE_YUV420SP // if (imageId) { // logger.info('[mainView]: 图片转换成功,imageId=' + imageId) // // 调整图像大小为160x160 // const resizedImageId = capturer.imageResizeResolution(imageId, 160, 160, 3) // 3表示FILTER_MODE_BOX // if (resizedImageId) { // logger.info('[mainView]: 图片调整成功,resizedImageId=' + resizedImageId) // // 保存调整后的图像为临时文件(使用固定路径,每次覆盖) // const tempFileName = '/app/data/user/temp/user1_resized.jpg' // const saveResult = capturer.imageToPictureFile(resizedImageId, 1, 0, 80, tempFileName) // 0表示TYPE_JPEG // if (saveResult) { // logger.info('[mainView]: 图片保存成功,tempFileName=' + tempFileName) // // 使用调整后的图片作为图标源 // mainView.user1Icon.source(tempFileName) // } else { // logger.error('[mainView]: 保存调整后的图片失败') // // 保存失败时使用原始图片 // mainView.user1Icon.source(fileName) // } // } else { // logger.error('[mainView]: 调整图片大小失败') // // 调整失败时使用原始图片 // mainView.user1Icon.source(fileName) // } // } else { // logger.error('[mainView]: 转换图片文件失败') // // 转换失败时使用原始图片 // mainView.user1Icon.source(fileName) // } // } catch (e) { // logger.error('[mainView]: 处理图片时出错: ' + e.message) // // 出错时使用原始图片 // mainView.user1Icon.source(fileName) // } // // // 强制更新和重绘 // mainView.user1Icon.update() // mainView.user1Icon.invalidate() // logger.info('[mainView]: 用户1图标更新成功') // } catch (error) { // logger.error('[mainView]: 处理图片时出错: ' + error.message) // // 出错时使用原始图片 // mainView.user1Icon.setSize(160, 160) // mainView.user1Icon.align(dxui.Utils.ALIGN.CENTER, 0, 0) // mainView.user1Icon.source(fileName) // mainView.user1Icon.update() // mainView.user1Icon.invalidate() // logger.info('[mainView]: 用户1图标更新失败,使用原始图片') // } // } else { // logger.error('[mainView]: 更新用户1图标失败,fileName=' + fileName + ', user1Icon=' + mainView.user1Icon) // } logger.info('[mainView]: 用户1信息已更新:' + userName + ', ' + (userType === 1 ? '科长' : '保管员') + ', ' + (hasPermission ? '核验成功' : '核验失败')) } else if (userIndex === 2) { // 第二个用户,更新用户2的UI if (mainView.user2Name) { mainView.user2Name.text(userName) } if (mainView.user2Role) { mainView.user2Role.text(userType === 1 ? '科长' : '保管员') } if (mainView.user2StatusLbl) { if (hasPermission) { mainView.user2Box.source('/app/code/resource/image/user_s.png') // 核验成功背景图 mainView.user2StatusLbl.text('核验成功') } else { mainView.user2Box.source('/app/code/resource/image/user_f.png') // 核验失败背景图 mainView.user2StatusLbl.text('核验失败') } } // 更新用户2图标为人脸认证图片 - 已注释,使用背景图片 // if (fileName && mainView.user2Icon) { // logger.info('[mainView]: 更新用户2图标为: ' + fileName) // try { // // 先设置图标大小,确保容器准备就绪 // mainView.user2Icon.setSize(160, 160) // // 确保图片居中显示 // mainView.user2Icon.align(dxui.Utils.ALIGN.CENTER, 0, 0) // // // 先清除旧图片,确保重新加载 // mainView.user2Icon.source('') // mainView.user2Icon.update() // mainView.user2Icon.invalidate() // // // 使用图片处理流程,确保图片正确显示 // logger.info('[mainView]: 开始处理用户2图片: ' + fileName) // // 转换图片为内部格式 // const imageId = capturer.pictureFileToImage(fileName, 1) // 1表示IMAGE_YUV420SP // if (imageId) { // logger.info('[mainView]: 图片转换成功,imageId=' + imageId) // // 调整图像大小为160x160 // const resizedImageId = capturer.imageResizeResolution(imageId, 160, 160, 3) // 3表示FILTER_MODE_BOX // if (resizedImageId) { // logger.info('[mainView]: 图片调整成功,resizedImageId=' + resizedImageId) // // 保存调整后的图像为临时文件(使用固定路径,每次覆盖) // const tempFileName = '/app/data/user/temp/user2_resized.jpg' // // const saveResult = capturer.imageToPictureFile(resizedImageId, 1, 0, 80, tempFileName) // 0表示TYPE_JPEG // if (saveResult) { // logger.info('[mainView]: 图片保存成功,tempFileName=' + tempFileName) // // // 使用调整后的图片作为图标源 // mainView.user2Icon.source(tempFileName) // } else { // logger.error('[mainView]: 保存调整后的图片失败') // // 保存失败时使用原始图片 // mainView.user2Icon.source(fileName) // } // } else { // logger.error('[mainView]: 调整图片大小失败') // // 调整失败时使用原始图片 // mainView.user2Icon.source(fileName) // } // } else { // logger.error('[mainView]: 转换图片失败') // // 转换失败时使用原始图片 // mainView.user2Icon.source(fileName) // } // // // 强制更新和重绘 // mainView.user2Icon.update() // mainView.user2Icon.invalidate() // logger.info('[mainView]: 用户2图标更新成功') // } catch (error) { // logger.error('[mainView]: 处理图片时出错: ' + error.message) // // 出错时使用默认图标 // mainView.user2Icon.setSize(160, 160) // mainView.user2Icon.align(dxui.Utils.ALIGN.CENTER, 0, 0) // mainView.user2Icon.source('/app/code/resource/image/user_1.png') // mainView.user2Icon.update() // mainView.user2Icon.invalidate() // logger.info('[mainView]: 用户2图标更新失败,使用默认图标') // } // } else { // logger.error('[mainView]: 更新用户2图标失败,fileName=' + fileName + ', user2Icon=' + mainView.user2Icon) // } logger.info('[mainView]: 用户2信息已更新:' + userName + ', ' + (userType === 1 ? '科长' : '保管员') + ', ' + (hasPermission ? '核验成功' : '核验失败')) } else { // 未知用户序号,默认更新用户1的UI if (mainView.user1Name) { mainView.user1Name.text(userName) } if (mainView.user1Role) { mainView.user1Role.text(userType === 1 ? '科长' : '保管员') } if (mainView.user1StatusLbl) { if (hasPermission) { mainView.user1Box.source('/app/code/resource/image/user_s.png') // 核验成功背景图 mainView.user1StatusLbl.text('核验成功') } else { mainView.user1Box.source('/app/code/resource/image/user_f.png') // 核验失败背景图 mainView.user1StatusLbl.text('核验失败') } } logger.info('[mainView]: 用户1信息已更新(默认):' + userName + ', ' + (userType === 1 ? '科长' : '保管员') + ', ' + (hasPermission ? '核验成功' : '核验失败')) } } else { logger.warn('[mainView]: 未找到用户信息, userId=' + userId) } } } // 控制按钮区域 const controlBox = dxui.Image.build('controlBox', overlayBox) viewUtils._clearStyle(controlBox) controlBox.setSize(779, 343) controlBox.align(dxui.Utils.ALIGN.BOTTOM_LEFT, 11, -120) controlBox.source('/app/code/resource/image/input_bg.png') // 使用背景图 controlBox.borderWidth(0) // 去掉边线 controlBox.radius(15) // 增大圆角弧度 const controlTitle = dxui.Label.build('controlTitle', controlBox) controlTitle.text('安全入仓联动控制') controlTitle.textFont(viewUtils.font(26, dxui.Utils.FONT_STYLE.BOLD)) // 增大字体 controlTitle.textColor(0x283248) controlTitle.align(dxui.Utils.ALIGN.TOP_LEFT, 50, 15) // 允许进仓模式 const mode1Box = dxui.View.build('mode1Box', controlBox) viewUtils._clearStyle(mode1Box) mode1Box.setSize(760, 80) mode1Box.align(dxui.Utils.ALIGN.TOP_LEFT, 43, 50) mode1Box.bgOpa(0) mode1Box.flexFlow(dxui.Utils.FLEX_FLOW.ROW) mode1Box.flexAlign(dxui.Utils.FLEX_ALIGN.FLEX_START, dxui.Utils.FLEX_ALIGN.CENTER, dxui.Utils.FLEX_ALIGN.CENTER) mode1Box.obj.lvObjSetStylePadGap(32, dxui.Utils.ENUM._LV_STYLE_STATE_CMP_SAME) // 设置按钮间距 const mode1Btn = dxui.Button.build('mode1Btn', mode1Box) mode1Btn.setSize(301, 68) // 增大按钮高度 mode1Btn.bgColor(0x017FEB) mode1Btn.radius(10) // 调整圆角弧度 mainView.mode1Btn = mode1Btn // 设置为mainView属性 const mode1Lbl = dxui.Label.build('mode1Lbl', mode1Btn) mode1Lbl.text('允许进仓模式') mode1Lbl.textFont(viewUtils.font(22, dxui.Utils.FONT_STYLE.BOLD)) // 稍微增大字体大小 mode1Lbl.textColor(0xffffff) mode1Lbl.align(dxui.Utils.ALIGN.CENTER, 0, -12) const mode1SubLbl = dxui.Label.build('mode1SubLbl', mode1Btn) mode1SubLbl.text('(正常保管/入粮后期)') mode1SubLbl.textFont(viewUtils.font(21)) mode1SubLbl.textColor(0xffffff) mode1SubLbl.align(dxui.Utils.ALIGN.CENTER, 0, 12) const inBtn = dxui.Button.build('inBtn', mode1Box) inBtn.setSize(161, 68) // 增大按钮高度 inBtn.bgColor(0x017FEB) inBtn.radius(10) // 调整圆角弧度 mainView.inBtn = inBtn // 设置为mainView属性 const inLbl = dxui.Label.build('inLbl', inBtn) inLbl.text('入仓') inLbl.textFont(viewUtils.font(23, dxui.Utils.FONT_STYLE.BOLD)) // 增大字体 inLbl.textColor(0xffffff) inLbl.align(dxui.Utils.ALIGN.CENTER, 0, 0) const outBtn = dxui.Button.build('outBtn', mode1Box) outBtn.setSize(161, 68) // 增大按钮高度 outBtn.bgColor(0x017FEB) outBtn.radius(10) // 调整圆角弧度 mainView.outBtn = outBtn // 设置为mainView属性 const outLbl = dxui.Label.build('outLbl', outBtn) outLbl.text('出仓') outLbl.textFont(viewUtils.font(23, dxui.Utils.FONT_STYLE.BOLD)) // 增大字体 outLbl.textColor(0xffffff) outLbl.align(dxui.Utils.ALIGN.CENTER, 0, 0) // 冬季通风模式 const mode2Box = dxui.View.build('mode2Box', controlBox) viewUtils._clearStyle(mode2Box) mode2Box.setSize(760, 80) mode2Box.align(dxui.Utils.ALIGN.TOP_LEFT, 43, 145) mode2Box.bgOpa(0) mode2Box.flexFlow(dxui.Utils.FLEX_FLOW.ROW) mode2Box.flexAlign(dxui.Utils.FLEX_ALIGN.FLEX_START, dxui.Utils.FLEX_ALIGN.CENTER, dxui.Utils.FLEX_ALIGN.CENTER) mode2Box.obj.lvObjSetStylePadGap(32, dxui.Utils.ENUM._LV_STYLE_STATE_CMP_SAME) // 设置按钮间距 const mode2Btn = dxui.Button.build('mode2Btn', mode2Box) mode2Btn.setSize(301, 68) // 增大按钮高度 mode2Btn.bgColor(0x017FEB) mode2Btn.radius(10) // 调整圆角弧度 mainView.mode2Btn = mode2Btn // 设置为mainView属性 const mode2Lbl = dxui.Label.build('mode2Lbl', mode2Btn) mode2Lbl.text('冬季通风模式') mode2Lbl.textFont(viewUtils.font(22, dxui.Utils.FONT_STYLE.BOLD)) // 稍微增大字体大小 mode2Lbl.textColor(0xffffff) mode2Lbl.align(dxui.Utils.ALIGN.CENTER, 0, -12) const mode2SubLbl = dxui.Label.build('mode2SubLbl', mode2Btn) mode2SubLbl.text('(需科长权限)') mode2SubLbl.textFont(viewUtils.font(21)) mode2SubLbl.textColor(0xffffff) mode2SubLbl.align(dxui.Utils.ALIGN.CENTER, 0, 12) const startBtn = dxui.Button.build('startBtn', mode2Box) startBtn.setSize(161, 68) // 增大按钮高度 startBtn.bgColor(0x017FEB) startBtn.radius(10) // 调整圆角弧度 mainView.startBtn = startBtn // 设置为mainView属性 const startLbl = dxui.Label.build('startLbl', startBtn) startLbl.text('启动') startLbl.textFont(viewUtils.font(23, dxui.Utils.FONT_STYLE.BOLD)) // 增大字体 startLbl.textColor(0xffffff) startLbl.align(dxui.Utils.ALIGN.CENTER, 0, 0) const stopBtn = dxui.Button.build('stopBtn', mode2Box) stopBtn.setSize(161, 68) // 增大按钮高度 stopBtn.bgColor(0x017FEB) stopBtn.radius(10) // 调整圆角弧度 mainView.stopBtn = stopBtn // 设置为mainView属性 const stopLbl = dxui.Label.build('stopLbl', stopBtn) stopLbl.text('关闭') stopLbl.textFont(viewUtils.font(23, dxui.Utils.FONT_STYLE.BOLD)) // 增大字体 stopLbl.textColor(0xffffff) stopLbl.align(dxui.Utils.ALIGN.CENTER, 0, 0) // 禁止进仓模式 const mode3Box = dxui.View.build('mode3Box', controlBox) viewUtils._clearStyle(mode3Box) mode3Box.setSize(760, 80) mode3Box.align(dxui.Utils.ALIGN.TOP_LEFT, 43, 240) mode3Box.bgOpa(0) mode3Box.flexFlow(dxui.Utils.FLEX_FLOW.ROW) mode3Box.flexAlign(dxui.Utils.FLEX_ALIGN.FLEX_START, dxui.Utils.FLEX_ALIGN.CENTER, dxui.Utils.FLEX_ALIGN.CENTER) mode3Box.obj.lvObjSetStylePadGap(32, dxui.Utils.ENUM._LV_STYLE_STATE_CMP_SAME) // 设置按钮间距 const mode3Btn = dxui.Button.build('mode3Btn', mode3Box) mode3Btn.setSize(301, 68) // 增大按钮高度 mode3Btn.bgColor(0x017FEB) mode3Btn.radius(10) // 调整圆角弧度 mainView.mode3Btn = mode3Btn // 设置为mainView属性 const mode3Lbl = dxui.Label.build('mode3Lbl', mode3Btn) mode3Lbl.text('禁止进仓模式') mode3Lbl.textFont(viewUtils.font(22, dxui.Utils.FONT_STYLE.BOLD)) // 稍微增大字体大小 mode3Lbl.textColor(0xffffff) mode3Lbl.align(dxui.Utils.ALIGN.CENTER, 0, -12) const mode3SubLbl = dxui.Label.build('mode3SubLbl', mode3Btn) mode3SubLbl.text('(需科长权限)') mode3SubLbl.textFont(viewUtils.font(21)) mode3SubLbl.textColor(0xffffff) mode3SubLbl.align(dxui.Utils.ALIGN.CENTER, 0, 12) const emergencyInBtn = dxui.Button.build('emergencyInBtn', mode3Box) emergencyInBtn.setSize(161, 68) // 增大按钮高度 emergencyInBtn.bgColor(0x017FEB) emergencyInBtn.radius(10) // 调整圆角弧度 mainView.emergencyInBtn = emergencyInBtn // 设置为mainView属性 const emergencyInLbl = dxui.Label.build('emergencyInLbl', emergencyInBtn) emergencyInLbl.text('紧急入仓') emergencyInLbl.textFont(viewUtils.font(23, dxui.Utils.FONT_STYLE.BOLD)) // 增大字体 emergencyInLbl.textColor(0xffffff) emergencyInLbl.align(dxui.Utils.ALIGN.CENTER, 0, 0) const emergencyOutBtn = dxui.Button.build('emergencyOutBtn', mode3Box) emergencyOutBtn.setSize(161, 68) // 增大按钮高度 emergencyOutBtn.bgColor(0x017FEB) emergencyOutBtn.radius(10) // 调整圆角弧度 mainView.emergencyOutBtn = emergencyOutBtn // 设置为mainView属性 const emergencyOutLbl = dxui.Label.build('emergencyOutLbl', emergencyOutBtn) emergencyOutLbl.text('出仓') emergencyOutLbl.textFont(viewUtils.font(23, dxui.Utils.FONT_STYLE.BOLD)) // 增大字体 emergencyOutLbl.textColor(0xffffff) emergencyOutLbl.align(dxui.Utils.ALIGN.CENTER, 0, 0) // 底部控制按钮 const bottomControlBox = dxui.View.build('bottomControlBox', overlayBox) viewUtils._clearStyle(bottomControlBox) bottomControlBox.setSize(screen.screenSize.width, 80) bottomControlBox.align(dxui.Utils.ALIGN.BOTTOM_LEFT, 20, -40) bottomControlBox.bgOpa(0) bottomControlBox.flexFlow(dxui.Utils.FLEX_FLOW.ROW) bottomControlBox.flexAlign(dxui.Utils.FLEX_ALIGN.FLEX_START, dxui.Utils.FLEX_ALIGN.CENTER, dxui.Utils.FLEX_ALIGN.CENTER) bottomControlBox.obj.lvObjSetStylePadGap(20, dxui.Utils.ENUM._LV_STYLE_STATE_CMP_SAME) // 设置按钮间距 // 开灯按钮 const lightOnBtn = viewUtils.imageBtn(bottomControlBox, 'lightOnBtn', '/app/code/resource/image/light_open.png') lightOnBtn.setSize(240, 68) mainView.lightOnBtn = lightOnBtn // 设置为mainView属性 const lightOnLbl = dxui.Label.build('lightOnLbl', lightOnBtn) lightOnLbl.text('开灯') lightOnLbl.textFont(viewUtils.font(23, dxui.Utils.FONT_STYLE.BOLD)) // 增大字体 lightOnLbl.textColor(0xffffff) lightOnLbl.align(dxui.Utils.ALIGN.CENTER, 20, 0) // 关灯按钮 const lightOffBtn = viewUtils.imageBtn(bottomControlBox, 'lightOffBtn', '/app/code/resource/image/light_close.png') lightOffBtn.setSize(240, 68) mainView.lightOffBtn = lightOffBtn // 设置为mainView属性 const lightOffLbl = dxui.Label.build('lightOffLbl', lightOffBtn) lightOffLbl.text('关灯') lightOffLbl.textFont(viewUtils.font(23, dxui.Utils.FONT_STYLE.BOLD)) // 增大字体 lightOffLbl.textColor(0xffffff) lightOffLbl.align(dxui.Utils.ALIGN.CENTER, 20, 0) // 应急开仓按钮 const emergencyBtn = viewUtils.imageBtn(bottomControlBox, 'emergencyBtn', '/app/code/resource/image/emergencyOpen.png') emergencyBtn.setSize(240, 68) mainView.emergencyBtn = emergencyBtn // 设置为mainView属性 const emergencyLbl = dxui.Label.build('emergencyLbl', emergencyBtn) emergencyLbl.text('应急开仓') emergencyLbl.textFont(viewUtils.font(23, dxui.Utils.FONT_STYLE.BOLD)) // 增大字体 emergencyLbl.textColor(0xffffff) emergencyLbl.align(dxui.Utils.ALIGN.CENTER, 20, 0) // 底部信息栏 const infoBox = dxui.View.build('infoBox', overlayBox) viewUtils._clearStyle(infoBox) infoBox.setSize(screen.screenSize.width, 30) infoBox.align(dxui.Utils.ALIGN.BOTTOM_MID, 0, 0) infoBox.bgColor(0x808080) const snInfoLbl = dxui.Label.build('snInfoLbl', infoBox) mainView.snInfoLbl = snInfoLbl snInfoLbl.text('SN: ') snInfoLbl.textFont(viewUtils.font(14)) snInfoLbl.textColor(0xffffff) snInfoLbl.align(dxui.Utils.ALIGN.BOTTOM_LEFT, 20, -5) const ipInfoLbl = dxui.Label.build('ipInfoLbl', infoBox) mainView.ipInfoLbl = ipInfoLbl ipInfoLbl.text('IP: ') ipInfoLbl.textFont(viewUtils.font(14)) ipInfoLbl.textColor(0xffffff) ipInfoLbl.align(dxui.Utils.ALIGN.BOTTOM_RIGHT, -20, -5) // 设置按钮点击事件 mode1Btn.on(dxui.Utils.EVENT.CLICK, () => { logger.info('允许进仓模式按钮点击') // 检查是否有用户已核验成功 if (!mainView.verifiedUsers[1] && !mainView.verifiedUsers[2]) { // 显示弹窗通知 bus.fire('showAccessResult', { faceAuth: false, gasConcentration: true, accessAllowed: false, message: "*联动控制操作无权限*" }) // 播放语音提示 driver.alsa.play('/app/code/resource/CN/wav/control_f.wav') return } // 获取气体浓度信息 grainService.checkGasConcentration() // 发送安全入仓联动控制请求 grainService.checkDevConcentration({ mode: 1, // 允许入仓模式 user1: mainView.verifiedUsers[1] || mainView.verifiedUsers[2], // 使用已核验成功的用户 user2: mainView.verifiedUsers[2] && mainView.verifiedUsers[1] ? mainView.verifiedUsers[2] : undefined // 如果有两个用户,都传递 }) }) inBtn.on(dxui.Utils.EVENT.CLICK, () => { logger.info('入仓按钮点击') // 检查是否有用户已核验成功 if (!mainView.verifiedUsers[1] && !mainView.verifiedUsers[2]) { // 显示弹窗通知 bus.fire('showAccessResult', { faceAuth: false, gasConcentration: true, accessAllowed: false, message: "*联动控制操作无权限*" }) // 播放语音提示 driver.alsa.play('/app/code/resource/CN/wav/control_f.wav') return } // 获取气体浓度信息 grainService.checkGasConcentration() // 发送安全入仓联动控制请求 grainService.checkDevConcentration({ mode: 1, // 允许入仓模式 btn: 1, // 入仓 user1: mainView.verifiedUsers[1] || mainView.verifiedUsers[2], // 使用已核验成功的用户 user2: mainView.verifiedUsers[2] && mainView.verifiedUsers[1] ? mainView.verifiedUsers[2] : undefined // 如果有两个用户,都传递 }) }) outBtn.on(dxui.Utils.EVENT.CLICK, () => { logger.info('出仓按钮点击') // 检查是否有用户已核验成功 if (!mainView.verifiedUsers[1] && !mainView.verifiedUsers[2]) { // 显示弹窗通知 bus.fire('showAccessResult', { faceAuth: false, gasConcentration: true, accessAllowed: false, message: "*联动控制操作无权限*" }) // 播放语音提示 driver.alsa.play('/app/code/resource/CN/wav/control_f.wav') return } // 获取气体浓度信息 grainService.checkGasConcentration() // 发送安全入仓联动控制请求 grainService.checkDevConcentration({ mode: 1, // 允许入仓模式 btn: 2, // 出仓 user1: mainView.verifiedUsers[1] || mainView.verifiedUsers[2], // 使用已核验成功的用户 user2: mainView.verifiedUsers[2] && mainView.verifiedUsers[1] ? mainView.verifiedUsers[2] : undefined // 如果有两个用户,都传递 }) }) mode2Btn.on(dxui.Utils.EVENT.CLICK, () => { logger.info('冬季通风模式按钮点击') // 检查是否有用户已核验成功 if (!mainView.verifiedUsers[1] && !mainView.verifiedUsers[2]) { // 显示弹窗通知 bus.fire('showAccessResult', { faceAuth: false, gasConcentration: true, accessAllowed: false, message: "*联动控制操作无权限*" }) // 播放语音提示 driver.alsa.play('/app/code/resource/CN/wav/control_f.wav') return } // 获取气体浓度信息 grainService.checkGasConcentration() // 发送安全入仓联动控制请求 grainService.checkDevConcentration({ mode: 2, // 冬季通风模式 user1: mainView.verifiedUsers[1] || mainView.verifiedUsers[2], // 使用已核验成功的用户 user2: mainView.verifiedUsers[2] && mainView.verifiedUsers[1] ? mainView.verifiedUsers[2] : undefined // 如果有两个用户,都传递 }) }) startBtn.on(dxui.Utils.EVENT.CLICK, () => { logger.info('启动按钮点击') // 检查是否有用户已核验成功 if (!mainView.verifiedUsers[1] && !mainView.verifiedUsers[2]) { // 显示弹窗通知 bus.fire('showAccessResult', { faceAuth: false, gasConcentration: true, accessAllowed: false, message: "*联动控制操作无权限*" }) // 播放语音提示 driver.alsa.play('/app/code/resource/CN/wav/control_f.wav') return } // 获取气体浓度信息 grainService.checkGasConcentration() // 发送安全入仓联动控制请求 grainService.checkDevConcentration({ mode: 2, // 冬季通风模式 btn: 1, // 开启 user1: mainView.verifiedUsers[1] || mainView.verifiedUsers[2], // 使用已核验成功的用户 user2: mainView.verifiedUsers[2] && mainView.verifiedUsers[1] ? mainView.verifiedUsers[2] : undefined // 如果有两个用户,都传递 }) }) stopBtn.on(dxui.Utils.EVENT.CLICK, () => { logger.info('关闭按钮点击') // 检查是否有用户已核验成功 if (!mainView.verifiedUsers[1] && !mainView.verifiedUsers[2]) { // 显示弹窗通知 bus.fire('showAccessResult', { faceAuth: false, gasConcentration: true, accessAllowed: false, message: "*联动控制操作无权限*" }) // 播放语音提示 driver.alsa.play('/app/code/resource/CN/wav/control_f.wav') return } // 获取气体浓度信息 grainService.checkGasConcentration() // 发送安全入仓联动控制请求 grainService.checkDevConcentration({ mode: 2, // 冬季通风模式 btn: 2, // 关闭 user1: mainView.verifiedUsers[1] || mainView.verifiedUsers[2], // 使用已核验成功的用户 user2: mainView.verifiedUsers[2] && mainView.verifiedUsers[1] ? mainView.verifiedUsers[2] : undefined // 如果有两个用户,都传递 }) }) mode3Btn.on(dxui.Utils.EVENT.CLICK, () => { logger.info('禁止进仓模式按钮点击') // 检查是否有用户已核验成功 if (!mainView.verifiedUsers[1] && !mainView.verifiedUsers[2]) { // 显示弹窗通知 bus.fire('showAccessResult', { faceAuth: false, gasConcentration: true, accessAllowed: false, message: "*联动控制操作无权限*" }) // 播放语音提示 driver.alsa.play('/app/code/resource/CN/wav/control_f.wav') return } // 获取气体浓度信息 grainService.checkGasConcentration() // 发送安全入仓联动控制请求 grainService.checkDevConcentration({ mode: 3, // 禁止入仓模式 user1: mainView.verifiedUsers[1] || mainView.verifiedUsers[2], // 使用已核验成功的用户 user2: mainView.verifiedUsers[2] && mainView.verifiedUsers[1] ? mainView.verifiedUsers[2] : undefined // 如果有两个用户,都传递 }) }) emergencyInBtn.on(dxui.Utils.EVENT.CLICK, () => { logger.info('紧急入仓按钮点击') // 检查是否有用户已核验成功 if (!mainView.verifiedUsers[1] && !mainView.verifiedUsers[2]) { // 显示弹窗通知 bus.fire('showAccessResult', { faceAuth: false, gasConcentration: true, accessAllowed: false, message: "*联动控制操作无权限*" }) // 播放语音提示 driver.alsa.play('/app/code/resource/CN/wav/control_f.wav') return } // 获取气体浓度信息 grainService.checkGasConcentration() // 发送安全入仓联动控制请求 grainService.checkDevConcentration({ mode: 3, // 禁止入仓模式 btn: 1, // 紧急入仓 user1: mainView.verifiedUsers[1] || mainView.verifiedUsers[2], // 使用已核验成功的用户 user2: mainView.verifiedUsers[2] && mainView.verifiedUsers[1] ? mainView.verifiedUsers[2] : undefined // 如果有两个用户,都传递 }) }) emergencyOutBtn.on(dxui.Utils.EVENT.CLICK, () => { logger.info('出仓按钮点击') // 检查是否有用户已核验成功 if (!mainView.verifiedUsers[1] && !mainView.verifiedUsers[2]) { // 显示弹窗通知 bus.fire('showAccessResult', { faceAuth: false, gasConcentration: true, accessAllowed: false, message: "*联动控制操作无权限*" }) // 播放语音提示 driver.alsa.play('/app/code/resource/CN/wav/control_f.wav') return } // 获取气体浓度信息 grainService.checkGasConcentration() // 发送安全入仓联动控制请求 grainService.checkDevConcentration({ mode: 3, // 禁止入仓模式 btn: 2, // 出仓 user1: mainView.verifiedUsers[1] || mainView.verifiedUsers[2], // 使用已核验成功的用户 user2: mainView.verifiedUsers[2] && mainView.verifiedUsers[1] ? mainView.verifiedUsers[2] : undefined // 如果有两个用户,都传递 }) }) lightOnBtn.on(dxui.Utils.EVENT.CLICK, () => { logger.info('开灯按钮点击') // 检查是否有用户已核验成功 if (!mainView.verifiedUsers[1] && !mainView.verifiedUsers[2]) { // 显示弹窗通知 bus.fire('showAccessResult', { faceAuth: false, gasConcentration: true, accessAllowed: false, message: "*联动控制操作无权限*" }) // 播放语音提示 driver.alsa.play('/app/code/resource/CN/wav/control_f.wav') return } // 获取气体浓度和状态信息 grainService.checkGasConcentration() grainService.checkDevConcentration() // 发送仓内照明联动控制请求 grainService.controlLight({ btn: 1, // 开灯 user1: mainView.verifiedUsers[1] || mainView.verifiedUsers[2], // 使用已核验成功的用户 user2: mainView.verifiedUsers[2] && mainView.verifiedUsers[1] ? mainView.verifiedUsers[2] : undefined // 如果有两个用户,都传递 }) }) lightOffBtn.on(dxui.Utils.EVENT.CLICK, () => { logger.info('关灯按钮点击') // 检查是否有用户已核验成功 if (!mainView.verifiedUsers[1] && !mainView.verifiedUsers[2]) { // 显示弹窗通知 bus.fire('showAccessResult', { faceAuth: false, gasConcentration: true, accessAllowed: false, message: "*联动控制操作无权限*" }) // 播放语音提示 driver.alsa.play('/app/code/resource/CN/wav/control_f.wav') return } // 获取气体浓度和状态信息 grainService.checkGasConcentration() grainService.checkDevConcentration() // 发送仓内照明联动控制请求 grainService.controlLight({ btn: 2, // 关灯 user1: mainView.verifiedUsers[1] || mainView.verifiedUsers[2], // 使用已核验成功的用户 user2: mainView.verifiedUsers[2] && mainView.verifiedUsers[1] ? mainView.verifiedUsers[2] : undefined // 如果有两个用户,都传递 }) }) emergencyBtn.on(dxui.Utils.EVENT.CLICK, () => { logger.info('应急开仓按钮点击') dxui.loadMain(emergencyPwdView.screenMain) }) } export default mainView