From f18442be2efd1fc92c7b0bee088fc06c8f609abc Mon Sep 17 00:00:00 2001 From: zlwu <704541015@qq.com> Date: Sun, 30 Aug 2026 10:58:14 +0800 Subject: [PATCH] feat(web-admin): make plan stop contract selector single-choice Co-authored-by: Cursor --- .../pl-plan-contract-multi-select/index.vue | 35 ++++++++++++------- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/web-admin/src/components/business/pl-plan-contract-multi-select/index.vue b/web-admin/src/components/business/pl-plan-contract-multi-select/index.vue index 146b7c609..a27a1c72e 100644 --- a/web-admin/src/components/business/pl-plan-contract-multi-select/index.vue +++ b/web-admin/src/components/business/pl-plan-contract-multi-select/index.vue @@ -132,7 +132,10 @@

暂无产品明细

-

+

{{ readonly ? '暂无关联合同' : '暂未选择合同' }}

@@ -141,10 +144,8 @@ v-model:visible="selectorVisible" :customer-id="customerId" :selectable-statuses="selectableStatuses" - multiple - :selected-ids="selectedIds" hide-amount - @confirm-multiple="handleConfirmMultiple" + @confirm="handleConfirmSingle" /> @@ -159,6 +160,7 @@ import { fetchProductDetail } from '@/api/crm/product' import ContractSelector from '@/components/business/contract-selector/index.vue' import DictTag from '@/components/DictTag/index.vue' import { applyAliasDisplayMeta, formatBrandConstraintLabel } from '@/utils/crm-product-brand' +import { collectContractProductIds } from '@/utils/pl-plan-contract-product' const ContractDetailDialog = defineAsyncComponent( () => import('@/views/crm/contract/components/ContractDetailDialog.vue') @@ -242,14 +244,19 @@ const selectedIds = computed(() => const triggerDisabled = computed(() => props.disabled || !props.customerId) -const hintWarn = computed( - () => !!props.customerId && props.required && !selectedIds.value.length -) +const hintWarn = computed(() => { + if (!props.customerId) return false + if (selectedIds.value.length > 1) return true + return !!props.required && !selectedIds.value.length +}) const hintText = computed(() => { if (!props.customerId) return '请先选择客户' - if (hintWarn.value) return '请至少选择一份合同' - if (selectedIds.value.length) return `已选 ${selectedIds.value.length} 份` + if (selectedIds.value.length > 1) { + return '只能保留一份合同,请移除多余合同后再保存' + } + if (hintWarn.value) return '请选择合同' + if (selectedIds.value.length) return '已选 1 份' return '' }) @@ -324,9 +331,9 @@ async function loadDetails(ids: string[]) { } } -async function handleConfirmMultiple(contracts: ContractVO[]) { - const enriched = await Promise.all((contracts || []).map(item => enrichContractProducts(item))) - detailRows.value = enriched +async function handleConfirmSingle(contract: ContractVO) { + const enriched = await enrichContractProducts(contract) + detailRows.value = [enriched] emitLinksFromDetails(detailRows.value) } @@ -369,7 +376,9 @@ async function handleViewContract(contractId: string) { } defineExpose({ - openSelector + openSelector, + getContractProductIds: () => + collectContractProductIds(detailRows.value.flatMap(row => row.products || [])) }) watch(