2d847e154f
中华文明全图鉴——文物全图系统(PC Web 地图 + NestJS API + 管理后台)。 含三大 IP(文物南迁北归 / 国宝海外回归 / 博物馆手艺人)、AI 文物对话、 文物地图与详情、以及 demo-video-kit 演示视频生成工具。
67 lines
1.9 KiB
TypeScript
67 lines
1.9 KiB
TypeScript
import { Injectable, NotFoundException } from "@nestjs/common";
|
|
import { DatabaseService } from "../database/database.service";
|
|
|
|
export interface RouteRow {
|
|
code: string;
|
|
title: string;
|
|
type: string;
|
|
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 StopRow {
|
|
seq: number;
|
|
name: string;
|
|
lng: number;
|
|
lat: number;
|
|
year_label: string | null;
|
|
event: string | null;
|
|
}
|
|
|
|
export type RouteDetail = RouteRow & { stops: StopRow[] };
|
|
|
|
const ROUTE_SELECT = `
|
|
SELECT nr.code, nr.title, nr.type, nr.color, nr.summary, nr.artifact_id,
|
|
a.name AS artifact_name, a.dynasty AS artifact_dynasty, a.category AS artifact_category,
|
|
i.name AS institution_name
|
|
FROM narrative_routes nr
|
|
LEFT JOIN artifacts a ON a.id = nr.artifact_id
|
|
LEFT JOIN artifact_locations al ON al.artifact_id = a.id AND al.is_current = true
|
|
LEFT JOIN institutions i ON i.id = al.institution_id`;
|
|
|
|
@Injectable()
|
|
export class RoutesService {
|
|
constructor(private db: DatabaseService) {}
|
|
|
|
async list(): Promise<RouteRow[]> {
|
|
const { rows } = await this.db.query<RouteRow>(
|
|
`${ROUTE_SELECT} ORDER BY nr.type, nr.code`
|
|
);
|
|
return rows;
|
|
}
|
|
|
|
async getByCode(code: string): Promise<RouteDetail> {
|
|
const { rows } = await this.db.query<RouteRow>(
|
|
`${ROUTE_SELECT} WHERE nr.code = $1 LIMIT 1`,
|
|
[code]
|
|
);
|
|
const route = rows[0];
|
|
if (!route) throw new NotFoundException("路线不存在");
|
|
|
|
const { rows: stops } = await this.db.query<StopRow>(
|
|
`SELECT seq, name, lng, lat, year_label, event
|
|
FROM route_stops rs
|
|
JOIN narrative_routes nr ON nr.id = rs.route_id
|
|
WHERE nr.code = $1
|
|
ORDER BY rs.seq`,
|
|
[code]
|
|
);
|
|
return { ...route, stops };
|
|
}
|
|
}
|