feat(web): 撤销静态SVG图片渲染,回退到自动线条生成模式,并保留断点支持

This commit is contained in:
2026-07-11 22:23:12 +08:00
parent 0c1341e9c7
commit 1ce7fd630b
6 changed files with 207 additions and 192 deletions
-75
View File
@@ -1139,80 +1139,6 @@ createApp({
const zoomFareMapOut = () => { fareMapScale.value = Math.max(0.3, Math.round((fareMapScale.value - 0.1) * 100) / 100); };
const zoomFareMapReset = () => { fareMapScale.value = 1; };
const mapBindingMode = ref(false);
const mapBindingStation = ref('');
const mapImageRef = ref(null);
const unboundStationsGrouped = computed(() => {
const groups = {};
stations.value.forEach(s => {
const name = String(s.name || s.cn_name || '').trim();
if (!groups[name]) groups[name] = [];
groups[name].push(s);
});
const out = [];
for (const [name, list] of Object.entries(groups)) {
out.push({
name,
isTransfer: list.length > 1,
stations: list,
isBound: list.every(s => s.svg_x != null && s.svg_y != null)
});
}
return out.sort((a, b) => {
if (a.isBound !== b.isBound) return a.isBound ? 1 : -1;
if (a.isTransfer !== b.isTransfer) return a.isTransfer ? -1 : 1;
return 0;
});
});
const onMapImageClick = async (e) => {
if (!mapBindingMode.value || !mapBindingStation.value) return;
const img = mapImageRef.value;
if (!img) return;
const rect = img.getBoundingClientRect();
const x = e.clientX - rect.left;
const y = e.clientY - rect.top;
const percentX = (x / rect.width) * 100;
const percentY = (y / rect.height) * 100;
const station = stations.value.find(s => s.code === mapBindingStation.value);
if (!station) return;
const pctX = Number(percentX.toFixed(2));
const pctY = Number(percentY.toFixed(2));
const targetName = String(station.name || station.cn_name || '').trim().toLowerCase();
// Auto-bind all stations with the same name (transfers)
const stationsToUpdate = stations.value.filter(s => {
if (s.code === mapBindingStation.value) return true;
const sName = String(s.name || s.cn_name || '').trim().toLowerCase();
return targetName && sName === targetName;
});
try {
for (const s of stationsToUpdate) {
s.svg_x = pctX;
s.svg_y = pctY;
await requestJson(`/api/stations/${encodeURIComponent(s.code)}`, {
method: 'PUT',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify(s)
}, { expectOk: true });
}
// Find the next station without coordinates and select it
const nextStation = stations.value.find(s => s.svg_x == null && s.svg_y == null);
if (nextStation) {
mapBindingStation.value = nextStation.code;
}
} catch (err) {
alert('保存坐标失败:' + err.message);
}
};
// --- Management Actions ---
const createStation = async () => {
@@ -1845,7 +1771,6 @@ createApp({
showAddLine, showAddStation, newLine, newStation, fareMapSvg, ticketSearch,
assetsManifest, assetsFarePreview, assetsRouteMapUrl, assetsFareTableUrl,
uploadRouteMap, uploadFareTable, deleteRouteMap, deleteFareTable,
mapBindingMode, mapBindingStation, mapImageRef, onMapImageClick,
// Management
selectedLine, fareMode, stationEditMode, fareSelection, showFareModal, currentFare, availableStations,