feat: 支持编辑线路图署名并固定 CC BY 4.0

This commit is contained in:
2026-07-19 00:16:20 +08:00
parent 6195ebb6be
commit 847957be61
6 changed files with 106 additions and 12 deletions
+21 -5
View File
@@ -56,10 +56,11 @@ createApp({
const logMax = ref(200);
const logLoading = ref(false);
const orders = ref([]);
const assetsManifest = reactive({ routeMap: null, fareTable: null, updatedAt: null });
const assetsManifest = reactive({ routeMap: null, routeMapCredit: '', routeMapLicense: 'CC BY 4.0', fareTable: null, updatedAt: null });
const assetsFarePreview = reactive({ headers: [], rows: [] });
const assetsRouteMapUrl = ref('');
const assetsFareTableUrl = ref('');
const assetsForm = reactive({ routeMapCredit: '' });
const icCards = ref([]);
const icCardSearch = ref('');
const icSelectedId = ref('');
@@ -577,8 +578,11 @@ createApp({
const fetchAssetsManifest = async () => {
const data = await requestJson('/api/assets/manifest');
assetsManifest.routeMap = data ? (data.routeMap || null) : null;
assetsManifest.routeMapCredit = data ? String(data.routeMapCredit || '') : '';
assetsManifest.routeMapLicense = data ? String(data.routeMapLicense || 'CC BY 4.0') : 'CC BY 4.0';
assetsManifest.fareTable = data ? (data.fareTable || null) : null;
assetsManifest.updatedAt = data ? (data.updatedAt || null) : null;
assetsForm.routeMapCredit = assetsManifest.routeMapCredit;
assetsRouteMapUrl.value = buildAssetUrl(assetsManifest.routeMap);
assetsFareTableUrl.value = buildAssetUrl(assetsManifest.fareTable);
assetsLoaded = true;
@@ -622,9 +626,12 @@ createApp({
markSynced();
};
const uploadAssetFile = async (url, file) => {
const uploadAssetFile = async (url, file, extraFields = {}) => {
const fd = new FormData();
fd.append('file', file);
for (const [key, value] of Object.entries(extraFields || {})) {
fd.append(key, value == null ? '' : String(value));
}
await requestJson(url, { method: 'POST', body: fd }, { expectOk: true });
await fetchAssetsManifest();
};
@@ -633,7 +640,7 @@ createApp({
const f = ev && ev.target && ev.target.files && ev.target.files[0];
if (!f) return;
ev.target.value = '';
await uploadAssetFile('/api/assets/route-map', f);
await uploadAssetFile('/api/assets/route-map', f, { credit: assetsForm.routeMapCredit });
};
const uploadFareTable = async (ev) => {
@@ -648,6 +655,15 @@ createApp({
await fetchAssetsManifest();
};
const saveRouteMapCredit = async () => {
await requestJson('/api/assets/route-map/credit', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ credit: assetsForm.routeMapCredit })
}, { expectOk: true });
await fetchAssetsManifest();
};
const deleteFareTable = async () => {
await requestJson('/api/assets/fare-table', { method: 'DELETE' }, { expectOk: true });
await fetchAssetsManifest();
@@ -2000,8 +2016,8 @@ createApp({
icCards, icCardSearch, icSelectedId, icSelectedCard, icSelectedEvents, icCreateForm, icDetailForm, icCardStats,
createIcCard, loadIcCard, saveIcCard, topupIcCard, deleteIcCard, icStatusInfo, icStatusColor, icEventTitle, formatIcEventDetail, cardOrderCode, displayIcCardId, formatMoney,
showAddLine, showAddStation, newLine, newStation, fareMapSvg, ticketSearch,
assetsManifest, assetsFarePreview, assetsRouteMapUrl, assetsFareTableUrl,
uploadRouteMap, uploadFareTable, deleteRouteMap, deleteFareTable,
assetsManifest, assetsForm, assetsFarePreview, assetsRouteMapUrl, assetsFareTableUrl,
uploadRouteMap, uploadFareTable, deleteRouteMap, deleteFareTable, saveRouteMapCredit,
// Management
selectedLine, fareMode, stationEditMode, fareSelection, showFareModal, currentFare, availableStations,