From 07d766a545881be779de94a800f6494ec46c1001 Mon Sep 17 00:00:00 2001
From: yyb <995253665@qq.com>
Date: 星期二, 19 五月 2026 17:10:08 +0800
Subject: [PATCH] 模板类型接口获取
---
src/views/officeProcessAutomation/ApproveManage/approve-template/useApproveTemplate.js | 299 +++++++++++++++++++++++++++++++++++++++--------------------
1 files changed, 197 insertions(+), 102 deletions(-)
diff --git a/src/views/officeProcessAutomation/ApproveManage/approve-template/useApproveTemplate.js b/src/views/officeProcessAutomation/ApproveManage/approve-template/useApproveTemplate.js
index c56d055..3e27afb 100644
--- a/src/views/officeProcessAutomation/ApproveManage/approve-template/useApproveTemplate.js
+++ b/src/views/officeProcessAutomation/ApproveManage/approve-template/useApproveTemplate.js
@@ -1,24 +1,88 @@
-import { Search } from "@element-plus/icons-vue";
-import dayjs from "dayjs";
-import { ElMessageBox } from "element-plus";
-import { computed, reactive, ref, watch } from "vue";
import {
+ addApprovalTemplate,
+ deleteApprovalTemplate,
+ getApprovalTemplateDetail,
+ listApprovalTemplatePage,
+ TEMPLATE_TYPE_CUSTOM,
+ updateApprovalTemplate,
+} from "@/api/officeProcessAutomation/approvalTemplate.js";
+import { getTypeEnums } from "@/api/basicData/enum.js";
+import { Search } from "@element-plus/icons-vue";
+import { ElMessage, ElMessageBox } from "element-plus";
+import { reactive, ref } from "vue";
+import {
+ buildApprovalTemplateListParams,
createEmptyTemplateForm,
- createInitialMockTemplates,
flowNodesSummary,
- getBuiltinTemplates,
- loadStoredTemplates,
+ mapTemplateFromApi,
+ mapTemplateToApi,
nodeSignModeLabel,
- saveStoredTemplates,
+ formatDisplayTime,
+ unwrapTemplateDetail,
validateTemplateForm,
} from "./approveTemplateConstants.js";
+import { parseFormConfigToData } from "./formConfigUtils.js";
+
+const LEGACY_STORAGE_KEY = "oa_approve_template_custom_v1";
+
+const FALLBACK_TEMPLATE_TYPE_OPTIONS = [
+ { value: 0, label: "绯荤粺鍐呯疆" },
+ { value: 1, label: "鑷畾涔�" },
+];
+
+function unwrapEnumList(data) {
+ if (Array.isArray(data)) return data;
+ if (!data || typeof data !== "object") return [];
+ if (Array.isArray(data.TypeEnums)) return data.TypeEnums;
+ if (Array.isArray(data.typeEnums)) return data.typeEnums;
+ const nested = Object.values(data).find((v) => Array.isArray(v));
+ return nested || [];
+}
+
+function normalizeTypeEnumOptions(data) {
+ return unwrapEnumList(data)
+ .map((item) => {
+ const rawValue = item?.value ?? item?.code ?? item?.businessType ?? item?.dictValue ?? item?.key;
+ if (rawValue == null || rawValue === "") return null;
+ const num = Number(rawValue);
+ const value =
+ typeof rawValue === "number" || (Number.isFinite(num) && String(rawValue).trim() !== "")
+ ? num
+ : rawValue;
+ const label =
+ item?.label ?? item?.name ?? item?.desc ?? item?.dictLabel ?? item?.text ?? String(value);
+ return { label, value };
+ })
+ .filter(Boolean);
+}
+
+function matchTemplateTypeValue(options, type) {
+ if (type == null || type === "") return false;
+ return options.some(
+ (x) => x.value === type || x.value === Number(type) || String(x.value) === String(type)
+ );
+}
+
+function clearLegacyStorage() {
+ try {
+ localStorage.removeItem(LEGACY_STORAGE_KEY);
+ } catch {
+ /* ignore */
+ }
+}
export function useApproveTemplate() {
- const stored = loadStoredTemplates();
- const allTemplates = ref(stored?.length ? stored : createInitialMockTemplates());
+ clearLegacyStorage();
- const activeTab = ref("custom");
- const builtinTemplates = getBuiltinTemplates();
+ const templateTypeOptions = ref([...FALLBACK_TEMPLATE_TYPE_OPTIONS]);
+
+ function templateTypeLabel(type) {
+ if (type == null || type === "") return "鈥�";
+ const hit = templateTypeOptions.value.find(
+ (x) => x.value === type || x.value === Number(type) || String(x.value) === String(type)
+ );
+ return hit?.label || "鈥�";
+ }
const searchForm = reactive({
keyword: "",
@@ -27,51 +91,43 @@
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();
+ async function loadTemplateTypeOptions() {
+ try {
+ const res = await getTypeEnums();
+ const list = normalizeTypeEnumOptions(res?.data);
+ templateTypeOptions.value = list.length ? list : [...FALLBACK_TEMPLATE_TYPE_OPTIONS];
+ } catch {
+ templateTypeOptions.value = [...FALLBACK_TEMPLATE_TYPE_OPTIONS];
+ }
+ if (!matchTemplateTypeValue(templateTypeOptions.value, form.businessType)) {
+ form.businessType = templateTypeOptions.value[0]?.value ?? "";
+ }
+ }
+
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 detailLoading = ref(false);
const formRules = {
templateName: [{ required: true, message: "璇疯緭鍏ユā鏉垮悕绉�", trigger: "blur" }],
+ businessType: [{ required: true, message: "璇烽�夋嫨妯℃澘绫诲瀷", trigger: "change" }],
};
const tableColumn = ref([
{ label: "妯℃澘鍚嶇О", prop: "templateName", minWidth: 140 },
+ {
+ label: "妯℃澘绫诲瀷",
+ prop: "businessType",
+ width: 100,
+ align: "center",
+ formatData: (v) => templateTypeLabel(v),
+ },
{ label: "璇存槑", prop: "description", minWidth: 160, showOverflowTooltip: true },
{
label: "鑺傜偣鏁�",
@@ -96,31 +152,59 @@
formatData: (v) => (v !== false ? "鍚敤" : "鍋滅敤"),
formatType: (v) => (v !== false ? "success" : "info"),
},
- { label: "鏇存柊鏃堕棿", prop: "updateTime", width: 170 },
+ {
+ 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: 200,
+ width: 220,
operation: [
{ name: "璇︽儏", type: "text", clickFun: (row) => openDetail(row) },
{ name: "缂栬緫", type: "text", clickFun: (row) => openFormDialog("edit", row) },
- { name: "鍒犻櫎", type: "text", clickFun: (row) => removeTemplate(row) },
+ {
+ name: "鍒犻櫎",
+ type: "danger",
+ link: true,
+ clickFun: (row) => removeTemplate(row),
+ },
],
},
]);
- function persist() {
- saveStoredTemplates(allTemplates.value);
+ 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() {
- tableLoading.value = true;
page.current = 1;
- setTimeout(() => {
- tableLoading.value = false;
- }, 150);
+ fetchTemplateList();
}
function resetSearch() {
@@ -132,6 +216,7 @@
function pagination({ page: p, limit }) {
page.current = p;
page.size = limit;
+ fetchTemplateList();
}
function resetForm(row) {
@@ -145,6 +230,11 @@
id: row.id,
templateName: row.templateName || "",
description: row.description || "",
+ businessType: row.businessType ?? "",
+ 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]])),
});
@@ -152,19 +242,27 @@
function openFormDialog(mode, row) {
formDialog.mode = mode;
- formDialog.title = mode === "add" ? "鏂板缓鑷畾涔夊鎵规ā鏉�" : "缂栬緫鑷畾涔夊鎵规ā鏉�";
+ formDialog.title = mode === "add" ? "鏂板缓瀹℃壒妯℃澘" : "缂栬緫瀹℃壒妯℃澘";
resetForm(mode === "edit" ? row : null);
formDialog.visible = true;
}
- function openDetail(row) {
- detailRow.value = { ...row };
+ async function openDetail(row) {
+ if (row?.id == null || row.id === "") {
+ ElMessage.warning("鏃犳硶鏌ョ湅璇︽儏锛氱己灏戞ā鏉� ID");
+ return;
+ }
detailDialog.visible = true;
- }
-
- function isNameDuplicate(name, excludeId) {
- const n = (name || "").trim();
- return allTemplates.value.some((t) => t.templateName?.trim() === n && t.id !== excludeId);
+ 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() {
@@ -178,64 +276,61 @@
if (!validated.ok) {
return { message: validated.message };
}
- if (isNameDuplicate(validated.name, form.id)) {
- return { message: "妯℃澘鍚嶇О宸插瓨鍦紝璇锋洿鎹㈠悕绉�" };
+ if (formDialog.mode === "edit" && !form.id) {
+ return { message: "缂哄皯妯℃澘 ID锛屾棤娉曚繚瀛樹慨鏀�" };
}
- 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;
+ const dto = mapTemplateToApi(form);
+ try {
+ if (formDialog.mode === "add") {
+ await addApprovalTemplate(dto);
+ } else {
+ await updateApprovalTemplate(dto);
+ }
+ } catch {
+ return false;
}
- persist();
formDialog.visible = false;
page.current = 1;
+ await fetchTemplateList();
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(`纭畾鍒犻櫎妯℃澘銆�${row.templateName}銆嶅悧锛焋, "鎻愮ず", {
- type: "warning",
- confirmButtonText: "鍒犻櫎",
- cancelButtonText: "鍙栨秷",
- });
+ await ElMessageBox.confirm(
+ `纭畾瑕佸垹闄ゅ鎵规ā鏉裤��${name}銆嶅悧锛熷垹闄ゅ悗涓嶅彲鎭㈠銆俙,
+ "鍒犻櫎纭",
+ {
+ type: "warning",
+ confirmButtonText: "纭畾鍒犻櫎",
+ cancelButtonText: "鍙栨秷",
+ distinguishCancelAndClose: true,
+ autofocus: false,
+ }
+ );
} catch {
return;
}
- const idx = allTemplates.value.findIndex((t) => t.id === row.id);
- if (idx >= 0) {
- allTemplates.value.splice(idx, 1);
- persist();
+ try {
+ await deleteApprovalTemplate([row.id]);
+ ElMessage.success("鍒犻櫎鎴愬姛");
+ await fetchTemplateList();
+ } catch {
+ /* 閿欒鐢辨嫤鎴櫒鎻愮ず */
}
- }
-
- 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,
+ templateTypeOptions,
+ loadTemplateTypeOptions,
+ templateTypeLabel,
+ fetchTemplateList,
nodeSignModeLabel,
flowNodesSummary,
searchForm,
@@ -249,12 +344,12 @@
formRules,
detailDialog,
detailRow,
+ detailLoading,
handleQuery,
resetSearch,
pagination,
openFormDialog,
openDetail,
submitForm,
- toggleEnabled,
};
}
--
Gitblit v1.9.3