From efc061e47109f8ed9d5d8064e6fcd1ae573b1c1c Mon Sep 17 00:00:00 2001 From: HenryDu8133 <813367384@qq.com> Date: Sat, 11 Jul 2026 14:58:30 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=96=B0=E5=A2=9E=E8=AE=BE=E5=A4=87?= =?UTF-8?q?=E4=BD=8D=E7=BD=AE=E8=BF=BD=E8=B8=AA=E4=B8=8E=E7=BD=91=E9=A1=B5?= =?UTF-8?q?=E7=AE=A1=E7=90=86=E9=A1=B5=E9=9D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 更新服务端默认Lua版本与客户端程序版本至 v1.5.16 - 新增后端API接口用于提交和查询设备位置数据 - 为售票机和检票机添加后台GPS位置同步任务,定期上报设备坐标 - 服务端新增设备位置缓存,并自动清理超过5分钟未更新的过期数据 - 新增网页端设备位置地图页面,支持实时展示、点击查看详情与每分钟自动刷新 --- gate.lua | 52 ++++++++++++++++++++++++++-------- server/routes/api.js | 23 +++++++++++++++ server/services/data.js | 15 ++++++++-- ticketmachine.lua | 25 ++++++++++++++-- web/index.html | 52 ++++++++++++++++++++++++++++++++++ web/index.js | 63 ++++++++++++++++++++++++++++++++++++++++- 6 files changed, 211 insertions(+), 19 deletions(-) diff --git a/gate.lua b/gate.lua index 36a731a..dabefc5 100644 --- a/gate.lua +++ b/gate.lua @@ -1,7 +1,7 @@ local DEFAULT_SERVER_BASE = "http://ticket.fse-media.group" local DEFAULT_SERVER_PATH = "/api/tickets/check" local GATE_OPEN_SECONDS = 2 -local VERSION = "v1.5.15" +local VERSION = "v1.5.16" local VERSION_CHECK_INTERVAL = 5 local CONFIG_PATH = "gate_config.json" @@ -1498,21 +1498,49 @@ local function processInspectionEvent(eventName, ev) end end -local versionTimer = os.startTimer(VERSION_CHECK_INTERVAL) +local function mainLoop() + while true do + local ev = pack(os.pullEvent()) + if ev[1] == "ticket_scanned" or ev[1] == "ic_card_scanned" then + processInspectionEvent(ev[1], ev) + os.sleep(0.35) + drawReadyScreen() + end + end +end - - -while true do - local ev = pack(os.pullEvent()) - if ev[1] == "ticket_scanned" or ev[1] == "ic_card_scanned" then - processInspectionEvent(ev[1], ev) - os.sleep(0.35) - drawReadyScreen() - elseif ev[1] == "timer" and ev[2] == versionTimer then +local function backgroundSyncTask() + while true do + sleep(VERSION_CHECK_INTERVAL) pcall(function() refreshRemoteLuaVersion(guessBaseFromStatusURL(serverURL)) end) pcall(checkAndApplyUpdate) - versionTimer = os.startTimer(VERSION_CHECK_INTERVAL) end end + +local function backgroundLocationSyncTask() + while true do + if gps and type(gps.locate) == "function" then + local x, y, z = gps.locate(2) + if x and y and z then + local label = os.getComputerLabel() + if not label or label == "" then label = "#" .. tostring(os.getComputerID()) end + local payload = { + device_id = label, + type = "Gate", + gate_mode = modeBySide and "bidirectional" or mode, + station_code = stationCodeForSide(nil) or "", + x = x, + y = y, + z = z + } + local serverBase = guessBaseFromStatusURL(serverURL) + pcall(postCheck, serverBase .. '/api/machine-location', payload) + end + end + sleep(60) + end +end + +parallel.waitForAny(mainLoop, backgroundSyncTask, backgroundLocationSyncTask) diff --git a/server/routes/api.js b/server/routes/api.js index 01389fb..7140159 100644 --- a/server/routes/api.js +++ b/server/routes/api.js @@ -163,6 +163,29 @@ router.get('/check-update', (req, res) => { res.json({ update_counter: globalUpdateCounter }); }); +router.post('/machine-location', (req, res) => { + const data = req.body || {}; + if (!data.device_id) return res.status(400).json({ ok: false, error: 'device_id required' }); + if (!data.station && data.station_code) { + data.station = resolveStationName(data.station_code); + } + DataService.updateMachineLocation(data.device_id, data); + res.json({ ok: true }); +}); + +router.get('/machine-locations', (req, res) => { + const locs = DataService.getMachineLocations() || {}; + // clean up old locations (> 5 minutes) + const now = Date.now(); + const active = {}; + for (const [id, data] of Object.entries(locs)) { + if (now - data.last_update_ts < 5 * 60 * 1000) { + active[id] = data; + } + } + res.json({ ok: true, data: active }); +}); + // Config router.get('/config', (req, res) => { const cfg = DataService.getConfig(); diff --git a/server/services/data.js b/server/services/data.js index 78ac335..b1df111 100644 --- a/server/services/data.js +++ b/server/services/data.js @@ -22,8 +22,8 @@ const pool = mysql.createPool({ }); const DEFAULT_LUA_VERSIONS = { - ticketmachine: 'v1.5.8', - gate: 'v1.5.8' + ticketmachine: 'v1.5.16', + gate: 'v1.5.16' }; function normalizeLuaVersions(input) { @@ -64,7 +64,8 @@ const cache = { icCardIndex: {}, icCardEvents: [], statsTicket: [], - statsGate: [] + statsGate: [], + machineLocations: {} }; const DataService = { @@ -522,6 +523,14 @@ const DataService = { }), saveExport: () => { try { fs.writeFileSync(paths.export, JSON.stringify(DataService.buildExportPayload(), null, 2)); } catch(e){} + }, + + getMachineLocations: () => cache.machineLocations, + updateMachineLocation: (deviceId, data) => { + cache.machineLocations[deviceId] = { + ...data, + last_update_ts: Date.now() + }; } }; diff --git a/ticketmachine.lua b/ticketmachine.lua index 5ca5564..3602cf4 100644 --- a/ticketmachine.lua +++ b/ticketmachine.lua @@ -1,6 +1,6 @@ local CURRENT_STATION_CODE = 'Ticket-Machine' local API_BASE = 'http://ticket.fse-media.group/api' -local VERSION = 'v1.5.15' +local VERSION = 'v1.5.16' local UPDATE_CHECK_INTERVAL = 5 -- ########################### @@ -775,7 +775,26 @@ local function backgroundTicketUploadTask() end end - +local function backgroundLocationSyncTask() + while true do + if gps and type(gps.locate) == "function" then + local x, y, z = gps.locate(2) + if x and y and z then + local payload = { + device_id = currentDeviceId(), + type = "TicketMachine", + station = (CFG.current_station and (CFG.current_station.en_name or CFG.current_station.name)) or state.stationName, + station_code = state.stationCode or CURRENT_STATION_CODE, + x = x, + y = y, + z = z + } + postJSONResult(API_BASE .. '/machine-location', payload) + end + end + sleep(60) + end +end -- ########################### -- Data logic & Config @@ -2528,4 +2547,4 @@ local function mainPageLoop() end end -parallel.waitForAny(mainPageLoop, backgroundSyncTask, backgroundTicketUploadTask, backgroundPeripheralTask) +parallel.waitForAny(mainPageLoop, backgroundSyncTask, backgroundTicketUploadTask, backgroundPeripheralTask, backgroundLocationSyncTask) diff --git a/web/index.html b/web/index.html index 4c5b4fe..658581e 100644 --- a/web/index.html +++ b/web/index.html @@ -64,6 +64,9 @@
+ @@ -641,6 +644,55 @@ + +机器位置与状态 (每 60 秒自动更新)
+ +