refactor(web): 优化订票线路图布局与换乘站视觉表现

This commit is contained in:
2026-07-11 23:37:35 +08:00
parent dc835f498d
commit 83c7d25cbe
18 changed files with 80 additions and 41 deletions
+4 -4
View File
@@ -1,7 +1,7 @@
{ {
"style.css": { "style.css": {
"size": 86271, "size": 86571,
"mtimeMs": 1783775484985.5583 "mtimeMs": 1783784204130.9187
}, },
"blog.css": { "blog.css": {
"size": 994, "size": 994,
@@ -16,8 +16,8 @@
"mtimeMs": 1783602619602.658 "mtimeMs": 1783602619602.658
}, },
"ticket-order.js": { "ticket-order.js": {
"size": 32083, "size": 34258,
"mtimeMs": 1783783215957.1775 "mtimeMs": 1783784148462.1907
}, },
"ticket-search.js": { "ticket-search.js": {
"size": 17269, "size": 17269,
+2 -2
View File
@@ -1,9 +1,9 @@
{ {
"style.css": 13, "style.css": 14,
"blog.css": 2, "blog.css": 2,
"custom-dialog.js": 11, "custom-dialog.js": 11,
"public-status.js": 14, "public-status.js": 14,
"ticket-order.js": 21, "ticket-order.js": 22,
"ticket-search.js": 12, "ticket-search.js": 12,
"ticket-route.js": 3, "ticket-route.js": 3,
"index.js": 5, "index.js": 5,
+1 -1
View File
@@ -7,7 +7,7 @@
<title>FMG</title> <title>FMG</title>
<link rel="icon" type="image/png" href="/FSE-ticket.png"> <link rel="icon" type="image/png" href="/FSE-ticket.png">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<link rel="stylesheet" href="style.css?v=13"> <link rel="stylesheet" href="style.css?v=14">
<link rel="stylesheet" href="blog.css?v=2"> <link rel="stylesheet" href="blog.css?v=2">
</head> </head>
+1 -1
View File
@@ -6,7 +6,7 @@
<title>首页|FSE铁路运输票务系统</title> <title>首页|FSE铁路运输票务系统</title>
<link rel="icon" type="image/png" href="/FSE-ticket.png"> <link rel="icon" type="image/png" href="/FSE-ticket.png">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<link rel="stylesheet" href="/style.css?v=13"> <link rel="stylesheet" href="/style.css?v=14">
</head> </head>
<body class="public-search jr-public-page"> <body class="public-search jr-public-page">
<div class="jr-public-shell"> <div class="jr-public-shell">
+1 -1
View File
@@ -7,7 +7,7 @@
<title>IC卡管理|FSE铁路运输票务系统</title> <title>IC卡管理|FSE铁路运输票务系统</title>
<link rel="icon" type="image/png" href="/FSE-ticket.png"> <link rel="icon" type="image/png" href="/FSE-ticket.png">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<link rel="stylesheet" href="/style.css?v=13"> <link rel="stylesheet" href="/style.css?v=14">
</head> </head>
<body class="jr-admin-page jr-admin-ic-page jr-public-page"> <body class="jr-admin-page jr-admin-ic-page jr-public-page">
+1 -1
View File
@@ -7,7 +7,7 @@
<title>IC卡详情|FSE铁路运输票务系统</title> <title>IC卡详情|FSE铁路运输票务系统</title>
<link rel="icon" type="image/png" href="/FSE-ticket.png"> <link rel="icon" type="image/png" href="/FSE-ticket.png">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<link rel="stylesheet" href="/style.css?v=13"> <link rel="stylesheet" href="/style.css?v=14">
</head> </head>
<body class="public-search jr-public-page"> <body class="public-search jr-public-page">
+1 -1
View File
@@ -7,7 +7,7 @@
<title>线上购卡|FSE铁路运输票务系统</title> <title>线上购卡|FSE铁路运输票务系统</title>
<link rel="icon" type="image/png" href="/FSE-ticket.png"> <link rel="icon" type="image/png" href="/FSE-ticket.png">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<link rel="stylesheet" href="/style.css?v=13"> <link rel="stylesheet" href="/style.css?v=14">
</head> </head>
<body class="public-search jr-public-page"> <body class="public-search jr-public-page">
+1 -1
View File
@@ -7,7 +7,7 @@
<title>IC卡查询|FSE铁路运输票务系统</title> <title>IC卡查询|FSE铁路运输票务系统</title>
<link rel="icon" type="image/png" href="/FSE-ticket.png"> <link rel="icon" type="image/png" href="/FSE-ticket.png">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<link rel="stylesheet" href="/style.css?v=13"> <link rel="stylesheet" href="/style.css?v=14">
</head> </head>
<body class="public-search jr-public-page"> <body class="public-search jr-public-page">
+1 -1
View File
@@ -7,7 +7,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>控制台|FSE铁路运输票务系统</title> <title>控制台|FSE铁路运输票务系统</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<link rel="stylesheet" href="style.css?v=13"> <link rel="stylesheet" href="style.css?v=14">
<script src="https://unpkg.com/vue@3/dist/vue.global.prod.js"></script> <script src="https://unpkg.com/vue@3/dist/vue.global.prod.js"></script>
<script src="/socket.io/socket.io.js"></script> <script src="/socket.io/socket.io.js"></script>
</head> </head>
+1 -1
View File
@@ -6,7 +6,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1" /> <meta name="viewport" content="width=device-width, initial-scale=1" />
<title>登录后台|FSE铁路运输票务系统</title> <title>登录后台|FSE铁路运输票务系统</title>
<link rel="icon" type="image/png" href="/FSE-ticket.png"> <link rel="icon" type="image/png" href="/FSE-ticket.png">
<link rel="stylesheet" href="/style.css?v=13" /> <link rel="stylesheet" href="/style.css?v=14" />
</head> </head>
<body class="jr-admin-login-page"> <body class="jr-admin-login-page">
<div class="jr-admin-login-shell"> <div class="jr-admin-login-shell">
+1 -1
View File
@@ -7,7 +7,7 @@
<title>票务查询|FSE铁路运输票务系统</title> <title>票务查询|FSE铁路运输票务系统</title>
<link rel="icon" type="image/png" href="/FSE-ticket.png"> <link rel="icon" type="image/png" href="/FSE-ticket.png">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<link rel="stylesheet" href="/style.css?v=13" /> <link rel="stylesheet" href="/style.css?v=14" />
</head> </head>
<body class="public-search jr-public-page"> <body class="public-search jr-public-page">
+13 -7
View File
@@ -1432,22 +1432,24 @@ input[type="date"].input::-webkit-calendar-picker-indicator {
/* Station Map */ /* Station Map */
.station-map-container { .station-map-container {
background: #00000033; background: radial-gradient(circle at top left, rgba(255,255,255,0.78), rgba(248,250,252,0.95) 38%, rgba(241,245,249,0.98) 100%);
padding: 24px; padding: 22px 24px 16px;
border-radius: 8px; border-radius: 24px;
margin-bottom: 20px; margin-bottom: 20px;
overflow-x: auto; overflow-x: auto;
display: flex; display: flex;
justify-content: center; justify-content: center;
min-height: 380px; min-height: 380px;
align-items: center; align-items: center;
border: 1px solid rgba(148, 163, 184, 0.28);
box-shadow: inset 0 1px 0 rgba(255,255,255,0.66);
} }
.station-map-container svg { .station-map-container svg {
min-width: 680px; min-width: 680px;
max-width: 100%; max-width: 100%;
height: auto; height: auto;
transform: scale(1.06); transform: scale(1.02);
transform-origin: center center; transform-origin: center center;
} }
@@ -1458,7 +1460,7 @@ input[type="date"].input::-webkit-calendar-picker-indicator {
.map-station.start .node-core { fill: var(--success) !important; r: 10; stroke: white; stroke-width: 3; } .map-station.start .node-core { fill: var(--success) !important; r: 10; stroke: white; stroke-width: 3; }
.map-station.end .node-core { fill: var(--danger) !important; r: 10; stroke: white; stroke-width: 3; } .map-station.end .node-core { fill: var(--danger) !important; r: 10; stroke: white; stroke-width: 3; }
.map-station text { pointer-events: none; } .map-station text { pointer-events: none; }
.map-station.transfer .node-core { stroke: #ffffffcc; stroke-width: 3; } .map-station.transfer .node-core { stroke: #e2e8f0; stroke-width: 3; }
.map-station.route .node-core { stroke: var(--primary); stroke-width: 4; } .map-station.route .node-core { stroke: var(--primary); stroke-width: 4; }
.map-station.route-transfer .node-core { stroke: #f59e0b; stroke-width: 4; } .map-station.route-transfer .node-core { stroke: #f59e0b; stroke-width: 4; }
@@ -2350,7 +2352,7 @@ body.jr-order-page .map-station:hover .node-core {
} }
body.jr-order-page .map-station .node-core { body.jr-order-page .map-station .node-core {
stroke: #1d3326; stroke: #334155;
} }
body.jr-order-page .map-station.start .node-core { body.jr-order-page .map-station.start .node-core {
@@ -2369,6 +2371,10 @@ body.jr-order-page .map-station.route-transfer .node-core {
stroke: #d69a0f; stroke: #d69a0f;
} }
body.jr-order-page .station-map-container text {
letter-spacing: 0.02em;
}
@media (max-width: 1080px) { @media (max-width: 1080px) {
.jr-hero, .jr-hero,
.jr-content-grid { .jr-content-grid {
@@ -4522,4 +4528,4 @@ body.jr-admin-login-page {
border-color: white; border-color: white;
} }
␍ ␍
+1 -1
View File
@@ -7,7 +7,7 @@
<title>电子客票|FSE铁路运输票务系统</title> <title>电子客票|FSE铁路运输票务系统</title>
<link rel="icon" type="image/png" href="/FSE-ticket.png"> <link rel="icon" type="image/png" href="/FSE-ticket.png">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<link rel="stylesheet" href="/style.css?v=13"> <link rel="stylesheet" href="/style.css?v=14">
<style> <style>
[v-cloak] { [v-cloak] {
display: none; display: none;
+2 -2
View File
@@ -7,7 +7,7 @@
<title>线上预定|FSE铁路运输票务系统</title> <title>线上预定|FSE铁路运输票务系统</title>
<link rel="icon" type="image/png" href="/FSE-ticket.png"> <link rel="icon" type="image/png" href="/FSE-ticket.png">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<link rel="stylesheet" href="/style.css?v=13"> <link rel="stylesheet" href="/style.css?v=14">
</head> </head>
<body class="public-search jr-order-page"> <body class="public-search jr-order-page">
@@ -158,7 +158,7 @@
</div> </div>
<script src="/custom-dialog.js?v=11"></script> <script src="/custom-dialog.js?v=11"></script>
<script src="/ticket-order.js?v=21"></script> <script src="/ticket-order.js?v=22"></script>
<script src="/public-status.js?v=14"></script> <script src="/public-status.js?v=14"></script>
<script> <script>
document.addEventListener('DOMContentLoaded', () => { document.addEventListener('DOMContentLoaded', () => {
+46 -13
View File
@@ -118,6 +118,7 @@
const lineStops = []; const lineStops = [];
const lineColors = []; const lineColors = [];
const linesByStation = new Map(); const linesByStation = new Map();
const lineIdxsByCanonical = {};
// NEW logic for breaking lines with '-' // NEW logic for breaking lines with '-'
let currentLineIdx = 0; let currentLineIdx = 0;
@@ -139,6 +140,9 @@
const arr = linesByStation.get(stopCode) || []; const arr = linesByStation.get(stopCode) || [];
arr.push(currentLineIdx); arr.push(currentLineIdx);
linesByStation.set(stopCode, arr); linesByStation.set(stopCode, arr);
const canonical = stationCanonicalByCode[stopCode] || stopCode;
if (!lineIdxsByCanonical[canonical]) lineIdxsByCanonical[canonical] = new Set();
lineIdxsByCanonical[canonical].add(currentLineIdx);
} }
currentSegment = []; currentSegment = [];
addedAny = true; addedAny = true;
@@ -154,6 +158,9 @@
const arr = linesByStation.get(stopCode) || []; const arr = linesByStation.get(stopCode) || [];
arr.push(currentLineIdx); arr.push(currentLineIdx);
linesByStation.set(stopCode, arr); linesByStation.set(stopCode, arr);
const canonical = stationCanonicalByCode[stopCode] || stopCode;
if (!lineIdxsByCanonical[canonical]) lineIdxsByCanonical[canonical] = new Set();
lineIdxsByCanonical[canonical].add(currentLineIdx);
} }
addedAny = true; addedAny = true;
} }
@@ -192,6 +199,11 @@
occurrences[canonical].push(i * minGapX); occurrences[canonical].push(i * minGapX);
} }
} }
const stationDegreeByCanonical = {};
for (const canonical of Object.keys(lineIdxsByCanonical)) {
stationDegreeByCanonical[canonical] = lineIdxsByCanonical[canonical].size;
}
stationXByCanonical = {}; stationXByCanonical = {};
for (const canonical of Object.keys(occurrences)) { for (const canonical of Object.keys(occurrences)) {
const arr = occurrences[canonical]; const arr = occurrences[canonical];
@@ -199,6 +211,16 @@
stationXByCanonical[canonical] = startX + Math.round(avg); stationXByCanonical[canonical] = startX + Math.round(avg);
} }
const sortedCanonicals = Object.keys(stationXByCanonical).sort((a, b) => stationXByCanonical[a] - stationXByCanonical[b]);
for (let i = 1; i < sortedCanonicals.length; i++) {
const prev = sortedCanonicals[i - 1];
const cur = sortedCanonicals[i];
const minSpacing = (stationDegreeByCanonical[prev] >= 2 || stationDegreeByCanonical[cur] >= 2) ? 108 : 82;
if (stationXByCanonical[cur] < stationXByCanonical[prev] + minSpacing) {
stationXByCanonical[cur] = stationXByCanonical[prev] + minSpacing;
}
}
for (let pass = 0; pass < 3; pass++) { for (let pass = 0; pass < 3; pass++) {
for (const li of lineStops) { for (const li of lineStops) {
let prevX = startX - minGapX; let prevX = startX - minGapX;
@@ -206,7 +228,8 @@
if (code === '-') continue; if (code === '-') continue;
const canonical = stationCanonicalByCode[code] || code; const canonical = stationCanonicalByCode[code] || code;
const x = stationXByCanonical[canonical] ?? (prevX + minGapX); const x = stationXByCanonical[canonical] ?? (prevX + minGapX);
const nx = Math.max(x, prevX + minGapX); const spacing = stationDegreeByCanonical[canonical] >= 2 ? 104 : minGapX;
const nx = Math.max(x, prevX + spacing);
if (stationXByCanonical[canonical] == null || nx > stationXByCanonical[canonical]) stationXByCanonical[canonical] = nx; if (stationXByCanonical[canonical] == null || nx > stationXByCanonical[canonical]) stationXByCanonical[canonical] = nx;
prevX = stationXByCanonical[canonical]; prevX = stationXByCanonical[canonical];
} }
@@ -282,7 +305,7 @@
// Vertical pill // Vertical pill
if (maxY > minY) { if (maxY > minY) {
svgContent += `<rect x="${x - 8}" y="${minY}" width="16" height="${maxY - minY}" rx="8" fill="#ffffff" stroke="#111827" stroke-width="3" />`; svgContent += `<rect x="${x - 6}" y="${minY + 12}" width="12" height="${Math.max(0, maxY - minY - 24)}" rx="6" fill="#f8fafc" stroke="#94a3b8" stroke-width="2" />`;
} }
const primaryCode = nodes[0].code; const primaryCode = nodes[0].code;
@@ -293,11 +316,11 @@
for (const node of nodes) { for (const node of nodes) {
const rOuter = isTransfer ? 13 : 12; const rOuter = isTransfer ? 13 : 12;
const outer = `<circle cx="${x}" cy="${node.y}" r="${rOuter}" fill="#ffffff" stroke="${node.color}" stroke-width="5" />`; const outer = `<circle cx="${x}" cy="${node.y}" r="${rOuter}" fill="#ffffff" stroke="${node.color}" stroke-width="5" />`;
const transferFill = isTransfer ? `<circle cx="${x}" cy="${node.y}" r="7" fill="#ffffff" stroke="#111827" stroke-width="3" />` : ''; const transferFill = isTransfer ? `<circle cx="${x}" cy="${node.y}" r="7" fill="#ffffff" stroke="#475569" stroke-width="2.5" />` : '';
nodesSvg += ` nodesSvg += `
${outer} ${outer}
${transferFill} ${transferFill}
<circle class="node-core" cx="${x}" cy="${node.y}" r="8" fill="#ffffff" stroke="#111827" stroke-width="3" /> <circle class="node-core" cx="${x}" cy="${node.y}" r="8" fill="#ffffff" stroke="#334155" stroke-width="2.5" />
`; `;
} }
@@ -305,18 +328,20 @@
let labelSvg = ''; let labelSvg = '';
if (isTransfer) { if (isTransfer) {
const labelY = minY - 34; // above the top node const labelY = minY - 34; // above the top node
labelSvg += `<rect x="${x - 42}" y="${labelY - 16}" width="84" height="24" rx="12" fill="rgba(241,245,249,0.92)" stroke="#cbd5e1" stroke-width="1.5" />`; const transferName = getStationDisplayName(canonical);
labelSvg += `<text x="${x}" y="${labelY}" text-anchor="middle" fill="#334155" font-size="13" font-weight="800">${getStationDisplayName(canonical)}</text>`; const transferLabelW = Math.max(72, transferName.length * 14 + 18);
labelSvg += `<rect x="${x - transferLabelW / 2}" y="${labelY - 16}" width="${transferLabelW}" height="24" rx="12" fill="rgba(248,250,252,0.96)" stroke="#cbd5e1" stroke-width="1.5" />`;
labelSvg += `<text x="${x}" y="${labelY}" text-anchor="middle" fill="#334155" font-size="13" font-weight="800">${transferName}</text>`;
} else { } else {
const labelY = maxY + 28; // below the single node const labelY = (nodes[0].y === baseY || nodes[0].y <= baseY + lineGapY) ? maxY + 28 : maxY + 30;
labelSvg += `<text x="${x}" y="${labelY}" text-anchor="middle" fill="#e5e7eb" font-size="14" font-weight="700">${name}</text>`; labelSvg += `<text x="${x}" y="${labelY}" text-anchor="middle" fill="#334155" font-size="14" font-weight="700">${name}</text>`;
} }
const hitY = (minY + maxY) / 2; const hitY = (minY + maxY) / 2;
const hitHeight = Math.max(30, maxY - minY + 30); const hitHeight = Math.max(30, maxY - minY + 30);
svgContent += ` svgContent += `
<g class="map-station ${isTransfer ? 'transfer' : ''}" data-code="${primaryCode}" onclick="handleStationClick('${primaryCode}')" style="cursor:pointer"> <g class="map-station ${isTransfer ? 'transfer' : ''}" data-code="${primaryCode}" data-canonical="${canonical}" onclick="handleStationClick('${primaryCode}')" style="cursor:pointer">
<rect x="${x - 20}" y="${hitY - hitHeight/2}" width="40" height="${hitHeight}" fill="transparent" /> <rect x="${x - 20}" y="${hitY - hitHeight/2}" width="40" height="${hitHeight}" fill="transparent" />
${nodesSvg} ${nodesSvg}
${labelSvg} ${labelSvg}
@@ -470,6 +495,13 @@
return { x, y }; return { x, y };
} }
function getMapStationEl(code) {
const normalized = String(code || '').trim();
if (!normalized) return null;
const canonical = stationCanonicalByCode[normalized] || normalized;
return document.querySelector(`.map-station[data-canonical="${canonical}"]`);
}
function renderRouteOverlay() { function renderRouteOverlay() {
const svgEl = mapContainer.querySelector('svg'); const svgEl = mapContainer.querySelector('svg');
if (!svgEl) return; if (!svgEl) return;
@@ -569,20 +601,21 @@
// Update Map Styles // Update Map Styles
document.querySelectorAll('.map-station').forEach(el => { document.querySelectorAll('.map-station').forEach(el => {
const code = el.getAttribute('data-code'); const code = el.getAttribute('data-code');
const canonical = el.getAttribute('data-canonical');
el.classList.remove('start', 'end', 'selected', 'route', 'route-transfer'); el.classList.remove('start', 'end', 'selected', 'route', 'route-transfer');
if(code === selection[0]) el.classList.add('start'); if (selection[0] && canonical === (stationCanonicalByCode[selection[0]] || selection[0])) el.classList.add('start');
if(code === selection[1]) el.classList.add('end'); if (selection[1] && canonical === (stationCanonicalByCode[selection[1]] || selection[1])) el.classList.add('end');
}); });
if (Array.isArray(currentRoute) && currentRoute.length > 0) { if (Array.isArray(currentRoute) && currentRoute.length > 0) {
for (const c of currentRoute) { for (const c of currentRoute) {
const el = document.querySelector(`.map-station[data-code="${c}"]`); const el = getMapStationEl(c);
if (el) el.classList.add('route'); if (el) el.classList.add('route');
} }
} }
if (Array.isArray(currentRouteTransfers) && currentRouteTransfers.length > 0) { if (Array.isArray(currentRouteTransfers) && currentRouteTransfers.length > 0) {
for (const c of currentRouteTransfers) { for (const c of currentRouteTransfers) {
const el = document.querySelector(`.map-station[data-code="${c}"]`); const el = getMapStationEl(c);
if (el) el.classList.add('route-transfer'); if (el) el.classList.add('route-transfer');
} }
} }
+1 -1
View File
@@ -8,7 +8,7 @@
<title>线路规划|FSE铁路运输票务系统</title> <title>线路规划|FSE铁路运输票务系统</title>
<link rel="icon" type="image/png" href="/FSE-ticket.png"> <link rel="icon" type="image/png" href="/FSE-ticket.png">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<link rel="stylesheet" href="/style.css?v=13"> <link rel="stylesheet" href="/style.css?v=14">
<script src="https://unpkg.com/vue@3/dist/vue.global.prod.js"></script> <script src="https://unpkg.com/vue@3/dist/vue.global.prod.js"></script>
<script src="/socket.io/socket.io.js"></script> <script src="/socket.io/socket.io.js"></script>
</head> </head>
+1 -1
View File
@@ -7,7 +7,7 @@
<title>票务查询|FSE铁路运输票务系统</title> <title>票务查询|FSE铁路运输票务系统</title>
<link rel="icon" type="image/png" href="/FSE-ticket.png"> <link rel="icon" type="image/png" href="/FSE-ticket.png">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<link rel="stylesheet" href="/style.css?v=13" /> <link rel="stylesheet" href="/style.css?v=14" />
</head> </head>
<body class="public-search jr-public-page"> <body class="public-search jr-public-page">
+1 -1
View File
@@ -7,7 +7,7 @@
<title>凭证详情|FSE铁路运输票务系统</title> <title>凭证详情|FSE铁路运输票务系统</title>
<link rel="icon" type="image/png" href="/FSE-ticket.png"> <link rel="icon" type="image/png" href="/FSE-ticket.png">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<link rel="stylesheet" href="/style.css?v=13" /> <link rel="stylesheet" href="/style.css?v=14" />
</head> </head>
<body class="public-search jr-public-page"> <body class="public-search jr-public-page">