export const API_URL = process.env.NEXT_PUBLIC_API_URL ?? "http://localhost:3002"; export interface MapPoint { id: string; name: string; category: string; level: string; dynasty: string; story_hook: string; lng: number; lat: number; institution_name: string; province?: string; city?: string; location_type?: string; image_url?: string | null; repatriation_status?: string; } export interface RouteStop { seq: number; name: string; lng: number; lat: number; year_label: string | null; event: string | null; } export interface RouteSummary { code: string; title: string; type: string; // migration | repatriation color: string | null; summary: string | null; artifact_id?: string | null; artifact_name?: string | null; artifact_dynasty?: string | null; artifact_category?: string | null; institution_name?: string | null; } export interface RouteDetail extends RouteSummary { stops: RouteStop[]; } export type Theme = "domestic" | "overseas" | "repatriated"; export function themeOf(p: { location_type?: string; repatriation_status?: string }): Theme { if (p.repatriation_status === "repatriated") return "repatriated"; if (p.repatriation_status === "lost_overseas" || p.location_type === "overseas") return "overseas"; return "domestic"; } export const REPATRIATION_LABELS: Record = { domestic: "国内传承", lost_overseas: "流失海外", repatriated: "已回归", in_transit: "在途", }; export const CATEGORY_LABELS: Record = { bronze: "青铜器", painting_calligraphy: "书画", porcelain: "陶瓷", jade: "玉器", gold_silver: "金银器", lacquer: "漆木器", textile: "织绣", stone_carving: "石刻造像", wood_carving: "木雕", dunhuang: "敦煌遗珍", ancient_book: "古籍文献", other: "其他", }; export const CATEGORY_MARKS: Record = { bronze: "铜", painting_calligraphy: "画", porcelain: "瓷", jade: "玉", gold_silver: "金", lacquer: "漆", textile: "织", stone_carving: "石", wood_carving: "木", dunhuang: "敦", ancient_book: "书", other: "物", }; export const LEVEL_LABELS: Record = { level_1: "国家一级", level_2: "国家二级", level_3: "国家三级", general: "一般文物", unknown: "未定级", }; export const DYNASTY_OPTIONS = [ "商代", "西周", "春秋", "战国", "秦代", "汉代", "唐代", "五代", "北宋", "南宋", "元代", "明代", "清代", ]; // 根据缩放层级与聚合数量计算 marker 直径(像素)。 export function markerSizeFor(zoom: number, count: number): number { const z = Math.max(2, Math.min(18, zoom)); const base = 13 + (z - 2) * 2.3; const countBonus = Math.min(15, Math.log2(count + 1) * 4); return Math.round(base + countBonus); } // 文物图片:优先用已下载到本地的静态图(同源、无需外网), // 加载失败时组件会回退到原始直链,再回退到统一示意图。 export function artifactImageSrc(id: string, _hd = false): string { return `/artifacts/${id}.jpg`; } export function isOverseas(locationType?: string): boolean { return locationType === "overseas"; }