From e491cdb48129752324c4e3764f99bd9203c56dec Mon Sep 17 00:00:00 2001
From: lgq <1015864684@qq.com>
Date: 星期二, 31 三月 2026 09:48:44 +0800
Subject: [PATCH] 1.新增VF205门禁机代码
---
vf205_access/resource/image/accessCtrl.png | 0
vf205_access/resource/image/wifi_dark.png | 0
vf205_access/dxmodules/dxUart.js | 242
vf205_access/src/view/config/identityVerificationView.js | 185
vf205_access/.temp/zipFolder/VF105_V12/dxAudio/2.0.0.zip | 0
vf205_access/resource/image/userMgmt.png | 0
vf205_access/resource/image/help.png | 0
vf205_access/dxmodules/dxSqlite.js | 54
vf205_access/src/common/utils/utils.js | 132
vf205_access/resource/image/light_close.png | 0
vf205_access/dxmodules/dxPwm.js | 116
vf205_access/.temp/zipFolder/VF105_V12/dxEventBus/2.0.2.zip | 0
vf205_access/dxmodules/libJLReader.so | 0
vf205_access/resource/image/faceError.png | 0
vf205_access/dxmodules/libvbar-drv-soc.so | 0
vf205_access/.temp/zipFolder/VF105_V12/dxWatchdog/1.0.1.zip | 0
vf205_access/.temp/zipFolder/VF105_V12/dxFacial/1.0.0.zip | 0
vf205_access/resource/image/eth_disable.png | 0
vf205_access/resource/image/space.png | 0
vf205_access/dxmodules/dxDriver.js | 81
vf205_access/dxmodules/dxNfc.js | 409
vf205_access/dxmodules/dxGpioKey.js | 84
vf205_access/resource/CN/wav/recg_s.wav | 0
vf205_access/dxmodules/libvbar-m-dxeid.so | 0
vf205_access/resource/EN/wav/verify_300_f.wav | 0
vf205_access/resource/EN/wav/verify_10x_f.wav | 0
vf205_access/resource/image/mini_background.png | 0
vf205_access/src/view/config/menu/deviceInfo/systemInfoView.js | 94
vf205_access/.temp/zipFolder/VF105_V12/dxEid/1.0.0.zip | 0
vf205_access/dxmodules/libyuv.so | 0
vf205_access/dxmodules/libvbar-b-dxface.so | 0
vf205_access/dxmodules/libalc.so | 0
vf205_access/.temp/zipFolder/VF105_V12/dxNfcCard/1.0.0.zip | 0
vf205_access/resource/image/co2_f.png | 0
vf205_access/resource/CN/wav/btn13.wav | 0
vf205_access/resource/CN/wav/verify.wav | 0
vf205_access/dxmodules/dxEid.js | 46
vf205_access/dxmodules/uiUtils.js | 292
vf205_access/resource/image/delete.png | 0
vf205_access/.temp/zipFolder/VF105_V12/dxDisplay/2.0.0.zip | 0
vf205_access/resource/image/close.png | 0
vf205_access/dxmodules/dxCameraCalibration.js | 136
vf205_access/resource/image/user.png | 0
vf205_access/resource/image/title_bg.png | 0
vf205_access/.temp/dxide_debug.log | 11
vf205_access/src/view/config/menu/factoryTestView.js | 77
vf205_access/dxmodules/libvbar-drv-face.so | 0
vf205_access/.temp/zipFolder/VF105_V12/dxPwm/1.0.0.zip | 0
vf205_access/dxmodules/vgUartWorker.js | 166
vf205_access/resource/image/lock.png | 0
vf205_access/resource/CN/wav/recognition_s.wav | 0
vf205_access/resource/image/success_fill.png | 0
vf205_access/dxmodules/libvbar-m-key.so | 0
vf205_access/resource/image/face.png | 0
vf205_access/resource/image/register.png | 0
vf205_access/.temp/zipFolder/VF105_V12/dxSqliteDB/1.0.0.zip | 0
vf205_access/resource/CN/wav/recognition.wav | 0
vf205_access/resource/CN/wav/user2.wav | 0
vf205_access/.temp/zipFolder/VF105_V12/dxWatchdog/1.0.0.zip | 0
vf205_access/.temp/zipFolder/VF105_V12/dxCapturer/1.0.0.zip | 0
vf205_access/dxmodules/libvbar-m-capturer.so | 0
vf205_access/resource/CN/wav/door_open.wav | 0
vf205_access/resource/image/faceRec2.png | 0
vf205_access/resource/image/grey_btn.png | 0
vf205_access/src/view/config/menu/helpView.js | 41
vf205_access/dxmodules/libvbar-m-dxmap.so | 0
vf205_access/resource/image/enter_b.png | 0
vf205_access/resource/EN/wav/verify_400_s.wav | 0
vf205_access/resource/image/sysSettings.png | 0
vf205_access/resource/image/config_btn.png | 0
vf205_access/dxmodules/libvbar-m-channel.so | 0
vf205_access/resource/image/back_2.png | 0
vf205_access/resource/image/user_s.png | 0
vf205_access/resource/image/recQuery.png | 0
vf205_access/.temp/zipFolder/VF105_V12/dxHttpClient/2.0.4.zip | 0
vf205_access/src/view/config/menu/deviceInfo/dataCapacityInfoView.js | 118
vf205_access/resource/CN/wav/btn21.wav | 0
vf205_access/resource/EN/wav/recognition.wav | 0
vf205_access/resource/CN/wav/read.wav | 0
vf205_access/.temp/zipFolder/VF105_V12/dxNfc/1.0.0.zip | 0
vf205_access/src/view/config/menu/systemSetting/passwordOpenDoorSettingView.js | 144
vf205_access/resource/image/rectangle.png | 0
vf205_access/resource/image/mqtt_dark.png | 0
vf205_access/dxmodules/mqttWorker.js | 64
vf205_access/dxmodules/uiStyle.js | 149
vf205_access/.temp/zipFolder/VF105_V12/dxHttpServer/1.0.1.zip | 0
vf205_access/resource/image/ethernet.png | 0
vf205_access/src/view/config/menu/dockingSetting.js | 135
vf205_access/src/config.json | 115
vf205_access/.temp/md5s.json | 330
vf205_access/src/view/config/menu/systemSetting/passwordManagementView.js | 115
vf205_access/dxmodules/libvbar-m-dxcapturer_calibration.so | 0
vf205_access/resource/langPack.js | 664 +
vf205_access/resource/image/mini_password.png | 0
vf205_access/resource/image/ph3_s.png | 0
vf205_access/resource/image/doorControl.png | 0
vf205_access/.temp/zipFolder/VF105_V12/dxOs/1.0.0.zip | 0
vf205_access/.temp/md5snew.json | 330
vf205_access/dxmodules/libvbar-m-dxhttp.so | 0
vf205_access/resource/image/app.png | 0
vf205_access/resource/CN/wav/emergency_s.wav | 0
vf205_access/.temp/zipFolder/VF105_V12/dxSqlite/1.0.0.zip | 0
vf205_access/.temp/zipFolder/VF105_V12/dxHttpClient/2.0.3.zip | 0
vf205_access/dxmodules/dxConfig.js | 140
vf205_access/.temp/zipFolder/VF105_V12/dxConfig/2.0.0.zip | 0
vf205_access/resource/EN/wav/read.wav | 0
vf205_access/dxmodules/uiLabel.js | 34
vf205_access/.temp/zipFolder/VF105_V12/dxCommon/1.0.1.zip | 0
vf205_access/resource/EN/wav/stranger.wav | 0
vf205_access/dxmodules/dxStd.js | 399
vf205_access/.temp/zipFolder/VF105_V12/dxDisplay/1.0.0.zip | 0
vf205_access/.temp/zipFolder/VF105_V12/dxCapturer/1.0.1.zip | 0
vf205_access/src/service/gpiokeyService.js | 52
vf205_access/resource/image/factoryTest.png | 0
vf205_access/src/screen.js | 1470 +++
vf205_access/src/view/config/menu/systemSetting/faceRecognitionSettingView.js | 167
vf205_access/dxmodules/libvbar-drv-capturer.so | 0
vf205_access/.temp/zipFolder/VF105_V12/dxAlsa/1.0.0.zip | 0
vf205_access/.temp/zipFolder/VF105_V12/dxWorkerPool/2.0.0.zip | 0
vf205_access/.temp/zipFolder/VF105_V12/dxEventBus/2.0.0.zip | 0
vf205_access/.temp/zipFolder/VF105_V12/dxHttp/1.0.0.zip | 0
vf205_access/resource/CN/wav/control_f.wav | 0
vf205_access/resource/CN/wav/network.wav | 0
vf205_access/resource/image/down.png | 0
vf205_access/dxmodules/libvbar-m-common.so | 0
vf205_access/dxmodules/uiList.js | 45
vf205_access/README_CN.md | 19
vf205_access/resource/CN/wav/btn22.wav | 0
vf205_access/src/view/config/menu/recordQuery/recordQueryDetailView.js | 227
vf205_access/resource/image/select_arrow.png | 0
vf205_access/resource/image/localUser.png | 0
vf205_access/.temp/zipFolder/VF105_V12/dxGpio/1.0.0.zip | 0
vf205_access/src/services.js | 109
vf205_access/resource/image/background.jpg | 0
vf205_access/src/view/config/menu/systemSettingView.js | 184
vf205_access/resource/image/co2_s.png | 0
vf205_access/.temp/zipFolder/VF105_V12/dxStd/2.0.3.zip | 0
vf205_access/dxmodules/dxWatchdog.js | 123
vf205_access/.temp/zipFolder/VF105_V12/dxNtp/2.0.0.zip | 0
vf205_access/dxmodules/libvbar-b-dxpwm.so | 0
vf205_access/src/service/platService.js | 4
vf205_access/resource/CN/wav/recg_f.wav | 0
vf205_access/src/service/grainService.js | 676 +
vf205_access/src/view/config/menu/systemSetting/timeSettingView.js | 124
vf205_access/resource/EN/wav/verify_200_f.wav | 0
vf205_access/src/view/topView.js | 170
vf205_access/dxmodules/libvbar-m-dxmqtt.so | 0
vf205_access/.temp/zipFolder/VF105_V12/dxCommon/1.0.0.zip | 0
vf205_access/dxmodules/uiTextarea.js | 76
vf205_access/src/view/pwdView.js | 72
vf205_access/resource/image/delete_fill.png | 0
vf205_access/resource/EN/wav/recg_s.wav | 0
vf205_access/resource/image/empty.png | 0
vf205_access/resource/image/eth_enable.png | 0
vf205_access/dxmodules/dxBase64.js | 308
vf205_access/resource/image/network_dark.png | 0
vf205_access/.temp/zipFolder/VF105_V12/dxMqtt/1.0.1.zip | 0
vf205_access/resource/CN/wav/verify_400_f.wav | 0
vf205_access/.temp/zipFolder/VF105_V12/dxOta/1.0.0.zip | 0
vf205_access/resource/image/pwd_btn.png | 0
vf205_access/src/ui.js | 32
vf205_access/resource/CN/wav/verify_10x_s.wav | 0
vf205_access/dxmodules/libid_jpg_codec.so | 0
vf205_access/dxmodules/libvbar-m-dxkey.so | 0
vf205_access/dxmodules/uiFont.js | 18
vf205_access/.temp/zipFolder/VF105_V12/dxFace/1.1.8.zip | 0
vf205_access/resource/image/setting.png | 0
vf205_access/dxmodules/uiCheckbox.js | 48
vf205_access/resource/image/commMgmt.png | 0
vf205_access/.temp/zipFolder/VF105_V12/dxCapturer/1.0.2.zip | 0
vf205_access/resource/CN/wav/calibration_s.wav | 0
vf205_access/resource/image/setting32.png | 0
vf205_access/.temp/zipFolder/VF105_V12/dxNet/1.0.0.zip | 0
vf205_access/dxmodules/dxEventBus.js | 167
vf205_access/resource/image/idleImage.jpg | 0
vf205_access/.temp/zipFolder/VF105_V12/dxNfcCard/1.0.1.zip | 0
vf205_access/dxmodules/libvbar-m-dxalsa.so | 0
vf205_access/resource/CN/wav/verify_200_s.wav | 0
vf205_access/resource/image/back.png | 0
vf205_access/dxmodules/libvbar-m-dxui.so | 0
vf205_access/resource/CN/wav/btn23.wav | 0
vf205_access/dxmodules/faceWorker.js | 23
vf205_access/dxmodules/gpioKeyWorker.js | 23
vf205_access/resource/image/black_btn.png | 0
vf205_access/.temp/zipFolder/VF105_V12/dxNetwork/1.0.0.zip | 0
vf205_access/resource/image/view_f.png | 0
vf205_access/.temp/zipFolder/VF105_V12/dxUi/1.0.2.zip | 0
vf205_access/dxmodules/libvbar-m-dxchannel.so | 0
vf205_access/.temp/zipFolder/VF105_V12/dxMap/1.0.0.zip | 0
vf205_access/dxmodules/dxNet.js | 341
vf205_access/src/view/pinyin/dict.js | 410
vf205_access/dxmodules/dxCommon.js | 733 +
vf205_access/dxmodules/dxNtp.js | 63
vf205_access/src/view/config/menu/recordQueryView.js | 276
vf205_access/.temp/zipFolder/VF105_V12/dxHttpServer/1.0.5.zip | 0
vf205_access/dxmodules/uiKeyboard.js | 102
vf205_access/dxmodules/libvbar-drv-tts.so | 0
vf205_access/resource/image/menu_btn.png | 0
vf205_access/src/view/config/menu/cloudCertView.js | 42
vf205_access/.temp/zipFolder/VF105_V12/dxPwm/2.0.1.zip | 0
vf205_access/.temp/zipFolder/VF105_V12/dxStd/1.0.0.zip | 0
vf205_access/resource/image/sys_info.png | 0
vf205_access/resource/image/vip.png | 0
vf205_access/src/view/config/menu/localUserView.js | 315
vf205_access/dxmodules/dxGpio.js | 123
vf205_access/.temp/zipFolder/VF105_V12/dxGpioKey/1.0.1.zip | 0
vf205_access/resource/CN/wav/btn32.wav | 0
vf205_access/src/service/uart485Service.js | 190
vf205_access/.temp/zipFolder/VF105_V12/dxNtp/2.0.2.zip | 0
vf205_access/resource/EN/wav/network.wav | 0
vf205_access/resource/image/config.png | 0
vf205_access/resource/EN/wav/verify_200_s.wav | 0
vf205_access/resource/image/network.png | 0
vf205_access/src/view/config/newPwdView.js | 137
vf205_access/resource/image/faceAdd.png | 0
vf205_access/resource/CN/wav/user2_s.wav | 0
vf205_access/.temp/zipFolder/VF105_V12/dxMqttClient/1.0.1.zip | 0
vf205_access/resource/image/card.png | 0
vf205_access/dxmodules/nfcWorker.js | 27
vf205_access/resource/image/close_small.png | 0
vf205_access/dxmodules/libvbar-m-dxsqlite.so | 0
vf205_access/.temp/zipFolder/VF105_V12/dxCapturer/1.0.3.zip | 0
vf205_access/dxmodules/dxOta.js | 256
vf205_access/dxmodules/libvbar-b-dxgpio.so | 0
vf205_access/README.md | 9
vf205_access/dxmodules/libvbar-m-alsa.so | 0
vf205_access/resource/CN/wav/failed.wav | 0
vf205_access/src/main.js | 78
vf205_access/resource/image/recordQuery.png | 0
vf205_access/dxmodules/libvbar-p-dxnfc.so | 0
vf205_access/resource/CN/wav/verify_10x_f.wav | 0
vf205_access/dxmodules/libie_jpg.so | 0
vf205_access/dxmodules/dxUi.js | 216
vf205_access/dxmodules/libvbar-drv-gpio.so | 0
vf205_access/resource/EN/wav/register.wav | 0
vf205_access/resource/image/deviceInfo.png | 0
vf205_access/dxmodules/uiButtons.js | 107
vf205_access/resource/image/systemSetting.png | 0
vf205_access/resource/image/advance.png | 0
vf205_access/dxmodules/dxLogger.js | 59
vf205_access/dxmodules/dxQrRule.js | 215
vf205_access/dxmodules/uiButton.js | 16
vf205_access/resource/image/o2_f.png | 0
vf205_access/.temp/zipFolder/VF105_V12/dxLogger/2.0.3.zip | 0
vf205_access/resource/CN/wav/light_close.wav | 0
vf205_access/resource/EN/wav/verify.wav | 0
vf205_access/src/view/emergencyPwdView.js | 140
vf205_access/src/view/config/menu/doorControlView.js | 258
vf205_access/resource/image/logo.png | 0
vf205_access/dxmodules/libvbar-drv-capturer_calibration.so | 0
vf205_access/dxmodules/uiLine.js | 24
vf205_access/dxmodules/uiSlider.js | 42
vf205_access/.temp/zipFolder/VF105_V12/dxGpioKey/1.0.0.zip | 0
vf205_access/resource/CN/wav/verify_300_s.wav | 0
vf205_access/dxmodules/libvbar-m-dxnet.so | 0
vf205_access/resource/image/arrow_right.png | 0
vf205_access/src/view/viewUtils.js | 475 +
vf205_access/dxmodules/uiImage.js | 27
vf205_access/.temp/zipFolder/VF105_V12/dxWorkerPool/2.0.1.zip | 0
vf205_access/dxmodules/cameraCalibrationWorker.js | 57
vf205_access/src/view/config/menu/systemSetting/passLogSettingView.js | 117
vf205_access/resource/image/cloudCert.png | 0
vf205_access/resource/image/failBg.png | 0
vf205_access/src/controller.js | 66
vf205_access/.temp/zipFolder/VF105_V12/dxPwm/2.0.0.zip | 0
vf205_access/dxmodules/capturerWorker.js | 27
vf205_access/resource/EN/wav/recognition_s.wav | 0
vf205_access/src/view/config/menu/systemSetting/displaySettingView.js | 289
vf205_access/resource/image/wifi.png | 0
vf205_access/dxmodules/uiView.js | 27
vf205_access/.temp/zipFolder/VF105_V12/dxNtp/2.0.3.zip | 0
vf205_access/dxmodules/libvbar-b-dxwatchdog.so | 0
vf205_access/resource/image/right.png | 0
vf205_access/dxmodules/libvbar-drv-display.so | 0
vf205_access/resource/image/user_w.png | 0
vf205_access/src/view/config/configView.js | 136
vf205_access/resource/CN/wav/access_f.wav | 0
vf205_access/resource/CN/wav/stranger.wav | 0
vf205_access/.temp/zipFolder/VF105_V12/dxSqlite/2.0.0.zip | 0
vf205_access/dxmodules/dxHttp.js | 155
vf205_access/resource/image/4g_dark.png | 0
vf205_access/resource/image/mini_config.png | 0
vf205_access/resource/CN/wav/door_close.wav | 0
vf205_access/.temp/zipFolder/VF105_V12/dxBase64/1.0.0.zip | 0
vf205_access/.temp/zipFolder/VF105_V12/dxDriver/1.1.4.zip | 0
vf205_access/.temp/zipFolder/VF105_V12/dxMap/2.0.1.zip | 0
vf205_access/resource/CN/wav/verify_300_f.wav | 0
vf205_access/src/service/faceService.js | 447 +
vf205_access/resource/image/ethernet_dark.png | 0
vf205_access/resource/image/input_bg.png | 0
vf205_access/.temp/zipFolder/VF105_V12/dxNet/1.0.2.zip | 0
vf205_access/dxmodules/libie_jpg_codec.so | 0
vf205_access/resource/image/app_btn.png | 0
vf205_access/resource/image/4g.png | 0
vf205_access/resource/image/light_open.png | 0
vf205_access/resource/wav/alarm.wav | 0
vf205_access/resource/CN/wav/btn31.wav | 0
vf205_access/resource/image/app_qrcode.png | 0
vf205_access/resource/CN/wav/access_s.wav | 0
vf205_access/resource/EN/wav/verify_400_f.wav | 0
vf205_access/resource/image/successBg.png | 0
vf205_access/src/view/mainView.js | 1646 +++
vf205_access/src/view/appView.js | 47
vf205_access/dxmodules/netWorker.js | 25
vf205_access/src/service/configService.js | 273
vf205_access/.temp/zipFolder/VF105_V12/dxCryptoES/2.0.0.zip | 0
vf205_access/resource/image/faceEmpty.png | 0
vf205_access/resource/CN/wav/verify_200_f.wav | 0
vf205_access/resource/CN/wav/light_open.wav | 0
vf205_access/resource/image/emergencyOpen.png | 0
vf205_access/resource/image/userGuide.png | 0
vf205_access/resource/image/backspace.png | 0
vf205_access/app.dxproj | 123
vf205_access/resource/image/enter.png | 0
vf205_access/.temp/zipFolder/VF105_V12/dxDriver/1.1.0.zip | 0
vf205_access/dxmodules/liblombo_jpeg.so | 0
vf205_access/dxmodules/libvbar-drv-memory.so | 0
vf205_access/resource/image/eye-off.png | 0
vf205_access/.temp/zipFolder/VF105_V12/dxLogger/2.0.0.zip | 0
vf205_access/src/view/config/menu/systemSetting/swipeCardRecognitionSettingView.js | 96
vf205_access/src/view/i18n.js | 82
vf205_access/dxmodules/uiBase.js | 582 +
vf205_access/resource/font/AlibabaPuHuiTi-2-65-Medium.ttf | 0
vf205_access/src/service/codeService.js | 205
vf205_access/src/service/sqliteService.js | 616 +
vf205_access/resource/image/ph3_f.png | 0
vf205_access/resource/EN/wav/verify_10x_s.wav | 0
vf205_access/resource/image/qrcode_small.png | 0
vf205_access/dxmodules/dxMqtt.js | 225
vf205_access/src/driver.js | 1226 ++
vf205_access/.temp/zipFolder/VF105_V12/dxAudio/1.0.1.zip | 0
vf205_access/dxmodules/libvbar-drv-audio_gain.so | 0
vf205_access/resource/CN/wav/verify_400_s.wav | 0
vf205_access/dxmodules/libvbar-m-net.so | 0
vf205_access/src/view/config/menu/deviceInfoView.js | 110
vf205_access/dxmodules/libid_jpg.so | 0
vf205_access/src/service/mqttService.js | 1832 ++++
vf205_access/src/common/consts/configConst.js | 99
vf205_access/resource/CN/wav/emergency.wav | 0
vf205_access/resource/image/o2_s.png | 0
vf205_access/resource/CN/wav/btn11.wav | 0
vf205_access/resource/image/eye_fill.png | 0
vf205_access/.temp/zipFolder/VF105_V12/dxCameraCalibration/test.zip | 0
vf205_access/dxmodules/dxWorkerPool.js | 167
vf205_access/dxmodules/libvbar-drv-watchdog.so | 0
vf205_access/resource/EN/wav/calibration_s.wav | 0
vf205_access/resource/image/user_f.png | 0
vf205_access/resource/image/mini_app.png | 0
vf205_access/resource/image/trackFace.png | 0
vf205_access/.temp/zipFolder/VF105_V12/dxCameraCalibration/1.0.0.zip | 0
vf205_access/src/view/config/menu/voiceBroadcastView.js | 137
vf205_access/resource/image/devInfo.png | 0
vf205_access/resource/image/basic.png | 0
vf205_access/dxmodules/libvbar-drv-pwm.so | 0
vf205_access/dxmodules/libvbar-m-dxcommon.so | 0
vf205_access/resource/image/networkSetting.png | 0
vf205_access/.temp/zipFolder/VF105_V12/dxBase64/2.0.0.zip | 0
vf205_access/resource/image/mqtt_enable.png | 0
vf205_access/resource/image/faceRec.png | 0
vf205_access/resource/EN/wav/recg_f.wav | 0
vf205_access/resource/image/add.png | 0
vf205_access/src/service/nfcService.js | 44
vf205_access/src/view/pinyin/pinyin.js | 1049 ++
vf205_access/dxmodules/libvbar-m-dxcapturer.so | 0
vf205_access/dxmodules/dxAlsa.js | 105
vf205_access/resource/image/mqtt.png | 0
vf205_access/src/service/accessService.js | 501 +
vf205_access/resource/image/voiceBroadcast.png | 0
vf205_access/src/view/config/menu/networkSettingView.js | 441 +
vf205_access/resource/CN/wav/btn33.wav | 0
vf205_access/resource/image/view_s.png | 0
vf205_access/src/view/idleView.js | 54
vf205_access/dxmodules/dxCapturer.js | 336
vf205_access/resource/CN/wav/register.wav | 0
vf205_access/.temp/zipFolder/VF105_V12/dxDriver/2.0.0.zip | 0
vf205_access/src/view/config/menu/localUser/localUserAddView.js | 682 +
vf205_access/resource/image/unlock.png | 0
vf205_access/.temp/zipFolder/VF105_V12/dxUart/1.0.0.zip | 0
vf205_access/dxmodules/libvbar-p-nfc.so | 0
vf205_access/dxmodules/uiDropdown.js | 53
vf205_access/resource/image/user_1.png | 0
vf205_access/.temp/zipFolder/VF105_V12/dxCommonUtils/1.0.1.zip | 0
vf205_access/resource/image/eye_fill_show.png | 0
vf205_access/src/view/config/menu/localUser/faceEnterView.js | 117
vf205_access/.temp/zipFolder/VF105_V12/dxEventBus/2.0.3.zip | 0
vf205_access/dxmodules/libvbar-m-vgmqtt.so | 0
vf205_access/.temp/zipFolder/VF105_V12/dxQrRule/1.0.0.zip | 0
vf205_access/.temp/zipFolder/VF105_V12/dxOta/2.0.2.zip | 0
vf205_access/dxmodules/libvbar-m-eid.so | 0
vf205_access/dxmodules/libvccore.so | 0
vf205_access/dxmodules/dxMap.js | 109
vf205_access/resource/CN/wav/emergency_f.wav | 0
vf205_access/resource/EN/wav/verify_300_s.wav | 0
vf205_access/resource/CN/wav/btn12.wav | 0
vf205_access/dxmodules/dxFace.js | 287
vf205_access/dxmodules/uiSwitch.js | 49
vf205_access/resource/image/eye-fill.png | 0
397 files changed, 26,360 insertions(+), 0 deletions(-)
diff --git a/vf205_access/.temp/dxide_debug.log b/vf205_access/.temp/dxide_debug.log
new file mode 100644
index 0000000..dd85166
--- /dev/null
+++ b/vf205_access/.temp/dxide_debug.log
@@ -0,0 +1,11 @@
+[2026/3/31 08:59:19] --- Start runUsb ---
+[2026/3/31 08:59:19] Platform: win32
+[2026/3/31 08:59:19] Kill command defined: wmic process where "name='node.exe' and commandline like '%device_manager.js%'" delete || powershell -NoProfile -ExecutionPolicy Bypass -Command "Get-CimInstance Win32_Process | Where-Object { $_.Name -eq 'node.exe' -and $_.CommandLine -like '*device_manager.js*' } | ForEach-Object { Stop-Process -Id $_.ProcessId -Force }"
+[2026/3/31 08:59:20] Node.js check passed
+[2026/3/31 08:59:20] Process exited with code: 0, signal: null
+[2026/3/31 08:59:20] Kill stdout: 删锟斤拷实锟斤拷 \\ACER-LGQ\ROOT\CIMV2:Win32_Process.Handle="42064"
+实锟斤拷删锟斤拷锟缴癸拷锟斤拷
+[2026/3/31 08:59:21] Manager script path: c:\Users\lgq10\.vscode\extensions\dxide.dxide-1.0.40\src\device\device_manager.js
+[2026/3/31 08:59:21] Spawning child process...
+[2026/3/31 08:59:21] Sending connect command: {"cmd":"connect","lang":"zh","model":"VF105_V12"}
+[2026/3/31 09:25:48] Process exited with code: 0, signal: null
diff --git a/vf205_access/.temp/md5s.json b/vf205_access/.temp/md5s.json
new file mode 100644
index 0000000..5283314
--- /dev/null
+++ b/vf205_access/.temp/md5s.json
@@ -0,0 +1,330 @@
+{
+ "app.dxproj": "cb10fd21e8e17ada45c25e1e1ba3226e",
+ "dxmodules\\cameraCalibrationWorker.js": "5812507304ced88da3677a3c68f79a78",
+ "dxmodules\\capturerWorker.js": "a3104a1d73ab1bd4f596495d817ecf39",
+ "dxmodules\\dxAlsa.js": "d82fe4f74383edf6198269968a82b5e7",
+ "dxmodules\\dxBase64.js": "7cb517ecd99830dde0ec13a501e831ea",
+ "dxmodules\\dxCameraCalibration.js": "8e42bf3752616896b88f9e9efbe20783",
+ "dxmodules\\dxCapturer.js": "7420d8e269fb8ebfc48c306e0a8fa7de",
+ "dxmodules\\dxCommon.js": "19f77916eb02e6fd01106597aca412bd",
+ "dxmodules\\dxConfig.js": "24072559b3cb1ec5c206cb358eaaaaae",
+ "dxmodules\\dxDriver.js": "c5969e91097030b90e9bcb62a827e344",
+ "dxmodules\\dxEid.js": "07d966e53b69629f152baf54cd163372",
+ "dxmodules\\dxEventBus.js": "81adf285545c12d49d7784327c41970a",
+ "dxmodules\\dxFace.js": "81790e30c6da75ae3bcb96afcafa5b02",
+ "dxmodules\\dxGpio.js": "30c34469e2dc8d80026fc5eac5bfd1f7",
+ "dxmodules\\dxGpioKey.js": "97ef2763bad50e0c82cfa5fb9b79f1eb",
+ "dxmodules\\dxHttp.js": "fa75a0a2951399fb5af7618d7ab4c6f1",
+ "dxmodules\\dxLogger.js": "f6d3f73086944fcdeeffa579ef6d1508",
+ "dxmodules\\dxMap.js": "2255d584c240c35a567f2c7b92e0a9da",
+ "dxmodules\\dxMqtt.js": "277fafb81971c8f3508a8a38f8f2703a",
+ "dxmodules\\dxNet.js": "58b13f928daeb1bae680c2350873baca",
+ "dxmodules\\dxNfc.js": "feb5bc21d4b13ab9736de1941290312d",
+ "dxmodules\\dxNtp.js": "0c90048eeb11e7e3b458e4d6e48932f2",
+ "dxmodules\\dxOta.js": "760dc97eb0724280f16f8616a2be171f",
+ "dxmodules\\dxPwm.js": "dc0734c231d7d4cd5f26a34c315cc4a2",
+ "dxmodules\\dxQrRule.js": "bfa9e2b4725c4fa358a2988f63c67210",
+ "dxmodules\\dxSqlite.js": "fb6a2f60b49d67a8ef36148355e5e30e",
+ "dxmodules\\dxStd.js": "6f239f2fd7d23e7ed053b762b235bd3c",
+ "dxmodules\\dxUart.js": "71edddfd98de79ccbd91e4e013af269b",
+ "dxmodules\\dxUi.js": "97bd858defaec480d755c162105a3f76",
+ "dxmodules\\dxWatchdog.js": "c4a7d5c8f0c203e6dafbc289a0f4fcbd",
+ "dxmodules\\dxWorkerPool.js": "5aad9b8f838d1339fc64083188d3ba69",
+ "dxmodules\\faceWorker.js": "d1d0d4f5e5503ca87bd69d1d2ee3ad00",
+ "dxmodules\\gpioKeyWorker.js": "78a7489cc3cf098fb4d218b17294175d",
+ "dxmodules\\libalc.so": "3128cc7cd0cc978e02db995433962c87",
+ "dxmodules\\libid_jpg.so": "18887cb0d0df6256604ed039d47dfc7b",
+ "dxmodules\\libid_jpg_codec.so": "c36bd0c28d2b43e9296736856da05129",
+ "dxmodules\\libie_jpg.so": "1343b7bc765f6464cf8e483c03edd542",
+ "dxmodules\\libie_jpg_codec.so": "508defffc1c72b0ae90afab117d6db80",
+ "dxmodules\\libJLReader.so": "ce7f448dea6a1c8988469d03ecfa6575",
+ "dxmodules\\liblombo_jpeg.so": "49508ccd603ed795efee3d0f8e7e3e2a",
+ "dxmodules\\libvbar-b-dxface.so": "689ee554f67057262860f7726042327b",
+ "dxmodules\\libvbar-b-dxgpio.so": "ca009351ab7d9719a71cd6105e9acba6",
+ "dxmodules\\libvbar-b-dxpwm.so": "b3e0e7cc950811385ceb204876fd8b19",
+ "dxmodules\\libvbar-b-dxwatchdog.so": "878352b309e9a9e17ce3ac83774d0fa9",
+ "dxmodules\\libvbar-drv-audio_gain.so": "14d23fe5134ff95982f1655058084709",
+ "dxmodules\\libvbar-drv-capturer.so": "295aaa64df97ee08053c26789ff57437",
+ "dxmodules\\libvbar-drv-capturer_calibration.so": "cdb2ca2205e36d82ebcce910e457bd9b",
+ "dxmodules\\libvbar-drv-display.so": "31c2a7a2ed4166d27359d208e4d34568",
+ "dxmodules\\libvbar-drv-face.so": "2c54abd0de9a287be3bbea490d0c45c4",
+ "dxmodules\\libvbar-drv-gpio.so": "e663856deb2d403558426455097e0bab",
+ "dxmodules\\libvbar-drv-memory.so": "0ed48486e154f24d6681a0195a7525ad",
+ "dxmodules\\libvbar-drv-pwm.so": "b9c2154b7020d41b01d63f6caac1510f",
+ "dxmodules\\libvbar-drv-soc.so": "73e4b6657af4bcff0affaacf55702096",
+ "dxmodules\\libvbar-drv-tts.so": "97076b55a3338196f512c61101ac0e9a",
+ "dxmodules\\libvbar-drv-watchdog.so": "9367e995f85cb191da0567d0acd4ed67",
+ "dxmodules\\libvbar-m-alsa.so": "1154ff7cb2f84ee378f29e0d03551f96",
+ "dxmodules\\libvbar-m-capturer.so": "8f0b6383db39494904294c3f60c5f013",
+ "dxmodules\\libvbar-m-channel.so": "6b6f7d8edb178b11b9a93123e0a7abdb",
+ "dxmodules\\libvbar-m-common.so": "074eb14e701c5ed910b979339453f484",
+ "dxmodules\\libvbar-m-dxalsa.so": "bb4fcf0be6ccb0cc2d7b295002925148",
+ "dxmodules\\libvbar-m-dxcapturer.so": "506307dec2552200eaa22412987b643e",
+ "dxmodules\\libvbar-m-dxcapturer_calibration.so": "c41e691d69621ab5a96322f47d3eb286",
+ "dxmodules\\libvbar-m-dxchannel.so": "ff80aaf50113c160c663a80015471079",
+ "dxmodules\\libvbar-m-dxcommon.so": "d4ca3ce51543d07c81cc75974adcbccb",
+ "dxmodules\\libvbar-m-dxeid.so": "3458f8221dd572220003e4344837d846",
+ "dxmodules\\libvbar-m-dxhttp.so": "1ec2f9ccc26aebc390944340afde6044",
+ "dxmodules\\libvbar-m-dxkey.so": "e49a86e25944050bda8565677713431a",
+ "dxmodules\\libvbar-m-dxmap.so": "55ebd66234d59490ab56f88398419dde",
+ "dxmodules\\libvbar-m-dxmqtt.so": "0cbeb2b46441ee89678516a1a941cd58",
+ "dxmodules\\libvbar-m-dxnet.so": "eed60270cabaf872983c6f905b0ceb03",
+ "dxmodules\\libvbar-m-dxsqlite.so": "15a0eb0d18b58cad3868f86e9edfb409",
+ "dxmodules\\libvbar-m-dxui.so": "ca22e1a0c52977749a32b2cc70e942a9",
+ "dxmodules\\libvbar-m-eid.so": "e7d1db4d1bfab4c462c9d22807099268",
+ "dxmodules\\libvbar-m-key.so": "f7f1f2ae6c9c1f298376375a8b16b6ee",
+ "dxmodules\\libvbar-m-net.so": "afa1adebb44fc9734b26b99e87e0728d",
+ "dxmodules\\libvbar-m-vgmqtt.so": "56e94165ba896867fbe3ead167022d3f",
+ "dxmodules\\libvbar-p-dxnfc.so": "14d17fe22a0dbfc00b13c4d9cef8512f",
+ "dxmodules\\libvbar-p-nfc.so": "f1a1f96558b2509c5b629790cec16386",
+ "dxmodules\\libvccore.so": "9c383ca78ee117ea3295baefb1f1fee2",
+ "dxmodules\\libyuv.so": "2c4faa3ab51260f5285cd91dda44b3a9",
+ "dxmodules\\mqttWorker.js": "4eedadbd41d6bd183cde2830a3347ad1",
+ "dxmodules\\netWorker.js": "c5d4c9022f8912b47249b14477aed70a",
+ "dxmodules\\nfcWorker.js": "88fadfc469cc397b66fd5e52db073bde",
+ "dxmodules\\uiBase.js": "9ea5cd2b5ed52d183fde2d87b8f70ca1",
+ "dxmodules\\uiButton.js": "8ffe0ffce9ac6b341c9993e260b52b05",
+ "dxmodules\\uiButtons.js": "52cb9727c2225f75ac6144e756a6d511",
+ "dxmodules\\uiCheckbox.js": "5aa8c851e8b2333cbe46cdd69452ab8c",
+ "dxmodules\\uiDropdown.js": "2b73bfacf3d4b115ab3997c83284c478",
+ "dxmodules\\uiFont.js": "257aa2f90ce2f0ace4095a03d3447b0b",
+ "dxmodules\\uiImage.js": "b2a0a963993474205bc7dc91c8696ec1",
+ "dxmodules\\uiKeyboard.js": "b225c62ff2f4b8aa0bdb675776b236a1",
+ "dxmodules\\uiLabel.js": "e0ae808d468459a6fedc7ba9a551359e",
+ "dxmodules\\uiLine.js": "cc18bc32c0a6f0f8db7992d6e0b4fd81",
+ "dxmodules\\uiList.js": "8b779a85cd54b25bc50ec616ed9f08d1",
+ "dxmodules\\uiSlider.js": "91b743902824b5decf5535dad49fc97e",
+ "dxmodules\\uiStyle.js": "60350cf77db84793bf093bda341f2cb9",
+ "dxmodules\\uiSwitch.js": "9a836405abe0b09f5a2940cf22698968",
+ "dxmodules\\uiTextarea.js": "0d5008a5a95b78ea8efde3408ba6fb4a",
+ "dxmodules\\uiUtils.js": "a04cc3baa5ba1dc6d1ab65b526464fa6",
+ "dxmodules\\uiView.js": "26fe7b992ac82bf5d45447f2921bff2f",
+ "dxmodules\\vgUartWorker.js": "fc3e9e0051836d5063c0eecf555d9521",
+ "README.md": "c472daef5243f3790f2faee1cf8e2255",
+ "README_CN.md": "a46b1c92c09f375881a49d8c42adf6b3",
+ "resource\\CN\\wav\\access_f.wav": "f951f3cc1f03aaa794231413fd4efcc6",
+ "resource\\CN\\wav\\access_s.wav": "6d1b31bdcaaa13ba719e3223b55d5235",
+ "resource\\CN\\wav\\btn11.wav": "a623797305d7b0e6b8cb6b2ab3d43591",
+ "resource\\CN\\wav\\btn12.wav": "26bbfc3eed36211713dca9afb423e168",
+ "resource\\CN\\wav\\btn13.wav": "67d6fe32693cb2e7653c2ff2141ce873",
+ "resource\\CN\\wav\\btn21.wav": "53071472fce6128fdd2ed304e4d78406",
+ "resource\\CN\\wav\\btn22.wav": "e35c87d370695099d3b6d7f512496395",
+ "resource\\CN\\wav\\btn23.wav": "f25db5592331f1e6deb67beecb3c1131",
+ "resource\\CN\\wav\\btn31.wav": "054a4f36ebda08fadca3162d955560bf",
+ "resource\\CN\\wav\\btn32.wav": "64eb5fef123eafd7b52108ebcd6bace9",
+ "resource\\CN\\wav\\btn33.wav": "67d6fe32693cb2e7653c2ff2141ce873",
+ "resource\\CN\\wav\\calibration_s.wav": "d2ff1f1f4a40bf4166130dc079939079",
+ "resource\\CN\\wav\\control_f.wav": "4dbaca7e4d227a720620b846544b469a",
+ "resource\\CN\\wav\\door_close.wav": "325ca8082f8e9fceb2c7eeeb78d8645b",
+ "resource\\CN\\wav\\door_open.wav": "f3b5291fc8babaffd32107198cdd5afa",
+ "resource\\CN\\wav\\emergency.wav": "a1855c22f3ef2f69d5c84d3a2852ae1f",
+ "resource\\CN\\wav\\emergency_f.wav": "946ac86e74b849ad8f1bec3615cf9b39",
+ "resource\\CN\\wav\\emergency_s.wav": "a717e3417891ff306225ac075ba28082",
+ "resource\\CN\\wav\\failed.wav": "891194e741b0bc8f6332f78eb607cc85",
+ "resource\\CN\\wav\\light_close.wav": "b1ac09e91ac4ce3825614ad1654a3f58",
+ "resource\\CN\\wav\\light_open.wav": "16b7b6b8c6eb469645a15e4a54a3e014",
+ "resource\\CN\\wav\\network.wav": "7bbc6d740918a20acfb5ef75df685bdb",
+ "resource\\CN\\wav\\read.wav": "c83edd035dc15f7a716644319e849215",
+ "resource\\CN\\wav\\recg_f.wav": "5cd4d88db4e3f8332b9e73fe05222c83",
+ "resource\\CN\\wav\\recg_s.wav": "4afadeb018b08518d5d3dd1cfc5e0d64",
+ "resource\\CN\\wav\\recognition.wav": "da00dd97d1e8ca0ed20dc43eb4daafc8",
+ "resource\\CN\\wav\\recognition_s.wav": "df9916d6fe3d285894668e63d1aeeb1d",
+ "resource\\CN\\wav\\register.wav": "a91d6ebb846dc834816a954168da1352",
+ "resource\\CN\\wav\\stranger.wav": "2e6690d7ddcd3609ca3e6d6717b61a9c",
+ "resource\\CN\\wav\\user2.wav": "868a9b15aac20b62457f98c955f4e5e0",
+ "resource\\CN\\wav\\user2_s.wav": "98904054df059be8cd69e08c302317e7",
+ "resource\\CN\\wav\\verify.wav": "2bc2b96e0ca05052985fda98fb552ef9",
+ "resource\\CN\\wav\\verify_10x_f.wav": "bf26ce11bbd801f5efeff8c9250f219f",
+ "resource\\CN\\wav\\verify_10x_s.wav": "2d04b22277844d9c35e08e4e2c67c11c",
+ "resource\\CN\\wav\\verify_200_f.wav": "393036b5fc28a3c04580593d59e26e7e",
+ "resource\\CN\\wav\\verify_200_s.wav": "585267371d37f3f45e3826ec7dcafbd3",
+ "resource\\CN\\wav\\verify_300_f.wav": "e44977e8b6dcac8adbf304894afd24e0",
+ "resource\\CN\\wav\\verify_300_s.wav": "d8e23a91e4999b2d77454aab824bd611",
+ "resource\\CN\\wav\\verify_400_f.wav": "05752c8c9c2bf4334943999842529d8b",
+ "resource\\CN\\wav\\verify_400_s.wav": "740a63ffe907dda0f2d0e14cb9a83f74",
+ "resource\\EN\\wav\\calibration_s.wav": "b5497547d9e7e6fb5b28ee307b27752b",
+ "resource\\EN\\wav\\network.wav": "1e8ccfd03ca83976fefdba1edcf1b194",
+ "resource\\EN\\wav\\read.wav": "8c1f6ee62c7bf74db5ecab28d3988eeb",
+ "resource\\EN\\wav\\recg_f.wav": "e303563b867dd6eaebac18679ca760df",
+ "resource\\EN\\wav\\recg_s.wav": "183a843b668aa919311a6d352af80f35",
+ "resource\\EN\\wav\\recognition.wav": "1c9e06bc338c49c120aa101b1fac8de0",
+ "resource\\EN\\wav\\recognition_s.wav": "f887f2b1615121bbe815fef7f64d3b92",
+ "resource\\EN\\wav\\register.wav": "de5d0048f840243fdd1392c09d9ac164",
+ "resource\\EN\\wav\\stranger.wav": "31775350903916827fdec25b9c65dd94",
+ "resource\\EN\\wav\\verify.wav": "2e77ec2c754e1dea329988d4e462aa2f",
+ "resource\\EN\\wav\\verify_10x_f.wav": "7ccc23490436b9f1de32200230953a62",
+ "resource\\EN\\wav\\verify_10x_s.wav": "0630e0410fca3c7fd7e701c69e8ea4bc",
+ "resource\\EN\\wav\\verify_200_f.wav": "64ce473b0f560cc1613469ab94197ce6",
+ "resource\\EN\\wav\\verify_200_s.wav": "e3d28c408cc3bef5461620c75b15abdf",
+ "resource\\EN\\wav\\verify_300_f.wav": "7fa0d7bf85d040b72a89cfb9e2f06bcf",
+ "resource\\EN\\wav\\verify_300_s.wav": "3e69fd763477d6cc30543d838f33d718",
+ "resource\\EN\\wav\\verify_400_f.wav": "d074b8f6e4e968b6d1984b123ed4d387",
+ "resource\\EN\\wav\\verify_400_s.wav": "9141136d3310a5fac5917d3f6056249f",
+ "resource\\font\\AlibabaPuHuiTi-2-65-Medium.ttf": "092a99ee52bbaef7481cc96c5b85b992",
+ "resource\\image\\4g.png": "e5b27ed5a596cb16c7ab695d82fe3014",
+ "resource\\image\\4g_dark.png": "414b3a9fcefd8ea6909158b51038d4d8",
+ "resource\\image\\accessCtrl.png": "6be30c8f648ec7153ae2c39a15884181",
+ "resource\\image\\add.png": "498480ce68e4d6047eb74d3aa5229f56",
+ "resource\\image\\advance.png": "d98aeb99a04163bce23b6c2638cd705a",
+ "resource\\image\\app.png": "7640c7358a3f5dba1f887b8413b93a9d",
+ "resource\\image\\app_btn.png": "aa325cea46fd3918c86d76bf009b1663",
+ "resource\\image\\app_qrcode.png": "0a20655d02ff0e473106bf41f7c9687b",
+ "resource\\image\\arrow_right.png": "edc6876d6fa1e2d0be2e606c73e0f2ec",
+ "resource\\image\\back.png": "aa5869ff78051dbdc5f688f1805064da",
+ "resource\\image\\background.jpg": "90d464f4221f62132ebf74e69446b6d7",
+ "resource\\image\\backspace.png": "26302e37dd8618e92c3a47d68039d0ec",
+ "resource\\image\\back_2.png": "b3f16ab01606d85c2c70124d50b3af1b",
+ "resource\\image\\basic.png": "84eedd84efdc5fdb54138dd29cf6fc41",
+ "resource\\image\\black_btn.png": "13ee1720aff247ba3f8e22e00f89a316",
+ "resource\\image\\card.png": "c05047d2ad6549db001d08790cb5d9ff",
+ "resource\\image\\close.png": "a5353c231df804fcc4577672ab3a4302",
+ "resource\\image\\close_small.png": "7d6cddddc38ce8d4950789169213add4",
+ "resource\\image\\cloudCert.png": "4481cfb9c2d1f44f0a0dd0489cb6fc2b",
+ "resource\\image\\co2_f.png": "7e6f00c03b71a4dbe439491083ca731c",
+ "resource\\image\\co2_s.png": "4fb691286b8856f1ed25ef8bacdb6099",
+ "resource\\image\\commMgmt.png": "5cd157e1b8c82fdf9ddba1f6d5047b9b",
+ "resource\\image\\config.png": "50d2091b9f7fba5915dbed0aa0dcf918",
+ "resource\\image\\config_btn.png": "e54cbc27d30e7c6480b83107a631e7ef",
+ "resource\\image\\delete.png": "014bad6d9a94a133c58ef350e198101e",
+ "resource\\image\\delete_fill.png": "947fc08278354a1151d5599382c2c5f3",
+ "resource\\image\\deviceInfo.png": "3e40246e01c1f7eede4d76fcbba33825",
+ "resource\\image\\devInfo.png": "1a80aba6780a45f8775bdfdcff4df23a",
+ "resource\\image\\doorControl.png": "68993ef92bb8c6b2d0dab2c75cc7533d",
+ "resource\\image\\down.png": "c4d5c1883db4694ccedb7c1140d89da9",
+ "resource\\image\\emergencyOpen.png": "890877dee840dabe60487f8ce57b41f6",
+ "resource\\image\\empty.png": "8283ac78099d9c13ef4b552ce86f5c38",
+ "resource\\image\\enter.png": "787e076256c8a47e07f2091a57585fb5",
+ "resource\\image\\enter_b.png": "02cb6c84fec128a639e3cf0828a6ee5f",
+ "resource\\image\\ethernet.png": "f3abb111d96a11a56f7ed77b21abab4c",
+ "resource\\image\\ethernet_dark.png": "10656303a6d22e204014f55ed0fb3efb",
+ "resource\\image\\eth_disable.png": "7017f5cc2c9b4f802f082f6c0f5bb581",
+ "resource\\image\\eth_enable.png": "84d1334e524ac669c3b79e8a69b41eb1",
+ "resource\\image\\eye-fill.png": "9ae71914bd47423be04d0a22eb4f3995",
+ "resource\\image\\eye-off.png": "295c3e8255ced50cf2667ecda524e11e",
+ "resource\\image\\eye_fill.png": "d0ac0d07f13e02e5fae7a12a0858ec49",
+ "resource\\image\\eye_fill_show.png": "265cf669797b94a138982c01c29d0bd9",
+ "resource\\image\\face.png": "d695a5f29dbf051fc0c6e0d4e177f5c5",
+ "resource\\image\\faceAdd.png": "5e0e3d4eb3f034a179a8eef5c08d4c63",
+ "resource\\image\\faceEmpty.png": "9ef3bd1d776183e203e69d5c91e4b129",
+ "resource\\image\\faceError.png": "19841af9136d4483642a254ab1a6f57c",
+ "resource\\image\\faceRec.png": "f1bfcb61f4642c6c1bbc04856fb57905",
+ "resource\\image\\faceRec2.png": "580c72783b4cfc64ec0a9593e77c456a",
+ "resource\\image\\factoryTest.png": "4bdb36420046870efcabd4a040e31913",
+ "resource\\image\\failBg.png": "5d6dca3cc98032a10ef4bc0658f7e546",
+ "resource\\image\\grey_btn.png": "b0ca6e44c0e01a17d0bdda5f7e057cc2",
+ "resource\\image\\help.png": "7d75da0510ca74870858a639882dc2ef",
+ "resource\\image\\idleImage.jpg": "90d464f4221f62132ebf74e69446b6d7",
+ "resource\\image\\input_bg.png": "8a8f5c43f1118869a7679ccbaaf47de2",
+ "resource\\image\\light_close.png": "607b38280bb5321327cacce5bd6c3fe9",
+ "resource\\image\\light_open.png": "1a8df3753b6f0df9e7abb5b53dabd72e",
+ "resource\\image\\localUser.png": "6429f43f7fee002d66d50a3d92a087da",
+ "resource\\image\\lock.png": "c1419aa2a9c9da4b7dbf3529a1af37f3",
+ "resource\\image\\logo.png": "5768b9344bedc53096d2227bee5d52d4",
+ "resource\\image\\menu_btn.png": "df98739cd4804d08b23eaf33bb92e1bc",
+ "resource\\image\\mini_app.png": "82ee9005b5d162a6fbb0d32764088da4",
+ "resource\\image\\mini_background.png": "620bf06dbfffe37f717b91fb3ed8ef40",
+ "resource\\image\\mini_config.png": "6bf78553fb53673a89e80613cfbee4c1",
+ "resource\\image\\mini_password.png": "6892385a457e084953bcf9acb2ae9957",
+ "resource\\image\\mqtt.png": "542ebc6bdbb66ea0f25cf29aeb9d264c",
+ "resource\\image\\mqtt_dark.png": "d4aab5adc128846c47a3b8bb015c757b",
+ "resource\\image\\mqtt_enable.png": "fc766f5fcbb95eca648ee10d421cc8fe",
+ "resource\\image\\network.png": "0a0119e3d5fce101b28575a4e44aaf7e",
+ "resource\\image\\networkSetting.png": "3e83d354e8293ed112fe7cc405b94187",
+ "resource\\image\\network_dark.png": "3c5f8ce5732e95ad613cdd41dc5adbc0",
+ "resource\\image\\o2_f.png": "b787951eba880b3ae82b42594b4e30df",
+ "resource\\image\\o2_s.png": "50564fb865bb7f5ed0352e43ea17d853",
+ "resource\\image\\ph3_f.png": "e95a348c887298dc4ed0555c577ea5bb",
+ "resource\\image\\ph3_s.png": "96e68d741b75fcd6938a6909014cccb0",
+ "resource\\image\\pwd_btn.png": "8764458bee98bff728445837e126231e",
+ "resource\\image\\qrcode_small.png": "285bbe7e8f968c8bf4506a563dffcac2",
+ "resource\\image\\recordQuery.png": "d340255a0c2342382bff6f8c57f6376b",
+ "resource\\image\\recQuery.png": "1b8c58663a6e61f4f885e784ee4e87d4",
+ "resource\\image\\rectangle.png": "394e2e483120908674f6de7fb879bfcf",
+ "resource\\image\\register.png": "7fa975d92007703532ba8011f2a0109f",
+ "resource\\image\\right.png": "a6f6bc770ad7a8220effcc96e750aaaa",
+ "resource\\image\\select_arrow.png": "9d82daa1092375abc413d581f36aaf2d",
+ "resource\\image\\setting.png": "92365fd93f2cfa63c7901ce3d8900a42",
+ "resource\\image\\setting32.png": "e531bf8a9ce7f6cf93a8ea9baf95377c",
+ "resource\\image\\space.png": "de9816e31308bd7ce187fe03ab634a37",
+ "resource\\image\\successBg.png": "1ef294bd7e1688bba47c2337906b1d1d",
+ "resource\\image\\success_fill.png": "09166b0cd4da44b76b4f6cdc2c550103",
+ "resource\\image\\sysSettings.png": "0a84bbe887481a1cce1ca562f83d5b89",
+ "resource\\image\\systemSetting.png": "9aee20d073df321250a5bbc57d16d5f1",
+ "resource\\image\\sys_info.png": "20dc23c019d07cd2c3ce32a160b7b63f",
+ "resource\\image\\title_bg.png": "82fbdcc4133899d03072dcd57a92f203",
+ "resource\\image\\trackFace.png": "e90f92eb629563ede01aadca2b719de9",
+ "resource\\image\\unlock.png": "7b97b659c36d3ba4f435f44792b90a80",
+ "resource\\image\\user.png": "6429f43f7fee002d66d50a3d92a087da",
+ "resource\\image\\userGuide.png": "3227210f670f66cd6c29641e1212b0b8",
+ "resource\\image\\userMgmt.png": "5dad96f344513f970c2b582d7feb537d",
+ "resource\\image\\user_1.png": "36ab26e22dc39ea28c03f05f4ab891ce",
+ "resource\\image\\user_f.png": "d82d235224deccd2235ab15dbf1fda26",
+ "resource\\image\\user_s.png": "709953f3695cae9ac1bb50533f1a96ba",
+ "resource\\image\\user_w.png": "bc2ca556f37181815c0093d802f2f24f",
+ "resource\\image\\view_f.png": "4fbdda957ef2966bc4938990725d0246",
+ "resource\\image\\view_s.png": "93ddad11d282c5a8f56233682290b38c",
+ "resource\\image\\vip.png": "0e816b4860ee87ed1169154e3f0fc524",
+ "resource\\image\\voiceBroadcast.png": "e6f1a31ba7159962d18b77deef71c106",
+ "resource\\image\\wifi.png": "fd668b648ac984ed92fad8e40e151283",
+ "resource\\image\\wifi_dark.png": "37505f892ac6a43cb8dc5ea685de9740",
+ "resource\\langPack.js": "b537e7ad7b7bd36ebef146692604007d",
+ "resource\\wav\\alarm.wav": "fe9d43cfb930f873973cc31fd6e8c132",
+ "src\\common\\consts\\configConst.js": "8cdbeff06611f7c94fc349afb2d04364",
+ "src\\common\\utils\\utils.js": "f45a9074748680b00ba663ad6490acf0",
+ "src\\config.json": "c6c52fdf036881dd11081f96b491fee5",
+ "src\\controller.js": "f09517062ac2a8641ea17909f9e635fd",
+ "src\\driver.js": "02c38e2dcc749c50fb348b94629278d0",
+ "src\\main.js": "a893be0e60fcd2ca32c94baf8534f996",
+ "src\\screen.js": "a2f377ed5832bb9139dfcaadffe091c7",
+ "src\\service\\accessService.js": "ca2abf5ea0cae58a1fc9ccffb9f03454",
+ "src\\service\\codeService.js": "63934baff614eedf7f8c7ee4855f9ebe",
+ "src\\service\\configService.js": "d991f7261781465e306cd9d4548eab4d",
+ "src\\service\\faceService.js": "4e6ef420f61bb617e3b57491f9305cb2",
+ "src\\service\\gpiokeyService.js": "71c8f8a2589492153671f1d7ed96e6c8",
+ "src\\service\\grainService.js": "99f05184d3fcdf5c4e54fce08500267b",
+ "src\\service\\mqttService.js": "78d18810234846a26b49161dc6f193af",
+ "src\\service\\nfcService.js": "45705bc6a95206927085f11e7208cac2",
+ "src\\service\\platService.js": "a38387366ed212029bb46c6d3a85f2e9",
+ "src\\service\\sqliteService.js": "f2f0864ae07d893789bfc1666b584410",
+ "src\\service\\uart485Service.js": "c62ad21c538095f950dffe12d6770aa0",
+ "src\\services.js": "b87698f1e9e03bcfac820956034b06fe",
+ "src\\ui.js": "e9adc3aac685e711427667fa7705be6f",
+ "src\\view\\appView.js": "3ada10f0136eb464c035aec809a6e600",
+ "src\\view\\config\\configView.js": "6e30bb6aa2a9f6e6187dc6d86d832901",
+ "src\\view\\config\\identityVerificationView.js": "aa8cdd417184b2bdcef1a6cbd49df487",
+ "src\\view\\config\\menu\\cloudCertView.js": "7c9181ccfa5b5e96a234f1f55307ccb9",
+ "src\\view\\config\\menu\\deviceInfo\\dataCapacityInfoView.js": "9b6d8db4b83758d778f84ac2a1a266c8",
+ "src\\view\\config\\menu\\deviceInfo\\systemInfoView.js": "9396136cd353b10bb9a56f9bda2315d5",
+ "src\\view\\config\\menu\\deviceInfoView.js": "b33452d2a4d7188c5d14c6f76b726e90",
+ "src\\view\\config\\menu\\dockingSetting.js": "13a156aa4889a7d032a6fa26605e85b8",
+ "src\\view\\config\\menu\\doorControlView.js": "ffd1d5bc1bb7c652bc678c52e9969fda",
+ "src\\view\\config\\menu\\factoryTestView.js": "9588321c8282257e9707ebedb5920cda",
+ "src\\view\\config\\menu\\helpView.js": "00e750b2b637dc318f75e840d901fb5c",
+ "src\\view\\config\\menu\\localUser\\faceEnterView.js": "d993d07711e15cf5f0fee01a22753bfa",
+ "src\\view\\config\\menu\\localUser\\localUserAddView.js": "bf4646521acd0e14832eb732bc424e77",
+ "src\\view\\config\\menu\\localUserView.js": "c870b92aaaec5aff368e07e9f254e8aa",
+ "src\\view\\config\\menu\\networkSettingView.js": "325d70ed8ab1e170ffc1fa03fff637f5",
+ "src\\view\\config\\menu\\recordQuery\\recordQueryDetailView.js": "7077207b15bf1d7eae3a9a01dc68dc77",
+ "src\\view\\config\\menu\\recordQueryView.js": "67b573825af0639a4103bdc97b0f2c4a",
+ "src\\view\\config\\menu\\systemSetting\\displaySettingView.js": "c57f3b9faf85e048864c08d592481a72",
+ "src\\view\\config\\menu\\systemSetting\\faceRecognitionSettingView.js": "4d6b4e8b6c0f6e0ccbaaaa169e65b780",
+ "src\\view\\config\\menu\\systemSetting\\passLogSettingView.js": "d51958ac39b104846586b1ed6590414c",
+ "src\\view\\config\\menu\\systemSetting\\passwordManagementView.js": "98a6ca138cc1e2bc33ff6a3248e11263",
+ "src\\view\\config\\menu\\systemSetting\\passwordOpenDoorSettingView.js": "6e2ab3793e6c569097b702c339ef1602",
+ "src\\view\\config\\menu\\systemSetting\\swipeCardRecognitionSettingView.js": "871b483fbc3d778df95b803c130101e1",
+ "src\\view\\config\\menu\\systemSetting\\timeSettingView.js": "6950faa3a3296a573d048eb782c0e6ca",
+ "src\\view\\config\\menu\\systemSettingView.js": "ca3ac7b0e0390c7d542b62d569f57b24",
+ "src\\view\\config\\menu\\voiceBroadcastView.js": "a809af8acdae03f15c6e677bef6f20a1",
+ "src\\view\\config\\newPwdView.js": "32e3cfb0cc7f88361f1c69797cdb14b8",
+ "src\\view\\emergencyPwdView.js": "c6413bc04d38d54e57f590ce44204bcb",
+ "src\\view\\i18n.js": "94f43798d35026189125bf2534d1bffd",
+ "src\\view\\idleView.js": "b95c100ae4b2757ea2b0844a3df35c9e",
+ "src\\view\\mainView.js": "ec96a69994b99ed36778338198f74765",
+ "src\\view\\pinyin\\dict.js": "e40764bfc6bab80119c584315c0c48b7",
+ "src\\view\\pinyin\\pinyin.js": "c0809d9d1ebe5937cb6831b2b70db439",
+ "src\\view\\pwdView.js": "226b8b83a13b82cc925519ae051f8b3f",
+ "src\\view\\topView.js": "c9d8a4e3bc362edb1a5007135323beea",
+ "src\\view\\viewUtils.js": "ceaaad4fb40024b448a66a03911a7279",
+ "src\\worker\\accessWorker.js": "1b1253b5a7fbb2e733be2a9b0714ecca",
+ "src\\worker\\httpWorker.js": "47ddc63bdd95ecf36f7eaaa5f409424c"
+}
\ No newline at end of file
diff --git a/vf205_access/.temp/md5snew.json b/vf205_access/.temp/md5snew.json
new file mode 100644
index 0000000..5283314
--- /dev/null
+++ b/vf205_access/.temp/md5snew.json
@@ -0,0 +1,330 @@
+{
+ "app.dxproj": "cb10fd21e8e17ada45c25e1e1ba3226e",
+ "dxmodules\\cameraCalibrationWorker.js": "5812507304ced88da3677a3c68f79a78",
+ "dxmodules\\capturerWorker.js": "a3104a1d73ab1bd4f596495d817ecf39",
+ "dxmodules\\dxAlsa.js": "d82fe4f74383edf6198269968a82b5e7",
+ "dxmodules\\dxBase64.js": "7cb517ecd99830dde0ec13a501e831ea",
+ "dxmodules\\dxCameraCalibration.js": "8e42bf3752616896b88f9e9efbe20783",
+ "dxmodules\\dxCapturer.js": "7420d8e269fb8ebfc48c306e0a8fa7de",
+ "dxmodules\\dxCommon.js": "19f77916eb02e6fd01106597aca412bd",
+ "dxmodules\\dxConfig.js": "24072559b3cb1ec5c206cb358eaaaaae",
+ "dxmodules\\dxDriver.js": "c5969e91097030b90e9bcb62a827e344",
+ "dxmodules\\dxEid.js": "07d966e53b69629f152baf54cd163372",
+ "dxmodules\\dxEventBus.js": "81adf285545c12d49d7784327c41970a",
+ "dxmodules\\dxFace.js": "81790e30c6da75ae3bcb96afcafa5b02",
+ "dxmodules\\dxGpio.js": "30c34469e2dc8d80026fc5eac5bfd1f7",
+ "dxmodules\\dxGpioKey.js": "97ef2763bad50e0c82cfa5fb9b79f1eb",
+ "dxmodules\\dxHttp.js": "fa75a0a2951399fb5af7618d7ab4c6f1",
+ "dxmodules\\dxLogger.js": "f6d3f73086944fcdeeffa579ef6d1508",
+ "dxmodules\\dxMap.js": "2255d584c240c35a567f2c7b92e0a9da",
+ "dxmodules\\dxMqtt.js": "277fafb81971c8f3508a8a38f8f2703a",
+ "dxmodules\\dxNet.js": "58b13f928daeb1bae680c2350873baca",
+ "dxmodules\\dxNfc.js": "feb5bc21d4b13ab9736de1941290312d",
+ "dxmodules\\dxNtp.js": "0c90048eeb11e7e3b458e4d6e48932f2",
+ "dxmodules\\dxOta.js": "760dc97eb0724280f16f8616a2be171f",
+ "dxmodules\\dxPwm.js": "dc0734c231d7d4cd5f26a34c315cc4a2",
+ "dxmodules\\dxQrRule.js": "bfa9e2b4725c4fa358a2988f63c67210",
+ "dxmodules\\dxSqlite.js": "fb6a2f60b49d67a8ef36148355e5e30e",
+ "dxmodules\\dxStd.js": "6f239f2fd7d23e7ed053b762b235bd3c",
+ "dxmodules\\dxUart.js": "71edddfd98de79ccbd91e4e013af269b",
+ "dxmodules\\dxUi.js": "97bd858defaec480d755c162105a3f76",
+ "dxmodules\\dxWatchdog.js": "c4a7d5c8f0c203e6dafbc289a0f4fcbd",
+ "dxmodules\\dxWorkerPool.js": "5aad9b8f838d1339fc64083188d3ba69",
+ "dxmodules\\faceWorker.js": "d1d0d4f5e5503ca87bd69d1d2ee3ad00",
+ "dxmodules\\gpioKeyWorker.js": "78a7489cc3cf098fb4d218b17294175d",
+ "dxmodules\\libalc.so": "3128cc7cd0cc978e02db995433962c87",
+ "dxmodules\\libid_jpg.so": "18887cb0d0df6256604ed039d47dfc7b",
+ "dxmodules\\libid_jpg_codec.so": "c36bd0c28d2b43e9296736856da05129",
+ "dxmodules\\libie_jpg.so": "1343b7bc765f6464cf8e483c03edd542",
+ "dxmodules\\libie_jpg_codec.so": "508defffc1c72b0ae90afab117d6db80",
+ "dxmodules\\libJLReader.so": "ce7f448dea6a1c8988469d03ecfa6575",
+ "dxmodules\\liblombo_jpeg.so": "49508ccd603ed795efee3d0f8e7e3e2a",
+ "dxmodules\\libvbar-b-dxface.so": "689ee554f67057262860f7726042327b",
+ "dxmodules\\libvbar-b-dxgpio.so": "ca009351ab7d9719a71cd6105e9acba6",
+ "dxmodules\\libvbar-b-dxpwm.so": "b3e0e7cc950811385ceb204876fd8b19",
+ "dxmodules\\libvbar-b-dxwatchdog.so": "878352b309e9a9e17ce3ac83774d0fa9",
+ "dxmodules\\libvbar-drv-audio_gain.so": "14d23fe5134ff95982f1655058084709",
+ "dxmodules\\libvbar-drv-capturer.so": "295aaa64df97ee08053c26789ff57437",
+ "dxmodules\\libvbar-drv-capturer_calibration.so": "cdb2ca2205e36d82ebcce910e457bd9b",
+ "dxmodules\\libvbar-drv-display.so": "31c2a7a2ed4166d27359d208e4d34568",
+ "dxmodules\\libvbar-drv-face.so": "2c54abd0de9a287be3bbea490d0c45c4",
+ "dxmodules\\libvbar-drv-gpio.so": "e663856deb2d403558426455097e0bab",
+ "dxmodules\\libvbar-drv-memory.so": "0ed48486e154f24d6681a0195a7525ad",
+ "dxmodules\\libvbar-drv-pwm.so": "b9c2154b7020d41b01d63f6caac1510f",
+ "dxmodules\\libvbar-drv-soc.so": "73e4b6657af4bcff0affaacf55702096",
+ "dxmodules\\libvbar-drv-tts.so": "97076b55a3338196f512c61101ac0e9a",
+ "dxmodules\\libvbar-drv-watchdog.so": "9367e995f85cb191da0567d0acd4ed67",
+ "dxmodules\\libvbar-m-alsa.so": "1154ff7cb2f84ee378f29e0d03551f96",
+ "dxmodules\\libvbar-m-capturer.so": "8f0b6383db39494904294c3f60c5f013",
+ "dxmodules\\libvbar-m-channel.so": "6b6f7d8edb178b11b9a93123e0a7abdb",
+ "dxmodules\\libvbar-m-common.so": "074eb14e701c5ed910b979339453f484",
+ "dxmodules\\libvbar-m-dxalsa.so": "bb4fcf0be6ccb0cc2d7b295002925148",
+ "dxmodules\\libvbar-m-dxcapturer.so": "506307dec2552200eaa22412987b643e",
+ "dxmodules\\libvbar-m-dxcapturer_calibration.so": "c41e691d69621ab5a96322f47d3eb286",
+ "dxmodules\\libvbar-m-dxchannel.so": "ff80aaf50113c160c663a80015471079",
+ "dxmodules\\libvbar-m-dxcommon.so": "d4ca3ce51543d07c81cc75974adcbccb",
+ "dxmodules\\libvbar-m-dxeid.so": "3458f8221dd572220003e4344837d846",
+ "dxmodules\\libvbar-m-dxhttp.so": "1ec2f9ccc26aebc390944340afde6044",
+ "dxmodules\\libvbar-m-dxkey.so": "e49a86e25944050bda8565677713431a",
+ "dxmodules\\libvbar-m-dxmap.so": "55ebd66234d59490ab56f88398419dde",
+ "dxmodules\\libvbar-m-dxmqtt.so": "0cbeb2b46441ee89678516a1a941cd58",
+ "dxmodules\\libvbar-m-dxnet.so": "eed60270cabaf872983c6f905b0ceb03",
+ "dxmodules\\libvbar-m-dxsqlite.so": "15a0eb0d18b58cad3868f86e9edfb409",
+ "dxmodules\\libvbar-m-dxui.so": "ca22e1a0c52977749a32b2cc70e942a9",
+ "dxmodules\\libvbar-m-eid.so": "e7d1db4d1bfab4c462c9d22807099268",
+ "dxmodules\\libvbar-m-key.so": "f7f1f2ae6c9c1f298376375a8b16b6ee",
+ "dxmodules\\libvbar-m-net.so": "afa1adebb44fc9734b26b99e87e0728d",
+ "dxmodules\\libvbar-m-vgmqtt.so": "56e94165ba896867fbe3ead167022d3f",
+ "dxmodules\\libvbar-p-dxnfc.so": "14d17fe22a0dbfc00b13c4d9cef8512f",
+ "dxmodules\\libvbar-p-nfc.so": "f1a1f96558b2509c5b629790cec16386",
+ "dxmodules\\libvccore.so": "9c383ca78ee117ea3295baefb1f1fee2",
+ "dxmodules\\libyuv.so": "2c4faa3ab51260f5285cd91dda44b3a9",
+ "dxmodules\\mqttWorker.js": "4eedadbd41d6bd183cde2830a3347ad1",
+ "dxmodules\\netWorker.js": "c5d4c9022f8912b47249b14477aed70a",
+ "dxmodules\\nfcWorker.js": "88fadfc469cc397b66fd5e52db073bde",
+ "dxmodules\\uiBase.js": "9ea5cd2b5ed52d183fde2d87b8f70ca1",
+ "dxmodules\\uiButton.js": "8ffe0ffce9ac6b341c9993e260b52b05",
+ "dxmodules\\uiButtons.js": "52cb9727c2225f75ac6144e756a6d511",
+ "dxmodules\\uiCheckbox.js": "5aa8c851e8b2333cbe46cdd69452ab8c",
+ "dxmodules\\uiDropdown.js": "2b73bfacf3d4b115ab3997c83284c478",
+ "dxmodules\\uiFont.js": "257aa2f90ce2f0ace4095a03d3447b0b",
+ "dxmodules\\uiImage.js": "b2a0a963993474205bc7dc91c8696ec1",
+ "dxmodules\\uiKeyboard.js": "b225c62ff2f4b8aa0bdb675776b236a1",
+ "dxmodules\\uiLabel.js": "e0ae808d468459a6fedc7ba9a551359e",
+ "dxmodules\\uiLine.js": "cc18bc32c0a6f0f8db7992d6e0b4fd81",
+ "dxmodules\\uiList.js": "8b779a85cd54b25bc50ec616ed9f08d1",
+ "dxmodules\\uiSlider.js": "91b743902824b5decf5535dad49fc97e",
+ "dxmodules\\uiStyle.js": "60350cf77db84793bf093bda341f2cb9",
+ "dxmodules\\uiSwitch.js": "9a836405abe0b09f5a2940cf22698968",
+ "dxmodules\\uiTextarea.js": "0d5008a5a95b78ea8efde3408ba6fb4a",
+ "dxmodules\\uiUtils.js": "a04cc3baa5ba1dc6d1ab65b526464fa6",
+ "dxmodules\\uiView.js": "26fe7b992ac82bf5d45447f2921bff2f",
+ "dxmodules\\vgUartWorker.js": "fc3e9e0051836d5063c0eecf555d9521",
+ "README.md": "c472daef5243f3790f2faee1cf8e2255",
+ "README_CN.md": "a46b1c92c09f375881a49d8c42adf6b3",
+ "resource\\CN\\wav\\access_f.wav": "f951f3cc1f03aaa794231413fd4efcc6",
+ "resource\\CN\\wav\\access_s.wav": "6d1b31bdcaaa13ba719e3223b55d5235",
+ "resource\\CN\\wav\\btn11.wav": "a623797305d7b0e6b8cb6b2ab3d43591",
+ "resource\\CN\\wav\\btn12.wav": "26bbfc3eed36211713dca9afb423e168",
+ "resource\\CN\\wav\\btn13.wav": "67d6fe32693cb2e7653c2ff2141ce873",
+ "resource\\CN\\wav\\btn21.wav": "53071472fce6128fdd2ed304e4d78406",
+ "resource\\CN\\wav\\btn22.wav": "e35c87d370695099d3b6d7f512496395",
+ "resource\\CN\\wav\\btn23.wav": "f25db5592331f1e6deb67beecb3c1131",
+ "resource\\CN\\wav\\btn31.wav": "054a4f36ebda08fadca3162d955560bf",
+ "resource\\CN\\wav\\btn32.wav": "64eb5fef123eafd7b52108ebcd6bace9",
+ "resource\\CN\\wav\\btn33.wav": "67d6fe32693cb2e7653c2ff2141ce873",
+ "resource\\CN\\wav\\calibration_s.wav": "d2ff1f1f4a40bf4166130dc079939079",
+ "resource\\CN\\wav\\control_f.wav": "4dbaca7e4d227a720620b846544b469a",
+ "resource\\CN\\wav\\door_close.wav": "325ca8082f8e9fceb2c7eeeb78d8645b",
+ "resource\\CN\\wav\\door_open.wav": "f3b5291fc8babaffd32107198cdd5afa",
+ "resource\\CN\\wav\\emergency.wav": "a1855c22f3ef2f69d5c84d3a2852ae1f",
+ "resource\\CN\\wav\\emergency_f.wav": "946ac86e74b849ad8f1bec3615cf9b39",
+ "resource\\CN\\wav\\emergency_s.wav": "a717e3417891ff306225ac075ba28082",
+ "resource\\CN\\wav\\failed.wav": "891194e741b0bc8f6332f78eb607cc85",
+ "resource\\CN\\wav\\light_close.wav": "b1ac09e91ac4ce3825614ad1654a3f58",
+ "resource\\CN\\wav\\light_open.wav": "16b7b6b8c6eb469645a15e4a54a3e014",
+ "resource\\CN\\wav\\network.wav": "7bbc6d740918a20acfb5ef75df685bdb",
+ "resource\\CN\\wav\\read.wav": "c83edd035dc15f7a716644319e849215",
+ "resource\\CN\\wav\\recg_f.wav": "5cd4d88db4e3f8332b9e73fe05222c83",
+ "resource\\CN\\wav\\recg_s.wav": "4afadeb018b08518d5d3dd1cfc5e0d64",
+ "resource\\CN\\wav\\recognition.wav": "da00dd97d1e8ca0ed20dc43eb4daafc8",
+ "resource\\CN\\wav\\recognition_s.wav": "df9916d6fe3d285894668e63d1aeeb1d",
+ "resource\\CN\\wav\\register.wav": "a91d6ebb846dc834816a954168da1352",
+ "resource\\CN\\wav\\stranger.wav": "2e6690d7ddcd3609ca3e6d6717b61a9c",
+ "resource\\CN\\wav\\user2.wav": "868a9b15aac20b62457f98c955f4e5e0",
+ "resource\\CN\\wav\\user2_s.wav": "98904054df059be8cd69e08c302317e7",
+ "resource\\CN\\wav\\verify.wav": "2bc2b96e0ca05052985fda98fb552ef9",
+ "resource\\CN\\wav\\verify_10x_f.wav": "bf26ce11bbd801f5efeff8c9250f219f",
+ "resource\\CN\\wav\\verify_10x_s.wav": "2d04b22277844d9c35e08e4e2c67c11c",
+ "resource\\CN\\wav\\verify_200_f.wav": "393036b5fc28a3c04580593d59e26e7e",
+ "resource\\CN\\wav\\verify_200_s.wav": "585267371d37f3f45e3826ec7dcafbd3",
+ "resource\\CN\\wav\\verify_300_f.wav": "e44977e8b6dcac8adbf304894afd24e0",
+ "resource\\CN\\wav\\verify_300_s.wav": "d8e23a91e4999b2d77454aab824bd611",
+ "resource\\CN\\wav\\verify_400_f.wav": "05752c8c9c2bf4334943999842529d8b",
+ "resource\\CN\\wav\\verify_400_s.wav": "740a63ffe907dda0f2d0e14cb9a83f74",
+ "resource\\EN\\wav\\calibration_s.wav": "b5497547d9e7e6fb5b28ee307b27752b",
+ "resource\\EN\\wav\\network.wav": "1e8ccfd03ca83976fefdba1edcf1b194",
+ "resource\\EN\\wav\\read.wav": "8c1f6ee62c7bf74db5ecab28d3988eeb",
+ "resource\\EN\\wav\\recg_f.wav": "e303563b867dd6eaebac18679ca760df",
+ "resource\\EN\\wav\\recg_s.wav": "183a843b668aa919311a6d352af80f35",
+ "resource\\EN\\wav\\recognition.wav": "1c9e06bc338c49c120aa101b1fac8de0",
+ "resource\\EN\\wav\\recognition_s.wav": "f887f2b1615121bbe815fef7f64d3b92",
+ "resource\\EN\\wav\\register.wav": "de5d0048f840243fdd1392c09d9ac164",
+ "resource\\EN\\wav\\stranger.wav": "31775350903916827fdec25b9c65dd94",
+ "resource\\EN\\wav\\verify.wav": "2e77ec2c754e1dea329988d4e462aa2f",
+ "resource\\EN\\wav\\verify_10x_f.wav": "7ccc23490436b9f1de32200230953a62",
+ "resource\\EN\\wav\\verify_10x_s.wav": "0630e0410fca3c7fd7e701c69e8ea4bc",
+ "resource\\EN\\wav\\verify_200_f.wav": "64ce473b0f560cc1613469ab94197ce6",
+ "resource\\EN\\wav\\verify_200_s.wav": "e3d28c408cc3bef5461620c75b15abdf",
+ "resource\\EN\\wav\\verify_300_f.wav": "7fa0d7bf85d040b72a89cfb9e2f06bcf",
+ "resource\\EN\\wav\\verify_300_s.wav": "3e69fd763477d6cc30543d838f33d718",
+ "resource\\EN\\wav\\verify_400_f.wav": "d074b8f6e4e968b6d1984b123ed4d387",
+ "resource\\EN\\wav\\verify_400_s.wav": "9141136d3310a5fac5917d3f6056249f",
+ "resource\\font\\AlibabaPuHuiTi-2-65-Medium.ttf": "092a99ee52bbaef7481cc96c5b85b992",
+ "resource\\image\\4g.png": "e5b27ed5a596cb16c7ab695d82fe3014",
+ "resource\\image\\4g_dark.png": "414b3a9fcefd8ea6909158b51038d4d8",
+ "resource\\image\\accessCtrl.png": "6be30c8f648ec7153ae2c39a15884181",
+ "resource\\image\\add.png": "498480ce68e4d6047eb74d3aa5229f56",
+ "resource\\image\\advance.png": "d98aeb99a04163bce23b6c2638cd705a",
+ "resource\\image\\app.png": "7640c7358a3f5dba1f887b8413b93a9d",
+ "resource\\image\\app_btn.png": "aa325cea46fd3918c86d76bf009b1663",
+ "resource\\image\\app_qrcode.png": "0a20655d02ff0e473106bf41f7c9687b",
+ "resource\\image\\arrow_right.png": "edc6876d6fa1e2d0be2e606c73e0f2ec",
+ "resource\\image\\back.png": "aa5869ff78051dbdc5f688f1805064da",
+ "resource\\image\\background.jpg": "90d464f4221f62132ebf74e69446b6d7",
+ "resource\\image\\backspace.png": "26302e37dd8618e92c3a47d68039d0ec",
+ "resource\\image\\back_2.png": "b3f16ab01606d85c2c70124d50b3af1b",
+ "resource\\image\\basic.png": "84eedd84efdc5fdb54138dd29cf6fc41",
+ "resource\\image\\black_btn.png": "13ee1720aff247ba3f8e22e00f89a316",
+ "resource\\image\\card.png": "c05047d2ad6549db001d08790cb5d9ff",
+ "resource\\image\\close.png": "a5353c231df804fcc4577672ab3a4302",
+ "resource\\image\\close_small.png": "7d6cddddc38ce8d4950789169213add4",
+ "resource\\image\\cloudCert.png": "4481cfb9c2d1f44f0a0dd0489cb6fc2b",
+ "resource\\image\\co2_f.png": "7e6f00c03b71a4dbe439491083ca731c",
+ "resource\\image\\co2_s.png": "4fb691286b8856f1ed25ef8bacdb6099",
+ "resource\\image\\commMgmt.png": "5cd157e1b8c82fdf9ddba1f6d5047b9b",
+ "resource\\image\\config.png": "50d2091b9f7fba5915dbed0aa0dcf918",
+ "resource\\image\\config_btn.png": "e54cbc27d30e7c6480b83107a631e7ef",
+ "resource\\image\\delete.png": "014bad6d9a94a133c58ef350e198101e",
+ "resource\\image\\delete_fill.png": "947fc08278354a1151d5599382c2c5f3",
+ "resource\\image\\deviceInfo.png": "3e40246e01c1f7eede4d76fcbba33825",
+ "resource\\image\\devInfo.png": "1a80aba6780a45f8775bdfdcff4df23a",
+ "resource\\image\\doorControl.png": "68993ef92bb8c6b2d0dab2c75cc7533d",
+ "resource\\image\\down.png": "c4d5c1883db4694ccedb7c1140d89da9",
+ "resource\\image\\emergencyOpen.png": "890877dee840dabe60487f8ce57b41f6",
+ "resource\\image\\empty.png": "8283ac78099d9c13ef4b552ce86f5c38",
+ "resource\\image\\enter.png": "787e076256c8a47e07f2091a57585fb5",
+ "resource\\image\\enter_b.png": "02cb6c84fec128a639e3cf0828a6ee5f",
+ "resource\\image\\ethernet.png": "f3abb111d96a11a56f7ed77b21abab4c",
+ "resource\\image\\ethernet_dark.png": "10656303a6d22e204014f55ed0fb3efb",
+ "resource\\image\\eth_disable.png": "7017f5cc2c9b4f802f082f6c0f5bb581",
+ "resource\\image\\eth_enable.png": "84d1334e524ac669c3b79e8a69b41eb1",
+ "resource\\image\\eye-fill.png": "9ae71914bd47423be04d0a22eb4f3995",
+ "resource\\image\\eye-off.png": "295c3e8255ced50cf2667ecda524e11e",
+ "resource\\image\\eye_fill.png": "d0ac0d07f13e02e5fae7a12a0858ec49",
+ "resource\\image\\eye_fill_show.png": "265cf669797b94a138982c01c29d0bd9",
+ "resource\\image\\face.png": "d695a5f29dbf051fc0c6e0d4e177f5c5",
+ "resource\\image\\faceAdd.png": "5e0e3d4eb3f034a179a8eef5c08d4c63",
+ "resource\\image\\faceEmpty.png": "9ef3bd1d776183e203e69d5c91e4b129",
+ "resource\\image\\faceError.png": "19841af9136d4483642a254ab1a6f57c",
+ "resource\\image\\faceRec.png": "f1bfcb61f4642c6c1bbc04856fb57905",
+ "resource\\image\\faceRec2.png": "580c72783b4cfc64ec0a9593e77c456a",
+ "resource\\image\\factoryTest.png": "4bdb36420046870efcabd4a040e31913",
+ "resource\\image\\failBg.png": "5d6dca3cc98032a10ef4bc0658f7e546",
+ "resource\\image\\grey_btn.png": "b0ca6e44c0e01a17d0bdda5f7e057cc2",
+ "resource\\image\\help.png": "7d75da0510ca74870858a639882dc2ef",
+ "resource\\image\\idleImage.jpg": "90d464f4221f62132ebf74e69446b6d7",
+ "resource\\image\\input_bg.png": "8a8f5c43f1118869a7679ccbaaf47de2",
+ "resource\\image\\light_close.png": "607b38280bb5321327cacce5bd6c3fe9",
+ "resource\\image\\light_open.png": "1a8df3753b6f0df9e7abb5b53dabd72e",
+ "resource\\image\\localUser.png": "6429f43f7fee002d66d50a3d92a087da",
+ "resource\\image\\lock.png": "c1419aa2a9c9da4b7dbf3529a1af37f3",
+ "resource\\image\\logo.png": "5768b9344bedc53096d2227bee5d52d4",
+ "resource\\image\\menu_btn.png": "df98739cd4804d08b23eaf33bb92e1bc",
+ "resource\\image\\mini_app.png": "82ee9005b5d162a6fbb0d32764088da4",
+ "resource\\image\\mini_background.png": "620bf06dbfffe37f717b91fb3ed8ef40",
+ "resource\\image\\mini_config.png": "6bf78553fb53673a89e80613cfbee4c1",
+ "resource\\image\\mini_password.png": "6892385a457e084953bcf9acb2ae9957",
+ "resource\\image\\mqtt.png": "542ebc6bdbb66ea0f25cf29aeb9d264c",
+ "resource\\image\\mqtt_dark.png": "d4aab5adc128846c47a3b8bb015c757b",
+ "resource\\image\\mqtt_enable.png": "fc766f5fcbb95eca648ee10d421cc8fe",
+ "resource\\image\\network.png": "0a0119e3d5fce101b28575a4e44aaf7e",
+ "resource\\image\\networkSetting.png": "3e83d354e8293ed112fe7cc405b94187",
+ "resource\\image\\network_dark.png": "3c5f8ce5732e95ad613cdd41dc5adbc0",
+ "resource\\image\\o2_f.png": "b787951eba880b3ae82b42594b4e30df",
+ "resource\\image\\o2_s.png": "50564fb865bb7f5ed0352e43ea17d853",
+ "resource\\image\\ph3_f.png": "e95a348c887298dc4ed0555c577ea5bb",
+ "resource\\image\\ph3_s.png": "96e68d741b75fcd6938a6909014cccb0",
+ "resource\\image\\pwd_btn.png": "8764458bee98bff728445837e126231e",
+ "resource\\image\\qrcode_small.png": "285bbe7e8f968c8bf4506a563dffcac2",
+ "resource\\image\\recordQuery.png": "d340255a0c2342382bff6f8c57f6376b",
+ "resource\\image\\recQuery.png": "1b8c58663a6e61f4f885e784ee4e87d4",
+ "resource\\image\\rectangle.png": "394e2e483120908674f6de7fb879bfcf",
+ "resource\\image\\register.png": "7fa975d92007703532ba8011f2a0109f",
+ "resource\\image\\right.png": "a6f6bc770ad7a8220effcc96e750aaaa",
+ "resource\\image\\select_arrow.png": "9d82daa1092375abc413d581f36aaf2d",
+ "resource\\image\\setting.png": "92365fd93f2cfa63c7901ce3d8900a42",
+ "resource\\image\\setting32.png": "e531bf8a9ce7f6cf93a8ea9baf95377c",
+ "resource\\image\\space.png": "de9816e31308bd7ce187fe03ab634a37",
+ "resource\\image\\successBg.png": "1ef294bd7e1688bba47c2337906b1d1d",
+ "resource\\image\\success_fill.png": "09166b0cd4da44b76b4f6cdc2c550103",
+ "resource\\image\\sysSettings.png": "0a84bbe887481a1cce1ca562f83d5b89",
+ "resource\\image\\systemSetting.png": "9aee20d073df321250a5bbc57d16d5f1",
+ "resource\\image\\sys_info.png": "20dc23c019d07cd2c3ce32a160b7b63f",
+ "resource\\image\\title_bg.png": "82fbdcc4133899d03072dcd57a92f203",
+ "resource\\image\\trackFace.png": "e90f92eb629563ede01aadca2b719de9",
+ "resource\\image\\unlock.png": "7b97b659c36d3ba4f435f44792b90a80",
+ "resource\\image\\user.png": "6429f43f7fee002d66d50a3d92a087da",
+ "resource\\image\\userGuide.png": "3227210f670f66cd6c29641e1212b0b8",
+ "resource\\image\\userMgmt.png": "5dad96f344513f970c2b582d7feb537d",
+ "resource\\image\\user_1.png": "36ab26e22dc39ea28c03f05f4ab891ce",
+ "resource\\image\\user_f.png": "d82d235224deccd2235ab15dbf1fda26",
+ "resource\\image\\user_s.png": "709953f3695cae9ac1bb50533f1a96ba",
+ "resource\\image\\user_w.png": "bc2ca556f37181815c0093d802f2f24f",
+ "resource\\image\\view_f.png": "4fbdda957ef2966bc4938990725d0246",
+ "resource\\image\\view_s.png": "93ddad11d282c5a8f56233682290b38c",
+ "resource\\image\\vip.png": "0e816b4860ee87ed1169154e3f0fc524",
+ "resource\\image\\voiceBroadcast.png": "e6f1a31ba7159962d18b77deef71c106",
+ "resource\\image\\wifi.png": "fd668b648ac984ed92fad8e40e151283",
+ "resource\\image\\wifi_dark.png": "37505f892ac6a43cb8dc5ea685de9740",
+ "resource\\langPack.js": "b537e7ad7b7bd36ebef146692604007d",
+ "resource\\wav\\alarm.wav": "fe9d43cfb930f873973cc31fd6e8c132",
+ "src\\common\\consts\\configConst.js": "8cdbeff06611f7c94fc349afb2d04364",
+ "src\\common\\utils\\utils.js": "f45a9074748680b00ba663ad6490acf0",
+ "src\\config.json": "c6c52fdf036881dd11081f96b491fee5",
+ "src\\controller.js": "f09517062ac2a8641ea17909f9e635fd",
+ "src\\driver.js": "02c38e2dcc749c50fb348b94629278d0",
+ "src\\main.js": "a893be0e60fcd2ca32c94baf8534f996",
+ "src\\screen.js": "a2f377ed5832bb9139dfcaadffe091c7",
+ "src\\service\\accessService.js": "ca2abf5ea0cae58a1fc9ccffb9f03454",
+ "src\\service\\codeService.js": "63934baff614eedf7f8c7ee4855f9ebe",
+ "src\\service\\configService.js": "d991f7261781465e306cd9d4548eab4d",
+ "src\\service\\faceService.js": "4e6ef420f61bb617e3b57491f9305cb2",
+ "src\\service\\gpiokeyService.js": "71c8f8a2589492153671f1d7ed96e6c8",
+ "src\\service\\grainService.js": "99f05184d3fcdf5c4e54fce08500267b",
+ "src\\service\\mqttService.js": "78d18810234846a26b49161dc6f193af",
+ "src\\service\\nfcService.js": "45705bc6a95206927085f11e7208cac2",
+ "src\\service\\platService.js": "a38387366ed212029bb46c6d3a85f2e9",
+ "src\\service\\sqliteService.js": "f2f0864ae07d893789bfc1666b584410",
+ "src\\service\\uart485Service.js": "c62ad21c538095f950dffe12d6770aa0",
+ "src\\services.js": "b87698f1e9e03bcfac820956034b06fe",
+ "src\\ui.js": "e9adc3aac685e711427667fa7705be6f",
+ "src\\view\\appView.js": "3ada10f0136eb464c035aec809a6e600",
+ "src\\view\\config\\configView.js": "6e30bb6aa2a9f6e6187dc6d86d832901",
+ "src\\view\\config\\identityVerificationView.js": "aa8cdd417184b2bdcef1a6cbd49df487",
+ "src\\view\\config\\menu\\cloudCertView.js": "7c9181ccfa5b5e96a234f1f55307ccb9",
+ "src\\view\\config\\menu\\deviceInfo\\dataCapacityInfoView.js": "9b6d8db4b83758d778f84ac2a1a266c8",
+ "src\\view\\config\\menu\\deviceInfo\\systemInfoView.js": "9396136cd353b10bb9a56f9bda2315d5",
+ "src\\view\\config\\menu\\deviceInfoView.js": "b33452d2a4d7188c5d14c6f76b726e90",
+ "src\\view\\config\\menu\\dockingSetting.js": "13a156aa4889a7d032a6fa26605e85b8",
+ "src\\view\\config\\menu\\doorControlView.js": "ffd1d5bc1bb7c652bc678c52e9969fda",
+ "src\\view\\config\\menu\\factoryTestView.js": "9588321c8282257e9707ebedb5920cda",
+ "src\\view\\config\\menu\\helpView.js": "00e750b2b637dc318f75e840d901fb5c",
+ "src\\view\\config\\menu\\localUser\\faceEnterView.js": "d993d07711e15cf5f0fee01a22753bfa",
+ "src\\view\\config\\menu\\localUser\\localUserAddView.js": "bf4646521acd0e14832eb732bc424e77",
+ "src\\view\\config\\menu\\localUserView.js": "c870b92aaaec5aff368e07e9f254e8aa",
+ "src\\view\\config\\menu\\networkSettingView.js": "325d70ed8ab1e170ffc1fa03fff637f5",
+ "src\\view\\config\\menu\\recordQuery\\recordQueryDetailView.js": "7077207b15bf1d7eae3a9a01dc68dc77",
+ "src\\view\\config\\menu\\recordQueryView.js": "67b573825af0639a4103bdc97b0f2c4a",
+ "src\\view\\config\\menu\\systemSetting\\displaySettingView.js": "c57f3b9faf85e048864c08d592481a72",
+ "src\\view\\config\\menu\\systemSetting\\faceRecognitionSettingView.js": "4d6b4e8b6c0f6e0ccbaaaa169e65b780",
+ "src\\view\\config\\menu\\systemSetting\\passLogSettingView.js": "d51958ac39b104846586b1ed6590414c",
+ "src\\view\\config\\menu\\systemSetting\\passwordManagementView.js": "98a6ca138cc1e2bc33ff6a3248e11263",
+ "src\\view\\config\\menu\\systemSetting\\passwordOpenDoorSettingView.js": "6e2ab3793e6c569097b702c339ef1602",
+ "src\\view\\config\\menu\\systemSetting\\swipeCardRecognitionSettingView.js": "871b483fbc3d778df95b803c130101e1",
+ "src\\view\\config\\menu\\systemSetting\\timeSettingView.js": "6950faa3a3296a573d048eb782c0e6ca",
+ "src\\view\\config\\menu\\systemSettingView.js": "ca3ac7b0e0390c7d542b62d569f57b24",
+ "src\\view\\config\\menu\\voiceBroadcastView.js": "a809af8acdae03f15c6e677bef6f20a1",
+ "src\\view\\config\\newPwdView.js": "32e3cfb0cc7f88361f1c69797cdb14b8",
+ "src\\view\\emergencyPwdView.js": "c6413bc04d38d54e57f590ce44204bcb",
+ "src\\view\\i18n.js": "94f43798d35026189125bf2534d1bffd",
+ "src\\view\\idleView.js": "b95c100ae4b2757ea2b0844a3df35c9e",
+ "src\\view\\mainView.js": "ec96a69994b99ed36778338198f74765",
+ "src\\view\\pinyin\\dict.js": "e40764bfc6bab80119c584315c0c48b7",
+ "src\\view\\pinyin\\pinyin.js": "c0809d9d1ebe5937cb6831b2b70db439",
+ "src\\view\\pwdView.js": "226b8b83a13b82cc925519ae051f8b3f",
+ "src\\view\\topView.js": "c9d8a4e3bc362edb1a5007135323beea",
+ "src\\view\\viewUtils.js": "ceaaad4fb40024b448a66a03911a7279",
+ "src\\worker\\accessWorker.js": "1b1253b5a7fbb2e733be2a9b0714ecca",
+ "src\\worker\\httpWorker.js": "47ddc63bdd95ecf36f7eaaa5f409424c"
+}
\ No newline at end of file
diff --git a/vf205_access/.temp/zipFolder/VF105_V12/dxAlsa/1.0.0.zip b/vf205_access/.temp/zipFolder/VF105_V12/dxAlsa/1.0.0.zip
new file mode 100644
index 0000000..71b6970
--- /dev/null
+++ b/vf205_access/.temp/zipFolder/VF105_V12/dxAlsa/1.0.0.zip
Binary files differ
diff --git a/vf205_access/.temp/zipFolder/VF105_V12/dxAudio/1.0.1.zip b/vf205_access/.temp/zipFolder/VF105_V12/dxAudio/1.0.1.zip
new file mode 100644
index 0000000..bedd38f
--- /dev/null
+++ b/vf205_access/.temp/zipFolder/VF105_V12/dxAudio/1.0.1.zip
Binary files differ
diff --git a/vf205_access/.temp/zipFolder/VF105_V12/dxAudio/2.0.0.zip b/vf205_access/.temp/zipFolder/VF105_V12/dxAudio/2.0.0.zip
new file mode 100644
index 0000000..5e10702
--- /dev/null
+++ b/vf205_access/.temp/zipFolder/VF105_V12/dxAudio/2.0.0.zip
Binary files differ
diff --git a/vf205_access/.temp/zipFolder/VF105_V12/dxBase64/1.0.0.zip b/vf205_access/.temp/zipFolder/VF105_V12/dxBase64/1.0.0.zip
new file mode 100644
index 0000000..633273c
--- /dev/null
+++ b/vf205_access/.temp/zipFolder/VF105_V12/dxBase64/1.0.0.zip
Binary files differ
diff --git a/vf205_access/.temp/zipFolder/VF105_V12/dxBase64/2.0.0.zip b/vf205_access/.temp/zipFolder/VF105_V12/dxBase64/2.0.0.zip
new file mode 100644
index 0000000..633273c
--- /dev/null
+++ b/vf205_access/.temp/zipFolder/VF105_V12/dxBase64/2.0.0.zip
Binary files differ
diff --git a/vf205_access/.temp/zipFolder/VF105_V12/dxCameraCalibration/1.0.0.zip b/vf205_access/.temp/zipFolder/VF105_V12/dxCameraCalibration/1.0.0.zip
new file mode 100644
index 0000000..814f496
--- /dev/null
+++ b/vf205_access/.temp/zipFolder/VF105_V12/dxCameraCalibration/1.0.0.zip
Binary files differ
diff --git a/vf205_access/.temp/zipFolder/VF105_V12/dxCameraCalibration/test.zip b/vf205_access/.temp/zipFolder/VF105_V12/dxCameraCalibration/test.zip
new file mode 100644
index 0000000..974da4e
--- /dev/null
+++ b/vf205_access/.temp/zipFolder/VF105_V12/dxCameraCalibration/test.zip
Binary files differ
diff --git a/vf205_access/.temp/zipFolder/VF105_V12/dxCapturer/1.0.0.zip b/vf205_access/.temp/zipFolder/VF105_V12/dxCapturer/1.0.0.zip
new file mode 100644
index 0000000..e727818
--- /dev/null
+++ b/vf205_access/.temp/zipFolder/VF105_V12/dxCapturer/1.0.0.zip
Binary files differ
diff --git a/vf205_access/.temp/zipFolder/VF105_V12/dxCapturer/1.0.1.zip b/vf205_access/.temp/zipFolder/VF105_V12/dxCapturer/1.0.1.zip
new file mode 100644
index 0000000..809e931
--- /dev/null
+++ b/vf205_access/.temp/zipFolder/VF105_V12/dxCapturer/1.0.1.zip
Binary files differ
diff --git a/vf205_access/.temp/zipFolder/VF105_V12/dxCapturer/1.0.2.zip b/vf205_access/.temp/zipFolder/VF105_V12/dxCapturer/1.0.2.zip
new file mode 100644
index 0000000..e2a4d0d
--- /dev/null
+++ b/vf205_access/.temp/zipFolder/VF105_V12/dxCapturer/1.0.2.zip
Binary files differ
diff --git a/vf205_access/.temp/zipFolder/VF105_V12/dxCapturer/1.0.3.zip b/vf205_access/.temp/zipFolder/VF105_V12/dxCapturer/1.0.3.zip
new file mode 100644
index 0000000..3460d10
--- /dev/null
+++ b/vf205_access/.temp/zipFolder/VF105_V12/dxCapturer/1.0.3.zip
Binary files differ
diff --git a/vf205_access/.temp/zipFolder/VF105_V12/dxCommon/1.0.0.zip b/vf205_access/.temp/zipFolder/VF105_V12/dxCommon/1.0.0.zip
new file mode 100644
index 0000000..ce067d5
--- /dev/null
+++ b/vf205_access/.temp/zipFolder/VF105_V12/dxCommon/1.0.0.zip
Binary files differ
diff --git a/vf205_access/.temp/zipFolder/VF105_V12/dxCommon/1.0.1.zip b/vf205_access/.temp/zipFolder/VF105_V12/dxCommon/1.0.1.zip
new file mode 100644
index 0000000..0efae86
--- /dev/null
+++ b/vf205_access/.temp/zipFolder/VF105_V12/dxCommon/1.0.1.zip
Binary files differ
diff --git a/vf205_access/.temp/zipFolder/VF105_V12/dxCommonUtils/1.0.1.zip b/vf205_access/.temp/zipFolder/VF105_V12/dxCommonUtils/1.0.1.zip
new file mode 100644
index 0000000..e8e15f9
--- /dev/null
+++ b/vf205_access/.temp/zipFolder/VF105_V12/dxCommonUtils/1.0.1.zip
Binary files differ
diff --git a/vf205_access/.temp/zipFolder/VF105_V12/dxConfig/2.0.0.zip b/vf205_access/.temp/zipFolder/VF105_V12/dxConfig/2.0.0.zip
new file mode 100644
index 0000000..066e3c8
--- /dev/null
+++ b/vf205_access/.temp/zipFolder/VF105_V12/dxConfig/2.0.0.zip
Binary files differ
diff --git a/vf205_access/.temp/zipFolder/VF105_V12/dxCryptoES/2.0.0.zip b/vf205_access/.temp/zipFolder/VF105_V12/dxCryptoES/2.0.0.zip
new file mode 100644
index 0000000..cefaedd
--- /dev/null
+++ b/vf205_access/.temp/zipFolder/VF105_V12/dxCryptoES/2.0.0.zip
Binary files differ
diff --git a/vf205_access/.temp/zipFolder/VF105_V12/dxDisplay/1.0.0.zip b/vf205_access/.temp/zipFolder/VF105_V12/dxDisplay/1.0.0.zip
new file mode 100644
index 0000000..de43995
--- /dev/null
+++ b/vf205_access/.temp/zipFolder/VF105_V12/dxDisplay/1.0.0.zip
Binary files differ
diff --git a/vf205_access/.temp/zipFolder/VF105_V12/dxDisplay/2.0.0.zip b/vf205_access/.temp/zipFolder/VF105_V12/dxDisplay/2.0.0.zip
new file mode 100644
index 0000000..e25dc30
--- /dev/null
+++ b/vf205_access/.temp/zipFolder/VF105_V12/dxDisplay/2.0.0.zip
Binary files differ
diff --git a/vf205_access/.temp/zipFolder/VF105_V12/dxDriver/1.1.0.zip b/vf205_access/.temp/zipFolder/VF105_V12/dxDriver/1.1.0.zip
new file mode 100644
index 0000000..b495407
--- /dev/null
+++ b/vf205_access/.temp/zipFolder/VF105_V12/dxDriver/1.1.0.zip
Binary files differ
diff --git a/vf205_access/.temp/zipFolder/VF105_V12/dxDriver/1.1.4.zip b/vf205_access/.temp/zipFolder/VF105_V12/dxDriver/1.1.4.zip
new file mode 100644
index 0000000..de46bf0
--- /dev/null
+++ b/vf205_access/.temp/zipFolder/VF105_V12/dxDriver/1.1.4.zip
Binary files differ
diff --git a/vf205_access/.temp/zipFolder/VF105_V12/dxDriver/2.0.0.zip b/vf205_access/.temp/zipFolder/VF105_V12/dxDriver/2.0.0.zip
new file mode 100644
index 0000000..341100e
--- /dev/null
+++ b/vf205_access/.temp/zipFolder/VF105_V12/dxDriver/2.0.0.zip
Binary files differ
diff --git a/vf205_access/.temp/zipFolder/VF105_V12/dxEid/1.0.0.zip b/vf205_access/.temp/zipFolder/VF105_V12/dxEid/1.0.0.zip
new file mode 100644
index 0000000..14140bd
--- /dev/null
+++ b/vf205_access/.temp/zipFolder/VF105_V12/dxEid/1.0.0.zip
Binary files differ
diff --git a/vf205_access/.temp/zipFolder/VF105_V12/dxEventBus/2.0.0.zip b/vf205_access/.temp/zipFolder/VF105_V12/dxEventBus/2.0.0.zip
new file mode 100644
index 0000000..6c3a0fd
--- /dev/null
+++ b/vf205_access/.temp/zipFolder/VF105_V12/dxEventBus/2.0.0.zip
Binary files differ
diff --git a/vf205_access/.temp/zipFolder/VF105_V12/dxEventBus/2.0.2.zip b/vf205_access/.temp/zipFolder/VF105_V12/dxEventBus/2.0.2.zip
new file mode 100644
index 0000000..408f14c
--- /dev/null
+++ b/vf205_access/.temp/zipFolder/VF105_V12/dxEventBus/2.0.2.zip
Binary files differ
diff --git a/vf205_access/.temp/zipFolder/VF105_V12/dxEventBus/2.0.3.zip b/vf205_access/.temp/zipFolder/VF105_V12/dxEventBus/2.0.3.zip
new file mode 100644
index 0000000..d7b3c50
--- /dev/null
+++ b/vf205_access/.temp/zipFolder/VF105_V12/dxEventBus/2.0.3.zip
Binary files differ
diff --git a/vf205_access/.temp/zipFolder/VF105_V12/dxFace/1.1.8.zip b/vf205_access/.temp/zipFolder/VF105_V12/dxFace/1.1.8.zip
new file mode 100644
index 0000000..8e5d0e3
--- /dev/null
+++ b/vf205_access/.temp/zipFolder/VF105_V12/dxFace/1.1.8.zip
Binary files differ
diff --git a/vf205_access/.temp/zipFolder/VF105_V12/dxFacial/1.0.0.zip b/vf205_access/.temp/zipFolder/VF105_V12/dxFacial/1.0.0.zip
new file mode 100644
index 0000000..4862fe6
--- /dev/null
+++ b/vf205_access/.temp/zipFolder/VF105_V12/dxFacial/1.0.0.zip
Binary files differ
diff --git a/vf205_access/.temp/zipFolder/VF105_V12/dxGpio/1.0.0.zip b/vf205_access/.temp/zipFolder/VF105_V12/dxGpio/1.0.0.zip
new file mode 100644
index 0000000..5c31150
--- /dev/null
+++ b/vf205_access/.temp/zipFolder/VF105_V12/dxGpio/1.0.0.zip
Binary files differ
diff --git a/vf205_access/.temp/zipFolder/VF105_V12/dxGpioKey/1.0.0.zip b/vf205_access/.temp/zipFolder/VF105_V12/dxGpioKey/1.0.0.zip
new file mode 100644
index 0000000..d85fc45
--- /dev/null
+++ b/vf205_access/.temp/zipFolder/VF105_V12/dxGpioKey/1.0.0.zip
Binary files differ
diff --git a/vf205_access/.temp/zipFolder/VF105_V12/dxGpioKey/1.0.1.zip b/vf205_access/.temp/zipFolder/VF105_V12/dxGpioKey/1.0.1.zip
new file mode 100644
index 0000000..3037e37
--- /dev/null
+++ b/vf205_access/.temp/zipFolder/VF105_V12/dxGpioKey/1.0.1.zip
Binary files differ
diff --git a/vf205_access/.temp/zipFolder/VF105_V12/dxHttp/1.0.0.zip b/vf205_access/.temp/zipFolder/VF105_V12/dxHttp/1.0.0.zip
new file mode 100644
index 0000000..3420ede
--- /dev/null
+++ b/vf205_access/.temp/zipFolder/VF105_V12/dxHttp/1.0.0.zip
Binary files differ
diff --git a/vf205_access/.temp/zipFolder/VF105_V12/dxHttpClient/2.0.3.zip b/vf205_access/.temp/zipFolder/VF105_V12/dxHttpClient/2.0.3.zip
new file mode 100644
index 0000000..9b7112f
--- /dev/null
+++ b/vf205_access/.temp/zipFolder/VF105_V12/dxHttpClient/2.0.3.zip
Binary files differ
diff --git a/vf205_access/.temp/zipFolder/VF105_V12/dxHttpClient/2.0.4.zip b/vf205_access/.temp/zipFolder/VF105_V12/dxHttpClient/2.0.4.zip
new file mode 100644
index 0000000..511e164
--- /dev/null
+++ b/vf205_access/.temp/zipFolder/VF105_V12/dxHttpClient/2.0.4.zip
Binary files differ
diff --git a/vf205_access/.temp/zipFolder/VF105_V12/dxHttpServer/1.0.1.zip b/vf205_access/.temp/zipFolder/VF105_V12/dxHttpServer/1.0.1.zip
new file mode 100644
index 0000000..90c429e
--- /dev/null
+++ b/vf205_access/.temp/zipFolder/VF105_V12/dxHttpServer/1.0.1.zip
Binary files differ
diff --git a/vf205_access/.temp/zipFolder/VF105_V12/dxHttpServer/1.0.5.zip b/vf205_access/.temp/zipFolder/VF105_V12/dxHttpServer/1.0.5.zip
new file mode 100644
index 0000000..c128e69
--- /dev/null
+++ b/vf205_access/.temp/zipFolder/VF105_V12/dxHttpServer/1.0.5.zip
Binary files differ
diff --git a/vf205_access/.temp/zipFolder/VF105_V12/dxLogger/2.0.0.zip b/vf205_access/.temp/zipFolder/VF105_V12/dxLogger/2.0.0.zip
new file mode 100644
index 0000000..c1f6d3e
--- /dev/null
+++ b/vf205_access/.temp/zipFolder/VF105_V12/dxLogger/2.0.0.zip
Binary files differ
diff --git a/vf205_access/.temp/zipFolder/VF105_V12/dxLogger/2.0.3.zip b/vf205_access/.temp/zipFolder/VF105_V12/dxLogger/2.0.3.zip
new file mode 100644
index 0000000..9eb380e
--- /dev/null
+++ b/vf205_access/.temp/zipFolder/VF105_V12/dxLogger/2.0.3.zip
Binary files differ
diff --git a/vf205_access/.temp/zipFolder/VF105_V12/dxMap/1.0.0.zip b/vf205_access/.temp/zipFolder/VF105_V12/dxMap/1.0.0.zip
new file mode 100644
index 0000000..0e44130
--- /dev/null
+++ b/vf205_access/.temp/zipFolder/VF105_V12/dxMap/1.0.0.zip
Binary files differ
diff --git a/vf205_access/.temp/zipFolder/VF105_V12/dxMap/2.0.1.zip b/vf205_access/.temp/zipFolder/VF105_V12/dxMap/2.0.1.zip
new file mode 100644
index 0000000..2294988
--- /dev/null
+++ b/vf205_access/.temp/zipFolder/VF105_V12/dxMap/2.0.1.zip
Binary files differ
diff --git a/vf205_access/.temp/zipFolder/VF105_V12/dxMqtt/1.0.1.zip b/vf205_access/.temp/zipFolder/VF105_V12/dxMqtt/1.0.1.zip
new file mode 100644
index 0000000..b59864e
--- /dev/null
+++ b/vf205_access/.temp/zipFolder/VF105_V12/dxMqtt/1.0.1.zip
Binary files differ
diff --git a/vf205_access/.temp/zipFolder/VF105_V12/dxMqttClient/1.0.1.zip b/vf205_access/.temp/zipFolder/VF105_V12/dxMqttClient/1.0.1.zip
new file mode 100644
index 0000000..5fdd302
--- /dev/null
+++ b/vf205_access/.temp/zipFolder/VF105_V12/dxMqttClient/1.0.1.zip
Binary files differ
diff --git a/vf205_access/.temp/zipFolder/VF105_V12/dxNet/1.0.0.zip b/vf205_access/.temp/zipFolder/VF105_V12/dxNet/1.0.0.zip
new file mode 100644
index 0000000..4406132
--- /dev/null
+++ b/vf205_access/.temp/zipFolder/VF105_V12/dxNet/1.0.0.zip
Binary files differ
diff --git a/vf205_access/.temp/zipFolder/VF105_V12/dxNet/1.0.2.zip b/vf205_access/.temp/zipFolder/VF105_V12/dxNet/1.0.2.zip
new file mode 100644
index 0000000..84d2120
--- /dev/null
+++ b/vf205_access/.temp/zipFolder/VF105_V12/dxNet/1.0.2.zip
Binary files differ
diff --git a/vf205_access/.temp/zipFolder/VF105_V12/dxNetwork/1.0.0.zip b/vf205_access/.temp/zipFolder/VF105_V12/dxNetwork/1.0.0.zip
new file mode 100644
index 0000000..5b68fe0
--- /dev/null
+++ b/vf205_access/.temp/zipFolder/VF105_V12/dxNetwork/1.0.0.zip
Binary files differ
diff --git a/vf205_access/.temp/zipFolder/VF105_V12/dxNfc/1.0.0.zip b/vf205_access/.temp/zipFolder/VF105_V12/dxNfc/1.0.0.zip
new file mode 100644
index 0000000..c7ea2de
--- /dev/null
+++ b/vf205_access/.temp/zipFolder/VF105_V12/dxNfc/1.0.0.zip
Binary files differ
diff --git a/vf205_access/.temp/zipFolder/VF105_V12/dxNfcCard/1.0.0.zip b/vf205_access/.temp/zipFolder/VF105_V12/dxNfcCard/1.0.0.zip
new file mode 100644
index 0000000..4145a05
--- /dev/null
+++ b/vf205_access/.temp/zipFolder/VF105_V12/dxNfcCard/1.0.0.zip
Binary files differ
diff --git a/vf205_access/.temp/zipFolder/VF105_V12/dxNfcCard/1.0.1.zip b/vf205_access/.temp/zipFolder/VF105_V12/dxNfcCard/1.0.1.zip
new file mode 100644
index 0000000..46c4fb9
--- /dev/null
+++ b/vf205_access/.temp/zipFolder/VF105_V12/dxNfcCard/1.0.1.zip
Binary files differ
diff --git a/vf205_access/.temp/zipFolder/VF105_V12/dxNtp/2.0.0.zip b/vf205_access/.temp/zipFolder/VF105_V12/dxNtp/2.0.0.zip
new file mode 100644
index 0000000..122d16d
--- /dev/null
+++ b/vf205_access/.temp/zipFolder/VF105_V12/dxNtp/2.0.0.zip
Binary files differ
diff --git a/vf205_access/.temp/zipFolder/VF105_V12/dxNtp/2.0.2.zip b/vf205_access/.temp/zipFolder/VF105_V12/dxNtp/2.0.2.zip
new file mode 100644
index 0000000..b4dbb22
--- /dev/null
+++ b/vf205_access/.temp/zipFolder/VF105_V12/dxNtp/2.0.2.zip
Binary files differ
diff --git a/vf205_access/.temp/zipFolder/VF105_V12/dxNtp/2.0.3.zip b/vf205_access/.temp/zipFolder/VF105_V12/dxNtp/2.0.3.zip
new file mode 100644
index 0000000..0d5693c
--- /dev/null
+++ b/vf205_access/.temp/zipFolder/VF105_V12/dxNtp/2.0.3.zip
Binary files differ
diff --git a/vf205_access/.temp/zipFolder/VF105_V12/dxOs/1.0.0.zip b/vf205_access/.temp/zipFolder/VF105_V12/dxOs/1.0.0.zip
new file mode 100644
index 0000000..63b21be
--- /dev/null
+++ b/vf205_access/.temp/zipFolder/VF105_V12/dxOs/1.0.0.zip
Binary files differ
diff --git a/vf205_access/.temp/zipFolder/VF105_V12/dxOta/1.0.0.zip b/vf205_access/.temp/zipFolder/VF105_V12/dxOta/1.0.0.zip
new file mode 100644
index 0000000..a746838
--- /dev/null
+++ b/vf205_access/.temp/zipFolder/VF105_V12/dxOta/1.0.0.zip
Binary files differ
diff --git a/vf205_access/.temp/zipFolder/VF105_V12/dxOta/2.0.2.zip b/vf205_access/.temp/zipFolder/VF105_V12/dxOta/2.0.2.zip
new file mode 100644
index 0000000..69e3e43
--- /dev/null
+++ b/vf205_access/.temp/zipFolder/VF105_V12/dxOta/2.0.2.zip
Binary files differ
diff --git a/vf205_access/.temp/zipFolder/VF105_V12/dxPwm/1.0.0.zip b/vf205_access/.temp/zipFolder/VF105_V12/dxPwm/1.0.0.zip
new file mode 100644
index 0000000..8060516
--- /dev/null
+++ b/vf205_access/.temp/zipFolder/VF105_V12/dxPwm/1.0.0.zip
Binary files differ
diff --git a/vf205_access/.temp/zipFolder/VF105_V12/dxPwm/2.0.0.zip b/vf205_access/.temp/zipFolder/VF105_V12/dxPwm/2.0.0.zip
new file mode 100644
index 0000000..8cc1c22
--- /dev/null
+++ b/vf205_access/.temp/zipFolder/VF105_V12/dxPwm/2.0.0.zip
Binary files differ
diff --git a/vf205_access/.temp/zipFolder/VF105_V12/dxPwm/2.0.1.zip b/vf205_access/.temp/zipFolder/VF105_V12/dxPwm/2.0.1.zip
new file mode 100644
index 0000000..eda71da
--- /dev/null
+++ b/vf205_access/.temp/zipFolder/VF105_V12/dxPwm/2.0.1.zip
Binary files differ
diff --git a/vf205_access/.temp/zipFolder/VF105_V12/dxQrRule/1.0.0.zip b/vf205_access/.temp/zipFolder/VF105_V12/dxQrRule/1.0.0.zip
new file mode 100644
index 0000000..b422640
--- /dev/null
+++ b/vf205_access/.temp/zipFolder/VF105_V12/dxQrRule/1.0.0.zip
Binary files differ
diff --git a/vf205_access/.temp/zipFolder/VF105_V12/dxSqlite/1.0.0.zip b/vf205_access/.temp/zipFolder/VF105_V12/dxSqlite/1.0.0.zip
new file mode 100644
index 0000000..6abf592
--- /dev/null
+++ b/vf205_access/.temp/zipFolder/VF105_V12/dxSqlite/1.0.0.zip
Binary files differ
diff --git a/vf205_access/.temp/zipFolder/VF105_V12/dxSqlite/2.0.0.zip b/vf205_access/.temp/zipFolder/VF105_V12/dxSqlite/2.0.0.zip
new file mode 100644
index 0000000..3114c72
--- /dev/null
+++ b/vf205_access/.temp/zipFolder/VF105_V12/dxSqlite/2.0.0.zip
Binary files differ
diff --git a/vf205_access/.temp/zipFolder/VF105_V12/dxSqliteDB/1.0.0.zip b/vf205_access/.temp/zipFolder/VF105_V12/dxSqliteDB/1.0.0.zip
new file mode 100644
index 0000000..a5085b0
--- /dev/null
+++ b/vf205_access/.temp/zipFolder/VF105_V12/dxSqliteDB/1.0.0.zip
Binary files differ
diff --git a/vf205_access/.temp/zipFolder/VF105_V12/dxStd/1.0.0.zip b/vf205_access/.temp/zipFolder/VF105_V12/dxStd/1.0.0.zip
new file mode 100644
index 0000000..d7aa3d4
--- /dev/null
+++ b/vf205_access/.temp/zipFolder/VF105_V12/dxStd/1.0.0.zip
Binary files differ
diff --git a/vf205_access/.temp/zipFolder/VF105_V12/dxStd/2.0.3.zip b/vf205_access/.temp/zipFolder/VF105_V12/dxStd/2.0.3.zip
new file mode 100644
index 0000000..3a1533e
--- /dev/null
+++ b/vf205_access/.temp/zipFolder/VF105_V12/dxStd/2.0.3.zip
Binary files differ
diff --git a/vf205_access/.temp/zipFolder/VF105_V12/dxUart/1.0.0.zip b/vf205_access/.temp/zipFolder/VF105_V12/dxUart/1.0.0.zip
new file mode 100644
index 0000000..3a080cb
--- /dev/null
+++ b/vf205_access/.temp/zipFolder/VF105_V12/dxUart/1.0.0.zip
Binary files differ
diff --git a/vf205_access/.temp/zipFolder/VF105_V12/dxUi/1.0.2.zip b/vf205_access/.temp/zipFolder/VF105_V12/dxUi/1.0.2.zip
new file mode 100644
index 0000000..a6e8753
--- /dev/null
+++ b/vf205_access/.temp/zipFolder/VF105_V12/dxUi/1.0.2.zip
Binary files differ
diff --git a/vf205_access/.temp/zipFolder/VF105_V12/dxWatchdog/1.0.0.zip b/vf205_access/.temp/zipFolder/VF105_V12/dxWatchdog/1.0.0.zip
new file mode 100644
index 0000000..e96c77a
--- /dev/null
+++ b/vf205_access/.temp/zipFolder/VF105_V12/dxWatchdog/1.0.0.zip
Binary files differ
diff --git a/vf205_access/.temp/zipFolder/VF105_V12/dxWatchdog/1.0.1.zip b/vf205_access/.temp/zipFolder/VF105_V12/dxWatchdog/1.0.1.zip
new file mode 100644
index 0000000..3d5f91d
--- /dev/null
+++ b/vf205_access/.temp/zipFolder/VF105_V12/dxWatchdog/1.0.1.zip
Binary files differ
diff --git a/vf205_access/.temp/zipFolder/VF105_V12/dxWorkerPool/2.0.0.zip b/vf205_access/.temp/zipFolder/VF105_V12/dxWorkerPool/2.0.0.zip
new file mode 100644
index 0000000..cd1a5be
--- /dev/null
+++ b/vf205_access/.temp/zipFolder/VF105_V12/dxWorkerPool/2.0.0.zip
Binary files differ
diff --git a/vf205_access/.temp/zipFolder/VF105_V12/dxWorkerPool/2.0.1.zip b/vf205_access/.temp/zipFolder/VF105_V12/dxWorkerPool/2.0.1.zip
new file mode 100644
index 0000000..c14f35a
--- /dev/null
+++ b/vf205_access/.temp/zipFolder/VF105_V12/dxWorkerPool/2.0.1.zip
Binary files differ
diff --git a/vf205_access/README.md b/vf205_access/README.md
new file mode 100644
index 0000000..562b2bd
--- /dev/null
+++ b/vf205_access/README.md
@@ -0,0 +1,9 @@
+# vf105_v12_access_new Access Control Application Source Code
+
+This directory contains the JavaScript source code for the `vf105_v12_access_new` access control application.
+
+**Important Note:**
+
+The JavaScript source code in this project is identical to the one used in the `vf203_v12_access_new` project (located at `../../vf203_v12/vf203_v12_access_new`).
+
+The only difference between the two projects lies in the underlying native shared library (`.so`) files. The specific version of the `.so` files to be used is determined and configured by the `app.dxproj` project file.
diff --git a/vf205_access/README_CN.md b/vf205_access/README_CN.md
new file mode 100644
index 0000000..d821497
--- /dev/null
+++ b/vf205_access/README_CN.md
@@ -0,0 +1,19 @@
+# vf105_v12_access_new 闂ㄧ搴旂敤婧愮爜
+
+姝ょ洰褰曞寘鍚� `vf105_v12_access_new` 闂ㄧ搴旂敤鐨� JavaScript 婧愮爜銆�
+
+**閲嶈璇存槑锛�**
+
+鏈」鐩殑 JavaScript 婧愮爜涓� `vf203_v12_access_new` 椤圭洰锛堣矾寰勶細`../../vf203_v12/vf203_v12_access_new`锛変娇鐢ㄧ殑鏄畬鍏ㄧ浉鍚岀殑涓�濂楁簮鐮併��
+
+涓や釜椤圭洰鍞竴鐨勫樊鍒湪浜庡簳灞傜殑鍘熺敓鍏变韩搴擄紙`.so`锛夋枃浠躲�傚叿浣撲娇鐢ㄥ摢涓増鏈殑 `.so` 鏂囦欢锛屾槸閫氳繃 `app.dxproj` 椤圭洰鏂囦欢鏉ュ尯鍒嗗拰閰嶇疆鐨勩��
+
+---
+
+褰撳墠椤圭洰宸蹭慨鏀规ā缁勬枃浠�-dxmodules/dxEventBus.js锛屼娇浜嬩欢鎬荤嚎鏀寔澶氫釜浜嬩欢澶勭悊鍑芥暟锛�
+
+1. 淇敼 bus.on 鍑芥暟 锛氬皢鍗曚釜浜嬩欢澶勭悊鍑芥暟鏀逛负瀛樺偍涓烘暟缁勶紝鏀寔澶氫釜澶勭悊鍑芥暟
+2. 淇敼 bus.fire 鍑芥暟 锛氭墽琛屾墍鏈夋敞鍐岀殑浜嬩欢澶勭悊鍑芥暟锛岃�屼笉浠呬粎鏄渶鍚庝竴涓�
+3. 娣诲姞閿欒澶勭悊 锛氱‘淇濅竴涓簨浠跺鐞嗗嚱鏁板嚭閿欐椂涓嶄細褰卞搷鍏朵粬澶勭悊鍑芥暟鐨勬墽琛�
+
+---
diff --git a/vf205_access/app.dxproj b/vf205_access/app.dxproj
new file mode 100644
index 0000000..0e18c5a
--- /dev/null
+++ b/vf205_access/app.dxproj
@@ -0,0 +1,123 @@
+{
+ "name": "vf105_v12_access",
+ "model": "VF105_V12",
+ "components": [
+ {
+ "component": "dxAlsa",
+ "version": "1.0.0"
+ },
+ {
+ "component": "dxBase64",
+ "version": "1.0.0"
+ },
+ {
+ "component": "dxCapturer",
+ "version": "1.0.2"
+ },
+ {
+ "component": "dxCommon",
+ "version": "1.0.0"
+ },
+ {
+ "component": "dxConfig",
+ "version": "2.0.0"
+ },
+ {
+ "component": "dxCameraCalibration",
+ "version": "test"
+ },
+ {
+ "component": "dxDriver",
+ "version": "1.1.0"
+ },
+ {
+ "component": "dxEventBus",
+ "version": "2.0.0"
+ },
+ {
+ "component": "dxEid",
+ "version": "1.0.0"
+ },
+ {
+ "component": "dxFace",
+ "version": "1.1.8"
+ },
+ {
+ "component": "dxGpio",
+ "version": "1.0.0"
+ },
+ {
+ "component": "dxGpioKey",
+ "version": "1.0.0"
+ },
+ {
+ "component": "dxHttp",
+ "version": "1.0.0"
+ },
+ {
+ "component": "dxLogger",
+ "version": "2.0.0"
+ },
+ {
+ "component": "dxMap",
+ "version": "1.0.0"
+ },
+ {
+ "component": "dxMqtt",
+ "version": "1.0.1"
+ },
+ {
+ "component": "dxNet",
+ "version": "1.0.0"
+ },
+ {
+ "component": "dxNtp",
+ "version": "2.0.0"
+ },
+ {
+ "component": "dxNfc",
+ "version": "1.0.0"
+ },
+ {
+ "component": "dxOta",
+ "version": "1.0.0"
+ },
+ {
+ "component": "dxPwm",
+ "version": "1.0.0"
+ },
+ {
+ "component": "dxQrRule",
+ "version": "1.0.0"
+ },
+ {
+ "component": "dxStd",
+ "version": "1.0.0"
+ },
+ {
+ "component": "dxSqlite",
+ "version": "1.0.0"
+ },
+ {
+ "component": "dxUi",
+ "version": "1.0.2"
+ },
+ {
+ "component": "dxUart",
+ "version": "1.0.0"
+ },
+ {
+ "component": "dxWorkerPool",
+ "version": "2.0.0"
+ },
+ {
+ "component": "dxWatchdog",
+ "version": "1.0.0"
+ }
+ ],
+ "ignore": {
+ "folder": ".temp,.git",
+ "file": "md5s.json,md5snew.json"
+ },
+ "version": "2.0.1.0"
+}
\ No newline at end of file
diff --git a/vf205_access/dxmodules/cameraCalibrationWorker.js b/vf205_access/dxmodules/cameraCalibrationWorker.js
new file mode 100644
index 0000000..4aaa65a
--- /dev/null
+++ b/vf205_access/dxmodules/cameraCalibrationWorker.js
@@ -0,0 +1,57 @@
+//build:20240524
+//鐢ㄤ簬绠�鍖朿ameraCalibration缁勪欢鐨勪娇鐢紝鎶奵ameraCalibration灏佽鍦ㄨ繖涓獁orker閲岋紝浣跨敤鑰呭彧闇�瑕佽闃卐ventcenter鐨勪簨浠跺氨鍙互鐩戝惉cameraCalibration
+import log from './dxLogger.js'
+import cameraCalibration from './dxCameraCalibration.js'
+import capturer from './dxCapturer.js'
+import std from './dxStd.js'
+import bus from './dxEventBus.js'
+import dxMap from './dxMap.js'
+import * as os from "os";
+const map = dxMap.get('default')
+const options = map.get("__cameraCalibration__run_init")
+
+function run() {
+ cameraCalibration.init()
+ log.info('cameraCalibration start......')
+ let startTime = new Date().getTime()
+ let cnt = 0
+ let timerId = std.setInterval(() => {
+ try {
+ let imageRgb = capturer.readImage(options.capturerRgbId)
+ let imageNir = capturer.readImage(options.capturerNirId)
+ let res = cameraCalibration.calibrationFromImage(imageRgb, imageNir, cnt)
+ if (res) {
+ if (cnt >= 1) {
+ log.info("涓ゆ鏍囧畾鎴愬姛锛岀粨鏉熸爣瀹�")
+ cameraCalibration.getMap(imageRgb, imageNir, cnt, "/app/path.txt")
+ bus.fire(cameraCalibration.RECEIVE_MSG, "success1")
+ capturer.destroyImage(imageRgb)
+ capturer.destroyImage(imageNir)
+ std.clearInterval(timerId)
+ }
+ log.info("绗�" + (cnt + 1) + "娆℃爣瀹氭垚鍔�")
+ bus.fire(cameraCalibration.RECEIVE_MSG, "success0")
+ cnt += 1
+ log.info("寮�濮嬭繘琛岀" + (cnt + 1) + "娆℃爣瀹�")
+ } else {
+ log.error("绗�" + (cnt + 1) + "娆℃爣瀹氬け璐ワ紝閲嶈瘯涓�")
+ }
+ capturer.destroyImage(imageRgb)
+ capturer.destroyImage(imageNir)
+ let endTime = new Date().getTime()
+ if (endTime - startTime > options.timeout * 1000) {
+ log.error('鏍囧畾瓒呮椂锛岃閲嶆柊鎵ц鏍囧畾')
+ bus.fire(cameraCalibration.RECEIVE_MSG, "timeout")
+ std.clearInterval(timerId)
+ }
+ } catch (error) {
+ log.error(error, error.stack)
+ }
+ }, 10)
+}
+
+try {
+ run()
+} catch (error) {
+ log.error(error, error.stack)
+}
\ No newline at end of file
diff --git a/vf205_access/dxmodules/capturerWorker.js b/vf205_access/dxmodules/capturerWorker.js
new file mode 100644
index 0000000..061bf6c
--- /dev/null
+++ b/vf205_access/dxmodules/capturerWorker.js
@@ -0,0 +1,27 @@
+//build:20240524
+//鐢ㄤ簬绠�鍖朿apturer缁勪欢鐨勪娇鐢紝鎶奵apturer灏佽鍦ㄨ繖涓獁orker閲岋紝浣跨敤鑰呭彧闇�瑕佽闃卐ventbus鐨勪簨浠跺氨鍙互鐩戝惉capturer
+import log from './dxLogger.js'
+import capturer from './dxCapturer.js'
+import dxMap from './dxMap.js'
+import std from './dxStd.js'
+const map = dxMap.get('default')
+const id = "{{id}}"
+const options = map.get("__capturer__run_init" + id)
+
+function run() {
+ capturer.worker.beforeLoop(options)
+ log.info('capturer start......,id =', options.id)
+ std.setInterval (function() {
+ try {
+ capturer.worker.loop(options)
+ } catch (error) {
+ log.error(error)
+ }
+ },10)
+}
+
+try {
+ run()
+} catch (error) {
+ log.error(error)
+}
\ No newline at end of file
diff --git a/vf205_access/dxmodules/dxAlsa.js b/vf205_access/dxmodules/dxAlsa.js
new file mode 100644
index 0000000..640a86a
--- /dev/null
+++ b/vf205_access/dxmodules/dxAlsa.js
@@ -0,0 +1,105 @@
+//build: 20240525
+//渚濊禆缁勪欢:dxDriver锛宒xCommon
+import { alsaClass } from './libvbar-m-dxalsa.so'
+import dxCommon from './dxCommon.js'
+const alsaObj = new alsaClass();
+const alsa = {}
+
+/**
+ * alsa 鍒濆鍖�
+ * @param {string} id 鍙ユ焺id锛岄潪蹇呭~锛堣嫢鍒濆鍖栧涓疄渚嬮渶瑕佷紶鍏ュ敮涓�id锛�
+ * @param {number} volume 闊抽噺锛岄潪蹇呭~
+ * @param {number} periodSize 鍛ㄦ湡澶у皬锛岄潪蹇呭~
+ * @param {number} bufferSize 缂撳瓨澶у皬锛岄潪蹇呭~
+ * @returns 鍙ユ焺id
+ */
+alsa.init = function (id, volume, periodSize, bufferSize) {
+ if (volume === undefined || volume === null) {
+ volume = 35
+ }
+ if (periodSize === undefined || periodSize === null) {
+ periodSize = 512
+ }
+ if (bufferSize === undefined || bufferSize === null) {
+ bufferSize = 2048
+ }
+ let pointer = alsaObj.alsaInit(volume, periodSize, bufferSize)
+ if (!pointer) {
+ throw new Error("alsa.init: init failed")
+ }
+ return dxCommon.handleId("alsa", id, pointer)
+}
+
+/**
+ * alsa 鍙栨秷鍒濆鍖�
+ * @param {string} id 鍙ユ焺id锛岄潪蹇呭~锛堥渶淇濇寔鍜宨nit涓殑id涓�鑷达級
+ * @returns true/false
+ */
+alsa.deinit = function (id) {
+ let pointer = dxCommon.handleId("alsa", id)
+ return alsaObj.alsaDeinit(pointer)
+}
+
+/**
+ * 鎾斁闊充箰鏂囦欢
+ * @param {string} path wav鏂囦欢缁濆璺緞锛岃矾寰勬槸浠�'/app/code/' 寮�澶达紝閫氬父鏀惧湪椤圭洰鐨剅esource鐩綍涓嬶紙鍜宻rc鍚岀骇)锛屽繀濉�
+ * @param {string} id 鍙ユ焺id锛岄潪蹇呭~锛堥渶淇濇寔鍜宨nit涓殑id涓�鑷达級
+ * @returns true/false
+ */
+alsa.play = function (path, id) {
+ if (!path) {
+ throw new Error("alsa.play: 'path' parameter should not be null")
+ }
+ let pointer = dxCommon.handleId("alsa", id)
+ return alsaObj.alsaWav(pointer, path)
+}
+
+/**
+ * TTS鏂囧瓧杞闊�
+ * @param {string} 瑕佹挱鏀剧殑闊抽鏂囧瓧锛屽繀濉�
+ * @param {string} id 鍙ユ焺id锛岄潪蹇呭~锛堥渶淇濇寔鍜宨nit涓殑id涓�鑷达級
+ * @returns true/false
+ */
+alsa.ttsPlay = function (str, id) {
+ if (!str) {
+ throw new Error("alsa.ttsPlay: 'str' parameter should not be null")
+ }
+ let pointer = dxCommon.handleId("alsa", id)
+ return alsaObj.alsaAudioPlayString(pointer, str)
+}
+
+/**
+ * 鑾峰彇闊抽噺
+ * @param {string} id 鍙ユ焺id锛岄潪蹇呭~锛堥渶淇濇寔鍜宨nit涓殑id涓�鑷达級
+ * @returns 杩斿洖鏁板瓧绫诲瀷鐨勯煶閲忥紝涓嶄細瓒呭嚭闊抽噺鑼冨洿
+ */
+alsa.getVolume = function (id) {
+ let pointer = dxCommon.handleId("alsa", id)
+ return alsaObj.alsaGetVolume(pointer)
+}
+
+/**
+ * 璁剧疆闊抽噺 璁剧疆杩囧ぇ鎴栬繃灏忎細缂虹渷绛変簬闊抽噺鑼冨洿鐨勬渶澶ф垨鏈�灏忓��
+ * @param {number} volume 闊抽噺锛屽繀濉�
+ * @param {string} id 鍙ユ焺id锛岄潪蹇呭~锛堥渶淇濇寔鍜宨nit涓殑id涓�鑷达級
+ * @returns true/false
+ */
+alsa.setVolume = function (volume, id) {
+ let pointer = dxCommon.handleId("alsa", id)
+ return alsaObj.alsaSetVolume(pointer, volume)
+}
+/**
+ * 鎾斁娴佸紡闊抽
+ * @param {ArrayBuffer} 闊抽娴� 锛屽繀濉�
+ * @param {string} id 鍙ユ焺id锛岄潪蹇呭~锛堥渶淇濇寔鍜宨nit涓殑id涓�鑷达級
+ * @returns true/false
+ */
+alsa.alsaWavData = function (buffer, id) {
+ if (!buffer) {
+ throw new Error("alsa.alsaWavData: 'buffer' parameter should not be null")
+ }
+ let pointer = dxCommon.handleId("alsa", id)
+ return alsaObj.alsaWavData(pointer, buffer)
+}
+
+export default alsa;
diff --git a/vf205_access/dxmodules/dxBase64.js b/vf205_access/dxmodules/dxBase64.js
new file mode 100644
index 0000000..5a7d7ec
--- /dev/null
+++ b/vf205_access/dxmodules/dxBase64.js
@@ -0,0 +1,308 @@
+//build:20240308
+//Base64缂栬В鐮佸伐鍏�
+//渚濊禆缁勪欢锛氭棤
+//鍩烘湰鍖呮嫭浠ヤ笅鍑芥暟:
+/**
+ * 1. encode(str): 瀛楃涓茶浆base64瀛楃涓诧紝姣斿Base64.encode("aa鐨勫仴搴穉ab")寰楀埌YWHnmoTlgaXlurdhYWI=
+ * 2. decode(b64): base64瀛楃涓茶浆鍘熷瓧绗︿覆
+ * 3. fromUint8Array(arr): byte鏁扮粍杞琤ase64瀛楃涓�
+ * 4. toUnit8Array(b64):base64瀛楃涓茶浆byte鏁扮粍
+ * 5. fromHexString(hex):16杩涘埗瀛楃涓诧紙灏忓啓锛屾棤绌烘牸锛夎浆base64瀛楃涓�
+ * 6. toHexString(b64):base64瀛楃涓茶浆16杩涘埗瀛楃涓诧紙灏忓啓锛屾棤绌烘牸
+ */
+/**
+ * base64.ts
+ *
+ * Licensed under the BSD 3-Clause License.
+ * http://opensource.org/licenses/BSD-3-Clause
+ *
+ * References:
+ * http://en.wikipedia.org/wiki/Base64
+ *
+ * @author Dan Kogai (https://github.com/dankogai)
+ */
+let version = '3.7.7';
+/**
+ * @deprecated use lowercase `version`.
+ */
+let VERSION = version;
+let _hasBuffer = typeof Buffer === 'function';
+let _TD = typeof TextDecoder === 'function' ? new TextDecoder() : undefined;
+let _TE = typeof TextEncoder === 'function' ? new TextEncoder() : undefined;
+let b64ch = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
+let b64chs = Array.prototype.slice.call(b64ch);
+let b64tab = (function (a) {
+ let tab = {};
+ a.forEach(function (c, i) { return tab[c] = i; });
+ return tab;
+})(b64chs);
+let b64re = /^(?:[A-Za-z\d+\/]{4})*?(?:[A-Za-z\d+\/]{2}(?:==)?|[A-Za-z\d+\/]{3}=?)?$/;
+let _fromCC = String.fromCharCode.bind(String);
+let _U8Afrom = typeof Uint8Array.from === 'function'
+ ? Uint8Array.from.bind(Uint8Array)
+ : function (it) { return new Uint8Array(Array.prototype.slice.call(it, 0)); };
+let _mkUriSafe = function (src) {
+ return src
+ .replace(/=/g, '').replace(/[+\/]/g, function (m0) { return m0 == '+' ? '-' : '_'; });
+};
+let _tidyB64 = function (s) { return s.replace(/[^A-Za-z0-9\+\/]/g, ''); };
+/**
+ * polyfill version of `btoa`
+ */
+let btoaPolyfill = function (bin) {
+ // console.log('polyfilled');
+ let u32, c0, c1, c2, asc = '';
+ let pad = bin.length % 3;
+ for (let i = 0; i < bin.length;) {
+ if ((c0 = bin.charCodeAt(i++)) > 255 ||
+ (c1 = bin.charCodeAt(i++)) > 255 ||
+ (c2 = bin.charCodeAt(i++)) > 255)
+ throw new TypeError('invalid character found');
+ u32 = (c0 << 16) | (c1 << 8) | c2;
+ asc += b64chs[u32 >> 18 & 63]
+ + b64chs[u32 >> 12 & 63]
+ + b64chs[u32 >> 6 & 63]
+ + b64chs[u32 & 63];
+ }
+ return pad ? asc.slice(0, pad - 3) + "===".substring(pad) : asc;
+};
+/**
+ * does what `window.btoa` of web browsers do.
+ * @param {String} bin binary string
+ * @returns {string} Base64-encoded string
+ */
+let _btoa = typeof btoa === 'function' ? function (bin) { return btoa(bin); }
+ : _hasBuffer ? function (bin) { return Buffer.from(bin, 'binary').toString('base64'); }
+ : btoaPolyfill;
+let _fromUint8Array = _hasBuffer
+ ? function (u8a) { return Buffer.from(u8a).toString('base64'); }
+ : function (u8a) {
+ // cf. https://stackoverflow.com/questions/12710001/how-to-convert-uint8-array-to-base64-encoded-string/12713326#12713326
+ let maxargs = 0x1000;
+ let strs = [];
+ for (let i = 0, l = u8a.length; i < l; i += maxargs) {
+ strs.push(_fromCC.apply(null, u8a.subarray(i, i + maxargs)));
+ }
+ return _btoa(strs.join(''));
+ };
+/**
+ * converts a Uint8Array to a Base64 string.
+ * @param {boolean} [urlsafe] URL-and-filename-safe a la RFC4648 搂5
+ * @returns {string} Base64 string
+ */
+let fromUint8Array = function (u8a, urlsafe) {
+ if (urlsafe === void 0) { urlsafe = false; }
+ return urlsafe ? _mkUriSafe(_fromUint8Array(u8a)) : _fromUint8Array(u8a);
+};
+let fromHexString = function (hexString) {
+ let byteString = hexString.match(/.{1,2}/g);
+ let byteArray = byteString.map(function (byte) {
+ return parseInt(byte, 16);
+ });
+ let buffer = new Uint8Array(byteArray);
+ return fromUint8Array(buffer)
+}
+// This trick is found broken https://github.com/dankogai/js-base64/issues/130
+// const utob = (src: string) => unescape(encodeURIComponent(src));
+// reverting good old fationed regexp
+let cb_utob = function (c) {
+ if (c.length < 2) {
+ let cc = c.charCodeAt(0);
+ return cc < 0x80 ? c
+ : cc < 0x800 ? (_fromCC(0xc0 | (cc >>> 6))
+ + _fromCC(0x80 | (cc & 0x3f)))
+ : (_fromCC(0xe0 | ((cc >>> 12) & 0x0f))
+ + _fromCC(0x80 | ((cc >>> 6) & 0x3f))
+ + _fromCC(0x80 | (cc & 0x3f)));
+ }
+ else {
+ let cc = 0x10000
+ + (c.charCodeAt(0) - 0xD800) * 0x400
+ + (c.charCodeAt(1) - 0xDC00);
+ return (_fromCC(0xf0 | ((cc >>> 18) & 0x07))
+ + _fromCC(0x80 | ((cc >>> 12) & 0x3f))
+ + _fromCC(0x80 | ((cc >>> 6) & 0x3f))
+ + _fromCC(0x80 | (cc & 0x3f)));
+ }
+};
+let re_utob = /[\uD800-\uDBFF][\uDC00-\uDFFFF]|[^\x00-\x7F]/g;
+/**
+ * @deprecated should have been internal use only.
+ * @param {string} src UTF-8 string
+ * @returns {string} UTF-16 string
+ */
+let utob = function (u) { return u.replace(re_utob, cb_utob); };
+//
+let _encode = _hasBuffer
+ ? function (s) { return Buffer.from(s, 'utf8').toString('base64'); }
+ : _TE
+ ? function (s) { return _fromUint8Array(_TE.encode(s)); }
+ : function (s) { return _btoa(utob(s)); };
+/**
+ * converts a UTF-8-encoded string to a Base64 string.
+ * @param {boolean} [urlsafe] if `true` make the result URL-safe
+ * @returns {string} Base64 string
+ */
+let encode = function (src, urlsafe) {
+ if (urlsafe === void 0) { urlsafe = false; }
+ return urlsafe
+ ? _mkUriSafe(_encode(src))
+ : _encode(src);
+};
+/**
+ * converts a UTF-8-encoded string to URL-safe Base64 RFC4648 搂5.
+ * @returns {string} Base64 string
+ */
+let encodeURI = function (src) { return encode(src, true); };
+// This trick is found broken https://github.com/dankogai/js-base64/issues/130
+// const btou = (src: string) => decodeURIComponent(escape(src));
+// reverting good old fationed regexp
+let re_btou = /[\xC0-\xDF][\x80-\xBF]|[\xE0-\xEF][\x80-\xBF]{2}|[\xF0-\xF7][\x80-\xBF]{3}/g;
+let cb_btou = function (cccc) {
+ switch (cccc.length) {
+ case 4:
+ let cp = ((0x07 & cccc.charCodeAt(0)) << 18)
+ | ((0x3f & cccc.charCodeAt(1)) << 12)
+ | ((0x3f & cccc.charCodeAt(2)) << 6)
+ | (0x3f & cccc.charCodeAt(3)), offset = cp - 0x10000;
+ return (_fromCC((offset >>> 10) + 0xD800)
+ + _fromCC((offset & 0x3FF) + 0xDC00));
+ case 3:
+ return _fromCC(((0x0f & cccc.charCodeAt(0)) << 12)
+ | ((0x3f & cccc.charCodeAt(1)) << 6)
+ | (0x3f & cccc.charCodeAt(2)));
+ default:
+ return _fromCC(((0x1f & cccc.charCodeAt(0)) << 6)
+ | (0x3f & cccc.charCodeAt(1)));
+ }
+};
+/**
+ * @deprecated should have been internal use only.
+ * @param {string} src UTF-16 string
+ * @returns {string} UTF-8 string
+ */
+let btou = function (b) { return b.replace(re_btou, cb_btou); };
+/**
+ * polyfill version of `atob`
+ */
+let atobPolyfill = function (asc) {
+ // console.log('polyfilled');
+ asc = asc.replace(/\s+/g, '');
+ if (!b64re.test(asc))
+ throw new TypeError('malformed base64.');
+ asc += '=='.slice(2 - (asc.length & 3));
+ let u24, bin = '', r1, r2;
+ for (let i = 0; i < asc.length;) {
+ u24 = b64tab[asc.charAt(i++)] << 18
+ | b64tab[asc.charAt(i++)] << 12
+ | (r1 = b64tab[asc.charAt(i++)]) << 6
+ | (r2 = b64tab[asc.charAt(i++)]);
+ bin += r1 === 64 ? _fromCC(u24 >> 16 & 255)
+ : r2 === 64 ? _fromCC(u24 >> 16 & 255, u24 >> 8 & 255)
+ : _fromCC(u24 >> 16 & 255, u24 >> 8 & 255, u24 & 255);
+ }
+ return bin;
+};
+/**
+ * does what `window.atob` of web browsers do.
+ * @param {String} asc Base64-encoded string
+ * @returns {string} binary string
+ */
+let _atob = typeof atob === 'function' ? function (asc) { return atob(_tidyB64(asc)); }
+ : _hasBuffer ? function (asc) { return Buffer.from(asc, 'base64').toString('binary'); }
+ : atobPolyfill;
+//
+let _toUint8Array = _hasBuffer
+ ? function (a) { return _U8Afrom(Buffer.from(a, 'base64')); }
+ : function (a) { return _U8Afrom(_atob(a).split('').map(function (c) { return c.charCodeAt(0); })); };
+/**
+ * converts a Base64 string to a Uint8Array.
+ */
+let toUint8Array = function (a) { return _toUint8Array(_unURI(a)); };
+//
+let toHexString = function (a) {
+ let uint8 = toUint8Array(a)
+ return Array.from(uint8)
+ .map((i) => i.toString(16).padStart(2, '0'))
+ .join('');;
+}
+let _decode = _hasBuffer
+ ? function (a) { return Buffer.from(a, 'base64').toString('utf8'); }
+ : _TD
+ ? function (a) { return _TD.decode(_toUint8Array(a)); }
+ : function (a) { return btou(_atob(a)); };
+let _unURI = function (a) { return _tidyB64(a.replace(/[-_]/g, function (m0) { return m0 == '-' ? '+' : '/'; })); };
+/**
+ * converts a Base64 string to a UTF-8 string.
+ * @param {String} src Base64 string. Both normal and URL-safe are supported
+ * @returns {string} UTF-8 string
+ */
+let decode = function (src) { return _decode(_unURI(src)); };
+/**
+ * check if a value is a valid Base64 string
+ * @param {String} src a value to check
+ */
+let isValid = function (src) {
+ if (typeof src !== 'string')
+ return false;
+ let s = src.replace(/\s+/g, '').replace(/={0,2}$/, '');
+ return !/[^\s0-9a-zA-Z\+/]/.test(s) || !/[^\s0-9a-zA-Z\-_]/.test(s);
+};
+//
+let _noEnum = function (v) {
+ return {
+ value: v, enumerable: false, writable: true, configurable: true
+ };
+};
+/**
+ * extend String.prototype with relevant methods
+ */
+let extendString = function () {
+ let _add = function (name, body) { return Object.defineProperty(String.prototype, name, _noEnum(body)); };
+ _add('fromBase64', function () { return decode(this); });
+ _add('toBase64', function (urlsafe) { return encode(this, urlsafe); });
+ _add('toBase64URI', function () { return encode(this, true); });
+ _add('toBase64URL', function () { return encode(this, true); });
+ _add('toUint8Array', function () { return toUint8Array(this); });
+};
+/**
+ * extend Uint8Array.prototype with relevant methods
+ */
+let extendUint8Array = function () {
+ let _add = function (name, body) { return Object.defineProperty(Uint8Array.prototype, name, _noEnum(body)); };
+ _add('toBase64', function (urlsafe) { return fromUint8Array(this, urlsafe); });
+ _add('toBase64URI', function () { return fromUint8Array(this, true); });
+ _add('toBase64URL', function () { return fromUint8Array(this, true); });
+};
+/**
+ * extend Builtin prototypes with relevant methods
+ */
+let extendBuiltins = function () {
+ extendString();
+ extendUint8Array();
+};
+let gBase64 = {
+ version: version,
+ VERSION: VERSION,
+ atob: _atob,
+ atobPolyfill: atobPolyfill,
+ btoa: _btoa,
+ btoaPolyfill: btoaPolyfill,
+ fromBase64: decode,
+ toBase64: encode,
+ encode: encode,
+ encodeURI: encodeURI,
+ encodeURL: encodeURI,
+ utob: utob,
+ btou: btou,
+ decode: decode,
+ isValid: isValid,
+ fromUint8Array: fromUint8Array,
+ toUint8Array: toUint8Array,
+ fromHexString: fromHexString,
+ toHexString: toHexString,
+ extendString: extendString,
+ extendUint8Array: extendUint8Array,
+ extendBuiltins: extendBuiltins
+};
+export default gBase64
\ No newline at end of file
diff --git a/vf205_access/dxmodules/dxCameraCalibration.js b/vf205_access/dxmodules/dxCameraCalibration.js
new file mode 100644
index 0000000..22a6127
--- /dev/null
+++ b/vf205_access/dxmodules/dxCameraCalibration.js
@@ -0,0 +1,136 @@
+//build: 20240528
+//渚濊禆缁勪欢:dxDriver锛宒xLogger锛宒xMap锛宒xCapturer
+import { calibrationClass } from './libvbar-m-dxcapturer_calibration.so'
+import capturer from '../dxmodules/dxCapturer.js'
+import * as os from "os";
+import dxMap from './dxMap.js'
+import log from './dxLogger.js'
+import bus from './dxEventBus.js'
+const calibrationObj = new calibrationClass();
+const map = dxMap.get('default')
+const calibration = {}
+let cnt = 0, startTime = 0;
+
+/**
+ * calibration 鍒濆鍖�
+ * @returns true/false
+ */
+calibration.init = function () {
+ return calibrationObj.init();
+}
+
+/**
+ * calibration 閿�姣�
+ * @returns true/false
+ */
+calibration.deinit = function () {
+ return calibrationObj.deinit();
+}
+
+/**
+ * 璇嗗埆鏍囧畾锛堟嬁鏂规牸绾稿鍑嗗睆骞曚笂鐨勬柟妗嗭級
+ * @param {number} imageRgb image鎸囬拡锛屽繀濉�
+ * @param {number} imageNir image鎸囬拡锛屽繀濉�
+ * @param {number} cnt 鏍囧畾娆℃暟锛屽繀濉紙0锛氱涓�娆℃爣瀹�,1锛氱浜屾鏍囧畾锛�
+ * @returns true/false
+ */
+calibration.calibrationFromImage = function (imageRgb, imageNir, cnt) {
+ return calibrationObj.calibrationFromImage(imageRgb, imageNir, cnt);
+}
+
+/**
+ * 璁$畻骞跺瓨鍌ㄦ爣瀹氱粨鏋�
+ * @param {number} imageNir image鎸囬拡锛屽繀濉�
+ * @param {string} path 瀛樺偍璺緞锛屽繀濉�
+ * @returns true/false
+ */
+calibration.getMap = function (imageRgb, imageNir,cnt, path) {
+ return calibrationObj.getMap(imageRgb, imageNir,cnt, path);
+}
+
+/**
+ * 鑾峰彇缁樺埗鏍囧畾ui妗嗕俊鎭�
+ * @param {number} cnt 鏍囧畾娆℃暟锛屽繀濉紙0锛氱涓�娆℃爣瀹�,1锛氱浜屾鏍囧畾锛�
+ * @param {number} type 妯珫灞忥紝蹇呭~锛�1锛氭í灞忥紝0锛氱珫灞忥級
+ * @returns {x:妯潗鏍�,y:绾靛潗鏍�,w:瀹�,h:楂榼
+ */
+calibration.getBox = function (cnt, type) {
+ let box = calibrationObj.getBox(cnt);
+ let coordinate = {
+ x: type == 1 ? box.x : box.y,
+ y: type == 1 ? box.y : box.x,
+ w: type == 1 ? box.w : box.h,
+ h: type == 1 ? box.h : box.w
+ }
+ return coordinate;
+}
+
+calibration.RECEIVE_MSG = '__calibration__MsgReceive'
+
+/**
+ * 绠�鍖朿ameraCalibration缁勪欢鐨勪娇鐢紝鏃犻渶杞鍘昏幏鍙栨暟鎹紝鏁版嵁浼氶�氳繃eventbus鍙戦�佸嚭鍘�
+ * 鐢变簬璇嗗埆鏍囧畾calibrationFromImage鏄樆濉炵嚎绋嬬殑鏂规硶锛屾墍浠ュ繀椤绘柊寮�涓�涓嚎绋嬫墽琛岋紝鍚﹀垯浼氶樆濉炲叾浠栫嚎绋�
+ * run 鍙細鎵ц涓�娆�
+ * @param {object} options 閰嶇疆鍙傛暟
+ * @param {string} options.capturerRgbId 蹇呭~锛宺gb鍙栧浘鍙ユ焺id
+ * @param {string} options.capturerNirId 蹇呭~锛宯ir鍙栧浘鍙ユ焺id
+ * @param {number} options.timeout 鍗曚綅绉掞紝闈炲繀濉紙缂虹渷20绉掞級锛屾爣瀹氱殑瓒呮椂鏃堕棿锛屽湪姝ゆ湡闂村唴鏈畬鎴愪袱娆℃爣瀹氾紝鍒欐爣瀹氬け璐ョ粨鏉熺嚎绋嬶紝濡傞渶閲嶆柊鏍囧畾锛屽繀椤诲啀娆℃墽琛宺un鏂规硶
+ */
+calibration.run = function (options) {
+ if (options === undefined || options.length === 0) {
+ throw new Error("dxCameraCalibration.run:'options' parameter should not be null or empty")
+ }
+ if (options.capturerRgbId === undefined || options.capturerRgbId === null || options.capturerRgbId.length <= 0) {
+ throw new Error("dxCameraCalibration.run:'capturerRgbId' should not be null or empty")
+ }
+ if (options.capturerNirId === undefined || options.capturerNirId === null || options.capturerNirId.length <= 0) {
+ throw new Error("dxCameraCalibration.run:'capturerNirId' should not be null or empty")
+ }
+ options.timeout = options.timeout ? options.timeout : 20
+ try {
+ if(startTime == null || startTime == 0){
+ startTime = new Date().getTime()
+ }
+ let imageRgb = capturer.readImage(options.capturerRgbId)
+ let imageNir = capturer.readImage(options.capturerNirId)
+ let res = this.calibrationFromImage(imageRgb, imageNir, cnt)
+ if (res) {
+ if (cnt >= 1) {
+ log.info("涓ゆ鏍囧畾鎴愬姛锛岀粨鏉熸爣瀹�")
+ let path = "/etc/.cameraCalibration"
+ if(options.path && options.path.length > 0){
+ path = options.path
+ }
+ this.getMap(imageRgb, imageNir, cnt, path)
+ bus.fire(this.RECEIVE_MSG, "success1")
+ capturer.destroyImage(imageRgb)
+ capturer.destroyImage(imageNir)
+ cnt = 0;
+ startTime = 0;
+ return "success1"
+ }
+ log.info("绗�" + (cnt + 1) + "娆℃爣瀹氭垚鍔�")
+ bus.fire(this.RECEIVE_MSG, "success0")
+ cnt += 1
+ log.info("寮�濮嬭繘琛岀" + (cnt + 1) + "娆℃爣瀹�")
+ return "success0"
+ } else {
+ log.error("绗�" + (cnt + 1) + "娆℃爣瀹氬け璐ワ紝閲嶈瘯涓�")
+ }
+ capturer.destroyImage(imageRgb)
+ capturer.destroyImage(imageNir)
+ let endTime = new Date().getTime()
+ if (endTime - startTime > options.timeout * 1000) {
+ log.error('鏍囧畾瓒呮椂锛岃閲嶆柊鎵ц鏍囧畾')
+ bus.fire(this.RECEIVE_MSG, "timeout")
+ cnt = 0
+ startTime = 0;
+ return "timeout"
+ }
+ return "failed"
+ } catch (error) {
+ log.error(error)
+ }
+}
+
+export default calibration;
\ No newline at end of file
diff --git a/vf205_access/dxmodules/dxCapturer.js b/vf205_access/dxmodules/dxCapturer.js
new file mode 100644
index 0000000..3943ae3
--- /dev/null
+++ b/vf205_access/dxmodules/dxCapturer.js
@@ -0,0 +1,336 @@
+//build: 20240524
+//鎽勫儚澶村彇鍥剧粍浠讹紝涓昏鐢ㄤ簬鑾峰彇浜岀淮鐮佸浘鍍忕劧鍚庡埄鐢╠xDecoder缁勪欢鏉ヨВ鏋愪簩缁寸爜鍥惧儚
+//渚濊禆缁勪欢锛歞xDriver锛宒xCommon锛宒xStd锛宒xMap
+import { capturerClass } from './libvbar-m-dxcapturer.so'
+import * as os from "os"
+import std from './dxStd.js'
+import dxMap from './dxMap.js'
+import dxCommon from './dxCommon.js';
+import bus from './dxEventBus.js'
+const capturerObj = new capturerClass();
+const map = dxMap.get('default')
+const capturer = {}
+
+/**
+ * 鍙栧浘妯″潡鍒濆鍖�
+ * @param {object} options 閰嶇疆鍙傛暟锛屽ぇ閮ㄥ垎鍙互鐢ㄩ粯璁ゅ��
+ * @param {string} options.path 蹇呭~锛屽浘鍍忛噰闆嗚澶囪矾寰勶紝姣忕璁惧鏈夊樊寮傦紝姣斿DW200瀵瑰簲鐨勫�兼槸'/dev/video11', M500瀵瑰簲鐨�'/dev/video0'
+ * @param {number} options.width 闈炲繀濉紝鍥惧儚瀹斤紝缂虹渷鏄�0
+ * @param {number} options.height 闈炲繀濉紝鍥惧儚楂橈紝缂虹渷鏄�0
+ * @param {number} options.widthbytes 闈炲繀濉紝姣忎釜鍍忕礌鎵�鍗犲瓧鑺傛暟 GREY : 1锛� YUV : 2锛孌W200缂虹渷鏄�1 VF203缂虹渷鏄�2
+ * @param {number} options.pixel_format 闈炲繀濉紝鍍忕礌鏍煎紡锛� 缂虹渷鏄�1497715271琛ㄧずV4L2_PIX_FMT_GREY
+ * @param {number} options.max_channels 闈炲繀濉紝鏈�澶ф敮鎸佺殑鍚屾杈撳嚭channel鏁伴噺锛岀己鐪佹槸3
+ * @param {number} options.rotation 闈炲繀濉紝鏃嬭浆瑙掑害锛岀己鐪佹槸90
+ * @param {number} options.frame_num 闈炲繀濉紝甯х紪鍙凤紝缂虹渷鏄�3
+ * @param {number} options.preview_enable 闈炲繀濉紝棰勮鏄惁鍚敤锛岀己鐪佹槸3
+ * @param {number} options.preview_left 闈炲繀濉紝棰勮妗嗗乏杈规鍧愭爣锛岀己鐪佹槸0
+ * @param {number} options.preview_top 闈炲繀濉紝棰勮妗嗕笂杈规鍧愭爣锛岀己鐪佹槸0
+ * @param {number} options.preview_width 闈炲繀濉紝棰勮妗嗗搴︼紝VF203缂虹渷鏄�1024
+ * @param {number} options.preview_height 闈炲繀濉紝棰勮妗嗛珮搴︼紝VF203缂虹渷鏄�600
+ * @param {number} options.preview_rotation 闈炲繀濉紝棰勮妗嗘棆杞搴︼紝缂虹渷鏄�0
+ * @param {number} options.preview_mode 闈炲繀濉紝棰勮妗嗘ā寮忥紝缂虹渷鏄�2
+ * @param {number} options.preview_screen_index 闈炲繀濉紝棰勮妗嗙储寮曪紝缂虹渷鏄�0
+ * @param {string} id 鍙ユ焺id锛岄潪蹇呭~锛堣嫢鍒濆鍖栧涓疄渚嬮渶瑕佷紶鍏ュ敮涓�id锛�
+ */
+capturer.init = function (options, id) {
+ if (options.path === undefined || options.path === null || options.path.length < 1) {
+ throw new Error("dxCapturer.init: 'path' parameter should not be null or empty")
+ }
+ let pointer = capturerObj.init(options);
+ if (!pointer) {
+ throw new Error("dxCapturer.init: init failed")
+ }
+ dxCommon.handleId("capturer", id, pointer)
+}
+
+/**
+ * 鍥炶皟娉ㄥ唽
+ * @param {string} id 鍙ユ焺id锛岄潪蹇呭~锛堥渶淇濇寔鍜宨nit涓殑id涓�鑷达級
+ * @param {string} capturerDogId 鎽勫儚澶寸湅闂ㄧ嫍鍙ユ焺id锛岄潪蹇呭~
+ * @returns true/false
+ */
+capturer.registerCallback = function (id, capturerDogId) {
+ let pointer = dxCommon.handleId("capturer", id)
+ let capturerDogPointer = null;
+ print("capturerDogPointer:", capturerDogPointer)
+ if(capturerDogId){
+ capturerDogPointer = dxCommon.handleId("watchdog", capturerDogId)
+ print("capturerDogPointer:", capturerDogPointer)
+ }
+ return capturerObj.registerCallback(pointer, "decoderCapturerImage", capturerDogPointer)
+}
+/**
+ * 鑾峰彇鍩烘湰淇℃伅
+ * @param {string} id 鍙ユ焺id锛岄潪蹇呭~锛堥渶淇濇寔鍜宨nit涓殑id涓�鑷达級
+ * @returns 鏍煎紡绫讳技锛� {"width":800,"widthbytes":1,"height":600,"name":{},"type":6}
+ */
+capturer.getInfo = function (id) {
+ let pointer = dxCommon.handleId("capturer", id)
+ return capturerObj.getInfo(pointer)
+}
+/**
+ * 鍏抽棴鍙栧浘妯″潡
+ * @param {string} id 鍙ユ焺id锛岄潪蹇呭~锛堥渶淇濇寔鍜宨nit涓殑id涓�鑷达級
+ * @returns true/false
+ */
+capturer.close = function (id) {
+ let pointer = dxCommon.handleId("capturer", id)
+ return capturerObj.close(pointer)
+}
+
+/**
+ * 鑾峰彇鍥惧儚鏁版嵁锛岃疆璇㈠彲璋冪敤姝ゆ帴鍙o紝绫讳技capturer.msgReceive鏂规硶鐨勮幏鍙栵紝鑻ヤ娇鐢ㄨ繖涓柟娉曪紝蹇呴』鎵嬪姩閿�姣佽幏鍙栫殑image鎸囬拡
+ * @param {string} id 鍙ユ焺id锛岄潪蹇呭~锛堥渶淇濇寔鍜宨nit涓殑id涓�鑷达級
+ * @returns image鎸囬拡
+ */
+capturer.readImage = function (id) {
+ let pointer = dxCommon.handleId("capturer", id)
+ return capturerObj.readImage(pointer)
+}
+
+/**
+ * 閿�姣佽幏鍙栫殑image鎸囬拡锛屼笌capturer.readImage鏂规硶鍏卞悓浣跨敤
+ * @param {number} image image鎸囬拡锛屽繀濉�
+ * @returns true/false
+ */
+capturer.destroyImage = function (image) {
+ return capturerObj.destroyImage(image)
+}
+
+/**
+ * 浣胯兘/鍏抽棴capture棰勮
+ * @param {number} 鎽勫儚澶村惎鐢�/绂佺敤锛屽繀濉�
+ * @param {string} id 鍙ユ焺id锛岄潪蹇呭~锛堥渶淇濇寔鍜宨nit涓殑id涓�鑷达級
+ * @returns true/false
+ */
+capturer.capturerEnable = function (enable, id) {
+ if (enable == null) {
+ throw new Error("nirEnable should not be null or empty")
+ }
+ let pointer = dxCommon.handleId("capturer", id)
+ return capturerObj.capturerPreviewEnable(pointer, enable)
+}
+
+/**
+ * @brief 鍥剧墖鏂囦欢杞琲mage
+ * @param {string} fileName 鏂囦欢璺緞
+ * @param {number} type 鍥惧儚绫诲瀷 IMAGE_YUV420P = 0, 1IMAGE_YUV420SP = 1,
+ * @return imageId image鍙ユ焺id
+ */
+capturer.pictureFileToImage = function (fileName, type) {
+ if (fileName == null) {
+ throw new Error("fileName should not be null or empty")
+ }
+ if (type == null) {
+ throw new Error("type should not be null or empty")
+ }
+ return capturerObj.pictureFileToImage(fileName, type)
+}
+
+/**
+ * @brief 鍥剧墖瑁佸壀
+ * @param {string} src_pic 婧愭枃浠惰矾寰�
+ * @param {number} width 鍥惧儚瀹藉害
+ * @param {number} height 鍥惧儚楂樺害
+ * @param {string} out_pic 瑁佸壀鍚庣殑鍥剧墖璺緞
+ * @return ture/false
+ */
+capturer.pictureCropping = function (src_pic, width, height, out_pic) {
+ if (src_pic == null) {
+ throw new Error("src_pic should not be null or empty")
+ }
+ if (width == null) {
+ throw new Error("width should not be null or empty")
+ }
+ if (height == null) {
+ throw new Error("height should not be null or empty")
+ }
+ if (out_pic == null) {
+ throw new Error("out_pic should not be null or empty")
+ }
+ return capturerObj.pictureCropping(src_pic, width, height, out_pic)
+}
+
+/**
+ * 鍥剧墖鏁版嵁杞琲mage
+ * @param {string} base64Data 鍥剧墖base64鏁版嵁
+ * @param {number} dataLen 鏁版嵁闀垮害dataLen
+ * @param {number} type 鍥惧儚绫诲瀷 IMAGE_YUV420P = 0, 1IMAGE_YUV420SP = 1,
+ * @returns imageId image鍙ユ焺id
+ */
+capturer.pictureDataToImage = function (base64Data, dataLen, type) {
+ if (base64Data == null) {
+ throw new Error("base64Data should not be null or empty")
+ }
+ if (dataLen == null) {
+ throw new Error("dataLen should not be null or empty")
+ }
+ if (type == null) {
+ throw new Error("type should not be null or empty")
+ }
+ return capturerObj.pictureDataToImage(base64Data, dataLen, type)
+}
+
+// image, (enum image_type)type, (enum vbar_drv_picture_type)save_type, quality, pic_data, data_len
+/**
+ * image 杞浘鐗囨暟鎹�
+ * @param {number} imageId image鍥剧墖鍙ユ焺id
+ * @param {number} type 鍥惧儚绫诲瀷 IMAGE_YUV420P = 0, 1IMAGE_YUV420SP = 1,
+ * @param {number} saveType 杞崲鍚庣殑鍥剧墖绫诲瀷 TYPE_JPEG = 0, TYPE_BMP = 1, TYPE_PNG = 2, TYPE_UNKNOE = 3;
+ * @param {number} quality 鍘嬬缉姣旓紝jpeg 0-100锛� png 鏃犳崯鍘嬬缉鏃犻渶姝ゅ弬鏁帮紝 bmp浣嶅浘鏃犻渶姝ゅ弬鏁�
+ * @returns 鍥剧墖base64鏁版嵁
+ */
+capturer.imageToPictureData = function (imageId, type, saveType, quality) {
+ if (imageId == null) {
+ throw new Error("imageId should not be null or empty")
+ }
+ if (type == null) {
+ throw new Error("type should not be null or empty")
+ }
+ if (saveType == null) {
+ throw new Error("saveType should not be null or empty")
+ }
+ if (quality == null) {
+ throw new Error("quality should not be null or empty")
+ }
+ return capturerObj.imageToPictureData(imageId, type, saveType, quality)
+}
+
+/**
+ * 杞浘鐗囨枃浠�
+ * @param {number} imageId image鍥惧儚鍙ユ焺id
+ * @param {string} type 鍥惧儚绫诲瀷 IMAGE_YUV420P = 0, 1IMAGE_YUV420SP = 1,
+ * @param {number} saveType 杞崲鍚庣殑鍥剧墖绫诲瀷 YPE_JPEG = 0, TYPE_BMP = 1, TYPE_PNG = 2, TYPE_UNKNOE = 3;
+ * @param {number} quality 鍘嬬缉姣旓紝jpeg 0-100锛� png 鏃犳崯鍘嬬缉鏃犻渶姝ゅ弬鏁帮紝 bmp浣嶅浘鏃犻渶姝ゅ弬鏁�
+ * @param {number} savePath 鍥剧墖淇濆瓨璺緞
+ * @returns true/false
+ */
+capturer.imageToPictureFile = function (imageId, type, saveType, quality, savePath) {
+ if (imageId == null) {
+ throw new Error("imageId should not be null or empty")
+ }
+ if (type == null) {
+ throw new Error("type should not be null or empty")
+ }
+ if (saveType == null) {
+ throw new Error("saveType should not be null or empty")
+ }
+ if (quality == null) {
+ throw new Error("quality should not be null or empty")
+ }
+ if (savePath == null) {
+ throw new Error("savePath should not be null or empty")
+ }
+ return capturerObj.imageToPictureFile(imageId, type, saveType, quality, savePath)
+}
+
+/**
+* 鍥剧墖缂╂斁
+* @param {number} imageId image鍥惧儚鍙ユ焺id
+* @param {number} width 鐩爣鍥惧儚瀹藉害
+* @param {number} height 鐩爣鍥惧儚楂樺害
+* @param {number} mode 婊ゆ尝鍣ㄦā寮�
+* FILTER_MODE_NONE 涓嶈繘琛屾护娉紝鐩存帴閲囨牱锛涢�熷害鏈�蹇��
+* FILTER_MODE_LINEAR 鍙部姘村钩鏂瑰悜婊ゆ尝銆�
+* FILTER_MODE_BILINEAR 鍙岀嚎鎬ф护娉紱姣旂洅婊ゆ尝鏇村揩锛屼絾鍦ㄧ缉灏忓浘鍍忔椂璐ㄩ噺杈冧綆銆�
+* FILTER_MODE_BOX 鐩掓护娉紱鎻愪緵鏈�楂樼殑缂╂斁璐ㄩ噺
+*/
+capturer.imageResizeResolution = function (imageId, width, height, mode) {
+ if (imageId == null) {
+ throw new Error("imageId should not be null or empty")
+ }
+ if (width == null) {
+ throw new Error("width should not be null or empty")
+ }
+ if (height == null) {
+ throw new Error("height should not be null or empty")
+ }
+ if (mode == null) {
+ throw new Error("mode should not be null or empty")
+ }
+ return capturerObj.imageResizeResolution(imageId, width, height, mode)
+}
+
+/**
+ * 鍒ゆ柇capturer娑堟伅闃熷垪鏄惁涓虹┖
+ * @param {string} id 鍙ユ焺id锛岄潪蹇呭~锛堥渶淇濇寔鍜宨nit涓殑id涓�鑷达級
+ * @returns true/false
+ */
+capturer.msgIsEmpty = function (id) {
+ let pointer = dxCommon.handleId("capturer", id)
+ return capturerObj.msgIsEmpty(pointer)
+}
+
+/**
+ * 浠巆apturer娑堟伅闃熷垪涓鍙栨暟鎹�
+ * @param {string} id 鍙ユ焺id锛岄潪蹇呭~锛堥渶淇濇寔鍜宨nit涓殑id涓�鑷达級
+ * @returns image鎸囬拡
+ */
+capturer.msgReceive = function (id) {
+ let pointer = dxCommon.handleId("capturer", id)
+ return capturerObj.msgReceive(pointer)
+}
+
+/**
+ * 鏌ヨcapturer娑堟伅闃熷垪澶у皬
+ * @param {string} id 鍙ユ焺id锛岄潪蹇呭~锛堥渶淇濇寔鍜宨nit涓殑id涓�鑷达級
+ * @returns size
+ */
+capturer.msgQueueSize = function (id) {
+ let pointer = dxCommon.handleId("capturer", id)
+ return capturerObj.msgQueueSize(pointer)
+}
+
+capturer.RECEIVE_MSG = '__capturer__MsgReceive'
+
+/**
+ * 鐢ㄤ簬绠�鍖朿apturer缁勪欢鐨勪娇鐢紝鎶奵apturer灏佽鍦ㄨ繖涓獁orker閲岋紝浣跨敤鑰呭彧闇�瑕佽闃卐ventbus鐨勪簨浠跺氨鍙互鐩戝惉capturer
+ * @param {object} options capturer缁勪欢鍙傛暟锛屽弬鑰僣apturer.init锛屽繀濉�
+ * @param {string} options.id 鍙ユ焺id锛岄潪蹇呭~锛堣嫢鍒濆鍖栧涓疄渚嬮渶瑕佷紶鍏ュ敮涓�id锛�
+ */
+capturer.run = function (options) {
+ if (options === undefined || options.length === 0) {
+ throw new Error("dxcapturer.run:'options' parameter should not be null or empty")
+ }
+ if (options.id === undefined || options.id === null || typeof options.id !== 'string') {
+ // 鍙ユ焺id
+ options.id = ""
+ }
+ if (options.path === undefined || options.path === null || options.path.length <= 0) {
+ throw new Error("dxcapturer.run:'path' should not be null or empty")
+ }
+ let oldfilepre = '/app/code/dxmodules/capturerWorker'
+ let content = std.loadFile(oldfilepre + '.js').replace("{{id}}", options.id)
+ let newfile = oldfilepre + options.id + '.js'
+ std.saveFile(newfile, content)
+ let init = map.get("__capturer__run_init" + options.id)
+ if (!init) {//纭繚鍙垵濮嬪寲涓�娆�
+ map.put("__capturer__run_init" + options.id, options)
+ bus.newWorker(options.id || '__capturer', newfile)
+ }
+}
+
+/**
+ * 濡傛灉capturer鍗曠嫭涓�涓嚎绋嬶紝鍙互鐩存帴浣跨敤run鍑芥暟锛屼細鑷姩鍚姩涓�涓嚎绋嬶紝
+ * 濡傛灉鎯冲姞鍏ュ埌鍏朵粬宸叉湁鐨勭嚎绋嬶紝鍙互浣跨敤浠ヤ笅灏佽鐨勫嚱鏁�
+ */
+capturer.worker = {
+ //鍦╳hile寰幆鍓�
+ beforeLoop: function (options) {
+ capturer.init(options, options.id)
+ capturer.registerCallback(options.id)
+ },
+ //鍦╳hile寰幆閲�
+ loop: function (options) {
+ if (!capturer.msgIsEmpty(options.id)) {
+ let res = capturer.msgReceive(options.id);
+ if (options.id === undefined || options.id === null || typeof options.id !== 'string') {
+ // 鍙ユ焺id
+ options.id = ""
+ }
+ bus.fire(capturer.RECEIVE_MSG + options.id, res)
+ }
+ }
+}
+
+export default capturer;
diff --git a/vf205_access/dxmodules/dxCommon.js b/vf205_access/dxmodules/dxCommon.js
new file mode 100644
index 0000000..f8f645a
--- /dev/null
+++ b/vf205_access/dxmodules/dxCommon.js
@@ -0,0 +1,733 @@
+//build: 20240617
+// 绯荤粺鐨勪竴浜涘熀鏈搷浣溿�佽繕鏈変竴浜涘父鐢ㄧ殑宸ュ叿鍑芥暟锛屽熀鏈笂姣忎釜椤圭洰閮介渶瑕佷緷璧栬繖涓粍浠讹紝鍙﹀dxLogger涔熶緷璧栬繖涓粍浠�
+// 渚濊禆缁勪欢锛歞xDriver锛宒xMap
+import { commonClass } from './libvbar-m-dxcommon.so'
+import dxMap from './dxMap.js'
+import * as std from 'std';
+import * as os from "os"
+
+const commonObj = new commonClass();
+
+const common = {}
+/**
+ * 鑾峰彇绯荤粺鍚姩鐨勮繍琛屾椂闂�(鍗曚綅鏄)
+ * @returns
+ */
+common.getUptime = function () {
+ return commonObj.getUptime();
+}
+
+/**
+ * 鑾峰彇绯荤粺鐨勬�诲唴瀛�(鍗曚綅鏄瓧鑺�)
+ * @returns
+ */
+common.getTotalmem = function () {
+ return commonObj.getTotalmem();
+}
+
+/**
+ * 鑾峰彇绯荤粺鍓╀綑鍐呭瓨(鍗曚綅鏄瓧鑺�)
+ * @returns
+ */
+common.getFreemem = function () {
+ return commonObj.getFreemem();
+}
+
+/**
+ * Deprcated, Please use `common.logMemory` instead.
+ */
+common.logMem = function (logger, interval = 10) {
+ if (logger) {
+ logger.debug("Deprcated, Please use `common.logMemory` instead.")
+ }
+}
+/**
+ * Logs the current memory usage at regular intervals for debugging and monitoring purposes.
+ * @param {object} logger The dxLogger module object.
+ * @param {number} interval The logging interval in seconds, defaulting to 10 seconds.
+ */
+common.logMemory = function (logger, interval = 10) {
+ if (!logger) return;
+
+ let first = new Date().getTime();
+ let min = common.getFreemem() / 1024;
+ let max = min;
+ const _logmemory = () => {
+ try {
+ const now = new Date().getTime();
+ const pass = (now - first) / 1000;
+ const free = common.getFreemem() / 1024;
+
+ min = Math.min(min, free);
+ max = Math.max(max, free);
+
+ // Format time
+ let passStr;
+ if (pass > 1700000000) {
+ first = now;
+ passStr = 'time synced, 0s';
+ } else if (pass >= 3600) {
+ const hours = Math.floor(pass / 3600);
+ const minutes = Math.floor((pass % 3600) / 60);
+ const seconds = Math.floor(pass % 60);
+ passStr = `${hours}h ${minutes}m ${seconds}s`;
+ } else if (pass >= 60) {
+ const minutes = Math.floor(pass / 60);
+ const seconds = Math.floor(pass % 60);
+ passStr = `${minutes}m ${seconds}s`;
+ } else {
+ passStr = `${Math.floor(pass)}s`;
+ }
+ const log = `------ ${passStr} passed, free memory (k): ${free}, min free memory (k): ${min}, max free memory (k): ${max} ------`;
+ logger.info(log);
+ } catch (err) {
+ logger.error('Error in logMemory:', err);
+ } finally {
+ os.setTimeout(_logmemory, interval * 1000);
+ }
+ };
+
+ os.setTimeout(_logmemory, interval * 1000);
+};
+
+/**
+ * The principle of converting asynchronous to synchronous is as follows:
+ * the `request` function periodically checks a designated variable in memory for a value.
+ * If the value is found within the timeout period, the result is returned; otherwise,
+ * it is considered a timeout. The `response` function is responsible for storing the result
+ * in the designated variable once the asynchronous request is completed.
+ */
+common.sync = {
+ /**
+ * Block and wait for data
+ * Usage:
+ common.sync.request(topic, 200)
+ .then((data) => {
+ log.info("Received data:", data);
+ })
+ .catch((err) => {
+ log.error("Request failed:", err.message);
+ });
+ * @param {string} topic The unique identifier for each request
+ * @param {int} timeout waitting timeout(microsecond)锛宒efault is 200 ms
+ * @returns
+ */
+ request: function (topic, timeout = 200) {
+ return new Promise((resolve, reject) => {
+ let map = dxMap.get("SYNC");
+ let startTime = Date.now();
+
+ const checkData = () => {
+ let data = map.get(topic);
+ if (data) {
+ map.del(topic); //del data in map
+ resolve(data); //return data
+ } else if (Date.now() - startTime >= timeout) {
+ map.del(topic); // del data in map with timeout
+ reject(new Error(`Timeout exceeded for topic: ${topic}`));
+ } else {
+ os.setTimeout(checkData, 10); //every 10 ms to check
+ }
+ };
+
+ os.setTimeout(checkData, 10); // first check
+ });
+ },
+
+ /**
+ * notify data to requester
+ * @param {string} topic The unique identifier for each request
+ * @param {*} data
+ * @returns
+ */
+ response: function (topic, data) {
+ let map = dxMap.get("SYNC");
+ map.put(topic, data); // save data in map
+ }
+};
+
+/**
+ * 鑾峰彇绯荤粺鍙敤纾佺洏鎬婚噺(鍗曚綅鏄瓧鑺�)
+ * @param {string} path 涓嶅悓鐨勭鐩樺垎鍖哄悕绉帮紙涓嶆槸鐩綍鍚嶏級锛岄潪蹇呭~锛岀己鐪佹槸'/'
+ */
+common.getTotaldisk = function (path) {
+ return commonObj.getTotaldisk(!path ? "/" : path);
+}
+
+/**
+ * 鑾峰彇绯荤粺纾佺洏鍓╀綑鍙敤閲�(鍗曚綅鏄瓧鑺�)
+ * @param {string} path 涓嶅悓鐨勭鐩樺垎鍖哄悕绉帮紙涓嶆槸鐩綍鍚嶏級锛岄潪蹇呭~锛岀己鐪佹槸'/'
+ * @returns
+ */
+common.getFreedisk = function (path) {
+ return commonObj.getFreedisk(!path ? "/" : path);
+}
+
+/**
+ * 鑾峰彇CPU ID
+ * @param {number} len 闈炲繀濉紝缂虹渷闀垮害鏄�33浣嶉暱
+ * @returns
+ */
+common.getCpuid = function () {
+ return commonObj.getCpuid(33);
+}
+
+/**
+ * 鑾峰彇璁惧uuid锛堝瓧绗︿覆锛�
+ * @returns
+ */
+common.getUuid = function () {
+ return commonObj.getUuid(19);
+}
+
+/**
+ * 鑾峰彇璁惧鍞竴鏍囪瘑
+ * @returns
+ */
+common.getSn = function () {
+ let sn = std.loadFile('/etc/.sn')
+ if (sn) {
+ return sn
+ } else {
+ return commonObj.getUuid(19);
+ }
+}
+
+/**
+ * 鑾峰彇閫氳繃uuid璁$畻鐨刴ac鍦板潃锛岃繖涓彲浠ョ敤鏉ュ垵濮嬪寲缃戝崱鐨勬椂鍊欑敤
+ * @returns 鏍煎紡绫讳技锛歜2:a1:63:3f:99:b6
+ */
+common.getUuid2mac = function () {
+ return commonObj.getUuid2mac(19);
+}
+
+/**
+ * 鑾峰彇cpu鍗犵敤鐜囷紙涓嶅ぇ浜�100鐨勬暟瀛楋級
+ * @returns
+ */
+common.getFreecpu = function () {
+ return commonObj.getFreecpu();
+}
+
+
+/**
+ * RSA 瑙e瘑 锛堢閽ュ姞瀵嗗叕閽ヨВ瀵嗭級
+ * 姣斿鍏挜鏄�
+ * @param {ArrayBuffer} data 瑕佽В瀵嗙殑鏁版嵁锛屽繀濉�
+ * @param {string} publicKey 鍏挜锛屽繀濉�
+ * @returns
+ */
+common.arrayBufferRsaDecrypt = function (data, publicKey) {
+ if (data === undefined || data === null) {
+ throw new Error("dxCommon.arrayBufferRsaDecrypt:'data' parameter should not be null or empty")
+ }
+ if (publicKey === undefined || publicKey === null || publicKey.length < 1) {
+ throw new Error("dxCommon.arrayBufferRsaDecrypt:'publicKey' parameter should not be null or empty")
+ }
+ return commonObj.arrayBufferRsaDecrypt(data, publicKey)
+}
+
+/**
+ * @brief Stirng aes 鍔犲瘑
+ */
+common.aes128EcbEncrypt = function (input, key) {
+ return commonObj.aes128EcbEncrypt(input, key)
+}
+/**
+ * @brief Stirng aes 瑙e瘑
+ */
+common.aes128EcbDecrypt = function (input, key) {
+ return commonObj.aes128EcbDecrypt(input, key)
+}
+
+/**
+ * arraybuffer ecb 128bit Pkcs5Padding aes 鍔犲瘑
+ * @param {ArrayBuffer} input 鏄庢枃
+ * @param {ArrayBuffer} key 瀵嗛挜
+ * @returns ArrayBuffer 瀵嗘枃
+ */
+common.aes128EcbPkcs5PaddingEncode = function (input, key) {
+ return commonObj.aes128Pkcs7PaddingEncode(input, key)
+}
+
+/**
+ * arraybuffer ecb 128bit Pkcs5Padding aes 瑙e瘑
+ *
+ * @param {ArrayBuffer} input 瀵嗘枃
+ * @param {ArrayBuffer} key 瀵嗛挜
+ * @returns ArrayBuffer 鏄庢枃
+ */
+common.aesEcb128Pkcs5PaddingDecode = function (input, key) {
+ return commonObj.aes128Pkcs7PaddingDecode(input, key)
+}
+
+/**
+ * aes ECB Pkcs5Padding 128 鍔犲瘑
+ * 绀轰緥锛歝ommon.aes128EcbPkcs5PaddingEncrypt("stamp=202008鏂�&tic", "1234567890123456")
+ * 缁撴灉锛歟f7c3cff9df57b3bcb0951938c574f969e13ffdcc1eadad298ddbd1fb1a4d2f7
+ * 鍙傝�� https://www.devglan.com/online-tools/aes-encryption-decryption
+ * @param {string} input 鏄庢枃鏁版嵁
+ * @param {string} key 瀵嗛挜 16瀛楄妭瀛楃涓�
+ * @return 瀵嗘枃 16杩涘埗瀛楃涓�
+ */
+common.aes128EcbPkcs5PaddingEncrypt = function (input, key) {
+ let data = common.hexStringToArrayBuffer(common.strToUtf8Hex(input))
+ key = common.hexStringToArrayBuffer(common.strToUtf8Hex(key))
+ // 鍔犲瘑
+ let hex = common.arrayBufferToHexString(common.aes128EcbPkcs5PaddingEncode(data, key))
+ return hex
+}
+/**
+ * aes ECB Pkcs5Padding 128 瑙e瘑
+ * @param {string} input 瀵嗘枃 16杩涘埗瀛楃涓�
+ * @param {string} key 瀵嗛挜 16瀛楄妭瀛楃涓�
+ * @return 鏄庢枃
+ */
+common.aes128EcbPkcs5PaddingDecrypt = function (input, key) {
+ key = common.hexStringToArrayBuffer(common.strToUtf8Hex(key))
+ let res = common.aesEcb128Pkcs5PaddingDecode(common.hexStringToArrayBuffer(input), key)
+ return common.utf8HexToStr(common.arrayBufferToHexString(res))
+}
+
+/**
+ * 鎵ц鎿嶄綔绯荤粺鐨勫懡浠�
+ * @param {*} cmd 鍛戒护
+ * @returns
+ */
+common.system = function (cmd) {
+ return commonObj.system(cmd)
+}
+
+/**
+ * 鎵ц鎿嶄綔绯荤粺鐨勫懡浠�
+ * @param {*} cmd 鍛戒护 鎿嶄綔绯荤粺甯哥敤鎸囦护(linux缁濆ぇ閮ㄥ垎鎸囦护閮芥敮鎸�)锛屽繀濉�
+ * @returns
+ */
+common.systemBrief = function (cmd) {
+ return commonObj.systemBrief(cmd)
+}
+
+/**
+ * 鎵ц鎿嶄綔绯荤粺鐨勫懡浠ゅ苟杩斿洖缁撴灉
+ * @param {*} cmd 鍛戒护 鎿嶄綔绯荤粺甯哥敤鎸囦护(linux缁濆ぇ閮ㄥ垎鎸囦护閮芥敮鎸�)锛屽繀濉�
+ * @param {*} resLen 鎺ユ敹鏁版嵁闀垮害 鏈夋椂鍊欒繑鍥炵殑鏁版嵁寰堝ぇ锛屽彲浠ラ�氳繃杩欎釜鍊兼潵杩斿洖鍥哄畾闀垮害鐨勬暟鎹紝蹇呭~
+ * @returns
+ */
+common.systemWithRes = function (cmd, resLen) {
+ return commonObj.systemWithRes(cmd, resLen)
+}
+
+/**
+ * 鎵ц鎿嶄綔绯荤粺鐨勫懡浠ら樆濉炴墽琛�
+ * @param {*} cmd 鍛戒护 鎿嶄綔绯荤粺甯哥敤鎸囦护(linux缁濆ぇ閮ㄥ垎鎸囦护閮芥敮鎸�)锛屽繀濉�
+ * @returns
+ */
+common.systemBlocked = function (cmd) {
+ return commonObj.systemBlocked(cmd)
+}
+
+/**
+ * 寮傛寤惰繜閲嶅惎
+ * @param {*} delay_s 寤惰繜鏃堕棿
+ * @returns
+ */
+common.asyncReboot = function (delay_s) {
+ return commonObj.asyncReboot(delay_s)
+}
+
+/**
+ * bcc鏍¢獙
+ * @param {array} data eg:[49,50,51,52,53,54]瀵瑰簲鐨勫�兼槸7
+ * @returns 鏍¢獙璁$畻缁撴灉
+ */
+common.calculateBcc = function (data) {
+ return commonObj.calculateBcc(data)
+}
+
+/**
+ * crc鏍¢獙 姣斿瀛楃涓�'123456'鏍¢獙璁$畻鐨勭粨鏋滄槸鏁板瓧 158520161
+ * @param {string} content 瑕佹牎楠岀殑瀛楃涓叉暟鎹紝
+ * @returns
+ */
+common.crc32 = function (content) {
+ if (content === undefined || content === null || typeof (content) != "string" || content.length < 1) {
+ throw new Error("dxCommon.crc32:'content' paramter should not be empty")
+ }
+ return commonObj.crc32(content)
+}
+
+/**
+ * 璁$畻MD5鍝堝笇锛屾瘮濡�'123456'瀵瑰簲鐨勬暟瀛楁暟缁勬槸[49,50,51,52,53,54] 瀵瑰簲鐨刴d5鏄�'e10adc3949ba59abbe56e057f20f883e'锛�
+ * 浣嗘槸杩斿洖鐨勪笉鏄�16杩涘埗瀛楃涓诧紝鏄暟瀛楁暟缁勶紝鍙互浣跨敤arrToHex鍑芥暟杞崲
+ * @param {array} arr 鏁板瓧鏁扮粍
+ * @returns 鏁板瓧鏁扮粍
+ */
+common.md5Hash = function (arr) {
+ return commonObj.md5Hash(arr)
+}
+
+/**
+ * 鏂囦欢璁$畻MD5鍝堝笇,姣斿鏂囦欢閲岀殑鍐呭鏄�'123456'锛屽搴旂殑md5鏄�'e10adc3949ba59abbe56e057f20f883e'
+ * 浣嗘槸杩斿洖鐨勪笉鏄�16杩涘埗瀛楃涓诧紝鏄暟瀛楁暟缁勶紝鍙互浣跨敤arrToHex鍑芥暟杞崲
+ * @param {string} 鏂囦欢璺緞锛岀粷瀵硅矾寰勶紝蹇呭~锛岄�氬父鏄互/app/code寮�澶�
+ * @returns 鏁板瓧鏁扮粍
+ */
+common.md5HashFile = function (filePath) {
+ if (filePath === undefined || filePath === null || typeof (filePath) != "string") {
+ return null
+ }
+ return commonObj.md5HashFile(filePath)
+}
+
+/**
+ * 璁$畻HMAC MD5鍔犲瘑,姣斿鍔犲瘑鐨勬暟鎹槸'123456',瀵嗛挜鏄�'654321'锛屽搴旂殑缁撴灉鏄�'357cbe6d81a8ec770799879dc8629a53'
+ * 浣嗘槸鍙傛暟鍜岃繑鍥炵殑鍊奸兘鏄疉rrayBuffer
+ * @param {ArrayBuffer} data 闇�瑕佸姞瀵嗙殑鍐呭,蹇呭~
+ * @param {ArrayBuffer} key 瀵嗛挜 ,蹇呭~
+ * @returns ArrayBuffer
+ */
+common.hmacMd5Hash = function (data, key) {
+ return commonObj.hmacMd5Hash(data, key)
+}
+
+/**
+ * 璁$畻HMAC MD5鍔犲瘑,姣斿鍔犲瘑鐨勬暟鎹槸'123456',瀵嗛挜鏄�'654321'锛屽搴旂殑缁撴灉鏄�'357cbe6d81a8ec770799879dc8629a53'
+ * @param {string} data 闇�瑕佸姞瀵嗙殑鍐呭,蹇呭~
+ * @param {string} key 瀵嗛挜 ,蹇呭~
+ * @returns ArrayBuffer
+ */
+common.hmac = function (data, key) {
+ return commonObj.hmac(data, key)
+}
+
+/**
+ * 鏂囦欢璁$畻HMAC MD5鍔犲瘑锛屾瘮濡傛枃浠堕噷鐨勫唴瀹规槸'123456'锛屽瘑閽ユ槸'654321'锛屽搴旂殑缁撴灉鏄�'357cbe6d81a8ec770799879dc8629a53'
+ * @param {string} filePath 闇�瑕佸姞瀵嗙殑鍐呭瀛樺偍鐨勬枃浠惰矾寰勶紝缁濆璺緞锛屽繀濉紝閫氬父鏄互/app/code寮�澶�
+ * @param {array} key 瀵嗛挜 ,鏁板瓧鏁扮粍,蹇呭~
+ * @returns 鏁板瓧鏁扮粍
+ */
+common.hmacMd5HashFile = function (filePath, key) {
+ return commonObj.hmacMd5HashFile(filePath, key)
+}
+
+
+/**
+ * base64杞琤in鏂囦欢
+ * @param {string} file_path 鏂囦欢璺緞锛屽繀濉�
+ * @param {string} base64Data base64鏁版嵁锛屽繀濉�
+ * @returns
+ */
+common.base64_2binfile = function (file_path, base64Data) {
+ return commonObj.base64_2binfile(file_path, base64Data);
+}
+
+/**
+ * bin鏂囦欢杞琤ase64
+ * @param {string} file_path 鏂囦欢璺緞锛屽繀濉�
+ * @returns base64Data base64鏁版嵁锛屽繀濉�
+ */
+common.binfile_2base64 = function (file_path) {
+ return commonObj.binfile_2base64(file_path);
+}
+
+/**
+ * 鍒囨崲璁惧妯″紡
+ * @description 妯″紡鍒囨崲鍚庝細閲嶅惎璁惧锛岃繘鍏ユ寚瀹氭ā寮忥紝浣跨敤鏂规硶鏃堕渶瀹屾暣缁存姢鐩镐簰鍒囨崲鐨勯�昏緫锛屽垏鎹负涓氬姟妯″紡鍚庝笉鑳戒娇鐢↖DE鍔熻兘
+ * @param {number} mode 娉ㄦ剰锛氭棫鐗堟湰妯″紡鍒囨崲浣跨敤锛�1銆�2銆�3锛夛紝鏂扮増鏈ā寮忓垏鎹娇鐢紙dev銆乼est銆乸rod銆乻afe锛�
+ * @returns true false
+ */
+common.setMode = function (mode) {
+ // 娉ㄦ剰锛氭棫鐗堟湰妯″紡鍒囨崲浣跨敤锛�1銆�2銆�3锛�
+ if (mode == 1) {
+ //鐢熶骇妯″紡
+ commonObj.systemWithRes(`echo 'app' > /etc/.mode`, 2)
+ // 1.0鐗堟湰鍒囨崲涓哄叾浠栨ā寮忓悗鍒犻櫎宸ュ巶妫�娴嬶紙鍚庣画鐗堟湰鍙兘浼氳皟鏁达級
+ commonObj.systemWithRes(`rm -rf /test`, 2)
+ } else if (mode == 2) {
+ //璋冭瘯妯″紡
+ commonObj.systemWithRes(`echo 'debug' > /etc/.mode`, 2)
+ // 1.0鐗堟湰鍒囨崲涓哄叾浠栨ā寮忓悗鍒犻櫎宸ュ巶妫�娴嬶紙鍚庣画鐗堟湰鍙兘浼氳皟鏁达級
+ commonObj.systemWithRes(`rm -rf /test`, 2)
+ } else if (mode == 3) {
+ //璇曚骇妯″紡
+ commonObj.systemWithRes(`echo 'pp' > /etc/.mode`, 2)
+ }
+
+ // 娉ㄦ剰锛氭柊鐗堟湰妯″紡鍒囨崲浣跨敤锛坉ev銆乼est銆乸rod銆乻afe锛�
+ else if (mode == "dev") {
+ //寮�鍙戞ā寮�
+ commonObj.systemWithRes(`echo 'dev' > /etc/.mode_v1`, 2)
+ } else if (mode == "test") {
+ //娴嬭瘯妯″紡锛堣瘯浜фā寮忥級
+ commonObj.systemWithRes(`echo 'test' > /etc/.mode_v1`, 2)
+ } else if (mode == "prod") {
+ //鐢熶骇妯″紡
+ commonObj.systemWithRes(`echo 'prod' > /etc/.mode_v1`, 2)
+ } else if (mode == "safe") {
+ //瀹夊叏妯″紡
+ commonObj.systemWithRes(`echo 'safe' > /etc/.mode_v1`, 2)
+ } else {
+ return false
+ }
+ commonObj.systemWithRes(`sync`, 2)
+ commonObj.asyncReboot(2)
+ return true
+}
+
+/**
+ * 鏌ヨ璁惧妯″紡
+ * @description 鑾峰彇璁惧褰撳墠妯″紡
+ * @returns 涓氬姟妯″紡锛�1锛屽紑鍙戞ā寮忥細2锛屽伐鍘傛ā寮忥細28锛� 寮傚父妯″紡锛�-1
+ */
+common.getMode = function () {
+ let ret = commonObj.systemWithRes(`test -e "/etc/.mode" && echo "OK" || echo "NO"`, 2)
+ if (ret.includes('NO')) {
+ return 28
+ }
+ let mode = commonObj.systemWithRes(`cat "/etc/.mode"`, 10)
+ if (mode.includes('app')) {
+ return 1
+ } else if (mode.includes('debug')) {
+ return 2
+ } else {
+ return -1
+ }
+}
+/**
+ * 鍗佸叚杩涘埗杞瓧鑺傛暟缁� eg:313233616263->[49,50,51,97,98,99]
+ * @param {string} str 16杩涘埗瀛楃涓� 灏忓啓涓斾腑闂存棤绌洪殧鐨勫崄鍏繘鍒跺瓧绗︿覆
+ * @returns 鏁板瓧鏁板瓧
+ */
+common.hexToArr = function (str) {
+ if (str === undefined || str === null || (typeof str) != 'string' || str.length < 1) {
+ throw new Error("dxCommon.hexToArr:'str' parameter should not be empty")
+ }
+ let regex = /.{2}/g;
+ let arr = str.match(regex);
+ return arr.map(item => parseInt(item, 16));
+}
+/**
+ * 瀛楄妭鏁扮粍杞崄鍏繘鍒� eg:[49,50,51,97,98,99]->313233616263
+ * @param {array}numbers 鏁板瓧鏁扮粍
+ * @returns str 16杩涘埗瀛楃涓� 灏忓啓涓斾腑闂存棤绌洪殧鐨勫崄鍏繘鍒跺瓧绗︿覆
+ */
+common.arrToHex = function (numbers) {
+ const hexArray = numbers.map(num => num.toString(16).padStart(2, '0').toLowerCase());
+ const hexString = hexArray.join('');
+ return hexString;
+}
+/**
+ * 鍗佸叚杩涘埗杞瓧绗︿覆 eg:313233616263->123abc
+ * 娉ㄦ剰濡傛灉16杩涘埗瀛楃涓叉槸鐢变腑鏂囪浆杩囧幓鐨勶紝鍐嶈浆鍥炰腑鏂囧瓧绗︿覆浼氭湁涔辩爜锛屽洜涓烘槸涓�涓竴涓瓧鑺傜殑杞崲
+ * @param {string} str 瑕佽浆鐨�16杩涘埗瀛楃涓�
+ * @returns
+ */
+common.hexToString = function (str) {
+ let regex = /.{2}/g;
+ let arr = str.match(regex);
+ arr = arr.map(item => String.fromCharCode(parseInt(item, 16)));
+ return arr.join("");
+}
+// 灏嗗瓧绗︿覆杞崲涓� UTF-8 缂栫爜鐨�16杩涘埗瀛楃涓�
+common.strToUtf8Hex = function (str) {
+ const bytes = [];
+ for (let i = 0; i < str.length; i++) {
+ let code = str.charCodeAt(i);
+ if (code < 0x80) {
+ bytes.push(code);
+ } else if (code < 0x800) {
+ bytes.push(0xc0 | (code >> 6), 0x80 | (code & 0x3f));
+ } else if (code < 0xd800 || code >= 0xe000) {
+ bytes.push(0xe0 | (code >> 12), 0x80 | ((code >> 6) & 0x3f), 0x80 | (code & 0x3f));
+ } else {
+ // 澶勭悊 Unicode 缂栫爜
+ i++;
+ code = 0x10000 + (((code & 0x3ff) << 10) | (str.charCodeAt(i) & 0x3ff));
+ bytes.push(
+ 0xf0 | (code >> 18),
+ 0x80 | ((code >> 12) & 0x3f),
+ 0x80 | ((code >> 6) & 0x3f),
+ 0x80 | (code & 0x3f)
+ );
+ }
+ }
+ return this.arrToHex(bytes);
+}
+/**
+ * 浼犻�掕繃鏉ョ殑utf-8鐨�16杩涘埗瀛楃涓茶浆鎹㈡垚瀛楃涓�
+ * @param {string} hex
+ * @returns
+ */
+common.utf8HexToStr = function (hex) {
+ let array = this.hexToArr(hex)
+ var out, i, len, c;
+ var char2, char3;
+
+ out = "";
+ len = array.length;
+ i = 0;
+ while (i < len) {
+ c = array[i++];
+ switch (c >> 4) {
+ case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
+ // 0xxxxxxx
+ out += String.fromCharCode(c);
+ break;
+ case 12: case 13:
+ // 110x xxxx 10xx xxxx
+ char2 = array[i++];
+ out += String.fromCharCode(((c & 0x1F) << 6) | (char2 & 0x3F));
+ break;
+ case 14:
+ // 1110 xxxx 10xx xxxx 10xx xxxx
+ char2 = array[i++];
+ char3 = array[i++];
+ out += String.fromCharCode(((c & 0x0F) << 12) |
+ ((char2 & 0x3F) << 6) |
+ ((char3 & 0x3F) << 0));
+ break;
+ }
+ }
+
+ return out;
+}
+/**
+ * 瀛楃涓茶浆鍗佸叚杩涘埗 eg:123abc->313233616263
+ * @param {string} str 瑕佽浆鐨勫瓧绗︿覆
+ * @returns
+ */
+common.stringToHex = function (str) {
+ if (str === undefined || str === null || typeof (str) != "string") {
+ return null
+ }
+ let val = "";
+ for (let i = 0; i < str.length; i++) {
+ val += str.charCodeAt(i).toString(16)
+ }
+ return val
+}
+
+/**
+ * 灏忕鏍煎紡杞崄杩涘埗鏁� eg:001001->69632
+ * @param {string} hexString 16杩涘埗瀛楃涓� 灏忓啓涓斾腑闂存棤绌洪殧鐨勫崄鍏繘鍒跺瓧绗︿覆
+ * @returns 鏁板瓧
+ */
+common.littleEndianToDecimal = function (hexString) {
+ // 灏嗗皬绔牸寮忕殑鍗佸叚杩涘埗瀛楃涓茶繘琛屽弽杞�
+ let reversedHexString = hexString
+ .match(/.{2}/g) // 姣忎袱涓瓧绗﹀垎闅�
+ .reverse() // 鍙嶈浆鏁扮粍
+ .join(""); // 鍚堝苟涓哄瓧绗︿覆
+
+ // 灏嗗弽杞悗鐨勫崄鍏繘鍒跺瓧绗︿覆杞崲涓哄崄杩涘埗鏁�
+ let decimal = parseInt(reversedHexString, 16);
+ return decimal;
+}
+
+
+/**
+ * 鍗佽繘鍒舵暟杞崲涓�16杩涘埗灏忕鏍煎紡瀛楃涓�
+ * eg:300->2c01
+ * eg:230->e600
+ * @param {number} decimalNumber 鍗佽繘鍒舵暟瀛�,蹇呭~
+ * @param {number} byteSize 鐢熸垚浣嶆暟 瀛楄妭鐨勪釜鏁帮紝濡傛灉瓒呭嚭瀹為檯瀛楄妭涓暟锛屼細鍦ㄥ彸杈硅ˉ0锛屼綆浜庝細鎴彇锛岄潪蹇呭~锛岀己鐪佹槸2
+ * @returns
+ */
+common.decimalToLittleEndianHex = function (decimalNumber, byteSize) {
+ if (decimalNumber === undefined || decimalNumber === null || (typeof decimalNumber) != 'number') {
+ throw new Error("dxCommon.decimalToLittleEndianHex:'decimalNumber' parameter should be number")
+ }
+ if (byteSize === undefined || byteSize === null || (typeof byteSize) != 'number' || byteSize <= 0) {
+ byteSize = 2
+ }
+ const littleEndianBytes = [];
+ for (let i = 0; i < byteSize; i++) {
+ littleEndianBytes.push(decimalNumber & 0xFF);
+ decimalNumber >>= 8;//鐩稿綋浜庨櫎浠�256
+ }
+ const littleEndianHex = littleEndianBytes
+ .map((byte) => byte.toString(16).padStart(2, '0'))
+ .join('');
+ return littleEndianHex;
+}
+
+/**
+ * 灏�16杩涘埗瀛楃涓茶浆鎹负ArrayBuffer
+ * @param {*} hexString 瑕佽浆鎹㈢殑16杩涘埗瀛楃涓�
+ * @returns
+ */
+common.hexStringToArrayBuffer = function (hexString) {
+ return this.hexStringToUint8Array(hexString).buffer;
+}
+
+/**
+ * 灏�16杩涘埗瀛楃涓茶浆鎹负Uint8Array
+ * @param {string} hexString 瑕佽浆鎹㈢殑16杩涘埗瀛楃涓诧紝灏忓啓涓斾腑闂存棤绌洪殧鐨勫崄鍏繘鍒跺瓧绗︿覆
+ * @returns Uint8Array瀵硅薄
+ */
+common.hexStringToUint8Array = function (hexString) {
+ if (hexString === undefined || hexString === null || (typeof hexString) != 'string' || hexString.length <= 0) {
+ throw new Error("dxCommon.hexStringToUint8Array:'hexString' parameter should not be empty")
+ }
+ let byteString = hexString.match(/.{1,2}/g);
+ let byteArray = byteString.map(function (byte) {
+ return parseInt(byte, 16);
+ });
+ let buffer = new Uint8Array(byteArray);
+ return buffer;
+}
+
+/**
+ * 灏� ArrayBuffer 杞崲涓哄崄鍏繘鍒跺瓧绗︿覆鏍煎紡
+ * @param {ArrayBuffer} buffer
+ * @returns 灏忓啓涓斾腑闂存棤绌洪殧鐨勫崄鍏繘鍒跺瓧绗︿覆
+ */
+common.arrayBufferToHexString = function (buffer) {
+ return this.uint8ArrayToHexString(new Uint8Array(buffer))
+}
+/**
+ * 灏� Uint8Array 杞崲涓哄崄鍏繘鍒跺瓧绗︿覆鏍煎紡
+ * @param {Uint8Array} array
+ * @returns 灏忓啓涓斾腑闂存棤绌洪殧鐨勫崄鍏繘鍒跺瓧绗︿覆
+ */
+common.uint8ArrayToHexString = function (array) {
+ let hexString = '';
+ for (let i = 0; i < array.length; i++) {
+ const byte = array[i].toString(16).padStart(2, '0');
+ hexString += byte;
+ }
+ return hexString
+}
+/**
+ * 璁剧疆/鑾峰彇缁勪欢鍙ユ焺id閫氱敤鏂规硶
+ * @param {string} name 缁勪欢鍚嶏紝蹇呭~
+ * @param {string} id 鍙ユ焺id锛岄潪蹇呭~
+ * @param {number} pointer 鍙ユ焺鎸囬拡鏁板瓧锛岄潪蹇呭~
+ * @returns
+ */
+common.handleId = function (name, id, pointer) {
+ // 缁勪欢鍚嶄笉鑳戒负绌�
+ if (name === undefined || name === null || name === "" || typeof name !== 'string') {
+ return
+ }
+ let map = dxMap.get('handleIds')
+ // 鍙ユ焺id
+ if (id === undefined || id === null || id === "" || typeof id !== 'string') {
+ id = "__" + name + "_default"
+ }
+ if (pointer === undefined || pointer === null || typeof pointer !== 'number') {
+ // pointer涓虹┖鍒欎负鑾峰彇
+ return map.get(id)
+ } else {
+ // pointer涓嶄负绌哄垯涓鸿缃�
+ let isExist = map.get(id)
+ if (isExist) {
+ // 鍙ユ焺宸插瓨鍦�
+ return
+ }
+ map.put(id, pointer)
+ }
+}
+
+
+export default common
\ No newline at end of file
diff --git a/vf205_access/dxmodules/dxConfig.js b/vf205_access/dxmodules/dxConfig.js
new file mode 100644
index 0000000..0f4844e
--- /dev/null
+++ b/vf205_access/dxmodules/dxConfig.js
@@ -0,0 +1,140 @@
+/**
+ * 瀹炵幇瀵瑰簲鐢ㄦ墍鏈夐厤缃」锛坘ey/value)鐨勭鐞嗭細
+ * 1. 鐢ㄦ埛闇�瑕佹妸鍒濆鐨勯厤缃」淇濆瓨鍦ㄩ」鐩殑 src/config.json 锛岄厤缃枃浠剁殑鏍煎紡璇蜂繚鐣檏ey/value鏍煎紡锛堟敮鎸佹敞閲�)锛寁alue鍙兘鏄瓧绗︿覆鍜屾暟瀛楃被鍨�,渚嬪锛�
+ * {
+ * //mqtt鐩稿叧閰嶇疆
+ * "mqtt.ip":"192.168.2.3",
+ * "mqtt.port":6199,
+ * }
+ * 2. 涔熸敮鎸佽嚜瀹氫箟閰嶇疆鏂囦欢锛屽垵濮嬪寲鍙互浼犻�掕嚜瀹氫箟閰嶇疆鏂囦欢鐨勮矾寰勫拰鏍囪瘑锛屽悗缁鍐欐暟鎹兘闇�瑕佷紶閫掕繖涓爣璇�
+ * 3. 鐢ㄦ埛鍦ㄥ簲鐢ㄤ腑绗竴娆′娇鐢ㄨ繖涓粍浠讹紝闇�瑕佸厛鍒濆鍖� init锛屽垵濮嬪寲浼氭妸 config.json 鐨勬暟鎹繚瀛樺埌鍐呭瓨閲岋紝浠ュ悗姣忔鑾峰彇閮芥槸浠庡唴瀛樿幏鍙�
+ * 4. 鐢ㄦ埛鍙互鍦ㄤ换浣曞湴鏂归兘鍙互閫氳繃 get 鍜� set 鏉ヨ鍐欓厤缃�
+ * 5. 濡傛灉淇敼閰嶇疆椤圭殑 value 鍚屾椂闇�瑕佷繚瀛樺埌閰嶇疆鏂囦欢锛堜繚璇侀噸鍚悗鏂伴厤缃敓鏁堬級锛屼娇鐢� setAndSave
+ * 6. 濡傛灉闇�瑕佹仮澶嶆墍鏈夐粯璁ら厤缃紝浣跨敤 reset
+ */
+import * as os from 'os';
+import dxMap from './dxMap.js'
+import common from './dxCommon.js'
+import logger from './dxLogger.js'
+import std from './dxStd.js'
+
+const map = dxMap.get("default")
+
+const config = {}
+const DEFALUT_OPTIONS = { path: '/app/code/src/config.json', savePath: '/app/data/config/config.json', flag: '___config.' }
+
+/**
+ * 鍒濆鍖栦細鎶� config.json 鎴栬嚜瀹氫箟鐨勯厤缃枃浠剁殑鏁版嵁淇濆瓨鍒板唴瀛橀噷锛屼互鍚庢瘡娆¤幏鍙栭兘鏄粠鍐呭瓨鑾峰彇
+ * @param {object} custom 闈炲繀濉紝鑷畾涔夌殑閰嶇疆鏂囦欢
+ * @param {string} custom.path 鑷畾涔夌殑閰嶇疆鏂囦欢瀹屾暣璺緞
+ * @param {string} custom.flag 鑷畾涔夐厤缃枃浠剁殑鏍囪瘑锛屾敞鎰忓鏋滄湁澶氫釜鑷畾涔夐厤缃枃浠讹紝杩欎釜鏍囪瘑涓嶈閲嶅
+ */
+config.init = function (custom) {
+ if (custom) {
+ if (!custom.path || !custom.flag) {
+ throw new Error('The path and flag for the custom configuration file cannot be empty.')
+ }
+ }
+ let flag = custom ? DEFALUT_OPTIONS.flag + custom.flag + '.' : DEFALUT_OPTIONS.flag;
+ const isInited = map.get('___inited' + flag)
+ if (isInited) {//鍙垵濮嬪寲涓�娆�
+ return
+ }
+ let path = custom ? custom.path : DEFALUT_OPTIONS.path
+ let savePath = custom ? '/app/data/config/config' + custom.flag + '.json' : DEFALUT_OPTIONS.savePath
+ if (!std.exist(path)) {
+ throw new Error('The config file not existed:' + path)
+ }
+ let existed = std.exist(savePath)
+ let content = existed ? std.parseExtJSON(std.loadFile(savePath)) : std.parseExtJSON(std.loadFile(path))
+ if (!existed) {
+ std.saveFile(savePath, JSON.stringify(content))
+ }
+ for (let [key, value] of Object.entries(content)) {
+ map.put(flag + key, value)
+ }
+ map.put('___inited' + flag, 'ok')
+}
+/**
+ * 鑾峰彇鎵�鏈夐厤缃」
+ * @param {string} flag 鑷畾涔夌殑閰嶇疆鏂囦欢鏍囪瘑锛屽彲浠ヤ负绌猴紝涓虹┖鍒欒繑鍥炵己鐪乧onfig.json閲屾墍鏈夊唴瀹�
+ * @returns json瀵硅薄
+ */
+config.getAll = function (flag) {
+ let _flag = _getFlag(flag)
+ let configInfo = {}
+ let keys = map.keys().filter(k => k.startsWith(_flag))
+ keys.forEach(k => {
+ let key = k.substring(_flag.length)
+ let val = map.get(k)
+ configInfo[key] = val
+ })
+ return configInfo
+}
+/**
+ * 鑾峰彇閰嶇疆锛屽彧浠巑ap鑾峰彇
+ * 濡傛灉閰嶇疆椤逛负绌猴紝杩斿洖鎵�鏈夋墍鏈夋暟鎹紱
+ * @param {string} key 閰嶇疆椤�
+ * @param {string} flag 鑷畾涔夌殑閰嶇疆鏂囦欢鏍囪瘑锛屽彲浠ヤ负绌猴紝涓虹┖鍒欒繑鍥炵己鐪乧onfig.json閲岀殑閰嶇疆鍊�
+ * @returns
+ */
+config.get = function (key, flag) {
+ if (!key) {
+ return this.getAll(flag);
+ }
+ let _flag = _getFlag(flag)
+ return map.get(_flag + key)
+}
+
+/**
+ * 鏇存柊閰嶇疆锛屽彧淇敼map
+ * @param {string} key 閰嶇疆椤�
+ * @param {string} value 閰嶇疆鍊�
+ * @param {string} flag 鑷畾涔夌殑閰嶇疆鏂囦欢鏍囪瘑锛屽彲浠ヤ负绌猴紝涓虹┖鍒欐寚鍚戠己鐪乧onfig.json閲岀殑閰嶇疆鍊�
+ */
+config.set = function (key, value, flag) {
+ if (!key || value == null || value == undefined) {
+ throw new Error("key or value should not be empty")
+ }
+ let _flag = _getFlag(flag)
+ map.put(_flag + key, value)
+}
+
+/**
+ * 灏唌ap涓殑鏁版嵁鎸佷箙鍖栧埌鏈湴
+ * @param {string} flag 鑷畾涔夌殑閰嶇疆鏂囦欢鏍囪瘑锛屽彲浠ヤ负绌猴紝涓虹┖鍒欐寚鍚戠己鐪乧onfig.json閲岀殑閰嶇疆鍊�
+ */
+config.save = function (flag) {
+ //淇濆瓨
+ std.saveFile(_getSavePath(flag), JSON.stringify(this.getAll(flag)))
+}
+
+/**
+ * 鏇存柊閰嶇疆锛屼慨鏀筸ap涓旀寔涔呭寲鏈湴
+ * @param {string} key 閰嶇疆椤�
+ * @param {string} value 閰嶇疆鍊�
+ * @param {string} flag 鑷畾涔夌殑閰嶇疆鏂囦欢鏍囪瘑锛屽彲浠ヤ负绌猴紝涓虹┖鍒欐寚鍚戠己鐪乧onfig.json閲岀殑閰嶇疆鍊�
+ */
+config.setAndSave = function (key, value, flag) {
+ this.set(key, value, flag)
+ //淇濆瓨
+ std.saveFile(_getSavePath(flag), JSON.stringify(this.getAll(flag)))
+}
+
+/**
+ * 閲嶇疆锛岄噸缃悗璇烽噸鍚姩璁惧
+ * @param {string} flag 鑷畾涔夌殑閰嶇疆鏂囦欢鏍囪瘑锛屽彲浠ヤ负绌猴紝涓虹┖鍒欐寚鍚戠己鐪乧onfig.json閲岀殑閰嶇疆鍊�
+ */
+config.reset = function (flag) {
+ common.systemBrief('rm -rf ' + _getSavePath(flag))
+}
+
+//-------------------private-------------------------------
+
+function _getFlag(flag) {
+ return flag ? DEFALUT_OPTIONS.flag + flag + '.' : DEFALUT_OPTIONS.flag
+}
+function _getSavePath(flag) {
+ return flag ? '/app/data/config/config' + flag + '.json' : DEFALUT_OPTIONS.savePath
+}
+export default config;
\ No newline at end of file
diff --git a/vf205_access/dxmodules/dxDriver.js b/vf205_access/dxmodules/dxDriver.js
new file mode 100644
index 0000000..f1d77e4
--- /dev/null
+++ b/vf205_access/dxmodules/dxDriver.js
@@ -0,0 +1,81 @@
+const dxDriver = {}
+
+/*************************************Device Resource Enumeration*************************************/
+
+/**
+ * GPIO device pins
+ */
+dxDriver.GPIO = {
+
+ // Relay
+ RELAY0: 44,
+}
+
+/**
+ * Channel communication
+ */
+dxDriver.CHANNEL = {
+
+ // 485
+ UART_PATH: "/dev/ttySLB2",
+
+ // USBHID
+ USBHID_PATH: "/dev/hidg1",
+}
+
+/**
+ * Camera related parameters
+ */
+dxDriver.CAPTURER = {
+ // Camera image width
+ RGB_WIDTH: 1280,
+ // Camera image height
+ RGB_HEIGHT: 800,
+ // Camera device files
+ RGB_PATH: "/dev/video3",
+
+ // Camera image width
+ NIR_WIDTH: 800,
+ // Camera image height
+ NIR_HEIGHT: 600,
+ // Camera device files
+ NIR_PATH: "/dev/video0"
+}
+
+/**
+ * PWM channel
+ */
+dxDriver.PWM = {
+
+ // Fill light
+ WHITE_SUPPLEMENT_CHANNEL: 4,
+ WHITE_SUPPLEMENT_PERIOD_NS: 255000,
+ WHITE_SUPPLEMENT_DUTY: 255000 * 255 / 255,
+
+ NIR_SUPPLEMENT_CHANNEL: 7,
+ NIR_SUPPLEMENT_PERIOD_NS: 255000,
+ NIR_SUPPLEMENT_DUTY: 255000 * 255 / 255,
+}
+
+/**
+ * GPIO pin function enumeration
+ */
+dxDriver.GPIO_FUNC = {
+ GPIO_FUNC_3: 0x03, //0011, GPIO as function 3 / device 3
+ GPIO_OUTPUT0: 0x04, //0100, GPIO output low level
+ GPIO_OUTPUT1: 0x05 //0101, GPIO output high level
+};
+
+/**
+ * Door opening button
+ */
+dxDriver.GPIO_KEY_OPEN = 30
+
+/**
+ * Door magnetic status
+ */
+dxDriver.GPIO_KEY_SEN = 48
+
+
+
+export default dxDriver
\ No newline at end of file
diff --git a/vf205_access/dxmodules/dxEid.js b/vf205_access/dxmodules/dxEid.js
new file mode 100644
index 0000000..f354aa2
--- /dev/null
+++ b/vf205_access/dxmodules/dxEid.js
@@ -0,0 +1,46 @@
+import { eidClass } from './libvbar-m-dxeid.so'
+const eidObj = new eidClass();
+
+const eid = {
+ /**
+ * @brief 浜戣瘉婵�娲�
+ * @param {string} sn 璁惧sn
+ * @param {string} version 涓氬姟鑷畾涔夌増鏈彿
+ * @param {string} mac 璁惧mac鍦板潃
+ * @param {string} codeMsg 浜戣瘉婵�娲荤爜鏁版嵁
+ * @returns
+ */
+ active: function(sn, version, mac, codeMsg){
+
+ if(!sn){
+ throw("sn should not be null or empty")
+ }
+ if(!version){
+ throw("version should not be null or empty")
+ }
+ if(!mac){
+ throw("mac should not be null or empty")
+ }
+ if(!codeMsg){
+ throw("codeMsg should not be null or empty")
+ }
+ return eidObj.active(sn, version, mac, codeMsg);
+ },
+ /**
+ * @brief 鑾峰彇淇℃伅
+ */
+ getInfo: function(){
+ if(data == null || data.length < 1){
+ throw("data should not be null or empty")
+ }
+ return eidObj.getInfo(data)
+ },
+ /**
+ * @brief 鑾峰彇鐗堟湰鍙�
+ */
+ getVersion: function(){
+ return eidObj.getVersion()
+ },
+}
+
+export default eid;
\ No newline at end of file
diff --git a/vf205_access/dxmodules/dxEventBus.js b/vf205_access/dxmodules/dxEventBus.js
new file mode 100644
index 0000000..4e450dd
--- /dev/null
+++ b/vf205_access/dxmodules/dxEventBus.js
@@ -0,0 +1,167 @@
+//build:20240628
+//浜嬩欢鎬荤嚎锛屽埄鐢╭uickjs鐨剋orker闂存暟鎹�氫俊鏉ュ疄鐜扮嚎绋嬩箣闂村彂閫佷簨浠堕�氱煡銆�
+//worker鍜寃orker涔嬮棿涓嶈兘鐩存帴閫氫俊锛岄渶瑕侀�氳繃parent(涓荤嚎绋�)鏉ヨ浆鍙戯紝鎵�浠ラ渶瑕佸疄鐜�5绉嶅彲鑳芥�х殑浜嬩欢閫氱煡
+//1. worker1--->parent--->worker2
+//2. worker3--->parent
+//3. parent--->worker4
+//4. parent<-->parent
+//5. worker5<--->worker5,涔熶細閫氳繃parent杞�
+//缁勪欢渚濊禆 dxLogger,dxCommon
+import std from './dxStd.js'
+import logger from './dxLogger.js'
+import * as os from "os";
+//-------------------------variable--------------------
+const bus = {}
+const all = {}
+const subs = {}
+const isMain = (os.Worker.parent === undefined)
+bus.id = isMain ? '__main' : null
+/**
+ * 鍦ㄦ�荤嚎涓婂惎鍔ㄤ竴涓獁orker锛岀粰瀹冨畾涔変竴涓敮涓�鐨刬d鏍囪瘑
+ * 鍥犱负worker鍙兘閫氳繃涓荤嚎绋嬪垱寤猴紝鎵�浠ewWorker鍑芥暟涔熷彧鑳藉湪涓荤嚎绋嬮噷鎵ц
+ * 娉ㄦ剰: worker瀵瑰簲鐨勬枃浠堕噷涓嶈兘鍖呭惈while(true)杩欑姝诲惊鐜紝鍚﹀垯灏辨敹涓嶅埌message锛屽彲浠ョ敤setInteval鏉ュ疄鐜板惊鐜�
+ * @param {string} id worker鐨勫敮涓�鏍囪瘑锛屼笉鑳戒负绌�
+ * @param {object} file worker瀵瑰簲鐨勬枃浠跺悕锛岀粷瀵硅矾寰勶紝閫氬父浠�'/app/code/src'寮�濮�
+ */
+bus.newWorker = function (id, file) {
+ if (!id) {
+ throw new Error("eventbus newWorker:'id' should not be empty")
+ } if (!file) {
+ throw new Error("eventbus newWorker:'file' should not be empty")
+ }
+ if (!isMain) {
+ throw new Error("evnetbus newWorker should be invoke in main thread")
+ }
+ if (!std.exist(file)) {
+ throw new Error("eventbus newWorker: file not found:" + file)
+ }
+ let content = std.loadFile(file) + `
+import __bus from '/app/code/dxmodules/dxEventBus.js'
+__bus.id='${id}'
+Object.keys(__bus.handlers).forEach(key => {
+ __bus.os.Worker.parent.postMessage({ __sub: key, id: __bus.id })
+})
+__bus.os.Worker.parent.onmessage = function (e) {
+ if(!e.data){
+ return
+ }
+ e = e.data
+ if (!e || !e.topic) {
+ return
+ }
+ let fun = __bus.handlers[e.topic]
+ if (fun) {
+ fun(e.data)
+ }
+}
+ `
+ let newfile = file + '_' + id + '.js'
+ std.saveFile(newfile, content)
+ let worker = new os.Worker(newfile)
+ all[id] = worker
+ worker.onmessage = function (data) {
+ if (data.data) {
+ if (data.data.__sub) {
+ sub(data.data.__sub, data.data.id)
+ return
+ }
+ //worker鍙戦�佽繃鏉ョ殑鏁版嵁鍐嶈皟鐢ㄤ竴娆′富绾跨▼鐨刦ire锛岃涔堜富绾跨▼鑷繁娑堣垂锛岃涔堣浆鍙戝埌鍏跺畠worker
+ bus.fire(data.data.topic, data.data.data)
+ }
+ }
+}
+/**
+ * 鏍规嵁id鍒犻櫎瀵瑰簲鐨剋orker锛岃繖鏍穡orker绾跨▼灏辫兘姝e父缁撴潫
+ * @param {string} id
+ */
+bus.delWorker = function (id) {
+ delete all[id]
+}
+/**
+ * 瑙﹀彂涓�涓簨浠讹紝杩欎釜浜嬩欢浼氱珛鍒诲彂閫佺粨鏉燂紝鎺ユ敹鍒版秷鎭殑澶勭悊濡傛灉姣旇緝鑰楁椂涓嶄細褰卞搷浜嬩欢鍙戦�佺殑椤哄簭鎴栧嚭鐜颁簨浠朵涪澶�
+ * 鍚屾牱涓�涓簨浠跺彲浠ユ湁澶氫釜璁㈤槄鑰咃紝鍙互鍚屾椂閫氱煡澶氫釜璁㈤槄鑰咃紝鍚屼竴涓猼opic鍗曚綅鏃堕棿鍐呭彧澶勭悊涓�涓簨浠讹紝
+ * 鍙湁褰撳墠topic琚墍鏈夌殑璁㈤槄鑰呭鐞嗗畬涔嬪悗鎵嶅厑璁稿鐞嗗悓涓�topic涓嬩竴涓簨浠�
+ *
+ * @param {string} topic 浜嬩欢鐨勬爣璇嗐�佷富棰�
+ * @param {*} data 浜嬩欢闄勫甫鐨勬暟鎹�
+ */
+bus.fire = function (topic, data) {
+ if (!topic || (typeof topic) != 'string') {
+ throw new Error("eventbus :'topic' should not be null");
+ }
+ if (isMain) {
+ if (subs[topic] && subs[topic].length > 0) {
+ for (let i = 0; i < subs[topic].length; i++) {
+ const id = subs[topic][i]
+ if (id === '__main' && bus.handlers[topic]) {
+ if (Array.isArray(bus.handlers[topic])) {
+ // 鎵ц鎵�鏈夋敞鍐岀殑澶勭悊鍑芥暟
+ for (let j = 0; j < bus.handlers[topic].length; j++) {
+ try {
+ bus.handlers[topic][j](data)
+ } catch (error) {
+ logger.error('Error in event handler for topic ' + topic + ': ' + error.message)
+ }
+ }
+ } else {
+ // 鍏煎鏃х増鏈紝鎵ц鍗曚釜澶勭悊鍑芥暟
+ try {
+ bus.handlers[topic](data)
+ } catch (error) {
+ logger.error('Error in event handler for topic ' + topic + ': ' + error.message)
+ }
+ }
+ } else {
+ const worker = all[id]
+ if (worker) {
+ worker.postMessage({ topic: topic, data: data })
+ }
+ }
+ }
+ }
+ } else {
+ os.Worker.parent.postMessage({ topic: topic, data: data })
+ }
+}
+
+
+bus.handlers = {}
+/**
+ * 璁㈤槄涓�涓簨浠�
+ * @param {string} topic 浜嬩欢鐨勬爣璇嗐�佷富棰� 锛屽繀濉�
+ * @param {function} callback 浜嬩欢澶勭悊鐨勫洖璋冨嚱鏁帮紝蹇呭~
+ */
+bus.on = function (topic, callback) {
+ if (!topic || (typeof topic) != 'string') {
+ throw new Error("The 'topic' should not be null");
+ }
+ if (!callback || (typeof callback) != 'function') {
+ throw new Error("The 'callback' should be a function");
+ }
+ sub(topic, bus.id)
+ // 鏀寔澶氫釜浜嬩欢澶勭悊鍑芥暟
+ if (!this.handlers[topic]) {
+ this.handlers[topic] = []
+ }
+ if (!Array.isArray(this.handlers[topic])) {
+ // 鍏煎鏃х増鏈紝灏嗗崟涓嚱鏁拌浆鎹负鏁扮粍
+ this.handlers[topic] = [this.handlers[topic]]
+ }
+ this.handlers[topic].push(callback)
+}
+function sub(topic, id) {
+ if (isMain) {
+ if (!subs[topic]) {
+ subs[topic] = []
+ }
+ if (!subs[topic].includes(id)) {
+ subs[topic].push(id)
+ }
+ } else {
+ if (id != null) {
+ os.Worker.parent.postMessage({ __sub: topic, id: id })
+ }
+ }
+}
+bus.os = os
+export default bus
diff --git a/vf205_access/dxmodules/dxFace.js b/vf205_access/dxmodules/dxFace.js
new file mode 100644
index 0000000..a12d723
--- /dev/null
+++ b/vf205_access/dxmodules/dxFace.js
@@ -0,0 +1,287 @@
+//build: 20250513
+//渚濊禆缁勪欢:dxDriver锛宒xStd锛宒xLogger锛宒xMap锛宒xEventBus,dxCommon
+import { faceClass } from './libvbar-b-dxface.so'
+import dxCommon from './dxCommon.js'
+import bus from './dxEventBus.js'
+const faceObj = new faceClass();
+const face = {}
+
+/**
+ * 浜鸿劯澶勭悊鍒濆鍖�
+ * @param {object} options 閰嶇疆鍙傛暟锛屽ぇ閮ㄥ垎鍙互鐢ㄩ粯璁ゅ��
+ * @param {string} options.rgbPath 蹇呭~锛宺gb鍥惧儚閲囬泦璁惧璺緞锛屾瘡绉嶈澶囨湁宸紓锛屾瘮濡侱W200瀵瑰簲鐨勫�兼槸'/dev/video11', M500瀵瑰簲鐨�'/dev/video0'
+ * @param {string} options.nirPath 蹇呭~锛岀孩澶栧浘鍍忛噰闆嗚澶囪矾寰勶紝姣忕璁惧鏈夊樊寮�
+ * @param {string} options.dbPath 鏁版嵁搴撹矾寰勶紝蹇呭~
+ * @param {number} options.score 鐗瑰緛鍊煎姣旀垚鍔熸墍闇�鏈�浣庡姣斿緱鍒� 锛岄潪蹇呭~锛堢己鐪�0.6锛�
+ * @param {number} options.dbMax 鍐呭瓨涓姞杞界殑鏈�澶х壒寰佸垪琛ㄦ暟閲忥紝闈炲繀濉紙缂虹渷5000锛�
+ * @param {string} options.mapPath 鏍囧畾缁撴灉鏂囦欢璺緞锛岄潪蹇呭~
+ * @param {string} options.picPath 淇濆瓨瀹屾暣浜鸿劯鐓х墖璺緞锛岄潪蹇呭~
+ * @param {string} capturerRgbId 蹇呭~锛宺gb鍙栧浘鍙ユ焺id
+ * @param {string} capturerNirId 蹇呭~锛宯ir鍙栧浘鍙ユ焺id
+ * @returns true/false
+ */
+face.init = function (options, capturerRgbId, capturerNirId) {
+ if (options.rgbPath === undefined || options.rgbPath === null || options.rgbPath.length < 1) {
+ throw new Error("dxFace.init: 'rgbPath' parameter should not be null or empty")
+ }
+ if (options.nirPath === undefined || options.nirPath === null || options.nirPath.length < 1) {
+ throw new Error("dxFace.init: 'nirPath' parameter should not be null or empty")
+ }
+ if (capturerRgbId === undefined || capturerRgbId === null || capturerRgbId.length < 1) {
+ throw new Error("dxFace.init: 'capturerRgbId' parameter should not be null or empty")
+ }
+ if (capturerNirId === undefined || capturerNirId === null || capturerNirId.length < 1) {
+ throw new Error("dxFace.init: 'capturerNirId' parameter should not be null or empty")
+ }
+ capturerRgbId = dxCommon.handleId("capturer", capturerRgbId)
+ capturerNirId = dxCommon.handleId("capturer", capturerNirId)
+
+ return faceObj.init(options, capturerRgbId, capturerNirId);
+}
+/**
+ * 浜鸿劯澶勭悊鍘诲垵濮嬪寲
+ * @returns true/false
+ */
+face.deinit = function () {
+ return faceObj.deinit();
+}
+
+/**
+ * 浜鸿劯宸ヤ綔妯″紡
+ * @param {number} mode 宸ヤ綔妯″紡锛屽繀濉紙 0 浜鸿劯璇嗗埆妯″紡锛�1 浜鸿劯娉ㄥ唽妯″紡锛�
+ * @returns true/false
+ */
+face.setRecgMode = function (mode) {
+ if (mode === undefined || mode === null) {
+ throw new Error("dxFace.setRecgMode: 'mode' parameter should not be null or empty")
+ }
+ return faceObj.setRecgMode(mode)
+}
+/**
+ * 浜鸿劯娉ㄥ唽
+ * @param {string} userId 浜哄憳ID锛屽繀濉�
+ * @param {string} feature 鐗瑰緛鍊� base64瀛楃涓诧紝蹇呭~
+ * @returns 0:鎴愬姛/闈�0:澶辫触
+ */
+face.addFaceFeatures = function (userId, feature) {
+ if (userId === undefined || userId === null) {
+ throw new Error("dxFace.addFaceFeatures: 'userId' parameter should not be null or empty")
+ }
+ if (feature === undefined || feature === null) {
+ throw new Error("dxFace.addFaceFeatures: 'feature' parameter should not be null or empty")
+ }
+
+ return faceObj.addFaceFeatures(userId, feature)
+}
+/**
+ * 浜鸿劯鐗瑰緛鍊煎姣�
+ * @param {string} feature 鐗瑰緛鍊� base64瀛楃涓诧紝蹇呭~
+ * @param {string} score 姣斿闃堝�硷紝闈炲繀濉紝榛樿0.6
+ * @returns string userId
+ */
+face.faceFeatureCompare = function (feature, score) {
+ if (feature === undefined || feature === null) {
+ throw new Error("dxFace.faceFeatureCompare: 'feature' parameter should not be null or empty")
+ }
+ return faceObj.faceFeatureCompare(feature, score)
+}
+/**
+ * 鏇存柊閰嶇疆
+ * @param {object} options 娉ㄥ唽鍙傛暟锛岀敱娉ㄥ唽鍥炶皟鑾峰彇锛屽弬鑰僨ace.addFaceFeatures鏂规硶
+ * @returns true/false
+ */
+face.faceUpdateConfig = function (options) {
+ if (options === null || options === undefined) {
+ throw new Error("dxFace.faceUpdateConfig: 'options' parameter should not be null or empty")
+ }
+ return faceObj.faceUpdateConfig(options)
+}
+/**
+ * 浜鸿劯鍒犻櫎
+ * @param {string} userId 浜哄憳ID锛屽繀濉�
+ * @returns true/false
+ */
+face.deleteFaceFeatures = function (userId) {
+ if (userId === null || userId === undefined) {
+ throw new Error("dxFace.deleteFaceFeatures: 'userId' parameter should not be null or empty")
+ }
+ return faceObj.deleteFaceFeatures(userId)
+}
+/**
+ * 鏍规嵁鐓х墖璺緞鍜寀serId娉ㄥ唽浜鸿劯
+ * @param {string} userId 鐢ㄦ埛id锛屽繀濉�
+ * @param {string} picPath 鐓х墖璺緞锛屽繀濉�
+ * @returns true/false
+ */
+face.registerFaceByPicFile = function (userId, picPath) {
+ if (userId === undefined || userId === null || userId.length < 1) {
+ throw new Error("dxFace.registerFaceByPicFile: 'userId' parameter should not be null or empty")
+ }
+ if (picPath === undefined || picPath === null || picPath.length < 1) {
+ throw new Error("dxFace.registerFaceByPicFile: 'picPath' parameter should not be null or empty")
+ }
+ return faceObj.registerFaceByPicFile(userId, picPath)
+}
+/**
+ * 浜鸿劯绾跨▼鍚敤/绂佺敤锛屽姛鑳藉紑鍏�
+ * @param {bool} en 鍚敤銆佺鐢紝蹇呭~
+ * @returns true/false
+ */
+face.faceSetEnable = function (en) {
+ if (en === undefined || en === null) {
+ throw new Error("dxFace.faceSetEnable: 'en' parameter should not be null or empty")
+ }
+ return faceObj.detectSetEnable(en ? 0 : -1)
+}
+
+/**
+ * 閲嶇疆浜鸿劯鐘舵��
+ * @returns
+ */
+face.resetFaceStatus = function () {
+ return faceObj.resetFaceStatus()
+}
+
+/**
+ * 娓呯┖浜鸿劯鏁版嵁
+ * @returns true/false
+ */
+face.faceFeaturesClean = function () {
+ return faceObj.faceFeaturesClean()
+}
+
+/**
+ * 鑾峰彇灞忓箷浜害
+ * @returns number 灞忓箷浜害
+ */
+face.getDisplayBacklight = function () {
+ return faceObj.getDisplayBacklight()
+}
+/**
+ * 璁剧疆灞忓箷浜害
+ * @param {number} light 灞忓箷浜害锛屽繀濉�
+ * @returns true/false
+ */
+face.setDisplayBacklight = function (light) {
+ if (light === undefined || light === null) {
+ throw new Error("dxFace.setDisplayBacklight: 'light' parameter should not be null or empty")
+ }
+ return faceObj.setDisplayBacklight(light)
+}
+/**
+ * 鑾峰彇灞忓箷鐘舵��
+ * @returns number 0-绂佺敤 1-鍚敤
+ */
+face.getEnableStatus = function () {
+ return faceObj.getEnableStatus()
+}
+/**
+ * 璁剧疆灞忓箷鐘舵��
+ * @param {number} enable 0-绂佺敤 1-鍚敤
+ * @returns true/false
+ */
+face.setEnableStatus = function (enable) {
+ if (enable === undefined || enable === null) {
+ throw new Error("dxFace.setEnableStatus: 'enable' parameter should not be null or empty")
+ }
+ return faceObj.setEnableStatus(enable)
+}
+/**
+/**
+ * 鑾峰彇灞忓箷鐘舵��
+ * @returns number 0-NORMAL 1-STANDBY
+ */
+face.getPowerMode = function () {
+ return faceObj.getPowerMode()
+}
+/**
+ * 璁剧疆灞忓箷鐘舵��
+ * @param {number} mode 0-NORMAL 1-STANDBY
+ * @returns true/false
+ */
+face.setPowerMode = function (mode) {
+ if (mode === undefined || mode === null) {
+ throw new Error("dxFace.setPowerMode: 'mode' parameter should not be null or empty")
+ }
+ return faceObj.setPowerMode(mode)
+}
+/**
+ * 鑾峰彇鐜鍏�
+ * @returns number 鐜鍏変寒搴�
+ */
+face.getEnvBrightness = function () {
+ return faceObj.getEnvBrightness()
+}
+/**
+ * 鑾峰彇浜鸿劯鍧愭爣
+ * @returns string 浜鸿劯鍧愭爣JSON
+ */
+face.getTrackingBox = function () {
+ return faceObj.getTrackingBox()
+}
+/**
+ * 鏌ヨ鐢ㄦ埛鎬绘暟
+ * @returns number
+ */
+face.selectCount = function () {
+ return faceObj.selectFaceFeatures(1)
+}
+/**
+ * 鏌ヨ鎵�鏈塽serId
+ * @returns JSON
+ */
+face.selectAll = function () {
+ return faceObj.selectFaceFeatures(2)
+}
+/**
+ * 鍒ゆ柇鐢ㄦ埛鏄惁瀛樺湪
+ * @returns true/false
+ */
+face.userExist = function (userId) {
+ return faceObj.selectFaceFeatures(3, userId)
+}
+/**
+ * 鍒ゆ柇face娑堟伅闃熷垪鏄惁涓虹┖
+ * @returns true/false
+ */
+face.msgIsEmpty = function () {
+ return faceObj.msgIsEmpty()
+}
+/**
+ * 浠巉ace娑堟伅闃熷垪涓鍙栨暟鎹�
+ * @returns json
+ */
+face.msgReceive = function () {
+ return JSON.parse(faceObj.msgReceive());
+}
+
+face.RECEIVE_MSG = '__face__MsgReceive'
+
+/**
+ * 鐢ㄤ簬绠�鍖杅ace缁勪欢寰厜閫氫俊鍗忚鐨勪娇鐢紝鎶奻ace灏佽鍦ㄨ繖涓獁orker閲岋紝浣跨敤鑰呭彧闇�瑕佽闃卐ventbus鐨勪簨浠跺氨鍙互鐩戝惉face
+ */
+face.run = function () {
+ let workerFile = '/app/code/dxmodules/faceWorker.js'
+ bus.newWorker('__face', workerFile)
+}
+
+/**
+ * 濡傛灉face鍗曠嫭涓�涓嚎绋嬶紝鍙互鐩存帴浣跨敤run鍑芥暟锛屼細鑷姩鍚姩涓�涓嚎绋嬶紝
+ * 濡傛灉鎯冲姞鍏ュ埌鍏朵粬宸叉湁鐨勭嚎绋嬶紝鍙互浣跨敤浠ヤ笅灏佽鐨勫嚱鏁�
+ */
+face.worker = {
+ //鍦╳hile寰幆鍓�
+ beforeLoop: function (options) {
+ // 浜鸿劯绠楁硶鍒濆鍖�
+ face.init(options, options.capturerRgbId, options.capturerNirId)
+ },
+ //鍦╳hile寰幆閲�
+ loop: function () {
+ if (!face.msgIsEmpty()) {
+ let res = face.msgReceive();
+ bus.fire(face.RECEIVE_MSG, res)
+ }
+ }
+}
+
+export default face;
diff --git a/vf205_access/dxmodules/dxGpio.js b/vf205_access/dxmodules/dxGpio.js
new file mode 100644
index 0000000..457d8ba
--- /dev/null
+++ b/vf205_access/dxmodules/dxGpio.js
@@ -0,0 +1,123 @@
+// build : 20240524
+// gpio 杈撳嚭,鍙兘杈撳嚭2绉嶇姸鎬侊紝楂樼數骞�/浣庣數骞筹紝濡傛灉鎺ュ叆缁х數鍣紝鍒欓珮鐢靛钩鏄紑锛屼綆鐢靛钩鏄叧
+import { gpioClass } from './libvbar-b-dxgpio.so'
+const gpioObj = new gpioClass();
+const gpio = {}
+
+/**
+ * 鍒濆鍖�,鍙渶瑕佹墽琛屼竴娆″嵆鍙�
+ * @returns true/false
+ */
+gpio.init = function () {
+ return gpioObj.init();
+}
+
+/**
+ * 閲婃斁gpio璧勬簮
+ * @returns true/false
+ */
+gpio.deinit = function () {
+ return gpioObj.exit();
+}
+
+/**
+ * 鐢宠gpio,姣忎釜gpio鍙渶瑕佺敵璇蜂竴娆�
+ * @param {number} gpio鐨勬爣璇嗭紝涓嶅悓鐨勮澶囦笉鍚岀殑鏍囪瘑锛屽繀濉�
+ * @returns true/false
+ */
+gpio.request = function (gpio_) {
+ let res = gpioObj.request(gpio_)
+ if (!res) {
+ return res
+ }
+ gpioObj.setFunc(gpio_, 0x04);
+ return true
+}
+
+/**
+ * 閲婃斁鎸囧畾gpio
+ * @param {number} gpio鐨勬爣璇嗭紝涓嶅悓鐨勮澶囦笉鍚岀殑鏍囪瘑锛屽繀濉�
+ * @returns true/false
+ */
+gpio.free = function (gpio_) {
+ return gpioObj.free(gpio_);
+}
+
+/**
+ * 鎸囧畾gpio杈撳嚭楂�/浣庣數骞�
+ * @param {number} gpio鐨勬爣璇嗭紝涓嶅悓鐨勮澶囦笉鍚岀殑鏍囪瘑锛屽繀濉�
+ * @param {number} value 鍙兘鏄�1鍜�0锛�1琛ㄧず楂樼數骞筹紝0琛ㄧず浣庣數骞筹紝缂虹渷鏄珮鐢靛钩锛屽繀濉�
+ * @returns true/false
+ */
+gpio.setValue = function (gpio_, value) {
+ return gpioObj.setValue(gpio_, value);
+}
+
+/**
+ * 鑾峰彇鎸囧畾gpio褰撳墠鐨勮緭鍑� 锛氶珮/浣庣數骞�
+ * @param {number} gpio鐨勬爣璇嗭紝涓嶅悓鐨勮澶囦笉鍚岀殑鏍囪瘑锛屽繀濉�
+ * @returns 1鍜�0锛�1琛ㄧず楂樼數骞筹紝0琛ㄧず浣庣數骞�
+ */
+gpio.getValue = function (gpio_) {
+ return gpioObj.getValue(gpio_);
+}
+
+/**
+ * 鐢宠gpio,姣忎釜gpio鍙渶瑕佺敵璇蜂竴娆�
+ * @param {number} gpio鐨勬爣璇嗭紝涓嶅悓鐨勮澶囦笉鍚岀殑鏍囪瘑锛屽繀濉�
+ * @returns true/false
+ */
+gpio.requestGpio = function (gpio_) {
+ let res = gpioObj.request(gpio_)
+ return res
+}
+
+/**
+ * 璁剧疆gpio鍔熻兘
+ * @param {number} gpio鐨勬爣璇嗭紝涓嶅悓鐨勮澶囦笉鍚岀殑鏍囪瘑锛屽繀濉�
+ * @param {number} gpio鍔熻兘灞炴�э紝涓嶅悓鐨勮澶囦笉鍚岀殑鍔熻兘灞炴�э紝蹇呭~
+ * @returns true/false
+ */
+gpio.setFuncGpio = function (gpio_, func) {
+ let res = gpioObj.setFunc(gpio_, func)
+ return res
+}
+
+/**
+ * 璁剧疆鎸囧畾gpio涓婃媺鐘舵��
+ * @param {number} gpio鐨勬爣璇嗭紝涓嶅悓鐨勮澶囦笉鍚岀殑鏍囪瘑锛屽繀濉�
+ * @param {number} state 涓婃媺鐘舵�侊紝蹇呭~
+ * @returns true/false
+ */
+gpio.setPullState = function (gpio_, state) {
+ return gpioObj.setPullState(gpio_, state);
+}
+
+/**
+ * 鑾峰彇鎸囧畾gpio涓婃媺鐘舵��
+ * @param {number} gpio鐨勬爣璇嗭紝涓嶅悓鐨勮澶囦笉鍚岀殑鏍囪瘑锛屽繀濉�
+ * @returns 涓婃媺鐘舵��(int)
+ */
+gpio.getPullState = function (gpio_) {
+ return gpioObj.getPullState(gpio_);
+}
+/**
+ * 璁剧疆鎸囧畾gpio鐨勯┍鍔ㄨ兘鍔�
+ * @param {number} gpio鐨勬爣璇嗭紝涓嶅悓鐨勮澶囦笉鍚岀殑鏍囪瘑锛屽繀濉�
+ * @param {number} strength 鑳藉姏锛屽繀濉�
+ * @returns true/false
+ */
+gpio.setDriveStrength = function (gpio_, strength) {
+ return gpioObj.setDriveStrength(gpio_, strength);
+}
+
+/**
+ * 鑾峰彇鎸囧畾gpio鐨勯┍鍔ㄨ兘鍔�
+ * @param {number} gpio鐨勬爣璇嗭紝涓嶅悓鐨勮澶囦笉鍚岀殑鏍囪瘑锛屽繀濉�
+ * @returns 鑳藉姏(int)
+ */
+gpio.getDriveStrength = function (gpio_) {
+ return gpioObj.getDriveStrength(gpio_);
+}
+
+export default gpio;
diff --git a/vf205_access/dxmodules/dxGpioKey.js b/vf205_access/dxmodules/dxGpioKey.js
new file mode 100644
index 0000000..44237b8
--- /dev/null
+++ b/vf205_access/dxmodules/dxGpioKey.js
@@ -0,0 +1,84 @@
+//build 20240524
+//鎺ュ彈 gpio 鐨勮緭鍏�
+//渚濊禆缁勪欢: dxLogger,dxDriver,dxEventBus
+import { gpioKeyClass } from './libvbar-m-dxkey.so'
+import bus from './dxEventBus.js'
+import * as os from "os";
+const gpioKeyObj = new gpioKeyClass();
+const gpioKey = {}
+
+/**
+ * gpioKey 鍒濆鍖�
+ * @returns true:鎴愬姛,false:澶辫触
+ */
+gpioKey.init = function () {
+ const res = gpioKeyObj.init()
+ if (res) {
+ gpioKeyObj.registerCb("gpioKeyCb")
+ }
+ return res
+}
+
+/**
+ * gpioKey 鍙栨秷鍒濆鍖�
+ * @returns true:鎴愬姛,false:澶辫触
+ */
+gpioKey.deinit = function () {
+ gpioKeyObj.unRegisterCb("gpioKeyCb")
+ return gpioKeyObj.deinit()
+}
+
+/**
+ * 鍒ゆ柇gpioKey娑堟伅闃熷垪鏄惁涓虹┖
+ * @returns true:鎴愬姛,false:澶辫触
+ */
+gpioKey.msgIsEmpty = function () {
+ return gpioKeyObj.msgIsEmpty()
+}
+
+/**
+ * 浠巊pioKey娑堟伅闃熷垪涓鍙栨暟鎹�
+ * @returns json娑堟伅瀵硅薄锛屾牸寮忥細{"code":30,"type":1,"value":1}
+ */
+gpioKey.msgReceive = function () {
+ let msg = gpioKeyObj.msgReceive()
+ return JSON.parse(msg);
+}
+
+gpioKey.RECEIVE_MSG = '__gpioKey__MsgReceive'
+
+/**
+ * 绠�鍖杇piokey缁勪欢鐨勪娇鐢紝鏃犻渶杞鍘昏幏鍙栨暟鎹紝鏁版嵁浼氶�氳繃eventbus鍙戦�佸嚭鍘�
+ * run 鍙細鎵ц涓�娆�
+ * 濡傛灉闇�瑕佸疄鏃惰幏鍙栨暟鎹紝鍙互璁㈤槄 eventbus鐨勪簨浠讹紝浜嬩欢鐨則opic鏄疓PIO_KEY锛屼簨浠剁殑鍐呭鏄被浼納"code":30,"type":1,"value":1}
+ * 鍏朵腑code鏄痝pio鐨勬爣璇嗭紝琛ㄧず鏄偅涓猤pio鏈夎緭鍏ワ紝value鍊煎彧鑳芥槸0锛�1閫氬父琛ㄧず浣庣數骞冲拰楂樼數骞�
+ * type鏄簨浠剁被鍨嬶紝閬靛惊Linux鐨勬爣鍑嗚緭鍏ヨ瀹�,浠ヤ笅鍒楀嚭甯哥敤鍑犱釜锛�
+ (0x01):鎸夐敭浜嬩欢锛屽寘鎷墍鏈夌殑閿洏鍜屾寜閽簨浠躲�備緥濡傦紝褰撴寜涓嬫垨閲婃斁閿洏涓婄殑涓�涓敭鏃讹紝灏嗘姤鍛婃绫讳簨浠躲��
+ (0x05):寮�鍏充簨浠讹紝渚嬪绗旇鏈數鑴戠洊鐨勫紑鍏冲彲浠ユ姤鍛婂紑鍚堢姸鎬併��
+ (Ox11):LED浜嬩欢锛岀敤浜庢帶鍒惰澶囦笂鐨凩ED鎸囩ず鐏紝
+ (Ox12):澹伴煶浜嬩欢锛岀敤浜庢帶鍒惰澶囦笂鐨勫0闊宠緭鍑猴紝
+ (0x16):鐢垫簮浜嬩欢锛屽彲浠ョ敤浜庢姤鍛婄數婧愭寜閽簨浠舵垨鐢垫睜鐢甸噺浣�
+ *
+ */
+gpioKey.run = function () {
+ bus.newWorker("__gpiokey", '/app/code/dxmodules/gpioKeyWorker.js')
+}
+
+/**
+ * 濡傛灉gpioKey鍗曠嫭涓�涓嚎绋嬶紝鍙互鐩存帴浣跨敤run鍑芥暟锛屼細鑷姩鍚姩涓�涓嚎绋嬶紝
+ * 濡傛灉鎯冲姞鍏ュ埌鍏朵粬宸叉湁鐨勭嚎绋嬶紝鍙互浣跨敤浠ヤ笅灏佽鐨勫嚱鏁�
+ */
+gpioKey.worker = {
+ //鍦╳hile寰幆鍓�
+ beforeLoop: function () {
+ gpioKey.init()
+ },
+ //鍦╳hile寰幆閲�
+ loop: function () {
+ if (!gpioKey.msgIsEmpty()) {
+ let res = gpioKey.msgReceive();
+ bus.fire(gpioKey.RECEIVE_MSG, res)
+ }
+ }
+}
+export default gpioKey;
diff --git a/vf205_access/dxmodules/dxHttp.js b/vf205_access/dxmodules/dxHttp.js
new file mode 100644
index 0000000..f94b6d1
--- /dev/null
+++ b/vf205_access/dxmodules/dxHttp.js
@@ -0,0 +1,155 @@
+// http瀹㈡埛绔粍浠�
+import { httpClass } from './libvbar-m-dxhttp.so'
+
+const httpObj = new httpClass();
+
+const http = {
+
+ HTTP_METHOD : {
+ GET: "GET",
+ POST: "POST",
+ PUT: "PUT",
+ DELETE: "DELETE",
+ HEAD: "HEAD",
+ OPTIONS: "OPTIONS",
+ PATCH: "PATCH"
+ },
+ HTTP_FORMAT : {
+ JSON: "JSON",
+ FORM: "FORM",
+ URLENCODE: "URLENCODE"
+ },
+ HTTP_FORM_TYPE : {
+ STRING: "STRING",
+ FILE: "FILE"
+ },
+ /**
+ * get璇锋眰
+ * @param {string} url
+ * @param {array} headers 闈炲繀濉紝浼氭湁榛樿濉厖 request headers
+ * @param {number} timeout 闈炲繀濉紝 瓒呮椂鏃堕棿
+ * @returns
+ */
+ get: function (url, headers, timeout) {
+ if (!url) {
+ throw new Error("url should not be null or empty")
+ }
+ return httpObj.request({ method: 0, url: url, headers: headers, timeout: timeout})
+ },
+ /**
+ * post璇锋眰,data涓簀son/form琛ㄥ崟鏁扮粍鏍煎紡
+ * @param {string} url
+ * @param {array} data
+ * @param {array} headers 闈炲繀濉紝浼氭湁榛樿濉厖 request headers
+ * @param {number} timeout 闈炲繀濉紝 瓒呮椂鏃堕棿
+ * @returns
+ */
+ post: function (url, data, headers, timeout, format = "JSON") {
+ if (!url) {
+ throw new Error("url should not be null or empty")
+ }
+ if (!data) {
+ throw new Error("data should not be null or empty")
+ }
+ if (typeof data != 'string' && format != "FORM") {
+ data = JSON.stringify(data)
+ }
+ if(format == "JSON"){
+ return httpObj.request({ method: 1, url: url, data: data, headers: headers, timeout: timeout})
+ }else{
+ return httpObj.request({ method: 1, url: url, formData: data, headers: headers, timeout: timeout})
+ }
+ },
+ /**
+ * put璇锋眰,data涓簀son/form琛ㄥ崟鏁扮粍鏍煎紡
+ * @param {string} url
+ * @param {array} data
+ * @param {array} headers 闈炲繀濉紝浼氭湁榛樿濉厖 request headers
+ * @param {number} timeout 闈炲繀濉紝 瓒呮椂鏃堕棿
+ * @returns
+ */
+ put: function (url, data, headers, timeout, format = "JSON") {
+ if (!url) {
+ throw new Error("url should not be null or empty")
+ }
+ if (!data) {
+ throw new Error("data should not be null or empty")
+ }
+ if (typeof data != 'string' && format != "FORM") {
+ data = JSON.stringify(data)
+ }
+ if(format == "JSON"){
+ return httpObj.request({ method: 2, url: url, data: data, headers: headers, timeout: timeout})
+ }else{
+ return httpObj.request({ method: 2, url: url, formData: data, headers: headers, timeout: timeout})
+ }
+ },
+ /**
+ * delete璇锋眰
+ * @param {string} url
+ * @param {array} headers 闈炲繀濉紝浼氭湁榛樿濉厖 request headers
+ * @param {number} timeout 闈炲繀濉紝 瓒呮椂鏃堕棿
+ * @returns
+ */
+ delete: function (url, headers, timeout) {
+ if (!url) {
+ throw new Error("url should not be null or empty")
+ }
+ return httpObj.request({ method: 3, url: url, headers: headers, timeout: timeout})
+ },
+ /**
+ * 涓嬭浇鏂囦欢锛屾湰璐ㄦ槸get璇锋眰
+ * @param {string} url
+ * @param {string} path 鐩爣璺緞(缁濆璺緞)
+ * @param {array} headers 闈炲繀濉紝浼氭湁榛樿濉厖 request headers
+ * @param {number} timeout 闈炲繀濉紝 瓒呮椂鏃堕棿
+ * @returns 涓嬭浇鏂囦欢鏈夊彲鑳借繑鍥瀗ull锛屼絾鏄笅杞芥槸鎴愬姛鐨�
+ */
+ download: function (url, path, headers, timeout) {
+ if (!url) {
+ throw new Error("url should not be null or empty")
+ }
+ if (!path) {
+ throw new Error("path should not be null or empty")
+ }
+ return httpObj.request({ method: 0, url: url, headers: headers, download: path, timeout: timeout })
+ },
+
+ /**
+ * 涓婁紶鏂囦欢锛屾湰璐ㄦ槸post璇锋眰
+ * @param {string} url
+ * @param {string} path 婧愯矾寰�(缁濆璺緞)
+ * @returns
+ */
+ upload: function (url, path) {
+ if (!url) {
+ throw new Error("url should not be null or empty")
+ }
+ if (!path) {
+ throw new Error("path should not be null or empty")
+ }
+ return httpObj.request({
+ method: 1,
+ url: url,
+ headers: ["application/x-www-form-urlencoded; charset=UTF-8"],
+ upload: path
+ })
+ },
+ /**
+ * 鍘熺敓鏂瑰紡
+ * 蹇呭~鍙傛暟锛歮ethod锛�0锛歡et璇锋眰锛�1锛歱ost璇锋眰锛夈�乽rl
+ * 鍙�夊弬鏁帮細headers(瀛楃涓叉暟缁勶紝瑕嗙洊榛樿header)銆乨ownload锛堟枃浠朵笅杞藉湴鍧�锛夈�乨ata(璇锋眰鎶ユ枃锛宲ost璇锋眰蹇呭~)銆乼imeout(瓒呮椂鏃堕棿/ms,缂虹渷:5000)銆乨ns(缂虹渷:"114.114.114.114,8.8.8.8")銆乽pload
+ * 榛樿header锛欰ccept-Charset:utf-8銆丆ontent-Type:application/json;charset=utf-8銆丆onnection:close
+ * @param {object} param json
+ * 濡傦細let param={
+ method:0,
+ url:"http://192.168.10.122:8000/DW200_1_0.zip",
+ download:"/testNet/aaa"
+ }
+ * @returns
+ */
+ request: function (param) {
+ return httpObj.request(param)
+ }
+}
+export default http;
diff --git a/vf205_access/dxmodules/dxLogger.js b/vf205_access/dxmodules/dxLogger.js
new file mode 100644
index 0000000..ed79322
--- /dev/null
+++ b/vf205_access/dxmodules/dxLogger.js
@@ -0,0 +1,59 @@
+/**
+ * dxLogger module
+ * To replace the `console.log` function, allowing logs to be viewed in the corresponding VSCode plugin during debugging,
+ * with support for three levels of logging: `debug`,`info`, and `error`.
+ * Supports printing various data types in JavaScript.
+ */
+import dxCommon from './dxCommon.js'
+const logger = {}
+
+logger.config = {
+ level: 0, // default is all,if<0,no print
+}
+logger.debug = function (...data) {
+ if (this.config.level === 0) {
+ log("DEBUG ", data)
+ }
+}
+logger.info = function (...data) {
+ if ([0, 1].includes(this.config.level)) {
+ log("INFO ", data)
+ }
+}
+logger.error = function (...data) {
+ if ([0, 1, 2].includes(this.config.level)) {
+ log("ERROR ", data)
+ }
+}
+//-----------------------------------private----------------------
+function log(level, messages) {
+ let message = messages.map(msg => getContent(msg)).join(' ');
+ let content = `[${level}${getTime()}]: ${message}`
+ dxCommon.systemBrief(`echo '${content}'`)
+}
+function getContent(message) {
+ if (message === undefined) {
+ return 'undefined'
+ } else if (message === null) {
+ return 'null'
+ }
+ if ((typeof message) == 'object') {
+ if (Object.prototype.toString.call(message) === '[object Error]') {
+ return message.message + '\n' + message.stack
+ }
+ return JSON.stringify(message)
+ }
+ return message
+}
+function getTime() {
+ const now = new Date();
+ const year = now.getFullYear();
+ const month = ('0' + (now.getMonth() + 1)).slice(-2);
+ const day = ('0' + now.getDate()).slice(-2);
+ const hours = ('0' + now.getHours()).slice(-2);
+ const minutes = ('0' + now.getMinutes()).slice(-2);
+ const seconds = ('0' + now.getSeconds()).slice(-2);
+ const milliseconds = ('0' + now.getMilliseconds()).slice(-3);
+ return year + '-' + month + '-' + day + ' ' + hours + ':' + minutes + ':' + seconds + '.' + milliseconds;
+}
+export default logger
\ No newline at end of file
diff --git a/vf205_access/dxmodules/dxMap.js b/vf205_access/dxmodules/dxMap.js
new file mode 100644
index 0000000..0f73d1d
--- /dev/null
+++ b/vf205_access/dxmodules/dxMap.js
@@ -0,0 +1,109 @@
+import { mapClass } from './libvbar-m-dxmap.so'
+/**
+ * build:20240407
+ * map 缁勪欢锛屽彲浠ュ湪鍐呭瓨閲岃鍐檏ey/value
+ */
+const mapObj = new mapClass();
+
+const map = {
+ get: function (name) {
+ if (!name || name.length == 0) {
+ throw new Error("dxMap.get:name should not be null or empty")
+ }
+ //绗竴娆ut浼氳嚜鍔ㄥ垱寤哄疄渚�
+ return {
+ /**
+ * @brief 鑾峰彇Map涓殑鎵�鏈夐敭,杩斿洖涓�涓暟缁�
+ */
+ keys: function () {
+ let all = mapObj.keys(name)
+ return all == null ? [] : all
+ },
+ /**
+ * @brief 鏍规嵁key鑾峰彇value
+ */
+ get: function (key) {
+ if (!key || key.length < 1) {
+ throw new Error("The 'key' parameter cannot be null or empty")
+ }
+ // put绌哄瓧绗︿覆锛実et浼氭槸null
+ let value = mapObj.get(name, key)
+ if (value === undefined || value === null) {
+ value = ""
+ }
+ return _parseString(value)
+ },
+ /**
+ * @brief 鍚慚ap涓彃鍏ラ敭鍊煎
+ */
+ put: function (key, value) {
+ if (!key || key.length < 1) {
+ throw new Error("The 'key' parameter cannot be null or empty")
+ }
+ if (value == null || value == undefined) {
+ throw new Error("The 'value' parameter cannot be null or empty")
+ }
+ return mapObj.insert(name, key, _stringifyValue(value))
+ },
+ /**
+ * @brief 鏍规嵁Key鍒犻櫎閿�煎
+ */
+ del: function (key) {
+ if (!key || key.length < 1) {
+ throw new Error("The 'key' parameter cannot be null or empty")
+ }
+ return mapObj.delete(name, key)
+ },
+ /**
+ * 涓嶅啀浣跨敤浜嗭紝灏遍攢姣�
+ */
+ destroy: function () {
+ return mapObj.destroy(name)
+ },
+ }
+ }
+
+}
+function _stringifyValue(value) {
+ const type = typeof value
+ if (type === 'string') {
+ return value
+ }
+ if (type === 'number') {
+ return '#n#' + value
+ }
+ if (type === 'boolean') {
+ return '#b#' + value
+ }
+ if (type === 'object') {
+ // 濡傛灉鏄璞★紝杩涗竴姝ュ垽鏂槸鍚︿负鏁扮粍
+ if (Array.isArray(value)) {
+ return '#a#' + JSON.stringify(value);
+ }// else if (value === null) { 鍓嶉潰宸茬粡瑙勯伩浜唍ull鐨勬儏鍐�
+ return '#o#' + JSON.stringify(value)
+ }
+ if (type === 'function') {
+ throw new Error("The 'value' parameter should not be function")
+ }
+}
+function _parseString(str) {
+ if (str.startsWith('#n#')) {
+ // 瑙f瀽鏁板瓧
+ const numberStr = str.substring(3);
+ return numberStr.includes('.') ? parseFloat(numberStr) : parseInt(numberStr, 10);
+ } else if (str.startsWith('#b#')) {
+ // 瑙f瀽甯冨皵鍊�
+ return str.substring(3) === 'true';
+ } else if (str.startsWith('#a#')) {
+ // 瑙f瀽鏁扮粍
+ return JSON.parse(str.substring(3));
+ } else if (str.startsWith('#o#')) {
+ // 瑙f瀽瀵硅薄
+ return JSON.parse(str.substring(3));
+ } else {
+ // 榛樿鎯呭喌涓嬶紝灏嗗瓧绗︿覆杩斿洖
+ return str;
+ }
+}
+export default map;
+
diff --git a/vf205_access/dxmodules/dxMqtt.js b/vf205_access/dxmodules/dxMqtt.js
new file mode 100644
index 0000000..71346ac
--- /dev/null
+++ b/vf205_access/dxmodules/dxMqtt.js
@@ -0,0 +1,225 @@
+//build:20240411
+//鍒╃敤mqtt鍗忚瀹炵幇鍜宮qtt鏈嶅姟绔殑閫氫俊鎴栭�氳繃mqtt broker瀹炵幇鍜屽叾瀹僲qtt瀹㈡埛绔殑閫氫俊
+//渚濊禆缁勪欢 dxMap,dxLogger,dxDriver,dxCommon,dxEventBus,dxNet
+import { mqttClass } from './libvbar-m-dxmqtt.so'
+import * as os from "os"
+import std from './dxStd.js'
+import dxMap from './dxMap.js'
+import dxCommon from './dxCommon.js'
+import bus from './dxEventBus.js'
+const map = dxMap.get("default")
+const mqttObj = new mqttClass();
+const mqtt = {}
+/**
+ * 鍒濆鍖杕qtt鐩稿叧灞炴�у苟鍒涘缓杩炴帴,璇峰湪worker閲屼娇鐢╠xMqtt缁勪欢鎴栦娇鐢ㄧ畝鍖栧嚱鏁癲xMqtt.run
+ * @param {string} mqttAddr mqtt鏈嶅姟鍦板潃锛屽繀濉紝浠cp://寮�澶达紝鏍煎紡鏄痶cp://ip:port
+ * @param {string} clientId 瀹㈡埛绔痠d锛屽繀濉紝涓嶅悓鐨勮澶囪浣跨敤涓嶅悓鐨勫鎴风id
+ * @param {string} username 闈炲繀濉紝mqtt鐢ㄦ埛鍚�
+ * @param {string} password 闈炲繀濉紝mqtt瀵嗙爜
+ * @param {string} prefix 闈炲繀濉紝缂虹渷涓虹┖瀛楃涓诧紝杩欎釜琛ㄧず鑷姩鍦ㄤ富棰樺墠鍔犱笂涓�涓墠缂�
+ * @param {number} qos 0,1,2 闈炲繀濉紝缂虹渷鏄�1. 鍏朵腑0琛ㄧず娑堟伅鏈�澶氬彂閫佷竴娆★紝鍙戦�佸悗娑堟伅灏辫涓㈠純;1琛ㄧず娑堟伅鑷冲皯鍙戦�佷竴娆★紝鍙互淇濊瘉娑堟伅琚帴鏀舵柟鏀跺埌锛屼絾鏄細瀛樺湪鎺ユ敹鏂规敹鍒伴噸澶嶆秷鎭殑鎯呭喌;2琛ㄧず娑堟伅鍙戦�佹垚鍔熶笖鍙彂閫佷竴娆�,璧勬簮寮�閿�澶�
+ * @param {string} willTopic 闈炲繀濉紝閬楀槺涓婚锛岄�氳繃broker閫氫俊鐨勬椂鍊欒澶囨柇寮�浼氳嚜鍔ㄨЕ鍙戜竴涓猰qtt閬楀槺娑堟伅锛岃繖涓槸閬楀槺娑堟伅鐨勪富棰�
+ * @param {string} willMessage 闈炲繀濉紝閬楀槺鍐呭锛岄�氳繃broker閫氫俊鐨勬椂鍊欒澶囨柇寮�浼氳嚜鍔ㄨЕ鍙戜竴涓猰qtt閬楀槺娑堟伅锛岃繖涓槸閬楀槺娑堟伅鐨勫唴瀹�
+ * @param {string} id 鍙ユ焺id锛岄潪蹇呭~锛堣嫢鍒濆鍖栧涓疄渚嬮渶瑕佷紶鍏ュ敮涓�id锛�
+ */
+mqtt.init = function (mqttAddr, clientId, username, password, prefix = "", qos = 1, willTopic, willMessage, id) {
+
+ if (mqttAddr === undefined || mqttAddr.length === 0) {
+ throw new Error("dxMqtt.init: 'mqttAddr' parameter should not be null or empty")
+ }
+ if (clientId === undefined || clientId.length === 0) {
+ throw new Error("dxMqtt.init: 'clientId' parameter should not be null or empty")
+ }
+ // 濡傛灉mqttAddr涓嶄互tcp://寮�澶达紝鑷姩娣诲姞鍓嶇紑
+ if (!mqttAddr.startsWith('tcp://')) {
+ mqttAddr = 'tcp://' + mqttAddr
+ }
+ let pointer = mqttObj.init(mqttAddr, clientId, username, password, prefix, qos, willTopic, willMessage);
+ if (pointer === undefined || pointer === null) {
+ throw new Error("dxMqtt.init: mqtt init failed")
+ }
+
+ dxCommon.handleId("mqtt", id, pointer)
+}
+
+/**
+ * 閲嶆柊杩炴帴,姣斿杩炴帴鎴愬姛鍚庣獊鐒剁綉缁滄柇寮�锛屾棤闇�閲嶆柊init锛岀洿鎺ラ噸杩炲嵆鍙�
+ * @param {string} willTopic 闈炲繀濉紝閬楀槺涓婚锛岄�氳繃broker閫氫俊鐨勬椂鍊欒澶囨柇寮�浼氳嚜鍔ㄨЕ鍙戜竴涓猰qtt閬楀槺娑堟伅锛岃繖涓槸閬楀槺娑堟伅鐨勪富棰�
+ * @param {string} willMessage 闈炲繀濉紝閬楀槺鍐呭锛岄�氳繃broker閫氫俊鐨勬椂鍊欒澶囨柇寮�浼氳嚜鍔ㄨЕ鍙戜竴涓猰qtt閬楀槺娑堟伅锛岃繖涓槸閬楀槺娑堟伅鐨勫唴瀹�
+ * @param {string} id 鍙ユ焺id锛岄潪蹇呭~锛堥渶淇濇寔鍜宨nit涓殑id涓�鑷达級
+ */
+mqtt.reconnect = function (willTopic, willMessage, id) {
+ let pointer = dxCommon.handleId("mqtt", id)
+ return mqttObj.recreate(pointer, willTopic, willMessage);
+}
+
+/**
+ * 璁㈤槄澶氫富棰�
+ * @param {array} topics 蹇呭~锛� 瑕佽闃呯殑涓婚鏁扮粍锛屽彲浠ュ悓鏃惰闃呭涓�
+ * @param {number} qos 闈炲繀濉紝缂虹渷鏄�1. 鍏朵腑0琛ㄧず娑堟伅鏈�澶氬彂閫佷竴娆★紝鍙戦�佸悗娑堟伅灏辫涓㈠純;1琛ㄧず娑堟伅鑷冲皯鍙戦�佷竴娆★紝鍙互淇濊瘉娑堟伅琚帴鏀舵柟鏀跺埌锛屼絾鏄細瀛樺湪鎺ユ敹鏂规敹鍒伴噸澶嶆秷鎭殑鎯呭喌;2琛ㄧず娑堟伅鍙戦�佹垚鍔熶笖鍙彂閫佷竴娆�,璧勬簮寮�閿�澶�
+ * @param {string} id 鍙ユ焺id锛岄潪蹇呭~锛堥渶淇濇寔鍜宨nit涓殑id涓�鑷达級
+ * @returns
+ */
+mqtt.subscribes = function (topics, qos, id) {
+ if (topics === undefined || topics.length === 0) {
+ throw new Error("dxMqtt.subscribes: 'topics' parameter should not be null or empty")
+ }
+
+ if (qos === undefined) {
+ qos = 1
+ }
+ let pointer = dxCommon.handleId("mqtt", id)
+ return mqttObj.subscribes(pointer, topics, qos);
+}
+
+/**
+ * 鍒ゆ柇mqtt鏄惁杩炴帴锛岃繛鎺ユ垚鍔熷悗濡傛灉缃戠粶鏂紑锛岃繛鎺ヤ篃浼氭柇寮�
+ * @param {string} id 鍙ユ焺id锛岄潪蹇呭~锛堥渶淇濇寔鍜宨nit涓殑id涓�鑷达級
+ * @returns false澶辫触锛� true鎴愬姛
+ */
+mqtt.isConnected = function (id) {
+ let pointer = dxCommon.handleId("mqtt", id)
+ return mqttObj.isConnected(pointer);
+}
+
+/**
+ * 鏌ヨmqtt閰嶇疆
+ * @param {string} id 鍙ユ焺id锛岄潪蹇呭~锛堥渶淇濇寔鍜宨nit涓殑id涓�鑷达級
+ * @returns mqtt閰嶇疆
+ */
+mqtt.getConfig = function (id) {
+ let pointer = dxCommon.handleId("mqtt", id)
+ return mqttObj.getConfig(pointer);
+}
+
+/**
+ * mqtt閰嶇疆鏇存柊
+ * @param {object} options 閰嶇疆鍙傛暟锛屽ぇ閮ㄥ垎鍙互鐢ㄩ粯璁ゅ��
+ * @param {string} options.mqttAddr mqtt鏈嶅姟鍦板潃锛屽繀濉紝浠cp://寮�澶达紝鏍煎紡鏄痶cp://ip:port
+ * @param {string} options.clientId 瀹㈡埛绔痠d锛屽繀濉紝涓嶅悓鐨勮澶囪浣跨敤涓嶅悓鐨勫鎴风id
+ * @param {string} options.userName 闈炲繀濉紝mqtt鐢ㄦ埛鍚�
+ * @param {string} options.password 闈炲繀濉紝mqtt瀵嗙爜
+ * @param {string} options.prefix 闈炲繀濉紝缂虹渷涓虹┖瀛楃涓诧紝杩欎釜琛ㄧず鑷姩鍦ㄤ富棰樺墠鍔犱笂涓�涓墠缂�
+ * @param {number} options.qos 0,1,2 闈炲繀濉紝缂虹渷鏄�1. 鍏朵腑0琛ㄧず娑堟伅鏈�澶氬彂閫佷竴娆★紝鍙戦�佸悗娑堟伅灏辫涓㈠純;1琛ㄧず娑堟伅鑷冲皯鍙戦�佷竴娆★紝鍙互淇濊瘉娑堟伅琚帴鏀舵柟鏀跺埌锛屼絾鏄細瀛樺湪鎺ユ敹鏂规敹鍒伴噸澶嶆秷鎭殑鎯呭喌;2琛ㄧず娑堟伅鍙戦�佹垚鍔熶笖鍙彂閫佷竴娆�,璧勬簮寮�閿�澶�
+ * @param {string} options.ssl 闈炲繀濉紝ssl閰嶇疆绫�
+ */
+mqtt.updateConfig = function (options, id) {
+ if (!options) {
+ throw new Error("dxMqtt.updateConfig: 'options' parameter should not be null or empty")
+ }
+ if (options.mqttAddr === undefined || options.mqttAddr.length === 0) {
+ throw new Error("dxMqtt.updateConfig: 'options.mqttAddr' parameter should not be null or empty")
+ }
+ if (options.clientId === undefined || options.clientId.length === 0) {
+ throw new Error("dxMqtt.updateConfig: 'options.clientId' parameter should not be null or empty")
+ }
+ if (options.qos === undefined || options.qos == null) {
+ throw new Error("dxMqtt.updateConfig: 'options.qos' parameter should not be null or empty")
+ }
+ // 濡傛灉mqttAddr涓嶄互tcp://寮�澶达紝鑷姩娣诲姞鍓嶇紑
+ if (!options.mqttAddr.startsWith('tcp://')) {
+ options.mqttAddr = 'tcp://' + options.mqttAddr
+ }
+ let pointer = dxCommon.handleId("mqtt", id)
+ let res = mqttObj.setConfig(pointer, options);
+ return res;
+}
+
+/**
+ * 鍙戦�乵qtt璇锋眰
+ * @param {string} topic 涓婚锛屽繀濉�
+ * @param {string} payload 娑堟伅浣撳唴瀹癸紝蹇呭~
+ * @param {string} id 鍙ユ焺id锛岄潪蹇呭~锛堥渶淇濇寔鍜宨nit涓殑id涓�鑷达級
+ */
+mqtt.send = function (topic, payload, id) {
+ if (topic === undefined || topic.length === 0) {
+ throw new Error("dxMqtt.send:'topic' parameter should not be null or empty")
+ }
+ if (payload === undefined || payload.length === 0) {
+ throw new Error("dxMqtt.send:'payload' parameter should not be null or empty")
+ }
+ let pointer = dxCommon.handleId("mqtt", id)
+ return mqttObj.sendMsg(pointer, topic, payload);
+}
+
+/**
+ * 鎺ユ敹mqtt鏁版嵁,闇�瑕佽疆璇㈠幓鑾峰彇
+ * @param {string} id 鍙ユ焺id锛岄潪蹇呭~锛堥渶淇濇寔鍜宨nit涓殑id涓�鑷达級
+ * @return mqtt璇锋眰鏁版嵁锛岀粨鏋勬槸: {topic:'涓婚',payload:'鍐呭'}
+ */
+mqtt.receive = function (id) {
+ let msg = mqttObj.msgReceive(id);
+ return JSON.parse(msg);
+}
+
+/**
+ * 鍒ゆ柇鏄惁鏈夋柊鐨勬暟鎹紝涓�鑸厛鍒ゆ柇鏈夋暟鎹悗鍐嶈皟鐢╮eceive鍘昏幏鍙栨暟鎹�
+ * @param {string} id 鍙ユ焺id锛岄潪蹇呭~锛堥渶淇濇寔鍜宨nit涓殑id涓�鑷达級
+ * @returns false 鏈夋暟鎹紱true 娌℃湁鏁版嵁
+ */
+mqtt.msgIsEmpty = function (id) {
+ return mqttObj.msgIsEmpty(id);
+}
+
+/**
+ * 閿�姣乵qtt瀹炰緥
+ * @param {string} id 鍙ユ焺id锛岄潪蹇呭~锛堥渶淇濇寔鍜宨nit涓殑id涓�鑷达級
+ */
+mqtt.destroy = function (id) {
+ let pointer = dxCommon.handleId("mqtt", id)
+ mqttObj.deinit(pointer);
+}
+
+mqtt.RECEIVE_MSG = '__mqtt__MsgReceive'
+mqtt.CONNECTED_CHANGED = '__mqtt__Connect_changed'
+mqtt.RECONNECT = '__mqtt__Reconnect'
+
+/**
+ * 鐢ㄧ畝鍗曠殑鏂瑰紡瀹炵幇mqtt瀹㈡埛绔紝鍙渶瑕佽皟鐢ㄨ繖涓�涓嚱鏁板氨鍙互瀹炵幇mqtt瀹㈡埛绔紝
+ * 鏀跺埌娑堟伅浼氳Е鍙戠粰 dxEventBus鍙戦�佷竴涓簨浠讹紝浜嬩欢鐨勪富棰樻槸mqtt.RECEIVE_MQTT_MSG锛屽唴瀹规槸{topic:'',payload:''}鏍煎紡
+ * 濡傛灉闇�瑕佸彂閫佹秷鎭紝鐩存帴浣跨敤 mqtt.send鏂规硶 mqtt鍙戦�佺殑鏁版嵁鏍煎紡绫讳技锛� { topic: "sendtopic1", payload: JSON.stringify({ a: i, b: "ssss" }) }
+ * mqtt鐨勮繛鎺ョ姸鎬佸彂鐢熷彉鍖栦細瑙﹀彂缁� dxEventBus鍙戦�佷竴涓簨浠讹紝浜嬩欢鐨勪富棰樻槸mqtt.CONNECTED_CHANGED锛屽唴瀹规槸'connected'鎴栬��'disconnect'
+ * mqtt闇�瑕佹湁缃戠粶锛屾墍浠ュ繀椤诲湪浣跨敤涔嬪墠纭繚dxNet缁勪欢瀹屾垚鍒濆鍖�
+ * @param {object} options mqtt鐩稿叧鍙傛暟,蹇呭~
+ * @param {string} options.mqttAddr mqtt鏈嶅姟鍦板潃锛屽繀濉紝浠cp://寮�澶达紝鏍煎紡鏄痶cp://ip:port
+ * @param {string} options.clientId 瀹㈡埛绔痠d锛屽繀濉紝涓嶅悓鐨勮澶囪浣跨敤涓嶅悓鐨勫鎴风id
+ * @param {string} options.username 闈炲繀濉紝mqtt鐢ㄦ埛鍚�
+ * @param {string} options.password 闈炲繀濉紝mqtt瀵嗙爜
+ * @param {string} options.prefix 闈炲繀濉紝缂虹渷涓虹┖瀛楃涓诧紝杩欎釜琛ㄧず鑷姩鍦ㄤ富棰樺墠鍔犱笂涓�涓墠缂�
+ * @param {number} options.qos 0,1,2 闈炲繀濉紝缂虹渷鏄�1. 鍏朵腑0琛ㄧず娑堟伅鏈�澶氬彂閫佷竴娆★紝鍙戦�佸悗娑堟伅灏辫涓㈠純;1琛ㄧず娑堟伅鑷冲皯鍙戦�佷竴娆★紝鍙互淇濊瘉娑堟伅琚帴鏀舵柟鏀跺埌锛屼絾鏄細瀛樺湪鎺ユ敹鏂规敹鍒伴噸澶嶆秷鎭殑鎯呭喌;2琛ㄧず娑堟伅鍙戦�佹垚鍔熶笖鍙彂閫佷竴娆�,璧勬簮寮�閿�澶�
+ * @param {string} options.willTopic 闈炲繀濉紝閬楀槺涓婚锛岄�氳繃broker閫氫俊鐨勬椂鍊欒澶囨柇寮�浼氳嚜鍔ㄨЕ鍙戜竴涓猰qtt閬楀槺娑堟伅锛岃繖涓槸閬楀槺娑堟伅鐨勪富棰�
+ * @param {string} options.willMessage 闈炲繀濉紝閬楀槺鍐呭锛岄�氳繃broker閫氫俊鐨勬椂鍊欒澶囨柇寮�浼氳嚜鍔ㄨЕ鍙戜竴涓猰qtt閬楀槺娑堟伅锛岃繖涓槸閬楀槺娑堟伅鐨勫唴瀹�
+ * @param {array} options.subs 闈炲繀濉紝瑕佽闃呯殑涓婚缁�
+ * @param {string} options.id 鍙ユ焺id锛岄潪蹇呭~锛堣嫢鍒濆鍖栧涓疄渚嬮渶瑕佷紶鍏ュ敮涓�id锛�
+ */
+mqtt.run = function (options) {
+ if (options === undefined || options.length === 0) {
+ throw new Error("dxmqtt.run:'options' parameter should not be null or empty")
+ }
+ if (options.id === undefined || options.id === null || typeof options.id !== 'string') {
+ // 鍙ユ焺id
+ options.id = ""
+ }
+ let oldfilepre = '/app/code/dxmodules/mqttWorker'
+ let content = std.loadFile(oldfilepre + '.js').replace("{{id}}", options.id)
+ let newfile = oldfilepre + options.id + '.js'
+ std.saveFile(newfile, content)
+ let init = map.get("__mqtt__run_init" + options.id)
+ if (!init) {//纭繚鍙垵濮嬪寲涓�娆�
+ map.put("__mqtt__run_init" + options.id, options)
+ bus.newWorker(options.id || "__mqtt", newfile)
+ }
+}
+/**
+ * 鑾峰彇褰撳墠mqtt杩炴帴鐨勭姸鎬�
+ * @param {string} id 鍙ユ焺id锛岄潪蹇呭~锛堥渶淇濇寔鍜宨nit涓殑id涓�鑷达級
+ * @returns 'connected' 鎴栬�� 'disconnected'
+ */
+mqtt.getConnected = function (id) {
+ if (id == undefined || id == null) {
+ id = ""
+ }
+ return mqtt.isConnected(id) ? "connected" : "disconnected"
+}
+
+export default mqtt;
diff --git a/vf205_access/dxmodules/dxNet.js b/vf205_access/dxmodules/dxNet.js
new file mode 100644
index 0000000..ad7df4c
--- /dev/null
+++ b/vf205_access/dxmodules/dxNet.js
@@ -0,0 +1,341 @@
+//build:20240626
+//閫氳繃杩欎釜缁勪欢鏉ラ厤缃綉缁滃拰鐩戝惉缃戠粶鐘舵�佸彉鍖�
+//渚濊禆缁勪欢: dxMap,dxLogger,dxDriver,dxEventBus
+import dxMap from './dxMap.js'
+import bus from './dxEventBus.js'
+import { netClass } from './libvbar-m-dxnet.so'
+const netObj = new netClass();
+const map = dxMap.get("default")
+
+const net = {}
+net.TYPE = {
+ "UNKNOWN": 0,
+ "ETHERNET": 1,
+ "WIFI": 2,
+ "4G": 4
+}
+net.DHCP = {
+ STATIC: 1,
+ DYNAMIC: 2,
+ WIFI_AP: 3 //WiFi AP鐑偣妯″紡
+}
+
+/**
+ * 缃戠粶鍒濆鍖�,wifi鎴栦互澶綉锛屽鏋滆繛涓嶄笂缃戠粶浼氳嚜鍔ㄤ笉鏂殑閲嶈瘯锛屾棤闇�閲嶅init銆備絾鏄痠nit鍚庨渶瑕佽疆璇㈠幓鑾峰彇缃戠粶鐘舵�侊紙閫氳繃msgReceive)
+ * 涔熷彲浠ョ洿鎺ヤ娇鐢ㄧ畝鍖栨柟娉昫xNet.run锛屾棤闇�杞
+ * @param {object} options 鍒濆鍖栫綉缁滅殑鍙傛暟
+ * @param {number} type 蹇呭~ 缃戠粶绫诲瀷锛屽弬鑰僴et.TYPE鏋氫妇
+ * @param {number} dhcp 蹇呭~ DHCP锛屽弬鑰僴et.DHCP鏋氫妇
+ * @param {string} macAddr 蹇呭~ mac鍦板潃,缂虹渷浣跨敤dxCommon.getUuid2mac()鏂规硶鏉ヨ幏鍙杕ac鍦板潃
+ * @param {string} ip 闈炲繀濉� 缃戠粶ip鍦板潃
+ * @param {string} gateway 闈炲繀濉� 缃戝叧鍦板潃
+ * @param {string} netmask 闈炲繀濉� 瀛愮綉鎺╃爜
+ * @param {string} dns0 闈炲繀濉� DNS鍦板潃
+ * @param {string} dns1 闈炲繀濉� 澶囬�塂NS鍦板潃
+ * @returns
+ */
+net.init = function (options) {
+ let ret = netObj.init()
+ if (!ret) {
+ return false
+ }
+ if (!options) {
+ throw new Error("dxNet.init: 'options' parameter should not be null or empty")
+ }
+ ret = netObj.setMasterCard(options.type)
+ if (!ret) {
+ return false
+ }
+ netObj.setMacaddr(options.type, options.macAddr)
+ ret = netObj.cardEnable(options.type, true)
+ if (!ret) {
+ return false
+ }
+ if (options.dhcp === 1) {
+ return netObj.setModeByCard(options.type, 1, {
+ ip: options.ip,
+ gateway: options.gateway,
+ netmask: options.netmask,
+ dns0: options.dns0,
+ dns1: options.dns1,
+ })
+ } else if (options.dhcp === 2) {
+ return netObj.setModeByCard(options.type, options.dhcp)
+ }
+ return false
+}
+
+/**
+ * 鑾峰彇Mac鍦板潃
+ * @param {number} type 蹇呭~ 缃戠粶绫诲瀷锛屽弬鑰僴et.TYPE鏋氫妇
+ * @returns Mac鍦板潃
+ */
+net.getMacaddr = function (type) {
+ return netObj.getMacaddr(type)
+}
+/**
+ * 璁剧疆Mac鍦板潃
+ * @param {number} type 蹇呭~ 缃戠粶绫诲瀷锛屽弬鑰僴et.TYPE鏋氫妇
+ * @param {string} addr Mac鍦板潃,蹇呭~锛屾牸寮忕被浼� b2:a1:63:3f:99:b6
+ * @returns true锛氭垚鍔� 涓荤綉鍗$被鍨嬶紝false 澶辫触
+ */
+net.setMacaddr = function (type, addr) {
+ if (type === null || type === undefined) {
+ throw new Error("dxNet.setMacaddr:'type' paramter should not be null or empty")
+ }
+ if (addr === null || addr === undefined || addr.length < 1) {
+ throw new Error("dxNet.setMacaddr:'addr' paramter should not be null or empty")
+ }
+ return netObj.setMacaddr(type, addr)
+}
+/**
+ * 浣胯兘缃戝崱锛屽苟娣诲姞鍒扮綉缁滅鐞嗘ā鍧�
+ * @param {number} type 蹇呭~ 缃戠粶绫诲瀷锛屽弬鑰僴et.TYPE鏋氫妇
+ * @param {boolean} on 寮�鍚�/鍏抽棴
+ * @returns 0锛氭垚鍔� <0 澶辫触
+ */
+net.cardEnable = function (type, on) {
+ if (type === null || type === undefined) {
+ throw new Error("dxNet.cardEnable: 'type' parameter should not be null or empty")
+ }
+ if (on === null) {
+ throw new Error("dxNet.cardEnable: 'on' parameter should not be null or empty")
+ }
+ return netObj.cardEnable(type, on)
+}
+/**
+ * net缃戠粶閿�姣�
+ * @return true锛氭垚鍔燂紝false 澶辫触
+ */
+net.exit = function () {
+ return netObj.exit()
+}
+/**
+ * 璁剧疆鎸囧畾缃戝崱鐨勬ā寮忓強瀵瑰簲鍙傛暟缃戠粶鍙傛暟
+ * @param {number} type 蹇呭~ 缃戠粶绫诲瀷锛屽弬鑰僴et.TYPE鏋氫妇
+ * @param {number} mode 蹇呭~ DHCP锛屽弬鑰僴et.DHCP鏋氫妇
+ * @param param 缃戠粶鍙傛暟
+ * @return true锛氭垚鍔燂紝false 澶辫触
+ */
+net.setModeByCard = function (type, mode, param) {
+ if (type === null || type === undefined) {
+ throw new Error("dxNet.setModeByCard: 'type' parameter should not be null or empty")
+ }
+ if (mode === null) {
+ throw new Error("dxNet.setModeByCard:'mode' parameter should not be null or empty")
+ }
+ return netObj.setModeByCard(type, mode, param)
+}
+/**
+ * 鑾峰彇鎸囧畾缃戝崱鐨勬ā寮忓強瀵瑰簲鍙傛暟缃戠粶鍙傛暟
+ * @param {number} type 蹇呭~ 缃戠粶绫诲瀷锛屽弬鑰僴et.TYPE鏋氫妇
+ * @returns 濡傛灉鏄潤鎬佺綉缁滄ā寮忥紝灏变細杩斿洖ip銆佺綉鍏崇瓑淇℃伅
+ */
+net.getModeByCard = function (type) {
+ if (type === null || type === undefined) {
+ throw new Error("dxNet.getModeByCard: 'type' parameter should not be null or empty")
+ }
+
+ return netObj.getModeByCard(type)
+}
+/**
+ * 璁剧疆涓荤綉鍗★紝搴旂敤绋嬪簭缃戠粶鐘舵�佺敱娆$綉鍗″喅瀹�
+ * @param {number} type 蹇呭~ 缃戠粶绫诲瀷锛屽弬鑰僴et.TYPE鏋氫妇
+ * @returns true锛氭垚鍔燂紝false 澶辫触
+ */
+net.setMasterCard = function (type) {
+ if (type === null || type === undefined) {
+ throw new Error("dxNet.setMasterCard: 'type' parameter should not be null or empty")
+ }
+ return netObj.setMasterCard(type)
+}
+/**
+ * 鑾峰彇涓荤綉鍗�
+ * @returns >0锛氭垚鍔� 涓荤綉鍗$被鍨嬶紝<0 澶辫触
+ */
+net.getMasterCard = function () {
+ return netObj.getMasterCard()
+}
+/**
+ * 鑾峰彇缃戠粶鐘舵�� 绫讳技{"status":4锛�"connected":true} ,鍏朵腑status濡備笅
+ * 0, 鏈垵濮嬫��
+ 1, 缃戝崱澶勪簬鍏抽棴鐘舵��
+ 2, 缃戝崱澶勪簬鎵撳紑鐘舵��
+ 3, 缃戠嚎宸叉彃鍏ユ垨鑰厀ifi宸茶繛鎺sid 浣嗘湭鍒嗛厤ip
+ 4, 宸叉垚鍔熷垎閰峣p
+ 5 宸茶繛鎺ユ寚瀹氭湇鍔℃垨鑰呴�氳繃娴嬭瘯鍙互杩炴帴鍒板箍鍩熺綉
+ * @returns 缃戠粶鐘舵��
+ */
+net.getStatus = function () {
+ let status = netObj.getStatus()
+ return { "status": status, "connected": status >= 4 }
+}
+/**
+ * 璁剧疆缃戠粶鐘舵��
+ * @param {number} status 缃戠粶鐘舵�侊紝蹇呭~
+ * @returns true锛氭垚鍔燂紝false 澶辫触
+ */
+net.setStatus = function (status) {
+ if (status === null || status === undefined) {
+ throw new Error("dxNet.setStatus: 'status' parameter should not be null or empty")
+ }
+ return netObj.setStatus(status)
+}
+
+/**
+ * 閲嶆柊浣胯兘缃戝崱
+ * @param {number} type 缃戠粶绫诲瀷锛屽繀濉�
+ * @param {number} phy_reset 寮�鍚�/鍏抽棴锛屽繀濉�
+ * @returns true锛氭垚鍔燂紝false 澶辫触
+ */
+net.netCardReset = function (type, phy_reset) {
+ if (type === null || type === undefined) {
+ throw new Error("dxNet.setStatus: 'status' parameter should not be null or empty")
+ }
+ if (phy_reset === null || phy_reset === undefined) {
+ throw new Error("dxNet.setStatus: 'status' parameter should not be null or empty")
+ }
+ return netObj.netCardReset(type, phy_reset)
+}
+
+/**
+ * 鑾峰彇wifi鍒楄〃
+ * @param {*} timeout 蹇呭~
+ * @param {*} interval 蹇呭~
+ * @returns wifi鍒楄〃
+ */
+net.netGetWifiSsidList = function (timeout, interval) {
+ if (timeout === null || timeout === undefined) {
+ throw new Error("dxNet.netGetWifiSsidList: 'timeout' parameter should not be null or empty")
+ }
+ if (interval === null) {
+ throw new Error("dxNet.netGetWifiSsidList: 'interval' parameter should not be null or empty")
+ }
+ return netObj.netGetWifiSsidList(timeout, interval)
+}
+/**
+ * 杩炴帴鍒皐ifi
+ * @param {*} ssid 蹇呭~
+ * @param {*} psk 蹇呭~
+ * @param {*} params 蹇呭~
+ * @returns
+ */
+net.netConnectWifiSsid = function (ssid, psk, params) {
+ if (ssid === null) {
+ throw new Error("dxNet.netConnectWifiSsid: 'ssid' parameter should not be null or empty")
+ }
+ if (psk === null) {
+ throw new Error("dxNet.netConnectWifiSsid: 'psk' parameter should not be null or empty")
+ }
+ if (params === null) {
+ throw new Error("dxNet.netConnectWifiSsid: 'params' parameter should not be null or empty")
+ }
+ return netObj.netConnectWifiSsid(ssid, psk, params)
+}
+/**
+ * 鑾峰彇宸蹭繚瀛樼殑鐑偣鍒楄〃
+ * @returns 宸蹭繚瀛樼殑鐑偣鍒楄〃
+ */
+net.netGetWifiSavedList = function () {
+ return netObj.netGetWifiSavedList()
+}
+/**
+ * 鏂紑褰撳墠杩炴帴鐨剋ifi鐑偣
+ * @returns
+ */
+net.netDisconnetWifi = function () {
+ return netObj.netDisconnetWifi()
+}
+/**
+ * 鑾峰彇褰撳墠鐑偣鐨勪俊鎭�
+ * @param timeout 蹇呭~
+ * @returns
+ */
+net.netGetCurrentWifiInfo = function (timeout) {
+ if (timeout === null) {
+ throw new Error("dxNet.netGetCurrentWifiInfo: 'timeout' parameter should not be null or empty")
+ }
+ return netObj.netGetCurrentWifiInfo(timeout)
+}
+
+/**
+ * 妫�鏌ユ秷鎭槦鍒楁槸鍚︿负绌�
+ * @returns true涓虹┖ false涓嶄负绌�
+ */
+net.msgIsEmpty = function () {
+ return netObj.msgIsEmpty()
+}
+/**
+ * 浠庢秷鎭槦鍒椾腑鍙栫綉缁滃綋鍓嶇姸鎬佹暟鎹紝杩斿洖缁撴瀯绫讳技{"type":1,"status":4锛�"connected":true}
+ * 鍏朵腑type鍙傝�僴et.TYPE鏋氫妇
+ * 鍏朵腑status鐨勫�艰鏄庡涓嬶細
+ * 0, 鏈垵濮嬫��
+ 1, 缃戝崱澶勪簬鍏抽棴鐘舵��
+ 2, 缃戝崱澶勪簬鎵撳紑鐘舵��
+ 3, 缃戠嚎宸叉彃鍏ユ垨鑰厀ifi宸茶繛鎺sid 浣嗘湭鍒嗛厤ip
+ 4, 宸叉垚鍔熷垎閰峣p
+ 5 宸茶繛鎺ユ寚瀹氭湇鍔℃垨鑰呴�氳繃娴嬭瘯鍙互杩炴帴鍒板箍鍩熺綉
+ * @returns 瀛楃涓茬被鍨嬬殑娑堟伅鏁版嵁
+ */
+net.msgReceive = function () {
+ let res = JSON.parse(netObj.msgReceive());
+ if (res.status >= 4) {
+ res.connected = true
+ } else {
+ res.connected = false
+ }
+ return res
+}
+
+net.STATUS_CHANGE = '__netstatus__changed'
+
+/**
+ * 绠�鍖栫綉缁滅粍浠剁殑浣跨敤锛屾棤闇�杞鍘昏幏鍙栫綉缁滅姸鎬侊紝缃戠粶鐨勭姸鎬佷細閫氳繃eventBus鍙戦�佸嚭鍘�
+ * run 鍙細鎵ц涓�娆★紝鎵ц涔嬪悗缃戠粶鍩烘湰閰嶇疆涓嶈兘淇敼
+ * 濡傛灉闇�瑕佸疄鏃惰幏鍙栫綉缁滅姸鎬佸彉鍖栵紝鍙互璁㈤槄 eventBus鐨勪簨浠讹紝浜嬩欢鐨則opic鏄痭et.STATUS_CHANGE锛屼簨浠剁殑鍐呭鏄被浼納"type":1,"status":4锛�"connected":true}
+ * 鍏朵腑type鍙傝�僴et.TYPE鏋氫妇
+ * 鍏朵腑status鐨勫�艰鏄庡涓嬶細
+ * 0, 鏈垵濮嬫��
+ 1, 缃戝崱澶勪簬鍏抽棴鐘舵��
+ 2, 缃戝崱澶勪簬鎵撳紑鐘舵��
+ 3, 缃戠嚎宸叉彃鍏ユ垨鑰厀ifi宸茶繛鎺sid 浣嗘湭鍒嗛厤ip
+ 4, 宸叉垚鍔熷垎閰峣p
+ 5 宸茶繛鎺ユ寚瀹氭湇鍔℃垨鑰呴�氳繃娴嬭瘯鍙互杩炴帴鍒板箍鍩熺綉
+ * @param {object} options 鍙傝�僫nit鐨刼ptions鎻忚堪
+ */
+net.run = function (options) {
+ if (options === undefined || options.length === 0) {
+ throw new Error("dxnet.run:'options' parameter should not be null or empty")
+ }
+ let workerFile = '/app/code/dxmodules/netWorker.js'
+ let init = map.get("__net__run_init")
+ if (!init) {//纭繚鍙垵濮嬪寲涓�娆�
+ map.put("__net__run_init", options)
+ bus.newWorker('__net', workerFile)
+ }
+}
+
+/**
+ * 濡傛灉net鍗曠嫭涓�涓嚎绋嬶紝鍙互鐩存帴浣跨敤run鍑芥暟锛屼細鑷姩鍚姩涓�涓嚎绋嬶紝
+ * 濡傛灉鎯冲姞鍏ュ埌鍏朵粬宸叉湁鐨勭嚎绋嬶紝鍙互浣跨敤浠ヤ笅灏佽鐨勫嚱鏁�
+ */
+net.worker = {
+ //鍦╳hile寰幆鍓�
+ beforeLoop: function (options) {
+ net.init(options)
+ },
+ //鍦╳hile寰幆閲�
+ loop: function () {
+ if (!net.msgIsEmpty()) {
+ let res = net.msgReceive();
+ if (res.status >= 4) {
+ res.connected = true
+ } else {
+ res.connected = false
+ }
+ bus.fire(net.STATUS_CHANGE, res)
+ }
+ }
+}
+
+export default net;
diff --git a/vf205_access/dxmodules/dxNfc.js b/vf205_access/dxmodules/dxNfc.js
new file mode 100644
index 0000000..377c6c4
--- /dev/null
+++ b/vf205_access/dxmodules/dxNfc.js
@@ -0,0 +1,409 @@
+//build:20240715
+//閫氳繃杩欎釜缁勪欢鏉ヨ鍙栧崱锛屽寘鎷琈1鍗★紝psam鍗′箣绫荤殑
+//渚濊禆缁勪欢: dxDriver,dxMap,dxLogger,dxDriver,dxCommon,dxEventBus
+import { nfcClass } from './libvbar-p-dxnfc.so'
+import dxCommon from './dxCommon.js'
+import bus from './dxEventBus.js'
+import dxMap from './dxMap.js'
+const nfcObj = new nfcClass();
+const map = dxMap.get("default")
+const nfc = {}
+
+/**
+ * NFC 鍒濆鍖�
+ * @param {number} useEid 闈炲繀濉紝鏄惁浣跨敤浜戣瘉 0涓嶄娇鐢� 1浣跨敤
+ */
+nfc.init = function (useEid = 0) {
+ let pointer = nfcObj.init(useEid)
+ if (pointer === undefined || pointer === null) {
+ throw new Error("nfc.init: init failed")
+ }
+ dxCommon.handleId("nfc", 'nfcid', pointer)
+}
+
+/**
+ * NFC 鏅�氬崱娉ㄥ唽鍥炶皟
+ */
+nfc.cbRegister = function (callback) {
+ let pointer = dxCommon.handleId("nfc", 'nfcid')
+ return nfcObj.cbRegister(pointer, "nfc_cb", 1, callback)
+}
+
+/**
+ * NFC PSAM鍗℃敞鍐屽洖璋�
+ */
+nfc.psamCbRegister = function (callback) {
+ let pointer = dxCommon.handleId("nfc", 'nfcid')
+ return nfcObj.nfcPsamCheckVgcardCallback(pointer, callback)
+}
+
+/**
+ * NFC 鍙栨秷鍒濆鍖�
+ */
+nfc.deinit = function () {
+ let pointer = dxCommon.handleId("nfc", 'nfcid')
+ let ret = nfcObj.cbUnregister(pointer, "nfc_cb")
+ if (ret === false) {
+ throw new Error("nfc.cbUnregister: cbUnregister failed")
+ }
+ return nfcObj.deinit(pointer)
+}
+
+/**
+ * NFC 鍗′俊鎭垱寤�
+ * @param {number} cardType 鍗¤姱鐗囩被鍨�(鍘熷巶瀹氫箟)
+ * @param {ArrayBuffer} cardId 鍗″彿
+ * @param {number} type 鍗$被鍨�(鎴戜滑鑷繁瀹氫箟鐨�)
+ * @returns cardInfo(pointer)
+ */
+nfc.cardInfoCreate = function (cardType, cardId, type) {
+ if (!cardType) {
+ throw new Error("cardInfoCreate:cardType should not be null or empty")
+ }
+ if (!cardId) {
+ throw new Error("cardInfoCreate:cardId should not be null or empty")
+ }
+ if (!type) {
+ throw new Error("cardInfoCreate:type should not be null or empty")
+ }
+ return nfcObj.cardInfoCreate(cardType, cardId, type);
+}
+
+/**
+ * NFC 鍗′俊鎭攢姣�
+ * @param {pointer} cardInfo 鍗′俊鎭�
+ * @returns
+ */
+nfc.cardInfoDestory = function (cardInfo) {
+ if (!cardInfo) {
+ throw new Error("cardInfoDestory:cardInfo should not be null or empty")
+ }
+ return nfcObj.cardInfoDestory(cardInfo);
+}
+
+/**
+ * NFC 鍗′俊鎭鍒�
+ * @param {pointer} cardInfo 鍗′俊鎭�
+ * @returns cardInfo(pointer)
+ */
+nfc.cardInfoCopy = function (cardInfo) {
+ if (cardInfo == null) {
+ throw new Error("cardInfoCopy:cardInfo should not be null or empty")
+ }
+ return nfcObj.cardInfoCopy(cardInfo);
+}
+
+/**
+ * NFC 鍒ゆ柇鏄惁鏈夊崱
+ * @returns bool
+ */
+nfc.isCardIn = function () {
+ let pointer = dxCommon.handleId("nfc", 'nfcid')
+ return nfcObj.isCardIn(pointer);
+}
+
+/**
+ * NFC 璇籑1鍗℃墖鍖�
+ * @param {number} taskFlg 浠诲姟鏍囧織锛�
+ * 0x00->AUTO 鍛婄煡鎵爜鍣ㄨ鎸囦护鍙崟鐙墽琛岋紝鏃犳寚浠ら棿鐨勪緷璧栧叧绯汇��
+ * 0x01->START 鍛婄煡鎵爜鍣ㄥ紑濮嬪鍗℃搷浣滄垨瀵瑰崱鎿嶄綔灏氭湭缁撴潫锛屼笖鎸囦护闂村彲鑳藉瓨鍦ㄤ緷璧栧叧绯汇��
+ * 0x02->FINISH 鍛婄煡鎵爜鍣ㄦ湰鏉℃寚浠ゆ槸鎿嶄綔鍗$殑鏈�鍚庝竴鏉℃寚浠わ紝灏嗗崱鐗囨搷浣滅幆澧冩仮澶嶅埌榛樻�併��
+ * @param {number} secNum 鎵囧尯鍙�
+ * @param {number} logicBlkNum 鍧楀彿锛堝湪鎵囧尯鍐呯殑閫昏緫鍙�0~3)
+ * @param {number} blkNums 鍧楁暟
+ * @param {array} key 瀵嗛挜, 闀垮害6bytes
+ * @param {number} keyType 瀵嗛挜绫诲瀷: A:0x60 B:0x61
+ * @returns Array 璇诲彇缁撴灉 undefined:澶辫触
+ */
+nfc.m1cardReadSector = function (taskFlg, secNum, logicBlkNum, blkNums, key, keyType) {
+ let pointer = dxCommon.handleId("nfc", 'nfcid')
+ _validate('m1cardReadSector', taskFlg, secNum, logicBlkNum, blkNums, key, keyType, ' ')
+ return nfcObj.m1cardReadSector(pointer, taskFlg, secNum, logicBlkNum, blkNums, key, keyType);
+}
+
+/**
+ * NFC 璇籑1鍗℃墖鍖�
+ * @param {number} taskFlg 浠诲姟鏍囧織锛�
+ * 0x00->AUTO 鍛婄煡鎵爜鍣ㄨ鎸囦护鍙崟鐙墽琛岋紝鏃犳寚浠ら棿鐨勪緷璧栧叧绯汇��
+ * 0x01->START 鍛婄煡鎵爜鍣ㄥ紑濮嬪鍗℃搷浣滄垨瀵瑰崱鎿嶄綔灏氭湭缁撴潫锛屼笖鎸囦护闂村彲鑳藉瓨鍦ㄤ緷璧栧叧绯汇��
+ * 0x02->FINISH 鍛婄煡鎵爜鍣ㄦ湰鏉℃寚浠ゆ槸鎿嶄綔鍗$殑鏈�鍚庝竴鏉℃寚浠わ紝灏嗗崱鐗囨搷浣滅幆澧冩仮澶嶅埌榛樻�併��
+ * @param {number} secNum 鎵囧尯鍙�
+ * @param {number} logicBlkNum 鍧楀彿锛堝湪鎵囧尯鍐呯殑閫昏緫鍙�0~3)
+ * @param {number} blkNums 鍧楁暟
+ * @param {array} key 瀵嗛挜, 闀垮害6bytes
+ * @param {number} keyType 瀵嗛挜绫诲瀷: A:0x60 B:0x61
+ * @param {array} data 鍐欏叆鏁版嵁
+ * @returns int 鍐欏叆闀垮害 -1:閿欒
+ */
+nfc.m1cardWriteSector = function (taskFlg, secNum, logicBlkNum, blkNums, key, keyType, data) {
+ let pointer = dxCommon.handleId("nfc", 'nfcid')
+ _validate('m1cardWriteSector', taskFlg, secNum, logicBlkNum, blkNums, key, keyType, data)
+ return nfcObj.m1cardWriteSector(pointer, taskFlg, secNum, logicBlkNum, blkNums, key, keyType, data);
+}
+
+/**
+ *
+ * @param {number} taskFlg 浠诲姟鏍囧織锛�
+ * 0x00->AUTO 鍛婄煡鎵爜鍣ㄨ鎸囦护鍙崟鐙墽琛岋紝鏃犳寚浠ら棿鐨勪緷璧栧叧绯汇��
+ * 0x01->START 鍛婄煡鎵爜鍣ㄥ紑濮嬪鍗℃搷浣滄垨瀵瑰崱鎿嶄綔灏氭湭缁撴潫锛屼笖鎸囦护闂村彲鑳藉瓨鍦ㄤ緷璧栧叧绯汇��
+ * 0x02->FINISH 鍛婄煡鎵爜鍣ㄦ湰鏉℃寚浠ゆ槸鎿嶄綔鍗$殑鏈�鍚庝竴鏉℃寚浠わ紝灏嗗崱鐗囨搷浣滅幆澧冩仮澶嶅埌榛樻�併��
+ * @param {number} blkNums 鍧楀彿
+ * @param {array} key 瀵嗛挜, 闀垮害6bytes
+ * @param {number} keyType 瀵嗛挜绫诲瀷: A:0x60 B:0x61
+ * @returns Array 璇诲彇缁撴灉 undefined:澶辫触
+ */
+nfc.m1cardReadBlk = function (taskFlg, blkNum, key, keyType) {
+ let pointer = dxCommon.handleId("nfc", 'nfcid')
+ _validate('m1cardReadBlk', taskFlg, 1, 0, blkNum, key, keyType, ' ')
+ return nfcObj.m1cardReadBlk(pointer, taskFlg, blkNum, key, keyType);
+}
+
+/**
+ *
+ * @param {number} taskFlg 浠诲姟鏍囧織锛�
+ * 0x00->AUTO 鍛婄煡鎵爜鍣ㄨ鎸囦护鍙崟鐙墽琛岋紝鏃犳寚浠ら棿鐨勪緷璧栧叧绯汇��
+ * 0x01->START 鍛婄煡鎵爜鍣ㄥ紑濮嬪鍗℃搷浣滄垨瀵瑰崱鎿嶄綔灏氭湭缁撴潫锛屼笖鎸囦护闂村彲鑳藉瓨鍦ㄤ緷璧栧叧绯汇��
+ * 0x02->FINISH 鍛婄煡鎵爜鍣ㄦ湰鏉℃寚浠ゆ槸鎿嶄綔鍗$殑鏈�鍚庝竴鏉℃寚浠わ紝灏嗗崱鐗囨搷浣滅幆澧冩仮澶嶅埌榛樻�併��
+ * @param {number} blkNums 鍧楀彿
+ * @param {array} key 瀵嗛挜, 闀垮害6bytes
+ * @param {number} keyType 瀵嗛挜绫诲瀷: A:0x60 B:0x61
+ * @param {array} data 鍐欏叆鏁版嵁
+ * @returns int 鍐欏叆闀垮害 -1:閿欒
+ */
+nfc.m1cardWriteBlk = function (taskFlg, blkNum, key, keyType, data) {
+ let pointer = dxCommon.handleId("nfc", 'nfcid')
+ _validate('m1cardWriteBlk', taskFlg, 1, 0, blkNum, key, keyType, data)
+ return nfcObj.m1cardWriteBlk(pointer, taskFlg, blkNum, key, keyType, data);
+}
+/**
+ * ATS妫�娴�
+ */
+nfc.nfc_iso14443_type_a_get_ats = function () {
+ let pointer = dxCommon.handleId("nfc", 'nfcid')
+ return nfcObj.nfc_iso14443_type_a_get_ats(pointer)
+}
+
+/**
+ *
+ * @param {number} taskFlg 浠诲姟鏍囧織锛�
+ * 0x00->AUTO 鍛婄煡鎵爜鍣ㄨ鎸囦护鍙崟鐙墽琛岋紝鏃犳寚浠ら棿鐨勪緷璧栧叧绯汇��
+ * 0x01->START 鍛婄煡鎵爜鍣ㄥ紑濮嬪鍗℃搷浣滄垨瀵瑰崱鎿嶄綔灏氭湭缁撴潫锛屼笖鎸囦护闂村彲鑳藉瓨鍦ㄤ緷璧栧叧绯汇��
+ * 0x02->FINISH 鍛婄煡鎵爜鍣ㄦ湰鏉℃寚浠ゆ槸鎿嶄綔鍗$殑鏈�鍚庝竴鏉℃寚浠わ紝灏嗗崱鐗囨搷浣滅幆澧冩仮澶嶅埌榛樻�併��
+ * @param {ArrayBuffer} buffer 瑕佸彂閫佺殑鏁版嵁
+ * @param {number} bufferLen 瑕佸彂閫佺殑鏁版嵁闀垮害
+ * @returns buffer
+ */
+nfc.iso14443Apdu = function (taskFlg, buffer, bufferLen) {
+ let pointer = dxCommon.handleId("nfc", "nfcid")
+ return nfcObj.iso14443Apdu(pointer, taskFlg, buffer, bufferLen);
+}
+
+/**
+ * PSAM鍗℃柇鐢�
+ */
+nfc.nfcPsamPowerDown = function () {
+ let pointer = dxCommon.handleId("nfc", "nfcid")
+ return nfcObj.nfcPsamPowerDown(pointer);
+}
+
+/**
+ * NFC 鏀瑰彉鐘舵��
+ */
+nfc.nfcPsamChangeBaud = function () {
+ let pointer = dxCommon.handleId("nfc", "nfcid")
+ return nfcObj.nfcPsamChangeBaud(pointer);
+}
+
+/**
+ * PSAM鍗¢噸缃�
+ */
+nfc.nfcPsamCardReset = function (force) {
+ let pointer = dxCommon.handleId("nfc", "nfcid")
+ return nfcObj.nfcPsamCardReset(pointer, force);
+}
+
+/**
+ * 鍙戦�丳SAM APDU鎸囦护
+ */
+nfc.nfcPsamCardApdu = function (buffer) {
+ let pointer = dxCommon.handleId("nfc", "nfcid")
+ return nfcObj.nfcPsamCardApdu(pointer, buffer);
+}
+
+/**
+ * EID 鏇存柊浜戣瘉閰嶇疆
+ * @param {object} eidConfig 浜戣瘉閰嶇疆
+ * @param {string} eidConfig.appid 骞冲彴鍒嗛厤缁欏簲鐢ㄧ殑appid
+ * @param {number} eidConfig.read_len; // 鍗曟璇诲崱闀垮害锛岄粯璁�0x80
+ * @param {number} eidConfig.declevel; // 鏄惁璇诲彇鐓х墖锛�1涓轰笉璇诲彇锛�2涓鸿鍙�
+ * @param {number} eidConfig.loglevel; //鏃ュ織绾у埆锛屾敮鎸�0锛�1锛�2
+ * @param {number} eidConfig.model; // 鏄惁鐩存帴鏌ュ嚭淇℃伅 0鏄� 1鍚� 锛堝嵆0鏄師璺繑鍥烇紝杩斿洖韬唤淇℃伅锛�1鏄浆鍙戯紝杩斿洖reqid锛�
+ * @param {number} eidConfig.type; // 鍗$墖绫诲瀷锛�0 韬唤璇� 1鐢靛瓙璇佺収
+ * @param {number} eidConfig.pic_type; // 鐓х墖瑙g爜鏁版嵁绫诲瀷 0 wlt 1 jpg
+ * @param {number} eidConfig.envCode; // 鐜璇嗗埆鐮�
+ * @param {string} eidConfig.sn[128]; // 璁惧搴忓垪鍙�
+ * @param {string} eidConfig.device_model[128]; // 璁惧鍨嬪彿
+ * @param {number} eidConfig.info_type; // 淇℃伅杩斿洖绫诲瀷锛�0 韬唤淇℃伅缁撴瀯浣� 锛�1鍘熷鏁版嵁 char
+ */
+nfc.eidUpdateConfig = function (eidConfig) {
+ if (eidConfig == null) {
+ throw new Error("eidUpdateConfig:eidConfig should not be null or empty")
+ }
+ return nfcObj.eidUpdateConfig(eidConfig);
+}
+
+/**
+ * 璇籒TAG鐗堟湰鍙�
+ * @param {number} hdl nfc鍙ユ焺
+ * @returns {ArrayBuffer} buffer
+ */
+nfc.nfcNtagReadVersion = function () {
+ let pointer = dxCommon.handleId("nfc", 'nfcid')
+ return nfcObj.nfcNtagReadVersion(pointer);
+}
+
+/**
+ * 璇籒TAG椤靛唴瀹� 鍥哄畾璇诲彇4椤靛叡16瀛楄妭
+ * @param {number} hdl nfc鍙ユ焺
+ * @param {number} pageNum 璧峰椤靛湴鍧�锛�
+ * 姣忔璇诲彇鍥涗釜椤�
+ * 濡傛灉鍦板潃(Addr)鏄�04h锛屽垯杩斿洖椤�04h銆�05h銆�06h銆�07h鍐呭
+ * @returns {ArrayBuffer} buffer
+ */
+nfc.nfcNtagReadPage = function (pageNum) {
+ let pointer = dxCommon.handleId("nfc", 'nfcid')
+ if (pageNum == null) {
+ throw new Error("nfcNtagReadPage:pageNum should not be null or empty")
+ }
+ return nfcObj.nfcNtagReadPage(pointer, pageNum);
+}
+
+/**
+ * 璇籒TAG澶氶〉鍐呭 璇诲彇鏁版嵁鐨刡uffer,鏈�灏忎负 椤垫暟*4锛涜璇诲彇鐨勬暟鎹暱搴� 椤垫暟*4
+ * @param {number} hdl nfc鍙ユ焺
+* @param {number} start_addr 璧峰椤靛湴鍧�
+ * @param {number} end_addr 缁撴潫椤靛湴鍧�
+ * @returns {ArrayBuffer} buffer
+ */
+nfc.nfcNtagFastReadPage = function (start_page, end_page) {
+ let pointer = dxCommon.handleId("nfc", 'nfcid')
+ if (start_page == null) {
+ throw new Error("nfcNtagFastReadPage:start_page should not be null or empty")
+ }
+ if (end_page == null) {
+ throw new Error("nfcNtagFastReadPage:end_page should not be null or empty")
+ }
+ return nfcObj.nfcNtagFastReadPage(pointer, start_page, end_page);
+}
+
+/**
+ * 鍐橬TAG椤靛唴瀹�
+ * @param {number} hdl nfc鍙ユ焺
+ * @param {number} pageNum 鍐欏叆鐨勯〉鍙� 锛氭湁鏁圓ddr鍙傛暟
+ * 瀵逛簬NTAG213锛岄〉鍦板潃02h鑷�2Ch
+ * 瀵逛簬NTAG215锛岄〉鍦板潃02h鑷�86h
+ * 瀵逛簬NTAG216锛岄〉鍦板潃02h鑷矱6h
+ * @param {ArrayBuffer} pageData 鍐欏叆椤电殑鍐呭锛氬洓瀛楄妭
+ * @returns {boolean} ture/false
+ */
+nfc.nfcNtagWritePage = function (pageNum, pageData) {
+ let pointer = dxCommon.handleId("nfc", 'nfcid')
+ if (pageNum == null) {
+ throw new Error("nfcNtagWritePage:pageNum should not be null or empty")
+ }
+ if (!pageData) {
+ throw new Error("nfcNtagWritePage:pageData should not be null or empty")
+ }
+ return nfcObj.nfcNtagWritePage(pointer, pageNum, pageData);
+}
+
+/**
+ * 鍒ゆ柇nfc娑堟伅闃熷垪鏄惁涓虹┖
+ * @returns bool
+ */
+nfc.msgIsEmpty = function () {
+ let pointer = dxCommon.handleId("nfc", 'nfcid')
+ return nfcObj.msgIsEmpty(pointer)
+}
+
+/**
+ * 浠巒fc娑堟伅闃熷垪涓鍙栨暟鎹�
+ * @returns json娑堟伅瀵硅薄
+ */
+nfc.msgReceive = function () {
+ let pointer = dxCommon.handleId("nfc", 'nfcid')
+ let msg = nfcObj.msgReceive(pointer)
+ return JSON.parse(msg);
+}
+
+function _validate(fun, taskFlg, secNum, logicBlkNum, blkNums, key, keyType, data) {
+ if (![0x00, 0x01, 0x02].includes(taskFlg)) {
+ throw new Error(fun, ":taskFlg error")
+ }
+ if (!(secNum >= 0)) {
+ throw new Error(fun, ":secNum error")
+ }
+ if (logicBlkNum == null || logicBlkNum == undefined || logicBlkNum < 0 || logicBlkNum > 3) {
+ throw new Error(fun, ":logicBlkNum error")
+ }
+ if (blkNums == null || blkNums == undefined || blkNums < 0 || blkNums > 59) {
+ throw new Error(fun, ":blkNums error")
+ }
+ if (key == null || key === undefined || key.length < 0) {
+ throw new Error(fun, ":key error")
+ }
+ if (![0x60, 0x61].includes(keyType)) {
+ throw new Error(fun, ":keyType error")
+ }
+ if (data === null || data === undefined) {
+ throw new Error(fun, ":data error")
+ }
+}
+
+nfc.RECEIVE_MSG = '__nfc__MsgReceive'
+
+/**
+ * 绠�鍖朜FC缁勪欢鐨勪娇鐢紝鏃犻渶杞鍘昏幏鍙栫綉缁滅姸鎬侊紝缃戠粶鐨勭姸鎬佷細閫氳繃eventcenter鍙戦�佸嚭鍘�
+ * run 鍙細鎵ц涓�娆★紝鎵ц涔嬪悗缃戠粶鍩烘湰閰嶇疆涓嶈兘淇敼
+ * 濡傛灉闇�瑕佸疄鏃惰幏鍙栧埛鍗℃暟鎹紝鍙互璁㈤槄 eventCenter鐨勪簨浠讹紝浜嬩欢鐨則opic鏄痭fc.CARD锛屼簨浠剁殑鍐呭鏄被浼�
+ * {id:'鍗d',card_type:鍗¤姱鐗囩被鍨�,id_len:鍗″彿闀垮害,type锛氬崱绫诲瀷,timestamp:'鍒峰崱鏃堕棿鎴�',monotonic_timestamp:'鐩稿寮�鏈虹殑鏃堕棿'}
+ * @param {*} options
+ * @param {boolean} options.m1 闈炲繀濉紝鏅�氬崱鍥炶皟寮�鍏�
+ * @param {boolean} options.psam 闈炲繀濉紝psam鍗″洖璋冨紑鍏�
+ */
+nfc.run = function (options) {
+ if (options === undefined || options.length === 0) {
+ throw new Error("dxnfc.run:'options' parameter should not be null or empty")
+ }
+ let init = map.get("__nfc__run_init")
+ if (!init) {//纭繚鍙垵濮嬪寲涓�娆�
+ map.put("__nfc__run_init", options)
+ bus.newWorker("__nfc", '/app/code/dxmodules/nfcWorker.js')
+ }
+}
+
+/**
+ * 濡傛灉nfc鍗曠嫭涓�涓嚎绋嬶紝鍙互鐩存帴浣跨敤run鍑芥暟锛屼細鑷姩鍚姩涓�涓嚎绋嬶紝
+ * 濡傛灉鎯冲姞鍏ュ埌鍏朵粬宸叉湁鐨勭嚎绋嬶紝鍙互浣跨敤浠ヤ笅灏佽鐨勫嚱鏁�
+ */
+nfc.worker = {
+ //鍦╳hile寰幆鍓�
+ beforeLoop: function (options) {
+ nfc.init(options.useEid)
+ // PSAM鍜屾櫘閫氬崱鍥炶皟
+ if (options.m1) {
+ nfc.cbRegister()
+ }
+ if (options.psam) {
+ nfc.psamCbRegister()
+ }
+ },
+ //鍦╳hile寰幆閲�
+ loop: function () {
+ if (!nfc.msgIsEmpty()) {
+ let res = nfc.msgReceive();
+ bus.fire(nfc.RECEIVE_MSG, res)
+ }
+ }
+}
+export default nfc;
diff --git a/vf205_access/dxmodules/dxNtp.js b/vf205_access/dxmodules/dxNtp.js
new file mode 100644
index 0000000..1e79146
--- /dev/null
+++ b/vf205_access/dxmodules/dxNtp.js
@@ -0,0 +1,63 @@
+//build: 20240523
+//鍚屾鏃堕棿,杩愯鏃堕渶瑕佹妸杩欎釜缁勪欢鍔犺浇鍒颁竴涓嚎绋嬮噷鐨剋hile寰幆,
+//缂虹渷姣忛殧24灏忔椂鍚屾涓�娆★紝涔熸敮鎸佷簨浠惰Е鍙戜富鍔ㄥ悓姝� eventcetner.fire(ntp.MANUAL_SYNC)
+//渚濊禆缁勪欢 dxLogger,dxCommon,dxCenter
+
+import common from "./dxCommon.js"
+import dxNet from './dxNet.js'
+import log from './dxLogger.js'
+const ntp = {}
+/**
+ * 鍚屾鏃堕棿寰幆鍒濆鍖�
+ * @param {string} server 鍚屾鏃堕棿鏈嶅姟鍣ㄥ湴鍧�锛岀己鐪佹槸182.92.12.11
+ * @param {number} interval 鍚屾鏃堕棿鐨勯棿闅旓紝鍗曚綅鏄垎閽燂紝缂虹渷鏄�24灏忔椂鍚屾涓�娆�
+ *
+ */
+ntp.beforeLoop = function (server = '182.92.12.11', interval = 24 * 60) {
+ this.server = server
+ this.interval = interval
+ this.tempinterval = 1000//绗竴娆¢殧1绉掑氨寮�濮嬬涓�娆″鏃�
+ this.last = new Date().getTime()
+}
+/**
+ * 鏇存柊鏃跺尯GMT锛屾瘮濡�8锛岃〃绀篏MT8鍖椾含鏃堕棿
+ * @param {number} gmt 鍙栧�艰寖鍥存槸0,1,2....24琛ㄧず鏃跺尯锛�
+ */
+ntp.updateGmt = function (gmt) {
+ if (gmt != undefined && gmt != null) {
+ let cmd = `cp /etc/localtimes/localtime${gmt} /etc/localtime`
+ common.systemBrief(cmd)
+ }
+}
+/**
+ * 绔嬪埢鍚屾
+ */
+ntp.syncnow = false
+/**
+ * 鍚屾鏃堕棿
+ */
+ntp.loop = function () {
+ if (!dxNet.getStatus().connected) {//娌℃湁缃戠粶
+ return
+ }
+ const now = new Date().getTime()
+ const minus = now - this.last
+ if (ntp.syncnow || (minus > (this.tempinterval))) {
+ ntp.syncnow = false
+ let cmd = `ntpdate -u -t 1 '${this.server}' > /dev/null && echo 'Y' || echo 'N'`
+ let res = common.systemWithRes(cmd, 100).split(/\s/)[0]
+ if (res != "Y" ) {
+ // 瀵规椂澶辫触锛�1鍒嗗悗閲嶈瘯
+ log.error('ntp sync failed')
+ this.tempinterval = 60 * 1000
+ } else {
+ // 瀵规椂鎴愬姛
+ log.info('ntp sync success')
+ this.tempinterval = this.interval * 60 * 1000
+ common.systemBrief("hwclock -u -w")
+ }
+ this.last = new Date().getTime()
+ }
+}
+
+export default ntp;
\ No newline at end of file
diff --git a/vf205_access/dxmodules/dxOta.js b/vf205_access/dxmodules/dxOta.js
new file mode 100644
index 0000000..a0061ee
--- /dev/null
+++ b/vf205_access/dxmodules/dxOta.js
@@ -0,0 +1,256 @@
+//build:20240724
+// 璐熻矗鍥轰欢鐨勫崌绾�
+import log from './dxLogger.js'
+import com from './dxCommon.js'
+import http from './dxHttp.js'
+import * as os from 'os';
+
+const ota = {}
+//鑾峰彇褰撳墠纾佺洏鍓╀綑澶у皬锛坘锛夊彲鑳戒笉鍚岀殑鎿嶄綔绯荤粺鎸囦护涓嶄竴鏍�
+ota.DF_CMD = `df -k / | awk 'NR==2 {print $4}'`
+ota.OTA_ROOT = '/ota'
+ota.OTA_RUN = ota.OTA_ROOT + '/run.sh'
+
+
+/**
+ * HTTP鍗囩骇锛氱綉缁滀笅杞藉崌绾у寘鍗囩骇
+ * @param {string} url 蹇呭~锛屼笅杞藉崌绾у寘鐨刪ttp url鍦板潃
+ * @param {string} md5 蹇呭~锛屽崌绾у寘鐨刴d5鏍囪瘑锛屼笅杞藉畬閫氳繃md5鏉ュ垽鏂槸鍚﹀畬鏁淬��32闀垮害鐨勫叏灏忓啓16杩涘埗瀛楃涓�
+ * @param {number} size 闈炲繀濉紝鍗囩骇鍖呯殑澶ф澶у皬锛屽崟浣嶆槸k锛屽鏋滄枃浠跺お澶ц�屽墿浣欑鐩樹笉澶燂紝浼氭彁鍓嶆姤閿欒锛屼笉浼氬紑濮嬪惎鍔ㄤ笅杞�
+ * @param {number} timeout 闈炲繀濉紝灏濊瘯閾炬帴涓嬭浇鍦板潃鐨勮秴鏃舵椂闂达紙涓嶆槸涓嬭浇瀹屾垚鐨勬椂闂达級锛岀己鐪佹槸3绉�
+ * @param {string} password 闈炲繀濉紝涓嬭浇瀹夎鍖呯殑瀵嗙爜锛屽彲閫夛紝濡傛灉璁剧疆锛屼笅杞芥椂闇�瑕佽緭鍏ュ瘑鐮�
+ */
+ota.updateHttp = function (url, md5, timeout = 3, password, size) {
+ if (!url || !md5) {
+ throw new Error("The 'url' and 'md5' param should not be null")
+ }
+ if (size && (typeof size != 'number')) {
+ throw new Error("The 'size' param should be a number")
+ }
+ //1. 鏌ョ湅纾佺洏杩樺墿浣欑殑澶у皬
+ let df = parseInt(com.systemWithRes(ota.DF_CMD, 1000))
+ if (size) {
+ if (df < (3 * size)) {//澶ф鏈湴蹇呴』鏈夊畨瑁呭寘3鍊嶅ぇ灏忕殑绌洪棿
+ throw new Error('The upgrade package is too large, and not be enough space on the disk to download it')
+ }
+ }
+ //2. 涓嬭浇鏂囦欢鍒颁复鏃剁洰褰�
+ const firmware = '/upgrades.zip'
+ const temp = '/upgrades.temp'
+ com.systemBrief(`rm -rf ${firmware} && rm -rf ${temp} `) //鍏堝垹闄ta鏍圭洰褰�
+
+ let downloadRet = http.download(url + (password ? "&password=" + password : '') , temp, null, timeout*1000)
+ let fileExist = (os.stat(temp)[1] === 0)
+ if (!fileExist) {
+ log.error("download result" + downloadRet)
+ com.systemBrief(`rm -rf ${firmware} && rm -rf ${temp} `)
+ throw new Error('Download failed, please check the url:' + url)
+ }
+ //3. 璁$畻骞舵瘮杈僲d5鏄惁涓�鏍�
+ let md5Hash = com.md5HashFile(temp)
+ md5Hash = md5Hash.map(v => v.toString(16).padStart(2, 0)).join('')
+ if (md5Hash != md5) {
+ com.systemBrief(`rm -rf ${firmware} && rm -rf ${temp} `)
+ throw new Error('Download failed with wrong md5 value')
+ }
+ //4. md5鏍¢獙閫氳繃锛屽皢鍗囩骇鍖呮斁鍒板崌绾х洰褰曚笅锛岀瓑寰呴噸鍚崌绾�
+ com.systemBrief(`mv ${temp} ${firmware} `)
+}
+
+
+/**
+ * 鏂囦欢鍗囩骇锛氶�氳繃鍏朵粬鏂瑰紡灏嗗崌绾у寘鏀惧埌鐢ㄦ埛鐩綍涓嬶紝璋冪敤姝ゆ柟娉曞崌绾�
+ * @param {string} path 蹇呭~锛屼笅杞藉崌绾у寘鐨刪ttp url鍦板潃
+ * @param {string} md5 蹇呭~锛屽崌绾у寘鐨刴d5鏍囪瘑锛屼笅杞藉畬閫氳繃md5鏉ュ垽鏂槸鍚﹀畬鏁淬��32闀垮害鐨勫叏灏忓啓16杩涘埗瀛楃涓�
+ * @param {number} size 闈炲繀濉紝鍗囩骇鍖呯殑澶ф澶у皬锛屽崟浣嶆槸k锛屽鏋滄枃浠跺お澶ц�屽墿浣欑鐩樹笉澶燂紝浼氭彁鍓嶆姤閿欒锛屼笉浼氬紑濮嬪惎鍔ㄤ笅杞�
+ */
+ota.updateFile = function (path, md5, size) {
+ if (!path || !md5) {
+ throw new Error("The 'path' and 'md5' param should not be null")
+ }
+ if (size && (typeof size != 'number')) {
+ throw new Error("The 'size' param should be a number")
+ }
+
+ //1. 鏌ョ湅纾佺洏杩樺墿浣欑殑澶у皬
+ let df = parseInt(com.systemWithRes(ota.DF_CMD, 1000))
+ if (size) {
+ if (df < (3 * size)) {//澶ф鏈湴蹇呴』鏈夊畨瑁呭寘3鍊嶅ぇ灏忕殑绌洪棿
+ throw new Error('The upgrade package is too large, and not be enough space on the disk to download it')
+ }
+ }
+
+ //2. 璁$畻骞舵瘮杈僲d5鏄惁涓�鏍�
+ let md5Hash = com.md5HashFile(path)
+ md5Hash = md5Hash.map(v => v.toString(16).padStart(2, 0)).join('')
+ if (md5Hash != md5) {
+ throw new Error('With wrong md5 value')
+ }
+
+ //3. md5鏍¢獙閫氳繃锛屽皢鍗囩骇鍖呮斁鍒板崌绾х洰褰曚笅锛岀瓑寰呴噸鍚崌绾�
+ const firmware = '/upgrades.zip'
+ com.systemBrief(`mv ${path} ${firmware} `)
+}
+
+
+/**
+ * 娉ㄦ剰锛氭鏂规硶鍗冲皢杩囨湡锛岀敤浜庡吋瀹规棫鐗堟湰锛屾柊鐗堟湰涓嶆帹鑽愪娇鐢�
+ * 鍗囩骇鍒嗕簩澶ф楠わ紝绗竴姝ユ槸鍦ㄥ簲鐢ㄧ涓嬭浇鍗囩骇鍖咃紙zip锛夛紝瑙e帇鍗囩骇鍖�
+ * 绗簩姝ュ寘鎷噸鍚澶囷紝鍒╃敤鑴氭湰澶嶅埗鐩綍鍜屾枃浠舵垨棰濆涓�浜涙搷浣�
+ * 濡傛灉鍦ㄥ崌绾у寘鏍圭洰褰曚笅鏀句竴涓猚ustom_update.sh,灏变細鍏堟墽琛岃繖涓猻hell鏂囦欢锛屾垜浠彲浠ュ湪杩欎釜鏂囦欢閲屾斁涓�浜涜嚜瀹氫箟鐨勫崌绾у姩浣�
+ * @param {string} url 蹇呭~锛屼笅杞藉崌绾у寘鐨刪ttp url鍦板潃
+ * @param {string} md5 蹇呭~锛屽崌绾у寘鐨刴d5鏍囪瘑锛屼笅杞藉畬閫氳繃md5鏉ュ垽鏂槸鍚﹀畬鏁淬��32闀垮害鐨勫叏灏忓啓16杩涘埗瀛楃涓�
+ * @param {number} size 闈炲繀濉紝鍗囩骇鍖呯殑澶ф澶у皬锛屽崟浣嶆槸k锛屽鏋滄枃浠跺お澶ц�屽墿浣欑鐩樹笉澶燂紝浼氭彁鍓嶆姤閿欒锛屼笉浼氬紑濮嬪惎鍔ㄤ笅杞�
+ * @param {string} shell 闈炲繀濉紝閲嶅惎璁惧鍚庣殑鍗囩骇鑴氭湰鍐呭锛岃В鍘嬪悗鐨勬枃浠跺す缂虹渷鏄� /ota/temp,鍗囩骇浼氱己鐪佹妸/ota/temp涓嬫墍鏈夋枃浠舵嫹璐濆鍒跺埌/app/code/涓�
+ * @param {number} timeout 闈炲繀濉紝灏濊瘯閾炬帴涓嬭浇鍦板潃鐨勮秴鏃舵椂闂达紙涓嶆槸涓嬭浇瀹屾垚鐨勬椂闂达級锛岀己鐪佹槸3绉�
+ */
+ota.update = function (url, md5, size, shell, timeout = 3) {
+ if (!url || !md5) {
+ throw new Error("The 'url' and 'md5' param should not be null")
+ }
+ if (size && (typeof size != 'number')) {
+ throw new Error("The 'size' param should be a number")
+ }
+ //1. 鏌ョ湅纾佺洏杩樺墿浣欑殑澶у皬
+ let df = parseInt(com.systemWithRes(ota.DF_CMD, 1000))
+ if (size) {
+ if (df < (3 * size)) {//澶ф鏈湴蹇呴』鏈夊畨瑁呭寘3鍊嶅ぇ灏忕殑绌洪棿
+ throw new Error('The upgrade package is too large, and not be enough space on the disk to download it')
+ }
+ }
+ //2. 涓嬭浇鏂囦欢鍒扮壒瀹氱洰褰�
+ const firmware = ota.OTA_ROOT + '/download.zip'
+ const temp = ota.OTA_ROOT + '/temp'
+ com.systemBrief(`rm -rf ${ota.OTA_ROOT} && mkdir ${ota.OTA_ROOT} `) //鍏堝垹闄ta鏍圭洰褰�
+ let download = `wget --no-check-certificate --timeout=${timeout} -c "${url}" -O ${firmware} 2>&1`
+ com.systemBrief(download, 1000)
+ let fileExist = (os.stat(firmware)[1] === 0)
+ let downloadRet
+ if (!fileExist) {
+ downloadRet = http.download(url, firmware, null, timeout*1000)
+ }
+ fileExist = (os.stat(firmware)[1] === 0)
+ if (!fileExist) {
+ log.error("download result" + downloadRet)
+ throw new Error('Download failed, please check the url:' + url)
+ }
+ //3. 璁$畻骞舵瘮杈僲d5鏄惁涓�鏍�
+ let md5Hash = com.md5HashFile(firmware)
+ md5Hash = md5Hash.map(v => v.toString(16).padStart(2, 0)).join('')
+ if (md5Hash != md5) {
+ log.error("download result" + downloadRet)
+ throw new Error('Download failed with wrong md5 value')
+ }
+ //4. 瑙e帇
+ com.systemBrief(`mkdir ${temp} && unzip -o ${firmware} -d ${temp}`)
+ //5. 鎵ц鑷畾涔夌殑鍗囩骇鑴氭湰
+ const custom_update = temp+'/custom_update.sh'
+ if(os.stat(custom_update)[1] === 0){
+ com.systemBrief(`chmod +x ${custom_update}`)
+ com.systemWithRes(`${custom_update}`)
+ }
+ //6. 鏋勫缓鑴氭湰鏂囦欢
+ if (!shell) {
+ //缂虹渷鍙槸鎷疯礉鐩綍骞跺垹闄ta鏍圭洰褰�
+ shell = `cp -r ${temp}/* /app/code \n rm -rf ${ota.OTA_ROOT}`
+ }
+
+ com.systemBrief(`echo "${shell}" > ${ota.OTA_RUN} && chmod +x ${ota.OTA_RUN}`)
+ fileExist = (os.stat(ota.OTA_RUN)[1] === 0)
+ if (!fileExist) {
+ throw new Error('Build shell file failed')
+ }
+ com.systemWithRes(`${ota.OTA_RUN}`)
+}
+
+/**
+ * 娉ㄦ剰锛氭鏂规硶鍗冲皢杩囨湡锛岀敤浜庡吋瀹规棫鐗堟湰锛屾柊鐗堟湰涓嶆帹鑽愪娇鐢�
+ * 鐗规畩锛氬吋瀹规棫鐨勫崌绾ф牸寮忥紝蹇呴』鏄痶ar.xz鏍煎紡锛屼笖鍙敤鏉ュ崌绾ц祫婧愭枃浠�
+ * 鍗囩骇鍒嗕簩澶ф楠わ紝绗竴姝ユ槸鍦ㄥ簲鐢ㄧ涓嬭浇鍗囩骇鍖咃紙zip锛夛紝瑙e帇鍗囩骇鍖�
+ * 绗簩姝ュ寘鎷噸鍚澶囷紝鍒╃敤鑴氭湰澶嶅埗鐩綍鍜屾枃浠舵垨棰濆涓�浜涙搷浣�
+ * 濡傛灉鍦ㄥ崌绾у寘鏍圭洰褰曚笅鏀句竴涓猚ustom_update.sh,灏变細鍏堟墽琛岃繖涓猻hell鏂囦欢锛屾垜浠彲浠ュ湪杩欎釜鏂囦欢閲屾斁涓�浜涜嚜瀹氫箟鐨勫崌绾у姩浣�
+ * @param {string} url 蹇呭~锛屼笅杞藉崌绾у寘鐨刪ttp url鍦板潃
+ * @param {string} md5 蹇呭~锛屽崌绾у寘鐨刴d5鏍囪瘑锛屼笅杞藉畬閫氳繃md5鏉ュ垽鏂槸鍚﹀畬鏁淬��32闀垮害鐨勫叏灏忓啓16杩涘埗瀛楃涓�
+ * @param {number} size 闈炲繀濉紝鍗囩骇鍖呯殑澶ф澶у皬锛屽崟浣嶆槸k锛屽鏋滄枃浠跺お澶ц�屽墿浣欑鐩樹笉澶燂紝浼氭彁鍓嶆姤閿欒锛屼笉浼氬紑濮嬪惎鍔ㄤ笅杞�
+ * @param {string} shell 闈炲繀濉紝閲嶅惎璁惧鍚庣殑鍗囩骇鑴氭湰鍐呭锛岃В鍘嬪悗鐨勬枃浠跺す缂虹渷鏄� /ota/temp,鍗囩骇浼氱己鐪佹妸/ota/temp涓嬫墍鏈夋枃浠舵嫹璐濆鍒跺埌/app/code/涓�
+ * @param {number} timeout 闈炲繀濉紝灏濊瘯閾炬帴涓嬭浇鍦板潃鐨勮秴鏃舵椂闂达紙涓嶆槸涓嬭浇瀹屾垚鐨勬椂闂达級锛岀己鐪佹槸3绉�
+ */
+ota.updateResource = function (url, md5, size, shell, timeout = 3) {
+ if (!url || !md5) {
+ throw new Error("The 'url' and 'md5' param should not be null")
+ }
+ if (size && (typeof size != 'number')) {
+ throw new Error("The 'size' param should be a number")
+ }
+ //1. 鏌ョ湅纾佺洏杩樺墿浣欑殑澶у皬
+ let df = parseInt(com.systemWithRes(ota.DF_CMD, 1000))
+ if (size) {
+ if (df < (3 * size)) {//澶ф鏈湴蹇呴』鏈夊畨瑁呭寘3鍊嶅ぇ灏忕殑绌洪棿
+ throw new Error('The upgrade package is too large, and not be enough space on the disk to download it')
+ }
+ }
+ //2. 涓嬭浇鏂囦欢鍒扮壒瀹氱洰褰�
+ const firmware = ota.OTA_ROOT + '/download.tar.xz'
+ const temp = ota.OTA_ROOT + '/temp'
+ com.systemBrief(`rm -rf ${ota.OTA_ROOT} && mkdir ${ota.OTA_ROOT} `) //鍏堝垹闄ta鏍圭洰褰�
+ let download = `wget --no-check-certificate --timeout=${timeout} -c "${url}" -O ${firmware} 2>&1`
+ com.systemBrief(download, 1000)
+ let fileExist = (os.stat(firmware)[1] === 0)
+ if (!fileExist) {
+ http.download(url, firmware, null, timeout*1000)
+ }
+ fileExist = (os.stat(firmware)[1] === 0)
+ if (!fileExist) {
+ throw new Error('Download failed, please check the url:' + url)
+ }
+
+ //3. 璁$畻骞舵瘮杈僲d5鏄惁涓�鏍�
+ let md5Hash = com.md5HashFile(firmware)
+ md5Hash = md5Hash.map(v => v.toString(16).padStart(2, 0)).join('')
+ if (md5Hash != md5) {
+ throw new Error('Download failed with wrong md5 value')
+ }
+ //4. 瑙e帇
+ //tar -xJvf test.tar.xz -C /path/
+ com.systemBrief(`mkdir ${temp} && tar -xJvf ${firmware} -C ${temp}`)
+ //5. 鏋勫缓鑴氭湰鏂囦欢
+ if (!shell) {
+ shell = `
+ source=${temp}/vgapp/res/image/bk.png
+ target=/app/code/resource/image/bg.png
+ if test -e "\\$source"; then
+ cp "\\$source" "\\$target"
+ fi
+ source=${temp}/vgapp/res/image/bk_90.png
+ target=/app/code/resource/image/bg_90.png
+ if test -e "\\$source"; then
+ cp "\\$source" "\\$target"
+ fi
+ source=${temp}/vgapp/res/font/AlibabaPuHuiTi-2-65-Medium.ttf
+ target=/app/code/resource/font.ttf
+ if test -e "\\$source"; then
+ cp "\\$source" "\\$target"
+ fi
+ source=${temp}/vgapp/wav/*.wav
+ target=/app/code/resource/wav/
+ cp "\\$source" "\\$target"
+ rm -rf ${ota.OTA_ROOT}
+ `
+ }
+
+ com.systemBrief(`echo "${shell}" > ${ota.OTA_RUN} && chmod +x ${ota.OTA_RUN}`)
+ fileExist = (os.stat(ota.OTA_RUN)[1] === 0)
+ if (!fileExist) {
+ throw new Error('Build shell file failed')
+ }
+ com.systemWithRes(`${ota.OTA_RUN}`)
+}
+/**
+ * 鐢辫皟鐢ㄨ�呮潵鍚姩閲嶅惎锛屼竴鑸槸update鍑芥暟娌℃湁閿欒锛岃繍琛屽畬鎴愬苟鍚戝寳鍚戞眹鎶ョ粨鏋滃悗鍐嶈皟鐢ㄩ噸鍚�
+ */
+ota.reboot = function () {
+ com.asyncReboot(2)
+}
+//-------------------------private-------------------
+
+export default ota
\ No newline at end of file
diff --git a/vf205_access/dxmodules/dxPwm.js b/vf205_access/dxmodules/dxPwm.js
new file mode 100644
index 0000000..25a709f
--- /dev/null
+++ b/vf205_access/dxmodules/dxPwm.js
@@ -0,0 +1,116 @@
+// build : 20240419
+// PWM浠h〃鑴夊啿瀹藉害璋冨埗锛圥ulse Width Modulation锛夎鐢ㄦ潵妯℃嫙杈撳嚭鐢靛帇鎴栧姛鐜囷紝浠ユ帶鍒惰渹楦e櫒銆佺數鏈虹殑閫熷害銆丩ED鐨勪寒搴︺�佹俯搴﹁皟鑺傚櫒鐨勬俯搴︾瓑绛�
+import { pwmClass } from './libvbar-b-dxpwm.so'
+import * as os from "os"
+const pwmObj = new pwmClass();
+
+const pwm = {}
+
+/**
+ * 鐢宠pwm閫氶亾,鐢宠涓�娆″嵆鍙�
+ * @param {number} channel 鐢宠鐨勯�氶亾鍙凤紝鏀寔0~7閫氶亾
+ * @returns true/false
+ */
+pwm.request = function (channel) {
+ return pwmObj.request(channel)
+}
+/**
+ * 璁剧疆PWM妯″紡
+ * @param {number} mode
+ 0 --> CPU mode,杩炵画娉㈠舰.
+ 1 --> DMA mode,鎸囧畾鏁伴噺鐨勬尝褰�.
+ 2 --> DMA mode,杩炵画娉㈠舰.
+ * @returns true/false
+ */
+pwm.setMode = function (mode) {
+ return pwmObj.setMode(mode)
+}
+/**
+ * 璁剧疆PWM鍛ㄦ湡 鏄寚涓�涓畬鏁寸殑PWM淇″彿鍛ㄦ湡鎵�鑺辫垂鐨勬椂闂�
+ * @param {number} periodNs 寰呰缃殑PWM鍛ㄦ湡鍊�(鍗曚綅: ns)
+ * @returns true/false
+ */
+pwm.setPeriod = function (periodNs) {
+ return pwmObj.setPeriod(periodNs)
+}
+/**
+ * 璁剧疆PWM鍗犵┖姣� 鏄寚楂樼數骞筹紙鑴夊啿锛夊湪涓�涓畬鏁寸殑鍛ㄦ湡鍐呮墍鍗犵殑鏃堕棿
+ * @param {number} dutyNs 寰呰缃殑PWM鍗犵┖姣�(璁剧疆楂樼數骞崇殑鏃堕棿, 鍗曚綅: ns)
+ * @returns true/false
+ */
+pwm.setDuty = function (dutyNs) {
+ return pwmObj.setDuty(dutyNs)
+}
+/**
+ * 璁剧疆PWM mode 2锛屾寚浠ゆ暟閲忕殑娉㈠舰妯″紡鐨勬暟閲�
+ * @param {number} dutyNs
+ * @returns true/false
+ */
+pwm.setDmaDuty = function (dutyNs) {
+ return pwmObj.setDmaDuty(dutyNs)
+}
+/**
+ * 浣胯兘鎸囧畾閫氶亾
+ * @param {number} channel 鐢宠鐨勯�氶亾鍙凤紝鏀寔0~7閫氶亾
+ * @param {boolean} on
+ * @returns true/false
+ */
+pwm.enable = function (channel, on) {
+ return pwmObj.enable(channel, on)
+}
+/**
+ * 鍏抽棴鎵�閫夐�氶亾
+ * @param {number} channel 杈撳叆鍙傛暟, 鐢宠鐨勯�氶亾鍙凤紝鏀寔0~7閫氶亾
+ * @returns true/false
+ */
+pwm.free = function (channel) {
+ return pwmObj.free(channel)
+}
+/**
+ * 璁剧疆鎸囧畾閫氶亾鐨凱WM鍛ㄦ湡
+ * @param {number} channel 鐢宠鐨勯�氶亾鍙凤紝鏀寔0~7閫氶亾
+ * @param {number} periodNs 寰呰缃殑PWM鍛ㄦ湡鍊�(鍗曚綅: ns)
+ * @returns true/false
+ */
+pwm.setPeriodByChannel = function (channel, periodNs) {
+ return pwmObj.setPeriodByChannel(channel, periodNs)
+}
+/**
+ * 璁剧疆鎸囧畾閫氶亾鐨凱WM鍗犵┖姣�
+ * @param {number} channel 鐢宠鐨勯�氶亾鍙凤紝鏀寔0~7閫氶亾
+ * @param {number} dutyNs 寰呰缃殑PWM鍗犵┖姣�(璁剧疆楂樼數骞崇殑鏃堕棿, 鍗曚綅: ns)
+ * @returns true/false
+ */
+pwm.setDutyByChannel = function (channel, dutyNs) {
+ return pwmObj.setDutyByChannel(channel, dutyNs);
+}
+/**
+* 铚傞福,闇�瑕佸厛request锛宻etPeriodByChannel鍜宔nable涔嬪悗鎵嶅彲浠ヤ娇鐢�
+* @param {object} options 铚傞福鐨勫弬鏁�
+* @param {number} options.channel 鐢宠鐨勯�氶亾鍙凤紝鏀寔0~7閫氶亾锛屽繀濉�
+* @param {number} options.period 寰呰缃殑PWM鍛ㄦ湡鍊�(鍗曚綅: ns) 缂虹渷鏄�366166
+* @param {number} options.count 铚傞福鐨勬鏁帮紝缂虹渷鏄�1娆�
+* @param {number} options.time 铚傞福鐨勬椂闂达紝缂虹渷鏄�50姣锛屽鏋滄兂闀块福锛屼竴鑸槸500姣
+* @param {number} options.interval 2娆¤渹楦d箣闂寸殑闂撮殧锛岀己鐪佹槸50姣
+* @param {number} options.volume 铚傞福鐨勯煶閲忥紝缂虹渷鏄�50
+*/
+pwm.beep = function (options) {
+ const {
+ count = 1,
+ time = 50,
+ interval = 50,
+ volume = 50,
+ period = 366166,
+ } = options;
+ for (let i = 0; i < count; i++) {
+ pwm.setDutyByChannel(options.channel, period * volume / 255)
+ os.sleep(time)
+ pwm.setDutyByChannel(options.channel, 0)
+ if (i < (count - 1)) {
+ // 鏈�鍚庝竴娆¤渹楦f棤闂撮殧
+ os.sleep(interval)
+ }
+ }
+}
+
+export default pwm;
diff --git a/vf205_access/dxmodules/dxQrRule.js b/vf205_access/dxmodules/dxQrRule.js
new file mode 100644
index 0000000..36bc9a8
--- /dev/null
+++ b/vf205_access/dxmodules/dxQrRule.js
@@ -0,0 +1,215 @@
+//build: 20240301
+//寰厜浜岀淮鐮佺爜鍒惰鍒欙紝鍖呮嫭101锛�103 绛�
+//渚濊禆缁勪欢: dxDriver,dxCommon,dxLogger
+import common from './dxCommon.js'
+import base64 from './dxBase64.js'
+import logger from './dxLogger.js'
+let sqliteObj
+
+// 姣旇緝涓や釜瀛楃涓茬殑鍓峃涓瓧绗︽槸鍚︾浉绛�
+function comparePrefix(str1, str2, N) {
+ let substring1 = str1.substring(0, N);
+ let substring2 = str2.substring(0, N);
+ return substring1 === substring2;
+}
+
+
+
+// 101鐮佸�艰В鐮�
+function decode101(str) {
+ if (str.length < 5) {
+ logger.info("鏃犳晥浜岀淮鐮�")
+ throw new Error("code invalid,length too short")
+ }
+ let decodeBuf = base64.decode(str.slice(0, -4))
+ decodeBuf=decodeBuf.substring(4)
+
+ return decodeBuf
+}
+function hexStringToArrayBuffer (hexString) {
+ var byteString = hexString.match(/.{1,2}/g);
+ var byteArray = byteString.map(function (byte) {
+ return parseInt(byte, 16);
+ });
+ var buffer = new Uint8Array(byteArray).buffer;
+ return buffer;
+}
+
+/**
+ * 103鐮佸�艰В鐮�
+ * 1銆乥ase64瑙g爜
+ * 2銆佽В鏋愮粍缁囩紪鍙�
+ * 3銆丷SA瑙e瘑
+ * 4銆佽В鏋愯韩浠界被鍨�
+ * 5銆佽В鏋愭潈闄愭爣璇�
+ * 6銆佽В鏋愮敓鐮佹椂闂�
+ * 7銆佽В鏋愮爜杩囨湡鏃堕棿
+ * 8銆佹牎楠岄�氳鐮佹槸鍚﹁繃鏈�
+ * @param {*} str
+ * @returns
+ */
+function decode103(str) {
+ // FIXME 杩欎釜pubKey鍚庢湡闇�瑕佷粠閰嶇疆涓煡璇�
+ let TLV_T_SIZE = 2, TLV_L_SIZE = 2, offset = 0, code, decryptedData, generationCodeTime, expirationTime
+
+ // 1銆乥ase64瑙g爜
+ let decodeBuf = base64.toHexString(str)
+ decodeBuf= hexStringToArrayBuffer(decodeBuf)
+ let view = new Uint8Array(decodeBuf)
+ let organizationNumber;
+ // 2銆佽В鏋愮粍缁囩紪鍙�
+ if (view[offset] == 0x01) {
+ offset += TLV_T_SIZE
+ let orgNumLen = view[offset]
+ offset += TLV_L_SIZE
+ let orgNumBuf = new Uint8Array(decodeBuf, offset, orgNumLen);
+ organizationNumber = String.fromCharCode.apply(null, new Uint8Array(orgNumBuf));
+ logger.info("缁勭粐缂栧彿: " + organizationNumber)
+ offset += orgNumLen
+ } else {
+ throw new Error("code invalid,organization number error")
+ }
+
+ // 3銆丷SA瑙e瘑
+ if (view[offset] == 0x02) {
+ // 缁勭粐缂栧彿鏁版嵁闀垮害
+ offset += TLV_T_SIZE
+ let cipherTextLen = view[offset]
+ offset += TLV_L_SIZE
+ // 瀵瑰瘑鏂囪繘琛孯SA瑙e瘑
+ let encryptedData = decodeBuf.slice(offset, offset + cipherTextLen)
+
+
+ // TODO 绉橀挜鍐欐锛屽悗缁渶瑕佹毚闇插嚭鏉�
+ // RSA 鏌ヨ瀵嗛挜(涔熷彲浠ュ浐瀹氾紝涔熷彲浠ュ啓鍦ㄦ枃鏈腑)锛屾牴鎹瘑閽ュ啀娆¤В瀵�
+ // RSA瑙e瘑鍚庣殑鏁版嵁
+ let arr = sqliteObj.securityFindAllByCodeAndTypeAndTimeAndkey(undefined, undefined, undefined, Math.floor(Date.parse(new Date()) / 1000), organizationNumber)
+ if (arr && arr.length > 0) {
+ for (let data of arr) {
+ decryptedData = common.arrayBufferRsaDecrypt(encryptedData, data.value)
+ if (decryptedData != null) {
+ break
+ }
+ }
+ }
+ if (!arr && arr.length <= 0 || decryptedData == null) {
+ return str
+ }
+ }
+ // 涓�涓澶囦竴涓瘑閽ワ紝鐩稿綋浜庤澶囧唴鐢ㄤ簬瑙e瘑鐨勫叕閽ユ槸鍥哄畾鐨勶紝鍙互鎶婂叕閽ユ斁鍒伴厤缃腑锛岃繖閲屽厛榛樿鍐欐
+ // "MTlBODExMDA2MTkwMzQ4Q0I5QUY3QTc4QzAzOTQzNUU5NzNFODAzMEU4QUU1QzBEMkZFOEYwRjEzRjU4M0M5MTU5QUU5MTdDMDIzRDU0RDgxRUY2NTI0NkUyQ0Y2MUMzMTQzNTNENjA2NDU5N0Y2OTY5RUE4QjA5MUY1RTYyODM=";
+ // let buf = common.arrayBufferRsaDecrypt(deData, deData.length)
+ // 0 3 0 3 0 31 30 33 4 0 a 0 31 30 35 34 33 32 33 33 32 33 5 0 4 0 af 8c fa 5a 6 0 1 0 35 7 0 0 0
+ // 0
+ // 3 0 3 0 31 30 33
+ // 4 0 a 0 31 30 35 34 33 32 33 33 32 33
+ // 5 0 4 0 af 8c fa 5a
+ // 6 0 1 0 35
+ // 7 0 0 0
+
+ offset = 1;
+ view = new Uint8Array(decryptedData)
+ // 4銆佽В鏋愯韩浠界被鍨�(type:103)
+ if (view[offset] == 0x03) {
+ // 韬唤绫诲瀷鏁版嵁闀垮害
+ offset += TLV_T_SIZE
+ let identityTypeLength = view[offset]
+ // 韬唤绫诲瀷鏁版嵁
+ offset += TLV_L_SIZE
+ let identityTypeBuf = new Uint8Array(decryptedData, offset, identityTypeLength);
+ let identityType = String.fromCharCode.apply(null, identityTypeBuf);
+ offset += identityTypeLength
+ logger.info("韬唤绫诲瀷鏁版嵁: " + identityType)
+ }
+
+
+ // 5銆佽В鏋愭潈闄愭爣璇�(code)
+ if (view[offset] == 0x04) {
+ // 鏉冮檺鏍囪瘑鏁版嵁闀垮害
+ offset += TLV_T_SIZE
+ let identityCodeLength = view[offset]
+ // 鏉冮檺鏍囪瘑鏁版嵁
+ offset += TLV_L_SIZE
+ let identityCodeBuf = new Uint8Array(decryptedData, offset, identityCodeLength);
+ offset += identityCodeLength
+ code = String.fromCharCode.apply(null, identityCodeBuf);
+ }
+
+
+ // 6銆佽В鏋愮敓鐮佹椂闂�
+ if (view[offset] == 0x05) {
+ // 鐢熺爜鏃堕棿鏁版嵁闀垮害
+ offset += TLV_T_SIZE
+ let createTimeLength = view[offset]
+ // 鐢熺爜鏃堕棿鏁版嵁
+ offset += TLV_L_SIZE
+ let createTimeBuf = new Uint8Array(decryptedData, offset, createTimeLength);
+ offset += createTimeLength
+ generationCodeTime = parseInt(common.arrayBufferToHexString(createTimeBuf.reverse()), 16)
+ }
+
+
+ // 7銆佽В鏋愮爜杩囨湡鏃堕棿
+ if (view[offset] == 0x06) {
+ // 鐮佽繃鏈熸椂闂存暟鎹暱搴�
+ offset += TLV_T_SIZE
+ let expireTimeLength = view[offset]
+ // 鐮佽繃鏈熸椂闂存暟鎹�
+ offset += TLV_L_SIZE
+ let expireTimeBuf = new Uint8Array(decryptedData, offset, expireTimeLength);
+ offset += expireTimeLength
+ expirationTime = parseInt(String.fromCharCode.apply(null, expireTimeBuf))
+ }
+
+ // 8銆佹牎楠岄�氳鐮佹槸鍚﹁繃鏈�
+ let timestamp = Date.now();
+ expirationTime = generationCodeTime + expirationTime
+ if (expirationTime * 1000 > timestamp) {
+ return code
+ } else {
+ return null
+ }
+
+}
+
+const code = {
+ formatCode: function (msg, sqlObj) {
+ if (!msg) {
+ throw new Error("msg should not be null or empty")
+ }
+ if (!sqlObj) {
+ throw new Error("sqlObj should not be null or empty")
+ }
+ if (!sqliteObj) {
+ sqliteObj = sqlObj
+ }
+
+ let data = {}
+ // 鍒ゆ柇鐮佸��
+ if (comparePrefix(msg, "&llgy", "&llgy".length) || comparePrefix(msg, "&v101", "&v101".length)) {
+ // 101鐮佸��
+ data.type = 101
+ data.code = decode101(msg.substring(5))
+ }
+ else if (comparePrefix(msg, "vg://v103", "vg://v103".length)) {
+ // 103鐮佸��
+ data.type = 103
+ data.code = decode103(msg.substring(9)) ? decode103(msg.substring(9)) : msg.substring(9)
+ } else if (comparePrefix(msg, "___VBAR_CONFIG_V1.1.0___", "___VBAR_CONFIG_V1.1.0___".length) || comparePrefix(msg, "___VBAR_KZB_V1.1.0___", "___VBAR_KZB_V1.1.0___".length)) {
+ //TODO 鍏堣繖鏍峰啓锛岃璁哄ソ鍚庢洿鏀规祦杞�昏緫
+ data.type = 'config'
+ data.code = msg
+ } else {
+ data.type = 100
+ data.code = msg
+ }
+ if (data.code) {
+ return data
+ } else {
+ console.log("decode fail")
+ return
+ }
+ }
+}
+
+export default code;
\ No newline at end of file
diff --git a/vf205_access/dxmodules/dxSqlite.js b/vf205_access/dxmodules/dxSqlite.js
new file mode 100644
index 0000000..b4c44ab
--- /dev/null
+++ b/vf205_access/dxmodules/dxSqlite.js
@@ -0,0 +1,54 @@
+//build: 20240525
+//渚濊禆缁勪欢:dxCommon
+import { sqliteClass } from './libvbar-m-dxsqlite.so'
+import dxCommon from './dxCommon.js'
+const sqliteObj = new sqliteClass();
+const sqlite = {}
+
+/**
+ * 鍒濆鍖栨暟鎹簱
+ * @param {string} path db鏂囦欢鍏ㄨ矾寰勶紝蹇呭~
+ * @param {string} id 鍙ユ焺id锛岄潪蹇呭~锛堣嫢鍒濆鍖栧涓疄渚嬮渶瑕佷紶鍏ュ敮涓�id锛�
+ */
+sqlite.init = function (path, id) {
+ if (path == undefined || path.length == 0) {
+ throw new Error("dxsqliteObj.initDb:path should not be null or empty")
+ }
+ let pointer = sqliteObj.open(path);
+ dxCommon.handleId("sqlite", id, pointer)
+}
+
+/**
+ * 鎵ц璇彞
+ * @param {string} sql 鑴氭湰璇彞锛屽繀濉�
+ * @param {string} id 鍙ユ焺id锛岄潪蹇呭~锛堥渶淇濇寔鍜宨nit涓殑id涓�鑷达級
+ * @returns 0:鎴愬姛锛岄潪0澶辫触
+ */
+sqlite.exec = function (sql, id) {
+ let pointer = dxCommon.handleId("sqlite", id)
+ return sqliteObj.sql_exec(pointer, sql)
+}
+
+
+/**
+ * 鎵ц鏌ヨ璇彞
+ * @param {string} sql 鑴氭湰璇彞锛屽繀濉�
+ * @param {string} id 鍙ユ焺id锛岄潪蹇呭~锛堥渶淇濇寔鍜宨nit涓殑id涓�鑷达級
+ * @returns 鏌ヨ缁撴灉锛屽舰濡傦細[{"id":"1","type":200,"code":"aad7485a","door":"澶ч棬","extra":"","tiemType":0,"beginTime":1716613766,"endTime":1716613766,"repeatBeginTime":1716613766,"repeatEndTime":1716613766,"period":"extra"}]
+ */
+sqlite.select = function (sql, id) {
+ let pointer = dxCommon.handleId("sqlite", id)
+ return sqliteObj.select(pointer, sql);
+}
+
+/**
+ * 鍏抽棴鏁版嵁搴撹繛鎺�
+ * @param {string} id 鍙ユ焺id锛岄潪蹇呭~锛堥渶淇濇寔鍜宨nit涓殑id涓�鑷达級
+ * @returns 0:鎴愬姛锛岄潪0澶辫触
+ */
+sqlite.close = function (id) {
+ let pointer = dxCommon.handleId("sqlite", id)
+ return sqliteObj.close(pointer)
+}
+
+export default sqlite;
\ No newline at end of file
diff --git a/vf205_access/dxmodules/dxStd.js b/vf205_access/dxmodules/dxStd.js
new file mode 100644
index 0000000..5b3504f
--- /dev/null
+++ b/vf205_access/dxmodules/dxStd.js
@@ -0,0 +1,399 @@
+//build 20240222
+//quickjs 鏍囧噯搴擄紝鎻愪緵鍜屾搷浣滅郴缁熺浉鍏冲嚱鏁帮紝鎻愪緵鏍囧噯IO鐩稿叧鍑芥暟
+import * as os from "os"
+import * as std from "std"
+import common from "./dxCommon.js"
+
+const dxstd = {}
+/**
+ * 閫�鍑哄簲鐢�
+ * @param {number} n 閫�鍑虹爜
+ */
+dxstd.exit = function (n) {
+ return std.exit(n);
+}
+/**
+ * 鍚姩璁℃椂鍣紝寤舵椂寮傛鎵ц鍑芥暟
+ * @param {function} func 闇�瑕佹墽琛岀殑鍑芥暟
+ * @param {number} delay 寤惰繜鐨勬椂闂达紙姣锛�
+ * @returns timer寮曠敤
+ */
+dxstd.setTimeout = function (func, delay) {
+ return os.setTimeout(func, delay)
+}
+/**
+ * 娓呴櫎鎸囧畾鐨勮鏃跺櫒
+ * @param {*} handle timer寮曠敤
+ */
+dxstd.clearTimeout = function (handle) {
+ os.clearTimeout(handle)
+}
+// 璁板綍瀹氭椂鍣╥d锛岀敤浜巆lear锛屽彧鑳藉湪鍚屼竴绾跨▼涓璫lear
+let allTimerIdsMap = {}
+
+/**
+ * interval瀹氭椂鍣�
+ * @param {function} callback 鍥炶皟鍑芥暟锛屽繀濉�
+ * @param {number} interval 闂撮殧鏃堕棿锛屽繀濉�
+ * @param {boolean} once 鍒涘缓鍚庣珛鍗虫墽琛屼竴娆★紝闈炲繀濉�
+ * @param {number} timerId 瀹氭椂鍣╥d锛岄潪蹇呭~
+ */
+dxstd.setInterval = function (callback, interval, once, timerId) {
+ if (timerId === null || timerId === undefined) {
+ timerId = new Date().getTime() + "_" + this.genRandomStr(5)
+ allTimerIdsMap[timerId] = "ready"
+ }
+ if (once === true) {
+ // 鍒涘缓鍚庣珛鍗虫墽琛屼竴娆�
+ os.setTimeout(() => {
+ if (allTimerIdsMap[timerId]) {
+ callback()
+ }
+ }, 0);
+ }
+ if (!allTimerIdsMap[timerId]) {
+ return
+ }
+ allTimerIdsMap[timerId] = os.setTimeout(() => {
+ if (allTimerIdsMap[timerId]) {
+ callback()
+ this.setInterval(callback, interval, false, timerId)
+ }
+ }, interval);
+ return timerId
+}
+
+/**
+ * 娓呴櫎interval瀹氭椂鍣�
+ * @param {number} timerId 瀹氭椂鍣╥d锛屽繀濉�
+ */
+dxstd.clearInterval = function (timerId) {
+ const timer = allTimerIdsMap[timerId];
+ if (timer) {
+ os.clearTimeout(timer);
+ delete allTimerIdsMap[timerId];
+ }
+}
+/**
+ * 鍒犻櫎褰撳墠绾跨▼鎵�鏈塱nterval瀹氭椂鍣紝娉ㄦ剰锛氬彧鏄垹闄ゅ綋鍓嶇嚎绋嬪垱寤虹殑瀹氭椂鍣紝鑻ユ湁澶氫釜绾跨▼锛屾瘡涓嚎绋嬮兘闇�瑕佽皟鐢ㄥ垹闄�
+ */
+dxstd.clearIntervalAll = function () {
+ for (let timerId in allTimerIdsMap) {
+ if (allTimerIdsMap.hasOwnProperty(timerId)) {
+ os.clearTimeout(allTimerIdsMap[timerId]);
+ delete allTimerIdsMap[timerId];
+ }
+ }
+}
+/**
+ * 鐢熸垚鎸囧畾闀垮害鐨勫瓧姣嶅拰鏁板瓧缁勫悎鐨勯殢鏈哄瓧绗︿覆
+ * @param {number} length 瀛楃涓查暱搴︼紝闈炲繀濉紝缂虹渷鏄�6
+ * @returns
+ */
+dxstd.genRandomStr = function (length = 6) {
+ const charset = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
+ let result = ''
+ for (let i = 0; i < length; i++) {
+ const randomIndex = Math.floor(Math.random() * charset.length)
+ result += charset.charAt(randomIndex)
+ }
+ return result
+}
+/**
+ * 鎶婁竴娈靛瓧绗︿覆浣滀负 javascript 鑴氭湰鎵ц
+ * @param {string} str js鑴氭湰瀛楃涓�
+ * @param {boolean} async 榛樿涓篺alse锛屽鏋滀负 true锛岃剼鏈腑灏嗘帴鍙� await 骞惰繑鍥炰竴涓� Promise
+ */
+dxstd.eval = function (str, async) {
+ return std.evalScript(str, { async: async });
+}
+/**
+ * 鍔犺浇涓�涓枃浠跺唴瀹逛綔涓� javascript 鑴氭湰鎵ц
+ * @param {string} filename js鑴氭湰鍐呭鐨勬枃浠跺悕(缁濆璺緞)
+ */
+dxstd.loadScript = function (filename) {
+ return std.loadScript(filename);
+}
+/**
+ * 鍔犺浇鏂囦欢锛岃鍙栨枃浠堕噷鐨勫唴瀹癸紙浣跨敤utf锛�
+ * @param {string} filename 鏂囦欢鍚�
+ */
+dxstd.loadFile = function (filename) {
+ return std.loadFile(filename)
+}
+/**
+ * 淇濆瓨瀛楃涓插埌鏂囦欢
+ * @param {string} filename
+ * @param {string} content
+ */
+dxstd.saveFile = function (filename, content) {
+ if (!content || (typeof content) != 'string') {
+ throw new Error("The 'content' value should be string and not empty")
+ }
+ if (!filename) {
+ throw new Error("The 'filename' should not be empty")
+ }
+ if (!this.exist(filename)) {
+ this.ensurePathExists(filename)
+ let fd = os.open(filename, os.O_RDWR | os.O_CREAT | os.O_TRUNC);
+ if (fd < 0) {
+ throw new Error("Create file failed:" + filename)
+ }
+ os.close(fd)
+ }
+ let fd = std.open(filename, "w");
+ fd.puts(content)
+ fd.flush();
+ fd.close();
+ common.systemBrief('sync')
+ return true
+}
+/**
+ * 纭繚鏂囦欢瀵瑰簲鐨勭洰褰曢兘瀛樺湪锛屼笉瀛樺湪灏变細鍒涘缓
+ * @param {string} filename
+ */
+dxstd.ensurePathExists = function (filename) {
+ const pathSegments = filename.split('/');
+ let currentPath = '';
+ for (let i = 0; i < pathSegments.length - 1; i++) {
+ currentPath += pathSegments[i] + '/';
+ if (!this.exist(currentPath)) {
+ this.mkdir(currentPath);
+ }
+ }
+}
+/**
+ * 鍒ゆ柇鏂囦欢鏄惁瀛樺湪
+ * @param {string} filename 鏂囦欢鍚�
+ * @returns true/false
+ */
+dxstd.exist = function (filename) {
+ return (os.stat(filename)[1] === 0)
+}
+/**
+ * 杩斿洖涓�涓寘鍚幆澧冨彉閲忕殑閿�煎鐨勫璞°��
+ */
+dxstd.getenviron = function () {
+ return std.getenviron();
+}
+/**
+ * 杩斿洖鐜鍙橀噺鍚嶇О鐨勫�硷紝濡傛灉鏈畾涔夊垯杩斿洖undefined
+ * @param {string} name 鍙橀噺鍚�
+ */
+dxstd.getenv = function (name) {
+ return std.getenv(name);
+}
+/**
+ * 灏嗙幆澧冨彉閲忓悕鐨勫�艰缃负瀛楃涓插��
+ * @param {string} name 鍙橀噺鍚�
+ * @param {string} value 鍙橀噺鍊�
+ */
+dxstd.setenv = function (name, value) {
+ return std.setenv(name, value);
+}
+/**
+ * 鍒犻櫎鐜鍙橀噺
+ * @param {string} name 鍙橀噺鍚�
+ */
+dxstd.unsetenv = function (name) {
+ return std.unsetenv(name);
+}
+/**
+ * 浣跨敤JSON.parse鐨勮秴闆嗘潵瑙f瀽瀛楃涓层�傚彲浠ヨВ鏋愰潪鏍囧噯鐨� JSON 瀛楃涓层�傛帴鍙椾互涓嬫墿灞曪細
+ * - 鍗曡鍜屽琛屾敞閲�
+ * - 鏈姞寮曞彿鐨勫睘鎬э紙浠匒SCII瀛楃鐨凧avaScript鏍囪瘑绗︼級
+ * - 鏁扮粍鍜屽璞℃渶鍚庡彲浠ュ姞閫楀彿
+ * - 鍗曞紩鍙峰瓧绗︿覆
+ * - \f 鍜� \v 琚帴鍙椾负绌烘牸瀛楃
+ * - 鏁板瓧涓殑鍓嶉潰鍙互鏈夊姞鍙�
+ * - 鍏繘鍒讹紙0o鍓嶇紑锛夊拰鍗佸叚杩涘埗锛�0x鍓嶇紑锛夋暟瀛�
+ * @param {string} str json瀛楃涓�
+ */
+dxstd.parseExtJSON = function (str) {
+ return std.parseExtJSON(str);
+}
+/**
+ * 浼戠湢delay_ms姣
+ */
+dxstd.sleep = function (delay_ms) {
+ return os.sleep(delay_ms);
+}
+/**
+ * 杩斿洖琛ㄧず骞冲彴鐨勫瓧绗︿覆锛�"linux"銆�"darwin"銆�"win32" 鎴� "js"銆�
+ */
+dxstd.platform = function () {
+ return os.platform;
+}
+/**
+ * 鍒涘缓涓�涓柊绾跨▼锛坵orker锛夌殑鏋勯�犲嚱鏁帮紝鍏禔PI鎺ヨ繎浜嶹ebWorkers銆�
+ * 瀵逛簬鍔ㄦ�佸鍏ョ殑妯″潡锛屽畠鐩稿浜庡綋鍓嶈剼鏈垨妯″潡璺緞銆傜嚎绋嬮�氬父涓嶅叡浜换浣曟暟鎹紝鍙互閫氳繃dxMap,dxQueue,dxWpc鏉ュ叡浜拰浼犻�掓暟鎹�備笉鏀寔宓屽鐨� worker銆�
+ * @param {string} module_filename 鎸囧畾鍦ㄦ柊鍒涘缓鐨勭嚎绋嬩腑鎵ц鐨勬ā鍧楁枃浠跺悕
+ */
+dxstd.Worker = function (module_filename) {
+ return new os.Worker(module_filename)
+}
+
+dxstd.O_RDONLY = os.O_RDONLY
+dxstd.O_WRONLY = os.O_WRONLY
+dxstd.O_RDWR = os.O_RDWR
+dxstd.O_APPEND = os.O_APPEND
+dxstd.O_CREAT = os.O_CREAT
+dxstd.O_EXCL = os.O_EXCL
+dxstd.O_TRUNC = os.O_TRUNC
+/**
+ * 鎵撳紑涓�涓枃浠躲�傝繑鍥炰竴涓彞鏌勶紝濡傛灉鍑虹幇閿欒鍒欒繑鍥� < 0銆�
+ * @param {string} filename 鏂囦欢缁濆璺緞
+ * @param {number} flags O_RDONLY,O_WRONLY,O_RDWR,O_APPEND,O_CREAT,O_EXCL,O_TRUNC
+ * 1. O_RDONLY 锛氫互鍙鏂瑰紡鎵撳紑鏂囦欢
+ * 2. O_WRONLY 锛氫互鍙啓鏂瑰紡鎵撳紑鏂囦欢
+ * 3. O_RDWR 锛氫互鍙鍙啓鏂瑰紡鎵撳紑鏂囦欢
+ * 浠ヤ笂涓変釜鏄枃浠惰闂潈闄愭爣蹇楋紝浼犲叆鐨刦lags 鍙傛暟涓繀椤昏鍖呭惈鍏朵腑涓�绉嶆爣蹇楋紝鑰屼笖鍙兘鍖呭惈涓�绉嶏紝鎵撳紑鐨勬枃浠跺彧鑳芥寜鐓ц繖绉嶆潈闄愭潵鎿嶄綔锛�
+ 璀浣跨敤浜� O_RDONLY 鏍囧織锛屽氨鍙兘瀵规枃浠惰繘琛岃鍙栨搷浣滐紝涓嶈兘鍐欐搷浣溿��
+
+ * 4. O_APPEND 锛氳皟鐢� open 鍑芥暟鎵撳紑鏂囦欢锛屽綋姣忔浣跨敤 write()鍑芥暟瀵规枃浠惰繘琛屽啓鎿嶄綔鏃讹紝閮戒細鑷姩鎶婃枃浠跺綋鍓嶄綅缃亸绉婚噺绉诲姩鍒版枃浠舵湯灏撅紝
+ 浠庢枃浠舵湯灏惧紑濮嬪啓鍏ユ暟鎹紝涔熷氨鏄剰鍛崇潃姣忔鍐欏叆鏁版嵁閮芥槸浠庢枃浠舵湯灏惧紑濮嬨��
+ O_APPEND鏍囧織骞朵笉浼氬奖鍝嶈鏂囦欢锛屽綋璇诲彇鏂囦欢鏃讹紝 O_APPEND 鏍囧織骞朵笉浼氬奖鍝嶈浣嶇疆鍋忕Щ閲忥紝
+ 鍗充娇浣跨敤浜� O_APPEND鏍囧織锛岃鏂囦欢浣嶇疆鍋忕Щ閲忛粯璁ゆ儏鍐典笅渚濈劧鏄枃浠跺ご锛�
+ 浣跨敤 lseek 鍑芥暟鏉ユ敼鍙� write()鏃剁殑鍐欎綅缃亸绉婚噺涔熶笉浼氭垚鍔燂紝
+ 褰撴墽琛� write()鍑芥暟鏃讹紝妫�娴嬪埌 open 鍑芥暟鎼哄甫浜� O_APPEND 鏍囧織锛屾墍浠ュ湪 write 鍑芥暟鍐呴儴浼氳嚜鍔ㄥ皢鍐欎綅缃亸绉婚噺绉诲姩鍒版枃浠舵湯灏�
+
+ * 5. O_CREAT锛氬鏋� filename 鍙傛暟鎸囧悜鐨勬枃浠朵笉瀛樺湪鍒欏垱寤烘鏂囦欢
+ * 6. O_EXCL :姝ゆ爣蹇椾竴鑸粨鍚� O_CREAT 鏍囧織涓�璧蜂娇鐢紝鐢ㄤ簬涓撻棬鍒涘缓鏂囦欢銆�
+ 鍦� flags 鍙傛暟鍚屾椂浣跨敤鍒颁簡 O_CREAT 鍜孫_EXCL 鏍囧織鐨勬儏鍐典笅锛屽鏋� filename 鍙傛暟鎸囧悜鐨勬枃浠跺凡缁忓瓨鍦紝
+ 鍒� open 鍑芥暟杩斿洖閿欒銆傚彲浠ョ敤浜庢祴璇曚竴涓枃浠舵槸鍚﹀瓨鍦紝濡傛灉涓嶅瓨鍦ㄥ垯鍒涘缓姝ゆ枃浠讹紝濡傛灉瀛樺湪鍒欒繑鍥為敊璇紝杩欎娇寰楁祴璇曞拰鍒涘缓涓よ�呮垚涓轰竴涓師瀛愭搷浣溿��
+ * 7. O_TRUNC 锛氳皟鐢� open 鍑芥暟鎵撳紑鏂囦欢鐨勬椂鍊欎細灏嗘枃浠跺師鏈殑鍐呭鍏ㄩ儴涓㈠純锛屾枃浠跺ぇ灏忓彉涓� 0锛�
+ */
+dxstd.open = function (filename, flags) {
+ return os.open(filename, flags);
+}
+/**
+ * 鍒ゆ柇缁欏畾璺緞鏄惁鏄竴涓枃浠跺す銆�
+ * @param {string} filename - 瑕佹鏌ョ殑璺緞銆�
+ * @returns {boolean} 濡傛灉鏄枃浠跺す鍒欒繑鍥� true锛屽惁鍒欒繑鍥� false,濡傛灉涓嶅瓨鍦紝鎶涘嚭寮傚父銆�
+ */
+dxstd.isDir = function (filename) {
+ let stat = os.stat(filename)
+ if (stat[1] != 0) {
+ throw new Error("No such file:" + filename)
+ }
+ return ((stat[0].mode & this.S_IFMT) === this.S_IFDIR);
+}
+/**
+ * 鍏抽棴鏂囦欢
+ * @param {*} fd 鏂囦欢鍙ユ焺
+ */
+dxstd.close = function (fd) {
+ return os.close(fd)
+}
+dxstd.SEEK_SET = std.SEEK_SET
+dxstd.SEEK_CUR = std.SEEK_CUR
+dxstd.SEEK_END = std.SEEK_END
+/**
+ * 鍦ㄦ枃浠朵腑杩涜瀹氫綅銆備娇鐢⊿EEK_*鏉ヨ〃绀簑hence銆俹ffset鍙互鏄暟瀛楁垨bigint銆傚鏋渙ffset鏄痓igint锛屽垯杩斿洖涓�涓猙igint銆�
+ * @param {*} fd 鏂囦欢鍙ユ焺
+ * @param {number} offset 涓哄亸绉婚噺锛屾暣鏁拌〃绀烘鍚戝亸绉伙紝璐熸暟琛ㄧず璐熷悜鍋忕Щ
+ * @param {*} whence 璁惧畾浠庢枃浠剁殑鍝噷寮�濮嬪亸绉�: SEEK_SET锛� 鏂囦欢寮�澶�;SEEK_CUR锛� 褰撳墠浣嶇疆;SEEK_END锛� 鏂囦欢缁撳熬
+ */
+dxstd.seek = function (fd, offset, whence) {
+ return os.seek(fd, offset, whence)
+}
+/**
+ * 浠庢枃浠跺彞鏌刦d璇诲彇length瀛楄妭鍒颁綅浜庡瓧鑺備綅缃畂ffset鐨凙rrayBuffer缂撳啿鍖恒�傝繑鍥炶鍙栫殑瀛楄妭鏁帮紝濡傛灉鍑虹幇閿欒鍒欒繑鍥� < 0銆�
+ * @param {*} fd 鏂囦欢鍙ユ焺
+ * @param {*} buffer ArrayBuffer瀵硅薄
+ * @param {number} offset 鍋忕Щ閲�
+ * @param {number} length 璇诲彇鐨勫瓧鑺傞暱搴�
+ */
+dxstd.read = function (fd, buffer, offset, length) {
+ return os.read(fd, buffer, offset, length);
+}
+/**
+ * 浠嶢rrayBuffer缂撳啿鍖虹殑瀛楄妭浣嶇疆offset鍚戞枃浠跺彞鏌刦d鍐欏叆length瀛楄妭銆傝繑鍥炲凡鍐欏叆鐨勫瓧鑺傛暟锛屽鏋滃嚭鐜伴敊璇垯杩斿洖 < 0銆�
+ * @param {*} fd 鏂囦欢鍙ユ焺
+ * @param {*} buffer ArrayBuffer瀵硅薄
+ * @param {*} offset 鍋忕Щ閲�
+ * @param {*} length 鍐欑殑瀛楄妭闀垮害
+ */
+dxstd.write = function (fd, buffer, offset, length) {
+ return os.write(fd, buffer, offset, length);
+}
+/**
+ * 鍒犻櫎鏂囦欢锛屾垚鍔熻繑鍥�0鍚﹀垯-errno
+ * @param {string} filename 鏂囦欢缁濆璺緞
+ */
+dxstd.remove = function (filename) {
+ return os.remove(filename)
+}
+/**
+ * 淇敼鏂囦欢鍚嶇О锛屾垚鍔熻繑鍥�0鍚﹀垯-errno
+ * @param {string} oldname 鏃ф枃浠剁粷瀵硅矾寰�
+ * @param {string} newname 鏂版枃浠剁粷瀵硅矾寰�
+ */
+dxstd.rename = function (oldname, newname) {
+ return os.rename(oldname, newname)
+}
+/**
+ * 杩斿洖 [str, err]锛屽叾涓� str 鏄綋鍓嶅伐浣滅洰褰曪紝err 鏄敊璇唬鐮�
+ */
+dxstd.getcwd = function () {
+ return os.getcwd()
+}
+/**
+ * 鏀瑰彉褰撳墠宸ヤ綔鐩綍
+ * @param {string} path 鐩綍,鏀寔缁濆鍜岀浉瀵硅矾寰�
+ */
+dxstd.chdir = function (path) {
+ return os.chdir(path)
+}
+/**
+ * 鍒涘缓鐩綍,鎴愬姛杩斿洖0鍚﹀垯-errno
+ * @param {string} path 鐩綍缁濆璺緞
+ */
+dxstd.mkdir = function (path) {
+ return os.mkdir(path)
+}
+dxstd.S_IFMT = os.S_IFMT
+dxstd.S_IFIFO = os.S_IFIFO
+dxstd.S_IFCHR = os.S_IFCHR
+dxstd.S_IFDIR = os.S_IFDIR
+dxstd.S_IFBLK = os.S_IFBLK
+dxstd.S_IFREG = os.S_IFREG
+dxstd.S_IFSOCK = os.S_IFSOCK
+dxstd.S_IFLNK = os.S_IFLNK
+dxstd.S_ISGID = os.S_ISGID
+dxstd.S_ISUID = os.S_ISUID
+/**
+ * 杩斿洖 [obj, err]锛屽叾涓� obj 鏄竴涓寘鍚矾寰刾ath鐨勬枃浠剁姸鎬佷俊鎭殑瀵硅薄銆�
+ * err 鏄敊璇唬鐮併�俹bj 涓畾涔変簡浠ヤ笅瀛楁锛歞ev銆乮no銆乵ode銆乶link銆乽id銆乬id銆乺dev銆乻ize銆乥locks銆乤time銆乵time銆乧time銆�
+ * 鏃堕棿浠ヨ嚜1970骞翠互鏉ョ殑姣涓哄崟浣嶆寚瀹氥��
+ * 鍏朵腑mode鐨勫�煎搴斾互涓嬫灇涓�,渚嬪锛屾鏌ヤ竴涓枃浠舵槸鍚︽槸鐩綍鍙互浣跨敤 (mode & S_IFMT) == S_IFDIR 鐨勬柟寮�:
+ S_IFMT锛氫綅鎺╃爜锛岀敤浜庢彁鍙栨枃浠剁被鍨嬮儴鍒嗙殑浣嶃�傝繖鏄竴涓敤浜庡睆钄芥枃浠剁被鍨嬩綅鐨勫父閲忋��
+ S_IFIFO锛氳〃绀篎IFO锛堝懡鍚嶇閬擄級銆�
+ S_IFCHR锛氳〃绀哄瓧绗﹁澶囥��
+ S_IFDIR锛氳〃绀虹洰褰曘��
+ S_IFBLK锛氳〃绀哄潡璁惧銆�
+ S_IFREG锛氳〃绀哄父瑙勬枃浠躲��
+ S_IFSOCK锛氳〃绀哄鎺ュ瓧銆�
+ S_IFLNK锛氳〃绀虹鍙烽摼鎺ャ��
+ S_ISGID锛氳缃粍ID浣嶃��
+ S_ISUID锛氳缃敤鎴稩D浣嶃��
+ * @param {string} path 鏂囦欢鎴栫洰褰曠粷瀵硅矾寰�
+ */
+dxstd.stat = function (path) {
+ return os.stat(path)
+}
+/**
+ * lstat() 涓� stat() 鐩稿悓锛屽彧鏄畠杩斿洖鍏充簬閾炬帴鏈韩鐨勪俊鎭��
+ * @param {*} path 鏂囦欢鎴栫洰褰曠粷瀵硅矾寰�
+ */
+dxstd.lstat = function (path) {
+ return os.lstat(path)
+}
+/**
+ * 杩斿洖 [array, err]锛屽叾涓� array 鏄寘鍚洰褰曡矾寰勪笅鐨勬枃浠跺悕鐨勫瓧绗︿覆鏁扮粍銆俥rr 鏄敊璇唬鐮併��
+ * @param {string} path 鐩綍缁濆璺緞
+ */
+dxstd.readdir = function (path) {
+ return os.readdir(path)
+}
+export default dxstd
\ No newline at end of file
diff --git a/vf205_access/dxmodules/dxUart.js b/vf205_access/dxmodules/dxUart.js
new file mode 100644
index 0000000..8e01ebe
--- /dev/null
+++ b/vf205_access/dxmodules/dxUart.js
@@ -0,0 +1,242 @@
+//build: 20240715
+//鏁版嵁閫氫俊閫氶亾锛屽寘鎷覆鍙o紙Serial port锛夈�乁SB锛圲niversal Serial Bus锛夊拰闊︽牴锛圵iegand锛�
+//渚濊禆缁勪欢:dxDriver锛宒xStd锛宒xLogger锛宒xMap锛宒xEventBus,dxCommon
+import { channelClass } from './libvbar-m-dxchannel.so'
+import std from './dxStd.js'
+import dxMap from './dxMap.js'
+import dxCommon from './dxCommon.js'
+import bus from './dxEventBus.js'
+const uartObj = new channelClass();
+const map = dxMap.get('default')
+const uart = {}
+uart.TYPE = {
+ USBKBW: 1,//USB Keyboard Wedge閫氳繃USB鎺ュ彛杩炴帴閿洏锛屽苟浠ラ煢鏍瑰崗璁殑褰㈠紡浼犺緭鏁版嵁
+ USBHID: 2,//USB浜轰綋鎺ュ彛璁惧锛圲SB Human Interface Device锛夐�氶亾绫诲瀷
+ UART: 3,//琛ㄧずUART閫氶亾绫诲瀷锛屽嵆涓插彛閫氶亾
+ WIEGAND: 4//闊︽牴锛圵iegand锛夐�氶亾绫诲瀷
+}
+
+/* 鍚勭被閫氶亾 IO 鎺у埗鎿嶄綔鐨勮缃�夐」鏋氫妇 */
+uart.IOC_SET_CMD = {
+ /* 璁剧疆KBW閫氶亾鐨勯厤缃弬鏁� */
+ CHANNEL_IOC_SET_KBW_CONFIG : 1,
+ /* 璁剧疆KBW閫氶亾鐨勪笂浣嶆満鍙傛暟 */
+ CHANNEL_IOC_SET_KBW_UPPER : 2,
+ /* KBW涓婄嚎鏃堕棿 */
+ CHANNEL_IOC_SET_KBW_UPTIME : 3,
+ /* KBW涓嬬嚎鏃堕棿 */
+ CHANNEL_IOC_SET_KBW_DOWNTIME : 4,
+ /* 璁剧疆HID閫氶亾鐨勬姤鍛婇暱搴� */
+ CHANNEL_IOC_SET_HID_REPORT_LEN : 5,
+ /* 璁剧疆UART閫氶亾鐨勫弬鏁� */
+ CHANNEL_IOC_SET_UART_PARAM : 6,
+ /* 璁剧疆闊︽牴閫氶亾鐨勫伐浣滄ā寮� */
+ CHANNEL_IOC_SET_WIEGAND_MODE : 7,
+ /* 璁剧疆闊︽牴閫氶亾鐨凣PIO閰嶇疆 */
+ CHANNEL_IOC_SET_WIEGAND_GPIO : 8,
+ /* 璁剧疆闊︽牴閫氶亾鐨勫欢杩熸椂闂� */
+ CHANNEL_IOC_SET_WIEGAND_DELAY : 9,
+ /* 璁剧疆闊︽牴閫氶亾鐨勬棩蹇楄褰曞姛鑳� */
+ CHANNEL_IOC_SET_WIEGAND_LOG : 10
+
+};
+
+/* 闊︽牴閫氶亾鐨勪笉鍚屽伐浣滄ā寮� */
+uart.WIEGAND_MODE = {
+ /* 闊︽牴妯″紡鍒濆鍖栧�� */
+ WIEGAND_MODE_INIT : 0,
+ /* 闊︽牴 26 浣嶆ā寮� */
+ WIEGAND_MODE_26 : 1,
+ /* 闊︽牴 34 浣嶆ā寮� */
+ WIEGAND_MODE_34 : 2,
+ /* 闊︽牴 128 浣嶆ā寮� */
+ WIEGAND_MODE_128 : 3,
+ /* 闊︽牴 256 浣嶆ā寮� */
+ WIEGAND_MODE_256 : 4,
+ /* 闊︽牴 2048 浣嶆ā寮� */
+ WIEGAND_MODE_2048 : 5,
+ /* 鑷畾涔夌殑闊︽牴妯″紡, 鏈�澶у彂閫� 6400 浣� */
+ WIEGAND_MODE_CUSTOM : 6
+};
+
+/**
+ * 鎵撳紑淇¢亾
+ * @param {number} type 閫氶亾绫诲瀷锛屽弬鑰冩灇涓� TYPE锛屽繀濉�
+ * @param {string} path 涓嶅悓鐨勮澶囨垨鍚屼竴璁惧鐨勪笉鍚岀被鍨嬮�氶亾瀵瑰簲鐨刾ath涓嶄竴鏍凤紝姣斿DW200鐨�485瀵瑰簲鐨勫�兼槸"/dev/ttyS2"锛屽繀濉�
+ * @param {string} id 鍙ユ焺id锛岄潪蹇呭~锛堣嫢鎵撳紑澶氫釜瀹炰緥闇�瑕佷紶鍏ュ敮涓�id锛�
+ */
+uart.open = function (type, path, id) {
+ if (type === undefined || type === null) {
+ throw new Error("uart.open:'type' should not be null or empty")
+ }
+ if (path === undefined || path === null) {
+ throw new Error("uart.open:'path' should not be null or empty")
+ }
+
+ let pointer = uartObj.open(type, path);
+
+ if (pointer === undefined || pointer === null) {
+ throw new Error("uart.open: open failed")
+ }
+
+ dxCommon.handleId("uart", id, pointer)
+}
+
+/**
+ * 淇¢亾鏁版嵁鍙戦��
+ * @param {ArrayBuffer} buffer 瑕佸彂閫佺殑鏁版嵁锛屽繀濉�
+ * @param {string} id 鍙ユ焺id锛岄潪蹇呭~锛堥渶淇濇寔鍜宨nit涓殑id涓�鑷达級
+ * @returns true/false
+ */
+uart.send = function (buffer, id) {
+ if (buffer === undefined || buffer === null) {
+ throw new Error("uart.send: 'buffer' should not be null or empty")
+ }
+ let pointer = dxCommon.handleId("uart", id)
+
+ return uartObj.send(pointer, buffer);
+}
+
+/**
+ * 淇¢亾鏁版嵁鍙戦�侊紝浣跨敤寰厜閫氫俊鍗忚鏍煎紡
+ * @param {string/object} data 瑕佸彂閫佺殑鏁版嵁锛屽繀濉�
+ * @param {string} id 鍙ユ焺id锛岄潪蹇呭~锛堥渶淇濇寔鍜宨nit涓殑id涓�鑷达級
+ * @returns true/false
+ */
+uart.sendVg = function (data, id) {
+ if (!data) {
+ return
+ }
+ if (typeof data === 'string') {
+ uart.send(dxCommon.hexStringToArrayBuffer(data), id)
+ return
+ }
+ let pack = '55aa' + data.cmd
+ if (data.hasOwnProperty('result')) {
+ pack += data.result
+ }
+ pack += (data.length % 256).toString(16).padStart(2, '0')
+ pack += (Math.floor(data.length / 256)).toString(16).padStart(2, '0')
+ pack += data.data
+ let all = dxCommon.hexToArr(pack)
+ let bcc = dxCommon.calculateBcc(all)
+ all.push(bcc)
+ uart.send(new Uint8Array(all).buffer, id)
+}
+
+/**
+ * 鎺ユ敹鏁版嵁锛岄渶瑕佸湪绾跨▼閲岃疆璇㈠幓鑾峰彇,杩斿洖Uint8Array绫诲瀷
+ * 濡傛灉鎺ユ敹鍒扮殑鏁版嵁娌℃湁杈惧埌size闀垮害锛屼細缁х画绛夊緟鐩村埌鎺ユ敹鍒皊ize闀垮害锛屼絾鏄鏋渢imeout寰堢煭锛屽氨浼氭湁鍙兘娌℃敹瀹屽氨缁撴潫杩欎竴娆℃搷浣�
+ * @param {number} size 鎺ユ敹鏁版嵁鐨勫瓧鑺傛暟锛屽繀濉�
+ * @param {number} timeout 瓒呮椂鏃堕棿锛堟绉掞級杩欎釜鍑芥暟浼氶樆濉炵瓑寰呮渶澶氳繖涓椂闂村氨缁撴潫锛屽鏋滄彁鍓嶆帴鏀跺埌浜唖ize涓暟鎹篃浼氱粨鏉燂紝闈炲繀濉紝缂虹渷鏄�10ms
+ * @param {string} id 鍙ユ焺id锛岄潪蹇呭~锛堥渶淇濇寔鍜宨nit涓殑id涓�鑷达級
+ * @returns Uint8Array,杩斿洖鍊肩殑byteLength琛ㄧず鎺ユ敹鍒扮殑闀垮害锛屽鏋滀负0琛ㄧず娌℃湁鎺ユ敹鍒颁换浣曟暟鎹�
+ */
+uart.receive = function (size, timeout, id) {
+ if (size === undefined || size === null) {
+ throw new Error("uart.receive:'size' should not be null or empty")
+ }
+
+ if (timeout === undefined || timeout === null) {
+ timeout = 10
+ }
+
+ let pointer = dxCommon.handleId("uart", id)
+
+ let res = uartObj.receive(pointer, size, timeout)
+ if (res === null) {
+ return null
+ }
+ return new Uint8Array(res)
+}
+
+/**
+ * 璋冪敤淇¢亾鐗规畩IO鎺ュ彛
+ * @param {*} request
+ * @param {*} arg
+ * @param {string} id 鍙ユ焺id锛岄潪蹇呭~锛堥渶淇濇寔鍜宨nit涓殑id涓�鑷达級
+ * @returns true/false
+ */
+uart.ioctl = function (request, arg, id) {
+ let pointer = dxCommon.handleId("uart", id)
+
+ return uartObj.ioctl(pointer, request, arg)
+}
+
+/**
+ * 鍏抽棴淇¢亾
+ * @param {string} id 鍙ユ焺id锛岄潪蹇呭~锛堥渶淇濇寔鍜宨nit涓殑id涓�鑷达級
+ * @returns true/false
+ */
+uart.close = function (id) {
+ let pointer = dxCommon.handleId("uart", id)
+
+ return uartObj.close(pointer)
+}
+
+
+/**
+ * 鍒锋柊淇¢亾
+ * @param {number} queue_selector 蹇呭~
+ * @param {string} id 鍙ユ焺id锛岄潪蹇呭~锛堥渶淇濇寔鍜宨nit涓殑id涓�鑷达級
+ * @returns true/false
+ */
+uart.flush = function (queue_selector, id) {
+ if (queue_selector == null) {
+ throw new Error("queue_selector should not be null or empty")
+ }
+ let pointer = dxCommon.handleId("uart", id)
+
+ return uartObj.flush(pointer, queue_selector);
+}
+
+
+uart.VG = {
+ RECEIVE_MSG: '__uartvg__MsgReceive',
+}
+
+/**
+ * 绠�鍖栧井鍏夐�氫俊鍗忚鐨勪娇鐢紝
+ * 1. 鎺ュ彈鏁版嵁锛氭妸TLV鐨勪簩杩涘埗鐨勬暟鎹帴鍙楀埌鍚庤В鏋愭垚瀵硅薄锛屽苟浠ventbus鐨別vent鍙戦�佸嚭鍘�(uart.VG.RECEIVE_MSG+options.id)
+ * 杩斿洖鐨勫璞℃牸寮忥細{cmd:"2a",result:"01",length:7,data:"0a1acc320fee32",bcc:true}
+ * cmd: 1涓瓧鑺傜殑鍛戒护瀛楋紝16杩涘埗瀛楃涓�
+ * result:1涓瓧鑺傜殑鏍囪瘑瀛楋紝琛ㄧず鏁版嵁澶勭悊鐨勭粨鏋滐紝鎴愬姛鎴栧け璐ユ垨鍏朵粬鐘舵�併�傚彧鏈夊弽棣堟暟鎹墠鏈夋爣璇嗗瓧锛�16杩涘埗瀛楃涓�
+ * length锛氭暟鎹殑闀垮害锛屽湪TLV閲岀敤2涓瓧鑺傛潵瀹氫箟锛岃繖閲岀洿鎺ヨ浆鎴�10杩涘埗鐨勬暟瀛�
+ * data锛氬涓瓧鑺傜殑鏁版嵁鍩燂紝16杩涘埗瀛楃涓�
+ * bcc: bcc鏍¢獙鎴愬姛鎴栧け璐�
+ * 2. 鍙戦�佹暟鎹細鎶婂璞¤浆鎴怲LV鏍煎紡鐨勪簩杩涘埗鏁版嵁鍐嶅彂閫佸嚭鍘伙紝鍙互閫氳繃uart.sendVg('瑕佸彂閫佺殑鏁版嵁',id)锛屾暟鎹牸寮忓涓�
+ * 鍙戦�佺殑鏁版嵁鏍煎紡鏈変簩绉� 1.瀵硅薄鏍煎紡 锛歿cmd:"2a",result:"01",length:7,data:"0a1acc320fee32"} 2. 瀹屾暣鐨�16杩涘埗瀛楃涓�'55AA09000000F6'
+ * 3. 鍚屾牱鐨刬d锛屽娆¤皟鐢╮unvg涔熷彧浼氭墽琛屼竴娆�
+ *
+ * @param {object} options 鍚姩鐨勫弬鏁�
+ * @param {number} options.type 閫氶亾绫诲瀷锛屽弬鑰冩灇涓� TYPE锛屽繀濉� 锛堝吋瀹筓SBHID鍧椾紶杈擄紝榛樿1024姣忓潡锛�
+ * @param {string} options.path 涓嶅悓鐨勮澶囨垨鍚屼竴璁惧鐨勪笉鍚岀被鍨嬮�氶亾瀵瑰簲鐨刾ath涓嶄竴鏍凤紝姣斿DW200鐨�485瀵瑰簲鐨勫�兼槸"/dev/ttyS2"锛屽繀濉�
+ * @param {number} options.result 0鍜�1(缂虹渷鏄�0)锛屾爣璇嗘槸鎺ユ敹鐨勬暟鎹繕鏄彂閫佺殑鏁版嵁鍖呭惈鏍囪瘑瀛楄妭锛�0琛ㄧず鎺ュ彈鐨勬暟鎹笉鍖呮嫭鏍囪瘑瀛楋紝鍙戦�佺殑鏁版嵁鍖呮嫭锛�1鏄弽涔�
+ * @param {number} options.passThrough passThrough涓簍rue鍒欐帴鏀剁殑鏁版嵁浣跨敤閫忎紶妯″紡锛岄潪蹇呭~
+ * @param {string} options.id 鍙ユ焺id锛岄潪蹇呭~锛堣嫢鍒濆鍖栧涓疄渚嬮渶瑕佷紶鍏ュ敮涓�id锛�
+ */
+uart.runvg = function (options) {
+ if (options === undefined || options.length === 0) {
+ throw new Error("dxuart.runvg:'options' parameter should not be null or empty")
+ }
+ if (options.id === undefined || options.id === null || typeof options.id !== 'string') {
+ // 鍙ユ焺id
+ options.id = ""
+ }
+ if (options.type === undefined || options.type === null) {
+ throw new Error("dxuart.runvg:'type' should not be null or empty")
+ }
+ if (options.path === undefined || options.path === null) {
+ throw new Error("dxuart.runvg:'path' should not be null or empty")
+ }
+ let oldfilepre = '/app/code/dxmodules/vgUartWorker'
+ let content = std.loadFile(oldfilepre + '.js').replace("{{id}}", options.id)
+ let newfile = oldfilepre + options.id + '.js'
+ std.saveFile(newfile, content)
+ let init = map.get("__vguart__run_init" + options.id)
+ if (!init) {//纭繚鍙垵濮嬪寲涓�娆�
+ map.put("__vguart__run_init" + options.id, options)
+ bus.newWorker(options.id || "__uart",newfile)
+ }
+}
+export default uart;
\ No newline at end of file
diff --git a/vf205_access/dxmodules/dxUi.js b/vf205_access/dxmodules/dxUi.js
new file mode 100644
index 0000000..bae9902
--- /dev/null
+++ b/vf205_access/dxmodules/dxUi.js
@@ -0,0 +1,216 @@
+//build:20240724
+/**
+ * UI 鐨勫熀纭�缁勪欢锛岄渶瑕佸厛浜嗚В涓�浜涙蹇�
+ * 1. 鍥惧眰锛氳澶囧叿澶�2涓熀鏈浘灞傦紝涓诲浘灞傦紙main锛夊拰椤堕儴鍥惧眰锛坱op锛�
+ 鍏朵腑TOP鍥惧眰姘歌繙鍦ㄤ富鍥惧眰涔嬩笂锛屼富鍥惧眰鍒囨崲椤甸潰涓嶄細鎸′綇TOP鍥惧眰锛孴OP鍥惧眰鐢ㄤ簬鏄剧ず涓�浜涚姸鎬佹爮鏄瘮杈冨悎閫傜殑銆�
+ 鍏朵腑涓诲浘灞傚彲浠ラ鍏堝湪鍐呭瓨涓瀯閫犲涓〉闈紝鐒跺悗閫氳繃loadMain鏉ュ姞杞藉垏鎹笉鍚岀殑椤甸潰銆傝�孴OP鍥惧眰涓嶈兘鍒囨崲锛屽彧鑳借ui瀵硅薄闅愯棌鎴栧垹闄�
+
+ * 2. UI瀵硅薄锛氭湁寰堝绉嶇被鐨刄I瀵硅薄锛屽叾涓渶鍩虹鐨勬槸 'view' 瀵硅薄锛屼富鍥惧眰鍜岄《閮ㄥ浘灞傜殑鏍箄i瀵硅薄蹇呴』鏄� 'view'瀵硅薄锛屽墿涓嬬殑 ui 瀵硅薄閮芥槸鏌愪釜 ui 瀵硅薄鐨勫瓙ui銆�
+ ui瀵硅薄鍖呮嫭甯歌鐨� 'button'銆�'label'銆�'image'绛夌瓑锛屾墍鏈夊璞¢兘鏈変竴浜涢�氱敤鐨勫睘鎬э紝涔熸湁涓�浜涚嫭鐗圭殑灞炴��
+ 鎵�鏈� ui 瀵硅薄閮芥湁鍏ㄥ眬鍞竴鐨� id 锛屼笉鑳介噸澶嶃�傞�氱敤鐨勫睘鎬ц繕鍖呮嫭
+ - type锛氳幏鍙杣i瀵硅薄鐨勭被鍨嬶紝瀛楃涓�
+ - parent锛氳幏鍙杣i瀵硅薄鐨勭埗鑺傜偣锛屽瓧绗︿覆
+ - children锛氳幏鍙杣i瀵硅薄鐨勬墍鏈夊瓙瀵硅薄鐨刬d锛屽瓧绗︿覆鏁扮粍
+
+ * 3. dxui鏂囦欢锛氫互.dxui涓烘墿灞曞悕鐨勬枃浠舵槸鍒╃敤鍙鍖栨嫋鎷藉伐鍏风敓鎴愮殑 ui 鏍�,宸ュ叿浼氳嚜鍔ㄧ敓鎴愬搴旂殑js鏂囦欢锛屽彲浠mport瀵瑰簲鐨刯s鏂囦欢鏉ユ搷浣�
+
+ */
+
+import logger from './dxLogger.js'
+import utils from './uiUtils.js'
+import button from './uiButton.js'
+import font from './uiFont.js'
+import image from './uiImage.js'
+import label from './uiLabel.js'
+import line from './uiLine.js'
+import list from './uiList.js'
+import dropdown from './uiDropdown.js'
+import checkbox from './uiCheckbox.js'
+import slider from './uiSlider.js'
+import _switch from './uiSwitch.js'
+import textarea from './uiTextarea.js'
+import keyboard from './uiKeyboard.js'
+import style from './uiStyle.js'
+import view from './uiView.js'
+import buttons from './uiButtons.js'
+
+const dxui = {}
+dxui.Button = button
+dxui.Font = font
+dxui.Image = image
+dxui.Label = label
+dxui.Line = line
+dxui.List = list
+dxui.Dropdown = dropdown
+dxui.Checkbox = checkbox
+dxui.Slider = slider
+dxui.Switch = _switch
+dxui.Textarea = textarea
+dxui.Keyboard = keyboard
+dxui.Style = style
+dxui.View = view
+dxui.Utils = utils
+dxui.Buttons = buttons
+let orientation = 1 //榛樿妯睆
+/**
+ * 鍒濆鍖栵紝蹇呴』鍦ㄤ唬鐮佹渶鍓嶉潰璋冪敤
+ * @param {object} options 鍒濆鍖栧弬鏁�
+ * @param {number} options.orientation 灞忓箷鏂瑰悜 鍙互涓�0锛�1锛�2锛�3锛屽垎鍒〃绀虹珫灞忥紝灞忓箷鍦ㄥ乏锛涙í灞忥紝灞忓箷鍦ㄤ笂锛涚珫灞忥紝灞忓箷鍦ㄥ彸锛涙í鎵癸紝灞忓箷鍦ㄤ笅
+ * @param {object} context 涓婁笅鏂囷紝姣忎釜搴旂敤閮芥湁鍞竴鐨勪竴涓笂涓嬫枃鍙橀噺锛屼笉鍚岀殑js鍙互閮藉紩鐢╠xUi.js锛屼絾鏄痗ontext蹇呴』涓�鑷�
+*/
+dxui.init = function (options, context = {}) {
+ this.initContext(context)
+ if (options && options.orientation != undefined && options.orientation != null && [0, 1, 2, 3].includes(options.orientation)) {
+ orientation = options.orientation
+ }
+ utils.GG.NativeDisp.lvDispSetRotation(orientation)
+}
+/**
+ * 鍒濆鍖栦笂涓嬫枃锛屾瘡涓簲鐢ㄩ兘鏈夊敮涓�鐨勪竴涓笂涓嬫枃鍙橀噺锛屼笉鍚岀殑js鍙互閮藉紩鐢╠xUi.js锛屼絾鏄痗ontext蹇呴』涓�鑷�
+ * 鍦ㄦ瀯寤簎i鍓嶉渶瑕佸垵濮嬪寲
+ * @param {object} context 鍒濆鏄竴涓┖瀵硅薄{}
+ */
+dxui.initContext = function (context) {
+ utils.validateObject(context)
+ dxui.all = context
+ dxui.Button.all = dxui.all
+ dxui.Image.all = dxui.all
+ dxui.Label.all = dxui.all
+ dxui.Line.all = dxui.all
+ dxui.List.all = dxui.all
+ dxui.Dropdown.all = dxui.all
+ dxui.Checkbox.all = dxui.all
+ dxui.Slider.all = dxui.all
+ dxui.Switch.all = dxui.all
+ dxui.Textarea.all = dxui.all
+ dxui.Keyboard.all = dxui.all
+ dxui.View.all = dxui.all
+ dxui.Buttons.all = dxui.all
+}
+/**
+ * 鏍规嵁id鑾峰彇宸茬粡鏋勫缓鐨剈i瀵硅薄
+ * @param {string} id
+ * @returns
+ */
+dxui.getUi = function (id) {
+ return dxui.all[id]
+}
+/**
+ * 澶栭儴寰幆闇�瑕佽皟鐢ㄦ鏂规硶
+ */
+dxui.handler = function () {
+ return utils.GG.NativeTimer.lvTimerHandler()
+}
+/**
+ * 鑾峰彇灞忓箷鏂瑰悜锛屼笉鍚岀殑灞忓箷鏂瑰悜鍙兘瑕佸姞杞戒笉鍚岀殑ui鎴栦笉鍚岀殑澶勭悊閫昏緫
+ * @returns 鍙互涓�0锛�1锛�2锛�3锛屽垎鍒〃绀虹珫灞忥紝灞忓箷鍦ㄥ乏锛涙í灞忥紝灞忓箷鍦ㄤ笂锛涚珫灞忥紝灞忓箷鍦ㄥ彸锛涙í鎵癸紝灞忓箷鍦ㄤ笅
+ */
+dxui.getOrientation = function () {
+ return orientation;
+}
+/**
+ * 鍒涘缓涓�涓畾鏃跺櫒锛屾瘡闅攎s姣鎵ц涓�娆″洖璋冨嚱鏁帮紝涓昏鐢ㄤ簬瀹氭椂鍒锋柊鏌愪釜ui瀵硅薄鐨勫��
+ * 鍙互鍦ㄥ洖璋冨嚱鏁伴噷鍒犻櫎瀹氭椂鍣�(clearInterval)鏉ュ疄鐜皊etTimeout鐨勬晥鏋�
+ * @param {string} id 瀹氭椂鍣ㄧ殑鍞竴鏍囪瘑 蹇呭~
+ * @param {function} callback 鍥炶皟鍑芥暟锛堝彲浠ユ槸鍖垮悕鍑芥暟锛�
+ * @param {number} ms 姣鏁�
+ * @param {object} user_data 鐢ㄦ埛鏁版嵁锛屼紶閫掔粰鍥炶皟鍙傛暟
+ * @returns 瀹氭椂鍣ㄥ彞鏌�
+ */
+dxui.setInterval = function (id, callback, ms, user_data) {
+ if (utils.validateId(dxui.all, id))
+ if (!callback || (typeof callback != 'function') || !callback.name || callback.name === '') {
+ throw new Error('The callback should not be null and should be named function')
+ }
+ if (!ms || (typeof ms != 'number')) {
+ throw new Error('The interval should not be empty, and should be number')
+ }
+ if (!this.all.__interval) {
+ this.all.__interval = {}
+ }
+ this.all.__interval[id] = utils.GG.NativeTimer.lvTimerCreate(callback, ms, user_data)
+}
+/**
+ * 瀹氭椂鍣ㄤ笉鍐嶉渶瑕佸悗锛屽彲浠ュ垹闄よ繖涓畾鏃跺櫒
+ * @param {string} id 瀹氭椂鍣╥d
+ */
+dxui.clearInterval = function (id) {
+ if (!dxui.all[id]) {
+ return
+ }
+ utils.GG.NativeTimer.lvTimerDel(dxui.all[id])
+ delete dxui.all.__interval[id]
+}
+/**
+ * 鑾峰彇ui瀵硅薄鐨勭埗瀵硅薄
+ * @param {Object} ui
+ */
+dxui.getParent = function (ui) {
+ if (ui.parent) {
+ return dxui.getUi(ui.parent)
+ }
+ return null
+}
+/**
+ * 鍒犻櫎褰撳墠鑷韩ui瀵硅薄
+ */
+dxui.del = function (ui) {
+ function recursiveDelete(ui) {
+ // 濡傛灉瀵硅薄涓嶅瓨鍦紝鐩存帴杩斿洖
+ if (!dxui.all[ui.id]) {
+ return;
+ }
+
+ // 鍏堥�掑綊鍒犻櫎鎵�鏈夊瓙瀵硅薄
+ if (ui.children && Array.isArray(ui.children)) {
+ // 鍊掑簭閬嶅巻瀛愯妭鐐�
+ for (let i = ui.children.length - 1; i >= 0; i--) {
+ const childId = ui.children[i];
+ if (dxui.all[childId]) {
+ recursiveDelete(dxui.all[childId]);
+ }
+ }
+ }
+ // 浠庣埗瀵硅薄涓Щ闄ゅ綋鍓嶅璞�
+ if (ui.parent && dxui.all[ui.parent] && Array.isArray(dxui.all[ui.parent].children)) {
+ const children = dxui.all[ui.parent].children
+ let index = children.indexOf(ui.id);
+ if (index !== -1) {
+ children.splice(index, 1);
+ }
+ }
+
+ // 鍒犻櫎褰撳墠瀵硅薄
+ ui.obj.lvObjDel();
+ delete dxui.all[ui.id];
+ }
+
+ // 寮�濮嬮�掑綊鍒犻櫎
+ recursiveDelete(ui);
+}
+/**
+ * 鍦ㄤ富鍥惧眰鍔犺浇锛堝垏鎹級宸茬粡鏋勫缓濂界殑 ui 瀵硅薄锛�
+ * @param {object} ui 浣跨敤build鍑芥暟鏋勫缓鐨� ui 瀵硅薄
+ */
+dxui.loadMain = function (ui) {
+ if (!ui || !ui.obj) {
+ throw new Error("dxui.loadMain:'ui' paramter should not be null")
+ }
+ // 鍔犺浇涓诲睆骞�
+ utils.GG.NativeDisp.lvScrLoad(ui.obj)
+}
+/**
+ * 浠庢渶鍚庝竴涓敤鎴锋椿鍔ㄦ樉绀�(濡傜偣鍑�)缁忚繃鐨勬椂闂�
+ * @returns 杩斿洖浠庢渶鍚庝竴涓椿鍔ㄥ紑濮嬬殑缁忚繃鏃堕棿(姣)
+ */
+dxui.getIdleDuration = function () {
+ return utils.GG.NativeDisp.lvDispGetInactiveTime()
+}
+/**
+ * 閲嶇疆鐢ㄦ埛娲诲姩鏄剧ず(濡傜偣鍑�)缁忚繃鐨勬椂闂�
+ */
+dxui.trigActivity = function () {
+ utils.GG.NativeDisp.lvDispTrigActivity()
+}
+
+export default dxui;
\ No newline at end of file
diff --git a/vf205_access/dxmodules/dxWatchdog.js b/vf205_access/dxmodules/dxWatchdog.js
new file mode 100644
index 0000000..963949b
--- /dev/null
+++ b/vf205_access/dxmodules/dxWatchdog.js
@@ -0,0 +1,123 @@
+//build 20240425
+//鐪嬮棬鐙楃粍浠讹紝鐢ㄤ簬鐩戞帶搴旂敤鏄惁鍗℃锛岃缃竴涓秴鏃舵椂闂达紝濡傛灉瓒呰繃杩欎釜鏃堕棿娌℃湁鍠傜嫍锛屼細鑷姩瑙﹀彂璁惧閲嶅惎
+//娉ㄦ剰浣跨敤鐪嬮棬鐙椾箣鍓嶅彲鑳介渶瑕佸厛鍒濆鍖杇pio
+//渚濊禆缁勪欢 dxDriver,dxLogger,dxCommon,dxMap,dxGpio
+import { watchdogClass } from './libvbar-b-dxwatchdog.so'
+import dxMap from './dxMap.js'
+import logger from './dxLogger.js'
+import dxCommon from './dxCommon.js'
+
+const map = dxMap.get("___watchdog")
+const watchdogObj = new watchdogClass();
+
+const watchdog = {}
+watchdog.last = new Date().getTime()
+/**
+ * 鎵撳紑鐪嬮棬鐙楄澶�
+ * @param {number} type 蹇呭~
+ * @param {string} id 鍙ユ焺id锛岄潪蹇呭~锛堣嫢鍒濆鍖栧涓疄渚嬮渶瑕佷紶鍏ュ敮涓�id锛�
+ */
+watchdog.open = function (type, id) {
+ let pointer = watchdogObj.open(type)
+ if (pointer === undefined || pointer === null) {
+ throw new Error("watchdog.open: open failed")
+ }
+ dxCommon.handleId("watchdog", id, pointer)
+}
+/**
+ * 鎺у埗鎸囧畾閫氶亾寮�鍏�
+ * @param {number} chan 閫氶亾id,蹇呭~
+ * @param {string} id 鍙ユ焺id锛岄潪蹇呭~锛堥渶淇濇寔鍜宨nit涓殑id涓�鑷达級
+ * @returns true/false
+ */
+watchdog.enable = function (chan, id) {
+ let pointer = dxCommon.handleId("watchdog", id)
+ return watchdogObj.enable(pointer, chan)
+}
+/**
+ * 寮�鍚湅闂ㄧ嫍鎬诲畾鏃跺櫒
+ * @param {*} timeout 蹇呭~
+ * @param {string} id 鍙ユ焺id锛岄潪蹇呭~锛堥渶淇濇寔鍜宨nit涓殑id涓�鑷达級
+ * @returns true/false
+ */
+watchdog.start = function (timeout, id) {
+ let pointer = dxCommon.handleId("watchdog", id)
+ return watchdogObj.start(pointer, timeout)
+}
+/**
+ * 鍒ゆ柇鏄惁鏄笂鐢靛浣嶏紝鐪嬮棬鐙楁槸鍚﹀凡缁忓惎鍔�
+ * @param {string} id 鍙ユ焺id锛岄潪蹇呭~锛堥渶淇濇寔鍜宨nit涓殑id涓�鑷达級
+ * @returns true/false
+ */
+watchdog.isPoweron = function (id) {
+ let pointer = dxCommon.handleId("watchdog", id)
+ return watchdogObj.isPoweron(pointer)
+}
+/**
+ * 鍠傜嫍鎸囧畾閫氶亾
+ * @param {*} chan 閫氶亾id锛屽繀濉�
+ * @param {string} id 鍙ユ焺id锛岄潪蹇呭~锛堥渶淇濇寔鍜宨nit涓殑id涓�鑷达級
+ * @returns true/false
+ */
+watchdog.restart = function (chan, id) {
+ let pointer = dxCommon.handleId("watchdog", id)
+ return watchdogObj.restart(pointer, chan)
+}
+/**
+ * 鍏抽棴鐪嬮棬鐙楁�诲畾鏃跺櫒
+ * @param {string} id 鍙ユ焺id锛岄潪蹇呭~锛堥渶淇濇寔鍜宨nit涓殑id涓�鑷达級
+ * @returns true/false
+ */
+watchdog.stop = function (id) {
+ let pointer = dxCommon.handleId("watchdog", id)
+ return watchdogObj.stop(pointer)
+}
+/**
+ * 鍏抽棴鐪嬮棬鐙楄澶�
+ * @param {string} id 鍙ユ焺id锛岄潪蹇呭~锛堥渶淇濇寔鍜宨nit涓殑id涓�鑷达級
+ * @returns true/false
+ */
+watchdog.close = function (id) {
+ let pointer = dxCommon.handleId("watchdog", id)
+ return watchdogObj.close(pointer)
+}
+/**
+ * 寰幆妫�鏌ユ瘡涓嚎绋嬬殑鍠傜嫍鎯呭喌锛屼换浣曚竴涓嚎绋嬫病鏈夊杺鐙楋紝鍒欎笉鍚姩restart
+ * @param {number} chan 閫氶亾id锛屽繀濉�
+ * @param {string} id 鍙ユ焺id锛岄潪蹇呭~锛堥渶淇濇寔鍜宨nit涓殑id涓�鑷达級
+ */
+watchdog.loop = function (chan, id) {
+ const now = new Date().getTime()
+ const minus = now - watchdog.last
+ if (minus > 3000 || minus < 0) {//姣�3绉掓鏌ヤ竴娆℃垨鑰呭皬浜�0浠h〃鎿嶄綔浜嗗線鍓嶆敼鏃堕棿
+ watchdog.last = now
+ let keys = map.keys()
+ let check = true
+ for (let i = 0; i < keys.length; i++) {
+ let key = keys[i]
+ let value = map.get(key)
+ const temp = now - value.now
+ if (temp > value.timeout * 1000 && temp < 1700000000) {
+ logger.error(`The worker ${key} did not feed the dog in time.`, temp)
+ check = false
+ break
+ }
+ }
+ if (check) {
+ this.restart(chan, id)
+ }
+ }
+}
+/**
+ * 涓嶅悓鐨勭嚎绋嬪杺鐙�
+ * @param {string} flag 绾跨▼鐨勬爣璇�,蹇呭~涓嶈兘涓虹┖
+ * @param {number} timeout 绾跨▼鍙互澶氶暱鏃堕棿涓嶅杺鐙楋紙绉掞級锛岀己鐪佹槸10绉�
+ */
+watchdog.feed = function (flag, timeout = 10) {
+ if (!flag || flag.length <= 0) {
+ return
+ }
+ map.put(flag, { now: new Date().getTime(), timeout: timeout })
+}
+
+export default watchdog;
diff --git a/vf205_access/dxmodules/dxWorkerPool.js b/vf205_access/dxmodules/dxWorkerPool.js
new file mode 100644
index 0000000..91cbf5d
--- /dev/null
+++ b/vf205_access/dxmodules/dxWorkerPool.js
@@ -0,0 +1,167 @@
+//build:20240717
+//绾跨▼姹狅紝閲岄潰鍔犺浇澶氫釜worker锛岀嚎绋嬫睜鎺ユ敹浠诲姟鎴栦簨鍔″悗鐒跺悗娲惧彂缁欑嚎绋嬫睜閲岄潰绌洪棽鐨剋orker鏉ユ墽琛屼换鍔★紝鐢ㄤ簬瑙e喅澶氫簨鍔″鐞嗙殑鐡堕
+//璁惧璧勬簮鏈夐檺锛岀嚎绋嬫暟閲忎笉瀹滃お澶氾紝鍙﹀涔熶笉鑰冭檻澶氫釜绾跨▼姹犵殑鎯呭喌锛屽叏灞�鍙竴涓�
+//缁勪欢渚濊禆 dxLogger,dxCommon锛宒xStd
+import std from './dxStd.js'
+import logger from './dxLogger.js'
+import * as os from "os";
+//-------------------------variable--------------------
+const pool = {}
+const isMain = (os.Worker.parent === undefined)
+let queueSize = 100
+const queue = []
+const all = {}
+pool.os = os
+/**
+ * 鍒濆鍖栫嚎绋嬫睜锛岃缃畐orker涓暟鍜岀紦瀛橀槦鍒楀ぇ灏忥紝鏈夊彲鑳藉涓獁orker閮芥病鏈夌┖闂诧紝缂撳瓨闃熷垪鍙互缂撳瓨鏉ヤ笉鍙婂鐞嗙殑浜嬪姟
+ * 鍥犱负worker鍙兘閫氳繃涓荤嚎绋嬪垱寤猴紝鎵�浠nit鍑芥暟涔熷彧鑳藉湪涓荤嚎绋嬮噷鎵ц
+ * 娉ㄦ剰: worker瀵瑰簲鐨勬枃浠堕噷涓嶈兘鍖呭惈while(true)杩欑姝诲惊鐜紝鍙互鐢╯etInteval鏉ュ疄鐜板惊鐜�
+ * @param {string} file worker瀵瑰簲鐨勬枃浠跺悕锛屽繀濉紝缁濆璺緞锛岄�氬父浠�'/app/code/src'寮�濮�
+ * @param {Object} bus EventBus瀵硅薄 蹇呭~
+ * @param {Array} topics 瑕佽闃呯殑涓婚缁� 蹇呭~
+ * @param {number} count 绾跨▼鐨勪釜鏁帮紝闈炲繀濉紝涓嶈兘灏忎簬1锛岀己鐪�2,
+ * @param {number} maxsize 浜嬪姟缂撳瓨鐨勫ぇ灏忥紝闈炲繀濉紝缂虹渷100锛屽鏋滆秴杩�100锛屾渶鑰佺殑浜嬪姟琚姏寮�
+ */
+pool.init = function (file, bus, topics, count = 2, maxsize = 100) {
+ if (!file) {
+ throw new Error("pool init:'file' should not be empty")
+ }
+ if (!bus) {
+ throw new Error("pool init:'bus' should not be empty")
+ }
+ if (!topics) {
+ throw new Error("pool init:'topics' should not be empty")
+ }
+ if (!isMain) {
+ throw new Error("pool init should be invoked in main thread")
+ }
+ if (!std.exist(file)) {
+ throw new Error("pool init: file not found:" + file)
+ }
+ queueSize = maxsize
+ if (count <= 1) {
+ count = 1
+ }
+ for (let i = 0; i < count; i++) {
+ const id = 'pool__id' + i
+ let content = std.loadFile(file) + `
+import __pool from '/app/code/dxmodules/dxWorkerPool.js'
+__pool.id = '${id}'
+const __parent = __pool.os.Worker.parent
+__parent.onmessage = function (e) {
+ if (!e.data) {
+ return
+ }
+ let fun = __pool.callbackFunc
+ if (fun) {
+ try {
+ fun(e.data)
+ __parent.postMessage({ id: __pool.id })//閫氱煡澶勭悊瀹屼簡idle
+ } catch (err) {
+ __parent.postMessage({ id: __pool.id, error: err.stack })//閫氱煡澶勭悊瀹屼簡idle,浣嗘槸澶辫触浜�
+ }
+ }
+}
+ `
+ let newfile = file + '_' + id + '.js'
+ std.saveFile(newfile, content)
+ let worker = new os.Worker(newfile)
+ all[id] = { isIdle: true, worker: worker }
+ worker.onmessage = function (data) {
+ if (!data.data) {
+ return
+ }
+ const id = data.data.id
+ if (id) {//閫氱煡澶勭悊瀹屾垚鐨勬秷鎭�
+ all[id].isIdle = true
+ if (data.data.error) {
+ logger.error(`worker ${id} callback error:${data.data.error}`)
+ }
+ } else {
+ const topic = data.data.topic
+ if (topic) {//bus.fire鍑烘潵鐨勬秷鎭�
+ bus.fire(topic, data.data.data)
+ }
+ }
+ }
+ }
+ for (let topic of topics) {
+ bus.on(topic, function (d) {
+ push({ topic: topic, data: d })
+ })
+ }
+
+ std.setInterval(function () {
+ Object.keys(all).forEach(key => {
+ const obj = all[key]
+ if (obj.isIdle) {
+ let event = take()
+ if (event) {
+ obj.isIdle = false
+ obj.worker.postMessage(event)
+ }
+ }
+ });
+ }, 5)
+}
+/**
+ * 杩斿洖绾跨▼鐨勫敮涓�鏍囪瘑id
+ * @returns worker鍞竴鏍囪瘑
+ */
+pool.getWorkerId = function () {
+ if (isMain) {
+ return 'main'
+ } else {
+ return pool.id
+ }
+}
+/**
+ * 璁㈤槄EventBus 涓婄殑浜嬪姟涓婚锛屽彲浠ヨ闃呭涓富棰�,杩欎釜鍑芥暟涔熷彧鑳藉湪涓荤嚎绋嬮噷鎵ц
+ * @param {Object} bus EventBus瀵硅薄
+ * @param {Array} topics 瑕佽闃呯殑涓婚缁�
+ */
+pool.on = function (bus, topics) {
+ if (!bus) {
+ throw new Error("pool onEventBus:'bus' should not be empty")
+ }
+ if (!topics) {
+ throw new Error("pool onEventBus:'topics' should not be empty")
+ }
+ if (!isMain) {
+ throw new Error("pool onEventBus should be invoked in main thread")
+ }
+
+}
+
+pool.callbackFunc = null
+/**
+ * worker绾跨▼璁㈤槄绾跨▼姹犵殑浜嬩欢锛屼笉鐢ㄩ�夋嫨鐗瑰畾鐨勪富棰橈紝绾跨▼姹犲叧娉ㄧ殑鎵�鏈変簨浠堕兘浼氬鐞�,
+ * 杩欎釜鍑芥暟蹇呴』鍦╳orker绾跨▼閲屾墽琛岋紝涓嶈兘鍦ㄤ富绾跨▼鎵ц
+ * @param {function} cb 浜嬩欢澶勭悊鐨勫洖璋冨嚱鏁帮紝蹇呭~
+ */
+pool.callback = function (cb) {
+ if (!cb || (typeof cb) != 'function') {
+ throw new Error("pool on :The 'callback' should be a function");
+ }
+ if (isMain) {
+ throw new Error("pool on should not be invoked in main thread")
+ }
+ pool.callbackFunc = cb
+}
+
+function push(item) {
+ if (queue.length >= queueSize) {
+ const first = JSON.stringify(queue[0])
+ logger.error(`pool queue is full,removing oldest element: ${first}`)
+ queue.shift(); // 绉婚櫎鏈�鑰佺殑鍏冪礌
+ }
+ queue.push(item);
+}
+
+function take() {
+ if (queue.length === 0) {
+ return null; // 闃熷垪涓虹┖鏃惰繑鍥� null
+ }
+ return queue.shift(); // 绉婚櫎骞惰繑鍥炴渶鏃╂坊鍔犵殑鍏冪礌
+}
+export default pool
diff --git a/vf205_access/dxmodules/faceWorker.js b/vf205_access/dxmodules/faceWorker.js
new file mode 100644
index 0000000..9b0fbc2
--- /dev/null
+++ b/vf205_access/dxmodules/faceWorker.js
@@ -0,0 +1,23 @@
+//build:20240606
+//鐢ㄤ簬绠�鍖杅ace缁勪欢寰厜閫氫俊鍗忚鐨勪娇鐢紝鎶奻ace灏佽鍦ㄨ繖涓獁orker閲岋紝浣跨敤鑰呭彧闇�瑕佽闃卐ventbus鐨勪簨浠跺氨鍙互鐩戝惉face
+import log from './dxLogger.js'
+import face from './dxFace.js'
+import std from './dxStd.js'
+
+function run() {
+ face.worker.beforeLoop()
+ log.info('face start......')
+ std.setInterval (function() {
+ try {
+ face.worker.loop()
+ } catch (error) {
+ log.error(error)
+ }
+ },10)
+}
+
+try {
+ run()
+} catch (error) {
+ log.error(error)
+}
\ No newline at end of file
diff --git a/vf205_access/dxmodules/gpioKeyWorker.js b/vf205_access/dxmodules/gpioKeyWorker.js
new file mode 100644
index 0000000..8590a4e
--- /dev/null
+++ b/vf205_access/dxmodules/gpioKeyWorker.js
@@ -0,0 +1,23 @@
+//build:20240524
+//鐢ㄤ簬绠�鍖杇pioKey缁勪欢寰厜閫氫俊鍗忚鐨勪娇鐢紝鎶奼pioKey灏佽鍦ㄨ繖涓獁orker閲岋紝浣跨敤鑰呭彧闇�瑕佽闃卐ventbus鐨勪簨浠跺氨鍙互鐩戝惉gpioKey
+import log from './dxLogger.js'
+import gpioKey from './dxGpioKey.js'
+import * as os from "os";
+import std from './dxStd.js'
+function run() {
+ gpioKey.worker.beforeLoop()
+ log.info('gpioKey start......')
+ std.setInterval(() => {
+ try {
+ gpioKey.worker.loop()
+ } catch (error) {
+ log.error(error)
+ }
+ },10)
+}
+
+try {
+ run()
+} catch (error) {
+ log.error(error)
+}
\ No newline at end of file
diff --git a/vf205_access/dxmodules/libJLReader.so b/vf205_access/dxmodules/libJLReader.so
new file mode 100644
index 0000000..4a7005b
--- /dev/null
+++ b/vf205_access/dxmodules/libJLReader.so
Binary files differ
diff --git a/vf205_access/dxmodules/libalc.so b/vf205_access/dxmodules/libalc.so
new file mode 100644
index 0000000..262f603
--- /dev/null
+++ b/vf205_access/dxmodules/libalc.so
Binary files differ
diff --git a/vf205_access/dxmodules/libid_jpg.so b/vf205_access/dxmodules/libid_jpg.so
new file mode 100644
index 0000000..65fbe33
--- /dev/null
+++ b/vf205_access/dxmodules/libid_jpg.so
Binary files differ
diff --git a/vf205_access/dxmodules/libid_jpg_codec.so b/vf205_access/dxmodules/libid_jpg_codec.so
new file mode 100644
index 0000000..7925e2a
--- /dev/null
+++ b/vf205_access/dxmodules/libid_jpg_codec.so
Binary files differ
diff --git a/vf205_access/dxmodules/libie_jpg.so b/vf205_access/dxmodules/libie_jpg.so
new file mode 100644
index 0000000..5eb005d
--- /dev/null
+++ b/vf205_access/dxmodules/libie_jpg.so
Binary files differ
diff --git a/vf205_access/dxmodules/libie_jpg_codec.so b/vf205_access/dxmodules/libie_jpg_codec.so
new file mode 100644
index 0000000..1b29084
--- /dev/null
+++ b/vf205_access/dxmodules/libie_jpg_codec.so
Binary files differ
diff --git a/vf205_access/dxmodules/liblombo_jpeg.so b/vf205_access/dxmodules/liblombo_jpeg.so
new file mode 100644
index 0000000..ab37215
--- /dev/null
+++ b/vf205_access/dxmodules/liblombo_jpeg.so
Binary files differ
diff --git a/vf205_access/dxmodules/libvbar-b-dxface.so b/vf205_access/dxmodules/libvbar-b-dxface.so
new file mode 100644
index 0000000..5c54f77
--- /dev/null
+++ b/vf205_access/dxmodules/libvbar-b-dxface.so
Binary files differ
diff --git a/vf205_access/dxmodules/libvbar-b-dxgpio.so b/vf205_access/dxmodules/libvbar-b-dxgpio.so
new file mode 100644
index 0000000..fd44d48
--- /dev/null
+++ b/vf205_access/dxmodules/libvbar-b-dxgpio.so
Binary files differ
diff --git a/vf205_access/dxmodules/libvbar-b-dxpwm.so b/vf205_access/dxmodules/libvbar-b-dxpwm.so
new file mode 100644
index 0000000..16b5dc0
--- /dev/null
+++ b/vf205_access/dxmodules/libvbar-b-dxpwm.so
Binary files differ
diff --git a/vf205_access/dxmodules/libvbar-b-dxwatchdog.so b/vf205_access/dxmodules/libvbar-b-dxwatchdog.so
new file mode 100644
index 0000000..9aac1d5
--- /dev/null
+++ b/vf205_access/dxmodules/libvbar-b-dxwatchdog.so
Binary files differ
diff --git a/vf205_access/dxmodules/libvbar-drv-audio_gain.so b/vf205_access/dxmodules/libvbar-drv-audio_gain.so
new file mode 100644
index 0000000..21237bf
--- /dev/null
+++ b/vf205_access/dxmodules/libvbar-drv-audio_gain.so
Binary files differ
diff --git a/vf205_access/dxmodules/libvbar-drv-capturer.so b/vf205_access/dxmodules/libvbar-drv-capturer.so
new file mode 100644
index 0000000..e15739d
--- /dev/null
+++ b/vf205_access/dxmodules/libvbar-drv-capturer.so
Binary files differ
diff --git a/vf205_access/dxmodules/libvbar-drv-capturer_calibration.so b/vf205_access/dxmodules/libvbar-drv-capturer_calibration.so
new file mode 100644
index 0000000..3b9d040
--- /dev/null
+++ b/vf205_access/dxmodules/libvbar-drv-capturer_calibration.so
Binary files differ
diff --git a/vf205_access/dxmodules/libvbar-drv-display.so b/vf205_access/dxmodules/libvbar-drv-display.so
new file mode 100644
index 0000000..e2a01dd
--- /dev/null
+++ b/vf205_access/dxmodules/libvbar-drv-display.so
Binary files differ
diff --git a/vf205_access/dxmodules/libvbar-drv-face.so b/vf205_access/dxmodules/libvbar-drv-face.so
new file mode 100644
index 0000000..203c6ce
--- /dev/null
+++ b/vf205_access/dxmodules/libvbar-drv-face.so
Binary files differ
diff --git a/vf205_access/dxmodules/libvbar-drv-gpio.so b/vf205_access/dxmodules/libvbar-drv-gpio.so
new file mode 100644
index 0000000..ef802b0
--- /dev/null
+++ b/vf205_access/dxmodules/libvbar-drv-gpio.so
Binary files differ
diff --git a/vf205_access/dxmodules/libvbar-drv-memory.so b/vf205_access/dxmodules/libvbar-drv-memory.so
new file mode 100644
index 0000000..338b6f6
--- /dev/null
+++ b/vf205_access/dxmodules/libvbar-drv-memory.so
Binary files differ
diff --git a/vf205_access/dxmodules/libvbar-drv-pwm.so b/vf205_access/dxmodules/libvbar-drv-pwm.so
new file mode 100644
index 0000000..9355d70
--- /dev/null
+++ b/vf205_access/dxmodules/libvbar-drv-pwm.so
Binary files differ
diff --git a/vf205_access/dxmodules/libvbar-drv-soc.so b/vf205_access/dxmodules/libvbar-drv-soc.so
new file mode 100644
index 0000000..62887bb
--- /dev/null
+++ b/vf205_access/dxmodules/libvbar-drv-soc.so
Binary files differ
diff --git a/vf205_access/dxmodules/libvbar-drv-tts.so b/vf205_access/dxmodules/libvbar-drv-tts.so
new file mode 100644
index 0000000..14480c3
--- /dev/null
+++ b/vf205_access/dxmodules/libvbar-drv-tts.so
Binary files differ
diff --git a/vf205_access/dxmodules/libvbar-drv-watchdog.so b/vf205_access/dxmodules/libvbar-drv-watchdog.so
new file mode 100644
index 0000000..34bce9a
--- /dev/null
+++ b/vf205_access/dxmodules/libvbar-drv-watchdog.so
Binary files differ
diff --git a/vf205_access/dxmodules/libvbar-m-alsa.so b/vf205_access/dxmodules/libvbar-m-alsa.so
new file mode 100644
index 0000000..44a6231
--- /dev/null
+++ b/vf205_access/dxmodules/libvbar-m-alsa.so
Binary files differ
diff --git a/vf205_access/dxmodules/libvbar-m-capturer.so b/vf205_access/dxmodules/libvbar-m-capturer.so
new file mode 100644
index 0000000..512f3b8
--- /dev/null
+++ b/vf205_access/dxmodules/libvbar-m-capturer.so
Binary files differ
diff --git a/vf205_access/dxmodules/libvbar-m-channel.so b/vf205_access/dxmodules/libvbar-m-channel.so
new file mode 100644
index 0000000..8d7c7c6
--- /dev/null
+++ b/vf205_access/dxmodules/libvbar-m-channel.so
Binary files differ
diff --git a/vf205_access/dxmodules/libvbar-m-common.so b/vf205_access/dxmodules/libvbar-m-common.so
new file mode 100644
index 0000000..a70db84
--- /dev/null
+++ b/vf205_access/dxmodules/libvbar-m-common.so
Binary files differ
diff --git a/vf205_access/dxmodules/libvbar-m-dxalsa.so b/vf205_access/dxmodules/libvbar-m-dxalsa.so
new file mode 100644
index 0000000..17f78fc
--- /dev/null
+++ b/vf205_access/dxmodules/libvbar-m-dxalsa.so
Binary files differ
diff --git a/vf205_access/dxmodules/libvbar-m-dxcapturer.so b/vf205_access/dxmodules/libvbar-m-dxcapturer.so
new file mode 100644
index 0000000..e63f0a9
--- /dev/null
+++ b/vf205_access/dxmodules/libvbar-m-dxcapturer.so
Binary files differ
diff --git a/vf205_access/dxmodules/libvbar-m-dxcapturer_calibration.so b/vf205_access/dxmodules/libvbar-m-dxcapturer_calibration.so
new file mode 100644
index 0000000..3dacb09
--- /dev/null
+++ b/vf205_access/dxmodules/libvbar-m-dxcapturer_calibration.so
Binary files differ
diff --git a/vf205_access/dxmodules/libvbar-m-dxchannel.so b/vf205_access/dxmodules/libvbar-m-dxchannel.so
new file mode 100644
index 0000000..55987ca
--- /dev/null
+++ b/vf205_access/dxmodules/libvbar-m-dxchannel.so
Binary files differ
diff --git a/vf205_access/dxmodules/libvbar-m-dxcommon.so b/vf205_access/dxmodules/libvbar-m-dxcommon.so
new file mode 100644
index 0000000..4c9f580
--- /dev/null
+++ b/vf205_access/dxmodules/libvbar-m-dxcommon.so
Binary files differ
diff --git a/vf205_access/dxmodules/libvbar-m-dxeid.so b/vf205_access/dxmodules/libvbar-m-dxeid.so
new file mode 100644
index 0000000..0ec5c15
--- /dev/null
+++ b/vf205_access/dxmodules/libvbar-m-dxeid.so
Binary files differ
diff --git a/vf205_access/dxmodules/libvbar-m-dxhttp.so b/vf205_access/dxmodules/libvbar-m-dxhttp.so
new file mode 100644
index 0000000..a654c8f
--- /dev/null
+++ b/vf205_access/dxmodules/libvbar-m-dxhttp.so
Binary files differ
diff --git a/vf205_access/dxmodules/libvbar-m-dxkey.so b/vf205_access/dxmodules/libvbar-m-dxkey.so
new file mode 100644
index 0000000..4dda42a
--- /dev/null
+++ b/vf205_access/dxmodules/libvbar-m-dxkey.so
Binary files differ
diff --git a/vf205_access/dxmodules/libvbar-m-dxmap.so b/vf205_access/dxmodules/libvbar-m-dxmap.so
new file mode 100644
index 0000000..66e69da
--- /dev/null
+++ b/vf205_access/dxmodules/libvbar-m-dxmap.so
Binary files differ
diff --git a/vf205_access/dxmodules/libvbar-m-dxmqtt.so b/vf205_access/dxmodules/libvbar-m-dxmqtt.so
new file mode 100644
index 0000000..50d60bd
--- /dev/null
+++ b/vf205_access/dxmodules/libvbar-m-dxmqtt.so
Binary files differ
diff --git a/vf205_access/dxmodules/libvbar-m-dxnet.so b/vf205_access/dxmodules/libvbar-m-dxnet.so
new file mode 100644
index 0000000..9971437
--- /dev/null
+++ b/vf205_access/dxmodules/libvbar-m-dxnet.so
Binary files differ
diff --git a/vf205_access/dxmodules/libvbar-m-dxsqlite.so b/vf205_access/dxmodules/libvbar-m-dxsqlite.so
new file mode 100644
index 0000000..95f8f56
--- /dev/null
+++ b/vf205_access/dxmodules/libvbar-m-dxsqlite.so
Binary files differ
diff --git a/vf205_access/dxmodules/libvbar-m-dxui.so b/vf205_access/dxmodules/libvbar-m-dxui.so
new file mode 100644
index 0000000..c2cd72b
--- /dev/null
+++ b/vf205_access/dxmodules/libvbar-m-dxui.so
Binary files differ
diff --git a/vf205_access/dxmodules/libvbar-m-eid.so b/vf205_access/dxmodules/libvbar-m-eid.so
new file mode 100644
index 0000000..c53fbcd
--- /dev/null
+++ b/vf205_access/dxmodules/libvbar-m-eid.so
Binary files differ
diff --git a/vf205_access/dxmodules/libvbar-m-key.so b/vf205_access/dxmodules/libvbar-m-key.so
new file mode 100644
index 0000000..db06fca
--- /dev/null
+++ b/vf205_access/dxmodules/libvbar-m-key.so
Binary files differ
diff --git a/vf205_access/dxmodules/libvbar-m-net.so b/vf205_access/dxmodules/libvbar-m-net.so
new file mode 100644
index 0000000..3e01601
--- /dev/null
+++ b/vf205_access/dxmodules/libvbar-m-net.so
Binary files differ
diff --git a/vf205_access/dxmodules/libvbar-m-vgmqtt.so b/vf205_access/dxmodules/libvbar-m-vgmqtt.so
new file mode 100644
index 0000000..ea8ae21
--- /dev/null
+++ b/vf205_access/dxmodules/libvbar-m-vgmqtt.so
Binary files differ
diff --git a/vf205_access/dxmodules/libvbar-p-dxnfc.so b/vf205_access/dxmodules/libvbar-p-dxnfc.so
new file mode 100644
index 0000000..f3561a4
--- /dev/null
+++ b/vf205_access/dxmodules/libvbar-p-dxnfc.so
Binary files differ
diff --git a/vf205_access/dxmodules/libvbar-p-nfc.so b/vf205_access/dxmodules/libvbar-p-nfc.so
new file mode 100644
index 0000000..d341cdf
--- /dev/null
+++ b/vf205_access/dxmodules/libvbar-p-nfc.so
Binary files differ
diff --git a/vf205_access/dxmodules/libvccore.so b/vf205_access/dxmodules/libvccore.so
new file mode 100644
index 0000000..3b40d88
--- /dev/null
+++ b/vf205_access/dxmodules/libvccore.so
Binary files differ
diff --git a/vf205_access/dxmodules/libyuv.so b/vf205_access/dxmodules/libyuv.so
new file mode 100644
index 0000000..1ed6931
--- /dev/null
+++ b/vf205_access/dxmodules/libyuv.so
Binary files differ
diff --git a/vf205_access/dxmodules/mqttWorker.js b/vf205_access/dxmodules/mqttWorker.js
new file mode 100644
index 0000000..bf2083d
--- /dev/null
+++ b/vf205_access/dxmodules/mqttWorker.js
@@ -0,0 +1,64 @@
+//build:20240524
+//鐢ㄤ簬绠�鍖杕qtt缁勪欢寰厜閫氫俊鍗忚鐨勪娇鐢紝鎶妋qtt灏佽鍦ㄨ繖涓獁orker閲岋紝浣跨敤鑰呭彧闇�瑕佽闃卐ventcenter鐨勪簨浠跺氨鍙互鐩戝惉mqtt
+import log from './dxLogger.js'
+import net from './dxNet.js'
+import mqtt from './dxMqtt.js'
+import dxMap from './dxMap.js'
+import std from './dxStd.js'
+import * as os from "os";
+const map = dxMap.get('default')
+const id = "{{id}}"
+const options = map.get("__mqtt__run_init" + id)
+let connected = false
+function run() {
+ mqtt.init(options.mqttAddr, options.clientId, options.username, options.password, options.prefix, options.qos, options.willTopic, options.willMessage, options.id)
+ log.info('mqtt start......,id =', id)
+ os.sleep(2000)//绛夊緟2绉�
+
+ __bus.on(mqtt.RECONNECT, (options) => {
+ mqtt.destroy(options.id)
+ mqtt.init(options.mqttAddr, options.clientId, options.username, options.password, options.prefix, options.qos, options.willTopic, options.willMessage, options.id)
+ })
+
+ std.setInterval(() => {
+ try {
+ if (mqtt.isConnected(options.id) && net.getStatus().connected) {
+ if (!connected) {
+ _fireChange(true)
+ if (options.subs) {
+ mqtt.subscribes(options.subs, options.qos, options.id)
+ }
+ }
+ } else {
+ if (connected) {
+ _fireChange(false)
+ }
+ // 閲嶈繛
+ mqtt.reconnect(options.willTopic, options.willMessage, options.id)
+ os.sleep(2000)//閲嶈繛鍚庣瓑寰�2绉�
+ }
+ } catch (error) {
+ log.error(error)
+ }
+ }, 3000)
+ std.setInterval(() => {
+ // 杩炴帴鎴愬姛鍚庤繘鍏ユ秷鎭洃鍚�
+ if (connected) {
+ if (!mqtt.msgIsEmpty(options.id)) {
+ let msg = mqtt.receive(options.id)
+ __bus.fire(mqtt.RECEIVE_MSG + options.id, msg)//bus.newworker鐨勬椂鍊欎細import eventbus as __bus
+ }
+ }
+ }, 10);
+}
+
+try {
+ run()
+} catch (error) {
+ log.error(error)
+}
+
+function _fireChange(status) {
+ __bus.fire(mqtt.CONNECTED_CHANGED + options.id, status ? 'connected' : 'disconnected')//bus.newworker鐨勬椂鍊欎細import eventbus as __bus
+ connected = status
+}
diff --git a/vf205_access/dxmodules/netWorker.js b/vf205_access/dxmodules/netWorker.js
new file mode 100644
index 0000000..8b77c79
--- /dev/null
+++ b/vf205_access/dxmodules/netWorker.js
@@ -0,0 +1,25 @@
+//build:20240525
+//鐢ㄤ簬绠�鍖杗et缁勪欢寰厜閫氫俊鍗忚鐨勪娇鐢紝鎶妌et灏佽鍦ㄨ繖涓獁orker閲岋紝浣跨敤鑰呭彧闇�瑕佽闃卐ventcenter鐨勪簨浠跺氨鍙互鐩戝惉net
+import log from './dxLogger.js'
+import net from './dxNet.js'
+import dxMap from './dxMap.js'
+import std from './dxStd.js'
+const map = dxMap.get('default')
+const options = map.get("__net__run_init")
+
+function run() {
+ net.worker.beforeLoop(options)
+ log.info('net worker start......')
+ std.setInterval (function() {
+ try {
+ net.worker.loop()
+ } catch (error) {
+ log.error(error)
+ }
+ },100)
+}
+try {
+ run()
+} catch (error) {
+ log.error(error)
+}
diff --git a/vf205_access/dxmodules/nfcWorker.js b/vf205_access/dxmodules/nfcWorker.js
new file mode 100644
index 0000000..c824cac
--- /dev/null
+++ b/vf205_access/dxmodules/nfcWorker.js
@@ -0,0 +1,27 @@
+//build:20240524
+//鐢ㄤ簬绠�鍖杗fc缁勪欢寰厜閫氫俊鍗忚鐨勪娇鐢紝鎶妌fc灏佽鍦ㄨ繖涓獁orker閲岋紝浣跨敤鑰呭彧闇�瑕佽闃卐ventcenter鐨勪簨浠跺氨鍙互鐩戝惉nfc
+import log from './dxLogger.js'
+import nfc from './dxNfc.js'
+import dxMap from './dxMap.js'
+import std from './dxStd.js'
+import * as os from "os";
+const map = dxMap.get('default')
+const options = map.get("__nfc__run_init")
+
+function run() {
+ nfc.worker.beforeLoop(options)
+ log.info('nfc start......')
+ std.setInterval(() => {
+ try {
+ nfc.worker.loop(options)
+ } catch (error) {
+ log.error(error)
+ }
+ }, 10)
+}
+
+try {
+ run()
+} catch (error) {
+ log.error(error)
+}
\ No newline at end of file
diff --git a/vf205_access/dxmodules/uiBase.js b/vf205_access/dxmodules/uiBase.js
new file mode 100644
index 0000000..4b2514c
--- /dev/null
+++ b/vf205_access/dxmodules/uiBase.js
@@ -0,0 +1,582 @@
+//build:20240524
+/**
+ * UI鐨勫熀绫伙紝鍏跺畠鎺т欢閮戒細缁ф壙锛屽瓙绫讳笉鍏佽淇敼瀵瑰簲鐨勫嚱鏁拌涓�,杩欎釜js涓嶉渶瑕佺洿鎺ュ紩鐢ㄥ拰浣跨敤
+ */
+import utils from "./uiUtils.js"
+import logger from './dxLogger.js'
+import * as os from "os"
+const uibase = {}
+/**
+* 淇敼鎴栬幏鍙栨帶浠剁殑瀹藉害
+* @param {number} w 闈炲繀濉紝濡傛灉涓嶅~鏄幏鍙栧搴︼紝鍚﹀垯灏辨槸淇敼瀹藉害
+*/
+uibase.width = function (w) {
+ if (!utils.validateNumber(w)) {
+ return this.obj.getWidth()
+ }
+ this.obj.lvObjSetWidth(w)
+}
+/**
+* 淇敼鎴栬幏鍙栨帶浠剁殑楂樺害
+* @param {number} h 闈炲繀濉紝濡傛灉涓嶅~灏辨槸鑾峰彇楂樺害锛屽惁鍒欏氨鏄慨鏀归珮搴�
+*/
+uibase.height = function (h) {
+ if (!utils.validateNumber(h)) {
+ return this.obj.getHeight()
+ }
+ this.obj.lvObjSetHeight(h)
+}
+/**
+ * 鑾峰彇鍘婚櫎杈规銆佸唴杈硅窛鐨勫搴�
+ * @returns
+ */
+uibase.contentWidth = function () {
+ return this.obj.lvObjGetContentWidth()
+}
+/**
+ * 鑾峰彇鍘婚櫎杈规銆佸唴杈硅窛鐨勯珮搴�
+ * @returns
+ */
+uibase.contentHeight = function () {
+ return this.obj.lvObjGetContentHeight()
+}
+/**
+ * 鑾峰彇涓婃柟婊氬姩璺濈
+ * @returns
+ */
+uibase.scrollTop = function () {
+ return this.obj.getScrollTop()
+}
+/**
+ * 鑾峰彇涓嬫柟婊氬姩璺濈
+ * @returns
+ */
+uibase.scrollBottom = function () {
+ return this.obj.getScrollBottom()
+}
+/**
+ * 鑾峰彇宸︽柟婊氬姩璺濈
+ * @returns
+ */
+uibase.scrollLeft = function () {
+ return this.obj.getScrollLeft()
+}
+/**
+ * 鑾峰彇鍙虫柟婊氬姩璺濈
+ * @returns
+ */
+uibase.scrollRight = function () {
+ return this.obj.getScrollRight()
+}
+/**
+* 淇敼鎺т欢鐨勫搴﹀拰楂樺害
+* @param {number} w 蹇呭~
+* @param {number} h 蹇呭~
+*/
+uibase.setSize = function (w, h) {
+ let err = 'dxui.setSize: width or height should not be empty'
+ utils.validateNumber(w, err)
+ utils.validateNumber(h, err)
+ this.obj.lvObjSetSize(w, h)
+}
+/**
+* 淇敼鎴栬幏鍙栨帶浠剁浉褰撲簬鐖跺璞$殑x鍧愭爣
+* @param {number} x 闈炲繀濉紝濡傛灉涓嶅~灏辨槸鑾峰彇x鍧愭爣锛屽惁鍒欏氨鏄慨鏀箈鍧愭爣
+*/
+uibase.x = function (x) {
+ if (!utils.validateNumber(x)) {
+ return this.obj.getX()
+ }
+ this.obj.lvObjSetX(x)
+}
+/**
+* 淇敼鎴栬幏鍙栨帶浠剁浉褰撲簬鐖跺璞$殑x鍧愭爣
+* @param {number} y 闈炲繀濉紝濡傛灉涓嶅~灏辨槸鑾峰彇y鍧愭爣锛屽惁鍒欏氨鏄慨鏀箉鍧愭爣
+*/
+uibase.y = function (y) {
+ if (!utils.validateNumber(y)) {
+ return this.obj.getY()
+ }
+ this.obj.lvObjSetY(y)
+}
+/**
+* 淇敼鎺т欢鐩稿鐖跺璞$殑x鍜寉鍧愭爣
+* @param {number} x 蹇呭~
+* @param {number} y 蹇呭~
+*/
+uibase.setPos = function (x, y) {
+ let err = 'dxui.setPos: x or y should not be empty'
+ utils.validateNumber(x, err)
+ utils.validateNumber(y, err)
+ this.obj.lvObjSetPos(x, y)
+}
+/**
+ * 鎶婃帶浠剁Щ鍔ㄥ埌鏈�涓婂眰锛岀浉褰撲簬鐖跺璞℃渶鍚庝竴涓垱寤虹殑瀛愭帶浠讹紝浼氳鐩栧叾瀹冩墍鏈夊瓙鎺т欢
+ */
+uibase.moveForeground = function () {
+ this.obj.moveForeground()
+}
+/**
+ * 鎶婃帶浠剁Щ鍔ㄥ埌鏈�搴曞眰锛岀浉褰撲簬鐖跺璞$涓�涓垱寤虹殑瀛愭帶浠讹紝浼氳鍏跺畠鎵�鏈夊瓙鎺т欢瑕嗙洊
+ */
+uibase.moveBackground = function () {
+ this.obj.moveBackground()
+}
+/**
+ * 璁㈤槄浜嬩欢锛屾敮鎸佺殑浜嬩欢绫诲瀷鍙傝�僽tils.EVENT
+ * @param {number} type 鏋氫妇utils.EVENT,姣斿鐐瑰嚮銆侀暱鎸夌瓑
+ * @param {function} cb 浜嬩欢瑙﹀彂鐨勫洖璋冨嚱鏁帮紙涓嶈兘鏄尶鍚嶅嚱鏁帮級
+ * @param {object} ud 鐢ㄦ埛鏁版嵁
+ */
+uibase.on = function (type, cb, ud) {
+ this.obj.addEventCb(() => {
+ if (cb) {
+ cb({ target: this, ud: ud })
+ }
+ }, type)
+}
+/**
+ * 鍙戦�佷簨浠讹紝姣斿妯℃嫙鐐瑰嚮鎸夐挳锛屽彲浠ョ粰鎸夐挳鍙戦�丆LICK浜嬩欢
+ * @param {number} type 鏋氫妇utils.EVENT,姣斿鐐瑰嚮銆侀暱鎸夌瓑
+ */
+uibase.send = function (type) {
+ NativeObject.APP.NativeComponents.NativeEvent.lvEventSend(this.obj, type)
+}
+/**
+ * 闅愯棌ui瀵硅薄
+ */
+uibase.hide = function () {
+ if (!this.obj.hasFlag(1)) {
+ this.obj.lvObjAddFlag(1);
+ }
+}
+/**
+ * 鍒ゆ柇鏄惁闅愯棌
+ * @returns
+ */
+uibase.isHide = function () {
+ return this.obj.hasFlag(1);
+}
+/**
+ * 鏄剧ず宸茬粡闅愯棌鐨剈i瀵硅薄
+ */
+uibase.show = function () {
+ if (this.obj.hasFlag(1)) {
+ this.obj.lvObjClearFlag(1);
+ }
+}
+/**
+ * 绂佸惎鐢ㄥ璞�
+ * @param {*} en false/true锛宼rue鏄鐢紝false鏄惎鐢�
+ */
+uibase.disable = function (en) {
+ if (en) {
+ this.obj.addState(utils.STATE.DISABLED)
+ } else {
+ this.obj.clearState(utils.STATE.DISABLED)
+ }
+}
+/**
+ * 鏄惁鍙偣鍑诲璞�
+ * @param {*} en false/true锛宼rue鏄彲鐐瑰嚮锛宖alse鏄笉鍙偣鍑�
+ */
+uibase.clickable = function (en) {
+ if (en) {
+ this.obj.lvObjAddFlag(utils.OBJ_FLAG.CLICKABLE)
+ } else {
+ this.obj.lvObjClearFlag(utils.OBJ_FLAG.CLICKABLE)
+ }
+}
+/**
+ * 鍒ゆ柇鏄惁绂佸惎鐢�
+ * @returns true鏄凡绂佺敤锛宖alse鏄凡鍚敤
+ */
+uibase.isDisable = function () {
+ return this.obj.hasState(utils.STATE.DISABLED)
+}
+/**
+ * 鑱氱劍瀵硅薄
+ * @param {*} en false/true锛宼rue鏄仛鐒︼紝false鏄彇娑堣仛鐒�
+ */
+uibase.focus = function (en) {
+ if (en) {
+ this.obj.addState(utils.STATE.FOCUSED)
+ } else {
+ this.obj.clearState(utils.STATE.FOCUSED)
+ }
+}
+/**
+ * 鍒ゆ柇鏄惁鑱氱劍
+ * @returns true鏄凡鑱氱劍锛宖alse鏄病鑱氱劍
+ */
+uibase.isFocus = function () {
+ return this.obj.hasState(utils.STATE.FOCUSED)
+}
+
+/**
+ * 璁剧疆ui鐨勬牱寮忥紝鍙互閫氳繃涓�涓釜鏍峰紡鍗曠嫭璁剧疆锛屼篃鍙互鍏堝畾涔夋牱寮忓璞★紝鐒跺悗鍜寀i瀵硅薄缁戝畾
+ * 缁檜i瀵硅薄鍜屾牱寮忓璞$粦瀹氾紝鍙互缁戝畾鍒颁笉鍚岀殑閮ㄥ垎鎴栦笉鍚岀殑鐘舵��
+ * @param {object} style style.js build鍑芥暟杩斿洖鐨勫璞�
+ * @param {number} type 鍙傝�僽tils.STYLE 闈炲繀濉紝缂虹渷鏄拰瀵硅薄鑷韩缁戝畾
+ */
+uibase.addStyle = function (style, type) {
+ if (!style || !style.obj) {
+ throw new Error('dxui.addStyle: style should not be null')
+ }
+ if (!utils.validateNumber(type)) {
+ type = 0
+ }
+ this.obj.lvObjAddStyle(style.obj, type);
+}
+/**
+* 璁剧疆宸﹀彸涓婁笅鐨勫唴杈硅窛閮戒负涓�涓��
+* @param {number} pad 杈硅窛鍊�
+* @param {number} type 鍙傝�僽tils.STYLE 闈炲繀濉紝缂虹渷鏄拰瀵硅薄鑷韩缁戝畾
+*/
+uibase.padAll = function (pad, type) {
+ if (!utils.validateNumber(type)) {
+ type = 0
+ }
+ this.obj.lvObjSetStylePadAll(pad, type)
+}
+/**
+ * 璁剧疆/鑾峰彇鍙冲唴杈硅窛閮戒负涓�涓��
+ * @param {number} pad 杈硅窛鍊�
+ * @param {number} type 鍙傝�僽tils.STYLE 闈炲繀濉紝缂虹渷鏄拰瀵硅薄鑷韩缁戝畾
+ */
+uibase.padRight = function (pad, type) {
+ if (!utils.validateNumber(type)) {
+ type = 0
+ }
+ if (!utils.validateNumber(pad)) {
+ return this.obj.getStylePadRight(type)
+ }
+ this.obj.setStylePadRight(pad, type)
+}
+/**
+ * 璁剧疆/鑾峰彇宸﹀唴杈硅窛閮戒负涓�涓��
+ * @param {number} pad 杈硅窛鍊�
+ * @param {number} type 鍙傝�僽tils.STYLE 闈炲繀濉紝缂虹渷鏄拰瀵硅薄鑷韩缁戝畾
+ */
+uibase.padLeft = function (pad, type) {
+ if (!utils.validateNumber(type)) {
+ type = 0
+ }
+ if (!utils.validateNumber(pad)) {
+ return this.obj.getStylePadLeft(type)
+ }
+ this.obj.setStylePadLeft(pad, type)
+}
+/**
+ * 璁剧疆/鑾峰彇涓婂唴杈硅窛閮戒负涓�涓��
+ * @param {number} pad 杈硅窛鍊�
+ * @param {number} type 鍙傝�僽tils.STYLE 闈炲繀濉紝缂虹渷鏄拰瀵硅薄鑷韩缁戝畾
+ */
+uibase.padTop = function (pad, type) {
+ if (!utils.validateNumber(type)) {
+ type = 0
+ }
+ if (!utils.validateNumber(pad)) {
+ return this.obj.getStylePadTop(type)
+ }
+ this.obj.setStylePadTop(pad, type)
+}
+/**
+ * 璁剧疆/鑾峰彇涓嬪唴杈硅窛閮戒负涓�涓��
+ * @param {number} pad 杈硅窛鍊�
+ * @param {number} type 鍙傝�僽tils.STYLE 闈炲繀濉紝缂虹渷鏄拰瀵硅薄鑷韩缁戝畾
+ */
+uibase.padBottom = function (pad, type) {
+ if (!utils.validateNumber(type)) {
+ type = 0
+ }
+ if (!utils.validateNumber(pad)) {
+ return this.obj.getStylePadBottom(type)
+ }
+ this.obj.setStylePadBottom(pad, type)
+}
+/**
+ * 璁剧疆/鑾峰彇杈规瀹藉害
+ * @param {number} w
+ * @param {number} type 鍙傝�僽tils.STYLE 闈炲繀濉紝缂虹渷鏄拰瀵硅薄鑷韩缁戝畾
+ */
+uibase.borderWidth = function (w, type) {
+ if (!utils.validateNumber(type)) {
+ type = 0
+ }
+ if (!utils.validateNumber(w)) {
+ return this.obj.lvObjGetStyleBorderWidth(type)
+ }
+ this.obj.lvObjSetStyleBorderWidth(w, type)
+}
+/**
+ * 璁剧疆杈规棰滆壊
+ * @param {number} color 鏀寔鏁板瓧绫诲瀷锛氭瘮濡�0x34ffaa锛涘瓧绗︿覆绫诲瀷(#寮�澶�),姣斿:'#34ffaa'
+ * @param {number} type 鍙傝�僽tils.STYLE 闈炲繀濉紝缂虹渷鏄拰瀵硅薄鑷韩缁戝畾
+ */
+uibase.setBorderColor = function (color, type) {
+ if (!utils.validateNumber(type)) {
+ type = 0
+ }
+ this.obj.setStyleBorderColor(utils.colorParse(color), type)
+}
+/**
+ * 璁剧疆杈瑰渾瑙�
+ * @param {number} r
+ * @param {number} type 鍙傝�僽tils.STYLE 闈炲繀濉紝缂虹渷鏄拰瀵硅薄鑷韩缁戝畾
+ */
+uibase.radius = function (r, type) {
+ if (!utils.validateNumber(type)) {
+ type = 0
+ }
+ this.obj.lvObjSetStyleRadius(r, type)
+}
+/**
+ * 璁剧疆鑳屾櫙閫忔槑搴︼紝鍊艰寖鍥存槸0-100锛屽�艰秺灏忚秺濂�
+ * @param {number} opa 蹇呴』鏄�0-100
+ * @param {number} type 鍙傝�僽tils.STYLE 闈炲繀濉紝缂虹渷鏄拰瀵硅薄鑷韩缁戝畾
+ */
+uibase.bgOpa = function (opa, type) {
+ if (!utils.validateNumber(type)) {
+ type = 0
+ }
+ this.obj.lvObjSetStyleBgOpa(utils.OPA_MAPPING(opa), type)
+}
+/**
+ * 璁剧疆鑳屾櫙棰滆壊
+ * @param {any} color 鏀寔鏁板瓧绫诲瀷锛氭瘮濡�0x34ffaa锛涘瓧绗︿覆绫诲瀷(#寮�澶�),姣斿:'#34ffaa'
+ * @param {number} type 鍙傝�僽tils.STYLE 闈炲繀濉紝缂虹渷鏄拰瀵硅薄鑷韩缁戝畾
+ */
+uibase.bgColor = function (color, type) {
+ if (!utils.validateNumber(type)) {
+ type = 0
+ }
+ this.obj.lvObjSetStyleBgColor(utils.colorParse(color), type)
+}
+/**
+ * 璁剧疆闃村奖
+ * @param {number} width 闃村奖瀹藉害
+ * @param {number} x 姘村钩鍋忕Щ
+ * @param {number} y 鍨傜洿鍋忕Щ
+ * @param {number} spread 鎵╂暎璺濈
+ * @param {number} color 棰滆壊
+ * @param {number} opa 閫忔槑搴︼紝蹇呴』鏄�0-100
+ * @param {number} type 鍙傝�僽tils.STYLE 闈炲繀濉紝缂虹渷鏄拰瀵硅薄鑷韩缁戝畾
+ */
+uibase.shadow = function (width, x, y, spread, color, opa, type) {
+ if (!utils.validateNumber(type)) {
+ type = 0
+ }
+ this.obj.lvObjSetStyleShadowWidth(width, type)
+ this.obj.lvObjSetStyleShadowOfsX(x, type)
+ this.obj.lvObjSetStyleShadowOfsY(y, type)
+ this.obj.lvObjSetStyleShadowSpread(spread, type)
+ this.obj.setStyleShadowColor(color, type)
+ this.obj.setStyleShadowOpa(utils.OPA_MAPPING(opa), type)
+}
+/**
+ * 璁剧疆鏂囨湰棰滆壊
+ * @param {any} color 鏀寔鏁板瓧绫诲瀷锛氭瘮濡�0x34ffaa锛涘瓧绗︿覆绫诲瀷(#寮�澶�),姣斿:'#34ffaa'
+ * @param {number} type 鍙傝�僽tils.STYLE 闈炲繀濉紝缂虹渷鏄拰瀵硅薄鑷韩缁戝畾
+ */
+uibase.textColor = function (color, type) {
+ if (!utils.validateNumber(type)) {
+ type = 0
+ }
+ this.obj.lvObjSetStyleTextColor(utils.colorParse(color), type)
+}
+/**
+ * 璁剧疆鏂囨湰瀵归綈鏂瑰紡
+ * @param {number} align 鍙傝�僽tils.TEXT_ALIGN
+ * @param {number} type 鍙傝�僽tils.STYLE 闈炲繀濉紝缂虹渷鏄拰瀵硅薄鑷韩缁戝畾
+ */
+uibase.textAlign = function (align, type) {
+ if (!utils.validateNumber(type)) {
+ type = 0
+ }
+ this.obj.lvObjSetStyleTextAlign(align, type)
+}
+/**
+ * 璁剧疆鏂囨湰瀛椾綋
+ * @param {object} font font.js閲宐uild杩斿洖鐨勫璞�
+ * @param {number} type 鍙傝�僽tils.STYLE 闈炲繀濉紝缂虹渷鏄拰瀵硅薄鑷韩缁戝畾
+ */
+uibase.textFont = function (font, type) {
+ if (!utils.validateNumber(type)) {
+ type = 0
+ }
+ if (!font || !font.obj) {
+ throw new Error("dxui.textFont: 'font' parameter should not be null")
+ }
+ this.obj.lvObjSetStyleTextFont(font.obj, type)
+}
+/**
+ * 璁剧疆绾垮璞�(line)棰滆壊
+ * @param {any} color 鏀寔鏁板瓧绫诲瀷锛氭瘮濡�0x34ffaa锛涘瓧绗︿覆绫诲瀷(#寮�澶�),姣斿:'#34ffaa'
+ * @param {number} type 鍙傝�僽tils.STYLE 闈炲繀濉紝缂虹渷鏄拰瀵硅薄鑷韩缁戝畾
+ */
+uibase.lineColor = function (color, type) {
+ if (!utils.validateNumber(type)) {
+ type = 0
+ }
+ this.obj.lvObjSetStyleLineColor(utils.colorParse(color), type)
+}
+/**
+ * 璁剧疆绾垮璞�(line)瀹藉害
+ * @param {number} w
+ * @param {number} type 鍙傝�僽tils.STYLE 闈炲繀濉紝缂虹渷鏄拰瀵硅薄鑷韩缁戝畾
+ */
+uibase.lineWidth = function (w, type) {
+ if (!utils.validateNumber(type)) {
+ type = 0
+ }
+ this.obj.lvObjSetStyleLineWidth(w, type)
+}
+/**
+ * 璁剧疆绾垮璞�(line)鍦嗚
+ * @param {boolean} enable true/false
+ */
+uibase.lineRound = function (enable) {
+ this.obj.lvObjSetStyleLineRounded(enable)
+}
+/**
+ * 璁剧疆ui瀵硅薄鐨勬粴鍔ㄦ潯鏄剧ず鏂瑰紡
+ * @param {boolean} state ture/false
+ */
+uibase.scrollbarMode = function (state) {
+ this.obj.lvObjSetScrollbarMode(state)
+}
+/**
+ * 璁剧疆ui瀵硅薄鏄惁鏀寔婊氬姩
+ * @param {boolean} state
+ */
+uibase.scroll = function (state) {
+ if (state) {
+ this.obj.lvObjAddFlag(16)
+ } else {
+ this.obj.lvObjClearFlag(16)
+ }
+}
+/**
+ * 灏嗗璞′笌鍏跺畠鍙傜収瀵硅薄瀵归綈
+ * @param {object} ref 鍙傜収瀵硅薄
+ * @param {number} type 瀵归綈鐨勬柟鍚戯紝鍙傝�僤xui.Utils.ALIGN鏋氫妇
+ * @param {number} x 鍋忕Щ鐨剎
+ * @param {number} y 鍋忕Щ鐨剏
+ */
+uibase.alignTo = function (ref, type, x, y) {
+ if (!ref || !ref.obj) {
+ throw new Error("dxui.alignto: 'ref' parameter should not be null")
+ }
+ this.obj.lvObjAlignTo(ref.obj, type, x, y)
+}
+/**
+ * 灏嗗璞′笌鐖跺璞″榻�
+ * @param {number} type 瀵归綈鐨勬柟鍚戯紝鍙傝�僤xui.Utils.ALIGN鏋氫妇
+ * @param {number} x 鍋忕Щ鐨剎
+ * @param {number} y 鍋忕Щ鐨剏
+ */
+uibase.align = function (type, x, y) {
+ this.obj.lvObjAlign(type, x, y)
+}
+/**
+ * 浼哥缉鐩掑竷灞�锛屽彲浠ユ洿鍔犵伒娲诲緱瀹氫綅銆佹帓鍒楀拰鍒嗗竷鍏冪礌锛屼娇寰楀垱寤哄搷搴斿紡鍜屽彲浼哥缉鐨勫竷灞�鍙樺緱鏇村姞瀹规槗銆�
+ * 瀹冨熀浜庝竴涓鍣紝鍜屽唴閮ㄧ殑涓�浜涘脊鎬ч」鐩紝涓嬮潰鏄娇鐢ㄨ繖绉嶅竷灞�鐨勪竴浜涙蹇碉細
+ * 1銆佸鍣細瀹瑰櫒鍖呭惈浜嗗唴閮ㄧ殑寮规�ч」鐩紝鍙互浣块噷闈㈤」鐩粠宸﹀悜鍙虫垨浠庡彸鍚戝乏绛夎鍒欐帓鍒椼��
+ * 2銆佷富杞村拰渚ц酱锛氫富杞达紝鏄鍣ㄤ腑椤圭洰鐨勪富瑕佹帓鍒楁柟寮忥紝閫氬父鏄按骞虫柟鍚戞垨鍨傜洿鏂瑰悜锛屽彲浠ヨ椤圭洰浠按骞虫帓鍒楁垨绾靛悜鎺掑垪銆�
+ * 渚ц酱锛屼笌涓昏酱鍨傜洿鐨勮酱鍚戯紝鍙互瑙勫畾椤圭洰浠湪渚ц酱涓婄殑鎺掑垪鏂瑰紡銆�
+ * 涓昏酱鍜屼晶杞寸敱flexFlow()璁剧疆锛屼富瑕佹湁ROW锛堟按骞虫柟鍚戯級銆丆OLUMN锛堝瀭鐩存柟鍚戯級涓ょ锛屽甫鏈塛RAP鍚庣紑鐨勫湪椤圭洰浠秴鍑哄鍣ㄦ椂鑷姩鎹㈣锛屽甫鏈塕EVERSE鍚庣紑鐨勪笌榛樿鎺掑垪鏂瑰悜鐩稿弽锛屽嵆涓轰粠鍙冲埌宸︽帓鍒楋紙鑻ヤ富杞存槸鍨傜洿鏂瑰悜鍒欎负浠庝笅鍒颁笂鎺掑垪锛夈��
+ * 3銆佷富杞村榻愭柟寮忥細START锛堥粯璁や富杞撮『搴忥級銆丒ND锛堥粯璁や富杞撮『搴忕浉鍙嶏級銆丆ENTER锛堝湪涓昏酱鏂瑰悜涓婂眳涓級銆丼PACE_EVENLY锛堝湪涓昏酱涓婂潎鍖�鍒嗗竷锛屼袱涓や箣闂磋窛绂荤浉绛夛級銆丼PACE_AROUND锛堝湪涓昏酱涓婂潎鍖�鍒嗗竷锛屾瘡涓」鐩钩鍒嗕富杞翠笂鐨勮窛绂伙級銆丼PACE_BETWEEN锛堜袱绔《鏍硷紝涓棿鍧囧垎锛夛紝鐢眆lexAlign()璁剧疆銆�
+ * 4銆佷晶杞村榻愭柟寮忥細灏嗘瘡涓�琛屾垨姣忎竴鍒楃湅浣滀竴涓」鐩紝鍦ㄤ晶杞存柟鍚戜笂瀵归綈锛屽榻愭柟寮忓悓涓昏酱锛岀敱flexAlign()璁剧疆銆�
+ * 5銆佹暣浣撳榻愭柟寮忥細灏嗗鍣ㄥ唴鎵�鏈夐」鐩湅浣滀竴涓暣浣擄紝鍦ㄥ鍣ㄤ腑瀵归綈锛屽榻愭柟寮忓悓涓昏酱锛岀敱flexAlign()璁剧疆銆�
+ * @param {number} type 涓昏酱鍜屼晶杞寸殑璁剧疆
+ */
+uibase.flexFlow = function (type) {
+ this.obj.lvObjSetFlexFlow(type)
+}
+/**
+ *
+ * @param {number} main 瀛愬厓绱犳寜涓昏酱鏂瑰悜鐨勫榻愭柟寮�
+ * @param {number} cross 瀛愬厓绱犳寜渚ц酱鏂瑰悜鐨勫榻愭柟寮�
+ * @param {number} track 鎵�鏈夊瓙鍏冪礌瀵逛簬瀹瑰櫒鐨勫榻愭柟寮�
+ */
+uibase.flexAlign = function (main, cross, track) {
+ this.obj.lvObjSetFlexAlign(main, cross, track)
+}
+/**
+ * 鏇存柊涓�涓帶浠剁殑灏哄锛屽綋鑾峰彇涓�涓帶浠剁殑灏哄涓�0鏃跺彲浠ュ厛璋冪敤锛岀浉褰撲簬鏇存柊鏄剧ず缂撳瓨銆�
+ */
+uibase.update = function () {
+ this.obj.lvObjUpdateLayout()
+}
+/**
+ * 娣诲姞涓�涓帶浠剁殑鐘舵��
+ * @param {number} state 鐘舵�佹灇涓�
+ */
+uibase.addState = function (state) {
+ this.obj.addState(state)
+}
+/**
+ * 鍒犻櫎涓�涓帶浠剁殑鐘舵�侊紝濡傛灉鎯宠涓�涓仛鐒﹁緭鍏ユ澶辩劍锛屽彲浠ヨ皟鐢ㄦ鏂规硶鍒犻櫎FOCUSED鐘舵��
+ * @param {number} state 鐘舵�佹灇涓�
+ */
+uibase.clearState = function (state) {
+ this.obj.clearState(state)
+}
+/**
+ * 鍒ゆ柇涓�涓帶浠舵槸鍚︽嫢鏈夌姸鎬侊紝鎯冲垽鏂竴涓緭鍏ユ鏄惁琚仛鐒︿簡锛屽彲浠ヤ娇鐢ㄦ鏂规硶骞朵紶鍏OCUSED鍙傛暟
+ * @param {number} state 鐘舵�佹灇涓�
+ * @returns true/false
+ */
+uibase.hasState = function (state) {
+ return this.obj.hasState(state)
+}
+/**
+ * 閲嶇粯涓�涓帶浠讹紝寮哄埗鍒锋柊鎺т欢鐨勭紦瀛橈紝鍙互寮哄埗瑙e喅鑺卞睆鐨勯棶棰橈紝浣嗘槸濡傛灉姝诲惊鐜腑璋冪敤浼氶檷浣庢�ц兘
+ */
+uibase.invalidate = function () {
+ this.obj.invalidate()
+}
+/**
+ * 婊氬姩鏌愪釜瀛愭帶浠剁洿鑷虫樉绀哄嚭鏉ワ紝濡傛灉鎯冲皢涓�涓婊氬姩鑷冲鍣ㄥ瀵艰嚧鐪嬩笉瑙佺殑椤圭洰婊氬姩鑷宠兘琚湅瑙佺殑浣嶇疆锛岃皟鐢ㄦ鏂规硶銆�
+ * @param {boolean} en 鏄惁寮�鍚姩鐢伙紝寮�鍚細缂撴參婊氬姩鍑烘潵锛屽叧闂垯鐩存帴璺冲嚭銆�
+ * @param {boolean} notRecursive 榛樿閫掑綊锛岄�傜敤浜庝竴鑸粴鍔ㄥ拰婊氬姩宓屽鎺т欢
+ */
+uibase.scrollToView = function (en, isRecursive) {
+ if (isRecursive) {
+ this.obj.scrollToView(en)
+ } else {
+ this.obj.scrollToViewRecursive(en)
+ }
+}
+/**
+ * 婊氬姩涓�涓帶浠剁殑x鏂瑰悜
+ * @param {number} x 婊氬姩x杞磋窛绂�
+ * @param {boolean} en 鏄惁寮�鍚姩鐢�
+ */
+uibase.scrollToX = function (x, en) {
+ this.obj.scrollToX(x, en)
+}
+/**
+ * 婊氬姩涓�涓帶浠剁殑y鏂瑰悜
+ * @param {number} y 婊氬姩y杞磋窛绂�
+ * @param {boolean} en 鏄惁寮�鍚姩鐢�
+ */
+uibase.scrollToY = function (y, en) {
+ this.obj.scrollToY(y, en)
+}
+/**
+ * 鍏冪礌蹇収锛堝叾瀹炲氨鏄埅鍥撅紝濡傛灉鎯充繚瀛樺叏灞忔埅鍥撅紝鍙互瀵瑰睆骞曞璞′娇鐢ㄦ鏂规硶锛�
+ * @param {string} fileName 蹇呭~锛屼繚瀛樺揩鐓х殑鏂囦欢鍚嶏紙娉ㄦ剰鍚庣紑搴斾笌鏍煎紡瀵瑰簲锛�
+ * @param {number} type 闈炲繀濉紝缂虹渷png锛屽揩鐓ф牸寮� 0:bmp/1:png/2:jpg(jpeg)
+ * @param {number} cf 闈炲繀濉紝涓�绉峈GB棰滆壊瀛樺偍鏍煎紡
+ */
+uibase.snapshot = function (fileName, type = 1, cf = NativeObject.APP.NativeComponents.NativeEnum.LV_IMG_CF_TRUE_COLOR_ALPHA) {
+ if (!fileName) {
+ return
+ }
+ // 榛樿瀛樺偍鍦�/app/data/snapshot浣嶇疆
+ os.mkdir("/app/data/snapshot/")
+ this.obj.lvSnapshotTake(cf, "/app/data/snapshot/" + fileName, type)
+}
+export default uibase;
\ No newline at end of file
diff --git a/vf205_access/dxmodules/uiButton.js b/vf205_access/dxmodules/uiButton.js
new file mode 100644
index 0000000..b60fc4d
--- /dev/null
+++ b/vf205_access/dxmodules/uiButton.js
@@ -0,0 +1,16 @@
+//build锛�20240311
+//button鎺т欢 鐩稿鍩虹被娌℃湁鏂板姛鑳�
+import utils from "./uiUtils.js"
+import base from "./uiBase.js"
+let button = {}
+
+button.build = function (id, parent) {
+ let temp = utils.validateBuild(button.all, id, parent, 'button')
+ let my = { type: 'button' }
+ my.obj = new utils.GG.NativeButton({ uid: id }, temp)
+ my.id = id
+ let comp = Object.assign(my, base);
+ utils.setParent(this.all, comp, parent)
+ return comp;
+}
+export default button;
\ No newline at end of file
diff --git a/vf205_access/dxmodules/uiButtons.js b/vf205_access/dxmodules/uiButtons.js
new file mode 100644
index 0000000..f1ff13f
--- /dev/null
+++ b/vf205_access/dxmodules/uiButtons.js
@@ -0,0 +1,107 @@
+//build锛�20240314
+//鎸夐挳缁勬帶浠�
+import utils from "./uiUtils.js"
+import base from "./uiBase.js"
+let buttons = {}
+
+buttons.build = function (id, parent) {
+ let temp = utils.validateBuild(buttons.all, id, parent, 'buttons')
+ let my = {type: 'buttons'}
+ my.obj = new utils.GG.NativeBtnmatrix({ uid: id }, temp)
+ my.id = id
+ /**
+ * 璁剧疆button缁勫搴旂殑鏁版嵁锛屽繀椤绘槸鏁扮粍鏍煎紡锛岀ず渚嬪涓嬶細琛ㄧず涓夎鎸夐挳锛屾�诲叡12涓寜閽�
+ * ["1", "2", "3", "0", "\n",
+ * "4", "5", "6", "鍙栨秷", "\n",
+ * "7", "8", "9", "纭", ""]
+ * @param {array} d 闈炲繀濉紝濡傛灉娌℃湁濉垨鑰呬笉鏄痮bject绫诲瀷灏辨槸鑾峰彇鏁版嵁
+ */
+ my.data = function (d) {
+ if (utils.validateObject(d)) {
+ this.obj.lvBtnmatrixSetMap(d)
+ } else {
+ return this.obj.lvBtnmatrixGetMap()
+ }
+ }
+ /**
+ * 鐐瑰嚮鎸夐挳缁勯噷浠讳綍涓�涓寜閽紝璋冪敤selectedData鏉ヨ幏鍙栫偣鍑绘寜閽殑id鍜屾枃鏈�
+ * 杩斿洖绀轰緥: {id:11,text:'鍙栨秷'}
+ */
+ my.clickedButton = function () {
+ let id = this.obj.lvBtnmatrixGetSelectedBtn();
+ if (id == 0xFFFF) {
+ // 鐐瑰嚮鎸夐挳缁勮竟鐣屼細鍑虹幇0xFFFF闈炴硶鍊硷紝杩斿洖绌�
+ return { id: null, text: null }
+ }
+ let txt = this.obj.lvBtnmatrixGetBtnText(id);
+ return { id: id, text: txt }
+ }
+ /**
+ * 璁剧疆鎸夐挳缁勯噷鏌愪竴涓壒瀹氭寜閽殑鐘舵�侊紝鍙互鏀规垚閫変腑锛屼笉鍙敤涔嬬被鐨�
+ * @param {number} id 鎸夐挳鐨勭储寮曪紝浠�0寮�濮嬩粠宸﹀埌鍙充粠涓婂埌涓嬶紝涔熸槸鐐瑰嚮鎸夐挳clickedButton杩斿洖鐨刬d
+ * @param {number} state 鍙傝�僤xui.Utils.BUTTONS_STATE
+ */
+ my.setState = function (id, state) {
+ this.obj.lvBtnmatrixSetBtnCtrl(id, state)
+ }
+ /**
+ * 娓呴櫎鎸夐挳缁勯噷鏌愪竴涓壒瀹氭寜閽殑宸茬粡璁剧疆濂界殑鐘舵��
+ * @param {number} id 鎸夐挳鐨勭储寮曪紝浠�0寮�濮嬩粠宸﹀埌鍙充粠涓婂埌涓嬶紝涔熸槸鐐瑰嚮鎸夐挳clickedButton杩斿洖鐨刬d
+ * @param {number} state 鍙傝�僤xui.Utils.BUTTONS_STATE
+ */
+ my.clearState = function (id, state) {
+ this.obj.lvBtnmatrixClearBtnCtrl(id, state)
+ }
+ /**
+ * 璁剧疆鎸夐挳缁勯噷鎵�鏈夋寜閽殑鐘舵�侊紝鍙互鏀规垚閫変腑锛屼笉鍙敤涔嬬被鐨�
+ * @param {number} state 鍙傝�僤xui.Utils.BUTTONS_STATE
+ */
+ my.setAllState = function (state) {
+ this.obj.lvBtnmatrixSetBtnCtrlAll(state)
+ }
+ /**
+ * 娓呴櫎鎸夐挳缁勯噷鎵�鏈夋寜閽殑宸茬粡璁剧疆濂界殑鐘舵��
+ * @param {number} state 鍙傝�僤xui.Utils.BUTTONS_STATE
+ */
+ my.clearAllState = function (state) {
+ this.obj.lvBtnmatrixClearBtnCtrlAll(state)
+ }
+ /**
+ * 璁剧疆鏌愪釜id鐨勬寜閽搴﹀崰鐢ㄥ嚑鏍�
+ * @param {number} id 鎸夐挳搴忓彿锛屼粠0寮�濮嬬紪鍙�
+ * @param {number} width 瀹藉害璺ㄨ秺鏍煎瓙鏁伴噺
+ */
+ my.setBtnWidth = function (id, width) {
+ this.obj.lvBtnmatrixSetBtnWidth(id, width)
+ }
+ /**
+ * 璁剧疆鏌愪釜id鐨勬寜閽浘鏍�
+ * @param {number} id 鎸夐挳搴忓彿锛屼粠0寮�濮嬬紪鍙�
+ * @param {string} src 鍥炬爣鏂囦欢璺緞
+ */
+ my.setBtnIcon = function (id, src) {
+ this.obj.addEventCb((e) => {
+ // 鑾峰彇缁樺埗鎺т欢瀵硅薄
+ let dsc = e.lvEventGetDrawPartDsc()
+ // 濡傛灉鏄粯鍒剁id涓寜閽�
+ if (dsc.type == utils.ENUM.LV_BTNMATRIX_DRAW_PART_BTN && dsc.id == id) {
+ // 鑾峰彇鍥剧墖淇℃伅
+ let header = utils.GG.NativeDraw.lvImgDecoderGetInfo(src)
+ // 瀹氫箟涓�鍧楀尯鍩燂紝灞呬腑鏄剧ず锛屾敞鎰忥細灏哄杞琣rea闇�瑕�-1锛宎rea杞昂瀵搁渶瑕�+1
+ let x1 = dsc.draw_area.x1 + (dsc.draw_area.x2 - dsc.draw_area.x1 + 1 - header.w) / 2;
+ let y1 = dsc.draw_area.y1 + (dsc.draw_area.y2 - dsc.draw_area.y1 + 1 - header.h) / 2;
+ let x2 = x1 + header.w - 1;
+ let y2 = y1 + header.h - 1;
+ let area = utils.GG.NativeArea.lvAreaSet(x1, y1, x2, y2)
+ // 缁樺埗鍥剧墖淇℃伅
+ let img_draw_dsc = utils.GG.NativeDraw.lvDrawImgDscInit()
+ // 缁樺埗鍥剧墖
+ utils.GG.NativeDraw.lvDrawImg(dsc.dsc, img_draw_dsc, area, src)
+ }
+ }, utils.ENUM.LV_EVENT_DRAW_PART_END)
+ }
+ let comp = Object.assign(my, base);
+ utils.setParent(this.all,comp,parent)
+ return comp;
+}
+export default buttons;
\ No newline at end of file
diff --git a/vf205_access/dxmodules/uiCheckbox.js b/vf205_access/dxmodules/uiCheckbox.js
new file mode 100644
index 0000000..f08dac2
--- /dev/null
+++ b/vf205_access/dxmodules/uiCheckbox.js
@@ -0,0 +1,48 @@
+//build锛�20240329
+//checkbox鎺т欢
+import utils from "./uiUtils.js"
+import base from "./uiBase.js"
+let checkbox = {}
+
+checkbox.build = function (id, parent) {
+ let temp = utils.validateBuild(checkbox.all, id, parent, 'checkbox')
+ let my = { type: 'checkbox' }
+ my.obj = new utils.GG.NativeCheckbox({ uid: id }, temp)
+ my.id = id
+ /**
+ * 鑾峰彇/璁剧疆鏂囧瓧
+ * @param {string} text 璁剧疆鏂囧瓧
+ * @returns 鑾峰彇鏂囧瓧
+ */
+ my.text = function (text) {
+ if (text == null || text == undefined) {
+ return this.obj.getText()
+ } else {
+ this.obj.setText(text)
+ }
+ }
+ /**
+ * 閫変腑鎴栦笉閫変腑
+ * @param {boolean} en true/false
+ */
+ my.select = function (en) {
+ if (en) {
+ if (!my.obj.hasState(utils.STATE.CHECKED)) {
+ my.obj.addState(utils.STATE.CHECKED)
+ }
+ } else {
+ my.obj.clearState(utils.STATE.CHECKED)
+ }
+ }
+ /**
+ * 鍒ゆ柇鏄惁閫変腑
+ * @returns 杩斿洖true/false
+ */
+ my.isSelect = function () {
+ return my.obj.hasState(utils.STATE.CHECKED)
+ }
+ let comp = Object.assign(my, base);
+ utils.setParent(this.all, comp, parent)
+ return comp;
+}
+export default checkbox;
\ No newline at end of file
diff --git a/vf205_access/dxmodules/uiDropdown.js b/vf205_access/dxmodules/uiDropdown.js
new file mode 100644
index 0000000..d517613
--- /dev/null
+++ b/vf205_access/dxmodules/uiDropdown.js
@@ -0,0 +1,53 @@
+//build锛�20240329
+//dropdown鎺т欢
+import utils from "./uiUtils.js"
+import base from "./uiBase.js"
+let dropdown = {}
+
+dropdown.build = function (id, parent) {
+ let temp = utils.validateBuild(dropdown.all, id, parent, 'dropdown')
+ let my = {type: 'dropdown'}
+ my.obj = new utils.GG.NativeDropdown({ uid: id }, temp)
+ my.id = id
+ /**
+ * 璁剧疆涓嬫媺閫夐」鍐呭
+ * @param {array} arr 閫夐」鍐呭锛屾槸涓瓧绗︿覆鏁扮粍锛屾瘡涓�椤逛负涓�涓�夐」
+ */
+ my.setOptions = function (arr) {
+ this.obj.setOptions(arr.join('\n'))
+ }
+ /**
+ * 鑾峰彇涓嬫媺閫夐」鍒楄〃
+ * @returns 杩斿洖鍒楄〃瀵硅薄锛屾槸涓�涓熀绫诲璞★紝鍙互鍗曠嫭璁剧疆瀹冪殑瀛椾綋
+ */
+ my.getList = function () {
+ let res = {}
+ res.obj = this.obj.getList()
+ return Object.assign(res, base)
+ }
+ /**
+ * 璁剧疆閫変腑椤癸紝榛樿浼氶�変腑杩欎釜
+ * @param {number} index 閫変腑椤圭储寮�
+ */
+ my.setSelected = function (index) {
+ this.obj.setSelected(index)
+ }
+ /**
+ * 鑾峰彇閫変腑椤圭储寮�
+ * @returns 杩斿洖褰撳墠閫変腑鐨勭储寮�
+ */
+ my.getSelected = function () {
+ return this.obj.getSelected()
+ }
+ /**
+ * 璁剧疆涓嬫媺妗嗛檮灞炲浘鏍囷紝榛樿鏄釜鏈濅笅鐨勭澶�
+ * @param {string} icon 鍥炬爣鍦板潃
+ */
+ my.setSymbol = function (icon) {
+ this.obj.setSymbol(icon)
+ }
+ let comp = Object.assign(my, base);
+ utils.setParent(this.all, comp, parent)
+ return comp;
+}
+export default dropdown;
\ No newline at end of file
diff --git a/vf205_access/dxmodules/uiFont.js b/vf205_access/dxmodules/uiFont.js
new file mode 100644
index 0000000..bea8251
--- /dev/null
+++ b/vf205_access/dxmodules/uiFont.js
@@ -0,0 +1,18 @@
+//build锛�20240311
+//瀛椾綋瀵硅薄(瑕佹敮鎸佷腑鏂囷紝闇�瑕佷娇鐢ㄦ敮鎸佷腑鏂囩殑瀛椾綋ttf鏂囦欢)
+import utils from "./uiUtils.js"
+let font = {}
+/**
+ * 鏋勫缓瀛椾綋
+ * @param {string} ttf 瀛椾綋ttf鏂囦欢鐨勫畬鏁磋矾寰�
+ * @param {number} size 瀛椾綋澶у皬
+ * @param {number} style 瀛椾綋鏍峰紡锛屽弬鑰僽tils.FONT_STYLE
+ * @returns
+ */
+font.build = function (ttf, size, style) {
+ let comp = {}
+ comp.obj = utils.GG.NativeFont.lvFontInit(ttf, size, style)
+ return comp;
+}
+
+export default font;
\ No newline at end of file
diff --git a/vf205_access/dxmodules/uiImage.js b/vf205_access/dxmodules/uiImage.js
new file mode 100644
index 0000000..3111257
--- /dev/null
+++ b/vf205_access/dxmodules/uiImage.js
@@ -0,0 +1,27 @@
+//build锛�20240311
+//image鎺т欢
+import utils from "./uiUtils.js"
+import base from "./uiBase.js"
+let image = {}
+
+image.build = function (id, parent) {
+ let temp = utils.validateBuild(image.all, id, parent, 'image')
+ let my = {type: 'image'}
+ my.obj = new utils.GG.NativeImage({ uid: id }, temp)
+ my.id = id
+ /**
+ * 璁剧疆image鐨勬潵婧愭垨鑾峰彇鏉ユ簮
+ * @param {string} path 闈炲繀濉紝鍥剧墖鏂囦欢鐨勭粷瀵硅矾寰勶紝濡傛灉娌℃湁濉垨鑰呬笉鏄痵tring绫诲瀷灏辨槸鑾峰彇
+ */
+ my.source = function (path) {
+ if (utils.validateString(path)) {
+ this.obj.lvImgSetSrc(path)
+ } else {
+ return this.obj.lvImgGetSrc()
+ }
+ }
+ let comp = Object.assign(my, base);
+ utils.setParent(this.all, comp, parent)
+ return comp;
+}
+export default image;
\ No newline at end of file
diff --git a/vf205_access/dxmodules/uiKeyboard.js b/vf205_access/dxmodules/uiKeyboard.js
new file mode 100644
index 0000000..5f50b27
--- /dev/null
+++ b/vf205_access/dxmodules/uiKeyboard.js
@@ -0,0 +1,102 @@
+//build锛�20240329
+//keyboard鎺т欢
+import utils from "./uiUtils.js"
+import base from "./uiBase.js"
+let keyboard = {}
+
+keyboard.build = function (id, parent) {
+ let temp = utils.validateBuild(keyboard.all, id, parent, 'keyboard')
+ let my = {type: 'keyboard'}
+ my.obj = new utils.GG.NativeKeyboard({ uid: id }, temp)
+
+ // 鎷奸煶杈撳叆娉曚細鑾峰緱涓�涓柊瀵硅薄锛屼笌褰撳墠閿洏缁戝畾锛屼互澧炲己閿洏鍔熻兘锛屽9閿瓑锛岀敤鎴蜂娇鐢ㄦ椂涓嶇敤鍏冲績锛屽彧瑕佹搷浣滄渶鍒濆垱寤虹殑閭d釜閿洏瀵硅薄
+ let pinyin = {}
+ pinyin.obj = my.obj.lvImePinyinCreate()
+ my.obj.lvImePinyinSetKeyboard(pinyin.obj)
+ my["__obj"] = Object.assign(pinyin, base)
+ my.__mode = "K26"
+
+ my.id = id
+ /**
+ * 璁剧疆鍏宠仈鏂囨湰妗嗭紝閿洏杈撳嚭鐨勫唴瀹逛細鏄剧ず鍦ㄨ繖閲�
+ * @param {object} textarea 鏂囨湰妗嗘帶浠跺璞�
+ */
+ my.setTextarea = function (textarea) {
+ this.obj.lvKeyboardSetTextarea(textarea.obj)
+ my.textarea = textarea
+ }
+ /**
+ * 璁剧疆/鑾峰彇妯″紡锛岀函鏁板瓧閿洏鎴栧叾浠栨ā寮�
+ * @param {any} mode 妯″紡锛屽弬鐓ф灇涓�
+ * @returns 杩斿洖褰撳墠妯″紡
+ */
+ my.mode = function (mode) {
+ if (!mode) {
+ return my.__mode
+ }
+ if (mode == "K26" || mode == "K9") {
+ this.obj.lvImePinyinSetMode(my["__obj"].obj, mode == "K26" ? 0 : 1)
+ } else {
+ if (mode == utils.KEYBOARD.NUMBER) {
+ this.obj.lvImePinyinSetMode(my["__obj"].obj, 2)
+ }
+ this.obj.lvKeyboardSetMode(mode)
+ }
+ my.__mode = mode
+ }
+ /**
+ * 璁剧疆鎷奸煶瀛椾綋锛屽拰閿洏涓嶅悓锛岃繖閲岃缃殑鏄�欓�夊瓧瀛椾綋
+ * @param {object} font font.js閲宐uild杩斿洖鐨勫璞�
+ * @param {number} type 鍙傝�僽tils.STYLE 闈炲繀濉紝缂虹渷鏄拰瀵硅薄鑷韩缁戝畾
+ */
+ my.chFont = function (font, type) {
+ if (!utils.validateNumber(type)) {
+ type = 0
+ }
+ if (!font || !font.obj) {
+ throw new Error("dxui.textFont: 'font' parameter should not be null")
+ }
+ my.obj.lvImePinyinGetCandPanel(my["__obj"].obj).lvObjSetStyleTextFont(font.obj, type)
+ }
+ /**
+ * 鎸変笅鏃跺湪寮瑰嚭绐楀彛涓樉绀烘寜閽爣棰橈紝鍗宠緟鍔╂樉绀虹殑涓婁綅妗嗐��
+ * @param {boolean} en true/false
+ */
+ my.setPopovers = function (en) {
+ this.obj.lvKeyboardSetPopovers(en)
+ }
+ /**
+ * 璁剧疆璇嶅簱
+ * @param {object} dict 璇嶅簱锛屾牸寮忓锛歿"a": "鍟�", "ai": "鐖�",...,"zu":"缁�"},26涓瓧姣嶉兘瑕佹湁锛屾病鏈夊�欓�夊瓧灏卞啓""
+ * @returns
+ */
+ my.dict = function (dict) {
+ if (!dict) {
+ return my.obj.lvImePinyinGetDict(my["__obj"].obj)
+ } else {
+ my.obj.lvImePinyinSetDict(my["__obj"].obj, dict)
+ }
+ }
+ let comp = Object.assign(my, base);
+ // 閲嶅啓鏂规硶
+ // 淇濈暀鍘熷鐨勬柟娉�
+ const super_hide = my.hide;
+ const super_show = my.show;
+ my.hide = function () {
+ super_hide.call(this)
+ my.obj.lvImePinyinGetCandPanel(my["__obj"].obj).lvObjAddFlag(1);
+ if (my.textarea.text() && my.textarea.text().length > 0) {
+ my.obj.lvImePinyinClearData(my["__obj"].obj)
+ }
+ }
+ my.show = function () {
+ super_show.call(this)
+ if (my.obj.lvImePinyinGetCandNum(my["__obj"].obj) > 0) {
+ my.obj.lvImePinyinGetCandPanel(my["__obj"].obj).lvObjClearFlag(1);
+ }
+ my.obj.lvImePinyinGetCandPanel(my["__obj"].obj).lvObjAlignTo(my.obj, utils.ALIGN.OUT_TOP_MID, 0, 0)
+ }
+ utils.setParent(this.all, comp, parent)
+ return comp;
+}
+export default keyboard;
\ No newline at end of file
diff --git a/vf205_access/dxmodules/uiLabel.js b/vf205_access/dxmodules/uiLabel.js
new file mode 100644
index 0000000..0e4b6ea
--- /dev/null
+++ b/vf205_access/dxmodules/uiLabel.js
@@ -0,0 +1,34 @@
+//build锛�20240311
+//label鎺т欢
+import utils from "./uiUtils.js"
+import base from "./uiBase.js"
+let label = {}
+
+label.build = function (id, parent) {
+ let temp = utils.validateBuild(label.all, id, parent, 'label')
+ let my = {type: 'label'}
+ my.obj = new utils.GG.NativeLabel({ uid: id }, temp)
+ my.id = id
+ /**
+ * 璁剧疆label鐨勬枃鏈垨鑾峰彇鏂囨湰鍐呭
+ * @param {string} t 闈炲繀濉紝濡傛灉娌℃湁濉垨鑰呬笉鏄痵tring绫诲瀷灏辨槸鑾峰彇鏂囨湰
+ */
+ my.text = function (t) {
+ if (utils.validateString(t)) {
+ this.obj.lvLabelSetText(t)
+ } else {
+ return this.obj.lvLabelGetText()
+ }
+ }
+ /**
+ * 璁剧疆鏂囨湰瓒呴暱鍚庢樉绀虹殑妯″紡锛屾瘮濡傛粴鍔ㄦ樉绀烘垨鎴柇鎴�...绛�
+ * @param {number} mode 鏋氫妇鍙傝�僽tils.LABEL_LONG_MODE
+ */
+ my.longMode = function (mode) {
+ this.obj.lvLabelSetLongMode(mode)
+ }
+ let comp = Object.assign(my, base);
+ utils.setParent(this.all, comp, parent)
+ return comp;
+}
+export default label;
\ No newline at end of file
diff --git a/vf205_access/dxmodules/uiLine.js b/vf205_access/dxmodules/uiLine.js
new file mode 100644
index 0000000..9639b84
--- /dev/null
+++ b/vf205_access/dxmodules/uiLine.js
@@ -0,0 +1,24 @@
+//build锛�20240311
+//line鎺т欢
+import utils from "./uiUtils.js"
+import base from "./uiBase.js"
+let line = {}
+
+line.build = function (id, parent) {
+ let temp = utils.validateBuild(line.all, id, parent, 'line')
+ let my = {type: 'line'}
+ my.obj = new utils.GG.NativeLine({ uid: id }, temp)
+ my.id = id
+ /**
+ * 璁剧疆line鐨勬墍鏈夌偣鐨勫潗鏍�
+ * @param {Array} points 蹇呭~锛屾墍鏈夌殑鐐圭粍鎴愮殑鏁扮粍锛屾瘮濡俒[x1,y1],[x2,y2]]
+ * @param {number} count 蹇呭~锛岃缁樺埗鐨勭偣鐨勪釜鏁帮紝娉ㄦ剰杩欎釜鍊煎彲浠ュ皬浜巔oints鐨勯暱搴�
+ */
+ my.setPoints = function (points, count) {
+ this.obj.lvLineSetPoints(points, count)
+ }
+ let comp = Object.assign(my, base);
+ utils.setParent(this.all, comp, parent)
+ return comp;
+}
+export default line;
\ No newline at end of file
diff --git a/vf205_access/dxmodules/uiList.js b/vf205_access/dxmodules/uiList.js
new file mode 100644
index 0000000..de1316a
--- /dev/null
+++ b/vf205_access/dxmodules/uiList.js
@@ -0,0 +1,45 @@
+//build锛�20240329
+//list鎺т欢
+import utils from "./uiUtils.js"
+import base from "./uiBase.js"
+let list = {}
+
+list.build = function (id, parent) {
+ let temp = utils.validateBuild(list.all, id, parent, 'list')
+ let my = {type: 'list'}
+ my.obj = new utils.GG.NativeList({ uid: id }, temp)
+ my.id = id
+ /**
+ * 娣诲姞鍗曚釜鏂囨湰椤�
+ * @param {string} text 椤圭殑鏂囨湰鍐呭
+ * @returns 椤硅嚜韬殑base瀵硅薄
+ */
+ my.addText = function (text) {
+ let res = {}
+ res.obj = this.obj.lvListAddText(text)
+ return Object.assign(res, base)
+ }
+ /**
+ * 娣诲姞鍗曚釜鎸夐挳椤�
+ * @param {string} src 椤瑰墠闈㈢殑鍥炬爣璺緞
+ * @param {string} text 椤圭殑鏂囨湰鍐呭
+ * @returns 椤硅嚜韬殑base瀵硅薄
+ */
+ my.addBtn = function (src, text) {
+ let res = {}
+ res.obj = this.obj.lvListAddBtn(src, text)
+ return Object.assign(res, base)
+ }
+ /**
+ * 鑾峰彇鎸夐挳椤圭殑鏂囨湰鍐呭
+ * @param {string} btn 鎸夐挳椤�
+ * @returns 鎸夐挳椤圭殑鏂囨湰鍐呭
+ */
+ my.getBtnText = function (btn) {
+ return this.obj.lvListGetBtnText(btn.obj)
+ }
+ let comp = Object.assign(my, base);
+ utils.setParent(this.all, comp, parent)
+ return comp;
+}
+export default list;
\ No newline at end of file
diff --git a/vf205_access/dxmodules/uiSlider.js b/vf205_access/dxmodules/uiSlider.js
new file mode 100644
index 0000000..e67d877
--- /dev/null
+++ b/vf205_access/dxmodules/uiSlider.js
@@ -0,0 +1,42 @@
+//build锛�20240329
+//slider鎺т欢
+import utils from "./uiUtils.js"
+import base from "./uiBase.js"
+let slider = {}
+
+slider.build = function (id, parent) {
+ let temp = utils.validateBuild(slider.all, id, parent, 'slider')
+ let my = {type: 'slider'}
+ my.obj = new utils.GG.NativeSlider({ uid: id }, temp)
+ my.id = id
+
+ /**
+ * 鑾峰彇/璁剧疆鍊�
+ * @param {number} v 璁剧疆鍊�
+ * @param {boolean} en 璁剧疆鍊兼椂鏄惁寮�鍚姩鐢伙紝鍗崇紦鍔ㄦ晥鏋�
+ * @returns 鑾峰彇鍊�
+ */
+ my.value = function (v, en) {
+ if (v == null || v == undefined) {
+ return this.obj.lvSliderGetValue()
+ } else {
+ if (!utils.validateNumber(en)) {
+ en = false
+ }
+ this.obj.lvSliderSetValue(v, en)
+ }
+ }
+ /**
+ * 璁剧疆鑼冨洿
+ * @param {number} min 鏈�灏忓��
+ * @param {number} max 鏈�澶у��
+ */
+ my.range = function (min, max) {
+ this.obj.lvSliderSetRange(min, max)
+ }
+
+ let comp = Object.assign(my, base);
+ utils.setParent(this.all, comp, parent)
+ return comp;
+}
+export default slider;
\ No newline at end of file
diff --git a/vf205_access/dxmodules/uiStyle.js b/vf205_access/dxmodules/uiStyle.js
new file mode 100644
index 0000000..0e4f845
--- /dev/null
+++ b/vf205_access/dxmodules/uiStyle.js
@@ -0,0 +1,149 @@
+//build锛�20240315
+//鎺т欢鏍峰紡 姣忎釜鎺т欢鍙互缁戝畾鏍峰紡瀵硅薄锛岃缃绉嶆牱寮�
+import utils from "./uiUtils.js"
+
+let style = {}
+style.build = function () {
+ let comp = {}
+ comp.obj = new utils.GG.NativeStyle()
+ comp.obj.lvStyleInit()
+ /**
+ * 璁剧疆宸﹀彸涓婁笅鐨勫唴杈硅窛閮戒负涓�涓��
+ * @param {number} pad 杈硅窛鍊�
+ */
+ comp.padAll = function (pad) {
+ this.obj.lvStyleSetPadAll(pad)
+ }
+ /**
+ * 璁剧疆鍙冲唴杈硅窛閮戒负涓�涓��
+ * @param {number} pad 杈硅窛鍊�
+ */
+ comp.padRight = function (pad) {
+ this.obj.lvStyleSetPadRight(pad)
+ }
+ /**
+ * 璁剧疆宸﹀唴杈硅窛閮戒负涓�涓��
+ * @param {number} pad 杈硅窛鍊�
+ */
+ comp.padLeft = function (pad) {
+ this.obj.lvStyleSetPadLeft(pad)
+ }
+ /**
+ * 璁剧疆涓婂唴杈硅窛閮戒负涓�涓��
+ * @param {number} pad 杈硅窛鍊�
+ */
+ comp.padTop = function (pad) {
+ this.obj.lvStyleSetPadTop(pad)
+ }
+ /**
+ * 璁剧疆涓嬪唴杈硅窛閮戒负涓�涓��
+ * @param {number} pad 杈硅窛鍊�
+ */
+ comp.padBottom = function (pad) {
+ this.obj.lvStyleSetPadBottom(pad)
+ }
+ /**
+ * 璁剧疆鍒椾笌鍒椾箣闂寸殑杈硅窛閮戒负涓�涓��
+ * @param {number} pad 杈硅窛鍊�
+ */
+ comp.padColumn = function (pad) {
+ this.obj.lvStyleSetPadColumn(pad)
+ }
+ /**
+ * 璁剧疆琛屼笌琛屼箣闂寸殑杈硅窛閮戒负涓�涓��
+ * @param {number} pad 杈硅窛鍊�
+ */
+ comp.padRow = function (pad) {
+ this.obj.lvStyleSetPadRow(pad)
+ }
+ /**
+ * 璁剧疆杈规瀹藉害
+ * @param {number} w
+ */
+ comp.borderWidth = function (w) {
+ this.obj.lvStyleSetBorderWidth(w)
+ }
+ /**
+ * 璁剧疆杈瑰渾瑙�
+ * @param {number} r
+ */
+ comp.radius = function (r) {
+ this.obj.lvStyleSetRadius(r)
+ }
+ /**
+ * 璁剧疆鑳屾櫙閫忔槑搴︼紝鍊艰寖鍥存槸0-100锛屽�艰秺灏忚秺濂�
+ * @param {number} opa 蹇呴』鏄�0-100
+ */
+ comp.bgOpa = function (opa) {
+ this.obj.lvStyleSetBgOpa(utils.OPA_MAPPING(opa))
+ }
+ /**
+ * 璁剧疆鑷韩閫忔槑搴︼紝鍊艰寖鍥存槸0-100锛屽�艰秺灏忚秺濂�
+ * @param {number} opa 蹇呴』鏄�0-100
+ */
+ comp.opa = function (opa) {
+ this.obj.lvStyleSetOpa(utils.OPA_MAPPING(opa))
+ }
+ /**
+ * 璁剧疆鑳屾櫙棰滆壊
+ * @param {any} color 鏀寔鏁板瓧绫诲瀷锛氭瘮濡�0x34ffaa锛涘瓧绗︿覆绫诲瀷(#寮�澶�),姣斿:'#34ffaa'
+ */
+ comp.bgColor = function (color) {
+ this.obj.lvStyleSetBgColor(utils.colorParse(color))
+ }
+ /**
+ * 璁剧疆鏂囨湰棰滆壊
+ * @param {any} color 鏀寔鏁板瓧绫诲瀷锛氭瘮濡�0x34ffaa锛涘瓧绗︿覆绫诲瀷(#寮�澶�),姣斿:'#34ffaa'
+ */
+ comp.textColor = function (color) {
+ this.obj.lvStyleSetTextColor(utils.colorParse(color))
+ }
+ /**
+ * 璁剧疆鏂囨湰瀵归綈鏂瑰紡
+ * @param {number} type 鍙傝�僽tils.TEXT_ALIGN
+ */
+ comp.textAlign = function (type) {
+ this.obj.lvStyleSetTextAlign(type)
+ }
+ /**
+ * 璁剧疆鏂囨湰瀛椾綋
+ * @param {object} font font.js閲宐uild杩斿洖鐨勫璞�
+ */
+ comp.textFont = function (font) {
+ if (!font || !font.obj) {
+ throw new Error("style.textFont: 'font' parameter should not be null")
+ }
+ this.obj.lvStyleSetTextFont(font.obj)
+ }
+ /**
+ * 璁剧疆娓愬彉鑹�
+ * @param {number} color 娓愬彉鑹诧紝渚嬪:0xffffff
+ */
+ comp.bgGradColor = function (color) {
+ this.obj.lvStyleSetBgGradColor(color)
+ }
+ /**
+ * 璁剧疆娓愬彉鑹叉柟鍚�
+ * @param {number} dir 鏂瑰悜锛岀洰鍓嶅彧鏀寔姘村钩鍜屽瀭鐩�
+ */
+ comp.bgGradDir = function (dir) {
+ this.obj.lvStyleSetBgGradDir(dir)
+ }
+ /**
+ * 鑳屾櫙鑹茬殑缁撴潫浣嶇疆(0-255)
+ * @param {number} value 璺濈锛屼粠宸︾寮�濮嬭绠�
+ */
+ comp.bgMainStop = function (value) {
+ this.obj.lvStyleSetBgMainStop(value)
+ }
+ /**
+ * 娓愬彉鑹茬殑璺濈(0-255)
+ * @param {number} value 璺濈锛屼粠鑳屾櫙鑹茬殑缁撴潫浣嶇疆寮�濮嬭绠�
+ */
+ comp.bgGradStop = function (value) {
+ this.obj.lvStyleSetBgGradStop(value)
+ }
+ return comp;
+}
+
+export default style;
\ No newline at end of file
diff --git a/vf205_access/dxmodules/uiSwitch.js b/vf205_access/dxmodules/uiSwitch.js
new file mode 100644
index 0000000..bfa4376
--- /dev/null
+++ b/vf205_access/dxmodules/uiSwitch.js
@@ -0,0 +1,49 @@
+//build锛�20240329
+//_switch鎺т欢
+import utils from "./uiUtils.js"
+import base from "./uiBase.js"
+let _switch = {}
+
+_switch.build = function (id, parent) {
+ let temp = utils.validateBuild(_switch.all, id, parent, '_switch')
+ let my = {type: 'switch'}
+ my.obj = new utils.GG.NativeSwitch({ uid: id }, temp)
+ my.id = id
+
+ /**
+ * 鑾峰彇/璁剧疆鏂囧瓧
+ * @param {string} text 璁剧疆鏂囧瓧
+ * @returns 鑾峰彇鏂囧瓧
+ */
+ my.text = function (text) {
+ if (text == null || text == undefined) {
+ return this.obj.getText()
+ } else {
+ this.obj.setText(text)
+ }
+ }
+ /**
+ * 閫変腑鎴栦笉閫変腑
+ * @param {boolean} en true/false
+ */
+ my.select = function (en) {
+ if (en) {
+ if (!my.obj.hasState(utils.STATE.CHECKED)) {
+ my.obj.addState(utils.STATE.CHECKED)
+ }
+ } else {
+ my.obj.clearState(utils.STATE.CHECKED)
+ }
+ }
+ /**
+ * 鍒ゆ柇鏄惁閫変腑
+ * @returns 杩斿洖true/false
+ */
+ my.isSelect = function () {
+ return my.obj.hasState(utils.STATE.CHECKED)
+ }
+ let comp = Object.assign(my, base);
+ utils.setParent(this.all, comp, parent)
+ return comp;
+}
+export default _switch;
\ No newline at end of file
diff --git a/vf205_access/dxmodules/uiTextarea.js b/vf205_access/dxmodules/uiTextarea.js
new file mode 100644
index 0000000..5ff82d0
--- /dev/null
+++ b/vf205_access/dxmodules/uiTextarea.js
@@ -0,0 +1,76 @@
+//build锛�20240330
+//textarea鎺т欢
+import utils from "./uiUtils.js"
+import base from "./uiBase.js"
+let textarea = {}
+
+textarea.build = function (id, parent) {
+ let temp = utils.validateBuild(textarea.all, id, parent, 'textarea')
+ let my = {type: 'textarea'}
+ my.obj = new utils.GG.NativeTextarea({ uid: id }, temp)
+ my.id = id
+ /**
+ * 璁剧疆鍗曡妯″紡锛屼笉鑳芥崲琛�
+ * @param {boolean} en true/false
+ */
+ my.setOneLine = function (en) {
+ this.obj.lvTextareaSetOneLine(en)
+ }
+ /**
+ * 璁剧疆瀵嗙爜妯″紡锛屽唴瀹规樉绀轰负路鍙�
+ * @param {boolean} en true/false
+ */
+ my.setPasswordMode = function (en) {
+ this.obj.lvTextareaSetPasswordMode(en)
+ }
+ /**
+ * 璁剧疆鍐呭瀵归綈鏂瑰紡锛屽眳涓潬宸﹂潬鍙崇瓑
+ * @param {number} align 瀵归綈鏂瑰紡鏋氫妇
+ */
+ my.setAlign = function (align) {
+ this.obj.lvTextareaSetAlign(align)
+ }
+ /**
+ * 璁剧疆鍐呭鏈�澶ч暱搴︼紝瀛楃鏁伴檺鍒�
+ * @param {number} length 闀垮害
+ */
+ my.setMaxLength = function (length) {
+ this.obj.lvTextareaSetMaxLength(length)
+ }
+ /**
+ * 璁剧疆鏄惁鍚敤鍏夋爣瀹氫綅锛屾槸鍚︽樉绀簗
+ * @param {boolean} en true/false
+ */
+ my.setCursorClickPos = function (en) {
+ this.obj.lvTextareaSetCursorClickPos(en)
+ }
+ /**
+ * 鍦ㄥ綋鍓嶅厜鏍囦綅缃彃鍏ユ枃鏈�
+ * @param {string} txt 鏂囨湰鍐呭
+ */
+ my.lvTextareaAddText = function (txt) {
+ this.obj.lvTextareaAddText(txt)
+ }
+ /**
+ * 浠庡綋鍓嶅厜鏍囦綅缃垹闄ゅ乏杈圭殑瀛楃
+ */
+ my.lvTextareaDelChar = function () {
+ this.obj.lvTextareaDelChar()
+ }
+ /**
+ * 鑾峰彇/璁剧疆鏂囨湰鍐呭
+ * @param {string} text 璁剧疆鏂囨湰鍐呭
+ * @returns 鑾峰彇鏂囨湰鍐呭
+ */
+ my.text = function (text) {
+ if (text == null || text == undefined) {
+ return this.obj.lvTextareaGetText()
+ } else {
+ this.obj.lvTextareaSetText(text)
+ }
+ }
+ let comp = Object.assign(my, base);
+ utils.setParent(this.all, comp, parent)
+ return comp;
+}
+export default textarea;
\ No newline at end of file
diff --git a/vf205_access/dxmodules/uiUtils.js b/vf205_access/dxmodules/uiUtils.js
new file mode 100644
index 0000000..eae2a07
--- /dev/null
+++ b/vf205_access/dxmodules/uiUtils.js
@@ -0,0 +1,292 @@
+//build锛�20240315
+//鍏敤鐨勪竴浜涘嚱鏁般�佸父閲忋�佹灇涓剧瓑
+import { uiClass } from '../dxmodules/libvbar-m-dxui.so'
+import logger from './dxLogger.js'
+const ui = new uiClass();
+// 鍒濆鍖杣i缁勪欢
+ui.init()
+
+let utils = {}
+utils.GG = NativeObject.APP.NativeComponents
+utils.ENUM = utils.GG.NativeEnum
+utils.LAYER = {
+ "MAIN": 0,
+ "SYS": 1,
+ "TOP": 2
+}
+utils.EVENT = {
+ "CLICK": 7,
+ "LONG_PRESSED": 5,
+ "SHORT_PRESSED": 4,
+ "PRESSING": utils.ENUM.LV_EVENT_PRESSING,
+ "FOCUSED": utils.ENUM.LV_EVENT_FOCUSED,
+ "DEFOCUSED": utils.ENUM.LV_EVENT_DEFOCUSED,
+ "VALUE_CHANGED": utils.ENUM.LV_EVENT_VALUE_CHANGED,
+ "INSERT": utils.ENUM.LV_EVENT_INSERT,
+ "REFRESH": utils.ENUM.LV_EVENT_REFRESH,
+ "READY": utils.ENUM.LV_EVENT_READY,
+ "CANCEL": utils.ENUM.LV_EVENT_CANCEL,
+}
+utils.TEXT_ALIGN = {
+ "AUTO": 0,
+ "LEFT": 1,
+ "CENTER": 2,
+ "RIGHT": 3
+}
+utils.STATE = {
+ "DEFAULT": utils.ENUM.LV_STATE_DEFAULT,
+ "CHECKED": utils.ENUM.LV_STATE_CHECKED,
+ "FOCUSED": utils.ENUM.LV_STATE_FOCUSED,
+ "FOCUS_KEY": utils.ENUM.LV_STATE_FOCUS_KEY,
+ "EDITED": utils.ENUM.LV_STATE_EDITED,
+ "HOVERED": utils.ENUM.LV_STATE_HOVERED,
+ "PRESSED": utils.ENUM.LV_STATE_PRESSED,
+ "SCROLLED": utils.ENUM.LV_STATE_SCROLLED,
+ "DISABLED": utils.ENUM.LV_STATE_DISABLED,
+}
+utils.OBJ_FLAG = {
+ "CLICKABLE": utils.ENUM.LV_OBJ_FLAG_CLICKABLE,
+}
+utils.ALIGN = {//鐩稿鍙傜収瀵硅薄鐨勪綅缃紝甯� OUT 鐨勫湪鍙傜収瀵硅薄鐨勮竟鐣屽
+ "OUT_TOP_LEFT": utils.ENUM.LV_ALIGN_OUT_TOP_LEFT,
+ "OUT_TOP_MID": utils.ENUM.LV_ALIGN_OUT_TOP_MID,
+ "OUT_TOP_RIGHT": utils.ENUM.LV_ALIGN_OUT_TOP_RIGHT,
+ "OUT_BOTTOM_LEFT": utils.ENUM.LV_ALIGN_OUT_BOTTOM_LEFT,
+ "OUT_BOTTOM_MID": utils.ENUM.LV_ALIGN_OUT_BOTTOM_MID,
+ "OUT_BOTTOM_RIGHT": utils.ENUM.LV_ALIGN_OUT_BOTTOM_RIGHT,
+ "OUT_LEFT_TOP": utils.ENUM.LV_ALIGN_OUT_LEFT_TOP,
+ "OUT_LEFT_MID": utils.ENUM.LV_ALIGN_OUT_LEFT_MID,
+ "OUT_LEFT_BOTTOM": utils.ENUM.LV_ALIGN_OUT_LEFT_BOTTOM,
+ "OUT_RIGHT_TOP": utils.ENUM.LV_ALIGN_OUT_RIGHT_TOP,
+ "OUT_RIGHT_MID": utils.ENUM.LV_ALIGN_OUT_RIGHT_MID,
+ "OUT_RIGHT_BOTTOM": utils.ENUM.LV_ALIGN_OUT_RIGHT_BOTTOM,
+ "TOP_LEFT": utils.ENUM.LV_ALIGN_TOP_LEFT,
+ "TOP_MID": utils.ENUM.LV_ALIGN_TOP_MID,
+ "TOP_RIGHT": utils.ENUM.LV_ALIGN_TOP_RIGHT,
+ "BOTTOM_LEFT": utils.ENUM.LV_ALIGN_BOTTOM_LEFT,
+ "BOTTOM_MID": utils.ENUM.LV_ALIGN_BOTTOM_MID,
+ "BOTTOM_RIGHT": utils.ENUM.LV_ALIGN_BOTTOM_RIGHT,
+ "LEFT_MID": utils.ENUM.LV_ALIGN_LEFT_MID,
+ "RIGHT_MID": utils.ENUM.LV_ALIGN_RIGHT_MID,
+ "CENTER": utils.ENUM.LV_ALIGN_CENTER,
+ "DEFAULT": utils.ENUM.LV_ALIGN_DEFAULT
+}
+utils.FLEX_ALIGN = {//flex甯冨眬锛屽榻愭柟寮�
+ "START": utils.ENUM.LV_FLEX_ALIGN_START,
+ "END": utils.ENUM.LV_FLEX_ALIGN_END,
+ "CENTER": utils.ENUM.LV_FLEX_ALIGN_CENTER,
+ "SPACE_EVENLY": utils.ENUM.LV_FLEX_ALIGN_SPACE_EVENLY,
+ "SPACE_AROUND": utils.ENUM.LV_FLEX_ALIGN_SPACE_AROUND,
+ "SPACE_BETWEEN": utils.ENUM.LV_FLEX_ALIGN_SPACE_BETWEEN,
+}
+utils.FLEX_FLOW = {//flex甯冨眬锛屼富渚ц酱
+ "ROW": utils.ENUM.LV_FLEX_FLOW_ROW,
+ "COLUMN": utils.ENUM.LV_FLEX_FLOW_COLUMN,
+ "ROW_WRAP": utils.ENUM.LV_FLEX_FLOW_ROW_WRAP,
+ "ROW_REVERSE": utils.ENUM.LV_FLEX_FLOW_ROW_REVERSE,
+ "ROW_WRAP_REVERSE": utils.ENUM.LV_FLEX_FLOW_ROW_WRAP_REVERSE,
+ "COLUMN_WRAP": utils.ENUM.LV_FLEX_FLOW_COLUMN_WRAP,
+ "COLUMN_REVERSE": utils.ENUM.LV_FLEX_FLOW_COLUMN_REVERSE,
+ "COLUMN_WRAP_REVERSE": utils.ENUM.LV_FLEX_FLOW_COLUMN_WRAP_REVERSE,
+}
+utils.GRAD = {//娓愬彉鑹叉柟鍚�
+ "NONE": utils.ENUM.LV_GRAD_DIR_NONE,
+ "VER": utils.ENUM.LV_GRAD_DIR_VER,
+ "HOR": utils.ENUM.LV_GRAD_DIR_HOR,
+}
+utils.KEYBOARD = {//閿洏妯″紡
+ "TEXT_LOWER": utils.ENUM.LV_KEYBOARD_MODE_TEXT_LOWER,
+ "TEXT_UPPER": utils.ENUM.LV_KEYBOARD_MODE_TEXT_UPPER,
+ "SPECIAL": utils.ENUM.LV_KEYBOARD_MODE_SPECIAL,
+ "NUMBER": utils.ENUM.LV_KEYBOARD_MODE_NUMBER,
+ "K26": "K26",
+ "K9": "K9",
+}
+utils.FONT_STYLE = {
+ "NORMAL": utils.ENUM.FT_FONT_STYLE_NORMAL,
+ "ITALIC": utils.ENUM.FT_FONT_STYLE_ITALIC,
+ "BOLD": utils.ENUM.FT_FONT_STYLE_BOLD,
+}
+utils.BUTTONS_STATE = {
+ "HIDDEN": utils.ENUM.LV_BTNMATRIX_CTRL_HIDDEN,//鎸夐挳鐭╅樀涓殑鏌愪釜鎸夐挳鏄惁闅愯棌
+ "NO_REPEAT": utils.ENUM.LV_BTNMATRIX_CTRL_NO_REPEAT,//鎸夐挳鐭╅樀涓殑鎸夐挳鏄惁鍙互閲嶅鎸変笅,涓嶄細閲嶅瑙﹀彂鎸夐敭浜嬩欢
+ "DISABLED": utils.ENUM.LV_BTNMATRIX_CTRL_DISABLED,//鎸夐挳鐭╅樀涓殑鏌愪釜鎸夐挳鏄惁绂佺敤
+ "CHECKABLE": utils.ENUM.LV_BTNMATRIX_CTRL_CHECKABLE,//鎸夐挳鐭╅樀涓殑鎸夐挳鏄惁鍙�変腑
+ "CHECKED": utils.ENUM.LV_BTNMATRIX_CTRL_CHECKED,//鎸夐挳鐭╅樀涓殑鏌愪釜鎸夐挳鏄惁宸茶閫変腑,鍦ㄧ晫闈笂鍛堢幇涓鸿閫変腑鐘舵��
+ "CLICK_TRIG": utils.ENUM.LV_BTNMATRIX_CTRL_CLICK_TRIG,//鎸夐挳鐭╅樀涓殑鎸夐挳鏄惁鍙互閫氳繃鐐瑰嚮瑙﹀彂
+ "POPOVER": utils.ENUM.LV_BTNMATRIX_CTRL_POPOVER,//鐭╅樀涓殑鏌愪釜鎸夐挳鏄惁寮瑰嚭,琚偣鍑诲悗浼氭樉绀烘洿澶氱殑閫夐」鎴栧唴瀹�
+ "RECOLOR": utils.ENUM.LV_BTNMATRIX_CTRL_RECOLOR//鐭╅樀涓殑鎸夐挳鏄惁鍙噸鏂扮潃鑹�
+}
+//鏍峰紡璧蜂綔鐢ㄧ殑閮ㄥ垎
+utils.STYLE_PART = {
+ "MAIN": 0, //瀵硅薄褰撳墠鏍峰紡璧蜂綔鐢�
+ "ITEMS": 327680//瀵硅薄鍐呴儴瀛愰」璧蜂綔鐢紝姣斿buttonMatrix閲岀殑鎸夐挳缁�
+}
+//鏂囨湰瓒呭嚭鎺т欢鏄剧ず鐨勬ā寮�
+utils.LABEL_LONG_MODE = {
+ "WRAP": utils.ENUM.LV_LABEL_LONG_WRAP,//鏂囨湰闀跨殑鏃跺�欐崲琛�
+ "DOT": utils.ENUM.LV_LABEL_LONG_DOT,//鏂囨湰闀跨殑鏃跺�欑敤...鏇夸唬
+ "SCROLL": utils.ENUM.LV_LABEL_LONG_SCROLL,//鏂囨湰闀跨殑鏃跺�欒嚜鍔ㄦ粴鍔�
+ "SCROLL_CIRCULAR": utils.ENUM.LV_LABEL_LONG_SCROLL_CIRCULAR,//鏂囨湰闀跨殑鏃跺�欏惊鐜粴鍔�
+ "CLIP": utils.ENUM.LV_LABEL_LONG_CLIP,//鏂囨湰闀跨殑鏃跺�欒嚜鍔ㄦ埅鏂�
+}
+// 瀹炵幇0-100鏄犲皠涓�0-255
+utils.OPA_MAPPING = function (value) {
+ return Math.round((value / 100) * 255);
+}
+/**
+* 鏍¢獙鏁板瓧鏄惁涓虹┖锛屾槸鍚︿负number
+* @param {number} n 蹇呭~
+* @param {err} 閿欒淇℃伅锛岄潪蹇呭~锛屽~浜嗕細鎶涘嚭Error
+*/
+utils.validateNumber = function (n, err) {
+ return _valid(n, 'number', err)
+}
+/**
+* 鏍¢獙瀵硅薄鏄惁涓虹┖锛屾槸鍚︿负object
+* @param {object} o 蹇呭~
+* @param {err} 閿欒淇℃伅锛岄潪蹇呭~锛屽~浜嗕細鎶涘嚭Error
+*/
+utils.validateObject = function (o, err) {
+ return _valid(o, 'object', err)
+}
+/**
+ * 鏍¢獙ui瀵硅薄鐨勬瀯寤哄弬鏁�
+ * @param {array} all 蹇呭~,鎵�鏈夊璞″紩鐢�
+ * @param {string} id 涓嶈兘涓虹┖锛屽繀濉�
+ * @param {object} parent 闈炲繀濉紝缂虹渷鏄�0
+ */
+utils.validateBuild = function (all, id, parent, type) {
+ this.validateId(all, id)
+ if (parent === 0 || parent === 1 || parent === 2) {
+ return parent
+ }
+ if (!parent || !parent.obj) {
+ throw new Error(type + ".build: 'parent' paramter should not be null")
+ }
+ return parent.obj
+}
+/**
+ * 鏍¢獙鎵�鏈塽i鎺т欢鐨刬d锛屼笉鑳介噸澶�
+ * @param {array} all
+ * @param {string} id
+ */
+utils.validateId = function (all, id) {
+ this.validateString(id, "The 'id' parameter should not be null.")
+ if (all[id]) {
+ throw new Error("The id(" + id + ") already exists. Please set a different id value.")
+ }
+}
+/**
+* 鏍¢獙瀛楃涓叉槸鍚︿负绌�
+* @param {string} s 蹇呭~
+* @param {err} 閿欒淇℃伅锛岄潪蹇呭~锛屽~浜嗕細鎶涘嚭Error
+*/
+utils.validateString = function (s, err) {
+ let res = _valid(s, 'string', err)
+ if (!res) {
+ return false
+ }
+ if (s.length <= 0) {
+ if (err) {
+ throw new Error(err)
+ }
+ return false
+ }
+ return true
+}
+/**
+ * 瑙f瀽涓嶅悓绫诲瀷鐨勯鑹插��
+ * @param {any} value 鏀寔鏁板瓧绫诲瀷锛�0x34ffaa锛屽瓧绗︿覆绫诲瀷:'0x34ffaa',瀛楃涓茬被鍨�:'#34ffaa'
+ * @returns
+ */
+utils.colorParse = function (value) {
+ if (typeof value == 'string') {
+ value = value.replace('#', '0x')
+ value = parseInt(value, 16)
+ }
+ return value
+}
+/**
+ * 鑾峰彇瑙︽懜鐐圭殑鍧愭爣
+ * @returns {x:妯潗鏍�,y:绾靛潗鏍噠
+ */
+utils.getTouchPoint = function () {
+ let point = NativeObject.APP.NativeComponents.NativeIndev.lvIndevGetPoint()
+ return point
+}
+/**
+ * 鎻愪緵鍔ㄧ敾
+ * @param {object} obj 鍔ㄧ敾鎿嶄綔瀵硅薄锛屽彲浠ユ槸浠绘剰瀵硅薄锛屽洖璋冨弬鏁拌幏鍙�
+ * @param {number} start 鍖洪棿寮�濮嬪�硷紝涓�鑸拰end鎼厤浣跨敤锛屽洖璋冨弬鏁拌幏鍙栵紝start鍦ㄥ姩鐢昏繃绋嬪彉鍖栧埌end
+ * @param {number} end 鍖洪棿缁撴潫鍊�
+ * @param {function} cb 鍥炶皟鍑芥暟(obj, v)=>{},obj鍗冲姩鐢绘搷浣滃璞★紝鍖洪棿鍊硷紙start-end锛�
+ * @param {number} duration 鍔ㄧ敾鎸佺画鏃堕棿锛屾绉�
+ * @param {number} backDuration 鍙�夛紝鍔ㄧ敾鍥炴斁鏃堕棿锛屾绉掞紝缂虹渷涓嶅洖鏀�
+ * @param {number} repeat 鍙�夛紝鍔ㄧ敾閲嶅娆℃暟锛岀己鐪�1娆�
+ * @param {string} mode 閫熺巼鏇茬嚎锛屽彲閫夛紝缂虹渷linear锛屽唴缃姛鑳斤細linear,ease_in,ease_out,ease_in_out,overshoot,bounce,step
+ * linear 绾挎�у姩鐢�
+ step 鍦ㄦ渶鍚庝竴姝ユ洿鏀�
+ ease_in 寮�濮嬬紦鎱�
+ ease_out 鏈�鍚庣紦鎱�
+ ease_in_out 鍦ㄥ紑濮嬪拰缁撴潫鏃堕兘寰堢紦鎱�
+ overshoot 瓒呭嚭鏈�缁堝��
+ bounce 浠庢渶缁堝�煎弽寮逛竴鐐癸紙姣斿鎾炲埌澧欙級
+ * @returns 鍔ㄧ敾瀹炰緥锛屼竴瀹氬緱淇濆瓨鍒板叏灞�
+ */
+utils.anime = function (obj, start, end, cb, duration, backDuration, repeat, mode) {
+ // 1銆佸垵濮嬪寲鍔ㄧ敾
+ let anim = NativeObject.APP.NativeComponents.NativeAnim.lvAnimInit()
+ // 2銆佽缃姩鐢诲璞�
+ anim.lvAnimSetVar(obj)
+ // 3銆佽缃捣濮嬪拰缁撴潫鍊�
+ anim.lvAnimSetValues(start, end)
+ //4銆佽缃姩鐢诲洖璋冨嚱鏁�
+ anim.lvAnimSetExecCb(cb)
+ // 5銆佽缃姩鐢绘椂闂�
+ anim.lvAnimSetTime(duration)
+ // 鍙�夛紝璁剧疆鍔ㄧ敾鍥炴斁鏃堕棿锛屼笉璁剧疆灏变笉鍥炴斁
+ if (backDuration) {
+ anim.lvAnimSetPlaybackTime(backDuration)
+ }
+ // 鍙�夛紝璁剧疆鍔ㄧ敾閲嶅娆℃暟
+ if (repeat) {
+ anim.lvAnimSetRepeatCount(repeat)
+ }
+ // 鍙�夛紝璁剧疆鍔ㄧ敾閫熺巼鏇茬嚎
+ if (mode) {
+ anim.lvAnimSetPathCb(mode)
+ }
+ // 6銆佽繍琛屽姩鐢�
+ anim.lvAnimStart()
+ return anim
+}
+//姣忎釜瀵硅薄璁剧疆parent鍜宑hildren
+utils.setParent = function (all, child, parent) {
+ if (!all || parent == null || parent == undefined || !child) {
+ return
+ }
+ if((typeof parent)=='number'){
+
+ }
+ const parentId = ((typeof parent)=='number')?'' + parent:parent.id//鎶�0锛�1锛�2杞垚瀛楃涓�
+ if (!all[parentId]) {
+ all[parentId] = { id: parentId }//鏍硅妭鐐�0,1,2
+ }
+ if (!all[parentId].children) {
+ all[parentId].children = []
+ }
+ all[parentId].children.push(child.id)
+ child.parent = parentId
+ all[child.id] = child
+}
+function _valid(n, type, err) {
+ if (n === undefined || n === null || (typeof n) != type) {
+ if (err) {
+ throw new Error(err)
+ }
+ return false
+ }
+ return true
+}
+export default utils
\ No newline at end of file
diff --git a/vf205_access/dxmodules/uiView.js b/vf205_access/dxmodules/uiView.js
new file mode 100644
index 0000000..9f66a80
--- /dev/null
+++ b/vf205_access/dxmodules/uiView.js
@@ -0,0 +1,27 @@
+//build锛�20240314
+//鍩虹鐭╁舰瀵硅薄 绫讳技div鍙互鍔犺浇浠讳綍鍏跺畠鎺т欢
+import utils from "./uiUtils.js"
+import base from "./uiBase.js"
+let view = {}
+/**
+ * 鍒涘缓涓�涓獀iew鍔犺浇鍦ㄧ埗鎺т欢瀵硅薄涓�
+ * @param {string} id 鎺т欢id锛屽繀濉�
+ * @param {object} parent 鐖跺璞�
+ * @returns 鍒涘缓瀹岀殑view瀵硅薄
+ */
+view.build = function (id, parent) {
+ let temp = utils.validateBuild(view.all, id, parent, 'view')
+ let my = {type: 'view'}
+ if (temp === 0 || temp === 1 || temp === 2) {
+ my.obj = new utils.GG.NativeBasicComponent({ uid: id }, null, temp)
+ }
+ else {
+ my.obj = new utils.GG.NativeBasicComponent({ uid: id }, temp)
+ }
+ my.id = id
+ let comp = Object.assign(my, base);
+ utils.setParent(this.all,comp,parent)
+ return comp;
+}
+
+export default view;
\ No newline at end of file
diff --git a/vf205_access/dxmodules/vgUartWorker.js b/vf205_access/dxmodules/vgUartWorker.js
new file mode 100644
index 0000000..62adb8c
--- /dev/null
+++ b/vf205_access/dxmodules/vgUartWorker.js
@@ -0,0 +1,166 @@
+//build:20240715
+//鐢ㄤ簬绠�鍖杣art缁勪欢寰厜閫氫俊鍗忚鐨勪娇鐢紝鎶妘art灏佽鍦ㄨ繖涓獁orker閲岋紝浣跨敤鑰呭彧闇�瑕佽闃卐ventcenter鐨勪簨浠跺氨鍙互鐩戝惉uart
+import log from './dxLogger.js'
+import uart from './dxUart.js'
+import common from './dxCommon.js';
+import dxMap from './dxMap.js'
+import * as os from "os";
+import std from './dxStd.js'
+const map = dxMap.get('default')
+const id = "{{id}}"
+const options = map.get("__vguart__run_init" + id)
+const timeout = 100
+const longTimeout = 500
+
+function run() {
+ uart.open(options.type, options.path, options.id)
+ log.info('vg uart start......,id =', id)
+ std.setInterval(() => {
+ try {
+ // 鎺ユ敹鏁版嵁妯″紡
+ if (options.passThrough) {
+ // 閫忎紶妯″紡锛岄�傞厤闊︽牴涔嬬被
+ passThrough()
+ }
+ if(options.type == uart.TYPE.USBHID){
+ receiveUsb()
+ } else {
+ // 寰厜閫氫俊鍗忚妯″紡
+ receive()
+ }
+ } catch (error) {
+ log.error(error)
+ }
+ }, 10)
+}
+
+// 閫忎紶妯″紡
+function passThrough() {
+ let pack = [];
+ let buffer = readOne()
+ while (buffer !== null) {
+ pack.push(buffer)
+ os.sleep(10)
+ buffer = readOne()
+ }
+ if (pack.length !== 0) {
+ __bus.fire(uart.VG.RECEIVE_MSG + options.id, pack)//bus.newworker鐨勬椂鍊欎細import eventbus as __bus
+ }
+}
+
+function receive() {
+ //鍓�2涓瓧鑺傚繀椤绘槸55aa
+ let buffer = readOne()
+ if (buffer === null) {
+ return;
+ }
+ if (buffer == 85) {//0x55
+ buffer = readOne()
+ if (buffer != 170) {//0xaa
+ return;
+ }
+ } else {
+ return;
+ }
+ let pack = {};
+ // 璇诲彇鍛戒护瀛楋紙鍗犵敤1Byte锛�
+ buffer = readOne()
+ if (buffer === null) {
+ return;
+ }
+ pack.cmd = buffer
+ if (options.result) {
+ // 璇诲彇缁撴灉瀛楋紙鍗犵敤1Byte锛�
+ buffer = readOne()
+ if (buffer === null) {
+ return;
+ }
+ pack.result = buffer;
+ } else {
+ pack.result = 0//0涓嶅奖鍝峛cc鐨勮绠楃粨鏋�
+ }
+ // 鍛戒护澶村凡瑙f瀽瀹岋紝璇诲彇闀垮害瀛楋紙鍗犵敤2Byte锛�
+ let len1 = readOne()
+ if (len1 === null) {
+ return;
+ }
+ let len2 = readOne()
+ if (len2 === null) {
+ return;
+ }
+ // 瑙f瀽闀垮害瀛楋紝鑾峰彇鏁版嵁鍩熼暱搴�
+ let len = len1 + len2 * 256
+ // 鏍规嵁闀垮害瀛楄鍙栨寚瀹氭暟鎹暱搴�
+ pack.length = len
+ if (len > 0) {
+ buffer = uart.receive(len, longTimeout, options.id)
+ if (buffer === null) {
+ return;
+ }
+ pack.data = Array.from(buffer);
+ } else {
+ pack.data = 0
+ }
+ // 璇诲彇1Byte鐨勬牎楠屼綅
+ buffer = readOne()
+ if (buffer === null) {
+ return;
+ }
+ let bcc = valid(pack, buffer)
+ let res = { cmd: int2hex(pack.cmd), length: pack.length, bcc: bcc }
+ if (pack.length > 0) {
+ res.data = common.arrToHex(pack.data)
+ }
+ if (options.result) {
+ res.result = int2hex(pack.result)
+ }
+ __bus.fire(uart.VG.RECEIVE_MSG + options.id, res)//bus.newworker鐨勬椂鍊欎細import eventbus as __bus
+}
+
+
+function receiveUsb() {
+ let arr = uart.receive(1024, 100, options.id)
+ if (arr && arr[0] == 0x55 && arr[1] == 0xAA) {
+ let cmd = arr[2]
+ let dlen = arr[4] * 256 + arr[3]
+ if (dlen > (1024 - 6)) {
+ let tempLen = dlen - 1024 + 5
+ while(tempLen >= 0){
+ let tempArr = uart.receive(1024, 100, options.id)
+ tempLen = tempLen - tempArr.length
+ let newArr = new Uint8Array(arr.length + tempArr.length)
+ newArr.set(arr)
+ newArr.set(tempArr, arr.length)
+ arr = newArr
+ }
+ }
+ let data = (dlen == 0 ? [] : Object.values(arr.slice(5, 5 + dlen)))
+ let bcc = common.calculateBcc([0x55, 0xAA, arr[2], arr[3], arr[4]].concat(data))
+ data = data.map(v => v.toString(16).padStart(2, '0')).join('')
+ if (bcc == arr[5 + dlen]) {
+ let res = { "cmd": cmd.toString(16).padStart(2, '0'), "length": dlen, "data": data, "bcc": true }
+ __bus.fire(uart.VG.RECEIVE_MSG + options.id, res)//bus.newworker鐨勬椂鍊欎細import eventbus as __bus
+ }
+ }
+}
+
+function valid(pack, bcc) {
+ let temp = common.calculateBcc([0x55, 0xaa, pack.cmd, pack.result, pack.length % 256, Math.floor(pack.length / 256)].concat(pack.data))
+ return temp === bcc
+}
+function readOne() {
+ let buffer = uart.receive(1, timeout, options.id)
+ if (buffer) {
+ return parseInt(buffer);
+ }
+ return null
+}
+function int2hex(num) {
+ return num.toString(16).padStart(2, '0')
+}
+
+try {
+ run()
+} catch (error) {
+ log.error(error, error.stack)
+}
\ No newline at end of file
diff --git a/vf205_access/resource/CN/wav/access_f.wav b/vf205_access/resource/CN/wav/access_f.wav
new file mode 100644
index 0000000..be7cdf6
--- /dev/null
+++ b/vf205_access/resource/CN/wav/access_f.wav
Binary files differ
diff --git a/vf205_access/resource/CN/wav/access_s.wav b/vf205_access/resource/CN/wav/access_s.wav
new file mode 100644
index 0000000..fdd6ec4
--- /dev/null
+++ b/vf205_access/resource/CN/wav/access_s.wav
Binary files differ
diff --git a/vf205_access/resource/CN/wav/btn11.wav b/vf205_access/resource/CN/wav/btn11.wav
new file mode 100644
index 0000000..b92f478
--- /dev/null
+++ b/vf205_access/resource/CN/wav/btn11.wav
Binary files differ
diff --git a/vf205_access/resource/CN/wav/btn12.wav b/vf205_access/resource/CN/wav/btn12.wav
new file mode 100644
index 0000000..b304efe
--- /dev/null
+++ b/vf205_access/resource/CN/wav/btn12.wav
Binary files differ
diff --git a/vf205_access/resource/CN/wav/btn13.wav b/vf205_access/resource/CN/wav/btn13.wav
new file mode 100644
index 0000000..197a085
--- /dev/null
+++ b/vf205_access/resource/CN/wav/btn13.wav
Binary files differ
diff --git a/vf205_access/resource/CN/wav/btn21.wav b/vf205_access/resource/CN/wav/btn21.wav
new file mode 100644
index 0000000..3f1cb3a
--- /dev/null
+++ b/vf205_access/resource/CN/wav/btn21.wav
Binary files differ
diff --git a/vf205_access/resource/CN/wav/btn22.wav b/vf205_access/resource/CN/wav/btn22.wav
new file mode 100644
index 0000000..f0b0eb1
--- /dev/null
+++ b/vf205_access/resource/CN/wav/btn22.wav
Binary files differ
diff --git a/vf205_access/resource/CN/wav/btn23.wav b/vf205_access/resource/CN/wav/btn23.wav
new file mode 100644
index 0000000..5e58697
--- /dev/null
+++ b/vf205_access/resource/CN/wav/btn23.wav
Binary files differ
diff --git a/vf205_access/resource/CN/wav/btn31.wav b/vf205_access/resource/CN/wav/btn31.wav
new file mode 100644
index 0000000..f600140
--- /dev/null
+++ b/vf205_access/resource/CN/wav/btn31.wav
Binary files differ
diff --git a/vf205_access/resource/CN/wav/btn32.wav b/vf205_access/resource/CN/wav/btn32.wav
new file mode 100644
index 0000000..641d760
--- /dev/null
+++ b/vf205_access/resource/CN/wav/btn32.wav
Binary files differ
diff --git a/vf205_access/resource/CN/wav/btn33.wav b/vf205_access/resource/CN/wav/btn33.wav
new file mode 100644
index 0000000..197a085
--- /dev/null
+++ b/vf205_access/resource/CN/wav/btn33.wav
Binary files differ
diff --git a/vf205_access/resource/CN/wav/calibration_s.wav b/vf205_access/resource/CN/wav/calibration_s.wav
new file mode 100644
index 0000000..a4bff16
--- /dev/null
+++ b/vf205_access/resource/CN/wav/calibration_s.wav
Binary files differ
diff --git a/vf205_access/resource/CN/wav/control_f.wav b/vf205_access/resource/CN/wav/control_f.wav
new file mode 100644
index 0000000..747e2c0
--- /dev/null
+++ b/vf205_access/resource/CN/wav/control_f.wav
Binary files differ
diff --git a/vf205_access/resource/CN/wav/door_close.wav b/vf205_access/resource/CN/wav/door_close.wav
new file mode 100644
index 0000000..5cceeaa
--- /dev/null
+++ b/vf205_access/resource/CN/wav/door_close.wav
Binary files differ
diff --git a/vf205_access/resource/CN/wav/door_open.wav b/vf205_access/resource/CN/wav/door_open.wav
new file mode 100644
index 0000000..a0c86f4
--- /dev/null
+++ b/vf205_access/resource/CN/wav/door_open.wav
Binary files differ
diff --git a/vf205_access/resource/CN/wav/emergency.wav b/vf205_access/resource/CN/wav/emergency.wav
new file mode 100644
index 0000000..aa78e67
--- /dev/null
+++ b/vf205_access/resource/CN/wav/emergency.wav
Binary files differ
diff --git a/vf205_access/resource/CN/wav/emergency_f.wav b/vf205_access/resource/CN/wav/emergency_f.wav
new file mode 100644
index 0000000..630d23b
--- /dev/null
+++ b/vf205_access/resource/CN/wav/emergency_f.wav
Binary files differ
diff --git a/vf205_access/resource/CN/wav/emergency_s.wav b/vf205_access/resource/CN/wav/emergency_s.wav
new file mode 100644
index 0000000..6f5ed36
--- /dev/null
+++ b/vf205_access/resource/CN/wav/emergency_s.wav
Binary files differ
diff --git a/vf205_access/resource/CN/wav/failed.wav b/vf205_access/resource/CN/wav/failed.wav
new file mode 100644
index 0000000..e47d4eb
--- /dev/null
+++ b/vf205_access/resource/CN/wav/failed.wav
Binary files differ
diff --git a/vf205_access/resource/CN/wav/light_close.wav b/vf205_access/resource/CN/wav/light_close.wav
new file mode 100644
index 0000000..f474245
--- /dev/null
+++ b/vf205_access/resource/CN/wav/light_close.wav
Binary files differ
diff --git a/vf205_access/resource/CN/wav/light_open.wav b/vf205_access/resource/CN/wav/light_open.wav
new file mode 100644
index 0000000..ee0428a
--- /dev/null
+++ b/vf205_access/resource/CN/wav/light_open.wav
Binary files differ
diff --git a/vf205_access/resource/CN/wav/network.wav b/vf205_access/resource/CN/wav/network.wav
new file mode 100644
index 0000000..41a063a
--- /dev/null
+++ b/vf205_access/resource/CN/wav/network.wav
Binary files differ
diff --git a/vf205_access/resource/CN/wav/read.wav b/vf205_access/resource/CN/wav/read.wav
new file mode 100644
index 0000000..5d43586
--- /dev/null
+++ b/vf205_access/resource/CN/wav/read.wav
Binary files differ
diff --git a/vf205_access/resource/CN/wav/recg_f.wav b/vf205_access/resource/CN/wav/recg_f.wav
new file mode 100644
index 0000000..357972f
--- /dev/null
+++ b/vf205_access/resource/CN/wav/recg_f.wav
Binary files differ
diff --git a/vf205_access/resource/CN/wav/recg_s.wav b/vf205_access/resource/CN/wav/recg_s.wav
new file mode 100644
index 0000000..9258bae
--- /dev/null
+++ b/vf205_access/resource/CN/wav/recg_s.wav
Binary files differ
diff --git a/vf205_access/resource/CN/wav/recognition.wav b/vf205_access/resource/CN/wav/recognition.wav
new file mode 100644
index 0000000..dac63a3
--- /dev/null
+++ b/vf205_access/resource/CN/wav/recognition.wav
Binary files differ
diff --git a/vf205_access/resource/CN/wav/recognition_s.wav b/vf205_access/resource/CN/wav/recognition_s.wav
new file mode 100644
index 0000000..e5c5772
--- /dev/null
+++ b/vf205_access/resource/CN/wav/recognition_s.wav
Binary files differ
diff --git a/vf205_access/resource/CN/wav/register.wav b/vf205_access/resource/CN/wav/register.wav
new file mode 100644
index 0000000..c76cd83
--- /dev/null
+++ b/vf205_access/resource/CN/wav/register.wav
Binary files differ
diff --git a/vf205_access/resource/CN/wav/stranger.wav b/vf205_access/resource/CN/wav/stranger.wav
new file mode 100644
index 0000000..9f08f3a
--- /dev/null
+++ b/vf205_access/resource/CN/wav/stranger.wav
Binary files differ
diff --git a/vf205_access/resource/CN/wav/user2.wav b/vf205_access/resource/CN/wav/user2.wav
new file mode 100644
index 0000000..96a9f09
--- /dev/null
+++ b/vf205_access/resource/CN/wav/user2.wav
Binary files differ
diff --git a/vf205_access/resource/CN/wav/user2_s.wav b/vf205_access/resource/CN/wav/user2_s.wav
new file mode 100644
index 0000000..611fd82
--- /dev/null
+++ b/vf205_access/resource/CN/wav/user2_s.wav
Binary files differ
diff --git a/vf205_access/resource/CN/wav/verify.wav b/vf205_access/resource/CN/wav/verify.wav
new file mode 100644
index 0000000..3a7555c
--- /dev/null
+++ b/vf205_access/resource/CN/wav/verify.wav
Binary files differ
diff --git a/vf205_access/resource/CN/wav/verify_10x_f.wav b/vf205_access/resource/CN/wav/verify_10x_f.wav
new file mode 100644
index 0000000..72c6d99
--- /dev/null
+++ b/vf205_access/resource/CN/wav/verify_10x_f.wav
Binary files differ
diff --git a/vf205_access/resource/CN/wav/verify_10x_s.wav b/vf205_access/resource/CN/wav/verify_10x_s.wav
new file mode 100644
index 0000000..deef22e
--- /dev/null
+++ b/vf205_access/resource/CN/wav/verify_10x_s.wav
Binary files differ
diff --git a/vf205_access/resource/CN/wav/verify_200_f.wav b/vf205_access/resource/CN/wav/verify_200_f.wav
new file mode 100644
index 0000000..357c4c4
--- /dev/null
+++ b/vf205_access/resource/CN/wav/verify_200_f.wav
Binary files differ
diff --git a/vf205_access/resource/CN/wav/verify_200_s.wav b/vf205_access/resource/CN/wav/verify_200_s.wav
new file mode 100644
index 0000000..52c66b5
--- /dev/null
+++ b/vf205_access/resource/CN/wav/verify_200_s.wav
Binary files differ
diff --git a/vf205_access/resource/CN/wav/verify_300_f.wav b/vf205_access/resource/CN/wav/verify_300_f.wav
new file mode 100644
index 0000000..fae609d
--- /dev/null
+++ b/vf205_access/resource/CN/wav/verify_300_f.wav
Binary files differ
diff --git a/vf205_access/resource/CN/wav/verify_300_s.wav b/vf205_access/resource/CN/wav/verify_300_s.wav
new file mode 100644
index 0000000..92b9958
--- /dev/null
+++ b/vf205_access/resource/CN/wav/verify_300_s.wav
Binary files differ
diff --git a/vf205_access/resource/CN/wav/verify_400_f.wav b/vf205_access/resource/CN/wav/verify_400_f.wav
new file mode 100644
index 0000000..5752539
--- /dev/null
+++ b/vf205_access/resource/CN/wav/verify_400_f.wav
Binary files differ
diff --git a/vf205_access/resource/CN/wav/verify_400_s.wav b/vf205_access/resource/CN/wav/verify_400_s.wav
new file mode 100644
index 0000000..876a228
--- /dev/null
+++ b/vf205_access/resource/CN/wav/verify_400_s.wav
Binary files differ
diff --git a/vf205_access/resource/EN/wav/calibration_s.wav b/vf205_access/resource/EN/wav/calibration_s.wav
new file mode 100644
index 0000000..5d8ba54
--- /dev/null
+++ b/vf205_access/resource/EN/wav/calibration_s.wav
Binary files differ
diff --git a/vf205_access/resource/EN/wav/network.wav b/vf205_access/resource/EN/wav/network.wav
new file mode 100644
index 0000000..f866c59
--- /dev/null
+++ b/vf205_access/resource/EN/wav/network.wav
Binary files differ
diff --git a/vf205_access/resource/EN/wav/read.wav b/vf205_access/resource/EN/wav/read.wav
new file mode 100644
index 0000000..7b40b0b
--- /dev/null
+++ b/vf205_access/resource/EN/wav/read.wav
Binary files differ
diff --git a/vf205_access/resource/EN/wav/recg_f.wav b/vf205_access/resource/EN/wav/recg_f.wav
new file mode 100644
index 0000000..bc4258f
--- /dev/null
+++ b/vf205_access/resource/EN/wav/recg_f.wav
Binary files differ
diff --git a/vf205_access/resource/EN/wav/recg_s.wav b/vf205_access/resource/EN/wav/recg_s.wav
new file mode 100644
index 0000000..054cdb6
--- /dev/null
+++ b/vf205_access/resource/EN/wav/recg_s.wav
Binary files differ
diff --git a/vf205_access/resource/EN/wav/recognition.wav b/vf205_access/resource/EN/wav/recognition.wav
new file mode 100644
index 0000000..1394a09
--- /dev/null
+++ b/vf205_access/resource/EN/wav/recognition.wav
Binary files differ
diff --git a/vf205_access/resource/EN/wav/recognition_s.wav b/vf205_access/resource/EN/wav/recognition_s.wav
new file mode 100644
index 0000000..b096125
--- /dev/null
+++ b/vf205_access/resource/EN/wav/recognition_s.wav
Binary files differ
diff --git a/vf205_access/resource/EN/wav/register.wav b/vf205_access/resource/EN/wav/register.wav
new file mode 100644
index 0000000..324688a
--- /dev/null
+++ b/vf205_access/resource/EN/wav/register.wav
Binary files differ
diff --git a/vf205_access/resource/EN/wav/stranger.wav b/vf205_access/resource/EN/wav/stranger.wav
new file mode 100644
index 0000000..6ba2568
--- /dev/null
+++ b/vf205_access/resource/EN/wav/stranger.wav
Binary files differ
diff --git a/vf205_access/resource/EN/wav/verify.wav b/vf205_access/resource/EN/wav/verify.wav
new file mode 100644
index 0000000..f95f56c
--- /dev/null
+++ b/vf205_access/resource/EN/wav/verify.wav
Binary files differ
diff --git a/vf205_access/resource/EN/wav/verify_10x_f.wav b/vf205_access/resource/EN/wav/verify_10x_f.wav
new file mode 100644
index 0000000..f787a39
--- /dev/null
+++ b/vf205_access/resource/EN/wav/verify_10x_f.wav
Binary files differ
diff --git a/vf205_access/resource/EN/wav/verify_10x_s.wav b/vf205_access/resource/EN/wav/verify_10x_s.wav
new file mode 100644
index 0000000..b00d806
--- /dev/null
+++ b/vf205_access/resource/EN/wav/verify_10x_s.wav
Binary files differ
diff --git a/vf205_access/resource/EN/wav/verify_200_f.wav b/vf205_access/resource/EN/wav/verify_200_f.wav
new file mode 100644
index 0000000..acacbcf
--- /dev/null
+++ b/vf205_access/resource/EN/wav/verify_200_f.wav
Binary files differ
diff --git a/vf205_access/resource/EN/wav/verify_200_s.wav b/vf205_access/resource/EN/wav/verify_200_s.wav
new file mode 100644
index 0000000..c85a71b
--- /dev/null
+++ b/vf205_access/resource/EN/wav/verify_200_s.wav
Binary files differ
diff --git a/vf205_access/resource/EN/wav/verify_300_f.wav b/vf205_access/resource/EN/wav/verify_300_f.wav
new file mode 100644
index 0000000..eb7a0d4
--- /dev/null
+++ b/vf205_access/resource/EN/wav/verify_300_f.wav
Binary files differ
diff --git a/vf205_access/resource/EN/wav/verify_300_s.wav b/vf205_access/resource/EN/wav/verify_300_s.wav
new file mode 100644
index 0000000..ec178b7
--- /dev/null
+++ b/vf205_access/resource/EN/wav/verify_300_s.wav
Binary files differ
diff --git a/vf205_access/resource/EN/wav/verify_400_f.wav b/vf205_access/resource/EN/wav/verify_400_f.wav
new file mode 100644
index 0000000..16aa712
--- /dev/null
+++ b/vf205_access/resource/EN/wav/verify_400_f.wav
Binary files differ
diff --git a/vf205_access/resource/EN/wav/verify_400_s.wav b/vf205_access/resource/EN/wav/verify_400_s.wav
new file mode 100644
index 0000000..e4914b2
--- /dev/null
+++ b/vf205_access/resource/EN/wav/verify_400_s.wav
Binary files differ
diff --git a/vf205_access/resource/font/AlibabaPuHuiTi-2-65-Medium.ttf b/vf205_access/resource/font/AlibabaPuHuiTi-2-65-Medium.ttf
new file mode 100644
index 0000000..588a02d
--- /dev/null
+++ b/vf205_access/resource/font/AlibabaPuHuiTi-2-65-Medium.ttf
Binary files differ
diff --git a/vf205_access/resource/image/4g.png b/vf205_access/resource/image/4g.png
new file mode 100644
index 0000000..5404f82
--- /dev/null
+++ b/vf205_access/resource/image/4g.png
Binary files differ
diff --git a/vf205_access/resource/image/4g_dark.png b/vf205_access/resource/image/4g_dark.png
new file mode 100644
index 0000000..c531e9a
--- /dev/null
+++ b/vf205_access/resource/image/4g_dark.png
Binary files differ
diff --git a/vf205_access/resource/image/accessCtrl.png b/vf205_access/resource/image/accessCtrl.png
new file mode 100644
index 0000000..bd73f79
--- /dev/null
+++ b/vf205_access/resource/image/accessCtrl.png
Binary files differ
diff --git a/vf205_access/resource/image/add.png b/vf205_access/resource/image/add.png
new file mode 100644
index 0000000..3e4c4b0
--- /dev/null
+++ b/vf205_access/resource/image/add.png
Binary files differ
diff --git a/vf205_access/resource/image/advance.png b/vf205_access/resource/image/advance.png
new file mode 100644
index 0000000..5f6ae29
--- /dev/null
+++ b/vf205_access/resource/image/advance.png
Binary files differ
diff --git a/vf205_access/resource/image/app.png b/vf205_access/resource/image/app.png
new file mode 100644
index 0000000..17d3e3c
--- /dev/null
+++ b/vf205_access/resource/image/app.png
Binary files differ
diff --git a/vf205_access/resource/image/app_btn.png b/vf205_access/resource/image/app_btn.png
new file mode 100644
index 0000000..86494be
--- /dev/null
+++ b/vf205_access/resource/image/app_btn.png
Binary files differ
diff --git a/vf205_access/resource/image/app_qrcode.png b/vf205_access/resource/image/app_qrcode.png
new file mode 100644
index 0000000..5172bfb
--- /dev/null
+++ b/vf205_access/resource/image/app_qrcode.png
Binary files differ
diff --git a/vf205_access/resource/image/arrow_right.png b/vf205_access/resource/image/arrow_right.png
new file mode 100644
index 0000000..f30bb36
--- /dev/null
+++ b/vf205_access/resource/image/arrow_right.png
Binary files differ
diff --git a/vf205_access/resource/image/back.png b/vf205_access/resource/image/back.png
new file mode 100644
index 0000000..b8fd21b
--- /dev/null
+++ b/vf205_access/resource/image/back.png
Binary files differ
diff --git a/vf205_access/resource/image/back_2.png b/vf205_access/resource/image/back_2.png
new file mode 100644
index 0000000..c7343d6
--- /dev/null
+++ b/vf205_access/resource/image/back_2.png
Binary files differ
diff --git a/vf205_access/resource/image/background.jpg b/vf205_access/resource/image/background.jpg
new file mode 100644
index 0000000..64adab6
--- /dev/null
+++ b/vf205_access/resource/image/background.jpg
Binary files differ
diff --git a/vf205_access/resource/image/backspace.png b/vf205_access/resource/image/backspace.png
new file mode 100644
index 0000000..51dcd8f
--- /dev/null
+++ b/vf205_access/resource/image/backspace.png
Binary files differ
diff --git a/vf205_access/resource/image/basic.png b/vf205_access/resource/image/basic.png
new file mode 100644
index 0000000..9582177
--- /dev/null
+++ b/vf205_access/resource/image/basic.png
Binary files differ
diff --git a/vf205_access/resource/image/black_btn.png b/vf205_access/resource/image/black_btn.png
new file mode 100644
index 0000000..28dfe8c
--- /dev/null
+++ b/vf205_access/resource/image/black_btn.png
Binary files differ
diff --git a/vf205_access/resource/image/card.png b/vf205_access/resource/image/card.png
new file mode 100644
index 0000000..9931f21
--- /dev/null
+++ b/vf205_access/resource/image/card.png
Binary files differ
diff --git a/vf205_access/resource/image/close.png b/vf205_access/resource/image/close.png
new file mode 100644
index 0000000..4f3a4a1
--- /dev/null
+++ b/vf205_access/resource/image/close.png
Binary files differ
diff --git a/vf205_access/resource/image/close_small.png b/vf205_access/resource/image/close_small.png
new file mode 100644
index 0000000..f5e815b
--- /dev/null
+++ b/vf205_access/resource/image/close_small.png
Binary files differ
diff --git a/vf205_access/resource/image/cloudCert.png b/vf205_access/resource/image/cloudCert.png
new file mode 100644
index 0000000..5d3fffe
--- /dev/null
+++ b/vf205_access/resource/image/cloudCert.png
Binary files differ
diff --git a/vf205_access/resource/image/co2_f.png b/vf205_access/resource/image/co2_f.png
new file mode 100644
index 0000000..89fb8db
--- /dev/null
+++ b/vf205_access/resource/image/co2_f.png
Binary files differ
diff --git a/vf205_access/resource/image/co2_s.png b/vf205_access/resource/image/co2_s.png
new file mode 100644
index 0000000..c88502f
--- /dev/null
+++ b/vf205_access/resource/image/co2_s.png
Binary files differ
diff --git a/vf205_access/resource/image/commMgmt.png b/vf205_access/resource/image/commMgmt.png
new file mode 100644
index 0000000..0b0be70
--- /dev/null
+++ b/vf205_access/resource/image/commMgmt.png
Binary files differ
diff --git a/vf205_access/resource/image/config.png b/vf205_access/resource/image/config.png
new file mode 100644
index 0000000..0a5b62b
--- /dev/null
+++ b/vf205_access/resource/image/config.png
Binary files differ
diff --git a/vf205_access/resource/image/config_btn.png b/vf205_access/resource/image/config_btn.png
new file mode 100644
index 0000000..d9e899b
--- /dev/null
+++ b/vf205_access/resource/image/config_btn.png
Binary files differ
diff --git a/vf205_access/resource/image/delete.png b/vf205_access/resource/image/delete.png
new file mode 100644
index 0000000..5ddd206
--- /dev/null
+++ b/vf205_access/resource/image/delete.png
Binary files differ
diff --git a/vf205_access/resource/image/delete_fill.png b/vf205_access/resource/image/delete_fill.png
new file mode 100644
index 0000000..6378e4e
--- /dev/null
+++ b/vf205_access/resource/image/delete_fill.png
Binary files differ
diff --git a/vf205_access/resource/image/devInfo.png b/vf205_access/resource/image/devInfo.png
new file mode 100644
index 0000000..2b3b8ef
--- /dev/null
+++ b/vf205_access/resource/image/devInfo.png
Binary files differ
diff --git a/vf205_access/resource/image/deviceInfo.png b/vf205_access/resource/image/deviceInfo.png
new file mode 100644
index 0000000..e1fa5cb
--- /dev/null
+++ b/vf205_access/resource/image/deviceInfo.png
Binary files differ
diff --git a/vf205_access/resource/image/doorControl.png b/vf205_access/resource/image/doorControl.png
new file mode 100644
index 0000000..ce3d59b
--- /dev/null
+++ b/vf205_access/resource/image/doorControl.png
Binary files differ
diff --git a/vf205_access/resource/image/down.png b/vf205_access/resource/image/down.png
new file mode 100644
index 0000000..2715cf0
--- /dev/null
+++ b/vf205_access/resource/image/down.png
Binary files differ
diff --git a/vf205_access/resource/image/emergencyOpen.png b/vf205_access/resource/image/emergencyOpen.png
new file mode 100644
index 0000000..0b89c97
--- /dev/null
+++ b/vf205_access/resource/image/emergencyOpen.png
Binary files differ
diff --git a/vf205_access/resource/image/empty.png b/vf205_access/resource/image/empty.png
new file mode 100644
index 0000000..8dac448
--- /dev/null
+++ b/vf205_access/resource/image/empty.png
Binary files differ
diff --git a/vf205_access/resource/image/enter.png b/vf205_access/resource/image/enter.png
new file mode 100644
index 0000000..0d59c8e
--- /dev/null
+++ b/vf205_access/resource/image/enter.png
Binary files differ
diff --git a/vf205_access/resource/image/enter_b.png b/vf205_access/resource/image/enter_b.png
new file mode 100644
index 0000000..2b68ac9
--- /dev/null
+++ b/vf205_access/resource/image/enter_b.png
Binary files differ
diff --git a/vf205_access/resource/image/eth_disable.png b/vf205_access/resource/image/eth_disable.png
new file mode 100644
index 0000000..d54411f
--- /dev/null
+++ b/vf205_access/resource/image/eth_disable.png
Binary files differ
diff --git a/vf205_access/resource/image/eth_enable.png b/vf205_access/resource/image/eth_enable.png
new file mode 100644
index 0000000..cd2c35c
--- /dev/null
+++ b/vf205_access/resource/image/eth_enable.png
Binary files differ
diff --git a/vf205_access/resource/image/ethernet.png b/vf205_access/resource/image/ethernet.png
new file mode 100644
index 0000000..9a5e4ab
--- /dev/null
+++ b/vf205_access/resource/image/ethernet.png
Binary files differ
diff --git a/vf205_access/resource/image/ethernet_dark.png b/vf205_access/resource/image/ethernet_dark.png
new file mode 100644
index 0000000..accc200
--- /dev/null
+++ b/vf205_access/resource/image/ethernet_dark.png
Binary files differ
diff --git a/vf205_access/resource/image/eye-fill.png b/vf205_access/resource/image/eye-fill.png
new file mode 100644
index 0000000..af3db1c
--- /dev/null
+++ b/vf205_access/resource/image/eye-fill.png
Binary files differ
diff --git a/vf205_access/resource/image/eye-off.png b/vf205_access/resource/image/eye-off.png
new file mode 100644
index 0000000..3e5798b
--- /dev/null
+++ b/vf205_access/resource/image/eye-off.png
Binary files differ
diff --git a/vf205_access/resource/image/eye_fill.png b/vf205_access/resource/image/eye_fill.png
new file mode 100644
index 0000000..0d2db7f
--- /dev/null
+++ b/vf205_access/resource/image/eye_fill.png
Binary files differ
diff --git a/vf205_access/resource/image/eye_fill_show.png b/vf205_access/resource/image/eye_fill_show.png
new file mode 100644
index 0000000..df86b59
--- /dev/null
+++ b/vf205_access/resource/image/eye_fill_show.png
Binary files differ
diff --git a/vf205_access/resource/image/face.png b/vf205_access/resource/image/face.png
new file mode 100644
index 0000000..5a8312b
--- /dev/null
+++ b/vf205_access/resource/image/face.png
Binary files differ
diff --git a/vf205_access/resource/image/faceAdd.png b/vf205_access/resource/image/faceAdd.png
new file mode 100644
index 0000000..01c4128
--- /dev/null
+++ b/vf205_access/resource/image/faceAdd.png
Binary files differ
diff --git a/vf205_access/resource/image/faceEmpty.png b/vf205_access/resource/image/faceEmpty.png
new file mode 100644
index 0000000..5672597
--- /dev/null
+++ b/vf205_access/resource/image/faceEmpty.png
Binary files differ
diff --git a/vf205_access/resource/image/faceError.png b/vf205_access/resource/image/faceError.png
new file mode 100644
index 0000000..d88383d
--- /dev/null
+++ b/vf205_access/resource/image/faceError.png
Binary files differ
diff --git a/vf205_access/resource/image/faceRec.png b/vf205_access/resource/image/faceRec.png
new file mode 100644
index 0000000..995137c
--- /dev/null
+++ b/vf205_access/resource/image/faceRec.png
Binary files differ
diff --git a/vf205_access/resource/image/faceRec2.png b/vf205_access/resource/image/faceRec2.png
new file mode 100644
index 0000000..07a0def
--- /dev/null
+++ b/vf205_access/resource/image/faceRec2.png
Binary files differ
diff --git a/vf205_access/resource/image/factoryTest.png b/vf205_access/resource/image/factoryTest.png
new file mode 100644
index 0000000..9256b1d
--- /dev/null
+++ b/vf205_access/resource/image/factoryTest.png
Binary files differ
diff --git a/vf205_access/resource/image/failBg.png b/vf205_access/resource/image/failBg.png
new file mode 100644
index 0000000..7988953
--- /dev/null
+++ b/vf205_access/resource/image/failBg.png
Binary files differ
diff --git a/vf205_access/resource/image/grey_btn.png b/vf205_access/resource/image/grey_btn.png
new file mode 100644
index 0000000..4643664
--- /dev/null
+++ b/vf205_access/resource/image/grey_btn.png
Binary files differ
diff --git a/vf205_access/resource/image/help.png b/vf205_access/resource/image/help.png
new file mode 100644
index 0000000..460396e
--- /dev/null
+++ b/vf205_access/resource/image/help.png
Binary files differ
diff --git a/vf205_access/resource/image/idleImage.jpg b/vf205_access/resource/image/idleImage.jpg
new file mode 100644
index 0000000..64adab6
--- /dev/null
+++ b/vf205_access/resource/image/idleImage.jpg
Binary files differ
diff --git a/vf205_access/resource/image/input_bg.png b/vf205_access/resource/image/input_bg.png
new file mode 100644
index 0000000..bc3528f
--- /dev/null
+++ b/vf205_access/resource/image/input_bg.png
Binary files differ
diff --git a/vf205_access/resource/image/light_close.png b/vf205_access/resource/image/light_close.png
new file mode 100644
index 0000000..2ab29cd
--- /dev/null
+++ b/vf205_access/resource/image/light_close.png
Binary files differ
diff --git a/vf205_access/resource/image/light_open.png b/vf205_access/resource/image/light_open.png
new file mode 100644
index 0000000..960b6a4
--- /dev/null
+++ b/vf205_access/resource/image/light_open.png
Binary files differ
diff --git a/vf205_access/resource/image/localUser.png b/vf205_access/resource/image/localUser.png
new file mode 100644
index 0000000..757907e
--- /dev/null
+++ b/vf205_access/resource/image/localUser.png
Binary files differ
diff --git a/vf205_access/resource/image/lock.png b/vf205_access/resource/image/lock.png
new file mode 100644
index 0000000..5bd2b25
--- /dev/null
+++ b/vf205_access/resource/image/lock.png
Binary files differ
diff --git a/vf205_access/resource/image/logo.png b/vf205_access/resource/image/logo.png
new file mode 100644
index 0000000..150a6be
--- /dev/null
+++ b/vf205_access/resource/image/logo.png
Binary files differ
diff --git a/vf205_access/resource/image/menu_btn.png b/vf205_access/resource/image/menu_btn.png
new file mode 100644
index 0000000..b562b86
--- /dev/null
+++ b/vf205_access/resource/image/menu_btn.png
Binary files differ
diff --git a/vf205_access/resource/image/mini_app.png b/vf205_access/resource/image/mini_app.png
new file mode 100644
index 0000000..fd1cabe
--- /dev/null
+++ b/vf205_access/resource/image/mini_app.png
Binary files differ
diff --git a/vf205_access/resource/image/mini_background.png b/vf205_access/resource/image/mini_background.png
new file mode 100644
index 0000000..6036302
--- /dev/null
+++ b/vf205_access/resource/image/mini_background.png
Binary files differ
diff --git a/vf205_access/resource/image/mini_config.png b/vf205_access/resource/image/mini_config.png
new file mode 100644
index 0000000..4da2b0e
--- /dev/null
+++ b/vf205_access/resource/image/mini_config.png
Binary files differ
diff --git a/vf205_access/resource/image/mini_password.png b/vf205_access/resource/image/mini_password.png
new file mode 100644
index 0000000..9e20fec
--- /dev/null
+++ b/vf205_access/resource/image/mini_password.png
Binary files differ
diff --git a/vf205_access/resource/image/mqtt.png b/vf205_access/resource/image/mqtt.png
new file mode 100644
index 0000000..4c55959
--- /dev/null
+++ b/vf205_access/resource/image/mqtt.png
Binary files differ
diff --git a/vf205_access/resource/image/mqtt_dark.png b/vf205_access/resource/image/mqtt_dark.png
new file mode 100644
index 0000000..becda23
--- /dev/null
+++ b/vf205_access/resource/image/mqtt_dark.png
Binary files differ
diff --git a/vf205_access/resource/image/mqtt_enable.png b/vf205_access/resource/image/mqtt_enable.png
new file mode 100644
index 0000000..5d0a993
--- /dev/null
+++ b/vf205_access/resource/image/mqtt_enable.png
Binary files differ
diff --git a/vf205_access/resource/image/network.png b/vf205_access/resource/image/network.png
new file mode 100644
index 0000000..356d7f1
--- /dev/null
+++ b/vf205_access/resource/image/network.png
Binary files differ
diff --git a/vf205_access/resource/image/networkSetting.png b/vf205_access/resource/image/networkSetting.png
new file mode 100644
index 0000000..8932fce
--- /dev/null
+++ b/vf205_access/resource/image/networkSetting.png
Binary files differ
diff --git a/vf205_access/resource/image/network_dark.png b/vf205_access/resource/image/network_dark.png
new file mode 100644
index 0000000..6ddbf4e
--- /dev/null
+++ b/vf205_access/resource/image/network_dark.png
Binary files differ
diff --git a/vf205_access/resource/image/o2_f.png b/vf205_access/resource/image/o2_f.png
new file mode 100644
index 0000000..41ada63
--- /dev/null
+++ b/vf205_access/resource/image/o2_f.png
Binary files differ
diff --git a/vf205_access/resource/image/o2_s.png b/vf205_access/resource/image/o2_s.png
new file mode 100644
index 0000000..b7d4924
--- /dev/null
+++ b/vf205_access/resource/image/o2_s.png
Binary files differ
diff --git a/vf205_access/resource/image/ph3_f.png b/vf205_access/resource/image/ph3_f.png
new file mode 100644
index 0000000..286e61a
--- /dev/null
+++ b/vf205_access/resource/image/ph3_f.png
Binary files differ
diff --git a/vf205_access/resource/image/ph3_s.png b/vf205_access/resource/image/ph3_s.png
new file mode 100644
index 0000000..19dc6b5
--- /dev/null
+++ b/vf205_access/resource/image/ph3_s.png
Binary files differ
diff --git a/vf205_access/resource/image/pwd_btn.png b/vf205_access/resource/image/pwd_btn.png
new file mode 100644
index 0000000..4f6bdc7
--- /dev/null
+++ b/vf205_access/resource/image/pwd_btn.png
Binary files differ
diff --git a/vf205_access/resource/image/qrcode_small.png b/vf205_access/resource/image/qrcode_small.png
new file mode 100644
index 0000000..b33c3dd
--- /dev/null
+++ b/vf205_access/resource/image/qrcode_small.png
Binary files differ
diff --git a/vf205_access/resource/image/recQuery.png b/vf205_access/resource/image/recQuery.png
new file mode 100644
index 0000000..33e2702
--- /dev/null
+++ b/vf205_access/resource/image/recQuery.png
Binary files differ
diff --git a/vf205_access/resource/image/recordQuery.png b/vf205_access/resource/image/recordQuery.png
new file mode 100644
index 0000000..bb83bfd
--- /dev/null
+++ b/vf205_access/resource/image/recordQuery.png
Binary files differ
diff --git a/vf205_access/resource/image/rectangle.png b/vf205_access/resource/image/rectangle.png
new file mode 100644
index 0000000..615c1e6
--- /dev/null
+++ b/vf205_access/resource/image/rectangle.png
Binary files differ
diff --git a/vf205_access/resource/image/register.png b/vf205_access/resource/image/register.png
new file mode 100644
index 0000000..aaea4f7
--- /dev/null
+++ b/vf205_access/resource/image/register.png
Binary files differ
diff --git a/vf205_access/resource/image/right.png b/vf205_access/resource/image/right.png
new file mode 100644
index 0000000..27ce040
--- /dev/null
+++ b/vf205_access/resource/image/right.png
Binary files differ
diff --git a/vf205_access/resource/image/select_arrow.png b/vf205_access/resource/image/select_arrow.png
new file mode 100644
index 0000000..b1f4612
--- /dev/null
+++ b/vf205_access/resource/image/select_arrow.png
Binary files differ
diff --git a/vf205_access/resource/image/setting.png b/vf205_access/resource/image/setting.png
new file mode 100644
index 0000000..dd0d549
--- /dev/null
+++ b/vf205_access/resource/image/setting.png
Binary files differ
diff --git a/vf205_access/resource/image/setting32.png b/vf205_access/resource/image/setting32.png
new file mode 100644
index 0000000..ebb535c
--- /dev/null
+++ b/vf205_access/resource/image/setting32.png
Binary files differ
diff --git a/vf205_access/resource/image/space.png b/vf205_access/resource/image/space.png
new file mode 100644
index 0000000..3df41f6
--- /dev/null
+++ b/vf205_access/resource/image/space.png
Binary files differ
diff --git a/vf205_access/resource/image/successBg.png b/vf205_access/resource/image/successBg.png
new file mode 100644
index 0000000..ca6bb9e
--- /dev/null
+++ b/vf205_access/resource/image/successBg.png
Binary files differ
diff --git a/vf205_access/resource/image/success_fill.png b/vf205_access/resource/image/success_fill.png
new file mode 100644
index 0000000..d8c21d0
--- /dev/null
+++ b/vf205_access/resource/image/success_fill.png
Binary files differ
diff --git a/vf205_access/resource/image/sysSettings.png b/vf205_access/resource/image/sysSettings.png
new file mode 100644
index 0000000..ab9707a
--- /dev/null
+++ b/vf205_access/resource/image/sysSettings.png
Binary files differ
diff --git a/vf205_access/resource/image/sys_info.png b/vf205_access/resource/image/sys_info.png
new file mode 100644
index 0000000..24643b4
--- /dev/null
+++ b/vf205_access/resource/image/sys_info.png
Binary files differ
diff --git a/vf205_access/resource/image/systemSetting.png b/vf205_access/resource/image/systemSetting.png
new file mode 100644
index 0000000..eeff386
--- /dev/null
+++ b/vf205_access/resource/image/systemSetting.png
Binary files differ
diff --git a/vf205_access/resource/image/title_bg.png b/vf205_access/resource/image/title_bg.png
new file mode 100644
index 0000000..c4c7c8e
--- /dev/null
+++ b/vf205_access/resource/image/title_bg.png
Binary files differ
diff --git a/vf205_access/resource/image/trackFace.png b/vf205_access/resource/image/trackFace.png
new file mode 100644
index 0000000..d1bb520
--- /dev/null
+++ b/vf205_access/resource/image/trackFace.png
Binary files differ
diff --git a/vf205_access/resource/image/unlock.png b/vf205_access/resource/image/unlock.png
new file mode 100644
index 0000000..7450bf6
--- /dev/null
+++ b/vf205_access/resource/image/unlock.png
Binary files differ
diff --git a/vf205_access/resource/image/user.png b/vf205_access/resource/image/user.png
new file mode 100644
index 0000000..757907e
--- /dev/null
+++ b/vf205_access/resource/image/user.png
Binary files differ
diff --git a/vf205_access/resource/image/userGuide.png b/vf205_access/resource/image/userGuide.png
new file mode 100644
index 0000000..ccf6102
--- /dev/null
+++ b/vf205_access/resource/image/userGuide.png
Binary files differ
diff --git a/vf205_access/resource/image/userMgmt.png b/vf205_access/resource/image/userMgmt.png
new file mode 100644
index 0000000..58e2457
--- /dev/null
+++ b/vf205_access/resource/image/userMgmt.png
Binary files differ
diff --git a/vf205_access/resource/image/user_1.png b/vf205_access/resource/image/user_1.png
new file mode 100644
index 0000000..c29ea5e
--- /dev/null
+++ b/vf205_access/resource/image/user_1.png
Binary files differ
diff --git a/vf205_access/resource/image/user_f.png b/vf205_access/resource/image/user_f.png
new file mode 100644
index 0000000..98f99dd
--- /dev/null
+++ b/vf205_access/resource/image/user_f.png
Binary files differ
diff --git a/vf205_access/resource/image/user_s.png b/vf205_access/resource/image/user_s.png
new file mode 100644
index 0000000..7eb46a8
--- /dev/null
+++ b/vf205_access/resource/image/user_s.png
Binary files differ
diff --git a/vf205_access/resource/image/user_w.png b/vf205_access/resource/image/user_w.png
new file mode 100644
index 0000000..7404530
--- /dev/null
+++ b/vf205_access/resource/image/user_w.png
Binary files differ
diff --git a/vf205_access/resource/image/view_f.png b/vf205_access/resource/image/view_f.png
new file mode 100644
index 0000000..c963060
--- /dev/null
+++ b/vf205_access/resource/image/view_f.png
Binary files differ
diff --git a/vf205_access/resource/image/view_s.png b/vf205_access/resource/image/view_s.png
new file mode 100644
index 0000000..4ed96d2
--- /dev/null
+++ b/vf205_access/resource/image/view_s.png
Binary files differ
diff --git a/vf205_access/resource/image/vip.png b/vf205_access/resource/image/vip.png
new file mode 100644
index 0000000..0d73f58
--- /dev/null
+++ b/vf205_access/resource/image/vip.png
Binary files differ
diff --git a/vf205_access/resource/image/voiceBroadcast.png b/vf205_access/resource/image/voiceBroadcast.png
new file mode 100644
index 0000000..91de4a9
--- /dev/null
+++ b/vf205_access/resource/image/voiceBroadcast.png
Binary files differ
diff --git a/vf205_access/resource/image/wifi.png b/vf205_access/resource/image/wifi.png
new file mode 100644
index 0000000..61d7ccf
--- /dev/null
+++ b/vf205_access/resource/image/wifi.png
Binary files differ
diff --git a/vf205_access/resource/image/wifi_dark.png b/vf205_access/resource/image/wifi_dark.png
new file mode 100644
index 0000000..32deff1
--- /dev/null
+++ b/vf205_access/resource/image/wifi_dark.png
Binary files differ
diff --git a/vf205_access/resource/langPack.js b/vf205_access/resource/langPack.js
new file mode 100644
index 0000000..3a63542
--- /dev/null
+++ b/vf205_access/resource/langPack.js
@@ -0,0 +1,664 @@
+// 璇█鍖�
+const messages = {
+ CN: {
+ mainView: {
+ config: "閰嶇疆",
+ pwd: "瀵嗙爜",
+ app: "灏忕▼搴忕爜",
+ success: "閫氳鎴愬姛",
+ fail: "閫氳澶辫触",
+ passwordDisabled: "瀵嗙爜宸茬鐢�",
+ },
+ idleView: {
+ week: {
+ 0: "鍛ㄦ棩",
+ 1: "鍛ㄤ竴",
+ 2: "鍛ㄤ簩",
+ 3: "鍛ㄤ笁",
+ 4: "鍛ㄥ洓",
+ 5: "鍛ㄤ簲",
+ 6: "鍛ㄥ叚",
+ },
+ },
+ appView: {
+ knowed: "鎴戝凡鐭ユ檽",
+ appQrcodeLbl: "浣跨敤灏忕▼搴忎究鎹风鐞�",
+ },
+ pwdView: {
+ title: "瀵嗙爜閫氳",
+ pwd: "璇疯緭鍏ュ瘑鐮�",
+ pwdAccess: "纭",
+ success: "瀵嗙爜閫氳鎴愬姛",
+ fail: "瀵嗙爜閫氳澶辫触",
+ },
+ newPwdView: {
+ title: "璁剧疆绠$悊瀵嗙爜",
+ pwdAccess: "纭",
+ pwd: "璇疯緭鍏ュ瘑鐮�",
+ confirmPwd: "璇峰啀娆¤緭鍏ュ瘑鐮�",
+ pwdAccess: "纭",
+ tip: "娉ㄦ剰锛氭偍璁剧疆鐨勫瘑鐮佷綅鏁板簲澶т簬鎴栫瓑浜� 8 浣嶏紝濡傝烦杩囪缃紝璁惧灏嗛噰鐢ㄩ粯璁ゅ瘑鐮併��",
+ skip: "璺宠繃锛屼互鍚庤缃�",
+ success: "瀵嗙爜璁剧疆鎴愬姛",
+ fail: "瀵嗙爜璁剧疆澶辫触",
+ pwdNotMatch: "涓ゆ杈撳叆瀵嗙爜涓嶄竴鑷�",
+ },
+ identityVerificationView: {
+ title: "韬唤楠岃瘉",
+ pwd: "璇疯緭鍏ョ鐞嗗瘑鐮�",
+ pwdAccess: "纭",
+ success: "浜鸿劯楠岃瘉鎴愬姛",
+ fail: "浜鸿劯楠岃瘉澶辫触",
+ pwdLog: "瀵嗙爜鐧诲綍",
+ faceLog: "浜鸿劯鐧诲綍",
+ pwdFail: "瀵嗙爜閿欒",
+ },
+ configView: {
+ title: "璁剧疆鑿滃崟",
+ localUser: "鏈湴鐢ㄦ埛",
+ networkSetting: "缃戠粶璁剧疆",
+ doorControl: "闂ㄧ绠$悊",
+ systemSetting: "绯荤粺璁剧疆",
+ deviceInfo: "璁惧淇℃伅",
+ recordQuery: "璁板綍鏌ヨ",
+ voiceBroadcast: "璇煶鎾姤",
+ cloudCert: "浜戣瘉鍔熻兘",
+ factoryTest: "宸ュ巶娴嬭瘯",
+ help: "浣跨敤甯姪",
+ confirmExit: "纭閫�鍑�",
+ confirmExitContent: "鏄惁纭閫�鍑鸿缃彍鍗曪紵",
+ },
+ cloudCertView: {
+ title: "浜戣瘉鍔熻兘",
+ cloudCertActive: "浜戣瘉婵�娲�",
+ inputKey: "璇疯緭鍏ュ瘑閽�",
+ key: "瀵嗛挜",
+ tip: "娉ㄦ剰锛氫簯璇佸彲浠ラ�氳繃鎵嬭緭瀵嗛挜鎴栨壂鎻廫n涓撶敤浜岀淮鐮佹縺娲伙紝璇︽儏璇疯仈绯诲鏈嶃��",
+ save: "淇濆瓨",
+ },
+ doorControlView: {
+ title: "闂ㄧ绠$悊",
+ save: "淇濆瓨",
+ openDoorRelayDelay: "寮�闂ㄧ户鐢靛櫒寤舵椂",
+ antiTamperAlarm: "闃叉媶鎶ヨ",
+ input: "璇疯緭鍏�",
+ success: "淇濆瓨鎴愬姛",
+ fail: "淇濆瓨澶辫触",
+ mqttAddr: "MQTT鍦板潃",
+ mqttUser: "MQTT璐﹀彿",
+ mqttPwd: "MQTT瀵嗙爜",
+ onlineChecking: "鍦ㄧ嚎楠岃瘉",
+ onlineCheckingTimeout: "鍦ㄧ嚎楠岃瘉瓒呮椂",
+ ms: "姣"
+ },
+ helpView: {
+ title: "浣跨敤甯姪",
+ scanCode: "鎵爜璁块棶瀹樻柟鏁欑▼",
+ },
+ networkSettingView: {
+ title: "缃戠粶璁剧疆",
+ type: "缃戠粶绫诲瀷",
+ ip: "IP",
+ dhcp: "DHCP",
+ mask: "瀛愮綉鎺╃爜",
+ gateway: "缃戝叧",
+ dns: "DNS1",
+ dns2: "DNS2",
+ mac: "MAC",
+ status: "缃戠粶鐘舵��",
+ save: "淇濆瓨",
+ input: "璇疯緭鍏�",
+ ethernet: "浠ュお缃�",
+ wifi: "WiFi",
+ _4G: "4G",
+ networkUnconnected: "缃戠粶鏈繛鎺�",
+ networkConnected: "缃戠粶宸茶繛鎺�",
+ wifiName: "WiFi鍚嶇О",
+ wifiPwd: "WiFi瀵嗙爜",
+ wifiList: "WiFi鍒楄〃",
+ close: "鍏抽棴",
+ confirm: "纭",
+ fail: "淇濆瓨澶辫触",
+ success: "淇濆瓨鎴愬姛",
+ },
+ systemSettingView: {
+ title: "绯荤粺璁剧疆",
+ displaySetting: "鏄剧ず鐣岄潰璁剧疆",
+ faceRecognitionSetting: "浜鸿劯璇嗗埆璁剧疆",
+ swipeCardRecognitionSetting: "鍒峰崱璇嗗埆璁剧疆",
+ passLogSetting: "閫氳鏃ュ織璁剧疆",
+ passwordOpenDoorSetting: "瀵嗙爜寮�闂ㄨ缃�",
+ passwordManagement: "瀵嗙爜绠$悊",
+ timeSetting: "鏃堕棿璁剧疆",
+ restartDevice: "閲嶅惎璁惧",
+ restoreDefaultConfig: "鎭㈠榛樿閰嶇疆",
+ resetDevice: "閲嶇疆璁惧",
+ restart: "閲嶅惎",
+ restoreDefault: "鎭㈠",
+ reset: "閲嶇疆",
+ autoAdjustScreenBrightness: "鑷姩璋冭妭灞忓箷浜害",
+ screenBrightness: "灞忓箷浜害",
+ autoTurnOffScreen: "鑷姩鐔勫睆",
+ autoTurnOffScreenTime: "鑷姩鐔勫睆鏃堕棿",
+ autoScreenSaver: "鑷姩灞忎繚",
+ autoScreenSaverTime: "鑷姩灞忎繚鏃堕棿",
+ displayIp: "鏄剧ずIP鍦板潃",
+ displayDeviceSn: "鏄剧ず璁惧SN",
+ language: "璇█",
+ displayCode: "鏄剧ず灏忕▼搴忕爜",
+ themeMode: "宸ヤ綔涓婚",
+ save: "淇濆瓨",
+ input: "璇疯緭鍏�",
+ faceSimilarityThreshold: "浜鸿劯鐩镐技搴﹂槇鍊�",
+ livenessDetectionFunction: "娲讳綋妫�娴嬪姛鑳�",
+ livenessDetectionThreshold: "娲讳綋妫�娴嬮槇鍊�",
+ infraredImageDisplay: "绾㈠鍥惧儚鏄剧ず",
+ maskRecognition: "鍙g僵璇嗗埆",
+ maskRecognitionThreshold: "鍙g僵璇嗗埆闃堝��",
+ recognitionDistance: "璇嗗埆璺濈",
+ imageSaveType: "鍥惧儚淇濆瓨绫诲瀷",
+ saveStrangerImage: "淇濆瓨闄岀敓浜哄浘鍍�",
+ fullView: "鍏ㄦ櫙",
+ face: "浜鸿劯",
+ swipeCardRecognition: "鍒峰崱鏍搁獙",
+ passwordOpenDoor: "瀵嗙爜寮�闂�",
+ inputOriginalPassword: "璇疯緭鍏ュ師绠$悊瀵嗙爜",
+ inputNewPassword: "璇疯緭鍏ユ柊瀵嗙爜",
+ inputRepeatNewPassword: "璇烽噸澶嶆柊瀵嗙爜",
+ syncMode: "鏃跺尯",
+ ntpAddress: "NTP鍦板潃",
+ timeSyncSuccess: "鏃堕棿涓庢湇鍔″櫒鍚屾鎴愬姛",
+ success: "淇濆瓨鎴愬姛",
+ fail: "淇濆瓨澶辫触",
+ appMode: "APP妯″紡",
+ confirmation: "纭",
+ confirmRestart: "纭閲嶅惎鍚楋紵",
+ confirmRecoveryConfiguration: "纭鎭㈠榛樿閰嶇疆鍚楋紵",
+ confirmReset: "纭閲嶇疆鍚楋紵",
+ min: "鍒嗛挓"
+ },
+ deviceInfoView: {
+ title: "璁惧淇℃伅",
+ systemInfo: "绯荤粺淇℃伅",
+ dataCapacityInfo: "鏁版嵁瀹归噺淇℃伅",
+ deviceQrCode: "璁惧浜岀淮鐮�",
+ miniProgramCode: "灏忕▼搴忕爜",
+ deviceSN: "璁惧SN鍙�",
+ firmwareVersion: "鍥轰欢鐗堟湰鍙�",
+ firmwareReleaseDate: "鍥轰欢鍙戝竷鏃ユ湡",
+ deviceTotalSpace: "璁惧鎬荤┖闂�",
+ deviceUsedSpace: "宸茬敤绌洪棿",
+ deviceRemainingSpace: "鍓╀綑绌洪棿",
+ registeredPersonNum: "娉ㄥ唽浜烘暟",
+ localFaceWhiteListNum: "鏈湴浜鸿劯鐧藉悕鍗曟暟閲�",
+ localPasswordWhiteListNum: "鏈湴瀵嗙爜鐧藉悕鍗曟暟閲�",
+ localSwipeCardWhiteListNum: "鏈湴鍒峰崱鐧藉悕鍗曟暟閲�",
+ passLogTotalNum: "閫氳璁板綍鎬绘暟",
+ updateDevice: "鏇存柊璁惧",
+ currentVersion: "褰撳墠宸茬粡鏄渶鏂扮増鏈紝鏃犻渶鏇存柊鍥轰欢",
+ deviceFreeSpace: "璁惧绌洪棽绌洪棿",
+ },
+ factoryTestView: {
+ title: "宸ュ巶娴嬭瘯",
+ calibration: "鎽勫儚澶存爣瀹�",
+ },
+ localUserView: {
+ title: "鏈湴鐢ㄦ埛",
+ empty: "鏈湴灏氭湭娣诲姞浜哄憳锛�",
+ add: "鏂板浜哄憳",
+ sync: "鍚屾鏈湴浜哄憳鑷冲皬绋嬪簭",
+ search: "濮撳悕鎴朓D",
+ searchBtn: "鎼滅储",
+ edit: "缂栬緫",
+ attention: "娉ㄦ剰",
+ attentionContent:
+ "1銆佽澶囧皢鍚屾璁惧鏈湴鐨勪汉鍛樹俊鎭痋n鑷冲皬绋嬪簭鐨勫鎵瑰垪琛ㄤ腑锛屾墽琛屾垚鍔焅n鍚庤澶囩灏嗘竻闄ゅ凡缁忓綍鍏ョ殑浜哄憳淇n鎭�� \n2銆佷綔涓虹鐞嗗憳锛屾偍鍙互鍦ㄥ皬绋嬪簭涓璡n瀵规湰鍦板悓姝ョ殑浜哄憳杩涜瀹℃壒銆傚鎵筡n閫氳繃骞惰ˉ鍏呭畬蹇呰鐨勫瓧娈靛悗锛岀粍缁嘰n鍐呯殑鍏ㄩ儴璁惧锛屽皢鎷ユ湁姝ゆ鍚屾浜篭n鍛樼殑閫氳鏉冮檺銆俓n姝ゆ搷浣滄棤娉曟挙閿�锛岃闂偍纭畾瑕佸悓\n姝ュ悧锛�",
+ tip: "鎻愮ず",
+ tipContent: "璁惧灏氭湭杩炴帴缃戠粶锛岃鍏堥厤缃綉缁滐紒",
+ },
+ recordQueryView: {
+ title: "璁板綍鏌ヨ",
+ code: "浜哄憳缂栧彿",
+ time: "閫氳鏃堕棿",
+ result: "閫氳缁撴灉",
+ stranger: "闄岀敓浜�",
+ face: "浜鸿劯",
+ card: "鍒峰崱",
+ password: "瀵嗙爜",
+ qrcode: "鎵爜",
+ success: "閫氳鎴愬姛",
+ fail: "閫氳澶辫触",
+ },
+ recordQueryDetailView: {
+ title: "閫氳璁板綍璇︽儏",
+ id: "绗竴鐢ㄦ埛缂栧彿",
+ name: "绗竴鐢ㄦ埛濮撳悕",
+ idCard: "绗竴鐢ㄦ埛韬唤璇佸彿",
+ face: "绗竴鐢ㄦ埛浜鸿劯鎶撴媿",
+ secondId: "绗簩鐢ㄦ埛缂栧彿",
+ secondName: "绗簩鐢ㄦ埛濮撳悕",
+ secondIdCard: "绗簩鐢ㄦ埛韬唤璇佸彿",
+ secondFace: "绗簩鐢ㄦ埛浜鸿劯鎶撴媿",
+ time: "閫氳鏃堕棿",
+ result: "閫氳缁撴灉",
+ },
+ voiceBroadcastView: {
+ title: "璇煶鎾姤",
+ save: "淇濆瓨",
+ strangerVoice: "闄岀敓浜鸿闊�",
+ voiceMode: "璇煶妯″紡",
+ volume: "闊抽噺",
+ success: "淇濆瓨鎴愬姛",
+ fail: "淇濆瓨澶辫触",
+ },
+ confirm: {
+ ok: "纭",
+ no: "鍙栨秷",
+ upgrade: "璁惧鍗囩骇",
+ upgrading: "姝e湪鍗囩骇",
+ upgradeSuccess: "鍗囩骇鎴愬姛",
+ upgradeFail: "鍗囩骇澶辫触",
+ cloudCertActive: "浜戣瘉婵�娲�",
+ cloudCertActiveSuccess: "婵�娲绘垚鍔�",
+ cloudCertActiveFail: "婵�娲诲け璐�",
+ restartDevice: "閲嶅惎璁惧",
+ restartDeviceDis: "閰嶇疆宸叉洿鏂帮紝璁惧鍗冲皢閲嶅惎",
+ },
+ localUserAddView: {
+ title: "鐢ㄦ埛鏂板",
+ title2: "鐢ㄦ埛缂栬緫",
+ save: "淇濆瓨",
+ id: "ID",
+ name: "浜哄憳濮撳悕",
+ idCard: "韬唤璇佸彿",
+ face: "浜鸿劯鍑瘉",
+ pwd: "瀵嗙爜鍑瘉",
+ card: "鍗$墖鍑瘉",
+ type: "浜哄憳绫诲瀷",
+ input: "璇疯緭鍏�",
+ enter: "褰曞叆",
+ generate: "鐢熸垚",
+ edit: "淇敼",
+ reset: "閲嶈",
+ confirm: "纭",
+ confirmDelete: "纭鍒犻櫎",
+ confirmDeleteContent: "鏄惁纭鍒犻櫎",
+ confirmFace: "纭鍒犻櫎浜鸿劯鍑瘉鍚楋紵",
+ confirmPwd: "纭鍒犻櫎瀵嗙爜鍑瘉鍚楋紵",
+ confirmCard: "纭鍒犻櫎鍗$墖鍑瘉鍚楋紵",
+ pwdBoxLbl: "瀵嗙爜鐢熸垚涓�",
+ pwdBoxSaveBtnLbl: "鎹竴涓�",
+ pwdBoxConfirmBtnLbl: "纭畾",
+ cardBoxResetBtnLbl: "閲嶇疆",
+ cardBoxSaveBtnLbl: "淇濆瓨",
+ cardBoxLbl: "璇诲彇鍗$墖涓�",
+ cardBoxInput: "璇峰~鍐欑敤鎴峰崱鍙�",
+ delete: "鍒犻櫎",
+ success: "鎴愬姛",
+ fail: "澶辫触",
+ requiredInfo: "璇峰厛濉啓蹇呭~淇℃伅",
+ preview: "棰勮",
+ failRepeat: "澶辫触锛岀敤鎴稩D閲嶅",
+ failSimilarity: "澶辫触锛屼汉鑴哥浉浼煎害杩囬珮",
+ failCardRepeat: "澶辫触锛屽崱鐗囬噸澶�",
+ failPwdRepeat: "澶辫触锛屽瘑鐮侀噸澶�",
+ },
+ faceEnterView: {
+ title: "浜鸿劯褰曞叆",
+ faceAdd: "浜鸿劯褰曞叆涓紝璇锋瑙嗘憚鍍忓ご",
+ recogFace: "璇嗗埆鍒颁汉鑴�",
+ recogSuccess: "璇嗗埆鎴愬姛",
+ faceError: "瓒呮椂鏈幏鍙�",
+ },
+ faceService: {
+ contrastFailure: "瀵规瘮澶辫触",
+ scalingFailure: "缂╂斁澶辫触",
+ failedToSavePicture: "瀛樺偍鍥剧墖澶辫触",
+ convertToBase64Failed: "鐗瑰緛鍊艰浆base64澶辫触",
+ base64DecodingFailed: "base64瑙g爜澶辫触",
+ similarityOverheight: "鐩镐技搴﹁繃楂�",
+ fileDoesNotExist: "鏂囦欢涓嶅瓨鍦�",
+ theImageFormatIsNotSupported: "鍥剧墖鏍煎紡涓嶆敮鎸�",
+ pictureReadFailure: "鍥剧墖璇诲彇澶辫触",
+ thePictureSizeDoesNotMatch: "鍥剧墖灏哄涓嶇",
+ imageParsingFailure: "鍥剧墖瑙f瀽澶辫触",
+ imageYUVProcessingFailed: "鍥剧墖YUV澶勭悊澶辫触",
+ failedToConvertJpegToImage: "jpeg杞琲mage澶辫触",
+ faceInformationExtractionFailed: "浜鸿劯淇℃伅鎻愬彇澶辫触",
+ theFaceIsNotUnique: "鍥剧墖涓汉鑴镐俊鎭笉鍞竴",
+ }
+ },
+ EN: {
+ mainView: {
+ config: "Settings",
+ pwd: "Password",
+ app: "Mini Program Code",//灞忚斀灏忕▼搴忕爜
+ success: "Access Granted",
+ fail: "Access Denied",
+ passwordDisabled: "Password Access Disabled",
+ },
+ idleView: {
+ week: {
+ 0: "Sun",
+ 1: "Mon",
+ 2: "Tue",
+ 3: "Wed",
+ 4: "Thu",
+ 5: "Fri",
+ 6: "Sat",
+ },
+ },
+ appView: {
+ knowed: "Got it",
+ appQrcodeLbl: "Manage with Mini Program",
+ },
+ pwdView: {
+ title: "Password Access",
+ pwd: "Enter Password",
+ pwdAccess: "Confirm",
+ success: "Access Granted",
+ fail: "Access Denied",
+ },
+ newPwdView: {
+ title: "Set Admin Password",
+ pwdAccess: "Confirm",
+ pwd: "Enter Password",
+ confirmPwd: "Confirm Password",
+ pwdAccess: "Confirm",
+ tip: "Note: Password must be at least 8 characters long. Default password will be used if skipped.",
+ skip: "Skip for Now",
+ success: "Password Set Successfully",
+ fail: "Failed to Set Password",
+ pwdNotMatch: "Passwords Don't Match",
+ },
+ identityVerificationView: {
+ title: "Identity Verification",
+ pwd: "Enter Admin Password",
+ pwdAccess: "Confirm",
+ success: "Face Verification Successful",
+ fail: "Face Verification Failed",
+ pwdLog: "Password Login",
+ faceLog: "Face Login",
+ pwdFail: "Wrong Password",
+ },
+ configView: {
+ title: "Settings",
+ localUser: "Local Users",
+ networkSetting: "Network",
+ doorControl: "Access Control",
+ systemSetting: "System",
+ deviceInfo: "Device Info",
+ recordQuery: "Access Logs",
+ voiceBroadcast: "Voice Settings",
+ cloudCert: "Cloud Certificate",
+ factoryTest: "Factory Test",
+ help: "Help",
+ confirmExit: "Exit Settings",
+ confirmExitContent: "Are you sure you want to exit Settings?",
+ },
+ cloudCertView: {
+ title: "Cloud Certificate",
+ cloudCertActive: "Activate Certificate",
+ inputKey: "Enter Key",
+ key: "Key",
+ tip: "Note: Activate using key or QR code scan. Contact support for details.",
+ save: "Save",
+ },
+ doorControlView: {
+ title: "Access Control",
+ save: "Save",
+ openDoorRelayDelay: "Door Release Delay",
+ antiTamperAlarm: "Tamper Alarm",
+ input: "Enter",
+ success: "Saved",
+ fail: "Save Failed",
+ mqttAddr: "MQTT Server",
+ mqttUser: "MQTT Username",
+ mqttPwd: "MQTT Password",
+ onlineChecking: "Online Verification",
+ onlineCheckingTimeout: "Verification Timeout",
+ ms: "ms"
+ },
+ helpView: {
+ title: "Help",
+ scanCode: "Scan for Tutorial",
+ },
+ networkSettingView: {
+ title: "Network",
+ type: "Connection Type",
+ ip: "IP Address",
+ dhcp: "DHCP",
+ mask: "Subnet Mask",
+ gateway: "Gateway",
+ dns: "Primary DNS",
+ dns2: "Secondary DNS",
+ mac: "MAC Address",
+ status: "Status",
+ save: "Save",
+ input: "Enter",
+ ethernet: "Ethernet",
+ wifi: "Wi-Fi",
+ _4G: "4G",
+ networkUnconnected: "Disconnected",
+ networkConnected: "Connected",
+ wifiName: "Network Name",
+ wifiPwd: "Password",
+ wifiList: "Available Networks",
+ close: "Close",
+ confirm: "Confirm",
+ fail: "Save Failed",
+ success: "Saved",
+ },
+ systemSettingView: {
+ title: "System Settings",
+ displaySetting: "Display",
+ faceRecognitionSetting: "Face Recognition",
+ swipeCardRecognitionSetting: "Card Access",
+ passLogSetting: "Access Logs",
+ passwordOpenDoorSetting: "Password Access",
+ passwordManagement: "Password Management",
+ timeSetting: "Date & Time",
+ restartDevice: "Restart",
+ restoreDefaultConfig: "Reset to Default",
+ resetDevice: "Factory Reset",
+ restart: "Restart",
+ restoreDefault: "Reset",
+ reset: "Reset",
+ autoAdjustScreenBrightness: "Auto Brightness",
+ screenBrightness: "Brightness",
+ autoTurnOffScreen: "Auto Screen Off",
+ autoTurnOffScreenTime: "Screen Off Timer",
+ autoScreenSaver: "Screen Saver",
+ autoScreenSaverTime: "Screen Saver Timer",
+ displayIp: "Show IP Address",
+ displayDeviceSn: "Show Device SN",
+ language: "Language",
+ displayCode: "Show Program Code",
+ themeMode: "Work Theme",
+ save: "Save",
+ input: "Enter",
+ faceSimilarityThreshold: "Face Match Threshold",
+ livenessDetectionFunction: "Liveness Detection",
+ livenessDetectionThreshold: "Liveness Threshold",
+ infraredImageDisplay: "IR Display",
+ maskRecognition: "Mask Detection",
+ maskRecognitionThreshold: "Mask Detection Threshold",
+ recognitionDistance: "Detection Range",
+ imageSaveType: "Image Storage Type",
+ saveStrangerImage: "Save Stranger Photos",
+ fullView: "Full View",
+ face: "Face Only",
+ swipeCardRecognition: "Card Verification",
+ passwordOpenDoor: "Password Access",
+ inputOriginalPassword: "Enter Current Password",
+ inputNewPassword: "Enter New Password",
+ inputRepeatNewPassword: "Confirm New Password",
+ syncMode: "Time Zone",
+ ntpAddress: "NTP Server",
+ timeSyncSuccess: "Time Synced Successfully",
+ success: "Saved",
+ fail: "Failed",
+ confirmation: "Confirm",
+ confirmRestart: "Confirm Restart?",
+ confirmRecoveryConfiguration: "Reset to Default Settings?",
+ confirmReset: "Confirm Factory Reset?",
+ min: "min"
+ },
+ deviceInfoView: {
+ title: "Device Info",
+ systemInfo: "System Info",
+ dataCapacityInfo: "Storage Info",
+ deviceQrCode: "Device QR Code",
+ miniProgramCode: "Mini Program Code",
+ deviceSN: "Serial Number",
+ firmwareVersion: "Firmware Version",
+ firmwareReleaseDate: "Release Date",
+ deviceTotalSpace: "Total Storage",
+ deviceUsedSpace: "Used Storage",
+ deviceRemainingSpace: "Available Storage",
+ registeredPersonNum: "Registered Users",
+ localFaceWhiteListNum: "Face Whitelist Count",
+ localPasswordWhiteListNum: "Password Whitelist Count",
+ localSwipeCardWhiteListNum: "Card Whitelist Count",
+ passLogTotalNum: "Total Access Logs",
+ updateDevice: "Update Device",
+ currentVersion: "Device is up to date",
+ deviceFreeSpace: "Free Space",
+ },
+ factoryTestView: {
+ title: "Factory Test",
+ calibration: "Camera Calibration",
+ appMode: "APP Mode",
+ },
+ localUserView: {
+ title: "Local Users",
+ empty: "No Users Added",
+ add: "Add User",
+ sync: "Sync to Mini Program",
+ search: "Search by Name or ID",
+ searchBtn: "Search",
+ edit: "Edit",
+ attention: "Notice",
+ attentionContent:
+ "1. Local user data will be synced to the Mini Program approval list. After successful sync, local user data will be cleared.\n2. As an admin, you can approve synced users in the Mini Program. Once approved and required fields are completed, users will have access to all organization devices.\nThis action cannot be undone. Continue?",
+ tip: "Note",
+ tipContent: "Please connect to network first",
+ },
+ recordQueryView: {
+ title: "Access Logs",
+ code: "User ID",
+ time: "Time",
+ result: "Result",
+ stranger: "Unknown",
+ face: "Face",
+ card: "Card",
+ password: "Password",
+ success: "Granted",
+ fail: "Denied",
+ },
+ recordQueryDetailView: {
+ title: "Access Log Details",
+ id: "User ID",
+ name: "Name",
+ idCard: "ID Number",
+ face: "First Face Photo",
+ secondId: "Second User ID",
+ secondName: "Second Name",
+ secondIdCard: "Second ID Number",
+ secondFace: "Second Face Photo",
+ time: "Access Time",
+ result: "Result",
+ },
+ voiceBroadcastView: {
+ title: "Voice Settings",
+ save: "Save",
+ strangerVoice: "Stranger Alert",
+ voiceMode: "Voice Mode",
+ volume: "Volume",
+ success: "Saved",
+ fail: "Save Failed",
+ },
+ confirm: {
+ ok: "OK",
+ no: "Cancel",
+ upgrade: "Update Device",
+ upgrading: "Updating...",
+ upgradeSuccess: "Update Complete",
+ upgradeFail: "Update Failed",
+ cloudCertActive: "Activate Certificate",
+ cloudCertActiveSuccess: "Activate Success",
+ cloudCertActiveFail: "Activate Failed",
+ restartDevice: "Restart Device",
+ restartDeviceDis: "Configuration updated, device will restart",
+ },
+ localUserAddView: {
+ title: "Add User",
+ title2: "Edit User",
+ save: "Save",
+ id: "ID",
+ name: "Name",
+ idCard: "ID Number",
+ face: "Face ID",
+ pwd: "Password",
+ card: "Access Card",
+ type: "User Type",
+ input: "Enter",
+ enter: "Add",
+ generate: "Generate",
+ edit: "Edit",
+ reset: "Reset",
+ confirm: "Confirm",
+ confirmDelete: "Confirm Delete",
+ confirmDeleteContent: "Delete this item?",
+ confirmFace: "Delete Face ID?",
+ confirmPwd: "Delete Password?",
+ confirmCard: "Delete Access Card?",
+ pwdBoxLbl: "Generating...",
+ pwdBoxSaveBtnLbl: "Generate New",
+ pwdBoxConfirmBtnLbl: "OK",
+ cardBoxResetBtnLbl: "Reset",
+ cardBoxSaveBtnLbl: "Save",
+ cardBoxLbl: "Reading Card...",
+ cardBoxInput: "Enter Card Number",
+ delete: "Delete",
+ success: "Success",
+ fail: "Failed",
+ requiredInfo: "Required Fields Missing",
+ preview: "Preview",
+ failRepeat: "ID Already Exists",
+ failSimilarity: "Face Too Similar",
+ failCardRepeat: "Card Already Exists",
+ failPwdRepeat: "Password Already Exists",
+ },
+ faceEnterView: {
+ title: "Face Enrollment",
+ faceAdd: "Look at Camera",
+ recogFace: "Face Detected",
+ recogSuccess: "Enrollment Complete",
+ faceError: "No Face Detected",
+ },
+ calibrationView: {
+ firstCalibration: "Initial Calibration",
+ secondCalibration: "Secondary Calibration"
+ },
+ faceService: {
+ contrastFailure: "Comparison Failed",
+ scalingFailure: "Scaling Failed",
+ failedToSavePicture: "Failed to Save Image",
+ convertToBase64Failed: "Base64 Conversion Failed",
+ base64DecodingFailed: "Base64 Decode Failed",
+ similarityOverheight: "Face Too Similar",
+ fileDoesNotExist: "File Not Found",
+ theImageFormatIsNotSupported: "Unsupported Image Format",
+ pictureReadFailure: "Failed to Read Image",
+ thePictureSizeDoesNotMatch: "the picture size does not match",
+ imageParsingFailure: "image parsing failure",
+ imageYUVProcessingFailed: "image yuv processing failed",
+ failedToConvertJpegToImage: "failed to convert jpeg to image",
+ faceInformationExtractionFailed: "face information extraction failed",
+ theFaceIsNotUnique: "the face is not unique",
+ }
+ },
+};
+
+export default messages;
diff --git a/vf205_access/resource/wav/alarm.wav b/vf205_access/resource/wav/alarm.wav
new file mode 100644
index 0000000..b8fd962
--- /dev/null
+++ b/vf205_access/resource/wav/alarm.wav
Binary files differ
diff --git a/vf205_access/src/common/consts/configConst.js b/vf205_access/src/common/consts/configConst.js
new file mode 100644
index 0000000..3c22fc4
--- /dev/null
+++ b/vf205_access/src/common/consts/configConst.js
@@ -0,0 +1,99 @@
+
+/**
+ * 閰嶇疆甯搁噺鏂囦欢
+ * 瀹氫箟绯荤粺涓墍鏈夐厤缃」鐨勯敭鍊兼槧灏�
+ * 鐢ㄤ簬缁熶竴绠$悊閰嶇疆椤圭殑璺緞锛屾柟渚垮湪绯荤粺涓紩鐢�
+ */
+const configConst = {}
+
+/**
+ * 閰嶇疆椤规槧灏勮〃
+ * 鍖呭惈绯荤粺鎵�鏈夊彲閰嶇疆椤圭殑閿�煎
+ * 閿负閰嶇疆椤瑰悕绉帮紝鍊间负閰嶇疆椤瑰湪閰嶇疆鏂囦欢涓殑璺緞
+ */
+configConst.setConfig = {
+ // 鍩虹閰嶇疆
+ language: "base.language", // 璇█璁剧疆锛欳N/EN
+ password: "base.password", // 绠$悊鍛樺瘑鐮�
+ screenOff: "base.screenOff", // 鐔勫睆鏃堕棿锛屽崟浣嶅垎閽燂紝0琛ㄧず浠庝笉
+ screensaver: "base.screensaver", // 灞忓箷淇濇姢锛屽崟浣嶅垎閽燂紝0琛ㄧず浠庝笉
+ brightness: "base.brightness", // 灞忓箷浜害
+ brightnessAuto: "base.brightnessAuto", // 鑷姩浜害寮�鍏�
+ volume: "base.volume", // 闊抽噺璁剧疆
+ showIp: "base.showIp", // 鏄惁鏄剧ずIP鍦板潃
+ showSn: "base.showSn", // 鏄惁鏄剧ず搴忓垪鍙�
+ showProgramCode: "base.showProgramCode", // 鏄惁鏄剧ず绋嬪簭浠g爜
+ showIdentityCard: "base.showIdentityCard", // 鏄惁鏄剧ず韬唤璇佷俊鎭�
+ appMode: "base.appMode", // 搴旂敤妯″紡
+ luminanceWhite: "base.luminanceWhite", // 鐧藉厜浜害
+ luminanceNir: "base.luminanceNir", // 绾㈠鍏変寒搴�
+
+ // 浜鸿劯璇嗗埆閰嶇疆
+ similarity: "face.similarity", // 浜鸿劯璇嗗埆鐩镐技搴﹂槇鍊�
+ livenessOff: "face.livenessOff", // 娲讳綋妫�娴嬪紑鍏�
+ livenessVal: "face.livenessVal", // 娲讳綋妫�娴嬮槇鍊�
+ showNir: "face.showNir", // 鏄惁鏄剧ず绾㈠鍥惧儚
+ detectMask: "face.detectMask", // 鏄惁妫�娴嬪彛缃�
+ stranger: "face.stranger", // 闄岀敓浜鸿闊虫彁绀猴細["鏃犺闊�", "鎾斁璇峰厛娉ㄥ唽", "鎾斁闄岀敓浜轰綘濂�"]
+ voiceMode: "face.voiceMode", // 璇煶妯″紡锛歔"鏃犺闊�", "鎾斁鍚嶅瓧", "鎾斁闂�欒"]
+ voiceModeDate: "face.voiceModeDate", // 璇煶妯″紡鏃ユ湡璁剧疆
+
+ // MQTT閰嶇疆
+ addr: "mqtt.addr", // MQTT鏈嶅姟鍣ㄥ湴鍧�
+ mqttclientId: "mqtt.clientId", // MQTT瀹㈡埛绔疘D
+ mqttusername: "mqtt.username", // MQTT鐢ㄦ埛鍚�
+ mqttpassword: "mqtt.password", // MQTT瀵嗙爜
+ mqttqos: "mqtt.qos", // MQTT QoS绾у埆
+ mqttprefix: "mqtt.prefix", // MQTT涓婚鍓嶇紑
+ onlinecheck: "mqtt.onlinecheck", // 鍦ㄧ嚎妫�鏌ュ紑鍏�
+ timeout: "mqtt.timeout", // MQTT杩炴帴瓒呮椂
+ willTopic: "mqtt.willTopic", // MQTT閬楀槺涓婚
+
+ // 缃戠粶閰嶇疆
+ type: "net.type", // 缃戠粶绫诲瀷
+ ssid: "net.ssid", // WiFi SSID
+ psk: "net.psk", // WiFi瀵嗙爜
+ dhcp: "net.dhcp", // DHCP寮�鍏�
+ ip: "net.ip", // IP鍦板潃
+ gateway: "net.gateway", // 缃戝叧鍦板潃
+ mask: "net.mask", // 瀛愮綉鎺╃爜
+ dns: "net.dns", // DNS鏈嶅姟鍣�
+ mac: "net.mac", // MAC鍦板潃
+
+ // NTP鏃堕棿鍚屾閰嶇疆
+ ntp: "ntp.ntp", // NTP寮�鍏�
+ server: "ntp.server", // NTP鏈嶅姟鍣ㄥ湴鍧�
+ ntpInterval: "ntp.interval", // NTP鍚屾闂撮殧
+ gmt: "ntp.gmt", // GMT鏃跺尯璁剧疆
+
+ // 绯荤粺閰嶇疆
+ version: "sys.version", // 绯荤粺鐗堟湰
+ appVersion: "sys.appVersion", // 搴旂敤鐗堟湰
+ releaseTime: "sys.releaseTime", // 鍙戝竷鏃堕棿
+ heart_en: "sys.heart_en", // 蹇冭烦寮�鍏筹細1寮� 0鍏�
+ heart_time: "sys.heart_time", // 蹇冭烦闂撮殧
+ nfc: "sys.nfc", // 鍒峰崱寮�鍏筹細1寮� 0鍏�
+ pwd: "sys.pwd", // 瀵嗙爜寮�闂ㄥ紑鍏筹細1寮� 0鍏�
+ emergencyPwd: "sys.emergencyPwd", // 搴旀�ュ紑浠撳瘑鐮�
+ interval: "sys.interval", // 绯荤粺闂撮殧璁剧疆
+ strangerImage: "sys.strangerImage", // 闄岀敓浜轰繚瀛樺浘鐗囧紑鍏筹細1寮� 0鍏�
+ accessImageType: "sys.accessImageType", // 閫氳鍥剧墖绫诲瀷锛�1浜鸿劯 0鍏ㄦ櫙
+ com_passwd: "sys.com_passwd", // 閰嶇疆鐮佸瘑鐮佹牎楠�
+ nfcIdentityCardEnable: "sys.nfcIdentityCardEnable", // 浜戣瘉寮�鍏筹細3浜戣瘉鑾峰彇 1鐗╃悊鍗″彿
+
+ // 闂ㄧ閰嶇疆
+ offlineAccessNum: "access.offlineAccessNum", // 绂荤嚎寮�闂ㄦ鏁�
+ relayTime: "access.relayTime", // 缁х數鍣ㄥ姩浣滄椂闂�
+ tamperAlarm: "access.tamperAlarm" // 闃叉媶鎶ヨ寮�鍏�
+}
+
+/**
+ * 鏍规嵁閿幏鍙栭厤缃」璺緞
+ * @param {string} key - 閰嶇疆椤瑰悕绉�
+ * @returns {string|undefined} 閰嶇疆椤瑰湪閰嶇疆鏂囦欢涓殑璺緞锛屽鏋滀笉瀛樺湪鍒欒繑鍥瀠ndefined
+ */
+configConst.getValueByKey = function (key) {
+ return this.setConfig[key] || undefined;
+}
+
+export default configConst
\ No newline at end of file
diff --git a/vf205_access/src/common/utils/utils.js b/vf205_access/src/common/utils/utils.js
new file mode 100644
index 0000000..efb1810
--- /dev/null
+++ b/vf205_access/src/common/utils/utils.js
@@ -0,0 +1,132 @@
+/**
+ * 宸ュ叿鍑芥暟妯″潡
+ * 鎻愪緵绯荤粺甯哥敤鐨勫伐鍏峰嚱鏁帮紝鍖呮嫭鏂囦欢涓嬭浇銆佸瓧绗︿覆澶勭悊銆佺郴缁熸搷浣滅瓑
+ */
+import * as os from "os"
+import common from '../../../dxmodules/dxCommon.js'
+import logger from "../../../dxmodules/dxLogger.js"
+const utils = {}
+
+/**
+ * 鑾峰彇URL鏂囦欢鐨勪笅杞藉ぇ灏忥紙瀛楄妭鏁帮級
+ * @param {string} url - 鏂囦欢鐨刄RL鍦板潃
+ * @returns {number} 鏂囦欢澶у皬锛堝瓧鑺傦級锛屽鏋滆幏鍙栧け璐ュ垯杩斿洖0
+ */
+utils.getUrlFileSize = function (url) {
+ // 浣跨敤wget鍛戒护鑾峰彇鏂囦欢澶у皬淇℃伅
+ let actualSize = common.systemWithRes(`wget --spider -S ${url} 2>&1 | grep 'Length' | awk '{print $2}'`, 100).match(/\d+/g)
+ return actualSize ? parseInt(actualSize) : 0
+}
+
+/**
+ * 鍒ゆ柇鍊兼槸鍚︿负绌猴紙绌哄瓧绗︿覆銆乶ull鎴杣ndefined锛�
+ * @param {*} str - 瑕佸垽鏂殑鍊�
+ * @returns {boolean} 濡傛灉鍊间负绌哄垯杩斿洖true锛屽惁鍒欒繑鍥瀎alse
+ */
+utils.isEmpty = function (str) {
+ return (str === "" || str === null || str === undefined)
+}
+
+/**
+ * 瑙f瀽瀛楃涓蹭负JSON瀵硅薄
+ * 娉ㄦ剰锛歷alue鍐呬笉鑳芥湁"鍙�
+ * @param {string} inputString - 瑕佽В鏋愮殑瀛楃涓诧紝鏍煎紡涓簕key1=value1, key2=value2}
+ * @returns {Object} 瑙f瀽鍚庣殑JSON瀵硅薄
+ */
+utils.parseString = function (inputString) {
+ // 鑾峰彇{}鍙婂叾涔嬮棿鐨勫唴瀹�
+ inputString = inputString.slice(inputString.indexOf("{"), inputString.lastIndexOf("}") + 1)
+ // key=value姝e垯锛宬ey鏄痋w+锛堝瓧姣嶆暟瀛椾笅鍒掔嚎锛屽尯鍒ぇ灏忓啓锛夛紝=涓よ竟鍙湁绌烘牸锛寁alue鏄痋w+鎴栫浉閭讳袱涓�"涔嬮棿鐨勫唴瀹癸紙鍖呭惈"锛�
+ const keyValueRegex = /(\w+)\s*=\s*("[^"]*"|\w+(\.\w+)?)/g;
+ let jsonObject = {};
+ let match;
+
+ // 閬嶅巻鍖归厤缁撴灉锛屾瀯寤篔SON瀵硅薄
+ while ((match = keyValueRegex.exec(inputString)) !== null) {
+ let key = match[1];
+ let value = match[2]
+
+ // 鏍规嵁鍊肩殑绫诲瀷杩涜杞崲
+ if (/^\d+$/.test(value)) {
+ // 鏁板瓧绫诲瀷
+ value = parseInt(value)
+ } else if (/^\d+\.\d+$/.test(value)) {
+ // 灏忔暟绫诲瀷
+ value = parseFloat(value)
+ } else if (value == 'true') {
+ // 甯冨皵鍊紅rue
+ value = true
+ } else if (value == 'false') {
+ // 甯冨皵鍊糵alse
+ value = false
+ } else {
+ // 瀛楃涓茬被鍨嬶紝鍘婚櫎寮曞彿鍜岀┖鏍�
+ value = value.replace(/"/g, '').trim()
+ }
+
+ jsonObject[key] = value;
+ }
+
+ return jsonObject;
+}
+
+/**
+ * 绛夊緟鏂囦欢涓嬭浇瀹屾垚骞惰繘琛孧D5鏍¢獙
+ * 娉ㄦ剰锛氳秴鏃舵椂闂翠笉寰楄秴杩囧杺鐙楁椂闂达紝鍚﹀垯涓嬭浇鎱細瀵艰嚧绯荤粺閲嶅惎
+ * @param {string} update_addr - 涓嬭浇鍦板潃
+ * @param {string} downloadPath - 瀛樺偍璺緞
+ * @param {number} timeout - 瓒呮椂鏃堕棿锛堟绉掞級
+ * @param {string} update_md5 - MD5鏍¢獙鍊�
+ * @param {number} fileSize - 鏂囦欢澶у皬锛堝瓧鑺傦級
+ * @returns {boolean} 涓嬭浇缁撴灉锛歵rue琛ㄧず鎴愬姛锛宖alse琛ㄧず澶辫触
+ */
+utils.waitDownload = function (update_addr, downloadPath, timeout, update_md5, fileSize) {
+ // 鍒犻櫎鍘熸枃浠�
+ common.systemBrief(`rm -rf "${downloadPath}"`)
+
+ // 寮傛涓嬭浇鏂囦欢
+ common.systemBrief(`wget -c "${update_addr}" -O "${downloadPath}" &`)
+
+ let startTime = new Date().getTime()
+
+ // 寰幆妫�鏌ヤ笅杞借繘搴�
+ while (true) {
+ // 璁$畻宸蹭笅杞界殑鏂囦欢澶у皬
+ let size = parseInt(common.systemWithRes(`file="${downloadPath}"; [ -e "$file" ] && wc -c "$file" | awk '{print $1}' || echo "0"`, 100).split(/\s/g)[0])
+
+ // 濡傛灉鏂囦欢澶у皬杈惧埌棰勬湡锛岃繘琛孧D5鏍¢獙
+ if (size == fileSize) {
+ let ret = common.md5HashFile(downloadPath)
+ if (ret) {
+ let md5 = ret.map(v => v.toString(16).padStart(2, '0')).join('')
+ if (md5 == update_md5) {
+ // MD5鏍¢獙鎴愬姛
+ return true
+ }
+ }
+ // MD5鏍¢獙澶辫触锛屽垹闄ゆ枃浠�
+ common.systemBrief(`rm -rf "${downloadPath}"`)
+ return false
+ }
+ // 濡傛灉涓嬭浇瓒呮椂锛屽垹闄や笅杞界殑鏂囦欢骞朵笖閲嶅惎锛屽仠姝㈠紓姝ョ户缁笅杞�
+ if (new Date().getTime() - startTime > timeout) {
+ vf203.pwm.fail()
+ common.systemBrief(`rm -rf "${downloadPath}"`)
+ // 绔嬪嵆閲嶅惎
+ this.restart()
+ return false
+ }
+
+ // 鏆傚仠100姣鍚庣户缁鏌�
+ os.sleep(100)
+ }
+}
+
+/**
+ * 绔嬪嵆閲嶅惎
+ */
+utils.restart = function () {
+ common.systemBrief("reboot -f")
+}
+
+export default utils
diff --git a/vf205_access/src/config.json b/vf205_access/src/config.json
new file mode 100644
index 0000000..933977d
--- /dev/null
+++ b/vf205_access/src/config.json
@@ -0,0 +1,115 @@
+{
+ // CN/EN
+ "base.language": "CN",
+ // 绠$悊鍛樺瘑鐮�
+ "base.password": "1",
+ //鏄惁绗竴娆$櫥褰曞悗鍙� 0 鏈櫥褰� 1 宸茬櫥褰�
+ "base.firstLogin": 0,
+ // 浜鸿劯璇嗗埆鐩镐技搴�
+ "face.similarity": 0.6,
+ // 娲讳綋妫�娴�
+ "face.livenessOff": 0,
+ // 娲讳綋妫�娴嬮槇鍊硷紙0-100锛�
+ "face.livenessVal": 0,
+ "face.showNir": 0,
+ "face.detectMask": 0,
+ // ["鏃犺闊�", "鎾斁璇峰厛娉ㄥ唽", "鎾斁闄岀敓浜轰綘濂�"]
+ "face.stranger": 1,
+ // ["鏃犺闊�", "鎾斁鍚嶅瓧", "鎾斁闂�欒"]
+ "face.voiceMode": 1,
+ "face.voiceModeDate": "娆㈣繋鍏変复",
+ "mqtt.addr": "192.168.1.78:1883",
+ "mqtt.clientId": "",
+ "mqtt.username": "admin",
+ "mqtt.password": "123456",
+ "mqtt.qos": 1,
+ "mqtt.prefix": "",
+ "mqtt.onlinecheck": 0,
+ "mqtt.timeout": 5000,
+ "mqtt.willTopic": "access_device/v2/event/offline",
+ "net.type": 2,
+ "net.ssid": "",
+ "net.psk": "Fzzy@#$432..K",
+ "net.dhcp": 1,
+ "net.ip": "192.168.1.188",
+ "net.gateway": "192.168.1.1",
+ "net.mask": "255.255.255.0",
+ "net.dns": "218.4.4.4,218.2.2.2",
+ "net.mac": "",
+ // 0鍏抽棴锛�1瀹氭椂鍚屾
+ "ntp.ntp": 2,
+ "ntp.server": "192.168.1.78",
+ // 瀹氭椂鍚屾锛�24灏忔椂鍒�
+ "ntp.hour": 3,
+ "ntp.gmt": 8,
+ // mac鍦板潃
+ "sys.mac": "",
+ "sys.uuid": "",
+ "sys.sn": "",
+ "sys.model": "vf105",
+ "sys.version": "",
+ "sys.appVersion": "vf105_v11_access_2.0.0",
+ "sys.releaseTime": "2024-09-13 09:52:00",
+ "sys.heart_en": 0, //蹇冭烦1寮� 0 鍏�
+ "sys.heart_time": 30,
+ "sys.nfc": 1, //1寮� 0 鍏� 鍒峰崱寮�鍏�
+ "sys.pwd": 1, //1寮� 0 鍏� 瀵嗙爜寮�闂ㄥ紑鍏�
+ "sys.strangerImage": 1, //1寮� 0 鍏� 闄岀敓浜轰繚瀛樺浘鐗囧紑鍏�
+ "sys.accessImageType": 1, //1浜鸿劯 0 鍏ㄦ櫙 閫氳鍥剧墖绫诲瀷
+ "sys.com_passwd": "1234567887654321", // 閰嶇疆鐮佸瘑鐮佹牎楠�
+ //浜戣瘉寮�鍏� 3:浜戣瘉鑾峰彇 1:鐗╃悊鍗″彿
+ "sys.nfcIdentityCardEnable": 1,
+ "sys.interval": 1000, //鎵爜闂撮殧妯″紡闂撮殧鏃堕棿
+ "access.offlineAccessNum": 2000,
+ "access.relayTime": 2000,
+ "access.tamperAlarm": 1,
+ // 鐔勫睆鏃堕棿锛屽崟浣嶅垎閽燂紝0浠庝笉
+ "base.screenOff": 5,
+ // 灞忓箷淇濇姢锛屽崟浣嶅垎閽燂紝0浠庝笉
+ "base.screensaver": 5,
+ //灞忓箷浜害
+ "base.brightness": 70,
+ //鑷姩璋冭妭浜害 1 鑷姩璋冭妭
+ "base.brightnessAuto": 1,
+ //闊抽噺
+ "base.volume": 80,
+ // ip 鏄剧ず 1 鏄剧ず 0 闅愯棌
+ "base.showIp": 0,
+ // sn 鏄剧ず 1 鏄剧ず 0 闅愯棌
+ "base.showSn": 0,
+ //灏忕▼搴忕爜 鏄剧ず 1 鏄剧ず 0 闅愯棌
+ "base.showProgramCode": 0,
+ //浜戣瘉鍔熻兘鑿滃崟 鏄剧ず 1 鏄剧ず 0 闅愯棌
+ "base.showIdentityCard": 0,
+ // 0: 鏍囧噯妯″紡 1: 绠�绾︽ā寮�
+ "base.appMode": 1,
+ // 鐧借壊琛ュ厜鐏寒搴�
+ "base.luminanceWhite": 80,
+ // 绾㈠琛ュ厜鐏寒搴�
+ "base.luminanceNir": 80,
+ // 0:wifi 鐗堟湰 1:4G鐗堟湰 2:浠ュお缃戠増鏈� 榛樿 3鏈鍙栫姸鎬�
+ "sys.devType": 0,
+ // 涓氬姟缂栫爜瀹氫箟锛團unctionId锛�
+ "functionId": {
+ "gasDetection": "1000",
+ "safeInputControl": "2000",
+ "lightControl": "3000"
+ },
+ // 鎺ュ彛杩斿洖缂栫爜锛坮espCode锛�
+ "respCode": {
+ "success": "200",
+ "badRequest": "400",
+ "unauthorized": "401",
+ "forbidden": "403",
+ "notFound": "404",
+ "serverError": "500"
+ },
+ // 浠撳粧鍚嶇О
+ "houseName": "01鍙蜂粨",
+ // 搴撳尯鍚嶇О
+ "GranaryName": "涓ぎ鍌ㄥ绮煇鏌愮洿灞炲簱",
+ // HTTP鎺ュ彛璺緞
+ "http": {
+ "safeInputAccess": "http://192.168.1.119:80/cgi-bin/safeInputAccess"
+ }
+}
\ No newline at end of file
diff --git a/vf205_access/src/controller.js b/vf205_access/src/controller.js
new file mode 100644
index 0000000..ddb7fee
--- /dev/null
+++ b/vf205_access/src/controller.js
@@ -0,0 +1,66 @@
+/**
+ * 鎺у埗鍣ㄦ枃浠�
+ * 璐熻矗瀹氭湡鎵ц绯荤粺鍚勯┍鍔ㄧ殑寰幆鎿嶄綔锛岀‘淇濈郴缁熸甯歌繍琛�
+ */
+import log from '../dxmodules/dxLogger.js'
+import std from '../dxmodules/dxStd.js'
+import face from '../dxmodules/dxFace.js'
+import bus from '../dxmodules/dxEventBus.js'
+import driver from './driver.js'
+
+/**
+ * 杩愯鎺у埗鍣�
+ * 璁剧疆澶氫釜瀹氭椂鍣紝瀹氭湡鎵ц涓嶅悓鐨勫惊鐜换鍔�
+ */
+function run() {
+ // 姣�5ms鎵ц涓�娆′富寰幆
+ std.setInterval(() => {
+ try {
+ driver.watchdog.feed("controller", 30) // 鍠傜嫍锛岃缃�30绉掕秴鏃�
+ loop() // 鎵ц涓诲惊鐜�
+ } catch (error) {
+ log.error(error) // 璁板綍閿欒
+ }
+ }, 5)
+
+ // 姣�500ms鎵ц涓�娆$綉缁滃惊鐜�
+ std.setInterval(() => {
+ try {
+ driver.watchdog.feed("controller1", 30) // 鍠傜嫍锛岃缃�30绉掕秴鏃�
+ driver.net.loop() // 鎵ц缃戠粶寰幆
+ } catch (error) {
+ log.error(error) // 璁板綍閿欒
+ }
+ }, 500)
+
+ // 姣�1000ms鎵ц涓�娆TP寰幆
+ std.setInterval(() => {
+ try {
+ driver.watchdog.feed("controller2", 30) // 鍠傜嫍锛岃缃�30绉掕秴鏃�
+ driver.ntp.loop() // 鎵цNTP寰幆
+ } catch (error) {
+ log.error(error) // 璁板綍閿欒
+ }
+ }, 1000)
+}
+
+/**
+ * 鍚姩鎺у埗鍣�
+ */
+try {
+ run()
+} catch (error) {
+ log.error(error)
+}
+
+/**
+ * 涓诲惊鐜嚱鏁�
+ * 鎵ц鍚勯┍鍔ㄧ殑寰幆鎿嶄綔
+ */
+function loop() {
+ driver.capturer.loop() // 鎵ц鎽勫儚澶村惊鐜�
+ driver.face.loop() // 鎵ц浜鸿劯璇嗗埆寰幆
+ driver.nfc.loop() // 鎵цNFC寰幆
+ driver.mqtt.heartbeat() // 鎵цMQTT蹇冭烦
+ driver.gpiokey.loop() // 鎵цGPIO鎸夐敭寰幆
+}
diff --git a/vf205_access/src/driver.js b/vf205_access/src/driver.js
new file mode 100644
index 0000000..bda4f7c
--- /dev/null
+++ b/vf205_access/src/driver.js
@@ -0,0 +1,1226 @@
+/**
+ * 椹卞姩妯″潡鏂囦欢
+ * 鍖呭惈绯荤粺鎵�鏈夌‖浠堕┍鍔ㄧ殑鍒濆鍖栧拰鎿嶄綔鏂规硶锛屾槸绯荤粺涓庣‖浠朵氦浜掔殑鏍稿績妯″潡
+ */
+import * as os from "os"
+import capturer from '../dxmodules/dxCapturer.js'
+import cameraCalibration from '../dxmodules/dxCameraCalibration.js'
+import face from '../dxmodules/dxFace.js'
+import std from '../dxmodules/dxStd.js'
+import common from '../dxmodules/dxCommon.js'
+import utils from './common/utils/utils.js'
+import alsa from '../dxmodules/dxAlsa.js'
+import config from '../dxmodules/dxConfig.js'
+import pwm from '../dxmodules/dxPwm.js'
+import net from '../dxmodules/dxNet.js'
+import ntp from '../dxmodules/dxNtp.js'
+import mqtt from '../dxmodules/dxMqtt.js'
+import dxMap from '../dxmodules/dxMap.js'
+import logger from '../dxmodules/dxLogger.js'
+import sqliteService from "./service/sqliteService.js"
+import mqttService from "./service/mqttService.js"
+import gpio from "../dxmodules/dxGpio.js"
+import map from "../dxmodules/dxMap.js"
+import eid from "../dxmodules/dxEid.js"
+import nfc from "../dxmodules/dxNfc.js"
+import bus from "../dxmodules/dxEventBus.js"
+import dxUart from "../dxmodules/dxUart.js"
+import watchdog from "../dxmodules/dxWatchdog.js"
+import base64 from "../dxmodules/dxBase64.js"
+import dxGpioKey from "../dxmodules/dxGpioKey.js"
+import dxDriver from "../dxmodules/dxDriver.js"
+const driver = {}
+
+/**
+ * 闊抽椹卞姩妯″潡
+ * 璐熻矗闊抽鎾斁鍜岃闊冲悎鎴�
+ */
+driver.alsa = alsa
+
+/**
+ * 閰嶇疆椹卞姩妯″潡
+ * 璐熻矗鍒濆鍖栫郴缁熼厤缃紝璁剧疆绯荤粺鍩烘湰淇℃伅
+ */
+driver.config = {
+ /**
+ * 鍒濆鍖栭厤缃�
+ * 鍒濆鍖栭厤缃ā鍧楋紝璁剧疆绯荤粺MAC銆乁UID銆丼N绛夊熀鏈俊鎭�
+ */
+ init: function () {
+ config.init()
+ let mac = common.getUuid2mac(19)
+ let uuid = common.getSn(19)
+ if (!config.get('sys.mac') && mac) {
+ config.set('sys.mac', mac)
+ }
+ if (!config.get('sys.uuid') && uuid) {
+ config.set('sys.uuid', uuid)
+ }
+ //濡傛灉 sn 涓虹┖鍏堢敤璁惧 uuid
+ if (!config.get('sys.sn') && uuid) {
+ config.set('sys.sn', uuid)
+ }
+ if (!config.get('mqtt.clientId') && uuid) {
+ config.set('mqtt.clientId', uuid)
+ }
+ config.save()
+ }
+}
+/**
+ * 灞忓箷椹卞姩妯″潡
+ * 璐熻矗灞忓箷鐩稿叧鐨勪簨浠惰Е鍙戝拰鎿嶄綔
+ */
+driver.screen = {
+ /**
+ * 閫氳澶辫触
+ * 瑙﹀彂閫氳澶辫触浜嬩欢
+ */
+ accessFail: function () {
+ bus.fire('accessRes', false)
+ },
+
+ /**
+ * 閫氳鎴愬姛
+ * 瑙﹀彂閫氳鎴愬姛浜嬩欢
+ */
+ accessSuccess: function () {
+ bus.fire('accessRes', true)
+ },
+
+ /**
+ * 鍗囩骇
+ * 瑙﹀彂鍗囩骇浜嬩欢
+ * @param {object} data - 鍗囩骇鏁版嵁
+ */
+ upgrade: function (data) {
+ bus.fire('upgrade', data)
+ },
+
+ /**
+ * 鑾峰彇鍗$墖
+ * 鎾斁璇诲崱澹伴煶骞惰Е鍙戣幏鍙栧崱鐗囦簨浠�
+ * @param {string} card - 鍗$墖淇℃伅
+ */
+ getCard: function (card) {
+ driver.alsa.play(`/app/code/resource/${config.get("base.language") == "CN" ? "CN" : "EN"}/wav/read.wav`)
+ bus.fire('getCard', card)
+ },
+
+ /**
+ * 闅愯棌SN
+ * 瑙﹀彂闅愯棌SN浜嬩欢
+ * @param {object} data - 浜嬩欢鏁版嵁
+ */
+ hideSn: function (data) {
+ bus.fire('hideSn', data)
+ },
+
+ /**
+ * 搴旂敤妯″紡
+ * 瑙﹀彂搴旂敤妯″紡浜嬩欢
+ * @param {object} data - 妯″紡鏁版嵁
+ */
+ appMode: function (data) {
+ bus.fire('appMode', data)
+ },
+
+ /**
+ * 闅愯棌IP
+ * 瑙﹀彂闅愯棌IP浜嬩欢
+ * @param {object} data - 浜嬩欢鏁版嵁
+ */
+ hideIp: function (data) {
+ bus.fire('hideIp', data)
+ },
+
+ /**
+ * 鍒囨崲璇█
+ * 瑙﹀彂璇█鍒囨崲浜嬩欢
+ */
+ changeLanguage: function () {
+ bus.fire('changeLanguage')
+ }
+}
+/**
+ * SQLite椹卞姩妯″潡
+ * 璐熻矗鏁版嵁搴撳垵濮嬪寲鍜岀鐞�
+ */
+driver.sqlite = {
+ /**
+ * 鍒濆鍖栨暟鎹簱
+ * 纭繚鏁版嵁搴撹矾寰勫瓨鍦ㄥ苟鍒濆鍖朣QLite鏈嶅姟
+ */
+ init: function () {
+ std.ensurePathExists('/app/data/db/app.db')
+ sqliteService.init('/app/data/db/app.db')
+ }
+}
+
+/**
+ * PWM椹卞姩妯″潡
+ * 璐熻矗鎺у埗琛ュ厜鐏殑浜害
+ */
+driver.pwm = {
+ /**
+ * 鍒濆鍖朠WM
+ * 鍒濆鍖栫櫧鑹茶ˉ鍏夌伅鍜岀孩澶栬ˉ鍏夌伅鐨凱WM閫氶亾
+ */
+ init: function () {
+ // 鐧界伅
+ let luminanceWhite = config.get('base.luminanceWhite') ?? 80
+ pwm.request(dxDriver.PWM.WHITE_SUPPLEMENT_CHANNEL);
+ pwm.setPeriodByChannel(dxDriver.PWM.WHITE_SUPPLEMENT_CHANNEL, dxDriver.PWM.WHITE_SUPPLEMENT_PERIOD_NS)
+ pwm.enable(dxDriver.PWM.WHITE_SUPPLEMENT_CHANNEL, true);
+ pwm.setDutyByChannel(dxDriver.PWM.WHITE_SUPPLEMENT_CHANNEL, dxDriver.PWM.WHITE_SUPPLEMENT_PERIOD_NS - (dxDriver.PWM.WHITE_SUPPLEMENT_PERIOD_NS * (luminanceWhite / 100)))
+ // 绾㈠
+ let luminanceNir = config.get('base.luminanceNir') ?? 80
+ pwm.request(dxDriver.PWM.NIR_SUPPLEMENT_CHANNEL);
+ pwm.setPeriodByChannel(dxDriver.PWM.NIR_SUPPLEMENT_CHANNEL, dxDriver.PWM.NIR_SUPPLEMENT_PERIOD_NS)
+ pwm.enable(dxDriver.PWM.NIR_SUPPLEMENT_CHANNEL, true);
+ pwm.setDutyByChannel(dxDriver.PWM.NIR_SUPPLEMENT_CHANNEL, dxDriver.PWM.NIR_SUPPLEMENT_PERIOD_NS - (dxDriver.PWM.NIR_SUPPLEMENT_PERIOD_NS * (luminanceNir / 100)))
+ },
+
+ /**
+ * 璋冭妭鐧借壊琛ュ厜鐏寒搴�
+ * @param {number} value - 浜害鍊硷紝鑼冨洿0-100
+ */
+ luminanceWhite: function (value) {
+ if (value < 0 || value > 100) {
+ logger.error("[driver.pwm]: value should be between 0 and 100")
+ return
+ }
+ pwm.setDutyByChannel(dxDriver.PWM.WHITE_SUPPLEMENT_CHANNEL, dxDriver.PWM.WHITE_SUPPLEMENT_PERIOD_NS - (dxDriver.PWM.WHITE_SUPPLEMENT_PERIOD_NS * (value / 100)))
+ },
+
+ /**
+ * 璋冭妭绾㈠琛ュ厜鐏寒搴�
+ * @param {number} value - 浜害鍊硷紝鑼冨洿0-100
+ */
+ luminanceNir: function (value) {
+ if (value < 0 || value > 100) {
+ logger.error("[driver.pwm]: value should be between 0 and 100")
+ return
+ }
+ pwm.setDutyByChannel(dxDriver.PWM.NIR_SUPPLEMENT_CHANNEL, dxDriver.PWM.NIR_SUPPLEMENT_PERIOD_NS - (dxDriver.PWM.NIR_SUPPLEMENT_PERIOD_NS * (value / 100)))
+ }
+}
+
+/**
+ * ALSA椹卞姩妯″潡
+ * 璐熻矗闊抽鎾斁鍜岄煶閲忔帶鍒�
+ */
+driver.alsa = {
+ /**
+ * 鍒濆鍖栭煶棰�
+ * 鍒濆鍖朅LSA闊抽妯″潡骞惰缃煶閲�
+ */
+ init: function () {
+ alsa.init()
+ this.volume(config.get("base.volume"))
+ },
+
+ /**
+ * 鎾斁闊抽鏂囦欢
+ * @param {string} src - 闊抽鏂囦欢璺緞
+ */
+ play: function (src) {
+ alsa.play(src)
+ },
+
+ /**
+ * 鏂囨湰杞闊虫挱鏀�
+ * @param {string} text - 瑕佹挱鏀剧殑鏂囨湰
+ */
+ ttsPlay: function (text) {
+ alsa.ttsPlay(text)
+ },
+
+ /**
+ * 鑾峰彇鎴栬缃煶閲�
+ * @param {number} [volume] - 闊抽噺鍊硷紝鑼冨洿1-100
+ * @returns {number} 褰撳墠闊抽噺鍊硷紙褰撴湭鎻愪緵鍙傛暟鏃讹級
+ */
+ volume: function (volume) {
+ if (volume === undefined || volume === null) {
+ return alsa.getVolume()
+ } else {
+ function mapScore(input) {
+ // 纭繚杈撳叆鍊煎湪1-100涔嬮棿
+ if (input < 1 || input > 100) {
+ throw new Error('杈撳叆鍊煎繀椤诲湪1鍒�100涔嬮棿');
+ }
+ if (input < 60 && input > 30) {
+ input = input * 1.2
+ }
+ if (input < 30 && input > 1) {
+ input = input * 2
+ }
+ return input
+ }
+ alsa.setVolume(mapScore(volume))
+ }
+ }
+}
+
+/**
+ * 鎽勫儚澶撮┍鍔ㄦā鍧�
+ * 璐熻矗鎽勫儚澶寸殑鍒濆鍖栧拰鎿嶄綔锛屽寘鎷僵鑹叉憚鍍忓ご鍜岀孩澶栨憚鍍忓ご
+ */
+driver.capturer = {
+ /**
+ * 褰╄壊鎽勫儚澶撮厤缃�
+ */
+ options1: {
+ id: "rgb",
+ path: dxDriver.CAPTURER.RGB_PATH,
+ width: dxDriver.CAPTURER.RGB_WIDTH,
+ height: dxDriver.CAPTURER.RGB_HEIGHT,
+ preview_width: dxDriver.CAPTURER.RGB_HEIGHT,
+ preview_height: dxDriver.CAPTURER.RGB_WIDTH,
+ preview_mode: 2,
+ preview_screen_index: 0 // 鍏堝悗椤哄簭锛屾暟瀛楄秺澶ц秺鍦ㄥ墠闈�
+ },
+
+ /**
+ * 绾㈠鎽勫儚澶撮厤缃�
+ */
+ options2: {
+ id: "nir",
+ path: dxDriver.CAPTURER.NIR_PATH,
+ width: dxDriver.CAPTURER.NIR_WIDTH,
+ height: dxDriver.CAPTURER.NIR_HEIGHT,
+ preview_width: 150,
+ preview_height: 200,
+ preview_mode: 1,
+ preview_left: 605,
+ preview_top: 80,
+ preview_screen_index: 1 // 鍏堝悗椤哄簭锛屾暟瀛楄秺澶ц秺鍦ㄥ墠闈�
+ },
+
+ /**
+ * 鍒濆鍖栨憚鍍忓ご
+ * 鍒濆鍖栧僵鑹叉憚鍍忓ご鍜岀孩澶栨憚鍍忓ご
+ */
+ init: function () {
+ capturer.worker.beforeLoop(this.options1)
+ capturer.worker.beforeLoop(this.options2)
+
+ this.showNir(config.get("face.showNir"))
+ },
+
+ /**
+ * 鏄剧ず鎴栭殣钘忕孩澶栨憚鍍忓ご棰勮
+ * @param {boolean} enable - 鏄惁鍚敤绾㈠鎽勫儚澶撮瑙�
+ */
+ showNir: function (enable) {
+ capturer.capturerEnable(enable, this.options2.id)
+ },
+
+ /**
+ * 灏嗗浘鐗囨暟鎹浆鎹负鍥惧儚
+ * @param {string} base64Data - Base64缂栫爜鐨勫浘鐗囨暟鎹�
+ * @returns {number} 鍥惧儚ID
+ */
+ pictureDataToImage: function (base64Data) {
+ return capturer.pictureDataToImage(base64Data, base64Data.length, 1)
+ },
+
+ /**
+ * 灏嗗浘鍍忎繚瀛樹负鏂囦欢
+ * @param {number} imageId - 鍥惧儚ID
+ * @param {string} savePath - 淇濆瓨璺緞
+ * @returns {boolean} 鏄惁淇濆瓨鎴愬姛
+ */
+ imageToPictureFile: function (imageId, savePath) {
+ return capturer.imageToPictureFile(imageId, 1, 0, 24, savePath)
+ },
+
+ /**
+ * 灏嗗浘鍍忎繚瀛樹负鏂囦欢锛堥珮璐ㄩ噺锛�
+ * @param {number} imageId - 鍥惧儚ID
+ * @param {string} savePath - 淇濆瓨璺緞
+ * @returns {boolean} 鏄惁淇濆瓨鎴愬姛
+ */
+ imageToPictureFile2: function (imageId, savePath) {
+ return capturer.imageToPictureFile(imageId, 1, 0, 100, savePath)
+ },
+
+ /**
+ * 璋冩暣鍥惧儚鍒嗚鲸鐜�
+ * @param {number} imageId - 鍥惧儚ID
+ * @param {number} width - 鐩爣瀹藉害
+ * @param {number} height - 鐩爣楂樺害
+ * @returns {number} 璋冩暣鍚庣殑鍥惧儚ID
+ */
+ imageResizeResolution: function (imageId, width, height) {
+ return capturer.imageResizeResolution(imageId, width, height, 0)
+ },
+
+ /**
+ * 鎽勫儚澶村惊鐜�
+ * 鎵ц鎽勫儚澶寸殑寰幆鎿嶄綔
+ */
+ loop: function () {
+ capturer.worker.loop(this.options1)
+ capturer.worker.loop(this.options2)
+ }
+}
+/**
+ * NFC椹卞姩妯″潡
+ * 璐熻矗NFC鍗$墖鐨勮鍙栧拰澶勭悊
+ */
+driver.nfc = {
+ /**
+ * NFC閰嶇疆閫夐」
+ */
+ options: { m1: true, psam: false },
+
+ /**
+ * 鍒濆鍖朜FC
+ * 鍒濆鍖朜FC妯″潡锛屾牴鎹厤缃喅瀹氭槸鍚﹀惎鐢�
+ */
+ init: function () {
+ if (!config.get('sys.nfc')) {
+ logger.debug("鍒峰崱宸插叧闂�")
+ return
+ }
+ this.options.useEid = config.get("sys.nfcIdentityCardEnable") == 3 ? 1 : 0
+ nfc.worker.beforeLoop(this.options)
+ },
+
+ /**
+ * 鍒濆鍖朎ID锛堢數瀛愯韩浠借瘉锛�
+ * 鏇存柊EID閰嶇疆
+ */
+ eidInit: function () {
+ if (!config.get('sys.nfc')) {
+ return
+ }
+ if (config.get("sys.nfcIdentityCardEnable") == 3) {
+ nfc.eidUpdateConfig({ appid: "1621503", sn: config.get("sys.sn"), device_model: config.get("sys.appVersion") })
+ }
+ },
+
+ /**
+ * NFC寰幆
+ * 鎵цNFC鐨勫惊鐜搷浣滐紝鏍规嵁閰嶇疆鍐冲畾鏄惁鍚敤
+ */
+ loop: function () {
+ if (!config.get('sys.nfc')) {
+ this.loop = () => { }
+ } else {
+ this.loop = () => nfc.worker.loop(this.options)
+ }
+ }
+}
+/**
+ * 浜鸿劯璇嗗埆椹卞姩妯″潡
+ * 璐熻矗浜鸿劯璇嗗埆銆佹敞鍐屽拰鐩稿叧鍔熻兘鐨勭鐞�
+ */
+driver.face = {
+ /**
+ * 鍒濆鍖栦汉鑴歌瘑鍒�
+ * 鍒濆鍖栦汉鑴告ā鍧楋紝璁剧疆鐩稿叧鍙傛暟鍜岄厤缃�
+ */
+ init: function () {
+ common.systemBrief('mkdir -p /app/data/user/temp/')
+ let options = {
+ dbPath: "/app/data/db/face.db",
+ rgbPath: "/dev/video3",
+ nirPath: "/dev/video0",
+ capturerRgbId: "rgb",
+ capturerNirId: "nir",
+ dbMax: 5000, //浜鸿劯娉ㄥ唽涓婇檺
+ score: config.get("face.similarity"),
+ picPath: "/app/data/user/temp",
+ gThumbnailHeight: 1280 / 6,
+ gThumbnailWidth: 800 / 6,
+ // 鏄惁寮�鍚噸妫�
+ recgFaceattrEnable: 1,
+ // 娲讳綋寮�鍏�
+ livingCheckEnable: config.get("face.livenessOff"),
+ // 娲讳綋妫�娴嬮槇鍊�
+ livingScore: config.get("face.livenessVal"),
+ // 鍙g僵妫�娴嬪紑鍏�
+ detectMaskEnable: config.get("face.detectMask"),
+ // 閲嶆闂撮殧
+ recheckIntervalTime: 5000,
+ // 妫�娴嬭秴鏃�
+ detectTimeoutTime: 1000
+ }
+ face.worker.beforeLoop(options)
+
+ // 榛樿涓轰汉鑴歌瘑鍒ā寮�
+ this.mode(0)
+ // 鍏抽棴鎵�鏈変汉鑴稿姛鑳�
+ this.status(false)
+
+ // 灞忓箷浜害
+ this.setDisplayBacklight(config.get("base.brightness"))
+
+ this.screenStatus(1)
+
+ // 琛ュ厜鐏姸鎬佽窡韪�
+ let isLightOn = true
+
+ // 灞忓箷浜害鑷姩璋冭妭
+ std.setInterval(() => {
+ // 鐔勫睆鍒ゆ柇
+ let screenOff = map.get("screenOff")
+ if (screenOff.get("status") == 1) {
+ this.setDisplayBacklight(0)
+ this.screenStatus(0)
+ // 鍏抽棴琛ュ厜鐏紙浠呭綋琛ュ厜鐏綋鍓嶆槸寮�鍚姸鎬佹椂锛�
+ if (isLightOn) {
+ driver.pwm.luminanceWhite(0)
+ driver.pwm.luminanceNir(0)
+ logger.info("[driver.face]: 鐔勫睆锛屽叧闂ˉ鍏夌伅")
+ isLightOn = false
+ }
+ }
+
+ // 鍋滄鐔勫睆
+ if (screenOff.get("status") != 1) {
+ if (config.get("base.brightnessAuto") == 1) {
+ // 鑷姩璋冭妭灞忓箷浜害
+ let brightness = Math.floor(face.getEnvBrightness() / 10)
+ brightness = brightness > 100 ? 100 : brightness
+ this.setDisplayBacklight(brightness)
+ } else {
+ this.setDisplayBacklight(config.get("base.brightness"))
+ }
+ // 寮�鍚ˉ鍏夌伅锛堜粎褰撹ˉ鍏夌伅褰撳墠鏄叧闂姸鎬佹椂锛�
+ if (!isLightOn) {
+ let luminanceWhite = config.get('base.luminanceWhite') ?? 80
+ let luminanceNir = config.get('base.luminanceNir') ?? 80
+ driver.pwm.luminanceWhite(luminanceWhite)
+ driver.pwm.luminanceNir(luminanceNir)
+ logger.info(`[driver.face]: 閫�鍑虹唲灞忥紝寮�鍚ˉ鍏夌伅锛堢櫧鐏�: ${luminanceWhite}%, 绾㈠: ${luminanceNir}%锛塦)
+ isLightOn = true
+ }
+ }
+ }, 1000)
+ },
+
+ /**
+ * 鑾峰彇浜鸿劯璺熻釜妗�
+ * @returns {object} 璺熻釜妗嗕俊鎭�
+ */
+ getTrackingBox: function () {
+ return face.getTrackingBox()
+ },
+
+ /**
+ * 浜鸿劯璇嗗埆寰幆
+ * 鎵ц浜鸿劯璇嗗埆鐨勫惊鐜搷浣�
+ */
+ loop: function () {
+ // 妫�鏌ュ睆骞曟槸鍚﹀浜庣唲灞忕姸鎬�
+ let screenOff = map.get("screenOff")
+ if (screenOff && screenOff.get("status") == 1) {
+ // 鐔勫睆鐘舵�佷笅涓嶈繘琛屼汉鑴歌瘑鍒�
+ return
+ }
+ face.worker.loop()
+ },
+
+ /**
+ * 浜鸿劯绾跨▼鍚敤寮�鍏�
+ * @param {boolean} flag - 鏄惁鍚敤浜鸿劯妫�娴�
+ */
+ status: function (flag) {
+ console.log('---浜鸿劯妫�娴�' + (flag ? '寮�鍚�' : '鏆傚仠') + '---');
+ face.faceSetEnable(flag)
+ },
+
+ /**
+ * 璁剧疆浜鸿劯璇嗗埆妯″紡
+ * @param {number} value - 妯″紡鍊硷紝0涓鸿瘑鍒ā寮忥紝1涓烘敞鍐屾ā寮�
+ */
+ mode: function (value) {
+ console.log('---浜鸿劯' + (value ? '娉ㄥ唽' : '璇嗗埆') + '妯″紡---');
+ face.setRecgMode(value)
+ },
+
+ /**
+ * 浜鸿劯娉ㄥ唽
+ * @param {string} id - 鐢ㄦ埛ID
+ * @param {string} feature - 浜鸿劯鐗瑰緛
+ * @returns {boolean} 鏄惁娉ㄥ唽鎴愬姛
+ */
+ reg: function (id, feature) {
+ return face.addFaceFeatures(id, feature);
+ },
+
+ /**
+ * 鏇存柊浜鸿劯閰嶇疆
+ * @param {object} options - 閰嶇疆閫夐」
+ */
+ faceUpdateConfig: function (options) {
+ console.log("鏇存柊浜鸿劯閰嶇疆", JSON.stringify(options));
+ face.faceUpdateConfig(options)
+ },
+
+ /**
+ * 璁剧疆灞忓箷浜害
+ * @param {number} brightness - 浜害鍊�
+ */
+ setDisplayBacklight: function (brightness) {
+ brightness = brightness < 2 ? 2 : brightness
+ face.setDisplayBacklight(brightness)
+ },
+
+ /**
+ * 閫氳繃鍥剧墖鏂囦欢娉ㄥ唽浜鸿劯
+ * @param {string} userId - 鐢ㄦ埛ID
+ * @param {string} picPath - 鍥剧墖璺緞
+ * @returns {boolean} 鏄惁娉ㄥ唽鎴愬姛
+ */
+ registerFaceByPicFile: function (userId, picPath) {
+ return face.registerFaceByPicFile(userId, picPath)
+ },
+
+ /**
+ * 娓呯┖浜鸿劯鏁版嵁
+ * @returns {boolean} 鏄惁娓呯┖鎴愬姛
+ */
+ clean: function () {
+ // 娓呯┖浜鸿劯锛岄渶瑕佸湪鍒濆鍖栦汉鑴哥粍浠朵箣鍓嶆墠鑳芥墽琛岋紝鍚﹀垯鎶ラ敊
+ face.faceFeaturesClean()
+ common.systemBrief("rm -rf /app/data/db/face.db")
+ return !std.exist("/app/data/db/face.db")
+ },
+
+ /**
+ * 鍒犻櫎鎸囧畾鐢ㄦ埛鐨勪汉鑴告暟鎹�
+ * @param {string} userId - 鐢ㄦ埛ID
+ * @returns {boolean} 鏄惁鍒犻櫎鎴愬姛
+ */
+ delete: function (userId) {
+ return face.deleteFaceFeatures(userId)
+ },
+
+ /**
+ * 璁剧疆灞忓箷鐘舵��
+ * @param {boolean} status - 鏄惁鍚敤灞忓箷
+ */
+ screenStatus: function (status) {
+ if (status) {
+ face.setPowerMode(0)
+ } else {
+ face.setPowerMode(1)
+ }
+ face.setEnableStatus(status)
+ },
+
+ /**
+ * 灏嗘枃浠惰浆鎹负base64缂栫爜
+ * @param {string} filePath - 鏂囦欢璺緞
+ * @returns {string} Base64缂栫爜鐨勬枃浠跺唴瀹�
+ */
+ fileToBase64: function (filePath) {
+ function fileToUint8Array(filename) {
+ // 璇诲彇鏂囦欢
+ const file = std.open(filename, "rb");
+ if (!file) {
+ throw new Error("鏃犳硶鎵撳紑鏂囦欢");
+ }
+
+ // 鑾峰彇鏂囦欢澶у皬
+ const size = std.seek(file, 0, std.SEEK_END)
+ std.seek(file, 0, std.SEEK_SET)
+
+ // 妫�鏌ユ枃浠跺ぇ灏忔槸鍚︽湁鏁�
+ if (size <= 0) {
+ std.close(file);
+ throw new Error("鏂囦欢澶у皬鏃犳晥");
+ }
+
+ // 鍒涘缓 ArrayBuffer 骞惰鍙栨枃浠跺唴瀹�
+ const buffer = new ArrayBuffer(size);
+ const array = new Uint8Array(buffer);
+ std.read(file, array.buffer, 0, size);
+
+ std.close(file);
+
+ return array;
+ }
+
+ try {
+ // 妫�鏌ユ枃浠惰矾寰勬槸鍚﹀瓨鍦�
+ if (!filePath) {
+ throw new Error("鏂囦欢璺緞涓虹┖");
+ }
+ const data = fileToUint8Array(filePath);
+ return base64.fromUint8Array(data);
+ } catch (error) {
+ logger.info("鏂囦欢杞珺ase64澶辫触: " + error.message);
+ return "";
+ }
+ }
+}
+
+/**
+ * 缃戠粶椹卞姩妯″潡
+ * 璐熻矗缃戠粶杩炴帴鍜岀鐞�
+ */
+driver.net = {
+ /**
+ * 鍒濆鍖栫綉缁�
+ * 鍒濆鍖栫綉缁滄ā鍧楋紝璁剧疆缃戠粶閰嶇疆
+ */
+ init: function () {
+ let dns = config.get("net.dns").split(",")
+ let option = {
+ type: config.get("net.type"),
+ dhcp: config.get("net.dhcp"),
+ ip: config.get("net.ip"),
+ gateway: config.get("net.gateway"),
+ netmask: config.get("net.mask"),
+ dns0: dns[0],
+ dns1: dns[1],
+ macAddr: common.getUuid2mac()
+ }
+ logger.info("鏇存柊鑱旂綉閰嶇疆锛�", JSON.stringify(option));
+ net.worker.beforeLoop(option)
+ config.set("net.mac", common.getUuid2mac())
+ if (config.get("net.type") == 2) {
+ //wifi鍙栭厤缃枃浠跺幓杩炴帴
+ let ssid = utils.isEmpty(config.get('net.ssid')) ? "ssid" : config.get('net.ssid')
+ let psk = utils.isEmpty(config.get('net.psk')) ? "psk" : config.get('net.psk')
+ driver.net.netConnectWifiSsid(ssid, psk)
+ }
+ // 瑙e喅缃戠粶鍒囨崲鐘舵�佷笉瀵�
+ std.setInterval(() => {
+ let status = net.getStatus()
+ if (status.status != map.get("NET").get("status")) {
+ status.type = config.get("net.type")
+ bus.fire(net.STATUS_CHANGE, status)
+ }
+ }, 1000)
+ },
+
+ /**
+ * 鍒囨崲缃戠粶绫诲瀷
+ * 鍒囨崲缃戠粶绫诲瀷骞堕厤缃浉搴旂殑缃戠粶鍙傛暟
+ */
+ changeNetType: function () {
+ // 鍔犻攣
+ if (map.get("NET").get("changeType") == "Y") {
+ return
+ }
+ map.get("NET").put("changeType", "Y")
+ let type = config.get("net.type")
+ logger.info("鍒囨崲缃戠粶", type);
+ [1, 2, 4].filter(v => v != type).forEach(v => {
+ logger.info("鍏抽棴缃戝崱", v, net.cardEnable(v, false));
+ })
+ logger.info("璁剧疆涓荤綉鍗�", type, net.setMasterCard(type));
+ logger.info("寮�鍚綉鍗�", type, net.cardEnable(type, true));
+ if (type == 2) {
+ //wifi鍙栭厤缃枃浠跺幓杩炴帴
+ let ssid = utils.isEmpty(config.get('net.ssid')) ? "ssid" : config.get('net.ssid')
+ let psk = utils.isEmpty(config.get('net.psk')) ? "psk" : config.get('net.psk')
+ logger.info("杩炴帴wifi", ssid, psk);
+ net.netConnectWifiSsid(ssid, psk)
+
+ // 绛夊緟WiFi杩炴帴鎴愬姛鍚庡啀璁剧疆缃戠粶妯″紡
+ std.setTimeout(() => {
+ let dns = config.get("net.dns").split(",")
+ net.setModeByCard(type, config.get("net.dhcp"), config.get("net.dhcp") == 1 ? {
+ ip: config.get("net.ip"),
+ gateway: config.get("net.gateway"),
+ netmask: config.get("net.mask"),
+ dns0: dns[0],
+ dns1: dns[1],
+ } : undefined)
+ }, 3000); // 绛夊緟3绉掕WiFi杩炴帴鎴愬姛
+ } else if (type == 1) {
+ // 浠ュお缃戠洿鎺ヨ缃綉缁滄ā寮�
+ let dns = config.get("net.dns").split(",")
+ net.setModeByCard(type, config.get("net.dhcp"), config.get("net.dhcp") == 1 ? {
+ ip: config.get("net.ip"),
+ gateway: config.get("net.gateway"),
+ netmask: config.get("net.mask"),
+ dns0: dns[0],
+ dns1: dns[1],
+ } : undefined)
+ }
+ map.get("NET").del("changeType")
+ },
+
+ /**
+ * 鍒濆鍖朎ID缃戠粶
+ * 閫�鍑虹綉缁滃苟閲嶅惎鐩稿叧鏈嶅姟
+ */
+ eidInit: function () {
+ net.exit();
+ common.systemWithRes(`pkill -9 -f 'wpa_supplicant|udhcpc'`, 5)
+ },
+
+ /**
+ * 鑾峰彇缃戠粶鐘舵��
+ * @returns {boolean} 鏄惁杩炴帴鎴愬姛
+ */
+ getStatus: function () {
+ let status = net.getStatus()
+ if (status.connected == true && status.status == 4) {
+ return true
+ } else {
+ return false
+ }
+
+ },
+
+ /**
+ * 杩炴帴WiFi
+ * @param {string} ssid - WiFi鍚嶇О
+ * @param {string} psk - WiFi瀵嗙爜
+ */
+ netConnectWifiSsid: function (ssid, psk) {
+ net.netConnectWifiSsid(ssid, psk, "")
+ },
+
+ /**
+ * 鑾峰彇WiFi鍒楄〃
+ * @returns {array} WiFi鍒楄〃
+ */
+ netGetWifiSsidList: function () {
+ if (!driver.net.getStatus()) {
+ //濡傛灉 wifi 杩炴帴澶辫触 鑾峰彇鍒楄〃浼氬け璐ラ渶瑕佸厛閿�姣�
+ net.netDisconnetWifi()
+ }
+ let result = net.netGetWifiSsidList(1000, 5)
+ if (!result || !result.results || result.results.length === 0) {
+ return [];
+ }
+ let wifiList = []; // 鍒濆鍖杦ifiList涓烘暟缁�
+ result.results.forEach(element => wifiList.push(element.ssid)); // 浣跨敤push鏂规硶娣诲姞ssid鍒版暟缁�
+ return wifiList;
+ },
+
+ /**
+ * 閲嶇疆缃戝崱
+ */
+ cardReset: function () {
+ // net.netCardReset(2,1)
+ },
+
+ /**
+ * 缃戠粶寰幆
+ * 鎵ц缃戠粶鐨勫惊鐜搷浣�
+ */
+ loop: function () {
+ net.worker.loop()
+ }
+}
+
+/**
+ * NTP椹卞姩妯″潡
+ * 璐熻矗缃戠粶鏃堕棿鍚屾
+ */
+driver.ntp = {
+ /**
+ * NTP寰幆
+ * 鍒濆鍖朜TP妯″潡骞舵墽琛屾椂闂村悓姝ユ搷浣�
+ */
+ loop: function () {
+ // 姣忕閽熷垽鏂椂闂达紝濡傛灉鏃跺樊澶т簬2绉掑垯杩涜浜嗗鏃�
+ let last = new Date().getTime()
+ dxMap.get("NTP_SYNC").put("syncTime", last)
+ std.setInterval(() => {
+ let now = new Date().getTime()
+ let diff = now - last
+ if (diff > 2000) {
+ dxMap.get("NTP_SYNC").put("syncTime", now)
+ last = now
+ }
+ }, 1000)
+
+ ntp.beforeLoop(config.get("ntp.server"), 9999999999999)
+ this.ntpHour = config.get('ntp.hour')
+ this.flag = true
+ driver.ntp.loop = () => {
+ if (config.get("ntp.ntp")) {
+ ntp.loop()
+ if (new Date().getHours() == this.ntpHour && this.flag) {
+ // 瀹氭椂鍚屾锛岀珛鍗冲悓姝ヤ竴娆℃椂闂�
+ ntp.syncnow = true
+ this.flag = false
+ }
+ if (new Date().getHours() != this.ntpHour) {
+ // 绛夎繃浜嗚繖涓皬鏃跺啀娆″厑璁稿鏃�
+ this.flag = true
+ }
+ }
+ }
+ }
+}
+/**
+ * 鍚屾椹卞姩妯″潡
+ * 鎻愪緵寮傛杞悓姝ョ殑瀹炵幇
+ */
+driver.sync = {
+ /**
+ * 寮傛杞悓姝ヨ姹�
+ * @param {string} topic - 涓婚
+ * @param {number} timeout - 瓒呮椂鏃堕棿锛堟绉掞級
+ * @returns {any} 鍝嶅簲鏁版嵁
+ */
+ request: function (topic, timeout) {
+ let map = dxMap.get("SYNC")
+ let count = 0
+ let data = map.get(topic)
+ while (utils.isEmpty(data) && count * 10 < timeout) {
+ data = map.get(topic)
+ std.sleep(10)
+ count += 1
+ }
+ let res = map.get(topic)
+ map.del(topic)
+ return res
+ },
+
+ /**
+ * 鍚屾鍝嶅簲
+ * @param {string} topic - 涓婚
+ * @param {any} data - 鍝嶅簲鏁版嵁
+ */
+ response: function (topic, data) {
+ let map = dxMap.get("SYNC")
+ map.put(topic, data)
+ }
+}
+/**
+ * MQTT椹卞姩妯″潡
+ * 璐熻矗MQTT閫氫俊鍜屾秷鎭鐞�
+ */
+driver.mqtt = {
+ /**
+ * 鍒濆鍖朚QTT
+ * 鍒濆鍖朚QTT妯″潡锛岃缃繛鎺ュ弬鏁�
+ */
+ init: function () {
+ mqtt.run({ mqttAddr: config.get("mqtt.addr"), clientId: config.get('mqtt.clientId'), subs: mqttService.getTopics(), username: config.get("mqtt.username"), password: config.get("mqtt.password"), qos: config.get("mqtt.qos"), willTopic: config.get("mqtt.willTopic"), willMessage: JSON.stringify({ "uuid": config.get("sys.uuid") }) })
+ },
+
+ /**
+ * 鍒濆鍖朎ID鐨凪QTT
+ * 閿�姣丮QTT杩炴帴
+ */
+ eidInit: function () {
+ mqtt.destroy()
+ },
+
+ /**
+ * 鍙戦�丮QTT娑堟伅
+ * @param {string} topic - 娑堟伅涓婚
+ * @param {any} payload - 娑堟伅杞借嵎
+ */
+ send: function (topic, payload,) {
+ logger.info("[driver.mqtt] send :", topic)
+ mqtt.send(topic, payload)
+ },
+
+ /**
+ * 鑾峰彇鍦ㄧ嚎妫�鏌�
+ * @returns {any} 鍦ㄧ嚎妫�鏌ョ粨鏋�
+ */
+ getOnlinecheck: function () {
+ let timeout = config.get("mqtt.timeout")
+ timeout = utils.isEmpty(timeout) ? 2000 : timeout
+ return driver.sync.request("mqtt.getOnlinecheck", timeout)
+ },
+
+ /**
+ * 鍦ㄧ嚎妫�鏌ュ洖澶�
+ * @param {any} data - 鍥炲鏁版嵁
+ */
+ getOnlinecheckReply: function (data) {
+ driver.sync.response("mqtt.getOnlinecheck", data)
+ },
+
+ /**
+ * 鑾峰彇MQTT杩炴帴鐘舵��
+ * @returns {boolean} 鏄惁杩炴帴鎴愬姛
+ */
+ getStatus: function () {
+ return mqtt.isConnected()
+ },
+
+ /**
+ * MQTT蹇冭烦
+ * 鍙戦�佸績璺虫秷鎭紝淇濇寔杩炴帴
+ */
+ heartbeat: function () {
+ if (utils.isEmpty(this.heart_en)) {
+ let heart_en = config.get('sys.heart_en')
+ this.heart_en = utils.isEmpty(heart_en) ? 0 : heart_en
+ let heart_time = config.get('sys.heart_time')
+ this.heart_time = utils.isEmpty(heart_time) ? 30 : heart_time < 30 ? 30 : heart_time
+ }
+ if (utils.isEmpty(this.lastHeartbeat)) {
+ this.lastHeartbeat = 0
+ }
+ if (this.heart_en === 1 && (new Date().getTime() - this.lastHeartbeat >= (this.heart_time * 1000))) {
+ this.lastHeartbeat = new Date().getTime()
+ driver.mqtt.send("access_device/v2/event/heartbeat", JSON.stringify(mqttService.mqttReply(std.genRandomStr(10), undefined, mqttService.CODE.S_000)))
+ }
+ }
+}
+
+/**
+ * GPIO椹卞姩妯″潡
+ * 璐熻矗GPIO璁惧鐨勬帶鍒讹紝涓昏鏄户鐢靛櫒鎺у埗
+ */
+driver.gpio = {
+ /**
+ * 鍒濆鍖朑PIO
+ * 鍒濆鍖朑PIO妯″潡骞惰姹傜户鐢靛櫒寮曡剼
+ */
+ init: function () {
+ gpio.init()
+ gpio.request(dxDriver.GPIO.RELAY0)
+ },
+
+ /**
+ * 鎵撳紑缁х數鍣�
+ * 鎵撳紑缁х數鍣ㄥ苟鍦ㄦ寚瀹氭椂闂村悗鑷姩鍏抽棴
+ */
+ open: function () {
+ logger.info("[GPIO]: 鎵撳紑缁х數鍣�")
+ let result = gpio.setValue(dxDriver.GPIO.RELAY0, 1);
+ logger.info("[GPIO]: 鎵撳紑缁х數鍣ㄧ粨鏋�: " + result)
+
+ let relayTime = config.get("access.relayTime")
+
+ std.setTimeout(() => {
+ logger.info("[GPIO]: 鍏抽棴缁х數鍣�")
+ let closeResult = gpio.setValue(dxDriver.GPIO.RELAY0, 0);
+ logger.info("[GPIO]: 鍏抽棴缁х數鍣ㄧ粨鏋�: " + closeResult)
+ }, relayTime)
+ },
+
+ /**
+ * 鍏抽棴缁х數鍣�
+ * 绔嬪嵆鍏抽棴缁х數鍣�
+ */
+ close: function () {
+ gpio.setValue(dxDriver.GPIO.RELAY0, 0)
+ }
+}
+
+/**
+ * UART485椹卞姩妯″潡
+ * 璐熻矗UART485閫氫俊
+ */
+driver.uart485 = {
+ /**
+ * UART485 ID
+ */
+ id: 'uart485',
+
+ /**
+ * 鍒濆鍖朥ART485
+ * 鍒濆鍖朥ART485妯″潡骞惰缃�氫俊鍙傛暟
+ */
+ init: function () {
+ dxUart.runvg({ id: this.id, type: dxUart.TYPE.UART, path: '/dev/ttySLB2', result: 0, passThrough: false })
+ std.sleep(2000)
+ dxUart.ioctl(6, '115200-8-N-1', this.id)
+ },
+
+ /**
+ * 鎺у埗UART485
+ * @param {string} data - 鎺у埗鏁版嵁
+ */
+ ioctl: function (data) {
+ dxUart.ioctl(6, data, this.id)
+ },
+
+ /**
+ * 鍙戦�佹暟鎹�
+ * @param {string} data - 瑕佸彂閫佺殑鏁版嵁
+ */
+ send: function (data) {
+ dxUart.send(data, this.id)
+ },
+
+ /**
+ * 鍙戦�乂G鏁版嵁
+ * @param {object|string} data - 瑕佸彂閫佺殑鏁版嵁
+ */
+ sendVg: function (data) {
+ if (typeof data == 'object') {
+ data.length = data.length ? data.length : (data.data ? data.data.length / 2 : 0)
+ }
+ dxUart.sendVg(data, this.id)
+ }
+}
+
+/**
+ * UARTCode椹卞姩妯″潡
+ * 璐熻矗UART鏉$爜鎵弿閫氫俊
+ */
+driver.uartCode = {
+ /**
+ * UARTCode ID
+ */
+ id: 'uartCode',
+
+ /**
+ * 鍒濆鍖朥ARTCode
+ * 鍒濆鍖朥ARTCode妯″潡骞惰缃�氫俊鍙傛暟
+ */
+ init: function () {
+ dxUart.runvg({ id: this.id, type: dxUart.TYPE.UART, path: '/dev/ttySLB1', result: 0, passThrough: false })
+ std.sleep(500)
+ dxUart.ioctl(6, '115200-8-N-1', this.id)
+ },
+
+ /**
+ * 鎺у埗UARTCode
+ * @param {string} data - 鎺у埗鏁版嵁
+ */
+ ioctl: function (data) {
+ dxUart.ioctl(6, data, this.id)
+ },
+
+ /**
+ * 鍙戦�佹暟鎹�
+ * @param {string} data - 瑕佸彂閫佺殑鏁版嵁
+ */
+ send: function (data) {
+ dxUart.send(data, this.id)
+ },
+
+ /**
+ * 鍙戦�乂G鏁版嵁
+ * @param {object|string} data - 瑕佸彂閫佺殑鏁版嵁
+ */
+ sendVg: function (data) {
+ if (typeof data == 'object') {
+ data.length = data.length ? data.length : (data.data ? data.data.length / 2 : 0)
+ }
+ dxUart.sendVg(data, this.id)
+ },
+}
+
+/**
+ * EID椹卞姩妯″潡
+ * 璐熻矗鐢靛瓙韬唤璇佺浉鍏虫搷浣�
+ */
+driver.eid = {
+ /**
+ * EID ID
+ */
+ id: "eid",
+
+ /**
+ * 婵�娲籈ID
+ * @param {string} sn - 璁惧SN
+ * @param {string} version - 鐗堟湰鍙�
+ * @param {string} mac - MAC鍦板潃
+ * @param {string} codeMsg - 婵�娲荤爜
+ * @returns {boolean} 鏄惁婵�娲绘垚鍔�
+ */
+ active: function (sn, version, mac, codeMsg) {
+ return eid.active(sn, version, mac, codeMsg)
+ },
+
+ /**
+ * 鑾峰彇EID鐗堟湰
+ * @returns {string} EID鐗堟湰
+ */
+ getVerion: function () {
+ return eid.getVersion()
+ }
+}
+/**
+ * GPIO鎸夐敭椹卞姩妯″潡
+ * 璐熻矗GPIO鎸夐敭鐨勫垵濮嬪寲鍜屽惊鐜鐞�
+ */
+driver.gpiokey = {
+ /**
+ * 鍒濆鍖朑PIO鎸夐敭
+ * 鍒濆鍖朑PIO鎸夐敭妯″潡
+ */
+ init: function () {
+ dxGpioKey.worker.beforeLoop()
+ },
+
+ /**
+ * GPIO鎸夐敭寰幆
+ * 鎵цGPIO鎸夐敭鐨勫惊鐜搷浣�
+ */
+ loop: function () {
+ dxGpioKey.worker.loop()
+ },
+}
+/**
+ * 鐪嬮棬鐙楅┍鍔ㄦā鍧�
+ * 璐熻矗绯荤粺鐪嬮棬鐙楃殑鍒濆鍖栧拰鍠傜嫍鎿嶄綔
+ */
+driver.watchdog = {
+ /**
+ * 鍒濆鍖栫湅闂ㄧ嫍
+ * 鍒濆鍖栫湅闂ㄧ嫍妯″潡
+ */
+ init: function () {
+ // watchdog.open(1)
+ // watchdog.enable(1)
+ // watchdog.start(20000)
+ },
+
+ /**
+ * 鐪嬮棬鐙楀惊鐜�
+ * 鎵ц鐪嬮棬鐙楃殑寰幆鎿嶄綔
+ */
+ loop: function () {
+ // watchdog.loop(1)
+ },
+
+ /**
+ * 鍠傜嫍
+ * 鍚戠湅闂ㄧ嫍鍙戦�佸杺鐙椾俊鍙凤紝闃叉绯荤粺閲嶅惎
+ * @param {string} flag - 鍠傜嫍鏍囧織
+ * @param {number} timeout - 瓒呮椂鏃堕棿
+ */
+ feed: function (flag, timeout) {
+ // if (utils.isEmpty(this["feedTime" + flag]) || new Date().getTime() - this["feedTime" + flag] > 2000) {
+ // // 闄嶄綆鍠傜嫍棰戠巼锛岄棿闅�2绉掑杺涓�娆�
+ // this["feedTime" + flag] = new Date().getTime()
+ // watchdog.feed(flag, timeout)
+ // }
+ }
+}
+
+/**
+ * 鑷姩閲嶅惎椹卞姩妯″潡
+ * 璐熻矗绯荤粺鐨勮嚜鍔ㄩ噸鍚姛鑳�
+ */
+driver.autoRestart = {
+ /**
+ * 涓婃閲嶅惎妫�鏌ョ殑灏忔椂鏁�
+ */
+ lastRestartCheck: new Date().getHours(), // 鍒濆鍖栦负褰撳墠灏忔椂鏁帮紝鑰屼笉鏄�0
+
+ /**
+ * 鍒濆鍖栬嚜鍔ㄩ噸鍚�
+ * 鍒濆鍖栬嚜鍔ㄩ噸鍚ā鍧楋紝璁剧疆瀹氭椂閲嶅惎鍔熻兘
+ */
+ init: function () {
+ // std.setInterval(() => { // 妫�鏌ユ槸鍚﹂渶瑕佹暣鐐归噸鍚�
+ // const now = new Date()
+ // const currentHour = now.getHours()
+ // // 鍙湁褰撳皬鏃舵暟绛変簬璁惧畾鍊硷紝涓斾笉鏄笂娆℃鏌ヨ繃鐨勫皬鏃舵椂鎵嶆墽琛�
+ // if (currentHour === 3 && currentHour !== this.lastRestartCheck && now.getMinutes() === 0) {
+ // common.systemBrief('reboot')
+ // }
+ // // 鏇存柊涓婃妫�鏌ョ殑灏忔椂鏁�
+ // this.lastRestartCheck = currentHour
+ // }, 60000)
+ }
+}
+
+export default driver
diff --git a/vf205_access/src/main.js b/vf205_access/src/main.js
new file mode 100644
index 0000000..a4b9565
--- /dev/null
+++ b/vf205_access/src/main.js
@@ -0,0 +1,78 @@
+/**
+ * 搴旂敤涓诲叆鍙f枃浠�
+ * 璐熻矗鍒濆鍖栫郴缁熷悇缁勪欢銆侀┍鍔ㄥ拰鏈嶅姟锛屽惎鍔ㄥ簲鐢ㄧ▼搴�
+ */
+import log from '../dxmodules/dxLogger.js'
+import std from '../dxmodules/dxStd.js'
+import bus from '../dxmodules/dxEventBus.js'
+import screen from './screen.js'
+import driver from './driver.js'
+import pool from '../dxmodules/dxWorkerPool.js'
+import config from '../dxmodules/dxConfig.js'
+import face from '../dxmodules/dxFace.js'
+import net from '../dxmodules/dxNet.js'
+import mqtt from '../dxmodules/dxMqtt.js'
+import dxNfc from '../dxmodules/dxNfc.js'
+import dxUart from '../dxmodules/dxUart.js'
+import dxGpioKey from '../dxmodules/dxGpioKey.js'
+
+/**
+ * 浜嬩欢鎬荤嚎涓婚鍒楄〃
+ * 鍖呭惈绯荤粺涓墍鏈夐渶瑕佺洃鍚殑浜嬩欢涓婚
+ */
+let topics = ["getCode", face.RECEIVE_MSG, dxGpioKey.RECEIVE_MSG, "netGetWifiSsidList", "switchNetworkType", "access", "setConfig", dxNfc.RECEIVE_MSG, net.STATUS_CHANGE, mqtt.CONNECTED_CHANGED, mqtt.RECEIVE_MSG, dxUart.VG.RECEIVE_MSG + driver.uart485.id, dxUart.VG.RECEIVE_MSG + driver.uartCode.id, "trackResult"]
+
+/**
+ * 鍒濆鍖栨帶鍒跺櫒
+ * 鍒濆鍖栫郴缁熸墍鏈夐┍鍔ㄦā鍧�
+ */
+function initController() {
+ driver.gpio.init() // 鍒濆鍖朑PIO
+ driver.watchdog.init() // 鍒濆鍖栫湅闂ㄧ嫍
+ driver.config.init() // 鍒濆鍖栭厤缃�
+ driver.gpiokey.init() // 鍒濆鍖朑PIO鎸夐敭
+ driver.net.init() // 鍒濆鍖栫綉缁�
+ driver.sqlite.init() // 鍒濆鍖栨暟鎹簱
+ driver.alsa.init() // 鍒濆鍖栭煶棰�
+ driver.nfc.init() // 鍒濆鍖朜FC
+ driver.nfc.eidInit() // 鍒濆鍖朎ID锛堢數瀛愯韩浠借瘉锛�
+ driver.uart485.init() // 鍒濆鍖朥ART485
+ driver.uartCode.init() // 鍒濆鍖朥ART鐮�
+ driver.capturer.init() // 鍒濆鍖栨憚鍍忓ご
+ std.sleep(100) // 绛夊緟100ms
+ driver.face.init() // 鍒濆鍖栦汉鑴歌瘑鍒�
+ std.sleep(100) // 绛夊緟100ms
+ driver.pwm.init() // 鍒濆鍖朠WM
+ std.sleep(100) // 绛夊緟100ms
+ driver.mqtt.init() // 鍒濆鍖朚QTT
+ driver.autoRestart.init() // 鍒濆鍖栬嚜鍔ㄩ噸鍚�
+}
+
+/**
+ * 搴旂敤绋嬪簭鍚姩鍑芥暟
+ * 鍒濆鍖栨帶鍒跺櫒銆佸睆骞曘�佸垱寤哄伐浣滅嚎绋嬪拰鏈嶅姟姹�
+ */
+(function () {
+ initController() // 鍒濆鍖栨帶鍒跺櫒
+ screen.init() // 鍒濆鍖栧睆骞�
+ bus.newWorker('controller', '/app/code/src/controller.js') // 鍒涘缓鎺у埗鍣ㄥ伐浣滅嚎绋�
+ pool.init('/app/code/src/services.js', bus, topics, 5, 100) // 鍒濆鍖栨湇鍔℃睜
+ const appVersion = 'vf105_v12_access_2.0.1.1' // 搴旂敤鐗堟湰鍙�
+ config.setAndSave('sys.version', appVersion) // 淇濆瓨鐗堟湰鍙峰埌閰嶇疆
+ config.setAndSave('sys.appVersion', appVersion) // 淇濆瓨搴旂敤鐗堟湰鍙峰埌閰嶇疆
+ log.info("=================== version:" + appVersion + " ====================")
+})();
+
+/**
+ * 涓诲惊鐜�
+ * 瀹氭湡鍠傜嫍銆佹墽琛岀湅闂ㄧ嫍寰幆鍜屽睆骞曞惊鐜�
+ */
+std.setInterval(() => {
+ try {
+ driver.watchdog.feed("main", 30) // 鍠傜嫍锛岃缃�30绉掕秴鏃�
+ driver.watchdog.loop() // 鎵ц鐪嬮棬鐙楀惊鐜�
+ screen.loop() // 鎵ц灞忓箷寰幆
+ } catch (error) {
+ log.error(error) // 璁板綍閿欒
+ }
+}, 5) // 姣�5ms鎵ц涓�娆�
\ No newline at end of file
diff --git a/vf205_access/src/screen.js b/vf205_access/src/screen.js
new file mode 100644
index 0000000..1227934
--- /dev/null
+++ b/vf205_access/src/screen.js
@@ -0,0 +1,1470 @@
+/**
+ * 灞忓箷绠$悊妯″潡
+ * 璐熻矗灞忓箷鏄剧ず銆乁I鎺у埗銆佺敤鎴风晫闈㈢鐞嗙瓑鍔熻兘
+ */
+import dxui from '../dxmodules/dxUi.js'
+import dxMap from '../dxmodules/dxMap.js'
+import log from '../dxmodules/dxLogger.js'
+import net from '../dxmodules/dxNet.js'
+import viewUtils from './view/viewUtils.js'
+import i18n from './view/i18n.js'
+import grainService from './service/grainService.js'
+import sqliteService from './service/sqliteService.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 emergencyPwdView from './view/emergencyPwdView.js'
+import newPwdView from './view/config/newPwdView.js'
+import identityVerificationView from './view/config/identityVerificationView.js'
+import configView from './view/config/configView.js'
+import cloudCertView from './view/config/menu/cloudCertView.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 factoryTestView from './view/config/menu/factoryTestView.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 dockingSettingView from './view/config/menu/dockingSetting.js'
+import localUserAddView from './view/config/menu/localUser/localUserAddView.js'
+import faceEnterView from './view/config/menu/localUser/faceEnterView.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 std from '../dxmodules/dxStd.js'
+import bus from '../dxmodules/dxEventBus.js'
+import driver from './driver.js'
+import config from '../dxmodules/dxConfig.js'
+import common from '../dxmodules/dxCommon.js'
+import configService from './service/configService.js'
+import codeService from './service/codeService.js'
+import face from '../dxmodules/dxFace.js'
+import faceService from './service/faceService.js'
+
+/**
+ * 灞忓箷绠$悊瀵硅薄
+ */
+const screen = {}
+
+/**
+ * 灞忓箷灏哄閰嶇疆
+ */
+screen.screenSize = {
+ width: 800,
+ height: 1280
+}
+
+/**
+ * UI涓婁笅鏂�
+ */
+const context = {}
+
+/**
+ * 鍒濆鍖栧睆骞曠鐞嗘ā鍧�
+ * 鍒濆鍖栨墍鏈塙I缁勪欢銆佽缃瑷�銆佸惎鍔ㄥ睆淇濊鏃跺櫒绛�
+ * 娉ㄦ剰锛氬湪main.js涓皟鐢紝鍙厑璁歌皟鐢ㄤ竴娆�
+ */
+screen.init = function () {
+ const loadMethod = dxui.loadMain
+ dxui.loadMain = function (view) {
+ if (screen.screenNow && screen.screenNow.id == view.id) {
+ return
+ }
+ screen.screenNow = view
+ pinyin.hide(true)
+ loadMethod.call(dxui, view)
+ }
+
+ dxui.init({ orientation: 0 }, context);
+ // 鍒濆鍖栨墍鏈夌粍浠�
+ pinyin.init(800, 400)
+
+ viewUtils.confirmInit()
+
+ mainView.init()
+ idleView.init()
+ topView.init()
+ appView.init()
+ pwdView.init()
+ emergencyPwdView.init()
+ newPwdView.init()
+ identityVerificationView.init()
+ configView.init()
+
+ cloudCertView.init()
+ doorControlView.init()
+ helpView.init()
+ networkSettingView.init()
+ systemSettingView.init()
+ deviceInfoView.init()
+ factoryTestView.init()
+ localUserView.init()
+ recordQueryView.init()
+ voiceBroadcastView.init()
+ dockingSettingView.init()
+
+ localUserAddView.init()
+ faceEnterView.init()
+
+ displaySettingView.init()
+ faceRecognitionSettingView.init()
+ swipeCardRecognitionSettingView.init()
+ passLogSettingView.init()
+
+
+ passwordOpenDoorSettingView.init()
+ passwordManagementView.init()
+ timeSettingView.init()
+
+ systemInfoView.init()
+ dataCapacityInfoView.init()
+ recordQueryDetailView.init()
+
+ // 璁剧疆璇█
+ // i18n.setLanguage("en-US")
+ i18n.setLanguage(config.get("base.language"))
+
+ dxui.loadMain(mainView.screenMain)
+ // dxui.loadMain(networkSettingView.screenMain)
+
+ // 鍚姩灞忎繚璁℃椂鍣�
+ idleTimerStart()
+
+ // bus浜嬩欢
+ busEvents()
+
+ // 瀹炴椂鑾峰彇鐐瑰嚮鍧愭爣
+ getClickPoint()
+
+ // 闅愯棌閿洏
+ hidePinyin()
+
+ // 浜鸿劯璺熻釜妗�
+ faceTrackingBox()
+}
+
+/**
+ * 浜鸿劯璺熻釜妗嗗鐞�
+ * 瀹氭湡鑾峰彇浜鸿劯璺熻釜鏁版嵁骞舵洿鏂拌窡韪鏄剧ず
+ */
+function faceTrackingBox() {
+ std.setInterval(() => {
+ let data = driver.face.getTrackingBox()
+ try {
+ if (data && typeof data === 'string') {
+ // 妫�鏌ユ暟鎹槸鍚︽槸鏈夋晥鐨凧SON瀛楃涓�
+ try {
+ data = JSON.parse(data)
+ // 鏈�澶�10涓汉
+ if (data.type == "track" && data.faces && data.faces.length <= 10) {
+ for (let i = 0; i < data.faces.length; i++) {
+ let item = data.faces[i]
+ if (item && item.rect_render && item.rect_render.length === 4) {
+ screen.trackUpdate({ w: item.rect_render[2] - item.rect_render[0], h: item.rect_render[3] - item.rect_render[1], x: item.rect_render[0], y: item.rect_render[1] }, item.id, item.is_living)
+ }
+ }
+ }
+ } catch (parseError) {
+ log.info('screen.faceTrackingBox: 鏃犳晥鐨凧SON鏁版嵁:', data);
+ log.error("screen.faceTrackingBox: JSON瑙f瀽閿欒:", parseError)
+ }
+ }
+ } catch (error) {
+ log.info('screen.faceTrackingBox:', data);
+ log.error("screen.faceTrackingBox:", error)
+ }
+ }, 110)
+}
+
+/**
+ * 鐐瑰嚮鍧愭爣鍙樺寲鏍囪
+ */
+let changedClickPoint
+
+/**
+ * 涓婃鐐瑰嚮鍧愭爣
+ */
+let lastClickPoint = { x: 0, y: 0 }
+
+/**
+ * 褰撳墠鐐瑰嚮鍧愭爣
+ */
+let clickPoint
+
+/**
+ * 瀹炴椂鑾峰彇鐐瑰嚮鍧愭爣
+ * 瀹氭湡鑾峰彇鐢ㄦ埛瑙︽懜灞忓箷鐨勫潗鏍囦綅缃�
+ */
+function getClickPoint() {
+ const indev = NativeObject.APP.NativeComponents.NativeIndev
+ std.setInterval(() => {
+ clickPoint = {
+ x: Math.abs(800 - indev.lvIndevGetPointVg().x),
+ y: indev.lvIndevGetPointVg().y
+ }
+
+ if (lastClickPoint.x != clickPoint.x || lastClickPoint.y != clickPoint.y) {
+ changedClickPoint = clickPoint
+ } else {
+ changedClickPoint = null
+ }
+
+ lastClickPoint = clickPoint
+ }, 5)
+}
+
+/**
+ * 闅愯棌鎷奸煶閿洏
+ * 澶勭悊鎷奸煶閿洏鐨勬樉绀哄拰闅愯棌閫昏緫锛屽綋鐢ㄦ埛鐐瑰嚮灞忓箷鍏朵粬鍖哄煙鏃惰嚜鍔ㄩ殣钘忛敭鐩�
+ */
+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 < (1280 - (pinyin.getMode() == 1 ? 400 + 70 : 400))) {
+ let defocus = dxMap.get("INPUT_KEYBOARD").get("defocus")
+ if (defocus == "defocus") {
+ dxMap.get("INPUT_KEYBOARD").del("defocus")
+ showPoint = null
+ pinyin.hide()
+ }
+ }
+ }
+ }, 5)
+}
+
+/**
+ * 灞忓箷绠$悊鍣ㄧ被
+ * 璐熻矗灞忓箷鐘舵�佺鐞嗭紝鍖呮嫭灞忎繚鍜岀唲灞忓姛鑳�
+ */
+class ScreenManager {
+ /**
+ * 鏋勯�犲嚱鏁�
+ * @param {object} callbacks - 鍥炶皟鍑芥暟瀵硅薄
+ */
+ 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);
+ }
+
+ /**
+ * 閰嶇疆鏃堕棿
+ * @param {number} screenSaverDelay - 灞忎繚寤惰繜锛堟绉掞級
+ * @param {number} screenOffDelay - 鐔勫睆寤惰繜锛堟绉掞級
+ */
+ 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();
+ }
+ }
+
+ /**
+ * 鑾峰彇褰撳墠鐘舵��
+ * @returns {object} 褰撳墠灞忓箷鐘舵��
+ */
+ 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)
+ // 鍋滄浜鸿劯璇嗗埆
+ driver.face.status(false)
+ screen.screenNow.hide()
+ topView.screenMain.hide()
+ },
+
+ /**
+ * 浜睆鍥炶皟
+ */
+ onScreenOn: () => {
+ screen.exitIdle(true)
+ dxMap.get("screenOff").put("status", 0)
+ // 鎭㈠浜鸿劯璇嗗埆
+ driver.face.status(true)
+ screen.screenNow.show()
+ topView.screenMain.show()
+
+ // 閫�鍑虹唲灞忔椂鑾峰彇骞舵洿鏂版皵浣撴祿搴﹀拰鐘舵�佷俊鎭�
+ try {
+ log.info('[screen]: 閫�鍑虹唲灞忥紝鑾峰彇姘斾綋娴撳害鍜岀姸鎬佷俊鎭�')
+ grainService.checkGasConcentration()
+ grainService.checkDevConcentration()
+ } catch (error) {
+ log.error(`[screen]: 鑾峰彇姘斾綋娴撳害鍜岀姸鎬佷俊鎭敊璇�: ${error.message}`)
+ }
+ }
+ });
+
+ // 閰嶇疆鏃堕棿锛堟绉掞級
+ 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()
+ dxui.loadMain(mainView.screenMain)
+ idleView.screenMain.show()
+ topView.changeTheme(false)
+ }
+ }, 1000)
+}
+
+/**
+ * 閫�鍑哄睆淇�
+ * 闅愯棌灞忎繚鐣岄潰
+ * @param {boolean} isSelf - 鏄惁鐢辩郴缁熻嚜韬Е鍙�
+ */
+screen.exitIdle = function (isSelf) {
+ if (enterIdleTimer) {
+ std.clearTimeout(enterIdleTimer)
+ enterIdleTimer = null
+ }
+ if (!isSelf) {
+ screenManager.resetTimers();
+ }
+ if (!idleView.screenMain.isHide()) {
+ idleView.screenMain.hide()
+ }
+}
+
+/**
+ * 灞忓箷寰幆澶勭悊
+ * 澶勭悊UI浜嬩欢
+ * @returns {boolean} 澶勭悊缁撴灉
+ */
+screen.loop = function () {
+ return dxui.handler()
+}
+
+/**
+ * 浜戣瘉婵�娲�
+ * 婵�娲荤數瀛愯韩浠借瘉
+ * @param {string} code - 婵�娲荤爜
+ * @returns {number} 婵�娲荤粨鏋滐紝0琛ㄧず鎴愬姛锛岄潪0琛ㄧず澶辫触
+ */
+screen.nfcIdentityCardActivation = function (code) {
+ return driver.eid.active(config.get("sys.sn"), config.get("sys.appVersion"), config.get("sys.mac"), code);
+
+}
+
+/**
+ * 鍒犻櫎浜哄憳
+ * 鍒犻櫎鐢ㄦ埛淇℃伅銆佹潈闄愩�佸嚟璇佸拰浜鸿劯鏁版嵁
+ * @param {object} user - 鐢ㄦ埛瀵硅薄
+ * @returns {boolean} 鍒犻櫎缁撴灉
+ */
+screen.deleteUser = function (user) {
+ // 鍒犻櫎浜哄憳淇℃伅
+ sqliteService.d1_person.deleteByUserId(user.userId)
+ // 鍒犻櫎鏉冮檺淇℃伅
+ sqliteService.d1_permission.deleteByUserId(user.userId)
+ // 鍒犻櫎鍑瘉淇℃伅
+ sqliteService.d1_voucher.deleteByUserId(user.userId)
+ // 鍒犻櫎浜鸿劯鏁版嵁
+ let res = driver.face.delete(user.userId)
+
+ return true
+}
+
+/**
+ * 鏇存柊浜哄憳淇℃伅
+ * 鏇存柊鐢ㄦ埛淇℃伅銆佸瘑鐮併�佸崱鐗囧拰浜鸿劯鏁版嵁
+ * @param {object} user - 鐢ㄦ埛瀵硅薄
+ * @returns {boolean|string} 鏇存柊缁撴灉锛屾垚鍔熻繑鍥瀟rue锛屽け璐ヨ繑鍥為敊璇俊鎭�
+ */
+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) {
+ //鍒ゆ柇搴撹〃鏄惁瀛樺湪杩欎釜鍑瘉
+ 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) {
+ let findByuserIdAndType = sqliteService.d1_voucher.findByuserIdAndType(user.userId, "300");
+ if (findByuserIdAndType.length <= 0) {
+ let ret = driver.face.registerFaceByPicFile(user.userId, user.face)
+ log.info("2娉ㄥ唽浜鸿劯,ret:", ret)
+ if (ret != 0) {
+ return faceService.regErrorEnum.picture[ret + '']
+ }
+ //娉ㄥ唽鎴愬姛鍚庨渶瑕佸惂鍘熸潵鍥剧墖绉诲姩鍒� user 瀵瑰簲鐩綍涓�
+ let src = "/app/data/user/" + user.userId + "/register.jpg"
+ std.ensurePathExists(src)
+ common.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.delete(user.userId)
+ //娉ㄥ唽鏂颁汉鑴�
+ let res = driver.face.registerFaceByPicFile(user.userId, user.face)
+ log.info("3娉ㄥ唽浜鸿劯,res:", res)
+ if (res != 0) {
+ return faceService.regErrorEnum.picture[res + '']
+ }
+ let src = "/app/data/user/" + user.userId + "/register.jpg"
+ std.ensurePathExists(src)
+ //鎶婁复鏃剁洰褰曚汉鑴哥Щ鍔ㄥ埌 user 瀵瑰簲鐨勬枃浠跺す涓�
+ common.systemBrief('mv ' + user.face + " " + src)
+ ret = sqliteService.d1_voucher.updatecodeAndExtraByuserIdAndtype(user.userId, "300", src, JSON.stringify({ faceType: 0 }))
+
+ }
+ }
+ } else {
+ //娌℃湁鍐呭鍘绘暟鎹簱琛ㄥ垹闄や竴涓�
+ sqliteService.d1_voucher.deleteByuserIdAndtype(user.userId, "300")
+ driver.face.delete(user.userId)
+ common.systemBrief("rm -rf /app/data/user/" + user.userId)
+ }
+
+ return true
+}
+
+/**
+ * 鏂板浜哄憳
+ * 娣诲姞鏂扮敤鎴蜂俊鎭�佸瘑鐮併�佸崱鐗囧拰浜鸿劯鏁版嵁
+ * @param {object} user - 鐢ㄦ埛瀵硅薄
+ * @returns {boolean|string} 娣诲姞缁撴灉锛屾垚鍔熻繑鍥瀟rue锛屽け璐ヨ繑鍥為敊璇俊鎭�
+ */
+screen.insertUser = async function (user) {
+ /**
+ * 淇濆瓨鍑瘉
+ * @param {string} type - 鍑瘉绫诲瀷
+ * @param {string} code - 鍑瘉浠g爜
+ * @returns {boolean|string} 淇濆瓨缁撴灉
+ */
+ const saveVoucher = async (type, code) => {
+ // 妫�鏌ュ崱鐗囧嚟璇佹槸鍚﹂噸澶�
+ 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); // 鍋囪杩欐槸鎮ㄦ彁鍒扮殑闇�瑕佽皟鐢ㄧ殑鏂规硶
+ if (preCheckResult !== true) { // 濡傛灉棰勬鏌ヤ笉閫氳繃锛屽垯鐩存帴杩斿洖 false
+ return preCheckResult;
+ }
+ code = "/app/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"
+ }
+ }
+
+ 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: 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;
+ };
+
+ /**
+ * 淇濆瓨鍓嶆鏌�
+ * @param {string} code - 浜鸿劯鍥剧墖璺緞
+ * @returns {boolean|string} 妫�鏌ョ粨鏋�
+ */
+ async function preSaveCheck(code) {
+ let ret = driver.face.registerFaceByPicFile(user.userId, code)
+ log.info("1娉ㄥ唽浜鸿劯,ret:", ret)
+ if (ret != 0) {
+ return faceService.regErrorEnum.picture[ret + '']
+ }
+ //娉ㄥ唽鎴愬姛鍚庨渶瑕佸惂鍘熸潵鍥剧墖绉诲姩鍒� user 瀵瑰簲鐩綍涓�
+ let src = "/app/data/user/" + user.userId + "/register.jpg"
+ std.ensurePathExists(src)
+ common.systemBrief('mv ' + code + " " + src)
+ return true;
+ }
+
+ let success = true;
+ // 淇濆瓨浜鸿劯鍑瘉
+ if (success === true && user.face && !(success = await saveVoucher("300", user.face)));
+ // 淇濆瓨瀵嗙爜鍑瘉
+ if (success === true && user.pwd && !(success = await saveVoucher("400", user.pwd)));
+ // 淇濆瓨鍗$墖鍑瘉
+ if (success === true && user.card && !(success = await saveVoucher("200", user.card)));
+
+ 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, userId: user.userId, timeType: 0 })
+ } else {
+ await sqliteService.d1_voucher.deleteByUserId(user.userId);
+ }
+
+ return success;
+
+}
+
+/**
+ * 鑾峰彇鏈湴浜哄憳淇℃伅
+ * 鑾峰彇鐢ㄦ埛鐨勫嚟璇佷俊鎭紝鍖呮嫭韬唤璇併�佸崱鐗囥�佸瘑鐮佸拰浜鸿劯鏁版嵁
+ * @param {string} userId - 鐢ㄦ埛ID
+ * @returns {object} 鐢ㄦ埛鍑瘉淇℃伅
+ */
+screen.getVoucher = function (userId) {
+ // 鑾峰彇鐢ㄦ埛淇℃伅
+ let person = sqliteService.d1_person.find({ userId: userId });
+
+ 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 idCard_voucher
+ try {
+ idCard_voucher = JSON.parse(person[0].extra).idCard
+ } catch (error) {
+ }
+
+ 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,
+ type: JSON.parse(person[0].extra).type || 0
+ }
+
+}
+
+/**
+ * 鑾峰彇鐢ㄦ埛鍒楄〃
+ * 鏍规嵁鏉′欢鏌ヨ鐢ㄦ埛鍒楄〃锛屾敮鎸佸垎椤靛拰鎼滅储
+ * @param {number} page - 椤电爜锛岄粯璁�0
+ * @param {number} size - 姣忛〉澶у皬锛岄粯璁�6
+ * @param {string} userId - 鐢ㄦ埛ID锛岀敤浜庣簿纭悳绱�
+ * @param {string} name - 鐢ㄦ埛濮撳悕锛岀敤浜庢ā绯婃悳绱�
+ * @returns {object} 鐢ㄦ埛鍒楄〃鏁版嵁锛屽寘鍚垎椤典俊鎭�
+ */
+screen.getUsers = function (page = 0, size = 6, userId, name) {
+ // 鎸夌敤鎴稩D鎴栧鍚嶆悳绱�
+ if (userId || name) {
+ // 鎸夌敤鎴稩D鎼滅储
+ let user = sqliteService.d1_person.findByUserId(userId)[0]
+ if (user) {
+ user.id = user.userId
+ return { data: [user], totalPage: 1, totalSize: 1, currentPage: 1 }
+ }
+ // 鎸夌敤鎴峰鍚嶆悳绱�
+ let users = sqliteService.d1_person.findByName(name)
+ if (users && users.length > 0) {
+ users.map(v => {
+ v.id = v.userId
+ })
+
+ /**
+ * 鏁扮粍鍒嗗潡
+ * @param {array} arr - 婧愭暟缁�
+ * @param {number} size - 鍧楀ぇ灏�
+ * @returns {array} 鍒嗗潡鍚庣殑鏁扮粍
+ */
+ 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 }
+}
+
+/**
+ * 鑾峰彇閫氳璁板綍
+ * 鑾峰彇鐢ㄦ埛閫氳璁板綍锛屾敮鎸佸垎椤�
+ * @param {number} page - 椤电爜锛岄粯璁�0
+ * @param {number} size - 姣忛〉澶у皬锛岄粯璁�6
+ * @returns {object} 閫氳璁板綍鏁版嵁锛屽寘鍚垎椤典俊鎭�
+ */
+screen.getPassRecord = function (page = 0, size = 6) {
+ let passCount = sqliteService.d1_pass_record.count()
+ let datas = sqliteService.d1_pass_record.findOrderByTimeDesc({ page, size })
+ // 鎬婚〉鏁�
+ let totalPage = Math.ceil(passCount / size)
+ return { data: datas, totalPage: totalPage, totalSize: passCount, currentPage: page + 1 }
+}
+
+/**
+ * 浜鸿劯褰曞叆寮�濮�
+ * 寮�濮嬩汉鑴稿綍鍏ワ紝UI鎺у埗
+ * @param {string} userId - 鐢ㄦ埛ID
+ */
+screen.faceEnterStart = function (userId) {
+ dxMap.get("UI").put("faceEnterStart", userId)
+ driver.face.status(1)
+ driver.face.mode(1)
+}
+
+/**
+ * 浜鸿劯褰曞叆缁撴潫
+ * 缁撴潫浜鸿劯褰曞叆锛孶I鎺у埗
+ */
+screen.faceEnterEnd = function () {
+ dxMap.get("UI").del("faceEnterStart")
+ driver.face.status(0)
+ // driver.face.mode(0)
+}
+
+/**
+ * 鑾峰彇鍗″彿寮�濮�
+ * 寮�濮嬭幏鍙栧崱鍙凤紝UI鎺у埗
+ */
+screen.getCardStart = function () {
+ dxMap.get("UI").put("getCardStart", true)
+}
+
+/**
+ * 鑾峰彇鍗″彿缁撴潫
+ * 缁撴潫鑾峰彇鍗″彿锛孶I鎺у埗
+ */
+screen.endCardEnd = function () {
+ dxMap.get("UI").del("getCardStart")
+}
+
+/**
+ * 寮�鍚汉鑴歌瘑鍒�
+ * 寮�濮嬩汉鑴歌瘑鍒姛鑳�
+ */
+screen.faceRecgStart = function () {
+ driver.face.status(1)
+ driver.face.mode(0)
+}
+
+/**
+ * 浜鸿劯璇嗗埆鏆傚仠
+ * 鏆傚仠浜鸿劯璇嗗埆鍔熻兘
+ */
+screen.faceRecgPause = function () {
+ driver.face.status(0)
+}
+
+/**
+ * 浜鸿劯褰曞叆缁撴灉
+ * 澶勭悊浜鸿劯褰曞叆缁撴灉
+ * @param {string} facePic - 浜鸿劯鍥剧墖璺緞
+ */
+screen.faceEnterResult = function (facePic) {
+ if (facePic) {
+ faceEnterView.successFlag = true
+ // 鎴愬姛锛屾樉绀轰汉鑴哥収鐗�
+ localUserAddView.addFace(facePic)
+ dxui.loadMain(localUserAddView.screenMain)
+ faceEnterView.backCb()
+ } else {
+ // 澶辫触锛屾姤閿�
+ faceEnterView.timeout()
+ }
+}
+
+/**
+ * 闈炶瘑鍒〉闈汉鑴歌璇佸紑濮�
+ * 寮�濮嬩汉鑴歌璇侊紝UI鎺у埗
+ */
+screen.faceAuthStart = function () {
+ dxMap.get("UI").put("faceAuthStart", "Y")
+ driver.face.status(1)
+ driver.face.mode(0)
+}
+
+/**
+ * 闈炶瘑鍒〉闈汉鑴歌璇佺粨鏉�
+ * 缁撴潫浜鸿劯璁よ瘉锛孶I鎺у埗
+ */
+screen.faceAuthEnd = function () {
+ dxMap.get("UI").del("faceAuthStart")
+ driver.face.status(0)
+}
+
+/**
+ * 闈炶瘑鍒〉闈汉鑴歌璇佺粨鏋�
+ * 澶勭悊浜鸿劯璁よ瘉缁撴灉
+ * @param {boolean} bool - 璁よ瘉缁撴灉锛宼rue琛ㄧず鎴愬姛锛宖alse琛ㄧず澶辫触
+ */
+screen.faceAuthResult = function (bool) {
+ if (bool) {
+ // 鎴愬姛锛岃繘鍏ヨ缃彍鍗�
+ driver.alsa.play(`/app/code/resource/${config.get("base.language") == "CN" ? "CN" : "EN"}/wav/recg_s.wav`)
+ dxui.loadMain(configView.screenMain)
+ } else {
+ // 澶辫触锛屾姤閿�
+ driver.alsa.play(`/app/code/resource/${config.get("base.language") == "CN" ? "CN" : "EN"}/wav/recg_f.wav`)
+ identityVerificationView.statusPanel.fail()
+ }
+}
+
+/**
+ * 淇濆瓨閰嶇疆
+ * 淇濆瓨绯荤粺閰嶇疆
+ * @param {object} configAll - 閰嶇疆瀵硅薄
+ * @returns {boolean} 淇濆瓨缁撴灉
+ */
+screen.saveConfig = function (configAll) {
+ // 鐩存帴璋冪敤閰嶇疆楠岃瘉鍜屼繚瀛樺嚱鏁�
+ return configService.configVerifyAndSave(configAll)
+}
+
+/**
+ * 鑾峰彇閰嶇疆
+ * 鑾峰彇绯荤粺閰嶇疆
+ * @returns {object} 閰嶇疆瀵硅薄
+ */
+screen.getConfig = function () {
+ let config1 = config.getAll()
+ return config1
+}
+
+/**
+ * 瀵嗙爜閫氳
+ * 浣跨敤瀵嗙爜杩涜閫氳楠岃瘉
+ * @param {string} pwd - 瀵嗙爜
+ * @returns {boolean} 楠岃瘉缁撴灉锛宼rue琛ㄧず鎴愬姛锛宖alse琛ㄧず澶辫触
+ */
+screen.pwdAccess = function (pwd) {
+ // 妫�鏌ユ暟鎹簱涓殑搴旀�ュ紑浠撳瘑鐮�
+ try {
+ const passwords = sqliteService.d1_emergency_password.findAll({ status: 1 })
+ for (let i = 0; i < passwords.length; i++) {
+ if (passwords[i].password === pwd) {
+ return true
+ }
+ }
+ } catch (error) {
+ logger.error('妫�鏌ュ簲鎬ュ紑浠撳瘑鐮佸け璐�:', error)
+ }
+
+ // 鍏朵粬瀵嗙爜楠岃瘉閫昏緫
+ bus.fire("access", { data: { type: "400", code: pwd } })
+ return false
+}
+
+/**
+ * 鍒囨崲缃戠粶绫诲瀷
+ * 鍒囨崲缃戠粶杩炴帴绫诲瀷
+ * @param {object} data - 缃戠粶绫诲瀷鏁版嵁
+ */
+screen.switchNetworkType = function (data) {
+ bus.fire("switchNetworkType", data)
+}
+
+/**
+ * 鑾峰彇WiFi鍒楄〃
+ * 鑾峰彇鍙敤鐨刉iFi缃戠粶鍒楄〃
+ */
+screen.netGetWifiSsidList = function () {
+ bus.fire("netGetWifiSsidList")
+}
+
+/**
+ * WiFi鍒楄〃鏁版嵁
+ * 澶勭悊WiFi鍒楄〃鏁版嵁
+ * @param {array} data - WiFi鍒楄〃鏁版嵁
+ */
+screen.netWifiSsidList = function (data) {
+ if (data.length == 0 && config.get("net.type") == 2) {
+ //鏃犵嚎缃�
+ std.setTimeout(() => {
+ screen.netGetWifiSsidList()
+ }, 1000)
+ return
+ }
+ networkSettingView.wifiListData = data
+ networkSettingView.wifiList.refresh()
+}
+
+/**
+ * 杩炴帴WiFi
+ * 杩炴帴鍒版寚瀹氱殑WiFi缃戠粶
+ * @param {string} ssid - WiFi鍚嶇О
+ * @param {string} psk - WiFi瀵嗙爜
+ * @returns {boolean} 杩炴帴缁撴灉
+ */
+screen.netConnectWifiSsid = function (ssid, psk) {
+ return driver.net.netConnectWifiSsid(ssid, psk)
+}
+
+/**
+ * 鑾峰彇鍗″彿
+ * 澶勭悊鑾峰彇鍒扮殑鍗″彿
+ * @param {string} card - 鍗″彿
+ */
+screen.getCard = function (card) {
+ localUserAddView.cardBoxInput.text(card)
+}
+
+/**
+ * 浜嬩欢鎬荤嚎浜嬩欢澶勭悊
+ * 娉ㄥ唽鍜屽鐞嗙郴缁熶簨浠�
+ */
+function busEvents() {
+ // 缃戠粶鐘舵��
+ bus.on('netStatus', (data) => {
+ console.log(JSON.stringify(data));
+ let type = config.get("net.type")
+ if (data.connected) {
+ let ip = net.getModeByCard(type).param.ip
+ mainView.overlayIpLbl.text("IP:" + ip)
+ config.setAndSave("net.ip", ip)
+ config.setAndSave("net.mac", net.getMacaddr(type))
+ topView.ethConnectState(true, type)
+ networkSettingView.netInfo[10].label.dataI18n = "networkSettingView.networkConnected"
+ } else {
+ topView.ethConnectState(false, type)
+ networkSettingView.netInfo[10].label.dataI18n = "networkSettingView.networkUnconnected"
+ }
+ i18n.refreshObj(networkSettingView.netInfo[10].label)
+ })
+
+ // mqtt杩炴帴鐘舵��
+ bus.on('mqttStatus', (data) => {
+ if (data == "connected") {
+ topView.mqttConnectState(true)
+ } else {
+ topView.mqttConnectState(false)
+ }
+ })
+
+ // 浜鸿劯褰曞叆寮�濮�
+ bus.on("beginAddFace", screen.beginAddFace)
+
+ // 浜鸿劯褰曞叆缁撴灉
+ bus.on("faceEnterResult", screen.faceEnterResult)
+
+ // 閫�鍑哄睆淇�
+ bus.on("exitIdle", screen.exitIdle)
+
+ // 鑾峰彇WiFi鍒楄〃 - 绉婚櫎浜嬩欢鐩戝惉鍣紝閬垮厤鏃犻檺寰幆
+
+ // 鑾峰彇鍗″彿
+ bus.on("getCard", screen.getCard)
+
+ // 浜鸿劯璁よ瘉缁撴灉
+ bus.on("faceAuthResult", screen.faceAuthResult)
+
+ // 閫氳缁撴灉
+ bus.on("accessRes", screen.accessRes)
+
+ // 璺熻釜鏇存柊
+ // bus.on("trackUpdate", screen.trackUpdate)
+
+ // 闅愯棌SN
+ bus.on("hideSn", screen.hideSn)
+
+ // 鍒囨崲璇█
+ bus.on("changeLanguage", screen.changeLanguage)
+
+ // 闅愯棌IP
+ bus.on("hideIp", screen.hideIp)
+
+ // 鍒锋柊灞忓箷绠$悊鍣�
+ bus.on("screenManagerRefresh", screen.screenManagerRefresh)
+
+ // WiFi鍒楄〃鏁版嵁
+ bus.on("netWifiSsidList", screen.netWifiSsidList)
+
+ // APP妯″紡
+ bus.on("appMode", screen.appMode)
+
+ // 鍗囩骇
+ bus.on("upgrade", screen.upgrade)
+
+ // 鍗$墖閲嶇疆
+ // bus.on("cardReset", screen.cardReset)
+
+ // 璺熻釜缁撴灉
+ bus.on("trackResult", screen.trackResult)
+ bus.on("showAccessResult", screen.showAccessResult)
+}
+
+/**
+ * 鍗$墖閲嶇疆瀹氭椂鍣�
+ */
+let setTimeout
+
+/**
+ * 鍗$墖閲嶇疆
+ * 澶勭悊鍗$墖閲嶇疆閫昏緫
+ * @param {object} msg - 娑堟伅瀵硅薄
+ */
+screen.cardReset = function (msg) {
+ if (msg.type == 2 && msg.status == 3) {
+ setTimeout = std.setTimeout(() => {
+ driver.net.cardReset()
+ }, 30 * 1000);
+ } else {
+ if (setTimeout) {
+ std.clearTimeout(setTimeout)
+ }
+ }
+}
+
+/**
+ * 寮�濮嬫敞鍐屼汉鑴�
+ * 澶勭悊浜鸿劯娉ㄥ唽寮�濮嬮�昏緫
+ * @param {object} data - 浜鸿劯鏁版嵁瀵硅薄
+ */
+screen.beginAddFace = function (data) {
+ log.info('screen.beginAddFace', JSON.stringify(data));
+
+ if (!data.fileName) {
+ return screen.faceEnterResult()
+ }
+
+ driver.alsa.play(`/app/code/resource/${config.get("base.language") == "CN" ? "CN" : "EN"}/wav/recognition_s.wav`)
+ faceEnterView.statusPanel.success("faceEnterView.recogSuccess")
+ // 淇濆瓨鍥剧墖鍒版湰鍦�
+ let src = `/app/data/user/register.jpg`
+ common.systemBrief(`mv ${data.fileName} ${src}`)
+ common.systemBrief(`rm -rf /app/data/user/temp/*`)
+
+ screen.faceEnterResult(src)
+}
+
+/**
+ * 閫氳缁撴灉
+ * 澶勭悊閫氳鎴愬姛鎴栧け璐ョ殑缁撴灉
+ * @param {boolean} bool - 閫氳缁撴灉锛宼rue琛ㄧず鎴愬姛锛宖alse琛ㄧず澶辫触
+ */
+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()
+ }
+ }
+}
+
+/**
+ * 鍒囨崲APP妯″紡
+ * 鍒囨崲搴旂敤绋嬪簭鏄剧ず妯″紡锛堟爣鍑嗘ā寮忔垨绠�娲佹ā寮忥級
+ * @param {number} mode - 妯″紡鍊硷紝0琛ㄧず鏍囧噯妯″紡锛�1琛ㄧず绠�娲佹ā寮�
+ */
+screen.appMode = function (mode) {
+ if (mode == 0) {
+ // 鍒囨崲鍒版爣鍑嗘ā寮�
+ } else if (mode == 1) {
+ // 鍒囨崲鍒扮畝娲佹ā寮�
+ }
+}
+
+/**
+ * 鏇存柊浜鸿劯璺熻釜妗�
+ * 鏇存柊浜鸿劯璺熻釜妗嗙殑浣嶇疆鍜岀姸鎬�
+ * @param {object} data - 鍧愭爣淇℃伅
+ * @param {number} id - face_id锛岀敤浜庡叧鑱旇瘑鍒鍚嶇敤
+ * @param {boolean} 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
+ }
+ }
+ item.face_id = id
+
+ if (item && item.timer) {
+ std.clearTimeout(item.timer)
+ item.timer = null
+ }
+
+ item.timer = std.setTimeout(() => {
+ item.trackFace.hide()
+ // item.trackFaceName.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)
+ }
+}
+
+/**
+ * 璁よ瘉缁撴灉
+ * 澶勭悊浜鸿劯璇嗗埆璁よ瘉缁撴灉
+ * @param {object} data - 璁よ瘉缁撴灉鏁版嵁
+ */
+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
+ }
+ }
+}
+
+/**
+ * 闅愯棌SN鎸夐挳
+ * 鎺у埗SN鎸夐挳鐨勬樉绀哄拰闅愯棌
+ * @param {boolean} bool - 鏄惁鏄剧ず锛宼rue琛ㄧず鏄剧ず锛宖alse琛ㄧず闅愯棌
+ */
+screen.hideSn = function (bool) {
+ if (bool) {
+ mainView.bottomSnBtn.show()
+ } else {
+ mainView.bottomSnBtn.hide()
+ }
+}
+
+/**
+ * 闅愯棌IP鏍囩
+ * 鎺у埗IP鏍囩鐨勬樉绀哄拰闅愯棌
+ * @param {boolean} bool - 鏄惁鏄剧ず锛宼rue琛ㄧず鏄剧ず锛宖alse琛ㄧず闅愯棌
+ */
+screen.hideIp = function (bool) {
+ // 涓嶅啀闇�瑕佹鍑芥暟锛屽洜涓篒P淇℃伅鐜板湪鏄剧ず鍦ㄥ崐閫忔槑瑕嗙洊鍥惧眰涓�
+}
+
+/**
+ * 闅愯棌搴曢儴妗�
+ * 鎺у埗搴曢儴妗嗙殑鏄剧ず鍜岄殣钘�
+ * @param {boolean} bool - 鏄惁鏄剧ず锛宼rue琛ㄧず鏄剧ず锛宖alse琛ㄧず闅愯棌
+ */
+screen.hideBottomBox = function (bool) {
+ if (bool) {
+ mainView.bottomBox.hide()
+ } else {
+ mainView.bottomBox.show()
+ }
+}
+
+/**
+ * 鍒囨崲璇█
+ * 鍒囨崲绯荤粺璇█璁剧疆
+ */
+screen.changeLanguage = function () {
+ i18n.setLanguage(screen.getConfig()['base.language'])
+}
+
+/**
+ * 鍗囩骇鎻愮ず
+ * 鏄剧ず绯荤粺鍗囩骇鎻愮ず淇℃伅
+ * @param {object} data - 鍗囩骇淇℃伅瀵硅薄锛屽寘鍚玹itle鍜宑ontent
+ */
+screen.upgrade = function (data) {
+ const { title, content } = data
+ viewUtils.confirmOpen(title, content)
+}
+
+/**
+ * 鏄剧ず閫氳缁撴灉寮圭獥
+ * @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)
+ }
+}
+
+export default screen
diff --git a/vf205_access/src/service/accessService.js b/vf205_access/src/service/accessService.js
new file mode 100644
index 0000000..0bdd955
--- /dev/null
+++ b/vf205_access/src/service/accessService.js
@@ -0,0 +1,501 @@
+/**
+ * 闂ㄧ閫氳鏈嶅姟妯″潡
+ * 澶勭悊闂ㄧ閫氳鐩稿叧鐨勪笟鍔¢�昏緫锛屽寘鎷汉鑴�/瀵嗙爜鐧藉悕鍗曟牎楠屻�佹潈闄愬垽鏂�侀�氳璁板綍淇濆瓨绛�
+ */
+import logger from "../../dxmodules/dxLogger.js"
+import std from "../../dxmodules/dxStd.js"
+import config from "../../dxmodules/dxConfig.js"
+import common from "../../dxmodules/dxCommon.js"
+import map from '../../dxmodules/dxMap.js'
+import bus from '../../dxmodules/dxEventBus.js'
+import driver from "../driver.js"
+import mqttService from "./mqttService.js"
+import sqliteService from "./sqliteService.js"
+import utils from '../common/utils/utils.js'
+import http from "../../dxmodules/dxHttp.js"
+import grainService from './grainService.js'
+const accessService = {}
+
+/**
+ * 灏嗗崄杩涘埗鏁拌浆鎹负灏忕搴忓崄鍏繘鍒跺瓧绗︿覆
+ * @param {number} decimalNumber - 鍗佽繘鍒舵暟
+ * @param {number} byteSize - 瀛楄妭澶у皬
+ * @returns {string} 灏忕搴忓崄鍏繘鍒跺瓧绗︿覆
+ */
+function decimalToLittleEndianHex(decimalNumber, byteSize) {
+ const littleEndianBytes = [];
+ for (let i = 0; i < byteSize; i++) {
+ littleEndianBytes.push(decimalNumber & 0xFF);
+ decimalNumber >>= 8; // 鐩稿綋浜庨櫎浠�256
+ }
+ const littleEndianHex = littleEndianBytes
+ .map((byte) => byte.toString(16).padStart(2, '0'))
+ .join('');
+ return littleEndianHex;
+}
+
+/**
+ * 灏嗘暟鎹寘杞崲涓哄瓧绗︿覆鏍煎紡
+ * @param {object} pack - 鏁版嵁鍖呭璞�
+ * @returns {string} 杞崲鍚庣殑瀛楃涓�
+ */
+function pack2str(pack) {
+ pack.data = (!pack.data) ? [] : pack.data.match(/.{2}/g)
+ let len = decimalToLittleEndianHex(pack.data.length, 2)
+ let str = "55aa" + pack.cmd + pack.result + len + pack.data.join('')
+ let crc = common.calculateBcc([0x55, 0xaa, parseInt(pack.cmd, 16), parseInt(pack.result, 16), pack.data.length % 256, pack.data.length / 256].concat(pack.data.map(v => parseInt(v, 16))))
+ return str + crc.toString(16).padStart(2, '0')
+}
+
+/**
+ * 浜鸿劯/瀵嗙爜鐧藉悕鍗曟牎楠�
+ * @param {object} data - 閫氳鏁版嵁锛屽寘鍚玹ype锛堢爜鍒讹級鍜宑ode锛堢爜鍐呭锛�
+ * @param {string} fileName - 閫氳鍥剧墖鏂囦欢璺緞
+ * @param {boolean|undefined} similarity - 鐩镐技搴﹂獙璇佺粨鏋滐紝false琛ㄧず楠岃瘉澶辫触
+ * @returns {number|string|boolean} -1锛堝弬鏁伴敊璇級锛�0锛堥�氳鎴愬姛锛夛紝1锛堝湪绾块獙璇侊級锛宻tring锛堟牎楠屽け璐ョ殑鍘熷洜锛夛紝false锛堥�氳鍔犻攣锛�
+ */
+accessService.access = function (data, fileName, similarity) {
+ // 閫氳鍔犻攣锛岄槻姝㈤噸澶嶉獙璇�
+ let lockMap = map.get("access_lock")
+ if (lockMap.get("access_lock")) {
+ logger.error("[access]: 閫氳鍔犻攣锛岃绋嶅悗鍐嶈瘯")
+ return false
+ }
+ lockMap.put("access_lock", true)
+
+ try {
+ // 璁板綍閫氳鏃堕棿鎴�
+ data.time = Math.floor(Date.parse(new Date()) / 1000)
+
+ // 鏍规嵁code鏌ヨ鍑瘉
+ let res
+ if (data.type == "300") {
+ // 浜鸿劯绫诲瀷锛屼娇鐢╱serId鏌ヨ
+ res = sqliteService.d1_voucher.findByUserIdAndType(data.code, data.type)
+ } else {
+ // 鍏朵粬绫诲瀷锛屼娇鐢╟ode鏌ヨ
+ res = sqliteService.d1_voucher.findByCodeAndType(data.code, data.type)
+ }
+
+ // 鏉冮檺璁よ瘉缁撴灉
+ let ret = true
+ // 鏄惁鏄檶鐢熶汉
+ let isStranger = false
+
+ if (similarity === false) {
+ // 濡傛灉鐩镐技搴﹂獙璇佸け璐ワ紝鍒欎笉杩涜璁よ瘉
+ ret = false
+ isStranger = true
+ } else {
+ // 楠岃瘉鍑瘉鏄惁瀛樺湪
+ if (res.length == 0) {
+ logger.error("[access]: 閫氳澶辫触锛屾病鏌ヨ鍒板嚟璇侊紒")
+ ret = false
+ isStranger = true
+ } else {
+ // 鍑瘉瀛樺湪锛岃幏鍙栫敤鎴蜂俊鎭�
+ data.userId = res[0].userId
+ data.keyId = res[0].id
+
+ // 鏍规嵁userId鏌ヨ浜哄憳淇℃伅
+ res = sqliteService.d1_person.findByUserId(data.userId)
+ if (res.length == 0) {
+ logger.error("[access]: 閫氳澶辫触锛屾病鏌ヨ鍒颁汉鍛橈紒")
+ ret = false
+ isStranger = true
+ } else {
+ // 鑾峰彇浜哄憳濮撳悕銆佽韩浠借瘉鍙峰拰韬唤绫诲瀷
+ let idCard
+ let userType = 0
+ try {
+ idCard = JSON.parse(res[0].extra).idCard
+ userType = JSON.parse(res[0].extra).type || 0
+ } catch (error) {
+ logger.error("鏃犺韩浠借瘉鍙锋垨绫诲瀷")
+ }
+ data.extra = { name: res[0].name, idCard: idCard, type: userType }
+ }
+
+ // 澶勭悊鍙屼汉璁よ瘉淇℃伅
+ if (data.dualAuthInfo) {
+ logger.info("[access]: 澶勭悊鍙屼汉璁よ瘉淇℃伅: " + JSON.stringify(data.dualAuthInfo))
+ // 瀛樺偍绗竴鐢ㄦ埛淇℃伅
+ let firstUserId = data.dualAuthInfo.firstUserId
+ // 鏌ヨ绗竴鐢ㄦ埛鐨勮缁嗕俊鎭�
+ let res1 = sqliteService.d1_person.findByUserId(firstUserId)
+ if (res1.length > 0) {
+ // 鑾峰彇绗竴鐢ㄦ埛鐨勫鍚嶃�佽韩浠借瘉鍙峰拰韬唤绫诲瀷
+ let idCard1
+ let firstUserType = 0
+ try {
+ idCard1 = JSON.parse(res1[0].extra).idCard
+ firstUserType = JSON.parse(res1[0].extra).type || 0
+ } catch (error) {
+ logger.error("鏃犵涓�鐢ㄦ埛韬唤璇佸彿鎴栫被鍨�")
+ }
+ data.userId = firstUserId
+ data.extra = { name: res1[0].name, idCard: idCard1, type: firstUserType }
+ } else {
+ // 濡傛灉娌℃湁鏌ヨ鍒扮涓�鐢ㄦ埛淇℃伅锛屼娇鐢ㄩ粯璁ゅ��
+ data.userId = firstUserId
+ data.extra = { name: data.dualAuthInfo.firstUserName, idCard: "", type: 0 }
+ }
+ // 瀛樺偍绗簩鐢ㄦ埛淇℃伅
+ data.userId2 = data.dualAuthInfo.secondUserId
+ // 鏌ヨ绗簩鐢ㄦ埛鐨勮缁嗕俊鎭�
+ let res2 = sqliteService.d1_person.findByUserId(data.dualAuthInfo.secondUserId)
+ if (res2.length > 0) {
+ // 鑾峰彇绗簩鐢ㄦ埛鐨勫鍚嶅拰韬唤璇佸彿
+ let idCard2
+ let secondUserType = 0
+ try {
+ idCard2 = JSON.parse(res2[0].extra).idCard
+ secondUserType = JSON.parse(res2[0].extra).type || 0
+ } catch (error) {
+ logger.error("鏃犵浜岀敤鎴疯韩浠借瘉鍙锋垨绫诲瀷")
+ }
+ data.extra2 = { name: res2[0].name, idCard: idCard2 }
+ // 瀛樺偍绗簩鐢ㄦ埛鐨勬潈闄怚D锛堣韩浠界被鍨嬶級
+ data.permissionId2 = secondUserType.toString()
+ } else {
+ // 濡傛灉娌℃湁鏌ヨ鍒扮浜岀敤鎴蜂俊鎭紝浣跨敤榛樿鍊�
+ data.extra2 = { name: data.dualAuthInfo.secondUserName, idCard: "" }
+ data.permissionId2 = ""
+ }
+ // 澶勭悊绗竴鐢ㄦ埛鐨勪汉鑴稿浘鐗�
+ if (data.firstUserFileName) {
+ let firstUserSrc = `/app/data/passRecord/${firstUserId}_${data.time}_1.jpg`
+ std.ensurePathExists(firstUserSrc) // 纭繚鐩綍瀛樺湪
+ if (std.exist(data.firstUserFileName)) {
+ // 绉诲姩鍥剧墖鍒版寚瀹氱洰褰�
+ common.systemBrief(`mv ${data.firstUserFileName} ${firstUserSrc}`)
+ // 鏇存柊data涓殑code涓虹涓�鐢ㄦ埛鐨勫浘鐗囪矾寰�
+ data.code = firstUserSrc
+ }
+ }
+ // 澶勭悊绗簩鐢ㄦ埛鐨勪汉鑴稿浘鐗�
+ if (fileName) {
+ let secondUserSrc = `/app/data/passRecord/${data.userId2}_${data.time}_2.jpg`
+ std.ensurePathExists(secondUserSrc) // 纭繚鐩綍瀛樺湪
+ if (std.exist(fileName)) {
+ // 绉诲姩鍥剧墖鍒版寚瀹氱洰褰�
+ common.systemBrief(`mv ${fileName} ${secondUserSrc}`)
+ // 鏇存柊data涓殑code2涓虹浜岀敤鎴风殑鍥剧墖璺緞
+ data.code2 = secondUserSrc
+ }
+ }
+ }
+ }
+
+ // 楠岃瘉鏉冮檺
+ if (ret) {
+ // 鏍规嵁userId鏌ヨ鏉冮檺
+ res = sqliteService.d1_permission.findByUserId(data.userId)
+ if (res && res.length > 0 && judgmentPermission(res)) {
+ logger.info("[access]: 鏉冮檺璁よ瘉閫氳繃")
+ ret = true
+ // 瀛樺偍鐢ㄦ埛韬唤绫诲瀷浣滀负鏉冮檺ID锛堟湰绯荤粺涓韩浠藉嵆鏉冮檺锛�
+ let userType = 0
+ try {
+ if (data.extra) {
+ userType = data.extra.type || 0
+ } else {
+ // 浠庢暟鎹簱鏌ヨ鐢ㄦ埛淇℃伅鑾峰彇韬唤绫诲瀷
+ let userRes = sqliteService.d1_person.findByUserId(data.userId)
+ if (userRes && userRes.length > 0) {
+ userType = JSON.parse(userRes[0].extra).type || 0
+ }
+ }
+ } catch (error) {
+ logger.error("瑙f瀽鐢ㄦ埛绫诲瀷澶辫触")
+ }
+ data.permissionId = userType.toString()
+ // 鏆傚仠浜鸿劯璁よ瘉鍔熻兘
+ driver.face.status(false)
+ logger.info("[access]: 鏆傚仠浜鸿劯璁よ瘉鍔熻兘")
+ } else {
+ logger.info("[access]: 鏃犳潈闄�")
+ ret = false
+ }
+ }
+
+ // 鏃犳潈闄愭椂锛屽皾璇曞湪绾块獙璇�
+ if (!ret && config.get('mqtt.onlinecheck') == 1 && driver.mqtt.getStatus()) {
+ logger.info("[access]: 鏃犳潈闄愶紝璧板湪绾块獙璇�")
+ let serialNo = std.genRandomStr(10)
+ driver.mqtt.send("access_device/v2/event/access_online", JSON.stringify(mqttService.mqttReply(serialNo, data, mqttService.CODE.S_000)))
+ driver.alsa.play(`/app/code/resource/${config.get("base.language") == "CN" ? "CN" : "EN"}/wav/verify.wav`)
+
+ // 绛夊緟鍦ㄧ嚎楠岃瘉缁撴灉
+ let payload = driver.mqtt.getOnlinecheck()
+ if (payload && payload.serialNo == serialNo && payload.code == '000000') {
+ ret = true
+ // 鏆傚仠浜鸿劯璁よ瘉鍔熻兘
+ driver.face.status(false)
+ logger.info("[access]: 鏆傚仠浜鸿劯璁よ瘉鍔熻兘")
+ } else {
+ logger.info("[access]: 鍦ㄧ嚎楠岃瘉澶辫触")
+ ret = false
+ }
+ }
+ }
+
+ // 纭畾璇煶鏂囦欢鍚嶇О
+ let alsaFile = (data.type).toString().startsWith("10") ? '10x' : data.type
+
+ //鏆傚仠浜鸿劯璁よ瘉鍔熻兘
+
+
+ if (ret == true) {
+ // 楠岃瘉姘斾綋娴撳害
+ grainService.checkGasConcentration(function() {
+ // 浠庡瓨鍌ㄧ殑姘斾綋鏁版嵁涓幏鍙栭獙璇佺粨鏋�
+ const gasData = grainService.getGasData()
+
+ if(gasData && gasData.data && gasData.data.status === "0") {
+ logger.info("[access]: 姘斾綋娴撳害楠岃瘉鍚堟牸")
+ // 閫氳鎴愬姛澶勭悊
+ driver.screen.accessSuccess()
+ logger.info("[access]: 閫氳鎴愬姛")
+
+ // 鏄剧ず閫氳鎴愬姛缁撴灉
+ bus.fire("showAccessResult", {
+ faceAuth: true,
+ gasConcentration: true,
+ accessAllowed: true,
+ message: "*浠撳唴姘斾綋娴撳害鍚堟牸锛屽厑璁搁�氳*"
+ })
+
+ // 瑙﹀彂閫氳鎴愬姛浜嬩欢锛岄�氱煡UI鏇存柊
+ bus.fire("accessSuccess", { data: data, fileName: fileName })
+ driver.alsa.play(`/app/code/resource/${config.get("base.language") == "CN" ? "CN" : "EN"}/wav/access_s.wav`)
+ driver.gpio.open() // 寮�闂�
+ savePassPic(data, fileName) // 淇濆瓨閫氳鍥剧墖
+ reply(data, true) // 涓婃姤閫氳璁板綍
+ } else {
+ logger.info("[access]: 姘斾綋娴撳害楠岃瘉涓嶅悎鏍�")
+ // 閫氳澶辫触澶勭悊
+ driver.screen.accessFail()
+ logger.error("[access]: 閫氳澶辫触")
+ // 瑙﹀彂澶辫触寮圭獥
+ bus.fire("showAccessResult", {
+ faceAuth: true,
+ gasConcentration: false,
+ accessAllowed: false,
+ message: "*浠撳唴姘斾綋娴撳害涓嶅悎鏍硷紝绂佹閫氳*"
+ })
+ if (utils.isEmpty(similarity)) {
+ driver.alsa.play(`/app/code/resource/${config.get("base.language") == "CN" ? "CN" : "EN"}/wav/access_f.wav`)
+ }
+ // if (isStranger && !config.get("sys.strangerImage")) {
+ // // 闄岀敓浜轰笉淇濆瓨鐓х墖
+ // } else {
+ // savePassPic(data, fileName)
+ // }
+ savePassPic(data, fileName)
+ // 娣诲姞姘斾綋娴撳害澶辫触淇℃伅
+ data.message = "姘斾綋娴撳害涓嶅悎鏍�"
+ reply(data, false) // 涓婃姤閫氳璁板綍
+ }
+ })
+
+ } else {
+ // 閫氳澶辫触澶勭悊
+ driver.screen.accessFail()
+ logger.error("[access]: 閫氳澶辫触")
+ // 瑙﹀彂澶辫触寮圭獥
+ bus.fire("showAccessResult", {
+ faceAuth: true,
+ gasConcentration: false,
+ accessAllowed: false,
+ message: "*鏉冮檺璁よ瘉澶辫触锛岀姝㈤�氳*"
+ })
+ if (utils.isEmpty(similarity)) {
+ driver.alsa.play(`/app/code/resource/${config.get("base.language") == "CN" ? "CN" : "EN"}/wav/recg_f.wav`)
+ }
+ // if (isStranger && !config.get("sys.strangerImage")) {
+ // // 闄岀敓浜轰笉淇濆瓨鐓х墖
+ // } else {
+ // savePassPic(data, fileName)
+ // }
+ savePassPic(data, fileName)
+
+ reply(data, false) // 涓婃姤閫氳璁板綍
+ }
+ } catch (error) {
+ logger.error(error)
+ }
+
+ // 璇煶鎾姤闇�瑕佹椂闂达紝鎵�浠ュ欢杩�1绉掕В閿�
+ std.sleep(1000)
+ lockMap.put("access_lock", false)
+ logger.error("[access]: 瑙i攣鎴愬姛")
+ // 瑙﹀彂閫氳瑙i攣瀹屾垚浜嬩欢锛岄�氱煡UI閲嶇疆
+ // bus.fire("accessUnlockComplete")
+}
+
+/**
+ * 淇濆瓨閫氳鍥剧墖
+ * @param {object} data - 閫氳鏁版嵁
+ * @param {string} fileName - 鍥剧墖鏂囦欢璺緞
+ */
+function savePassPic(data, fileName) {
+ if (data.type == "300") { // 浠呭鐞嗕汉鑴哥被鍨�
+ // 濡傛灉鏄弻浜鸿璇侊紝宸茬粡鍦ㄥ鐞嗗弻浜鸿璇佷俊鎭椂淇濆瓨浜嗗浘鐗囷紝杩欓噷璺宠繃
+ if (data.dualAuthInfo) {
+ return
+ }
+ let src = `/app/data/passRecord/${data.userId}_${data.time}.jpg`
+ std.ensurePathExists(src) // 纭繚鐩綍瀛樺湪
+ if (std.exist(fileName)) {
+ // 绉诲姩鍥剧墖鍒版寚瀹氱洰褰�
+ common.systemBrief(`mv ${fileName} ${src}`)
+ // 鍙竻鐞嗗師濮嬩复鏃跺浘鐗囨枃浠讹紙浠ユ椂闂存埑鍛藉悕鐨勬枃浠讹級锛屼繚鐣欒皟鏁村悗鐨勫浘鐗囨枃浠�
+ common.systemBrief(`rm -rf /app/data/user/temp/[0-9]*.jpg`)
+ // 鏇存柊data涓殑code涓哄浘鐗囪矾寰�
+ data.code = src
+ } else {
+ logger.error("[access]: 閫氳澶辫触锛屽浘鐗囦笉瀛樺湪锛侊紒锛侊紒锛侊紒锛侊紒锛侊紒锛侊紒锛侊紒锛�" + fileName)
+ }
+ }
+}
+
+/**
+ * 鏍¢獙鏉冮檺鏃堕棿鏄惁鍙互閫氳
+ * @param {array} permissions - 鏉冮檺璁板綍鏁扮粍
+ * @returns {boolean} true琛ㄧず鏈夋潈闄愶紝false琛ㄧず鏃犳潈闄�
+ */
+function judgmentPermission(permissions) {
+ let currentTime = Math.floor(Date.now() / 1000)
+ for (let permission of permissions) {
+ if (permission.timeType == 0) {
+ // 姘镐箙鏉冮檺
+ return true
+ } else if (permission.beginTime <= currentTime && currentTime <= permission.endTime) {
+ if (permission.timeType == 1) {
+ // 鏃堕棿娈垫潈闄�
+ return true
+ }
+ if (permission.timeType == 2) {
+ // 姣忔棩鏉冮檺
+ let seconds = Math.floor((new Date() - new Date().setHours(0, 0, 0, 0)) / 1000);
+ if (permission.repeatBeginTime <= seconds && seconds <= permission.repeatEndTime) {
+ return true
+ }
+ }
+ if (permission.timeType == 3 && permission.period) {
+ // 鍛ㄩ噸澶嶆潈闄�
+ let dayTimes = JSON.parse(permission.period)[new Date().getDay() + 1]
+ if (dayTimes && dayTimes.split("|").some((dayTime) => isCurrentTimeInTimeRange(dayTime))) {
+ return true
+ }
+ }
+ }
+ }
+ return false
+}
+
+/**
+ * 鍒ゆ柇褰撳墠鏃堕棿鏄惁鍦ㄦ椂闂存鍐�
+ * @param {string} time - 鏃堕棿娈靛瓧绗︿覆锛屾牸寮忓"15:00-19:00"
+ * @returns {boolean} true琛ㄧず褰撳墠鏃堕棿鍦ㄦ椂闂存鍐咃紝false琛ㄧず涓嶅湪
+ */
+function isCurrentTimeInTimeRange(time) {
+ // 鍒嗗壊寮�濮嬫椂闂村拰缁撴潫鏃堕棿
+ let [startTime, endTime] = time.split('-');
+ // 瑙f瀽寮�濮嬫椂闂寸殑灏忔椂鍜屽垎閽�
+ let [startHour, startMinute] = startTime.split(':');
+ // 瑙f瀽缁撴潫鏃堕棿鐨勫皬鏃跺拰鍒嗛挓
+ let [endHour, endMinute] = endTime.split(':');
+
+ // 鑾峰彇褰撳墠鏃堕棿
+ let currentTime = new Date();
+
+ // 鍒涘缓寮�濮嬫椂闂寸殑鏃ユ湡瀵硅薄
+ let startDate = new Date();
+ startDate.setHours(parseInt(startHour, 10));
+ startDate.setMinutes(parseInt(startMinute, 10));
+ // 鍒涘缓缁撴潫鏃堕棿鐨勬棩鏈熷璞�
+ let endDate = new Date();
+ endDate.setHours(parseInt(endHour, 10));
+ endDate.setMinutes(parseInt(endMinute, 10));
+
+ // 妫�鏌ュ綋鍓嶆椂闂存槸鍚﹀湪鏃堕棿鑼冨洿鍐�
+ return currentTime >= startDate && currentTime <= endDate;
+}
+
+/**
+ * 閫氳璁板綍涓婃姤
+ * @param {object} data - 閫氳鏁版嵁
+ * @param {boolean} result - 閫氳缁撴灉锛宼rue琛ㄧず鎴愬姛锛宖alse琛ㄧず澶辫触
+ */
+function reply(data, result) {
+ // 浣跨敤绾跨▼澶勭悊鏁翠釜reply鍑芥暟锛岄伩鍏嶅牭濉炰富杩涚▼
+ std.setTimeout(() => {
+ try {
+ // 鏋勫缓閫氳璁板綍
+ let record = {
+ id: std.genRandomStr(16),
+ result: result ? 0 : 1, // 0琛ㄧず鎴愬姛锛�1琛ㄧず澶辫触
+ }
+
+ // 澶嶅埗data涓殑瀛楁锛屾帓闄xtra鍜宔xtra2
+ for (const key in data) {
+ if (key !== 'extra' && key !== 'extra2' && !(key in record)) {
+ record[key] = data[key]
+ }
+ }
+
+ // 澶勭悊extra瀛楁
+ if (data.extra) {
+ record.extra = JSON.stringify(data.extra)
+ }
+
+ // 澶勭悊extra2瀛楁
+ if (data.extra2) {
+ record.extra2 = JSON.stringify(data.extra2)
+ }
+
+ // 瀛樺偍閫氳璁板綍锛屽垽鏂笂闄�
+ let count = sqliteService.d1_pass_record.count()
+ let configNum = config.get("access.offlineAccessNum");
+ configNum = configNum ? configNum : 2000;
+
+ if (configNum > 0) {
+ if (count >= configNum) {
+ // 杈惧埌鏈�澶у瓨鍌ㄦ暟閲忥紝鍒犻櫎鏈�鏃х殑璁板綍
+ let lastRecord = sqliteService.d1_pass_record.findAllOrderBytimeDesc({ page: 0, size: 1 })
+ if (lastRecord && lastRecord.length == 1) {
+ // 濡傛灉鏄汉鑴歌褰曪紝鍒犻櫎瀵瑰簲鐨勫浘鐗囨枃浠�
+ if (lastRecord[0].type == 300) {
+ common.systemBrief(`rm -rf ${lastRecord[0].code}`)
+ }
+ sqliteService.d1_pass_record.deleteByid(lastRecord[0].id)
+ }
+ }
+ // 淇濆瓨鏂拌褰�
+ sqliteService.d1_pass_record.save(record)
+ }
+
+ // // 鐢熸垚搴忓垪鍙�
+ // let serialNo = std.genRandomStr(10)
+
+ // // 澶勭悊浜鸿劯鍥剧墖
+ // if (record.type == 300) {
+ // let m = map.get("faceAccesss")
+ // m.del(serialNo)
+ // m.put(serialNo, record.code ? record.code : "")
+ // // 灏嗗浘鐗囪浆鎹负base64鏍煎紡
+ // record.code = driver.face.fileToBase64(record.code)
+ // }
+
+ // // 鏋勫缓MQTT娑堟伅骞跺彂閫�
+ // let payload = mqttService.mqttReply(serialNo, [record], mqttService.CODE.S_000)
+ // driver.mqtt.send("access_device/v2/event/access", JSON.stringify(payload))
+ } catch (error) {
+ logger.error(`[accessService]: 澶勭悊閫氳璁板綍澶辫触: ${error.message}`)
+ }
+ }, 0)
+}
+
+export default accessService
diff --git a/vf205_access/src/service/codeService.js b/vf205_access/src/service/codeService.js
new file mode 100644
index 0000000..10dfe20
--- /dev/null
+++ b/vf205_access/src/service/codeService.js
@@ -0,0 +1,205 @@
+/**
+ * 浜岀淮鐮�/鏉″舰鐮佸鐞嗘湇鍔℃ā鍧�
+ * 澶勭悊鍚勭被浜岀淮鐮�/鏉″舰鐮佺殑瑙f瀽鍜屽鐞嗭紝鍖呮嫭閰嶇疆鐮併�佷簯璇佹縺娲荤爜鍜岄�氳鐮�
+ */
+import common from '../../dxmodules/dxCommon.js';
+import log from '../../dxmodules/dxLogger.js'
+import qrRule from '../../dxmodules/dxQrRule.js'
+import std from '../../dxmodules/dxStd.js'
+import config from '../../dxmodules/dxConfig.js'
+import base64 from '../../dxmodules/dxBase64.js'
+import dxMap from '../../dxmodules/dxMap.js'
+import ota from "../../dxmodules/dxOta.js";
+import bus from "../../dxmodules/dxEventBus.js"
+import sqliteService from "./sqliteService.js";
+import driver from '../driver.js';
+import utils from '../common/utils/utils.js';
+import configConst from '../common/consts/configConst.js';
+import configService from './configService.js';
+import accessService from './accessService.js';
+import logger from '../../dxmodules/dxLogger.js';
+const codeService = {}
+
+/**
+ * 鎺ユ敹娑堟伅骞跺鐞�
+ * @param {ArrayBuffer} data - 鎺ユ敹鍒扮殑鍘熷鏁版嵁
+ */
+codeService.receiveMsg = function (data) {
+ log.info('[codeService] receiveMsg :' + JSON.stringify(data))
+ // 灏咥rrayBuffer杞崲涓哄崄鍏繘鍒跺瓧绗︿覆锛屽啀杞崲涓篣TF8瀛楃涓�
+ let str = common.utf8HexToStr(common.arrayBufferToHexString(data))
+ // 璋冪敤code鏂规硶澶勭悊瀛楃涓�
+ this.code(str)
+}
+
+/**
+ * 姣旇緝涓や釜瀛楃涓茬殑鍓峃涓瓧绗︽槸鍚︾浉绛�
+ * @param {string} str1 - 绗竴涓瓧绗︿覆
+ * @param {string} str2 - 绗簩涓瓧绗︿覆
+ * @param {number} N - 姣旇緝鐨勫瓧绗︽暟
+ * @returns {boolean} 鍓峃涓瓧绗︽槸鍚︾浉绛�
+ */
+function comparePrefix (str1, str2, N) {
+ let substring1 = str1.substring(0, N);
+ let substring2 = str2.substring(0, N);
+ return substring1 === substring2;
+}
+
+/**
+ * 澶勭悊浜岀淮鐮�/鏉″舰鐮佹暟鎹�
+ * @param {string} data - 浜岀淮鐮�/鏉″舰鐮佺殑鍘熷鏁版嵁
+ */
+codeService.code = function (data) {
+ log.info('[codeService] code :' + data)
+ // 鏍煎紡鍖栦簩缁寸爜鏁版嵁
+ data = qrRule.formatCode(data, sqliteService)
+
+ // 鍒ゆ柇浜岀淮鐮佺被鍨�
+ if (data.type == 'config' || comparePrefix(data.code, "___VF102_CONFIG_V1.1.0___", "___VF102_CONFIG_V1.1.0___".length)) {
+ // 閰嶇疆鐮佸鐞�
+ configCode(data.code)
+ } else if (comparePrefix(data.code, "___VBAR_ID_ACTIVE_V", "___VBAR_ID_ACTIVE_V".length)) {
+ // 浜戣瘉婵�娲荤爜澶勭悊
+ let activeResute = driver.eid.active(config.get("sys.sn"), config.get("sys.appVersion"), config.get("sys.mac"), data.code);
+ log.info("[codeService] code: activeResute " + activeResute)
+ if (activeResute === 0) {
+ log.info("[codeService] code: 浜戣瘉婵�娲绘垚鍔�")
+ driver.screen.upgrade({ title: "confirm.cloudCertActive", content: "confirm.cloudCertActiveSuccess" })
+ } else {
+ log.info("[codeService] code: 浜戣瘉婵�娲诲け璐�")
+ driver.screen.upgrade({ title: "confirm.cloudCertActive", content: "confirm.cloudCertActiveFail" })
+ }
+ } else {
+ // 閫氳鐮佸鐞�
+ log.info("瑙f瀽閫氳鐮侊細", JSON.stringify(data))
+ bus.fire("access", { data })
+ }
+}
+
+/**
+ * 閰嶇疆鐮佸鐞�
+ * @param {string} code - 閰嶇疆鐮佹暟鎹�
+ * @param {boolean} configType - 閰嶇疆绫诲瀷鏍囧織
+ */
+function configCode (code, configType) {
+ // 閰嶇疆鐮佹牎楠屾殏鏃舵敞閲�
+ // if (!checkConfigCode(code)) {
+ // log.error("閰嶇疆鐮佹牎楠屽け璐�")
+ // return
+ // }
+
+ // 瑙f瀽閰嶇疆鐮佷负JSON瀵硅薄
+ let json = utils.parseString(code)
+ if (Object.keys(json).length <= 0) {
+ try {
+ json = JSON.parse(code.slice(code.indexOf("{"), code.lastIndexOf("}") + 1))
+ } catch (error) {
+ log.error(error)
+ }
+ }
+ log.info("瑙f瀽閰嶇疆鐮侊細", JSON.stringify(json))
+
+ // 妯″紡鍒囨崲澶勭悊
+ if (!utils.isEmpty(json.w_model)) {
+ try {
+ common.setMode(json.w_model)
+ common.asyncReboot(1)
+ } catch (error) {
+ log.error(error, error.stack)
+ log.info('鍒囨崲澶辫触涓嶅仛浠讳綍澶勭悊');
+ }
+ return
+ }
+
+ let map = dxMap.get("UPDATE")
+ // 鎵爜鍗囩骇澶勭悊
+ if (json.update_flag === 1) {
+ if (!driver.net.getStatus()) {
+ driver.alsa.play(`/app/code/resource/${config.get("base.language") == "CN" ? "CN" : "EN"}/wav/network.wav`)
+ return
+ }
+ if (map.get("updateFlag")) {
+ return
+ }
+ map.put("updateFlag", true)
+ try {
+ driver.screen.upgrade({ title: "confirm.upgrade", content: "confirm.upgrading" })
+ ota.updateHttp(json.update_addr, json.update_md5, 300)
+ driver.screen.upgrade({ title: "confirm.upgrade", content: "confirm.upgradeSuccess" })
+ } catch (error) {
+ logger.info(error.message)
+ driver.screen.upgrade({ title: "confirm.upgrade", content: "confirm.upgradeFail" })
+ } finally {
+ map.del("updateFlag")
+ }
+ common.asyncReboot(3)
+ return
+ }
+
+ // 璁惧閰嶇疆澶勭悊
+ let configData = {}
+ for (let key in json) {
+ let transKey
+ if (configType == true) {
+ transKey = key
+ } else {
+ transKey = configConst.getValueByKey(key)
+ }
+ if (transKey == undefined) {
+ continue
+ }
+ let keys = transKey.split(".")
+ if (utils.isEmpty(configData[keys[0]])) {
+ configData[keys[0]] = {}
+ }
+ configData[keys[0]][keys[1]] = json[key]
+ }
+
+ let res = false
+ if (Object.keys(configData).length > 0) {
+ res = configService.configVerifyAndSave(configData)
+ }
+
+ if (typeof res != 'boolean') {
+ log.error(res)
+ return
+ }
+
+ if (res) {
+ log.info("閰嶇疆鎴愬姛")
+ } else {
+ log.error("閰嶇疆澶辫触")
+ }
+
+ // 閰嶇疆鍚庨噸鍚�
+ if (json.reboot === 1) {
+ driver.screen.warning({ msg: config.get("sysInfo.language") == 1 ? "Rebooting" : "閲嶅惎涓�", beep: false })
+ common.asyncReboot(1)
+ }
+}
+
+/**
+ * 鏍¢獙閰嶇疆鐮�
+ * @param {string} code - 閰嶇疆鐮佹暟鎹�
+ * @returns {boolean} 鏍¢獙鏄惁鎴愬姛
+ */
+function checkConfigCode (code) {
+ let password = config.get('sysInfo.com_passwd') || '1234567887654321'
+ let lastIndex = code.lastIndexOf("--");
+ if (lastIndex < 0) {
+ lastIndex = code.lastIndexOf("__");
+ }
+ let firstPart = code.substring(0, lastIndex);
+ let secondPart = code.substring(lastIndex + 2);
+ let res
+ try {
+ res = base64.fromHexString(common.arrayBufferToHexString(common.hmac(firstPart, password)))
+ } catch (error) {
+ log.error(error)
+ return false
+ }
+
+ return res == secondPart;
+}
+
+export default codeService
diff --git a/vf205_access/src/service/configService.js b/vf205_access/src/service/configService.js
new file mode 100644
index 0000000..77c0387
--- /dev/null
+++ b/vf205_access/src/service/configService.js
@@ -0,0 +1,273 @@
+/**
+ * 閰嶇疆鏈嶅姟妯″潡
+ * 璐熻矗閰嶇疆鐨勬牎楠屻�佷繚瀛樺拰搴旂敤锛屽寘鎷悇绉嶉厤缃」鐨勮鍒欓獙璇佸拰鍥炶皟澶勭悊
+ */
+import utils from '../common/utils/utils.js'
+import config from '../../dxmodules/dxConfig.js'
+import mqtt from '../../dxmodules/dxMqtt.js'
+import std from '../../dxmodules/dxStd.js'
+import ntp from '../../dxmodules/dxNtp.js'
+import common from '../../dxmodules/dxCommon.js'
+import driver from '../driver.js'
+import bus from '../../dxmodules/dxEventBus.js'
+import mqttService from './mqttService.js'
+import logger from '../../dxmodules/dxLogger.js'
+const configService = {}
+
+/**
+ * IP鍦板潃鏍¢獙姝e垯
+ * 鍖归厤浠ョ偣鍒嗗崄杩涘埗褰㈠紡琛ㄧず鐨� IP 鍦板潃锛屼緥濡傦細192.168.0.1
+ */
+const ipCheck = v => /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?).){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/.test(v)
+
+/**
+ * IP鍦板潃鎴栧煙鍚嶆牎楠屾鍒欙紙甯︾鍙o級
+ * 鍖归厤IP鍦板潃鎴栧煙鍚嶏紝鍙�夋嫨甯︽湁绔彛鍙�
+ */
+const ipOrDomainCheckWithPort = v => /^(?:(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)|(?:[a-zA-Z0-9-]+\.)+[a-zA-Z]{2,})(:\d{1,5})?$/.test(v);
+
+/**
+ * 姝f暣鏁版牎楠屾鍒�
+ */
+const regpCheck = v => /^[1-9]\d*$/.test(v)
+
+/**
+ * 闈炶礋鏁存暟鏍¢獙姝e垯
+ */
+const regnCheck = v => /^([1-9]\d*|0{1})$/.test(v)
+
+/**
+ * 鎵�鏈夋敮鎸佺殑閰嶇疆椤圭殑妫�楠岃鍒欎互鍙婅缃垚鍔熷悗鐨勫洖璋�
+ * rule锛氭牎楠岃鍒欙紝杩斿洖true鏍¢獙鎴愬姛锛宖alse鏍¢獙澶辫触
+ * callback锛氶厤缃慨鏀硅Е鍙戝洖璋�
+ */
+const supported = {
+ // 浜鸿劯閰嶇疆
+ face: {
+ similarity: { rule: v => typeof v == 'number' && v >= 0 && v <= 1, callback: v => driver.face.faceUpdateConfig({ score: v }) },
+ livenessOff: { rule: v => [0, 1].includes(v), callback: v => driver.face.faceUpdateConfig({ livingCheckEnable: v }) },
+ livenessVal: { rule: v => typeof v == 'number' && v >= 0 && v <= 1, callback: v => driver.face.faceUpdateConfig({ livingScore: v }) },
+ showNir: { rule: v => [0, 1].includes(v), callback: v => driver.capturer.showNir(v) },
+ detectMask: { rule: v => [0, 1].includes(v), callback: v => driver.face.faceUpdateConfig({ detectMaskEnable: v }) },
+ stranger: { rule: v => [0, 1, 2].includes(v) },
+ voiceMode: { rule: v => [0, 1, 2].includes(v) },
+ voiceModeDate: { rule: v => typeof v == 'string' },
+ },
+ // MQTT閰嶇疆
+ mqtt: {
+ addr: { rule: ipOrDomainCheckWithPort },
+ clientId: { rule: v => typeof v == 'string' },
+ username: { rule: v => typeof v == 'string' },
+ password: { rule: v => typeof v == 'string' },
+ qos: { rule: v => [0, 1, 2].includes(v) },
+ prefix: { rule: v => typeof v == 'string' },
+ willtopic: { rule: v => typeof v == 'string' },
+ onlinecheck: { rule: v => [0, 1, 2].includes(v) },
+ timeout: { rule: regpCheck },
+ },
+ // 缃戠粶閰嶇疆
+ net: {
+ type: { rule: v => [0, 1, 2, 4].includes(v) }, // 缃戠粶绫诲瀷
+ dhcp: { rule: v => [1, 2, 3].includes(v) }, // DHCP璁剧疆
+ ip: { rule: ipCheck }, // IP鍦板潃
+ gateway: { rule: ipCheck }, // 缃戝叧鍦板潃
+ dns: { rule: v => !v.split(",").some(ip => !ipCheck(ip)) }, // DNS鏈嶅姟鍣�
+ mask: { rule: ipCheck }, // 瀛愮綉鎺╃爜
+ mac: { rule: v => typeof v == 'string' }, // MAC鍦板潃
+ ssid: { rule: v => typeof v == 'string' }, // WiFi SSID
+ psk: { rule: v => typeof v == 'string' }, // WiFi瀵嗙爜
+ },
+ // NTP鏃堕棿鍚屾閰嶇疆
+ ntp: {
+ ntp: { rule: v => [0, 1].includes(v) }, // NTP寮�鍏�
+ server: { rule: ipCheck }, // NTP鏈嶅姟鍣�
+ gmt: { rule: v => typeof v == 'number' && v >= 0 && v <= 24, callback: v => ntp.updateGmt(v) }, // 鏃跺尯璁剧疆
+ },
+ // 绯荤粺閰嶇疆
+ sys: {
+ uuid: { rule: v => typeof v == 'string' }, // 璁惧UUID
+ model: { rule: v => typeof v == 'string' }, // 璁惧鍨嬪彿
+ mode: { rule: v => typeof v == 'string', callback: v => setMode(v) }, // 璁惧妯″紡
+ sn: { rule: v => typeof v == 'string' }, // 璁惧搴忓垪鍙�
+ version: { rule: v => typeof v == 'string' }, // 绯荤粺鐗堟湰
+ releaseDate: { rule: v => typeof v == 'string' }, // 鍙戝竷鏃ユ湡
+ nfc: { rule: v => [0, 1].includes(v) }, // NFC寮�鍏�
+ nfcIdentityCardEnable: { rule: v => [1, 3].includes(v) }, // 浜戣瘉寮�鍏�
+ pwd: { rule: v => [0, 1].includes(v) }, // 瀵嗙爜寮�闂ㄥ紑鍏�
+ strangerImage: { rule: v => [0, 1].includes(v) }, // 闄岀敓浜轰繚瀛樺浘鐗囧紑鍏�
+ accessImageType: { rule: v => [0, 1].includes(v) }, // 閫氳鍥剧墖绫诲瀷
+ interval: { rule: regnCheck }, // 绯荤粺闂撮殧璁剧疆
+ },
+ // 闂ㄧ閰嶇疆
+ access: {
+ relayTime: { rule: regpCheck }, // 缁х數鍣ㄥ姩浣滄椂闂�
+ offlineAccessNum: { rule: regpCheck }, // 绂荤嚎寮�闂ㄦ鏁�
+ tamperAlarm: { rule: v => [0, 1].includes(v) }, // 闃叉媶鎶ヨ寮�鍏�
+ },
+ // 鍩虹閰嶇疆
+ base: {
+ firstLogin: { rule: v => [0, 1].includes(v) }, // 棣栨鐧诲綍鏍囧織
+ brightness: { rule: regnCheck, callback: v => driver.face.setDisplayBacklight(v) }, // 灞忓箷浜害
+ brightnessAuto: { rule: v => [0, 1].includes(v) }, // 鑷姩浜害寮�鍏�
+ showIp: { rule: v => [0, 1].includes(v), callback: v => driver.screen.hideIp(v) }, // 鏄惁鏄剧ずIP鍦板潃
+ showSn: { rule: v => [0, 1].includes(v), callback: v => driver.screen.hideSn(v) }, // 鏄惁鏄剧ず搴忓垪鍙�
+ appMode: { rule: v => [0, 1].includes(v), callback: v => driver.screen.appMode(v) }, // 搴旂敤妯″紡
+ screenOff: { rule: regnCheck, callback: v => bus.fire("screenManagerRefresh") }, // 鐔勫睆鏃堕棿
+ screensaver: { rule: regnCheck, callback: v => bus.fire("screenManagerRefresh") }, // 灞忓箷淇濇姢
+ volume: { rule: regnCheck, callback: v => driver.alsa.volume(v) }, // 闊抽噺璁剧疆
+ password: { rule: v => typeof v == 'string' && v.length >= 8 }, // 绠$悊鍛樺瘑鐮�
+ language: { rule: v => ["EN", "CN"].includes(v), callback: v => driver.screen.changeLanguage() }, // 璇█璁剧疆
+ showProgramCode: { rule: v => [0, 1].includes(v) }, // 鏄惁鏄剧ず绋嬪簭浠g爜
+ showIdentityCard: { rule: v => [0, 1].includes(v) }, // 鏄惁鏄剧ず韬唤璇佷俊鎭�
+ luminanceWhite: { rule: v => typeof v == 'number' && v >= 0 && v <= 100, callback: v => driver.pwm.luminanceWhite(v) }, // 鐧藉厜浜害
+ luminanceNir: { rule: v => typeof v == 'number' && v >= 0 && v <= 100, callback: v => driver.pwm.luminanceNir(v) }, // 绾㈠鍏変寒搴�
+ },
+ // 瀵嗙爜閫氳閰嶇疆
+ passwordAccess: {
+ passwordAccess: { rule: v => [0, 1].includes(v) }, // 瀵嗙爜閫氳寮�鍏�
+ emergencyPassword: { rule: v => typeof v == 'string' && v.length >= 8 }, // 搴旀�ュ紑浠撳瘑鐮�
+ },
+ // HTTP閰嶇疆
+ http: {
+ gas: { rule: v => typeof v == 'string' }, // HTTP_姘斾綋
+ status: { rule: v => typeof v == 'string' }, // HTTP_鐘舵��
+ safeInputAccess: { rule: v => typeof v == 'string' } // HTTP鎺ュ彛璺緞
+ },
+ // 浠撳粧鍚嶇О
+ houseName: {},
+ // 搴撳尯鍚嶇О
+ GranaryName: {},
+ // 鏇存柊閰嶇疆
+ update: {
+ gasTime: { rule: regpCheck }, // 姘斾綋娴撳害鏇存柊鏃堕棿锛堢锛�
+ statusTime: { rule: regpCheck } // 鐘舵�佷俊鎭洿鏂版椂闂达紙绉掞級
+ }
+}
+
+/**
+ * 闇�瑕侀噸鍚殑閰嶇疆椤�
+ */
+const needReboot = ["sys.nfc", "sys.nfcIdentityCardEnable", "ntp"]
+configService.needReboot = needReboot
+
+/**
+ * 淇敼璁惧妯″紡
+ * @param {string} params - 妯″紡鍙傛暟
+ */
+function setMode(params) {
+ common.systemWithRes(`echo 'app' > /etc/.app_v1`, 2)
+ common.setMode(params)
+}
+
+/**
+ * 閰嶇疆json鏍¢獙骞朵繚瀛�
+ * @param {object} data - 閰嶇疆json瀵硅薄
+ * @returns {boolean|string} true琛ㄧず鏍¢獙骞朵繚瀛樻垚鍔燂紝string琛ㄧず閿欒淇℃伅
+ */
+configService.configVerifyAndSave = function (data) {
+ let netFlag = false // 缃戠粶閰嶇疆鏍囧織
+ let mqttFlag = false // MQTT閰嶇疆鏍囧織
+ let isReboot = false // 鏄惁闇�瑕侀噸鍚�
+
+ for (const key in data) {
+ if (key == 'net') {
+ netFlag = true
+ }
+ if (key == 'mqtt') {
+ mqttFlag = true
+ }
+
+ // 妫�鏌ラ厤缃粍鏄惁鏀寔
+ if (!supported[key]) {
+ return key + " not supported"
+ }
+
+ const item = data[key];
+ if (typeof item != 'object') {
+ // 椤跺眰閰嶇疆椤癸紝鐩存帴淇濆瓨
+ config.set(key, item)
+ continue
+ }
+
+ // 妫�鏌ユ槸鍚﹂渶瑕侀噸鍚�
+ if (needReboot.includes(key)) {
+ isReboot = true
+ }
+
+ for (const subKey in item) {
+ let option = supported[key][subKey]
+ if (isEmpty(option)) {
+ return subKey + " not supported"
+ }
+
+ const value = item[subKey];
+
+ // 妫�鏌ユ槸鍚﹂渶瑕侀噸鍚�
+ if (needReboot.includes(key + "." + subKey)) {
+ isReboot = true
+ }
+
+ // 鏍¢獙閰嶇疆鍊�
+ if (!option.rule || option.rule(value)) {
+ // 娌℃湁鏍¢獙瑙勫垯榛樿鏍¢獙閫氳繃
+ config.set(key + "." + subKey, value)
+ if (option.callback) {
+ // 鎵ц閰嶇疆璁剧疆鍥炶皟
+ option.callback(value)
+ }
+ } else {
+ return value + " check failure"
+ }
+ }
+ }
+
+ // 淇濆瓨閰嶇疆
+ config.save()
+
+ // 妫�鏌ラ渶瑕侀噸鍚殑閰嶇疆锛�3绉掑悗閲嶅惎
+ if (isReboot) {
+ driver.screen.upgrade({ title: "confirm.restartDevice", content: "confirm.restartDeviceDis" })
+ common.asyncReboot(3)
+ }
+
+ // 澶勭悊缃戠粶閰嶇疆鍙樻洿
+ if (netFlag) {
+ // 绛夊緟 1 绉� 鍥犱负闇�瑕佽繑鍥� mqtt
+ std.setTimeout(() => {
+ bus.fire("switchNetworkType", config.get("net.type"))
+ }, 1000);
+ }
+
+ // 澶勭悊MQTT閰嶇疆鍙樻洿
+ if (mqttFlag) {
+ let option = {
+ mqttAddr: config.get("mqtt.addr"),
+ clientId: config.get('mqtt.clientId') + std.genRandomStr(3),
+ subs: mqttService.getTopics(),
+ username: config.get("mqtt.username"),
+ password: config.get("mqtt.password"),
+ qos: config.get("mqtt.qos"),
+ willTopic: config.get("mqtt.willTopic"),
+ willMessage: JSON.stringify({ "uuid": config.get("sys.uuid") })
+ }
+ logger.info("閲嶅惎mqtt", JSON.stringify(option))
+ // 閿�姣� mqtt 閲嶆柊 init
+ bus.fire(mqtt.RECONNECT, option)
+ }
+
+ // 瑙﹀彂閰嶇疆鏇存柊浜嬩欢锛岄�氱煡鍏朵粬妯″潡閰嶇疆宸叉洿鏂�
+ bus.fire('configUpdated')
+
+ return true
+}
+
+/**
+ * 鍒ょ┖鍑芥暟
+ * @param {*} value - 瑕佸垽鏂殑鍊�
+ * @returns {boolean} true琛ㄧず鍊间负绌猴紝false琛ㄧず鍊间笉涓虹┖
+ */
+function isEmpty(value) {
+ return value === undefined || value === null
+}
+
+export default configService
\ No newline at end of file
diff --git a/vf205_access/src/service/faceService.js b/vf205_access/src/service/faceService.js
new file mode 100644
index 0000000..a84aab1
--- /dev/null
+++ b/vf205_access/src/service/faceService.js
@@ -0,0 +1,447 @@
+/**
+ * 浜鸿劯璇嗗埆鏈嶅姟妯″潡
+ * 澶勭悊浜鸿劯璇嗗埆鐩稿叧鐨勪笟鍔¢�昏緫锛屽寘鎷汉鑴告敞鍐屽拰浜鸿劯姣斿
+ */
+import logger from "../../dxmodules/dxLogger.js";
+import dxCommon from "../../dxmodules/dxCommon.js";
+import bus from "../../dxmodules/dxEventBus.js";
+import dxMap from "../../dxmodules/dxMap.js";
+import driver from "../driver.js";
+import config from "../../dxmodules/dxConfig.js";
+import sqliteService from "./sqliteService.js";
+import std from "../../dxmodules/dxStd.js";
+import pool from "../../dxmodules/dxWorkerPool.js";
+
+let map = dxMap.get("LOGIN")
+const faceService = {}
+
+// 璇煶鎾斁闃叉姈鎺у埗
+let lastPlayTime = 0
+const PLAY_DELAY = 2000 // 2绉掑唴涓嶉噸澶嶆挱鏀剧浉鍚岃闊�
+
+/**
+ * 璇煶鎾斁闃叉姈鍑芥暟
+ * @param {function} playFunction - 鎾斁鍑芥暟
+ * @returns {boolean} 鏄惁鎵ц浜嗘挱鏀�
+ */
+function debouncePlay(playFunction) {
+ const now = Date.now()
+ if (now - lastPlayTime > PLAY_DELAY) {
+ lastPlayTime = now
+ playFunction()
+ return true
+ }
+ return false
+}
+
+// 鍙屼汉璁よ瘉鐘舵�佺鐞�
+let dualAuthState = {
+ firstUserId: null, // 绗竴涓敤鎴稩D
+ firstUserName: null, // 绗竴涓敤鎴峰鍚�
+ firstUserFileName: null, // 绗竴涓敤鎴蜂汉鑴稿浘鐗囨枃浠惰矾寰�
+ firstUserIdCard: null, // 绗竴涓敤鎴疯韩浠借瘉鍙�
+ firstUserType: null, // 绗竴涓敤鎴疯韩浠界被鍨�
+ secondUserId: null, // 绗簩涓敤鎴稩D
+ secondUserName: null, // 绗簩涓敤鎴峰鍚�
+ secondUserIdCard: null, // 绗簩涓敤鎴疯韩浠借瘉鍙�
+ secondUserType: null, // 绗簩涓敤鎴疯韩浠界被鍨�
+ startTime: 0, // 寮�濮嬫椂闂�
+ timeout: null, // 瀹氭椂鍣�
+ authComplete: false // 璁よ瘉鏄惁瀹屾垚
+}
+
+/**
+ * 鎺ユ敹浜鸿劯璇嗗埆娑堟伅骞跺鐞�
+ * @param {object} data - 浜鸿劯璇嗗埆鏁版嵁
+ */
+faceService.receiveMsg = function (data) {
+ logger.info('[faceService] receiveMsg :' + JSON.stringify(data))
+ // 瑙﹀彂閫�鍑虹┖闂茬姸鎬佷簨浠讹紙閿佸睆鍜屾伅灞忥級
+ bus.fire("exitIdle")
+
+ switch (data.type) {
+ case "register":
+ // 娉ㄥ唽浜鸿劯澶勭悊
+ for (let i = 0; i < data.faces.length; i++) {
+ const element = data.faces[i];
+ bus.fire("beginAddFace", element)
+ }
+ break;
+ case "compare":
+ // 浜鸿劯姣斿澶勭悊
+ // 鏄剧ず濮撳悕锛屼唬琛ㄦ湁娉ㄥ唽杩囦汉鑴革紝浣嗘槸鏉冮檺涓嶄竴瀹氭湁鏁堬紝闇�瑕佽繘涓�姝ヨ璇�
+ for (let i = 0; i < data.faces.length; i++) {
+ const element = data.faces[i];
+
+ // 鍙湁鍦ㄨ璇佹湭瀹屾垚鏃舵墠瑙﹀彂trackResult浜嬩欢
+ if (!dualAuthState.authComplete) {
+ // 鍒ゆ柇褰撳墠鏄鍑犱釜鐢ㄦ埛锛堢敤浜庡弻浜鸿璇侊級
+ let userIndex = 1 // 0琛ㄧず鏈煡锛�1琛ㄧず绗竴涓敤鎴凤紝2琛ㄧず绗簩涓敤鎴�
+ if (!dualAuthState.firstUserId) {
+ // 绗竴涓敤鎴疯繕鏈缃紝褰撳墠鐢ㄦ埛灏辨槸绗竴涓敤鎴�
+ userIndex = 1
+ } else if (element.userId === dualAuthState.firstUserId) {
+ userIndex = 1
+ } else if (element.userId !== dualAuthState.firstUserId) {
+ userIndex = 2
+ }
+
+ logger.info('[faceService]: 鍑嗗瑙﹀彂trackResult浜嬩欢, userIndex=' + userIndex + ', result=' + element.result + ', userId=' + element.userId + ', authComplete=' + dualAuthState.authComplete + ', fileName=' + element.fileName)
+
+ // 鐩存帴浣跨敤bus.fire瑙﹀彂trackResult浜嬩欢
+ bus.fire("trackResult", { id: element.id, result: element.result, userId: element.userId, userIndex: userIndex, fileName: element.fileName })
+ }
+
+ if (element.result) {
+ // 浜鸿劯鐩镐技搴﹂獙璇侀�氳繃
+ let ret = sqliteService.d1_person.find({ userId: element.userId })
+
+ if (dxMap.get("UI").get("faceAuthStart") == "Y") {
+ // 姝e湪浜鸿劯鐧诲綍
+ if (JSON.parse(ret[0].extra).type != 0) {
+ bus.fire("faceAuthResult", true)
+ } else {
+ bus.fire("faceAuthResult", false)
+ }
+ return
+ }
+
+ // 妫�鏌ョ敤鎴风被鍨嬶紙绠$悊鍛樼骇鍒級
+ let userType = 0
+ try {
+ userType = JSON.parse(ret[0].extra).type || 0
+ } catch (error) {
+ logger.error("瑙f瀽鐢ㄦ埛绫诲瀷澶辫触")
+ }
+
+ // 绠$悊鍛樼骇鍒敤鎴凤紙type != 0锛夌洿鎺ヨ璇侀�氳繃
+ if (userType != 0) {
+ // 娓呴櫎鍙屼汉璁よ瘉鐘舵��
+ clearDualAuthState()
+
+ // 鏍规嵁璇煶妯″紡鎾斁鐩稿簲鐨勮闊�
+ switch (config.get("face.voiceMode")) {
+ case 0:
+ // 鏃犺闊�
+ break;
+ case 1:
+ // 鎾斁鍚嶅瓧
+ driver.alsa.ttsPlay(ret[0].name)
+ break;
+ case 2:
+ // 鎾斁闂�欒
+ driver.alsa.ttsPlay(config.get("face.voiceModeDate") ? config.get("face.voiceModeDate") : "娆㈣繋鍏変复")
+ break;
+ default:
+ break;
+ }
+
+ // 閫氳璁よ瘉澶勭悊
+ bus.fire("access", { data: { type: "300", code: element.userId }, fileName: element.fileName })
+ } else {
+ // 闈炵鐞嗗憳绾у埆鐢ㄦ埛锛岄渶瑕佸弻浜鸿璇�
+ handleDualAuth(element.userId, ret[0].name, element.fileName)
+ }
+ } else {
+ // 浜鸿劯鐩镐技搴﹂獙璇佸け璐�
+ if (dxMap.get("UI").get("faceAuthStart") == "Y") {
+ // 浜鸿劯鐧诲綍澶辫触
+ bus.fire("faceAuthResult", false)
+ } else {
+ // 闄岀敓浜哄鐞�
+ switch (config.get("face.stranger")) {
+ case 0:
+ // 鏃犺闊�
+ break;
+ case 1:
+ // 鎾斁璇峰厛娉ㄥ唽锛堥槻鎶栨帶鍒讹級
+ debouncePlay(() => {
+ driver.alsa.play(`/app/code/resource/${config.get("base.language") == "CN" ? "CN" : "EN"}/wav/register.wav`)
+ })
+ break;
+ case 2:
+ // 鎾斁闄岀敓浜轰綘濂斤紙闃叉姈鎺у埗锛�
+ debouncePlay(() => {
+ driver.alsa.play(`/app/code/resource/${config.get("base.language") == "CN" ? "CN" : "EN"}/wav/stranger.wav`)
+ })
+ break;
+ default:
+ break;
+ }
+ // 閫氳璁よ瘉澶勭悊锛堢浉浼煎害楠岃瘉澶辫触锛�
+ bus.fire("access", { data: { type: "300", code: element.userId }, fileName: element.fileName, similarity: false })
+ }
+ }
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+// 鐩戝惉閫氳瑙i攣瀹屾垚浜嬩欢锛岄噸缃弻浜鸿璇佺姸鎬�
+bus.on('accessUnlockComplete', () => {
+ logger.info('[faceService]: accessUnlockComplete浜嬩欢瑙﹀彂锛岄噸缃弻浜鸿璇佺姸鎬�')
+ clearDualAuthState()
+})
+
+/**
+ * 娓呴櫎鍙屼汉璁よ瘉鐘舵��
+ */
+function clearDualAuthState() {
+ dualAuthState.firstUserId = null
+ dualAuthState.firstUserName = null
+ dualAuthState.firstUserFileName = null
+ dualAuthState.firstUserIdCard = null
+ dualAuthState.firstUserType = null
+ dualAuthState.secondUserId = null
+ dualAuthState.secondUserName = null
+ dualAuthState.secondUserIdCard = null
+ dualAuthState.secondUserType = null
+ dualAuthState.startTime = 0
+ dualAuthState.authComplete = false // 閲嶇疆璁よ瘉瀹屾垚鏍囧織
+ if (dualAuthState.timeout) {
+ std.clearTimeout(dualAuthState.timeout)
+ dualAuthState.timeout = null
+ }
+}
+
+/**
+ * 澶勭悊鍙屼汉璁よ瘉瓒呮椂
+ */
+function handleDualAuthTimeout() {
+ try {
+ // 淇濆瓨璁よ瘉璁板綍
+ if (dualAuthState.firstUserId && !dualAuthState.authComplete) {
+ // 鏌ヨ绗竴鐢ㄦ埛鐨勮缁嗕俊鎭紝鑾峰彇韬唤绫诲瀷
+ let firstUserType = dualAuthState.firstUserType || 0
+ if (!firstUserType) {
+ let res = sqliteService.d1_person.findByUserId(dualAuthState.firstUserId)
+ if (res.length > 0) {
+ try {
+ firstUserType = JSON.parse(res[0].extra).type || 0
+ } catch (error) {
+ logger.error("鏃犵涓�鐢ㄦ埛绫诲瀷")
+ }
+ }
+ }
+
+ // 鏌ヨ绗簩鐢ㄦ埛鐨勮缁嗕俊鎭紝鑾峰彇韬唤绫诲瀷
+ let secondUserType = dualAuthState.secondUserType || 0
+ if (dualAuthState.secondUserId && !secondUserType) {
+ let res = sqliteService.d1_person.findByUserId(dualAuthState.secondUserId)
+ if (res.length > 0) {
+ try {
+ secondUserType = JSON.parse(res[0].extra).type || 0
+ } catch (error) {
+ logger.error("鏃犵浜岀敤鎴风被鍨�")
+ }
+ }
+ }
+
+ // 鍒涘缓璁よ瘉璁板綍
+ const record = {
+ id: std.genRandomStr(16),
+ userId: dualAuthState.firstUserId,
+ userId2: dualAuthState.secondUserId || "",
+ type: "300", // 浜鸿劯璁よ瘉锛堝瓧绗︿覆鏍煎紡锛�
+ code: dualAuthState.firstUserFileName, // 浜鸿劯鎶撴媿鍥剧墖璺緞
+ result: 1, // 璁よ瘉澶辫触锛�0鎴愬姛锛�1澶辫触锛�
+ time: Math.floor(Date.now() / 1000), // 鏃堕棿鎴筹紙绉掞級
+ message: "鍙屼汉璁よ瘉瓒呮椂",
+ extra: JSON.stringify({ name: dualAuthState.firstUserName, idCard: dualAuthState.firstUserIdCard, type: firstUserType }),
+ extra2: dualAuthState.secondUserId ? JSON.stringify({ name: dualAuthState.secondUserName || "", idCard: dualAuthState.secondUserIdCard || "", type: secondUserType }) : "",
+ permissionId: firstUserType.toString(),
+ permissionId2: dualAuthState.secondUserId ? secondUserType.toString() : ""
+ }
+
+ // 淇濆瓨鍒版暟鎹簱
+ sqliteService.d1_pass_record.save(record)
+ logger.info(`[faceService]: 淇濆瓨鍙屼汉璁よ瘉瓒呮椂璁板綍: ${JSON.stringify(record)}`)
+ }
+
+ // 娓呴櫎璁よ瘉鐘舵��
+ clearDualAuthState()
+
+ // 鎾斁澶辫触鎻愮ず闊�
+ driver.alsa.play(`/app/code/resource/${config.get("base.language") == "CN" ? "CN" : "EN"}/wav/verify_300_f.wav`)
+
+ // 璇煶鎻愮ず璁よ瘉澶辫触
+ // driver.alsa.ttsPlay("鍙屼汉璁よ瘉瓒呮椂锛岃璇佸け璐�")
+
+ // 瑙﹀彂璁よ瘉澶辫触浜嬩欢
+ bus.fire("showAccessResult", {
+ faceAuth: false,
+ gasConcentration: true,
+ accessAllowed: false,
+ message: "*鍙屼汉璁よ瘉瓒呮椂锛岃璇佸け璐�*"
+ })
+
+ // 瑙﹀彂閫氳澶辫触浜嬩欢锛岄�氱煡UI閲嶇疆
+ bus.fire("accessRes", false)
+
+
+ } catch (error) {
+ logger.error(`[faceService]: 澶勭悊鍙屼汉璁よ瘉瓒呮椂閿欒: ${error.message}`)
+ }
+}
+
+/**
+ * 澶勭悊鍙屼汉璁よ瘉閫昏緫
+ * @param {string} userId - 褰撳墠鐢ㄦ埛ID
+ * @param {string} userName - 褰撳墠鐢ㄦ埛濮撳悕
+ * @param {string} fileName - 浜鸿劯鍥剧墖鏂囦欢璺緞
+ */
+function handleDualAuth(userId, userName, fileName) {
+ try {
+ if (!dualAuthState.firstUserId) {
+ // 绗竴娆¤璇�
+ dualAuthState.firstUserId = userId
+ dualAuthState.firstUserName = userName
+ dualAuthState.firstUserFileName = fileName
+
+ // 鏌ヨ绗竴鐢ㄦ埛鐨勮缁嗕俊鎭紝鑾峰彇韬唤璇佸彿鍜岃韩浠界被鍨�
+ let res = sqliteService.d1_person.findByUserId(userId)
+ if (res.length > 0) {
+ let idCard
+ let userType = 0
+ try {
+ idCard = JSON.parse(res[0].extra).idCard
+ userType = JSON.parse(res[0].extra).type || 0
+ } catch (error) {
+ logger.error("鏃犵涓�鐢ㄦ埛韬唤璇佸彿鎴栫被鍨�")
+ }
+ dualAuthState.firstUserIdCard = idCard
+ dualAuthState.firstUserType = userType
+ }
+
+ dualAuthState.startTime = Date.now()
+
+ // 娓呴櫎涔嬪墠鐨勫畾鏃跺櫒
+ if (dualAuthState.timeout) {
+ std.clearTimeout(dualAuthState.timeout)
+ }
+
+ // 璁剧疆1鍒嗛挓瓒呮椂
+ dualAuthState.timeout = std.setTimeout(() => {
+ // 瓒呮椂澶勭悊锛岃涓鸿璇佸け璐�
+ handleDualAuthTimeout()
+ }, 60000)
+
+ // 璇煶鎻愮ず-璇风浜岀敤鎴疯繘琛岃璇�
+ driver.alsa.play(`/app/code/resource/${config.get("base.language") == "CN" ? "CN" : "EN"}/wav/user2.wav`)
+ } else {
+ // 绗簩娆¤璇�
+ if (userId !== dualAuthState.firstUserId) {
+ // 涓嶅悓鐢ㄦ埛锛岃璇侀�氳繃
+ // 鏌ヨ绗簩鐢ㄦ埛鐨勮缁嗕俊鎭紝鑾峰彇韬唤璇佸彿鍜岃韩浠界被鍨�
+ let secondUserIdCard = ""
+ let secondUserType = 0
+ let res = sqliteService.d1_person.findByUserId(userId)
+ if (res.length > 0) {
+ try {
+ secondUserIdCard = JSON.parse(res[0].extra).idCard
+ secondUserType = JSON.parse(res[0].extra).type || 0
+ } catch (error) {
+ logger.error("鏃犵浜岀敤鎴疯韩浠借瘉鍙锋垨绫诲瀷")
+ }
+ }
+
+ // 淇濆瓨鍙屼汉璁よ瘉鐘舵�佷俊鎭紝鐢ㄤ簬UI鏇存柊
+ let dualAuthInfo = {
+ firstUserId: dualAuthState.firstUserId,
+ firstUserName: dualAuthState.firstUserName,
+ secondUserId: userId,
+ secondUserName: userName,
+ secondUserIdCard: secondUserIdCard,
+ secondUserType: secondUserType
+ }
+ // 淇濆瓨绗竴鐢ㄦ埛鐨勪汉鑴稿浘鐗囪矾寰�
+ let firstUserFileName = dualAuthState.firstUserFileName
+ // 璁剧疆璁よ瘉瀹屾垚鏍囧織
+ dualAuthState.authComplete = true
+ clearDualAuthState()
+
+ // 璇煶鎻愮ず-鍙屼汉璁よ瘉閫氳繃
+ driver.alsa.play(`/app/code/resource/${config.get("base.language") == "CN" ? "CN" : "EN"}/wav/user2_s.wav`)
+
+ // 閫氳璁よ瘉澶勭悊锛屼紶閫掑弻浜鸿璇佷俊鎭�
+ bus.fire("access", { data: { type: "300", code: userId, dualAuthInfo: dualAuthInfo, authComplete: true, firstUserFileName: firstUserFileName }, fileName: fileName })
+ } else {
+ // 鍚屼竴鐢ㄦ埛锛岄噸鏂板紑濮�
+ dualAuthState.firstUserId = userId
+ dualAuthState.firstUserName = userName
+
+ // 鏌ヨ鐢ㄦ埛鐨勮缁嗕俊鎭紝鑾峰彇韬唤璇佸彿鍜岃韩浠界被鍨�
+ let idCard
+ let userType = 0
+ let res = sqliteService.d1_person.findByUserId(userId)
+ if (res.length > 0) {
+ try {
+ idCard = JSON.parse(res[0].extra).idCard
+ userType = JSON.parse(res[0].extra).type || 0
+ } catch (error) {
+ logger.error("鏃犵敤鎴疯韩浠借瘉鍙锋垨绫诲瀷")
+ }
+ dualAuthState.firstUserIdCard = idCard
+ dualAuthState.firstUserType = userType
+ }
+
+ dualAuthState.startTime = Date.now()
+
+ // 娓呴櫎涔嬪墠鐨勫畾鏃跺櫒
+ if (dualAuthState.timeout) {
+ std.clearTimeout(dualAuthState.timeout)
+ }
+
+ // 閲嶆柊璁剧疆1鍒嗛挓瓒呮椂
+ dualAuthState.timeout = std.setTimeout(() => {
+ // 瓒呮椂澶勭悊锛岃涓鸿璇佸け璐�
+ handleDualAuthTimeout()
+ }, 60000)
+
+ // 璇煶鎻愮ず-璇风浜岀敤鎴疯繘琛岃璇�
+ driver.alsa.play(`/app/code/resource/${config.get("base.language") == "CN" ? "CN" : "EN"}/wav/user2.wav`)
+ }
+ }
+ } catch (error) {
+ logger.error(`[faceService]: 澶勭悊鍙屼汉璁よ瘉閿欒: ${error.message}`)
+ // 娓呴櫎璁よ瘉鐘舵��
+ clearDualAuthState()
+ }
+}
+/**
+ * 浜鸿劯娉ㄥ唽閿欒鏋氫妇
+ * 鍖呭惈鍚勭娉ㄥ唽澶辫触鐨勯敊璇爜鍜屽搴旂殑閿欒淇℃伅
+ */
+faceService.regErrorEnum = {
+ "callback": {
+ title: "娉ㄥ唽鍥炶皟鐘舵�佹灇涓�",
+ "-1": "faceService.contrastFailure", // 瀵规瘮澶辫触
+ "-2": "faceService.scalingFailure", // 缂╂斁澶辫触
+ "-3": "faceService.failedToSavePicture", // 淇濆瓨鍥剧墖澶辫触
+ "-4": "faceService.convertToBase64Fail", // 杞崲涓篵ase64澶辫触
+ },
+ "feature": {
+ title: "鐗瑰緛鍊兼敞鍐岀姸鎬佹灇涓�",
+ "-1": "faceService.base64DecodingFail", // base64瑙g爜澶辫触
+ "-10": "faceService.contrastFailure", // 瀵规瘮澶辫触
+ "-11": "faceService.similarityOverheight", // 鐩镐技搴﹁繃楂�
+ },
+ "picture": {
+ title: "鍥剧墖娉ㄥ唽鐘舵�佹灇涓�",
+ "-1": "faceService.fileDoesNotExist", // 鏂囦欢涓嶅瓨鍦�
+ "-2": "faceService.theImageFormatIsNotSupported", // 鍥剧墖鏍煎紡涓嶆敮鎸�
+ "-3": "faceService.pictureReadFailure", // 鍥剧墖璇诲彇澶辫触
+ "-4": "faceService.thePictureSizeDoesNotMatch", // 鍥剧墖灏哄涓嶅尮閰�
+ "-5": "faceService.imageParsingFailure", // 鍥剧墖瑙f瀽澶辫触
+ "-6": "faceService.imageYUVProcessingFailed", // 鍥剧墖YUV澶勭悊澶辫触
+ "-7": "faceService.failedToConvertJpegToImage", // JPEG杞崲涓哄浘鐗囧け璐�
+ "-8": "faceService.faceInformationExtractionFailed", // 浜鸿劯淇℃伅鎻愬彇澶辫触
+ "-9": "faceService.theFaceIsNotUnique", // 浜鸿劯涓嶅敮涓�
+ "-10": "faceService.contrastFailure", // 瀵规瘮澶辫触
+ "-11": "faceService.similarityOverheight", // 鐩镐技搴﹁繃楂�
+ }
+}
+
+export default faceService
\ No newline at end of file
diff --git a/vf205_access/src/service/gpiokeyService.js b/vf205_access/src/service/gpiokeyService.js
new file mode 100644
index 0000000..bfbae2a
--- /dev/null
+++ b/vf205_access/src/service/gpiokeyService.js
@@ -0,0 +1,52 @@
+/**
+ * GPIO鎸夐敭鏈嶅姟妯″潡
+ * 澶勭悊GPIO鎸夐敭鐩稿叧鐨勪笟鍔¢�昏緫锛屼富瑕佸寘鎷槻鎷嗘姤璀﹀姛鑳�
+ */
+import logger from "../../dxmodules/dxLogger.js";
+import config from "../../dxmodules/dxConfig.js";
+import driver from "../driver.js";
+import bus from "../../dxmodules/dxEventBus.js";
+
+const gpiokeyService = {}
+
+/**
+ * 鎺ユ敹GPIO鎸夐敭娑堟伅骞跺鐞�
+ * @param {object} data - GPIO鎸夐敭鏁版嵁
+ * @param {number} data.code - GPIO鐨勬爣璇嗭紝琛ㄧず鏄摢涓狦PIO鏈夎緭鍏� 256-闃叉媶锛�257-闂ㄧ
+ * @param {number} data.type - 鎸夐敭绫诲瀷锛�1琛ㄧず闃叉媶/闂ㄧ鐘舵�佸彉鍖�
+ * @param {number} data.value - 鎸夐敭鍊硷紝1琛ㄧず瑙﹀彂/闂ㄥ紑锛�0琛ㄧず鏈Е鍙�/闂ㄥ叧
+ */
+gpiokeyService.receiveMsg = function (data) {
+ logger.info('[gpiokeyService] 鎺ユ敹鍒癎PIO娑堟伅:', JSON.stringify(data))
+
+ // 闃叉媶鎶ヨ澶勭悊
+ if (data.code === 256) {
+ if (config.get("access.tamperAlarm") && data.type == 1 && data.value == 1) {
+ logger.info('[gpiokeyService] 闃叉媶鎶ヨ瑙﹀彂')
+ driver.alsa.play("/app/code/resource/wav/alarm.wav")
+ }
+ }
+
+ // 闂ㄧ鐘舵�佸彉鍖栧鐞�
+ if (data.code === 257) {
+ const doorStatus = data.value == 1 ? "闂ㄥ紑" : "闂ㄥ叧"
+ logger.info(`[gpiokeyService] 闂ㄧ鐘舵�佸彉鍖�: ${doorStatus}`)
+
+ if (data.value === 1) {
+ // 闂ㄥ紑
+ driver.alsa.play("/app/code/resource/CN/wav/door_open.wav")
+ } else {
+ // 闂ㄥ叧
+ driver.alsa.play("/app/code/resource/CN/wav/door_close.wav")
+ }
+
+ // 鍙戦�侀棬纾佺姸鎬佸彉鍖栭�氱煡浜嬩欢
+ bus.fire('doorStatusChanged', {
+ status: data.value,
+ statusText: doorStatus,
+ time: Math.floor(Date.now() / 1000)
+ })
+ }
+}
+
+export default gpiokeyService
\ No newline at end of file
diff --git a/vf205_access/src/service/grainService.js b/vf205_access/src/service/grainService.js
new file mode 100644
index 0000000..4c5721c
--- /dev/null
+++ b/vf205_access/src/service/grainService.js
@@ -0,0 +1,676 @@
+/**
+ * 绮儏鏈嶅姟妯″潡
+ * 璐熻矗姘斾綋娴撳害鏁版嵁鑾峰彇鍜岀姸鎬佷俊鎭暟鎹幏鍙�
+ */
+import logger from "../../dxmodules/dxLogger.js"
+import config from "../../dxmodules/dxConfig.js"
+import http from "../../dxmodules/dxHttp.js"
+import bus from '../../dxmodules/dxEventBus.js'
+import std from "../../dxmodules/dxStd.js"
+import driver from "../driver.js"
+const grainService = {}
+
+// 浠庨厤缃腑鑾峰彇涓氬姟缂栫爜瀹氫箟
+const functionId = {
+ gasDetection: config.get('functionId.gasDetection') || "1000",
+ safeInputControl: config.get('functionId.safeInputControl') || "2000",
+ lightControl: config.get('functionId.lightControl') || "3000",
+ doorStatus: config.get('functionId.doorStatus') || "4000"
+}
+
+// 浠庨厤缃腑鑾峰彇鎺ュ彛杩斿洖缂栫爜
+const respCode = {
+ success: config.get('respCode.success') || "200",
+ badRequest: config.get('respCode.badRequest') || "400",
+ unauthorized: config.get('respCode.unauthorized') || "401",
+ forbidden: config.get('respCode.forbidden') || "403",
+ notFound: config.get('respCode.notFound') || "404",
+ serverError: config.get('respCode.serverError') || "500"
+}
+
+// 閿欒鐮佸搴旂殑閿欒淇℃伅
+const errorMessages = {
+ "400": "璇锋眰鍙傛暟鏈夎",
+ "401": "鏈櫥褰曪紝鐢ㄦ埛涓嶅瓨鍦�",
+ "403": "鐢ㄦ埛鏃犳潈闄�",
+ "404": "璇锋眰鍔熻兘涓嶅瓨鍦�",
+ "500": "璇锋眰鎵ц寮傚父锛岃鑱旂郴绠$悊鍛�"
+}
+
+// 鎿嶄綔鎸夐挳瀵瑰簲鐨勮闊虫枃浠�
+const voiceFiles = {
+ // 鍏佽杩涗粨妯″紡
+ "11": "btn11.wav", // 鍏佽杩涗粨妯″紡
+ "12": "btn12.wav", // 鍏ヤ粨
+ "13": "btn13.wav", // 鍑轰粨
+ // 鍐閫氶妯″紡
+ "21": "btn21.wav", // 鍐閫氶妯″紡
+ "22": "btn22.wav", // 鍚姩
+ "23": "btn23.wav", // 鍏抽棴
+ // 绂佹杩涗粨妯″紡
+ "31": "btn31.wav", // 绂佹杩涗粨妯″紡
+ "32": "btn32.wav", // 绱ф�ュ叆浠�
+ "33": "btn33.wav", // 鍑轰粨
+ // 鐓ф槑鎺у埗
+ "light_open": "light_open.wav", // 寮�鐏�
+ "light_close": "light_close.wav" // 鍏崇伅
+}
+
+/**
+ * 鏍规嵁閿欒鐮佽幏鍙栭敊璇俊鎭�
+ * @param {string} code - 閿欒鐮�
+ * @returns {string} 閿欒淇℃伅
+ */
+function getErrorMessage(code) {
+ return errorMessages[code] || "鎿嶄綔澶辫触"
+}
+
+/**
+ * 鏍规嵁鎿嶄綔鎸夐挳鍜屽姛鑳界爜鑾峰彇璇煶鏂囦欢
+ * @param {string} functionId - 鍔熻兘鐮�
+ * @param {object} params - 璇锋眰鍙傛暟锛屽寘鍚玬ode鍜宐tn
+ * @returns {string} 璇煶鏂囦欢璺緞
+ */
+function getVoiceFile(functionId, params) {
+ // 鐓ф槑鎺у埗鍔熻兘
+ if (functionId === "3000") {
+ // 寮�鐏�
+ if (String(params.btn) === "1") return voiceFiles["light_open"]
+ // 鍏崇伅
+ if (String(params.btn) === "2") return voiceFiles["light_close"]
+ }
+ // 瀹夊叏鍏ヤ粨鎺у埗鍔熻兘
+ if (functionId === "2000" && params) {
+ const { mode, btn } = params
+ // 妯″紡1: 鍏佽杩涗粨妯″紡
+ if (mode === 1) {
+ if (!btn) return voiceFiles["11"] // 鍏佽杩涗粨妯″紡鎸夐挳
+ if (String(btn) === "1") return voiceFiles["12"] // 鍏ヤ粨鎸夐挳
+ if (String(btn) === "2") return voiceFiles["13"] // 鍑轰粨鎸夐挳
+ }
+ // 妯″紡2: 鍐閫氶妯″紡
+ if (mode === 2) {
+ if (!btn) return voiceFiles["21"] // 鍐閫氶妯″紡鎸夐挳
+ if (String(btn) === "1") return voiceFiles["22"] // 鍚姩鎸夐挳
+ if (String(btn) === "2") return voiceFiles["23"] // 鍏抽棴鎸夐挳
+ }
+ // 妯″紡3: 绂佹杩涗粨妯″紡
+ if (mode === 3) {
+ if (!btn) return voiceFiles["31"] // 绂佹杩涗粨妯″紡鎸夐挳
+ if (String(btn) === "1") return voiceFiles["32"] // 绱ф�ュ叆浠撴寜閽�
+ if (String(btn) === "2") return voiceFiles["33"] // 鍑轰粨鎸夐挳
+ }
+ }
+ return null
+}
+
+// 浠庨厤缃腑鑾峰彇HTTP鎺ュ彛璺緞
+function getHttpUrl() {
+ return config.get('http.safeInputAccess') || "http://192.168.1.199:80/cgi-bin/safeInputAccess"
+}
+
+// 瀛樺偍姘斾綋娴撳害鏁版嵁
+let gasDataStorage = null
+
+/**
+ * 妫�鏌ユ皵浣撴祿搴�
+ * @param {function} callback - 鍥炶皟鍑芥暟锛屽湪姘斾綋娴撳害妫�娴嬪畬鎴愬悗璋冪敤
+ * @returns {boolean} true琛ㄧず姘斾綋娴撳害鍚堟牸锛宖alse琛ㄧず姘斾綋娴撳害涓嶅悎鏍�
+ */
+grainService.checkGasConcentration = function(callback) {
+ // 浣跨敤setTimeout灏咹TTP璇锋眰鏀惧叆鍚庡彴鎵ц锛岄伩鍏嶉樆濉炰富绾跨▼
+ std.setTimeout(() => {
+ try {
+ // 纭繚URL鏍煎紡姝g‘锛屾坊鍔爃ttp://鍓嶇紑
+ let url = getHttpUrl()
+ if (!url.startsWith('http://') && !url.startsWith('https://')) {
+ url = 'http://' + url
+ }
+
+ const timeout = 3000 // 3绉掕秴鏃�
+
+ logger.info(`[grain]: 姝e湪鑾峰彇姘斾綋娴撳害鏁版嵁: ${url}`)
+
+ // 鏋勫缓POST璇锋眰鏁版嵁
+ const postData = {
+ sn: config.get("sys.sn") || " ", // 璁惧搴忓垪鍙凤紝浠庨厤缃腑鑾峰彇
+ houseId: "0000", // 浠撳粧缂栫爜锛岄粯璁ゅ~鍏�"0000"
+ outId: "0000", // 鑷畾涔夌紪鐮侊紝榛樿濉厖"0000"
+ functionId: functionId.gasDetection, // 姘斾綋娴撳害妫�娴嬪姛鑳界爜
+ timestamp: Date.now().toString() // 鏃堕棿鎴�
+ }
+
+ logger.info(`[grain]: 鍙戦�丳OST璇锋眰鏁版嵁: ${JSON.stringify(postData)}`)
+
+ // 鍙戦�丠TTP POST璇锋眰
+ let response = http.post(url, postData, timeout)
+
+ // logger.info(`[grain]: 姘斾綋娴撳害鏁版嵁鍝嶅簲: ${JSON.stringify(response)}`)
+
+ // 瑙f瀽鍝嶅簲鏁版嵁
+ // 妫�鏌esponse鏄惁涓哄瓧绗︿覆锛屽鏋滄槸鍒欒В鏋愪负瀵硅薄
+ if (typeof response === 'string') {
+ response = JSON.parse(response)
+ }
+
+ if (response && response.body) {
+ // 瑙f瀽鍝嶅簲浣�
+ let gasData
+ try {
+ gasData = JSON.parse(response.body)
+ logger.info(`[grain]: 瑙f瀽鍚庣殑姘斾綋娴撳害鏁版嵁: ${JSON.stringify(gasData)}`)
+
+ // 鏍规嵁鎺ュ彛杩斿洖缂栫爜杩涜鏃ュ織杈撳嚭
+ if (gasData.respCode === respCode.success) {
+ logger.info(`[grain]: 姘斾綋娴撳害妫�娴嬫帴鍙h皟鐢ㄦ垚鍔焋)
+ } else {
+ logger.error(`[grain]: 姘斾綋娴撳害妫�娴嬫帴鍙h皟鐢ㄥけ璐ワ紝杩斿洖缂栫爜: ${gasData.respCode}, 杩斿洖淇℃伅: ${gasData.respMsg}`)
+ }
+ } catch (parseError) {
+ logger.error(`[grain]: 瑙f瀽姘斾綋娴撳害鏁版嵁澶辫触: ${parseError.message}`)
+ // 灏濊瘯娓呯悊鍝嶅簲浣撲腑鐨勮浆涔夊瓧绗�
+ try {
+ // 绉婚櫎澶氫綑鐨勮浆涔夊瓧绗�
+ const cleanedBody = response.body.replace(/\\r\\n/g, '').replace(/\\t/g, '').replace(/\"/g, '"')
+ gasData = JSON.parse(cleanedBody)
+ logger.info(`[grain]: 娓呯悊鍚庤В鏋愮殑姘斾綋娴撳害鏁版嵁: ${JSON.stringify(gasData)}`)
+
+ // 鏍规嵁鎺ュ彛杩斿洖缂栫爜杩涜鏃ュ織杈撳嚭
+ if (gasData.respCode === respCode.success) {
+ logger.info(`[grain]: 姘斾綋娴撳害妫�娴嬫帴鍙h皟鐢ㄦ垚鍔焋)
+ } else {
+ logger.error(`[grain]: 姘斾綋娴撳害妫�娴嬫帴鍙h皟鐢ㄥけ璐ワ紝杩斿洖缂栫爜: ${gasData.respCode}, 杩斿洖淇℃伅: ${gasData.respMsg}`)
+ }
+ } catch (cleanError) {
+ logger.error(`[grain]: 娓呯悊鍚庤В鏋愭皵浣撴祿搴︽暟鎹粛澶辫触: ${cleanError.message}`)
+ // 璋冪敤鍥炶皟鍑芥暟
+ if (callback) {
+ callback()
+ }
+ return
+ }
+ }
+
+ // 瀛樺偍姘斾綋鏁版嵁
+ gasDataStorage = gasData
+
+ // 妫�鏌ユ皵浣撴祿搴︽槸鍚﹀悎鏍�
+ // 鏂版牸寮�: {"value":[{"o2":"20.5","statusO2":"0","co2":"401","statusCo2":"0","ph3":"0","statusPh3":"0"}],"status":"1"}
+ // statusO2/statusCo2/statusPh3: "0"琛ㄧず鍚堟牸锛�"1"琛ㄧず涓嶅悎鏍硷紙浠呯敤浜嶶I鏄剧ず锛�
+ // data.status: "0"琛ㄧず鏈�缁堝悎鏍硷紝"1"琛ㄧず鏈�缁堜笉鍚堟牸
+ const gasValue = gasData.data && gasData.data.value ? gasData.data.value[0] : null
+ const isO2Qualified = gasValue && gasValue.statusO2 === "0"
+ const isCo2Qualified = gasValue && gasValue.statusCo2 === "0"
+ const isPh3Qualified = gasValue && gasValue.statusPh3 === "0"
+
+ // 瑙﹀彂浜嬩欢鏇存柊UI
+ bus.fire('gasConcentrationUpdated', gasData)
+
+ // 鏈�缁堝悎鏍煎垽鏂彧渚濊禆status瀛楁鍊�
+ const isAllQualified = gasData.data && gasData.data.status === "0"
+
+ if (isAllQualified) {
+ logger.info("[grain]: 姘斾綋娴撳害妫�娴嬪悎鏍�")
+ } else {
+ logger.info("[grain]: 姘斾綋娴撳害妫�娴嬩笉鍚堟牸")
+ }
+
+ // 璋冪敤鍥炶皟鍑芥暟
+ if (callback) {
+ callback()
+ }
+ } else {
+ logger.error(`[grain]: 姘斾綋娴撳害鏁版嵁鑾峰彇澶辫触: ${response ? "鏃犲搷搴斾綋" : "鏃犲搷搴�"}`)
+ // 璋冪敤鍥炶皟鍑芥暟
+ if (callback) {
+ callback()
+ }
+ }
+ } catch (error) {
+ logger.error(`[grain]: 姘斾綋娴撳害妫�娴嬮敊璇�: ${error.message}`)
+ // 璋冪敤鍥炶皟鍑芥暟
+ if (callback) {
+ callback()
+ }
+ }
+ }, 0)
+
+ // 绔嬪嵆杩斿洖锛岄伩鍏嶉樆濉炰富绾跨▼
+ return true
+}
+
+/**
+ * 鑾峰彇瀛樺偍鐨勬皵浣撴祿搴︽暟鎹�
+ * @returns {object|null} 瀛樺偍鐨勬皵浣撴祿搴︽暟鎹紝濡傛灉娌℃湁鍒欒繑鍥瀗ull
+ */
+grainService.getGasData = function() {
+ return gasDataStorage
+}
+
+/**
+ * 妫�鏌ヨ澶囩姸鎬佷俊鎭�
+ * @param {object} params - 璇锋眰鍙傛暟
+ * @param {string} params.user1 - 浜鸿劯璇嗗埆鐢ㄦ埛1
+ * @param {string} params.user2 - 浜鸿劯璇嗗埆鐢ㄦ埛2
+ * @param {string} params.mode - 閫夋嫨妯″紡锛�1-鍏佽鍏ヤ粨锛�2-鍐閫氶锛�3-绂佹鍏ヤ粨锛�
+ * @param {string} params.btn - 鎿嶄綔鎸夐挳锛�1-鍏ヤ粨/寮�鍚紱2-鍑轰粨/鍏抽棴锛�
+ * @returns {boolean} true琛ㄧず鐘舵�佷俊鎭幏鍙栨垚鍔燂紝false琛ㄧず澶辫触
+ */
+grainService.checkDevConcentration = function(params) {
+ // 浣跨敤setTimeout灏咹TTP璇锋眰鏀惧叆鍚庡彴鎵ц锛岄伩鍏嶉樆濉炰富绾跨▼
+ std.setTimeout(() => {
+ try {
+ // 纭繚URL鏍煎紡姝g‘锛屾坊鍔爃ttp://鍓嶇紑
+ let url = getHttpUrl()
+ if (!url.startsWith('http://') && !url.startsWith('https://')) {
+ url = 'http://' + url
+ }
+
+ const timeout = 3000 // 3绉掕秴鏃�
+
+ // logger.info(`[grain]: 姝e湪鑾峰彇鐘舵�佷俊鎭暟鎹�: ${url}`)
+
+ // 鏋勫缓POST璇锋眰鏁版嵁
+ const postData = {
+ sn: config.get("sys.sn") || " ", // 璁惧搴忓垪鍙凤紝浠庨厤缃腑鑾峰彇
+ houseId: "0000", // 浠撳粧缂栫爜锛岄粯璁ゅ~鍏�"0000"
+ outId: "0000", // 鑷畾涔夌紪鐮侊紝榛樿濉厖"0000"
+ functionId: params && params.functionId ? params.functionId : functionId.safeInputControl, // 鍔熻兘鐮侊紝榛樿涓哄畨鍏ㄥ叆浠撹仈鍔ㄦ帶鍒�
+ timestamp: Date.now().toString(), // 鏃堕棿鎴�
+ data: {}
+ }
+
+ // 娣诲姞鍙�夊弬鏁�
+ if (params) {
+ if (params.user1) postData.data.user1 = params.user1
+ if (params.user2) postData.data.user2 = params.user2
+ if (params.mode) postData.data.mode = params.mode
+ if (params.btn) postData.data.btn = params.btn
+ }
+
+ logger.info(`[grain]: 鍙戦�丳OST璇锋眰鏁版嵁: ${JSON.stringify(postData)}`)
+
+ // 鍙戦�丠TTP POST璇锋眰
+ let response = http.post(url, postData, timeout)
+
+ // logger.info(`[grain]: 鐘舵�佷俊鎭暟鎹搷搴�: ${JSON.stringify(response)}`)
+
+ // 瑙f瀽鍝嶅簲鏁版嵁
+ // 妫�鏌esponse鏄惁涓哄瓧绗︿覆锛屽鏋滄槸鍒欒В鏋愪负瀵硅薄
+ if (typeof response === 'string') {
+ response = JSON.parse(response)
+ }
+
+ if (response && response.body) {
+ // 瑙f瀽鍝嶅簲浣�
+ let statusData
+ try {
+ statusData = JSON.parse(response.body)
+ logger.info(`[grain]: 瑙f瀽鍚庣殑鐘舵�佷俊鎭暟鎹�: ${JSON.stringify(statusData)}`)
+
+ // 鏍规嵁鎺ュ彛杩斿洖缂栫爜杩涜鏃ュ織杈撳嚭
+ if (statusData.respCode === respCode.success) {
+ logger.info(`[grain]: 鐘舵�佷俊鎭帴鍙h皟鐢ㄦ垚鍔焋)
+ // 妫�鏌ata鏄惁涓虹┖锛屼笉涓虹┖鎵嶈Е鍙戦�氱煡
+ if (Object.keys(postData.data).length > 0) {
+ // 瑙﹀彂鎴愬姛寮圭獥
+ bus.fire('showAccessResult', {
+ faceAuth: true,
+ gasConcentration: true,
+ accessAllowed: true,
+ message: '*鎵ц鎴愬姛*'
+ })
+
+ // 鎾斁鎴愬姛璇煶鎻愮ず
+ try {
+ const voiceFile = getVoiceFile(postData.functionId, postData.data)
+ if (voiceFile) {
+ driver.alsa.play(`/app/code/resource/${config.get("base.language") == "CN" ? "CN" : "EN"}/wav/${voiceFile}`)
+ logger.info(`[grain]: 鎾斁鎴愬姛璇煶鎻愮ず: ${voiceFile}`)
+ }
+ } catch (error) {
+ logger.error(`[grain]: 鎾斁璇煶鎻愮ず澶辫触: ${error.message}`)
+ }
+ }
+ } else {
+ logger.error(`[grain]: 鐘舵�佷俊鎭帴鍙h皟鐢ㄥけ璐ワ紝杩斿洖缂栫爜: ${statusData.respCode}, 杩斿洖淇℃伅: ${statusData.respMsg}`)
+ // 妫�鏌ata鏄惁涓虹┖锛屼笉涓虹┖鎵嶈Е鍙戦�氱煡
+ if (Object.keys(postData.data).length > 0) {
+ // 瑙﹀彂澶辫触寮圭獥
+ bus.fire('showAccessResult', {
+ faceAuth: true,
+ gasConcentration: true,
+ accessAllowed: false,
+ message: statusData.respMsg || getErrorMessage(statusData.respCode)
+ })
+ // 鎾斁澶辫触璇煶鎻愮ず
+ try {
+ driver.alsa.play(`/app/code/resource/${config.get("base.language") == "CN" ? "CN" : "EN"}/wav/failed.wav`)
+ logger.info(`[grain]: 鎾斁澶辫触璇煶鎻愮ず: failed.wav`)
+ } catch (error) {
+ logger.error(`[grain]: 鎾斁璇煶鎻愮ず澶辫触: ${error.message}`)
+ }
+ }
+ }
+ } catch (parseError) {
+ logger.error(`[grain]: 瑙f瀽鐘舵�佷俊鎭暟鎹け璐�: ${parseError.message}`)
+ // 灏濊瘯娓呯悊鍝嶅簲浣撲腑鐨勮浆涔夊瓧绗�
+ try {
+ // 绉婚櫎澶氫綑鐨勮浆涔夊瓧绗�
+ const cleanedBody = response.body.replace(/\\r\\n/g, '').replace(/\\t/g, '').replace(/\"/g, '"')
+ statusData = JSON.parse(cleanedBody)
+ logger.info(`[grain]: 娓呯悊鍚庤В鏋愮殑鐘舵�佷俊鎭暟鎹�: ${JSON.stringify(statusData)}`)
+
+ // 鏍规嵁鎺ュ彛杩斿洖缂栫爜杩涜鏃ュ織杈撳嚭
+ if (statusData.respCode === respCode.success) {
+ logger.info(`[grain]: 鐘舵�佷俊鎭帴鍙h皟鐢ㄦ垚鍔焋)
+ // 妫�鏌ata鏄惁涓虹┖锛屼笉涓虹┖鎵嶈Е鍙戦�氱煡
+ if (Object.keys(postData.data).length > 0) {
+ // 瑙﹀彂鎴愬姛寮圭獥
+ bus.fire('showAccessResult', {
+ faceAuth: true,
+ gasConcentration: true,
+ accessAllowed: true,
+ message: '*鎵ц鎴愬姛*'
+ })
+
+ // 鎾斁鎴愬姛璇煶鎻愮ず
+ try {
+ const voiceFile = getVoiceFile(postData.functionId, postData.data)
+ if (voiceFile) {
+ driver.alsa.play(`/app/code/resource/${config.get("base.language") == "CN" ? "CN" : "EN"}/wav/${voiceFile}`)
+ logger.info(`[grain]: 鎾斁鎴愬姛璇煶鎻愮ず: ${voiceFile}`)
+ }
+ } catch (error) {
+ logger.error(`[grain]: 鎾斁璇煶鎻愮ず澶辫触: ${error.message}`)
+ }
+ }
+ } else {
+ logger.error(`[grain]: 鐘舵�佷俊鎭帴鍙h皟鐢ㄥけ璐ワ紝杩斿洖缂栫爜: ${statusData.respCode}, 杩斿洖淇℃伅: ${statusData.respMsg}`)
+ // 妫�鏌ata鏄惁涓虹┖锛屼笉涓虹┖鎵嶈Е鍙戦�氱煡
+ if (Object.keys(postData.data).length > 0) {
+ // 瑙﹀彂澶辫触寮圭獥
+ bus.fire('showAccessResult', {
+ faceAuth: true,
+ gasConcentration: true,
+ accessAllowed: false,
+ message: statusData.respMsg || getErrorMessage(statusData.respCode)
+ })
+ // 鎾斁澶辫触璇煶鎻愮ず
+ try {
+ driver.alsa.play(`/app/code/resource/${config.get("base.language") == "CN" ? "CN" : "EN"}/wav/failed.wav`)
+ logger.info(`[grain]: 鎾斁澶辫触璇煶鎻愮ず: failed.wav`)
+ } catch (error) {
+ logger.error(`[grain]: 鎾斁璇煶鎻愮ず澶辫触: ${error.message}`)
+ }
+ }
+ }
+ } catch (cleanError) {
+ logger.error(`[grain]: 娓呯悊鍚庤В鏋愮姸鎬佷俊鎭暟鎹粛澶辫触: ${cleanError.message}`)
+ return false
+ }
+ }
+
+ // 瑙﹀彂浜嬩欢鏇存柊UI
+ bus.fire('statusInfoUpdated', statusData)
+
+ return true
+ } else {
+ logger.error(`[grain]: 鐘舵�佷俊鎭暟鎹幏鍙栧け璐�: ${response ? "鏃犲搷搴斾綋" : "鏃犲搷搴�"}`)
+ // 缃戠粶璇锋眰澶辫触鏃讹紝榛樿杩斿洖false锛堝畨鍏ㄨ捣瑙侊級
+ return false
+ }
+ } catch (error) {
+ logger.error(`[grain]: 鐘舵�佷俊鎭娴嬮敊璇�: ${error.message}`)
+ // 鍙戠敓閿欒鏃讹紝榛樿杩斿洖false锛堝畨鍏ㄨ捣瑙侊級
+ return false
+ }
+ }, 0)
+
+ // 绔嬪嵆杩斿洖锛岄伩鍏嶉樆濉炰富绾跨▼
+ return true
+}
+
+/**
+ * 浠撳唴鐓ф槑鑱斿姩鎺у埗
+ * @param {object} params - 璇锋眰鍙傛暟
+ * @param {string} params.user1 - 浜鸿劯璇嗗埆鐢ㄦ埛1
+ * @param {string} params.user2 - 浜鸿劯璇嗗埆鐢ㄦ埛2
+ * @param {string} params.btn - 鎿嶄綔鎸夐挳锛�1-寮�鐏紱2-鍏崇伅锛�
+ * @returns {boolean} true琛ㄧず鎺у埗鎴愬姛锛宖alse琛ㄧず鎺у埗澶辫触
+ */
+grainService.controlLight = function(params) {
+ // 浣跨敤setTimeout灏咹TTP璇锋眰鏀惧叆鍚庡彴鎵ц锛岄伩鍏嶉樆濉炰富绾跨▼
+ std.setTimeout(() => {
+ try {
+ // 纭繚URL鏍煎紡姝g‘锛屾坊鍔爃ttp://鍓嶇紑
+ let url = getHttpUrl()
+ if (!url.startsWith('http://') && !url.startsWith('https://')) {
+ url = 'http://' + url
+ }
+
+ const timeout = 3000 // 3绉掕秴鏃�
+
+ // 鏋勫缓POST璇锋眰鏁版嵁
+ const postData = {
+ sn: config.get("sys.sn") || " ", // 璁惧搴忓垪鍙凤紝浠庨厤缃腑鑾峰彇
+ houseId: "0000", // 浠撳粧缂栫爜锛岄粯璁ゅ~鍏�"0000"
+ outId: "0000", // 鑷畾涔夌紪鐮侊紝榛樿濉厖"0000"
+ functionId: functionId.lightControl, // 浠撳唴鐓ф槑鑱斿姩鎺у埗鍔熻兘鐮�
+ timestamp: Date.now().toString(), // 鏃堕棿鎴�
+ data: {}
+ }
+
+ // 娣诲姞鍙�夊弬鏁�
+ if (params) {
+ if (params.user1) postData.data.user1 = params.user1
+ if (params.user2) postData.data.user2 = params.user2
+ if (params.btn) postData.data.btn = params.btn
+ }
+
+ logger.info(`[grain]: 鍙戦�佷粨鍐呯収鏄庤仈鍔ㄦ帶鍒惰姹傛暟鎹�: ${JSON.stringify(postData)}`)
+
+ // 鍙戦�丠TTP POST璇锋眰
+ let response = http.post(url, postData, timeout)
+
+ // 瑙f瀽鍝嶅簲鏁版嵁
+ // 妫�鏌esponse鏄惁涓哄瓧绗︿覆锛屽鏋滄槸鍒欒В鏋愪负瀵硅薄
+ if (typeof response === 'string') {
+ response = JSON.parse(response)
+ }
+
+ if (response && response.body) {
+ // 瑙f瀽鍝嶅簲浣�
+ let statusData
+ try {
+ statusData = JSON.parse(response.body)
+ logger.info(`[grain]: 瑙f瀽鍚庣殑浠撳唴鐓ф槑鑱斿姩鎺у埗鍝嶅簲鏁版嵁: ${JSON.stringify(statusData)}`)
+
+ // 鏍规嵁鎺ュ彛杩斿洖缂栫爜杩涜鏃ュ織杈撳嚭
+ if (statusData.respCode === respCode.success) {
+ logger.info(`[grain]: 浠撳唴鐓ф槑鑱斿姩鎺у埗鎺ュ彛璋冪敤鎴愬姛`)
+ // 瑙﹀彂鎴愬姛寮圭獥
+ bus.fire('showAccessResult', {
+ faceAuth: true,
+ gasConcentration: true,
+ accessAllowed: true,
+ message: '*鎵ц鎴愬姛*'
+ })
+
+ // 鎾斁鎴愬姛璇煶鎻愮ず
+ try {
+ const voiceFile = getVoiceFile(postData.functionId, postData.data)
+ if (voiceFile) {
+ driver.alsa.play(`/app/code/resource/${config.get("base.language") == "CN" ? "CN" : "EN"}/wav/${voiceFile}`)
+ logger.info(`[grain]: 鎾斁鎴愬姛璇煶鎻愮ず: ${voiceFile}`)
+ }
+ } catch (error) {
+ logger.error(`[grain]: 鎾斁璇煶鎻愮ず澶辫触: ${error.message}`)
+ }
+ } else {
+ logger.error(`[grain]: 浠撳唴鐓ф槑鑱斿姩鎺у埗鎺ュ彛璋冪敤澶辫触锛岃繑鍥炵紪鐮�: ${statusData.respCode}, 杩斿洖淇℃伅: ${statusData.respMsg}`)
+ // 瑙﹀彂澶辫触寮圭獥
+ bus.fire('showAccessResult', {
+ faceAuth: true,
+ gasConcentration: true,
+ accessAllowed: false,
+ message: statusData.respMsg || getErrorMessage(statusData.respCode)
+ })
+ // 鎾斁澶辫触璇煶鎻愮ず
+ try {
+ driver.alsa.play(`/app/code/resource/${config.get("base.language") == "CN" ? "CN" : "EN"}/wav/failed.wav`)
+ logger.info(`[grain]: 鎾斁澶辫触璇煶鎻愮ず: failed.wav`)
+ } catch (error) {
+ logger.error(`[grain]: 鎾斁璇煶鎻愮ず澶辫触: ${error.message}`)
+ }
+ }
+ } catch (parseError) {
+ logger.error(`[grain]: 瑙f瀽浠撳唴鐓ф槑鑱斿姩鎺у埗鍝嶅簲鏁版嵁澶辫触: ${parseError.message}`)
+ // 灏濊瘯娓呯悊鍝嶅簲浣撲腑鐨勮浆涔夊瓧绗�
+ try {
+ // 绉婚櫎澶氫綑鐨勮浆涔夊瓧绗�
+ const cleanedBody = response.body.replace(/\\r\\n/g, '').replace(/\\t/g, '').replace(/\"/g, '"')
+ statusData = JSON.parse(cleanedBody)
+ logger.info(`[grain]: 娓呯悊鍚庤В鏋愮殑浠撳唴鐓ф槑鑱斿姩鎺у埗鍝嶅簲鏁版嵁: ${JSON.stringify(statusData)}`)
+
+ // 鏍规嵁鎺ュ彛杩斿洖缂栫爜杩涜鏃ュ織杈撳嚭
+ if (statusData.respCode === respCode.success) {
+ logger.info(`[grain]: 浠撳唴鐓ф槑鑱斿姩鎺у埗鎺ュ彛璋冪敤鎴愬姛`)
+ // 瑙﹀彂鎴愬姛寮圭獥
+ bus.fire('showAccessResult', {
+ faceAuth: true,
+ gasConcentration: true,
+ accessAllowed: true,
+ message: '*鎵ц鎴愬姛*'
+ })
+
+ // 鎾斁鎴愬姛璇煶鎻愮ず
+ try {
+ const voiceFile = getVoiceFile(postData.functionId, postData.data)
+ if (voiceFile) {
+ driver.alsa.play(`/app/code/resource/${config.get("base.language") == "CN" ? "CN" : "EN"}/wav/${voiceFile}`)
+ logger.info(`[grain]: 鎾斁鎴愬姛璇煶鎻愮ず: ${voiceFile}`)
+ }
+ } catch (error) {
+ logger.error(`[grain]: 鎾斁璇煶鎻愮ず澶辫触: ${error.message}`)
+ }
+ } else {
+ logger.error(`[grain]: 浠撳唴鐓ф槑鑱斿姩鎺у埗鎺ュ彛璋冪敤澶辫触锛岃繑鍥炵紪鐮�: ${statusData.respCode}, 杩斿洖淇℃伅: ${statusData.respMsg}`)
+ // 瑙﹀彂澶辫触寮圭獥
+ bus.fire('showAccessResult', {
+ faceAuth: true,
+ gasConcentration: true,
+ accessAllowed: false,
+ message: statusData.respMsg || getErrorMessage(statusData.respCode)
+ })
+ // 鎾斁澶辫触璇煶鎻愮ず
+ try {
+ driver.alsa.play(`/app/code/resource/${config.get("base.language") == "CN" ? "CN" : "EN"}/wav/failed.wav`)
+ logger.info(`[grain]: 鎾斁澶辫触璇煶鎻愮ず: failed.wav`)
+ } catch (error) {
+ logger.error(`[grain]: 鎾斁璇煶鎻愮ず澶辫触: ${error.message}`)
+ }
+ }
+ } catch (cleanError) {
+ logger.error(`[grain]: 娓呯悊鍚庤В鏋愪粨鍐呯収鏄庤仈鍔ㄦ帶鍒跺搷搴旀暟鎹粛澶辫触: ${cleanError.message}`)
+ return false
+ }
+ }
+
+ // 瑙﹀彂浜嬩欢鏇存柊UI
+ bus.fire('statusInfoUpdated', statusData)
+
+ return true
+ } else {
+ logger.error(`[grain]: 浠撳唴鐓ф槑鑱斿姩鎺у埗璇锋眰澶辫触: ${response ? "鏃犲搷搴斾綋" : "鏃犲搷搴�"}`)
+ // 缃戠粶璇锋眰澶辫触鏃讹紝榛樿杩斿洖false锛堝畨鍏ㄨ捣瑙侊級
+ return false
+ }
+ } catch (error) {
+ logger.error(`[grain]: 浠撳唴鐓ф槑鑱斿姩鎺у埗閿欒: ${error.message}`)
+ // 鍙戠敓閿欒鏃讹紝榛樿杩斿洖false锛堝畨鍏ㄨ捣瑙侊級
+ return false
+ }
+ }, 0)
+
+ // 绔嬪嵆杩斿洖锛岄伩鍏嶉樆濉炰富绾跨▼
+ return true
+}
+
+/**
+ * 鍙戦�侀棬纾佺姸鎬佹秷鎭�
+ * @param {object} doorStatusData - 闂ㄧ鐘舵�佹暟鎹�
+ * @param {number} doorStatusData.status - 闂ㄧ鐘舵�侊紝0琛ㄧず闂ㄥ叧锛�1琛ㄧず闂ㄥ紑
+ * @param {string} doorStatusData.statusText - 闂ㄧ鐘舵�佹枃鏈�
+ * @param {number} doorStatusData.time - 鏃堕棿鎴�
+ */
+grainService.sendDoorStatusMessage = function(doorStatusData) {
+ // 浣跨敤setTimeout灏咹TTP璇锋眰鏀惧叆鍚庡彴鎵ц锛岄伩鍏嶉樆濉炰富绾跨▼
+ std.setTimeout(() => {
+ try {
+ // 纭繚URL鏍煎紡姝g‘锛屾坊鍔爃ttp://鍓嶇紑
+ let url = getHttpUrl()
+ if (!url.startsWith('http://') && !url.startsWith('https://')) {
+ url = 'http://' + url
+ }
+
+ const timeout = 3000 // 3绉掕秴鏃�
+
+ logger.info(`[grain]: 姝e湪鍙戦�侀棬纾佺姸鎬佹秷鎭�: ${url}`)
+
+ // 鏋勫缓POST璇锋眰鏁版嵁
+ const postData = {
+ sn: config.get("sys.sn") || " ", // 璁惧搴忓垪鍙凤紝浠庨厤缃腑鑾峰彇
+ houseId: "0000", // 浠撳粧缂栫爜锛岄粯璁ゅ~鍏�"0000"
+ outId: "0000", // 鑷畾涔夌紪鐮侊紝榛樿濉厖"0000"
+ functionId: functionId.doorStatus, // 闂ㄧ鐘舵�佸姛鑳界爜
+ timestamp: Date.now().toString(), // 鏃堕棿鎴�
+ data: {
+ doorStatus: doorStatusData.status // 闂ㄧ鐘舵��
+ }
+ }
+
+ logger.info(`[grain]: 鍙戦�侀棬纾佺姸鎬佹秷鎭暟鎹�: ${JSON.stringify(postData)}`)
+
+ // 鍙戦�丠TTP POST璇锋眰
+ let response = http.post(url, postData, timeout)
+
+ // 瑙f瀽鍝嶅簲鏁版嵁
+ if (typeof response === 'string') {
+ response = JSON.parse(response)
+ }
+
+ if (response && response.body) {
+ let respData
+ try {
+ respData = JSON.parse(response.body)
+ logger.info(`[grain]: 闂ㄧ鐘舵�佹秷鎭搷搴�: ${JSON.stringify(respData)}`)
+ } catch (error) {
+ logger.error(`[grain]: 瑙f瀽闂ㄧ鐘舵�佹秷鎭搷搴斿け璐�: ${error.message}`)
+ }
+ } else {
+ logger.info(`[grain]: 闂ㄧ鐘舵�佹秷鎭搷搴斾负绌篳)
+ }
+ } catch (error) {
+ logger.error(`[grain]: 鍙戦�侀棬纾佺姸鎬佹秷鎭け璐�: ${error.message}`)
+ }
+ }, 0)
+}
+
+// 鐩戝惉闂ㄧ鐘舵�佸彉鍖栦簨浠�
+bus.on('doorStatusChanged', (doorStatusData) => {
+ logger.info(`[grain]: 鎺ユ敹鍒伴棬纾佺姸鎬佸彉鍖栦簨浠�: ${JSON.stringify(doorStatusData)}`)
+ // 璋冪敤鍙戦�侀棬纾佺姸鎬佹秷鎭殑鍑芥暟
+ try {
+ if (typeof grainService.sendDoorStatusMessage === 'function') {
+ grainService.sendDoorStatusMessage(doorStatusData)
+ } else {
+ logger.error('[grain]: sendDoorStatusMessage 涓嶆槸涓�涓嚱鏁�')
+ logger.error('[grain]: grainService.sendDoorStatusMessage =', grainService.sendDoorStatusMessage)
+ }
+ } catch (error) {
+ logger.error('[grain]: 璋冪敤sendDoorStatusMessage鍑洪敊:', error.message)
+ }
+})
+
+export default grainService
\ No newline at end of file
diff --git a/vf205_access/src/service/mqttService.js b/vf205_access/src/service/mqttService.js
new file mode 100644
index 0000000..63dad5a
--- /dev/null
+++ b/vf205_access/src/service/mqttService.js
@@ -0,0 +1,1832 @@
+/**
+ * MQTT鏈嶅姟妯″潡
+ * 澶勭悊MQTT娑堟伅鐨勬帴鏀跺拰鍙戦�侊紝鍖呮嫭璁惧绠$悊銆佷汉鍛樼鐞嗐�佹潈闄愮鐞嗙瓑鍔熻兘
+ */
+import common from "../../dxmodules/dxCommon.js";
+import config from "../../dxmodules/dxConfig.js";
+import logger from "../../dxmodules/dxLogger.js";
+import ota from "../../dxmodules/dxOta.js";
+import std from "../../dxmodules/dxStd.js";
+import dxMap from '../../dxmodules/dxMap.js'
+import driver from "../driver.js";
+import configService from "./configService.js";
+import sqliteService from "./sqliteService.js";
+import sqlite from "../../dxmodules/dxSqlite.js";
+import utils from '../common/utils/utils.js'
+
+const mqttService = {}
+let map = dxMap.get("faceAccesss")
+
+/**
+ * 鎺ユ敹MQTT娑堟伅骞跺鐞�
+ * @param {object} data - MQTT娑堟伅鏁版嵁
+ * @param {string} data.topic - 娑堟伅涓婚
+ * @param {string} data.payload - 娑堟伅杞借嵎
+ */
+mqttService.receiveMsg = function (data) {
+ // {"topic":"ddddd","payload":"{\n \"msg\": \"world\"\n}"}
+ logger.info('[mqttService] receiveMsg :' + JSON.stringify(data.topic))
+ // 鎻愬彇涓婚鐨勬渶鍚庨儴鍒嗕綔涓哄嚱鏁板悕
+ if (typeof mqttService[data.topic.match(/[^/]+$/)[0]] == 'function') {
+ mqttService[data.topic.match(/[^/]+$/)[0]](data)
+ } else {
+ logger.error("鏈疄鐜扮殑topic", data.topic)
+ }
+}
+
+// =================================鏉冮檺澧炲垹鏀规煡=================================
+/**
+ * 娣诲姞鏉冮檺
+ * @param {object} event - MQTT浜嬩欢瀵硅薄
+ */
+mqttService.insertPermission = function (event) {
+ try {
+ logger.info('[mqttService] 鎺ユ敹鍒癷nsertPermission鍛戒护:', JSON.stringify(event.topic))
+ logger.info('[mqttService] 鍛戒护payload:', event.payload)
+ let payload = JSON.parse(event.payload)
+ let data = payload.payload && payload.payload.data ? payload.payload.data : {}
+ logger.info('[mqttService] 瑙f瀽鍚庣殑鍙傛暟:', JSON.stringify(data))
+ let res = this.insertPermissionAgreement(data)
+ if (typeof res == 'string') {
+ logger.error('[mqttService] insertPermission澶辫触:', res)
+ return reply(event, res, CODE.E_100)
+ }
+ logger.info('[mqttService] insertPermission鎴愬姛')
+ return reply(event)
+ } catch (error) {
+ logger.error('[mqttService] insertPermission error:', error)
+ return reply(event, { error: error.message }, CODE.E_100)
+ }
+}
+
+/**
+ * 娣诲姞鏉冮檺閫氱敤鍗忚鏍煎紡
+ * @param {array} data - 鏉冮檺鏁版嵁鏁扮粍
+ * @returns {boolean|string} true琛ㄧず鎴愬姛锛宻tring琛ㄧず閿欒淇℃伅
+ */
+mqttService.insertPermissionAgreement = function (data) {
+ let permissions = []
+ for (let i = 0; i < data.length; i++) {
+ const permission = data[i];
+ if (!permission.permissionId || !permission.userId) {
+ return "id or userId cannot be empty"
+ }
+ if (!permission.extra) {
+ permission.extra = ""
+ }
+ if (!permission.time) {
+ return "time and type cannot be empty"
+ }
+ if (permission.time.type != 0 && permission.time.type != 1 && permission.time.type != 2 && permission.time.type != 3) {
+ return "time type is not supported"
+ }
+ let record = {}
+ record.permissionId = permission.permissionId
+ record.userId = permission.userId
+ record.door = isEmpty(permission.index) ? 0 : permission.index
+ record.extra = isEmpty(permission.extra) ? JSON.stringify({}) : JSON.stringify(permission.extra)
+ record.timeType = permission.time.type
+ record.beginTime = permission.time.type == 0 ? 0 : permission.time.range.beginTime
+ record.endTime = permission.time.type == 0 ? 0 : permission.time.range.endTime
+ record.repeatBeginTime = permission.time.type != 2 ? 0 : permission.time.beginTime
+ record.repeatEndTime = permission.time.type != 2 ? 0 : permission.time.endTime
+ record.period = permission.time.type != 3 ? 0 : JSON.stringify(permission.time.weekPeriodTime)
+ let ret = sqliteService.d1_permission.save(record)
+ if (ret != 0) {
+ // 濡傛灉淇濆瓨澶辫触锛屽皾璇曞垹闄ゅ悗閲嶆柊淇濆瓨
+ sqliteService.d1_permission.deleteByPermissionId(record.permissionId)
+ ret = sqliteService.d1_permission.save(record)
+ if (ret != 0) {
+ return "sql error ret:" + ret
+ } else {
+ continue
+ }
+ }
+ }
+ return true
+}
+
+/**
+ * 鏌ヨ鏉冮檺
+ * @param {object} event - MQTT浜嬩欢瀵硅薄
+ */
+mqttService.getPermission = function (event) {
+ try {
+ logger.info('[mqttService] 鎺ユ敹鍒癵etPermission鍛戒护:', JSON.stringify(event.topic))
+ logger.info('[mqttService] 鍛戒护payload:', event.payload)
+ let payload = JSON.parse(event.payload)
+ let data = payload.payload && payload.payload.data ? payload.payload.data : {}
+ logger.info('[mqttService] 瑙f瀽鍚庣殑鏌ヨ鍙傛暟:', JSON.stringify(data))
+ let res = this.getPermissionAgreement(data)
+ logger.info('[mqttService] 鏌ヨ缁撴灉:', JSON.stringify(res))
+ return reply(event, res)
+ } catch (error) {
+ logger.error('[mqttService] getPermission error:', error)
+ return reply(event, { error: error.message }, CODE.E_100)
+ }
+}
+
+/**
+ * 鏌ヨ鏉冮檺閫氱敤鍗忚鏍煎紡
+ * @param {object} data - 鏌ヨ鍙傛暟
+ * @returns {object} 鏌ヨ缁撴灉
+ */
+mqttService.getPermissionAgreement = function (data) {
+ try {
+ // 纭繚data鍙傛暟涓嶄负undefined
+ data = data || {}
+ data.page = isEmpty(data.page) ? 0 : data.page
+ data.size = isEmpty(data.size) ? 10 : data.size
+ let totalCount = sqliteService.d1_permission.count(data)
+ let permissions = sqliteService.d1_permission.findAll(data)
+ // 鏋勫缓杩斿洖缁撴灉
+ let content = permissions.map(permission => ({
+ permissionId: permission.permissionId,
+ userId: permission.userId,
+ extra: JSON.parse(permission.extra ? permission.extra : "{}"),
+ time: {
+ type: permission.timeType,
+ beginTime: permission.timeType != 2 ? undefined : permission.repeatBeginTime,
+ endTime: permission.timeType != 2 ? undefined : permission.repeatEndTime,
+ range: permission.timeType === 0 ? undefined : { beginTime: permission.beginTime, endTime: permission.endTime },
+ weekPeriodTime: permission.timeType != 3 ? undefined : JSON.parse(permission.period)
+ }
+ }))
+ return {
+ content: content,
+ page: data.page,
+ size: data.size,
+ total: totalCount,
+ totalPage: Math.ceil(totalCount / data.size),
+ count: content.length
+ }
+ } catch (error) {
+ logger.error('[mqttService] getPermissionAgreement error:', error)
+ throw error
+ }
+}
+
+/**
+ * 鍒犻櫎鏉冮檺
+ * @param {object} event - MQTT浜嬩欢瀵硅薄
+ */
+mqttService.delPermission = function (event) {
+ try {
+ logger.info('[mqttService] 鎺ユ敹鍒癲elPermission鍛戒护:', JSON.stringify(event.topic))
+ logger.info('[mqttService] 鍛戒护payload:', event.payload)
+ let payload = JSON.parse(event.payload)
+ let data = payload.payload && payload.payload.data ? payload.payload.data : {}
+ logger.info('[mqttService] 瑙f瀽鍚庣殑鍙傛暟:', JSON.stringify(data))
+ let res = this.delPermissionAgreement(data)
+ if (typeof res == 'string') {
+ logger.error('[mqttService] delPermission澶辫触:', res)
+ return reply(event, res, CODE.E_100)
+ }
+ logger.info('[mqttService] delPermission鎴愬姛')
+ return reply(event)
+ } catch (error) {
+ logger.error('[mqttService] delPermission error:', error)
+ return reply(event, { error: error.message }, CODE.E_100)
+ }
+}
+
+/**
+ * 鍒犻櫎鏉冮檺閫氱敤鍗忚鏍煎紡
+ * @param {object} data - 鍒犻櫎鍙傛暟
+ * @returns {boolean|string} true琛ㄧず鎴愬姛锛宻tring琛ㄧず閿欒淇℃伅
+ */
+mqttService.delPermissionAgreement = function (data) {
+ if (data.permissionIds && data.permissionIds.length > 0) {
+ let ret = sqliteService.d1_permission.deleteByPermissionIdInBatch(data.permissionIds)
+ if (ret != 0) {
+ return "sql error ret:" + ret
+ }
+ }
+ if (data.userIds && data.userIds.length > 0) {
+ let ret = sqliteService.d1_permission.deleteByUserIdInBatch(data.userIds)
+ if (ret != 0) {
+ return "sql error ret:" + ret
+ }
+ }
+ return true
+}
+
+/**
+ * 娓呯┖鏉冮檺
+ * @param {object} event - MQTT浜嬩欢瀵硅薄
+ */
+mqttService.clearPermission = function (event) {
+ try {
+ logger.info('[mqttService] 鎺ユ敹鍒癱learPermission鍛戒护:', JSON.stringify(event.topic))
+ logger.info('[mqttService] 鍛戒护payload:', event.payload)
+ let ret = sqliteService.d1_permission.deleteAll()
+ if (ret == 0) {
+ logger.info('[mqttService] clearPermission鎴愬姛')
+ return reply(event)
+ } else {
+ logger.error('[mqttService] clearPermission澶辫触:', "sql error ret:" + ret)
+ return reply(event, "sql error ret:" + ret, CODE.E_100)
+ }
+ } catch (error) {
+ logger.error('[mqttService] clearPermission error:', error)
+ return reply(event, { error: error.message }, CODE.E_100)
+ }
+}
+
+
+// =================================浜哄憳澧炲垹鏀规煡=================================
+/**
+ * 娣诲姞浜哄憳
+ * @param {object} event - MQTT浜嬩欢瀵硅薄
+ */
+mqttService.insertUser = function (event) {
+ try {
+ logger.info('[mqttService] 鎺ユ敹鍒癷nsertUser鍛戒护:', JSON.stringify(event.topic))
+ logger.info('[mqttService] 鍛戒护payload:', event.payload)
+ let payload = JSON.parse(event.payload)
+ let data = payload.payload && payload.payload.data ? payload.payload.data : []
+ logger.info('[mqttService] 瑙f瀽鍚庣殑鍙傛暟:', JSON.stringify(data))
+ let res = this.insertUserAgreement(data)
+ if (typeof res == 'string') {
+ logger.error('[mqttService] insertUser澶辫触:', res)
+ return reply(event, res, CODE.E_100)
+ }
+ logger.info('[mqttService] insertUser鎴愬姛')
+ return reply(event)
+ } catch (error) {
+ logger.error('[mqttService] insertUser error:', error)
+ return reply(event, { error: error.message }, CODE.E_100)
+ }
+}
+
+/**
+ * 娣诲姞浜哄憳閫氱敤鍗忚鏍煎紡
+ * @param {array} data - 浜哄憳鏁版嵁鏁扮粍
+ * @returns {boolean|string} true琛ㄧず鎴愬姛锛宻tring琛ㄧず閿欒淇℃伅
+ */
+mqttService.insertUserAgreement = function (data) {
+ let persons = []
+ for (let i = 0; i < data.length; i++) {
+ const person = data[i];
+ // 涓ユ牸妫�鏌ユ暟鎹牸寮�
+ if (!person.userId || !person.name || person.type === undefined || !person.idCard) {
+ return "鏁版嵁鏍煎紡閿欒锛岀己灏戝繀瑕佸瓧娈碉紙userId銆乶ame銆乼ype銆乮dCard锛�"
+ }
+ // 妫�鏌ype瀛楁绫诲瀷
+ if (typeof person.type !== 'number') {
+ return "鏁版嵁鏍煎紡閿欒锛宼ype瀛楁蹇呴』鏄暟瀛�"
+ }
+ // 妫�鏌ype瀛楁鍊艰寖鍥�
+ if (person.type < 0 || person.type > 1) {
+ return "鏁版嵁鏍煎紡閿欒锛宼ype瀛楁鍊煎繀椤诲湪0-1涔嬮棿"
+ }
+ let record = {}
+ record.userId = person.userId
+ record.name = person.name
+ // 澶勭悊浜哄憳绫诲瀷瀛楁鍜岃韩浠借瘉鍙�
+ let extra = {}
+ extra.type = person.type
+ extra.idCard = person.idCard
+ record.extra = JSON.stringify(extra)
+ persons.push(record)
+
+ // 澶勭悊浜鸿劯淇℃伅
+ if (person.face) {
+ try {
+ logger.info('[mqttService] 寮�濮嬪鐞嗕汉鑴镐俊鎭�:', person.userId)
+
+ let faceFilePath = person.face
+
+ // 妫�鏌ユ槸鍚︽槸base64缂栫爜鐨勫浘鐗囨暟鎹�
+ if (person.face.startsWith('data:image/')) {
+ logger.info('[mqttService] 妫�娴嬪埌base64缂栫爜鐨勫浘鐗囨暟鎹�')
+ // 鎻愬彇base64鏁版嵁
+ let base64Data = person.face.split(',')[1]
+ // 鍒涘缓涓存椂鏂囦欢
+ faceFilePath = '/app/data/user/temp_face_' + person.userId + '.jpg'
+ std.ensurePathExists(faceFilePath)
+ // 灏哹ase64鏁版嵁杞崲涓烘枃浠�
+ common.base64_2binfile(faceFilePath, base64Data)
+ logger.info('[mqttService] 宸插皢base64鏁版嵁淇濆瓨涓烘枃浠�:', faceFilePath)
+ } else {
+ return "鏁版嵁鏍煎紡閿欒锛宖ace瀛楁蹇呴』鏄痓ase64缂栫爜鐨勫浘鐗囨暟鎹�"
+ }
+
+ // 妫�鏌ユ枃浠舵槸鍚﹀瓨鍦�
+ let fileExists = common.systemWithRes(`test -e "${faceFilePath}" && echo "OK" || echo "NO"`, 2)
+ logger.info('[mqttService] 浜鸿劯鍥剧墖鏂囦欢瀛樺湪:', fileExists.includes('OK'))
+
+ if (fileExists.includes('OK')) {
+ // 娉ㄥ唽浜鸿劯
+ logger.info('[mqttService] 寮�濮嬫敞鍐屼汉鑴�:', person.userId)
+ let ret = driver.face.registerFaceByPicFile(person.userId, faceFilePath)
+ logger.info('[mqttService] 娉ㄥ唽浜鸿劯缁撴灉:', ret)
+
+ if (ret == 0) {
+ // 娉ㄥ唽鎴愬姛鍚庣Щ鍔ㄥ浘鐗囧埌鐢ㄦ埛鐩綍
+ let src = "/app/data/user/" + person.userId + "/register.jpg"
+ std.ensurePathExists(src)
+ logger.info('[mqttService] 绉诲姩浜鸿劯鍥剧墖鍒扮敤鎴风洰褰�:', faceFilePath, '->', src)
+ common.systemBrief('mv ' + faceFilePath + " " + src)
+
+ // 淇濆瓨浜鸿劯鍑瘉
+ logger.info('[mqttService] 淇濆瓨浜鸿劯鍑瘉:', 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('[mqttService] 淇濆瓨浜鸿劯鍑瘉缁撴灉:', voucherRet)
+ } else {
+ logger.error('[mqttService] 娉ㄥ唽浜鸿劯澶辫触锛岃繑鍥炵爜:', ret)
+ }
+ } else {
+ logger.error('[mqttService] 浜鸿劯鍥剧墖鏂囦欢涓嶅瓨鍦�:', faceFilePath)
+ }
+ } catch (error) {
+ logger.error('[mqttService] 澶勭悊浜鸿劯淇℃伅閿欒:', error)
+ return "澶勭悊浜鸿劯淇℃伅閿欒: " + error.message
+ } finally {
+ logger.info('[mqttService] 浜鸿劯淇℃伅澶勭悊瀹屾垚:', person.userId)
+ }
+ }
+ }
+ let ret = sqliteService.d1_person.saveAll(persons)
+ if (ret != 0) {
+ //澶辫触浜� 鎶婅繖浜涗汉鍏ㄩ兘鍒犻櫎鍚庡湪鏂板涓�涓�
+ let userIds = persons.map(obj => obj.userId);
+ sqliteService.d1_person.deleteByUserIdInBatch(userIds)
+ //閲嶆柊鏂板
+ let ret = sqliteService.d1_person.saveAll(persons)
+ if (ret != 0) {
+ return "sql error ret:" + ret
+ }
+ }
+
+ // 涓虹敤鎴锋坊鍔犲搴旀潈闄�
+ for (let i = 0; i < data.length; i++) {
+ const person = data[i];
+ let userId = person.userId
+ let userType = person.type
+
+ // 鍙湁淇濈鍛橈紙0锛夊拰绉戦暱锛�1锛夐渶瑕佹坊鍔犳潈闄�
+ if (userType == 0 || userType == 1) {
+ try {
+ // 妫�鏌ユ槸鍚﹀凡瀛樺湪鏉冮檺璁板綍
+ let existingPermissions = sqliteService.d1_permission.findByUserId(userId)
+ if (existingPermissions && existingPermissions.length == 0) {
+ // 娣诲姞姘镐箙鏉冮檺
+ let permissionRet = sqliteService.d1_permission.save({
+ permissionId: std.genRandomStr(32),
+ userId: userId,
+ timeType: 0, // 姘镐箙鏉冮檺
+ beginTime: 0,
+ endTime: 0,
+ repeatBeginTime: 0,
+ repeatEndTime: 0,
+ period: ""
+ });
+ logger.info('[mqttService] 涓虹敤鎴锋坊鍔犳潈闄愮粨鏋�:', permissionRet)
+ } else {
+ logger.info('[mqttService] 鐢ㄦ埛宸插瓨鍦ㄦ潈闄愯褰曪紝璺宠繃鏉冮檺娣诲姞:', userId)
+ }
+ } catch (error) {
+ logger.error('[mqttService] 娣诲姞鏉冮檺鏃跺嚭閿�:', error)
+ }
+ }
+ }
+
+ return true
+
+}
+
+/**
+ * 鏌ヨ浜哄憳
+ * @param {object} event - MQTT浜嬩欢瀵硅薄
+ */
+mqttService.getUser = function (event) {
+ try {
+ logger.info('[mqttService] 鎺ユ敹鍒癵etUser鍛戒护:', JSON.stringify(event.topic))
+ logger.info('[mqttService] 鍛戒护payload:', event.payload)
+ let payload = JSON.parse(event.payload)
+ let data = payload.payload && payload.payload.data ? payload.payload.data : {}
+ let res = this.getUserAgreement(data)
+ logger.info('[mqttService] 鏌ヨ缁撴灉:', JSON.stringify(res))
+ return reply(event, res)
+ } catch (error) {
+ logger.error('[mqttService] getUser error:', error)
+ return reply(event, { error: error.message }, CODE.E_100)
+ }
+}
+
+/**
+ * 鏌ヨ浜哄憳閫氱敤鍗忚鏍煎紡
+ * @param {object} data - 鏌ヨ鍙傛暟
+ * @returns {object} 鏌ヨ缁撴灉
+ */
+mqttService.getUserAgreement = function (data) {
+ try {
+ data.page = isEmpty(data.page) ? 0 : data.page
+ data.size = isEmpty(data.size) ? 10 : data.size
+ let totalCount = sqliteService.d1_person.count(data)
+ let persons = sqliteService.d1_person.findAll(data)
+ // 瑙f瀽 extra 瀛楁锛孞SON瀛楃涓茶浆鍖栦负JSON瀵硅薄锛屾秷闄よ浆涔夊瓧绗�
+ persons.forEach(person => {
+ try {
+ if (person.extra) {
+ person.extra = JSON.parse(person.extra)
+ }
+ } catch (error) {
+ logger.error('[mqttService] 瑙f瀽 extra 瀛楁閿欒:', error)
+ }
+ })
+
+ let result = {
+ content: persons,
+ page: data.page,
+ size: data.size,
+ total: totalCount,
+ totalPage: Math.ceil(totalCount / data.size),
+ count: persons.length
+ }
+
+ return result
+ } catch (error) {
+ logger.error('[mqttService] getUserAgreement error:', error)
+ throw error
+ }
+}
+
+/**
+ * 鍒犻櫎浜哄憳
+ * @param {object} event - MQTT浜嬩欢瀵硅薄
+ */
+mqttService.delUser = function (event) {
+ try {
+ logger.info('[mqttService] 鎺ユ敹鍒癲elUser鍛戒护:', JSON.stringify(event.topic))
+ logger.info('[mqttService] 鍛戒护payload:', event.payload)
+ let payload = JSON.parse(event.payload)
+ let data = payload.payload && payload.payload.data ? payload.payload.data : []
+ logger.info('[mqttService] 瑙f瀽鍚庣殑鍙傛暟:', JSON.stringify(data))
+ let res = this.delUserAgreement(data)
+ if (typeof res == 'string') {
+ logger.error('[mqttService] delUser澶辫触:', res)
+ return reply(event, res, CODE.E_100)
+ }
+ logger.info('[mqttService] delUser鎴愬姛')
+ return reply(event)
+ } catch (error) {
+ logger.error('[mqttService] delUser error:', error)
+ return reply(event, { error: error.message }, CODE.E_100)
+ }
+}
+
+/**
+ * 鍒犻櫎浜哄憳閫氱敤鍗忚鏍煎紡
+ * @param {array} data - 浜哄憳ID鏁扮粍
+ * @returns {boolean|string} true琛ㄧず鎴愬姛锛宻tring琛ㄧず閿欒淇℃伅
+ */
+mqttService.delUserAgreement = function (data) {
+ if (data && data.length > 0) {
+ sqliteService.transaction()
+ let ret1 = sqliteService.d1_person.deleteByUserIdInBatch(data)
+ let ret2 = sqliteService.d1_permission.deleteByUserIdInBatch(data)
+ let ret3 = sqliteService.d1_voucher.deleteByUserIdInBatch(data)
+ if (ret1 != 0 || ret2 != 0 || ret3 != 0) {
+ sqliteService.rollback()
+ return "sql error"
+ }
+ sqliteService.commit()
+ // 鍒犻櫎浜哄憳鐨勪汉鑴告暟鎹�
+ data.forEach(element => {
+ driver.face.delete(element)
+ });
+ }
+ return true
+}
+
+
+/**
+ * 娓呯┖浜哄憳
+ * @param {object} event - MQTT浜嬩欢瀵硅薄
+ */
+mqttService.clearUser = function (event) {
+ try {
+ logger.info('[mqttService] 鎺ユ敹鍒癱learUser鍛戒护:', JSON.stringify(event.topic))
+ logger.info('[mqttService] 鍛戒护payload:', event.payload)
+ let persons = sqliteService.d1_person.findAll()
+ // 鍒犻櫎鎵�鏈変汉鍛樼殑浜鸿劯鏁版嵁
+ logger.info('[mqttService] 寮�濮嬪垹闄や汉鑴告暟鎹紝鍏�', persons.length, '鏉�')
+ persons.forEach(element => {
+ driver.face.delete(element.userId)
+ });
+ let ret1 = sqliteService.d1_person.deleteAll()
+ let ret2 = sqliteService.d1_permission.deleteAll()
+ let ret3 = sqliteService.d1_voucher.deleteAll()
+ if (ret1 == 0 && ret2 == 0 && ret3 == 0) {
+ logger.info('[mqttService] clearUser鎴愬姛')
+ return reply(event)
+ } else {
+ let errorMsg = "sql error ret: " + ret1 + ", " + ret2 + ", " + ret3
+ logger.error('[mqttService] clearUser澶辫触:', errorMsg)
+ return reply(event, errorMsg, CODE.E_100)
+ }
+ } catch (error) {
+ logger.error('[mqttService] clearUser error:', error)
+ return reply(event, { error: error.message }, CODE.E_100)
+ }
+}
+
+// =================================鍑瘉澧炲垹鏀规煡=================================
+/**
+ * 娣诲姞鍑瘉
+ * @param {object} event - MQTT浜嬩欢瀵硅薄
+ */
+mqttService.insertKey = function (event) {
+ try {
+ logger.info('[mqttService] 鎺ユ敹鍒癷nsertKey鍛戒护:', JSON.stringify(event.topic))
+ logger.info('[mqttService] 鍛戒护payload:', event.payload)
+ let payload = JSON.parse(event.payload)
+ let data = payload.payload && payload.payload.data ? payload.payload.data : {}
+ logger.info('[mqttService] 瑙f瀽鍚庣殑鍙傛暟:', JSON.stringify(data))
+ let res = this.insertKeyAgreement(data)
+ if (typeof res == 'string') {
+ logger.error('[mqttService] insertKey澶辫触:', res)
+ return reply(event, res, CODE.E_100)
+ }
+ logger.info('[mqttService] insertKey鎴愬姛')
+ return reply(event)
+ } catch (error) {
+ logger.error('[mqttService] insertKey error:', error)
+ return reply(event, { error: error.message }, CODE.E_100)
+ }
+}
+
+/**
+ * 娣诲姞鍑瘉閫氱敤鍗忚鏍煎紡
+ * @param {array} data - 鍑瘉鏁版嵁鏁扮粍
+ * @returns {boolean|string} true琛ㄧず鎴愬姛锛宻tring琛ㄧず閿欒淇℃伅
+ */
+mqttService.insertKeyAgreement = function (data) {
+ let vouchers = []
+ for (let i = 0; i < data.length; i++) {
+ const voucher = data[i];
+ if (!voucher.keyId || !voucher.type || !voucher.code || !voucher.userId) {
+ return "keyId or type or code or userId cannot be empty"
+ }
+
+ // 鍑瘉閲嶅
+ let ret = sqliteService.d1_voucher.findAllBycode(voucher.code)
+ if (ret.length != 0) {
+ return "Duplicate vouchers"
+ }
+
+ if (voucher.type == 300) {
+ if (voucher.extra) {
+ if (voucher.extra.faceType != 0 && voucher.extra.faceType != 1) {
+ return "faceType Incorrect format"
+ }
+ } else {
+ return "faceType is required"
+ }
+ }
+ let record = {}
+ record.keyId = voucher.keyId
+ record.type = voucher.type
+ if (voucher.type == "400") {
+ if (voucher.code.length > 6) {
+ return "Password length cannot exceed 6 digits"
+ }
+ }
+ if (voucher.type == "300") {
+ if (voucher.extra.faceType == 0) {
+ record.code = `/app/data/user/${voucher.userId}/register.jpg`
+ // 淇濆瓨base64鍥剧墖
+ std.ensurePathExists(record.code)
+ common.base64_2binfile(record.code, voucher.code)
+ // 娉ㄥ唽浜鸿劯
+ let weq = driver.face.registerFaceByPicFile(voucher.userId, record.code)
+ if (weq == 0) {
+ logger.info("娉ㄥ唽浜鸿劯鎴愬姛")
+ } else {
+ logger.info("绗竴娆′汉鑴告敞鍐屽け璐�")
+ //鍒犻櫎閲嶆柊娉ㄥ唽
+ driver.face.delete(voucher.userId)
+ let res = driver.face.registerFaceByPicFile(voucher.userId, record.code)
+ if (res == 0) {
+ logger.info("绗簩娆℃敞鍐屼汉鑴告垚鍔�")
+ sqliteService.d1_voucher.deleteByKeyId(record.keyId)
+ } else {
+ return "Face registration failed"
+ }
+ }
+ } else {
+ record.code = voucher.code
+ //鐗瑰緛鍊兼敞鍐�
+ let res = driver.face.reg(voucher.userId, voucher.code)
+ if (res != 0) {
+ return "Face registration failed"
+ }
+ }
+ } else {
+ record.code = voucher.code
+ let ret = sqliteService.d1_voucher.findAllByCodeAndType(voucher.code, voucher.type)
+ if (ret.length != 0) {
+ return "Duplicate vouchers"
+ }
+ }
+
+ record.userId = voucher.userId
+ record.extra = isEmpty(voucher.extra) ? JSON.stringify({ type: 0 }) : JSON.stringify(voucher.extra)
+ vouchers.push(record)
+ }
+ let ret = sqliteService.d1_voucher.saveAll(vouchers)
+ if (ret == 0) {
+ return true
+ } else {
+ return "sql error ret:" + ret
+ }
+}
+
+/**
+ * 鏌ヨ鍑瘉
+ * @param {object} event - MQTT浜嬩欢瀵硅薄
+ */
+mqttService.getKey = function (event) {
+ try {
+ logger.info('[mqttService] 鎺ユ敹鍒癵etKey鍛戒护:', JSON.stringify(event.topic))
+ logger.info('[mqttService] 鍛戒护payload:', event.payload)
+ let payload = JSON.parse(event.payload)
+ let data = payload.payload && payload.payload.data ? payload.payload.data : {}
+ logger.info('[mqttService] 瑙f瀽鍚庣殑鏌ヨ鍙傛暟:', JSON.stringify(data))
+ let res = this.getKeyAgreement(data)
+ if (typeof res == 'string') {
+ logger.error('[mqttService] getKey澶辫触:', res)
+ return reply(event, res, CODE.E_100)
+ }
+ logger.info('[mqttService] 鏌ヨ缁撴灉:', JSON.stringify(res))
+ return reply(event, res)
+ } catch (error) {
+ logger.error('[mqttService] getKey error:', error)
+ return reply(event, { error: error.message }, CODE.E_100)
+ }
+}
+
+/**
+ * 鏌ヨ鍑瘉閫氱敤鍗忚鏍煎紡
+ * @param {object} data - 鏌ヨ鍙傛暟
+ * @returns {object|string} 鏌ヨ缁撴灉鎴栭敊璇俊鎭�
+ */
+mqttService.getKeyAgreement = function (data) {
+ if (!data.type) {
+ return "type is required"
+ }
+ if (data.type == 300) {
+ data.size = 1
+ } else {
+ data.page = isEmpty(data.page) ? 0 : data.page
+ data.size = isEmpty(data.size) ? 10 : data.size
+ }
+ let totalCount = sqliteService.d1_voucher.count(data)
+ let vouchers = sqliteService.d1_voucher.findAll(data)
+ vouchers.forEach(element => {
+ if (element.type == 300 && element.extra && JSON.parse(element.extra).faceType == 0) {
+ //浜鸿劯鐗规畩澶勭悊涓�涓�
+ element.code = driver.face.fileToBase64(element.code)
+ }
+ });
+ return {
+ content: vouchers,
+ page: data.page,
+ size: data.size,
+ total: totalCount,
+ totalPage: Math.ceil(totalCount / data.size),
+ count: vouchers.length
+ }
+}
+
+/**
+ * 鍒犻櫎鍑瘉
+ * @param {object} event - MQTT浜嬩欢瀵硅薄
+ */
+mqttService.delKey = function (event) {
+ try {
+ logger.info('[mqttService] 鎺ユ敹鍒癲elKey鍛戒护:', JSON.stringify(event.topic))
+ logger.info('[mqttService] 鍛戒护payload:', event.payload)
+ let payload = JSON.parse(event.payload)
+ let data = payload.payload && payload.payload.data ? payload.payload.data : {}
+ logger.info('[mqttService] 瑙f瀽鍚庣殑鍙傛暟:', JSON.stringify(data))
+ let res = this.delKeyAgreement(data)
+ if (typeof res == 'string') {
+ logger.error('[mqttService] delKey澶辫触:', res)
+ return reply(event, res, CODE.E_100)
+ }
+ logger.info('[mqttService] delKey鎴愬姛')
+ return reply(event)
+ } catch (error) {
+ logger.error('[mqttService] delKey error:', error)
+ return reply(event, { error: error.message }, CODE.E_100)
+ }
+}
+
+/**
+ * 鍒犻櫎鍑瘉閫氱敤鍗忚鏍煎紡
+ * @param {object} data - 鍒犻櫎鍙傛暟
+ * @returns {boolean|string} true琛ㄧず鎴愬姛锛宻tring琛ㄧず閿欒淇℃伅
+ */
+mqttService.delKeyAgreement = function (data) {
+ if (data.keyIds && data.keyIds.length > 0) {
+ let userIds = []
+ for (let i = 0; i < data.keyIds.length; i++) {
+ const element = data.keyIds[i];
+ let res = sqliteService.d1_voucher.findAllByKeyId(element)
+ if (res.length <= 0) {
+ continue
+ }
+ if (res[0].type == 300) {
+ userIds.push(res[0].userId)
+ }
+ }
+ let ret = sqliteService.d1_voucher.deleteByKeyIdInBatch(data.keyIds)
+ if (ret != 0) {
+ return "sql error ret:" + ret
+ }
+ // 鍒犻櫎浜鸿劯鏁版嵁
+ userIds.forEach(element => {
+ driver.face.delete(element)
+ });
+ }
+ if (data.userIds && data.userIds.length > 0) {
+ let ret = sqliteService.d1_voucher.deleteByUserIdInBatch(data.userIds)
+ if (ret != 0) {
+ return "sql error ret:" + ret
+ }
+ // 鍒犻櫎浜鸿劯鏁版嵁
+ data.userIds.forEach(element => {
+ driver.face.delete(element)
+ });
+ }
+ return true
+}
+
+/**
+ * 娓呯┖鍑瘉
+ * @param {object} event - MQTT浜嬩欢瀵硅薄
+ */
+mqttService.clearKey = function (event) {
+ try {
+ logger.info('[mqttService] 鎺ユ敹鍒癱learKey鍛戒护:', JSON.stringify(event.topic))
+ logger.info('[mqttService] 鍛戒护payload:', event.payload)
+ let res = sqliteService.d1_voucher.findAll()
+ let userIds = []
+ res.forEach(element => {
+ if (element.type == 300) {
+ userIds.push(element.userId)
+ }
+ });
+ logger.info('[mqttService] 鎵惧埌闇�瑕佸垹闄ょ殑浜鸿劯鏁版嵁锛屽叡', userIds.length, '鏉�')
+ let ret = sqliteService.d1_voucher.deleteAll()
+ if (ret == 0) {
+ // 鍒犻櫎浜鸿劯鏁版嵁
+ logger.info('[mqttService] 寮�濮嬪垹闄や汉鑴告暟鎹�')
+ userIds.forEach((element, index) => {
+ driver.face.delete(element)
+ });
+ logger.info('[mqttService] clearKey鎴愬姛')
+ reply(event)
+ } else {
+ logger.error('[mqttService] clearKey澶辫触:', "sql error ret:" + ret)
+ reply(event, "sql error ret:" + ret, CODE.E_100)
+ }
+ } catch (error) {
+ logger.error('[mqttService] clearKey error:', error)
+ return reply(event, { error: error.message }, CODE.E_100)
+ }
+}
+
+// =================================搴旀�ュ紑浠撳瘑鐮佸鍒犳敼鏌�=================================
+/**
+ * 娣诲姞搴旀�ュ紑浠撳瘑鐮�
+ * @param {object} event - MQTT浜嬩欢瀵硅薄
+ */
+mqttService.insertEmergencyPassword = function (event) {
+ try {
+ logger.info('[mqttService] 鎺ユ敹鍒癷nsertEmergencyPassword鍛戒护:', JSON.stringify(event.topic))
+ logger.info('[mqttService] 鍛戒护payload:', event.payload)
+ let payload = JSON.parse(event.payload)
+ let data = payload.payload && payload.payload.data ? payload.payload.data : {}
+ logger.info('[mqttService] 瑙f瀽鍚庣殑鍙傛暟:', JSON.stringify(data))
+ let res = this.insertEmergencyPasswordAgreement(data)
+ if (typeof res == 'string') {
+ logger.error('[mqttService] insertEmergencyPassword澶辫触:', res)
+ return reply(event, res, CODE.E_100)
+ }
+ logger.info('[mqttService] insertEmergencyPassword鎴愬姛')
+ return reply(event)
+ } catch (error) {
+ logger.error('[mqttService] insertEmergencyPassword error:', error)
+ return reply(event, { error: error.message }, CODE.E_100)
+ }
+}
+
+/**
+ * 娣诲姞搴旀�ュ紑浠撳瘑鐮侀�氱敤鍗忚鏍煎紡
+ * @param {object} data - 搴旀�ュ紑浠撳瘑鐮佹暟鎹璞�
+ * @returns {boolean|string} true琛ㄧず鎴愬姛锛宻tring琛ㄧず閿欒淇℃伅
+ */
+mqttService.insertEmergencyPasswordAgreement = 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 || ""
+ 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
+ }
+}
+
+/**
+ * 鏌ヨ搴旀�ュ紑浠撳瘑鐮�
+ * @param {object} event - MQTT浜嬩欢瀵硅薄
+ */
+mqttService.getEmergencyPassword = function (event) {
+ try {
+ logger.info('[mqttService] 鎺ユ敹鍒癵etEmergencyPassword鍛戒护:', JSON.stringify(event.topic))
+ logger.info('[mqttService] 鍛戒护payload:', event.payload)
+ let payload = JSON.parse(event.payload)
+ let res = this.getEmergencyPasswordAgreement()
+ logger.info('[mqttService] 鏌ヨ缁撴灉:', JSON.stringify(res))
+ return reply(event, res)
+ } catch (error) {
+ logger.error('[mqttService] getEmergencyPassword error:', error)
+ return reply(event, { error: error.message }, CODE.E_100)
+ }
+}
+
+/**
+ * 鏃堕棿鎴宠浆鏃ユ湡瀛楃涓�
+ * @param {number} timestamp - 鏃堕棿鎴�
+ * @returns {string} 鏃ユ湡瀛楃涓诧紝鏍煎紡锛歒YYY-MM-DD HH:MM:SS
+ */
+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}`;
+}
+
+/**
+ * 鏌ヨ搴旀�ュ紑浠撳瘑鐮侀�氱敤鍗忚鏍煎紡
+ * @returns {object} 鏌ヨ缁撴灉
+ */
+mqttService.getEmergencyPasswordAgreement = function () {
+ let passwords = sqliteService.d1_emergency_password.findAll()
+ if (passwords && passwords.length > 0) {
+ let password = passwords[0];
+ // 杞崲鏃堕棿鎴充负瀛楃涓叉牸寮�
+ password.createTime = timestampToDateString(password.createTime);
+ password.updateTime = timestampToDateString(password.updateTime);
+ return password;
+ }
+ return {};
+}
+
+
+/**
+ * 娓呯┖搴旀�ュ紑浠撳瘑鐮�
+ * @param {object} event - MQTT浜嬩欢瀵硅薄
+ */
+mqttService.clearEmergencyPassword = function (event) {
+ try {
+ logger.info('[mqttService] 鎺ユ敹鍒癱learEmergencyPassword鍛戒护:', JSON.stringify(event.topic))
+ logger.info('[mqttService] 鍛戒护payload:', event.payload)
+ let ret = sqliteService.d1_emergency_password.deleteAll()
+ if (ret == 0) {
+ logger.info('[mqttService] clearEmergencyPassword鎴愬姛')
+ return reply(event)
+ } else {
+ logger.error('[mqttService] clearEmergencyPassword澶辫触:', "sql error ret:" + ret)
+ return reply(event, "sql error ret:" + ret, CODE.E_100)
+ }
+ } catch (error) {
+ logger.error('[mqttService] clearEmergencyPassword error:', error)
+ return reply(event, { error: error.message }, CODE.E_100)
+ }
+}
+
+// =================================瀵嗛挜澧炲垹鏀规煡=================================
+/**
+ * 娣诲姞瀵嗛挜
+ * @param {object} event - MQTT浜嬩欢瀵硅薄
+ */
+mqttService.insertSecurity = function (event) {
+ try {
+ logger.info('[mqttService] 鎺ユ敹鍒癷nsertSecurity鍛戒护:', JSON.stringify(event.topic))
+ logger.info('[mqttService] 鍛戒护payload:', event.payload)
+ let payload = JSON.parse(event.payload)
+ let data = payload.payload && payload.payload.data ? payload.payload.data : {}
+ logger.info('[mqttService] 瑙f瀽鍚庣殑鍙傛暟:', JSON.stringify(data))
+ let res = this.insertSecurityAgreement(data)
+ if (typeof res == 'string') {
+ logger.error('[mqttService] insertSecurity澶辫触:', res)
+ return reply(event, res, CODE.E_100)
+ }
+ logger.info('[mqttService] insertSecurity鎴愬姛')
+ return reply(event)
+ } catch (error) {
+ logger.error('[mqttService] insertSecurity error:', error)
+ return reply(event, { error: error.message }, CODE.E_100)
+ }
+}
+
+/**
+ * 娣诲姞瀵嗛挜閫氱敤鍗忚鏍煎紡
+ * @param {array} data - 瀵嗛挜鏁版嵁鏁扮粍
+ * @returns {boolean|string} true琛ㄧず鎴愬姛锛宻tring琛ㄧず閿欒淇℃伅
+ */
+mqttService.insertSecurityAgreement = function (data) {
+ let securities = []
+ for (let i = 0; i < data.length; i++) {
+ const security = data[i];
+ let record = []
+ record.securityId = security.securityId
+ record.type = security.type
+ record.key = security.key
+ record.value = security.value
+ record.startTime = security.startTime
+ record.endTime = security.endTime
+ securities.push(record)
+ }
+ let ret = sqliteService.d1_security.saveAll(securities)
+ if (ret == 0) {
+ return true
+ } else {
+ return "sql error ret:" + ret
+ }
+}
+
+/**
+ * 鏌ヨ瀵嗛挜
+ * @param {object} event - MQTT浜嬩欢瀵硅薄
+ */
+mqttService.getKey = function (event) {
+ try {
+ logger.info('[mqttService] 鎺ユ敹鍒癵etKey鍛戒护:', JSON.stringify(event.topic))
+ logger.info('[mqttService] 鍛戒护payload:', event.payload)
+ let payload = JSON.parse(event.payload)
+ let data = payload.payload && payload.payload.data ? payload.payload.data : {}
+ logger.info('[mqttService] 瑙f瀽鍚庣殑鏌ヨ鍙傛暟:', JSON.stringify(data))
+ let res = this.getKeyAgreement(data)
+ logger.info('[mqttService] 鏌ヨ缁撴灉:', JSON.stringify(res))
+ return reply(event, res)
+ } catch (error) {
+ logger.error('[mqttService] getKey error:', error)
+ return reply(event, { error: error.message }, CODE.E_100)
+ }
+}
+
+/**
+ * 鏌ヨ瀵嗛挜閫氱敤鍗忚鏍煎紡
+ * @param {object} data - 鏌ヨ鍙傛暟
+ * @returns {object} 鏌ヨ缁撴灉
+ */
+mqttService.getSecurityAgreement = function (data) {
+ data.page = isEmpty(data.page) ? 0 : data.page
+ data.size = isEmpty(data.size) ? 10 : data.size
+ let totalCount = sqliteService.d1_security.count(data)
+ let securities = sqliteService.d1_security.findAll(data)
+ return {
+ content: securities,
+ page: data.page,
+ size: data.size,
+ total: totalCount,
+ totalPage: Math.ceil(totalCount / data.size),
+ count: securities.length
+ }
+}
+
+/**
+ * 鍒犻櫎瀵嗛挜
+ * @param {object} event - MQTT浜嬩欢瀵硅薄
+ */
+mqttService.delSecurity = function (event) {
+ try {
+ logger.info('[mqttService] 鎺ユ敹鍒癲elSecurity鍛戒护:', JSON.stringify(event.topic))
+ logger.info('[mqttService] 鍛戒护payload:', event.payload)
+ let payload = JSON.parse(event.payload)
+ let data = payload.payload && payload.payload.data ? payload.payload.data : {}
+ logger.info('[mqttService] 瑙f瀽鍚庣殑鍙傛暟:', JSON.stringify(data))
+ let res = this.delSecurityAgreement(data)
+ if (typeof res == 'string') {
+ logger.error('[mqttService] delSecurity澶辫触:', res)
+ return reply(event, res, CODE.E_100)
+ }
+ logger.info('[mqttService] delSecurity鎴愬姛')
+ return reply(event)
+ } catch (error) {
+ logger.error('[mqttService] delSecurity error:', error)
+ return reply(event, { error: error.message }, CODE.E_100)
+ }
+}
+
+/**
+ * 鍒犻櫎瀵嗛挜閫氱敤鍗忚鏍煎紡
+ * @param {array} data - 瀵嗛挜ID鏁扮粍
+ * @returns {boolean|string} true琛ㄧず鎴愬姛锛宻tring琛ㄧず閿欒淇℃伅
+ */
+mqttService.delSecurityAgreement = function (data) {
+ if (data.length > 0) {
+ let ret = sqliteService.d1_security.deleteBySecurityIdInBatch(data)
+ if (ret != 0) {
+ return "sql error ret:" + ret
+ }
+ }
+ return true
+}
+
+/**
+ * 娓呯┖瀵嗛挜
+ * @param {object} event - MQTT浜嬩欢瀵硅薄
+ */
+mqttService.clearSecurity = function (event) {
+ try {
+ logger.info('[mqttService] 鎺ユ敹鍒癱learSecurity鍛戒护:', JSON.stringify(event.topic))
+ logger.info('[mqttService] 鍛戒护payload:', event.payload)
+ let ret = sqliteService.d1_key.deleteAll()
+ if (ret == 0) {
+ logger.info('[mqttService] clearSecurity鎴愬姛')
+ return reply(event)
+ } else {
+ logger.error('[mqttService] clearSecurity澶辫触:', "sql error ret:" + ret)
+ return reply(event, "sql error ret:" + ret, CODE.E_100)
+ }
+ } catch (error) {
+ logger.error('[mqttService] clearSecurity error:', error)
+ return reply(event, { error: error.message }, CODE.E_100)
+ }
+}
+
+/**
+ * 杩滅▼鎺у埗
+ * @param {object} event - MQTT浜嬩欢瀵硅薄
+ */
+mqttService.control = function (event) {
+ try {
+ logger.info('[mqttService] 鎺ユ敹鍒癱ontrol鍛戒护:', JSON.stringify(event.topic))
+ logger.info('[mqttService] 鍛戒护payload:', event.payload)
+ let payload = JSON.parse(event.payload)
+ let data = payload.payload.data || {}
+ switch (data.command) {
+ case 0:
+ //閲嶅惎
+ logger.info('[mqttService] 鎵ц閲嶅惎鍛戒护')
+ reply(event)
+ common.asyncReboot(2)
+ return
+ case 1:
+ //杩滅▼寮�闂�
+ logger.info('[mqttService] 鎵ц杩滅▼寮�闂ㄥ懡浠�')
+ driver.gpio.open()
+ break
+ case 4:
+ //閲嶇疆
+ logger.info('[mqttService] 鎵ц閲嶇疆鍛戒护')
+ common.systemBrief("rm -rf /app/data/config/*")
+ common.systemBrief("rm -rf /app/data/db/*")
+ common.systemBrief("rm -rf /app/data/user/*")
+ common.systemBrief("rm -rf /app/data/user/*")
+ common.systemBrief("rm -rf /vgmj.db")
+ reply(event)
+ common.asyncReboot(2)
+ return
+ case 5:
+ //鎾斁璇煶
+ logger.info('[mqttService] 鎵ц鎾斁璇煶鍛戒护')
+ if (data.extra) {
+ let res = common.systemWithRes(`test -e "/app/code/resource/wav/${data.extra.wav}.wav" && echo "OK" || echo "NO"`, 2)
+ if (res.includes('OK')) {
+ driver.alsa.play(`/app/code/resource/wav/${data.extra.wav}.wav`)
+ }
+ }
+ break
+ case 6:
+ // 6锛氬睆骞曞睍绀哄浘鐗�
+ // TODO
+ logger.info('[mqttService] 鎵ц灞忓箷灞曠ず鍥剧墖鍛戒护')
+ break
+ case 7:
+ // 7锛氬睆骞曞睍绀烘枃瀛�
+ // TODO
+ logger.info('[mqttService] 鎵ц灞忓箷灞曠ず鏂囧瓧鍛戒护')
+ break
+ case 10:
+ logger.info('[mqttService] 鎵ц浜岀淮鐮佸睍绀哄懡浠�')
+ if (!isEmpty(data.extra.qrCodeBase64) && typeof data.extra.qrCodeBase64 == 'string') {
+ //base64杞浘鐗囦繚瀛�
+ let src = `/app/code/resource/image/app_qrcode.png`
+ std.ensurePathExists(src)
+ common.base64_2binfile(src, data.extra.qrCodeBase64)
+ logger.info('[mqttService] 浜岀淮鐮佷繚瀛樻垚鍔�')
+ return reply(event)
+ }
+ break
+ default:
+ logger.info('[mqttService] 鏈煡鍛戒护:', data.command)
+ break
+ }
+ logger.info('[mqttService] control鍛戒护鎵ц瀹屾垚')
+ return reply(event)
+ } catch (error) {
+ logger.error('[mqttService] control error:', error)
+ return reply(event, { error: error.message }, CODE.E_100)
+ }
+}
+
+/**
+ * 鏌ヨ閰嶇疆
+ * @param {object} event - MQTT浜嬩欢瀵硅薄
+ */
+mqttService.getConfig = function (event) {
+ try {
+ logger.info('[mqttService] 鎺ユ敹鍒癵etConfig鍛戒护:', JSON.stringify(event.topic))
+ logger.info('[mqttService] 鍛戒护payload:', event.payload)
+ let payload = JSON.parse(event.payload)
+ let data = payload.payload && payload.payload.data ? payload.payload.data : {}
+ logger.info('[mqttService] 瑙f瀽鍚庣殑鍙傛暟:', JSON.stringify(data))
+ let configAll = config.getAll()
+ let res = {}
+ // 閰嶇疆鍒嗙粍
+ for (const key in configAll) {
+ const value = configAll[key];
+ const keys = key.split(".")
+ if (keys.length == 2) {
+ if (!res[keys[0]]) {
+ res[keys[0]] = {}
+ }
+ res[keys[0]][keys[1]] = value
+ } else {
+ res[keys[0]] = value
+ }
+ }
+ res.sys = {
+ // 淇濈暀鍘熸湁鐨� sysInfo 涓殑鍏朵粬鍊�
+ ...res.sys,
+ totalmem: common.getTotalmem(),
+ freemem: common.getFreemem(),
+ totaldisk: common.getTotaldisk(),
+ freedisk: common.getFreedisk(),
+ freecpu: common.getFreecpu()
+ };
+ if (isEmpty(data) || typeof data != "string" || data == "") {
+ // 鏌ヨ鍏ㄩ儴
+ logger.info('[mqttService] getConfig鎴愬姛锛岃繑鍥炲叏閮ㄩ厤缃紝閰嶇疆鏁伴噺:', Object.keys(res).length)
+ return reply(event, res)
+ }
+ // 鍗曟潯浠舵煡璇�"data": "mqttInfo.clientId"
+ let keys = data.split(".")
+ let search = {}
+ if (keys.length == 2) {
+ if (res[keys[0]]) {
+ search[keys[0]] = {}
+ search[keys[0]][keys[1]] = res[keys[0]][keys[1]]
+ }
+ } else {
+ search[keys[0]] = res[keys[0]]
+ }
+ logger.info('[mqttService] getConfig鎴愬姛锛岃繑鍥炴寚瀹氶厤缃�:', JSON.stringify(search))
+ return reply(event, search)
+ } catch (error) {
+ logger.error('[mqttService] getConfig error:', error)
+ return reply(event, { error: error.message }, CODE.E_100)
+ }
+}
+
+/**
+ * 淇敼閰嶇疆
+ * @param {object} event - MQTT浜嬩欢瀵硅薄
+ */
+mqttService.setConfig = function (event) {
+ try {
+ logger.info('[mqttService] 鎺ユ敹鍒皊etConfig鍛戒护:', JSON.stringify(event.topic))
+ logger.info('[mqttService] 鍛戒护payload:', event.payload)
+ let payload = JSON.parse(event.payload)
+ let data = payload.payload && payload.payload.data ? payload.payload.data : {}
+ logger.info('[mqttService] 瑙f瀽鍚庣殑鍙傛暟:', JSON.stringify(data))
+ if (!data || typeof data != 'object') {
+ logger.error('[mqttService] setConfig澶辫触: data should not be empty')
+ return reply(event, "data should not be empty", CODE.E_100)
+ }
+ let res = configService.configVerifyAndSave(data)
+ if (typeof res != 'boolean') {
+ // 杩斿洖閿欒淇℃伅
+ logger.error('[mqttService] setConfig澶辫触:', res)
+ return reply(event, res, CODE.E_100)
+ }
+ if (res) {
+ logger.info('[mqttService] setConfig鎴愬姛')
+ return reply(event)
+ } else {
+ logger.error('[mqttService] setConfig澶辫触: unknown failure')
+ return reply(event, "unknown failure", CODE.E_100)
+ }
+ } catch (error) {
+ logger.error('[mqttService] setConfig error:', error)
+ return reply(event, { error: error.message }, CODE.E_100)
+ }
+}
+
+/**
+ * 鍗囩骇鍥轰欢
+ * @param {object} event - MQTT浜嬩欢瀵硅薄
+ */
+mqttService.upgradeFirmware = function (event) {
+ try {
+ logger.info('[mqttService] 鎺ユ敹鍒皍pgradeFirmware鍛戒护:', JSON.stringify(event.topic))
+ logger.info('[mqttService] 鍛戒护payload:', event.payload)
+ let payload = JSON.parse(event.payload)
+ let data = payload.payload && payload.payload.data ? payload.payload.data : {}
+ logger.info('[mqttService] 瑙f瀽鍚庣殑鍙傛暟:', JSON.stringify(data))
+ if (!data || typeof data != 'object' || typeof data.type != 'number' || typeof data.url != 'string' || typeof data.md5 != 'string') {
+ logger.error('[mqttService] upgradeFirmware澶辫触: data\'s params error')
+ return reply(event, "data's params error", CODE.E_100)
+ }
+
+ if (data.type == 0) {
+ try {
+ logger.info('[mqttService] 寮�濮嬪浐浠跺崌绾э紝url:', data.url, 'md5:', data.md5)
+ driver.screen.upgrade({ title: "confirm.upgrade", content: "confirm.upgrading" })
+ ota.updateHttp(data.url, data.md5, 300)
+ driver.screen.upgrade({ title: "confirm.upgrade", content: "confirm.upgradeSuccess" })
+ logger.info('[mqttService] 鍥轰欢鍗囩骇鎴愬姛')
+ reply(event)
+ common.asyncReboot(3)
+ return
+ } catch (error) {
+ logger.error('[mqttService] 鍥轰欢鍗囩骇澶辫触:', error)
+ driver.screen.upgrade({ title: "confirm.upgrade", content: "confirm.upgradeFail" })
+ return reply(event, "upgrade failure", CODE.E_100)
+ }
+ }
+
+ logger.error('[mqttService] upgradeFirmware澶辫触: 涓嶆敮鎸佺殑鍗囩骇绫诲瀷')
+ return reply(event, "upgrade failure", CODE.E_100)
+ } catch (error) {
+ logger.error('[mqttService] upgradeFirmware error:', error)
+ return reply(event, { error: error.message }, CODE.E_100)
+ }
+}
+
+/**
+ * 鏌ヨ璇嗗埆璁板綍
+ * @param {object} event - MQTT浜嬩欢瀵硅薄
+ */
+mqttService.getRecords = function (event) {
+ try {
+ logger.info('[mqttService] 鎺ユ敹鍒癵etRecords鍛戒护:', JSON.stringify(event.topic))
+ logger.info('[mqttService] 鍛戒护payload:', event.payload)
+ let payload = JSON.parse(event.payload)
+ let data = payload.payload && payload.payload.data ? payload.payload.data : {}
+ logger.info('[mqttService] 瑙f瀽鍚庣殑鏌ヨ鍙傛暟:', JSON.stringify(data))
+ let res = this.getRecordsAgreement(data)
+ logger.info('[mqttService] 鏌ヨ缁撴灉:', JSON.stringify(res))
+ return reply(event, res)
+ } catch (error) {
+ logger.error('[mqttService] getRecords error:', error)
+ return reply(event, { error: error.message }, CODE.E_100)
+ }
+}
+
+/**
+ * 灏嗘棩鏈熷瓧绗︿覆杞崲涓烘椂闂存埑锛堢锛�
+ * @param {string} dateString - 鏃ユ湡瀛楃涓诧紝鏍煎紡锛歒YYY-MM-DD HH:MM:SS
+ * @returns {number} 鏃堕棿鎴筹紙绉掞級
+ */
+function dateStringToTimestamp(dateString) {
+ if (!dateString) return null
+ // 灏哬YYY-MM-DD HH:MM:SS鏍煎紡杞崲涓篩YYY-MM-DDTHH:MM:SS鏍煎紡锛屼互渚縩ew Date()姝g‘瑙f瀽
+ const formattedDateString = dateString.replace(' ', 'T')
+ const date = new Date(formattedDateString)
+ return Math.floor(date.getTime() / 1000)
+}
+
+/**
+ * 鏌ヨ璇嗗埆璁板綍閫氱敤鍗忚鏍煎紡
+ * @param {object} data - 鏌ヨ鍙傛暟
+ * @returns {object} 鏌ヨ缁撴灉
+ */
+mqttService.getRecordsAgreement = function (data) {
+ data.page = isEmpty(data.page) ? 0 : data.page
+ data.size = isEmpty(data.size) ? 10 : data.size
+
+ // 澶勭悊鏃堕棿鍙傛暟锛屽皢瀛楃涓叉牸寮忚浆鎹负鏃堕棿鎴�
+ let startTime = null
+ let endTime = null
+ if (data.startTime) {
+ if (typeof data.startTime === 'string') {
+ startTime = dateStringToTimestamp(data.startTime)
+ } else {
+ startTime = Math.floor(data.startTime / 1000) // 杞崲涓虹绾ф椂闂存埑
+ }
+ }
+ if (data.endTime) {
+ if (typeof data.endTime === 'string') {
+ endTime = dateStringToTimestamp(data.endTime)
+ } else {
+ endTime = Math.floor(data.endTime / 1000) // 杞崲涓虹绾ф椂闂存埑
+ }
+ }
+
+ // 鏋勫缓鏌ヨ鏉′欢
+ let queryData = {}
+ let nameFilter = null
+ // 澶嶅埗鍏朵粬鏌ヨ鍙傛暟
+ for (const key in data) {
+ if (key !== 'startTime' && key !== 'endTime' && key !== 'name') {
+ queryData[key] = data[key]
+ } else if (key === 'name') {
+ nameFilter = data[key]
+ }
+ }
+
+ // 鏋勫缓SQL鏉′欢
+ let whereClause = ''
+ if (startTime) {
+ whereClause += `time >= ${startTime} `
+ }
+ if (endTime) {
+ if (whereClause) {
+ whereClause += `AND `
+ }
+ whereClause += `time <= ${endTime} `
+ }
+
+ // 澶嶅埗鍏朵粬鏉′欢
+ for (const key in queryData) {
+ if (key !== 'page' && key !== 'size') {
+ if (whereClause) {
+ whereClause += `AND `
+ }
+ if (typeof queryData[key] === 'string') {
+ whereClause += `${key} = '${queryData[key]}' `
+ } else {
+ whereClause += `${key} = ${queryData[key]} `
+ }
+ }
+ }
+
+ // 鎵ц鏌ヨ
+ let totalCount = 0
+ let securities = []
+ try {
+ // 鏋勫缓count SQL
+ let countSql = `SELECT COUNT(*) FROM d1_pass_record `
+ if (whereClause) {
+ countSql += `WHERE ${whereClause} `
+ }
+ countSql += `;`
+ let countResult = sqlite.select(countSql)
+ if (countResult && countResult[0] && countResult[0]['COUNT(*)']) {
+ totalCount = countResult[0]['COUNT(*)']
+ }
+
+ // 鏋勫缓findAll SQL
+ let findSql = `SELECT * FROM d1_pass_record `
+ if (whereClause) {
+ findSql += `WHERE ${whereClause} `
+ }
+ findSql += `ORDER BY time DESC `
+ if (queryData.page !== undefined && queryData.size !== undefined) {
+ findSql += `LIMIT ${queryData.size} OFFSET ${queryData.page * queryData.size} `
+ }
+ findSql += `;`
+ securities = sqlite.select(findSql)
+ } catch (error) {
+ logger.error('[mqttService] 鏌ヨ璁板綍澶辫触:', error)
+ }
+
+ // 澶勭悊姣忔潯璁板綍
+ let processedSecurities = securities.map(record => {
+ // 瑙f瀽extra瀛楁
+ let extraData = {}
+ try {
+ if (record.extra && record.extra !== '') {
+ extraData = JSON.parse(record.extra)
+ }
+ } catch (error) {
+ logger.error('[mqttService] 瑙f瀽extra澶辫触:', error)
+ }
+
+ // 瑙f瀽extra2瀛楁
+ let extra2Data = {}
+ try {
+ if (record.extra2 && record.extra2 !== '') {
+ extra2Data = JSON.parse(record.extra2)
+ }
+ } catch (error) {
+ logger.error('[mqttService] 瑙f瀽extra2澶辫触:', error)
+ }
+
+ // 鏋勫缓鏂拌褰�
+ return {
+ id: record.id,
+ keyId: record.keyId,
+ permissionId: record.permissionId,
+ permissionId2: record.permissionId2,
+ userId: record.userId,
+ userId2: record.userId2,
+ type: record.type,
+ code: record.code,
+ door: record.door,
+ time: timestampToDateString(record.time * 1000), // 灏嗙绾ф椂闂存埑杞崲涓烘绉掔骇锛屽啀杞崲涓烘棩鏈熷瓧绗︿覆
+ result: record.result,
+ name: extraData.name || '',
+ idCard: extraData.idCard || '',
+ name2: extra2Data.name || '',
+ idCard2: extra2Data.idCard || '',
+ message: record.message
+ }
+ })
+
+ // 搴旂敤name杩囨护
+ if (nameFilter) {
+ processedSecurities = processedSecurities.filter(record =>
+ record.name.toLowerCase().includes(nameFilter.toLowerCase())
+ )
+ // 鏇存柊鎬绘暟鍜屾�婚〉鏁�
+ totalCount = processedSecurities.length
+ }
+
+ return {
+ content: processedSecurities,
+ page: data.page,
+ size: data.size,
+ total: totalCount,
+ totalPage: Math.ceil(totalCount / data.size),
+ count: processedSecurities.length
+ }
+}
+
+/**
+ * 鍒犻櫎璁板綍
+ * @param {object} event - MQTT浜嬩欢瀵硅薄
+ */
+mqttService.delRecords = function (event) {
+ try {
+ logger.info('[mqttService] 鎺ユ敹鍒癲elRecords鍛戒护:', JSON.stringify(event.topic))
+ logger.info('[mqttService] 鍛戒护payload:', event.payload)
+ let payload = JSON.parse(event.payload)
+ let data = payload.payload && payload.payload.data ? payload.payload.data : {}
+ logger.info('[mqttService] 瑙f瀽鍚庣殑鍙傛暟:', JSON.stringify(data))
+ let res = this.delRecordsAgreement(data)
+ if (typeof res == 'string') {
+ logger.error('[mqttService] delRecords澶辫触:', res)
+ return reply(event, res, CODE.E_100)
+ }
+ logger.info('[mqttService] delRecords鎴愬姛')
+ return reply(event)
+ } catch (error) {
+ logger.error('[mqttService] delRecords error:', error)
+ return reply(event, { error: error.message }, CODE.E_100)
+ }
+}
+
+/**
+ * 鍒犻櫎璁板綍閫氱敤鍗忚鏍煎紡
+ * @param {object} data - 鍒犻櫎鍙傛暟
+ * @returns {boolean|string} true琛ㄧず鎴愬姛锛宻tring琛ㄧず閿欒淇℃伅
+ */
+mqttService.delRecordsAgreement = function (data) {
+
+ // 鏍规嵁鏃堕棿鑼冨洿鍒犻櫎璁板綍
+ if (data.startTime || data.endTime) {
+ logger.info('[mqttService] 鏃堕棿鑼冨洿: startTime=' + data.startTime + ', endTime=' + data.endTime)
+
+ try {
+ // 鏋勫缓鏌ヨ鏉′欢
+ let query = {};
+ if (data.startTime) {
+ query.startTime = data.startTime;
+ }
+ if (data.endTime) {
+ query.endTime = data.endTime;
+ }
+
+ // 浣跨敤getRecordsAgreement鍑芥暟鐨勬煡璇㈤�昏緫鏉ヨ幏鍙栫鍚堟潯浠剁殑璁板綍
+ let result = mqttService.getRecordsAgreement(query);
+ let records = result.content || [];
+
+ // 閫愪釜鍒犻櫎璁板綍
+ let deletedCount = 0;
+ for (let record of records) {
+ // 濡傛灉鏄汉鑴歌褰曪紝鍒犻櫎瀵瑰簲鐨勫浘鐗囨枃浠�
+ if (record.type == 300 && record.code) {
+ try {
+ common.systemBrief(`rm -rf ${record.code}`);
+ } catch (error) {
+ logger.error('[mqttService] 鍒犻櫎鍥剧墖鏂囦欢鍑洪敊: ' + error.message);
+ }
+ }
+ // 鍒犻櫎璁板綍
+ sqliteService.d1_pass_record.delete({ id: record.id });
+ deletedCount++;
+ }
+
+ logger.info('[mqttService] 鎴愬姛鍒犻櫎 ' + deletedCount + ' 鏉¤褰�');
+ } catch (error) {
+ logger.error('[mqttService] 鍒犻櫎璁板綍鍑洪敊: ' + error.message);
+ // 蹇界暐閿欒锛岃繑鍥炴垚鍔�
+ }
+ }
+
+ return true
+}
+/**
+ * 閫氳涓婃姤鍥炲
+ * @param {object} event - MQTT浜嬩欢瀵硅薄
+ */
+mqttService.access_reply = function (event) {
+ try {
+ logger.info('[mqttService] 鎺ユ敹鍒癮ccess_reply鍛戒护:', JSON.stringify(event.topic))
+ logger.info('[mqttService] 鍛戒护payload:', event.payload)
+ let payload = JSON.parse(event.payload)
+ logger.info('[mqttService] 瑙f瀽鍚庣殑鍙傛暟:', JSON.stringify(payload))
+ let serialNo = map.get(payload.serialNo)
+ if (serialNo) {
+ logger.info('[mqttService] 娓呯悊涓存椂鏂囦欢:', serialNo)
+ common.systemBrief(`rm -rf ${serialNo}`)
+ map.del(payload.serialNo)
+ }
+ logger.info('[mqttService] 娓呯┖閫氳璁板綍')
+ sqliteService.d1_pass_record.deleteAll()
+ logger.info('[mqttService] access_reply澶勭悊瀹屾垚')
+ } catch (error) {
+ logger.error('[mqttService] access_reply error:', error)
+ }
+}
+
+/**
+ * 鍦ㄧ嚎楠岃瘉鍥炲
+ * @param {object} raw - MQTT浜嬩欢瀵硅薄
+ */
+mqttService.access_online_reply = function (raw) {
+ try {
+ logger.info('[mqttService] 鎺ユ敹鍒癮ccess_online_reply鍛戒护:', JSON.stringify(raw.topic))
+ logger.info('[mqttService] 鍛戒护payload:', raw.payload)
+ let payload = JSON.parse(raw.payload)
+ logger.info('[mqttService] 瑙f瀽鍚庣殑鍙傛暟:', JSON.stringify(payload))
+ let map = dxMap.get("VERIFY")
+ let data = map.get(payload.serialNo)
+ if (data) {
+ logger.info('[mqttService] 澶勭悊鍦ㄧ嚎楠岃瘉鍥炲锛宻erialNo:', payload.serialNo)
+ map.del(payload.serialNo)
+ driver.mqtt.getOnlinecheckReply(payload)
+ }
+ logger.info('[mqttService] access_online_reply澶勭悊瀹屾垚')
+ } catch (error) {
+ logger.error('[mqttService] access_online_reply error:', error)
+ }
+}
+
+/**
+ * 閿欒浠g爜瀹氫箟
+ */
+const CODE = {
+ // 鎴愬姛
+ S_000: "000000",
+ // 鏈煡閿欒
+ E_100: "100000",
+ // 璁惧宸茶绂佺敤
+ E_101: "100001",
+ // 璁惧姝e繖锛岃绋嶅悗鍐嶈瘯
+ E_102: "100002",
+ // 绛惧悕妫�楠屽け璐�
+ E_103: "100003",
+ // 瓒呮椂閿欒
+ E_104: "100004",
+ // 璁惧绂荤嚎
+ E_105: "100005",
+}
+mqttService.CODE = CODE
+
+/**
+ * 涓婃姤璁惧淇℃伅鍜岄�氳璁板綍
+ */
+mqttService.report = function () {
+ // 鍦ㄧ嚎涓婃姤
+ let payloadReply = mqttReply(std.genRandomStr(10), {
+ mac: config.get("sys.mac") || '',
+ version: config.get("sys.version"),
+ appVersion: config.get("sys.version"),
+ releaseTime: config.get("sys.createTime"),
+ type: config.get("net.type"),
+ }, CODE.S_000)
+ driver.mqtt.send("access_device/v2/event/connect", JSON.stringify(payloadReply))
+
+ //閫氳璁板綍涓婃姤 - 宸插叧闂�
+ // let res = sqliteService.d1_pass_record.findAll()
+ // if (res.length <= 0) {
+ // return
+ // }
+ // // 绛涢�夊嚭 type === 300 鐨勫璞★紙浜鸿劯璁板綍锛�
+ // let faceArray = res.filter(item => item.type == 300);
+ // // 绛涢�夊嚭 type !== 300 鐨勫璞★紙鍏朵粬璁板綍锛�
+ // let recordArray = res.filter(item => item.type != 300);
+ // if (recordArray.length > 0) {
+ // driver.mqtt.send("access_device/v2/event/access", JSON.stringify(mqttReply(std.genRandomStr(10), recordArray, CODE.S_000)))
+ // }
+ // if (faceArray.length > 0) {
+ // let index = 0
+ // let timer = std.setInterval(() => {
+ // let serialNo = std.genRandomStr(10)
+ // //缂撳瓨鏀惧叆瑕佸垹闄ょ殑浜鸿劯鐓х墖 src
+ // map.del(serialNo)
+ // map.put(serialNo, faceArray[index].code)
+ //
+ // // 妫�鏌aceArray[index].code鏄惁鏈夋晥
+ // if (faceArray[index].code) {
+ // faceArray[index].code = driver.face.fileToBase64(faceArray[index].code)
+ // } else {
+ // faceArray[index].code = ""
+ // logger.info("浜鸿劯璁板綍涓璫ode瀛楁涓虹┖锛岃烦杩嘊ase64杞崲")
+ // }
+ //
+ // driver.mqtt.send("access_device/v2/event/access", JSON.stringify(mqttReply(serialNo, [faceArray[index]], CODE.S_000)))
+ // index++
+ // if (!faceArray[index]) {
+ // std.clearInterval(saveTimer)
+ // std.clearInterval(timer)
+ // }
+ // }, 1000)
+ // // 姣忛殧500ms妫�鏌ヤ竴娆qtt杩炴帴鐘舵�侊紝濡傛灉鏂紑锛屽垯鍋滄涓婃姤
+ // let saveTimer = std.setInterval(() => {
+ // if (!driver.mqtt.getStatus()) {
+ // std.clearInterval(saveTimer)
+ // std.clearInterval(timer)
+ // }
+ // }, 500)
+ // }
+}
+
+/**
+ * mqtt璇锋眰缁熶竴鍥炲
+ * @param {object} event - MQTT浜嬩欢瀵硅薄
+ * @param {any} data - 鍥炲鏁版嵁
+ * @param {string} code - 閿欒浠g爜
+ */
+function reply(event, data, code) {
+ try {
+ let topic = getReplyTopic(event)
+ let payload = JSON.parse(event.payload)
+ let serialNo = payload.serialNo || std.genRandomStr(10)
+ let reply = JSON.stringify(mqttReply(serialNo, data, isEmpty(code) ? CODE.S_000 : code))
+ driver.mqtt.send(topic, reply)
+ } catch (error) {
+ logger.error('[mqttService] reply error:', error)
+ }
+}
+
+/**
+ * 鑾峰彇鍥炲涓婚
+ * @param {object} data - MQTT浜嬩欢瀵硅薄
+ * @returns {string} 鍥炲涓婚
+ */
+function getReplyTopic(data) {
+ // return data.topic.replace("/" + config.get("sys.sn"), '') + "_reply";
+ try {
+ let sn = config.get("mqtt.clientId")
+ return data.topic.replace("/" + sn, '') + "_reply";
+ } catch (error) {
+ logger.error('[mqttService] getReplyTopic error:', error)
+ // 鍥為��鍒颁娇鐢ㄥ浐瀹氭牸寮�
+ return data.topic + "_reply"
+ }
+}
+
+/**
+ * mqtt鍥炲鏍煎紡鏋勫缓
+ * @param {string} serialNo - 搴忓垪鍙�
+ * @param {any} data - 鍥炲鏁版嵁
+ * @param {string} code - 閿欒浠g爜
+ * @returns {object} 鍥炲鏍煎紡瀵硅薄
+ */
+function mqttReply(serialNo, data, code) {
+ // 鐢熸垚褰撳墠鏃堕棿鐨勫瓧绗︿覆鏍煎紡
+ const now = new Date();
+ const year = now.getFullYear();
+ const month = String(now.getMonth() + 1).padStart(2, '0');
+ const day = String(now.getDate()).padStart(2, '0');
+ const hours = String(now.getHours()).padStart(2, '0');
+ const minutes = String(now.getMinutes()).padStart(2, '0');
+ const seconds = String(now.getSeconds()).padStart(2, '0');
+ const timeString = `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
+
+ return {
+ serialNo: serialNo,
+ uuid: config.get("sys.uuid"),
+ sign: '',
+ code: code,
+ data: data,
+ time: timeString
+ }
+}
+mqttService.mqttReply = mqttReply
+
+/**
+ * 鑾峰彇鎵�鏈夎闃呯殑topic
+ * @returns {array} 璁㈤槄鐨則opic鍒楄〃
+ */
+mqttService.getTopics = function () {
+ // 鑾峰彇鎵�鏈夎闃呯殑topic
+ let sn = config.get("mqtt.clientId")
+ const topics = [
+ "control", "getConfig", "setConfig", "upgradeFirmware", "test",
+ "getPermission", "insertPermission", "delPermission", "clearPermission",
+ "getKey", "insertKey", "delKey", "clearKey",
+ "getUser", "insertUser", "delUser", "clearUser",
+ "getSecurity", "insertSecurity", "delSecurity", "clearSecurity", "getRecords", "delRecords",
+ "insertEmergencyPassword", "delEmergencyPassword", "clearEmergencyPassword", "getEmergencyPassword"
+ ]
+ const eventReplies = ["connect_reply", "alarm_reply", "access_reply", "access_online_reply"]
+
+ let flag = 'access_device/v2/cmd/' + sn + "/"
+ let eventFlag = 'access_device/v2/event/' + sn + "/"
+ return topics.map(item => flag + item).concat(eventReplies.map(item => eventFlag + item));
+}
+
+/**
+ * 鍒ょ┖鍑芥暟
+ * @param {any} value - 瑕佸垽鏂殑鍊�
+ * @returns {boolean} 鏄惁涓虹┖
+ */
+function isEmpty(value) {
+ return value === undefined || value === null || value === ""
+}
+
+export default mqttService
+
+/*
+`mqttService.getTopics()` 鍑芥暟杩斿洖鐨勬墍鏈� topic 濡備笅锛�
+
+### 鍛戒护 topic锛堢敤浜庢帴鏀舵湇鍔″櫒涓嬪彂鐨勫懡浠わ級锛�
+- `access_device/v2/cmd/{sn}/control` - 鎺у埗鍛戒护
+- `access_device/v2/cmd/{sn}/getConfig` - 鑾峰彇閰嶇疆
+- `access_device/v2/cmd/{sn}/setConfig` - 璁剧疆閰嶇疆
+- `access_device/v2/cmd/{sn}/upgradeFirmware` - 鍥轰欢鍗囩骇
+- `access_device/v2/cmd/{sn}/test` - 娴嬭瘯鍛戒护
+- `access_device/v2/cmd/{sn}/getPermission` - 鑾峰彇鏉冮檺
+- `access_device/v2/cmd/{sn}/insertPermission` - 鎻掑叆鏉冮檺
+- `access_device/v2/cmd/{sn}/delPermission` - 鍒犻櫎鏉冮檺
+- `access_device/v2/cmd/{sn}/clearPermission` - 娓呴櫎鏉冮檺
+- `access_device/v2/cmd/{sn}/getKey` - 鑾峰彇瀵嗛挜
+- `access_device/v2/cmd/{sn}/insertKey` - 鎻掑叆瀵嗛挜
+- `access_device/v2/cmd/{sn}/delKey` - 鍒犻櫎瀵嗛挜
+- `access_device/v2/cmd/{sn}/clearKey` - 娓呴櫎瀵嗛挜
+- `access_device/v2/cmd/{sn}/getUser` - 鑾峰彇鐢ㄦ埛
+- `access_device/v2/cmd/{sn}/insertUser` - 鎻掑叆鐢ㄦ埛
+- `access_device/v2/cmd/{sn}/delUser` - 鍒犻櫎鐢ㄦ埛
+- `access_device/v2/cmd/{sn}/clearUser` - 娓呴櫎鐢ㄦ埛
+- `access_device/v2/cmd/{sn}/getSecurity` - 鑾峰彇瀹夊叏淇℃伅
+- `access_device/v2/cmd/{sn}/insertSecurity` - 鎻掑叆瀹夊叏淇℃伅
+- `access_device/v2/cmd/{sn}/delSecurity` - 鍒犻櫎瀹夊叏淇℃伅
+- `access_device/v2/cmd/{sn}/clearSecurity` - 娓呴櫎瀹夊叏淇℃伅
+- `access_device/v2/cmd/{sn}/getRecords` - 鑾峰彇璁板綍
+- `access_device/v2/cmd/{sn}/delRecords` - 鍒犻櫎璁板綍
+
+### 浜嬩欢鍥炲 topic锛堢敤浜庢帴鏀舵湇鍔″櫒瀵逛簨浠剁殑鍥炲锛夛細
+- `access_device/v2/event/{sn}/connect_reply` - 杩炴帴鍥炲
+- `access_device/v2/event/{sn}/alarm_reply` - 鍛婅鍥炲
+- `access_device/v2/event/{sn}/access_reply` - 閫氳鍥炲
+- `access_device/v2/event/{sn}/access_online_reply` - 鍦ㄧ嚎楠岃瘉鍥炲
+
+鍏朵腑 `{sn}` 鏄澶囩殑搴忓垪鍙凤紝浼氳鏇挎崲涓哄疄闄呯殑璁惧搴忓垪鍙枫��
+*/
\ No newline at end of file
diff --git a/vf205_access/src/service/nfcService.js b/vf205_access/src/service/nfcService.js
new file mode 100644
index 0000000..bfb90a4
--- /dev/null
+++ b/vf205_access/src/service/nfcService.js
@@ -0,0 +1,44 @@
+/**
+ * NFC鏈嶅姟妯″潡
+ * 澶勭悊NFC鍗$墖鐩稿叧鐨勪笟鍔¢�昏緫锛屽寘鎷韩浠借瘉鍗″拰浜戣瘉鐨勫鐞�
+ */
+import log from '../../dxmodules/dxLogger.js'
+import dxMap from '../../dxmodules/dxMap.js'
+import accessService from '../service/accessService.js'
+import config from '../../dxmodules/dxConfig.js'
+import driver from '../driver.js';
+
+const nfcService = {}
+
+/**
+ * 鎺ユ敹NFC鍗$墖娑堟伅骞跺鐞�
+ * @param {object} data - NFC鍗$墖鏁版嵁
+ * @param {string} [data.card_type] - 鍗$墖绫诲瀷
+ * @param {string} [data.id] - 韬唤璇佺墿鐞嗗崱鍙�
+ * @param {string} [data.name] - 濮撳悕锛堜簯璇侊級
+ * @param {string} [data.sex] - 鎬у埆锛堜簯璇侊級
+ * @param {string} [data.idCardNo] - 韬唤璇佸彿鐮侊紙浜戣瘉锛�
+ */
+nfcService.receiveMsg = function (data) {
+ // log.info('[nfcService] receiveMsg :' + JSON.stringify(data))
+
+ // 棣栧厛鍒ゆ柇鏄惁鏄韩浠借瘉鍗�
+ if (data.card_type && data.id) {
+ if (dxMap.get("UI").get("getCardStart")) {
+ driver.screen.getCard(data.id)
+ return
+ }
+ // 韬唤璇佺墿鐞嗗崱鍙�/鏅�氬崱
+ accessService.access({ type: "200", code: data.id })
+ } else if (data.name && data.sex && data.idCardNo) {
+ if (dxMap.get("UI").get("getCardStart")) {
+ driver.screen.getCard(data.idCardNo)
+ return
+ }
+ // 浜戣瘉
+ accessService.access({ type: "200", code: data.idCardNo });
+ }
+
+}
+
+export default nfcService
diff --git a/vf205_access/src/service/platService.js b/vf205_access/src/service/platService.js
new file mode 100644
index 0000000..a1e9d22
--- /dev/null
+++ b/vf205_access/src/service/platService.js
@@ -0,0 +1,4 @@
+/**
+ * 骞冲彴鏈嶅姟閫氫俊妯″潡
+ * 澶勭悊骞冲彴鏈嶅姟鐩稿叧鐨勪笟鍔¢�昏緫锛屽寘鎷嚟璇佷笅鍙戝拰浜戣瘉鐨勫鐞�
+ */
\ No newline at end of file
diff --git a/vf205_access/src/service/sqliteService.js b/vf205_access/src/service/sqliteService.js
new file mode 100644
index 0000000..7993751
--- /dev/null
+++ b/vf205_access/src/service/sqliteService.js
@@ -0,0 +1,616 @@
+/**
+ * SQLite鏈嶅姟妯″潡
+ * 鎻愪緵鏁版嵁搴撳垵濮嬪寲銆佽〃缁撴瀯绠$悊銆丣PA椋庢牸鐨勫鍒犳敼鏌ユ柟娉曞拰浜嬪姟绠$悊
+ */
+import log from '../../dxmodules/dxLogger.js'
+import sqlite from '../../dxmodules/dxSqlite.js'
+
+//-------------------------variable-------------------------
+const sqliteService = {}
+//-------------------------public-------------------------
+
+/**
+ * 鍒濆鍖栨暟鎹簱
+ * @param {string} path - 鏁版嵁搴撴枃浠惰矾寰�
+ * @throws {Error} 濡傛灉璺緞涓虹┖鍒欐姏鍑洪敊璇�
+ */
+sqliteService.init = function (path) {
+ if (!path) {
+ throw new Error("path should not be null or empty")
+ }
+ // 鍒涘缓鏁版嵁搴�
+ sqlite.init(path)
+ // 鍒涘缓琛�
+ createTables()
+}
+
+/**
+ * 鏁版嵁搴撹〃缁撴瀯瀹氫箟
+ */
+let entities = {
+ d1_pass_record: {
+ id: "VARCHAR(128) PRIMARY KEY",
+ keyId: "VARCHAR(128)",
+ permissionId: "VARCHAR(128)",
+ permissionId2: "VARCHAR(128)",
+ userId: "VARCHAR(128)",
+ userId2: "VARCHAR(128)",
+ type: "VARCHAR(128)",
+ code: "VARCHAR(128)",
+ door: "VARCHAR(128)",
+ time: "INTEGER",
+ result: "INTEGER",
+ extra: "TEXT",
+ extra2: "TEXT",
+ message: "TEXT",
+ },
+ d1_permission: {
+ permissionId: "VARCHAR(128) PRIMARY KEY",
+ userId: "VARCHAR(128)",
+ door: "VARCHAR(128)",
+ extra: "TEXT",
+ timeType: "INTEGER",
+ beginTime: "INTEGER",
+ endTime: "INTEGER",
+ repeatBeginTime: "INTEGER",
+ repeatEndTime: "INTEGER",
+ period: "TEXT",
+ },
+ d1_security: {
+ securityId: "VARCHAR(128) PRIMARY KEY",
+ type: "VARCHAR(128)",
+ key: "VARCHAR(128)",
+ value: "TEXT",
+ startTime: "INTEGER",
+ endTime: "INTEGER",
+ },
+ d1_voucher: {
+ keyId: "VARCHAR(128) PRIMARY KEY",
+ type: "VARCHAR(128)",
+ code: "TEXT",
+ userId: "VARCHAR(128)",
+ extra: "TEXT",
+ },
+ d1_person: {
+ userId: "VARCHAR(128) PRIMARY KEY",
+ name: "VARCHAR(128)",
+ extra: "TEXT",
+ },
+ d1_emergency_password: {
+ id: "VARCHAR(128) PRIMARY KEY",
+ password: "VARCHAR(128)",
+ description: "VARCHAR(256)",
+ createTime: "INTEGER",
+ updateTime: "INTEGER",
+ status: "INTEGER"
+ }
+}
+
+/**
+ * SQL绫诲瀷杞琂S绫诲瀷
+ * @param {string} sqlType - SQL鏁版嵁绫诲瀷
+ * @returns {string} JavaScript鏁版嵁绫诲瀷
+ */
+let sqlType2jsType = (sqlType) => {
+ if (sqlType.indexOf("INTEGER") > -1) {
+ return 'number'
+ } else {
+ return 'string'
+ }
+}
+
+/**
+ * 鍒涘缓琛ㄧ粨鏋�
+ * @throws {Error} 濡傛灉琛ㄥ垱寤哄け璐ュ垯鎶涘嚭閿欒
+ */
+function createTables() {
+ for (const tableName in entities) {
+ const table = entities[tableName];
+ let sql = `CREATE TABLE IF NOT EXISTS ${tableName} (`
+ for (const column in table) {
+ const type = table[column];
+ sql += ` ${column} ${type},`
+ }
+ sql = sql.slice(0, -1);
+ sql += ")"
+ let ret = sqlite.exec(sql)
+ if (ret != 0) {
+ throw new Error(`table ${tableName} create exception: ${ret}`)
+ }
+ }
+}
+
+/**
+ * 鍒涘缓JPA椋庢牸鐨勪唬鐞嗗鐞嗗櫒
+ */
+let handler = {
+ get: function (target, prop, receiver) {
+ return (...args) => {
+ return createJPA(prop, target.tableName, ...args)
+ }
+ }
+}
+
+// 涓烘瘡涓〃鍒涘缓JPA椋庢牸鐨勫鍒犳敼鏌ユ柟娉�
+sqliteService.d1_pass_record = new Proxy({ tableName: "d1_pass_record" }, handler);
+
+// 娣诲姞鏍规嵁鏃堕棿鑼冨洿鍒犻櫎璁板綍鐨勬柟娉�
+sqliteService.d1_pass_record.deleteByTimeRange = function (startTime, endTime) {
+ try {
+ // 鏋勫缓鏌ヨ鏉′欢
+ let conditions = {};
+ if (startTime) {
+ conditions.time = {
+ $gte: startTime
+ };
+ }
+ if (endTime) {
+ if (!conditions.time) {
+ conditions.time = {};
+ }
+ conditions.time.$lte = endTime;
+ }
+
+ // 浣跨敤JPA椋庢牸鐨刣elete鏂规硶
+ let ret = sqliteService.d1_pass_record.delete(conditions);
+ log.info('[sqliteService] deleteByTimeRange杩斿洖鍊�: ' + ret);
+ return ret;
+ } catch (error) {
+ log.error('deleteByTimeRange error:', error);
+ return -1;
+ }
+};
+sqliteService.d1_permission = new Proxy({ tableName: "d1_permission" }, handler);
+sqliteService.d1_security = new Proxy({ tableName: "d1_security" }, handler);
+sqliteService.d1_voucher = new Proxy({ tableName: "d1_voucher" }, handler);
+sqliteService.d1_person = new Proxy({ tableName: "d1_person" }, handler);
+sqliteService.d1_emergency_password = new Proxy({ tableName: "d1_emergency_password" }, handler);
+
+/**
+ * 寮�濮嬩簨鍔�
+ * 浜嬪姟涓嶆彁浜ゆ暟鎹簱閲嶅惎鍚庯紝鏁版嵁浼氳繕鍘燂紝鎵�浠ransaction鍚庝竴瀹氳commit
+ * 濡傛灉鍦ㄤ竴涓簨鍔″皻鏈彁浜ゆ垨鍥炴粴鐨勬儏鍐典笅鎵ц鍙︿竴涓� BEGIN TRANSACTION锛孲QLite 浼氳嚜鍔ㄥ皢鏂扮殑浜嬪姟宓屽鍦ㄤ箣鍓嶇殑浜嬪姟鍐呴儴锛岃�屼笉鏄鐩栦箣鍓嶇殑浜嬪姟銆�
+ */
+sqliteService.transaction = function () {
+ sqlite.exec("BEGIN TRANSACTION;")
+}
+
+/**
+ * 鍥炴粴浜嬪姟
+ */
+sqliteService.rollback = function () {
+ sqlite.exec("ROLLBACK;")
+}
+
+/**
+ * 鎻愪氦浜嬪姟
+ * 鎻愪氦鍚庢棤娉曞洖婊氾紝鏁版嵁鏃犳硶杩樺師
+ */
+sqliteService.commit = function () {
+ sqlite.exec("COMMIT;")
+}
+
+/**
+ * 鑷姩鍒涘缓jpa甯哥敤澧炲垹鏀规煡sql鏂规硶锛�
+ * 鏀寔鐨勮鍒欙細findByAAndBAndC,findAll,findAllOrderByADescBAsc,deleteByAAndBAndC,deleteAll,deleteInBatch,deleteByIdInBatch,updateAByBAndCAndD,save,saveAll,count,countBy
+ * 鏉′欢鍒嗛〉鏌ヨ锛宔g锛歠indByAAndBAndC(x,x,x,{ page: 0, size: 200, 鍏朵粬鏉′欢, id:"123456" })
+ * 鎵归噺鍒犻櫎锛宔g锛歞eleteInBatch([{ a: 1, b: 2, c: "3" }, { a: 2 }])
+ * 鏉′欢鍒犻櫎锛宔g锛歞eleteAll({ a: 1, b: 2, c: "3" })
+ * 鍗曟潯浠舵壒閲忓垹闄わ紝eg锛歞eleteByIdInBatch([1,2,3,4,5,6])
+ * 鏇村绀轰緥鍙弬鑰冧笅闈㈡祴璇曟柟娉�
+ * @param {string} methodName 鏂规硶鍚�
+ * @param {string} tableName 琛ㄥ悕
+ * @param {...any} nums 鏂规硶鍙傛暟
+ * @returns {any} sqlite鎵ц缁撴灉
+ */
+function createJPA(methodName, tableName, ...nums) {
+ let sql
+ let isFind = false
+ let isCount = false
+ let noPageable = false
+ let hasOrderBy = false
+ if (methodName.startsWith("save")) {
+ // 澧�
+ if (methodName.startsWith("saveAll")) {
+ // 鎵归噺
+ nums = nums[0]
+ sql = `INSERT INTO ${tableName} VALUES `
+ for (let i = 0; i < nums.length; i++) {
+ const record = nums[i];
+ sql += `(`
+ for (const column in entities[tableName]) {
+ const item = record[column];
+ if (sqlType2jsType(entities[tableName][column]) == 'string') {
+ sql += `'${isEmpty(item) ? "" : item}',`
+ } else {
+ sql += `${isEmpty(item) ? 0 : item},`
+ }
+ }
+ sql = sql.slice(0, -1);
+ sql += `)`
+ if (i != nums.length - 1) {
+ sql += `, `
+ }
+ }
+ } else {
+ // 鍗曟潯
+ let record = nums[0]
+ sql = `INSERT INTO ${tableName} VALUES (`
+ for (const column in entities[tableName]) {
+ const item = record[column];
+ if (sqlType2jsType(entities[tableName][column]) == 'string') {
+ sql += `'${isEmpty(item) ? "" : item}',`
+ } else {
+ sql += `${isEmpty(item) ? 0 : item},`
+ }
+ }
+ sql = sql.slice(0, -1);
+ sql += `)`
+ }
+ methodName = ""
+ noPageable = true
+ } else if (methodName.startsWith("delete")) {
+ // 鍒�
+ if (methodName.startsWith("deleteAll")) {
+ // 娓呯┖琛�
+ sql = `DELETE FROM ${tableName} `
+ methodName = ""
+ } else if (methodName.endsWith("InBatch")) {
+ if (nums.length != 1) {
+ log.error("[JPA]:", "缂哄皯鍙傛暟")
+ return
+ }
+ sql = `DELETE FROM ${tableName} WHERE `
+ if (methodName.indexOf("By") > -1) {
+ methodName = methodName.split("By")[1].split("InBatch")[0]
+ sql += `${firstLower(methodName)} IN `
+ let whereClauses = ""
+ for (let i = 0; i < nums[0].length; i++) {
+ const value = nums[0][i];
+ if (typeof value == 'string') {
+ whereClauses += `'${value}'`
+ } else {
+ whereClauses += `${value} `
+ }
+ if (i != nums[0].length - 1) {
+ whereClauses += ","
+ }
+ }
+ sql += `(${whereClauses})`
+ } else {
+ for (let i = 0; i < nums[0].length; i++) {
+ let whereClauses = ""
+ const record = nums[0][i];
+ for (const column in record) {
+ const value = record[column];
+ if (typeof value == 'string') {
+ whereClauses += `${column} = '${value}'`
+ } else {
+ whereClauses += `${column} = ${value}`
+ }
+ whereClauses += ` AND `
+ }
+ whereClauses = whereClauses.slice(0, " AND ".length * (-1))
+ sql += `(${whereClauses})`
+ if (i != nums[0].length - 1) {
+ sql += ` OR `
+ }
+ }
+ }
+ methodName = ""
+ noPageable = true
+ } else {
+ sql = `DELETE FROM ${tableName} `
+ methodName = methodName.substring("delete".length)
+ }
+ } else if (methodName.startsWith("update")) {
+ // 鏀�
+ sql = `UPDATE ${tableName} SET`
+ methodName = methodName.substring("update".length)
+ } else if (methodName.startsWith("find")) {
+ // 鏌�
+ isFind = true
+ sql = `SELECT * FROM ${tableName} `
+ if (methodName.startsWith("findAll")) {
+ methodName = methodName.substring("findAll".length)
+ } else {
+ methodName = methodName.substring("find".length)
+ }
+ let index = methodName.indexOf("OrderBy")
+ if (index > -1) {
+ hasOrderBy = methodName.substring(index + "OrderBy".length).match(/\w+?(Desc|Asc)/g)
+ methodName = methodName.substring(0, index)
+ }
+ } else if (methodName.startsWith("count")) {
+ // 缁熻
+ isFind = true
+ isCount = true
+ sql = `SELECT COUNT(*) FROM ${tableName} `
+ methodName = methodName.substring("count".length)
+ } else {
+ log.error("[JPA]:", "涓嶆敮鎸佺殑鏂规硶")
+ return
+ }
+ // where鏉′欢鏋勫缓
+ let index = methodName.indexOf("By")
+ let whereClauses = ""
+ if (index > -1) {
+ let count = 0
+ let conditionsPart = methodName.substring(index + 2)
+ if (conditionsPart.indexOf("And") > -1) {
+ conditionsPart = conditionsPart.split("And")
+ if (nums.length < conditionsPart.length) {
+ log.error("[JPA]:", "缂哄皯鍙傛暟")
+ return
+ }
+ for (let i = 0; i < conditionsPart.length; i++) {
+ const field = conditionsPart[i];
+ if (typeof nums[i] == 'string') {
+ whereClauses += `${firstLower(field)} = '${nums[i]}'`
+ } else {
+ whereClauses += `${firstLower(field)} = ${nums[i]}`
+ }
+ if (i != conditionsPart.length - 1) {
+ whereClauses += ` AND `
+ }
+ count = i
+ }
+ } else if (conditionsPart.indexOf("Or") > -1) {
+ conditionsPart = conditionsPart.split("Or")
+ if (nums.length < conditionsPart.length) {
+ log.error("[JPA]:", "缂哄皯鍙傛暟")
+ return
+ }
+ for (let i = 0; i < conditionsPart.length; i++) {
+ const field = conditionsPart[i];
+ if (typeof nums[i] == 'string') {
+ whereClauses += `${firstLower(field)} = '${nums[i]}'`
+ } else {
+ whereClauses += `${firstLower(field)} = ${nums[i]}`
+ }
+ if (i != conditionsPart.length - 1) {
+ whereClauses += ` OR `
+ }
+ count = i
+ }
+ } else {
+ if (nums.length < 1) {
+ log.error("[JPA]:", "缂哄皯鍙傛暟")
+ return
+ }
+ if (typeof nums[0] == 'string') {
+ whereClauses = `${firstLower(conditionsPart)} = '${nums[0]}' `
+ } else {
+ whereClauses = `${firstLower(conditionsPart)} = ${nums[0]} `
+ }
+ }
+ count++
+ // update鐨剆et椤规瀯寤�
+ let setClauses = ""
+ let prefix = methodName.substring(0, index);
+ if (prefix.length > 0) {
+ prefix = prefix.split("And")
+ if ((nums.length - count) < prefix.length) {
+ log.error("[JPA]:", "缂哄皯鍙傛暟")
+ return
+ }
+ for (let i = 0; i < prefix.length; i++) {
+ const field = prefix[i];
+ if (typeof nums[i + count] == 'string') {
+ setClauses += `${firstLower(field)} = '${nums[i + count]}',`
+ } else {
+ setClauses += `${firstLower(field)} = ${nums[i + count]},`
+ }
+ }
+ setClauses = setClauses.slice(0, -1)
+ sql += ` ${setClauses} `
+ }
+ sql += `WHERE ${whereClauses} `
+ }
+ // order鎺掑簭
+ let orderByClauses = ""
+ if (hasOrderBy) {
+ orderByClauses = "ORDER BY "
+ let conditionsPart = hasOrderBy
+ for (let i = 0; i < conditionsPart.length; i++) {
+ const orderItem = conditionsPart[i];
+ let isDesc = orderItem.indexOf("Desc")
+ let isAsc = orderItem.indexOf("Asc")
+ if (isDesc > -1) {
+ orderByClauses += `${firstLower(orderItem.substring(0, isDesc))} DESC,`
+ }
+ if (isAsc > -1) {
+ orderByClauses += `${firstLower(orderItem.substring(0, isAsc))} ASC,`
+ }
+ }
+ orderByClauses = orderByClauses.slice(0, -1)
+ }
+ // 鍒ゆ柇鍒嗛〉鏉′欢鏌ヨ
+ let pageable = nums[nums.length - 1]
+ if (typeof pageable == 'object' && !noPageable) {
+ let clauses = ""
+ for (const key in pageable) {
+ const condition = pageable[key];
+ if (key == "page" || key == "size") {
+ continue
+ }
+ if (typeof condition == 'string') {
+ clauses += `${firstLower(key)} = '${condition}'`
+ } else {
+ clauses += `${firstLower(key)} = ${condition}`
+ }
+ clauses += ` AND `
+ }
+ if (clauses.length > 0) {
+ clauses = clauses.slice(0, " AND ".length * (-1))
+ if (sql.indexOf("WHERE") > -1) {
+ sql += `AND ${clauses} `
+ } else {
+ sql += `WHERE ${clauses} `
+ }
+ }
+ sql += `${orderByClauses} `
+ if (isFind && !isCount && !isEmpty(pageable.page) && !isEmpty(pageable.size)) {
+ sql += `LIMIT ${pageable.size} OFFSET ${pageable.page * pageable.size} `
+ }
+ } else {
+ sql += `${orderByClauses} `
+ }
+ sql += `;`;
+ // log.info("[JPA]:", sql)
+ let ret
+ if (isFind) {
+ ret = sqlite.select(sql)
+ if (isCount) {
+ if (ret[0] && ret[0]["COUNT(*)"]) {
+ return ret[0]["COUNT(*)"]
+ } else {
+ return 0
+ }
+ }
+ } else {
+ ret = sqlite.exec(sql)
+ }
+ return ret
+}
+
+/**
+ * 鍒ょ┖鍑芥暟
+ * @param {any} value - 瑕佸垽鏂殑鍊�
+ * @returns {boolean} 鏄惁涓虹┖
+ */
+function isEmpty(value) {
+ return value === undefined || value === null
+}
+
+/**
+ * 棣栧瓧姣嶅皬鍐�
+ * @param {string} str - 瀛楃涓�
+ * @returns {string} 棣栧瓧姣嶅皬鍐欑殑瀛楃涓�
+ */
+function firstLower(str) {
+ return str.charAt(0).toLowerCase() + str.slice(1);
+}
+
+/**
+ * JPA娴嬭瘯鏂规硶
+ * 鎻愪緵鍚勭JPA鏂规硶鐨勪娇鐢ㄧず渚�
+ */
+sqliteService.testJPA = function () {
+ // 鏌ヨ
+ // SELECT * FROM d1_pass_record ;
+ sqliteService.d1_pass_record.find()
+ // SELECT * FROM d1_pass_record WHERE a = 1 AND b = 2 ;
+ sqliteService.d1_pass_record.find({ a: 1, b: 2 })
+ // SELECT * FROM d1_pass_record WHERE a = 1 AND b = 2 ;
+ sqliteService.d1_pass_record.find({ a: 1, b: 2, page: 1 })
+ // SELECT * FROM d1_pass_record WHERE a = 1 AND b = 2 LIMIT 1 OFFSET 1 ;
+ sqliteService.d1_pass_record.find({ a: 1, b: 2, page: 1, size: 1 })
+ // SELECT * FROM d1_pass_record WHERE a = 1 AND b = 2 AND c = 3 ;
+ sqliteService.d1_pass_record.findByAAndBAndC(1, 2, 3)
+ // SELECT * FROM d1_pass_record WHERE a = 1 AND b = 2 AND c = 3 AND a = 1 AND b = 2 ;
+ sqliteService.d1_pass_record.findByAAndBAndC(1, 2, 3, { a: 1, b: 2 })
+ // SELECT * FROM d1_pass_record WHERE a = 1 AND b = 2 AND c = 3 AND a = 1 AND b = 2 LIMIT 1 OFFSET 1 ;
+ sqliteService.d1_pass_record.findByAAndBAndC(1, 2, 3, { a: 1, b: 2, page: 1, size: 1 })
+ // SELECT * FROM d1_pass_record ;
+ sqliteService.d1_pass_record.findAll()
+ // SELECT * FROM d1_pass_record WHERE a = 1 AND b = 2 ;
+ sqliteService.d1_pass_record.findAll({ a: 1, b: 2 })
+ // SELECT * FROM d1_pass_record WHERE a = 1 AND b = 2 ;
+ sqliteService.d1_pass_record.findAll({ a: 1, b: 2, page: 1 })
+ // SELECT * FROM d1_pass_record WHERE a = 1 AND b = 2 LIMIT 1 OFFSET 1 ;
+ sqliteService.d1_pass_record.findAll({ a: 1, b: 2, page: 1, size: 1 })
+ // SELECT * FROM d1_pass_record WHERE a = 1 AND b = 2 AND c = 3 ;
+ sqliteService.d1_pass_record.findAllByAAndBAndC(1, 2, 3)
+ // SELECT * FROM d1_pass_record WHERE a = 1 AND b = 2 AND c = 3 AND a = 1 AND b = 2 ;
+ sqliteService.d1_pass_record.findAllByAAndBAndC(1, 2, 3, { a: 1, b: 2 })
+ // SELECT * FROM d1_pass_record WHERE a = 1 AND b = 2 AND c = 3 AND a = 1 AND b = 2 LIMIT 1 OFFSET 1 ;
+ sqliteService.d1_pass_record.findAllByAAndBAndC(1, 2, 3, { a: 1, b: 2, page: 1, size: 1 })
+ // SELECT * FROM d1_pass_record WHERE a = 1 AND b = 2 AND c = 3 AND a = 1 AND b = 2 ORDER BY a DESC,b ASC,c ASC LIMIT 1 OFFSET 1 ;
+ sqliteService.d1_pass_record.findAllByAAndBAndCOrderByADescBAscCAsc(1, 2, 3, { a: 1, b: 2, page: 1, size: 1 })
+ // 鍒犻櫎
+ // DELETE FROM d1_pass_record ;
+ sqliteService.d1_pass_record.delete()
+ // DELETE FROM d1_pass_record WHERE a = 1 AND b = 2 ;
+ sqliteService.d1_pass_record.delete({ a: 1, b: 2 })
+ // DELETE FROM d1_pass_record WHERE a = 1 AND b = 2 ;
+ sqliteService.d1_pass_record.delete({ a: 1, b: 2, page: 1 })
+ // DELETE FROM d1_pass_record WHERE a = 1 AND b = 2 ;
+ sqliteService.d1_pass_record.delete({ a: 1, b: 2, page: 1, size: 1 })
+ // DELETE FROM d1_pass_record WHERE a = 1 AND b = 2 AND c = 3 ;
+ sqliteService.d1_pass_record.deleteByAAndBAndC(1, 2, 3)
+ // DELETE FROM d1_pass_record WHERE a = 1 AND b = 2 AND c = 3 AND a = 1 AND b = 2 ;
+ sqliteService.d1_pass_record.deleteByAAndBAndC(1, 2, 3, { a: 1, b: 2 })
+ // DELETE FROM d1_pass_record WHERE a = 1 AND b = 2 AND c = 3 AND a = 1 AND b = 2 ;
+ sqliteService.d1_pass_record.deleteByAAndBAndC(1, 2, 3, { a: 1, b: 2, page: 1, size: 1 })
+ // DELETE FROM d1_pass_record ;
+ sqliteService.d1_pass_record.deleteAll()
+ // DELETE FROM d1_pass_record WHERE a = 1 AND b = 2 ;
+ sqliteService.d1_pass_record.deleteAll({ a: 1, b: 2 })
+ // DELETE FROM d1_pass_record WHERE a = 1 AND b = 2 ;
+ sqliteService.d1_pass_record.deleteAll({ a: 1, b: 2, page: 1 })
+ // DELETE FROM d1_pass_record WHERE a = 1 AND b = 2 ;
+ sqliteService.d1_pass_record.deleteAll({ a: 1, b: 2, page: 1, size: 1 })
+ // DELETE FROM d1_pass_record ;
+ sqliteService.d1_pass_record.deleteAllByAAndBAndC(1, 2, 3)
+ // DELETE FROM d1_pass_record WHERE a = 1 AND b = 2 ;
+ sqliteService.d1_pass_record.deleteAllByAAndBAndC(1, 2, 3, { a: 1, b: 2 })
+ // DELETE FROM d1_pass_record WHERE a = 1 AND b = 2 ;
+ sqliteService.d1_pass_record.deleteAllByAAndBAndC(1, 2, 3, { a: 1, b: 2, page: 1, size: 1 })
+ // DELETE FROM d1_pass_record WHERE (a = 1 AND b = 2) OR (a = 1 AND b = 2 AND page = 1) OR (a = 1 AND b = 2 AND page = 1 AND size = 1);
+ sqliteService.d1_pass_record.deleteInBatch([{ a: 1, b: 2 }, { a: 1, b: 2, page: 1 }, { a: 1, b: 2, page: 1, size: 1 }])
+ // DELETE FROM d1_pass_record WHERE id IN (1 ,2 ,3 );
+ sqliteService.d1_pass_record.deleteByIdInBatch([1, 2, 3])
+ // 鏇存柊
+ // UPDATE d1_pass_record SET a = 4 WHERE b = 1 AND c = 2 AND d = 3 ;
+ sqliteService.d1_pass_record.updateAByBAndCAndD(1, 2, 3, 4)
+ // UPDATE d1_pass_record SET a = 4,b = 5,c = 6 WHERE d = 1 AND e = 2 AND f = 3 ;
+ sqliteService.d1_pass_record.updateAAndBAndCByDAndEAndF(1, 2, 3, 4, 5, 6)
+ // 娣诲姞
+ // INSERT INTO d1_pass_record VALUES (,,,,,,,0,0,,);
+ sqliteService.d1_pass_record.save({ a: 1, b: 2 })
+ // INSERT INTO d1_pass_record VALUES (,,,,,,,0,0,,), (,,,,,,,0,0,,);
+ sqliteService.d1_pass_record.saveAll([{ a: 1, b: 2 }, { a: 1, b: 2 }])
+ // 鑱氬悎
+ // SELECT COUNT(*) FROM d1_pass_record ;
+ sqliteService.d1_pass_record.count();
+ // SELECT COUNT(*) FROM d1_pass_record WHERE a = 1 AND b = 2 AND c = 3 ;
+ sqliteService.d1_pass_record.countByAAndBAndC(1, 2, 3);
+}
+
+/**
+ * 瀹夊叏瀵嗛挜鏌ヨ
+ * @param {string} code - 浠g爜
+ * @param {string} type - 绫诲瀷
+ * @param {string} id - 瀹夊叏ID
+ * @param {number} time - 鏃堕棿
+ * @param {string} key - 瀵嗛挜
+ * @param {string} index - 绱㈠紩
+ * @returns {array} 鏌ヨ缁撴灉
+ */
+sqliteService.securityFindAllByCodeAndTypeAndTimeAndkey = function (code, type, id, time, key, index) {
+ var query = `SELECT * FROM d1_security WHERE 1=1`
+ if (code) {
+ query += ` AND code = '${code}'`
+ }
+ if (type) {
+ query += ` AND type = '${type}'`
+ }
+ if (id) {
+ query += ` AND securityId = '${id}'`
+ }
+ if (index) {
+ query += ` AND door = '${index}'`
+ }
+ if (key) {
+ query += ` AND key = '${key}'`
+ }
+ if (time) {
+ query += ` AND endTime >= '${time}'`
+ }
+ return sqlite.select(query)
+}
+
+export default sqliteService
+
+
diff --git a/vf205_access/src/service/uart485Service.js b/vf205_access/src/service/uart485Service.js
new file mode 100644
index 0000000..ade31dc
--- /dev/null
+++ b/vf205_access/src/service/uart485Service.js
@@ -0,0 +1,190 @@
+/**
+ * UART485鏈嶅姟妯″潡
+ * 澶勭悊UART485閫氫俊鐩稿叧鐨勪笟鍔¢�昏緫锛屽寘鎷潯鐮佹暟鎹帴鏀躲�佽澶囬厤缃鐞嗙瓑鍔熻兘
+ */
+import bus from "../../dxmodules/dxEventBus.js"
+import common from "../../dxmodules/dxCommon.js"
+import log from "../../dxmodules/dxLogger.js"
+import std from '../../dxmodules/dxStd.js'
+import driver from '../driver.js'
+import utils from '../common/utils/utils.js'
+import dxMap from '../../dxmodules/dxMap.js'
+import config from '../../dxmodules/dxConfig.js'
+const uart485Service = {}
+
+/**
+ * 灏嗗崄杩涘埗鏁拌浆鎹负灏忕搴忓崄鍏繘鍒跺瓧绗︿覆
+ * @param {number} decimalNumber - 鍗佽繘鍒舵暟瀛�
+ * @param {number} byteSize - 瀛楄妭澶у皬
+ * @returns {string} 灏忕搴忓崄鍏繘鍒跺瓧绗︿覆
+ */
+function decimalToLittleEndianHex (decimalNumber, byteSize) {
+ const littleEndianBytes = [];
+ for (let i = 0; i < byteSize; i++) {
+ littleEndianBytes.push(decimalNumber & 0xFF);
+ decimalNumber >>= 8; // 鐩稿綋浜庨櫎浠�256
+ }
+ const littleEndianHex = littleEndianBytes
+ .map((byte) => byte.toString(16).padStart(2, '0'))
+ .join('');
+ return littleEndianHex;
+}
+
+/**
+ * 灏嗘暟鎹寘杞崲涓哄瓧绗︿覆鏍煎紡
+ * @param {object} pack - 鏁版嵁鍖呭璞�
+ * @param {string} pack.cmd - 鍛戒护鐮�
+ * @param {string} pack.result - 缁撴灉鐮�
+ * @param {string} [pack.data] - 鏁版嵁
+ * @returns {string} 杞崲鍚庣殑瀛楃涓�
+ */
+function pack2str (pack) {
+ pack.data = (!pack.data) ? [] : pack.data.match(/.{2}/g)
+ let len = decimalToLittleEndianHex(pack.data.length, 2)
+ let str = "55aa" + pack.cmd + pack.result + len + pack.data.join('')
+ let crc = common.calculateBcc([0x55, 0xaa, parseInt(pack.cmd, 16), parseInt(pack.result, 16), pack.data.length % 256, pack.data.length / 256].concat(pack.data.map(v => parseInt(v, 16))))
+ return str + crc.toString(16).padStart(2, '0')
+}
+
+/**
+ * 鎺ユ敹UART485鏁版嵁骞跺鐞�
+ * @param {object} data - 鎺ユ敹鍒扮殑鏁版嵁
+ * @param {string} type - 鏁版嵁绫诲瀷锛�'code'琛ㄧず鏉$爜鏁版嵁锛�'instruction'琛ㄧず鎸囦护
+ */
+uart485Service.receive = function (data, type) {
+ log.info("code:",JSON.stringify(data))
+ if (type == 'code') {
+ if(data.cmd == "30") {
+ if(data.length > 0) {
+ let code = common.hexToString(data.data)
+ const now = new Date().getTime()
+ let map = dxMap.get("CODETIME")
+ let time = map.get("time") || 0
+ let interval = Math.max(1000, config.get("sys.interval"))
+ if(now - time > interval) {
+ bus.fire("getCode", code)
+ map.put("time", new Date().getTime())
+ }
+ }
+ }
+ }
+ if (type == 'instruction') {
+ if (data.cmd == "0a") {
+ // 鑾峰彇璁惧SN
+ if (data.length > 0) {
+ console.log('---0A鍐欏叆--');
+
+ let newSn = common.hexToString(data.data)
+ //淇敼 sn 鍙锋敼鎴愪紶鍏ュ弬鏁�
+ try {
+ let wgetApp = common.systemWithRes(`test -e "/etc/.sn" && echo "OK" || echo "NO"`, 2)
+ if (!wgetApp.includes('OK')) {
+ //娌℃湁鍒涘缓涓�涓�
+ common.systemBrief("touch /etc/.sn")
+ }
+ std.saveFile('/etc/.sn', newSn)
+ common.systemWithRes(`rm -rf /app/data/config/config.json`, 2)
+ } catch (error) {
+ log.info('0A鍐欏叆 sn 澶辫触鍘熷洜:', error.stack)
+ let pack1 = { "cmd": '0A', "result": '90', 'data': '' }
+ driver.uart485.sendVg(pack2str(pack1))
+ return
+ }
+ //杩斿洖涓插彛
+ let pack1 = { "cmd": '0A', "result": '00', 'data': common.stringToHex(newSn) }
+ driver.uart485.sendVg(pack2str(pack1))
+ common.asyncReboot(2)
+ } else {
+ log.info('-----0A鏌ヨ-----', common.getSn());
+ let pack1 = { "cmd": '0A', "result": '00', "data": common.stringToHex(common.getSn()) }
+ // log.info(pack2str(pack1));
+ driver.uart485.sendVg(pack2str(pack1))
+ }
+ } else if (data.cmd == "b0") {
+ log.info("----b0---")
+ // 鏌ヨ/淇敼璁惧閰嶇疆
+ let str = data.data
+ if (!str) {
+ return
+ }
+ //鏁版嵁鍩熺涓�涓瓧鑺傝〃绀轰慨鏀硅繕鏄煡璇� 00 鏌ヨ 01 淇敼
+ if (parseInt(str.substring(0, 2)) == 0) {
+ //鏌ヨ閰嶇疆
+ let pack1 = { "cmd": 'B0', "result": '00', "data": common.stringToHex(common.getSn()) }
+ driver.uart485.sendVg(pack2str(pack1))
+ } else {
+ //淇敼閰嶇疆
+ if (data.dlen <= 1) {
+ return
+ }
+ // ___VBAR_CONFIG_V1.1.0___{ble_name="11127S"}--lLqHBRnE2bU8D2HJ5RTioQ==
+ let toString = common.hexToString(str.substring(2))
+ let content = parseString(toString)
+ if (content.sn) {
+ //淇敼 sn 鍙锋敼鎴愪紶鍏ュ弬鏁�
+ try {
+ let wgetApp = common.systemWithRes(`test -e "/etc/.sn" && echo "OK" || echo "NO"`, 2)
+ if (!wgetApp.includes('OK')) {
+ //娌℃湁鍒涘缓涓�涓�
+ common.systemBrief("touch /etc/.sn")
+ }
+ std.saveFile('/etc/.sn', content.sn)
+ common.systemWithRes(`rm -rf /app/data/config/config.json`, 2)
+ } catch (error) {
+ log.info('鍐欏叆/etc/.sn鏂囦欢澶辫触,鍘熷洜:', error.stack)
+ let pack1 = { "cmd": 'B0', "result": '90', "data": common.stringToHex(common.getSn()) }
+ driver.uart485.sendVg(pack2str(pack1))
+ return
+ }
+ //杩斿洖涓插彛
+ let pack1 = { "cmd": 'B0', "result": '00', "data": common.stringToHex(content.sn) }
+ driver.uart485.sendVg(pack2str(pack1))
+ common.asyncReboot(2)
+ }
+
+ }
+ } else if (data.cmd == "0c") {
+ log.info("----0c--")
+ // 鑾峰彇涓绘帶chipID
+ let pack = { "cmd": '0C', "result": '00', "data": common.stringToHex(common.getUuid()) }
+ driver.uart485.sendVg(pack2str(pack))
+ }
+ }
+}
+
+/**
+ * 瑙f瀽瀛楃涓蹭负JSON瀵硅薄锛屾敞鎰弙alue鍐呬笉鑳芥湁"鍙�
+ * @param {string} inputString - 杈撳叆瀛楃涓�
+ * @returns {object} 瑙f瀽鍚庣殑JSON瀵硅薄
+ */
+utils.parseString = function (inputString) {
+ // 鑾峰彇{}鍙婂叾涔嬮棿鐨勫唴瀹�
+ inputString = inputString.slice(inputString.indexOf("{"), inputString.lastIndexOf("}") + 1)
+ // key=value姝e垯锛宬ey鏄痋w+锛堝瓧姣嶆暟瀛椾笅鍒掔嚎锛屽尯鍒ぇ灏忓啓锛夛紝=涓よ竟鍙湁绌烘牸锛寁alue鏄痋w+鎴栫浉閭讳袱涓�"涔嬮棿鐨勫唴瀹癸紙鍖呭惈"锛�
+ const keyValueRegex = /(\w+)\s*=\s*("[^"]*"|\w+)/g;
+ let jsonObject = {};
+ let match;
+ while ((match = keyValueRegex.exec(inputString)) !== null) {
+ let key = match[1];
+ let value = match[2]
+
+ if (/^\d+$/.test(value)) {
+ // 鏁板瓧
+ value = parseInt(value)
+ } else if (/^\d+\.\d+$/.test(value)) {
+ // 灏忔暟
+ value = parseFloat(value)
+ } else if (value == 'true') {
+ value = true
+ } else if (value == 'false') {
+ value = false
+ } else {
+ // 瀛楃涓�
+ value = value.replace(/"/g, '').trim()
+ }
+ jsonObject[key] = value;
+ }
+ return jsonObject;
+}
+
+export default uart485Service
diff --git a/vf205_access/src/services.js b/vf205_access/src/services.js
new file mode 100644
index 0000000..10962f0
--- /dev/null
+++ b/vf205_access/src/services.js
@@ -0,0 +1,109 @@
+/**
+ * 鏈嶅姟姹犻厤缃枃浠�
+ * 娉ㄥ唽绯荤粺涓墍鏈夋湇鍔$殑浜嬩欢澶勭悊鍥炶皟锛屽鐞嗘潵鑷悇妯″潡鐨勪簨浠�
+ */
+import pool from '../dxmodules/dxWorkerPool.js'
+import face from '../dxmodules/dxFace.js'
+import driver from './driver.js'
+import bus from '../dxmodules/dxEventBus.js'
+import faceService from './service/faceService.js'
+import net from '../dxmodules/dxNet.js'
+import config from '../dxmodules/dxConfig.js'
+import nfc from '../dxmodules/dxNfc.js'
+import mqtt from '../dxmodules/dxMqtt.js'
+import map from '../dxmodules/dxMap.js'
+import mqttService from './service/mqttService.js'
+import accessService from './service/accessService.js'
+import nfcService from './service/nfcService.js'
+import common from '../dxmodules/dxCommon.js'
+import log from '../dxmodules/dxLogger.js'
+import dxGpioKey from '../dxmodules/dxGpioKey.js'
+import uart from '../dxmodules/dxUart.js'
+import uart485Service from './service/uart485Service.js'
+import configService from './service/configService.js'
+import grainService from './service/grainService.js'
+import gpiokeyService from './service/gpiokeyService.js'
+import codeService from './service/codeService.js'
+
+/**
+ * 鏈嶅姟姹犲洖璋冨嚱鏁�
+ * 澶勭悊鏉ヨ嚜鍚勬ā鍧楃殑浜嬩欢娑堟伅锛屾牴鎹簨浠朵富棰樺垎鍙戝埌鐩稿簲鐨勬湇鍔″鐞�
+ * @param {object} data - 浜嬩欢鏁版嵁
+ * @param {string} data.topic - 浜嬩欢涓婚
+ * @param {any} data.data - 浜嬩欢鏁版嵁
+ */
+pool.callback((data) => {
+ let topic = data.topic
+ let msg = data.data
+ switch (topic) {
+ case face.RECEIVE_MSG:
+ // 澶勭悊浜鸿劯璇嗗埆娑堟伅
+ faceService.receiveMsg(msg)
+ break;
+ case dxGpioKey.RECEIVE_MSG:
+ // 澶勭悊GPIO鎸夐敭娑堟伅
+ gpiokeyService.receiveMsg(msg)
+ break;
+ case "netGetWifiSsidList":
+ // 鑾峰彇WiFi鍒楄〃
+ let wifiList = driver.net.netGetWifiSsidList()
+ bus.fire("netWifiSsidList", wifiList)
+ break;
+ case "switchNetworkType":
+ // 鍒囨崲缃戠粶绫诲瀷
+ config.setAndSave("net.type", msg)
+ console.log("鍒囨崲缃戠粶", msg);
+ driver.net.changeNetType()
+ break;
+ case "setConfig":
+ // 閰嶇疆楠岃瘉鍜屼繚瀛�
+ configService.configVerifyAndSave(msg)
+ break;
+ case "access":
+ // 澶勭悊閫氳楠岃瘉
+ accessService.access(msg.data, msg.fileName, msg.similarity)
+ break;
+ case nfc.RECEIVE_MSG:
+ // 澶勭悊NFC鍗$墖娑堟伅
+ nfcService.receiveMsg(msg)
+ break;
+ case net.STATUS_CHANGE:
+ // 缃戠粶鐘舵�佸彉鍖�
+ map.get("NET").put("status", msg.status)
+ bus.fire("netStatus", msg)
+ break;
+ case mqtt.CONNECTED_CHANGED:
+ // MQTT杩炴帴鐘舵�佸彉鍖�
+ bus.fire("mqttStatus", msg)
+ // mqtt杩炴帴涓婃姤
+ if (msg == "connected") {
+ mqttService.report()
+ }
+ break;
+ case mqtt.RECEIVE_MSG:
+ // 澶勭悊MQTT娑堟伅
+ mqttService.receiveMsg(msg)
+ break;
+ case uart.VG.RECEIVE_MSG + driver.uart485.id:
+ // 澶勭悊UART485鎸囦护娑堟伅
+ uart485Service.receive(msg, 'instruction')
+ break;
+ case uart.VG.RECEIVE_MSG + driver.uartCode.id:
+ // 澶勭悊UART鐮佹秷鎭�
+ uart485Service.receive(msg, 'code')
+ break;
+ case "getCode":
+ // 澶勭悊鏉$爜鏁版嵁
+ codeService.code(msg)
+ break;
+ case "trackResult":
+ // 澶勭悊浜鸿劯璇嗗埆缁撴灉浜嬩欢锛堢敱mainView.js澶勭悊锛�
+ break;
+
+ default:
+ // 鏈煡涓婚
+ log.error("No such topic ", topic)
+ break;
+ }
+})
+
diff --git a/vf205_access/src/ui.js b/vf205_access/src/ui.js
new file mode 100644
index 0000000..71ba065
--- /dev/null
+++ b/vf205_access/src/ui.js
@@ -0,0 +1,32 @@
+import ui from "../dxmodules/dxUi.js";
+import std from "../dxmodules/dxStd.js"
+
+// ui涓婁笅鏂�
+let context = {}
+
+// ui鍒濆鍖�
+ui.init({ orientation: 0 }, context);
+
+const screenMain = ui.View.build('mainView', ui.Utils.LAYER.MAIN)
+
+const bottomSnBtn = ui.Button.build('bottomSnBtn', screenMain)
+bottomSnBtn.bgColor(0xff0000)
+bottomSnBtn.bgOpa(20)
+bottomSnBtn.setSize(200, 100)
+bottomSnBtn.setPos(100, 700)
+
+
+bottomSnBtn.on(ui.Utils.EVENT.CLICK, () => {
+ print("passwordView")
+})
+
+// 鍔犺浇灞忓箷
+ui.loadMain(screenMain)
+
+// 鍒锋柊ui
+let timer = std.setInterval(() => {
+ if (ui.handler() < 0) {
+ std.clearInterval(timer)
+ }
+}, 1)
+
diff --git a/vf205_access/src/view/appView.js b/vf205_access/src/view/appView.js
new file mode 100644
index 0000000..7aa7be4
--- /dev/null
+++ b/vf205_access/src/view/appView.js
@@ -0,0 +1,47 @@
+import dxui from '../../dxmodules/dxUi.js'
+import std from '../../dxmodules/dxStd.js'
+import viewUtils from "./viewUtils.js"
+import topView from './topView.js'
+import mainView from './mainView.js'
+import i18n from './i18n.js'
+const appView = {}
+appView.init = function () {
+ /**************************************************鍒涘缓灞忓箷*****************************************************/
+ const screenMain = dxui.View.build('appView', dxui.Utils.LAYER.MAIN)
+ appView.screenMain = screenMain
+ screenMain.scroll(false)
+ screenMain.bgColor(0xffffff)
+ screenMain.on(dxui.Utils.ENUM.LV_EVENT_SCREEN_LOADED, () => {
+ topView.changeTheme(true)
+ appQrcode.source('/app/code/resource/image/app_qrcode.png')
+ // 鏃犳搷浣�10绉掕嚜鍔ㄨ繑鍥�
+ if (appView.timer) {
+ std.clearInterval(appView.timer)
+ }
+ appView.timer = std.setInterval(() => {
+ let count = dxui.Utils.GG.NativeDisp.lvDispGetInactiveTime()
+ if (count > 10 * 1000) {
+ std.clearInterval(appView.timer)
+ appView.timer = null
+ dxui.loadMain(mainView.screenMain)
+ }
+ }, 1000)
+ })
+
+ const appQrcode = dxui.Image.build('appQrcode', screenMain)
+ appQrcode.source('/app/code/resource/image/app_qrcode.png')
+ appQrcode.align(dxui.Utils.ALIGN.TOP_MID, 0, 206)
+
+ const knowedBtn = viewUtils.bottomBtn(screenMain, 'knowedBtn', 'appView.knowed', () => {
+ dxui.loadMain(mainView.screenMain)
+ })
+ knowedBtn.align(dxui.Utils.ALIGN.BOTTOM_MID, 0, -124)
+
+ const appQrcodeLbl = dxui.Label.build('appQrcodeLbl', screenMain)
+ appQrcodeLbl.text('浣跨敤灏忕▼搴忎究鎹风鐞�')
+ appQrcodeLbl.textFont(viewUtils.font(30))
+ appQrcodeLbl.align(dxui.Utils.ALIGN.BOTTOM_MID, 0, -403)
+ appQrcodeLbl.dataI18n = 'appView.appQrcodeLbl'
+}
+
+export default appView
\ No newline at end of file
diff --git a/vf205_access/src/view/config/configView.js b/vf205_access/src/view/config/configView.js
new file mode 100644
index 0000000..0a01162
--- /dev/null
+++ b/vf205_access/src/view/config/configView.js
@@ -0,0 +1,136 @@
+import dxui from "../../../dxmodules/dxUi.js"
+import config from "../../../dxmodules/dxConfig.js"
+import viewUtils from "../viewUtils.js"
+import topView from "../topView.js"
+import mainView from "../mainView.js"
+import cloudCertView from "./menu/cloudCertView.js"
+import doorControlView from "./menu/doorControlView.js"
+import helpView from "./menu/helpView.js"
+import networkSettingView from "./menu/networkSettingView.js"
+import systemSettingView from "./menu/systemSettingView.js"
+import deviceInfoView from "./menu/deviceInfoView.js"
+import factoryTestView from "./menu/factoryTestView.js"
+import localUserView from "./menu/localUserView.js"
+import recordQueryView from "./menu/recordQueryView.js"
+import voiceBroadcastView from "./menu/voiceBroadcastView.js"
+
+import screen from '../../screen.js'
+const configView = {}
+configView.init = function () {
+ /**************************************************鍒涘缓灞忓箷*****************************************************/
+ const screenMain = dxui.View.build('configView', dxui.Utils.LAYER.MAIN)
+ configView.screenMain = screenMain
+ screenMain.scroll(false)
+ screenMain.bgColor(0xffffff)
+ screenMain.on(dxui.Utils.ENUM.LV_EVENT_SCREEN_LOADED, () => {
+ topView.changeTheme(true)
+ })
+
+ // const confirm = viewUtils.confirmWin('configViewConfirm', 'configView.confirmExit', () => {
+ // dxui.loadMain(mainView.screenMain)
+ // })
+
+ const titleBox = viewUtils.title(screenMain, undefined, 'configViewTitle', 'configView.title', () => {
+ viewUtils.confirmOpen('configView.confirmExit', 'configView.confirmExitContent', () => {
+ dxui.loadMain(mainView.screenMain)
+ }, () => { })
+ })
+ titleBox.align(dxui.Utils.ALIGN.TOP_MID, 0, 70)
+
+
+ const menuBox = dxui.View.build('menuBox', screenMain)
+ viewUtils._clearStyle(menuBox)
+ menuBox.setSize(screen.screenSize.width, 800)
+ menuBox.bgOpa(0)
+ menuBox.align(dxui.Utils.ALIGN.TOP_MID, 0, 178)
+ menuBox.flexFlow(dxui.Utils.FLEX_FLOW.ROW_WRAP)
+ menuBox.flexAlign(dxui.Utils.FLEX_ALIGN.START, dxui.Utils.FLEX_ALIGN.START, dxui.Utils.FLEX_ALIGN.START)
+ menuBox.obj.lvObjSetStylePadGap(0, dxui.Utils.ENUM._LV_STYLE_STATE_CMP_SAME)
+
+ configView.menuBtn('localUser', menuBox, screen.screenSize.width / 4, screen.screenSize.width / 4, '/app/code/resource/image/localUser.png', 'configView.localUser', () => {
+ dxui.loadMain(localUserView.screenMain)
+ })
+
+ configView.menuBtn('networkSetting', menuBox, screen.screenSize.width / 4, screen.screenSize.width / 4, '/app/code/resource/image/networkSetting.png', 'configView.networkSetting', () => {
+ dxui.loadMain(networkSettingView.screenMain)
+ })
+
+ configView.menuBtn('doorControl', menuBox, screen.screenSize.width / 4, screen.screenSize.width / 4, '/app/code/resource/image/doorControl.png', 'configView.doorControl', () => {
+ dxui.loadMain(doorControlView.screenMain)
+ })
+
+ configView.menuBtn('systemSetting', menuBox, screen.screenSize.width / 4, screen.screenSize.width / 4, '/app/code/resource/image/systemSetting.png', 'configView.systemSetting', () => {
+ dxui.loadMain(systemSettingView.screenMain)
+ })
+
+ configView.menuBtn('deviceInfo', menuBox, screen.screenSize.width / 4, screen.screenSize.width / 4, '/app/code/resource/image/deviceInfo.png', 'configView.deviceInfo', () => {
+ dxui.loadMain(deviceInfoView.screenMain)
+ })
+
+ configView.menuBtn('recordQuery', menuBox, screen.screenSize.width / 4, screen.screenSize.width / 4, '/app/code/resource/image/recordQuery.png', 'configView.recordQuery', () => {
+ dxui.loadMain(recordQueryView.screenMain)
+ })
+
+ configView.menuBtn('voiceBroadcast', menuBox, screen.screenSize.width / 4, screen.screenSize.width / 4, '/app/code/resource/image/voiceBroadcast.png', 'configView.voiceBroadcast', () => {
+ dxui.loadMain(voiceBroadcastView.screenMain)
+ })
+
+ if (config.get("base.showIdentityCard") == 1) {
+ configView.menuBtn('cloudCert', menuBox, screen.screenSize.width / 4, screen.screenSize.width / 4, '/app/code/resource/image/cloudCert.png', 'configView.cloudCert', () => {
+ dxui.loadMain(cloudCertView.screenMain)
+ })
+ }
+
+
+
+ configView.menuBtn('help', menuBox, screen.screenSize.width / 4, screen.screenSize.width / 4, '/app/code/resource/image/help.png', 'configView.help', () => {
+ dxui.loadMain(helpView.screenMain)
+ })
+}
+
+configView.menuBtn = function (id, parent, width, height, src, dataI18n, callback = () => { }) {
+ const box = dxui.View.build(id, parent)
+ viewUtils._clearStyle(box)
+ box.setSize(width, height)
+ box.bgOpa(0)
+
+ const zoom = 1.02
+
+ const bg = dxui.View.build(id + 'bg', box)
+ viewUtils._clearStyle(bg)
+ bg.setSize(140, 140)
+ bg.bgColor(0xf6f6f6)
+ bg.radius(30)
+ bg.align(dxui.Utils.ALIGN.TOP_MID, 0, 10)
+
+ const image = dxui.Image.build(id + 'image', bg)
+ image.source(src)
+ image.align(dxui.Utils.ALIGN.CENTER, 0, 0)
+
+ bg.on(dxui.Utils.ENUM.LV_EVENT_PRESSED, () => {
+ bg.setSize(140 * zoom, 140 * zoom)
+ image.obj.lvImgSetZoom(256 * zoom)
+ })
+ bg.on(dxui.Utils.ENUM.LV_EVENT_RELEASED, () => {
+ bg.setSize(140, 140)
+ image.obj.lvImgSetZoom(256)
+ })
+
+ bg.on(dxui.Utils.EVENT.CLICK, () => {
+ callback()
+ })
+
+ const textLbl = dxui.Label.build(id + 'text', box)
+ textLbl.textFont(viewUtils.font(22))
+ textLbl.textColor(0x767676)
+ textLbl.dataI18n = dataI18n
+ textLbl.align(dxui.Utils.ALIGN.BOTTOM_MID, 0, -10)
+ textLbl.width(width)
+ textLbl.textAlign(dxui.Utils.TEXT_ALIGN.CENTER)
+ textLbl.longMode(dxui.Utils.LABEL_LONG_MODE.SCROLL_CIRCULAR)
+
+
+}
+
+
+export default configView
diff --git a/vf205_access/src/view/config/identityVerificationView.js b/vf205_access/src/view/config/identityVerificationView.js
new file mode 100644
index 0000000..417263d
--- /dev/null
+++ b/vf205_access/src/view/config/identityVerificationView.js
@@ -0,0 +1,185 @@
+import dxui from '../../../dxmodules/dxUi.js'
+import std from '../../../dxmodules/dxStd.js'
+import viewUtils from "../viewUtils.js"
+import topView from '../topView.js'
+import mainView from '../mainView.js'
+import configView from './configView.js'
+import i18n from '../i18n.js'
+import screen from '../../screen.js'
+const identityVerificationView = {}
+identityVerificationView.init = function () {
+ /**************************************************鍒涘缓灞忓箷*****************************************************/
+ const screenMain = dxui.View.build('identityVerificationView', dxui.Utils.LAYER.MAIN)
+ identityVerificationView.screenMain = screenMain
+ screenMain.scroll(false)
+ screenMain.bgColor(0xffffff)
+ screenMain.on(dxui.Utils.ENUM.LV_EVENT_SCREEN_LOADED, () => {
+ topView.changeTheme(true)
+ toggleTab(0)
+
+ // 鏃犳搷浣�15绉掕嚜鍔ㄨ繑鍥�
+ if (identityVerificationView.timer) {
+ std.clearInterval(identityVerificationView.timer)
+ }
+ identityVerificationView.timer = std.setInterval(() => {
+ let count = dxui.Utils.GG.NativeDisp.lvDispGetInactiveTime()
+ if (count > 15 * 1000) {
+ std.clearInterval(identityVerificationView.timer)
+ identityVerificationView.timer = null
+ dxui.loadMain(mainView.screenMain)
+ }
+ }, 1000)
+ })
+
+ screenMain.on(dxui.Utils.ENUM.LV_EVENT_SCREEN_UNLOADED, () => {
+ // 浜鸿劯璁よ瘉缁撴潫
+ if (identityVerificationView.timer) {
+ std.clearInterval(identityVerificationView.timer)
+ }
+ if (!faceRec.isHide()) {
+ screen.faceAuthEnd()
+ }
+ })
+
+ const titleBoxBg = dxui.View.build('titleBoxBg', screenMain)
+ viewUtils._clearStyle(titleBoxBg)
+ titleBoxBg.setSize(screen.screenSize.width, 70)
+ titleBoxBg.align(dxui.Utils.ALIGN.TOP_MID, 0, 0)
+ titleBoxBg.bgColor(0xffffff)
+
+ const titleBox = viewUtils.title(screenMain, mainView.screenMain, 'identityVerificationViewTitle', 'identityVerificationView.title')
+ titleBox.align(dxui.Utils.ALIGN.TOP_MID, 0, 70)
+
+ const tab = dxui.View.build('tab', screenMain)
+ viewUtils._clearStyle(tab)
+ tab.setSize(screen.screenSize.width, 80)
+ tab.alignTo(titleBox, dxui.Utils.ALIGN.OUT_BOTTOM_MID, 0, 0)
+ tab.flexFlow(dxui.Utils.FLEX_FLOW.ROW)
+ tab.flexAlign(dxui.Utils.FLEX_ALIGN.SPACE_AROUND, dxui.Utils.FLEX_ALIGN.CENTER, dxui.Utils.FLEX_ALIGN.CENTER)
+
+ const pwdLogBox = dxui.View.build('pwdLogBox', tab)
+ viewUtils._clearStyle(pwdLogBox)
+ const pwdLogLbl = dxui.Label.build('pwdLogLbl', pwdLogBox)
+ pwdLogLbl.textFont(viewUtils.font(28))
+ pwdLogLbl.textColor(0x888888)
+ pwdLogLbl.text('瀵嗙爜鐧诲綍')
+ pwdLogLbl.dataI18n = 'identityVerificationView.pwdLog'
+ const pwdLogText = pwdLogLbl.text
+ pwdLogLbl.text = (data) => {
+ pwdLogText.call(pwdLogLbl, data)
+ pwdLogLbl.update()
+ pwdLogBox.setSize(pwdLogLbl.width() + 8, 80)
+ }
+ pwdLogLbl.align(dxui.Utils.ALIGN.CENTER, 0, 0)
+ pwdLogLbl.update()
+ pwdLogBox.setSize(pwdLogLbl.width() + 8, 80)
+ pwdLogBox.borderWidth(4)
+ pwdLogBox.obj.setStyleBorderSide(dxui.Utils.ENUM.LV_BORDER_SIDE_BOTTOM, 0)
+ pwdLogBox.setBorderColor(0x0836C)
+ pwdLogBox.on(dxui.Utils.EVENT.CLICK, () => {
+ toggleTab(0)
+ })
+
+ const faceLogBox = dxui.View.build('faceLogBox', tab)
+ viewUtils._clearStyle(faceLogBox)
+ const faceLogLbl = dxui.Label.build('faceLogLbl', faceLogBox)
+ faceLogLbl.textFont(viewUtils.font(28))
+ faceLogLbl.textColor(0x888888)
+ faceLogLbl.text('浜鸿劯鐧诲綍')
+ faceLogLbl.dataI18n = 'identityVerificationView.faceLog'
+ const faceLogText = faceLogLbl.text
+ faceLogLbl.text = (data) => {
+ faceLogText.call(faceLogLbl, data)
+ faceLogLbl.update()
+ faceLogBox.setSize(faceLogLbl.width() + 8, 80)
+ }
+ faceLogLbl.align(dxui.Utils.ALIGN.CENTER, 0, 0)
+ faceLogLbl.update()
+ faceLogBox.setSize(faceLogLbl.width() + 8, 80)
+ faceLogBox.borderWidth(4)
+ faceLogBox.obj.setStyleBorderSide(dxui.Utils.ENUM.LV_BORDER_SIDE_BOTTOM, 0)
+ faceLogBox.setBorderColor(0x0836C)
+ faceLogBox.on(dxui.Utils.EVENT.CLICK, () => {
+ toggleTab(1)
+ })
+
+ const pwdInput = viewUtils.input(screenMain, screenMain.id + 'pwdInput', undefined, undefined, 'identityVerificationView.pwd')
+ pwdInput.align(dxui.Utils.ALIGN.TOP_MID, 0, 263)
+ pwdInput.setPasswordMode(true)
+
+ const eyeFill = viewUtils.imageBtn(screenMain, screenMain.id + 'eye_fill', '/app/code/resource/image/eye-fill.png')
+ eyeFill.alignTo(pwdInput, dxui.Utils.ALIGN.RIGHT_MID, 0, 0)
+ eyeFill.on(dxui.Utils.EVENT.CLICK, () => {
+ pwdInput.setPasswordMode(true)
+ eyeFill.hide()
+ eyeOff.show()
+ })
+ eyeFill.hide()
+
+ const eyeOff = viewUtils.imageBtn(screenMain, screenMain.id + 'eye_off', '/app/code/resource/image/eye-off.png')
+ eyeOff.alignTo(pwdInput, dxui.Utils.ALIGN.RIGHT_MID, 0, 0)
+ eyeOff.on(dxui.Utils.EVENT.CLICK, () => {
+ pwdInput.setPasswordMode(false)
+ eyeFill.show()
+ eyeOff.hide()
+ })
+
+ const pwdAccessBtn = viewUtils.bottomBtn(screenMain, screenMain.id + 'pwdAccessBtn', 'identityVerificationView.pwdAccess', () => {
+ if (screen.getConfig()['base.password'] === pwdInput.text()) {
+ // 杩涘叆璁剧疆鑿滃崟
+ std.clearInterval(identityVerificationView.timer)
+ dxui.loadMain(configView.screenMain)
+ } else {
+ if (faceRec.isHide()) {
+ // 瀵嗙爜閿欒
+ identityVerificationView.statusPanel.fail('identityVerificationView.pwdFail')
+ } else {
+ // 浜鸿劯璁よ瘉澶辫触
+ identityVerificationView.statusPanel.fail('identityVerificationView.fail')
+ }
+ }
+ })
+ pwdAccessBtn.align(dxui.Utils.ALIGN.BOTTOM_MID, 0, -83)
+
+ const faceRec = dxui.Image.build('faceRec', screenMain)
+ faceRec.source('/app/code/resource/image/faceRec.png')
+ faceRec.alignTo(tab, dxui.Utils.ALIGN.OUT_BOTTOM_MID, 0, 70)
+
+ identityVerificationView.statusPanel = viewUtils.statusPanel(screenMain, 'identityVerificationView.success', 'identityVerificationView.fail')
+
+ function toggleTab(index) {
+ screenMain.send(dxui.Utils.EVENT.CLICK)
+ if (index == 0) {
+ pwdLogLbl.textColor(0x0836C)
+ faceLogLbl.textColor(0x888888)
+ pwdLogBox.setBorderColor(0x0836C)
+ faceLogBox.setBorderColor(0xffffff)
+ pwdInput.show()
+ eyeFill.show()
+ eyeOff.show()
+ pwdAccessBtn.show()
+ screenMain.bgOpa(100)
+ faceRec.hide()
+
+ // 浜鸿劯璁よ瘉缁撴潫
+ screen.faceAuthEnd()
+ } else {
+ pwdLogLbl.textColor(0x888888)
+ faceLogLbl.textColor(0x0836C)
+ pwdLogBox.setBorderColor(0xffffff)
+ faceLogBox.setBorderColor(0x0836C)
+ pwdInput.hide()
+ eyeFill.hide()
+ eyeOff.hide()
+ pwdAccessBtn.hide()
+ screenMain.bgOpa(0)
+ faceRec.show()
+
+ // 浜鸿劯璁よ瘉寮�濮�
+ screen.faceAuthStart()
+ }
+ }
+ toggleTab(0)
+}
+
+export default identityVerificationView
\ No newline at end of file
diff --git a/vf205_access/src/view/config/menu/cloudCertView.js b/vf205_access/src/view/config/menu/cloudCertView.js
new file mode 100644
index 0000000..007f389
--- /dev/null
+++ b/vf205_access/src/view/config/menu/cloudCertView.js
@@ -0,0 +1,42 @@
+import dxui from '../../../../dxmodules/dxUi.js'
+import viewUtils from "../../viewUtils.js"
+import topView from "../../topView.js"
+import configView from '../configView.js'
+const cloudCertView = {}
+cloudCertView.init = function () {
+ /**************************************************鍒涘缓灞忓箷*****************************************************/
+ const screenMain = dxui.View.build('cloudCertView', dxui.Utils.LAYER.MAIN)
+ cloudCertView.screenMain = screenMain
+ screenMain.scroll(false)
+ screenMain.bgColor(0xffffff)
+ screenMain.on(dxui.Utils.ENUM.LV_EVENT_SCREEN_LOADED, () => {
+ topView.changeTheme(true)
+ })
+
+ const titleBox = viewUtils.title(screenMain, configView.screenMain, 'cloudCertViewTitle', 'cloudCertView.cloudCertActive')
+ titleBox.align(dxui.Utils.ALIGN.TOP_MID, 0, 70)
+
+ const inputBox = viewUtils.input(screenMain, 'cloudCertViewInput', undefined, () => {
+ console.log('cloudCertViewInput')
+ }, 'cloudCertView.inputKey')
+ inputBox.align(dxui.Utils.ALIGN.TOP_LEFT, 109, 179)
+ inputBox.width(654)
+
+ const keyLbl = dxui.Label.build('cloudCertViewKey', screenMain)
+ keyLbl.dataI18n = 'cloudCertView.key'
+ keyLbl.textFont(viewUtils.font(26))
+ keyLbl.align(dxui.Utils.ALIGN.TOP_LEFT, 43, 201)
+
+ const tipLbl = dxui.Label.build('cloudCertViewTip', screenMain)
+ tipLbl.dataI18n = 'cloudCertView.tip'
+ tipLbl.textFont(viewUtils.font(22))
+ tipLbl.textColor(0x888888)
+ tipLbl.align(dxui.Utils.ALIGN.TOP_MID, 0, 650)
+
+
+ const saveBtn = viewUtils.bottomBtn(screenMain, screenMain.id + 'saveBtn', 'cloudCertView.save', () => {
+ })
+ saveBtn.align(dxui.Utils.ALIGN.BOTTOM_MID, 0, -83)
+}
+
+export default cloudCertView
diff --git a/vf205_access/src/view/config/menu/deviceInfo/dataCapacityInfoView.js b/vf205_access/src/view/config/menu/deviceInfo/dataCapacityInfoView.js
new file mode 100644
index 0000000..ef90a0b
--- /dev/null
+++ b/vf205_access/src/view/config/menu/deviceInfo/dataCapacityInfoView.js
@@ -0,0 +1,118 @@
+import dxui from '../../../../../dxmodules/dxUi.js'
+import dxCommon from '../../../../../dxmodules/dxCommon.js'
+import viewUtils from "../../../viewUtils.js"
+import topView from "../../../topView.js"
+import deviceInfoView from '../deviceInfoView.js'
+import i18n from "../../../i18n.js"
+import sqliteService from '../../../../service/sqliteService.js'
+import screen from '../../../../screen.js'
+const dataCapacityInfoView = {}
+dataCapacityInfoView.init = function () {
+ /**************************************************鍒涘缓灞忓箷*****************************************************/
+ const screenMain = dxui.View.build('dataCapacityInfoView', dxui.Utils.LAYER.MAIN)
+ dataCapacityInfoView.screenMain = screenMain
+ screenMain.scroll(false)
+ screenMain.bgColor(0xffffff)
+ screenMain.on(dxui.Utils.ENUM.LV_EVENT_SCREEN_LOADED, () => {
+ topView.changeTheme(true)
+
+ dataCapacityInfoView.info[0].label.text(Math.floor(dxCommon.getTotaldisk() / 1024 / 1024) + ' M')
+ dataCapacityInfoView.info[1].label.text(Math.floor((dxCommon.getTotaldisk() - dxCommon.getFreedisk()) / 1024 / 1024) + ' M')
+ dataCapacityInfoView.info[2].label.text(Math.floor(dxCommon.getFreedisk() / 1024 / 1024) + ' M')
+ dataCapacityInfoView.info[3].label.text(sqliteService.d1_person.count() + '')
+ dataCapacityInfoView.info[4].label.text(sqliteService.d1_voucher.countByType(300) + '')
+ dataCapacityInfoView.info[5].label.text(sqliteService.d1_voucher.countByType(400) + '')
+ dataCapacityInfoView.info[6].label.text(sqliteService.d1_voucher.countByType(200) + '')
+ dataCapacityInfoView.info[7].label.text(sqliteService.d1_pass_record.count() + '')
+ })
+
+ const titleBox = viewUtils.title(screenMain, deviceInfoView.screenMain, 'dataCapacityInfoViewTitle', 'deviceInfoView.dataCapacityInfo')
+ titleBox.align(dxui.Utils.ALIGN.TOP_MID, 0, 70)
+
+ dataCapacityInfoView.info = [
+ {
+ title: "deviceInfoView.deviceTotalSpace",
+ type: 'label',
+ value: '5918 M',
+ },
+ {
+ title: "deviceInfoView.deviceUsedSpace",
+ type: 'label',
+ value: '344 M',
+ },
+ // {
+ // title: "deviceInfoView.deviceFreeSpace",
+ // type: 'label',
+ // value: '5574 M',
+ // },
+ {
+ title: "deviceInfoView.deviceRemainingSpace",
+ type: 'label',
+ value: '3',
+ },
+ {
+ title: "deviceInfoView.registeredPersonNum",
+ type: 'label',
+ value: '3',
+ },
+ {
+ title: "deviceInfoView.localFaceWhiteListNum",
+ type: 'label',
+ value: '3',
+ },
+ {
+ title: "deviceInfoView.localPasswordWhiteListNum",
+ type: 'label',
+ value: '3',
+ },
+ {
+ title: "deviceInfoView.localSwipeCardWhiteListNum",
+ type: 'label',
+ value: '3',
+ },
+ {
+ title: "deviceInfoView.passLogTotalNum",
+ type: 'label',
+ value: '3',
+ }
+ ]
+
+ const dataCapacityInfoBox = dxui.View.build('dataCapacityInfoBox', screenMain)
+ viewUtils._clearStyle(dataCapacityInfoBox)
+ dataCapacityInfoBox.align(dxui.Utils.ALIGN.TOP_MID, 0, 140)
+ dataCapacityInfoBox.setSize(screen.screenSize.width, 700)
+ dataCapacityInfoBox.bgOpa(0)
+ dataCapacityInfoBox.flexFlow(dxui.Utils.FLEX_FLOW.ROW_WRAP)
+ dataCapacityInfoBox.flexAlign(dxui.Utils.FLEX_ALIGN.CENTER, dxui.Utils.FLEX_ALIGN.START, dxui.Utils.FLEX_ALIGN.START)
+ dataCapacityInfoBox.obj.lvObjSetStylePadGap(0, dxui.Utils.ENUM._LV_STYLE_STATE_CMP_SAME)
+ dataCapacityInfoBox.borderWidth(1)
+ dataCapacityInfoBox.setBorderColor(0xDEDEDE)
+ dataCapacityInfoBox.obj.setStyleBorderSide(dxui.Utils.ENUM.LV_BORDER_SIDE_TOP, 0)
+
+ dataCapacityInfoView.info.forEach(item => {
+ const itemBox = dxui.View.build(item.title, dataCapacityInfoBox)
+ viewUtils._clearStyle(itemBox)
+ itemBox.setSize(760, 76)
+ itemBox.borderWidth(1)
+ itemBox.setBorderColor(0xDEDEDE)
+ itemBox.obj.setStyleBorderSide(dxui.Utils.ENUM.LV_BORDER_SIDE_BOTTOM, 0)
+
+ const itemLabel = dxui.Label.build(item.title + 'Label', itemBox)
+ itemLabel.dataI18n = item.title
+ itemLabel.align(dxui.Utils.ALIGN.LEFT_MID, 0, 0)
+ itemLabel.textFont(viewUtils.font(26))
+
+ switch (item.type) {
+ case 'label':
+ const label = dxui.Label.build(item.title + 'label', itemBox)
+ label.textFont(viewUtils.font(24))
+ label.align(dxui.Utils.ALIGN.RIGHT_MID, 0, 0)
+ label.text(item.value)
+ label.textColor(0x767676)
+ item.label = label
+ break;
+ }
+ })
+}
+
+export default dataCapacityInfoView
diff --git a/vf205_access/src/view/config/menu/deviceInfo/systemInfoView.js b/vf205_access/src/view/config/menu/deviceInfo/systemInfoView.js
new file mode 100644
index 0000000..f70e9a0
--- /dev/null
+++ b/vf205_access/src/view/config/menu/deviceInfo/systemInfoView.js
@@ -0,0 +1,94 @@
+import dxui from '../../../../../dxmodules/dxUi.js'
+import viewUtils from "../../../viewUtils.js"
+import topView from "../../../topView.js"
+import deviceInfoView from '../deviceInfoView.js'
+import i18n from "../../../i18n.js"
+import screen from '../../../../screen.js'
+const systemInfoView = {}
+systemInfoView.init = function () {
+ /**************************************************鍒涘缓灞忓箷*****************************************************/
+ const screenMain = dxui.View.build('systemInfoView', dxui.Utils.LAYER.MAIN)
+ systemInfoView.screenMain = screenMain
+ screenMain.scroll(false)
+ screenMain.bgColor(0xffffff)
+ screenMain.on(dxui.Utils.ENUM.LV_EVENT_SCREEN_LOADED, () => {
+ topView.changeTheme(true)
+ const config = screen.getConfig()
+ systemInfoView.info[0].label.text(config["sys.sn"])
+ systemInfoView.info[1].label.text(config["sys.appVersion"])
+ systemInfoView.info[2].label.text(config["sys.releaseTime"])
+ })
+
+ const titleBox = viewUtils.title(screenMain, deviceInfoView.screenMain, 'systemInfoViewTitle', 'deviceInfoView.systemInfo')
+ titleBox.align(dxui.Utils.ALIGN.TOP_MID, 0, 70)
+
+ systemInfoView.info = [
+ {
+ title: "deviceInfoView.deviceSN",
+ type: 'label',
+ value: 'G2440288881',
+ },
+ {
+ title: "deviceInfoView.firmwareVersion",
+ type: 'label',
+ value: 'VF203-v1.1.36.3a885-240611',
+ },
+ {
+ title: "deviceInfoView.firmwareReleaseDate",
+ type: 'label',
+ value: '2024-06-11 18:00:00',
+ },
+ ]
+
+ const settingInfoBox = dxui.View.build('settingInfoBox', screenMain)
+ viewUtils._clearStyle(settingInfoBox)
+ settingInfoBox.align(dxui.Utils.ALIGN.TOP_MID, 0, 140)
+ settingInfoBox.setSize(screen.screenSize.width, 700)
+ settingInfoBox.bgOpa(0)
+ settingInfoBox.flexFlow(dxui.Utils.FLEX_FLOW.ROW_WRAP)
+ settingInfoBox.flexAlign(dxui.Utils.FLEX_ALIGN.CENTER, dxui.Utils.FLEX_ALIGN.START, dxui.Utils.FLEX_ALIGN.START)
+ settingInfoBox.obj.lvObjSetStylePadGap(0, dxui.Utils.ENUM._LV_STYLE_STATE_CMP_SAME)
+ settingInfoBox.borderWidth(1)
+ settingInfoBox.setBorderColor(0xDEDEDE)
+ settingInfoBox.obj.setStyleBorderSide(dxui.Utils.ENUM.LV_BORDER_SIDE_TOP, 0)
+
+ systemInfoView.info.forEach(item => {
+ const itemBox = dxui.View.build(item.title, settingInfoBox)
+ viewUtils._clearStyle(itemBox)
+ itemBox.setSize(760, 76)
+ itemBox.borderWidth(1)
+ itemBox.setBorderColor(0xDEDEDE)
+ itemBox.obj.setStyleBorderSide(dxui.Utils.ENUM.LV_BORDER_SIDE_BOTTOM, 0)
+
+ const itemLabel = dxui.Label.build(item.title + 'Label', itemBox)
+ itemLabel.dataI18n = item.title
+ itemLabel.align(dxui.Utils.ALIGN.LEFT_MID, 0, 0)
+ itemLabel.textFont(viewUtils.font(26))
+
+ switch (item.type) {
+ case 'label':
+ const label = dxui.Label.build(item.title + 'label', itemBox)
+ label.textFont(viewUtils.font(24))
+ label.align(dxui.Utils.ALIGN.RIGHT_MID, 0, 0)
+ label.text(item.value)
+ label.textColor(0x767676)
+ item.label = label
+ break;
+ }
+ })
+
+ const currentVersion = dxui.Label.build('deviceInfoView.currentVersion', screenMain)
+ currentVersion.align(dxui.Utils.ALIGN.BOTTOM_MID, 0, -213)
+ currentVersion.textFont(viewUtils.font(22))
+ currentVersion.textColor(0x888888)
+ currentVersion.dataI18n = 'deviceInfoView.currentVersion'
+ currentVersion.textAlign(dxui.Utils.TEXT_ALIGN.CENTER, 0, 0)
+ currentVersion.hide()
+
+ const saveBtn = viewUtils.bottomBtn(screenMain, screenMain.id + 'saveBtn', 'deviceInfoView.updateDevice', () => {
+ })
+ saveBtn.align(dxui.Utils.ALIGN.BOTTOM_MID, 0, -83)
+ saveBtn.hide()
+}
+
+export default systemInfoView
diff --git a/vf205_access/src/view/config/menu/deviceInfoView.js b/vf205_access/src/view/config/menu/deviceInfoView.js
new file mode 100644
index 0000000..cfe5b67
--- /dev/null
+++ b/vf205_access/src/view/config/menu/deviceInfoView.js
@@ -0,0 +1,110 @@
+import dxui from '../../../../dxmodules/dxUi.js'
+import viewUtils from "../../viewUtils.js"
+import topView from "../../topView.js"
+import configView from '../configView.js'
+import systemInfoView from './deviceInfo/systemInfoView.js'
+import dataCapacityInfoView from './deviceInfo/dataCapacityInfoView.js'
+import i18n from "../../i18n.js"
+import screen from '../../../screen.js'
+
+const deviceInfoView = {}
+deviceInfoView.init = function () {
+ /**************************************************鍒涘缓灞忓箷*****************************************************/
+ const screenMain = dxui.View.build('deviceInfoView', dxui.Utils.LAYER.MAIN)
+ deviceInfoView.screenMain = screenMain
+ screenMain.scroll(false)
+ screenMain.bgColor(0xffffff)
+ screenMain.on(dxui.Utils.ENUM.LV_EVENT_SCREEN_LOADED, () => {
+ topView.changeTheme(true)
+ let config = screen.getConfig()
+ dxui.Utils.GG.NativeBasicComponent.lvQrcodeUpdate(deviceInfoView.sysInfo[2].qrcodeObj, config["sys.sn"])
+ })
+
+ const titleBox = viewUtils.title(screenMain, configView.screenMain, 'deviceInfoViewTitle', 'deviceInfoView.title')
+ titleBox.align(dxui.Utils.ALIGN.TOP_MID, 0, 70)
+
+ deviceInfoView.sysInfo = [
+ {
+ title: 'deviceInfoView.systemInfo',
+ type: 'menu',
+ view: systemInfoView,
+ obj: null,
+ },
+ {
+ title: 'deviceInfoView.dataCapacityInfo',
+ type: 'menu',
+ view: dataCapacityInfoView,
+ obj: null,
+ },
+ {
+ title: 'deviceInfoView.deviceQrCode',
+ value: '123',
+ type: 'qrcode',
+ obj: null,
+ },
+ ]
+
+
+ const deviceInfoBox = dxui.View.build('deviceInfoBox', screenMain)
+ viewUtils._clearStyle(deviceInfoBox)
+ deviceInfoBox.setSize(screen.screenSize.width, screen.screenSize.height - 140)
+ deviceInfoBox.align(dxui.Utils.ALIGN.TOP_MID, 0, 140)
+ deviceInfoBox.bgColor(0xf7f7f7)
+ deviceInfoBox.flexFlow(dxui.Utils.FLEX_FLOW.ROW_WRAP)
+ deviceInfoBox.flexAlign(dxui.Utils.FLEX_ALIGN.CENTER, dxui.Utils.FLEX_ALIGN.START, dxui.Utils.FLEX_ALIGN.START)
+ deviceInfoBox.obj.lvObjSetStylePadGap(10, dxui.Utils.ENUM._LV_STYLE_STATE_CMP_SAME)
+ deviceInfoBox.padTop(10)
+ deviceInfoBox.padBottom(10)
+
+ deviceInfoView.sysInfo.forEach(item => {
+ item.obj = dxui.View.build(item.title, deviceInfoBox)
+ viewUtils._clearStyle(item.obj)
+ item.obj.setSize(760, 76)
+ item.obj.bgColor(0xffffff)
+ item.obj.radius(10)
+ item.obj.on(dxui.Utils.ENUM.LV_EVENT_PRESSED, () => {
+ item.obj.bgColor(0xEAEAEA)
+ })
+ item.obj.on(dxui.Utils.ENUM.LV_EVENT_RELEASED, () => {
+ item.obj.bgColor(0xffffff)
+ })
+
+ const titleLbl = dxui.Label.build(item.title + 'Label', item.obj)
+ titleLbl.dataI18n = item.title
+ titleLbl.align(dxui.Utils.ALIGN.LEFT_MID, 20, 0)
+ titleLbl.textFont(viewUtils.font(26))
+
+ switch (item.type) {
+ case 'menu':
+ const image = dxui.Image.build(item.title + 'Image', item.obj)
+ image.align(dxui.Utils.ALIGN.RIGHT_MID, -15, 0)
+ image.source('/app/code/resource/image/right.png')
+ item.obj.on(dxui.Utils.EVENT.CLICK, () => {
+ dxui.loadMain(item.view.screenMain)
+ })
+ break
+ case 'qrcode':
+ item.obj.height(350)
+ if (item.title == "deviceInfoView.miniProgramCode") {
+ const qrcodeImage = dxui.Image.build(item.title + 'qrcodeImage', item.obj)
+ deviceInfoView.qrcodeImage = qrcodeImage
+ qrcodeImage.source('/app/code/resource/image/app_qrcode.png')
+ qrcodeImage.obj.lvImgSetZoom(256 * 0.6)
+ qrcodeImage.obj.lvImgSetSizeMode(dxui.Utils.ENUM.LV_IMG_SIZE_MODE_REAL)
+ qrcodeImage.align(dxui.Utils.ALIGN.RIGHT_MID, -20, 0)
+ } else {
+ const qrcodeBox = dxui.View.build(item.title + 'QrCode', item.obj)
+ viewUtils._clearStyle(qrcodeBox)
+ qrcodeBox.setSize(220, 220)
+ qrcodeBox.align(dxui.Utils.ALIGN.RIGHT_MID, -20, 0)
+ const qrcodeObj = dxui.Utils.GG.NativeBasicComponent.lvQrcodeCreate(qrcodeBox.obj, 220, 0x000000, 0xffffff)
+ dxui.Utils.GG.NativeBasicComponent.lvQrcodeUpdate(qrcodeObj, item.value)
+ item.qrcodeObj = qrcodeObj
+ }
+ break
+ }
+ })
+
+}
+
+export default deviceInfoView
diff --git a/vf205_access/src/view/config/menu/dockingSetting.js b/vf205_access/src/view/config/menu/dockingSetting.js
new file mode 100644
index 0000000..1c90a38
--- /dev/null
+++ b/vf205_access/src/view/config/menu/dockingSetting.js
@@ -0,0 +1,135 @@
+import dxui from '../../../../dxmodules/dxUi.js'
+import std from '../../../../dxmodules/dxStd.js'
+import viewUtils from '../../viewUtils.js'
+import topView from '../../topView.js'
+import configView from '../configView.js'
+import i18n from '../../i18n.js'
+import screen from '../../../screen.js'
+const dockingSettingView = {}
+dockingSettingView.init = function () {
+ /**************************************************鍒涘缓灞忓箷*****************************************************/
+ const screenMain = dxui.View.build('dockingSettingView', dxui.Utils.LAYER.MAIN)
+ dockingSettingView.screenMain = screenMain
+ screenMain.scroll(false)
+ screenMain.bgColor(0xffffff)
+ screenMain.on(dxui.Utils.ENUM.LV_EVENT_SCREEN_LOADED, () => {
+ topView.changeTheme(true)
+
+ const configAll = screen.getConfig()
+ httpGasSettingInput.text(configAll['http.gas'] || '')
+ httpStatusSettingInput.text(configAll['http.status'] || '')
+ gasUpdateTimeSettingInput.text((configAll['update.gasTime'] || 5) + '')
+ statusUpdateTimeSettingInput.text((configAll['update.statusTime'] || 5) + '')
+ })
+
+ const titleBox = viewUtils.title(screenMain, configView.screenMain, 'dockingSettingViewTitle', 'dockingSettingView.title')
+ titleBox.align(dxui.Utils.ALIGN.TOP_MID, 0, 70)
+
+ const httpGasSettingBox = dxui.View.build('httpGasSettingBox', screenMain)
+ viewUtils._clearStyle(httpGasSettingBox)
+ httpGasSettingBox.align(dxui.Utils.ALIGN.TOP_MID, 0, 140)
+ httpGasSettingBox.setSize(750, 76)
+ httpGasSettingBox.borderWidth(1)
+ httpGasSettingBox.setBorderColor(0xDEDEDE)
+ httpGasSettingBox.obj.setStyleBorderSide(dxui.Utils.ENUM.LV_BORDER_SIDE_BOTTOM, 0)
+
+ const httpGasSettingLbl = dxui.Label.build('httpGasSettingLbl', httpGasSettingBox)
+ httpGasSettingLbl.text('HTTP_姘斾綋')
+ httpGasSettingLbl.align(dxui.Utils.ALIGN.LEFT_MID, 0, 0)
+ httpGasSettingLbl.textFont(viewUtils.font(26))
+
+ const httpGasSettingInput = viewUtils.input(httpGasSettingBox, 'httpGasSettingInput', undefined, undefined, 'dockingSettingView.input')
+ httpGasSettingInput.align(dxui.Utils.ALIGN.RIGHT_MID, 0, 0)
+ httpGasSettingInput.setSize(320, 60)
+
+ const httpStatusSettingBox = dxui.View.build('httpStatusSettingBox', screenMain)
+ viewUtils._clearStyle(httpStatusSettingBox)
+ httpStatusSettingBox.align(dxui.Utils.ALIGN.TOP_MID, 0, 216)
+ httpStatusSettingBox.setSize(750, 76)
+ httpStatusSettingBox.borderWidth(1)
+ httpStatusSettingBox.setBorderColor(0xDEDEDE)
+ httpStatusSettingBox.obj.setStyleBorderSide(dxui.Utils.ENUM.LV_BORDER_SIDE_BOTTOM, 0)
+
+ const httpStatusSettingLbl = dxui.Label.build('httpStatusSettingLbl', httpStatusSettingBox)
+ httpStatusSettingLbl.text('HTTP_鐘舵��')
+ httpStatusSettingLbl.align(dxui.Utils.ALIGN.LEFT_MID, 0, 0)
+ httpStatusSettingLbl.textFont(viewUtils.font(26))
+
+ const httpStatusSettingInput = viewUtils.input(httpStatusSettingBox, 'httpStatusSettingInput', undefined, undefined, 'dockingSettingView.input')
+ httpStatusSettingInput.align(dxui.Utils.ALIGN.RIGHT_MID, 0, 0)
+ httpStatusSettingInput.setSize(320, 60)
+
+ // 姘斾綋娴撳害鏇存柊鏃堕棿璁剧疆
+ const gasUpdateTimeSettingBox = dxui.View.build('gasUpdateTimeSettingBox', screenMain)
+ viewUtils._clearStyle(gasUpdateTimeSettingBox)
+ gasUpdateTimeSettingBox.align(dxui.Utils.ALIGN.TOP_MID, 0, 292)
+ gasUpdateTimeSettingBox.setSize(750, 76)
+ gasUpdateTimeSettingBox.borderWidth(1)
+ gasUpdateTimeSettingBox.setBorderColor(0xDEDEDE)
+ gasUpdateTimeSettingBox.obj.setStyleBorderSide(dxui.Utils.ENUM.LV_BORDER_SIDE_BOTTOM, 0)
+
+ const gasUpdateTimeSettingLbl = dxui.Label.build('gasUpdateTimeSettingLbl', gasUpdateTimeSettingBox)
+ gasUpdateTimeSettingLbl.text('姘斾綋娴撳害鏇存柊鏃堕棿')
+ gasUpdateTimeSettingLbl.align(dxui.Utils.ALIGN.LEFT_MID, 0, 0)
+ gasUpdateTimeSettingLbl.textFont(viewUtils.font(26))
+
+ const gasUpdateTimeSettingUnitLbl = dxui.Label.build('gasUpdateTimeSettingUnitLbl', gasUpdateTimeSettingBox)
+ gasUpdateTimeSettingUnitLbl.text('绉�')
+ gasUpdateTimeSettingUnitLbl.align(dxui.Utils.ALIGN.RIGHT_MID, 0, 0)
+ gasUpdateTimeSettingUnitLbl.textFont(viewUtils.font(26))
+
+ const gasUpdateTimeSettingInput = viewUtils.input(gasUpdateTimeSettingBox, 'gasUpdateTimeSettingInput', 2, undefined, 'dockingSettingView.input')
+ gasUpdateTimeSettingInput.align(dxui.Utils.ALIGN.RIGHT_MID, -45, 0)
+ gasUpdateTimeSettingInput.setSize(150, 60)
+
+ // 鐘舵�佷俊鎭洿鏂版椂闂磋缃�
+ const statusUpdateTimeSettingBox = dxui.View.build('statusUpdateTimeSettingBox', screenMain)
+ viewUtils._clearStyle(statusUpdateTimeSettingBox)
+ statusUpdateTimeSettingBox.align(dxui.Utils.ALIGN.TOP_MID, 0, 368)
+ statusUpdateTimeSettingBox.setSize(750, 76)
+ statusUpdateTimeSettingBox.borderWidth(1)
+ statusUpdateTimeSettingBox.setBorderColor(0xDEDEDE)
+ statusUpdateTimeSettingBox.obj.setStyleBorderSide(dxui.Utils.ENUM.LV_BORDER_SIDE_BOTTOM, 0)
+
+ const statusUpdateTimeSettingLbl = dxui.Label.build('statusUpdateTimeSettingLbl', statusUpdateTimeSettingBox)
+ statusUpdateTimeSettingLbl.text('鐘舵�佷俊鎭洿鏂版椂闂�')
+ statusUpdateTimeSettingLbl.align(dxui.Utils.ALIGN.LEFT_MID, 0, 0)
+ statusUpdateTimeSettingLbl.textFont(viewUtils.font(26))
+
+ const statusUpdateTimeSettingUnitLbl = dxui.Label.build('statusUpdateTimeSettingUnitLbl', statusUpdateTimeSettingBox)
+ statusUpdateTimeSettingUnitLbl.text('绉�')
+ statusUpdateTimeSettingUnitLbl.align(dxui.Utils.ALIGN.RIGHT_MID, 0, 0)
+ statusUpdateTimeSettingUnitLbl.textFont(viewUtils.font(26))
+
+ const statusUpdateTimeSettingInput = viewUtils.input(statusUpdateTimeSettingBox, 'statusUpdateTimeSettingInput', 2, undefined, 'dockingSettingView.input')
+ statusUpdateTimeSettingInput.align(dxui.Utils.ALIGN.RIGHT_MID, -45, 0)
+ statusUpdateTimeSettingInput.setSize(150, 60)
+
+ const saveBtn = viewUtils.bottomBtn(screenMain, screenMain.id + 'saveBtn', 'dockingSettingView.save', () => {
+ const saveConfigData = {
+ http: {
+ gas: httpGasSettingInput.text(),
+ status: httpStatusSettingInput.text()
+ },
+ update: {
+ gasTime: parseInt(gasUpdateTimeSettingInput.text()) || 5,
+ statusTime: parseInt(statusUpdateTimeSettingInput.text()) || 5
+ }
+ }
+ const res = screen.saveConfig(saveConfigData)
+ if (res === true) {
+ dockingSettingView.statusPanel.success()
+ std.setTimeout(() => {
+ // 鎴愬姛杩斿洖涓婁竴灞傜晫闈�
+ dxui.loadMain(configView.screenMain)
+ }, 500)
+ } else {
+ dockingSettingView.statusPanel.fail()
+ }
+ })
+ saveBtn.align(dxui.Utils.ALIGN.BOTTOM_MID, 0, -83)
+
+ dockingSettingView.statusPanel = viewUtils.statusPanel(screenMain, 'dockingSettingView.success', 'dockingSettingView.fail')
+}
+
+export default dockingSettingView
\ No newline at end of file
diff --git a/vf205_access/src/view/config/menu/doorControlView.js b/vf205_access/src/view/config/menu/doorControlView.js
new file mode 100644
index 0000000..e8479d5
--- /dev/null
+++ b/vf205_access/src/view/config/menu/doorControlView.js
@@ -0,0 +1,258 @@
+import dxui from '../../../../dxmodules/dxUi.js'
+import std from '../../../../dxmodules/dxStd.js'
+import viewUtils from "../../viewUtils.js"
+import topView from "../../topView.js"
+import configView from '../configView.js'
+import i18n from "../../i18n.js"
+import screen from '../../../screen.js'
+import bus from '../../../../dxmodules/dxEventBus.js'
+const doorControlView = {}
+doorControlView.init = function () {
+ /**************************************************鍒涘缓灞忓箷*****************************************************/
+ const screenMain = dxui.View.build('doorControlView', dxui.Utils.LAYER.MAIN)
+ doorControlView.screenMain = screenMain
+ screenMain.scroll(false)
+ screenMain.bgColor(0xffffff)
+ screenMain.on(dxui.Utils.ENUM.LV_EVENT_SCREEN_LOADED, () => {
+ topView.changeTheme(true)
+
+ const configAll = screen.getConfig()
+ delaySettingInput.text(configAll['access.relayTime'] + '')
+ alarmSettingSwitch.select(configAll['access.tamperAlarm'] == 1)
+ mqttSettingInput.text(configAll['mqtt.addr'])
+ mqttUserSettingInput.text(configAll['mqtt.username'])
+ mqttPwdSettingInput.text(configAll['mqtt.password'])
+ onlineCheckingSettingSwitch.select(configAll['mqtt.onlinecheck'] == 1)
+ onlineCheckingTimeoutSettingInput.text(configAll['mqtt.timeout'] + '')
+ GranarySettingInput.text(configAll['GranaryName'] || '涓ぎ鍌ㄥ绮煇鏌愮洿灞炲簱')
+ houseNameSettingInput.text(configAll['houseName'] || '01鍙蜂粨')
+ doorHttpGasSettingInput.text(configAll['http.safeInputAccess'] || "http://192.168.1.199:80/cgi-bin/safeInputAccess")
+ })
+
+ const titleBox = viewUtils.title(screenMain, configView.screenMain, 'doorControlViewTitle', 'doorControlView.title')
+ titleBox.align(dxui.Utils.ALIGN.TOP_MID, 0, 70)
+
+ const delaySettingBox = dxui.View.build('delaySettingBox', screenMain)
+ viewUtils._clearStyle(delaySettingBox)
+ delaySettingBox.align(dxui.Utils.ALIGN.TOP_MID, 0, 140)
+ delaySettingBox.setSize(750, 76)
+ delaySettingBox.borderWidth(1)
+ delaySettingBox.setBorderColor(0xDEDEDE)
+ delaySettingBox.obj.setStyleBorderSide(dxui.Utils.ENUM.LV_BORDER_SIDE_BOTTOM, 0)
+
+ const delaySettingLbl = dxui.Label.build('delaySettingLbl', delaySettingBox)
+ delaySettingLbl.dataI18n = 'doorControlView.openDoorRelayDelay'
+ delaySettingLbl.align(dxui.Utils.ALIGN.LEFT_MID, 0, 0)
+ delaySettingLbl.textFont(viewUtils.font(26))
+
+ const delaySettingUnitLbl = dxui.Label.build('delaySettingUnitLbl', delaySettingBox)
+ delaySettingUnitLbl.dataI18n = "doorControlView.ms"
+ delaySettingUnitLbl.align(dxui.Utils.ALIGN.RIGHT_MID, 0, 0)
+ delaySettingUnitLbl.textFont(viewUtils.font(26))
+
+ const delaySettingInput = viewUtils.input(delaySettingBox, 'delaySettingInput', 2, undefined, 'doorControlView.input')
+ delaySettingInput.align(dxui.Utils.ALIGN.RIGHT_MID, -60, 0)
+ delaySettingInput.setSize(150, 60)
+
+ const alarmSettingBox = dxui.View.build('alarmSettingBox', screenMain)
+ viewUtils._clearStyle(alarmSettingBox)
+ alarmSettingBox.align(dxui.Utils.ALIGN.TOP_MID, 0, 216)
+ alarmSettingBox.setSize(750, 76)
+ alarmSettingBox.borderWidth(1)
+ alarmSettingBox.setBorderColor(0xDEDEDE)
+ alarmSettingBox.obj.setStyleBorderSide(dxui.Utils.ENUM.LV_BORDER_SIDE_BOTTOM, 0)
+
+ const alarmSettingLbl = dxui.Label.build('alarmSettingLbl', alarmSettingBox)
+ alarmSettingLbl.dataI18n = 'doorControlView.antiTamperAlarm'
+ alarmSettingLbl.align(dxui.Utils.ALIGN.LEFT_MID, 0, 0)
+ alarmSettingLbl.textFont(viewUtils.font(26))
+
+ const alarmSettingSwitch = dxui.Switch.build('alarmSettingSwitch', alarmSettingBox)
+ alarmSettingSwitch.align(dxui.Utils.ALIGN.RIGHT_MID, 0, 0)
+ alarmSettingSwitch.setSize(70, 35)
+
+
+ const mqttSettingBox = dxui.View.build('mqttSettingBox', screenMain)
+ viewUtils._clearStyle(mqttSettingBox)
+ mqttSettingBox.align(dxui.Utils.ALIGN.TOP_MID, 0, 292)
+ mqttSettingBox.setSize(750, 76)
+ mqttSettingBox.borderWidth(1)
+ mqttSettingBox.setBorderColor(0xDEDEDE)
+ mqttSettingBox.obj.setStyleBorderSide(dxui.Utils.ENUM.LV_BORDER_SIDE_BOTTOM, 0)
+
+ const mqttSettingLbl = dxui.Label.build('mqttSettingLbl', mqttSettingBox)
+ mqttSettingLbl.dataI18n = 'doorControlView.mqttAddr'
+ mqttSettingLbl.align(dxui.Utils.ALIGN.LEFT_MID, 0, 0)
+ mqttSettingLbl.textFont(viewUtils.font(26))
+
+ const mqttSettingInput = viewUtils.input(mqttSettingBox, 'mqttSettingInput', undefined, undefined, 'doorControlView.input')
+ mqttSettingInput.align(dxui.Utils.ALIGN.RIGHT_MID, 0, 0)
+ mqttSettingInput.setSize(320, 60)
+
+ const mqttUserSettingBox = dxui.View.build('mqttUserSettingBox', screenMain)
+ viewUtils._clearStyle(mqttUserSettingBox)
+ mqttUserSettingBox.align(dxui.Utils.ALIGN.TOP_MID, 0, 368)
+ mqttUserSettingBox.setSize(750, 76)
+ mqttUserSettingBox.borderWidth(1)
+ mqttUserSettingBox.setBorderColor(0xDEDEDE)
+ mqttUserSettingBox.obj.setStyleBorderSide(dxui.Utils.ENUM.LV_BORDER_SIDE_BOTTOM, 0)
+
+ const mqttUserSettingLbl = dxui.Label.build('mqttUserSettingLbl', mqttUserSettingBox)
+ mqttUserSettingLbl.dataI18n = 'doorControlView.mqttUser'
+ mqttUserSettingLbl.align(dxui.Utils.ALIGN.LEFT_MID, 0, 0)
+ mqttUserSettingLbl.textFont(viewUtils.font(26))
+
+ const mqttUserSettingInput = viewUtils.input(mqttUserSettingBox, 'mqttUserSettingInput', undefined, undefined, 'doorControlView.input')
+ mqttUserSettingInput.align(dxui.Utils.ALIGN.RIGHT_MID, 0, 0)
+ mqttUserSettingInput.setSize(320, 60)
+
+ const mqttPwdSettingBox = dxui.View.build('mqttPwdSettingBox', screenMain)
+ viewUtils._clearStyle(mqttPwdSettingBox)
+ mqttPwdSettingBox.align(dxui.Utils.ALIGN.TOP_MID, 0, 444)
+ mqttPwdSettingBox.setSize(750, 76)
+ mqttPwdSettingBox.borderWidth(1)
+ mqttPwdSettingBox.setBorderColor(0xDEDEDE)
+ mqttPwdSettingBox.obj.setStyleBorderSide(dxui.Utils.ENUM.LV_BORDER_SIDE_BOTTOM, 0)
+
+ const mqttPwdSettingLbl = dxui.Label.build('mqttPwdSettingLbl', mqttPwdSettingBox)
+ mqttPwdSettingLbl.dataI18n = 'doorControlView.mqttPwd'
+ mqttPwdSettingLbl.align(dxui.Utils.ALIGN.LEFT_MID, 0, 0)
+ mqttPwdSettingLbl.textFont(viewUtils.font(26))
+
+ const mqttPwdSettingInput = viewUtils.input(mqttPwdSettingBox, 'mqttPwdSettingInput', undefined, undefined, 'doorControlView.input')
+ mqttPwdSettingInput.align(dxui.Utils.ALIGN.RIGHT_MID, 0, 0)
+ mqttPwdSettingInput.setSize(320, 60)
+
+
+ const onlineCheckingSettingBox = dxui.View.build('onlineCheckingSettingBox', screenMain)
+ viewUtils._clearStyle(onlineCheckingSettingBox)
+ onlineCheckingSettingBox.align(dxui.Utils.ALIGN.TOP_MID, 0, 540)
+ onlineCheckingSettingBox.setSize(750, 76)
+ onlineCheckingSettingBox.borderWidth(1)
+ onlineCheckingSettingBox.setBorderColor(0xDEDEDE)
+ onlineCheckingSettingBox.obj.setStyleBorderSide(dxui.Utils.ENUM.LV_BORDER_SIDE_BOTTOM, 0)
+
+ const onlineCheckingSettingLbl = dxui.Label.build('onlineCheckingSettingLbl', onlineCheckingSettingBox)
+ onlineCheckingSettingLbl.dataI18n = 'doorControlView.onlineChecking'
+ onlineCheckingSettingLbl.align(dxui.Utils.ALIGN.LEFT_MID, 0, 0)
+ onlineCheckingSettingLbl.textFont(viewUtils.font(26))
+
+ const onlineCheckingSettingSwitch = dxui.Switch.build('onlineCheckingSettingSwitch', onlineCheckingSettingBox)
+ onlineCheckingSettingSwitch.align(dxui.Utils.ALIGN.RIGHT_MID, 0, 0)
+ onlineCheckingSettingSwitch.setSize(70, 35)
+
+ const onlineCheckingTimeoutSettingBox = dxui.View.build('onlineCheckingTimeoutSettingBox', screenMain)
+ viewUtils._clearStyle(onlineCheckingTimeoutSettingBox)
+ onlineCheckingTimeoutSettingBox.align(dxui.Utils.ALIGN.TOP_MID, 0, 616)
+ onlineCheckingTimeoutSettingBox.setSize(750, 76)
+ onlineCheckingTimeoutSettingBox.borderWidth(1)
+ onlineCheckingTimeoutSettingBox.setBorderColor(0xDEDEDE)
+ onlineCheckingTimeoutSettingBox.obj.setStyleBorderSide(dxui.Utils.ENUM.LV_BORDER_SIDE_BOTTOM, 0)
+
+ const onlineCheckingTimeoutSettingLbl = dxui.Label.build('onlineCheckingTimeoutSettingLbl', onlineCheckingTimeoutSettingBox)
+ onlineCheckingTimeoutSettingLbl.dataI18n = 'doorControlView.onlineCheckingTimeout'
+ onlineCheckingTimeoutSettingLbl.align(dxui.Utils.ALIGN.LEFT_MID, 0, 0)
+ onlineCheckingTimeoutSettingLbl.textFont(viewUtils.font(26))
+
+ const onlineCheckingTimeoutSettingUnitLbl = dxui.Label.build('onlineCheckingTimeoutSettingUnitLbl', onlineCheckingTimeoutSettingBox)
+ onlineCheckingTimeoutSettingUnitLbl.text('ms')
+ onlineCheckingTimeoutSettingUnitLbl.align(dxui.Utils.ALIGN.RIGHT_MID, 0, 0)
+ onlineCheckingTimeoutSettingUnitLbl.textFont(viewUtils.font(26))
+
+ const onlineCheckingTimeoutSettingInput = viewUtils.input(onlineCheckingTimeoutSettingBox, 'onlineCheckingTimeoutSettingInput', 2, undefined, 'doorControlView.input')
+ onlineCheckingTimeoutSettingInput.align(dxui.Utils.ALIGN.RIGHT_MID, -45, 0)
+ onlineCheckingTimeoutSettingInput.setSize(150, 60)
+
+ // HTTP鎺ュ彛璺緞璁剧疆
+ // 搴撳尯鍚嶇О璁剧疆
+ const GranarySettingBox = dxui.View.build('GranarySettingBox', screenMain)
+ viewUtils._clearStyle(GranarySettingBox)
+ GranarySettingBox.align(dxui.Utils.ALIGN.TOP_MID, 0, 692)
+ GranarySettingBox.setSize(750, 76)
+ GranarySettingBox.borderWidth(1)
+ GranarySettingBox.setBorderColor(0xDEDEDE)
+ GranarySettingBox.obj.setStyleBorderSide(dxui.Utils.ENUM.LV_BORDER_SIDE_BOTTOM, 0)
+
+ const GranarySettingLbl = dxui.Label.build('GranarySettingLbl', GranarySettingBox)
+ GranarySettingLbl.text('搴撳尯鍚嶇О')
+ GranarySettingLbl.align(dxui.Utils.ALIGN.LEFT_MID, 0, 0)
+ GranarySettingLbl.textFont(viewUtils.font(26))
+
+ const GranarySettingInput = viewUtils.input(GranarySettingBox, 'GranarySettingInput', undefined, undefined, 'doorControlView.input')
+ GranarySettingInput.align(dxui.Utils.ALIGN.RIGHT_MID, 0, 0)
+ GranarySettingInput.setSize(320, 60)
+
+ // 浠撳粧鍚嶇О璁剧疆
+ const houseNameSettingBox = dxui.View.build('houseNameSettingBox', screenMain)
+ viewUtils._clearStyle(houseNameSettingBox)
+ houseNameSettingBox.align(dxui.Utils.ALIGN.TOP_MID, 0, 768)
+ houseNameSettingBox.setSize(750, 76)
+ houseNameSettingBox.borderWidth(1)
+ houseNameSettingBox.setBorderColor(0xDEDEDE)
+ houseNameSettingBox.obj.setStyleBorderSide(dxui.Utils.ENUM.LV_BORDER_SIDE_BOTTOM, 0)
+
+ const houseNameSettingLbl = dxui.Label.build('houseNameSettingLbl', houseNameSettingBox)
+ houseNameSettingLbl.text('浠撳粧鍚嶇О')
+ houseNameSettingLbl.align(dxui.Utils.ALIGN.LEFT_MID, 0, 0)
+ houseNameSettingLbl.textFont(viewUtils.font(26))
+
+ const houseNameSettingInput = viewUtils.input(houseNameSettingBox, 'houseNameSettingInput', undefined, undefined, 'doorControlView.input')
+ houseNameSettingInput.align(dxui.Utils.ALIGN.RIGHT_MID, 0, 0)
+ houseNameSettingInput.setSize(320, 60)
+
+ // HTTP鎺ュ彛璺緞璁剧疆
+ const doorHttpGasSettingBox = dxui.View.build('doorHttpGasSettingBox', screenMain)
+ viewUtils._clearStyle(doorHttpGasSettingBox)
+ doorHttpGasSettingBox.align(dxui.Utils.ALIGN.TOP_MID, 0, 844)
+ doorHttpGasSettingBox.setSize(750, 76)
+ doorHttpGasSettingBox.borderWidth(1)
+ doorHttpGasSettingBox.setBorderColor(0xDEDEDE)
+ doorHttpGasSettingBox.obj.setStyleBorderSide(dxui.Utils.ENUM.LV_BORDER_SIDE_BOTTOM, 0)
+
+ const doorHttpGasSettingLbl = dxui.Label.build('doorHttpGasSettingLbl', doorHttpGasSettingBox)
+ doorHttpGasSettingLbl.text('HTTP鎺ュ彛璺緞')
+ doorHttpGasSettingLbl.align(dxui.Utils.ALIGN.LEFT_MID, 0, 0)
+ doorHttpGasSettingLbl.textFont(viewUtils.font(26))
+
+ const doorHttpGasSettingInput = viewUtils.input(doorHttpGasSettingBox, 'doorHttpGasSettingInput', undefined, undefined, 'doorControlView.input')
+ doorHttpGasSettingInput.align(dxui.Utils.ALIGN.RIGHT_MID, 0, 0)
+ doorHttpGasSettingInput.setSize(320, 60)
+
+ const saveBtn = viewUtils.bottomBtn(screenMain, screenMain.id + 'saveBtn', 'doorControlView.save', () => {
+ const saveConfigData = {
+ access: {
+ relayTime: parseInt(delaySettingInput.text()),
+ tamperAlarm: alarmSettingSwitch.isSelect() ? 1 : 0
+ },
+ mqtt: {
+ addr: mqttSettingInput.text(),
+ username: mqttUserSettingInput.text(),
+ password: mqttPwdSettingInput.text(),
+ onlinecheck: onlineCheckingSettingSwitch.isSelect() ? 1 : 0,
+ timeout: parseInt(onlineCheckingTimeoutSettingInput.text())
+ },
+ GranaryName: GranarySettingInput.text(),
+ houseName: houseNameSettingInput.text(),
+ http: {
+ safeInputAccess: doorHttpGasSettingInput.text()
+ }
+ }
+ const res = screen.saveConfig(saveConfigData)
+ if (res === true) {
+ doorControlView.statusPanel.success()
+ // 閫氱煡mainView鏇存柊搴撳尯鍚嶇О鍜屼粨鍙�
+ bus.fire('warehouseInfoUpdated')
+ std.setTimeout(() => {
+ // 鎴愬姛杩斿洖涓婁竴灞傜晫闈�
+ dxui.loadMain(configView.screenMain)
+ }, 500)
+ } else {
+ doorControlView.statusPanel.fail()
+ }
+ })
+ saveBtn.align(dxui.Utils.ALIGN.BOTTOM_MID, 0, -83)
+
+ doorControlView.statusPanel = viewUtils.statusPanel(screenMain, 'doorControlView.success', 'doorControlView.fail')
+}
+
+export default doorControlView
diff --git a/vf205_access/src/view/config/menu/factoryTestView.js b/vf205_access/src/view/config/menu/factoryTestView.js
new file mode 100644
index 0000000..661dc87
--- /dev/null
+++ b/vf205_access/src/view/config/menu/factoryTestView.js
@@ -0,0 +1,77 @@
+import dxui from "../../../../dxmodules/dxUi.js";
+import viewUtils from "../../viewUtils.js";
+import topView from "../../topView.js";
+import configView from "../configView.js";
+import i18n from "../../i18n.js";
+import screen from "../../../screen.js";
+const factoryTestView = {};
+factoryTestView.init = function () {
+ /**************************************************鍒涘缓灞忓箷*****************************************************/
+ const screenMain = dxui.View.build("factoryTestView", dxui.Utils.LAYER.MAIN);
+ factoryTestView.screenMain = screenMain;
+ screenMain.scroll(false);
+ screenMain.bgColor(0xffffff);
+ screenMain.on(dxui.Utils.ENUM.LV_EVENT_SCREEN_LOADED, () => {
+ topView.changeTheme(true);
+ });
+
+ const titleBox = viewUtils.title(
+ screenMain,
+ configView.screenMain,
+ "factoryTestViewTitle",
+ "factoryTestView.title"
+ );
+ titleBox.align(dxui.Utils.ALIGN.TOP_MID, 0, 70);
+
+ const factoryTestBox = dxui.View.build("factoryTestBox", screenMain);
+ viewUtils._clearStyle(factoryTestBox);
+ factoryTestBox.setSize(
+ screen.screenSize.width,
+ screen.screenSize.height - 140
+ );
+ factoryTestBox.align(dxui.Utils.ALIGN.TOP_MID, 0, 140);
+ factoryTestBox.bgColor(0xf7f7f7);
+ factoryTestBox.flexFlow(dxui.Utils.FLEX_FLOW.ROW_WRAP);
+ factoryTestBox.flexAlign(
+ dxui.Utils.FLEX_ALIGN.CENTER,
+ dxui.Utils.FLEX_ALIGN.START,
+ dxui.Utils.FLEX_ALIGN.START
+ );
+ factoryTestBox.obj.lvObjSetStylePadGap(
+ 10,
+ dxui.Utils.ENUM._LV_STYLE_STATE_CMP_SAME
+ );
+ factoryTestBox.padTop(10);
+ factoryTestBox.padBottom(10);
+
+ const calibrationBox = dxui.View.build("calibrationBox", factoryTestBox);
+ viewUtils._clearStyle(calibrationBox);
+ // calibrationBox.align(dxui.Utils.ALIGN.TOP_MID, 0, 150);
+ calibrationBox.setSize(560, 76);
+ // calibrationBox.bgColor(0xf7f7f7);
+ calibrationBox.bgColor(0xffffff);
+ calibrationBox.radius(10);
+ calibrationBox.on(dxui.Utils.ENUM.LV_EVENT_PRESSED, () => {
+ calibrationBox.bgColor(0xeaeaea);
+ });
+ calibrationBox.on(dxui.Utils.ENUM.LV_EVENT_RELEASED, () => {
+ calibrationBox.bgColor(0xffffff);
+ });
+
+ const titleLbl = dxui.Label.build("calibrationBox" + "Label", calibrationBox);
+ titleLbl.dataI18n = "factoryTestView.calibration";
+ titleLbl.align(dxui.Utils.ALIGN.LEFT_MID, 20, 0);
+ titleLbl.textFont(viewUtils.font(26));
+
+ const image = dxui.Image.build(calibrationBox.id + "Image", calibrationBox);
+ image.align(dxui.Utils.ALIGN.RIGHT_MID, -15, 0);
+ image.source("/app/code/resource/image/right.png");
+
+ calibrationBox.on(dxui.Utils.EVENT.CLICK, () => {
+ // dxui.loadMain(item.view.screenMain);
+ console.log(123);
+
+ });
+};
+
+export default factoryTestView;
diff --git a/vf205_access/src/view/config/menu/helpView.js b/vf205_access/src/view/config/menu/helpView.js
new file mode 100644
index 0000000..fffc887
--- /dev/null
+++ b/vf205_access/src/view/config/menu/helpView.js
@@ -0,0 +1,41 @@
+import dxui from '../../../../dxmodules/dxUi.js'
+import viewUtils from "../../viewUtils.js"
+import topView from "../../topView.js"
+import configView from '../configView.js'
+import i18n from "../../i18n.js"
+const helpView = {}
+helpView.init = function () {
+ /**************************************************鍒涘缓灞忓箷*****************************************************/
+ const screenMain = dxui.View.build('helpView', dxui.Utils.LAYER.MAIN)
+ helpView.screenMain = screenMain
+ screenMain.scroll(false)
+ screenMain.bgColor(0xffffff)
+ screenMain.on(dxui.Utils.ENUM.LV_EVENT_SCREEN_LOADED, () => {
+ topView.changeTheme(true)
+ })
+
+ const titleBox = viewUtils.title(screenMain, configView.screenMain, 'helpViewTitle', 'helpView.title')
+ titleBox.align(dxui.Utils.ALIGN.TOP_MID, 0, 70)
+
+ // 浜岀淮鐮�
+ const helpQrcode = dxui.View.build('helpQrcode', screenMain)
+ viewUtils._clearStyle(helpQrcode)
+ helpQrcode.setSize(344, 344)
+ helpQrcode.align(dxui.Utils.ALIGN.TOP_MID, 0, 170)
+ helpQrcode.bgOpa(0)
+
+ const qrcode = dxui.View.build(helpQrcode.id + 'qrcode', helpQrcode)
+ viewUtils._clearStyle(qrcode)
+ qrcode.setSize(320, 320)
+ qrcode.align(dxui.Utils.ALIGN.CENTER, 0, 0);
+ const qrcodeObj = dxui.Utils.GG.NativeBasicComponent.lvQrcodeCreate(qrcode.obj, 320, 0x000000, 0xffffff)
+ dxui.Utils.GG.NativeBasicComponent.lvQrcodeUpdate(qrcodeObj, '寰俊鏆備笉鏀寔灞曠ず浜岀淮鐮佷腑鐨勬枃鏈唴瀹�')
+
+
+ const helpLabel = dxui.Label.build('helpLabel', screenMain)
+ helpLabel.dataI18n='helpView.scanCode'
+ helpLabel.align(dxui.Utils.ALIGN.TOP_MID, 0, 541)
+ helpLabel.textFont(viewUtils.font(26))
+}
+
+export default helpView
diff --git a/vf205_access/src/view/config/menu/localUser/faceEnterView.js b/vf205_access/src/view/config/menu/localUser/faceEnterView.js
new file mode 100644
index 0000000..83fdcb8
--- /dev/null
+++ b/vf205_access/src/view/config/menu/localUser/faceEnterView.js
@@ -0,0 +1,117 @@
+import dxui from '../../../../../dxmodules/dxUi.js'
+import std from '../../../../../dxmodules/dxStd.js'
+import viewUtils from "../../../viewUtils.js"
+import topView from "../../../topView.js"
+import i18n from "../../../i18n.js"
+import localUserAddView from './localUserAddView.js'
+import screen from '../../../../screen.js'
+const faceEnterView = {}
+faceEnterView.init = function () {
+ /**************************************************鍒涘缓灞忓箷*****************************************************/
+ const screenMain = dxui.View.build('faceEnterView', dxui.Utils.LAYER.MAIN)
+ faceEnterView.screenMain = screenMain
+ screenMain.scroll(false)
+ screenMain.bgOpa(0)
+ screenMain.on(dxui.Utils.ENUM.LV_EVENT_SCREEN_LOADED, () => {
+ topView.changeTheme(false)
+ screen.faceEnterStart(localUserAddView.nowUser.id)
+
+ faceEnterView.statusPanel.success("faceEnterView.faceAdd")
+ // faceEnterView.faceAdd.show()
+ // faceEnterView.faceError.hide()
+ // 娉ㄥ唽10绉掕秴鏃�
+ faceEnterView.backTimer = std.setTimeout(() => {
+ if (!faceEnterView.successFlag) {
+ faceEnterView.statusPanel.fail("faceEnterView.faceError")
+ std.setTimeout(() => {
+ faceEnterView.backCb()
+ dxui.loadMain(localUserAddView.screenMain)
+ }, 500);
+ }
+ }, 10000);
+ })
+
+ screenMain.on(dxui.Utils.ENUM.LV_EVENT_SCREEN_UNLOADED, () => {
+ faceEnterView.successFlag = false
+ screen.faceEnterEnd()
+ if (faceEnterView.backTimer) {
+ std.clearTimeout(faceEnterView.backTimer)
+ faceEnterView.backTimer = null
+ }
+ })
+
+ const titleBoxBg = dxui.View.build(screenMain.id + 'titleBoxBg', screenMain)
+ viewUtils._clearStyle(titleBoxBg)
+ titleBoxBg.setSize(screen.screenSize.width, 70)
+ titleBoxBg.align(dxui.Utils.ALIGN.TOP_MID, 0, 0)
+ titleBoxBg.bgColor(0xffffff)
+
+ const titleBox = viewUtils.title(screenMain, localUserAddView.screenMain, 'faceEnterViewTitle', 'faceEnterView.title', faceEnterView.backCb)
+ titleBox.align(dxui.Utils.ALIGN.TOP_MID, 0, 70)
+
+ const faceRec2 = dxui.Image.build('faceRec2', screenMain)
+ faceRec2.align(dxui.Utils.ALIGN.TOP_MID, 0, -111)
+ faceRec2.source('/app/code/resource/image/faceRec2.png')
+
+ // const faceAdd = dxui.Image.build('faceAdd', screenMain)
+ // faceEnterView.faceAdd = faceAdd
+ // faceAdd.align(dxui.Utils.ALIGN.BOTTOM_MID, 0, -90)
+ // faceAdd.source('/app/code/resource/image/faceAdd.png')
+
+ // const faceAddLbl = dxui.Label.build('faceAddLbl', faceAdd)
+ // faceAddLbl.align(dxui.Utils.ALIGN.CENTER, 0, 0)
+ // faceAddLbl.textFont(viewUtils.font(30))
+ // faceAddLbl.textColor(0xffffff)
+ // faceAddLbl.dataI18n = 'faceEnterView.faceAdd'
+ // faceAddLbl.textAlign(dxui.Utils.TEXT_ALIGN.CENTER)
+
+
+ faceEnterView.statusPanel = viewUtils.statusPanel(screenMain)
+ // const faceError = dxui.Image.build('faceError', screenMain)
+ // faceEnterView.faceError = faceError
+ // faceError.align(dxui.Utils.ALIGN.BOTTOM_MID, 0, -90)
+ // faceError.source('/app/code/resource/image/faceError.png')
+ // faceError.hide()
+
+ // const faceErrorLbl = dxui.Label.build('faceErrorLbl', faceError)
+ // faceErrorLbl.align(dxui.Utils.ALIGN.CENTER, 0, 0)
+ // faceErrorLbl.textFont(viewUtils.font(30))
+ // faceErrorLbl.textColor(0xffffff)
+ // faceErrorLbl.dataI18n = 'faceEnterView.faceError'
+ // faceErrorLbl.textAlign(dxui.Utils.TEXT_ALIGN.CENTER)
+
+ // faceEnterView.timeout()
+}
+
+faceEnterView.timeout = function () {
+ // faceEnterView.statusPanel.fail("faceEnterView.faceError")
+ // faceEnterView.faceAdd.hide()
+ // faceEnterView.faceError.show()
+}
+
+faceEnterView.backCb = function () {
+ if (!localUserAddView.nowUser) {
+ return
+ }
+ if (localUserAddView.nowUser.id) {
+ localUserAddView.addID(localUserAddView.nowUser.id)
+ }
+ if (localUserAddView.nowUser.name) {
+ localUserAddView.addName(localUserAddView.nowUser.name)
+ }
+ if (localUserAddView.nowUser.idCard) {
+ localUserAddView.addIDCard(localUserAddView.nowUser.idCard)
+ }
+ if (localUserAddView.nowUser.face) {
+ localUserAddView.addFace(localUserAddView.nowUser.face)
+ }
+ if (localUserAddView.nowUser.pwd) {
+ localUserAddView.addPwd(localUserAddView.nowUser.pwd)
+ }
+ if (localUserAddView.nowUser.card) {
+ localUserAddView.addCard(localUserAddView.nowUser.card)
+ }
+ localUserAddView.addType(localUserAddView.nowUser.type)
+}
+
+export default faceEnterView
\ No newline at end of file
diff --git a/vf205_access/src/view/config/menu/localUser/localUserAddView.js b/vf205_access/src/view/config/menu/localUser/localUserAddView.js
new file mode 100644
index 0000000..a61655d
--- /dev/null
+++ b/vf205_access/src/view/config/menu/localUser/localUserAddView.js
@@ -0,0 +1,682 @@
+import dxui from '../../../../../dxmodules/dxUi.js'
+import std from '../../../../../dxmodules/dxStd.js'
+import viewUtils from "../../../viewUtils.js"
+import topView from "../../../topView.js"
+import localUserView from '../localUserView.js'
+import faceEnterView from './faceEnterView.js'
+import i18n from "../../../i18n.js"
+import pinyin from '../../../pinyin/pinyin.js'
+import screen from '../../../../screen.js'
+const localUserAddView = {}
+const dropdownData = ['淇濈鍛�', '绉戦暱']
+const dropdownData2 = ['User', 'Administrator']
+
+localUserAddView.init = function () {
+ /**************************************************鍒涘缓灞忓箷*****************************************************/
+ const screenMain = dxui.View.build('localUserAddView', dxui.Utils.LAYER.MAIN)
+ localUserAddView.screenMain = screenMain
+ screenMain.scroll(false)
+ screenMain.bgColor(0xffffff)
+ screenMain.on(dxui.Utils.ENUM.LV_EVENT_SCREEN_LOADED, () => {
+ topView.changeTheme(true)
+ refreshType()
+ if (!localUserAddView.deleteBtn.isHide()) {
+ //淇敼鐢ㄦ埛涓嶅厑璁告敼id
+ localUserAddView.userInfo[0].input.disable(true)
+ } else {
+ localUserAddView.userInfo[0].input.disable(false)
+ }
+ })
+
+ screenMain.on(dxui.Utils.ENUM.LV_EVENT_SCREEN_UNLOADED, () => {
+ })
+
+ const titleBox = viewUtils.title(screenMain, localUserView.screenMain, 'localUserAddViewTitle', 'localUserAddView.title', undefined)
+ localUserAddView.titleBox = titleBox
+ titleBox.align(dxui.Utils.ALIGN.TOP_MID, 0, 70)
+
+ const titleBox2 = viewUtils.title(screenMain, localUserView.screenMain, 'localUserAddViewTitle2', 'localUserAddView.title2', undefined)
+ localUserAddView.titleBox2 = titleBox2
+ titleBox2.align(dxui.Utils.ALIGN.TOP_MID, 0, 70)
+ titleBox2.hide()
+
+ const addUserBox = dxui.View.build('addUserBox', screenMain)
+ viewUtils._clearStyle(addUserBox)
+ addUserBox.setSize(screen.screenSize.width, 700)
+ addUserBox.align(dxui.Utils.ALIGN.TOP_MID, 0, 142)
+ addUserBox.borderWidth(1)
+ addUserBox.setBorderColor(0xDEDEDE)
+ addUserBox.obj.setStyleBorderSide(dxui.Utils.ENUM.LV_BORDER_SIDE_TOP, 0)
+ addUserBox.bgOpa(0)
+
+ addUserBox.flexFlow(dxui.Utils.FLEX_FLOW.ROW_WRAP)
+ addUserBox.flexAlign(dxui.Utils.FLEX_ALIGN.CENTER, dxui.Utils.FLEX_ALIGN.CENTER, dxui.Utils.FLEX_ALIGN.START)
+ addUserBox.obj.lvObjSetStylePadGap(0, dxui.Utils.ENUM._LV_STYLE_STATE_CMP_SAME)
+
+ localUserAddView.userInfo = [
+ {
+ title: 'localUserAddView.id',
+ value: null,
+ required: true,
+ type: 'input',
+ input: null
+ },
+ {
+ title: 'localUserAddView.name',
+ value: null,
+ required: true,
+ type: 'input',
+ input: null
+ },
+ {
+ title: 'localUserAddView.idCard',
+ value: null,
+ type: 'input',
+ input: null
+ },
+ {
+ title: 'localUserAddView.face',
+ value: null,
+ type: 'button',
+ btn: null,
+ btnEdit: null,
+ faceImg: null,
+ deleteBtn: null
+ },
+ {
+ title: 'localUserAddView.pwd',
+ value: null,
+ type: 'button',
+ btn: null,
+ btnEdit: null,
+ pwdLbl: null,
+ deleteBtn: null
+ },
+ {
+ title: 'localUserAddView.card',
+ value: null,
+ type: 'button',
+ btn: null,
+ btnEdit: null,
+ cardLbl: null,
+ deleteBtn: null
+ },
+ {
+ title: 'localUserAddView.type',
+ value: null,
+ type: 'dropdown'
+ }
+ ]
+
+ localUserAddView.userInfo.forEach((item, index) => {
+ const userBox = dxui.View.build('userInfo' + index, addUserBox)
+ viewUtils._clearStyle(userBox)
+ userBox.setSize(700, 65)
+ userBox.borderWidth(1)
+ userBox.setBorderColor(0xDEDEDE)
+ userBox.obj.setStyleBorderSide(dxui.Utils.ENUM.LV_BORDER_SIDE_BOTTOM, 0)
+ userBox.bgOpa(0)
+
+ if (item.required) {
+ const titleLbl = dxui.Label.build('titleLblRequired' + index, userBox)
+ titleLbl.textFont(viewUtils.font(22))
+ titleLbl.align(dxui.Utils.ALIGN.LEFT_MID, 0, 0)
+ titleLbl.text('*')
+ titleLbl.textColor(0xFD5353)
+ }
+
+ const titleLbl = dxui.Label.build('titleLbl' + index, userBox)
+ titleLbl.textFont(viewUtils.font(22))
+ titleLbl.align(dxui.Utils.ALIGN.LEFT_MID, 10, 0)
+ titleLbl.dataI18n = item.title
+
+ if (item.type === 'input') {
+ const input = viewUtils.input(userBox, item.title, item.mode, undefined, "localUserAddView.input")
+ input.align(dxui.Utils.ALIGN.RIGHT_MID, 0, 0)
+ input.textFont(viewUtils.font(22))
+ input.setSize(260, 50)
+ item.input = input
+
+ input.on(dxui.Utils.EVENT.VALUE_CHANGED, () => {
+ if (input.text() === "") {
+ return
+ }
+ switch (item.title) {
+ case 'localUserAddView.id':
+ localUserAddView.nowUser.id = input.text()
+ localUserAddView.nowUser.userId = input.text()
+ break;
+ case 'localUserAddView.name':
+ localUserAddView.nowUser.name = input.text()
+ break;
+ case 'localUserAddView.idCard':
+ localUserAddView.nowUser.idCard = input.text()
+ break;
+ default:
+ break;
+ }
+ })
+ } else if (item.type === 'button') {
+ const btn = dxui.Button.build(item.title, userBox)
+ item.btn = btn
+ btn.setSize(150, 50)
+ btn.align(dxui.Utils.ALIGN.RIGHT_MID, 0, 0)
+ btn.bgColor(0xEEEEEE)
+ btn.radius(10)
+ const btnLbl = dxui.Label.build(item.title + 'btnLbl', btn)
+ btnLbl.textFont(viewUtils.font(22))
+ btnLbl.textColor(0x05AA8D)
+ btnLbl.align(dxui.Utils.ALIGN.CENTER, 0, 0)
+
+ const btnEdit = dxui.Button.build(item.title + 'edit', userBox)
+ item.btnEdit = btnEdit
+ btnEdit.setSize(150, 50)
+ btnEdit.align(dxui.Utils.ALIGN.RIGHT_MID, -60, 0)
+ btnEdit.bgColor(0xEEEEEE)
+ btnEdit.radius(10)
+ btnEdit.hide()
+ const btnEditLbl = dxui.Label.build(item.title + 'btnEditLbl', btnEdit)
+ btnEditLbl.textFont(viewUtils.font(22))
+ btnEditLbl.textColor(0x05AA8D)
+ btnEditLbl.align(dxui.Utils.ALIGN.CENTER, 0, 0)
+
+ const deleteBtn = viewUtils.imageBtn(userBox, item.title + 'deleteBtn', '/app/code/resource/image/delete.png')
+ item.deleteBtn = deleteBtn
+ deleteBtn.align(dxui.Utils.ALIGN.RIGHT_MID, 0, 0)
+ deleteBtn.hide()
+
+ if (item.title === 'localUserAddView.pwd') {
+ btnLbl.dataI18n = 'localUserAddView.generate'
+ btnEditLbl.dataI18n = 'localUserAddView.reset'
+
+ // 瀵嗙爜
+ const pwdLbl = dxui.Label.build(userBox.id + 'pwdLbl', userBox)
+ item.pwdLbl = pwdLbl
+ pwdLbl.align(dxui.Utils.ALIGN.LEFT_MID, 180, 0)
+ pwdLbl.textColor(0x767676)
+ pwdLbl.textFont(viewUtils.font(26))
+ pwdLbl.hide()
+
+ btn.on(dxui.Utils.EVENT.CLICK, () => {
+ pwdBoxBg.show()
+ pwdBoxBg.moveForeground()
+ topView.changeTheme(false)
+ localUserAddView.changePwd()
+ })
+
+ btnEdit.on(dxui.Utils.EVENT.CLICK, () => {
+ btn.send(dxui.Utils.EVENT.CLICK)
+ })
+
+ deleteBtn.on(dxui.Utils.EVENT.CLICK, () => {
+ viewUtils.confirmOpen('localUserAddView.confirm', 'localUserAddView.confirmPwd', () => {
+ localUserAddView.removePwd()
+ }, () => { })
+ })
+
+ } else {
+ btnLbl.dataI18n = 'localUserAddView.enter'
+ btnEditLbl.dataI18n = 'localUserAddView.edit'
+ }
+
+ if (item.title === 'localUserAddView.card') {
+ // 鍗�
+ const cardLbl = dxui.Label.build(userBox.id + 'cardLbl', userBox)
+ item.cardLbl = cardLbl
+ cardLbl.align(dxui.Utils.ALIGN.LEFT_MID, 180, 0)
+ cardLbl.textColor(0x767676)
+ cardLbl.textFont(viewUtils.font(26))
+ cardLbl.hide()
+ cardLbl.longMode(dxui.Utils.LABEL_LONG_MODE.SCROLL_CIRCULAR)
+ cardLbl.width(150)
+
+ btn.on(dxui.Utils.EVENT.CLICK, () => {
+ cardBoxBg.show()
+ cardBoxBg.moveForeground()
+ topView.changeTheme(false)
+ // 寮�鍚埛鍗¤瘑鍒�
+ screen.getCardStart()
+ })
+
+ btnEdit.on(dxui.Utils.EVENT.CLICK, () => {
+ btn.send(dxui.Utils.EVENT.CLICK)
+ })
+
+ deleteBtn.on(dxui.Utils.EVENT.CLICK, () => {
+ viewUtils.confirmOpen('localUserAddView.confirm', 'localUserAddView.confirmCard', () => {
+ localUserAddView.removeCard()
+ }, () => { })
+ })
+ }
+
+ if (item.title === 'localUserAddView.face') {
+ // userBox.height(220)
+ btn.on(dxui.Utils.EVENT.CLICK, () => {
+ if (!checkRequired()) {
+ return
+ }
+ dxui.loadMain(faceEnterView.screenMain)
+ })
+
+ btnEdit.on(dxui.Utils.EVENT.CLICK, () => {
+ if (!checkRequired()) {
+ return
+ }
+ dxui.loadMain(faceEnterView.screenMain)
+ })
+
+ // 浜鸿劯鍥剧墖
+ const facePreview = dxui.Button.build('facePreview', userBox)
+ item.facePreview = facePreview
+ facePreview.bgColor(0x000000)
+ facePreview.align(dxui.Utils.ALIGN.LEFT_MID, 180, 0)
+ const facePreviewLbl = dxui.Label.build('facePreviewLbl', facePreview)
+ facePreviewLbl.textFont(viewUtils.font(22))
+ facePreviewLbl.dataI18n = "localUserAddView.preview"
+ facePreview.on(dxui.Utils.EVENT.CLICK, () => {
+ facePreviewBox.show()
+ facePreviewBox.moveForeground()
+ })
+
+ const facePreviewBox = dxui.View.build('facePreviewBox', screenMain)
+ viewUtils._clearStyle(facePreviewBox)
+ facePreviewBox.hide()
+ facePreviewBox.setSize(screenMain.width(), screenMain.height())
+ facePreviewBox.on(dxui.Utils.EVENT.CLICK, () => {
+ facePreviewBox.hide()
+ })
+
+ const faceImg = dxui.Image.build('faceImg', facePreviewBox)
+ faceImg.align(dxui.Utils.ALIGN.CENTER, 0, 0)
+ item.faceImg = faceImg
+
+
+ deleteBtn.on(dxui.Utils.EVENT.CLICK, () => {
+ if (!checkRequired()) {
+ return
+ }
+ viewUtils.confirmOpen('localUserAddView.confirm', 'localUserAddView.confirmFace', () => {
+ localUserAddView.removeFace()
+ }, () => { })
+ })
+ }
+ } else if (item.type === 'dropdown') {
+ const dropdown = dxui.Dropdown.build(item.title, userBox)
+ item.dropdown = dropdown
+ dropdown.setSize(260, 50)
+ dropdown.align(dxui.Utils.ALIGN.RIGHT_MID, 0, 0)
+ dropdown.textFont(viewUtils.font(22))
+ dropdown.getList().textFont(viewUtils.font(22))
+ dropdown.setSymbol('/app/code/resource/image/down.png')
+ dropdown.on(dxui.Utils.EVENT.VALUE_CHANGED, () => {
+ localUserAddView.nowUser.type = dropdown.getSelected()
+ })
+ }
+ })
+
+ // 瀵嗙爜鐢熸垚椤�
+ const pwdBoxBg = dxui.View.build('pwdBoxBg', screenMain)
+ viewUtils._clearStyle(pwdBoxBg)
+ pwdBoxBg.bgColor(0x000000)
+ pwdBoxBg.bgOpa(50)
+ pwdBoxBg.setSize(screen.screenSize.width, screen.screenSize.height)
+ pwdBoxBg.scroll(false)
+ pwdBoxBg.hide()
+ pwdBoxBg.on(dxui.Utils.EVENT.CLICK, () => {
+ pwdBoxCloseBtn.send(dxui.Utils.EVENT.CLICK)
+ })
+
+ const pwdBox = dxui.View.build('pwdBox', pwdBoxBg)
+ viewUtils._clearStyle(pwdBox)
+ pwdBox.setSize(screen.screenSize.width, 694)
+ pwdBox.align(dxui.Utils.ALIGN.BOTTOM_MID, 0, 50)
+ pwdBox.bgColor(0xffffff)
+ pwdBox.radius(50)
+
+ const pwdBoxLbl = dxui.Label.build('pwdBoxLbl', pwdBox)
+ pwdBoxLbl.dataI18n = 'localUserAddView.pwdBoxLbl'
+ pwdBoxLbl.textFont(viewUtils.font(36))
+ pwdBoxLbl.align(dxui.Utils.ALIGN.TOP_MID, 0, 39)
+
+ const pwdBoxCloseBtn = viewUtils.imageBtn(pwdBox, 'pwdBoxCloseBtn', '/app/code/resource/image/close_small.png')
+ pwdBoxCloseBtn.align(dxui.Utils.ALIGN.TOP_RIGHT, -55, 18)
+ pwdBoxCloseBtn.on(dxui.Utils.EVENT.CLICK, () => {
+ pwdBoxBg.hide()
+ topView.changeTheme(true)
+ })
+
+ const pwdBoxContent = dxui.View.build('pwdBoxContent', pwdBox)
+ viewUtils._clearStyle(pwdBoxContent)
+ pwdBoxContent.setSize(650, 100)
+ pwdBoxContent.align(dxui.Utils.ALIGN.TOP_MID, 0, 172)
+ pwdBoxContent.flexFlow(dxui.Utils.FLEX_FLOW.ROW_WRAP)
+ pwdBoxContent.flexAlign(dxui.Utils.FLEX_ALIGN.SPACE_AROUND, dxui.Utils.FLEX_ALIGN.CENTER, dxui.Utils.FLEX_ALIGN.CENTER)
+
+ localUserAddView.pwdBoxContentItem = []
+ for (let i = 0; i < 6; i++) {
+ const pwdBoxContentItem = dxui.View.build('pwdBoxContentItem' + i, pwdBoxContent)
+ pwdBoxContentItem.setSize(78, 90)
+ pwdBoxContentItem.radius(13)
+ pwdBoxContentItem.borderWidth(1)
+ pwdBoxContentItem.setBorderColor(0xEAEAEA)
+
+ const pwdBoxContentItemLbl = dxui.Label.build('pwdBoxContentItemLbl' + i, pwdBoxContentItem)
+ pwdBoxContentItemLbl.textFont(viewUtils.font(30))
+ pwdBoxContentItemLbl.align(dxui.Utils.ALIGN.CENTER, 0, 0)
+ pwdBoxContentItemLbl.text('0')
+ localUserAddView.pwdBoxContentItem.push(pwdBoxContentItemLbl)
+ }
+
+ const pwdBoxSaveBtn = dxui.Button.build('pwdBoxSaveBtn', pwdBox)
+ pwdBoxSaveBtn.setSize(210, 60)
+ pwdBoxSaveBtn.align(dxui.Utils.ALIGN.TOP_LEFT, 87, 340)
+ pwdBoxSaveBtn.bgColor(0xEAEAEA)
+ pwdBoxSaveBtn.radius(10)
+ pwdBoxSaveBtn.on(dxui.Utils.EVENT.CLICK, () => {
+ localUserAddView.changePwd()
+ })
+
+ const pwdBoxSaveBtnLbl = dxui.Label.build('pwdBoxSaveBtnLbl', pwdBoxSaveBtn)
+ pwdBoxSaveBtnLbl.dataI18n = 'localUserAddView.pwdBoxSaveBtnLbl'
+ pwdBoxSaveBtnLbl.textFont(viewUtils.font(24))
+ pwdBoxSaveBtnLbl.align(dxui.Utils.ALIGN.CENTER, 0, 0)
+ pwdBoxSaveBtnLbl.textColor(0x000000)
+
+ const pwdBoxConfirmBtn = dxui.Button.build('pwdBoxConfirmBtn', pwdBox)
+ pwdBoxConfirmBtn.setSize(210, 60)
+ pwdBoxConfirmBtn.align(dxui.Utils.ALIGN.TOP_RIGHT, -76, 340)
+ pwdBoxConfirmBtn.bgColor(0x000000)
+ pwdBoxConfirmBtn.radius(10)
+ pwdBoxConfirmBtn.on(dxui.Utils.EVENT.CLICK, () => {
+ localUserAddView.addPwd(localUserAddView.pwdBoxContentFin)
+ pwdBoxCloseBtn.send(dxui.Utils.EVENT.CLICK)
+ })
+
+ const pwdBoxConfirmBtnLbl = dxui.Label.build('pwdBoxConfirmBtnLbl', pwdBoxConfirmBtn)
+ pwdBoxConfirmBtnLbl.dataI18n = 'localUserAddView.pwdBoxConfirmBtnLbl'
+ pwdBoxConfirmBtnLbl.textFont(viewUtils.font(24))
+ pwdBoxConfirmBtnLbl.align(dxui.Utils.ALIGN.CENTER, 0, 0)
+
+ // 璇诲彇鍗$墖涓�
+ const cardBoxBg = dxui.View.build('cardBoxBg', screenMain)
+ viewUtils._clearStyle(cardBoxBg)
+ cardBoxBg.setSize(screen.screenSize.width, screen.screenSize.height)
+ cardBoxBg.align(dxui.Utils.ALIGN.TOP_MID, 0, 0)
+ cardBoxBg.bgColor(0x000000)
+ cardBoxBg.bgOpa(50)
+ cardBoxBg.scroll(false)
+ cardBoxBg.hide()
+ cardBoxBg.on(dxui.Utils.EVENT.CLICK, () => {
+ cardBoxCloseBtn.send(dxui.Utils.EVENT.CLICK)
+ })
+
+ const cardBox = dxui.View.build('cardBox', cardBoxBg)
+ viewUtils._clearStyle(cardBox)
+ cardBox.setSize(screen.screenSize.width, 694)
+ cardBox.align(dxui.Utils.ALIGN.BOTTOM_MID, 0, 50)
+ cardBox.bgColor(0xffffff)
+ cardBox.radius(50)
+ cardBox.on(dxui.Utils.EVENT.CLICK, () => {
+ })
+
+ const cardBoxLbl = dxui.Label.build('cardBoxLbl', cardBox)
+ cardBoxLbl.dataI18n = 'localUserAddView.cardBoxLbl'
+ cardBoxLbl.textFont(viewUtils.font(36))
+ cardBoxLbl.align(dxui.Utils.ALIGN.TOP_MID, 0, 39)
+
+ const cardBoxCloseBtn = viewUtils.imageBtn(cardBox, 'cardBoxCloseBtn', '/app/code/resource/image/close_small.png')
+ cardBoxCloseBtn.align(dxui.Utils.ALIGN.TOP_RIGHT, -55, 18)
+ cardBoxCloseBtn.on(dxui.Utils.EVENT.CLICK, () => {
+ cardBoxBg.hide()
+ topView.changeTheme(true)
+ // 鍏抽棴鍒峰崱璇嗗埆
+ screen.endCardEnd()
+ })
+
+ const cardBoxInput = viewUtils.input(cardBox, 'localUserAddView.cardBoxInput', undefined, undefined, 'localUserAddView.cardBoxInput')
+ localUserAddView.cardBoxInput = cardBoxInput
+ cardBoxInput.align(dxui.Utils.ALIGN.TOP_MID, 0, 183)
+ cardBoxInput.setSize(630, 75)
+ cardBoxInput.on(dxui.Utils.EVENT.CLICK, () => {
+ cardBoxInput.align(dxui.Utils.ALIGN.TOP_MID, 0, 90)
+ pinyin.hideCb(() => {
+ cardBoxInput.align(dxui.Utils.ALIGN.TOP_MID, 0, 183)
+ })
+ })
+
+ const cardBoxResetBtn = dxui.Button.build('cardBoxResetBtn', cardBox)
+ cardBoxResetBtn.setSize(210, 60)
+ cardBoxResetBtn.align(dxui.Utils.ALIGN.TOP_LEFT, 87, 340)
+ cardBoxResetBtn.bgColor(0xEAEAEA)
+ cardBoxResetBtn.radius(10)
+ cardBoxResetBtn.on(dxui.Utils.EVENT.CLICK, () => {
+ cardBoxInput.text('')
+ })
+
+ const cardBoxResetBtnLbl = dxui.Label.build('cardBoxResetBtnLbl', cardBoxResetBtn)
+ cardBoxResetBtnLbl.dataI18n = 'localUserAddView.cardBoxResetBtnLbl'
+ cardBoxResetBtnLbl.textFont(viewUtils.font(24))
+ cardBoxResetBtnLbl.align(dxui.Utils.ALIGN.CENTER, 0, 0)
+ cardBoxResetBtnLbl.textColor(0x000000)
+
+ const cardBoxSaveBtn = dxui.Button.build('cardBoxSaveBtn', cardBox)
+ cardBoxSaveBtn.setSize(210, 60)
+ cardBoxSaveBtn.align(dxui.Utils.ALIGN.TOP_RIGHT, -76, 340)
+ cardBoxSaveBtn.bgColor(0x000000)
+ cardBoxSaveBtn.radius(10)
+ cardBoxSaveBtn.on(dxui.Utils.EVENT.CLICK, () => {
+ cardBoxCloseBtn.send(dxui.Utils.EVENT.CLICK)
+ if (cardBoxInput.text()) {
+ localUserAddView.addCard(cardBoxInput.text())
+ }
+ })
+
+ const cardBoxSaveBtnLbl = dxui.Label.build('cardBoxSaveBtnLbl', cardBoxSaveBtn)
+ cardBoxSaveBtnLbl.dataI18n = 'localUserAddView.cardBoxSaveBtnLbl'
+ cardBoxSaveBtnLbl.textFont(viewUtils.font(24))
+ cardBoxSaveBtnLbl.align(dxui.Utils.ALIGN.CENTER, 0, 0)
+
+ const deleteBtn = viewUtils.bottomBtn(screenMain, screenMain.id + 'deleteBtn', 'localUserAddView.delete', () => {
+ if (!checkRequired()) {
+ return
+ }
+
+ viewUtils.confirmOpen('localUserAddView.confirmDelete', 'localUserAddView.confirmDeleteContent', () => {
+ // 鍒犻櫎鐢ㄦ埛
+ const res = screen.deleteUser(localUserAddView.nowUser)
+ if (res) {
+ dxui.loadMain(localUserView.screenMain)
+ } else {
+ localUserAddView.statusPanel.fail()
+ }
+ }, () => { })
+
+ }, 0xEAEAEA, 0xEA0000)
+ deleteBtn.align(dxui.Utils.ALIGN.BOTTOM_MID, 0, -200)
+ localUserAddView.deleteBtn = deleteBtn
+ deleteBtn.hide()
+
+ const saveBtn = viewUtils.bottomBtn(screenMain, screenMain.id + 'saveBtn', 'localUserAddView.save', async () => {
+ if (!checkRequired()) {
+ return
+ }
+ let res = false
+ if (localUserAddView.deleteBtn.isHide()) {
+ // 鏂板鐢ㄦ埛
+ res = await screen.insertUser(localUserAddView.nowUser)
+ } else {
+ // 淇敼鐢ㄦ埛
+ res = screen.updateUser(localUserAddView.nowUser)
+ }
+
+ if (res === true) {
+ localUserAddView.statusPanel.success()
+ std.setTimeout(() => {
+ // 鎴愬姛杩斿洖涓婁竴灞傜晫闈�
+ dxui.loadMain(localUserView.screenMain)
+ }, 500)
+ } else {
+ if (typeof res === "string") {
+ localUserAddView.statusPanel.fail(res)
+ } else {
+ localUserAddView.statusPanel.fail()
+ }
+ }
+ })
+ saveBtn.align(dxui.Utils.ALIGN.BOTTOM_MID, 0, -83)
+ localUserAddView.saveBtn = saveBtn
+
+ localUserAddView.statusPanel = viewUtils.statusPanel(screenMain, 'localUserAddView.success', 'localUserAddView.fail')
+}
+
+localUserAddView.addID = function (id) {
+ localUserAddView.userInfo[0].input.text(id)
+ localUserAddView.nowUser.id = id
+}
+
+localUserAddView.removeID = function () {
+ localUserAddView.userInfo[0].input.text('')
+}
+
+localUserAddView.addName = function (name) {
+ localUserAddView.userInfo[1].input.text(name)
+ localUserAddView.nowUser.name = name
+}
+
+localUserAddView.removeName = function () {
+ localUserAddView.userInfo[1].input.text('')
+}
+
+localUserAddView.addIDCard = function (idCard) {
+ localUserAddView.userInfo[2].input.text(idCard)
+ localUserAddView.nowUser.idCard = idCard
+}
+
+localUserAddView.removeIDCard = function () {
+ localUserAddView.userInfo[2].input.text('')
+}
+
+localUserAddView.addFace = function (face) {
+ localUserAddView.userInfo[3].btnEdit.show()
+ localUserAddView.userInfo[3].btn.hide()
+
+ const faceImg = localUserAddView.userInfo[3].faceImg
+ faceImg.source(face)
+ faceImg.show()
+
+ // let header = dxui.Utils.GG.NativeDraw.lvImgDecoderGetInfo(face)
+ // let zoom = 60 / header.h * 256
+ // faceImg.obj.lvImgSetZoom(zoom)
+ // faceImg.obj.lvImgSetSizeMode(dxui.Utils.ENUM.LV_IMG_SIZE_MODE_REAL)
+ // faceImg.setSize(Math.ceil(zoom / 256 * header.w), 60)
+
+ localUserAddView.userInfo[3].deleteBtn.show()
+ localUserAddView.nowUser.face = face
+}
+
+localUserAddView.removeFace = function () {
+ localUserAddView.userInfo[3].btn.show()
+ localUserAddView.userInfo[3].btnEdit.hide()
+ localUserAddView.userInfo[3].deleteBtn.hide()
+ localUserAddView.userInfo[3].faceImg.hide()
+ if (localUserAddView.nowUser && localUserAddView.nowUser.face) {
+ delete localUserAddView.nowUser.face
+ }
+}
+
+localUserAddView.addPwd = function (pwd) {
+ localUserAddView.userInfo[4].btn.hide()
+ localUserAddView.userInfo[4].btnEdit.show()
+ localUserAddView.userInfo[4].deleteBtn.show()
+ localUserAddView.userInfo[4].pwdLbl.show()
+ localUserAddView.userInfo[4].pwdLbl.text(pwd)
+ localUserAddView.nowUser.pwd = pwd
+}
+
+localUserAddView.removePwd = function () {
+ localUserAddView.userInfo[4].btn.show()
+ localUserAddView.userInfo[4].btnEdit.hide()
+ localUserAddView.userInfo[4].deleteBtn.hide()
+ localUserAddView.userInfo[4].pwdLbl.hide()
+ if (localUserAddView.nowUser && localUserAddView.nowUser.pwd) {
+ delete localUserAddView.nowUser.pwd
+ }
+}
+
+localUserAddView.addCard = function (card) {
+ localUserAddView.userInfo[5].btn.hide()
+ localUserAddView.userInfo[5].btnEdit.show()
+ localUserAddView.userInfo[5].deleteBtn.show()
+ localUserAddView.userInfo[5].cardLbl.show()
+ localUserAddView.userInfo[5].cardLbl.text(card)
+ localUserAddView.nowUser.card = card
+}
+
+localUserAddView.removeCard = function () {
+ localUserAddView.userInfo[5].btn.show()
+ localUserAddView.userInfo[5].btnEdit.hide()
+ localUserAddView.userInfo[5].deleteBtn.hide()
+ localUserAddView.userInfo[5].cardLbl.hide()
+ if (localUserAddView.nowUser && localUserAddView.nowUser.card) {
+ delete localUserAddView.nowUser.card
+ }
+}
+
+localUserAddView.addType = function (type) {
+ localUserAddView.userInfo[6].dropdown.setSelected(type)
+}
+
+localUserAddView.changePwd = function () {
+ const randomPwd = Math.floor(Math.random() * 900000 + 100000).toString()
+ localUserAddView.pwdBoxContentFin = randomPwd
+ localUserAddView.pwdBoxContentItem.forEach((item, index) => {
+ item.text(randomPwd[index])
+ })
+}
+
+localUserAddView.isEdit = function (flag) {
+ localUserAddView.removeFace()
+ localUserAddView.removePwd()
+ localUserAddView.removeCard()
+ localUserAddView.removeID()
+ localUserAddView.removeName()
+ localUserAddView.removeIDCard()
+ if (flag) {
+ localUserAddView.saveBtn.align(dxui.Utils.ALIGN.BOTTOM_MID, 0, -53)
+ localUserAddView.deleteBtn.show()
+ localUserAddView.titleBox2.show()
+ } else {
+ localUserAddView.saveBtn.align(dxui.Utils.ALIGN.BOTTOM_MID, 0, -83)
+ localUserAddView.deleteBtn.hide()
+ localUserAddView.titleBox2.hide()
+ localUserAddView.nowUser = {}
+ }
+}
+
+// 妫�鏌ュ繀濉」
+function checkRequired() {
+ if (!localUserAddView.userInfo[0].input.text()) {
+ localUserAddView.statusPanel.fail("localUserAddView.requiredInfo")
+ return false
+ }
+ if (!localUserAddView.userInfo[1].input.text()) {
+ localUserAddView.statusPanel.fail("localUserAddView.requiredInfo")
+ return false
+ }
+ return true
+}
+
+function refreshType() {
+ switch (screen.getConfig()['base.language']) {
+ case 'CN':
+ localUserAddView.userInfo[6].dropdown.setOptions(dropdownData)
+ break;
+ case 'EN':
+ localUserAddView.userInfo[6].dropdown.setOptions(dropdownData2)
+ break;
+ default:
+ break;
+ }
+}
+
+export default localUserAddView
diff --git a/vf205_access/src/view/config/menu/localUserView.js b/vf205_access/src/view/config/menu/localUserView.js
new file mode 100644
index 0000000..3c0d986
--- /dev/null
+++ b/vf205_access/src/view/config/menu/localUserView.js
@@ -0,0 +1,315 @@
+import dxui from '../../../../dxmodules/dxUi.js'
+import viewUtils from "../../viewUtils.js"
+import topView from "../../topView.js"
+import configView from '../configView.js'
+import pinyin from '../../pinyin/pinyin.js'
+import localUserAddView from './localUser/localUserAddView.js'
+import faceEnterView from './localUser/faceEnterView.js'
+import screen from '../../../screen.js'
+const localUserView = {}
+localUserView.init = function () {
+ /**************************************************鍒涘缓灞忓箷*****************************************************/
+ const screenMain = dxui.View.build('localUserView', dxui.Utils.LAYER.MAIN)
+ localUserView.screenMain = screenMain
+ screenMain.scroll(false)
+ screenMain.bgColor(0xffffff)
+ screenMain.on(dxui.Utils.ENUM.LV_EVENT_SCREEN_LOADED, () => {
+ topView.changeTheme(true)
+
+ localUserView.nowPage = localUserView.nowPage ? localUserView.nowPage : 0
+ let users = screen.getUsers(localUserView.nowPage, 6)
+ while (users.data.length == 0 && localUserView.nowPage > 0) {
+ localUserView.nowPage -= 1
+ users = screen.getUsers(localUserView.nowPage, 6)
+ }
+ if (users.data.length > 0) {
+ // localUserView.initData([{ id: "1", name: '寮犱笁' }, { id: "2", name: '鏉庡洓' }, { id: "3", name: '鐜嬩簲' }, { id: "4", name: '璧靛叚' }, { id: "5", name: '瀛欎竷' }, { id: "6", name: '鍛ㄥ叓' }, { id: "7", name: '鍚翠節' }, { id: "8", name: '閮戝崄' }, { id: "9", name: '闄堝崄涓�' }, { id: "10", name: '璧靛崄浜�' }, { id: "11", name: '瀛欏崄涓�' }, { id: "12", name: '鍛ㄥ崄鍥�' }, { id: "13", name: '鍚村崄浜�' }, { id: "14", name: '閮戝崄鍏�' }, { id: "15", name: '闄堝崄涓�' }, { id: "16", name: '璧靛崄鍏�' }, { id: "17", name: '瀛欏崄涔�' }, { id: "20", name: '鍛ㄤ簩鍗�' },])
+ localUserView.initData(users.data)
+ } else {
+ localUserView.initData()
+ }
+ // 鍒锋柊鍒嗛〉淇℃伅
+ refreshPageInfo(users)
+ })
+
+ const titleBox = viewUtils.title(screenMain, configView.screenMain, 'localUserViewTitle', 'localUserView.title', () => { localUserView.nowPage = 0 })
+ titleBox.align(dxui.Utils.ALIGN.TOP_MID, 0, 70)
+
+ const empty = dxui.Image.build('empty', screenMain)
+ localUserView.empty = empty
+ empty.align(dxui.Utils.ALIGN.TOP_MID, 0, 218)
+ empty.source('/app/code/resource/image/empty.png')
+
+ const emptyLbl = dxui.Label.build('emptyLbl', screenMain)
+ localUserView.emptyLbl = emptyLbl
+ emptyLbl.textFont(viewUtils.font(26))
+ emptyLbl.align(dxui.Utils.ALIGN.TOP_MID, 0, 479)
+ emptyLbl.dataI18n = 'localUserView.empty'
+ emptyLbl.textColor(0x888888)
+
+ const userList = dxui.View.build('userList', screenMain)
+ viewUtils._clearStyle(userList)
+ localUserView.userList = userList
+ userList.setSize(screen.screenSize.width, 570)
+ userList.align(dxui.Utils.ALIGN.TOP_MID, 0, 142)
+ userList.flexFlow(dxui.Utils.FLEX_FLOW.ROW_WRAP)
+ userList.flexAlign(dxui.Utils.FLEX_ALIGN.START, dxui.Utils.FLEX_ALIGN.START, dxui.Utils.FLEX_ALIGN.START)
+ userList.obj.lvObjSetStylePadGap(5, dxui.Utils.ENUM._LV_STYLE_STATE_CMP_SAME)
+ userList.hide()
+
+ const searchBox = dxui.View.build('searchBox', userList)
+ viewUtils._clearStyle(searchBox)
+ searchBox.setSize(screen.screenSize.width, 76)
+ searchBox.bgOpa(0)
+ searchBox.borderWidth(1)
+ searchBox.setBorderColor(0xDEDEDE)
+ searchBox.obj.setStyleBorderSide(dxui.Utils.ENUM.LV_BORDER_SIDE_BOTTOM, 0)
+
+ const searchInput = viewUtils.input(searchBox, 'searchBoxInput', undefined, () => {
+ }, 'localUserView.search')
+ searchInput.setSize(screen.screenSize.width / 2, 60)
+ searchInput.align(dxui.Utils.ALIGN.LEFT_MID, 28, 0)
+
+ const searchBtn = dxui.Button.build('searchBtn', searchBox)
+ searchBtn.setSize(126, 44)
+ searchBtn.align(dxui.Utils.ALIGN.RIGHT_MID, -29, 0)
+ searchBtn.bgColor(0xF6FAFA)
+ searchBtn.radius(10)
+
+ searchBtn.on(dxui.Utils.EVENT.CLICK, () => {
+ const users = screen.getUsers(0, 6, searchInput.text(), searchInput.text())
+ if (users.data) {
+ localUserView.initData(users.data)
+ } else {
+ localUserView.initData([])
+ }
+ // pinyin.hide()
+ })
+
+ const searchBtnLbl = dxui.Label.build('searchBtnLbl', searchBtn)
+ searchBtnLbl.dataI18n = 'localUserView.searchBtn'
+ searchBtnLbl.textFont(viewUtils.font(26))
+ searchBtnLbl.textColor(0x05AA8D)
+ searchBtnLbl.align(dxui.Utils.ALIGN.CENTER, 0, 0)
+
+ localUserView.userItemList = []
+ for (let i = 0; i < 6; i++) {
+ const userItem = dxui.View.build('userItem' + i, userList)
+ viewUtils._clearStyle(userItem)
+ userItem.setSize(screen.screenSize.width, 76)
+ userItem.align(dxui.Utils.ALIGN.TOP_MID, 0, 0)
+ userItem.bgOpa(0)
+ userItem.borderWidth(1)
+ userItem.setBorderColor(0xDEDEDE)
+ userItem.obj.setStyleBorderSide(dxui.Utils.ENUM.LV_BORDER_SIDE_BOTTOM, 0)
+ userItem.hide()
+
+ const userItemId0 = dxui.Label.build('userItemId0' + i, userItem)
+ userItemId0.text('ID锛�')
+ userItemId0.textFont(viewUtils.font(26))
+ userItemId0.align(dxui.Utils.ALIGN.LEFT_MID, 28, 0)
+
+ const userItemId = dxui.Label.build('userItemId' + i, userItem)
+ userItemId.text(i + '')
+ userItemId.textFont(viewUtils.font(26))
+ userItemId.align(dxui.Utils.ALIGN.LEFT_MID, 80, 0)
+ userItemId.width(100)
+ userItemId.longMode(dxui.Utils.LABEL_LONG_MODE.SCROLL_CIRCULAR)
+
+ const userItemName = dxui.Label.build('userItemName' + i, userItem)
+ userItemName.text('')
+ userItemName.textFont(viewUtils.font(26))
+ userItemName.align(dxui.Utils.ALIGN.LEFT_MID, 220, 0)
+ userItemName.width(200)
+ userItemName.longMode(dxui.Utils.LABEL_LONG_MODE.SCROLL_CIRCULAR)
+
+ const userItemEdit = dxui.Button.build('userItemEdit' + i, userItem)
+ userItemEdit.setSize(126, 44)
+ userItemEdit.align(dxui.Utils.ALIGN.RIGHT_MID, -29, 0)
+ userItemEdit.bgColor(0xF6FAFA)
+ userItemEdit.radius(10)
+
+ userItemEdit.on(dxui.Utils.EVENT.CLICK, () => {
+ localUserAddView.isEdit(true)
+ dxui.loadMain(localUserAddView.screenMain)
+
+ let item = localUserView.userData.filter(item => {
+ return item.id === userItemId.text().replace('ID锛�', '')
+ })
+ if (item) {
+ item = item[0]
+ const voucher = screen.getVoucher(item.id)
+ Object.assign(item, voucher);
+ localUserAddView.nowUser = item
+
+ if (item.id) {
+ localUserAddView.addID(item.id)
+ }
+ if (item.name) {
+ localUserAddView.addName(item.name)
+ }
+ if (item.idCard) {
+ localUserAddView.addIDCard(item.idCard)
+ }
+ if (item.face) {
+ localUserAddView.addFace(item.face)
+ }
+ if (item.pwd) {
+ localUserAddView.addPwd(item.pwd)
+ }
+ if (item.card) {
+ localUserAddView.addCard(item.card)
+ }
+ localUserAddView.addType(item.type)
+ }
+ })
+
+ const userItemEditLbl = dxui.Label.build('userItemEditLbl' + i, userItemEdit)
+ userItemEditLbl.dataI18n = 'localUserView.edit'
+ userItemEditLbl.textFont(viewUtils.font(26))
+ userItemEditLbl.textColor(0x05AA8D)
+ userItemEditLbl.align(dxui.Utils.ALIGN.CENTER, 0, 0)
+
+ localUserView.userItemList.push({ userItem, userItemId, userItemName })
+ }
+
+ const pageNextBtn = dxui.Button.build('pageNextBtn', screenMain)
+ pageNextBtn.bgColor(0x000000)
+ localUserView.pageNextBtn = pageNextBtn
+ const pageNextLbl = dxui.Label.build('pageNextLbl', pageNextBtn)
+ pageNextLbl.text("鈫�")
+ pageNextBtn.align(dxui.Utils.ALIGN.BOTTOM_RIGHT, -20, -372)
+ pageNextBtn.textFont(viewUtils.font(20))
+ const pagePrevBtn = dxui.Button.build('pagePrevBtn', screenMain)
+ pagePrevBtn.bgColor(0x000000)
+ localUserView.pagePrevBtn = pagePrevBtn
+ const pagePrevLbl = dxui.Label.build('pagePrevLbl', pagePrevBtn)
+ pagePrevLbl.text("鈫�")
+ pagePrevBtn.align(dxui.Utils.ALIGN.BOTTOM_LEFT, 20, -372)
+ pagePrevBtn.textFont(viewUtils.font(20))
+
+ pageNextBtn.on(dxui.Utils.EVENT.CLICK, () => {
+ if (!localUserView.nowPage) {
+ localUserView.nowPage = 0
+ }
+ localUserView.pageNum += 1
+ const users = screen.getUsers(localUserView.pageNum, 6)
+ if (users.data) {
+ localUserView.initData(users.data)
+ } else {
+ localUserView.initData([])
+ }
+ refreshPageInfo(users)
+ })
+ pagePrevBtn.on(dxui.Utils.EVENT.CLICK, () => {
+ if (!localUserView.nowPage) {
+ localUserView.nowPage = 0
+ }
+ localUserView.pageNum -= 1
+ const users = screen.getUsers(localUserView.pageNum, 6)
+ if (users.data) {
+ localUserView.initData(users.data)
+ } else {
+ localUserView.initData([])
+ }
+ refreshPageInfo(users)
+ })
+
+ const pageSelect = dxui.Dropdown.build('pageSelect', screenMain)
+ localUserView.pageSelect = pageSelect
+ pageSelect.textFont(viewUtils.font(22))
+ pageSelect.getList().textFont(viewUtils.font(22))
+ pageSelect.setSize(150, 55)
+ pageSelect.setSymbol('/app/code/resource/image/down.png')
+ pageSelect.align(dxui.Utils.ALIGN.BOTTOM_MID, 0, -370)
+ pageSelect.on(dxui.Utils.EVENT.VALUE_CHANGED, () => {
+ localUserView.pageNum = pageSelect.getSelected()
+ const users = screen.getUsers(localUserView.pageNum, 6)
+ if (users.data) {
+ localUserView.initData(users.data)
+ } else {
+ localUserView.initData([])
+ }
+ refreshPageInfo(users)
+ })
+
+ const syncBtn = viewUtils.bottomBtn(screenMain, screenMain.id + 'syncBtn', 'localUserView.sync', () => {
+ }, 0xEAEAEA, 0x000000)
+ syncBtn.align(dxui.Utils.ALIGN.BOTTOM_MID, 0, -204)
+ localUserView.syncBtn = syncBtn
+ syncBtn.hide()
+
+ syncBtn.on(dxui.Utils.EVENT.CLICK, () => {
+ viewUtils.confirmOpen('localUserView.attention', 'localUserView.attentionContent', () => {
+ viewUtils.confirmOpen('localUserView.tip', 'localUserView.tipContent')
+ })
+ })
+
+ const addBtn = viewUtils.bottomBtn(screenMain, screenMain.id + 'addBtn', 'localUserView.add', () => {
+ localUserAddView.isEdit(false)
+ dxui.loadMain(localUserAddView.screenMain)
+ })
+ addBtn.align(dxui.Utils.ALIGN.BOTTOM_MID, 0, -83)
+}
+
+localUserView.initData = function (data) {
+ // 褰撳墠椤电殑浜哄憳淇℃伅
+ localUserView.userData = data
+ localUserView.refresh(data)
+}
+
+localUserView.refresh = function (data) {
+ if (data === undefined || data === null) {
+ localUserView.empty.show()
+ localUserView.emptyLbl.show()
+ localUserView.syncBtn.hide()
+ localUserView.userList.hide()
+ return
+ }
+
+ localUserView.userItemList.forEach(item => {
+ item.userItem.hide()
+ })
+
+ // 娓叉煋浜哄憳鍒楄〃
+ data.forEach((item, index) => {
+ if (index >= localUserView.userItemList.length) {
+ return
+ }
+ localUserView.userItemList[index].userItemId.text(item.id)
+ // 鏄剧ず濮撳悕鍜屼汉鍛樼被鍨�
+ let typeText = item.type == 1 ? '锛堜繚绠″憳锛�' : item.type == 2 ? '锛堢闀匡級' : ''
+ localUserView.userItemList[index].userItemName.text(item.name + typeText)
+ localUserView.userItemList[index].userItem.show()
+ })
+
+ localUserView.empty.hide()
+ localUserView.emptyLbl.hide()
+ // localUserView.syncBtn.show()
+ localUserView.userList.show()
+}
+
+function refreshPageInfo(users) {
+ if (users.currentPage == 1) {
+ localUserView.pagePrevBtn.disable(true)
+ localUserView.pagePrevBtn.hide()
+ } else {
+ localUserView.pagePrevBtn.disable(false)
+ localUserView.pagePrevBtn.show()
+ }
+ if (users.currentPage == users.totalPage || users.totalPage == 0) {
+ localUserView.pageNextBtn.disable(true)
+ localUserView.pageNextBtn.hide()
+ } else {
+ localUserView.pageNextBtn.disable(false)
+ localUserView.pageNextBtn.show()
+ }
+ if (users.totalPage == 0 || users.totalPage == 1) {
+ localUserView.pageSelect.hide()
+ } else {
+ localUserView.pageSelect.show()
+ }
+ localUserView.pageSelect.setOptions(Array.from({ length: users.totalPage }, (_, index) => String(index + 1)))
+ localUserView.pageSelect.setSelected(users.currentPage - 1)
+}
+export default localUserView
diff --git a/vf205_access/src/view/config/menu/networkSettingView.js b/vf205_access/src/view/config/menu/networkSettingView.js
new file mode 100644
index 0000000..8008c7d
--- /dev/null
+++ b/vf205_access/src/view/config/menu/networkSettingView.js
@@ -0,0 +1,441 @@
+import dxui from '../../../../dxmodules/dxUi.js'
+import std from '../../../../dxmodules/dxStd.js'
+import viewUtils from "../../viewUtils.js"
+import topView from "../../topView.js"
+import configView from '../configView.js'
+import i18n from "../../i18n.js"
+import screen from '../../../screen.js'
+
+const networkSettingView = {}
+networkSettingView.init = function () {
+ /**************************************************鍒涘缓灞忓箷*****************************************************/
+ const screenMain = dxui.View.build('networkSettingView', dxui.Utils.LAYER.MAIN)
+ networkSettingView.screenMain = screenMain
+ screenMain.scroll(false)
+ screenMain.bgColor(0xffffff)
+ screenMain.on(dxui.Utils.ENUM.LV_EVENT_SCREEN_LOADED, () => {
+ topView.changeTheme(true)
+ let devType = screen.getConfig()["sys.devType"]
+ let netTypes = []
+ netTypes = devType == 1 ? [i18n.t('networkSettingView.ethernet'), i18n.t('networkSettingView._4G')] : [i18n.t('networkSettingView.ethernet'), i18n.t('networkSettingView.wifi'), i18n.t('networkSettingView._4G')]
+ networkSettingView.netInfo[0].value = netTypes
+ networkSettingView.netInfo[0].dropdown.setOptions(networkSettingView.netInfo[0].value)
+ const configAll = screen.getConfig()
+ networkSettingView.changeNetType(configAll["net.type"] - 1)
+ networkSettingView.netInfo[0].dropdown.setSelected(configAll["net.type"] - 1)
+ networkSettingView.netInfo[1].dropdown.setOptions([configAll["net.ssid"]])
+ networkSettingView.netInfo[1].dropdown.setSelected(0)
+ networkSettingView.netInfo[2].input.text(configAll["net.psk"])
+ networkSettingView.netInfo[3].switch.select(configAll["net.dhcp"] == 2)
+ networkSettingView.netInfo[4].input.text(configAll["net.ip"])
+ networkSettingView.netInfo[5].input.text(configAll["net.mask"])
+ networkSettingView.netInfo[6].input.text(configAll["net.gateway"])
+ networkSettingView.netInfo[7].input.text(configAll["net.dns"].split(",")[0])
+ networkSettingView.netInfo[8].input.text(configAll["net.dns"].split(",")[1])
+ networkSettingView.netInfo[9].label.text(configAll["net.mac"])
+ })
+
+ screenMain.on(dxui.Utils.ENUM.LV_EVENT_SCREEN_UNLOADED, () => {
+ wifiListBoxClose.send(dxui.Utils.EVENT.CLICK)
+ })
+
+ const titleBox = viewUtils.title(screenMain, configView.screenMain, 'networkSettingViewTitle', 'networkSettingView.title')
+ titleBox.align(dxui.Utils.ALIGN.TOP_MID, 0, 70)
+
+
+ const networkSettingBox = dxui.View.build('networkSettingBox', screenMain)
+ viewUtils._clearStyle(networkSettingBox)
+ networkSettingBox.setSize(screen.screenSize.width, 830)
+ networkSettingBox.bgColor(0xeeeeee)
+ networkSettingBox.align(dxui.Utils.ALIGN.TOP_MID, 0, 142)
+ networkSettingBox.borderWidth(1)
+ networkSettingBox.setBorderColor(0xDEDEDE)
+ networkSettingBox.obj.setStyleBorderSide(dxui.Utils.ENUM.LV_BORDER_SIDE_TOP, 0)
+ networkSettingBox.bgOpa(0)
+ networkSettingBox.flexFlow(dxui.Utils.FLEX_FLOW.ROW_WRAP)
+ networkSettingBox.flexAlign(dxui.Utils.FLEX_ALIGN.CENTER, dxui.Utils.FLEX_ALIGN.START, dxui.Utils.FLEX_ALIGN.START)
+ networkSettingBox.obj.lvObjSetStylePadGap(0, dxui.Utils.ENUM._LV_STYLE_STATE_CMP_SAME)
+
+ networkSettingView.netInfo = [
+ {
+ title: 'networkSettingView.type',
+ value: [i18n.t('networkSettingView.ethernet'), i18n.t('networkSettingView.wifi'), i18n.t('networkSettingView._4G')],
+ type: 'dropdown',
+ obj: null,
+ dropdown: null
+ },
+ {
+ title: 'networkSettingView.wifiName',
+ value: [],
+ type: 'dropdown',
+ obj: null,
+ dropdown: null
+ },
+ {
+ title: 'networkSettingView.wifiPwd',
+ value: null,
+ type: 'input',
+ obj: null
+ },
+ {
+ title: 'networkSettingView.dhcp',
+ value: null,
+ type: 'switch',
+ obj: null
+ },
+ {
+ title: 'networkSettingView.ip',
+ value: null,
+ type: 'input',
+ obj: null
+ },
+ {
+ title: 'networkSettingView.mask',
+ value: null,
+ type: 'input',
+ obj: null
+ },
+ {
+ title: 'networkSettingView.gateway',
+ value: null,
+ type: 'input',
+ obj: null
+ },
+ {
+ title: 'networkSettingView.dns',
+ value: null,
+ type: 'input',
+ obj: null
+ },
+ {
+ title: 'networkSettingView.dns2',
+ value: null,
+ type: 'input',
+ obj: null
+ },
+ {
+ title: 'networkSettingView.mac',
+ value: 'DC-87-F2-97-3B-26',
+ type: 'label',
+ obj: null,
+ label: null
+ },
+ {
+ title: 'networkSettingView.status',
+ value: i18n.t('networkSettingView.networkUnconnected'),
+ type: 'label',
+ obj: null,
+ label: null
+ }
+ ]
+
+ networkSettingView.netInfo.forEach((item, index) => {
+ const networkSettingItem = dxui.View.build(networkSettingBox.id + item.title, networkSettingBox)
+ viewUtils._clearStyle(networkSettingItem)
+ item.obj = networkSettingItem
+ networkSettingItem.setSize(760, 76)
+ networkSettingItem.bgColor(0xffffff)
+ networkSettingItem.borderWidth(1)
+ networkSettingItem.setBorderColor(0xDEDEDE)
+ networkSettingItem.obj.setStyleBorderSide(dxui.Utils.ENUM.LV_BORDER_SIDE_BOTTOM, 0)
+
+ const title = dxui.Label.build(item.title, networkSettingItem)
+ title.textFont(viewUtils.font(26))
+ title.align(dxui.Utils.ALIGN.LEFT_MID, 0, 0)
+ title.dataI18n = item.title
+
+
+ if (item.type === 'input') {
+ const input = viewUtils.input(networkSettingItem, item.title + 'input', undefined, undefined, 'networkSettingView.input')
+ input.align(dxui.Utils.ALIGN.RIGHT_MID, 0, 0)
+ input.setSize(400, 60)
+ item.input = input
+ }
+
+ if (item.type === 'switch') {
+ const __switch = dxui.Switch.build(item.title + 'switch', networkSettingItem)
+ __switch.align(dxui.Utils.ALIGN.RIGHT_MID, 0, 0)
+ __switch.setSize(70, 35)
+ item.switch = __switch
+ }
+
+ if (item.type === 'dropdown') {
+ const dropdown = dxui.Dropdown.build(item.title + 'dropdown', networkSettingItem)
+ dropdown.align(dxui.Utils.ALIGN.RIGHT_MID, 0, 0)
+ dropdown.setSize(200, 60)
+ dropdown.textFont(viewUtils.font(26))
+ dropdown.getList().textFont(viewUtils.font(26))
+ dropdown.setSymbol('/app/code/resource/image/down.png')
+ dropdown.setOptions(item.value)
+ item.dropdown = dropdown
+
+ if (item.title === 'networkSettingView.type') {
+ dropdown.on(dxui.Utils.EVENT.VALUE_CHANGED, () => {
+ networkSettingView.changeNetType(dropdown.getSelected())
+ if(dropdown.getSelected() == 2) {
+ // screen.switchNetworkType(dropdown.getSelected() + 2)
+ } else {
+ screen.switchNetworkType(dropdown.getSelected() + 1)
+ }
+ })
+ }
+
+ if (item.title === 'networkSettingView.wifiName') {
+ dropdown.on(dxui.Utils.EVENT.CLICK, () => {
+ screen.netGetWifiSsidList()
+ wifiList.refresh()
+ wifiListBoxbg.moveForeground()
+ wifiListBoxbg.show()
+ })
+ }
+ }
+
+ if (item.type === 'label') {
+ const label = dxui.Label.build(item.title + 'label', networkSettingItem)
+ label.textFont(viewUtils.font(26))
+ label.align(dxui.Utils.ALIGN.RIGHT_MID, 0, 0)
+ label.text(item.value)
+ label.textColor(0x333333)
+ item.label = label
+ }
+
+ })
+
+ // wifi鍒楄〃
+ const wifiListBoxbg = dxui.View.build('wifiListBoxbg', screenMain)
+ viewUtils._clearStyle(wifiListBoxbg)
+ wifiListBoxbg.setSize(screen.screenSize.width, screen.screenSize.height)
+ wifiListBoxbg.bgColor(0x000000)
+ wifiListBoxbg.bgOpa(50)
+ wifiListBoxbg.hide()
+ wifiListBoxbg.on(dxui.Utils.EVENT.CLICK, () => {
+ wifiListBoxClose.send(dxui.Utils.EVENT.CLICK)
+ })
+
+ const wifiListBox = dxui.View.build('wifiListBox', wifiListBoxbg)
+ viewUtils._clearStyle(wifiListBox)
+ wifiListBox.setSize(520, 560)
+ wifiListBox.bgColor(0xffffff)
+ wifiListBox.radius(20)
+ wifiListBox.align(dxui.Utils.ALIGN.CENTER, 0, 0)
+
+ const wifiListBoxTitle = dxui.Label.build('wifiListBoxTitle', wifiListBox)
+ wifiListBoxTitle.textFont(viewUtils.font(28))
+ wifiListBoxTitle.align(dxui.Utils.ALIGN.TOP_MID, 0, 32)
+ wifiListBoxTitle.dataI18n = 'networkSettingView.wifiList'
+
+ const wifiListBoxClose = viewUtils.imageBtn(wifiListBox, 'wifiListBoxClose', '/app/code/resource/image/close_small.png')
+ wifiListBoxClose.align(dxui.Utils.ALIGN.TOP_RIGHT, -36, 30)
+ wifiListBoxClose.on(dxui.Utils.EVENT.CLICK, () => {
+ wifiListBoxbg.hide()
+ })
+
+ const closeBtn = dxui.Button.build('closeBtn', wifiListBox)
+ closeBtn.setSize(172, 50)
+ closeBtn.radius(10)
+ closeBtn.bgColor(0xEAEAEA)
+ closeBtn.align(dxui.Utils.ALIGN.BOTTOM_LEFT, 69, -53)
+ closeBtn.on(dxui.Utils.EVENT.CLICK, () => {
+ wifiListBoxClose.send(dxui.Utils.EVENT.CLICK)
+ })
+
+ const closeBtnText = dxui.Label.build('closeBtnText', closeBtn)
+ closeBtnText.textFont(viewUtils.font(24))
+ closeBtnText.dataI18n = 'networkSettingView.close'
+ closeBtnText.align(dxui.Utils.ALIGN.CENTER, 0, 0)
+ closeBtnText.textColor(0x000000)
+
+ const confirmBtn = dxui.Button.build('confirmBtn', wifiListBox)
+ confirmBtn.setSize(172, 50)
+ confirmBtn.radius(10)
+ confirmBtn.bgColor(0x000000)
+ confirmBtn.align(dxui.Utils.ALIGN.BOTTOM_RIGHT, -69, -53)
+ confirmBtn.on(dxui.Utils.EVENT.CLICK, () => {
+ wifiListBoxClose.send(dxui.Utils.EVENT.CLICK)
+ networkSettingView.netInfo[1].dropdown.setOptions([networkSettingView.selectedValue])
+ })
+
+ const confirmBtnText = dxui.Label.build('confirmBtnText', confirmBtn)
+ confirmBtnText.textFont(viewUtils.font(24))
+ confirmBtnText.dataI18n = 'networkSettingView.confirm'
+ confirmBtnText.align(dxui.Utils.ALIGN.CENTER, 0, 0)
+ confirmBtnText.textColor(0xffffff)
+ networkSettingView.wifiListData = []
+ networkSettingView.selectedValue = ''
+ networkSettingView.selectedItem = 0
+
+ const wifiList = viewUtils.cycleList(wifiListBox, 'wifiList', [440, 300], 5, (item) => {
+ const wifiItemLbl = dxui.Label.build(item.id + 'wifiItemLbl', item)
+ wifiItemLbl.align(dxui.Utils.ALIGN.LEFT_MID, 25, 0)
+ wifiItemLbl.textFont(viewUtils.font(26))
+ wifiItemLbl.textColor(0x888888)
+ wifiItemLbl.width(300)
+ wifiItemLbl.longMode(dxui.Utils.LABEL_LONG_MODE.SCROLL_CIRCULAR)
+ item.radius(10)
+ item.on(dxui.Utils.EVENT.CLICK, () => {
+ if (networkSettingView.selectedItem) {
+ networkSettingView.selectedItem.bgOpa(0)
+ }
+ networkSettingView.selectedItem = item
+ networkSettingView.selectedValue = wifiItemLbl.text()
+ item.bgColor(0xEAEAEA)
+ item.bgOpa(100)
+ })
+
+ const wifiItemImg = dxui.Image.build(item.id + 'wifi', item)
+ wifiItemImg.align(dxui.Utils.ALIGN.RIGHT_MID, -24, 0)
+ wifiItemImg.source('/app/code/resource/image/wifi.png')
+
+ const lockItemImg = dxui.Image.build(item.id + 'lock', item)
+ lockItemImg.align(dxui.Utils.ALIGN.RIGHT_MID, -55, 0)
+ lockItemImg.source('/app/code/resource/image/lock.png')
+
+ return { wifiItemLbl, wifiItemImg, lockItemImg }
+ }, (userdata, index) => {
+ const txt = networkSettingView.wifiListData[Math.abs((index % 5))]
+ if (txt) {
+ userdata.wifiItemLbl.text(txt)
+ userdata.wifiItemImg.show()
+ userdata.lockItemImg.show()
+ } else {
+ userdata.wifiItemLbl.text(' ')
+ userdata.wifiItemImg.hide()
+ userdata.lockItemImg.hide()
+ }
+ })
+ wifiList.align(dxui.Utils.ALIGN.TOP_MID, 0, 110)
+ wifiList.bgOpa(0)
+ networkSettingView.wifiList = wifiList
+
+ const saveBtn = viewUtils.bottomBtn(screenMain, screenMain.id + 'saveBtn', 'networkSettingView.save', () => {
+ // 鑾峰彇WiFi SSID锛屼紭鍏堜娇鐢ㄤ笅鎷夐�夋嫨鐨勫�硷紝濡傛灉娌℃湁鍒欎娇鐢ㄩ厤缃腑鐨勫��
+ let wifiSsid = networkSettingView.selectedValue || ""
+
+ let saveConfigData = {
+ "net": {
+ "type": networkSettingView.netInfo[0].dropdown.getSelected() + 1,
+ "dhcp": networkSettingView.netInfo[3].switch.isSelect() ? 2 : 1,
+ "ip": networkSettingView.netInfo[4].input.text(),
+ "mask": networkSettingView.netInfo[5].input.text(),
+ "gateway": networkSettingView.netInfo[6].input.text(),
+ "dns": networkSettingView.netInfo[7].input.text() + ',' + networkSettingView.netInfo[8].input.text(),
+ "psk": networkSettingView.netInfo[2].input.text(),
+ "ssid": wifiSsid
+ }
+ }
+ if (!networkSettingView.netInfo[3].switch.isSelect()) {
+ // 闈欐�乮p
+ if (networkSettingView.netInfo[0].dropdown.getSelected() + 1 == 1) {
+ // 浠ュお缃�
+ saveConfigData = {
+ "net": {
+ "type": networkSettingView.netInfo[0].dropdown.getSelected() + 1,
+ "dhcp": networkSettingView.netInfo[3].switch.isSelect() ? 2 : 1,
+ "ip": networkSettingView.netInfo[4].input.text(),
+ "mask": networkSettingView.netInfo[5].input.text(),
+ "gateway": networkSettingView.netInfo[6].input.text(),
+ "dns": networkSettingView.netInfo[7].input.text() + ',' + networkSettingView.netInfo[8].input.text(),
+ }
+ }
+ } else if (networkSettingView.netInfo[0].dropdown.getSelected() + 1 == 2) {
+ // WIFI
+ saveConfigData = {
+ "net": {
+ "type": networkSettingView.netInfo[0].dropdown.getSelected() + 1,
+ "dhcp": networkSettingView.netInfo[3].switch.isSelect() ? 2 : 1,
+ "ip": networkSettingView.netInfo[4].input.text(),
+ "mask": networkSettingView.netInfo[5].input.text(),
+ "gateway": networkSettingView.netInfo[6].input.text(),
+ "dns": networkSettingView.netInfo[7].input.text() + ',' + networkSettingView.netInfo[8].input.text(),
+ "psk": networkSettingView.netInfo[2].input.text(),
+ "ssid": wifiSsid
+ }
+ }
+ } else {
+ //4G
+ saveConfigData = {
+ "net": {
+ "type": 4,
+ }
+ }
+ }
+ } else {
+ // 鍔ㄦ�乮p
+ if (networkSettingView.netInfo[0].dropdown.getSelected() + 1 == 1) {
+ // 浠ュお缃�
+ saveConfigData = {
+ "net": {
+ "type": networkSettingView.netInfo[0].dropdown.getSelected() + 1,
+ "dhcp": networkSettingView.netInfo[3].switch.isSelect() ? 2 : 1,
+ }
+ }
+ } else if (networkSettingView.netInfo[0].dropdown.getSelected() + 1 == 2) {
+ // WIFI
+ saveConfigData = {
+ "net": {
+ "type": networkSettingView.netInfo[0].dropdown.getSelected() + 1,
+ "dhcp": networkSettingView.netInfo[3].switch.isSelect() ? 2 : 1,
+ "psk": networkSettingView.netInfo[2].input.text(),
+ "ssid": wifiSsid
+ }
+ }
+ } else {
+ //4G
+ saveConfigData = {
+ "net": {
+ "type": 4,
+ }
+ }
+ }
+ }
+ const res = screen.saveConfig(saveConfigData)
+ if (res === true) {
+ networkSettingView.statusPanel.success()
+ std.setTimeout(() => {
+ // 鎴愬姛杩斿洖涓婁竴灞傜晫闈�
+ dxui.loadMain(configView.screenMain)
+ }, 500)
+ } else {
+ networkSettingView.statusPanel.fail()
+ }
+ })
+ saveBtn.align(dxui.Utils.ALIGN.BOTTOM_MID, 0, -83)
+
+ networkSettingView.changeNetType(0)
+
+ networkSettingView.statusPanel = viewUtils.statusPanel(screenMain, 'networkSettingView.success', 'networkSettingView.fail')
+}
+
+// 0:浠ュお缃� 1:wifi 3:4G
+networkSettingView.changeNetType = function (type) {
+ if (type === 0) {
+ networkSettingView.netInfo[1].obj.hide()
+ networkSettingView.netInfo[2].obj.hide()
+ networkSettingView.netInfo[3].obj.show()
+ networkSettingView.netInfo[4].obj.show()
+ networkSettingView.netInfo[5].obj.show()
+ networkSettingView.netInfo[6].obj.show()
+ networkSettingView.netInfo[7].obj.show()
+ networkSettingView.netInfo[8].obj.show()
+ } else if (type === 1) {
+ networkSettingView.netInfo[1].obj.show()
+ networkSettingView.netInfo[2].obj.show()
+ networkSettingView.netInfo[3].obj.show()
+ networkSettingView.netInfo[4].obj.show()
+ networkSettingView.netInfo[5].obj.show()
+ networkSettingView.netInfo[6].obj.show()
+ networkSettingView.netInfo[7].obj.show()
+ networkSettingView.netInfo[8].obj.show()
+ } else {
+ networkSettingView.netInfo[1].obj.hide()
+ networkSettingView.netInfo[2].obj.hide()
+ networkSettingView.netInfo[3].obj.hide()
+ networkSettingView.netInfo[4].obj.hide()
+ networkSettingView.netInfo[5].obj.hide()
+ networkSettingView.netInfo[6].obj.hide()
+ networkSettingView.netInfo[7].obj.hide()
+ networkSettingView.netInfo[8].obj.hide()
+ }
+}
+
+export default networkSettingView
diff --git a/vf205_access/src/view/config/menu/recordQuery/recordQueryDetailView.js b/vf205_access/src/view/config/menu/recordQuery/recordQueryDetailView.js
new file mode 100644
index 0000000..0067ffe
--- /dev/null
+++ b/vf205_access/src/view/config/menu/recordQuery/recordQueryDetailView.js
@@ -0,0 +1,227 @@
+import dxui from '../../../../../dxmodules/dxUi.js'
+import viewUtils from "../../../viewUtils.js"
+import topView from "../../../topView.js"
+import recordQueryView from '../recordQueryView.js'
+import i18n from "../../../i18n.js"
+import screen from '../../../../screen.js'
+import logger from '../../../../../dxmodules/dxLogger.js'
+const recordQueryDetailView = {}
+recordQueryDetailView.init = function () {
+ /**************************************************鍒涘缓灞忓箷*****************************************************/
+ const screenMain = dxui.View.build('recordQueryDetailView', dxui.Utils.LAYER.MAIN)
+ recordQueryDetailView.screenMain = screenMain
+ screenMain.scroll(false)
+ screenMain.bgColor(0xffffff)
+ screenMain.on(dxui.Utils.ENUM.LV_EVENT_SCREEN_LOADED, () => {
+ topView.changeTheme(true)
+ fillInfo()
+ })
+ const titleBox = viewUtils.title(screenMain, recordQueryView.screenMain, 'recordQueryDetailViewTitle', 'recordQueryDetailView.title')
+ titleBox.align(dxui.Utils.ALIGN.TOP_MID, 0, 70)
+
+ const box = dxui.View.build(screenMain.id + 'box', screenMain)
+ viewUtils._clearStyle(box)
+ box.align(dxui.Utils.ALIGN.TOP_MID, 0, 150)
+ box.setSize(screen.screenSize.width, screen.screenSize.height - 150)
+ box.bgOpa(0)
+ box.flexFlow(dxui.Utils.FLEX_FLOW.ROW_WRAP)
+ box.flexAlign(dxui.Utils.FLEX_ALIGN.CENTER, dxui.Utils.FLEX_ALIGN.START, dxui.Utils.FLEX_ALIGN.START)
+ box.obj.lvObjSetStylePadGap(5, dxui.Utils.ENUM._LV_STYLE_STATE_CMP_SAME)
+ box.scroll(true)
+
+ recordQueryDetailView.info = [{
+ title: 'recordQueryDetailView.result',
+ key: 'result',
+ label: null
+ }, {
+ title: 'recordQueryDetailView.time',
+ key: 'time',
+ label: null
+ }, {
+ title: 'recordQueryDetailView.id',
+ key: 'userId',
+ label: null
+ }, {
+ title: 'recordQueryDetailView.name',
+ key: 'name',
+ label: null
+ }, {
+ title: 'recordQueryDetailView.idCard',
+ key: 'idCard',
+ label: null
+ }, {
+ title: 'recordQueryDetailView.face',
+ key: 'code',
+ label: null
+ }, {
+ title: 'recordQueryDetailView.secondId',
+ key: 'userId2',
+ label: null
+ }, {
+ title: 'recordQueryDetailView.secondName',
+ key: 'name2',
+ label: null
+ }, {
+ title: 'recordQueryDetailView.secondIdCard',
+ key: 'idCard2',
+ label: null
+ }, {
+ title: 'recordQueryDetailView.secondFace',
+ key: 'code2',
+ label: null
+ }]
+
+ recordQueryDetailView.info.forEach((item, index) => {
+ const itemBox = dxui.View.build(screenMain.id + '.' + index, box)
+ viewUtils._clearStyle(itemBox)
+ itemBox.setSize(760, 76)
+ itemBox.borderWidth(1)
+ itemBox.obj.setStyleBorderSide(dxui.Utils.ENUM.LV_BORDER_SIDE_BOTTOM, 0)
+ itemBox.setBorderColor(0x767676)
+
+ const titleLbl = dxui.Label.build(screenMain.id + 'titleLbl' + index, itemBox)
+ titleLbl.align(dxui.Utils.ALIGN.LEFT_MID, 0, 0)
+ titleLbl.textFont(viewUtils.font(26))
+ titleLbl.dataI18n = item.title
+
+ if ("recordQueryDetailView.face" == item.title || "recordQueryDetailView.secondFace" == item.title) {
+ itemBox.setSize(760, 260)
+ itemBox.scroll(false)
+ const faceImg = dxui.Image.build(screenMain.id + 'faceImg' + index, itemBox)
+ faceImg.align(dxui.Utils.ALIGN.RIGHT_MID, 0, 0)
+ item.face = faceImg
+ return
+ }
+
+ const valueLbl = dxui.Label.build(screenMain.id + 'valueLbl' + index, itemBox)
+ valueLbl.align(dxui.Utils.ALIGN.RIGHT_MID, 0, 0)
+ valueLbl.textFont(viewUtils.font(26))
+ valueLbl.textColor(0x333333)
+ item.label = valueLbl
+ })
+
+}
+
+function fillInfo () {
+ let extra
+ try {
+ extra = JSON.parse(recordQueryView.nowRecord.extra)
+ } catch (error) {
+ logger.error("娌℃湁棰濆瀛楁璺宠繃")
+ }
+
+ let extra2
+ try {
+ extra2 = JSON.parse(recordQueryView.nowRecord.extra2)
+ } catch (error) {
+ logger.error("娌℃湁绗簩鐢ㄦ埛棰濆瀛楁璺宠繃")
+ }
+
+ const language = screen.getConfig(["base.language"])
+ recordQueryDetailView.info.forEach((item, index) => {
+ switch (item.key) {
+ case 'userId':
+ item.label.text((recordQueryView.nowRecord.userId || ' '))
+ break;
+ case 'name':
+ if (extra && extra.name) {
+ item.label.text(extra.name)
+ } else {
+ item.label.text(" ")
+ }
+ break;
+ case 'idCard':
+ if (extra && extra.idCard) {
+ item.label.text(extra.idCard)
+ } else {
+ item.label.text(" ")
+ }
+ break;
+ case 'userId2':
+ item.label.text((recordQueryView.nowRecord.userId2 || ' '))
+ break;
+ case 'name2':
+ if (extra2 && extra2.name) {
+ item.label.text(extra2.name)
+ } else {
+ item.label.text(" ")
+ }
+ break;
+ case 'idCard2':
+ if (extra2 && extra2.idCard) {
+ item.label.text(extra2.idCard)
+ } else {
+ item.label.text(" ")
+ }
+ break;
+ case 'time':
+ const t = new Date(recordQueryView.nowRecord[item.key] * 1000)
+ // 琛ラ浂鍑芥暟
+ const pad = (n) => n < 10 ? `0${n}` : n;
+ item.label.text(`${t.getFullYear()}-${pad(t.getMonth() + 1)}-${pad(t.getDate())} ${pad(t.getHours())}:${pad(t.getMinutes())}:${pad(t.getSeconds())}`)
+ break;
+ case 'result':
+ let msg = ""
+ if (recordQueryView.nowRecord.message === "姘斾綋娴撳害涓嶅悎鏍�") {
+ msg = "姘斾綋娴撳害涓嶅悎鏍�"
+ } else if (recordQueryView.nowRecord.message === "鍙屼汉璁よ瘉瓒呮椂") {
+ msg = "鍙屼汉璁よ瘉瓒呮椂"
+ } else {
+ switch (recordQueryView.nowRecord.type) {
+ case "200":
+ msg = i18n.t('recordQueryView.card')
+ break;
+ case "300":
+ msg = i18n.t('recordQueryView.face')
+ break;
+ case "400":
+ msg = i18n.t('recordQueryView.password')
+ break;
+ case "100":
+ msg = i18n.t('recordQueryView.qrcode')
+ break;
+ case "101":
+ msg = i18n.t('recordQueryView.qrcode')
+ break;
+ case "103":
+ msg = i18n.t('recordQueryView.qrcode')
+ break;
+ default:
+ break;
+ }
+ msg += language === 'CN' ? "" : " "
+ if (recordQueryView.nowRecord.result == 0) {
+ msg += i18n.t('recordQueryView.success')
+ } else {
+ msg += i18n.t('recordQueryView.fail')
+ }
+ }
+ item.label.text(msg)
+ break;
+ case 'code':
+ // 绗竴鐢ㄦ埛浜鸿劯鎶撴媿
+ if (recordQueryView.nowRecord.type == "300") {
+ let src = recordQueryView.nowRecord.code || `/app/data/passRecord/${recordQueryView.nowRecord.userId ? recordQueryView.nowRecord.userId : "undefined"}_${recordQueryView.nowRecord.time}_1.jpg`
+ item.face.show()
+ item.face.source(src)
+ } else {
+ item.face.hide()
+ }
+ break;
+ case 'code2':
+ // 绗簩鐢ㄦ埛浜鸿劯鎶撴媿
+ if (recordQueryView.nowRecord.type == "300" && recordQueryView.nowRecord.userId2) {
+ let src = recordQueryView.nowRecord.code2 || `/app/data/passRecord/${recordQueryView.nowRecord.userId2}_${recordQueryView.nowRecord.time}_2.jpg`
+ item.face.show()
+ item.face.source(src)
+ } else {
+ item.face.hide()
+ }
+ break;
+ default:
+ break;
+ }
+ })
+}
+
+export default recordQueryDetailView
diff --git a/vf205_access/src/view/config/menu/recordQueryView.js b/vf205_access/src/view/config/menu/recordQueryView.js
new file mode 100644
index 0000000..e1a7c67
--- /dev/null
+++ b/vf205_access/src/view/config/menu/recordQueryView.js
@@ -0,0 +1,276 @@
+import dxui from '../../../../dxmodules/dxUi.js'
+import viewUtils from "../../viewUtils.js"
+import topView from "../../topView.js"
+import configView from '../configView.js'
+import i18n from "../../i18n.js"
+import screen from '../../../screen.js'
+import recordQueryDetailView from './recordQuery/recordQueryDetailView.js'
+const recordQueryView = {}
+recordQueryView.init = function () {
+ /**************************************************鍒涘缓灞忓箷*****************************************************/
+ const screenMain = dxui.View.build('recordQueryView', dxui.Utils.LAYER.MAIN)
+ recordQueryView.screenMain = screenMain
+ screenMain.scroll(false)
+ screenMain.bgColor(0xffffff)
+ screenMain.on(dxui.Utils.ENUM.LV_EVENT_SCREEN_LOADED, () => {
+ topView.changeTheme(true)
+ refreshRecordList(recordQueryView.nowPage ? recordQueryView.nowPage : 0, 6)
+ })
+
+ const empty = dxui.Image.build(screenMain.id + 'empty', screenMain)
+ recordQueryView.empty = empty
+ empty.source('/app/code/resource/image/empty.png')
+ empty.align(dxui.Utils.ALIGN.CENTER, 0, 0)
+ empty.hide()
+
+ const titleBox = viewUtils.title(screenMain, configView.screenMain, 'recordQueryViewTitle', 'recordQueryView.title', () => { recordQueryView.nowPage = 0 })
+ titleBox.align(dxui.Utils.ALIGN.TOP_MID, 0, 70)
+
+ const box = dxui.View.build(screenMain.id + 'box', screenMain)
+ viewUtils._clearStyle(box)
+ box.align(dxui.Utils.ALIGN.TOP_MID, 0, 150)
+ box.setSize(screen.screenSize.width, 1000)
+ box.bgOpa(0)
+ box.flexFlow(dxui.Utils.FLEX_FLOW.ROW_WRAP)
+ box.flexAlign(dxui.Utils.FLEX_ALIGN.CENTER, dxui.Utils.FLEX_ALIGN.START, dxui.Utils.FLEX_ALIGN.START)
+ box.obj.lvObjSetStylePadGap(5, dxui.Utils.ENUM._LV_STYLE_STATE_CMP_SAME)
+
+ recordQueryView.items = []
+ for (let i = 0; i < 6; i++) {
+ const item = dxui.View.build(box.id + 'item' + i, box)
+ viewUtils._clearStyle(item)
+ item.setSize(760, 160)
+ item.bgOpa(0)
+ item.borderWidth(1)
+ item.obj.setStyleBorderSide(dxui.Utils.ENUM.LV_BORDER_SIDE_BOTTOM, 0)
+ item.setBorderColor(0x767676)
+
+ const name = dxui.Label.build(item.id + 'name' + i, item)
+ name.align(dxui.Utils.ALIGN.TOP_LEFT, 0, 5)
+ name.textFont(viewUtils.font(24))
+
+ const code = dxui.Label.build(item.id + 'code' + i, item)
+ code.align(dxui.Utils.ALIGN.TOP_LEFT, 0, 40)
+ code.textFont(viewUtils.font(24))
+ code.dataI18n = 'recordQueryView.code'
+
+ const codeValue = dxui.Label.build(item.id + 'codeValue' + i, item)
+ codeValue.align(dxui.Utils.ALIGN.TOP_LEFT, 0, 40)
+ codeValue.textFont(viewUtils.font(24))
+ codeValue.dataI18n = 'recordQueryView.codeValue'
+
+ const time = dxui.Label.build(item.id + 'time' + i, item)
+ time.align(dxui.Utils.ALIGN.TOP_LEFT, 0, 75)
+ time.textFont(viewUtils.font(24))
+ time.dataI18n = 'recordQueryView.time'
+
+ const timeValue = dxui.Label.build(item.id + 'timeValue' + i, item)
+ timeValue.align(dxui.Utils.ALIGN.TOP_LEFT, 0, 75)
+ timeValue.textFont(viewUtils.font(24))
+ timeValue.dataI18n = 'recordQueryView.timeValue'
+
+ const result = dxui.Label.build(item.id + 'result' + i, item)
+ result.align(dxui.Utils.ALIGN.TOP_LEFT, 0, 110)
+ result.textFont(viewUtils.font(24))
+ result.dataI18n = 'recordQueryView.result'
+
+ const resultValue = dxui.Label.build(item.id + 'resultValue' + i, item)
+ resultValue.align(dxui.Utils.ALIGN.TOP_LEFT, 0, 110)
+ resultValue.textFont(viewUtils.font(24))
+ resultValue.dataI18n = 'recordQueryView.resultValue'
+
+ const moreBtn = dxui.Button.build(item.id + 'btn' + i, item)
+ moreBtn.align(dxui.Utils.ALIGN.TOP_RIGHT, 0, 10)
+ const moreBtnLbl = dxui.Label.build(item.id + 'btnLbl' + i, moreBtn)
+ moreBtnLbl.textFont(viewUtils.font(24))
+ moreBtnLbl.text('璇︽儏')
+
+ moreBtn.on(dxui.Utils.EVENT.CLICK, () => {
+ recordQueryView.nowRecord = recordQueryView.recordData.data[i]
+ dxui.loadMain(recordQueryDetailView.screenMain)
+ })
+
+ recordQueryView.items.push({
+ item,
+ name,
+ id: codeValue,
+ idLbl: code,
+ time: timeValue,
+ timeLbl: time,
+ result: resultValue,
+ resultLbl: result
+ })
+ }
+
+ const pageNextBtn = dxui.Button.build(screenMain.id + 'pageNextBtn', screenMain)
+ recordQueryView.pageNextBtn = pageNextBtn
+ pageNextBtn.bgColor(0x000000)
+ const pageNextLbl = dxui.Label.build(screenMain.id + 'pageNextLbl', pageNextBtn)
+ pageNextLbl.text("鈫�")
+ pageNextBtn.align(dxui.Utils.ALIGN.BOTTOM_RIGHT, -20, -52)
+ pageNextBtn.textFont(viewUtils.font(20))
+ const pagePrevBtn = dxui.Button.build(screenMain.id + 'pagePrevBtn', screenMain)
+ recordQueryView.pagePrevBtn = pagePrevBtn
+ pagePrevBtn.bgColor(0x000000)
+ const pagePrevLbl = dxui.Label.build(screenMain.id + 'pagePrevLbl', pagePrevBtn)
+ pagePrevLbl.text("鈫�")
+ pagePrevBtn.align(dxui.Utils.ALIGN.BOTTOM_LEFT, 20, -52)
+ pagePrevBtn.textFont(viewUtils.font(20))
+ const pageSelect = dxui.Dropdown.build(screenMain.id + 'pageSelect', screenMain)
+ recordQueryView.pageSelect = pageSelect
+ pageSelect.textFont(viewUtils.font(22))
+ pageSelect.getList().textFont(viewUtils.font(22))
+ pageSelect.setSize(150, 55)
+ pageSelect.setSymbol('/app/code/resource/image/down.png')
+ pageSelect.align(dxui.Utils.ALIGN.BOTTOM_MID, 0, -50)
+ pageSelect.setOptions([])
+ pageSelect.on(dxui.Utils.EVENT.VALUE_CHANGED, () => {
+ refreshRecordList(pageSelect.getSelected(), 6)
+ recordQueryView.nowPage = pageSelect.getSelected()
+ })
+ pageNextBtn.on(dxui.Utils.EVENT.CLICK, () => {
+ refreshRecordList(pageSelect.getSelected() + 1, 6)
+ if (!recordQueryView.nowPage) {
+ recordQueryView.nowPage = 0
+ }
+ recordQueryView.nowPage += 1
+ })
+ pagePrevBtn.on(dxui.Utils.EVENT.CLICK, () => {
+ refreshRecordList(pageSelect.getSelected() - 1, 6)
+ if (!recordQueryView.nowPage) {
+ recordQueryView.nowPage = 0
+ }
+ recordQueryView.nowPage -= 1
+ })
+}
+
+// 鍒锋柊鍒楄〃
+function refreshRecordList (page, size) {
+ const recordData = screen.getPassRecord(page, size)
+ recordQueryView.recordData = recordData
+
+ const data = recordData.data
+ const totalPage = recordData.totalPage
+ const totalSize = recordData.totalSize
+ const currentPage = recordData.currentPage
+ const language = screen.getConfig()['base.language']
+
+ if (currentPage == 1) {
+ recordQueryView.pagePrevBtn.disable(true)
+ recordQueryView.pagePrevBtn.hide()
+ } else {
+ recordQueryView.pagePrevBtn.disable(false)
+ recordQueryView.pagePrevBtn.show()
+ }
+ if (currentPage == totalPage || totalPage == 0) {
+ recordQueryView.pageNextBtn.disable(true)
+ recordQueryView.pageNextBtn.hide()
+ } else {
+ recordQueryView.pageNextBtn.disable(false)
+ recordQueryView.pageNextBtn.show()
+ }
+ if (totalPage == 0 || totalPage == 1) {
+ recordQueryView.pageSelect.hide()
+ } else {
+ recordQueryView.pageSelect.show()
+ }
+
+ recordQueryView.pageSelect.setOptions(Array.from({ length: totalPage }, (_, index) => String(index + 1)))
+ recordQueryView.pageSelect.setSelected(currentPage - 1)
+
+ if (!data || data.length == 0) {
+ recordQueryView.items.forEach(item => {
+ item.item.hide()
+ })
+ recordQueryView.empty.show()
+ return
+ } else {
+ recordQueryView.empty.hide()
+ }
+
+ recordQueryView.items.forEach((item, index) => {
+ if (!data[index]) {
+ item.item.hide()
+ } else {
+ item.item.show()
+ let extra
+ try {
+ extra = JSON.parse(data[index].extra)
+ } catch (error) {
+ }
+ let extra2
+ try {
+ extra2 = JSON.parse(data[index].extra2)
+ } catch (error) {
+ }
+ // 鏄剧ず濮撳悕
+ let nameText = ""
+ if (extra && extra.name) {
+ nameText = extra.name
+ } else {
+ nameText = i18n.t('recordQueryView.stranger')
+ }
+ if (data[index].userId2 && extra2 && extra2.name) {
+ nameText += " / " + extra2.name
+ }
+ item.name.text(nameText)
+ // 鏄剧ず浜哄憳缂栧彿
+ let idText = ":" + data[index].userId
+ if (data[index].userId2) {
+ idText += " / " + data[index].userId2
+ }
+ item.id.text(idText)
+ item.id.alignTo(item.idLbl, dxui.Utils.ALIGN.OUT_RIGHT_MID, 0, 0)
+
+ const t = new Date(data[index].time * 1000)
+
+
+ // 琛ラ浂鍑芥暟
+ const pad = (n) => n < 10 ? `0${n}` : n;
+
+ item.time.text(":" + `${t.getFullYear()}-${pad(t.getMonth() + 1)}-${pad(t.getDate())} ${pad(t.getHours())}:${pad(t.getMinutes())}:${pad(t.getSeconds())}`)
+ // item.time.text(":" + data[index].time)
+ item.time.alignTo(item.timeLbl, dxui.Utils.ALIGN.OUT_RIGHT_MID, 0, 0)
+
+ let msg = ""
+ // 妫�鏌ユ槸鍚︽槸鐗规畩娑堟伅瀵艰嚧鐨勫け璐�
+ if (data[index].message === "姘斾綋娴撳害涓嶅悎鏍�") {
+ msg = "姘斾綋娴撳害涓嶅悎鏍�"
+ } else if (data[index].message === "鍙屼汉璁よ瘉瓒呮椂") {
+ msg = "鍙屼汉璁よ瘉瓒呮椂"
+ } else {
+ switch (data[index].type) {
+ case "200":
+ msg = i18n.t('recordQueryView.card')
+ break;
+ case "300":
+ msg = i18n.t('recordQueryView.face')
+ break;
+ case "400":
+ msg = i18n.t('recordQueryView.password')
+ break;
+ case "100":
+ msg = i18n.t('recordQueryView.qrcode')
+ break;
+ case "101":
+ msg = i18n.t('recordQueryView.qrcode')
+ break;
+ case "103":
+ msg = i18n.t('recordQueryView.qrcode')
+ break;
+ default:
+ break;
+ }
+ msg += language === 'CN' ? "" : " "
+ if (data[index].result == 0) {
+ msg += i18n.t('recordQueryView.success')
+ } else {
+ msg += i18n.t('recordQueryView.fail')
+ }
+ }
+ item.result.text(":" + msg)
+ item.result.alignTo(item.resultLbl, dxui.Utils.ALIGN.OUT_RIGHT_MID, 0, 0)
+ }
+ })
+}
+export default recordQueryView
diff --git a/vf205_access/src/view/config/menu/systemSetting/displaySettingView.js b/vf205_access/src/view/config/menu/systemSetting/displaySettingView.js
new file mode 100644
index 0000000..94f66de
--- /dev/null
+++ b/vf205_access/src/view/config/menu/systemSetting/displaySettingView.js
@@ -0,0 +1,289 @@
+import dxui from '../../../../../dxmodules/dxUi.js'
+import std from '../../../../../dxmodules/dxStd.js'
+import viewUtils from "../../../viewUtils.js"
+import topView from "../../../topView.js"
+import systemSettingView from '../systemSettingView.js'
+import i18n from "../../../i18n.js"
+import screen from '../../../../screen.js'
+import logger from '../../../../../dxmodules/dxLogger.js'
+const displaySettingView = {}
+const languageData = ['CN', 'EN']
+const languageData2 = ['涓枃', '鑻辨枃']
+const themeModeData = ['鏍囧噯妯″紡', '绠�娲佹ā寮�']
+const themeModeData2 = ['StandardMode', 'SimpleMode']
+
+displaySettingView.init = function () {
+ /**************************************************鍒涘缓灞忓箷*****************************************************/
+ const screenMain = dxui.View.build('displaySettingView', dxui.Utils.LAYER.MAIN)
+ displaySettingView.screenMain = screenMain
+ screenMain.scroll(false)
+ screenMain.bgColor(0xffffff)
+ screenMain.on(dxui.Utils.ENUM.LV_EVENT_SCREEN_LOADED, () => {
+ topView.changeTheme(true)
+
+ refreshLanguage()
+
+ const configAll = screen.getConfig()
+ // 鑷姩璋冭妭灞忓箷浜害
+ displaySettingView.info[0].switch.select(configAll['base.brightnessAuto'] == 1)
+ if (configAll['base.brightnessAuto'] == 1) {
+ displaySettingView.info[1].slider.disable(true)
+ } else {
+ displaySettingView.info[1].slider.disable(false)
+ }
+ // 灞忓箷浜害
+ displaySettingView.info[1].slider.value(configAll['base.brightness'])
+ displaySettingView.info[1].slider.send(dxui.Utils.EVENT.VALUE_CHANGED)
+ // 鑷姩鍏冲睆
+ displaySettingView.info[2].switch.select(configAll['base.screenOff'] != 0)
+ // 鍏冲睆鏃堕棿
+ displaySettingView.info[3].input.text(configAll['base.screenOff'] + '')
+ // 鑷姩灞忎繚
+ displaySettingView.info[4].switch.select(configAll['base.screensaver'] != 0)
+ // 灞忎繚鏃堕棿
+ displaySettingView.info[5].input.text(configAll['base.screensaver'] + '')
+ // 鏄剧ずIP
+ displaySettingView.info[6].switch.select(configAll['base.showIp'] == 1)
+ // 鏄剧ずSN
+ displaySettingView.info[7].switch.select(configAll['base.showSn'] == 1)
+ // 鏄剧ず灏忕▼搴忕爜
+ displaySettingView.info[9].switch.select(configAll['base.showProgramCode'] == 1)
+ // app妯″紡
+ displaySettingView.info[10].dropdown.setSelected(configAll['base.appMode'])
+ })
+
+ const titleBox = viewUtils.title(screenMain, systemSettingView.screenMain, 'displaySettingViewTitle', 'systemSettingView.displaySetting')
+ titleBox.align(dxui.Utils.ALIGN.TOP_MID, 0, 70)
+
+ displaySettingView.info = [
+ {
+ title: "systemSettingView.autoAdjustScreenBrightness",
+ type: 'switch',
+ },
+ {
+ title: "systemSettingView.screenBrightness",
+ type: 'slider',
+ unit: '%'
+ },
+ {
+ title: "systemSettingView.autoTurnOffScreen",
+ type: 'switch',
+ },
+ {
+ title: "systemSettingView.autoTurnOffScreenTime",
+ type: 'input',
+ i18nUnit: 'systemSettingView.min'
+ },
+ {
+ title: "systemSettingView.autoScreenSaver",
+ type: 'switch',
+ },
+ {
+ title: "systemSettingView.autoScreenSaverTime",
+ type: 'input',
+ i18nUnit: 'systemSettingView.min'
+ },
+ {
+ title: "systemSettingView.displayIp",
+ type: 'switch',
+ },
+ {
+ title: "systemSettingView.displayDeviceSn",
+ type: 'switch',
+ },
+ {
+ title: "systemSettingView.language",
+ type: 'dropdown',
+ },
+ {
+ title: "systemSettingView.displayCode",
+ type: 'switch',
+ },
+ {
+ title: "systemSettingView.themeMode",
+ type: 'dropdown',
+ },
+ ]
+
+ const displaySettingBox = dxui.View.build('displaySettingBox', screenMain)
+ viewUtils._clearStyle(displaySettingBox)
+ displaySettingBox.align(dxui.Utils.ALIGN.TOP_MID, 0, 140)
+ displaySettingBox.setSize(screen.screenSize.width, 850)
+ displaySettingBox.bgOpa(0)
+ displaySettingBox.flexFlow(dxui.Utils.FLEX_FLOW.ROW_WRAP)
+ displaySettingBox.flexAlign(dxui.Utils.FLEX_ALIGN.CENTER, dxui.Utils.FLEX_ALIGN.START, dxui.Utils.FLEX_ALIGN.START)
+ displaySettingBox.obj.lvObjSetStylePadGap(0, dxui.Utils.ENUM._LV_STYLE_STATE_CMP_SAME)
+ displaySettingBox.borderWidth(1)
+ displaySettingBox.setBorderColor(0xDEDEDE)
+ displaySettingBox.obj.setStyleBorderSide(dxui.Utils.ENUM.LV_BORDER_SIDE_TOP, 0)
+
+ displaySettingView.info.forEach(item => {
+ const itemBox = dxui.View.build(item.title, displaySettingBox)
+ viewUtils._clearStyle(itemBox)
+ itemBox.setSize(760, 76)
+ itemBox.borderWidth(1)
+ itemBox.setBorderColor(0xDEDEDE)
+ itemBox.obj.setStyleBorderSide(dxui.Utils.ENUM.LV_BORDER_SIDE_BOTTOM, 0)
+
+ const itemLabel = dxui.Label.build(item.title + 'Label', itemBox)
+ itemLabel.dataI18n = item.title
+ itemLabel.align(dxui.Utils.ALIGN.LEFT_MID, 0, 0)
+ itemLabel.textFont(viewUtils.font(26))
+
+ if (item.unit) {
+ const unitLabel = dxui.Label.build(item.title + 'UnitLabel', itemBox)
+ unitLabel.text(item.unit)
+ unitLabel.align(dxui.Utils.ALIGN.RIGHT_MID, 0, 0)
+ unitLabel.textFont(viewUtils.font(26))
+ }
+
+ if (item.i18nUnit) {
+ const unitLabel = dxui.Label.build(item.title + 'UnitLabel', itemBox)
+ unitLabel.dataI18n = item.i18nUnit
+ unitLabel.align(dxui.Utils.ALIGN.RIGHT_MID, 0, 0)
+ unitLabel.textFont(viewUtils.font(26))
+ }
+
+ switch (item.type) {
+ case 'switch':
+ const __switch = dxui.Switch.build(item.title + 'switch', itemBox)
+ __switch.align(dxui.Utils.ALIGN.RIGHT_MID, 0, 0)
+ __switch.setSize(70, 35)
+ item.switch = __switch
+
+ if (item.title == 'systemSettingView.autoAdjustScreenBrightness') {
+ __switch.on(dxui.Utils.EVENT.VALUE_CHANGED, () => {
+ screen.saveConfig({
+ base: {
+ brightnessAuto: __switch.isSelect() ? 1 : 0
+ }
+ })
+ if (__switch.isSelect()) {
+ displaySettingView.info[1].slider.disable(true)
+ } else {
+ displaySettingView.info[1].slider.disable(false)
+ }
+ })
+ }
+
+ if (item.title == 'systemSettingView.autoTurnOffScreen') {
+ __switch.on(dxui.Utils.EVENT.VALUE_CHANGED, () => {
+ if (!__switch.isSelect()) {
+ displaySettingView.info[3].input.text("0")
+ }
+ })
+ }
+
+ if (item.title == 'systemSettingView.autoScreenSaver') {
+ __switch.on(dxui.Utils.EVENT.VALUE_CHANGED, () => {
+ if (!__switch.isSelect()) {
+ displaySettingView.info[5].input.text("0")
+ }
+ })
+ }
+
+ break;
+ case 'input':
+ const input = viewUtils.input(itemBox, item.title + 'input', undefined, undefined, undefined)
+ input.align(dxui.Utils.ALIGN.RIGHT_MID, -60, 0)
+ input.setSize(100, 55)
+ item.input = input
+ break;
+ case 'dropdown':
+ const dropdown = dxui.Dropdown.build(item.title + 'dropdown', itemBox)
+ dropdown.align(dxui.Utils.ALIGN.RIGHT_MID, 0, 0)
+ dropdown.textFont(viewUtils.font(26))
+ dropdown.getList().textFont(viewUtils.font(26))
+ dropdown.setSize(230,55)
+ dropdown.setSymbol('/app/code/resource/image/down.png')
+ item.dropdown = dropdown
+ break;
+ case 'slider':
+ const sliderLabel = dxui.Label.build(item.title + 'sliderLabel', itemBox)
+ sliderLabel.align(dxui.Utils.ALIGN.RIGHT_MID, -30, 0)
+ sliderLabel.width(50)
+ sliderLabel.text('0')
+ sliderLabel.textFont(viewUtils.font(26))
+ sliderLabel.textAlign(dxui.Utils.TEXT_ALIGN.RIGHT)
+
+ const slider = dxui.Slider.build(item.title + 'slider', itemBox)
+ slider.align(dxui.Utils.ALIGN.RIGHT_MID, -90, 0)
+ slider.width(150)
+ slider.range(0, 100)
+
+ slider.on(dxui.Utils.EVENT.VALUE_CHANGED, () => {
+ sliderLabel.text(slider.value() + '')
+ if (screen.getConfig()['base.brightness'] == slider.value()) {
+ return
+ }
+ screen.saveConfig({
+ base: {
+ brightness: slider.value()
+ }
+ })
+ })
+ item.slider = slider
+ break;
+ }
+
+ })
+
+ const saveBtn = viewUtils.bottomBtn(screenMain, screenMain.id + 'saveBtn', 'systemSettingView.save', () => {
+ const saveConfigData = {
+ base: {
+ language: languageData[displaySettingView.info[8].dropdown.getSelected()],
+ brightnessAuto: displaySettingView.info[0].switch.isSelect() ? 1 : 0,
+ brightness: displaySettingView.info[1].slider.value(),
+ screenOff: parseInt(displaySettingView.info[3].input.text()),
+ screensaver: parseInt(displaySettingView.info[5].input.text()),
+ showIp: displaySettingView.info[6].switch.isSelect() ? 1 : 0,
+ showSn: displaySettingView.info[7].switch.isSelect() ? 1 : 0,
+ showProgramCode: displaySettingView.info[9].switch.isSelect() ? 1 : 0,
+ appMode: displaySettingView.info[10].dropdown.getSelected(),
+ }
+ }
+
+ const res = screen.saveConfig(saveConfigData)
+ if (res === true) {
+ displaySettingView.statusPanel.success()
+ i18n.setLanguage(screen.getConfig()['base.language'])
+ refreshLanguage()
+ std.setTimeout(() => {
+ // 鎴愬姛杩斿洖涓婁竴灞傜晫闈�
+ dxui.loadMain(systemSettingView.screenMain)
+ }, 500)
+
+ if (displaySettingView.info[0].switch.isSelect()) {
+ displaySettingView.info[1].slider.disable(true)
+ } else {
+ displaySettingView.info[1].slider.disable(false)
+ }
+ } else {
+ displaySettingView.statusPanel.fail()
+ }
+ })
+ saveBtn.align(dxui.Utils.ALIGN.BOTTOM_MID, 0, -83)
+
+ displaySettingView.statusPanel = viewUtils.statusPanel(screenMain, 'systemSettingView.success', 'systemSettingView.fail')
+}
+
+function refreshLanguage() {
+ switch (screen.getConfig()['base.language']) {
+ case 'CN':
+ displaySettingView.info[8].dropdown.setOptions(languageData2)
+ displaySettingView.info[8].dropdown.setSelected(0)
+ displaySettingView.info[10].dropdown.setOptions(themeModeData)
+ displaySettingView.info[10].dropdown.setSelected(0)
+ break;
+ case 'EN':
+ displaySettingView.info[8].dropdown.setOptions(languageData)
+ displaySettingView.info[8].dropdown.setSelected(1)
+ displaySettingView.info[10].dropdown.setOptions(themeModeData2)
+ displaySettingView.info[10].dropdown.setSelected(1)
+ break;
+ default:
+ break;
+ }
+}
+
+export default displaySettingView
diff --git a/vf205_access/src/view/config/menu/systemSetting/faceRecognitionSettingView.js b/vf205_access/src/view/config/menu/systemSetting/faceRecognitionSettingView.js
new file mode 100644
index 0000000..e50cf3c
--- /dev/null
+++ b/vf205_access/src/view/config/menu/systemSetting/faceRecognitionSettingView.js
@@ -0,0 +1,167 @@
+import dxui from '../../../../../dxmodules/dxUi.js'
+import std from '../../../../../dxmodules/dxStd.js'
+import viewUtils from "../../../viewUtils.js"
+import topView from "../../../topView.js"
+import i18n from "../../../i18n.js"
+import systemSettingView from '../systemSettingView.js'
+import screen from '../../../../screen.js'
+const faceRecognitionSettingView = {}
+faceRecognitionSettingView.init = function () {
+ /**************************************************鍒涘缓灞忓箷*****************************************************/
+ const screenMain = dxui.View.build('faceRecognitionSettingView', dxui.Utils.LAYER.MAIN)
+ faceRecognitionSettingView.screenMain = screenMain
+ screenMain.scroll(false)
+ screenMain.bgColor(0xffffff)
+ screenMain.on(dxui.Utils.ENUM.LV_EVENT_SCREEN_LOADED, () => {
+ topView.changeTheme(true)
+
+ const configAll = screen.getConfig()
+ // 浜鸿劯鐩镐技搴﹂槇鍊�
+ faceRecognitionSettingView.info[0].slider.value(configAll['face.similarity'] * 100)
+ faceRecognitionSettingView.info[0].slider.send(dxui.Utils.EVENT.VALUE_CHANGED)
+ // 娲讳綋妫�娴嬪紑鍏�
+ faceRecognitionSettingView.info[1].switch.select(configAll['face.livenessOff'] == 1)
+ // 娲讳綋妫�娴嬮槇鍊�
+ faceRecognitionSettingView.info[2].slider.value(configAll['face.livenessVal'])
+ faceRecognitionSettingView.info[2].slider.send(dxui.Utils.EVENT.VALUE_CHANGED)
+ // 绾㈠鍥惧儚鏄剧ず
+ faceRecognitionSettingView.info[3].switch.select(configAll['face.showNir'] == 1)
+ // // 鍙g僵妫�娴嬪紑鍏�
+ // faceRecognitionSettingView.info[4].switch.select(configAll['face.detectMask'] == 1)
+ })
+
+ const titleBox = viewUtils.title(screenMain, systemSettingView.screenMain, 'faceRecognitionSettingViewTitle', 'systemSettingView.faceRecognitionSetting')
+ titleBox.align(dxui.Utils.ALIGN.TOP_MID, 0, 70)
+
+
+ faceRecognitionSettingView.info = [
+ {
+ title: "systemSettingView.faceSimilarityThreshold",
+ type: 'slider',
+ unit: '%'
+ },
+ {
+ title: "systemSettingView.livenessDetectionFunction",
+ type: 'switch',
+ },
+ {
+ title: "systemSettingView.livenessDetectionThreshold",
+ type: 'slider',
+ unit: ''
+ },
+ {
+ title: "systemSettingView.infraredImageDisplay",
+ type: 'switch',
+ },
+ // {
+ // title: "systemSettingView.maskRecognition",
+ // type: 'switch',
+ // },
+ // {
+ // title: "systemSettingView.maskRecognitionThreshold",
+ // type: 'slider',
+ // unit: '%'
+ // },
+ // {
+ // title: "systemSettingView.recognitionDistance",
+ // type: 'input',
+ // unit: 'cm'
+ // }
+ ]
+
+ const faceSettingBox = dxui.View.build('faceSettingBox', screenMain)
+ viewUtils._clearStyle(faceSettingBox)
+ faceSettingBox.align(dxui.Utils.ALIGN.TOP_MID, 0, 140)
+ faceSettingBox.setSize(screen.screenSize.width, 600)
+ faceSettingBox.bgOpa(0)
+ faceSettingBox.flexFlow(dxui.Utils.FLEX_FLOW.ROW_WRAP)
+ faceSettingBox.flexAlign(dxui.Utils.FLEX_ALIGN.CENTER, dxui.Utils.FLEX_ALIGN.START, dxui.Utils.FLEX_ALIGN.START)
+ faceSettingBox.obj.lvObjSetStylePadGap(0, dxui.Utils.ENUM._LV_STYLE_STATE_CMP_SAME)
+ faceSettingBox.borderWidth(1)
+ faceSettingBox.setBorderColor(0xDEDEDE)
+ faceSettingBox.obj.setStyleBorderSide(dxui.Utils.ENUM.LV_BORDER_SIDE_TOP, 0)
+
+
+ faceRecognitionSettingView.info.forEach(item => {
+ const itemBox = dxui.View.build(item.title, faceSettingBox)
+ viewUtils._clearStyle(itemBox)
+ itemBox.setSize(760, 76)
+ itemBox.borderWidth(1)
+ itemBox.setBorderColor(0xDEDEDE)
+ itemBox.obj.setStyleBorderSide(dxui.Utils.ENUM.LV_BORDER_SIDE_BOTTOM, 0)
+
+ const itemLabel = dxui.Label.build(item.title + 'Label', itemBox)
+ itemLabel.dataI18n = item.title
+ itemLabel.align(dxui.Utils.ALIGN.LEFT_MID, 0, 0)
+ itemLabel.textFont(viewUtils.font(26))
+ itemLabel.width(280)
+ itemLabel.longMode(dxui.Utils.LABEL_LONG_MODE.SCROLL_CIRCULAR)
+
+ if (item.unit) {
+ const unitLabel = dxui.Label.build(item.title + 'UnitLabel', itemBox)
+ unitLabel.text(item.unit)
+ unitLabel.align(dxui.Utils.ALIGN.RIGHT_MID, 0, 0)
+ unitLabel.textFont(viewUtils.font(26))
+ }
+
+ switch (item.type) {
+ case 'switch':
+ const __switch = dxui.Switch.build(item.title + 'switch', itemBox)
+ __switch.align(dxui.Utils.ALIGN.RIGHT_MID, 0, 0)
+ __switch.setSize(70, 35)
+ item.switch = __switch
+ break;
+ case 'input':
+ const input = viewUtils.input(itemBox, item.title + 'input', undefined, undefined, undefined)
+ input.align(dxui.Utils.ALIGN.RIGHT_MID, -45, 0)
+ input.setSize(100, 55)
+ item.input = input
+ break;
+ case 'slider':
+ const sliderLabel = dxui.Label.build(item.title + 'sliderLabel', itemBox)
+ sliderLabel.align(dxui.Utils.ALIGN.RIGHT_MID, -20, 0)
+ sliderLabel.width(50)
+ sliderLabel.text('0')
+ sliderLabel.textFont(viewUtils.font(26))
+ sliderLabel.textAlign(dxui.Utils.TEXT_ALIGN.RIGHT)
+
+ const slider = dxui.Slider.build(item.title + 'slider', itemBox)
+ slider.align(dxui.Utils.ALIGN.RIGHT_MID, -80, 0)
+ slider.width(150)
+ slider.range(0, 100)
+
+ slider.on(dxui.Utils.EVENT.VALUE_CHANGED, () => {
+ sliderLabel.text(slider.value() + '')
+ })
+ item.slider = slider
+ break;
+ }
+ })
+
+ const saveBtn = viewUtils.bottomBtn(screenMain, screenMain.id + 'saveBtn', 'systemSettingView.save', () => {
+ const saveConfigData = {
+ face: {
+ similarity: faceRecognitionSettingView.info[0].slider.value() / 100,
+ livenessOff: faceRecognitionSettingView.info[1].switch.isSelect() ? 1 : 0,
+ livenessVal: faceRecognitionSettingView.info[2].slider.value(),
+ showNir: faceRecognitionSettingView.info[3].switch.isSelect() ? 1 : 0,
+ // detectMask: faceRecognitionSettingView.info[4].switch.isSelect() ? 1 : 0
+ }
+ }
+ const res = screen.saveConfig(saveConfigData)
+ if (res === true) {
+ faceRecognitionSettingView.statusPanel.success()
+ std.setTimeout(() => {
+ // 鎴愬姛杩斿洖涓婁竴灞傜晫闈�
+ dxui.loadMain(systemSettingView.screenMain)
+ }, 500)
+ } else {
+ faceRecognitionSettingView.statusPanel.fail()
+ }
+ })
+ saveBtn.align(dxui.Utils.ALIGN.BOTTOM_MID, 0, -83)
+
+ faceRecognitionSettingView.statusPanel = viewUtils.statusPanel(screenMain, 'systemSettingView.success', 'systemSettingView.fail')
+}
+
+export default faceRecognitionSettingView
diff --git a/vf205_access/src/view/config/menu/systemSetting/passLogSettingView.js b/vf205_access/src/view/config/menu/systemSetting/passLogSettingView.js
new file mode 100644
index 0000000..c72d874
--- /dev/null
+++ b/vf205_access/src/view/config/menu/systemSetting/passLogSettingView.js
@@ -0,0 +1,117 @@
+import dxui from '../../../../../dxmodules/dxUi.js'
+import std from '../../../../../dxmodules/dxStd.js'
+import viewUtils from "../../../viewUtils.js"
+import topView from "../../../topView.js"
+import i18n from "../../../i18n.js"
+import systemSettingView from '../systemSettingView.js'
+import screen from '../../../../screen.js'
+const passLogSettingView = {}
+passLogSettingView.init = function () {
+ /**************************************************鍒涘缓灞忓箷*****************************************************/
+ const screenMain = dxui.View.build('passLogSettingView', dxui.Utils.LAYER.MAIN)
+ passLogSettingView.screenMain = screenMain
+ screenMain.scroll(false)
+ screenMain.bgColor(0xffffff)
+ screenMain.on(dxui.Utils.ENUM.LV_EVENT_SCREEN_LOADED, () => {
+ topView.changeTheme(true)
+
+ // passLogSettingView.info[0].value = [i18n.t('systemSettingView.fullView'), i18n.t('systemSettingView.face')]
+ // passLogSettingView.info[0].dropdown.setOptions(passLogSettingView.info[0].value)
+
+ const configAll = screen.getConfig()
+ // passLogSettingView.info[0].dropdown.setSelected(configAll['sys.accessImageType'])
+ passLogSettingView.info[0].switch.select(configAll['sys.strangerImage'] == 1)
+ })
+
+ const titleBox = viewUtils.title(screenMain, systemSettingView.screenMain, 'passLogSettingViewTitle', 'systemSettingView.passLogSetting')
+ titleBox.align(dxui.Utils.ALIGN.TOP_MID, 0, 70)
+
+ passLogSettingView.info = [
+ // {
+ // title: "systemSettingView.imageSaveType",
+ // type: 'dropdown',
+ // value: [i18n.t('systemSettingView.fullView'), i18n.t('systemSettingView.face')],
+ // dropdown: null
+ // },
+ {
+ title: "systemSettingView.saveStrangerImage",
+ type: 'switch',
+ },
+ ]
+
+ const passSettingBox = dxui.View.build('passSettingBox', screenMain)
+ viewUtils._clearStyle(passSettingBox)
+ passSettingBox.align(dxui.Utils.ALIGN.TOP_MID, 0, 140)
+ passSettingBox.setSize(screen.screenSize.width, 600)
+ passSettingBox.bgOpa(0)
+ passSettingBox.flexFlow(dxui.Utils.FLEX_FLOW.ROW_WRAP)
+ passSettingBox.flexAlign(dxui.Utils.FLEX_ALIGN.CENTER, dxui.Utils.FLEX_ALIGN.START, dxui.Utils.FLEX_ALIGN.START)
+ passSettingBox.obj.lvObjSetStylePadGap(0, dxui.Utils.ENUM._LV_STYLE_STATE_CMP_SAME)
+ passSettingBox.borderWidth(1)
+ passSettingBox.setBorderColor(0xDEDEDE)
+ passSettingBox.obj.setStyleBorderSide(dxui.Utils.ENUM.LV_BORDER_SIDE_TOP, 0)
+
+ passLogSettingView.info.forEach(item => {
+ const itemBox = dxui.View.build(item.title, passSettingBox)
+ viewUtils._clearStyle(itemBox)
+ itemBox.setSize(760, 76)
+ itemBox.borderWidth(1)
+ itemBox.setBorderColor(0xDEDEDE)
+ itemBox.obj.setStyleBorderSide(dxui.Utils.ENUM.LV_BORDER_SIDE_BOTTOM, 0)
+
+ const itemLabel = dxui.Label.build(item.title + 'Label', itemBox)
+ itemLabel.dataI18n = item.title
+ itemLabel.align(dxui.Utils.ALIGN.LEFT_MID, 0, 0)
+ itemLabel.textFont(viewUtils.font(26))
+
+ if (item.unit) {
+ const unitLabel = dxui.Label.build(item.title + 'UnitLabel', itemBox)
+ unitLabel.text(item.unit)
+ unitLabel.align(dxui.Utils.ALIGN.RIGHT_MID, 0, 0)
+ unitLabel.textFont(viewUtils.font(26))
+ }
+
+ switch (item.type) {
+ case 'switch':
+ const __switch = dxui.Switch.build(item.title + 'switch', itemBox)
+ __switch.align(dxui.Utils.ALIGN.RIGHT_MID, 0, 0)
+ __switch.setSize(70, 35)
+ item.switch = __switch
+ break;
+ case 'dropdown':
+ const dropdown = dxui.Dropdown.build(item.title + 'dropdown', itemBox)
+ dropdown.align(dxui.Utils.ALIGN.RIGHT_MID, 0, 0)
+ dropdown.setSize(200, 60)
+ dropdown.textFont(viewUtils.font(26))
+ dropdown.getList().textFont(viewUtils.font(26))
+ dropdown.setSymbol('/app/code/resource/image/down.png')
+ dropdown.setOptions(item.value)
+ item.dropdown = dropdown
+ break;
+ }
+ })
+
+ const saveBtn = viewUtils.bottomBtn(screenMain, screenMain.id + 'saveBtn', 'systemSettingView.save', () => {
+ const saveConfigData = {
+ sys: {
+ // accessImageType: passLogSettingView.info[0].dropdown.getSelected(),
+ strangerImage: passLogSettingView.info[0].switch.isSelect() ? 1 : 0
+ }
+ }
+ const res = screen.saveConfig(saveConfigData)
+ if (res === true) {
+ passLogSettingView.statusPanel.success()
+ std.setTimeout(() => {
+ // 鎴愬姛杩斿洖涓婁竴灞傜晫闈�
+ dxui.loadMain(systemSettingView.screenMain)
+ }, 500)
+ } else {
+ passLogSettingView.statusPanel.fail()
+ }
+ })
+ saveBtn.align(dxui.Utils.ALIGN.BOTTOM_MID, 0, -83)
+
+ passLogSettingView.statusPanel = viewUtils.statusPanel(screenMain, 'systemSettingView.success', 'systemSettingView.fail')
+}
+
+export default passLogSettingView
diff --git a/vf205_access/src/view/config/menu/systemSetting/passwordManagementView.js b/vf205_access/src/view/config/menu/systemSetting/passwordManagementView.js
new file mode 100644
index 0000000..1e289ab
--- /dev/null
+++ b/vf205_access/src/view/config/menu/systemSetting/passwordManagementView.js
@@ -0,0 +1,115 @@
+
+import dxui from '../../../../../dxmodules/dxUi.js'
+import std from '../../../../../dxmodules/dxStd.js'
+import viewUtils from "../../../viewUtils.js"
+import topView from "../../../topView.js"
+import systemSettingView from '../systemSettingView.js'
+import i18n from "../../../i18n.js"
+import screen from '../../../../screen.js'
+const passwordManagementView = {}
+passwordManagementView.init = function () {
+ /**************************************************鍒涘缓灞忓箷*****************************************************/
+ const screenMain = dxui.View.build('passwordManagementView', dxui.Utils.LAYER.MAIN)
+ passwordManagementView.screenMain = screenMain
+ screenMain.scroll(false)
+ screenMain.bgColor(0xffffff)
+ screenMain.on(dxui.Utils.ENUM.LV_EVENT_SCREEN_LOADED, () => {
+ topView.changeTheme(true)
+ })
+
+ const titleBox = viewUtils.title(screenMain, systemSettingView.screenMain, 'passwordManagementViewTitle', 'systemSettingView.passwordManagement')
+ titleBox.align(dxui.Utils.ALIGN.TOP_MID, 0, 70)
+
+ passwordManagementView.info = [
+ {
+ title: "systemSettingView.inputOriginalPassword",
+ type: 'input',
+ },
+ {
+ title: "systemSettingView.inputNewPassword",
+ type: 'input',
+ },
+ {
+ title: "systemSettingView.inputRepeatNewPassword",
+ type: 'input',
+ }
+ ]
+
+ const passwordManagementBox = dxui.View.build('passwordManagementBox', screenMain)
+ viewUtils._clearStyle(passwordManagementBox)
+ passwordManagementBox.align(dxui.Utils.ALIGN.TOP_MID, 0, 140)
+ passwordManagementBox.setSize(screen.screenSize.width, 300)
+ passwordManagementBox.bgOpa(0)
+ passwordManagementBox.flexFlow(dxui.Utils.FLEX_FLOW.ROW_WRAP)
+ passwordManagementBox.flexAlign(dxui.Utils.FLEX_ALIGN.CENTER, dxui.Utils.FLEX_ALIGN.START, dxui.Utils.FLEX_ALIGN.START)
+ passwordManagementBox.obj.lvObjSetStylePadGap(0, dxui.Utils.ENUM._LV_STYLE_STATE_CMP_SAME)
+ passwordManagementBox.borderWidth(1)
+ passwordManagementBox.setBorderColor(0xDEDEDE)
+ passwordManagementBox.obj.setStyleBorderSide(dxui.Utils.ENUM.LV_BORDER_SIDE_TOP, 0)
+
+ passwordManagementView.info.forEach(item => {
+ const itemBox = dxui.View.build(item.title, passwordManagementBox)
+ viewUtils._clearStyle(itemBox)
+ itemBox.setSize(760, 76)
+ itemBox.borderWidth(1)
+ itemBox.setBorderColor(0xDEDEDE)
+ itemBox.obj.setStyleBorderSide(dxui.Utils.ENUM.LV_BORDER_SIDE_BOTTOM, 0)
+
+ const itemLabel = dxui.Label.build(item.title + 'Label', itemBox)
+ itemLabel.dataI18n = item.title
+ itemLabel.align(dxui.Utils.ALIGN.LEFT_MID, 0, 0)
+ itemLabel.textFont(viewUtils.font(26))
+ itemLabel.width(300)
+ itemLabel.longMode(dxui.Utils.LABEL_LONG_MODE.SCROLL_CIRCULAR)
+
+ if (item.unit) {
+ const unitLabel = dxui.Label.build(item.title + 'UnitLabel', itemBox)
+ unitLabel.text(item.unit)
+ unitLabel.align(dxui.Utils.ALIGN.RIGHT_MID, 0, 0)
+ unitLabel.textFont(viewUtils.font(26))
+ }
+
+ switch (item.type) {
+ case 'input':
+ const input = viewUtils.input(itemBox, item.title + 'input', undefined, undefined, undefined)
+ input.align(dxui.Utils.ALIGN.RIGHT_MID, 0, 0)
+ input.setSize(280, 55)
+ item.input = input
+ break;
+ }
+ })
+
+
+ const saveBtn = viewUtils.bottomBtn(screenMain, screenMain.id + 'saveBtn', 'systemSettingView.save', () => {
+ const configAll = screen.getConfig()
+ if (configAll['base.password'] != passwordManagementView.info[0].input.text()) {
+ passwordManagementView.statusPanel.fail()
+ return
+ }
+
+ if (passwordManagementView.info[1].input.text() != passwordManagementView.info[2].input.text()) {
+ passwordManagementView.statusPanel.fail()
+ return
+ }
+
+ const saveConfigData = {
+ base: {
+ password: passwordManagementView.info[2].input.text(),
+ }
+ }
+ const res = screen.saveConfig(saveConfigData)
+ if (res === true) {
+ passwordManagementView.statusPanel.success()
+ std.setTimeout(() => {
+ // 鎴愬姛杩斿洖涓婁竴灞傜晫闈�
+ dxui.loadMain(systemSettingView.screenMain)
+ }, 500)
+ } else {
+ passwordManagementView.statusPanel.fail()
+ }
+ })
+ saveBtn.align(dxui.Utils.ALIGN.BOTTOM_MID, 0, -83)
+ passwordManagementView.statusPanel = viewUtils.statusPanel(screenMain, 'systemSettingView.success', 'systemSettingView.fail')
+}
+
+export default passwordManagementView
diff --git a/vf205_access/src/view/config/menu/systemSetting/passwordOpenDoorSettingView.js b/vf205_access/src/view/config/menu/systemSetting/passwordOpenDoorSettingView.js
new file mode 100644
index 0000000..7c4b764
--- /dev/null
+++ b/vf205_access/src/view/config/menu/systemSetting/passwordOpenDoorSettingView.js
@@ -0,0 +1,144 @@
+import dxui from '../../../../../dxmodules/dxUi.js'
+import std from '../../../../../dxmodules/dxStd.js'
+import viewUtils from "../../../viewUtils.js"
+import topView from "../../../topView.js"
+import i18n from "../../../i18n.js"
+import systemSettingView from '../systemSettingView.js'
+import screen from '../../../../screen.js'
+import sqliteService from '../../../../service/sqliteService.js'
+import logger from '../../../../../dxmodules/dxLogger.js'
+const passwordOpenDoorSettingView = {}
+passwordOpenDoorSettingView.init = function () {
+ /**************************************************鍒涘缓灞忓箷*****************************************************/
+ const screenMain = dxui.View.build('passwordOpenDoorSettingView', dxui.Utils.LAYER.MAIN)
+ passwordOpenDoorSettingView.screenMain = screenMain
+ screenMain.scroll(false)
+ screenMain.bgColor(0xffffff)
+ screenMain.on(dxui.Utils.ENUM.LV_EVENT_SCREEN_LOADED, () => {
+ topView.changeTheme(true)
+
+ const configAll = screen.getConfig()
+ passwordOpenDoorSettingView.info[0].switch.select(configAll['sys.pwd'] == 1)
+ // 鍔犺浇搴旀�ュ紑浠撳瘑鐮侊紙浠庢暟鎹簱锛�
+ if (passwordOpenDoorSettingView.info[1].input) {
+ try {
+ const passwords = sqliteService.d1_emergency_password.findAll()
+ if (passwords && passwords.length > 0) {
+ // 鍙樉绀虹涓�涓瘑鐮侊紝鍥犱负搴旀�ュ紑浠撳瘑鐮佸湪璁惧涓粎鏈夊敮涓�鐨�1涓�
+ passwordOpenDoorSettingView.info[1].input.text(passwords[0].password || '')
+ }
+ } catch (error) {
+ logger.error('鍔犺浇搴旀�ュ紑浠撳瘑鐮佸け璐�:', error)
+ }
+ }
+ })
+
+ const titleBox = viewUtils.title(screenMain, systemSettingView.screenMain, 'passwordOpenDoorSettingViewTitle', 'systemSettingView.passwordOpenDoorSetting')
+ titleBox.align(dxui.Utils.ALIGN.TOP_MID, 0, 70)
+
+ passwordOpenDoorSettingView.info = [
+ {
+ title: "systemSettingView.passwordOpenDoor",
+ type: 'switch',
+ },
+ {
+ title: "搴旀�ュ紑浠撳瘑鐮�",
+ type: 'input',
+ placeholder: '璇疯緭鍏ヨ嚦灏�8浣嶅簲鎬ュ紑浠撳瘑鐮�',
+ password: true
+ }
+ ]
+
+ const passwordOpenDoorSettingBox = dxui.View.build('passwordOpenDoorSettingBox', screenMain)
+ viewUtils._clearStyle(passwordOpenDoorSettingBox)
+ passwordOpenDoorSettingBox.align(dxui.Utils.ALIGN.TOP_MID, 0, 140)
+ passwordOpenDoorSettingBox.setSize(screen.screenSize.width, 600)
+ passwordOpenDoorSettingBox.bgOpa(0)
+ passwordOpenDoorSettingBox.flexFlow(dxui.Utils.FLEX_FLOW.ROW_WRAP)
+ passwordOpenDoorSettingBox.flexAlign(dxui.Utils.FLEX_ALIGN.CENTER, dxui.Utils.FLEX_ALIGN.START, dxui.Utils.FLEX_ALIGN.START)
+ passwordOpenDoorSettingBox.obj.lvObjSetStylePadGap(0, dxui.Utils.ENUM._LV_STYLE_STATE_CMP_SAME)
+ passwordOpenDoorSettingBox.borderWidth(1)
+ passwordOpenDoorSettingBox.setBorderColor(0xDEDEDE)
+ passwordOpenDoorSettingBox.obj.setStyleBorderSide(dxui.Utils.ENUM.LV_BORDER_SIDE_TOP, 0)
+
+ passwordOpenDoorSettingView.info.forEach(item => {
+ const itemBox = dxui.View.build(item.title, passwordOpenDoorSettingBox)
+ viewUtils._clearStyle(itemBox)
+ itemBox.setSize(760, 76)
+ itemBox.borderWidth(1)
+ itemBox.setBorderColor(0xDEDEDE)
+ itemBox.obj.setStyleBorderSide(dxui.Utils.ENUM.LV_BORDER_SIDE_BOTTOM, 0)
+
+ const itemLabel = dxui.Label.build(item.title + 'Label', itemBox)
+ itemLabel.dataI18n = item.title
+ itemLabel.align(dxui.Utils.ALIGN.LEFT_MID, 0, 0)
+ itemLabel.textFont(viewUtils.font(26))
+
+ if (item.unit) {
+ const unitLabel = dxui.Label.build(item.title + 'UnitLabel', itemBox)
+ unitLabel.text(item.unit)
+ unitLabel.align(dxui.Utils.ALIGN.RIGHT_MID, 0, 0)
+ unitLabel.textFont(viewUtils.font(26))
+ }
+
+ switch (item.type) {
+ case 'switch':
+ const __switch = dxui.Switch.build(item.title + 'switch', itemBox)
+ __switch.align(dxui.Utils.ALIGN.RIGHT_MID, 0, 0)
+ __switch.setSize(70, 35)
+ item.switch = __switch
+ break;
+ case 'input':
+ const input = viewUtils.input(itemBox, item.title + 'input', undefined, undefined, item.placeholder)
+ input.align(dxui.Utils.ALIGN.RIGHT_MID, 0, 0)
+ input.setSize(300, 40)
+ input.setPasswordMode(item.password)
+ item.input = input
+ break;
+ }
+ })
+
+ const saveBtn = viewUtils.bottomBtn(screenMain, screenMain.id + 'saveBtn', 'systemSettingView.save', () => {
+ const emergencyPassword = passwordOpenDoorSettingView.info[1].input.text()
+ const saveConfigData = {
+ sys: {
+ pwd: passwordOpenDoorSettingView.info[0].switch.isSelect() ? 1 : 0
+ }
+ }
+
+ // 鏇存柊鏁版嵁搴撲腑鐨勫簲鎬ュ紑浠撳瘑鐮�
+ try {
+ // 鍏堝垹闄ゆ棫鐨勫簲鎬ュ紑浠撳瘑鐮�
+ sqliteService.d1_emergency_password.deleteAll()
+ // 娣诲姞鏂扮殑搴旀�ュ紑浠撳瘑鐮�
+ if (emergencyPassword) {
+ sqliteService.d1_emergency_password.save({
+ id: 'emergency_' + Date.now(),
+ password: emergencyPassword,
+ description: '绯荤粺璁剧疆鐨勫簲鎬ュ紑浠撳瘑鐮�',
+ createTime: Date.now(),
+ updateTime: Date.now(),
+ status: 1
+ })
+ }
+ } catch (error) {
+ logger.error('鏇存柊搴旀�ュ紑浠撳瘑鐮佸け璐�:', error)
+ }
+
+ const res = screen.saveConfig(saveConfigData)
+ if (res === true) {
+ passwordOpenDoorSettingView.statusPanel.success()
+ std.setTimeout(() => {
+ // 鎴愬姛杩斿洖涓婁竴灞傜晫闈�
+ dxui.loadMain(systemSettingView.screenMain)
+ }, 500)
+ } else {
+ passwordOpenDoorSettingView.statusPanel.fail()
+ }
+ })
+ saveBtn.align(dxui.Utils.ALIGN.BOTTOM_MID, 0, -83)
+
+ passwordOpenDoorSettingView.statusPanel = viewUtils.statusPanel(screenMain, 'systemSettingView.success', 'systemSettingView.fail')
+}
+
+export default passwordOpenDoorSettingView
diff --git a/vf205_access/src/view/config/menu/systemSetting/swipeCardRecognitionSettingView.js b/vf205_access/src/view/config/menu/systemSetting/swipeCardRecognitionSettingView.js
new file mode 100644
index 0000000..ef12287
--- /dev/null
+++ b/vf205_access/src/view/config/menu/systemSetting/swipeCardRecognitionSettingView.js
@@ -0,0 +1,96 @@
+import dxui from '../../../../../dxmodules/dxUi.js'
+import std from '../../../../../dxmodules/dxStd.js'
+import viewUtils from "../../../viewUtils.js"
+import topView from "../../../topView.js"
+import systemSettingView from '../systemSettingView.js'
+import i18n from "../../../i18n.js"
+import screen from '../../../../screen.js'
+const swipeCardRecognitionSettingView = {}
+swipeCardRecognitionSettingView.init = function () {
+ /**************************************************鍒涘缓灞忓箷*****************************************************/
+ const screenMain = dxui.View.build('swipeCardRecognitionSettingView', dxui.Utils.LAYER.MAIN)
+ swipeCardRecognitionSettingView.screenMain = screenMain
+ screenMain.scroll(false)
+ screenMain.bgColor(0xffffff)
+ screenMain.on(dxui.Utils.ENUM.LV_EVENT_SCREEN_LOADED, () => {
+ topView.changeTheme(true)
+
+ const configAll = screen.getConfig()
+ swipeCardRecognitionSettingView.info[0].switch.select(configAll['sys.nfc'] == 1)
+ })
+
+ const titleBox = viewUtils.title(screenMain, systemSettingView.screenMain, 'swipeCardRecognitionSettingViewTitle', 'systemSettingView.swipeCardRecognitionSetting')
+ titleBox.align(dxui.Utils.ALIGN.TOP_MID, 0, 70)
+
+ swipeCardRecognitionSettingView.info = [
+ {
+ title: "systemSettingView.swipeCardRecognition",
+ type: 'switch',
+ }
+ ]
+
+ const swipeCardRecognitionSettingBox = dxui.View.build('swipeCardRecognitionSettingBox', screenMain)
+ viewUtils._clearStyle(swipeCardRecognitionSettingBox)
+ swipeCardRecognitionSettingBox.align(dxui.Utils.ALIGN.TOP_MID, 0, 140)
+ swipeCardRecognitionSettingBox.setSize(screen.screenSize.width, 600)
+ swipeCardRecognitionSettingBox.bgOpa(0)
+ swipeCardRecognitionSettingBox.flexFlow(dxui.Utils.FLEX_FLOW.ROW_WRAP)
+ swipeCardRecognitionSettingBox.flexAlign(dxui.Utils.FLEX_ALIGN.CENTER, dxui.Utils.FLEX_ALIGN.START, dxui.Utils.FLEX_ALIGN.START)
+ swipeCardRecognitionSettingBox.obj.lvObjSetStylePadGap(0, dxui.Utils.ENUM._LV_STYLE_STATE_CMP_SAME)
+ swipeCardRecognitionSettingBox.borderWidth(1)
+ swipeCardRecognitionSettingBox.setBorderColor(0xDEDEDE)
+ swipeCardRecognitionSettingBox.obj.setStyleBorderSide(dxui.Utils.ENUM.LV_BORDER_SIDE_TOP, 0)
+
+ swipeCardRecognitionSettingView.info.forEach(item => {
+ const itemBox = dxui.View.build(item.title, swipeCardRecognitionSettingBox)
+ viewUtils._clearStyle(itemBox)
+ itemBox.setSize(760, 76)
+ itemBox.borderWidth(1)
+ itemBox.setBorderColor(0xDEDEDE)
+ itemBox.obj.setStyleBorderSide(dxui.Utils.ENUM.LV_BORDER_SIDE_BOTTOM, 0)
+
+ const itemLabel = dxui.Label.build(item.title + 'Label', itemBox)
+ itemLabel.dataI18n = item.title
+ itemLabel.align(dxui.Utils.ALIGN.LEFT_MID, 0, 0)
+ itemLabel.textFont(viewUtils.font(26))
+
+ if (item.unit) {
+ const unitLabel = dxui.Label.build(item.title + 'UnitLabel', itemBox)
+ unitLabel.text(item.unit)
+ unitLabel.align(dxui.Utils.ALIGN.RIGHT_MID, 0, 0)
+ unitLabel.textFont(viewUtils.font(26))
+ }
+
+ switch (item.type) {
+ case 'switch':
+ const __switch = dxui.Switch.build(item.title + 'switch', itemBox)
+ __switch.align(dxui.Utils.ALIGN.RIGHT_MID, 0, 0)
+ __switch.setSize(70, 35)
+ item.switch = __switch
+ break;
+ }
+ })
+
+ const saveBtn = viewUtils.bottomBtn(screenMain, screenMain.id + 'saveBtn', 'systemSettingView.save', () => {
+ const saveConfigData = {
+ sys: {
+ nfc: swipeCardRecognitionSettingView.info[0].switch.isSelect() ? 1 : 0,
+ }
+ }
+ const res = screen.saveConfig(saveConfigData)
+ if (res === true) {
+ swipeCardRecognitionSettingView.statusPanel.success()
+ std.setTimeout(() => {
+ // 鎴愬姛杩斿洖涓婁竴灞傜晫闈�
+ dxui.loadMain(systemSettingView.screenMain)
+ }, 500)
+ } else {
+ swipeCardRecognitionSettingView.statusPanel.fail()
+ }
+ })
+ saveBtn.align(dxui.Utils.ALIGN.BOTTOM_MID, 0, -83)
+
+ swipeCardRecognitionSettingView.statusPanel = viewUtils.statusPanel(screenMain, 'systemSettingView.success', 'systemSettingView.fail')
+}
+
+export default swipeCardRecognitionSettingView
diff --git a/vf205_access/src/view/config/menu/systemSetting/timeSettingView.js b/vf205_access/src/view/config/menu/systemSetting/timeSettingView.js
new file mode 100644
index 0000000..1012fc9
--- /dev/null
+++ b/vf205_access/src/view/config/menu/systemSetting/timeSettingView.js
@@ -0,0 +1,124 @@
+import dxui from '../../../../../dxmodules/dxUi.js'
+import std from '../../../../../dxmodules/dxStd.js'
+import dxMap from '../../../../../dxmodules/dxMap.js'
+import viewUtils from "../../../viewUtils.js"
+import topView from "../../../topView.js"
+import systemSettingView from '../systemSettingView.js'
+import i18n from "../../../i18n.js"
+import screen from '../../../../screen.js'
+const timeSettingView = {}
+timeSettingView.init = function () {
+ /**************************************************鍒涘缓灞忓箷*****************************************************/
+ const screenMain = dxui.View.build('timeSettingView', dxui.Utils.LAYER.MAIN)
+ timeSettingView.screenMain = screenMain
+ screenMain.scroll(false)
+ screenMain.bgColor(0xffffff)
+ screenMain.on(dxui.Utils.ENUM.LV_EVENT_SCREEN_LOADED, () => {
+ topView.changeTheme(true)
+
+ const configAll = screen.getConfig()
+ timeSettingView.info[0].input.text(configAll['ntp.gmt'] + '')
+ timeSettingView.info[1].input.text(configAll['ntp.server'] + '')
+
+ const syncTime = dxMap.get("NTP_SYNC").get("syncTime")
+ if (syncTime) {
+ msgLabel.text(new Date(syncTime).toLocaleString())
+ }
+ })
+
+ const titleBox = viewUtils.title(screenMain, systemSettingView.screenMain, 'timeSettingViewTitle', 'systemSettingView.timeSetting')
+ titleBox.align(dxui.Utils.ALIGN.TOP_MID, 0, 70)
+
+ timeSettingView.info = [
+ {
+ title: "systemSettingView.syncMode",
+ type: 'input',
+ },
+ {
+ title: "systemSettingView.ntpAddress",
+ type: 'input',
+ }
+ ]
+
+ const timeSettingBox = dxui.View.build('timeSettingBox', screenMain)
+ viewUtils._clearStyle(timeSettingBox)
+ timeSettingBox.align(dxui.Utils.ALIGN.TOP_MID, 0, 140)
+ timeSettingBox.setSize(screen.screenSize.width, 300)
+ timeSettingBox.bgOpa(0)
+ timeSettingBox.flexFlow(dxui.Utils.FLEX_FLOW.ROW_WRAP)
+ timeSettingBox.flexAlign(dxui.Utils.FLEX_ALIGN.CENTER, dxui.Utils.FLEX_ALIGN.START, dxui.Utils.FLEX_ALIGN.START)
+ timeSettingBox.obj.lvObjSetStylePadGap(0, dxui.Utils.ENUM._LV_STYLE_STATE_CMP_SAME)
+ timeSettingBox.borderWidth(1)
+ timeSettingBox.setBorderColor(0xDEDEDE)
+ timeSettingBox.obj.setStyleBorderSide(dxui.Utils.ENUM.LV_BORDER_SIDE_TOP, 0)
+
+ timeSettingView.info.forEach(item => {
+ const itemBox = dxui.View.build(item.title, timeSettingBox)
+ viewUtils._clearStyle(itemBox)
+ itemBox.setSize(760, 76)
+ itemBox.borderWidth(1)
+ itemBox.setBorderColor(0xDEDEDE)
+ itemBox.obj.setStyleBorderSide(dxui.Utils.ENUM.LV_BORDER_SIDE_BOTTOM, 0)
+
+ const itemLabel = dxui.Label.build(item.title + 'Label', itemBox)
+ itemLabel.dataI18n = item.title
+ itemLabel.align(dxui.Utils.ALIGN.LEFT_MID, 0, 0)
+ itemLabel.textFont(viewUtils.font(26))
+
+ if (item.unit) {
+ const unitLabel = dxui.Label.build(item.title + 'UnitLabel', itemBox)
+ unitLabel.text(item.unit)
+ unitLabel.align(dxui.Utils.ALIGN.RIGHT_MID, 0, 0)
+ unitLabel.textFont(viewUtils.font(26))
+ }
+
+ switch (item.type) {
+ case 'input':
+ const input = viewUtils.input(itemBox, item.title + 'input', undefined, undefined, undefined)
+ input.align(dxui.Utils.ALIGN.RIGHT_MID, 0, 0)
+ if (item.title == "systemSettingView.ntpAddress") {
+ input.setSize(300, 55)
+ } else {
+ input.setSize(150, 55)
+ }
+ item.input = input
+ break;
+ }
+ })
+
+ const msgLabel = dxui.Label.build('msgLabel', screenMain)
+ msgLabel.align(dxui.Utils.ALIGN.TOP_MID, 0, 662)
+ msgLabel.textFont(viewUtils.font(22))
+ msgLabel.text('2024/02/12 19:07')
+ msgLabel.textColor(0x888888)
+
+ const msgLabel2 = dxui.Label.build('msgLabel2', screenMain)
+ msgLabel2.align(dxui.Utils.ALIGN.TOP_MID, 0, 690)
+ msgLabel2.textFont(viewUtils.font(22))
+ msgLabel2.textColor(0x888888)
+ msgLabel2.dataI18n = 'systemSettingView.timeSyncSuccess'
+
+
+ const saveBtn = viewUtils.bottomBtn(screenMain, screenMain.id + 'saveBtn', 'systemSettingView.save', () => {
+ const saveConfigData = {
+ ntp: {
+ gmt: parseInt(timeSettingView.info[0].input.text()),
+ server: timeSettingView.info[1].input.text(),
+ }
+ }
+ const res = screen.saveConfig(saveConfigData)
+ if (res === true) {
+ timeSettingView.statusPanel.success()
+ std.setTimeout(() => {
+ // 鎴愬姛杩斿洖涓婁竴灞傜晫闈�
+ dxui.loadMain(systemSettingView.screenMain)
+ }, 500)
+ } else {
+ timeSettingView.statusPanel.fail()
+ }
+ })
+ saveBtn.align(dxui.Utils.ALIGN.BOTTOM_MID, 0, -83)
+ timeSettingView.statusPanel = viewUtils.statusPanel(screenMain, 'systemSettingView.success', 'systemSettingView.fail')
+}
+
+export default timeSettingView
diff --git a/vf205_access/src/view/config/menu/systemSettingView.js b/vf205_access/src/view/config/menu/systemSettingView.js
new file mode 100644
index 0000000..dc62150
--- /dev/null
+++ b/vf205_access/src/view/config/menu/systemSettingView.js
@@ -0,0 +1,184 @@
+import dxui from '../../../../dxmodules/dxUi.js'
+import std from '../../../../dxmodules/dxStd.js'
+import dxCommon from '../../../../dxmodules/dxCommon.js'
+import viewUtils from "../../viewUtils.js"
+import topView from "../../topView.js"
+import configView from '../configView.js'
+import displaySettingView from './systemSetting/displaySettingView.js'
+import faceRecognitionSettingView from './systemSetting/faceRecognitionSettingView.js'
+import swipeCardRecognitionSettingView from './systemSetting/swipeCardRecognitionSettingView.js'
+import passLogSettingView from './systemSetting/passLogSettingView.js'
+import passwordOpenDoorSettingView from './systemSetting/passwordOpenDoorSettingView.js'
+import passwordManagementView from './systemSetting/passwordManagementView.js'
+import timeSettingView from './systemSetting/timeSettingView.js'
+import i18n from "../../i18n.js"
+import screen from '../../../screen.js'
+
+const systemSettingView = {}
+systemSettingView.init = function () {
+ /**************************************************鍒涘缓灞忓箷*****************************************************/
+ const screenMain = dxui.View.build('systemSettingView', dxui.Utils.LAYER.MAIN)
+ systemSettingView.screenMain = screenMain
+ screenMain.scroll(false)
+ screenMain.bgColor(0xffffff)
+ screenMain.on(dxui.Utils.ENUM.LV_EVENT_SCREEN_LOADED, () => {
+ topView.changeTheme(true)
+ })
+
+ const titleBox = viewUtils.title(screenMain, configView.screenMain, 'systemSettingViewTitle', 'systemSettingView.title')
+ titleBox.align(dxui.Utils.ALIGN.TOP_MID, 0, 70)
+
+ systemSettingView.sysInfo = [
+ {
+ title: 'systemSettingView.displaySetting',
+ type: 'menu',
+ view: displaySettingView,
+ obj: null,
+ },
+ {
+ title: 'systemSettingView.faceRecognitionSetting',
+ type: 'menu',
+ view: faceRecognitionSettingView,
+ obj: null,
+ },
+ {
+ title: 'systemSettingView.swipeCardRecognitionSetting',
+ type: 'menu',
+ view: swipeCardRecognitionSettingView,
+ obj: null,
+ },
+ {
+ title: 'systemSettingView.passLogSetting',
+ type: 'menu',
+ view: passLogSettingView,
+ obj: null,
+ },
+ {
+ title: 'systemSettingView.passwordOpenDoorSetting',
+ type: 'menu',
+ view: passwordOpenDoorSettingView,
+ obj: null,
+ },
+ {
+ title: 'systemSettingView.passwordManagement',
+ type: 'menu',
+ view: passwordManagementView,
+ obj: null,
+ },
+ {
+ title: 'systemSettingView.timeSetting',
+ type: 'menu',
+ view: timeSettingView,
+ obj: null,
+ },
+ {
+ title: 'systemSettingView.restartDevice',
+ type: 'button',
+ obj: null,
+ },
+ {
+ title: 'systemSettingView.restoreDefaultConfig',
+ type: 'button',
+ obj: null,
+ },
+ {
+ title: 'systemSettingView.resetDevice',
+ type: 'button',
+ obj: null,
+ },
+ ]
+
+
+ const settingBox = dxui.View.build('settingBox', screenMain)
+ viewUtils._clearStyle(settingBox)
+ settingBox.setSize(screen.screenSize.width, screen.screenSize.height - 140)
+ settingBox.align(dxui.Utils.ALIGN.TOP_MID, 0, 140)
+ settingBox.bgColor(0xf7f7f7)
+ settingBox.flexFlow(dxui.Utils.FLEX_FLOW.ROW_WRAP)
+ settingBox.flexAlign(dxui.Utils.FLEX_ALIGN.CENTER, dxui.Utils.FLEX_ALIGN.START, dxui.Utils.FLEX_ALIGN.START)
+ settingBox.obj.lvObjSetStylePadGap(10, dxui.Utils.ENUM._LV_STYLE_STATE_CMP_SAME)
+ settingBox.padTop(10)
+ settingBox.padBottom(10)
+
+ systemSettingView.sysInfo.forEach(item => {
+ item.obj = dxui.View.build(item.title, settingBox)
+ viewUtils._clearStyle(item.obj)
+ item.obj.setSize(760, 76)
+ item.obj.bgColor(0xffffff)
+ item.obj.radius(10)
+ item.obj.on(dxui.Utils.ENUM.LV_EVENT_PRESSED, () => {
+ item.obj.bgColor(0xEAEAEA)
+ })
+ item.obj.on(dxui.Utils.ENUM.LV_EVENT_RELEASED, () => {
+ item.obj.bgColor(0xffffff)
+ })
+
+ const titleLbl = dxui.Label.build(item.title + 'Label', item.obj)
+ titleLbl.dataI18n = item.title
+ titleLbl.align(dxui.Utils.ALIGN.LEFT_MID, 20, 0)
+ titleLbl.textFont(viewUtils.font(26))
+
+ switch (item.type) {
+ case 'menu':
+ const image = dxui.Image.build(item.title + 'Image', item.obj)
+ image.align(dxui.Utils.ALIGN.RIGHT_MID, -15, 0)
+ image.source('/app/code/resource/image/right.png')
+ item.obj.on(dxui.Utils.EVENT.CLICK, () => {
+ dxui.loadMain(item.view.screenMain)
+ })
+ break
+ case 'button':
+ const btn = dxui.Button.build(item.title + 'Button', item.obj)
+ btn.align(dxui.Utils.ALIGN.RIGHT_MID, -15, 0)
+ btn.setSize(200, 44)
+ btn.radius(10)
+ btn.bgColor(0xEAEAEA)
+
+ const btnLbl = dxui.Label.build(btn.id + 'Label', btn)
+ btnLbl.align(dxui.Utils.ALIGN.CENTER, 0, 0)
+ btnLbl.textFont(viewUtils.font(24))
+ btnLbl.textColor(0x767676)
+
+ if (item.title == 'systemSettingView.restartDevice') {
+ btnLbl.dataI18n = 'systemSettingView.restart'
+ btn.on(dxui.Utils.EVENT.CLICK, () => {
+ viewUtils.confirmOpen('systemSettingView.confirmation', 'systemSettingView.confirmRestart', () => {
+ std.setTimeout(() => {
+ dxCommon.systemBrief("reboot -f")
+ }, 1000)
+ }, () => { })
+ })
+ } else if (item.title == 'systemSettingView.restoreDefaultConfig') {
+ btnLbl.dataI18n = 'systemSettingView.restoreDefault'
+ btn.on(dxui.Utils.EVENT.CLICK, () => {
+ viewUtils.confirmOpen('systemSettingView.confirmation', 'systemSettingView.confirmRecoveryConfiguration', () => {
+ dxCommon.systemBrief("rm -rf /app/data/config/*")
+ std.setTimeout(() => {
+ dxCommon.systemBrief("reboot -f")
+ }, 1000)
+ }, () => { })
+ })
+ } else if (item.title == 'systemSettingView.resetDevice') {
+ btnLbl.dataI18n = 'systemSettingView.reset'
+ btn.bgColor(0xffdddd)
+ btnLbl.textColor(0xFD5353)
+ btn.on(dxui.Utils.EVENT.CLICK, () => {
+ viewUtils.confirmOpen('systemSettingView.confirmation', 'systemSettingView.confirmReset', () => {
+ dxCommon.systemBrief("rm -rf /app/data/config/*")
+ dxCommon.systemBrief("rm -rf /app/data/db/*")
+ dxCommon.systemBrief("rm -rf /app/data/user/*")
+ dxCommon.systemBrief("rm -rf /vgmj.db")
+ std.setTimeout(() => {
+ dxCommon.systemBrief("reboot -f")
+ }, 1000)
+ }, () => { })
+ })
+ }
+
+ break
+ }
+ })
+
+}
+
+export default systemSettingView
diff --git a/vf205_access/src/view/config/menu/voiceBroadcastView.js b/vf205_access/src/view/config/menu/voiceBroadcastView.js
new file mode 100644
index 0000000..3d31fce
--- /dev/null
+++ b/vf205_access/src/view/config/menu/voiceBroadcastView.js
@@ -0,0 +1,137 @@
+import dxui from '../../../../dxmodules/dxUi.js'
+import std from '../../../../dxmodules/dxStd.js'
+import viewUtils from "../../viewUtils.js"
+import topView from "../../topView.js"
+import configView from '../configView.js'
+import i18n from "../../i18n.js"
+import screen from '../../../screen.js'
+const voiceBroadcastView = {}
+
+const strangerData = ["鏃犺闊�", "璇峰厛娉ㄥ唽", "闄岀敓浜轰綘濂�"]
+const strangerData0 = ["No voice", "Play first register", "Play stranger hello"]
+const voiceModeData = ["鏃犺闊�", "鍚嶅瓧", "闂�欒"]
+const voiceModeData0 = ["No voice", "Play name", "Play greeting"]
+
+voiceBroadcastView.init = function () {
+ /**************************************************鍒涘缓灞忓箷*****************************************************/
+ const screenMain = dxui.View.build('voiceBroadcastView', dxui.Utils.LAYER.MAIN)
+ voiceBroadcastView.screenMain = screenMain
+ screenMain.scroll(false)
+ screenMain.bgColor(0xffffff)
+ screenMain.on(dxui.Utils.ENUM.LV_EVENT_SCREEN_LOADED, () => {
+ topView.changeTheme(true)
+
+ const configAll = screen.getConfig()
+ strangerVoiceDropdown.setOptions(configAll['base.language'] == 'CN' ? strangerData : strangerData0)
+ voiceModeDropdown.setOptions(configAll['base.language'] == 'CN' ? voiceModeData : voiceModeData0)
+
+ strangerVoiceDropdown.setSelected(configAll['face.stranger'])
+ voiceModeDropdown.setSelected(configAll['face.voiceMode'])
+ volumeSlider.value(configAll['base.volume'])
+ volumeSlider.send(dxui.Utils.EVENT.VALUE_CHANGED)
+ })
+
+ const titleBox = viewUtils.title(screenMain, configView.screenMain, 'voiceBroadcastViewTitle', 'voiceBroadcastView.title')
+ titleBox.align(dxui.Utils.ALIGN.TOP_MID, 0, 70)
+
+ const strangerVoiceBox = dxui.View.build('strangerVoiceBox', screenMain)
+ viewUtils._clearStyle(strangerVoiceBox)
+ strangerVoiceBox.bgOpa(0)
+ strangerVoiceBox.setSize(screen.screenSize.width - 28 * 2, 80)
+ strangerVoiceBox.align(dxui.Utils.ALIGN.TOP_MID, 0, 140)
+ strangerVoiceBox.borderWidth(1)
+ strangerVoiceBox.setBorderColor(0xDEDEDE)
+ strangerVoiceBox.obj.setStyleBorderSide(dxui.Utils.ENUM.LV_BORDER_SIDE_BOTTOM, 0)
+
+ const strangerVoiceLbl = dxui.Label.build('strangerVoiceLbl', strangerVoiceBox)
+ strangerVoiceLbl.textFont(viewUtils.font(26))
+ strangerVoiceLbl.dataI18n = 'voiceBroadcastView.strangerVoice'
+ strangerVoiceLbl.align(dxui.Utils.ALIGN.LEFT_MID, 0, 0)
+
+ const strangerVoiceDropdown = dxui.Dropdown.build('strangerVoiceDropdown', strangerVoiceBox)
+ strangerVoiceDropdown.textFont(viewUtils.font(26))
+ strangerVoiceDropdown.getList().textFont(viewUtils.font(26))
+ strangerVoiceDropdown.align(dxui.Utils.ALIGN.RIGHT_MID, 0, 0)
+ strangerVoiceDropdown.setSymbol('/app/code/resource/image/down.png')
+ strangerVoiceDropdown.width(300)
+ strangerVoiceDropdown.setOptions(['璇峰厛娉ㄥ唽', '璇峰厛娉ㄥ唽璇峰厛娉ㄥ唽璇峰厛娉ㄥ唽', '璇峰厛娉ㄥ唽'])
+
+
+ const voiceModeBox = dxui.View.build('voiceModeBox', screenMain)
+ viewUtils._clearStyle(voiceModeBox)
+ voiceModeBox.bgOpa(0)
+ voiceModeBox.setSize(screen.screenSize.width - 28 * 2, 80)
+ voiceModeBox.align(dxui.Utils.ALIGN.TOP_MID, 0, 220)
+ voiceModeBox.borderWidth(1)
+ voiceModeBox.setBorderColor(0xDEDEDE)
+ voiceModeBox.obj.setStyleBorderSide(dxui.Utils.ENUM.LV_BORDER_SIDE_BOTTOM, 0)
+
+ const voiceModeLbl = dxui.Label.build('voiceModeLbl', voiceModeBox)
+ voiceModeLbl.textFont(viewUtils.font(26))
+ voiceModeLbl.dataI18n = 'voiceBroadcastView.voiceMode'
+ voiceModeLbl.align(dxui.Utils.ALIGN.LEFT_MID, 0, 0)
+
+ const voiceModeDropdown = dxui.Dropdown.build('voiceModeDropdown', voiceModeBox)
+ voiceModeDropdown.textFont(viewUtils.font(26))
+ voiceModeDropdown.getList().textFont(viewUtils.font(26))
+ voiceModeDropdown.align(dxui.Utils.ALIGN.RIGHT_MID, 0, 0)
+ voiceModeDropdown.setSymbol('/app/code/resource/image/down.png')
+ voiceModeDropdown.width(300)
+ voiceModeDropdown.setOptions(['璇峰厛娉ㄥ唽', '璇峰厛娉ㄥ唽璇峰厛娉ㄥ唽璇峰厛娉ㄥ唽', '璇峰厛娉ㄥ唽'])
+
+
+ const volumeBox = dxui.View.build('volumeBox', screenMain)
+ viewUtils._clearStyle(volumeBox)
+ volumeBox.bgOpa(0)
+ volumeBox.setSize(screen.screenSize.width - 28 * 2, 80)
+ volumeBox.align(dxui.Utils.ALIGN.TOP_MID, 0, 300)
+ volumeBox.borderWidth(1)
+ volumeBox.setBorderColor(0xDEDEDE)
+ volumeBox.obj.setStyleBorderSide(dxui.Utils.ENUM.LV_BORDER_SIDE_BOTTOM, 0)
+
+ const volumeLbl = dxui.Label.build('volumeLbl', volumeBox)
+ volumeLbl.textFont(viewUtils.font(26))
+ volumeLbl.dataI18n = 'voiceBroadcastView.volume'
+ volumeLbl.align(dxui.Utils.ALIGN.LEFT_MID, 0, 0)
+
+ const volumeValueLbl = dxui.Label.build('volumeValueLbl', volumeBox)
+ volumeValueLbl.textFont(viewUtils.font(26))
+ volumeValueLbl.align(dxui.Utils.ALIGN.RIGHT_MID, 0, 0)
+ volumeValueLbl.width(50)
+ volumeValueLbl.text('0')
+ volumeValueLbl.textAlign(dxui.Utils.TEXT_ALIGN.RIGHT)
+
+ const volumeSlider = dxui.Slider.build('volumeSlider', volumeBox)
+ volumeSlider.width(300)
+ volumeSlider.range(0, 100)
+ volumeSlider.on(dxui.Utils.EVENT.VALUE_CHANGED, () => {
+ volumeValueLbl.text(volumeSlider.value() + '')
+ })
+ volumeSlider.alignTo(volumeValueLbl, dxui.Utils.ALIGN.OUT_LEFT_MID, -10, 0)
+
+ const saveBtn = viewUtils.bottomBtn(screenMain, screenMain.id + 'saveBtn', 'voiceBroadcastView.save', () => {
+ const saveConfigData = {
+ face: {
+ stranger: strangerVoiceDropdown.getSelected(),
+ voiceMode: voiceModeDropdown.getSelected(),
+ },
+ base: {
+ volume: volumeSlider.value(),
+ }
+ }
+ const res = screen.saveConfig(saveConfigData)
+ if (res === true) {
+ voiceBroadcastView.statusPanel.success()
+ std.setTimeout(() => {
+ // 鎴愬姛杩斿洖涓婁竴灞傜晫闈�
+ dxui.loadMain(configView.screenMain)
+ }, 500)
+ } else {
+ voiceBroadcastView.statusPanel.fail()
+ }
+ })
+ saveBtn.align(dxui.Utils.ALIGN.BOTTOM_MID, 0, -83)
+ voiceBroadcastView.statusPanel = viewUtils.statusPanel(screenMain, 'voiceBroadcastView.success', 'voiceBroadcastView.fail')
+}
+
+export default voiceBroadcastView
diff --git a/vf205_access/src/view/config/newPwdView.js b/vf205_access/src/view/config/newPwdView.js
new file mode 100644
index 0000000..da0b51b
--- /dev/null
+++ b/vf205_access/src/view/config/newPwdView.js
@@ -0,0 +1,137 @@
+import dxui from '../../../dxmodules/dxUi.js'
+import std from '../../../dxmodules/dxStd.js'
+import viewUtils from "../viewUtils.js"
+import topView from '../topView.js'
+import mainView from '../mainView.js'
+import identityVerificationView from './identityVerificationView.js'
+import screen from '../../screen.js'
+const newPwdView = {}
+newPwdView.init = function () {
+ /**************************************************鍒涘缓灞忓箷*****************************************************/
+ const screenMain = dxui.View.build('newPwdView', dxui.Utils.LAYER.MAIN)
+ newPwdView.screenMain = screenMain
+ screenMain.scroll(false)
+ screenMain.bgColor(0xffffff)
+ screenMain.on(dxui.Utils.ENUM.LV_EVENT_SCREEN_LOADED, () => {
+ topView.changeTheme(true)
+
+ newPwdView.timer = std.setInterval(() => {
+ let count = dxui.Utils.GG.NativeDisp.lvDispGetInactiveTime()
+ if (count > 15 * 1000) {
+ std.clearInterval(newPwdView.timer)
+ newPwdView.timer = null
+ dxui.loadMain(mainView.screenMain)
+ }
+ }, 1000)
+ // 濡傛灉绠$悊鍛樺瘑鐮佷负绌�,鍒欏脊鍑烘鐣岄潰,鍚﹀垯鐩存帴杩涘叆璁よ瘉鐣岄潰
+ if (screen.getConfig()['base.firstLogin'] == 1) {
+ std.clearInterval(newPwdView.timer)
+ dxui.loadMain(identityVerificationView.screenMain)
+ }
+ })
+ screenMain.on(dxui.Utils.ENUM.LV_EVENT_SCREEN_UNLOADED, () => {
+ if (newPwdView.timer) {
+ std.clearInterval(newPwdView.timer)
+ }
+ })
+
+ const titleBox = viewUtils.title(screenMain, mainView.screenMain, 'newPwdViewTitle', 'newPwdView.title')
+ titleBox.align(dxui.Utils.ALIGN.TOP_MID, 0, 70)
+
+ const pwdInput = viewUtils.input(screenMain, 'newPwdInput', undefined, undefined, 'newPwdView.pwd')
+ pwdInput.align(dxui.Utils.ALIGN.TOP_MID, 0, 211)
+ pwdInput.setPasswordMode(true)
+
+ const eyeFill = viewUtils.imageBtn(screenMain, screenMain.id + 'eye_fill', '/app/code/resource/image/eye-fill.png')
+ eyeFill.alignTo(pwdInput, dxui.Utils.ALIGN.RIGHT_MID, 0, 0)
+ eyeFill.on(dxui.Utils.EVENT.CLICK, () => {
+ pwdInput.setPasswordMode(true)
+ eyeFill.hide()
+ eyeOff.show()
+ })
+ eyeFill.hide()
+
+ const eyeOff = viewUtils.imageBtn(screenMain, screenMain.id + 'eye_off', '/app/code/resource/image/eye-off.png')
+ eyeOff.alignTo(pwdInput, dxui.Utils.ALIGN.RIGHT_MID, 0, 0)
+ eyeOff.on(dxui.Utils.EVENT.CLICK, () => {
+ pwdInput.setPasswordMode(false)
+ eyeFill.show()
+ eyeOff.hide()
+ })
+
+ const confirmPwdInput = viewUtils.input(screenMain, 'confirmPwdInput', undefined, undefined, 'newPwdView.confirmPwd')
+ confirmPwdInput.alignTo(pwdInput, dxui.Utils.ALIGN.OUT_BOTTOM_MID, 0, 30)
+ confirmPwdInput.setPasswordMode(true)
+
+ const eyeFill2 = viewUtils.imageBtn(screenMain, screenMain.id + 'eye_fill2', '/app/code/resource/image/eye-fill.png')
+ eyeFill2.alignTo(confirmPwdInput, dxui.Utils.ALIGN.RIGHT_MID, 0, 0)
+ eyeFill2.on(dxui.Utils.EVENT.CLICK, () => {
+ confirmPwdInput.setPasswordMode(true)
+ eyeFill2.hide()
+ eyeOff2.show()
+ })
+ eyeFill2.hide()
+
+ const eyeOff2 = viewUtils.imageBtn(screenMain, screenMain.id + 'eye_off2', '/app/code/resource/image/eye-off.png')
+ eyeOff2.alignTo(confirmPwdInput, dxui.Utils.ALIGN.RIGHT_MID, 0, 0)
+ eyeOff2.on(dxui.Utils.EVENT.CLICK, () => {
+ confirmPwdInput.setPasswordMode(false)
+ eyeFill2.show()
+ eyeOff2.hide()
+ })
+
+ const tipLbl = dxui.Label.build('newPwdViewTip', screenMain)
+ tipLbl.textFont(viewUtils.font(22))
+ tipLbl.textColor(0x888888)
+ tipLbl.dataI18n = 'newPwdView.tip'
+ tipLbl.align(dxui.Utils.ALIGN.TOP_MID, 0, 530)
+
+ const skipView = dxui.View.build('skipView', screenMain)
+ viewUtils._clearStyle(skipView)
+ const skipLbl = dxui.Label.build('skipLbl', skipView)
+ skipLbl.textFont(viewUtils.font(24))
+ skipLbl.textColor(0x767676)
+ skipLbl.dataI18n = 'newPwdView.skip'
+ const skipText = skipLbl.text
+ skipLbl.text = (data) => {
+ skipText.call(skipLbl, data)
+ skipLbl.update()
+ skipView.setSize(skipLbl.width(), skipLbl.height())
+ }
+ skipLbl.borderWidth(2)
+ skipLbl.obj.setStyleBorderSide(dxui.Utils.ENUM.LV_BORDER_SIDE_BOTTOM, 0)
+ skipLbl.setBorderColor(0x767676)
+
+ const pwdAccessBtn = viewUtils.bottomBtn(screenMain, screenMain.id + 'pwdAccessBtn', 'newPwdView.pwdAccess', () => {
+ if (pwdInput.text() != confirmPwdInput.text()) {
+ newPwdView.statusPanel.fail("newPwdView.pwdNotMatch")
+ return
+ }
+ const res = screen.saveConfig({
+ base: {
+ password: pwdInput.text()
+ }
+ })
+ if (res === true) {
+ newPwdView.statusPanel.success()
+ std.clearInterval(newPwdView.timer)
+ dxui.loadMain(identityVerificationView.screenMain)
+ } else {
+ newPwdView.statusPanel.fail()
+ }
+ })
+ pwdAccessBtn.align(dxui.Utils.ALIGN.BOTTOM_MID, 0, -83)
+
+ skipView.setSize(skipLbl.width(), skipLbl.height())
+ skipView.align(dxui.Utils.ALIGN.BOTTOM_MID, 0, -217)
+ skipView.on(dxui.Utils.EVENT.CLICK, () => {
+ //淇敼鐘舵��
+ screen.saveConfig({ base: { firstLogin: 1 } })
+ std.clearInterval(newPwdView.timer)
+ dxui.loadMain(identityVerificationView.screenMain)
+ })
+
+ newPwdView.statusPanel = viewUtils.statusPanel(screenMain, 'newPwdView.success', 'newPwdView.fail')
+}
+
+export default newPwdView
\ No newline at end of file
diff --git a/vf205_access/src/view/emergencyPwdView.js b/vf205_access/src/view/emergencyPwdView.js
new file mode 100644
index 0000000..01704cc
--- /dev/null
+++ b/vf205_access/src/view/emergencyPwdView.js
@@ -0,0 +1,140 @@
+import dxui from '../../dxmodules/dxUi.js'
+import std from '../../dxmodules/dxStd.js'
+import viewUtils from "./viewUtils.js"
+import topView from './topView.js'
+import mainView from './mainView.js'
+import screen from '../screen.js'
+import logger from '../../dxmodules/dxLogger.js'
+import driver from '../driver.js'
+import config from '../../dxmodules/dxConfig.js'
+
+const emergencyPwdView = {}
+emergencyPwdView.init = function () {
+ /**************************************************鍒涘缓灞忓箷*****************************************************/
+ const screenMain = dxui.View.build('emergencyPwdView', dxui.Utils.LAYER.MAIN)
+ emergencyPwdView.screenMain = screenMain
+ screenMain.scroll(false)
+ screenMain.bgColor(0xffffff)
+ screenMain.on(dxui.Utils.ENUM.LV_EVENT_SCREEN_LOADED, () => {
+ topView.changeTheme(true)
+
+ // 鎾斁搴旀�ラ�氳璇煶鎻愮ず
+ try {
+ driver.alsa.play(`/app/code/resource/${config.get("base.language") == "CN" ? "CN" : "EN"}/wav/emergency.wav`)
+ logger.info('[emergencyPwdView]: 鎾斁搴旀�ラ�氳璇煶鎻愮ず')
+ } catch (error) {
+ logger.error('[emergencyPwdView]: 鎾斁璇煶鎻愮ず澶辫触: ' + error.message)
+ }
+
+ emergencyPwdView.timer = std.setInterval(() => {
+ let count = dxui.Utils.GG.NativeDisp.lvDispGetInactiveTime()
+ if (count > 15 * 1000) {
+ std.clearInterval(emergencyPwdView.timer)
+ emergencyPwdView.timer = null
+ dxui.loadMain(mainView.screenMain)
+ }
+ }, 1000)
+
+ pwdInput.send(dxui.Utils.EVENT.CLICK)
+ pwdInput.send(dxui.Utils.EVENT.FOCUSED)
+ })
+ screenMain.on(dxui.Utils.ENUM.LV_EVENT_SCREEN_UNLOADED, () => {
+ if (emergencyPwdView.timer) {
+ std.clearInterval(emergencyPwdView.timer)
+ }
+ // 娓呯┖楠岃瘉缁撴灉鎻愮ず
+ if (emergencyPwdView.resultLbl) {
+ emergencyPwdView.resultLbl.text(' ')
+ }
+ })
+
+ const titleBox = viewUtils.title(screenMain, mainView.screenMain, 'emergencyPwdViewTitle', '搴旀�ュ瘑鐮侀�氳')
+ titleBox.align(dxui.Utils.ALIGN.TOP_MID, 0, 70)
+
+ const pwdInput = viewUtils.input(screenMain, 'emergencyPwdInput', 2, undefined, '璇疯緭鍏ュ簲鎬ュ瘑鐮�')
+ pwdInput.align(dxui.Utils.ALIGN.TOP_MID, 0, 211)
+ pwdInput.setPasswordMode(true)
+
+ const eyeFill = viewUtils.imageBtn(screenMain, screenMain.id + 'eye_fill', '/app/code/resource/image/eye-fill.png')
+ eyeFill.alignTo(pwdInput, dxui.Utils.ALIGN.RIGHT_MID, 0, 0)
+ eyeFill.on(dxui.Utils.EVENT.CLICK, () => {
+ pwdInput.setPasswordMode(true)
+ eyeFill.hide()
+ eyeOff.show()
+ })
+ eyeFill.hide()
+
+ const eyeOff = viewUtils.imageBtn(screenMain, screenMain.id + 'eye_off', '/app/code/resource/image/eye-off.png')
+ eyeOff.alignTo(pwdInput, dxui.Utils.ALIGN.RIGHT_MID, 0, 0)
+ eyeOff.on(dxui.Utils.EVENT.CLICK, () => {
+ pwdInput.setPasswordMode(false)
+ eyeFill.show()
+ eyeOff.hide()
+ })
+
+ // 娣诲姞鎻愮ず鏂囨湰
+ const hintText1 = dxui.Label.build('hintText1', screenMain)
+ hintText1.text('1.搴旀�ュ紑闂ㄦ棤瑙嗕粨鍐呮皵浣撴祿搴︽槸鍚﹁揪鏍�,璇疯嚜琛岀‘淇濆紑闂ㄥ叆浠撳畨鍏ㄣ��')
+ hintText1.textFont(viewUtils.font(24))
+ hintText1.textColor(0xff0000)
+ hintText1.align(dxui.Utils.ALIGN.TOP_MID, 0, 350)
+ hintText1.longMode(dxui.Utils.LABEL_LONG_MODE.BREAK)
+ hintText1.width(680)
+
+ const hintText2 = dxui.Label.build('hintText2', screenMain)
+ hintText2.text('2.姘旇皟浠撴垨鐔忚捀浠撹鍔″繀浣╂埓涓撲笟璁惧,纭繚鍏ヤ粨瀹夊叏銆�')
+ hintText2.textFont(viewUtils.font(24))
+ hintText2.textColor(0xff0000)
+ hintText2.align(dxui.Utils.ALIGN.TOP_MID, 0, 400)
+ hintText2.longMode(dxui.Utils.LABEL_LONG_MODE.BREAK)
+ hintText2.width(680)
+
+ // 楠岃瘉缁撴灉鎻愮ず
+ const resultLbl = dxui.Label.build('resultLbl', screenMain)
+ resultLbl.text(' ')
+ resultLbl.textFont(viewUtils.font(32))
+ resultLbl.textColor(0x000000)
+ resultLbl.align(dxui.Utils.ALIGN.TOP_MID, 0, 480)
+ emergencyPwdView.resultLbl = resultLbl
+
+ const emergencyAccessBtn = viewUtils.bottomBtn(screenMain, 'emergencyAccessBtn', '搴旀�ュ瘑鐮侀�氳', () => {
+ // 纭瀵嗙爜
+ const pwd = pwdInput.text()
+ const result = screen.pwdAccess(pwd)
+
+ if (result) {
+ // 瀵嗙爜楠岃瘉閫氳繃
+ logger.info('[emergencyPwdView]: 搴旀�ュ瘑鐮侀獙璇侀�氳繃')
+ resultLbl.text('搴旀�ュ瘑鐮侀獙璇侀�氳繃锛屾鍦ㄥ紑浠�...')
+ resultLbl.textColor(0x008000)
+
+ // 寮�缁х數鍣�
+ try {
+ driver.gpio.open() // 鎵撳紑缁х數鍣ㄥ苟鍦ㄦ寚瀹氭椂闂村悗鑷姩鍏抽棴
+ logger.info(`[emergencyPwdView]: 鎵撳紑缁х數鍣ㄦ垚鍔焋)
+ resultLbl.text('搴旀�ュ瘑鐮侀獙璇侀�氳繃锛屽凡寮�浠擄紒')
+ } catch (error) {
+ logger.error(`[emergencyPwdView]: 鎵撳紑缁х數鍣ㄥけ璐�: ${error.message}`)
+ }
+
+ // 璇煶鎻愮ず
+ driver.alsa.play(`/app/code/resource/${config.get("base.language") == "CN" ? "CN" : "EN"}/wav/emergency_s.wav`)
+
+ // 寤惰繜杩斿洖涓荤晫闈�
+ std.setTimeout(() => {
+ dxui.loadMain(mainView.screenMain)
+ }, 3000)
+ } else {
+ // 瀵嗙爜楠岃瘉澶辫触
+ logger.info('[emergencyPwdView]: 搴旀�ュ瘑鐮侀獙璇佸け璐�')
+ resultLbl.text('搴旀�ュ瘑鐮侀敊璇紝璇烽噸鏂拌緭鍏�')
+ resultLbl.textColor(0xff0000)
+
+ // 璇煶鎻愮ず
+ driver.alsa.play(`/app/code/resource/${config.get("base.language") == "CN" ? "CN" : "EN"}/wav/emergency_f.wav`)
+ }
+ })
+ emergencyAccessBtn.align(dxui.Utils.ALIGN.BOTTOM_MID, 0, -83)
+}
+
+export default emergencyPwdView
\ No newline at end of file
diff --git a/vf205_access/src/view/i18n.js b/vf205_access/src/view/i18n.js
new file mode 100644
index 0000000..b9c8936
--- /dev/null
+++ b/vf205_access/src/view/i18n.js
@@ -0,0 +1,82 @@
+import dxMap from '../../dxmodules/dxMap.js'
+import dxui from '../../dxmodules/dxUi.js'
+// 璇█鍖�
+import messages from '../../resource/langPack.js'
+
+class I18n {
+ constructor() {
+ const i18nMap = dxMap.get("i18n")
+ this.locale = i18nMap.get("language") || 'EN'
+ this.fallbackLocale = 'CN'
+ }
+
+ // 鑾峰彇缈昏瘧鏂囨湰
+ t(key) {
+ const keys = key.split('.')
+ let result = messages[this.locale]
+
+ for (const k of keys) {
+ if (result && result[k]) {
+ result = result[k]
+ } else {
+ // 濡傛灉褰撳墠璇█娌℃湁鎵惧埌缈昏瘧锛屼娇鐢ㄥ鐢ㄨ瑷�
+ result = this._getFallbackText(key)
+ break
+ }
+ }
+
+ return result || key
+ }
+
+ // 鑾峰彇澶囩敤璇█鐨勭炕璇�
+ _getFallbackText(key) {
+ const keys = key.split('.')
+ let result = messages[this.fallbackLocale]
+
+ for (const k of keys) {
+ if (result && result[k]) {
+ result = result[k]
+ } else {
+ return key
+ }
+ }
+
+ return result
+ }
+
+ // 鍒锋柊
+ refresh() {
+ for (const key in dxui.all) {
+ const obj = dxui.all[key]
+ if (obj.dataI18n) {
+ obj.text(this.t(obj.dataI18n))
+ }
+ }
+ }
+
+ // 鍒锋柊鎸囧畾瀵硅薄
+ refreshObj(obj) {
+ if (obj.dataI18n) {
+ obj.text(this.t(obj.dataI18n))
+ }
+ }
+
+ // 鍒囨崲璇█
+ setLanguage(lang) {
+ if (messages[lang]) {
+ this.locale = lang
+ dxMap.get("i18n").put("language", lang)
+ // 瑙﹀彂鑷畾涔変簨浠讹紝閫氱煡璇█鍙樺寲
+ for (const key in dxui.all) {
+ const obj = dxui.all[key]
+ if (obj.dataI18n) {
+ obj.text(this.t(obj.dataI18n))
+ }
+ }
+ }
+ }
+}
+
+// 鍒涘缓鍗曚緥
+const i18n = new I18n()
+export default i18n
diff --git a/vf205_access/src/view/idleView.js b/vf205_access/src/view/idleView.js
new file mode 100644
index 0000000..fb0ff43
--- /dev/null
+++ b/vf205_access/src/view/idleView.js
@@ -0,0 +1,54 @@
+import dxui from '../../dxmodules/dxUi.js'
+import viewUtils from './viewUtils.js'
+import std from '../../dxmodules/dxStd.js'
+import i18n from './i18n.js'
+import screen from '../screen.js'
+const idleView = {}
+idleView.init = function () {
+ /**************************************************鍒涘缓灞忓箷*****************************************************/
+ const screenMain = dxui.View.build('idleView', dxui.Utils.LAYER.SYS)
+ idleView.screenMain = screenMain
+ viewUtils._clearStyle(screenMain)
+ screenMain.hide()
+ screenMain.scroll(false)
+ screenMain.width(screen.screenSize.width)
+ screenMain.height(screen.screenSize.height)
+
+ const idleImage = dxui.Image.build('idleImage', screenMain)
+ // 灞忎繚鍥剧墖
+ idleImage.source('/app/code/resource/image/idleImage.jpg')
+
+ const dateBox = dxui.View.build('dateBox', screenMain)
+ viewUtils._clearStyle(dateBox)
+ dateBox.width(600)
+ dateBox.height(200)
+ dateBox.align(dxui.Utils.ALIGN.CENTER, 0, 0)
+ dateBox.bgOpa(0)
+
+ const timeLbl = dxui.Label.build(dateBox.id + 'timeLbl', dateBox)
+ timeLbl.textFont(viewUtils.font(80, dxui.Utils.FONT_STYLE.BOLD))
+ timeLbl.text("10:00:00")
+ timeLbl.textColor(0xffffff)
+ timeLbl.align(dxui.Utils.ALIGN.TOP_MID, 0, 0)
+
+ const dateLbl = dxui.Label.build(dateBox.id + 'dateLbl', dateBox)
+ dateLbl.textFont(viewUtils.font(40))
+ dateLbl.text("2025-01-17 鍛ㄤ簲")
+ dateLbl.textColor(0xffffff)
+ dateLbl.align(dxui.Utils.ALIGN.BOTTOM_MID, 0, 0)
+
+ std.setInterval(() => {
+ const t = new Date();
+ // 琛ラ浂鍑芥暟
+ const pad = (n) => n < 10 ? `0${n}` : n;
+ // 鑾峰彇鏄熸湡鐨勫浗闄呭寲鏂囨湰
+ const weekDay = i18n.t(`idleView.week.${t.getDay()}`);
+
+ timeLbl.text(`${pad(t.getHours())}:${pad(t.getMinutes())}:${pad(t.getSeconds())}`)
+ dateLbl.text(`${t.getFullYear()}-${pad(t.getMonth() + 1)}-${pad(t.getDate())} ${weekDay}`)
+ }, 1000, true)
+
+}
+
+
+export default idleView
\ No newline at end of file
diff --git a/vf205_access/src/view/mainView.js b/vf205_access/src/view/mainView.js
new file mode 100644
index 0000000..b3b35ef
--- /dev/null
+++ b/vf205_access/src/view/mainView.js
@@ -0,0 +1,1646 @@
+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, // 璁よ瘉鏄惁瀹屾垚锛岀敤浜庢帶鍒禪I鏇存柊
+ 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)
+
+
+
+ // 鏇存柊璁惧淇℃伅锛圫N鍜孖P锛�
+ function updateDeviceInfo() {
+ let config = screen.getConfig()
+ let sn = config["sys.sn"] || ""
+ // 鐩存帴浠巒et妯″潡鑾峰彇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) {
+ // 鍑洪敊鏃朵娇鐢╟onfig涓殑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) {
+ // 缃戠粶杩炴帴鏃舵洿鏂癐P淇℃伅
+ 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鐨刄I
+ 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("瑙f瀽鐢ㄦ埛2绫诲瀷澶辫触")
+ }
+
+ // 妫�鏌ョ敤鎴�2鏉冮檺
+ let hasPermission2 = false
+ let permissions2 = sqliteService.d1_permission.find({ userId: dualAuthInfo.secondUserId })
+ if (permissions2 && permissions2.length > 0) {
+ hasPermission2 = true
+ }
+
+ // 鏇存柊鐢ㄦ埛2鐨刄I
+ 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鐨刄I
+ logger.info('[mainView]: 鐢ㄦ埛宸蹭綔涓虹浜岀敤鎴疯繘琛屼簡璁よ瘉锛屼笉鏇存柊鐢ㄦ埛1鐨刄I')
+ } 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("瑙f瀽鐢ㄦ埛绫诲瀷澶辫触")
+ }
+
+ // 妫�鏌ョ敤鎴锋潈闄�
+ let hasPermission = false
+ let permissions = sqliteService.d1_permission.find({ userId: userId })
+ if (permissions && permissions.length > 0) {
+ hasPermission = true
+ }
+
+ // 鏇存柊鐢ㄦ埛1鐨刄I
+ 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鍒嗛挓鍚庨噸缃敤鎴稶I鐨勫畾鏃跺櫒
+ resetTimerId = std.setTimeout(() => {
+ logger.info('[mainView]: 1鍒嗛挓瀹氭椂鍣ㄨЕ鍙戯紝閲嶇疆鐢ㄦ埛UI')
+ // 瑙﹀彂閫氳瑙i攣瀹屾垚浜嬩欢锛岄�氱煡UI閲嶇疆
+ bus.fire("accessUnlockComplete")
+ }, 60000) // 60000姣 = 1鍒嗛挓
+ logger.info('[mainView]: 璁剧疆1鍒嗛挓鍚庨噸缃敤鎴稶I鐨勫畾鏃跺櫒')
+ })
+
+ // 鐘舵�佷俊鎭洿鏂颁簨浠剁洃鍚�
+ bus.on('statusInfoUpdated', (data) => {
+ // 鍙鐞嗗畨鍏ㄥ叆浠撴帶鍒剁殑鍝嶅簲锛屽拷鐣ラ潪瀹夊叏鍏ヤ粨鎺у埗鐨勫搷搴�
+ const safeInputControlFunctionId = config['functionId.safeInputControl'] || '2000'
+ if (data.functionId && data.functionId !== safeInputControlFunctionId) {
+ logger.info(`[mainView]: 蹇界暐闈炲畨鍏ㄥ叆浠撴帶鍒剁殑鍝嶅簲锛宖unctionId=${data.functionId}`)
+ return
+ }
+
+ // 杩欓噷鍙互鏍规嵁瀹為檯鐨勭姸鎬佷俊鎭暟鎹粨鏋勬潵鏇存柊UI
+ logger.info(`[mainView]: 鐘舵�佷俊鎭洿鏂�: ${JSON.stringify(data)}`)
+
+ // 妫�鏌ヨ繑鍥炵殑mode鍜宐tn鍙傛暟
+ if (data.data) {
+ const mode = parseInt(data.data.mode) // 灏嗗瓧绗︿覆杞崲涓烘暟瀛�
+ const btn = parseInt(data.data.btn) // 灏嗗瓧绗︿覆杞崲涓烘暟瀛�
+
+ logger.info(`[mainView]: 鎺ユ敹鍒癿ode=${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鍜宐tn鏇存柊鎸夐挳鐘舵��
+ 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)
+ }
+ }
+ })
+
+ // 閫氳瑙i攣瀹屾垚浜嬩欢鐩戝惉锛岄噸缃敤鎴稶I
+ bus.on('accessUnlockComplete', () => {
+ logger.info('[mainView]: accessUnlockComplete浜嬩欢瑙﹀彂锛岄噸缃敤鎴稶I')
+
+ // 閲嶇疆璁よ瘉瀹屾垚鏍囧織
+ mainView.authComplete = false
+ // 閲嶇疆宸叉牳楠岀敤鎴蜂俊鎭�
+ mainView.verifiedUsers = {}
+
+ // 閲嶇疆鐢ㄦ埛1鐨刄I
+ 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鐨刄I
+ 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宸查噸缃�')
+ })
+
+ // 浜鸿劯璇嗗埆缁撴灉浜嬩欢鐩戝惉锛堢Щ鍒癓V_EVENT_SCREEN_LOADED鍥炶皟涓級
+ if (!mainView.trackResultListenerRegistered) {
+ logger.info('[mainView]: 寮�濮嬫敞鍐宼rackResult浜嬩欢鐩戝惉鍣�')
+ 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]: 浜嬩欢鐩戝惉鍣ㄦ敞鍐屽畬鎴�')
+ }
+
+ // 瀛樺偍瀹氭椂鍣↖D
+ 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宸插垱寤哄苟鏄剧ず')
+
+ // 鍦╫verlayBox涓婂垱寤鸿璇佺粨鏋滃睍绀哄尯鍩燂紙浣嶄簬userBox鍜宑ontrolBox涔嬮棿锛�
+ // 鍒濆鍖栧皬鍨嬬姸鎬侀潰鏉�
+ 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)
+ }
+
+ // 璁惧淇℃伅鏄剧ず锛圫N鍜孖P锛�- 鎻愬墠瀹氫箟锛岀‘淇濆湪鍥炶皟涓彲鐢�
+ 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 // 璁剧疆涓簃ainView灞炴��
+
+ 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 // 璁剧疆涓簃ainView灞炴��
+
+ // 姘ф皵鍗曚綅閮ㄥ垎
+ const oxygenUnit = dxui.Label.build('oxygenUnit', oxygenValueContainer)
+ oxygenUnit.text('%')
+ oxygenUnit.textFont(viewUtils.font(14))
+ oxygenUnit.textColor(0xffffff)
+ mainView.oxygenUnit = oxygenUnit // 璁剧疆涓簃ainView灞炴��
+
+ 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 // 璁剧疆涓簃ainView灞炴��
+
+ // 纾峰寲姘㈡祿搴�
+ 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 // 璁剧疆涓簃ainView灞炴��
+
+ 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 // 璁剧疆涓簃ainView灞炴��
+
+ // 纾峰寲姘㈠崟浣嶉儴鍒�
+ const ph3Unit = dxui.Label.build('ph3Unit', ph3ValueContainer)
+ ph3Unit.text('PPM')
+ ph3Unit.textFont(viewUtils.font(14))
+ ph3Unit.textColor(0xffffff)
+ mainView.ph3Unit = ph3Unit // 璁剧疆涓簃ainView灞炴��
+
+ 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 // 璁剧疆涓簃ainView灞炴��
+
+ // 浜屾哀鍖栫⒊娴撳害
+ 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 // 璁剧疆涓簃ainView灞炴��
+
+ 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 // 璁剧疆涓簃ainView灞炴��
+
+ // 浜屾哀鍖栫⒊鍗曚綅閮ㄥ垎
+ const co2Unit = dxui.Label.build('co2Unit', co2ValueContainer)
+ co2Unit.text('PPM')
+ co2Unit.textFont(viewUtils.font(14))
+ co2Unit.textColor(0xffffff)
+ mainView.co2Unit = co2Unit // 璁剧疆涓簃ainView灞炴��
+
+ 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 // 璁剧疆涓簃ainView灞炴��
+
+ // 鏃堕棿鏄剧ず
+ 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 // 璁剧疆涓簃ainView灞炴��
+ logger.info('[mainView]: userBox宸插垱寤哄苟鏄剧ず鍦ㄩ《閮ㄤ笅鏂�580鍍忕礌浣嶇疆')
+
+
+ // 鐢ㄦ埛1
+ const user1Box = dxui.Image.build('user1Box', userBox)
+ viewUtils._clearStyle(user1Box)
+ user1Box.setSize(239, 193) // 浣跨敤姝g‘鐨勮儗鏅浘鐗囧昂瀵�
+ user1Box.source('/app/code/resource/image/user_w.png') // 榛樿浣跨敤寰呮牳楠岃儗鏅浘
+ mainView.user1Box = user1Box // 璁剧疆涓簃ainView灞炴��
+
+ // 濮撳悕
+ 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 // 璁剧疆涓簃ainView灞炴��
+
+ // 鏉冮檺
+ 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 // 璁剧疆涓簃ainView灞炴��
+
+ // 鏍搁獙鐘舵��
+ 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 // 璁剧疆涓簃ainView灞炴��
+
+ // 鐢ㄦ埛2
+ const user2Box = dxui.Image.build('user2Box', userBox)
+ viewUtils._clearStyle(user2Box)
+ user2Box.setSize(239, 193) // 浣跨敤姝g‘鐨勮儗鏅浘鐗囧昂瀵�
+ user2Box.source('/app/code/resource/image/user_w.png') // 榛樿浣跨敤寰呮牳楠岃儗鏅浘
+ mainView.user2Box = user2Box // 璁剧疆涓簃ainView灞炴��
+
+ // 濮撳悕
+ 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 // 璁剧疆涓簃ainView灞炴��
+
+ // 鏉冮檺
+ 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 // 璁剧疆涓簃ainView灞炴��
+
+ // 鏍搁獙鐘舵��
+ 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 // 璁剧疆涓簃ainView灞炴��
+
+ // 鏇存柊鐢ㄦ埛UI鐨勬柟娉�
+ mainView.updateUserUI = function(userIndex, userId, forceUpdate = false, fileName = null) {
+ // 鍙湪璁よ瘉鏈畬鎴愭垨寮哄埗鏇存柊鏃舵洿鏂扮敤鎴稶I
+ 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("瑙f瀽鐢ㄦ埛绫诲瀷澶辫触")
+ }
+
+ // 妫�鏌ョ敤鎴锋潈闄�
+ let hasPermission = false
+ let permissions = sqliteService.d1_permission.find({ userId: userId })
+ if (permissions && permissions.length > 0) {
+ hasPermission = true
+ }
+
+ // 鏍规嵁鐢ㄦ埛搴忓彿鏇存柊瀵瑰簲鐨刄I
+ if (userIndex === 1) {
+ // 绗竴涓敤鎴凤紝鏇存柊鐢ㄦ埛1鐨刄I
+ 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]: 鍥剧墖杞崲鎴愬姛锛宨mageId=' + imageId)
+ // // 璋冩暣鍥惧儚澶у皬涓�160x160
+ // const resizedImageId = capturer.imageResizeResolution(imageId, 160, 160, 3) // 3琛ㄧずFILTER_MODE_BOX
+ // if (resizedImageId) {
+ // logger.info('[mainView]: 鍥剧墖璋冩暣鎴愬姛锛宺esizedImageId=' + 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]: 鍥剧墖淇濆瓨鎴愬姛锛宼empFileName=' + 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鍥炬爣澶辫触锛宖ileName=' + fileName + ', user1Icon=' + mainView.user1Icon)
+ // }
+ logger.info('[mainView]: 鐢ㄦ埛1淇℃伅宸叉洿鏂帮細' + userName + ', ' + (userType === 1 ? '绉戦暱' : '淇濈鍛�') + ', ' + (hasPermission ? '鏍搁獙鎴愬姛' : '鏍搁獙澶辫触'))
+ } else if (userIndex === 2) {
+ // 绗簩涓敤鎴凤紝鏇存柊鐢ㄦ埛2鐨刄I
+ 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]: 鍥剧墖杞崲鎴愬姛锛宨mageId=' + imageId)
+ // // 璋冩暣鍥惧儚澶у皬涓�160x160
+ // const resizedImageId = capturer.imageResizeResolution(imageId, 160, 160, 3) // 3琛ㄧずFILTER_MODE_BOX
+ // if (resizedImageId) {
+ // logger.info('[mainView]: 鍥剧墖璋冩暣鎴愬姛锛宺esizedImageId=' + 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]: 鍥剧墖淇濆瓨鎴愬姛锛宼empFileName=' + 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鍥炬爣澶辫触锛宖ileName=' + fileName + ', user2Icon=' + mainView.user2Icon)
+ // }
+ logger.info('[mainView]: 鐢ㄦ埛2淇℃伅宸叉洿鏂帮細' + userName + ', ' + (userType === 1 ? '绉戦暱' : '淇濈鍛�') + ', ' + (hasPermission ? '鏍搁獙鎴愬姛' : '鏍搁獙澶辫触'))
+ } else {
+ // 鏈煡鐢ㄦ埛搴忓彿锛岄粯璁ゆ洿鏂扮敤鎴�1鐨刄I
+ 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 // 璁剧疆涓簃ainView灞炴��
+
+ 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('(姝e父淇濈/鍏ョ伯鍚庢湡)')
+ 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 // 璁剧疆涓簃ainView灞炴��
+
+ 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 // 璁剧疆涓簃ainView灞炴��
+
+ 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 // 璁剧疆涓簃ainView灞炴��
+
+ 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 // 璁剧疆涓簃ainView灞炴��
+
+ 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 // 璁剧疆涓簃ainView灞炴��
+
+ 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 // 璁剧疆涓簃ainView灞炴��
+
+ 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 // 璁剧疆涓簃ainView灞炴��
+
+ 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 // 璁剧疆涓簃ainView灞炴��
+
+ 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 // 璁剧疆涓簃ainView灞炴��
+
+ 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 // 璁剧疆涓簃ainView灞炴��
+
+ 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 // 璁剧疆涓簃ainView灞炴��
+
+ 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
diff --git a/vf205_access/src/view/pinyin/dict.js b/vf205_access/src/view/pinyin/dict.js
new file mode 100644
index 0000000..00dca5b
--- /dev/null
+++ b/vf205_access/src/view/pinyin/dict.js
@@ -0,0 +1,410 @@
+const dict = {
+ "a": "鍟婇樋鍚栧梽鑵岄敃",
+ "ai": "鍩冩尐鍝庡攭鍝�鐨戠檶钄肩煯鑹剧鐖遍殬鎹卞棾鍡屽櫕瀚掔懛鏆х牴閿块湱",
+ "an": "闉嶆皑瀹変亢鎸夋殫宀歌兒妗堣皺鍩彏鐘村旱妗夐摰楣岄化",
+ "ang": "鑲槀鐩�",
+ "ao": "鍑规晼鐔勘琚勫偛濂ユ噴婢冲澇鎷楀椃宀欏粧閬ㄥ楠滅崚鐕犺伇铻強槌岄彇",
+ "ba": "鑺崒鎵掑彮鍚х瑔鍏枻宸存嫈璺嬮澏鎶婅�欏潩闇哥舰鐖镐集鑼囪彎钀嗘嵀宀滅仦閽矐椴呴瓋",
+ "bai": "鐧芥煆鐧炬憜浣拌触鎷滅浼枩鎹憲鎺�",
+ "ban": "鏂戠彮鎼壋鑸鏉跨増鎵媽浼寸摚鍗婂姙缁婇槳鍧傝背閽g槩鐧嶈埁",
+ "bang": "閭﹀府姊嗘鑶�缁戞纾呰殞闀戝倣璋よ挕娴�",
+ "bao": "鑻炶優鍖呰鍓ヨ杽闆逛繚鍫¢ケ瀹濇姳鎶ユ毚璞归矋鐖嗗埁鏇濆嫻钁嗗鐓查辅瑜撹兜榫�",
+ "bei": "鏉鎮插崙鍖楄緢鑳岃礉閽″�嶇媹澶囨儷鐒欒鑷傚煿瀛涢檪閭惰悊钃撳憲鎮栫楣庤閻鹃灤",
+ "ben": "濂旇嫰鏈澶暁鍧岃床閿�",
+ "beng": "铓屽穿缁风敪娉佃功杩稿爧鍞槪鐢�",
+ "bi": "閫奸蓟姣旈剻绗斿郊纰ц摉钄芥瘯姣欐瘱甯佸簢鐥归棴鏁濆紛蹇呰緹澹佽噦閬块櫅鎷傜娉屽寱浠充烤鑺樿崪鑽歌悊钖滄嵀鍚″摂鐙村撼鎰庢粭婵炲技濡e瀣栫挧璐茬潵鐣�閾嬬瑁ㄧ瓪绠呯鑸璺搁珋",
+ "bian": "闉竟缂栬船鎵佷究鍙樺崬杈ㄨ京杈亶鍖惧紒鑻勫凯姹寸紡鐓哥牠纰ョü绐嗚铦欑槌�",
+ "biao": "鏍囧姜鑶樿〃濠婇獱椋戦椋氱伂闀栭暢鐦1槌旈珶",
+ "bie": "鎹岄硸鎲嬪埆鐦供",
+ "bin": "褰枌婵掓花瀹炬憟鍌ц背缂ゆ娈¤啈闀旈珜楝�",
+ "bing": "鍏靛啺鏌勪笝绉夐ゼ鐐崇梾骞跺睆绂�鍐偞鎽掓鐕�",
+ "bo": "鏌忕櫨鑸墺钖勭幓鑿犳挱鎷ㄩ挼娉㈠崥鍕冩悘閾傜當浼笡鑸惰剸鑶婃袱娉婇┏鍗滀撼钑冭枩鎿楀暤楗借壌妾楁摌绀撮捁楣佺案瓒佃窙韪�",
+ "bu": "鍫℃崟鍗滃摵琛ュ煚涓嶅竷姝ョ翱閮ㄦ�栧煍鍗熼�嬬摽鏅¢挌閽搁啳",
+ "ca": "鎿﹀殦绀�",
+ "cai": "鐚滆鏉愭墠璐㈢潿韪╅噰褰╄彍钄�",
+ "can": "椁愬弬铓曟畫鎯儴鐏垮楠栫挩绮查华",
+ "cang": "鑻嶈埍浠撴钵钘�",
+ "cao": "鎿嶇硻妲芥浌鑽夎壒鍢堟紩灞灛鑹�",
+ "ce": "鍘曠瓥渚у唽娴嬫伝",
+ "cen": "鍙傚矐娑�",
+ "ceng": "灞傝弓鏇惧檶",
+ "cha": "鎻掑弶鑼尪鏌ョ⒋鎼藉療宀斿樊璇у埞鍠冲殦鐚归姹婂Ч鏉堟妾敻闀茶々",
+ "chai": "宸媶鏌磋焙渚挆鐦ヨ櫩",
+ "chan": "鎼�鎺鸿潐棣嬭皸缂犻摬浜ч槓棰ゅ崟鍐佽皠钂囧粵蹇忔胶婢跺缇煎┑楠h绂呴暋锜捐簲",
+ "chang": "鏄岀寲鍦哄皾甯搁暱鍋胯偁鍘傛暈鐣呭敱鍊¤3鍊樹讥楝媽鑿栧緶鎬呮儩闃婂瀚︽樁姘呴渤",
+ "chao": "瓒呮妱閽炴湞鍢叉疆宸㈠惖鐐掑壙鎬婃檨鐒��",
+ "che": "杞︽壇鎾ゆ帲褰绘緢灏哄澕灞牀",
+ "chen": "閮磋嚕杈板皹鏅ㄥ勘娌夐檲瓒佽‖绉版矆浼ц皩璋舵娀鍡斿鐞涙鑲滅榫�",
+ "cheng": "鎾戠О鍩庢鎴愬憟涔樼▼鎯╂緞璇氭壙閫為獘绉ょ洓涓炲煏鏋ㄦ熃妯樻櫉濉嶇灎閾栭摏瑁庤洀閰�",
+ "chi": "鍚冪棿鎸佸寵姹犺繜寮涢┌鑰婚娇渚堝昂璧ょ繀鏂ョ偨鍌洪儣澧�鑼屽彵鍝у暬鍡ゅ匠楗鏁曠湹楦辩槢瑜毄铻瑸绡眽韪熼瓚",
+ "chong": "鍏呭啿铏磭瀹犳秾閲嶈尯蹇℃啩閾宠垈鑹�",
+ "chou": "鎶介叕鐣磋笇绋犳剚绛逛粐缁哥瀰涓戣嚟淇﹀副鎯嗙槼闆�",
+ "chu": "鍒濆嚭姗卞帹韬囬攧闆忔粊闄ゆ纭�鍌ㄧ煑鎼愯Е澶勭暅浜嶅垗鎬垫喎缁屾澋妤瑜氳湇韫伴粶",
+ "chuai": "鎻f悑鍟愬槵鑶腹",
+ "chuan": "宸濈┛妞戒紶鑸瑰枠涓叉幘鑸涢亜宸涙皻閽忚垺韪�",
+ "chuang": "鐤獥骞㈠簥闂垱鎬�",
+ "chui": "鍚圭倞鎹堕敜鍨傞櫜妫版",
+ "chun": "鏄ユた閱囧攪娣崇函锠㈣幖鑲箲铦�",
+ "chuo": "鎴崇话缂�鍟滆径杈嶇劘瓒佃笖榫�",
+ "ci": "宸柕鑼ㄧ闆岃緸鎱堢摲璇嶆鍒鸿祼娆′己鍏硅寛鍛插弹绁犻箽绮㈢硩",
+ "cong": "鑱懕鍥卞寙浠庝笡鑻佹窓楠㈢惍鐠佹灋",
+ "cou": "鍑戞ケ杈忚厾",
+ "cu": "绮楅唻绨囦績鍗掕敓寰傜対娈傞參韫欒勾",
+ "cuan": "韫跨绐滄敀姹嗘捄鐖ㄩ暕",
+ "cui": "鎽у磾鍌剢鐦佺补娣繝钀冨晲鎮寸拃姒辨闅�",
+ "cun": "鏉戝瓨瀵稿繓鐨�",
+ "cuo": "纾嬫挳鎼撴帾鎸敊鍘濆弹鑴為攭鐭棨鐦ラ咕韫�",
+ "da": "鎼揪绛旂槱鎵撳ぇ鑰峰搾鍡掓�涘Σ鐤歌ぁ绗澕闉�",
+ "dai": "澶у憜姝瑰偅鎴村甫娈嗕唬璐疯寰呴��犲煭鐢欏脖杩ㄩ�獉缁愮幊榛�",
+ "dan": "鑰芥媴涓瑰崟閮告幐鑳嗘棪姘絾鎯贰璇炲脊铔嬬煶鐐稿剫钀忓晼婢规径娈氳禃鐪堢柛鐦呰亙绠�",
+ "dang": "褰撴尅鍏氳崱妗h盃鍑艰彧瀹曠爛閾涜",
+ "dao": "鍒�鎹h箞鍊掑矝绁峰鍒扮ɑ鎮奸亾鐩楀垈鍙ㄥ副蹇夋皹鐒樼簺",
+ "de": "寰峰緱鐨勫湴閿�",
+ "dei": "寰�",
+ "deng": "婢勮宫鐏櫥绛夌灙鍑抽倱鍣斿稘鎴ョ4闀唉",
+ "di": "鐨勫牑浣庢淮杩晫绗涚媱娑ょ繜瀚℃姷搴曞湴钂傜甯濆紵閫掔紨缁︽彁姘愮贝璇嬭皼閭稿澔鑽诲榾濞f煝妫h鐮ョ⒉鐫囬暆缇濋",
+ "dia": "鍡�",
+ "dian": "棰犳巶婊囩鐐瑰吀闈涘灚鐢典絻鐢稿簵鎯﹀娣�娈块樈鍧煗宸呯幏閽跨櫆鐧盁韪�",
+ "diao": "纰夊徏闆曞噵鍒佹帀鍚婇挀璋冮笩閾為摣铚╄矀椴�",
+ "die": "璺岀埞纰熻澏杩皪鍙犲灓鍫炴彶鍠嬪棽鐗掔摓鑰嬭箑椴�",
+ "ding": "涓佺洴鍙拤椤堕紟閿畾璁粌钁跺暥鐜庤厷纰囩敽鐤旇�甸厞",
+ "diu": "涓㈤摜",
+ "dong": "涓滃啲钁f噦鍔ㄦ爧渚楁伀鍐绘礊鍨屽挌宀藉硳姘¤儴鑳寸楦�",
+ "dou": "鍏滄姈鏂楅櫋璞嗛�楃棙閮借钄搁挱绐︾铓",
+ "du": "閮界潱姣掔妸鐙鍫电澒璧屾潨闀�鑲氬害娓″鑺忓槦娓庢鐗嶈牴绗冪簺楂戦哗",
+ "duan": "绔煭閿绘鏂紟妞寸厖绨栬腹",
+ "dui": "鍫嗗厬闃熷鎬兼啙纰撻暒",
+ "dun": "澧╁惃韫叉暒椤块挐鐩鹃亖娌岀倴鐮樼鐩归暒瓒�",
+ "duo": "搴︽巼鍝嗗澶哄灈韬叉湹璺鸿埖鍓佹儼鍫曢┊鍜勫摎缂嶆焷閾庤0閰¤副",
+ "e": "闃胯浘宄ㄩ箙淇勯璁瑰ē鎭跺巹鎵奸亸閯傞タ鍝﹂鍣╄皵鍨╄媻鑾惣鍛冨晲鎰曢槒灞欏﹢杞浄鑵攪閿烽箺棰氳毜槌�",
+ "ei": "宸ヨ",
+ "EN": "鎭╄捊鎽佸棷",
+ "er": "鑰屽効鑰冲皵楗垫幢浜岃窗浣磋咯鐝ラ搾楦搁矔",
+ "fa": "鍙戠綒绛忎紣涔忛榾娉曠彁鍨$牆",
+ "fan": "钘╁竼鐣炕妯婄熅閽掔箒鍑$儲鍙嶈繑鑼冭穿鐘キ娉涜晝铇╁埂姊电嚁鐣堣ⅱ韫�",
+ "fang": "鍧婅姵鏂硅偑鎴块槻濡ㄤ豢璁跨汉鏀惧寶閭″椒鏋嬮挮鑸矀",
+ "fei": "鑿查潪鍟¢鑲ュ尓璇藉悹鑲哄簾娌歌垂鑺捐寚鐙掓偙娣濆缁Η鑵撴枑鎵夌牘闀勭棻铚氱瘹缈¢湉椴�",
+ "fen": "鑺厷鍚╂皼鍒嗙悍鍧熺剼姹剧矇濂嬩唤蹇挎劋绮伨鐎电帰妫肩嚁鎰嶉布榧�",
+ "feng": "涓板皝鏋渹宄伴攱椋庣柉鐑介�㈠啹缂濊濂夊嚖淇搁厗钁戝敧娌i�勭牅",
+ "fo": "浣�",
+ "fou": "鍚︾级",
+ "fu": "浣涘か鏁疯偆瀛垫壎鎷傝緪骞呮盁绗︿紡淇樻湇娴丢绂忚⒈寮楃敨鎶氳緟淇嚋鏂ц劘鑵戝簻鑵愯荡鍓璧嬪鍌呬粯闃滅埗鑵硅礋瀵岃闄勫缂氬拹鍖愬嚝闃濋儧鑺欒娋鑻昏尟鑿旀媻鎺婂憢骞炴�粡瀹撹壌瀛氶└缁傜粙妗磋禉绁撶牘榛婚患缃樼▋棣ヨ毃",
+ "ga": "鍣跺槑鑳冲す浠风晫鍜栦冀灏懛灏曞皽鏃拞",
+ "gai": "璇ユ敼姒傞挋鐩栨簤鑺ヤ笎闄斿灀鎴よ祬鑳�",
+ "gan": "骞茬敇鏉嗘煈绔胯倽璧舵劅绉嗘暍璧i棿鍧╄嫹灏存搥娉旀乏婢夌粈姗勬棸鐭哥柍閰�",
+ "gang": "鍐堝垰閽㈢几鑲涚翰宀楁腐鏉犳垎缃$",
+ "gao": "绡欑殝楂樿啅缇旂硶鎼為晲绋垮憡鐫捐閮滆梺缂熸妲佹澆閿�",
+ "ge": "鐩栧摜姝屾悂鎴堥附鑳崇枡鍓查潻钁涙牸铔ら榿闅旈摤涓悇鍚堝挴楝蹭弧鍝垮湭濉ュ棟鎼胯唸纭岄晧琚艰櫦鑸搁",
+ "gei": "缁�",
+ "gen": "鏍硅窡浜樿寷鍝忚壆",
+ "geng": "鑰曟洿搴氱竟鍩傝�挎棰堝摻璧撶粻椴�",
+ "gong": "宸ユ敾鍔熸伃榫氫緵韬叕瀹紦宸╂睘鎷辫础鍏辩孩寤剧彊鑲辫殻铔╄Д",
+ "gou": "閽╁嬀娌熻嫙鐙楀灑鏋勮喘澶熷彞浣濊療宀i仒濯剧紤鏋歌褰�绗辩瘽闉�",
+ "gu": "杈滆弴鍜曠畭浼版步瀛ゅ榧撳彜铔婇璋疯偂鏁呴【鍥洪泧瀹惰淳鍢忚瘋鑿板串姹╂杞辩壇鐗胯儘鑷屾瘋鐬界綗閽撮敘楦箘鐥艰泟閰よ椴�",
+ "gua": "鍓插埉鐡滃墣瀵℃寕瑜傛嫭鍗﹀垐璇栧懕鑳嶉腹",
+ "guai": "涔栨嫄鎬幋",
+ "guan": "妫哄叧瀹樺啝瑙傜棣嗙綈鎯亴璐�岃帪鎺兼东鐩ラ钩槌�",
+ "guang": "鍏夊箍閫涘挘鐘锋鑳�",
+ "gui": "鐟拌鍦褰掗緹闂鸿建楝艰鐧告鏌滆藩璐靛埥鍖﹀尞鍒块殫搴嬪畡濡¨鐐呮櫡鐨堢皨瑙栭矐槌�",
+ "gun": "杈婃粴妫嶄辅琛徊纾欓钵",
+ "guo": "閿呴儹鍥芥灉瑁硅繃娑¢锠冨煔鍛欏洍甯煎礊鐚撴铏㈣亽铚捐潏",
+ "ha": "铔ゅ搱铏鹃摢",
+ "hai": "楠稿娴锋唉浜ュ楠囪繕鍜村棬鑳查啟",
+ "han": "閰f啫閭煩鍚兜瀵掑嚱鍠婄綍缈版捈鎹嶆棻鎲炬倣鐒婃睏姹夐倵鑿℃挅鐘撮槡娣︽緣鐎氭櫁鐒撻「棰旇毝榧�",
+ "hang": "澶澀鑸惌琛屾矄缁楃彥妗侀閰�",
+ "hao": "闀愬鍤庤豹姣儩濂借�楀彿娴╄矇钂胯枀鍡ュ殕婵犵亸鏄婄殦棰㈣殱",
+ "he": "鍛靛枬鑽疯弿鏍哥鍜屼綍鍚堢洅璨夐槀娌虫陡璧楣よ春鍚撹瘍鍔惧鍡槚绾ユ浄鐩嶉缈�",
+ "hei": "鍢块粦",
+ "hen": "鐥曞緢鐙犳仺",
+ "heng": "鍝间酣妯 鎭掕铇呯彥妗�",
+ "hong": "杞板搫鐑樿櫣楦挎椽瀹忓紭绾㈤粔瑷囪鑽暬钖ㄩ棾娉撴礆",
+ "hou": "鍠変警鐚村惣鍘氬�欏悗鍫犲緦閫呯槉绡岀硣椴庨",
+ "hu": "鏍稿拰鍛间箮蹇界憵澹惰懌鑳¤澊鐙愮硦婀栧姬铏庡敩鎶や簰娌埛鍐辫姶鍞垮洬宀电將鎬欐儦娴掓还鐞ユР杞疯儘瑙崇儉鐓虫埥鎵堢鐡犻箘楣曢贡铏嶇瑥閱愭枦楣�",
+ "hua": "鑺卞摋鍗庣尵婊戠敾鍒掑寲璇濊眮楠呮ˇ鐮夐摟",
+ "huai": "妲愬緤鎬�娣潖韪�",
+ "huan": "娆㈢幆妗撹繕缂撴崲鎮e敜鐥雹鐒曟叮瀹﹀够濂傚灨钀戞搻鍦滅嵕娲规担婕跺閫汲鐟楄剺閿鹃博楝�",
+ "huang": "鑽掓厡榛勭:铦楃哀鐨囧嚢鎯剁厡鏅冨箤鎭嶈皫鍙岄殟寰ㄦ篃娼㈤亼鐠滆倱鐧�锜ョ瘉槌�",
+ "hui": "鐏版尌杈夊窘鎭㈣洈鍥炴瘉鎮旀収鍗夋儬鏅﹁纯绉戒細鐑╂眹璁宠缁樻簝璇欒尨鑽熻暀鍜村摃鍠欓毘娲勬祶褰楃紜妗ф櫀鎭氱湱铏鸿煪楹�",
+ "hun": "鑽ゆ槒濠氶瓊娴戞贩璇ㄩ闃嶆悍鐝�",
+ "huo": "鍜岃眮娲讳紮鐏幏鎴栨儜闇嶈揣绁稿姁钘挎攭鍤ぅ鐏爥閽敧闀�犺爾",
+ "i": "浣犵埍灏煎�摝鎷熷Ξ娉ラ��",
+ "ji": "缁欏嚮鍦惧熀鏈虹暩绋界Н绠曡倢楗ヨ抗婵�璁ラ浮濮哗缂夊悏鏋佹杈戠睄闆嗗強鎬ョ柧姹插嵆瀚夌骇鎸ゅ嚑鑴婂繁钃熸妧鍐�瀛d紟绁墏鎮告祹瀵勫瘋璁¤鏃㈠繉闄呭缁х邯钘夊鑸岀郴涓屼簾涔╁墳浣跺亪澧艰姩鑺拌崰钂鸿暫鎺庡徑鍜摐鍞у矊宓�",
+ "jia": "鍢夋灧澶逛匠瀹跺姞鑽氶璐剧敳閽惧亣绋间环鏋堕┚瀚佽寗鍢忎冀閮忚懎宀祪杩︾張鏌欐垱鑳涙仢閾楅晸鐥傜槙琚疯洷绗宠璺忛",
+ "jian": "姝肩洃鍧氬皷绗洪棿鐓庡吋鑲╄壈濂哥紕鑼ф鏌⒈纭锋嫞鎹$畝淇壀鍑忚崘妲涢壌璺佃幢瑙侀敭绠欢鍋ヨ埌鍓戦ク娓愭簠娑у缓鍍皬璋弲钂规悰鍥濈姶婀旇箛璎囩迹鏋ф鎴嬫埇鐗妽姣借叡鐫戦攺楣h%绗曠喀瓒艰负椴i灟",
+ "jiang": "鍍靛灏嗘祮姹熺枂钂嬫〃濂栬鍖犻叡闄嶅己鑼虫礆缁涚及鐘熺鑰╃敞璞�",
+ "jiao": "钑夋绀佺劍鑳朵氦閮婃祰楠勫▏鍤兼悈閾扮煫渚ヨ剼鐙¤楗虹即缁炲壙鏁欓叺杞胯緝鍙獤瑙夋牎浣煎儸鑹借尛鎸㈠檷宄ゅ炯婀В鏁垵鐨庨躬铔熼啴璺ら矝",
+ "jie": "鎻帴鐨嗙Ц琛楅樁鎴姭鑺傛鏉版嵎鐫娲佺粨瑙e鎴掕棄鑺ョ晫鍊熶粙鐤ヨ灞婂亪璁﹁瘶鍗╂嫯鍠堝棢濠曞瓚鏍夋纰g枛棰夎毀缇矑楠�",
+ "jin": "宸剧瓔鏂ら噾浠婃触瑗熺揣閿︿粎璋ㄨ繘闈虫檵绂佽繎鐑蹈灏藉姴鍗鸿崺鍫囧櫎棣戝缂欑懢妲胯祮瑙愰拝琛跨煖",
+ "jing": "鍔茶崋鍏㈣寧鐫涙櫠椴镐含鎯婄簿绮崇粡浜曡鏅闈欏鏁暅寰勭棄闈栫珶绔炲噣鍒剢闃辫弫鐛嶆啲娉捐砍寮┃妾犳櫉鑲艰儷鑵堟棇闈�",
+ "jiong": "鐐獦鍐傚灖杩ョ倕鎵�",
+ "jiu": "鎻┒绾犵帠闊箙鐏镐節閰掑帺鏁戞棫鑷艰垍鍜庡氨鐤氬儲鍟鹃槃婀煩妗曢笭楣潳璧抽瑥",
+ "ju": "杞︽闉犳嫎鐙欑柦灞呴┕鑿婂眬鍜�鐭╀妇娌仛鎷掓嵁宸ㄥ叿璺濊笧閿勘鍙ユ儳鐐墽鍊ㄨ閯硅嫞鑻磋帓鎺伣灞︾悮鏋告姒樻姗樼妺椋撻挏閿旂瑁捐秳閱佃附榫冮泿闉�",
+ "juan": "鎹愰箖濞熷�︾湻鍗风虎鍦堥剟鎿愮嫹娉稉妗婅牪閿╅晫闅�",
+ "jue": "鍤艰鎾呮敨鎶夋帢鍊旂埖瑙夊喅璇�缁濆帴鍔傝安鐭嶈暔钑炲櫂宕涚崡瀛撶弿鏌芥》姗涚垵闀㈣苟瑙�",
+ "jun": "榫熷潎鑿岄挧鍐涘悰宄讳繆绔f禋閮¢獜鎹冪嫽鐨查毥",
+ "ka": "鍠�鍜栧崱浣у挃鑳�",
+ "kai": "寮�鎻╂シ鍑叏鍓�鍨茶拡蹇炬伜閾犻攷閿�",
+ "kan": "妲涘垔鍫嫎鍧庣爫鐪嬪祵渚冨嚨鑾伴槡鎴¢緵鐬�",
+ "kang": "搴锋叿绯犳墰鎶椾孩鐐曚級闂堕挭",
+ "kao": "鑰冩嫹鐑ら潬灏绘牪鐘掗搻",
+ "ke": "鍧疯嫑鏌5纾曢绉戝3鍜冲彲娓村厠鍒诲璇惧棏宀㈡仾婧橀獟缂傜弬杞叉蔼鐬岀泹閽堕敒绋炵柎绐犻铓佃潓楂�",
+ "ken": "鑲晝鍨︽伋瑁�",
+ "keng": "鍧戝惌纭庨摽",
+ "kong": "绌烘亹瀛旀帶鍊ュ磫绠�",
+ "kou": "鎶犲彛鎵e瘒鍒充綕鑺よ敾鍙╃湇绛�",
+ "ku": "鏋摥绐熻嫤閰峰簱瑁ゅ埑鍫�鍠剧粩楠�",
+ "kua": "澶稿灝鎸庤法鑳緣楂�",
+ "kuai": "浼氬潡绛蜂京蹇挴閮愬摍鐙祶鑴�",
+ "kuan": "瀹芥楂�",
+ "kuang": "鍖$瓙鐙傛鐭跨湺鏃峰喌璇撹閭濆湽澶煎搻绾╄炊",
+ "kui": "浜忕洈宀跨钁靛榄佸個棣堟劎婧冮鍖闅楄拤鎻嗗柟鍠熸倽鎰﹂�垫殞鐫借仼铦扮瘧璺",
+ "kun": "鍧ゆ槅鎹嗗洶鎮冮槂鐞ㄩ敓閱岄膊楂�",
+ "kuo": "鎷墿寤撻様閫傛牆铔�",
+ "la": "鍨冩媺鍠囪湣鑵婅荆鍟﹁惤鍓岄倠鏃牞鐦�",
+ "lai": "鑾辨潵璧栧磧寰曟稙婵戣祲鐫愰摷鐧炵眮",
+ "lan": "钃濆┆鏍忔嫤绡槕鍏版緶璋版徑瑙堟噿缂嗙儌婊ュ矚鎳旀激姒勬枔缃遍暓瑜�",
+ "lang": "鐞呮鐙煎粖閮庢湕娴帹钂楀暦闃嗛敀绋傝瀭",
+ "lao": "鎹炲姵鐗㈣�佷浆濮ラ叒鐑欐稘涔愯惤鍞犲磦鏍抽搼閾圭棬鑰㈤啰",
+ "le": "鍕掍箰浜嗕粋鍙诲槥娉愰硴",
+ "lei": "鍕掗浄闀暰纾婄疮鍎″瀿鎿傝倠绫绘唱缇歌瘮鍢炲珮缂ф獞鑰掗吂",
+ "leng": "妫辨鍐峰紕濉勬劊",
+ "li": "鍘樻ⅷ鐘侀粠绡辩嫺绂绘紦鐞嗘潕閲岄菠绀艰帀鑽斿悘鏍椾附鍘夊姳鐮惧巻鍒╁倛渚嬩繍鐥㈢珛绮掓播闅跺姏鐠冨摡楝蹭开淇氶儲鍧滆媹鑾呰摖钘滃憱鍞冲柋鐚佹骇婢ч�﹀▽瀚犻獖缂℃灔鏍庤焦鎴剧牶纭岃﹫缃归攤楣傜枲鐤泿铚婅牎绗犵绮濋喆璺為洺椴¢尝",
+ "lia": "淇�",
+ "lian": "鑱旇幉杩為暟寤夋�滄稛甯樻暃鑴搁摼鎭嬬偧缁冭敼濂佹悰娼嬫總鐞忔娈撹噥鑶︾灥瑁㈣#锠婇并",
+ "liang": "淇╃伯鍑夋绮辫壇涓よ締閲忔櫨浜皡澧氭韪夐潛榄�",
+ "liao": "鎾╄亰鍍氱枟鐕庡杈芥溅浜嗘拏闀e粬鏂欒摷灏ュ樄鐛犲缂拰楣�",
+ "lie": "鍒楄鐑堝姡鐚庡喗鍩掓崺鍜ф磳瓒旇簮楝�",
+ "lin": "鐞虫灄纾烽湒涓撮偦槌炴穻鍑涜祦鍚濇嫀钄哄晧宥欏华鎳旈伌妾╄練鑶︾灥绮艰簭楹�",
+ "ling": "妫辩幉鑿遍浂榫勯搩浼剁練鍑岀伒闄靛箔棰嗗彟浠ら厓鑻撳懁鍥规碃缁焹妫傜摯鑱嗚泬缈庨伯",
+ "liu": "婧滅悏姒寸~棣忕暀鍒樼槫娴佹煶鍏娉栨祻閬涢獫缁烘棐鐔橀攳闀忛龚閹�",
+ "long": "榫欒亱鍜欑绐块殕鍨勬嫝闄囧紕鍨呰審娉风彂鏍婅儳鐮荤檭",
+ "lou": "妤煎▌鎼傜瘬婕忛檵闇插伝钂屽柦宓濋晜鐦樿�ц澕楂�",
+ "lu": "鍏姦鍗㈤搴愮倝鎺冲崵铏忛瞾楹撶闇茶矾璧傞箍娼炵褰曢檰鎴豢鍨嗘捀鍣滄掣娓屾級閫拹鏍屾┕杞宠緜杈樻皣鑳暐楦弓鐦崇皬鑸婚矆",
+ "luan": "宄︽寷瀛沪鍗典贡鑴斿▓鏍鹃妇閵�",
+ "lun": "鎶¤疆浼︿粦娌︾憾璁哄浀",
+ "luo": "鍜彛閰悵铻虹綏閫婚敚绠╅瑁歌惤娲涢獑缁滃�爟鑽︽崑鎽炵寭鐚℃澈婕彏妞よ劧纭岄暀鐦拌溇璺為洅",
+ "lv": "椹村悤閾濅荆鏃呭饱灞$紩铏戞隘寰嬬巼婊ょ豢闂炬鑶傜▎瑜�",
+ "lve": "鎺犵暐閿�",
+ "m": "鍛�",
+ "ma": "濡堥夯鐜涚爜铓傞┈楠傚槢鍚椾箞鎽╂姽鐘稿鏉╄焼",
+ "mai": "鍩嬩拱楹﹀崠杩堣剦缇庡姠鑽敍闇�",
+ "man": "鍩嬬瀿棣掕洰婊¤敁鏇兼參婕癌澧佸箶缂︾喅闀橀铻ㄩ硹闉�",
+ "mang": "鑺掕尗鐩叉皳蹇欒幗閭欑灑婕…锜�",
+ "mao": "鐚寘閿氭瘺鐭涢搯鍗寕鍐掑附璨岃锤渚旇ⅳ鍕栬寙宄佹硸鐟佹槾鐗﹁�勬梽鎳嬬瀫铔戣潵锜婇",
+ "me": "涔堟湯楹�",
+ "mei": "鐜灇姊呴叾闇夌叅娌$湁濯掗晛姣忕編鏄у瘣濡瑰獨璋滃澏鑾撳祴鐚告导婀勬ィ闀呴箾琚傞瓍",
+ "men": "闂ㄩ椃浠壀鐒栨噾閽旈灁",
+ "meng": "姘撹悓钂欐鐩熼敯鐚涙ⅵ瀛熷嫄鐢嶇灑鎳垫湨绀炶櫥铚㈣爴鑹嬭墾榛�",
+ "mi": "鐪啔闈$硿杩疯皽寮ョ背绉樿娉岃湝瀵嗗箓鑺堝問璋ц樇鍜槯鐚曟报瀹撳辑鑴掔ア鏁夌掣绺婚簨",
+ "mian": "妫夌湢缁靛啎鍏嶅媺濞╃紖闈㈡矓娓戞箮瀹�鑵肩渼榛�",
+ "miao": "鑻楁弿鐬勮棎绉掓负搴欏鍠甸倛缂堟潽娣肩渿楣�",
+ "mie": "钄戠伃涔滃挬锠涚",
+ "min": "姘戞娍鐨挎晱鎮椊鑻犲卜闂垫朝缂楃弶鎰嶉痪槌�",
+ "ming": "鏄庤灍楦i摥鍚嶅懡鍐ヨ寳婧熸殱鐬戦叐",
+ "miu": "璋吉",
+ "mo": "鑴変箞娌℃懜鎽硅槕妯¤啘纾ㄦ懇榄旀姽鏈帿澧ㄩ粯娌紶瀵為檶涓囨棤璋熻寜钃﹂瀚娈侀晢绉g樇鑰辫矈璨橀航",
+ "mou": "璋嬬墴鏌愪緮鍘跺摓缂湼铔戦崻",
+ "mu": "濮ユā鐗熸媷鐗′憨濮嗘瘝澧撴毊骞曞嫙鎱曟湪鐩潶鐗х﹩浠澏鑻滄矏姣捈",
+ "na": "鎷垮摢鍛愰挔閭e绾冲崡鎹鸿偔闀庤〔绠�",
+ "nai": "姘栦箖濂惰�愬榧愪酱鑹胯悩鏌�",
+ "nan": "鍗楃敺闅惧杻鍥℃鑵╃奖铦昏掸",
+ "nang": "鍥婃敭鍥旈鏇�",
+ "nao": "鎸犺剳鎭奸椆娣栧鍨村懚鐚辩憴纭囬摍铔�",
+ "ne": "鍝憿璁风枓",
+ "nei": "棣佸唴",
+ "nen": "瀚�",
+ "neng": "鑳�",
+ "ni": "鍛㈠Ξ闇撳�偿灏兼嫙浣犲尶鑵婚�嗘汉浼插澀鐚婃�╂樀鏃庣ア鎱濈潹閾岄驳",
+ "nian": "钄媹骞寸⒕鎾垫嵒蹇电矘寤垮煗杈囬粡椴囬捕",
+ "niang": "濞橀吙",
+ "niao": "婧洪笩灏胯寫瀣茶劜琚�",
+ "nie": "鎹忚亗瀛藉暜闀婇晬娑呴櫑鍩濊槚鍡鑷箲",
+ "nin": "鎮�",
+ "ning": "鏌犵嫗鍑濆畞鎷ф碁浣炲挍鐢亶",
+ "niu": "鐗涙壄閽航鎷楃媰蹇稿",
+ "nong": "鑴撴祿鍐滃紕渚摑",
+ "nou": "鑰�",
+ "nu": "濂村姫鎬掑缉鑳椹�",
+ "nuan": "鏆�",
+ "nuo": "濞滄尓鎳︾朝璇哄偐鎼﹀枏閿�",
+ "nv": "濂崇媰鎭ч挄琛�",
+ "nve": "铏愮枱",
+ "o": "鍠斿櫌",
+ "ou": "娆ч弗娈磋棔鍛曞伓娌よ鎬勭摨鑰�",
+ "pa": "鎵掕�欏暘瓒寸埇甯曟�曠惗钁╂澐绛�",
+ "pai": "鎷嶆帓鐗屽緲婀冩淳杩砍钂庡搶",
+ "pan": "鑸崬鐣攢娼樼洏纾愮浖鐣斿垽鍙涜儢寮佹嫐鐖挎钞鐨よⅱ瑗昏煚韫�",
+ "pang": "鑶�纾呬箵搴炴梺鑰儢褰锋粋閫勮瀮",
+ "pao": "鎶涘拞鍒ㄧ偖琚嶈窇娉″審鐙嶅簴鑴柋瓒�",
+ "pei": "鍛歌儦鍩硅4璧旈櫔閰嶄僵娌涜寚鎺婅緮甯旀窢鑹存梿閿唴闇�",
+ "pen": "鍠风泦婀�",
+ "peng": "鐮版姩鐑规編褰摤妫氱〖绡疯啫鏈嬮箯鎹х鍫嬪槶鎬﹁煕",
+ "pi": "杈熷惁鍧爳闇规壒鎶妶鐞垫瘲鍟よ劸鐤茬毊鍖圭棡鍍诲眮璀笗浠抽檪闄撮偝閮湲鍩ら紮鑺樿悊钖滄摋鍣煎笖搴�搴虫窢濯茬喊鏋囩敁缃撮搷鐧栫枊铓嶈湵璨�",
+ "pian": "鎵佷究绡囧亸鐗囬獥璋濋獔缂忕姀鑳肩咯韫�",
+ "piao": "椋樻紓鐡㈢エ鏈村壗鑾╁槍瀚栭獱缂ユ畭鐬熻灥楂�",
+ "pie": "鎾囩灔涓胯嫟姘�",
+ "pin": "鎷奸璐搧鑱樻嫐濮樺珨姒�鐗濋ⅵ",
+ "ping": "鍐箳鍧嫻钀嶅钩鍑摱璇勫睆淇滃爧濞夋灠椴�",
+ "po": "娉婂潯娉奸濠嗙牬榄勮揩绮曟湸鍙甸檪閯辨澈鐝�閽嬮挿鐨ょ",
+ "pou": "鍓栬鎺�",
+ "pu": "鍫℃毚鑴墤閾轰粏鑾嗚憽鑿╄挷鍩旀湸鍦冩櫘娴﹁氨鏇濈�戝實鍣楁亥婵挒鏀存皢鏀甸暏闀ㄨ辜",
+ "qi": "绋芥湡娆烘爾鎴氬涓冨噭婕嗘煉娌忓叾妫嬪姝х暒宕庤剱榻愭棗绁堢楠戣捣宀備篂浼佸惎濂戠爩鍣ㄦ皵杩勫純姹芥常璁笇浜撲繜鍋堝溁鑺戣姫鑽犺悂钀嬭懞钑插榿灞哄矏姹旀穱楠愮划鐞惁鏉炴·妲�嗘绁烘仢鎲╃棰�铔磋湠缍︾懂韫婇硩楹�",
+ "qia": "鍗℃帎鎭版唇钁滈珎",
+ "qian": "鐗垫墻閽庨搮鍗冭縼绛句粺璋︿咕榛旈挶閽冲墠娼滈仯娴呰按鍫戝祵娆犳瓑绾ゅ�╀渐闃″嚨鑺婅姟鑼滆崹鎺挅宀嶆偔鎱婃稊楠炴惔瑜扮急妞犵妽鑲锋剢閽よ檾绠�",
+ "qiang": "灏嗘灙鍛涜厰缇屽钄峰己鎶脯鐖挎垥瀚辨ǒ鎴楃倽閿栭數闀铚g緹璺穭",
+ "qiao": "钑夊3姗囬敼鏁叉倓妗ョ灖涔斾鲸宸ч灅鎾繕宄繌绐嶉泙鍔佽璋崬宄ゆ剙鎲旂疾妯垫鏁璺烽瀿",
+ "qie": "娌忕爩鍒囪寗涓旀�獌浼介儎鍞兼儸鎱婂濠曟寛鑴為敳绠ц秳",
+ "qin": "閽︿镜浜茬Е鐞村嫟鑺规搾绂藉瘽娌佽姪钃佹徔鍚e棯鍣欏粦婧辨獛閿撹】铻撹【",
+ "qing": "浜查潚杞绘阿鍊惧嵖娓呮搸鏅存鞍鎯呴》璇峰簡鑻樺湂妾犵,铚荤絼绠愮懂璎﹂箔榛�",
+ "qiong": "鐞肩┓閭涜妿鑼曠┕铔╃瓏璺妿",
+ "qiu": "榫熺涓橀偙鐞冩眰鍥氶厠娉呬繀宸姲鎰�婀�戦亽妤歌祰铏毌铦よ绯楅硡榧�",
+ "qu": "瓒嬪尯铔嗘洸韬眻椹辨笭鍙栧ǘ榫嬭叮鍘绘垖璇庡姮鑻h晼铇у矕琛㈤槖鐠╄姘嶆湊绁涚2楦茬櫙铔愯牸楹寸灴闉虎",
+ "quan": "鍦堥ⅶ鏉冮啗娉夊叏鐥婃嫵鐘埜鍔濊癄鑽冪姯鎮涚换妗婅緛鐣庨摠铚风瓕楝�",
+ "que": "缂虹倲鐦稿嵈楣婃Ψ纭泙鑺嶉槙闃欐偒",
+ "qun": "瑁欑兢閫¢簢",
+ "ran": "鐒剁噧鍐夋煋鑻掕毢楂�",
+ "rang": "鐡ゅ¥鏀樺毞璁╃Τ绌�",
+ "rao": "楗舵壈缁曡崨濞嗘 ",
+ "re": "鎯圭儹鑻ュ枏",
+ "ren": "澹粊浜哄繊闊т换璁ゅ垉濡婄韩浜讳粸鑽忛オ杞亖绋旇〗",
+ "reng": "鎵斾粛",
+ "ri": "鏃�",
+ "rong": "鎴庤尭钃夎崳铻嶇啍婧跺缁掑啑宓樼嫧姒曡倻铦�",
+ "rou": "鎻夋煍鑲夌硡韫傞灒",
+ "ru": "鑼硅爼鍎掑濡傝颈涔虫睗鍏ヨぅ钃愯柗鍤呮闯婧芥俊缂涢摲瑗﹂ⅴ",
+ "ruan": "杞槷鏈�",
+ "rui": "钑婄憺閿愯姰钑ゆ灅鐫胯殝",
+ "run": "闂版鼎",
+ "ruo": "鑻ュ急鍋岀",
+ "sa": "鎾掓磼钀ㄥ崊浠ㄦ鎸茶剮椋�",
+ "sai": "鑵硟濉炶禌鍣�",
+ "san": "涓夊弫浼炴暎棣撴绯�",
+ "sang": "妗戝棑涓ф悺纾夐ⅰ",
+ "sao": "鎼旈獨鎵珎鍩界极缂茶噴鐦欓硧",
+ "se": "濉炵憻鑹叉订鍟摨绌�",
+ "sen": "妫�",
+ "seng": "鍍�",
+ "sha": "鑾庣爞鏉�鍒规矙绾卞偦鍟ョ厼鍘﹀敿鍡勬瓋閾╃棫瑁熼湈椴�",
+ "shai": "鑹茬瓫鏅掗吘",
+ "shan": "鍗曟幐鐝婅嫬鏉夊北鍒犵吔琛棯闄曟搮璧¤喅鍠勬睍鎵囩籍鏍呭墶璁劘鍩忚姛褰℃礁濮楀瑮楠熻喕绂呴拹鐤濊煯鑸㈣窔槌濋珶",
+ "shang": "澧掍激鍟嗚祻鏅屼笂灏氳3鍨х槐娈囩喌瑙�",
+ "shao": "姊㈡崕绋嶇儳鑺嶅嫼闊跺皯鍝ㄩ偟缁嶅彫鍔嫊娼叉潛铔哥鑹�",
+ "she": "濂㈣祳铔囪垖鑸嶈郸鎽勫皠鎱戞秹绀捐鎷炬姌鍘嶄綐鎻茬尀婊犳瓩鐣查簼",
+ "shei": "璋�",
+ "shen": "鍙傜牱鐢冲懟浼歌韩娣卞缁呯娌堝濠剁敋鑲炬厧娓椾粈璇滆皞鑾樿憵鍝傛笘妞硅儌鐭ц渻",
+ "sheng": "涔樿韩澹扮敓鐢ョ壊鍗囩怀鐪佺洓鍓╄儨鍦e祳鏅熺湚绗�",
+ "shi": "鍖欏笀澶辩嫯鏂芥箍璇楀案铏卞崄鐭虫嬀鏃朵粈椋熻殌瀹炶瘑鍙茬煝浣垮睅椹跺寮忕ず澹笘鏌夸簨鎷獡閫濆娍鏄棞鍣�備粫渚嶉噴楗版皬甯傛亙瀹よ璇曚技娈栧硻璋ュ煒鑾宠搷寮戦ィ杞艰闯鐐荤せ閾堣垚绛吘璞曢播椴�",
+ "shou": "鏀舵墜棣栧畧瀵挎巿鍞彈鐦﹀吔鐔熸墝鐙╃欢鑹�",
+ "shu": "钄灑姊虫畩鎶掕緭鍙旇垝娣戠枏涔﹁祹瀛扮啛钖殤鏇欑讲铚�榛嶉紶灞炴湳杩版爲鏉熸垗绔栧搴舵暟婕辨仌淇炲�忓【鑿芥憛娌稇婢嶅绾炬鑵ф绉枊",
+ "shua": "鍒疯�嶅敯",
+ "shuai": "鐜囨憯琛扮敥甯呰焵",
+ "shuan": "鏍撴嫶闂╂懂韪�",
+ "shuang": "闇滃弻鐖芥撤娣欏瓈",
+ "shui": "璋佹按鐫$◣璇存暗",
+ "shun": "鍚灛椤鸿垳鎭傚窙",
+ "shuo": "鏁拌纭曟湐鐑佽挻鎼犲棈濡佹閾�",
+ "si": "鍘曟柉鎾曞樁鎬濈鍙镐笣姝昏倖瀵哄棧鍥涗己浼奸ゲ宸冲幃淇熷厱鍘跺挐姹滄硹婢屽椹风簾缂岀閿堕付鑰滆洺绗ョ掣",
+ "song": "鏉捐�告�傞閫佸畫璁艰鍑囪彉宕у旦蹇倸娣炵",
+ "sou": "鎼滆墭鎿炲椊鍙熻柈鍡栧椌棣婃稇婧查鐬嶉敿铻�",
+ "su": "鑻忛叆淇楃礌閫熺矡鍍冲婧璇夎們澶欒啊钄屽棄鎰稇绨岃Й绋�",
+ "suan": "閰歌挏绠楃嫽",
+ "sui": "灏胯櫧闅嬮殢缁ラ珦纰庡瞾绌楅亗闅х璋囪嵔婵夐們鐕х湱鐫�",
+ "sun": "瀛欐崯绗嬭崻鐙查'姒毤",
+ "suo": "鑾庤搼姊攩缂╃悙绱㈤攣鎵�鍞㈠棪鍡嶅☉妗尣鐫冪晶",
+ "ta": "濉屼粬瀹冨ス濉旂嵀鎸炶箣韪忔嫇鍡掗椉婧婚仮姒绘矒閾婅犊槌�",
+ "tai": "鑳庤嫈鎶彴娉伴厼澶�佹卑閭拌柟鍛旈獉鑲界偙閽涜穯椴�",
+ "tan": "寮瑰潔鎽婅椽鐦哗鍧涙獉鐥版江璋皥鍧︽琚掔⒊鎺㈠徆鐐儻鏄欏繍閽介敩闀¤",
+ "tang": "姹ゅ鎼爞妫犺啗鍞愮硸鍊樿汉娣岃稛鐑偉甯戞簭鐟閾撮晽鑰ヨ灄铻崇景閱�",
+ "tao": "鎺忔稕婊旂沪钀勬閫冩窐闄惰濂楅紬鍙ㄥ晻娲煬鐒橀",
+ "te": "鐗瑰繏蹇戞厺閾�",
+ "teng": "钘よ吘鐤艰獖婊�",
+ "ti": "鍫ゅ紵姊墧韪㈤攽鎻愰韫勫暭浣撴浛鍤忔儠娑曞墐灞夊�滆崙鎮岄�栫花缂囬箞閱�",
+ "tian": "澶╂坊濉敯鐢滄伂鑸旇厗鎺繚闃楁畡鑵肩晪閽�",
+ "tiao": "璋冩寫鏉¤竣鐪鸿烦浣昏嫊绁х獣铚╃绮滈締椴﹂",
+ "tie": "璐撮搧甯栬悳椁�",
+ "ting": "鍘呭惉鐑冩眬寤峰仠浜涵鎸鸿墖鑾涜懚濠锋鐢洪摛铚撻渾",
+ "tong": "渚楁礊閫氭閰灣鍚岄摐褰ょ妗舵崊绛掔粺鐥涗綗鍍粷鍨岃尲鍡靛硳鎭告郊鐮�",
+ "tou": "鍋锋姇澶撮�忎籂閽",
+ "tu": "鍑哥绐佸浘寰掗�旀秱灞犲湡鍚愬厰鍫嶈嵓鑿熼拲閰�",
+ "tuan": "婀嶅洟鎶熷綎鐤�",
+ "tui": "鍫嗘帹棰撹吙铚曡お閫�鐓�",
+ "tun": "鍥よお鍚炲悲鑷�姘介エ鏆捐偒璞�",
+ "tuo": "鎷栨墭鑴遍傅闄�椹┘妞Ε鎷撳斁涔囦綏鍧ㄥ汗娌叉脖鏌濇焷姗愮牐閾婄閰¤穾榧�",
+ "u": "鍘讳笉涓庨洦楸�",
+ "v": "鍚冩墠杞﹀嚭闄�",
+ "wa": "鍑规寲鍝囪洐娲煎▋鐡﹁浣ゅú鑵�",
+ "wai": "姝宕�",
+ "wan": "璞屽集婀剧帺椤戒父鐑峰畬纰楁尳鏅氱殩鎯嬪疀濠変竾鑵曞墱鑺勮帪鑿�绾ㄧ痪鐞剺鐣硅溈",
+ "wang": "姹帇浜℃瀴缃戝線鏃烘湜蹇樺缃斿阿鎯樿緥榄�",
+ "wei": "濞佸穽寰嵄闊﹁繚妗呭洿鍞儫涓烘綅缁磋媷钀庡浼熶吉灏剧含鏈敋鍛崇晱鑳冨杺榄忎綅娓皳灏夋叞鍗亷璇块殘闅楀湬鑺熻懗钖囧洍甯忓阜宓尌鐚棻娌╂揣娑犻�跺〒鐜煪杌庣倻鐓ㄧ湱鐥胯墘闅归矓",
+ "wen": "鐦熸俯铓婃枃闂荤汗鍚荤ǔ绱婇棶鍒庨槍姹剁師鐠烘畞绗忛洴",
+ "weng": "鍡$縼鐡搳钑�",
+ "wo": "鎸濊湕娑$獫鎴戞枴鍗ф彙娌冨�幋鍠斿棇骞勬弗濯偀纭緦",
+ "wu": "鎭跺帆鍛滈挩涔屾薄璇眿鏃犺姕姊у惥鍚存瘚姝︿簲鎹傚崍鑸炰紞渚潪鎴婇浘鏅ょ墿鍕垮姟鎮熻鍏�浠甸槩閭湰鑺村憭鍞斿枖搴戞�冨郡娴杩曞Ι濠洪獩鏉岀壘鏂肩剱楣夐箿鐥﹁湀绗忛媹榧�",
+ "xi": "鏍栨様鐔欐瀽瑗跨鐭芥櫚鍢诲惛閿$壓绋�鎭笇鎮夎啙澶曟儨鐔勭儻婧睈鐘�妾勮甯範濯冲枩閾f礂绯婚殭鎴忕粏鍍栧叜闅伴儎閮楄寽鑿ヨ懜钃板鍜﹀攺寰欓ォ闃嬫禒娣呭保瀣夌幒妯ㄦ洣瑙嬫鐔圭绂у祰鐨欑└瑁艰湧铻呰煁鑸勮埦缇茬矠缈曢啹韫�",
+ "xia": "鐬庤櫨鍖i湠杈栨殗宄′緺鐙笅鍘﹀鍚撹懎鍡勭嫀閬愮憰鏌欐纭栫槙缃呴粻",
+ "xian": "瑙侀摚娲楁巰閿ㄥ厛浠欓矞绾ゅ捀璐よ鑸烽棽娑庡鸡瀚屾樉闄╃幇鐚幙鑵洪缇″闄烽檺绾挎兂鍐艰媼鑾惰棑宀樺健鐚冩厞鏆瑰ù姘欑嚬绁嗛还閿箛鐥毈绛呯奔閰拌罚璺归湴",
+ "xiang": "闄嶇浉鍘㈤暥棣欑瑗勬箻涔$繑绁ヨ鎯冲搷浜」宸锋鍍忓悜璞¤姉钁欓シ搴犻缂冭煋鑸¢矠椋�",
+ "xiao": "钀х闇勫墛鍝殻閿�娑堝娣嗘檽灏忓瓭鏍¤倴鍟哥瑧鏁堢埢鍝撳搐娼囬�嶅В楠佺弧鏋灥铔哥绠瓐",
+ "xie": "瑙f浜涙瓏铦庨瀷鍗忔専鎼洪偑鏂滆儊璋愬啓姊板嵏锜规噲娉勬郴璋㈠睉琛�鍙跺仌浜靛嫲鐕枻鎾峰枅鐛花娓�i倐缁佺棘姒鐪番韬為",
+ "xin": "钖姱閿屾杈涙柊蹇诲績淇¤鍥熼Θ鑾樺縿鏄曟瓎闀¢懌",
+ "xing": "鐪佹槦鑵ョ尒鎯哄叴鍒戝瀷褰㈤偄琛岄啋骞告潖鎬у鍏勯檳鑽囪崶鎿らェ鎮荤",
+ "xiong": "鍏勫嚩鑳稿寛姹归泟鐔婅妿",
+ "xiu": "鑷浼戜慨缇炴溄鍡呴攬绉�琚栫唬鍜诲搏棣愬亥婧撮负璨呴",
+ "xu": "澧熸垖闇�铏氬槝椤诲緪璁歌搫閰楀彊鏃簭鐣滄仱绲┛缁画鍚佽鍕栧湬钃挎传婧嗛〖鏍╄偡鐓︾爥鐩辫儱绯堥啈闆�",
+ "xuan": "杞╁枾瀹f偓鏃嬬巹閫夌櫍鐪╃粴鍎囪皷钀辨弾鎿愭倡娓叉缉鐠囨ウ鏄曟殑鐐厞纰归搲闀熺梼",
+ "xue": "鍓婇澊钖涘绌撮洩琛�璋戝櫛鍤扯韪呴硶",
+ "xun": "鑽ゆ禋鍕嬬啅寰棳璇㈠椹贰娈夋睕璁閫婅繀宸介儑鍩欒崁鑽ㄨ晥钖板硧寰囩嫽鐛亗娲垫禂鏇涢喓椴�",
+ "ya": "鍘嬫娂楦﹂腑鍛�涓娊鐗欒殰宕栬娑泤鍝戜簹璁惰涧浼㈠灜鎻犲矆杩撳▍鐞婃姘╃爲鐫氱棖鐤�",
+ "yan": "淇洪搮鐒夊捊闃夌儫娣圭洂涓ョ爺铚掑博寤惰█棰滈槑鐐庢部濂勬帺鐪艰婕旇壋鍫扮嚂鍘岀牃闆佸攣褰︾劙瀹磋皻楠屾鍘h禎鍓′卡鍋冨厲璁犺俺闃介兙閯㈠煆鍩姭鑿告彏宕︽伖闂槒婀粺濡嶅鐞版獝鏅忚儹鑵岀劚缃ㄧ閰介瓏椁嶉脊",
+ "yang": "娈冨ぎ楦Ё鏉ㄦ壃浣枴缇婃磱闃虫哀浠扮棐鍏绘牱婕惧緣鎬忔潮鐐�鐑婃仚铔橀瀰",
+ "yao": "渚ョ枱閭�鑵板鐟舵憞灏ч仴绐戣埃濮氬挰鑸�鑽鑰�绾﹂挜澶埢鍚嗗搐宕惧经鐎瑰购鐝ф澇杞烘洔鑲撮摣楣炵獔绻囬硱",
+ "ye": "鍜芥ぐ鍣庤�剁埛閲庡喍涔熼〉鎺栦笟鍙舵洺鑵嬪娑叉嫿闈ヨ皰閭烘彾鎻叉彏鏅旂儴閾�",
+ "yi": "鑹捐泧灏句竴澹瑰尰鎻栭摫渚濅紛琛i澶烽仐绉讳华鑳扮枒娌傚疁濮ㄥ綕妞呰殎鍊氬凡涔欑煟浠ヨ壓鎶戞槗閭戝惫浜垮焦鑷嗛�歌倓鐤害瑁旀剰姣呭繂涔夌泭婧㈣璁皧璇戝紓缈肩繉缁庝缚鍒堝姄浣氫骄璇掑湳鍩告嚳鑻¤枏寮堝鎸规帋寮嬪憮鍜﹀捒鍡屽櫕",
+ "yin": "鑼佃崼鍥犳闊抽槾濮诲悷閾舵帆瀵呴ギ灏瑰紩闅愬嵃鑳ら劄寤村灎鍫欒姪鑼氬惒鍠戠嫼澶ゆ磭婀挨閾熺樉绐ㄨ殦闇緢",
+ "ying": "鑻辨ū濠撮拱搴旂绩鑾硅悿钀ヨ崸铦囪繋璧㈢泩褰遍纭槧瀣撮儮鑼旇崶鑾鸿惁钃ユ拕鍢よ喓婊㈡絾鐎涚憶鐠庢ス濯甸功鐦块缃�",
+ "yo": "鍝熷敺",
+ "yong": "鎷ヤ剑鑷冪棃搴搁泹韪婅浌鍜忔吵娑屾案鎭垮媷鐢ㄤ繎澹呭鍠佹叺閭曢暃鐢硻楗�",
+ "you": "骞戒紭鎮犲咖灏ょ敱閭搥鐘规补娓搁厜鏈夊弸鍙充綉閲夎鍙堝辜鍗f敻渚戣帬鑾滆幐灏㈠懄鍥垮鏌氱尫鐗栭摃鐤h伇铓拌毚铦h潳绻囬笨榛濋棘",
+ "yu": "璋疯敋灏夎總娣や簬鐩傛铏炴剼鑸嗕綑淇為�鹃奔鎰夋笣娓旈殔浜堝ū闆ㄤ笌灞跨瀹囪缇界帀鍩熻妺閮佸悂閬囧柣宄尽鎰堟鐙辫偛瑾夋荡瀵撹棰勮鲍椹播绂烘瘬浼涗浚璋�璋曞湬钀歌摚鎻勫渼鍦夊禌鐙抽カ棣�搴鹃槇楝诲Κ濡ょ骸鐟滄槺瑙庢鑵存",
+ "yuan": "瀹涢赋娓婂啢鍏冨灒琚佸師鎻磋緯鍥憳鍦嗙尶婧愮紭杩滆嫅鎰挎�ㄩ櫌鍨稿‖鑺幘娌呭獩鐟楁┘鐖扮湤楦㈣瀳绠㈤紜",
+ "yue": "涔愭洶绾﹁秺璺冮挜宀崇菠鏈堟偊闃呴緺鍝曠�规ň鍒栭捄",
+ "yun": "鑰樹簯閮у寑闄ㄥ厑杩愯暣閰濇檿闊靛瓡閮撹姼鐙佹伣鎰犲绾煫娈掓榾姘茬啫绛�",
+ "za": "鍖濈牳鏉傚挶鎵庡拫绫村拏鍟�",
+ "zai": "鏍藉搲鐏惧杞藉啀鍦ㄤ粩宕界斁",
+ "zan": "鍜辨敀鏆傝禐鎷舵稊鐡掓槤绨硨瓒遍尵",
+ "zang": "钘忚祪鑴忚懍濂橀┑鑷�",
+ "zao": "閬碂鍑胯椈鏋f棭婢¤殼韬佸櫔閫犵殏鐏剁嚗鍞�",
+ "ze": "璐f嫨鍒欐辰浠勮禍鍟у富杩槂绗鑸�",
+ "zei": "璐�",
+ "zen": "鎬庤爱",
+ "zeng": "澧炴啂鏇捐禒缂攽缃鹃攦",
+ "zha": "鐖嗘煡鎵庡柍娓f湱杞ч摗闂哥湪鏍呮Θ鍜嬩箥鐐歌瘓鏌炴徃鍚掑挙鍝抽妤傜牊鐥勮毐绗絼",
+ "zhai": "缈熸嫨鎽樻枊瀹呯獎鍊哄鐮︾樀",
+ "zhan": "棰ょ灮姣¤┕绮樻簿鐩忔柀杈楀喘灞曡樃鏍堝崰鎴樼珯婀涚唤璋垫悓婢舵梼",
+ "zhang": "闀挎绔犲桨婕冲紶鎺屾定鏉栦笀甯愯处浠楄儉鐦撮殰浠夐劊骞涘秱鐛愬珳鐠嬭煈",
+ "zhao": "鏈濆槻鎷涙槶鎵炬布璧电収缃╁厗鑲囧彫鐖潃璇忓晛妫规檨閽婄瑠",
+ "zhe": "閬姌鍝茶洶杈欒�呴敆钄楄繖娴欑潃涔囪蔼闄懞鏌樿緞纾旈恭瑜惰渿铻淡",
+ "zhen": "鐝嶆枱鐪熺攧鐮ц嚮璐為拡渚︽灂鐤硅瘖闇囨尟闀囬樀甯у湷钃佹祱婧辩紲妗㈡す姒涜礁鎴¤祱鑳楁湑绁暃绋归俯绠�",
+ "zheng": "涓佽捀鎸g潄寰佺嫲浜夋�旀暣鎷鏀跨棁閮戣瘉璇ゅ偿閽查摦绛�",
+ "zhi": "璇嗘皬鑺濇灊鏀惐铚樼煡鑲㈣剛姹佷箣缁囪亴鐩存娈栨墽鍊间緞鍧�鎸囨瓒惧彧鏃ㄧ焊蹇楁寶鎺疯嚦鑷寸疆甯滃硻鍒舵櫤绉╃璐ㄧ倷鐥旀粸娌荤獟鍗皭闄熼儏鍩磋姺鎽笝寰靛蹇綐鍜獦鏍夋灣鏍�妗庤降杞捐唇鑳濊啠绁夌榛归泬楦风棧铔捣閰窎韪腐璞歌Н",
+ "zhong": "涓泤蹇犻挓琛风粓绉嶈偪閲嶄徊浼楀啟澶傚开閿鸿灲鑸傅",
+ "zhou": "鑸熷懆宸炴床璇岀播杞磋倶甯氬拻鐨卞畽鏄奸鑽晛濡海缁夎儎纰$眬鑸抽厧",
+ "zhu": "灞炴湳鐝犳牚铔涙湵鐚璇涢�愮鐑涚叜鎷勭灘鍢变富钁楁煴鍔╄泙璐摳绛戜綇娉ㄧ椹绘涓朵极渚忛偩鑻庤尡娲欐笟娼存緧鏉兼姗ョ偡閾㈢柊鐦冪绠歌埑缈ヨ簠楹�",
+ "zhua": "鎶撶埅",
+ "zhuai": "鎷借浆",
+ "zhuan": "浼犱笓鐮栬浆鎾拌禋绡嗗暛棣旈",
+ "zhuang": "妗╁簞瑁呭鎾炲.鐘跺儺",
+ "zhui": "妞庨敟杩借禈鍧犵紑钀戞兇楠撶紥闅�",
+ "zhun": "灞皢鍑嗚偒鑳楃獉",
+ "zhuo": "钁楁崏鎷欏崜妗岀悽鑼侀厡鍟勭潃鐏兼祳鍊钑炴摙娴炴犊婵9鑲劘绂氭柅闀兜",
+ "zi": "鍚卞吂鍜ㄨ祫濮挎粙娣勫瓬绱粩绫芥粨瀛愯嚜娓嶅瓧璋樺懖宓瀛崇紒姊撹編璧�鎭g湨閿辩Л鑰旂绮㈣稇瑙滆ň榫囬不楂�",
+ "zong": "楝冩韪畻缁兼�荤旱鍋灋鑵欑步",
+ "zou": "閭硅蛋濂忔弽璇归櫖閯归┖妤遍舶",
+ "zu": "绉熻冻鍗掓棌绁栬瘏闃荤粍淇庤徆鍟愰暈",
+ "zuan": "閽荤簜鏀ョ嫉韬�",
+ "zui": "鍜�鍢撮唹鏈�缃暈瑙�",
+ "zun": "灏婇伒鎾欐ń槌�",
+ "zuo": "鍑跨悽鏄ㄥ乏浣愭煘鍋氫綔鍧愬骇闃煎攽鍢�嶈儥绁氱牊绗參"
+}
+export default dict
diff --git a/vf205_access/src/view/pinyin/pinyin.js b/vf205_access/src/view/pinyin/pinyin.js
new file mode 100644
index 0000000..4a2003d
--- /dev/null
+++ b/vf205_access/src/view/pinyin/pinyin.js
@@ -0,0 +1,1049 @@
+import dxui from '../../../dxmodules/dxUi.js'
+import dict from './dict.js'
+const pinyin = {}
+
+// 閿洏澶у皬
+let width = 800
+let height = 400
+// 鏄惁閿佸畾閿洏
+let isLock = false
+// 鏄惁鏀寔鎷奸煶杈撳叆
+let enablePinyin = true
+// 鍒濆鍖栧鍣�
+pinyin.init = function (w, h) {
+ width = w
+ height = h
+
+ // 鍙厑璁稿垵濮嬪寲涓�娆�
+ if (pinyin.inited) {
+ return
+ }
+ pinyin.inited = true
+ // 鍏ㄥ眬瀛椾綋
+ pinyin.font24 = dxui.Font.build('/app/code/resource/font/AlibabaPuHuiTi-2-65-Medium.ttf', 24, dxui.Utils.FONT_STYLE.NORMAL)
+ let container = dxui.View.build('container', dxui.Utils.LAYER.TOP)
+ pinyin.container = container
+ clearStyle(container)
+ container.obj.lvObjAddFlag(dxui.Utils.ENUM.LV_OBJ_FLAG_OVERFLOW_VISIBLE)
+ container.setSize(width, height)
+ container.align(dxui.Utils.ALIGN.BOTTOM_MID, 0, 0)
+ container.textFont(pinyin.font24)
+ // 瀹瑰櫒鍒濆鍖�
+ container.bgOpa(0)
+ container.update()
+ container.hide()
+ // 鍒涘缓涓夌閿洏妯″紡
+ pinyin.englishPanel = createEnglish()
+ pinyin.pinyinPanel = createPinyin()
+ pinyin.numPanel = createNum()
+ pinyin.symbolPanel = createSymbol()
+}
+pinyin.getSize = function () {
+ return { width: width, height: height }
+}
+/**
+ * 鏄剧ず閿洏锛岄渶瑕佸厛鍒濆鍖�
+ * @param {number} mode 閿洏妯″紡锛�0锛氳嫳鏂囬敭鐩橈紝1锛氭嫾闊抽敭鐩橈紝2锛氭暟瀛楅敭鐩橈紝3锛氱鍙烽敭鐩�
+ * @param {function} cb 鎸夐敭鍐呭鍥炶皟
+ */
+pinyin.show = function (mode, cb) {
+ if (![0, 1, 2, 3].includes(mode)) {
+ return
+ }
+ this.unlock()
+ this.hide()
+ // 鎸夐敭鍐呭鍥炶皟
+ pinyin.cb = cb
+ pinyin.container.show()
+ pinyin.container.moveForeground()
+ switch (mode) {
+ case 0:
+ pinyin.englishPanel.show()
+ break;
+ case 1:
+ pinyin.pinyinPanel.show()
+ break;
+ case 2:
+ pinyin.numPanel.show()
+ break;
+ case 3:
+ pinyin.symbolPanel.show()
+ break;
+ default:
+ break;
+ }
+}
+// 鑾峰彇褰撳墠閿洏妯″紡
+pinyin.getMode = function () {
+ if (!pinyin.englishPanel.isHide()) {
+ return 0
+ } else if (!pinyin.pinyinPanel.isHide()) {
+ return 1
+ } else if (!pinyin.numPanel.isHide()) {
+ return 2
+ } else if (!pinyin.symbolPanel.isHide()) {
+ return 3
+ } else {
+ return 0
+ }
+}
+// 闅愯棌閿洏
+pinyin.hide = function () {
+ pinyin.englishPanel.hide()
+ pinyin.pinyinPanel.hide()
+ pinyin.numPanel.hide()
+ pinyin.symbolPanel.hide()
+ pinyin.container.hide()
+ if (pinyin.callback) {
+ pinyin.callback()
+ pinyin.callback = null
+ }
+}
+// 闅愯棌鍥炶皟锛屽崟娆℃湁鏁�
+pinyin.hideCb = function (cb) {
+ pinyin.callback = cb
+}
+// 閿佸畾閿洏锛屼笉鍏佽鍒囨崲妯″紡
+pinyin.lock = function () {
+ isLock = true
+}
+// 瑙i櫎閿佸畾閿洏
+pinyin.unlock = function () {
+ isLock = false
+}
+pinyin.pinyinSupport = function (bool) {
+ enablePinyin = bool
+}
+
+// 鑻辨枃閿洏
+function createEnglish() {
+ let englishPanel = dxui.View.build(pinyin.container.id + 'englishPanel', pinyin.container)
+ clearStyle(englishPanel)
+ englishPanel.setSize(pinyin.container.width(), pinyin.container.height())
+ englishPanel.update()
+ // 鍒涘缓澶у皬鍐欑殑鑻辨枃閿洏
+ function createKeyboard(capital) {
+ let englishKeyboard = dxui.Buttons.build(englishPanel.id + 'englishKeyboard' + (capital ? "Big" : "Small"), englishPanel)
+ clearStyle(englishKeyboard)
+ englishKeyboard.obj.lvObjSetStylePadGap(10, dxui.Utils.ENUM._LV_STYLE_STATE_CMP_SAME)
+ englishKeyboard.padAll(10)
+ englishKeyboard.bgColor(0xffffff, dxui.Utils.STYLE_PART.ITEMS)
+ englishKeyboard.bgColor(0xe6e6e6)
+ englishKeyboard.setSize(englishPanel.width(), englishPanel.height())
+ englishKeyboard.align(dxui.Utils.ALIGN.BOTTOM_MID, 0, 0)
+ if (capital) {
+ englishKeyboard.data([
+ "Q", "W", "E", "R", "T", "Y", "U", "I", "O", "P", "\n",
+ " ", "A", "S", "D", "F", "G", "H", "J", "K", "L", " ", "\n",
+ "鈫�", "Z", "X", "C", "V", "B", "N", "M", " ", "\n",
+ "!?#", "123", ",", " ", ".", "EN", " ",
+ ""])
+ } else {
+ englishKeyboard.data([
+ "q", "w", "e", "r", "t", "y", "u", "i", "o", "p", "\n",
+ " ", "a", "s", "d", "f", "g", "h", "j", "k", "l", " ", "\n",
+ "鈫�", "z", "x", "c", "v", "b", "n", "m", " ", "\n",
+ "!?#", "123", ",", " ", ".", "EN", " ",
+ ""])
+ }
+ // 璁剧疆鎸夐挳瀹藉害
+ englishKeyboard.setBtnWidth(10, 1)
+ for (let i = 11; i < 20; i++) {
+ englishKeyboard.setBtnWidth(i, 2)
+ }
+ englishKeyboard.setBtnWidth(20, 1)
+ englishKeyboard.setBtnWidth(21, 3)
+ for (let i = 22; i < 29; i++) {
+ englishKeyboard.setBtnWidth(i, 2)
+ }
+ englishKeyboard.setBtnWidth(29, 3)
+ englishKeyboard.obj.addEventCb((e) => {
+ let dsc = e.lvEventGetDrawPartDsc()
+ if (dsc.class_p == englishKeyboard.obj.ClassP && dsc.type == dxui.Utils.ENUM.LV_BTNMATRIX_DRAW_PART_BTN) {
+ // 闅愯棌鏃犵敤鎸夐挳
+ if (dsc.id == 10 || dsc.id == 20) {
+ dxui.Utils.GG.NativeDraw.lvDrawRectReset(dsc.rect_dsc, { bg_opa: 0, shadow_opa: 0 })
+ }
+ // 鍔犳繁涓�浜涘姛鑳芥寜閽�
+ if (dsc.id == 21 || dsc.id == 29 || dsc.id == 30 || dsc.id == 31 || dsc.id == 35) {
+ if (englishKeyboard.obj.lvBtnmatrixGetSelectedBtn() == dsc.id && e.lvEventGetTarget().hasState(dxui.Utils.ENUM.LV_STATE_PRESSED)) {
+ dxui.Utils.GG.NativeDraw.lvDrawRectReset(dsc.rect_dsc, { bg_color: 0xcdcdcd })
+ } else {
+ dxui.Utils.GG.NativeDraw.lvDrawRectReset(dsc.rect_dsc, { bg_color: 0xdbdbdb })
+ }
+ }
+ // 鍥炶溅鎸夐挳钃濊壊
+ if (dsc.id == 36) {
+ if (englishKeyboard.obj.lvBtnmatrixGetSelectedBtn() == dsc.id && e.lvEventGetTarget().hasState(dxui.Utils.ENUM.LV_STATE_PRESSED)) {
+ dxui.Utils.GG.NativeDraw.lvDrawRectReset(dsc.rect_dsc, { bg_color: 0x0C6CE4 })
+ } else {
+ dxui.Utils.GG.NativeDraw.lvDrawRectReset(dsc.rect_dsc, { bg_color: 0x0C78FE })
+ }
+ }
+ }
+ }, dxui.Utils.ENUM.LV_EVENT_DRAW_PART_BEGIN)
+ englishKeyboard.obj.addEventCb((e) => {
+ let dsc = e.lvEventGetDrawPartDsc()
+ if (dsc.class_p == englishKeyboard.obj.ClassP && dsc.type == dxui.Utils.ENUM.LV_BTNMATRIX_DRAW_PART_BTN) {
+ // 鍒犻櫎鎸夐挳鍥炬娣诲姞
+ if (dsc.id == 29) {
+ let src = '/app/code/resource/image/backspace.png'
+ // 鑾峰彇鍥剧墖淇℃伅
+ let header = dxui.Utils.GG.NativeDraw.lvImgDecoderGetInfo(src)
+ // 瀹氫箟涓�鍧楀尯鍩燂紝灞呬腑鏄剧ず锛屾敞鎰忥細灏哄杞琣rea闇�瑕�-1锛宎rea杞昂瀵搁渶瑕�+1
+ let x1 = dsc.draw_area.x1 + (dsc.draw_area.x2 - dsc.draw_area.x1 + 1 - header.w) / 2;
+ let y1 = dsc.draw_area.y1 + (dsc.draw_area.y2 - dsc.draw_area.y1 + 1 - header.h) / 2;
+ let x2 = x1 + header.w - 1;
+ let y2 = y1 + header.h - 1;
+ let area = dxui.Utils.GG.NativeArea.lvAreaSet(x1, y1, x2, y2)
+ // 缁樺埗鍥剧墖淇℃伅
+ let img_draw_dsc = dxui.Utils.GG.NativeDraw.lvDrawImgDscInit()
+ // 缁樺埗鍥剧墖
+ dxui.Utils.GG.NativeDraw.lvDrawImg(dsc.dsc, img_draw_dsc, area, src)
+ }
+ // 鍥炶溅鎸夐挳鍥炬娣诲姞
+ if (dsc.id == 36) {
+ let src = '/app/code/resource/image/enter.png'
+ // 鑾峰彇鍥剧墖淇℃伅
+ let header = dxui.Utils.GG.NativeDraw.lvImgDecoderGetInfo(src)
+ // 瀹氫箟涓�鍧楀尯鍩燂紝灞呬腑鏄剧ず锛屾敞鎰忥細灏哄杞琣rea闇�瑕�-1锛宎rea杞昂瀵搁渶瑕�+1
+ let x1 = dsc.draw_area.x1 + (dsc.draw_area.x2 - dsc.draw_area.x1 + 1 - header.w) / 2;
+ let y1 = dsc.draw_area.y1 + (dsc.draw_area.y2 - dsc.draw_area.y1 + 1 - header.h) / 2;
+ let x2 = x1 + header.w - 1;
+ let y2 = y1 + header.h - 1;
+ let area = dxui.Utils.GG.NativeArea.lvAreaSet(x1, y1, x2, y2)
+ // 缁樺埗鍥剧墖淇℃伅
+ let img_draw_dsc = dxui.Utils.GG.NativeDraw.lvDrawImgDscInit()
+ // 缁樺埗鍥剧墖
+ dxui.Utils.GG.NativeDraw.lvDrawImg(dsc.dsc, img_draw_dsc, area, src)
+ }
+ // 绌烘牸鎸夐挳鍥炬娣诲姞
+ if (dsc.id == 33) {
+ let src = '/app/code/resource/image/space.png'
+ // 鑾峰彇鍥剧墖淇℃伅
+ let header = dxui.Utils.GG.NativeDraw.lvImgDecoderGetInfo(src)
+ // 瀹氫箟涓�鍧楀尯鍩燂紝灞呬腑鏄剧ず锛屾敞鎰忥細灏哄杞琣rea闇�瑕�-1锛宎rea杞昂瀵搁渶瑕�+1
+ let x1 = dsc.draw_area.x1 + (dsc.draw_area.x2 - dsc.draw_area.x1 + 1 - header.w) / 2;
+ let y1 = dsc.draw_area.y1 + (dsc.draw_area.y2 - dsc.draw_area.y1 + 1 - header.h) / 2;
+ let x2 = x1 + header.w - 1;
+ let y2 = y1 + header.h - 1;
+ y1 += 10
+ y2 += 10
+ let area = dxui.Utils.GG.NativeArea.lvAreaSet(x1, y1, x2, y2)
+ // 缁樺埗鍥剧墖淇℃伅
+ let img_draw_dsc = dxui.Utils.GG.NativeDraw.lvDrawImgDscInit()
+ // 缁樺埗鍥剧墖
+ dxui.Utils.GG.NativeDraw.lvDrawImg(dsc.dsc, img_draw_dsc, area, src)
+ }
+ }
+ }, dxui.Utils.ENUM.LV_EVENT_DRAW_PART_END)
+ englishKeyboard.on(dxui.Utils.ENUM.LV_EVENT_LONG_PRESSED_REPEAT, () => {
+ let clickBtn = englishKeyboard.clickedButton()
+ let id = clickBtn.id
+ switch (id) {
+ case 29:
+ // 閫�鏍�
+ pinyin.cb({ cmd: "backspace" })
+ break;
+ }
+ })
+ englishKeyboard.on(dxui.Utils.ENUM.LV_EVENT_PRESSED, () => {
+ let clickBtn = englishKeyboard.clickedButton()
+ let id = clickBtn.id
+ let text = clickBtn.text
+ switch (id) {
+ case 21:
+ // 澶у皬鍐欏垏鎹�
+ if (englishKeyboardBig.isHide()) {
+ englishKeyboardBig.show()
+ englishKeyboardSmall.hide()
+ } else {
+ englishKeyboardBig.hide()
+ englishKeyboardSmall.show()
+ }
+ break;
+ case 29:
+ // 閫�鏍�
+ pinyin.cb({ cmd: "backspace" })
+ break;
+ case 30:
+ if (isLock) {
+ break;
+ }
+ // 鍒囨崲绗﹀彿閿洏
+ pinyin.symbolPanel.show()
+ pinyin.englishPanel.hide()
+ break;
+ case 31:
+ if (isLock) {
+ break;
+ }
+ // 鍒囨崲鏁板瓧閿洏
+ pinyin.numPanel.show()
+ pinyin.englishPanel.hide()
+ break;
+ case 33:
+ // 绌烘牸
+ pinyin.cb(" ")
+ break;
+ case 35:
+ if (isLock || !enablePinyin) {
+ break;
+ }
+ // 鍒囨崲鎷奸煶閿洏
+ pinyin.pinyinPanel.show()
+ pinyin.englishPanel.hide()
+ break;
+ case 36:
+ // 鍥炶溅
+ pinyin.cb({ cmd: "enter" })
+ break;
+ default:
+ break;
+ }
+ // 鎵撳嵃瀛楃
+ if (["q", "w", "e", "r", "t", "y", "u", "i", "o", "p",
+ "a", "s", "d", "f", "g", "h", "j", "k", "l",
+ "z", "x", "c", "v", "b", "n", "m",
+ ",", "."].includes(text) || [
+ "Q", "W", "E", "R", "T", "Y", "U", "I", "O", "P",
+ "A", "S", "D", "F", "G", "H", "J", "K", "L",
+ "Z", "X", "C", "V", "B", "N", "M",
+ ",", "."].includes(text)) {
+ pinyin.cb(text)
+ }
+ })
+ return englishKeyboard
+ }
+ // 鍒涘缓澶у皬鍐欓敭鐩�
+ let englishKeyboardBig = createKeyboard(true)
+ let englishKeyboardSmall = createKeyboard(false)
+ // 榛樿鏄皬鍐�
+ englishKeyboardBig.hide()
+ englishKeyboardSmall.show()
+ englishPanel.hide()
+ return englishPanel
+}
+
+// 鎷奸煶閿洏
+function createPinyin() {
+ let pinyinPanel = dxui.View.build(pinyin.container.id + 'pinyinPanel', pinyin.container)
+ clearStyle(pinyinPanel)
+ pinyinPanel.setSize(pinyin.container.width(), pinyin.container.height())
+ pinyinPanel.obj.lvObjAddFlag(dxui.Utils.ENUM.LV_OBJ_FLAG_OVERFLOW_VISIBLE)
+ pinyinPanel.update()
+ // 鍒涘缓姹夊瓧棰勮妗�
+ let previewBox = dxui.View.build(pinyinPanel.id + 'previewBox', pinyinPanel)
+ clearStyle(previewBox)
+ previewBox.setSize(pinyinPanel.width(), 70)
+ previewBox.align(dxui.Utils.ALIGN.TOP_LEFT, 0, -70)
+ previewBox.padLeft(20)
+ previewBox.flexFlow(dxui.Utils.FLEX_FLOW.ROW)
+ previewBox.flexAlign(dxui.Utils.FLEX_ALIGN.SPACE_AROUND, dxui.Utils.FLEX_ALIGN.CENTER, dxui.Utils.FLEX_ALIGN.CENTER)
+ previewBox.labels = []
+ // 8涓瑙堟枃瀛�
+ for (let i = 0; i < 8; i++) {
+ let labelBox = dxui.View.build(previewBox.id + 'labelBox' + i, previewBox)
+ clearStyle(labelBox)
+ labelBox.setSize(50, 70)
+ labelBox.on(dxui.Utils.ENUM.LV_EVENT_PRESSED, () => {
+ if (label.text() != " ") {
+ labelBox.bgColor(0xe6e6e6)
+ }
+ })
+ labelBox.on(dxui.Utils.ENUM.LV_EVENT_RELEASED, () => {
+ if (label.text() != " ") {
+ labelBox.bgColor(0xffffff)
+ pinyin.cb(label.text())
+ // 娓呯┖鎷奸煶锛岃繕鍘熺姸鎬�
+ phrase.text("")
+ previewBox.fillData()
+ }
+ })
+ let label = dxui.Label.build(labelBox.id + 'label' + i, labelBox)
+ label.align(dxui.Utils.ALIGN.CENTER, 0, 0)
+ label.text(" ")
+ previewBox.labels.push(label)
+ }
+ // 濉厖棰勮鏂囧瓧
+ previewBox.fillData = (str) => {
+ if (!str) {
+ // str = "寰厜浜掕仈"
+ str = ""
+ }
+ previewBox.characters = str
+ for (let i = 0; i < 8; i++) {
+ if (str.charAt(i)) {
+ previewBox.labels[i].text(str.charAt(i))
+ } else {
+ previewBox.labels[i].text(" ")
+ }
+ }
+ if (str.length > 8) {
+ // 鏂囧瓧澶氫簬8涓紝灞曠ず鏇村鏂囧瓧鎸夐挳
+ morePreview.show()
+ } else {
+ morePreview.hide()
+ }
+ }
+ // 鏇村姹夊瓧棰勮鎸夐挳
+ let morePreview = dxui.View.build(pinyinPanel.id + 'morePreview', pinyinPanel)
+ clearStyle(morePreview)
+ morePreview.setSize(70, 70)
+ morePreview.align(dxui.Utils.ALIGN.TOP_RIGHT, 0, -70)
+ morePreview.hide()
+ let rightBtn = dxui.Image.build(morePreview.id + 'rightBtn', morePreview)
+ rightBtn.source('/app/code/resource/image/right.png')
+ rightBtn.align(dxui.Utils.ALIGN.CENTER, 0, 0)
+ morePreview.on(dxui.Utils.ENUM.LV_EVENT_PRESSED, () => {
+ morePreview.bgColor(0xe6e6e6)
+ })
+ morePreview.on(dxui.Utils.ENUM.LV_EVENT_RELEASED, () => {
+ morePreview.bgColor(0xffffff)
+ morePreviewKeyboard.moveForeground()
+ morePreviewKeyboard.fillData(0)
+ morePreviewKeyboard.show()
+ })
+ // 鍒濆鐘舵��
+ previewBox.fillData()
+ // 鏇村姹夊瓧闈㈡澘
+ let morePreviewKeyboard = dxui.Buttons.build(pinyinPanel.id + 'morePreviewKeyboard', pinyinPanel)
+ clearStyle(morePreviewKeyboard)
+ morePreviewKeyboard.setSize(pinyinPanel.width(), pinyinPanel.height())
+ morePreviewKeyboard.hide()
+ morePreviewKeyboard.obj.lvObjSetStylePadGap(10, dxui.Utils.ENUM._LV_STYLE_STATE_CMP_SAME)
+ morePreviewKeyboard.padAll(10)
+ morePreviewKeyboard.bgColor(0xffffff, dxui.Utils.STYLE_PART.ITEMS)
+ morePreviewKeyboard.bgColor(0xe6e6e6)
+ morePreviewKeyboard.align(dxui.Utils.ALIGN.BOTTOM_MID, 0, 0)
+ morePreviewKeyboard.data([
+ " ", " ", " ", " ", " ", " ", " ", " ", "\n",
+ " ", " ", " ", " ", " ", " ", " ", " ", "\n",
+ " ", " ", " ", " ", " ", " ", " ", " ", "\n",
+ " ", " ", " ", " ", " ", " ", " ", " ", "\n",
+ "涓婁竴椤�", "杩斿洖", "涓嬩竴椤�",
+ ""])
+ morePreviewKeyboard.index = 0
+ // index:0绗竴椤碉紝1涓嬩竴椤碉紝-1涓婁竴椤�
+ morePreviewKeyboard.fillData = (index) => {
+ if (index == 1 && previewBox.characters.charAt((morePreviewKeyboard.index + 1) * 32)) {
+ morePreviewKeyboard.index += 1
+ } else if (index == -1 && morePreviewKeyboard.index > 0) {
+ morePreviewKeyboard.index -= 1
+ } else {
+ morePreviewKeyboard.index = 0
+ }
+ let temp = []
+ for (let i = 0; i < 32; i++) {
+ let character = previewBox.characters.charAt(i + morePreviewKeyboard.index * 32)
+ if (character) {
+ temp.push(character)
+ } else {
+ if (i == 0) {
+ // 鏃犳暟鎹�
+ return
+ }
+ temp.push(" ")
+ }
+ if ((i + 1) % 8 == 0) {
+ temp.push("\n")
+ }
+ }
+ temp.push("涓婁竴椤�")
+ temp.push("杩斿洖")
+ temp.push("涓嬩竴椤�")
+ temp.push("")
+ morePreviewKeyboard.data(temp)
+ }
+ morePreviewKeyboard.obj.addEventCb((e) => {
+ let dsc = e.lvEventGetDrawPartDsc()
+ if (dsc.class_p == morePreviewKeyboard.obj.ClassP && dsc.type == dxui.Utils.ENUM.LV_BTNMATRIX_DRAW_PART_BTN) {
+ // 鍔犳繁涓や釜鍔熻兘鎸夐挳
+ if ([32, 33, 34].includes(dsc.id)) {
+ if (morePreviewKeyboard.obj.lvBtnmatrixGetSelectedBtn() == dsc.id && e.lvEventGetTarget().hasState(dxui.Utils.ENUM.LV_STATE_PRESSED)) {
+ dxui.Utils.GG.NativeDraw.lvDrawRectReset(dsc.rect_dsc, { bg_color: 0xcdcdcd })
+ } else {
+ dxui.Utils.GG.NativeDraw.lvDrawRectReset(dsc.rect_dsc, { bg_color: 0xdbdbdb })
+ }
+ }
+ }
+ }, dxui.Utils.ENUM.LV_EVENT_DRAW_PART_BEGIN)
+ morePreviewKeyboard.on(dxui.Utils.ENUM.LV_EVENT_PRESSED, () => {
+ let clickBtn = morePreviewKeyboard.clickedButton()
+ let id = clickBtn.id
+ let text = clickBtn.text
+ if (text == "杩斿洖") {
+ morePreviewKeyboard.hide()
+ } else if (text == "涓婁竴椤�") {
+ morePreviewKeyboard.fillData(-1)
+ } else if (text == "涓嬩竴椤�") {
+ morePreviewKeyboard.fillData(1)
+ } else if (text != " ") {
+ pinyin.cb(text)
+ // 娓呯┖鎷奸煶锛岃繕鍘熺姸鎬�
+ phrase.text("")
+ previewBox.fillData()
+ morePreviewKeyboard.hide()
+ }
+ })
+ // 璇嶇粍棰勮
+ let phrasePreview = dxui.View.build(pinyinPanel.id + 'phrasePreview', pinyinPanel)
+ clearStyle(phrasePreview)
+ phrasePreview.setSize(70, 35)
+ phrasePreview.align(dxui.Utils.ALIGN.TOP_LEFT, 0, -105)
+ phrasePreview.bgColor(0xe6e6e6)
+ phrasePreview.hide()
+ let phrase = dxui.Label.build(phrasePreview.id + 'phrase', phrasePreview)
+ phrase.align(dxui.Utils.ALIGN.CENTER, 0, 0)
+ let overwrite = phrase.text
+ phrase.text = (v) => {
+ if (typeof v != 'string') {
+ // 鑾峰彇璇嶇粍
+ let temp = overwrite.call(phrase, v)
+ temp = temp == "Text" ? "" : temp
+ return temp
+ }
+ if (v.length == 0) {
+ // 璇嶇粍闀垮害涓�0灏遍殣钘�
+ overwrite.call(phrase, "Text")
+ return phrasePreview.hide()
+ }
+ if (v.length > 10) {
+ // 璇嶇粍棰勮闀垮害涓嶈秴杩�10瀛楃
+ return
+ }
+ phrasePreview.show()
+ overwrite.call(phrase, v)
+ phrase.update()
+ phrasePreview.width(phrase.width() + 40)
+ }
+ let overwrite1 = pinyinPanel.show
+ pinyinPanel.show = () => {
+ // 閲嶅啓鏄剧ず鏂规硶锛屾樉绀烘眽瀛楅瑙堟
+ previewBox.align(dxui.Utils.ALIGN.TOP_LEFT, 0, -70)
+ morePreview.align(dxui.Utils.ALIGN.TOP_RIGHT, 0, -70)
+ phrasePreview.align(dxui.Utils.ALIGN.TOP_LEFT, 0, -105)
+ overwrite1.call(pinyinPanel)
+ }
+ let overwrite2 = pinyinPanel.hide
+ pinyinPanel.hide = () => {
+ // 閲嶅啓闅愯棌鏂规硶锛岄殣钘忔眽瀛楅瑙堟
+ previewBox.align(dxui.Utils.ALIGN.TOP_LEFT, 0, 0)
+ morePreview.align(dxui.Utils.ALIGN.TOP_RIGHT, 0, 0)
+ phrasePreview.align(dxui.Utils.ALIGN.TOP_LEFT, 0, 0)
+ overwrite2.call(pinyinPanel)
+ }
+ // 鍒涘缓鎷奸煶閿洏
+ let pinyinKeyboard = dxui.Buttons.build(pinyinPanel.id + 'pinyinKeyboard', pinyinPanel)
+ clearStyle(pinyinKeyboard)
+ pinyinKeyboard.obj.lvObjSetStylePadGap(10, dxui.Utils.ENUM._LV_STYLE_STATE_CMP_SAME)
+ pinyinKeyboard.padAll(10)
+ pinyinKeyboard.bgColor(0xffffff, dxui.Utils.STYLE_PART.ITEMS)
+ pinyinKeyboard.bgColor(0xe6e6e6)
+ pinyinKeyboard.setSize(pinyinPanel.width(), pinyinPanel.height())
+ pinyinKeyboard.align(dxui.Utils.ALIGN.BOTTOM_MID, 0, 0)
+ pinyinKeyboard.data([
+ "q", "w", "e", "r", "t", "y", "u", "i", "o", "p", "\n",
+ " ", "a", "s", "d", "f", "g", "h", "j", "k", "l", " ", "\n",
+ "鍒嗚瘝", "z", "x", "c", "v", "b", "n", "m", " ", "\n",
+ "!?#", "123", "锛�", " ", "銆�", "涓�", " ",
+ ""])
+ // 璁剧疆鎸夐挳瀹藉害
+ pinyinKeyboard.setBtnWidth(10, 1)
+ for (let i = 11; i < 20; i++) {
+ pinyinKeyboard.setBtnWidth(i, 2)
+ }
+ pinyinKeyboard.setBtnWidth(20, 1)
+ pinyinKeyboard.setBtnWidth(21, 3)
+ for (let i = 22; i < 29; i++) {
+ pinyinKeyboard.setBtnWidth(i, 2)
+ }
+ pinyinKeyboard.setBtnWidth(29, 3)
+ pinyinKeyboard.obj.addEventCb((e) => {
+ let dsc = e.lvEventGetDrawPartDsc()
+ if (dsc.class_p == pinyinKeyboard.obj.ClassP && dsc.type == dxui.Utils.ENUM.LV_BTNMATRIX_DRAW_PART_BTN) {
+ // 闅愯棌鏃犵敤鎸夐挳
+ if (dsc.id == 10 || dsc.id == 20) {
+ dxui.Utils.GG.NativeDraw.lvDrawRectReset(dsc.rect_dsc, { bg_opa: 0, shadow_opa: 0 })
+ }
+ // 鍔犳繁涓�浜涘姛鑳芥寜閽�
+ if (dsc.id == 21 || dsc.id == 29 || dsc.id == 30 || dsc.id == 31 || dsc.id == 35) {
+ if (pinyinKeyboard.obj.lvBtnmatrixGetSelectedBtn() == dsc.id && e.lvEventGetTarget().hasState(dxui.Utils.ENUM.LV_STATE_PRESSED)) {
+ dxui.Utils.GG.NativeDraw.lvDrawRectReset(dsc.rect_dsc, { bg_color: 0xcdcdcd })
+ } else {
+ dxui.Utils.GG.NativeDraw.lvDrawRectReset(dsc.rect_dsc, { bg_color: 0xdbdbdb })
+ }
+ }
+ // 鍥炶溅鎸夐挳钃濊壊
+ if (dsc.id == 36) {
+ if (pinyinKeyboard.obj.lvBtnmatrixGetSelectedBtn() == dsc.id && e.lvEventGetTarget().hasState(dxui.Utils.ENUM.LV_STATE_PRESSED)) {
+ dxui.Utils.GG.NativeDraw.lvDrawRectReset(dsc.rect_dsc, { bg_color: 0x0C6CE4 })
+ } else {
+ dxui.Utils.GG.NativeDraw.lvDrawRectReset(dsc.rect_dsc, { bg_color: 0x0C78FE })
+ }
+ }
+ }
+ }, dxui.Utils.ENUM.LV_EVENT_DRAW_PART_BEGIN)
+ pinyinKeyboard.obj.addEventCb((e) => {
+ let dsc = e.lvEventGetDrawPartDsc()
+ if (dsc.class_p == pinyinKeyboard.obj.ClassP && dsc.type == dxui.Utils.ENUM.LV_BTNMATRIX_DRAW_PART_BTN) {
+ // 鍒犻櫎鎸夐挳鍥炬娣诲姞
+ if (dsc.id == 29) {
+ let src = '/app/code/resource/image/backspace.png'
+ // 鑾峰彇鍥剧墖淇℃伅
+ let header = dxui.Utils.GG.NativeDraw.lvImgDecoderGetInfo(src)
+ // 瀹氫箟涓�鍧楀尯鍩燂紝灞呬腑鏄剧ず锛屾敞鎰忥細灏哄杞琣rea闇�瑕�-1锛宎rea杞昂瀵搁渶瑕�+1
+ let x1 = dsc.draw_area.x1 + (dsc.draw_area.x2 - dsc.draw_area.x1 + 1 - header.w) / 2;
+ let y1 = dsc.draw_area.y1 + (dsc.draw_area.y2 - dsc.draw_area.y1 + 1 - header.h) / 2;
+ let x2 = x1 + header.w - 1;
+ let y2 = y1 + header.h - 1;
+ let area = dxui.Utils.GG.NativeArea.lvAreaSet(x1, y1, x2, y2)
+ // 缁樺埗鍥剧墖淇℃伅
+ let img_draw_dsc = dxui.Utils.GG.NativeDraw.lvDrawImgDscInit()
+ // 缁樺埗鍥剧墖
+ dxui.Utils.GG.NativeDraw.lvDrawImg(dsc.dsc, img_draw_dsc, area, src)
+ }
+ // 鍥炶溅鎸夐挳鍥炬娣诲姞
+ if (dsc.id == 36) {
+ let src = '/app/code/resource/image/enter.png'
+ // 鑾峰彇鍥剧墖淇℃伅
+ let header = dxui.Utils.GG.NativeDraw.lvImgDecoderGetInfo(src)
+ // 瀹氫箟涓�鍧楀尯鍩燂紝灞呬腑鏄剧ず锛屾敞鎰忥細灏哄杞琣rea闇�瑕�-1锛宎rea杞昂瀵搁渶瑕�+1
+ let x1 = dsc.draw_area.x1 + (dsc.draw_area.x2 - dsc.draw_area.x1 + 1 - header.w) / 2;
+ let y1 = dsc.draw_area.y1 + (dsc.draw_area.y2 - dsc.draw_area.y1 + 1 - header.h) / 2;
+ let x2 = x1 + header.w - 1;
+ let y2 = y1 + header.h - 1;
+ let area = dxui.Utils.GG.NativeArea.lvAreaSet(x1, y1, x2, y2)
+ // 缁樺埗鍥剧墖淇℃伅
+ let img_draw_dsc = dxui.Utils.GG.NativeDraw.lvDrawImgDscInit()
+ // 缁樺埗鍥剧墖
+ dxui.Utils.GG.NativeDraw.lvDrawImg(dsc.dsc, img_draw_dsc, area, src)
+ }
+ // 绌烘牸鎸夐挳鍥炬娣诲姞
+ if (dsc.id == 33) {
+ let src = '/app/code/resource/image/space.png'
+ // 鑾峰彇鍥剧墖淇℃伅
+ let header = dxui.Utils.GG.NativeDraw.lvImgDecoderGetInfo(src)
+ // 瀹氫箟涓�鍧楀尯鍩燂紝灞呬腑鏄剧ず锛屾敞鎰忥細灏哄杞琣rea闇�瑕�-1锛宎rea杞昂瀵搁渶瑕�+1
+ let x1 = dsc.draw_area.x1 + (dsc.draw_area.x2 - dsc.draw_area.x1 + 1 - header.w) / 2;
+ let y1 = dsc.draw_area.y1 + (dsc.draw_area.y2 - dsc.draw_area.y1 + 1 - header.h) / 2;
+ let x2 = x1 + header.w - 1;
+ let y2 = y1 + header.h - 1;
+ y1 += 10
+ y2 += 10
+ let area = dxui.Utils.GG.NativeArea.lvAreaSet(x1, y1, x2, y2)
+ // 缁樺埗鍥剧墖淇℃伅
+ let img_draw_dsc = dxui.Utils.GG.NativeDraw.lvDrawImgDscInit()
+ // 缁樺埗鍥剧墖
+ dxui.Utils.GG.NativeDraw.lvDrawImg(dsc.dsc, img_draw_dsc, area, src)
+ }
+ }
+ }, dxui.Utils.ENUM.LV_EVENT_DRAW_PART_END)
+ // 鏌ュ瓧鍏革紝鏍规嵁杈撳叆鍐呭鏌ユ壘
+ function search() {
+ // 杈撳叆鐨勬嫾闊�
+ let searchStr = phrase.text()
+ if (searchStr.indexOf("'") >= 0) {
+ searchStr = searchStr.substring(0, searchStr.indexOf("'"))
+ }
+ if (searchStr.length <= 0) {
+ // 杈撳叆鐨勬嫾闊充负绌�
+ previewBox.fillData()
+ return
+ }
+ let characters = ""
+ let res = Object.keys(dict).filter(v => v.startsWith(searchStr))
+ if (res.length > 0) {
+ res.forEach(v => {
+ characters += dict[v]
+ })
+ }
+ previewBox.fillData(characters)
+ }
+ pinyinKeyboard.on(dxui.Utils.ENUM.LV_EVENT_LONG_PRESSED_REPEAT, () => {
+ let clickBtn = pinyinKeyboard.clickedButton()
+ let id = clickBtn.id
+ switch (id) {
+ case 29:
+ // 閫�鏍硷紝鏈夎瘝缁勫厛鍒犻櫎璇嶇粍
+ let temp = phrase.text()
+ if (temp.length > 0) {
+ phrase.text(temp.substring(0, temp.length - 1))
+ } else {
+ pinyin.cb({ cmd: "backspace" })
+ }
+ break;
+ }
+ })
+ pinyinKeyboard.on(dxui.Utils.ENUM.LV_EVENT_PRESSED, () => {
+ let clickBtn = pinyinKeyboard.clickedButton()
+ let id = clickBtn.id
+ let text = clickBtn.text
+ switch (id) {
+ case 21:
+ // 鍒嗚瘝
+ if (phrase.text().length != 0 && phrase.text().indexOf("'") < 0) {
+ phrase.text(phrase.text() + "'")
+ }
+ break;
+ case 29:
+ // 閫�鏍硷紝鏈夎瘝缁勫厛鍒犻櫎璇嶇粍
+ let temp = phrase.text()
+ if (temp.length > 0) {
+ phrase.text(temp.substring(0, temp.length - 1))
+ } else {
+ pinyin.cb({ cmd: "backspace" })
+ }
+ break;
+ case 30:
+ if (isLock) {
+ break;
+ }
+ // 鍒囨崲绗﹀彿閿洏
+ pinyin.symbolPanel.show()
+ pinyin.pinyinPanel.hide()
+ break;
+ case 31:
+ if (isLock) {
+ break;
+ }
+ // 鍒囨崲鏁板瓧閿洏
+ pinyin.numPanel.show()
+ pinyin.pinyinPanel.hide()
+ break;
+ case 33:
+ // 绌烘牸
+ pinyin.cb(" ")
+ break;
+ case 35:
+ if (isLock) {
+ break;
+ }
+ // 鍒囨崲鑻辨枃閿洏
+ pinyin.englishPanel.show()
+ pinyin.pinyinPanel.hide()
+ break;
+ case 36:
+ if (phrase.text().length > 0) {
+ pinyin.cb(phrase.text())
+ phrase.text("")
+ previewBox.fillData()
+ break;
+ }
+ // 鍥炶溅
+ pinyin.cb({ cmd: "enter" })
+ break;
+ default:
+ break;
+ }
+ // 鎵撳嵃瀛楃
+ if (["锛�", "銆�"].includes(text)) {
+ pinyin.cb(text)
+ }
+ if (["q", "w", "e", "r", "t", "y", "u", "i", "o", "p",
+ "a", "s", "d", "f", "g", "h", "j", "k", "l",
+ "z", "x", "c", "v", "b", "n", "m"].includes(text) && phrase.text().indexOf("'") < 0) {
+ phrase.text(phrase.text() + text)
+ }
+ search()
+ })
+ pinyinPanel.hide()
+ return pinyinPanel
+}
+
+// 鏁板瓧閿洏
+function createNum() {
+ let numPanel = dxui.View.build(pinyin.container.id + 'numPanel', pinyin.container)
+ clearStyle(numPanel)
+ numPanel.setSize(pinyin.container.width(), pinyin.container.height())
+ numPanel.update()
+ // 鍒涘缓鏁板瓧閿洏
+ let numKeyboard = dxui.Buttons.build(numPanel.id + 'numKeyboard', numPanel)
+ clearStyle(numKeyboard)
+ numKeyboard.obj.lvObjSetStylePadGap(10, dxui.Utils.ENUM._LV_STYLE_STATE_CMP_SAME)
+ numKeyboard.padAll(10)
+ numKeyboard.bgColor(0xffffff, dxui.Utils.STYLE_PART.ITEMS)
+ numKeyboard.bgColor(0xe6e6e6)
+ numKeyboard.setSize(numPanel.width(), numPanel.height())
+ numKeyboard.data([
+ "1", "2", "3", " ", "\n",
+ "4", "5", "6", "+", "\n",
+ "7", "8", "9", "-", "\n",
+ "ABC", "0", ".", " ", "",
+ ])
+ numKeyboard.obj.addEventCb((e) => {
+ let dsc = e.lvEventGetDrawPartDsc()
+ if (dsc.class_p == numKeyboard.obj.ClassP && dsc.type == dxui.Utils.ENUM.LV_BTNMATRIX_DRAW_PART_BTN) {
+ // 鍔犳繁涓や釜鍔熻兘鎸夐挳
+ if ([3, 7, 11, 12, 14].includes(dsc.id)) {
+ if (numKeyboard.obj.lvBtnmatrixGetSelectedBtn() == dsc.id && e.lvEventGetTarget().hasState(dxui.Utils.ENUM.LV_STATE_PRESSED)) {
+ dxui.Utils.GG.NativeDraw.lvDrawRectReset(dsc.rect_dsc, { bg_color: 0xcdcdcd })
+ } else {
+ dxui.Utils.GG.NativeDraw.lvDrawRectReset(dsc.rect_dsc, { bg_color: 0xdbdbdb })
+ }
+ }
+ // 鍥炶溅鎸夐挳钃濊壊
+ if (dsc.id == 15) {
+ if (numKeyboard.obj.lvBtnmatrixGetSelectedBtn() == dsc.id && e.lvEventGetTarget().hasState(dxui.Utils.ENUM.LV_STATE_PRESSED)) {
+ dxui.Utils.GG.NativeDraw.lvDrawRectReset(dsc.rect_dsc, { bg_color: 0x0C6CE4 })
+ } else {
+ dxui.Utils.GG.NativeDraw.lvDrawRectReset(dsc.rect_dsc, { bg_color: 0x0C78FE })
+ }
+ }
+ }
+ }, dxui.Utils.ENUM.LV_EVENT_DRAW_PART_BEGIN)
+ numKeyboard.obj.addEventCb((e) => {
+ let dsc = e.lvEventGetDrawPartDsc()
+ if (dsc.class_p == numKeyboard.obj.ClassP && dsc.type == dxui.Utils.ENUM.LV_BTNMATRIX_DRAW_PART_BTN) {
+ // 鍒犻櫎鎸夐挳鍥炬
+ if (dsc.id == 3) {
+ let src = '/app/code/resource/image/backspace.png'
+ // 鑾峰彇鍥剧墖淇℃伅
+ let header = dxui.Utils.GG.NativeDraw.lvImgDecoderGetInfo(src)
+ // 瀹氫箟涓�鍧楀尯鍩燂紝灞呬腑鏄剧ず锛屾敞鎰忥細灏哄杞琣rea闇�瑕�-1锛宎rea杞昂瀵搁渶瑕�+1
+ let x1 = dsc.draw_area.x1 + (dsc.draw_area.x2 - dsc.draw_area.x1 + 1 - header.w) / 2;
+ let y1 = dsc.draw_area.y1 + (dsc.draw_area.y2 - dsc.draw_area.y1 + 1 - header.h) / 2;
+ let x2 = x1 + header.w - 1;
+ let y2 = y1 + header.h - 1;
+ let area = dxui.Utils.GG.NativeArea.lvAreaSet(x1, y1, x2, y2)
+ // 缁樺埗鍥剧墖淇℃伅
+ let img_draw_dsc = dxui.Utils.GG.NativeDraw.lvDrawImgDscInit()
+ // 缁樺埗鍥剧墖
+ dxui.Utils.GG.NativeDraw.lvDrawImg(dsc.dsc, img_draw_dsc, area, src)
+ }
+ if (dsc.id == 15) {
+ let src = '/app/code/resource/image/enter.png'
+ // 鑾峰彇鍥剧墖淇℃伅
+ let header = dxui.Utils.GG.NativeDraw.lvImgDecoderGetInfo(src)
+ // 瀹氫箟涓�鍧楀尯鍩燂紝灞呬腑鏄剧ず锛屾敞鎰忥細灏哄杞琣rea闇�瑕�-1锛宎rea杞昂瀵搁渶瑕�+1
+ let x1 = dsc.draw_area.x1 + (dsc.draw_area.x2 - dsc.draw_area.x1 + 1 - header.w) / 2;
+ let y1 = dsc.draw_area.y1 + (dsc.draw_area.y2 - dsc.draw_area.y1 + 1 - header.h) / 2;
+ let x2 = x1 + header.w - 1;
+ let y2 = y1 + header.h - 1;
+ let area = dxui.Utils.GG.NativeArea.lvAreaSet(x1, y1, x2, y2)
+ // 缁樺埗鍥剧墖淇℃伅
+ let img_draw_dsc = dxui.Utils.GG.NativeDraw.lvDrawImgDscInit()
+ // 缁樺埗鍥剧墖
+ dxui.Utils.GG.NativeDraw.lvDrawImg(dsc.dsc, img_draw_dsc, area, src)
+ }
+ }
+ }, dxui.Utils.ENUM.LV_EVENT_DRAW_PART_END)
+ numKeyboard.on(dxui.Utils.ENUM.LV_EVENT_LONG_PRESSED_REPEAT, () => {
+ let clickBtn = numKeyboard.clickedButton()
+ let id = clickBtn.id
+ switch (id) {
+ case 3:
+ // 閫�鏍�
+ pinyin.cb({ cmd: "backspace" })
+ break;
+ }
+ })
+ numKeyboard.on(dxui.Utils.ENUM.LV_EVENT_PRESSED, () => {
+ let clickBtn = numKeyboard.clickedButton()
+ let id = clickBtn.id
+ let text = clickBtn.text
+ switch (id) {
+ case 3:
+ // 閫�鏍�
+ pinyin.cb({ cmd: "backspace" })
+ break;
+ case 12:
+ if (isLock) {
+ break;
+ }
+ // 鍒囨崲鑻辨枃閿洏
+ pinyin.englishPanel.show()
+ pinyin.numPanel.hide()
+ break;
+ case 15:
+ // 鍥炶溅
+ pinyin.cb({ cmd: "enter" })
+ break;
+ default:
+ break;
+ }
+ // 鎵撳嵃瀛楃
+ if (["1", "2", "3",
+ "4", "5", "6", "+",
+ "7", "8", "9", "-",
+ "0", "."].includes(text)) {
+ pinyin.cb(text)
+ }
+ })
+ numPanel.hide()
+ return numPanel
+}
+
+// 绗﹀彿閿洏
+function createSymbol() {
+ let symbolPanel = dxui.View.build(pinyin.container.id + 'symbolPanel', pinyin.container)
+ clearStyle(symbolPanel)
+ symbolPanel.setSize(pinyin.container.width(), pinyin.container.height())
+ symbolPanel.update()
+ // 鍒涘缓绗﹀彿閿洏
+ let symbolKeyboard = dxui.Buttons.build(symbolPanel.id + 'symbolKeyboard', symbolPanel)
+ clearStyle(symbolKeyboard)
+ symbolKeyboard.obj.lvObjSetStylePadGap(10, dxui.Utils.ENUM._LV_STYLE_STATE_CMP_SAME)
+ symbolKeyboard.padAll(10)
+ symbolKeyboard.bgColor(0xffffff, dxui.Utils.STYLE_PART.ITEMS)
+ symbolKeyboard.bgColor(0xe6e6e6)
+ symbolKeyboard.setSize(symbolPanel.width(), symbolPanel.height())
+ symbolKeyboard.data([
+ "^", "\\", "|", "<", ">", "垄", "拢", "鈧�", "楼", "鈧�", "\n",
+ "[", "]", "{", "}", "#", "%", "+", "=", "~", "_", "\n",
+ " ", "-", "/", ":", ";", "(", ")", "$", "&", "\"", " ", "\n",
+ "123", "`", "?", "!", "*", "@", ",", "'", " ", "\n",
+ "ABC", " ", " ", ""
+ ])
+ symbolKeyboard.setBtnWidth(20, 1)
+ for (let i = 21; i < 30; i++) {
+ symbolKeyboard.setBtnWidth(i, 2)
+ }
+ symbolKeyboard.setBtnWidth(30, 1)
+ symbolKeyboard.setBtnWidth(31, 3)
+ for (let i = 32; i < 39; i++) {
+ symbolKeyboard.setBtnWidth(i, 2)
+ }
+ symbolKeyboard.setBtnWidth(39, 3)
+ symbolKeyboard.setBtnWidth(41, 2)
+ symbolKeyboard.obj.addEventCb((e) => {
+ let dsc = e.lvEventGetDrawPartDsc()
+ if (dsc.class_p == symbolKeyboard.obj.ClassP && dsc.type == dxui.Utils.ENUM.LV_BTNMATRIX_DRAW_PART_BTN) {
+ // 闅愯棌鏃犵敤鎸夐挳
+ if (dsc.id == 20 || dsc.id == 30) {
+ dxui.Utils.GG.NativeDraw.lvDrawRectReset(dsc.rect_dsc, { bg_opa: 0, shadow_opa: 0 })
+ }
+ // 鍔犳繁涓�浜涘姛鑳芥寜閽�
+ if (dsc.id == 31 || dsc.id == 39 || dsc.id == 40 || dsc.id == 41 || dsc.id == 45) {
+ if (symbolKeyboard.obj.lvBtnmatrixGetSelectedBtn() == dsc.id && e.lvEventGetTarget().hasState(dxui.Utils.ENUM.LV_STATE_PRESSED)) {
+ dxui.Utils.GG.NativeDraw.lvDrawRectReset(dsc.rect_dsc, { bg_color: 0xcdcdcd })
+ } else {
+ dxui.Utils.GG.NativeDraw.lvDrawRectReset(dsc.rect_dsc, { bg_color: 0xdbdbdb })
+ }
+ }
+ // 鍥炶溅鎸夐挳钃濊壊
+ if (dsc.id == 42) {
+ if (symbolKeyboard.obj.lvBtnmatrixGetSelectedBtn() == dsc.id && e.lvEventGetTarget().hasState(dxui.Utils.ENUM.LV_STATE_PRESSED)) {
+ dxui.Utils.GG.NativeDraw.lvDrawRectReset(dsc.rect_dsc, { bg_color: 0x0C6CE4 })
+ } else {
+ dxui.Utils.GG.NativeDraw.lvDrawRectReset(dsc.rect_dsc, { bg_color: 0x0C78FE })
+ }
+ }
+ }
+ }, dxui.Utils.ENUM.LV_EVENT_DRAW_PART_BEGIN)
+ symbolKeyboard.obj.addEventCb((e) => {
+ let dsc = e.lvEventGetDrawPartDsc()
+ if (dsc.class_p == symbolKeyboard.obj.ClassP && dsc.type == dxui.Utils.ENUM.LV_BTNMATRIX_DRAW_PART_BTN) {
+ if (dsc.id == 39) {
+ let src = '/app/code/resource/image/backspace.png'
+ // 鑾峰彇鍥剧墖淇℃伅
+ let header = dxui.Utils.GG.NativeDraw.lvImgDecoderGetInfo(src)
+ // 瀹氫箟涓�鍧楀尯鍩燂紝灞呬腑鏄剧ず锛屾敞鎰忥細灏哄杞琣rea闇�瑕�-1锛宎rea杞昂瀵搁渶瑕�+1
+ let x1 = dsc.draw_area.x1 + (dsc.draw_area.x2 - dsc.draw_area.x1 + 1 - header.w) / 2;
+ let y1 = dsc.draw_area.y1 + (dsc.draw_area.y2 - dsc.draw_area.y1 + 1 - header.h) / 2;
+ let x2 = x1 + header.w - 1;
+ let y2 = y1 + header.h - 1;
+ let area = dxui.Utils.GG.NativeArea.lvAreaSet(x1, y1, x2, y2)
+ // 缁樺埗鍥剧墖淇℃伅
+ let img_draw_dsc = dxui.Utils.GG.NativeDraw.lvDrawImgDscInit()
+ // 缁樺埗鍥剧墖
+ dxui.Utils.GG.NativeDraw.lvDrawImg(dsc.dsc, img_draw_dsc, area, src)
+ }
+ if (dsc.id == 42) {
+ let src = '/app/code/resource/image/enter.png'
+ // 鑾峰彇鍥剧墖淇℃伅
+ let header = dxui.Utils.GG.NativeDraw.lvImgDecoderGetInfo(src)
+ // 瀹氫箟涓�鍧楀尯鍩燂紝灞呬腑鏄剧ず锛屾敞鎰忥細灏哄杞琣rea闇�瑕�-1锛宎rea杞昂瀵搁渶瑕�+1
+ let x1 = dsc.draw_area.x1 + (dsc.draw_area.x2 - dsc.draw_area.x1 + 1 - header.w) / 2;
+ let y1 = dsc.draw_area.y1 + (dsc.draw_area.y2 - dsc.draw_area.y1 + 1 - header.h) / 2;
+ let x2 = x1 + header.w - 1;
+ let y2 = y1 + header.h - 1;
+ let area = dxui.Utils.GG.NativeArea.lvAreaSet(x1, y1, x2, y2)
+ // 缁樺埗鍥剧墖淇℃伅
+ let img_draw_dsc = dxui.Utils.GG.NativeDraw.lvDrawImgDscInit()
+ // 缁樺埗鍥剧墖
+ dxui.Utils.GG.NativeDraw.lvDrawImg(dsc.dsc, img_draw_dsc, area, src)
+ }
+ if (dsc.id == 41) {
+ let src = '/app/code/resource/image/space.png'
+ // 鑾峰彇鍥剧墖淇℃伅
+ let header = dxui.Utils.GG.NativeDraw.lvImgDecoderGetInfo(src)
+ // 瀹氫箟涓�鍧楀尯鍩燂紝灞呬腑鏄剧ず锛屾敞鎰忥細灏哄杞琣rea闇�瑕�-1锛宎rea杞昂瀵搁渶瑕�+1
+ let x1 = dsc.draw_area.x1 + (dsc.draw_area.x2 - dsc.draw_area.x1 + 1 - header.w) / 2;
+ let y1 = dsc.draw_area.y1 + (dsc.draw_area.y2 - dsc.draw_area.y1 + 1 - header.h) / 2;
+ let x2 = x1 + header.w - 1;
+ let y2 = y1 + header.h - 1;
+ y1 += 10
+ y2 += 10
+ let area = dxui.Utils.GG.NativeArea.lvAreaSet(x1, y1, x2, y2)
+ // 缁樺埗鍥剧墖淇℃伅
+ let img_draw_dsc = dxui.Utils.GG.NativeDraw.lvDrawImgDscInit()
+ // 缁樺埗鍥剧墖
+ dxui.Utils.GG.NativeDraw.lvDrawImg(dsc.dsc, img_draw_dsc, area, src)
+ }
+ }
+ }, dxui.Utils.ENUM.LV_EVENT_DRAW_PART_END)
+ symbolKeyboard.on(dxui.Utils.ENUM.LV_EVENT_LONG_PRESSED_REPEAT, () => {
+ let clickBtn = symbolKeyboard.clickedButton()
+ let id = clickBtn.id
+ switch (id) {
+ case 39:
+ // 閫�鏍�
+ pinyin.cb({ cmd: "backspace" })
+ break;
+ }
+ })
+ symbolKeyboard.on(dxui.Utils.ENUM.LV_EVENT_PRESSED, () => {
+ let clickBtn = symbolKeyboard.clickedButton()
+ let id = clickBtn.id
+ let text = clickBtn.text
+ switch (id) {
+ case 31:
+ if (isLock) {
+ break;
+ }
+ // 鍒囨崲鏁板瓧閿洏
+ pinyin.numPanel.show()
+ pinyin.symbolPanel.hide()
+ break;
+ case 39:
+ // 閫�鏍�
+ pinyin.cb({ cmd: "backspace" })
+ break;
+ case 40:
+ if (isLock) {
+ break;
+ }
+ // 鍒囨崲鑻辨枃閿洏
+ pinyin.englishPanel.show()
+ pinyin.symbolPanel.hide()
+ break;
+ case 41:
+ // 绌烘牸
+ pinyin.cb(" ")
+ break;
+ case 42:
+ // 鍥炶溅
+ pinyin.cb({ cmd: "enter" })
+ break;
+ default:
+ break;
+ }
+ // 鎵撳嵃瀛楃
+ if (["^", "\\", "|", "<", ">", "垄", "拢", "鈧�", "楼", "鈧�",
+ "[", "]", "{", "}", "#", "%", "+", "=", "~", "_",
+ "-", "/", ":", ";", "(", ")", "$", "&", "\"",
+ "`", "?", "!", "*", "@", ",", "'"].includes(text)) {
+ pinyin.cb(text)
+ }
+ })
+ symbolPanel.hide()
+ return symbolPanel
+}
+// 娓呴櫎鏍峰紡
+function clearStyle(obj) {
+ obj.radius(0)
+ obj.borderWidth(0)
+ obj.padAll(0)
+}
+export default pinyin
diff --git a/vf205_access/src/view/pwdView.js b/vf205_access/src/view/pwdView.js
new file mode 100644
index 0000000..56c142d
--- /dev/null
+++ b/vf205_access/src/view/pwdView.js
@@ -0,0 +1,72 @@
+import dxui from '../../dxmodules/dxUi.js'
+import std from '../../dxmodules/dxStd.js'
+import viewUtils from "./viewUtils.js"
+import topView from './topView.js'
+import mainView from './mainView.js'
+import i18n from './i18n.js'
+import screen from '../screen.js'
+
+const pwdView = {}
+pwdView.init = function () {
+ /**************************************************鍒涘缓灞忓箷*****************************************************/
+ const screenMain = dxui.View.build('pwdView', dxui.Utils.LAYER.MAIN)
+ pwdView.screenMain = screenMain
+ screenMain.scroll(false)
+ screenMain.bgColor(0xffffff)
+ screenMain.on(dxui.Utils.ENUM.LV_EVENT_SCREEN_LOADED, () => {
+ topView.changeTheme(true)
+
+ const configAll = screen.getConfig()
+ pwdAccessBtn.disable(configAll['sys.pwd'] == 0)
+
+ pwdView.timer = std.setInterval(() => {
+ let count = dxui.Utils.GG.NativeDisp.lvDispGetInactiveTime()
+ if (count > 15 * 1000) {
+ std.clearInterval(pwdView.timer)
+ pwdView.timer = null
+ dxui.loadMain(mainView.screenMain)
+ }
+ }, 1000)
+
+ pwdInput.send(dxui.Utils.EVENT.CLICK)
+ pwdInput.send(dxui.Utils.EVENT.FOCUSED)
+ })
+ screenMain.on(dxui.Utils.ENUM.LV_EVENT_SCREEN_UNLOADED, () => {
+ if (pwdView.timer) {
+ std.clearInterval(pwdView.timer)
+ }
+ })
+
+ const titleBox = viewUtils.title(screenMain, mainView.screenMain, 'pwdViewTitle', 'pwdView.title')
+ titleBox.align(dxui.Utils.ALIGN.TOP_MID, 0, 70)
+
+ const pwdInput = viewUtils.input(screenMain, 'pwdInput', 2, undefined, 'pwdView.pwd')
+ pwdInput.align(dxui.Utils.ALIGN.TOP_MID, 0, 211)
+ pwdInput.setPasswordMode(true)
+
+ const eyeFill = viewUtils.imageBtn(screenMain, screenMain.id + 'eye_fill', '/app/code/resource/image/eye-fill.png')
+ eyeFill.alignTo(pwdInput, dxui.Utils.ALIGN.RIGHT_MID, 0, 0)
+ eyeFill.on(dxui.Utils.EVENT.CLICK, () => {
+ pwdInput.setPasswordMode(true)
+ eyeFill.hide()
+ eyeOff.show()
+ })
+ eyeFill.hide()
+
+ const eyeOff = viewUtils.imageBtn(screenMain, screenMain.id + 'eye_off', '/app/code/resource/image/eye-off.png')
+ eyeOff.alignTo(pwdInput, dxui.Utils.ALIGN.RIGHT_MID, 0, 0)
+ eyeOff.on(dxui.Utils.EVENT.CLICK, () => {
+ pwdInput.setPasswordMode(false)
+ eyeFill.show()
+ eyeOff.hide()
+ })
+
+ const pwdAccessBtn = viewUtils.bottomBtn(screenMain, 'pwdAccessBtn', 'pwdView.pwdAccess', () => {
+ // 纭瀵嗙爜
+ screen.pwdAccess(pwdInput.text())
+ dxui.loadMain(mainView.screenMain)
+ })
+ pwdAccessBtn.align(dxui.Utils.ALIGN.BOTTOM_MID, 0, -83)
+}
+
+export default pwdView
\ No newline at end of file
diff --git a/vf205_access/src/view/topView.js b/vf205_access/src/view/topView.js
new file mode 100644
index 0000000..db0f041
--- /dev/null
+++ b/vf205_access/src/view/topView.js
@@ -0,0 +1,170 @@
+import dxui from '../../dxmodules/dxUi.js'
+import std from '../../dxmodules/dxStd.js'
+import viewUtils from './viewUtils.js'
+import screen from '../screen.js'
+import newPwdView from './config/newPwdView.js'
+import logger from '../../dxmodules/dxLogger.js'
+
+// 涓昏鏄剧ず绯荤粺鏃堕棿鍜岀姸鎬佸浘鏍�
+const topView = {}
+topView.init = function () {
+ const screenMain = dxui.View.build('topView', dxui.Utils.LAYER.TOP)
+ topView.screenMain = screenMain
+ viewUtils._clearStyle(screenMain)
+ screenMain.scroll(false)
+ screenMain.width(screen.screenSize.width)
+ screenMain.height(screen.screenSize.height)
+ screenMain.bgOpa(0)
+ screenMain.clickable(false)
+
+ const topBox = dxui.View.build('topBox', screenMain)
+ viewUtils._clearStyle(topBox)
+ topBox.width(screen.screenSize.width)
+ topBox.height(70)
+ topBox.bgOpa(0)
+ topBox.clickable(false)
+
+ topBox.flexFlow(dxui.Utils.FLEX_FLOW.ROW)
+ topBox.flexAlign(dxui.Utils.FLEX_ALIGN.SPACE_BETWEEN, dxui.Utils.FLEX_ALIGN.CENTER, dxui.Utils.FLEX_ALIGN.CENTER)
+
+ const topBoxLeft = dxui.View.build('topBoxLeft', topBox)
+ viewUtils._clearStyle(topBoxLeft)
+ topBoxLeft.width(400)
+ topBoxLeft.height(70)
+ topBoxLeft.padLeft(38)
+ topBoxLeft.bgOpa(0)
+ topBoxLeft.clickable(false)
+
+ const topBoxRight = dxui.View.build('topBoxRight', topBox)
+ viewUtils._clearStyle(topBoxRight)
+ topBoxRight.width(400)
+ topBoxRight.height(70)
+ topBoxRight.padRight(38)
+ topBoxRight.bgOpa(0)
+ topBoxRight.clickable(false)
+ topBoxRight.flexFlow(dxui.Utils.FLEX_FLOW.ROW)
+ topBoxRight.flexAlign(dxui.Utils.FLEX_ALIGN.END, dxui.Utils.FLEX_ALIGN.CENTER, dxui.Utils.FLEX_ALIGN.CENTER)
+
+ const ethShow = dxui.Image.build('ethShow', topBoxRight)
+ topView.ethShow = ethShow
+ ethShow.source('/app/code/resource/image/ethernet.png')
+ ethShow.clickable(false)
+ ethShow.hide()
+
+ const wifiShow = dxui.Image.build('wifiShow', topBoxRight)
+ topView.wifiShow = wifiShow
+ wifiShow.source('/app/code/resource/image/wifi.png')
+ wifiShow.clickable(false)
+ wifiShow.hide()
+
+ const _4gShow = dxui.Image.build('4gShow', topBoxRight)
+ topView._4gShow = _4gShow
+ _4gShow.source('/app/code/resource/image/4g.png')
+ _4gShow.clickable(false)
+ _4gShow.hide()
+
+ const mqttShow = dxui.Image.build('mqttShow', topBoxRight)
+ topView.mqttShow = mqttShow
+ mqttShow.source('/app/code/resource/image/mqtt.png')
+ mqttShow.clickable(false)
+ mqttShow.hide()
+
+ // 娣诲姞闀挎寜杩涘叆绠$悊椤甸潰鐨勫尯鍩�
+ const adminArea = dxui.View.build('adminArea', screenMain)
+ viewUtils._clearStyle(adminArea)
+ adminArea.setSize(120, 120)
+ adminArea.align(dxui.Utils.ALIGN.TOP_RIGHT, 0, 0)
+ adminArea.bgOpa(0)
+ adminArea.clickable(true)
+
+ logger.info('[topView]: 闀挎寜鍖哄煙宸插垱寤猴紝浣嶇疆锛氬彸涓婅')
+
+ let pressStartTime = 0
+ let isPressing = false
+ let longPressTimer = null
+
+ // 浣跨敤PRESSING浜嬩欢妫�娴嬫寜浣忕姸鎬�
+ adminArea.on(dxui.Utils.EVENT.PRESSING, () => {
+ if (!isPressing) {
+ // 绗竴娆℃娴嬪埌鎸変綇
+ isPressing = true
+ pressStartTime = Date.now()
+ logger.info('[topView]: 寮�濮嬫寜浣�')
+
+ // 鍚姩闀挎寜璁℃椂鍣�
+ longPressTimer = std.setTimeout(() => {
+ const pressDuration = Date.now() - pressStartTime
+ logger.info(`[topView]: 鎸変綇涓嶆斁${pressDuration}ms鎴愬姛锛岃繘鍏ョ鐞嗛〉闈)
+ dxui.loadMain(newPwdView.screenMain)
+ longPressTimer = null
+ }, 3000)
+ }
+ })
+
+ // 浣跨敤CLICK浜嬩欢妫�娴嬮噴鏀撅紙褰撶敤鎴烽噴鏀炬椂锛孭RESSING浜嬩欢浼氬仠姝級
+ adminArea.on(dxui.Utils.EVENT.CLICK, () => {
+ if (isPressing) {
+ const pressDuration = Date.now() - pressStartTime
+ logger.info(`[topView]: 鎸変綇鏃堕棿${pressDuration}ms锛岄噴鏀綻)
+
+ // 娓呴櫎璁℃椂鍣�
+ if (longPressTimer) {
+ std.clearTimeout(longPressTimer)
+ longPressTimer = null
+ }
+
+ isPressing = false
+ } else {
+ logger.info('[topView]: 闀挎寜鍖哄煙妫�娴嬪埌鐐瑰嚮浜嬩欢')
+ }
+ })
+
+}
+
+// 鍒囨崲涓婚锛屼袱濂楀浘鏍囷紝涓�濂楃櫧鑹诧紝涓�濂楅粦鑹�
+topView.changeTheme = function (dark) {
+ if (dark) {
+ topView.ethShow.source('/app/code/resource/image/ethernet_dark.png')
+ topView.mqttShow.source('/app/code/resource/image/mqtt_dark.png')
+ topView.wifiShow.source('/app/code/resource/image/wifi_dark.png')
+ topView._4gShow.source('/app/code/resource/image/4g_dark.png')
+ } else {
+ topView.ethShow.source('/app/code/resource/image/ethernet.png')
+ topView.mqttShow.source('/app/code/resource/image/mqtt.png')
+ topView.wifiShow.source('/app/code/resource/image/wifi.png')
+ topView._4gShow.source('/app/code/resource/image/4g.png')
+ }
+}
+
+// mqtt杩炴帴鐘舵��
+topView.mqttConnectState = function (connected) {
+ if (connected) {
+ topView.mqttShow.show()
+ } else {
+ topView.mqttShow.hide()
+ }
+}
+
+// eth杩炴帴鐘舵��
+topView.ethConnectState = function (connected, type) {
+ if (connected) {
+ if (type == 1) {
+ topView.ethShow.show()
+ topView.wifiShow.hide()
+ topView._4gShow.hide()
+ } else if (type == 2) {
+ topView.wifiShow.show()
+ topView.ethShow.hide()
+ topView._4gShow.hide()
+ } else if (type == 4) {
+ topView._4gShow.show()
+ topView.ethShow.hide()
+ topView.wifiShow.hide()
+ }
+ } else {
+ topView.ethShow.hide()
+ topView.wifiShow.hide()
+ topView._4gShow.hide()
+ }
+}
+export default topView
diff --git a/vf205_access/src/view/viewUtils.js b/vf205_access/src/view/viewUtils.js
new file mode 100644
index 0000000..9d3c90d
--- /dev/null
+++ b/vf205_access/src/view/viewUtils.js
@@ -0,0 +1,475 @@
+import * as os from "os"
+import dxui from '../../dxmodules/dxUi.js'
+import dxMap from '../../dxmodules/dxMap.js'
+import screen from '../screen.js'
+import pinyin from './pinyin/pinyin.js'
+// import utils from "../common/utils/utils.js"
+import i18n from "./i18n.js"
+import std from '../../dxmodules/dxStd.js'
+
+const viewUtils = {}
+
+viewUtils.font = function (size, style) {
+ return dxui.Font.build('/app/code/resource/font/AlibabaPuHuiTi-2-65-Medium.ttf', size || 14, style || dxui.Utils.FONT_STYLE.NORMAL)
+}
+
+// 璇箟鍖栭鑹�
+viewUtils.color = {
+ // 鎴愬姛锛岀豢鑹�
+ success: 0x00BF8A,
+ // 澶辫触锛岀孩鑹�
+ fail: 0xFF0000,
+ // 璀﹀憡锛岄粍鑹�
+ warning: 0xFFA800,
+ // 榛樿锛氳摑鑹�
+ default: 0x00a8ff
+}
+
+// 娓呴櫎鏍峰紡
+viewUtils._clearStyle = function (obj) {
+ obj.radius(0)
+ obj.borderWidth(0)
+ obj.padAll(0)
+}
+
+// 鍥剧墖鎸夐挳灏佽锛屾寜閽牴鎹浘鐗囧ぇ灏忚缃紝鐭╁舰
+viewUtils.imageBtn = function (parent, id, src, dataI18n, textColor) {
+ const zoom = 1.02
+
+ const imageBox = dxui.View.build(id, parent)
+ viewUtils._clearStyle(imageBox)
+ imageBox.bgOpa(0)
+
+ const image = dxui.Image.build(id + 'image', imageBox)
+ image.source(src)
+ image.update()
+ const width = image.width()
+ const height = image.height()
+ imageBox.setSize(width * zoom + 5, height * zoom + 5)
+ imageBox.scroll(false)
+ image.align(dxui.Utils.ALIGN.CENTER, 0, 0)
+
+ if (dataI18n) {
+ const textLbl = dxui.Label.build(id + 'text', image)
+ textLbl.textFont(viewUtils.font(Math.round(height / 3)))
+ if (textColor !== undefined && textColor !== null) {
+ textLbl.textColor(textColor)
+ } else {
+ textLbl.textColor(0xffffff)
+ }
+ textLbl.align(dxui.Utils.ALIGN.CENTER, 0, 0)
+ textLbl.dataI18n = dataI18n
+ }
+
+ imageBox.on(dxui.Utils.ENUM.LV_EVENT_PRESSED, () => {
+ image.obj.lvImgSetZoom(256 * zoom)
+ })
+
+ imageBox.on(dxui.Utils.ENUM.LV_EVENT_RELEASED, () => {
+ image.obj.lvImgSetZoom(256)
+ })
+
+ return imageBox
+}
+
+// 鍒涘缓鏍囬鏍�
+viewUtils.title = function (parent, backScreen, id, dataI18n, backCb) {
+ const titleBox = dxui.View.build(id, parent)
+ viewUtils._clearStyle(titleBox)
+ titleBox.setSize(800, 70)
+ titleBox.bgColor(0xffffff)
+
+ if (dataI18n) {
+ const titleLbl = dxui.Label.build(id + 'title', titleBox)
+ titleLbl.textFont(viewUtils.font(32))
+ titleLbl.align(dxui.Utils.ALIGN.CENTER, 0, 0)
+ titleLbl.dataI18n = dataI18n
+ }
+
+ const back = viewUtils.imageBtn(titleBox, id + 'back', '/app/code/resource/image/back.png')
+ back.setSize(80, 70)
+ back.align(dxui.Utils.ALIGN.LEFT_MID, 0, 0)
+
+ back.on(dxui.Utils.EVENT.CLICK, () => {
+ if (backScreen) {
+ dxui.loadMain(backScreen)
+ }
+ if (backCb) {
+ backCb()
+ }
+ })
+
+ return titleBox
+}
+
+// 杈撳叆妗�
+viewUtils.input = function (parent, id, mode, enter = () => { }, dataI18n) {
+ const input = dxui.Textarea.build(id + 'input', parent)
+ viewUtils._clearStyle(input)
+ input.align(dxui.Utils.ALIGN.TOP_MID, 0, 100)
+ input.textAlign(dxui.Utils.TEXT_ALIGN.LEFT_MID)
+ input.setOneLine(true)
+ input.borderWidth(2)
+ input.setBorderColor(0xE7E7E7)
+ const font = viewUtils.font(26)
+ const superSetSize = input.setSize
+ input.setSize = (width, height) => {
+ superSetSize.call(input, width, height)
+ input.padAll((height - 4 - font.obj.lvFontGetLineHeight()) / 2)
+ input.padLeft(30)
+ input.padRight(30)
+ }
+ input.setSize(650, 100)
+ input.radius(13)
+ input.textFont(font)
+ if (dataI18n) {
+ // 鍙湁鍦╠xui.all涓紝鎵嶈兘浣跨敤dataI18n
+ dxui.all[id + 'input' + 'obj'] = input.obj
+ input.obj.dataI18n = dataI18n
+ input.obj.text = (text) => {
+ input.obj.lvTextareaSetPlaceholderText(text)
+ }
+ }
+
+ input.on(dxui.Utils.EVENT.CLICK, () => {
+ input.setBorderColor(0x3670f7)
+ pinyin.show(mode || pinyin.getMode(), (data) => {
+ if (typeof data == 'string') {
+ input.lvTextareaAddText(data)
+ } else if (typeof data == 'object') {
+ switch (data.cmd) {
+ case 'enter':
+ enter()
+ pinyin.hide()
+ break
+ case 'backspace':
+ input.lvTextareaDelChar()
+ break
+ }
+ }
+ })
+ if (mode) {
+ pinyin.lock()
+ }
+ })
+ input.on(dxui.Utils.EVENT.DEFOCUSED, () => {
+ dxMap.get("INPUT_KEYBOARD").put("defocus", "defocus")
+ })
+
+ let root = parent
+ let rootId = parent.id
+ while ((rootId = dxui.all[rootId].parent) != "0") {
+ root = dxui.all[rootId]
+ }
+
+ root.on(dxui.Utils.EVENT.CLICK, () => {
+ input.setBorderColor(0xE7E7E7)
+ // pinyin.hide()
+ })
+
+ root.on(dxui.Utils.ENUM.LV_EVENT_SCREEN_UNLOADED, () => {
+ input.setBorderColor(0xE7E7E7)
+ // pinyin.hide()
+ input.text('')
+ })
+ return input
+}
+
+// 纭寮圭獥
+viewUtils.confirmInit = function () {
+ const confirm = dxui.View.build('confirm', dxui.Utils.LAYER.TOP)
+ viewUtils._clearStyle(confirm)
+ confirm.setSize(screen.screenSize.width, screen.screenSize.height)
+ confirm.bgColor(0x0)
+ confirm.bgOpa(50)
+ confirm.hide()
+
+ const box = dxui.View.build('confirmBox', confirm)
+ viewUtils._clearStyle(box)
+ box.setSize(500, 300)
+ box.radius(20)
+ box.align(dxui.Utils.ALIGN.CENTER, 0, 0)
+ box.bgColor(0xffffff)
+
+ const title = dxui.Label.build('confirmTitle', box)
+ title.align(dxui.Utils.ALIGN.TOP_MID, 0, 22)
+ title.textFont(viewUtils.font(30))
+ title.text("Confirm")
+
+ const close = viewUtils.imageBtn(box, 'confirmClose', '/app/code/resource/image/close_small.png')
+ close.align(dxui.Utils.ALIGN.TOP_RIGHT, -28, 18)
+
+ const content = dxui.Label.build('confirmContent', box)
+ content.align(dxui.Utils.ALIGN.TOP_MID, 0, 114)
+ content.textFont(viewUtils.font(24))
+ content.textColor(0x767676)
+ content.text("Are you sure you want to exit?")
+ content.textAlign(dxui.Utils.TEXT_ALIGN.CENTER)
+
+ const ok = dxui.Button.build('okBtn', box)
+ ok.align(dxui.Utils.ALIGN.BOTTOM_LEFT, 69, -31)
+ ok.bgColor(0x0)
+ ok.radius(10)
+ ok.setSize(150, 50)
+ const okLbl = dxui.Label.build('okLbl', ok)
+ okLbl.textFont(viewUtils.font(26))
+ okLbl.dataI18n = 'confirm.ok'
+ okLbl.textColor(0xffffff)
+ okLbl.align(dxui.Utils.ALIGN.CENTER, 0, 0)
+ ok.on(dxui.Utils.EVENT.CLICK, () => {
+ confirm.hide()
+ if (typeof viewUtils.confirm.okFunc == 'function') {
+ viewUtils.confirm.okFunc()
+ }
+ })
+
+ const no = dxui.Button.build('noBtn', box)
+ no.align(dxui.Utils.ALIGN.BOTTOM_RIGHT, -69, -31)
+ no.bgColor(0xF3F3F3)
+ no.radius(10)
+ no.setSize(150, 50)
+ const noLbl = dxui.Label.build('noLbl', no)
+ noLbl.textFont(viewUtils.font(26))
+ noLbl.dataI18n = 'confirm.no'
+ noLbl.align(dxui.Utils.ALIGN.CENTER, 0, 0)
+ noLbl.textColor(0x0)
+ no.on(dxui.Utils.EVENT.CLICK, () => {
+ confirm.hide()
+ })
+
+ close.on(dxui.Utils.EVENT.CLICK, () => {
+ confirm.hide()
+ if (typeof viewUtils.confirm.noFunc == 'function') {
+ viewUtils.confirm.noFunc()
+ }
+ })
+ viewUtils.confirm = { confirm, box, title, close, content, ok, no, okLbl, noLbl }
+}
+
+viewUtils.confirmClose = function () {
+ viewUtils.confirm.confirm.hide()
+}
+
+viewUtils.confirmOpen = function (title, content, ok, no) {
+ viewUtils.confirm.confirm.moveForeground()
+ viewUtils.confirm.title.dataI18n = title
+ viewUtils.confirm.content.dataI18n = content
+ if (ok) {
+ viewUtils.confirm.ok.show()
+ viewUtils.confirm.okFunc = ok
+ } else {
+ viewUtils.confirm.ok.hide()
+ }
+ if (no) {
+ viewUtils.confirm.no.show()
+ viewUtils.confirm.noFunc = no
+ } else {
+ viewUtils.confirm.no.hide()
+ }
+ viewUtils.confirm.confirm.show()
+ i18n.refreshObj(viewUtils.confirm.title)
+ i18n.refreshObj(viewUtils.confirm.content)
+ viewUtils.confirm.content.update()
+ viewUtils.confirm.box.height(viewUtils.confirm.content.height() + 257)
+}
+
+
+viewUtils.bottomBtn = function (parent, id, dataI18n, click, btnColor = 0x000000, textColor = 0xffffff, fontSize = 28) {
+ const btn = dxui.Button.build(id, parent)
+ btn.align(dxui.Utils.ALIGN.BOTTOM_MID, 0, -124)
+ btn.bgColor(btnColor)
+ btn.setSize(620, 100)
+ btn.radius(60)
+ const btnLbl = dxui.Label.build(id + 'lbl', btn)
+ btnLbl.dataI18n = dataI18n
+ btnLbl.textFont(viewUtils.font(fontSize))
+ btnLbl.textColor(textColor)
+ btnLbl.align(dxui.Utils.ALIGN.CENTER, 0, 0)
+ btn.on(dxui.Utils.EVENT.CLICK, click)
+ return btn
+}
+
+// 寰幆婊氬姩
+viewUtils.cycleList = function (parent, id, size, maxNum, template = () => { }, update = () => { }) {
+ const cycleList = dxui.View.build(id, parent)
+ viewUtils._clearStyle(cycleList)
+ cycleList.setSize(size[0], size[1])
+ cycleList.cycleList = []
+ cycleList.cycleIndex = 0
+ for (let i = -1; i < (maxNum + 1); i++) {
+ const cycleItem = dxui.View.build(id + 'item' + i, cycleList)
+ viewUtils._clearStyle(cycleItem)
+ cycleItem.setSize(size[0], size[1] / maxNum)
+ cycleItem.bgOpa(0)
+ cycleItem.borderWidth(1)
+ cycleItem.setBorderColor(0xDEDEDE)
+ cycleItem.obj.setStyleBorderSide(dxui.Utils.ENUM.LV_BORDER_SIDE_BOTTOM, 0)
+ cycleItem.userdata = template(cycleItem)
+ cycleList.cycleIndex = i
+ update(cycleItem.userdata, i)
+ if (cycleList.cycleList.length > 0) {
+ cycleItem.alignTo(cycleList.cycleList[cycleList.cycleList.length - 1], dxui.Utils.ALIGN.OUT_BOTTOM_MID, 0, 0)
+ } else {
+ cycleItem.align(dxui.Utils.ALIGN.TOP_MID, 0, 0)
+ }
+ cycleList.cycleList.push(cycleItem)
+ }
+ cycleList.scrollToY(size[1] / maxNum, false)
+
+ cycleList.on(dxui.Utils.ENUM.LV_EVENT_SCROLL, () => {
+ if (cycleList.scrollTop() >= size[1] / maxNum * 2) {
+ const cycleItem = cycleList.cycleList.shift()
+ cycleList.cycleList.push(cycleItem)
+ for (let i = 0; i < cycleList.cycleList.length; i++) {
+ const item = cycleList.cycleList[i]
+ if (i == 0) {
+ item.align(dxui.Utils.ALIGN.TOP_MID, 0, 0)
+ } else {
+ item.alignTo(cycleList.cycleList[i - 1], dxui.Utils.ALIGN.OUT_BOTTOM_MID, 0, 0)
+ }
+ }
+ cycleList.cycleIndex += 1
+ update(cycleItem.userdata, cycleList.cycleIndex)
+ cycleList.scrollToY(size[1] / maxNum, false)
+ } else if (cycleList.scrollTop() <= 0) {
+ const cycleItem = cycleList.cycleList.pop()
+ cycleList.cycleList.unshift(cycleItem)
+ for (let i = 0; i < cycleList.cycleList.length; i++) {
+ const item = cycleList.cycleList[i]
+ if (i == 0) {
+ item.align(dxui.Utils.ALIGN.TOP_MID, 0, 0)
+ } else {
+ item.alignTo(cycleList.cycleList[i - 1], dxui.Utils.ALIGN.OUT_BOTTOM_MID, 0, 0)
+ }
+ }
+ cycleList.cycleIndex -= 1
+ update(cycleItem.userdata, cycleList.cycleIndex)
+ cycleList.scrollToY(size[1] / maxNum, false)
+ }
+ })
+ cycleList.refresh = () => {
+ cycleList.cycleList.forEach((item, index) => {
+ update(item.userdata, index)
+ })
+ }
+ return cycleList
+}
+
+viewUtils.statusPanel = function (parent, successI18n, failI18n) {
+ const successBg = dxui.Image.build(parent.id + 'successBg', parent)
+ successBg.source('/app/code/resource/image/successBg.png')
+ successBg.align(dxui.Utils.ALIGN.BOTTOM_MID, 0, 0)
+ successBg.hide()
+
+ const successIcon = dxui.Image.build(parent.id + 'successIcon', successBg)
+ successIcon.source('/app/code/resource/image/success_fill.png')
+ successIcon.align(dxui.Utils.ALIGN.CENTER, 0, 0)
+
+ const successLbl = dxui.Label.build(parent.id + 'successLbl', successBg)
+ successLbl.textFont(viewUtils.font(38))
+ successLbl.textColor(0xffffff)
+ successLbl.dataI18n = successI18n
+ successLbl.textAlign(dxui.Utils.TEXT_ALIGN.CENTER)
+ successLbl.align(dxui.Utils.ALIGN.TOP_MID, 0, 244)
+
+ const failBg = dxui.Image.build(parent.id + 'failBg', parent)
+ failBg.source('/app/code/resource/image/failBg.png')
+ failBg.align(dxui.Utils.ALIGN.BOTTOM_MID, 0, 0)
+ failBg.hide()
+
+ const failIcon = dxui.Image.build(parent.id + 'failIcon', failBg)
+ failIcon.source('/app/code/resource/image/delete_fill.png')
+ failIcon.align(dxui.Utils.ALIGN.CENTER, 0, 0)
+
+ const failLbl = dxui.Label.build(parent.id + 'failLbl', failBg)
+ failLbl.textFont(viewUtils.font(38))
+ failLbl.textColor(0xffffff)
+ failLbl.dataI18n = failI18n
+ failLbl.textAlign(dxui.Utils.TEXT_ALIGN.CENTER)
+ failLbl.align(dxui.Utils.ALIGN.TOP_MID, 0, 244)
+
+ return {
+ success: (dataI18n) => {
+ if (dataI18n) {
+ successLbl.dataI18n = dataI18n
+ i18n.refreshObj(successLbl)
+ }
+ successBg.show()
+ failBg.hide()
+ std.setTimeout(() => {
+ successBg.hide()
+ }, 3000)
+ },
+ fail: (dataI18n) => {
+ if (dataI18n) {
+ failLbl.dataI18n = dataI18n
+ i18n.refreshObj(failLbl)
+ }
+ failBg.show()
+ successBg.hide()
+ std.setTimeout(() => {
+ failBg.hide()
+ }, 3000)
+ },
+ successBg: successBg,
+ failBg: failBg
+ }
+}
+
+// 鏂板寮圭獥甯冨眬 - 灏忓瀷鐘舵�侀潰鏉�
+viewUtils.smallStatusPanel = function (parent, successI18n, failI18n) {
+ const successBg = dxui.Image.build(parent.id + 'smallSuccessBg', parent)
+ successBg.source('/app/code/resource/image/view_s.png') // 鎴愬姛鑳屾櫙鍥�
+ successBg.setSize(499, 97) // 璁剧疆灏哄
+ successBg.align(dxui.Utils.ALIGN.BOTTOM_MID, 0, 0)
+ successBg.hide()
+
+ const successLbl = dxui.Label.build(parent.id + 'smallSuccessLbl', successBg)
+ successLbl.textFont(viewUtils.font(24, dxui.Utils.FONT_STYLE.BOLD))
+ successLbl.textColor(0xffffff)
+ successLbl.dataI18n = successI18n
+ successLbl.textAlign(dxui.Utils.TEXT_ALIGN.CENTER)
+ successLbl.align(dxui.Utils.ALIGN.CENTER, 0, 0)
+
+ const failBg = dxui.Image.build(parent.id + 'smallFailBg', parent)
+ failBg.source('/app/code/resource/image/view_f.png') // 澶辫触鑳屾櫙鍥�
+ failBg.setSize(499, 97) // 璁剧疆灏哄
+ failBg.align(dxui.Utils.ALIGN.BOTTOM_MID, 0, 0)
+ failBg.hide()
+
+ const failLbl = dxui.Label.build(parent.id + 'smallFailLbl', failBg)
+ failLbl.textFont(viewUtils.font(24, dxui.Utils.FONT_STYLE.BOLD))
+ failLbl.textColor(0xffffff)
+ failLbl.dataI18n = failI18n
+ failLbl.textAlign(dxui.Utils.TEXT_ALIGN.CENTER)
+ failLbl.align(dxui.Utils.ALIGN.CENTER, 0, 0)
+
+ return {
+ success: (dataI18n) => {
+ if (dataI18n) {
+ successLbl.dataI18n = dataI18n
+ i18n.refreshObj(successLbl)
+ }
+ successBg.show()
+ failBg.hide()
+ std.setTimeout(() => {
+ successBg.hide()
+ }, 3000)
+ },
+ fail: (dataI18n) => {
+ if (dataI18n) {
+ failLbl.dataI18n = dataI18n
+ i18n.refreshObj(failLbl)
+ }
+ failBg.show()
+ successBg.hide()
+ std.setTimeout(() => {
+ failBg.hide()
+ }, 3000)
+ },
+ successBg: successBg,
+ failBg: failBg
+ }
+}
+
+export default viewUtils
\ No newline at end of file
--
Gitblit v1.9.3