fix: 优化采购申请页面会议纪要字段及动态配置

1. 统一会议纪要字段名称为校党委会议纪要
2. 部门自行采购会议纪要使用动态配置替代硬编码2000
3. 动态配置获取不到值时直接报错而非使用默认值
4. 调整部门自行采购会议纪要显示条件为金额>=2000
This commit is contained in:
吴红兵
2026-03-04 17:00:37 +08:00
parent 338610dc51
commit 72160787f9
2 changed files with 31 additions and 27 deletions

View File

@@ -1,4 +1,4 @@
import { ref, computed, watch } from 'vue'; import { ref } from 'vue';
import { evaluateRules, getEnabledRules } from '/@/api/purchase/purchasingRuleConfig'; import { evaluateRules, getEnabledRules } from '/@/api/purchase/purchasingRuleConfig';
const RULE_CACHE_KEY = 'purchase_rule_cache'; const RULE_CACHE_KEY = 'purchase_rule_cache';
@@ -65,26 +65,29 @@ export function usePurchaseRules() {
const getThresholds = () => { const getThresholds = () => {
const thresholds: Record<string, number> = { const thresholds: Record<string, number> = {
deptPurchase: 50000, deptPurchase: 0,
feasibility: 300000, feasibility: 0,
publicSelect: 300000, publicSelect: 0,
govPurchase: 1000000 govPurchase: 0,
deptSelfMeetingMinutes: 0
}; };
rules.value.forEach(rule => { const getRuleAmount = (code: string, defaultVal?: number) => {
if (rule.ruleCode === 'DEPT_PURCHASE_THRESHOLD' && rule.amountMax) { const rule = rules.value.find(r => r.ruleCode === code);
thresholds.deptPurchase = Number(rule.amountMax); if (!rule || rule.amountMin === undefined || rule.amountMin === null) {
if (defaultVal === undefined) {
throw new Error(`采购规则配置缺失: ${code},请在系统配置中维护`);
}
return defaultVal;
} }
if (rule.ruleCode === 'FEASIBILITY_REPORT' && rule.amountMin) { return Number(rule.amountMin);
thresholds.feasibility = Number(rule.amountMin); };
}
if (rule.ruleCode === 'PUBLIC_BID_40W_100W' && rule.amountMin) { thresholds.deptPurchase = getRuleAmount('DEPT_PURCHASE_THRESHOLD');
thresholds.publicSelect = Number(rule.amountMin); thresholds.feasibility = getRuleAmount('FEASIBILITY_REPORT');
} thresholds.publicSelect = getRuleAmount('PUBLIC_BID_40W_100W');
if (rule.ruleCode === 'GOV_PURCHASE_THRESHOLD' && rule.amountMin) { thresholds.govPurchase = getRuleAmount('GOV_PURCHASE_THRESHOLD');
thresholds.govPurchase = Number(rule.amountMin); thresholds.deptSelfMeetingMinutes = getRuleAmount('DEPT_SELF_MEETING_MINUTES', 2000);
}
});
return thresholds; return thresholds;
}; };

View File

@@ -154,7 +154,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="8" class="mb12" v-if="dataForm.purchaseChannel === PURCHASE_CHANNEL.SELF && dataForm.budget != null && dataForm.budget < 2000"> <el-col :span="8" class="mb12" v-if="dataForm.purchaseChannel === PURCHASE_CHANNEL.SELF && dataForm.budget != null && dataForm.budget >= BUDGET_DEPT_SELF_MEETING_MINUTES">
<el-form-item label="部门自行采购会议纪要" prop="deptSelfMeetingMinutes" required> <el-form-item label="部门自行采购会议纪要" prop="deptSelfMeetingMinutes" required>
<upload-file v-model="dataForm.deptSelfMeetingMinutes" :limit="1" :file-type="['doc', 'docx', 'pdf']" :data="{ fileType: FILE_TYPE_MAP.deptSelfMeetingMinutes }" upload-file-url="/purchase/purchasingfiles/upload" :disabled="flowFieldDisabled('deptSelfMeetingMinutes')" /> <upload-file v-model="dataForm.deptSelfMeetingMinutes" :limit="1" :file-type="['doc', 'docx', 'pdf']" :data="{ fileType: FILE_TYPE_MAP.deptSelfMeetingMinutes }" upload-file-url="/purchase/purchasingfiles/upload" :disabled="flowFieldDisabled('deptSelfMeetingMinutes')" />
</el-form-item> </el-form-item>
@@ -271,12 +271,12 @@
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="8" class="mb12" v-if="dataForm.budget && dataForm.budget >= BUDGET_FEASIBILITY_THRESHOLD && !isUrgentSpecial && !isSpecialType('2') && !isSpecialType('3')"> <el-col :span="8" class="mb12" v-if="dataForm.budget && dataForm.budget >= BUDGET_FEASIBILITY_THRESHOLD && !isUrgentSpecial && !isSpecialType('2') && !isSpecialType('3')">
<el-form-item label="会议纪要" prop="meetingMinutes" required> <el-form-item label="校党委会议纪要" prop="meetingMinutes" required>
<upload-file v-model="dataForm.meetingMinutes" :limit="1" :file-type="['doc', 'docx', 'pdf']" :data="{ fileType: FILE_TYPE_MAP.meetingMinutes }" upload-file-url="/purchase/purchasingfiles/upload" :disabled="flowFieldDisabled('meetingMinutes')" /> <upload-file v-model="dataForm.meetingMinutes" :limit="1" :file-type="['doc', 'docx', 'pdf']" :data="{ fileType: FILE_TYPE_MAP.meetingMinutes }" upload-file-url="/purchase/purchasingfiles/upload" :disabled="flowFieldDisabled('meetingMinutes')" />
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="8" class="mb12" v-if="isUrgentSpecial"> <el-col :span="8" class="mb12" v-if="isUrgentSpecial">
<el-form-item label="会议纪要" prop="meetingMinutesUrgent" required> <el-form-item label="校党委会议纪要(紧急)" prop="meetingMinutesUrgent" required>
<upload-file v-model="dataForm.meetingMinutesUrgent" :limit="1" :file-type="['doc', 'docx', 'pdf']" :data="{ fileType: FILE_TYPE_MAP.meetingMinutesUrgent }" upload-file-url="/purchase/purchasingfiles/upload" :disabled="flowFieldDisabled('meetingMinutesUrgent')" /> <upload-file v-model="dataForm.meetingMinutesUrgent" :limit="1" :file-type="['doc', 'docx', 'pdf']" :data="{ fileType: FILE_TYPE_MAP.meetingMinutesUrgent }" upload-file-url="/purchase/purchasingfiles/upload" :disabled="flowFieldDisabled('meetingMinutesUrgent')" />
</el-form-item> </el-form-item>
</el-col> </el-col>
@@ -287,7 +287,7 @@
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="8" class="mb12" v-if="isSpecialType('2')"> <el-col :span="8" class="mb12" v-if="isSpecialType('2')">
<el-form-item label="会议纪要" prop="meetingMinutesSingle" required> <el-form-item label="校党委会议纪要" prop="meetingMinutesSingle" required>
<upload-file v-model="dataForm.meetingMinutesSingle" :limit="1" :file-type="['doc', 'docx', 'pdf']" :data="{ fileType: FILE_TYPE_MAP.meetingMinutesSingle }" upload-file-url="/purchase/purchasingfiles/upload" :disabled="flowFieldDisabled('meetingMinutesSingle')" /> <upload-file v-model="dataForm.meetingMinutesSingle" :limit="1" :file-type="['doc', 'docx', 'pdf']" :data="{ fileType: FILE_TYPE_MAP.meetingMinutesSingle }" upload-file-url="/purchase/purchasingfiles/upload" :disabled="flowFieldDisabled('meetingMinutesSingle')" />
</el-form-item> </el-form-item>
</el-col> </el-col>
@@ -298,7 +298,7 @@
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="8" class="mb12" v-if="isSpecialType('3')"> <el-col :span="8" class="mb12" v-if="isSpecialType('3')">
<el-form-item label="会议纪要" prop="meetingMinutesImport" required> <el-form-item label="校党委会议纪要" prop="meetingMinutesImport" required>
<upload-file v-model="dataForm.meetingMinutesImport" :limit="1" :file-type="['doc', 'docx', 'pdf']" :data="{ fileType: FILE_TYPE_MAP.meetingMinutesImport }" upload-file-url="/purchase/purchasingfiles/upload" :disabled="flowFieldDisabled('meetingMinutesImport')" /> <upload-file v-model="dataForm.meetingMinutesImport" :limit="1" :file-type="['doc', 'docx', 'pdf']" :data="{ fileType: FILE_TYPE_MAP.meetingMinutesImport }" upload-file-url="/purchase/purchasingfiles/upload" :disabled="flowFieldDisabled('meetingMinutesImport')" />
</el-form-item> </el-form-item>
</el-col> </el-col>
@@ -725,10 +725,11 @@ Object.entries(FILE_TYPE_MAP).forEach(([field, type]) => {
// 金额阈值(从规则配置动态获取,默认值与后端 PurchaseConstants 保持一致) // 金额阈值(从规则配置动态获取,默认值与后端 PurchaseConstants 保持一致)
const { rules: purchaseRules, getThresholds, evaluate: evaluatePurchaseRules } = usePurchaseRulesSingleton(); const { rules: purchaseRules, getThresholds, evaluate: evaluatePurchaseRules } = usePurchaseRulesSingleton();
const BUDGET_DEPT_PURCHASE_THRESHOLD = computed(() => getThresholds().deptPurchase || 50000); const BUDGET_DEPT_PURCHASE_THRESHOLD = computed(() => getThresholds().deptPurchase);
const BUDGET_FEASIBILITY_THRESHOLD = computed(() => getThresholds().feasibility || 300000); const BUDGET_FEASIBILITY_THRESHOLD = computed(() => getThresholds().feasibility);
const BUDGET_PUBLIC_SELECT_THRESHOLD = computed(() => getThresholds().publicSelect || 400000); const BUDGET_PUBLIC_SELECT_THRESHOLD = computed(() => getThresholds().publicSelect);
const BUDGET_GOV_PURCHASE_THRESHOLD = computed(() => getThresholds().govPurchase || 1000000); const BUDGET_GOV_PURCHASE_THRESHOLD = computed(() => getThresholds().govPurchase);
const BUDGET_DEPT_SELF_MEETING_MINUTES = computed(() => getThresholds().deptSelfMeetingMinutes);
// 部门采购方式字典 value与 DeptPurchaseTypeEnum 一致) // 部门采购方式字典 value与 DeptPurchaseTypeEnum 一致)
const DEPT_PURCHASE_TYPE = { const DEPT_PURCHASE_TYPE = {