diff --git a/renderer/src/pages/TemplateConfig.jsx b/renderer/src/pages/TemplateConfig.jsx index 94839fa..a76608c 100644 --- a/renderer/src/pages/TemplateConfig.jsx +++ b/renderer/src/pages/TemplateConfig.jsx @@ -1 +1,147 @@ -export default function TemplateConfig() { return
TemplateConfig
; } +import React, { useState, useEffect } from "react"; +import { useNavigate, useParams } from "react-router-dom"; +import FieldMappingEditor from "../components/FieldMappingEditor"; + +export default function TemplateConfig() { + const navigate = useNavigate(); + const { id } = useParams(); + const isEdit = Boolean(id); + + const [name, setName] = useState(""); + const [grp, setGrp] = useState(""); + const [filePath, setFilePath] = useState(""); + const [fields, setFields] = useState([]); + const [autoDetected, setAutoDetected] = useState([]); + const [saving, setSaving] = useState(false); + + useEffect(() => { + if (isEdit) { + window.api.listTemplates().then((templates) => { + const t = templates.find((t) => t.id === id); + if (t) { + setName(t.name); + setGrp(t.grp || ""); + setFilePath(t.file_path); + setFields(t.fields || []); + } + }); + } + }, [id]); + + async function handleSelectFile() { + const path = await window.api.selectFile([ + { name: "Excel 文件", extensions: ["xlsx"] }, + ]); + if (!path) return; + setFilePath(path); + const result = await window.api.parseTemplate(path); + if (result.placeholders?.length > 0) { + setAutoDetected(result.placeholders); + const detected = result.placeholders.map((p) => ({ + name: p.name, + type: "text", + sheet: p.sheet, + cell: p.cell, + })); + setFields((prev) => { + const existing = prev.map((f) => f.name); + const newOnes = detected.filter((d) => !existing.includes(d.name)); + return [...prev, ...newOnes]; + }); + } + } + + async function handleSave() { + if (!name.trim() || !filePath) return alert("请填写模板名称并选择文件"); + setSaving(true); + try { + if (!isEdit) { + const tempId = Date.now().toString(); + const storedPath = await window.api.copyFileToAppData(filePath, tempId); + await window.api.saveTemplate({ name, grp, file_path: storedPath, fields }); + } else { + await window.api.updateTemplate(id, { name, grp, fields }); + } + navigate("/templates"); + } finally { + setSaving(false); + } + } + + return ( +
+
+
+

{isEdit ? "编辑模板" : "新建模板"}

+ +
+ +
+
+ + setName(e.target.value)} + className="w-full border rounded px-3 py-2 text-sm" + placeholder="如:月度报告模板" + /> +
+
+ + setGrp(e.target.value)} + className="w-full border rounded px-3 py-2 text-sm" + placeholder="如:财务部" + /> +
+
+ +
+ + +
+ {autoDetected.length > 0 && ( +

+ 已自动识别 {autoDetected.length} 个占位符 +

+ )} +
+ +
+ + +
+
+ +
+ + +
+
+
+ ); +}