src/views/officeProcessAutomation/ApproveManage/approve-template/useApproveTemplate.js
@@ -3,17 +3,18 @@
  deleteApprovalTemplate,
  getApprovalTemplateDetail,
  listApprovalTemplatePage,
  TEMPLATE_TYPE_CUSTOM,
  TEMPLATE_TYPE_BUILTIN,
  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 { computed, reactive, ref } from "vue";
import {
  buildApprovalTemplateListParams,
  createEmptyTemplateForm,
  fetchBusinessTypeOptions,
  flowNodesSummary,
  isBuiltinTemplate,
  mapTemplateFromApi,
  mapTemplateToApi,
  nodeSignModeLabel,
@@ -23,38 +24,10 @@
} 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;
@@ -63,17 +36,7 @@
  );
}
function clearLegacyStorage() {
  try {
    localStorage.removeItem(LEGACY_STORAGE_KEY);
  } catch {
    /* ignore */
  }
}
export function useApproveTemplate() {
  clearLegacyStorage();
  const templateTypeOptions = ref([...FALLBACK_TEMPLATE_TYPE_OPTIONS]);
  function templateTypeLabel(type) {
@@ -97,10 +60,13 @@
  const form = reactive(createEmptyTemplateForm());
  const formRef = ref();
  const isEditingBuiltin = computed(
    () => formDialog.mode === "edit" && Number(form.templateType) === TEMPLATE_TYPE_BUILTIN
  );
  async function loadTemplateTypeOptions() {
    try {
      const res = await getTypeEnums();
      const list = normalizeTypeEnumOptions(res?.data);
      const list = await fetchBusinessTypeOptions();
      templateTypeOptions.value = list.length ? list : [...FALLBACK_TEMPLATE_TYPE_OPTIONS];
    } catch {
      templateTypeOptions.value = [...FALLBACK_TEMPLATE_TYPE_OPTIONS];
@@ -179,6 +145,7 @@
          name: "删除",
          type: "danger",
          link: true,
          disabled: (row) => isBuiltinTemplate(row),
          clickFun: (row) => removeTemplate(row),
        },
      ],
@@ -225,18 +192,25 @@
      Object.assign(form, base);
      return;
    }
    const formConfigData = JSON.parse(
      JSON.stringify(row.formConfigData || parseFormConfigToData(row.formConfig))
    );
    const builtin = isBuiltinTemplate(row);
    Object.assign(form, {
      ...base,
      id: row.id,
      templateName: row.templateName || "",
      description: row.description || "",
      templateType: row.templateType != null ? Number(row.templateType) : base.templateType,
      businessType: row.businessType ?? "",
      formConfig: row.formConfig || "",
      formConfigData: JSON.parse(
        JSON.stringify(row.formConfigData || parseFormConfigToData(row.formConfig))
      ),
      formConfigData,
      lockedFormFieldUids: builtin
        ? (formConfigData.fields || []).map((f) => f._uid).filter(Boolean)
        : [],
      enabled: row.enabled !== false,
      flowNodes: JSON.parse(JSON.stringify(row.flowNodes || [base.flowNodes[0]])),
      storageBlobDTOs: JSON.parse(JSON.stringify(row.storageBlobDTOs || [])),
    });
  }
@@ -296,6 +270,10 @@
  }
  async function removeTemplate(row) {
    if (isBuiltinTemplate(row)) {
      ElMessage.warning("系统内置模板不允许删除");
      return;
    }
    if (row?.id == null || row.id === "") {
      ElMessage.warning("无法删除:缺少模板 ID");
      return;
@@ -342,6 +320,7 @@
    form,
    formRef,
    formRules,
    isEditingBuiltin,
    detailDialog,
    detailRow,
    detailLoading,