修改流程 修改打包报错
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,188 +2,354 @@
|
|||||||
<el-dialog
|
<el-dialog
|
||||||
:title="dialogTitle"
|
:title="dialogTitle"
|
||||||
v-model="visible"
|
v-model="visible"
|
||||||
width="900px"
|
width="1000px"
|
||||||
:close-on-click-modal="false"
|
:close-on-click-modal="false"
|
||||||
draggable>
|
draggable>
|
||||||
<el-form
|
<div v-loading="loading">
|
||||||
ref="formRef"
|
<!-- 步骤条 -->
|
||||||
:model="dataForm"
|
<el-steps :active="currentStep" finish-status="success" style="margin-bottom: 30px;">
|
||||||
:rules="dataRules"
|
<el-step title="基本信息" />
|
||||||
label-width="140px"
|
<el-step :title="stepTwoTitle" />
|
||||||
v-loading="loading">
|
</el-steps>
|
||||||
<el-row :gutter="24">
|
|
||||||
<el-col :span="12" class="mb20">
|
<el-form
|
||||||
<el-form-item label="采购项目名称" prop="projectName">
|
ref="formRef"
|
||||||
<el-input
|
:model="dataForm"
|
||||||
v-model="dataForm.projectName"
|
:rules="dataRules"
|
||||||
placeholder="请输入采购项目名称"
|
label-width="140px">
|
||||||
clearable
|
|
||||||
:disabled="isView" />
|
<!-- 第一步:基本信息 -->
|
||||||
</el-form-item>
|
<div v-show="currentStep === 0">
|
||||||
</el-col>
|
<el-row :gutter="24">
|
||||||
<el-col :span="12" class="mb20">
|
<el-col :span="12" class="mb20">
|
||||||
<el-form-item label="项目类别" prop="projectType">
|
<el-form-item label="采购项目名称" prop="projectName">
|
||||||
<el-select
|
<el-input
|
||||||
v-model="dataForm.projectType"
|
v-model="dataForm.projectName"
|
||||||
placeholder="请选择项目类别"
|
placeholder="请输入采购项目名称"
|
||||||
clearable
|
clearable
|
||||||
:disabled="isView"
|
:disabled="isView" />
|
||||||
style="width: 100%">
|
</el-form-item>
|
||||||
<el-option label="货物" value="A" />
|
</el-col>
|
||||||
<el-option label="工程" value="B" />
|
<el-col :span="12" class="mb20">
|
||||||
<el-option label="服务" value="C" />
|
<el-form-item label="填报日期" prop="applyDate">
|
||||||
</el-select>
|
<el-date-picker
|
||||||
</el-form-item>
|
v-model="dataForm.applyDate"
|
||||||
</el-col>
|
type="date"
|
||||||
</el-row>
|
placeholder="请选择填报日期"
|
||||||
<el-row :gutter="24">
|
format="YYYY-MM-DD"
|
||||||
<el-col :span="12" class="mb20">
|
value-format="YYYY-MM-DD"
|
||||||
<el-form-item label="品目编码" prop="categoryCode">
|
:disabled="isView"
|
||||||
<el-tree-select
|
style="width: 100%" />
|
||||||
v-model="dataForm.categoryCode"
|
</el-form-item>
|
||||||
:data="categoryTreeData"
|
</el-col>
|
||||||
:props="{ value: 'code', label: 'name', children: 'children' }"
|
</el-row>
|
||||||
placeholder="请选择品目编码"
|
<el-row :gutter="24">
|
||||||
clearable
|
<el-col :span="12" class="mb20">
|
||||||
check-strictly
|
<el-form-item label="资金来源" prop="fundSource">
|
||||||
:render-after-expand="false"
|
<el-select
|
||||||
:disabled="isView"
|
v-model="dataForm.fundSource"
|
||||||
style="width: 100%" />
|
placeholder="请选择资金来源"
|
||||||
</el-form-item>
|
clearable
|
||||||
</el-col>
|
:disabled="isView"
|
||||||
<el-col :span="12" class="mb20">
|
style="width: 100%">
|
||||||
<el-form-item label="填报日期" prop="applyDate">
|
<el-option
|
||||||
<el-date-picker
|
v-for="item in fundSourceList"
|
||||||
v-model="dataForm.applyDate"
|
:key="item.value"
|
||||||
type="date"
|
:label="item.label"
|
||||||
placeholder="请选择填报日期"
|
:value="item.value" />
|
||||||
format="YYYY-MM-DD"
|
</el-select>
|
||||||
value-format="YYYY-MM-DD"
|
</el-form-item>
|
||||||
:disabled="isView"
|
</el-col>
|
||||||
style="width: 100%" />
|
<el-col :span="12" class="mb20">
|
||||||
</el-form-item>
|
<el-form-item label="预算金额(元)" prop="budget">
|
||||||
</el-col>
|
<el-input-number
|
||||||
</el-row>
|
v-model="dataForm.budget"
|
||||||
<el-form-item label="采购内容" prop="projectContent" class="mb20">
|
:min="0.01"
|
||||||
<el-input
|
:precision="2"
|
||||||
v-model="dataForm.projectContent"
|
placeholder="请输入预算金额"
|
||||||
type="textarea"
|
:disabled="isView"
|
||||||
:rows="3"
|
style="width: 100%" />
|
||||||
placeholder="请输入采购内容"
|
</el-form-item>
|
||||||
clearable
|
</el-col>
|
||||||
:disabled="isView" />
|
</el-row>
|
||||||
</el-form-item>
|
<el-row :gutter="24">
|
||||||
<el-row :gutter="24">
|
<el-col :span="12" class="mb20">
|
||||||
<el-col :span="12" class="mb20">
|
<el-form-item label="是否集采" prop="isCentralized">
|
||||||
<el-form-item label="资金来源" prop="fundSource">
|
<el-select
|
||||||
<el-input
|
v-model="dataForm.isCentralized"
|
||||||
v-model="dataForm.fundSource"
|
placeholder="请选择是否集采"
|
||||||
placeholder="请输入资金来源"
|
clearable
|
||||||
clearable
|
:disabled="isView"
|
||||||
:disabled="isView" />
|
style="width: 100%">
|
||||||
</el-form-item>
|
<el-option
|
||||||
</el-col>
|
v-for="item in isCentralizedList"
|
||||||
<el-col :span="12" class="mb20">
|
:key="item.value"
|
||||||
<el-form-item label="预算金额(元)" prop="budget">
|
:label="item.label"
|
||||||
<el-input-number
|
:value="item.value" />
|
||||||
v-model="dataForm.budget"
|
</el-select>
|
||||||
:min="0.01"
|
</el-form-item>
|
||||||
:precision="2"
|
</el-col>
|
||||||
placeholder="请输入预算金额"
|
<el-col :span="12" class="mb20">
|
||||||
:disabled="isView"
|
<el-form-item label="是否特殊情况" prop="isSpecial">
|
||||||
style="width: 100%" />
|
<el-select
|
||||||
</el-form-item>
|
v-model="dataForm.isSpecial"
|
||||||
</el-col>
|
placeholder="请选择是否特殊情况"
|
||||||
</el-row>
|
clearable
|
||||||
<el-row :gutter="24">
|
:disabled="isView"
|
||||||
<el-col :span="12" class="mb20">
|
style="width: 100%">
|
||||||
<el-form-item label="是否集采" prop="isCentralized">
|
<el-option label="否" value="0" />
|
||||||
<el-select
|
<el-option label="紧急" value="1" />
|
||||||
v-model="dataForm.isCentralized"
|
<el-option label="单一" value="2" />
|
||||||
placeholder="请选择是否集采"
|
<el-option label="进口" value="3" />
|
||||||
clearable
|
</el-select>
|
||||||
:disabled="isView"
|
</el-form-item>
|
||||||
style="width: 100%">
|
</el-col>
|
||||||
<el-option label="否" value="0" />
|
</el-row>
|
||||||
<el-option label="是" value="1" />
|
<el-row :gutter="24">
|
||||||
</el-select>
|
<el-col :span="24" class="mb20">
|
||||||
</el-form-item>
|
<el-form-item label="品目编码" prop="categoryCode">
|
||||||
</el-col>
|
<el-tree-select
|
||||||
<el-col :span="12" class="mb20">
|
v-model="dataForm.categoryCode"
|
||||||
<el-form-item label="是否特殊情况" prop="isSpecial">
|
:data="categoryTreeData"
|
||||||
<el-select
|
:props="{ value: 'code', label: 'name', children: 'children' }"
|
||||||
v-model="dataForm.isSpecial"
|
placeholder="请选择品目编码(包含项目类别)"
|
||||||
placeholder="请选择是否特殊情况"
|
clearable
|
||||||
clearable
|
check-strictly
|
||||||
:disabled="isView"
|
:render-after-expand="false"
|
||||||
style="width: 100%">
|
:disabled="isView"
|
||||||
<el-option label="否" value="0" />
|
style="width: 100%" />
|
||||||
<el-option label="紧急" value="1" />
|
</el-form-item>
|
||||||
<el-option label="单一" value="2" />
|
</el-col>
|
||||||
<el-option label="进口" value="3" />
|
</el-row>
|
||||||
</el-select>
|
</div>
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
<!-- 第二步:采购详情 -->
|
||||||
</el-row>
|
<div v-show="currentStep === 1">
|
||||||
<el-row :gutter="24">
|
<!-- 分支一:内部自行采购 -->
|
||||||
<el-col :span="12" class="mb20">
|
<div v-if="isInternalPurchase">
|
||||||
<el-form-item label="采购形式" prop="purchaseMode">
|
<div class="step-title mb20">内部自行采购</div>
|
||||||
<el-select
|
<el-form-item label="采购内容" prop="projectContent" class="mb20">
|
||||||
v-model="dataForm.purchaseMode"
|
<el-input
|
||||||
placeholder="请选择采购形式"
|
v-model="dataForm.projectContent"
|
||||||
clearable
|
type="textarea"
|
||||||
:disabled="isView"
|
:rows="4"
|
||||||
style="width: 100%">
|
:maxlength="1000"
|
||||||
<el-option label="部门自行采购" value="0" />
|
show-word-limit
|
||||||
<el-option label="学校统一采购" value="2" />
|
placeholder="请输入采购内容(限制1000字)"
|
||||||
</el-select>
|
clearable
|
||||||
</el-form-item>
|
:disabled="isView" />
|
||||||
</el-col>
|
</el-form-item>
|
||||||
<el-col :span="12" class="mb20">
|
<el-form-item label="采购方式" prop="purchaseType" class="mb20">
|
||||||
<el-form-item label="学校统一采购方式" prop="purchaseSchool">
|
<el-select
|
||||||
<el-select
|
v-model="dataForm.purchaseType"
|
||||||
v-model="dataForm.purchaseSchool"
|
placeholder="请选择采购方式"
|
||||||
placeholder="请选择学校统一采购方式"
|
clearable
|
||||||
clearable
|
:disabled="isView"
|
||||||
:disabled="isView || dataForm.purchaseMode !== '2'"
|
style="width: 100%">
|
||||||
style="width: 100%">
|
<el-option label="网上商城" value="online_mall" />
|
||||||
<el-option label="无" value="0" />
|
<el-option label="市场采购" value="market_purchase" />
|
||||||
<el-option label="政府采购" value="1" />
|
<el-option label="商务洽谈" value="business_negotiation" />
|
||||||
<el-option label="学校自主采购" value="2" />
|
<el-option label="委托采购中心(服务类网上商城)" value="entrust_service_online" />
|
||||||
</el-select>
|
<el-option label="委托采购中心(其他方式)" value="entrust_other" />
|
||||||
</el-form-item>
|
</el-select>
|
||||||
</el-col>
|
</el-form-item>
|
||||||
</el-row>
|
|
||||||
<el-form-item label="采购方式" prop="purchaseType" class="mb20">
|
<!-- 上传需求模版 -->
|
||||||
<el-input
|
<el-form-item label="上传需求模版" prop="requirementTemplate" class="mb20">
|
||||||
v-model="dataForm.purchaseType"
|
<div v-if="showDefaultRequirementTemplate" class="mb10">
|
||||||
placeholder="请输入采购方式"
|
<el-button
|
||||||
clearable
|
type="primary"
|
||||||
:disabled="isView" />
|
link
|
||||||
</el-form-item>
|
icon="Download"
|
||||||
<el-form-item label="附件" prop="fileIds" class="mb20">
|
@click="downloadTemplate('default_requirement')"
|
||||||
<upload-file
|
:disabled="isView">
|
||||||
v-model="dataForm.fileIds"
|
下载默认需求表
|
||||||
:limit="10"
|
</el-button>
|
||||||
:disabled="isView"
|
</div>
|
||||||
upload-file-url="/purchase/purchasingfiles/upload" />
|
<div v-if="showDirectSelectTemplate" class="mb10">
|
||||||
</el-form-item>
|
<el-button
|
||||||
<el-form-item label="备注" prop="remark">
|
type="primary"
|
||||||
<el-input
|
link
|
||||||
v-model="dataForm.remark"
|
icon="Download"
|
||||||
type="textarea"
|
@click="downloadTemplate('direct_select')"
|
||||||
:rows="3"
|
:disabled="isView">
|
||||||
placeholder="请输入备注"
|
下载直选模版需求表
|
||||||
clearable
|
</el-button>
|
||||||
:disabled="isView" />
|
<div class="template-note mt5">
|
||||||
</el-form-item>
|
<el-text type="info" size="small">
|
||||||
</el-form>
|
如无意向单位,则需要上传公开比选需求模版
|
||||||
|
</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.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>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<el-form-item label="备注" prop="remark" v-if="currentStep === 1">
|
||||||
|
<el-input
|
||||||
|
v-model="dataForm.remark"
|
||||||
|
type="textarea"
|
||||||
|
:rows="3"
|
||||||
|
placeholder="请输入备注"
|
||||||
|
clearable
|
||||||
|
:disabled="isView" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</div>
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<span class="dialog-footer">
|
<span class="dialog-footer">
|
||||||
<el-button @click="visible = false">{{ isView ? '关闭' : '取消' }}</el-button>
|
<el-button @click="visible = false">{{ isView ? '关闭' : '取消' }}</el-button>
|
||||||
<template v-if="!isView">
|
<template v-if="!isView">
|
||||||
<el-button v-if="dataForm.id && dataForm.status === '-1'" type="warning" @click="handleTempStore" :disabled="loading">暂存</el-button>
|
<el-button v-if="currentStep > 0" @click="prevStep">上一步</el-button>
|
||||||
<el-button type="primary" @click="handleSubmit" :disabled="loading">{{ dataForm.id ? '保存' : '提交' }}</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>
|
</template>
|
||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
@@ -191,17 +357,20 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts" name="PurchasingRequisitionForm">
|
<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 { getObj, addObj, editObj, tempStore, submitObj } from '/@/api/finance/purchasingrequisition';
|
||||||
import { getTree } from '/@/api/finance/purchasingcategory';
|
import { getTree } from '/@/api/finance/purchasingcategory';
|
||||||
|
import { getDicts } from '/@/api/admin/dict';
|
||||||
import { useMessage } from '/@/hooks/message';
|
import { useMessage } from '/@/hooks/message';
|
||||||
import UploadFile from '/@/components/Upload/index.vue';
|
import UploadFile from '/@/components/Upload/index.vue';
|
||||||
|
import other from '/@/utils/other';
|
||||||
|
|
||||||
// 定义子组件向父组件传值/事件
|
// 定义子组件向父组件传值/事件
|
||||||
const emit = defineEmits(['refresh']);
|
const emit = defineEmits(['refresh']);
|
||||||
|
|
||||||
// 定义变量内容
|
// 定义变量内容
|
||||||
const formRef = ref();
|
const formRef = ref();
|
||||||
|
const currentStep = ref(0);
|
||||||
const dataForm = reactive({
|
const dataForm = reactive({
|
||||||
id: '',
|
id: '',
|
||||||
projectName: '',
|
projectName: '',
|
||||||
@@ -219,8 +388,20 @@ const dataForm = reactive({
|
|||||||
fileIds: '',
|
fileIds: '',
|
||||||
remark: '',
|
remark: '',
|
||||||
status: '',
|
status: '',
|
||||||
|
// 第二步新增字段
|
||||||
|
requirementTemplate: '',
|
||||||
|
purchaseRequirement: '',
|
||||||
|
meetingMinutes: '',
|
||||||
|
feasibilityReport: '',
|
||||||
|
importApplication: '',
|
||||||
|
singleSourceProof: '',
|
||||||
|
governmentPurchaseIntent: '',
|
||||||
|
businessDept: '',
|
||||||
|
otherMaterials: '',
|
||||||
});
|
});
|
||||||
const categoryTreeData = ref<any[]>([]);
|
const categoryTreeData = ref<any[]>([]);
|
||||||
|
const fundSourceList = ref<any[]>([]);
|
||||||
|
const isCentralizedList = ref<any[]>([]);
|
||||||
const visible = ref(false);
|
const visible = ref(false);
|
||||||
const loading = ref(false);
|
const loading = ref(false);
|
||||||
const dialogType = ref<'add' | 'edit' | 'view'>('add');
|
const dialogType = ref<'add' | 'edit' | 'view'>('add');
|
||||||
@@ -233,9 +414,137 @@ const dialogTitle = computed(() => {
|
|||||||
return '新增采购申请';
|
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({
|
const dataRules = reactive({
|
||||||
projectContent: [
|
projectName: [
|
||||||
{ required: true, message: '采购内容不能为空', trigger: 'blur' }
|
{ required: true, message: '采购项目名称不能为空', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
applyDate: [
|
||||||
|
{ required: true, message: '填报日期不能为空', trigger: 'change' }
|
||||||
|
],
|
||||||
|
fundSource: [
|
||||||
|
{ required: true, message: '资金来源不能为空', trigger: 'change' }
|
||||||
],
|
],
|
||||||
budget: [
|
budget: [
|
||||||
{ required: true, message: '预算金额不能为空', trigger: 'blur' },
|
{ required: true, message: '预算金额不能为空', trigger: 'blur' },
|
||||||
@@ -247,32 +556,75 @@ const dataRules = reactive({
|
|||||||
isSpecial: [
|
isSpecial: [
|
||||||
{ required: true, message: '请选择是否特殊情况', trigger: 'change' }
|
{ 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) => {
|
const openDialog = async (type: 'add' | 'edit' | 'view', rowData?: any) => {
|
||||||
dialogType.value = type;
|
dialogType.value = type;
|
||||||
visible.value = true;
|
visible.value = true;
|
||||||
|
currentStep.value = 0;
|
||||||
|
|
||||||
// 重置表单
|
// 重置表单
|
||||||
dataForm.id = '';
|
Object.assign(dataForm, {
|
||||||
dataForm.projectName = '';
|
id: '',
|
||||||
dataForm.projectType = '';
|
projectName: '',
|
||||||
dataForm.projectContent = '';
|
projectType: '',
|
||||||
dataForm.applyDate = '';
|
projectContent: '',
|
||||||
dataForm.fundSource = '';
|
applyDate: '',
|
||||||
dataForm.budget = null;
|
fundSource: '',
|
||||||
dataForm.isCentralized = '';
|
budget: null,
|
||||||
dataForm.isSpecial = '';
|
isCentralized: '',
|
||||||
dataForm.purchaseMode = '';
|
isSpecial: '',
|
||||||
dataForm.purchaseSchool = '';
|
purchaseMode: '',
|
||||||
dataForm.purchaseType = '';
|
purchaseSchool: '',
|
||||||
dataForm.categoryCode = '';
|
purchaseType: '',
|
||||||
dataForm.fileIds = '';
|
categoryCode: '',
|
||||||
dataForm.remark = '';
|
fileIds: '',
|
||||||
dataForm.status = '';
|
remark: '',
|
||||||
|
status: '',
|
||||||
|
requirementTemplate: '',
|
||||||
|
purchaseRequirement: '',
|
||||||
|
meetingMinutes: '',
|
||||||
|
feasibilityReport: '',
|
||||||
|
importApplication: '',
|
||||||
|
singleSourceProof: '',
|
||||||
|
governmentPurchaseIntent: '',
|
||||||
|
businessDept: '',
|
||||||
|
otherMaterials: '',
|
||||||
|
});
|
||||||
|
|
||||||
await getCategoryTreeData();
|
await Promise.all([
|
||||||
|
getCategoryTreeData(),
|
||||||
|
getFundSourceDict(),
|
||||||
|
getIsCentralizedDict(),
|
||||||
|
]);
|
||||||
|
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
formRef.value?.resetFields();
|
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) : '',
|
fileIds: res.data.fileIds ? (Array.isArray(res.data.fileIds) ? res.data.fileIds.join(',') : res.data.fileIds) : '',
|
||||||
remark: res.data.remark || '',
|
remark: res.data.remark || '',
|
||||||
status: res.data.status || '',
|
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) => {
|
.catch((err: any) => {
|
||||||
useMessage().error(err.msg || '获取详情失败');
|
useMessage().error(err.msg || '获取详情失败');
|
||||||
@@ -323,38 +688,75 @@ const getCategoryTreeData = async () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// 处理文件ID字符串转数组
|
// 获取资金来源字典
|
||||||
// 从URL中提取文件ID,URL格式通常为: /admin/sys-file/show?fileName=xxx&id=xxx
|
const getFundSourceDict = async () => {
|
||||||
const getFileIdsArray = (): string[] => {
|
try {
|
||||||
if (!dataForm.fileIds) return [];
|
const res = await getDicts('fund_source');
|
||||||
if (Array.isArray(dataForm.fileIds)) return dataForm.fileIds;
|
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 getIsCentralizedDict = async () => {
|
||||||
const fileIds: string[] = [];
|
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 => {
|
urls.forEach(url => {
|
||||||
try {
|
try {
|
||||||
// 尝试从URL参数中提取id
|
|
||||||
const urlObj = new URL(url, window.location.origin);
|
const urlObj = new URL(url, window.location.origin);
|
||||||
const id = urlObj.searchParams.get('id') || urlObj.searchParams.get('fileName');
|
const id = urlObj.searchParams.get('id') || urlObj.searchParams.get('fileName');
|
||||||
if (id) {
|
if (id) {
|
||||||
fileIds.push(id);
|
ids.push(id);
|
||||||
} else {
|
} else {
|
||||||
// 如果没有id参数,尝试从路径中提取
|
|
||||||
const pathParts = urlObj.pathname.split('/');
|
const pathParts = urlObj.pathname.split('/');
|
||||||
const lastPart = pathParts[pathParts.length - 1];
|
const lastPart = pathParts[pathParts.length - 1];
|
||||||
if (lastPart) {
|
if (lastPart) {
|
||||||
fileIds.push(lastPart);
|
ids.push(lastPart);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch {
|
} catch {
|
||||||
// 如果URL解析失败,直接使用原始值
|
ids.push(url);
|
||||||
fileIds.push(url);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return fileIds;
|
return ids;
|
||||||
};
|
};
|
||||||
|
|
||||||
// 提交(新增或编辑)
|
// 提交(新增或编辑)
|
||||||
@@ -371,15 +773,21 @@ const handleSubmit = async () => {
|
|||||||
|
|
||||||
const submitData = {
|
const submitData = {
|
||||||
...dataForm,
|
...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) {
|
if (dataForm.id) {
|
||||||
// 编辑
|
|
||||||
await editObj(submitData);
|
await editObj(submitData);
|
||||||
useMessage().success('保存成功');
|
useMessage().success('保存成功');
|
||||||
} else {
|
} else {
|
||||||
// 新增(暂存,不启动流程)
|
|
||||||
await addObj(submitData);
|
await addObj(submitData);
|
||||||
useMessage().success('提交成功');
|
useMessage().success('提交成功');
|
||||||
}
|
}
|
||||||
@@ -406,7 +814,15 @@ const handleTempStore = async () => {
|
|||||||
|
|
||||||
const submitData = {
|
const submitData = {
|
||||||
...dataForm,
|
...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);
|
await tempStore(submitData);
|
||||||
@@ -430,5 +846,21 @@ defineExpose({
|
|||||||
.mb20 {
|
.mb20 {
|
||||||
margin-bottom: 20px;
|
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>
|
</style>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user