采购更新

This commit is contained in:
吴红兵
2026-02-10 16:13:29 +08:00
parent 71de4c4549
commit 87967781d6
3 changed files with 105 additions and 329 deletions

View File

@@ -60,23 +60,15 @@
</el-col> </el-col>
<el-col :span="12" class="mb16"> <el-col :span="12" class="mb16">
<el-form-item label="预算金额" prop="budget"> <el-form-item label="预算金额" prop="budget">
<div class="budget-input-group"> <div class="budget-yuan-wrap">
<el-input-number <el-input-number
v-model="budgetInputValue" v-model="dataForm.budget"
:min="0.01" :min="0.01"
:precision="2" :precision="2"
:placeholder="getBudgetPlaceholder()" placeholder="请输入金额"
:controls="false" :controls="false"
class="budget-input" style="width: 100%" />
@change="handleBudgetChange" /> <span class="budget-unit"></span>
<el-select
v-model="budgetUnit"
class="budget-unit-select"
@change="handleBudgetUnitChange">
<el-option label="元" value="yuan" />
<el-option label="千元" value="thousand" />
<el-option label="万元" value="wan" />
</el-select>
</div> </div>
</el-form-item> </el-form-item>
</el-col> </el-col>
@@ -165,19 +157,19 @@
</el-select> </el-select>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12" class="mb16" v-if="isPurchaseType(PURCHASE_TYPE_IDS.BUSINESS_NEGOTIATION)"> <el-col :span="12" class="mb16" v-if="isPurchaseType(DEPT_PURCHASE_TYPE.BUSINESS_NEGOTIATION)">
<el-form-item label="商务洽谈表" prop="businessNegotiationTable" required class="mb16"> <el-form-item label="商务洽谈表" prop="businessNegotiationTable" required class="mb16">
<upload-file v-model="dataForm.businessNegotiationTable" :limit="1" :file-type="['doc', 'docx', 'pdf']" :data="{ fileType: FILE_TYPE_MAP.businessNegotiationTable }" upload-file-url="/purchase/purchasingfiles/upload" /> <upload-file v-model="dataForm.businessNegotiationTable" :limit="1" :file-type="['doc', 'docx', 'pdf']" :data="{ fileType: FILE_TYPE_MAP.businessNegotiationTable }" upload-file-url="/purchase/purchasingfiles/upload" />
<el-button type="primary" link icon="Download" size="small" @click="downloadTemplate('business_negotiation')" style="margin-top: 8px; display: inline-block">下载商务洽谈表模版</el-button> <el-button type="primary" link icon="Download" size="small" @click="downloadTemplate('business_negotiation')" style="margin-top: 8px; display: inline-block">下载商务洽谈表模版</el-button>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12" class="mb16" v-if="isPurchaseType(PURCHASE_TYPE_IDS.MARKET_PURCHASE)"> <el-col :span="12" class="mb16" v-if="isPurchaseType(DEPT_PURCHASE_TYPE.MARKET_PURCHASE)">
<el-form-item label="市场采购纪要" prop="marketPurchaseMinutes" required class="mb16"> <el-form-item label="市场采购纪要" prop="marketPurchaseMinutes" required class="mb16">
<upload-file v-model="dataForm.marketPurchaseMinutes" :limit="1" :file-type="['doc', 'docx', 'pdf']" :data="{ fileType: FILE_TYPE_MAP.marketPurchaseMinutes }" upload-file-url="/purchase/purchasingfiles/upload" /> <upload-file v-model="dataForm.marketPurchaseMinutes" :limit="1" :file-type="['doc', 'docx', 'pdf']" :data="{ fileType: FILE_TYPE_MAP.marketPurchaseMinutes }" upload-file-url="/purchase/purchasingfiles/upload" />
<el-button type="primary" link icon="Download" size="small" @click="downloadTemplate('market_purchase_minutes')" style="margin-top: 8px; display: inline-block">下载市场采购纪要模版</el-button> <el-button type="primary" link icon="Download" size="small" @click="downloadTemplate('market_purchase_minutes')" style="margin-top: 8px; display: inline-block">下载市场采购纪要模版</el-button>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12" class="mb16" v-if="isPurchaseType(PURCHASE_TYPE_IDS.ONLINE_MALL)"> <el-col :span="12" class="mb16" v-if="isPurchaseType(DEPT_PURCHASE_TYPE.ONLINE_MALL)">
<el-form-item label="网上商城采购相关材料" prop="onlineMallMaterials" required class="mb16"> <el-form-item label="网上商城采购相关材料" prop="onlineMallMaterials" required class="mb16">
<upload-file v-model="dataForm.onlineMallMaterials" :limit="1" :file-type="['doc', 'docx', 'pdf']" :data="{ fileType: FILE_TYPE_MAP.onlineMallMaterials }" upload-file-url="/purchase/purchasingfiles/upload" /> <upload-file v-model="dataForm.onlineMallMaterials" :limit="1" :file-type="['doc', 'docx', 'pdf']" :data="{ fileType: FILE_TYPE_MAP.onlineMallMaterials }" upload-file-url="/purchase/purchasingfiles/upload" />
</el-form-item> </el-form-item>
@@ -188,7 +180,7 @@
<el-button type="primary" link icon="Download" size="small" @click="downloadTemplate('inquiry')" style="margin-top: 8px; display: inline-block">下载部门采购询价模版模版</el-button> <el-button type="primary" link icon="Download" size="small" @click="downloadTemplate('inquiry')" style="margin-top: 8px; display: inline-block">下载部门采购询价模版模版</el-button>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12" class="mb16" v-if="isPurchaseType(PURCHASE_TYPE_IDS.ENTRUST_CENTER)"> <el-col :span="12" class="mb16" v-if="isPurchaseType(DEPT_PURCHASE_TYPE.ENTRUST_CENTER)">
<el-form-item label="委托采购中心方式" prop="entrustCenterType" class="mb16"> <el-form-item label="委托采购中心方式" prop="entrustCenterType" class="mb16">
<el-radio-group v-model="dataForm.entrustCenterType" disabled> <el-radio-group v-model="dataForm.entrustCenterType" disabled>
<el-radio label="service_online">服务类网上商城</el-radio> <el-radio label="service_online">服务类网上商城</el-radio>
@@ -196,7 +188,7 @@
</el-radio-group> </el-radio-group>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12" class="mb16" v-if="isPurchaseType(PURCHASE_TYPE_IDS.ENTRUST_CENTER) && dataForm.entrustCenterType === 'service_online' && categoryCodePath && categoryCodePath.length > 0 && categoryCodePath[0] === 'C'"> <el-col :span="12" class="mb16" v-if="isPurchaseType(DEPT_PURCHASE_TYPE.ENTRUST_CENTER) ">
<el-form-item label="是否有供应商" prop="hasSupplier" class="mb16"> <el-form-item label="是否有供应商" prop="hasSupplier" class="mb16">
<el-radio-group v-model="dataForm.hasSupplier"> <el-radio-group v-model="dataForm.hasSupplier">
<el-radio label="1"></el-radio> <el-radio label="1"></el-radio>
@@ -204,25 +196,19 @@
</el-radio-group> </el-radio-group>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12" class="mb16" v-if="isPurchaseType(PURCHASE_TYPE_IDS.ENTRUST_CENTER) && dataForm.entrustCenterType === 'service_online' && categoryCodePath && categoryCodePath[0] === 'C' && dataForm.hasSupplier === '1'"> <el-col :span="12" class="mb16" v-if="isPurchaseType(DEPT_PURCHASE_TYPE.ENTRUST_CENTER) && dataForm.entrustCenterType === 'service_online' && categoryCodePath && categoryCodePath[0] === 'C' && dataForm.hasSupplier === '1'">
<el-form-item label="供应商名称" prop="suppliers" class="mb16">
<el-input v-model="dataForm.suppliers" type="textarea" :rows="2" placeholder="请输入供应商名称,多个供应商请用逗号或分号分隔" maxlength="500" show-word-limit />
<div class="template-note mt5"><el-text type="info" size="small">多个供应商请用逗号,或分号;分隔</el-text></div>
</el-form-item>
</el-col>
<el-col :span="12" class="mb16" v-if="isPurchaseType(PURCHASE_TYPE_IDS.ENTRUST_CENTER) && dataForm.entrustCenterType === 'service_online' && categoryCodePath && categoryCodePath[0] === 'C' && dataForm.hasSupplier === '1'">
<el-form-item label="需求文件" prop="serviceDirectSelect" required class="mb16"> <el-form-item label="需求文件" prop="serviceDirectSelect" required class="mb16">
<upload-file v-model="dataForm.serviceDirectSelect" :limit="1" :file-type="['doc', 'docx', 'pdf']" :data="{ fileType: FILE_TYPE_MAP.serviceDirectSelect }" upload-file-url="/purchase/purchasingfiles/upload" /> <upload-file v-model="dataForm.serviceDirectSelect" :limit="1" :file-type="['doc', 'docx', 'pdf']" :data="{ fileType: FILE_TYPE_MAP.serviceDirectSelect }" upload-file-url="/purchase/purchasingfiles/upload" />
<el-button type="primary" link icon="Download" size="small" @click="downloadTemplate('direct_select')" style="margin-top: 8px; display: inline-block">下载服务商城项目需求模板直选模版</el-button> <el-button type="primary" link icon="Download" size="small" @click="downloadTemplate('direct_select')" style="margin-top: 8px; display: inline-block">下载服务商城项目需求模板直选模版</el-button>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12" class="mb16" v-if="isPurchaseType(PURCHASE_TYPE_IDS.ENTRUST_CENTER) && dataForm.entrustCenterType === 'service_online' && categoryCodePath && categoryCodePath[0] === 'C' && dataForm.hasSupplier === '0'"> <el-col :span="12" class="mb16" v-if="isPurchaseType(DEPT_PURCHASE_TYPE.ENTRUST_CENTER) && dataForm.entrustCenterType === 'service_online' && categoryCodePath && categoryCodePath[0] === 'C' && dataForm.hasSupplier === '0'">
<el-form-item label="需求文件" prop="serviceInviteSelect" required class="mb16"> <el-form-item label="需求文件" prop="serviceInviteSelect" required class="mb16">
<upload-file v-model="dataForm.serviceInviteSelect" :limit="1" :file-type="['doc', 'docx', 'pdf']" :data="{ fileType: FILE_TYPE_MAP.serviceInviteSelect }" upload-file-url="/purchase/purchasingfiles/upload" /> <upload-file v-model="dataForm.serviceInviteSelect" :limit="1" :file-type="['doc', 'docx', 'pdf']" :data="{ fileType: FILE_TYPE_MAP.serviceInviteSelect }" upload-file-url="/purchase/purchasingfiles/upload" />
<el-button type="primary" link icon="Download" size="small" @click="downloadTemplate('invite_select')" style="margin-top: 8px; display: inline-block">下载服务商城项目需求模板邀请比选模版</el-button> <el-button type="primary" link icon="Download" size="small" @click="downloadTemplate('public_select')" style="margin-top: 8px; display: inline-block">下载服务商城项目需求模板公开比选模版</el-button>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12" class="mb16" v-if="isPurchaseType(PURCHASE_TYPE_IDS.ENTRUST_CENTER) && dataForm.entrustCenterType === 'other' && categoryCodePath && categoryCodePath[0] === 'A'"> <el-col :span="12" class="mb16" v-if="isPurchaseType(DEPT_PURCHASE_TYPE.ENTRUST_CENTER) && dataForm.entrustCenterType === 'other' && categoryCodePath && categoryCodePath[0] === 'A'">
<el-form-item label="需求模板" prop="purchaseRequirementTemplate" required class="mb16"> <el-form-item label="需求模板" prop="purchaseRequirementTemplate" required class="mb16">
<upload-file v-model="dataForm.purchaseRequirementTemplate" :limit="1" :file-type="['doc', 'docx', 'pdf']" :data="{ fileType: FILE_TYPE_MAP.purchaseRequirementTemplate }" upload-file-url="/purchase/purchasingfiles/upload" /> <upload-file v-model="dataForm.purchaseRequirementTemplate" :limit="1" :file-type="['doc', 'docx', 'pdf']" :data="{ fileType: FILE_TYPE_MAP.purchaseRequirementTemplate }" upload-file-url="/purchase/purchasingfiles/upload" />
<el-button type="primary" link icon="Download" size="small" @click="downloadTemplate('purchase_requirement')" style="margin-top: 8px; display: inline-block">下载表1需求模板模版</el-button> <el-button type="primary" link icon="Download" size="small" @click="downloadTemplate('purchase_requirement')" style="margin-top: 8px; display: inline-block">下载表1需求模板模版</el-button>
@@ -236,12 +222,12 @@
</el-radio-group> </el-radio-group>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12" class="mb16" v-if="showAutoInviteSelect && dataForm.hasSupplier === '1'"> <!-- <el-col :span="12" class="mb16" v-if="showAutoInviteSelect && dataForm.hasSupplier === '1'">
<el-form-item label="推荐供应商" prop="suppliers" class="mb16"> <el-form-item label="推荐供应商" prop="suppliers" class="mb16">
<el-input v-model="dataForm.suppliers" placeholder="请输入三家供应商名称,用逗号分隔" clearable /> <el-input v-model="dataForm.suppliers" placeholder="请输入三家供应商名称,用逗号分隔" clearable />
<div class="template-note mt5"><el-text type="info" size="small">请输入三家供应商名称用逗号分隔</el-text></div> <div class="template-note mt5"><el-text type="info" size="small">请输入三家供应商名称用逗号分隔</el-text></div>
</el-form-item> </el-form-item>
</el-col> </el-col> -->
<el-col :span="12" class="mb16" v-if="showAutoInviteSelect && dataForm.hasSupplier === '1'"> <el-col :span="12" class="mb16" v-if="showAutoInviteSelect && dataForm.hasSupplier === '1'">
<el-form-item label="服务商城项目需求模板(邀请比选)" prop="serviceInviteSelect" required class="mb16"> <el-form-item label="服务商城项目需求模板(邀请比选)" prop="serviceInviteSelect" required class="mb16">
<upload-file v-model="dataForm.serviceInviteSelect" :limit="1" :file-type="['doc', 'docx', 'pdf']" :data="{ fileType: FILE_TYPE_MAP.serviceInviteSelect }" upload-file-url="/purchase/purchasingfiles/upload" /> <upload-file v-model="dataForm.serviceInviteSelect" :limit="1" :file-type="['doc', 'docx', 'pdf']" :data="{ fileType: FILE_TYPE_MAP.serviceInviteSelect }" upload-file-url="/purchase/purchasingfiles/upload" />
@@ -341,12 +327,12 @@
</el-radio-group> </el-radio-group>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12" class="mb16" v-if="showAutoInviteSelectSchool && dataForm.hasSupplier === '1'"> <!-- <el-col :span="12" class="mb16" v-if="showAutoInviteSelectSchool && dataForm.hasSupplier === '1'">
<el-form-item label="推荐供应商" prop="suppliers"> <el-form-item label="推荐供应商" prop="suppliers">
<el-input v-model="dataForm.suppliers" type="textarea" :rows="2" placeholder="请输入至少三家供应商名称,用逗号或分号分隔" clearable /> <el-input v-model="dataForm.suppliers" type="textarea" :rows="2" placeholder="请输入至少三家供应商名称,用逗号或分号分隔" clearable />
<div class="template-note mt5"><el-text type="info" size="small">请输入至少三家供应商名称用逗号或分号分隔</el-text></div> <div class="template-note mt5"><el-text type="info" size="small">请输入至少三家供应商名称用逗号或分号分隔</el-text></div>
</el-form-item> </el-form-item>
</el-col> </el-col> -->
<el-col :span="12" class="mb16"> <el-col :span="12" class="mb16">
<el-form-item label="需求文件" :prop="getRequirementFileProp()" required class="mb16"> <el-form-item label="需求文件" :prop="getRequirementFileProp()" required class="mb16">
<template v-if="showAutoInviteSelectSchool"> <template v-if="showAutoInviteSelectSchool">
@@ -613,18 +599,6 @@ const businessDeptList = ref<any[]>([]);
const schoolLeaderList = ref<any[]>([]); const schoolLeaderList = ref<any[]>([]);
const loading = ref(false); const loading = ref(false);
// 预算金额输入相关
const budgetUnit = ref<'yuan' | 'thousand' | 'wan'>('yuan');
const budgetInputValue = ref<number | null>(null);
// 采购方式ID常量
const PURCHASE_TYPE_IDS = {
BUSINESS_NEGOTIATION: '77b429c146fc9e12ba4c5573da19ad70', // 商务洽谈
MARKET_PURCHASE: 'd522054027140e4d76e074cd96ecfc12', // 市场采购
ONLINE_MALL: 'e8723b4e3c3d51deb54f9349482ea894', // 网上商城
ENTRUST_CENTER: '981bf052a0b30b028a4a89ae490c9b1d' // 委托采购中心
};
// 文件类型映射(对应数据库 file_type 字段) // 文件类型映射(对应数据库 file_type 字段)
// 10:商务洽谈纪要 20:市场采购纪要 30:网上商城采购相关材料 40:可行性论证报告 50:会议记录 60:其他材料 70:单一来源专家论证表 90:进口产品专家论证表 100:政府采购意向表 110:履约验收单 120:采购需求表 130:采购文件 // 10:商务洽谈纪要 20:市场采购纪要 30:网上商城采购相关材料 40:可行性论证报告 50:会议记录 60:其他材料 70:单一来源专家论证表 90:进口产品专家论证表 100:政府采购意向表 110:履约验收单 120:采购需求表 130:采购文件
const FILE_TYPE_MAP: Record<string, string> = { const FILE_TYPE_MAP: Record<string, string> = {
@@ -660,81 +634,52 @@ Object.entries(FILE_TYPE_MAP).forEach(([field, type]) => {
FILE_TYPE_TO_FIELDS[type].push(field); FILE_TYPE_TO_FIELDS[type].push(field);
}); });
// 辅助函数:判断当前采购方式是否为指定类型(通过 id 或 value 匹配 // 部门采购方式字典 value与 DeptPurchaseTypeEnum 一致
const isPurchaseType = (purchaseTypeId: string) => { const DEPT_PURCHASE_TYPE = {
ONLINE_MALL: '1',
MARKET_PURCHASE: '2',
BUSINESS_NEGOTIATION: '3',
ENTRUST_CENTER: '4',
INQUIRY: '6',
} as const;
// 学校统一采购方式字典 value与 PurchaseTypeEnum 一致)
const UNION_PURCHASE_TYPE = {
ONLINE_MALL: '8',
} as const;
// 辅助函数:判断当前采购方式是否为指定类型(通过字典 value 匹配)
const isPurchaseType = (dictValue: string) => {
if (!dataForm.purchaseType) return false; if (!dataForm.purchaseType) return false;
// 在字典中查找匹配的项 return dataForm.purchaseType === dictValue;
const item = purchaseTypeDeptList.value.find(item =>
item.id === purchaseTypeId || item.value === purchaseTypeId
);
if (item) {
return dataForm.purchaseType === item.value;
}
// 如果字典中找不到,直接比较 value兼容性处理
return dataForm.purchaseType === purchaseTypeId;
}; };
// 辅助函数:判断当前采购方式是否为"询价"(通过 label 匹配) // 辅助函数:判断当前采购方式是否为"询价"(通过 value 匹配)
const isInquiryPurchaseType = computed(() => { const isInquiryPurchaseType = computed(() => isPurchaseType(DEPT_PURCHASE_TYPE.INQUIRY));
if (!dataForm.purchaseType) return false;
const item = purchaseTypeDeptList.value.find(item => item.value === dataForm.purchaseType);
if (item) {
const label = item.label || item.dictLabel || item.name || '';
return label.includes('询价');
}
return false;
});
// 辅助函数:判断特殊情况是否为指定类型(通过 id 或 value 匹配) // 辅助函数:判断特殊情况是否为指定类型(通过字典 value 匹配)
const isSpecialType = (specialIdOrValue: string) => { const isSpecialType = (dictValue: string) => {
if (!dataForm.isSpecial) return false; if (!dataForm.isSpecial) return false;
// 在字典中查找匹配的项 const item = isSpecialList.value.find(item => item.value === dictValue);
const item = isSpecialList.value.find(item => return item ? dataForm.isSpecial === item.value : dataForm.isSpecial === dictValue;
item.id === specialIdOrValue || item.value === specialIdOrValue
);
if (item) {
return dataForm.isSpecial === item.value;
}
// 如果字典中找不到,直接比较 value兼容性处理
return dataForm.isSpecial === specialIdOrValue;
}; };
// 判断是否为部门自行采购 // 判断是否为部门自行采购
// 条件:特殊情况=否 且 集采=否 且 预算金额<5万 → 部门自行采购 // 条件:特殊情况=否 且 集采=否 且 预算金额<5万 → 部门自行采购
// 其他情况 → 学校统一采购 // 其他情况 → 学校统一采购
const isDeptPurchase = computed(() => { const isDeptPurchase = computed(() => {
// 检查是否特殊情况是否为"否"(通过 id 或 value 查找value 为 '0' const isSpecialNo = isSpecialList.value.find(item => item.value === '0');
const isSpecialNo = isSpecialList.value.find(item => const isCentralizedNo = isCentralizedList.value.find(item => item.value === '0');
item.id === '1799c07f3a3b8a484f60c495ab9227b6' || item.value === '0'
);
const isSpecialNoValue = isSpecialNo ? isSpecialNo.value : null; const isSpecialNoValue = isSpecialNo ? isSpecialNo.value : null;
// 检查是否集采是否为"否"(通过 id 或 value 查找value 为 '0'
const isCentralizedNo = isCentralizedList.value.find(item =>
item.id === '8e60f8860c1ea2459a41a8ae64fe5518' || item.value === '0'
);
const isCentralizedNoValue = isCentralizedNo ? isCentralizedNo.value : null; const isCentralizedNoValue = isCentralizedNo ? isCentralizedNo.value : null;
return !!(isSpecialNoValue && isCentralizedNoValue &&
// 三个条件必须同时满足:特殊情况=否 且 集采=否 且 预算金额<5万
if (isSpecialNoValue && isCentralizedNoValue &&
dataForm.isSpecial === isSpecialNoValue && dataForm.isSpecial === isSpecialNoValue &&
dataForm.isCentralized === isCentralizedNoValue && dataForm.isCentralized === isCentralizedNoValue &&
dataForm.budget && dataForm.budget < 50000) { dataForm.budget && dataForm.budget < 50000);
return true;
}
return false;
}); });
// 判断是否为紧急情况(通过 id 或 value 查找value 为 '1' // 特殊情况字典 value0否 1紧急 2单一 3进口
const isUrgentSpecial = computed(() => { const isUrgentSpecial = computed(() => dataForm.isSpecial === '1');
const urgentItem = isSpecialList.value.find(item =>
item.id === '6509b59e24c1c6568f4277e544f3e55e' ||
(item.value === '1' && (item.label?.includes('紧急') || item.dictLabel?.includes('紧急')))
);
if (!urgentItem) return false;
return dataForm.isSpecial === urgentItem.value;
});
// 第二步标题 // 第二步标题
const stepTwoTitle = computed(() => { const stepTwoTitle = computed(() => {
@@ -816,7 +761,7 @@ const isSpecialServiceCategory = computed(() => {
// - 服务类:若末级节点 isMallService=0 且 isMallProject=0则选“其他方式”否则选“服务类网上商城” // - 服务类:若末级节点 isMallService=0 且 isMallProject=0则选“其他方式”否则选“服务类网上商城”
// - 非服务类:默认选“其他方式” // - 非服务类:默认选“其他方式”
const calcEntrustCenterType = (): 'service_online' | 'other' | '' => { const calcEntrustCenterType = (): 'service_online' | 'other' | '' => {
if (!isPurchaseType(PURCHASE_TYPE_IDS.ENTRUST_CENTER)) return ''; if (!isPurchaseType(DEPT_PURCHASE_TYPE.ENTRUST_CENTER)) return '';
if (!dataForm.categoryCode) return ''; if (!dataForm.categoryCode) return '';
const category = getCategoryInfo(); const category = getCategoryInfo();
@@ -916,25 +861,15 @@ const isAutoSelectPurchaseTypeUnion = computed(() => {
watch([() => dataForm.categoryCode, () => dataForm.budget], () => { watch([() => dataForm.categoryCode, () => dataForm.budget], () => {
// 部门自行采购:自动设置网上商城 // 部门自行采购:自动设置网上商城
if (isAutoSelectPurchaseType.value && isDeptPurchase.value) { if (isAutoSelectPurchaseType.value && isDeptPurchase.value) {
// 查找网上商城选项(通过 id、value 或 label 匹配) const onlineMallOption = purchaseTypeDeptList.value.find(item => item.value === DEPT_PURCHASE_TYPE.ONLINE_MALL);
const onlineMallOption = purchaseTypeDeptList.value.find(item => {
const label = item.label || item.dictLabel || item.name || '';
return item.id === PURCHASE_TYPE_IDS.ONLINE_MALL ||
item.value === PURCHASE_TYPE_IDS.ONLINE_MALL ||
label.includes('网上商城') || label.includes('商城');
});
if (onlineMallOption && dataForm.purchaseType !== onlineMallOption.value) { if (onlineMallOption && dataForm.purchaseType !== onlineMallOption.value) {
dataForm.purchaseType = onlineMallOption.value; dataForm.purchaseType = onlineMallOption.value;
} }
} }
// 学校统一采购:自动设置网上商城采购方式(提交字段统一为 purchaseType // 学校统一采购:自动设置网上商城采购方式
if (isAutoSelectPurchaseTypeUnion.value && !isDeptPurchase.value) { if (isAutoSelectPurchaseTypeUnion.value && !isDeptPurchase.value) {
// 查找学校统一采购方式字典中包含"网上商城"的选项 const onlineMallOption = purchaseTypeUnionList.value.find(item => item.value === UNION_PURCHASE_TYPE.ONLINE_MALL);
const onlineMallOption = purchaseTypeUnionList.value.find(item => {
const label = item.label || item.dictLabel || item.name || '';
return label.includes('网上商城') || label.includes('商城');
});
if (onlineMallOption && dataForm.purchaseType !== onlineMallOption.value) { if (onlineMallOption && dataForm.purchaseType !== onlineMallOption.value) {
dataForm.purchaseType = onlineMallOption.value; dataForm.purchaseType = onlineMallOption.value;
} }
@@ -1151,10 +1086,6 @@ async function loadDetail(applyId: string | number) {
fileFlowStatus: detail.fileFlowStatus ?? '', fileFlowStatus: detail.fileFlowStatus ?? '',
}); });
setCategoryCodePath(); setCategoryCodePath();
if (dataForm.budget != null) {
budgetInputValue.value = dataForm.budget;
budgetUnit.value = 'yuan';
}
currentStep.value = 0; currentStep.value = 0;
try { try {
const fileRes = await getApplyFiles(String(applyId)); const fileRes = await getApplyFiles(String(applyId));
@@ -1327,26 +1258,15 @@ const getFundSourceDict = async () => {
const getIsCentralizedDict = async () => { const getIsCentralizedDict = async () => {
try { try {
const res = await getDicts('PURCHASE_IS_CEN'); const res = await getDicts('PURCHASE_IS_CEN');
isCentralizedList.value = []; isCentralizedList.value = res.data && Array.isArray(res.data)
if (res.data && Array.isArray(res.data)) { ? res.data.map((item: any) => ({
isCentralizedList.value = res.data.map((item: any) => ({
id: item.id, id: item.id,
label: item.label || item.dictLabel || item.name, label: item.label || item.dictLabel || item.name,
value: item.value || item.dictValue || item.code value: item.value || item.dictValue || item.code
})); }))
} else { : [];
isCentralizedList.value = [
{ id: '8e60f8860c1ea2459a41a8ae64fe5518', label: '否', value: '0' },
{ id: '', label: '政府集中采购', value: '1' },
{ id: '', label: '学校集中采购', value: '2' }
];
}
} catch (err) { } catch (err) {
isCentralizedList.value = [ isCentralizedList.value = [];
{ id: '8e60f8860c1ea2459a41a8ae64fe5518', label: '否', value: '0' },
{ id: '', label: '政府集中采购', value: '1' },
{ id: '', label: '学校集中采购', value: '2' }
];
} }
}; };
@@ -1354,28 +1274,15 @@ const getIsCentralizedDict = async () => {
const getIsSpecialDict = async () => { const getIsSpecialDict = async () => {
try { try {
const res = await getDicts('PURCHASE_IS_SPEC'); const res = await getDicts('PURCHASE_IS_SPEC');
isSpecialList.value = []; isSpecialList.value = res.data && Array.isArray(res.data)
if (res.data && Array.isArray(res.data)) { ? res.data.map((item: any) => ({
isSpecialList.value = res.data.map((item: any) => ({
id: item.id, id: item.id,
label: item.label || item.dictLabel || item.name, label: item.label || item.dictLabel || item.name,
value: item.value || item.dictValue || item.code value: item.value || item.dictValue || item.code
})); }))
} else { : [];
isSpecialList.value = [
{ id: '1799c07f3a3b8a484f60c495ab9227b6', label: '否', value: '0' },
{ id: '', label: '紧急', value: '1' },
{ id: '', label: '单一', value: '2' },
{ id: '', label: '进口', value: '3' }
];
}
} catch (err) { } catch (err) {
isSpecialList.value = [ isSpecialList.value = [];
{ id: '1799c07f3a3b8a484f60c495ab9227b6', label: '否', value: '0' },
{ id: '', label: '紧急', value: '1' },
{ id: '', label: '单一', value: '2' },
{ id: '', label: '进口', value: '3' }
];
} }
}; };
@@ -1383,16 +1290,15 @@ const getIsSpecialDict = async () => {
const getPurchaseTypeDeptDict = async () => { const getPurchaseTypeDeptDict = async () => {
try { try {
const res = await getDicts('PURCHASE_TYPE_DEPT'); const res = await getDicts('PURCHASE_TYPE_DEPT');
purchaseTypeDeptList.value = []; purchaseTypeDeptList.value = res.data && Array.isArray(res.data)
if (res.data && Array.isArray(res.data)) { ? res.data.map((item: any) => ({
purchaseTypeDeptList.value = res.data.map((item: any) => ({
id: item.id, id: item.id,
label: item.label || item.dictLabel || item.name, label: item.label || item.dictLabel || item.name,
value: item.value || item.dictValue || item.code value: item.value || item.dictValue || item.code
})); }))
} : [];
} catch (err) { } catch (err) {
console.error('获取部门采购方式字典失败', err); purchaseTypeDeptList.value = [];
} }
}; };
@@ -1400,24 +1306,15 @@ const getPurchaseTypeDeptDict = async () => {
const getPurchaseModeSchoolDict = async () => { const getPurchaseModeSchoolDict = async () => {
try { try {
const res = await getDicts('PURCHASE_MODE_SCHOOL'); const res = await getDicts('PURCHASE_MODE_SCHOOL');
purchaseModeSchoolList.value = []; purchaseModeSchoolList.value = res.data && Array.isArray(res.data)
if (res.data && Array.isArray(res.data)) { ? res.data.map((item: any) => ({
purchaseModeSchoolList.value = res.data.map((item: any) => ({
id: item.id, id: item.id,
label: item.label || item.dictLabel || item.name, label: item.label || item.dictLabel || item.name,
value: item.value || item.dictValue || item.code value: item.value || item.dictValue || item.code
})); }))
} else { : [];
purchaseModeSchoolList.value = [
{ label: '政府采购', value: '1' },
{ label: '学校自主采购', value: '2' }
];
}
} catch (err) { } catch (err) {
purchaseModeSchoolList.value = [ purchaseModeSchoolList.value = [];
{ label: '政府采购', value: '1' },
{ label: '学校自主采购', value: '2' }
];
} }
}; };
@@ -1425,16 +1322,15 @@ const getPurchaseModeSchoolDict = async () => {
const getPurchaseTypeUnionDict = async () => { const getPurchaseTypeUnionDict = async () => {
try { try {
const res = await getDicts('PURCHASE_TYPE_UNION'); const res = await getDicts('PURCHASE_TYPE_UNION');
purchaseTypeUnionList.value = []; purchaseTypeUnionList.value = res.data && Array.isArray(res.data)
if (res.data && Array.isArray(res.data)) { ? res.data.map((item: any) => ({
purchaseTypeUnionList.value = res.data.map((item: any) => ({
id: item.id, id: item.id,
label: item.label || item.dictLabel || item.name, label: item.label || item.dictLabel || item.name,
value: item.value || item.dictValue || item.code value: item.value || item.dictValue || item.code
})); }))
} : [];
} catch (err) { } catch (err) {
console.error('获取学校统一采购方式字典失败', err); purchaseTypeUnionList.value = [];
} }
}; };
@@ -1479,9 +1375,9 @@ const getSchoolLeaderListData = async () => {
// 处理业务分管处室选择变化 // 处理业务分管处室选择变化
const handleBusinessDeptChange = (value: string) => { const handleBusinessDeptChange = (value: string) => {
if (value) { if (value) {
const selected = businessDeptList.value.find(item => item.id === value); const selected = businessDeptList.value.find(item => item.userId === value);
if (selected) { if (selected) {
dataForm.deptClassifyUserId = selected.id; dataForm.deptClassifyUserId = selected.userId;
dataForm.deptClassifyName = selected.deptName || ''; dataForm.deptClassifyName = selected.deptName || '';
} }
} else { } else {
@@ -1719,83 +1615,6 @@ const setCategoryCodePath = () => {
} }
}; };
// 预算金额单位转换
const handleBudgetChange = (value: number | null) => {
if (value === null || value === undefined) {
dataForm.budget = null;
return;
}
// 根据单位转换为元
switch (budgetUnit.value) {
case 'yuan':
dataForm.budget = value;
break;
case 'thousand':
dataForm.budget = value * 1000;
break;
case 'wan':
dataForm.budget = value * 10000;
break;
}
};
// 预算金额单位变化处理
const handleBudgetUnitChange = (unit: 'yuan' | 'thousand' | 'wan') => {
if (!dataForm.budget) {
budgetInputValue.value = null;
return;
}
// 根据新单位转换显示值
switch (unit) {
case 'yuan':
budgetInputValue.value = dataForm.budget;
break;
case 'thousand':
budgetInputValue.value = dataForm.budget / 1000;
break;
case 'wan':
budgetInputValue.value = dataForm.budget / 10000;
break;
}
};
// 获取预算金额输入框的 placeholder
const getBudgetPlaceholder = (): string => {
switch (budgetUnit.value) {
case 'yuan':
return '请输入金额';
case 'thousand':
return '请输入金额(千元)';
case 'wan':
return '请输入金额(万元)';
default:
return '请输入金额';
}
};
// 监听 dataForm.budget 变化,同步到 budgetInputValue
watch(() => dataForm.budget, (newVal) => {
if (newVal === null || newVal === undefined) {
budgetInputValue.value = null;
return;
}
// 根据当前单位转换显示值
switch (budgetUnit.value) {
case 'yuan':
budgetInputValue.value = newVal;
break;
case 'thousand':
budgetInputValue.value = newVal / 1000;
break;
case 'wan':
budgetInputValue.value = newVal / 10000;
break;
}
}, { immediate: true });
// 监听 categoryTreeData 变化,设置回显路径 // 监听 categoryTreeData 变化,设置回显路径
watch(() => categoryTreeData.value, () => { watch(() => categoryTreeData.value, () => {
if (dataForm.categoryCode) { if (dataForm.categoryCode) {
@@ -1881,11 +1700,6 @@ onMounted(async () => {
dataForm.isSpecial = '0'; dataForm.isSpecial = '0';
} }
// 初始化预算金额显示值
if (dataForm.budget) {
budgetInputValue.value = dataForm.budget;
}
// 如果有 categoryCode设置回显路径 // 如果有 categoryCode设置回显路径
if (dataForm.categoryCode) { if (dataForm.categoryCode) {
setCategoryCodePath(); setCategoryCodePath();
@@ -1955,58 +1769,21 @@ onMounted(async () => {
font-size: 12px; font-size: 12px;
} }
/* 预算金额输入组样式 - 并排显示,无缝连接 */ /* 预算金额输入框 + 单位元 */
.budget-input-group { .budget-yuan-wrap {
display: flex; display: flex;
align-items: stretch; align-items: center;
width: 100%; width: 100%;
transition: all 0.2s ease; gap: 8px;
.budget-input { :deep(.el-input-number) {
flex: 1; flex: 1;
:deep(.el-input__wrapper) {
border-radius: 4px 0 0 4px;
border-right: none;
transition: all 0.2s ease;
} }
:deep(.el-input__wrapper:hover) { .budget-unit {
z-index: 1; color: var(--el-text-color-regular);
border-color: var(--el-color-primary); font-size: 14px;
box-shadow: 0 0 0 1px var(--el-color-primary-light-7);
}
:deep(.el-input__wrapper.is-focus) {
z-index: 1;
border-color: var(--el-color-primary);
box-shadow: 0 0 0 1px var(--el-color-primary-light-7);
}
}
.budget-unit-select {
width: 100px;
flex-shrink: 0; flex-shrink: 0;
cursor: pointer;
:deep(.el-input__wrapper) {
border-radius: 0 4px 4px 0;
border-left: 1px solid var(--el-border-color);
margin-left: -1px;
transition: all 0.2s ease;
}
:deep(.el-input__wrapper:hover) {
z-index: 1;
border-color: var(--el-color-primary);
box-shadow: 0 0 0 1px var(--el-color-primary-light-7);
}
:deep(.el-input__wrapper.is-focus) {
z-index: 1;
border-color: var(--el-color-primary);
box-shadow: 0 0 0 1px var(--el-color-primary-light-7);
}
} }
} }

View File

@@ -2,7 +2,7 @@
<el-dialog <el-dialog
v-model="visible" v-model="visible"
title="实施采购" title="实施采购"
width="560px" width="50%"
:close-on-click-modal="false" :close-on-click-modal="false"
destroy-on-close destroy-on-close
class="implement-iframe-dialog" class="implement-iframe-dialog"

View File

@@ -533,8 +533,7 @@ const getActionMenuItems = (row: any) => {
{ {
command: 'implement', command: 'implement',
label: '实施采购', label: '实施采购',
icon: Upload, icon: Upload
visible: () => isTemp,
}, },
{ {
command: 'archive', command: 'archive',