Files
ai-doc-template-system/frontend/src/stores/templateStore.ts
T
2026-07-01 20:48:02 +08:00

132 lines
5.0 KiB
TypeScript

import { defineStore } from "pinia";
export type RegionType = "ai_generate" | "manual" | "fixed" | "table";
export type TemplateBlock = {
block_id: string;
block_type: "title" | "heading" | "paragraph" | "table";
text_preview: string;
level: number;
sort_order: number;
table_rows?: number;
table_cols?: number;
};
export type TreeNode = {
id: string;
name: string;
status: "done" | "review" | "disabled" | "empty";
children?: TreeNode[];
};
export type BlockConfig = {
region_name: string;
region_type: RegionType;
data_sources: string[];
prompt: string;
output_format: string;
need_review: number;
remark: string;
enabled: number;
};
const mockPreviewHtml = `
<h1 data-block-id="block_001" style="margin:0 0 28px;text-align:center;font-size:20px;">企业经营分析报告</h1>
<p data-block-id="block_002" style="margin:8px 0;text-align:justify;text-indent:2em;">本报告用于展示 Word 模板解析后的 A4 预览效果,后续会由后端返回的 preview_html 驱动渲染。</p>
<h2 data-block-id="block_003" style="margin:24px 0 12px;padding-bottom:6px;border-bottom:2px solid #1a1d24;font-size:16px;">一、经营概况</h2>
<p data-block-id="block_004" style="margin:8px 0;text-align:justify;text-indent:2em;">点击预览区块后,左侧配置面板将展示对应区域的提示词、数据源和输出格式配置。</p>
<table data-block-id="block_005" style="width:100%;margin:14px 0;border-collapse:collapse;">
<thead><tr>
<th style="padding:7px 10px;border:1px solid #e0e2e6;text-align:left;background:#f0f1f3;">指标</th>
<th style="padding:7px 10px;border:1px solid #e0e2e6;text-align:left;background:#f0f1f3;">本期</th>
<th style="padding:7px 10px;border:1px solid #e0e2e6;text-align:left;background:#f0f1f3;">同比</th>
</tr></thead>
<tbody>
<tr><td style="padding:7px 10px;border:1px solid #e0e2e6;">营业收入</td><td style="padding:7px 10px;border:1px solid #e0e2e6;">-</td><td style="padding:7px 10px;border:1px solid #e0e2e6;">-</td></tr>
<tr><td style="padding:7px 10px;border:1px solid #e0e2e6;">利润率</td><td style="padding:7px 10px;border:1px solid #e0e2e6;">-</td><td style="padding:7px 10px;border:1px solid #e0e2e6;">-</td></tr>
</tbody>
</table>
`;
export const useTemplateStore = defineStore("template", {
state: () => ({
loading: false,
error: "",
template: {
id: 1,
name: "企业经营分析报告模板",
version: "v1.0.0",
},
previewHtml: mockPreviewHtml,
blocks: [
{ block_id: "block_001", block_type: "title", text_preview: "企业经营分析报告", level: 0, sort_order: 1 },
{ block_id: "block_002", block_type: "paragraph", text_preview: "报告说明", level: 0, sort_order: 2 },
{ block_id: "block_003", block_type: "heading", text_preview: "一、经营概况", level: 1, sort_order: 3 },
{ block_id: "block_004", block_type: "paragraph", text_preview: "经营概况段落", level: 0, sort_order: 4 },
{ block_id: "block_005", block_type: "table", text_preview: "经营指标表", level: 0, sort_order: 5, table_rows: 3, table_cols: 3 },
] as TemplateBlock[],
tree: [
{
id: "block_001",
name: "企业经营分析报告",
status: "done",
children: [
{ id: "block_002", name: "报告说明", status: "review" },
{
id: "block_003",
name: "一、经营概况",
status: "done",
children: [
{ id: "block_004", name: "经营概况段落", status: "empty" },
{ id: "block_005", name: "经营指标表", status: "disabled" },
],
},
],
},
] as TreeNode[],
configs: {
block_003: {
region_name: "一、经营概况",
region_type: "ai_generate",
data_sources: ["business_data"],
prompt: "请基于业务数据生成经营概况,突出核心指标变化和原因。",
output_format: "formal_paragraph",
need_review: 1,
remark: "",
enabled: 1,
},
block_005: {
region_name: "经营指标表",
region_type: "table",
data_sources: ["business_data"],
prompt: "",
output_format: "table_summary",
need_review: 1,
remark: "",
enabled: 0,
},
} as Record<string, BlockConfig>,
}),
getters: {
blockById: (state) => (blockId: string) => state.blocks.find((block) => block.block_id === blockId),
configById: (state) => (blockId: string) => state.configs[blockId],
},
actions: {
async loadTemplate() {
this.loading = true;
this.error = "";
try {
await new Promise((resolve) => window.setTimeout(resolve, 200));
} catch {
this.error = "模板加载失败";
} finally {
this.loading = false;
}
},
async saveBlockConfig(blockId: string, config: BlockConfig) {
await new Promise((resolve) => window.setTimeout(resolve, 400));
this.configs[blockId] = { ...config };
},
},
});