| | |
| | | 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() { |
| | |
| | | } |
| | | |
| | | 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) { |
| | |
| | | } |
| | | } |
| | | |
| | | /** 提交审批 - 先获取协同办公审批流程列表 */ |
| | | 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: { |
| | |
| | | <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 |
| | |
| | | <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'), |
| | |
| | | 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), |