This commit is contained in:
2026-02-03 19:18:57 +08:00
parent 777e18a8a5
commit ddab0a9072
3 changed files with 1125 additions and 483 deletions

View File

@@ -21,12 +21,13 @@
ref="formRef" ref="formRef"
:model="dataForm" :model="dataForm"
:rules="dataRules" :rules="dataRules"
label-width="140px"> label-width="120px"
class="compact-form">
<!-- 第一步基本信息 --> <!-- 第一步基本信息 -->
<div v-show="currentStep === 0"> <div v-show="currentStep === 0">
<el-row :gutter="24"> <el-row :gutter="20">
<el-col :span="12" class="mb20"> <el-col :span="12" class="mb16">
<el-form-item label="采购项目名称" prop="projectName"> <el-form-item label="采购项目名称" prop="projectName">
<el-input <el-input
v-model="dataForm.projectName" v-model="dataForm.projectName"
@@ -34,7 +35,7 @@
clearable /> clearable />
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12" class="mb20"> <el-col :span="12" class="mb16">
<el-form-item label="填报日期" prop="applyDate"> <el-form-item label="填报日期" prop="applyDate">
<el-date-picker <el-date-picker
v-model="dataForm.applyDate" v-model="dataForm.applyDate"
@@ -46,8 +47,8 @@
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
<el-row :gutter="24"> <el-row :gutter="20">
<el-col :span="12" class="mb20"> <el-col :span="12" class="mb16">
<el-form-item label="资金来源" prop="fundSource"> <el-form-item label="资金来源" prop="fundSource">
<el-select <el-select
v-model="dataForm.fundSource" v-model="dataForm.fundSource"
@@ -62,19 +63,31 @@
</el-select> </el-select>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12" class="mb20"> <el-col :span="12" class="mb16">
<el-form-item label="预算金额(元)" prop="budget"> <el-form-item label="预算金额" prop="budget">
<div class="budget-input-group">
<el-input-number <el-input-number
v-model="dataForm.budget" v-model="budgetInputValue"
:min="0.01" :min="0.01"
:precision="2" :precision="2"
placeholder="请输入预算金额" :placeholder="getBudgetPlaceholder()"
style="width: 100%" /> :controls="false"
class="budget-input"
@change="handleBudgetChange" />
<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>
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
<el-row :gutter="24"> <el-row :gutter="20">
<el-col :span="12" class="mb20"> <el-col :span="12" class="mb16">
<el-form-item label="是否集采" prop="isCentralized"> <el-form-item label="是否集采" prop="isCentralized">
<el-select <el-select
v-model="dataForm.isCentralized" v-model="dataForm.isCentralized"
@@ -89,7 +102,7 @@
</el-select> </el-select>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12" class="mb20"> <el-col :span="12" class="mb16">
<el-form-item label="是否特殊情况" prop="isSpecial"> <el-form-item label="是否特殊情况" prop="isSpecial">
<el-select <el-select
v-model="dataForm.isSpecial" v-model="dataForm.isSpecial"
@@ -105,8 +118,8 @@
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
<el-row :gutter="24"> <el-row :gutter="20">
<el-col :span="24" class="mb20"> <el-col :span="24" class="mb16">
<el-form-item label="品目编码" prop="categoryCode"> <el-form-item label="品目编码" prop="categoryCode">
<el-cascader <el-cascader
v-model="categoryCodePath" v-model="categoryCodePath"
@@ -127,18 +140,18 @@
<div v-show="currentStep === 1"> <div v-show="currentStep === 1">
<!-- 分支一部门自行采购 --> <!-- 分支一部门自行采购 -->
<div class="mb20" v-if="isDeptPurchase"> <div class="mb20" v-if="isDeptPurchase">
<div class="step-title mb20">部门自行采购</div> <div class="step-title mb16">部门自行采购</div>
<el-form-item label="采购内容" prop="projectContent" class="mb20"> <el-form-item label="采购内容" prop="projectContent" class="mb16">
<el-input <el-input
v-model="dataForm.projectContent" v-model="dataForm.projectContent"
type="textarea" type="textarea"
:rows="4" :rows="3"
:maxlength="1000" :maxlength="1000"
show-word-limit show-word-limit
placeholder="请输入采购内容限制1000字" placeholder="请输入采购内容限制1000字"
clearable /> clearable />
</el-form-item> </el-form-item>
<el-form-item label="采购方式" prop="purchaseType" class="mb20"> <el-form-item label="采购方式" prop="purchaseType" class="mb16">
<el-select <el-select
v-model="dataForm.purchaseType" v-model="dataForm.purchaseType"
placeholder="请选择采购方式" placeholder="请选择采购方式"
@@ -158,7 +171,7 @@
v-if="isPurchaseType(PURCHASE_TYPE_IDS.BUSINESS_NEGOTIATION)" v-if="isPurchaseType(PURCHASE_TYPE_IDS.BUSINESS_NEGOTIATION)"
label="商务洽谈表" label="商务洽谈表"
prop="businessNegotiationTable" prop="businessNegotiationTable"
class="mb20"> class="mb16">
<el-button <el-button
type="primary" type="primary"
link link
@@ -180,7 +193,7 @@
v-if="isPurchaseType(PURCHASE_TYPE_IDS.MARKET_PURCHASE)" v-if="isPurchaseType(PURCHASE_TYPE_IDS.MARKET_PURCHASE)"
label="市场采购纪要" label="市场采购纪要"
prop="marketPurchaseMinutes" prop="marketPurchaseMinutes"
class="mb20"> class="mb16">
<el-button <el-button
type="primary" type="primary"
link link
@@ -202,7 +215,7 @@
v-if="isPurchaseType(PURCHASE_TYPE_IDS.ONLINE_MALL)" v-if="isPurchaseType(PURCHASE_TYPE_IDS.ONLINE_MALL)"
label="网上商城采购相关材料" label="网上商城采购相关材料"
prop="onlineMallMaterials" prop="onlineMallMaterials"
class="mb20"> class="mb16">
<upload-file <upload-file
v-model="dataForm.onlineMallMaterials" v-model="dataForm.onlineMallMaterials"
:limit="1" :limit="1"
@@ -216,7 +229,7 @@
v-if="isInquiryPurchaseType" v-if="isInquiryPurchaseType"
label="询价模板" label="询价模板"
prop="inquiryTemplate" prop="inquiryTemplate"
class="mb20"> class="mb16">
<el-button <el-button
type="primary" type="primary"
link link
@@ -235,7 +248,7 @@
<!-- 委托采购中心 --> <!-- 委托采购中心 -->
<template v-if="isPurchaseType(PURCHASE_TYPE_IDS.ENTRUST_CENTER)"> <template v-if="isPurchaseType(PURCHASE_TYPE_IDS.ENTRUST_CENTER)">
<el-form-item label="委托采购中心方式" prop="entrustCenterType" class="mb20"> <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>
@@ -245,7 +258,7 @@
<!-- 服务类网上商城判断品目编码的第一个值是否为C --> <!-- 服务类网上商城判断品目编码的第一个值是否为C -->
<template v-if="dataForm.entrustCenterType === 'service_online' && categoryCodePath && categoryCodePath.length > 0 && categoryCodePath[0] === 'C'"> <template v-if="dataForm.entrustCenterType === 'service_online' && categoryCodePath && categoryCodePath.length > 0 && categoryCodePath[0] === 'C'">
<el-form-item label="是否有供应商" prop="hasSupplier" class="mb20"> <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>
<el-radio label="0"></el-radio> <el-radio label="0"></el-radio>
@@ -256,11 +269,11 @@
<el-form-item <el-form-item
label="供应商名称" label="供应商名称"
prop="suppliers" prop="suppliers"
class="mb20"> class="mb16">
<el-input <el-input
v-model="dataForm.suppliers" v-model="dataForm.suppliers"
type="textarea" type="textarea"
:rows="3" :rows="2"
placeholder="请输入供应商名称,多个供应商请用逗号或分号分隔" placeholder="请输入供应商名称,多个供应商请用逗号或分号分隔"
maxlength="500" maxlength="500"
show-word-limit /> show-word-limit />
@@ -271,7 +284,7 @@
<el-form-item <el-form-item
label="服务商城项目需求模板(直选)" label="服务商城项目需求模板(直选)"
prop="serviceDirectSelect" prop="serviceDirectSelect"
class="mb20"> class="mb16">
<el-button <el-button
type="primary" type="primary"
link link
@@ -292,7 +305,7 @@
v-if="dataForm.hasSupplier === 'no'" v-if="dataForm.hasSupplier === 'no'"
label="服务商城项目需求模板(邀请比选)" label="服务商城项目需求模板(邀请比选)"
prop="serviceInviteSelect" prop="serviceInviteSelect"
class="mb20"> class="mb16">
<el-button <el-button
type="primary" type="primary"
link link
@@ -315,7 +328,7 @@
v-if="dataForm.entrustCenterType === 'other' && categoryCodePath && categoryCodePath[0] === 'A'" v-if="dataForm.entrustCenterType === 'other' && categoryCodePath && categoryCodePath[0] === 'A'"
label="采购需求填报模板" label="采购需求填报模板"
prop="purchaseRequirementTemplate" prop="purchaseRequirementTemplate"
class="mb20"> class="mb16">
<el-button <el-button
type="primary" type="primary"
link link
@@ -335,18 +348,18 @@
<!-- 特殊规则5<=金额<40万服务类目自动使用邀请比选模版 --> <!-- 特殊规则5<=金额<40万服务类目自动使用邀请比选模版 -->
<template v-if="showAutoInviteSelect"> <template v-if="showAutoInviteSelect">
<el-form-item label="是否有推荐供应商" prop="hasRecommendedSupplier" class="mb20"> <el-form-item label="是否有推荐供应商" prop="hasRecommendedSupplier" class="mb16">
<el-radio-group v-model="dataForm.hasRecommendedSupplier"> <el-radio-group v-model="dataForm.hasRecommendedSupplier">
<el-radio label="yes"></el-radio> <el-radio label="1"></el-radio>
<el-radio label="no"></el-radio> <el-radio label="0"></el-radio>
</el-radio-group> </el-radio-group>
</el-form-item> </el-form-item>
<!-- 有推荐供应商显示推荐供应商输入框和邀请比选模板 --> <!-- 有推荐供应商显示推荐供应商输入框和邀请比选模板 -->
<template v-if="dataForm.hasRecommendedSupplier === 'yes'"> <template v-if="dataForm.hasRecommendedSupplier === '1'">
<el-form-item <el-form-item
label="推荐供应商" label="推荐供应商"
prop="recommendedSuppliers" prop="recommendedSuppliers"
class="mb20"> class="mb16">
<el-input <el-input
v-model="dataForm.recommendedSuppliers" v-model="dataForm.recommendedSuppliers"
placeholder="请输入三家供应商名称,用逗号分隔" placeholder="请输入三家供应商名称,用逗号分隔"
@@ -358,7 +371,7 @@
<el-form-item <el-form-item
label="服务商城项目需求模板(邀请比选)" label="服务商城项目需求模板(邀请比选)"
prop="serviceInviteSelect" prop="serviceInviteSelect"
class="mb20"> class="mb16">
<el-button <el-button
type="primary" type="primary"
link link
@@ -380,7 +393,7 @@
v-if="dataForm.hasRecommendedSupplier === 'no'" v-if="dataForm.hasRecommendedSupplier === 'no'"
label="服务商城项目需求模板(公开比选)" label="服务商城项目需求模板(公开比选)"
prop="servicePublicSelectAuto" prop="servicePublicSelectAuto"
class="mb20"> class="mb16">
<el-button <el-button
type="primary" type="primary"
link link
@@ -399,7 +412,7 @@
</template> </template>
<!-- 其他材料zip压缩包 --> <!-- 其他材料zip压缩包 -->
<el-form-item label="其他材料" prop="otherMaterials" class="mb20"> <el-form-item label="其他材料" prop="otherMaterials" class="mb16">
<upload-file <upload-file
v-model="dataForm.otherMaterials" v-model="dataForm.otherMaterials"
:limit="5" :limit="5"
@@ -411,22 +424,23 @@
</div> </div>
<!-- 分支二学校统一采购 --> <!-- 分支二学校统一采购 -->
<div class="mb20" v-else > <div class="mb20" v-else>
<div class="step-title mb20">学校统一采购</div> <div class="step-title mb16">学校统一采购</div>
<el-form-item label="采购形式" prop="purchaseMode" class="mb20"> <el-row :gutter="20">
<el-select <el-col :span="12" class="mb16">
v-model="dataForm.purchaseMode" <el-form-item label="采购形式" prop="purchaseMode">
placeholder="请选择采购形式" <el-radio-group v-model="dataForm.purchaseMode">
clearable <el-radio
style="width: 100%">
<el-option
v-for="item in purchaseModeSchoolList" v-for="item in purchaseModeSchoolList"
:key="item.value" :key="item.value"
:label="item.label" :label="item.value">
:value="item.value" /> {{ item.label }}
</el-select> </el-radio>
</el-radio-group>
</el-form-item> </el-form-item>
<el-form-item label="采购方式" prop="purchaseTypeUnion" class="mb20"> </el-col>
<el-col :span="12" class="mb16">
<el-form-item label="采购方式" prop="purchaseTypeUnion">
<el-select <el-select
v-model="dataForm.purchaseTypeUnion" v-model="dataForm.purchaseTypeUnion"
placeholder="请选择采购方式" placeholder="请选择采购方式"
@@ -440,9 +454,13 @@
:value="item.value" /> :value="item.value" />
</el-select> </el-select>
</el-form-item> </el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<!-- 业务分管处室 --> <!-- 业务分管处室 -->
<el-form-item label="业务分管处室" prop="deptClassifyId" class="mb20"> <el-col :span="12" class="mb16">
<el-form-item label="业务分管处室" prop="deptClassifyId">
<el-select <el-select
v-model="dataForm.deptClassifyId" v-model="dataForm.deptClassifyId"
placeholder="请选择业务分管处室" placeholder="请选择业务分管处室"
@@ -457,9 +475,11 @@
:value="item.id" /> :value="item.id" />
</el-select> </el-select>
</el-form-item> </el-form-item>
</el-col>
<!-- 分管校领导 --> <!-- 分管校领导 -->
<el-form-item label="分管校领导" prop="schoolLeaderUserId" class="mb20"> <el-col :span="12" class="mb16">
<el-form-item label="分管校领导" prop="schoolLeaderUserId">
<el-select <el-select
v-model="dataForm.schoolLeaderUserId" v-model="dataForm.schoolLeaderUserId"
placeholder="请选择分管校领导" placeholder="请选择分管校领导"
@@ -474,13 +494,16 @@
:value="item.userId" /> :value="item.userId" />
</el-select> </el-select>
</el-form-item> </el-form-item>
</el-col>
</el-row>
<!-- 金额>=30显示可行性论证报告和会议纪要 --> <!-- 金额>=30显示可行性论证报告和会议纪要 -->
<template v-if="dataForm.budget && dataForm.budget >= 300000"> <template v-if="dataForm.budget && dataForm.budget >= 300000">
<el-row :gutter="20">
<el-col :span="12" class="mb16">
<el-form-item <el-form-item
label="项目可行性论证报告" label="项目可行性论证报告"
prop="feasibilityReport" prop="feasibilityReport">
class="mb20">
<el-button <el-button
type="primary" type="primary"
link link
@@ -496,7 +519,15 @@
:data="{ fileType: FILE_TYPE_MAP.feasibilityReport }" :data="{ fileType: FILE_TYPE_MAP.feasibilityReport }"
upload-file-url="/purchase/purchasingfiles/upload" /> upload-file-url="/purchase/purchasingfiles/upload" />
</el-form-item> </el-form-item>
<el-form-item label="会议纪要" prop="meetingMinutes" class="mb20"> </el-col>
<!-- 通用会议纪要只有在没有选择特殊情况时才显示 -->
<el-col
v-if="!isUrgentSpecial && !isSpecialType('2') && !isSpecialType('3')"
:span="12"
class="mb16">
<el-form-item
label="会议纪要"
prop="meetingMinutes">
<upload-file <upload-file
v-model="dataForm.meetingMinutes" v-model="dataForm.meetingMinutes"
:limit="5" :limit="5"
@@ -504,11 +535,15 @@
:data="{ fileType: FILE_TYPE_MAP.meetingMinutes }" :data="{ fileType: FILE_TYPE_MAP.meetingMinutes }"
upload-file-url="/purchase/purchasingfiles/upload" /> upload-file-url="/purchase/purchasingfiles/upload" />
</el-form-item> </el-form-item>
</el-col>
</el-row>
</template> </template>
<!-- 特殊情况紧急 --> <!-- 特殊情况紧急 -->
<template v-if="isUrgentSpecial"> <template v-if="isUrgentSpecial">
<el-form-item label="会议纪要" prop="meetingMinutesUrgent" class="mb20"> <el-row :gutter="20">
<el-col :span="12" class="mb16">
<el-form-item label="会议纪要" prop="meetingMinutesUrgent">
<upload-file <upload-file
v-model="dataForm.meetingMinutesUrgent" v-model="dataForm.meetingMinutesUrgent"
:limit="5" :limit="5"
@@ -516,14 +551,17 @@
:data="{ fileType: FILE_TYPE_MAP.meetingMinutesUrgent }" :data="{ fileType: FILE_TYPE_MAP.meetingMinutesUrgent }"
upload-file-url="/purchase/purchasingfiles/upload" /> upload-file-url="/purchase/purchasingfiles/upload" />
</el-form-item> </el-form-item>
</el-col>
</el-row>
</template> </template>
<!-- 特殊情况单一来源 --> <!-- 特殊情况单一来源 -->
<template v-if="isSpecialType('2')"> <template v-if="isSpecialType('2')">
<el-row :gutter="20">
<el-col :span="12" class="mb16">
<el-form-item <el-form-item
label="单一来源论专家证附件" label="单一来源论专家证附件"
prop="singleSourceProof" prop="singleSourceProof">
class="mb20">
<el-button <el-button
type="primary" type="primary"
link link
@@ -539,7 +577,9 @@
:data="{ fileType: FILE_TYPE_MAP.singleSourceProof }" :data="{ fileType: FILE_TYPE_MAP.singleSourceProof }"
upload-file-url="/purchase/purchasingfiles/upload" /> upload-file-url="/purchase/purchasingfiles/upload" />
</el-form-item> </el-form-item>
<el-form-item label="会议纪要" prop="meetingMinutesSingle" class="mb20"> </el-col>
<el-col :span="12" class="mb16">
<el-form-item label="会议纪要" prop="meetingMinutesSingle">
<upload-file <upload-file
v-model="dataForm.meetingMinutesSingle" v-model="dataForm.meetingMinutesSingle"
:limit="5" :limit="5"
@@ -547,14 +587,17 @@
:data="{ fileType: FILE_TYPE_MAP.meetingMinutesSingle }" :data="{ fileType: FILE_TYPE_MAP.meetingMinutesSingle }"
upload-file-url="/purchase/purchasingfiles/upload" /> upload-file-url="/purchase/purchasingfiles/upload" />
</el-form-item> </el-form-item>
</el-col>
</el-row>
</template> </template>
<!-- 特殊情况进口 --> <!-- 特殊情况进口 -->
<template v-if="isSpecialType('3')"> <template v-if="isSpecialType('3')">
<el-row :gutter="20">
<el-col :span="12" class="mb16">
<el-form-item <el-form-item
label="进口产品申请及专家论证意见表" label="进口产品申请及专家论证意见表"
prop="importApplication" prop="importApplication">
class="mb20">
<el-button <el-button
type="primary" type="primary"
link link
@@ -570,7 +613,9 @@
:data="{ fileType: FILE_TYPE_MAP.importApplication }" :data="{ fileType: FILE_TYPE_MAP.importApplication }"
upload-file-url="/purchase/purchasingfiles/upload" /> upload-file-url="/purchase/purchasingfiles/upload" />
</el-form-item> </el-form-item>
<el-form-item label="会议纪要" prop="meetingMinutesImport" class="mb20"> </el-col>
<el-col :span="12" class="mb16">
<el-form-item label="会议纪要" prop="meetingMinutesImport">
<upload-file <upload-file
v-model="dataForm.meetingMinutesImport" v-model="dataForm.meetingMinutesImport"
:limit="5" :limit="5"
@@ -578,36 +623,45 @@
:data="{ fileType: FILE_TYPE_MAP.meetingMinutesImport }" :data="{ fileType: FILE_TYPE_MAP.meetingMinutesImport }"
upload-file-url="/purchase/purchasingfiles/upload" /> upload-file-url="/purchase/purchasingfiles/upload" />
</el-form-item> </el-form-item>
</el-col>
</el-row>
</template> </template>
<!-- 特殊规则5<=金额<40万服务类目isMallService=1isProjectService=1自动使用邀请比选模版 --> <!-- 特殊规则5<=金额<40万服务类目isMallService=1isProjectService=1自动使用邀请比选模版 -->
<template v-if="showAutoInviteSelectSchool"> <template v-if="showAutoInviteSelectSchool">
<el-form-item label="是否有推荐供应商" prop="hasRecommendedSupplierSchool" class="mb20"> <el-row :gutter="20">
<el-col :span="12" class="mb16">
<el-form-item label="是否有推荐供应商" prop="hasRecommendedSupplierSchool">
<el-radio-group v-model="dataForm.hasRecommendedSupplierSchool"> <el-radio-group v-model="dataForm.hasRecommendedSupplierSchool">
<el-radio label="yes"></el-radio> <el-radio label="yes"></el-radio>
<el-radio label="no"></el-radio> <el-radio label="no"></el-radio>
</el-radio-group> </el-radio-group>
</el-form-item> </el-form-item>
</el-col>
<!-- 有推荐供应商显示推荐供应商输入框 --> <!-- 有推荐供应商显示推荐供应商输入框 -->
<el-form-item <el-col
v-if="dataForm.hasRecommendedSupplierSchool === 'yes'" v-if="dataForm.hasRecommendedSupplierSchool === 'yes'"
:span="12"
class="mb16">
<el-form-item
label="推荐供应商" label="推荐供应商"
prop="recommendedSuppliersSchool" prop="recommendedSuppliersSchool">
class="mb20">
<el-input <el-input
v-model="dataForm.recommendedSuppliersSchool" v-model="dataForm.recommendedSuppliersSchool"
type="textarea" type="textarea"
:rows="3" :rows="2"
placeholder="请输入三家供应商名称,用逗号或分号分隔" placeholder="请输入三家供应商名称,用逗号或分号分隔"
clearable /> clearable />
<div class="template-note mt5"> <div class="template-note mt5">
<el-text type="info" size="small">请输入三家供应商名称用逗号或分号分隔</el-text> <el-text type="info" size="small">请输入三家供应商名称用逗号或分号分隔</el-text>
</div> </div>
</el-form-item> </el-form-item>
</el-col>
</el-row>
</template> </template>
<!-- 需求文件 --> <!-- 需求文件 -->
<el-form-item label="需求文件" :prop="getRequirementFileProp()" class="mb20"> <el-form-item label="需求文件" :prop="getRequirementFileProp()" class="mb16">
<!-- 特殊规则5<=金额<40万服务类目isMallService=1isProjectService=1自动使用邀请比选模版 --> <!-- 特殊规则5<=金额<40万服务类目isMallService=1isProjectService=1自动使用邀请比选模版 -->
<template v-if="showAutoInviteSelectSchool"> <template v-if="showAutoInviteSelectSchool">
<!-- 有推荐供应商显示邀请比选模板 --> <!-- 有推荐供应商显示邀请比选模板 -->
@@ -691,12 +745,15 @@
</template> </template>
</el-form-item> </el-form-item>
<el-row :gutter="20">
<!-- 金额>=100政府采购意向表 --> <!-- 金额>=100政府采购意向表 -->
<el-form-item <el-col
v-if="dataForm.budget && dataForm.budget >= 1000000" v-if="dataForm.budget && dataForm.budget >= 1000000"
:span="12"
class="mb16">
<el-form-item
label="政府采购意向申请表" label="政府采购意向申请表"
prop="governmentPurchaseIntent" prop="governmentPurchaseIntent">
class="mb20">
<upload-file <upload-file
v-model="dataForm.governmentPurchaseIntent" v-model="dataForm.governmentPurchaseIntent"
:limit="5" :limit="5"
@@ -704,9 +761,11 @@
:data="{ fileType: FILE_TYPE_MAP.governmentPurchaseIntent }" :data="{ fileType: FILE_TYPE_MAP.governmentPurchaseIntent }"
upload-file-url="/purchase/purchasingfiles/upload" /> upload-file-url="/purchase/purchasingfiles/upload" />
</el-form-item> </el-form-item>
</el-col>
<!-- 其他材料zip压缩包 --> <!-- 其他材料zip压缩包 -->
<el-form-item label="其他材料" prop="otherMaterials" class="mb20"> <el-col :span="12" class="mb16">
<el-form-item label="其他材料" prop="otherMaterials">
<upload-file <upload-file
v-model="dataForm.otherMaterials" v-model="dataForm.otherMaterials"
:limit="5" :limit="5"
@@ -715,14 +774,16 @@
upload-file-url="/purchase/purchasingfiles/upload" /> upload-file-url="/purchase/purchasingfiles/upload" />
<div class="template-note">支持上传zip格式的压缩包文件</div> <div class="template-note">支持上传zip格式的压缩包文件</div>
</el-form-item> </el-form-item>
</el-col>
</el-row>
</div> </div>
</div> </div>
<el-form-item label="备注" prop="remark" v-if="currentStep === 1"> <el-form-item label="备注" prop="remark" v-if="currentStep === 1" class="mb16">
<el-input <el-input
v-model="dataForm.remark" v-model="dataForm.remark"
type="textarea" type="textarea"
:rows="3" :rows="2"
placeholder="请输入备注" placeholder="请输入备注"
clearable /> clearable />
</el-form-item> </el-form-item>
@@ -846,6 +907,10 @@ 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常量 // 采购方式ID常量
const PURCHASE_TYPE_IDS = { const PURCHASE_TYPE_IDS = {
BUSINESS_NEGOTIATION: '77b429c146fc9e12ba4c5573da19ad70', // 商务洽谈 BUSINESS_NEGOTIATION: '77b429c146fc9e12ba4c5573da19ad70', // 商务洽谈
@@ -1635,7 +1700,11 @@ const handleSubmit = async () => {
router.push('/finance/purchasingrequisition'); router.push('/finance/purchasingrequisition');
} }
} catch (err: any) { } catch (err: any) {
useMessage().error(err.msg || '提交失败'); // 全局拦截器已经显示了错误提示,这里不需要再次显示
// 只有当错误没有 msg 时才显示默认错误提示
if (!err?.msg) {
useMessage().error('提交失败');
}
} finally { } finally {
loading.value = false; loading.value = false;
} }
@@ -1698,7 +1767,11 @@ const handleTempStore = async () => {
router.push('/finance/purchasingrequisition'); router.push('/finance/purchasingrequisition');
} }
} catch (err: any) { } catch (err: any) {
useMessage().error(err.msg || '暂存失败'); // 全局拦截器已经显示了错误提示,这里不需要再次显示
// 只有当错误没有 msg 时才显示默认错误提示
if (!err?.msg) {
useMessage().error('暂存失败');
}
} finally { } finally {
loading.value = false; loading.value = false;
} }
@@ -1718,6 +1791,83 @@ 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) {
@@ -1780,6 +1930,11 @@ 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();
@@ -1793,6 +1948,9 @@ onMounted(async () => {
.mb20 { .mb20 {
margin-bottom: 20px; margin-bottom: 20px;
} }
.mb16 {
margin-bottom: 16px;
}
.mb10 { .mb10 {
margin-bottom: 10px; margin-bottom: 10px;
} }
@@ -1805,18 +1963,94 @@ onMounted(async () => {
color: var(--el-text-color-primary); color: var(--el-text-color-primary);
padding-bottom: 10px; padding-bottom: 10px;
border-bottom: 1px solid var(--el-border-color-light); border-bottom: 1px solid var(--el-border-color-light);
margin-bottom: 20px; margin-bottom: 16px;
} }
/* 紧凑表单样式 */
.compact-form {
:deep(.el-form-item) {
margin-bottom: 16px;
}
:deep(.el-form-item__label) {
padding-right: 12px;
font-size: 14px;
}
:deep(.el-input__inner),
:deep(.el-textarea__inner) {
font-size: 14px;
}
}
.template-note { .template-note {
margin-top: 5px; margin-top: 5px;
color: var(--el-text-color-secondary); color: var(--el-text-color-secondary);
font-size: 12px;
} }
/* 预算金额输入组样式 - 并排显示,无缝连接 */
.budget-input-group {
display: flex;
align-items: stretch;
width: 100%;
transition: all 0.2s ease;
.budget-input {
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) {
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);
}
}
.budget-unit-select {
width: 100px;
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);
}
}
}
.form-footer { .form-footer {
display: flex; display: flex;
justify-content: flex-end; justify-content: flex-end;
gap: 10px; gap: 10px;
padding-top: 20px; padding-top: 16px;
border-top: 1px solid var(--el-border-color-light); border-top: 1px solid var(--el-border-color-light);
margin-top: 16px;
} }
</style> </style>

View File

@@ -2,12 +2,17 @@
<el-dialog <el-dialog
:title="dialogTitle" :title="dialogTitle"
v-model="visible" v-model="visible"
width="1200px" :width="isView ? '1400px' : '1200px'"
:close-on-click-modal="false" :close-on-click-modal="false"
draggable> draggable
<div v-loading="loading"> :class="{ 'view-dialog': isView }">
<!-- 步骤条 --> <div v-loading="loading" :class="{ 'view-content': isView }">
<el-steps :active="currentStep" finish-status="success" style="margin-bottom: 30px;"> <!-- 步骤条查看模式下隐藏 -->
<el-steps
v-if="!isView"
:active="currentStep"
finish-status="success"
style="margin-bottom: 30px;">
<el-step title="基本信息" /> <el-step title="基本信息" />
<el-step :title="stepTwoTitle" /> <el-step :title="stepTwoTitle" />
</el-steps> </el-steps>
@@ -16,41 +21,49 @@
ref="formRef" ref="formRef"
:model="dataForm" :model="dataForm"
:rules="dataRules" :rules="dataRules"
label-width="140px"> :label-width="isView ? '120px' : '140px'"
:class="{ 'view-form': isView }">
<!-- 第一步基本信息 --> <!-- 第一步基本信息 -->
<div v-show="currentStep === 0"> <div v-show="currentStep === 0 || isView">
<el-row :gutter="24"> <el-row :gutter="isView ? 16 : 24">
<el-col :span="12" class="mb20"> <el-col :span="isView ? 8 : 12" :class="isView ? 'mb16' : 'mb20'">
<el-form-item label="采购项目名称" prop="projectName"> <el-form-item label="采购项目名称" prop="projectName">
<template v-if="isView">
<span class="view-text">{{ dataForm.projectName || '-' }}</span>
</template>
<el-input <el-input
v-else
v-model="dataForm.projectName" v-model="dataForm.projectName"
placeholder="请输入采购项目名称" placeholder="请输入采购项目名称"
clearable clearable />
:disabled="isView" />
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12" class="mb20"> <el-col :span="isView ? 8 : 12" :class="isView ? 'mb16' : 'mb20'">
<el-form-item label="填报日期" prop="applyDate"> <el-form-item label="填报日期" prop="applyDate">
<template v-if="isView">
<span class="view-text">{{ dataForm.applyDate || '-' }}</span>
</template>
<el-date-picker <el-date-picker
v-else
v-model="dataForm.applyDate" v-model="dataForm.applyDate"
type="date" type="date"
placeholder="请选择填报日期" placeholder="请选择填报日期"
format="YYYY-MM-DD" format="YYYY-MM-DD"
value-format="YYYY-MM-DD" value-format="YYYY-MM-DD"
:disabled="isView"
style="width: 100%" /> style="width: 100%" />
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> <el-col :span="isView ? 8 : 12" :class="isView ? 'mb16' : 'mb20'">
<el-row :gutter="24">
<el-col :span="12" class="mb20">
<el-form-item label="资金来源" prop="fundSource"> <el-form-item label="资金来源" prop="fundSource">
<template v-if="isView">
<span class="view-text">{{ getDictLabel(fundSourceList, dataForm.fundSource) || '-' }}</span>
</template>
<el-select <el-select
v-else
v-model="dataForm.fundSource" v-model="dataForm.fundSource"
placeholder="请选择资金来源" placeholder="请选择资金来源"
clearable clearable
:disabled="isView"
style="width: 100%"> style="width: 100%">
<el-option <el-option
v-for="item in fundSourceList" v-for="item in fundSourceList"
@@ -60,26 +73,34 @@
</el-select> </el-select>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12" class="mb20"> </el-row>
<el-row :gutter="isView ? 16 : 24">
<el-col :span="isView ? 8 : 12" :class="isView ? 'mb16' : 'mb20'">
<el-form-item label="预算金额(元)" prop="budget"> <el-form-item label="预算金额(元)" prop="budget">
<template v-if="isView">
<span class="view-text">{{ dataForm.budget ? Number(dataForm.budget).toLocaleString('zh-CN', { minimumFractionDigits: 2, maximumFractionDigits: 2 }) : '-' }}</span>
</template>
<el-input-number <el-input-number
v-else
v-model="dataForm.budget" v-model="dataForm.budget"
:min="0.01" :min="0.01"
:precision="2" :precision="2"
placeholder="请输入预算金额" placeholder="请输入预算金额"
:disabled="isView"
style="width: 100%" /> style="width: 100%" />
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> <el-col :span="isView ? 8 : 12" :class="isView ? 'mb16' : 'mb20'">
<el-row :gutter="24">
<el-col :span="12" class="mb20">
<el-form-item label="是否集采" prop="isCentralized"> <el-form-item label="是否集采" prop="isCentralized">
<template v-if="isView">
<el-tag v-if="dataForm.isCentralized === '1'" type="success"></el-tag>
<el-tag v-else-if="dataForm.isCentralized === '0'" type="info"></el-tag>
<span v-else class="view-text">-</span>
</template>
<el-select <el-select
v-else
v-model="dataForm.isCentralized" v-model="dataForm.isCentralized"
placeholder="请选择是否集采" placeholder="请选择是否集采"
clearable clearable
:disabled="isView"
style="width: 100%"> style="width: 100%">
<el-option <el-option
v-for="item in isCentralizedList" v-for="item in isCentralizedList"
@@ -89,13 +110,16 @@
</el-select> </el-select>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12" class="mb20"> <el-col :span="isView ? 8 : 12" :class="isView ? 'mb16' : 'mb20'">
<el-form-item label="是否特殊情况" prop="isSpecial"> <el-form-item label="是否特殊情况" prop="isSpecial">
<template v-if="isView">
<span class="view-text">{{ getDictLabel(isSpecialList, dataForm.isSpecial) || '-' }}</span>
</template>
<el-select <el-select
v-else
v-model="dataForm.isSpecial" v-model="dataForm.isSpecial"
placeholder="请选择是否特殊情况" placeholder="请选择是否特殊情况"
clearable clearable
:disabled="isView"
style="width: 100%"> style="width: 100%">
<el-option <el-option
v-for="item in isSpecialList" v-for="item in isSpecialList"
@@ -106,10 +130,14 @@
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
<el-row :gutter="24"> <el-row :gutter="isView ? 16 : 24">
<el-col :span="24" class="mb20"> <el-col :span="24" :class="isView ? 'mb16' : 'mb20'">
<el-form-item label="品目编码" prop="categoryCode"> <el-form-item label="品目编码" prop="categoryCode">
<template v-if="isView">
<span class="view-text">{{ getCategoryDisplayText() }}</span>
</template>
<el-cascader <el-cascader
v-else
v-model="categoryCodePath" v-model="categoryCodePath"
:options="categoryTreeData" :options="categoryTreeData"
:props="{ value: 'code', label: 'name', children: 'children', checkStrictly: true }" :props="{ value: 'code', label: 'name', children: 'children', checkStrictly: true }"
@@ -117,7 +145,6 @@
clearable clearable
filterable filterable
:show-all-levels="true" :show-all-levels="true"
:disabled="isView"
style="width: 100%" style="width: 100%"
@change="handleCategoryChange" /> @change="handleCategoryChange" />
</el-form-item> </el-form-item>
@@ -126,27 +153,34 @@
</div> </div>
<!-- 第二步采购详情 --> <!-- 第二步采购详情 -->
<div v-show="currentStep === 1"> <div v-show="currentStep === 1 || isView">
<!-- 分支一部门自行采购 --> <!-- 分支一部门自行采购 -->
<div v-if="isDeptPurchase"> <div v-if="isDeptPurchase">
<div class="step-title mb20">部门自行采购</div> <div :class="isView ? 'step-title mb16' : 'step-title mb20'">部门自行采购</div>
<el-form-item label="采购内容" prop="projectContent" class="mb20"> <el-form-item label="采购内容" prop="projectContent" :class="isView ? 'mb16' : 'mb20'">
<template v-if="isView">
<div class="view-text view-textarea">{{ dataForm.projectContent || '-' }}</div>
</template>
<el-input <el-input
v-else
v-model="dataForm.projectContent" v-model="dataForm.projectContent"
type="textarea" type="textarea"
:rows="4" :rows="4"
:maxlength="1000" :maxlength="1000"
show-word-limit show-word-limit
placeholder="请输入采购内容限制1000字" placeholder="请输入采购内容限制1000字"
clearable clearable />
:disabled="isView" />
</el-form-item> </el-form-item>
<el-form-item label="采购方式" prop="purchaseType" class="mb20"> <el-form-item label="采购方式" prop="purchaseType" :class="isView ? 'mb16' : 'mb20'">
<template v-if="isView">
<span class="view-text">{{ getDictLabel(purchaseTypeDeptList, dataForm.purchaseType) || '-' }}</span>
</template>
<el-select <el-select
v-else
v-model="dataForm.purchaseType" v-model="dataForm.purchaseType"
placeholder="请选择采购方式" placeholder="请选择采购方式"
clearable clearable
:disabled="isView || isAutoSelectPurchaseType" :disabled="isAutoSelectPurchaseType"
style="width: 100%"> style="width: 100%">
<el-option <el-option
v-for="item in purchaseTypeDeptList" v-for="item in purchaseTypeDeptList"
@@ -161,16 +195,17 @@
v-if="dataForm.purchaseType === 'business_negotiation'" v-if="dataForm.purchaseType === 'business_negotiation'"
label="商务洽谈表" label="商务洽谈表"
prop="businessNegotiationTable" prop="businessNegotiationTable"
class="mb20"> :class="isView ? 'mb16' : 'mb20'">
<template v-if="!isView">
<el-button <el-button
type="primary" type="primary"
link link
icon="Download" icon="Download"
@click="downloadTemplate('business_negotiation')" @click="downloadTemplate('business_negotiation')"
:disabled="isView"
class="mb10"> class="mb10">
下载商务洽谈表模版 下载商务洽谈表模版
</el-button> </el-button>
</template>
<upload-file <upload-file
v-model="dataForm.businessNegotiationTable" v-model="dataForm.businessNegotiationTable"
:limit="5" :limit="5"
@@ -183,16 +218,17 @@
v-if="dataForm.purchaseType === 'market_purchase'" v-if="dataForm.purchaseType === 'market_purchase'"
label="市场采购纪要" label="市场采购纪要"
prop="marketPurchaseMinutes" prop="marketPurchaseMinutes"
class="mb20"> :class="isView ? 'mb16' : 'mb20'">
<template v-if="!isView">
<el-button <el-button
type="primary" type="primary"
link link
icon="Download" icon="Download"
@click="downloadTemplate('market_purchase_minutes')" @click="downloadTemplate('market_purchase_minutes')"
:disabled="isView"
class="mb10"> class="mb10">
下载市场采购纪要模版 下载市场采购纪要模版
</el-button> </el-button>
</template>
<upload-file <upload-file
v-model="dataForm.marketPurchaseMinutes" v-model="dataForm.marketPurchaseMinutes"
:limit="5" :limit="5"
@@ -205,22 +241,25 @@
v-if="dataForm.purchaseType === 'online_mall'" v-if="dataForm.purchaseType === 'online_mall'"
label="网上商城采购相关材料" label="网上商城采购相关材料"
prop="onlineMallMaterials" prop="onlineMallMaterials"
class="mb20"> :class="isView ? 'mb16' : 'mb20'">
<upload-file <upload-file
v-model="dataForm.onlineMallMaterials" v-model="dataForm.onlineMallMaterials"
:limit="1" :limit="1"
accept=".zip" accept=".zip"
:disabled="isView" :disabled="isView"
upload-file-url="/purchase/purchasingfiles/upload" /> upload-file-url="/purchase/purchasingfiles/upload" />
<div class="template-note mt5"> <div v-if="!isView" class="template-note mt5">
<el-text type="info" size="small">请上传zip格式的压缩包</el-text> <el-text type="info" size="small">请上传zip格式的压缩包</el-text>
</div> </div>
</el-form-item> </el-form-item>
<!-- 委托采购中心 --> <!-- 委托采购中心 -->
<template v-if="dataForm.purchaseType === 'entrust_center'"> <template v-if="dataForm.purchaseType === 'entrust_center'">
<el-form-item label="委托采购中心方式" prop="entrustCenterType" class="mb20"> <el-form-item label="委托采购中心方式" prop="entrustCenterType" :class="isView ? 'mb16' : 'mb20'">
<el-radio-group v-model="dataForm.entrustCenterType" :disabled="isView"> <template v-if="isView">
<span class="view-text">{{ dataForm.entrustCenterType === 'service_online' ? '服务类网上商城' : dataForm.entrustCenterType === 'other' ? '其他方式' : '-' }}</span>
</template>
<el-radio-group v-else v-model="dataForm.entrustCenterType">
<el-radio label="service_online">服务类网上商城</el-radio> <el-radio label="service_online">服务类网上商城</el-radio>
<el-radio label="other">其他方式</el-radio> <el-radio label="other">其他方式</el-radio>
</el-radio-group> </el-radio-group>
@@ -281,16 +320,17 @@
v-if="dataForm.entrustCenterType === 'other' && isGoodsCategory" v-if="dataForm.entrustCenterType === 'other' && isGoodsCategory"
label="采购需求填报模板" label="采购需求填报模板"
prop="purchaseRequirementTemplate" prop="purchaseRequirementTemplate"
class="mb20"> :class="isView ? 'mb16' : 'mb20'">
<template v-if="!isView">
<el-button <el-button
type="primary" type="primary"
link link
icon="Download" icon="Download"
@click="downloadTemplate('purchase_requirement')" @click="downloadTemplate('purchase_requirement')"
:disabled="isView"
class="mb10"> class="mb10">
下载表1采购需求填报模板模版 下载表1采购需求填报模板模版
</el-button> </el-button>
</template>
<upload-file <upload-file
v-model="dataForm.purchaseRequirementTemplate" v-model="dataForm.purchaseRequirementTemplate"
:limit="5" :limit="5"
@@ -301,8 +341,11 @@
<!-- 特殊规则5<=金额<40万服务类目自动使用邀请比选模版 --> <!-- 特殊规则5<=金额<40万服务类目自动使用邀请比选模版 -->
<template v-if="showAutoInviteSelect"> <template v-if="showAutoInviteSelect">
<el-form-item label="是否有推荐供应商" prop="hasRecommendedSupplier" class="mb20"> <el-form-item label="是否有推荐供应商" prop="hasRecommendedSupplier" :class="isView ? 'mb16' : 'mb20'">
<el-radio-group v-model="dataForm.hasRecommendedSupplier" :disabled="isView"> <template v-if="isView">
<span class="view-text">{{ dataForm.hasRecommendedSupplier === 'yes' ? '有' : dataForm.hasRecommendedSupplier === 'no' ? '无' : '-' }}</span>
</template>
<el-radio-group v-else v-model="dataForm.hasRecommendedSupplier">
<el-radio label="yes"></el-radio> <el-radio label="yes"></el-radio>
<el-radio label="no"></el-radio> <el-radio label="no"></el-radio>
</el-radio-group> </el-radio-group>
@@ -311,29 +354,34 @@
v-if="dataForm.hasRecommendedSupplier === 'yes'" v-if="dataForm.hasRecommendedSupplier === 'yes'"
label="推荐供应商" label="推荐供应商"
prop="recommendedSuppliers" prop="recommendedSuppliers"
class="mb20"> :class="isView ? 'mb16' : 'mb20'">
<template v-if="isView">
<span class="view-text">{{ dataForm.recommendedSuppliers || '-' }}</span>
</template>
<template v-else>
<el-input <el-input
v-model="dataForm.recommendedSuppliers" v-model="dataForm.recommendedSuppliers"
placeholder="请输入三家供应商名称,用逗号分隔" placeholder="请输入三家供应商名称,用逗号分隔"
clearable clearable />
:disabled="isView" />
<div class="template-note mt5"> <div class="template-note mt5">
<el-text type="info" size="small">请输入三家供应商名称用逗号分隔</el-text> <el-text type="info" size="small">请输入三家供应商名称用逗号分隔</el-text>
</div> </div>
</template>
</el-form-item> </el-form-item>
<el-form-item <el-form-item
label="服务商城项目需求模板(邀请比选)" label="服务商城项目需求模板(邀请比选)"
prop="serviceInviteSelect" prop="serviceInviteSelect"
class="mb20"> :class="isView ? 'mb16' : 'mb20'">
<template v-if="!isView">
<el-button <el-button
type="primary" type="primary"
link link
icon="Download" icon="Download"
@click="downloadTemplate('invite_select')" @click="downloadTemplate('invite_select')"
:disabled="isView"
class="mb10"> class="mb10">
下载服务商城项目需求模板邀请比选模版 下载服务商城项目需求模板邀请比选模版
</el-button> </el-button>
</template>
<upload-file <upload-file
v-model="dataForm.serviceInviteSelect" v-model="dataForm.serviceInviteSelect"
:limit="5" :limit="5"
@@ -344,16 +392,17 @@
v-if="dataForm.hasRecommendedSupplier === 'no'" v-if="dataForm.hasRecommendedSupplier === 'no'"
label="服务商城项目需求模板(公开比选)" label="服务商城项目需求模板(公开比选)"
prop="servicePublicSelectAuto" prop="servicePublicSelectAuto"
class="mb20"> :class="isView ? 'mb16' : 'mb20'">
<template v-if="!isView">
<el-button <el-button
type="primary" type="primary"
link link
icon="Download" icon="Download"
@click="downloadTemplate('public_select')" @click="downloadTemplate('public_select')"
:disabled="isView"
class="mb10"> class="mb10">
下载服务商城项目需求模板公开比选模版 下载服务商城项目需求模板公开比选模版
</el-button> </el-button>
</template>
<upload-file <upload-file
v-model="dataForm.servicePublicSelectAuto" v-model="dataForm.servicePublicSelectAuto"
:limit="5" :limit="5"
@@ -365,13 +414,18 @@
<!-- 分支二学校统一采购 --> <!-- 分支二学校统一采购 -->
<div v-else> <div v-else>
<div class="step-title mb20">学校统一采购</div> <div :class="isView ? 'step-title mb16' : 'step-title mb20'">学校统一采购</div>
<el-form-item label="采购形式" prop="purchaseMode" class="mb20"> <el-row :gutter="isView ? 16 : 24">
<el-col :span="isView ? 12 : 24" :class="isView ? 'mb16' : 'mb20'">
<el-form-item label="采购形式" prop="purchaseMode">
<template v-if="isView">
<span class="view-text">{{ getDictLabel(purchaseModeSchoolList, dataForm.purchaseMode) || '-' }}</span>
</template>
<el-select <el-select
v-else
v-model="dataForm.purchaseMode" v-model="dataForm.purchaseMode"
placeholder="请选择采购形式" placeholder="请选择采购形式"
clearable clearable
:disabled="isView"
style="width: 100%"> style="width: 100%">
<el-option <el-option
v-for="item in purchaseModeSchoolList" v-for="item in purchaseModeSchoolList"
@@ -380,12 +434,17 @@
:value="item.value" /> :value="item.value" />
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="采购方式" prop="purchaseTypeUnion" class="mb20"> </el-col>
<el-col :span="isView ? 12 : 24" :class="isView ? 'mb16' : 'mb20'">
<el-form-item label="采购方式" prop="purchaseTypeUnion">
<template v-if="isView">
<span class="view-text">{{ getDictLabel(purchaseTypeUnionList, dataForm.purchaseTypeUnion) || '-' }}</span>
</template>
<el-select <el-select
v-else
v-model="dataForm.purchaseTypeUnion" v-model="dataForm.purchaseTypeUnion"
placeholder="请选择采购方式" placeholder="请选择采购方式"
clearable clearable
:disabled="isView"
style="width: 100%"> style="width: 100%">
<el-option <el-option
v-for="item in purchaseTypeUnionList" v-for="item in purchaseTypeUnionList"
@@ -394,29 +453,32 @@
:value="item.value" /> :value="item.value" />
</el-select> </el-select>
</el-form-item> </el-form-item>
</el-col>
</el-row>
<!-- 金额>=30显示可行性论证报告和会议纪要 --> <!-- 金额>=30显示可行性论证报告和会议纪要 -->
<template v-if="dataForm.budget && dataForm.budget >= 300000"> <template v-if="dataForm.budget && dataForm.budget >= 300000">
<el-form-item <el-form-item
label="项目可行性论证报告" label="项目可行性论证报告"
prop="feasibilityReport" prop="feasibilityReport"
class="mb20"> :class="isView ? 'mb16' : 'mb20'">
<template v-if="!isView">
<el-button <el-button
type="primary" type="primary"
link link
icon="Download" icon="Download"
@click="downloadTemplate('feasibility_report')" @click="downloadTemplate('feasibility_report')"
:disabled="isView"
class="mb10"> class="mb10">
下载项目可行性论证报告模板.doc 下载项目可行性论证报告模板.doc
</el-button> </el-button>
</template>
<upload-file <upload-file
v-model="dataForm.feasibilityReport" v-model="dataForm.feasibilityReport"
:limit="5" :limit="5"
:disabled="isView" :disabled="isView"
upload-file-url="/purchase/purchasingfiles/upload" /> upload-file-url="/purchase/purchasingfiles/upload" />
</el-form-item> </el-form-item>
<el-form-item label="会议纪要" prop="meetingMinutes" class="mb20"> <el-form-item label="会议纪要" prop="meetingMinutes" :class="isView ? 'mb16' : 'mb20'">
<upload-file <upload-file
v-model="dataForm.meetingMinutes" v-model="dataForm.meetingMinutes"
:limit="5" :limit="5"
@@ -430,23 +492,24 @@
<el-form-item <el-form-item
label="单一来源论专家证附件" label="单一来源论专家证附件"
prop="singleSourceProof" prop="singleSourceProof"
class="mb20"> :class="isView ? 'mb16' : 'mb20'">
<template v-if="!isView">
<el-button <el-button
type="primary" type="primary"
link link
icon="Download" icon="Download"
@click="downloadTemplate('single_source')" @click="downloadTemplate('single_source')"
:disabled="isView"
class="mb10"> class="mb10">
下载单一来源论专家证附件.docx 下载单一来源论专家证附件.docx
</el-button> </el-button>
</template>
<upload-file <upload-file
v-model="dataForm.singleSourceProof" v-model="dataForm.singleSourceProof"
:limit="5" :limit="5"
:disabled="isView" :disabled="isView"
upload-file-url="/purchase/purchasingfiles/upload" /> upload-file-url="/purchase/purchasingfiles/upload" />
</el-form-item> </el-form-item>
<el-form-item label="会议纪要" prop="meetingMinutesSingle" class="mb20"> <el-form-item label="会议纪要" prop="meetingMinutesSingle" :class="isView ? 'mb16' : 'mb20'">
<upload-file <upload-file
v-model="dataForm.meetingMinutesSingle" v-model="dataForm.meetingMinutesSingle"
:limit="5" :limit="5"
@@ -460,23 +523,24 @@
<el-form-item <el-form-item
label="进口产品申请及专家论证意见表" label="进口产品申请及专家论证意见表"
prop="importApplication" prop="importApplication"
class="mb20"> :class="isView ? 'mb16' : 'mb20'">
<template v-if="!isView">
<el-button <el-button
type="primary" type="primary"
link link
icon="Download" icon="Download"
@click="downloadTemplate('import_application')" @click="downloadTemplate('import_application')"
:disabled="isView"
class="mb10"> class="mb10">
下载进口产品申请及专家论证意见表.doc 下载进口产品申请及专家论证意见表.doc
</el-button> </el-button>
</template>
<upload-file <upload-file
v-model="dataForm.importApplication" v-model="dataForm.importApplication"
:limit="5" :limit="5"
:disabled="isView" :disabled="isView"
upload-file-url="/purchase/purchasingfiles/upload" /> upload-file-url="/purchase/purchasingfiles/upload" />
</el-form-item> </el-form-item>
<el-form-item label="会议纪要" prop="meetingMinutesImport" class="mb20"> <el-form-item label="会议纪要" prop="meetingMinutesImport" :class="isView ? 'mb16' : 'mb20'">
<upload-file <upload-file
v-model="dataForm.meetingMinutesImport" v-model="dataForm.meetingMinutesImport"
:limit="5" :limit="5"
@@ -486,16 +550,17 @@
</template> </template>
<!-- 需求文件默认 --> <!-- 需求文件默认 -->
<el-form-item label="需求文件" prop="purchaseRequirement" class="mb20"> <el-form-item label="需求文件" prop="purchaseRequirement" :class="isView ? 'mb16' : 'mb20'">
<template v-if="!isView">
<el-button <el-button
type="primary" type="primary"
link link
icon="Download" icon="Download"
@click="downloadTemplate('purchase_requirement')" @click="downloadTemplate('purchase_requirement')"
:disabled="isView"
class="mb10"> class="mb10">
下载采购需求填报模板模版 下载采购需求填报模板模版
</el-button> </el-button>
</template>
<upload-file <upload-file
v-model="dataForm.purchaseRequirement" v-model="dataForm.purchaseRequirement"
:limit="5" :limit="5"
@@ -508,16 +573,17 @@
v-if="showAutoPublicSelect" v-if="showAutoPublicSelect"
label="服务商城项目需求模板(公开比选)" label="服务商城项目需求模板(公开比选)"
prop="servicePublicSelectSchool" prop="servicePublicSelectSchool"
class="mb20"> :class="isView ? 'mb16' : 'mb20'">
<template v-if="!isView">
<el-button <el-button
type="primary" type="primary"
link link
icon="Download" icon="Download"
@click="downloadTemplate('public_select')" @click="downloadTemplate('public_select')"
:disabled="isView"
class="mb10"> class="mb10">
下载服务商城项目需求模板公开比选模版 下载服务商城项目需求模板公开比选模版
</el-button> </el-button>
</template>
<upload-file <upload-file
v-model="dataForm.servicePublicSelectSchool" v-model="dataForm.servicePublicSelectSchool"
:limit="5" :limit="5"
@@ -530,7 +596,7 @@
v-if="dataForm.budget && dataForm.budget >= 1000000" v-if="dataForm.budget && dataForm.budget >= 1000000"
label="政府采购意向申请表" label="政府采购意向申请表"
prop="governmentPurchaseIntent" prop="governmentPurchaseIntent"
class="mb20"> :class="isView ? 'mb16' : 'mb20'">
<upload-file <upload-file
v-model="dataForm.governmentPurchaseIntent" v-model="dataForm.governmentPurchaseIntent"
:limit="5" :limit="5"
@@ -540,11 +606,11 @@
</div> </div>
</div> </div>
<el-form-item label="备注" prop="remark" v-if="currentStep === 1"> <el-form-item label="备注" prop="remark" v-if="currentStep === 1 || isView">
<el-input <el-input
v-model="dataForm.remark" v-model="dataForm.remark"
type="textarea" type="textarea"
:rows="3" :rows="isView ? 2 : 3"
placeholder="请输入备注" placeholder="请输入备注"
clearable clearable
:disabled="isView" /> :disabled="isView" />
@@ -638,6 +704,19 @@ const dataForm = reactive({
governmentPurchaseIntent: '', governmentPurchaseIntent: '',
servicePublicSelectSchool: '', servicePublicSelectSchool: '',
}); });
// 定义 props
const props = defineProps<{
dictData?: {
fundSourceList?: any[];
isCentralizedList?: any[];
isSpecialList?: any[];
purchaseTypeDeptList?: any[];
purchaseModeSchoolList?: any[];
purchaseTypeUnionList?: any[];
categoryTreeData?: any[];
};
}>();
const categoryTreeData = ref<any[]>([]); const categoryTreeData = ref<any[]>([]);
const categoryCodePath = ref<string[]>([]); // 级联选择器的路径数组 const categoryCodePath = ref<string[]>([]); // 级联选择器的路径数组
const selectedCategory = ref<any>(null); const selectedCategory = ref<any>(null);
@@ -669,6 +748,77 @@ const stepTwoTitle = computed(() => {
return isDeptPurchase.value ? '部门自行采购' : '学校统一采购'; return isDeptPurchase.value ? '部门自行采购' : '学校统一采购';
}); });
// 获取字典项的label
const getDictLabel = (list: any[], value: string | number | null | undefined): string => {
if (!value || !list || list.length === 0) return '';
const item = list.find(item => item.value === value || item.id === value);
return item ? (item.label || item.dictLabel || item.name || '') : '';
};
// 获取品目编码的显示文本(用于查看模式)
const getCategoryDisplayText = (): string => {
if (!dataForm.categoryCode) return '-';
// 如果 categoryCodePath 已经有值,根据路径查找名称
if (categoryCodePath.value && categoryCodePath.value.length > 0) {
const names: string[] = [];
let currentData = categoryTreeData.value;
for (const code of categoryCodePath.value) {
const found = findCategoryByCode(currentData, code);
if (found) {
names.push(found.name || found.label || code);
currentData = found.children || [];
} else {
names.push(code);
}
}
return names.length > 0 ? names.join(' / ') : dataForm.categoryCode;
}
// 如果 categoryCodePath 没有值,尝试查找路径
if (categoryTreeData.value && categoryTreeData.value.length > 0) {
const path = findCategoryPath(categoryTreeData.value, dataForm.categoryCode);
if (path && path.length > 0) {
// 根据路径查找名称
const names: string[] = [];
let currentData = categoryTreeData.value;
for (const code of path) {
const found = findCategoryByCode(currentData, code);
if (found) {
names.push(found.name || found.label || code);
currentData = found.children || [];
} else {
names.push(code);
}
}
return names.length > 0 ? names.join(' / ') : dataForm.categoryCode;
}
}
return dataForm.categoryCode || '-';
};
// 根据 code 查找分类项
const findCategoryByCode = (data: any[], code: string): any => {
if (!data || !Array.isArray(data) || !code) {
return null;
}
for (const item of data) {
if (item && item.code === code) {
return item;
}
if (item && item.children && Array.isArray(item.children) && item.children.length > 0) {
const found = findCategoryByCode(item.children, code);
if (found) return found;
}
}
return null;
};
// 根据 code 查找完整路径(用于回显) // 根据 code 查找完整路径(用于回显)
const findCategoryPath = (data: any[], targetCode: string, path: string[] = []): string[] | null => { const findCategoryPath = (data: any[], targetCode: string, path: string[] = []): string[] | null => {
for (const item of data) { for (const item of data) {
@@ -929,6 +1079,17 @@ const openDialog = async (type: 'add' | 'edit' | 'view', rowData?: any) => {
servicePublicSelectSchool: '', servicePublicSelectSchool: '',
}); });
// 如果通过 props 传递了字典数据,直接使用;否则调用接口获取
if (props.dictData) {
fundSourceList.value = props.dictData.fundSourceList || [];
isCentralizedList.value = props.dictData.isCentralizedList || [];
isSpecialList.value = props.dictData.isSpecialList || [];
purchaseTypeDeptList.value = props.dictData.purchaseTypeDeptList || [];
purchaseModeSchoolList.value = props.dictData.purchaseModeSchoolList || [];
purchaseTypeUnionList.value = props.dictData.purchaseTypeUnionList || [];
categoryTreeData.value = props.dictData.categoryTreeData || [];
} else {
// 如果没有传递字典数据,则调用接口获取(兼容性处理)
await Promise.all([ await Promise.all([
getCategoryTreeData(), getCategoryTreeData(),
getFundSourceDict(), getFundSourceDict(),
@@ -938,6 +1099,7 @@ const openDialog = async (type: 'add' | 'edit' | 'view', rowData?: any) => {
getPurchaseModeSchoolDict(), getPurchaseModeSchoolDict(),
getPurchaseTypeUnionDict(), getPurchaseTypeUnionDict(),
]); ]);
}
nextTick(() => { nextTick(() => {
formRef.value?.resetFields(); formRef.value?.resetFields();
@@ -946,11 +1108,16 @@ const openDialog = async (type: 'add' | 'edit' | 'view', rowData?: any) => {
getObj(rowData.id) getObj(rowData.id)
.then((res) => { .then((res) => {
Object.assign(dataForm, res.data || {}); Object.assign(dataForm, res.data || {});
// 设置品目编码回显路径 // 设置品目编码回显路径 - 使用 nextTick 确保 categoryTreeData 已经设置
if (dataForm.categoryCode) { if (dataForm.categoryCode) {
nextTick(() => {
setCategoryCodePath(); setCategoryCodePath();
});
} }
if (type === 'edit' || type === 'view') { if (type === 'edit') {
currentStep.value = 1;
} else if (type === 'view') {
// 查看模式下直接显示所有内容,不需要步骤
currentStep.value = 1; currentStep.value = 1;
} }
}) })
@@ -1252,11 +1419,20 @@ const handleTempStore = async () => {
}; };
// 监听 categoryTreeData 变化,设置回显路径 // 监听 categoryTreeData 变化,设置回显路径
watch(() => categoryTreeData.value, () => { watch(() => categoryTreeData.value, (newVal) => {
if (dataForm.categoryCode) { if (newVal && newVal.length > 0 && dataForm.categoryCode) {
setCategoryCodePath(); setCategoryCodePath();
} }
}, { deep: true }); }, { deep: true, immediate: false });
// 监听 dataForm.categoryCode 变化,设置回显路径(用于查看模式)
watch(() => dataForm.categoryCode, (newVal) => {
if (newVal && categoryTreeData.value && categoryTreeData.value.length > 0) {
nextTick(() => {
setCategoryCodePath();
});
}
});
// 暴露变量 // 暴露变量
defineExpose({ defineExpose({
@@ -1268,6 +1444,9 @@ defineExpose({
.mb20 { .mb20 {
margin-bottom: 20px; margin-bottom: 20px;
} }
.mb16 {
margin-bottom: 16px;
}
.mb10 { .mb10 {
margin-bottom: 10px; margin-bottom: 10px;
} }
@@ -1285,4 +1464,57 @@ defineExpose({
margin-top: 5px; margin-top: 5px;
color: var(--el-text-color-secondary); color: var(--el-text-color-secondary);
} }
/* 查看模式优化样式 */
:deep(.view-dialog) {
.el-dialog__body {
max-height: calc(100vh - 150px);
overflow-y: auto;
overflow-x: hidden;
padding: 20px;
}
}
.view-content {
max-height: calc(100vh - 200px);
overflow-y: auto;
overflow-x: hidden;
}
.view-form {
/* 查看模式下使用更紧凑的布局 */
}
.view-form :deep(.el-form-item) {
margin-bottom: 16px;
}
.view-form :deep(.el-form-item__label) {
font-weight: 500;
color: #606266;
}
/* 查看模式文本样式 */
.view-text {
color: #303133;
font-size: 14px;
line-height: 1.5;
word-break: break-word;
}
.view-textarea {
white-space: pre-wrap;
min-height: 40px;
padding: 8px 0;
}
/* 查看模式下两列布局优化 */
.view-form :deep(.el-row) {
margin-bottom: 0;
}
.view-form :deep(.el-col) {
margin-bottom: 16px;
}
</style> </style>

View File

@@ -102,16 +102,10 @@
<el-icon><List /></el-icon> <el-icon><List /></el-icon>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="code" label="编号" min-width="120" show-overflow-tooltip> <el-table-column prop="code" label="申请单编号" min-width="140" show-overflow-tooltip>
<template #header> <template #header>
<el-icon><DocumentCopy /></el-icon> <el-icon><DocumentCopy /></el-icon>
<span style="margin-left: 4px">编号</span> <span style="margin-left: 4px">申请单编号</span>
</template>
</el-table-column>
<el-table-column prop="purchaseNo" label="采购编号" min-width="120" show-overflow-tooltip>
<template #header>
<el-icon><DocumentCopy /></el-icon>
<span style="margin-left: 4px">采购编号</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="projectName" label="采购项目名称" min-width="200" show-overflow-tooltip> <el-table-column prop="projectName" label="采购项目名称" min-width="200" show-overflow-tooltip>
@@ -120,27 +114,57 @@
<span style="margin-left: 4px">采购项目名称</span> <span style="margin-left: 4px">采购项目名称</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="projectType" label="项目类别" width="100" align="center"> <el-table-column prop="applyDate" label="填报日期" width="120" align="center" show-overflow-tooltip>
<template #header>
<el-icon><Calendar /></el-icon>
<span style="margin-left: 4px">填报日期</span>
</template>
</el-table-column>
<el-table-column prop="deptName" label="需求部门" min-width="150" show-overflow-tooltip>
<template #header>
<el-icon><OfficeBuilding /></el-icon>
<span style="margin-left: 4px">需求部门</span>
</template>
</el-table-column>
<el-table-column prop="projectType" label="项目类别" min-width="200" align="left" show-overflow-tooltip>
<template #header> <template #header>
<el-icon><Collection /></el-icon> <el-icon><Collection /></el-icon>
<span style="margin-left: 4px">项目类别</span> <span style="margin-left: 4px">项目类别</span>
</template> </template>
<template #default="scope"> <template #default="scope">
<el-tag v-if="scope.row.projectType === 'A'" type="success">货物</el-tag> <div>
<el-tag v-else-if="scope.row.projectType === 'B'" type="warning">工程</el-tag> <el-tag v-if="scope.row.projectType === 'A'" type="success" style="margin-right: 8px;">货物</el-tag>
<el-tag v-else-if="scope.row.projectType === 'C'" type="info">服务</el-tag> <el-tag v-else-if="scope.row.projectType === 'B'" type="warning" style="margin-right: 8px;">工程</el-tag>
<span v-else>-</span> <el-tag v-else-if="scope.row.projectType === 'C'" type="info" style="margin-right: 8px;">服务</el-tag>
<span v-if="scope.row.categoryName" style="color: #606266; font-size: 12px;">
{{ scope.row.categoryName }}
</span>
<span v-else-if="scope.row.categoryCode" style="color: #909399; font-size: 12px;">
{{ scope.row.categoryCode }}
</span>
</div>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="budget" label="预算金额(元)" width="120" align="right"> <el-table-column prop="budget" label="项目预算(元)" width="130" align="right">
<template #header> <template #header>
<el-icon><Money /></el-icon> <el-icon><Money /></el-icon>
<span style="margin-left: 4px">预算金额</span> <span style="margin-left: 4px">项目预算</span>
</template> </template>
<template #default="scope"> <template #default="scope">
{{ scope.row.budget ? Number(scope.row.budget).toLocaleString() : '-' }} {{ scope.row.budget ? Number(scope.row.budget).toLocaleString() : '-' }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="isSpecial" label="是否特殊" width="100" align="center">
<template #header>
<el-icon><Warning /></el-icon>
<span style="margin-left: 4px">是否特殊</span>
</template>
<template #default="scope">
<el-tag v-if="scope.row.isSpecial === '1' || scope.row.isSpecial === 1" type="warning"></el-tag>
<el-tag v-else-if="scope.row.isSpecial === '0' || scope.row.isSpecial === 0" type="info"></el-tag>
<span v-else>-</span>
</template>
</el-table-column>
<el-table-column prop="isCentralized" label="是否集采" width="100" align="center"> <el-table-column prop="isCentralized" label="是否集采" width="100" align="center">
<template #header> <template #header>
<el-icon><CircleCheck /></el-icon> <el-icon><CircleCheck /></el-icon>
@@ -152,10 +176,10 @@
<span v-else>-</span> <span v-else>-</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="status" label="状态" width="100" align="center"> <el-table-column prop="status" label="审核状态" width="100" align="center">
<template #header> <template #header>
<el-icon><InfoFilled /></el-icon> <el-icon><InfoFilled /></el-icon>
<span style="margin-left: 4px">状态</span> <span style="margin-left: 4px">审核状态</span>
</template> </template>
<template #default="scope"> <template #default="scope">
<el-tag v-if="scope.row.status === '-2'" type="info">撤回</el-tag> <el-tag v-if="scope.row.status === '-2'" type="info">撤回</el-tag>
@@ -167,13 +191,7 @@
<span v-else>-</span> <span v-else>-</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="createTime" label="创建时间" width="180" show-overflow-tooltip> <el-table-column label="操作" align="center" fixed="right" width="300">
<template #header>
<el-icon><Clock /></el-icon>
<span style="margin-left: 4px">创建时间</span>
</template>
</el-table-column>
<el-table-column label="操作" align="center" fixed="right" width="200">
<template #default="scope"> <template #default="scope">
<el-button <el-button
icon="View" icon="View"
@@ -204,10 +222,10 @@
<!-- 分页 --> <!-- 分页 -->
<pagination <pagination
v-show="state.total > 0" v-if="state.pagination && state.pagination.total && state.pagination.total > 0"
:total="state.total" :total="state.pagination.total"
v-model:page="state.page" :current="state.pagination.current"
v-model:limit="state.limit" :size="state.pagination.size"
@pagination="getDataList" @pagination="getDataList"
/> />
</el-card> </el-card>
@@ -217,7 +235,8 @@
<el-dialog <el-dialog
v-model="showAddIframe" v-model="showAddIframe"
title="新增采购申请" title="新增采购申请"
width="1000px" width="90%"
:style="{ maxWidth: '1600px' }"
:close-on-click-modal="false" :close-on-click-modal="false"
:close-on-press-escape="true" :close-on-press-escape="true"
destroy-on-close destroy-on-close
@@ -229,26 +248,42 @@
:src="addIframeSrc" :src="addIframeSrc"
frameborder="0" frameborder="0"
class="add-iframe" class="add-iframe"
@load="onIframeLoad" /> />
</div> </div>
</el-dialog> </el-dialog>
<!-- 编辑新增表单对话框 --> <!-- 编辑新增表单对话框 -->
<FormDialog ref="formDialogRef" @refresh="getDataList" /> <FormDialog
ref="formDialogRef"
:dict-data="dictData"
@refresh="getDataList" />
</div> </div>
</template> </template>
<script setup lang="ts" name="PurchasingRequisition"> <script setup lang="ts" name="PurchasingRequisition">
import { ref, reactive, defineAsyncComponent, onUnmounted } from 'vue' import { ref, reactive, defineAsyncComponent, onUnmounted, onMounted } from 'vue'
import { useRouter } from 'vue-router' import { useRouter } from 'vue-router'
import { BasicTableProps, useTable } from "/@/hooks/table"; import { BasicTableProps, useTable } from "/@/hooks/table";
import { getPage, delObj } from "/@/api/finance/purchasingrequisition"; import { getPage, delObj } from "/@/api/finance/purchasingrequisition";
import { useMessage, useMessageBox } from "/@/hooks/message"; import { useMessage, useMessageBox } from "/@/hooks/message";
import { List, Document, DocumentCopy, Search, Collection, Money, CircleCheck, InfoFilled, Clock } from '@element-plus/icons-vue' import { getDicts } from '/@/api/admin/dict';
import { getTree } from '/@/api/finance/purchasingcategory';
import { List, Document, DocumentCopy, Search, Collection, Money, CircleCheck, InfoFilled, Calendar, OfficeBuilding, Warning } from '@element-plus/icons-vue'
// 引入组件 // 引入组件
const FormDialog = defineAsyncComponent(() => import('./form.vue')); const FormDialog = defineAsyncComponent(() => import('./form.vue'));
// 字典数据和品目树数据
const dictData = ref({
fundSourceList: [] as any[],
isCentralizedList: [] as any[],
isSpecialList: [] as any[],
purchaseTypeDeptList: [] as any[],
purchaseModeSchoolList: [] as any[],
purchaseTypeUnionList: [] as any[],
categoryTreeData: [] as any[],
});
// 定义变量内容 // 定义变量内容
const router = useRouter() const router = useRouter()
const tableRef = ref() const tableRef = ref()
@@ -332,11 +367,7 @@ const handleIframeMessage = (event: MessageEvent) => {
*/ */
const handleDelete = async (row: any) => { const handleDelete = async (row: any) => {
try { try {
await useMessageBox().confirm('确定要删除该记录吗?', '提示', { await useMessageBox().confirm('确定要删除该记录吗?');
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
});
} catch { } catch {
return; return;
} }
@@ -350,6 +381,151 @@ const handleDelete = async (row: any) => {
} }
}; };
// 获取字典数据和品目树数据
const loadDictData = async () => {
try {
const [
fundSourceRes,
isCentralizedRes,
isSpecialRes,
purchaseTypeDeptRes,
purchaseModeSchoolRes,
purchaseTypeUnionRes,
categoryTreeRes
] = await Promise.all([
getDicts('PURCHASE_FUND_SOURCE'),
getDicts('PURCHASE_IS_CEN'),
getDicts('PURCHASE_IS_SPEC'),
getDicts('PURCHASE_TYPE_DEPT'),
getDicts('PURCHASE_MODE_SCHOOL'),
getDicts('PURCHASE_TYPE_UNION'),
getTree()
]);
// 处理资金来源字典
if (fundSourceRes.data && Array.isArray(fundSourceRes.data)) {
dictData.value.fundSourceList = fundSourceRes.data.map((item: any) => ({
label: item.label || item.dictLabel || item.name,
value: item.value || item.dictValue || item.code
}));
} else {
dictData.value.fundSourceList = [
{ label: '切块经费', value: '0' },
{ label: '设备购置费', value: '1' },
{ label: '专项经费', value: '2' },
{ label: '代办费', value: '3' },
{ label: '培训经费', value: '4' },
{ label: '日常公用经费', value: '5' },
{ label: '技能大赛经费', value: '6' },
{ label: '基本建设资金', value: '7' },
{ label: '暂存款', value: '8' },
{ label: '会议费', value: '9' },
];
}
// 处理是否集采字典
if (isCentralizedRes.data && Array.isArray(isCentralizedRes.data)) {
dictData.value.isCentralizedList = isCentralizedRes.data.map((item: any) => ({
label: item.label || item.dictLabel || item.name,
value: item.value || item.dictValue || item.code
}));
} else {
dictData.value.isCentralizedList = [
{ label: '否', value: '0' },
{ label: '政府集中采购', value: '1' },
{ label: '学校集中采购', value: '2' }
];
}
// 处理是否特殊情况字典
if (isSpecialRes.data && Array.isArray(isSpecialRes.data)) {
dictData.value.isSpecialList = isSpecialRes.data.map((item: any) => ({
label: item.label || item.dictLabel || item.name,
value: item.value || item.dictValue || item.code
}));
} else {
dictData.value.isSpecialList = [
{ label: '否', value: '0' },
{ label: '紧急', value: '1' },
{ label: '单一', value: '2' },
{ label: '进口', value: '3' }
];
}
// 处理部门采购方式字典
if (purchaseTypeDeptRes.data && Array.isArray(purchaseTypeDeptRes.data)) {
dictData.value.purchaseTypeDeptList = purchaseTypeDeptRes.data.map((item: any) => ({
label: item.label || item.dictLabel || item.name,
value: item.value || item.dictValue || item.code
}));
}
// 处理学校采购形式字典
if (purchaseModeSchoolRes.data && Array.isArray(purchaseModeSchoolRes.data)) {
dictData.value.purchaseModeSchoolList = purchaseModeSchoolRes.data.map((item: any) => ({
label: item.label || item.dictLabel || item.name,
value: item.value || item.dictValue || item.code
}));
} else {
dictData.value.purchaseModeSchoolList = [
{ label: '政府采购', value: '1' },
{ label: '学校自主采购', value: '2' }
];
}
// 处理学校统一采购方式字典
if (purchaseTypeUnionRes.data && Array.isArray(purchaseTypeUnionRes.data)) {
dictData.value.purchaseTypeUnionList = purchaseTypeUnionRes.data.map((item: any) => ({
label: item.label || item.dictLabel || item.name,
value: item.value || item.dictValue || item.code
}));
}
// 处理品目树数据
if (categoryTreeRes.data && Array.isArray(categoryTreeRes.data)) {
dictData.value.categoryTreeData = categoryTreeRes.data;
} else {
dictData.value.categoryTreeData = [];
}
} catch (err) {
console.error('加载字典数据失败', err);
// 设置默认值
dictData.value.fundSourceList = [
{ label: '切块经费', value: '0' },
{ label: '设备购置费', value: '1' },
{ label: '专项经费', value: '2' },
{ label: '代办费', value: '3' },
{ label: '培训经费', value: '4' },
{ label: '日常公用经费', value: '5' },
{ label: '技能大赛经费', value: '6' },
{ label: '基本建设资金', value: '7' },
{ label: '暂存款', value: '8' },
{ label: '会议费', value: '9' },
];
dictData.value.isCentralizedList = [
{ label: '否', value: '0' },
{ label: '政府集中采购', value: '1' },
{ label: '学校集中采购', value: '2' }
];
dictData.value.isSpecialList = [
{ label: '否', value: '0' },
{ label: '紧急', value: '1' },
{ label: '单一', value: '2' },
{ label: '进口', value: '3' }
];
dictData.value.purchaseModeSchoolList = [
{ label: '政府采购', value: '1' },
{ label: '学校自主采购', value: '2' }
];
dictData.value.categoryTreeData = [];
}
};
// 页面加载时获取字典数据和品目树数据
onMounted(() => {
loadDictData();
});
// 组件卸载时清理事件监听器 // 组件卸载时清理事件监听器
onUnmounted(() => { onUnmounted(() => {
window.removeEventListener('message', handleIframeMessage) window.removeEventListener('message', handleIframeMessage)