import { addApprovalTemplate, deleteApprovalTemplate, getApprovalTemplateDetail, listApprovalTemplate, listApprovalTemplatePage, TEMPLATE_TYPE_BUILTIN, TEMPLATE_TYPE_CUSTOM, TEMPLATE_TYPE_OPTIONS, updateApprovalTemplate, } from "@/api/officeProcessAutomation/approvalTemplate.js"; import { Search } from "@element-plus/icons-vue"; import { ElMessage, ElMessageBox } from "element-plus"; import { reactive, ref } from "vue"; import { buildApprovalTemplateListParams, createEmptyTemplateForm, flowNodesSummary, mapBuiltinCardFromApi, mapTemplateFromApi, mapTemplateToApi, nodeSignModeLabel, templateTypeLabel, unwrapTemplateList, formatDisplayTime, unwrapTemplateDetail, validateTemplateForm, } from "./approveTemplateConstants.js"; import { parseFormConfigToData } from "./formConfigUtils.js"; const LEGACY_STORAGE_KEY = "oa_approve_template_custom_v1"; function clearLegacyStorage() { try { localStorage.removeItem(LEGACY_STORAGE_KEY); } catch { /* ignore */ } } export function useApproveTemplate() { clearLegacyStorage(); const activeTab = ref("custom"); const builtinTemplates = ref([]); const builtinLoading = ref(false); const searchForm = reactive({ keyword: "", enabledOnly: false, }); const tableLoading = ref(false); const page = reactive({ current: 1, size: 10, total: 0 }); const tableData = ref([]); const formDialog = reactive({ visible: false, title: "", mode: "add" }); const form = reactive(createEmptyTemplateForm()); const formRef = ref(); const detailDialog = reactive({ visible: false }); const detailRow = ref({}); const detailLoading = ref(false); const formRules = { templateName: [{ required: true, message: "请输入模板名称", trigger: "blur" }], templateType: [{ required: true, message: "请选择模板类型", trigger: "change" }], }; const tableColumn = ref([ { label: "模板名称", prop: "templateName", minWidth: 140 }, { label: "模板类型", prop: "templateType", width: 100, align: "center", formatData: (v) => templateTypeLabel(v), }, { label: "说明", prop: "description", minWidth: 160, showOverflowTooltip: true }, { label: "节点数", prop: "flowNodes", width: 80, align: "center", formatData: (v) => (Array.isArray(v) ? v.length : 0), }, { label: "流程概要", prop: "flowNodes", minWidth: 220, showOverflowTooltip: true, formatData: (v) => flowNodesSummary(v), }, { label: "状态", prop: "enabled", width: 90, align: "center", dataType: "tag", formatData: (v) => (v !== false ? "启用" : "停用"), formatType: (v) => (v !== false ? "success" : "info"), }, { label: "创建时间", prop: "createdTime", width: 170, showOverflowTooltip: true, formatData: (v) => formatDisplayTime(v), }, { label: "更新时间", prop: "updatedTime", width: 170, showOverflowTooltip: true, formatData: (v) => formatDisplayTime(v), }, { dataType: "action", label: "操作", align: "center", fixed: "right", width: 220, operation: [ { name: "详情", type: "text", clickFun: (row) => openDetail(row) }, { name: "编辑", type: "text", clickFun: (row) => openFormDialog("edit", row) }, { name: "删除", type: "danger", link: true, clickFun: (row) => removeTemplate(row), }, ], }, ]); async function loadBuiltinTemplates() { builtinLoading.value = true; try { const res = await listApprovalTemplate(TEMPLATE_TYPE_BUILTIN); builtinTemplates.value = unwrapTemplateList(res).map(mapBuiltinCardFromApi); } catch { builtinTemplates.value = []; ElMessage.warning("系统常用审批加载失败"); } finally { builtinLoading.value = false; } } async function fetchTemplateList() { tableLoading.value = true; try { const res = await listApprovalTemplatePage( buildApprovalTemplateListParams({ page, searchForm }) ); const data = res?.data || {}; tableData.value = (data.records || []).map(mapTemplateFromApi); page.total = Number(data.total || 0); } catch { tableData.value = []; page.total = 0; } finally { tableLoading.value = false; } } function handleQuery() { page.current = 1; fetchTemplateList(); } function resetSearch() { searchForm.keyword = ""; searchForm.enabledOnly = false; handleQuery(); } function pagination({ page: p, limit }) { page.current = p; page.size = limit; fetchTemplateList(); } function resetForm(row) { const base = createEmptyTemplateForm(); if (!row) { Object.assign(form, base); return; } Object.assign(form, { ...base, id: row.id, templateName: row.templateName || "", description: row.description || "", templateType: row.templateType ?? TEMPLATE_TYPE_CUSTOM, formConfig: row.formConfig || "", formConfigData: JSON.parse( JSON.stringify(row.formConfigData || parseFormConfigToData(row.formConfig)) ), enabled: row.enabled !== false, flowNodes: JSON.parse(JSON.stringify(row.flowNodes || [base.flowNodes[0]])), }); } function openFormDialog(mode, row) { formDialog.mode = mode; formDialog.title = mode === "add" ? "新建审批模板" : "编辑审批模板"; resetForm(mode === "edit" ? row : null); formDialog.visible = true; } async function openDetail(row) { if (row?.id == null || row.id === "") { ElMessage.warning("无法查看详情:缺少模板 ID"); return; } detailDialog.visible = true; detailLoading.value = true; detailRow.value = {}; try { const res = await getApprovalTemplateDetail(row.id); detailRow.value = mapTemplateFromApi(unwrapTemplateDetail(res)); } catch { detailDialog.visible = false; } finally { detailLoading.value = false; } } async function submitForm() { if (!formRef.value) return false; try { await formRef.value.validate(); } catch { return false; } const validated = validateTemplateForm(form); if (!validated.ok) { return { message: validated.message }; } if (formDialog.mode === "edit" && !form.id) { return { message: "缺少模板 ID,无法保存修改" }; } const dto = mapTemplateToApi(form); try { if (formDialog.mode === "add") { await addApprovalTemplate(dto); } else { await updateApprovalTemplate(dto); } } catch { return false; } formDialog.visible = false; page.current = 1; await fetchTemplateList(); if (dto.templateType === TEMPLATE_TYPE_BUILTIN) { await loadBuiltinTemplates(); } return { ok: true }; } async function removeTemplate(row) { if (row?.id == null || row.id === "") { ElMessage.warning("无法删除:缺少模板 ID"); return; } const name = row.templateName || "未命名模板"; try { await ElMessageBox.confirm( `确定要删除审批模板「${name}」吗?删除后不可恢复。`, "删除确认", { type: "warning", confirmButtonText: "确定删除", cancelButtonText: "取消", distinguishCancelAndClose: true, autofocus: false, } ); } catch { return; } try { await deleteApprovalTemplate([row.id]); ElMessage.success("删除成功"); await fetchTemplateList(); if (row.templateType === TEMPLATE_TYPE_BUILTIN) { await loadBuiltinTemplates(); } } catch { /* 错误由拦截器提示 */ } } return { Search, TEMPLATE_TYPE_OPTIONS, templateTypeLabel, activeTab, builtinTemplates, builtinLoading, loadBuiltinTemplates, fetchTemplateList, nodeSignModeLabel, flowNodesSummary, searchForm, tableLoading, page, tableData, tableColumn, formDialog, form, formRef, formRules, detailDialog, detailRow, detailLoading, handleQuery, resetSearch, pagination, openFormDialog, openDetail, submitForm, }; }