This commit is contained in:
吴红兵
2026-03-03 13:59:57 +08:00
parent d0e4071836
commit 168e134e1b
5 changed files with 642 additions and 20 deletions

View File

@@ -121,12 +121,17 @@
</div>
</el-form-item>
</el-col>
<el-col :span="24" class="mb12">
<el-form-item label="采购内容" prop="projectContent">
<el-input v-model="dataForm.projectContent" type="textarea" :rows="3" :maxlength="1000" show-word-limit placeholder="请输入采购内容限制1000字" clearable :disabled="flowFieldDisabled('projectContent')" />
</el-form-item>
</el-col>
<el-col :span="8" class="mb12" v-if="isPurchaseType(DEPT_PURCHASE_TYPE.BUSINESS_NEGOTIATION)">
<el-col :span="24" class="mb12">
<el-form-item label="采购内容" prop="projectContent">
<el-input v-model="dataForm.projectContent" type="textarea" :rows="3" :maxlength="1000" show-word-limit placeholder="请输入采购内容限制1000字" clearable :disabled="flowFieldDisabled('projectContent')" />
</el-form-item>
</el-col>
<el-col :span="24" class="mb12" v-if="isPurchaseType(DEPT_PURCHASE_TYPE.BUSINESS_NEGOTIATION)">
<el-form-item label="洽谈理由" prop="negotiationReason" required>
<el-input v-model="dataForm.negotiationReason" type="textarea" :rows="3" :maxlength="500" show-word-limit placeholder="请输入洽谈理由限制500字" clearable :disabled="flowFieldDisabled('negotiationReason')" />
</el-form-item>
</el-col>
<el-col :span="8" class="mb12" v-if="isPurchaseType(DEPT_PURCHASE_TYPE.BUSINESS_NEGOTIATION)">
<el-form-item label="商务洽谈表" prop="businessNegotiationTable" required>
<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" :disabled="flowFieldDisabled('businessNegotiationTable')" />
<el-button type="primary" link icon="Download" size="small" @click="downloadTemplate('business_negotiation')" style="margin-top: 8px; display: inline-block">下载商务洽谈表模版</el-button>
@@ -517,6 +522,7 @@ import { addObj, tempStore, getObj, editObj, getApplyFiles } from '/@/api/purcha
import { getTree } from '/@/api/purchase/purchasingcategory';
import { getDicts } from '/@/api/admin/dict';
import { useMessage } from '/@/hooks/message';
import { usePurchaseRulesSingleton } from '/@/hooks/usePurchaseRules';
import UploadFile from '/@/components/Upload/index.vue';
import other from '/@/utils/other';
import { Document, Download, QuestionFilled } from '@element-plus/icons-vue';
@@ -656,7 +662,8 @@ const dataForm = reactive({
agentId: '',
agentName: '',
representorName:'',
representorType: ''
representorType: '',
negotiationReason: ''
});
/** 查看时展示的招标文件列表(实施采购上传的 type=130 */
const viewImplementPurchaseFiles = ref<{ id: string; fileTitle?: string; createTime?: string; remark?: string }[]>([]);
@@ -714,11 +721,13 @@ Object.entries(FILE_TYPE_MAP).forEach(([field, type]) => {
FILE_TYPE_TO_FIELDS[type].push(field);
});
// 金额阈值常量(与后端 PurchaseConstants 保持一致)
const BUDGET_DEPT_PURCHASE_THRESHOLD = 50000; // 部门自行采购上限(< 5 万)
const BUDGET_FEASIBILITY_THRESHOLD = 300000; // 可行性论证/会议纪要起点(≥ 30 万)
const BUDGET_PUBLIC_SELECT_THRESHOLD = 400000; // 公开比选起点(≥ 40 万)
const BUDGET_GOV_PURCHASE_THRESHOLD = 1000000; // 政府采购起点(≥ 100 万)
// 金额阈值(从规则配置动态获取,默认值与后端 PurchaseConstants 保持一致)
const { rules: purchaseRules, getThresholds, evaluate: evaluatePurchaseRules } = usePurchaseRulesSingleton();
const BUDGET_DEPT_PURCHASE_THRESHOLD = computed(() => getThresholds().deptPurchase || 50000);
const BUDGET_FEASIBILITY_THRESHOLD = computed(() => getThresholds().feasibility || 300000);
const BUDGET_PUBLIC_SELECT_THRESHOLD = computed(() => getThresholds().publicSelect || 400000);
const BUDGET_GOV_PURCHASE_THRESHOLD = computed(() => getThresholds().govPurchase || 1000000);
// 部门采购方式字典 value与 DeptPurchaseTypeEnum 一致)
const DEPT_PURCHASE_TYPE = {
@@ -775,7 +784,7 @@ const isDeptPurchase = computed(() => {
return !!(isSpecialNoValue && isCentralizedNoValue &&
dataForm.isSpecial === isSpecialNoValue &&
dataForm.isCentralized === isCentralizedNoValue &&
dataForm.budget && dataForm.budget < 50000);
dataForm.budget && dataForm.budget < BUDGET_DEPT_PURCHASE_THRESHOLD.value);
});
// 是否为“委托采购中心采购”途径
@@ -795,8 +804,8 @@ const showPurchaseDetailBlocks = computed(() => {
const schoolUnifiedPurchaseFormDefault = computed(() => {
if (isDeptPurchase.value || dataForm.budget == null) return null;
const budget = Number(dataForm.budget);
if (budget >= BUDGET_GOV_PURCHASE_THRESHOLD) return '1'; // 政府采购
if (budget >= BUDGET_DEPT_PURCHASE_THRESHOLD && budget < BUDGET_GOV_PURCHASE_THRESHOLD) {
if (budget >= BUDGET_GOV_PURCHASE_THRESHOLD.value) return '1'; // 政府采购
if (budget >= BUDGET_DEPT_PURCHASE_THRESHOLD.value && budget < BUDGET_GOV_PURCHASE_THRESHOLD.value) {
if (dataForm.isCentralized === '0') return '2'; // 集采=否 → 学校自主采购
if (dataForm.isCentralized === '1') return '1'; // 政府集中采购 → 政府采购
if (dataForm.isCentralized === '2') return '2'; // 学校集中采购 → 学校自主采购
@@ -959,7 +968,7 @@ watch(
const isAutoSelectPurchaseType = computed(() => {
if (!dataForm.budget) return false;
const budget = dataForm.budget;
return budget >= BUDGET_DEPT_PURCHASE_THRESHOLD && budget < BUDGET_PUBLIC_SELECT_THRESHOLD && isServiceCategory.value && isSpecialServiceCategory.value;
return budget >= BUDGET_DEPT_PURCHASE_THRESHOLD.value && budget < BUDGET_PUBLIC_SELECT_THRESHOLD.value && isServiceCategory.value && isSpecialServiceCategory.value;
});
// 判断是否显示自动邀请比选模版5万<=金额<40万服务类目特殊服务类目
@@ -967,7 +976,7 @@ const showAutoInviteSelect = computed(() => {
if (!isDeptPurchase.value) return false;
if (!dataForm.budget) return false;
const budget = dataForm.budget;
return budget >= BUDGET_DEPT_PURCHASE_THRESHOLD && budget < BUDGET_PUBLIC_SELECT_THRESHOLD && isServiceCategory.value && isSpecialServiceCategory.value;
return budget >= BUDGET_DEPT_PURCHASE_THRESHOLD.value && budget < BUDGET_PUBLIC_SELECT_THRESHOLD.value && isServiceCategory.value && isSpecialServiceCategory.value;
});
// 判断是否显示学校统一采购的自动邀请比选模版5万<=金额<40万服务类目特殊服务类目
@@ -975,7 +984,7 @@ const showAutoInviteSelectSchool = computed(() => {
if (isDeptPurchase.value) return false;
if (!dataForm.budget) return false;
const budget = dataForm.budget;
return budget >= BUDGET_DEPT_PURCHASE_THRESHOLD && budget < BUDGET_PUBLIC_SELECT_THRESHOLD && isSpecialServiceCategory.value;
return budget >= BUDGET_DEPT_PURCHASE_THRESHOLD.value && budget < BUDGET_PUBLIC_SELECT_THRESHOLD.value && isSpecialServiceCategory.value;
});
// 判断是否显示自动公开比选模版40万<=金额<100万特殊服务类目isMallService=1、isProjectService=1
@@ -983,7 +992,7 @@ const showAutoPublicSelect = computed(() => {
if (isDeptPurchase.value) return false;
if (!dataForm.budget) return false;
const budget = dataForm.budget;
return budget >= BUDGET_PUBLIC_SELECT_THRESHOLD && budget < BUDGET_GOV_PURCHASE_THRESHOLD && isSpecialServiceCategory.value;
return budget >= BUDGET_PUBLIC_SELECT_THRESHOLD.value && budget < BUDGET_GOV_PURCHASE_THRESHOLD.value && isSpecialServiceCategory.value;
});
// 获取需求文件的 prop 名称(用于表单验证)
@@ -1005,7 +1014,7 @@ const isAutoSelectPurchaseTypeUnion = computed(() => {
if (isDeptPurchase.value) return false;
if (!dataForm.budget) return false;
const budget = dataForm.budget;
return budget >= BUDGET_DEPT_PURCHASE_THRESHOLD && budget < BUDGET_PUBLIC_SELECT_THRESHOLD && isSpecialServiceCategory.value;
return budget >= BUDGET_DEPT_PURCHASE_THRESHOLD.value && budget < BUDGET_PUBLIC_SELECT_THRESHOLD.value && isSpecialServiceCategory.value;
});
// 监听品目编码、预算金额、采购类型及采购途径变化,自动设置/清空采购方式
@@ -1217,6 +1226,20 @@ const dataRules = reactive({
trigger: 'change'
}
],
negotiationReason: [
{
validator: (_rule: any, value: string, callback: (e?: Error) => void) => {
if (isPurchaseType(DEPT_PURCHASE_TYPE.BUSINESS_NEGOTIATION)) {
if (!value || String(value).trim() === '') {
callback(new Error('采购方式为商务洽谈时,洽谈理由不能为空'));
return;
}
}
callback();
},
trigger: 'blur'
}
],
});
// 取消
@@ -1298,6 +1321,7 @@ async function loadDetail(applyId: string | number) {
agentName: detail.agentName ?? '',
representorName: detail.representorName ?? '',
representorType: detail.representorType ?? '',
negotiationReason: detail.negotiationReason ?? '',
});
setCategoryCodePath();
try {