From 31f8c28b502a3f963a2651194112584371448e37 Mon Sep 17 00:00:00 2001
From: liu <2021943741@qq.com>
Date: 星期四, 27 八月 2026 16:39:47 +0800
Subject: [PATCH] feat(srm): 供应商准入审核接入协同办公(BPM)

---
 src/views/srm/supplierApply/index.vue |  188 +++++++++++++++--------------------------------
 1 files changed, 60 insertions(+), 128 deletions(-)

diff --git a/src/views/srm/supplierApply/index.vue b/src/views/srm/supplierApply/index.vue
index 47b8a8f..34663a8 100644
--- a/src/views/srm/supplierApply/index.vue
+++ b/src/views/srm/supplierApply/index.vue
@@ -2,118 +2,38 @@
 import type { VxeTableGridOptions } from '#/adapter/vxe-table';
 import type { SrmSupplierApplyApi } from '#/api/srm/supplierApply';
 
-import { computed, ref } from 'vue';
+import { useRouter } from 'vue-router';
 
 import { Page, useVbenModal } from '@vben/common-ui';
 
 import { message } from 'ant-design-vue';
 
-import { useVbenForm } from '#/adapter/form';
 import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
 import {
   deleteApply,
+  getApproveProcessList,
   getApplyPage,
-  submitApply,
-  reviewPurchase,
-  reviewQuality,
-  reviewFinance,
 } from '#/api/srm/supplierApply';
 import { $t } from '#/locales';
 
 import { useGridColumns, useGridFormSchema } from './data';
 import ApplyForm from './modules/form.vue';
+import ProcessSelectModal from './modules/process-select-modal.vue';
 import { APPLY_STATUS } from '../enums';
 
 defineOptions({ name: 'SrmSupplierApply' });
 
-// ---------- reviewModal ----------
-const reviewFormData = ref({
-  applyId: 0,
-  reviewType: '' as 'purchase' | 'quality' | 'finance',
-  passed: true,
-  comment: '',
-});
-const reviewTitle = computed(() => {
-  const labels: Record<string, string> = {
-    purchase: '閲囪喘瀹℃牳',
-    quality: '璐ㄩ噺瀹℃牳',
-    finance: '璐㈠姟瀹℃牳',
-  };
-  return labels[reviewFormData.value.reviewType] || '瀹℃牳';
+const router = useRouter();
+
+const [FormModal, formModalApi] = useVbenModal({
+  connectedComponent: ApplyForm,
+  destroyOnClose: true,
 });
 
-const [ReviewForm, reviewFormApi] = useVbenForm({
-  commonConfig: {
-    componentProps: { class: 'w-full' },
-    labelWidth: 100,
-  },
-  wrapperClass: 'grid-cols-1',
-  layout: 'horizontal',
-  schema: [
-    {
-      fieldName: 'passed',
-      label: '瀹℃牳缁撴灉',
-      component: 'RadioGroup',
-      rules: 'required',
-      componentProps: {
-        options: [
-          { label: '閫氳繃', value: true },
-          { label: '鎷掔粷', value: false },
-        ],
-        buttonStyle: 'solid',
-        optionType: 'button',
-      },
-    },
-    {
-      fieldName: 'comment',
-      label: '瀹℃牳鎰忚',
-      component: 'Textarea',
-      componentProps: { placeholder: '璇疯緭鍏ュ鏍告剰瑙�', rows: 3 },
-    },
-  ],
-  showDefaultActions: false,
+const [ProcessModal, processModalApi] = useVbenModal({
+  connectedComponent: ProcessSelectModal,
+  destroyOnClose: true,
 });
-
-const [ReviewModal, reviewModalApi] = useVbenModal({
-  async onConfirm() {
-    const { valid } = await reviewFormApi.validate();
-    if (!valid) {
-      return;
-    }
-    reviewModalApi.lock();
-    const data = (await reviewFormApi.getValues()) as { passed: boolean; comment?: string };
-    try {
-      const payload: SrmSupplierApplyApi.ReviewVO = {
-        id: reviewFormData.value.applyId,
-        passed: data.passed,
-        comment: data.comment,
-      };
-      if (reviewFormData.value.reviewType === 'purchase') {
-        await reviewPurchase(payload);
-      } else if (reviewFormData.value.reviewType === 'quality') {
-        await reviewQuality(payload);
-      } else if (reviewFormData.value.reviewType === 'finance') {
-        await reviewFinance(payload);
-      }
-      await reviewModalApi.close();
-      handleRefresh();
-      message.success($t('ui.actionMessage.operationSuccess'));
-    } finally {
-      reviewModalApi.unlock();
-    }
-  },
-});
-
-function openReviewModal(row: SrmSupplierApplyApi.ApplyVO, reviewType: 'purchase' | 'quality' | 'finance') {
-  reviewFormData.value = {
-    applyId: row.id!,
-    reviewType,
-    passed: true,
-    comment: '',
-  };
-  reviewFormApi.resetForm();
-  reviewModalApi.open();
-}
 
 // ---------- grid ----------
 function handleRefresh() {
@@ -121,11 +41,16 @@
 }
 
 function handleCreate() {
-  formModalApi.setData(null).open();
+  formModalApi.setData({ formType: 'create' }).open();
 }
 
 function handleEdit(row: SrmSupplierApplyApi.ApplyVO) {
-  formModalApi.setData(row).open();
+  formModalApi.setData({ formType: 'edit', id: row.id }).open();
+}
+
+/** 鏌ョ湅璇︽儏锛堝彧璇伙級 */
+function handleDetail(row: SrmSupplierApplyApi.ApplyVO) {
+  formModalApi.setData({ formType: 'detail', id: row.id }).open();
 }
 
 async function handleDelete(row: SrmSupplierApplyApi.ApplyVO) {
@@ -142,21 +67,38 @@
   }
 }
 
+/** 鎻愪氦瀹℃壒 - 鍏堣幏鍙栧崗鍚屽姙鍏鎵规祦绋嬪垪琛� */
 async function handleSubmit(row: SrmSupplierApplyApi.ApplyVO) {
-  const hideLoading = message.loading({ content: '鎻愪氦涓�...', duration: 0 });
+  const hideLoading = message.loading({
+    content: '鑾峰彇瀹℃壒娴佺▼...',
+    duration: 0,
+  });
   try {
-    await submitApply(row.id!);
-    message.success($t('ui.actionMessage.operationSuccess'));
-    handleRefresh();
-  } finally {
+    const processList = await getApproveProcessList();
+    hideLoading();
+    if (!processList || processList.length === 0) {
+      message.warning('鏆傛棤鍙敤瀹℃壒娴佺▼锛岃鍏堝湪鍗忓悓鍔炲叕閰嶇疆瀹℃壒娴佺▼');
+      return;
+    }
+    // 鎵撳紑娴佺▼閫夋嫨寮圭獥
+    processModalApi.setData({ id: row.id, processList }).open();
+  } catch {
     hideLoading();
   }
 }
 
-const [FormModal, formModalApi] = useVbenModal({
-  connectedComponent: ApplyForm,
-  destroyOnClose: true,
-});
+/** 鏌ョ湅瀹℃壒杩涘害锛堣烦杞崗鍚屽姙鍏祦绋嬪疄渚嬭鎯咃紝鍙鏌ョ湅锛� */
+function handleViewProcess(row: SrmSupplierApplyApi.ApplyVO) {
+  if (!row.processInstanceId) {
+    message.warning('璇ョ敵璇峰皻鏈彁浜ゅ鎵�');
+    return;
+  }
+  // viewOnly=1锛氶殣钘忓鎵规搷浣滄寜閽紝浠呮煡鐪嬪鎵硅繘搴�
+  router.push({
+    name: 'BpmProcessInstanceDetail',
+    query: { id: row.processInstanceId, viewOnly: '1' },
+  });
+}
 
 const [Grid, gridApi] = useVbenVxeGrid({
   formOptions: {
@@ -186,9 +128,7 @@
 <template>
   <Page auto-content-height>
     <FormModal @success="handleRefresh" />
-    <ReviewModal :title="reviewTitle" class="w-1/3">
-      <ReviewForm class="mx-4" />
-    </ReviewModal>
+    <ProcessModal @success="handleRefresh" />
     <Grid table-title="鍑嗗叆鐢宠鍒楄〃">
       <template #toolbar-tools>
         <TableAction
@@ -207,43 +147,34 @@
         <TableAction
           :actions="[
             {
-              label: $t('common.edit'),
+              label: $t('common.detail'),
               type: 'link',
-              icon: ACTION_ICON.EDIT,
-              auth: ['srm:supplier-apply:update'],
-              onClick: handleEdit.bind(null, row),
+              icon: ACTION_ICON.VIEW,
+              auth: ['srm:supplier-apply:query'],
+              onClick: handleDetail.bind(null, row),
             },
             {
               label: '鎻愪氦',
               type: 'link',
-              icon: ACTION_ICON.CHECK,
+              icon: ACTION_ICON.AUDIT,
               auth: ['srm:supplier-apply:update'],
-              ifShow: row.applyStatus === APPLY_STATUS.DRAFT,
+              ifShow: () => row.applyStatus === APPLY_STATUS.DRAFT || row.applyStatus === APPLY_STATUS.REJECTED,
               onClick: handleSubmit.bind(null, row),
             },
             {
-              label: '閲囪喘瀹℃牳',
+              label: '鏌ョ湅瀹℃壒',
               type: 'link',
-              icon: ACTION_ICON.CHECK,
-              auth: ['srm:supplier-apply:update'],
-              ifShow: row.applyStatus === APPLY_STATUS.PENDING_PURCHASE,
-              onClick: openReviewModal.bind(null, row, 'purchase'),
+              icon: ACTION_ICON.VIEW,
+              ifShow: () => !!row.processInstanceId,
+              onClick: handleViewProcess.bind(null, row),
             },
             {
-              label: '璐ㄩ噺瀹℃牳',
+              label: $t('common.edit'),
               type: 'link',
-              icon: ACTION_ICON.CHECK,
+              icon: ACTION_ICON.EDIT,
               auth: ['srm:supplier-apply:update'],
-              ifShow: row.applyStatus === APPLY_STATUS.PENDING_QUALITY,
-              onClick: openReviewModal.bind(null, row, 'quality'),
-            },
-            {
-              label: '璐㈠姟瀹℃牳',
-              type: 'link',
-              icon: ACTION_ICON.CHECK,
-              auth: ['srm:supplier-apply:update'],
-              ifShow: row.applyStatus === APPLY_STATUS.PENDING_FINANCE,
-              onClick: openReviewModal.bind(null, row, 'finance'),
+              ifShow: () => row.applyStatus === APPLY_STATUS.DRAFT || row.applyStatus === APPLY_STATUS.REJECTED,
+              onClick: handleEdit.bind(null, row),
             },
             {
               label: $t('common.delete'),
@@ -251,6 +182,7 @@
               danger: true,
               icon: ACTION_ICON.DELETE,
               auth: ['srm:supplier-apply:delete'],
+              ifShow: () => row.applyStatus === APPLY_STATUS.DRAFT || row.applyStatus === APPLY_STATUS.REJECTED,
               popConfirm: {
                 title: $t('ui.actionMessage.deleteConfirm', [row.supplierName]),
                 confirm: handleDelete.bind(null, row),

--
Gitblit v1.9.3