feat: 优化自动更新逻辑,移除单程票购票并升级版本至1.0.18
升级package.json版本至1.0.18;重构update_gate.lua和update_machine.lua,支持--silent静默运行参数,统一日志输出逻辑;优化ticketmachine.lua和gate.lua的自动更新触发逻辑,新增设备空闲检测,避免打断用户操作,仅在空闲时执行静默更新后重启设备;修复ticketmachine.lua中state变量重复声明的问题;移除Web端ticket-order相关的单程票购票UI与业务逻辑,简化购票流程;将gate.lua中的版本检查间隔从5秒调整为60秒,优化设备ID显示格式。
This commit is contained in:
+7
-133
@@ -565,43 +565,9 @@
|
||||
|
||||
async function previewPrice(force = false){
|
||||
const seq = ++previewSeq;
|
||||
const ticketClass = document.querySelector('input[name="ticketClass"]:checked').value;
|
||||
const type = document.querySelector('input[name="trainType"]:checked').value;
|
||||
const trips = normalizeTrips();
|
||||
|
||||
if (ticketClass === 'single') {
|
||||
const lineName = document.getElementById('singleSegmentSelection').value;
|
||||
const priceStr = document.getElementById('singleSegmentPrice').value;
|
||||
if (!lineName || !priceStr) {
|
||||
priceBox.innerHTML = '<div class="empty-state jr-empty-state"><p>请选择单程区间</p></div>';
|
||||
return;
|
||||
}
|
||||
const cost = Number(priceStr) * trips;
|
||||
priceBox.innerHTML = `
|
||||
<div class="list-item jr-result-row">
|
||||
<span class="k">线路</span>
|
||||
<span class="v" style="font-weight:700; color:#0ea5e9;">${lineName}</span>
|
||||
</div>
|
||||
<div class="list-item jr-result-row">
|
||||
<span class="k">区间</span>
|
||||
<span class="v">任意单区间</span>
|
||||
</div>
|
||||
<div class="list-item jr-result-row">
|
||||
<span class="k">车型</span>
|
||||
<span class="v">${type}</span>
|
||||
</div>
|
||||
<div class="list-item jr-result-row">
|
||||
<span class="k">单价</span>
|
||||
<span class="v">$${priceStr}</span>
|
||||
</div>
|
||||
<div class="list-item jr-result-row">
|
||||
<span class="k">总价</span>
|
||||
<span class="v" style="font-size:18px; font-weight:800; color:#0ea5e9;">$${cost}</span>
|
||||
</div>
|
||||
`;
|
||||
return;
|
||||
}
|
||||
|
||||
const from = (fromEl.value||'').trim();
|
||||
const to = (toEl.value||'').trim();
|
||||
if(!from || !to){ priceBox.innerHTML = '<div class="empty-state jr-empty-state"><p>请选择起点与终点</p></div>'; return; }
|
||||
@@ -679,29 +645,18 @@
|
||||
|
||||
// Create Order with auto-preview
|
||||
async function createOrder(){
|
||||
const ticketClass = document.querySelector('input[name="ticketClass"]:checked').value;
|
||||
const type = document.querySelector('input[name="trainType"]:checked').value;
|
||||
const trips = normalizeTrips();
|
||||
const ride_date = new Date().toISOString().slice(0, 10);
|
||||
|
||||
let payload = null;
|
||||
if (ticketClass === 'single') {
|
||||
const lineName = document.getElementById('singleSegmentSelection').value;
|
||||
const priceStr = document.getElementById('singleSegmentPrice').value;
|
||||
if (!lineName || !priceStr) {
|
||||
alert('请选择单程区间');
|
||||
return;
|
||||
}
|
||||
payload = { start: lineName, terminal: 'SINGLE_SEGMENT', train_type: 'single', price: Number(priceStr), trips, ride_date };
|
||||
} else {
|
||||
const from = (fromEl.value||'').trim();
|
||||
const to = (toEl.value||'').trim();
|
||||
if(!from || !to){ alert('请完整填写信息'); return; }
|
||||
|
||||
// Auto-fetch price before creating
|
||||
await previewPrice(true);
|
||||
payload = { start: from, terminal: to, train_type: type, trips, ride_date };
|
||||
}
|
||||
const from = (fromEl.value||'').trim();
|
||||
const to = (toEl.value||'').trim();
|
||||
if(!from || !to){ alert('请完整填写信息'); return; }
|
||||
|
||||
// Auto-fetch price before creating
|
||||
await previewPrice(true);
|
||||
payload = { start: from, terminal: to, train_type: type, trips, ride_date };
|
||||
|
||||
try{
|
||||
const res = await fetch('/api/public/orders', { method:'POST', headers:{ 'Content-Type':'application/json' }, body: JSON.stringify(payload) });
|
||||
@@ -740,89 +695,8 @@
|
||||
document.querySelectorAll('input[name="trainType"]').forEach(el => {
|
||||
el.onchange = () => { if(fromEl.value && toEl.value) previewPrice(); };
|
||||
});
|
||||
document.querySelectorAll('input[name="ticketClass"]').forEach(r => r.addEventListener('change', toggleTicketClass));
|
||||
if (tripsEl) {
|
||||
tripsEl.oninput = () => { if(fromEl.value && toEl.value) previewPrice(); };
|
||||
tripsEl.onchange = () => { normalizeTrips(); if(fromEl.value && toEl.value) previewPrice(); };
|
||||
}
|
||||
|
||||
function toggleTicketClass() {
|
||||
const isSingle = document.querySelector('input[name="ticketClass"]:checked').value === 'single';
|
||||
if (isSingle) {
|
||||
document.getElementById('normalTicketView').style.display = 'none';
|
||||
document.getElementById('singleTicketView').style.display = 'block';
|
||||
document.getElementById('tripsBlock').style.display = 'none';
|
||||
if (tripsEl) tripsEl.value = 1;
|
||||
renderSingleSegments();
|
||||
} else {
|
||||
document.getElementById('normalTicketView').style.display = 'block';
|
||||
document.getElementById('singleTicketView').style.display = 'none';
|
||||
document.getElementById('tripsBlock').style.display = 'block';
|
||||
}
|
||||
previewPrice(true);
|
||||
}
|
||||
|
||||
async function renderSingleSegments() {
|
||||
const listEl = document.getElementById('singleSegmentList');
|
||||
if (listEl.innerHTML.includes('jr-result-row')) return; // Already rendered
|
||||
listEl.innerHTML = '<div class="loading">加载区间数据...</div>';
|
||||
try {
|
||||
const [lines, fares] = await Promise.all([
|
||||
fetch('/api/public/lines').then(r=>r.json()),
|
||||
fetch('/api/public/fares').then(r=>r.json())
|
||||
]);
|
||||
|
||||
const type = document.querySelector('input[name="trainType"]:checked').value;
|
||||
const segments = [];
|
||||
|
||||
lines.forEach(line => {
|
||||
const stops = Array.isArray(line.stops) ? line.stops : (Array.isArray(line.站点列表) ? line.站点列表 : []);
|
||||
const lineFares = new Set();
|
||||
for (let i = 0; i < stops.length - 1; i++) {
|
||||
const a = stops[i], b = stops[i+1];
|
||||
const f = fares.find(x => (x.from === a && x.to === b) || (x.from === b && x.to === a));
|
||||
if (f) {
|
||||
const cost = type === 'Express' ? (f.cost_express ?? f.cost ?? 0) : (f.cost_regular ?? f.cost ?? 0);
|
||||
lineFares.add(Number(cost));
|
||||
}
|
||||
}
|
||||
lineFares.forEach(cost => {
|
||||
segments.push({
|
||||
lineName: line.name || line.线路名称 || '未知线路',
|
||||
color: line.color || line.颜色 || '#93a2b7',
|
||||
cost
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
if (segments.length === 0) {
|
||||
listEl.innerHTML = '<div class="empty-state jr-empty-state"><p>暂无单程区间数据</p></div>';
|
||||
return;
|
||||
}
|
||||
|
||||
let html = '';
|
||||
segments.forEach((seg, idx) => {
|
||||
html += `
|
||||
<label class="list-item jr-result-row" style="cursor: pointer; display: flex; align-items: center; gap: 12px; padding: 12px;">
|
||||
<input type="radio" name="singleSegmentOption" value="${idx}" onchange="selectSingleSegment('${seg.lineName}', ${seg.cost})" style="margin: 0;">
|
||||
<div style="width: 12px; height: 12px; border-radius: 50%; background-color: ${seg.color};"></div>
|
||||
<div style="flex: 1;">
|
||||
<div style="font-weight: bold; color: #1e293b;">${seg.lineName}</div>
|
||||
<div style="font-size: 12px; color: #64748b;">单区间票</div>
|
||||
</div>
|
||||
<div style="font-weight: bold; color: #0ea5e9;">$${seg.cost}</div>
|
||||
</label>
|
||||
`;
|
||||
});
|
||||
listEl.innerHTML = html;
|
||||
} catch (e) {
|
||||
listEl.innerHTML = '<div class="error">加载区间数据失败</div>';
|
||||
}
|
||||
}
|
||||
|
||||
window.selectSingleSegment = (lineName, cost) => {
|
||||
document.getElementById('singleSegmentSelection').value = lineName;
|
||||
document.getElementById('singleSegmentPrice').value = cost;
|
||||
previewPrice(true);
|
||||
};
|
||||
})();
|
||||
|
||||
Reference in New Issue
Block a user