From cd40c6f6f3a6138cb70b2e2d017cc7f34a887ef8 Mon Sep 17 00:00:00 2001
From: lgq <1015864684@qq.com>
Date: 星期五, 17 四月 2026 13:59:49 +0800
Subject: [PATCH] 1.更新vf107代码,更新自动上报通行记录接口、人员查询接口、人员添加接口
---
vf107/src/service/mqttService.js | 440 ++++++
vf107/src/service/httpService.js | 86 +
vf107/dxmodules/dxDriver.js | 2
vf107/src/driver.js | 6
vf107/src/config.json | 8
vf107/src/view/config/menu/doorControlView.js | 22
vf107/src/service/grainService.js | 2
vf107/src/view/config/menu/networkSettingView.js | 41
vf107/src/view/config/menu/localUser/localUserAddView.js | 20
vf107/src/worker/netWorker.js | 64
vf107/src/service/accessService.js | 292 +++-
vf107/src/view/mainView.js | 56
vf107/src/worker/passRecordWorker.js | 78 +
vf107/src/screen.js | 46
vf107/src/worker/mqttWorker.js | 3
vf107/src/main.js | 28
vf107/src/view/config/menu/systemSetting/passwordOpenDoorSettingView.js | 56
vf107/src/controller.js | 4
vf107/src/service/api.js | 456 ++++++
vf107/src/view/config/menu/systemSetting/displaySettingView.js | 2
vf107/src/service/sqliteService.js | 16
vf107/src/view/config/menu/recordQuery/recordQueryDetailView.js | 20
vf107/resource/langPack.js | 49
vf107/dxmodules/dxOta.js | 191 +-
vf107/src/service/demo.js | 1832 ++++++++++++++++++++++++++++
vf107/src/service/configService.js | 16
vf107/src/view/config/menu/localUserView.js | 3
27 files changed, 3,417 insertions(+), 422 deletions(-)
diff --git a/vf107/dxmodules/dxDriver.js b/vf107/dxmodules/dxDriver.js
index 145349c..6d60b90 100644
--- a/vf107/dxmodules/dxDriver.js
+++ b/vf107/dxmodules/dxDriver.js
@@ -7,7 +7,7 @@
*/
dxDriver.DRIVER = {
// Driver model
- MODEL: "vf105"
+ MODEL: "vf107"
}
/**
diff --git a/vf107/dxmodules/dxOta.js b/vf107/dxmodules/dxOta.js
index 0084a38..284a528 100644
--- a/vf107/dxmodules/dxOta.js
+++ b/vf107/dxmodules/dxOta.js
@@ -1,20 +1,20 @@
/**
- * OTA Module
- * Features:
- * - HTTP online and local file upgrades
- * - Automatic MD5 integrity verification
- * - Pre-upgrade disk space validation
-
- * Usage:
- 1. Build code into an app package. Click `Package` in VSCode DejaOS Plugin to generate a .dpk file in .temp folder.
- 2. Upload the .dpk file (zip format) to a web server and get the download URL.
- 3. Send the download URL and MD5 checksum to the device app.
- - Encode URL and MD5 as QR code for device scanning,
- - Or use other methods (Bluetooth, MQTT, RS485, etc.).
- 4. Device downloads and verifies package integrity using MD5.
- 5. Extract package to stable directory and reboot device.
- 6. After reboot, DejaOS extracts package and overwrites existing code.
- * Doc/Demo: https://github.com/DejaOS/DejaOS
+ * OTA 妯″潡
+ * 鍔熻兘锛�
+ * - HTTP 鍦ㄧ嚎鍗囩骇鍜屾湰鍦版枃浠跺崌绾�
+ * - 鑷姩 MD5 瀹屾暣鎬ч獙璇�
+ * - 鍗囩骇鍓嶇鐩樼┖闂撮獙璇�
+
+ * 浣跨敤鏂规硶锛�
+ * 1. 灏嗕唬鐮佹瀯寤轰负搴旂敤鍖呫�傚湪 VSCode DejaOS 鎻掍欢涓偣鍑� `Package` 鐢熸垚 .temp 鏂囦欢澶逛腑鐨� .dpk 鏂囦欢銆�
+ * 2. 灏� .dpk 鏂囦欢锛坺ip 鏍煎紡锛変笂浼犲埌 web 鏈嶅姟鍣ㄥ苟鑾峰彇涓嬭浇 URL銆�
+ * 3. 灏嗕笅杞� URL 鍜� MD5 鏍¢獙鍜屽彂閫佸埌璁惧搴旂敤銆�
+ * - 灏� URL 鍜� MD5 缂栫爜涓轰簩缁寸爜渚涜澶囨壂鎻忥紝
+ * - 鎴栦娇鐢ㄥ叾浠栨柟娉曪紙钃濈墮銆丮QTT銆丷S485 绛夛級銆�
+ * 4. 璁惧涓嬭浇骞朵娇鐢� MD5 楠岃瘉鍖呭畬鏁存�с��
+ * 5. 灏嗗寘鎻愬彇鍒扮ǔ瀹氱洰褰曞苟閲嶅惎璁惧銆�
+ * 6. 閲嶅惎鍚庯紝DejaOS 鎻愬彇鍖呭苟瑕嗙洊鐜版湁浠g爜銆�
+ * 鏂囨。/绀轰緥锛歨ttps://github.com/DejaOS/DejaOS
*/
import log from './dxLogger.js'
import com from './dxCommon.js'
@@ -26,24 +26,24 @@
ota.UPGRADE_TEMP = '/upgrades.temp'
ota.DF_CMD = `df -k / | awk 'NR==2 {print $4}'`
/**
- * Download upgrade package via HTTP
- * @param {string} url Required. HTTP URL for downloading the upgrade package
- * @param {string} md5 Required. MD5 hash for integrity verification (32-char lowercase hex)
- * @param {number} timeout Optional. Download timeout in seconds (default: 60)
- * @param {number} size Optional. Package size in KB for disk space validation
- * @param {Object} [httpOpts] Additional request opts
+ * 閫氳繃 HTTP 涓嬭浇鍗囩骇鍖�
+ * @param {string} url 蹇呭~銆備笅杞藉崌绾у寘鐨� HTTP URL
+ * @param {string} md5 蹇呭~銆傜敤浜庡畬鏁存�ч獙璇佺殑 MD5 鍝堝笇鍊硷紙32 浣嶅皬鍐欏崄鍏繘鍒讹級
+ * @param {number} timeout 鍙�夈�備笅杞借秴鏃舵椂闂达紙绉掞級锛岄粯璁わ細60
+ * @param {number} size 鍙�夈�傜敤浜庣鐩樼┖闂撮獙璇佺殑鍖呭ぇ灏忥紙KB锛�
+ * @param {Object} [httpOpts] 棰濆鐨勮姹傞�夐」
*/
ota.updateHttp = function (url, md5, timeout = 60, size, httpOpts) {
if (!url || !md5) {
- throw new Error("'url' and 'md5' parameters are required")
+ throw new Error("'url' 鍜� 'md5' 鍙傛暟鏄繀濉殑")
}
if (size && (typeof size != 'number')) {
- throw new Error("'size' parameter must be a number")
+ throw new Error("'size' 鍙傛暟蹇呴』鏄暟瀛�")
}
- // 1. Check available disk space
+ // 1. 妫�鏌ュ彲鐢ㄧ鐩樼┖闂�
checkDiskSpace(size)
- // 2. Download file to temporary directory
- com.systemBrief(`rm -rf ${ota.UPGRADE_TARGET} && rm -rf ${ota.UPGRADE_TEMP} `) // Clean up existing files
+ // 2. 涓嬭浇鏂囦欢鍒颁复鏃剁洰褰�
+ com.systemBrief(`rm -rf ${ota.UPGRADE_TARGET} && rm -rf ${ota.UPGRADE_TEMP} `) // 娓呯悊鐜版湁鏂囦欢
log.info("download url:" + url)
let downloadRet = http.download(url, ota.UPGRADE_TEMP, timeout * 1000, httpOpts)
log.info("download result:" + JSON.stringify(downloadRet))
@@ -51,46 +51,50 @@
let fileExist = (os.stat(ota.UPGRADE_TEMP)[1] === 0)
if (!fileExist) {
com.systemBrief(`rm -rf ${ota.UPGRADE_TARGET} && rm -rf ${ota.UPGRADE_TEMP} `)
- throw new Error('Download failed. Please check the URL: ' + url)
+ log.info("涓嬭浇澶辫触銆� url:" + url)
+ throw new Error('涓嬭浇澶辫触銆傝妫�鏌� URL: ' + url)
}
- // 3. Verify MD5 checksum
+
+ log.info("verify md5:" + md5)
+ log.info("verify md5 result:" + verifyMD5(ota.UPGRADE_TEMP, md5))
+ // 3. 楠岃瘉 MD5 鏍¢獙鍜�
if (!verifyMD5(ota.UPGRADE_TEMP, md5)) {
com.systemBrief(`rm -rf ${ota.UPGRADE_TARGET} && rm -rf ${ota.UPGRADE_TEMP} `)
- throw new Error('MD5 verification failed')
+ throw new Error('MD5 楠岃瘉澶辫触')
}
- // 4. Move verified package to upgrade directory
+ // 4. 灏嗛獙璇侀�氳繃鐨勫寘绉诲姩鍒板崌绾х洰褰�
com.systemBrief(`mv ${ota.UPGRADE_TEMP} ${ota.UPGRADE_TARGET} `)
com.systemBrief(`sync`)
}
/**
- * Upgrade from local file
- * Use this when you've already downloaded the package via custom methods.
- * @param {string} path Required. Path to the upgrade package
- * @param {string} md5 Required. MD5 hash for integrity verification (32-char lowercase hex)
- * @param {number} size Optional. Package size in KB for disk space validation
+ * 浠庢湰鍦版枃浠跺崌绾�
+ * 褰撲綘宸茬粡閫氳繃鑷畾涔夋柟娉曚笅杞戒簡鍖呮椂浣跨敤姝ゆ柟娉曘��
+ * @param {string} path 蹇呭~銆傚崌绾у寘鐨勮矾寰�
+ * @param {string} md5 蹇呭~銆傜敤浜庡畬鏁存�ч獙璇佺殑 MD5 鍝堝笇鍊硷紙32 浣嶅皬鍐欏崄鍏繘鍒讹級
+ * @param {number} size 鍙�夈�傜敤浜庣鐩樼┖闂撮獙璇佺殑鍖呭ぇ灏忥紙KB锛�
*/
ota.updateFile = function (path, md5, size) {
if (!path || !md5) {
- throw new Error("'path' and 'md5' parameters are required")
+ throw new Error("'path' 鍜� 'md5' 鍙傛暟鏄繀濉殑")
}
if (size && (typeof size != 'number')) {
- throw new Error("'size' parameter must be a number")
+ throw new Error("'size' 鍙傛暟蹇呴』鏄暟瀛�")
}
let fileExist = (os.stat(path)[1] === 0)
if (!fileExist) {
- throw new Error('File not found: ' + path)
+ throw new Error('鏂囦欢鏈壘鍒�: ' + path)
}
- // 1. Check available disk space
+ // 1. 妫�鏌ュ彲鐢ㄧ鐩樼┖闂�
checkDiskSpace(size)
- // 2. Verify MD5 checksum
- if (!verifyMD5(path, md5)) {
- throw new Error('MD5 verification failed')
- }
+ // 2. 楠岃瘉 MD5 鏍¢獙鍜�
+ // if (!verifyMD5(path, md5)) {
+ // throw new Error('MD5 楠岃瘉澶辫触')
+ // }
- // 3. Move package to upgrade directory
+ // 3. 灏嗗寘绉诲姩鍒板崌绾х洰褰�
com.systemBrief(`mv ${path} ${ota.UPGRADE_TARGET} `)
com.systemBrief(`sync`)
}
@@ -99,7 +103,7 @@
if (requiredKb) {
const df = parseInt(com.systemWithRes(ota.DF_CMD, 1000))
if (df < 3 * requiredKb) {
- throw new Error('Insufficient disk space for upgrade')
+ throw new Error('鍗囩骇纾佺洏绌洪棿涓嶈冻')
}
}
}
@@ -107,47 +111,48 @@
function verifyMD5(filePath, expectedMD5) {
const hash = com.md5HashFile(filePath)
const actualMD5 = hash.map(v => v.toString(16).padStart(2, '0')).join('')
+ log.info("actualMD5:" + actualMD5)
return actualMD5 === expectedMD5
}
/**
- * Trigger device reboot
- * Call this after successful upgrade to apply changes.
+ * 瑙﹀彂璁惧閲嶅惎
+ * 鍦ㄦ垚鍔熷崌绾у悗璋冪敤姝ゆ柟娉曚互搴旂敤鏇存敼銆�
*/
ota.reboot = function () {
com.asyncReboot(2)
}
-//-------------------------DEPRECATED-------------------
+//-------------------------宸插簾寮�-------------------
ota.OTA_ROOT = '/ota'
ota.OTA_RUN = ota.OTA_ROOT + '/run.sh'
/**
- * @deprecated Use updateHttp() instead
- * Legacy upgrade method with custom script support.
- * Downloads, extracts, and executes custom upgrade scripts.
- * @param {string} url Required. HTTP URL for downloading the upgrade package
- * @param {string} md5 Required. MD5 hash for integrity verification (32-char lowercase hex)
- * @param {number} size Optional. Package size in KB for disk space validation
- * @param {string} shell Optional. Custom upgrade script content
- * @param {number} timeout Optional. Connection timeout in seconds (default: 3)
+ * @deprecated 浣跨敤 updateHttp() 浠f浛
+ * 鏀寔鑷畾涔夎剼鏈殑鏃у崌绾ф柟娉曘��
+ * 涓嬭浇銆佹彁鍙栧苟鎵ц鑷畾涔夊崌绾ц剼鏈��
+ * @param {string} url 蹇呭~銆備笅杞藉崌绾у寘鐨� HTTP URL
+ * @param {string} md5 蹇呭~銆傜敤浜庡畬鏁存�ч獙璇佺殑 MD5 鍝堝笇鍊硷紙32 浣嶅皬鍐欏崄鍏繘鍒讹級
+ * @param {number} size 鍙�夈�傜敤浜庣鐩樼┖闂撮獙璇佺殑鍖呭ぇ灏忥紙KB锛�
+ * @param {string} shell 鍙�夈�傝嚜瀹氫箟鍗囩骇鑴氭湰鍐呭
+ * @param {number} timeout 鍙�夈�傝繛鎺ヨ秴鏃舵椂闂达紙绉掞級锛岄粯璁わ細3
*/
ota.update = function (url, md5, size, shell, timeout = 3) {
if (!url || !md5) {
- throw new Error("'url' and 'md5' parameters are required")
+ throw new Error("'url' 鍜� 'md5' 鍙傛暟鏄繀濉殑")
}
if (size && (typeof size != 'number')) {
- throw new Error("'size' parameter must be a number")
+ throw new Error("'size' 鍙傛暟蹇呴』鏄暟瀛�")
}
- // 1. Check available disk space
+ // 1. 妫�鏌ュ彲鐢ㄧ鐩樼┖闂�
let df = parseInt(com.systemWithRes(ota.DF_CMD, 1000))
if (size) {
- if (df < (3 * size)) { // Require 3x package size for extraction
- throw new Error('Insufficient disk space for upgrade')
+ if (df < (3 * size)) { // 闇�瑕� 3 鍊嶅寘澶у皬鐢ㄤ簬鎻愬彇
+ throw new Error('鍗囩骇纾佺洏绌洪棿涓嶈冻')
}
}
- // 2. Download to specific directory
+ // 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} `) // Clean and create directory
+ com.systemBrief(`rm -rf ${ota.OTA_ROOT} && mkdir ${ota.OTA_ROOT} `) // 娓呯悊骞跺垱寤虹洰褰�
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)
@@ -158,65 +163,65 @@
fileExist = (os.stat(firmware)[1] === 0)
if (!fileExist) {
log.error("download result" + downloadRet)
- throw new Error('Download failed. Please check the URL: ' + url)
+ throw new Error('涓嬭浇澶辫触銆傝妫�鏌� URL: ' + url)
}
- // 3. Verify MD5 checksum
+ // 3. 楠岃瘉 MD5 鏍¢獙鍜�
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('MD5 verification failed')
+ throw new Error('MD5 楠岃瘉澶辫触')
}
- // 4. Extract package
+ // 4. 鎻愬彇鍖�
com.systemBrief(`mkdir ${temp} && unzip -o ${firmware} -d ${temp}`)
- // 5. Execute custom upgrade script if present
+ // 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. Create upgrade script
+ // 6. 鍒涘缓鍗囩骇鑴氭湰
if (!shell) {
- // Default: copy files and clean up
+ // 榛樿锛氬鍒舵枃浠跺苟娓呯悊
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('Failed to create upgrade script')
+ throw new Error('鍒涘缓鍗囩骇鑴氭湰澶辫触')
}
com.systemWithRes(`${ota.OTA_RUN}`)
}
/**
- * @deprecated Use updateHttp() instead
- * Legacy resource upgrade for tar.xz packages.
- * Specialized for upgrading resource files only.
- * @param {string} url Required. HTTP URL for downloading the upgrade package
- * @param {string} md5 Required. MD5 hash for integrity verification (32-char lowercase hex)
- * @param {number} size Optional. Package size in KB for disk space validation
- * @param {string} shell Optional. Custom upgrade script content
- * @param {number} timeout Optional. Connection timeout in seconds (default: 3)
+ * @deprecated 浣跨敤 updateHttp() 浠f浛
+ * 鐢ㄤ簬 tar.xz 鍖呯殑鏃ц祫婧愬崌绾с��
+ * 涓撻棬鐢ㄤ簬浠呭崌绾ц祫婧愭枃浠躲��
+ * @param {string} url 蹇呭~銆備笅杞藉崌绾у寘鐨� HTTP URL
+ * @param {string} md5 蹇呭~銆傜敤浜庡畬鏁存�ч獙璇佺殑 MD5 鍝堝笇鍊硷紙32 浣嶅皬鍐欏崄鍏繘鍒讹級
+ * @param {number} size 鍙�夈�傜敤浜庣鐩樼┖闂撮獙璇佺殑鍖呭ぇ灏忥紙KB锛�
+ * @param {string} shell 鍙�夈�傝嚜瀹氫箟鍗囩骇鑴氭湰鍐呭
+ * @param {number} timeout 鍙�夈�傝繛鎺ヨ秴鏃舵椂闂达紙绉掞級锛岄粯璁わ細3
*/
ota.updateResource = function (url, md5, size, shell, timeout = 3) {
if (!url || !md5) {
- throw new Error("'url' and 'md5' parameters are required")
+ throw new Error("'url' 鍜� 'md5' 鍙傛暟鏄繀濉殑")
}
if (size && (typeof size != 'number')) {
- throw new Error("'size' parameter must be a number")
+ throw new Error("'size' 鍙傛暟蹇呴』鏄暟瀛�")
}
- // 1. Check available disk space
+ // 1. 妫�鏌ュ彲鐢ㄧ鐩樼┖闂�
let df = parseInt(com.systemWithRes(ota.DF_CMD, 1000))
if (size) {
- if (df < (3 * size)) { // Require 3x package size for extraction
- throw new Error('Insufficient disk space for upgrade')
+ if (df < (3 * size)) { // 闇�瑕� 3 鍊嶅寘澶у皬鐢ㄤ簬鎻愬彇
+ throw new Error('鍗囩骇纾佺洏绌洪棿涓嶈冻')
}
}
- // 2. Download to specific directory
+ // 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} `) // Clean and create directory
+ com.systemBrief(`rm -rf ${ota.OTA_ROOT} && mkdir ${ota.OTA_ROOT} `) // 娓呯悊骞跺垱寤虹洰褰�
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)
@@ -225,18 +230,18 @@
}
fileExist = (os.stat(firmware)[1] === 0)
if (!fileExist) {
- throw new Error('Download failed. Please check the URL: ' + url)
+ throw new Error('涓嬭浇澶辫触銆傝妫�鏌� URL: ' + url)
}
- // 3. Verify MD5 checksum
+ // 3. 楠岃瘉 MD5 鏍¢獙鍜�
let md5Hash = com.md5HashFile(firmware)
md5Hash = md5Hash.map(v => v.toString(16).padStart(2, 0)).join('')
if (md5Hash != md5) {
- throw new Error('MD5 verification failed')
+ throw new Error('MD5 楠岃瘉澶辫触')
}
- // 4. Extract tar.xz package
+ // 4. 鎻愬彇 tar.xz 鍖�
com.systemBrief(`mkdir ${temp} && tar -xJvf ${firmware} -C ${temp}`)
- // 5. Create resource upgrade script
+ // 5. 鍒涘缓璧勬簮鍗囩骇鑴氭湰
if (!shell) {
shell = `
source=${temp}/vgapp/res/image/bk.png
@@ -264,7 +269,7 @@
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('Failed to create upgrade script')
+ throw new Error('鍒涘缓鍗囩骇鑴氭湰澶辫触')
}
com.systemWithRes(`${ota.OTA_RUN}`)
}
diff --git a/vf107/resource/langPack.js b/vf107/resource/langPack.js
index 7bf4081..cc65698 100644
--- a/vf107/resource/langPack.js
+++ b/vf107/resource/langPack.js
@@ -195,6 +195,7 @@
face: "浜鸿劯",
swipeCardRecognition: "鍒峰崱鏍搁獙",
passwordOpenDoor: "瀵嗙爜寮�闂�",
+ emergencyOpenDoorPassword: "搴旀�ュ紑闂ㄥ瘑鐮�",
inputOriginalPassword: "璇疯緭鍏ュ師鐧诲綍瀵嗙爜",
inputNewPassword: "璇疯緭鍏ユ柊瀵嗙爜",
inputRepeatNewPassword: "璇烽噸澶嶆柊瀵嗙爜",
@@ -265,10 +266,10 @@
title: "閫氳璁板綍璇︽儏",
id: "浜哄憳1缂栧彿",
name: "浜哄憳1濮撳悕",
- idCard: "浜哄憳1韬唤璇佸彿",
+ card: "浜哄憳1鍗″彿",
userId2: "浜哄憳2缂栧彿(绗簩鐢ㄦ埛)",
name2: "浜哄憳2濮撳悕",
- idCard2: "浜哄憳2韬唤璇佸彿",
+ card2: "浜哄憳2鍗″彿",
time: "閫氳鏃堕棿",
result: "閫氳缁撴灉",
face: "浜哄憳1浜鸿劯鎶撴媿",
@@ -338,7 +339,7 @@
failSimilarity: "澶辫触锛屼汉鑴哥浉浼煎害杩囬珮",
failCardRepeat: "澶辫触锛屽崱鐗囬噸澶�",
failPwdRepeat: "澶辫触锛屽瘑鐮侀噸澶�",
- typeOptions: ["鏅�氱敤鎴�", "绠$悊鍛�"],
+ typeOptions: ["淇濈鍛�", "绉戦暱"],
finger: "鎸囩汗鍑瘉",
confirmFinger: "纭鍒犻櫎鎸囩汗鍑瘉鍚楋紵",
failFingerRepeat: "澶辫触锛屾寚绾归噸澶�",
@@ -602,6 +603,7 @@
face: "Face Only",
swipeCardRecognition: "Card Verification",
passwordOpenDoor: "Password Access",
+ emergencyOpenDoorPassword: "Emergency Open Door Password",
inputOriginalPassword: "Enter Current Password",
inputNewPassword: "Enter New Password",
inputRepeatNewPassword: "Confirm New Password",
@@ -673,10 +675,13 @@
title: "Access Log Details",
id: "User ID",
name: "Name",
- idCard: "ID Number",
+ card: "Card Number",
+ userId2: "User ID 2",
+ name2: "Name 2",
time: "Access Time",
result: "Result",
face: "Face Photo",
+ face2: "Face Photo 2",
},
voiceBroadcastView: {
title: "Voice Settings",
@@ -1000,6 +1005,7 @@
face: "Solo rostro",
swipeCardRecognition: "Verificaci贸n tarjeta",
passwordOpenDoor: "Acceso con clave",
+ emergencyOpenDoorPassword: "Contrase帽a de emergencia",
inputOriginalPassword: "Contrase帽a actual",
inputNewPassword: "Nueva contrase帽a",
inputRepeatNewPassword: "Repite contrase帽a",
@@ -1067,10 +1073,13 @@
title: "Detalle registro",
id: "ID usuario",
name: "Nombre",
- idCard: "Documento",
+ card: "N煤mero tarjeta",
+ userId2: "ID usuario 2",
+ name2: "Nombre 2",
time: "Hora",
result: "Resultado",
face: "Foto rostro",
+ face2: "Foto rostro 2",
},
voiceBroadcastView: {
title: "Voz",
@@ -1462,10 +1471,13 @@
title: "D茅tail journal",
id: "ID utilisateur",
name: "Nom",
- idCard: "Document",
+ card: "Num茅ro carte",
+ userId2: "ID utilisateur 2",
+ name2: "Nom 2",
time: "Heure",
result: "R茅sultat",
face: "Photo visage",
+ face2: "Photo visage 2",
},
voiceBroadcastView: {
title: "Voix",
@@ -1857,10 +1869,13 @@
title: "Protokoll-Detail",
id: "Nutzer-ID",
name: "Name",
- idCard: "Ausweis",
+ card: "Kartennummer",
+ userId2: "Nutzer-ID 2",
+ name2: "Name 2",
time: "Zeit",
result: "Ergebnis",
face: "Gesichtsfoto",
+ face2: "Gesichtsfoto 2",
},
voiceBroadcastView: {
title: "Stimme",
@@ -2252,10 +2267,13 @@
title: "袛械褌邪谢褜 谢芯谐邪",
id: "ID",
name: "袠屑褟",
- idCard: "袛芯泻褍屑械薪褌",
+ card: "袧芯屑械褉 泻邪褉褌褘",
+ userId2: "ID 2",
+ name2: "袠屑褟 2",
time: "袙褉械屑褟",
result: "袪械蟹褍谢褜褌邪褌",
face: "肖芯褌芯 谢懈褑邪",
+ face2: "肖芯褌芯 谢懈褑邪 2",
},
voiceBroadcastView: {
title: "袚芯谢芯褋",
@@ -2647,10 +2665,13 @@
title: "鬲賮丕氐賷賱 爻噩賱",
id: "ID",
name: "丕爻賲",
- idCard: "賵孬賷賯丞",
+ card: "乇賯賲 丕賱亘胤丕賯丞",
+ userId2: "ID 2",
+ name2: "丕爻賲 2",
time: "賵賯鬲",
result: "賳鬲賷噩丞",
face: "氐賵乇丞 賵噩賴",
+ face2: "氐賵乇丞 賵噩賴 2",
},
voiceBroadcastView: {
title: "氐賵鬲",
@@ -3045,10 +3066,13 @@
title: "Detalhe registro",
id: "ID usu谩rio",
name: "Nome",
- idCard: "Documento",
+ card: "N煤mero cart茫o",
+ userId2: "ID usu谩rio 2",
+ name2: "Nome 2",
time: "Hora",
result: "Resultado",
face: "Foto face",
+ face2: "Foto face 2",
},
voiceBroadcastView: {
title: "Voz",
@@ -3440,10 +3464,13 @@
title: "旮半 靸侅劯",
id: "ID",
name: "鞚措",
- idCard: "鞁犽秳歃�",
+ card: "旃措摐 氩堩樃",
+ userId2: "ID 2",
+ name2: "鞚措 2",
time: "鞁滉皠",
result: "瓴瓣臣",
face: "鞏缄荡 靷",
+ face2: "鞏缄荡 靷 2",
},
voiceBroadcastView: {
title: "鞚岇劚",
diff --git a/vf107/src/config.json b/vf107/src/config.json
index 7fce11d..0ca3c00 100644
--- a/vf107/src/config.json
+++ b/vf107/src/config.json
@@ -65,9 +65,9 @@
//鏄惁绗竴娆$櫥褰曞悗鍙� 0 鏈櫥褰� 1 宸茬櫥褰� // TODO 杩欎釜閰嶇疆椤瑰簲璇ュ睘浜庤繍琛屾椂鐘舵��,涓嶈耽璇ュ啓鍏onfig.json鎴栬�呭啓鍏ュ崟鐙垎缁�,鏌ヨ閰嶇疆鏃跺仛杩囨护
"base.firstLogin": 0,
// 鐔勫睆鏃堕棿锛屽崟浣嶅垎閽燂紝0浠庝笉
- "base.screenOff": 0,
+ "base.screenOff": 2,
// 灞忓箷淇濇姢锛屽崟浣嶅垎閽燂紝0浠庝笉
- "base.screensaver": 0,
+ "base.screensaver": 2,
//灞忓箷鑳屽厜
"base.backlight": 70,
//鐧借壊琛ュ厜鐏�
@@ -137,5 +137,7 @@
// 搴撳尯鍚嶇О
"GranaryName": "涓ぎ鍌ㄥ绮煇鏌愮洿灞炲簱",
// HTTP鎺ュ彛璺緞
- "http.safeInputAccess": "http://192.168.1.227:80/cgi-bin/safeInputAccess"
+ "http.safeInputAccess": "http://192.168.1.227:80/cgi-bin/safeInputAccess",
+ // 鏄惁寮�鍚皵浣撴祿搴﹂獙璇� 1:鏄� 0:鍚�
+ "gas.verification": 1
}
\ No newline at end of file
diff --git a/vf107/src/controller.js b/vf107/src/controller.js
index 442134b..b3c4e68 100644
--- a/vf107/src/controller.js
+++ b/vf107/src/controller.js
@@ -31,7 +31,7 @@
driver.nfc.loop()
driver.gpiokey.loop()
driver.face.loop()
- if (!driver.device.finger && (dxDriver.DRIVER.MODEL == "vf105" || dxDriver.DRIVER.MODEL == "vf114")) {
+ if (!driver.device.finger && (dxDriver.DRIVER.MODEL == "vf105" || dxDriver.DRIVER.MODEL == "vf107" || dxDriver.DRIVER.MODEL == "vf114")) {
driver.uartCode.loop()
}
if (dxDriver.DRIVER.MODEL == "vf202") {
@@ -74,7 +74,7 @@
bus.fire(driver.gpiokey.RECEIVE_MSG, event)
}
});
- if (!driver.device.finger && (dxDriver.DRIVER.MODEL == "vf105" || dxDriver.DRIVER.MODEL == "vf114")) {
+ if (!driver.device.finger && (dxDriver.DRIVER.MODEL == "vf105" || dxDriver.DRIVER.MODEL == "vf107" || dxDriver.DRIVER.MODEL == "vf114")) {
driver.uartCode.setCallbacks({
onMessage: (event) => {
bus.fire(driver.uartCode.RECEIVE_MSG, event)
diff --git a/vf107/src/driver.js b/vf107/src/driver.js
index 89037d3..cfaed7d 100644
--- a/vf107/src/driver.js
+++ b/vf107/src/driver.js
@@ -48,7 +48,7 @@
config.set('mqtt.clientId', uuid)
}
if (driver.device.finger) {
- if (dxDriver.DRIVER.MODEL == "vf105") {
+ if (dxDriver.DRIVER.MODEL == "vf105" || dxDriver.DRIVER.MODEL == "vf107") {
config.set('sys.model', "vf107")
} else if (dxDriver.DRIVER.MODEL == "vf114") {
config.set('sys.model', "vf124")
@@ -129,7 +129,7 @@
if (dxDriver.DRIVER.MODEL == "vf203") {
pwm.init(dxDriver.PWM.NIR_SUPPLEMENT_CHANNEL);
pwm.setPower(nirLuminance, dxDriver.PWM.NIR_SUPPLEMENT_CHANNEL);
- } else if (dxDriver.DRIVER.MODEL == "vf202" || dxDriver.DRIVER.MODEL == "vf114" || dxDriver.DRIVER.MODEL == "vf105") {
+ } else if (dxDriver.DRIVER.MODEL == "vf202" || dxDriver.DRIVER.MODEL == "vf114" || dxDriver.DRIVER.MODEL == "vf105" || dxDriver.DRIVER.MODEL == "vf107") {
pwm.init(dxDriver.PWM.WHITE_SUPPLEMENT_CHANNEL);
pwm.init(dxDriver.PWM.NIR_SUPPLEMENT_CHANNEL);
pwm.setPower(whiteLuminance, dxDriver.PWM.WHITE_SUPPLEMENT_CHANNEL);
@@ -362,7 +362,7 @@
driver.uartCode = {
RECEIVE_MSG: '__UART_RECEIVE_MSG__',
init: function () {
- if (dxDriver.DRIVER.MODEL == 'vf105') {
+ if (dxDriver.DRIVER.MODEL == 'vf105' || dxDriver.DRIVER.MODEL == 'vf107') {
dxVgCode.init('/dev/ttySLB1', '115200-8-N-1')
} else if (dxDriver.DRIVER.MODEL == 'vf114') {
dxVgCode.init('/dev/ttySLB3', '115200-8-N-1')
diff --git a/vf107/src/main.js b/vf107/src/main.js
index ffcb751..5f02040 100644
--- a/vf107/src/main.js
+++ b/vf107/src/main.js
@@ -205,31 +205,9 @@
// 娓呯悊鏈粦瀹氱殑鍑瘉淇℃伅
cleanupUnboundVouchers()
- let appVersion
- let releaseTime
- if (dxDriver.DRIVER.MODEL == "vf202") {
- appVersion = 'vf202_v12_access_2.0.2'
- releaseTime = '2026-01-09 13:00:00'
- } else if (dxDriver.DRIVER.MODEL == "vf203") {
- appVersion = 'vf203_v14_access_2.0.2'
- releaseTime = '2026-02-04 14:30:00'
- } else if (dxDriver.DRIVER.MODEL == "vf114") {
- if(driver.device.finger) {
- appVersion = 'vf124_v12_access_2.0.2'
- releaseTime = '2026-03-19 13:00:00'
- } else {
- appVersion = 'vf114_v12_access_2.0.2'
- releaseTime = '2026-01-09 13:00:00'
- }
- } else if (dxDriver.DRIVER.MODEL == "vf105") {
- if(driver.device.finger) {
- appVersion = 'vf107_v12_access_2.0.2.1'
- releaseTime = '2026-03-19 13:00:00'
- } else {
- appVersion = 'vf105_v12_access_2.0.2'
- releaseTime = '2026-01-09 13:00:00'
- }
- }
+ let appVersion = 'vf107_access_2.0.2.1'
+ let releaseTime = '2026-03-19 13:00:00'
+
config.setAndSave('sys.version', appVersion)
config.setAndSave('sys.appVersion', appVersion)
config.setAndSave('sys.releaseTime', releaseTime)
diff --git a/vf107/src/screen.js b/vf107/src/screen.js
index 4380ba9..08da513 100644
--- a/vf107/src/screen.js
+++ b/vf107/src/screen.js
@@ -65,7 +65,7 @@
screen.model = dxDriver.DRIVER.MODEL
screen.resourcePath = {
- imagePath: `/app/code/resource/image/${dxDriver.DRIVER.MODEL}/`
+ imagePath: `/app/code/resource/image/vf105/`
}
screen.dropdownSymbol = screen.resourcePath.imagePath + '/down.png'
@@ -179,28 +179,12 @@
function getClickPoint() {
const indev = NativeObject.APP.NativeComponents.NativeIndev
std.setInterval(() => {
- if (dxDriver.DRIVER.MODEL == "vf203") {
- clickPoint = {
- x: Math.abs(600 - indev.lvIndevGetPointVg().y),
- y: indev.lvIndevGetPointVg().x
- }
- } else if (dxDriver.DRIVER.MODEL == "vf202") {
- clickPoint = {
- x: indev.lvIndevGetPointVg().x,
- y: indev.lvIndevGetPointVg().y
- }
- } else if (dxDriver.DRIVER.MODEL == "vf114") {
- clickPoint = {
- x: indev.lvIndevGetPointVg().x,
- y: indev.lvIndevGetPointVg().y
- }
- } else if (dxDriver.DRIVER.MODEL == "vf105") {
- clickPoint = {
- x: indev.lvIndevGetPointVg().x,
- y: indev.lvIndevGetPointVg().y
- }
+
+ clickPoint = {
+ x: indev.lvIndevGetPointVg().x,
+ y: indev.lvIndevGetPointVg().y
}
-
+
if (lastClickPoint.x != clickPoint.x || lastClickPoint.y != clickPoint.y) {
changedClickPoint = clickPoint
} else {
@@ -1035,11 +1019,14 @@
let param = driver.net.getNetParam()
if (data == "connected" && param) {
- config.setAndSave("net.ip", param.ip)
- config.setAndSave("net.gateway", param.gateway)
- config.setAndSave("net.mask", param.netmask)
- config.setAndSave('net.dns', param.dns)
- config.setAndSave('net.mac', screen.getNetMac())
+ // 鍙湁鍦ㄧ綉缁滈厤缃〉闈笉鍙涓旂敤鎴蜂笉鍦ㄧ紪杈戦厤缃椂鎵嶈嚜鍔ㄤ繚瀛樼綉缁滃弬鏁�
+ if (!networkSettingView.isVisible && !networkSettingView.isEditing) {
+ config.setAndSave("net.ip", param.ip)
+ config.setAndSave("net.gateway", param.gateway)
+ config.setAndSave("net.mask", param.netmask)
+ config.setAndSave('net.dns', param.dns)
+ config.setAndSave('net.mac', screen.getNetMac())
+ }
topView.ethConnectState(true, type)
networkSettingView.netInfo[10].label.dataI18n = "networkSettingView.networkConnected"
if (mainView.ipInfoLbl) mainView.ipInfoLbl.text("IP:" + param.ip)
@@ -1054,7 +1041,10 @@
}
i18n.refreshObj(networkSettingView.netInfo[10].label)
networkSettingView.refresh()
- networkSettingView.changeNetType(type)
+ // 鍙湁鍦ㄧ敤鎴蜂笉鍦ㄧ紪杈戦厤缃椂鎵嶆墽琛岀綉缁滅被鍨嬪垏鎹�
+ if (!networkSettingView.isEditing) {
+ networkSettingView.changeNetType(type)
+ }
}
screen.fireNetStatus = function () {
diff --git a/vf107/src/service/accessService.js b/vf107/src/service/accessService.js
index 35ec0a1..09940bc 100644
--- a/vf107/src/service/accessService.js
+++ b/vf107/src/service/accessService.js
@@ -169,7 +169,16 @@
} catch (error) {
logger.error("鏃犺韩浠借瘉鍙锋垨绫诲瀷")
}
- data.extra = { name: res[0].name, idCard: idCard, type: userType }
+ // 鏍规嵁data.type璁剧疆姝g‘鐨勮璇佺被鍨�
+ let accessType = 0
+ if (data.type == "200") {
+ accessType = 200 // 鍒峰崱
+ } else if (data.type == "300") {
+ accessType = 300 // 浜鸿劯
+ } else if (data.type == "500") {
+ accessType = 500 // 鎸囩汗
+ }
+ data.extra = { name: res[0].name, idCard: idCard, card: data.code, type: userType, accessType: accessType }
data.permissionIds = res[0].permissionIds
}
@@ -183,21 +192,39 @@
// 鏌ヨ绗竴鐢ㄦ埛鐨勮缁嗕俊鎭�
let res1 = sqliteService.d1_person.findByUserId(firstUserId)
if (res1.length > 0) {
- // 鑾峰彇绗竴鐢ㄦ埛鐨勫鍚嶃�佽韩浠借瘉鍙峰拰韬唤绫诲瀷
+ // 鑾峰彇绗竴鐢ㄦ埛鐨勫鍚嶃�佽韩浠借瘉鍙�
let idCard1
- let firstUserType = 0
+ let userType1 = 0
try {
idCard1 = JSON.parse(res1[0].extra).idCard
- firstUserType = JSON.parse(res1[0].extra).type || 0
+ userType1 = JSON.parse(res1[0].extra).type || 0
} catch (error) {
- logger.error("鏃犵涓�鐢ㄦ埛韬唤璇佸彿鎴栫被鍨�")
+ logger.error("鏃犵涓�鐢ㄦ埛韬唤璇佸彿")
+ }
+ // 鏍规嵁data.type璁剧疆姝g‘鐨勮璇佺被鍨�
+ let accessType1 = 0
+ if (data.type == "200") {
+ accessType1 = 200 // 鍒峰崱
+ } else if (data.type == "300") {
+ accessType1 = 300 // 浜鸿劯
+ } else if (data.type == "500") {
+ accessType1 = 500 // 鎸囩汗
}
data.userId = firstUserId
- data.extra = { name: res1[0].name, idCard: idCard1, type: firstUserType }
+ data.extra = { name: res1[0].name, idCard: idCard1, card: data.code, type: userType1, accessType: accessType1 }
} else {
// 濡傛灉娌℃湁鏌ヨ鍒扮涓�鐢ㄦ埛淇℃伅锛屼娇鐢ㄩ粯璁ゅ��
data.userId = firstUserId
- data.extra = { name: data.dualAuthInfo.firstUserName, idCard: "", type: 0 }
+ // 鏍规嵁data.type璁剧疆姝g‘鐨勮璇佺被鍨�
+ let accessType1 = 0
+ if (data.type == "200") {
+ accessType1 = 200 // 鍒峰崱
+ } else if (data.type == "300") {
+ accessType1 = 300 // 浜鸿劯
+ } else if (data.type == "500") {
+ accessType1 = 500 // 鎸囩汗
+ }
+ data.extra = { name: data.dualAuthInfo.firstUserName, idCard: "", type: 0, accessType: accessType1 }
}
// 瀛樺偍绗簩鐢ㄦ埛淇℃伅
data.userId2 = data.dualAuthInfo.secondUserId
@@ -206,19 +233,37 @@
if (res2.length > 0) {
// 鑾峰彇绗簩鐢ㄦ埛鐨勫鍚嶅拰韬唤璇佸彿
let idCard2
- let secondUserType = 0
+ let userType2 = 0
try {
idCard2 = JSON.parse(res2[0].extra).idCard
- secondUserType = JSON.parse(res2[0].extra).type || 0
+ userType2 = JSON.parse(res2[0].extra).type || 0
} catch (error) {
- logger.error("鏃犵浜岀敤鎴疯韩浠借瘉鍙锋垨绫诲瀷")
+ logger.error("鏃犵浜岀敤鎴疯韩浠借瘉鍙�")
}
- data.extra2 = { name: res2[0].name, idCard: idCard2 }
+ // 鏍规嵁data.type璁剧疆姝g‘鐨勮璇佺被鍨�
+ let accessType2 = 0
+ if (data.type == "200") {
+ accessType2 = 200 // 鍒峰崱
+ } else if (data.type == "300") {
+ accessType2 = 300 // 浜鸿劯
+ } else if (data.type == "500") {
+ accessType2 = 500 // 鎸囩汗
+ }
+ data.extra2 = { name: res2[0].name, idCard: idCard2, card: data.code2, type: userType2, accessType: accessType2 }
// 瀛樺偍绗簩鐢ㄦ埛鐨勬潈闄怚D锛堣韩浠界被鍨嬶級
- data.permissionId2 = secondUserType.toString()
+ data.permissionId2 = userType2.toString()
} else {
// 濡傛灉娌℃湁鏌ヨ鍒扮浜岀敤鎴蜂俊鎭紝浣跨敤榛樿鍊�
- data.extra2 = { name: data.dualAuthInfo.secondUserName, idCard: "" }
+ // 鏍规嵁data.type璁剧疆姝g‘鐨勮璇佺被鍨�
+ let accessType2 = 0
+ if (data.type == "200") {
+ accessType2 = 200 // 鍒峰崱
+ } else if (data.type == "300") {
+ accessType2 = 300 // 浜鸿劯
+ } else if (data.type == "500") {
+ accessType2 = 500 // 鎸囩汗
+ }
+ data.extra2 = { name: data.dualAuthInfo.secondUserName, idCard: "", type: 0, accessType: accessType2 }
data.permissionId2 = ""
}
// 澶勭悊绗竴鐢ㄦ埛鐨勪汉鑴稿浘鐗�
@@ -323,6 +368,19 @@
if (authQueue.length === 1) {
// 绗竴鐢ㄦ埛璁よ瘉
logger.info("[access]: 淇濈鍛樻潈闄愶紝闇�瑕佸弻浜鸿璇�")
+ // 纭繚data.extra鍖呭惈accessType瀛楁
+ if (!data.extra.accessType) {
+ // 鏍规嵁data.type璁剧疆姝g‘鐨勮璇佺被鍨�
+ let accessType = 0
+ if (data.type == "200") {
+ accessType = 200 // 鍒峰崱
+ } else if (data.type == "300") {
+ accessType = 300 // 浜鸿劯
+ } else if (data.type == "500") {
+ accessType = 500 // 鎸囩汗
+ }
+ data.extra.accessType = accessType
+ }
// 瑙﹀彂绗竴鐢ㄦ埛璁よ瘉鎴愬姛浜嬩欢锛屾洿鏂癠I
bus.fire("accessSuccess", {
data: {
@@ -413,13 +471,19 @@
} catch (error) {
logger.error("鏃犵涓�鐢ㄦ埛韬唤璇佸彿鎴栫被鍨�")
}
- data.extra = { name: userRes[0].name, idCard: idCard1, type: firstUserType }
+ // 纭繚绗竴鐢ㄦ埛鐨勪俊鎭寘鍚玜ccessType瀛楁
+ let accessType1 = firstUser.data.extra.accessType || 0
+ data.extra = { name: userRes[0].name, idCard: idCard1, type: firstUserType, accessType: accessType1 }
} else {
- data.extra = { name: firstUser.name, idCard: '', type: firstUser.type }
+ // 纭繚绗竴鐢ㄦ埛鐨勪俊鎭寘鍚玜ccessType瀛楁
+ let accessType1 = firstUser.data.extra.accessType || 0
+ data.extra = { name: firstUser.name, idCard: '', type: firstUser.type, accessType: accessType1 }
}
} catch (error) {
logger.error("瑙f瀽绗竴鐢ㄦ埛淇℃伅澶辫触")
- data.extra = { name: firstUser.name, idCard: '', type: firstUser.type }
+ // 纭繚绗竴鐢ㄦ埛鐨勪俊鎭寘鍚玜ccessType瀛楁
+ let accessType1 = firstUser.data.extra.accessType || 0
+ data.extra = { name: firstUser.name, idCard: '', type: firstUser.type, accessType: accessType1 }
}
// 瀛樺偍绗簩鐢ㄦ埛鐨勪汉鑴稿浘鐗�
if (secondUser.fileName) {
@@ -481,7 +545,7 @@
if (!ret && config.get('mqtt.onlinecheck') == 1 && mqtt_map.get("MQTT_STATUS") == "connected") {
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.mqtt.send(`access_device/v2/event/${sn}/access_online`, JSON.stringify(mqttService.mqttReply(serialNo, data, mqttService.CODE.S_000)))
driver.audio.play(`/app/code/resource/${language}/wav/recg.wav`)
// 绛夊緟鍦ㄧ嚎楠岃瘉缁撴灉
@@ -504,63 +568,28 @@
bleReply(data, 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]: 閫氳鎴愬姛")
+ // 妫�鏌ユ槸鍚﹀紑鍚皵浣撴祿搴﹂獙璇�
+ const gasVerificationEnabled = config.get('gas.verification')
+
+ if (gasVerificationEnabled) {
+ // 楠岃瘉姘斾綋娴撳害
+ grainService.checkGasConcentration(function() {
+ // 浠庡瓨鍌ㄧ殑姘斾綋鏁版嵁涓幏鍙栭獙璇佺粨鏋�
+ const gasData = grainService.getGasData()
- // 鏄剧ず閫氳鎴愬姛缁撴灉
- bus.fire("showAccessResult", {
- faceAuth: true,
- gasConcentration: true,
- accessAllowed: true,
- message: "*浠撳唴姘斾綋娴撳害鍚堟牸锛屽厑璁搁�氳*"
- })
-
- // 瑙﹀彂閫氳鎴愬姛浜嬩欢锛岄�氱煡UI鏇存柊
- bus.fire("accessSuccess", { data: data, fileName: fileName })
- driver.audio.play(`/app/code/resource/${language}/wav/access_s.wav`) // 鎾斁璇煶
- driver.gpio.open() // 寮�闂�
- savePassPic(data, fileName) // 淇濆瓨閫氳鍥剧墖
- reply(data, true) // 涓婃姤閫氳璁板綍
-
- // 60绉掑悗閲嶇疆鐢ㄦ埛UI
- std.setTimeout(() => {
- bus.fire("accessUnlockComplete")
- }, 60000)
- } else {
- logger.info("[access]: 姘斾綋娴撳害楠岃瘉涓嶅悎鏍�")
- // 閫氳澶辫触澶勭悊
- driver.screen.accessFail()
- logger.error("[access]: 閫氳澶辫触")
- // 瑙﹀彂澶辫触寮圭獥
- bus.fire("showAccessResult", {
- faceAuth: true,
- gasConcentration: false,
- accessAllowed: false,
- message: "*浠撳唴姘斾綋娴撳害涓嶅悎鏍硷紝绂佹閫氳*"
- })
- // 瑙﹀彂閫氳鎴愬姛浜嬩欢锛屾洿鏂扮敤鎴稶I
- bus.fire("accessSuccess", { data: data, fileName: fileName })
- if (utils.isEmpty(similarity)) {
- driver.audio.play(`/app/code/resource/${language}/wav/access_f.wav`)
+ if(gasData && gasData.data && gasData.data.status === "0") {
+ logger.info("[access]: 姘斾綋娴撳害楠岃瘉鍚堟牸")
+ handleAccessSuccess(data, fileName, similarity, "*浠撳唴姘斾綋娴撳害鍚堟牸锛屽厑璁搁�氳*")
+ } else {
+ logger.info("[access]: 姘斾綋娴撳害楠岃瘉涓嶅悎鏍�")
+ handleAccessFail(data, fileName, similarity, "*浠撳唴姘斾綋娴撳害涓嶅悎鏍硷紝绂佹閫氳*", "姘斾綋娴撳害涓嶅悎鏍�")
}
- // 60绉掑悗閲嶇疆鐢ㄦ埛UI
- std.setTimeout(() => {
- bus.fire("accessUnlockComplete")
- }, 60000)
- savePassPic(data, fileName)
- // 娣诲姞姘斾綋娴撳害澶辫触淇℃伅
- data.message = "姘斾綋娴撳害涓嶅悎鏍�"
- reply(data, false) // 涓婃姤閫氳璁板綍
- }
- })
+ })
+ } else {
+ // 璺宠繃姘斾綋娴撳害楠岃瘉锛岀洿鎺ラ�氳鎴愬姛
+ logger.info("[access]: 姘斾綋娴撳害楠岃瘉宸插叧闂紝璺宠繃楠岃瘉")
+ handleAccessSuccess(data, fileName, similarity, "*鍏佽閫氳*")
+ }
} else {
if (data.type == 500) {
@@ -771,24 +800,55 @@
sqliteService.d1_pass_record.save(record)
}
let accessRecord = {
- userId: record.userId,
- type: record.type,
- result: record.result,
- name: data.extra && data.extra.name ? data.extra.name : "",
- timeStamp: record.timeStamp,
- extra: {},
- error: record.message
+ timeStamp: record.timeStamp || 0,
+ result: record.result || 0,
+ error: record.message || "",
+ permissionId: record.permissionId || "",
+ door: record.door || "",
+ users: [
+ {
+ userId: record.userId || "",
+ name: data.extra && data.extra.name ? data.extra.name : "",
+ keyId: record.keyId || "",
+ userType: data.extra && data.extra.type ? data.extra.type : 0,
+ accessType: data.extra && data.extra.accessType || ""
+ }
+ ]
}
+
+ // 濡傛灉鏄弻浜鸿璇侊紝娣诲姞绗簩涓敤鎴蜂俊鎭�
+ if (record.userId2) {
+ let extra2 = record.extra2 ? JSON.parse(record.extra2) : ""
+ let secondUser = {
+ userId: record.userId2 || "",
+ name: extra2 && extra2.name ? extra2.name : "",
+ userType: extra2 && extra2.type ? extra2.type : 0,
+ accessType: extra2.accessType || ""
+ }
+ // 濡傛灉鏈夊崱鍙蜂俊鎭紝娣诲姞card瀛楁
+ if (extra2 && extra2.card) {
+ secondUser.card = extra2.card
+ }
+ accessRecord.users.push(secondUser)
+ }
+
let serialNo = record.id
if (record.type == 300) {
if (config.get('sys.strangerImage') && config.get('access.uploadToCloud')) {
- accessRecord.code = dxCommonUtils.fs.fileToBase64(record.code)
+ accessRecord.users[0].code = dxCommonUtils.fs.fileToBase64(record.code)
} else {
- accessRecord.code = ""
+ accessRecord.users[0].code = ""
+ }
+
+ // 濡傛灉鏈夌浜屼釜鐢ㄦ埛鐨勪簩缁寸爜
+ if (record.code2) {
+ accessRecord.users[1] = accessRecord.users[1] || {}
+ accessRecord.users[1].code = record.code2
}
}
- let payload = mqttService.mqttReply(serialNo, [accessRecord], mqttService.CODE.S_000)
- driver.mqtt.send("access_device/v2/event/access", JSON.stringify(payload))
+ // 涓嶅啀鐩存帴鍙戦�丮QTT娑堟伅锛岀敱passRecordWorker.js缁熶竴澶勭悊涓婃姤
+ // let payload = mqttService.mqttReply(serialNo, [accessRecord], mqttService.CODE.S_000)
+ // driver.mqtt.send("access_device/v2/event/access", JSON.stringify(payload))
}
// 钃濈墮鍥炲
@@ -801,5 +861,71 @@
driver.uartBle.send("0101" + dxCommonUtils.codec.strToUtf8Hex(replyData))
}
+function handleAccessSuccess(data, fileName, similarity, message) {
+ let language = config.get("base.language") || "CN";
+ driver.screen.accessSuccess()
+ logger.info("[access]: 閫氳鎴愬姛")
+
+ // 纭繚绗竴鐢ㄦ埛鐨別xtra鍖呭惈accessType瀛楁
+ if (!data.extra.accessType) {
+ // 鏍规嵁data.type璁剧疆姝g‘鐨勮璇佺被鍨�
+ let accessType = 0
+ if (data.type == "200" || data.type == 200) {
+ accessType = 200 // 鍒峰崱
+ } else if (data.type == "300" || data.type == 300) {
+ accessType = 300 // 浜鸿劯
+ } else if (data.type == "500" || data.type == 500) {
+ accessType = 500 // 鎸囩汗
+ }
+ data.extra.accessType = accessType
+ }
+
+ // 鏄剧ず閫氳鎴愬姛缁撴灉
+ bus.fire("showAccessResult", {
+ faceAuth: true,
+ gasConcentration: true,
+ accessAllowed: true,
+ message: message
+ })
+
+ // 瑙﹀彂閫氳鎴愬姛浜嬩欢锛岄�氱煡UI鏇存柊
+ bus.fire("accessSuccess", { data: data, fileName: fileName })
+ driver.audio.play(`/app/code/resource/${language}/wav/access_s.wav`) // 鎾斁璇煶
+ driver.gpio.open() // 寮�闂�
+ savePassPic(data, fileName) // 淇濆瓨閫氳鍥剧墖
+ reply(data, true) // 涓婃姤閫氳璁板綍
+
+ // 60绉掑悗閲嶇疆鐢ㄦ埛UI
+ std.setTimeout(() => {
+ bus.fire("accessUnlockComplete")
+ }, 60000)
+}
+
+function handleAccessFail(data, fileName, similarity, message, errorMessage) {
+ let language = config.get("base.language") || "CN";
+ driver.screen.accessFail()
+ logger.error("[access]: 閫氳澶辫触")
+ // 瑙﹀彂澶辫触寮圭獥
+ bus.fire("showAccessResult", {
+ faceAuth: true,
+ gasConcentration: false,
+ accessAllowed: false,
+ message: message
+ })
+ // 瑙﹀彂閫氳鎴愬姛浜嬩欢锛屾洿鏂扮敤鎴稶I
+ bus.fire("accessSuccess", { data: data, fileName: fileName })
+ if (utils.isEmpty(similarity)) {
+ driver.audio.play(`/app/code/resource/${language}/wav/access_f.wav`)
+ }
+ // 60绉掑悗閲嶇疆鐢ㄦ埛UI
+ std.setTimeout(() => {
+ bus.fire("accessUnlockComplete")
+ }, 60000)
+ savePassPic(data, fileName)
+ // 娣诲姞澶辫触淇℃伅
+ data.message = errorMessage
+ reply(data, false) // 涓婃姤閫氳璁板綍
+}
+
export default accessService
\ No newline at end of file
diff --git a/vf107/src/service/api.js b/vf107/src/service/api.js
index 65e7be6..c75cb20 100644
--- a/vf107/src/service/api.js
+++ b/vf107/src/service/api.js
@@ -202,7 +202,12 @@
if (data.type == 0) {
try {
driver.screen.upgrade({ title: "confirm.upgrade", content: "confirm.upgrading" })
- ota.updateHttp(data.url, data.md5, 100)
+ // 纭繚URL鍖呭惈鍗忚鍓嶇紑
+ let url = data.url
+ if (!url.startsWith('http://') && !url.startsWith('https://')) {
+ url = 'http://' + url
+ }
+ ota.updateHttp(url, data.md5, 300)
driver.screen.upgrade({ title: "confirm.upgrade", content: "confirm.upgradeSuccess" })
} catch (error) {
driver.screen.upgrade({ title: "confirm.upgrade", content: "confirm.upgradeFail" })
@@ -315,7 +320,18 @@
let person = sqliteService.d1_person.findByUserId(record.userId)
if (person.length) {
record.name = person[0].name
- record.extra = person[0].extra
+ // 灏唀xtra瀛楁浠嶫SON瀛楃涓茶В鏋愪负JSON瀵硅薄
+ if (person[0].extra && typeof person[0].extra === 'string') {
+ try {
+ record.extra = JSON.parse(person[0].extra)
+ } catch (error) {
+ // 濡傛灉瑙f瀽澶辫触锛屼繚鎸佸師鏍�
+ console.error('瑙f瀽extra瀛楁澶辫触:', error)
+ record.extra = person[0].extra
+ }
+ } else {
+ record.extra = person[0].extra
+ }
}
}
})
@@ -396,6 +412,7 @@
userId: person.userId || 'unknown',
errmsg: ''
}
+ // 澧炲己鏁版嵁楠岃瘉
if (!person.userId || !person.name) {
errorItem.errmsg = "userId or name cannot be empty"
errors.push(errorItem)
@@ -406,11 +423,15 @@
errors.push(errorItem)
continue
}
+
+ // 鏋勫缓浜哄憳璁板綍
let record = {}
record.userId = person.userId
record.name = person.name
record.extra = isEmpty(person.extra) ? JSON.stringify({}) : JSON.stringify(person.extra)
record.permissionIds = person.permissionIds ? person.permissionIds.join(",") : ""
+
+ // 淇濆瓨浜哄憳淇℃伅
let ret = sqliteService.d1_person.save(record)
if (ret != 0) {
sqliteService.d1_person.deleteByUserId(record.userId)
@@ -420,6 +441,197 @@
errors.push(errorItem)
continue
}
+ }
+
+ // 澶勭悊浜鸿劯淇℃伅
+ if (person.face) {
+ try {
+ logger.info('[api] 寮�濮嬪鐞嗕汉鑴镐俊鎭�:', person.userId)
+
+ let faceFilePath = person.face
+
+ // 妫�鏌ユ槸鍚︽槸base64缂栫爜鐨勫浘鐗囨暟鎹�
+ if (person.face.startsWith('data:image/')) {
+ logger.info('[api] 妫�娴嬪埌base64缂栫爜鐨勫浘鐗囨暟鎹�')
+ // 鎻愬彇base64鏁版嵁
+ let base64Data = person.face.split(',')[1]
+ // 鍒涘缓涓存椂鏂囦欢
+ faceFilePath = '/data/user/temp_face_' + person.userId + '.jpg'
+ std.ensurePathExists(faceFilePath)
+ // 灏哹ase64鏁版嵁杞崲涓烘枃浠�
+ dxCommonUtils.fs.base64ToFile(faceFilePath, base64Data)
+ logger.info('[api] 宸插皢base64鏁版嵁淇濆瓨涓烘枃浠�:', faceFilePath)
+ } else {
+ errorItem.errmsg = "鏁版嵁鏍煎紡閿欒锛宖ace瀛楁蹇呴』鏄痓ase64缂栫爜鐨勫浘鐗囨暟鎹�"
+ errors.push(errorItem)
+ continue
+ }
+
+ // 娉ㄥ唽浜鸿劯
+ logger.info('[api] 寮�濮嬫敞鍐屼汉鑴�:', person.userId)
+ let featureFile = driver.face.getFeaByFile(faceFilePath)
+ let addFeaRes = driver.face.addFea(person.userId, featureFile.feature)
+
+ if (addFeaRes == 0) {
+ // 娉ㄥ唽鎴愬姛鍚庣Щ鍔ㄥ浘鐗囧埌鐢ㄦ埛鐩綍
+ let src = "/data/user/" + person.userId + "/register.jpg"
+ std.ensurePathExists(src)
+ logger.info('[api] 绉诲姩浜鸿劯鍥剧墖鍒扮敤鎴风洰褰�:', faceFilePath, '->', src)
+ dxos.systemBrief('mv ' + faceFilePath + " " + src)
+
+ // 淇濆瓨浜鸿劯鍑瘉
+ logger.info('[api] 淇濆瓨浜鸿劯鍑瘉:', person.userId)
+ let voucherRet = sqliteService.d1_voucher.save({
+ keyId: std.genRandomStr(32),
+ type: "300",
+ code: src,
+ userId: person.userId,
+ extra: JSON.stringify({ faceType: 0 })
+ });
+ logger.info('[api] 淇濆瓨浜鸿劯鍑瘉缁撴灉:', voucherRet)
+ } else {
+ logger.error('[api] 娉ㄥ唽浜鸿劯澶辫触锛岃繑鍥炵爜:', addFeaRes)
+ errorItem.errmsg = "娉ㄥ唽浜鸿劯澶辫触锛岃繑鍥炵爜:" + addFeaRes
+ errors.push(errorItem)
+ continue
+ }
+ } catch (error) {
+ logger.error('[api] 澶勭悊浜鸿劯淇℃伅閿欒:', error)
+ errorItem.errmsg = "澶勭悊浜鸿劯淇℃伅閿欒: " + error.message
+ errors.push(errorItem)
+ continue
+ } finally {
+ logger.info('[api] 浜鸿劯淇℃伅澶勭悊瀹屾垚:', person.userId)
+ }
+ }
+
+ // 澶勭悊鎸囩汗淇℃伅
+ if (person.fingerprint) {
+ try {
+ logger.info('[api] 寮�濮嬪鐞嗘寚绾逛俊鎭�:', person.userId)
+
+ // 妫�鏌ヤ箣鍓嶆槸鍚︽湁鎸囩汗鍑瘉
+ let oldVoucher = sqliteService.d1_voucher.findByuserIdAndType(person.userId, "500");
+ if (oldVoucher.length > 0) {
+ logger.info('[api] 鍒犻櫎鏃ф寚绾瑰嚟璇�:', JSON.stringify(oldVoucher[0]))
+ try {
+ let ret = driver.finger.delete(parseInt(oldVoucher[0].code))
+ if (ret != 0) {
+ errorItem.errmsg = "finger delete error ret:" + ret
+ errors.push(errorItem)
+ continue
+ }
+ } catch (error) {
+ logger.error('[api] 鍒犻櫎鏃ф寚绾瑰け璐�:', error)
+ }
+ }
+
+ // 褰曞叆鏂版寚绾�
+ logger.info('[api] 褰曞叆鏂版寚绾�:', person.userId)
+ let index = driver.finger.insert(person.fingerprint)
+ if(index < 0){
+ errorItem.errmsg = "insertKey finger insert error ret:" + index
+ errors.push(errorItem)
+ continue
+ }
+
+ // 淇濆瓨鎸囩汗鍑瘉
+ logger.info('[api] 淇濆瓨鎸囩汗鍑瘉:', person.userId)
+ let voucherRet = sqliteService.d1_voucher.save({
+ keyId: std.genRandomStr(32),
+ type: "500",
+ code: index.toString(),
+ userId: person.userId,
+ extra: JSON.stringify({ type: 0 })
+ });
+ logger.info('[api] 淇濆瓨鎸囩汗鍑瘉缁撴灉:', voucherRet)
+ logger.info('[api] 鎸囩汗淇℃伅澶勭悊瀹屾垚:', person.userId)
+ } catch (error) {
+ logger.error('[api] 澶勭悊鎸囩汗淇℃伅閿欒:', error)
+ errorItem.errmsg = "澶勭悊鎸囩汗淇℃伅閿欒: " + error.message
+ errors.push(errorItem)
+ continue
+ }
+ }
+
+ // 澶勭悊NFC鍗′俊鎭�
+ if (person.nfcCard) {
+ try {
+ logger.info('[api] 寮�濮嬪鐞哊FC鍗′俊鎭�:', person.userId)
+
+ // 妫�鏌FC鍗℃槸鍚﹂噸澶�
+ let existingVoucher = sqliteService.d1_voucher.findByCodeAndType(person.nfcCard, "200")
+ if (existingVoucher.length > 0 && existingVoucher[0].userId != person.userId) {
+ errorItem.errmsg = "NFC鍗″凡琚叾浠栫敤鎴蜂娇鐢�"
+ errors.push(errorItem)
+ continue
+ }
+
+ // 淇濆瓨NFC鍗″嚟璇�
+ logger.info('[api] 淇濆瓨NFC鍗″嚟璇�:', person.userId)
+ let voucherRet = sqliteService.d1_voucher.save({
+ keyId: std.genRandomStr(32),
+ type: "200",
+ code: person.nfcCard.toUpperCase(),
+ userId: person.userId,
+ extra: JSON.stringify({ type: 0 })
+ });
+ logger.info('[api] 淇濆瓨NFC鍗″嚟璇佺粨鏋�:', voucherRet)
+ logger.info('[api] NFC鍗′俊鎭鐞嗗畬鎴�:', person.userId)
+ } catch (error) {
+ logger.error('[api] 澶勭悊NFC鍗′俊鎭敊璇�:', error)
+ errorItem.errmsg = "澶勭悊NFC鍗′俊鎭敊璇�: " + error.message
+ errors.push(errorItem)
+ continue
+ }
+ }
+
+ // 涓虹敤鎴锋坊鍔犳潈闄�
+ try {
+ // 鑾峰彇鐢ㄦ埛绫诲瀷
+ let userType = 0
+ if (person.extra) {
+ try {
+ userType = person.extra.type || 0
+ } catch (error) {
+ logger.error('[api] 瑙f瀽鐢ㄦ埛绫诲瀷澶辫触:', error)
+ }
+ }
+
+ // 鍙湁淇濈鍛橈紙0锛夊拰绉戦暱锛�1锛夐渶瑕佹坊鍔犳潈闄�
+ if (userType == 0 || userType == 1) {
+ // 妫�鏌ユ槸鍚﹀凡瀛樺湪鏉冮檺璁板綍
+ let existingPermissions = sqliteService.d1_permission.findByUserId(person.userId)
+ if (existingPermissions && existingPermissions.length == 0) {
+ // 娣诲姞姘镐箙鏉冮檺
+ let permissionId = std.genRandomStr(32)
+ let permissionRet = sqliteService.d1_permission.save({
+ permissionId: permissionId,
+ userId: person.userId,
+ door: "", // 绌哄瓧绗︿覆琛ㄧず鎵�鏈夐棬
+ timeType: 0, // 姘镐箙鏉冮檺
+ beginTime: 0,
+ endTime: 0,
+ period: ""
+ });
+ logger.info('[api] 涓虹敤鎴锋坊鍔犳潈闄愮粨鏋�:', permissionRet)
+
+ // 鏇存柊浜哄憳琛ㄤ腑鐨刾ermissionIds瀛楁
+ if (permissionRet == 0) {
+ // 鏋勫缓鏇存柊璁板綍
+ let updateRecord = { permissionIds: permissionId }
+ // 浣跨敤updateAllByUserId鏂规硶鏇存柊
+ let updateRet = sqliteService.d1_person.updateAllByUserId(updateRecord, person.userId)
+ logger.info('[api] 鏇存柊浜哄憳鏉冮檺ID缁撴灉:', updateRet)
+ }
+ } else {
+ logger.info('[api] 鐢ㄦ埛宸插瓨鍦ㄦ潈闄愯褰曪紝璺宠繃鏉冮檺娣诲姞:', person.userId)
+ }
+ } else {
+ logger.info('[api] 鐢ㄦ埛绫诲瀷涓嶉渶瑕佹坊鍔犳潈闄愶紝璺宠繃鏉冮檺娣诲姞:', person.userId)
+ }
+ } catch (error) {
+ logger.error('[api] 娣诲姞鏉冮檺鏃跺嚭閿�:', error)
}
}
if (errors.length > 0) {
@@ -438,6 +650,14 @@
userId: userId || 'unknown',
errmsg: ''
}
+ try {
+ // 鍒犻櫎浜鸿劯鏁版嵁
+ driver.face.deleteFea(userId)
+ logger.info('[api] 鍒犻櫎浜鸿劯鏁版嵁鎴愬姛:', userId)
+ } catch (error) {
+ logger.error(`Failed to delete face feature for user ${userId}:`, error)
+ }
+
// 鍒犻櫎鎸囩汗鍑瘉涔嬪墠闇�瑕佸厛鍒犻櫎鎸囩汗搴撲腑鐨勬寚绾�
let fingerVoucher = sqliteService.d1_voucher.findByuserIdAndType(userId, "500")
if (fingerVoucher.length > 0) {
@@ -448,19 +668,18 @@
errors.push(errorItem)
continue
}
+ logger.info('[api] 鍒犻櫎鎸囩汗鏁版嵁鎴愬姛:', userId)
}
+
let ret1 = sqliteService.d1_person.deleteByUserId(userId)
let ret3 = sqliteService.d1_voucher.deleteByUserId(userId)
- if (ret1 != 0 || ret3 != 0) {
- errorItem.errmsg = `sql error: person(${ret1}), voucher(${ret3})`
+ let ret4 = sqliteService.d1_permission.deleteByUserId(userId)
+ if (ret1 != 0 || ret3 != 0 || ret4 != 0) {
+ errorItem.errmsg = `sql error: person(${ret1}), voucher(${ret3}), permission(${ret4})`
errors.push(errorItem)
continue
}
- try {
- driver.face.deleteFea(userId)
- } catch (error) {
- logger.error(`Failed to delete face feature for user ${userId}:`, error)
- }
+ logger.info('[api] 鍒犻櫎浜哄憳鎴愬姛:', userId)
}
}
if (errors.length > 0) {
@@ -479,6 +698,19 @@
}
let totalCount = sqliteService.d1_person.count(data)
let persons = sqliteService.d1_person.findAll(data)
+
+ // 灏唀xtra瀛楁浠嶫SON瀛楃涓茶В鏋愪负JSON瀵硅薄
+ persons.forEach(person => {
+ if (person.extra && typeof person.extra === 'string') {
+ try {
+ person.extra = JSON.parse(person.extra)
+ } catch (error) {
+ // 濡傛灉瑙f瀽澶辫触锛屼繚鎸佸師鏍�
+ console.error('瑙f瀽extra瀛楁澶辫触:', error)
+ }
+ }
+ })
+
return {
content: persons,
page: data.page,
@@ -573,10 +805,18 @@
if (voucher.type == "200" || voucher.type == "201" || voucher.type == "202") {
voucher.code = voucher.code.toUpperCase()
}
- if (voucher.type == "300" && voucher.extra.faceType != 0 && voucher.extra.faceType != 1) {
- errorItem.errmsg = "faceType Incorrect format"
- errors.push(errorItem)
- continue
+ if (voucher.type == "300") {
+ if (voucher.extra) {
+ if (voucher.extra.faceType != 0 && voucher.extra.faceType != 1) {
+ errorItem.errmsg = "faceType Incorrect format"
+ errors.push(errorItem)
+ continue
+ }
+ } else {
+ errorItem.errmsg = "faceType is required"
+ errors.push(errorItem)
+ continue
+ }
}
if (voucher.type == "400") {
if (voucher.code.length != 6) {
@@ -585,17 +825,6 @@
continue
}
}
- // // 鍒ゆ柇鎸囩汗鍑瘉鏄惁閲嶅锛屽鏋滄病鏈夐噸澶嶅氨褰曞叆鎸囩汗
- // if (voucher.type == "500") {
- // voucher.code = parseInt(voucher.code)
- // let index = driver.finger.insert(voucher.code)
- // if(index < 0){
- // errorItem.errmsg = "finger insert error ret:" + index
- // errors.push(errorItem)
- // continue
- // }
- // voucher.code = index
- // }
let record = {}
record.keyId = voucher.keyId
record.type = voucher.type
@@ -755,8 +984,17 @@
let totalCount = sqliteService.d1_voucher.count(data)
let vouchers = sqliteService.d1_voucher.findAll(data)
vouchers.forEach(element => {
- if (element.type == 300 && element.extra && JSON.parse(element.extra).faceType == 0) {
- //浜鸿劯鐗规畩澶勭悊涓�涓�
+ // 灏唀xtra瀛楁浠嶫SON瀛楃涓茶В鏋愪负JSON瀵硅薄
+ if (element.extra && typeof element.extra === 'string') {
+ try {
+ element.extra = JSON.parse(element.extra)
+ } catch (error) {
+ // 濡傛灉瑙f瀽澶辫触锛屼繚鎸佸師鏍�
+ console.error('瑙f瀽extra瀛楁澶辫触:', error)
+ }
+ }
+ // 浜鸿劯鐗规畩澶勭悊涓�涓�
+ if (element.type == 300 && element.extra && element.extra.faceType == 0) {
element.code = dxCommonUtils.fs.fileToBase64(element.code)
}
});
@@ -1217,7 +1455,7 @@
return true
}
-//娓呯┖鏉冮檺
+// 娓呯┖鏉冮檺
api.clearPermission = function () {
let ret = sqliteService.d1_permission.deleteAll()
if (ret == 0) {
@@ -1225,28 +1463,6 @@
} else {
return "sql error "
}
-}
-
-// 鍒ょ┖
-function isEmpty(value) {
- return value === undefined || value === null || value === ""
-}
-
-// 婵�娲讳簯璇�
-api.eidActive = function (data) {
- if (data.code && data.code.startsWith("___VBAR_ID_ACTIVE_V")) {
- try {
- let activeResute = driver.nfc.eidActive(data.code);
- if (activeResute != 0) {
- return 'Activation failed'
- }
- } catch (error) {
- return error.message
- }
- } else {
- return 'The key format is incorrect'
- }
- return true
}
// 鏂板瀵嗛挜
@@ -1299,9 +1515,9 @@
// 鍒犻櫎瀵嗛挜
api.delSecurity = function (data) {
let errors = []
- if (data.length > 0) {
- for (let i = 0; i < data.length; i++) {
- const securityId = data[i];
+ if (data.securityIds && data.securityIds.length > 0) {
+ for (let i = 0; i < data.securityIds.length; i++) {
+ const securityId = data.securityIds[i];
let errorItem = {
securityId: securityId || 'unknown',
errmsg: ''
@@ -1326,8 +1542,142 @@
if (ret == 0) {
return true
} else {
- return "sql error "
+ return "sql error ret:" + ret
}
}
+// 娣诲姞搴旀�ュ紑浠撳瘑鐮�
+api.insertEmergencyPassword = function (data) {
+ // 搴旀�ュ紑浠撳瘑鐮佸湪璁惧涓粎鏈夊敮涓�鐨�1涓紝鎵�浠ュ厛娓呯┖琛�
+ let deleteRet = sqliteService.d1_emergency_password.deleteAll()
+ if (deleteRet != 0) {
+ return "娓呯┖鏃у瘑鐮佸け璐�: " + deleteRet
+ }
+
+ // 妫�鏌ュ瘑鐮佹槸鍚︽湁鏁�
+ if (!data.password) {
+ return "password cannot be empty"
+ }
+
+ // 妫�鏌ュ瘑鐮侀暱搴︽槸鍚﹀ぇ浜庣瓑浜�8浣�
+ if (data.password.length < 8) {
+ return "Password length must be at least 8 digits"
+ }
+
+ // 鏋勫缓瀵嗙爜璁板綍
+ let record = {}
+ record.id = data.id || 'emergency_' + Date.now() // 濡傛灉娌℃湁id锛岃嚜鍔ㄧ敓鎴�
+ record.password = data.password
+ record.description = data.description || "浜戠涓嬪彂" // 濡傛灉娌℃湁浼犲叆description锛岄粯璁や负"浜戠涓嬪彂"锛圡QTT鍜孒TTP鎺ュ彛璁剧疆鐨勬儏鍐碉級
+ record.createTime = Date.now()
+ record.updateTime = Date.now()
+ record.status = data.status || 1
+
+ // 淇濆瓨瀵嗙爜
+ let ret = sqliteService.d1_emergency_password.save(record)
+ if (ret == 0) {
+ return true
+ } else {
+ return "sql error ret:" + ret
+ }
+}
+
+// 娓呯┖瀵嗛挜
+api.clearSecurity = function () {
+ let ret = sqliteService.d1_security.deleteAll()
+ if (ret == 0) {
+ return true
+ } else {
+ return "sql error ret:" + ret
+ }
+}
+
+// 娣诲姞搴旀�ュ紑浠撳瘑鐮�
+api.insertEmergencyPassword = function (data) {
+ // 搴旀�ュ紑浠撳瘑鐮佸湪璁惧涓粎鏈夊敮涓�鐨�1涓紝鎵�浠ュ厛娓呯┖琛�
+ let deleteRet = sqliteService.d1_emergency_password.deleteAll()
+ if (deleteRet != 0) {
+ return "娓呯┖鏃у瘑鐮佸け璐�: " + deleteRet
+ }
+
+ // 妫�鏌ュ瘑鐮佹槸鍚︽湁鏁�
+ if (!data.password) {
+ return "password cannot be empty"
+ }
+
+ // 妫�鏌ュ瘑鐮侀暱搴︽槸鍚﹀ぇ浜庣瓑浜�8浣�
+ if (data.password.length < 8) {
+ return "Password length must be at least 8 digits"
+ }
+
+ // 鏋勫缓瀵嗙爜璁板綍
+ let record = {}
+ record.id = data.id || 'emergency_' + Date.now() // 濡傛灉娌℃湁id锛岃嚜鍔ㄧ敓鎴�
+ record.password = data.password
+ record.description = data.description || "浜戠涓嬪彂" // 濡傛灉娌℃湁浼犲叆description锛岄粯璁や负"浜戠涓嬪彂"锛圡QTT鍜孒TTP鎺ュ彛璁剧疆鐨勬儏鍐碉級
+ record.createTime = Date.now()
+ record.updateTime = Date.now()
+ record.status = data.status || 1
+
+ // 淇濆瓨瀵嗙爜
+ let ret = sqliteService.d1_emergency_password.save(record)
+ if (ret == 0) {
+ return true
+ } else {
+ return "sql error ret:" + ret
+ }
+}
+
+// 鏌ヨ搴旀�ュ紑浠撳瘑鐮�
+api.getEmergencyPassword = function () {
+ let passwords = sqliteService.d1_emergency_password.findAll()
+ if (passwords && passwords.length > 0) {
+ let password = passwords[0];
+ // 杞崲鏃堕棿鎴充负瀛楃涓叉牸寮�
+ if (password.createTime) {
+ // 灏濊瘯灏哻reateTime杞崲涓烘暟瀛�
+ const createTimeNum = Number(password.createTime);
+ if (!isNaN(createTimeNum)) {
+ password.createTime = timestampToDateString(createTimeNum);
+ }
+ }
+ if (password.updateTime) {
+ // 灏濊瘯灏唘pdateTime杞崲涓烘暟瀛�
+ const updateTimeNum = Number(password.updateTime);
+ if (!isNaN(updateTimeNum)) {
+ password.updateTime = timestampToDateString(updateTimeNum);
+ }
+ }
+ return password;
+ }
+ return {};
+}
+
+// 娓呯┖搴旀�ュ紑浠撳瘑鐮�
+api.clearEmergencyPassword = function () {
+ let ret = sqliteService.d1_emergency_password.deleteAll()
+ if (ret == 0) {
+ return true
+ } else {
+ return "sql error ret:" + ret
+ }
+}
+
+// 鏃堕棿鎴宠浆鏃ユ湡瀛楃涓�
+function timestampToDateString(timestamp) {
+ const date = new Date(timestamp);
+ const year = date.getFullYear();
+ const month = String(date.getMonth() + 1).padStart(2, '0');
+ const day = String(date.getDate()).padStart(2, '0');
+ const hours = String(date.getHours()).padStart(2, '0');
+ const minutes = String(date.getMinutes()).padStart(2, '0');
+ const seconds = String(date.getSeconds()).padStart(2, '0');
+ return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
+}
+
+// 鍒ょ┖
+function isEmpty(value) {
+ return value === undefined || value === null || value === ""
+}
+
export default api
\ No newline at end of file
diff --git a/vf107/src/service/configService.js b/vf107/src/service/configService.js
index 46b9175..15d5d2d 100644
--- a/vf107/src/service/configService.js
+++ b/vf107/src/service/configService.js
@@ -212,6 +212,12 @@
tamper: validators.switch,
uploadToCloud: validators.switch
},
+ gas: {
+ verification: validators.switch
+ },
+ http: {
+ safeInputAccess: validators.string
+ },
base: {
firstLogin: validators.switch,
backlight: validators.percentage,
@@ -315,6 +321,13 @@
// 楠岃瘉骞舵敹闆嗛厤缃」
for (const [section, sectionData] of Object.entries(data)) {
+ // 澶勭悊椤剁骇閰嶇疆椤癸紙闈炲垎缁勯厤缃級
+ if (typeof sectionData !== 'object' || sectionData === null) {
+ // 鐩存帴淇濆瓨椤剁骇閰嶇疆椤�
+ configsToSave.push({ section: '', key: section, value: sectionData })
+ continue
+ }
+
for (let [key, value] of Object.entries(sectionData)) {
// 楠岃瘉閰嶇疆椤�
validateConfig(section, key, value)
@@ -341,7 +354,8 @@
// 鎵归噺淇濆瓨閰嶇疆
configsToSave.forEach(({ section, key, value }) => {
- config.set(`${section}.${key}`, value)
+ const configKey = section ? `${section}.${key}` : key
+ config.set(configKey, value)
})
config.save()
diff --git a/vf107/src/service/demo.js b/vf107/src/service/demo.js
new file mode 100644
index 0000000..beb7a4e
--- /dev/null
+++ b/vf107/src/service/demo.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/vf107/src/service/grainService.js b/vf107/src/service/grainService.js
index ee4a283..a182a10 100644
--- a/vf107/src/service/grainService.js
+++ b/vf107/src/service/grainService.js
@@ -36,7 +36,7 @@
"401": "鏈櫥褰曪紝鐢ㄦ埛涓嶅瓨鍦�",
"403": "鐢ㄦ埛鏃犳潈闄�",
"404": "璇锋眰鍔熻兘涓嶅瓨鍦�",
- "500": "璇锋眰鎵ц寮傚父锛岃鑱旂郴绠$悊鍛�"
+ "500": "璇锋眰鎵ц寮傚父锛岃鑱旂郴绉戦暱"
}
// 鎿嶄綔鎸夐挳瀵瑰簲鐨勮闊虫枃浠�
diff --git a/vf107/src/service/httpService.js b/vf107/src/service/httpService.js
index 0fb560e..caeb8b0 100644
--- a/vf107/src/service/httpService.js
+++ b/vf107/src/service/httpService.js
@@ -172,7 +172,20 @@
server.route("/clearSecurity", function (req, res) {
clearSecurity(req, res);
});
-
+
+ //娣诲姞搴旀�ュ紑浠撳瘑鐮�
+ server.route("/insertEmergencyPassword", function (req, res) {
+ insertEmergencyPassword(req, res);
+ });
+ //鏌ヨ搴旀�ュ紑浠撳瘑鐮�
+ server.route("/getEmergencyPassword", function (req, res) {
+ getEmergencyPassword(req, res);
+ });
+ //娓呯┖搴旀�ュ紑浠撳瘑鐮�
+ server.route("/clearEmergencyPassword", function (req, res) {
+ clearEmergencyPassword(req, res);
+ });
+
//鑾峰彇鎸囩汗鐗瑰緛
server.route("/getFingerChar", function (req, res) {
getFingerChar(req, res);
@@ -1001,6 +1014,77 @@
res.send(JSON.stringify(result), { "Content-Type": "application/json" });
}
+// 娣诲姞搴旀�ュ紑浠撳瘑鐮�
+function insertEmergencyPassword(req, res) {
+ let result = {
+ code: 400,
+ message: "",
+ data: {},
+ }
+ if (verifyToken(req)) {
+ let body = req.body;
+ body = JSON.parse(body).data;
+ try {
+ let res = api.insertEmergencyPassword(body)
+ if (typeof res == 'string') {
+ result.data = res
+ } else {
+ result.code = 200
+ }
+ } catch (error) {
+ result.message = error.message
+ }
+ } else {
+ result = messageExpired
+ }
+ res.send(JSON.stringify(result), { "Content-Type": "application/json" });
+}
+
+// 鏌ヨ搴旀�ュ紑浠撳瘑鐮�
+function getEmergencyPassword(req, res) {
+ let result = {
+ code: 400,
+ message: "",
+ data: {},
+ }
+ if (verifyToken(req)) {
+ try {
+ let res = api.getEmergencyPassword()
+ result.code = 200
+ result.data = res
+ } catch (error) {
+ result.message = error.message
+ }
+ } else {
+ result = messageExpired
+ }
+ res.send(JSON.stringify(result), { "Content-Type": "application/json" });
+}
+
+// 娓呯┖搴旀�ュ紑浠撳瘑鐮�
+function clearEmergencyPassword(req, res) {
+ let result = {
+ code: 400,
+ message: "",
+ data: {},
+ }
+ if (verifyToken(req)) {
+ try {
+ let res = api.clearEmergencyPassword()
+ if (typeof res == 'string') {
+ result.data = res
+ } else {
+ result.code = 200
+ }
+ } catch (error) {
+ result.message = error.message
+ }
+ } else {
+ result = messageExpired
+ }
+ res.send(JSON.stringify(result), { "Content-Type": "application/json" });
+}
+
// 鑾峰彇鎸囩汗鐗瑰緛
function getFingerChar(req,res) {
let result = {
diff --git a/vf107/src/service/mqttService.js b/vf107/src/service/mqttService.js
index b582aa4..61721b4 100644
--- a/vf107/src/service/mqttService.js
+++ b/vf107/src/service/mqttService.js
@@ -42,7 +42,7 @@
*/
mqttService.insertPermission = function (event) {
let payload = JSON.parse(event.payload)
- let data = payload.data
+ let data = payload.payload && payload.payload.data ? payload.payload.data : payload.data
if (data.length > 100) {
return reply(event, "data length should not be greater than 100", CODE.E_100)
}
@@ -58,7 +58,7 @@
*/
mqttService.getPermission = function (event) {
let payload = JSON.parse(event.payload)
- let data = payload.data
+ let data = payload.payload && payload.payload.data ? payload.payload.data : payload.data
let res = api.getPermission(data)
return reply(event, res)
}
@@ -68,7 +68,7 @@
*/
mqttService.delPermission = function (event) {
let payload = JSON.parse(event.payload)
- let data = payload.data
+ let data = payload.payload && payload.payload.data ? payload.payload.data : payload.data
let res = api.delPermission(data)
if (Array.isArray(res)) {
return reply(event, res, CODE.E_100)
@@ -81,7 +81,7 @@
*/
mqttService.modifyPermission = function (event) {
let payload = JSON.parse(event.payload)
- let data = payload.data
+ let data = payload.payload && payload.payload.data ? payload.payload.data : payload.data
if (data.length > 100) {
return reply(event, "data length should not be greater than 100", CODE.E_100)
}
@@ -111,7 +111,7 @@
*/
mqttService.insertUser = function (event) {
let payload = JSON.parse(event.payload)
- let data = payload.data
+ let data = payload.payload && payload.payload.data ? payload.payload.data : payload.data
if (data.length > 100) {
return reply(event, "data length should not be greater than 100", CODE.E_100)
}
@@ -128,7 +128,7 @@
*/
mqttService.getUser = function (event) {
let payload = JSON.parse(event.payload)
- let data = payload.data
+ let data = payload.payload && payload.payload.data ? payload.payload.data : payload.data
let res = api.getUser(data)
return reply(event, res)
}
@@ -138,7 +138,7 @@
*/
mqttService.delUser = function (event) {
let payload = JSON.parse(event.payload)
- let data = payload.data
+ let data = payload.payload && payload.payload.data ? payload.payload.data : payload.data
let res = api.delUser(data)
if (Array.isArray(res)) {
return reply(event, res, CODE.E_100)
@@ -163,7 +163,7 @@
*/
mqttService.modifyUser = function (event) {
let payload = JSON.parse(event.payload)
- let data = payload.data
+ let data = payload.payload && payload.payload.data ? payload.payload.data : payload.data
if (data.length > 100) {
return reply(event, "data length should not be greater than 100", CODE.E_100)
}
@@ -171,7 +171,7 @@
if (Array.isArray(res)) {
return reply(event, res, CODE.E_100)
}
- return reply(event, res)
+ return reply(event)
}
// =================================鍑瘉澧炲垹鏀规煡=================================
@@ -180,7 +180,7 @@
*/
mqttService.insertKey = function (event) {
let payload = JSON.parse(event.payload)
- let data = payload.data
+ let data = payload.payload && payload.payload.data ? payload.payload.data : payload.data
if (data.length > 100) {
return reply(event, "data length should not be greater than 100", CODE.E_100)
}
@@ -196,7 +196,7 @@
*/
mqttService.getKey = function (event) {
let payload = JSON.parse(event.payload)
- let data = payload.data
+ let data = payload.payload && payload.payload.data ? payload.payload.data : payload.data
let res = api.getKey(data)
if (typeof res == 'string') {
return reply(event, res, CODE.E_100)
@@ -209,7 +209,7 @@
*/
mqttService.delKey = function (event) {
let payload = JSON.parse(event.payload)
- let data = payload.data
+ let data = payload.payload && payload.payload.data ? payload.payload.data : payload.data
let res = api.delKey(data)
if (Array.isArray(res)) {
return reply(event, res, CODE.E_100)
@@ -223,7 +223,7 @@
*/
mqttService.clearKey = function (event) {
let payload = JSON.parse(event.payload)
- let data = payload.data
+ let data = payload.payload && payload.payload.data ? payload.payload.data : payload.data
let ret = api.clearKey(data)
if (typeof ret == "string") {
return reply(event, "sql error ret:" + ret, CODE.E_100)
@@ -237,7 +237,7 @@
*/
mqttService.modifyKey = function (event) {
let payload = JSON.parse(event.payload)
- let data = payload.data
+ let data = payload.payload && payload.payload.data ? payload.payload.data : payload.data
if (data.length > 100) {
return reply(event, "data length should not be greater than 100", CODE.E_100)
}
@@ -249,13 +249,163 @@
}
+
+// =================================搴旀�ュ紑浠撳瘑鐮佸鍒犳敼鏌�=================================
+/**
+ * 娣诲姞搴旀�ュ紑浠撳瘑鐮�
+ * @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 = "浜戠涓嬪彂" // 閫氳繃MQTT鍜孒TTP鎺ュ彛璁剧疆鐨勫簲鎬ュ紑浠撳瘑鐮侊紝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)
+ }
+}
+
+/**
+ * 鏌ヨ搴旀�ュ紑浠撳瘑鐮侀�氱敤鍗忚鏍煎紡
+ * @returns {object} 鏌ヨ缁撴灉
+ */
+mqttService.getEmergencyPasswordAgreement = function () {
+ let passwords = sqliteService.d1_emergency_password.findAll()
+ if (passwords && passwords.length > 0) {
+ let password = passwords[0];
+ // 杞崲鏃堕棿鎴充负瀛楃涓叉牸寮�
+ if (password.createTime) {
+ // 灏濊瘯灏哻reateTime杞崲涓烘暟瀛�
+ const createTimeNum = Number(password.createTime);
+ if (!isNaN(createTimeNum)) {
+ // 妫�鏌ユ椂闂存埑鏄惁涓烘绉掔骇锛堝ぇ浜庣瓑浜�10浣嶏級
+ if (createTimeNum.toString().length >= 10) {
+ // 宸茬粡鏄绉掔骇锛岃浆鎹负绉掔骇
+ password.createTime = timestampToDateString(createTimeNum / 1000);
+ } else {
+ // 绉掔骇锛岀洿鎺ヤ娇鐢�
+ password.createTime = timestampToDateString(createTimeNum);
+ }
+ }
+ }
+ if (password.updateTime) {
+ // 灏濊瘯灏唘pdateTime杞崲涓烘暟瀛�
+ const updateTimeNum = Number(password.updateTime);
+ if (!isNaN(updateTimeNum)) {
+ // 妫�鏌ユ椂闂存埑鏄惁涓烘绉掔骇锛堝ぇ浜庣瓑浜�10浣嶏級
+ if (updateTimeNum.toString().length >= 10) {
+ // 宸茬粡鏄绉掔骇锛岃浆鎹负绉掔骇
+ password.updateTime = timestampToDateString(updateTimeNum / 1000);
+ } else {
+ // 绉掔骇锛岀洿鎺ヤ娇鐢�
+ password.updateTime = timestampToDateString(updateTimeNum);
+ }
+ }
+ }
+ 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)
+ }
+}
+
+
// =================================瀵嗛挜澧炲垹鏀规煡=================================
/**
* 娣诲姞瀵嗛挜
*/
mqttService.insertSecurity = function (event) {
let payload = JSON.parse(event.payload)
- let data = payload.data
+ let data = payload.payload && payload.payload.data ? payload.payload.data : payload.data
if (data.length > 100) {
return reply(event, "data length should not be greater than 100", CODE.E_100)
}
@@ -271,7 +421,7 @@
*/
mqttService.getSecurity = function (event) {
let payload = JSON.parse(event.payload)
- let data = payload.data
+ let data = payload.payload && payload.payload.data ? payload.payload.data : payload.data
let res = api.getSecurity(data)
if (typeof res == 'string') {
return reply(event, res, CODE.E_100)
@@ -284,7 +434,7 @@
*/
mqttService.delSecurity = function (event) {
let payload = JSON.parse(event.payload)
- let data = payload.data
+ let data = payload.payload && payload.payload.data ? payload.payload.data : payload.data
let res = api.delSecurity(data)
if (Array.isArray(res)) {
return reply(event, res, CODE.E_100)
@@ -304,24 +454,230 @@
}
}
+
+// =================================搴旀�ュ紑浠撳瘑鐮佸鍒犳敼鏌�=================================
+/**
+ * 娣诲姞搴旀�ュ紑浠撳瘑鐮�
+ * @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 = "浜戠涓嬪彂" // 閫氳繃MQTT鍜孒TTP鎺ュ彛璁剧疆鐨勫簲鎬ュ紑浠撳瘑鐮侊紝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)
+ }
+}
+
+/**
+ * 鏌ヨ搴旀�ュ紑浠撳瘑鐮侀�氱敤鍗忚鏍煎紡
+ * @returns {object} 鏌ヨ缁撴灉
+ */
+mqttService.getEmergencyPasswordAgreement = function () {
+ let passwords = sqliteService.d1_emergency_password.findAll()
+ if (passwords && passwords.length > 0) {
+ let password = passwords[0];
+ // 杞崲鏃堕棿鎴充负瀛楃涓叉牸寮�
+ if (password.createTime) {
+ // 灏濊瘯灏哻reateTime杞崲涓烘暟瀛�
+ const createTimeNum = Number(password.createTime);
+ if (!isNaN(createTimeNum)) {
+ // 妫�鏌ユ椂闂存埑鏄惁涓烘绉掔骇锛堝ぇ浜庣瓑浜�10浣嶏級
+ if (createTimeNum.toString().length >= 10) {
+ // 宸茬粡鏄绉掔骇锛岃浆鎹负绉掔骇
+ password.createTime = timestampToDateString(createTimeNum / 1000);
+ } else {
+ // 绉掔骇锛岀洿鎺ヤ娇鐢�
+ password.createTime = timestampToDateString(createTimeNum);
+ }
+ }
+ }
+ if (password.updateTime) {
+ // 灏濊瘯灏唘pdateTime杞崲涓烘暟瀛�
+ const updateTimeNum = Number(password.updateTime);
+ if (!isNaN(updateTimeNum)) {
+ // 妫�鏌ユ椂闂存埑鏄惁涓烘绉掔骇锛堝ぇ浜庣瓑浜�10浣嶏級
+ if (updateTimeNum.toString().length >= 10) {
+ // 宸茬粡鏄绉掔骇锛岃浆鎹负绉掔骇
+ password.updateTime = timestampToDateString(updateTimeNum / 1000);
+ } else {
+ // 绉掔骇锛岀洿鎺ヤ娇鐢�
+ password.updateTime = timestampToDateString(updateTimeNum);
+ }
+ }
+ }
+ 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.control = function (event) {
- let payload = JSON.parse(event.payload)
- let ret = api.control(payload)
- // 杩滅▼鎶撴媿銆佷紒涓氬井淇¤В缁戯紝闇�瑕佺瓑娴佺▼瀹屾垚鍚庢墠鍥炲锛屼笉鑳界珛鍗冲洖澶�
- if (payload.data.command != 8 && payload.data.command != 11) {
- // 濡傛灉鏄寚绾规搷浣滐紝浣嗘槸璁惧涓嶆敮鎸佹寚绾圭殑璇濓紝灏辩洿鎺ヨ繑鍥為敊璇�
- if(payload.data.command == 12 && !driver.device.finger){
- return reply(event, "finger not supported", CODE.E_100)
- }
- if (typeof ret == "string") {
- return reply(event, "unknown failure", CODE.E_100)
- } else {
+ 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)
}
- }
}
/**
@@ -343,7 +699,7 @@
*/
mqttService.setConfig = function (event) {
let payload = JSON.parse(event.payload)
- let data = payload.data
+ let data = payload.payload && payload.payload.data ? payload.payload.data : payload.data
let res = api.setConfig(data)
if (typeof res == "string") {
return reply(event, res, CODE.E_100)
@@ -356,8 +712,9 @@
* 鍗囩骇鍥轰欢
*/
mqttService.upgradeFirmware = function (event) {
+ logger.info('[mqttService] 鎺ユ敹鍒板崌绾у浐浠跺懡浠�:', JSON.stringify(event.topic))
let payload = JSON.parse(event.payload)
- let data = payload.data
+ let data = payload.payload && payload.payload.data ? payload.payload.data : payload.data
let res = api.upgradeFirmware(data)
if (typeof res == "string") {
return reply(event, res, CODE.E_100)
@@ -371,7 +728,7 @@
*/
mqttService.getRecords = function (event) {
let payload = JSON.parse(event.payload)
- let data = payload.data
+ let data = payload.payload && payload.payload.data ? payload.payload.data : payload.data
let res = api.getRecords(data, true)
return reply(event, res)
}
@@ -382,7 +739,7 @@
*/
mqttService.delRecords = function (event) {
let payload = JSON.parse(event.payload)
- let data = payload.data
+ let data = payload.payload && payload.payload.data ? payload.payload.data : payload.data
let res = api.delRecords(data)
if (typeof res == 'string') {
return reply(event, res, CODE.E_100)
@@ -487,6 +844,23 @@
}
mqttService.mqttReply = mqttReply
+/**
+ * 鏃堕棿鎴宠浆鏃ユ湡瀛楃涓�
+ * @param {number} timestamp - 鏃堕棿鎴筹紙绉掔骇锛�
+ * @returns {string} 鏃ユ湡瀛楃涓诧紝鏍煎紡锛歒YYY-MM-DD HH:MM:SS
+ */
+function timestampToDateString(timestamp) {
+ const date = new Date(timestamp * 1000);
+ 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}`;
+}
+mqttService.timestampToDateString = timestampToDateString
+
// 鍒ょ┖
function isEmpty(value) {
return value === undefined || value === null || value === ""
diff --git a/vf107/src/service/sqliteService.js b/vf107/src/service/sqliteService.js
index d5fcd26..9b41ded 100644
--- a/vf107/src/service/sqliteService.js
+++ b/vf107/src/service/sqliteService.js
@@ -29,9 +29,11 @@
extra: "TEXT",
extra2: "TEXT",
message: "TEXT",
+ reported: "INTEGER DEFAULT 0",
},
d1_permission: {
permissionId: "VARCHAR(128) PRIMARY KEY",
+ userId: "VARCHAR(128)",
door: "VARCHAR(128)",
extra: "TEXT",
timeType: "INTEGER",
@@ -59,6 +61,14 @@
name: "VARCHAR(128)",
extra: "TEXT",
permissionIds: "TEXT",
+ },
+ d1_emergency_password: {
+ id: "VARCHAR(128) PRIMARY KEY",
+ password: "VARCHAR(128)",
+ description: "TEXT",
+ createTime: "INTEGER",
+ updateTime: "INTEGER",
+ status: "INTEGER",
}
}
@@ -133,6 +143,7 @@
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);
// 鎸夊鍚嶆ā绯婃煡璇汉鍛�
sqliteService.findPersonsByNameLike = function (name) {
@@ -165,6 +176,11 @@
return sqliteService.select(query)
}
+// 鏌ヨ鎵�鏈夋湭涓婃姤鐨勯�氳璁板綍锛堟寜鏃堕棿鍗囧簭锛�
+sqliteService.d1_pass_record.findAllByReportedOrderByTimeStampAsc = function () {
+ const sql = `SELECT * FROM d1_pass_record WHERE reported = 0 OR reported IS NULL ORDER BY timeStamp ASC;`
+ return sqliteService.select(sql)
+}
// 寮�濮嬩簨鍔★紝浜嬪姟涓嶆彁浜ゆ暟鎹簱閲嶅惎鍚庯紝鏁版嵁浼氳繕鍘燂紝鎵�浠ransaction鍚庝竴瀹氳commit锛屼絾鏄鏋滃湪涓�涓簨鍔″皻鏈彁浜ゆ垨鍥炴粴鐨勬儏鍐典笅鎵ц鍙︿竴涓� BEGIN TRANSACTION锛孲QLite 浼氳嚜鍔ㄥ皢鏂扮殑浜嬪姟宓屽鍦ㄤ箣鍓嶇殑浜嬪姟鍐呴儴锛岃�屼笉鏄鐩栦箣鍓嶇殑浜嬪姟銆�
sqliteService.transaction = function () {
diff --git a/vf107/src/view/config/menu/doorControlView.js b/vf107/src/view/config/menu/doorControlView.js
index 89cb8a7..04e9cb1 100644
--- a/vf107/src/view/config/menu/doorControlView.js
+++ b/vf107/src/view/config/menu/doorControlView.js
@@ -26,6 +26,7 @@
mqttPwdSettingInput.text(configAll['mqtt.password'])
onlineCheckingSettingSwitch.select(configAll['mqtt.onlinecheck'] == 1)
onlineCheckingTimeoutSettingInput.text(configAll['mqtt.timeout'] + '')
+ gasVerificationSwitch.select(configAll['gas.verification'] == 1)
})
const titleBox = viewUtils.title(screenMain, configView.screenMain, 'doorControlViewTitle', 'doorControlView.title')
@@ -224,6 +225,24 @@
onlineCheckingTimeoutSettingInput.align(dxui.Utils.ALIGN.RIGHT_MID, -screen.screenSize.width * (60 / 600), 0)
onlineCheckingTimeoutSettingInput.setSize(screen.screenSize.width * (150 / 600), screen.screenSize.height * (60 / 1280))
+ const gasVerificationBox = dxui.View.build('gasVerificationBox', screenMain)
+ viewUtils._clearStyle(gasVerificationBox)
+ gasVerificationBox.align(dxui.Utils.ALIGN.TOP_MID, 0, screen.screenSize.height * (880 / 1280))
+ gasVerificationBox.setSize(screen.screenSize.width * (550 / 600), screen.screenSize.height * (76 / 1280))
+ gasVerificationBox.borderWidth(1)
+ gasVerificationBox.setBorderColor(0xDEDEDE)
+ gasVerificationBox.obj.setStyleBorderSide(dxui.Utils.ENUM.LV_BORDER_SIDE_BOTTOM, 0)
+
+ const gasVerificationLbl = dxui.Label.build('gasVerificationLbl', gasVerificationBox)
+ gasVerificationLbl.text('姘斾綋娴撳害楠岃瘉')
+ gasVerificationLbl.align(dxui.Utils.ALIGN.LEFT_MID, 0, 0)
+ gasVerificationLbl.textFont(viewUtils.font(26))
+
+ const gasVerificationSwitch = dxui.Switch.build('gasVerificationSwitch', gasVerificationBox)
+ gasVerificationSwitch.align(dxui.Utils.ALIGN.RIGHT_MID, 0, 0)
+ gasVerificationSwitch.setSize(screen.screenSize.width * (70 / 600), screen.screenSize.height * (35 / 1280))
+ gasVerificationSwitch.bgColor(0x000000, NativeObject.APP.NativeComponents.NativeEnum.LV_PART_INDICATOR | NativeObject.APP.NativeComponents.NativeEnum.LV_STATE_CHECKED)
+
const saveBtn = viewUtils.bottomBtn(screenMain, screenMain.id + 'saveBtn', 'doorControlView.save', () => {
const saveConfigData = {
access: {
@@ -235,6 +254,9 @@
},
houseName: houseNameSettingInput.text(),
GranaryName: granaryNameSettingInput.text(),
+ gas: {
+ verification: gasVerificationSwitch.isSelect() ? 1 : 0
+ },
mqtt: {
addr: mqttSettingInput.text(),
username: mqttUserSettingInput.text(),
diff --git a/vf107/src/view/config/menu/localUser/localUserAddView.js b/vf107/src/view/config/menu/localUser/localUserAddView.js
index 6bed5bf..a71c649 100644
--- a/vf107/src/view/config/menu/localUser/localUserAddView.js
+++ b/vf107/src/view/config/menu/localUser/localUserAddView.js
@@ -75,12 +75,6 @@
input: null,
mode: screen.isInternationalVersion() ? 0 : 1
},
- idCard: {
- title: 'localUserAddView.idCard',
- value: null,
- type: 'input',
- input: null
- },
face: {
title: 'localUserAddView.face',
value: null,
@@ -124,7 +118,7 @@
}
}
- const userInfoOrder = ['id', 'name', 'idCard', 'face', 'pwd', 'card', 'finger', 'type']
+ const userInfoOrder = ['id', 'name', 'face', 'pwd', 'card', 'finger', 'type']
userInfoOrder.forEach((key, index) => {
const item = localUserAddView.userInfo[key]
@@ -171,9 +165,6 @@
break;
case 'localUserAddView.name':
localUserAddView.nowUser.name = input.text()
- break;
- case 'localUserAddView.idCard':
- localUserAddView.nowUser.idCard = input.text()
break;
default:
break;
@@ -665,14 +656,6 @@
localUserAddView.userInfo.name.input.text('')
}
-localUserAddView.addIDCard = function (idCard) {
- localUserAddView.userInfo.idCard.input.text(idCard)
- localUserAddView.nowUser.idCard = idCard
-}
-
-localUserAddView.removeIDCard = function () {
- localUserAddView.userInfo.idCard.input.text('')
-}
localUserAddView.addFace = function (face, feature) {
localUserAddView.userInfo.face.facePreview.show()
localUserAddView.userInfo.face.btnEdit.show()
@@ -781,7 +764,6 @@
localUserAddView.removeCard()
localUserAddView.removeID()
localUserAddView.removeName()
- localUserAddView.removeIDCard()
if (flag) {
localUserAddView.saveBtn.align(dxui.Utils.ALIGN.BOTTOM_MID, 0, -screen.screenSize.height * (40 / 1024))
localUserAddView.deleteBtn.show()
diff --git a/vf107/src/view/config/menu/localUserView.js b/vf107/src/view/config/menu/localUserView.js
index 931ca09..0658fb5 100644
--- a/vf107/src/view/config/menu/localUserView.js
+++ b/vf107/src/view/config/menu/localUserView.js
@@ -147,9 +147,6 @@
if (item.name) {
localUserAddView.addName(item.name)
}
- if (item.idCard) {
- localUserAddView.addIDCard(item.idCard)
- }
if (item.face) {
localUserAddView.addFace(item.face,item.feature)
}
diff --git a/vf107/src/view/config/menu/networkSettingView.js b/vf107/src/view/config/menu/networkSettingView.js
index 4b85f13..63b4d87 100644
--- a/vf107/src/view/config/menu/networkSettingView.js
+++ b/vf107/src/view/config/menu/networkSettingView.js
@@ -9,6 +9,9 @@
const net_map = map.get("NET")
const networkSettingView = {}
+networkSettingView.isEditing = false // 鏄惁姝e湪缂栬緫閰嶇疆鐨勬爣蹇椾綅
+networkSettingView.isVisible = false // 鏄惁鍦ㄧ綉缁滈厤缃〉闈㈢殑鏍囧織浣�
+
networkSettingView.init = function () {
/**************************************************鍒涘缓灞忓箷*****************************************************/
const screenMain = dxui.View.build('networkSettingView', dxui.Utils.LAYER.MAIN)
@@ -20,6 +23,8 @@
screenMain.bgColor(0xffffff)
screenMain.on(dxui.Utils.ENUM.LV_EVENT_SCREEN_LOADED, () => {
topView.changeTheme(true)
+ networkSettingView.isEditing = false // 灞忓箷鍔犺浇鏃堕噸缃紪杈戠姸鎬�
+ networkSettingView.isVisible = true // 灞忓箷鍔犺浇鏃惰缃负鍙
const configAll = screen.getConfig()
// Store initial state for comparison on save
@@ -38,6 +43,7 @@
let netList = []
switch (screen.dxDriver.DRIVER.MODEL) {
case "vf105":
+ case "vf107":
netList = [i18n.t('networkSettingView.ethernet'), i18n.t('networkSettingView.wifi')]
break;
case "vf114":
@@ -59,6 +65,8 @@
screenMain.on(dxui.Utils.ENUM.LV_EVENT_SCREEN_UNLOADED, () => {
wifiListBoxClose.send(dxui.Utils.EVENT.CLICK)
+ networkSettingView.isVisible = false // 灞忓箷鍗歌浇鏃惰缃负涓嶅彲瑙�
+ networkSettingView.isEditing = false // 灞忓箷鍗歌浇鏃堕噸缃紪杈戠姸鎬�
})
const titleBox = viewUtils.title(screenMain, configView.screenMain, 'networkSettingViewTitle', 'networkSettingView.title')
@@ -177,6 +185,21 @@
input.setSize(screen.screenSize.width * (310 / 600), screen.screenSize.height * (45 / 1280))
item.input = input
+ // 娣诲姞杈撳叆妗嗙劍鐐逛簨浠剁洃鍚拰鍊煎彉鍖栫洃鍚紝闃叉缂栬緫鏃堕厤缃閲嶇疆
+ input.on(dxui.Utils.EVENT.FOCUSED, () => {
+ networkSettingView.isEditing = true
+ })
+ input.on(dxui.Utils.EVENT.DEFOCUSED, () => {
+ // 鍙湁褰撻厤缃病鏈夊彉鍖栨椂鎵嶈缃甶sEditing涓篺alse
+ if (!networkSettingView._isConfigChanged()) {
+ networkSettingView.isEditing = false
+ }
+ })
+ // 娣诲姞鍊煎彉鍖栫洃鍚紝褰撶敤鎴蜂慨鏀逛簡鍊兼椂璁剧疆isEditing涓簍rue
+ input.on(dxui.Utils.EVENT.VALUE_CHANGED, () => {
+ networkSettingView.isEditing = true
+ })
+
if (item.title === 'networkSettingView.wifiName') {
input.setSize(screen.screenSize.width * (200 / 600), screen.screenSize.height * (45 / 1280))
input.align(dxui.Utils.ALIGN.RIGHT_MID, -screen.screenSize.width * (110 / 600), 0)
@@ -217,6 +240,11 @@
__switch.setSize(screen.screenSize.width * (70 / 600), screen.screenSize.height * (35 / 1280))
__switch.bgColor(0x000000, NativeObject.APP.NativeComponents.NativeEnum.LV_PART_INDICATOR | NativeObject.APP.NativeComponents.NativeEnum.LV_STATE_CHECKED)
item.switch = __switch
+
+ // 娣诲姞寮�鍏充簨浠剁洃鍚紝闃叉鎿嶄綔鏃堕厤缃閲嶇疆
+ __switch.on(dxui.Utils.EVENT.VALUE_CHANGED, () => {
+ networkSettingView.isEditing = true
+ })
}
if (item.type === 'dropdown') {
@@ -233,6 +261,7 @@
if (item.title === 'networkSettingView.type') {
dropdown.on(dxui.Utils.EVENT.VALUE_CHANGED, () => {
+ networkSettingView.isEditing = true
switch (dropdown.getSelected()) {
case 0:
networkSettingView.changeNetType(1)
@@ -406,6 +435,7 @@
const saveBtn = viewUtils.bottomBtn(screenMain, screenMain.id + 'saveBtn', 'networkSettingView.save', () => {
if (!networkSettingView._isConfigChanged()) {
// No changes, just go back
+ networkSettingView.isEditing = false
dxui.loadMain(screenMain.backScreen)
return
}
@@ -527,6 +557,7 @@
networkSettingView.statusPanel.success()
std.setTimeout(() => {
// 鎴愬姛杩斿洖涓婁竴灞傜晫闈�
+ networkSettingView.isEditing = false
dxui.loadMain(screenMain.backScreen)
}, 500)
screen.updateNetStatus("disconnect")
@@ -546,10 +577,7 @@
}
networkSettingView._isConfigChanged = function () {
- //濡傛灉鎵撳紑鐣岄潰鏃剁殑鏁版嵁鍜岀偣鍑讳繚瀛樻寜閽椂鐨勬暟鎹墠鍚庢病鏈夊彂鐢熷彉鍖栵紝灏变笉瑙﹀彂閲嶈繛鍜屾暟鎹繚瀛�
- if (net_map.get("NET_STATUS") != "connected") {
- return true //浣嗘槸鍋囧缃戠粶娌¤繛涓婏紝灏变竴瀹氳瑙﹀彂閲嶈繛鍜屾暟鎹繚瀛�
- }
+ //妫�鏌ラ厤缃槸鍚︾湡鐨勫彂鐢熶簡鍙樺寲锛屾棤璁虹綉缁滅姸鎬佸浣�
const selectedTypeIndex = networkSettingView.netInfo[0].dropdown.getSelected()
let currentType
switch (selectedTypeIndex) {
@@ -633,6 +661,11 @@
}
networkSettingView.refresh = function () {
+ // 濡傛灉鐢ㄦ埛姝e湪缂栬緫閰嶇疆锛屼笉鎵ц鑷姩鍒锋柊
+ if (networkSettingView.isEditing) {
+ return
+ }
+
const configAll = screen.getConfig()
let selectNum = 0
diff --git a/vf107/src/view/config/menu/recordQuery/recordQueryDetailView.js b/vf107/src/view/config/menu/recordQuery/recordQueryDetailView.js
index dbb8a08..8097857 100644
--- a/vf107/src/view/config/menu/recordQuery/recordQueryDetailView.js
+++ b/vf107/src/view/config/menu/recordQuery/recordQueryDetailView.js
@@ -37,8 +37,8 @@
key: 'name',
label: null
}, {
- title: 'recordQueryDetailView.idCard',
- key: 'idCard',
+ title: 'recordQueryDetailView.card',
+ key: 'card',
label: null
}, {
title: 'recordQueryDetailView.userId2',
@@ -49,8 +49,8 @@
key: 'name2',
label: null
}, {
- title: 'recordQueryDetailView.idCard2',
- key: 'idCard2',
+ title: 'recordQueryDetailView.card2',
+ key: 'card2',
label: null
}, {
title: 'recordQueryDetailView.time',
@@ -128,9 +128,9 @@
item.label.text(" ")
}
break;
- case 'idCard':
- if (extra && extra.idCard) {
- item.label.text(extra.idCard)
+ case 'card':
+ if (extra && extra.card) {
+ item.label.text(extra.card)
} else {
item.label.text(" ")
}
@@ -145,9 +145,9 @@
item.label.text(" ")
}
break;
- case 'idCard2':
- if (extra2 && extra2.idCard) {
- item.label.text(extra2.idCard)
+ case 'card2':
+ if (extra2 && extra2.card) {
+ item.label.text(extra2.card)
} else {
item.label.text(" ")
}
diff --git a/vf107/src/view/config/menu/systemSetting/displaySettingView.js b/vf107/src/view/config/menu/systemSetting/displaySettingView.js
index 3a80902..f5e34c2 100644
--- a/vf107/src/view/config/menu/systemSetting/displaySettingView.js
+++ b/vf107/src/view/config/menu/systemSetting/displaySettingView.js
@@ -239,7 +239,7 @@
// })
})
} else if (item.key === 'brightness') {
- if (dxDriver.DRIVER.MODEL == "vf202" || dxDriver.DRIVER.MODEL == "vf114" || dxDriver.DRIVER.MODEL == "vf105") {
+ if (dxDriver.DRIVER.MODEL == "vf202" || dxDriver.DRIVER.MODEL == "vf114" || dxDriver.DRIVER.MODEL == "vf105" || dxDriver.DRIVER.MODEL == "vf107") {
itemBox.show()
slider.on(dxui.Utils.EVENT.VALUE_CHANGED, () => {
sliderLabel.text(slider.value() + '')
diff --git a/vf107/src/view/config/menu/systemSetting/passwordOpenDoorSettingView.js b/vf107/src/view/config/menu/systemSetting/passwordOpenDoorSettingView.js
index cc69a5c..8753787 100644
--- a/vf107/src/view/config/menu/systemSetting/passwordOpenDoorSettingView.js
+++ b/vf107/src/view/config/menu/systemSetting/passwordOpenDoorSettingView.js
@@ -5,6 +5,7 @@
import i18n from "../../../i18n.js"
import systemSettingView from '../systemSettingView.js'
import screen from '../../../../screen.js'
+import api from '../../../../service/api.js'
const passwordOpenDoorSettingView = {}
passwordOpenDoorSettingView.init = function () {
/**************************************************鍒涘缓灞忓箷*****************************************************/
@@ -17,6 +18,9 @@
const configAll = screen.getConfig()
passwordOpenDoorSettingView.info[0].switch.select(configAll['sys.pwd'] == 1)
+
+ // 鏌ヨ搴旀�ュ紑闂ㄥ瘑鐮�
+ passwordOpenDoorSettingView.getEmergencyPassword()
})
const titleBox = viewUtils.title(screenMain, systemSettingView.screenMain, 'passwordOpenDoorSettingViewTitle', 'systemSettingView.passwordOpenDoorSetting')
@@ -26,13 +30,17 @@
{
title: "systemSettingView.passwordOpenDoor",
type: 'switch',
+ },
+ {
+ title: "systemSettingView.emergencyOpenDoorPassword",
+ type: 'password',
}
]
const passwordOpenDoorSettingBox = dxui.View.build('passwordOpenDoorSettingBox', screenMain)
viewUtils._clearStyle(passwordOpenDoorSettingBox)
passwordOpenDoorSettingBox.align(dxui.Utils.ALIGN.TOP_MID, 0, screen.screenSize.height * (140 / 1280))
- passwordOpenDoorSettingBox.setSize(screen.screenSize.width * (600 / 600), screen.screenSize.height * (600 / 1280))
+ passwordOpenDoorSettingBox.setSize(screen.screenSize.width * (600 / 600), screen.screenSize.height * (700 / 1280))
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)
@@ -69,6 +77,30 @@
__switch.bgColor(0x000000, NativeObject.APP.NativeComponents.NativeEnum.LV_PART_INDICATOR | NativeObject.APP.NativeComponents.NativeEnum.LV_STATE_CHECKED)
item.switch = __switch
break;
+ case 'password':
+ const pwdInput = viewUtils.input(itemBox, item.title + 'Input', 2, undefined, '璇疯緭鍏ュ簲鎬ュ紑闂ㄥ瘑鐮�')
+ pwdInput.align(dxui.Utils.ALIGN.RIGHT_MID, 0, 0)
+ pwdInput.setSize(screen.screenSize.width * (300 / 600), screen.screenSize.height * (50 / 1280))
+ pwdInput.setPasswordMode(true)
+ item.input = pwdInput
+
+ const eyeFill = viewUtils.imageBtn(itemBox, item.title + '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(itemBox, item.title + '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()
+ })
+ break;
}
})
@@ -76,6 +108,16 @@
const saveConfigData = {
sys: {
pwd: passwordOpenDoorSettingView.info[0].switch.isSelect() ? 1 : 0,
+ }
+ }
+
+ // 淇濆瓨搴旀�ュ紑闂ㄥ瘑鐮�
+ const emergencyPwd = passwordOpenDoorSettingView.info[1].input.text()
+ if (emergencyPwd) {
+ const res = api.insertEmergencyPassword({ password: emergencyPwd, description: "璁惧绔缃�" })
+ if (res !== true) {
+ passwordOpenDoorSettingView.statusPanel.fail()
+ return
}
}
@@ -95,4 +137,16 @@
passwordOpenDoorSettingView.statusPanel = viewUtils.statusPanel(screenMain, 'systemSettingView.success', 'systemSettingView.fail')
}
+// 鏌ヨ搴旀�ュ紑闂ㄥ瘑鐮�
+passwordOpenDoorSettingView.getEmergencyPassword = function () {
+ try {
+ const password = api.getEmergencyPassword()
+ if (password && password.password) {
+ passwordOpenDoorSettingView.info[1].input.text(password.password)
+ }
+ } catch (error) {
+ console.error('鏌ヨ搴旀�ュ紑闂ㄥ瘑鐮佸け璐�:', error)
+ }
+}
+
export default passwordOpenDoorSettingView
diff --git a/vf107/src/view/mainView.js b/vf107/src/view/mainView.js
index 669dcc6..7fd7566 100644
--- a/vf107/src/view/mainView.js
+++ b/vf107/src/view/mainView.js
@@ -35,10 +35,10 @@
// 鐩存帴浠巒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
+ // 浣跨敤getNetParam()鏂规硶鑾峰彇鏈�鏂扮殑缃戠粶鍙傛暟
+ let param = net.getNetParam()
+ if (param && param.ip) {
+ ip = param.ip
}
} catch (error) {
// 鍑洪敊鏃朵娇鐢╟onfig涓殑IP
@@ -86,10 +86,10 @@
// 鐩存帴浠巒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
+ // 浣跨敤getNetParam()鏂规硶鑾峰彇鏈�鏂扮殑缃戠粶鍙傛暟
+ let param = net.getNetParam()
+ if (param && param.ip) {
+ ip = param.ip
}
} catch (error) {
// 鍑洪敊鏃朵娇鐢╟onfig涓殑IP
@@ -128,6 +128,33 @@
}
}
+ // 鏇存柊缃戠粶鍥炬爣
+ function updateNetworkIcon() {
+ try {
+ let config = screen.getConfig()
+ let netType = config["net.type"] || 1
+ let isConnected = net.isConnected()
+
+ // 闅愯棌鎵�鏈夌綉缁滃浘鏍�
+ if (topView.ethShow) topView.ethShow.hide()
+ if (topView.wifiShow) topView.wifiShow.hide()
+ if (topView._4gShow) topView._4gShow.hide()
+
+ // 鏍规嵁缃戠粶绫诲瀷鍜岃繛鎺ョ姸鎬佹樉绀哄搴旂殑鍥炬爣
+ if (isConnected) {
+ if (netType === 1) { // 浠ュお缃�
+ if (topView.ethShow) topView.ethShow.show()
+ } else if (netType === 2) { // WiFi
+ if (topView.wifiShow) topView.wifiShow.show()
+ } else if (netType === 4) { // 4G
+ if (topView._4gShow) topView._4gShow.show()
+ }
+ }
+ } catch (error) {
+ logger.error('[mainView]: 鏇存柊缃戠粶鍥炬爣澶辫触:', error)
+ }
+ }
+
screenMain.on(dxui.Utils.ENUM.LV_EVENT_SCREEN_LOADED, () => {
topView.changeTheme(false)
@@ -148,6 +175,8 @@
// 绋嬪簭鍚姩鏃舵洿鏂板簱鍖哄悕绉板拰浠撳彿
updateWarehouseInfo()
+ // 鍒濆鍖栫綉缁滃浘鏍�
+ updateNetworkIcon()
// 鍙敞鍐屼竴娆′簨浠剁洃鍚櫒
if (!mainView.eventListenersRegistered) {
@@ -158,9 +187,11 @@
onStatusChange: function(netType, status) {
// 缃戠粶鐘舵�佸彉鍖栨椂鏇存柊IP淇℃伅
updateDeviceInfo()
+ // 鏇存柊缃戠粶鍥炬爣
+ updateNetworkIcon()
}
})
-
+
// 鍚姩缃戠粶浜嬩欢寰幆
std.setInterval(() => {
try {
@@ -803,9 +834,10 @@
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.text('-')
oxygenValue.textFont(viewUtils.font(20, dxui.Utils.FONT_STYLE.BOLD))
oxygenValue.textColor(0xffffff)
mainView.oxygenValue = oxygenValue // 璁剧疆涓簃ainView灞炴��
@@ -865,7 +897,7 @@
// 纾峰寲姘㈡暟鍊奸儴鍒�
const ph3Value = dxui.Label.build('ph3Value', ph3ValueContainer)
- ph3Value.text('0')
+ ph3Value.text('-')
ph3Value.textFont(viewUtils.font(20, dxui.Utils.FONT_STYLE.BOLD))
ph3Value.textColor(0xffffff)
mainView.ph3Value = ph3Value // 璁剧疆涓簃ainView灞炴��
@@ -909,7 +941,7 @@
// 浜屾哀鍖栫⒊鏁板�奸儴鍒�
const co2Value = dxui.Label.build('co2Value', co2ValueContainer)
- co2Value.text('400')
+ co2Value.text('-')
co2Value.textFont(viewUtils.font(20, dxui.Utils.FONT_STYLE.BOLD))
co2Value.textColor(0xffffff)
mainView.co2Value = co2Value // 璁剧疆涓簃ainView灞炴��
diff --git a/vf107/src/worker/mqttWorker.js b/vf107/src/worker/mqttWorker.js
index e3118a8..d5596c0 100644
--- a/vf107/src/worker/mqttWorker.js
+++ b/vf107/src/worker/mqttWorker.js
@@ -36,6 +36,7 @@
"getPermission", "insertPermission", "delPermission", "clearPermission", "modifyPermission",
"getKey", "insertKey", "delKey", "clearKey", "modifyKey",
"getUser", "insertUser", "delUser", "clearUser", "modifyUser",
+ "insertEmergencyPassword", "delEmergencyPassword", "clearEmergencyPassword", "getEmergencyPassword",
"getSecurity", "insertSecurity", "delSecurity", "clearSecurity", "getRecords", "delRecords"
]
const eventReplies = ["connect_reply", "alarm_reply", "access_reply", "access_online_reply", "wecom_reply"]
@@ -84,7 +85,7 @@
mqtt.subscribe(v, { qos });
})
} catch (error) {
- logger.error("MQTT connection error锛宺etry in 5s:");
+ // logger.error("MQTT connection error锛宺etry in 5s:");
}
}
diff --git a/vf107/src/worker/netWorker.js b/vf107/src/worker/netWorker.js
index c068030..da189d0 100644
--- a/vf107/src/worker/netWorker.js
+++ b/vf107/src/worker/netWorker.js
@@ -31,6 +31,8 @@
// 缃戠粶鐘舵�佽窡韪彉閲�
let lastConnected = false // 涓婃杩炴帴鐘舵��
let shouldReconnect = false
+let lastReconnectTime = 0 // 涓婃閲嶈繛鏃堕棿
+const RECONNECT_INTERVAL = 15000 // 閲嶈繛闂撮殧锛堟绉掞級
const net_map = map.get("NET")
/**
* 鏍规嵁閰嶇疆寤虹珛缃戠粶杩炴帴
@@ -42,6 +44,12 @@
*/
function connect() {
try {
+ // 濡傛灉缃戠粶宸茬粡杩炴帴锛屼笉闇�瑕侀噸杩�
+ if (net.isConnected()) {
+ logger.info("NET already connected, skip connect")
+ return 0
+ }
+
let res = 0;
// 鑾峰彇缃戠粶閰嶇疆
let dhcp = config.get("net.dhcp") == 2 // DHCP鍚敤鏍囧織
@@ -119,7 +127,10 @@
logger.info("NET connect res:", res);
if (res < 0) {
//灏忎簬0骞朵笉鏄〃绀虹綉缁滆繛鎺ュけ璐ワ紝鑰屾槸涓�涓壒娈婄殑閿欒锛屽彲浠ラ噸璇曚竴娆″氨鍙互
- shouldReconnect = true
+ const currentTime = Date.now()
+ if (currentTime - lastReconnectTime >= RECONNECT_INTERVAL) {
+ shouldReconnect = true
+ }
}
return res;
} catch (error) {
@@ -187,28 +198,43 @@
if (net.getNative()) {
net.loop(); // 鎵ц缃戠粶寰幆澶勭悊
}
+
+ // 鍏堟鏌ョ綉缁滆繛鎺ョ姸鎬�
+ if (net.isConnected()) {
+ let param = driver.net.getNetParam()
+ if (!lastConnected || lastConnectedIp != param.ip) {
+ bus.fire(driver.net.CONNECTED_CHANGED, "connected")
+ lastConnected = true
+ net_map.put("NET_STATUS", "connected")
+ lastConnectedIp = param.ip
+ }
+ } else {
+ logger.info("NET not isConnected");
+ // if (lastConnected) {
+ bus.fire(driver.net.CONNECTED_CHANGED, "disconnected")
+ lastConnected = false
+ net_map.put("NET_STATUS", "disconnected")
+ // 鑷姩瑙﹀彂閲嶈繛
+ shouldReconnect = true
+ // }
+ }
+
+ // 鐒跺悗妫�鏌ユ槸鍚﹂渶瑕侀噸杩�
if (shouldReconnect) {
- logger.info("NET shouldReconnect");
- shouldReconnect = false
- connect()
+ const currentTime = Date.now()
+ if (currentTime - lastReconnectTime >= RECONNECT_INTERVAL) {
+ logger.info("NET shouldReconnect");
+ shouldReconnect = false
+ lastReconnectTime = currentTime
+ connect()
+ } else {
+ // 閲嶈繛闂撮殧涓嶈冻锛屽彇娑堥噸杩�
+ shouldReconnect = false
+ // logger.info("NET reconnect skipped, interval not reached")
+ }
}
} catch (error) {
logger.error(error)
- }
- if (net.isConnected()) {
- let param = driver.net.getNetParam()
- if (!lastConnected || lastConnectedIp != param.ip) {
- bus.fire(driver.net.CONNECTED_CHANGED, "connected")
- lastConnected = true
- net_map.put("NET_STATUS", "connected")
- lastConnectedIp = param.ip
- }
- } else {
- if (lastConnected) {
- bus.fire(driver.net.CONNECTED_CHANGED, "disconnected")
- lastConnected = false
- net_map.put("NET_STATUS", "disconnected")
- }
}
}, 5000)
}
diff --git a/vf107/src/worker/passRecordWorker.js b/vf107/src/worker/passRecordWorker.js
index 5c7f693..df0ecd3 100644
--- a/vf107/src/worker/passRecordWorker.js
+++ b/vf107/src/worker/passRecordWorker.js
@@ -12,7 +12,7 @@
*
* 鑱岃矗锛�
* - 甯搁┗杩愯锛屽彧瑕� MQTT 杩炴帴灏辨寔缁笂鎶�
- * - 姣忔鍔犺浇鎵�鏈夋湭鍒犻櫎鐨勯�氳璁板綍锛坉1_pass_record锛�
+ * - 姣忔鍔犺浇鎵�鏈夋湭涓婃姤鐨勯�氳璁板綍锛坉1_pass_record锛�
* - 姣忛殧 5 绉掍笂鎶ヤ竴鏉�
* - 鍙戝畬褰撳墠鎵规鍚庯紝鑷姩閲嶆柊鍔犺浇鏈�鏂拌褰�
*/
@@ -29,10 +29,12 @@
return mqtt_map.get("MQTT_STATUS") === "connected"
}
-// 鍔犺浇鏂版壒娆★細鏌ヨ鎵�鏈夋湭鍒犻櫎鐨勮褰曪紙鎸夋椂闂村崌搴忥級
+// 鍔犺浇鏂版壒娆★細鏌ヨ鎵�鏈夋湭鍒犻櫎涓旀湭涓婃姤鐨勮褰曪紙鎸夋椂闂村崌搴忥級
function loadNewBatch() {
try {
- currentBatch = sqliteService.d1_pass_record.findAllOrderByTimeStampAsc()
+ let sql = `SELECT * FROM d1_pass_record WHERE reported = 0 OR reported IS NULL ORDER BY timeStamp ASC`
+ let result = sqliteService.select(sql)
+ currentBatch = result || []
currentIndex = 0
} catch (err) {
logger.error("[passRecordWorker] Failed to load batch:", err)
@@ -59,29 +61,70 @@
return
}
let extra = record.extra ? JSON.parse(record.extra) : ""
+ let extra2 = record.extra2 ? JSON.parse(record.extra2) : ""
let accessRecord = {
- userId: record.userId,
- type: record.type,
- result: record.result,
- name: extra && extra.name ? extra.name : "",
- timeStamp: record.timeStamp,
- extra: {},
- error: record.message
+ timeStamp: mqttService.timestampToDateString(record.timeStamp || 0),
+ result: record.result || 0,
+ error: record.message || "",
+ // permissionId: record.permissionId || "", // TODO
+ door: config.get("houseName") || "",
+ users: [
+ {
+ userId: record.userId || "",
+ name: extra && extra.name ? extra.name : "",
+ userType: extra && extra.type ? extra.type : 0,
+ accessType: extra && extra.accessType !== undefined ? extra.accessType : "",
+ card: extra && extra.card ? extra.card : "",
+ face: extra && extra.face ? extra.face : "",
+ finge: extra && extra.finge ? extra.finge : ""
+ }
+ ]
}
+
+ // 濡傛灉鏄弻浜鸿璇侊紝娣诲姞绗簩涓敤鎴蜂俊鎭�
+ if (record.userId2) {
+ let secondUser = {
+ userId: record.userId2 || "",
+ name: extra2 && extra2.name ? extra2.name : "",
+ userType: extra2 && extra2.type ? extra2.type : 0,
+ accessType: extra2 && extra2.accessType !== undefined ? extra2.accessType : "",
+ card: extra2 && extra2.card ? extra2.card : "",
+ face: extra2 && extra2.face ? extra2.face : "",
+ finge: extra2 && extra2.finge ? extra2.finge : ""
+ }
+ // 鏍规嵁璁よ瘉绫诲瀷娣诲姞鐩稿簲鐨勮璇佷俊鎭�
+ if (extra2 && extra2.accessType == 200 && extra2.card) {
+ secondUser.card = extra2.card
+ } else if (extra2 && extra2.accessType == 300) {
+ // 浜鸿劯璁よ瘉锛宖ace瀛楁鍙互鐣欑┖鎴栨坊鍔犵浉搴斾俊鎭�
+ } else if (extra2 && extra2.accessType == 500) {
+ // 鎸囩汗璁よ瘉锛宖inge瀛楁鍙互鐣欑┖鎴栨坊鍔犵浉搴斾俊鎭�
+ }
+ accessRecord.users.push(secondUser)
+ }
+
if (record.type == 300) {
- if (std.exist(record.code) && config.get("access.uploadToCloud")) {
- accessRecord.code = dxCommonUtils.fs.fileToBase64(record.code)
+ if (std.exist(record.code)) {
+ // 浜鸿劯璁よ瘉锛屽皢鍥剧墖杞崲涓篵ase64濉厖鍒癴ace瀛楁
+ accessRecord.users[0].face = dxCommonUtils.fs.fileToBase64(record.code)
if (currentIndex > 0) {
currentBatch[currentIndex - 1].code = ""
}
} else {
- accessRecord.code = ""
+ accessRecord.users[0].face = ""
+ }
+
+ // 濡傛灉鏈夌浜屼釜鐢ㄦ埛鐨勪簩缁寸爜
+ if (record.code2) {
+ accessRecord.users[1] = accessRecord.users[1] || {}
+ accessRecord.users[1].code = record.code2
}
}
// 鍙戦��
try {
+ const sn = config.get("sys.sn") || "default"
driver.mqtt.send(
- "access_device/v2/event/access",
+ `access_device/v2/event/${sn}/access`,
JSON.stringify(
mqttService.mqttReply(
record.id,
@@ -90,6 +133,13 @@
)
)
)
+ // 鏍囪璁板綍涓哄凡涓婃姤
+ try {
+ let updateSql = `UPDATE d1_pass_record SET reported = 1 WHERE id = '${record.id}'`
+ sqliteService.exec(updateSql)
+ } catch (updateErr) {
+ logger.error("[passRecordWorker] Failed to update reported status for record", record.id, updateErr)
+ }
} catch (e) {
logger.error("[passRecordWorker] Send failed for record", record.id, e)
}
--
Gitblit v1.9.3