修改了一些东西

This commit is contained in:
2026-07-10 11:33:37 +08:00
parent fa2457ce7f
commit d2809c4d6d
9 changed files with 166 additions and 50 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "ticketmachine",
"version": "1.0.14",
"version": "1.0.15",
"main": "server/index.js",
"scripts": {
"start": "node server/index.js",
+6 -16
View File
@@ -1,6 +1,6 @@
local CURRENT_STATION_CODE = 'Ticket-Machine'
local API_BASE = 'http://ticket.fse-media.group/api'
local VERSION = 'v1.5.11'
local VERSION = 'v1.5.12'
-- ###########################
-- Core HTTP & JSON Utilities
@@ -239,10 +239,7 @@ local function firstNumber(...)
end
local function currentDeviceId()
local dev = nil
if os.getComputerLabel then dev = os.getComputerLabel() end
if not dev and os.getComputerID then dev = tostring(os.getComputerID()) end
return tostring(dev or 'unknown')
return 'ticket_machine'
end
local function normalizeTrainTypeLabel(v)
@@ -658,10 +655,6 @@ local function backgroundSyncTask()
sleep(5)
pcall(refreshConfigOnce)
if versionMismatch == true then
pcall(function()
clear()
centerText(math.floor(h/2), "Auto Updating...", colors.yellow)
end)
pcall(function()
if shell and type(shell.run) == "function" then
shell.run("update_machine.lua")
@@ -669,7 +662,7 @@ local function backgroundSyncTask()
os.run(getfenv and getfenv() or _ENV, "update_machine.lua")
end
end)
os.reboot()
-- Removed os.reboot() to prevent interrupting user unexpectedly
end
end
end
@@ -963,9 +956,7 @@ local function waitButtons()
end
end
elseif ev == 'config_updated' then
singleSegments = nil
-- If config was updated in background, return to force UI re-render
return
-- Ignore config_updated while waiting for buttons, to prevent interrupting user's selection
end
end
end
@@ -1211,10 +1202,9 @@ local function buildSingleSegments()
end
local function showSingleSegmentSelection()
while state.page == 'single_segment' do
if not singleSegments or #singleSegments == 0 then
singleSegments = buildSingleSegments()
end
singleSegmentScroll = 0
while state.page == 'single_segment' do
drawHeader('Select Single Segment', 'Select a line and fare')
Buttons = {}
local itemsPerPage = math.floor((h - 10) / 4) * 2
+35
View File
@@ -0,0 +1,35 @@
/*
* @Author: HenryDu8133 813367384@qq.com
* @Date: 2026-07-10 11:05:43
* @LastEditors: HenryDu8133 813367384@qq.com
* @LastEditTime: 2026-07-10 11:23:30
* @FilePath: \TicketMachine\update-db.js
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
const mysql = require('mysql2/promise');
async function run() {
const pool = mysql.createPool({
host: '127.0.0.1',
port: 3306,
user: 'cc-ticket-machine',
password: 'cc-ticket-machine',
database: 'cc-ticket-machine',
});
try {
const [rows] = await pool.query('SELECT data FROM config LIMIT 1');
if (rows.length > 0) {
let data = rows[0].data;
if (typeof data === 'string') data = JSON.parse(data);
data.lua_versions = data.lua_versions || {};
data.lua_versions.ticketmachine = 'v1.5.12';
data.lua_versions.gate = 'v1.5.9';
await pool.query('UPDATE config SET data = ?', [JSON.stringify(data)]);
console.log('Updated DB config to v1.5.12');
}
} catch(e) {
console.error(e);
} finally {
await pool.end();
}
}
run();
+5 -1
View File
@@ -191,7 +191,11 @@
const formatIcCardEventUnified = (ev) => {
const type = String(ev?.type || '').toLowerCase();
const action = String(ev?.action || '').toLowerCase();
const deviceId = ev?.device || ev?.device_id || ev?.["设备编号"] || ev?.["机器ID"] || '---';
let deviceId = ev?.device || ev?.device_id || ev?.["设备编号"] || ev?.["机器ID"] || '---';
if (/^\d+$/.test(deviceId)) deviceId = 'ticket_machine';
if (deviceId === 'ticket_machine') deviceId = '售票机';
if (deviceId === 'gate') deviceId = '闸机';
if (deviceId === 'refill_machine') deviceId = '充值机';
const timeStr = formatTime(ev?.ts);
const balance = ev?.balance ?? ev?.["余额"] ?? 0;
+5 -1
View File
@@ -90,7 +90,11 @@
const formatIcCardEventUnified = (ev) => {
const type = String(ev?.type || '').toLowerCase();
const action = String(ev?.action || '').toLowerCase();
const deviceId = ev?.device || ev?.device_id || ev?.["设备编号"] || ev?.["机器ID"] || '---';
let deviceId = ev?.device || ev?.device_id || ev?.["设备编号"] || ev?.["机器ID"] || '---';
if (/^\d+$/.test(deviceId)) deviceId = 'ticket_machine';
if (deviceId === 'ticket_machine') deviceId = '售票机';
if (deviceId === 'gate') deviceId = '闸机';
if (deviceId === 'refill_machine') deviceId = '充值机';
const timeStr = formatTime(ev?.ts);
const balance = ev?.balance ?? ev?.["余额"] ?? 0;
+10 -2
View File
@@ -348,7 +348,11 @@ createApp({
const formatTicketEventUnified = (ev) => {
const type = getTicketEventType(ev);
const action = getTicketEventAction(ev);
const deviceId = ev?.device || ev?.device_id || ev?.["设备编号"] || ev?.["机器ID"] || '---';
let deviceId = ev?.device || ev?.device_id || ev?.["设备编号"] || ev?.["机器ID"] || '---';
if (/^\d+$/.test(deviceId)) deviceId = 'ticket_machine';
if (deviceId === 'ticket_machine') deviceId = '售票机';
if (deviceId === 'gate') deviceId = '闸机';
if (deviceId === 'refill_machine') deviceId = '充值机';
const timeStr = formatTime(ev?.ts || ev?.["时间戳"]);
if (type === 'sale' || type === '售票') {
@@ -451,7 +455,11 @@ createApp({
const formatIcEventDetail = (ev) => {
const type = String(ev?.type || '').toLowerCase();
const action = String(ev?.action || '').toLowerCase();
const deviceId = ev?.device || ev?.device_id || ev?.["设备编号"] || ev?.["机器ID"] || '---';
let deviceId = ev?.device || ev?.device_id || ev?.["设备编号"] || ev?.["机器ID"] || '---';
if (/^\d+$/.test(deviceId)) deviceId = 'ticket_machine';
if (deviceId === 'ticket_machine') deviceId = '售票机';
if (deviceId === 'gate') deviceId = '闸机';
if (deviceId === 'refill_machine') deviceId = '充值机';
const timeStr = formatTime(ev?.ts);
const balance = ev?.balance ?? ev?.["余额"] ?? 0;
+27 -3
View File
@@ -96,7 +96,15 @@
{{ statusInfo.text }}
</span>
</div>
<div class="jr-route-board">
<div v-if="String(ticket.overview.train_type || ticket.overview['车型'] || '').toLowerCase() === 'single'" class="jr-route-board" style="justify-content: center; text-align: center;">
<div class="jr-station-block">
<div class="jr-station-line" style="justify-content: center;">
<span class="jr-station-title">{{ ticket.overview.start_name }}</span>
</div>
<div class="jr-station-en" style="text-align: center; margin-top: 4px;">单程单区间</div>
</div>
</div>
<div v-else class="jr-route-board">
<div class="jr-station-block">
<div class="jr-station-line">
<span class="jr-station-title">{{ ticket.overview.start_name }}</span>
@@ -113,7 +121,18 @@
<div class="jr-station-en">{{ ticket.overview.terminal_en }}</div>
</div>
</div>
<div class="jr-meta-grid">
<div v-if="String(ticket.overview.train_type || ticket.overview['车型'] || '').toLowerCase() === 'single'" class="jr-meta-grid" style="grid-template-columns: repeat(2, 1fr);">
<div class="jr-meta-item">
<span>票价</span>
<strong>¥ {{ ticket.overview.amount || 0 }}</strong>
</div>
<div class="jr-meta-item">
<span>更新时间</span>
<strong>{{ formatTime(ticket.overview.last_update_ts) }}</strong>
</div>
</div>
<div v-else class="jr-meta-grid">
<div class="jr-meta-item">
<span>车型</span>
<strong>{{ formatTrainType(ticket.overview.train_type) }}</strong>
@@ -298,7 +317,12 @@
}
const stationEn = event.station_en || event['站点英文'] || '';
const deviceId = event.device_id || event['设备编号'] || '';
let deviceId = event.device || event.device_id || event['设备编号'] || event['机器ID'] || '';
if (/^\d+$/.test(deviceId)) deviceId = 'ticket_machine';
if (deviceId === 'ticket_machine') deviceId = '售票机';
if (deviceId === 'gate') deviceId = '闸机';
if (deviceId === 'refill_machine') deviceId = '充值机';
if (stationEn && deviceId) return `${stationEn} (${deviceId})`;
if (deviceId) return `设备:${deviceId}`;
return stationEn;
+5 -1
View File
@@ -228,7 +228,11 @@ createApp({
const formatTicketEventUnified = (ev) => {
const type = getTicketEventType(ev);
const action = getTicketEventAction(ev);
const deviceId = ev?.device || ev?.device_id || ev?.["设备编号"] || ev?.["机器ID"] || '---';
let deviceId = ev?.device || ev?.device_id || ev?.["设备编号"] || ev?.["机器ID"] || '---';
if (/^\d+$/.test(deviceId)) deviceId = 'ticket_machine';
if (deviceId === 'ticket_machine') deviceId = '售票机';
if (deviceId === 'gate') deviceId = '闸机';
if (deviceId === 'refill_machine') deviceId = '充值机';
const timeStr = formatTime(ev?.ts || ev?.["时间戳"]);
if (type === 'sale' || type === '售票') {
+72 -25
View File
@@ -110,7 +110,11 @@
const formatTicketEventUnified = (ev) => {
const type = getEventType(ev);
const action = String(ev.action || ev["动作"] || '').toLowerCase();
const deviceId = ev.device || ev.device_id || ev["设备编号"] || ev["机器ID"] || '---';
let deviceId = ev.device || ev.device_id || ev["设备编号"] || ev["机器ID"] || '---';
if (/^\d+$/.test(deviceId)) deviceId = 'ticket_machine';
if (deviceId === 'ticket_machine') deviceId = '售票机';
if (deviceId === 'gate') deviceId = '闸机';
if (deviceId === 'refill_machine') deviceId = '充值机';
const timeStr = formatTime(ev.ts || ev["时间戳"]);
if (type === 'sale' || type === '售票') {
@@ -151,6 +155,9 @@
const overview = it.overview || it["概览"] || null;
const startName = overview ? (overview.start_name || overview["起点"]) : (it.start_name || it["起点"] || '---');
const terminalName = overview ? (overview.terminal_name || overview["终点"]) : (it.terminal_name || it["终点"] || '---');
const trainType = overview ? (overview.train_type || overview["车型"]) : (it.train_type || it["车型"]);
const isSingle = String(trainType || '').toLowerCase() === 'single';
const updateTime = formatTime(
(overview && (overview.last_update_ts || overview["上次更新时间"])) ||
it.last_update_ts ||
@@ -158,13 +165,20 @@
''
);
let routeHtml = '';
if (isSingle) {
routeHtml = `${escapeHtml(startName)} <span style="font-size: 0.8em; margin-left: 8px; color: #666; font-weight: normal;">单程单区间</span>`;
} else {
routeHtml = `${escapeHtml(startName)} → ${escapeHtml(terminalName)}`;
}
row.innerHTML = `
<div class="jr-ticket-row-head">
<span class="jr-ticket-id mono">${escapeHtml(id)}</span>
<span class="jr-status-pill ${isValidStatus(statusText) ? 'jr-status-valid' : (statusText === '已使用' ? 'jr-status-used' : 'jr-status-expired')}">${escapeHtml(statusText)}</span>
</div>
<div class="jr-ticket-route">
${escapeHtml(startName)} → ${escapeHtml(terminalName)}
${routeHtml}
</div>
<div class="jr-list-meta">最近更新 ${escapeHtml(updateTime)}</div>
`;
@@ -192,6 +206,60 @@
const stRaw = ov.status || ov["状态"] || d.status || d["状态"] || '';
const statusText = formatStatusText(stRaw);
const statusClass = isValidStatus(stRaw) ? 'jr-status-valid' : (statusText === '已使用' ? 'jr-status-used' : 'jr-status-expired');
const isSingle = String(ov.train_type || ov["车型"] || '').toLowerCase() === 'single';
let routeBoardHtml = '';
if (isSingle) {
routeBoardHtml = `
<div class="jr-route-board" style="justify-content: center; text-align: center;">
<div class="jr-station-block">
<div class="jr-station-line" style="justify-content: center;">
<span class="jr-station-title">${escapeHtml(ov.start_name || ov["起点"] || '---')}</span>
</div>
<div class="jr-station-en" style="text-align: center; margin-top: 4px;">单程单区间</div>
</div>
</div>
`;
} else {
routeBoardHtml = `
<div class="jr-route-board">
<div class="jr-station-block">
<div class="jr-station-line">
<span class="jr-station-title">${escapeHtml(ov.start_name || ov["起点"] || '---')}</span>
<span class="jr-station-code">${escapeHtml(ov.start_code || ov["起点编号"] || '')}</span>
</div>
<div class="jr-station-en">${escapeHtml(ov.start_en || ov["起点英文"] || '')}</div>
</div>
<div class="jr-route-track"><i class="fas fa-train"></i></div>
<div class="jr-station-block is-end">
<div class="jr-station-line">
<span class="jr-station-title">${escapeHtml(ov.terminal_name || ov["终点"] || '---')}</span>
<span class="jr-station-code">${escapeHtml(ov.terminal_code || ov["终点编号"] || '')}</span>
</div>
<div class="jr-station-en">${escapeHtml(ov.terminal_en || ov["终点英文"] || '')}</div>
</div>
</div>
`;
}
let metaGridHtml = '';
if (isSingle) {
metaGridHtml = `
<div class="jr-meta-grid" style="grid-template-columns: repeat(2, 1fr);">
<div class="jr-meta-item"><span>票价</span><strong>${escapeHtml(ov.amount ?? ov["金额"] ?? 0)}</strong></div>
<div class="jr-meta-item"><span>更新</span><strong>${escapeHtml(formatTime(ov.last_update_ts ?? ov["上次更新时间"]))}</strong></div>
</div>
`;
} else {
metaGridHtml = `
<div class="jr-meta-grid">
<div class="jr-meta-item"><span>车型</span><strong>${escapeHtml(formatTrainType(ov.train_type || ov["车型"]))}</strong></div>
<div class="jr-meta-item"><span>乘次</span><strong>${escapeHtml(ov.trips_total ?? ov["总乘次"] ?? 0)}</strong></div>
<div class="jr-meta-item"><span>票价</span><strong>${escapeHtml(ov.amount ?? ov["金额"] ?? 0)}</strong></div>
<div class="jr-meta-item"><span>更新</span><strong>${escapeHtml(formatTime(ov.last_update_ts ?? ov["上次更新时间"]))}</strong></div>
</div>
`;
}
detailEl.innerHTML = `
<div class="jr-ticket-preview" onclick="openTicketDetail('${id}')" style="cursor:pointer;" title="点击查看电子票看板">
@@ -199,29 +267,8 @@
<span class="jr-ticket-id mono">${id} <i class="fas fa-external-link-alt" style="font-size:0.8em; margin-left:4px"></i></span>
<span class="jr-status-pill ${statusClass}">${statusText}</span>
</div>
<div class="jr-route-board">
<div class="jr-station-block">
<div class="jr-station-line">
<span class="jr-station-title">${ov.start_name || ov["起点"] || '---'}</span>
<span class="jr-station-code">${ov.start_code || ov["起点编号"] || ''}</span>
</div>
<div class="jr-station-en">${ov.start_en || ov["起点英文"] || ''}</div>
</div>
<div class="jr-route-track"><i class="fas fa-train"></i></div>
<div class="jr-station-block is-end">
<div class="jr-station-line">
<span class="jr-station-title">${ov.terminal_name || ov["终点"] || '---'}</span>
<span class="jr-station-code">${ov.terminal_code || ov["终点编号"] || ''}</span>
</div>
<div class="jr-station-en">${ov.terminal_en || ov["终点英文"] || ''}</div>
</div>
</div>
<div class="jr-meta-grid">
<div class="jr-meta-item"><span>车型</span><strong>${formatTrainType(ov.train_type || ov["车型"])}</strong></div>
<div class="jr-meta-item"><span>乘次</span><strong>${ov.trips_total ?? ov["总乘次"] ?? 0}</strong></div>
<div class="jr-meta-item"><span>票价</span><strong>${ov.amount ?? ov["金额"] ?? 0}</strong></div>
<div class="jr-meta-item"><span>更新</span><strong>${formatTime(ov.last_update_ts ?? ov["上次更新时间"])}</strong></div>
</div>
${routeBoardHtml}
${metaGridHtml}
</div>
<div class="jr-panel-headline" style="margin:20px 0 14px;">