diff --git a/.gitignore b/.gitignore deleted file mode 100644 index 1ff3991..0000000 --- a/.gitignore +++ /dev/null @@ -1,27 +0,0 @@ -# Node.js -node_modules/ -npm-debug.log -yarn-error.log - -# IDE / Editor -.vscode/ -.idea/ -*.swp -*.swo -.DS_Store - -# Project Specific (Logs & Cache) -logs/ -.dbg/ -.last_update_ts -.last_update_version -config.json -gate_config.json -web/data/ - -# Environment Variables -.env -.env.local - -# Trae AI -.trae/ diff --git a/gate.lua b/gate.lua index bbee6ea..36a731a 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.18" +local VERSION = "v1.5.15" local VERSION_CHECK_INTERVAL = 5 local CONFIG_PATH = "gate_config.json" @@ -192,7 +192,6 @@ local function checkAndApplyUpdate() print("OTA Update Error: " .. tostring(res)) term.setTextColor(colors.white) end - sleep(3) end else lastUpdateError = "loadfile failed: " .. tostring(err) @@ -201,7 +200,6 @@ local function checkAndApplyUpdate() print("OTA Update Error: " .. tostring(err)) term.setTextColor(colors.white) end - sleep(3) end isUpdating = false @@ -1500,49 +1498,21 @@ local function processInspectionEvent(eventName, ev) end end -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 +local versionTimer = os.startTimer(VERSION_CHECK_INTERVAL) -local function backgroundSyncTask() - while true do - sleep(VERSION_CHECK_INTERVAL) + + +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 pcall(function() refreshRemoteLuaVersion(guessBaseFromStatusURL(serverURL)) end) pcall(checkAndApplyUpdate) + versionTimer = os.startTimer(VERSION_CHECK_INTERVAL) end end - -local function backgroundLocationSyncTask() - sleep(5) - local x, y, z - if gps and type(gps.locate) == "function" then - x, y, z = gps.locate(2) - end - 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) - while true do - sleep(86400) - end -end - -parallel.waitForAny(mainLoop, backgroundSyncTask, backgroundLocationSyncTask) diff --git a/server/routes/api.js b/server/routes/api.js index 93773d2..01389fb 100644 --- a/server/routes/api.js +++ b/server/routes/api.js @@ -163,33 +163,6 @@ router.get('/check-update', (req, res) => { res.json({ update_counter: globalUpdateCounter }); }); -router.post('/machine-location', async (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); - } - await DataService.updateMachineLocation(data.device_id, data); - res.json({ ok: true }); -}); - -router.get('/machine-locations', (req, res) => { - const locs = DataService.getMachineLocations() || {}; - res.json({ ok: true, data: locs }); -}); - -router.put('/machine-location/:id', async (req, res) => { - const id = req.params.id; - const data = req.body || {}; - const current = DataService.getMachineLocations()[id]; - if (!current) return res.status(404).json({ ok: false, error: 'machine not found' }); - if (!data.station && data.station_code) { - data.station = resolveStationName(data.station_code); - } - await DataService.updateMachineLocation(id, data); - res.json({ ok: true }); -}); - // Config router.get('/config', (req, res) => { const cfg = DataService.getConfig(); diff --git a/server/routes/public.js b/server/routes/public.js index 2d1a13a..311c0ae 100644 --- a/server/routes/public.js +++ b/server/routes/public.js @@ -224,11 +224,6 @@ router.get('/fares/query', (req, res) => { } }); -router.get('/machine-locations', (req, res) => { - const locs = DataService.getMachineLocations() || {}; - res.json({ ok: true, data: locs }); -}); - router.get('/config', (req, res) => { const cfg = DataService.getConfig(); res.json({ diff --git a/server/services/data.js b/server/services/data.js index 3b3dbf8..78ac335 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.18', - gate: 'v1.5.18' + ticketmachine: 'v1.5.8', + gate: 'v1.5.8' }; function normalizeLuaVersions(input) { @@ -64,8 +64,7 @@ const cache = { icCardIndex: {}, icCardEvents: [], statsTicket: [], - statsGate: [], - machineLocations: {} + statsGate: [] }; const DataService = { @@ -95,9 +94,6 @@ const DataService = { if (configs.length > 0) cache.config = normalizeConfig(configs[0].v); else await conn.query('INSERT INTO kv_store (k, v) VALUES (?, ?)', ['config', JSON.stringify(cache.config)]); - const [machLocs] = await conn.query('SELECT v FROM kv_store WHERE k = ?', ['machine_locations']); - if (machLocs.length > 0) cache.machineLocations = machLocs[0].v || {}; - const [stations] = await conn.query('SELECT data FROM stations'); cache.stations = stations.map(r => r.data); @@ -526,19 +522,6 @@ const DataService = { }), saveExport: () => { try { fs.writeFileSync(paths.export, JSON.stringify(DataService.buildExportPayload(), null, 2)); } catch(e){} - }, - - getMachineLocations: () => cache.machineLocations, - updateMachineLocation: async (deviceId, data) => { - cache.machineLocations[deviceId] = { - ...cache.machineLocations[deviceId], - ...data, - last_update_ts: Date.now() - }; - try { - await pool.query('INSERT INTO kv_store (k, v) VALUES (?, ?) ON DUPLICATE KEY UPDATE v = VALUES(v)', - ['machine_locations', JSON.stringify(cache.machineLocations)]); - } catch(e) { console.error('updateMachineLocation error', e); } } }; diff --git a/ticketmachine.lua b/ticketmachine.lua index 410f57d..5ca5564 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.18' +local VERSION = 'v1.5.15' local UPDATE_CHECK_INTERVAL = 5 -- ########################### @@ -722,7 +722,6 @@ local function checkAndApplyUpdate() print("OTA Update Error: " .. tostring(res)) term.setTextColor(colors.white) end - sleep(3) end else lastUpdateError = "loadfile failed: " .. tostring(err) @@ -731,7 +730,6 @@ local function checkAndApplyUpdate() print("OTA Update Error: " .. tostring(err)) term.setTextColor(colors.white) end - sleep(3) end isUpdating = false @@ -777,26 +775,7 @@ local function backgroundTicketUploadTask() end end -local function backgroundLocationSyncTask() - sleep(5) - local x, y, z - if gps and type(gps.locate) == "function" then - x, y, z = gps.locate(2) - end - 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) - while true do - sleep(86400) - end -end + -- ########################### -- Data logic & Config @@ -2549,4 +2528,4 @@ local function mainPageLoop() end end -parallel.waitForAny(mainPageLoop, backgroundSyncTask, backgroundTicketUploadTask, backgroundPeripheralTask, backgroundLocationSyncTask) +parallel.waitForAny(mainPageLoop, backgroundSyncTask, backgroundTicketUploadTask, backgroundPeripheralTask) diff --git a/web/home.html b/web/home.html index bea0eea..8e6be64 100644 --- a/web/home.html +++ b/web/home.html @@ -39,7 +39,6 @@ 车票查询 IC 卡查询 线上购卡 - 机器位置 diff --git a/web/ic-card-order.html b/web/ic-card-order.html index 299b47b..937c815 100644 --- a/web/ic-card-order.html +++ b/web/ic-card-order.html @@ -40,7 +40,6 @@ 车票查询 IC 卡查询 线上购卡 - 机器位置 diff --git a/web/ic-card-search.html b/web/ic-card-search.html index ec4258b..296b4ad 100644 --- a/web/ic-card-search.html +++ b/web/ic-card-search.html @@ -40,7 +40,6 @@ 车票查询 IC 卡查询 线上购卡 - 机器位置 diff --git a/web/index.html b/web/index.html index f965989..4c5b4fe 100644 --- a/web/index.html +++ b/web/index.html @@ -64,9 +64,6 @@ - @@ -644,99 +641,6 @@ - -
-
-

设备分布图

-

机器位置与状态 (每 60 秒自动更新)

-
- - -
- 暂无机器坐标数据 -
- -
-
-
- - -
-
-
-

编辑设备位置 - {{ editMachineForm.device_id }}

- -
-
-
- - -
-
-
- - -
-
- - -
-
- - -
-
-
- - -
-
- -
-
-
diff --git a/web/index.js b/web/index.js index 09f2682..700efad 100644 --- a/web/index.js +++ b/web/index.js @@ -24,7 +24,6 @@ createApp({ dashboard: '仪表盘', management: '线路与票价管理', faremap: '票价地图', - machinemap: '机器位置', tickets: '车票记录', vouchers: '凭证管理', iccards: 'IC 卡管理', @@ -79,14 +78,12 @@ createApp({ let logDataLoaded = false; let assetsLoaded = false; let fareMapLoaded = false; - let machineLocationsLoaded = false; const loadingState = reactive({ core: false, tickets: false, orders: false, logs: false, - iccards: false, - machinemap: false + iccards: false }); const lastSyncAt = ref(0); @@ -1119,82 +1116,6 @@ createApp({ } }; - const machineLocations = ref({}); - const selectedMachineId = ref(''); - const getMapX = (x) => { - if (typeof x !== 'number') return 50; - // Assuming typical MC coords are between -10000 and +10000. - // We can auto-scale based on actual data bounds instead. - let min = 0, max = 0; - const vals = Object.values(machineLocations.value).map(l => l.x).filter(v => typeof v === 'number'); - if (vals.length > 0) { - min = Math.min(...vals) - 50; - max = Math.max(...vals) + 50; - } else { - return 50; - } - if (max === min) return 50; - return ((x - min) / (max - min)) * 90 + 5; // 5% to 95% margin - }; - const getMapY = (z) => { - if (typeof z !== 'number') return 50; - let min = 0, max = 0; - const vals = Object.values(machineLocations.value).map(l => l.z).filter(v => typeof v === 'number'); - if (vals.length > 0) { - min = Math.min(...vals) - 50; - max = Math.max(...vals) + 50; - } else { - return 50; - } - if (max === min) return 50; - return ((z - min) / (max - min)) * 90 + 5; - }; - - const fetchMachineLocations = async () => { - loadingState.machinemap = true; - try { - const res = await requestJson('/api/machine-locations'); - if (res && res.data) { - machineLocations.value = res.data; - } - machineLocationsLoaded = true; - } catch (e) { - console.error(e); - } finally { - loadingState.machinemap = false; - } - }; - - const showEditMachineModal = ref(false); - const editMachineForm = reactive({ device_id: '', station_code: '', x: 0, y: 0, z: 0, type: 'TicketMachine' }); - - const openEditMachineModal = (id) => { - const loc = machineLocations.value[id]; - if (!loc) return; - editMachineForm.device_id = id; - editMachineForm.station_code = loc.station_code || loc.station || ''; - editMachineForm.x = loc.x || 0; - editMachineForm.y = loc.y || 0; - editMachineForm.z = loc.z || 0; - editMachineForm.type = loc.type || 'TicketMachine'; - showEditMachineModal.value = true; - }; - - const saveMachineLocation = async () => { - try { - const payload = { ...editMachineForm }; - await requestJson(`/api/machine-location/${encodeURIComponent(payload.device_id)}`, { - method: 'PUT', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify(payload) - }, { expectOk: true }); - showEditMachineModal.value = false; - await fetchMachineLocations(); - } catch (e) { - alert('保存失败: ' + e.message); - } - }; - const ensureViewData = async (view = currentView.value, { force = false } = {}) => { await fetchCoreData({ force }); if (view === 'tickets' && (force || !ticketDataLoaded)) await fetchTicketData(); @@ -1208,7 +1129,6 @@ createApp({ } if (view === 'faremap' && (force || !fareMapLoaded)) await loadFareMap({ force }); if (view === 'assets' && (!assetsLoaded || force)) await fetchAssetsManifest(); - if (view === 'machinemap') await fetchMachineLocations(); }; const fetchData = async () => { @@ -1644,8 +1564,6 @@ createApp({ syncSelectedIcCard().catch(console.error); }); - let machineMapTimer = null; - watch(currentView, (v) => { sidebarOpen.value = false; if (v === 'iccards') { @@ -1653,14 +1571,6 @@ createApp({ } else { stopIcCardSync(); } - if (v === 'machinemap') { - if (!machineMapTimer) machineMapTimer = setInterval(fetchMachineLocations, 60000); - } else { - if (machineMapTimer) { - clearInterval(machineMapTimer); - machineMapTimer = null; - } - } ensureViewData(v).catch(console.error); const sp = new URLSearchParams(location.search); if (v === 'dashboard') sp.delete('view'); @@ -1810,7 +1720,6 @@ createApp({ }; return { - machineLocations, selectedMachineId, getMapX, getMapY, showEditMachineModal, editMachineForm, openEditMachineModal, saveMachineLocation, currentView, viewTitle, sidebarOpen, loadingState, isViewBusy, lastSyncText, currentViewSummary, stations, lines, fares, stats, config, recentLogs, ticketList, ticketStats, orderStats, diff --git a/web/machine-map.html b/web/machine-map.html index ed63846..3530f63 100644 --- a/web/machine-map.html +++ b/web/machine-map.html @@ -4,7 +4,7 @@ - 机器位置|FSE铁路运输票务系统 + 票务查询|FSE铁路运输票务系统 @@ -38,130 +38,113 @@
- MACHINE MAP -

设备分布图

-

实时查看所有售票机和检票机的位置及状态。

+ TICKET SEARCH +

按票号、站点或日期快速查询票据

+

输入完整票号、起终点、日期或关键词,左侧浏览结果,右侧查看票据详情与最近流转记录。

+ +
-

机器位置

- Live Map +

检索条件

+ Ticket ID / Station / Date
-
-
- 加载中... -
+
+ +
+

可直接输入完整票号,也可输入起点、终点或日期关键字进行模糊检索。

+ +
+
+
+

结果列表

+ Search Results +
+
+
+

请输入关键词开始查询。

+
+
+
+ +
+
+
+

车票详情

+ Ticket Overview +
+
+
+

从左侧选择一张车票以查看详情。

+
+
+
+ +
+
+
+

热门站点

+ Popular Stations +
+ +
+
+
+

热门路线

+ Popular Routes +
+ +
+
+
+
+ +
- + + + + + diff --git a/web/ticket-order.html b/web/ticket-order.html index 5e77868..6e435da 100644 --- a/web/ticket-order.html +++ b/web/ticket-order.html @@ -38,10 +38,9 @@ 首页 线上预定 车票查询 - IC 卡查询 - 线上购卡 - 机器位置 - + IC 卡查询 + 线上购卡 +
diff --git a/web/ticket-search.html b/web/ticket-search.html index 4d1fe47..3530f63 100644 --- a/web/ticket-search.html +++ b/web/ticket-search.html @@ -40,8 +40,7 @@ 线上预定 车票查询 IC 卡查询 - 线上购卡 - 机器位置 + 线上购卡