diff --git a/server/routes/public.js b/server/routes/public.js index 5ecbf55..1e38931 100644 --- a/server/routes/public.js +++ b/server/routes/public.js @@ -257,9 +257,19 @@ router.post('/orders', async (req, res) => { return res.status(400).json({ ok: false, error: 'missing start/terminal/ride_date' }); } const resolveStation = buildStationResolver(); - const fromCode = resolveStation(from); - const toCode = resolveStation(to); - const priceSingle = LogicService.computePrice(fromCode, toCode, type); + let fromCode = resolveStation(from); + let toCode = resolveStation(to); + + let priceSingle = 0; + if (type === 'single') { + priceSingle = Math.max(0, Number(req.body.price) || 0); + // keep from and to as whatever string was passed (e.g. line and fare) + fromCode = from; + toCode = to; + } else { + priceSingle = LogicService.computePrice(fromCode, toCode, type); + } + const price = Math.max(0, priceSingle * t); const code = LogicService.genVoucherCode(); const rec = { code, start: fromCode, terminal: toCode, train_type: type, trips: t, ride_date: date, price, created_ts: Date.now(), consumed: false }; diff --git a/web/ic-card-admin.js b/web/ic-card-admin.js index 6c87391..5c10a7d 100644 --- a/web/ic-card-admin.js +++ b/web/ic-card-admin.js @@ -199,18 +199,23 @@ const cardType = ev?.detail?.card_type || ev?.card_type || ev?.["类型"] || '储值卡'; return `[${cardType}];余额: ${balance};时间: ${timeStr}`; } - if (type === 'topup' || type === 'refill' || action === 'topup') { + if (type === 'topup' || type === 'refill' || action === 'topup' || type === '充值') { const amount = ev?.amount ?? ev?.["充值数额"] ?? 0; + const code = ev?.station_code || ev?.["站点编号"] || '---'; + const name = ev?.station_name || ev?.["站点中文"] || ev?.["发生站"] || (typeof getStationName === 'function' && code !== '---' ? getStationName(code) : code); + if (code !== '---' || ev?.station_name) { + return `机器ID: ${deviceId};站点编号: ${code};站点中文: ${name};充值数额: ${amount};余额: ${balance};时间: ${timeStr}`; + } return `机器ID: ${deviceId};充值数额: ${amount};余额: ${balance};时间: ${timeStr}`; } - if (action === 'entry' || type === 'entry') { + if (action === 'entry' || type === 'entry' || type === '进站') { const code = ev?.station_code || ev?.["站点编号"] || '---'; - const name = ev?.station_name || ev?.["站点中文"] || ev?.["发生站"] || '---'; + const name = ev?.station_name || ev?.["站点中文"] || ev?.["发生站"] || (typeof getStationName === 'function' && code !== '---' ? getStationName(code) : code); return `机器ID: ${deviceId};站点编号: ${code};站点中文: ${name};余额: ${balance};时间: ${timeStr}`; } - if (action === 'exit' || type === 'exit') { + if (action === 'exit' || type === 'exit' || type === '出站') { const code = ev?.station_code || ev?.["站点编号"] || '---'; - const name = ev?.station_name || ev?.["站点中文"] || ev?.["发生站"] || '---'; + const name = ev?.station_name || ev?.["站点中文"] || ev?.["发生站"] || (typeof getStationName === 'function' && code !== '---' ? getStationName(code) : code); return `机器ID: ${deviceId};站点编号: ${code};站点中文: ${name};余额: ${balance};时间: ${timeStr}`; } @@ -355,7 +360,18 @@ }, 240); }); + let stationMap = {}; + window.getStationName = (code) => stationMap[code] || code; + (async () => { + try { + const res = await fetch('/api/public/stations'); + const list = await res.json(); + if (Array.isArray(list)) { + list.forEach(s => { stationMap[s.code] = s.name || s.cn_name; }); + } + } catch(e) {} + await pingServer(); await refreshList(false); if (state.cards[0]) await loadCard(state.cards[0].card_id); diff --git a/web/ic-card-search.js b/web/ic-card-search.js index bcd29c8..f63ca17 100644 --- a/web/ic-card-search.js +++ b/web/ic-card-search.js @@ -100,16 +100,21 @@ } if (type === 'topup' || type === 'refill' || action === 'topup' || type === '充值') { const amount = ev?.amount ?? ev?.["充值数额"] ?? 0; + const code = ev?.station_code || ev?.["站点编号"] || '---'; + const name = ev?.station_name || ev?.["站点中文"] || ev?.["发生站"] || (typeof getStationName === 'function' && code !== '---' ? getStationName(code) : code); + if (code !== '---' || ev?.station_name) { + return `机器ID: ${deviceId};站点编号: ${code};站点中文: ${name};充值数额: ${amount};余额: ${balance};时间: ${timeStr}`; + } return `机器ID: ${deviceId};充值数额: ${amount};余额: ${balance};时间: ${timeStr}`; } if (action === 'entry' || type === 'entry' || type === '进站') { const code = ev?.station_code || ev?.["站点编号"] || '---'; - const name = ev?.station_name || ev?.["站点中文"] || ev?.["发生站"] || '---'; + const name = ev?.station_name || ev?.["站点中文"] || ev?.["发生站"] || (typeof getStationName === 'function' && code !== '---' ? getStationName(code) : code); return `机器ID: ${deviceId};站点编号: ${code};站点中文: ${name};余额: ${balance};时间: ${timeStr}`; } if (action === 'exit' || type === 'exit' || type === '出站') { const code = ev?.station_code || ev?.["站点编号"] || '---'; - const name = ev?.station_name || ev?.["站点中文"] || ev?.["发生站"] || '---'; + const name = ev?.station_name || ev?.["站点中文"] || ev?.["发生站"] || (typeof getStationName === 'function' && code !== '---' ? getStationName(code) : code); return `机器ID: ${deviceId};站点编号: ${code};站点中文: ${name};余额: ${balance};时间: ${timeStr}`; } @@ -261,10 +266,25 @@ const params = new URLSearchParams(location.search); const q = params.get('q'); - if (q) { - inputEl.value = q; - doQuery().catch((error) => renderQueryError(error.message || String(error))); - } else { - loadAllCards().catch((error) => renderQueryError(error.message || String(error))); + + let stationMap = {}; + window.getStationName = (code) => stationMap[code] || code; + + async function init() { + try { + const res = await fetch('/api/public/stations'); + const list = await res.json(); + if (Array.isArray(list)) { + list.forEach(s => { stationMap[s.code] = s.name || s.cn_name; }); + } + } catch(e) {} + + if (q) { + inputEl.value = q; + doQuery().catch((error) => renderQueryError(error.message || String(error))); + } else { + loadAllCards().catch((error) => renderQueryError(error.message || String(error))); + } } + init(); })(); diff --git a/web/index.js b/web/index.js index a4e1fb0..c77d682 100644 --- a/web/index.js +++ b/web/index.js @@ -353,22 +353,24 @@ createApp({ if (type === 'sale' || type === '售票') { const cost = ev?.cost ?? ev?.price ?? ev?.amount ?? ev?.["票价"] ?? ev?.["售票额"] ?? '0'; - return `机器ID: ${deviceId};票价: ${cost};时间: ${timeStr}`; + const code = ev?.station_code || ev?.["站点编号"] || '---'; + const name = ev?.station_name || ev?.["售票站"] || ev?.["发生站"] || (typeof getStationName === 'function' && code !== '---' ? getStationName(code) : code); + return `机器ID: ${deviceId};站点编号: ${code};站点中文: ${name};票价: ${cost};时间: ${timeStr}`; } if (type === 'entry' || action === 'entry') { const code = ev?.station_code || ev?.["站点编号"] || '---'; - const name = ev?.station_name || ev?.["站点中文"] || ev?.["发生站"] || '---'; + const name = ev?.station_name || ev?.["站点中文"] || ev?.["发生站"] || (typeof getStationName === 'function' && code !== '---' ? getStationName(code) : code); return `机器ID: ${deviceId};站点编号: ${code};站点中文: ${name};时间: ${timeStr}`; } if (type === 'exit' || action === 'exit') { const code = ev?.station_code || ev?.["站点编号"] || '---'; - const name = ev?.station_name || ev?.["站点中文"] || ev?.["发生站"] || '---'; + const name = ev?.station_name || ev?.["站点中文"] || ev?.["发生站"] || (typeof getStationName === 'function' && code !== '---' ? getStationName(code) : code); return `机器ID: ${deviceId};站点编号: ${code};站点中文: ${name};时间: ${timeStr}`; } // fallback const code = ev?.station_code || ev?.["站点编号"] || '---'; - const name = ev?.station_name || ev?.["站点中文"] || ev?.["发生站"] || '---'; + const name = ev?.station_name || ev?.["站点中文"] || ev?.["发生站"] || (typeof getStationName === 'function' && code !== '---' ? getStationName(code) : code); return `机器ID: ${deviceId};站点编号: ${code};站点中文: ${name};时间: ${timeStr}`; }; @@ -459,18 +461,23 @@ createApp({ const cardType = ev?.detail?.card_type || ev?.card_type || ev?.["类型"] || '储值卡'; return `[${cardType}];余额: ${balance};时间: ${timeStr}`; } - if (type === 'topup' || type === 'refill' || action === 'topup') { + if (type === 'topup' || type === 'refill' || action === 'topup' || type === '充值') { const amount = ev?.amount ?? ev?.["充值数额"] ?? 0; + const code = ev?.station_code || ev?.["站点编号"] || '---'; + const name = ev?.station_name || ev?.["站点中文"] || ev?.["发生站"] || (typeof getStationName === 'function' && code !== '---' ? getStationName(code) : code); + if (code !== '---' || ev?.station_name) { + return `机器ID: ${deviceId};站点编号: ${code};站点中文: ${name};充值数额: ${amount};余额: ${balance};时间: ${timeStr}`; + } return `机器ID: ${deviceId};充值数额: ${amount};余额: ${balance};时间: ${timeStr}`; } if (action === 'entry' || type === 'entry') { const code = ev?.station_code || ev?.["站点编号"] || '---'; - const name = ev?.station_name || ev?.["站点中文"] || ev?.["发生站"] || '---'; + const name = ev?.station_name || ev?.["站点中文"] || ev?.["发生站"] || (typeof getStationName === 'function' && code !== '---' ? getStationName(code) : code); return `机器ID: ${deviceId};站点编号: ${code};站点中文: ${name};余额: ${balance};时间: ${timeStr}`; } if (action === 'exit' || type === 'exit') { const code = ev?.station_code || ev?.["站点编号"] || '---'; - const name = ev?.station_name || ev?.["站点中文"] || ev?.["发生站"] || '---'; + const name = ev?.station_name || ev?.["站点中文"] || ev?.["发生站"] || (typeof getStationName === 'function' && code !== '---' ? getStationName(code) : code); return `机器ID: ${deviceId};站点编号: ${code};站点中文: ${name};余额: ${balance};时间: ${timeStr}`; } diff --git a/web/ticket-route.js b/web/ticket-route.js index 7e8d7b0..3f03f56 100644 --- a/web/ticket-route.js +++ b/web/ticket-route.js @@ -233,22 +233,24 @@ createApp({ if (type === 'sale' || type === '售票') { const cost = ev?.cost ?? ev?.price ?? ev?.amount ?? ev?.["票价"] ?? ev?.["售票额"] ?? '0'; - return `机器ID: ${deviceId};票价: ${cost};时间: ${timeStr}`; + const code = ev?.station_code || ev?.["站点编号"] || '---'; + const name = ev?.station_name || ev?.["售票站"] || ev?.["发生站"] || (typeof getStationName === 'function' && code !== '---' ? getStationName(code) : code); + return `机器ID: ${deviceId};站点编号: ${code};站点中文: ${name};票价: ${cost};时间: ${timeStr}`; } if (type === 'entry' || action === 'entry') { const code = ev?.station_code || ev?.["站点编号"] || '---'; - const name = ev?.station_name || ev?.["站点中文"] || ev?.["发生站"] || '---'; + const name = ev?.station_name || ev?.["站点中文"] || ev?.["发生站"] || (typeof getStationName === 'function' && code !== '---' ? getStationName(code) : code); return `机器ID: ${deviceId};站点编号: ${code};站点中文: ${name};时间: ${timeStr}`; } if (type === 'exit' || action === 'exit') { const code = ev?.station_code || ev?.["站点编号"] || '---'; - const name = ev?.station_name || ev?.["站点中文"] || ev?.["发生站"] || '---'; + const name = ev?.station_name || ev?.["站点中文"] || ev?.["发生站"] || (typeof getStationName === 'function' && code !== '---' ? getStationName(code) : code); return `机器ID: ${deviceId};站点编号: ${code};站点中文: ${name};时间: ${timeStr}`; } // fallback const code = ev?.station_code || ev?.["站点编号"] || '---'; - const name = ev?.station_name || ev?.["站点中文"] || ev?.["发生站"] || '---'; + const name = ev?.station_name || ev?.["站点中文"] || ev?.["发生站"] || (typeof getStationName === 'function' && code !== '---' ? getStationName(code) : code); return `机器ID: ${deviceId};站点编号: ${code};站点中文: ${name};时间: ${timeStr}`; }; diff --git a/web/ticket-search.js b/web/ticket-search.js index cf041e8..3070bcf 100644 --- a/web/ticket-search.js +++ b/web/ticket-search.js @@ -115,22 +115,24 @@ if (type === 'sale' || type === '售票') { const cost = ev.cost ?? ev.price ?? ev.amount ?? ev["票价"] ?? ev["售票额"] ?? '0'; - return `机器ID: ${deviceId};票价: ${cost};时间: ${timeStr}`; + const code = ev.station_code || ev["站点编号"] || '---'; + const name = ev.station_name || ev["售票站"] || ev["发生站"] || (typeof getStationName === 'function' && code !== '---' ? getStationName(code) : code); + return `机器ID: ${deviceId};站点编号: ${code};站点中文: ${name};票价: ${cost};时间: ${timeStr}`; } if (type === 'entry' || action === 'entry') { const code = ev.station_code || ev["站点编号"] || '---'; - const name = ev.station_name || ev["站点中文"] || ev["发生站"] || '---'; + const name = ev.station_name || ev["站点中文"] || ev["发生站"] || (typeof getStationName === 'function' && code !== '---' ? getStationName(code) : code); return `机器ID: ${deviceId};站点编号: ${code};站点中文: ${name};时间: ${timeStr}`; } if (type === 'exit' || action === 'exit') { const code = ev.station_code || ev["站点编号"] || '---'; - const name = ev.station_name || ev["站点中文"] || ev["发生站"] || '---'; + const name = ev.station_name || ev["站点中文"] || ev["发生站"] || (typeof getStationName === 'function' && code !== '---' ? getStationName(code) : code); return `机器ID: ${deviceId};站点编号: ${code};站点中文: ${name};时间: ${timeStr}`; } // fallback const code = ev.station_code || ev["站点编号"] || '---'; - const name = ev.station_name || ev["站点中文"] || ev["发生站"] || '---'; + const name = ev.station_name || ev["站点中文"] || ev["发生站"] || (typeof getStationName === 'function' && code !== '---' ? getStationName(code) : code); return `机器ID: ${deviceId};站点编号: ${code};站点中文: ${name};时间: ${timeStr}`; }; @@ -302,13 +304,27 @@ const sp = new URLSearchParams(location.search); const qid = sp.get('id'); - if (qid) { - qEl.value = qid; - loadDetail(qid); - doSearch(); - } else { - doSearch(); + let stationMap = {}; + window.getStationName = (code) => stationMap[code] || code; + + async function init() { + try { + const res = await fetch('/api/public/stations'); + const list = await res.json(); + if (Array.isArray(list)) { + list.forEach(s => { stationMap[s.code] = s.name || s.cn_name; }); + } + } catch(e) {} + + if (qid) { + qEl.value = qid; + loadDetail(qid); + doSearch(); + } else { + doSearch(); + } + loadPopular(); } - loadPopular(); + init(); })();