修改流程 修改打包报错
This commit is contained in:
BIN
src/assets/file/服务商城项目需求模板(公开比选).doc
Normal file
BIN
src/assets/file/服务商城项目需求模板(公开比选).doc
Normal file
Binary file not shown.
BIN
src/assets/file/服务商城项目需求模板(直选).doc
Normal file
BIN
src/assets/file/服务商城项目需求模板(直选).doc
Normal file
Binary file not shown.
BIN
src/assets/file/服务商城项目需求模板(邀请比选).doc
Normal file
BIN
src/assets/file/服务商城项目需求模板(邀请比选).doc
Normal file
Binary file not shown.
BIN
src/assets/file/表6:项目可行性论证报告模板.doc
Normal file
BIN
src/assets/file/表6:项目可行性论证报告模板.doc
Normal file
Binary file not shown.
BIN
src/assets/file/表7:单一来源论专家证附件.docx
Normal file
BIN
src/assets/file/表7:单一来源论专家证附件.docx
Normal file
Binary file not shown.
BIN
src/assets/file/附件1:进口产品申请及专家论证意见表.doc
Normal file
BIN
src/assets/file/附件1:进口产品申请及专家论证意见表.doc
Normal file
Binary file not shown.
@@ -2,15 +2,24 @@
|
||||
<el-dialog
|
||||
:title="dialogTitle"
|
||||
v-model="visible"
|
||||
width="900px"
|
||||
width="1000px"
|
||||
:close-on-click-modal="false"
|
||||
draggable>
|
||||
<div v-loading="loading">
|
||||
<!-- 步骤条 -->
|
||||
<el-steps :active="currentStep" finish-status="success" style="margin-bottom: 30px;">
|
||||
<el-step title="基本信息" />
|
||||
<el-step :title="stepTwoTitle" />
|
||||
</el-steps>
|
||||
|
||||
<el-form
|
||||
ref="formRef"
|
||||
:model="dataForm"
|
||||
:rules="dataRules"
|
||||
label-width="140px"
|
||||
v-loading="loading">
|
||||
label-width="140px">
|
||||
|
||||
<!-- 第一步:基本信息 -->
|
||||
<div v-show="currentStep === 0">
|
||||
<el-row :gutter="24">
|
||||
<el-col :span="12" class="mb20">
|
||||
<el-form-item label="采购项目名称" prop="projectName">
|
||||
@@ -21,36 +30,6 @@
|
||||
:disabled="isView" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12" class="mb20">
|
||||
<el-form-item label="项目类别" prop="projectType">
|
||||
<el-select
|
||||
v-model="dataForm.projectType"
|
||||
placeholder="请选择项目类别"
|
||||
clearable
|
||||
:disabled="isView"
|
||||
style="width: 100%">
|
||||
<el-option label="货物" value="A" />
|
||||
<el-option label="工程" value="B" />
|
||||
<el-option label="服务" value="C" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="24">
|
||||
<el-col :span="12" class="mb20">
|
||||
<el-form-item label="品目编码" prop="categoryCode">
|
||||
<el-tree-select
|
||||
v-model="dataForm.categoryCode"
|
||||
:data="categoryTreeData"
|
||||
:props="{ value: 'code', label: 'name', children: 'children' }"
|
||||
placeholder="请选择品目编码"
|
||||
clearable
|
||||
check-strictly
|
||||
:render-after-expand="false"
|
||||
:disabled="isView"
|
||||
style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12" class="mb20">
|
||||
<el-form-item label="填报日期" prop="applyDate">
|
||||
<el-date-picker
|
||||
@@ -64,23 +43,21 @@
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-form-item label="采购内容" prop="projectContent" class="mb20">
|
||||
<el-input
|
||||
v-model="dataForm.projectContent"
|
||||
type="textarea"
|
||||
:rows="3"
|
||||
placeholder="请输入采购内容"
|
||||
clearable
|
||||
:disabled="isView" />
|
||||
</el-form-item>
|
||||
<el-row :gutter="24">
|
||||
<el-col :span="12" class="mb20">
|
||||
<el-form-item label="资金来源" prop="fundSource">
|
||||
<el-input
|
||||
<el-select
|
||||
v-model="dataForm.fundSource"
|
||||
placeholder="请输入资金来源"
|
||||
placeholder="请选择资金来源"
|
||||
clearable
|
||||
:disabled="isView" />
|
||||
:disabled="isView"
|
||||
style="width: 100%">
|
||||
<el-option
|
||||
v-for="item in fundSourceList"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12" class="mb20">
|
||||
@@ -104,8 +81,11 @@
|
||||
clearable
|
||||
:disabled="isView"
|
||||
style="width: 100%">
|
||||
<el-option label="否" value="0" />
|
||||
<el-option label="是" value="1" />
|
||||
<el-option
|
||||
v-for="item in isCentralizedList"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
@@ -126,49 +106,214 @@
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="24">
|
||||
<el-col :span="12" class="mb20">
|
||||
<el-form-item label="采购形式" prop="purchaseMode">
|
||||
<el-select
|
||||
v-model="dataForm.purchaseMode"
|
||||
placeholder="请选择采购形式"
|
||||
<el-col :span="24" class="mb20">
|
||||
<el-form-item label="品目编码" prop="categoryCode">
|
||||
<el-tree-select
|
||||
v-model="dataForm.categoryCode"
|
||||
:data="categoryTreeData"
|
||||
:props="{ value: 'code', label: 'name', children: 'children' }"
|
||||
placeholder="请选择品目编码(包含项目类别)"
|
||||
clearable
|
||||
check-strictly
|
||||
:render-after-expand="false"
|
||||
:disabled="isView"
|
||||
style="width: 100%">
|
||||
<el-option label="部门自行采购" value="0" />
|
||||
<el-option label="学校统一采购" value="2" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12" class="mb20">
|
||||
<el-form-item label="学校统一采购方式" prop="purchaseSchool">
|
||||
<el-select
|
||||
v-model="dataForm.purchaseSchool"
|
||||
placeholder="请选择学校统一采购方式"
|
||||
clearable
|
||||
:disabled="isView || dataForm.purchaseMode !== '2'"
|
||||
style="width: 100%">
|
||||
<el-option label="无" value="0" />
|
||||
<el-option label="政府采购" value="1" />
|
||||
<el-option label="学校自主采购" value="2" />
|
||||
</el-select>
|
||||
style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-form-item label="采购方式" prop="purchaseType" class="mb20">
|
||||
</div>
|
||||
|
||||
<!-- 第二步:采购详情 -->
|
||||
<div v-show="currentStep === 1">
|
||||
<!-- 分支一:内部自行采购 -->
|
||||
<div v-if="isInternalPurchase">
|
||||
<div class="step-title mb20">内部自行采购</div>
|
||||
<el-form-item label="采购内容" prop="projectContent" class="mb20">
|
||||
<el-input
|
||||
v-model="dataForm.purchaseType"
|
||||
placeholder="请输入采购方式"
|
||||
v-model="dataForm.projectContent"
|
||||
type="textarea"
|
||||
:rows="4"
|
||||
:maxlength="1000"
|
||||
show-word-limit
|
||||
placeholder="请输入采购内容(限制1000字)"
|
||||
clearable
|
||||
:disabled="isView" />
|
||||
</el-form-item>
|
||||
<el-form-item label="附件" prop="fileIds" class="mb20">
|
||||
<el-form-item label="采购方式" prop="purchaseType" class="mb20">
|
||||
<el-select
|
||||
v-model="dataForm.purchaseType"
|
||||
placeholder="请选择采购方式"
|
||||
clearable
|
||||
:disabled="isView"
|
||||
style="width: 100%">
|
||||
<el-option label="网上商城" value="online_mall" />
|
||||
<el-option label="市场采购" value="market_purchase" />
|
||||
<el-option label="商务洽谈" value="business_negotiation" />
|
||||
<el-option label="委托采购中心(服务类网上商城)" value="entrust_service_online" />
|
||||
<el-option label="委托采购中心(其他方式)" value="entrust_other" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<!-- 上传需求模版 -->
|
||||
<el-form-item label="上传需求模版" prop="requirementTemplate" class="mb20">
|
||||
<div v-if="showDefaultRequirementTemplate" class="mb10">
|
||||
<el-button
|
||||
type="primary"
|
||||
link
|
||||
icon="Download"
|
||||
@click="downloadTemplate('default_requirement')"
|
||||
:disabled="isView">
|
||||
下载默认需求表
|
||||
</el-button>
|
||||
</div>
|
||||
<div v-if="showDirectSelectTemplate" class="mb10">
|
||||
<el-button
|
||||
type="primary"
|
||||
link
|
||||
icon="Download"
|
||||
@click="downloadTemplate('direct_select')"
|
||||
:disabled="isView">
|
||||
下载直选模版需求表
|
||||
</el-button>
|
||||
<div class="template-note mt5">
|
||||
<el-text type="info" size="small">
|
||||
如无意向单位,则需要上传公开比选需求模版
|
||||
</el-text>
|
||||
<el-button
|
||||
type="primary"
|
||||
link
|
||||
size="small"
|
||||
icon="Download"
|
||||
@click="downloadTemplate('public_select')"
|
||||
:disabled="isView">
|
||||
下载公开比选需求模版
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="showInviteSelectTemplate" class="mb10">
|
||||
<el-button
|
||||
type="primary"
|
||||
link
|
||||
icon="Download"
|
||||
@click="downloadTemplate('invite_select')"
|
||||
:disabled="isView">
|
||||
下载邀请比选模版
|
||||
</el-button>
|
||||
</div>
|
||||
<upload-file
|
||||
v-model="dataForm.fileIds"
|
||||
v-model="dataForm.requirementTemplate"
|
||||
:limit="5"
|
||||
:disabled="isView"
|
||||
upload-file-url="/purchase/purchasingfiles/upload" />
|
||||
</el-form-item>
|
||||
</div>
|
||||
|
||||
<!-- 分支二:学校统一采购 -->
|
||||
<div v-else>
|
||||
<div class="step-title mb20">学校统一采购</div>
|
||||
<el-form-item label="采购需求表" prop="purchaseRequirement" class="mb20">
|
||||
<upload-file
|
||||
v-model="dataForm.purchaseRequirement"
|
||||
:limit="5"
|
||||
:disabled="isView"
|
||||
upload-file-url="/purchase/purchasingfiles/upload" />
|
||||
</el-form-item>
|
||||
<el-form-item label="会议纪要" prop="meetingMinutes" class="mb20">
|
||||
<upload-file
|
||||
v-model="dataForm.meetingMinutes"
|
||||
:limit="5"
|
||||
:disabled="isView"
|
||||
upload-file-url="/purchase/purchasingfiles/upload" />
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
v-if="dataForm.budget && dataForm.budget >= 300000"
|
||||
label="可行性论证报告"
|
||||
prop="feasibilityReport"
|
||||
class="mb20">
|
||||
<el-button
|
||||
type="primary"
|
||||
link
|
||||
icon="Download"
|
||||
@click="downloadTemplate('feasibility_report')"
|
||||
:disabled="isView"
|
||||
class="mb10">
|
||||
下载《项目可行性论证报告模板.doc》
|
||||
</el-button>
|
||||
<upload-file
|
||||
v-model="dataForm.feasibilityReport"
|
||||
:limit="5"
|
||||
:disabled="isView"
|
||||
upload-file-url="/purchase/purchasingfiles/upload" />
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
v-if="dataForm.isSpecial === '3'"
|
||||
label="进口产品申请及专家论证意见表"
|
||||
prop="importApplication"
|
||||
class="mb20">
|
||||
<el-button
|
||||
type="primary"
|
||||
link
|
||||
icon="Download"
|
||||
@click="downloadTemplate('import_application')"
|
||||
:disabled="isView"
|
||||
class="mb10">
|
||||
下载《进口产品申请及专家论证意见表.doc》
|
||||
</el-button>
|
||||
<upload-file
|
||||
v-model="dataForm.importApplication"
|
||||
:limit="5"
|
||||
:disabled="isView"
|
||||
upload-file-url="/purchase/purchasingfiles/upload" />
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
v-if="dataForm.isSpecial === '2'"
|
||||
label="单一来源论专家证附件"
|
||||
prop="singleSourceProof"
|
||||
class="mb20">
|
||||
<el-button
|
||||
type="primary"
|
||||
link
|
||||
icon="Download"
|
||||
@click="downloadTemplate('single_source')"
|
||||
:disabled="isView"
|
||||
class="mb10">
|
||||
下载《单一来源论专家证附件.docx》
|
||||
</el-button>
|
||||
<upload-file
|
||||
v-model="dataForm.singleSourceProof"
|
||||
:limit="5"
|
||||
:disabled="isView"
|
||||
upload-file-url="/purchase/purchasingfiles/upload" />
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
v-if="dataForm.budget && dataForm.budget >= 1000000"
|
||||
label="政府采购意向申请表"
|
||||
prop="governmentPurchaseIntent"
|
||||
class="mb20">
|
||||
<upload-file
|
||||
v-model="dataForm.governmentPurchaseIntent"
|
||||
:limit="5"
|
||||
:disabled="isView"
|
||||
upload-file-url="/purchase/purchasingfiles/upload" />
|
||||
</el-form-item>
|
||||
<el-form-item label="业务分管处室" prop="businessDept" class="mb20">
|
||||
<el-input
|
||||
v-model="dataForm.businessDept"
|
||||
placeholder="自动绑定分管校领导"
|
||||
clearable
|
||||
:disabled="true" />
|
||||
</el-form-item>
|
||||
<el-form-item label="其他材料" prop="otherMaterials" class="mb20">
|
||||
<upload-file
|
||||
v-model="dataForm.otherMaterials"
|
||||
:limit="10"
|
||||
:disabled="isView"
|
||||
upload-file-url="/purchase/purchasingfiles/upload" />
|
||||
</el-form-item>
|
||||
<el-form-item label="备注" prop="remark">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<el-form-item label="备注" prop="remark" v-if="currentStep === 1">
|
||||
<el-input
|
||||
v-model="dataForm.remark"
|
||||
type="textarea"
|
||||
@@ -178,12 +323,33 @@
|
||||
:disabled="isView" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="visible = false">{{ isView ? '关闭' : '取消' }}</el-button>
|
||||
<template v-if="!isView">
|
||||
<el-button v-if="dataForm.id && dataForm.status === '-1'" type="warning" @click="handleTempStore" :disabled="loading">暂存</el-button>
|
||||
<el-button type="primary" @click="handleSubmit" :disabled="loading">{{ dataForm.id ? '保存' : '提交' }}</el-button>
|
||||
<el-button v-if="currentStep > 0" @click="prevStep">上一步</el-button>
|
||||
<el-button
|
||||
v-if="currentStep < 1"
|
||||
type="primary"
|
||||
@click="nextStep"
|
||||
:disabled="loading">
|
||||
下一步
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="currentStep === 1 && dataForm.id && dataForm.status === '-1'"
|
||||
type="warning"
|
||||
@click="handleTempStore"
|
||||
:disabled="loading">
|
||||
暂存
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="currentStep === 1"
|
||||
type="primary"
|
||||
@click="handleSubmit"
|
||||
:disabled="loading">
|
||||
{{ dataForm.id ? '保存' : '提交' }}
|
||||
</el-button>
|
||||
</template>
|
||||
</span>
|
||||
</template>
|
||||
@@ -191,17 +357,20 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="PurchasingRequisitionForm">
|
||||
import { reactive, ref, nextTick, computed } from 'vue'
|
||||
import { reactive, ref, nextTick, computed, watch } from 'vue'
|
||||
import { getObj, addObj, editObj, tempStore, submitObj } from '/@/api/finance/purchasingrequisition';
|
||||
import { getTree } from '/@/api/finance/purchasingcategory';
|
||||
import { getDicts } from '/@/api/admin/dict';
|
||||
import { useMessage } from '/@/hooks/message';
|
||||
import UploadFile from '/@/components/Upload/index.vue';
|
||||
import other from '/@/utils/other';
|
||||
|
||||
// 定义子组件向父组件传值/事件
|
||||
const emit = defineEmits(['refresh']);
|
||||
|
||||
// 定义变量内容
|
||||
const formRef = ref();
|
||||
const currentStep = ref(0);
|
||||
const dataForm = reactive({
|
||||
id: '',
|
||||
projectName: '',
|
||||
@@ -219,8 +388,20 @@ const dataForm = reactive({
|
||||
fileIds: '',
|
||||
remark: '',
|
||||
status: '',
|
||||
// 第二步新增字段
|
||||
requirementTemplate: '',
|
||||
purchaseRequirement: '',
|
||||
meetingMinutes: '',
|
||||
feasibilityReport: '',
|
||||
importApplication: '',
|
||||
singleSourceProof: '',
|
||||
governmentPurchaseIntent: '',
|
||||
businessDept: '',
|
||||
otherMaterials: '',
|
||||
});
|
||||
const categoryTreeData = ref<any[]>([]);
|
||||
const fundSourceList = ref<any[]>([]);
|
||||
const isCentralizedList = ref<any[]>([]);
|
||||
const visible = ref(false);
|
||||
const loading = ref(false);
|
||||
const dialogType = ref<'add' | 'edit' | 'view'>('add');
|
||||
@@ -233,9 +414,137 @@ const dialogTitle = computed(() => {
|
||||
return '新增采购申请';
|
||||
});
|
||||
|
||||
// 判断是否为内部采购
|
||||
const isInternalPurchase = computed(() => {
|
||||
// 内部采购条件:非集采 + 非特殊 + 金额 < 50000
|
||||
const isNotCentralized = dataForm.isCentralized === '0';
|
||||
const isNotSpecial = dataForm.isSpecial === '0';
|
||||
const isLessThan50000 = dataForm.budget !== null && dataForm.budget < 50000;
|
||||
return isNotCentralized && isNotSpecial && isLessThan50000;
|
||||
});
|
||||
|
||||
// 第二步标题
|
||||
const stepTwoTitle = computed(() => {
|
||||
return isInternalPurchase.value ? '内部自行采购' : '学校统一采购';
|
||||
});
|
||||
|
||||
// 判断是否显示默认需求表(委托采购中心其他方式 + 货物类)
|
||||
const showDefaultRequirementTemplate = computed(() => {
|
||||
return dataForm.purchaseType === 'entrust_other' && getProjectTypeFromCategory() === 'A';
|
||||
});
|
||||
|
||||
// 判断是否显示直选模版(委托采购中心服务类网上商城 + 服务类)
|
||||
const showDirectSelectTemplate = computed(() => {
|
||||
if (dataForm.purchaseType !== 'entrust_service_online') return false;
|
||||
const projectType = getProjectTypeFromCategory();
|
||||
if (projectType !== 'C') return false;
|
||||
// 如果项目类型为服务类,且在约定的特殊服务类目中,且预算金额大于等于5万且小于100万,跳过此规则
|
||||
if (isSpecialServiceCategory() && dataForm.budget && dataForm.budget >= 50000 && dataForm.budget < 1000000) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
// 判断是否显示邀请比选模版(服务类 + 特殊服务类目 + 5万<=金额<100万)
|
||||
const showInviteSelectTemplate = computed(() => {
|
||||
const projectType = getProjectTypeFromCategory();
|
||||
if (projectType !== 'C') return false;
|
||||
return isSpecialServiceCategory() && dataForm.budget && dataForm.budget >= 50000 && dataForm.budget < 1000000;
|
||||
});
|
||||
|
||||
// 从品目编码中获取项目类型(A:货物, B:工程, C:服务)
|
||||
const getProjectTypeFromCategory = (): string => {
|
||||
// 这里需要根据实际的品目编码数据结构来判断
|
||||
// 假设品目编码的前缀或某个字段包含项目类型信息
|
||||
// 暂时返回空,需要根据实际数据结构调整
|
||||
if (dataForm.categoryCode) {
|
||||
// 可以根据categoryCode查询categoryTreeData来获取类型
|
||||
const findCategory = (data: any[], code: string): any => {
|
||||
for (const item of data) {
|
||||
if (item.code === code) {
|
||||
return item;
|
||||
}
|
||||
if (item.children && item.children.length > 0) {
|
||||
const found = findCategory(item.children, code);
|
||||
if (found) return found;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
};
|
||||
const category = findCategory(categoryTreeData.value, dataForm.categoryCode);
|
||||
// 假设category对象有type字段,或者根据name判断
|
||||
// 这里需要根据实际数据结构调整
|
||||
return dataForm.projectType || '';
|
||||
}
|
||||
return dataForm.projectType || '';
|
||||
};
|
||||
|
||||
// 判断是否为特殊服务类目(需要根据实际业务规则判断)
|
||||
const isSpecialServiceCategory = (): boolean => {
|
||||
// 这里需要根据实际的特殊服务类目列表来判断
|
||||
// 暂时返回false,需要根据实际业务规则调整
|
||||
return false;
|
||||
};
|
||||
|
||||
// 下载模版
|
||||
const downloadTemplate = async (type: string) => {
|
||||
const templateMap: Record<string, { fileName: string, displayName: string }> = {
|
||||
'default_requirement': { fileName: '服务商城项目需求模板(直选).doc', displayName: '默认需求表.doc' },
|
||||
'direct_select': { fileName: '服务商城项目需求模板(直选).doc', displayName: '直选模版需求表.doc' },
|
||||
'public_select': { fileName: '服务商城项目需求模板(公开比选).doc', displayName: '公开比选需求模版.doc' },
|
||||
'invite_select': { fileName: '服务商城项目需求模板(邀请比选).doc', displayName: '邀请比选模版.doc' },
|
||||
'import_application': { fileName: '附件1:进口产品申请及专家论证意见表.doc', displayName: '进口产品申请及专家论证意见表.doc' },
|
||||
'single_source': { fileName: '表7:单一来源论专家证附件.docx', displayName: '单一来源论专家证附件.docx' },
|
||||
'feasibility_report': { fileName: '表6:项目可行性论证报告模板.doc', displayName: '项目可行性论证报告模板.doc' },
|
||||
};
|
||||
|
||||
const template = templateMap[type];
|
||||
if (!template) {
|
||||
useMessage().error('模版不存在');
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
// 如果模版在assets/file目录下
|
||||
const fileUrl = new URL(`../../assets/file/${template.fileName}`, import.meta.url).href;
|
||||
const response = await fetch(fileUrl);
|
||||
if (!response.ok) {
|
||||
throw new Error('文件下载失败');
|
||||
}
|
||||
const blob = await response.blob();
|
||||
const url = window.URL.createObjectURL(blob);
|
||||
const link = document.createElement('a');
|
||||
link.href = url;
|
||||
link.download = template.displayName;
|
||||
document.body.appendChild(link);
|
||||
link.click();
|
||||
window.URL.revokeObjectURL(url);
|
||||
document.body.removeChild(link);
|
||||
useMessage().success('模版下载成功');
|
||||
} catch (error) {
|
||||
// 如果本地文件不存在,尝试从后端下载
|
||||
try {
|
||||
await other.downBlobFile(
|
||||
`/purchase/purchasingfiles/downloadTemplate?type=${type}`,
|
||||
{},
|
||||
template.displayName
|
||||
);
|
||||
useMessage().success('模版下载成功');
|
||||
} catch (err) {
|
||||
useMessage().error('模版下载失败,请先维护模版文件');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const dataRules = reactive({
|
||||
projectContent: [
|
||||
{ required: true, message: '采购内容不能为空', trigger: 'blur' }
|
||||
projectName: [
|
||||
{ required: true, message: '采购项目名称不能为空', trigger: 'blur' }
|
||||
],
|
||||
applyDate: [
|
||||
{ required: true, message: '填报日期不能为空', trigger: 'change' }
|
||||
],
|
||||
fundSource: [
|
||||
{ required: true, message: '资金来源不能为空', trigger: 'change' }
|
||||
],
|
||||
budget: [
|
||||
{ required: true, message: '预算金额不能为空', trigger: 'blur' },
|
||||
@@ -247,32 +556,75 @@ const dataRules = reactive({
|
||||
isSpecial: [
|
||||
{ required: true, message: '请选择是否特殊情况', trigger: 'change' }
|
||||
],
|
||||
categoryCode: [
|
||||
{ required: true, message: '品目编码不能为空', trigger: 'change' }
|
||||
],
|
||||
projectContent: [
|
||||
{ required: true, message: '采购内容不能为空', trigger: 'blur' },
|
||||
{ max: 1000, message: '采购内容不能超过1000字', trigger: 'blur' }
|
||||
],
|
||||
purchaseType: [
|
||||
{ required: true, message: '请选择采购方式', trigger: 'change' }
|
||||
],
|
||||
});
|
||||
|
||||
// 下一步
|
||||
const nextStep = async () => {
|
||||
try {
|
||||
// 验证第一步的必填项
|
||||
const fieldsToValidate = ['projectName', 'applyDate', 'fundSource', 'budget', 'isCentralized', 'isSpecial', 'categoryCode'];
|
||||
await formRef.value?.validateField(fieldsToValidate);
|
||||
currentStep.value = 1;
|
||||
} catch (error) {
|
||||
useMessage().warning('请完善第一步信息');
|
||||
}
|
||||
};
|
||||
|
||||
// 上一步
|
||||
const prevStep = () => {
|
||||
currentStep.value = 0;
|
||||
};
|
||||
|
||||
// 打开弹窗
|
||||
const openDialog = async (type: 'add' | 'edit' | 'view', rowData?: any) => {
|
||||
dialogType.value = type;
|
||||
visible.value = true;
|
||||
currentStep.value = 0;
|
||||
|
||||
// 重置表单
|
||||
dataForm.id = '';
|
||||
dataForm.projectName = '';
|
||||
dataForm.projectType = '';
|
||||
dataForm.projectContent = '';
|
||||
dataForm.applyDate = '';
|
||||
dataForm.fundSource = '';
|
||||
dataForm.budget = null;
|
||||
dataForm.isCentralized = '';
|
||||
dataForm.isSpecial = '';
|
||||
dataForm.purchaseMode = '';
|
||||
dataForm.purchaseSchool = '';
|
||||
dataForm.purchaseType = '';
|
||||
dataForm.categoryCode = '';
|
||||
dataForm.fileIds = '';
|
||||
dataForm.remark = '';
|
||||
dataForm.status = '';
|
||||
Object.assign(dataForm, {
|
||||
id: '',
|
||||
projectName: '',
|
||||
projectType: '',
|
||||
projectContent: '',
|
||||
applyDate: '',
|
||||
fundSource: '',
|
||||
budget: null,
|
||||
isCentralized: '',
|
||||
isSpecial: '',
|
||||
purchaseMode: '',
|
||||
purchaseSchool: '',
|
||||
purchaseType: '',
|
||||
categoryCode: '',
|
||||
fileIds: '',
|
||||
remark: '',
|
||||
status: '',
|
||||
requirementTemplate: '',
|
||||
purchaseRequirement: '',
|
||||
meetingMinutes: '',
|
||||
feasibilityReport: '',
|
||||
importApplication: '',
|
||||
singleSourceProof: '',
|
||||
governmentPurchaseIntent: '',
|
||||
businessDept: '',
|
||||
otherMaterials: '',
|
||||
});
|
||||
|
||||
await getCategoryTreeData();
|
||||
await Promise.all([
|
||||
getCategoryTreeData(),
|
||||
getFundSourceDict(),
|
||||
getIsCentralizedDict(),
|
||||
]);
|
||||
|
||||
nextTick(() => {
|
||||
formRef.value?.resetFields();
|
||||
@@ -297,7 +649,20 @@ const openDialog = async (type: 'add' | 'edit' | 'view', rowData?: any) => {
|
||||
fileIds: res.data.fileIds ? (Array.isArray(res.data.fileIds) ? res.data.fileIds.join(',') : res.data.fileIds) : '',
|
||||
remark: res.data.remark || '',
|
||||
status: res.data.status || '',
|
||||
requirementTemplate: res.data.requirementTemplate || '',
|
||||
purchaseRequirement: res.data.purchaseRequirement || '',
|
||||
meetingMinutes: res.data.meetingMinutes || '',
|
||||
feasibilityReport: res.data.feasibilityReport || '',
|
||||
importApplication: res.data.importApplication || '',
|
||||
singleSourceProof: res.data.singleSourceProof || '',
|
||||
governmentPurchaseIntent: res.data.governmentPurchaseIntent || '',
|
||||
businessDept: res.data.businessDept || '',
|
||||
otherMaterials: res.data.otherMaterials || '',
|
||||
});
|
||||
// 编辑或查看时,直接显示第二步
|
||||
if (type === 'edit' || type === 'view') {
|
||||
currentStep.value = 1;
|
||||
}
|
||||
})
|
||||
.catch((err: any) => {
|
||||
useMessage().error(err.msg || '获取详情失败');
|
||||
@@ -323,38 +688,75 @@ const getCategoryTreeData = async () => {
|
||||
}
|
||||
};
|
||||
|
||||
// 处理文件ID字符串转数组
|
||||
// 从URL中提取文件ID,URL格式通常为: /admin/sys-file/show?fileName=xxx&id=xxx
|
||||
const getFileIdsArray = (): string[] => {
|
||||
if (!dataForm.fileIds) return [];
|
||||
if (Array.isArray(dataForm.fileIds)) return dataForm.fileIds;
|
||||
// 获取资金来源字典
|
||||
const getFundSourceDict = async () => {
|
||||
try {
|
||||
const res = await getDicts('fund_source');
|
||||
fundSourceList.value = [];
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
fundSourceList.value = res.data.map((item: any) => ({
|
||||
label: item.label || item.dictLabel || item.name,
|
||||
value: item.value || item.dictValue || item.code
|
||||
}));
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取资金来源字典失败', err);
|
||||
}
|
||||
};
|
||||
|
||||
// 如果是逗号分隔的URL字符串,需要从URL中提取文件ID
|
||||
const urls = dataForm.fileIds.split(',').filter(url => url.trim());
|
||||
const fileIds: string[] = [];
|
||||
// 获取是否集采字典
|
||||
const getIsCentralizedDict = async () => {
|
||||
try {
|
||||
const res = await getDicts('is_centralized');
|
||||
isCentralizedList.value = [];
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
isCentralizedList.value = res.data.map((item: any) => ({
|
||||
label: item.label || item.dictLabel || item.name,
|
||||
value: item.value || item.dictValue || item.code
|
||||
}));
|
||||
} else {
|
||||
// 如果没有字典数据,使用默认值
|
||||
isCentralizedList.value = [
|
||||
{ label: '否', value: '0' },
|
||||
{ label: '是', value: '1' }
|
||||
];
|
||||
}
|
||||
} catch (err) {
|
||||
// 如果获取失败,使用默认值
|
||||
isCentralizedList.value = [
|
||||
{ label: '否', value: '0' },
|
||||
{ label: '是', value: '1' }
|
||||
];
|
||||
}
|
||||
};
|
||||
|
||||
// 处理文件ID字符串转数组
|
||||
const getFileIdsArray = (fileIds: string | string[]): string[] => {
|
||||
if (!fileIds) return [];
|
||||
if (Array.isArray(fileIds)) return fileIds;
|
||||
|
||||
const urls = fileIds.split(',').filter(url => url.trim());
|
||||
const ids: string[] = [];
|
||||
|
||||
urls.forEach(url => {
|
||||
try {
|
||||
// 尝试从URL参数中提取id
|
||||
const urlObj = new URL(url, window.location.origin);
|
||||
const id = urlObj.searchParams.get('id') || urlObj.searchParams.get('fileName');
|
||||
if (id) {
|
||||
fileIds.push(id);
|
||||
ids.push(id);
|
||||
} else {
|
||||
// 如果没有id参数,尝试从路径中提取
|
||||
const pathParts = urlObj.pathname.split('/');
|
||||
const lastPart = pathParts[pathParts.length - 1];
|
||||
if (lastPart) {
|
||||
fileIds.push(lastPart);
|
||||
ids.push(lastPart);
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
// 如果URL解析失败,直接使用原始值
|
||||
fileIds.push(url);
|
||||
ids.push(url);
|
||||
}
|
||||
});
|
||||
|
||||
return fileIds;
|
||||
return ids;
|
||||
};
|
||||
|
||||
// 提交(新增或编辑)
|
||||
@@ -371,15 +773,21 @@ const handleSubmit = async () => {
|
||||
|
||||
const submitData = {
|
||||
...dataForm,
|
||||
fileIds: getFileIdsArray(),
|
||||
fileIds: getFileIdsArray(dataForm.fileIds),
|
||||
requirementTemplate: getFileIdsArray(dataForm.requirementTemplate),
|
||||
purchaseRequirement: getFileIdsArray(dataForm.purchaseRequirement),
|
||||
meetingMinutes: getFileIdsArray(dataForm.meetingMinutes),
|
||||
feasibilityReport: getFileIdsArray(dataForm.feasibilityReport),
|
||||
importApplication: getFileIdsArray(dataForm.importApplication),
|
||||
singleSourceProof: getFileIdsArray(dataForm.singleSourceProof),
|
||||
governmentPurchaseIntent: getFileIdsArray(dataForm.governmentPurchaseIntent),
|
||||
otherMaterials: getFileIdsArray(dataForm.otherMaterials),
|
||||
};
|
||||
|
||||
if (dataForm.id) {
|
||||
// 编辑
|
||||
await editObj(submitData);
|
||||
useMessage().success('保存成功');
|
||||
} else {
|
||||
// 新增(暂存,不启动流程)
|
||||
await addObj(submitData);
|
||||
useMessage().success('提交成功');
|
||||
}
|
||||
@@ -406,7 +814,15 @@ const handleTempStore = async () => {
|
||||
|
||||
const submitData = {
|
||||
...dataForm,
|
||||
fileIds: getFileIdsArray(),
|
||||
fileIds: getFileIdsArray(dataForm.fileIds),
|
||||
requirementTemplate: getFileIdsArray(dataForm.requirementTemplate),
|
||||
purchaseRequirement: getFileIdsArray(dataForm.purchaseRequirement),
|
||||
meetingMinutes: getFileIdsArray(dataForm.meetingMinutes),
|
||||
feasibilityReport: getFileIdsArray(dataForm.feasibilityReport),
|
||||
importApplication: getFileIdsArray(dataForm.importApplication),
|
||||
singleSourceProof: getFileIdsArray(dataForm.singleSourceProof),
|
||||
governmentPurchaseIntent: getFileIdsArray(dataForm.governmentPurchaseIntent),
|
||||
otherMaterials: getFileIdsArray(dataForm.otherMaterials),
|
||||
};
|
||||
|
||||
await tempStore(submitData);
|
||||
@@ -430,5 +846,21 @@ defineExpose({
|
||||
.mb20 {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.mb10 {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.mt5 {
|
||||
margin-top: 5px;
|
||||
}
|
||||
.step-title {
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
color: var(--el-text-color-primary);
|
||||
padding-bottom: 10px;
|
||||
border-bottom: 1px solid var(--el-border-color-light);
|
||||
}
|
||||
.template-note {
|
||||
margin-top: 5px;
|
||||
color: var(--el-text-color-secondary);
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user