Files
mosr-web/src/views/project-demand/requirement/add.vue
2024-10-11 14:02:36 +08:00

642 lines
19 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div v-loading="loading" class="add-block">
<baseTitle title="需求征集信息录入"></baseTitle>
<el-form :model="formData" ref="demandForm" :rules="rules" label-width="140px" :scroll-to-error="true"
:style="{marginLeft: !formData.isSpecialFund?'-55px':'-30px'}">
<el-row gutter="30">
<el-col :span="6">
<el-form-item label="征集名称" prop="requirementName">
<el-input v-model="formData.requirementName" placeholder="请输入征集名称" clearable></el-input>
</el-form-item>
</el-col>
<el-col :span="6" style="margin-left: -40px">
<el-form-item label="征集类型" prop="collectType">
<el-select v-model="formData.collectType" placeholder="请选择征集类型" clearable filterable>
<el-option
v-for="item in cacheStore.getDict('collect_type')"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="6" style="margin-left: 10px">
<el-form-item label="需求上报截止时间" prop="deadline">
<el-config-provider>
<el-date-picker
style="width: 100%"
v-model="formData.deadline"
type="date"
placeholder="请选择需求上报截止时间"
value-format="YYYY-MM-DD"
:disabled-date="disabledDate"
/>
</el-config-provider>
</el-form-item>
</el-col>
<el-col :span="6" style="margin-left: -20px">
<el-form-item label="是否专项资金" prop="isSpecialFund">
<el-select v-model="formData.isSpecialFund" placeholder="请选择是否专项资金" clearable filterable>
<el-option :value="true" label="是"></el-option>
<el-option :value="false" label="否"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="专项资金名称" prop="specialFundId" v-if="formData.isSpecialFund">
<el-select v-model="formData.specialFundId" placeholder="请选择专项资金名称" clearable filterable>
<el-option
v-for="item in specialFundOption"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="6" v-if="formData.isSpecialFund">
<!-- <el-form-item>-->
<a @click="addSpecialFund" style="width: 116px;text-align: right;display: inline-block">新增专项资金</a>
<!-- </el-form-item>-->
</el-col>
<el-col :span="24">
<el-form-item label="征集公司" :required="true" prop="" class="company-select">
<div style="width: 100%">
<el-button color="#DED0B2" @click="showCompany">{{ selectedCompanyList.length === 0 ? '请选择征集公司' : '更改' }}
</el-button>
</div>
<div :class="showExpendClass(showMoreCompany)">{{ getName(selectedCompanyList) }}</div>
<div style="color: #2a99ff;text-align: center;width: 100%;font-size: 15px;cursor: pointer"
@click="handleExpend">
{{ showExpendText }}
</div>
</el-form-item>
</el-col>
<el-col :span="24" style="margin-bottom: -18px">
<el-form-item label="征集说明" prop="" required>
<el-input
v-model="formData.collectExplain"
style="width:100%;margin-right: 50px"
:rows="5"
type="textarea"
placeholder="请输入征集说明"
/>
</el-form-item>
</el-col>
</el-row>
</el-form>
<baseTitle title="附件文件" style="margin-right: 10px"></baseTitle>
<file-upload v-if="checkFormPrem('fileList')" @getFile="getFile"/>
<div style="margin-right: 50px">
<fvTable style="width: 100%;max-height: 160px;" height="160" v-if="showTable"
:tableConfig="tableConfig" :data="formData.fileList"
:isSettingCol="false" :pagination="false" perm="EDIT">
<template #empty>
<el-empty :image-size="55" description="暂无数据" style="padding: 0"/>
</template>
</fvTable>
</div>
<div class="approval-record">
<div class="approval-title">
<baseTitle title="审批记录"></baseTitle>
<div class="diagram">
<div class="base-title">流程图</div>
<el-switch
v-model="changeDiagram"
style="--el-switch-on-color:#BEA266; --el-switch-off-color:#cecdcd;"
/>
</div>
</div>
<el-empty :image-size="100" description="暂无审批记录"
v-if="processDiagramViewer&& !opentionData?.operationList&&!changeDiagram"/>
<!-- <process-diagram-viewer mode="view" v-if="processDiagramViewer&&changeDiagram"/>-->
<div class="process">
<operation-render
v-if="processDiagramViewer&& opentionData?.operationList && opentionData?.operationList.length > 0&&!changeDiagram"
:operation-list="opentionData?.operationList"
:state="opentionData.state"/>
<process-diagram-viewer mode="view" v-if="processDiagramViewer&&changeDiagram"/>
</div>
</div>
<div style="width: 100%;height: 30px"></div>
<div class="oper-page-btn">
<el-button color="#DED0B2" v-if="routerName==='Requirement/add'" @click="handleSubmit(demandForm)">提交</el-button>
<el-button color="#DED0B2" v-else @click="handleResubmit(demandForm)">重新提交</el-button>
<el-button @click="handleBack">返回</el-button>
</div>
<company-picker :multiple="true" ref="companyRef" title="请选择征集公司" @ok="sureSelectedCompany" @cancelOrClear="cancelSelectedCompany"
v-model:value="selectedCompanyList"/>
<file-preview ref="filePreviewRef" v-if="filePreviewShow" :fileName="filePreviewParam.fileName"
:fileUrl="filePreviewParam.fileUrl"
:fileType="filePreviewParam.fileType"/>
</div>
</template>
<script setup lang="jsx">
import {useAuthStore} from '@/stores/userstore.js'
import {useProcessStore} from '@/stores/processStore.js';
import {
getWorkflowInfo,
addRequirement,
getInfo,
resubmit,
deleteFile,
downloadFile
} from "@/api/project-demand/index.js";
import FileUpload from "@/components/FileUpload.vue";
import OperationRender from '@/views/workflow/common/OperationRender.vue'
import ProcessDiagramViewer from '@/views/workflow/common/ProcessDiagramViewer.vue';
import {ElNotification} from "element-plus";
import {getSubCompOpt} from '@/api/user/user.js'
import {useTagsView} from '@/stores/tagsview.js'
import {getFundOption} from "@/api/special-fund";
import CompanyPicker from "@/components/DetailComponent/CompanyPicker.vue";
import {useCacheStore} from '@/stores/cache.js'
const filePreviewParam = ref({
fileUrl: '',
fileName: '',
fileType: 'pdf'
})
const filePreviewShow = ref(false)
const cacheStore = useCacheStore()
const companyRef = ref()
const opentionData = ref({})
const showExpendText = ref('')
const showMoreCompany = ref(false)
const selectedCompanyList = ref([])
// const companyList = ref([])
const changeDiagram = ref(false)
const tagsViewStore = useTagsView()
const authStore = useAuthStore()
const router = useRouter()
const route = useRoute()
const demandForm = ref()
const dateValue = ref()
const formData = ref({
requirementName: '',
companyIds: [],
collectType: '科技创新与信息化系统建设',
deadline: '',
collectExplain: '',
fileList: [],
isSpecialFund: false
})
const routerName = ref(router.currentRoute.value.name)
const processDiagramViewer = ref(false)
const companyOption = ref([])
const specialFundOption = ref([])
const form = ref(null)
const fileList = ref([])
const loading = ref(false)
const showTable = ref(true)
const processStore = useProcessStore()
const processInstanceData = ref()
const formPermMap = ref(new Map());
const companyNameArray = ref([])
const rules = reactive({
requirementName: [{required: true, message: '请输入征集名称', trigger: ['blur', 'change']}],
isSpecialFund: [{required: true, message: '请选择是否专项资金', trigger: ['blur', 'change']}],
collectType: [{required: true, message: '请选择征集类型', trigger: ['blur', 'change']}],
deadline: [{required: true, message: '请选择需求上报截止时间', trigger: ['blur', 'change']}],
specialFundId: [{required: true, message: '请选择专项资金名称', trigger: ['blur', 'change']}],
})
const tableConfig = reactive({
columns: [
{
prop: 'index',
type: 'index',
label: '序号',
align: 'center',
width: '80',
},
{
prop: 'originalFileName',
label: '文件名',
align: 'center',
showOverflowTooltip: false,
currentRender: ({row, index}) => (
<div style="color: #2a99ff;cursor: pointer;" onClick={() => clickToPreview(row)}>{row.originalFileName}</div>)
},
{
prop: 'tag',
label: '标签',
align: 'center'
},
{
prop: 'size',
label: '文件大小',
align: 'center',
currentRender: ({row, index}) => (parseInt(row.size / 1024) + 'KB')
},
{
prop: 'oper',
label: '操作',
align: 'center',
showOverflowTooltip: false,
currentRender: ({row, index}) => {
return (
<div>
<el-button type="primary" link onClick={() => handleDownload(row)}>下载</el-button>
<popover-delete name={row.originalFileName} type={'文件'} btnType={'danger'}
onDelete={() => handleDelete(row)}/>
</div>
)
}
}
]
})
localStorage.removeItem('originallyCompanySelectedList')
const addSpecialFund=()=>{
router.push({
name: 'Fund/add',
query: {}
})
}
const clickToPreview = (row) => {
filePreviewShow.value = false
filePreviewParam.value = {
fileUrl: row.url,
fileName: row.originalFileName,
fileType: row.fileType
}
nextTick(() => {
filePreviewShow.value = true
})
// filePreviewRef.value.show()
}
const disabledDate = (time) => {
return time.getTime() < Date.now() - 8.64e7//不能选择之后的数据
}
const handleExpend = () => {
showMoreCompany.value = !showMoreCompany.value;
showExpendClass(showMoreCompany.value)
}
const showExpendClass = (showMoreCompany) => {
if (!showMoreCompany) {
if (selectedCompanyList.value.length === 0) {
showExpendText.value = ''
return ''
} else if (selectedCompanyList.value.length > 14) {
showExpendText.value = '展开'
return 'company-style'
}
} else {
showExpendText.value = '收缩'
return ''
}
}
const getName = (list) => {
return list.map(item => item.label).join('')
}
const showCompany = () => {
companyRef.value.show()
}
const cancelSelectedCompany=(select)=>{
console.info("🚀 ~ file:add method:cancelSelectedCompany line:287 -----", select)
formData.value.companyIds = []
if(select.length>0){
for (let val of select) {
formData.value.companyIds.push(val.value)
}
}
selectedCompanyList.value = select
}
const sureSelectedCompany = (select) => {
formData.value.companyIds = []
for (let val of select) {
formData.value.companyIds.push(val.value)
}
selectedCompanyList.value = select
}
const checkFormPrem = (formKey) => {
if (formPermMap.value.hasOwnProperty(formKey)) {
let formItem = formPermMap.value[formKey];
return formItem.perm === 'EDIT'
} else {
return true;
}
}
const handleDownload = (row) => {
downloadFile(row.fileId).then(res => {
const blob = new Blob([res])
let a = document.createElement('a')
a.href = URL.createObjectURL(blob)
a.download = row.originalFileName
a.click()
})
}
const getSpecialFundName = (val) => {
let label
specialFundOption.value.forEach(item => {
if (item.value == val) {
label = item.label
}
})
return label
}
const compositeParam = (item) => {
let tag = ''
if (!formData.value.collectType && routerName.value === 'Requirement/add') {
tag = '需求征集'
} else if (!formData.value.collectType && routerName.value === 'Requirement/edit') {
tag = '需求征集'
}
if (formData.value.collectType) {
tag = formData.value.collectType
}
return {
fileId: item.id,
size: item.size,
originalFileName: item.originalFilename,
fileType: item.fileType,
url: item.url,
processNodeTag: null,
tag: tag,
newFile: true,
userId: authStore.userinfo.userId
}
}
const getFile = (val) => {
showTable.value = false
let fileObj = compositeParam(val)
formData.value.fileList.push(fileObj)
nextTick(() => {
showTable.value = true
})
}
const init = async () => {
const res = await getSubCompOpt()
companyOption.value = res.data
const resFund = await getFundOption()
specialFundOption.value = resFund.data
getWorkflowInfo().then(res => {
if (res.code === 1000) {
let data = res.data
processInstanceData.value = data
processStore.setDesign(data)
processStore.runningList.value = data.runningList;
processStore.endList.value = data.endList;
processStore.noTakeList.value = data.noTakeList;
processStore.refuseList.value = data.refuseList;
processStore.passList.value = data.passList;
formPermMap.value = data.formPermMap
// const entriesArray = Object.entries(data.formPermMap);// 使用Map构造函数将键值对数组转换为Map对象
// formPermMap.value = new Map(entriesArray);
nextTick(() => {
processDiagramViewer.value = true
})
} else {
ElNotification({
title: '提示',
message: res.msg,
type: 'error'
})
}
})
}
const submitParam = (item) => {
let files = []
item.fileList.forEach(item => {
let obj = {
fileId: item.fileId,
tag: item.tag
}
files.push(obj)
})
return {
collectExplain: item.collectExplain,
collectType: item.collectType,
companyIds: item.companyIds,
deadline: item.deadline,
requirementId: item.requirementId ? item.requirementId : 0,
requirementName: item.requirementName,
fileList: files,
deploymentId: processInstanceData.value.deploymentId,
isSpecialFund: item.isSpecialFund,
specialFundId: item.specialFundId,
specialFund: getSpecialFundName(item.specialFundId)
}
}
const handleSubmit = async (instance) => {
if (!instance) return
instance.validate(async (valid) => {
if (!valid) {
ElNotification({
title: '提示',
message: '请完善数据,再提交!',
type: 'error'
})
return;
}
if (formData.value.companyIds.length === 0) {
ElNotification({
title: '提示',
message: '请选择征集公司',
type: 'error'
})
return;
}
const {msg, code} = await addRequirement(submitParam(formData.value))
ElNotification({
title: '提示',
message: msg,
type: code === 1000 ? 'success' : 'error'
})
if (code === 1000) {
tagsViewStore.delVisitedViews(router.currentRoute.value.path)
await router.push({
name: 'Requirement'
})
}
})
}
const handleResubmit = (instance) => {
if (!instance) return
instance.validate(async (valid) => {
if (!valid) {
ElNotification({
title: '提示',
message: '请完善数据,再提交!',
type: 'error'
})
return;
}
if (formData.value.companyIds.length === 0) {
ElNotification({
title: '提示',
message: '请选择征集公司',
type: 'error'
})
return;
}
resubmit(submitParam(formData.value)).then(res => {
ElNotification({
title: '提示',
message: res.msg,
type: res.code === 1000 ? 'success' : 'error'
})
if (res.code === 1000) {
tagsViewStore.delVisitedViews(router.currentRoute.value.path)
router.push({
name: 'Requirement'
})
}
})
})
}
const matterTree = (array, data, id) => {
if (id) {
data.forEach(item => {
if (item.value == id) {
let obj = {
label: item.label,
value: item.value
}
array.push(obj);
}
if (item.children && item.children.length > 0) {
matterTree(array, item.children, id)
}
})
return array;
}
}
const getCompanyOptionItem = (val) => {
if (val !== undefined) {
val.forEach(item => {
matterTree(companyNameArray.value, companyOption.value, item)
})
}
return companyNameArray.value;
}
const getDetailInfo = async () => {
getInfo(route.query.id).then(res => {
if (res.code === 1000) {
if (res.data.formData.companyIds[0] == -1) {
selectedCompanyList.value = [
{
value: -1,
label: '所有公司'
}
]
} else {
selectedCompanyList.value = getCompanyOptionItem(res.data.formData.companyIds)
}
formData.value = res.data.formData
opentionData.value = res.data
if (res.data.formData.fileList.length !== 0) {
showTable.value = false
nextTick(() => {
showTable.value = true
})
}
} else {
ElNotification({
title: '提示',
message: res.msg,
type: 'error'
})
}
})
}
const handleBack = () => {
history.back()
}
const handleDelete = (row) => {
deleteFile(row.fileId).then(res => {
ElNotification({
title: '提示',
message: res.msg,
type: res.code === 1000 ? 'success' : 'error'
})
if (res.code === 1000) {
formData.value.fileList.splice(formData.value.fileList.findIndex((item) => item.fileId === row.fileId), 1);
// showTable.value = formData.value.fileList.length !== 0;
}
});
}
onMounted(async () => {
loading.value = true
await init()
if (route.query.id) {
await getDetailInfo()
}
loading.value = false
})
</script>
<style lang="scss" scoped>
:deep(.el-empty__description) {
margin-top: 0;
}
.company-select {
:deep(.el-form-item__content .el-select__wrapper ) {
width: 750px;
}
.company-style {
//width: 98%;
min-height: 30px;
max-height: 60px;
overflow: hidden;
text-overflow: ellipsis;
-webkit-line-clamp: 2;
display: -webkit-box;
-webkit-box-orient: vertical;
}
.company {
color: #fff;
height: auto;
}
}
:deep(.el-table--fit ) {
height: 300px !important;
}
.add-block {
//display: flex;
//justify-content: space-between;
overflow-x: hidden;
overflow-y: auto;
padding: 0 0 0 30px;
a {
cursor: pointer;
font-size: 14px;
color: #2a99ff;
}
.approval-record {
position: relative;
}
}
:deep(.el-table__header) {
.is-leaf:first-child {
.cell {
margin-left: -20px !important;
}
}
}
:deep(.el-table__body) {
.el-table__cell:first-child {
.cell {
margin-left: -10px !important;
}
}
}
</style>