From f3cac4aa2db56d6017c1d1dc035bcfeaec76c3e2 Mon Sep 17 00:00:00 2001
From: gaoluyang <2820782392@qq.com>
Date: 星期四, 05 十一月 2026 18:31:13 +0800
Subject: [PATCH] feat(crm): 投标保证金迁移到销售管理并接入销售台账
---
/dev/null | 116 ----------
src/views/crm/bidBond/index.vue | 33 +-
src/views/crm/bidBond/data.ts | 290 ++++++++++++++++++++++++++
src/views/crm/bidBond/modules/form.vue | 141 ++++++++++++
src/api/crm/bidBond/index.ts | 77 +++++++
5 files changed, 526 insertions(+), 131 deletions(-)
diff --git a/src/api/crm/bidBond/index.ts b/src/api/crm/bidBond/index.ts
new file mode 100644
index 0000000..f306d97
--- /dev/null
+++ b/src/api/crm/bidBond/index.ts
@@ -0,0 +1,77 @@
+import type { PageParam, PageResult } from '@vben/request';
+
+import { requestClient } from '#/api/request';
+
+export namespace CrmBidBondApi {
+ /** 鎶曟爣淇濊瘉閲� */
+ export interface BidBond {
+ id?: number;
+ no?: string;
+ customerId?: number;
+ customerName?: string;
+ projectName?: string;
+ tenderNo?: string;
+ saleOrderId?: number;
+ saleOrderNo?: string;
+ saleOrderAmount?: number;
+ bondAmount?: number;
+ payDate?: string;
+ /** 涓爣缁撴灉锛�0 寰呭紑鏍囥��1 宸蹭腑鏍囥��2 鏈腑鏍� */
+ bidResult?: number;
+ /** 閫�鍥炵姸鎬侊細0 鏈��鍥炪��1 閮ㄥ垎閫�鍥炪��2 宸查��鍥炪��3 鏃犻渶閫�鍥� */
+ refundStatus?: number;
+ refundAmount?: number;
+ refundDate?: string;
+ remark?: string;
+ createTime?: string;
+ }
+
+ /** 鍙叧鑱旂殑閿�鍞鍗曪紙閿�鍞彴璐︼級 */
+ export interface SaleOrderOption {
+ id: number;
+ no: string;
+ customerId: number;
+ status: number;
+ statusName?: string;
+ totalPrice?: number;
+ contractNo?: string;
+ }
+}
+
+/** 鍒嗛〉鏌ヨ鎶曟爣淇濊瘉閲� */
+export function getBidBondPage(params: PageParam) {
+ return requestClient.get<PageResult<CrmBidBondApi.BidBond>>(
+ '/crm/bid-bond/page',
+ { params },
+ );
+}
+
+/** 鏌ヨ鎶曟爣淇濊瘉閲戣鎯� */
+export function getBidBond(id: number) {
+ return requestClient.get<CrmBidBondApi.BidBond>(
+ `/crm/bid-bond/get?id=${id}`,
+ );
+}
+
+/** 鍒涘缓鎶曟爣淇濊瘉閲� */
+export function createBidBond(data: CrmBidBondApi.BidBond) {
+ return requestClient.post<number>('/crm/bid-bond/create', data);
+}
+
+/** 鏇存柊鎶曟爣淇濊瘉閲� */
+export function updateBidBond(data: CrmBidBondApi.BidBond) {
+ return requestClient.put('/crm/bid-bond/update', data);
+}
+
+/** 鍒犻櫎鎶曟爣淇濊瘉閲� */
+export function deleteBidBond(id: number) {
+ return requestClient.delete('/crm/bid-bond/delete', { params: { id } });
+}
+
+/** 鏌ヨ瀹㈡埛涓嬪彲鍏宠仈鐨勯攢鍞鍗曪紙浠呭凡瀹℃牳锛� */
+export function getSaleOrderOptions(customerId: number) {
+ return requestClient.get<CrmBidBondApi.SaleOrderOption[]>(
+ '/crm/bid-bond/sale-order-list',
+ { params: { customerId } },
+ );
+}
diff --git a/src/api/srm/bidBond/index.ts b/src/api/srm/bidBond/index.ts
deleted file mode 100644
index 1f18660..0000000
--- a/src/api/srm/bidBond/index.ts
+++ /dev/null
@@ -1,56 +0,0 @@
-import type { PageParam, PageResult } from '@vben/request';
-
-import { requestClient } from '#/api/request';
-
-export namespace SrmBidBondApi {
- /** 鎶曟爣淇濊瘉閲� */
- export interface BidBond {
- id?: number;
- no?: string;
- supplierId?: number;
- supplierName?: string;
- projectName?: string;
- inquiryId?: number;
- inquiryNo?: string;
- purchaseOrderId?: number;
- purchaseOrderNo?: string;
- bondAmount?: number;
- payDate?: string;
- won?: boolean;
- refundStatus?: number;
- refundAmount?: number;
- refundDate?: string;
- remark?: string;
- createTime?: string;
- }
-}
-
-/** 鍒嗛〉鏌ヨ鎶曟爣淇濊瘉閲� */
-export function getBidBondPage(params: PageParam) {
- return requestClient.get<PageResult<SrmBidBondApi.BidBond>>(
- '/srm/bid-bond/page',
- { params },
- );
-}
-
-/** 鏌ヨ鎶曟爣淇濊瘉閲戣鎯� */
-export function getBidBond(id: number) {
- return requestClient.get<SrmBidBondApi.BidBond>(
- `/srm/bid-bond/get?id=${id}`,
- );
-}
-
-/** 鍒涘缓鎶曟爣淇濊瘉閲� */
-export function createBidBond(data: SrmBidBondApi.BidBond) {
- return requestClient.post<number>('/srm/bid-bond/create', data);
-}
-
-/** 鏇存柊鎶曟爣淇濊瘉閲� */
-export function updateBidBond(data: SrmBidBondApi.BidBond) {
- return requestClient.put('/srm/bid-bond/update', data);
-}
-
-/** 鍒犻櫎鎶曟爣淇濊瘉閲� */
-export function deleteBidBond(id: number) {
- return requestClient.delete('/srm/bid-bond/delete', { params: { id } });
-}
diff --git a/src/views/crm/bidBond/data.ts b/src/views/crm/bidBond/data.ts
new file mode 100644
index 0000000..48d362c
--- /dev/null
+++ b/src/views/crm/bidBond/data.ts
@@ -0,0 +1,290 @@
+import type { VbenFormSchema } from '#/adapter/form';
+import type { VxeTableGridOptions } from '#/adapter/vxe-table';
+
+import { getCustomerSimpleList } from '#/api/crm/customer';
+import { getSaleOrderOptions } from '#/api/crm/bidBond';
+
+export const BID_RESULT_OPTIONS = [
+ { label: '寰呭紑鏍�', value: 0, color: 'processing' },
+ { label: '宸蹭腑鏍�', value: 1, color: 'success' },
+ { label: '鏈腑鏍�', value: 2, color: 'default' },
+];
+
+export const REFUND_STATUS_OPTIONS = [
+ { label: '鏈��鍥�', value: 0, color: 'warning' },
+ { label: '閮ㄥ垎閫�鍥�', value: 1, color: 'processing' },
+ { label: '宸查��鍥�', value: 2, color: 'success' },
+ { label: '鏃犻渶閫�鍥�', value: 3, color: 'default' },
+];
+
+export function getBidResultLabel(result?: number) {
+ return BID_RESULT_OPTIONS.find((item) => item.value === result)?.label ?? '-';
+}
+
+export function getBidResultColor(result?: number) {
+ return BID_RESULT_OPTIONS.find((item) => item.value === result)?.color ?? 'default';
+}
+
+export function getRefundStatusLabel(status?: number) {
+ return REFUND_STATUS_OPTIONS.find((item) => item.value === status)?.label ?? '-';
+}
+
+export function getRefundStatusColor(status?: number) {
+ return REFUND_STATUS_OPTIONS.find((item) => item.value === status)?.color ?? 'default';
+}
+
+/** 鏂板/淇敼鎶曟爣淇濊瘉閲戠殑琛ㄥ崟 */
+export function useFormSchema(): VbenFormSchema[] {
+ return [
+ {
+ fieldName: 'customerId',
+ label: '瀹㈡埛锛堟嫑鏍囨柟锛�',
+ component: 'ApiSelect',
+ rules: 'required',
+ componentProps: {
+ placeholder: '璇烽�夋嫨瀹㈡埛',
+ allowClear: true,
+ showSearch: true,
+ api: getCustomerSimpleList,
+ labelField: 'name',
+ valueField: 'id',
+ },
+ },
+ {
+ fieldName: 'projectName',
+ label: '椤圭洰鍚嶇О',
+ component: 'Input',
+ componentProps: { placeholder: '璇疯緭鍏ユ湰娆℃姇鏍囬」鐩悕绉�' },
+ },
+ {
+ fieldName: 'tenderNo',
+ label: '鎷涙爣缂栧彿',
+ component: 'Input',
+ componentProps: { placeholder: '璇疯緭鍏ユ嫑鏍囨柟鍙戝竷鐨勬嫑鏍囩紪鍙�' },
+ },
+ {
+ fieldName: 'saleOrderId',
+ label: '鍏宠仈閿�鍞鍗�',
+ component: 'ApiSelect',
+ componentProps: {
+ placeholder: '璇峰厛閫夋嫨瀹㈡埛',
+ allowClear: true,
+ showSearch: true,
+ labelField: 'no',
+ valueField: 'id',
+ optionFilterProp: 'label',
+ },
+ dependencies: {
+ triggerFields: ['customerId'],
+ componentProps: (values) => {
+ const customerId = values.customerId as number | undefined;
+ return {
+ placeholder: customerId
+ ? '璇烽�夋嫨璇ュ鎴峰凡瀹℃牳鐨勯攢鍞鍗曪紙閿�鍞彴璐︼級'
+ : '璇峰厛閫夋嫨瀹㈡埛',
+ disabled: !customerId,
+ api: customerId
+ ? () => getSaleOrderOptions(customerId)
+ : () => Promise.resolve([]),
+ };
+ },
+ },
+ },
+ {
+ fieldName: 'bondAmount',
+ label: '淇濊瘉閲戦噾棰�',
+ component: 'InputNumber',
+ rules: 'required',
+ componentProps: {
+ class: '!w-full',
+ placeholder: '璇疯緭鍏ョ即绾崇殑淇濊瘉閲戦噾棰�',
+ min: 0,
+ precision: 2,
+ },
+ },
+ {
+ fieldName: 'payDate',
+ label: '缂寸撼鏃ユ湡',
+ component: 'DatePicker',
+ componentProps: {
+ class: 'w-full',
+ placeholder: '璇烽�夋嫨鍚戝鎴风即绾充繚璇侀噾鐨勬棩鏈�',
+ format: 'YYYY-MM-DD',
+ valueFormat: 'YYYY-MM-DD',
+ },
+ },
+ {
+ fieldName: 'bidResult',
+ label: '涓爣缁撴灉',
+ component: 'Select',
+ rules: 'required',
+ componentProps: {
+ placeholder: '璇烽�夋嫨涓爣缁撴灉',
+ options: BID_RESULT_OPTIONS.map(({ label, value }) => ({
+ label,
+ value,
+ })),
+ },
+ defaultValue: 0,
+ },
+ {
+ fieldName: 'refundStatus',
+ label: '閫�鍥炵姸鎬�',
+ component: 'Select',
+ componentProps: {
+ placeholder: '鏈腑鏍囨椂璺熻釜淇濊瘉閲戞槸鍚﹂��鍥�',
+ options: REFUND_STATUS_OPTIONS.map(({ label, value }) => ({
+ label,
+ value,
+ })),
+ },
+ },
+ {
+ fieldName: 'refundAmount',
+ label: '閫�鍥為噾棰�',
+ component: 'InputNumber',
+ componentProps: {
+ class: '!w-full',
+ placeholder: '宸查��鍥炴椂椤荤瓑浜庝繚璇侀噾閲戦锛涢儴鍒嗛��鍥炴椂椤诲皬浜庝繚璇侀噾閲戦',
+ min: 0,
+ precision: 2,
+ },
+ },
+ {
+ fieldName: 'refundDate',
+ label: '閫�鍥炴棩鏈�',
+ component: 'DatePicker',
+ componentProps: {
+ class: 'w-full',
+ placeholder: '璇烽�夋嫨瀹㈡埛瀹為檯閫�鍥炰繚璇侀噾鐨勬棩鏈�',
+ format: 'YYYY-MM-DD',
+ valueFormat: 'YYYY-MM-DD',
+ },
+ },
+ {
+ fieldName: 'remark',
+ label: '澶囨敞',
+ component: 'Textarea',
+ componentProps: { placeholder: '璇疯緭鍏ュ娉�', rows: 2 },
+ formItemClass: 'col-span-2',
+ },
+ ];
+}
+
+/** 鎼滅储琛ㄥ崟 */
+export function useGridFormSchema(): VbenFormSchema[] {
+ return [
+ {
+ fieldName: 'no',
+ label: '淇濊瘉閲戝崟鍙�',
+ component: 'Input',
+ componentProps: { placeholder: '璇疯緭鍏ヤ繚璇侀噾鍗曞彿', allowClear: true },
+ },
+ {
+ fieldName: 'customerId',
+ label: '瀹㈡埛',
+ component: 'ApiSelect',
+ componentProps: {
+ placeholder: '璇烽�夋嫨瀹㈡埛',
+ allowClear: true,
+ showSearch: true,
+ api: getCustomerSimpleList,
+ labelField: 'name',
+ valueField: 'id',
+ },
+ },
+ {
+ fieldName: 'projectName',
+ label: '椤圭洰鍚嶇О',
+ component: 'Input',
+ componentProps: { placeholder: '璇疯緭鍏ラ」鐩悕绉�', allowClear: true },
+ },
+ {
+ fieldName: 'saleOrderNo',
+ label: '閿�鍞鍗曞彿',
+ component: 'Input',
+ componentProps: { placeholder: '璇疯緭鍏ュ叧鑱旈攢鍞鍗曞彿', allowClear: true },
+ },
+ {
+ fieldName: 'bidResult',
+ label: '涓爣缁撴灉',
+ component: 'Select',
+ componentProps: {
+ placeholder: '璇烽�夋嫨',
+ allowClear: true,
+ options: BID_RESULT_OPTIONS.map(({ label, value }) => ({
+ label,
+ value,
+ })),
+ },
+ },
+ {
+ fieldName: 'refundStatus',
+ label: '閫�鍥炵姸鎬�',
+ component: 'Select',
+ componentProps: {
+ placeholder: '璇烽�夋嫨',
+ allowClear: true,
+ options: REFUND_STATUS_OPTIONS.map(({ label, value }) => ({
+ label,
+ value,
+ })),
+ },
+ },
+ ];
+}
+
+/** 琛ㄦ牸鍒� */
+export function useGridColumns(): VxeTableGridOptions['columns'] {
+ return [
+ { field: 'no', title: '淇濊瘉閲戝崟鍙�', minWidth: 150 },
+ { field: 'customerName', title: '瀹㈡埛锛堟嫑鏍囨柟锛�', minWidth: 160 },
+ { field: 'projectName', title: '椤圭洰鍚嶇О', minWidth: 180 },
+ { field: 'tenderNo', title: '鎷涙爣缂栧彿', minWidth: 140 },
+ {
+ field: 'saleOrderNo',
+ title: '鍏宠仈閿�鍞鍗�',
+ minWidth: 160,
+ slots: { default: 'saleOrderNo' },
+ },
+ {
+ field: 'saleOrderAmount',
+ title: '璁㈠崟閲戦',
+ minWidth: 120,
+ formatter: 'formatAmount2',
+ },
+ {
+ field: 'bondAmount',
+ title: '淇濊瘉閲戦噾棰�',
+ minWidth: 120,
+ formatter: 'formatAmount2',
+ },
+ { field: 'payDate', title: '缂寸撼鏃ユ湡', minWidth: 110 },
+ {
+ field: 'bidResult',
+ title: '涓爣缁撴灉',
+ minWidth: 100,
+ slots: { default: 'bidResult' },
+ },
+ {
+ field: 'refundStatus',
+ title: '閫�鍥炵姸鎬�',
+ minWidth: 110,
+ slots: { default: 'refundStatus' },
+ },
+ {
+ field: 'refundAmount',
+ title: '閫�鍥為噾棰�',
+ minWidth: 120,
+ formatter: 'formatAmount2',
+ },
+ { field: 'refundDate', title: '閫�鍥炴棩鏈�', minWidth: 110 },
+ { field: 'remark', title: '澶囨敞', minWidth: 150 },
+ {
+ title: '鎿嶄綔',
+ width: 130,
+ fixed: 'right',
+ slots: { default: 'actions' },
+ },
+ ];
+}
diff --git a/src/views/srm/bidBond/index.vue b/src/views/crm/bidBond/index.vue
similarity index 77%
rename from src/views/srm/bidBond/index.vue
rename to src/views/crm/bidBond/index.vue
index 49b9a04..cb48e66 100644
--- a/src/views/srm/bidBond/index.vue
+++ b/src/views/crm/bidBond/index.vue
@@ -1,19 +1,18 @@
<script lang="ts" setup>
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
-import type { SrmBidBondApi } from '#/api/srm/bidBond';
+import type { CrmBidBondApi } from '#/api/crm/bidBond';
import { Page, useVbenModal } from '@vben/common-ui';
import { message, Tag } from 'ant-design-vue';
import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
-import {
- deleteBidBond,
- getBidBondPage,
-} from '#/api/srm/bidBond';
+import { deleteBidBond, getBidBondPage } from '#/api/crm/bidBond';
import { $t } from '#/locales';
import {
+ getBidResultColor,
+ getBidResultLabel,
getRefundStatusColor,
getRefundStatusLabel,
useGridColumns,
@@ -21,7 +20,7 @@
} from './data';
import BidBondForm from './modules/form.vue';
-defineOptions({ name: 'SrmBidBond' });
+defineOptions({ name: 'CrmBidBond' });
const [FormModal, formModalApi] = useVbenModal({
connectedComponent: BidBondForm,
@@ -36,11 +35,11 @@
formModalApi.setData(null).open();
}
-function handleEdit(row: SrmBidBondApi.BidBond) {
+function handleEdit(row: CrmBidBondApi.BidBond) {
formModalApi.setData({ id: row.id }).open();
}
-async function handleDelete(row: SrmBidBondApi.BidBond) {
+async function handleDelete(row: CrmBidBondApi.BidBond) {
await deleteBidBond(row.id!);
message.success($t('ui.actionMessage.deleteSuccess', [row.no]));
handleRefresh();
@@ -67,7 +66,7 @@
},
rowConfig: { keyField: 'id', isHover: true },
toolbarConfig: { refresh: true, search: true },
- } as VxeTableGridOptions<SrmBidBondApi.BidBond>,
+ } as VxeTableGridOptions<CrmBidBondApi.BidBond>,
});
</script>
@@ -82,15 +81,19 @@
label: $t('ui.actionTitle.create', ['鎶曟爣淇濊瘉閲�']),
type: 'primary',
icon: ACTION_ICON.ADD,
- auth: ['srm:bid-bond:create'],
+ auth: ['crm:bid-bond:create'],
onClick: handleCreate,
},
]"
/>
</template>
- <template #won="{ row }">
- <Tag :color="row.won ? 'success' : 'default'">
- {{ row.won ? '涓爣' : '鏈腑鏍�' }}
+ <template #saleOrderNo="{ row }">
+ <span v-if="row.saleOrderNo">{{ row.saleOrderNo }}</span>
+ <span v-else class="text-gray-400">鏈叧鑱�</span>
+ </template>
+ <template #bidResult="{ row }">
+ <Tag :color="getBidResultColor(row.bidResult)">
+ {{ getBidResultLabel(row.bidResult) }}
</Tag>
</template>
<template #refundStatus="{ row }">
@@ -105,7 +108,7 @@
label: $t('common.edit'),
type: 'link',
icon: ACTION_ICON.EDIT,
- auth: ['srm:bid-bond:update'],
+ auth: ['crm:bid-bond:update'],
onClick: handleEdit.bind(null, row),
},
{
@@ -113,7 +116,7 @@
type: 'link',
danger: true,
icon: ACTION_ICON.DELETE,
- auth: ['srm:bid-bond:delete'],
+ auth: ['crm:bid-bond:delete'],
popConfirm: {
title: $t('ui.actionMessage.deleteConfirm', [row.no]),
confirm: handleDelete.bind(null, row),
diff --git a/src/views/crm/bidBond/modules/form.vue b/src/views/crm/bidBond/modules/form.vue
new file mode 100644
index 0000000..a68a07d
--- /dev/null
+++ b/src/views/crm/bidBond/modules/form.vue
@@ -0,0 +1,141 @@
+<script lang="ts" setup>
+import type { CrmBidBondApi } from '#/api/crm/bidBond';
+
+import { computed, ref } from 'vue';
+
+import { useVbenModal } from '@vben/common-ui';
+
+import { message } from 'ant-design-vue';
+
+import { useVbenForm } from '#/adapter/form';
+import {
+ createBidBond,
+ getBidBond,
+ updateBidBond,
+} from '#/api/crm/bidBond';
+import { $t } from '#/locales';
+
+import { useFormSchema } from '../data';
+
+const emit = defineEmits(['success']);
+const formData = ref<CrmBidBondApi.BidBond>();
+/** 鎵撳紑寮圭獥鍥炲~鏁版嵁鏃朵笉瑙﹀彂瀛楁鑱斿姩锛岄伩鍏嶅洖濉妸宸查�夐攢鍞鍗曟竻绌� */
+const loading = ref(false);
+
+const getTitle = computed(() => {
+ return formData.value?.id
+ ? $t('ui.actionTitle.edit', ['鎶曟爣淇濊瘉閲�'])
+ : $t('ui.actionTitle.create', ['鎶曟爣淇濊瘉閲�']);
+});
+
+const [Form, formApi] = useVbenForm({
+ commonConfig: {
+ componentProps: { class: 'w-full' },
+ labelWidth: 120,
+ },
+ wrapperClass: 'grid-cols-2',
+ layout: 'horizontal',
+ schema: useFormSchema(),
+ showDefaultActions: false,
+ handleValuesChange: async (values, changedFields) => {
+ if (loading.value) {
+ return;
+ }
+ // 鎹㈠鎴峰悗锛屽師閿�鍞鍗曚竴瀹氫笉鍐嶅睘浜庤瀹㈡埛锛屽繀椤绘竻绌洪噸閫�
+ if (changedFields.includes('customerId') && values.saleOrderId) {
+ await formApi.setValues({ saleOrderId: undefined });
+ return;
+ }
+ // 閫変簡閿�鍞鍗曡鏄庡凡涓爣锛涙竻绌鸿鍗曞垯閫�鍥炲緟寮�鏍�
+ if (changedFields.includes('saleOrderId')) {
+ if (values.saleOrderId && values.bidResult !== 1) {
+ await formApi.setValues({ bidResult: 1 });
+ return;
+ }
+ if (!values.saleOrderId && values.bidResult === 1) {
+ await formApi.setValues({ bidResult: 0 });
+ return;
+ }
+ }
+ // 鏈腑鏍囦笉鍙兘鏈夐攢鍞鍗曪紝娓呯┖璁㈠崟閬垮厤鍚庣鏍¢獙澶辫触
+ if (changedFields.includes('bidResult') && values.bidResult === 2) {
+ if (values.saleOrderId) {
+ await formApi.setValues({ saleOrderId: undefined });
+ }
+ if (values.refundStatus === 3) {
+ await formApi.setValues({ refundStatus: 0 });
+ }
+ return;
+ }
+ // 宸蹭腑鏍囦笉瀛樺湪閫�娆惧満鏅�
+ if (changedFields.includes('bidResult') && values.bidResult === 1) {
+ if (values.refundStatus !== 3) {
+ await formApi.setValues({
+ refundStatus: 3,
+ refundAmount: undefined,
+ refundDate: undefined,
+ });
+ }
+ }
+ },
+});
+
+const [Modal, modalApi] = useVbenModal({
+ async onConfirm() {
+ const { valid } = await formApi.validate();
+ if (!valid) {
+ return;
+ }
+ const data = (await formApi.getValues()) as CrmBidBondApi.BidBond;
+ // 鏈��鍥� / 鏃犻渶閫�鍥炰笉鍏佽甯﹂��娆鹃噾棰濅笌鏃ユ湡锛岄伩鍏嶅悗绔姸鎬佷笌閲戦鍐茬獊鏍¢獙
+ if (
+ data.refundStatus === 0 ||
+ data.refundStatus === 3 ||
+ data.refundStatus === undefined ||
+ data.refundStatus === null
+ ) {
+ data.refundAmount = undefined;
+ data.refundDate = undefined;
+ }
+ modalApi.lock();
+ try {
+ await (formData.value?.id
+ ? updateBidBond({ ...data, id: formData.value.id })
+ : createBidBond(data));
+ await modalApi.close();
+ emit('success');
+ message.success($t('ui.actionMessage.operationSuccess'));
+ } finally {
+ modalApi.unlock();
+ }
+ },
+ async onOpenChange(isOpen: boolean) {
+ if (!isOpen) {
+ formData.value = undefined;
+ return;
+ }
+ const data = modalApi.getData<{ id?: number }>();
+ if (!data?.id) {
+ formData.value = undefined;
+ return;
+ }
+ modalApi.lock();
+ loading.value = true;
+ try {
+ formData.value = await getBidBond(data.id);
+ await formApi.setValues(formData.value);
+ } finally {
+ loading.value = false;
+ modalApi.unlock();
+ }
+ },
+});
+
+defineExpose({ modalApi });
+</script>
+
+<template>
+ <Modal :title="getTitle" class="w-3/4">
+ <Form class="mx-4" />
+ </Modal>
+</template>
diff --git a/src/views/srm/bidBond/data.ts b/src/views/srm/bidBond/data.ts
deleted file mode 100644
index bc47f5e..0000000
--- a/src/views/srm/bidBond/data.ts
+++ /dev/null
@@ -1,255 +0,0 @@
-import type { VbenFormSchema } from '#/adapter/form';
-import type { VxeTableGridOptions } from '#/adapter/vxe-table';
-
-import { z } from '#/adapter/form';
-import { getPurchaseOrderPage } from '#/api/erp/purchase/order';
-import { getInquirySimpleList } from '#/api/srm/inquiry';
-import { getSupplierSimpleList } from '#/api/srm/supplier';
-
-export const REFUND_STATUS_OPTIONS = [
- { label: '鏈��鍥�', value: 0, color: 'warning' },
- { label: '閮ㄥ垎閫�鍥�', value: 1, color: 'processing' },
- { label: '宸查��鍥�', value: 2, color: 'success' },
- { label: '鏃犻渶閫�鍥�', value: 3, color: 'default' },
-];
-
-export function getRefundStatusLabel(status?: number) {
- return REFUND_STATUS_OPTIONS.find((item) => item.value === status)?.label ?? '-';
-}
-
-export function getRefundStatusColor(status?: number) {
- return REFUND_STATUS_OPTIONS.find((item) => item.value === status)?.color ?? 'default';
-}
-
-/** 閲囪喘璁㈠崟涓嬫媺鏁版嵁 */
-async function getPurchaseOrderOptions() {
- const result = await getPurchaseOrderPage({ pageNo: 1, pageSize: 200 });
- return result.list ?? [];
-}
-
-/** 鏂板/淇敼鎶曟爣淇濊瘉閲戠殑琛ㄥ崟 */
-export function useFormSchema(): VbenFormSchema[] {
- return [
- {
- fieldName: 'supplierId',
- label: '渚涘簲鍟�',
- component: 'ApiSelect',
- rules: 'required',
- componentProps: {
- placeholder: '璇烽�夋嫨渚涘簲鍟�',
- allowClear: true,
- showSearch: true,
- api: getSupplierSimpleList,
- labelField: 'name',
- valueField: 'id',
- },
- },
- {
- fieldName: 'projectName',
- label: '椤圭洰鍚嶇О',
- component: 'Input',
- componentProps: { placeholder: '閫夋嫨璇环鍗曞悗鑷姩甯﹀嚭锛屼篃鍙墜宸ュ~鍐�' },
- },
- {
- fieldName: 'inquiryId',
- label: '鍏宠仈璇环鍗�',
- component: 'ApiSelect',
- componentProps: {
- placeholder: '璇烽�夋嫨璇环鍗�',
- allowClear: true,
- showSearch: true,
- api: getInquirySimpleList,
- labelField: 'title',
- valueField: 'id',
- },
- },
- {
- fieldName: 'purchaseOrderId',
- label: '鍏宠仈閲囪喘璁㈠崟',
- component: 'ApiSelect',
- componentProps: {
- placeholder: '璇烽�夋嫨閲囪喘璁㈠崟',
- allowClear: true,
- showSearch: true,
- api: getPurchaseOrderOptions,
- labelField: 'no',
- valueField: 'id',
- },
- },
- {
- fieldName: 'bondAmount',
- label: '淇濊瘉閲戦噾棰�',
- component: 'InputNumber',
- rules: 'required',
- componentProps: {
- class: '!w-full',
- placeholder: '璇疯緭鍏ヤ繚璇侀噾閲戦',
- min: 0,
- precision: 2,
- },
- },
- {
- fieldName: 'payDate',
- label: '缂寸撼鏃ユ湡',
- component: 'DatePicker',
- componentProps: {
- class: 'w-full',
- placeholder: '璇烽�夋嫨缂寸撼鏃ユ湡',
- format: 'YYYY-MM-DD',
- valueFormat: 'YYYY-MM-DD',
- },
- },
- {
- fieldName: 'won',
- label: '鏄惁涓爣',
- component: 'Switch',
- componentProps: {
- checkedChildren: '涓爣',
- unCheckedChildren: '鏈腑鏍�',
- },
- rules: z.boolean().default(false),
- },
- {
- fieldName: 'refundStatus',
- label: '閫�鍥炵姸鎬�',
- component: 'Select',
- componentProps: {
- placeholder: '璇烽�夋嫨閫�鍥炵姸鎬�',
- options: REFUND_STATUS_OPTIONS.map(({ label, value }) => ({
- label,
- value,
- })),
- },
- },
- {
- fieldName: 'refundAmount',
- label: '閫�鍥為噾棰�',
- component: 'InputNumber',
- componentProps: {
- class: '!w-full',
- placeholder: '璇疯緭鍏ラ��鍥為噾棰�',
- min: 0,
- precision: 2,
- },
- },
- {
- fieldName: 'refundDate',
- label: '閫�鍥炴棩鏈�',
- component: 'DatePicker',
- componentProps: {
- class: 'w-full',
- placeholder: '璇烽�夋嫨閫�鍥炴棩鏈�',
- format: 'YYYY-MM-DD',
- valueFormat: 'YYYY-MM-DD',
- },
- },
- {
- fieldName: 'remark',
- label: '澶囨敞',
- component: 'Textarea',
- componentProps: { placeholder: '璇疯緭鍏ュ娉�', rows: 2 },
- formItemClass: 'col-span-2',
- },
- ];
-}
-
-/** 鎼滅储琛ㄥ崟 */
-export function useGridFormSchema(): VbenFormSchema[] {
- return [
- {
- fieldName: 'no',
- label: '淇濊瘉閲戝崟鍙�',
- component: 'Input',
- componentProps: { placeholder: '璇疯緭鍏ヤ繚璇侀噾鍗曞彿', allowClear: true },
- },
- {
- fieldName: 'supplierId',
- label: '渚涘簲鍟�',
- component: 'ApiSelect',
- componentProps: {
- placeholder: '璇烽�夋嫨渚涘簲鍟�',
- allowClear: true,
- showSearch: true,
- api: getSupplierSimpleList,
- labelField: 'name',
- valueField: 'id',
- },
- },
- {
- fieldName: 'projectName',
- label: '椤圭洰鍚嶇О',
- component: 'Input',
- componentProps: { placeholder: '璇疯緭鍏ラ」鐩悕绉�', allowClear: true },
- },
- {
- fieldName: 'won',
- label: '鏄惁涓爣',
- component: 'Select',
- componentProps: {
- placeholder: '璇烽�夋嫨',
- allowClear: true,
- options: [
- { label: '涓爣', value: true },
- { label: '鏈腑鏍�', value: false },
- ],
- },
- },
- {
- fieldName: 'refundStatus',
- label: '閫�鍥炵姸鎬�',
- component: 'Select',
- componentProps: {
- placeholder: '璇烽�夋嫨閫�鍥炵姸鎬�',
- allowClear: true,
- options: REFUND_STATUS_OPTIONS.map(({ label, value }) => ({
- label,
- value,
- })),
- },
- },
- ];
-}
-
-/** 琛ㄦ牸鍒� */
-export function useGridColumns(): VxeTableGridOptions['columns'] {
- return [
- { field: 'no', title: '淇濊瘉閲戝崟鍙�', minWidth: 150 },
- { field: 'supplierName', title: '渚涘簲鍟�', minWidth: 150 },
- { field: 'projectName', title: '椤圭洰鍚嶇О', minWidth: 180 },
- { field: 'inquiryNo', title: '鍏宠仈璇环鍗�', minWidth: 150 },
- { field: 'purchaseOrderNo', title: '鍏宠仈閲囪喘璁㈠崟', minWidth: 160 },
- {
- field: 'bondAmount',
- title: '淇濊瘉閲戦噾棰�',
- minWidth: 120,
- formatter: 'formatAmount2',
- },
- { field: 'payDate', title: '缂寸撼鏃ユ湡', minWidth: 110 },
- {
- field: 'won',
- title: '鏄惁涓爣',
- minWidth: 90,
- slots: { default: 'won' },
- },
- {
- field: 'refundStatus',
- title: '閫�鍥炵姸鎬�',
- minWidth: 110,
- slots: { default: 'refundStatus' },
- },
- {
- field: 'refundAmount',
- title: '閫�鍥為噾棰�',
- minWidth: 120,
- formatter: 'formatAmount2',
- },
- { field: 'refundDate', title: '閫�鍥炴棩鏈�', minWidth: 110 },
- { field: 'remark', title: '澶囨敞', minWidth: 150 },
- {
- title: '鎿嶄綔',
- width: 130,
- fixed: 'right',
- slots: { default: 'actions' },
- },
- ];
-}
diff --git a/src/views/srm/bidBond/modules/form.vue b/src/views/srm/bidBond/modules/form.vue
deleted file mode 100644
index a0c39ab..0000000
--- a/src/views/srm/bidBond/modules/form.vue
+++ /dev/null
@@ -1,116 +0,0 @@
-<script lang="ts" setup>
-import type { ErpPurchaseOrderApi } from '#/api/erp/purchase/order';
-import type { SrmBidBondApi } from '#/api/srm/bidBond';
-
-import { computed, ref } from 'vue';
-
-import { useVbenModal } from '@vben/common-ui';
-
-import { message } from 'ant-design-vue';
-
-import { useVbenForm } from '#/adapter/form';
-import { getPurchaseOrder } from '#/api/erp/purchase/order';
-import {
- createBidBond,
- getBidBond,
- updateBidBond,
-} from '#/api/srm/bidBond';
-import { getInquiry } from '#/api/srm/inquiry';
-import { $t } from '#/locales';
-
-import { useFormSchema } from '../data';
-
-const emit = defineEmits(['success']);
-const formData = ref<SrmBidBondApi.BidBond>();
-const getTitle = computed(() => {
- return formData.value?.id
- ? $t('ui.actionTitle.edit', ['鎶曟爣淇濊瘉閲�'])
- : $t('ui.actionTitle.create', ['鎶曟爣淇濊瘉閲�']);
-});
-
-const [Form, formApi] = useVbenForm({
- commonConfig: {
- componentProps: { class: 'w-full' },
- labelWidth: 110,
- },
- wrapperClass: 'grid-cols-2',
- layout: 'horizontal',
- schema: useFormSchema(),
- showDefaultActions: false,
- handleValuesChange: async (values, changedFields) => {
- if (changedFields.includes('inquiryId') && values.inquiryId) {
- try {
- const inquiry = await getInquiry(values.inquiryId);
- await formApi.setValues({
- projectName: inquiry.title,
- });
- } catch {
- // 璇环鍗曡鍙栧け璐ユ椂涓嶉樆鏂墜宸ュ綍鍏�
- }
- }
- if (changedFields.includes('purchaseOrderId') && values.purchaseOrderId) {
- try {
- const order: ErpPurchaseOrderApi.PurchaseOrder =
- await getPurchaseOrder(values.purchaseOrderId);
- await formApi.setValues({
- supplierId: order.supplierId,
- projectName: values.projectName || order.no,
- won: true,
- });
- } catch {
- // 閲囪喘璁㈠崟璇诲彇澶辫触鏃朵笉闃绘柇鎵嬪伐褰曞叆
- }
- }
- },
-});
-
-const [Modal, modalApi] = useVbenModal({
- async onConfirm() {
- const { valid } = await formApi.validate();
- if (!valid) {
- return;
- }
- const data = (await formApi.getValues()) as SrmBidBondApi.BidBond;
- if (data.won && data.refundStatus === undefined) {
- data.refundStatus = 3;
- }
- modalApi.lock();
- try {
- await (formData.value?.id
- ? updateBidBond({ ...data, id: formData.value.id })
- : createBidBond(data));
- await modalApi.close();
- emit('success');
- message.success($t('ui.actionMessage.operationSuccess'));
- } finally {
- modalApi.unlock();
- }
- },
- async onOpenChange(isOpen: boolean) {
- if (!isOpen) {
- formData.value = undefined;
- return;
- }
- const data = modalApi.getData<{ id?: number }>();
- if (!data?.id) {
- formData.value = undefined;
- return;
- }
- modalApi.lock();
- try {
- formData.value = await getBidBond(data.id);
- await formApi.setValues(formData.value);
- } finally {
- modalApi.unlock();
- }
- },
-});
-
-defineExpose({ modalApi });
-</script>
-
-<template>
- <Modal :title="getTitle" class="w-3/4">
- <Form class="mx-4" />
- </Modal>
-</template>
--
Gitblit v1.9.3