| ¶Ô±ÈÐÂÎļþ |
| | |
| | | import { |
| | | getApprovalTemplateDetail, |
| | | listApprovalTemplate, |
| | | TEMPLATE_TYPE_CUSTOM, |
| | | } from "@/api/officeProcessAutomation/approvalTemplate.js"; |
| | | import { computed, reactive, ref } from "vue"; |
| | | import { ElMessage } from "element-plus"; |
| | | import { |
| | | fetchBusinessTypeOptions, |
| | | mapEnabledFromApi, |
| | | unwrapTemplateList, |
| | | } from "../approve-template/approveTemplateConstants.js"; |
| | | import { |
| | | createEmptySubmitForm, |
| | | mapSubmitTemplateCard, |
| | | matchBusinessTypeValue, |
| | | } from "../approve-list/approveListConstants.js"; |
| | | import { |
| | | getApprovalModuleConfig, |
| | | getModuleMatchingBusinessTypes, |
| | | resolveModuleBusinessType, |
| | | } from "./approvalModuleRegistry.js"; |
| | | import { |
| | | buildFormPayloadRules, |
| | | buildTemplateBindingFromDetail, |
| | | validateTemplateBinding, |
| | | } from "./approvalTemplateBindingUtils.js"; |
| | | |
| | | /** |
| | | * å®¡æ¹æ¨¡æ¿ç»å®ï¼ä¸å¡æ¨¡ååºå®ç±»å / 审æ¹å表éç¨ï¼ |
| | | * |
| | | * @param {object} options |
| | | * @param {string} [options.moduleKey] ä¸å¡æ¨¡å keyï¼è§ approvalModuleRegistry |
| | | * @param {string|number} [options.businessType] ç´æ¥æå®ç±»åï¼ä¼å
级é«äº moduleKeyï¼ |
| | | * @param {'module'|'universal'} [options.mode] module=ä»
æ¬ç±»å模æ¿ï¼universal=éå
éç±»å |
| | | */ |
| | | export function useApprovalTemplateBinding(options = {}) { |
| | | const { moduleKey = null, businessType: fixedBusinessType = null, mode = moduleKey ? "module" : "universal" } = |
| | | options; |
| | | |
| | | const isUniversal = mode === "universal" && !moduleKey && fixedBusinessType == null; |
| | | |
| | | const allTemplates = ref([]); |
| | | const businessTypeOptions = ref([]); |
| | | const selectedBusinessType = ref(fixedBusinessType ?? ""); |
| | | const templatesLoading = ref(false); |
| | | const step = ref(isUniversal ? 1 : 1); |
| | | |
| | | const bindingForm = reactive(createEmptySubmitForm("")); |
| | | |
| | | const moduleConfig = computed(() => getApprovalModuleConfig(moduleKey)); |
| | | |
| | | const resolvedBusinessType = computed(() => { |
| | | if (fixedBusinessType != null && fixedBusinessType !== "") return fixedBusinessType; |
| | | if (selectedBusinessType.value != null && selectedBusinessType.value !== "") { |
| | | return selectedBusinessType.value; |
| | | } |
| | | if (moduleKey) { |
| | | return resolveModuleBusinessType(moduleKey, businessTypeOptions.value); |
| | | } |
| | | return ""; |
| | | }); |
| | | |
| | | const matchingBusinessTypes = computed(() => { |
| | | if (fixedBusinessType != null && fixedBusinessType !== "") return [fixedBusinessType]; |
| | | if (isUniversal) { |
| | | const t = selectedBusinessType.value; |
| | | return t != null && t !== "" ? [t] : []; |
| | | } |
| | | if (moduleKey) { |
| | | return getModuleMatchingBusinessTypes(moduleKey, businessTypeOptions.value); |
| | | } |
| | | const t = resolvedBusinessType.value; |
| | | return t != null && t !== "" ? [t] : []; |
| | | }); |
| | | |
| | | const templateCards = computed(() => { |
| | | const types = matchingBusinessTypes.value; |
| | | if (!types.length) return []; |
| | | return allTemplates.value.filter((card) => |
| | | types.some( |
| | | (t) => |
| | | matchBusinessTypeValue(card.businessType, t) || |
| | | matchBusinessTypeValue(card.approvalType, t) |
| | | ) |
| | | ); |
| | | }); |
| | | |
| | | const activeTemplate = computed(() => bindingForm.templateSnapshot || null); |
| | | |
| | | const formFields = computed(() => { |
| | | const tplFields = activeTemplate.value?.fields; |
| | | if (tplFields?.length) return tplFields; |
| | | return bindingForm.formFieldDefs || []; |
| | | }); |
| | | |
| | | const formRules = computed(() => buildFormPayloadRules(formFields.value)); |
| | | |
| | | const hasTemplateBound = computed(() => Boolean(activeTemplate.value?.templateId || bindingForm.templateId)); |
| | | |
| | | function businessTypeLabel(type) { |
| | | if (type == null || type === "") return ""; |
| | | const hit = businessTypeOptions.value.find((x) => matchBusinessTypeValue(x.value, type)); |
| | | return hit?.label || moduleConfig.value?.label || ""; |
| | | } |
| | | |
| | | const selectedBusinessTypeLabel = computed(() => businessTypeLabel(resolvedBusinessType.value)); |
| | | |
| | | function countTemplatesByBusinessType(type) { |
| | | const types = |
| | | moduleKey && !fixedBusinessType |
| | | ? getModuleMatchingBusinessTypes(moduleKey, businessTypeOptions.value) |
| | | : [type]; |
| | | return allTemplates.value.filter((card) => |
| | | types.some( |
| | | (t) => |
| | | matchBusinessTypeValue(card.businessType, t) || |
| | | matchBusinessTypeValue(card.approvalType, t) |
| | | ) |
| | | ).length; |
| | | } |
| | | |
| | | async function loadTemplates() { |
| | | templatesLoading.value = true; |
| | | try { |
| | | const [typeOptions, customRes] = await Promise.all([ |
| | | fetchBusinessTypeOptions(), |
| | | listApprovalTemplate(TEMPLATE_TYPE_CUSTOM), |
| | | ]); |
| | | businessTypeOptions.value = typeOptions; |
| | | allTemplates.value = unwrapTemplateList(customRes) |
| | | .filter((row) => mapEnabledFromApi(row.enabled)) |
| | | .map(mapSubmitTemplateCard); |
| | | |
| | | if (moduleKey && !fixedBusinessType) { |
| | | const resolved = resolveModuleBusinessType(moduleKey, typeOptions); |
| | | if (resolved != null && resolved !== "") selectedBusinessType.value = resolved; |
| | | } |
| | | } catch { |
| | | businessTypeOptions.value = []; |
| | | allTemplates.value = []; |
| | | ElMessage.error("å è½½å®¡æ¹æ¨¡æ¿å¤±è´¥"); |
| | | } finally { |
| | | templatesLoading.value = false; |
| | | } |
| | | } |
| | | |
| | | function resetBinding() { |
| | | step.value = isUniversal ? 1 : 1; |
| | | if (!fixedBusinessType && !moduleKey) selectedBusinessType.value = ""; |
| | | else if (moduleKey) { |
| | | selectedBusinessType.value = |
| | | fixedBusinessType ?? resolveModuleBusinessType(moduleKey, businessTypeOptions.value) ?? ""; |
| | | } |
| | | Object.assign(bindingForm, createEmptySubmitForm("")); |
| | | } |
| | | |
| | | function pickBusinessType(type) { |
| | | if (!countTemplatesByBusinessType(type)) { |
| | | ElMessage.warning("该类å䏿æ å¯ç¨å®¡æ¹æ¨¡æ¿"); |
| | | return; |
| | | } |
| | | selectedBusinessType.value = type; |
| | | step.value = 2; |
| | | } |
| | | |
| | | function backToBusinessTypePick() { |
| | | selectedBusinessType.value = ""; |
| | | step.value = 1; |
| | | } |
| | | |
| | | function backToTemplatePick() { |
| | | step.value = isUniversal ? 2 : 1; |
| | | } |
| | | |
| | | async function pickTemplate(card) { |
| | | if (!card?.id) return false; |
| | | templatesLoading.value = true; |
| | | try { |
| | | const res = await getApprovalTemplateDetail(card.id); |
| | | const applied = buildTemplateBindingFromDetail(res); |
| | | Object.assign(bindingForm, { |
| | | templateKey: String(card.id), |
| | | ...applied, |
| | | }); |
| | | step.value = isUniversal ? 3 : 2; |
| | | return true; |
| | | } catch { |
| | | ElMessage.error("å 载模æ¿è¯¦æ
失败"); |
| | | return false; |
| | | } finally { |
| | | templatesLoading.value = false; |
| | | } |
| | | } |
| | | |
| | | /** ç´æ¥ä»¥è¯¦æ
è¡ç»å®ï¼ç¼è¾åæ¾ï¼ */ |
| | | function applyBindingState(state) { |
| | | if (!state) return; |
| | | Object.assign(bindingForm, createEmptySubmitForm(""), state); |
| | | step.value = isUniversal ? 3 : 2; |
| | | } |
| | | |
| | | async function validateBinding(formRef) { |
| | | if (formRef?.validate) { |
| | | try { |
| | | await formRef.validate(); |
| | | } catch { |
| | | return { ok: false }; |
| | | } |
| | | } |
| | | if (!hasTemplateBound.value) { |
| | | return { ok: false, message: "è¯·éæ©å®¡æ¹æ¨¡æ¿" }; |
| | | } |
| | | return validateTemplateBinding({ flowNodes: bindingForm.flowNodes }); |
| | | } |
| | | |
| | | function getBindingPayload() { |
| | | return { |
| | | templateId: bindingForm.templateId, |
| | | templateName: bindingForm.templateName, |
| | | businessType: bindingForm.businessType ?? resolvedBusinessType.value, |
| | | templateSnapshot: bindingForm.templateSnapshot, |
| | | formFieldDefs: bindingForm.formFieldDefs, |
| | | formPayload: bindingForm.formPayload, |
| | | flowNodes: bindingForm.flowNodes, |
| | | templateAttachments: bindingForm.templateAttachments, |
| | | storageBlobDTOs: bindingForm.storageBlobDTOs, |
| | | }; |
| | | } |
| | | |
| | | return { |
| | | isUniversal, |
| | | moduleConfig, |
| | | step, |
| | | bindingForm, |
| | | allTemplates, |
| | | businessTypeOptions, |
| | | selectedBusinessType, |
| | | resolvedBusinessType, |
| | | selectedBusinessTypeLabel, |
| | | templateCards, |
| | | activeTemplate, |
| | | formFields, |
| | | formRules, |
| | | hasTemplateBound, |
| | | templatesLoading, |
| | | loadTemplates, |
| | | resetBinding, |
| | | pickBusinessType, |
| | | backToBusinessTypePick, |
| | | backToTemplatePick, |
| | | pickTemplate, |
| | | applyBindingState, |
| | | validateBinding, |
| | | getBindingPayload, |
| | | countTemplatesByBusinessType, |
| | | businessTypeLabel, |
| | | }; |
| | | } |