From dcde4b33fa739b09486c39faade9ed19b29a6d7a Mon Sep 17 00:00:00 2001
From: 云 <2163098428@qq.com>
Date: 星期一, 03 八月 2026 14:58:35 +0800
Subject: [PATCH] feat(srm): 优化供应商选择组件功能
---
src/api/srm/supplier/index.ts | 2
src/views/srm/supplier/components/select.vue | 4 +
src/views/srm/enums.ts | 31 ++++++++-------
src/views/srm/supplier/components/select-dialog.vue | 7 +++
src/views/srm/supplierApply/data.ts | 5 ++
src/views/srm/tender/detail.vue | 44 +++++++++++++++++++++-
6 files changed, 73 insertions(+), 20 deletions(-)
diff --git a/src/api/srm/supplier/index.ts b/src/api/srm/supplier/index.ts
index 27da1c2..60b176a 100644
--- a/src/api/srm/supplier/index.ts
+++ b/src/api/srm/supplier/index.ts
@@ -7,7 +7,7 @@
id?: number;
code: string;
name: string;
- type: number;
+ type: string;
status: number;
contactName?: string;
contactMobile?: string;
diff --git a/src/views/srm/enums.ts b/src/views/srm/enums.ts
index 71712b5..4d014f1 100644
--- a/src/views/srm/enums.ts
+++ b/src/views/srm/enums.ts
@@ -36,29 +36,30 @@
labels: { 0: '寮�鍚�', 1: '鍏抽棴' },
};
-/** 渚涘簲鍟嗙被鍨� 鈥� 瀵归綈 SupplierTypeEnum (1=鐢熶骇鍨� 2=璐告槗鍨� 3=鏈嶅姟鍨� 4=鍏朵粬) */
+/** 渚涘簲鍟嗙被鍨� 鈥� 瀵归綈 SupplierTypeEnum (1=鐢熶骇鍨� 2=璐告槗鍨� 3=鏈嶅姟鍨� 4=鍏朵粬)
+ * 娉ㄦ剰锛氬悗绔� DO/RespVO 涓� type 涓� String 绫诲瀷锛屾澶勯�夐」鍊肩粺涓�鐢ㄥ瓧绗︿覆涓庡悗绔榻� */
export const SUPPLIER_TYPE = {
- PRODUCTION: 1,
- TRADING: 2,
- SERVICE: 3,
- OTHER: 4,
+ PRODUCTION: '1',
+ TRADING: '2',
+ SERVICE: '3',
+ OTHER: '4',
} as const;
export const SUPPLIER_TYPE_OPTIONS: EnumOption[] = [
- { label: '鐢熶骇鍨�', value: 1 },
- { label: '璐告槗鍨�', value: 2 },
- { label: '鏈嶅姟鍨�', value: 3 },
- { label: '鍏朵粬', value: 4 },
+ { label: '鐢熶骇鍨�', value: '1' },
+ { label: '璐告槗鍨�', value: '2' },
+ { label: '鏈嶅姟鍨�', value: '3' },
+ { label: '鍏朵粬', value: '4' },
];
-export const SUPPLIER_TYPE_CELLTAG: { data: CellTagItem[]; labels: Record<number, string> } = {
+export const SUPPLIER_TYPE_CELLTAG: { data: CellTagItem[]; labels: Record<string, string> } = {
data: [
- { value: 1, color: 'blue' },
- { value: 2, color: 'green' },
- { value: 3, color: 'orange' },
- { value: 4, color: 'default' },
+ { value: '1', color: 'blue' },
+ { value: '2', color: 'green' },
+ { value: '3', color: 'orange' },
+ { value: '4', color: 'default' },
],
- labels: { 1: '鐢熶骇鍨�', 2: '璐告槗鍨�', 3: '鏈嶅姟鍨�', 4: '鍏朵粬' },
+ labels: { '1': '鐢熶骇鍨�', '2': '璐告槗鍨�', '3': '鏈嶅姟鍨�', '4': '鍏朵粬' },
};
// ========== 鍑嗗叆鐢宠 鈥� 瀵归綈 SupplierApplyStatusEnum (0/10/20/30/40/50) ==========
diff --git a/src/views/srm/supplier/components/select-dialog.vue b/src/views/srm/supplier/components/select-dialog.vue
index 1f3c614..431b1cf 100644
--- a/src/views/srm/supplier/components/select-dialog.vue
+++ b/src/views/srm/supplier/components/select-dialog.vue
@@ -20,6 +20,7 @@
const open = ref(false);
const multiple = ref(true);
const approvalFilter = ref(true);
+const excludeApproved = ref(false);
const selectedRows = ref<SrmSupplierApi.SupplierVO[]>([]);
const preSelectedIds = ref<number[]>([]);
@@ -178,6 +179,9 @@
if (approvalFilter.value) {
params.approved = true;
}
+ if (excludeApproved.value) {
+ params.excludeApproved = true;
+ }
return await getSupplierPage(params);
},
},
@@ -211,11 +215,12 @@
async function openModal(
selectedIds?: number[],
- options?: { multiple?: boolean; approvalFilter?: boolean },
+ options?: { multiple?: boolean; approvalFilter?: boolean; excludeApproved?: boolean },
) {
open.value = true;
multiple.value = options?.multiple ?? true;
approvalFilter.value = options?.approvalFilter ?? true;
+ excludeApproved.value = options?.excludeApproved ?? false;
preSelectedIds.value = selectedIds || [];
await nextTick();
gridApi.setGridOptions({
diff --git a/src/views/srm/supplier/components/select.vue b/src/views/srm/supplier/components/select.vue
index 0da35fd..25f7dd3 100644
--- a/src/views/srm/supplier/components/select.vue
+++ b/src/views/srm/supplier/components/select.vue
@@ -16,6 +16,7 @@
allowClear?: boolean;
approvalFilter?: boolean;
disabled?: boolean;
+ excludeApproved?: boolean;
modelValue?: number;
placeholder?: string;
supplierName?: string;
@@ -24,6 +25,7 @@
allowClear: true,
approvalFilter: true,
disabled: false,
+ excludeApproved: false,
modelValue: undefined,
placeholder: '璇烽�夋嫨渚涘簲鍟�',
supplierName: undefined,
@@ -66,7 +68,7 @@
const selectedIds = (
props.modelValue === null ? [] : [props.modelValue]
) as number[];
- dialogRef.value?.open(selectedIds, { multiple: false, approvalFilter: props.approvalFilter });
+ dialogRef.value?.open(selectedIds, { multiple: false, approvalFilter: props.approvalFilter, excludeApproved: props.excludeApproved });
}
function handleSelected(rows: SrmSupplierApi.SupplierVO[]) {
diff --git a/src/views/srm/supplierApply/data.ts b/src/views/srm/supplierApply/data.ts
index 0e172a0..6b99c4c 100644
--- a/src/views/srm/supplierApply/data.ts
+++ b/src/views/srm/supplierApply/data.ts
@@ -27,6 +27,7 @@
component: markRaw(SrmSupplierSelect),
componentProps: {
approvalFilter: false,
+ excludeApproved: true,
placeholder: '璇烽�夋嫨SRM渚涘簲鍟嗭紙鎴栫洿鎺ュ~鍐欎緵搴斿晢鍚嶇О锛�',
onChange: async (supplier?: SrmSupplierApi.SupplierVO) => {
if (!supplier || !formApi) return;
@@ -37,6 +38,9 @@
contactEmail: supplier.contactEmail || '',
taxNo: supplier.taxNo || '',
address: supplier.address || '',
+ bankName: supplier.bankName || '',
+ bankAccount: supplier.bankAccount || '',
+ remark: supplier.remark || '',
});
},
},
@@ -44,6 +48,7 @@
triggerFields: ['supplierName'],
componentProps: (values) => ({
approvalFilter: false,
+ excludeApproved: true,
placeholder: '璇烽�夋嫨SRM渚涘簲鍟嗭紙鎴栫洿鎺ュ~鍐欎緵搴斿晢鍚嶇О锛�',
supplierName: values.supplierName as string,
}),
diff --git a/src/views/srm/tender/detail.vue b/src/views/srm/tender/detail.vue
index 772d2eb..7de94be 100644
--- a/src/views/srm/tender/detail.vue
+++ b/src/views/srm/tender/detail.vue
@@ -6,7 +6,7 @@
import { Page } from '@vben/common-ui';
-import { message } from 'ant-design-vue';
+import { message, Modal } from 'ant-design-vue';
import { IconifyIcon } from '@vben/icons';
import {
@@ -63,6 +63,25 @@
const materialLoading = ref(false);
const materialFormVisible = ref(false);
const materialForm = ref<SrmTenderApi.TenderMaterialVO>({ tenderProjectId: projectId });
+
+// 宸叉坊鍔犵殑鐗╂枡浜у搧ID闆嗗悎锛岄伩鍏嶉噸澶嶆坊鍔�
+const addedProductIds = computed(() => {
+ const ids = new Set(
+ materialList.value
+ .filter((m) => m.productId !== undefined)
+ .map((m) => m.productId!),
+ );
+ // 缂栬緫鏃跺厑璁镐繚鐣欏綋鍓嶇墿鏂欑殑 productId
+ if (materialForm.value.id && materialForm.value.productId) {
+ ids.delete(materialForm.value.productId);
+ }
+ return ids;
+});
+
+// 鐗╂枡涓嬫媺鍙�夊垪琛紙鎺掗櫎宸叉坊鍔犵殑锛�
+const availableMdmItems = computed(() =>
+ mdmItemList.value.filter((item) => !addedProductIds.value.has(item.id!)),
+);
async function loadProject() {
project.value = await getTenderProject(projectId);
@@ -150,6 +169,27 @@
try { quoteList.value = await getQuoteList(bidId); } finally { quoteLoading.value = false; }
}
async function handleSaveQuote() {
+ // 鏍¢獙锛氭姤浠烽噾棰濅笌鎶曟爣閲戦涓�鑷存��
+ const bid = bidList.value.find((b) => b.id === quoteForm.value.bidId);
+ if (bid?.bidTotalAmount != null) {
+ const otherQuotesTotal = quoteList.value
+ .filter((q) => q.id !== quoteForm.value.id)
+ .reduce((sum, q) => sum + (q.quotePrice ?? 0), 0);
+ const newTotal = otherQuotesTotal + (quoteForm.value.quotePrice ?? 0);
+ if (newTotal !== bid.bidTotalAmount) {
+ await new Promise<void>((resolve, reject) => {
+ Modal.confirm({
+ title: '閲戦涓嶄竴鑷存彁绀�',
+ content: `鎶ヤ环鎬婚噾棰濓紙${newTotal.toLocaleString()}锛変笌鎶曟爣閲戦锛�${bid.bidTotalAmount!.toLocaleString()}锛変笉涓�鑷达紝鏄惁缁х画鎻愪氦锛焋,
+ okText: '缁х画鎻愪氦',
+ cancelText: '鍙栨秷',
+ onOk: () => { resolve(); },
+ onCancel: () => { reject(new Error('cancel')); },
+ });
+ });
+ }
+ }
+
if (quoteForm.value.id) {
await updateQuote(quoteForm.value);
} else {
@@ -685,7 +725,7 @@
<a-form layout="vertical" class="mt-4">
<a-form-item label="MDM鐗╂枡" required>
<a-select v-model:value="materialForm.productId" show-search placeholder="鎼滅储骞堕�夋嫨MDM鐗╂枡" :filter-option="filterOption" option-label-prop="label" @change="onMaterialSelect">
- <a-select-option v-for="item in mdmItemList" :key="item.id" :value="item.id" :label="`${item.code} ${item.name}`">
+ <a-select-option v-for="item in availableMdmItems" :key="item.id" :value="item.id" :label="`${item.code} ${item.name}`">
<div class="flex flex-col">
<span class="font-medium">{{ item.code }}</span>
<span class="text-xs text-gray-400">{{ item.name }}{{ item.specification ? ` 路 ${item.specification}` : '' }}</span>
--
Gitblit v1.9.3