feat(srm): 供应商准入审核接入协同办公(BPM)
- 移除采购/质量/财务审核按钮,改为提交时选择协同办公审批流程
- 新增审批流程选择弹窗、查看审批(只读)跳转
- 新增协同办公审批详情业务组件 /srm/supplierApply/detail/index.vue
- 状态简化为 5 态,表单支持只读详情模式
- 接口新增 getApproveProcessList,submit 携带 processDefinitionKey
Co-Authored-By: Claude <noreply@anthropic.com>
| | |
| | | applyNo?: string; |
| | | supplierId?: number; |
| | | supplierName: string; |
| | | contactName?: string; |
| | | contactMobile?: string; |
| | | contactEmail?: string; |
| | | supplierType?: string; |
| | | companyNature?: string; |
| | | registeredCapital?: number; |
| | | businessLicenseNo?: string; |
| | | taxNo?: string; |
| | | address?: string; |
| | | bankName?: string; |
| | | bankAccount?: string; |
| | | taxNo?: string; |
| | | businessLicense?: string; |
| | | taxCertificate?: string; |
| | | orgCodeCertificate?: string; |
| | | contactName?: string; |
| | | contactMobile?: string; |
| | | contactEmail?: string; |
| | | applyUserName?: string; |
| | | applyTime?: string; |
| | | applyStatus?: number; |
| | | applyStatusLabel?: string; |
| | | auditComment?: string; |
| | | processInstanceId?: string; |
| | | remark?: string; |
| | | createTime?: string; |
| | | } |
| | | |
| | | export interface ReviewVO { |
| | | id: number; |
| | | passed: boolean; |
| | | comment?: string; |
| | | /** åååå
¬å®¡æ¹æµç¨å®ä¹ */ |
| | | export interface ProcessDefinition { |
| | | id: string; |
| | | key: string; |
| | | name: string; |
| | | } |
| | | } |
| | | |
| | |
| | | return requestClient.delete(`/srm/supplier-apply/delete?id=${id}`); |
| | | } |
| | | |
| | | /** æäº¤å®¡æ ¸ */ |
| | | export function submitApply(id: number) { |
| | | return requestClient.put(`/srm/supplier-apply/submit?id=${id}`); |
| | | /** è·åå®¡æ¹æµç¨å表ï¼åååå
¬å·²å叿µç¨ï¼ */ |
| | | export function getApproveProcessList() { |
| | | return requestClient.get<SrmSupplierApplyApi.ProcessDefinition[]>( |
| | | '/srm/supplier-apply/approve-process-list', |
| | | ); |
| | | } |
| | | |
| | | /** éè´å®¡æ ¸ */ |
| | | export function reviewPurchase(data: SrmSupplierApplyApi.ReviewVO) { |
| | | return requestClient.put('/srm/supplier-apply/review-purchase', data); |
| | | } |
| | | |
| | | /** è´¨éå®¡æ ¸ */ |
| | | export function reviewQuality(data: SrmSupplierApplyApi.ReviewVO) { |
| | | return requestClient.put('/srm/supplier-apply/review-quality', data); |
| | | } |
| | | |
| | | /** è´¢å¡å®¡æ ¸ */ |
| | | export function reviewFinance(data: SrmSupplierApplyApi.ReviewVO) { |
| | | return requestClient.put('/srm/supplier-apply/review-finance', data); |
| | | /** æäº¤åå
¥ç³è¯·å®¡æ¹ï¼å¯å¨åååå
¬æµç¨ï¼ */ |
| | | export function submitApply(id: number, processDefinitionKey: string) { |
| | | return requestClient.put('/srm/supplier-apply/submit', null, { |
| | | params: { id, processDefinitionKey }, |
| | | }); |
| | | } |
| | |
| | | labels: { '1': 'ç产å', '2': 'è´¸æå', '3': 'æå¡å', '4': 'å
¶ä»' }, |
| | | }; |
| | | |
| | | // ========== åå
¥ç³è¯· â å¯¹é½ SupplierApplyStatusEnum (0/10/20/30/40/50) ========== |
| | | // ========== åå
¥ç³è¯· â å¯¹é½ SupplierApplyStatusEnum (0/10/30/40/50) |
| | | // æ¥å
¥åååå
¬åç®å为 5 æï¼å¾
æäº¤ / 审æ¹ä¸ / 已忶 / å·²éè¿ / 已驳å |
| | | // åå¾
éè´å®¡æ ¸(10)/å¾
è´¨éå®¡æ ¸(20)/å¾
è´¢å¡å®¡æ ¸(30)å·²åºå¼ ========== |
| | | |
| | | export const APPLY_STATUS = { |
| | | DRAFT: 0, |
| | | PENDING_PURCHASE: 10, |
| | | PENDING_QUALITY: 20, |
| | | PENDING_FINANCE: 30, |
| | | PROCESS: 10, |
| | | CANCEL: 30, |
| | | APPROVED: 40, |
| | | REJECTED: 50, |
| | | } as const; |
| | | |
| | | export const APPLY_STATUS_OPTIONS: EnumOption[] = [ |
| | | { label: 'å¾
æäº¤', value: 0 }, |
| | | { label: 'å¾
éè´å®¡æ ¸', value: 10 }, |
| | | { label: 'å¾
è´¨éå®¡æ ¸', value: 20 }, |
| | | { label: 'å¾
è´¢å¡å®¡æ ¸', value: 30 }, |
| | | { label: '审æ¹ä¸', value: 10 }, |
| | | { label: '已忶', value: 30 }, |
| | | { label: 'å·²éè¿', value: 40 }, |
| | | { label: 'å·²æç»', value: 50 }, |
| | | { label: '已驳å', value: 50 }, |
| | | ]; |
| | | |
| | | export const APPLY_STATUS_CELLTAG: { data: CellTagItem[]; labels: Record<number, string> } = { |
| | | data: [ |
| | | { value: 0, color: 'gray' }, |
| | | { value: 10, color: 'blue' }, |
| | | { value: 20, color: 'orange' }, |
| | | { value: 30, color: 'purple' }, |
| | | { value: 40, color: 'green' }, |
| | | { value: 50, color: 'red' }, |
| | | ], |
| | | labels: { 0: 'å¾
æäº¤', 10: 'å¾
éè´å®¡æ ¸', 20: 'å¾
è´¨éå®¡æ ¸', 30: 'å¾
è´¢å¡å®¡æ ¸', 40: 'å·²éè¿', 50: 'å·²æç»' }, |
| | | labels: { 0: 'å¾
æäº¤', 10: '审æ¹ä¸', 30: '已忶', 40: 'å·²éè¿', 50: '已驳å' }, |
| | | }; |
| | | |
| | | // ========== èµè´¨è¯ä¹¦ â å¯¹é½ CertificateTypeEnum (1=è¥ä¸æ§ç
§ 2=认è¯è¯ä¹¦ 3=æ£æµæ¥å 4=å
¶ä») ========== |
| | |
| | | |
| | | import { APPLY_STATUS_CELLTAG, APPLY_STATUS_OPTIONS } from '../enums'; |
| | | |
| | | /** 表åç±»åï¼æ°å¢ / ç¼è¾ / 详æ
ï¼åªè¯»ï¼ */ |
| | | export type FormType = 'create' | 'edit' | 'detail'; |
| | | |
| | | /** æ°å¢/ä¿®æ¹ç表å */ |
| | | export function useFormSchema(formApi?: VbenFormApi): VbenFormSchema[] { |
| | | return [ |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <script lang="ts" setup> |
| | | import type { SrmSupplierApplyApi } from '#/api/srm/supplierApply'; |
| | | import type { DescriptionItemSchema } from '#/components/description'; |
| | | |
| | | import { h, onMounted, ref } from 'vue'; |
| | | |
| | | import { ContentWrap } from '@vben/common-ui'; |
| | | import { formatDateTime } from '@vben/utils'; |
| | | |
| | | import { Spin, Tag } from 'ant-design-vue'; |
| | | |
| | | import { getApply } from '#/api/srm/supplierApply'; |
| | | import { useDescription } from '#/components/description'; |
| | | |
| | | import { APPLY_STATUS_CELLTAG } from '../../enums'; |
| | | |
| | | defineOptions({ name: 'SrmSupplierApplyDetail' }); |
| | | |
| | | const props = defineProps<{ id: string }>(); |
| | | |
| | | const loading = ref(false); |
| | | const formData = ref<SrmSupplierApplyApi.ApplyVO>(); |
| | | |
| | | /** ææ¬åæ®µç©ºå¼å ä½ */ |
| | | function textRender(val: unknown) { |
| | | return val === 0 || val ? String(val) : '-'; |
| | | } |
| | | |
| | | /** ç³è¯·ç¶ææ ç¾æ¸²æ */ |
| | | function statusRender(val: unknown) { |
| | | const num = Number(val); |
| | | const item = APPLY_STATUS_CELLTAG.data.find((i) => Number(i.value) === num); |
| | | const label = APPLY_STATUS_CELLTAG.labels[num] || '-'; |
| | | return h(Tag, { color: item?.color }, { default: () => label }); |
| | | } |
| | | |
| | | const [Descriptions] = useDescription({ |
| | | bordered: true, |
| | | column: 2, |
| | | schema: [ |
| | | { label: 'ç³è¯·ç¼å·', field: 'applyNo', render: textRender }, |
| | | { label: 'ç³è¯·ç¶æ', field: 'applyStatus', render: statusRender }, |
| | | { label: 'ç³è¯·äºº', field: 'applyUserName', render: textRender }, |
| | | { |
| | | label: 'ç³è¯·æ¶é´', |
| | | field: 'applyTime', |
| | | render: (val) => formatDateTime(val) as string, |
| | | }, |
| | | { label: 'ä¾åºååç§°', field: 'supplierName', render: textRender }, |
| | | { label: 'ä¾åºåç±»å', field: 'supplierType', render: textRender }, |
| | | { label: 'ä¼ä¸æ§è´¨', field: 'companyNature', render: textRender }, |
| | | { |
| | | label: '注åèµé(ä¸å
)', |
| | | field: 'registeredCapital', |
| | | render: textRender, |
| | | }, |
| | | { label: 'è¥ä¸æ§ç
§ç¼å·', field: 'businessLicenseNo', render: textRender }, |
| | | { label: 'ç¨å·', field: 'taxNo', render: textRender }, |
| | | { label: '弿·é¶è¡', field: 'bankName', render: textRender }, |
| | | { label: 'é¶è¡è´¦å·', field: 'bankAccount', render: textRender }, |
| | | { label: 'è系人', field: 'contactName', render: textRender }, |
| | | { label: 'èç³»çµè¯', field: 'contactMobile', render: textRender }, |
| | | { label: 'é®ç®±', field: 'contactEmail', render: textRender }, |
| | | { label: 'å
¬å¸å°å', field: 'address', render: textRender }, |
| | | { |
| | | label: '夿³¨', |
| | | field: 'remark', |
| | | render: textRender, |
| | | span: 2, |
| | | }, |
| | | ] as DescriptionItemSchema[], |
| | | }); |
| | | |
| | | onMounted(async () => { |
| | | try { |
| | | loading.value = true; |
| | | formData.value = await getApply(Number(props.id)); |
| | | } finally { |
| | | loading.value = false; |
| | | } |
| | | }); |
| | | </script> |
| | | |
| | | <template> |
| | | <ContentWrap class="m-2"> |
| | | <Spin :spinning="loading" tip="å è½½ä¸..."> |
| | | <div class="rounded-lg border border-border bg-background p-4"> |
| | | <div class="mb-4 flex items-center gap-2"> |
| | | <span class="inline-block h-4 w-1 rounded bg-primary" /> |
| | | <span class="text-base font-semibold">ä¾åºååå
¥ç³è¯·</span> |
| | | </div> |
| | | <Descriptions :data="formData" /> |
| | | </div> |
| | | </Spin> |
| | | </ContentWrap> |
| | | </template> |
| | |
| | | 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), |
| | |
| | | <script lang="ts" setup> |
| | | import type { SrmSupplierApplyApi } from '#/api/srm/supplierApply'; |
| | | import type { FormType } from '../data'; |
| | | |
| | | import { computed, ref } from 'vue'; |
| | | |
| | |
| | | |
| | | const emit = defineEmits(['success']); |
| | | const formData = ref<SrmSupplierApplyApi.ApplyVO>(); |
| | | const formType = ref<FormType>('create'); |
| | | |
| | | const getTitle = computed(() => { |
| | | return formData.value?.id |
| | | ? $t('ui.actionTitle.edit', ['åå
¥ç³è¯·']) |
| | | : $t('ui.actionTitle.create', ['åå
¥ç³è¯·']); |
| | | if (formType.value === 'create') { |
| | | return $t('ui.actionTitle.create', ['åå
¥ç³è¯·']); |
| | | } else if (formType.value === 'edit') { |
| | | return $t('ui.actionTitle.edit', ['åå
¥ç³è¯·']); |
| | | } else { |
| | | return 'åå
¥ç³è¯·è¯¦æ
'; |
| | | } |
| | | }); |
| | | |
| | | const [Form, formApi] = useVbenForm({ |
| | |
| | | formData.value = undefined; |
| | | return; |
| | | } |
| | | const data = modalApi.getData<SrmSupplierApplyApi.ApplyVO>(); |
| | | const data = modalApi.getData<{ formType: FormType; id?: number }>(); |
| | | formType.value = data?.formType ?? 'create'; |
| | | formApi.setDisabled(formType.value === 'detail'); |
| | | formApi.updateSchema(useFormSchema(formApi)); |
| | | if (!data || !data.id) { |
| | | return; |
| | | } |
| | |
| | | </script> |
| | | |
| | | <template> |
| | | <Modal :title="getTitle" class="w-1/2"> |
| | | <Modal |
| | | :title="getTitle" |
| | | class="w-1/2" |
| | | :show-confirm-button="formType !== 'detail'" |
| | | > |
| | | <Form class="mx-4" /> |
| | | </Modal> |
| | | </template> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <script lang="ts" setup> |
| | | import type { SrmSupplierApplyApi } from '#/api/srm/supplierApply'; |
| | | |
| | | import { computed, ref } from 'vue'; |
| | | |
| | | import { useVbenModal } from '@vben/common-ui'; |
| | | |
| | | import { message, Select } from 'ant-design-vue'; |
| | | |
| | | import { submitApply } from '#/api/srm/supplierApply'; |
| | | |
| | | const emit = defineEmits(['success']); |
| | | |
| | | const applyId = ref<number>(); |
| | | const processList = ref<SrmSupplierApplyApi.ProcessDefinition[]>([]); |
| | | const selectedProcessKey = ref<string>(''); |
| | | |
| | | const processOptions = computed(() => { |
| | | return processList.value.map((p) => ({ |
| | | label: p.name, |
| | | value: p.key, |
| | | })); |
| | | }); |
| | | |
| | | const [Modal, modalApi] = useVbenModal({ |
| | | async onConfirm() { |
| | | if (!selectedProcessKey.value) { |
| | | message.warning('è¯·éæ©å®¡æ¹æµç¨'); |
| | | return; |
| | | } |
| | | modalApi.lock(); |
| | | try { |
| | | await submitApply(applyId.value!, selectedProcessKey.value); |
| | | await modalApi.close(); |
| | | emit('success'); |
| | | message.success('æäº¤æå'); |
| | | } finally { |
| | | modalApi.unlock(); |
| | | } |
| | | }, |
| | | async onOpenChange(isOpen: boolean) { |
| | | if (!isOpen) { |
| | | applyId.value = undefined; |
| | | selectedProcessKey.value = ''; |
| | | processList.value = []; |
| | | return; |
| | | } |
| | | const data = modalApi.getData<{ |
| | | id: number; |
| | | processList: SrmSupplierApplyApi.ProcessDefinition[]; |
| | | }>(); |
| | | applyId.value = data?.id; |
| | | processList.value = data?.processList || []; |
| | | // é»è®¤éæ©ç¬¬ä¸ä¸ªæµç¨ |
| | | if (processList.value.length > 0) { |
| | | selectedProcessKey.value = processList.value[0]!.key; |
| | | } |
| | | }, |
| | | }); |
| | | </script> |
| | | |
| | | <template> |
| | | <Modal title="éæ©å®¡æ¹æµç¨" class="w-1/3"> |
| | | <div class="mb-4"> |
| | | <span class="mr-2">å®¡æ¹æµç¨ï¼</span> |
| | | <Select |
| | | v-model:value="selectedProcessKey" |
| | | :options="processOptions" |
| | | style="width: 220px" |
| | | placeholder="è¯·éæ©å®¡æ¹æµç¨" |
| | | /> |
| | | </div> |
| | | </Modal> |
| | | </template> |