| | |
| | | createBidOpen, getBidOpen, |
| | | getEvaluationList, createBidEvaluation, updateBidEvaluation, calculateRanking, |
| | | createAward, deleteAward, getAward, getAwardByProject, approveAward, generatePurchaseOrder, |
| | | confirmTenderProject, |
| | | } from '#/api/srm/tender'; |
| | | import { getSupplierSimpleList } from '#/api/srm/supplier'; |
| | | import { getItemSimpleList } from '#/api/mdm/item'; |
| | |
| | | AWARD_STATUS, |
| | | AWARD_STATUS_MAP, |
| | | getLabel, |
| | | BIDDING_MODE, |
| | | } from '../enums'; |
| | | |
| | | defineOptions({ name: 'SrmTenderDetail' }); |
| | |
| | | const bidList = ref<SrmTenderApi.TenderBidVO[]>([]); |
| | | const bidLoading = ref(false); |
| | | const bidFormVisible = ref(false); |
| | | const bidForm = ref<SrmTenderApi.TenderBidVO>({ tenderProjectId: projectId, supplierId: 0, bidNo: '' }); |
| | | const bidForm = ref<SrmTenderApi.TenderBidVO>({ tenderProjectId: projectId, supplierId: undefined!, bidNo: '' }); |
| | | |
| | | async function loadBids() { |
| | | bidLoading.value = true; |
| | |
| | | const quoteList = ref<SrmTenderApi.QuoteVO[]>([]); |
| | | const quoteLoading = ref(false); |
| | | const quoteFormVisible = ref(false); |
| | | const quoteForm = ref<SrmTenderApi.QuoteVO>({ bidId: 0, tenderMaterialId: 0 }); |
| | | const quoteForm = ref<SrmTenderApi.QuoteVO>({ bidId: undefined!, tenderMaterialId: undefined! }); |
| | | const selectedBidId = ref<number>(); |
| | | |
| | | const availableMaterials = computed(() => { |
| | |
| | | loadQuotes(selectedBidId.value); |
| | | } |
| | | function handleAddQuote() { |
| | | quoteForm.value = { bidId: selectedBidId.value!, tenderMaterialId: 0 }; |
| | | quoteForm.value = { bidId: selectedBidId.value!, tenderMaterialId: undefined! }; |
| | | quoteFormVisible.value = true; |
| | | } |
| | | function handleEditQuote(row: SrmTenderApi.QuoteVO) { |
| | |
| | | const evaluationList = ref<SrmTenderApi.BidEvaluationVO[]>([]); |
| | | const evalLoading = ref(false); |
| | | const evalFormVisible = ref(false); |
| | | const evalForm = ref<SrmTenderApi.BidEvaluationVO>({ tenderProjectId: projectId, supplierId: 0, bidId: 0 }); |
| | | const evalForm = ref<SrmTenderApi.BidEvaluationVO>({ tenderProjectId: projectId, supplierId: undefined!, bidId: undefined! }); |
| | | |
| | | async function loadEvaluations() { |
| | | evalLoading.value = true; |
| | |
| | | // ========== 定标 ========== |
| | | const award = ref<SrmTenderApi.BidAwardVO>(); |
| | | const awardFormVisible = ref(false); |
| | | const awardForm = ref<SrmTenderApi.BidAwardVO>({ tenderProjectId: projectId, supplierId: 0, bidId: 0, awardNo: '' }); |
| | | const awardForm = ref<SrmTenderApi.BidAwardVO>({ tenderProjectId: projectId, supplierId: undefined!, bidId: undefined!, awardNo: '' }); |
| | | |
| | | /** 已投标且未撤标的供应商列表(从投标记录中提取) */ |
| | | const bidSuppliers = computed(() => { |
| | | const activeBids = bidList.value.filter((b) => b.bidStatus !== BID_STATUS.WITHDRAWN); |
| | | const seen = new Map<number, { id: number; name: string }>(); |
| | | activeBids.forEach((b) => { |
| | | if (b.supplierId && !seen.has(b.supplierId)) { |
| | | seen.set(b.supplierId, { id: b.supplierId, name: b.supplierName || '' }); |
| | | } |
| | | }); |
| | | return [...seen.values()]; |
| | | }); |
| | | |
| | | /** 可选投标记录:排除撤标,且如果选了供应商则只显示该供应商的投标 */ |
| | | const activeBids = computed(() => { |
| | | return bidList.value.filter((b) => { |
| | | if (b.bidStatus === BID_STATUS.WITHDRAWN) return false; |
| | | if (awardForm.value.supplierId && b.supplierId !== awardForm.value.supplierId) return false; |
| | | return true; |
| | | }); |
| | | }); |
| | | |
| | | /** 选择供应商时清空已选的投标 */ |
| | | function onAwardSupplierChange() { |
| | | awardForm.value.bidId = undefined!; |
| | | } |
| | | |
| | | /** 选择投标时自动带入该投标的报价金额 */ |
| | | function onAwardBidChange(bidId: number) { |
| | | const bid = bidList.value.find((b) => b.id === bidId); |
| | | if (bid?.bidTotalAmount != null) { |
| | | awardForm.value.awardAmount = bid.bidTotalAmount; |
| | | } |
| | | } |
| | | |
| | | async function loadAward() { |
| | | try { award.value = await getAwardByProject(projectId); } catch { award.value = undefined; } |
| | |
| | | loadProject(); |
| | | } |
| | | |
| | | // ========== 简易模式:确认中标 ========== |
| | | const confirmBidId = ref<number>(); |
| | | const confirmModalVisible = ref(false); |
| | | |
| | | async function handleConfirmBidAsWinner(bidId: number) { |
| | | await confirmTenderProject({ id: projectId, bidId }); |
| | | message.success('确认中标成功,采购订单已自动生成'); |
| | | loadProject(); |
| | | loadBids(); |
| | | loadAward(); |
| | | } |
| | | |
| | | function openSimpleConfirmModal() { |
| | | confirmBidId.value = undefined; |
| | | confirmModalVisible.value = true; |
| | | } |
| | | |
| | | async function handleSimpleConfirm() { |
| | | if (!confirmBidId.value) { |
| | | message.warning('请选择中标的投标记录'); |
| | | return; |
| | | } |
| | | await confirmTenderProject({ id: projectId, bidId: confirmBidId.value }); |
| | | message.success('确认中标成功,采购订单已自动生成'); |
| | | confirmModalVisible.value = false; |
| | | loadProject(); |
| | | loadBids(); |
| | | loadAward(); |
| | | } |
| | | |
| | | // ========== 初始化 ========== |
| | | loadProject(); |
| | | loadMaterials(); |
| | |
| | | const statusLabel = computed(() => getLabel(TENDER_STATUS_CELLTAG.labels, project.value?.tenderStatus)); |
| | | const statusColor = computed(() => TENDER_STATUS_COLORS[project.value?.tenderStatus!] || 'default'); |
| | | const typeLabel = computed(() => getLabel(TENDER_TYPE_CELLTAG.labels, project.value?.tenderType)); |
| | | const isAwarded = computed(() => project.value?.tenderStatus === TENDER_STATUS.AWARDED); |
| | | const isDraft = computed(() => project.value?.tenderStatus === TENDER_STATUS.DRAFT); |
| | | const isPublished = computed(() => project.value?.tenderStatus === TENDER_STATUS.PUBLISHED); |
| | | const isPublishedOrBidding = computed(() => { |
| | | const s = project.value?.tenderStatus; |
| | | return s === TENDER_STATUS.PUBLISHED || s === TENDER_STATUS.BIDDING; |
| | | }); |
| | | const isBiddingOrEvaluating = computed(() => { |
| | | const s = project.value?.tenderStatus; |
| | | return s === TENDER_STATUS.BIDDING || s === TENDER_STATUS.EVALUATING; |
| | | }); |
| | | const isEvaluating = computed(() => project.value?.tenderStatus === TENDER_STATUS.EVALUATING); |
| | | const canDeleteAward = computed(() => award.value?.awardStatus === AWARD_STATUS.PENDING_APPROVAL); |
| | | const canApproveAward = computed(() => award.value?.awardStatus === AWARD_STATUS.PENDING_APPROVAL); |
| | | const canGeneratePO = computed(() => award.value?.awardStatus === AWARD_STATUS.AWARDED); |
| | | |
| | | const stepItems = [ |
| | | { title: '草稿', status: TENDER_STATUS.DRAFT }, |
| | | { title: '发布', status: TENDER_STATUS.PUBLISHED }, |
| | | { title: '投标中', status: TENDER_STATUS.BIDDING }, |
| | | { title: '评标中', status: TENDER_STATUS.EVALUATING }, |
| | | { title: '已定标', status: TENDER_STATUS.AWARDED }, |
| | | ]; |
| | | // 简易模式 |
| | | const isSimpleMode = computed(() => project.value?.biddingMode === BIDDING_MODE.SIMPLE); |
| | | const isPriceComparing = computed(() => project.value?.tenderStatus === TENDER_STATUS.PRICE_COMPARING); |
| | | |
| | | const stepItems = computed(() => { |
| | | if (isSimpleMode.value) { |
| | | return [ |
| | | { title: '草稿', status: TENDER_STATUS.DRAFT }, |
| | | { title: '比价中', status: TENDER_STATUS.PRICE_COMPARING }, |
| | | { title: '已确认', status: TENDER_STATUS.CONFIRMED }, |
| | | ]; |
| | | } |
| | | return [ |
| | | { title: '草稿', status: TENDER_STATUS.DRAFT }, |
| | | { title: '发布', status: TENDER_STATUS.PUBLISHED }, |
| | | { title: '投标中', status: TENDER_STATUS.BIDDING }, |
| | | { title: '评标中', status: TENDER_STATUS.EVALUATING }, |
| | | { title: '已定标', status: TENDER_STATUS.AWARDED }, |
| | | ]; |
| | | }); |
| | | const currentStep = computed(() => { |
| | | const s = project.value?.tenderStatus ?? 0; |
| | | if (s === TENDER_STATUS.CLOSED) return 4; |
| | | const idx = stepItems.findIndex((item) => item.status >= s); |
| | | const items = stepItems.value; |
| | | if (s === TENDER_STATUS.CLOSED) return items.length - 1; |
| | | const idx = items.findIndex((item) => item.status >= s); |
| | | return idx === -1 ? 0 : idx; |
| | | }); |
| | | const stepStatus = computed(() => { |
| | | const s = project.value?.tenderStatus; |
| | | if (s === TENDER_STATUS.CLOSED) return 'error'; |
| | | if (s === TENDER_STATUS.AWARDED) return 'finish'; |
| | | if (s === TENDER_STATUS.AWARDED || s === TENDER_STATUS.CONFIRMED) return 'finish'; |
| | | return 'process'; |
| | | }); |
| | | |
| | |
| | | { title: '投标金额', dataIndex: 'bidTotalAmount', width: 120 }, |
| | | { title: '投标时间', dataIndex: 'bidTime', width: 160 }, |
| | | { title: '状态', dataIndex: 'bidStatus', width: 100, customRender: ({ text }: any) => BID_STATUS_MAP[text] || text }, |
| | | { title: '操作', key: 'actions', width: 180 }, |
| | | { title: '操作', key: 'actions', width: 240 }, |
| | | ]; |
| | | |
| | | const quoteColumns = [ |
| | |
| | | <span class="text-gray-400 text-xs">{{ project.tenderNo }}</span> |
| | | <a-tag :color="statusColor">{{ statusLabel }}</a-tag> |
| | | <a-tag color="blue">{{ typeLabel }}</a-tag> |
| | | <a-tag v-if="isSimpleMode" color="purple">简易版</a-tag> |
| | | <div class="flex-1" /> |
| | | <a-button |
| | | v-if="isPriceComparing" |
| | | type="primary" |
| | | size="small" |
| | | @click="openSimpleConfirmModal" |
| | | > |
| | | 确认中标 |
| | | </a-button> |
| | | <a-button size="small" @click="loadProject(); loadMaterials(); loadBids(); loadEvaluations(); loadAward();"> |
| | | <template #icon><IconifyIcon icon="ant-design:reload-outlined" /></template> |
| | | 刷新 |
| | |
| | | <a-space> |
| | | <span class="text-xs text-gray-400">共 <b class="text-gray-600">{{ materialList.length }}</b> 项,预估总金额 <b class="text-blue-500">{{ materialTotalAmount.toLocaleString() }}</b> 元</span> |
| | | </a-space> |
| | | <a-button v-if="!isAwarded" type="primary" size="small" @click="handleAddMaterial"> |
| | | <a-button v-if="isDraft" type="primary" size="small" @click="handleAddMaterial"> |
| | | <template #icon><IconifyIcon icon="ant-design:plus-outlined" /></template> |
| | | 添加物料 |
| | | </a-button> |
| | |
| | | {{ record.estimatedPrice ? record.estimatedPrice.toLocaleString() : '-' }} |
| | | </template> |
| | | <template v-if="column.key === 'actions'"> |
| | | <a-space v-if="!isAwarded"> |
| | | <a-space v-if="isDraft"> |
| | | <a-button size="small" type="link" @click="handleEditMaterial(record)"><IconifyIcon icon="ant-design:edit-outlined" />编辑</a-button> |
| | | <a-popconfirm title="确认删除该物料?" @confirm="handleDeleteMaterial(record.id)"> |
| | | <a-button size="small" type="link" danger><IconifyIcon icon="ant-design:delete-outlined" />删除</a-button> |
| | |
| | | </template> |
| | | <div class="flex items-center justify-between mb-3"> |
| | | <span class="text-xs text-gray-400">共 <b class="text-gray-600">{{ bidCount }}</b> 个投标</span> |
| | | <a-button v-if="!isAwarded" type="primary" size="small" @click="bidForm = { tenderProjectId: projectId, supplierId: 0, bidNo: '' }; bidFormVisible = true"> |
| | | <a-button v-if="isPublishedOrBidding || isDraft || isPriceComparing" type="primary" size="small" @click="bidForm = { tenderProjectId: projectId, supplierId: undefined!, bidNo: '' }; bidFormVisible = true"> |
| | | <template #icon><IconifyIcon icon="ant-design:plus-outlined" /></template> |
| | | 新增投标 |
| | | </a-button> |
| | |
| | | <template v-if="column.key === 'actions'"> |
| | | <a-space> |
| | | <a-button size="small" type="link" @click="loadQuotes(record.id); activeTab = 'quote'"><IconifyIcon icon="ant-design:dollar-outlined" />报价</a-button> |
| | | <a-popconfirm v-if="!isAwarded && record.bidStatus === BID_STATUS.REGISTERED" title="确认撤标?" @confirm="handleWithdrawBid(record.id)"> |
| | | <a-popconfirm v-if="isPriceComparing && record.bidStatus !== BID_STATUS.WITHDRAWN" title="确认选择该投标为中标?将自动生成采购订单。" ok-text="确认中标" cancel-text="取消" @confirm="handleConfirmBidAsWinner(record.id)"> |
| | | <a-button size="small" type="link" style="color: #52c41a;"><IconifyIcon icon="ant-design:check-circle-outlined" />确认中标</a-button> |
| | | </a-popconfirm> |
| | | <a-popconfirm v-if="(isPublishedOrBidding || isDraft || isPriceComparing) && record.bidStatus === BID_STATUS.REGISTERED" title="确认撤标?" @confirm="handleWithdrawBid(record.id)"> |
| | | <a-button size="small" type="link" danger><IconifyIcon icon="ant-design:close-circle-outlined" />撤标</a-button> |
| | | </a-popconfirm> |
| | | </a-space> |
| | |
| | | <a-button size="small" type="link" class="ml-auto" @click="activeTab = 'bid'">切换投标</a-button> |
| | | </div> |
| | | <div class="text-right mb-3"> |
| | | <a-button v-if="!isAwarded && selectedBid.bidStatus !== BID_STATUS.WITHDRAWN" type="primary" size="small" @click="handleAddQuote"> |
| | | <a-button v-if="(isPublishedOrBidding || isDraft || isPriceComparing) && selectedBid?.bidStatus !== BID_STATUS.WITHDRAWN" type="primary" size="small" @click="handleAddQuote"> |
| | | <template #icon><IconifyIcon icon="ant-design:plus-outlined" /></template> |
| | | 新增报价 |
| | | </a-button> |
| | |
| | | {{ record.warrantyPeriod != null ? `${record.warrantyPeriod} 个月` : '-' }} |
| | | </template> |
| | | <template v-if="column.key === 'actions'"> |
| | | <a-button v-if="!isAwarded && selectedBid?.bidStatus !== BID_STATUS.WITHDRAWN" size="small" type="link" @click="handleEditQuote(record)"><IconifyIcon icon="ant-design:edit-outlined" />编辑</a-button> |
| | | <a-button v-if="(isPublishedOrBidding || isDraft || isPriceComparing) && selectedBid?.bidStatus !== BID_STATUS.WITHDRAWN" size="small" type="link" @click="handleEditQuote(record)"><IconifyIcon icon="ant-design:edit-outlined" />编辑</a-button> |
| | | </template> |
| | | </template> |
| | | </a-table> |
| | |
| | | </a-tab-pane> |
| | | |
| | | <!-- Tab4: 开标 --> |
| | | <a-tab-pane key="bidOpen"> |
| | | <a-tab-pane v-if="!isSimpleMode" key="bidOpen"> |
| | | <template #tab> |
| | | <a-space :size="4"><IconifyIcon icon="ant-design:unlock-outlined" />开标</a-space> |
| | | </template> |
| | |
| | | <div class="text-center py-8"> |
| | | <a-result status="info" title="尚未开标" sub-title="执行开标后项目进入投标阶段,供应商可正式投标" /> |
| | | <br /> |
| | | <a-button v-if="!isAwarded" type="primary" @click="handleCreateBidOpen"> |
| | | <a-button v-if="isPublished" type="primary" @click="handleCreateBidOpen"> |
| | | <template #icon><IconifyIcon icon="ant-design:thunderbolt-outlined" /></template> |
| | | 执行开标 |
| | | </a-button> |
| | |
| | | </a-tab-pane> |
| | | |
| | | <!-- Tab5: 评标 --> |
| | | <a-tab-pane key="evaluation"> |
| | | <a-tab-pane v-if="!isSimpleMode" key="evaluation"> |
| | | <template #tab> |
| | | <a-space :size="4"><IconifyIcon icon="ant-design:trophy-outlined" />评标</a-space> |
| | | </template> |
| | | <div class="flex items-center justify-between mb-3"> |
| | | <span class="text-xs text-gray-400">共 <b class="text-gray-600">{{ evalCount }}</b> 条,已排名 <b class="text-green-500">{{ rankedCount }}</b> 条</span> |
| | | <a-space v-if="!isAwarded"> |
| | | <a-space v-if="isBiddingOrEvaluating"> |
| | | <a-button size="small" @click="handleCalculateRanking"> |
| | | <template #icon><IconifyIcon icon="ant-design:bar-chart-outlined" /></template> |
| | | 计算排名 |
| | | </a-button> |
| | | <a-button type="primary" size="small" @click="evalForm = { tenderProjectId: projectId, supplierId: 0, bidId: 0 }; evalFormVisible = true"> |
| | | <a-button type="primary" size="small" @click="evalForm = { tenderProjectId: projectId, supplierId: undefined!, bidId: undefined! }; evalFormVisible = true"> |
| | | <template #icon><IconifyIcon icon="ant-design:plus-outlined" /></template> |
| | | 新增评标 |
| | | </a-button> |
| | |
| | | <span v-else class="text-gray-300">-</span> |
| | | </template> |
| | | <template v-if="column.key === 'actions'"> |
| | | <a-button v-if="!isAwarded" size="small" type="link" @click="evalForm = { ...record }; evalFormVisible = true"><IconifyIcon icon="ant-design:edit-outlined" />编辑</a-button> |
| | | <a-button v-if="isBiddingOrEvaluating" size="small" type="link" @click="evalForm = { ...record }; evalFormVisible = true"><IconifyIcon icon="ant-design:edit-outlined" />编辑</a-button> |
| | | </template> |
| | | </template> |
| | | </a-table> |
| | |
| | | </a-tab-pane> |
| | | |
| | | <!-- Tab6: 定标 --> |
| | | <a-tab-pane key="award"> |
| | | <a-tab-pane v-if="!isSimpleMode" key="award"> |
| | | <template #tab> |
| | | <a-space :size="4"><IconifyIcon icon="ant-design:check-circle-outlined" />定标</a-space> |
| | | </template> |
| | |
| | | <span class="text-sm">采购订单 ID: {{ award.purchaseOrderId }}</span> |
| | | </template> |
| | | </a-result> |
| | | <a-popconfirm v-if="!isAwarded" title="确定删除该定标记录?" ok-text="确定" cancel-text="取消" @confirm="handleDeleteAward"> |
| | | <a-popconfirm v-if="canDeleteAward" title="确定删除该定标记录?" ok-text="确定" cancel-text="取消" @confirm="handleDeleteAward"> |
| | | <a-button type="link" danger size="small" class="mt-2">删除定标</a-button> |
| | | </a-popconfirm> |
| | | </div> |
| | |
| | | <template v-else-if="award.awardStatus === AWARD_STATUS.AWARDED"> |
| | | <div class="text-center"> |
| | | <a-result status="success" title="定标完成" class="p-0 mb-3" /> |
| | | <a-button v-if="!isAwarded" type="primary" block @click="handleGeneratePurchaseOrder"> |
| | | <a-button v-if="canGeneratePO" type="primary" block @click="handleGeneratePurchaseOrder"> |
| | | <template #icon><IconifyIcon icon="ant-design:shopping-cart-outlined" /></template> |
| | | 生成采购订单 |
| | | </a-button> |
| | | <a-popconfirm v-if="!isAwarded" title="确定删除该定标记录?" ok-text="确定" cancel-text="取消" @confirm="handleDeleteAward"> |
| | | <a-popconfirm v-if="canDeleteAward" title="确定删除该定标记录?" ok-text="确定" cancel-text="取消" @confirm="handleDeleteAward"> |
| | | <a-button type="link" danger size="small" class="mt-2">删除定标</a-button> |
| | | </a-popconfirm> |
| | | </div> |
| | |
| | | <template v-else> |
| | | <div class="text-center"> |
| | | <div class="text-gray-500 text-sm mb-3">定标信息已创建,请审批</div> |
| | | <a-button v-if="!isAwarded" type="primary" block @click="handleApproveAward" style="background: #52c41a; border-color: #52c41a;"> |
| | | <a-button v-if="canApproveAward" type="primary" block @click="handleApproveAward" style="background: #52c41a; border-color: #52c41a;"> |
| | | <template #icon><IconifyIcon icon="ant-design:check-outlined" /></template> |
| | | 审批通过 |
| | | </a-button> |
| | | <a-popconfirm v-if="!isAwarded" title="确定删除该定标记录?" ok-text="确定" cancel-text="取消" @confirm="handleDeleteAward"> |
| | | <a-popconfirm v-if="canDeleteAward" title="确定删除该定标记录?" ok-text="确定" cancel-text="取消" @confirm="handleDeleteAward"> |
| | | <a-button type="link" danger size="small" class="mt-2">删除定标</a-button> |
| | | </a-popconfirm> |
| | | </div> |
| | |
| | | <div class="text-center py-8"> |
| | | <a-result status="info" title="尚未定标" sub-title="基于评标排名选择中标供应商并创建定标" /> |
| | | <br /> |
| | | <a-button v-if="!isAwarded" type="primary" @click="awardForm = { tenderProjectId: projectId, supplierId: 0, bidId: 0, awardNo: '' }; awardFormVisible = true"> |
| | | <a-button v-if="isEvaluating" type="primary" @click="awardForm = { tenderProjectId: projectId, supplierId: undefined!, bidId: undefined!, awardNo: '' }; awardFormVisible = true"> |
| | | <template #icon><IconifyIcon icon="ant-design:plus-outlined" /></template> |
| | | 创建定标 |
| | | </a-button> |
| | |
| | | </a-form> |
| | | </a-modal> |
| | | |
| | | <!-- 简易模式:确认中标弹窗 --> |
| | | <a-modal v-model:open="confirmModalVisible" title="确认中标" :width="460" @ok="handleSimpleConfirm"> |
| | | <a-form layout="vertical" class="mt-4"> |
| | | <a-form-item label="中标投标记录" required> |
| | | <a-select |
| | | v-model:value="confirmBidId" |
| | | show-search |
| | | placeholder="选择中标的投标记录" |
| | | :filter-option="filterOption" |
| | | > |
| | | <a-select-option |
| | | v-for="b in bidList.filter((i) => i.bidStatus !== BID_STATUS.WITHDRAWN)" |
| | | :key="b.id" |
| | | :value="b.id" |
| | | :label="`${b.supplierName} - ${b.bidNo}`" |
| | | > |
| | | {{ b.supplierName }} - {{ b.bidNo }} (¥{{ b.bidTotalAmount?.toLocaleString?.() ?? b.bidTotalAmount }}) |
| | | </a-select-option> |
| | | </a-select> |
| | | </a-form-item> |
| | | <div class="text-gray-400 text-xs"> |
| | | 确认后将自动生成采购订单,该操作不可撤销。 |
| | | </div> |
| | | </a-form> |
| | | </a-modal> |
| | | |
| | | <!-- 定标表单 --> |
| | | <a-modal v-model:open="awardFormVisible" title="创建定标" :width="500" @ok="handleCreateAward"> |
| | | <a-form layout="vertical" class="mt-4"> |
| | |
| | | <a-row :gutter="12"> |
| | | <a-col :span="12"> |
| | | <a-form-item label="供应商" required> |
| | | <a-select v-model:value="awardForm.supplierId" show-search placeholder="选择供应商" :filter-option="filterOption"> |
| | | <a-select-option v-for="s in supplierList" :key="s.id" :value="s.id" :label="s.name">{{ s.name }}</a-select-option> |
| | | <a-select v-model:value="awardForm.supplierId" show-search placeholder="选择供应商" :filter-option="filterOption" @change="onAwardSupplierChange"> |
| | | <a-select-option v-for="s in bidSuppliers" :key="s.id" :value="s.id" :label="s.name">{{ s.name }}</a-select-option> |
| | | </a-select> |
| | | </a-form-item> |
| | | </a-col> |
| | | <a-col :span="12"> |
| | | <a-form-item label="投标" required> |
| | | <a-select v-model:value="awardForm.bidId" show-search placeholder="选择投标" :filter-option="filterOption"> |
| | | <a-select-option v-for="b in bidList" :key="b.id" :value="b.id" :label="`${b.bidNo} - ${b.supplierName}`">{{ b.bidNo }} - {{ b.supplierName }}</a-select-option> |
| | | <a-select v-model:value="awardForm.bidId" show-search placeholder="选择投标" :filter-option="filterOption" :disabled="!awardForm.supplierId" @change="onAwardBidChange"> |
| | | <a-select-option v-for="b in activeBids" :key="b.id" :value="b.id" :label="`${b.bidNo} - ${b.supplierName}`">{{ b.bidNo }} - {{ b.supplierName }}</a-select-option> |
| | | </a-select> |
| | | </a-form-item> |
| | | </a-col> |