From dacc95761cf7090c628fc37a5d4f8bb825ccbbb0 Mon Sep 17 00:00:00 2001
From: yyb <995253665@qq.com>
Date: 星期六, 16 五月 2026 15:41:45 +0800
Subject: [PATCH] 企业新闻和通知公告

---
 src/views/officeProcessAutomation/ApproveManage/approve-template/useApproveTemplate.js |  260 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 260 insertions(+), 0 deletions(-)

diff --git a/src/views/officeProcessAutomation/ApproveManage/approve-template/useApproveTemplate.js b/src/views/officeProcessAutomation/ApproveManage/approve-template/useApproveTemplate.js
new file mode 100644
index 0000000..c56d055
--- /dev/null
+++ b/src/views/officeProcessAutomation/ApproveManage/approve-template/useApproveTemplate.js
@@ -0,0 +1,260 @@
+import { Search } from "@element-plus/icons-vue";
+import dayjs from "dayjs";
+import { ElMessageBox } from "element-plus";
+import { computed, reactive, ref, watch } from "vue";
+import {
+  createEmptyTemplateForm,
+  createInitialMockTemplates,
+  flowNodesSummary,
+  getBuiltinTemplates,
+  loadStoredTemplates,
+  nodeSignModeLabel,
+  saveStoredTemplates,
+  validateTemplateForm,
+} from "./approveTemplateConstants.js";
+
+export function useApproveTemplate() {
+  const stored = loadStoredTemplates();
+  const allTemplates = ref(stored?.length ? stored : createInitialMockTemplates());
+
+  const activeTab = ref("custom");
+  const builtinTemplates = getBuiltinTemplates();
+
+  const searchForm = reactive({
+    keyword: "",
+    enabledOnly: false,
+  });
+
+  const tableLoading = ref(false);
+  const page = reactive({ current: 1, size: 10, total: 0 });
+
+  const formDialog = reactive({ visible: false, title: "", mode: "add" });
+  const form = reactive(createEmptyTemplateForm());
+  const formRef = ref();
+
+  const detailDialog = reactive({ visible: false });
+  const detailRow = ref({});
+
+  const filteredList = computed(() => {
+    let list = [...allTemplates.value];
+    const kw = (searchForm.keyword || "").trim().toLowerCase();
+    if (kw) {
+      list = list.filter((r) => {
+        const name = (r.templateName || "").toLowerCase();
+        const desc = (r.description || "").toLowerCase();
+        return name.includes(kw) || desc.includes(kw);
+      });
+    }
+    if (searchForm.enabledOnly) {
+      list = list.filter((r) => r.enabled !== false);
+    }
+    return list.sort((a, b) => (String(a.updateTime) < String(b.updateTime) ? 1 : -1));
+  });
+
+  watch(
+    filteredList,
+    (list) => {
+      page.total = list.length;
+      const maxPage = Math.max(1, Math.ceil(list.length / page.size) || 1);
+      if (page.current > maxPage) page.current = maxPage;
+    },
+    { immediate: true }
+  );
+
+  const tableData = computed(() => {
+    const start = (page.current - 1) * page.size;
+    return filteredList.value.slice(start, start + page.size);
+  });
+
+  const formRules = {
+    templateName: [{ required: true, message: "璇疯緭鍏ユā鏉垮悕绉�", trigger: "blur" }],
+  };
+
+  const tableColumn = ref([
+    { label: "妯℃澘鍚嶇О", prop: "templateName", minWidth: 140 },
+    { 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: "updateTime", width: 170 },
+    {
+      dataType: "action",
+      label: "鎿嶄綔",
+      align: "center",
+      fixed: "right",
+      width: 200,
+      operation: [
+        { name: "璇︽儏", type: "text", clickFun: (row) => openDetail(row) },
+        { name: "缂栬緫", type: "text", clickFun: (row) => openFormDialog("edit", row) },
+        { name: "鍒犻櫎", type: "text", clickFun: (row) => removeTemplate(row) },
+      ],
+    },
+  ]);
+
+  function persist() {
+    saveStoredTemplates(allTemplates.value);
+  }
+
+  function handleQuery() {
+    tableLoading.value = true;
+    page.current = 1;
+    setTimeout(() => {
+      tableLoading.value = false;
+    }, 150);
+  }
+
+  function resetSearch() {
+    searchForm.keyword = "";
+    searchForm.enabledOnly = false;
+    handleQuery();
+  }
+
+  function pagination({ page: p, limit }) {
+    page.current = p;
+    page.size = limit;
+  }
+
+  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 || "",
+      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;
+  }
+
+  function openDetail(row) {
+    detailRow.value = { ...row };
+    detailDialog.visible = true;
+  }
+
+  function isNameDuplicate(name, excludeId) {
+    const n = (name || "").trim();
+    return allTemplates.value.some((t) => t.templateName?.trim() === n && t.id !== excludeId);
+  }
+
+  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 (isNameDuplicate(validated.name, form.id)) {
+      return { message: "妯℃澘鍚嶇О宸插瓨鍦紝璇锋洿鎹㈠悕绉�" };
+    }
+    const now = dayjs().format("YYYY-MM-DD HH:mm:ss");
+    if (formDialog.mode === "add") {
+      allTemplates.value.unshift({
+        id: `tpl_${Date.now()}`,
+        templateName: validated.name,
+        description: (form.description || "").trim(),
+        enabled: form.enabled !== false,
+        createTime: now,
+        updateTime: now,
+        flowNodes: validated.nodes,
+      });
+    } else {
+      const hit = allTemplates.value.find((t) => t.id === form.id);
+      if (!hit) return { message: "妯℃澘涓嶅瓨鍦ㄦ垨宸插垹闄�" };
+      hit.templateName = validated.name;
+      hit.description = (form.description || "").trim();
+      hit.enabled = form.enabled !== false;
+      hit.flowNodes = validated.nodes;
+      hit.updateTime = now;
+    }
+    persist();
+    formDialog.visible = false;
+    page.current = 1;
+    return { ok: true };
+  }
+
+  async function removeTemplate(row) {
+    try {
+      await ElMessageBox.confirm(`纭畾鍒犻櫎妯℃澘銆�${row.templateName}銆嶅悧锛焋, "鎻愮ず", {
+        type: "warning",
+        confirmButtonText: "鍒犻櫎",
+        cancelButtonText: "鍙栨秷",
+      });
+    } catch {
+      return;
+    }
+    const idx = allTemplates.value.findIndex((t) => t.id === row.id);
+    if (idx >= 0) {
+      allTemplates.value.splice(idx, 1);
+      persist();
+    }
+  }
+
+  function toggleEnabled(row) {
+    const hit = allTemplates.value.find((t) => t.id === row.id);
+    if (!hit) return;
+    hit.enabled = !hit.enabled;
+    hit.updateTime = dayjs().format("YYYY-MM-DD HH:mm:ss");
+    persist();
+  }
+
+  return {
+    Search,
+    activeTab,
+    builtinTemplates,
+    nodeSignModeLabel,
+    flowNodesSummary,
+    searchForm,
+    tableLoading,
+    page,
+    tableData,
+    tableColumn,
+    formDialog,
+    form,
+    formRef,
+    formRules,
+    detailDialog,
+    detailRow,
+    handleQuery,
+    resetSearch,
+    pagination,
+    openFormDialog,
+    openDetail,
+    submitForm,
+    toggleEnabled,
+  };
+}

--
Gitblit v1.9.3