@@ -0,0 +1,14 @@ | |||||
<script setup name="commonLogin"> | |||||
import { onMounted } from 'vue' | |||||
import { singleLogin } from '@/http/apis/auth' | |||||
import { useRoute, useRouter } from 'vue-router' | |||||
const route = useRoute(), | |||||
router = useRouter() | |||||
onMounted(async () => { | |||||
const postData = new URLSearchParams() | |||||
postData.append('credential', route.query.PROVINCE_FOREIGN_USER_TOKEN) | |||||
postData.append('platform', 'PROVINCIAL_BUREAU') | |||||
await singleLogin(postData) | |||||
router.replace('/') | |||||
}) | |||||
</script> |
@@ -0,0 +1,266 @@ | |||||
<script setup name="applicationRegist"> | |||||
import { ref, reactive, onMounted, getCurrentInstance } from 'vue' | |||||
// import { declareExport } from '@/http/apis/declareMange' | |||||
import { useRouter } from 'vue-router' | |||||
// import useExportExc from '@/utils/useExportExc' | |||||
import { list, pushProjectApp } from '@/http/apis/declareMange/applicationRegist' | |||||
import store from '@/store' | |||||
const router = useRouter(), | |||||
{ digitalModifySystem, projectTypeOptions } = store.dictStore.globalDicts, | |||||
{ proxy } = getCurrentInstance() | |||||
// 搜索栏表单数据 | |||||
const searchForm = reactive({ | |||||
projectType: undefined, | |||||
status: undefined, | |||||
projectYear: undefined, | |||||
projectName: undefined, | |||||
createOnMin: undefined, | |||||
createOnMax: undefined, | |||||
times: [] | |||||
}), | |||||
column = reactive([ | |||||
{ | |||||
type: 'expand' | |||||
}, | |||||
{ | |||||
label: '序号', | |||||
type: 'index', | |||||
width: '80' | |||||
}, | |||||
{ | |||||
label: '项目名称', | |||||
key: 'projectName', | |||||
prop: 'projectName', | |||||
minWidth: '200', | |||||
showOverflowTooltip: true | |||||
}, | |||||
{ | |||||
label: '项目类型', | |||||
key: 'projectTypeName', | |||||
prop: 'projectTypeName', | |||||
width: '80' | |||||
}, | |||||
{ | |||||
label: '预算年度', | |||||
key: 'projectYear', | |||||
prop: 'projectYear', | |||||
width: 80 | |||||
}, | |||||
{ | |||||
label: '批复时间', | |||||
key: 'approvalDate', | |||||
prop: 'approvalDate', | |||||
width: '110' | |||||
}, | |||||
{ | |||||
label: '批复金额(万元)', | |||||
key: 'approvedAmount', | |||||
prop: 'approvedAmount', | |||||
width: '140' | |||||
}, | |||||
{ | |||||
label: '创建时间', | |||||
key: 'createOn', | |||||
prop: 'createOn', | |||||
width: '200' | |||||
}, | |||||
{ | |||||
label: '操作', | |||||
slot: 'action', | |||||
width: '120', | |||||
fixed: 'right' | |||||
} | |||||
]), | |||||
data = ref([]), | |||||
tableListRef = ref(), | |||||
getTableData = async (pageParams = tableListRef.value.pageParams) => { | |||||
const res = await list({ | |||||
...pageParams, | |||||
...searchForm, | |||||
createOnMin: searchForm.times?.[0], | |||||
createOnMax: searchForm.times?.[1], | |||||
projectYear: searchForm.projectYear * 1 || undefined, | |||||
times: undefined | |||||
}) | |||||
data.value = res.data.records | |||||
total.value = res.data.total | |||||
}, | |||||
// 数据总数 | |||||
total = ref(2), | |||||
// 提交查询 | |||||
search = () => { | |||||
getTableData() | |||||
}, | |||||
// 重置 | |||||
formReset = () => { | |||||
searchForm.projectYear = undefined | |||||
searchForm.projectName = undefined | |||||
searchForm.projectType = undefined | |||||
searchForm.createOnMin = undefined | |||||
searchForm.createOnMax = undefined | |||||
searchForm.times = undefined | |||||
tableListRef.value.pageParams.pageNumber = 1 | |||||
tableListRef.value.pageParams.pageSize = 10 | |||||
getTableData() | |||||
}, | |||||
// // 导出excel文件 | |||||
// { exportLoading, exportData } = useExportExc(), | |||||
// handleExcel = () => { | |||||
// exportData(() => declareExport(6, { | |||||
// ...searchForm, | |||||
// createOnMin: searchForm.times?.[0], | |||||
// createOnMax: searchForm.times?.[1], | |||||
// projectYear: searchForm.projectYear * 1 || undefined, | |||||
// times: undefined | |||||
// })) | |||||
// }, | |||||
// 应用注册 | |||||
visible = ref(false), | |||||
appData = ref(), | |||||
showDialog = (data) => { | |||||
visible.value = true | |||||
appData.value = data | |||||
} | |||||
onMounted(async () => { | |||||
getTableData() | |||||
window.onmessage = async (event) => { | |||||
if (event.data && event.data.msg === '编码已生成,请复制编码查询应用') { | |||||
console.log(event.data, '编码') | |||||
appData.value['appCode'] = event.data.data | |||||
await pushProjectApp(appData.value) | |||||
proxy.$message.success('注册成功') | |||||
visible.value = false | |||||
getTableData() | |||||
} | |||||
} | |||||
}) | |||||
</script> | |||||
<template> | |||||
<el-card class="w-full search"> | |||||
<el-form :model="searchForm" size="small" label-suffix=":"> | |||||
<el-row :gutter="16" class="mb-16"> | |||||
<el-col :span="8"> | |||||
<el-form-item label="项目名称"> | |||||
<el-input | |||||
v-model="searchForm.projectName" | |||||
maxlength="50" | |||||
placeholder="请输入" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<el-form-item label="项目类型"> | |||||
<el-select | |||||
v-model="searchForm.projectType" | |||||
placeholder="全部" | |||||
class="w-full" | |||||
> | |||||
<el-option | |||||
v-for="(v,k) in projectTypeOptions" | |||||
:key="k" | |||||
:label="v" | |||||
:value="k" | |||||
/> | |||||
</el-select> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<el-form-item label="预算年度"> | |||||
<el-date-picker | |||||
v-model="searchForm.projectYear" | |||||
type="year" | |||||
placeholder="请选择" | |||||
format="YYYY" | |||||
value-format="YYYY" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
</el-row> | |||||
<el-row :gutter="24"> | |||||
<el-col :span="12"> | |||||
<el-form-item label="创建时间"> | |||||
<el-date-picker | |||||
v-model="searchForm.times" | |||||
type="datetimerange" | |||||
range-separator="-" | |||||
start-placeholder="开始时间" | |||||
end-placeholder="结束时间" | |||||
format="YYYY-MM-DD HH:mm" | |||||
value-format="YYYY-MM-DD HH:mm" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="12"> | |||||
<el-form-item class="btn"> | |||||
<div class="flex"> | |||||
<el-button type="primary" @click="search">查询</el-button> | |||||
<el-button @click="formReset">重置</el-button> | |||||
</div> | |||||
</el-form-item> | |||||
</el-col> | |||||
</el-row> | |||||
</el-form> | |||||
</el-card> | |||||
<el-card class="w-full mt-8"> | |||||
<template #header> | |||||
<div class="flex justify-between"> | |||||
<span>列表</span> | |||||
<!-- <div>--> | |||||
<!-- <el-button--> | |||||
<!-- type="primary"--> | |||||
<!-- size="small"--> | |||||
<!-- plain--> | |||||
<!-- :loading="exportLoading"--> | |||||
<!-- @click="handleExcel"--> | |||||
<!-- >--> | |||||
<!-- 导出--> | |||||
<!-- </el-button>--> | |||||
<!-- </div>--> | |||||
</div> | |||||
</template> | |||||
<table-list | |||||
ref="tableListRef" | |||||
:column="column" | |||||
:data="data" | |||||
:total="total" | |||||
@get-table-data="getTableData" | |||||
> | |||||
<template #expand="{scope}"> | |||||
<div | |||||
v-for="(item,index) in scope.row.projectApplications" | |||||
:key="index" | |||||
class="flex py-8" | |||||
style="padding-left: 140px;border-bottom: 1px solid rgb(235, 238, 245)" | |||||
> | |||||
<p class="flex-1 pr-4"> | |||||
应用名称:{{ item.applicationName ||item.relatedExistsApplication }} | |||||
</p> | |||||
<p class="flex-1 pr-4"> | |||||
数改系统:{{ item.digitalModification&&item.digitalModification.split(',').map(i=>digitalModifySystem[i]).join(',')||'-' }} | |||||
</p> | |||||
<p class="flex-1 pr-4"> | |||||
是否初次建设:{{ item.isFirst?'是':'否' }} | |||||
</p> | |||||
<p class="flex-1 pr-4"> | |||||
是否注册:{{ item.isFirst&&item.appCode?'是':item.isFirst&&!item.appCode?'否':'--' }} | |||||
</p> | |||||
<p class="flex-1"> | |||||
<a v-if="!item.appCode" @click="showDialog({projectCode:scope.row.projectCode,appId:item.id})">应用注册</a> | |||||
</p> | |||||
</div> | |||||
</template> | |||||
<template #action="{ scope }"> | |||||
<a @click="router.push({name:'applicationRegistDetail',query:{id:scope.row.id}})">详情</a> | |||||
</template> | |||||
</table-list> | |||||
</el-card> | |||||
<el-dialog | |||||
:model-value="visible" | |||||
title="应用注册" | |||||
width="80%" | |||||
@close="visible=false" | |||||
> | |||||
<iframe src="https://jdirs.zj.gov.cn/api/system/register-view?X-BG-HMAC-ACCESS-KEY=42bcb49bea174986a3bfdfba7d005566&path=Ovl4aua87eB" width="100%" height="700px"></iframe> | |||||
</el-dialog> | |||||
</template> | |||||
<style lang="less" scoped></style> |
@@ -0,0 +1,323 @@ | |||||
<script setup name = 'constructionPlanDeclare'> | |||||
import { ref, reactive, onMounted, getCurrentInstance } from 'vue' | |||||
import { useRouter } from 'vue-router' | |||||
import { genFileId } from 'element-plus' | |||||
import store from '@/store' | |||||
import { | |||||
getConstructionDeclarePlan, | |||||
declareConstructionScheme, | |||||
declareExport | |||||
} from '@/http/apis/declareMange' | |||||
import { fileFormatVerification, handleFileSuccess, fileTypes, fileDesc, handleFilePreview } from '@/utils/uploadAction.js' | |||||
import useExportExc from '@/utils/useExportExc' | |||||
const { projectTypeOptions } = store.dictStore.globalDicts || {} | |||||
// 搜索栏表单数据 | |||||
const { proxy } = getCurrentInstance(), | |||||
formInline = reactive({ | |||||
projectName: '', | |||||
projectType: '', | |||||
projectYear: null, | |||||
startTime: '', | |||||
endTime: '', | |||||
createTimeArr: [] | |||||
}), | |||||
router = useRouter(), | |||||
tableListRef = ref(), | |||||
selectData = ref([]), | |||||
getTableData = async (pageParams = tableListRef.value.pageParams) => { | |||||
const res = await getConstructionDeclarePlan({ | |||||
...pageParams, | |||||
...formInline, | |||||
startTime: formInline.createTimeArr?.length | |||||
? formInline.createTimeArr[0] | |||||
: undefined, | |||||
endTime: formInline.createTimeArr?.length | |||||
? formInline.createTimeArr[0] | |||||
: undefined, | |||||
createTimeArr: undefined | |||||
}) | |||||
selectData.value = res.data.records | |||||
total.value = res.data.total | |||||
}, | |||||
column = reactive([ | |||||
{ | |||||
label: '序号', | |||||
type: 'index', | |||||
width: '80' | |||||
}, | |||||
{ | |||||
label: '项目名称', | |||||
key: 'projectName', | |||||
prop: 'projectName', | |||||
minWidth: '200', | |||||
showOverflowTooltip: true | |||||
}, | |||||
{ | |||||
label: '项目类型', | |||||
key: 'projectTypeName', | |||||
prop: 'projectTypeName', | |||||
width: 80 | |||||
}, | |||||
{ | |||||
label: '申报金额(万元)', | |||||
key: 'declaredAmount', | |||||
prop: 'declaredAmount', | |||||
width: '200' | |||||
}, | |||||
{ | |||||
label: '预算年度', | |||||
key: 'projectYear', | |||||
prop: 'projectYear', | |||||
width: '100' | |||||
}, | |||||
{ | |||||
label: '创建时间', | |||||
key: 'createOn', | |||||
prop: 'createOn', | |||||
width: '250' | |||||
}, | |||||
{ | |||||
label: '操作', | |||||
slot: 'action', | |||||
width: '140', | |||||
fixed: 'right' | |||||
} | |||||
]), | |||||
// projectData = reactive([]), | |||||
rules = reactive({ | |||||
constructionPlanFile: [ | |||||
{ required: true, message: '请上传建设方案', trigger: 'blur' } | |||||
] }), | |||||
// 数据总数 | |||||
total = ref(2), | |||||
checkDetail = (detailData) => { | |||||
// console.log('detailData', detailData) | |||||
router.push({ name: 'projectDeclareDetail', query: { id: detailData.id }}) | |||||
}, | |||||
// 提交查询 | |||||
onSubmit = () => { | |||||
getTableData() | |||||
}, | |||||
formReset = () => { | |||||
formInline.projectName = null | |||||
formInline.projectType = null | |||||
formInline.projectYear = null | |||||
formInline.startTime = null | |||||
formInline.endTime = null | |||||
formInline.createTimeArr = null | |||||
getTableData() | |||||
}, | |||||
// 导出excel文件 | |||||
tableDom = ref(), | |||||
handleTable = (value) => { | |||||
tableDom.value = value | |||||
}, | |||||
// handleExcel = () => { | |||||
// exportExcel(tableDom.value) | |||||
// }, | |||||
// 申报方案 | |||||
// declarePlan = (val) => { | |||||
// projectId.value = val.id | |||||
// dialogVisible.value = true | |||||
// if (upload.value)upload.value.clearFiles() | |||||
// }, | |||||
dialogVisible = ref(false), | |||||
handleClose = (done) => { | |||||
done() | |||||
}, | |||||
// 文件上传 | |||||
uploadUrl = store.dictStore.uploadUrl, | |||||
ruleForm = reactive({ | |||||
constructionPlanFile: [] | |||||
}), | |||||
upload = ref(), | |||||
planUploadRef = ref(), | |||||
constructionPlanRef = ref(), | |||||
handleExceed = (files) => { | |||||
upload.value.clearFiles() | |||||
const file = files[0] | |||||
file.uid = genFileId() | |||||
upload.value.handleStart(file) | |||||
}, | |||||
projectId = ref(), | |||||
submitUpload = async (formEl) => { | |||||
if (!formEl) return | |||||
formEl.validate((valid) => { | |||||
if (valid) { | |||||
declareConstructionSchemeFunction() | |||||
} else { | |||||
console.log('error submit!') | |||||
} | |||||
}) | |||||
}, | |||||
declareConstructionSchemeFunction = async () => { | |||||
await declareConstructionScheme({ | |||||
projectInfo: { | |||||
id: projectId.value, | |||||
constructionPlanFile: JSON.stringify(ruleForm.constructionPlanFile && ruleForm.constructionPlanFile.map(i => { | |||||
return { | |||||
fileId: i.response.data.id, | |||||
fileName: i.response.data.originalFileName | |||||
} | |||||
})[0]) | |||||
} | |||||
}) | |||||
dialogVisible.value = false | |||||
ruleForm.constructionPlanFile = [] | |||||
proxy.$message.success('提交成功') | |||||
getTableData() | |||||
}, | |||||
// 导出excel文件 | |||||
{ exportLoading, exportData } = useExportExc(), | |||||
handleExcel = () => { | |||||
exportData(() => declareExport(3, { | |||||
...formInline, | |||||
year: formInline.year * 1, | |||||
startTime: formInline.createTimeArr?.length | |||||
? formInline.createTimeArr[0] | |||||
: undefined, | |||||
endTime: formInline.createTimeArr?.length | |||||
? formInline.createTimeArr[0] | |||||
: undefined, | |||||
createTimeArr: undefined | |||||
})) | |||||
} | |||||
onMounted(async () => { | |||||
getTableData() | |||||
}) | |||||
</script> | |||||
<template> | |||||
<el-card class="w-full search"> | |||||
<el-form :model="formInline" size="small" label-suffix=":"> | |||||
<el-row :gutter="16" class="mb-16"> | |||||
<el-col :span="8"> | |||||
<el-form-item label="项目名称"> | |||||
<el-input v-model="formInline.projectName" maxlength="50" placeholder="请输入" /> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<el-form-item label="项目类型"> | |||||
<el-select v-model="formInline.projectType" placeholder="全部" class="w-full"> | |||||
<el-option | |||||
v-for="(v,k) in projectTypeOptions" | |||||
:key="k" | |||||
:label="v" | |||||
:value="k" | |||||
/> | |||||
</el-select> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<el-form-item label="预算年度"> | |||||
<el-date-picker | |||||
v-model="formInline.projectYear" | |||||
type="year" | |||||
placeholder="请选择" | |||||
format="YYYY" | |||||
value-format="YYYY" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
</el-row> | |||||
<el-row :gutter="16"> | |||||
<el-col :span="10"> | |||||
<el-form-item label="创建时间"> | |||||
<el-date-picker | |||||
v-model="formInline.createTimeArr" | |||||
type="datetimerange" | |||||
range-separator="-" | |||||
start-placeholder="开始时间" | |||||
end-placeholder="结束时间" | |||||
format="YYYY-MM-DD HH:mm" | |||||
value-format="YYYY-MM-DD HH:mm" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="14"> | |||||
<el-form-item class="btn"> | |||||
<div class="flex"> | |||||
<el-button type="primary" @click="onSubmit">查询</el-button> | |||||
<el-button @click="formReset">重置</el-button> | |||||
</div> | |||||
</el-form-item> | |||||
</el-col> | |||||
</el-row> | |||||
</el-form> | |||||
</el-card> | |||||
<el-card class="w-full mt-8"> | |||||
<template #header> | |||||
<div class="flex justify-between"> | |||||
<span>待申报的项目</span> | |||||
<div> | |||||
<el-button | |||||
type="primary" | |||||
plain | |||||
size="small" | |||||
:loading="exportLoading" | |||||
@click="handleExcel" | |||||
>导出</el-button> | |||||
</div> | |||||
</div> | |||||
</template> | |||||
<table-list | |||||
ref="tableListRef" | |||||
:column="column" | |||||
:data="selectData" | |||||
:total="total" | |||||
@handle-table="handleTable" | |||||
@get-table-data="getTableData" | |||||
> | |||||
<template #action="{ scope }"> | |||||
<a @click="$router.push({name:'declarePlan',query:{id:scope.row.id}})">申报方案</a> | |||||
<a @click="checkDetail(scope.row)">详情</a> | |||||
</template> | |||||
</table-list> | |||||
</el-card> | |||||
<el-dialog | |||||
v-model="dialogVisible" | |||||
title="申报建设方案" | |||||
width="35%" | |||||
:before-close="handleClose" | |||||
> | |||||
<el-form | |||||
ref="constructionPlanRef" | |||||
:model="ruleForm" | |||||
:rules="rules" | |||||
label-position="right" | |||||
label-width="auto" | |||||
status-icon | |||||
> | |||||
<el-form-item label="建设方案:" prop="constructionPlanFile"> | |||||
<el-upload | |||||
ref="planUploadRef" | |||||
v-model:file-list="ruleForm.constructionPlanFile" | |||||
:action="uploadUrl" | |||||
:limit="1" | |||||
:on-exceed="handleExceed" | |||||
:on-success="res => handleFileSuccess(res, ruleForm.constructionPlanFile, true)" | |||||
:before-upload="file=>fileFormatVerification(file, {types: fileTypes})" | |||||
:accept="fileTypes.map(i=>`.${i}`).join(',')" | |||||
:on-preview="handleFilePreview" | |||||
> | |||||
<el-button plain type="primary">选择文件</el-button> | |||||
<template #tip> | |||||
<div class="el-upload__tip"> | |||||
支持{{ fileDesc }}文件 | |||||
</div> | |||||
</template> | |||||
</el-upload> | |||||
</el-form-item> | |||||
</el-form> | |||||
<template #footer> | |||||
<span class="dialog-footer"> | |||||
<el-button type="primary" @click="submitUpload(constructionPlanRef)"> | |||||
提交 | |||||
</el-button> | |||||
<el-button @click="dialogVisible = false">关闭</el-button> | |||||
</span> | |||||
</template> | |||||
</el-dialog> | |||||
</template> | |||||
<style lang='less' scoped> | |||||
</style> |
@@ -0,0 +1,466 @@ | |||||
<script setup name="fillContractInfo"> | |||||
import { getCurrentInstance, ref, onMounted } from 'vue' | |||||
import { changFilesParam, fileFormatVerification, handleFileSuccess, reviewFileParam, fileTypes, fileDesc, handleFilePreview } from '@/utils/uploadAction.js' | |||||
import store from '@/store' | |||||
import { useRouter, useRoute } from 'vue-router' | |||||
import { contractDetail, submitContract, supplement } from '@/http/apis/declareMange/contractRecord' | |||||
const uploadUrl = store.dictStore.uploadUrl, | |||||
{ proxy } = getCurrentInstance(), | |||||
router = useRouter(), | |||||
route = useRoute() | |||||
const formRef = ref(), | |||||
moneyValidator = (rule, value, callback) => { | |||||
if (!value) callback() | |||||
if (!/^\d+(\.\d{1,6})?$/.test(value)) { | |||||
callback('请输入正确格式,最多保留六位小数') | |||||
} else if (value * 1 >= 100000000) { | |||||
callback('请输入正确格式,小于100000000') | |||||
} else { | |||||
callback() | |||||
} | |||||
}, | |||||
rules = { | |||||
name: [{ required: true, message: '请输入合同名称' }], | |||||
totalAmount: [{ required: true, message: '请输入合同总金额' }, { validator: moneyValidator, trigger: 'blur' }], | |||||
supplierBank: [{ required: true, message: '请输入供应商收款开户行' }], | |||||
supplierAccount: [{ required: true, message: '请输入供应商收款账号' }], | |||||
warrantyPeriod: [{ required: true, message: '请输入质保期' }], | |||||
retentionMoney: [{ required: true, message: '请输入质保金' }, { validator: moneyValidator, trigger: 'blur' }], | |||||
contractTime: [{ required: true, message: '请选择合同签订完成时间' }], | |||||
deliveryTime: [{ required: true, message: '请选择交货日期' }], | |||||
attachment: [{ required: true, message: '请上传合同附件' }] | |||||
}, | |||||
formData = ref({ | |||||
attachment: [], | |||||
payments: [] | |||||
}), | |||||
// 付款计划 | |||||
column = ref([ | |||||
{ | |||||
label: '付款笔数', | |||||
key: 'number', | |||||
slot: 'number' | |||||
}, | |||||
{ | |||||
label: '付款计划', | |||||
key: 'planAmount', | |||||
slot: 'planAmount' | |||||
}, | |||||
{ | |||||
label: '付款比例(%)', | |||||
key: 'ratio', | |||||
slot: 'ratio' | |||||
}, | |||||
{ | |||||
label: '付款金额(万元)', | |||||
key: 'paymentAmount', | |||||
slot: 'paymentAmount' | |||||
}, | |||||
{ | |||||
label: '预计付款时间', | |||||
key: 'paymentTime', | |||||
slot: 'paymentTime' | |||||
}, | |||||
{ | |||||
label: '操作', | |||||
key: 'action', | |||||
slot: 'action', | |||||
width: 80 | |||||
} | |||||
]), | |||||
// 添加付款计划 | |||||
add = () => { | |||||
formData.value.payments.push({}) | |||||
}, | |||||
// 删除付款计划 | |||||
del = (index) => { | |||||
formData.value.payments.splice(index, 1) | |||||
}, | |||||
// 计算付款比例 | |||||
blurMoney = (row) => { | |||||
row.ratio = Math.floor((row.paymentAmount / formData.value.totalAmount * 1) * 100 * 100) / 100 | |||||
}, | |||||
// 提交 | |||||
submitLoading = ref(false), | |||||
submit = async (formEl) => { | |||||
console.log(formData.value) | |||||
if (!formEl) { | |||||
return | |||||
} | |||||
formEl.validate(async (valid, err) => { | |||||
if (valid) { | |||||
if (!route.query.isReplenishment) { | |||||
if (!formData.value.payments?.length) { | |||||
proxy.$message.warning('请至少添加一个付款计划') | |||||
return | |||||
} | |||||
const totalMoney = formData.value.payments.reduce((acc, cur) => { | |||||
return acc + cur.paymentAmount | |||||
}, 0) | |||||
if (totalMoney !== formData.value.totalAmount) { | |||||
proxy.$message.warning('付款金额总和必须等于合同总金额') | |||||
return | |||||
} | |||||
submitLoading.value = true | |||||
const postData = { | |||||
...formData.value, | |||||
projectId: route.query.id, | |||||
attachment: formData.value.attachment && JSON.stringify(changFilesParam(formData.value.attachment)) | |||||
} | |||||
try { | |||||
await submitContract(postData) | |||||
submitLoading.value = false | |||||
proxy.$message.success('提交成功') | |||||
router.go(-1) | |||||
} catch (e) { | |||||
submitLoading.value = false | |||||
} | |||||
} else { | |||||
submitActualPaymentAmount() | |||||
} | |||||
} | |||||
}) | |||||
}, | |||||
// 提交补充金额 | |||||
submitActualPaymentAmount = async () => { | |||||
submitLoading.value = true | |||||
try { | |||||
const postData = [] | |||||
formData.value.payments.forEach(i => { | |||||
if ((i.actualPaymentAmount || i.actualPaymentAmount === 0) && !i.isReplenishment) { | |||||
postData.push({ | |||||
actualPaymentAmount: i.actualPaymentAmount, | |||||
id: i.id, | |||||
projectCode: i.projectCode | |||||
}) | |||||
} | |||||
}) | |||||
await supplement(postData) | |||||
proxy.$message.success('提交成功') | |||||
router.go(-1) | |||||
submitLoading.value = false | |||||
} catch (e) { | |||||
submitLoading.value = false | |||||
} | |||||
}, | |||||
// 获取详情 | |||||
getDetail = async () => { | |||||
const res = await contractDetail(route.query.id) | |||||
if (res.data) { | |||||
formData.value = { | |||||
...res.data, | |||||
attachment: res.data.attachment ? reviewFileParam(JSON.parse(res.data.attachment)) : [], | |||||
payments: res.data.payments?.map(i => { | |||||
return { | |||||
...i, | |||||
isReplenishment: !!i.actualPaymentAmount | |||||
} | |||||
}) || [] | |||||
} | |||||
} | |||||
}, | |||||
validActualPaymentAmount = (rule, value, callback, index) => { | |||||
if (value < 0) { | |||||
callback('实际支付金额必须大于等于0') | |||||
} else if (index === 0) { | |||||
if (value > formData.value.payments[index].paymentAmount) { | |||||
callback('实际支付金额不能超过合同计划付款金额') | |||||
} | |||||
} else { | |||||
let maxData = formData.value.payments[index].paymentAmount | |||||
for (let i = 0; i < index; i++) { | |||||
maxData += formData.value.payments[i].paymentAmount - formData.value.payments[i]?.actualPaymentAmount || 0 | |||||
} | |||||
if (value > maxData) { | |||||
callback(`实际支付金额不能超过${maxData}万元`) | |||||
} | |||||
} | |||||
callback() | |||||
} | |||||
onMounted(() => { | |||||
getDetail() | |||||
if (route.query.isReplenishment) { | |||||
column.value = [ | |||||
{ | |||||
label: '付款笔数', | |||||
key: 'number', | |||||
slot: 'number' | |||||
}, | |||||
{ | |||||
label: '付款计划', | |||||
key: 'planAmount', | |||||
slot: 'planAmount' | |||||
}, | |||||
{ | |||||
label: '付款比例(%)', | |||||
key: 'ratio', | |||||
slot: 'ratio' | |||||
}, | |||||
{ | |||||
label: '付款金额(万元)', | |||||
key: 'paymentAmount', | |||||
slot: 'paymentAmount' | |||||
}, | |||||
{ | |||||
label: '预计付款时间', | |||||
key: 'paymentTime', | |||||
slot: 'paymentTime' | |||||
}, | |||||
{ | |||||
label: '实际支付金额(万元)', | |||||
key: 'actualPaymentAmount', | |||||
slot: 'actualPaymentAmount', | |||||
width: 180 | |||||
} | |||||
] | |||||
} | |||||
}) | |||||
</script> | |||||
<template> | |||||
<div class="fillPurchasingResult footerPage"> | |||||
<el-card class="w-full"> | |||||
<el-form | |||||
ref="formRef" | |||||
:model="formData" | |||||
:rules="rules" | |||||
label-position="right" | |||||
label-width="180px" | |||||
label-suffix=":" | |||||
scroll-to-error | |||||
> | |||||
<el-row :gutter="40"> | |||||
<el-col :span="12"> | |||||
<el-form-item label="合同名称" prop="name"> | |||||
<el-input | |||||
v-model="formData.name" | |||||
maxlength="50" | |||||
placeholder="请输入" | |||||
:disabled="!!$route.query.isReplenishment" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="12"> | |||||
<el-form-item label="合同总金额" prop="totalAmount"> | |||||
<el-input | |||||
v-model.number="formData.totalAmount" | |||||
placeholder="请填写" | |||||
:disabled="!!$route.query.isReplenishment" | |||||
> | |||||
<template #suffix>万元</template> | |||||
</el-input> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="12"> | |||||
<el-form-item label="供应商收款开户行" prop="supplierBank"> | |||||
<el-input | |||||
v-model="formData.supplierBank" | |||||
maxlength="50" | |||||
placeholder="请输入" | |||||
:disabled="!!$route.query.isReplenishment" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="12"> | |||||
<el-form-item label="供应商收款账号" prop="supplierAccount"> | |||||
<el-input | |||||
v-model="formData.supplierAccount" | |||||
maxlength="50" | |||||
placeholder="请输入" | |||||
:disabled="!!$route.query.isReplenishment" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="12"> | |||||
<el-form-item label="质保期" prop="warrantyPeriod"> | |||||
<el-input | |||||
v-model="formData.warrantyPeriod" | |||||
maxlength="50" | |||||
placeholder="请输入" | |||||
:disabled="!!$route.query.isReplenishment" | |||||
@input="formData.warrantyPeriod=formData.warrantyPeriod?.replace(/[^\d]/g,'')" | |||||
> | |||||
<template #suffix> | |||||
年 | |||||
</template> | |||||
</el-input> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="12"> | |||||
<el-form-item label="质保金" prop="retentionMoney"> | |||||
<el-input | |||||
v-model.number="formData.retentionMoney" | |||||
placeholder="请填写" | |||||
:disabled="!!$route.query.isReplenishment" | |||||
> | |||||
<template #suffix>万元</template> | |||||
</el-input> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="12"> | |||||
<el-form-item | |||||
label="合同签订完成时间" | |||||
prop="contractTime" | |||||
> | |||||
<el-date-picker | |||||
v-model="formData.contractTime" | |||||
type="date" | |||||
format="YYYY-MM-DD" | |||||
value-format="YYYY-MM-DD" | |||||
placeholder="请选择" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="12"> | |||||
<el-form-item | |||||
label="交货日期" | |||||
prop="deliveryTime" | |||||
> | |||||
<el-date-picker | |||||
v-model="formData.deliveryTime" | |||||
type="date" | |||||
format="YYYY-MM-DD" | |||||
value-format="YYYY-MM-DD" | |||||
placeholder="请选择" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
</el-row> | |||||
<el-row> | |||||
<el-col :span="12"> | |||||
<el-form-item label="合同附件" prop="attachment"> | |||||
<el-upload | |||||
v-model:file-list="formData.attachment" | |||||
class="w-full" | |||||
:action="uploadUrl" | |||||
:on-success="res => handleFileSuccess(res, formData.attachment)" | |||||
:before-upload="file=>fileFormatVerification(file, {types: fileTypes})" | |||||
:accept="fileTypes.map(i=>`.${i}`).join(',')" | |||||
:on-preview="handleFilePreview" | |||||
> | |||||
<el-button type="primary" plain>选择文件</el-button> | |||||
<template #tip> | |||||
<div class="el-upload__tip"> | |||||
支持{{ fileDesc }}文件 | |||||
</div> | |||||
</template> | |||||
</el-upload> | |||||
</el-form-item> | |||||
</el-col> | |||||
</el-row> | |||||
<el-row> | |||||
<el-col :span="24"> | |||||
<table-list | |||||
ref="tableListRef" | |||||
:column="column" | |||||
:data="formData.payments" | |||||
:pagination="false" | |||||
:empty-temp="false" | |||||
> | |||||
<template #number="{scope}"> | |||||
<span>第{{ scope.$index+1 }}笔</span> | |||||
</template> | |||||
<template #planAmount="{scope}"> | |||||
<el-form-item | |||||
v-if="scope.$index>=0" | |||||
:prop="`payments[${scope.$index}].planAmount`" | |||||
:rules="[{ required: true, message: '请输入' }]" | |||||
label-width="0" | |||||
style="margin-bottom: 0" | |||||
> | |||||
<el-input | |||||
v-model="scope.row.planAmount" | |||||
placeholder="请填写" | |||||
:disabled="!!$route.query.isReplenishment" | |||||
/> | |||||
</el-form-item> | |||||
</template> | |||||
<template #ratio="{scope}"> | |||||
<el-form-item | |||||
v-if="scope.$index>=0" | |||||
:prop="`payments[${scope.$index}].ratio`" | |||||
:rules="[{ required: true, message: '请输入' }]" | |||||
label-width="0" | |||||
style="margin-bottom: 0" | |||||
> | |||||
<el-input v-model.number="scope.row.ratio" placeholder="自动计算" disabled /> | |||||
</el-form-item> | |||||
</template> | |||||
<template #paymentAmount="{scope}"> | |||||
<el-form-item | |||||
v-if="scope.$index>=0" | |||||
:prop="`payments[${scope.$index}].paymentAmount`" | |||||
:rules="[{ required: true, message: '请输入' }]" | |||||
label-width="0" | |||||
style="margin-bottom: 0" | |||||
> | |||||
<el-input-number | |||||
v-model="scope.row.paymentAmount" | |||||
placeholder="请填写" | |||||
:min="0" | |||||
:controls="false" | |||||
:disabled="!!$route.query.isReplenishment" | |||||
@mousewheel.prevent | |||||
@blur="blurMoney(scope.row)" | |||||
/> | |||||
</el-form-item> | |||||
</template> | |||||
<template #paymentTime="{scope}"> | |||||
<el-form-item | |||||
v-if="scope.$index>=0" | |||||
:prop="`payments[${scope.$index}].paymentTime`" | |||||
:rules="[{ required: true, message: '请选择' }]" | |||||
label-width="0" | |||||
style="margin-bottom: 0" | |||||
> | |||||
<el-date-picker | |||||
v-model="scope.row.paymentTime" | |||||
type="date" | |||||
format="YYYY-MM-DD" | |||||
value-format="YYYY-MM-DD" | |||||
placeholder="请选择" | |||||
:disabled="!!$route.query.isReplenishment" | |||||
/> | |||||
</el-form-item> | |||||
</template> | |||||
<template #action="{scope}"> | |||||
<a class="text-danger" @click="del(scope.$index)">删除</a> | |||||
</template> | |||||
<template #actualPaymentAmount="{scope}"> | |||||
<el-form-item | |||||
v-if="scope.$index>=0" | |||||
label-width="0" | |||||
:prop="`payments[${scope.$index}].actualPaymentAmount`" | |||||
:rules="[{ validator: (rule,value,callback)=>validActualPaymentAmount(rule,value,callback,scope.$index)}]" | |||||
style="margin-bottom: 25px;margin-top: 20px" | |||||
> | |||||
<el-input-number | |||||
v-model="scope.row.actualPaymentAmount" | |||||
placeholder="请填写" | |||||
:min="0" | |||||
:controls="false" | |||||
:disabled="scope.row.isReplenishment" | |||||
@mousewheel.prevent | |||||
/> | |||||
</el-form-item> | |||||
</template> | |||||
</table-list> | |||||
<el-button | |||||
v-if="!$route.query.isReplenishment" | |||||
type="primary" | |||||
icon="Plus" | |||||
plain | |||||
class="w-full mt-8" | |||||
@click="add" | |||||
>添加付款计划</el-button> | |||||
<p v-if="$route.query.isReplenishment" class="text-danger text-14">温馨提示:请谨慎填写实际支付金额,填写后不允许修改</p> | |||||
</el-col> | |||||
</el-row> | |||||
</el-form> | |||||
</el-card> | |||||
<div class="footer"> | |||||
<el-button @click="router.go(-1)"> 返回 </el-button> | |||||
<el-button type="primary" :loading="submitLoading" @click="submit(formRef)"> 提交 </el-button> | |||||
</div> | |||||
</div> | |||||
</template> |
@@ -0,0 +1,224 @@ | |||||
<script setup name="contractRecord"> | |||||
import { ref, reactive, onMounted } from 'vue' | |||||
import { declareExport } from '@/http/apis/declareMange' | |||||
import { useRouter } from 'vue-router' | |||||
import useExportExc from '@/utils/useExportExc' | |||||
import { list } from '@/http/apis/declareMange/contractRecord' | |||||
import store from '@/store' | |||||
const { projectTypeOptions } = store.dictStore.globalDicts || {} | |||||
const router = useRouter() | |||||
// 搜索栏表单数据 | |||||
const searchForm = reactive({ | |||||
projectType: undefined, | |||||
status: undefined, | |||||
projectYear: undefined, | |||||
projectName: undefined, | |||||
createOnMin: undefined, | |||||
createOnMax: undefined, | |||||
times: [] | |||||
}), | |||||
activeName = ref('1'), | |||||
column = reactive([ | |||||
{ | |||||
label: '序号', | |||||
type: 'index', | |||||
width: '80' | |||||
}, | |||||
{ | |||||
label: '项目名称', | |||||
key: 'projectName', | |||||
prop: 'projectName', | |||||
minWidth: '200', | |||||
showOverflowTooltip: true | |||||
}, | |||||
{ | |||||
label: '项目类型', | |||||
key: 'projectTypeName', | |||||
prop: 'projectTypeName', | |||||
width: '80' | |||||
}, | |||||
{ | |||||
label: '成交金额(万元)', | |||||
key: 'transactionAmount', | |||||
prop: 'transactionAmount', | |||||
width: '150' | |||||
}, | |||||
{ | |||||
label: '预算年度', | |||||
key: 'projectYear', | |||||
prop: 'projectYear', | |||||
width: 80 | |||||
}, | |||||
{ | |||||
label: '成交时间', | |||||
key: 'transactionTime', | |||||
prop: 'transactionTime', | |||||
width: '120' | |||||
}, | |||||
{ | |||||
label: '创建时间', | |||||
key: 'createOn', | |||||
prop: 'createOn', | |||||
width: '200' | |||||
}, | |||||
{ | |||||
label: '操作', | |||||
slot: 'action', | |||||
width: '190', | |||||
fixed: 'right' | |||||
} | |||||
]), | |||||
data = ref([]), | |||||
tableListRef = ref(), | |||||
getTableData = async (pageParams = tableListRef.value.pageParams) => { | |||||
const res = await list(activeName.value, { | |||||
...pageParams, | |||||
...searchForm, | |||||
createOnMin: searchForm.times?.[0], | |||||
createOnMax: searchForm.times?.[1], | |||||
projectYear: searchForm.projectYear * 1 || undefined, | |||||
times: undefined | |||||
}) | |||||
data.value = res.data.records | |||||
total.value = res.data.total | |||||
}, | |||||
// 数据总数 | |||||
total = ref(2), | |||||
// 提交查询 | |||||
search = () => { | |||||
tableListRef.value.pageParams.pageNumber = 1 | |||||
getTableData() | |||||
}, | |||||
// 重置 | |||||
formReset = () => { | |||||
searchForm.projectYear = undefined | |||||
searchForm.projectName = undefined | |||||
searchForm.projectType = undefined | |||||
searchForm.createOnMin = undefined | |||||
searchForm.createOnMax = undefined | |||||
searchForm.times = undefined | |||||
tableListRef.value.pageParams.pageNumber = 1 | |||||
tableListRef.value.pageParams.pageSize = 10 | |||||
getTableData() | |||||
}, | |||||
tabChange = (val) => { | |||||
activeName.value = val | |||||
getTableData() | |||||
}, | |||||
// 导出excel文件 | |||||
{ exportLoading, exportData } = useExportExc(), | |||||
handleExcel = () => { | |||||
exportData(() => declareExport(7, { | |||||
...searchForm, | |||||
createOnMin: searchForm.times?.[0], | |||||
createOnMax: searchForm.times?.[1], | |||||
projectYear: searchForm.projectYear * 1 || undefined, | |||||
times: undefined | |||||
})) | |||||
} | |||||
onMounted(async () => { | |||||
getTableData() | |||||
}) | |||||
</script> | |||||
<template> | |||||
<el-card class="w-full search"> | |||||
<el-form :model="searchForm" size="small" label-suffix=":"> | |||||
<el-row :gutter="16" class="mb-16"> | |||||
<el-col :span="8"> | |||||
<el-form-item label="项目名称"> | |||||
<el-input | |||||
v-model="searchForm.projectName" | |||||
maxlength="50" | |||||
placeholder="请输入" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<el-form-item label="项目类型"> | |||||
<el-select | |||||
v-model="searchForm.projectType" | |||||
placeholder="全部" | |||||
class="w-full" | |||||
> | |||||
<el-option | |||||
v-for="(v,k) in projectTypeOptions" | |||||
:key="k" | |||||
:label="v" | |||||
:value="k" | |||||
/> | |||||
</el-select> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<el-form-item label="预算年度"> | |||||
<el-date-picker | |||||
v-model="searchForm.projectYear" | |||||
type="year" | |||||
placeholder="请选择" | |||||
format="YYYY" | |||||
value-format="YYYY" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
</el-row> | |||||
<el-row :gutter="24"> | |||||
<el-col :span="12"> | |||||
<el-form-item label="创建时间"> | |||||
<el-date-picker | |||||
v-model="searchForm.times" | |||||
type="datetimerange" | |||||
range-separator="-" | |||||
start-placeholder="开始时间" | |||||
end-placeholder="结束时间" | |||||
format="YYYY-MM-DD HH:mm" | |||||
value-format="YYYY-MM-DD HH:mm" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="12"> | |||||
<el-form-item class="btn"> | |||||
<div class="flex"> | |||||
<el-button type="primary" @click="search">查询</el-button> | |||||
<el-button @click="formReset">重置</el-button> | |||||
</div> | |||||
</el-form-item> | |||||
</el-col> | |||||
</el-row> | |||||
</el-form> | |||||
</el-card> | |||||
<el-card class="w-full mt-8 tab-card"> | |||||
<template #header> | |||||
<div class="flex justify-between items-center"> | |||||
<el-tabs v-model="activeName" @tab-change="tabChange"> | |||||
<el-tab-pane label="待完善合同信息" name="1" /> | |||||
<el-tab-pane label="已完善合同信息" name="2" /> | |||||
</el-tabs> | |||||
<div> | |||||
<el-button | |||||
type="primary" | |||||
size="small" | |||||
plain | |||||
:loading="exportLoading" | |||||
@click="handleExcel" | |||||
> | |||||
导出 | |||||
</el-button> | |||||
</div> | |||||
</div> | |||||
</template> | |||||
<table-list | |||||
ref="tableListRef" | |||||
:column="column" | |||||
:data="data" | |||||
:total="total" | |||||
@get-table-data="getTableData" | |||||
> | |||||
<template #action="{ scope }"> | |||||
<a v-if="activeName==='1'" @click="router.push({ name: 'fillContractInfo', query: { id: scope.row.id }})">填写合同信息</a> | |||||
<a v-if="activeName==='2'&&!scope.row.supplemented" @click="router.push({ name: 'fillContractInfo', query: { id: scope.row.id,isReplenishment:true }})">补充实际付款金额</a> | |||||
<a @click="router.push({name:'contractRecordDetail',query:{id:scope.row.id}})">详情</a> | |||||
</template> | |||||
</table-list> | |||||
</el-card> | |||||
</template> | |||||
<style lang="less" scoped></style> |
@@ -0,0 +1,132 @@ | |||||
<script name="applyDialog" setup> | |||||
import { ref, getCurrentInstance, watch } from 'vue' | |||||
import { changFilesParam, fileFormatVerification, handleFileSuccess, fileTypes, fileDesc, handleFilePreview } from '@/utils/uploadAction.js' | |||||
import { delayedApply } from '@/http/apis/declareMange/delayApply' | |||||
import store from '@/store' | |||||
const { proxy } = getCurrentInstance(), | |||||
uploadUrl = store.dictStore.uploadUrl, | |||||
props = defineProps({ | |||||
visible: { | |||||
type: Boolean, | |||||
default: false, | |||||
required: true | |||||
}, | |||||
data: Object | |||||
}), | |||||
emits = defineEmits(['close']), | |||||
loading = ref(false), | |||||
dialogForm = ref({ | |||||
supportingMaterials: [] | |||||
}), | |||||
rules = { | |||||
'delayedMonth': [{ required: true, message: '请输入延期时长' }], | |||||
'delayedReason': [{ required: true, message: '请输入延期理由' }], | |||||
'supportingMaterials': [{ required: true, message: '请上传' }] | |||||
}, | |||||
dialogFormRef = ref(), | |||||
submit = async (formEl) => { | |||||
if (!formEl) { | |||||
return | |||||
} | |||||
formEl.validate(async (valid) => { | |||||
if (valid) { | |||||
loading.value = true | |||||
try { | |||||
const postData = { | |||||
...dialogForm.value, | |||||
supportingMaterials: dialogForm.value?.supportingMaterials?.length && JSON.stringify(changFilesParam(dialogForm.value.supportingMaterials)) || undefined, | |||||
projectId: props.data.id | |||||
} | |||||
await delayedApply(postData) | |||||
proxy.$message.success('提交成功!') | |||||
loading.value = false | |||||
emits('close', true) | |||||
} catch (e) { | |||||
loading.value = false | |||||
} | |||||
} | |||||
} | |||||
) | |||||
} | |||||
watch( | |||||
() => props.visible, | |||||
async val => { | |||||
if (val) { | |||||
console.log('props.data', props.data) | |||||
} else { | |||||
dialogForm.value = { higherLineSuperOrgReviewComments: [] } | |||||
} | |||||
} | |||||
) | |||||
</script> | |||||
<template> | |||||
<el-dialog | |||||
:model-value="visible" | |||||
title="申请延期" | |||||
width="600px" | |||||
destroy-on-close | |||||
@close="emits('close')" | |||||
> | |||||
<el-form | |||||
ref="dialogFormRef" | |||||
:model="dialogForm" | |||||
:rules="rules" | |||||
label-width="auto" | |||||
status-icon | |||||
class="mt-16" | |||||
> | |||||
<el-form-item label="延期时长" prop="delayedMonth"> | |||||
<el-input | |||||
v-model="dialogForm.delayedMonth" | |||||
placeholder="请填写需要延长几个月" | |||||
@input="dialogForm.delayedMonth=dialogForm.delayedMonth?.replace(/[^\d]/g,'')" | |||||
> | |||||
<template #suffix>月</template> | |||||
</el-input> | |||||
</el-form-item> | |||||
<el-form-item label="延期理由" prop="delayedReason"> | |||||
<el-input | |||||
v-model="dialogForm.delayedReason" | |||||
type="textarea" | |||||
maxlength="1000" | |||||
show-word-limit | |||||
placeholder="请填写" | |||||
/> | |||||
</el-form-item> | |||||
<el-form-item label="佐证材料:" prop="supportingMaterials"> | |||||
<el-upload | |||||
v-model:file-list="dialogForm.supportingMaterials" | |||||
class=" w-full" | |||||
:action="uploadUrl" | |||||
:limit="1" | |||||
:on-success="res => handleFileSuccess(res, dialogForm.supportingMaterials, true)" | |||||
:before-upload="file=>fileFormatVerification(file, {types: fileTypes})" | |||||
:accept="fileTypes.map(i=>`.${i}`).join(',')" | |||||
:on-preview="handleFilePreview" | |||||
> | |||||
<el-button type="primary" plain>选择文件</el-button> | |||||
<template #tip> | |||||
<div class="el-upload__tip"> | |||||
支持{{ fileDesc }}文件 | |||||
</div> | |||||
</template> | |||||
</el-upload> | |||||
</el-form-item> | |||||
</el-form> | |||||
<template #footer> | |||||
<el-button | |||||
type="primary" | |||||
:loading="loading" | |||||
@click="submit(dialogFormRef)" | |||||
> | |||||
提交 | |||||
</el-button> | |||||
<el-button | |||||
@click="emits('close')" | |||||
> | |||||
关闭 | |||||
</el-button> | |||||
</template> | |||||
</el-dialog> | |||||
</template> |
@@ -0,0 +1,225 @@ | |||||
<script setup name="delayApply"> | |||||
import { ref, reactive, onMounted } from 'vue' | |||||
import { declareExport } from '@/http/apis/declareMange' | |||||
import { useRouter } from 'vue-router' | |||||
import useExportExc from '@/utils/useExportExc' | |||||
import { list } from '@/http/apis/declareMange/delayApply' | |||||
import ApplyDialog from './components/applyDialog.vue' | |||||
import store from '@/store' | |||||
const { projectTypeOptions } = store.dictStore.globalDicts || {} | |||||
const router = useRouter() | |||||
// 搜索栏表单数据 | |||||
const searchForm = reactive({ | |||||
projectType: undefined, | |||||
status: undefined, | |||||
projectYear: undefined, | |||||
projectName: undefined, | |||||
createOnMin: undefined, | |||||
createOnMax: undefined, | |||||
times: [] | |||||
}), | |||||
column = reactive([ | |||||
{ | |||||
label: '序号', | |||||
type: 'index', | |||||
width: '80' | |||||
}, | |||||
{ | |||||
label: '项目名称', | |||||
key: 'projectName', | |||||
prop: 'projectName', | |||||
minWidth: '200', | |||||
showOverflowTooltip: true | |||||
}, | |||||
{ | |||||
label: '项目类型', | |||||
key: 'projectTypeName', | |||||
prop: 'projectTypeName', | |||||
width: '80' | |||||
}, | |||||
{ | |||||
label: '批复金额(万元)', | |||||
key: 'approvedAmount', | |||||
prop: 'approvedAmount', | |||||
width: '150' | |||||
}, | |||||
{ | |||||
label: '预算年度', | |||||
key: 'projectYear', | |||||
prop: 'projectYear', | |||||
width: 80 | |||||
}, | |||||
{ | |||||
label: '计划验收时间', | |||||
key: 'planAcceptanceTime', | |||||
prop: 'planAcceptanceTime', | |||||
width: '200' | |||||
}, | |||||
{ | |||||
label: '操作', | |||||
slot: 'action', | |||||
width: '180', | |||||
fixed: 'right' | |||||
} | |||||
]), | |||||
data = ref([]), | |||||
tableListRef = ref(), | |||||
getTableData = async (pageParams = tableListRef.value.pageParams) => { | |||||
const res = await list({ | |||||
...pageParams, | |||||
...searchForm, | |||||
createOnMin: searchForm.times?.[0], | |||||
createOnMax: searchForm.times?.[1], | |||||
projectYear: searchForm.projectYear * 1 || undefined, | |||||
times: undefined | |||||
}) | |||||
data.value = res.data.records | |||||
total.value = res.data.total | |||||
}, | |||||
// 数据总数 | |||||
total = ref(2), | |||||
// 提交查询 | |||||
search = () => { | |||||
getTableData() | |||||
}, | |||||
// 重置 | |||||
formReset = () => { | |||||
searchForm.projectYear = undefined | |||||
searchForm.projectName = undefined | |||||
searchForm.projectType = undefined | |||||
searchForm.createOnMin = undefined | |||||
searchForm.createOnMax = undefined | |||||
searchForm.times = undefined | |||||
tableListRef.value.pageParams.pageNumber = 1 | |||||
tableListRef.value.pageParams.pageSize = 10 | |||||
getTableData() | |||||
}, | |||||
// 导出excel文件 | |||||
{ exportLoading, exportData } = useExportExc(), | |||||
handleExcel = () => { | |||||
exportData(() => declareExport(10, { | |||||
...searchForm, | |||||
createOnMin: searchForm.times?.[0], | |||||
createOnMax: searchForm.times?.[1], | |||||
projectYear: searchForm.projectYear * 1 || undefined, | |||||
times: undefined | |||||
})) | |||||
}, | |||||
// 申请延期 | |||||
applyDelay = (data) => { | |||||
dialogData.visible = true | |||||
dialogData.data = data | |||||
}, | |||||
dialogData = reactive({ | |||||
visible: undefined, | |||||
data: undefined | |||||
}), | |||||
close = (flag) => { | |||||
dialogData.visible = false | |||||
flag && getTableData() | |||||
} | |||||
onMounted(async () => { | |||||
getTableData() | |||||
}) | |||||
</script> | |||||
<template> | |||||
<el-card class="w-full search"> | |||||
<el-form :model="searchForm" size="small" label-suffix=":"> | |||||
<el-row :gutter="16" class="mb-16"> | |||||
<el-col :span="8"> | |||||
<el-form-item label="项目名称"> | |||||
<el-input | |||||
v-model="searchForm.projectName" | |||||
maxlength="50" | |||||
placeholder="请输入" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="6"> | |||||
<el-form-item label="项目类型"> | |||||
<el-select | |||||
v-model="searchForm.projectType" | |||||
placeholder="全部" | |||||
class="w-full" | |||||
> | |||||
<el-option | |||||
v-for="(v,k) in projectTypeOptions" | |||||
:key="k" | |||||
:label="v" | |||||
:value="k" | |||||
/> | |||||
</el-select> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="10"> | |||||
<el-form-item label="计划验收时间"> | |||||
<el-date-picker | |||||
v-model="searchForm.times" | |||||
type="datetimerange" | |||||
range-separator="-" | |||||
start-placeholder="开始时间" | |||||
end-placeholder="结束时间" | |||||
format="YYYY-MM-DD HH:mm" | |||||
value-format="YYYY-MM-DD HH:mm" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
</el-row> | |||||
<el-row :gutter="24"> | |||||
<el-col :span="12"> | |||||
<el-form-item label="创建时间"> | |||||
<el-date-picker | |||||
v-model="searchForm.times" | |||||
type="datetimerange" | |||||
range-separator="-" | |||||
start-placeholder="开始时间" | |||||
end-placeholder="结束时间" | |||||
format="YYYY-MM-DD HH:mm" | |||||
value-format="YYYY-MM-DD HH:mm" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="12"> | |||||
<el-form-item class="btn"> | |||||
<div class="flex"> | |||||
<el-button type="primary" @click="search">查询</el-button> | |||||
<el-button @click="formReset">重置</el-button> | |||||
</div> | |||||
</el-form-item> | |||||
</el-col> | |||||
</el-row> | |||||
</el-form> | |||||
</el-card> | |||||
<el-card class="w-full mt-8"> | |||||
<template #header> | |||||
<div class="flex justify-between"> | |||||
<span>列表</span> | |||||
<div> | |||||
<el-button | |||||
type="primary" | |||||
size="small" | |||||
plain | |||||
:loading="exportLoading" | |||||
@click="handleExcel" | |||||
> | |||||
导出 | |||||
</el-button> | |||||
</div> | |||||
</div> | |||||
</template> | |||||
<table-list | |||||
ref="tableListRef" | |||||
:column="column" | |||||
:data="data" | |||||
:total="total" | |||||
@get-table-data="getTableData" | |||||
> | |||||
<template #action="{ scope }"> | |||||
<a v-if="scope.row.canDelayApply" @click="applyDelay(scope.row)">申请延期</a> | |||||
<a @click="router.push({name:'delayApplyDetail',query:{id:scope.row.id}})">详情</a> | |||||
</template> | |||||
</table-list> | |||||
</el-card> | |||||
<apply-dialog :visible="dialogData.visible" :data="dialogData.data" @close="close" /> | |||||
</template> | |||||
<style lang="less" scoped></style> |
@@ -0,0 +1,794 @@ | |||||
<script name="declarationFinal" setup> | |||||
import { onMounted, ref, nextTick, getCurrentInstance, reactive } from 'vue' | |||||
import { fileFormatVerification, handleFileSuccess, handleFilePreview, fileTypes } from '@/utils/uploadAction.js' | |||||
import store from '@/store' | |||||
import * as echarts from 'echarts' | |||||
import { useRoute, useRouter } from 'vue-router' | |||||
import { submitFinal } from '@/http/apis/declareMange/finalInspectionDeclare' | |||||
import { projectDetail } from '@/http/apis/projectStoreManage/projectStore' | |||||
import ActualPerformanceIndicatorsDialog | |||||
from '@/pages/declareManage/initialInspectionRecord/uploadInitMaterials/components/actualPerformanceIndicatorsDialog.vue' | |||||
const uploadUrl = store.dictStore.uploadUrl, | |||||
route = useRoute(), | |||||
{ proxy } = getCurrentInstance(), | |||||
router = useRouter() | |||||
const collapseModal = ['1', '2', '3', '4', '5', '6', '7'], | |||||
formRef = ref(), | |||||
formData = ref({ | |||||
finalAcceptanceMaterials: [ | |||||
{ | |||||
title: '一、项目前期材料', | |||||
data: [ | |||||
{ | |||||
name: '信息化项目立项批复文件', | |||||
isHave: true, | |||||
files: [], | |||||
reason: '' | |||||
}, | |||||
{ | |||||
name: '市政府采购计划表', | |||||
isHave: true, | |||||
files: [], | |||||
reason: '' | |||||
}, | |||||
{ | |||||
name: '采购需求', | |||||
isHave: true, | |||||
files: [], | |||||
reason: '' | |||||
}, | |||||
{ | |||||
name: '中标通知书', | |||||
isHave: true, | |||||
files: [], | |||||
reason: '' | |||||
}, | |||||
{ | |||||
name: '技术(软件、系统等)开发合同(协议)', | |||||
isHave: true, | |||||
files: [], | |||||
reason: '' | |||||
}, | |||||
{ | |||||
name: '设备采购合同(协议)含采购内容清单、以及合同上规定交付的所有文档', | |||||
isHave: true, | |||||
files: [], | |||||
reason: '' | |||||
}, | |||||
{ | |||||
name: '第三方监理合同(协议)', | |||||
isHave: true, | |||||
files: [], | |||||
reason: '' | |||||
}, | |||||
{ | |||||
name: '其他前期资料(含中标单位营业执照、工程相关资质等)', | |||||
isHave: true, | |||||
files: [], | |||||
reason: '' | |||||
} | |||||
] | |||||
}, | |||||
{ | |||||
title: '二、项目开工资料', | |||||
data: [ | |||||
{ | |||||
name: '工程开工报告单(工程名称、建设单位、承建单位、施工单位、计划开工和完工日期、工程实施主要内容、建设单位审批意见及盖章日期,承建单位、施工单位盖章日期)', | |||||
isHave: true, | |||||
files: [], | |||||
reason: '' | |||||
}, | |||||
{ | |||||
name: '软件类系统开发、部署等功能介绍', | |||||
isHave: true, | |||||
files: [], | |||||
reason: '' | |||||
}, | |||||
{ | |||||
name: '隐蔽工程类设计图、材料选材、施工计划等(可另作图册)', | |||||
isHave: true, | |||||
files: [], | |||||
reason: '' | |||||
}, | |||||
{ | |||||
name: '购置到位的设备产品证书、开箱证明、序列号等(可另附成册)', | |||||
isHave: true, | |||||
files: [], | |||||
reason: '' | |||||
}, | |||||
{ | |||||
name: '项目组名单及人员介绍资料', | |||||
isHave: true, | |||||
files: [], | |||||
reason: '' | |||||
} | |||||
] | |||||
}, | |||||
{ | |||||
title: '三、项目实施过程资料', | |||||
data: [ | |||||
{ | |||||
name: '设备安装时间、位置一览表等', | |||||
isHave: true, | |||||
files: [], | |||||
reason: '' | |||||
}, | |||||
{ | |||||
name: '软件类系统开发、部署等完成情况对照表', | |||||
isHave: true, | |||||
required: true, | |||||
files: [], | |||||
reason: '' | |||||
}, | |||||
{ | |||||
name: '历次多方讨论会议记录表、项目变更单等原始凭证', | |||||
isHave: true, | |||||
files: [], | |||||
reason: '' | |||||
}, | |||||
{ | |||||
name: '信息安全等级保护测评报告', | |||||
isHave: true, | |||||
required: true, | |||||
files: [], | |||||
reason: '' | |||||
}, | |||||
{ | |||||
name: '商业密码应用评估报告', | |||||
isHave: true, | |||||
files: [], | |||||
reason: '' | |||||
}, | |||||
{ | |||||
name: '财务审计报告', | |||||
isHave: true, | |||||
files: [], | |||||
reason: '' | |||||
}, | |||||
{ | |||||
name: '变更申请单', | |||||
isHave: true, | |||||
files: [], | |||||
reason: '' | |||||
}, | |||||
{ | |||||
name: '变更批复文件', | |||||
isHave: true, | |||||
files: [], | |||||
reason: '' | |||||
} | |||||
] | |||||
}, | |||||
{ | |||||
title: '四、项目试运行资料', | |||||
data: [ | |||||
{ | |||||
name: '试运行报告及整改情况(建设单位)', | |||||
isHave: true, | |||||
files: [], | |||||
reason: '' | |||||
}, | |||||
{ | |||||
name: '试运行情况业主单位意见(领导签字、单位盖章)', | |||||
isHave: true, | |||||
files: [], | |||||
reason: '' | |||||
}, | |||||
{ | |||||
name: '历次巡检流程及记录表等原始凭证', | |||||
isHave: true, | |||||
files: [], | |||||
reason: '' | |||||
}, | |||||
{ | |||||
name: '用户使用报告', | |||||
isHave: true, | |||||
required: true, | |||||
files: [], | |||||
reason: '' | |||||
}, | |||||
{ | |||||
name: 'IRS应用试运行报告', | |||||
isHave: true, | |||||
required: true, | |||||
files: [], | |||||
reason: '' | |||||
} | |||||
] | |||||
}, | |||||
{ | |||||
title: '五、项目完工资料', | |||||
data: [ | |||||
{ | |||||
name: '工程类竣工报告(建设单位)', | |||||
isHave: true, | |||||
files: [], | |||||
reason: '' | |||||
}, | |||||
{ | |||||
name: '完工整体运行情况报告', | |||||
isHave: true, | |||||
files: [], | |||||
reason: '' | |||||
}, | |||||
{ | |||||
name: '监理总结报告', | |||||
isHave: true, | |||||
files: [], | |||||
reason: '' | |||||
}, | |||||
{ | |||||
name: '第三方项目评测报告(另册)', | |||||
isHave: true, | |||||
files: [], | |||||
reason: '' | |||||
}, | |||||
{ | |||||
name: '业主单位组织的初验专家意见及名单,整改情况', | |||||
isHave: true, | |||||
files: [], | |||||
reason: '' | |||||
}, | |||||
{ | |||||
name: '各类系统、场地、设备使用的管理手册、操作手册、维护手册(可另册)', | |||||
isHave: true, | |||||
files: [], | |||||
reason: '' | |||||
}, | |||||
{ | |||||
name: '售后服务承诺等(建设单位)', | |||||
isHave: true, | |||||
files: [], | |||||
reason: '' | |||||
}, | |||||
{ | |||||
name: '终验意见', | |||||
isHave: true, | |||||
required: true, | |||||
files: [], | |||||
reason: '' | |||||
} | |||||
] | |||||
} | |||||
] | |||||
}), | |||||
// 材料表格 | |||||
column = [ | |||||
{ | |||||
label: '序号', | |||||
type: 'index', | |||||
width: '60' | |||||
}, | |||||
{ | |||||
label: '材料名称', | |||||
key: 'name', | |||||
prop: 'name' | |||||
}, | |||||
{ | |||||
label: '是否有材料', | |||||
key: 'isHave', | |||||
slot: 'isHave', | |||||
width: 100 | |||||
}, | |||||
{ | |||||
label: '附件/说明(支持扩展名:.doc .docx .pdf)', | |||||
key: 'files', | |||||
slot: 'files' | |||||
} | |||||
], | |||||
applications = ref([ | |||||
{ | |||||
name: '应用1', | |||||
status: '运行中', | |||||
memoryRate: 11, | |||||
cpuRate: 33, | |||||
cpRate: 44 | |||||
}, | |||||
{ | |||||
name: '应用2', | |||||
status: '运行中', | |||||
memoryRate: 68, | |||||
cpuRate: 43, | |||||
cpRate: 30 | |||||
} | |||||
]), | |||||
applicationData = ref({}) | |||||
let chart1, chart2, chart3 | |||||
const chart1Ref = ref(), chart2Ref = ref(), chart3Ref = ref(), | |||||
getCirChartOptions = (precent, color, text) => { | |||||
const colorList = [color, 'rgba(0, 0, 0, 0.1)'] | |||||
return { | |||||
legend: { | |||||
show: false | |||||
}, | |||||
graphic: [ | |||||
{ | |||||
type: 'text', | |||||
left: 'center', | |||||
top: '48%', | |||||
style: { | |||||
text: `${precent}%`, | |||||
fill: '#333333', // 文字的颜色 | |||||
fontSize: 16, | |||||
fontWeight: 'bold', | |||||
fontFamily: 'DINAlternate-Bold, DINAlternate' | |||||
} | |||||
}, | |||||
{ | |||||
type: 'text', | |||||
left: 'center', | |||||
bottom: '0', | |||||
style: { | |||||
text: `${text}`, | |||||
fill: '#333333', // 文字的颜色 | |||||
fontSize: 12 | |||||
} | |||||
} | |||||
], | |||||
series: [ | |||||
{ | |||||
type: 'pie', | |||||
radius: ['58%', '75%'], | |||||
center: ['50%', '50%'], | |||||
avoidLabelOverlap: false, | |||||
data: [ | |||||
{ | |||||
value: precent | |||||
}, | |||||
{ | |||||
value: 100 - precent | |||||
} | |||||
], | |||||
itemStyle: { | |||||
color: function (params) { | |||||
return colorList[params.dataIndex] | |||||
} | |||||
}, | |||||
labelLine: { | |||||
show: false | |||||
} | |||||
} | |||||
] | |||||
} | |||||
}, | |||||
initChart1 = () => { | |||||
if (!chart1) chart1 = echarts.init(chart1Ref.value) | |||||
const option = getCirChartOptions(applicationData.value.memoryRate, '#5ADE92', | |||||
'近三个月内存平均使用率') | |||||
chart1.setOption(option) | |||||
}, | |||||
initChart2 = () => { | |||||
if (!chart2) chart2 = echarts.init(chart2Ref.value) | |||||
const option = getCirChartOptions(applicationData.value.cpuRate, '#0967FD', | |||||
'近三个月CPU平均使用率') | |||||
chart2.setOption(option) | |||||
}, | |||||
initChart3 = () => { | |||||
if (!chart3) chart3 = echarts.init(chart3Ref.value) | |||||
const option = getCirChartOptions(applicationData.value.cpRate, '#ffae00', | |||||
'近三个月磁盘平均使用率') | |||||
chart3.setOption(option) | |||||
}, | |||||
getChart = () => { | |||||
initChart1() | |||||
initChart2() | |||||
initChart3() | |||||
}, | |||||
// 切换应用 | |||||
tabName = ref(0), | |||||
changeApp = (index) => { | |||||
tabName.value = index | |||||
applicationData.value = applications.value[index] | |||||
getChart() | |||||
}, | |||||
// 提交 | |||||
submitLoading = ref(false), | |||||
submit = async (formEl) => { | |||||
if (!formEl) { | |||||
return | |||||
} | |||||
formEl.validate(async (valid, err) => { | |||||
if (valid) { | |||||
submitLoading.value = true | |||||
const postData = { | |||||
id: route.query.id, | |||||
isCompletedLogCollection: formData.value.isCompletedLogCollection, | |||||
finalAcceptanceMaterials: JSON.stringify(formData.value.finalAcceptanceMaterials), | |||||
actualPerformanceIndicators: formData.value.actualPerformanceIndicators && JSON.stringify(formData.value.actualPerformanceIndicators) || undefined | |||||
} | |||||
try { | |||||
await submitFinal(route.name === 'declarationFinal' ? 1 : 2, { projectInfo: postData }) | |||||
submitLoading.value = false | |||||
proxy.$message.success('提交成功') | |||||
router.go(-1) | |||||
} catch (e) { | |||||
submitLoading.value = false | |||||
} | |||||
} else { | |||||
console.log(err) | |||||
} | |||||
}) | |||||
}, | |||||
getProjectDetail = async () => { | |||||
const res = await projectDetail(route.query.id) | |||||
formData.value = { | |||||
isCompletedLogCollection: res.data.isCompletedLogCollection, | |||||
finalAcceptanceMaterials: res.data.finalAcceptanceMaterials && JSON.parse(res.data.finalAcceptanceMaterials) || res.data.preliminaryInspectionMaterials && JSON.parse(res.data.preliminaryInspectionMaterials), | |||||
actualPerformanceIndicators: res.data.actualPerformanceIndicators && JSON.parse(res.data.actualPerformanceIndicators) || res.data.actualPerformanceIndicators && JSON.parse(res.data.actualPerformanceIndicators) | |||||
} | |||||
formData.value.finalAcceptanceMaterials = formData.value.finalAcceptanceMaterials.map(i => { | |||||
return { | |||||
...i, | |||||
data: i.data.map(j => { | |||||
return { | |||||
...j, | |||||
isHave: ['软件类系统开发、部署等完成情况对照表', '信息安全等级保护测评报告', '用户使用报告', 'IRS应用试运行报告', '终验意见'].includes(j.name) ? true : j.isHave, | |||||
required: ['软件类系统开发、部署等完成情况对照表', '信息安全等级保护测评报告', '用户使用报告', 'IRS应用试运行报告', '终验意见'].includes(j.name) ? true : j.required | |||||
} | |||||
}) | |||||
} | |||||
}) | |||||
if (res.data.projectApplications?.length) { | |||||
if (res.data.projectApplications.map(i => i.secrecyGrade).includes(3) || res.data.projectApplications.map(i => i.secrecyGrade).includes(4) || res.data.projectApplications.map(i => i.secrecyGrade).includes(5)) { | |||||
formData.value.finalAcceptanceMaterials = formData.value.finalAcceptanceMaterials.map(i => { | |||||
return { | |||||
...i, | |||||
data: i.data.map(j => { | |||||
return { | |||||
...j, | |||||
isHave: ['商业密码应用评估报告'].includes(j.name) ? true : j.isHave, | |||||
required: ['商业密码应用评估报告'].includes(j.name) ? true : j.required | |||||
} | |||||
}) | |||||
} | |||||
}) | |||||
} | |||||
} | |||||
applications.value = res.data.projectApplications?.map((i, index) => { | |||||
return { | |||||
name: i.applicationName || i.relatedExistsApplication, | |||||
status: '运行中', | |||||
finalIrsApps: res.data.finalIrsApps[index] | |||||
} | |||||
}) || [] | |||||
applicationData.value = applications.value[0] | |||||
}, | |||||
// 实际成效指标 | |||||
column1 = [ | |||||
{ | |||||
label: '核心业务', | |||||
prop: 'businessName', | |||||
key: 'businessName' | |||||
}, | |||||
{ | |||||
label: '实际成效指标', | |||||
prop: 'name', | |||||
key: 'name' | |||||
}, | |||||
{ | |||||
label: '数值', | |||||
prop: 'nums', | |||||
key: 'nums' | |||||
}, | |||||
{ | |||||
label: '单位', | |||||
prop: 'unit', | |||||
key: 'unit' | |||||
}, | |||||
{ | |||||
label: '操作', | |||||
slot: 'action', | |||||
key: 'action' | |||||
} | |||||
], | |||||
projectContentDialogData = reactive({ | |||||
visible: false, | |||||
data: undefined | |||||
}), | |||||
projectContentIndex = ref(), | |||||
showProjectContentDialog = (data, index) => { | |||||
projectContentDialogData.data = data | |||||
projectContentDialogData.visible = true | |||||
projectContentIndex.value = index | |||||
}, | |||||
setContent = (data) => { | |||||
if (projectContentIndex.value === undefined) { | |||||
formData.value.actualPerformanceIndicators = formData.value.actualPerformanceIndicators?.length ? [...formData.value.actualPerformanceIndicators, ...data] : data | |||||
} else { | |||||
formData.value.actualPerformanceIndicators[projectContentIndex.value] = data[0] | |||||
} | |||||
}, | |||||
delProjectContent = (index) => { | |||||
formData.value.actualPerformanceIndicators.splice(index, 1) | |||||
} | |||||
onMounted(async () => { | |||||
await nextTick() | |||||
// getChart() | |||||
getProjectDetail() | |||||
}) | |||||
</script> | |||||
<template> | |||||
<div class="uploadInitfinalAcceptanceMaterials footerPage"> | |||||
<el-form | |||||
ref="formRef" | |||||
:model="formData" | |||||
label-position="right" | |||||
label-width="90px" | |||||
label-suffix=":" | |||||
scroll-to-error | |||||
class="table-form" | |||||
> | |||||
<el-collapse v-model="collapseModal"> | |||||
<el-collapse-item v-if="applications?.length" name="1" class="mb-16"> | |||||
<template #title> | |||||
<div class="collapse-title">关联的应用信息</div> | |||||
</template> | |||||
<div class="pb-24"> | |||||
<el-tabs v-model="tabName" tab-position="left" @tab-change="changeApp"> | |||||
<el-tab-pane | |||||
v-for="(item,index) in applications" | |||||
:key="index" | |||||
:label="item.name" | |||||
:name="index" | |||||
/> | |||||
<div class="pl-24"> | |||||
<p class="font-semibold text-14 mb-16">应用状态:<span class="text-primary">{{ applicationData.status }}</span></p> | |||||
<p class="font-semibold text-14">资源概览</p> | |||||
<div class="p-16"> | |||||
<el-row class="mb-16"> | |||||
<el-col :span="12"> | |||||
<p class="mb-8">云资源使用情况</p> | |||||
<el-descriptions :column="1" border> | |||||
<el-descriptions-item label="云资源实例使用数"> | |||||
{{ applicationData?.finalIrsApps?.cloudResourceUsage.instancesNum }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="云资源产品"> | |||||
暂无 | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="云资源利用率"> | |||||
{{ applicationData?.finalIrsApps?.cloudResourceUsage.utilizationRate }} | |||||
</el-descriptions-item> | |||||
</el-descriptions> | |||||
</el-col> | |||||
</el-row> | |||||
<el-row :gutter="24"> | |||||
<el-col :span="12" class="mb-16"> | |||||
<p class="mb-8">数据使用情况</p> | |||||
<el-descriptions :column="1" border> | |||||
<el-descriptions-item label="数据共享申请量"> | |||||
{{ applicationData?.finalIrsApps?.dataUsage.sharedApplicationVolume }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="数据共享使用量"> | |||||
{{ applicationData?.finalIrsApps?.dataUsage.sharedUsage }} | |||||
</el-descriptions-item> | |||||
</el-descriptions> | |||||
</el-col> | |||||
<el-col :span="12" class="mb-16"> | |||||
<p class="mb-31"></p> | |||||
<el-descriptions :column="1" border> | |||||
<el-descriptions-item label="协同接口调用量"> | |||||
{{ applicationData?.finalIrsApps?.dataUsage.collaborativeInterfaceCallVolume }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="数据共享调用量"> | |||||
{{ applicationData?.finalIrsApps?.dataUsage.sharedInterfaceCallVolume }} | |||||
</el-descriptions-item> | |||||
</el-descriptions> | |||||
</el-col> | |||||
<el-col :span="12" class="mb-16"> | |||||
<p class="mb-8">组件使用情况</p> | |||||
<el-descriptions :column="1" border> | |||||
<el-descriptions-item label="组件申请量"> | |||||
{{ applicationData?.finalIrsApps?.componentUsage.applicationVolume }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="组件调用量"> | |||||
{{ applicationData?.finalIrsApps?.componentUsage.callVolume }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="组件使用量"> | |||||
{{ applicationData?.finalIrsApps?.componentUsage.useVolume }} | |||||
</el-descriptions-item> | |||||
</el-descriptions> | |||||
</el-col> | |||||
<el-col :span="12" class="mb-16"> | |||||
<p class="mb-31"></p> | |||||
<el-descriptions :column="1" border> | |||||
<el-descriptions-item label="统一组件调用量"> | |||||
{{ applicationData?.finalIrsApps?.componentUsage.unifyCallolVolume }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="使用组件"> | |||||
暂无 | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="使用强制类组件"> | |||||
暂无 | |||||
</el-descriptions-item> | |||||
</el-descriptions> | |||||
</el-col> | |||||
<el-col :span="12" class="mb-16"> | |||||
<p class="mb-8">产生数据</p> | |||||
<el-descriptions :column="1" border> | |||||
<el-descriptions-item label="产生数据量"> | |||||
{{ applicationData?.finalIrsApps?.generateData.volume }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="产生数据共享使用量"> | |||||
{{ applicationData?.finalIrsApps?.generateData.sharedUseVolume }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="数据接口被调用量"> | |||||
{{ applicationData?.finalIrsApps?.generateData.dataInterfaceCallsVolume }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="使用批量数据"> | |||||
暂无 | |||||
</el-descriptions-item> | |||||
</el-descriptions> | |||||
</el-col> | |||||
<el-col :span="12" class="mb-16"> | |||||
<p class="mb-31"></p> | |||||
<el-descriptions :column="1" border> | |||||
<el-descriptions-item label="产生数据共享申请量"> | |||||
{{ applicationData?.finalIrsApps?.generateData.sharedApplicationVolume }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="产生数据审批通过率"> | |||||
{{ applicationData?.finalIrsApps?.generateData.approvalPassRate }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="协同接口被调用量"> | |||||
{{ applicationData?.finalIrsApps?.generateData.collaborativeInterfaceCallVolume }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="使用共享接口"> | |||||
暂无 | |||||
</el-descriptions-item> | |||||
</el-descriptions> | |||||
</el-col> | |||||
<el-col :span="12"> | |||||
<p class="mb-8">试运行报告</p> | |||||
<el-descriptions :column="1" border> | |||||
<el-descriptions-item label="试运行报告通过率"> | |||||
{{ applicationData?.finalIrsApps?.operationReport.passRate }} | |||||
</el-descriptions-item> | |||||
</el-descriptions> | |||||
</el-col> | |||||
</el-row> | |||||
</div> | |||||
<template v-if="false"> | |||||
<p class="font-semibold text-14">云资源利用率</p> | |||||
<el-row> | |||||
<el-col :span="8"> | |||||
<div ref="chart1Ref" style="height: 200px"></div> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<div ref="chart2Ref" style="height: 200px"></div> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<div ref="chart3Ref" style="height: 200px"></div> | |||||
</el-col> | |||||
</el-row> | |||||
</template> | |||||
</div> | |||||
</el-tabs> | |||||
</div> | |||||
</el-collapse-item> | |||||
<el-collapse-item name="7" class="mb-16"> | |||||
<template #title> | |||||
<div class="collapse-title">实施信息</div> | |||||
</template> | |||||
<el-form-item | |||||
label="是否完成日志数据归集" | |||||
label-width="170" | |||||
prop="isCompletedLogCollection" | |||||
:rules="[{required:true,message:'请选择'}]" | |||||
> | |||||
<el-radio-group v-model="formData.isCompletedLogCollection"> | |||||
<el-radio :label="true">是</el-radio> | |||||
<el-radio :label="false">否</el-radio> | |||||
</el-radio-group> | |||||
</el-form-item> | |||||
<el-form-item | |||||
label="实际成效指标" | |||||
label-width="170" | |||||
prop="actualPerformanceIndicators" | |||||
:rules="[{required:true,message:'请选择'}]" | |||||
> | |||||
<table-list | |||||
:pagination="false" | |||||
style="width: 100%" | |||||
:column="column1" | |||||
:data="formData.actualPerformanceIndicators" | |||||
:empty-temp="false" | |||||
> | |||||
<template #action="{scope}"> | |||||
<a @click="showProjectContentDialog(scope.row,scope.$index)">编辑</a> | |||||
<a class="text-danger" @click="delProjectContent(scope.$index)">删除</a> | |||||
</template> | |||||
</table-list> | |||||
<p class="text-right w-full mt-8"> | |||||
<el-button | |||||
type="primary" | |||||
class="w-full" | |||||
plain | |||||
icon="Plus" | |||||
@click="()=>showProjectContentDialog()" | |||||
>添加</el-button> | |||||
</p> | |||||
</el-form-item> | |||||
</el-collapse-item> | |||||
<el-collapse-item | |||||
v-for="(item,index) in formData.finalAcceptanceMaterials" | |||||
:key="index" | |||||
:name="index+2+''" | |||||
class="mb-16" | |||||
> | |||||
<template #title> | |||||
<div class="collapse-title">{{ item.title }}</div> | |||||
</template> | |||||
<table-list | |||||
ref="tableListRef" | |||||
:column="column" | |||||
:data="item.data" | |||||
:pagination="false" | |||||
:empty-temp="false" | |||||
> | |||||
<template #isHave="{scope}"> | |||||
<el-switch v-model="scope.row.isHave" :disabled="scope.row.required" /> | |||||
</template> | |||||
<template #files="{scope}"> | |||||
<template v-if="scope.$index>=0"> | |||||
<el-form-item | |||||
v-if="scope.row.isHave" | |||||
:prop="`finalAcceptanceMaterials[${index}].data[${scope.$index}].files`" | |||||
:rules="[{ required: true, message: '请上传' }]" | |||||
label-width="0" | |||||
style="margin-bottom: 0" | |||||
class="uploadFormItem" | |||||
> | |||||
<el-upload | |||||
v-model:file-list="scope.row.files" | |||||
class="w-full table-upload" | |||||
:action="uploadUrl" | |||||
:on-success="res => handleFileSuccess(res, scope.row.files)" | |||||
:before-upload="file=>fileFormatVerification(file, {types: fileTypes})" | |||||
:accept="fileTypes.map(i=>`.${i}`).join(',')" | |||||
:on-preview="handleFilePreview" | |||||
> | |||||
<el-button type="primary" plain size="small">选择文件</el-button> | |||||
</el-upload> | |||||
</el-form-item> | |||||
<el-form-item | |||||
v-else | |||||
:prop="`finalAcceptanceMaterials[${index}].data[${scope.$index}].reason`" | |||||
:rules="[{ required: true, message: '请输入' }]" | |||||
label-width="0" | |||||
style="margin-bottom: 0" | |||||
> | |||||
<el-input v-model="scope.row.reason" placeholder="请填写缺少该材料的原因" maxlength="50" /> | |||||
</el-form-item> | |||||
</template> | |||||
</template> | |||||
</table-list> | |||||
</el-collapse-item> | |||||
</el-collapse> | |||||
</el-form> | |||||
<div class="footer"> | |||||
<el-button @click="router.go(-1)"> 返回 </el-button> | |||||
<el-button type="primary" :loading="submitLoading" @click="submit(formRef)"> 提交 </el-button> | |||||
</div> | |||||
</div> | |||||
<actual-performance-indicators-dialog | |||||
:visible="projectContentDialogData.visible" | |||||
:data="projectContentDialogData.data" | |||||
@set-content="setContent" | |||||
@close="projectContentDialogData.visible=false" | |||||
/> | |||||
</template> | |||||
<style lang="less"> | |||||
.uploadInitfinalAcceptanceMaterials{ | |||||
.table-form{ | |||||
.uploadFormItem{ | |||||
.el-form-item__error{ | |||||
position: absolute; | |||||
left: 100px; | |||||
top:16px; | |||||
transform: translateY(-50%); | |||||
} | |||||
} | |||||
} | |||||
} | |||||
</style> |
@@ -0,0 +1,210 @@ | |||||
<script setup name="finalInspectionDeclare"> | |||||
import { ref, reactive, onMounted } from 'vue' | |||||
import { declareExport } from '@/http/apis/declareMange' | |||||
import { useRouter } from 'vue-router' | |||||
import useExportExc from '@/utils/useExportExc' | |||||
import { list } from '@/http/apis/declareMange/finalInspectionDeclare' | |||||
import store from '@/store' | |||||
const router = useRouter() | |||||
const { projectTypeOptions } = store.dictStore.globalDicts || {} | |||||
// 搜索栏表单数据 | |||||
const searchForm = reactive({ | |||||
projectType: undefined, | |||||
status: undefined, | |||||
projectYear: undefined, | |||||
projectName: undefined, | |||||
createOnMin: undefined, | |||||
createOnMax: undefined, | |||||
times: [] | |||||
}), | |||||
column = reactive([ | |||||
{ | |||||
label: '序号', | |||||
type: 'index', | |||||
width: '80' | |||||
}, | |||||
{ | |||||
label: '项目名称', | |||||
key: 'projectName', | |||||
prop: 'projectName', | |||||
minWidth: '200', | |||||
showOverflowTooltip: true | |||||
}, | |||||
{ | |||||
label: '项目类型', | |||||
key: 'projectTypeName', | |||||
prop: 'projectTypeName', | |||||
width: '80' | |||||
}, | |||||
{ | |||||
label: '批复金额(万元)', | |||||
key: 'approvedAmount', | |||||
prop: 'approvedAmount', | |||||
width: '150' | |||||
}, | |||||
{ | |||||
label: '预算年度', | |||||
key: 'projectYear', | |||||
prop: 'projectYear', | |||||
width: 80 | |||||
}, | |||||
{ | |||||
label: '计划验收时间', | |||||
key: 'planAcceptanceTime', | |||||
prop: 'planAcceptanceTime', | |||||
width: '200' | |||||
}, | |||||
{ | |||||
label: '操作', | |||||
slot: 'action', | |||||
width: '180', | |||||
fixed: 'right' | |||||
} | |||||
]), | |||||
data = ref([]), | |||||
tableListRef = ref(), | |||||
getTableData = async (pageParams = tableListRef.value.pageParams) => { | |||||
const res = await list({ | |||||
...pageParams, | |||||
...searchForm, | |||||
createOnMin: searchForm.times?.[0], | |||||
createOnMax: searchForm.times?.[1], | |||||
projectYear: searchForm.projectYear * 1 || undefined, | |||||
times: undefined | |||||
}) | |||||
data.value = res.data.records | |||||
total.value = res.data.total | |||||
}, | |||||
// 数据总数 | |||||
total = ref(0), | |||||
// 提交查询 | |||||
search = () => { | |||||
getTableData() | |||||
}, | |||||
// 重置 | |||||
formReset = () => { | |||||
searchForm.projectYear = undefined | |||||
searchForm.projectName = undefined | |||||
searchForm.projectType = undefined | |||||
searchForm.createOnMin = undefined | |||||
searchForm.createOnMax = undefined | |||||
searchForm.times = undefined | |||||
tableListRef.value.pageParams.pageNumber = 1 | |||||
tableListRef.value.pageParams.pageSize = 10 | |||||
getTableData() | |||||
}, | |||||
// 导出excel文件 | |||||
{ exportLoading, exportData } = useExportExc(), | |||||
handleExcel = () => { | |||||
exportData(() => declareExport(9, { | |||||
...searchForm, | |||||
createOnMin: searchForm.times?.[0], | |||||
createOnMax: searchForm.times?.[1], | |||||
projectYear: searchForm.projectYear * 1 || undefined, | |||||
times: undefined | |||||
})) | |||||
} | |||||
onMounted(async () => { | |||||
getTableData() | |||||
}) | |||||
</script> | |||||
<template> | |||||
<el-card class="w-full search"> | |||||
<el-form :model="searchForm" size="small" label-suffix=":"> | |||||
<el-row :gutter="16" class="mb-16"> | |||||
<el-col :span="8"> | |||||
<el-form-item label="项目名称"> | |||||
<el-input | |||||
v-model="searchForm.projectName" | |||||
maxlength="50" | |||||
placeholder="请输入" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="6"> | |||||
<el-form-item label="项目类型"> | |||||
<el-select | |||||
v-model="searchForm.projectType" | |||||
placeholder="全部" | |||||
class="w-full" | |||||
> | |||||
<el-option | |||||
v-for="(v,k) in projectTypeOptions" | |||||
:key="k" | |||||
:label="v" | |||||
:value="k" | |||||
/> | |||||
</el-select> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="10"> | |||||
<el-form-item label="计划验收时间"> | |||||
<el-date-picker | |||||
v-model="searchForm.times" | |||||
type="datetimerange" | |||||
range-separator="-" | |||||
start-placeholder="开始时间" | |||||
end-placeholder="结束时间" | |||||
format="YYYY-MM-DD HH:mm" | |||||
value-format="YYYY-MM-DD HH:mm" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
</el-row> | |||||
<el-row :gutter="24"> | |||||
<el-col :span="12"> | |||||
<el-form-item label="创建时间"> | |||||
<el-date-picker | |||||
v-model="searchForm.times" | |||||
type="datetimerange" | |||||
range-separator="-" | |||||
start-placeholder="开始时间" | |||||
end-placeholder="结束时间" | |||||
format="YYYY-MM-DD HH:mm" | |||||
value-format="YYYY-MM-DD HH:mm" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="12"> | |||||
<el-form-item class="btn"> | |||||
<div class="flex"> | |||||
<el-button type="primary" @click="search">查询</el-button> | |||||
<el-button @click="formReset">重置</el-button> | |||||
</div> | |||||
</el-form-item> | |||||
</el-col> | |||||
</el-row> | |||||
</el-form> | |||||
</el-card> | |||||
<el-card class="w-full mt-8"> | |||||
<template #header> | |||||
<div class="flex justify-between"> | |||||
<span>列表</span> | |||||
<div> | |||||
<el-button | |||||
type="primary" | |||||
size="small" | |||||
plain | |||||
:loading="exportLoading" | |||||
@click="handleExcel" | |||||
> | |||||
导出 | |||||
</el-button> | |||||
</div> | |||||
</div> | |||||
</template> | |||||
<table-list | |||||
ref="tableListRef" | |||||
:column="column" | |||||
:data="data" | |||||
:total="total" | |||||
@get-table-data="getTableData" | |||||
> | |||||
<template #action="{ scope }"> | |||||
<a @click="router.push({ name: 'declarationFinal', query: { id: scope.row.id }})">终验申报</a> | |||||
<a @click="router.push({name:'finalInspectionDeclareDetail',query:{id:scope.row.id}})">详情</a> | |||||
</template> | |||||
</table-list> | |||||
</el-card> | |||||
</template> | |||||
<style lang="less" scoped></style> |
@@ -0,0 +1,226 @@ | |||||
<script setup name="initialInspectionRecord"> | |||||
import { ref, reactive, onMounted } from 'vue' | |||||
import { declareExport } from '@/http/apis/declareMange' | |||||
import { useRouter } from 'vue-router' | |||||
import useExportExc from '@/utils/useExportExc' | |||||
import { list } from '@/http/apis/declareMange/initialInspectionRecord' | |||||
import store from '@/store' | |||||
const { projectTypeOptions } = store.dictStore.globalDicts || {} | |||||
const router = useRouter() | |||||
// 搜索栏表单数据 | |||||
const searchForm = reactive({ | |||||
projectType: undefined, | |||||
status: undefined, | |||||
projectYear: undefined, | |||||
projectName: undefined, | |||||
createOnMin: undefined, | |||||
createOnMax: undefined, | |||||
times: [] | |||||
}), | |||||
column = reactive([ | |||||
{ | |||||
label: '序号', | |||||
type: 'index', | |||||
width: '80' | |||||
}, | |||||
{ | |||||
label: '项目名称', | |||||
key: 'projectName', | |||||
prop: 'projectName', | |||||
minWidth: '200', | |||||
showOverflowTooltip: true | |||||
}, | |||||
{ | |||||
label: '项目类型', | |||||
key: 'projectTypeName', | |||||
prop: 'projectTypeName', | |||||
width: '80' | |||||
}, | |||||
{ | |||||
label: '年度预算(万元)', | |||||
key: 'annualPlanAmount', | |||||
prop: 'annualPlanAmount', | |||||
width: '150' | |||||
}, | |||||
{ | |||||
label: '成交金额(万元)', | |||||
key: 'transactionAmount', | |||||
prop: 'transactionAmount', | |||||
width: '150' | |||||
}, | |||||
{ | |||||
label: '合同金额(万元)', | |||||
key: 'contractAmount', | |||||
prop: 'contractAmount', | |||||
width: '150' | |||||
}, | |||||
{ | |||||
label: '预算年度', | |||||
key: 'projectYear', | |||||
prop: 'projectYear', | |||||
width: 80 | |||||
}, | |||||
{ | |||||
label: '交货日期', | |||||
key: 'deliveryTime', | |||||
prop: 'deliveryTime', | |||||
width: '200' | |||||
}, | |||||
{ | |||||
label: '创建时间', | |||||
key: 'createOn', | |||||
prop: 'createOn', | |||||
width: '200' | |||||
}, | |||||
{ | |||||
label: '操作', | |||||
slot: 'action', | |||||
width: '180', | |||||
fixed: 'right' | |||||
} | |||||
]), | |||||
data = ref([]), | |||||
tableListRef = ref(), | |||||
getTableData = async (pageParams = tableListRef.value.pageParams) => { | |||||
const res = await list({ | |||||
...pageParams, | |||||
...searchForm, | |||||
createOnMin: searchForm.times?.[0], | |||||
createOnMax: searchForm.times?.[1], | |||||
projectYear: searchForm.projectYear * 1 || undefined, | |||||
times: undefined | |||||
}) | |||||
data.value = res.data.records | |||||
total.value = res.data.total | |||||
}, | |||||
// 数据总数 | |||||
total = ref(2), | |||||
// 提交查询 | |||||
search = () => { | |||||
getTableData() | |||||
}, | |||||
// 重置 | |||||
formReset = () => { | |||||
searchForm.projectYear = undefined | |||||
searchForm.projectName = undefined | |||||
searchForm.projectType = undefined | |||||
searchForm.createOnMin = undefined | |||||
searchForm.createOnMax = undefined | |||||
searchForm.times = undefined | |||||
tableListRef.value.pageParams.pageNumber = 1 | |||||
tableListRef.value.pageParams.pageSize = 10 | |||||
getTableData() | |||||
}, | |||||
// 导出excel文件 | |||||
{ exportLoading, exportData } = useExportExc(), | |||||
handleExcel = () => { | |||||
exportData(() => declareExport(8, { | |||||
...searchForm, | |||||
createOnMin: searchForm.times?.[0], | |||||
createOnMax: searchForm.times?.[1], | |||||
projectYear: searchForm.projectYear * 1 || undefined, | |||||
times: undefined | |||||
})) | |||||
} | |||||
onMounted(async () => { | |||||
getTableData() | |||||
}) | |||||
</script> | |||||
<template> | |||||
<el-card class="w-full search"> | |||||
<el-form :model="searchForm" size="small" label-suffix=":"> | |||||
<el-row :gutter="16" class="mb-16"> | |||||
<el-col :span="8"> | |||||
<el-form-item label="项目名称"> | |||||
<el-input | |||||
v-model="searchForm.projectName" | |||||
maxlength="50" | |||||
placeholder="请输入" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<el-form-item label="项目类型"> | |||||
<el-select | |||||
v-model="searchForm.projectType" | |||||
placeholder="全部" | |||||
class="w-full" | |||||
> | |||||
<el-option | |||||
v-for="(v,k) in projectTypeOptions" | |||||
:key="k" | |||||
:label="v" | |||||
:value="k" | |||||
/> | |||||
</el-select> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<el-form-item label="预算年度"> | |||||
<el-date-picker | |||||
v-model="searchForm.projectYear" | |||||
type="year" | |||||
placeholder="请选择" | |||||
format="YYYY" | |||||
value-format="YYYY" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
</el-row> | |||||
<el-row :gutter="24"> | |||||
<el-col :span="12"> | |||||
<el-form-item label="创建时间"> | |||||
<el-date-picker | |||||
v-model="searchForm.times" | |||||
type="datetimerange" | |||||
range-separator="-" | |||||
start-placeholder="开始时间" | |||||
end-placeholder="结束时间" | |||||
format="YYYY-MM-DD HH:mm" | |||||
value-format="YYYY-MM-DD HH:mm" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="12"> | |||||
<el-form-item class="btn"> | |||||
<div class="flex"> | |||||
<el-button type="primary" @click="search">查询</el-button> | |||||
<el-button @click="formReset">重置</el-button> | |||||
</div> | |||||
</el-form-item> | |||||
</el-col> | |||||
</el-row> | |||||
</el-form> | |||||
</el-card> | |||||
<el-card class="w-full mt-8"> | |||||
<template #header> | |||||
<div class="flex justify-between"> | |||||
<span>列表</span> | |||||
<div> | |||||
<el-button | |||||
type="primary" | |||||
size="small" | |||||
plain | |||||
:loading="exportLoading" | |||||
@click="handleExcel" | |||||
> | |||||
导出 | |||||
</el-button> | |||||
</div> | |||||
</div> | |||||
</template> | |||||
<table-list | |||||
ref="tableListRef" | |||||
:column="column" | |||||
:data="data" | |||||
:total="total" | |||||
@get-table-data="getTableData" | |||||
> | |||||
<template #action="{ scope }"> | |||||
<a @click="router.push({ name: 'uploadInitMaterials', query: { id: scope.row.id }})">上传初验材料</a> | |||||
<a @click="router.push({name:'initialInspectionRecordDetail',query:{id:scope.row.id}})">详情</a> | |||||
</template> | |||||
</table-list> | |||||
</el-card> | |||||
</template> | |||||
<style lang="less" scoped></style> |
@@ -0,0 +1,186 @@ | |||||
<script setup name="actualPerformanceIndicatorsDialog"> | |||||
import { ref, watch } from 'vue' | |||||
const | |||||
props = defineProps({ | |||||
visible: { | |||||
type: Boolean, | |||||
default: false, | |||||
required: true | |||||
}, | |||||
data: Object | |||||
}), | |||||
form = ref({ | |||||
perIndicator: [] | |||||
}), | |||||
formRef = ref(), | |||||
rules = { | |||||
perIndicator: [{ required: true, message: '请至少添加一个实际成效指标' }] | |||||
}, | |||||
column = [ | |||||
{ | |||||
label: '核心业务名称', | |||||
key: 'businessName', | |||||
slot: 'businessName', | |||||
width: 140 | |||||
}, | |||||
{ | |||||
label: '实际成效指标名称', | |||||
key: 'name', | |||||
slot: 'name', | |||||
width: 140 | |||||
}, | |||||
{ | |||||
label: '数值', | |||||
key: 'nums', | |||||
slot: 'nums' | |||||
}, | |||||
{ | |||||
label: '单位', | |||||
key: 'unit', | |||||
slot: 'unit' | |||||
}, | |||||
{ | |||||
label: '操作', | |||||
key: 'action', | |||||
slot: 'action', | |||||
width: 70 | |||||
} | |||||
], | |||||
// 添加 | |||||
add = () => { | |||||
form.value.perIndicator.push({}) | |||||
}, | |||||
del = (index) => { | |||||
form.value.perIndicator.splice(index, 1) | |||||
}, | |||||
submit = async (formEl) => { | |||||
if (!formEl) { | |||||
return | |||||
} | |||||
await formEl.validate(async (valid) => { | |||||
if (valid) { | |||||
const data = JSON.parse(JSON.stringify(form.value.perIndicator)) | |||||
emits('setContent', data) | |||||
emits('close', true) | |||||
} | |||||
}) | |||||
}, | |||||
isShowAdd = ref(true), | |||||
emits = defineEmits(['close', 'setContent']) | |||||
watch( | |||||
() => props.visible, | |||||
async (val) => { | |||||
if (val && props.data) { | |||||
isShowAdd.value = !props.data | |||||
form.value.perIndicator = [JSON.parse(JSON.stringify(props.data))] | |||||
} else { | |||||
isShowAdd.value = true | |||||
formRef.value?.resetFields() | |||||
form.value = { | |||||
perIndicator: [] | |||||
} | |||||
} | |||||
} | |||||
) | |||||
</script> | |||||
<template> | |||||
<el-dialog | |||||
:model-value="visible" | |||||
title="添加" | |||||
:size="840" | |||||
@close="emits('close')" | |||||
> | |||||
<el-form | |||||
ref="formRef" | |||||
label-suffix=":" | |||||
:model="form" | |||||
:rules="rules" | |||||
label-width="160" | |||||
> | |||||
<el-button | |||||
v-if="isShowAdd" | |||||
type="primary" | |||||
plain | |||||
icon="Plus" | |||||
class="w-full mb-8" | |||||
@click="add" | |||||
>添加 | |||||
</el-button> | |||||
<table-list | |||||
:pagination="false" | |||||
:column="column" | |||||
:empty-temp="false" | |||||
:data="form.perIndicator" | |||||
> | |||||
<template #businessName="{scope}"> | |||||
<el-form-item | |||||
v-if="scope.$index>=0" | |||||
:prop="`perIndicator[${scope.$index}].businessName`" | |||||
:rules="[{required:true,message:' '}]" | |||||
label-width="0" | |||||
style="margin-bottom: 0" | |||||
> | |||||
<el-input | |||||
v-model="form.perIndicator[scope.$index].businessName" | |||||
placeholder="请输入" | |||||
maxlength="50" | |||||
/> | |||||
</el-form-item> | |||||
</template> | |||||
<template #name="{scope}"> | |||||
<el-form-item | |||||
v-if="scope.$index>=0" | |||||
:prop="`perIndicator[${scope.$index}].name`" | |||||
:rules="[{required:true,message:' '}]" | |||||
label-width="0" | |||||
style="margin-bottom: 0" | |||||
> | |||||
<el-input | |||||
v-model="form.perIndicator[scope.$index].name" | |||||
placeholder="请输入" | |||||
maxlength="50" | |||||
/> | |||||
</el-form-item> | |||||
</template> | |||||
<template #nums="{scope}"> | |||||
<el-form-item | |||||
v-if="scope.$index>=0" | |||||
:prop="`perIndicator[${scope.$index}].nums`" | |||||
label-width="0" | |||||
style="margin-bottom: 0" | |||||
> | |||||
<el-input-number | |||||
v-model="form.perIndicator[scope.$index].nums" | |||||
:controls="false" | |||||
class="flex-1 mr-8" | |||||
placeholder="请输入" | |||||
@mousewheel.prevent | |||||
/> | |||||
</el-form-item> | |||||
</template> | |||||
<template #unit="{scope}"> | |||||
<el-form-item | |||||
v-if="scope.$index>=0" | |||||
:prop="`perIndicator[${scope.$index}].unit`" | |||||
label-width="0" | |||||
style="margin-bottom: 0" | |||||
> | |||||
<el-input | |||||
v-model="form.perIndicator[scope.$index].unit" | |||||
placeholder="请输入" | |||||
maxlength="10" | |||||
/> | |||||
</el-form-item> | |||||
</template> | |||||
<template #action="{scope}"> | |||||
<a class="text-danger cursor-pointer" @click="del(scope.$index)">移除</a> | |||||
</template> | |||||
</table-list> | |||||
</el-form> | |||||
<template #footer> | |||||
<el-button type="primary" @click="submit(formRef)">提交</el-button> | |||||
<el-button @click="emits('close')">取消</el-button> | |||||
</template> | |||||
</el-dialog> | |||||
</template> |
@@ -0,0 +1,581 @@ | |||||
<script name="uploadInitpreliminaryInspectionMaterials" setup> | |||||
import { getCurrentInstance, onMounted, reactive, ref } from 'vue' | |||||
import { fileFormatVerification, handleFileSuccess, handleFilePreview, fileTypes } from '@/utils/uploadAction.js' | |||||
import store from '@/store' | |||||
import { preInsDetail, submitPreIns } from '@/http/apis/declareMange/initialInspectionRecord' | |||||
import { useRoute, useRouter } from 'vue-router' | |||||
import ActualPerformanceIndicatorsDialog | |||||
from '@/pages/declareManage/initialInspectionRecord/uploadInitMaterials/components/actualPerformanceIndicatorsDialog.vue' | |||||
import { projectDetail } from '@/http/apis/projectStoreManage/projectStore' | |||||
const uploadUrl = store.dictStore.uploadUrl, | |||||
route = useRoute(), | |||||
{ proxy } = getCurrentInstance(), | |||||
router = useRouter() | |||||
const collapseModal = ['1', '2', '3', '4', '5', '6', '7'], | |||||
formRef = ref(), | |||||
formData = ref({ | |||||
acceptancePersons: [ | |||||
{ | |||||
personName: '', | |||||
unit: '' | |||||
} | |||||
], | |||||
actualPerformanceIndicators: [], | |||||
preliminaryInspectionMaterials: [ | |||||
{ | |||||
title: '一、项目前期材料', | |||||
data: [ | |||||
{ | |||||
name: '信息化项目立项批复文件', | |||||
isHave: true, | |||||
files: [], | |||||
reason: '' | |||||
}, | |||||
{ | |||||
name: '市政府采购计划表', | |||||
isHave: true, | |||||
files: [], | |||||
reason: '' | |||||
}, | |||||
{ | |||||
name: '采购需求', | |||||
isHave: true, | |||||
files: [], | |||||
reason: '' | |||||
}, | |||||
{ | |||||
name: '中标通知书', | |||||
isHave: true, | |||||
files: [], | |||||
reason: '' | |||||
}, | |||||
{ | |||||
name: '技术(软件、系统等)开发合同(协议)', | |||||
isHave: true, | |||||
files: [], | |||||
reason: '' | |||||
}, | |||||
{ | |||||
name: '设备采购合同(协议)含采购内容清单、以及合同上规定交付的所有文档', | |||||
isHave: true, | |||||
files: [], | |||||
reason: '' | |||||
}, | |||||
{ | |||||
name: '第三方监理合同(协议)', | |||||
isHave: true, | |||||
files: [], | |||||
reason: '' | |||||
}, | |||||
{ | |||||
name: '其他前期资料(含中标单位营业执照、工程相关资质等)', | |||||
isHave: true, | |||||
files: [], | |||||
reason: '' | |||||
} | |||||
] | |||||
}, | |||||
{ | |||||
title: '二、项目开工资料', | |||||
data: [ | |||||
{ | |||||
name: '工程开工报告单(工程名称、建设单位、承建单位、施工单位、计划开工和完工日期、工程实施主要内容、建设单位审批意见及盖章日期,承建单位、施工单位盖章日期)', | |||||
isHave: true, | |||||
files: [], | |||||
reason: '' | |||||
}, | |||||
{ | |||||
name: '软件类系统开发、部署等功能介绍', | |||||
isHave: true, | |||||
files: [], | |||||
reason: '' | |||||
}, | |||||
{ | |||||
name: '隐蔽工程类设计图、材料选材、施工计划等(可另作图册)', | |||||
isHave: true, | |||||
files: [], | |||||
reason: '' | |||||
}, | |||||
{ | |||||
name: '购置到位的设备产品证书、开箱证明、序列号等(可另附成册)', | |||||
isHave: true, | |||||
files: [], | |||||
reason: '' | |||||
}, | |||||
{ | |||||
name: '项目组名单及人员介绍资料', | |||||
isHave: true, | |||||
files: [], | |||||
reason: '' | |||||
} | |||||
] | |||||
}, | |||||
{ | |||||
title: '三、项目实施过程资料', | |||||
data: [ | |||||
{ | |||||
name: '设备安装时间、位置一览表等', | |||||
isHave: true, | |||||
files: [], | |||||
reason: '' | |||||
}, | |||||
{ | |||||
name: '软件类系统开发、部署等完成情况对照表', | |||||
isHave: true, | |||||
files: [], | |||||
reason: '' | |||||
}, | |||||
{ | |||||
name: '历次多方讨论会议记录表、项目变更单等原始凭证', | |||||
isHave: true, | |||||
files: [], | |||||
reason: '' | |||||
}, | |||||
{ | |||||
name: '信息安全等级保护测评报告', | |||||
isHave: true, | |||||
files: [], | |||||
reason: '' | |||||
}, | |||||
{ | |||||
name: '商业密码应用评估报告', | |||||
isHave: true, | |||||
files: [], | |||||
reason: '' | |||||
}, | |||||
{ | |||||
name: '财务审计报告', | |||||
isHave: true, | |||||
files: [], | |||||
reason: '' | |||||
}, | |||||
{ | |||||
name: '变更申请单', | |||||
isHave: true, | |||||
files: [], | |||||
reason: '' | |||||
}, | |||||
{ | |||||
name: '变更批复文件', | |||||
isHave: true, | |||||
files: [], | |||||
reason: '' | |||||
} | |||||
] | |||||
}, | |||||
{ | |||||
title: '四、项目试运行资料', | |||||
data: [ | |||||
{ | |||||
name: '试运行报告及整改情况(建设单位)', | |||||
isHave: true, | |||||
files: [], | |||||
reason: '' | |||||
}, | |||||
{ | |||||
name: '试运行情况业主单位意见(领导签字、单位盖章)', | |||||
isHave: true, | |||||
files: [], | |||||
reason: '' | |||||
}, | |||||
{ | |||||
name: '历次巡检流程及记录表等原始凭证', | |||||
isHave: true, | |||||
files: [], | |||||
reason: '' | |||||
}, | |||||
{ | |||||
name: '用户使用报告', | |||||
isHave: true, | |||||
files: [], | |||||
reason: '' | |||||
}, | |||||
{ | |||||
name: 'IRS应用试运行报告', | |||||
isHave: true, | |||||
files: [], | |||||
reason: '' | |||||
} | |||||
] | |||||
}, | |||||
{ | |||||
title: '五、项目完工资料', | |||||
data: [ | |||||
{ | |||||
name: '工程类竣工报告(建设单位)', | |||||
isHave: true, | |||||
files: [], | |||||
reason: '' | |||||
}, | |||||
{ | |||||
name: '完工整体运行情况报告', | |||||
isHave: true, | |||||
files: [], | |||||
reason: '' | |||||
}, | |||||
{ | |||||
name: '监理总结报告', | |||||
isHave: true, | |||||
files: [], | |||||
reason: '' | |||||
}, | |||||
{ | |||||
name: '第三方项目评测报告(另册)', | |||||
isHave: true, | |||||
files: [], | |||||
reason: '' | |||||
}, | |||||
{ | |||||
name: '业主单位组织的初验专家意见及名单,整改情况', | |||||
isHave: true, | |||||
files: [], | |||||
reason: '' | |||||
}, | |||||
{ | |||||
name: '各类系统、场地、设备使用的管理手册、操作手册、维护手册(可另册)', | |||||
isHave: true, | |||||
files: [], | |||||
reason: '' | |||||
}, | |||||
{ | |||||
name: '售后服务承诺等(建设单位)', | |||||
isHave: true, | |||||
files: [], | |||||
reason: '' | |||||
}, | |||||
{ | |||||
name: '终验意见', | |||||
isHave: true, | |||||
files: [], | |||||
reason: '' | |||||
} | |||||
] | |||||
} | |||||
] | |||||
}), | |||||
// 增加验收人员 | |||||
add = () => { | |||||
formData.value.acceptancePersons.push({}) | |||||
}, | |||||
// 删除验收人员 | |||||
del = (index) => { | |||||
formData.value.acceptancePersons.splice(index, 1) | |||||
}, | |||||
// 材料表格 | |||||
column = [ | |||||
{ | |||||
label: '序号', | |||||
type: 'index', | |||||
width: '60' | |||||
}, | |||||
{ | |||||
label: '材料名称', | |||||
key: 'name', | |||||
prop: 'name' | |||||
}, | |||||
{ | |||||
label: '是否有材料', | |||||
key: 'isHave', | |||||
slot: 'isHave', | |||||
width: 100 | |||||
}, | |||||
{ | |||||
label: '附件/说明(支持扩展名:.doc .docx .pdf)', | |||||
key: 'files', | |||||
slot: 'files' | |||||
} | |||||
], | |||||
// 获取详情 | |||||
getDetail = async () => { | |||||
const res = await preInsDetail(route.query.id) | |||||
if (res.data) { | |||||
formData.value = { | |||||
...res.data, | |||||
acceptancePersons: res.data.acceptancePersons ? res.data.acceptancePersons : [ | |||||
{ | |||||
personName: '', | |||||
unit: '' | |||||
} | |||||
], | |||||
actualPerformanceIndicators: res.data.actualPerformanceIndicators && JSON.parse(res.data.actualPerformanceIndicators)?.length ? JSON.parse(res.data.actualPerformanceIndicators) : formData.value.actualPerformanceIndicators, | |||||
preliminaryInspectionMaterials: res.data.preliminaryInspectionMaterials && JSON.parse(res.data.preliminaryInspectionMaterials)?.length ? JSON.parse(res.data.preliminaryInspectionMaterials) : formData.value.preliminaryInspectionMaterials | |||||
} | |||||
} | |||||
}, | |||||
// 提交 | |||||
submitLoading = ref(false), | |||||
submit = async (formEl) => { | |||||
if (!formEl) { | |||||
return | |||||
} | |||||
formEl.validate(async (valid, err) => { | |||||
if (valid) { | |||||
submitLoading.value = true | |||||
const postData = { | |||||
...formData.value, | |||||
actualPerformanceIndicators: formData.value.actualPerformanceIndicators && JSON.stringify(formData.value.actualPerformanceIndicators), | |||||
preliminaryInspectionMaterials: JSON.stringify(formData.value.preliminaryInspectionMaterials) | |||||
} | |||||
try { | |||||
await submitPreIns(postData) | |||||
submitLoading.value = false | |||||
proxy.$message.success('提交成功') | |||||
router.go(-1) | |||||
} catch (e) { | |||||
submitLoading.value = false | |||||
} | |||||
} else { | |||||
console.log(err) | |||||
} | |||||
}) | |||||
}, | |||||
// 实际成效指标 | |||||
column1 = [ | |||||
{ | |||||
label: '核心业务', | |||||
prop: 'businessName', | |||||
key: 'businessName' | |||||
}, | |||||
{ | |||||
label: '实际成效指标', | |||||
prop: 'name', | |||||
key: 'name' | |||||
}, | |||||
{ | |||||
label: '数值', | |||||
prop: 'nums', | |||||
key: 'nums' | |||||
}, | |||||
{ | |||||
label: '单位', | |||||
prop: 'unit', | |||||
key: 'unit' | |||||
}, | |||||
{ | |||||
label: '操作', | |||||
slot: 'action', | |||||
key: 'action' | |||||
} | |||||
], | |||||
projectContentDialogData = reactive({ | |||||
visible: false, | |||||
data: undefined | |||||
}), | |||||
projectContentIndex = ref(), | |||||
showProjectContentDialog = (data, index) => { | |||||
projectContentDialogData.data = data | |||||
projectContentDialogData.visible = true | |||||
projectContentIndex.value = index | |||||
}, | |||||
setContent = (data) => { | |||||
if (projectContentIndex.value === undefined) { | |||||
formData.value.actualPerformanceIndicators = [...formData.value.actualPerformanceIndicators, ...data] | |||||
} else { | |||||
formData.value.actualPerformanceIndicators[projectContentIndex.value] = data[0] | |||||
} | |||||
}, | |||||
delProjectContent = (index) => { | |||||
formData.value.actualPerformanceIndicators.splice(index, 1) | |||||
}, | |||||
getProjectDetail = async () => { | |||||
const res = await projectDetail(route.query.id) | |||||
if (res.data.projectApplications?.length) { | |||||
if (res.data.projectApplications.map(i => i.secrecyGrade).includes(3) || res.data.projectApplications.map(i => i.secrecyGrade).includes(4) || res.data.projectApplications.map(i => i.secrecyGrade).includes(5)) { | |||||
formData.value.preliminaryInspectionMaterials = formData.value.preliminaryInspectionMaterials.map(i => { | |||||
return { | |||||
...i, | |||||
data: i.data.map(j => { | |||||
return { | |||||
...j, | |||||
required: j.name === '商业密码应用评估报告' ? true : j.required | |||||
} | |||||
}) | |||||
} | |||||
}) | |||||
} | |||||
} | |||||
} | |||||
onMounted(() => { | |||||
getDetail() | |||||
getProjectDetail() | |||||
}) | |||||
</script> | |||||
<template> | |||||
<div class="uploadInitpreliminaryInspectionMaterials footerPage"> | |||||
<el-form | |||||
ref="formRef" | |||||
:model="formData" | |||||
label-position="right" | |||||
label-width="90px" | |||||
label-suffix=":" | |||||
scroll-to-error | |||||
class="table-form" | |||||
> | |||||
<el-collapse v-model="collapseModal"> | |||||
<el-collapse-item name="1" class="mb-16"> | |||||
<template #title> | |||||
<div class="collapse-title">验收人员信息</div> | |||||
</template> | |||||
<div class="p-24"> | |||||
<el-row v-for="(item,index) in formData.acceptancePersons" :key="index" :gutter="40"> | |||||
<el-col :span="12"> | |||||
<el-form-item | |||||
label="验收人员" | |||||
:prop="`acceptancePersons[${index}].personName`" | |||||
:rules="[{ required: true, message: '请输入' }]" | |||||
> | |||||
<el-input v-model="item.personName" placeholder="请填写姓名" maxlength="50" /> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="12"> | |||||
<el-form-item | |||||
label="所在单位" | |||||
:prop="`acceptancePersons[${index}].unit`" | |||||
:rules="[{ required: true, message: '请输入' }]" | |||||
> | |||||
<el-input v-model="item.unit" placeholder="请填写单位" maxlength="50" /> | |||||
</el-form-item> | |||||
</el-col> | |||||
<a | |||||
v-if="formData.acceptancePersons?.length>1" | |||||
class="text-danger absolute top-4" | |||||
style="right: -12px" | |||||
@click="del(index)" | |||||
>删除</a> | |||||
</el-row> | |||||
<el-button | |||||
type="primary" | |||||
plain | |||||
icon="Plus" | |||||
size="small" | |||||
@click="add" | |||||
>增加</el-button> | |||||
</div> | |||||
</el-collapse-item> | |||||
<el-collapse-item name="7" class="mb-16"> | |||||
<template #title> | |||||
<div class="collapse-title">实施信息</div> | |||||
</template> | |||||
<el-form-item | |||||
label="是否完成日志数据归集" | |||||
label-width="170" | |||||
prop="isCompletedLogCollection" | |||||
:rules="[{required:true,message:'请选择'}]" | |||||
> | |||||
<el-radio-group v-model="formData.isCompletedLogCollection"> | |||||
<el-radio :label="true">是</el-radio> | |||||
<el-radio :label="false">否</el-radio> | |||||
</el-radio-group> | |||||
</el-form-item> | |||||
<el-form-item | |||||
label="实际成效指标" | |||||
label-width="170" | |||||
prop="actualPerformanceIndicators" | |||||
:rules="[{required:true,message:'请选择'}]" | |||||
> | |||||
<table-list | |||||
:pagination="false" | |||||
style="width: 100%" | |||||
:column="column1" | |||||
:data="formData.actualPerformanceIndicators" | |||||
:empty-temp="false" | |||||
> | |||||
<template #action="{scope}"> | |||||
<a @click="showProjectContentDialog(scope.row,scope.$index)">编辑</a> | |||||
<a class="text-danger" @click="delProjectContent(scope.$index)">删除</a> | |||||
</template> | |||||
</table-list> | |||||
<p class="text-right w-full mt-8"> | |||||
<el-button | |||||
type="primary" | |||||
class="w-full" | |||||
plain | |||||
icon="Plus" | |||||
@click="()=>showProjectContentDialog()" | |||||
>添加</el-button> | |||||
</p> | |||||
</el-form-item> | |||||
</el-collapse-item> | |||||
<el-collapse-item | |||||
v-for="(item,index) in formData.preliminaryInspectionMaterials" | |||||
:key="index" | |||||
:name="index+2+''" | |||||
class="mb-16" | |||||
> | |||||
<template #title> | |||||
<div class="collapse-title">{{ item.title }}</div> | |||||
</template> | |||||
<table-list | |||||
ref="tableListRef" | |||||
:column="column" | |||||
:data="item.data" | |||||
:pagination="false" | |||||
:empty-temp="false" | |||||
> | |||||
<template #isHave="{scope}"> | |||||
<el-switch v-model="scope.row.isHave" :disabled="scope.row.required" /> | |||||
</template> | |||||
<template #files="{scope}"> | |||||
<template v-if="scope.$index>=0"> | |||||
<el-form-item | |||||
v-if="scope.row.isHave" | |||||
:prop="`preliminaryInspectionMaterials[${index}].data[${scope.$index}].files`" | |||||
:rules="[{ required: true, message: '请上传' }]" | |||||
label-width="0" | |||||
style="margin-bottom: 0" | |||||
class="uploadFormItem" | |||||
> | |||||
<el-upload | |||||
v-model:file-list="scope.row.files" | |||||
class="w-full table-upload" | |||||
:action="uploadUrl" | |||||
:on-success="res => handleFileSuccess(res, scope.row.files)" | |||||
:before-upload="file=>fileFormatVerification(file, {types: fileTypes})" | |||||
:accept="fileTypes.map(i=>`.${i}`).join(',')" | |||||
:on-preview="handleFilePreview" | |||||
> | |||||
<el-button type="primary" plain size="small">选择文件</el-button> | |||||
</el-upload> | |||||
</el-form-item> | |||||
<el-form-item | |||||
v-else | |||||
:prop="`preliminaryInspectionMaterials[${index}].data[${scope.$index}].reason`" | |||||
:rules="[{ required: true, message: '请输入' }]" | |||||
label-width="0" | |||||
style="margin-bottom: 0" | |||||
> | |||||
<el-input v-model="scope.row.reason" placeholder="请填写缺少该材料的原因" maxlength="50" /> | |||||
</el-form-item> | |||||
</template> | |||||
</template> | |||||
</table-list> | |||||
</el-collapse-item> | |||||
</el-collapse> | |||||
</el-form> | |||||
<div class="footer"> | |||||
<el-button @click="router.go(-1)"> 返回 </el-button> | |||||
<el-button type="primary" :loading="submitLoading" @click="submit(formRef)"> 提交 </el-button> | |||||
</div> | |||||
</div> | |||||
<actual-performance-indicators-dialog | |||||
:visible="projectContentDialogData.visible" | |||||
:data="projectContentDialogData.data" | |||||
@set-content="setContent" | |||||
@close="projectContentDialogData.visible=false" | |||||
/> | |||||
</template> | |||||
<style lang="less"> | |||||
.uploadInitpreliminaryInspectionMaterials{ | |||||
.table-form{ | |||||
.uploadFormItem{ | |||||
.el-form-item__error{ | |||||
position: absolute; | |||||
left: 100px; | |||||
top:16px; | |||||
transform: translateY(-50%); | |||||
} | |||||
} | |||||
} | |||||
} | |||||
</style> |
@@ -0,0 +1,69 @@ | |||||
<script setup name="basicInfo"> | |||||
import { onMounted, ref } from 'vue' | |||||
import { applicationList } from '@/http/apis/declareMange' | |||||
import { storeToRefs } from 'pinia' | |||||
import store from '@/store' | |||||
const userInfo = storeToRefs(store.userStore).userInfo, | |||||
props = defineProps({ | |||||
detailData: { | |||||
type: Object, | |||||
default: () => {} | |||||
} | |||||
}), | |||||
column = [ | |||||
{ | |||||
label: '序号', | |||||
type: 'index', | |||||
width: 60 | |||||
}, | |||||
{ | |||||
label: '关联IRS应用名称', | |||||
prop: 'applicationName', | |||||
key: 'applicationName' | |||||
}, | |||||
{ | |||||
label: 'IRS应用编码', | |||||
prop: 'applicationCode', | |||||
key: 'applicationCode' | |||||
}, | |||||
{ | |||||
label: '一本账重大应用名称', | |||||
prop: 'baseAccountAppName', | |||||
key: 'baseAccountAppName' | |||||
}, | |||||
{ | |||||
label: '"领域大脑"一本账名称', | |||||
prop: 'baseBrainName', | |||||
key: 'baseBrainName' | |||||
} | |||||
], | |||||
data = ref([]), | |||||
appList = ref([]) | |||||
onMounted(async () => { | |||||
const res = await applicationList({ areaCode: userInfo.value.regionCode }) | |||||
appList.value = res.data | |||||
data.value = props?.detailData?.baseProjSysCode?.split(';')?.map((i, k) => { | |||||
return { | |||||
applicationCode: i, | |||||
applicationName: props?.detailData?.baseProjSys?.split(';')[k] || '', | |||||
baseAccountAppName: props?.detailData?.baseAccountAppName?.split(';')[k] || '', | |||||
baseBrainName: props?.detailData?.baseBrainName?.split(';')[k] || '' | |||||
} | |||||
}) || [] | |||||
}) | |||||
</script> | |||||
<template> | |||||
<el-descriptions :column="2" border> | |||||
<el-descriptions-item label="关联IRS应用名称"> | |||||
<table-list | |||||
:pagination="false" | |||||
style="width: 100%" | |||||
:column="column" | |||||
:data="data" | |||||
:empty-temp="false" | |||||
/> | |||||
</el-descriptions-item> | |||||
</el-descriptions> | |||||
</template> |
@@ -0,0 +1,186 @@ | |||||
<script setup name="applyInfo"> | |||||
import { onMounted, ref } from 'vue' | |||||
import Accessory from '@/components/accessory/index.vue' | |||||
const props = defineProps({ | |||||
detailData: { | |||||
type: Object, | |||||
default: () => {} | |||||
}, | |||||
basicInfoData: { | |||||
type: Object, | |||||
default: () => {} | |||||
}, | |||||
dictionaryList: Array | |||||
}) | |||||
const column = [ | |||||
{ | |||||
label: '序号', | |||||
type: 'index', | |||||
width: 60 | |||||
}, | |||||
{ | |||||
label: '项目名称', | |||||
prop: 'baseProjName', | |||||
key: 'baseProjName' | |||||
}, | |||||
{ | |||||
label: '预算年度', | |||||
prop: 'baseProjSetYear', | |||||
key: 'baseProjSetYear' | |||||
} | |||||
], | |||||
column1 = [ | |||||
{ | |||||
label: '项目主要内容', | |||||
prop: 'mainContent', | |||||
key: 'mainContent' | |||||
}, | |||||
{ | |||||
label: '业务对象', | |||||
prop: 'businessObject', | |||||
key: 'businessObject' | |||||
} | |||||
], | |||||
// 立项依据 | |||||
buildBasisColumn = [ | |||||
{ | |||||
label: '序号', | |||||
type: 'index', | |||||
width: 60 | |||||
}, | |||||
{ | |||||
label: '依据项', | |||||
key: 'title', | |||||
prop: 'title' | |||||
}, | |||||
{ | |||||
label: '依据文件名', | |||||
slot: 'fileName' | |||||
}, | |||||
{ | |||||
label: '文件(支持word、pdf格式)', | |||||
slot: 'action', | |||||
width: 300 | |||||
} | |||||
], | |||||
buildBasisTableData = ref([]), | |||||
tableListRef = ref() | |||||
onMounted(() => { | |||||
buildBasisTableData.value = props.detailData?.baseProjBasis?.split(';')?.map((i, index) => { | |||||
const file = `[${props.detailData?.baseProjBasisFile.replace(/}];/g, '}],')}]` | |||||
return { | |||||
title: props.dictionaryList?.filter(k => k.type === 'PROJECT_BASIS')?.find(j => j.value === i)?.label, | |||||
fileList: props.detailData?.baseProjBasisFile ? JSON.parse(file)[index] : [], | |||||
value: i | |||||
} | |||||
}) | |||||
}) | |||||
</script> | |||||
<template> | |||||
<el-descriptions :column="2" border> | |||||
<el-descriptions-item label="发改编码"> | |||||
{{ detailData?.baseDevelopCode ||'-' }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="财政编码"> | |||||
{{ detailData?.setProjCodeFinan ||'-' }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="项目起止时间"> | |||||
<span v-if="detailData?.baseProjStartTime&&detailData?.baseProjEndTime">{{ detailData?.baseProjStartTime?.split(' ')[0] }} ~ {{ detailData?.baseProjEndTime?.split(' ')[0] }}</span> | |||||
<span v-else>-</span> | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="预算年度"> | |||||
{{ detailData?.baseProjSetYear ||'-' }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="项目总投资"> | |||||
{{ detailData?.baseProjTotalAmount ||'-' }}万元 | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="申报年度预算"> | |||||
{{ detailData?.baseProjDeclAmount ||'-' }}万元 | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="建设层级"> | |||||
{{ dictionaryList?.filter(i => i.type === 'BUILD_LEVEL').find(i=>i.value===detailData?.baseProjConsClass)?.label ||'-' }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item v-if="!(basicInfoData?.baseConstructionType?.split(';')?.includes('03')&&!basicInfoData?.baseConstructionType?.split(';')?.includes('01'))" label="贯通层级"> | |||||
{{ dictionaryList?.filter(i => i.type === 'LINK_UP_LEVEL').find(i=>i.value===detailData?.baseLowestLevel)?.label ||'-' }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="历年项目名称" :span="2"> | |||||
<span v-if="detailData.missing">缺失</span> | |||||
<table-list | |||||
v-else | |||||
:pagination="false" | |||||
style="width: 100%" | |||||
:column="column" | |||||
:data="detailData.baseHistorProjs" | |||||
:empty-temp="false" | |||||
/> | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="预算来源" :span="2"> | |||||
{{ detailData?.baseProjAmountOri?.split(';').map(i=>dictionaryList?.filter(j => j.type === 'BUDGET_SOURCE').find(k=>k.value===i)?.label).join('、') ||'-' }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="预算来源说明" :span="2"> | |||||
{{ detailData?.baseBasisAmountOri ||'-' }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="立项依据" :span="2"> | |||||
<table-list | |||||
ref="tableListRef" | |||||
:pagination="false" | |||||
style="width: 100%" | |||||
:column="buildBasisColumn" | |||||
:data="buildBasisTableData" | |||||
> | |||||
<template #fileName="{scope}"> | |||||
{{ scope.row.fileList[0].originalFileName }} | |||||
</template> | |||||
<template #action="{scope}"> | |||||
<p v-for="(file,fileIndex) in scope.row.fileList" :key="fileIndex" class="mb-4"> | |||||
<accessory :file-name="file.originalFileName" :file-id="file.id" /> | |||||
</p> | |||||
</template> | |||||
</table-list> | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="立项依据说明" :span="2"> | |||||
{{ detailData?.baseBasisEstablish ||'-' }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="项目概述" :span="2"> | |||||
{{ detailData?.baseProjIntro ||'-' }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="项目内容与预期成效" :span="2"> | |||||
<table-list | |||||
:pagination="false" | |||||
style="width: 100%" | |||||
:column="column1" | |||||
:data="detailData?.beseExpectedResults&&JSON.parse(detailData?.beseExpectedResults)" | |||||
:empty-temp="false" | |||||
/> | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="项目申报书" :span="2"> | |||||
<template v-if="detailData?.baseProjApplyFile&&JSON.parse(detailData?.baseProjApplyFile)?.length"> | |||||
<p v-for="(file,fileIndex) in detailData?.baseProjApplyFile&&JSON.parse(detailData?.baseProjApplyFile)" :key="fileIndex" class="mb-4"> | |||||
<accessory :file-name="file.originalFileName" :file-id="file.id" /> | |||||
</p> | |||||
</template> | |||||
<span v-else>-</span> | |||||
</el-descriptions-item> | |||||
<el-descriptions-item v-if="basicInfoData?.baseProjType==='01'||basicInfoData?.baseProjType==='02'" label="可行性研究报告" :span="2"> | |||||
<template v-if="detailData?.baseResearchReportFile&&JSON.parse(detailData?.baseResearchReportFile)?.length"> | |||||
<p v-for="(file,fileIndex) in detailData?.baseResearchReportFile&&JSON.parse(detailData?.baseResearchReportFile)" :key="fileIndex" class="mb-4"> | |||||
<accessory :file-name="file.originalFileName" :file-id="file.id" /> | |||||
</p> | |||||
</template> | |||||
<span v-else>-</span> | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="其他附件" :span="2"> | |||||
<template v-if="detailData?.baseProjOtherFile&&JSON.parse(detailData?.baseProjOtherFile)?.length"> | |||||
<p v-for="(file,fileIndex) in detailData?.baseProjOtherFile&&JSON.parse(detailData?.baseProjOtherFile)" :key="fileIndex" class="mb-4"> | |||||
<accessory :file-name="file.originalFileName" :file-id="file.id" /> | |||||
</p> | |||||
</template> | |||||
<span v-else>-</span> | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="备注" :span="2"> | |||||
{{ detailData?.baseProjRemark ||'-' }} | |||||
</el-descriptions-item> | |||||
</el-descriptions> | |||||
</template> |
@@ -0,0 +1,72 @@ | |||||
<script setup name="basicInfo"> | |||||
import store from '@/store' | |||||
const { projectTypeOptions } = store.dictStore.globalDicts || {} | |||||
defineProps({ | |||||
detailData: { | |||||
type: Object, | |||||
default: () => {} | |||||
}, | |||||
dictionaryList: Array, | |||||
templateTypeListData: Array | |||||
}) | |||||
</script> | |||||
<template> | |||||
<el-descriptions :column="2" border> | |||||
<!-- <el-descriptions-item label="是否涉密项目">--> | |||||
<!-- {{ dictionaryList?.filter(i => i.type === 'CLASSIFIED').find(i=>i.value===detailData?.baseProjIsConfidentiality)?.label ||'-' }}--> | |||||
<!-- </el-descriptions-item>--> | |||||
<el-descriptions-item label="项目是否归集省里" span="2"> | |||||
{{ detailData?.push?'是':'否' }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="项目名称" span="2"> | |||||
{{ detailData?.baseProjName ||'-' }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="项目类型"> | |||||
{{ detailData?.baseProjType&&projectTypeOptions[detailData?.baseProjType]||'-' }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="内容类别"> | |||||
{{ detailData?.baseConstructionType?.split(';').map(i=>dictionaryList?.filter(j => j.type === 'CONTENT_TYPE').find(k=>k.value===i)?.label).join('、') ||'-' }} | |||||
</el-descriptions-item> | |||||
<!-- <el-descriptions-item label="项目状态">--> | |||||
<!-- {{ dictionaryList?.filter(i => i.type === 'PROJECT_STATUS').find(i=>i.value===detailData?.baseProjSetProg)?.label ||'-' }}--> | |||||
<!-- </el-descriptions-item>--> | |||||
<el-descriptions-item label="上级主管单位类型"> | |||||
{{ detailData?.baseProvManDeprtType===1?'省级':detailData?.baseProvManDeprtType===2?'非省级':'-' }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="上级主管单位"> | |||||
{{ detailData?.baseProvManDeprt ||'-' }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="本级主管单位"> | |||||
{{ detailData?.baseManDeprt ||'-' }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="本级主管单位统一社会信用代码"> | |||||
{{ detailData?.baseManDepartUsci ||'-' }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="建设单位"> | |||||
{{ detailData?.baseBuildDeprt ||'-' }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="建设单位统一信用代码"> | |||||
{{ detailData?.baseBuildDepartUsci ||'-' }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="项目负责人"> | |||||
{{ detailData?.baseProjPrincipal ||'-' }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="负责人手机号码"> | |||||
{{ detailData?.baseProjPrincipalCall ||'-' }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="项目联系人"> | |||||
{{ detailData?.baseProjContacts ||'-' }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="联系人手机号码"> | |||||
{{ detailData?.baseProjContactsCall ||'-' }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="系统定位" :span="2"> | |||||
{{ detailData?.systemPosition ||'-' }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="绩效评价类型" :span="2"> | |||||
{{ templateTypeListData?.find(i=>i.id===detailData?.templateType)?.name||"-" }} | |||||
</el-descriptions-item> | |||||
</el-descriptions> | |||||
</template> |
@@ -0,0 +1,59 @@ | |||||
<script setup name="coreBusiness"> | |||||
import { onMounted, ref } from 'vue' | |||||
import { storeToRefs } from 'pinia' | |||||
import store from '@/store' | |||||
const userInfo = storeToRefs(store.userStore).userInfo, | |||||
props = defineProps({ | |||||
detailData: { | |||||
type: Object, | |||||
default: () => {} | |||||
} | |||||
}), | |||||
column = [ | |||||
{ | |||||
label: '序号', | |||||
type: 'index', | |||||
width: 60 | |||||
}, | |||||
// { | |||||
// label: '业务编号', | |||||
// key: 'oid', | |||||
// prop: 'oid' | |||||
// }, | |||||
{ | |||||
label: '业务名称', | |||||
key: 'matterName', | |||||
prop: 'matterName' | |||||
}, | |||||
{ | |||||
label: '所属单位', | |||||
key: 'orgName', | |||||
prop: 'orgName' | |||||
} | |||||
], | |||||
data = ref([]) | |||||
onMounted(async () => { | |||||
data.value = props?.detailData?.baseCoreBusinessCode?.split(';')?.map((i, k) => { | |||||
return { | |||||
oid: i, | |||||
matterName: props?.detailData?.baseCoreBusiness?.split(';')[k], | |||||
orgName: userInfo.value.empPosUnitName | |||||
} | |||||
}) || [] | |||||
}) | |||||
</script> | |||||
<template> | |||||
<el-descriptions :column="2" border> | |||||
<el-descriptions-item label="核心业务"> | |||||
<table-list | |||||
:pagination="false" | |||||
style="width: 100%" | |||||
:column="column" | |||||
:data="data" | |||||
:empty-temp="false" | |||||
/> | |||||
</el-descriptions-item> | |||||
</el-descriptions> | |||||
</template> |
@@ -0,0 +1,139 @@ | |||||
<script setup name="empMaterials"> | |||||
import Accessory from '@/components/accessory/index.vue' | |||||
defineProps({ | |||||
detailData: { | |||||
type: Object, | |||||
default: () => {} | |||||
}, | |||||
basicInfoData: { | |||||
type: Object | |||||
}, | |||||
approvalInfoData: { | |||||
type: Object | |||||
}, | |||||
baseProjSetYear: { | |||||
type: String, | |||||
default: '' | |||||
} | |||||
}) | |||||
const column1 = [ | |||||
{ | |||||
label: '核心业务', | |||||
prop: 'businessName', | |||||
key: 'businessName' | |||||
}, | |||||
{ | |||||
label: '实际成效指标', | |||||
prop: 'name', | |||||
key: 'name' | |||||
}, | |||||
{ | |||||
label: '数值', | |||||
prop: 'nums', | |||||
key: 'nums' | |||||
}, | |||||
{ | |||||
label: '单位', | |||||
prop: 'unit', | |||||
key: 'unit' | |||||
} | |||||
] | |||||
</script> | |||||
<template> | |||||
<el-descriptions :column="2" border> | |||||
<el-descriptions-item label="是否完成日志数据归集" :span="2"> | |||||
{{ detailData.baseLogAggregation==='1'?'是':'否' }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="实际成效指标" :span="2"> | |||||
<table-list | |||||
:pagination="false" | |||||
style="width: 100%" | |||||
:column="column1" | |||||
:data="detailData.baseBusinessMetrics&&JSON.parse(detailData.baseBusinessMetrics)||[]" | |||||
:empty-temp="false" | |||||
/> | |||||
</el-descriptions-item> | |||||
<el-descriptions-item v-if="(['05','06','07','00'].includes(basicInfoData?.baseProjSetProg)&&basicInfoData?.baseConstructionType?.includes('01'))||!basicInfoData?.baseConstructionType?.includes('01')" label="信息安全等级保护测评报告" :span="2"> | |||||
<template v-if="detailData?.baseInforLevelFile&&JSON.parse(detailData?.baseInforLevelFile)?.length"> | |||||
<p v-for="(file,fileIndex) in detailData?.baseInforLevelFile&&JSON.parse(detailData?.baseInforLevelFile)" :key="fileIndex" class="mb-4"> | |||||
<accessory :file-name="file.originalFileName" :file-id="file.id" /> | |||||
</p> | |||||
</template> | |||||
<span v-else>-</span> | |||||
</el-descriptions-item> | |||||
<el-descriptions-item v-if="!['01','02','03'].includes(basicInfoData?.baseProjSetProg)||baseProjSetYear*1<2023" label="商业密码应用评估报告" :span="2"> | |||||
<template v-if="detailData?.basePasswAssessFile&&JSON.parse(detailData?.basePasswAssessFile)?.length"> | |||||
<p v-for="(file,fileIndex) in detailData?.basePasswAssessFile&&JSON.parse(detailData?.basePasswAssessFile)" :key="fileIndex" class="mb-4"> | |||||
<accessory :file-name="file.originalFileName" :file-id="file.id" /> | |||||
</p> | |||||
</template> | |||||
<span v-else>-</span> | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="第三方验收测试报告" :span="2"> | |||||
<template v-if="detailData?.baseThirdAcceptFile&&JSON.parse(detailData?.baseThirdAcceptFile)?.length"> | |||||
<p v-for="(file,fileIndex) in detailData?.baseThirdAcceptFile&&JSON.parse(detailData?.baseThirdAcceptFile)" :key="fileIndex" class="mb-4"> | |||||
<accessory :file-name="file.originalFileName" :file-id="file.id" /> | |||||
</p> | |||||
</template> | |||||
<span v-else>-</span> | |||||
</el-descriptions-item> | |||||
<el-descriptions-item v-if="!['01','02','03','04'].includes(basicInfoData?.baseProjSetProg)||baseProjSetYear*1<2023" label="用户使用报告" :span="2"> | |||||
<template v-if="detailData?.baseUserConsFile&&JSON.parse(detailData?.baseUserConsFile)?.length"> | |||||
<p v-for="(file,fileIndex) in detailData?.baseUserConsFile&&JSON.parse(detailData?.baseUserConsFile)" :key="fileIndex" class="mb-4"> | |||||
<accessory :file-name="file.originalFileName" :file-id="file.id" /> | |||||
</p> | |||||
</template> | |||||
<span v-else>-</span> | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="监理总结报告" :span="2"> | |||||
<template v-if="detailData?.baseEstaSummFile&&JSON.parse(detailData?.baseEstaSummFile)?.length"> | |||||
<p v-for="(file,fileIndex) in detailData?.baseEstaSummFile&&JSON.parse(detailData?.baseEstaSummFile)" :key="fileIndex" class="mb-4"> | |||||
<accessory :file-name="file.originalFileName" :file-id="file.id" /> | |||||
</p> | |||||
</template> | |||||
<span v-else>-</span> | |||||
</el-descriptions-item> | |||||
<el-descriptions-item v-if="!['01','02','03','04'].includes(basicInfoData?.baseProjSetProg)||baseProjSetYear*1<2023" label="运维总结报告" :span="2"> | |||||
<template v-if="detailData?.baseOperatMaintenSummFile&&JSON.parse(detailData?.baseOperatMaintenSummFile)?.length"> | |||||
<p v-for="(file,fileIndex) in detailData?.baseOperatMaintenSummFile&&JSON.parse(detailData?.baseOperatMaintenSummFile)" :key="fileIndex" class="mb-4"> | |||||
<accessory :file-name="file.originalFileName" :file-id="file.id" /> | |||||
</p> | |||||
</template> | |||||
<span v-else>-</span> | |||||
</el-descriptions-item> | |||||
<el-descriptions-item v-if="basicInfoData?.baseProjSetProg==='07'" label="终验意见" :span="2"> | |||||
<template v-if="detailData?.baseFinalExpertOpinionFile&&JSON.parse(detailData?.baseFinalExpertOpinionFile)?.length"> | |||||
<p v-for="(file,fileIndex) in detailData?.baseFinalExpertOpinionFile&&JSON.parse(detailData?.baseFinalExpertOpinionFile)" :key="fileIndex" class="mb-4"> | |||||
<accessory :file-name="file.originalFileName" :file-id="file.id" /> | |||||
</p> | |||||
</template> | |||||
<span v-else>-</span> | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="项目延期申请表" :span="2"> | |||||
<template v-if="detailData?.baseEngineerPostpoFile&&JSON.parse(detailData?.baseEngineerPostpoFile)?.length"> | |||||
<p v-for="(file,fileIndex) in detailData?.baseEngineerPostpoFile&&JSON.parse(detailData?.baseEngineerPostpoFile)" :key="fileIndex" class="mb-4"> | |||||
<accessory :file-name="file.originalFileName" :file-id="file.id" /> | |||||
</p> | |||||
</template> | |||||
<span v-else>-</span> | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="变更报告" :span="2"> | |||||
<template v-if="detailData?.baseEngineerAlterFile&&JSON.parse(detailData?.baseEngineerAlterFile)?.length"> | |||||
<p v-for="(file,fileIndex) in detailData?.baseEngineerAlterFile&&JSON.parse(detailData?.baseEngineerAlterFile)" :key="fileIndex" class="mb-4"> | |||||
<accessory :file-name="file.originalFileName" :file-id="file.id" /> | |||||
</p> | |||||
</template> | |||||
<span v-else>-</span> | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="变更批复文件" :span="2"> | |||||
<template v-if="detailData?.baseChanFile&&JSON.parse(detailData?.baseChanFile)?.length"> | |||||
<p v-for="(file,fileIndex) in detailData?.baseChanFile&&JSON.parse(detailData?.baseChanFile)" :key="fileIndex" class="mb-4"> | |||||
<accessory :file-name="file.originalFileName" :file-id="file.id" /> | |||||
</p> | |||||
</template> | |||||
<span v-else>-</span> | |||||
</el-descriptions-item> | |||||
</el-descriptions> | |||||
</template> |
@@ -0,0 +1,77 @@ | |||||
<script setup name="projectApprovalInfo"> | |||||
import Accessory from '@/components/accessory/index.vue' | |||||
defineProps({ | |||||
detailData: { | |||||
type: Object, | |||||
default: () => {} | |||||
}, | |||||
basicInfoData: { | |||||
type: Object | |||||
}, | |||||
dictionaryList: Array | |||||
}) | |||||
</script> | |||||
<template> | |||||
<el-descriptions :column="2" border> | |||||
<el-descriptions-item v-if="basicInfoData?.baseProjSetProg!=='01'" label="评审结果"> | |||||
{{ dictionaryList?.filter(i => i.type === 'REVIEW_RESULTS').find(i=>i.value===detailData?.baseReviewResults)?.label ||'-' }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item v-if="basicInfoData?.baseProjIsConfidentiality === '01'&&!['01','02','03'].includes(basicInfoData?.baseProjSetProg)" label="等保定级"> | |||||
{{ dictionaryList?.filter(i => i.type === 'EQUAL_PROTECTION_RATING').find(i=>i.value===detailData?.equalProtectionLevel)?.label ||'-' }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item v-if="basicInfoData?.baseProjSetProg!=='01'" label="评审意见" :span="2"> | |||||
{{ detailData?.baseReviewOpinion||'-' }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item v-if="basicInfoData?.baseProjSetProg!=='01'" label="评审意见附件" :span="2"> | |||||
<template v-if="detailData?.baseReviewCommentsFile&&JSON.parse(detailData?.baseReviewCommentsFile)?.length"> | |||||
<p v-for="(file,fileIndex) in detailData?.baseReviewCommentsFile&&JSON.parse(detailData?.baseReviewCommentsFile)" :key="fileIndex" class="mb-4"> | |||||
<accessory :file-name="file.originalFileName" :file-id="file.id" /> | |||||
</p> | |||||
</template> | |||||
<span v-else>-</span> | |||||
</el-descriptions-item> | |||||
<el-descriptions-item v-if="!['01','02','03'].includes(basicInfoData?.baseProjSetProg)" label="立项批复文件" :span="2"> | |||||
<template v-if="detailData?.approvalFile&&JSON.parse(detailData?.approvalFile)?.length"> | |||||
<p v-for="(file,fileIndex) in detailData?.approvalFile&&JSON.parse(detailData?.approvalFile)" :key="fileIndex" class="mb-4"> | |||||
<accessory :file-name="file.originalFileName" :file-id="file.id" /> | |||||
</p> | |||||
</template> | |||||
<span v-else>-</span> | |||||
</el-descriptions-item> | |||||
<el-descriptions-item v-if="!['01','03'].includes(basicInfoData?.baseProjSetProg)" label="建议总投资"> | |||||
{{ detailData?.baseExpertTotalMoney||'-' }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item v-if="!['01','03'].includes(basicInfoData?.baseProjSetProg)" label="建议年度预算"> | |||||
{{ detailData?.baseExpertYearMoney||'-' }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item v-if="!['01','02','03'].includes(basicInfoData?.baseProjSetProg)" label="建议批复总投资"> | |||||
{{ detailData?.baseInitialReviewTotalMoney||'-' }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item v-if="!['01','02','03'].includes(basicInfoData?.baseProjSetProg)" label="建议批复年度预算"> | |||||
{{ detailData?.baseProjReplyAmount||'-' }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item v-if="['05','06','07','00'].includes(basicInfoData?.baseProjSetProg)" label="年度预算下达金额"> | |||||
{{ detailData?.releaseYearMoney||'-' }} | |||||
</el-descriptions-item> | |||||
<template v-if="detailData?.baseProjReplyAmount>=5000&&['04','05','06','07','00'].includes(basicInfoData?.baseProjSetProg)"> | |||||
<el-descriptions-item label="初步设计方案" :span="2"> | |||||
<template v-if="detailData?.preliminaryDesignScheme&&JSON.parse(detailData?.preliminaryDesignScheme)?.length"> | |||||
<p v-for="(file,fileIndex) in detailData?.preliminaryDesignScheme&&JSON.parse(detailData?.preliminaryDesignScheme)" :key="fileIndex" class="mb-4"> | |||||
<accessory :file-name="file.originalFileName" :file-id="file.id" /> | |||||
</p> | |||||
</template> | |||||
<span v-else>-</span> | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="初步设计方案批复函" :span="2"> | |||||
<template v-if="detailData?.preliminaryDesignFile&&JSON.parse(detailData?.preliminaryDesignFile)?.length"> | |||||
<p v-for="(file,fileIndex) in detailData?.preliminaryDesignFile&&JSON.parse(detailData?.preliminaryDesignFile)" :key="fileIndex" class="mb-4"> | |||||
<accessory :file-name="file.originalFileName" :file-id="file.id" /> | |||||
</p> | |||||
</template> | |||||
<span v-else>-</span> | |||||
</el-descriptions-item> | |||||
</template> | |||||
</el-descriptions> | |||||
</template> |
@@ -0,0 +1,94 @@ | |||||
<script setup name="basicInfo"> | |||||
import Accessory from '@/components/accessory/index.vue' | |||||
import NoData from '@/components/noData/index.vue' | |||||
defineProps({ | |||||
detailData: { | |||||
type: Array, | |||||
default: () => [] | |||||
}, | |||||
basicInfoData: { | |||||
type: Object | |||||
}, | |||||
baseProjSetYear: { | |||||
type: String, | |||||
default: '' | |||||
}, | |||||
dictionaryList: { | |||||
type: Array, | |||||
default: () => [] | |||||
} | |||||
}) | |||||
</script> | |||||
<template> | |||||
<template v-if="detailData?.length"> | |||||
<el-descriptions | |||||
v-for="(item,index) in detailData" | |||||
:key="index" | |||||
:column="2" | |||||
border | |||||
class="mb-16" | |||||
> | |||||
<template v-if="['05','06','07','00'].includes(basicInfoData?.baseProjSetProg)"> | |||||
<el-descriptions-item label="标段名称"> | |||||
{{ item?.baseBidName ||'-' }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="采购方式"> | |||||
{{ dictionaryList?.filter(i => i.type === 'PURCHASE_METHOD').find(i=>i.value===item?.baseProjPurchaseWay)?.label ||'-' }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="预算执行确认书编号"> | |||||
{{ item?.basePurchaseCode ||'-' }} | |||||
</el-descriptions-item> | |||||
</template> | |||||
<template v-if="['05','06','07','00'].includes(basicInfoData?.baseProjSetProg)||baseProjSetYear*1<2023"> | |||||
<el-descriptions-item label="采购代理机构"> | |||||
{{ item?.basePurchasingAgencies ||'-' }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="采购代理机构统一社会信用代码"> | |||||
{{ item?.baseUnifiedCreditCode ||'-' }} | |||||
</el-descriptions-item> | |||||
</template> | |||||
<template v-if="['05','06','07','00'].includes(basicInfoData?.baseProjSetProg)"> | |||||
<el-descriptions-item label="中标(成交)时间"> | |||||
{{ item?.baseWinningBidTime ||'-' }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="中标(成交)金额"> | |||||
{{ item?.baseProjPurchaseAmount ||'-' }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="中标(成交)供应商名称"> | |||||
{{ item?.baseConsDeprt ||'-' }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="中标(成交)供应商统一社会信用代码"> | |||||
{{ item?.baseConsDeprtUsci ||'-' }} | |||||
</el-descriptions-item> | |||||
</template> | |||||
<template v-if="['05','06','07','00'].includes(basicInfoData?.baseProjSetProg)||baseProjSetYear*1<2023"> | |||||
<el-descriptions-item label="项目款支付时间"> | |||||
{{ item?.basePaymentTime ||'-' }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="项目款支付金额"> | |||||
{{ item?.paymentProgress ||'-' }}万元 | |||||
</el-descriptions-item> | |||||
</template> | |||||
<template v-if="['05','06','07','00']?.includes(basicInfoData?.baseProjSetProg)"> | |||||
<el-descriptions-item label="招标(采购)文件"> | |||||
<p v-for="(file,fileIndex) in item?.purchaseFile&&JSON.parse(item?.purchaseFile)" :key="fileIndex" class="mb-4"> | |||||
<accessory :file-name="file.originalFileName" :file-id="file.id" /> | |||||
</p> | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="中标(成交)通知"> | |||||
<p v-for="(file,fileIndex) in item?.biddingFile&&JSON.parse(item?.biddingFile)" :key="fileIndex" class="mb-4"> | |||||
<accessory :file-name="file.originalFileName" :file-id="file.id" /> | |||||
</p> | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="采购合同"> | |||||
<p v-for="(file,fileIndex) in item?.purchaseContract&&JSON.parse(item?.purchaseContract)" :key="fileIndex" class="mb-4"> | |||||
<accessory :file-name="file.originalFileName" :file-id="file.id" /> | |||||
</p> | |||||
</el-descriptions-item> | |||||
</template> | |||||
</el-descriptions> | |||||
</template> | |||||
<no-data v-else /> | |||||
</template> |
@@ -0,0 +1,142 @@ | |||||
<script setup name="projectCollectionEnterDetail"> | |||||
import { onMounted, ref } from 'vue' | |||||
import { useRoute } from 'vue-router' | |||||
import BasicInfo from './components/basicInfo.vue' | |||||
import { dictionary } from '@/http/apis/projectCollection/projectCollectionEnter' | |||||
import { detail } from '@/http/apis/declareMange/operationProjectRecord' | |||||
import ApplyInfo from './components/applyInfo.vue' | |||||
import ApplicationInfo from './components/applicationInfo.vue' | |||||
import CoreBusiness from './components/coreBusiness.vue' | |||||
import ProjectApprovalInfo from './components/projectApprovalInfo.vue' | |||||
import EmpMaterials from './components/empMaterials.vue' | |||||
import PurchaseInfo from './components/purchaseInfo.vue' | |||||
import store from '@/store' | |||||
import { templateTypeList } from '@/http/apis/performanceEvaluation/indicatorTemplate' | |||||
const { statusGjOptions } = store.dictStore.globalDicts || {} | |||||
const | |||||
tabList = ref(['项目基本信息', '项目申报信息', '项目关联信息', '核心业务', '项目立项评审信息', '项目采购、资金支付信息', '实施材料信息']), | |||||
activeName = ref('项目基本信息'), | |||||
changeTab = (val) => { | |||||
activeName.value = val | |||||
}, | |||||
route = useRoute(), | |||||
detailData = ref(), | |||||
getDetail = async () => { | |||||
const id = route.query.type === '1' ? route.query.id : route.query.draftId | |||||
const res = await detail(route.query.type, id) | |||||
detailData.value = { | |||||
...res.data, | |||||
apply: { | |||||
...res.data.apply, | |||||
baseHistorProjs: res.data.apply?.baseHistorProjId?.split(';').map((i, k) => { | |||||
return { | |||||
baseProjId: i, | |||||
baseProjName: res.data.apply?.baseHistorProjName.split(';')[k], | |||||
baseProjSetYear: res.data.apply?.baseHistorProjYear.split(';')[k] | |||||
} | |||||
}) || [] | |||||
} | |||||
} | |||||
if ((detailData.value?.baseinfo?.baseConstructionType?.split(';')?.length === 1 && detailData.value?.baseinfo?.baseConstructionType?.split(';').includes('02'))) { | |||||
tabList.value = tabList.value.filter(i => i !== '项目关联信息') | |||||
} | |||||
if (detailData.value?.baseinfo?.baseProjSetProg === '01') { | |||||
tabList.value = tabList.value.filter(i => i !== '项目立项评审信息') | |||||
} | |||||
}, | |||||
dictionaryList = ref([]), | |||||
templateTypeListData = ref(), | |||||
getTemplateTypeList = async () => { | |||||
const res = await templateTypeList() | |||||
templateTypeListData.value = res.data | |||||
} | |||||
onMounted(async () => { | |||||
getTemplateTypeList() | |||||
dictionaryList.value = (await dictionary()).data | |||||
getDetail() | |||||
}) | |||||
</script> | |||||
<template> | |||||
<div class="px-20 pt-10 pb-20 overflow-auto"> | |||||
<el-card shadow="never" class="mb-16"> | |||||
<div class="card-header"> | |||||
<div class="flex justify-between items-center"> | |||||
<div class="flex-1"> | |||||
<p class="font-bold">{{ detailData?.baseinfo?.baseProjName }}</p> | |||||
<div class="mt-8 search"> | |||||
<el-form label-suffix=":"> | |||||
<el-row :gutter="24"> | |||||
<el-col :span="6"> | |||||
<el-form-item label="建设单位">{{ detailData?.baseinfo?.baseBuildDeprt||'-' }}</el-form-item> | |||||
</el-col> | |||||
<el-col :span="6"> | |||||
<el-form-item label="主管单位">{{ detailData?.baseinfo?.baseManDeprt||'-' }}</el-form-item> | |||||
</el-col> | |||||
<el-col :span="6"> | |||||
<el-form-item label="创建时间">{{ detailData?.baseinfo?.createOn||'-' }}</el-form-item> | |||||
</el-col> | |||||
<el-col :span="6"> | |||||
<el-form-item label="更新时间">{{ detailData?.baseinfo?.updateOn||'-' }}</el-form-item> | |||||
</el-col> | |||||
</el-row> | |||||
</el-form> | |||||
</div> | |||||
</div> | |||||
<div class="textRight"> | |||||
<span :class="`text-${statusGjOptions[detailData?.baseinfo?.baseProjSetProg.slice(-1)]?.color}`"> | |||||
{{ dictionaryList?.filter(i => i.type === 'PROJECT_STATUS').find(i=>i.value===detailData?.baseinfo?.baseProjSetProg)?.label ||'-' }} | |||||
</span> | |||||
<p>状态</p> | |||||
</div> | |||||
</div> | |||||
</div> | |||||
</el-card> | |||||
<el-card shadow="never" class="tab-card"> | |||||
<template #header> | |||||
<el-tabs v-model="activeName" @tab-change="changeTab"> | |||||
<el-tab-pane | |||||
v-for="(item,index) in tabList" | |||||
:key="index" | |||||
:label="item" | |||||
:name="item" | |||||
/> | |||||
</el-tabs> | |||||
</template> | |||||
<basic-info | |||||
v-if="activeName==='项目基本信息'" | |||||
:detail-data="detailData?.baseinfo" | |||||
:dictionary-list="dictionaryList" | |||||
:template-type-list-data="templateTypeListData" | |||||
/> | |||||
<apply-info | |||||
v-if="activeName==='项目申报信息'" | |||||
:detail-data="detailData?.apply" | |||||
:dictionary-list="dictionaryList" | |||||
:basic-info-data="detailData?.baseinfo" | |||||
/> | |||||
<application-info v-if="activeName==='项目关联信息'" :detail-data="detailData?.apply" /> | |||||
<core-business v-if="activeName==='核心业务'" :detail-data="detailData?.apply" /> | |||||
<project-approval-info | |||||
v-if="activeName==='项目立项评审信息'" | |||||
:detail-data="detailData?.approve" | |||||
:dictionary-list="dictionaryList" | |||||
:basic-info-data="detailData?.baseinfo" | |||||
/> | |||||
<purchase-info | |||||
v-if="activeName==='项目采购、资金支付信息'" | |||||
:basic-info-data="detailData?.baseinfo" | |||||
:base-proj-set-year="detailData?.apply?.baseProjSetYear" | |||||
:dictionary-list="dictionaryList" | |||||
:detail-data="detailData?.procures" | |||||
/> | |||||
<emp-materials | |||||
v-if="activeName==='实施材料信息'" | |||||
:detail-data="detailData?.mimplement" | |||||
:basic-info-data="detailData?.baseinfo" | |||||
:base-proj-set-year="detailData?.apply?.baseProjSetYear" | |||||
:approval-info-data="detailData?.approve" | |||||
/> | |||||
</el-card> | |||||
</div> | |||||
</template> |
@@ -0,0 +1,201 @@ | |||||
<script setup name="operationProjectRecord"> | |||||
import { getCurrentInstance, onMounted, reactive, ref } from 'vue' | |||||
import { useRouter } from 'vue-router' | |||||
import ElTree from '@/components/elTree/index.vue' | |||||
import { list, del } from '@/http/apis/declareMange/operationProjectRecord' | |||||
import { getIsShowRegionTree, getTreeParams } from '@/utils/getIsShowRegionTree' | |||||
import { storeToRefs } from 'pinia' | |||||
import store from '@/store' | |||||
const | |||||
userInfo = storeToRefs(store.userStore).userInfo, | |||||
{ proxy } = getCurrentInstance(), | |||||
router = useRouter(), | |||||
searchForm = reactive({ | |||||
projectName: undefined, | |||||
buildOrg: undefined | |||||
}), | |||||
tableListRef = ref(), | |||||
total = ref(0), | |||||
// 列表数据 | |||||
column = reactive([ | |||||
{ | |||||
label: '序号', | |||||
type: 'index', | |||||
width: '60' | |||||
}, | |||||
{ | |||||
label: '项目编号', | |||||
key: 'baseProjId', | |||||
prop: 'baseProjId' | |||||
}, | |||||
{ | |||||
label: '项目名称', | |||||
key: 'baseProjName', | |||||
prop: 'baseProjName' | |||||
}, | |||||
{ | |||||
label: '建设单位', | |||||
key: 'baseBuildDeprt', | |||||
prop: 'baseBuildDeprt' | |||||
}, | |||||
{ | |||||
label: '行政区划', | |||||
key: 'baseAreaName', | |||||
prop: 'baseAreaName' | |||||
}, | |||||
{ | |||||
label: '申报金额(万元)', | |||||
key: 'baseProjDeclAmount', | |||||
prop: 'baseProjDeclAmount', | |||||
width: '180' | |||||
}, | |||||
{ | |||||
label: '操作', | |||||
slot: 'action', | |||||
width: '160', | |||||
fixed: 'right' | |||||
} | |||||
]), | |||||
data = ref([]), | |||||
areaCode = ref(), | |||||
getTree = (value) => { | |||||
areaCode.value = value.regionLevel === 3 ? value.regionCode : undefined | |||||
tableListRef.value.pageParams.pageNumber = 1 | |||||
getTableData() | |||||
}, | |||||
activeName = ref('1'), | |||||
changeTab = (val) => { | |||||
activeName.value = val | |||||
reset() | |||||
}, | |||||
getTableData = async (pageParams = tableListRef.value.pageParams) => { | |||||
const res = await list(activeName.value, { | |||||
...pageParams, | |||||
...searchForm, | |||||
regionCode: areaCode.value | |||||
}) | |||||
data.value = res.data.records | |||||
total.value = res.data.total | |||||
}, | |||||
search = () => { | |||||
getTableData() | |||||
}, | |||||
reset = () => { | |||||
searchForm.projectName = undefined | |||||
searchForm.buildOrg = undefined | |||||
tableListRef.value.pageParams.pageNumber = 1 | |||||
tableListRef.value.pageParams.pageSize = 10 | |||||
getTableData() | |||||
}, | |||||
// 删除· | |||||
deleteItem = (data) => { | |||||
proxy.$messageBox | |||||
.confirm('确定要删除该项吗?', '提示!', { | |||||
type: 'warning' | |||||
}) | |||||
.then(async () => { | |||||
await del(activeName.value, activeName.value === '1' ? data.baseProjId : data.draftId) | |||||
proxy.$message.success('删除成功!') | |||||
await getTableData() | |||||
}) | |||||
} | |||||
onMounted(() => { | |||||
if (!getIsShowRegionTree(['SUPER_ADMIN', 'REGION_MANAGER'])) { | |||||
areaCode.value = userInfo.value.regionCode | |||||
getTableData(tableListRef.value.pageParams) | |||||
} | |||||
}) | |||||
</script> | |||||
<template> | |||||
<el-container class="overflow-y-auto"> | |||||
<div class="px-20 pt-10 pb-20 w-full"> | |||||
<el-row> | |||||
<el-col | |||||
v-if="getIsShowRegionTree(['SUPER_ADMIN','REGION_MANAGER'])" | |||||
:span="4" | |||||
class="pr-16" | |||||
> | |||||
<elTree :params="getTreeParams({'SUPER_ADMIN':false,'REGION_MANAGER':false})" @get-tree="getTree" /> | |||||
</el-col> | |||||
<el-col :span="getIsShowRegionTree(['SUPER_ADMIN','REGION_MANAGER'])?20:24"> | |||||
<el-card class="w-full search"> | |||||
<el-form | |||||
:model="searchForm" | |||||
size="small" | |||||
label-suffix=":" | |||||
> | |||||
<el-row | |||||
:gutter="16" | |||||
> | |||||
<el-col :span="8"> | |||||
<el-form-item label="项目名称"> | |||||
<el-input | |||||
v-model="searchForm.projectName" | |||||
placeholder="请输入" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<el-form-item label="项目单位"> | |||||
<el-input | |||||
v-model="searchForm.buildOrg" | |||||
placeholder="请输入" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<el-form-item class="btn"> | |||||
<div class="flex"> | |||||
<el-button | |||||
type="primary" | |||||
@click="search" | |||||
>查询</el-button> | |||||
<el-button | |||||
@click="reset" | |||||
>重置</el-button> | |||||
</div> | |||||
</el-form-item> | |||||
</el-col> | |||||
</el-row> | |||||
</el-form> | |||||
</el-card> | |||||
<el-card class="w-full mt-8 tab-card"> | |||||
<template #header> | |||||
<div class="flex justify-between items-center"> | |||||
<el-tabs v-model="activeName" @tab-change="changeTab"> | |||||
<el-tab-pane label="项目列表" name="1" /> | |||||
<el-tab-pane label="草稿箱" name="2" /> | |||||
</el-tabs> | |||||
<div> | |||||
<el-button | |||||
type="primary" | |||||
size="small" | |||||
icon="Plus" | |||||
@click="router.push({ name: 'operationProjectEdit'})" | |||||
>录入项目</el-button> | |||||
</div> | |||||
</div> | |||||
</template> | |||||
<table-list | |||||
ref="tableListRef" | |||||
:column="column" | |||||
:data="data" | |||||
:total="total" | |||||
@get-table-data="getTableData" | |||||
> | |||||
<template #action="{ scope }"> | |||||
<a @click="$router.push({name:'operationProjectRecordDetail', query: { id: scope.row.baseProjId,draftId: scope.row.draftId,type:activeName }})">查看</a> | |||||
<a @click="$router.push({ name: 'operationProjectEdit', query: { id: scope.row.baseProjId, draftId: scope.row.draftId, type: activeName }})">编辑</a> | |||||
<a class="text-danger" @click="deleteItem(scope.row)">删除</a> | |||||
</template> | |||||
</table-list> | |||||
</el-card> | |||||
</el-col> | |||||
</el-row> | |||||
</div> | |||||
</el-container> | |||||
</template> | |||||
<style lang='less' scoped> | |||||
</style> |
@@ -0,0 +1,261 @@ | |||||
<script name="projectCollectionEnterBasicInfo" setup> | |||||
import { onMounted, ref, watch } from 'vue' | |||||
import { applicationList } from '@/http/apis/declareMange' | |||||
import store from '@/store' | |||||
import { storeToRefs } from 'pinia' | |||||
import { useRoute } from 'vue-router' | |||||
const userInfo = storeToRefs(store.userStore).userInfo, | |||||
route = useRoute(), | |||||
props = defineProps({ | |||||
detail: { | |||||
type: Object | |||||
}, | |||||
basicInfoData: { | |||||
type: Object | |||||
} | |||||
}), | |||||
{ | |||||
accountAppNameOption, | |||||
domainBrainAccountOptions | |||||
} = store.dictStore.globalDicts || {}, | |||||
formRef = ref(), | |||||
currentRules = ref(), | |||||
formData = ref({ | |||||
applications: [] | |||||
}), | |||||
column = [ | |||||
{ | |||||
label: '序号', | |||||
type: 'index', | |||||
width: 60 | |||||
}, | |||||
{ | |||||
label: '关联IRS应用名称', | |||||
slot: 'application', | |||||
key: 'application' | |||||
}, | |||||
{ | |||||
label: 'IRS应用编码', | |||||
slot: 'applicationCode', | |||||
key: 'applicationCode' | |||||
}, | |||||
{ | |||||
label: '一本账重大应用名称', | |||||
slot: 'baseAccountAppName', | |||||
key: 'baseAccountAppName' | |||||
}, | |||||
{ | |||||
label: '"领域大脑"一本账名称', | |||||
slot: 'baseBrainName', | |||||
key: 'baseBrainName' | |||||
}, | |||||
{ | |||||
label: '操作', | |||||
slot: 'action', | |||||
key: 'action' | |||||
} | |||||
], | |||||
add = () => { | |||||
formData.value.applications.push({ | |||||
application: undefined | |||||
}) | |||||
}, | |||||
del = (index) => { | |||||
formData.value.applications.splice(index, 1) | |||||
}, | |||||
appList = ref([]) | |||||
defineExpose({ formRef, formData }) | |||||
watch(() => props.basicInfoData, val => { | |||||
if (val?.baseProjIsConfidentiality === '02' || val?.baseProjSetProg === '00') { | |||||
currentRules.value = {} | |||||
} else { | |||||
currentRules.value = { | |||||
applications: [{ required: true, message: '请至少关联一个应用' }] | |||||
} | |||||
} | |||||
formRef.value?.clearValidate() | |||||
}, { deep: true, immediate: true }) | |||||
onMounted(async () => { | |||||
if (!route.query.id) { | |||||
const res = await applicationList({ areaCode: userInfo.value.regionCode }) | |||||
appList.value = res.data | |||||
} | |||||
}) | |||||
watch(() => props.detail, async val => { | |||||
if (val) { | |||||
const res = await applicationList({ areaCode: userInfo.value.regionCode }) | |||||
appList.value = res.data | |||||
formData.value = { | |||||
applications: val.apply.baseProjSysCode?.split(';')?.map((i, k) => { | |||||
return { | |||||
application: appList.value?.find(j => j.applicationCode === i) || { applicationCode: i, applicationName: val.apply?.baseProjSys?.split(';')[k] || '' }, | |||||
baseAccountAppName: val.apply?.baseAccountAppName?.split(';')[k] || '', | |||||
baseBrainName: val.apply?.baseBrainName?.split(';')[k] || '' | |||||
} | |||||
}) || [] | |||||
} | |||||
} | |||||
}) | |||||
</script> | |||||
<template> | |||||
<el-form | |||||
ref="formRef" | |||||
:model="formData" | |||||
:rules="currentRules" | |||||
label-position="top" | |||||
label-suffix=":" | |||||
scroll-to-error | |||||
:validate-on-rule-change="false" | |||||
> | |||||
<el-row :gutter="40"> | |||||
<el-col :span="24"> | |||||
<el-form-item | |||||
v-if="basicInfoData?.baseConstructionType?.includes('01')&&!(basicInfoData?.baseProjType==='01'&&(basicInfoData?.baseProjSetProg==='01'||basicInfoData?.baseProjSetProg==='02'))" | |||||
key="applications1" | |||||
label="关联IRS应用名称" | |||||
prop="applications" | |||||
> | |||||
<p class="text-right w-full mb-8"> | |||||
<el-button type="primary" @click="add">添加关联应用</el-button> | |||||
</p> | |||||
<table-list | |||||
:pagination="false" | |||||
style="width: 100%" | |||||
:column="column" | |||||
:data="formData.applications" | |||||
:empty-temp="false" | |||||
> | |||||
<template #application="{scope}"> | |||||
<el-form-item v-if="scope.$index>=0" :prop="`applications[${scope.$index}].application`" :rules="[{required:true,message:' '}]"> | |||||
<el-select | |||||
v-model="formData.applications[scope.$index].application" | |||||
class="w-full" | |||||
placeholder="请选择" | |||||
value-key="applicationCode" | |||||
filterable | |||||
> | |||||
<el-option | |||||
v-for="(item, index) in appList" | |||||
:key="index" | |||||
:label="item.applicationName" | |||||
:value="item" | |||||
/> | |||||
</el-select> | |||||
</el-form-item> | |||||
</template> | |||||
<template #applicationCode="{scope}"> | |||||
<el-form-item> | |||||
<el-input disabled :model-value="scope.row.application?.applicationCode" /> | |||||
</el-form-item> | |||||
</template> | |||||
<template #baseAccountAppName="{scope}"> | |||||
<el-form-item | |||||
v-if="scope.$index>=0" | |||||
:prop="`applications[${scope.$index}].baseAccountAppName`" | |||||
> | |||||
<el-select v-model="scope.row.baseAccountAppName"> | |||||
<el-option | |||||
v-for="(item,index) in accountAppNameOption" | |||||
:key="index" | |||||
:label="item" | |||||
:value="item" | |||||
/> | |||||
</el-select> | |||||
</el-form-item> | |||||
</template> | |||||
<template #baseBrainName="{scope}"> | |||||
<el-form-item | |||||
v-if="scope.$index>=0" | |||||
:prop="`applications[${scope.$index}].baseBrainName`" | |||||
> | |||||
<el-select v-model="scope.row.baseBrainName"> | |||||
<el-option | |||||
v-for="(item,index) in domainBrainAccountOptions" | |||||
:key="index" | |||||
:label="item" | |||||
:value="item" | |||||
/> | |||||
</el-select> | |||||
</el-form-item> | |||||
</template> | |||||
<template #action="{scope}"> | |||||
<a class="text-danger" @click="del(scope.$index)">删除</a> | |||||
</template> | |||||
</table-list> | |||||
</el-form-item> | |||||
<el-form-item v-else key="applications2" label="关联IRS应用名称"> | |||||
<p class="text-right w-full mb-8"> | |||||
<el-button type="primary" @click="add">添加关联应用</el-button> | |||||
</p> | |||||
<table-list | |||||
:pagination="false" | |||||
style="width: 100%" | |||||
:column="column" | |||||
:data="formData.applications" | |||||
:empty-temp="false" | |||||
> | |||||
<template #application="{scope}"> | |||||
<el-form-item v-if="scope.$index>=0" :prop="`applications[${scope.$index}].application`" :rules="[{required:true,message:' '}]"> | |||||
<el-select | |||||
v-model="formData.applications[scope.$index].application" | |||||
class="w-full" | |||||
placeholder="请选择" | |||||
value-key="applicationCode" | |||||
filterable | |||||
> | |||||
<el-option | |||||
v-for="(item, index) in appList" | |||||
:key="index" | |||||
:label="item.applicationName" | |||||
:value="item" | |||||
/> | |||||
</el-select> | |||||
</el-form-item> | |||||
</template> | |||||
<template #applicationCode="{scope}"> | |||||
<el-form-item> | |||||
<el-input disabled :model-value="scope.row.application?.applicationCode" /> | |||||
</el-form-item> | |||||
</template> | |||||
<template #baseAccountAppName="{scope}"> | |||||
<el-form-item | |||||
v-if="scope.$index>=0" | |||||
:prop="`applications[${scope.$index}].baseAccountAppName`" | |||||
> | |||||
<el-select v-model="scope.row.baseAccountAppName"> | |||||
<el-option | |||||
v-for="(item,index) in accountAppNameOption" | |||||
:key="index" | |||||
:label="item" | |||||
:value="item" | |||||
/> | |||||
</el-select> | |||||
</el-form-item> | |||||
</template> | |||||
<template #baseBrainName="{scope}"> | |||||
<el-form-item | |||||
v-if="scope.$index>=0" | |||||
:prop="`applications[${scope.$index}].baseBrainName`" | |||||
> | |||||
<el-select v-model="scope.row.baseBrainName"> | |||||
<el-option | |||||
v-for="(item,index) in domainBrainAccountOptions" | |||||
:key="index" | |||||
:label="item" | |||||
:value="item" | |||||
/> | |||||
</el-select> | |||||
</el-form-item> | |||||
</template> | |||||
<template #action="{scope}"> | |||||
<a class="text-danger" @click="del(scope.$index)">删除</a> | |||||
</template> | |||||
</table-list> | |||||
</el-form-item> | |||||
</el-col> | |||||
</el-row> | |||||
</el-form> | |||||
</template> |
@@ -0,0 +1,425 @@ | |||||
<script name="projectCollectionEnterBasicInfo" setup> | |||||
import { computed, onMounted, reactive, ref, watch } from 'vue' | |||||
import { districtList, getOrganizationByCode } from '@/http/apis/commonApi' | |||||
import OrgTree from '@/components/orgTree/index.vue' | |||||
import UserDialog from '@/pages/projectCollection/projectCollectionEnter/components/userDialog.vue' | |||||
import { storeToRefs } from 'pinia' | |||||
import store from '@/store' | |||||
import LineOrgDialog from '@/pages/projectCollection/projectCollectionEnter/components/lineOrgDialog.vue' | |||||
import { templateTypePage } from '@/http/apis/performanceEvaluation/indicatorTemplate' | |||||
const { projectOpeOptions } = | |||||
store.dictStore.globalDicts || {} | |||||
const props = defineProps({ | |||||
detail: { | |||||
type: Object | |||||
}, | |||||
dictionaryList: { | |||||
type: Array, | |||||
default: () => [] | |||||
} | |||||
}), | |||||
userInfo = storeToRefs(store.userStore).userInfo || {}, | |||||
formRef = ref(), | |||||
formData = ref({ | |||||
baseProjIsConfidentiality: '01', | |||||
// baseProjSetProg: '07', | |||||
push: true | |||||
// baseProjType: '04' | |||||
}), | |||||
userValidator = (rule, value, callback) => { | |||||
if (!value) callback() | |||||
if (formData.value.baseProjPrincipal === formData.value.baseProjContacts && formData.value.baseProjPrincipalCall === formData.value.baseProjContactsCall) { | |||||
callback('项目负责人与项目联系人不能相同') | |||||
} else { | |||||
callback() | |||||
} | |||||
}, | |||||
currentRules = computed(() => { | |||||
if (formData.value.baseProjIsConfidentiality === '02') { | |||||
return { | |||||
baseProjIsConfidentiality: [{ required: true, message: '请选择是否涉密项目' }], | |||||
baseProjName: [{ required: true, message: '请填写项目名称', trigger: 'blur' }] | |||||
} | |||||
} else { | |||||
return { | |||||
push: [{ required: true, message: '请选择是否归集省里', type: Boolean }], | |||||
baseProjIsConfidentiality: [{ required: true, message: '请选择是否涉密项目' }], | |||||
baseProjName: [{ required: true, message: '请填写项目名称' }], | |||||
baseProjType: [{ required: true, message: '请选择项目类型' }], | |||||
baseArea: [{ required: true, message: '请选择所属区划' }], | |||||
baseConstructionType: [{ required: true, message: '请选择内容类别' }], | |||||
baseProjSetProg: [{ required: true, message: '请选择项目状态' }], | |||||
baseProvManDeprtType: [{ required: true, message: '请选择上级主管单位类型' }], | |||||
baseProvManDeprt: [{ required: true, message: '请选择上级主管单位' }], | |||||
baseManDeprt: [{ required: true, message: '请选择本级主管单位' }], | |||||
baseManDepartUsci: [{ required: true, message: '请填写本级主管单位统一社会信用代码' }], | |||||
baseBuildDeprt: [{ required: true, message: '请填写建设单位' }], | |||||
baseBuildDepartUsci: [{ required: true, message: '请填写建设单位统一信用代码' }], | |||||
baseProjPrincipal: [{ required: true, message: '请选择项目负责人' }, { validator: userValidator }], | |||||
baseProjPrincipalCall: [{ required: true, message: '请选择项目负责人' }], | |||||
baseProjContacts: [{ required: true, message: '请选择项目联系人' }, { validator: userValidator }], | |||||
baseProjContactsCall: [{ required: true, message: '请选择联系人手机号码' }], | |||||
systemPosition: [{ required: true, message: '请填写系统定位' }], | |||||
templateType: [{ required: true, message: '请选择绩效评价类型' }] | |||||
} | |||||
} | |||||
}), | |||||
isDisabledCreditCode = ref({}), | |||||
getCode = async (name, code) => { | |||||
const res = await getOrganizationByCode(code || userInfo.value.empPosUnitCode) | |||||
isDisabledCreditCode.value[name] = !!res.data.unifiedSocialCreditCode | |||||
formData.value[name] = res.data.unifiedSocialCreditCode || formData.value[name] | |||||
}, | |||||
regionTree = ref([]), | |||||
// 单位选择 | |||||
orgProps = reactive({ | |||||
field: undefined, | |||||
unitVisible: false, | |||||
data: undefined, | |||||
title: undefined, | |||||
type: undefined, | |||||
params: undefined | |||||
}), | |||||
showOrgTree = (fieldName) => { | |||||
orgProps.fieldName = fieldName | |||||
orgProps.unitVisible = true | |||||
orgProps.title = '选择单位' | |||||
orgProps.type = 'UNIT' | |||||
orgProps.showCheckbox = true | |||||
orgProps.defaultProps = { | |||||
children: 'children', | |||||
label: 'title', | |||||
value: 'key', | |||||
isLeaf: 'isLeaf' | |||||
} | |||||
orgProps.params = { | |||||
onlyUnit: true | |||||
} | |||||
orgProps.data = formData.value[`${fieldName}Ding`] ? [{ | |||||
key: formData.value[`${fieldName}Ding`], | |||||
title: formData.value[fieldName] | |||||
}] : [] | |||||
console.log(orgProps.data) | |||||
}, | |||||
closeOrg = () => { | |||||
orgProps.unitVisible = false | |||||
}, | |||||
getOrgData = (data) => { | |||||
formData.value[orgProps.fieldName + 'Ding'] = data?.[0].key || undefined | |||||
formData.value[orgProps.fieldName] = data?.[0].title || undefined | |||||
if (orgProps.fieldName === 'baseManDeprt' || orgProps.fieldName === 'baseBuildDeprt') { getCode(orgProps.fieldName === 'baseManDeprt' ? 'baseManDepartUsci' : 'baseBuildDepartUsci', formData.value[orgProps.fieldName + 'Ding']) } | |||||
}, | |||||
// 选择负责人、联系人 | |||||
userDialogData = reactive({ | |||||
visible: false, | |||||
params: {} | |||||
}), | |||||
filedName = ref(), | |||||
filedPhone = ref(), | |||||
showUserDialog = (name, phone) => { | |||||
userDialogData.visible = true | |||||
filedName.value = name | |||||
filedPhone.value = phone | |||||
}, | |||||
getUserData = (data) => { | |||||
formData.value[filedName.value] = data.name | |||||
formData.value[filedPhone.value] = data.phoneNo | |||||
}, | |||||
// 上级主管单位类型 | |||||
changeBaseProvManDeprtType = (val, data) => { | |||||
formData.value.baseProvManDeprtDing = '' | |||||
formData.value.baseProvManDeprt = '' | |||||
}, | |||||
lineOrgDialogData = reactive({ | |||||
visible: false, | |||||
data: undefined | |||||
}), | |||||
showLineDialog = () => { | |||||
lineOrgDialogData.visible = true | |||||
lineOrgDialogData.data = { | |||||
businessStripCode: formData.value.baseProvManDeprtDing | |||||
} | |||||
}, | |||||
getBaseProvManDeprt = (data) => { | |||||
formData.value.baseProvManDeprtDing = data.businessStripCode | |||||
formData.value.baseProvManDeprt = data.businessStripName | |||||
lineOrgDialogData.visible = false | |||||
}, | |||||
emits = defineEmits(['getBasicInfoData']), | |||||
templateTypeListData = ref(), | |||||
getTemplateTypeList = async () => { | |||||
const res = await templateTypePage({ | |||||
pageNumber: 1, | |||||
pageSize: 10000 | |||||
}) | |||||
templateTypeListData.value = res?.data?.records || [] | |||||
} | |||||
defineExpose({ formRef, formData }) | |||||
onMounted(async () => { | |||||
getTemplateTypeList() | |||||
const res = await districtList({ regionCode: 330500, regionLevel: 2 }) | |||||
regionTree.value = res.data | |||||
}) | |||||
watch(() => props.detail, val => { | |||||
if (val) { | |||||
formData.value = { | |||||
...val.baseinfo, | |||||
baseProjIsConfidentiality: '01', | |||||
// baseProjSetProg: '07', | |||||
baseProvManDeprtType: val.baseinfo?.baseProvManDeprtType + '' || '', | |||||
baseConstructionType: val.baseinfo?.baseConstructionType?.split(';') || [] | |||||
} | |||||
} | |||||
}) | |||||
watch(() => formData.value.baseProjIsConfidentiality, val => { | |||||
formRef.value.clearValidate() | |||||
}) | |||||
watch(() => formData.value, val => { | |||||
emits('getBasicInfoData', formData.value) | |||||
}, { deep: true }) | |||||
</script> | |||||
<template> | |||||
<el-form | |||||
ref="formRef" | |||||
:model="formData" | |||||
:rules="currentRules" | |||||
label-position="top" | |||||
label-suffix=":" | |||||
scroll-to-error | |||||
:validate-on-rule-change="false" | |||||
> | |||||
<el-row :gutter="40"> | |||||
<el-col :span="24"> | |||||
<el-form-item prop="push" label="项目是否归集省里" class="flex-form-item"> | |||||
<el-switch v-model="formData['push']" class="mr-8" /> | |||||
<el-tooltip | |||||
class="box-item" | |||||
content="选择是的情况下,会将项目信息推送至省里进行归集;选择否的情况下,不会将项目信息推至省里。" | |||||
placement="top" | |||||
> | |||||
<div class="flex items-center"> | |||||
<el-icon class="cursor-pointer"><QuestionFilled /></el-icon> | |||||
</div> | |||||
</el-tooltip> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col v-if="false" :span="8"> | |||||
<el-form-item label="是否涉密项目" prop="baseProjIsConfidentiality"> | |||||
<el-select | |||||
v-model="formData.baseProjIsConfidentiality" | |||||
placeholder="请选择" | |||||
class="w-full" | |||||
> | |||||
<el-option | |||||
v-for="(item,index) in dictionaryList?.filter(i => i.type === 'CLASSIFIED')" | |||||
:key="index" | |||||
:label="item.label" | |||||
:value="item.value" | |||||
/> | |||||
</el-select> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<el-form-item label="项目名称" prop="baseProjName"> | |||||
<el-input v-model="formData.baseProjName" maxlength="50" placeholder="请填写" /> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<el-form-item label="项目类型" prop="baseProjType"> | |||||
<el-select | |||||
v-model="formData.baseProjType" | |||||
placeholder="请选择" | |||||
class="w-full" | |||||
> | |||||
<el-option | |||||
v-for="(v,k) in projectOpeOptions" | |||||
:key="k" | |||||
:label="v" | |||||
:value="k" | |||||
/> | |||||
</el-select> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col v-if="false" :span="8"> | |||||
<el-form-item label="所属区划" prop="baseArea"> | |||||
<el-select v-model="formData.baseArea" value-key="baseAreaCode" class="w-full"> | |||||
<el-option | |||||
v-for="(item,index) in regionTree?.children" | |||||
:key="index" | |||||
:label="item.name==='市本级'?'丽水市':item.name" | |||||
:value="{baseAreaCode:item.regionCode,baseAreaName:item.name==='市本级'?'丽水市':item.name}" | |||||
/> | |||||
</el-select> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<el-form-item label="内容类别" prop="baseConstructionType"> | |||||
<el-checkbox-group v-model="formData.baseConstructionType"> | |||||
<el-checkbox v-for="(item,index) in dictionaryList?.filter(i => i.type === 'CONTENT_TYPE')" :key="index" :label="item.value">{{ item.label }}</el-checkbox> | |||||
</el-checkbox-group> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<el-form-item label="项目状态" prop="baseProjSetProg"> | |||||
<el-select | |||||
v-model="formData.baseProjSetProg" | |||||
placeholder="请选择" | |||||
class="w-full" | |||||
> | |||||
<el-option | |||||
v-for="(item,index) in dictionaryList?.filter(i => i.type === 'PROJECT_STATUS')" | |||||
:key="index" | |||||
:label="item.label" | |||||
:value="item.value" | |||||
/> | |||||
</el-select> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<el-form-item label="上级主管单位类型" prop="baseProvManDeprtType"> | |||||
<el-radio-group v-model="formData.baseProvManDeprtType" @change="changeBaseProvManDeprtType"> | |||||
<el-radio label="1">省级</el-radio> | |||||
<el-radio label="2">非省级</el-radio> | |||||
</el-radio-group> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<el-form-item label="上级主管单位" prop="baseProvManDeprt"> | |||||
<el-input | |||||
v-if="formData.baseProvManDeprtType==='2'" | |||||
v-model="formData.baseProvManDeprt" | |||||
placeholder="请选择" | |||||
readonly | |||||
@click="showOrgTree('baseProvManDeprt')" | |||||
/> | |||||
<el-input | |||||
v-else | |||||
v-model="formData.baseProvManDeprt" | |||||
placeholder="请选择" | |||||
readonly | |||||
@click="showLineDialog" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<el-form-item label="本级主管单位" prop="baseManDeprt"> | |||||
<el-input | |||||
v-model="formData.baseManDeprt" | |||||
placeholder="请选择" | |||||
readonly | |||||
@click="showOrgTree('baseManDeprt',)" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<el-form-item label="本级主管单位统一社会信用代码" prop="baseManDepartUsci"> | |||||
<el-input v-model="formData.baseManDepartUsci" placeholder="请填写" :disabled="isDisabledCreditCode['baseManDepartUsci']" /> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<el-form-item label="建设单位" prop="baseBuildDeprt"> | |||||
<el-input | |||||
v-model="formData.baseBuildDeprt" | |||||
placeholder="请选择" | |||||
readonly | |||||
@click="showOrgTree('baseBuildDeprt',)" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<el-form-item label="建设单位统一信用代码" prop="baseBuildDepartUsci"> | |||||
<el-input v-model="formData.baseBuildDepartUsci" placeholder="请填写" :disabled="isDisabledCreditCode['baseBuildDepartUsci']" /> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<el-form-item label="项目负责人" prop="baseProjPrincipal"> | |||||
<el-input | |||||
v-model="formData.baseProjPrincipal" | |||||
readonly | |||||
placeholder="请选择,温馨提示:项目负责人请填写领导信息" | |||||
@click="showUserDialog('baseProjPrincipal','baseProjPrincipalCall')" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<el-form-item label="负责人手机号码" prop="baseProjPrincipalCall"> | |||||
<el-input | |||||
v-model="formData.baseProjPrincipalCall" | |||||
readonly | |||||
placeholder="请选择" | |||||
@click="showUserDialog('baseProjPrincipal','baseProjPrincipalCall')" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<el-form-item label="项目联系人" prop="baseProjContacts"> | |||||
<el-input | |||||
v-model="formData.baseProjContacts" | |||||
readonly | |||||
placeholder="请选择" | |||||
@click="showUserDialog('baseProjContacts','baseProjContactsCall')" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<el-form-item label="联系人手机号码" prop="baseProjContactsCall"> | |||||
<el-input | |||||
v-model="formData.baseProjContactsCall" | |||||
readonly | |||||
placeholder="请选择" | |||||
@click="showUserDialog('baseProjContacts','baseProjContactsCall')" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="24"> | |||||
<el-form-item label="系统定位" prop="systemPosition"> | |||||
<el-input | |||||
v-model="formData.systemPosition" | |||||
type="textarea" | |||||
show-word-limit | |||||
placeholder="请填写" | |||||
:maxlength="2000" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="24"> | |||||
<el-form-item label="绩效评价类型" prop="templateType"> | |||||
<el-radio-group v-model="formData.templateType"> | |||||
<el-radio | |||||
v-for="(v,k) in templateTypeListData" | |||||
:key="k" | |||||
:label="v.id" | |||||
> | |||||
{{ v.name }} | |||||
</el-radio> | |||||
</el-radio-group> | |||||
</el-form-item> | |||||
</el-col> | |||||
</el-row> | |||||
</el-form> | |||||
<org-tree | |||||
:visible="orgProps.unitVisible" | |||||
:show-checkbox="false" | |||||
:default-data="orgProps.data" | |||||
:title="orgProps.title" | |||||
:type="orgProps.type" | |||||
:default-props="orgProps.defaultProps" | |||||
:params="orgProps.params" | |||||
@close="closeOrg" | |||||
@get-select-unit="getOrgData" | |||||
/> | |||||
<user-dialog | |||||
:visible="userDialogData.visible" | |||||
:params="userDialogData.params" | |||||
@close="userDialogData.visible=false" | |||||
@get-user-data="getUserData" | |||||
/> | |||||
<line-org-dialog | |||||
:visible="lineOrgDialogData.visible" | |||||
:data="lineOrgDialogData.data" | |||||
@close="lineOrgDialogData.visible=false" | |||||
@get-base-prov-man-deprt="getBaseProvManDeprt" | |||||
/> | |||||
</template> |
@@ -0,0 +1,110 @@ | |||||
<script name="projectCollectionEnterBudgetInfo" setup> | |||||
import { ref, watch } from 'vue' | |||||
import store from '@/store' | |||||
const { budgetSourceOptions } = store.dictStore.globalDicts || {} | |||||
const props = defineProps({ | |||||
detail: { | |||||
type: Object | |||||
} | |||||
}), | |||||
formRef = ref(), | |||||
moneyValidator = (rule, value, callback) => { // 金额校验 | |||||
if (!value) callback() | |||||
if (!/^\d+(\.\d{1,6})?$/.test(value)) { | |||||
callback('请输入正确格式,最多保留六位小数') | |||||
} else if (value * 1 >= 100000000) { | |||||
callback('请输入正确格式,小于100000000') | |||||
} else { | |||||
callback() | |||||
} | |||||
}, | |||||
formData = ref({}), | |||||
rules = { | |||||
declareAmount: [{ required: true, message: '请填写申报金额', trigger: 'blur' }, { validator: moneyValidator, trigger: 'blur' }], | |||||
approvalAmount: [{ required: true, message: '请填写批复金额', trigger: 'blur' }, { validator: moneyValidator, trigger: 'blur' }], | |||||
budgetSource: [{ required: true, message: '请选择预算来源', trigger: 'change' }], | |||||
projectYear: [{ required: true, message: '请选择预算年度', trigger: 'blur' }] | |||||
} | |||||
defineExpose({ formRef, formData }) | |||||
watch(() => props.detail, val => { | |||||
if (val) { | |||||
formData.value = { | |||||
declareAmount: val.declareAmount, | |||||
approvalAmount: val.approvalAmount, | |||||
budgetSource: val.budgetSource, | |||||
projectYear: `${val.projectYear}` | |||||
} | |||||
} | |||||
}) | |||||
</script> | |||||
<template> | |||||
<el-form | |||||
ref="formRef" | |||||
:model="formData" | |||||
:rules="rules" | |||||
label-position="top" | |||||
label-suffix=":" | |||||
scroll-to-error | |||||
> | |||||
<el-row :gutter="40"> | |||||
<el-col :span="6"> | |||||
<el-form-item label="申报金额" prop="declareAmount"> | |||||
<el-input-number | |||||
v-model="formData.declareAmount" | |||||
class="input-amount" | |||||
placeholder="请填写" | |||||
:min="0.000001" | |||||
:controls="false" | |||||
@mousewheel.prevent | |||||
> | |||||
<template #suffix>万元</template> | |||||
</el-input-number> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="6"> | |||||
<el-form-item label="批复金额" prop="approvalAmount"> | |||||
<el-input-number | |||||
v-model="formData.approvalAmount" | |||||
class="input-amount" | |||||
placeholder="请填写" | |||||
:min="0.000001" | |||||
:controls="false" | |||||
@mousewheel.prevent | |||||
> | |||||
<template #suffix>万元</template> | |||||
</el-input-number> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="6"> | |||||
<el-form-item label="预算来源" prop="budgetSource"> | |||||
<el-select | |||||
v-model="formData.budgetSource" | |||||
placeholder="请选择" | |||||
class="w-full" | |||||
> | |||||
<el-option | |||||
v-for="(v,k) in budgetSourceOptions" | |||||
:key="k" | |||||
:label="v" | |||||
:value="k*1" | |||||
/> | |||||
</el-select> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="6"> | |||||
<el-form-item label="预算年度" prop="projectYear"> | |||||
<el-date-picker | |||||
v-model="formData.projectYear" | |||||
type="year" | |||||
placeholder="请选择" | |||||
format="YYYY" | |||||
value-format="YYYY" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
</el-row> | |||||
</el-form> | |||||
</template> |
@@ -0,0 +1,193 @@ | |||||
<script name="coreBusiness" setup> | |||||
import { reactive, ref, nextTick, watch } from 'vue' | |||||
import { getCoreBusinessData } from '@/http/apis/declareMange' | |||||
import { storeToRefs } from 'pinia' | |||||
import store from '@/store' | |||||
const props = defineProps({ | |||||
detail: { | |||||
type: Object | |||||
}, | |||||
basicInfoData: { | |||||
type: Object | |||||
} | |||||
}), | |||||
userInfo = storeToRefs(store.userStore).userInfo || {}, | |||||
formData = ref({}), | |||||
formRef = ref(), | |||||
rules = { | |||||
coreBusiness: [{ required: false, message: '请至少选择一个核心业务' }] | |||||
}, | |||||
// 选择核心业务 | |||||
selectCoreBusiness = () => { | |||||
coreBusinessvisible.value = true | |||||
getCoreBusinessTableData({ pageNumber: 1, pageSize: 10 }, true) | |||||
}, | |||||
column = [ | |||||
{ | |||||
type: 'index', | |||||
label: '序号', | |||||
width: 60 | |||||
}, | |||||
// { | |||||
// label: '业务编号', | |||||
// key: 'oid', | |||||
// prop: 'oid' | |||||
// }, | |||||
{ | |||||
label: '业务名称', | |||||
key: 'matterName', | |||||
prop: 'matterName' | |||||
}, | |||||
{ | |||||
label: '所属单位', | |||||
key: 'orgName', | |||||
prop: 'orgName' | |||||
} | |||||
], | |||||
tableListRef = ref(), | |||||
coreBusinessData = ref([]), | |||||
coreBusinesstotal = ref(0), | |||||
column2 = [ | |||||
{ | |||||
type: 'selection' | |||||
}, | |||||
// { | |||||
// label: '业务编号', | |||||
// prop: 'oid', | |||||
// key: 'oid' | |||||
// }, | |||||
{ | |||||
label: '业务名称', | |||||
prop: 'matterName', | |||||
key: 'matterName' | |||||
}, | |||||
{ | |||||
label: '所属单位', | |||||
prop: 'orgName', | |||||
key: 'orgName' | |||||
} | |||||
], | |||||
coreBusinessvisible = ref(false), | |||||
getCoreBusinessTableData = async (pageParams = tableListRef.value?.pageParams, flag) => { | |||||
var orgCode = [] | |||||
props?.basicInfoData?.baseManDeprtDing && orgCode.push(props.basicInfoData.baseManDeprtDing) | |||||
props?.basicInfoData?.baseBuildDeprtDing && orgCode.push(props.basicInfoData.baseBuildDeprtDing) | |||||
const res = await getCoreBusinessData({ | |||||
...pageParams, | |||||
businessName: coreBusinessParams.businessName, | |||||
orgCode: orgCode.join(',') | |||||
}) | |||||
coreBusinessData.value = res.data.data | |||||
coreBusinesstotal.value = res.data.total | |||||
await nextTick() | |||||
if (flag) { | |||||
coreBusinessData.value && coreBusinessData.value.forEach(item => { | |||||
const dataIds = formData.value.coreBusiness && formData.value.coreBusiness.map(i => i.id * 1) || [] | |||||
if (dataIds.includes(item.id)) { | |||||
tableListRef.value.toggleRowSelect(item, true) | |||||
} else { | |||||
tableListRef.value.toggleRowSelect(item, false) | |||||
} | |||||
}) | |||||
} | |||||
}, | |||||
searchCoreBussiness = () => { | |||||
getCoreBusinessTableData() | |||||
}, | |||||
coreBusinessTempotary = ref(), | |||||
selectionCoreBusinessChange = (data) => { | |||||
coreBusinessTempotary.value = data | |||||
}, | |||||
coreBusinessParams = reactive({ | |||||
businessName: undefined | |||||
}), | |||||
handleReset = () => { | |||||
coreBusinessParams.businessName = '' | |||||
}, | |||||
confirmCoreBusiness = () => { | |||||
formData.value.coreBusiness = coreBusinessTempotary.value | |||||
coreBusinessvisible.value = false | |||||
} | |||||
defineExpose({ formRef, formData }) | |||||
watch(() => props.detail, val => { | |||||
if (val) { | |||||
formData.value = { | |||||
coreBusiness: val.apply?.baseCoreBusinessCode?.split(';')?.map((i, k) => { | |||||
return { | |||||
id: i, | |||||
matterName: val.apply?.baseCoreBusiness?.split(';')[k], | |||||
orgName: userInfo.value.empPosUnitName | |||||
} | |||||
}) || [] | |||||
} | |||||
} | |||||
}) | |||||
</script> | |||||
<template> | |||||
<el-form | |||||
ref="formRef" | |||||
:model="formData" | |||||
:rules="rules" | |||||
label-position="right" | |||||
label-width="0" | |||||
label-suffix=":" | |||||
scroll-to-error | |||||
> | |||||
<el-row :gutter="40"> | |||||
<el-col :span="24" class="mb-16"> | |||||
<el-button type="primary" class="float-right" @click="selectCoreBusiness"> | |||||
选择核心业务 | |||||
</el-button> | |||||
</el-col> | |||||
<el-col :span="24"> | |||||
<el-form-item> | |||||
<table-list | |||||
:pagination="false" | |||||
style="width: 100%" | |||||
:column="column" | |||||
:data="formData.coreBusiness" | |||||
:empty-temp="false" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
</el-row> | |||||
</el-form> | |||||
<el-dialog | |||||
title="选择核心业务" | |||||
:close-on-click-modal="false" | |||||
:before-close="()=>coreBusinessvisible=false" | |||||
:model-value="coreBusinessvisible" | |||||
width="700px" | |||||
> | |||||
<el-row style="margin-bottom: 16px" :gutter="20"> | |||||
<el-col :span="12"> | |||||
<el-input v-model="coreBusinessParams.businessName" placeholder="请输入" /> | |||||
</el-col> | |||||
<el-col :span="12"> | |||||
<div class="flex"> | |||||
<el-button type="primary" @click="searchCoreBussiness">查询</el-button> | |||||
<el-button @click="handleReset">重置</el-button> | |||||
</div> | |||||
</el-col> | |||||
</el-row> | |||||
<table-list | |||||
ref="tableListRef" | |||||
:column="column2" | |||||
:data="coreBusinessData" | |||||
:total="coreBusinesstotal" | |||||
@selection-change="selectionCoreBusinessChange" | |||||
@get-table-data="getCoreBusinessTableData" | |||||
/> | |||||
<template #footer> | |||||
<el-button type="primary" @click="confirmCoreBusiness"> 提交 </el-button> | |||||
<el-button @click="coreBusinessvisible = false"> 关闭 </el-button> | |||||
</template> | |||||
</el-dialog> | |||||
</template> | |||||
<style lang="less"> | |||||
.el-upload-list{ | |||||
width: 100%; | |||||
} | |||||
</style> |
@@ -0,0 +1,559 @@ | |||||
<script name="empMaterials" setup> | |||||
import { reactive, ref, watch } from 'vue' | |||||
import { fileFormatVerification, handleFileError, handleFileSuccess, handleFilePreview, reviewFileParam, fileTypes, fileDesc } from '@/utils/uploadAction' | |||||
import store from '@/store' | |||||
import ActualPerformanceIndicatorsDialog | |||||
from '@/pages/declareManage/initialInspectionRecord/uploadInitMaterials/components/actualPerformanceIndicatorsDialog.vue' | |||||
const props = defineProps({ | |||||
detail: { | |||||
type: Object | |||||
}, | |||||
data: { | |||||
type: Object | |||||
}, | |||||
basicInfoData: { | |||||
type: Object | |||||
}, | |||||
approvalInfoData: { | |||||
type: Object | |||||
}, | |||||
baseProjSetYear: { | |||||
type: String, | |||||
default: '' | |||||
} | |||||
}), | |||||
uploadUrl = store.dictStore.uploadUrl, | |||||
formRef = ref(), | |||||
formData = ref({ | |||||
feasibilityStudyReport: [], | |||||
approvedFile: [], | |||||
purchaseFile: [], | |||||
acceptanceLetter: [], | |||||
purchaseContract: [], | |||||
acceptanceReport: [], | |||||
changeApprovalDoc: [], | |||||
baseBusinessMetrics: [] | |||||
}), | |||||
fileRule = [{ required: true, message: '请选择文件' }], | |||||
currentRules = ref({ | |||||
baseInitialOpinionFile: fileRule, | |||||
baseInforLevelFile: fileRule, | |||||
basePasswAssessFile: fileRule, | |||||
baseThirdAcceptFile: fileRule, | |||||
baseCheckFile: fileRule, | |||||
baseFinanlAuditFile: fileRule, | |||||
baseUserConsFile: fileRule, | |||||
baseEstaSummFile: fileRule, | |||||
baseOperatMaintenSummFile: fileRule, | |||||
baseFinalExpertOpinionFile: fileRule, | |||||
baseEngineerPostpoFile: fileRule, | |||||
baseEngineerAlterFile: fileRule, | |||||
baseChanFile: fileRule, | |||||
baseBusinessMetrics: [{ required: true, message: '请添加' }], | |||||
baseLogAggregation: [{ required: true, message: '请选择' }] | |||||
}), | |||||
// 实际成效指标 | |||||
column1 = [ | |||||
{ | |||||
label: '核心业务', | |||||
prop: 'businessName', | |||||
key: 'businessName' | |||||
}, | |||||
{ | |||||
label: '实际成效指标', | |||||
prop: 'name', | |||||
key: 'name' | |||||
}, | |||||
{ | |||||
label: '数值', | |||||
prop: 'nums', | |||||
key: 'nums' | |||||
}, | |||||
{ | |||||
label: '单位', | |||||
prop: 'unit', | |||||
key: 'unit' | |||||
}, | |||||
{ | |||||
label: '操作', | |||||
slot: 'action', | |||||
key: 'action' | |||||
} | |||||
], | |||||
projectContentDialogData = reactive({ | |||||
visible: false, | |||||
data: undefined | |||||
}), | |||||
projectContentIndex = ref(), | |||||
showProjectContentDialog = (data, index) => { | |||||
projectContentDialogData.data = data | |||||
projectContentDialogData.visible = true | |||||
projectContentIndex.value = index | |||||
}, | |||||
setContent = (data) => { | |||||
if (projectContentIndex.value === undefined) { | |||||
formData.value.baseBusinessMetrics = [...formData.value.baseBusinessMetrics, ...data] | |||||
} else { | |||||
formData.value.baseBusinessMetrics[projectContentIndex.value] = data[0] | |||||
} | |||||
}, | |||||
delProjectContent = (index) => { | |||||
formData.value.baseBusinessMetrics.splice(index, 1) | |||||
} | |||||
defineExpose({ formRef, formData }) | |||||
watch(() => props.basicInfoData, val => { | |||||
if (val.baseProjIsConfidentiality === '02' || val?.baseProjSetProg === '00') { | |||||
currentRules.value = {} | |||||
} else { | |||||
currentRules.value = { | |||||
baseInitialOpinionFile: fileRule, | |||||
baseInforLevelFile: fileRule, | |||||
basePasswAssessFile: fileRule, | |||||
baseThirdAcceptFile: fileRule, | |||||
baseCheckFile: fileRule, | |||||
baseFinanlAuditFile: fileRule, | |||||
baseUserConsFile: fileRule, | |||||
baseEstaSummFile: fileRule, | |||||
baseOperatMaintenSummFile: fileRule, | |||||
baseFinalExpertOpinionFile: fileRule, | |||||
baseEngineerPostpoFile: fileRule, | |||||
baseEngineerAlterFile: fileRule, | |||||
baseChanFile: fileRule, | |||||
baseBusinessMetrics: [{ required: true, message: '请添加' }], | |||||
baseLogAggregation: [{ required: true, message: '请选择' }] | |||||
} | |||||
} | |||||
formRef.value.clearValidate() | |||||
}, { deep: true }) | |||||
watch(() => props.detail, val => { | |||||
if (val) { | |||||
formData.value = { | |||||
...val.mimplement, | |||||
baseInitialOpinionFile: val.mimplement?.baseInitialOpinionFile ? reviewFileParam(JSON.parse(val.mimplement.baseInitialOpinionFile)) : [], | |||||
baseInforLevelFile: val.mimplement?.baseInforLevelFile ? reviewFileParam(JSON.parse(val.mimplement.baseInforLevelFile)) : [], | |||||
basePasswAssessFile: val.mimplement?.basePasswAssessFile ? reviewFileParam(JSON.parse(val.mimplement.basePasswAssessFile)) : [], | |||||
baseThirdAcceptFile: val.mimplement?.baseThirdAcceptFile ? reviewFileParam(JSON.parse(val.mimplement.baseThirdAcceptFile)) : [], | |||||
baseCheckFile: val.mimplement?.baseCheckFile ? reviewFileParam(JSON.parse(val.mimplement.baseCheckFile)) : [], | |||||
baseFinanlAuditFile: val.mimplement?.baseFinanlAuditFile ? reviewFileParam(JSON.parse(val.mimplement.baseFinanlAuditFile)) : [], | |||||
baseUserConsFile: val.mimplement?.baseUserConsFile ? reviewFileParam(JSON.parse(val.mimplement.baseUserConsFile)) : [], | |||||
baseEstaSummFile: val.mimplement?.baseEstaSummFile ? reviewFileParam(JSON.parse(val.mimplement.baseEstaSummFile)) : [], | |||||
baseOperatMaintenSummFile: val.mimplement?.baseOperatMaintenSummFile ? reviewFileParam(JSON.parse(val.mimplement.baseOperatMaintenSummFile)) : [], | |||||
baseFinalExpertOpinionFile: val.mimplement?.baseFinalExpertOpinionFile ? reviewFileParam(JSON.parse(val.mimplement.baseFinalExpertOpinionFile)) : [], | |||||
baseEngineerPostpoFile: val.mimplement?.baseEngineerPostpoFile ? reviewFileParam(JSON.parse(val.mimplement.baseEngineerPostpoFile)) : [], | |||||
baseEngineerAlterFile: val.mimplement?.baseEngineerAlterFile ? reviewFileParam(JSON.parse(val.mimplement.baseEngineerAlterFile)) : [], | |||||
baseChanFile: val.mimplement?.baseChanFile ? reviewFileParam(JSON.parse(val.mimplement.baseChanFile)) : [], | |||||
baseBusinessMetrics: val.mimplement?.baseBusinessMetrics && JSON.parse(val.mimplement?.baseBusinessMetrics) || [] | |||||
} | |||||
} | |||||
}) | |||||
watch(() => props.data, val => { | |||||
}, | |||||
{ immediate: true, deep: true }) | |||||
</script> | |||||
<template> | |||||
<el-form | |||||
ref="formRef" | |||||
:model="formData" | |||||
:rules="currentRules" | |||||
label-position="top" | |||||
label-suffix=":" | |||||
scroll-to-error | |||||
:validate-on-rule-change="false" | |||||
> | |||||
<el-row :gutter="40"> | |||||
<el-col :span="24"> | |||||
<el-form-item | |||||
v-if="baseProjSetYear*1>=2024" | |||||
label="是否完成日志数据归集" | |||||
label-width="170" | |||||
prop="baseLogAggregation" | |||||
> | |||||
<el-radio-group v-model="formData.baseLogAggregation"> | |||||
<el-radio label="1">是</el-radio> | |||||
<el-radio label="2">否</el-radio> | |||||
</el-radio-group> | |||||
</el-form-item> | |||||
<el-form-item | |||||
v-else | |||||
label="是否完成日志数据归集" | |||||
label-width="170" | |||||
> | |||||
<el-radio-group v-model="formData.baseLogAggregation"> | |||||
<el-radio label="1">是</el-radio> | |||||
<el-radio label="2">否</el-radio> | |||||
</el-radio-group> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="24"> | |||||
<el-form-item | |||||
v-if="baseProjSetYear*1>=2024" | |||||
label="实际成效指标" | |||||
label-width="170" | |||||
prop="baseBusinessMetrics" | |||||
> | |||||
<table-list | |||||
:pagination="false" | |||||
style="width: 100%" | |||||
:column="column1" | |||||
:data="formData.baseBusinessMetrics" | |||||
:empty-temp="false" | |||||
> | |||||
<template #action="{scope}"> | |||||
<a @click="showProjectContentDialog(scope.row,scope.$index)">编辑</a> | |||||
<a class="text-danger" @click="delProjectContent(scope.$index)">删除</a> | |||||
</template> | |||||
</table-list> | |||||
<p class="text-right w-full mt-8"> | |||||
<el-button | |||||
type="primary" | |||||
class="w-full" | |||||
plain | |||||
icon="Plus" | |||||
@click="()=>showProjectContentDialog()" | |||||
>添加</el-button> | |||||
</p> | |||||
</el-form-item> | |||||
<el-form-item | |||||
v-else | |||||
label="实际成效指标" | |||||
label-width="170" | |||||
> | |||||
<table-list | |||||
:pagination="false" | |||||
style="width: 100%" | |||||
:column="column1" | |||||
:data="formData.baseBusinessMetrics" | |||||
:empty-temp="false" | |||||
> | |||||
<template #action="{scope}"> | |||||
<a @click="showProjectContentDialog(scope.row,scope.$index)">编辑</a> | |||||
<a class="text-danger" @click="delProjectContent(scope.$index)">删除</a> | |||||
</template> | |||||
</table-list> | |||||
<p class="text-right w-full mt-8"> | |||||
<el-button | |||||
type="primary" | |||||
class="w-full" | |||||
plain | |||||
icon="Plus" | |||||
@click="()=>showProjectContentDialog()" | |||||
>添加</el-button> | |||||
</p> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col v-if="(['05','06','07','00'].includes(basicInfoData?.baseProjSetProg)&&basicInfoData?.baseConstructionType?.includes('01'))||!basicInfoData?.baseConstructionType?.includes('01')" :span="8"> | |||||
<el-form-item | |||||
v-if="basicInfoData?.baseProjSetProg==='07'&&basicInfoData?.baseConstructionType?.includes('01')&&['03','04','05'].includes(approvalInfoData?.equalProtectionLevel)" | |||||
label="信息安全等级保护测评报告" | |||||
prop="baseInforLevelFile" | |||||
> | |||||
<el-upload | |||||
v-model:file-list="formData.baseInforLevelFile" | |||||
class="w-full" | |||||
:action="uploadUrl" | |||||
:on-success="res => handleFileSuccess(res, formData.baseInforLevelFile)" | |||||
:on-error="handleFileError" | |||||
:before-upload="file=>fileFormatVerification(file, {types: fileTypes})" | |||||
:accept="fileTypes.map(i=>`.${i}`).join(',')" | |||||
multiple | |||||
:on-preview="handleFilePreview" | |||||
> | |||||
<el-button type="primary" class="mr-4" plain>上传文件</el-button> | |||||
<template #tip> | |||||
<div class="el-upload__tip">支持{{ fileDesc }}文件</div> | |||||
</template> | |||||
</el-upload> | |||||
</el-form-item> | |||||
<el-form-item | |||||
v-else | |||||
label="信息安全等级保护测评报告" | |||||
> | |||||
<el-upload | |||||
v-model:file-list="formData.baseInforLevelFile" | |||||
class="w-full" | |||||
:action="uploadUrl" | |||||
:on-success="res => handleFileSuccess(res, formData.baseInforLevelFile)" | |||||
:on-error="handleFileError" | |||||
:before-upload="file=>fileFormatVerification(file, {types: fileTypes})" | |||||
:accept="fileTypes.map(i=>`.${i}`).join(',')" | |||||
multiple | |||||
:on-preview="handleFilePreview" | |||||
> | |||||
<el-button type="primary" class="mr-4" plain>上传文件</el-button> | |||||
<template #tip> | |||||
<div class="el-upload__tip">支持{{ fileDesc }}文件</div> | |||||
</template> | |||||
</el-upload> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col v-if="!['01','02','03'].includes(basicInfoData?.baseProjSetProg)||baseProjSetYear*1<2023" :span="8"> | |||||
<el-form-item | |||||
v-if="['01','02'].includes(approvalInfoData?.equalProtectionLevel)||baseProjSetYear*1<2023" | |||||
label="商业密码应用评估报告" | |||||
> | |||||
<el-upload | |||||
v-model:file-list="formData.basePasswAssessFile" | |||||
class="w-full" | |||||
:action="uploadUrl" | |||||
:on-success="res => handleFileSuccess(res, formData.basePasswAssessFile)" | |||||
:on-error="handleFileError" | |||||
:before-upload="file=>fileFormatVerification(file, {types: fileTypes})" | |||||
:accept="fileTypes.map(i=>`.${i}`).join(',')" | |||||
multiple | |||||
:on-preview="handleFilePreview" | |||||
> | |||||
<el-button type="primary" class="mr-4" plain>上传文件</el-button> | |||||
<template #tip> | |||||
<div class="el-upload__tip">支持{{ fileDesc }}文件</div> | |||||
</template> | |||||
</el-upload> | |||||
</el-form-item> | |||||
<el-form-item | |||||
v-else | |||||
label="商业密码应用评估报告" | |||||
prop="basePasswAssessFile" | |||||
> | |||||
<el-upload | |||||
v-model:file-list="formData.basePasswAssessFile" | |||||
class="w-full" | |||||
:action="uploadUrl" | |||||
:on-success="res => handleFileSuccess(res, formData.basePasswAssessFile)" | |||||
:on-error="handleFileError" | |||||
:before-upload="file=>fileFormatVerification(file, {types: fileTypes})" | |||||
:accept="fileTypes.map(i=>`.${i}`).join(',')" | |||||
multiple | |||||
:on-preview="handleFilePreview" | |||||
> | |||||
<el-button type="primary" class="mr-4" plain>上传文件</el-button> | |||||
<template #tip> | |||||
<div class="el-upload__tip">支持{{ fileDesc }}文件</div> | |||||
</template> | |||||
</el-upload> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<el-form-item | |||||
label="第三方验收测试报告" | |||||
> | |||||
<el-upload | |||||
v-model:file-list="formData.baseThirdAcceptFile" | |||||
class="w-full" | |||||
:action="uploadUrl" | |||||
:on-success="res => handleFileSuccess(res, formData.baseThirdAcceptFile)" | |||||
:on-error="handleFileError" | |||||
:before-upload="file=>fileFormatVerification(file, {types: fileTypes})" | |||||
:accept="fileTypes.map(i=>`.${i}`).join(',')" | |||||
multiple | |||||
:on-preview="handleFilePreview" | |||||
> | |||||
<el-button type="primary" class="mr-4" plain>上传文件</el-button> | |||||
<template #tip> | |||||
<div class="el-upload__tip">支持{{ fileDesc }}文件</div> | |||||
</template> | |||||
</el-upload> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col v-if="!['01','02','03','04'].includes(basicInfoData?.baseProjSetProg)||baseProjSetYear*1<2023" :span="8"> | |||||
<el-form-item | |||||
v-if="baseProjSetYear*1<2023||['05','06','07'].includes(basicInfoData?.baseProjSetProg)" | |||||
label="用户使用报告" | |||||
> | |||||
<el-upload | |||||
v-model:file-list="formData.baseUserConsFile" | |||||
class="w-full" | |||||
:action="uploadUrl" | |||||
:on-success="res => handleFileSuccess(res, formData.baseUserConsFile)" | |||||
:on-error="handleFileError" | |||||
:before-upload="file=>fileFormatVerification(file, {types: fileTypes})" | |||||
:accept="fileTypes.map(i=>`.${i}`).join(',')" | |||||
multiple | |||||
> | |||||
<el-button type="primary" class="mr-4" plain>上传文件</el-button> | |||||
<template #tip> | |||||
<div class="el-upload__tip">支持{{ fileDesc }}文件</div> | |||||
</template> | |||||
</el-upload> | |||||
</el-form-item> | |||||
<el-form-item | |||||
v-else | |||||
label="用户使用报告" | |||||
prop="baseUserConsFile" | |||||
> | |||||
<el-upload | |||||
v-model:file-list="formData.baseUserConsFile" | |||||
class="w-full" | |||||
:action="uploadUrl" | |||||
:on-success="res => handleFileSuccess(res, formData.baseUserConsFile)" | |||||
:on-error="handleFileError" | |||||
:before-upload="file=>fileFormatVerification(file, {types: fileTypes})" | |||||
:accept="fileTypes.map(i=>`.${i}`).join(',')" | |||||
multiple | |||||
> | |||||
<el-button type="primary" class="mr-4" plain>上传文件</el-button> | |||||
<template #tip> | |||||
<div class="el-upload__tip">支持{{ fileDesc }}文件</div> | |||||
</template> | |||||
</el-upload> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<el-form-item | |||||
label="监理总结报告" | |||||
> | |||||
<el-upload | |||||
v-model:file-list="formData.baseEstaSummFile" | |||||
class="w-full" | |||||
:action="uploadUrl" | |||||
:on-success="res => handleFileSuccess(res, formData.baseEstaSummFile)" | |||||
:on-error="handleFileError" | |||||
:before-upload="file=>fileFormatVerification(file, {types: fileTypes})" | |||||
:accept="fileTypes.map(i=>`.${i}`).join(',')" | |||||
multiple | |||||
> | |||||
<el-button type="primary" class="mr-4" plain>上传文件</el-button> | |||||
<template #tip> | |||||
<div class="el-upload__tip">支持{{ fileDesc }}文件</div> | |||||
</template> | |||||
</el-upload> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col v-if="!['01','02','03','04'].includes(basicInfoData?.baseProjSetProg)||baseProjSetYear*1<2023" :span="8"> | |||||
<el-form-item | |||||
v-if="basicInfoData?.baseProjSetProg==='07'&&baseProjSetYear*1>=2023" | |||||
label="运维总结报告" | |||||
prop="baseOperatMaintenSummFile" | |||||
> | |||||
<el-upload | |||||
v-model:file-list="formData.baseOperatMaintenSummFile" | |||||
class="w-full" | |||||
:action="uploadUrl" | |||||
:on-success="res => handleFileSuccess(res, formData.baseOperatMaintenSummFile)" | |||||
:on-error="handleFileError" | |||||
:before-upload="file=>fileFormatVerification(file, {types: fileTypes})" | |||||
:accept="fileTypes.map(i=>`.${i}`).join(',')" | |||||
multiple | |||||
> | |||||
<el-button type="primary" class="mr-4" plain>上传文件</el-button> | |||||
<template #tip> | |||||
<div class="el-upload__tip">支持{{ fileDesc }}文件</div> | |||||
</template> | |||||
</el-upload> | |||||
</el-form-item> | |||||
<el-form-item | |||||
v-else | |||||
label="运维总结报告" | |||||
> | |||||
<el-upload | |||||
v-model:file-list="formData.baseOperatMaintenSummFile" | |||||
class="w-full" | |||||
:action="uploadUrl" | |||||
:on-success="res => handleFileSuccess(res, formData.baseOperatMaintenSummFile)" | |||||
:on-error="handleFileError" | |||||
:before-upload="file=>fileFormatVerification(file, {types: fileTypes})" | |||||
:accept="fileTypes.map(i=>`.${i}`).join(',')" | |||||
multiple | |||||
> | |||||
<el-button type="primary" class="mr-4" plain>上传文件</el-button> | |||||
<template #tip> | |||||
<div class="el-upload__tip">支持{{ fileDesc }}文件</div> | |||||
</template> | |||||
</el-upload> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col v-if="basicInfoData?.baseProjSetProg==='07'" :span="8"> | |||||
<el-form-item | |||||
label="终验意见" | |||||
prop="baseFinalExpertOpinionFile" | |||||
> | |||||
<el-upload | |||||
v-model:file-list="formData.baseFinalExpertOpinionFile" | |||||
class="w-full" | |||||
:action="uploadUrl" | |||||
:on-success="res => handleFileSuccess(res, formData.baseFinalExpertOpinionFile)" | |||||
:on-error="handleFileError" | |||||
:before-upload="file=>fileFormatVerification(file, {types: fileTypes})" | |||||
:accept="fileTypes.map(i=>`.${i}`).join(',')" | |||||
multiple | |||||
> | |||||
<el-button type="primary" class="mr-4" plain>上传文件</el-button> | |||||
<template #tip> | |||||
<div class="el-upload__tip">支持{{ fileDesc }}文件</div> | |||||
</template> | |||||
</el-upload> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<el-form-item | |||||
label="项目延期申请表" | |||||
> | |||||
<el-upload | |||||
v-model:file-list="formData.baseEngineerPostpoFile" | |||||
class="w-full" | |||||
:action="uploadUrl" | |||||
:on-success="res => handleFileSuccess(res, formData.baseEngineerPostpoFile)" | |||||
:on-error="handleFileError" | |||||
:before-upload="file=>fileFormatVerification(file, {types: fileTypes})" | |||||
:accept="fileTypes.map(i=>`.${i}`).join(',')" | |||||
multiple | |||||
> | |||||
<el-button type="primary" class="mr-4" plain>上传文件</el-button> | |||||
<template #tip> | |||||
<div class="el-upload__tip">支持{{ fileDesc }}文件</div> | |||||
</template> | |||||
</el-upload> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<el-form-item | |||||
label="变更报告" | |||||
> | |||||
<el-upload | |||||
v-model:file-list="formData.baseEngineerAlterFile" | |||||
class="w-full" | |||||
:action="uploadUrl" | |||||
:on-success="res => handleFileSuccess(res, formData.baseEngineerAlterFile)" | |||||
:on-error="handleFileError" | |||||
:before-upload="file=>fileFormatVerification(file, {types: fileTypes})" | |||||
:accept="fileTypes.map(i=>`.${i}`).join(',')" | |||||
multiple | |||||
> | |||||
<el-button type="primary" class="mr-4" plain>上传文件</el-button> | |||||
<template #tip> | |||||
<div class="el-upload__tip">支持{{ fileDesc }}文件</div> | |||||
</template> | |||||
</el-upload> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<el-form-item | |||||
label="变更批复文件" | |||||
> | |||||
<el-upload | |||||
v-model:file-list="formData.baseChanFile" | |||||
class="w-full" | |||||
:action="uploadUrl" | |||||
:on-success="res => handleFileSuccess(res, formData.baseChanFile)" | |||||
:on-error="handleFileError" | |||||
:before-upload="file=>fileFormatVerification(file, {types: fileTypes})" | |||||
:accept="fileTypes.map(i=>`.${i}`).join(',')" | |||||
multiple | |||||
> | |||||
<el-button type="primary" class="mr-4" plain>上传文件</el-button> | |||||
<template #tip> | |||||
<div class="el-upload__tip">支持{{ fileDesc }}文件</div> | |||||
</template> | |||||
</el-upload> | |||||
</el-form-item> | |||||
</el-col> | |||||
</el-row> | |||||
</el-form> | |||||
<actual-performance-indicators-dialog | |||||
:visible="projectContentDialogData.visible" | |||||
:data="projectContentDialogData.data" | |||||
@set-content="setContent" | |||||
@close="projectContentDialogData.visible=false" | |||||
/> | |||||
</template> |
@@ -0,0 +1,124 @@ | |||||
<script name="relatedIrsAppDialog" setup> | |||||
import { nextTick, ref, watch } from 'vue' | |||||
import { govStripList } from '@/http/apis/declareMange' | |||||
const | |||||
props = defineProps({ | |||||
visible: { | |||||
type: Boolean, | |||||
default: false, | |||||
required: true | |||||
}, | |||||
data: Object, | |||||
column: { | |||||
type: Array, | |||||
default: () => { | |||||
return [ | |||||
{ | |||||
type: 'radio', | |||||
key: 'businessStripCode', | |||||
width: '60' | |||||
}, | |||||
{ | |||||
label: '单位名称', | |||||
key: 'businessStripName', | |||||
prop: 'businessStripName', | |||||
minWidth: '150', | |||||
showOverflowTooltip: true | |||||
}, | |||||
{ | |||||
label: '单位编码', | |||||
key: 'businessStripCode', | |||||
prop: 'businessStripCode', | |||||
minWidth: '150', | |||||
showOverflowTooltip: true | |||||
} | |||||
] | |||||
} | |||||
} | |||||
}), | |||||
searchForm = ref({ | |||||
name: undefined | |||||
}), | |||||
// 表格数据 | |||||
tableListRef = ref(), | |||||
total = ref(0), | |||||
tableData = ref([]), | |||||
getTableData = async (pageParams = tableListRef.value.pageParams) => { | |||||
const res = await govStripList({ ...pageParams, ...searchForm.value }) | |||||
tableData.value = res.data | |||||
await nextTick() | |||||
tableListRef.value.setRadio(props?.data?.businessStripCode || '') | |||||
}, | |||||
// 搜索 | |||||
search = () => { | |||||
tableListRef.value.pageParams.pageNumber = 1 | |||||
getTableData() | |||||
}, | |||||
reset = () => { | |||||
tableListRef.value.pageParams.pageNumber = 1 | |||||
searchForm.value.businessStripName = undefined | |||||
getTableData() | |||||
}, | |||||
selectData = ref(), | |||||
radioChange = (val) => { | |||||
selectData.value = val | |||||
}, | |||||
submit = async () => { | |||||
emits('getBaseProvManDeprt', selectData.value) | |||||
emits('close', true) | |||||
}, | |||||
emits = defineEmits(['close', 'getBaseProvManDeprt']) | |||||
watch(() => props.visible, async (val) => { | |||||
if (val) { | |||||
await nextTick() | |||||
await getTableData() | |||||
} else { | |||||
tableListRef.value.tableRef.clearSelection() | |||||
} | |||||
}) | |||||
</script> | |||||
<template> | |||||
<el-dialog | |||||
:model-value="visible" | |||||
title="选择单位" | |||||
:width="840" | |||||
@close="emits('close')" | |||||
> | |||||
<el-form :model="searchForm" label-suffix=":"> | |||||
<el-row :gutter="24"> | |||||
<el-col :span="12"> | |||||
<el-form-item label="单位名称"> | |||||
<el-input v-model="searchForm.businessStripName" placeholder="请输入" /> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="12"> | |||||
<el-form-item class="search_btn"> | |||||
<el-button type="primary" @click="search">搜索</el-button> | |||||
<el-button @click="reset">重置</el-button> | |||||
</el-form-item> | |||||
</el-col> | |||||
</el-row> | |||||
</el-form> | |||||
<table-list | |||||
ref="tableListRef" | |||||
:column="column" | |||||
:data="tableData" | |||||
:total="total" | |||||
row-key="appId" | |||||
:pagination="false" | |||||
@radio-change="radioChange" | |||||
@get-table-data="getTableData" | |||||
/> | |||||
<template #footer> | |||||
<div class="flex justify-center"> | |||||
<el-button type="primary" @click="submit">确定</el-button> | |||||
<el-button @click="emits('close')">取消</el-button> | |||||
</div> | |||||
</template> | |||||
</el-dialog> | |||||
</template> |
@@ -0,0 +1,216 @@ | |||||
<script name="projectCollectionEnterManageInfo" setup> | |||||
import { onMounted, reactive, ref, watch } from 'vue' | |||||
import OrgTree from '@/components/orgTree/index.vue' | |||||
import store from '@/store' | |||||
import { getTreeParams } from '@/utils/getIsShowRegionTree' | |||||
import { districtList } from '@/http/apis/commonApi' | |||||
const props = defineProps({ | |||||
detail: { | |||||
type: Object | |||||
} | |||||
}), | |||||
{ baseProjConsClassOptions } = store.dictStore.globalDicts || {}, | |||||
// 行政区划 | |||||
areaOptions = ref([]), | |||||
formRef = ref(), | |||||
formData = ref({}), | |||||
// 手机号码校验 | |||||
checkTelPhone = (rule, value, callback) => { | |||||
if (value === '') { | |||||
return callback(new Error('请输入正确的手机号')) | |||||
} else { | |||||
const regIdCard = | |||||
/^(13[0-9]|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18[0-9]|19[0-35-9])\d{8}$/ | |||||
if (regIdCard.test(value)) { | |||||
callback() | |||||
} else { | |||||
return callback(new Error('请输入正确的手机号')) | |||||
} | |||||
} | |||||
}, | |||||
rules = { | |||||
areaCode: [{ required: true, message: '请选择行政区划', trigger: 'change' }], | |||||
buildOrg: [{ required: true, message: '请选择建设单位', trigger: 'change' }], | |||||
responsibleMan: [{ required: true, message: '请填写项目负责人', trigger: 'blur' }], | |||||
responsibleManMobile: [ | |||||
{ required: true, message: '请填写项目负责人手机号', trigger: 'blur' }, | |||||
{ validator: checkTelPhone, trigger: 'blur' } | |||||
], | |||||
contactName: [{ required: true, message: '请填写项目联系人', trigger: 'blur' }], | |||||
contactPhone: [ | |||||
{ required: true, message: '请填写项目联系人手机号', trigger: 'blur' }, | |||||
{ validator: checkTelPhone, trigger: 'blur' } | |||||
], | |||||
higherSuperOrg: [{ required: true, message: '请选择上级业务主管部门', trigger: 'change' }], | |||||
superOrg: [{ required: true, message: '请选择本级业务主管部门', trigger: 'change' }], | |||||
constructionOrg: [{ required: true, message: '请选择建设单位', trigger: 'change' }], | |||||
buildLevel: [{ required: true, message: '请选择建设层级', trigger: 'change' }] | |||||
}, | |||||
// 单位选择 | |||||
orgProps = reactive({ | |||||
field: undefined, | |||||
unitVisible: false, | |||||
data: undefined, | |||||
title: undefined, | |||||
type: undefined, | |||||
params: undefined | |||||
}), | |||||
showOrgTree = (field) => { | |||||
orgProps.field = field | |||||
orgProps.unitVisible = true | |||||
orgProps.title = '选择单位' | |||||
orgProps.type = 'UNIT' | |||||
orgProps.showCheckbox = true | |||||
orgProps.defaultProps = { | |||||
children: 'children', | |||||
label: 'title', | |||||
value: 'key', | |||||
isLeaf: 'isLeaf' | |||||
} | |||||
orgProps.params = { | |||||
onlyUnit: true | |||||
} | |||||
orgProps.data = formData.value[`${field}Code`] ? [{ | |||||
key: formData.value[`${field}Code`], | |||||
title: formData.value[field] | |||||
}] : [] | |||||
}, | |||||
closeOrg = () => { | |||||
orgProps.unitVisible = false | |||||
}, | |||||
getOrgData = (data) => { | |||||
formData.value[`${orgProps.field}Code`] = data?.[0].key || undefined | |||||
formData.value[orgProps.field] = data?.[0].title || undefined | |||||
} | |||||
defineExpose({ formRef, formData }) | |||||
watch(() => props.detail, val => { | |||||
if (val) { | |||||
formData.value = { | |||||
areaCode: ['330500', val.areaCode], | |||||
responsibleMan: val.responsibleMan, | |||||
responsibleManMobile: val.responsibleManMobile, | |||||
contactName: val.contactName, | |||||
contactPhone: val.contactPhone, | |||||
higherSuperOrg: val.higherSuperOrg, | |||||
superOrg: val.superOrg, | |||||
constructionOrg: val.constructionOrg, | |||||
constructionOrgCreditCode: val.constructionOrgCreditCode, | |||||
buildLevel: val.buildLevel, | |||||
buildOrg: val.buildOrg, | |||||
buildOrgCode: val.buildOrgCode | |||||
} | |||||
} | |||||
}) | |||||
onMounted(async () => { | |||||
areaOptions.value = [(await districtList(getTreeParams({ 'SUPER_ADMIN': false, 'REGION_MANAGER': false }))).data] | |||||
}) | |||||
</script> | |||||
<template> | |||||
<el-form | |||||
ref="formRef" | |||||
:model="formData" | |||||
:rules="rules" | |||||
label-position="top" | |||||
label-suffix=":" | |||||
scroll-to-error | |||||
> | |||||
<el-row :gutter="40"> | |||||
<el-col :span="8"> | |||||
<el-form-item label="行政区划" prop="areaCode"> | |||||
<el-cascader | |||||
v-model="formData.areaCode" | |||||
class="w-full" | |||||
:props="{label:'name',value:'regionCode'}" | |||||
:options="areaOptions" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<el-form-item label="项目负责人" prop="responsibleMan"> | |||||
<el-input v-model="formData.responsibleMan" maxlength="50" placeholder="请填写" /> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<el-form-item label="项目负责人手机号" prop="responsibleManMobile"> | |||||
<el-input v-model="formData.responsibleManMobile" maxlength="11" placeholder="请填写" /> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="6"> | |||||
<el-form-item label="项目联系人" prop="contactName"> | |||||
<el-input v-model="formData.contactName" maxlength="50" placeholder="请填写" /> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="6"> | |||||
<el-form-item label="项目联系人手机号" prop="contactPhone"> | |||||
<el-input v-model="formData.contactPhone" maxlength="11" placeholder="请填写" /> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="6"> | |||||
<el-form-item label="上级业务主管部门" prop="higherSuperOrg"> | |||||
<el-input | |||||
v-model="formData.higherSuperOrg" | |||||
placeholder="请选择" | |||||
readonly | |||||
@click="showOrgTree('higherSuperOrg')" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="6"> | |||||
<el-form-item label="本级业务主管部门" prop="superOrg"> | |||||
<el-input | |||||
v-model="formData.superOrg" | |||||
placeholder="请选择" | |||||
readonly | |||||
@click="showOrgTree('superOrg')" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<el-form-item label="建设单位" prop="buildOrg"> | |||||
<el-input | |||||
v-model="formData.buildOrg" | |||||
placeholder="请选择" | |||||
readonly | |||||
@click="showOrgTree('buildOrg')" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<el-form-item label="建设单位统一信用代码" prop="constructionOrgCreditCode"> | |||||
<el-input v-model="formData.constructionOrgCreditCode" maxlength="50" placeholder="请填写" /> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<el-form-item label="建设层级" prop="buildLevel"> | |||||
<el-select | |||||
v-model="formData.buildLevel" | |||||
placeholder="请选择" | |||||
class="w-full" | |||||
> | |||||
<el-option | |||||
v-for="(value, key) in baseProjConsClassOptions" | |||||
:key="key" | |||||
:label="value" | |||||
:value="key*1" | |||||
/> | |||||
</el-select> | |||||
</el-form-item> | |||||
</el-col> | |||||
</el-row> | |||||
</el-form> | |||||
<org-tree | |||||
:visible="orgProps.unitVisible" | |||||
:show-checkbox="false" | |||||
:default-data="orgProps.data" | |||||
:title="orgProps.title" | |||||
:type="orgProps.type" | |||||
:default-props="orgProps.defaultProps" | |||||
:params="orgProps.params" | |||||
@close="closeOrg" | |||||
@get-select-unit="getOrgData" | |||||
/> | |||||
</template> |
@@ -0,0 +1,263 @@ | |||||
<script name="projectCollectionEnterOtherMaterials" setup> | |||||
import { ref, watch } from 'vue' | |||||
import { fileFormatVerification, handleFileError, handleFileSuccess, handleFilePreview, reviewFileParam, fileTypes, fileDesc } from '@/utils/uploadAction' | |||||
import store from '@/store' | |||||
const props = defineProps({ | |||||
detail: { | |||||
type: Object | |||||
}, | |||||
data: { | |||||
type: Object | |||||
} | |||||
}), | |||||
uploadUrl = store.dictStore.uploadUrl, | |||||
formRef = ref(), | |||||
formData = ref({ | |||||
feasibilityStudyReport: [], | |||||
approvedFile: [], | |||||
purchaseFile: [], | |||||
acceptanceLetter: [], | |||||
purchaseContract: [], | |||||
acceptanceReport: [], | |||||
changeApprovalDoc: [] | |||||
}), | |||||
fileRule = [{ required: true, message: '请选择文件' }], | |||||
rules = { | |||||
feasibilityStudyReport: fileRule, | |||||
approvedFile: fileRule, | |||||
purchaseFile: fileRule, | |||||
acceptanceLetter: fileRule, | |||||
purchaseContract: fileRule, | |||||
acceptanceReport: fileRule, | |||||
changeApprovalDoc: fileRule, | |||||
constructionOrg: [{ required: true, message: '请填写承建单位' }], | |||||
constructionOrgCreditCode: [{ required: true, message: '请填写承建单位统一信用代码' }] | |||||
} | |||||
defineExpose({ formRef, formData }) | |||||
watch(() => props.detail, val => { | |||||
if (val) { | |||||
formData.value = { | |||||
feasibilityStudyReport: reviewFileParam(JSON.parse(val.feasibilityStudyReport)), | |||||
approvedFile: reviewFileParam(JSON.parse(val.approvedFile)), | |||||
purchaseFile: reviewFileParam(JSON.parse(val.purchaseFile)), | |||||
acceptanceLetter: reviewFileParam(JSON.parse(val.acceptanceLetter)), | |||||
purchaseContract: reviewFileParam(JSON.parse(val.purchaseContract)), | |||||
acceptanceReport: reviewFileParam(JSON.parse(val.acceptanceReport)), | |||||
changeApprovalDoc: reviewFileParam(JSON.parse(val.changeApprovalDoc)), | |||||
constructionOrg: val.constructionOrg, | |||||
constructionOrgCreditCode: val.constructionOrgCreditCode, | |||||
supervisorOrg: val.supervisorOrg, | |||||
supervisorOrgCreditCode: val.supervisorOrgCreditCode | |||||
} | |||||
} | |||||
}) | |||||
watch(() => props.data, val => { | |||||
}, | |||||
{ immediate: true, deep: true }) | |||||
</script> | |||||
<template> | |||||
<el-form | |||||
ref="formRef" | |||||
:model="formData" | |||||
:rules="rules" | |||||
label-position="top" | |||||
label-suffix=":" | |||||
scroll-to-error | |||||
> | |||||
<el-row :gutter="40"> | |||||
<el-col :span="24"> | |||||
<el-form-item | |||||
label="可行性研究报告(建设方案、运维方案)" | |||||
:prop="props.data.status===1||props.data.status===2?'':'feasibilityStudyReport'" | |||||
> | |||||
<el-upload | |||||
v-model:file-list="formData.feasibilityStudyReport" | |||||
class="w-full" | |||||
:action="uploadUrl" | |||||
:on-success="res => handleFileSuccess(res, formData.feasibilityStudyReport)" | |||||
:on-error="handleFileError" | |||||
:before-upload="file=>fileFormatVerification(file, {types: fileTypes})" | |||||
:accept="fileTypes.map(i=>`.${i}`).join(',')" | |||||
multiple | |||||
:limit="10" | |||||
:on-preview="handleFilePreview" | |||||
> | |||||
<el-button type="primary" class="mr-4">上传文件</el-button> | |||||
<template #tip> | |||||
<div class="el-upload__tip">支持{{ fileDesc }}文件</div> | |||||
</template> | |||||
</el-upload> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<el-form-item | |||||
label="立项批复文件" | |||||
prop="approvedFile" | |||||
> | |||||
<el-upload | |||||
v-model:file-list="formData.approvedFile" | |||||
class="w-full" | |||||
:action="uploadUrl" | |||||
:on-success="res => handleFileSuccess(res, formData.approvedFile)" | |||||
:on-error="handleFileError" | |||||
:before-upload="file=>fileFormatVerification(file, {types: fileTypes})" | |||||
:accept="fileTypes.map(i=>`.${i}`).join(',')" | |||||
multiple | |||||
:limit="10" | |||||
:on-preview="handleFilePreview" | |||||
> | |||||
<el-button type="primary" class="mr-4">上传文件</el-button> | |||||
<template #tip> | |||||
<div class="el-upload__tip">支持{{ fileDesc }}文件</div> | |||||
</template> | |||||
</el-upload> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<el-form-item | |||||
label="采购文件" | |||||
prop="purchaseFile" | |||||
> | |||||
<el-upload | |||||
v-model:file-list="formData.purchaseFile" | |||||
class="w-full" | |||||
:action="uploadUrl" | |||||
:on-success="res => handleFileSuccess(res, formData.purchaseFile)" | |||||
:on-error="handleFileError" | |||||
:before-upload="file=>fileFormatVerification(file, {types: fileTypes})" | |||||
:accept="fileTypes.map(i=>`.${i}`).join(',')" | |||||
multiple | |||||
:limit="10" | |||||
:on-preview="handleFilePreview" | |||||
> | |||||
<el-button type="primary" class="mr-4">上传文件</el-button> | |||||
<template #tip> | |||||
<div class="el-upload__tip">支持{{ fileDesc }}文件</div> | |||||
</template> | |||||
</el-upload> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<el-form-item | |||||
label="中标通知书" | |||||
prop="acceptanceLetter" | |||||
> | |||||
<el-upload | |||||
v-model:file-list="formData.acceptanceLetter" | |||||
class="w-full" | |||||
:action="uploadUrl" | |||||
:on-success="res => handleFileSuccess(res, formData.acceptanceLetter)" | |||||
:on-error="handleFileError" | |||||
:before-upload="file=>fileFormatVerification(file, {types: fileTypes})" | |||||
:accept="fileTypes.map(i=>`.${i}`).join(',')" | |||||
multiple | |||||
:limit="10" | |||||
:on-preview="handleFilePreview" | |||||
> | |||||
<el-button type="primary" class="mr-4">上传文件</el-button> | |||||
<template #tip> | |||||
<div class="el-upload__tip">支持{{ fileDesc }}文件</div> | |||||
</template> | |||||
</el-upload> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<el-form-item | |||||
label="采购合同" | |||||
prop="purchaseContract" | |||||
> | |||||
<el-upload | |||||
v-model:file-list="formData.purchaseContract" | |||||
class="w-full" | |||||
:action="uploadUrl" | |||||
:on-success="res => handleFileSuccess(res, formData.purchaseContract)" | |||||
:on-error="handleFileError" | |||||
:before-upload="file=>fileFormatVerification(file, {types: fileTypes})" | |||||
:accept="fileTypes.map(i=>`.${i}`).join(',')" | |||||
multiple | |||||
:limit="10" | |||||
:on-preview="handleFilePreview" | |||||
> | |||||
<el-button type="primary" class="mr-4">上传文件</el-button> | |||||
<template #tip> | |||||
<div class="el-upload__tip">支持{{ fileDesc }}文件</div> | |||||
</template> | |||||
</el-upload> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<el-form-item | |||||
label="验收报告" | |||||
prop="acceptanceReport" | |||||
> | |||||
<el-upload | |||||
v-model:file-list="formData.acceptanceReport" | |||||
class="w-full" | |||||
:action="uploadUrl" | |||||
:on-success="res => handleFileSuccess(res, formData.acceptanceReport)" | |||||
:on-error="handleFileError" | |||||
:before-upload="file=>fileFormatVerification(file, {types: fileTypes})" | |||||
:accept="fileTypes.map(i=>`.${i}`).join(',')" | |||||
multiple | |||||
:limit="10" | |||||
:on-preview="handleFilePreview" | |||||
> | |||||
<el-button type="primary" class="mr-4">上传文件</el-button> | |||||
<template #tip> | |||||
<div class="el-upload__tip">支持{{ fileDesc }}文件</div> | |||||
</template> | |||||
</el-upload> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<el-form-item | |||||
label="变更批复文件" | |||||
prop="changeApprovalDoc" | |||||
> | |||||
<el-upload | |||||
v-model:file-list="formData.changeApprovalDoc" | |||||
class="w-full" | |||||
:action="uploadUrl" | |||||
:on-success="res => handleFileSuccess(res, formData.changeApprovalDoc)" | |||||
:on-error="handleFileError" | |||||
:before-upload="file=>fileFormatVerification(file, {types: fileTypes})" | |||||
:accept="fileTypes.map(i=>`.${i}`).join(',')" | |||||
multiple | |||||
:limit="10" | |||||
:on-preview="handleFilePreview" | |||||
> | |||||
<el-button type="primary" class="mr-4">上传文件</el-button> | |||||
<template #tip> | |||||
<div class="el-upload__tip">支持{{ fileDesc }}文件</div> | |||||
</template> | |||||
</el-upload> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="6"> | |||||
<el-form-item label="承建单位" :prop="props.data.status===3||props.data.status===4||props.data.status===6?'constructionOrg':''"> | |||||
<el-input v-model="formData.constructionOrg" maxlength="50" placeholder="请填写" /> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="6"> | |||||
<el-form-item label="承建单位统一信用代码" :prop="props.data.status===3||props.data.status===4||props.data.status===6?'constructionOrgCreditCode':''"> | |||||
<el-input v-model="formData.constructionOrgCreditCode" maxlength="50" placeholder="请填写" /> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="6"> | |||||
<el-form-item label="监理单位" prop="supervisorOrg"> | |||||
<el-input v-model="formData.supervisorOrg" maxlength="50" placeholder="请填写" /> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="6"> | |||||
<el-form-item label="监理单位统一信用代码" prop="supervisorOrgCreditCode"> | |||||
<el-input v-model="formData.supervisorOrgCreditCode" maxlength="50" placeholder="请填写" /> | |||||
</el-form-item> | |||||
</el-col> | |||||
</el-row> | |||||
</el-form> | |||||
</template> |
@@ -0,0 +1,69 @@ | |||||
<script name="projectCollectionEnterProgressInfo" setup> | |||||
import { ref, watch } from 'vue' | |||||
import store from '@/store' | |||||
const props = defineProps({ | |||||
detail: { | |||||
type: Object | |||||
} | |||||
}), | |||||
{ baseProjSetProgOptions } = store.dictStore.globalDicts || {}, | |||||
formRef = ref(), | |||||
formData = ref({}), | |||||
rules = { | |||||
status: [{ required: true, message: '请选择项目状态', trigger: 'change' }] | |||||
} | |||||
defineExpose({ formRef, formData }) | |||||
watch(() => props.detail, val => { | |||||
console.log(val) | |||||
if (val) { | |||||
formData.value = { | |||||
status: val.status, | |||||
applicationName: val.applicationName, | |||||
applicationIrsCode: val.applicationIrsCode | |||||
} | |||||
} | |||||
}) | |||||
</script> | |||||
<template> | |||||
<el-form | |||||
ref="formRef" | |||||
:model="formData" | |||||
:rules="rules" | |||||
label-position="top" | |||||
label-suffix=":" | |||||
scroll-to-error | |||||
> | |||||
<el-row :gutter="40"> | |||||
<el-col :span="8"> | |||||
<el-form-item label="项目状态" prop="status"> | |||||
<el-select | |||||
v-model="formData.status" | |||||
class="w-full" | |||||
placeholder="请选择" | |||||
clearable | |||||
> | |||||
<el-option | |||||
v-for="(v,k) in baseProjSetProgOptions" | |||||
:key="k" | |||||
:label="v" | |||||
:value="k*1" | |||||
/> | |||||
</el-select> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<el-form-item label="关联应用" prop="applicationName"> | |||||
<el-input v-model="formData.applicationName" maxlength="50" placeholder="请填写" /> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<el-form-item label="关联应用IRS编码" prop="applicationIrsCode"> | |||||
<el-input v-model="formData.applicationIrsCode" maxlength="50" placeholder="请填写" /> | |||||
</el-form-item> | |||||
</el-col> | |||||
</el-row> | |||||
</el-form> | |||||
</template> |
@@ -0,0 +1,365 @@ | |||||
<script name="projectApprovalInfo" setup> | |||||
import { ref, watch } from 'vue' | |||||
import { fileFormatVerification, handleFileError, handleFileSuccess, handleFilePreview, reviewFileParam, fileTypes, fileDesc } from '@/utils/uploadAction' | |||||
import store from '@/store' | |||||
const props = defineProps({ | |||||
detail: { | |||||
type: Object | |||||
}, | |||||
basicInfoData: { | |||||
type: Object | |||||
}, | |||||
dictionaryList: { | |||||
type: Array, | |||||
default: () => [] | |||||
} | |||||
}), | |||||
uploadUrl = store.dictStore.uploadUrl, | |||||
formRef = ref(), | |||||
formData = ref({ | |||||
}), | |||||
currentRules = ref([]) | |||||
defineExpose({ formRef, formData }) | |||||
watch(() => props.detail, val => { | |||||
if (val) { | |||||
formData.value = { | |||||
...val.approve, | |||||
baseReviewCommentsFile: val.approve?.baseReviewCommentsFile && reviewFileParam(JSON.parse(val.approve.baseReviewCommentsFile)) || [], | |||||
approvalFile: val.approve?.approvalFile && reviewFileParam(JSON.parse(val.approve.approvalFile)) || [], | |||||
preliminaryDesignScheme: val.approve?.preliminaryDesignScheme && reviewFileParam(JSON.parse(val.approve.preliminaryDesignScheme)) || [], | |||||
preliminaryDesignFile: val.approve?.preliminaryDesignFile && reviewFileParam(JSON.parse(val.approve.preliminaryDesignFile)) || [] | |||||
} | |||||
} | |||||
}) | |||||
const fileRule = [{ required: true, message: '请上传' }], | |||||
emits = defineEmits(['getApprovalInfoData']) | |||||
watch(() => props.basicInfoData, val => { | |||||
if (val?.baseProjIsConfidentiality === '02') { | |||||
currentRules.value = {} | |||||
} else { | |||||
currentRules.value = { | |||||
baseReviewResults: [{ required: true, message: '请选择评审结果' }], | |||||
equalProtectionLevel: [{ required: true, message: '请选择等保定级' }], | |||||
baseReviewOpinion: [{ required: true, message: '请填写评审意见' }], | |||||
baseReviewCommentsFile: fileRule, | |||||
approvalFile: fileRule, | |||||
baseExpertTotalMoney: [{ required: true, message: '请填写建议总投资' }], | |||||
baseExpertYearMoney: [{ required: true, message: '请填写建议年度预算' }], | |||||
baseInitialReviewTotalMoney: [{ required: true, message: '请填写建议批复总投资' }], | |||||
baseProjReplyAmount: [{ required: true, message: '请填写建议批复年度预算' }], | |||||
releaseYearMoney: [{ required: true, message: '请填写年度预算下达金额' }], | |||||
preliminaryDesignScheme: fileRule, | |||||
preliminaryDesignFile: fileRule | |||||
} | |||||
} | |||||
formRef.value?.clearValidate() | |||||
}, { deep: true, immediate: true }) | |||||
watch(() => formData.value, val => { | |||||
emits('getApprovalInfoData', val) | |||||
}, { deep: true }) | |||||
</script> | |||||
<template> | |||||
<el-form | |||||
ref="formRef" | |||||
:model="formData" | |||||
:rules="currentRules" | |||||
label-position="top" | |||||
label-suffix=":" | |||||
scroll-to-error | |||||
:validate-on-rule-change="false" | |||||
> | |||||
<el-row :gutter="40"> | |||||
<el-col v-if="basicInfoData?.baseProjSetProg!=='01'" :span="8"> | |||||
<el-form-item label="评审结果" prop="baseReviewResults"> | |||||
<el-select v-model="formData.baseReviewResults" class="w-full"> | |||||
<el-option | |||||
v-for="(item,index) in dictionaryList?.filter(i => i.type === 'REVIEW_RESULTS')" | |||||
:key="index" | |||||
:label="item.label" | |||||
:value="item.value" | |||||
/> | |||||
</el-select> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col v-if="basicInfoData?.baseProjIsConfidentiality === '01'&&!['01','02','03'].includes(basicInfoData?.baseProjSetProg)" :span="8"> | |||||
<el-form-item | |||||
v-if="basicInfoData?.baseConstructionType?.includes('01')&&basicInfoData?.baseProjSetProg!=='04'" | |||||
key="equalProtectionLevel1" | |||||
label="等保定级" | |||||
prop="equalProtectionLevel" | |||||
> | |||||
<el-select v-model="formData.equalProtectionLevel" class="w-full"> | |||||
<el-option | |||||
v-for="(item,index) in dictionaryList?.filter(i => i.type === 'EQUAL_PROTECTION_RATING')" | |||||
:key="index" | |||||
:label="item.label" | |||||
:value="item.value" | |||||
/> | |||||
</el-select> | |||||
</el-form-item> | |||||
<el-form-item | |||||
v-else | |||||
key="equalProtectionLevel2" | |||||
label="等保定级" | |||||
> | |||||
<el-select v-model="formData.equalProtectionLevel" class="w-full"> | |||||
<el-option | |||||
v-for="(item,index) in dictionaryList?.filter(i => i.type === 'EQUAL_PROTECTION_RATING')" | |||||
:key="index" | |||||
:label="item.label" | |||||
:value="item.value" | |||||
/> | |||||
</el-select> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col v-if="basicInfoData?.baseProjSetProg!=='01'" :span="24"> | |||||
<el-form-item label="评审意见" prop="baseReviewOpinion"> | |||||
<el-input | |||||
v-model="formData.baseReviewOpinion" | |||||
type="textarea" | |||||
show-word-limit | |||||
:maxlength="500" | |||||
placeholder="请填写" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col v-if="basicInfoData?.baseProjSetProg!=='01'" :span="8"> | |||||
<el-form-item | |||||
label="评审意见附件" | |||||
prop="baseReviewCommentsFile" | |||||
> | |||||
<el-upload | |||||
v-model:file-list="formData.baseReviewCommentsFile" | |||||
class="w-full" | |||||
:action="uploadUrl" | |||||
:on-success="res => handleFileSuccess(res, formData.baseReviewCommentsFile)" | |||||
:on-error="handleFileError" | |||||
:before-upload="file=>fileFormatVerification(file, {types: fileTypes})" | |||||
:accept="fileTypes.map(i=>`.${i}`).join(',')" | |||||
multiple | |||||
:limit="10" | |||||
:on-preview="handleFilePreview" | |||||
> | |||||
<el-button type="primary" class="mr-4">上传文件</el-button> | |||||
<template #tip> | |||||
<div class="el-upload__tip">支持{{ fileDesc }}文件</div> | |||||
</template> | |||||
</el-upload> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col v-if="!['01','02','03'].includes(basicInfoData?.baseProjSetProg)" :span="8"> | |||||
<el-form-item | |||||
label="立项批复文件" | |||||
prop="approvalFile" | |||||
> | |||||
<el-upload | |||||
v-model:file-list="formData.approvalFile" | |||||
class="w-full" | |||||
:action="uploadUrl" | |||||
:on-success="res => handleFileSuccess(res, formData.approvalFile)" | |||||
:on-error="handleFileError" | |||||
:before-upload="file=>fileFormatVerification(file, {types: fileTypes})" | |||||
:accept="fileTypes.map(i=>`.${i}`).join(',')" | |||||
multiple | |||||
:limit="10" | |||||
:on-preview="handleFilePreview" | |||||
> | |||||
<el-button type="primary" class="mr-4">上传文件</el-button> | |||||
<template #tip> | |||||
<div class="el-upload__tip">支持{{ fileDesc }}文件</div> | |||||
</template> | |||||
</el-upload> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col v-if="!['01','03'].includes(basicInfoData?.baseProjSetProg)" :span="8"> | |||||
<el-form-item label="建议总投资" prop="baseExpertTotalMoney"> | |||||
<el-input-number | |||||
v-model="formData.baseExpertTotalMoney" | |||||
class="input-amount" | |||||
placeholder="请填写" | |||||
:min="0.000001" | |||||
:controls="false" | |||||
@mousewheel.prevent | |||||
> | |||||
<template #suffix>万元</template> | |||||
</el-input-number> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col v-if="!['01','03'].includes(basicInfoData?.baseProjSetProg)" :span="8"> | |||||
<el-form-item label="建议年度预算" prop="baseExpertYearMoney"> | |||||
<el-input-number | |||||
v-model="formData.baseExpertYearMoney" | |||||
class="input-amount" | |||||
placeholder="请填写" | |||||
:min="0.000001" | |||||
:controls="false" | |||||
@mousewheel.prevent | |||||
> | |||||
<template #suffix>万元</template> | |||||
</el-input-number> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col v-if="!['01','02','03'].includes(basicInfoData?.baseProjSetProg)" :span="8"> | |||||
<el-form-item label="建议批复总投资" prop="baseInitialReviewTotalMoney"> | |||||
<el-input-number | |||||
v-model="formData.baseInitialReviewTotalMoney" | |||||
class="input-amount" | |||||
placeholder="请填写" | |||||
:min="0.000001" | |||||
:controls="false" | |||||
@mousewheel.prevent | |||||
> | |||||
<template #suffix>万元</template> | |||||
</el-input-number> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col v-if="!['01','02','03'].includes(basicInfoData?.baseProjSetProg)" :span="8"> | |||||
<el-form-item label="建议批复年度预算" prop="baseProjReplyAmount"> | |||||
<el-input-number | |||||
v-model="formData.baseProjReplyAmount" | |||||
class="input-amount" | |||||
placeholder="请填写" | |||||
:min="0.000001" | |||||
:controls="false" | |||||
@mousewheel.prevent | |||||
> | |||||
<template #suffix>万元</template> | |||||
</el-input-number> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col v-if="['05','06','07','00'].includes(basicInfoData?.baseProjSetProg)" :span="8"> | |||||
<el-form-item label="年度预算下达金额" prop="releaseYearMoney"> | |||||
<el-input-number | |||||
v-model="formData.releaseYearMoney" | |||||
class="input-amount" | |||||
placeholder="请填写" | |||||
:min="0.000001" | |||||
:controls="false" | |||||
@mousewheel.prevent | |||||
> | |||||
<template #suffix>万元</template> | |||||
</el-input-number> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col v-if="formData.baseProjReplyAmount>=5000&&['04','05','06','07','00'].includes(basicInfoData?.baseProjSetProg)" :span="8"> | |||||
<el-form-item | |||||
v-if="basicInfoData?.baseProjSetProg!=='04'" | |||||
key="preliminaryDesignScheme1" | |||||
label="初步设计方案" | |||||
prop="preliminaryDesignScheme" | |||||
> | |||||
<el-upload | |||||
v-model:file-list="formData.preliminaryDesignScheme" | |||||
class="w-full" | |||||
:action="uploadUrl" | |||||
:on-success="res => handleFileSuccess(res, formData.preliminaryDesignScheme)" | |||||
:on-error="handleFileError" | |||||
:before-upload="file=>fileFormatVerification(file, {types: fileTypes})" | |||||
:accept="fileTypes.map(i=>`.${i}`).join(',')" | |||||
multiple | |||||
:limit="10" | |||||
> | |||||
<el-button type="primary" class="mr-4">上传文件</el-button> | |||||
<template #tip> | |||||
<div class="el-upload__tip">支持{{ fileDesc }}文件</div> | |||||
</template> | |||||
</el-upload> | |||||
</el-form-item> | |||||
<el-form-item | |||||
v-else | |||||
key="preliminaryDesignScheme2" | |||||
label="初步设计方案" | |||||
> | |||||
<el-upload | |||||
v-model:file-list="formData.preliminaryDesignScheme" | |||||
class="w-full" | |||||
:action="uploadUrl" | |||||
:on-success="res => handleFileSuccess(res, formData.preliminaryDesignScheme)" | |||||
:on-error="handleFileError" | |||||
:before-upload=" | |||||
file => | |||||
fileFormatVerification(file, { | |||||
types: [ | |||||
'application/pdf', | |||||
] | |||||
}) | |||||
" | |||||
accept=".pdf" | |||||
multiple | |||||
:limit="10" | |||||
> | |||||
<el-button type="primary" class="mr-4">上传文件</el-button> | |||||
<template #tip> | |||||
<div class="el-upload__tip">支持格式:pdf</div> | |||||
</template> | |||||
</el-upload> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col v-if="formData.baseProjReplyAmount>=5000&&['04','05','06','07','00'].includes(basicInfoData?.baseProjSetProg)" :span="8"> | |||||
<el-form-item | |||||
v-if="basicInfoData?.baseProjSetProg!=='04'" | |||||
key="preliminaryDesignFile1" | |||||
label="初步设计方案批复函" | |||||
prop="preliminaryDesignFile" | |||||
> | |||||
<el-upload | |||||
v-model:file-list="formData.preliminaryDesignFile" | |||||
class="w-full" | |||||
:action="uploadUrl" | |||||
:on-success="res => handleFileSuccess(res, formData.preliminaryDesignFile)" | |||||
:on-error="handleFileError" | |||||
:before-upload=" | |||||
file => | |||||
fileFormatVerification(file, { | |||||
types: [ | |||||
'application/pdf', | |||||
] | |||||
}) | |||||
" | |||||
accept=".pdf" | |||||
multiple | |||||
:limit="10" | |||||
> | |||||
<el-button type="primary" class="mr-4">上传文件</el-button> | |||||
<template #tip> | |||||
<div class="el-upload__tip">支持格式:pdf</div> | |||||
</template> | |||||
</el-upload> | |||||
</el-form-item> | |||||
<el-form-item | |||||
v-else | |||||
key="preliminaryDesignFile2" | |||||
label="初步设计方案批复函" | |||||
> | |||||
<el-upload | |||||
v-model:file-list="formData.preliminaryDesignFile" | |||||
class="w-full" | |||||
:action="uploadUrl" | |||||
:on-success="res => handleFileSuccess(res, formData.preliminaryDesignFile)" | |||||
:on-error="handleFileError" | |||||
:before-upload=" | |||||
file => | |||||
fileFormatVerification(file, { | |||||
types: [ | |||||
'application/pdf', | |||||
] | |||||
}) | |||||
" | |||||
accept=".pdf" | |||||
multiple | |||||
:limit="10" | |||||
> | |||||
<el-button type="primary" class="mr-4">上传文件</el-button> | |||||
<template #tip> | |||||
<div class="el-upload__tip">支持格式:pdf</div> | |||||
</template> | |||||
</el-upload> | |||||
</el-form-item> | |||||
</el-col> | |||||
</el-row> | |||||
</el-form> | |||||
</template> | |||||
@@ -0,0 +1,198 @@ | |||||
<script setup name="projectContentDialog"> | |||||
import { ref, watch } from 'vue' | |||||
const | |||||
props = defineProps({ | |||||
visible: { | |||||
type: Boolean, | |||||
default: false, | |||||
required: true | |||||
}, | |||||
data: Object | |||||
}), | |||||
form = ref({ | |||||
perIndicator: [] | |||||
}), | |||||
formRef = ref(), | |||||
rules = { | |||||
mainContent: [{ required: true, message: '请输入项目主要内容' }], | |||||
businessObject: [{ required: true, message: '请输入业务对象' }], | |||||
perIndicator: [{ required: true, message: '请至少添加一个预期成效指标' }] | |||||
}, | |||||
column = [ | |||||
{ | |||||
label: '预期成效指标名称', | |||||
key: 'name', | |||||
slot: 'name', | |||||
width: 140 | |||||
}, | |||||
{ | |||||
label: '符号', | |||||
key: 'symbol', | |||||
slot: 'symbol' | |||||
}, | |||||
{ | |||||
label: '数值', | |||||
key: 'nums', | |||||
slot: 'nums' | |||||
}, | |||||
{ | |||||
label: '单位', | |||||
key: 'unit', | |||||
slot: 'unit' | |||||
}, | |||||
{ | |||||
label: '操作', | |||||
key: 'action', | |||||
slot: 'action', | |||||
width: 70 | |||||
} | |||||
], | |||||
// 添加 | |||||
add = () => { | |||||
form.value.perIndicator.push({}) | |||||
}, | |||||
del = (index) => { | |||||
form.value.perIndicator.splice(index, 1) | |||||
}, | |||||
submit = async (formEl) => { | |||||
if (!formEl) { | |||||
return | |||||
} | |||||
await formEl.validate(async (valid) => { | |||||
if (valid) { | |||||
const data = JSON.parse(JSON.stringify(form.value)) | |||||
emits('setContent', data) | |||||
emits('close', true) | |||||
} | |||||
}) | |||||
}, | |||||
emits = defineEmits(['close', 'setContent']) | |||||
watch( | |||||
() => props.visible, | |||||
async (val) => { | |||||
if (val && props.data) { | |||||
form.value = JSON.parse(JSON.stringify(props.data)) | |||||
} else { | |||||
formRef.value?.resetFields() | |||||
form.value = { | |||||
perIndicator: [] | |||||
} | |||||
} | |||||
} | |||||
) | |||||
</script> | |||||
<template> | |||||
<el-dialog | |||||
:model-value="visible" | |||||
title="添加" | |||||
:size="840" | |||||
@close="emits('close')" | |||||
> | |||||
<el-form | |||||
ref="formRef" | |||||
label-suffix=":" | |||||
:model="form" | |||||
:rules="rules" | |||||
label-width="160" | |||||
> | |||||
<el-form-item label="项目主要内容" prop="mainContent"> | |||||
<el-input | |||||
v-model="form.mainContent" | |||||
placeholder="请输入" | |||||
maxlength="100" | |||||
/> | |||||
</el-form-item> | |||||
<el-form-item label="业务对象" prop="businessObject"> | |||||
<el-input | |||||
v-model="form.businessObject" | |||||
placeholder="请输入" | |||||
maxlength="100" | |||||
/> | |||||
</el-form-item> | |||||
<el-button | |||||
type="primary" | |||||
plain | |||||
icon="Plus" | |||||
class="w-full mb-8" | |||||
@click="add" | |||||
>添加 | |||||
</el-button> | |||||
<table-list | |||||
:pagination="false" | |||||
:column="column" | |||||
:empty-temp="false" | |||||
:data="form.perIndicator" | |||||
> | |||||
<template #name="{scope}"> | |||||
<el-form-item | |||||
v-if="scope.$index>=0" | |||||
:prop="`perIndicator[${scope.$index}].name`" | |||||
:rules="[{required:true,message:' '}]" | |||||
label-width="0" | |||||
style="margin-bottom: 0" | |||||
> | |||||
<el-input | |||||
v-model="form.perIndicator[scope.$index].name" | |||||
placeholder="请输入" | |||||
maxlength="50" | |||||
/> | |||||
</el-form-item> | |||||
</template> | |||||
<template #symbol="{scope}"> | |||||
<el-form-item | |||||
v-if="scope.$index>=0" | |||||
:prop="`perIndicator[${scope.$index}].symbol`" | |||||
label-width="0" | |||||
style="margin-bottom: 0" | |||||
> | |||||
<el-select v-model="form.perIndicator[scope.$index].symbol"> | |||||
<el-option label="等于" value="等于" /> | |||||
<el-option label="大于" value="大于" /> | |||||
<el-option label="大于等于" value="大于等于" /> | |||||
<el-option label="小于" value="小于" /> | |||||
<el-option label="小于等于" value="小于等于" /> | |||||
</el-select> | |||||
</el-form-item> | |||||
</template> | |||||
<template #nums="{scope}"> | |||||
<el-form-item | |||||
v-if="scope.$index>=0" | |||||
:prop="`perIndicator[${scope.$index}].nums`" | |||||
label-width="0" | |||||
style="margin-bottom: 0" | |||||
> | |||||
<el-input-number | |||||
v-model="form.perIndicator[scope.$index].nums" | |||||
:controls="false" | |||||
class="flex-1 mr-8" | |||||
placeholder="请输入" | |||||
@mousewheel.prevent | |||||
/> | |||||
</el-form-item> | |||||
</template> | |||||
<template #unit="{scope}"> | |||||
<el-form-item | |||||
v-if="scope.$index>=0" | |||||
:prop="`perIndicator[${scope.$index}].unit`" | |||||
label-width="0" | |||||
style="margin-bottom: 0" | |||||
> | |||||
<el-input | |||||
v-model="form.perIndicator[scope.$index].unit" | |||||
placeholder="请输入" | |||||
maxlength="10" | |||||
/> | |||||
</el-form-item> | |||||
</template> | |||||
<template #action="{scope}"> | |||||
<a class="text-danger cursor-pointer" @click="del(scope.$index)">移除</a> | |||||
</template> | |||||
</table-list> | |||||
</el-form> | |||||
<template #footer> | |||||
<el-button type="primary" @click="submit(formRef)">提交</el-button> | |||||
<el-button @click="emits('close')">取消</el-button> | |||||
</template> | |||||
</el-dialog> | |||||
</template> |
@@ -0,0 +1,716 @@ | |||||
<script name="projectCollectionEnterBasicInfo" setup> | |||||
import { reactive, ref, watch } from 'vue' | |||||
import RelatedProjectDialog from '@/pages/projectCollection/projectCollectionEnter/components/relatedProjectDialog.vue' | |||||
import ProjectContentDialog from '@/pages/projectCollection/projectCollectionEnter/components/projectContentDialog.vue' | |||||
import { reviewFileParam, fileFormatVerification, handleFileSuccess, handleFileError, handleFilePreview, fileTypes, fileDesc } from '@/utils/uploadAction' | |||||
import store from '@/store' | |||||
const props = defineProps({ | |||||
detail: { | |||||
type: Object | |||||
}, | |||||
basicInfoData: { | |||||
type: Object | |||||
}, | |||||
dictionaryList: { | |||||
type: Array, | |||||
default: () => [] | |||||
} | |||||
}), | |||||
uploadUrl = store.dictStore.uploadUrl, | |||||
// { budgetSourceOptions } = store.dictStore.globalDicts || {}, | |||||
formRef = ref(), | |||||
formData = ref({ | |||||
baseHistorProjs: [], | |||||
beseExpectedResults: [] | |||||
}), | |||||
currentRules = ref({ | |||||
baseProjTime: [{ required: true, message: '请选择项目起止时间' }], | |||||
baseProjSetYear: [{ required: true, message: '请选择预算年度' }], | |||||
baseProjTotalAmount: [{ required: true, message: '请填写项目总投资' }], | |||||
baseProjDeclAmount: [{ required: true, message: '请填写申报年度预算' }], | |||||
baseProjConsClass: [{ required: true, message: '请选择建设层级' }], | |||||
baseLowestLevel: [{ required: true, message: '请选择贯通层级' }], | |||||
baseProjAmountOri: [{ required: true, message: '请选择预算来源' }], | |||||
baseBasisAmountOri: [{ required: true, message: '请填写预算来源说明' }], | |||||
baseProjBasis: [{ required: true, message: '请选择立项依据' }], | |||||
baseBasisEstablish: [{ required: true, message: '请填写立项依据说明' }], | |||||
baseProjIntro: [{ required: true, message: '请填写项目概述' }], | |||||
beseExpectedResults: [{ required: true, message: '请至少添加一个项目内容与预期成效' }], | |||||
baseOperatMaintenFile: [{ required: true, message: '请上传' }], | |||||
baseHistorProjs: [{ required: true, message: '请关联项目', type: 'array' }], | |||||
baseProjApplyFile: [{ required: true, message: '请上传' }] | |||||
}), | |||||
column = [ | |||||
{ | |||||
label: '序号', | |||||
type: 'index', | |||||
width: 60 | |||||
}, | |||||
{ | |||||
label: '项目名称', | |||||
prop: 'baseProjName', | |||||
key: 'baseProjName' | |||||
}, | |||||
{ | |||||
label: '预算年度', | |||||
prop: 'baseProjSetYear', | |||||
key: 'baseProjSetYear' | |||||
}, | |||||
{ | |||||
label: '操作', | |||||
slot: 'action', | |||||
key: 'action' | |||||
} | |||||
], | |||||
// 立项依据 | |||||
buildBasisColumn = [ | |||||
{ | |||||
type: 'selection' | |||||
}, | |||||
{ | |||||
label: '依据项', | |||||
key: 'title', | |||||
prop: 'title' | |||||
}, | |||||
{ | |||||
label: '依据文件名', | |||||
slot: 'fileName' | |||||
}, | |||||
{ | |||||
label: '文件(支持word、pdf格式)', | |||||
slot: 'action', | |||||
width: 300 | |||||
} | |||||
], | |||||
buildBasisTableData = ref([ | |||||
{ | |||||
id: 1, | |||||
title: '政策、法规', | |||||
fileName: '', | |||||
fileList: [] | |||||
}, | |||||
{ | |||||
id: 2, | |||||
title: '规划或决策部署', | |||||
fileName: '', | |||||
fileList: [] | |||||
}, | |||||
{ | |||||
id: 3, | |||||
title: '上级下达任务', | |||||
fileName: '', | |||||
fileList: [] | |||||
}, | |||||
{ | |||||
id: 4, | |||||
title: '领导批示', | |||||
fileName: '', | |||||
fileList: [] | |||||
}, | |||||
{ | |||||
id: 5, | |||||
title: '单位核心业务或单位职能', | |||||
fileName: '', | |||||
fileList: [] | |||||
}, | |||||
{ | |||||
id: 6, | |||||
title: '其他', | |||||
fileName: '', | |||||
fileList: [] | |||||
} | |||||
]), | |||||
selectionChange = (val) => { | |||||
formData.value.baseProjBasis = val.map(i => i) | |||||
}, | |||||
column1 = [ | |||||
{ | |||||
label: '项目主要内容', | |||||
prop: 'mainContent', | |||||
key: 'mainContent' | |||||
}, | |||||
{ | |||||
label: '业务对象', | |||||
prop: 'businessObject', | |||||
key: 'businessObject' | |||||
}, | |||||
{ | |||||
label: '操作', | |||||
slot: 'action', | |||||
key: 'action' | |||||
} | |||||
], | |||||
// 关联项目 | |||||
relatedProjectDialogData = reactive({ | |||||
visible: false | |||||
}), | |||||
showRelatedProjectDialog = () => { | |||||
relatedProjectDialogData.visible = true | |||||
relatedProjectDialogData.data = formData.value.baseHistorProjs | |||||
}, | |||||
getProjectList = (data) => { | |||||
formData.value.baseHistorProjs = data.map(i => { | |||||
return { | |||||
baseProjName: i.projectName, | |||||
baseProjSetYear: i.projectYear, | |||||
baseProjId: i.id | |||||
} | |||||
}) | |||||
}, | |||||
delPro = (index) => { | |||||
formData.value.baseHistorProjs.splice(index, 1) | |||||
}, | |||||
// 项目内容与预期成效 | |||||
projectContentDialogData = reactive({ | |||||
visible: false, | |||||
data: undefined | |||||
}), | |||||
projectContentIndex = ref(), | |||||
showProjectContentDialog = (data, index) => { | |||||
projectContentDialogData.data = data | |||||
projectContentDialogData.visible = true | |||||
projectContentIndex.value = index | |||||
}, | |||||
setContent = (data) => { | |||||
if (projectContentIndex.value === undefined) { | |||||
formData.value.beseExpectedResults.push(data) | |||||
} else { | |||||
formData.value.beseExpectedResults[projectContentIndex.value] = data | |||||
} | |||||
}, | |||||
delProjectContent = (index) => { | |||||
formData.value.beseExpectedResults.splice(index, 1) | |||||
}, | |||||
emits = defineEmits(['getProYear']), | |||||
tableListRef = ref() | |||||
defineExpose({ formRef, formData }) | |||||
watch(() => props.dictionaryList, val => { | |||||
if (val) { | |||||
buildBasisTableData.value = [] | |||||
props.dictionaryList?.filter(i => i.type === 'PROJECT_BASIS').forEach(i => { | |||||
buildBasisTableData.value.push({ | |||||
title: i.label, | |||||
fileName: '', | |||||
fileList: [], | |||||
value: i.value | |||||
}) | |||||
}) | |||||
} | |||||
}) | |||||
watch(() => props.detail, val => { | |||||
if (val) { | |||||
formData.value = { | |||||
...val.apply, | |||||
baseProjTime: val.apply?.baseProjStartTime ? [val.apply?.baseProjStartTime.slice(0, 10), val.apply?.baseProjEndTime.slice(0, 10)] : [], | |||||
baseHistorProjs: val.apply?.baseHistorProjId?.split(';').map((i, k) => { | |||||
return { | |||||
baseProjId: i, | |||||
baseProjName: val.apply?.baseHistorProjName.split(';')[k], | |||||
baseProjSetYear: val.apply?.baseHistorProjYear.split(';')[k] | |||||
} | |||||
}) || [], | |||||
baseProjAmountOri: val.apply?.baseProjAmountOri && val.apply?.baseProjAmountOri?.split(';'), | |||||
baseProjBasis: val.apply?.baseProjBasis?.split(';')?.map((i, index) => { | |||||
const file = `[${val.apply?.baseProjBasisFile.replace(/}];/g, '}],')}]` | |||||
return { | |||||
title: buildBasisTableData.value?.find(j => j.value === i)?.title, | |||||
fileList: val.apply?.baseProjBasisFile ? reviewFileParam(JSON.parse(file)[index]) : [], | |||||
value: i | |||||
} | |||||
}), | |||||
beseExpectedResults: val.apply?.beseExpectedResults && JSON.parse(val.apply?.beseExpectedResults) || [], | |||||
baseProjApplyFile: val.apply?.baseProjApplyFile ? reviewFileParam(JSON.parse(val.apply.baseProjApplyFile)) : [], | |||||
baseOperatMaintenFile: val.apply?.baseOperatMaintenFile ? reviewFileParam(JSON.parse(val.apply.baseOperatMaintenFile)) : [], | |||||
baseProjOtherFile: val.apply?.baseProjOtherFile ? reviewFileParam(JSON.parse(val.apply.baseProjOtherFile)) : [] | |||||
} | |||||
const baseProjBasis = formData.value.baseProjBasis ? JSON.parse(JSON.stringify(formData.value.baseProjBasis)) : [] | |||||
if (val.apply?.baseProjBasis?.split(';')?.length) { | |||||
const dataIds = val.apply?.baseProjBasis?.split(';') | |||||
buildBasisTableData.value && buildBasisTableData.value.forEach(item => { | |||||
if (dataIds.includes(item.value)) { | |||||
item.fileList = baseProjBasis.find(i => i.value === item.value)?.fileList | |||||
item.fileName = baseProjBasis.find(i => i.value === item.value)?.fileName | |||||
tableListRef.value.toggleRowSelect(item, true) | |||||
} | |||||
}) | |||||
} | |||||
} | |||||
}) | |||||
watch(() => props.basicInfoData, val => { | |||||
if (val.baseProjIsConfidentiality === '02') { | |||||
currentRules.value = {} | |||||
} else { | |||||
currentRules.value = { | |||||
baseProjTime: [{ required: true, message: '请选择项目起止时间' }], | |||||
baseProjSetYear: [{ required: true, message: '请选择预算年度' }], | |||||
baseProjDeclAmount: [{ required: true, message: '请填写申报年度预算' }], | |||||
baseProjConsClass: [{ required: true, message: '请选择建设层级' }], | |||||
baseLowestLevel: [{ required: true, message: '请选择贯通层级' }], | |||||
baseProjAmountOri: [{ required: true, message: '请选择预算来源' }], | |||||
baseBasisAmountOri: [{ required: true, message: '请填写预算来源说明' }], | |||||
baseProjBasis: [{ required: true, message: '请选择立项依据' }], | |||||
baseBasisEstablish: [{ required: true, message: '请填写立项依据说明' }], | |||||
baseProjIntro: [{ required: true, message: '请填写项目概述' }], | |||||
beseExpectedResults: [{ required: true, message: '请至少添加一个项目内容与预期成效' }], | |||||
baseOperatMaintenFile: [{ required: true, message: '请上传' }], | |||||
baseHistorProjs: [{ required: true, message: '请关联项目', type: 'array' }], | |||||
baseProjApplyFile: [{ required: true, message: '请上传' }] | |||||
} | |||||
} | |||||
formRef.value?.clearValidate() | |||||
}, { deep: true }) | |||||
watch(() => formData.value.baseProjSetYear, val => { | |||||
emits('getProYear', val) | |||||
}) | |||||
</script> | |||||
<template> | |||||
<el-form | |||||
ref="formRef" | |||||
:model="formData" | |||||
:rules="currentRules" | |||||
label-position="top" | |||||
label-suffix=":" | |||||
scroll-to-error | |||||
:validate-on-rule-change="false" | |||||
> | |||||
<el-row :gutter="40"> | |||||
<el-col :span="8"> | |||||
<el-form-item label="发改编码" prop="baseDevelopCode"> | |||||
<el-input v-model="formData.baseDevelopCode" placeholder="请填写" /> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<el-form-item label="财政编码" prop="setProjCodeFinan"> | |||||
<el-input v-model="formData.setProjCodeFinan" placeholder="请填写" /> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<el-form-item label="项目起止时间" prop="baseProjTime"> | |||||
<el-date-picker | |||||
v-model="formData.baseProjTime" | |||||
type="daterange" | |||||
range-separator="-" | |||||
start-placeholder="开始时间" | |||||
end-placeholder="结束时间" | |||||
format="YYYY-MM-DD" | |||||
value-format="YYYY-MM-DD" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<el-form-item label="预算年度" prop="baseProjSetYear"> | |||||
<el-date-picker | |||||
v-model="formData.baseProjSetYear" | |||||
type="year" | |||||
placeholder="请选择" | |||||
format="YYYY" | |||||
value-format="YYYY" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<el-form-item label="项目总投资" prop="baseProjTotalAmount"> | |||||
<el-input-number | |||||
v-model="formData.baseProjTotalAmount" | |||||
placeholder="请填写" | |||||
:min="0.000001" | |||||
:controls="false" | |||||
class="input-amount" | |||||
@mousewheel.prevent | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<el-form-item | |||||
v-if="formData.baseProjSetYear*1>=2023" | |||||
key="baseProjDeclAmount1" | |||||
label="申报年度预算" | |||||
prop="baseProjDeclAmount" | |||||
> | |||||
<el-input-number | |||||
v-model="formData.baseProjDeclAmount" | |||||
placeholder="请填写" | |||||
:min="0.000001" | |||||
:controls="false" | |||||
class="input-amount" | |||||
@mousewheel.prevent | |||||
/> | |||||
</el-form-item> | |||||
<el-form-item v-else key="baseProjDeclAmount2" label="申报年度预算"> | |||||
<el-input-number | |||||
v-model="formData.baseProjDeclAmount" | |||||
placeholder="请填写" | |||||
:min="0.000001" | |||||
:controls="false" | |||||
class="input-amount" | |||||
@mousewheel.prevent | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<el-form-item label="建设层级" prop="baseProjConsClass"> | |||||
<el-select | |||||
v-model="formData.baseProjConsClass" | |||||
placeholder="请选择" | |||||
class="w-full" | |||||
> | |||||
<el-option | |||||
v-for="(item,index) in dictionaryList?.filter(i => i.type === 'BUILD_LEVEL')" | |||||
:key="index" | |||||
:label="item.label" | |||||
:value="item.value" | |||||
/> | |||||
</el-select> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col v-if="!(basicInfoData?.baseConstructionType?.includes('03')&&!basicInfoData?.baseConstructionType?.includes('01'))" :span="8"> | |||||
<el-form-item v-if="basicInfoData?.baseConstructionType?.includes('01')" label="贯通层级" prop="baseLowestLevel"> | |||||
<el-select | |||||
v-model="formData.baseLowestLevel" | |||||
placeholder="请选择" | |||||
class="w-full" | |||||
> | |||||
<el-option | |||||
v-for="(item,index) in dictionaryList?.filter(i => i.type === 'LINK_UP_LEVEL')" | |||||
:key="index" | |||||
:label="item.label" | |||||
:value="item.value" | |||||
/> | |||||
</el-select> | |||||
</el-form-item> | |||||
<el-form-item v-else label="贯通层级"> | |||||
<el-select | |||||
v-model="formData.baseLowestLevel" | |||||
placeholder="请选择" | |||||
class="w-full" | |||||
> | |||||
<el-option | |||||
v-for="(item,index) in dictionaryList?.filter(i => i.type === 'LINK_UP_LEVEL')" | |||||
:key="index" | |||||
:label="item.label" | |||||
:value="item.value" | |||||
/> | |||||
</el-select> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="24"> | |||||
<el-form-item v-if="!formData.missing" label="历年项目名称" prop="baseHistorProjs"> | |||||
<span class="text-[#666666]">是否缺失:</span> | |||||
<el-switch v-model="formData.missing" /> | |||||
<p class="text-right w-full mb-8"> | |||||
<el-button type="primary" @click="showRelatedProjectDialog">关联历年项目</el-button> | |||||
</p> | |||||
<table-list | |||||
:pagination="false" | |||||
style="width: 100%" | |||||
:column="column" | |||||
:data="formData.baseHistorProjs" | |||||
:empty-temp="false" | |||||
> | |||||
<template #action="{scope}"> | |||||
<a class="text-danger" @click="delPro(scope.$index)">删除</a> | |||||
</template> | |||||
</table-list> | |||||
</el-form-item> | |||||
<el-form-item v-else label="历年项目名称" prop="missing"> | |||||
<span class="text-[#666666]">是否缺失:</span> | |||||
<el-switch v-model="formData.missing" /> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="24"> | |||||
<el-form-item label="预算来源" prop="baseProjAmountOri"> | |||||
<el-checkbox-group v-model="formData.baseProjAmountOri"> | |||||
<el-checkbox | |||||
v-for="(item,index) in dictionaryList?.filter(i => i.type === 'BUDGET_SOURCE')" | |||||
:key="index" | |||||
:label="item.value" | |||||
> | |||||
{{ item.label }} | |||||
</el-checkbox> | |||||
</el-checkbox-group> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="24"> | |||||
<el-form-item v-if="formData.baseProjAmountOri?.includes('00')" label="预算来源说明" prop="baseBasisAmountOri"> | |||||
<el-input | |||||
v-model="formData.baseBasisAmountOri" | |||||
type="textarea" | |||||
show-word-limit | |||||
placeholder="请填写" | |||||
:maxlength="150" | |||||
/> | |||||
</el-form-item> | |||||
<el-form-item v-else label="预算来源说明"> | |||||
<el-input | |||||
v-model="formData.baseBasisAmountOri" | |||||
type="textarea" | |||||
show-word-limit | |||||
placeholder="请填写" | |||||
:maxlength="150" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="24"> | |||||
<el-form-item label="立项依据" prop="baseProjBasis"> | |||||
<table-list | |||||
ref="tableListRef" | |||||
:pagination="false" | |||||
style="width: 100%" | |||||
:column="buildBasisColumn" | |||||
:data="buildBasisTableData" | |||||
@selection-change="selectionChange" | |||||
> | |||||
<template #fileName="{scope}"> | |||||
<el-form-item v-if="formData.baseProjBasis&&formData.baseProjBasis.map(i=>i.value).includes(scope.row.value)"> | |||||
<el-input | |||||
:value="formData.baseProjBasis[formData.baseProjBasis.findIndex(i=>i.value===scope.row.value)]?.fileList?.[0]?.name" | |||||
placeholder="请输入" | |||||
:maxlength="50" | |||||
:disabled="true" | |||||
/> | |||||
</el-form-item> | |||||
<el-input v-else :disabled="true" /> | |||||
</template> | |||||
<template #action="{scope}"> | |||||
<el-form-item | |||||
v-if="formData.baseProjBasis&&formData.baseProjBasis.map(i=>i.value).includes(scope.row.value)" | |||||
class="basicUploadItem" | |||||
:rules="{required: true,message:'请上传'}" | |||||
:prop="`baseProjBasis[${formData.baseProjBasis.findIndex(i=>i.value===scope.row.value)}].fileList`" | |||||
> | |||||
<el-upload | |||||
ref="materialUploadRef" | |||||
v-model:file-list="formData.baseProjBasis[formData.baseProjBasis.findIndex(i=>i.value===scope.row.value)].fileList" | |||||
class="flex items-center flex-col w-full" | |||||
:action="uploadUrl" | |||||
:on-success="res => handleFileSuccess(res, formData.baseProjBasis[formData.baseProjBasis.findIndex(i=>i.value===scope.row.value)].fileList, true)" | |||||
:on-error="handleFileError" | |||||
:before-upload="file=>fileFormatVerification(file, {types: fileTypes})" | |||||
:accept="fileTypes.map(i=>`.${i}`).join(',')" | |||||
:limit="1" | |||||
:on-preview="handleFilePreview" | |||||
> | |||||
<template #trigger> | |||||
<div> | |||||
<a>上传</a> | |||||
</div> | |||||
</template> | |||||
</el-upload> | |||||
</el-form-item> | |||||
<span v-else class="text-info cursor-not-allowed">上传</span> | |||||
</template> | |||||
</table-list> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="24"> | |||||
<el-form-item label="立项依据说明" prop="baseBasisEstablish"> | |||||
<el-input | |||||
v-model="formData.baseBasisEstablish" | |||||
type="textarea" | |||||
show-word-limit | |||||
placeholder="请填写" | |||||
:maxlength="150" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="24"> | |||||
<el-form-item label="项目概述" prop="baseProjIntro"> | |||||
<el-input | |||||
v-model="formData.baseProjIntro" | |||||
type="textarea" | |||||
show-word-limit | |||||
placeholder="请填写" | |||||
:maxlength="2000" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="24"> | |||||
<el-form-item v-if="formData.baseProjSetYear*1>=2023" label="项目内容与预期成效" prop="beseExpectedResults"> | |||||
<table-list | |||||
:pagination="false" | |||||
style="width: 100%" | |||||
:column="column1" | |||||
:data="formData.beseExpectedResults" | |||||
:empty-temp="false" | |||||
> | |||||
<template #action="{scope}"> | |||||
<a @click="showProjectContentDialog(scope.row,scope.$index)">编辑</a> | |||||
<a class="text-danger" @click="delProjectContent(scope.$index)">删除</a> | |||||
</template> | |||||
</table-list> | |||||
<p class="text-right w-full mt-8"> | |||||
<el-button | |||||
type="primary" | |||||
class="w-full" | |||||
plain | |||||
icon="Plus" | |||||
@click="()=>showProjectContentDialog()" | |||||
>添加</el-button> | |||||
</p> | |||||
</el-form-item> | |||||
<el-form-item v-else label="项目内容与预期成效"> | |||||
<table-list | |||||
:pagination="false" | |||||
style="width: 100%" | |||||
:column="column1" | |||||
:data="formData.beseExpectedResults" | |||||
:empty-temp="false" | |||||
> | |||||
<template #action="{scope}"> | |||||
<a @click="showProjectContentDialog(scope.row,scope.$index)">编辑</a> | |||||
<a class="text-danger" @click="delProjectContent(scope.$index)">删除</a> | |||||
</template> | |||||
</table-list> | |||||
<p class="text-right w-full mt-8"> | |||||
<el-button | |||||
type="primary" | |||||
class="w-full" | |||||
plain | |||||
icon="Plus" | |||||
@click="()=>showProjectContentDialog()" | |||||
>添加</el-button> | |||||
</p> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<el-form-item | |||||
v-if="formData.baseProjSetYear*1<2023" | |||||
label="项目申报书" | |||||
> | |||||
<el-upload | |||||
v-model:file-list="formData.baseProjApplyFile" | |||||
class="w-full" | |||||
:action="uploadUrl" | |||||
:on-success="res => handleFileSuccess(res, formData.baseProjApplyFile)" | |||||
:on-error="handleFileError" | |||||
:before-upload="file=>fileFormatVerification(file, {types: fileTypes})" | |||||
:accept="fileTypes.map(i=>`.${i}`).join(',')" | |||||
:limit="1" | |||||
:on-preview="handleFilePreview" | |||||
> | |||||
<el-button type="primary" class="mr-4" plain>上传文件</el-button> | |||||
<template #tip> | |||||
<div class="el-upload__tip">支持{{ fileDesc }}文件</div> | |||||
</template> | |||||
</el-upload> | |||||
</el-form-item> | |||||
<el-form-item | |||||
v-else-if="formData.baseProjSetYear*1>=2023&&['01','02','04','05'].includes(basicInfoData?.baseProjType)" | |||||
label="项目申报书" | |||||
prop="baseProjApplyFile" | |||||
> | |||||
<el-upload | |||||
v-model:file-list="formData.baseProjApplyFile" | |||||
class="w-full" | |||||
:action="uploadUrl" | |||||
:on-success="res => handleFileSuccess(res, formData.baseProjApplyFile)" | |||||
:on-error="handleFileError" | |||||
:before-upload="file=>fileFormatVerification(file, {types: fileTypes})" | |||||
:accept="fileTypes.map(i=>`.${i}`).join(',')" | |||||
:limit="1" | |||||
:on-preview="handleFilePreview" | |||||
> | |||||
<el-button type="primary" class="mr-4" plain>上传文件</el-button> | |||||
<template #tip> | |||||
<div class="el-upload__tip">支持{{ fileDesc }}文件</div> | |||||
</template> | |||||
</el-upload> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col v-if="false" :span="8"> | |||||
<el-form-item | |||||
label="可行性研究报告" | |||||
prop="baseResearchReportFile" | |||||
> | |||||
<el-upload | |||||
v-model:file-list="formData.baseResearchReportFile" | |||||
class="w-full" | |||||
:action="uploadUrl" | |||||
:on-success="res => handleFileSuccess(res, formData.baseResearchReportFile)" | |||||
:on-error="handleFileError" | |||||
:before-upload="file=>fileFormatVerification(file, {types: fileTypes})" | |||||
:accept="fileTypes.map(i=>`.${i}`).join(',')" | |||||
:limit="1" | |||||
:on-preview="handleFilePreview" | |||||
> | |||||
<el-button type="primary" class="mr-4" plain>上传文件</el-button> | |||||
<template #tip> | |||||
<div class="el-upload__tip">支持{{ fileDesc }}文件</div> | |||||
</template> | |||||
</el-upload> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<el-form-item | |||||
label="运维方案" | |||||
prop="baseOperatMaintenFile" | |||||
> | |||||
<el-upload | |||||
v-model:file-list="formData.baseOperatMaintenFile" | |||||
class="w-full" | |||||
:action="uploadUrl" | |||||
:on-success="res => handleFileSuccess(res, formData.baseOperatMaintenFile)" | |||||
:on-error="handleFileError" | |||||
:before-upload="file=>fileFormatVerification(file, {types: fileTypes})" | |||||
:accept="fileTypes.map(i=>`.${i}`).join(',')" | |||||
:limit="1" | |||||
:on-preview="handleFilePreview" | |||||
> | |||||
<el-button type="primary" class="mr-4" plain>上传文件</el-button> | |||||
<template #tip> | |||||
<div class="el-upload__tip">支持{{ fileDesc }}文件</div> | |||||
</template> | |||||
</el-upload> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<el-form-item | |||||
label="其他附件" | |||||
> | |||||
<el-upload | |||||
v-model:file-list="formData.baseProjOtherFile" | |||||
class="w-full" | |||||
:action="uploadUrl" | |||||
:on-success="res => handleFileSuccess(res, formData.baseProjOtherFile)" | |||||
:on-error="handleFileError" | |||||
:before-upload="file=>fileFormatVerification(file, {types: fileTypes})" | |||||
:accept="fileTypes.map(i=>`.${i}`).join(',')" | |||||
multiple | |||||
:on-preview="handleFilePreview" | |||||
> | |||||
<el-button type="primary" class="mr-4" plain>上传文件</el-button> | |||||
<template #tip> | |||||
<div class="el-upload__tip">支持{{ fileDesc }}文件</div> | |||||
</template> | |||||
</el-upload> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="24"> | |||||
<el-form-item | |||||
label="备注" | |||||
> | |||||
<el-input | |||||
v-model="formData.baseProjRemark" | |||||
type="textarea" | |||||
placeholder="请输入" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
</el-row> | |||||
</el-form> | |||||
<related-project-dialog | |||||
:visible="relatedProjectDialogData.visible" | |||||
:data="relatedProjectDialogData.data" | |||||
@get-project-list="getProjectList" | |||||
@close="relatedProjectDialogData.visible=false" | |||||
/> | |||||
<project-content-dialog | |||||
:visible="projectContentDialogData.visible" | |||||
:data="projectContentDialogData.data" | |||||
@set-content="setContent" | |||||
@close="projectContentDialogData.visible=false" | |||||
/> | |||||
</template> |
@@ -0,0 +1,720 @@ | |||||
<script name="purchaseInfo" setup> | |||||
import { ref, watch } from 'vue' | |||||
import { fileFormatVerification, handleFileError, handleFileSuccess, handleFilePreview, reviewFileParam, fileTypes, fileDesc } from '@/utils/uploadAction' | |||||
import store from '@/store' | |||||
const props = defineProps({ | |||||
detail: { | |||||
type: Object | |||||
}, | |||||
basicInfoData: { | |||||
type: Object | |||||
}, | |||||
baseProjSetYear: { | |||||
type: String, | |||||
default: '' | |||||
}, | |||||
dictionaryList: { | |||||
type: Array, | |||||
default: () => [] | |||||
} | |||||
}), | |||||
uploadUrl = store.dictStore.uploadUrl, | |||||
formRef = ref(), | |||||
formData = ref({ | |||||
sections: [{ | |||||
purchaseFile: [], | |||||
biddingFile: [], | |||||
purchaseContract: [] | |||||
}] | |||||
}), | |||||
currentRules = {}, | |||||
add = () => { | |||||
formData.value.sections.push({}) | |||||
}, | |||||
del = (index) => { | |||||
formData.value.sections.splice(index, 1) | |||||
} | |||||
defineExpose({ formRef, formData }) | |||||
watch(() => props.basicInfoData, val => { | |||||
if (val?.baseProjIsConfidentiality === '02' || val?.baseProjSetProg === '00') { | |||||
currentRules.value = {} | |||||
} else { | |||||
currentRules.value = { | |||||
sections: [{ required: true, message: '请至少添加一个标段' }] | |||||
} | |||||
} | |||||
formRef.value?.clearValidate() | |||||
}, { deep: true, immediate: true }) | |||||
watch(() => props.detail, val => { | |||||
if (val) { | |||||
if (props.detail?.procures?.length) { | |||||
formData.value = { | |||||
sections: props.detail?.procures?.map(i => { | |||||
return { | |||||
...i, | |||||
purchaseFile: i.purchaseFile ? reviewFileParam(JSON.parse(i.purchaseFile)) : [], | |||||
biddingFile: i.biddingFile ? reviewFileParam(JSON.parse(i.biddingFile)) : [], | |||||
purchaseContract: i.purchaseContract ? reviewFileParam(JSON.parse(i.purchaseContract)) : [] | |||||
} | |||||
}) || [{ | |||||
purchaseFile: [], | |||||
biddingFile: [], | |||||
purchaseContract: [] | |||||
}] | |||||
} | |||||
} | |||||
} | |||||
}) | |||||
</script> | |||||
<template> | |||||
<el-form | |||||
ref="formRef" | |||||
:model="formData" | |||||
:rules="currentRules" | |||||
label-position="top" | |||||
label-suffix=":" | |||||
scroll-to-error | |||||
> | |||||
<template v-for="(item,index) in formData.sections" :key="index"> | |||||
<el-button | |||||
v-if="formData.sections?.length>1" | |||||
type="danger" | |||||
icon="Delete" | |||||
link | |||||
class="float-right" | |||||
@click="del(index)" | |||||
>删除</el-button> | |||||
<template v-if="basicInfoData?.baseProjIsConfidentiality!=='02'&&basicInfoData?.baseProjSetProg!=='00'"> | |||||
<el-row :gutter="40"> | |||||
<template v-if="['05','06','07','00'].includes(basicInfoData?.baseProjSetProg)"> | |||||
<el-col :span="24"> | |||||
<el-form-item label="标段名称" :prop="`sections[${index}].baseBidName`" :rules="[{required:true,message:'请填写'}]"> | |||||
<el-input v-model="formData.sections[index].baseBidName" placeholder="请填写" /> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<el-form-item label="采购方式" :prop="`sections[${index}].baseProjPurchaseWay`" :rules="[{required:true,message:'请选择'}]"> | |||||
<el-select v-model="formData.sections[index].baseProjPurchaseWay" class="w-full"> | |||||
<el-option | |||||
v-for="(row,key) in dictionaryList?.filter(i => i.type === 'PURCHASE_METHOD')" | |||||
:key="key" | |||||
:label="row.label" | |||||
:value="row.value" | |||||
/> | |||||
</el-select> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<el-form-item label="预算执行确认书编号" :prop="`sections[${index}].basePurchaseCode`"> | |||||
<el-input | |||||
v-model="formData.sections[index].basePurchaseCode" | |||||
placeholder="请填写" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
</template> | |||||
<template v-if="['05','06','07','00'].includes(basicInfoData?.baseProjSetProg)||baseProjSetYear*1<2023"> | |||||
<template v-if="['01','02','03','04','06'].includes(item.baseProjPurchaseWay)&&baseProjSetYear*1>=2023"> | |||||
<el-col :span="8"> | |||||
<el-form-item label="采购代理机构" :prop="`sections[${index}].basePurchasingAgencies`" :rules="[{required:true,message:'请填写'}]"> | |||||
<el-input | |||||
v-model="formData.sections[index].basePurchasingAgencies" | |||||
placeholder="请填写" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<el-form-item label="采购代理机构统一社会信用代码" :prop="`sections[${index}].baseUnifiedCreditCode`" :rules="[{required:true,message:'请填写'}]"> | |||||
<el-input | |||||
v-model="formData.sections[index].baseUnifiedCreditCode" | |||||
placeholder="请填写" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
</template> | |||||
<template v-else> | |||||
<el-col :span="8"> | |||||
<el-form-item label="采购代理机构" :prop="`sections[${index}].basePurchaseCode`"> | |||||
<el-input | |||||
v-model="formData.sections[index].basePurchasingAgencies" | |||||
placeholder="请填写" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<el-form-item label="采购代理机构统一社会信用代码" :prop="`sections[${index}].baseUnifiedCreditCode`"> | |||||
<el-input | |||||
v-model="formData.sections[index].baseUnifiedCreditCode" | |||||
placeholder="请填写" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
</template> | |||||
</template> | |||||
<template v-if="['05','06','07','00'].includes(basicInfoData?.baseProjSetProg)"> | |||||
<el-col :span="8"> | |||||
<el-form-item | |||||
label="中标(成交)时间" | |||||
:prop="`sections[${index}].baseWinningBidTime`" | |||||
:rules="[{ required: true, message: '请选择' }]" | |||||
> | |||||
<el-date-picker | |||||
v-model="formData.sections[index].baseWinningBidTime" | |||||
type="date" | |||||
format="YYYY-MM-DD" | |||||
value-format="YYYY-MM-DD" | |||||
placeholder="请选择" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<el-form-item | |||||
label="中标(成交)金额" | |||||
:prop="`sections[${index}].baseProjPurchaseAmount`" | |||||
:rules="[{ required: true, message: '请输入' }]" | |||||
> | |||||
<el-input-number | |||||
v-model="formData.sections[index].baseProjPurchaseAmount" | |||||
class="input-amount" | |||||
placeholder="请填写" | |||||
:min="0.000001" | |||||
:controls="false" | |||||
@mousewheel.prevent | |||||
> | |||||
<template #suffix>万元</template> | |||||
</el-input-number> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<el-form-item | |||||
label="中标(成交)供应商名称" | |||||
:prop="`sections[${index}].baseConsDeprt`" | |||||
:rules="[{ required: true, message: '请输入' }]" | |||||
> | |||||
<el-input | |||||
v-model="formData.sections[index].baseConsDeprt" | |||||
placeholder="请填写" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<el-form-item label="中标(成交)供应商统一社会信用代码" :prop="`sections[${index}].baseConsDeprtUsci`" :rules="[{ required: true, message: '请输入' }]"> | |||||
<el-input | |||||
v-model="formData.sections[index].baseConsDeprtUsci" | |||||
placeholder="请填写" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
</template> | |||||
<template v-if="['05','06','07','00'].includes(basicInfoData?.baseProjSetProg)||baseProjSetYear*1<2023"> | |||||
<el-col :span="8"> | |||||
<el-form-item | |||||
v-if="basicInfoData?.baseProjSetProg==='05'||baseProjSetYear*1<2023" | |||||
label="项目款支付时间" | |||||
:prop="`sections[${index}].basePaymentTime`" | |||||
> | |||||
<el-date-picker | |||||
v-model="formData.sections[index].basePaymentTime" | |||||
type="date" | |||||
format="YYYY-MM-DD" | |||||
value-format="YYYY-MM-DD" | |||||
placeholder="请选择" | |||||
/> | |||||
</el-form-item> | |||||
<el-form-item | |||||
v-else | |||||
label="项目款支付时间" | |||||
:prop="`sections[${index}].basePaymentTime`" | |||||
:rules="[{ required: true, message: '请选择' }]" | |||||
> | |||||
<el-date-picker | |||||
v-model="formData.sections[index].basePaymentTime" | |||||
type="date" | |||||
format="YYYY-MM-DD" | |||||
value-format="YYYY-MM-DD" | |||||
placeholder="请选择" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<el-form-item v-if="basicInfoData?.baseProjSetProg==='05'||baseProjSetYear*1<2023" label="项目款支付金额" :prop="`sections[${index}].paymentProgress`"> | |||||
<el-input-number | |||||
v-model="formData.sections[index].paymentProgress" | |||||
class="input-amount" | |||||
placeholder="请填写" | |||||
:min="0.000001" | |||||
:controls="false" | |||||
@mousewheel.prevent | |||||
> | |||||
<template #suffix>万元</template> | |||||
</el-input-number> | |||||
</el-form-item> | |||||
<el-form-item | |||||
v-else | |||||
label="项目款支付金额" | |||||
:prop="`sections[${index}].paymentProgress`" | |||||
:rules="[{ required: true, message: '请选择' }]" | |||||
> | |||||
<el-input-number | |||||
v-model="formData.sections[index].paymentProgress" | |||||
class="input-amount" | |||||
placeholder="请填写" | |||||
:min="0.000001" | |||||
:controls="false" | |||||
@mousewheel.prevent | |||||
> | |||||
<template #suffix>万元</template> | |||||
</el-input-number> | |||||
</el-form-item> | |||||
</el-col> | |||||
</template> | |||||
</el-row> | |||||
<el-row> | |||||
<template v-if="['05','06','07','00']?.includes(basicInfoData?.baseProjSetProg)"> | |||||
<el-col :span="8"> | |||||
<el-form-item | |||||
v-if="item.baseProjPurchaseWay==='00'" | |||||
label="招标(采购)文件" | |||||
:prop="`sections[${index}].purchaseFile`" | |||||
> | |||||
<el-upload | |||||
v-model:file-list="formData.sections[index].purchaseFile" | |||||
class="w-full" | |||||
:action="uploadUrl" | |||||
:on-success="res => handleFileSuccess(res, formData.sections[index].purchaseFile)" | |||||
:on-error="handleFileError" | |||||
:before-upload="file=>fileFormatVerification(file, {types: fileTypes})" | |||||
:accept="fileTypes.map(i=>`.${i}`).join(',')" | |||||
multiple | |||||
:limit="10" | |||||
:on-preview="handleFilePreview" | |||||
> | |||||
<el-button type="primary" class="mr-4">上传文件</el-button> | |||||
<template #tip> | |||||
<div class="el-upload__tip">支持{{ fileDesc }}文件</div> | |||||
</template> | |||||
</el-upload> | |||||
</el-form-item> | |||||
<el-form-item | |||||
v-else | |||||
label="招标(采购)文件" | |||||
:prop="`sections[${index}].purchaseFile`" | |||||
:rules="[{required:true,message:'请上传'}]" | |||||
> | |||||
<el-upload | |||||
v-model:file-list="formData.sections[index].purchaseFile" | |||||
class="w-full" | |||||
:action="uploadUrl" | |||||
:on-success="res => handleFileSuccess(res, formData.sections[index].purchaseFile)" | |||||
:on-error="handleFileError" | |||||
:before-upload="file=>fileFormatVerification(file, {types: fileTypes})" | |||||
:accept="fileTypes.map(i=>`.${i}`).join(',')" | |||||
multiple | |||||
:limit="10" | |||||
:on-preview="handleFilePreview" | |||||
> | |||||
<el-button type="primary" class="mr-4">上传文件</el-button> | |||||
<template #tip> | |||||
<div class="el-upload__tip">支持{{ fileDesc }}文件</div> | |||||
</template> | |||||
</el-upload> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<el-form-item | |||||
v-if="item.baseProjPurchaseWay==='00'||item.baseProjPurchaseWay==='05'" | |||||
label="中标(成交)通知" | |||||
:prop="`sections[${index}].biddingFile`" | |||||
> | |||||
<el-upload | |||||
v-model:file-list="formData.sections[index].biddingFile" | |||||
class="w-full" | |||||
:action="uploadUrl" | |||||
:on-success="res => handleFileSuccess(res, formData.sections[index].biddingFile)" | |||||
:on-error="handleFileError" | |||||
:before-upload="file=>fileFormatVerification(file, {types: fileTypes})" | |||||
:accept="fileTypes.map(i=>`.${i}`).join(',')" | |||||
multiple | |||||
:limit="10" | |||||
:on-preview="handleFilePreview" | |||||
> | |||||
<el-button type="primary" class="mr-4">上传文件</el-button> | |||||
<template #tip> | |||||
<div class="el-upload__tip">支持{{ fileDesc }}文件</div> | |||||
</template> | |||||
</el-upload> | |||||
</el-form-item> | |||||
<el-form-item | |||||
v-else | |||||
label="中标(成交)通知" | |||||
:prop="`sections[${index}].biddingFile`" | |||||
:rules="[{required:true,message:'请上传'}]" | |||||
> | |||||
<el-upload | |||||
v-model:file-list="formData.sections[index].biddingFile" | |||||
class="w-full" | |||||
:action="uploadUrl" | |||||
:on-success="res => handleFileSuccess(res, formData.sections[index].biddingFile)" | |||||
:on-error="handleFileError" | |||||
:before-upload="file=>fileFormatVerification(file, {types: fileTypes})" | |||||
:accept="fileTypes.map(i=>`.${i}`).join(',')" | |||||
multiple | |||||
:on-preview="handleFilePreview" | |||||
:limit="10" | |||||
> | |||||
<el-button type="primary" class="mr-4">上传文件</el-button> | |||||
<template #tip> | |||||
<div class="el-upload__tip">支持{{ fileDesc }}文件</div> | |||||
</template> | |||||
</el-upload> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<el-form-item | |||||
label="采购合同" | |||||
:prop="`sections[${index}].purchaseContract`" | |||||
:rules="[{required:true,message:'请上传'}]" | |||||
> | |||||
<el-upload | |||||
v-model:file-list="formData.sections[index].purchaseContract" | |||||
class="w-full" | |||||
:action="uploadUrl" | |||||
:on-success="res => handleFileSuccess(res, formData.sections[index].purchaseContract)" | |||||
:on-error="handleFileError" | |||||
:before-upload="file=>fileFormatVerification(file, {types: fileTypes})" | |||||
:accept="fileTypes.map(i=>`.${i}`).join(',')" | |||||
multiple | |||||
:limit="10" | |||||
> | |||||
<el-button type="primary" class="mr-4">上传文件</el-button> | |||||
<template #tip> | |||||
<div class="el-upload__tip">支持{{ fileDesc }}文件</div> | |||||
</template> | |||||
</el-upload> | |||||
</el-form-item> | |||||
</el-col> | |||||
</template> | |||||
</el-row> | |||||
</template> | |||||
<template v-else> | |||||
<el-row :gutter="40"> | |||||
<template v-if="['05','06','07','00'].includes(basicInfoData?.baseProjSetProg)"> | |||||
<el-col :span="24"> | |||||
<el-form-item label="标段名称" :prop="`sections[${index}].baseBidName`"> | |||||
<el-input v-model="formData.sections[index].baseBidName" placeholder="请填写" /> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<el-form-item label="采购方式" :prop="`sections[${index}].baseProjPurchaseWay`" :rules="[{required:false,message:'请选择'}]"> | |||||
<el-select v-model="formData.sections[index].baseProjPurchaseWay" class="w-full"> | |||||
<el-option | |||||
v-for="(row,key) in dictionaryList?.filter(i => i.type === 'PURCHASE_METHOD')" | |||||
:key="key" | |||||
:label="row.label" | |||||
:value="row.value" | |||||
/> | |||||
</el-select> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<el-form-item label="预算执行确认书编号" :prop="`sections[${index}].basePurchaseCode`"> | |||||
<el-input | |||||
v-model="formData.sections[index].basePurchaseCode" | |||||
placeholder="请填写" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
</template> | |||||
<template v-if="['05','06','07','00'].includes(basicInfoData?.baseProjSetProg)||baseProjSetYear*1<2023"> | |||||
<template v-if="['01','02','03','04','06'].includes(item.baseProjPurchaseWay)&&baseProjSetYear*1>=2023"> | |||||
<el-col :span="8"> | |||||
<el-form-item label="采购代理机构" :prop="`sections[${index}].basePurchaseCode`" :rules="[{required:false,message:'请填写'}]"> | |||||
<el-input | |||||
v-model="formData.sections[index].basePurchasingAgencies" | |||||
placeholder="请填写" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<el-form-item label="采购代理机构统一社会信用代码" :prop="`sections[${index}].baseUnifiedCreditCode`" :rules="[{required:false,message:'请填写'}]"> | |||||
<el-input | |||||
v-model="formData.sections[index].baseUnifiedCreditCode" | |||||
placeholder="请填写" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
</template> | |||||
<template v-else> | |||||
<el-col :span="8"> | |||||
<el-form-item label="采购代理机构" :prop="`sections[${index}].basePurchaseCode`"> | |||||
<el-input | |||||
v-model="formData.sections[index].basePurchasingAgencies" | |||||
placeholder="请填写" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<el-form-item label="采购代理机构统一社会信用代码" :prop="`sections[${index}].baseUnifiedCreditCode`"> | |||||
<el-input | |||||
v-model="formData.sections[index].baseUnifiedCreditCode" | |||||
placeholder="请填写" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
</template> | |||||
</template> | |||||
<template v-if="['05','06','07','00'].includes(basicInfoData?.baseProjSetProg)"> | |||||
<el-col :span="8"> | |||||
<el-form-item | |||||
label="中标(成交)时间" | |||||
:prop="`sections[${index}].baseWinningBidTime`" | |||||
:rules="[{ required: false, message: '请选择' }]" | |||||
> | |||||
<el-date-picker | |||||
v-model="formData.sections[index].baseWinningBidTime" | |||||
type="date" | |||||
format="YYYY-MM-DD" | |||||
value-format="YYYY-MM-DD" | |||||
placeholder="请选择" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<el-form-item | |||||
label="中标(成交)金额" | |||||
:prop="`sections[${index}].baseProjPurchaseAmount`" | |||||
:rules="[{ required: false, message: '请输入' }]" | |||||
> | |||||
<el-input-number | |||||
v-model="formData.sections[index].baseProjPurchaseAmount" | |||||
class="input-amount" | |||||
placeholder="请填写" | |||||
:min="0.000001" | |||||
:controls="false" | |||||
@mousewheel.prevent | |||||
> | |||||
<template #suffix>万元</template> | |||||
</el-input-number> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<el-form-item | |||||
label="中标(成交)供应商名称" | |||||
:prop="`sections[${index}].baseConsDeprt`" | |||||
:rules="[{ required: false, message: '请输入' }]" | |||||
> | |||||
<el-input | |||||
v-model="formData.sections[index].baseConsDeprt" | |||||
placeholder="请填写" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<el-form-item label="中标(成交)供应商统一社会信用代码" :prop="`sections[${index}].baseConsDeprtUsci`" :rules="[{ required: false, message: '请输入' }]"> | |||||
<el-input | |||||
v-model="formData.sections[index].baseConsDeprtUsci" | |||||
placeholder="请填写" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
</template> | |||||
<template v-if="['05','06','07','00'].includes(basicInfoData?.baseProjSetProg)||baseProjSetYear*1<2023"> | |||||
<el-col :span="8"> | |||||
<el-form-item | |||||
v-if="basicInfoData?.baseProjSetProg==='05'||baseProjSetYear*1<2023" | |||||
label="项目款支付时间" | |||||
:prop="`sections[${index}].basePaymentTime`" | |||||
> | |||||
<el-date-picker | |||||
v-model="formData.sections[index].basePaymentTime" | |||||
type="date" | |||||
format="YYYY-MM-DD" | |||||
value-format="YYYY-MM-DD" | |||||
placeholder="请选择" | |||||
/> | |||||
</el-form-item> | |||||
<el-form-item | |||||
v-else | |||||
label="项目款支付时间" | |||||
:prop="`sections[${index}].basePaymentTime`" | |||||
:rules="[{ required: false, message: '请选择' }]" | |||||
> | |||||
<el-date-picker | |||||
v-model="formData.sections[index].basePaymentTime" | |||||
type="date" | |||||
format="YYYY-MM-DD" | |||||
value-format="YYYY-MM-DD" | |||||
placeholder="请选择" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<el-form-item v-if="basicInfoData?.baseProjSetProg==='05'||baseProjSetYear*1<2023" label="项目款支付金额" :prop="`sections[${index}].paymentProgress`"> | |||||
<el-input-number | |||||
v-model="formData.sections[index].paymentProgress" | |||||
class="input-amount" | |||||
placeholder="请填写" | |||||
:min="0.000001" | |||||
:controls="false" | |||||
@mousewheel.prevent | |||||
> | |||||
<template #suffix>万元</template> | |||||
</el-input-number> | |||||
</el-form-item> | |||||
<el-form-item | |||||
v-else | |||||
label="项目款支付金额" | |||||
:prop="`sections[${index}].paymentProgress`" | |||||
:rules="[{ required: false, message: '请选择' }]" | |||||
> | |||||
<el-input-number | |||||
v-model="formData.sections[index].paymentProgress" | |||||
class="input-amount" | |||||
placeholder="请填写" | |||||
:min="0.000001" | |||||
:controls="false" | |||||
@mousewheel.prevent | |||||
> | |||||
<template #suffix>万元</template> | |||||
</el-input-number> | |||||
</el-form-item> | |||||
</el-col> | |||||
</template> | |||||
</el-row> | |||||
<el-row> | |||||
<template v-if="['05','06','07','00']?.includes(basicInfoData?.baseProjSetProg)"> | |||||
<el-col :span="8"> | |||||
<el-form-item | |||||
v-if="item.baseProjPurchaseWay==='00'" | |||||
label="招标(采购)文件" | |||||
:prop="`sections[${index}].purchaseFile`" | |||||
> | |||||
<el-upload | |||||
v-model:file-list="formData.sections[index].purchaseFile" | |||||
class="w-full" | |||||
:action="uploadUrl" | |||||
:on-success="res => handleFileSuccess(res, formData.sections[index].purchaseFile)" | |||||
:on-error="handleFileError" | |||||
:before-upload="file=>fileFormatVerification(file, {types: fileTypes})" | |||||
:accept="fileTypes.map(i=>`.${i}`).join(',')" | |||||
multiple | |||||
:limit="10" | |||||
> | |||||
<el-button type="primary" class="mr-4">上传文件</el-button> | |||||
<template #tip> | |||||
<div class="el-upload__tip">支持{{ fileDesc }}文件</div> | |||||
</template> | |||||
</el-upload> | |||||
</el-form-item> | |||||
<el-form-item | |||||
v-else | |||||
label="招标(采购)文件" | |||||
:prop="`sections[${index}].purchaseFile`" | |||||
:rules="[{required:false,message:'请上传'}]" | |||||
> | |||||
<el-upload | |||||
v-model:file-list="formData.sections[index].purchaseFile" | |||||
class="w-full" | |||||
:action="uploadUrl" | |||||
:on-success="res => handleFileSuccess(res, formData.sections[index].purchaseFile)" | |||||
:on-error="handleFileError" | |||||
:before-upload="file=>fileFormatVerification(file, {types: fileTypes})" | |||||
:accept="fileTypes.map(i=>`.${i}`).join(',')" | |||||
multiple | |||||
:limit="10" | |||||
> | |||||
<el-button type="primary" class="mr-4">上传文件</el-button> | |||||
<template #tip> | |||||
<div class="el-upload__tip">支持{{ fileDesc }}文件</div> | |||||
</template> | |||||
</el-upload> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<el-form-item | |||||
v-if="item.baseProjPurchaseWay==='00'" | |||||
label="中标(成交)通知" | |||||
:prop="`sections[${index}].biddingFile`" | |||||
> | |||||
<el-upload | |||||
v-model:file-list="formData.sections[index].biddingFile" | |||||
class="w-full" | |||||
:action="uploadUrl" | |||||
:on-success="res => handleFileSuccess(res, formData.sections[index].biddingFile)" | |||||
:on-error="handleFileError" | |||||
:before-upload="file=>fileFormatVerification(file, {types: fileTypes})" | |||||
:accept="fileTypes.map(i=>`.${i}`).join(',')" | |||||
multiple | |||||
:limit="10" | |||||
> | |||||
<el-button type="primary" class="mr-4">上传文件</el-button> | |||||
<template #tip> | |||||
<div class="el-upload__tip">支持{{ fileDesc }}文件</div> | |||||
</template> | |||||
</el-upload> | |||||
</el-form-item> | |||||
<el-form-item | |||||
v-else | |||||
label="中标(成交)通知" | |||||
:prop="`sections[${index}].biddingFile`" | |||||
:rules="[{required:false,message:'请上传'}]" | |||||
> | |||||
<el-upload | |||||
v-model:file-list="formData.sections[index].biddingFile" | |||||
class="w-full" | |||||
:action="uploadUrl" | |||||
:on-success="res => handleFileSuccess(res, formData.sections[index].biddingFile)" | |||||
:on-error="handleFileError" | |||||
:before-upload="file=>fileFormatVerification(file, {types: fileTypes})" | |||||
:accept="fileTypes.map(i=>`.${i}`).join(',')" | |||||
multiple | |||||
:limit="10" | |||||
> | |||||
<el-button type="primary" class="mr-4">上传文件</el-button> | |||||
<template #tip> | |||||
<div class="el-upload__tip">支持{{ fileDesc }}文件</div> | |||||
</template> | |||||
</el-upload> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<el-form-item | |||||
label="采购合同" | |||||
:prop="`sections[${index}].purchaseContract`" | |||||
> | |||||
<el-upload | |||||
v-model:file-list="formData.sections[index].purchaseContract" | |||||
class="w-full" | |||||
:action="uploadUrl" | |||||
:on-success="res => handleFileSuccess(res, formData.sections[index].purchaseContract)" | |||||
:on-error="handleFileError" | |||||
:before-upload="file=>fileFormatVerification(file, {types: fileTypes})" | |||||
:accept="fileTypes.map(i=>`.${i}`).join(',')" | |||||
multiple | |||||
:limit="10" | |||||
> | |||||
<el-button type="primary" class="mr-4">上传文件</el-button> | |||||
<template #tip> | |||||
<div class="el-upload__tip">支持{{ fileDesc }}文件</div> | |||||
</template> | |||||
</el-upload> | |||||
</el-form-item> | |||||
</el-col> | |||||
</template> | |||||
</el-row> | |||||
</template> | |||||
<el-divider v-if="index<formData.sections?.length-1" /> | |||||
</template> | |||||
</el-form> | |||||
<p> | |||||
<el-button | |||||
type="primary" | |||||
plain | |||||
icon="Plus" | |||||
class="w-full" | |||||
@click="add" | |||||
>添加标段</el-button> | |||||
</p> | |||||
</template> |
@@ -0,0 +1,117 @@ | |||||
<script name="relatedIrsAppDialog" setup> | |||||
import { nextTick, ref, watch } from 'vue' | |||||
import { applicationList } from '@/http/apis/declareMange' | |||||
import { storeToRefs } from 'pinia' | |||||
import store from '@/store' | |||||
const userInfo = storeToRefs(store.userStore).userInfo || {}, | |||||
props = defineProps({ | |||||
visible: { | |||||
type: Boolean, | |||||
default: false, | |||||
required: true | |||||
}, | |||||
data: Object, | |||||
column: { | |||||
type: Array, | |||||
default: () => { | |||||
return [ | |||||
{ | |||||
type: 'radio', | |||||
width: '55', | |||||
key: 'appId' | |||||
}, | |||||
{ | |||||
label: '应用名称', | |||||
prop: 'name', | |||||
key: 'name' | |||||
} | |||||
] | |||||
} | |||||
} | |||||
}), | |||||
searchForm = ref({ | |||||
name: undefined | |||||
}), | |||||
// 表格数据 | |||||
tableListRef = ref(), | |||||
total = ref(0), | |||||
tableData = ref([]), | |||||
getTableData = async (pageParams = tableListRef.value.pageParams) => { | |||||
const res = await applicationList({ areaCode: userInfo.value.regionCode, ...searchForm.value }) | |||||
tableData.value = res.data.records | |||||
total.value = res.data.total | |||||
await nextTick() | |||||
tableListRef.value.setRadio(props?.data?.appId || '') | |||||
}, | |||||
// 搜索 | |||||
search = () => { | |||||
tableListRef.value.pageParams.pageNumber = 1 | |||||
getTableData() | |||||
}, | |||||
reset = () => { | |||||
tableListRef.value.pageParams.pageNumber = 1 | |||||
searchForm.value.name = undefined | |||||
getTableData() | |||||
}, | |||||
selectData = ref(), | |||||
radioChange = (val) => { | |||||
selectData.value = val | |||||
}, | |||||
submit = async () => { | |||||
emits('getIrsApp', selectData.value) | |||||
emits('close', true) | |||||
}, | |||||
emits = defineEmits(['close', 'getIrsApp']) | |||||
watch(() => props.visible, async (val) => { | |||||
if (val) { | |||||
await nextTick() | |||||
await getTableData() | |||||
} else { | |||||
tableListRef.value.tableRef.clearSelection() | |||||
} | |||||
}) | |||||
</script> | |||||
<template> | |||||
<el-dialog | |||||
:model-value="visible" | |||||
title="选择项目" | |||||
:width="840" | |||||
@close="emits('close')" | |||||
> | |||||
<el-form :model="searchForm" label-suffix=":"> | |||||
<el-row :gutter="24"> | |||||
<el-col :span="12"> | |||||
<el-form-item label="应用名称"> | |||||
<el-input v-model="searchForm.name" placeholder="请输入" /> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="12"> | |||||
<el-form-item class="search_btn"> | |||||
<el-button type="primary" @click="search">搜索</el-button> | |||||
<el-button @click="reset">重置</el-button> | |||||
</el-form-item> | |||||
</el-col> | |||||
</el-row> | |||||
</el-form> | |||||
<table-list | |||||
ref="tableListRef" | |||||
:column="column" | |||||
:data="tableData" | |||||
:total="total" | |||||
row-key="appId" | |||||
@radio-change="radioChange" | |||||
@get-table-data="getTableData" | |||||
/> | |||||
<template #footer> | |||||
<div class="flex justify-center"> | |||||
<el-button type="primary" @click="submit">确定</el-button> | |||||
<el-button @click="emits('close')">取消</el-button> | |||||
</div> | |||||
</template> | |||||
</el-dialog> | |||||
</template> |
@@ -0,0 +1,171 @@ | |||||
<script name="relatedProjectDialog" setup> | |||||
import { nextTick, ref, watch, reactive } from 'vue' | |||||
import { list } from '@/http/apis/projectStoreManage/projectStore' | |||||
const | |||||
props = defineProps({ | |||||
visible: { | |||||
type: Boolean, | |||||
default: false, | |||||
required: true | |||||
}, | |||||
data: Object, | |||||
column: { | |||||
type: Array, | |||||
default: () => { | |||||
return [ | |||||
{ | |||||
type: 'selection', | |||||
reserveSelection: true, | |||||
width: '55', | |||||
fixed: 'left' | |||||
}, | |||||
{ | |||||
label: '项目名称', | |||||
prop: 'projectName', | |||||
key: 'projectName' | |||||
}, | |||||
{ | |||||
label: '预算年度', | |||||
prop: 'projectYear', | |||||
key: 'projectYear', | |||||
width: 80 | |||||
} | |||||
] | |||||
} | |||||
} | |||||
}), | |||||
searchForm = reactive({ | |||||
projectName: undefined, | |||||
projectYear: undefined | |||||
}), | |||||
// 表格数据 | |||||
tableListRef = ref(), | |||||
total = ref(0), | |||||
tableData = ref([]), | |||||
getTableData = async (pageParams = tableListRef.value.pageParams) => { | |||||
const res = await list({ | |||||
...pageParams, | |||||
...searchForm | |||||
}) | |||||
tableData.value = res.data.records | |||||
total.value = res.data.total | |||||
selectCopyData.value = JSON.parse(JSON.stringify(selectData.value)) | |||||
if (selectCopyData.value?.length) { | |||||
tableData.value && tableData.value.forEach(item => { | |||||
const dataIds = selectCopyData.value.map(i => i.id) | |||||
if (dataIds.includes(item.id) && !tableListRef.value.getSelectRows().map(i => i.id).includes(item.id)) { | |||||
tableListRef.value.toggleRowSelect(item, true) | |||||
} | |||||
}) | |||||
} | |||||
}, | |||||
// 搜索 | |||||
search = () => { | |||||
tableListRef.value.pageParams.pageNumber = 1 | |||||
getTableData() | |||||
}, | |||||
reset = () => { | |||||
searchForm.projectName = undefined | |||||
searchForm.projectYear = undefined | |||||
tableListRef.value.pageParams.pageNumber = 1 | |||||
tableListRef.value.pageParams.pageSize = 10 | |||||
getTableData() | |||||
}, | |||||
// 表格多选 | |||||
selectData = ref([]), | |||||
selectCopyData = ref([]), | |||||
selectionChange = (val) => { | |||||
const ids = val.map(i => i.id) | |||||
tableData.value.forEach(row => { | |||||
if (ids.includes(row.id)) { | |||||
selectData.value.push(row) | |||||
} else { | |||||
selectData.value = selectData.value.filter(i => i.id !== row.id) | |||||
} | |||||
}) | |||||
}, | |||||
submit = async () => { | |||||
const obj = {} | |||||
const data = selectData.value.reduce((cur, next) => { | |||||
obj[next.id] ? '' : obj[next.id] = true && cur.push(next) | |||||
return cur | |||||
}, []) | |||||
emits('getProjectList', data) | |||||
emits('close', true) | |||||
}, | |||||
emits = defineEmits(['close', 'getProjectList']) | |||||
watch(() => props.visible, async (val) => { | |||||
if (val) { | |||||
await nextTick() | |||||
if (props.data?.length) { | |||||
selectData.value = props.data.map(i => { | |||||
return { | |||||
id: i.baseProjId, | |||||
projectName: i.baseProjName, | |||||
projectYear: i.baseProjSetYear | |||||
} | |||||
}) | |||||
} | |||||
reset() | |||||
} else { | |||||
tableListRef.value.tableRef.clearSelection() | |||||
} | |||||
}) | |||||
</script> | |||||
<template> | |||||
<el-dialog | |||||
:model-value="visible" | |||||
title="选择项目" | |||||
:width="840" | |||||
@close="emits('close')" | |||||
> | |||||
<el-form :model="searchForm" label-suffix=":" size="small"> | |||||
<el-row :gutter="16"> | |||||
<el-col :span="8"> | |||||
<el-form-item label="项目名称"> | |||||
<el-input v-model="searchForm.projectName" placeholder="请输入" /> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<el-form-item label="项目预算年度" prop="projectYear"> | |||||
<el-date-picker | |||||
v-model="searchForm.projectYear" | |||||
type="year" | |||||
value-format="YYYY" | |||||
placeholder="请选择" | |||||
style="width: 100%" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<el-form-item class="btn"> | |||||
<div class="flex"> | |||||
<el-button type="primary" @click="search">搜索</el-button> | |||||
<el-button @click="reset">重置</el-button> | |||||
</div> | |||||
</el-form-item> | |||||
</el-col> | |||||
</el-row> | |||||
</el-form> | |||||
<table-list | |||||
ref="tableListRef" | |||||
:column="column" | |||||
:data="tableData" | |||||
:total="total" | |||||
row-key="id" | |||||
@selection-change="selectionChange" | |||||
@get-table-data="getTableData" | |||||
/> | |||||
<template #footer> | |||||
<div class="flex justify-center"> | |||||
<el-button type="primary" @click="submit">确定</el-button> | |||||
<el-button @click="emits('close')">取消</el-button> | |||||
</div> | |||||
</template> | |||||
</el-dialog> | |||||
</template> |
@@ -0,0 +1,149 @@ | |||||
<script setup name="userDialog"> | |||||
import { reactive, ref, watch } from 'vue' | |||||
import { userList } from '@/http/apis/systemManage/userManage' | |||||
const props = defineProps({ | |||||
visible: { | |||||
type: Boolean, | |||||
default: false, | |||||
required: true | |||||
}, | |||||
data: { | |||||
type: Array, | |||||
default: undefined | |||||
}, | |||||
params: { | |||||
type: Object, | |||||
default: () => { | |||||
return {} | |||||
} | |||||
} | |||||
}), | |||||
emits = defineEmits(['close', 'getUserData']), | |||||
column = [ | |||||
{ | |||||
type: 'radio', | |||||
key: 'userId', | |||||
width: 60 | |||||
}, | |||||
{ | |||||
label: '序号', | |||||
type: 'index', | |||||
width: 60 | |||||
}, | |||||
{ | |||||
label: '姓名', | |||||
key: 'name', | |||||
prop: 'name' | |||||
}, | |||||
{ | |||||
label: '所属单位(主职)', | |||||
key: 'orgName', | |||||
prop: 'orgName', | |||||
showOverflowTooltip: true, | |||||
width: 250 | |||||
}, | |||||
{ | |||||
label: '手机号码', | |||||
key: 'phoneNo', | |||||
prop: 'phoneNo', | |||||
width: '150' | |||||
} | |||||
], | |||||
tableListRef = ref(), | |||||
total = ref(0), | |||||
tableData = ref([]), | |||||
searchForm = reactive({ | |||||
name: undefined | |||||
}), | |||||
getTableData = async (pageParams = tableListRef.value?.pageParams) => { | |||||
const res = await userList({ | |||||
...pageParams, | |||||
...searchForm, | |||||
...props.params | |||||
}) | |||||
total.value = res.data.total | |||||
tableData.value = res.data.records || [] | |||||
}, | |||||
search = () => { | |||||
getTableData() | |||||
}, | |||||
reset = () => { | |||||
searchForm.name = undefined | |||||
searchForm.phoneNo = undefined | |||||
tableListRef.value.pageParams.pageNumber = 1 | |||||
tableListRef.value.pageParams.pageSize = 10 | |||||
getTableData() | |||||
}, | |||||
userData = ref(), | |||||
radioChange = (val) => { | |||||
userData.value = val | |||||
}, | |||||
submit = () => { | |||||
emits('getUserData', userData.value) | |||||
emits('close') | |||||
} | |||||
watch( | |||||
() => props.visible, | |||||
async val => { | |||||
if (val) { | |||||
getTableData() | |||||
} | |||||
} | |||||
) | |||||
</script> | |||||
<template> | |||||
<el-dialog | |||||
:model-value="visible" | |||||
title="项目负责人/项目联系人" | |||||
width="70%" | |||||
destroy-on-close | |||||
@close="emits('close')" | |||||
> | |||||
<div class="search mb-16"> | |||||
<el-form label-suffix=":" :model="searchForm" size="small"> | |||||
<el-row :gutter="16"> | |||||
<el-col :span="8"> | |||||
<el-form-item label="用户姓名"> | |||||
<el-input v-model="searchForm.name" placeholder="请输入" /> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<el-form-item label="联系电话"> | |||||
<el-input v-model="searchForm.phoneNo" placeholder="请输入" /> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<el-form-item class="btn"> | |||||
<el-button type="primary" @click="search">查询</el-button> | |||||
<el-button @click="reset">重置</el-button> | |||||
</el-form-item> | |||||
</el-col> | |||||
</el-row> | |||||
</el-form> | |||||
</div> | |||||
<table-list | |||||
ref="tableListRef" | |||||
:column="column" | |||||
class="mt-15" | |||||
:data="tableData" | |||||
:total="total" | |||||
row-key="userId" | |||||
@radio-change="radioChange" | |||||
@get-table-data="getTableData" | |||||
/> | |||||
<template #footer> | |||||
<span class="dialog-footer"> | |||||
<el-button @click="emits('close')">关闭</el-button> | |||||
<el-button | |||||
type="primary" | |||||
@click="submit" | |||||
> | |||||
提交 | |||||
</el-button> | |||||
</span> | |||||
</template> | |||||
</el-dialog> | |||||
</template> |
@@ -0,0 +1,281 @@ | |||||
<script name="projectCollectionEnter" setup> | |||||
import BasicInfo from './components/basicInfo.vue' | |||||
import { getCurrentInstance, onMounted, ref } from 'vue' | |||||
import { useRoute, useRouter } from 'vue-router' | |||||
import { changFilesParam } from '@/utils/uploadAction' | |||||
import ProjectDeclareInfo from './components/projectDeclareInfo.vue' | |||||
import ApplicationInfo from './components/applicationInfo.vue' | |||||
import CoreBusiness from './components/coreBusiness.vue' | |||||
import ProjectApprovalInfo from './components/projectApprovalInfo.vue' | |||||
import PurchaseInfo from './components/purchaseInfo.vue' | |||||
import EmpMaterials from './components/empMaterials.vue' | |||||
import { dictionary } from '@/http/apis/projectCollection/projectCollectionEnter' | |||||
import { detail, save, draftSave } from '@/http/apis/declareMange/operationProjectRecord' | |||||
const { proxy } = getCurrentInstance(), | |||||
route = useRoute(), | |||||
router = useRouter(), | |||||
collapseModal = ['1', '2', '3', '4', '5', '6', '7'], | |||||
formRefs = {}, | |||||
submitLoading = ref(false), | |||||
dictionaryList = ref(), | |||||
detailData = ref(), | |||||
getDetail = async () => { | |||||
const id = route.query.type === '1' ? route.query.id : route.query.draftId | |||||
const res = await detail(route.query.type, id) | |||||
detailData.value = res.data | |||||
}, | |||||
submit = async () => { | |||||
submitLoading.value = true | |||||
try { | |||||
const arr = Object.values(formRefs).map(async i => i?.formRef && await i.formRef.validate()) | |||||
await Promise.all(arr) | |||||
const postData = changePostData() | |||||
// const postData = changePostData() | |||||
// console.log(postData) | |||||
// const formData = formRefs.map(i => i.formData).reduce((result, obj) => ({ ...result, ...obj }), {}) | |||||
await save(postData) | |||||
submitLoading.value = false | |||||
proxy.$message.success('提交成功!') | |||||
router.go(-1) | |||||
} catch (e) { | |||||
submitLoading.value = false | |||||
} | |||||
}, | |||||
basicInfoData = ref(), | |||||
getBasicInfoData = (data) => { | |||||
basicInfoData.value = data | |||||
}, | |||||
baseProjSetYear = ref(), | |||||
getProYear = (data) => { | |||||
baseProjSetYear.value = data | |||||
}, | |||||
approvalInfoData = ref(), | |||||
getApprovalInfoData = (data) => { | |||||
approvalInfoData.value = data | |||||
}, | |||||
changePostData = () => { | |||||
const baseinfo = JSON.parse(JSON.stringify(formRefs['baseinfo'].formData)) | |||||
const apply = JSON.parse(JSON.stringify(formRefs['apply'].formData)) | |||||
const application = formRefs['application'] && JSON.parse(JSON.stringify(formRefs['application'].formData)) || {} | |||||
const baseCore = formRefs['baseCore'] && JSON.parse(JSON.stringify(formRefs['baseCore'].formData)) || {} | |||||
const approve = formRefs['approve'] && JSON.parse(JSON.stringify(formRefs['approve'].formData)) || {} | |||||
const procures = formRefs['procures'] && JSON.parse(JSON.stringify(formRefs['procures'].formData)) || [] | |||||
const cimplement = formRefs['cimplement'] && JSON.parse(JSON.stringify(formRefs['cimplement'].formData)) || [] | |||||
return { | |||||
baseProjId: route.query.id || '', | |||||
draftId: route.query.draftId * 1 || '', | |||||
baseinfo: { | |||||
...baseinfo, | |||||
baseProvManDeprtType: baseinfo?.baseProvManDeprtType * 1 || undefined, | |||||
baseConstructionType: baseinfo?.baseConstructionType?.join(';') | |||||
// baseAreaCode: baseinfo?.baseArea?.baseAreaCode || undefined, | |||||
// baseAreaName: baseinfo?.baseArea?.baseAreaName || undefined, | |||||
// baseArea: undefined | |||||
}, | |||||
apply: { | |||||
...apply, | |||||
baseProjStartTime: apply?.baseProjTime?.length ? apply?.baseProjTime[0] + ' 00:00:00' : undefined, | |||||
baseProjEndTime: apply?.baseProjTime?.length ? apply?.baseProjTime[1] + ' 00:00:00' : undefined, | |||||
baseProjTime: undefined, | |||||
baseHistorProjId: apply?.missing ? '' : apply?.baseHistorProjs?.map(i => i.baseProjId)?.join(';'), | |||||
baseHistorProjName: apply?.missing ? '' : apply?.baseHistorProjs?.map(i => i.baseProjName)?.join(';'), | |||||
baseHistorProjYear: apply?.missing ? '' : apply?.baseHistorProjs?.map(i => i.baseProjSetYear)?.join(';'), | |||||
baseProjAmountOri: apply?.baseProjAmountOri?.join(';') || undefined, | |||||
baseProjBasis: apply?.baseProjBasis?.map(i => i.value)?.join(';') || undefined, | |||||
baseProjBasisFile: apply?.baseProjBasis?.map(i => i.fileList && JSON.stringify(changFilesParam(i.fileList)))?.join(';') || '', | |||||
beseExpectedResults: apply?.beseExpectedResults?.length && JSON.stringify(apply.beseExpectedResults) || '', | |||||
baseProjApplyFile: ((['01', '02', '04', '05'].includes(baseinfo?.baseProjType) && apply?.baseProjSetYear * 1 >= 2023) || apply?.baseProjSetYear * 1 < 2023) && apply?.baseProjApplyFile?.length ? JSON.stringify(changFilesParam(apply?.baseProjApplyFile)) : '', | |||||
baseOperatMaintenFile: apply?.baseOperatMaintenFile?.length ? JSON.stringify(changFilesParam(apply?.baseOperatMaintenFile)) : '', | |||||
baseProjOtherFile: apply?.baseProjOtherFile?.length ? JSON.stringify(changFilesParam(apply?.baseProjOtherFile)) : '', | |||||
baseHistorProjs: undefined, | |||||
...application, | |||||
baseProjSysCode: application?.applications?.map(i => i.application.applicationCode).join(';') || '', | |||||
baseProjSys: application?.applications?.map(i => i.application.applicationName).join(';') || '', | |||||
baseAccountAppName: application?.applications?.map(i => i.baseAccountAppName).join(';') || '', | |||||
baseBrainName: application?.applications?.map(i => i.baseBrainName).join(';') || '', | |||||
applications: undefined, | |||||
...baseCore, | |||||
baseCoreBusinessCode: baseCore?.coreBusiness?.map(i => i.id).join(';') || '', | |||||
baseCoreBusiness: baseCore?.coreBusiness?.map(i => i.matterName).join(';') || '', | |||||
baseCoreBusinessOrg: baseCore?.coreBusiness?.map(i => i.orgName).join(';') || '', | |||||
coreBusiness: undefined | |||||
}, | |||||
approve: { | |||||
...approve, | |||||
baseReviewResults: baseinfo?.baseProjSetProg !== '01' ? approve?.baseReviewResults : '', | |||||
baseReviewOpinion: baseinfo?.baseProjSetProg !== '01' ? approve?.baseReviewOpinion : '', | |||||
baseReviewCommentsFile: baseinfo?.baseProjSetProg !== '01' ? approve?.baseReviewCommentsFile?.length && JSON.stringify(changFilesParam(approve?.baseReviewCommentsFile)) : '', | |||||
equalProtectionLevel: baseinfo?.baseProjIsConfidentiality === '01' && !['01', '02', '03'].includes(baseinfo?.baseProjSetProg) ? approve?.equalProtectionLevel : '', | |||||
approvalFile: !['01', '02', '03'].includes(baseinfo?.baseProjSetProg) ? approve?.approvalFile?.length && JSON.stringify(changFilesParam(approve?.approvalFile)) : '', | |||||
baseExpertTotalMoney: !['01', '03'].includes(baseinfo?.baseProjSetProg) ? approve?.baseExpertTotalMoney : '', | |||||
baseExpertYearMoney: !['01', '03'].includes(baseinfo?.baseProjSetProg) ? approve?.baseExpertYearMoney : '', | |||||
baseInitialReviewTotalMoney: !['01', '02', '03'].includes(baseinfo?.baseProjSetProg) ? approve?.baseInitialReviewTotalMoney : '', | |||||
baseProjReplyAmount: !['01', '02', '03'].includes(baseinfo?.baseProjSetProg) ? approve?.baseProjReplyAmount : '', | |||||
releaseYearMoney: ['05', '06', '07', '00'].includes(baseinfo?.baseProjSetProg) ? approve?.releaseYearMoney : '', | |||||
preliminaryDesignScheme: approve?.baseProjReplyAmount >= 5000 && ['04', '05', '06', '07', '00'].includes(baseinfo.baseProjSetProg) ? approve?.preliminaryDesignScheme?.length && JSON.stringify(changFilesParam(approve.preliminaryDesignScheme)) : '', | |||||
preliminaryDesignFile: approve?.baseProjReplyAmount >= 5000 && ['04', '05', '06', '07', '00'].includes(baseinfo.baseProjSetProg) ? approve?.preliminaryDesignFile?.length && JSON.stringify(changFilesParam(approve.preliminaryDesignFile)) : '' | |||||
}, | |||||
procures: (['05', '06', '07', '00'].includes(baseinfo?.baseProjSetProg) || apply?.baseProjSetYear * 1 < 2023) && procures?.sections?.map(i => { | |||||
return { | |||||
...i, | |||||
baseBidName: ['05', '06', '07', '00'].includes(baseinfo?.baseProjSetProg) && i.baseBidName || '', | |||||
baseProjPurchaseWay: ['05', '06', '07', '00'].includes(baseinfo?.baseProjSetProg) && i.baseProjPurchaseWay || '', | |||||
basePurchaseCode: ['05', '06', '07', '00'].includes(baseinfo?.baseProjSetProg) && i.basePurchaseCode || '', | |||||
basePurchasingAgencies: (['05', '06', '07', '00'].includes(baseinfo?.baseProjSetProg) || apply?.baseProjSetYear * 1 < 2023) && i.basePurchasingAgencies || '', | |||||
baseUnifiedCreditCode: (['05', '06', '07', '00'].includes(baseinfo?.baseProjSetProg) || apply?.baseProjSetYear * 1 < 2023) && i.baseUnifiedCreditCode || '', | |||||
baseWinningBidTime: ['05', '06', '07', '00'].includes(baseinfo?.baseProjSetProg) && i.baseWinningBidTime || '', | |||||
baseProjPurchaseAmount: ['05', '06', '07', '00'].includes(baseinfo?.baseProjSetProg) && i.baseProjPurchaseAmount || '', | |||||
baseConsDeprt: ['05', '06', '07', '00'].includes(baseinfo?.baseProjSetProg) && i.baseConsDeprt || '', | |||||
baseConsDeprtUsci: ['05', '06', '07', '00'].includes(baseinfo?.baseProjSetProg) && i.baseConsDeprtUsci || '', | |||||
basePaymentTime: (['05', '06', '07', '00'].includes(baseinfo?.baseProjSetProg) || apply?.baseProjSetYear * 1 < 2023) && i.basePaymentTime || '', | |||||
paymentProgress: (['05', '06', '07', '00'].includes(baseinfo?.baseProjSetProg) || apply?.baseProjSetYear * 1 < 2023) && i.paymentProgress || '', | |||||
purchaseFile: ['05', '06', '07', '00'].includes(baseinfo?.baseProjSetProg) && i.purchaseFile?.length ? JSON.stringify(changFilesParam(i.purchaseFile)) : '', | |||||
biddingFile: ['05', '06', '07', '00'].includes(baseinfo?.baseProjSetProg) && i.biddingFile?.length ? JSON.stringify(changFilesParam(i.biddingFile)) : '', | |||||
purchaseContract: ['05', '06', '07', '00'].includes(baseinfo?.baseProjSetProg) && i.purchaseContract?.length ? JSON.stringify(changFilesParam(i.purchaseContract)) : '' | |||||
} | |||||
}) || [], | |||||
mimplement: { | |||||
...cimplement, | |||||
baseInitialOpinionFile: cimplement?.baseInitialOpinionFile?.length ? JSON.stringify(changFilesParam(cimplement.baseInitialOpinionFile)) : '', | |||||
baseInforLevelFile: ((['05', '06', '07', '00'].includes(baseinfo?.baseProjSetProg) && baseinfo?.baseConstructionType?.includes('01')) || !baseinfo?.baseConstructionType?.includes('01')) && cimplement?.baseInforLevelFile?.length ? JSON.stringify(changFilesParam(cimplement.baseInforLevelFile)) : '', | |||||
basePasswAssessFile: (['04', '05', '06', '07', '00'].includes(baseinfo?.baseProjSetProg) || apply?.baseProjSetYear * 1 < 2023) && cimplement?.basePasswAssessFile?.length ? JSON.stringify(changFilesParam(cimplement.basePasswAssessFile)) : '', | |||||
baseThirdAcceptFile: cimplement.baseThirdAcceptFile?.length ? JSON.stringify(changFilesParam(cimplement.baseThirdAcceptFile)) : '', | |||||
baseCheckFile: ['05', '06', '07', '00'].includes(baseinfo?.baseProjSetProg) && cimplement?.baseCheckFile?.length ? JSON.stringify(changFilesParam(cimplement.baseCheckFile)) : '', | |||||
baseFinanlAuditFile: ['05', '06', '07', '00'].includes(baseinfo?.baseProjSetProg) && approve?.releaseYearMoney * 1 >= 2000 && cimplement?.baseFinanlAuditFile?.length ? JSON.stringify(changFilesParam(cimplement.baseFinanlAuditFile)) : '', | |||||
baseUserConsFile: (['05', '06', '07', '00'].includes(baseinfo?.baseProjSetProg) || apply?.baseProjSetYear * 1 < 2023) && cimplement?.baseUserConsFile?.length ? JSON.stringify(changFilesParam(cimplement.baseUserConsFile)) : '', | |||||
baseEstaSummFile: cimplement?.baseEstaSummFile?.length ? JSON.stringify(changFilesParam(cimplement?.baseEstaSummFile)) : '', | |||||
baseOperatMaintenSummFile: (['05', '06', '07', '00'].includes(baseinfo?.baseProjSetProg) || apply?.baseProjSetYear * 1 < 2023) && cimplement?.baseOperatMaintenSummFile?.length ? JSON.stringify(changFilesParam(cimplement.baseOperatMaintenSummFile)) : '', | |||||
baseFinalExpertOpinionFile: baseinfo?.baseProjSetProg === '07' && cimplement.baseFinalExpertOpinionFile?.length ? JSON.stringify(changFilesParam(cimplement?.baseFinalExpertOpinionFile)) : '', | |||||
baseEngineerPostpoFile: cimplement?.baseEngineerPostpoFile?.length ? JSON.stringify(changFilesParam(cimplement?.baseEngineerPostpoFile)) : '', | |||||
baseEngineerAlterFile: cimplement?.baseEngineerAlterFile?.length ? JSON.stringify(changFilesParam(cimplement?.baseEngineerAlterFile)) : '', | |||||
baseChanFile: cimplement?.baseChanFile?.length ? JSON.stringify(changFilesParam(cimplement?.baseChanFile)) : '', | |||||
baseBusinessMetrics: cimplement?.baseBusinessMetrics?.length ? JSON.stringify(cimplement?.baseBusinessMetrics) : '' | |||||
} | |||||
} | |||||
}, | |||||
// 暂存 | |||||
saveLoading = ref(false), | |||||
saveDraft = async () => { | |||||
saveLoading.value = true | |||||
const postData = changePostData() | |||||
try { | |||||
await draftSave(postData) | |||||
saveLoading.value = false | |||||
proxy.$message.success('暂存成功!') | |||||
router.go(-1) | |||||
} catch (e) { | |||||
saveLoading.value = false | |||||
} | |||||
} | |||||
onMounted(async () => { | |||||
dictionaryList.value = (await dictionary()).data | |||||
if (route.query.id) getDetail() | |||||
}) | |||||
</script> | |||||
<template> | |||||
<div class="footerPage"> | |||||
<div> | |||||
<el-collapse v-model="collapseModal"> | |||||
<el-collapse-item name="1" class="mb-16"> | |||||
<template #title> | |||||
<div class="collapse-title">项目基本信息</div> | |||||
</template> | |||||
<div class="pb-24"> | |||||
<basic-info | |||||
:ref="el=>formRefs['baseinfo']=el" | |||||
:detail="detailData" | |||||
:dictionary-list="dictionaryList" | |||||
@get-basic-info-data="getBasicInfoData" | |||||
/> | |||||
</div> | |||||
</el-collapse-item> | |||||
<el-collapse-item name="2" class="mb-16"> | |||||
<template #title> | |||||
<div class="collapse-title">项目申报信息</div> | |||||
</template> | |||||
<div class="pb-24"> | |||||
<project-declare-info | |||||
:ref="el=>formRefs['apply']=el" | |||||
:detail="detailData" | |||||
:basic-info-data="basicInfoData" | |||||
:dictionary-list="dictionaryList" | |||||
@get-pro-year="getProYear" | |||||
/> | |||||
</div> | |||||
</el-collapse-item> | |||||
<el-collapse-item v-if="!(basicInfoData?.baseConstructionType?.length===1&&basicInfoData?.baseConstructionType.includes('02'))" name="3" class="mb-16"> | |||||
<template #title> | |||||
<div class="collapse-title">项目关联信息</div> | |||||
</template> | |||||
<div class="pb-24"> | |||||
<application-info :ref="el=>formRefs['application']=el" :detail="detailData" :basic-info-data="basicInfoData" /> | |||||
</div> | |||||
</el-collapse-item> | |||||
<el-collapse-item name="4" class="mb-16"> | |||||
<template #title> | |||||
<div class="collapse-title">核心业务</div> | |||||
</template> | |||||
<div class="pb-24"> | |||||
<core-business :ref="el=>formRefs['baseCore']=el" :detail="detailData" :basic-info-data="basicInfoData" /> | |||||
</div> | |||||
</el-collapse-item> | |||||
<el-collapse-item v-if="basicInfoData?.baseProjSetProg!=='01'" name="5" class="mb-16"> | |||||
<template #title> | |||||
<div class="collapse-title">项目立项评审信息</div> | |||||
</template> | |||||
<div class="pb-24"> | |||||
<project-approval-info | |||||
:ref="el=>formRefs['approve']=el" | |||||
:detail="detailData" | |||||
:basic-info-data="basicInfoData" | |||||
:dictionary-list="dictionaryList" | |||||
@get-approval-info-data="getApprovalInfoData" | |||||
/> | |||||
</div> | |||||
</el-collapse-item> | |||||
<el-collapse-item name="6" class="mb-16"> | |||||
<template #title> | |||||
<div class="collapse-title">项目采购、资金支付信息</div> | |||||
</template> | |||||
<div class="pb-24"> | |||||
<purchase-info | |||||
:ref="el=>formRefs['procures']=el" | |||||
:detail="detailData" | |||||
:dictionary-list="dictionaryList" | |||||
:base-proj-set-year="baseProjSetYear" | |||||
:basic-info-data="basicInfoData" | |||||
/> | |||||
</div> | |||||
</el-collapse-item> | |||||
<el-collapse-item name="7" class="mb-16"> | |||||
<template #title> | |||||
<div class="collapse-title">实施材料信息</div> | |||||
</template> | |||||
<div class="pb-24"> | |||||
<emp-materials | |||||
:ref="el=>formRefs['cimplement']=el" | |||||
:detail="detailData" | |||||
:basic-info-data="basicInfoData" | |||||
:base-proj-set-year="baseProjSetYear" | |||||
:approval-info-data="approvalInfoData" | |||||
/> | |||||
</div> | |||||
</el-collapse-item> | |||||
<div class="footer"> | |||||
<el-button @click="$router.go(-1)"> 返回 </el-button> | |||||
<el-button | |||||
v-if="route.query.type!=='1'" | |||||
type="primary" | |||||
:loading="saveLoading" | |||||
plain | |||||
@click="saveDraft" | |||||
> 暂存 </el-button> | |||||
<el-button type="primary" :loading="submitLoading" @click="submit"> 提交 </el-button> | |||||
</div> | |||||
</el-collapse></div> | |||||
</div> | |||||
</template> |
@@ -0,0 +1,128 @@ | |||||
<script name="approvalDialog" setup> | |||||
import { ref, getCurrentInstance, watch } from 'vue' | |||||
import { changFilesParam, fileFormatVerification, handleFileSuccess, handleFilePreview, fileTypes, fileDesc } from '@/utils/uploadAction.js' | |||||
import store from '@/store' | |||||
import { preExamineDeclare } from '@/http/apis/declareMange' | |||||
const { proxy } = getCurrentInstance(), | |||||
uploadUrl = store.dictStore.uploadUrl, | |||||
props = defineProps({ | |||||
visible: { | |||||
type: Boolean, | |||||
default: false, | |||||
required: true | |||||
}, | |||||
data: Object | |||||
}), | |||||
emits = defineEmits(['close']), | |||||
loading = ref(false), | |||||
dialogForm = ref({ | |||||
higherLineSuperOrgReviewComments: [] | |||||
}), | |||||
rules = { | |||||
'higherLineSuperOrgReviewComments': [{ required: true, message: '请选择' }] | |||||
}, | |||||
dialogFormRef = ref(), | |||||
submit = async (formEl) => { | |||||
if (!formEl) { | |||||
save() | |||||
return | |||||
} | |||||
formEl.validate(async (valid) => { | |||||
if (valid) { | |||||
save() | |||||
} | |||||
} | |||||
) | |||||
}, | |||||
save = async () => { | |||||
loading.value = true | |||||
try { | |||||
await preExamineDeclare({ | |||||
projectInfo: { | |||||
...dialogForm.value, | |||||
higherLineSuperOrgReviewComments: dialogForm.value?.higherLineSuperOrgReviewComments?.length && JSON.stringify(changFilesParam(dialogForm.value.higherLineSuperOrgReviewComments)) || undefined, | |||||
id: props.data.id | |||||
} | |||||
}) | |||||
proxy.$message.success('发起成功!') | |||||
loading.value = false | |||||
emits('close', true) | |||||
} catch (e) { | |||||
loading.value = false | |||||
} | |||||
} | |||||
watch( | |||||
() => props.visible, | |||||
async val => { | |||||
if (val) { | |||||
console.log('props.data', props.data) | |||||
} else { | |||||
dialogForm.value = { higherLineSuperOrgReviewComments: [] } | |||||
} | |||||
} | |||||
) | |||||
</script> | |||||
<template> | |||||
<el-dialog | |||||
:model-value="visible" | |||||
title="预审申报" | |||||
width="600px" | |||||
destroy-on-close | |||||
@close="emits('close')" | |||||
> | |||||
<div> | |||||
<p>根据《浙江省电子政务重大应用项目联审》要求,提交预审后:</p> | |||||
<p>1、市级大于1000万元的重大项目将由省级数改牵头部门及业务主管单位进行联审</p> | |||||
<p>2、区县申报项目将由市级数改牵头部门及业务主管单位进行联审,大于500万元的重大项目联审后会提交省里进行备案。</p> | |||||
</div> | |||||
<template v-if="false"> | |||||
<p>提交后将发起项目预审流程,确定提交吗?</p> | |||||
<el-form | |||||
v-if="data.needUploadSuperLineFile" | |||||
ref="dialogFormRef" | |||||
:model="dialogForm" | |||||
:rules="rules" | |||||
label-position="top" | |||||
label-width="auto" | |||||
status-icon | |||||
class="mt-16" | |||||
> | |||||
<el-form-item label="上级条线主管单位审核意见:" prop="higherLineSuperOrgReviewComments"> | |||||
<el-upload | |||||
v-model:file-list="dialogForm.higherLineSuperOrgReviewComments" | |||||
class=" w-full" | |||||
:action="uploadUrl" | |||||
:limit="1" | |||||
:on-success="res => handleFileSuccess(res, dialogForm.higherLineSuperOrgReviewComments, true)" | |||||
:before-upload="file=>fileFormatVerification(file, {types: fileTypes})" | |||||
:accept="fileTypes.map(i=>`.${i}`).join(',')" | |||||
:on-preview="handleFilePreview" | |||||
> | |||||
<el-button type="primary" plain>选择文件</el-button> | |||||
<template #tip> | |||||
<div class="el-upload__tip"> | |||||
支持{{ fileDesc }}文件 | |||||
</div> | |||||
</template> | |||||
</el-upload> | |||||
</el-form-item> | |||||
</el-form> | |||||
</template> | |||||
<template #footer> | |||||
<el-button | |||||
type="primary" | |||||
:loading="loading" | |||||
@click="submit(dialogFormRef)" | |||||
> | |||||
提交 | |||||
</el-button> | |||||
<el-button | |||||
@click="emits('close')" | |||||
> | |||||
关闭 | |||||
</el-button> | |||||
</template> | |||||
</el-dialog> | |||||
</template> |
@@ -0,0 +1,261 @@ | |||||
<script setup name="preExaminationDeclare"> | |||||
import { ref, reactive, onMounted, h } from 'vue' | |||||
import { getPreExamineList, declareExport } from '@/http/apis/declareMange' | |||||
import { useRouter } from 'vue-router' | |||||
import useExportExc from '@/utils/useExportExc' | |||||
import PreExaminationDialog from './components/preExaminationDialog.vue' | |||||
import store from '@/store' | |||||
const { statusOptions, projectTypeOptions } = store.dictStore.globalDicts || {} | |||||
// 搜索栏表单数据 | |||||
const | |||||
router = useRouter(), | |||||
searchForm = reactive({ | |||||
projectName: undefined, | |||||
buildUnitName: undefined, | |||||
projectType: undefined, | |||||
year: undefined, | |||||
times: undefined | |||||
}), | |||||
tableListRef = ref(), | |||||
total = ref(0), | |||||
// 列表数据 | |||||
column = reactive([ | |||||
{ | |||||
label: '序号', | |||||
type: 'index', | |||||
width: '60' | |||||
}, | |||||
{ | |||||
label: '项目名称', | |||||
key: 'projectName', | |||||
prop: 'projectName', | |||||
minWidth: 200, | |||||
showOverflowTooltip: true | |||||
}, | |||||
{ | |||||
label: '项目类型', | |||||
key: 'projectTypeName', | |||||
prop: 'projectTypeName', | |||||
width: 80 | |||||
}, | |||||
{ | |||||
label: '申报金额(万元)', | |||||
key: 'declaredAmount', | |||||
prop: 'declaredAmount', | |||||
width: '150' | |||||
}, | |||||
{ | |||||
label: '申报单位', | |||||
key: 'buildOrg', | |||||
prop: 'buildOrg', | |||||
width: '120', | |||||
showOverflowTooltip: true | |||||
}, | |||||
{ | |||||
label: '预算年度', | |||||
key: 'projectYear', | |||||
prop: 'projectYear', | |||||
width: '80' | |||||
}, | |||||
{ | |||||
label: '项目状态', | |||||
key: 'status', | |||||
prop: 'status', | |||||
showOverflowTooltip: true, | |||||
width: '180', | |||||
render: row => [ | |||||
h('span', { | |||||
class: ['dot mr-4', `bg-${statusOptions[row.status].color}`] | |||||
}), | |||||
h( | |||||
'span', | |||||
{ | |||||
class: `text-${statusOptions[row.status]?.color}` | |||||
}, | |||||
row.status && statusOptions[row.stage]?.name + '-' + statusOptions[row.status]?.name | |||||
) | |||||
] | |||||
}, | |||||
{ | |||||
label: '创建时间', | |||||
key: 'createOn', | |||||
prop: 'createOn', | |||||
width: '180' | |||||
}, | |||||
{ | |||||
label: '操作', | |||||
slot: 'action', | |||||
width: '160', | |||||
fixed: 'right' | |||||
} | |||||
]), | |||||
data = ref([]), | |||||
getTableData = async (pageParams = tableListRef.value.pageParams) => { | |||||
const res = await getPreExamineList({ | |||||
...pageParams, | |||||
...searchForm, | |||||
createOnMin: searchForm.times?.[0] || undefined, | |||||
createOnMax: searchForm.times?.[1] || undefined, | |||||
times: undefined | |||||
}) | |||||
data.value = res.data.records | |||||
total.value = res.data.total | |||||
}, | |||||
search = () => { | |||||
getTableData() | |||||
}, | |||||
reset = () => { | |||||
searchForm.projectName = undefined | |||||
searchForm.buildUnitName = undefined | |||||
searchForm.projectType = undefined | |||||
searchForm.projectYear = undefined | |||||
searchForm.times = undefined | |||||
tableListRef.value.pageParams.pageNumber = 1 | |||||
tableListRef.value.pageParams.pageSize = 10 | |||||
getTableData() | |||||
}, | |||||
// 导出excel文件 | |||||
{ exportLoading, exportData } = useExportExc(), | |||||
handleExcel = () => { | |||||
exportData(() => declareExport(2, { | |||||
...searchForm, | |||||
createOnMin: searchForm.times?.[0] || undefined, | |||||
createOnMax: searchForm.times?.[1] || undefined, | |||||
times: undefined | |||||
})) | |||||
}, | |||||
// 预审申报 | |||||
preExamDeclare = (data) => { | |||||
dialogData.visible = true | |||||
dialogData.data = data | |||||
}, | |||||
dialogData = reactive({ | |||||
visible: undefined, | |||||
data: undefined | |||||
}), | |||||
close = (flag) => { | |||||
dialogData.visible = false | |||||
flag && getTableData() | |||||
}, | |||||
checkDetail = (data) => { | |||||
router.push({ name: 'preExaminationDeclareDetail', query: { id: data.id }}) | |||||
} | |||||
onMounted(async () => { | |||||
getTableData() | |||||
}) | |||||
</script> | |||||
<template> | |||||
<el-row> | |||||
<el-card class="w-full search"> | |||||
<el-form :model="searchForm" size="small" label-suffix=":"> | |||||
<el-row :gutter="16" class="mb-16"> | |||||
<el-col :span="8"> | |||||
<el-form-item label="项目名称"> | |||||
<el-input v-model="searchForm.projectName" placeholder="请输入" /> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<el-form-item label="项目类型"> | |||||
<el-select v-model="searchForm.projectType" placeholder="全部" class="w-full"> | |||||
<el-option | |||||
v-for="(v,k) in projectTypeOptions" | |||||
:key="k" | |||||
:label="v" | |||||
:value="k" | |||||
/> | |||||
</el-select> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<el-form-item label="预算年度"> | |||||
<el-date-picker | |||||
v-model="searchForm.projectYear" | |||||
type="year" | |||||
value-format="YYYY" | |||||
placeholder="请选择" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
</el-row> | |||||
<el-row :gutter="16"> | |||||
<el-col :span="10"> | |||||
<el-form-item label="创建时间"> | |||||
<el-date-picker | |||||
v-model="searchForm.times" | |||||
type="datetimerange" | |||||
:editable="false" | |||||
format="YYYY-MM-DD HH:mm" | |||||
value-format="YYYY-MM-DD HH:mm" | |||||
range-separator="-" | |||||
start-placeholder="开始时间" | |||||
end-placeholder="结束时间" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="14"> | |||||
<el-form-item class="btn"> | |||||
<div class="flex"> | |||||
<el-button type="primary" @click="search">查询</el-button> | |||||
<el-button @click="reset">重置</el-button> | |||||
</div> | |||||
</el-form-item> | |||||
</el-col> | |||||
</el-row> | |||||
</el-form> | |||||
</el-card> | |||||
<el-card class="w-full mt-8"> | |||||
<template #header> | |||||
<div class="flex justify-between"> | |||||
<span>待申报的项目</span> | |||||
<div> | |||||
<el-button | |||||
type="primary" | |||||
size="small" | |||||
plain | |||||
:loading="exportLoading" | |||||
@click="handleExcel" | |||||
>导出</el-button> | |||||
</div> | |||||
</div> | |||||
</template> | |||||
<div class="mb-8"> | |||||
<el-alert | |||||
title="温馨提示" | |||||
:closable="false" | |||||
type="info" | |||||
description="一级单位用户有权限进行[申报预审]操作,若您无权操作,请联系您上级单位管理员" | |||||
show-icon | |||||
class="primary-alert" | |||||
/> | |||||
</div> | |||||
<table-list | |||||
ref="tableListRef" | |||||
:column="column" | |||||
:data="data" | |||||
:total="total" | |||||
@get-table-data="getTableData" | |||||
> | |||||
<template #action="{ scope }"> | |||||
<a v-if="scope.row.canPreDeclared" @click="preExamDeclare(scope.row)">申报预审</a> | |||||
<a @click="checkDetail(scope.row)">详情</a> | |||||
</template> | |||||
</table-list> | |||||
</el-card> | |||||
</el-row> | |||||
<pre-examination-dialog :visible="dialogData.visible" :data="dialogData.data" @close="close" /> | |||||
</template> | |||||
<style lang='less' scoped> | |||||
.container{ | |||||
position: relative; | |||||
.funcBtn{ | |||||
position: absolute; | |||||
top: 0; | |||||
right: 26px; | |||||
} | |||||
} | |||||
:deep(.el-form--inline .el-form-item) { | |||||
display: inline-flex; | |||||
vertical-align: middle; | |||||
margin-right: 8px; | |||||
} | |||||
</style> |
@@ -0,0 +1,252 @@ | |||||
<script setup name="projectAdjustment"> | |||||
import { ref, reactive, onMounted, h } from 'vue' | |||||
import { declareExport, projectAdjustmentList } from '@/http/apis/declareMange' | |||||
import store from '@/store' | |||||
import { useRouter } from 'vue-router' | |||||
import useExportExc from '@/utils/useExportExc' | |||||
const { statusOptionsCascader, statusOptions, projectTypeOptions } = | |||||
store.dictStore.globalDicts || {}, | |||||
router = useRouter() | |||||
// 搜索栏表单数据 | |||||
const formInline = reactive({ | |||||
projectType: undefined, | |||||
status: undefined, | |||||
projectYear: undefined, | |||||
projectName: undefined, | |||||
createOnMin: undefined, | |||||
createOnMax: undefined, | |||||
times: [] | |||||
}), | |||||
column = reactive([ | |||||
{ | |||||
label: '序号', | |||||
type: 'index', | |||||
width: '80' | |||||
}, | |||||
{ | |||||
label: '项目名称', | |||||
key: 'projectName', | |||||
prop: 'projectName', | |||||
minWidth: '200', | |||||
showOverflowTooltip: true | |||||
}, | |||||
{ | |||||
label: '项目类型', | |||||
key: 'projectTypeName', | |||||
prop: 'projectTypeName', | |||||
width: '80' | |||||
}, | |||||
{ | |||||
label: '申报金额(万元)', | |||||
key: 'declaredAmount', | |||||
prop: 'declaredAmount', | |||||
width: '150' | |||||
}, | |||||
{ | |||||
label: '预算年度', | |||||
key: 'projectYear', | |||||
prop: 'projectYear', | |||||
width: 80 | |||||
}, | |||||
{ | |||||
label: '项目状态', | |||||
key: 'status', | |||||
prop: 'status', | |||||
width: '220', | |||||
render: row => [ | |||||
h('span', { | |||||
class: ['dot mr-4', `bg-${statusOptions[row.status]?.color}`] | |||||
}), | |||||
h( | |||||
'span', | |||||
{ | |||||
class: `text-${statusOptions[row.status]?.color}` | |||||
}, | |||||
row.status && statusOptions[row.stage]?.name + '-' + statusOptions[row.status]?.name | |||||
) | |||||
] | |||||
}, | |||||
{ | |||||
label: '创建时间', | |||||
key: 'createOn', | |||||
prop: 'createOn', | |||||
showOverflowTooltip: true, | |||||
width: '200' | |||||
}, | |||||
{ | |||||
label: '操作', | |||||
slot: 'action', | |||||
width: '150px', | |||||
fixed: 'right' | |||||
} | |||||
]), | |||||
data = ref([]), | |||||
tableListRef = ref(), | |||||
getTableData = async (pageParams = tableListRef.value.pageParams) => { | |||||
const res = await projectAdjustmentList({ | |||||
...pageParams, | |||||
...formInline, | |||||
createOnMin: formInline.times?.[0], | |||||
createOnMax: formInline.times?.[1], | |||||
projectYear: formInline.projectYear * 1 || undefined, | |||||
status: formInline.status?.[formInline.status.length - 1], | |||||
times: undefined | |||||
}) | |||||
data.value = res.data.records | |||||
total.value = res.data.total | |||||
}, | |||||
// 数据总数 | |||||
total = ref(2), | |||||
// 提交查询 | |||||
search = () => { | |||||
getTableData() | |||||
}, | |||||
// 重置 | |||||
formReset = () => { | |||||
formInline.status = undefined | |||||
formInline.projectYear = undefined | |||||
formInline.projectName = undefined | |||||
formInline.projectType = undefined | |||||
formInline.createOnMin = undefined | |||||
formInline.createOnMax = undefined | |||||
formInline.times = undefined | |||||
tableListRef.value.pageParams.pageNumber = 1 | |||||
tableListRef.value.pageParams.pageSize = 10 | |||||
getTableData() | |||||
}, | |||||
// 导出excel文件 | |||||
{ exportLoading, exportData } = useExportExc(), | |||||
handleExcel = () => { | |||||
exportData(() => declareExport(4, { | |||||
...formInline, | |||||
createOnMin: formInline.times?.[0], | |||||
createOnMax: formInline.times?.[1], | |||||
projectYear: formInline.projectYear * 1 || undefined, | |||||
status: formInline.status?.[formInline.status.length - 1], | |||||
times: undefined | |||||
})) | |||||
}, | |||||
reDeclare = (row) => { | |||||
if (row.status === 20005) { | |||||
router.push({ name: 'declarationFinal', query: { id: row.id }}) | |||||
} else { | |||||
router.push({ name: 'declarePage', query: { id: row.id }}) | |||||
} | |||||
} | |||||
onMounted(async () => { | |||||
getTableData() | |||||
}) | |||||
</script> | |||||
<template> | |||||
<el-card class="w-full search"> | |||||
<el-form :model="formInline" size="small" label-suffix=":"> | |||||
<el-row :gutter="16" class="mb-16"> | |||||
<el-col :span="8"> | |||||
<el-form-item label="项目名称"> | |||||
<el-input | |||||
v-model="formInline.projectName" | |||||
maxlength="50" | |||||
placeholder="请输入" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<el-form-item label="项目类型"> | |||||
<el-select | |||||
v-model="formInline.projectType" | |||||
placeholder="全部" | |||||
class="w-full" | |||||
> | |||||
<el-option | |||||
v-for="(v,k) in projectTypeOptions" | |||||
:key="k" | |||||
:label="v" | |||||
:value="k" | |||||
/> | |||||
</el-select> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<el-form-item label="项目状态"> | |||||
<el-cascader | |||||
v-model="formInline.status" | |||||
class="w-full" | |||||
:props="{label:'name',value:'code'}" | |||||
:options="statusOptionsCascader.map(i=>{ | |||||
return { | |||||
...i, | |||||
children:i?.children?.filter(j=>j.color==='danger') | |||||
} | |||||
})" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
</el-row> | |||||
<el-row :gutter="20"> | |||||
<el-col :span="8"> | |||||
<el-form-item label="预算年度"> | |||||
<el-date-picker | |||||
v-model="formInline.projectYear" | |||||
type="year" | |||||
placeholder="请选择" | |||||
format="YYYY" | |||||
value-format="YYYY" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="12"> | |||||
<el-form-item label="创建时间"> | |||||
<el-date-picker | |||||
v-model="formInline.times" | |||||
type="datetimerange" | |||||
range-separator="-" | |||||
start-placeholder="开始时间" | |||||
end-placeholder="结束时间" | |||||
format="YYYY-MM-DD HH:mm" | |||||
value-format="YYYY-MM-DD HH:mm" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="4"> | |||||
<el-form-item class="btn"> | |||||
<div class="flex"> | |||||
<el-button type="primary" @click="search">查询</el-button> | |||||
<el-button @click="formReset">重置</el-button> | |||||
</div> | |||||
</el-form-item> | |||||
</el-col> | |||||
</el-row> | |||||
</el-form> | |||||
</el-card> | |||||
<el-card class="w-full mt-8"> | |||||
<template #header> | |||||
<div class="flex justify-between"> | |||||
<span>待调整的项目</span> | |||||
<div> | |||||
<el-button | |||||
type="primary" | |||||
size="small" | |||||
plain | |||||
:loading="exportLoading" | |||||
@click="handleExcel" | |||||
> | |||||
导出 | |||||
</el-button> | |||||
</div> | |||||
</div> | |||||
</template> | |||||
<table-list | |||||
ref="tableListRef" | |||||
:column="column" | |||||
:data="data" | |||||
:total="total" | |||||
@get-table-data="getTableData" | |||||
> | |||||
<template #action="{ scope }"> | |||||
<a v-if="scope.row.status!==10009" @click="reDeclare(scope.row)">重新申报</a> | |||||
<a @click="router.push({name:'projectDeclareDetail',query:{id:scope.row.id}})">详情</a> | |||||
</template> | |||||
</table-list> | |||||
</el-card> | |||||
</template> | |||||
<style lang="less" scoped></style> |
@@ -0,0 +1,298 @@ | |||||
<script name="accessory" setup> | |||||
import { ref } from 'vue' | |||||
import { fileFormatVerification, handleFileSuccess, reviewFileParam, handleFilePreview, fileTypes, fileDesc } from '@/utils/uploadAction.js' | |||||
import store from '@/store' | |||||
defineProps({ | |||||
detailData: { | |||||
type: Object, | |||||
default: () => { | |||||
return {} | |||||
} | |||||
}, | |||||
projectType: { | |||||
type: String, | |||||
default: '' | |||||
}, | |||||
declareAmount: { | |||||
type: Number | |||||
} | |||||
}) | |||||
const uploadUrl = store.dictStore.uploadUrl, | |||||
formData = ref({ | |||||
constructionPlanFile: [], | |||||
preliminaryPlanFile: [], | |||||
mainResponsibilitiesApplicantFile: [], | |||||
supportingMaterialsFile: [], | |||||
calculationTotalInvestmentFile: [], | |||||
projectApplicationForm: [], | |||||
mainAccusationDoc: [] | |||||
}), | |||||
formRef = ref(), | |||||
rules = { | |||||
preliminaryPlanFile: [ | |||||
{ required: true, message: '请上传初步方案', trigger: 'blur' } | |||||
], | |||||
supportingMaterialsFile: [ | |||||
{ required: true, message: '请上传佐证材料', trigger: 'blur' } | |||||
], | |||||
calculationTotalInvestmentFile: [ | |||||
{ required: true, message: '请上传项目总投资测算明细', trigger: 'blur' } | |||||
], | |||||
mainResponsibilitiesApplicantFile: [ | |||||
{ required: true, message: '请上传申报单位主要职责(单位三定方案)', trigger: 'blur' } | |||||
], | |||||
projectApplicationForm: [{ required: true, message: '请上传项目申报书' }], | |||||
baseResearchReportFile: [{ required: true, message: '请上传可行性研究报告' }], | |||||
constructionPlanFile: [{ required: true, message: '请上传建设方案' }], | |||||
mainAccusationDoc: [{ required: true, message: '请上传申报单位主要职责(单位三定方案)', trigger: 'blur' }] | |||||
}, | |||||
// 校验 | |||||
validForm = (callback) => { | |||||
formRef.value.validate(valid => { | |||||
callback(valid) | |||||
}) | |||||
}, | |||||
// 回显 | |||||
setFormData = (data) => { | |||||
formData.value = { | |||||
constructionPlanFile: data.constructionPlanFile ? reviewFileParam(JSON.parse(data.constructionPlanFile)) : [], | |||||
preliminaryPlanFile: data.preliminaryPlanFile ? reviewFileParam(JSON.parse(data.preliminaryPlanFile)) : [], | |||||
mainResponsibilitiesApplicantFile: data.mainResponsibilitiesApplicantFile ? reviewFileParam(JSON.parse(data.mainResponsibilitiesApplicantFile)) : [], | |||||
supportingMaterialsFile: data.supportingMaterialsFile ? reviewFileParam(JSON.parse(data.supportingMaterialsFile)) : [], | |||||
baseResearchReportFile: data.baseResearchReportFile ? reviewFileParam(JSON.parse(data.baseResearchReportFile)) : [], | |||||
calculationTotalInvestmentFile: data.calculationTotalInvestmentFile ? reviewFileParam(JSON.parse(data.calculationTotalInvestmentFile)) : [], | |||||
projectApplicationForm: data.projectApplicationForm ? reviewFileParam(JSON.parse(data.projectApplicationForm)) : [], | |||||
baseProjOtherFile: data.baseProjOtherFile ? reviewFileParam(JSON.parse(data.baseProjOtherFile)) : [], | |||||
mainAccusationDoc: data.mainAccusationDoc ? reviewFileParam(JSON.parse(data.mainAccusationDoc)) : [] | |||||
} | |||||
} | |||||
defineExpose({ validForm, formData, setFormData }) | |||||
</script> | |||||
<template> | |||||
<el-form | |||||
ref="formRef" | |||||
:model="formData" | |||||
:rules="rules" | |||||
label-position="right" | |||||
label-width="180px" | |||||
label-suffix=":" | |||||
scroll-to-error | |||||
> | |||||
<el-row :gutter="40"> | |||||
<el-col :span="12"> | |||||
<el-form-item label="初步设计方案"> | |||||
<el-upload | |||||
v-model:file-list="formData.preliminaryPlanFile" | |||||
class="w-full" | |||||
:action="uploadUrl" | |||||
:limit="1" | |||||
:on-success="res => handleFileSuccess(res, formData.preliminaryPlanFile, true)" | |||||
:before-upload="file=>fileFormatVerification(file, { | |||||
types: fileTypes | |||||
})" | |||||
:accept="fileTypes.map(i=>`.${i}`).join(',')" | |||||
:on-preview="handleFilePreview" | |||||
> | |||||
<el-button type="primary" plain>选择文件</el-button> | |||||
<template #tip> | |||||
<div class="el-upload__tip"> | |||||
支持{{ fileDesc }}文件 | |||||
</div> | |||||
</template> | |||||
</el-upload> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col v-if="false" :span="12"> | |||||
<el-form-item | |||||
label="佐证材料" | |||||
prop="supportingMaterialsFile" | |||||
> | |||||
<el-upload | |||||
v-model:file-list="formData.supportingMaterialsFile" | |||||
class="upload-demo" | |||||
:action="uploadUrl" | |||||
multiple | |||||
:on-success="res => handleFileSuccess(res, formData.supportingMaterialsFile)" | |||||
:before-upload="file=>fileFormatVerification(file, { | |||||
types: fileTypes | |||||
})" | |||||
:accept="fileTypes.map(i=>`.${i}`).join(',')" | |||||
:limit="10" | |||||
:on-preview="handleFilePreview" | |||||
> | |||||
<el-button plain type="primary">选择文件</el-button> | |||||
<template #tip> | |||||
<div class="el-upload__tip"> | |||||
支持{{ fileDesc }}文件 | |||||
</div> | |||||
</template> | |||||
</el-upload> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col v-if="false" :span="12"> | |||||
<el-form-item label="项目总投资测算明细" prop="calculationTotalInvestmentFile"> | |||||
<el-upload | |||||
ref="investmentCalculationDetailsRef" | |||||
v-model:file-list="formData.calculationTotalInvestmentFile" | |||||
class="upload-demo" | |||||
:action="uploadUrl" | |||||
multiple | |||||
:on-success="res => handleFileSuccess(res, formData.calculationTotalInvestmentFile)" | |||||
:before-upload="file=>fileFormatVerification(file, {types: fileTypes})" | |||||
:accept="fileTypes.map(i=>`.${i}`).join(',')" | |||||
:limit="10" | |||||
:on-preview="handleFilePreview" | |||||
> | |||||
<el-button plain type="primary">选择文件</el-button> | |||||
<template #tip> | |||||
<div class="el-upload__tip"> | |||||
支持{{ fileDesc }}文件 | |||||
</div> | |||||
</template> | |||||
</el-upload> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col v-if="false" :span="12"> | |||||
<el-form-item | |||||
label="申报单位主要职责(单位三定方案)" | |||||
prop="mainResponsibilitiesApplicantFile" | |||||
> | |||||
<el-upload | |||||
v-model:file-list="formData.mainResponsibilitiesApplicantFile" | |||||
class="upload-demo" | |||||
:action="uploadUrl" | |||||
multiple | |||||
:on-success="res => handleFileSuccess(res, formData.mainResponsibilitiesApplicantFile)" | |||||
:before-upload="file=>fileFormatVerification(file, {types: fileTypes})" | |||||
:accept="fileTypes.map(i=>`.${i}`).join(',')" | |||||
:limit="10" | |||||
:on-preview="handleFilePreview" | |||||
> | |||||
<el-button plain type="primary">选择文件</el-button> | |||||
<template #tip> | |||||
<div class="el-upload__tip"> | |||||
支持{{ fileDesc }}文件 | |||||
</div> | |||||
</template> | |||||
</el-upload> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col v-if="projectType!=='03'&&false" :span="12"> | |||||
<el-form-item label="项目申报书" prop="projectApplicationForm"> | |||||
<el-upload | |||||
v-model:file-list="formData.projectApplicationForm" | |||||
class="w-full" | |||||
:action="uploadUrl" | |||||
:limit="1" | |||||
:on-success="res => handleFileSuccess(res, formData.projectApplicationForm, true)" | |||||
:before-upload="file=>fileFormatVerification(file, {types: fileTypes})" | |||||
:accept="fileTypes.map(i=>`.${i}`).join(',')" | |||||
:on-preview="handleFilePreview" | |||||
> | |||||
<el-button type="primary" plain>选择文件</el-button> | |||||
<template #tip> | |||||
<div class="el-upload__tip"> | |||||
支持{{ fileDesc }}文件 | |||||
</div> | |||||
</template> | |||||
</el-upload> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col v-if="projectType!=='03'" :span="12"> | |||||
<el-form-item label="可行性研究报告" prop="baseResearchReportFile"> | |||||
<el-upload | |||||
v-model:file-list="formData.baseResearchReportFile" | |||||
class="w-full" | |||||
:action="uploadUrl" | |||||
:limit="1" | |||||
:on-success="res => handleFileSuccess(res, formData.baseResearchReportFile, true)" | |||||
:before-upload="file=>fileFormatVerification(file, {types: fileTypes})" | |||||
:accept="fileTypes.map(i=>`.${i}`).join(',')" | |||||
:on-preview="handleFilePreview" | |||||
> | |||||
<el-button type="primary" plain>选择文件</el-button> | |||||
<template #tip> | |||||
<div class="el-upload__tip"> | |||||
支持{{ fileDesc }}文件 | |||||
</div> | |||||
</template> | |||||
</el-upload> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col v-if="$route.name==='declarePlan'||[10012,10013,10016].includes(detailData?.status)" :span="12"> | |||||
<el-form-item label="建设方案" prop="constructionPlanFile"> | |||||
<el-upload | |||||
v-model:file-list="formData.constructionPlanFile" | |||||
class="w-full" | |||||
:action="uploadUrl" | |||||
:limit="1" | |||||
:on-success="res => handleFileSuccess(res, formData.constructionPlanFile, true)" | |||||
:before-upload="file=>fileFormatVerification(file, {types: fileTypes})" | |||||
:accept="fileTypes.map(i=>`.${i}`).join(',')" | |||||
:on-preview="handleFilePreview" | |||||
> | |||||
<el-button type="primary" plain>选择文件</el-button> | |||||
<template #tip> | |||||
<div class="el-upload__tip"> | |||||
支持{{ fileDesc }}文件 | |||||
</div> | |||||
</template> | |||||
</el-upload> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="12"> | |||||
<el-form-item label="其他附件"> | |||||
<el-upload | |||||
ref="baseProjOtherFileRef" | |||||
v-model:file-list="formData.baseProjOtherFile" | |||||
class="upload-demo" | |||||
:action="uploadUrl" | |||||
multiple | |||||
:on-success="res => handleFileSuccess(res, formData.baseProjOtherFile)" | |||||
:before-upload="file=>fileFormatVerification(file, {types: fileTypes})" | |||||
:accept="fileTypes.map(i=>`.${i}`).join(',')" | |||||
:limit="10" | |||||
:on-preview="handleFilePreview" | |||||
> | |||||
<el-button plain type="primary">选择文件</el-button> | |||||
<template #tip> | |||||
<div class="el-upload__tip"> | |||||
支持{{ fileDesc }}文件 | |||||
</div> | |||||
</template> | |||||
</el-upload> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="12"> | |||||
<el-form-item v-if="declareAmount>=1000" label="申报单位主要职责文件(单位三定职责)" prop="mainAccusationDoc"> | |||||
<el-upload | |||||
ref="mainAccusationDocRef" | |||||
v-model:file-list="formData.mainAccusationDoc" | |||||
class="upload-demo" | |||||
:action="uploadUrl" | |||||
multiple | |||||
:on-success="res => handleFileSuccess(res, formData.mainAccusationDoc)" | |||||
:before-upload="file=>fileFormatVerification(file, {types: fileTypes})" | |||||
:accept="fileTypes.map(i=>`.${i}`).join(',')" | |||||
:limit="10" | |||||
:on-preview="handleFilePreview" | |||||
> | |||||
<el-button plain type="primary">选择文件</el-button> | |||||
<template #tip> | |||||
<div class="el-upload__tip"> | |||||
支持{{ fileDesc }}文件 | |||||
</div> | |||||
</template> | |||||
</el-upload> | |||||
</el-form-item> | |||||
</el-col> | |||||
</el-row> | |||||
</el-form> | |||||
</template> | |||||
<style lang="less"> | |||||
.el-upload-list{ | |||||
width: 100%; | |||||
} | |||||
</style> |
@@ -0,0 +1,158 @@ | |||||
<script name="annualPaymentPlan" setup> | |||||
import { ref } from 'vue' | |||||
const formData = ref({}), | |||||
formRef = ref(), | |||||
moneyValidator = (rule, value, callback) => { | |||||
if (!value) callback() | |||||
if (!/^\d+(\.\d{1,6})?$/.test(value)) { | |||||
callback('请输入正确格式,最多保留六位小数') | |||||
} else if (value * 1 >= 100000000) { | |||||
callback('请输入正确格式,小于100000000') | |||||
} else { | |||||
callback() | |||||
} | |||||
}, | |||||
rules = { | |||||
annualPlanAmount: [ | |||||
{ required: true, message: '请输入年度支付金额', trigger: 'blur' }, | |||||
{ validator: moneyValidator, trigger: 'blur' } | |||||
], | |||||
annualPlanHaveAmount: [ | |||||
{ required: true, message: '请输入自有资金', trigger: 'blur' }, | |||||
{ validator: moneyValidator, trigger: 'blur' } | |||||
], | |||||
annualPlanGovOwnFinanceAmount: [ | |||||
{ | |||||
required: true, | |||||
message: '请输入政府投资-本级财政资金', | |||||
trigger: 'blur' | |||||
}, | |||||
{ validator: moneyValidator, trigger: 'blur' } | |||||
], | |||||
annualPlanGovSuperiorFinanceAmount: [ | |||||
{ | |||||
required: true, | |||||
message: '请输入政府投资-上级补助资金', | |||||
trigger: 'blur' | |||||
}, | |||||
{ validator: moneyValidator, trigger: 'blur' } | |||||
], | |||||
annualPlanBankLendingAmount: [ | |||||
{ required: true, message: '请输入银行贷款', trigger: 'blur' }, | |||||
{ validator: moneyValidator, trigger: 'blur' } | |||||
], | |||||
annualPlanOtherAmount: [{ required: true, message: '请输入其他', trigger: 'blur' }, | |||||
{ validator: moneyValidator, trigger: 'blur' }] | |||||
}, | |||||
// 校验 | |||||
validForm = (callback) => { | |||||
formRef.value.validate(valid => { | |||||
callback(valid) | |||||
}) | |||||
}, | |||||
// 回显 | |||||
setFormData = (data) => { | |||||
formData.value = { | |||||
annualPlanAmount: data.annualPlanAmount, | |||||
annualPlanHaveAmount: data.annualPlanHaveAmount, | |||||
annualPlanGovOwnFinanceAmount: data.annualPlanGovOwnFinanceAmount, | |||||
annualPlanGovSuperiorFinanceAmount: data.annualPlanGovSuperiorFinanceAmount, | |||||
annualPlanBankLendingAmount: data.annualPlanBankLendingAmount, | |||||
annualPlanOtherAmount: data.annualPlanOtherAmount | |||||
} | |||||
} | |||||
defineExpose({ validForm, formData, setFormData }) | |||||
</script> | |||||
<template> | |||||
<el-form | |||||
ref="formRef" | |||||
:model="formData" | |||||
:rules="rules" | |||||
label-position="right" | |||||
label-width="180px" | |||||
label-suffix=":" | |||||
scroll-to-error | |||||
> | |||||
<el-row :gutter="40"> | |||||
<el-col :span="24"> | |||||
<el-form-item label="年度支付金额" prop="annualPlanAmount"> | |||||
<el-input-number | |||||
v-model="formData.annualPlanAmount" | |||||
placeholder="请填写" | |||||
:min="0" | |||||
:controls="false" | |||||
@mousewheel.prevent | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="12"> | |||||
<el-form-item label="自有资金" prop="annualPlanHaveAmount"> | |||||
<el-input-number | |||||
v-model="formData.annualPlanHaveAmount" | |||||
placeholder="请填写" | |||||
:min="0" | |||||
:controls="false" | |||||
@mousewheel.prevent | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="12"> | |||||
<el-form-item | |||||
label="政府投资-本级财政资金" | |||||
prop="annualPlanGovOwnFinanceAmount" | |||||
> | |||||
<el-input-number | |||||
v-model="formData.annualPlanGovOwnFinanceAmount" | |||||
placeholder="请填写" | |||||
:min="0" | |||||
:controls="false" | |||||
@mousewheel.prevent | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="12"> | |||||
<el-form-item | |||||
label="政府投资-上级补助资金" | |||||
prop="annualPlanGovSuperiorFinanceAmount" | |||||
> | |||||
<el-input-number | |||||
v-model="formData.annualPlanGovSuperiorFinanceAmount" | |||||
placeholder="请填写" | |||||
:min="0" | |||||
:controls="false" | |||||
@mousewheel.prevent | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="12"> | |||||
<el-form-item label="银行贷款" prop="annualPlanBankLendingAmount"> | |||||
<el-input-number | |||||
v-model="formData.annualPlanBankLendingAmount" | |||||
placeholder="请填写" | |||||
:min="0" | |||||
:controls="false" | |||||
@mousewheel.prevent | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="12"> | |||||
<el-form-item label="其他" prop="annualPlanOtherAmount"> | |||||
<el-input-number | |||||
v-model="formData.annualPlanOtherAmount" | |||||
placeholder="请填写" | |||||
:min="0" | |||||
:controls="false" | |||||
@mousewheel.prevent | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
</el-row> | |||||
</el-form> | |||||
</template> | |||||
<style lang="less"> | |||||
.el-upload-list{ | |||||
width: 100%; | |||||
} | |||||
</style> |
@@ -0,0 +1,460 @@ | |||||
<script name="appBasicInfo" setup> | |||||
import { watch, ref } from 'vue' | |||||
import store from '@/store' | |||||
import { fileFormatVerification, handleFileSuccess, handleFilePreview, fileTypes, fileDesc } from '@/utils/uploadAction.js' | |||||
import { applicationList, piotTasks } from '@/http/apis/declareMange' | |||||
import { storeToRefs } from 'pinia' | |||||
const { | |||||
accountAppNameOption, | |||||
constructionLevel, | |||||
applicationType, | |||||
businessField, | |||||
publisher, | |||||
useScope, | |||||
digitalModifySystem, | |||||
domainBrainAccountOptions | |||||
} = store.dictStore.globalDicts || {}, | |||||
uploadUrl = store.dictStore.uploadUrl, | |||||
userInfo = storeToRefs(store.userStore).userInfo || {}, | |||||
props = defineProps({ | |||||
data: { | |||||
type: Object, | |||||
default: null | |||||
}, | |||||
drawerVisible: { | |||||
type: Boolean, | |||||
default: false | |||||
}, | |||||
isInnovateWholeProvinceShare: { | |||||
type: Boolean, | |||||
default: false | |||||
} | |||||
}), | |||||
formData = ref({ | |||||
experimentsFile: [] | |||||
}), | |||||
formRef = ref(), | |||||
rules = { | |||||
isFirst: [{ required: true, message: '请选择是否为首次建设' }], | |||||
applicationName: [ | |||||
{ required: true, message: '请填写应用名称' } | |||||
], | |||||
relatedExistsApplication: [{ required: true, message: '请选择IRS注册应用' }], | |||||
relatedExistsApplicationCode: [{ required: true, message: '请选择IRS应用编码' }], | |||||
pilotTasksName: [{ required: true, message: '请选择试点任务名称' }], | |||||
pilotTasksCode: [{ required: true, message: '请选择试点任务编号' }], | |||||
importantTaskName: [{ required: true, message: '所属重大应用名称' }], | |||||
importantTaskCode: [{ required: true, message: '所属重大应用编码' }], | |||||
subSceneApplicationName: [{ required: true, message: '所属子场景应用名称' }], | |||||
experimentsFile: [{ required: true, message: '请上传试点文件' }], | |||||
applicationType: [{ required: true, message: '请选择应用类型' }], | |||||
buildLevel: [{ required: true, message: '请选择建设层级', trigger: 'change' }], | |||||
isUniteBuild: [{ required: true, message: '请选择是否为统建应用' }], | |||||
unionBuildKind: [{ required: true, message: '请选择统建类型' }], | |||||
isDigitalModification: [{ required: true, message: '请选择是否为数改系统' }], | |||||
digitalModification: [{ required: true, message: '请选择数改系统' }], | |||||
bizDomain: [{ required: true, message: '请选择业务领域' }], | |||||
publishSide: [{ required: true, message: '请选择发布端' }], | |||||
isAccountAppName: [{ required: true, message: '请选择是否S2一本账名称' }], | |||||
accountAppName: [{ required: true, message: '请选择S2一本账名称' }], | |||||
domainBrainAccount: [{ required: true, message: '请选择领域“大脑”一本账' }], | |||||
isBizCooperate: [{ required: true, message: '请选择是否为业务协同' }], | |||||
bizCooperateInfo: [{ required: true, message: '请填写业务协同描述' }], | |||||
usesRangeRemark: [{ required: true, message: '请选择使用范围' }], | |||||
applicationSummary: [{ required: true, message: '请填写应用简介' }], | |||||
applicationRemark: [{ required: true, message: '请填写应用备注' }], | |||||
applicationEstimateFile: [{ required: true, message: '请上传总投资测算明细' }] | |||||
}, | |||||
// 校验 | |||||
validForm = (callback) => { | |||||
formRef.value.validate(valid => { | |||||
callback(valid) | |||||
}) | |||||
}, | |||||
// 清空校验 | |||||
clearValidate = () => { | |||||
formRef.value.clearValidate() | |||||
}, | |||||
// 获取irs应用列表 | |||||
applicationOptions = ref([]), | |||||
getApplicationOptions = async () => { | |||||
const res = await applicationList({ areaCode: userInfo.value.regionCode }) | |||||
applicationOptions.value = res.data | |||||
}, | |||||
// 获取试点任务列表 | |||||
piotTasksOptions = ref([]), | |||||
getPiotTasksOptions = async () => { | |||||
const res = await piotTasks() | |||||
piotTasksOptions.value = res.data | |||||
}, | |||||
// 修改关联应用 | |||||
changeIrsApp = (data) => { | |||||
formData.value.relatedExistsApplicationCode = data.applicationCode | |||||
}, | |||||
// 修改试点任务 | |||||
changePilotTask = (data) => { | |||||
formData.value.pilotTasksCode = data.taskCode | |||||
formData.value.importantTaskName = data.importantTaskName | |||||
formData.value.importantTaskCode = data.importantTaskCode | |||||
formData.value.subSceneApplicationName = data.subSceneApplicationName | |||||
}, | |||||
// 修改是否初次建设 | |||||
changeIsFirst = () => { | |||||
if (formData.value.isFirst === 1) { | |||||
formData.value.relatedExistsApplication = undefined | |||||
formData.value.relatedExistsApplicationCode = undefined | |||||
} else { | |||||
formData.value.applicationName = undefined | |||||
} | |||||
} | |||||
watch( | |||||
() => props.drawerVisible, | |||||
val => { | |||||
if (val) { | |||||
formData.value = { | |||||
...props.data, | |||||
isFirst: props.data.isFirst || undefined | |||||
} | |||||
getApplicationOptions() | |||||
getPiotTasksOptions() | |||||
} | |||||
}, | |||||
{ immediate: true } | |||||
) | |||||
defineExpose({ validForm, formData, clearValidate }) | |||||
</script> | |||||
<template> | |||||
<el-form | |||||
ref="formRef" | |||||
:model="formData" | |||||
:rules="rules" | |||||
label-position="right" | |||||
label-width="180px" | |||||
label-suffix=":" | |||||
scroll-to-error | |||||
> | |||||
<el-row :gutter="20"> | |||||
<el-col v-if="!props.isInnovateWholeProvinceShare" :span="12"> | |||||
<el-form-item label="是否初次建设" prop="isFirst" @change="changeIsFirst"> | |||||
<el-radio-group v-model="formData.isFirst"> | |||||
<el-radio :label="1">是</el-radio> | |||||
<el-radio :label="2">否</el-radio> | |||||
</el-radio-group> | |||||
</el-form-item> | |||||
</el-col> | |||||
<template v-if="formData.isFirst===2||props.isInnovateWholeProvinceShare"> | |||||
<el-col :span="12"> | |||||
<el-form-item label="关联IRS已注册应用" prop="relatedExistsApplication"> | |||||
<el-select | |||||
v-model="formData.relatedExistsApplication" | |||||
class="w-full" | |||||
placeholder="请选择" | |||||
value-key="applicationCode" | |||||
@change="changeIrsApp" | |||||
> | |||||
<el-option | |||||
v-for="(item, index) in applicationOptions" | |||||
:key="index" | |||||
:label="item.applicationName" | |||||
:value="{applicationCode:item.applicationCode,applicationName:item.applicationName}" | |||||
/> | |||||
</el-select> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="12"> | |||||
<el-form-item label="IRS应用编码" prop="relatedExistsApplicationCode"> | |||||
<el-input v-model="formData.relatedExistsApplicationCode" disabled /> | |||||
</el-form-item> | |||||
</el-col> | |||||
</template> | |||||
<template v-if="props.isInnovateWholeProvinceShare"> | |||||
<el-col :span="12"> | |||||
<el-form-item label="试点任务名称" prop="pilotTasksName"> | |||||
<el-select | |||||
v-model="formData.pilotTasksName" | |||||
class="w-full" | |||||
placeholder="请选择" | |||||
value-key="taskCode" | |||||
@change="changePilotTask" | |||||
> | |||||
<el-option | |||||
v-for="(item, index) in piotTasksOptions" | |||||
:key="index" | |||||
:label="item.taskName" | |||||
:value="item" | |||||
/> | |||||
</el-select> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="12"> | |||||
<el-form-item label="试点任务编号" prop="pilotTasksCode"> | |||||
<el-input v-model="formData.pilotTasksCode" disabled /> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="12"> | |||||
<el-form-item label="所属重大应用名称" prop="importantTaskName"> | |||||
<el-input v-model="formData.importantTaskName" disabled /> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="12"> | |||||
<el-form-item label="所属重大应用编码" prop="importantTaskCode"> | |||||
<el-input v-model="formData.importantTaskCode" disabled /> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="12"> | |||||
<el-form-item label="所属子场景应用名称" prop="subSceneApplicationName"> | |||||
<el-input v-model="formData.subSceneApplicationName" disabled /> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="12"> | |||||
<el-form-item label="试点文件" prop="experimentsFile"> | |||||
<el-upload | |||||
ref="preliminaryPlanRef" | |||||
v-model:file-list="formData.experimentsFile" | |||||
class="upload-demo" | |||||
:action="uploadUrl" | |||||
multiple | |||||
:on-success="res => handleFileSuccess(res, formData.experimentsFile, true)" | |||||
:before-upload="file=>fileFormatVerification(file, {types: fileTypes})" | |||||
:accept="fileTypes.map(i=>`.${i}`).join(',')" | |||||
:limit="1" | |||||
:on-preview="handleFilePreview" | |||||
> | |||||
<el-button plain type="primary">选择文件</el-button> | |||||
<template #tip> | |||||
<div class="el-upload__tip"> | |||||
支持{{ fileDesc }}文件 | |||||
</div> | |||||
</template> | |||||
</el-upload> | |||||
</el-form-item> | |||||
</el-col> | |||||
</template> | |||||
<el-col v-if="formData.isFirst===1&&!props.isInnovateWholeProvinceShare" :span="12"> | |||||
<el-form-item label="应用名称" prop="applicationName"> | |||||
<el-input | |||||
v-model="formData.applicationName" | |||||
placeholder="请填写" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="12"> | |||||
<el-form-item label="应用类型" prop="applicationType"> | |||||
<el-select v-model="formData.applicationType" placeholder="请选择" class="w-full"> | |||||
<el-option | |||||
v-for="(item, index) in applicationType" | |||||
:key="index" | |||||
:label="item" | |||||
:value="item" | |||||
/> | |||||
</el-select> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="24"> | |||||
<el-form-item label="建设层级" prop="buildLevel"> | |||||
<el-radio-group v-model="formData.buildLevel"> | |||||
<el-radio | |||||
v-for="(item, index) in constructionLevel" | |||||
:key="index" | |||||
:label="index*1" | |||||
>{{ item }} | |||||
</el-radio> | |||||
</el-radio-group> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="12"> | |||||
<el-form-item label="是否统建应用" prop="isUniteBuild"> | |||||
<el-radio-group v-model="formData.isUniteBuild"> | |||||
<el-radio :label="1">是</el-radio> | |||||
<el-radio :label="0">否</el-radio> | |||||
</el-radio-group> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="12"> | |||||
<el-form-item v-if="formData.isUniteBuild===1" label="统建类型" prop="unionBuildKind"> | |||||
<el-radio-group v-model="formData.unionBuildKind"> | |||||
<el-radio :label="1">全省统建</el-radio> | |||||
<el-radio :label="2">全市统建</el-radio> | |||||
</el-radio-group> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="12"> | |||||
<el-form-item label="是否数改系统" prop="isDigitalModification"> | |||||
<el-radio-group v-model="formData.isDigitalModification"> | |||||
<el-radio :label="1">是</el-radio> | |||||
<el-radio :label="0">否</el-radio> | |||||
</el-radio-group> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="12"> | |||||
<el-form-item v-if="formData.isDigitalModification===1" label="数改系统" prop="digitalModification"> | |||||
<el-select | |||||
v-model="formData.digitalModification" | |||||
multiple | |||||
collapse-tags | |||||
collapse-tags-tooltip | |||||
placeholder="请选择" | |||||
class="w-full" | |||||
> | |||||
<el-option | |||||
v-for="(v, k) in digitalModifySystem" | |||||
:key="k" | |||||
:label="v" | |||||
:value="k" | |||||
/> | |||||
</el-select> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="12"> | |||||
<el-form-item label="业务领域" prop="bizDomain"> | |||||
<el-select v-model="formData.bizDomain" placeholder="请选择" class="w-full"> | |||||
<el-option | |||||
v-for="(item, index) in businessField" | |||||
:key="index" | |||||
:label="item" | |||||
:value="item" | |||||
/> | |||||
</el-select> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="12"> | |||||
<el-form-item label="发布端" prop="publishSide"> | |||||
<el-select v-model="formData.publishSide" placeholder="请选择" class="w-full"> | |||||
<el-option | |||||
v-for="(item, index) in publisher" | |||||
:key="index" | |||||
:label="item" | |||||
:value="item" | |||||
/> | |||||
</el-select> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="12"> | |||||
<el-form-item label="是否S2一本账名称" prop="isAccountAppName"> | |||||
<el-radio-group v-model="formData.isAccountAppName"> | |||||
<el-radio :label="1">是</el-radio> | |||||
<el-radio :label="0">否</el-radio> | |||||
</el-radio-group> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="12"> | |||||
<el-form-item v-if="formData.isAccountAppName === 1" label="S2一本账名称" prop="accountAppName"> | |||||
<el-select | |||||
v-model="formData.accountAppName" | |||||
placeholder="请选择" | |||||
class="w-full" | |||||
clearable | |||||
> | |||||
<el-option | |||||
v-for="(item, index) in accountAppNameOption" | |||||
:key="index" | |||||
:label="item" | |||||
:value="item" | |||||
/> | |||||
</el-select> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="16"> | |||||
<el-form-item v-if="formData.isAccountAppName === 1 && formData.isDigitalModification===1" label="领域“大脑”一本账" prop="domainBrainAccount"> | |||||
<el-select v-model="formData.domainBrainAccount" placeholder="请选择" class="w-full"> | |||||
<el-option | |||||
v-for="(item, index) in domainBrainAccountOptions" | |||||
:key="index" | |||||
:label="item" | |||||
:value="item" | |||||
/> | |||||
</el-select> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="12"> | |||||
<el-form-item label="是否业务协同" prop="isBizCooperate"> | |||||
<el-radio-group v-model="formData.isBizCooperate"> | |||||
<el-radio :label="1">是</el-radio> | |||||
<el-radio :label="0">否</el-radio> | |||||
</el-radio-group> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="24"> | |||||
<el-form-item | |||||
v-if="formData.isBizCooperate === 1" | |||||
label="业务协同描述" | |||||
prop="bizCooperateInfo" | |||||
><el-input | |||||
v-model="formData.bizCooperateInfo" | |||||
:autosize="{ minRows: 2, maxRows: 4 }" | |||||
maxlength="2000" | |||||
type="textarea" | |||||
placeholder="请填写" | |||||
/> </el-form-item> | |||||
</el-col> | |||||
<el-col :span="16"> | |||||
<el-form-item label="使用范围" prop="usesRangeRemark"> | |||||
<el-cascader | |||||
v-model="formData.usesRangeRemark" | |||||
:options="useScope" | |||||
class="w-full" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="24"> | |||||
<el-form-item | |||||
label="应用简介" | |||||
prop="applicationSummary" | |||||
><el-input | |||||
v-model="formData.applicationSummary" | |||||
:autosize="{ minRows: 2, maxRows: 4 }" | |||||
maxlength="2000" | |||||
type="textarea" | |||||
placeholder="请填写" | |||||
/> </el-form-item> | |||||
</el-col> | |||||
<el-col :span="24"> | |||||
<el-form-item | |||||
label="应用备注" | |||||
prop="applicationRemark" | |||||
><el-input | |||||
v-model="formData.applicationRemark" | |||||
:autosize="{ minRows: 2, maxRows: 4 }" | |||||
maxlength="2000" | |||||
type="textarea" | |||||
placeholder="请填写" | |||||
/> </el-form-item> | |||||
</el-col> | |||||
<el-col :span="24"> | |||||
<el-form-item | |||||
label="应用总投资测算明细" | |||||
prop="applicationEstimateFile" | |||||
> | |||||
<el-upload | |||||
v-model:file-list="formData.applicationEstimateFile" | |||||
class="upload-demo" | |||||
:action="uploadUrl" | |||||
multiple | |||||
:on-success="res => handleFileSuccess(res, formData.applicationEstimateFile, false)" | |||||
:before-upload="file=>fileFormatVerification(file, {types: fileTypes})" | |||||
:accept="fileTypes.map(i=>`.${i}`).join(',')" | |||||
:limit="10" | |||||
:on-preview="handleFilePreview" | |||||
> | |||||
<el-button plain type="primary">选择文件</el-button> | |||||
<template #tip> | |||||
<div class="el-upload__tip"> | |||||
支持{{ fileDesc }}文件 | |||||
</div> | |||||
</template> | |||||
</el-upload> | |||||
</el-form-item> | |||||
</el-col> | |||||
</el-row> | |||||
</el-form> | |||||
</template> | |||||
<style lang="less"> | |||||
.el-upload-list{ | |||||
width: 100%; | |||||
} | |||||
</style> |
@@ -0,0 +1,185 @@ | |||||
<script name="appResourceInfo" setup> | |||||
import { ref, watch } from 'vue' | |||||
import store from '@/store' | |||||
const { | |||||
netEnvOptions | |||||
} = store.dictStore.globalDicts || {} | |||||
const props = defineProps({ | |||||
data: { | |||||
type: Object, | |||||
default: null | |||||
} | |||||
}), | |||||
formData = ref({}), | |||||
formRef = ref(), | |||||
rules = { | |||||
useGovCloud: [{ required: true, message: '请选择是否使用政务云资源' }], | |||||
cloudsType: [{ required: true, message: '请填写云资源类型' }], | |||||
cloudsFoundationSpecifications: [{ required: true, message: '请填写云资源基础规格' }], | |||||
cloudsNumber: [{ required: true, message: '请填写云资源台数' }], | |||||
cloudsDescription: [{ required: true, message: '请填写云资源台数' }], | |||||
netEnv: [{ required: true, message: '请选择网络环境' }], | |||||
useCommonData: [{ required: true, message: '请选择是否使用公共数据' }], | |||||
dataName: [{ required: true, message: '请输入公共数据名称' }], | |||||
useCommonComponent: [{ required: true, message: '请选择是否使用公共组件' }], | |||||
commonComponents: [{ required: true, message: '请输入公共组件名称' }], | |||||
produceCommonComponent: [{ required: true, message: '请选择是否使用公共组件' }], | |||||
produceCommonComponents: [{ required: true, message: '请填写预计组件名称' }] | |||||
}, | |||||
// 校验 | |||||
validForm = (callback) => { | |||||
formRef.value.validate(valid => { | |||||
callback(valid) | |||||
}) | |||||
}, | |||||
// 清空校验 | |||||
clearValidate = () => { | |||||
formRef.value.clearValidate() | |||||
} | |||||
watch( | |||||
() => props.data, | |||||
val => { | |||||
formData.value = { | |||||
useGovCloud: props.data.useGovCloud, | |||||
cloudsType: props.data.cloudsType, | |||||
cloudsFoundationSpecifications: props.data.cloudsFoundationSpecifications, | |||||
cloudsNumber: props.data.cloudsNumber, | |||||
cloudsDescription: props.data.cloudsDescription, | |||||
netEnv: props.data.netEnv, | |||||
useCommonData: props.data.useCommonData, | |||||
dataName: props.data.dataName, | |||||
useCommonComponent: props.data.useCommonComponent, | |||||
commonComponents: props.data.commonComponents, | |||||
produceCommonComponent: props.data.produceCommonComponent, | |||||
produceCommonComponents: props.data.produceCommonComponents | |||||
} | |||||
}, | |||||
{ immediate: true, deep: true } | |||||
) | |||||
defineExpose({ validForm, formData, clearValidate }) | |||||
</script> | |||||
<template> | |||||
<el-form | |||||
ref="formRef" | |||||
:model="formData" | |||||
:rules="rules" | |||||
label-position="right" | |||||
label-width="180px" | |||||
label-suffix=":" | |||||
scroll-to-error | |||||
> | |||||
<el-row :gutter="20"> | |||||
<el-col :span="24"> | |||||
<el-form-item label="是否使用政务云资源" prop="useGovCloud"> | |||||
<el-radio-group v-model="formData.useGovCloud"> | |||||
<el-radio :label="1">是</el-radio> | |||||
<el-radio :label="0">否</el-radio> | |||||
</el-radio-group> | |||||
</el-form-item> | |||||
</el-col> | |||||
<template v-if="formData.useGovCloud === 1"> | |||||
<el-col :span="12"> | |||||
<el-form-item label="云资源类型" prop="cloudsType"> | |||||
<el-input | |||||
v-model="formData.cloudsType" | |||||
placeholder="请填写" | |||||
:maxlength="50" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="12"> | |||||
<el-form-item label="云资源基础规格" prop="cloudsFoundationSpecifications"> | |||||
<el-input | |||||
v-model="formData.cloudsFoundationSpecifications" | |||||
placeholder="请填写" | |||||
:maxlength="50" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="12"> | |||||
<el-form-item label="云资源台数" prop="cloudsNumber"> | |||||
<el-input | |||||
v-model="formData.cloudsNumber" | |||||
placeholder="请填写" | |||||
maxlength="6" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="12"> | |||||
<el-form-item label="云资源用途描述" prop="cloudsDescription"> | |||||
<el-input | |||||
v-model="formData.cloudsDescription" | |||||
placeholder="请填写" | |||||
:maxlength="50" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
</template> | |||||
<el-col :span="24"> | |||||
<el-form-item label="网络环境" prop="netEnv"> | |||||
<el-radio-group v-model="formData.netEnv"> | |||||
<el-radio v-for="(v,k) in netEnvOptions" :key="k" :label="k*1">{{ v }}</el-radio> | |||||
</el-radio-group> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="24"> | |||||
<el-form-item label="是否使用公共数据" prop="useCommonData"> | |||||
<el-radio-group v-model="formData.useCommonData"> | |||||
<el-radio :label="1">是</el-radio> | |||||
<el-radio :label="0">否</el-radio> | |||||
</el-radio-group> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="16"> | |||||
<el-form-item v-if="formData.useCommonData === 1" label="数据名称" prop="dataName"> | |||||
<el-input | |||||
v-model="formData.dataName" | |||||
placeholder="请填写" | |||||
:maxlength="50" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="16"> | |||||
<el-form-item label="是否使用公共组件" prop="useCommonComponent"> | |||||
<el-radio-group v-model="formData.useCommonComponent"> | |||||
<el-radio :label="1">是</el-radio> | |||||
<el-radio :label="0">否</el-radio> | |||||
</el-radio-group> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="16"> | |||||
<el-form-item v-if="formData.useCommonComponent === 1" label="使用公共组件名称" prop="commonComponents"> | |||||
<el-input | |||||
v-model="formData.commonComponents" | |||||
placeholder="请填写" | |||||
:maxlength="50" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="16"> | |||||
<el-form-item label="是否产生公共组件" prop="produceCommonComponent"> | |||||
<el-radio-group v-model="formData.produceCommonComponent"> | |||||
<el-radio :label="1">是</el-radio> | |||||
<el-radio :label="0">否</el-radio> | |||||
</el-radio-group> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="16"> | |||||
<el-form-item v-if="formData.produceCommonComponent === 1" label="预计产生组件名称" prop="produceCommonComponents"> | |||||
<el-input | |||||
v-model="formData.produceCommonComponents" | |||||
placeholder="请填写" | |||||
:maxlength="50" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
</el-row> | |||||
</el-form> | |||||
</template> | |||||
<style lang="less"> | |||||
.el-upload-list{ | |||||
width: 100%; | |||||
} | |||||
</style> |
@@ -0,0 +1,85 @@ | |||||
<script name="appSafeInfo" setup> | |||||
import { ref, watch } from 'vue' | |||||
import store from '@/store' | |||||
const { | |||||
insuranceLevel | |||||
} = store.dictStore.globalDicts || {} | |||||
const props = defineProps({ | |||||
data: { | |||||
type: Object, | |||||
default: null | |||||
} | |||||
}), | |||||
formData = ref({}), | |||||
formRef = ref(), | |||||
rules = { | |||||
secrecyGrade: [{ required: true, message: '请选择等保级别' }], | |||||
passwordGrade: [{ required: true, message: '密码测评级别' }], | |||||
nationalItSpec: [{ required: true, message: '请选择是否符合相关规范' }] | |||||
}, | |||||
// 校验 | |||||
validForm = (callback) => { | |||||
formRef.value.validate(valid => { | |||||
callback(valid) | |||||
}) | |||||
}, | |||||
// 清空校验 | |||||
clearValidate = () => { | |||||
formRef.value.clearValidate() | |||||
} | |||||
watch( | |||||
() => props.data, | |||||
val => { | |||||
formData.value = { | |||||
secrecyGrade: props.data.secrecyGrade, | |||||
passwordGrade: props.data.passwordGrade, | |||||
nationalItSpec: props.data.nationalItSpec | |||||
} | |||||
}, | |||||
{ immediate: true, deep: true } | |||||
) | |||||
defineExpose({ validForm, formData, clearValidate }) | |||||
</script> | |||||
<template> | |||||
<el-form | |||||
ref="formRef" | |||||
:model="formData" | |||||
:rules="rules" | |||||
label-position="right" | |||||
label-width="180px" | |||||
label-suffix=":" | |||||
scroll-to-error | |||||
> | |||||
<el-row :gutter="20"> | |||||
<el-col :span="24"> | |||||
<el-form-item label="等保级别" prop="secrecyGrade"> | |||||
<el-radio-group v-model="formData.secrecyGrade"> | |||||
<el-radio v-for="(v,k) in insuranceLevel" :key="k" :label="k*1">{{ v }}</el-radio> | |||||
</el-radio-group> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="24"> | |||||
<el-form-item label="密码测评级别" prop="passwordGrade"> | |||||
<el-radio-group v-model="formData.passwordGrade"> | |||||
<el-radio v-for="(v,k) in insuranceLevel" :key="k" :label="k*1">{{ v }}</el-radio> | |||||
</el-radio-group> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="12"> | |||||
<el-form-item label="是否符合国家信息技术应用创新相关规范" prop="nationalItSpec"> | |||||
<el-radio-group v-model="formData.nationalItSpec"> | |||||
<el-radio :label="1">是</el-radio> | |||||
<el-radio :label="0">否</el-radio> | |||||
</el-radio-group> | |||||
</el-form-item> | |||||
</el-col> | |||||
</el-row> | |||||
</el-form> | |||||
</template> | |||||
<style lang="less"> | |||||
.el-upload-list{ | |||||
width: 100%; | |||||
} | |||||
</style> |
@@ -0,0 +1,330 @@ | |||||
<script name="appBasicInfo" setup> | |||||
import { watch, ref, getCurrentInstance } from 'vue' | |||||
import store from '@/store' | |||||
import { applicationList } from '@/http/apis/declareMange' | |||||
import { storeToRefs } from 'pinia' | |||||
const { | |||||
publisher, | |||||
insuranceLevel, | |||||
applicationType, | |||||
accountAppNameOption, | |||||
domainBrainAccountOptions | |||||
} = store.dictStore.globalDicts || {}, | |||||
userInfo = storeToRefs(store.userStore).userInfo || {}, | |||||
{ proxy } = getCurrentInstance(), | |||||
props = defineProps({ | |||||
data: { | |||||
type: Object, | |||||
default: null | |||||
}, | |||||
drawerVisible: { | |||||
type: Boolean, | |||||
default: false | |||||
}, | |||||
isFirst: { | |||||
type: Number, | |||||
default: undefined | |||||
}, | |||||
coreBusiness: { | |||||
type: Array, | |||||
default: () => { | |||||
return [] | |||||
} | |||||
} | |||||
}), | |||||
formData = ref({ | |||||
coreBusinessList: [{}] | |||||
}), | |||||
formRef = ref(), | |||||
rules = { | |||||
applicationName: [ | |||||
{ required: true, message: '请填写应用名称' } | |||||
], | |||||
relatedExistsApplication: [{ required: true, message: '请选择IRS注册应用' }], | |||||
relatedExistsApplicationCode: [{ required: true, message: '请选择IRS应用编码' }], | |||||
applicationType: [{ required: true, message: '请选择应用类型' }], | |||||
publishSide: [{ required: true, message: '请选择发布端' }], | |||||
applicationSummary: [{ required: true, message: '请填写应用简介' }], | |||||
secrecyGrade: [{ required: true, message: '请选择等保级别' }], | |||||
passwordGrade: [{ required: true, message: '请选择密码测评级别' }], | |||||
accountAppName: [{ required: true, message: '请选择' }], | |||||
domainBrainAccount: [{ required: true, message: '请选择' }] | |||||
}, | |||||
// 校验 | |||||
validForm = (callback) => { | |||||
formRef.value.validate((valid) => { | |||||
callback(valid) | |||||
}) | |||||
}, | |||||
// 清空校验 | |||||
clearValidate = () => { | |||||
formRef.value.clearValidate() | |||||
}, | |||||
// 获取irs应用列表 | |||||
applicationOptions = ref([]), | |||||
getApplicationOptions = async () => { | |||||
const res = await applicationList({ areaCode: userInfo.value.regionCode }) | |||||
applicationOptions.value = res.data | |||||
}, | |||||
// 修改关联应用 | |||||
changeIrsApp = (data) => { | |||||
formData.value.relatedExistsApplicationCode = data.applicationCode | |||||
}, | |||||
// 添加核心业务 | |||||
addCore = () => { | |||||
if (props.coreBusiness?.length <= formData.value.coreBusinessList?.length) { | |||||
proxy.$message.warning(`最多添加${props.coreBusiness?.length || 1}个核心业务`) | |||||
return | |||||
} | |||||
formData.value.coreBusinessList.push({}) | |||||
}, | |||||
// 删除核心业务 | |||||
delCore = (index) => { | |||||
formData.value.coreBusinessList.splice(index, 1) | |||||
} | |||||
watch( | |||||
() => props.drawerVisible, | |||||
val => { | |||||
if (val) { | |||||
formData.value = { | |||||
...props.data, | |||||
coreBusinessList: props.data.coreBusinessList?.length ? props.data.coreBusinessList : [{}] | |||||
} | |||||
getApplicationOptions() | |||||
} | |||||
}, | |||||
{ immediate: true } | |||||
) | |||||
watch( | |||||
() => props.data, | |||||
val => { | |||||
formData.value = { | |||||
...props.data, | |||||
coreBusinessList: props.data.coreBusinessList?.length ? props.data.coreBusinessList : [{}] | |||||
} | |||||
}, | |||||
{ immediate: true, deep: true } | |||||
) | |||||
defineExpose({ validForm, formData, clearValidate }) | |||||
</script> | |||||
<template> | |||||
<el-form | |||||
ref="formRef" | |||||
:model="formData" | |||||
:rules="rules" | |||||
label-position="right" | |||||
label-width="180px" | |||||
label-suffix=":" | |||||
scroll-to-error | |||||
> | |||||
<el-row :gutter="20"> | |||||
<template v-if="(props.isFirst===0&&userInfo.regionCode==='331123')||userInfo.regionCode!=='331123'"> | |||||
<el-col :span="12"> | |||||
<el-form-item label="关联IRS已注册应用" prop="relatedExistsApplication"> | |||||
<el-select | |||||
v-model="formData.relatedExistsApplication" | |||||
class="w-full" | |||||
placeholder="请选择" | |||||
value-key="applicationCode" | |||||
@change="changeIrsApp" | |||||
> | |||||
<el-option | |||||
v-for="(item, index) in applicationOptions" | |||||
:key="index" | |||||
:label="item.applicationName" | |||||
:value="{applicationCode:item.applicationCode,applicationName:item.applicationName}" | |||||
/> | |||||
</el-select> | |||||
<p class="text-12 text-danger" style="line-height: 1.4">温馨提示:首次建设项目请先去IRS平台注册后再关联应用</p> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="12"> | |||||
<el-form-item label="IRS应用编码" prop="relatedExistsApplicationCode"> | |||||
<el-input v-model="formData.relatedExistsApplicationCode" disabled /> | |||||
</el-form-item> | |||||
</el-col> | |||||
</template> | |||||
<el-col v-else :span="12"> | |||||
<el-form-item label="应用名称" prop="applicationName"> | |||||
<el-input | |||||
v-model="formData.applicationName" | |||||
placeholder="请填写" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="12"> | |||||
<el-form-item label="应用类型" prop="applicationType"> | |||||
<el-select v-model="formData.applicationType" placeholder="请选择" class="w-full"> | |||||
<el-option | |||||
v-for="(item, index) in applicationType" | |||||
:key="index" | |||||
:label="item" | |||||
:value="item" | |||||
/> | |||||
</el-select> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="12"> | |||||
<el-form-item label="发布端" prop="publishSide"> | |||||
<el-select v-model="formData.publishSide" placeholder="请选择" class="w-full"> | |||||
<el-option | |||||
v-for="(item, index) in publisher" | |||||
:key="index" | |||||
:label="item" | |||||
:value="item" | |||||
/> | |||||
</el-select> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="24"> | |||||
<el-form-item | |||||
label="应用简介" | |||||
prop="applicationSummary" | |||||
><el-input | |||||
v-model="formData.applicationSummary" | |||||
:autosize="{ minRows: 2, maxRows: 4 }" | |||||
maxlength="2000" | |||||
type="textarea" | |||||
placeholder="请填写" | |||||
/> </el-form-item> | |||||
</el-col> | |||||
<el-col :span="12"> | |||||
<el-form-item label="一本账重大应用名称"> | |||||
<el-select | |||||
v-model="formData.accountAppName" | |||||
placeholder="请选择" | |||||
class="w-full" | |||||
clearable | |||||
> | |||||
<el-option | |||||
v-for="(item, index) in accountAppNameOption" | |||||
:key="index" | |||||
:label="item" | |||||
:value="item" | |||||
/> | |||||
</el-select> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="12"> | |||||
<el-form-item label="领域“大脑”一本账"> | |||||
<el-select v-model="formData.domainBrainAccount" placeholder="请选择" class="w-full"> | |||||
<el-option | |||||
v-for="(item, index) in domainBrainAccountOptions" | |||||
:key="index" | |||||
:label="item" | |||||
:value="item" | |||||
/> | |||||
</el-select> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="24"> | |||||
<el-form-item label="等保级别" prop="secrecyGrade"> | |||||
<el-radio-group v-model="formData.secrecyGrade"> | |||||
<el-radio v-for="(v,k) in insuranceLevel" :key="k" :label="k*1">{{ v }}</el-radio> | |||||
</el-radio-group> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="24"> | |||||
<el-form-item label="密码测评级别" prop="passwordGrade"> | |||||
<el-radio-group v-model="formData.passwordGrade"> | |||||
<el-radio v-for="(v,k) in insuranceLevel" :key="k" :label="k*1">{{ v }}</el-radio> | |||||
</el-radio-group> | |||||
</el-form-item> | |||||
</el-col> | |||||
<div | |||||
v-for="(item,index) in formData.coreBusinessList" | |||||
:key="index" | |||||
class="py-24 pr-60 mb-16 relative" | |||||
style="background: rgb(245, 248, 250);" | |||||
> | |||||
<el-row> | |||||
<el-col :span="12"> | |||||
<el-form-item label="核心业务" :prop="`coreBusinessList[${index}].coreBusiness`" :rules="[{required:true,message:'请选择'}]"> | |||||
<el-select v-model="formData.coreBusinessList[index].coreBusiness" placeholder="请选择核心业务" class="w-full"> | |||||
<el-option | |||||
v-for="(row,key) in props.coreBusiness" | |||||
:key="key" | |||||
:label="row.matterName" | |||||
:value="row.matterName" | |||||
/> | |||||
</el-select> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="12"> | |||||
<el-form-item label="分值" :prop="`coreBusinessList[${index}].score`" :rules="[{required:true,message:'请输入'}]"> | |||||
<el-input-number | |||||
v-model="formData.coreBusinessList[index].score" | |||||
class="input-amount f" | |||||
placeholder="请填写" | |||||
:min="0.01" | |||||
:max="10" | |||||
:precision="2" | |||||
:controls="false" | |||||
@mousewheel.prevent | |||||
> | |||||
<template #suffix>分</template> | |||||
</el-input-number> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="12"> | |||||
<el-form-item label="业务指标名称" :prop="`coreBusinessList[${index}].businessIndicatorName`" :rules="[{required:true,message:'请输入'}]"> | |||||
<el-input v-model="formData.coreBusinessList[index].businessIndicatorName" :maxlength="50" placeholder="请填写" /> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="12"> | |||||
<el-form-item label="业务指标描述" :prop="`coreBusinessList[${index}].businessIndicatorDescription`" :rules="[{required:true,message:'请输入'}]"> | |||||
<el-input v-model="formData.coreBusinessList[index].businessIndicatorDescription" :maxlength="50" placeholder="请填写" /> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="12"> | |||||
<el-form-item | |||||
label="指标设计依据" | |||||
:prop="`coreBusinessList[${index}].indexDesignBasis`" | |||||
style="margin-bottom: 0" | |||||
:rules="[{required:true,message:'请输入'}]" | |||||
> | |||||
<el-input v-model="formData.coreBusinessList[index].indexDesignBasis" :maxlength="50" placeholder="请填写" /> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="12"> | |||||
<el-form-item | |||||
label="指标计算方法" | |||||
:prop="`coreBusinessList[${index}].indexCalculationMethod`" | |||||
style="margin-bottom: 0" | |||||
:rules="[{required:true,message:'请输入'}]" | |||||
> | |||||
<el-input v-model="formData.coreBusinessList[index].indexCalculationMethod" :maxlength="50" placeholder="请填写" /> | |||||
</el-form-item> | |||||
</el-col> | |||||
</el-row> | |||||
<el-button | |||||
v-if="formData.coreBusinessList?.length>1" | |||||
type="danger" | |||||
link | |||||
plain | |||||
class="absolute top-10 right-8" | |||||
@click="delCore(index)" | |||||
>删除</el-button> | |||||
</div> | |||||
<p> | |||||
<el-button | |||||
type="primary" | |||||
size="small" | |||||
icon="Plus" | |||||
plain | |||||
class="ml-80 block" | |||||
@click="addCore" | |||||
>添加核心业务</el-button> | |||||
</p> | |||||
</el-row> | |||||
</el-form> | |||||
</template> | |||||
<style lang="less"> | |||||
.el-upload-list{ | |||||
width: 100%; | |||||
} | |||||
</style> |
@@ -0,0 +1,289 @@ | |||||
<script name="applications" setup> | |||||
import { getCurrentInstance, ref, h, nextTick } from 'vue' | |||||
import AppBasicInfo from './appBasicInfo.vue' | |||||
import AppSafeInfo from './appSafeInfo.vue' | |||||
import AppResourceInfo from './appResourceInfo.vue' | |||||
import { ElMessageBox } from 'element-plus' | |||||
import { useRoute } from 'vue-router' | |||||
import ApplicationInfo from '@/pages/declareManage/projectDeclare/declarePage/components/applicationInfo.vue' | |||||
defineProps({ | |||||
isInnovateWholeProvinceShare: { | |||||
type: Boolean, | |||||
default: false | |||||
}, | |||||
isFirst: { | |||||
type: Number, | |||||
default: undefined | |||||
}, | |||||
coreBusiness: { | |||||
type: Array, | |||||
default: () => { | |||||
return [] | |||||
} | |||||
} | |||||
}) | |||||
const route = useRoute(), | |||||
{ proxy } = getCurrentInstance(), | |||||
formData = ref({ | |||||
applicationList: [] | |||||
}), | |||||
formRef = ref(), | |||||
rules = { | |||||
includeApplication: [ | |||||
{ required: true, message: '请选择是否包含应用', trigger: 'blur' } | |||||
], | |||||
applicationList: [ | |||||
{ required: true, message: '请添加应用', trigger: 'blur' } | |||||
] | |||||
}, | |||||
column = [ | |||||
{ | |||||
type: 'index', | |||||
label: '序号', | |||||
width: 60 | |||||
}, | |||||
{ | |||||
label: '应用名称', | |||||
key: 'applicationName', | |||||
prop: 'applicationName', | |||||
render: row => h('span', row.applicationName || row.relatedExistsApplication?.applicationName || '') | |||||
}, | |||||
// { | |||||
// label: '数改系统', | |||||
// key: 'digitalModification', | |||||
// prop: 'digitalModification', | |||||
// render: row => h('span', row.digitalModification?.map(i => digitalModifySystem[i]).join(',')) | |||||
// }, | |||||
{ | |||||
label: '操作', | |||||
slot: 'action' | |||||
} | |||||
], | |||||
// 删除应用 | |||||
deleteApplication = (index) => { | |||||
proxy.$messageBox | |||||
.confirm('确定要删除该项吗?', '提示!', { | |||||
type: 'warning' | |||||
}) | |||||
.then(() => { | |||||
formData.value.applicationList.splice(index, 1) | |||||
}) | |||||
}, | |||||
// 编辑、新增应用 | |||||
drawerVisible = ref(false), | |||||
collapseModal = ref(['1', '2', '3']), | |||||
applicationData = ref({}), | |||||
appBasicInfoRef = ref(), | |||||
appSafeInfoRef = ref(), | |||||
appResourceInfoRef = ref(), | |||||
applicationInfoRef = ref(), | |||||
isEdit = ref(false), | |||||
appIndex = ref(), | |||||
editApplication = async (index, row) => { | |||||
isEdit.value = true | |||||
appIndex.value = index | |||||
applicationData.value = row | |||||
drawerVisible.value = true | |||||
await nextTick() | |||||
applicationInfoRef.value.clearValidate() | |||||
}, | |||||
addApplication = async () => { | |||||
isEdit.value = false | |||||
applicationData.value = {} | |||||
drawerVisible.value = true | |||||
await nextTick() | |||||
applicationInfoRef.value.clearValidate() | |||||
}, | |||||
handleDrawerClose = () => { | |||||
ElMessageBox.confirm('确定要关闭应用编辑页面吗?') | |||||
.then(() => { | |||||
close() | |||||
}) | |||||
.catch(() => { | |||||
}) | |||||
}, | |||||
close = () => { | |||||
// appSafeInfoRef.value.clearValidate() | |||||
// appResourceInfoRef.value.clearValidate() | |||||
// appBasicInfoRef.value.clearValidate() | |||||
applicationInfoRef.value.formData = {} | |||||
applicationInfoRef.value.clearValidate() | |||||
drawerVisible.value = false | |||||
}, | |||||
// 暂存 | |||||
save = () => { | |||||
if (!isEdit.value) { | |||||
formData.value.applicationList.push({ | |||||
// ...appBasicInfoRef.value.formData, | |||||
// ...appSafeInfoRef.value.formData, | |||||
// ...appResourceInfoRef.value.formData | |||||
...applicationInfoRef.value.formData | |||||
}) | |||||
} else { | |||||
formData.value.applicationList[appIndex.value] = { | |||||
// ...appBasicInfoRef.value.formData, | |||||
// ...appSafeInfoRef.value.formData, | |||||
// ...appResourceInfoRef.value.formData | |||||
...applicationInfoRef.value.formData | |||||
} | |||||
} | |||||
close() | |||||
}, | |||||
// 提交 | |||||
submitApplication = () => { | |||||
const form = [] | |||||
// form.push(new Promise((resolve, reject) => { | |||||
// appBasicInfoRef.value.validForm((valid) => { | |||||
// if (valid) resolve() | |||||
// }) | |||||
// })) | |||||
// form.push(new Promise((resolve, reject) => { | |||||
// appSafeInfoRef.value.validForm((valid) => { | |||||
// if (valid) resolve() | |||||
// }) | |||||
// })) | |||||
// form.push(new Promise((resolve, reject) => { | |||||
// appResourceInfoRef.value.validForm((valid) => { | |||||
// if (valid) resolve() | |||||
// }) | |||||
// })) | |||||
form.push(new Promise((resolve, reject) => { | |||||
applicationInfoRef.value.validForm((valid) => { | |||||
if (valid) resolve() | |||||
}) | |||||
})) | |||||
Promise.all([...form]).then(() => { | |||||
save() | |||||
}) | |||||
}, | |||||
// 校验 | |||||
validForm = (callback) => { | |||||
formRef.value.validate(valid => { | |||||
callback(valid) | |||||
}) | |||||
}, | |||||
// 回显 | |||||
setFormData = (data) => { | |||||
const appname = route.query.isDraft ? 'applicationList' : 'projectApplications' | |||||
formData.value = { | |||||
includeApplication: data.includeApplication, | |||||
applicationList: data[appname]?.length ? data[appname].map(i => { | |||||
return { | |||||
...i, | |||||
relatedExistsApplication: i.relatedExistsApplication ? { applicationCode: i.relatedExistsApplicationCode, applicationName: i.relatedExistsApplication } : undefined | |||||
} | |||||
}) : [] | |||||
} | |||||
}, | |||||
// 修改是否包含应用 | |||||
changeIncludeApplication = () => { | |||||
formData.value.applicationList = [] | |||||
} | |||||
defineExpose({ validForm, formData, applicationData, setFormData }) | |||||
</script> | |||||
<template> | |||||
<el-form | |||||
ref="formRef" | |||||
:model="formData" | |||||
:rules="rules" | |||||
label-position="right" | |||||
label-width="180px" | |||||
label-suffix=":" | |||||
scroll-to-error | |||||
> | |||||
<el-row :gutter="40"> | |||||
<el-col :span="12"> | |||||
<el-form-item | |||||
label="是否包含应用" | |||||
label-width="atuo" | |||||
prop="includeApplication" | |||||
> | |||||
<el-radio-group v-model="formData.includeApplication" @change="changeIncludeApplication"> | |||||
<el-radio :label="1">是</el-radio> | |||||
<el-radio :label="0">否</el-radio> | |||||
</el-radio-group> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col v-if="formData.includeApplication === 1" :span="24"> | |||||
<el-form-item label="包含的应用" prop="applicationList"> | |||||
<el-button | |||||
type="primary" | |||||
plain | |||||
class="w-full mb-10" | |||||
icon="Plus" | |||||
@click="addApplication" | |||||
>添加应用</el-button> | |||||
<table-list | |||||
class="w-full" | |||||
:pagination="false" | |||||
:data="formData.applicationList" | |||||
:column="column" | |||||
> | |||||
<template #action="{scope}"> | |||||
<a | |||||
@click="editApplication(scope.$index, scope.row)" | |||||
>编辑</a> | |||||
<a | |||||
class="text-red-400" | |||||
@click="deleteApplication(scope.$index)" | |||||
>删除</a> | |||||
</template> | |||||
</table-list> | |||||
</el-form-item> | |||||
</el-col> | |||||
</el-row> | |||||
</el-form> | |||||
<el-drawer | |||||
v-model="drawerVisible" | |||||
title="添加应用" | |||||
:before-close="handleDrawerClose" | |||||
:size="1000" | |||||
> | |||||
<el-collapse v-if="false" v-model="collapseModal"> | |||||
<el-collapse-item name="1"> | |||||
<template #title> | |||||
<div class="collapse-title">基本信息</div> | |||||
</template> | |||||
<app-basic-info | |||||
ref="appBasicInfoRef" | |||||
:data="applicationData" | |||||
:is-innovate-whole-province-share="isInnovateWholeProvinceShare" | |||||
:drawer-visible="drawerVisible" | |||||
/> | |||||
</el-collapse-item> | |||||
<el-collapse-item name="2"> | |||||
<template #title> | |||||
<div class="collapse-title">安全信息</div> | |||||
</template> | |||||
<app-safe-info ref="appSafeInfoRef" :data="applicationData" /> | |||||
</el-collapse-item> | |||||
<el-collapse-item name="3"> | |||||
<template #title> | |||||
<div class="collapse-title">资源信息</div> | |||||
</template> | |||||
<app-resource-info ref="appResourceInfoRef" :data="applicationData" /> | |||||
</el-collapse-item> | |||||
</el-collapse> | |||||
<application-info | |||||
ref="applicationInfoRef" | |||||
:data="applicationData" | |||||
:is-first="isFirst" | |||||
:core-business="coreBusiness" | |||||
:drawer-visible="drawerVisible" | |||||
/> | |||||
<template #footer> | |||||
<div class="applyBottomBtn flexCenter marginTop"> | |||||
<el-button @click="handleDrawerClose"> 关闭 </el-button> | |||||
<el-button type="primary" plain @click="save"> 暂存 </el-button> | |||||
<el-button type="primary" @click="submitApplication"> 确定 </el-button> | |||||
</div> | |||||
</template> | |||||
</el-drawer> | |||||
</template> | |||||
<style lang="less"> | |||||
.el-upload-list{ | |||||
width: 100%; | |||||
} | |||||
</style> |
@@ -0,0 +1,189 @@ | |||||
<script name="coreBusiness" setup> | |||||
import { reactive, ref, nextTick } from 'vue' | |||||
import { getCoreBusinessData } from '@/http/apis/declareMange' | |||||
import { storeToRefs } from 'pinia' | |||||
import store from '@/store' | |||||
const props = defineProps({ | |||||
basicInfoData: { | |||||
type: Object | |||||
} | |||||
}) | |||||
const userInfo = storeToRefs(store.userStore).userInfo || {}, | |||||
formData = ref({}), | |||||
formRef = ref(), | |||||
rules = { | |||||
coreBusiness: [{ required: true, message: '请至少选择一个核心业务' }] | |||||
}, | |||||
// 校验 | |||||
validForm = (callback) => { | |||||
formRef.value.validate(valid => { | |||||
callback(valid) | |||||
}) | |||||
}, | |||||
// 选择核心业务 | |||||
selectCoreBusiness = () => { | |||||
coreBusinessvisible.value = true | |||||
getCoreBusinessTableData({ pageNumber: 1, pageSize: 10 }, true) | |||||
}, | |||||
column = [ | |||||
{ | |||||
type: 'index', | |||||
label: '序号', | |||||
width: 60 | |||||
}, | |||||
// { | |||||
// label: '业务编号', | |||||
// key: 'oid', | |||||
// prop: 'oid' | |||||
// }, | |||||
{ | |||||
label: '业务名称', | |||||
key: 'matterName', | |||||
prop: 'matterName' | |||||
}, | |||||
{ | |||||
label: '所属单位', | |||||
key: 'orgName', | |||||
prop: 'orgName' | |||||
} | |||||
], | |||||
tableListRef = ref(), | |||||
coreBusinessData = ref([]), | |||||
coreBusinesstotal = ref(0), | |||||
column2 = [ | |||||
{ | |||||
type: 'selection' | |||||
}, | |||||
// { | |||||
// label: '业务编号', | |||||
// prop: 'oid', | |||||
// key: 'oid' | |||||
// }, | |||||
{ | |||||
label: '业务名称', | |||||
prop: 'matterName', | |||||
key: 'matterName' | |||||
}, | |||||
{ | |||||
label: '所属单位', | |||||
prop: 'orgName', | |||||
key: 'orgName' | |||||
} | |||||
], | |||||
coreBusinessvisible = ref(false), | |||||
getCoreBusinessTableData = async (pageParams = tableListRef.value?.pageParams, flag) => { | |||||
var orgCode = [] | |||||
props?.basicInfoData?.superOrgCode && orgCode.push(props.basicInfoData.superOrgCode) | |||||
userInfo.value?.empPosUnitCode && orgCode.push(userInfo.value.empPosUnitCode) | |||||
const res = await getCoreBusinessData({ | |||||
...pageParams, | |||||
businessName: coreBusinessParams.businessName, | |||||
orgCode: orgCode.join(',') | |||||
}) | |||||
coreBusinessData.value = res.data.data | |||||
coreBusinesstotal.value = res.data.total | |||||
await nextTick() | |||||
if (flag) { | |||||
coreBusinessData.value && coreBusinessData.value.forEach(item => { | |||||
const dataIds = formData.value.coreBusiness && formData.value.coreBusiness.map(i => i.id) || [] | |||||
if (dataIds.includes(item.id)) { | |||||
tableListRef.value.toggleRowSelect(item, true) | |||||
} else { | |||||
tableListRef.value.toggleRowSelect(item, false) | |||||
} | |||||
}) | |||||
} | |||||
}, | |||||
searchCoreBussiness = () => { | |||||
getCoreBusinessTableData() | |||||
}, | |||||
coreBusinessTempotary = ref(), | |||||
selectionCoreBusinessChange = (data) => { | |||||
coreBusinessTempotary.value = data | |||||
}, | |||||
coreBusinessParams = reactive({ | |||||
businessName: undefined | |||||
}), | |||||
handleReset = () => { | |||||
coreBusinessParams.businessName = '' | |||||
}, | |||||
confirmCoreBusiness = () => { | |||||
formData.value.coreBusiness = coreBusinessTempotary.value | |||||
coreBusinessvisible.value = false | |||||
}, | |||||
// 回显 | |||||
setFormData = (data) => { | |||||
formData.value = { | |||||
coreBusiness: data.coreBusiness ? JSON.parse(data.coreBusiness) : [] | |||||
} | |||||
} | |||||
defineExpose({ validForm, formData, setFormData }) | |||||
</script> | |||||
<template> | |||||
<el-form | |||||
ref="formRef" | |||||
:model="formData" | |||||
:rules="rules" | |||||
label-position="right" | |||||
label-width="0" | |||||
label-suffix=":" | |||||
scroll-to-error | |||||
> | |||||
<el-row :gutter="40"> | |||||
<el-col :span="24" class="mb-16"> | |||||
<el-button type="primary" class="float-right" @click="selectCoreBusiness"> | |||||
选择核心业务 | |||||
</el-button> | |||||
</el-col> | |||||
<el-col :span="24"> | |||||
<el-form-item prop="coreBusiness"> | |||||
<table-list | |||||
:pagination="false" | |||||
style="width: 100%" | |||||
:column="column" | |||||
:data="formData.coreBusiness" | |||||
:empty-temp="false" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
</el-row> | |||||
</el-form> | |||||
<el-dialog | |||||
title="选择核心业务" | |||||
:close-on-click-modal="false" | |||||
:before-close="()=>coreBusinessvisible=false" | |||||
:model-value="coreBusinessvisible" | |||||
width="700px" | |||||
> | |||||
<el-row style="margin-bottom: 16px" :gutter="20"> | |||||
<el-col :span="12"> | |||||
<el-input v-model="coreBusinessParams.businessName" placeholder="请输入" /> | |||||
</el-col> | |||||
<el-col :span="12"> | |||||
<div class="flex"> | |||||
<el-button type="primary" @click="searchCoreBussiness">查询</el-button> | |||||
<el-button @click="handleReset">重置</el-button> | |||||
</div> | |||||
</el-col> | |||||
</el-row> | |||||
<table-list | |||||
ref="tableListRef" | |||||
:column="column2" | |||||
:data="coreBusinessData" | |||||
:total="coreBusinesstotal" | |||||
@selection-change="selectionCoreBusinessChange" | |||||
@get-table-data="getCoreBusinessTableData" | |||||
/> | |||||
<template #footer> | |||||
<el-button type="primary" @click="confirmCoreBusiness"> 提交 </el-button> | |||||
<el-button @click="coreBusinessvisible = false"> 关闭 </el-button> | |||||
</template> | |||||
</el-dialog> | |||||
</template> | |||||
<style lang="less"> | |||||
.el-upload-list{ | |||||
width: 100%; | |||||
} | |||||
</style> |
@@ -0,0 +1,81 @@ | |||||
<script name="fundsAllocation" setup> | |||||
import { ref } from 'vue' | |||||
const formData = ref({}), | |||||
formRef = ref(), | |||||
rules = { | |||||
softwareDevelopmentAmount: [{ required: true, message: '请输入软件开发', trigger: 'blur' }], | |||||
cloudHardwarePurchaseAmount: [ | |||||
{ required: true, message: '请输入云资源、硬件配置', trigger: 'blur' } | |||||
], | |||||
thirdPartyAmount: [{ required: true, message: '请输入第三方服务', trigger: 'blur' }] | |||||
}, | |||||
// 校验 | |||||
validForm = (callback) => { | |||||
formRef.value.validate(valid => { | |||||
callback(valid) | |||||
}) | |||||
}, | |||||
// 回显 | |||||
setFormData = (data) => { | |||||
formData.value = { | |||||
softwareDevelopmentAmount: data.softwareDevelopmentAmount, | |||||
cloudHardwarePurchaseAmount: data.cloudHardwarePurchaseAmount, | |||||
thirdPartyAmount: data.thirdPartyAmount | |||||
} | |||||
} | |||||
defineExpose({ validForm, formData, setFormData }) | |||||
</script> | |||||
<template> | |||||
<el-form | |||||
ref="formRef" | |||||
:model="formData" | |||||
:rules="rules" | |||||
label-position="right" | |||||
label-width="180px" | |||||
label-suffix=":" | |||||
scroll-to-error | |||||
> | |||||
<el-row :gutter="40"> | |||||
<el-col :span="8"> | |||||
<el-form-item label="软件开发" prop="softwareDevelopmentAmount"> | |||||
<el-input-number | |||||
v-model="formData.softwareDevelopmentAmount" | |||||
placeholder="请填写" | |||||
:min="0" | |||||
:controls="false" | |||||
@mousewheel.prevent | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<el-form-item label="云资源、硬件配置" prop="cloudHardwarePurchaseAmount"> | |||||
<el-input-number | |||||
v-model="formData.cloudHardwarePurchaseAmount" | |||||
placeholder="请填写" | |||||
:min="0" | |||||
:controls="false" | |||||
@mousewheel.prevent | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<el-form-item label="第三方服务" prop="thirdPartyAmount"> | |||||
<el-input-number | |||||
v-model="formData.thirdPartyAmount" | |||||
placeholder="请填写" | |||||
:min="0" | |||||
:controls="false" | |||||
@mousewheel.prevent | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
</el-row> | |||||
</el-form> | |||||
</template> | |||||
<style lang="less"> | |||||
.el-upload-list{ | |||||
width: 100%; | |||||
} | |||||
</style> |
@@ -0,0 +1,189 @@ | |||||
<script name="fundsInfo" setup> | |||||
import { ref } from 'vue' | |||||
defineProps({ | |||||
detailData: { | |||||
type: Object, | |||||
default: () => { | |||||
return {} | |||||
} | |||||
} | |||||
}) | |||||
const formData = ref({ | |||||
}), | |||||
formRef = ref(), | |||||
moneyValidator = (rule, value, callback) => { | |||||
if (!value) callback() | |||||
if (!/^\d+(\.\d{1,6})?$/.test(value)) { | |||||
callback('请输入正确格式,最多保留六位小数') | |||||
} else if (value * 1 >= 100000000) { | |||||
callback('请输入正确格式,小于100000000') | |||||
} else { | |||||
callback() | |||||
} | |||||
}, | |||||
rules = { | |||||
projectYear: [{ required: true, message: '请选择预算年度' }], | |||||
declareAmount: [{ required: true, message: '请输入申报金额', trigger: 'blur' }, { validator: moneyValidator, trigger: 'blur' }], | |||||
declareHaveAmount: [{ required: true, message: '请输入自有资金', trigger: 'blur' }, { validator: moneyValidator, trigger: 'blur' }], | |||||
declareGovOwnFinanceAmount: [ | |||||
{ | |||||
required: true, | |||||
message: '请输入政府投资-本级财政资金', | |||||
trigger: 'blur' | |||||
}, | |||||
{ validator: moneyValidator, trigger: 'blur' } | |||||
], | |||||
declareGovSuperiorFinanceAmount: [ | |||||
{ | |||||
required: true, | |||||
message: '请输入政府投资-上级补助资金', | |||||
trigger: 'blur' | |||||
}, | |||||
{ validator: moneyValidator, trigger: 'blur' } | |||||
], | |||||
declareBankLendingAmount: [{ required: true, message: '请输入银行贷款', trigger: 'blur' }, { validator: moneyValidator, trigger: 'blur' }], | |||||
declareOtherAmount: [{ required: true, message: '请输入其他资金', trigger: 'blur' }, { validator: moneyValidator, trigger: 'blur' }], | |||||
consultancy: [{ required: true, message: '请填写咨询公司' }], | |||||
baseBasisAmountOri: [{ required: true, message: '请填写预算来源说明' }] | |||||
}, | |||||
// 校验 | |||||
validForm = (callback) => { | |||||
formRef.value.validate(valid => { | |||||
callback(valid) | |||||
}) | |||||
}, | |||||
// 回显 | |||||
setFormData = (data) => { | |||||
formData.value = { | |||||
projectYear: data.projectYear ? data.projectYear + '' : null, | |||||
declareAmount: data.declareAmount, | |||||
declareHaveAmount: data.declareHaveAmount, | |||||
declareGovOwnFinanceAmount: data.declareGovOwnFinanceAmount, | |||||
declareGovSuperiorFinanceAmount: data.declareGovSuperiorFinanceAmount, | |||||
declareBankLendingAmount: data.declareBankLendingAmount, | |||||
declareOtherAmount: data.declareOtherAmount, | |||||
baseBasisAmountOri: data.baseBasisAmountOri || '', | |||||
consultancy: data.consultancy || '' | |||||
} | |||||
} | |||||
defineExpose({ validForm, formData, setFormData }) | |||||
</script> | |||||
<template> | |||||
<el-form | |||||
ref="formRef" | |||||
:model="formData" | |||||
:rules="rules" | |||||
label-position="right" | |||||
label-width="180px" | |||||
label-suffix=":" | |||||
scroll-to-error | |||||
> | |||||
<el-row :gutter="40"> | |||||
<el-col :span="12"> | |||||
<el-form-item label="预算年度" prop="projectYear"> | |||||
<el-date-picker | |||||
v-model="formData.projectYear" | |||||
:disabled="$route.name==='declarePlan'||[10012,10013,10016].includes(detailData?.status)" | |||||
type="year" | |||||
placeholder="请选择" | |||||
format="YYYY" | |||||
value-format="YYYY" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="12"> | |||||
<el-form-item label="申报金额" prop="declareAmount"> | |||||
<el-input-number | |||||
v-model="formData.declareAmount" | |||||
placeholder="请填写" | |||||
:min="0.000001" | |||||
:controls="false" | |||||
@mousewheel.prevent | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="12"> | |||||
<el-form-item label="自有资金" prop="declareHaveAmount"> | |||||
<el-input-number | |||||
v-model="formData.declareHaveAmount" | |||||
placeholder="请填写" | |||||
:min="0" | |||||
:controls="false" | |||||
@mousewheel.prevent | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="12"> | |||||
<el-form-item label="政府投资-本级财政资金" prop="declareGovOwnFinanceAmount"> | |||||
<el-input-number | |||||
v-model="formData.declareGovOwnFinanceAmount" | |||||
placeholder="请填写" | |||||
:min="0" | |||||
:controls="false" | |||||
@mousewheel.prevent | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="12"> | |||||
<el-form-item label="政府投资-上级补助资金" prop="declareGovSuperiorFinanceAmount"> | |||||
<el-input-number | |||||
v-model="formData.declareGovSuperiorFinanceAmount" | |||||
placeholder="请填写" | |||||
:min="0" | |||||
:controls="false" | |||||
@mousewheel.prevent | |||||
><template #append>万元</template></el-input-number> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="12"> | |||||
<el-form-item label="银行贷款" prop="declareBankLendingAmount"> | |||||
<el-input-number | |||||
v-model="formData.declareBankLendingAmount" | |||||
placeholder="请填写" | |||||
:min="0" | |||||
:controls="false" | |||||
@mousewheel.prevent | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="12"> | |||||
<el-form-item label="其他资金" prop="declareOtherAmount"> | |||||
<el-input-number | |||||
v-model="formData.declareOtherAmount" | |||||
placeholder="请填写" | |||||
:min="0" | |||||
:controls="false" | |||||
@mousewheel.prevent | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col v-if="($route.name==='declarePlan'||[10012,10013,10016].includes(detailData?.status))&&formData.declareAmount>400" :span="12"> | |||||
<el-form-item label="咨询公司" prop="consultancy"> | |||||
<el-input | |||||
v-model="formData.consultancy" | |||||
placeholder="请填写" | |||||
maxlength="100" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col v-if="formData.declareOtherAmount>0" :span="24"> | |||||
<el-form-item label="预算来源说明" prop="baseBasisAmountOri"> | |||||
<el-input | |||||
v-model="formData.baseBasisAmountOri" | |||||
type="textarea" | |||||
show-word-limit | |||||
placeholder="请填写" | |||||
:maxlength="150" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
</el-row> | |||||
</el-form> | |||||
</template> | |||||
<style lang="less"> | |||||
.el-upload-list{ | |||||
width: 100%; | |||||
} | |||||
</style> |
@@ -0,0 +1,106 @@ | |||||
<script setup name="hiddenAppForm"> | |||||
import { nextTick, ref, watch } from 'vue' | |||||
// import appBasicInfo from './appBasicInfo.vue' | |||||
// import appSafeInfo from './appSafeInfo.vue' | |||||
// import appResourceInfo from './appResourceInfo.vue' | |||||
import ApplicationInfo from '@/pages/declareManage/projectDeclare/declarePage/components/applicationInfo.vue' | |||||
const props = defineProps({ | |||||
applicationList: Array, | |||||
isFirst: { | |||||
type: Number, | |||||
default: undefined | |||||
} | |||||
}), | |||||
// appBasicInfoRef = ref(), | |||||
// appSafeInfoRef = ref(), | |||||
// appResourceInfoRef = ref(), | |||||
applicationInfoRef = ref(), | |||||
applicationData = ref([]), | |||||
validCount = ref(0), | |||||
drawerVisible = ref(), | |||||
validAllAppForm = async (callback) => { | |||||
drawerVisible.value = true | |||||
validCount.value = 0 | |||||
for (const item of props.applicationList) { // 不能用forEach,因为不会等异步的执行完成才执行下一条 | |||||
await doAsyncOperation(item) | |||||
} | |||||
setTimeout(async () => { | |||||
drawerVisible.value = false | |||||
callback(validCount.value === props.applicationList.length) | |||||
}) | |||||
}, | |||||
doAsyncOperation = async (data) => { | |||||
applicationData.value = JSON.parse(JSON.stringify(data)) | |||||
await nextTick() // 必须nextTick,不然赋值视图上不会更新 | |||||
return new Promise((resolve, reject) => { | |||||
const form = [] | |||||
// form.push(new Promise((resolve, reject) => { | |||||
// appBasicInfoRef.value.validForm((valid) => { | |||||
// if (valid) { | |||||
// resolve() | |||||
// } else { | |||||
// reject(false) | |||||
// } | |||||
// }) | |||||
// })) | |||||
// form.push(new Promise((resolve, reject) => { | |||||
// appSafeInfoRef.value.validForm((valid) => { | |||||
// if (valid) { | |||||
// resolve() | |||||
// } else { | |||||
// reject(false) | |||||
// } | |||||
// }) | |||||
// })) | |||||
// form.push(new Promise((resolve, reject) => { | |||||
// appResourceInfoRef.value.validForm((valid) => { | |||||
// if (valid) { | |||||
// resolve() | |||||
// } else { | |||||
// reject(false) | |||||
// } | |||||
// }) | |||||
// })) | |||||
form.push(new Promise((resolve, reject) => { | |||||
applicationInfoRef.value.validForm((valid) => { | |||||
if (valid) { | |||||
resolve() | |||||
} else { | |||||
reject(false) | |||||
} | |||||
}) | |||||
})) | |||||
Promise.all([...form]).then(() => { | |||||
validCount.value++ | |||||
}).finally(() => { | |||||
resolve() | |||||
}) | |||||
}) | |||||
} | |||||
watch( | |||||
() => props.applicationList, | |||||
() => { | |||||
}, | |||||
{ immediate: true, deep: true } | |||||
) | |||||
defineExpose({ validAllAppForm }) | |||||
</script> | |||||
<template> | |||||
<div style="display: none"> | |||||
<!-- <app-basic-info--> | |||||
<!-- ref="appBasicInfoRef"--> | |||||
<!-- :data="applicationData"--> | |||||
<!-- :drawer-visible="drawerVisible"--> | |||||
<!-- :is-innovate-whole-province-share="isInnovateWholeProvinceShare"--> | |||||
<!-- />--> | |||||
<!-- <app-safe-info ref="appSafeInfoRef" :data="applicationData" />--> | |||||
<!-- <app-resource-info ref="appResourceInfoRef" :data="applicationData" />--> | |||||
<application-info | |||||
ref="applicationInfoRef" | |||||
:data="applicationData" | |||||
:is-first="isFirst" | |||||
/> | |||||
</div> | |||||
</template> |
@@ -0,0 +1,103 @@ | |||||
<script name="newModuleForm" setup> | |||||
import { fileFormatVerification, handleFileSuccess, handleFilePreview, fileTypes, fileDesc } from '@/utils/uploadAction.js' | |||||
import { onMounted, ref } from 'vue' | |||||
import store from '@/store' | |||||
const | |||||
uploadUrl = store.dictStore.uploadUrl, | |||||
props = defineProps({ | |||||
data: { | |||||
type: Object, | |||||
default: null | |||||
} | |||||
}), | |||||
formData = ref({ | |||||
formList: [] | |||||
}), | |||||
formRef = ref(), | |||||
// 校验 | |||||
validForm = (callback) => { | |||||
formRef.value.validate(valid => { | |||||
callback(valid) | |||||
}) | |||||
} | |||||
onMounted(() => { | |||||
formData.value = props.data | |||||
}) | |||||
defineExpose({ validForm, formData }) | |||||
</script> | |||||
<template> | |||||
<el-form | |||||
v-if="formData&&formData.formList?.length" | |||||
ref="formRef" | |||||
:model="formData" | |||||
label-position="right" | |||||
label-width="180px" | |||||
label-suffix=":" | |||||
scroll-to-error | |||||
@submit.prevent | |||||
> | |||||
<el-row :gutter="40"> | |||||
<el-col | |||||
v-for="(eachForm,order) in props.data&&props.data.formList" | |||||
:key="order" | |||||
:span="12" | |||||
> | |||||
<el-form-item | |||||
:label="eachForm.name" | |||||
:prop="`formList[${order}].value`" | |||||
:rules="[{ | |||||
required:eachForm.props.required, | |||||
message:'请完善必填内容' | |||||
}]" | |||||
> | |||||
<el-input | |||||
v-if="eachForm.props.type === '输入'" | |||||
v-model="formData.formList[order].value" | |||||
placeholder="请输入" | |||||
:maxlength="eachForm.props.maxLength" | |||||
/> | |||||
<el-input-number | |||||
v-else-if="eachForm.props.type === '数值输入'" | |||||
v-model="formData.formList[order].value" | |||||
placeholder="请输入" | |||||
:min="eachForm.props.minNumber" | |||||
:max="eachForm.props.maxNumber" | |||||
:controls="false" | |||||
@mousewheel.prevent | |||||
/> | |||||
<el-radio-group v-else-if="eachForm.props.type === '单选'" v-model="formData.formList[order].value"> | |||||
<el-radio v-for="( radioOption,radioIndex ) in eachForm.props.options" :key="radioIndex" :label="radioOption.name">{{ radioOption.name }}</el-radio> | |||||
</el-radio-group> | |||||
<el-checkbox-group v-else-if="eachForm.props.type === '多选'" v-model="formData.formList[order].value"> | |||||
<el-checkbox v-for="( checkboxOption,checkboxIndex ) in eachForm.props.options" :key="checkboxIndex" :label="checkboxOption.name">{{ checkboxOption.name }}</el-checkbox> | |||||
</el-checkbox-group> | |||||
<el-upload | |||||
v-else | |||||
v-model:file-list="formData.formList[order].value" | |||||
class="w-full" | |||||
:limit="eachForm.props.fileNumber" | |||||
:action="uploadUrl" | |||||
:on-success="res => handleFileSuccess(res, formData.formList[order].value, false)" | |||||
:before-upload="file=>fileFormatVerification(file, {types: fileTypes})" | |||||
:accept="fileTypes.map(i=>`.${i}`).join(',')" | |||||
:on-preview="handleFilePreview" | |||||
> | |||||
<el-button type="primary" plain>选择文件</el-button> | |||||
<template #tip> | |||||
<div class="el-upload__tip"> | |||||
支持{{ fileDesc }}文件 | |||||
</div> | |||||
</template> | |||||
</el-upload> | |||||
</el-form-item> | |||||
</el-col> | |||||
</el-row> | |||||
</el-form> | |||||
</template> | |||||
<style lang="less"> | |||||
.el-upload-list{ | |||||
width: 100%; | |||||
} | |||||
</style> |
@@ -0,0 +1,92 @@ | |||||
<script name="safetyInput" setup> | |||||
import { ref } from 'vue' | |||||
const formData = ref({}), | |||||
formRef = ref(), | |||||
rules = { | |||||
engineeringSpeedOne: [ | |||||
{ required: true, message: '请填写第一季度进度', trigger: 'blur' } | |||||
], | |||||
engineeringSpeedTwo: [ | |||||
{ required: true, message: '请填写第二季度进度', trigger: 'blur' } | |||||
], | |||||
engineeringSpeedThree: [ | |||||
{ required: true, message: '请填写第三季度进度', trigger: 'blur' } | |||||
], | |||||
engineeringSpeedFour: [ | |||||
{ required: true, message: '请填写第四季度进度', trigger: 'blur' } | |||||
] | |||||
}, | |||||
// 校验 | |||||
validForm = (callback) => { | |||||
formRef.value.validate(valid => { | |||||
callback(valid) | |||||
}) | |||||
}, | |||||
// 回显 | |||||
setFormData = (data) => { | |||||
formData.value = { | |||||
engineeringSpeedOne: data.engineeringSpeedOne, | |||||
engineeringSpeedTwo: data.engineeringSpeedTwo, | |||||
engineeringSpeedThree: data.engineeringSpeedThree, | |||||
engineeringSpeedFour: data.engineeringSpeedFour | |||||
} | |||||
} | |||||
defineExpose({ validForm, formData, setFormData }) | |||||
</script> | |||||
<template> | |||||
<el-form | |||||
ref="formRef" | |||||
:model="formData" | |||||
:rules="rules" | |||||
label-position="right" | |||||
label-width="180px" | |||||
label-suffix=":" | |||||
scroll-to-error | |||||
> | |||||
<el-row :gutter="40"> | |||||
<el-col :span="12"> | |||||
<el-form-item label="第一季度" prop="engineeringSpeedOne"> | |||||
<el-input | |||||
v-model="formData.engineeringSpeedOne" | |||||
maxlength="50" | |||||
placeholder="请填写" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="12"> | |||||
<el-form-item label="第二季度" prop="engineeringSpeedTwo"> | |||||
<el-input | |||||
v-model="formData.engineeringSpeedTwo" | |||||
maxlength="50" | |||||
placeholder="请填写" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="12"> | |||||
<el-form-item label="第三季度" prop="engineeringSpeedThree"> | |||||
<el-input | |||||
v-model="formData.engineeringSpeedThree" | |||||
maxlength="50" | |||||
placeholder="请填写" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="12"> | |||||
<el-form-item label="第四季度" prop="engineeringSpeedFour"> | |||||
<el-input | |||||
v-model="formData.engineeringSpeedFour" | |||||
maxlength="50" | |||||
placeholder="请填写" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
</el-row> | |||||
</el-form> | |||||
</template> | |||||
<style lang="less"> | |||||
.el-upload-list{ | |||||
width: 100%; | |||||
} | |||||
</style> |
@@ -0,0 +1,53 @@ | |||||
<script name="projectRemark" setup> | |||||
import { ref } from 'vue' | |||||
const formData = ref({}), | |||||
formRef = ref(), | |||||
rules = {}, | |||||
// 校验 | |||||
validForm = (callback) => { | |||||
formRef.value.validate(valid => { | |||||
callback(valid) | |||||
}) | |||||
}, | |||||
// 回显 | |||||
setFormData = (data) => { | |||||
formData.value = { | |||||
projectRemarks: data.projectRemarks | |||||
} | |||||
} | |||||
defineExpose({ validForm, formData, setFormData }) | |||||
</script> | |||||
<template> | |||||
<el-form | |||||
ref="formRef" | |||||
:model="formData" | |||||
:rules="rules" | |||||
label-position="right" | |||||
label-width="180px" | |||||
label-suffix=":" | |||||
scroll-to-error | |||||
> | |||||
<el-row :gutter="40"> | |||||
<el-col :span="24"> | |||||
<el-form-item | |||||
label="备注" | |||||
> | |||||
<el-input | |||||
v-model="formData.projectRemarks" | |||||
maxlength="2000" | |||||
type="textarea" | |||||
placeholder="请填写" | |||||
show-word-limit | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
</el-row> | |||||
</el-form> | |||||
</template> | |||||
<style lang="less"> | |||||
.el-upload-list{ | |||||
width: 100%; | |||||
} | |||||
</style> |
@@ -0,0 +1,179 @@ | |||||
<script name="provincialExamine" setup> | |||||
import { nextTick, reactive, ref } from 'vue' | |||||
import { govStripList } from '@/http/apis/declareMange' | |||||
const formData = ref({}), | |||||
formRef = ref(), | |||||
rules = { | |||||
operationManageUnitName: [{ required: true, message: '请选择业务主管部门' }] | |||||
}, | |||||
// 校验 | |||||
validForm = (callback) => { | |||||
formRef.value.validate(valid => { | |||||
callback(valid) | |||||
}) | |||||
}, | |||||
// 回显 | |||||
setFormData = (data) => { | |||||
formData.value = { | |||||
operationManageUnit: data.operationManageUnit, | |||||
operationManageUnitName: '' | |||||
} | |||||
if (data.operationManageUnit) { | |||||
getTableData(true) | |||||
} | |||||
}, | |||||
dialogVisible = ref(false), | |||||
tableListRef = ref(), | |||||
searchForm = reactive({ | |||||
businessStripName: undefined | |||||
}), | |||||
showDialog = async () => { | |||||
dialogVisible.value = true | |||||
getTableData() | |||||
}, | |||||
column = [ | |||||
{ | |||||
type: 'selection', | |||||
key: 'businessStripCode', | |||||
width: '60' | |||||
}, | |||||
{ | |||||
label: '单位名称', | |||||
key: 'businessStripName', | |||||
prop: 'businessStripName', | |||||
minWidth: '150', | |||||
showOverflowTooltip: true | |||||
}, | |||||
{ | |||||
label: '单位编码', | |||||
key: 'businessStripCode', | |||||
prop: 'businessStripCode', | |||||
minWidth: '150', | |||||
showOverflowTooltip: true | |||||
} | |||||
], | |||||
tableData = ref(), | |||||
getTableData = async (flag) => { | |||||
const res = await govStripList({ ...searchForm }) | |||||
tableData.value = res.data | |||||
await nextTick() | |||||
const operationManageUnitName = [] | |||||
tableData.value && tableData.value.forEach(item => { | |||||
const dataIds = formData.value?.operationManageUnit?.split(',') || [] | |||||
if (dataIds.includes(item.businessStripCode)) { | |||||
if (!flag) { | |||||
tableListRef.value.toggleRowSelect(item, true) | |||||
} else { | |||||
operationManageUnitName.push(item.businessStripName) | |||||
} | |||||
} | |||||
}) | |||||
if (flag) { | |||||
formData.value.operationManageUnitName = operationManageUnitName.join(',') || '' | |||||
} | |||||
}, | |||||
reset = () => { | |||||
searchForm.businessStripName = undefined | |||||
getTableData() | |||||
}, | |||||
selectUnit = ref([]), | |||||
selectionChange = (val) => { | |||||
selectUnit.value = val | |||||
}, | |||||
submit = () => { | |||||
dialogVisible.value = false | |||||
formData.value.operationManageUnitName = selectUnit.value.map(i => i.businessStripName).join(',') | |||||
formData.value.operationManageUnit = selectUnit.value.map(i => i.businessStripCode).join(',') | |||||
} | |||||
defineExpose({ validForm, formData, setFormData }) | |||||
</script> | |||||
<template> | |||||
<el-form | |||||
ref="formRef" | |||||
:model="formData" | |||||
:rules="rules" | |||||
label-position="right" | |||||
label-width="180px" | |||||
label-suffix=":" | |||||
scroll-to-error | |||||
> | |||||
<el-row :gutter="40"> | |||||
<el-col :span="24"> | |||||
<el-form-item label="业务主管部门(省级)" prop="operationManageUnitName"> | |||||
<el-input | |||||
v-model="formData.operationManageUnitName" | |||||
placeholder="请选择" | |||||
readonly | |||||
@click="showDialog" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
</el-row> | |||||
</el-form> | |||||
<el-dialog | |||||
:model-value="dialogVisible" | |||||
title="上级条线主管单位" | |||||
width="60%" | |||||
@close="dialogVisible = false" | |||||
> | |||||
<el-form | |||||
:model="searchForm" | |||||
size="small" | |||||
label-suffix=":" | |||||
> | |||||
<el-row | |||||
:gutter="16" | |||||
class="mb-16" | |||||
> | |||||
<el-col :span="8"> | |||||
<el-form-item label="单位名称"> | |||||
<el-input | |||||
v-model="searchForm.businessStripName" | |||||
placeholder="请输入" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="16"> | |||||
<el-form-item class="btn"> | |||||
<div class="flex"> | |||||
<el-button | |||||
type="primary" | |||||
@click="getTableData" | |||||
>查询</el-button> | |||||
<el-button | |||||
@click="reset" | |||||
>重置</el-button> | |||||
</div> | |||||
</el-form-item> | |||||
</el-col> | |||||
</el-row> | |||||
</el-form> | |||||
<table-list | |||||
ref="tableListRef" | |||||
:column="column" | |||||
:data="tableData" | |||||
:pagination="false" | |||||
style="height: 600px;overflow: auto" | |||||
@get-table-data="getTableData" | |||||
@selection-change="selectionChange" | |||||
/> | |||||
<template #footer> | |||||
<span class="dialog-footer"> | |||||
<el-button @click="dialogVisible = false">关闭</el-button> | |||||
<el-button | |||||
type="primary" | |||||
@click="submit" | |||||
> | |||||
提交 | |||||
</el-button> | |||||
</span> | |||||
</template> | |||||
</el-dialog> | |||||
</template> | |||||
<style lang="less"> | |||||
.el-upload-list{ | |||||
width: 100%; | |||||
} | |||||
</style> |
@@ -0,0 +1,81 @@ | |||||
<script name="reviewCheck" setup> | |||||
import { ref } from 'vue' | |||||
const props = defineProps({ | |||||
detailData: { | |||||
type: Object, | |||||
default: () => { | |||||
return {} | |||||
} | |||||
}, | |||||
data: { | |||||
type: Array, | |||||
default: () => [] | |||||
} | |||||
}) | |||||
const formData = ref({ | |||||
reviewChecklist: props.data | |||||
}), | |||||
formRef = ref(), | |||||
// 校验 | |||||
validForm = (callback) => { | |||||
formRef.value.validate(valid => { | |||||
callback(valid) | |||||
}) | |||||
}, | |||||
// 回显 | |||||
setFormData = (data) => { | |||||
formData.value = { | |||||
reviewChecklist: data.reviewChecklist | |||||
} | |||||
} | |||||
defineExpose({ validForm, formData, setFormData }) | |||||
</script> | |||||
<template> | |||||
<el-form | |||||
ref="formRef" | |||||
:model="formData" | |||||
label-suffix=":" | |||||
label-position="top" | |||||
scroll-to-error | |||||
> | |||||
<template v-for="(item,index) in formData.reviewChecklist" :key="index"> | |||||
<p class="font-bold text-16">{{ item.title }}</p> | |||||
<template v-for="(child,key) in item.modules" :key="key"> | |||||
<el-row :gutter="16" class="items-center"> | |||||
<el-col :span="9"> | |||||
<el-form-item :label="child.subTitle"> | |||||
<el-input v-model="child.content" type="textarea" disabled /> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="6"> | |||||
<el-form-item label="否决情形"> | |||||
<el-input v-model="child.rejectionSituation" type="textarea" disabled /> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="9"> | |||||
<el-form-item | |||||
label="响应情况" | |||||
class="flex-form-item" | |||||
style="margin-bottom: 14px" | |||||
:prop="`reviewChecklist[${index}].modules[${key}].responseSituation`" | |||||
:rules="[{required:true,message:'请输入'}]" | |||||
> | |||||
<el-input v-model="child.responseSituation" /> | |||||
</el-form-item> | |||||
<el-form-item | |||||
label="对应页面" | |||||
class="flex-form-item" | |||||
style="margin-bottom: 0" | |||||
:prop="`reviewChecklist[${index}].modules[${key}].corrPageNum`" | |||||
:rules="[{required:true,message:'请输入'}]" | |||||
> | |||||
<el-input v-model="child.corrPageNum" /> | |||||
</el-form-item> | |||||
</el-col> | |||||
</el-row> | |||||
</template> | |||||
</template> | |||||
</el-form> | |||||
</template> |
@@ -0,0 +1,143 @@ | |||||
<script name="safetyInput" setup> | |||||
import { ref, getCurrentInstance } from 'vue' | |||||
const { proxy } = getCurrentInstance(), | |||||
formData = ref({ | |||||
safetyInput: [{}] | |||||
}), | |||||
formRef = ref(), | |||||
moneyValidator = (rule, value, callback) => { | |||||
if (!value) callback() | |||||
if (!/^\d+(\.\d{1,6})?$/.test(value)) { | |||||
callback('请输入正确格式,最多保留六位小数') | |||||
} else if (value * 1 >= 100000000) { | |||||
callback('请输入正确格式,小于100000000') | |||||
} else { | |||||
callback() | |||||
} | |||||
}, | |||||
rules = { | |||||
safetyInputTitle: [ | |||||
{ required: true, message: '请输入投入项', trigger: 'blur' } | |||||
], | |||||
safetyInputDescribe: [ | |||||
{ required: true, message: '请输入内容描述', trigger: 'blur' } | |||||
], | |||||
safetyInputAmount: [ | |||||
{ required: true, message: '请输入金额', trigger: 'blur' }, | |||||
{ validator: moneyValidator, trigger: 'blur' } | |||||
] | |||||
}, | |||||
// 校验 | |||||
validForm = (callback) => { | |||||
formRef.value.validate(valid => { | |||||
callback(valid) | |||||
}) | |||||
}, | |||||
// 回显 | |||||
setFormData = (data) => { | |||||
formData.value = { | |||||
safetyInput: data.safetyInputDescribe ? JSON.parse(data.safetyInputDescribe) : [{}] | |||||
} | |||||
}, | |||||
// 添加 | |||||
add = () => { | |||||
if (formData.value.safetyInput.length >= 10) { | |||||
proxy.$message.warning('最多添加10项') | |||||
return | |||||
} | |||||
formData.value.safetyInput.push({}) | |||||
}, | |||||
// 删除 | |||||
del = (index) => { | |||||
formData.value.safetyInput.splice(index, 1) | |||||
} | |||||
defineExpose({ validForm, formData, setFormData }) | |||||
</script> | |||||
<template> | |||||
<el-form | |||||
ref="formRef" | |||||
:model="formData" | |||||
:rules="rules" | |||||
label-position="right" | |||||
label-width="180px" | |||||
label-suffix=":" | |||||
scroll-to-error | |||||
> | |||||
<div | |||||
v-for="(item,index) in formData.safetyInput" | |||||
:key="index" | |||||
style="background: #f5f8fa" | |||||
class="p-8 mb-16 relative" | |||||
> | |||||
<el-row :gutter="40"> | |||||
<el-col :span="12"> | |||||
<el-form-item | |||||
label="投入项" | |||||
:prop="`safetyInput[${index}].safetyInputTitle`" | |||||
:rules="{ | |||||
required: true, | |||||
message: '请输入', | |||||
}" | |||||
> | |||||
<el-input | |||||
v-model="formData.safetyInput[index].safetyInputTitle" | |||||
placeholder="请输入" | |||||
:maxlength="50" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="24"> | |||||
<el-form-item | |||||
label="内容描述" | |||||
:prop="`safetyInput[${index}].safetyInputDescribe`" | |||||
:rules="{ | |||||
required: true, | |||||
message: '请输入', | |||||
}" | |||||
> | |||||
<el-input | |||||
v-model="formData.safetyInput[index].safetyInputDescribe" | |||||
:rows="4" | |||||
maxlength="2000" | |||||
type="textarea" | |||||
show-word-limit | |||||
placeholder="请输入" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="12"> | |||||
<el-form-item | |||||
label="金额(万元)" | |||||
:prop="`safetyInput[${index}].safetyInputDescribe`" | |||||
:rules="{ | |||||
required: true, | |||||
message: '请输入', | |||||
}" | |||||
> | |||||
<el-input-number | |||||
v-model="formData.safetyInput[index].safetyInputAmount" | |||||
placeholder="请填写" | |||||
:min="0" | |||||
:controls="false" | |||||
@mousewheel.prevent | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
</el-row> | |||||
<span v-if="formData.safetyInput.length>1" class="text-danger absolute right-8 top-8 cursor-pointer" @click="del(index)">删除</span> | |||||
</div> | |||||
<el-button | |||||
type="primary" | |||||
icon="Plus" | |||||
plain | |||||
@click="add" | |||||
>添加投入项</el-button> | |||||
</el-form> | |||||
</template> | |||||
<style lang="less"> | |||||
.el-upload-list{ | |||||
width: 100%; | |||||
} | |||||
</style> |
@@ -0,0 +1,870 @@ | |||||
<script name="declarePage" setup> | |||||
import { getCurrentInstance, nextTick, onMounted, reactive, ref } from 'vue' | |||||
import { getFormConfig } from '@/http/apis/systemManage/formConfiguration' | |||||
import { useRoute, useRouter } from 'vue-router' | |||||
import { storeToRefs } from 'pinia' | |||||
import store from '@/store' | |||||
import BasicInfo from './components/basicInfo.vue' | |||||
import FundsInfo from './components/fundsInfo.vue' | |||||
import FundsAllocation from './components/fundsAllocation.vue' | |||||
import AnnualPaymentPlan from './components/annualPaymentPlan.vue' | |||||
import CoreBusiness from './components/coreBusiness.vue' | |||||
import SafetyInput from './components/safetyInput.vue' | |||||
import ProjectImageProgress from './components/projectImageProgress.vue' | |||||
import Accessory from './components/accessory.vue' | |||||
import ProjectRemark from './components/projectRemark.vue' | |||||
import NewModuleForm from './components/newModuleForm.vue' | |||||
import Applications from './components/applications.vue' | |||||
import HiddenAppForm from './components/hiddenAppForm.vue' | |||||
import FlowRecordDialog from '@/pages/projectStoreManage/projectStore/projectDetail/components/flowRecordDialog.vue' | |||||
import { declareConstructionScheme, getDraftDetail, projectStart, saveDraft } from '@/http/apis/declareMange' | |||||
import { projectDetail } from '@/http/apis/projectStoreManage/projectStore' | |||||
import { annualPlanModify } from '@/http/apis/projectStoreManage/annualPlanStore' | |||||
import { adjustAndHandle, progressDetail } from '@/http/apis/toDoCenter/todoList' | |||||
import { changFilesParam, reviewFileParam } from '@/utils/uploadAction' | |||||
import { dictionary } from '@/http/apis/projectCollection/projectCollectionEnter' | |||||
import ReviewCheck from '@/pages/declareManage/projectDeclare/declarePage/components/reviewCheck.vue' | |||||
import { getIsShowReviewCheck } from '@/utils/getIsShowReviewCheck' | |||||
import ProvincialExamine from '@/pages/declareManage/projectDeclare/declarePage/components/provincialExamine.vue' | |||||
const { proxy } = getCurrentInstance(), | |||||
route = useRoute(), | |||||
router = useRouter(), | |||||
userInfo = storeToRefs(store.userStore).userInfo || {}, | |||||
formConfig = ref({}), | |||||
collapseModal = ref(['1', '2', '3', '4', '5', '6', '7', '8', '9', '10']), | |||||
basicInfoRef = ref(), // 基本信息 | |||||
fundsInfoRef = ref(), // 资金申报情况 | |||||
fundsAllocationRef = ref(), // 资金分配情况 | |||||
provincialExamineRef = ref(), // 重大项目省级联审 | |||||
annualPaymentPlanRef = ref(), // 年度计划支付 | |||||
coreBusinessRef = ref(), // 核心业务 | |||||
safetyInputRef = ref(), // 安全投入 | |||||
projectImageProgressRef = ref(), // 工程形象进度 | |||||
accessoryRef = ref(), // 附件 | |||||
projectRemarkRef = ref(), // 备注 | |||||
newModuleformRef = ref({}), // 新增模块 | |||||
applicationsRef = ref(), // 应用 | |||||
hiddenAppFormRef = ref(), | |||||
reviewCheckRef = ref(), // 审查清单 | |||||
// 提交 | |||||
submitAllForm = () => { | |||||
const form = [] | |||||
if (basicInfoRef.value.formData?.baseProjIsConfidentiality === '02') { | |||||
form.push(new Promise((resolve, reject) => { | |||||
basicInfoRef.value.validForm((valid) => { | |||||
if (valid) { | |||||
resolve() | |||||
} | |||||
}) | |||||
})) | |||||
} else { | |||||
form.push(new Promise((resolve, reject) => { | |||||
basicInfoRef.value.validForm((valid) => { | |||||
if (valid) { | |||||
if (fundsInfoRef.value.formData.declareAmount >= 1000 && basicInfoRef.value.formData.baseProvManDeprtType === '2') { | |||||
basicInfoRef.value.formData.baseProvManDeprtType = '' | |||||
reject('根据《浙江省电子政务重大应用项目联审》要求:大于1000万元的重大项目将由省级数改牵头部门及业务主管单位进行联审,请将上级主管单位修改为您对应条线的省级主管单位。') | |||||
} else { | |||||
resolve() | |||||
} | |||||
} | |||||
}) | |||||
})) | |||||
form.push(new Promise((resolve, reject) => { | |||||
fundsInfoRef.value.validForm((valid) => { | |||||
if (valid) resolve() | |||||
}) | |||||
})) | |||||
form.push(new Promise((resolve, reject) => { | |||||
fundsAllocationRef.value.validForm((valid) => { | |||||
if (valid) resolve() | |||||
}) | |||||
})) | |||||
form.push(new Promise((resolve, reject) => { | |||||
annualPaymentPlanRef.value.validForm((valid) => { | |||||
if (valid) resolve() | |||||
}) | |||||
})) | |||||
formConfig.value.isCoreBusiness && form.push(new Promise((resolve, reject) => { | |||||
coreBusinessRef.value.validForm((valid) => { | |||||
if (valid) resolve() | |||||
}) | |||||
})) | |||||
formConfig.value.isSafetyInput && form.push(new Promise((resolve, reject) => { | |||||
safetyInputRef.value.validForm((valid) => { | |||||
if (valid) resolve() | |||||
}) | |||||
})) | |||||
formConfig.value.isProjectImageProgress && form.push(new Promise((resolve, reject) => { | |||||
projectImageProgressRef.value.validForm((valid) => { | |||||
if (valid) resolve() | |||||
}) | |||||
})) | |||||
getIsShowReviewCheck() && formConfig.value.isReviewChecklist && (route.name === 'declarePlan' || [10012, 10013, 10016].includes(detailData.value?.status)) && form.push(new Promise((resolve, reject) => { | |||||
reviewCheckRef.value.validForm((valid) => { | |||||
if (valid) resolve() | |||||
}) | |||||
})) | |||||
form.push(new Promise((resolve, reject) => { | |||||
accessoryRef.value.validForm((valid) => { | |||||
if (valid) resolve() | |||||
}) | |||||
})) | |||||
for (const key in newModuleformRef.value) { | |||||
form.push(new Promise((resolve, reject) => { | |||||
newModuleformRef.value[key].validForm((valid) => { | |||||
if (valid) resolve() | |||||
}) | |||||
})) | |||||
} | |||||
applicationsRef.value && form.push(new Promise((resolve, reject) => { | |||||
applicationsRef.value.validForm((valid) => { | |||||
if (valid) resolve() | |||||
}) | |||||
})) | |||||
form.push(new Promise((resolve, reject) => { | |||||
fundsInfoRef.value.validForm((valid) => { | |||||
if (valid) { | |||||
const total = floatAdd([fundsInfoRef.value.formData.declareHaveAmount, fundsInfoRef.value.formData.declareGovOwnFinanceAmount, fundsInfoRef.value.formData.declareGovSuperiorFinanceAmount, fundsInfoRef.value.formData.declareBankLendingAmount, fundsInfoRef.value.formData.declareOtherAmount]) | |||||
if (fundsInfoRef.value.formData.declareAmount > 0 && fundsInfoRef.value.formData.declareAmount === total) { resolve() } else { | |||||
reject('资金申报情况:5类资金总和必须等于申报金额') | |||||
} | |||||
} | |||||
}) | |||||
})) | |||||
form.push(new Promise((resolve, reject) => { | |||||
fundsAllocationRef.value.validForm(valid => { | |||||
if (valid) { | |||||
const total = floatAdd([fundsAllocationRef.value.formData.softwareDevelopmentAmount, fundsAllocationRef.value.formData.cloudHardwarePurchaseAmount, fundsAllocationRef.value.formData.thirdPartyAmount]) | |||||
if (fundsInfoRef.value.formData.declareAmount > 0 && fundsInfoRef.value.formData.declareAmount === total) { resolve() } else { | |||||
reject('资金分配情况:3类资金总和必须等于申报金额') | |||||
} | |||||
} | |||||
}) | |||||
})) | |||||
applicationsRef.value?.formData.includeApplication === 1 && form.push(new Promise((resolve, reject) => { | |||||
hiddenAppFormRef.value.validAllAppForm((valid) => { | |||||
if (valid) { | |||||
resolve() | |||||
} else { | |||||
reject('请完善已添加的应用信息') | |||||
} | |||||
}) | |||||
})) | |||||
} | |||||
Promise.all([...form]).then(async () => { | |||||
if (basicInfoRef.value.formData?.baseProjIsConfidentiality === '02') { | |||||
saveData(1) | |||||
} else { | |||||
if (formConfig.value.isSafetyInput) { | |||||
const num = safetyInputRef.value?.formData.safetyInput.reduce((acc, cur) => acc + cur.safetyInputAmount, 0) | |||||
const precent = (num / fundsInfoRef.value.formData.declareAmount) * 100 | |||||
if (precent < 5) { | |||||
proxy.$messageBox | |||||
.confirm(`当前安全投入占比低于5%,确认要提交吗?`, '确认要提交吗?', { | |||||
type: 'warning' | |||||
}) | |||||
.then(async () => { | |||||
saveData(1) | |||||
}) | |||||
} else { | |||||
saveData(1) | |||||
} | |||||
} else { | |||||
saveData(1) | |||||
} | |||||
} | |||||
}).catch(err => { | |||||
if (err) { | |||||
proxy.$message.warning(err) | |||||
} | |||||
}) | |||||
}, | |||||
floatAdd = (args) => { | |||||
const data = [] | |||||
args.forEach(i => { | |||||
try { | |||||
data.push(i.toString().split('.')[1].length) | |||||
} catch (e) { | |||||
data.push(0) | |||||
} | |||||
}) | |||||
const m = Math.pow(10, Math.max(...data)) | |||||
let sum = 0 | |||||
args.forEach(item => { | |||||
sum += item * m | |||||
}) | |||||
return sum / m | |||||
}, | |||||
// 保存草稿 | |||||
toSaveDraft = async () => { | |||||
saveData(2) | |||||
}, | |||||
// 设置应用是否填写完全的值 | |||||
changeIsFirst = (val) => { | |||||
if (applicationsRef.value?.formData && applicationsRef.value?.formData.includeApplication === 1 && applicationsRef.value?.formData?.applicationList?.length) { | |||||
applicationsRef.value.formData.applicationList = applicationsRef.value.formData?.applicationList?.map(data => { | |||||
return { | |||||
...data, | |||||
applicationName: val ? data.applicationName : undefined, | |||||
relatedExistsApplication: !val ? data.relatedExistsApplication : undefined, | |||||
relatedExistsApplicationCode: !val ? data.relatedExistsApplication : undefined | |||||
} | |||||
}) | |||||
} | |||||
}, | |||||
saveLoading = ref(false), | |||||
submitLoading = ref(false), | |||||
saveData = async (type) => { | |||||
// const buildBasis = basicInfoRef.value.formData?.buildBasis?.map(i => { | |||||
// return { | |||||
// ...i, | |||||
// fileList: changFilesParam(i.fileList), | |||||
// fileName: i.fileList?.[0].name || '' | |||||
// } | |||||
// }) | |||||
var postData = {} | |||||
if (basicInfoRef.value.formData?.baseProjIsConfidentiality === '02') { | |||||
postData = { | |||||
isRemarks: formConfig.value.isRemarks, | |||||
isOpenCoreBusiness: formConfig.value.isCoreBusiness, | |||||
isOpenSafetyInput: formConfig.value.isSafetyInput, | |||||
isEngineeringSpeed: formConfig.value.isProjectImageProgress, | |||||
isReviewChecklist: formConfig.value.isReviewChecklist, | |||||
id: route.query.id * 1 || undefined, | |||||
baseProjIsConfidentiality: basicInfoRef.value.formData?.baseProjIsConfidentiality, | |||||
projectName: basicInfoRef.value.formData?.projectName, | |||||
projectType: basicInfoRef.value.formData?.projectType, | |||||
baseConstructionType: basicInfoRef.value.formData?.baseConstructionType?.join(';') || '', | |||||
responsibleMan: basicInfoRef.value.formData?.responsibleMan, | |||||
responsibleManMobile: basicInfoRef.value.formData?.responsibleManMobile, | |||||
contactName: basicInfoRef.value.formData?.contactName, | |||||
contactPhone: basicInfoRef.value.formData?.contactPhone, | |||||
buildOrgName: basicInfoRef.value.formData?.buildOrgName, | |||||
orgCreditCode: basicInfoRef.value.formData?.orgCreditCode, | |||||
baseProvManDeprtType: basicInfoRef.value.formData.baseProvManDeprtType * 1 || undefined, | |||||
higherSuperOrg: basicInfoRef.value.formData?.higherSuperOrg, | |||||
higherSuperOrgCode: basicInfoRef.value.formData?.higherSuperOrgCode, | |||||
superOrg: basicInfoRef.value.formData?.superOrg, | |||||
superOrgCode: basicInfoRef.value.formData?.superOrgCode, | |||||
superOrgCreditCode: basicInfoRef.value.formData?.superOrgCreditCode, | |||||
projectYear: basicInfoRef.value.formData?.projectYear * 1, | |||||
declareAmount: basicInfoRef.value.formData?.declareAmount, | |||||
annualPlanAmount: basicInfoRef.value.formData?.declareAmount | |||||
} | |||||
} else { | |||||
postData = { | |||||
isRemarks: formConfig.value.isRemarks, | |||||
isOpenCoreBusiness: formConfig.value.isCoreBusiness, | |||||
isOpenSafetyInput: formConfig.value.isSafetyInput, | |||||
isEngineeringSpeed: formConfig.value.isProjectImageProgress, | |||||
isReviewChecklist: formConfig.value.isReviewChecklist, | |||||
id: route.query.id * 1 || undefined, | |||||
...basicInfoRef.value.formData, | |||||
...fundsInfoRef.value.formData, | |||||
...fundsAllocationRef.value.formData, | |||||
bizDomain: basicInfoRef.value.formData?.isDigitalReform === 1 ? basicInfoRef.value.formData.bizDomain.join(',') : undefined, | |||||
baseConstructionType: basicInfoRef.value.formData?.baseConstructionType?.join(';') || '', | |||||
baseProvManDeprtType: basicInfoRef.value.formData.baseProvManDeprtType * 1 || undefined, | |||||
projectYear: fundsInfoRef.value.formData?.projectYear * 1, | |||||
beginTime: basicInfoRef.value.formData?.buildDuration?.length && basicInfoRef.value.formData.buildDuration[0], | |||||
endTime: basicInfoRef.value.formData?.buildDuration?.length && basicInfoRef.value.formData.buildDuration[1], | |||||
buildDuration: undefined, | |||||
lowestLevel: !(basicInfoRef.value.formData?.baseConstructionType?.includes('03') && !basicInfoRef.value.formData?.baseConstructionType?.includes('01')) && basicInfoRef.value.formData?.lowestLevel || '', | |||||
// buildBasis: buildBasis && JSON.stringify(buildBasis), | |||||
baseProjBasis: basicInfoRef.value.formData?.baseProjBasis?.map(i => i.value)?.join(';') || undefined, | |||||
baseProjBasisFile: basicInfoRef.value.formData?.baseProjBasis?.map(i => i.fileList && JSON.stringify(changFilesParam(i.fileList)))?.join(';') || '', | |||||
cloudType: basicInfoRef.value.formData?.isCloud && basicInfoRef.value.formData?.cloudType?.length && basicInfoRef.value.formData.cloudType.join(',') || undefined, | |||||
baseHistorProjId: basicInfoRef.value.formData?.baseHistorProjs?.map(i => i.baseProjId)?.join(';') || '', | |||||
baseHistorProjName: basicInfoRef.value.formData?.baseHistorProjs?.map(i => i.baseProjName)?.join(';') || '', | |||||
baseHistorProjYear: basicInfoRef.value.formData?.baseHistorProjs?.map(i => i.baseProjSetYear)?.join(';') || '', | |||||
baseHistorProjs: undefined, | |||||
beseExpectedResults: basicInfoRef.value.formData?.beseExpectedResults?.length && JSON.stringify(basicInfoRef.value.formData.beseExpectedResults) || '', | |||||
baseBasisAmountOri: fundsInfoRef.value?.formData.declareOtherAmount > 0 && fundsInfoRef.value.formData?.baseBasisAmountOri || '', | |||||
consultancy: fundsInfoRef.value?.formData.declareAmount > 400 && fundsInfoRef.value.formData?.consultancy || '', | |||||
operationManageUnit: fundsInfoRef.value?.formData.declareAmount >= 1000 && provincialExamineRef.value.formData.operationManageUnit || undefined, | |||||
...applicationsRef.value?.formData, | |||||
...annualPaymentPlanRef.value.formData, | |||||
...accessoryRef.value.formData, | |||||
constructionPlanFile: accessoryRef.value.formData?.constructionPlanFile && JSON.stringify(changFilesParam(accessoryRef.value.formData.constructionPlanFile)), | |||||
preliminaryPlanFile: accessoryRef.value.formData?.preliminaryPlanFile && JSON.stringify(changFilesParam(accessoryRef.value.formData.preliminaryPlanFile)), | |||||
mainResponsibilitiesApplicantFile: accessoryRef.value.formData?.mainResponsibilitiesApplicantFile && JSON.stringify(changFilesParam(accessoryRef.value.formData.mainResponsibilitiesApplicantFile)), | |||||
supportingMaterialsFile: accessoryRef.value.formData?.supportingMaterialsFile && JSON.stringify(changFilesParam(accessoryRef.value.formData.supportingMaterialsFile)), | |||||
calculationTotalInvestmentFile: accessoryRef.value.formData?.calculationTotalInvestmentFile && JSON.stringify(changFilesParam(accessoryRef.value.formData.calculationTotalInvestmentFile)), | |||||
projectApplicationForm: basicInfoRef.value.formData?.projectType !== '03' && accessoryRef.value.formData?.projectApplicationForm && JSON.stringify(changFilesParam(accessoryRef.value.formData.projectApplicationForm)) || '', | |||||
baseResearchReportFile: basicInfoRef.value.formData?.projectType !== '03' && accessoryRef.value.formData?.baseResearchReportFile && JSON.stringify(changFilesParam(accessoryRef.value.formData.baseResearchReportFile)) || '', | |||||
baseProjOtherFile: accessoryRef.value.formData?.baseProjOtherFile && JSON.stringify(changFilesParam(accessoryRef.value.formData.baseProjOtherFile)), | |||||
mainAccusationDoc: fundsInfoRef.value?.formData.declareAmount >= 1000 && accessoryRef.value.formData?.mainAccusationDoc && JSON.stringify(changFilesParam(accessoryRef.value.formData.mainAccusationDoc)) || '', | |||||
reviewChecklist: reviewCheckRef.value?.formData?.reviewChecklist || undefined | |||||
} | |||||
if (formConfig.value.isCoreBusiness) { | |||||
postData = Object.assign(postData, { ...coreBusinessRef.value.formData, coreBusiness: coreBusinessRef.value.formData.coreBusiness && JSON.stringify(coreBusinessRef.value.formData.coreBusiness) }) | |||||
} | |||||
if (formConfig.value.isSafetyInput) { | |||||
// ...safetyInputRef.value.formData | |||||
postData = Object.assign(postData, { | |||||
safetyInputDescribe: JSON.stringify(safetyInputRef.value.formData.safetyInput) | |||||
}) | |||||
} | |||||
if (formConfig.value.isProjectImageProgress) { | |||||
postData = Object.assign(postData, { ...projectImageProgressRef.value.formData }) | |||||
} | |||||
if (formConfig.value.isRemark) { | |||||
postData = Object.assign(postData, { ...projectRemarkRef.value.formData }) | |||||
} | |||||
if (applicationsRef.value?.formData?.includeApplication && applicationsRef.value?.formData.applicationList?.length) { | |||||
postData.applicationList = applicationsRef.value.formData.applicationList.map(i => { | |||||
return { | |||||
...i, | |||||
isFirst: !basicInfoRef.value.formData?.isFirst ? 0 : 1, | |||||
relatedExistsApplication: ((!basicInfoRef.value.formData?.isFirst && userInfo.value.regionCode === '331123') || userInfo.regionCode !== '331123') && i.relatedExistsApplication?.applicationName || undefined, | |||||
relatedExistsApplicationCode: ((!basicInfoRef.value.formData?.isFirst && userInfo.value.regionCode === '331123') || userInfo.regionCode !== '331123') && i.relatedExistsApplicationCode || undefined, | |||||
applicationName: (basicInfoRef.value.formData?.isFirst && userInfo.regionCode === '331123') && i.applicationName || undefined, | |||||
coreBusinessList: i.coreBusinessList.map(j => { | |||||
return { | |||||
...j, | |||||
projectId: detailData.value?.projectId || undefined, | |||||
projectCode: detailData.value?.projectCode || undefined | |||||
} | |||||
}) | |||||
} | |||||
}) | |||||
} | |||||
if (formConfig.value.safetyInputModular?.length) { | |||||
postData.safetyInputModular = [] | |||||
for (const key in newModuleformRef.value) { | |||||
postData.safetyInputModular.push( | |||||
newModuleformRef.value[key].formData | |||||
) | |||||
} | |||||
const safetyInputModular = postData.safetyInputModular.map(i => { | |||||
return { | |||||
...i, | |||||
formList: i.formList.map(j => { | |||||
return { | |||||
...j, | |||||
value: !j.value ? undefined : j.props.type === '文件上传' ? changFilesParam(j.value) : j.value | |||||
} | |||||
}) | |||||
} | |||||
}) | |||||
postData.safetyInputModular = JSON.stringify(safetyInputModular) | |||||
} else { | |||||
postData.safetyInputModular = undefined | |||||
} | |||||
} | |||||
if (type === 1) { | |||||
submitLoading.value = true | |||||
try { | |||||
const data = { | |||||
projectInfo: { ...postData, id: !route.query.isDraft ? postData.id : undefined, draftId: route.query.isDraft ? route.query.id * 1 : undefined } | |||||
} | |||||
if (route.name === 'declarePage') { | |||||
await projectStart(!route.query.isDraft && route.query.id ? 2 : 1, data)// 申报 | |||||
} else if (route.name === 'planEdit') { | |||||
await annualPlanModify(data.projectInfo) // 年度计划编辑 | |||||
} else if (route.name === 'handleAfterGiveBack') { | |||||
await adjustAndHandle({ | |||||
...data, | |||||
projectId: route.query.id, | |||||
instanceId: route.query.instanceId, | |||||
taskId: route.query.taskId | |||||
}) | |||||
} else if (route.name === 'declarePlan') { | |||||
await declareConstructionScheme(data) | |||||
} | |||||
proxy.$message.success('提交成功') | |||||
submitLoading.value = false | |||||
if (route.name === 'projectDeclare') { | |||||
router.push({ name: 'projectDeclare' }) | |||||
} else { | |||||
router.go(-1) | |||||
} | |||||
} catch (e) { | |||||
submitLoading.value = false | |||||
} | |||||
} else if (type === 2) { | |||||
saveLoading.value = true | |||||
try { | |||||
await saveDraft({ | |||||
projectInfo: { ...postData }, | |||||
user: userInfo.value // 测试需要 | |||||
}) | |||||
proxy.$message.success('保存成功') | |||||
saveLoading.value = false | |||||
router.go(-1) | |||||
} catch (e) { | |||||
saveLoading.value = false | |||||
} | |||||
} | |||||
}, | |||||
// 回显 | |||||
detailData = ref({}), | |||||
// allApplicationsDone = ref(1), // 所有应用信息校验字段 | |||||
setData = () => { | |||||
basicInfoRef.value.setFormData(detailData.value) | |||||
if (detailData.value?.baseProjIsConfidentiality !== '02') { | |||||
fundsInfoRef.value.setFormData(detailData.value) | |||||
fundsAllocationRef.value.setFormData(detailData.value) | |||||
annualPaymentPlanRef.value.setFormData(detailData.value) | |||||
formConfig.value.isCoreBusiness && coreBusinessRef.value.setFormData(detailData.value) | |||||
formConfig.value.isSafetyInput && safetyInputRef.value.setFormData(detailData.value) | |||||
formConfig.value.isProjectImageProgress && projectImageProgressRef.value.setFormData(detailData.value) | |||||
accessoryRef.value.setFormData(detailData.value) | |||||
formConfig.value.isRemark && projectRemarkRef.value.setFormData(detailData.value) | |||||
// detailData.value.safetyInputModular?.length && newModuleformRef.value.setFormData(detailData.value) | |||||
applicationsRef.value?.setFormData(detailData.value) | |||||
setTimeout(() => { | |||||
provincialExamineRef.value?.setFormData(detailData.value) | |||||
}) | |||||
} | |||||
}, | |||||
// 被退回处理 | |||||
// 获取审核详情 | |||||
flowData = ref({ | |||||
processProgressVo: { | |||||
progressInfo: [ | |||||
] | |||||
} | |||||
}), | |||||
lastData = ref(), | |||||
getFlowData = async () => { | |||||
const res = await progressDetail({ instanceId: route.query.instanceId, projectId: route.query.id, nodeId: route.query.nodeId }) | |||||
flowData.value = { | |||||
...res.data, | |||||
processProgressVo: { | |||||
...res.data.processProgressVo, | |||||
progressInfo: changeProgressInfo(res.data.processProgressVo.progressInfo) | |||||
} | |||||
} | |||||
lastData.value = flowData.value.processProgressVo.progressInfo.slice(-1)[0]?.children?.slice(-1)[0] || flowData.value.processProgressVo.progressInfo.slice(-1)[0] | |||||
}, | |||||
// 审核记录 | |||||
flowRecordDialogData = reactive({ | |||||
visible: false, | |||||
flowData: undefined | |||||
}), | |||||
showFlowRecordDialog = (data) => { | |||||
flowRecordDialogData.visible = true | |||||
flowRecordDialogData.flowData = flowData.value.processProgressVo.progressInfo | |||||
}, | |||||
changeProgressInfo = (data) => { | |||||
data.forEach(res => { | |||||
if (res.children) { | |||||
const nodeIds = [] | |||||
const newChildren = [] | |||||
res.children.forEach(child => { | |||||
if (!nodeIds.includes(child.nodeId)) { | |||||
nodeIds.push(child.nodeId) | |||||
newChildren.push({ | |||||
nodeId: child.nodeId, | |||||
approvalMode: child.approvalMode, | |||||
name: child.name, | |||||
taskId: child.taskId, | |||||
nodeType: child.nodeType, | |||||
list: [{ ...child }], | |||||
userIds: [child.userId] | |||||
}) | |||||
} else { | |||||
newChildren.find(i => i.nodeId === child.nodeId).list.push(child) | |||||
newChildren.find(i => i.nodeId === child.nodeId).userIds.push(child.userId) | |||||
} | |||||
}) | |||||
res.children = newChildren | |||||
} else { | |||||
res['userIds'] = [res.userId] | |||||
} | |||||
}) | |||||
return data | |||||
}, | |||||
closeFlowRecordDialog = () => { | |||||
flowRecordDialogData.visible = false | |||||
}, | |||||
dictionaryList = ref([]), | |||||
basicInfoData = ref(), | |||||
getBasicInfoData = (data) => { | |||||
basicInfoData.value = data | |||||
} | |||||
onMounted(async () => { | |||||
dictionaryList.value = (await dictionary()).data | |||||
if (!route.query.id) { | |||||
const res = await getFormConfig({ | |||||
regionCode: userInfo.value.regionCode | |||||
}) | |||||
formConfig.value = { | |||||
isCoreBusiness: res.data.isCoreBusiness, | |||||
isProjectImageProgress: res.data.isProjectImageProgress, | |||||
isRemark: res.data.isRemark, | |||||
isSafetyInput: res.data.isSafetyInput, | |||||
safetyInputModular: res.data.safetyInputModular || [] | |||||
} | |||||
} else { | |||||
var res = {}, res1 = {}, reviewChecklist = [], isReviewChecklist = false | |||||
if (route.query?.isDraft) { | |||||
res = await getDraftDetail({ id: route.query.id }) | |||||
} else { | |||||
res = await projectDetail(route.query.id) | |||||
res1 = await getFormConfig({ | |||||
regionCode: userInfo.value.regionCode | |||||
}) | |||||
if ((route.name === 'declarePlan' || [10012, 10013, 10016].includes(detailData.value?.status))) { | |||||
isReviewChecklist = res.data.reviewChecklist && JSON.parse(res.data.reviewChecklist)?.length ? true : res1.data.isReviewChecklist | |||||
reviewChecklist = res1.data.reviewChecklist && JSON.parse(res1.data.reviewChecklist) || [] | |||||
} | |||||
} | |||||
detailData.value = { | |||||
...res.data, | |||||
reviewChecklist: res.data.reviewChecklist ? JSON.parse(res.data.reviewChecklist) : undefined | |||||
} | |||||
const safetyInputModular = res.data.safetyInputModular && JSON.parse(res.data.safetyInputModular).map(i => { | |||||
return { | |||||
...i, | |||||
formList: i.formList.map(j => { | |||||
return { | |||||
...j, | |||||
value: !j.value ? undefined : j.props.type === '文件上传' ? reviewFileParam(j.value) : j.value | |||||
} | |||||
}) | |||||
} | |||||
}) | |||||
formConfig.value = { | |||||
isCoreBusiness: res.data.isOpenCoreBusiness, | |||||
isProjectImageProgress: res.data.isEngineeringSpeed, | |||||
isRemark: res.data.isRemark, | |||||
isSafetyInput: res.data.isOpenSafetyInput, | |||||
safetyInputModular: safetyInputModular || [], | |||||
isReviewChecklist, | |||||
reviewChecklist | |||||
} | |||||
nextTick(() => { | |||||
setData() | |||||
}) | |||||
if (route.name === 'handleAfterGiveBack') { | |||||
getFlowData() | |||||
} | |||||
} | |||||
if (formConfig.value.safetyInputModular?.length) { | |||||
let index = 11 | |||||
formConfig.value.safetyInputModular.forEach(i => { | |||||
collapseModal.value.push(index++ + '') | |||||
}) | |||||
} | |||||
}) | |||||
</script> | |||||
<template> | |||||
<div class="declarePage footerPage"> | |||||
<!-- 退回编辑--> | |||||
<div v-if="route.name==='handleAfterGiveBack'" class="errorTip mb-16"> | |||||
<el-icon class="icon"><Warning /></el-icon> | |||||
<div> | |||||
<p class="title">流程被退回</p> | |||||
<p> | |||||
<span>{{ detailData?.projectName }}的{{ flowData?.processProgressVo?.processDefName }}被退回,请根据审核记录调整项目信息</span> | |||||
<el-button | |||||
type="primary" | |||||
plain | |||||
size="small" | |||||
class="ml-16" | |||||
@click="showFlowRecordDialog" | |||||
>查看审核记录</el-button> | |||||
</p> | |||||
</div> | |||||
</div> | |||||
<!-- 建设方案申报--> | |||||
<el-card v-if="route.name==='declarePlan'" shadow="never" class="mb-16"> | |||||
<div class="card-header"> | |||||
<div class="flex justify-between items-center"> | |||||
<div class="flex-1"> | |||||
<p class="font-bold">{{ detailData.projectName }}</p> | |||||
<div class="mt-8 search"> | |||||
<el-form label-suffix=":"> | |||||
<el-row :gutter="24"> | |||||
<el-col :span="6"> | |||||
<el-form-item label="申报单位">{{ detailData.buildOrgName||'-' }}</el-form-item> | |||||
</el-col> | |||||
<el-col :span="6"> | |||||
<el-form-item label="主管单位">{{ detailData.superOrg||'-' }}</el-form-item> | |||||
</el-col> | |||||
<el-col :span="6"> | |||||
<el-form-item label="创建时间">{{ detailData.createOn||'-' }}</el-form-item> | |||||
</el-col> | |||||
</el-row> | |||||
</el-form> | |||||
</div> | |||||
</div> | |||||
</div> | |||||
</div> | |||||
</el-card> | |||||
<el-row> | |||||
<el-col class="leftCol" :span="24"> | |||||
<el-collapse v-model="collapseModal"> | |||||
<el-collapse-item name="1" class="mb-16"> | |||||
<template #title> | |||||
<div class="collapse-title">基本信息</div> | |||||
</template> | |||||
<div class="p-24"> | |||||
<basic-info | |||||
ref="basicInfoRef" | |||||
:detail-data="detailData" | |||||
:dictionary-list="dictionaryList" | |||||
:declare-amount="fundsInfoRef?.formData.declareAmount" | |||||
@change-is-first="changeIsFirst" | |||||
@get-basic-info-data="getBasicInfoData" | |||||
/> | |||||
</div> | |||||
</el-collapse-item> | |||||
<template v-if="basicInfoRef?.formData?.baseProjIsConfidentiality==='01'"> | |||||
<el-collapse-item v-if="basicInfoRef?.formData?.baseProjIsConfidentiality==='01'" name="2" class="mb-16"> | |||||
<template #title> | |||||
<div class="collapse-title"> | |||||
<span>资金申报情况(单位:万元)</span> | |||||
<span class="text-info">申报金额 = 自有资金 + 政府投资-本级财政资金 + 政府投资-上级补助资金 + 银行贷款 + 其他资金</span> | |||||
</div> | |||||
</template> | |||||
<div class="p-24"> | |||||
<funds-info ref="fundsInfoRef" :detail-data="detailData" /> | |||||
</div> | |||||
</el-collapse-item> | |||||
<el-collapse-item v-if="basicInfoRef?.formData?.baseProjIsConfidentiality==='01'" name="3" class="mb-16"> | |||||
<template #title> | |||||
<div class="collapse-title"> | |||||
资金分配情况(单位:万元) | |||||
<span class="text-info">软件开发 + 云资源、硬件配置 + 第三方服务 = 申报金额</span> | |||||
</div> | |||||
</template> | |||||
<div class="p-24"> | |||||
<funds-allocation ref="fundsAllocationRef" /> | |||||
</div> | |||||
</el-collapse-item> | |||||
<el-collapse-item v-if="fundsInfoRef?.formData.declareAmount>=1000&&basicInfoRef?.formData?.baseProjIsConfidentiality==='01'" name="10" class="mb-16"> | |||||
<template #title> | |||||
<div class="collapse-title"> | |||||
重大项目省级联审信息 | |||||
</div> | |||||
</template> | |||||
<div class="p-24"> | |||||
<provincial-examine ref="provincialExamineRef" /> | |||||
</div> | |||||
</el-collapse-item> | |||||
<el-collapse-item | |||||
v-if="basicInfoRef?.formData?.baseProjIsConfidentiality==='01'" | |||||
name="4" | |||||
class="mb-16" | |||||
> | |||||
<template #title> | |||||
<div class="collapse-title"> | |||||
年度支付计划(单位:万元) | |||||
<span class="text-info">年度支付金额 = 自有资金 + 政府投资-本级财政资金 + 政府投资-上级补助资金 + 银行贷款 + 其他资金</span> | |||||
</div> | |||||
</template> | |||||
<div class="p-24"> | |||||
<annual-payment-plan ref="annualPaymentPlanRef" /> | |||||
</div> | |||||
</el-collapse-item> | |||||
<el-collapse-item v-if="formConfig.isCoreBusiness" name="5" class="mb-16"> | |||||
<template #title> | |||||
<div class="collapse-title">核心业务</div> | |||||
</template> | |||||
<div class="p-24"> | |||||
<core-business ref="coreBusinessRef" :basic-info-data="basicInfoRef?.formData" /> | |||||
</div> | |||||
</el-collapse-item> | |||||
<el-collapse-item v-if="formConfig.isSafetyInput" name="6" class="mb-16"> | |||||
<template #title> | |||||
<div class="collapse-title">安全投入</div> | |||||
</template> | |||||
<div class="p-24"> | |||||
<safety-input ref="safetyInputRef" /> | |||||
</div> | |||||
</el-collapse-item> | |||||
<el-collapse-item v-if="formConfig.isProjectImageProgress" name="7" class="mb-16"> | |||||
<template #title> | |||||
<div class="collapse-title">工程形象进度</div> | |||||
</template> | |||||
<div class="p-24"> | |||||
<projectImageProgress ref="projectImageProgressRef" /> | |||||
</div> | |||||
</el-collapse-item> | |||||
<el-collapse-item v-if="getIsShowReviewCheck()&&formConfig.isReviewChecklist&&($route.name==='declarePlan'||[10012,10013,10016].includes(detailData?.status))" name="8" class="mb-16"> | |||||
<template #title> | |||||
<div class="collapse-title">审查清单</div> | |||||
</template> | |||||
<div class="p-24"> | |||||
<review-check ref="reviewCheckRef" :detail-data="detailData" :data="detailData.reviewChecklist||formConfig.reviewChecklist" /> | |||||
</div> | |||||
</el-collapse-item> | |||||
<el-collapse-item name="8" class="mb-16"> | |||||
<template #title> | |||||
<div class="collapse-title">附件</div> | |||||
</template> | |||||
<div class="p-24"> | |||||
<accessory | |||||
ref="accessoryRef" | |||||
:detail-data="detailData" | |||||
:project-type="basicInfoRef?.formData?.projectType" | |||||
:declare-amount="fundsInfoRef?.formData.declareAmount" | |||||
/> | |||||
</div> | |||||
</el-collapse-item> | |||||
<el-collapse-item v-if="formConfig.isRemark" name="9" class="mb-16"> | |||||
<template #title> | |||||
<div class="collapse-title">备注</div> | |||||
</template> | |||||
<div class="p-24"> | |||||
<projectRemark ref="projectRemarkRef" /> | |||||
</div> | |||||
</el-collapse-item> | |||||
<template v-if="formConfig.safetyInputModular?.length"> | |||||
<el-collapse-item | |||||
v-for="(item,index) in formConfig.safetyInputModular" | |||||
:key="index" | |||||
:name="11+index+''" | |||||
class="mb-16" | |||||
> | |||||
<template #title> | |||||
<div class="collapse-title">{{ item.moduleName }}</div> | |||||
</template> | |||||
<div class="p-24"> | |||||
<newModuleForm :ref="el => {newModuleformRef[item.id] = el}" :data="item" /> | |||||
</div> | |||||
</el-collapse-item> | |||||
</template> | |||||
<el-collapse-item | |||||
v-if="($route.name==='declarePlan')||([10012,10016,10013].includes(detailData.status))" | |||||
name="4" | |||||
class="mb-16" | |||||
> | |||||
<template #title> | |||||
<div class="collapse-title">应用信息</div> | |||||
</template> | |||||
<div class="p-24"> | |||||
<applications ref="applicationsRef" :is-first="basicInfoRef?.formData?.isFirst" :core-business="coreBusinessRef?.formData?.coreBusiness" /> | |||||
</div> | |||||
</el-collapse-item> | |||||
</template> | |||||
</el-collapse> | |||||
</el-col> | |||||
</el-row> | |||||
<hidden-app-form | |||||
ref="hiddenAppFormRef" | |||||
:application-list="applicationsRef?.formData?.applicationList" | |||||
:is-first="basicInfoRef?.formData?.isFirst" | |||||
/> | |||||
<div class="footer"> | |||||
<el-button @click="router.go(-1)"> 返回 </el-button> | |||||
<el-button | |||||
v-if="route.name==='declarePage'&&(!route.query.id||(route.query.id&&route.query.isDraft))" | |||||
plain | |||||
type="primary" | |||||
:loading="saveLoading" | |||||
@click="toSaveDraft" | |||||
> 暂 存 </el-button> | |||||
<el-button type="primary" :loading="submitLoading" @click="submitAllForm"> 提交审核 </el-button> | |||||
</div> | |||||
</div> | |||||
<flow-record-dialog :visible="flowRecordDialogData.visible" :flow-data="flowRecordDialogData.flowData" @close="closeFlowRecordDialog" /> | |||||
</template> | |||||
<style lang="less" scoped> | |||||
.declarePage { | |||||
//position: relative; | |||||
.errorTip{ | |||||
background: #FFF0EF; | |||||
border-radius: 4px; | |||||
border: 1px solid #FF9E99; | |||||
padding: 18px 24px; | |||||
display: flex; | |||||
font-size: 14px; | |||||
color: rgba(0,0,0,0.85); | |||||
.icon{ | |||||
color:#FF3B30; | |||||
font-size: 24px; | |||||
margin-right: 8px; | |||||
} | |||||
.title{ | |||||
font-size: 20px; | |||||
font-weight: 500; | |||||
color: rgba(0,0,0,0.85); | |||||
line-height: 28px; | |||||
margin-bottom: 17px; | |||||
} | |||||
} | |||||
} | |||||
:deep(.el-collapse) { | |||||
.el-collapse-item__header { | |||||
padding: 0px 16px; | |||||
font-size: 14px; | |||||
} | |||||
.el-collapse-item__content { | |||||
padding: 16px 16px 16px 0px; | |||||
} | |||||
.el-collapse-item__header.is-active { | |||||
border-bottom: 1px solid rgba(0, 0, 0, 0.1); | |||||
} | |||||
.collapse-title { | |||||
flex: 1 0 90%; | |||||
order: 1; | |||||
.el-collapse-item__header { | |||||
flex: 1 0 auto; | |||||
order: -1; | |||||
} | |||||
.el-input-number { | |||||
width: 150px !important; | |||||
} | |||||
} | |||||
} | |||||
.btnClass { | |||||
:deep(.el-form-item__content) { | |||||
line-height: 24px; | |||||
} | |||||
} | |||||
.marginTop { | |||||
margin-top: 16px; | |||||
} | |||||
.delClass { | |||||
color: #e65151; | |||||
} | |||||
.btn { | |||||
display: flex; | |||||
align-items: center; | |||||
justify-content: center; | |||||
color: rgba(0, 100, 235, 1); | |||||
width: 100%; | |||||
padding: 2px 0px; | |||||
border-radius: 4px; | |||||
border: 1px solid rgba(0, 100, 235, 1); | |||||
cursor: pointer; | |||||
} | |||||
.bottomBtn { | |||||
width: calc(100% - 201px); | |||||
position: fixed; | |||||
z-index: 999; | |||||
right: 0px; | |||||
bottom: 0px; | |||||
background: #fff; | |||||
padding: 10px 0px; | |||||
border-top: 1px solid rgba(0, 0, 0, 0.1); | |||||
} | |||||
.applyBottomBtn { | |||||
width: 1000px; | |||||
position: fixed; | |||||
z-index: 999; | |||||
right: 0px; | |||||
bottom: 0px; | |||||
background: #fff; | |||||
padding: 10px 0px; | |||||
border-top: 1px solid rgba(0, 0, 0, 0.1); | |||||
} | |||||
.ocupation{ | |||||
height: 80px; | |||||
} | |||||
</style> |
@@ -0,0 +1,61 @@ | |||||
<script setup> | |||||
import { ref, onMounted } from 'vue' | |||||
import { useRoute } from 'vue-router' | |||||
import projectInfo from '../../../projectStoreManage/projectStore/projectDetail/components/projectInfo.vue' | |||||
import { getDraftDetail } from '@/http/apis/declareMange' | |||||
const route = useRoute(), | |||||
// 项目详情 | |||||
detailData = ref({ | |||||
projectName: '12', | |||||
status: 10002, | |||||
stage: 1 | |||||
}), | |||||
GetProjectDetail = async () => { | |||||
const detailRes = await getDraftDetail({ id: route.query.id }) | |||||
detailData.value = detailRes.data | |||||
} | |||||
onMounted(() => { | |||||
GetProjectDetail() | |||||
}) | |||||
</script> | |||||
<template> | |||||
<el-row> | |||||
<el-card class="w-full"> | |||||
<div class="card-header"> | |||||
<span class="font-bold">{{ detailData.projectName }}</span> | |||||
<div class="mt-8 search"> | |||||
<el-form label-suffix=":"> | |||||
<el-row :gutter="24"> | |||||
<el-col :span="6"> | |||||
<el-form-item label="申报单位">{{ detailData.buildOrgName||'-' }}</el-form-item> | |||||
</el-col> | |||||
<el-col :span="6"> | |||||
<el-form-item label="主管单位">{{ detailData.superOrg||'-' }}</el-form-item> | |||||
</el-col> | |||||
<el-col :span="6"> | |||||
<el-form-item label="创建时间">{{ detailData.beginTime||'-' }}</el-form-item> | |||||
</el-col> | |||||
<el-col :span="6"> | |||||
<el-form-item label="更新时间">{{ detailData.updatedAt||'-' }}</el-form-item> | |||||
</el-col> | |||||
</el-row> | |||||
</el-form> | |||||
</div> | |||||
</div> | |||||
</el-card> | |||||
<el-card class="mt-10 w-full"> | |||||
<project-info :detail-data="detailData" /> | |||||
</el-card> | |||||
</el-row> | |||||
</template> | |||||
<style lang='less' scoped> | |||||
.textSize{ | |||||
font-size: 13px; | |||||
margin-top: 10px; | |||||
} | |||||
.myCardTab{ | |||||
:deep(.el-tabs__header){ | |||||
margin: 0; | |||||
} | |||||
} | |||||
</style> |
@@ -0,0 +1,427 @@ | |||||
<script setup name = 'projectDeclare'> | |||||
import { ref, reactive, h, onMounted, getCurrentInstance } from 'vue' | |||||
import { useRouter } from 'vue-router' | |||||
import { getProjectList, draftList, declareExport, removeProject } from '@/http/apis/declareMange' | |||||
import store from '@/store' | |||||
import useExportExc from '@/utils/useExportExc' | |||||
const { | |||||
statusOptionsCascader, statusOptions, | |||||
projectConTypeOptions | |||||
} = store.dictStore.globalDicts || {}, | |||||
{ proxy } = getCurrentInstance(), | |||||
// 搜索栏表单数据 | |||||
searchForm = reactive({ | |||||
stage: undefined, | |||||
status: undefined, | |||||
projectName: '', | |||||
projectType: undefined, | |||||
projectYear: undefined, | |||||
createTiming_: undefined | |||||
}), | |||||
// 获取项目列表 | |||||
getTableData = async (pageParams = tableListRef.value.pageParams) => { | |||||
const params = { | |||||
...pageParams, | |||||
...searchForm, | |||||
createOnMin: searchForm.createTiming_?.length && searchForm.createTiming_[0], | |||||
createOnMax: searchForm.createTiming_?.length && searchForm.createTiming_[1], | |||||
projectYear: searchForm.projectYear * 1 || undefined, | |||||
createTiming_: undefined, | |||||
status: searchForm.status?.[searchForm.status.length - 1] | |||||
} | |||||
const res = tabStatus.value ? await getProjectList(params) : await draftList(params) | |||||
projectData.value = res.data.records | |||||
total.value = res.data.total | |||||
}, | |||||
activeName = ref('已申报'), | |||||
// 切换栏 | |||||
handleClick = (tab, event) => { | |||||
switch (tab.props.name) { | |||||
case '已申报': | |||||
tabStatus.value = true | |||||
formReset() | |||||
break | |||||
case '草稿箱': | |||||
tabStatus.value = false | |||||
formReset() | |||||
break | |||||
default: | |||||
break | |||||
} | |||||
}, | |||||
tabStatus = ref(true), | |||||
column = reactive([ | |||||
{ | |||||
label: '序号', | |||||
type: 'index', | |||||
width: '80' | |||||
}, | |||||
{ | |||||
label: '项目名称', | |||||
key: 'projectName', | |||||
prop: 'projectName', | |||||
minWidth: '250', | |||||
showOverflowTooltip: true | |||||
}, | |||||
{ | |||||
label: '项目类型', | |||||
key: 'projectTypeName', | |||||
prop: 'projectTypeName', | |||||
width: '100' | |||||
}, | |||||
{ | |||||
label: '申报金额(万元)', | |||||
key: 'declaredAmount', | |||||
prop: 'declaredAmount', | |||||
width: '120' | |||||
}, | |||||
{ | |||||
label: '预算年度', | |||||
key: 'projectYear', | |||||
prop: 'projectYear', | |||||
width: '100' | |||||
}, | |||||
{ | |||||
label: '创建时间', | |||||
key: 'createOn', | |||||
prop: 'createOn', | |||||
showOverflowTooltip: true, | |||||
width: '180' | |||||
}, | |||||
{ | |||||
label: '项目状态', | |||||
key: 'status', | |||||
prop: 'status', | |||||
width: '220', | |||||
render: row => [ | |||||
h('span', { | |||||
class: ['dot mr-4', `bg-${row.status && statusOptions[row.status]?.color}`] | |||||
}), | |||||
h( | |||||
'span', | |||||
{ | |||||
class: `text-${row.status && statusOptions[row.status]?.color}` | |||||
}, | |||||
row.status && statusOptions[row.stage]?.name + '-' + statusOptions[row.status]?.name | |||||
) | |||||
] | |||||
}, | |||||
{ | |||||
label: '操作', | |||||
slot: 'action', | |||||
width: '200', | |||||
fixed: 'right' | |||||
} | |||||
]), | |||||
column2 = reactive([ | |||||
{ | |||||
label: '序号', | |||||
type: 'index', | |||||
width: '80' | |||||
}, | |||||
{ | |||||
label: '项目名称', | |||||
key: 'projectName', | |||||
prop: 'projectName', | |||||
minWidth: '250', | |||||
showOverflowTooltip: true | |||||
}, | |||||
{ | |||||
label: '项目类型', | |||||
key: 'projectTypeName', | |||||
prop: 'projectTypeName', | |||||
width: '100' | |||||
}, | |||||
{ | |||||
label: '申报金额(万元)', | |||||
key: 'declareAmount', | |||||
prop: 'declareAmount', | |||||
width: '120' | |||||
}, | |||||
{ | |||||
label: '预算年度', | |||||
key: 'projectYear', | |||||
prop: 'projectYear', | |||||
width: '80' | |||||
}, | |||||
{ | |||||
label: '创建时间', | |||||
key: 'createOn', | |||||
prop: 'createOn', | |||||
showOverflowTooltip: true, | |||||
width: '180' | |||||
}, | |||||
{ | |||||
label: '操作', | |||||
slot: 'action', | |||||
width: '160', | |||||
fixed: 'right' | |||||
} | |||||
]), | |||||
projectData = ref([]), | |||||
// 数据总数 | |||||
total = ref(1), | |||||
editProject = (row) => { | |||||
$router.push({ name: 'declarePage', query: { id: row.id, isDraft: 1 }}) | |||||
}, | |||||
checkDetail = (detailData) => { | |||||
if (tabStatus.value) { | |||||
$router.push({ name: 'projectDeclareDetail', query: { id: detailData.id }}) | |||||
} else { | |||||
$router.push({ name: 'draftDetails', query: { id: detailData.id }}) | |||||
} | |||||
}, | |||||
reDeclare = (row) => { | |||||
if (row.status === 20005) { | |||||
$router.push({ name: 'reDeclarationFinal', query: { id: row.id }}) | |||||
} else { | |||||
$router.push({ name: 'declarePage', query: { id: row.id }}) | |||||
} | |||||
}, | |||||
// 提交查询 | |||||
onSearch = () => { | |||||
getTableData() | |||||
}, | |||||
formReset = () => { | |||||
searchForm.status = undefined | |||||
searchForm.projectName = undefined | |||||
searchForm.createTiming_ = undefined | |||||
searchForm.projectType = undefined | |||||
searchForm.projectYear = undefined | |||||
tableListRef.value.pageParams.pageNumber = 1 | |||||
tableListRef.value.pageParams.pageSize = 10 | |||||
getTableData() | |||||
}, | |||||
$router = useRouter(), | |||||
// 去项目申报页 | |||||
toDeclarePage = () => { | |||||
$router.push({ name: 'declarePage' }) | |||||
}, | |||||
tableListRef = ref(), | |||||
// 导出excel文件 | |||||
{ exportLoading, exportData } = useExportExc(), | |||||
handleExcel = () => { | |||||
exportData(() => declareExport(1, { | |||||
...searchForm, | |||||
createOnMin: searchForm.createTiming_?.length && searchForm.createTiming_[0], | |||||
createOnMax: searchForm.createTiming_?.length && searchForm.createTiming_[1], | |||||
projectYear: searchForm.projectYear * 1 || undefined, | |||||
status: searchForm.status?.[searchForm.status.length - 1] | |||||
})) | |||||
}, | |||||
dictionaryList = ref([]), | |||||
// 删除项目 | |||||
remove = (data) => { | |||||
proxy.$messageBox | |||||
.confirm(`确定要删除${data.projectName}吗?`, '提示!', { | |||||
type: 'warning' | |||||
}) | |||||
.then(async () => { | |||||
await removeProject(data.projectCode) | |||||
proxy.$message.success('删除成功') | |||||
getTableData() | |||||
}) | |||||
} | |||||
onMounted(async () => { | |||||
tabStatus.value = ref(true) | |||||
getTableData() | |||||
}) | |||||
</script> | |||||
<template> | |||||
<el-row> | |||||
<el-card class="w-full search"> | |||||
<!-- 已申报 --> | |||||
<el-form | |||||
v-show="tabStatus" | |||||
size="small" | |||||
:model="searchForm" | |||||
label-suffix=":" | |||||
> | |||||
<el-row :gutter="16" class="mb-16"> | |||||
<el-col :span="8"> | |||||
<el-form-item label="项目名称" class="w-full"> | |||||
<el-input | |||||
v-model="searchForm.projectName" | |||||
maxlength="50" | |||||
placeholder="请输入" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<el-form-item label="项目类型"> | |||||
<el-select | |||||
v-model="searchForm.projectType" | |||||
placeholder="全部" | |||||
class="w-full" | |||||
> | |||||
<el-option | |||||
v-for="(v,k) in projectConTypeOptions" | |||||
:key="k" | |||||
:label="v" | |||||
:value="k" | |||||
/> | |||||
</el-select> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<el-form-item v-show="tabStatus" label="项目状态"> | |||||
<el-cascader | |||||
v-model="searchForm.status" | |||||
class="w-full" | |||||
:props="{label:'name',value:'code'}" | |||||
:options="statusOptionsCascader" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
</el-row> | |||||
<el-row :gutter="16"> | |||||
<el-col :span="8"> | |||||
<el-form-item label="预算年度"> | |||||
<el-date-picker | |||||
v-model="searchForm.projectYear" | |||||
class="w-full" | |||||
type="year" | |||||
format="YYYY" | |||||
value-format="YYYY" | |||||
placeholder="请选择" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="12"> | |||||
<el-form-item label="创建时间" class="w-full"> | |||||
<el-date-picker | |||||
v-model="searchForm.createTiming_" | |||||
type="datetimerange" | |||||
range-separator="-" | |||||
start-placeholder="开始时间" | |||||
end-placeholder="结束时间" | |||||
format="YYYY-MM-DD HH:mm" | |||||
value-format="YYYY-MM-DD HH:mm" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="4"> | |||||
<el-form-item class="btn"> | |||||
<div class="flex"> | |||||
<el-button type="primary" @click="onSearch">查询</el-button> | |||||
<el-button @click="formReset">重置</el-button> | |||||
</div> | |||||
</el-form-item> | |||||
</el-col> | |||||
</el-row> | |||||
</el-form> | |||||
<!-- 草稿箱 --> | |||||
<el-form | |||||
v-show="!tabStatus" | |||||
label-suffix=":" | |||||
:model="searchForm" | |||||
size="small" | |||||
> | |||||
<el-row :gutter="16" class="mb-16"> | |||||
<el-col :span="8"> | |||||
<el-form-item label="项目名称" class="w-full"> | |||||
<el-input | |||||
v-model="searchForm.projectName" | |||||
placeholder="请输入" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<el-form-item label="项目类型"> | |||||
<el-select | |||||
v-model="searchForm.projectType" | |||||
placeholder="全部" | |||||
class="w-full" | |||||
> | |||||
<el-option | |||||
v-for="(item,index) in dictionaryList?.filter(i => i.type === 'PROJECT_TYPE')" | |||||
:key="index" | |||||
:label="item.label" | |||||
:value="item.value" | |||||
/> | |||||
</el-select> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<el-form-item label="预算年度"> | |||||
<el-date-picker | |||||
v-model="searchForm.projectYear" | |||||
class="w-full" | |||||
type="year" | |||||
value-format="YYYY" | |||||
placeholder="请选择" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
</el-row> | |||||
<el-row :gutter="16"> | |||||
<el-col :span="10"> | |||||
<el-form-item label="创建时间"> | |||||
<el-date-picker | |||||
v-model="searchForm.createTiming_" | |||||
type="datetimerange" | |||||
range-separator="-" | |||||
start-placeholder="开始时间" | |||||
end-placeholder="结束时间" | |||||
format="YYYY-MM-DD HH:mm" | |||||
value-format="YYYY-MM-DD HH:mm" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="14"> | |||||
<el-form-item class="btn"> | |||||
<div class="flex"> | |||||
<el-button type="primary" @click="onSearch">查询</el-button> | |||||
<el-button @click="formReset">重置</el-button> | |||||
</div> | |||||
</el-form-item> | |||||
</el-col> | |||||
</el-row> | |||||
</el-form> | |||||
</el-card> | |||||
<el-card class="w-full mt-8 tab-card"> | |||||
<template #header> | |||||
<div class="flex justify-between items-center"> | |||||
<el-tabs v-model="activeName" @tab-click="handleClick"> | |||||
<el-tab-pane label="已申报" name="已申报" /> | |||||
<el-tab-pane label="草稿箱" name="草稿箱" /> | |||||
</el-tabs> | |||||
<div> | |||||
<el-button | |||||
v-show="tabStatus" | |||||
type="primary" | |||||
size="small" | |||||
plain | |||||
:loading="exportLoading" | |||||
@click="handleExcel" | |||||
>导出</el-button> | |||||
<el-button | |||||
type="primary" | |||||
size="small" | |||||
icon="plus" | |||||
@click="toDeclarePage" | |||||
>项目申报</el-button> | |||||
</div> | |||||
</div> | |||||
</template> | |||||
<table-list | |||||
ref="tableListRef" | |||||
:column="tabStatus ? column : column2" | |||||
:data="projectData" | |||||
:total="total" | |||||
@get-table-data="getTableData" | |||||
> | |||||
<template #action="{ scope }"> | |||||
<a @click="checkDetail(scope.row)">详情</a> | |||||
<a v-if="!tabStatus" @click="editProject(scope.row)">编辑</a> | |||||
<a v-if="tabStatus && [10002,10005,10007,10013,20005].includes(scope.row.status)" @click="reDeclare(scope.row)">重新申报</a> | |||||
<a v-if="tabStatus && [10007].includes(scope.row.status)" @click="remove(scope.row)">删除</a> | |||||
</template> | |||||
</table-list> | |||||
</el-card> | |||||
</el-row> | |||||
</template> | |||||
<style lang='less' scoped> | |||||
</style> | |||||
@@ -0,0 +1,154 @@ | |||||
<script name="implementPlanDialog" setup> | |||||
import { getCurrentInstance, nextTick, ref, watch } from 'vue' | |||||
import { operationDetail, pushOperation } from '@/http/apis/declareMange/purchaseResults' | |||||
import { projectDetail } from '@/http/apis/projectStoreManage/projectStore' | |||||
const { proxy } = getCurrentInstance(), | |||||
props = defineProps({ | |||||
visible: { | |||||
type: Boolean, | |||||
default: false | |||||
}, | |||||
data: { | |||||
type: Object, | |||||
default: () => {} | |||||
} | |||||
}), | |||||
emits = defineEmits(['close']), | |||||
formData = ref({}), | |||||
formRef = ref(), | |||||
validatorTime1 = (rule, value, callback) => { | |||||
if (new Date(value).getTime() >= new Date(formData.value.finalInspectionDate).getTime()) { | |||||
return callback(new Error('项目开工时间必须在项目终验时间之前')) | |||||
} else if (new Date(value).getTime() >= new Date(formData.value.initialInspectionDate).getTime()) { | |||||
return callback(new Error('项目开工时间必须在项目初验时间之前')) | |||||
} else if (new Date(value).getTime() >= new Date(formData.value.startTrialOperationDate).getTime()) { | |||||
return callback(new Error('项目开工时间必须在项目试运行开始时间之前')) | |||||
} else { | |||||
return callback() | |||||
} | |||||
}, | |||||
validatorTime2 = (rule, value, callback) => { | |||||
if (new Date(value).getTime() <= new Date(formData.value.projectStartDate).getTime()) { | |||||
return callback(new Error('项目初验时间必须在项目开工时间之后')) | |||||
} else if (new Date(value).getTime() >= new Date(formData.value.startTrialOperationDate).getTime()) { | |||||
return callback(new Error('项目初验时间必须在项目试运行开始时间之前')) | |||||
} else if (new Date(value).getTime() >= new Date(formData.value.finalInspectionDate).getTime()) { | |||||
return callback(new Error('项目初验时间必须在项目终验时间之前')) | |||||
} else { | |||||
return callback() | |||||
} | |||||
}, | |||||
validatorTime3 = (rule, value, callback) => { | |||||
if (new Date(value).getTime() <= new Date(formData.value.projectStartDate).getTime()) { | |||||
return callback(new Error('项目试运行开始时间必须在项目开工时间之后')) | |||||
} else if (new Date(value).getTime() <= new Date(formData.value.initialInspectionDate).getTime()) { | |||||
return callback(new Error('项目试运行开始时间必须在项目初验时间之后')) | |||||
} else if (new Date(value).getTime() >= new Date(formData.value.finalInspectionDate).getTime()) { | |||||
return callback(new Error('项目初验时间必须在项目终验时间之前')) | |||||
} else { | |||||
return callback() | |||||
} | |||||
}, | |||||
rules = { | |||||
projectStartDate: [{ required: true, message: '请输入' }, { validator: validatorTime1 }], | |||||
initialInspectionDate: [{ required: true, message: '请选择' }, { validator: validatorTime2 }], | |||||
startTrialOperationDate: [{ required: true, message: '请选择' }, { validator: validatorTime3 }], | |||||
finalInspectionDate: [{ required: true, message: '请选择' }] | |||||
}, | |||||
loading = ref(false), | |||||
submit = async (formEl) => { | |||||
if (!formEl) return | |||||
await formEl.validate(async valid => { | |||||
if (valid) { | |||||
loading.value = true | |||||
try { | |||||
const postData = { | |||||
...formData.value, | |||||
projectId: props.data.id | |||||
} | |||||
await pushOperation(postData) | |||||
proxy.$message.success('提交成功!') | |||||
loading.value = false | |||||
emits('close', true) | |||||
} catch (e) { | |||||
loading.value = false | |||||
} | |||||
} | |||||
}) | |||||
} | |||||
watch( | |||||
() => props.visible, | |||||
async val => { | |||||
if (val) { | |||||
await nextTick() | |||||
formRef.value.clearValidate() | |||||
const detail = await projectDetail(props.data.id) | |||||
const res = await operationDetail(props.data.id) | |||||
formData.value = res?.data ? { | |||||
...res.data, | |||||
finalInspectionDate: detail.data.planAcceptanceTime | |||||
} : { | |||||
finalInspectionDate: detail.data.planAcceptanceTime | |||||
} | |||||
} | |||||
} | |||||
) | |||||
defineExpose({ formRef }) | |||||
</script> | |||||
<template> | |||||
<el-dialog :model-value="visible" title="填写实施计划" @close="emits('close')"> | |||||
<el-form | |||||
ref="formRef" | |||||
:model="formData" | |||||
:rules="rules" | |||||
label-suffix=":" | |||||
label-width="140" | |||||
> | |||||
<el-form-item label="项目开工时间" prop="projectStartDate"> | |||||
<el-date-picker | |||||
v-model="formData.projectStartDate" | |||||
type="date" | |||||
format="YYYY-MM-DD" | |||||
value-format="YYYY-MM-DD HH:mm:ss" | |||||
placeholder="请选择" | |||||
/> | |||||
</el-form-item> | |||||
<el-form-item label="项目初验时间" prop="initialInspectionDate"> | |||||
<el-date-picker | |||||
v-model="formData.initialInspectionDate" | |||||
type="date" | |||||
format="YYYY-MM-DD" | |||||
value-format="YYYY-MM-DD HH:mm:ss" | |||||
placeholder="请选择" | |||||
/> | |||||
</el-form-item> | |||||
<el-form-item label="试运行开始时间" prop="startTrialOperationDate"> | |||||
<el-date-picker | |||||
v-model="formData.startTrialOperationDate" | |||||
type="date" | |||||
format="YYYY-MM-DD" | |||||
value-format="YYYY-MM-DD HH:mm:ss" | |||||
placeholder="请选择" | |||||
/> | |||||
</el-form-item> | |||||
<el-form-item label="项目终验时间" prop="finalInspectionDate"> | |||||
<el-date-picker | |||||
v-model="formData.finalInspectionDate" | |||||
type="date" | |||||
format="YYYY-MM-DD" | |||||
value-format="YYYY-MM-DD HH:mm:ss" | |||||
placeholder="请选择" | |||||
disabled | |||||
/> | |||||
</el-form-item> | |||||
</el-form> | |||||
<template #footer> | |||||
<span class="dialog-footer"> | |||||
<el-button type="primary" :loading="loading" @click="submit(formRef)">提交</el-button> | |||||
<el-button @click="emits('close')">关闭</el-button> | |||||
</span> | |||||
</template> | |||||
</el-dialog> | |||||
</template> |
@@ -0,0 +1,355 @@ | |||||
<script setup name="fillPurchasingResult"> | |||||
import { getCurrentInstance, onMounted, ref } from 'vue' | |||||
import { changFilesParam, fileFormatVerification, handleFileSuccess, handleFilePreview, fileTypes, fileDesc } from '@/utils/uploadAction.js' | |||||
import store from '@/store' | |||||
import { useRouter, useRoute } from 'vue-router' | |||||
import { submitResult } from '@/http/apis/declareMange/purchaseResults' | |||||
import { dictionary } from '@/http/apis/projectCollection/projectCollectionEnter' | |||||
const uploadUrl = store.dictStore.uploadUrl, | |||||
{ proxy } = getCurrentInstance(), | |||||
router = useRouter(), | |||||
route = useRoute() | |||||
const formRef = ref(), | |||||
// 手机号码校验 | |||||
checkTelPhone = (rule, value, callback) => { | |||||
if (value === '') { | |||||
return callback(new Error('请输入正确的手机号')) | |||||
} else { | |||||
const regIdCard = | |||||
/^(13[0-9]|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18[0-9]|19[0-35-9])\d{8}$/ | |||||
if (regIdCard.test(value)) { | |||||
callback() | |||||
} else { | |||||
return callback(new Error('请输入正确的手机号')) | |||||
} | |||||
} | |||||
}, | |||||
rules = { | |||||
bidName: [{ required: true, message: '请输入标段名称' }], | |||||
supplier: [{ required: true, message: '请输入供应商' }], | |||||
supplierContact: [{ required: true, message: '请输入供应商联系人' }], | |||||
supplierContactInfo: [ | |||||
{ required: true, message: '请输入供应商联系方式' }, | |||||
{ validator: checkTelPhone, trigger: 'blur' } | |||||
], | |||||
purchaseMethod: [{ required: true, message: '请选择采购方式' }], | |||||
transactionAmount: [{ required: true, message: '请输入成交金额' }], | |||||
transactionTime: [{ required: true, message: '请选择成交时间' }], | |||||
biddingDoc: [{ required: true, message: '请上传投标文件' }], | |||||
bidDoc: [{ required: true, message: '请上传招标文件' }], | |||||
acceptanceLetter: [{ required: true, message: '请上传中标通知书' }] | |||||
}, | |||||
formData = ref({ | |||||
sections: [{ | |||||
biddingDoc: [], | |||||
bidDoc: [], | |||||
acceptanceLetter: [] | |||||
}] | |||||
}), | |||||
submitLoading = ref(false), | |||||
submit = async (formEl) => { | |||||
if (!formEl) { | |||||
return | |||||
} | |||||
formEl.validate(async (valid) => { | |||||
if (valid) { | |||||
submitLoading.value = true | |||||
const postData = { | |||||
projectId: route.query.id, | |||||
tenders: formData.value.sections.map(i => { | |||||
return { | |||||
...i, | |||||
biddingDoc: i.biddingDoc && JSON.stringify(changFilesParam(i.biddingDoc)), | |||||
bidDoc: i.bidDoc && JSON.stringify(changFilesParam(i.bidDoc)), | |||||
acceptanceLetter: i.acceptanceLetter && JSON.stringify(changFilesParam(i.acceptanceLetter)) | |||||
} | |||||
}) | |||||
} | |||||
try { | |||||
await submitResult(postData) | |||||
submitLoading.value = false | |||||
proxy.$message.success('提交成功') | |||||
router.go(-1) | |||||
} catch (e) { | |||||
submitLoading.value = false | |||||
} | |||||
} | |||||
}) | |||||
}, | |||||
// 添加标段 | |||||
add = () => { | |||||
if (formData.value.sections?.length >= 10) { | |||||
proxy.$message.warning('最多添加10个标段') | |||||
return | |||||
} | |||||
formData.value.sections.push({ | |||||
biddingDoc: [], | |||||
bidDoc: [], | |||||
acceptanceLetter: [] | |||||
}) | |||||
}, | |||||
// 删除标段 | |||||
del = (index) => { | |||||
formData.value.sections.splice(index, 1) | |||||
}, | |||||
dictionaryList = ref([]) | |||||
onMounted(async () => { | |||||
dictionaryList.value = (await dictionary()).data | |||||
}) | |||||
</script> | |||||
<template> | |||||
<div class="fillPurchasingResult footerPage"> | |||||
<el-form | |||||
ref="formRef" | |||||
:model="formData" | |||||
:rules="rules" | |||||
label-position="right" | |||||
label-width="180px" | |||||
label-suffix=":" | |||||
scroll-to-error | |||||
> | |||||
<el-card v-for="(item,index) in formData.sections" :key="index" class="w-full mb-16"> | |||||
<template #header> | |||||
<div class="flex justify-between"> | |||||
<span>标段{{ index+1 }}</span> | |||||
<el-button | |||||
v-if="formData.sections?.length>1" | |||||
link | |||||
type="danger" | |||||
@click="del(index)" | |||||
>删除</el-button> | |||||
</div> | |||||
</template> | |||||
<el-row :gutter="40"> | |||||
<el-col :span="12"> | |||||
<el-form-item label="标段名称" :prop="`sections[${index}].bidName`" :rules="[{ required: true, message: '请输入' }]"> | |||||
<el-input v-model="formData.sections[index].bidName" maxlength="50" placeholder="请输入" /> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="12"> | |||||
<el-form-item label="供应商" :prop="`sections[${index}].supplier`" :rules="[{ required: true, message: '请输入' }]"> | |||||
<el-input v-model="formData.sections[index].supplier" maxlength="50" placeholder="请输入" /> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="12"> | |||||
<el-form-item label="供应商统一社会信用代码" :prop="`sections[${index}].supplierSocialCreditCode`" :rules="[{ required: true, message: '请输入' }]"> | |||||
<el-input v-model="formData.sections[index].supplierSocialCreditCode" placeholder="请输入" /> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="12"> | |||||
<el-form-item label="供应商联系人" :prop="`sections[${index}].supplierContact`" :rules="[{ required: true, message: '请输入' }]"> | |||||
<el-input v-model="formData.sections[index].supplierContact" maxlength="50" placeholder="请输入" /> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="12"> | |||||
<el-form-item label="供应商联系方式" :prop="`sections[${index}].supplierContactInfo`" :rules="[{ required: true, message: '请输入' }]"> | |||||
<el-input v-model="formData.sections[index].supplierContactInfo" maxlength="11" placeholder="请输入" /> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="24"> | |||||
<el-form-item label="采购方式" :prop="`sections[${index}].purchaseMethod`" :rules="[{ required: true, message: '请选择' }]"> | |||||
<el-radio-group v-model="formData.sections[index].purchaseMethod"> | |||||
<el-radio | |||||
v-for="(row,key) in dictionaryList?.filter(i => i.type === 'PURCHASE_METHOD')" | |||||
:key="key" | |||||
:label="row.value" | |||||
>{{ row.label }}</el-radio> | |||||
</el-radio-group> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="12"> | |||||
<el-form-item label="成交金额" :prop="`sections[${index}].transactionAmount`" :rules="[{ required: true, message: '请输入' }]"> | |||||
<el-input-number | |||||
v-model="formData.sections[index].transactionAmount" | |||||
placeholder="请填写" | |||||
:min="0" | |||||
:controls="false" | |||||
@mousewheel.prevent | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="12"> | |||||
<el-form-item | |||||
label="成交时间" | |||||
:prop="`sections[${index}].transactionTime`" | |||||
:rules="[{ required: true, message: '请选择' }]" | |||||
> | |||||
<el-date-picker | |||||
v-model="formData.sections[index].transactionTime" | |||||
type="date" | |||||
format="YYYY-MM-DD" | |||||
value-format="YYYY-MM-DD" | |||||
placeholder="请选择" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
</el-row> | |||||
<el-row :gutter="40"> | |||||
<el-col :span="12"> | |||||
<el-form-item v-if="['00','05'].includes(formData.sections[index].purchaseMethod)" label="采购代理机构"> | |||||
<el-input v-model="formData.sections[index].agency" maxlength="50" placeholder="请输入" /> | |||||
</el-form-item> | |||||
<el-form-item | |||||
v-else | |||||
label="采购代理机构" | |||||
:prop="`sections[${index}].agency`" | |||||
:rules="[{ required: true, message: '请输入' }]" | |||||
> | |||||
<el-input v-model="formData.sections[index].agency" maxlength="50" placeholder="请输入" /> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="12"> | |||||
<el-form-item v-if="['00','05'].includes(formData.sections[index].purchaseMethod)" label="采购代理机构统一社会信用代码"> | |||||
<el-input v-model="formData.sections[index].purchaseSocialCreditCode" placeholder="请输入" /> | |||||
</el-form-item> | |||||
<el-form-item | |||||
v-else | |||||
label="采购代理机构统一社会信用代码" | |||||
:prop="`sections[${index}].purchaseSocialCreditCode`" | |||||
:rules="[{ required: true, message: '请输入' }]" | |||||
> | |||||
<el-input v-model="formData.sections[index].purchaseSocialCreditCode" placeholder="请输入" /> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="12"> | |||||
<el-form-item label="预算执行确认书编号"> | |||||
<el-input v-model="formData.sections[index].budgetExecConfirmNo" placeholder="请输入" /> | |||||
</el-form-item> | |||||
</el-col> | |||||
</el-row> | |||||
<el-row> | |||||
<el-col :span="12"> | |||||
<el-form-item | |||||
label="投标文件" | |||||
:prop="`sections[${index}].biddingDoc`" | |||||
:rules="[{ required: true, message: '请上传' }]" | |||||
> | |||||
<el-upload | |||||
v-model:file-list="formData.sections[index].biddingDoc" | |||||
class="w-full" | |||||
:action="uploadUrl" | |||||
:on-success="res => handleFileSuccess(res, formData.sections[index].biddingDoc)" | |||||
:before-upload="file=>fileFormatVerification(file, {types: fileTypes})" | |||||
:accept="fileTypes.map(i=>`.${i}`).join(',')" | |||||
:on-preview="handleFilePreview" | |||||
> | |||||
<el-button type="primary" plain>选择文件</el-button> | |||||
<template #tip> | |||||
<div class="el-upload__tip"> | |||||
支持{{ fileDesc }}文件 | |||||
</div> | |||||
</template> | |||||
</el-upload> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="12"> | |||||
<el-form-item | |||||
v-if="formData.sections[index].purchaseMethod!=='00'" | |||||
label="招标文件" | |||||
:prop="`sections[${index}].bidDoc`" | |||||
:rules="[{ required: true, message: '请上传' }]" | |||||
> | |||||
<el-upload | |||||
v-model:file-list="formData.sections[index].bidDoc" | |||||
class="w-full" | |||||
:action="uploadUrl" | |||||
:on-success="res => handleFileSuccess(res, formData.sections[index].bidDoc)" | |||||
:before-upload="file=>fileFormatVerification(file, {types: fileTypes})" | |||||
:accept="fileTypes.map(i=>`.${i}`).join(',')" | |||||
:on-preview="handleFilePreview" | |||||
> | |||||
<el-button type="primary" plain>选择文件</el-button> | |||||
<template #tip> | |||||
<div class="el-upload__tip"> | |||||
支持{{ fileDesc }}文件 | |||||
</div> | |||||
</template> | |||||
</el-upload> | |||||
</el-form-item> | |||||
<el-form-item | |||||
v-else | |||||
label="招标文件" | |||||
> | |||||
<el-upload | |||||
v-model:file-list="formData.sections[index].bidDoc" | |||||
class="w-full" | |||||
:action="uploadUrl" | |||||
:on-success="res => handleFileSuccess(res, formData.sections[index].bidDoc)" | |||||
:before-upload="file=>fileFormatVerification(file, {types: fileTypes})" | |||||
:accept="fileTypes.map(i=>`.${i}`).join(',')" | |||||
:on-preview="handleFilePreview" | |||||
> | |||||
<el-button type="primary" plain>选择文件</el-button> | |||||
<template #tip> | |||||
<div class="el-upload__tip"> | |||||
支持{{ fileDesc }}文件 | |||||
</div> | |||||
</template> | |||||
</el-upload> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="12"> | |||||
<el-form-item | |||||
v-if="!['00','05'].includes(formData.sections[index].purchaseMethod)" | |||||
label="中标通知书" | |||||
:prop="`sections[${index}].acceptanceLetter`" | |||||
:rules="[{ required: true, message: '请上传' }]" | |||||
> | |||||
<el-upload | |||||
v-model:file-list="formData.sections[index].acceptanceLetter" | |||||
class="w-full" | |||||
:action="uploadUrl" | |||||
:on-success="res => handleFileSuccess(res, formData.sections[index].acceptanceLetter)" | |||||
:before-upload="file=>fileFormatVerification(file, {types: fileTypes})" | |||||
:accept="fileTypes.map(i=>`.${i}`).join(',')" | |||||
:on-preview="handleFilePreview" | |||||
> | |||||
<el-button type="primary" plain>选择文件</el-button> | |||||
<template #tip> | |||||
<div class="el-upload__tip"> | |||||
支持{{ fileDesc }}文件 | |||||
</div> | |||||
</template> | |||||
</el-upload> | |||||
</el-form-item> | |||||
<el-form-item | |||||
v-else | |||||
label="中标通知书" | |||||
> | |||||
<el-upload | |||||
v-model:file-list="formData.sections[index].acceptanceLetter" | |||||
class="w-full" | |||||
:action="uploadUrl" | |||||
:on-success="res => handleFileSuccess(res, formData.sections[index].acceptanceLetter)" | |||||
:before-upload="file=>fileFormatVerification(file, {types: fileTypes})" | |||||
:accept="fileTypes.map(i=>`.${i}`).join(',')" | |||||
:on-preview="handleFilePreview" | |||||
> | |||||
<el-button type="primary" plain>选择文件</el-button> | |||||
<template #tip> | |||||
<div class="el-upload__tip"> | |||||
支持{{ fileDesc }}文件 | |||||
</div> | |||||
</template> | |||||
</el-upload> | |||||
</el-form-item> | |||||
</el-col> | |||||
</el-row> | |||||
</el-card> | |||||
<p> | |||||
<el-button | |||||
type="primary" | |||||
plain | |||||
icon="Plus" | |||||
class="w-full" | |||||
@click="add" | |||||
>添加标段</el-button> | |||||
</p> | |||||
</el-form> | |||||
<div class="footer"> | |||||
<el-button @click="router.go(-1)"> 返回 </el-button> | |||||
<el-button type="primary" :loading="submitLoading" @click="submit(formRef)"> 提交 </el-button> | |||||
</div> | |||||
</div> | |||||
</template> |
@@ -0,0 +1,252 @@ | |||||
<script setup name="purchaseResults"> | |||||
import { ref, reactive, onMounted, h } from 'vue' | |||||
import { declareExport } from '@/http/apis/declareMange' | |||||
import { useRouter } from 'vue-router' | |||||
import useExportExc from '@/utils/useExportExc' | |||||
import { purchaseList } from '@/http/apis/declareMange/purchaseResults' | |||||
import ImplementPlanDialog from '@/pages/declareManage/purchaseResults/components/implementPlanDialog.vue' | |||||
import store from '@/store' | |||||
const router = useRouter(), | |||||
{ | |||||
statusOptions, | |||||
projectTypeOptions | |||||
} = store.dictStore.globalDicts || {} | |||||
// 搜索栏表单数据 | |||||
const searchForm = reactive({ | |||||
projectType: undefined, | |||||
status: undefined, | |||||
projectYear: undefined, | |||||
projectName: undefined, | |||||
createOnMin: undefined, | |||||
createOnMax: undefined, | |||||
times: [] | |||||
}), | |||||
column = reactive([ | |||||
{ | |||||
label: '序号', | |||||
type: 'index', | |||||
width: '80' | |||||
}, | |||||
{ | |||||
label: '项目名称', | |||||
key: 'projectName', | |||||
prop: 'projectName', | |||||
minWidth: '200', | |||||
showOverflowTooltip: true | |||||
}, | |||||
{ | |||||
label: '项目类型', | |||||
key: 'projectTypeName', | |||||
prop: 'projectTypeName', | |||||
width: '80' | |||||
}, | |||||
{ | |||||
label: '批复金额(万元)', | |||||
key: 'approvedAmount', | |||||
prop: 'approvedAmount', | |||||
width: '150' | |||||
}, | |||||
{ | |||||
label: '预算年度', | |||||
key: 'projectYear', | |||||
prop: 'projectYear', | |||||
width: 80 | |||||
}, | |||||
{ | |||||
label: '批复时间', | |||||
key: 'approvalDate', | |||||
prop: 'approvalDate', | |||||
width: '200' | |||||
}, | |||||
{ | |||||
label: '项目状态', | |||||
key: 'status', | |||||
prop: 'status', | |||||
showOverflowTooltip: true, | |||||
width: '180', | |||||
render: row => [ | |||||
h('span', { | |||||
class: ['dot mr-4', `bg-${statusOptions[row.status].color}`] | |||||
}), | |||||
h( | |||||
'span', | |||||
{ | |||||
class: `text-${statusOptions[row.status]?.color}` | |||||
}, | |||||
row.status && statusOptions[row.stage]?.name + '-' + statusOptions[row.status]?.name | |||||
) | |||||
] | |||||
}, | |||||
{ | |||||
label: '创建时间', | |||||
key: 'createOn', | |||||
prop: 'createOn', | |||||
width: '200' | |||||
}, | |||||
{ | |||||
label: '操作', | |||||
slot: 'action', | |||||
width: '180', | |||||
fixed: 'right' | |||||
} | |||||
]), | |||||
data = ref([]), | |||||
tableListRef = ref(), | |||||
getTableData = async (pageParams = tableListRef.value.pageParams) => { | |||||
const res = await purchaseList({ | |||||
...pageParams, | |||||
...searchForm, | |||||
createOnMin: searchForm.times?.[0], | |||||
createOnMax: searchForm.times?.[1], | |||||
projectYear: searchForm.projectYear * 1 || undefined, | |||||
times: undefined | |||||
}) | |||||
data.value = res.data.records | |||||
total.value = res.data.total | |||||
}, | |||||
// 数据总数 | |||||
total = ref(2), | |||||
// 提交查询 | |||||
search = () => { | |||||
getTableData() | |||||
}, | |||||
// 重置 | |||||
formReset = () => { | |||||
searchForm.projectYear = undefined | |||||
searchForm.projectName = undefined | |||||
searchForm.projectType = undefined | |||||
searchForm.createOnMin = undefined | |||||
searchForm.createOnMax = undefined | |||||
searchForm.times = undefined | |||||
tableListRef.value.pageParams.pageNumber = 1 | |||||
tableListRef.value.pageParams.pageSize = 10 | |||||
getTableData() | |||||
}, | |||||
// 导出excel文件 | |||||
{ exportLoading, exportData } = useExportExc(), | |||||
handleExcel = () => { | |||||
exportData(() => declareExport(6, { | |||||
...searchForm, | |||||
createOnMin: searchForm.times?.[0], | |||||
createOnMax: searchForm.times?.[1], | |||||
projectYear: searchForm.projectYear * 1 || undefined, | |||||
times: undefined | |||||
})) | |||||
}, | |||||
// 实施计划 | |||||
implementPlanDialogData = reactive({ | |||||
visible: false, | |||||
data: undefined | |||||
}), | |||||
showImplementPlanDialog = (data) => { | |||||
implementPlanDialogData.visible = true | |||||
implementPlanDialogData.data = data | |||||
}, | |||||
close = (flag) => { | |||||
implementPlanDialogData.visible = false | |||||
flag && getTableData() | |||||
} | |||||
onMounted(async () => { | |||||
getTableData() | |||||
}) | |||||
</script> | |||||
<template> | |||||
<el-card class="w-full search"> | |||||
<el-form :model="searchForm" size="small" label-suffix=":"> | |||||
<el-row :gutter="16" class="mb-16"> | |||||
<el-col :span="8"> | |||||
<el-form-item label="项目名称"> | |||||
<el-input | |||||
v-model="searchForm.projectName" | |||||
maxlength="50" | |||||
placeholder="请输入" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<el-form-item label="项目类型"> | |||||
<el-select | |||||
v-model="searchForm.projectType" | |||||
placeholder="全部" | |||||
class="w-full" | |||||
> | |||||
<el-option | |||||
v-for="(v,k) in projectTypeOptions" | |||||
:key="k" | |||||
:label="v" | |||||
:value="k" | |||||
/> | |||||
</el-select> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<el-form-item label="预算年度"> | |||||
<el-date-picker | |||||
v-model="searchForm.projectYear" | |||||
type="year" | |||||
placeholder="请选择" | |||||
format="YYYY" | |||||
value-format="YYYY" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
</el-row> | |||||
<el-row :gutter="24"> | |||||
<el-col :span="12"> | |||||
<el-form-item label="创建时间"> | |||||
<el-date-picker | |||||
v-model="searchForm.times" | |||||
type="datetimerange" | |||||
range-separator="-" | |||||
start-placeholder="开始时间" | |||||
end-placeholder="结束时间" | |||||
format="YYYY-MM-DD HH:mm" | |||||
value-format="YYYY-MM-DD HH:mm" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="12"> | |||||
<el-form-item class="btn"> | |||||
<div class="flex"> | |||||
<el-button type="primary" @click="search">查询</el-button> | |||||
<el-button @click="formReset">重置</el-button> | |||||
</div> | |||||
</el-form-item> | |||||
</el-col> | |||||
</el-row> | |||||
</el-form> | |||||
</el-card> | |||||
<el-card class="w-full mt-8"> | |||||
<template #header> | |||||
<div class="flex justify-between"> | |||||
<span>列表</span> | |||||
<div> | |||||
<el-button | |||||
type="primary" | |||||
size="small" | |||||
plain | |||||
:loading="exportLoading" | |||||
@click="handleExcel" | |||||
> | |||||
导出 | |||||
</el-button> | |||||
</div> | |||||
</div> | |||||
</template> | |||||
<table-list | |||||
ref="tableListRef" | |||||
:column="column" | |||||
:data="data" | |||||
:total="total" | |||||
@get-table-data="getTableData" | |||||
> | |||||
<template #action="{ scope }"> | |||||
<a v-if="scope.row.status===20001" @click="router.push({ name: 'fillPurchasingResult', query: { id: scope.row.id }})">填写采购结果</a> | |||||
<a v-if="scope.row.status===20006" @click="showImplementPlanDialog(scope.row)">填写实施计划</a> | |||||
<a @click="router.push({name:'purchasingResultDetail',query:{id:scope.row.id}})">详情</a> | |||||
</template> | |||||
</table-list> | |||||
</el-card> | |||||
<implement-plan-dialog :visible="implementPlanDialogData.visible" :data="implementPlanDialogData.data" @close="close" /> | |||||
</template> | |||||
<style lang="less" scoped></style> |
@@ -0,0 +1,289 @@ | |||||
<script setup name="projectStore"> | |||||
import { getCurrentInstance, h, onMounted, reactive, ref } from 'vue' | |||||
import { useRouter } from 'vue-router' | |||||
import store from '@/store' | |||||
import { renewalProjectDelete, renewalProjectList } from '@/http/apis/projectStoreManage/renewalProjectTreasury' | |||||
import useExportExc from '@/utils/useExportExc' | |||||
import { declareExport } from '@/http/apis/declareMange' | |||||
const | |||||
{ proxy } = getCurrentInstance(), | |||||
router = useRouter(), | |||||
{ reAuditStatusOptions, projectTypeOptions } = store.dictStore.globalDicts || {}, | |||||
searchForm = reactive({ | |||||
projectName: undefined, | |||||
projectType: undefined, | |||||
approvalStatus: undefined, | |||||
year: undefined, | |||||
times: undefined | |||||
}), | |||||
tableListRef = ref(), | |||||
total = ref(0), | |||||
// 列表数据 | |||||
column = reactive([ | |||||
{ | |||||
label: '序号', | |||||
type: 'index', | |||||
width: '60' | |||||
}, | |||||
{ | |||||
label: '项目名称', | |||||
key: 'projectName', | |||||
prop: 'projectName', | |||||
minWidth: '200', | |||||
showOverflowTooltip: true | |||||
}, | |||||
{ | |||||
label: '项目类型', | |||||
key: 'projectType', | |||||
prop: 'projectType', | |||||
minWidth: '80', | |||||
render: row => h('span', projectTypeOptions[row.projectType] || '-') | |||||
}, | |||||
{ | |||||
label: '预算年度', | |||||
key: 'projectYear', | |||||
prop: 'projectYear', | |||||
width: '80' | |||||
}, | |||||
{ | |||||
label: '下一年度支付金额(万元)', | |||||
key: 'annualPaymentAmount', | |||||
prop: 'annualPaymentAmount', | |||||
width: '200' | |||||
}, | |||||
{ | |||||
label: '项目状态', | |||||
key: 'approvalStatus', | |||||
prop: 'approvalStatus', | |||||
width: '180', | |||||
render: row => [ | |||||
h('span', { | |||||
class: [ | |||||
'dot mr-4', | |||||
`bg-${row.approvalStatus === 'PENDING' ? 'warning' : row.approvalStatus === 'PASS' ? 'success' : 'danger'}` | |||||
] | |||||
}), | |||||
h( | |||||
'span', | |||||
{ | |||||
class: `text-${row.approvalStatus === 'PENDING' ? 'warning' : row.approvalStatus === 'PASS' ? 'success' : 'danger'}` | |||||
}, | |||||
row.approvalStatus === 'PENDING' ? '待审核' : row.approvalStatus === 'PASS' ? '审核通过' : '审核不通过' | |||||
) | |||||
] | |||||
}, | |||||
{ | |||||
label: '创建时间', | |||||
key: 'createOn', | |||||
prop: 'createOn', | |||||
width: '180' | |||||
}, | |||||
{ | |||||
label: '操作', | |||||
slot: 'action', | |||||
width: '200', | |||||
fixed: 'right' | |||||
} | |||||
]), | |||||
data = ref([]), | |||||
areaCode = ref(), | |||||
getTableData = async (pageParams = tableListRef.value.pageParams) => { | |||||
const res = await renewalProjectList({ | |||||
...pageParams, | |||||
...searchForm, | |||||
year: searchForm.year * 1 || undefined, | |||||
startTime: searchForm.times?.[0] || undefined, | |||||
endTime: searchForm.times?.[1] || undefined, | |||||
regionCode: areaCode.value || undefined, | |||||
times: undefined | |||||
}) | |||||
data.value = res.data.records | |||||
total.value = res.data.total | |||||
}, | |||||
search = () => { | |||||
getTableData() | |||||
}, | |||||
reset = () => { | |||||
searchForm.projectName = undefined | |||||
searchForm.projectType = undefined | |||||
searchForm.approvalStatus = undefined | |||||
searchForm.maxDeclareAmount = undefined | |||||
searchForm.maxApprovalAmount = undefined | |||||
searchForm.year = undefined | |||||
searchForm.times = undefined | |||||
tableListRef.value.pageParams.pageNumber = 1 | |||||
tableListRef.value.pageParams.pageSize = 10 | |||||
getTableData() | |||||
}, | |||||
// 导出excel文件 | |||||
{ exportLoading, exportData } = useExportExc(), | |||||
handleExcel = () => { | |||||
exportData(() => declareExport(5, { | |||||
...searchForm, | |||||
year: searchForm.year * 1 || undefined, | |||||
maxDeclareAmount: searchForm.maxDeclareAmount * 1 || undefined, | |||||
maxApprovalAmount: searchForm.maxApprovalAmount * 1 || undefined, | |||||
startTime: searchForm.times?.[0] || undefined, | |||||
endTime: searchForm.times?.[1] || undefined, | |||||
areaCode: areaCode.value || undefined, | |||||
times: undefined | |||||
})) | |||||
}, | |||||
deleteItem = (data) => { | |||||
proxy.$messageBox | |||||
.confirm('确定要删除该项吗?', '提示!', { | |||||
type: 'warning' | |||||
}) | |||||
.then(async () => { | |||||
await renewalProjectDelete({ projectRenewalId: data.id }) | |||||
proxy.$message.success('删除成功!') | |||||
getTableData() | |||||
}) | |||||
}, | |||||
checkDetail = (row) => { | |||||
router.push({ name: 'renewProjectDetail', query: { id: row.id }}) | |||||
}, | |||||
redeclare = (row) => { | |||||
router.push({ name: 'renewalCapitalDeclare', query: { id: row.id }}) | |||||
} | |||||
onMounted(async () => { | |||||
getTableData() | |||||
}) | |||||
</script> | |||||
<template> | |||||
<el-row> | |||||
<el-col :span="24"> | |||||
<el-card class="w-full search"> | |||||
<el-form | |||||
:model="searchForm" | |||||
size="small" | |||||
label-suffix=":" | |||||
> | |||||
<el-row | |||||
:gutter="16" | |||||
class="mb-16" | |||||
> | |||||
<el-col :span="8"> | |||||
<el-form-item label="项目名称"> | |||||
<el-input | |||||
v-model="searchForm.projectName" | |||||
placeholder="请输入" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<el-form-item label="项目类型"> | |||||
<el-select | |||||
v-model="searchForm.projectType" | |||||
placeholder="全部" | |||||
class="w-full" | |||||
> | |||||
<el-option | |||||
v-for="(v,k) in projectTypeOptions" | |||||
:key="k" | |||||
:label="v" | |||||
:value="k" | |||||
/> | |||||
</el-select> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<el-form-item label="项目状态"> | |||||
<el-select | |||||
v-model="searchForm.approvalStatus" | |||||
placeholder="全部" | |||||
class="w-full" | |||||
> | |||||
<el-option | |||||
v-for="(v,k) in reAuditStatusOptions" | |||||
:key="k" | |||||
:label="v" | |||||
:value="k" | |||||
/> | |||||
</el-select> | |||||
</el-form-item> | |||||
</el-col> | |||||
</el-row> | |||||
<el-row | |||||
:gutter="16" | |||||
> | |||||
<el-col :span="8"> | |||||
<el-form-item label="预算年度"> | |||||
<el-date-picker | |||||
v-model="searchForm.year" | |||||
type="year" | |||||
value-format="YYYY" | |||||
placeholder="请选择" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="12"> | |||||
<el-form-item label="创建时间"> | |||||
<el-date-picker | |||||
v-model="searchForm.times" | |||||
type="datetimerange" | |||||
:editable="false" | |||||
format="YYYY-MM-DD HH:mm" | |||||
value-format="YYYY-MM-DD HH:mm" | |||||
range-separator="-" | |||||
start-placeholder="开始时间" | |||||
end-placeholder="结束时间" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="4"> | |||||
<el-form-item class="btn"> | |||||
<div class="flex"> | |||||
<el-button | |||||
type="primary" | |||||
@click="search" | |||||
>查询</el-button> | |||||
<el-button | |||||
@click="reset" | |||||
>重置</el-button> | |||||
</div> | |||||
</el-form-item> | |||||
</el-col> | |||||
</el-row> | |||||
</el-form> | |||||
</el-card> | |||||
<el-card class="w-full mt-8"> | |||||
<template #header> | |||||
<div class="flex justify-between"> | |||||
<span>申报列表</span> | |||||
<div> | |||||
<el-button | |||||
type="primary" | |||||
plain | |||||
size="small" | |||||
:loading="exportLoading" | |||||
@click="handleExcel" | |||||
>导出</el-button> | |||||
<el-button | |||||
type="primary" | |||||
size="small" | |||||
icon="Plus" | |||||
@click="router.push({ name: 'renewalCapitalDeclare'})" | |||||
>续建资金申报</el-button> | |||||
</div> | |||||
</div> | |||||
</template> | |||||
<table-list | |||||
ref="tableListRef" | |||||
:column="column" | |||||
:data="data" | |||||
:total="total" | |||||
@get-table-data="getTableData" | |||||
> | |||||
<template #action="{ scope }"> | |||||
<a @click="checkDetail(scope.row)">详情</a> | |||||
<a v-if="scope.row.approvalStatus==='NOT_PASS'" @click="redeclare(scope.row)">重新申报</a> | |||||
<a v-if="scope.row.approvalStatus==='NOT_PASS'" class="text-danger" @click="deleteItem(scope.row)">删除</a> | |||||
</template> | |||||
</table-list> | |||||
</el-card> | |||||
</el-col> | |||||
</el-row> | |||||
</template> | |||||
<style lang='less' scoped> | |||||
</style> |
@@ -0,0 +1,377 @@ | |||||
<script setup name='renewProjectDetail'> | |||||
import { getCurrentInstance, h, onMounted, reactive, ref, watch } from 'vue' | |||||
import { useRouter, useRoute } from 'vue-router' | |||||
import { renewalDeclaredDetail } from '@/http/apis/declareMange/renewalProjectCapitalDeclare' | |||||
import store from '@/store' | |||||
import { renewalProjectAsscess } from '@/http/apis/projectStoreManage/renewalProjectTreasury' | |||||
import { contractDetail } from '@/http/apis/declareMange/contractRecord' | |||||
const { statusOptions, projectTypeOptions, statusGjOptions } = | |||||
store.dictStore.globalDicts || {}, | |||||
tableListRef = ref(), | |||||
ruleFormRef = ref(), | |||||
router = useRouter(), | |||||
route = useRoute(), | |||||
total = ref(0), | |||||
dialogFormVisible = ref(false), | |||||
{ proxy } = getCurrentInstance(), | |||||
// 列表数据 | |||||
column = reactive([ | |||||
{ | |||||
label: '项目名称', | |||||
key: 'projectName', | |||||
prop: 'projectName', | |||||
minWidth: '200', | |||||
showOverflowTooltip: true | |||||
}, | |||||
{ | |||||
label: '项目类型', | |||||
key: 'projectType', | |||||
prop: 'projectType', | |||||
minWidth: '80', | |||||
render: row => h('span', projectTypeOptions[row.projectType] || '-') | |||||
}, | |||||
{ | |||||
label: '批复总金额(万元)', | |||||
key: 'approvalAmount', | |||||
prop: 'approvalAmount', | |||||
width: 150 | |||||
}, | |||||
{ | |||||
label: '累计年度投资资金', | |||||
key: 'annualAccumulateAmountList', | |||||
slot: 'annualAccumulateAmountList', | |||||
width: 150 | |||||
}, | |||||
{ | |||||
label: '项目状态', | |||||
key: 'status', | |||||
prop: 'status', | |||||
width: '120', | |||||
render: row => [ | |||||
h('span', { | |||||
class: ['dot mr-4', `bg-${statusOptions[row.status]?.color || statusGjOptions[row.status]?.color}`] | |||||
}), | |||||
h( | |||||
'span', | |||||
{ | |||||
class: `text-${statusOptions[row.status]?.color || statusGjOptions[row.status]?.color}` | |||||
}, | |||||
row.status && statusOptions[row.stage]?.name ? `${statusOptions[row.stage]?.name}-${statusOptions[row.status]?.name}` : statusGjOptions[row.status]?.name || '-' | |||||
) | |||||
] | |||||
} | |||||
]), | |||||
data = ref([]), | |||||
form = reactive({}), | |||||
rules = reactive({ | |||||
recommend: [ | |||||
{ required: true, message: '请填写审核意见', trigger: 'blur' } | |||||
] | |||||
}), | |||||
submitForm = async (formEl) => { | |||||
if (!formEl) return | |||||
await formEl.validate(async (valid) => { | |||||
if (valid) { | |||||
await renewalProjectAsscess({ | |||||
...form, | |||||
projectRenewalId: route.query.id, | |||||
result: false | |||||
}) | |||||
dialogFormVisible.value = false | |||||
proxy.$message.success('审核成功!') | |||||
router.push({ name: 'renewalProjectTreasury' }) | |||||
} else { | |||||
console.log('error submit!') | |||||
} | |||||
}) | |||||
}, | |||||
redeclare = () => { | |||||
router.push({ name: 'renewalCapitalDeclare', query: { id: route.query.id }}) | |||||
}, | |||||
adopt = () => { | |||||
proxy.$messageBox | |||||
.confirm('确认审核通过吗?', '提示!', { | |||||
type: 'warning' | |||||
}) | |||||
.then(async () => { | |||||
await renewalProjectAsscess({ | |||||
projectRenewalId: route.query.id, | |||||
result: true | |||||
}) | |||||
proxy.$message.success('审核成功!') | |||||
router.push({ name: 'renewalProjectTreasury' }) | |||||
}) | |||||
}, | |||||
goBack = () => { | |||||
router.go(-1) | |||||
}, | |||||
routeName = ref(''), | |||||
detail = ref({}), | |||||
getDetail = async () => { | |||||
const res = await renewalDeclaredDetail(route.query.id) | |||||
detail.value = res.data | |||||
data.value = [{ ...res.data }] | |||||
getPayInfo(data.value[0].projectId) | |||||
}, | |||||
// 支付信息 | |||||
payColumn = [ | |||||
{ | |||||
label: '付款笔数', | |||||
key: 'number', | |||||
slot: 'number' | |||||
}, | |||||
{ | |||||
label: '付款计划', | |||||
key: 'planAmount', | |||||
slot: 'planAmount' | |||||
}, | |||||
{ | |||||
label: '付款比例(%)', | |||||
key: 'ratio', | |||||
slot: 'ratio' | |||||
}, | |||||
{ | |||||
label: '付款金额(万元)', | |||||
key: 'paymentAmount', | |||||
slot: 'paymentAmount' | |||||
}, | |||||
{ | |||||
label: '预计付款时间', | |||||
key: 'paymentTime', | |||||
slot: 'paymentTime' | |||||
}, | |||||
{ | |||||
label: '实际支付金额(万元)', | |||||
key: 'actualPaymentAmount', | |||||
slot: 'actualPaymentAmount', | |||||
width: 180 | |||||
} | |||||
], | |||||
paymentsData = ref(), | |||||
getPayInfo = async (id) => { | |||||
const res = await contractDetail(id) | |||||
paymentsData.value = res?.data?.payments || [] | |||||
} | |||||
watch( | |||||
route, | |||||
(val) => { | |||||
routeName.value = route.meta.title | |||||
}, | |||||
{ immediate: true, deep: true } | |||||
) | |||||
onMounted(() => { | |||||
getDetail() | |||||
}) | |||||
</script> | |||||
<template> | |||||
<div class=""> | |||||
<el-alert | |||||
v-if="detail.approvalStatus==='NOT_PASS'" | |||||
title="审核不通过" | |||||
type="error" | |||||
:description="`审核意见:${detail.auditOpinion||'-'}`" | |||||
show-icon | |||||
/> | |||||
<el-alert | |||||
v-if="detail.approvalStatus==='PASS'" | |||||
title="审核通过" | |||||
type="success" | |||||
:description="`审核意见:${detail.auditOpinion||'-'}`" | |||||
show-icon | |||||
/> | |||||
<el-card class="box-card"> | |||||
<template #header> | |||||
<div class="card-header"> | |||||
<span>申报信息</span> | |||||
</div> | |||||
</template> | |||||
<div class="flex justify-around"> | |||||
<div style="font-size: 14px;flex-shrink:0">关联项目:</div> | |||||
<table-list | |||||
ref="tableListRef" | |||||
class="flex-1 mb-16" | |||||
:column="column" | |||||
:data="data" | |||||
:total="total" | |||||
:height="200" | |||||
:pagination="false" | |||||
> | |||||
<template #annualAccumulateAmountList="{scope}"> | |||||
<p v-for="(item,index) in scope.row.annualAccumulateAmountList" :key="index">{{ index+1 }}、{{ item.projectYear }}年投资{{ item.annualAmount }}万元</p> | |||||
</template> | |||||
</table-list> | |||||
</div> | |||||
<p class="font-bold mb-8">支付信息</p> | |||||
<table-list | |||||
ref="tableListRef" | |||||
:column="payColumn" | |||||
:data="paymentsData" | |||||
:pagination="false" | |||||
:empty-temp="false" | |||||
class="mb-16" | |||||
> | |||||
<template #number="{scope}"> | |||||
<span>第{{ scope.$index+1 }}笔</span> | |||||
</template> | |||||
<template #planAmount="{scope}"> | |||||
{{ scope.row.planAmount }} | |||||
</template> | |||||
<template #ratio="{scope}"> | |||||
{{ scope.row.ratio }} | |||||
</template> | |||||
<template #paymentAmount="{scope}"> | |||||
{{ scope.row.paymentAmount }} | |||||
</template> | |||||
<template #paymentTime="{scope}"> | |||||
{{ scope.row.paymentTime }} | |||||
</template> | |||||
<template #actualPaymentAmount="{scope}"> | |||||
{{ scope.row.actualPaymentAmount }} | |||||
</template> | |||||
</table-list> | |||||
<template v-if="detail.annualAccumulateAmountList?.filter((i,key)=>key!==0&&i.projectYear!==detail.projectYear)?.length"> | |||||
<p class="font-bold mt-20">历史续建资金信息</p> | |||||
<el-descriptions | |||||
v-for="(item,index) in detail.annualAccumulateAmountList.filter((i,key)=>key!==0&&i.projectYear!==detail.projectYear)" | |||||
:key="index" | |||||
class="mt-20" | |||||
:column="2" | |||||
border | |||||
> | |||||
<el-descriptions-item | |||||
label="预算年度" | |||||
span="1" | |||||
width="250px" | |||||
> | |||||
{{ item.projectYear }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item | |||||
:label="`${item.projectYear}年支付金额(万元)`" | |||||
width="250px" | |||||
> | |||||
{{ item.annualAmount }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="自有金额(万元)"> | |||||
{{ item.haveAmount }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="政府投资-本级财政资金(万元)"> | |||||
{{ item.govOwnFinanceAmount }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="政府投资-上级补助资金(万元)"> | |||||
{{ item.govSuperiorFinanceAmount }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="银行贷款(万元)"> | |||||
{{ item.bankLendingAmount }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item | |||||
label="其他(万元)" | |||||
span="2" | |||||
> | |||||
{{ item.otherAmount }} | |||||
</el-descriptions-item> | |||||
</el-descriptions> | |||||
</template> | |||||
<el-descriptions | |||||
class="mt-20" | |||||
title="申报续建资金信息" | |||||
:column="2" | |||||
border | |||||
> | |||||
<el-descriptions-item | |||||
label="预算年度" | |||||
span="1" | |||||
width="250px" | |||||
> | |||||
{{ detail.projectYear }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item | |||||
:label="`${detail.projectYear}年支付金额(万元)`" | |||||
width="250px" | |||||
> | |||||
{{ detail.annualPaymentAmount }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="自有金额(万元)"> | |||||
{{ detail.haveAmount }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="政府投资-本级财政资金(万元)"> | |||||
{{ detail.govOwnFinanceAmount }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="政府投资-上级补助资金(万元)"> | |||||
{{ detail.govSuperiorFinanceAmount }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="银行贷款(万元)"> | |||||
{{ detail.bankLendingAmount }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item | |||||
label="其他(万元)" | |||||
span="2" | |||||
> | |||||
{{ detail.otherAmount }} | |||||
</el-descriptions-item> | |||||
</el-descriptions> | |||||
<div class="flex justify-center items-center mt-10"> | |||||
<el-button | |||||
v-if="routeName =='续建项目资金申报详情'&&detail.approvalStatus==='NOT_PASS'" | |||||
class="mr-20" | |||||
type="primary" | |||||
@click="redeclare" | |||||
>重新申报</el-button> | |||||
<template v-if="routeName !=='续建项目资金申报详情'&&detail.approvalStatus==='PENDING'"> | |||||
<el-button | |||||
class="mr-20" | |||||
type="primary" | |||||
@click="adopt" | |||||
>通过</el-button> | |||||
<el-button | |||||
class="mr-20" | |||||
type="danger" | |||||
@click="dialogFormVisible = true" | |||||
>不通过</el-button> | |||||
</template> | |||||
<el-button | |||||
plain | |||||
@click="goBack" | |||||
>返回</el-button> | |||||
</div> | |||||
</el-card> | |||||
<el-dialog | |||||
v-model="dialogFormVisible" | |||||
title="不通过" | |||||
> | |||||
<el-form | |||||
ref="ruleFormRef" | |||||
:model="form" | |||||
:rules="rules" | |||||
status-icon | |||||
> | |||||
<el-form-item | |||||
label="审核意见" | |||||
label-width="auto" | |||||
prop="auditOpinion" | |||||
> | |||||
<el-input | |||||
v-model="form.auditOpinion" | |||||
maxlength="200" | |||||
placeholder="请输入" | |||||
show-word-limit | |||||
type="textarea" | |||||
/> | |||||
</el-form-item> | |||||
</el-form> | |||||
<template #footer> | |||||
<span class="dialog-footer"> | |||||
<el-button | |||||
type="primary" | |||||
@click="submitForm(ruleFormRef)" | |||||
> | |||||
提交 | |||||
</el-button> | |||||
<el-button @click="dialogFormVisible = false">关闭</el-button> | |||||
</span> | |||||
</template> | |||||
</el-dialog> | |||||
</div> | |||||
</template> | |||||
<style lang='less' scoped> </style> |
@@ -0,0 +1,862 @@ | |||||
<script setup name='renewalCapitalDeclare'> | |||||
import { reactive, ref, onMounted, h, getCurrentInstance } from 'vue' | |||||
import { useRouter, useRoute } from 'vue-router' | |||||
import store from '@/store' | |||||
import { | |||||
convertToCollection, | |||||
renewalDeclared, | |||||
renewalDeclaredDetail, | |||||
libAllList | |||||
} from '@/http/apis/declareMange/renewalProjectCapitalDeclare' | |||||
import { detail } from '@/http/apis/projectCollection/projectCollectionEnter' | |||||
import { storeToRefs } from 'pinia' | |||||
import { dictionary, save } from '@/http/apis/projectCollection/projectCollectionEnter' | |||||
import BasicInfo from '@/pages/projectCollection/projectCollectionEnter/components/basicInfo.vue' | |||||
import ProjectDeclareInfo from '@/pages/projectCollection/projectCollectionEnter/components/projectDeclareInfo.vue' | |||||
import ApplicationInfo from '@/pages/projectCollection/projectCollectionEnter/components/applicationInfo.vue' | |||||
import CoreBusiness from '@/pages/projectCollection/projectCollectionEnter/components/coreBusiness.vue' | |||||
import ProjectApprovalInfo from '@/pages/projectCollection/projectCollectionEnter/components/projectApprovalInfo.vue' | |||||
import PurchaseInfo from '@/pages/projectCollection/projectCollectionEnter/components/purchaseInfo.vue' | |||||
import EmpMaterials from '@/pages/projectCollection/projectCollectionEnter/components/empMaterials.vue' | |||||
import { contractDetail } from '@/http/apis/declareMange/contractRecord' | |||||
import { changFilesParam } from '@/utils/uploadAction' | |||||
const { proxy } = getCurrentInstance(), | |||||
{ statusOptions, statusGjOptions, projectTypeOptions } = store.dictStore.globalDicts || {}, | |||||
userInfo = storeToRefs(store.userStore).userInfo || {}, | |||||
router = useRouter(), | |||||
route = useRoute(), | |||||
// 列表 | |||||
column = reactive([ | |||||
{ | |||||
type: 'radio', | |||||
key: 'id', | |||||
width: '50' | |||||
}, | |||||
{ | |||||
label: '项目名称', | |||||
key: 'projectName', | |||||
prop: 'projectName', | |||||
minWidth: '200', | |||||
showOverflowTooltip: true | |||||
}, | |||||
{ | |||||
label: '项目类型', | |||||
key: 'projectType', | |||||
prop: 'projectType', | |||||
minWidth: '80', | |||||
render: row => h('span', projectTypeOptions[row.projectType] || '-') | |||||
}, | |||||
{ | |||||
label: '批复总金额(万元)', | |||||
key: 'approvedAmount', | |||||
prop: 'approvedAmount', | |||||
width: '180' | |||||
}, | |||||
{ | |||||
label: '累计年度投资资金', | |||||
key: 'annualAccumulateAmountList', | |||||
slot: 'annualAccumulateAmountList', | |||||
width: '180' | |||||
}, | |||||
{ | |||||
label: '项目状态', | |||||
key: 'status', | |||||
prop: 'status', | |||||
width: '180', | |||||
render: row => [ | |||||
h('span', { | |||||
class: ['dot mr-4', `bg-${statusOptions[row.status]?.color || statusGjOptions[row.status]?.color}`] | |||||
}), | |||||
h( | |||||
'span', | |||||
{ | |||||
class: `text-${statusOptions[row.status]?.color || statusGjOptions[row.status]?.color}` | |||||
}, | |||||
row.status && statusOptions[row.stage]?.name ? `${statusOptions[row.stage]?.name}-${statusOptions[row.status]?.name}` : statusGjOptions[row.status]?.name || '-' | |||||
) | |||||
] | |||||
} | |||||
]), | |||||
column1 = reactive([ | |||||
{ | |||||
label: '项目名称', | |||||
key: 'projectName', | |||||
prop: 'projectName', | |||||
minWidth: '200', | |||||
showOverflowTooltip: true | |||||
}, | |||||
{ | |||||
label: '项目类型', | |||||
key: 'projectType', | |||||
prop: 'projectType', | |||||
minWidth: '80', | |||||
render: row => h('span', projectTypeOptions[row.projectType] || '-') | |||||
}, | |||||
{ | |||||
label: '批复总金额(万元)', | |||||
key: 'approvalAmount', | |||||
prop: 'approvalAmount', | |||||
width: 150 | |||||
}, | |||||
{ | |||||
label: '累计年度投资资金', | |||||
key: 'annualAccumulateAmountList', | |||||
slot: 'annualAccumulateAmountList', | |||||
width: 150 | |||||
}, | |||||
{ | |||||
label: '项目状态', | |||||
key: 'status', | |||||
prop: 'status', | |||||
width: '120', | |||||
render: row => [ | |||||
h('span', { | |||||
class: ['dot mr-4', `bg-${statusOptions[row.status]?.color || statusGjOptions[row.status]?.color}`] | |||||
}), | |||||
h( | |||||
'span', | |||||
{ | |||||
class: `text-${statusOptions[row.status]?.color || statusGjOptions[row.status]?.color}` | |||||
}, | |||||
row.status && statusOptions[row.stage]?.name ? `${statusOptions[row.stage]?.name}-${statusOptions[row.status]?.name}` : statusGjOptions[row.status]?.name || '-' | |||||
) | |||||
] | |||||
} | |||||
]), | |||||
total = ref(0), | |||||
data = ref([]), | |||||
tableListRef = ref(), | |||||
maxYear = ref(), | |||||
totalAmount = ref(0), | |||||
approvedAmount = ref(), | |||||
radioChange = (val) => { | |||||
ruleForm.value.projectId = val.id | |||||
ruleForm.value.projectCode = val.projectCode | |||||
maxYear.value = val.annualAccumulateAmountList?.length > 1 && val.annualAccumulateAmountList.reduce((acc, cur) => Math.max(acc.projectYear, cur.projectYear)) || val.annualAccumulateAmountList[0].projectYear | |||||
totalAmount.value = val.annualAccumulateAmountList?.map(i => i.annualAmount)?.reduce((acc, cur) => { return acc + cur }, 0) | |||||
approvedAmount.value = val.approvedAmount | |||||
getPayInfo(val.id) | |||||
getProjectDetail(val.projectCode, val.fromType) | |||||
}, | |||||
searchForm = reactive({ | |||||
projectName: undefined | |||||
}), | |||||
search = () => { | |||||
tableListRef.value.pageParams.pageNumber = 1 | |||||
getTableData() | |||||
}, | |||||
getTableData = async (pageParams = tableListRef.value.pageParams) => { | |||||
const res = await libAllList({ | |||||
...pageParams, | |||||
projectName: searchForm.projectName | |||||
}) | |||||
data.value = res.data.records.map(i => { | |||||
return { | |||||
...i, | |||||
isRadioDisabled: i.annualAccumulateAmountList?.map(i => i.annualAmount)?.reduce((acc, cur) => { return acc + cur }, 0) === i.approvedAmount | |||||
} | |||||
}) | |||||
total.value = res.data.total | |||||
}, | |||||
// 表单 | |||||
ruleFormRef = ref(), | |||||
moneyValidator = (rule, value, callback) => { | |||||
if (!value) callback() | |||||
if (!/^\d+(\.\d{1,6})?$/.test(value)) { | |||||
callback('请输入正确格式,最多保留六位小数') | |||||
} else if (value * 1 >= 100000000) { | |||||
callback('请输入正确格式,小于100000000') | |||||
} else { | |||||
callback() | |||||
} | |||||
}, | |||||
moneyValidator1 = (rule, value, callback) => { | |||||
if (!value) callback() | |||||
if (!/^\d+(\.\d{1,6})?$/.test(value)) { | |||||
callback('请输入正确格式,最多保留六位小数') | |||||
} else if (value * 1 >= 100000000) { | |||||
callback('请输入正确格式,小于100000000') | |||||
} | |||||
let maxData = 0 | |||||
paymentsData.value.forEach(i => { | |||||
if (new Date(i.paymentTime).getFullYear() < ruleForm.value.projectYear * 1) { | |||||
maxData += i.paymentAmount - i.actualPaymentAmount | |||||
} | |||||
}) | |||||
maxData += paymentsData.value.find(i => new Date(i.paymentTime).getFullYear() === ruleForm.value.projectYear * 1)?.paymentAmount | |||||
if (value > maxData) { | |||||
callback(`支付金额最大不能超过${maxData}万元`) | |||||
} else { | |||||
callback() | |||||
} | |||||
}, | |||||
// yearValidator = (rule, value, callback) => { | |||||
// if (!value) callback() | |||||
// if (!paymentsData.value?.length) { | |||||
// callback('未有支付信息,无法提交') | |||||
// } | |||||
// const years1 = paymentsData.value.map(i => new Date(i.paymentTime).getFullYear() + '') | |||||
// // const years2 = paymentsData.value.filter(i => i.actualPaymentAmount || i.actualPaymentAmount === 0).map(i => new Date(i.paymentTime).getFullYear() + '') | |||||
// if (!years1.includes(value)) { | |||||
// callback('未有所选年度的支付计划,无法提交') | |||||
// } else { | |||||
// callback() | |||||
// } | |||||
// // else if (!years2.includes(value)) { | |||||
// // callback('未填写当年度的实际支付金额,请去合同备案补充”') | |||||
// // } | |||||
// }, | |||||
disabledDate = (time) => { | |||||
return new Date(time).getFullYear() <= new Date().getFullYear() | |||||
}, | |||||
rules = reactive({ | |||||
projectId: [ | |||||
{ required: true, message: '请选择关联项目', trigger: 'blur' } | |||||
], | |||||
projectYear: [ | |||||
{ required: true, message: '请选择预算年度', trigger: 'blur' } | |||||
// { validator: yearValidator, trigger: 'blur' } | |||||
], | |||||
annualPaymentAmount: [ | |||||
{ required: true, message: '请输入年度支付金额', trigger: 'blur' }, | |||||
{ validator: moneyValidator1, trigger: 'blur' } | |||||
], | |||||
haveAmount: [ | |||||
{ required: true, message: '请输入自有资金金额', trigger: 'blur' }, | |||||
{ validator: moneyValidator, trigger: 'blur' } | |||||
], | |||||
govOwnFinanceAmount: [ | |||||
{ required: true, message: '请输入政府投资-本级财政资金金额', trigger: 'blur' }, | |||||
{ validator: moneyValidator, trigger: 'blur' } | |||||
], | |||||
govSuperiorFinanceAmount: [ | |||||
{ required: true, message: '请输入政府投资-上级补助资金金额', trigger: 'blur' }, | |||||
{ validator: moneyValidator, trigger: 'blur' } | |||||
], | |||||
bankLendingAmount: [ | |||||
{ required: true, message: '请输入银行贷款金额', trigger: 'blur' }, | |||||
{ validator: moneyValidator, trigger: 'blur' } | |||||
], | |||||
otherAmount: [ | |||||
{ required: true, message: '请输入其他金额', trigger: 'blur' }, | |||||
{ validator: moneyValidator, trigger: 'blur' } | |||||
] | |||||
}), | |||||
ruleForm = ref({ | |||||
id: route.query.id || undefined, | |||||
orgCode: userInfo.empPosUnitCode, | |||||
regionCode: userInfo.regionCode | |||||
}), | |||||
// floatAdd = (args) => { | |||||
// const data = [] | |||||
// args.forEach(i => { | |||||
// try { | |||||
// data.push(i.toString().split('.')[1].length) | |||||
// } catch (e) { | |||||
// data.push(0) | |||||
// } | |||||
// }) | |||||
// const m = Math.pow(10, Math.max(...data)) | |||||
// let sum = 0 | |||||
// args.forEach(item => { | |||||
// sum += item * m | |||||
// }) | |||||
// return sum / m | |||||
// }, | |||||
submitForm = async (formEl) => { | |||||
if (!formEl) return | |||||
await formEl.validate(async (valid, fields) => { | |||||
if (valid) { | |||||
// if (ruleForm.value.projectYear * 1 <= maxYear.value * 1) { | |||||
// proxy.$message.warning('预算年度必须大于累计投资的最大年度') | |||||
// return | |||||
// } | |||||
// if (floatAdd([ruleForm.value.annualPaymentAmount, totalAmount.value]) > approvedAmount.value) { | |||||
// proxy.$message.warning('累计年度投资金额必须小于等于批复总金额') | |||||
// return | |||||
// } | |||||
if (errorText.value) { | |||||
proxy.$message.error(errorText.value) | |||||
return | |||||
} | |||||
// const total = floatAdd([ruleForm.value.haveAmount, ruleForm.value.govOwnFinanceAmount, ruleForm.value.govSuperiorFinanceAmount, ruleForm.value.bankLendingAmount, ruleForm.value.otherAmount]) | |||||
// if (total !== ruleForm.value.annualPaymentAmount) { | |||||
// proxy.$message.warning('各资金来源的和必须等于年度支付金额') | |||||
// return | |||||
// } | |||||
if (!route.query.id) { | |||||
const arr = Object.values(formRefs).map(async i => i?.formRef && await i.formRef.validate()) | |||||
await Promise.all(arr) | |||||
} | |||||
const postData = { | |||||
...ruleForm.value, | |||||
projectYear: ruleForm.value.projectYear * 1 | |||||
} | |||||
await renewalDeclared(postData) | |||||
!route.query.id && submitProject() | |||||
} else { | |||||
console.log('error submit!', fields) | |||||
} | |||||
}) | |||||
}, | |||||
getDetail = async () => { | |||||
const res = await renewalDeclaredDetail(route.query.id) | |||||
ruleForm.value = { ...res.data, projectYear: res.data.projectYear + '' } | |||||
data.value = [{ ...res.data }] | |||||
maxYear.value = res.data.annualAccumulateAmountList?.length > 1 && res.data.annualAccumulateAmountList.reduce((acc, cur) => Math.max(acc.projectYear, cur.projectYear)) || res.data.annualAccumulateAmountList[0].projectYear | |||||
totalAmount.value = res.data.annualAccumulateAmountList?.map(i => i.annualAmount)?.reduce((acc, cur) => { return acc + cur }, 0) | |||||
approvedAmount.value = res.data.approvalAmount | |||||
getPayInfo(res.data.projectId) | |||||
}, | |||||
// 支付信息 | |||||
payColumn = [ | |||||
{ | |||||
label: '付款笔数', | |||||
key: 'number', | |||||
slot: 'number' | |||||
}, | |||||
{ | |||||
label: '付款计划', | |||||
key: 'planAmount', | |||||
slot: 'planAmount' | |||||
}, | |||||
{ | |||||
label: '付款比例(%)', | |||||
key: 'ratio', | |||||
slot: 'ratio' | |||||
}, | |||||
{ | |||||
label: '付款金额(万元)', | |||||
key: 'paymentAmount', | |||||
slot: 'paymentAmount' | |||||
}, | |||||
{ | |||||
label: '预计付款时间', | |||||
key: 'paymentTime', | |||||
slot: 'paymentTime' | |||||
}, | |||||
{ | |||||
label: '实际支付金额(万元)', | |||||
key: 'actualPaymentAmount', | |||||
slot: 'actualPaymentAmount', | |||||
width: 180 | |||||
} | |||||
], | |||||
paymentsData = ref(), | |||||
errorText = ref(''), | |||||
getPayInfo = async (id) => { | |||||
const res = await contractDetail(id) | |||||
paymentsData.value = res?.data?.payments || [] | |||||
errorText.value = '' | |||||
// if (!paymentsData.value?.length) { | |||||
// errorText.value = '该项目未有支付信息' | |||||
// proxy.$message.error(errorText.value) | |||||
// return | |||||
// } | |||||
// let count = 0 | |||||
// paymentsData.value.forEach(i => { | |||||
// if (new Date(i.paymentTime).getTime() < new Date().getTime() && !(i.actualPaymentAmount || i.actualPaymentAmount === 0)) { | |||||
// count++ | |||||
// } | |||||
// }) | |||||
// if (count > 0) { | |||||
// errorText.value = '超过预付款时间的支付计划未填写实际支付金额,请去合同备案补充' | |||||
// proxy.$message.error(errorText.value) | |||||
// return | |||||
// } | |||||
return | |||||
}, | |||||
// 补充信息 | |||||
formRefs = {}, | |||||
detailData = ref(), | |||||
basicInfoData = ref(), | |||||
getBasicInfoData = (data) => { | |||||
basicInfoData.value = data | |||||
}, | |||||
dictionaryList = ref(), | |||||
baseProjSetYear = ref(), | |||||
getProYear = (data) => { | |||||
baseProjSetYear.value = data | |||||
}, | |||||
approvalInfoData = ref(), | |||||
getApprovalInfoData = (data) => { | |||||
approvalInfoData.value = data | |||||
}, | |||||
baseProjName = ref(), | |||||
getProjectDetail = async (projectCode, fromType) => { | |||||
let res = {} | |||||
// 归集项目详情使用detail 申报项目详情使用convertToCollection | |||||
if (fromType === '2') { | |||||
res = await detail('1', projectCode) | |||||
} else { | |||||
res = await convertToCollection(projectCode) | |||||
} | |||||
baseProjName.value = res.data.baseinfo.baseProjName | |||||
detailData.value = { | |||||
...res.data, | |||||
baseinfo: { | |||||
...res.data.baseinfo, | |||||
baseProjType: '03' | |||||
}, | |||||
cimplement: { | |||||
...res.data.cimplement, | |||||
baseCheckFile: res.data.cimplement?.baseCheckFile && JSON.stringify(changFilesParam(JSON.parse(res.data.cimplement?.baseCheckFile))) || undefined, | |||||
baseInitialOpinionFile: res.data.cimplement?.baseInitialOpinionFile && JSON.stringify(changFilesParam(JSON.parse(res.data.cimplement?.baseInitialOpinionFile))) || undefined, | |||||
baseEstaSummFile: res.data.cimplement?.baseEstaSummFile && JSON.stringify(changFilesParam(JSON.parse(res.data.cimplement?.baseEstaSummFile))) || undefined, | |||||
baseSummReportFile: res.data.cimplement?.baseEstaSummFile && JSON.stringify(changFilesParam(JSON.parse(res.data.cimplement?.baseSummReportFile))) || undefined, | |||||
baseThirdAcceptFile: res.data.cimplement?.baseEstaSummFile && JSON.stringify(changFilesParam(JSON.parse(res.data.cimplement?.baseThirdAcceptFile))) || undefined, | |||||
baseInforLevelFile: res.data.cimplement?.baseInforLevelFile && JSON.stringify(changFilesParam(JSON.parse(res.data.cimplement?.baseInforLevelFile))) || undefined, | |||||
basePasswAssessFile: res.data.cimplement?.basePasswAssessFile && JSON.stringify(changFilesParam(JSON.parse(res.data.cimplement?.basePasswAssessFile))) || undefined, | |||||
baseFinanlAuditFile: res.data.cimplement?.baseFinanlAuditFile && JSON.stringify(changFilesParam(JSON.parse(res.data.cimplement?.baseFinanlAuditFile))) || undefined, | |||||
baseUserConsFile: res.data.cimplement?.baseUserConsFile && JSON.stringify(changFilesParam(JSON.parse(res.data.cimplement?.baseUserConsFile))) || undefined, | |||||
baseFinalExpertOpinionFile: res.data.cimplement?.baseFinalExpertOpinionFile && JSON.stringify(changFilesParam(JSON.parse(res.data.cimplement?.baseFinalExpertOpinionFile))) || undefined, | |||||
baseEngineerPostpoFile: res.data.cimplement?.baseEngineerPostpoFile && JSON.stringify(changFilesParam(JSON.parse(res.data.cimplement?.baseEngineerPostpoFile))) || undefined, | |||||
baseChangeFormFile: res.data.cimplement?.baseChangeFormFile && JSON.stringify(changFilesParam(JSON.parse(res.data.cimplement?.baseChangeFormFile))) || undefined, | |||||
baseChanFile: res.data.cimplement?.baseChanFile && JSON.stringify(changFilesParam(JSON.parse(res.data.cimplement?.baseChanFile))) || undefined | |||||
} | |||||
} | |||||
}, | |||||
changeYear = () => { | |||||
detailData.value.baseinfo.baseProjName = baseProjName.value + `(${ruleForm.value.projectYear})` | |||||
}, | |||||
changePostData = () => { | |||||
const baseinfo = JSON.parse(JSON.stringify(formRefs['baseinfo'].formData)) | |||||
const apply = JSON.parse(JSON.stringify(formRefs['apply'].formData)) | |||||
const application = formRefs['application'] && JSON.parse(JSON.stringify(formRefs['application'].formData)) || {} | |||||
const baseCore = formRefs['baseCore'] && JSON.parse(JSON.stringify(formRefs['baseCore'].formData)) || {} | |||||
const approve = formRefs['approve'] && JSON.parse(JSON.stringify(formRefs['approve'].formData)) || {} | |||||
const procures = formRefs['procures'] && JSON.parse(JSON.stringify(formRefs['procures'].formData)) || [] | |||||
const cimplement = formRefs['cimplement'] && JSON.parse(JSON.stringify(formRefs['cimplement'].formData)) || [] | |||||
return { | |||||
baseProjId: '', | |||||
baseinfo: { | |||||
...baseinfo, | |||||
baseProvManDeprtType: baseinfo?.baseProvManDeprtType * 1 || undefined, | |||||
baseConstructionType: baseinfo?.baseConstructionType?.join(';') | |||||
// baseAreaCode: baseinfo?.baseArea?.baseAreaCode || undefined, | |||||
// baseAreaName: baseinfo?.baseArea?.baseAreaName || undefined, | |||||
// baseArea: undefined | |||||
}, | |||||
apply: { | |||||
...apply, | |||||
baseProjStartTime: apply?.baseProjTime?.length ? apply?.baseProjTime[0] + ' 00:00:00' : undefined, | |||||
baseProjEndTime: apply?.baseProjTime?.length ? apply?.baseProjTime[1] + ' 00:00:00' : undefined, | |||||
baseProjTime: undefined, | |||||
baseHistorProjId: apply?.missing || baseinfo?.baseProjType === '01' ? '' : apply?.baseHistorProjs?.map(i => i.baseProjId)?.join(';'), | |||||
baseHistorProjName: apply?.missing || baseinfo?.baseProjType === '01' ? '' : apply?.baseHistorProjs?.map(i => i.baseProjName)?.join(';'), | |||||
baseHistorProjYear: apply?.missing || baseinfo?.baseProjType === '01' ? '' : apply?.baseHistorProjs?.map(i => i.baseProjSetYear)?.join(';'), | |||||
baseProjAmountOri: apply?.baseProjAmountOri?.join(';') || undefined, | |||||
baseProjBasis: apply?.baseProjBasis?.map(i => i.value)?.join(';') || undefined, | |||||
baseProjBasisFile: apply?.baseProjBasis?.map(i => i.fileList && JSON.stringify(changFilesParam(i.fileList)))?.join(';') || '', | |||||
beseExpectedResults: apply?.beseExpectedResults?.length && JSON.stringify(apply.beseExpectedResults) || '', | |||||
baseProjApplyFile: ((['01', '02', '04', '05'].includes(baseinfo?.baseProjType) && apply?.baseProjSetYear * 1 >= 2023) || apply?.baseProjSetYear * 1 < 2023) && apply?.baseProjApplyFile?.length ? JSON.stringify(changFilesParam(apply?.baseProjApplyFile)) : '', | |||||
baseResearchReportFile: (baseinfo?.baseProjType === '01' || baseinfo?.baseProjType === '02') && apply?.baseResearchReportFile?.length ? JSON.stringify(changFilesParam(apply?.baseResearchReportFile)) : '', | |||||
baseProjOtherFile: apply?.baseProjOtherFile?.length ? JSON.stringify(changFilesParam(apply?.baseProjOtherFile)) : '', | |||||
baseHistorProjs: undefined, | |||||
...application, | |||||
baseProjSysCode: application?.applications?.map(i => i.application.applicationCode).join(';') || '', | |||||
baseProjSys: application?.applications?.map(i => i.application.applicationName).join(';') || '', | |||||
baseAccountAppName: application?.applications?.map(i => i.baseAccountAppName).join(';') || '', | |||||
baseBrainName: application?.applications?.map(i => i.baseBrainName).join(';') || '', | |||||
applications: undefined, | |||||
...baseCore, | |||||
baseCoreBusinessCode: baseCore?.coreBusiness?.map(i => i.id).join(';') || '', | |||||
baseCoreBusiness: baseCore?.coreBusiness?.map(i => i.matterName).join(';') || '', | |||||
baseCoreBusinessOrg: baseCore?.coreBusiness?.map(i => i.orgName).join(';') || '', | |||||
coreBusiness: undefined, | |||||
baseProjId: '' | |||||
}, | |||||
approve: { | |||||
...approve, | |||||
baseReviewResults: baseinfo?.baseProjSetProg !== '01' ? approve?.baseReviewResults : '', | |||||
baseReviewOpinion: baseinfo?.baseProjSetProg !== '01' ? approve?.baseReviewOpinion : '', | |||||
baseReviewCommentsFile: baseinfo?.baseProjSetProg !== '01' ? approve?.baseReviewCommentsFile?.length && JSON.stringify(changFilesParam(approve?.baseReviewCommentsFile)) : '', | |||||
equalProtectionLevel: baseinfo?.baseProjIsConfidentiality === '01' && !['01', '02', '03'].includes(baseinfo?.baseProjSetProg) ? approve?.equalProtectionLevel : '', | |||||
approvalFile: !['01', '02', '03'].includes(baseinfo?.baseProjSetProg) ? approve?.approvalFile?.length && JSON.stringify(changFilesParam(approve?.approvalFile)) : '', | |||||
baseExpertTotalMoney: !['01', '03'].includes(baseinfo?.baseProjSetProg) ? approve?.baseExpertTotalMoney : '', | |||||
baseExpertYearMoney: !['01', '03'].includes(baseinfo?.baseProjSetProg) ? approve?.baseExpertYearMoney : '', | |||||
baseInitialReviewTotalMoney: !['01', '02', '03'].includes(baseinfo?.baseProjSetProg) ? approve?.baseInitialReviewTotalMoney : '', | |||||
baseProjReplyAmount: !['01', '02', '03'].includes(baseinfo?.baseProjSetProg) ? approve?.baseProjReplyAmount : '', | |||||
releaseYearMoney: ['05', '06', '07', '00'].includes(baseinfo?.baseProjSetProg) ? approve?.releaseYearMoney : '', | |||||
preliminaryDesignScheme: approve?.baseProjReplyAmount >= 5000 && ['04', '05', '06', '07', '00'].includes(baseinfo.baseProjSetProg) ? approve?.preliminaryDesignScheme?.length && JSON.stringify(changFilesParam(approve.preliminaryDesignScheme)) : '', | |||||
preliminaryDesignFile: approve?.baseProjReplyAmount >= 5000 && ['04', '05', '06', '07', '00'].includes(baseinfo.baseProjSetProg) ? approve?.preliminaryDesignFile?.length && JSON.stringify(changFilesParam(approve.preliminaryDesignFile)) : '' | |||||
}, | |||||
procures: (['05', '06', '07', '00'].includes(baseinfo?.baseProjSetProg) || apply?.baseProjSetYear * 1 < 2023) && procures?.sections?.map(i => { | |||||
return { | |||||
...i, | |||||
baseBidName: ['05', '06', '07', '00'].includes(baseinfo?.baseProjSetProg) && i.baseBidName || '', | |||||
baseProjPurchaseWay: ['05', '06', '07', '00'].includes(baseinfo?.baseProjSetProg) && i.baseProjPurchaseWay || '', | |||||
basePurchaseCode: ['05', '06', '07', '00'].includes(baseinfo?.baseProjSetProg) && i.basePurchaseCode || '', | |||||
basePurchasingAgencies: (['05', '06', '07', '00'].includes(baseinfo?.baseProjSetProg) || apply?.baseProjSetYear * 1 < 2023) && i.basePurchasingAgencies || '', | |||||
baseUnifiedCreditCode: (['05', '06', '07', '00'].includes(baseinfo?.baseProjSetProg) || apply?.baseProjSetYear * 1 < 2023) && i.baseUnifiedCreditCode || '', | |||||
baseWinningBidTime: ['05', '06', '07', '00'].includes(baseinfo?.baseProjSetProg) && i.baseWinningBidTime || '', | |||||
baseProjPurchaseAmount: ['05', '06', '07', '00'].includes(baseinfo?.baseProjSetProg) && i.baseProjPurchaseAmount || '', | |||||
baseConsDeprt: ['05', '06', '07', '00'].includes(baseinfo?.baseProjSetProg) && i.baseConsDeprt || '', | |||||
baseConsDeprtUsci: ['05', '06', '07', '00'].includes(baseinfo?.baseProjSetProg) && i.baseConsDeprtUsci || '', | |||||
basePaymentTime: (['05', '06', '07', '00'].includes(baseinfo?.baseProjSetProg) || apply?.baseProjSetYear * 1 < 2023) && i.basePaymentTime || '', | |||||
paymentProgress: (['05', '06', '07', '00'].includes(baseinfo?.baseProjSetProg) || apply?.baseProjSetYear * 1 < 2023) && i.paymentProgress || '', | |||||
purchaseFile: ['05', '06', '07', '00'].includes(baseinfo?.baseProjSetProg) && i.purchaseFile?.length ? JSON.stringify(changFilesParam(i.purchaseFile)) : '', | |||||
biddingFile: ['05', '06', '07', '00'].includes(baseinfo?.baseProjSetProg) && i.biddingFile?.length ? JSON.stringify(changFilesParam(i.biddingFile)) : '', | |||||
purchaseContract: ['05', '06', '07', '00'].includes(baseinfo?.baseProjSetProg) && i.purchaseContract?.length ? JSON.stringify(changFilesParam(i.purchaseContract)) : '' | |||||
} | |||||
}) || [], | |||||
cimplement: { | |||||
...cimplement, | |||||
baseInitialOpinionFile: cimplement?.baseInitialOpinionFile?.length ? JSON.stringify(changFilesParam(cimplement.baseInitialOpinionFile)) : '', | |||||
baseInforLevelFile: ((['05', '06', '07', '00'].includes(baseinfo?.baseProjSetProg) && baseinfo?.baseConstructionType?.includes('01')) || !baseinfo?.baseConstructionType?.includes('01')) && cimplement?.baseInforLevelFile?.length ? JSON.stringify(changFilesParam(cimplement.baseInforLevelFile)) : '', | |||||
basePasswAssessFile: (['04', '05', '06', '07', '00'].includes(baseinfo?.baseProjSetProg) || apply?.baseProjSetYear * 1 < 2023) && cimplement?.basePasswAssessFile?.length ? JSON.stringify(changFilesParam(cimplement.basePasswAssessFile)) : '', | |||||
baseThirdAcceptFile: cimplement.baseThirdAcceptFile?.length ? JSON.stringify(changFilesParam(cimplement.baseThirdAcceptFile)) : '', | |||||
baseCheckFile: (['05', '06', '07', '00'].includes(baseinfo?.baseProjSetProg) || apply?.baseProjSetYear * 1 < 2023) && cimplement?.baseCheckFile?.length ? JSON.stringify(changFilesParam(cimplement.baseCheckFile)) : '', | |||||
baseFinanlAuditFile: ['05', '06', '07', '00'].includes(baseinfo?.baseProjSetProg) && approve?.releaseYearMoney * 1 >= 2000 && cimplement?.baseFinanlAuditFile?.length ? JSON.stringify(changFilesParam(cimplement.baseFinanlAuditFile)) : '', | |||||
baseUserConsFile: (['05', '06', '07', '00'].includes(baseinfo?.baseProjSetProg) || apply?.baseProjSetYear * 1 < 2023) && cimplement?.baseUserConsFile?.length ? JSON.stringify(changFilesParam(cimplement.baseUserConsFile)) : '', | |||||
baseEstaSummFile: cimplement?.baseEstaSummFile?.length ? JSON.stringify(changFilesParam(cimplement?.baseEstaSummFile)) : '', | |||||
baseSummReportFile: (['05', '06', '07', '00'].includes(baseinfo?.baseProjSetProg) || apply?.baseProjSetYear * 1 < 2023) && cimplement?.baseSummReportFile?.length ? JSON.stringify(changFilesParam(cimplement.baseSummReportFile)) : '', | |||||
baseFinalExpertOpinionFile: baseinfo?.baseProjSetProg === '07' && cimplement.baseFinalExpertOpinionFile?.length ? JSON.stringify(changFilesParam(cimplement?.baseFinalExpertOpinionFile)) : '', | |||||
baseEngineerPostpoFile: cimplement?.baseEngineerPostpoFile?.length ? JSON.stringify(changFilesParam(cimplement?.baseEngineerPostpoFile)) : '', | |||||
baseChangeFormFile: cimplement?.baseChangeFormFile?.length ? JSON.stringify(changFilesParam(cimplement?.baseChangeFormFile)) : '', | |||||
baseChanFile: cimplement?.baseChanFile?.length ? JSON.stringify(changFilesParam(cimplement?.baseChanFile)) : '' | |||||
} | |||||
} | |||||
}, | |||||
submitProject = async () => { | |||||
const postData = changePostData() | |||||
await save(postData) | |||||
proxy.$message.success('提交成功!') | |||||
router.go(-1) | |||||
} | |||||
onMounted(async () => { | |||||
dictionaryList.value = (await dictionary()).data | |||||
if (route.query.id) { | |||||
getDetail() | |||||
} else { | |||||
getTableData() | |||||
} | |||||
}) | |||||
</script> | |||||
<template> | |||||
<div class="footerPage"> | |||||
<el-alert | |||||
v-if="ruleForm.approvalStatus==='NOT_PASS'" | |||||
style="marginBottom:20px;" | |||||
title="审核不通过" | |||||
type="error" | |||||
:description="`审核意见:${ruleForm.auditOpinion}`" | |||||
show-icon | |||||
/> | |||||
<el-card class="box-card"> | |||||
<template #header> | |||||
<div class="card-header"> | |||||
<span>申报信息</span> | |||||
</div> | |||||
</template> | |||||
<el-form | |||||
ref="ruleFormRef" | |||||
:model="ruleForm" | |||||
:rules="rules" | |||||
label-width="auto" | |||||
class="demo-ruleForm" | |||||
status-icon | |||||
> | |||||
<el-input | |||||
v-if="!$route.query.id" | |||||
v-model="searchForm.projectName" | |||||
placeholder="搜索项目名称" | |||||
style="width: 200px;margin-left: 100px;" | |||||
class="mb-8" | |||||
> | |||||
<template #append> | |||||
<el-button icon="Search" @click="search" /> | |||||
</template> | |||||
</el-input> | |||||
<el-form-item | |||||
label="关联项目" | |||||
prop="projectId" | |||||
:label-width="100" | |||||
clas="mb-16" | |||||
> | |||||
<table-list | |||||
v-if="!route.query.id" | |||||
ref="tableListRef" | |||||
:column="column" | |||||
:height="350" | |||||
:data="data" | |||||
:total="total" | |||||
class="w-full" | |||||
row-key="id" | |||||
@radio-change="radioChange" | |||||
@get-table-data="getTableData" | |||||
> | |||||
<template #annualAccumulateAmountList="{scope}"> | |||||
<p v-for="(item,index) in scope.row.annualAccumulateAmountList" :key="index">{{ index+1 }}、{{ item.projectYear }}年投资{{ item.annualAmount }}万元</p> | |||||
</template> | |||||
</table-list> | |||||
<table-list | |||||
v-else | |||||
ref="tableListRef" | |||||
:column="column1" | |||||
:data="data" | |||||
:height="200" | |||||
:pagination="false" | |||||
class="flex-1" | |||||
><template #annualAccumulateAmountList="{scope}"> | |||||
<p v-for="(item,index) in scope.row.annualAccumulateAmountList" :key="index">{{ index+1 }}、{{ item.projectYear }}年投资{{ item.annualAmount }}万元</p> | |||||
</template></table-list> | |||||
</el-form-item> | |||||
<p class="mb-16 flex items-center"> | |||||
<span class="mr-24">支付信息</span> | |||||
<span class="text-danger text-14">温馨提示:实际支付金额请去合同信息填写</span> | |||||
</p> | |||||
<table-list | |||||
ref="tableListRef" | |||||
:column="payColumn" | |||||
:data="paymentsData" | |||||
:pagination="false" | |||||
:empty-temp="false" | |||||
class="mb-16" | |||||
> | |||||
<template #number="{scope}"> | |||||
<span>第{{ scope.$index+1 }}笔</span> | |||||
</template> | |||||
<template #planAmount="{scope}"> | |||||
{{ scope.row.planAmount }} | |||||
</template> | |||||
<template #ratio="{scope}"> | |||||
{{ scope.row.ratio }} | |||||
</template> | |||||
<template #paymentAmount="{scope}"> | |||||
{{ scope.row.paymentAmount }} | |||||
</template> | |||||
<template #paymentTime="{scope}"> | |||||
{{ scope.row.paymentTime }} | |||||
</template> | |||||
<template #actualPaymentAmount="{scope}"> | |||||
{{ scope.row.actualPaymentAmount }} | |||||
</template> | |||||
</table-list> | |||||
<p style="margin-bottom: 16px;">申报续建资金信息</p> | |||||
<el-row :gutter="20"> | |||||
<el-col :span="12"> | |||||
<el-form-item | |||||
label="预算年度" | |||||
prop="projectYear" | |||||
> | |||||
<el-date-picker | |||||
v-model="ruleForm.projectYear" | |||||
type="year" | |||||
placeholder="请选择" | |||||
format="YYYY" | |||||
value-format="YYYY" | |||||
:disabled-date="disabledDate" | |||||
@change="changeYear" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="12"> | |||||
<el-form-item | |||||
:label="`${ruleForm.projectYear||''}支付金额`" | |||||
prop="annualPaymentAmount" | |||||
> | |||||
<el-input-number | |||||
v-model="ruleForm.annualPaymentAmount" | |||||
placeholder="请填写" | |||||
:min="0" | |||||
:controls="false" | |||||
@mousewheel.prevent | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
</el-row> | |||||
<el-row :gutter="20"> | |||||
<el-col :span="12"> | |||||
<el-form-item | |||||
label="自有资金(万元)" | |||||
prop="haveAmount" | |||||
> | |||||
<el-input-number | |||||
v-model="ruleForm.haveAmount" | |||||
placeholder="请填写" | |||||
:min="0" | |||||
:controls="false" | |||||
@mousewheel.prevent | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="12"> | |||||
<el-form-item | |||||
label="政府投资-本级财政资金(万元)" | |||||
prop="govOwnFinanceAmount" | |||||
> | |||||
<el-input-number | |||||
v-model="ruleForm.govOwnFinanceAmount" | |||||
placeholder="请填写" | |||||
:min="0" | |||||
:controls="false" | |||||
@mousewheel.prevent | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
</el-row> | |||||
<el-row :gutter="20"> | |||||
<el-col :span="12"> | |||||
<el-form-item | |||||
label="政府投资-上级补助资金(万元)" | |||||
prop="govSuperiorFinanceAmount" | |||||
> | |||||
<el-input-number | |||||
v-model="ruleForm.govSuperiorFinanceAmount" | |||||
placeholder="请填写" | |||||
:min="0" | |||||
:controls="false" | |||||
@mousewheel.prevent | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="12"> | |||||
<el-form-item | |||||
label="银行贷款(万元)" | |||||
prop="bankLendingAmount" | |||||
> | |||||
<el-input-number | |||||
v-model="ruleForm.bankLendingAmount" | |||||
placeholder="请填写" | |||||
:min="0" | |||||
:controls="false" | |||||
@mousewheel.prevent | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
</el-row> | |||||
<el-row :gutter="20"> | |||||
<el-col :span="12"> | |||||
<el-form-item | |||||
label="其他" | |||||
prop="otherAmount" | |||||
> | |||||
<el-input-number | |||||
v-model="ruleForm.otherAmount" | |||||
placeholder="请填写" | |||||
:min="0" | |||||
:controls="false" | |||||
@mousewheel.prevent | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
</el-row> | |||||
<template v-if="!route.query.id"> | |||||
<p style="margin-bottom: 16px;">补充项目信息</p> | |||||
<el-collapse> | |||||
<el-collapse-item name="1" class="mb-16"> | |||||
<template #title> | |||||
<div class="collapse-title">项目基本信息</div> | |||||
</template> | |||||
<div class="pb-24"> | |||||
<basic-info | |||||
:ref="el=>formRefs['baseinfo']=el" | |||||
:detail="detailData" | |||||
:dictionary-list="dictionaryList" | |||||
:is-supplemented="true" | |||||
@get-basic-info-data="getBasicInfoData" | |||||
/> | |||||
</div> | |||||
</el-collapse-item> | |||||
<el-collapse-item name="2" class="mb-16"> | |||||
<template #title> | |||||
<div class="collapse-title">项目申报信息</div> | |||||
</template> | |||||
<div class="pb-24"> | |||||
<project-declare-info | |||||
:ref="el=>formRefs['apply']=el" | |||||
:detail="detailData" | |||||
:basic-info-data="basicInfoData" | |||||
:dictionary-list="dictionaryList" | |||||
:is-supplemented="true" | |||||
@get-pro-year="getProYear" | |||||
/> | |||||
</div> | |||||
</el-collapse-item> | |||||
<el-collapse-item v-if="!(basicInfoData?.baseConstructionType?.length===1&&basicInfoData?.baseConstructionType.includes('01'))" name="3" class="mb-16"> | |||||
<template #title> | |||||
<div class="collapse-title">项目关联信息</div> | |||||
</template> | |||||
<div class="pb-24"> | |||||
<application-info | |||||
:ref="el=>formRefs['application']=el" | |||||
:detail="detailData" | |||||
:basic-info-data="basicInfoData" | |||||
:is-supplemented="true" | |||||
/> | |||||
</div> | |||||
</el-collapse-item> | |||||
<el-collapse-item name="4" class="mb-16"> | |||||
<template #title> | |||||
<div class="collapse-title">核心业务</div> | |||||
</template> | |||||
<div class="pb-24"> | |||||
<core-business :ref="el=>formRefs['baseCore']=el" :detail="detailData" :is-supplemented="true" /> | |||||
</div> | |||||
</el-collapse-item> | |||||
<el-collapse-item v-if="basicInfoData?.baseProjSetProg!=='01'" name="5" class="mb-16"> | |||||
<template #title> | |||||
<div class="collapse-title">项目立项评审信息</div> | |||||
</template> | |||||
<div class="pb-24"> | |||||
<project-approval-info | |||||
:ref="el=>formRefs['approve']=el" | |||||
:detail="detailData" | |||||
:basic-info-data="basicInfoData" | |||||
:dictionary-list="dictionaryList" | |||||
:is-supplemented="true" | |||||
@get-approval-info-data="getApprovalInfoData" | |||||
/> | |||||
</div> | |||||
</el-collapse-item> | |||||
<el-collapse-item v-show="['05','06','07','00'].includes(basicInfoData?.baseProjSetProg)||baseProjSetYear*1<2023" name="6" class="mb-16"> | |||||
<template #title> | |||||
<div class="collapse-title">项目采购、资金支付信息</div> | |||||
</template> | |||||
<div class="pb-24"> | |||||
<purchase-info | |||||
:ref="el=>formRefs['procures']=el" | |||||
:detail="detailData" | |||||
:dictionary-list="dictionaryList" | |||||
:base-proj-set-year="baseProjSetYear" | |||||
:basic-info-data="basicInfoData" | |||||
:is-supplemented="true" | |||||
/> | |||||
</div> | |||||
</el-collapse-item> | |||||
<el-collapse-item name="7" class="mb-16"> | |||||
<template #title> | |||||
<div class="collapse-title">实施材料信息</div> | |||||
</template> | |||||
<div class="pb-24"> | |||||
<emp-materials | |||||
:ref="el=>formRefs['cimplement']=el" | |||||
:detail="detailData" | |||||
:basic-info-data="basicInfoData" | |||||
:base-proj-set-year="baseProjSetYear" | |||||
:approval-info-data="approvalInfoData" | |||||
:is-supplemented="true" | |||||
/> | |||||
</div> | |||||
</el-collapse-item> | |||||
</el-collapse> | |||||
</template> | |||||
</el-form> | |||||
</el-card> | |||||
</div> | |||||
<div class="footer"> | |||||
<el-button | |||||
type="primary" | |||||
@click="submitForm(ruleFormRef)" | |||||
> | |||||
提交 | |||||
</el-button> | |||||
<el-button @click="router.go(-1)">返回</el-button> | |||||
</div> | |||||
</template> | |||||
<style lang='less' scoped> </style> |
@@ -0,0 +1,431 @@ | |||||
<script name="expertEnroll" setup> | |||||
import { getCurrentInstance, ref, onMounted, reactive } from 'vue' | |||||
import { useRoute, useRouter } from 'vue-router' | |||||
import BasicInfo from '@/pages/expertManage/expertStore/addOrEditExpert/components/basicInfo.vue' | |||||
import EduInfo from '@/pages/expertManage/expertStore/addOrEditExpert/components/eduInfo.vue' | |||||
import JobInfo from '@/pages/expertManage/expertStore/addOrEditExpert/components/jobInfo.vue' | |||||
import ProfessionalInfo from '@/pages/expertManage/expertStore/addOrEditExpert/components/professionalInfo.vue' | |||||
import RecommendInfo from '@/pages/expertManage/expertStore/addOrEditExpert/components/recommendInfo.vue' | |||||
import { expertEdit, expertSignUp, registration } from '@/http/apis/expertManage/expertStore' | |||||
import { downloadFileUrl } from '@/utils/uploadAction.js' | |||||
import { getExpertDetail } from '@/http/apis/expertManage/expertVerify' | |||||
import { getVerificationCode } from '@/http/apis/auth' | |||||
import getTimeDiffer from '@/utils/getTimeDiffer' | |||||
import ExpertOtherInfo from '@/pages/expertManage/expertStore/addOrEditExpert/components/expertOtherInfo.vue' | |||||
const { proxy } = getCurrentInstance(), | |||||
route = useRoute(), | |||||
router = useRouter(), | |||||
formData = ref({ | |||||
basicInfo: { | |||||
// isDingUser: false | |||||
} | |||||
}), | |||||
collapseModal = ref(['1', '2', '3', '4', '5', '6']), | |||||
basicInfoRef = ref(), // 基本信息 | |||||
eduInfoRef = ref(), // 学历信息 | |||||
jobInfoRef = ref(), // 职业信息 | |||||
professionalInfoRef = ref(), // 专业信息 | |||||
recommendInfoRef = ref(), // 推荐信息 | |||||
expertOtherInfoRef = ref(), // 其他信息 | |||||
// 提交 | |||||
submitForm = async () => { | |||||
const form = [] | |||||
form.push(new Promise((resolve, reject) => { | |||||
basicInfoRef.value.validForm((valid) => { | |||||
if (valid) resolve() | |||||
}) | |||||
})) | |||||
form.push(new Promise((resolve, reject) => { | |||||
eduInfoRef.value.validForm((valid) => { | |||||
if (valid) resolve() | |||||
}) | |||||
})) | |||||
form.push(new Promise((resolve, reject) => { | |||||
jobInfoRef.value.validForm((valid) => { | |||||
if (valid) resolve() | |||||
}) | |||||
})) | |||||
form.push(new Promise((resolve, reject) => { | |||||
professionalInfoRef.value.validForm((valid) => { | |||||
if (valid) resolve() | |||||
}) | |||||
})) | |||||
form.push(new Promise((resolve, reject) => { | |||||
recommendInfoRef.value.validForm((valid) => { | |||||
if (valid) resolve() | |||||
}) | |||||
})) | |||||
form.push(new Promise((resolve, reject) => { | |||||
expertOtherInfoRef.value.validForm((valid) => { | |||||
if (valid) resolve() | |||||
}) | |||||
})) | |||||
Promise.all([...form]).then(async () => { | |||||
saveData() | |||||
}).catch(err => { | |||||
if (err) { | |||||
proxy.$message.warning(err) | |||||
} | |||||
}) | |||||
}, | |||||
saveData = async () => { | |||||
var data = { | |||||
expertUserId: route.query.id || undefined, | |||||
basicInfo: { | |||||
...basicInfoRef.value.formData, | |||||
// isDingUser: formData.value.basicInfo.isDingUser, | |||||
avatarUrl: basicInfoRef.value.formData?.avatarFile?.fileId && await downloadFileUrl(basicInfoRef.value.formData.avatarFile.fileId), | |||||
expertIntentionWorkRegions: | |||||
basicInfoRef.value.formData.expertIntentionWorkRegions?.map((i, index) => ({ | |||||
regionName: i.unionCode?.join('@@'), | |||||
regionCode: i.unionCode?.slice(-1)[0]?.split('##')[0], | |||||
regionLevel: i.unionCode?.slice(-1)[0]?.split('##')[2] | |||||
})), | |||||
expertRegionInfo: { | |||||
regionName: basicInfoRef.value.formData.expertRegionInfo?.join('@@'), | |||||
regionCode: basicInfoRef.value.formData.expertRegionInfo?.slice(-1)[0].split('##')[0], | |||||
regionLevel: basicInfoRef.value.formData.expertRegionInfo?.slice(-1)[0].split('##')[2] | |||||
}, | |||||
political: basicInfoRef.value.formData.political && [basicInfoRef.value.formData.political] || [], | |||||
expertSource: basicInfoRef.value.formData.expertSource && [basicInfoRef.value.formData.expertSource] || [], | |||||
expertType: basicInfoRef.value.formData.expertType && [basicInfoRef.value.formData.expertType] || [] | |||||
}, | |||||
eduInfo: { | |||||
...eduInfoRef.value.formData, | |||||
edu: eduInfoRef.value.formData.edu && [eduInfoRef.value.formData.edu], | |||||
degree: eduInfoRef.value.formData.degree && [eduInfoRef.value.formData.degree], | |||||
degreeCertificateFile: eduInfoRef.value.formData.degreeCertificateFile && await Promise.all( | |||||
eduInfoRef.value.formData.degreeCertificateFile && eduInfoRef.value.formData.degreeCertificateFile.map(async i => { | |||||
return { | |||||
fileName: i.name, | |||||
fileId: i.response.data.id, | |||||
url: i.fileUrlById | |||||
} | |||||
}) | |||||
) || [], | |||||
graduationCertificateFile: eduInfoRef.value.formData.graduationCertificateFile && await Promise.all( | |||||
eduInfoRef.value.formData.graduationCertificateFile && eduInfoRef.value.formData.graduationCertificateFile.map(async i => { | |||||
return { | |||||
fileName: i.name, | |||||
fileId: i.response.data.id, | |||||
url: i.fileUrlById | |||||
} | |||||
}) | |||||
) || [] | |||||
}, | |||||
jobInfo: { | |||||
...jobInfoRef.value.formData, | |||||
administrativeRank: jobInfoRef.value.formData.administrativeRank && [jobInfoRef.value.formData.administrativeRank] || [], | |||||
jobStatus: jobInfoRef.value.formData.jobStatus && [jobInfoRef.value.formData.jobStatus] || [], | |||||
companyAttribute: jobInfoRef.value.formData.companyAttribute && [jobInfoRef.value.formData.companyAttribute] || [] | |||||
}, | |||||
professionalInfo: { | |||||
...professionalInfoRef.value.formData, | |||||
goodAt: professionalInfoRef.value.formData.goodAt && [professionalInfoRef.value.formData.goodAt] || [], | |||||
titleLevel: professionalInfoRef.value.formData.titleLevel && [professionalInfoRef.value.formData.titleLevel] || [], | |||||
titleCertificateFile: professionalInfoRef.value.formData.titleCertificateFile && await Promise.all( | |||||
professionalInfoRef.value.formData.titleCertificateFile && professionalInfoRef.value.formData.titleCertificateFile.map(async i => { | |||||
return { | |||||
fileName: i.name, | |||||
fileId: i.response.data.id, | |||||
url: i.fileUrlById | |||||
} | |||||
}) | |||||
) || [], | |||||
technicalExpertise: professionalInfoRef.value.formData.technicalExpertise && professionalInfoRef.value.formData.technicalExpertise.map(i => { | |||||
return { | |||||
tagCode: i.split('##')[1], | |||||
tagName: i.split('##')[0] | |||||
} | |||||
}), | |||||
industrySector: professionalInfoRef.value.formData.industrySector && professionalInfoRef.value.formData.industrySector.map(i => { | |||||
return { | |||||
tagCode: i.split('##')[1], | |||||
tagName: i.split('##')[0] | |||||
} | |||||
}) | |||||
}, | |||||
recommendInfo: { | |||||
...recommendInfoRef.value.formData, | |||||
recommendedWay: recommendInfoRef.value.formData.recommendedWay && [recommendInfoRef.value.formData.recommendedWay] || [], | |||||
recommendationProofFile: recommendInfoRef.value.formData.recommendationProofFile && await Promise.all( | |||||
recommendInfoRef.value.formData.recommendationProofFile && recommendInfoRef.value.formData.recommendationProofFile.map(async i => { | |||||
return { | |||||
fileName: i.name, | |||||
fileId: i.response.data.id, | |||||
url: i.fileUrlById | |||||
} | |||||
}) | |||||
) || [] | |||||
}, | |||||
expertOtherInfo: { | |||||
...expertOtherInfoRef.value.formData, | |||||
other: expertOtherInfoRef.value.formData.other && expertOtherInfoRef.value.formData.other.map(i => { | |||||
return { | |||||
tagCode: i.split('##')[1], | |||||
tagName: i.split('##')[0] | |||||
} | |||||
}) | |||||
} | |||||
} | |||||
if (route.name === 'expertEnroll') { | |||||
showSmsDiaglog(data) | |||||
} else { | |||||
if (!route.query.id) { | |||||
await expertSignUp(data) | |||||
proxy.$message.success('专家新增成功') | |||||
router.go(-1) | |||||
} else { | |||||
await expertEdit(data) | |||||
proxy.$message.success('专家编辑成功') | |||||
router.go(-1) | |||||
} | |||||
} | |||||
}, | |||||
// 专家报名-短信验证 | |||||
smsDialogData = reactive({ | |||||
visible: false, | |||||
data: {} | |||||
}), | |||||
showSmsDiaglog = (data) => { | |||||
smsDialogData.data = data | |||||
smsDialogData.visible = true | |||||
}, | |||||
smsDialogFormRef = ref(), | |||||
smsDialogForm = ref({ | |||||
verificationCode: '' | |||||
}), | |||||
smsDialogRules = { | |||||
'verificationCode': [{ required: true, message: '请输入' }] | |||||
}, | |||||
smsDialogLoading = ref(false), | |||||
submitSms = async (formEl) => { | |||||
if (!formEl) { | |||||
return | |||||
} | |||||
formEl.validate(async (valid) => { | |||||
if (valid) { | |||||
await registration({ | |||||
...smsDialogData.data, | |||||
verificationCode: smsDialogForm.value.verificationCode | |||||
}) | |||||
proxy.$message.success('提交成功') | |||||
router.go(0) | |||||
} | |||||
} | |||||
) | |||||
}, | |||||
timer = ref(null), | |||||
count = ref(0), | |||||
getVerificationCodeFunc = async () => { | |||||
await getVerificationCode({ mobile: basicInfoRef.value.formData.phoneNo, verificationType: 'EXPERT_REGISTER' }) | |||||
proxy.$message.success('验证码已发送') | |||||
const TIME_COUNT = 60 | |||||
if (!timer.value) { | |||||
count.value = TIME_COUNT | |||||
timer.value = setInterval(() => { | |||||
if (count.value > 0 && count.value <= TIME_COUNT) { | |||||
count.value-- | |||||
} else { | |||||
clearInterval(timer.value) | |||||
timer.value = null | |||||
} | |||||
}, 1000) | |||||
} | |||||
}, | |||||
// 获取详情 | |||||
getDetail = async () => { | |||||
const res = await getExpertDetail({ expertUserId: route.query.id }) | |||||
basicInfoRef.value.setFormData(res.data.basicInfo) | |||||
eduInfoRef.value.setFormData(res.data.eduInfo) | |||||
jobInfoRef.value.setFormData(res.data.jobInfo) | |||||
professionalInfoRef.value.setFormData(res.data.professionalInfo) | |||||
recommendInfoRef.value.setFormData(res.data.recommendInfo) | |||||
expertOtherInfoRef.value.setFormData(res.data.expertOtherInfo) | |||||
}, | |||||
// 是否失效 | |||||
isFailure = ref(false), | |||||
getIsFailure = () => { | |||||
const time = window.atob(route.query.time) | |||||
if (getTimeDiffer(new Date(), new Date(time * 1), 'd') > 3) { | |||||
isFailure.value = true | |||||
} | |||||
} | |||||
onMounted(() => { | |||||
if (route.query.time) { | |||||
getIsFailure() | |||||
setInterval(() => { | |||||
getIsFailure() | |||||
}, 10000) | |||||
} else { | |||||
isFailure.value = true | |||||
} | |||||
if (route.query.id) { | |||||
getDetail() | |||||
} | |||||
}) | |||||
</script> | |||||
<template> | |||||
<div class="expertEnroll footerPage" :class="{ 'relative':route.path === 'expertEnroll'}"> | |||||
<div class="top">丽水市信息化专家报名</div> | |||||
<template v-if="!isFailure"> | |||||
<div class="px-[107px] mt-[-60px]"> | |||||
<el-collapse v-model="collapseModal"> | |||||
<el-collapse-item name="1" class="mb-16"> | |||||
<template #title> | |||||
<div class="collapse-title">基本信息</div> | |||||
</template> | |||||
<div class="pb-24"> | |||||
<basic-info ref="basicInfoRef" :basic-info="formData.basicInfo" /> | |||||
</div> | |||||
</el-collapse-item> | |||||
<el-collapse-item name="2" class="mb-16"> | |||||
<template #title> | |||||
<div class="collapse-title">学历信息</div> | |||||
</template> | |||||
<div class="pb-24"> | |||||
<edu-info ref="eduInfoRef" /> | |||||
</div> | |||||
</el-collapse-item> | |||||
<el-collapse-item name="3" class="mb-16"> | |||||
<template #title> | |||||
<div class="collapse-title">职业信息</div> | |||||
</template> | |||||
<div class="pb-24"> | |||||
<job-info ref="jobInfoRef" /> | |||||
</div> | |||||
</el-collapse-item> | |||||
<el-collapse-item name="4" class="mb-16"> | |||||
<template #title> | |||||
<div class="collapse-title">专业信息</div> | |||||
</template> | |||||
<div class="pb-24"> | |||||
<professional-info ref="professionalInfoRef" /> | |||||
</div> | |||||
</el-collapse-item> | |||||
<el-collapse-item name="5" class="mb-16"> | |||||
<template #title> | |||||
<div class="collapse-title">推荐信息</div> | |||||
</template> | |||||
<div class="pb-24"> | |||||
<recommend-info ref="recommendInfoRef" /> | |||||
</div> | |||||
</el-collapse-item> | |||||
<el-collapse-item name="6" class="mb-16"> | |||||
<template #title> | |||||
<div class="collapse-title">其他信息</div> | |||||
</template> | |||||
<div class="pb-24"> | |||||
<expert-other-info ref="expertOtherInfoRef" /> | |||||
</div> | |||||
</el-collapse-item> | |||||
</el-collapse> | |||||
</div> | |||||
<div class="footer"> | |||||
<el-button | |||||
type="primary" | |||||
@click="submitForm" | |||||
> | |||||
提交 | |||||
</el-button> | |||||
<el-button @click="router.go(-1)">取消</el-button> | |||||
</div> | |||||
</template> | |||||
<template v-else> | |||||
<img src="@/assets/images/link-failure-img.png" style="width: 320px;height: 245px;margin: 160px auto 0" /> | |||||
<p style="color: #83868C;" class="mt-32 text-19 text-center">链接已失效,请联系管理员</p> | |||||
</template> | |||||
<el-dialog | |||||
:model-value="smsDialogData.visible" | |||||
title="短信验证" | |||||
width="400px" | |||||
destroy-on-close | |||||
@close="smsDialogData.visible=false" | |||||
> | |||||
<el-form | |||||
ref="smsDialogFormRef" | |||||
:model="smsDialogForm" | |||||
:rules="smsDialogRules" | |||||
label-width="auto" | |||||
label-suffix=":" | |||||
> | |||||
<el-form-item label="手机号"> | |||||
<span>{{ basicInfoRef.formData.phoneNo }}</span> | |||||
</el-form-item> | |||||
<el-form-item label="验证码" prop="verificationCode"> | |||||
<el-input v-model="smsDialogForm.verificationCode" placeholder="请输入验证码"> | |||||
<template #suffix> | |||||
<a v-if="!count" class="itemBlue" @click="getVerificationCodeFunc"> 获取验证码</a> | |||||
<span v-else class="itemBlue">{{ count }}</span> | |||||
</template> | |||||
</el-input> | |||||
</el-form-item> | |||||
</el-form> | |||||
<template #footer> | |||||
<el-button | |||||
type="primary" | |||||
:loading="smsDialogLoading" | |||||
@click="submitSms(smsDialogFormRef)" | |||||
> | |||||
提交 | |||||
</el-button> | |||||
<el-button | |||||
@click="smsDialogData.visible=false" | |||||
> | |||||
关闭 | |||||
</el-button> | |||||
</template> | |||||
</el-dialog> | |||||
</div> | |||||
</template> | |||||
<style lang="less" scoped> | |||||
.expertEnroll{ | |||||
.top{ | |||||
background: url("@/assets/images/expertTopBg.png"); | |||||
background-size: 100% 100%; | |||||
background-repeat: no-repeat; | |||||
padding-top: 60px; | |||||
padding-bottom: 117px; | |||||
font-size: 53px; | |||||
font-weight: 600; | |||||
color: #FFFFFF; | |||||
text-align: center; | |||||
line-height: 75px; | |||||
} | |||||
.header{ | |||||
height: 60px; | |||||
display: flex; | |||||
justify-content: center; | |||||
align-items: center; | |||||
background-color: #fff; | |||||
margin-bottom: 15px; | |||||
font-size: 20px; | |||||
} | |||||
:deep(.el-collapse) { | |||||
.el-collapse-item__header { | |||||
padding: 0px 16px; | |||||
font-size: 14px; | |||||
} | |||||
.el-collapse-item__content { | |||||
padding: 16px 16px 16px 0px; | |||||
// margin-left: -50px; | |||||
} | |||||
.el-collapse-item__header.is-active { | |||||
border-bottom: 1px solid rgba(0, 0, 0, 0.1); | |||||
} | |||||
.collapse-title { | |||||
flex: 1 0 90%; | |||||
order: 1; | |||||
.el-collapse-item__header { | |||||
flex: 1 0 auto; | |||||
order: -1; | |||||
} | |||||
.el-input-number { | |||||
width: 150px !important; | |||||
} | |||||
} | |||||
} | |||||
} | |||||
</style> |
@@ -0,0 +1,124 @@ | |||||
<script name="leaveDialog" setup> | |||||
import { ref, getCurrentInstance, watch } from 'vue' | |||||
import { leaveSave } from '@/http/apis/expertManage/expertReview' | |||||
import { storeToRefs } from 'pinia' | |||||
import store from '@/store' | |||||
const userInfo = storeToRefs(store.userStore).userInfo | |||||
const | |||||
{ proxy } = getCurrentInstance(), | |||||
props = defineProps({ | |||||
visible: { | |||||
type: Boolean, | |||||
default: false, | |||||
required: true | |||||
}, | |||||
data: { | |||||
type: Object, | |||||
default: undefined | |||||
}, | |||||
title: { | |||||
type: String, | |||||
default: undefined | |||||
} | |||||
}), | |||||
emits = defineEmits(['close']), | |||||
formRef = ref(), | |||||
form = ref({ | |||||
}), | |||||
rules = { | |||||
postscript: [{ required: true, message: '请输入请假原因', trigger: 'blur' }] | |||||
}, | |||||
submit = async formEl => { | |||||
if (!formEl) { | |||||
return | |||||
} | |||||
await formEl.validate(async valid => { | |||||
if (valid) { | |||||
await leaveSave({ | |||||
...form.value, | |||||
type: 3, | |||||
expertId: props.data.expertId || userInfo.value.userId, | |||||
meetingId: props.data.meetingId | |||||
}) | |||||
proxy.$message.success('提交成功!') | |||||
emits('close', true) | |||||
} | |||||
}) | |||||
} | |||||
watch( | |||||
() => props.visible, | |||||
async val => { | |||||
if (val) { | |||||
console.log(props.data) | |||||
} else { | |||||
formRef.value.resetFields() | |||||
form.value = {} | |||||
} | |||||
} | |||||
) | |||||
</script> | |||||
<template> | |||||
<el-dialog | |||||
:model-value="visible" | |||||
:title="props.title||`填写请假原因-${data?.meetingName}`" | |||||
width="600px" | |||||
destroy-on-close | |||||
@close="emits('close')" | |||||
> | |||||
<el-form | |||||
ref="formRef" | |||||
:model="form" | |||||
:rules="rules" | |||||
label-width="auto" | |||||
label-suffix=":" | |||||
> | |||||
<el-row> | |||||
<template v-if="data?.connecter"> | |||||
<el-col :span="24"> | |||||
<el-form-item | |||||
label="联系人" | |||||
> | |||||
{{ data?.connecter }} | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="24"> | |||||
<el-form-item | |||||
label="联系方式" | |||||
>{{ data?.contact }}</el-form-item> | |||||
</el-col> | |||||
</template> | |||||
<el-col :span="24"> | |||||
<el-form-item | |||||
label="请假原因" | |||||
prop="postscript" | |||||
> | |||||
<el-input | |||||
v-model="form.postscript" | |||||
maxlength="200" | |||||
placeholder="请输入" | |||||
show-word-limit | |||||
type="textarea" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
</el-row> | |||||
</el-form> | |||||
<template #footer> | |||||
<div class="flex justify-center"> | |||||
<el-button | |||||
class="ml-22" | |||||
type="primary" | |||||
@click="submit(formRef)" | |||||
> | |||||
提交 | |||||
</el-button> | |||||
<el-button | |||||
@click="emits('close')" | |||||
> | |||||
关闭 | |||||
</el-button> | |||||
</div> | |||||
</template> | |||||
</el-dialog> | |||||
</template> |
@@ -0,0 +1,171 @@ | |||||
<script name="meetingsLeaveDialog" setup> | |||||
import { ref, reactive, watch, h } from 'vue' | |||||
import meetingProjectDialog from '../../reviewMeeting/components/meetingProjectDialog.vue' | |||||
import store from '@/store' | |||||
import leaveDialog from './leaveDialog.vue' | |||||
import { meetingListForLeave } from '@/http/apis/expertManage/expertReview' | |||||
import { storeToRefs } from 'pinia' | |||||
const props = defineProps({ | |||||
visible: { | |||||
type: Boolean, | |||||
default: false, | |||||
required: true | |||||
} | |||||
}), | |||||
userInfo = storeToRefs(store.userStore).userInfo || {}, | |||||
emits = defineEmits(['close']), | |||||
column = reactive([ | |||||
{ | |||||
label: '序号', | |||||
type: 'index', | |||||
width: '60' | |||||
}, | |||||
{ | |||||
label: '会议名称', | |||||
key: 'meetingName', | |||||
prop: 'meetingName', | |||||
minWidth: '180', | |||||
showOverflowTooltip: true | |||||
}, | |||||
{ | |||||
label: '评审类型', | |||||
key: 'meetingTypeName', | |||||
prop: 'meetingTypeName' | |||||
}, | |||||
{ | |||||
label: '评审项目', | |||||
key: 'projectName', | |||||
slot: 'projectName', | |||||
minWidth: '80' | |||||
}, | |||||
{ | |||||
label: '联系人/联系方式', | |||||
key: 'contact', | |||||
prop: 'contact', | |||||
minWidth: '180', | |||||
render: row => h('span', row.connecter + '/' + row.contact) | |||||
}, | |||||
{ | |||||
label: '是否参与', | |||||
key: 'isAbsent', | |||||
prop: 'isAbsent', | |||||
width: '80', | |||||
render: row => h('span', row.expertStatus === 3 || row.expertStatus === 5 ? '是' : '否') | |||||
}, | |||||
{ | |||||
label: '是否请假', | |||||
key: 'isAbsent', | |||||
prop: 'isAbsent', | |||||
width: '80', | |||||
render: row => h('span', row.expertStatus === 5 ? '是' : '否') | |||||
}, | |||||
{ | |||||
label: '会议状态', | |||||
key: 'status', | |||||
prop: 'status', | |||||
width: '80', | |||||
render: row => [ | |||||
h('span', { | |||||
class: ['dot mr-4', `${row.status === 1 ? 'bg-success' : row.status === 3 ? 'bg-danger' : ''}`] | |||||
}), | |||||
h( | |||||
'span', | |||||
{ | |||||
class: `${row.status === 1 ? 'text-success' : row.status === 3 ? 'text-danger' : ''}` | |||||
}, | |||||
row.status === 1 ? '正常' : '已取消' | |||||
) | |||||
] | |||||
}, | |||||
{ | |||||
label: '评审时间', | |||||
key: 'startTime', | |||||
prop: 'startTime', | |||||
width: '280', | |||||
render: row => h('span', row.startTime + '~' + row.endTime) | |||||
}, | |||||
{ | |||||
label: '操作', | |||||
slot: 'action', | |||||
width: '80', | |||||
fixed: 'right' | |||||
} | |||||
]), | |||||
tableData = ref(), | |||||
total = ref(0), | |||||
tableListRef = ref(), | |||||
getTableData = async (pageParams = tableListRef.value?.pageParams) => { | |||||
const res = await meetingListForLeave({ | |||||
...pageParams, | |||||
expertId: userInfo.value.userId | |||||
}) | |||||
total.value = res.data.total | |||||
tableData.value = res.data.records | |||||
}, | |||||
// 查看项目 | |||||
viewProject = (data) => { | |||||
meetingProjectDialogData.value.visible = true | |||||
meetingProjectDialogData.value.meetingId = data.meetingId | |||||
}, | |||||
meetingProjectDialogData = ref({ | |||||
visible: false, | |||||
meetingId: undefined | |||||
}), | |||||
closeMeetingProjectDialog = () => { | |||||
meetingProjectDialogData.value.visible = false | |||||
}, | |||||
// 请假 | |||||
leaveDialogData = reactive({ | |||||
visible: false, | |||||
data: undefined | |||||
}), | |||||
leave = (data) => { | |||||
leaveDialogData.visible = true | |||||
leaveDialogData.data = data | |||||
}, | |||||
closeLeaveDialog = (flag) => { | |||||
leaveDialogData.visible = false | |||||
flag && getTableData() | |||||
} | |||||
watch( | |||||
() => props.visible, | |||||
async val => { | |||||
if (val) { | |||||
getTableData() | |||||
} | |||||
} | |||||
) | |||||
</script> | |||||
<template> | |||||
<el-dialog | |||||
:model-value="visible" | |||||
title="会议请假" | |||||
width="80%" | |||||
@close="emits('close')" | |||||
> | |||||
<table-list | |||||
ref="tableListRef" | |||||
:column="column" | |||||
:total="total" | |||||
:data="tableData" | |||||
@get-table-data="getTableData" | |||||
> | |||||
<template #projectName="{scope}"> | |||||
<a @click="viewProject(scope.row)">查看</a> | |||||
</template> | |||||
<template #action="{scope}"> | |||||
<a v-if="scope.row.expertStatus !== 5" @click="leave(scope.row)">请假</a> | |||||
<span v-else>-</span> | |||||
</template> | |||||
</table-list> | |||||
<template #footer> | |||||
<span class="dialog-footer"> | |||||
<el-button @click="emits('close')">关闭</el-button> | |||||
</span> | |||||
</template> | |||||
</el-dialog> | |||||
<meeting-project-dialog :visible="meetingProjectDialogData.visible" :meeting-id="meetingProjectDialogData.meetingId" @close="closeMeetingProjectDialog" /> | |||||
<leave-dialog :visible="leaveDialogData.visible" :data="leaveDialogData.data" @close="closeLeaveDialog" /> | |||||
</template> | |||||
@@ -0,0 +1,88 @@ | |||||
<script setup name="memberOpinion"> | |||||
import store from '@/store' | |||||
import Accessory from '@/components/accessory/index.vue' | |||||
defineProps({ | |||||
memberOpinions: Array | |||||
}) | |||||
const { reviewResultOptions } = store.dictStore.globalDicts || {} | |||||
</script> | |||||
<template> | |||||
<div class="memberOpinion"> | |||||
<div v-for="(item,index) in memberOpinions" :key="index" class="box mb-16"> | |||||
<div class="flex items-center justify-between title"> | |||||
<p class="name font-bold flex items-center"> | |||||
<span>{{ item.creator }}</span> | |||||
<el-tag v-if="item.isFinal" class="ml-8">最终评审意见</el-tag> | |||||
</p> | |||||
<p class="time"> | |||||
<svg-icon name="time" class="mr-2" /> | |||||
<span>{{ item.createOn }}</span> | |||||
</p> | |||||
</div> | |||||
<div class="content"> | |||||
<div v-for="(option,key) in item.reviewTemplateOptions" :key="key" class="item"> | |||||
<p class="label">{{ option.title }}:</p> | |||||
<div> | |||||
<p class="value">{{ option.optionsValue }}。</p> | |||||
<p class="value">{{ option.otherAdvice }}</p> | |||||
</div> | |||||
</div> | |||||
<div class="item"> | |||||
<p class="label">其他意见或建议:</p> | |||||
<p class="value">{{ item. otherAdvice }}</p> | |||||
</div> | |||||
<div class="item"> | |||||
<p class="label">附件:</p> | |||||
<p class="value"> | |||||
<accessory :file-name="item.attachFile?.originalFileName" :file-id="item?.attachFileId" /> | |||||
</p> | |||||
</div> | |||||
<div class="item"> | |||||
<p class="label">评审结果:</p> | |||||
<p class="value "> | |||||
<span | |||||
:class="`dot ${item.reviewResult===1?'bg-success':item.reviewResult===2?'bg-warning':'bg-danger'}`" | |||||
></span> | |||||
<span>{{ reviewResultOptions[item.reviewResult] }}</span> | |||||
</p> | |||||
</div> | |||||
</div> | |||||
</div> | |||||
</div> | |||||
</template> | |||||
<style lang="less"> | |||||
.memberOpinion{ | |||||
.box{ | |||||
background: #FFFFFF; | |||||
box-shadow: 0px 3px 6px 0px rgba(62,99,170,0.06); | |||||
border-radius: 4px; | |||||
border: 1px solid #D8DADF; | |||||
padding: 24px; | |||||
.title{ | |||||
margin-bottom: 24px; | |||||
.time{ | |||||
display: flex; | |||||
align-items: center; | |||||
color: rgba(0,0,0,0.45); | |||||
} | |||||
} | |||||
.content{ | |||||
.item{ | |||||
display: flex; | |||||
align-items: center; | |||||
&:not(:last-of-type){ | |||||
margin-bottom: 8px; | |||||
} | |||||
} | |||||
.label{ | |||||
color: rgba(0,0,0,0.45); | |||||
} | |||||
.value{ | |||||
color: rgba(0,0,0,0.65); | |||||
} | |||||
} | |||||
} | |||||
} | |||||
</style> |
@@ -0,0 +1,188 @@ | |||||
<script setup name="projectList"> | |||||
import { reactive } from 'vue' | |||||
import store from '@/store' | |||||
import noData from '@/components/noData/index.vue' | |||||
const { projectTypeOptions, businessTerritory, meetingTypeOptions } = store.dictStore.globalDicts || {}, | |||||
props = defineProps({ | |||||
listData: Array, | |||||
// 分页 | |||||
pageSizes: { | |||||
type: Array, | |||||
default: () => [10, 20, 30, 40] | |||||
}, | |||||
total: { | |||||
type: Number, | |||||
default: 0 | |||||
}, | |||||
small: { | |||||
type: Boolean, | |||||
default: false | |||||
} | |||||
}), | |||||
emits = defineEmits(['getTableData', 'preExamDeclare', 'toDetail']), | |||||
// 分页 | |||||
pageParams = reactive({ | |||||
pageNumber: 1, | |||||
pageSize: props.pageSizes[0] | |||||
}), | |||||
handleSizeChange = () => { | |||||
emits('getTableData', pageParams) | |||||
}, | |||||
handleCurrentChange = () => { | |||||
emits('getTableData', pageParams) | |||||
}, | |||||
goToDetail = (item) => { | |||||
if (new Date().getTime() >= new Date(item.reviewTime).getTime() && (!item.reviewed || (item.isHeadman && item.reviewed < 2))) { | |||||
emits('toDetail', item, 1) | |||||
} else { | |||||
emits('toDetail', item, 2) | |||||
} | |||||
} | |||||
defineExpose({ pageParams }) | |||||
</script> | |||||
<template> | |||||
<div class="projectList"> | |||||
<template v-if="listData?.length"> | |||||
<div v-for="(item,index) in listData" :key="index" class="list"> | |||||
<div class="left"> | |||||
<svg-icon | |||||
name="projectIcon" | |||||
class="icon" | |||||
/> | |||||
<div class="info"> | |||||
<div class="tit"> | |||||
<p class="mb-4 pointTit" @click="goToDetail(item)">{{ item.projectName }}</p> | |||||
<el-tag v-if="item.bizDomain">{{ businessTerritory[item.bizDomain] }}</el-tag> | |||||
</div> | |||||
<el-row :gutter="4"> | |||||
<el-col :span="6" class="mb-8"> | |||||
<span class="label">申报单位:</span> | |||||
<span class="value">{{ item.buildOrgName || '-' }}</span> | |||||
</el-col> | |||||
<el-col :span="6" class="mb-8"> | |||||
<span class="label">项目类型:</span> | |||||
<span class="value">{{ projectTypeOptions[item.projectType] || '-' }}</span> | |||||
</el-col> | |||||
<el-col :span="6" class="mb-8"> | |||||
<span class="label">申报金额:</span> | |||||
<span class="value">{{ item.declaredAmount || '-' }}万元</span> | |||||
</el-col> | |||||
<el-col :span="6" class="mb-8"> | |||||
<span class="label">预算年度:</span> | |||||
<span class="value">{{ item.projectYear }}年</span> | |||||
</el-col> | |||||
<el-col :span="12" class="mb-8"> | |||||
<span class="label">评审时间:</span> | |||||
<span class="value">{{ item.reviewTime }}~{{ item.endReviewTime }}</span> | |||||
</el-col> | |||||
<el-col :span="6" class="mb-8"> | |||||
<span class="label">评审类型:</span> | |||||
<span class="value">{{ meetingTypeOptions[item.reviewType] }}</span> | |||||
</el-col> | |||||
<el-col :span="6" class="mb-8"> | |||||
<span class="label">联系人:</span> | |||||
<span class="value">{{ item.connecter }}</span> | |||||
</el-col> | |||||
<el-col :span="6" class="mb-8"> | |||||
<span class="label">联系方式:</span> | |||||
<span class="value">{{ item.contact }}</span> | |||||
</el-col> | |||||
</el-row> | |||||
</div> | |||||
</div> | |||||
<div class="right"> | |||||
<a v-if="new Date().getTime()>=new Date(item.reviewTime).getTime()&&(!item.reviewed||(item.isHeadman&&item.reviewed<2))" @click="emits('toDetail',item,1)">处理</a> | |||||
<a v-else @click="emits('toDetail',item,2)">详情</a> | |||||
</div> | |||||
</div> | |||||
</template> | |||||
<noData v-else /> | |||||
<el-pagination | |||||
v-model:currentPage="pageParams.pageNumber" | |||||
v-model:page-size="pageParams.pageSize" | |||||
:small="small" | |||||
background | |||||
:page-sizes="props.pageSizes" | |||||
layout="total, sizes, prev, pager, next" | |||||
:total="props.total" | |||||
@size-change="handleSizeChange" | |||||
@current-change="handleCurrentChange" | |||||
/> | |||||
</div> | |||||
</template> | |||||
<style lang="less"> | |||||
.projectList { | |||||
.list { | |||||
display: flex; | |||||
align-items: center; | |||||
justify-content: space-between; | |||||
font-size: 14px; | |||||
padding: 16px; | |||||
box-shadow: inset 0px -1px 0px 0px #D8DADF; | |||||
.left { | |||||
display: flex; | |||||
flex: 1; | |||||
.icon { | |||||
font-size: 44px; | |||||
margin-right: 24px; | |||||
} | |||||
.info { | |||||
flex: 1; | |||||
.tit { | |||||
font-weight: 400; | |||||
color: rgba(0, 0, 0, 0.85); | |||||
margin: 11px 0 16px; | |||||
} | |||||
.label { | |||||
color: rgba(0, 0, 0, 0.45); | |||||
} | |||||
.value { | |||||
color: rgba(0, 0, 0, 0.65); | |||||
} | |||||
.statusTag { | |||||
font-weight: 400; | |||||
line-height: 18px; | |||||
border-radius: 4px; | |||||
display: inline-block; | |||||
padding: 4px; | |||||
&.status-warning { | |||||
color: #FFA43D; | |||||
background: rgba(255, 164, 61, 0.06); | |||||
} | |||||
&.status-success { | |||||
color: #4ECB74; | |||||
background: rgba(78,203,116,0.06); | |||||
} | |||||
&.status-danger { | |||||
color: #FF3B30; | |||||
background: rgba(255,59,48,0.06); | |||||
} | |||||
} | |||||
} | |||||
} | |||||
.right{ | |||||
display: flex; | |||||
flex-direction: column; | |||||
align-items: center; | |||||
a{ | |||||
margin:0 | |||||
} | |||||
} | |||||
} | |||||
.el-pagination { | |||||
padding: 16px 16px 0 16px; | |||||
flex-wrap: wrap; | |||||
justify-content: flex-end; | |||||
} | |||||
} | |||||
</style> |
@@ -0,0 +1,157 @@ | |||||
<script name="reviewCommentsDialog" setup> | |||||
import { ref, onMounted } from 'vue' | |||||
import { fileFormatVerification, handleFileSuccess, handleFileError, handleFilePreview, fileTypes, fileDesc } from '@/utils/uploadAction.js' | |||||
import store from '@/store' | |||||
const | |||||
uploadUrl = store.dictStore.uploadUrl, | |||||
props = defineProps({ | |||||
templateData: Object | |||||
}), | |||||
formRef = ref(), | |||||
form = ref({ | |||||
templates: [], | |||||
attachments: [] | |||||
}), | |||||
rules = { | |||||
otherAdvice: [{ required: true, message: '请输入意见', trigger: 'blur' }], | |||||
reviewResult: [{ required: true, message: '请选择评审结果', trigger: 'blur' }] | |||||
}, | |||||
// 校验 | |||||
validForm = (callback) => { | |||||
formRef.value.validate(valid => { | |||||
callback(valid) | |||||
}) | |||||
} | |||||
onMounted(async () => { | |||||
form.value.templates = props.templateData.templates.map(i => { | |||||
return { | |||||
optionSerialNo: undefined, | |||||
otherAdvice: '', | |||||
questionSerialNo: i.serialNo | |||||
} | |||||
}) | |||||
form.value.templateId = props.templateData.templateId | |||||
}) | |||||
defineExpose({ validForm, form }) | |||||
</script> | |||||
<template> | |||||
<el-form | |||||
ref="formRef" | |||||
:model="form" | |||||
:rules="rules" | |||||
label-width="auto" | |||||
label-suffix=":" | |||||
label-position="top" | |||||
class="reviewForm" | |||||
> | |||||
<el-row> | |||||
<template v-if="form.templates?.length"> | |||||
<el-col | |||||
v-for="(item,index) in templateData.templates" | |||||
:key="index" | |||||
:span="24" | |||||
> | |||||
<el-form-item | |||||
:label="item.title" | |||||
:prop="`templates[${index}].optionSerialNo`" | |||||
:rules="[{required:true,message:'请选择'}]" | |||||
> | |||||
<el-checkbox-group v-if="item.optionType===2" v-model="form.templates[index].optionSerialNo"> | |||||
<el-checkbox | |||||
v-for="(option,key) in item.options" | |||||
:key="key" | |||||
:label="option.serialNo" | |||||
>{{ option.option }}</el-checkbox> | |||||
</el-checkbox-group> | |||||
<el-radio-group | |||||
v-else | |||||
v-model="form.templates[index].optionSerialNo" | |||||
class="myWrap" | |||||
> | |||||
<el-radio | |||||
v-for="(option,key) in item.options" | |||||
:key="key" | |||||
:label="option.serialNo" | |||||
>{{ option.option }}</el-radio> | |||||
</el-radio-group> | |||||
</el-form-item> | |||||
<el-form-item | |||||
:prop="`templates[${index}].otherAdvice`" | |||||
> | |||||
<el-input | |||||
v-model="form.templates[index].otherAdvice" | |||||
:rows="2" | |||||
type="textarea" | |||||
:placeholder="`请输入${item.title}的其他意见或建议`" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
</template> | |||||
<el-col :span="24"> | |||||
<el-form-item | |||||
label="其他意见或建议" | |||||
prop="otherAdvice" | |||||
> | |||||
<el-input | |||||
v-model="form.otherAdvice" | |||||
:rows="2" | |||||
maxlength="200" | |||||
type="textarea" | |||||
show-word-limit | |||||
placeholder="请输入其他意见或建议" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="24"> | |||||
<el-form-item | |||||
label="附件" | |||||
prop="attachments" | |||||
> | |||||
<el-upload | |||||
v-model:file-list="form.attachments" | |||||
class="w-full" | |||||
:action="uploadUrl" | |||||
:on-success="res => handleFileSuccess(res, form.attachments,true)" | |||||
:on-error="handleFileError" | |||||
:before-upload="file=>fileFormatVerification(file, {types: fileTypes})" | |||||
:accept="fileTypes.map(i=>`.${i}`).join(',')" | |||||
:limit="1" | |||||
:on-preview="handleFilePreview" | |||||
> | |||||
<el-button type="primary" class="mr-4">上传附件</el-button> | |||||
<template #tip> | |||||
<div class="el-upload__tip">支持{{ fileDesc }}文件</div> | |||||
</template> | |||||
</el-upload> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="24" class="result"> | |||||
<el-form-item | |||||
label="评审结果" | |||||
prop="reviewResult" | |||||
class="mb-0" | |||||
> | |||||
<el-radio-group | |||||
v-model="form.reviewResult" | |||||
class="ml-4" | |||||
> | |||||
<el-radio :label="1">评审通过</el-radio> | |||||
<el-radio :label="2">通过需调整</el-radio> | |||||
<el-radio :label="3">修改方案后重新评审</el-radio> | |||||
</el-radio-group> | |||||
</el-form-item> | |||||
</el-col> | |||||
</el-row> | |||||
</el-form> | |||||
</template> | |||||
<style lang="less"> | |||||
.reviewForm{ | |||||
.result{ | |||||
background: rgba(0,87,255,0.06); | |||||
border-radius: 4px; | |||||
border: 1px solid #0057FF; | |||||
padding:24px 24px 0; | |||||
} | |||||
} | |||||
</style> |
@@ -0,0 +1,141 @@ | |||||
<script name="fillReviewComments" setup> | |||||
import { getCurrentInstance, onMounted, ref } from 'vue' | |||||
import { useRouter, useRoute } from 'vue-router' | |||||
import reviewComments from '../components/reviewComments.vue' | |||||
import memberOpinion from '../components/memberOpinion.vue' | |||||
import { template } from '@/http/apis/expertManage/reviewTemplateConfig' | |||||
import { listForGroupLeader, save, templatesById } from '@/http/apis/expertManage/expertReview' | |||||
const { proxy } = getCurrentInstance(), | |||||
router = useRouter(), | |||||
route = useRoute(), | |||||
// 获取模板 | |||||
templateData = ref(), | |||||
getTemplate = async () => { | |||||
const res = await template({ templateType: route.query.reviewType, regionCode: route.query.regionCode }) | |||||
templateData.value = res.data | |||||
reviewVisible.value = true | |||||
}, | |||||
reviewVisible = ref(false), | |||||
// 提交 | |||||
loading = ref(false), | |||||
reviewCommentsRef = ref(), | |||||
submit = () => { | |||||
reviewCommentsRef.value.validForm(async (valid) => { | |||||
if (valid) { | |||||
loading.value = true | |||||
const postData = { | |||||
meetingId: route.query.meetingId, | |||||
projectId: route.query.projectId, | |||||
projectCode: route.query.projectCode, | |||||
...reviewCommentsRef.value.form, | |||||
reviewTemplateOptions: reviewCommentsRef.value.form.templates.map(i => { | |||||
return { | |||||
...i, | |||||
optionSerialNo: Array.isArray(i.optionSerialNo) ? i.optionSerialNo.map(r => r) : [i.optionSerialNo] | |||||
} | |||||
}), | |||||
attachFileId: reviewCommentsRef.value.form.attachments?.length && reviewCommentsRef.value.form.attachments[0].response.data.id || undefined, | |||||
isFinal: route.query.type * 1 === 2, | |||||
templates: undefined, | |||||
attachments: undefined | |||||
} | |||||
try { | |||||
await save(postData) | |||||
proxy.$message.success('提交成功') | |||||
loading.value = false | |||||
router.go(-2) | |||||
} catch (e) { | |||||
loading.value = false | |||||
} | |||||
} | |||||
}) | |||||
}, | |||||
// 组员意见-抽屉 | |||||
drawerVisible = ref(false), | |||||
templatesData = ref([]), // 模板数据 | |||||
memberOpinions = ref([]), // 组员意见 | |||||
showDrawer = async () => { | |||||
const res = await listForGroupLeader({ projectId: route.query.projectId, meetingId: route.query.meetingId }) | |||||
const res1 = await templatesById({ templateIds: res.data.map(i => i.templateId).join(',') }) | |||||
templatesData.value = res1.data | |||||
memberOpinions.value = res.data && res.data.map(i => { | |||||
return { | |||||
...i, | |||||
reviewTemplateOptions: i.reviewTemplateOptions && i.reviewTemplateOptions.map(temp => { | |||||
const data = templatesData.value.find(j => i.templateId === j.templateId).templates | |||||
return { | |||||
...temp, | |||||
title: data.find(r => r.serialNo === temp.questionSerialNo)?.title, | |||||
optionsValue: data.find(r => r.serialNo === temp.questionSerialNo)?.options.filter(j => temp.optionSerialNo.includes(j.serialNo)).map(j => j.option).join('、') | |||||
} | |||||
}) || [] | |||||
} | |||||
}) || [] | |||||
drawerVisible.value = true | |||||
} | |||||
onMounted(() => { | |||||
getTemplate() | |||||
}) | |||||
</script> | |||||
<template> | |||||
<div class="footerPage"> | |||||
<el-card class="w-full" shadow="never"> | |||||
<el-row :gutter="16"> | |||||
<el-col :span="14"> | |||||
<review-comments v-if="reviewVisible" ref="reviewCommentsRef" :template-data="templateData" /> | |||||
</el-col> | |||||
<!-- 最终意见显示按钮--> | |||||
<el-col v-if="route.query.type*1===2" :span="10"> | |||||
<div | |||||
v-if="!drawerVisible" | |||||
class="viewBtn" | |||||
@click="showDrawer" | |||||
> | |||||
<svg-icon name="eye" /> | |||||
<span>查看评审意见</span> | |||||
</div> | |||||
</el-col> | |||||
</el-row> | |||||
</el-card> | |||||
<div class="footer"> | |||||
<el-button type="primary" :loading="loading" @click="submit">提交</el-button> | |||||
<el-button @click="router.go(-1)">关闭</el-button> | |||||
</div> | |||||
</div> | |||||
<el-drawer | |||||
v-model="drawerVisible" | |||||
title="组员意见" | |||||
style="position: absolute" | |||||
direction="rtl" | |||||
size="40%" | |||||
:modal="false" | |||||
:append-to-body="false" | |||||
modal-class="myDrawerModal" | |||||
> | |||||
<member-opinion :member-opinions="memberOpinions" /> | |||||
</el-drawer> | |||||
</template> | |||||
<style lang="less"> | |||||
.viewBtn{ | |||||
width: 36px; | |||||
background: rgba(0,87,255,0.08); | |||||
border-radius: 4px; | |||||
border: 1px solid #0057FF; | |||||
padding: 8px; | |||||
font-size: 14px; | |||||
display: flex; | |||||
align-items: center; | |||||
flex-direction: column; | |||||
text-align: center; | |||||
justify-content: center; | |||||
color: #0057FF; | |||||
cursor: pointer; | |||||
} | |||||
.myDrawerModal{ | |||||
position: static !important; | |||||
} | |||||
</style> |
@@ -0,0 +1,66 @@ | |||||
<script name='handleExpertReview' setup> | |||||
import { onMounted, ref } from 'vue' | |||||
import { useRoute, useRouter } from 'vue-router' | |||||
import projectInfo from '../../../projectStoreManage/projectStore/projectDetail/components/projectInfo.vue' | |||||
import { getProjectDetail } from '@/http/apis/declareMange' | |||||
import { storeToRefs } from 'pinia' | |||||
import store from '@/store' | |||||
import { meetingBasicInfo } from '@/http/apis/expertManage/reviewMeeting' | |||||
// 项目详情 | |||||
const userInfo = storeToRefs(store.userStore).userInfo || {}, | |||||
detailData = ref({}), | |||||
router = useRouter(), | |||||
route = useRoute(), | |||||
getDetail = async () => { | |||||
const res = await getProjectDetail({ id: route.query.projectId }) | |||||
detailData.value = res.data | |||||
}, | |||||
toReviewComments = (type) => { | |||||
router.push({ name: 'fillReviewComments', query: { ...route.query, type, regionCode: basicInfo.value.regionCode, projectCode: detailData.value.projectCode }}) | |||||
}, | |||||
// 获取会议详情 | |||||
basicInfo = ref(), | |||||
getMeetingDetail = async () => { | |||||
const res = await meetingBasicInfo(route.query.meetingId) | |||||
basicInfo.value = res.data | |||||
} | |||||
onMounted(() => { | |||||
getDetail() | |||||
getMeetingDetail() | |||||
}) | |||||
</script> | |||||
<template> | |||||
<div class="w-full footerCard handleExpertReview"> | |||||
<div | |||||
v-waterMarker="{text:userInfo.realName+userInfo.phoneNo.substring(userInfo.phoneNo.length - 4)}" | |||||
style="position: absolute;pointer-events: none;width:100%;height:100%" | |||||
> | |||||
</div> | |||||
<project-info :detail-data="detailData" /> | |||||
<div class="footer"> | |||||
<template v-if="new Date().getTime()>=new Date(basicInfo?.startTime).getTime()&&route.query.type==='1'"> | |||||
<el-button | |||||
v-if="route.query.reviewed==='0'" | |||||
type="primary" | |||||
@click="toReviewComments(1)" | |||||
>填写评审意见</el-button> | |||||
<el-button | |||||
v-if="route.query.isHeadman==='true'&&route.query.reviewed==='1'" | |||||
type="primary" | |||||
@click="toReviewComments(2)" | |||||
>填写最终意见</el-button> | |||||
</template> | |||||
<el-button | |||||
plain | |||||
@click="router.go(-1)" | |||||
>返回</el-button> | |||||
</div> | |||||
</div> | |||||
</template> | |||||
<style lang='less'> | |||||
.handleExpertReview{ | |||||
padding-bottom: 56px; | |||||
} | |||||
</style> |
@@ -0,0 +1,189 @@ | |||||
<script setup name='expertReview'> | |||||
import { reactive, ref, onMounted } from 'vue' | |||||
import { useRouter } from 'vue-router' | |||||
import { listReviewProject } from '@/http/apis/expertManage/expertReview' | |||||
import projectList from './components/projectList.vue' | |||||
import { storeToRefs } from 'pinia' | |||||
import store from '@/store' | |||||
import meetingsLeaveDialog from './components/meetingsLeaveDialog.vue' | |||||
const userInfo = storeToRefs(store.userStore).userInfo, | |||||
listRef = ref(), | |||||
router = useRouter(), | |||||
searchForm = reactive({ | |||||
projectName: undefined, | |||||
buildOrgName: undefined | |||||
}), | |||||
// 列表数据 | |||||
data = ref([]), | |||||
total = ref(0), | |||||
count = ref(0), | |||||
getTableData = async (pageParams = listRef.value.pageParams) => { | |||||
const res = await listReviewProject({ | |||||
...pageParams, | |||||
...searchForm, | |||||
reviewed: activeName.value, | |||||
userId: userInfo.value.userId | |||||
}) | |||||
console.log(activeName.value) | |||||
data.value = res.data.records | |||||
total.value = res.data.total | |||||
if (activeName.value === 'false') { | |||||
count.value = res.data.total | |||||
} | |||||
}, | |||||
// 查询 | |||||
search = () => { | |||||
getTableData() | |||||
}, | |||||
// 重置 | |||||
reset = () => { | |||||
searchForm.projectName = undefined | |||||
searchForm.buildOrgName = undefined | |||||
listRef.value.pageParams.pageNumber = 1 | |||||
listRef.value.pageParams.pageSize = 10 | |||||
getTableData() | |||||
}, | |||||
activeName = ref('false'), | |||||
handleClick = ({ props }) => { | |||||
activeName.value = props.name | |||||
getTableData() | |||||
}, | |||||
// 详情 | |||||
toDetail = (item, type) => { | |||||
router.push({ | |||||
name: 'handleExpertReview', | |||||
query: { | |||||
projectId: item.projectId, // 项目id | |||||
meetingId: item.meetingId, // 会议id | |||||
isHeadman: item.isHeadman, // 是否组长 | |||||
reviewType: item.reviewType, // 评审类型 | |||||
type, | |||||
reviewed: item.reviewed | |||||
} | |||||
}) | |||||
}, | |||||
// 会议请假 | |||||
meetingsLeaveDialogData = reactive({ | |||||
visible: false | |||||
}), | |||||
showMeetingsLeaveDialog = () => { | |||||
meetingsLeaveDialogData.visible = true | |||||
}, | |||||
closeMeetingsLeaveDialog = () => { | |||||
meetingsLeaveDialogData.visible = false | |||||
} | |||||
onMounted(() => { | |||||
getTableData() | |||||
}) | |||||
</script> | |||||
<template> | |||||
<el-row class="box-card"> | |||||
<el-col :span="24"> | |||||
<el-card class="w-full search"> | |||||
<el-form | |||||
:model="searchForm" | |||||
size="small" | |||||
label-suffix=":" | |||||
> | |||||
<el-row | |||||
:gutter="16" | |||||
> | |||||
<el-col :span="8"> | |||||
<el-form-item label="项目名称"> | |||||
<el-input | |||||
v-model="searchForm.projectName" | |||||
placeholder="请输入" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<el-form-item label="申报单位"> | |||||
<el-input | |||||
v-model="searchForm.buildOrgName" | |||||
placeholder="请输入" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<el-form-item class="btn"> | |||||
<div class="flex"> | |||||
<el-button | |||||
type="primary" | |||||
@click="search" | |||||
>查询</el-button> | |||||
<el-button | |||||
@click="reset" | |||||
>重置</el-button> | |||||
</div> | |||||
</el-form-item> | |||||
</el-col> | |||||
</el-row> | |||||
</el-form> | |||||
</el-card> | |||||
<el-card class="w-full mt-8 tab-card"> | |||||
<template #header> | |||||
<div class="flex justify-between items-center"> | |||||
<el-tabs v-model="activeName" @tab-click="handleClick"> | |||||
<el-tab-pane :label="`待评审(${count})`" name="false" /> | |||||
<el-tab-pane label="已评审" name="true" /> | |||||
</el-tabs> | |||||
<el-button | |||||
type="primary" | |||||
plain | |||||
size="small" | |||||
@click="showMeetingsLeaveDialog" | |||||
>会议请假</el-button> | |||||
</div> | |||||
</template> | |||||
<project-list | |||||
ref="listRef" | |||||
:list-data="data" | |||||
:total="total" | |||||
@get-table-data="getTableData" | |||||
@to-detail="toDetail" | |||||
/> | |||||
</el-card> | |||||
</el-col> | |||||
</el-row> | |||||
<meetings-leave-dialog :visible="meetingsLeaveDialogData.visible" @close="closeMeetingsLeaveDialog" /> | |||||
</template> | |||||
<style lang='less' scoped> | |||||
.projectDynamicContainer{ | |||||
height: 540px; | |||||
overflow: scroll; | |||||
.projectDynamic { | |||||
width: 100%; | |||||
height: 150px; | |||||
// background-color: #bfc; | |||||
border-bottom: solid 1px rgba(216, 218, 223); | |||||
margin-bottom: 10px; | |||||
display: flex; | |||||
.leftPart{ | |||||
width: 84px; | |||||
height: auto; | |||||
display: flex; | |||||
justify-content: center; | |||||
} | |||||
.rightPart{ | |||||
flex: 1; | |||||
height: auto; | |||||
.checkDetail{ | |||||
color: rgba(0, 87, 255, 1); | |||||
cursor: pointer; | |||||
} | |||||
} | |||||
.projectAvartarStyle{ | |||||
width: 44px; | |||||
height: 44px; | |||||
} | |||||
} | |||||
} | |||||
.el-pagination { | |||||
padding: 16px 16px 0 16px; | |||||
flex-wrap: wrap; | |||||
justify-content: flex-end; | |||||
}</style> |
@@ -0,0 +1,546 @@ | |||||
<script name="basicInfo" setup> | |||||
import { onMounted, ref } from 'vue' | |||||
import store from '@/store' | |||||
import { storeToRefs } from 'pinia' | |||||
import { districtList } from '@/http/apis/commonApi' | |||||
import { fileFormatVerification, downloadFileUrl } from '@/utils/uploadAction.js' | |||||
import { zzdInfo } from '@/http/apis/expertManage/expertStore' | |||||
const uploadUrl = store.dictStore.uploadUrl, | |||||
userInfo = storeToRefs(store.userStore).userInfo, | |||||
{ nationList } = store.dictStore.globalDicts, | |||||
{ tagList } = storeToRefs(store.dictStore), | |||||
formData = ref({ | |||||
expertIntentionWorkRegions: [{}], // 履职意向 | |||||
avatarFile: { fileId: '' } | |||||
}), | |||||
formRef = ref(), | |||||
// 手机号码校验 | |||||
checkTelPhone = (rule, value, callback) => { | |||||
if (value === '') { | |||||
return callback(new Error('请输入正确的手机号')) | |||||
} else { | |||||
const regIdCard = | |||||
/^(13[0-9]|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18[0-9]|19[0-35-9])\d{8}$/ | |||||
if (regIdCard.test(value)) { | |||||
callback() | |||||
} else { | |||||
return callback(new Error('请输入正确的手机号')) | |||||
} | |||||
} | |||||
}, | |||||
idCardValidator = (rule, value, callback) => { | |||||
const _IDRe18 = /^([1-6][1-9]|50)\d{4}(18|19|20)\d{2}((0[1-9])|10|11|12)(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$/ | |||||
const _IDre15 = /^([1-6][1-9]|50)\d{4}\d{2}((0[1-9])|10|11|12)(([0-2][1-9])|10|20|30|31)\d{3}$/ | |||||
// 校验身份证: | |||||
if (!(_IDRe18.test(value) || _IDre15.test(value))) { | |||||
callback('请输入正确格式') | |||||
} else { | |||||
callback() | |||||
} | |||||
}, | |||||
rules = { | |||||
phoneNo: [ | |||||
{ required: true, message: '请输入手机号', trigger: 'blur' }, | |||||
{ validator: checkTelPhone, trigger: 'blur' } | |||||
], | |||||
name: [ | |||||
{ required: true, message: '请输入姓名', trigger: 'blur' } | |||||
], | |||||
gender: [ | |||||
{ required: true, message: '请选择性别', trigger: 'blur' } | |||||
], | |||||
hometown: [ | |||||
{ required: true, message: '请选择籍贯', trigger: 'blur' } | |||||
], | |||||
nationality: [ | |||||
{ required: true, message: '请选择民族', trigger: 'blur' } | |||||
], | |||||
political: [ | |||||
{ required: true, message: '请选择政治面貌', trigger: 'blur' } | |||||
], | |||||
idCard: [ | |||||
{ required: true, message: '请输入正确的身份证号', trigger: 'blur' }, | |||||
{ validator: idCardValidator, tigger: 'blur' } | |||||
], | |||||
birth: [ | |||||
{ required: true, message: '请选择出生年月', trigger: 'blur' } | |||||
], | |||||
bankNo: [ | |||||
{ required: true, message: '请输入银行卡号', trigger: 'blur' } | |||||
], | |||||
bank: [ | |||||
{ required: false, message: '请输入开户行', trigger: 'blur' } | |||||
], | |||||
email: [ | |||||
{ required: false, message: '请输入电子邮箱', trigger: 'blur' }, | |||||
{ | |||||
pattern: /^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/, | |||||
message: '请输入正确邮箱', | |||||
trigger: 'blur' | |||||
} | |||||
], | |||||
expertSource: [ | |||||
{ | |||||
required: true, | |||||
trigger: 'change', | |||||
message: '请选择专家来源' | |||||
} | |||||
], | |||||
expertRegionInfo: [ | |||||
{ | |||||
required: true, | |||||
trigger: 'change', | |||||
message: '请选择专家级别' | |||||
} | |||||
], | |||||
expertIntentionWorkRegions: [ | |||||
{ | |||||
required: true, | |||||
trigger: 'change', | |||||
message: '请选择履职意向' | |||||
} | |||||
], | |||||
expertType: [ | |||||
{ required: true, message: '请选择专家类型', trigger: 'blur' } | |||||
], | |||||
avatarUrl: [ | |||||
{ | |||||
required: true, | |||||
message: '请上传免冠照' | |||||
} | |||||
] | |||||
}, | |||||
// 校验 | |||||
validForm = (callback) => { | |||||
formRef.value.validate(valid => { | |||||
callback(valid) | |||||
}) | |||||
}, | |||||
// 回显 | |||||
setFormData = async (data) => { | |||||
formData.value = { | |||||
...data, | |||||
political: data.political?.[0] || undefined, | |||||
expertSource: data.expertSource?.[0] || undefined, | |||||
expertType: data.expertType?.[0] || undefined, | |||||
expertRegionInfo: data.expertRegionInfo.regionName?.split('@@').slice(1), | |||||
expertIntentionWorkRegions: data.expertIntentionWorkRegions?.map(i => { return { unionCode: i.regionName.split('@@').slice(1) } }), | |||||
avatarUrl: data?.avatarFile?.fileId && await downloadFileUrl(data.avatarFile.fileId), | |||||
avatarFile: data?.avatarFile || { fileId: '' } | |||||
} | |||||
}, | |||||
regionTree = ref(), | |||||
// 增加或删除履职意向 | |||||
updateWorkRegions = (type, index) => { | |||||
if (type === 'add') { | |||||
formData.value.expertIntentionWorkRegions.push({ | |||||
id: new Date().getTime() | |||||
}) | |||||
} else { | |||||
formData.value.expertIntentionWorkRegions.splice(index, 1) | |||||
} | |||||
}, | |||||
// 上传免冠照 | |||||
handleAvatarSuccess = res => { | |||||
formData.value.avatarFile['fileId'] = res.data.id | |||||
downloadFileUrl(res.data.id).then(res => { | |||||
formData.value.avatarUrl = res | |||||
}) | |||||
}, | |||||
// 获取浙政钉信息 | |||||
getZzdInfo = async () => { | |||||
const res = await zzdInfo({ phoneNo: formData.value.phoneNo }) | |||||
formData.value.isDingUser = res.data.isDingUser | |||||
if (res.data.isDingUser) { | |||||
formData.value.name = res.data.name | |||||
} | |||||
} | |||||
defineExpose({ validForm, formData, setFormData }) | |||||
onMounted(async () => { | |||||
const res = await districtList({ regionCode: 330500, regionLevel: 2 }) | |||||
regionTree.value = [res.data] | |||||
}) | |||||
</script> | |||||
<template> | |||||
<el-form | |||||
ref="formRef" | |||||
:model="formData" | |||||
:rules="rules" | |||||
label-position="right" | |||||
label-width="120px" | |||||
label-suffix=":" | |||||
scroll-to-error | |||||
class="basicInfo" | |||||
> | |||||
<el-row :gutter="8"> | |||||
<el-col :span="8"> | |||||
<el-form-item | |||||
label="手机号" | |||||
prop="phoneNo" | |||||
> | |||||
<el-input | |||||
v-model="formData.phoneNo" | |||||
placeholder="请输入" | |||||
:maxlength="11" | |||||
:disabled="!!$route.query.id||$route.name==='selfEditExpertInfo'" | |||||
@blur="getZzdInfo" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<el-form-item | |||||
label="姓名" | |||||
prop="name" | |||||
> | |||||
<el-input | |||||
v-model="formData.name" | |||||
placeholder="请输入" | |||||
:disabled="!!$route.query.id||$route.name==='selfEditExpertInfo'" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<el-form-item | |||||
label="性别" | |||||
prop="gender" | |||||
> | |||||
<el-select | |||||
v-model="formData.gender" | |||||
class="w-full" | |||||
placeholder="请选择" | |||||
> | |||||
<el-option value="1" label="男" /> | |||||
<el-option value="0" label="女" /> | |||||
</el-select> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<el-form-item | |||||
label="籍贯" | |||||
prop="hometown" | |||||
> | |||||
<el-input | |||||
v-model="formData.hometown" | |||||
placeholder="请输入" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<el-form-item | |||||
label="民族" | |||||
prop="nationality" | |||||
> | |||||
<el-select | |||||
v-model="formData.nationality" | |||||
class="m-2 w-full" | |||||
placeholder="请选择" | |||||
> | |||||
<el-option | |||||
v-for="item in nationList" | |||||
:key="item.id" | |||||
:label="item.info" | |||||
:value="item.info" | |||||
/> | |||||
</el-select> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<el-form-item | |||||
label="政治面貌" | |||||
prop="political" | |||||
> | |||||
<el-select | |||||
v-model="formData.political" | |||||
class="w-full" | |||||
placeholder="请选择" | |||||
value-key="dictionaryCode" | |||||
> | |||||
<el-option | |||||
v-for="(item,index) in store.dictStore.politicalDict" | |||||
:key="index" | |||||
:label="item.dictionaryName" | |||||
:value="item" | |||||
/> | |||||
</el-select> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<el-form-item | |||||
label="身份证" | |||||
prop="idCard" | |||||
> | |||||
<el-input | |||||
v-model="formData.idCard" | |||||
placeholder="请输入" | |||||
:maxlength="18" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<el-form-item | |||||
label="办公电话" | |||||
prop="officePhone" | |||||
> | |||||
<el-input | |||||
v-model="formData.officePhone" | |||||
placeholder="请输入" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<el-form-item | |||||
label="出生年月" | |||||
prop="birth" | |||||
> | |||||
<el-date-picker | |||||
v-model="formData.birth" | |||||
type="month" | |||||
placeholder="请选择" | |||||
format="YYYY-MM" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<el-form-item | |||||
label="银行卡号" | |||||
prop="bankNo" | |||||
> | |||||
<el-input | |||||
v-model="formData.bankNo" | |||||
placeholder="请输入" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<el-form-item | |||||
label="开户银行" | |||||
prop="bank" | |||||
> | |||||
<el-input | |||||
v-model="formData.bank" | |||||
placeholder="请输入" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<el-form-item | |||||
label="电子邮箱" | |||||
prop="email" | |||||
> | |||||
<el-input | |||||
v-model="formData.email" | |||||
placeholder="请输入" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col v-if="false" :span="8"> | |||||
<el-form-item | |||||
label="入库意向" | |||||
prop="expertSource" | |||||
> | |||||
<el-select | |||||
v-model="formData.expertSource" | |||||
class="w-full" | |||||
placeholder="请选择" | |||||
clearable | |||||
> | |||||
<el-option | |||||
v-for="(item,index) in tagList && | |||||
tagList.length && | |||||
tagList.find(i => i.tagCode === 'expert_source') | |||||
.children" | |||||
:key="index" | |||||
:label="item.tagName" | |||||
:value="item.unionCode" | |||||
/> | |||||
</el-select> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<el-form-item | |||||
label="专家级别" | |||||
prop="expertRegionInfo" | |||||
> | |||||
<el-cascader | |||||
v-model="formData.expertRegionInfo" | |||||
:options="regionTree" | |||||
:props="{ | |||||
value: 'unionCode', | |||||
label: 'name' | |||||
}" | |||||
clearable | |||||
placeholder="请选择" | |||||
class="w-full" | |||||
:disabled="$route.name==='selfEditExpertInfo'||$route.query.id&&userInfo.regionCode!==formData?.expertRegionInfo?.[formData.expertRegionInfo?.length-1].split('##')[0]" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<el-form-item | |||||
label="专家来源" | |||||
> | |||||
<el-select | |||||
v-model="formData.expertSource" | |||||
class="w-full" | |||||
placeholder="请选择" | |||||
clearable | |||||
value-key="tagCode" | |||||
> | |||||
<el-option | |||||
v-for="(item,index) in store.dictStore.expertSourceDict" | |||||
:key="index" | |||||
:label="item.tagName" | |||||
:value="item" | |||||
/> | |||||
</el-select> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<el-form-item | |||||
label="专家类型" | |||||
prop="expertType" | |||||
> | |||||
<el-select | |||||
v-model="formData.expertType" | |||||
class="w-full" | |||||
placeholder="请选择" | |||||
value-key="dictionaryCode" | |||||
> | |||||
<el-option | |||||
v-for="(item,index) in store.dictStore.expertTypeDict" | |||||
:key="index" | |||||
:label="item.dictionaryName" | |||||
:value="item" | |||||
/> | |||||
</el-select> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<el-form-item | |||||
label="履职意向" | |||||
prop="expertIntentionWorkRegions" | |||||
> | |||||
<el-row | |||||
v-for="(item, index) in formData | |||||
.expertIntentionWorkRegions" | |||||
:key="item.id" | |||||
class="intention-item w-full" | |||||
> | |||||
<el-col :span="24"> | |||||
<el-cascader | |||||
v-model=" | |||||
formData.expertIntentionWorkRegions[index] | |||||
.unionCode | |||||
" | |||||
:options="regionTree" | |||||
:props="{ | |||||
value: 'unionCode', | |||||
label: 'name' | |||||
}" | |||||
clearable | |||||
style="width: 100%" | |||||
class="mb-4" | |||||
/> | |||||
<span | |||||
v-if="index > 0" | |||||
style="position: absolute; right: -20px" | |||||
@click="updateWorkRegions('del', index)" | |||||
> | |||||
<el-icon> | |||||
<Delete color="#D40000" /> | |||||
</el-icon> | |||||
</span> | |||||
</el-col> | |||||
</el-row> | |||||
<p class="addGhostBtn mt-8 w-full"> | |||||
<el-button | |||||
class="w-full" | |||||
type="primary" | |||||
plain | |||||
style="margin: 0" | |||||
@click="updateWorkRegions('add')" | |||||
> | |||||
+ 增加履职意向地区 | |||||
</el-button> | |||||
</p> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="24"> | |||||
<el-form-item | |||||
class="avatarForm" | |||||
label="一寸免冠照" | |||||
prop="avatarUrl" | |||||
style="margin-bottom: 32px" | |||||
> | |||||
<el-upload | |||||
class="avatar-uploader" | |||||
:action="uploadUrl" | |||||
:show-file-list="false" | |||||
:on-success="handleAvatarSuccess" | |||||
:before-upload=" | |||||
file => | |||||
fileFormatVerification(file, { | |||||
size: 500, | |||||
types: ['png', 'jpg', 'jpeg'] | |||||
}) | |||||
" | |||||
accept="image/png,image/jpeg" | |||||
> | |||||
<img | |||||
v-if="formData.avatarUrl" | |||||
:src="formData.avatarUrl" | |||||
class="avatar" | |||||
/> | |||||
<i v-else class="el-icon-plus avatar-uploader-icon"> | |||||
<el-icon><Camera /></el-icon> | |||||
</i> | |||||
</el-upload> | |||||
<div class="limit-name ml-4">请上传蓝底1寸免冠照片,小于500Kb</div> | |||||
</el-form-item> | |||||
</el-col> | |||||
</el-row> | |||||
</el-form> | |||||
</template> | |||||
<style lang="less"> | |||||
.basicInfo{ | |||||
.avatarForm { | |||||
:deep(.el-form-item__content) { | |||||
display: block; | |||||
} | |||||
} | |||||
.avatar-uploader { | |||||
.el-upload { | |||||
background: #edf4ff; | |||||
border-radius: 4px; | |||||
border: 1px dashed #007df1; | |||||
cursor: pointer; | |||||
position: relative; | |||||
overflow: hidden; | |||||
&:hover { | |||||
border-color: #409eff; | |||||
} | |||||
} | |||||
.avatar-uploader-icon { | |||||
border-radius: 4px; | |||||
border: 1px dashed #007df1; | |||||
font-size: 28px; | |||||
color: #007df1; | |||||
width: 104px; | |||||
height: 104px; | |||||
display: flex; | |||||
justify-content: center; | |||||
align-items: center; | |||||
} | |||||
.avatar { | |||||
width: 80px; | |||||
height: 80px; | |||||
display: block; | |||||
} | |||||
} | |||||
.limit-name { | |||||
margin-top: 13px; | |||||
color: #999999; | |||||
font-size: 12px; | |||||
} | |||||
} | |||||
</style> |
@@ -0,0 +1,232 @@ | |||||
<script name="eduInfo" setup> | |||||
import { onMounted, getCurrentInstance, ref } from 'vue' | |||||
import store from '@/store' | |||||
import { districtList } from '@/http/apis/commonApi' | |||||
import { fileFormatVerification, handleFileSuccess, handleFilePreview } from '@/utils/uploadAction.js' | |||||
const uploadUrl = store.dictStore.uploadUrl, | |||||
{ proxy } = getCurrentInstance(), | |||||
formData = ref({ | |||||
}), | |||||
formRef = ref(), | |||||
rules = { | |||||
edu: [ | |||||
{ required: true, message: '请选择学历', trigger: 'blur' } | |||||
], | |||||
degree: [ | |||||
{ required: true, message: '请选择学位', trigger: 'blur' } | |||||
] | |||||
}, | |||||
// 校验 | |||||
validForm = (callback) => { | |||||
formRef.value.validate(valid => { | |||||
callback(valid) | |||||
}) | |||||
}, | |||||
fileExceed = (files, uploadFiles) => { | |||||
proxy.$message.warning('仅限上传一个文件') | |||||
}, | |||||
// 回显 | |||||
setFormData = async (data) => { | |||||
formData.value = { | |||||
...data, | |||||
edu: data.edu?.[0] || undefined, | |||||
degree: data.degree?.[0] || undefined, | |||||
degreeCertificateFile: data.degreeCertificateFile && data.degreeCertificateFile.map(i => { | |||||
return { | |||||
name: i.fileName, | |||||
response: { | |||||
data: { | |||||
id: i.fileId | |||||
} | |||||
}, | |||||
fileUrlById: i.url | |||||
} | |||||
}), | |||||
graduationCertificateFile: data.graduationCertificateFile && data.graduationCertificateFile.map(i => { | |||||
return { | |||||
name: i.fileName, | |||||
response: { | |||||
data: { | |||||
id: i.fileId | |||||
} | |||||
}, | |||||
fileUrlById: i.url | |||||
} | |||||
}) | |||||
} | |||||
}, | |||||
regionTree = ref() | |||||
defineExpose({ validForm, formData, setFormData }) | |||||
onMounted(async () => { | |||||
const res = await districtList({ regionCode: 330500, regionLevel: 2 }) | |||||
regionTree.value = [res.data] | |||||
}) | |||||
</script> | |||||
<template> | |||||
<el-form | |||||
ref="formRef" | |||||
:model="formData" | |||||
:rules="rules" | |||||
label-position="right" | |||||
label-width="100px" | |||||
label-suffix=":" | |||||
scroll-to-error | |||||
class="eduInfo" | |||||
> | |||||
<el-row :gutter="8"> | |||||
<el-col :span="8"> | |||||
<el-form-item | |||||
label="毕业学校" | |||||
prop="school" | |||||
> | |||||
<el-input | |||||
v-model="formData.school" | |||||
placeholder="请输入" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<el-form-item | |||||
label="毕业时间" | |||||
prop="graduatedAt" | |||||
> | |||||
<el-date-picker | |||||
v-model="formData.graduatedAt" | |||||
type="date" | |||||
format="YYYY-MM-DD" | |||||
value-format="YYYY-MM-DD" | |||||
placeholder="请选择" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<el-form-item | |||||
label="所学专业" | |||||
prop="academicTitle" | |||||
> | |||||
<el-input | |||||
v-model="formData.academicTitle" | |||||
placeholder="请输入" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<el-form-item label="学历" prop="edu"> | |||||
<el-select | |||||
v-model="formData.edu" | |||||
placeholder="请选择学历" | |||||
value-key="dictionaryCode" | |||||
clearable | |||||
class="w-full" | |||||
> | |||||
<el-option | |||||
v-for="(item, index) in store.dictStore.eduDict " | |||||
:key="index" | |||||
:label="item.dictionaryName" | |||||
:value="item" | |||||
/> | |||||
</el-select> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<el-form-item label="学位" prop="degree"> | |||||
<el-select | |||||
v-model="formData.degree" | |||||
placeholder="请选择学位" | |||||
value-key="dictionaryCode" | |||||
class="w-full" | |||||
> | |||||
<el-option | |||||
v-for="(item, index) in store.dictStore.degreeDict " | |||||
:key="index" | |||||
:label="item.dictionaryName" | |||||
:value="item" | |||||
/> | |||||
</el-select> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="24"> | |||||
<el-form-item | |||||
label="毕业证书" | |||||
prop="graduationCertificateFile" | |||||
> | |||||
<el-upload | |||||
v-model:file-list="formData.graduationCertificateFile" | |||||
class="w-full" | |||||
:action="uploadUrl" | |||||
:limit="1" | |||||
:on-exceed="fileExceed" | |||||
:on-success=" | |||||
res => | |||||
handleFileSuccess( | |||||
res, | |||||
formData.graduationCertificateFile | |||||
) | |||||
" | |||||
:on-preview="handleFilePreview" | |||||
accept="application/pdf,image/png,image/jpeg" | |||||
:before-upload=" | |||||
file => | |||||
fileFormatVerification(file, { | |||||
size: 1024, | |||||
types: ['png', 'jpg', 'jpeg','pdf']})" | |||||
> | |||||
<el-button | |||||
type="primary" | |||||
plain | |||||
>选择文件</el-button> | |||||
<template #tip> | |||||
<div class="el-upload__tip"> | |||||
支持扩展名:.pdf.png .jpg .pdf ,文件大小不超过1M | |||||
</div> | |||||
</template> | |||||
</el-upload> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="24"> | |||||
<el-form-item | |||||
label="学位证书" | |||||
prop="degreeCertificateFile" | |||||
> | |||||
<el-upload | |||||
v-model:file-list="formData.degreeCertificateFile" | |||||
class="w-full" | |||||
:action="uploadUrl" | |||||
:on-exceed="fileExceed" | |||||
:limit="1" | |||||
:on-success=" | |||||
res => | |||||
handleFileSuccess( | |||||
res, | |||||
formData.degreeCertificateFile | |||||
) | |||||
" | |||||
:before-upload=" | |||||
file => | |||||
fileFormatVerification(file, { | |||||
size: 1024, | |||||
types: ['png', 'jpg', 'jpeg','pdf'] | |||||
}) | |||||
" | |||||
accept="application/pdf,image/png,image/jpeg,image/jpg" | |||||
:on-preview="handleFilePreview" | |||||
> | |||||
<el-button | |||||
type="primary" | |||||
plain | |||||
>选择文件</el-button> | |||||
<template #tip> | |||||
<div class="el-upload__tip"> | |||||
支持扩展名:.pdf.png .jpg .pdf,文件大小不超过1M | |||||
</div> | |||||
</template> | |||||
</el-upload> | |||||
</el-form-item> | |||||
</el-col> | |||||
</el-row> | |||||
</el-form> | |||||
</template> | |||||
<style lang="less"> | |||||
.eduInfo{ | |||||
} | |||||
</style> |
@@ -0,0 +1,80 @@ | |||||
<script name="expertOtherInfo" setup> | |||||
import { onMounted, ref } from 'vue' | |||||
import { storeToRefs } from 'pinia' | |||||
import store from '@/store' | |||||
const { tagList } = storeToRefs(store.dictStore), | |||||
formData = ref({ | |||||
}), | |||||
formRef = ref(), | |||||
rules = {}, | |||||
// 校验 | |||||
validForm = (callback) => { | |||||
formRef.value.validate(valid => { | |||||
callback(valid) | |||||
}) | |||||
}, | |||||
// 回显 | |||||
setFormData = (data) => { | |||||
formData.value = { | |||||
...data, | |||||
other: data.other && data.other.map(i => `${i.tagName}##${i.tagCode}`) | |||||
} | |||||
} | |||||
defineExpose({ validForm, formData, setFormData }) | |||||
onMounted(async () => { | |||||
}) | |||||
</script> | |||||
<template> | |||||
<el-form | |||||
ref="formRef" | |||||
:model="formData" | |||||
:rules="rules" | |||||
label-position="right" | |||||
label-width="120px" | |||||
label-suffix=":" | |||||
scroll-to-error | |||||
class="expertOtherInfo" | |||||
> | |||||
<el-row :gutter="8"> | |||||
<el-col :span="24"> | |||||
<el-form-item label="其他标签"> | |||||
<el-tree-select | |||||
v-model="formData.other" | |||||
placeholder="请选择其他标签" | |||||
:data=" | |||||
tagList && | |||||
tagList.length && | |||||
tagList.find(i => i.tagCode === 'other').children||[] | |||||
" | |||||
:props="{ | |||||
label: 'tagName', | |||||
value: 'unionCode' | |||||
}" | |||||
node-key="unionCode" | |||||
collapse-tags | |||||
multiple | |||||
show-checkbox | |||||
check-on-click-node | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="24"> | |||||
<el-form-item | |||||
label="备注" | |||||
> | |||||
<el-input | |||||
v-model="formData.remark" | |||||
maxlength="200" | |||||
show-word-limit | |||||
type="textarea" | |||||
placeholder="请输入" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
</el-row> | |||||
</el-form> | |||||
</template> | |||||
<style lang="less"> | |||||
.expertOtherInfo{ | |||||
} | |||||
</style> |
@@ -0,0 +1,315 @@ | |||||
<script name="jobInfo" setup> | |||||
import { onMounted, ref } from 'vue' | |||||
import { getOrgLevelByLevel, getOrgTree } from '@/http/apis/systemManage/unitManage' | |||||
import { getBusinessstripLine } from '@/http/apis/commonApi' | |||||
import store from '@/store' | |||||
const formData = ref({ | |||||
companyAttribute: undefined | |||||
}), | |||||
formRef = ref(), | |||||
rules = { | |||||
company: [ | |||||
{ required: true, message: '请上选择工作单位', trigger: 'blur' } | |||||
], | |||||
companyUniqCode: [ | |||||
{ required: true, message: '工作单位code不能为空', trigger: 'blur' } | |||||
], | |||||
legalEntityCode: [ | |||||
{ required: true, message: '请输入单位法人编号', trigger: 'blur' } | |||||
], | |||||
administrativeDuties: [ | |||||
{ required: true, message: '请输入行政职务', trigger: 'blur' } | |||||
], | |||||
startWorkAt: [ | |||||
{ required: true, message: '请选择开始工作日期', trigger: 'blur' } | |||||
], | |||||
administrativeRank: [ | |||||
{ required: true, message: '请选择行政职级', trigger: 'blur' } | |||||
], | |||||
jobStatus: [ | |||||
{ required: true, message: '请选择在职状态', trigger: 'blur' } | |||||
], | |||||
retiredAt: [ | |||||
{ required: true, message: '请选退休日期', trigger: 'blur' } | |||||
], | |||||
companyAttribute: [ | |||||
{ required: true, message: '请选单位类型', trigger: 'blur' } | |||||
] | |||||
}, | |||||
// 校验 | |||||
validForm = (callback) => { | |||||
formRef.value.validate(valid => { | |||||
callback(valid) | |||||
}) | |||||
}, | |||||
// 回显 | |||||
setFormData = (data) => { | |||||
formData.value = { | |||||
...data, | |||||
administrativeRank: data.administrativeRank?.[0] || undefined, | |||||
jobStatus: data.jobStatus?.[0] || undefined, | |||||
companyAttribute: data.companyAttribute?.[0] || undefined | |||||
} | |||||
}, | |||||
// 工作单位 | |||||
orgTreeRef = ref(), | |||||
changeCompany = () => { | |||||
formData.value.company = orgTreeRef.value.getCurrentNode().name | |||||
}, | |||||
// 获取单位组织架构 | |||||
loadNode = async (node, resolve) => { | |||||
if (node.level === 0) { | |||||
const res = await getOrgLevelByLevel({ | |||||
isCompetentUnit: true, | |||||
isSuperiorLineCompetentUnit: true | |||||
}) | |||||
resolve(res.data) | |||||
} else { | |||||
const res = await getOrgLevelByLevel({ | |||||
parentCode: node.data.organizationCode | |||||
}) | |||||
if (res.data?.length) { | |||||
resolve(res.data) | |||||
} else { | |||||
resolve([]) | |||||
} | |||||
} | |||||
}, | |||||
lineListData = ref([]), | |||||
getLineList = async () => { | |||||
const res = await getBusinessstripLine() | |||||
lineListData.value = res.data | |||||
}, | |||||
companyTreeData = ref(), | |||||
getCompany = (data) => { | |||||
const items = [] | |||||
data.forEach(i => { | |||||
items.push({ | |||||
name: i.title, | |||||
organizationCode: i.key, | |||||
children: i.children?.lengt ? getCompany(i.children) : [] | |||||
}) | |||||
}) | |||||
return items | |||||
}, | |||||
remoteMethod = async (query) => { | |||||
const res = await getOrgTree({ organizationName: query }) | |||||
companyTreeData.value = getCompany(res.data) | |||||
} | |||||
defineExpose({ validForm, formData, setFormData }) | |||||
onMounted(async () => { | |||||
getLineList() | |||||
}) | |||||
</script> | |||||
<template> | |||||
<el-form | |||||
ref="formRef" | |||||
:model="formData" | |||||
:rules="rules" | |||||
label-position="right" | |||||
label-width="120px" | |||||
label-suffix=":" | |||||
scroll-to-error | |||||
class="jobInfo" | |||||
> | |||||
<el-row :gutter="8"> | |||||
<el-col :span="8"> | |||||
<el-form-item | |||||
label="工作单位" | |||||
prop="company" | |||||
> | |||||
<el-tree-select | |||||
ref="orgTreeRef" | |||||
v-model="formData.companyUniqCode" | |||||
:data="companyTreeData" | |||||
class="w-full" | |||||
node-key="organizationCode" | |||||
lazy | |||||
:check-strictly="true" | |||||
:load="loadNode" | |||||
:cache-data="formData.company&&formData.companyUniqCode?[{organizationCode:formData.companyUniqCode,name:formData.company}]:[]" | |||||
:props="{ | |||||
label:'name', | |||||
value:'organizationCode' | |||||
}" | |||||
filterable | |||||
remote | |||||
:remote-method="remoteMethod" | |||||
@change="changeCompany" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<el-form-item | |||||
label="工作单位code" | |||||
prop="formData.companyUniqCode" | |||||
> | |||||
<el-input | |||||
v-model="formData.companyUniqCode" | |||||
placeholder="请选择" | |||||
disabled | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<el-form-item | |||||
label="单位法人编号" | |||||
> | |||||
<el-input | |||||
v-model="formData.legalEntityCode" | |||||
placeholder="请输入" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<el-form-item | |||||
label="行政职务" | |||||
prop="administrativeDuties" | |||||
> | |||||
<el-input | |||||
v-model="formData.administrativeDuties" | |||||
placeholder="请输入" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<el-form-item | |||||
label="开始工作日期" | |||||
prop="startWorkAt" | |||||
> | |||||
<el-date-picker | |||||
v-model="formData.startWorkAt" | |||||
type="date" | |||||
format="YYYY-MM-DD" | |||||
value-format="YYYY-MM-DD" | |||||
placeholder="请选择" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<el-form-item | |||||
label="行政职级" | |||||
prop="administrativeRank" | |||||
> | |||||
<el-select | |||||
v-model="formData.administrativeRank" | |||||
class="w-full" | |||||
placeholder="请选择" | |||||
value-key="dictionaryCode" | |||||
> | |||||
<el-option | |||||
v-for="(item,index) in store.dictStore.administrativeRankDict" | |||||
:key="index" | |||||
:label="item.dictionaryName" | |||||
:value="item" | |||||
/> | |||||
</el-select> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<el-form-item | |||||
label="在职状态" | |||||
prop="jobStatus" | |||||
> | |||||
<el-select | |||||
v-model="formData.jobStatus" | |||||
class="w-full" | |||||
placeholder="请选择" | |||||
value-key="dictionaryCode" | |||||
> | |||||
<el-option | |||||
v-for="(item,index) in store.dictStore.jobStatusDict" | |||||
:key="index" | |||||
:label="item.dictionaryName" | |||||
:value="item" | |||||
/> | |||||
</el-select> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col v-if="formData.jobStatus?.dictionaryName==='退休'" :span="8"> | |||||
<el-form-item | |||||
label="退休日期" | |||||
prop="retiredAt" | |||||
> | |||||
<el-date-picker | |||||
v-model="formData.retiredAt" | |||||
type="date" | |||||
format="YYYY-MM-DD" | |||||
value-format="YYYY-MM-DD" | |||||
placeholder="请选择" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<el-form-item | |||||
label="单位类型" | |||||
prop="companyAttribute" | |||||
> | |||||
<el-select | |||||
v-model="formData.companyAttribute" | |||||
placeholder="请选择" | |||||
class="w-full" | |||||
value-key="dictionaryCode" | |||||
> | |||||
<el-option | |||||
v-for="(item,index) in store.dictStore.companyAttributeDict" | |||||
:key="index" | |||||
:label="item.dictionaryName" | |||||
:value="item" | |||||
/> | |||||
</el-select> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<el-form-item label="条线"> | |||||
<el-select | |||||
v-model="formData.businessStrips" | |||||
multiple | |||||
value-key="businessStripCode" | |||||
filterable | |||||
class="w-full" | |||||
> | |||||
<el-option | |||||
v-for="(item,index) in lineListData" | |||||
:key="index" | |||||
:label="item.businessStripName" | |||||
:value="item" | |||||
/> | |||||
</el-select> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="24"> | |||||
<el-form-item | |||||
label="工作地址" | |||||
prop="address" | |||||
> | |||||
<el-input | |||||
v-model="formData.address" | |||||
maxlength="50" | |||||
placeholder="请输入" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="24"> | |||||
<el-form-item | |||||
label="工作经历" | |||||
prop="experience" | |||||
> | |||||
<el-input | |||||
v-model="formData.experience" | |||||
maxlength="200" | |||||
:rows="5" | |||||
type="textarea" | |||||
show-word-limit | |||||
placeholder="请输入" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
</el-row> | |||||
</el-form> | |||||
</template> | |||||
<style lang="less"> | |||||
.jobInfo{ | |||||
} | |||||
</style> |
@@ -0,0 +1,347 @@ | |||||
<script name="professionalInfo" setup> | |||||
import { getCurrentInstance, onMounted, reactive, ref } from 'vue' | |||||
import store from '@/store' | |||||
import orgTree from '@/components/orgTree/index.vue' | |||||
import { storeToRefs } from 'pinia' | |||||
import { fileFormatVerification, handleFileSuccess, handleFilePreview } from '@/utils/uploadAction.js' | |||||
const uploadUrl = store.dictStore.uploadUrl | |||||
const { tagList } = storeToRefs(store.dictStore), | |||||
{ proxy } = getCurrentInstance(), | |||||
formData = ref({ | |||||
}), | |||||
formRef = ref(), | |||||
rules = { | |||||
technicalTitles: [ | |||||
{ required: true, message: '请输入技术职称', trigger: 'blur' } | |||||
], | |||||
titleLevel: [ | |||||
{ required: true, message: '请选择职称级别', trigger: 'blur' } | |||||
], | |||||
goodAt: [ | |||||
{ required: true, message: '请选择擅长方向', trigger: 'blur' } | |||||
], | |||||
technicalExpertise: [ | |||||
{ required: true, message: '请选择技术专长', trigger: 'blur' } | |||||
], | |||||
industrySector: [ | |||||
{ required: true, message: '请选择行业领域', trigger: 'blur' } | |||||
], | |||||
avoidCompanyList: [ | |||||
{ required: true, message: '请输入回避单位', trigger: 'blur' } | |||||
], | |||||
titleCertificateFile: [ | |||||
{ required: true, message: '请上传职称证明', trigger: 'blur' } | |||||
] | |||||
}, | |||||
// 校验 | |||||
validForm = (callback) => { | |||||
formRef.value.validate(valid => { | |||||
callback(valid) | |||||
}) | |||||
}, | |||||
fileExceed = (files, uploadFiles) => { | |||||
proxy.$message.warning('仅限上传一个文件') | |||||
}, | |||||
// 回显 | |||||
setFormData = (data) => { | |||||
formData.value = { | |||||
...data, | |||||
goodAt: data.goodAt && data.goodAt || undefined, | |||||
titleLevel: data.titleLevel && data.titleLevel[0] || undefined, | |||||
industrySector: data.industrySector && data.industrySector.map(i => `${i.tagName}##${i.tagCode}`), | |||||
technicalExpertise: data.technicalExpertise && data.technicalExpertise.map(i => `${i.tagName}##${i.tagCode}`), | |||||
titleCertificateFile: data.titleCertificateFile && data.titleCertificateFile.map(i => { | |||||
return { | |||||
name: i.fileName, | |||||
response: { | |||||
data: { | |||||
id: i.fileId | |||||
} | |||||
}, | |||||
fileUrlById: i.url | |||||
} | |||||
}) | |||||
} | |||||
}, | |||||
handleChangeTreeTag = (checkedKeys, checkedNodes, name) => { | |||||
console.log(checkedNodes) | |||||
}, | |||||
// 回避单位单位 | |||||
orgProps = reactive({ | |||||
unitVisible: false, | |||||
showCheckbox: false, | |||||
data: undefined, | |||||
name: undefined | |||||
}), | |||||
showOrgTree = (name) => { | |||||
orgProps.name = name | |||||
orgProps.unitVisible = true | |||||
orgProps.showCheckbox = true | |||||
orgProps.data = formData.value.avoidCompanyList?.map(i => { | |||||
return { | |||||
key: i.companyUniqCode, | |||||
title: i.companyName | |||||
} | |||||
}) | |||||
}, | |||||
closeOrg = () => { | |||||
orgProps.unitVisible = false | |||||
}, | |||||
getOrgData = (data, expandedKeys) => { | |||||
formData.value[orgProps.name] = data.map(i => { | |||||
return { | |||||
companyUniqCode: i.key, | |||||
companyName: i.title | |||||
} | |||||
}) | |||||
}, | |||||
// 删除回避单位 | |||||
delTag = (index) => { | |||||
formData.value.avoidCompanyList.splice(index, 1) | |||||
} | |||||
defineExpose({ validForm, formData, setFormData }) | |||||
onMounted(async () => { | |||||
}) | |||||
</script> | |||||
<template> | |||||
<el-form | |||||
ref="formRef" | |||||
:model="formData" | |||||
:rules="rules" | |||||
label-position="right" | |||||
label-width="120px" | |||||
label-suffix=":" | |||||
scroll-to-error | |||||
class="professionalInfo" | |||||
> | |||||
<el-row :gutter="8"> | |||||
<el-col :span="8"> | |||||
<el-form-item | |||||
label="技术职称" | |||||
prop="technicalTitles" | |||||
> | |||||
<el-input | |||||
v-model="formData.technicalTitles" | |||||
placeholder="请输入" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<el-form-item | |||||
label="职称级别" | |||||
prop="titleLevel" | |||||
> | |||||
<el-select | |||||
v-model="formData.titleLevel" | |||||
class="w-full" | |||||
placeholder="请选择" | |||||
value-key="dictionaryCode" | |||||
> | |||||
<el-option | |||||
v-for="(item,index) in store.dictStore.titleLevelDict " | |||||
:key="index" | |||||
:label="item.dictionaryName" | |||||
:value="item" | |||||
/> | |||||
</el-select> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<el-form-item | |||||
label="擅长方向" | |||||
prop="goodAt" | |||||
> | |||||
<el-select | |||||
v-model="formData.goodAt" | |||||
class="w-full" | |||||
placeholder="请选择" | |||||
clearable | |||||
value-key="tagCode" | |||||
multiple | |||||
> | |||||
<el-option | |||||
v-for="(item,index) in store.dictStore.goodAtDict" | |||||
:key="index" | |||||
:label="item.tagName" | |||||
:value="item" | |||||
/> | |||||
</el-select> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<el-form-item | |||||
label="技术专长" | |||||
prop="technicalExpertise" | |||||
> | |||||
<el-tree-select | |||||
v-model="formData.technicalExpertise" | |||||
class="w-full" | |||||
placeholder="请选择技术专长" | |||||
:data=" | |||||
tagList && | |||||
tagList.length && | |||||
tagList.find(i => i.tagCode === 'technical_expertise') | |||||
.children||[] | |||||
" | |||||
:props="{ | |||||
label: 'tagName', | |||||
value: 'unionCode' | |||||
}" | |||||
node-key="unionCode" | |||||
collapse-tags | |||||
multiple | |||||
show-checkbox | |||||
check-on-click-node | |||||
@check=" | |||||
(checkedKeys, checkedNodes) => | |||||
handleChangeTreeTag( | |||||
checkedKeys, | |||||
checkedNodes, | |||||
'technicalExpertise' | |||||
) | |||||
" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<el-form-item | |||||
label="行业领域" | |||||
prop="industrySector" | |||||
> | |||||
<el-tree-select | |||||
v-model="formData.industrySector" | |||||
class="w-full" | |||||
placeholder="请选择行业领域" | |||||
:data=" | |||||
tagList && | |||||
tagList.length && | |||||
tagList.find(i => i.tagCode === 'industry_sector').children||[] | |||||
" | |||||
:props="{ | |||||
label: 'tagName', | |||||
value: 'unionCode' | |||||
}" | |||||
node-key="unionCode" | |||||
collapse-tags | |||||
multiple | |||||
show-checkbox | |||||
check-on-click-node | |||||
@check=" | |||||
(checkedKeys, checkedNodes) => | |||||
handleChangeTreeTag( | |||||
checkedKeys, | |||||
checkedNodes, | |||||
'industrySector' | |||||
) | |||||
" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="24"> | |||||
<el-form-item | |||||
label="获奖情况" | |||||
prop="awards" | |||||
> | |||||
<el-input | |||||
v-model="formData.awards" | |||||
maxlength="200" | |||||
show-word-limit | |||||
type="textarea" | |||||
placeholder="请输入" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="24"> | |||||
<el-form-item | |||||
label="表彰奖励" | |||||
prop="recognitionReward" | |||||
> | |||||
<el-input | |||||
v-model="formData.recognitionReward" | |||||
maxlength="200" | |||||
show-word-limit | |||||
type="textarea" | |||||
placeholder="请输入" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="24"> | |||||
<el-form-item | |||||
label="回避单位" | |||||
prop="avoidCompanyList" | |||||
> | |||||
<div class="flex flex-col items-start"> | |||||
<el-button | |||||
type="primary" | |||||
@click="showOrgTree('avoidCompanyList')" | |||||
> | |||||
<el-icon> | |||||
<Plus /> | |||||
</el-icon>选择回避单位 | |||||
</el-button> | |||||
<p> | |||||
<el-tag | |||||
v-for="(item,index) in formData.avoidCompanyList" | |||||
:key="index" | |||||
class="mr-8" | |||||
closable | |||||
@close="delTag(index)" | |||||
> | |||||
{{ item.companyName }} | |||||
</el-tag> | |||||
</p> | |||||
</div> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="24"> | |||||
<el-form-item | |||||
label="职称证明" | |||||
prop="titleCertificateFile" | |||||
> | |||||
<el-upload | |||||
v-model:file-list="formData.titleCertificateFile" | |||||
class="w-full" | |||||
:action="uploadUrl" | |||||
:on-exceed="fileExceed" | |||||
:limit="1" | |||||
:on-success=" | |||||
res => | |||||
handleFileSuccess( | |||||
res, | |||||
formData.titleCertificateFile | |||||
) | |||||
" | |||||
:on-preview="handleFilePreview" | |||||
accept="application/pdf,image/png,image/jpeg" | |||||
:before-upload=" | |||||
file => | |||||
fileFormatVerification(file, { | |||||
types: ['png', 'jpg', 'jpeg','pdf'],size:1024})" | |||||
> | |||||
<el-button | |||||
type="primary" | |||||
plain | |||||
>选择文件</el-button> | |||||
<template #tip> | |||||
<div class="el-upload__tip"> | |||||
支持扩展名:.pdf .png .jpg .pdf,文件大小不超过1M | |||||
</div> | |||||
</template> | |||||
</el-upload> | |||||
</el-form-item> | |||||
</el-col> | |||||
</el-row> | |||||
</el-form> | |||||
<org-tree | |||||
:visible="orgProps.unitVisible" | |||||
:show-checkbox="orgProps.showCheckbox" | |||||
:default-data="orgProps.data" | |||||
@close="closeOrg" | |||||
@get-select-unit="getOrgData" | |||||
/> | |||||
</template> | |||||
<style lang="less"> | |||||
.professionalInfo{ | |||||
} | |||||
</style> |
@@ -0,0 +1,124 @@ | |||||
<script name="recommendInfo" setup> | |||||
import { getCurrentInstance, onMounted, ref } from 'vue' | |||||
import store from '@/store' | |||||
import { fileFormatVerification, handleFileSuccess, handleFilePreview } from '@/utils/uploadAction.js' | |||||
const uploadUrl = store.dictStore.uploadUrl, | |||||
{ proxy } = getCurrentInstance(), | |||||
formData = ref({ | |||||
}), | |||||
formRef = ref(), | |||||
rules = { | |||||
recommendedWay: [ | |||||
{ required: true, message: '请选择推荐类型', trigger: 'blur' } | |||||
], | |||||
recommendationProofFile: [ | |||||
{ required: true, message: '请上传推荐证明', trigger: 'blur' } | |||||
] | |||||
}, | |||||
// 校验 | |||||
validForm = (callback) => { | |||||
formRef.value.validate(valid => { | |||||
callback(valid) | |||||
}) | |||||
}, | |||||
fileExceed = (files, uploadFiles) => { | |||||
proxy.$message.warning('仅限上传一个文件') | |||||
}, | |||||
// 回显 | |||||
setFormData = (data) => { | |||||
formData.value = { | |||||
...data, | |||||
recommendedWay: data.recommendedWay?.[0] || undefined, | |||||
recommendationProofFile: data.recommendationProofFile && data.recommendationProofFile.map(i => { | |||||
return { | |||||
name: i.fileName, | |||||
response: { | |||||
data: { | |||||
id: i.fileId | |||||
} | |||||
}, | |||||
fileUrlById: i.url | |||||
} | |||||
}) | |||||
} | |||||
} | |||||
defineExpose({ validForm, formData, setFormData }) | |||||
onMounted(async () => { | |||||
}) | |||||
</script> | |||||
<template> | |||||
<el-form | |||||
ref="formRef" | |||||
:model="formData" | |||||
:rules="rules" | |||||
label-position="right" | |||||
label-width="120px" | |||||
label-suffix=":" | |||||
scroll-to-error | |||||
class="recommendInfo" | |||||
> | |||||
<el-row :gutter="8"> | |||||
<el-col :span="8"> | |||||
<el-form-item | |||||
label="推荐类型" | |||||
prop="recommendedWay" | |||||
> | |||||
<el-select | |||||
v-model="formData.recommendedWay" | |||||
class="w-full" | |||||
placeholder="请选择" | |||||
value-key="dictionaryCode" | |||||
> | |||||
<el-option | |||||
v-for="(item,index) in store.dictStore.recommendedWayDict" | |||||
:key="index" | |||||
:label="item.dictionaryName" | |||||
:value="item" | |||||
/> | |||||
</el-select> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="24"> | |||||
<el-form-item | |||||
label="推荐证明" | |||||
prop="recommendationProofFile" | |||||
> | |||||
<el-upload | |||||
v-model:file-list="formData.recommendationProofFile" | |||||
class="w-full" | |||||
:action="uploadUrl" | |||||
:limit="1" | |||||
:on-exceed="fileExceed" | |||||
:on-success=" | |||||
res => | |||||
handleFileSuccess( | |||||
res, | |||||
formData.recommendationProofFile | |||||
) | |||||
" | |||||
:on-preview="handleFilePreview" | |||||
accept="application/pdf,image/png,image/jpeg,image/jpg" | |||||
:before-upload=" | |||||
file => | |||||
fileFormatVerification(file, { | |||||
types:['png', 'jpg', 'jpeg','pdf'],size:1024})" | |||||
> | |||||
<el-button | |||||
type="primary" | |||||
plain | |||||
>选择文件</el-button> | |||||
<template #tip> | |||||
<div class="el-upload__tip"> | |||||
支持扩展名:.pdf .png .jpg .pdf ,文件大小不超过1M | |||||
</div> | |||||
</template> | |||||
</el-upload> | |||||
</el-form-item> | |||||
</el-col> | |||||
</el-row> | |||||
</el-form> | |||||
</template> | |||||
<style lang="less"> | |||||
.recommendInfo{ | |||||
} | |||||
</style> |
@@ -0,0 +1,409 @@ | |||||
<script name="addOrEditExpert" setup> | |||||
import { getCurrentInstance, ref, onMounted, reactive } from 'vue' | |||||
import { useRoute, useRouter } from 'vue-router' | |||||
import basicInfo from './components/basicInfo.vue' | |||||
import eduInfo from './components/eduInfo.vue' | |||||
import jobInfo from './components/jobInfo.vue' | |||||
import professionalInfo from './components/professionalInfo.vue' | |||||
import recommendInfo from './components/recommendInfo.vue' | |||||
import expertOtherInfo from './components/expertOtherInfo.vue' | |||||
import { expertEdit, expertSignUp, modifyApply, registration } from '@/http/apis/expertManage/expertStore' | |||||
import { downloadFileUrl } from '@/utils/uploadAction.js' | |||||
import { getExpertDetail } from '@/http/apis/expertManage/expertVerify' | |||||
import { getVerificationCode } from '@/http/apis/auth' | |||||
import { storeToRefs } from 'pinia' | |||||
import store from '@/store' | |||||
const { proxy } = getCurrentInstance(), | |||||
route = useRoute(), | |||||
router = useRouter(), | |||||
formData = ref({ | |||||
basicInfo: { | |||||
// isDingUser: false | |||||
} | |||||
}), | |||||
basicInfoRef = ref(), // 基本信息 | |||||
eduInfoRef = ref(), // 学历信息 | |||||
jobInfoRef = ref(), // 职业信息 | |||||
professionalInfoRef = ref(), // 专业信息 | |||||
recommendInfoRef = ref(), // 推荐信息 | |||||
expertOtherInfoRef = ref(), // 其他信息 | |||||
// 提交 | |||||
submitForm = async () => { | |||||
const form = [] | |||||
form.push(new Promise((resolve, reject) => { | |||||
basicInfoRef.value.validForm((valid) => { | |||||
if (valid) resolve() | |||||
}) | |||||
})) | |||||
form.push(new Promise((resolve, reject) => { | |||||
eduInfoRef.value.validForm((valid) => { | |||||
if (valid) resolve() | |||||
}) | |||||
})) | |||||
form.push(new Promise((resolve, reject) => { | |||||
jobInfoRef.value.validForm((valid) => { | |||||
if (valid) resolve() | |||||
}) | |||||
})) | |||||
form.push(new Promise((resolve, reject) => { | |||||
professionalInfoRef.value.validForm((valid) => { | |||||
if (valid) resolve() | |||||
}) | |||||
})) | |||||
form.push(new Promise((resolve, reject) => { | |||||
recommendInfoRef.value.validForm((valid) => { | |||||
if (valid) resolve() | |||||
}) | |||||
})) | |||||
form.push(new Promise((resolve, reject) => { | |||||
expertOtherInfoRef.value.validForm((valid) => { | |||||
if (valid) resolve() | |||||
}) | |||||
})) | |||||
Promise.all([...form]).then(async () => { | |||||
saveData() | |||||
}).catch(err => { | |||||
if (err) { | |||||
proxy.$message.warning(err) | |||||
} | |||||
}) | |||||
}, | |||||
saveData = async () => { | |||||
var data = { | |||||
expertUserId: route.name === 'selfEditExpertInfo' ? userInfo.value.userId : route.query.id || undefined, | |||||
basicInfo: { | |||||
...basicInfoRef.value.formData, | |||||
isDingUser: basicInfoRef.value.formData.isDingUser, | |||||
avatarUrl: basicInfoRef.value.formData?.avatarFile?.fileId && await downloadFileUrl(basicInfoRef.value.formData.avatarFile.fileId), | |||||
expertIntentionWorkRegions: | |||||
basicInfoRef.value.formData.expertIntentionWorkRegions?.map((i, index) => ({ | |||||
regionName: i.unionCode?.join('@@'), | |||||
regionCode: i.unionCode?.slice(-1)[0]?.split('##')[0], | |||||
regionLevel: i.unionCode?.slice(-1)[0]?.split('##')[2] | |||||
})), | |||||
expertRegionInfo: { | |||||
regionName: basicInfoRef.value.formData.expertRegionInfo?.join('@@'), | |||||
regionCode: basicInfoRef.value.formData.expertRegionInfo?.slice(-1)[0].split('##')[0], | |||||
regionLevel: basicInfoRef.value.formData.expertRegionInfo?.slice(-1)[0].split('##')[2] | |||||
}, | |||||
political: basicInfoRef.value.formData.political && [basicInfoRef.value.formData.political] || [], | |||||
expertSource: basicInfoRef.value.formData.expertSource && [basicInfoRef.value.formData.expertSource] || [], | |||||
expertType: basicInfoRef.value.formData.expertType && [basicInfoRef.value.formData.expertType] || [] | |||||
}, | |||||
eduInfo: { | |||||
...eduInfoRef.value.formData, | |||||
edu: eduInfoRef.value.formData.edu && [eduInfoRef.value.formData.edu], | |||||
degree: eduInfoRef.value.formData.degree && [eduInfoRef.value.formData.degree], | |||||
degreeCertificateFile: eduInfoRef.value.formData.degreeCertificateFile && await Promise.all( | |||||
eduInfoRef.value.formData.degreeCertificateFile && eduInfoRef.value.formData.degreeCertificateFile.map(async i => { | |||||
return { | |||||
fileName: i.name, | |||||
fileId: i.response.data.id, | |||||
url: i.fileUrlById | |||||
} | |||||
}) | |||||
) || [], | |||||
graduationCertificateFile: eduInfoRef.value.formData.graduationCertificateFile && await Promise.all( | |||||
eduInfoRef.value.formData.graduationCertificateFile && eduInfoRef.value.formData.graduationCertificateFile.map(async i => { | |||||
return { | |||||
fileName: i.name, | |||||
fileId: i.response.data.id, | |||||
url: i.fileUrlById | |||||
} | |||||
}) | |||||
) || [] | |||||
}, | |||||
jobInfo: { | |||||
...jobInfoRef.value.formData, | |||||
administrativeRank: jobInfoRef.value.formData.administrativeRank && [jobInfoRef.value.formData.administrativeRank] || [], | |||||
jobStatus: jobInfoRef.value.formData.jobStatus && [jobInfoRef.value.formData.jobStatus] || [], | |||||
companyAttribute: jobInfoRef.value.formData.companyAttribute && [jobInfoRef.value.formData.companyAttribute] || [] | |||||
}, | |||||
professionalInfo: { | |||||
...professionalInfoRef.value.formData, | |||||
goodAt: professionalInfoRef.value.formData.goodAt.map(i => { | |||||
return { | |||||
...i, | |||||
tagFieldName: 'good_at' | |||||
} | |||||
}) || [], | |||||
titleLevel: professionalInfoRef.value.formData.titleLevel && [professionalInfoRef.value.formData.titleLevel] || [], | |||||
titleCertificateFile: professionalInfoRef.value.formData.titleCertificateFile && await Promise.all( | |||||
professionalInfoRef.value.formData.titleCertificateFile && professionalInfoRef.value.formData.titleCertificateFile.map(async i => { | |||||
return { | |||||
fileName: i.name, | |||||
fileId: i.response.data.id, | |||||
url: i.fileUrlById | |||||
} | |||||
}) | |||||
) || [], | |||||
technicalExpertise: professionalInfoRef.value.formData.technicalExpertise && professionalInfoRef.value.formData.technicalExpertise.map(i => { | |||||
return { | |||||
tagCode: i.split('##')[1], | |||||
tagName: i.split('##')[0] | |||||
} | |||||
}), | |||||
industrySector: professionalInfoRef.value.formData.industrySector && professionalInfoRef.value.formData.industrySector.map(i => { | |||||
return { | |||||
tagCode: i.split('##')[1], | |||||
tagName: i.split('##')[0] | |||||
} | |||||
}) | |||||
}, | |||||
recommendInfo: { | |||||
...recommendInfoRef.value.formData, | |||||
recommendedWay: recommendInfoRef.value.formData.recommendedWay && [recommendInfoRef.value.formData.recommendedWay] || [], | |||||
recommendationProofFile: recommendInfoRef.value.formData.recommendationProofFile && await Promise.all( | |||||
recommendInfoRef.value.formData.recommendationProofFile && recommendInfoRef.value.formData.recommendationProofFile.map(async i => { | |||||
return { | |||||
fileName: i.name, | |||||
fileId: i.response.data.id, | |||||
url: i.fileUrlById | |||||
} | |||||
}) | |||||
) || [] | |||||
}, | |||||
expertOtherInfo: { | |||||
...expertOtherInfoRef.value.formData, | |||||
other: expertOtherInfoRef.value.formData.other && expertOtherInfoRef.value.formData.other.map(i => { | |||||
return { | |||||
tagCode: i.split('##')[1], | |||||
tagName: i.split('##')[0] | |||||
} | |||||
}) | |||||
} | |||||
} | |||||
if (route.name === 'expertEnroll') { | |||||
showSmsDiaglog(data) | |||||
} else { | |||||
if (!route.query.id && route.name !== 'selfEditExpertInfo') { | |||||
await expertSignUp(data) | |||||
proxy.$message.success('专家新增成功') | |||||
router.go(-1) | |||||
} else { | |||||
const apiFn = route.name === 'selfEditExpertInfo' ? modifyApply : expertEdit | |||||
await apiFn(data) | |||||
proxy.$message.success(route.name === 'selfEditExpertInfo' ? '申请成功' : '专家编辑成功') | |||||
route.name !== 'selfEditExpertInfo' && router.go(-1) | |||||
} | |||||
} | |||||
}, | |||||
// 专家报名-短信验证 | |||||
smsDialogData = reactive({ | |||||
visible: false, | |||||
data: {} | |||||
}), | |||||
showSmsDiaglog = (data) => { | |||||
smsDialogData.data = data | |||||
smsDialogData.visible = true | |||||
}, | |||||
smsDialogFormRef = ref(), | |||||
smsDialogForm = ref({ | |||||
verificationCode: '' | |||||
}), | |||||
smsDialogRules = { | |||||
'verificationCode': [{ required: true, message: '请输入' }] | |||||
}, | |||||
smsDialogLoading = ref(false), | |||||
submitSms = async (formEl) => { | |||||
if (!formEl) { | |||||
return | |||||
} | |||||
formEl.validate(async (valid) => { | |||||
if (valid) { | |||||
await registration({ | |||||
...smsDialogData.data, | |||||
verificationCode: smsDialogForm.value.verificationCode | |||||
}) | |||||
proxy.$message.success('提交成功') | |||||
router.go(0) | |||||
} | |||||
} | |||||
) | |||||
}, | |||||
timer = ref(null), | |||||
count = ref(0), | |||||
getVerificationCodeFunc = async () => { | |||||
await getVerificationCode({ mobile: basicInfoRef.value.formData.phoneNo, verificationType: 'RECOMMENDATION_PROOF_FILE_SUBMIT' }) | |||||
proxy.$message.success('验证码已发送') | |||||
const TIME_COUNT = 60 | |||||
if (!timer.value) { | |||||
count.value = TIME_COUNT | |||||
timer.value = setInterval(() => { | |||||
if (count.value > 0 && count.value <= TIME_COUNT) { | |||||
count.value-- | |||||
} else { | |||||
clearInterval(timer.value) | |||||
timer.value = null | |||||
} | |||||
}, 1000) | |||||
} | |||||
}, | |||||
// 获取详情 | |||||
getDetail = async () => { | |||||
const res = await getExpertDetail({ expertUserId: route.name === 'selfEditExpertInfo' ? userInfo.value.userId : route.query.id }) | |||||
// formData.value.basicInfo.isDingUser = res.data.basicInfo.isDingUser | |||||
basicInfoRef.value.setFormData(res.data.basicInfo) | |||||
eduInfoRef.value.setFormData(res.data.eduInfo) | |||||
jobInfoRef.value.setFormData(res.data.jobInfo) | |||||
professionalInfoRef.value.setFormData(res.data.professionalInfo) | |||||
recommendInfoRef.value.setFormData(res.data.recommendInfo) | |||||
expertOtherInfoRef.value.setFormData(res.data.expertOtherInfo) | |||||
}, | |||||
userInfo = storeToRefs(store.userStore).userInfo | |||||
onMounted(() => { | |||||
if (route.query.id || route.name === 'selfEditExpertInfo') { | |||||
getDetail() | |||||
} | |||||
}) | |||||
</script> | |||||
<template> | |||||
<div class="addOrEditExpert footerPage" :class="{ 'relative':route.path === 'expertEnroll'}"> | |||||
<div v-if="route.name === 'expertEnroll'" class="header">丽水市信息化专家报名</div> | |||||
<el-card shadow="never" class="mb-16"> | |||||
<template #header> | |||||
<div class="card-header flex items-center justify-between"> | |||||
<span>基本信息</span> | |||||
<!-- <span class="flex items-center">是否在浙政钉组内: | |||||
<el-switch | |||||
v-model="formData.basicInfo.isDingUser" | |||||
inline-prompt | |||||
active-text="是" | |||||
inactive-text="否" | |||||
/> | |||||
</span> --> | |||||
</div> | |||||
</template> | |||||
<basic-info ref="basicInfoRef" :basic-info="formData.basicInfo" /> | |||||
</el-card> | |||||
<el-card shadow="never" class="mb-16"> | |||||
<template #header> | |||||
<div> | |||||
<span>学历信息</span> | |||||
</div> | |||||
</template> | |||||
<edu-info ref="eduInfoRef" /> | |||||
</el-card> | |||||
<el-card shadow="never" class="mb-16"> | |||||
<template #header> | |||||
<div> | |||||
<span>职业信息</span> | |||||
</div> | |||||
</template> | |||||
<job-info ref="jobInfoRef" /> | |||||
</el-card> | |||||
<el-card shadow="never" class="mb-16"> | |||||
<template #header> | |||||
<div> | |||||
<span>专业信息</span> | |||||
</div> | |||||
</template> | |||||
<professional-info ref="professionalInfoRef" /> | |||||
</el-card> | |||||
<el-card shadow="never" class="mb-16"> | |||||
<template #header> | |||||
<div> | |||||
<span>推荐信息</span> | |||||
</div> | |||||
</template> | |||||
<recommend-info ref="recommendInfoRef" /> | |||||
</el-card> | |||||
<el-card shadow="never" class="mb-16"> | |||||
<template #header> | |||||
<div> | |||||
<span>其他信息</span> | |||||
</div> | |||||
</template> | |||||
<expert-other-info ref="expertOtherInfoRef" /> | |||||
</el-card> | |||||
<div class="footer"> | |||||
<el-button | |||||
type="primary" | |||||
@click="submitForm" | |||||
> | |||||
提交 | |||||
</el-button> | |||||
<el-button @click="router.go(-1)">取消</el-button> | |||||
</div> | |||||
<el-dialog | |||||
:model-value="smsDialogData.visible" | |||||
title="短信验证" | |||||
width="400px" | |||||
destroy-on-close | |||||
@close="smsDialogData.visible=false" | |||||
> | |||||
<el-form | |||||
ref="smsDialogFormRef" | |||||
:model="smsDialogForm" | |||||
:rules="smsDialogRules" | |||||
label-width="auto" | |||||
label-suffix=":" | |||||
> | |||||
<el-form-item label="手机号"> | |||||
<span>{{ basicInfoRef.formData.phoneNo }}</span> | |||||
</el-form-item> | |||||
<el-form-item label="验证码" prop="verificationCode"> | |||||
<el-input v-model="smsDialogForm.verificationCode" placeholder="请输入验证码"> | |||||
<template #suffix> | |||||
<a v-if="!count" class="itemBlue" @click="getVerificationCodeFunc"> 获取验证码</a> | |||||
<span v-else class="itemBlue">{{ count }}</span> | |||||
</template> | |||||
</el-input> | |||||
</el-form-item> | |||||
</el-form> | |||||
<template #footer> | |||||
<el-button | |||||
type="primary" | |||||
:loading="smsDialogLoading" | |||||
@click="submitSms(smsDialogFormRef)" | |||||
> | |||||
提交 | |||||
</el-button> | |||||
<el-button | |||||
@click="smsDialogData.visible=false" | |||||
> | |||||
关闭 | |||||
</el-button> | |||||
</template> | |||||
</el-dialog> | |||||
</div> | |||||
</template> | |||||
<style lang="less" scoped> | |||||
.addOrEditExpert{ | |||||
.header{ | |||||
height: 60px; | |||||
display: flex; | |||||
justify-content: center; | |||||
align-items: center; | |||||
background-color: #fff; | |||||
margin-bottom: 15px; | |||||
font-size: 20px; | |||||
} | |||||
:deep(.el-collapse) { | |||||
.el-collapse-item__header { | |||||
padding: 0px 16px; | |||||
font-size: 14px; | |||||
} | |||||
.el-collapse-item__content { | |||||
padding: 16px 16px 16px 0px; | |||||
// margin-left: -50px; | |||||
} | |||||
.el-collapse-item__header.is-active { | |||||
border-bottom: 1px solid rgba(0, 0, 0, 0.1); | |||||
} | |||||
.collapse-title { | |||||
flex: 1 0 90%; | |||||
order: 1; | |||||
.el-collapse-item__header { | |||||
flex: 1 0 auto; | |||||
order: -1; | |||||
} | |||||
.el-input-number { | |||||
width: 150px !important; | |||||
} | |||||
} | |||||
} | |||||
} | |||||
</style> |
@@ -0,0 +1,168 @@ | |||||
<script name="evaluateDialog" setup> | |||||
import { getCurrentInstance, nextTick, ref, watch } from 'vue' | |||||
import { judgeDetail, judgeSubmit } from '@/http/apis/expertManage/expertStore' | |||||
const { proxy } = getCurrentInstance(), | |||||
props = defineProps({ | |||||
visible: { | |||||
type: Boolean, | |||||
default: false | |||||
}, | |||||
data: { | |||||
type: Object, | |||||
default: () => {} | |||||
}, | |||||
isEdit: { | |||||
type: Boolean, | |||||
default: true | |||||
} | |||||
}), | |||||
emits = defineEmits(['close']), | |||||
formData = ref({}), | |||||
formRef = ref(), | |||||
rules = { | |||||
score: [{ required: true, message: '请输入' }], | |||||
attended: [{ required: true, message: '请选择' }], | |||||
performance: [{ required: true, message: '请选择' }], | |||||
advised: [{ required: true, message: '请选择' }], | |||||
leaveEarly: [{ required: true, message: '请选择' }], | |||||
brokeRule: [{ required: true, message: '请选择' }], | |||||
brokeRuleContent: [{ required: true, message: '请选择' }] | |||||
}, | |||||
loading = ref(false), | |||||
submit = async (formEl) => { | |||||
if (!formEl) return | |||||
await formEl.validate(async valid => { | |||||
if (valid) { | |||||
loading.value = true | |||||
try { | |||||
const postData = { | |||||
...formData.value | |||||
} | |||||
await judgeSubmit(postData) | |||||
proxy.$message.success('提交成功!') | |||||
loading.value = false | |||||
emits('close', true) | |||||
} catch (e) { | |||||
loading.value = false | |||||
} | |||||
} | |||||
}) | |||||
}, | |||||
getDetail = async () => { | |||||
const res = await judgeDetail(props.data.meetingExpertId) | |||||
formData.value = { | |||||
...res.data | |||||
} | |||||
} | |||||
watch( | |||||
() => props.visible, | |||||
async val => { | |||||
if (val) { | |||||
await nextTick() | |||||
formRef.value.clearValidate() | |||||
formData.value = { | |||||
meetingExpertId: props.data.meetingExpertId, | |||||
meetingId: props.data.meetingId | |||||
} | |||||
if (!props.isEdit) { | |||||
getDetail() | |||||
} | |||||
} | |||||
} | |||||
) | |||||
defineExpose({ formRef }) | |||||
</script> | |||||
<template> | |||||
<el-dialog :model-value="visible" :title="isEdit?'履职评价':'查看评价'" @close="emits('close')"> | |||||
<el-form | |||||
ref="formRef" | |||||
:model="formData" | |||||
:rules="rules" | |||||
label-suffix=":" | |||||
> | |||||
<el-form-item v-if="isEdit" label="评分" prop="score"> | |||||
<el-input-number | |||||
v-model="formData.score" | |||||
placeholder="请对该专家在本次会议的表现进行评分,最低0分,满分10分" | |||||
:min="0" | |||||
:max="10" | |||||
:controls="false" | |||||
@mousewheel.prevent | |||||
/> | |||||
</el-form-item> | |||||
<el-form-item v-else label="评分"> | |||||
<span>{{ formData.score }}</span> | |||||
</el-form-item> | |||||
<el-form-item v-if="isEdit" label="专家是否参加" prop="attended"> | |||||
<el-radio-group v-model="formData.attended"> | |||||
<el-radio :label="1">准时参加</el-radio> | |||||
<el-radio :label="2">迟到</el-radio> | |||||
<el-radio :label="3">缺席</el-radio> | |||||
</el-radio-group> | |||||
</el-form-item> | |||||
<el-form-item v-else label="专家是否参加"> | |||||
<span>{{ formData.attended===1?'准时参加':formData.attended===2?'迟到':'缺席' }}</span> | |||||
</el-form-item> | |||||
<template v-if="formData.attended!==3"> | |||||
<el-form-item v-if="isEdit" label="专家参与程度" prop="performance"> | |||||
<el-radio-group v-model="formData.performance"> | |||||
<el-radio :label="1">积极</el-radio> | |||||
<el-radio :label="2">消极</el-radio> | |||||
</el-radio-group> | |||||
</el-form-item> | |||||
<el-form-item v-else label="专家参与程度"> | |||||
<span>{{ formData.performance===1?'积极':formData.performance===2?'消极':'-' }}</span> | |||||
</el-form-item> | |||||
<el-form-item v-if="isEdit" label="专家是否提出专业建议" prop="advised"> | |||||
<el-radio-group v-model="formData.advised"> | |||||
<el-radio :label="true">有提出</el-radio> | |||||
<el-radio :label="false">未提出</el-radio> | |||||
</el-radio-group> | |||||
</el-form-item> | |||||
<el-form-item v-else label="专家是否提出专业建议"> | |||||
<span>{{ formData.advised?'有提出':'未提出' }}</span> | |||||
</el-form-item> | |||||
<el-form-item v-if="isEdit" label=" 专家是否早退" prop="leaveEarly"> | |||||
<el-radio-group v-model="formData.leaveEarly"> | |||||
<el-radio :label="false">未早退</el-radio> | |||||
<el-radio :label="true">早退</el-radio> | |||||
</el-radio-group> | |||||
</el-form-item> | |||||
<el-form-item v-else label="专家是否早退"> | |||||
<span>{{ formData.leaveEarly?'早退':'未早退' }}</span> | |||||
</el-form-item> | |||||
<el-form-item v-if="isEdit" label="专家有无违规行为" prop="brokeRule"> | |||||
<el-radio-group v-model="formData.brokeRule"> | |||||
<el-radio :label="false">无</el-radio> | |||||
<el-radio :label="true">有</el-radio> | |||||
</el-radio-group> | |||||
</el-form-item> | |||||
<el-form-item v-else label="专家有无违规行为"> | |||||
<span>{{ formData.brokeRule?'有':'无' }}</span> | |||||
</el-form-item> | |||||
<template v-if="formData.brokeRule"> | |||||
<el-form-item v-if="isEdit" label="违规行为" prop="brokeRuleContent"> | |||||
<el-input | |||||
v-model="formData.brokeRuleContent" | |||||
placeholder="请填写" | |||||
type="textarea" | |||||
:maxlength="200" | |||||
show-word-limit | |||||
/> | |||||
</el-form-item> | |||||
<el-form-item v-else label="违规行为"> | |||||
<span>{{ formData.brokeRuleContent }}</span> | |||||
</el-form-item> | |||||
</template> | |||||
</template> | |||||
</el-form> | |||||
<template v-if="isEdit" #footer> | |||||
<span class="dialog-footer"> | |||||
<el-button type="primary" :loading="loading" @click="submit(formRef)">提交</el-button> | |||||
<el-button @click="emits('close')">关闭</el-button> | |||||
</span> | |||||
</template> | |||||
</el-dialog> | |||||
</template> |
@@ -0,0 +1,147 @@ | |||||
<script> | |||||
import { defineComponent } from 'vue' | |||||
export default defineComponent({ | |||||
beforeRouteEnter (to, from, next) { | |||||
if (to.query.name) { | |||||
to.meta.title = '履职记录-' + to.query.name | |||||
} | |||||
next() | |||||
} | |||||
}) | |||||
</script> | |||||
<script setup name='deputyActivityRecord'> | |||||
import { reactive, ref, onMounted, h } from 'vue' | |||||
import { getDeputyActivityRecord } from '@/http/apis/expertManage/expertStore' | |||||
import MeetingProjectDialog from '@/pages/expertManage/reviewMeeting/components/meetingProjectDialog.vue' | |||||
import { useRoute } from 'vue-router' | |||||
import EvaluateDialog from '@/pages/expertManage/expertStore/deputyActivityRecord/components/evaluateDialog.vue' | |||||
const route = useRoute(), | |||||
tableListRef = ref(), | |||||
total = ref(0), | |||||
// 列表数据 | |||||
column = reactive([ | |||||
{ | |||||
label: '序号', | |||||
type: 'index', | |||||
width: '60' | |||||
}, | |||||
{ | |||||
label: '会议名称', | |||||
key: 'meetingName', | |||||
prop: 'meetingName', | |||||
minWidth: '80', | |||||
showOverflowTooltip: true | |||||
}, | |||||
{ | |||||
label: '评审项目', | |||||
slot: 'projectName', | |||||
minWidth: '100', | |||||
showOverflowTooltip: true | |||||
}, | |||||
{ | |||||
label: '评审时间', | |||||
key: 'createOn', | |||||
prop: 'createOn', | |||||
width: '180' | |||||
}, | |||||
{ | |||||
label: '是否参会', | |||||
key: 'inviteStatus', | |||||
prop: 'inviteStatus', | |||||
width: '150', | |||||
render: row => h('span', '是') | |||||
}, | |||||
{ | |||||
label: '是否请假', | |||||
key: 'expertStatus', | |||||
prop: 'expertStatus', | |||||
width: '150', | |||||
render: row => h('span', row.expertStatus === 5 ? '是' : '否') | |||||
}, | |||||
{ | |||||
label: '是否评价', | |||||
key: 'hasJudge', | |||||
prop: 'hasJudge', | |||||
width: '150', | |||||
render: row => h('span', row.hasJudge ? '是' : '否') | |||||
}, | |||||
{ | |||||
label: '操作', | |||||
slot: 'action', | |||||
width: '100', | |||||
fixed: 'right' | |||||
} | |||||
]), | |||||
data = ref([]), | |||||
getTableData = async (pageParams = tableListRef.value.pageParams) => { | |||||
const res = await getDeputyActivityRecord({ | |||||
...pageParams, | |||||
expertId: route.query.id | |||||
}) | |||||
data.value = res.data.records | |||||
total.value = res.data.total | |||||
}, | |||||
// 查看项目 | |||||
viewProject = (data) => { | |||||
meetingProjectDialogData.value.visible = true | |||||
meetingProjectDialogData.value.meetingId = data.meetingId | |||||
}, | |||||
meetingProjectDialogData = ref({ | |||||
visible: false, | |||||
meetingId: undefined | |||||
}), | |||||
close = () => { | |||||
meetingProjectDialogData.value.visible = false | |||||
}, | |||||
// 履职评价 | |||||
evaluateDialogData = reactive({ | |||||
visible: false, | |||||
data: {}, | |||||
isEdit: true | |||||
}), | |||||
evaluateDialogRef = ref(), | |||||
showEvaluateDialog = (data, isEdit) => { | |||||
evaluateDialogData.data = data | |||||
evaluateDialogData.isEdit = isEdit | |||||
evaluateDialogData.visible = true | |||||
}, | |||||
closeEvaluateDialog = (flag) => { | |||||
evaluateDialogData.visible = false | |||||
flag && getTableData() | |||||
} | |||||
onMounted(() => { | |||||
getTableData() | |||||
}) | |||||
</script> | |||||
<template> | |||||
<div class=""> | |||||
<el-card class="box-card"> | |||||
<table-list | |||||
ref="tableListRef" | |||||
:column="column" | |||||
:data="data" | |||||
:total="total" | |||||
@get-table-data="getTableData" | |||||
> | |||||
<template #projectName="{scope}"> | |||||
<a @click="viewProject(scope.row)">查看</a> | |||||
</template> | |||||
<template #action="{scope}"> | |||||
<a v-if="!scope.row.hasJudge" @click="showEvaluateDialog(scope.row,true)">履职评价</a> | |||||
<a v-else @click="showEvaluateDialog(scope.row,false)">查看评价</a> | |||||
</template> | |||||
</table-list> | |||||
</el-card> | |||||
<meeting-project-dialog :visible="meetingProjectDialogData.visible" :meeting-id="meetingProjectDialogData.meetingId" @close="close" /> | |||||
</div> | |||||
<evaluate-dialog | |||||
ref="evaluateDialogRef" | |||||
:visible="evaluateDialogData.visible" | |||||
:data="evaluateDialogData.data" | |||||
:is-edit="evaluateDialogData.isEdit" | |||||
@close="closeEvaluateDialog" | |||||
/> | |||||
</template> | |||||
@@ -0,0 +1,315 @@ | |||||
<script setup name='expertDetail'> | |||||
import { ref, onMounted } from 'vue' | |||||
import { useRoute, useRouter } from 'vue-router' | |||||
import { getExpertDetail } from '@/http/apis/expertManage/expertVerify' | |||||
import Accessory from '@/components/accessory/index.vue' | |||||
const route = useRoute() | |||||
const router = useRouter() | |||||
const activeName = ref('basicInfo') | |||||
const handleClick = (tab, event) => { | |||||
console.log(tab, event) | |||||
} | |||||
const expertInfo = ref({ basicInfo: {}, eduInfo: {}, jobInfo: {}, professionalInfo: {}, recommendInfo: {}}) | |||||
const getVerifyDetail = async () => { | |||||
const res = await getExpertDetail({ expertUserId: route.query.id }) | |||||
expertInfo.value = res.data | |||||
} | |||||
// 查看文件 | |||||
const view = (data) => { | |||||
const routeUrl = router.resolve({ | |||||
path: '/fileView', | |||||
query: { id: data } | |||||
}) | |||||
window.open(routeUrl.href, '_blank') | |||||
} | |||||
onMounted(async () => { | |||||
getVerifyDetail() | |||||
}) | |||||
</script> | |||||
<template> | |||||
<div class=""> | |||||
<el-card class="box-card"> | |||||
<el-tabs | |||||
v-model="activeName" | |||||
class="demo-tabs" | |||||
@tab-click="handleClick" | |||||
> | |||||
<el-tab-pane | |||||
label="基本信息" | |||||
name="basicInfo" | |||||
> | |||||
<el-descriptions | |||||
class="mt-20" | |||||
title="" | |||||
:column="2" | |||||
border | |||||
> | |||||
<el-descriptions-item | |||||
label="专家名称" | |||||
span="1" | |||||
width="200px" | |||||
> | |||||
{{ expertInfo.basicInfo.name }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="是否在浙政钉组织"> | |||||
{{ expertInfo.basicInfo.isDingUser?'是':'否' }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item | |||||
label="手机号码" | |||||
width="200px" | |||||
> | |||||
{{ expertInfo.basicInfo.phoneNo }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="性别"> | |||||
{{ expertInfo.basicInfo.gender === '1' ? '男': '女' }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="籍贯"> | |||||
{{ expertInfo.basicInfo.hometown ||'-' }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="民族"> | |||||
{{ expertInfo.basicInfo.nationality ||'-' }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="政治面貌"> | |||||
{{ expertInfo.basicInfo.political?.[0].dictionaryName ||'-' }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="身份证号"> | |||||
{{ expertInfo.basicInfo.idCard||'-' }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="办公电话"> | |||||
{{ expertInfo.basicInfo.officePhone||'-' }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="出生年月"> | |||||
{{ expertInfo.basicInfo.birth ||'-' }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="银行卡号"> | |||||
{{ expertInfo.basicInfo.bankNo||'-' }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="开户银行"> | |||||
{{ expertInfo.basicInfo.bank||'-' }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="电子邮箱"> | |||||
{{ expertInfo.basicInfo.email||'-' }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="专家级别"> | |||||
{{ expertInfo.basicInfo?.expertRegionInfo?.regionName.split('@@').map(i=>i.split('##')[1]).join('-') }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="专家来源"> | |||||
{{ expertInfo.basicInfo.expertSource?.[0].tagName ||'-' }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="专家类型"> | |||||
{{ expertInfo.basicInfo.expertType?.[0].dictionaryName||'-' }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="履职意向"> | |||||
{{ expertInfo.basicInfo.expertIntentionWorkRegions?.map(i=>i.regionName.split('@@').map(j=>j.split('##')[1]).join('-')).join(';') }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item | |||||
label="头像(免冠照)" | |||||
span="2" | |||||
> | |||||
<a target="_blank" @click="view(expertInfo.basicInfo.avatarFile.fileId)">{{ expertInfo.basicInfo.avatarFile?.fileName }}</a> | |||||
</el-descriptions-item> | |||||
</el-descriptions> | |||||
</el-tab-pane> | |||||
<el-tab-pane | |||||
label="学历信息" | |||||
name="eduInfo" | |||||
> | |||||
<el-descriptions | |||||
class="mt-20" | |||||
title="" | |||||
:column="2" | |||||
border | |||||
> | |||||
<el-descriptions-item | |||||
label="毕业院校" | |||||
span="2" | |||||
width="200px" | |||||
> | |||||
{{ expertInfo.eduInfo.school||'-' }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="毕业时间"> | |||||
{{ expertInfo.eduInfo.graduatedAt||'-' }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item | |||||
label="所学专业" | |||||
width="200px" | |||||
> | |||||
{{ expertInfo.eduInfo.academicTitle ||'-' }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="学位"> | |||||
{{ expertInfo.eduInfo.degree?.[0].dictionaryName ||'-' }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="学历"> | |||||
{{ expertInfo.eduInfo.edu?.[0].dictionaryName ||'-' }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="毕业证书"> | |||||
<p v-for="(file,fileIndex) in expertInfo.eduInfo.graduationCertificateFile" :key="fileIndex" class="mb-4"> | |||||
<accessory :file-name="file.fileName" :file-id="file.fileId" /> | |||||
</p> | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="学位证书"> | |||||
<p v-for="(file,fileIndex) in expertInfo.eduInfo.degreeCertificateFile" :key="fileIndex" class="mb-4"> | |||||
<accessory :file-name="file.fileName" :file-id="file.fileId" /> | |||||
</p> | |||||
</el-descriptions-item> | |||||
</el-descriptions> | |||||
</el-tab-pane> | |||||
<el-tab-pane | |||||
label="职业信息" | |||||
name="professionInfo" | |||||
> | |||||
<el-descriptions | |||||
class="mt-20" | |||||
title="" | |||||
:column="2" | |||||
border | |||||
> | |||||
<el-descriptions-item | |||||
label="工作单位" | |||||
width="200px" | |||||
> | |||||
{{ expertInfo.jobInfo.company||'-' }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="工作单位code"> | |||||
{{ expertInfo.jobInfo.companyUniqCode ||'-' }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item | |||||
label="单位法人编号" | |||||
width="200px" | |||||
> | |||||
{{ expertInfo.jobInfo.legalEntityCode||'-' }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="行政职务"> | |||||
{{ expertInfo.jobInfo.administrativeDuties ||'-' }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="开始工作日期"> | |||||
{{ expertInfo.jobInfo.startWorkAt ||'-' }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="行政职级"> | |||||
{{ expertInfo.jobInfo.administrativeRank?.[0].dictionaryName||'-' }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="在职状态"> | |||||
{{ expertInfo.jobInfo.jobStatus?.[0].dictionaryName ||'-' }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="退休日期"> | |||||
{{ expertInfo.jobInfo.retiredAt||'-' }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="单位类型"> | |||||
{{ expertInfo.jobInfo.companyAttribute?.[0].dictionaryName ||'-' }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="条线"> | |||||
{{ expertInfo.jobInfo?.businessStrips?.map(i=>i.businessStripName).join('、')||'-' }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="工作地址"> | |||||
{{ expertInfo.jobInfo.address||'-' }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="工作经历"> | |||||
{{ expertInfo.jobInfo.experience||'-' }} | |||||
</el-descriptions-item> | |||||
</el-descriptions> | |||||
</el-tab-pane> | |||||
<el-tab-pane | |||||
label="专业信息" | |||||
name="majorInfo" | |||||
> | |||||
<el-descriptions | |||||
class="mt-20" | |||||
title="" | |||||
:column="2" | |||||
border | |||||
> | |||||
<el-descriptions-item | |||||
label="技术职称" | |||||
width="200px" | |||||
> | |||||
{{ expertInfo.professionalInfo.technicalTitles||'-' }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="职称级别"> | |||||
{{ expertInfo.professionalInfo.titleLevel?.[0].dictionaryName ||'-' }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item | |||||
label="擅长方向" | |||||
width="200px" | |||||
> | |||||
{{ expertInfo.professionalInfo.goodAt?.map(i=>i.tagName).join('、') ||'-' }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="技术专长"> | |||||
<span v-for="(item,index) in expertInfo.professionalInfo.technicalExpertise" :key="index">{{ item.tagName }} </span> | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="行业领域"> | |||||
<span v-for="(item,index) in expertInfo.professionalInfo.industrySector" :key="index">{{ item.tagName }} </span> | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="获奖情况"> | |||||
{{ expertInfo.professionalInfo.awards||'-' }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="表彰奖励"> | |||||
{{ expertInfo.professionalInfo.recognitionReward ||'-' }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="回避单位"> | |||||
<span v-for="(item, index) in expertInfo.professionalInfo.avoidCompanyList" :key="index">{{ item.companyName }} </span> | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="职称证明"> | |||||
<p v-for="(file,fileIndex) in expertInfo.professionalInfo.titleCertificateFile" :key="fileIndex" class="mb-4"> | |||||
<accessory :file-name="file.fileName" :file-id="file.fileId" /> | |||||
</p> | |||||
</el-descriptions-item> | |||||
</el-descriptions> | |||||
</el-tab-pane> | |||||
<el-tab-pane | |||||
label="推荐信息" | |||||
name="recommendInfo" | |||||
> | |||||
<el-descriptions | |||||
class="mt-20" | |||||
title="" | |||||
:column="2" | |||||
border | |||||
> | |||||
<el-descriptions-item | |||||
label="推荐类型" | |||||
width="200px" | |||||
> | |||||
{{ expertInfo.recommendInfo.recommendedWay?.[0].dictionaryName||'-' }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item | |||||
width="200px" | |||||
label="推荐证明" | |||||
> | |||||
<p v-for="(file,fileIndex) in expertInfo.recommendInfo.recommendationProofFile" :key="fileIndex" class="mb-4"> | |||||
<accessory :file-name="file.fileName" :file-id="file.fileId" /> | |||||
</p> | |||||
</el-descriptions-item> | |||||
</el-descriptions> | |||||
</el-tab-pane> | |||||
<el-tab-pane | |||||
label="其他信息" | |||||
name="otherInfo" | |||||
> | |||||
<el-descriptions | |||||
class="mt-20" | |||||
title="" | |||||
:column="2" | |||||
border | |||||
> | |||||
<el-descriptions-item | |||||
label="其他标签" | |||||
width="200px" | |||||
> | |||||
{{ expertInfo.expertOtherInfo?.other?.map(i=>i.tagName)?.join('、') ||'-' }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item | |||||
width="200px" | |||||
label="备注" | |||||
> | |||||
{{ expertInfo.expertOtherInfo?.remark ||'-' }} | |||||
</el-descriptions-item> | |||||
</el-descriptions> | |||||
</el-tab-pane> | |||||
</el-tabs> | |||||
</el-card> | |||||
</div> | |||||
</template> | |||||
<style lang='less' scoped> </style> |
@@ -0,0 +1,249 @@ | |||||
<script setup name="expertStore"> | |||||
import { getCurrentInstance, onMounted, reactive, ref } from 'vue' | |||||
import { useRouter } from 'vue-router' | |||||
import ElTree from '@/components/elTree/index.vue' | |||||
import store from '@/store' | |||||
import { storeToRefs } from 'pinia' | |||||
import { delivery, getExpertList } from '@/http/apis/expertManage/expertStore' | |||||
import { getIsShowRegionTree, getTreeParams } from '@/utils/getIsShowRegionTree' | |||||
const | |||||
{ dictList } = storeToRefs(store.dictStore), | |||||
router = useRouter(), | |||||
{ proxy } = getCurrentInstance(), | |||||
searchForm = reactive({ | |||||
expertName: undefined, | |||||
company: undefined, | |||||
expertTypeDictionaryCode: undefined, | |||||
status: undefined, | |||||
maxDeclareAmount: undefined, | |||||
maxApprovalAmount: undefined | |||||
}), | |||||
tableListRef = ref(), | |||||
total = ref(0), | |||||
// 列表数据 | |||||
column = reactive([ | |||||
{ | |||||
label: '序号', | |||||
type: 'index', | |||||
width: '60' | |||||
}, | |||||
{ | |||||
label: '专家姓名', | |||||
key: 'expertName', | |||||
prop: 'expertName', | |||||
minWidth: '80', | |||||
showOverflowTooltip: true | |||||
}, | |||||
{ | |||||
label: '工作单位', | |||||
key: 'company', | |||||
prop: 'company', | |||||
minWidth: '150', | |||||
showOverflowTooltip: true | |||||
}, | |||||
{ | |||||
label: '手机号码', | |||||
key: 'phoneNo', | |||||
prop: 'phoneNo', | |||||
width: '120' | |||||
}, | |||||
{ | |||||
label: '专家类型', | |||||
key: 'expertType[0].dictionaryName', | |||||
prop: 'expertType[0].dictionaryName', | |||||
width: '80' | |||||
}, | |||||
{ | |||||
label: '创建时间', | |||||
key: 'createTime', | |||||
prop: 'createTime', | |||||
width: '180' | |||||
}, | |||||
{ | |||||
label: '操作', | |||||
slot: 'action', | |||||
width: '240', | |||||
fixed: 'right' | |||||
} | |||||
]), | |||||
data = ref([]), | |||||
areaCode = ref(), | |||||
getTree = (value) => { | |||||
searchForm.intentionRegionInfo = { | |||||
regionCode: value.regionCode, | |||||
regionLevel: value.regionLevel | |||||
} | |||||
tableListRef.value.pageParams.pageNumber = 1 | |||||
getTableData() | |||||
}, | |||||
getTableData = async (pageParams = tableListRef.value.pageParams) => { | |||||
const res = await getExpertList({ | |||||
...pageParams, | |||||
...searchForm, | |||||
year: searchForm.year * 1 || undefined, | |||||
areaCode: areaCode.value || undefined | |||||
}) | |||||
data.value = res.data.records | |||||
total.value = res.data.total | |||||
}, | |||||
search = () => { | |||||
getTableData() | |||||
}, | |||||
reset = () => { | |||||
searchForm.expertName = undefined | |||||
searchForm.company = undefined | |||||
searchForm.expertTypeDictionaryCode = undefined | |||||
tableListRef.value.pageParams.pageNumber = 1 | |||||
tableListRef.value.pageParams.pageSize = 10 | |||||
getTableData() | |||||
}, | |||||
toAddorEditExpert = (row) => { | |||||
if (row.userId) { | |||||
router.push({ name: 'addOrEditExpert', query: { id: row.userId }}) | |||||
} else { | |||||
router.push({ name: 'addOrEditExpert' }) | |||||
} | |||||
}, | |||||
checkDetail = (row) => { | |||||
router.push({ name: 'expertDetail', query: { id: row.userId }}) | |||||
}, | |||||
checkDeputyActivityRecord = (row) => { | |||||
router.push({ name: 'deputyActivityRecord', query: { id: row.userId, name: row.expertName }}) | |||||
}, | |||||
expertApply = () => { | |||||
const timestamp = new Date().getTime() | |||||
const time = window.btoa(timestamp) | |||||
const routeData = router.resolve({ | |||||
name: 'expertEnroll', | |||||
query: { time } | |||||
}) | |||||
window.open(routeData.href, '_blank') | |||||
}, | |||||
del = (data) => { | |||||
proxy.$messageBox | |||||
.confirm(`确定要删除${data.expertName}专家吗?`, '提示!', { | |||||
type: 'warning' | |||||
}).then(async () => { | |||||
await delivery(data.userId) | |||||
proxy.$message.success('删除成功') | |||||
getTableData() | |||||
}) | |||||
} | |||||
onMounted(() => { | |||||
if (!getIsShowRegionTree(['SUPER_ADMIN', 'REGION_MANAGER', 'EXPERT_ADMIN'])) getTableData() | |||||
}) | |||||
</script> | |||||
<template> | |||||
<el-row> | |||||
<el-col | |||||
v-if="getIsShowRegionTree(['SUPER_ADMIN','REGION_MANAGER','EXPERT_ADMIN'])" | |||||
style="padding-right: 16px" | |||||
:span="4" | |||||
> | |||||
<elTree :params="getTreeParams({'SUPER_ADMIN':false,'REGION_MANAGER':false,'EXPERT_ADMIN':false})" @get-tree="getTree" /> | |||||
</el-col> | |||||
<el-col :span="getIsShowRegionTree(['SUPER_ADMIN','REGION_MANAGER','EXPERT_ADMIN'])?20:24"> | |||||
<el-card class="w-full search"> | |||||
<el-form | |||||
:model="searchForm" | |||||
size="small" | |||||
label-suffix=":" | |||||
> | |||||
<el-row | |||||
:gutter="16" | |||||
class="mb-16" | |||||
> | |||||
<el-col :span="8"> | |||||
<el-form-item label="专家姓名"> | |||||
<el-input | |||||
v-model="searchForm.expertName" | |||||
placeholder="请输入" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<el-form-item label="工作单位"> | |||||
<el-input | |||||
v-model="searchForm.company" | |||||
placeholder="请输入" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<el-form-item label="专家类型"> | |||||
<el-select | |||||
v-model="searchForm.expertTypeDictionaryCode" | |||||
placeholder="全部" | |||||
class="w-full" | |||||
> | |||||
<el-option | |||||
v-for="(item,index) in dictList && | |||||
dictList.length && | |||||
dictList.find(i => i.dictionaryName === 'expert_type') | |||||
.dictionaryList" | |||||
:key="index" | |||||
:label="item.describe" | |||||
:value="item.dictionaryCode" | |||||
/> | |||||
</el-select> | |||||
</el-form-item> | |||||
</el-col> | |||||
</el-row> | |||||
<el-row> | |||||
<el-col :span="24"> | |||||
<el-form-item class="btn"> | |||||
<div class="flex"> | |||||
<el-button | |||||
type="primary" | |||||
@click="search" | |||||
>查询</el-button> | |||||
<el-button | |||||
@click="reset" | |||||
>重置</el-button> | |||||
</div> | |||||
</el-form-item> | |||||
</el-col> | |||||
</el-row> | |||||
</el-form> | |||||
</el-card> | |||||
<el-card class="w-full mt-8"> | |||||
<template #header> | |||||
<div class="flex justify-between"> | |||||
<span>列表</span> | |||||
<div> | |||||
<el-button | |||||
type="primary" | |||||
plain | |||||
size="small" | |||||
icon="Plus" | |||||
@click="toAddorEditExpert" | |||||
>新增专家</el-button> | |||||
<el-button | |||||
type="primary" | |||||
size="small" | |||||
@click="expertApply" | |||||
>专家报名</el-button> | |||||
</div> | |||||
</div> | |||||
</template> | |||||
<table-list | |||||
ref="tableListRef" | |||||
:column="column" | |||||
:data="data" | |||||
:total="total" | |||||
@get-table-data="getTableData" | |||||
> | |||||
<template #action="{ scope }"> | |||||
<a @click="toAddorEditExpert(scope.row)">编辑</a> | |||||
<a @click="checkDetail(scope.row)">详情</a> | |||||
<a @click="checkDeputyActivityRecord(scope.row)">履职记录</a> | |||||
<a class="text-danger" @click="del(scope.row)">删除</a> | |||||
</template> | |||||
</table-list> | |||||
</el-card> | |||||
</el-col> | |||||
</el-row> | |||||
</template> | |||||
<style lang='less' scoped> | |||||
</style> |
@@ -0,0 +1,234 @@ | |||||
<script setup name='expertVerify'> | |||||
import elTree from '@/components/elTree/index.vue' | |||||
import { reactive, ref, onMounted, h } from 'vue' | |||||
import { useRouter } from 'vue-router' | |||||
import { getExpertVerifyList } from '@/http/apis/expertManage/expertVerify' | |||||
import { getIsShowRegionTree, getTreeParams } from '@/utils/getIsShowRegionTree' | |||||
import store from '@/store' | |||||
const tableListRef = ref(), | |||||
router = useRouter(), | |||||
searchForm = reactive({ | |||||
expertName: undefined, | |||||
companyName: undefined, | |||||
expertType: undefined, | |||||
applyStatusList: ['pending_review'], | |||||
maxDeclareAmount: undefined, | |||||
maxApprovalAmount: undefined | |||||
}), | |||||
total = ref(0), | |||||
// 列表数据 | |||||
column = reactive([ | |||||
{ | |||||
label: '序号', | |||||
type: 'index', | |||||
width: '60' | |||||
}, | |||||
{ | |||||
label: '专家姓名', | |||||
key: 'name', | |||||
prop: 'name', | |||||
minWidth: '80', | |||||
showOverflowTooltip: true | |||||
}, | |||||
{ | |||||
label: '工作单位', | |||||
key: 'company', | |||||
prop: 'company', | |||||
minWidth: '150', | |||||
showOverflowTooltip: true | |||||
}, | |||||
{ | |||||
label: '手机号码', | |||||
key: 'phoneNo', | |||||
prop: 'phoneNo', | |||||
width: '120' | |||||
}, | |||||
{ | |||||
label: '专家类型', | |||||
key: 'expertType', | |||||
prop: 'expertType', | |||||
width: '80', | |||||
render: row => h('span', row?.expertType?.[0].dictionaryName || '-') | |||||
}, | |||||
{ | |||||
label: '报名时间', | |||||
key: 'applyTime', | |||||
prop: 'applyTime', | |||||
width: '180' | |||||
}, | |||||
{ | |||||
label: '操作', | |||||
slot: 'action', | |||||
width: '200', | |||||
fixed: 'right' | |||||
} | |||||
]), | |||||
data = ref([]), | |||||
areaCode = ref(), | |||||
getTree = (value) => { | |||||
searchForm.expertRegionInfo = { | |||||
regionCode: value.regionCode, | |||||
regionLevel: value.regionLevel | |||||
} | |||||
tableListRef.value.pageParams.pageNumber = 1 | |||||
getTableData() | |||||
}, | |||||
getTableData = async (pageParams = tableListRef.value.pageParams) => { | |||||
const res = await getExpertVerifyList({ | |||||
...pageParams, | |||||
...searchForm, | |||||
year: searchForm.year * 1 || undefined, | |||||
maxDeclareAmount: searchForm.maxDeclareAmount * 1 || undefined, | |||||
maxApprovalAmount: searchForm.maxApprovalAmount * 1 || undefined, | |||||
startTime: searchForm.times?.[0] || undefined, | |||||
endTime: searchForm.times?.[1] || undefined, | |||||
areaCode: areaCode.value || undefined | |||||
}) | |||||
data.value = res.data.records | |||||
total.value = res.data.total | |||||
}, | |||||
activeName = ref('待审核'), | |||||
search = () => { | |||||
getTableData() | |||||
}, | |||||
reset = () => { | |||||
searchForm.expertName = undefined | |||||
searchForm.companyName = undefined | |||||
searchForm.expertType = undefined | |||||
searchForm.maxDeclareAmount = undefined | |||||
searchForm.maxApprovalAmount = undefined | |||||
tableListRef.value.pageParams.pageNumber = 1 | |||||
tableListRef.value.pageParams.pageSize = 10 | |||||
getTableData() | |||||
}, | |||||
checkDetail = (data) => { | |||||
if (activeName.value === '待审核') { | |||||
router.push({ name: 'expertVerifyAction', query: { applyId: data.id, applyType: data.applyType }}) | |||||
} else { | |||||
router.push({ name: 'verifyDetail', query: { applyId: data.id }}) | |||||
} | |||||
}, | |||||
handleClick = ({ props: { name }}) => { | |||||
if (name === '待审核') { | |||||
searchForm.applyStatusList = ['pending_review'] | |||||
getTableData() | |||||
} else { | |||||
searchForm.applyStatusList = ['passed', 'refused', 'revoked'] | |||||
getTableData() | |||||
} | |||||
} | |||||
onMounted(() => { | |||||
if (!getIsShowRegionTree(['SUPER_ADMIN', 'REGION_MANAGER', 'EXPERT_ADMIN'])) getTableData() | |||||
}) | |||||
</script> | |||||
<template> | |||||
<el-row> | |||||
<el-col | |||||
v-if="getIsShowRegionTree(['SUPER_ADMIN','REGION_MANAGER','EXPERT_ADMIN'])" | |||||
style="padding-right: 16px" | |||||
:span="4" | |||||
> | |||||
<elTree :params="getTreeParams({'SUPER_ADMIN':false,'REGION_MANAGER':false,'EXPERT_ADMIN':false})" @get-tree="getTree" /> | |||||
</el-col> | |||||
<el-col :span="getIsShowRegionTree(['SUPER_ADMIN','REGION_MANAGER','EXPERT_ADMIN'])?20:24"> | |||||
<el-card class="w-full search"> | |||||
<el-form | |||||
:model="searchForm" | |||||
size="small" | |||||
label-suffix=":" | |||||
> | |||||
<el-row | |||||
:gutter="16" | |||||
class="mb-16" | |||||
> | |||||
<el-col :span="8"> | |||||
<el-form-item label="专家姓名"> | |||||
<el-input | |||||
v-model="searchForm.expertName" | |||||
placeholder="请输入" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<el-form-item label="工作单位"> | |||||
<el-input | |||||
v-model="searchForm.companyName" | |||||
placeholder="请输入" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<el-form-item label="专家类型"> | |||||
<el-select | |||||
v-model="searchForm.expertType" | |||||
placeholder="全部" | |||||
class="w-full" | |||||
value-key="dictionaryCode" | |||||
> | |||||
<el-option | |||||
v-for="(item,index) in store.dictStore.expertTypeDict" | |||||
:key="index" | |||||
:label="item.dictionaryName" | |||||
:value="item" | |||||
/> | |||||
</el-select> | |||||
</el-form-item> | |||||
</el-col> | |||||
</el-row> | |||||
<el-row | |||||
:gutter="16" | |||||
> | |||||
<el-col :span="24"> | |||||
<el-form-item class="btn"> | |||||
<div class="flex"> | |||||
<el-button | |||||
type="primary" | |||||
@click="search" | |||||
>查询</el-button> | |||||
<el-button | |||||
@click="reset" | |||||
>重置</el-button> | |||||
</div> | |||||
</el-form-item> | |||||
</el-col> | |||||
</el-row> | |||||
</el-form> | |||||
</el-card> | |||||
<el-card class="w-full mt-8 tab-card"> | |||||
<template #header> | |||||
<el-tabs | |||||
v-model="activeName" | |||||
class="demo-tabs" | |||||
@tab-click="handleClick" | |||||
> | |||||
<el-tab-pane | |||||
label="待审核" | |||||
name="待审核" | |||||
/> | |||||
<el-tab-pane | |||||
label="已审核" | |||||
name="已审核" | |||||
/> | |||||
</el-tabs> | |||||
</template> | |||||
<table-list | |||||
ref="tableListRef" | |||||
:column="column" | |||||
:data="data" | |||||
:total="total" | |||||
@get-table-data="getTableData" | |||||
> | |||||
<template #action="{ scope }"> | |||||
<a @click="checkDetail(scope.row)">{{ activeName==='待审核'?'处理':'详情' }}</a> | |||||
</template> | |||||
</table-list> | |||||
</el-card> | |||||
</el-col> | |||||
</el-row> | |||||
</template> | |||||
<style lang='less' scoped> | |||||
</style> |
@@ -0,0 +1,428 @@ | |||||
<script setup name='verifyDetail'> | |||||
import { getCurrentInstance, ref, reactive, watch, onMounted, nextTick } from 'vue' | |||||
import { | |||||
getExpertVerifyDetail, | |||||
submitVerifyResult, | |||||
getExpertDetail, | |||||
modifyDetail | |||||
} from '@/http/apis/expertManage/expertVerify' | |||||
import { useRouter, useRoute } from 'vue-router' | |||||
import Accessory from '@/components/accessory/index.vue' | |||||
import store from '@/store' | |||||
const { expertAuditStatusOptions } = store.dictStore.globalDicts | |||||
const activeName = ref('basicInfo'), | |||||
{ proxy } = getCurrentInstance(), | |||||
dialogFormVisible = ref(false), | |||||
route = useRoute(), | |||||
router = useRouter(), | |||||
routeName = ref(''), | |||||
form = reactive({ | |||||
applyId: route.query.applyId | |||||
}), | |||||
rules = reactive({ | |||||
auditOpinion: [ | |||||
{ required: true, message: '请填写审核意见', trigger: 'blur' } | |||||
] | |||||
}), | |||||
ruleFormRef = ref(''), | |||||
submitForm = async (formEl) => { | |||||
if (!formEl) return | |||||
await formEl.validate(async (valid, fields) => { | |||||
if (valid) { | |||||
if (recommendTitle.value === '通过') { | |||||
form.applyResult = true | |||||
} else { | |||||
form.applyResult = false | |||||
} | |||||
await submitVerifyResult(form) | |||||
form.auditOpinion = undefined | |||||
dialogFormVisible.value = false | |||||
proxy.$message.success('审核意见提交成功!') | |||||
router.push({ name: 'expertVerify' }) | |||||
} else { | |||||
console.log('error submit!', fields) | |||||
} | |||||
}) | |||||
}, | |||||
recommendTitle = ref(''), | |||||
adopt = (title) => { | |||||
recommendTitle.value = title | |||||
dialogFormVisible.value = true | |||||
nextTick(() => { | |||||
ruleFormRef.value.resetFields() | |||||
}) | |||||
}, | |||||
goBack = () => { | |||||
router.push({ name: 'expertVerify' }) | |||||
}, | |||||
expertDetail = ref({ basicInfo: {}, eduInfo: {}, jobInfo: {}, professionalInfo: {}, recommendInfo: {}}), | |||||
verifyInfo = ref(), | |||||
getVerifyDetail = async () => { | |||||
const res = await getExpertVerifyDetail({ applyId: route.query.applyId }) | |||||
verifyInfo.value = res.data | |||||
}, | |||||
getExpertDetailRequest = async () => { | |||||
const apiFn = route.query.applyType === 'expert_info_modify_admin' ? modifyDetail : getExpertDetail | |||||
const res = await apiFn({ expertUserId: verifyInfo.value.expertUserId }) | |||||
expertDetail.value = res.data | |||||
}, | |||||
// 查看文件 | |||||
view = (data) => { | |||||
const routeUrl = router.resolve({ | |||||
path: '/fileView', | |||||
query: { id: data } | |||||
}) | |||||
window.open(routeUrl.href, '_blank') | |||||
} | |||||
onMounted(async () => { | |||||
await getVerifyDetail() | |||||
await getExpertDetailRequest() | |||||
}) | |||||
watch( | |||||
route, | |||||
(val) => { | |||||
routeName.value = route.meta.title | |||||
}, | |||||
{ immediate: true, deep: true } | |||||
) | |||||
</script> | |||||
<template> | |||||
<div class="footerPage"> | |||||
<el-card | |||||
v-if="routeName ==='专家审核详情'" | |||||
shadow="never" | |||||
class="mb-16" | |||||
> | |||||
<div> | |||||
<div class="flex justify-between items-center"> | |||||
<div class="flex-1"> | |||||
<p class="font-bold">关于{{ expertDetail.basicInfo.name }}的专家审核结果</p> | |||||
<div class="mt-8 search"> | |||||
<el-form label-suffix=":"> | |||||
<el-row :gutter="24"> | |||||
<el-col :span="6"> | |||||
<el-form-item label="审核人">{{ verifyInfo?.auditor||'-' }}</el-form-item> | |||||
</el-col> | |||||
<el-col :span="6"> | |||||
<el-form-item label="审核时间">{{ verifyInfo?.auditTime||'-' }}</el-form-item> | |||||
</el-col> | |||||
<el-col :span="6"> | |||||
<el-form-item label="审核意见">{{ verifyInfo?.auditOption||'-' }}</el-form-item> | |||||
</el-col> | |||||
</el-row> | |||||
</el-form> | |||||
</div> | |||||
</div> | |||||
<div class="textRight"> | |||||
<p> | |||||
<span :class="`dot mr-4 bg-${verifyInfo&&verifyInfo.auditStatus&&expertAuditStatusOptions[verifyInfo.auditStatus]?.color}`"></span> | |||||
<span :class="`font-semibold text-${verifyInfo&&verifyInfo.auditStatus&&expertAuditStatusOptions[verifyInfo.auditStatus]?.color}`">{{ verifyInfo&&verifyInfo.auditStatus&&expertAuditStatusOptions[verifyInfo.auditStatus]?.name }}</span> | |||||
</p> | |||||
<p>审核结果</p> | |||||
</div> | |||||
</div> | |||||
</div> | |||||
</el-card> | |||||
<el-card class="tab-card" shadow="never"> | |||||
<template #header> | |||||
<el-tabs v-model="activeName"> | |||||
<el-tab-pane label="基本信息" name="basicInfo" /> | |||||
<el-tab-pane label="学历信息" name="eduInfo" /> | |||||
<el-tab-pane label="职业信息" name="professionInfo" /> | |||||
<el-tab-pane label="专业信息" name="majorInfo" /> | |||||
<el-tab-pane label="推荐信息" name="recommendInfo" /> | |||||
<el-tab-pane label="其他信息" name="expertOtherInfo" /> | |||||
</el-tabs> | |||||
</template> | |||||
<el-descriptions | |||||
v-if="activeName==='basicInfo'" | |||||
:column="2" | |||||
border | |||||
> | |||||
<el-descriptions-item | |||||
label="专家名称" | |||||
span="1" | |||||
width="200px" | |||||
> | |||||
{{ expertDetail.basicInfo.name }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="是否在浙政钉组织" width="200px"> | |||||
{{ expertDetail.basicInfo.isDingUser?'是':'否' }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item | |||||
label="手机号码" | |||||
width="200px" | |||||
> | |||||
{{ expertDetail.basicInfo.phoneNo }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="性别"> | |||||
{{ expertDetail.basicInfo.gender === '1' ? '男': '女' }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="籍贯"> | |||||
{{ expertDetail.basicInfo.hometown }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="民族"> | |||||
{{ expertDetail.basicInfo.nationality }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="政治面貌"> | |||||
{{ expertDetail.basicInfo.political?.[0].dictionaryName }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="身份证号"> | |||||
{{ expertDetail.basicInfo.idCard }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="办公电话"> | |||||
{{ expertDetail.basicInfo.officePhone }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="出生年月"> | |||||
{{ expertDetail.basicInfo.birth }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="银行卡号"> | |||||
{{ expertDetail.basicInfo.bankNo }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="开户银行"> | |||||
{{ expertDetail.basicInfo.bank }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item span="1" label="电子邮箱"> | |||||
{{ expertDetail.basicInfo.email }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="专家级别"> | |||||
{{ expertDetail.basicInfo?.expertRegionInfo?.regionName.split('@@').map(i=>i.split('##')[1]).join('-') }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="专家来源"> | |||||
{{ expertDetail.basicInfo.expertSource?.[0].tagName }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="专家类型"> | |||||
{{ expertDetail.basicInfo.expertType?.[0].dictionaryName }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="履职意向"> | |||||
{{ expertDetail.basicInfo.expertIntentionWorkRegions?.map(i=>i.regionName.split('@@').map(j=>j.split('##')[1]).join('-')).join(';') }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item | |||||
label="头像(免冠照)" | |||||
span="2" | |||||
> | |||||
<a target="_blank" @click="view(expertDetail.basicInfo.avatarFile.fileId)">{{ expertDetail.basicInfo.avatarFile?.fileName }}</a> | |||||
</el-descriptions-item> | |||||
</el-descriptions> | |||||
<el-descriptions | |||||
v-if="activeName==='eduInfo'" | |||||
:column="2" | |||||
border | |||||
> | |||||
<el-descriptions-item | |||||
label="毕业院校" | |||||
span="2" | |||||
width="200px" | |||||
> | |||||
{{ expertDetail.eduInfo.school }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="毕业时间"> | |||||
{{ expertDetail.eduInfo.graduatedAt }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item | |||||
label="所学专业" | |||||
width="200px" | |||||
> | |||||
{{ expertDetail.eduInfo.academicTitle }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="学位"> | |||||
{{ expertDetail.eduInfo.degree?.[0].dictionaryName }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="学历"> | |||||
{{ expertDetail.eduInfo.edu?.[0].dictionaryName }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="毕业证书"> | |||||
<p v-for="(file,fileIndex) in expertDetail.eduInfo.graduationCertificateFile" :key="fileIndex" class="mb-4"> | |||||
<accessory :file-name="file.fileName" :file-id="file.fileId" /> | |||||
</p> | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="学位证书"> | |||||
<p v-for="(file,fileIndex) in expertDetail.eduInfo.degreeCertificateFile" :key="fileIndex" class="mb-4"> | |||||
<accessory :file-name="file.fileName" :file-id="file.fileId" /> | |||||
</p> | |||||
</el-descriptions-item> | |||||
</el-descriptions> | |||||
<el-descriptions | |||||
v-if="activeName==='professionInfo'" | |||||
:column="2" | |||||
border | |||||
> | |||||
<el-descriptions-item | |||||
label="工作单位" | |||||
width="200px" | |||||
> | |||||
{{ expertDetail.jobInfo.company }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="工作单位code" width="200px"> | |||||
{{ expertDetail.jobInfo.companyUniqCode }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item | |||||
label="单位法人编号" | |||||
width="200px" | |||||
> | |||||
{{ expertDetail.jobInfo.legalEntityCode }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="行政职务"> | |||||
{{ expertDetail.jobInfo.administrativeDuties }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="开始工作日期"> | |||||
{{ expertDetail.jobInfo.startWorkAt }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="行政职级"> | |||||
{{ expertDetail.jobInfo.administrativeRank?.[0].dictionaryName }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="在职状态"> | |||||
{{ expertDetail.jobInfo.jobStatus?.[0].dictionaryName }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="退休日期"> | |||||
{{ expertDetail.jobInfo.retiredAt }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="单位类型"> | |||||
{{ expertDetail.jobInfo.companyAttribute?.[0].dictionaryName }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="工作地址"> | |||||
{{ expertDetail.jobInfo.address }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="工作经历"> | |||||
{{ expertDetail.jobInfo.experience }} | |||||
</el-descriptions-item> | |||||
</el-descriptions> | |||||
<el-descriptions | |||||
v-if="activeName==='majorInfo'" | |||||
:column="2" | |||||
border | |||||
> | |||||
<el-descriptions-item | |||||
label="技术职称" | |||||
width="200px" | |||||
> | |||||
{{ expertDetail.professionalInfo.technicalTitles }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="职称级别" width="200px"> | |||||
{{ expertDetail.professionalInfo.titleLevel?.[0].dictionaryName }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item | |||||
label="擅长方向" | |||||
width="200px" | |||||
> | |||||
{{ expertDetail.professionalInfo.goodAt?.map(i=>i.tagName).join('、')||'-' }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="技术专长"> | |||||
{{ expertDetail.professionalInfo.technicalExpertise?.[0].tagName }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="行业领域"> | |||||
{{ expertDetail.professionalInfo.industrySector?.[0].tagName }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="获奖情况"> | |||||
{{ expertDetail.professionalInfo.awards }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="表彰奖励"> | |||||
{{ expertDetail.professionalInfo.recognitionReward }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="回避单位"> | |||||
<span v-for="(item,index) in expertDetail.professionalInfo.avoidCompanyList" :key="index">{{ item.companyName }} </span> | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="职称证明"> | |||||
<p v-for="(file,fileIndex) in expertDetail.professionalInfo.titleCertificateFile" :key="fileIndex" class="mb-4"> | |||||
<accessory :file-name="file.fileName" :file-id="file.fileId" /> | |||||
</p> | |||||
</el-descriptions-item> | |||||
</el-descriptions> | |||||
<el-descriptions | |||||
v-if="activeName==='recommendInfo'" | |||||
:column="2" | |||||
border | |||||
> | |||||
<el-descriptions-item | |||||
label="推荐类型" | |||||
width="200px" | |||||
> | |||||
{{ expertDetail.recommendInfo.recommendedWay?.[0].dictionaryName }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item | |||||
width="200px" | |||||
label="推荐证明" | |||||
> | |||||
<p v-for="(file,fileIndex) in expertDetail.recommendInfo.recommendationProofFile" :key="fileIndex" class="mb-4"> | |||||
<accessory :file-name="file.fileName" :file-id="file.fileId" /> | |||||
</p> | |||||
</el-descriptions-item> | |||||
</el-descriptions> | |||||
<el-descriptions | |||||
v-if="activeName==='expertOtherInfo'" | |||||
:column="2" | |||||
border | |||||
> | |||||
<el-descriptions-item | |||||
label="其他标签" | |||||
width="200px" | |||||
> | |||||
{{ expertDetail.expertOtherInfo?.other?.map(i=>i.tagName)?.join('、') ||'-' }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item | |||||
width="200px" | |||||
label="备注" | |||||
> | |||||
{{ expertDetail.expertOtherInfo?.remark ||'-' }} | |||||
</el-descriptions-item> | |||||
</el-descriptions> | |||||
</el-card> | |||||
<div class="footer"> | |||||
<el-button | |||||
v-if="routeName !=='专家审核详情'" | |||||
type="primary" | |||||
@click="adopt('通过')" | |||||
>通过</el-button> | |||||
<el-button | |||||
v-if="routeName !=='专家审核详情'" | |||||
plain | |||||
type="danger" | |||||
@click="adopt('驳回')" | |||||
>驳回</el-button> | |||||
<el-button | |||||
@click="goBack" | |||||
>返回</el-button> | |||||
</div> | |||||
</div> | |||||
<el-dialog | |||||
v-model="dialogFormVisible" | |||||
:title="recommendTitle" | |||||
> | |||||
<el-form | |||||
ref="ruleFormRef" | |||||
:model="form" | |||||
:rules="rules" | |||||
status-icon | |||||
> | |||||
<el-form-item | |||||
label="审核意见" | |||||
label-width="auto" | |||||
prop="auditOpinion" | |||||
> | |||||
<el-input | |||||
v-model="form.auditOpinion" | |||||
maxlength="200" | |||||
placeholder="请输入" | |||||
show-word-limit | |||||
type="textarea" | |||||
/> | |||||
</el-form-item> | |||||
</el-form> | |||||
<template #footer> | |||||
<span class="dialog-footer"> | |||||
<el-button | |||||
type="primary" | |||||
@click="submitForm(ruleFormRef)" | |||||
> | |||||
提交 | |||||
</el-button> | |||||
<el-button @click="dialogFormVisible = false">关闭</el-button> | |||||
</span> | |||||
</template> | |||||
</el-dialog> | |||||
</template> | |||||
<style lang='less' scoped> </style> |
@@ -0,0 +1,218 @@ | |||||
<script setup name="driverDialog"> | |||||
import { getCurrentInstance, reactive, ref, watch } from 'vue' | |||||
import { getExpertList } from '@/http/apis/expertManage/expertStore' | |||||
import store from '@/store' | |||||
import { districtList } from '@/http/apis/commonApi' | |||||
const { proxy } = getCurrentInstance(), | |||||
props = defineProps({ | |||||
visible: { | |||||
type: Boolean, | |||||
default: false, | |||||
required: true | |||||
}, | |||||
data: { | |||||
type: Array, | |||||
default: undefined | |||||
}, | |||||
selectExpertType: { | |||||
type: Number, | |||||
default: 1 | |||||
} | |||||
}), | |||||
emits = defineEmits(['close', 'getUserData']), | |||||
searchForm = reactive({ | |||||
expertRegionLevel: undefined, | |||||
expertName: undefined, | |||||
company: undefined | |||||
}), | |||||
tableListRef = ref(), | |||||
total = ref(0), | |||||
column = [ | |||||
{ | |||||
type: 'selection', | |||||
reserveSelection: true, | |||||
width: '55' | |||||
}, | |||||
{ | |||||
label: '姓名', | |||||
key: 'expertName', | |||||
prop: 'expertName' | |||||
}, | |||||
{ | |||||
label: '工作单位', | |||||
key: 'company', | |||||
prop: 'company', | |||||
showOverflowTooltip: true, | |||||
width: 250 | |||||
}, | |||||
{ | |||||
label: '专家级别', | |||||
key: 'expertRegionInfo', | |||||
slot: 'expertRegionInfo', | |||||
width: '150' | |||||
}, | |||||
{ | |||||
label: '手机号码', | |||||
key: 'phoneNo', | |||||
prop: 'phoneNo', | |||||
width: '150' | |||||
}, | |||||
{ | |||||
label: '专家类型', | |||||
key: 'expertType[0].dictionaryName', | |||||
prop: 'expertType[0].dictionaryName', | |||||
width: '150' | |||||
} | |||||
], | |||||
tableData = ref([]), | |||||
getTableData = async (pageParams = tableListRef.value?.pageParams) => { | |||||
const res = await getExpertList({ | |||||
...pageParams, | |||||
...searchForm, | |||||
expertRegionInfo: searchForm.expertRegionInfo ? { | |||||
regionCode: searchForm.expertRegionInfo.slice(-1)[0].split('##')[0], | |||||
regionLevel: searchForm.expertRegionInfo.slice(-1)[0].split('##')[2], | |||||
regionName: searchForm.expertRegionInfo.slice(-1)[0].split('##')[1] | |||||
} : undefined | |||||
}) | |||||
total.value = res.data.total | |||||
tableData.value = res.data.records || [] | |||||
const selectCopyData = JSON.parse(JSON.stringify(selectData.value)) | |||||
if (selectCopyData?.length) { | |||||
tableData.value && tableData.value.forEach(item => { | |||||
const dataIds = selectCopyData.map(i => i.userId * 1) | |||||
if (dataIds.includes(item.userId)) { | |||||
tableListRef.value.toggleRowSelect(item, true) | |||||
} | |||||
}) | |||||
} | |||||
}, | |||||
search = () => { | |||||
getTableData() | |||||
}, | |||||
reset = () => { | |||||
searchForm.expertRegionInfo = undefined | |||||
searchForm.expertName = undefined | |||||
searchForm.company = undefined | |||||
tableListRef.value.pageParams.pageNumber = 1 | |||||
tableListRef.value.pageParams.pageSize = 10 | |||||
getTableData() | |||||
}, | |||||
selectData = ref([]), | |||||
selectionChange = val => { | |||||
// selectData.value = val | |||||
const ids = val.map(i => i.userId) | |||||
tableData.value.forEach(row => { | |||||
if (ids.includes(row.userId)) { | |||||
selectData.value.push(row) | |||||
} else { | |||||
selectData.value = selectData.value.filter(i => i.userId !== row.userId) | |||||
} | |||||
}) | |||||
}, | |||||
confirm = () => { | |||||
const obj = {} | |||||
const data = selectData.value.reduce((cur, next) => { | |||||
obj[next.userId] ? '' : obj[next.userId] = true && cur.push(next) | |||||
return cur | |||||
}, []) | |||||
if (props.selectExpertType === 1 && data?.length > 10) { | |||||
proxy.$message.warning('最多选择10位人员') | |||||
} else { | |||||
emits('getUserData', data) | |||||
} | |||||
}, | |||||
regionTree = ref([]) | |||||
watch( | |||||
() => props.visible, | |||||
async val => { | |||||
if (val) { | |||||
if (props.data?.length) { | |||||
selectData.value = props.data.map(i => i) | |||||
} | |||||
const res = await districtList({ regionCode: 330500, regionLevel: 2 }) | |||||
regionTree.value = [res.data] | |||||
getTableData() | |||||
store.userStore.setRoleStore() | |||||
} | |||||
} | |||||
) | |||||
</script> | |||||
<template> | |||||
<el-dialog | |||||
:model-value="visible" | |||||
title="选择人员" | |||||
width="840px" | |||||
destroy-on-close | |||||
@close="emits('close')" | |||||
> | |||||
<div class="search mb-16"> | |||||
<el-form label-suffix=":" :model="searchForm" size="small"> | |||||
<el-row :gutter="16" class="mb-16"> | |||||
<el-col :span="8"> | |||||
<el-form-item label="专家级别"> | |||||
<el-cascader | |||||
v-model="searchForm.expertRegionInfo" | |||||
:options="regionTree" | |||||
placeholder="请选择" | |||||
class="w-full" | |||||
:props="{ | |||||
value:'unionCode', | |||||
label:'name' | |||||
}" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<el-form-item label="专家姓名"> | |||||
<el-input | |||||
v-model="searchForm.expertName" | |||||
placeholder="请输入" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<el-form-item label="工作单位"> | |||||
<el-input | |||||
v-model="searchForm.company" | |||||
maxlength="11" | |||||
placeholder="请输入" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
</el-row> | |||||
<el-row> | |||||
<el-col :span="24"> | |||||
<el-form-item class="btn"> | |||||
<el-button type="primary" @click="search">查询</el-button> | |||||
<el-button @click="reset">重置</el-button> | |||||
</el-form-item> | |||||
</el-col> | |||||
</el-row> | |||||
</el-form> | |||||
</div> | |||||
<table-list | |||||
ref="tableListRef" | |||||
:column="column" | |||||
:data="tableData" | |||||
:total="total" | |||||
row-key="userId" | |||||
@selection-change="selectionChange" | |||||
@get-table-data="getTableData" | |||||
> | |||||
<template #expertRegionInfo="{scope}"> | |||||
<span>{{ scope.row?.expertRegionInfo?.regionName||'-' }}</span> | |||||
</template> | |||||
</table-list> | |||||
<template #footer> | |||||
<el-button type="primary" size="small" @click="confirm"> | |||||
确定 | |||||
</el-button> | |||||
<el-button size="small" @click="emits('close')"> | |||||
关闭 | |||||
</el-button> | |||||
</template> | |||||
</el-dialog> | |||||
</template> |
@@ -0,0 +1,149 @@ | |||||
<script setup name="driverDialog"> | |||||
import { nextTick, reactive, ref, watch } from 'vue' | |||||
import { getMeetingProjectList } from '@/http/apis/expertManage/reviewMeeting' | |||||
import store from '@/store' | |||||
const { projectTypeOptions } = store.dictStore.globalDicts || {} | |||||
const | |||||
props = defineProps({ | |||||
visible: { | |||||
type: Boolean, | |||||
default: false, | |||||
required: true | |||||
}, | |||||
data: { | |||||
type: Array, | |||||
default: undefined | |||||
}, | |||||
meetingType: { | |||||
type: String, | |||||
default: '1' | |||||
}, | |||||
dictionaryList: { | |||||
type: Array, | |||||
default: undefined | |||||
} | |||||
}), | |||||
emits = defineEmits(['close', 'getProjectData']), | |||||
tableListRef = ref(), | |||||
total = ref(0), | |||||
column = reactive([ | |||||
{ | |||||
type: 'selection', | |||||
width: '50' | |||||
}, | |||||
{ | |||||
label: '项目名称', | |||||
key: 'projectName', | |||||
prop: 'projectName', | |||||
minWidth: '150', | |||||
showOverflowTooltip: true | |||||
}, | |||||
{ | |||||
label: '申报单位', | |||||
key: 'buildOrg', | |||||
prop: 'buildOrg', | |||||
minWidth: '120', | |||||
showOverflowTooltip: true | |||||
}, | |||||
{ | |||||
label: '项目类型', | |||||
slot: 'projectTypeName', | |||||
prop: 'projectTypeName', | |||||
width: '100' | |||||
}, | |||||
{ | |||||
label: '申报金额', | |||||
key: 'declaredAmount', | |||||
prop: 'declaredAmount', | |||||
width: '100' | |||||
}, | |||||
{ | |||||
label: '预算年度', | |||||
key: 'projectYear', | |||||
prop: 'projectYear', | |||||
width: '80' | |||||
} | |||||
]), | |||||
tableData = ref([]), | |||||
getTableData = async (pageParams = tableListRef.value?.pageParams) => { | |||||
const res = await getMeetingProjectList({ | |||||
meetingType: props.meetingType, | |||||
...pageParams | |||||
}) | |||||
total.value = res.data.total | |||||
tableData.value = res.data.records || [] | |||||
await nextTick() | |||||
const selectCopyData = JSON.parse(JSON.stringify(selectData.value)) || [] | |||||
if (selectCopyData?.length) { | |||||
tableData.value && tableData.value.forEach(item => { | |||||
const dataIds = selectCopyData.map(i => i.id * 1) | |||||
if (dataIds.includes(item.id)) { | |||||
tableListRef.value.toggleRowSelect(item, true) | |||||
} | |||||
}) | |||||
} | |||||
}, | |||||
selectData = ref([]), | |||||
selectionChange = val => { | |||||
const ids = val.map(i => i.id) | |||||
tableData.value.forEach(row => { | |||||
if (ids.includes(row.id)) { | |||||
selectData.value.push(row) | |||||
} else { | |||||
selectData.value = selectData.value.filter(i => i.id !== row.id) | |||||
} | |||||
}) | |||||
}, | |||||
confirm = () => { | |||||
const obj = {} | |||||
const data = selectData.value.reduce((cur, next) => { | |||||
obj[next.id] ? '' : obj[next.id] = true && cur.push(next) | |||||
return cur | |||||
}, []) | |||||
emits('getProjectData', data) | |||||
} | |||||
watch( | |||||
() => props.visible, | |||||
async val => { | |||||
if (val) { | |||||
if (props.data?.length) { | |||||
selectData.value = props.data.map(i => i) | |||||
} | |||||
getTableData() | |||||
} | |||||
} | |||||
) | |||||
</script> | |||||
<template> | |||||
<el-dialog | |||||
:model-value="visible" | |||||
title="添加项目" | |||||
width="840px" | |||||
destroy-on-close | |||||
@close="emits('close')" | |||||
> | |||||
<table-list | |||||
ref="tableListRef" | |||||
:column="column" | |||||
:data="tableData" | |||||
:total="total" | |||||
row-key="id" | |||||
@selection-change="selectionChange" | |||||
@get-table-data="getTableData" | |||||
> | |||||
<template #projectTypeName="{scope}"> | |||||
{{ projectTypeOptions[scope.row?.projectType] }} | |||||
</template> | |||||
</table-list> | |||||
<template #footer> | |||||
<el-button type="primary" size="small" @click="confirm"> | |||||
确定 | |||||
</el-button> | |||||
<el-button size="small" @click="emits('close')"> | |||||
关闭 | |||||
</el-button> | |||||
</template> | |||||
</el-dialog> | |||||
</template> |
@@ -0,0 +1,92 @@ | |||||
<script name="meetingProjectDialog" setup> | |||||
import { ref, reactive, watch } from 'vue' | |||||
import { projects } from '@/http/apis/expertManage/reviewMeeting' | |||||
const props = defineProps({ | |||||
visible: { | |||||
type: Boolean, | |||||
default: false, | |||||
required: true | |||||
}, | |||||
meetingId: { | |||||
type: Number, | |||||
default: null | |||||
} | |||||
}), | |||||
emits = defineEmits(['close']), | |||||
column = reactive([ | |||||
{ | |||||
label: '序号', | |||||
type: 'index', | |||||
width: '60' | |||||
}, | |||||
{ | |||||
label: '项目名称', | |||||
key: 'projectName', | |||||
prop: 'projectName', | |||||
minWidth: '150', | |||||
showOverflowTooltip: true | |||||
}, | |||||
{ | |||||
label: '申报单位', | |||||
key: 'buildOrg', | |||||
prop: 'buildOrg', | |||||
minWidth: '80', | |||||
showOverflowTooltip: true | |||||
}, | |||||
{ | |||||
label: '项目类型', | |||||
key: 'projectTypeName', | |||||
prop: 'projectTypeName', | |||||
width: '100' | |||||
}, | |||||
{ | |||||
label: '申报金额(万元)', | |||||
key: 'declaredAmount', | |||||
prop: 'declaredAmount', | |||||
width: '150' | |||||
}, | |||||
{ | |||||
label: '预算年度', | |||||
key: 'projectYear', | |||||
prop: 'projectYear', | |||||
width: '80' | |||||
} | |||||
]), | |||||
tableData = ref(), | |||||
getTableData = async () => { | |||||
const res = await projects(props.meetingId) | |||||
tableData.value = res.data | |||||
} | |||||
watch( | |||||
() => props.visible, | |||||
async val => { | |||||
if (val) { | |||||
getTableData() | |||||
} | |||||
} | |||||
) | |||||
</script> | |||||
<template> | |||||
<el-dialog | |||||
:model-value="visible" | |||||
title="评审项目" | |||||
width="60%" | |||||
@close="emits('close')" | |||||
> | |||||
<table-list | |||||
ref="tableListRef" | |||||
:column="column" | |||||
:data="tableData" | |||||
:pagination="false" | |||||
@get-table-data="getTableData" | |||||
/> | |||||
<template #footer> | |||||
<span class="dialog-footer"> | |||||
<el-button @click="emits('close')">关闭</el-button> | |||||
</span> | |||||
</template> | |||||
</el-dialog> | |||||
</template> | |||||
@@ -0,0 +1,263 @@ | |||||
<script setup name="reviewMeeting"> | |||||
import { h, onMounted, reactive, ref } from 'vue' | |||||
import { useRouter } from 'vue-router' | |||||
import ElTree from '@/components/elTree/index.vue' | |||||
import { meetingList } from '@/http/apis/expertManage/reviewMeeting' | |||||
import MeetingProjectDialog from './components/meetingProjectDialog.vue' | |||||
import { getIsShowRegionTree, getTreeParams } from '@/utils/getIsShowRegionTree' | |||||
const | |||||
router = useRouter(), | |||||
searchForm = reactive({ | |||||
name: undefined, | |||||
projectName: undefined, | |||||
times: undefined | |||||
}), | |||||
tableListRef = ref(), | |||||
total = ref(0), | |||||
// 列表数据 | |||||
column = reactive([ | |||||
{ | |||||
label: '序号', | |||||
type: 'index', | |||||
width: '60' | |||||
}, | |||||
{ | |||||
label: '会议名称', | |||||
key: 'meetingName', | |||||
prop: 'meetingName', | |||||
minWidth: '180', | |||||
showOverflowTooltip: true | |||||
}, | |||||
{ | |||||
label: '评审项目', | |||||
key: 'projectName', | |||||
slot: 'projectName', | |||||
minWidth: '80' | |||||
}, | |||||
{ | |||||
label: '评审时间', | |||||
key: 'startTime', | |||||
prop: 'startTime', | |||||
width: '290', | |||||
render: row => h('span', row.startTime + '~' + row.endTime) | |||||
}, | |||||
{ | |||||
label: '会议状态', | |||||
key: 'status', | |||||
prop: 'status', | |||||
width: '80', | |||||
render: row => [ | |||||
h('span', { | |||||
class: ['dot mr-4', `${row.status === 1 ? 'bg-success' : row.status === 3 ? 'bg-danger' : ''}`] | |||||
}), | |||||
h( | |||||
'span', | |||||
{ | |||||
class: `${row.status === 1 ? 'text-success' : row.status === 3 ? 'text-danger' : ''}` | |||||
}, | |||||
row.status === 1 ? '正常' : '已取消' | |||||
) | |||||
] | |||||
}, | |||||
{ | |||||
label: '抽取方式', | |||||
key: 'inviteType', | |||||
prop: 'inviteType', | |||||
width: '80', | |||||
render: row => h('span', row.inviteType === 1 ? '随机抽取' : '指定抽取') | |||||
}, | |||||
{ | |||||
label: '抽取状态', | |||||
key: 'inviteStatus', | |||||
prop: 'inviteStatus', | |||||
width: '80', | |||||
render: row => h('span', !row.inviteStatus ? '抽取中' : '抽取结束') | |||||
}, | |||||
{ | |||||
label: '名单确认状态', | |||||
key: 'confirmedRoster', | |||||
prop: 'confirmedRoster', | |||||
width: '120', | |||||
render: row => [ | |||||
h( | |||||
'span', | |||||
{ | |||||
class: `${row.confirmedRoster ? 'text-success' : ''}` | |||||
}, | |||||
row.confirmedRoster ? '已确认' : '未确认' | |||||
) | |||||
] | |||||
}, | |||||
{ | |||||
label: '创建时间', | |||||
key: 'createOn', | |||||
prop: 'createOn', | |||||
width: '180' | |||||
}, | |||||
{ | |||||
label: '操作', | |||||
slot: 'action', | |||||
width: '80', | |||||
fixed: 'right' | |||||
} | |||||
]), | |||||
data = ref([]), | |||||
getTree = (value) => { | |||||
searchForm.regionCode = value.regionCode | |||||
searchForm.regionLevel = value.regionLevel | |||||
tableListRef.value.pageParams.pageNumber = 1 | |||||
getTableData() | |||||
}, | |||||
getTableData = async (pageParams = tableListRef.value.pageParams) => { | |||||
const res = await meetingList({ | |||||
...pageParams, | |||||
...searchForm, | |||||
startTime: searchForm.times?.[0] || undefined, | |||||
endTime: searchForm.times?.[1] || undefined, | |||||
times: undefined | |||||
}) | |||||
data.value = res.data.records | |||||
total.value = res.data.total | |||||
}, | |||||
search = () => { | |||||
getTableData() | |||||
}, | |||||
reset = () => { | |||||
searchForm.name = undefined | |||||
searchForm.projectName = undefined | |||||
searchForm.times = undefined | |||||
tableListRef.value.pageParams.pageNumber = 1 | |||||
tableListRef.value.pageParams.pageSize = 10 | |||||
getTableData() | |||||
}, | |||||
// 新增会议 | |||||
toAddMeeting = (data) => { | |||||
router.push({ name: 'addMeeting' }) | |||||
}, | |||||
checkDetail = (row) => { | |||||
router.push({ name: 'meetingDetail', query: { id: row.meetingId }}) | |||||
}, | |||||
// 查看项目 | |||||
viewProject = (data) => { | |||||
meetingProjectDialogData.value.visible = true | |||||
meetingProjectDialogData.value.meetingId = data.meetingId | |||||
}, | |||||
meetingProjectDialogData = ref({ | |||||
visible: false, | |||||
meetingId: undefined | |||||
}), | |||||
close = () => { | |||||
meetingProjectDialogData.value.visible = false | |||||
} | |||||
onMounted(() => { | |||||
if (!getIsShowRegionTree(['SUPER_ADMIN', 'REGION_MANAGER', 'EXPERT_ADMIN'])) getTableData() | |||||
}) | |||||
</script> | |||||
<template> | |||||
<el-row> | |||||
<el-col | |||||
v-if="getIsShowRegionTree(['SUPER_ADMIN','REGION_MANAGER','EXPERT_ADMIN'])" | |||||
style="padding-right: 16px" | |||||
:span="4" | |||||
> | |||||
<elTree :params="getTreeParams({'SUPER_ADMIN':false,'REGION_MANAGER':false,'EXPERT_ADMIN':true})" @get-tree="getTree" /> | |||||
</el-col> | |||||
<el-col :span="getIsShowRegionTree(['SUPER_ADMIN','REGION_MANAGER','EXPERT_ADMIN'])?20:24"> | |||||
<el-card class="w-full search"> | |||||
<el-form | |||||
:model="searchForm" | |||||
size="small" | |||||
label-suffix=":" | |||||
> | |||||
<el-row | |||||
:gutter="16" | |||||
class="mb-16" | |||||
> | |||||
<el-col :span="12"> | |||||
<el-form-item label="会议名称"> | |||||
<el-input | |||||
v-model="searchForm.name" | |||||
placeholder="请输入" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="12"> | |||||
<el-form-item label="评审项目"> | |||||
<el-input | |||||
v-model="searchForm.projectName" | |||||
placeholder="请输入" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
</el-row> | |||||
<el-row | |||||
:gutter="16" | |||||
> | |||||
<el-col :span="16"> | |||||
<el-form-item label="评审时间"> | |||||
<el-date-picker | |||||
v-model="searchForm.times" | |||||
type="datetimerange" | |||||
:editable="false" | |||||
format="YYYY-MM-DD HH:mm" | |||||
value-format="YYYY-MM-DD HH:mm" | |||||
range-separator="-" | |||||
start-placeholder="开始时间" | |||||
end-placeholder="结束时间" | |||||
/> | |||||
</el-form-item> | |||||
</el-col> | |||||
<el-col :span="8"> | |||||
<el-form-item class="btn"> | |||||
<div class="flex"> | |||||
<el-button | |||||
type="primary" | |||||
@click="search" | |||||
>查询</el-button> | |||||
<el-button | |||||
@click="reset" | |||||
>重置</el-button> | |||||
</div> | |||||
</el-form-item> | |||||
</el-col> | |||||
</el-row> | |||||
</el-form> | |||||
</el-card> | |||||
<el-card class="w-full mt-8"> | |||||
<template #header> | |||||
<div class="flex justify-between"> | |||||
<span>列表</span> | |||||
<div> | |||||
<el-button | |||||
type="primary" | |||||
size="small" | |||||
icon="Plus" | |||||
@click="toAddMeeting" | |||||
>新增会议</el-button> | |||||
</div> | |||||
</div> | |||||
</template> | |||||
<table-list | |||||
ref="tableListRef" | |||||
:column="column" | |||||
:data="data" | |||||
:total="total" | |||||
@get-table-data="getTableData" | |||||
> | |||||
<template #projectName="{scope}"> | |||||
<a @click="viewProject(scope.row)">查看</a> | |||||
</template> | |||||
<template #action="{ scope }"> | |||||
<a @click="checkDetail(scope.row)">详情</a> | |||||
</template> | |||||
</table-list> | |||||
</el-card> | |||||
</el-col> | |||||
</el-row> | |||||
<meeting-project-dialog :visible="meetingProjectDialogData.visible" :meeting-id="meetingProjectDialogData.meetingId" @close="close" /> | |||||
</template> | |||||
<style lang='less' scoped> | |||||
</style> |
@@ -0,0 +1,860 @@ | |||||
<script setup name='meetingDetail'> | |||||
import { ref, reactive, onMounted, h, getCurrentInstance, nextTick } from 'vue' | |||||
import { useRouter, useRoute } from 'vue-router' | |||||
import { | |||||
batchAppoint, | |||||
confirmedRoster, convertToAppoint, expertConfirm, | |||||
expertRelease, | |||||
inviteExpertList, | |||||
meetingBasicInfo, | |||||
meetingCancel, | |||||
meetingInviteRuleDetail, setUpHeadman, stopInvite, | |||||
continueInvite, listReview, expertRemove, exportTable | |||||
} from '@/http/apis/expertManage/reviewMeeting' | |||||
import store from '@/store' | |||||
import addExpertDialog from '../addMeeting/components/addExpertDialog.vue' | |||||
import { districtList } from '@/http/apis/commonApi' | |||||
import { templatesById } from '@/http/apis/expertManage/expertReview' | |||||
import memberOpinion from '@/pages/expertManage/expertReview/components/memberOpinion.vue' | |||||
import LeaveDialog from '@/pages/expertManage/expertReview/components/leaveDialog.vue' | |||||
const { proxy } = getCurrentInstance(), | |||||
router = useRouter(), | |||||
route = useRoute(), | |||||
{ meetingTypeOptions } = store.dictStore.globalDicts || {}, | |||||
dialogVisible = ref(false), | |||||
// 评审项目 | |||||
column = reactive([ | |||||
{ | |||||
label: '序号', | |||||
type: 'index', | |||||
width: '60' | |||||
}, | |||||
{ | |||||
label: '项目名称', | |||||
key: 'projectName', | |||||
prop: 'projectName', | |||||
minWidth: '150', | |||||
showOverflowTooltip: true | |||||
}, | |||||
{ | |||||
label: '申报单位', | |||||
key: 'buildOrg', | |||||
prop: 'buildOrg', | |||||
minWidth: '80', | |||||
showOverflowTooltip: true | |||||
}, | |||||
{ | |||||
label: '项目类型', | |||||
key: 'projectTypeName', | |||||
prop: 'projectTypeName', | |||||
width: '80' | |||||
}, | |||||
{ | |||||
label: '申报金额(万元)', | |||||
key: 'declareAmount', | |||||
prop: 'declareAmount' | |||||
}, | |||||
{ | |||||
label: '预算年度', | |||||
key: 'projectYear', | |||||
prop: 'projectYear' | |||||
}, | |||||
{ | |||||
label: '评审结果', | |||||
key: 'reviewResult', | |||||
prop: 'reviewResult', | |||||
render: row => h('span', row.reviewResult || '-') | |||||
}, | |||||
{ | |||||
label: '操作', | |||||
slot: 'action', | |||||
width: '80', | |||||
fixed: 'right' | |||||
} | |||||
]), | |||||
column2 = reactive([ | |||||
{ | |||||
label: '序号', | |||||
type: 'index', | |||||
width: '60' | |||||
}, | |||||
{ | |||||
label: '规则', | |||||
key: 'ruleId', | |||||
slot: 'ruleId' | |||||
}, | |||||
{ | |||||
label: '申请人数', | |||||
key: 'inviteCnt', | |||||
prop: 'inviteCnt' | |||||
}, | |||||
{ | |||||
label: '已确认参会人数', | |||||
key: 'agreeCnt', | |||||
slot: 'agreeCnt' | |||||
}, | |||||
{ | |||||
label: '实抽人数', | |||||
key: 'noticedCnt', | |||||
prop: 'noticedCnt' | |||||
} | |||||
]), | |||||
column3 = reactive([ | |||||
{ | |||||
label: '序号', | |||||
type: 'index', | |||||
width: '60' | |||||
}, | |||||
{ | |||||
label: '专家姓名', | |||||
key: 'name', | |||||
prop: 'name', | |||||
width: '140', | |||||
render: row => h('span', `${row.name}${row.isHeadman ? '(组长)' : ''}`) | |||||
}, | |||||
{ | |||||
label: '手机号码', | |||||
key: 'contact', | |||||
slot: 'contact', | |||||
width: '120' | |||||
}, | |||||
{ | |||||
label: '匹配规则', | |||||
key: 'ruleId', | |||||
slot: 'ruleId' | |||||
}, | |||||
{ | |||||
label: '是否参加', | |||||
key: 'confirmedAttend', | |||||
prop: 'confirmedAttend', | |||||
render: row => h('span', `${row.noticeStatus === '已通知' && row.confirmedAttend ? '确认参加' : row.noticeStatus === '已通知' && !row.confirmedAttend ? '拒绝参加' : '-'}`) | |||||
}, | |||||
{ | |||||
label: '专家请假', | |||||
key: 'leaved', | |||||
slot: 'leaved' | |||||
}, | |||||
{ | |||||
label: '语音通知状态', | |||||
key: 'noticeStatus', | |||||
prop: 'noticeStatus', | |||||
width: '200' | |||||
}, | |||||
{ | |||||
label: '语音通知时间', | |||||
key: 'noticeTime', | |||||
prop: 'noticeTime', | |||||
width: '200' | |||||
} | |||||
]), | |||||
column4 = reactive([ | |||||
{ | |||||
type: 'radio', | |||||
key: 'expertId', | |||||
width: '60' | |||||
}, | |||||
{ | |||||
label: '专家姓名', | |||||
key: 'name', | |||||
prop: 'name' | |||||
}, | |||||
{ | |||||
label: '工作单位', | |||||
key: 'company', | |||||
prop: 'company', | |||||
minWidth: '150', | |||||
showOverflowTooltip: true | |||||
}, | |||||
{ | |||||
label: '手机号码', | |||||
key: 'mobile', | |||||
slot: 'mobile' | |||||
}, | |||||
{ | |||||
label: '专家类型', | |||||
key: 'expertTypeName', | |||||
prop: 'expertTypeName' | |||||
} | |||||
]), | |||||
column5 = reactive([ | |||||
{ | |||||
label: '专家姓名', | |||||
key: 'name', | |||||
prop: 'name', | |||||
render: row => h('span', `${row.name}${row.isHeadman ? '(组长)' : ''}`) | |||||
}, | |||||
{ | |||||
label: '手机号码', | |||||
key: 'mobile', | |||||
slot: 'mobile' | |||||
}, | |||||
{ | |||||
label: '是否参会', | |||||
key: 'status', | |||||
prop: 'status', | |||||
render: row => h('span', row.status === 3 ? '是' : row.status === 4 || row.status === 5 || row.status === 7 ? '否' : '-') | |||||
}, | |||||
{ | |||||
label: '操作', | |||||
slot: 'action', | |||||
width: '180', | |||||
fixed: 'right' | |||||
} | |||||
]), | |||||
// 获取会议详情 | |||||
basicInfo = ref({}), | |||||
inviteRuleDetail = ref({}), | |||||
isExpertConfirmed = ref(false), | |||||
getDetail = async () => { | |||||
const res = await meetingBasicInfo(route.query.id) | |||||
isExpertConfirmed.value = res.data.confirmedRoster | |||||
const res1 = await meetingInviteRuleDetail(route.query.id) | |||||
basicInfo.value = res.data | |||||
inviteRuleDetail.value = res1.data | |||||
}, | |||||
// 抽取情况、通知情况 | |||||
inviteExpertListData = ref({}), | |||||
getInviteExpertList = async () => { | |||||
const res = await inviteExpertList(route.query.id) | |||||
console.log(res.data) | |||||
inviteExpertListData.value = res.data | |||||
}, | |||||
// 查看规则 | |||||
ruleDialogData = reactive({ | |||||
visible: false, | |||||
data: [] | |||||
}), | |||||
viewRule = (id) => { | |||||
ruleDialogData.visible = true | |||||
ruleDialogData.data = inviteRuleDetail.value.randomRules.find(i => i.id === id) | |||||
}, | |||||
// 取消会议 | |||||
cancelMeeting = () => { | |||||
proxy.$messageBox | |||||
.confirm('确认取消该会议吗?', '提示!', { | |||||
type: 'warning' | |||||
}) | |||||
.then(async () => { | |||||
await meetingCancel({ meetingId: route.query.id * 1 }) | |||||
proxy.$message.success('取消会议成功!') | |||||
onLoad() | |||||
}) | |||||
}, | |||||
// 释放专家 | |||||
releaseExpert = () => { | |||||
proxy.$messageBox | |||||
.confirm('确认释放专家吗?', '提示!', { | |||||
type: 'warning' | |||||
}) | |||||
.then(async () => { | |||||
await expertRelease({ meetingId: route.query.id * 1 }) | |||||
proxy.$message.success('释放专家成功!') | |||||
onLoad() | |||||
}) | |||||
}, | |||||
// 1重发短信、2、3确认召开会议 | |||||
reText = (type) => { | |||||
let text = `${type === 1 ? '确认重发短信' : '确认召开会议'}` | |||||
if (type === 3) { | |||||
const data = inviteExpertListData.value.inviteStatistics?.filter(i => i.inviteCnt > i.agreeCnt).map(i => '规则' + (inviteRuleDetail.value?.randomRules?.findIndex(j => j.id === i.ruleId) + 1)).join('、') | |||||
if (data) { | |||||
text = `${data}人数不够,确认召开会议` | |||||
} | |||||
} | |||||
proxy.$messageBox | |||||
.confirm(`${text}吗?`, '提示!', { | |||||
type: 'warning' | |||||
}) | |||||
.then(async () => { | |||||
await confirmedRoster({ meetingId: route.query.id * 1 }) | |||||
proxy.$message.success('操作成功!') | |||||
onLoad() | |||||
}) | |||||
}, | |||||
// 指定抽取-是否所有专家已参会或是不参会 | |||||
IsAllExpertAttend = () => { | |||||
if (inviteExpertListData.value.inviteExpertList.filter(i => !i.status && i.inviteType !== 1)?.length) { | |||||
return false | |||||
} | |||||
return true | |||||
}, | |||||
// 终止抽取 | |||||
stopInvites = () => { | |||||
proxy.$messageBox | |||||
.confirm('确认终止抽取吗?', '提示!', { | |||||
type: 'warning' | |||||
}) | |||||
.then(async () => { | |||||
await stopInvite(route.query.id * 1) | |||||
proxy.$message.success('终止抽取成功!') | |||||
onLoad() | |||||
}) | |||||
}, | |||||
// 参会、不参会 | |||||
confirmExpert = (data, agreed) => { | |||||
proxy.$messageBox | |||||
.confirm(`确认${agreed ? '参会' : '不参会'}吗?`, '提示!', { | |||||
type: 'warning' | |||||
}) | |||||
.then(async () => { | |||||
await expertConfirm({ | |||||
agreed, | |||||
expertMeetingId: data.expertMeetingId, | |||||
meetingId: route.query.id * 1 | |||||
}) | |||||
onLoad() | |||||
}) | |||||
}, | |||||
// 指定抽取-移除 | |||||
removeExpert = async (row) => { | |||||
await expertRemove({ expertMeetingId: row.expertMeetingId, meetingId: row.meetingId }) | |||||
proxy.$message.success('移除成功!') | |||||
onLoad() | |||||
}, | |||||
// 设置组长 | |||||
tableHeadListRef = ref(), | |||||
headManData = ref(), | |||||
radioChange = (val) => { | |||||
headManData.value = val | |||||
}, | |||||
showHeadManDialog = async () => { | |||||
dialogVisible.value = true | |||||
await nextTick() // 必须 | |||||
tableHeadListRef.value.setRadio(inviteExpertListData.value?.inviteExpertList?.find(i => i.isHeadman)?.expertId || '') | |||||
}, | |||||
submitUpHeadman = async () => { | |||||
dialogVisible.value = false | |||||
await setUpHeadman({ | |||||
agreed: true, | |||||
expertMeetingId: headManData.value.expertMeetingId, | |||||
meetingId: route.query.id * 1 | |||||
}) | |||||
proxy.$message.success('设置组长成功!') | |||||
onLoad() | |||||
}, | |||||
// 指定专家-补充 | |||||
expertDialogData = reactive({ | |||||
visible: false, | |||||
data: undefined | |||||
}), | |||||
regionTree = ref([]), | |||||
showExpertDialog = () => { | |||||
expertDialogData.visible = true | |||||
}, | |||||
getExpertData = async (row) => { | |||||
await batchAppoint({ | |||||
expertIdList: row.map(i => i.userId), | |||||
meetingId: route.query.id * 1 | |||||
}) | |||||
expertDialogData.visible = false | |||||
proxy.$message.success('添加成功!') | |||||
onLoad() | |||||
}, | |||||
// 转为指定抽取 | |||||
toAppointInvite = async () => { | |||||
await convertToAppoint({ meetingId: route.query.id * 1 }) | |||||
proxy.$message.success('转为指定抽取成功!') | |||||
onLoad() | |||||
}, | |||||
// 刷新 | |||||
reloadLoaing = ref(false), | |||||
onLoad = async (flag) => { | |||||
reloadLoaing.value = !flag && true | |||||
await getDetail() | |||||
await getInviteExpertList() | |||||
reloadLoaing.value = false | |||||
}, | |||||
// 随机邀请人数是否足够 | |||||
getIsEnough = () => { | |||||
if (inviteExpertListData.value.inviteStatistics.filter(i => i.agreeCnt !== i.inviteCnt)?.length) { | |||||
return true | |||||
} | |||||
return false | |||||
}, | |||||
// 续抽 | |||||
continueInvites = () => { | |||||
proxy.$messageBox | |||||
.confirm('续抽后,将重新通知已拒绝参会的专家们,确定继续吗?', '提示!', { | |||||
type: 'warning' | |||||
}) | |||||
.then(async () => { | |||||
await continueInvite({ meetingId: route.query.id * 1 }) | |||||
proxy.$message.success('续抽成功!') | |||||
onLoad() | |||||
}) | |||||
}, | |||||
// 查看评审意见详情 | |||||
// 所有意见-抽屉 | |||||
drawerVisible = ref(false), | |||||
templatesData = ref([]), // 模板数据 | |||||
memberOpinions = ref([]), // 所有意见 | |||||
showReviewDetail = async (data) => { | |||||
const res = await listReview({ projectId: data.projectId, meetingId: route.query.id }) | |||||
const res1 = await templatesById({ templateIds: res.data.map(i => i.templateId).join(',') }) | |||||
templatesData.value = res1.data | |||||
memberOpinions.value = res.data && res.data.map(i => { | |||||
return { | |||||
...i, | |||||
reviewTemplateOptions: i.reviewTemplateOptions && i.reviewTemplateOptions.map(temp => { | |||||
const data = templatesData.value.find(j => i.templateId === j.templateId).templates | |||||
return { | |||||
...temp, | |||||
title: data.find(r => r.serialNo === temp.questionSerialNo)?.title, | |||||
optionsValue: data.find(r => r.serialNo === temp.questionSerialNo)?.options.filter(j => temp.optionSerialNo.includes(j.serialNo)).map(j => j.option).join('、') | |||||
} | |||||
}) || [] | |||||
} | |||||
}) || [] | |||||
drawerVisible.value = true | |||||
}, | |||||
tableName = { | |||||
1: '劳务费发放审批单', | |||||
2: '专家费用单', | |||||
3: '专家抽取表', | |||||
4: '项目评审单' | |||||
}, | |||||
handleCommand = async (command) => { | |||||
const res = await exportTable(command, route.query.id) | |||||
let suffix = 'docx' | |||||
if (res.type === 'application/zip') { | |||||
suffix = 'zip' | |||||
} | |||||
const url = URL.createObjectURL(res) | |||||
const link = document.createElement('a') | |||||
link.style.display = 'none' | |||||
link.href = url | |||||
link.download = `${tableName[command]}.${suffix}` | |||||
document.body.appendChild(link) | |||||
link.click() | |||||
document.body.removeChild(link) | |||||
window.URL.revokeObjectURL(url) | |||||
}, | |||||
// 请假 | |||||
leaveDialogData = reactive({ | |||||
visible: false, | |||||
data: undefined | |||||
}), | |||||
leave = (row) => { | |||||
leaveDialogData.visible = true | |||||
leaveDialogData.data = { | |||||
expertId: row.expertId, | |||||
meetingId: route.query.id | |||||
} | |||||
}, | |||||
closeLeaveDialog = (flag) => { | |||||
leaveDialogData.visible = false | |||||
flag && getInviteExpertList() | |||||
} | |||||
onMounted(async () => { | |||||
getDetail() | |||||
getInviteExpertList() | |||||
const res = await districtList() | |||||
regionTree.value.push(res.data) | |||||
}) | |||||
</script> | |||||
<template> | |||||
<el-card class="box-card"> | |||||
<template #header> | |||||
<div class="card-header"> | |||||
<span>会议信息</span> | |||||
</div> | |||||
</template> | |||||
<el-descriptions | |||||
title="" | |||||
:column="2" | |||||
border | |||||
> | |||||
<el-descriptions-item label="会议名称"> | |||||
{{ basicInfo.meetingName }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="评审类型"> | |||||
{{ meetingTypeOptions[basicInfo.meetingType] }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item | |||||
label="评审项目" | |||||
:span="2" | |||||
> | |||||
<table-list | |||||
ref="tableListRef" | |||||
:column="column" | |||||
:pagination="false" | |||||
style="max-height: 200px;width:95%" | |||||
:data="basicInfo.projects" | |||||
> | |||||
<template #action="{ scope }"> | |||||
<a v-if="scope.row.reviewResult" @click="showReviewDetail(scope.row)">详情</a> | |||||
</template> | |||||
</table-list> | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="评审时间"> | |||||
{{ basicInfo.startTime }}~{{ basicInfo.endTime }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item | |||||
label="评审耗时" | |||||
> | |||||
{{ basicInfo.meetingUsageTime===1?'半天':'一天' }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="评审地点"> | |||||
{{ basicInfo.meetingAddress }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="评委到场时间"> | |||||
{{ basicInfo.judgesAttendanceTime }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="联系人"> | |||||
{{ basicInfo.connecter }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="联系方式"> | |||||
{{ basicInfo.contact }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="会议状态"> | |||||
<span :class="`dot mr-4 ${basicInfo.status === 1 ? 'bg-success' : 'bg-danger'}`"></span> | |||||
<span :class="`${basicInfo.status === 1 ? 'text-success' : 'text-danger'}`">{{ basicInfo.status===1?'正常': '已取消' }}</span> | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="抽取方式"> | |||||
{{ basicInfo.inviteType === 1 ? '随机抽取' : basicInfo.inviteType === 2?'指定抽取':'-' }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="抽取状态"> | |||||
{{ basicInfo.invitedStopped?'抽取结束':!basicInfo.inviteStatus ? '抽取中' :'抽取结束' }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="专家名单确认状态"> | |||||
{{ basicInfo.confirmedRoster? '已确认' : '未确认' }} | |||||
</el-descriptions-item> | |||||
<template v-if="basicInfo.inviteType === 1"> | |||||
<el-descriptions-item label="部门、条线回避规则"> | |||||
{{ inviteRuleDetail.avoidInfo?.avoidType===2?'回避条线':inviteRuleDetail.avoidInfo?.avoidType===1?'回避单位':inviteRuleDetail.avoidInfo?.avoidType===3?'不回避':'-' }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item | |||||
label="回避单位" | |||||
> {{ inviteRuleDetail.avoidInfo?.avoidUnits?.map(i=>i).join('、')||"-" }}</el-descriptions-item> | |||||
<el-descriptions-item label="回避专家"> | |||||
{{ inviteRuleDetail.avoidInfo?.experts?.map(i=>i.name).join('、')||"-" }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="回避条线"> | |||||
{{ inviteRuleDetail.avoidInfo?.avoidOrgs?.map(i=>i).join('、')||'-' }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="回避次数"> | |||||
{{ inviteRuleDetail.avoidInfo?.weekInviteCount||'-' }} | |||||
</el-descriptions-item> | |||||
</template> | |||||
<el-descriptions-item | |||||
v-else | |||||
label="邀请理由" | |||||
:span="2" | |||||
>{{ basicInfo?.inviteRule?.appointRule?.inviteDesc||'-' }}</el-descriptions-item> | |||||
</el-descriptions> | |||||
</el-card> | |||||
<!-- 随机抽取--> | |||||
<template v-if="basicInfo.inviteType === 1"> | |||||
<el-card class="box-card"> | |||||
<template #header> | |||||
<div class="card-header"> | |||||
<span>抽取情况</span> | |||||
<div> | |||||
<el-button | |||||
v-if="basicInfo.invitedStopped||basicInfo.inviteStatus" | |||||
class="button" | |||||
type="primary" | |||||
plain | |||||
@click="toAppointInvite" | |||||
>转为指定抽取</el-button> | |||||
<el-button | |||||
v-if="basicInfo.status===1&&(basicInfo.invitedStopped||basicInfo.inviteStatus)&&getIsEnough()" | |||||
class="button" | |||||
type="primary" | |||||
plain | |||||
@click="continueInvites" | |||||
>续抽</el-button> | |||||
<!-- <el-button--> | |||||
<!-- v-if="basicInfo.status===1&&(basicInfo.invitedStopped||basicInfo.inviteStatus)&&!basicInfo.confirmedRoster"--> | |||||
<!-- class="button"--> | |||||
<!-- type="primary"--> | |||||
<!-- @click="reText(3)"--> | |||||
<!-- >确认召开会议</el-button>--> | |||||
</div> | |||||
</div> | |||||
</template> | |||||
<table-list | |||||
ref="tableListRef" | |||||
:column="column2" | |||||
:pagination="false" | |||||
:data="inviteExpertListData.inviteStatistics" | |||||
> | |||||
<template #agreeCnt="{ scope }"> | |||||
<div class="flex items-center"> | |||||
<span>{{ scope.row.agreeCnt }}</span> | |||||
<el-icon | |||||
v-if="scope.row.agreeCnt===scope.row.inviteCnt" | |||||
class="ml-8" | |||||
style="color: #4ecb74" | |||||
><Select /></el-icon> | |||||
</div> | |||||
</template> | |||||
<template | |||||
#ruleId="{scope}" | |||||
> | |||||
<a @click="viewRule(scope.row.ruleId)">规则{{ inviteRuleDetail?.randomRules?.findIndex(i => i.id === scope.row.ruleId)+1||'' }}</a> | |||||
</template> | |||||
</table-list> | |||||
</el-card> | |||||
<el-card class="box-card"> | |||||
<template #header> | |||||
<div class="card-header"> | |||||
<span>通知情况</span> | |||||
<el-button | |||||
v-if="!basicInfo.invitedStopped" | |||||
class="button" | |||||
type="danger" | |||||
plain | |||||
@click="stopInvites" | |||||
>终止抽取</el-button> | |||||
</div> | |||||
</template> | |||||
<el-alert | |||||
type="warning" | |||||
:description="`共有${inviteExpertListData.inviteExpertList?.length}位专家,已通知${inviteExpertListData.inviteExpertList?.filter(i=>i.noticeStatus==='已通知')?.length}位,尚未通知${inviteExpertListData.inviteExpertList?.filter(i=>i.noticeStatus==='未通知')?.length}位。`" | |||||
show-icon | |||||
:closable="false" | |||||
/> | |||||
<table-list | |||||
ref="tableListRef" | |||||
:column="column3" | |||||
:pagination="false" | |||||
class="mt-15" | |||||
:data="inviteExpertListData.inviteExpertList" | |||||
> | |||||
<template #contact="{scope}"> | |||||
<el-tooltip | |||||
class="box-item" | |||||
effect="dark" | |||||
:content="scope.row.contact" | |||||
> | |||||
<span>{{ scope.row.contact?.replace(/(\d{3})\d*(\d{4})/, '$1****$2') }}</span> | |||||
</el-tooltip> | |||||
</template> | |||||
<template #leaved="{scope}"> | |||||
<a v-if="!scope.row.leaved&&scope.row.confirmedAttend" @click="leave(scope.row)">请假</a> | |||||
<span v-else-if="scope.row.leaved">已请假</span> | |||||
<span v-else>-</span> | |||||
</template> | |||||
<template #ruleId="{ scope }"> | |||||
<a @click="viewRule(scope.row.ruleId)">规则{{ inviteRuleDetail?.randomRules?.findIndex(i => i.id === scope.row.ruleId)+1||'' }}</a> | |||||
</template> | |||||
</table-list> | |||||
</el-card> | |||||
</template> | |||||
<!-- 指定抽取--> | |||||
<el-card v-else class="box-card"> | |||||
<template #header> | |||||
<div class="card-header"> | |||||
<span>通知情况</span> | |||||
<span v-if="basicInfo.status===1"> | |||||
<el-button | |||||
v-if="!isExpertConfirmed" | |||||
class="button" | |||||
plain | |||||
@click="showExpertDialog" | |||||
>添加专家</el-button> | |||||
<el-button | |||||
v-if="!basicInfo.confirmedRoster&&IsAllExpertAttend()" | |||||
class="button" | |||||
type="primary" | |||||
plain | |||||
@click="reText(2)" | |||||
>确认召开会议</el-button> | |||||
</span> | |||||
</div> | |||||
</template> | |||||
<el-alert | |||||
type="warning" | |||||
:description="`共有${inviteExpertListData.inviteExpertList?.length}位专家,确认参会${inviteExpertListData.inviteExpertList?.filter(i=>i.status===3)?.length}位。`" | |||||
show-icon | |||||
:closable="false" | |||||
/> | |||||
<table-list | |||||
ref="tableListRef" | |||||
:column="column5" | |||||
:pagination="false" | |||||
class="mt-15" | |||||
:data="inviteExpertListData.inviteExpertList" | |||||
> | |||||
<template #mobile="{scope}"> | |||||
<el-tooltip | |||||
class="box-item" | |||||
effect="dark" | |||||
:content="scope.row.mobile" | |||||
> | |||||
<span>{{ scope.row.mobile?.replace(/(\d{3})\d*(\d{4})/, '$1****$2') }}</span> | |||||
</el-tooltip> | |||||
</template> | |||||
<template #action="{ scope }"> | |||||
<div v-if="!scope.row.status&&scope.row.inviteType!==1"> | |||||
<a @click="confirmExpert(scope.row,true)">参会</a> | |||||
<a @click="confirmExpert(scope.row,false)">不参会</a> | |||||
<a class="text-danger" @click="removeExpert(scope.row)">移除</a> | |||||
</div> | |||||
<div v-else> | |||||
<span>-</span> | |||||
</div> | |||||
</template> | |||||
</table-list> | |||||
</el-card> | |||||
<div class="flex h-60 items-center justify-between bg-white "> | |||||
<div class="flex items-center ml-20"> | |||||
<el-button plain @click="router.go(-1)">返回</el-button> | |||||
<el-button plain :loading="reloadLoaing" @click="onLoad(false)">刷新</el-button> | |||||
<el-button | |||||
v-if="basicInfo.status===1" | |||||
type="danger" | |||||
plain | |||||
@click="cancelMeeting" | |||||
>取消会议</el-button> | |||||
<el-button | |||||
v-if="basicInfo.status===1&&basicInfo.inviteStatus" | |||||
type="danger" | |||||
plain | |||||
@click="releaseExpert" | |||||
>释放专家</el-button> | |||||
</div> | |||||
<div class="flex items-center mr-20"> | |||||
<el-button | |||||
v-if="basicInfo.status===1&&basicInfo.confirmedRoster" | |||||
plain | |||||
type="primary" | |||||
@click="showHeadManDialog" | |||||
>设置专家组长</el-button> | |||||
<el-button | |||||
v-if="basicInfo.status===1&&basicInfo.confirmedRoster" | |||||
plain | |||||
type="primary" | |||||
@click="reText(1)" | |||||
>重发短信</el-button> | |||||
<el-dropdown v-if="basicInfo.status===1&&basicInfo.confirmedRoster" class="ml-12" @command="handleCommand"> | |||||
<el-button type="primary" plain> | |||||
导出<el-icon class="el-icon--right"><arrow-down /></el-icon> | |||||
</el-button> | |||||
<template #dropdown> | |||||
<el-dropdown-menu> | |||||
<el-dropdown-item command="1">劳务费发放审批单</el-dropdown-item> | |||||
<el-dropdown-item command="2">专家费用单</el-dropdown-item> | |||||
<el-dropdown-item command="3">专家抽取表</el-dropdown-item> | |||||
<el-dropdown-item command="4">项目评审单</el-dropdown-item> | |||||
</el-dropdown-menu> | |||||
</template> | |||||
</el-dropdown> | |||||
</div> | |||||
</div> | |||||
<el-dialog | |||||
v-model="dialogVisible" | |||||
title="设置专家组长" | |||||
width="50%" | |||||
> | |||||
<table-list | |||||
ref="tableHeadListRef" | |||||
:column="column4" | |||||
:pagination="false" | |||||
class="mt-15" | |||||
:data="inviteExpertListData.inviteExpertList.filter(i=>i.status===3)" | |||||
@radio-change="radioChange" | |||||
> | |||||
<template #mobile="{scope}"> | |||||
<el-tooltip | |||||
class="box-item" | |||||
effect="dark" | |||||
:content="scope.row.mobile" | |||||
> | |||||
<span>{{ scope.row.mobile?.replace(/(\d{3})\d*(\d{4})/, '$1****$2') }}</span> | |||||
</el-tooltip> | |||||
</template> | |||||
</table-list> | |||||
<template #footer> | |||||
<span class="dialog-footer"> | |||||
<el-button @click="dialogVisible = false">关闭</el-button> | |||||
<el-button | |||||
type="primary" | |||||
@click="submitUpHeadman" | |||||
> | |||||
提交 | |||||
</el-button> | |||||
</span> | |||||
</template> | |||||
</el-dialog> | |||||
<el-dialog | |||||
v-model="ruleDialogData.visible" | |||||
title="规则" | |||||
width="70%" | |||||
> | |||||
<el-descriptions :column="3"> | |||||
<el-descriptions-item label="内外围:"> | |||||
{{ ruleDialogData.data?.expertDicts?.find(i=>i.expertDict==='expert_type')?.dictCodes.join('、')||'-' }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="履职意向:"> | |||||
{{ ruleDialogData.data?.intentionRegions?.map(i=>i.regionName).join('-') }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="专家来源:"> | |||||
{{ ruleDialogData.data?.expertTags?.find(i=>i.expertTag==='expert_source')?.tagCodes.join('、')||'-' }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="职称级别:"> | |||||
{{ ruleDialogData.data?.expertDicts?.find(i=>i.expertDict==='title_level')?.dictCodes.join('、')||'-' }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="擅长方向:"> | |||||
{{ ruleDialogData.data?.expertTags?.find(i=>i.expertTag==='good_at')?.tagCodes.join('、')||'-' }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="技术专长:"> | |||||
{{ ruleDialogData.data?.expertTags?.find(i=>i.expertTag==='technical_expertise')?.tagCodes.join('、')||'-' }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="行业领域:"> | |||||
{{ ruleDialogData.data?.expertTags?.find(i=>i.expertTag==='industry_sector')?.tagCodes.join('、')||'-' }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="其他标签:"> | |||||
{{ ruleDialogData.data?.expertTags?.find(i=>i.expertTag==='other')?.tagCodes.join('、')||'-' }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="专家级别:"> | |||||
{{ ruleDialogData.data?.expertRegions?.map(i=>i.regionName).join('-') }} | |||||
</el-descriptions-item> | |||||
<el-descriptions-item label="邀请数量:"> | |||||
{{ ruleDialogData.data.count }} | |||||
</el-descriptions-item> | |||||
</el-descriptions> | |||||
</el-dialog> | |||||
<add-expert-dialog | |||||
:visible="expertDialogData.visible" | |||||
:data="expertDialogData.data" | |||||
:region-tree="regionTree" | |||||
@get-user-data="getExpertData" | |||||
@close="expertDialogData.visible = false" | |||||
/> | |||||
<el-drawer | |||||
v-model="drawerVisible" | |||||
title="评审详情" | |||||
style="position: absolute" | |||||
direction="rtl" | |||||
size="70%" | |||||
:modal="false" | |||||
:append-to-body="false" | |||||
modal-class="myDrawerModal" | |||||
> | |||||
<member-opinion :member-opinions="memberOpinions" /> | |||||
</el-drawer> | |||||
<leave-dialog | |||||
:visible="leaveDialogData.visible" | |||||
:data="leaveDialogData.data" | |||||
title="填写请假原因" | |||||
@close="closeLeaveDialog" | |||||
/> | |||||
</template> | |||||
<style lang='less' scoped> | |||||
.box-card{ | |||||
margin-bottom: 20px; | |||||
.card-header { | |||||
display: flex; | |||||
justify-content: space-between; | |||||
align-items: center; | |||||
} | |||||
} | |||||
</style> | |||||
@@ -0,0 +1,251 @@ | |||||
<script setup name='reviewTemplateConfig'> | |||||
import { reactive, ref, onMounted, getCurrentInstance } from 'vue' | |||||
import ElTree from '@/components/elTree/index.vue' | |||||
import { template, save } from '@/http/apis/expertManage/reviewTemplateConfig' | |||||
import { getIsShowRegionTree, getTreeParams } from '@/utils/getIsShowRegionTree' | |||||
const { proxy } = getCurrentInstance(), | |||||
searchForm = reactive({ | |||||
regionCode: undefined, | |||||
templateType: '1' | |||||
}), | |||||
// 地区 | |||||
getTree = (data) => { | |||||
searchForm.regionCode = data.regionLevel === 3 ? data.regionCode : undefined | |||||
getTemplate() | |||||
}, | |||||
// 切换模板类型 | |||||
handleClickTab = ({ props }) => { | |||||
searchForm.templateType = props.name | |||||
getTemplate() | |||||
}, | |||||
// 获取模板 | |||||
getTemplate = async () => { | |||||
try { | |||||
const res = await template({ ...searchForm, templateType: searchForm.templateType * 1 }) | |||||
formData.value = res.data || { templates: [] } | |||||
} catch (e) { | |||||
formData.value = { templates: [] } | |||||
} | |||||
}, | |||||
// 模板列表 | |||||
column = [ | |||||
{ | |||||
label: '序号', | |||||
type: 'index', | |||||
width: '60' | |||||
}, | |||||
{ | |||||
label: '意见标题', | |||||
slot: 'title' | |||||
}, | |||||
{ | |||||
label: '选项类型', | |||||
slot: 'optionType', | |||||
width: 120 | |||||
}, | |||||
{ | |||||
label: '包含的选项', | |||||
slot: 'options' | |||||
}, | |||||
{ | |||||
label: '操作', | |||||
slot: 'action', | |||||
width: 60 | |||||
} | |||||
], | |||||
formData = ref({ | |||||
templates: [] | |||||
}), | |||||
formRef = ref(), | |||||
// 增加问题 | |||||
addTemp = () => { | |||||
formData.value.templates.push({ title: '', optionType: undefined, options: [{}] }) | |||||
}, | |||||
// 删除 | |||||
removeTemp = (index) => { | |||||
formData.value.templates.splice(index, 1) | |||||
}, | |||||
// 增加选项 | |||||
addOptions = (index) => { | |||||
formData.value.templates[index].options.push({ option: '' }) | |||||
}, | |||||
// 删除选项 | |||||
removeOption = (index, key) => { | |||||
formData.value.templates[index].options.splice(key, 1) | |||||
}, | |||||
loading = ref(false), | |||||
submit = async formEl => { | |||||
if (!formEl) { | |||||
return | |||||
} | |||||
await formEl.validate(async valid => { | |||||
if (valid) { | |||||
const postData = getData() | |||||
loading.value = true | |||||
try { | |||||
await save(postData) | |||||
proxy.$message.success('提交成功!') | |||||
loading.value = false | |||||
} catch (e) { | |||||
loading.value = false | |||||
} | |||||
} | |||||
}) | |||||
}, | |||||
// 插入序号 | |||||
getData = () => { | |||||
return { | |||||
regionCode: searchForm.regionCode, | |||||
templateType: searchForm.templateType * 1, | |||||
templates: formData.value?.templates.map((item, index) => { | |||||
return { | |||||
...item, | |||||
serialNo: index, | |||||
options: item.options.map((option, key) => { | |||||
return { | |||||
...option, | |||||
serialNo: key | |||||
} | |||||
}) | |||||
} | |||||
}) || [] | |||||
} | |||||
} | |||||
onMounted(() => { | |||||
if (!getIsShowRegionTree(['SUPER_ADMIN', 'REGION_MANAGER', 'EXPERT_ADMIN'])) getTemplate() | |||||
}) | |||||
</script> | |||||
<template> | |||||
<el-row :gutter="16"> | |||||
<el-col | |||||
v-if="getIsShowRegionTree(['SUPER_ADMIN','REGION_MANAGER','EXPERT_ADMIN'])" | |||||
style="padding-right: 16px" | |||||
:span="4" | |||||
> | |||||
<elTree :params="getTreeParams({'SUPER_ADMIN':false,'REGION_MANAGER':false,'EXPERT_ADMIN':false})" @get-tree="getTree" /> | |||||
</el-col> | |||||
<el-col :span="getIsShowRegionTree(['SUPER_ADMIN','REGION_MANAGER','EXPERT_ADMIN'])?20:24"> | |||||
<el-card class="w-full tab-card footerCard"> | |||||
<template #header> | |||||
<el-tabs | |||||
v-model="searchForm.templateType" | |||||
class="demo-tabs" | |||||
@tab-click="handleClickTab" | |||||
> | |||||
<el-tab-pane | |||||
label="初步方案评审模版" | |||||
name="1" | |||||
/> | |||||
<el-tab-pane | |||||
label="建设方案评审模版" | |||||
name="2" | |||||
/> | |||||
<el-tab-pane | |||||
label="验收评审模版" | |||||
name="3" | |||||
/> | |||||
<el-tab-pane | |||||
label="部门联审模版" | |||||
name="4" | |||||
/> | |||||
<el-tab-pane | |||||
label="公平性审查" | |||||
name="5" | |||||
/> | |||||
</el-tabs> | |||||
</template> | |||||
<el-form ref="formRef" :model="formData"> | |||||
<table-list | |||||
ref="tableListRef" | |||||
:column="column" | |||||
:data="formData?.templates||[]" | |||||
:pagination="false" | |||||
> | |||||
<template #title="{scope}"> | |||||
<el-form-item | |||||
v-if="formData.templates[scope.$index]" | |||||
:prop="`templates[${scope.$index}].title`" | |||||
:rules="[ | |||||
{ | |||||
required: true, | |||||
message: '请输入', | |||||
} | |||||
]" | |||||
> | |||||
<el-input v-model="formData.templates[scope.$index].title" /> | |||||
</el-form-item> | |||||
</template> | |||||
<template #optionType="{scope}"> | |||||
<el-form-item | |||||
v-if="formData.templates[scope.$index]" | |||||
:prop="`templates[${scope.$index}].optionType`" | |||||
:rules="[ | |||||
{ | |||||
required: true, | |||||
message: '请选择', | |||||
} | |||||
]" | |||||
> | |||||
<el-select v-model="formData.templates[scope.$index].optionType"> | |||||
<el-option label="单选" :value="1" /> | |||||
<el-option label="多选" :value="2" /> | |||||
</el-select> | |||||
</el-form-item> | |||||
</template> | |||||
<template #options="{scope}"> | |||||
<template v-if="formData.templates[scope.$index]"> | |||||
<div | |||||
v-for="(item,key) in formData.templates[scope.$index].options" | |||||
:key="key" | |||||
class="flex items-center mb-8" | |||||
> | |||||
<el-form-item | |||||
class="flex-1" | |||||
style="margin-bottom: 0;" | |||||
:prop="`templates[${scope.$index}].options[${key}].option`" | |||||
:rules="[ | |||||
{ | |||||
required: true, | |||||
message: '请输入', | |||||
} | |||||
]" | |||||
> | |||||
<el-input v-model="formData.templates[scope.$index].options[key].option" /> | |||||
</el-form-item> | |||||
<svg-icon name="deleteIcon" class="ml-4 cursor-pointer text-24" @click="removeOption(scope.$index,key)" /> | |||||
</div> | |||||
<el-button | |||||
type="primary" | |||||
size="small" | |||||
class="w-full" | |||||
plain | |||||
icon="Plus" | |||||
@click="addOptions(scope.$index)" | |||||
>添加选项</el-button> | |||||
</template> | |||||
</template> | |||||
<template #action="{scope}"> | |||||
<a v-if="formData.templates[scope.$index]" class="text-danger" @click="removeTemp(scope.$index)">移除</a> | |||||
</template> | |||||
</table-list> | |||||
</el-form> | |||||
<el-button | |||||
type="primary" | |||||
class="w-full" | |||||
plain | |||||
icon="Plus" | |||||
@click="addTemp" | |||||
>添加意见类型</el-button> | |||||
<div class="footer"> | |||||
<el-button type="primary" :loading="loading" @click="submit(formRef)"> | |||||
提交 | |||||
</el-button> | |||||
</div> | |||||
</el-card> | |||||
</el-col> | |||||
</el-row> | |||||
</template> | |||||
<style lang='less' scoped> </style> |
@@ -0,0 +1,108 @@ | |||||
<script name="leaveDialog" setup> | |||||
import { watch } from 'vue' | |||||
import { useRouter } from 'vue-router' | |||||
const | |||||
props = defineProps({ | |||||
visible: { | |||||
type: Boolean, | |||||
default: false, | |||||
required: true | |||||
}, | |||||
initData: { | |||||
type: Array, | |||||
default: () => { | |||||
return [ | |||||
{ | |||||
name: '配置单位流程', | |||||
remark: '用于项目审核,请先配置单位默认流程。', | |||||
path: 'systemManage/unitSet/flowPathConfiguration' | |||||
}, | |||||
// { | |||||
// name: '配置财政编码', | |||||
// remark: '用于生成项目唯一编码。', | |||||
// path: 'unitSet/fiscalCodeSet' | |||||
// }, | |||||
{ | |||||
name: '配置印章编码', | |||||
remark: '用于电子签章。', | |||||
path: 'systemManage/unitSet/fiscalCodeSet' | |||||
}] | |||||
} | |||||
} | |||||
}), | |||||
router = useRouter(), | |||||
emits = defineEmits(['close']), | |||||
getUrlParams = (url) => { | |||||
// 通过 ? 分割获取后面的参数字符串 | |||||
const urlStr = url?.split('?')[1] || '' | |||||
if (!urlStr) { | |||||
return {} | |||||
} | |||||
// 创建空对象存储参数 | |||||
const obj = {} | |||||
// 再通过 & 将每一个参数单独分割出来 | |||||
const paramsArr = urlStr.split('&') | |||||
for (let i = 0, len = paramsArr.length; i < len; i++) { | |||||
// 再通过 = 将每一个参数分割为 key:value 的形式 | |||||
const arr = paramsArr[i].split('=') | |||||
obj[arr[0]] = arr[1] | |||||
} | |||||
return obj | |||||
}, | |||||
view = (path) => { | |||||
const routeUrl = router.resolve({ | |||||
path: `/systemManage/${path}`, | |||||
query: getUrlParams(path) | |||||
}) | |||||
window.open(routeUrl.href, '_blank') | |||||
} | |||||
watch( | |||||
() => props.visible, | |||||
async val => { | |||||
if (val) { | |||||
console.log(val) | |||||
} | |||||
} | |||||
) | |||||
</script> | |||||
<template> | |||||
<el-dialog | |||||
:model-value="visible" | |||||
title="初始化引导" | |||||
width="600px" | |||||
destroy-on-close | |||||
@close="emits('close')" | |||||
> | |||||
<div> | |||||
<el-alert | |||||
title="为保证正常申报项目,请完成以下配置工作:" | |||||
:closable="false" | |||||
type="info" | |||||
show-icon | |||||
class="primary-alert" | |||||
/> | |||||
</div> | |||||
<div class="p-16"> | |||||
<el-steps | |||||
direction="vertical" | |||||
:space="100" | |||||
:active="-1" | |||||
> | |||||
<el-step | |||||
v-for="(item, index) in initData.filter(i=>i.name!=='配置财政编码')" | |||||
:key="index" | |||||
:title="item.name" | |||||
:status="item.isFinish?'success':'wait'" | |||||
> | |||||
<template #description> | |||||
<p>{{ item.remark }}</p> | |||||
<el-button link type="primary" @click="view(item.path)">前往配置</el-button> | |||||
</template> | |||||
</el-step> | |||||
</el-steps> | |||||
</div> | |||||
</el-dialog> | |||||
</template> | |||||