落地报价模板主账与后台:合同映射、灌种 SQL/脚本、智能体填表,并补测服运维探针与合同文档对齐。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
linmianxun
2026-09-14 14:09:45 +08:00
co-authored by Cursor
parent 8bdf4990a2
commit a70bce3c8f
138 changed files with 7239 additions and 1085 deletions
@@ -1,6 +1,6 @@
/**
* 演示数据:对齐原型 `询价机器人原型图/后台/admin-quote-templates.html` 列表行。
* 关键词 / 默认模板字段对齐旧仓 quoteTemplate(keywordItems + defaultTemplate)。
* 报价模板列表行类型(对接主账 list 摘要)。
* placeholderCount 语义改为 mappingPointCount(映射点数)。
*/
export type TemplateRow = {
@@ -8,24 +8,27 @@ export type TemplateRow = {
name: string;
bizType: "空运" | "海运" | "陆运";
category: string;
/** 列表「模板文件」列展示名(原型常与模板名一致,不含扩展名) */
fileLabel: string;
/** 预览/上传用完整文件名 */
fileName: string;
format: "excel" | "pdf";
parseStatus: "已解析" | "解析中" | "失败";
placeholderCount: number;
/** 匹配用关键词;每项可含逗号,整体不去拆 */
parseStatus: string;
/** 已映射字段点数(原 mock 占位符数) */
mappingPointCount: number;
keywords: string[];
/** 同业务下默认模板(Mock 保存时互斥) */
isDefault: boolean;
status: "enabled" | "disabled";
useCount: number;
createdAt: string;
operator: string;
mode?: "auto" | "manual";
versionId?: string;
currentVersion?: number;
parseMessage?: string;
unmappedRequired?: string[];
objectKey?: string;
};
/** 业务 → 分类(与原型 CATEGORY_BY_BUSINESS 一致) */
/** 业务 → 分类(与 contracts/quote-template-mapping-v1.json 一致) */
export const CATEGORY_BY_BIZ: Record<TemplateRow["bizType"], string[]> = {
海运: ["海运报价单模板"],
空运: ["空运到港报价单模板", "空运到门报价单模板"],
@@ -53,90 +56,35 @@ export const ALL_CATEGORIES = [
"凭祥保税仓&普仓仓储",
];
export const mockTemplates: TemplateRow[] = [
{
id: "t1",
name: "海运整柜报价单模板",
bizType: "海运",
category: "海运报价单模板",
fileLabel: "海运整柜报价单模板",
fileName: "海运整柜报价单模板.xlsx",
format: "excel",
parseStatus: "已解析",
placeholderCount: 14,
keywords: ["整柜", "FCL"],
isDefault: true,
status: "enabled",
useCount: 62,
createdAt: "2024-06-15",
operator: "王磊",
},
{
id: "t2",
name: "海运拼柜报价单模板",
bizType: "海运",
category: "海运报价单模板",
fileLabel: "海运拼柜报价单模板",
fileName: "海运拼柜报价单模板.xlsx",
format: "excel",
parseStatus: "已解析",
placeholderCount: 12,
keywords: ["拼柜", "LCL"],
isDefault: false,
status: "enabled",
useCount: 34,
createdAt: "2024-08-20",
operator: "林雯",
},
{
id: "t3",
name: "空运到港报价单模板",
bizType: "空运",
category: "空运到港报价单模板",
fileLabel: "空运到港报价单模板",
fileName: "空运到港报价单模板.xlsx",
format: "excel",
parseStatus: "已解析",
placeholderCount: 14,
keywords: ["到港"],
isDefault: true,
status: "enabled",
useCount: 52,
createdAt: "2024-03-08",
operator: "林雯",
},
{
id: "t4",
name: "空运到门报价单模板",
bizType: "空运",
category: "空运到门报价单模板",
fileLabel: "空运到门报价单模板",
fileName: "空运到门报价单模板.xlsx",
format: "excel",
parseStatus: "已解析",
placeholderCount: 14,
keywords: ["到门"],
isDefault: false,
status: "enabled",
useCount: 34,
createdAt: "2024-03-08",
operator: "林雯",
},
{
id: "t5",
name: "陆运干线报价单模板",
bizType: "陆运",
category: "国内整车",
fileLabel: "陆运干线报价单模板",
fileName: "陆运干线报价单模板.pdf",
format: "pdf",
parseStatus: "已解析",
placeholderCount: 9,
keywords: ["干线", "整车"],
isDefault: false,
status: "disabled",
useCount: 18,
createdAt: "2025-11-01",
operator: "张敏",
},
];
/** 将主账 list 记录规范为页面行 */
export function mapApiRow(raw: any): TemplateRow {
const created =
typeof raw.createdAt === "string"
? raw.createdAt.slice(0, 10)
: raw.createTime
? String(raw.createTime).slice(0, 10)
: "";
return {
id: String(raw.id || ""),
name: raw.name || "",
bizType: (raw.bizType || "海运") as TemplateRow["bizType"],
category: raw.category || "",
fileLabel: raw.fileLabel || raw.name || "",
fileName: raw.fileName || "",
format: raw.format === "pdf" ? "pdf" : "excel",
parseStatus: raw.parseStatus || "",
mappingPointCount: Number(raw.mappingPointCount || 0),
keywords: Array.isArray(raw.keywords) ? raw.keywords : [],
isDefault: Boolean(raw.isDefault),
status: raw.status === "enabled" ? "enabled" : "disabled",
useCount: Number(raw.useCount || 0),
createdAt: created,
operator: raw.operator || "",
mode: raw.mode === "manual" ? "manual" : "auto",
versionId: raw.versionId || undefined,
currentVersion: raw.currentVersion,
parseMessage: raw.parseMessage,
unmappedRequired: raw.unmappedRequired,
objectKey: raw.objectKey,
};
}