Merge pull request 'dj' (#953) from dj into master

Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/953
This commit is contained in:
2025-03-25 06:28:09 +00:00
21 changed files with 332 additions and 165 deletions

View File

@@ -479,6 +479,11 @@ html, body, #app, .el-container, .el-aside, .el-main {
height: 1.4em;
margin-right: 5px;
}
.file-svg{
width: 1.4em;
height: 1.4em;
fill: #BEA266;
}
.middle-icon {
width: 1.4em;
height: 1.4em;

View File

@@ -1,8 +1,24 @@
<template>
<div class="apply-block">
<baseTitle :title="getTitleName(title)+'信息'"></baseTitle>
<el-form :model="localFormData" ref="formRef" label-width="auto" v-if="step!=='50'">
<el-form :model="localFormData" ref="formRef" label-width="auto" v-if="step!=='50'" :rules="rules">
<el-row>
<el-col :span="6" v-if="title==='apply'">
<!-- label-width="106"-->
<el-form-item label="实际经费预算" prop="actualEconomicEstimate" label-width="111" >
<el-input v-model="localFormData.actualEconomicEstimate" placeholder="请输入实际经费预算">
</el-input>
</el-form-item>
</el-col>
<!-- <el-col :span="6" v-if="title==='apply'">-->
<!-- &lt;!&ndash; label-width="106"&ndash;&gt;-->
<!-- <el-form-item label="实际专项资金" prop="budget" label-width="120">-->
<!-- <el-input v-model="localFormData.budget" placeholder="请输入实际专项资金">-->
<!-- </el-input>-->
<!-- </el-form-item>-->
<!-- </el-col>-->
</el-row>
<el-row>
<el-col :span="6" v-if="title==='apply'">
<!-- label-width="106"-->
<el-form-item label="项目负责人" :required="true" prop="" label-width="111">
@@ -17,7 +33,7 @@
</el-form-item>
</el-col>
<el-col :span="6" v-if="title==='apply'">
<el-form-item label="项目成员" :required="true" prop="" label-width="85"
<el-form-item label="项目成员" :required="true" prop="" label-width="120"
>
<el-button color="#DED0B2" style="margin-right: 10px" @click="handleShowProjectPersonTable">
{{ projectPersonUserList?.length !== 0 ? '更改' : getProjectPerson(projectPersonUserList) ? '更改' : '请选择' }}
@@ -91,8 +107,8 @@
</div>
</div>
<div class="oper-page-btn">
<el-button color="#DED0B2" v-if="mode === 'submit'" @click="handleSubmit">提交</el-button>
<el-button color="#DED0B2" v-else-if="mode === 'resubmit'" @click="handleSubmit">重新提交</el-button>
<el-button color="#DED0B2" v-if="mode === 'submit'" @click="handleSubmit(formRef)">提交</el-button>
<el-button color="#DED0B2" v-else-if="mode === 'resubmit'" @click="handleSubmit(formRef)">重新提交</el-button>
<el-button @click="handleBack">返回</el-button>
</div>
@@ -160,6 +176,7 @@ import UserPicker from "@/views/workflow/process/common/UserPicker.vue";
const router = useRouter()
const route = useRoute()
const formRef = ref()
const changeDiagram = ref(false)
const showSingleTable = ref(false)
const projectChargePersonUserList = ref([])
@@ -211,11 +228,11 @@ const pageInfo = reactive({
pageNum: 1,
pageSize: 10,
})
// const rules = reactive({
// preProcess: [{required: true, message: '请选择前置流程', trigger: 'blur'}],
// projectChargePerson: [{required: true, message: '请选择项目负责人', trigger: 'blur'}],
// projectPerson: [{required: true, message: '请选择项目成员', trigger: 'blur'}],
// })
const rules = reactive({
actualEconomicEstimate: [{required: true, message: '请输入实际经费预算', trigger: ['blur','change']}],
// projectChargePerson: [{required: true, message: '请选择项目负责人', trigger: 'blur'}],
// projectPerson: [{required: true, message: '请选择项目成员', trigger: 'blur'}],
})
const tagsViewStore = useTagsView()
const processStore = useProcessStore()
const localProjectPerson = ref([])
@@ -489,106 +506,118 @@ const getFileParam = (item) => {
tag: item.tag
}
}
const handleSubmit = async () => {
let files = []
if (props.mode === 'resubmit') {
attachment.value.allFileList.forEach(item => {
files.push(getFileParam(item))
})
} else {
otherFileList.value.forEach(item => {
files.push(getFileParam(item))
})
}
// console.info("🚀 ~method:handleSubmit -----", files,attachment.value.isHaveOneFile)
if (!attachment.value.isHaveOneFile) {
attachment.value.validate()
const handleSubmit = async (instance) => {
if (!instance) return
instance.validate(async (valid) => {
if (!valid) {
ElNotification({
title: '提示',
message: '请完善数据,再提交!',
type: 'error'
})
return;
}
let files = []
if (props.mode === 'resubmit') {
attachment.value.allFileList.forEach(item => {
files.push(getFileParam(item))
})
} else {
otherFileList.value.forEach(item => {
files.push(getFileParam(item))
})
}
// console.info("🚀 ~method:handleSubmit -----", files,attachment.value.isHaveOneFile)
if (!attachment.value.isHaveOneFile) {
attachment.value.validate()
ElNotification({
title: '提示',
message: '请上传附件',
type: 'error'
})
return;
} else {
attachment.value.clearValidate()
}
let projectPersonIds = []
for (const item of projectPersonUserList.value) {
projectPersonIds.push(parseInt(item.id))
}
let params = {
deploymentId: deploymentId.value,
requirementId: route.query.id,
fileList: files,
// singleFile: attachment.value.singleFile,
projectId: projectId.value,
actualEconomicEstimate: localFormData.value.actualEconomicEstimate,
preProcess: JSON.stringify(localFormData.value.preProcess)
}
if (sessionParams.value.preProcess && !localFormData.value.preProcess) {
params.preProcess = JSON.stringify(sessionParams.value.preProcess)
}
console.log('params',params)
let res
if (props.step === '20') {
if (projectChargePersonUserList.value && projectChargePersonUserList.value.length === 0) {
ElNotification({
title: '提示',
message: '请选择项目负责人!',
type: 'error'
})
return;
}
if (projectPersonUserList.value && projectPersonUserList.value.length === 0) {
ElNotification({
title: '提示',
message: '请选择项目成员!',
type: 'error'
})
return;
}
params.projectChargePerson = parseInt(projectChargePersonUserList.value[0].id)
params.projectPersonIds = projectPersonIds
params.optionalChargeLeadership = optionalChargeLeadershipList.value
if (props.mode === 'resubmit') {
res = await resubmitApply(params)
} else {
res = await projectApply(params)
}
} else if (props.step === '40') {
params.optionalChargeLeadership = optionalChargeLeadershipList.value
if (props.mode === 'resubmit') {
res = await resubmitCheck(params)
} else {
res = await projectCheck(params)
}
} else if (props.step === '50') {
if (props.mode === 'resubmit') {
res = await resubmitConclusion(params)
} else {
res = await projectConclusion(params)
}
}
ElNotification({
title: '提示',
message: '请上传附件',
type: 'error'
message: res.msg,
type: res.code === 1000 ? 'success' : 'error'
})
return;
} else {
attachment.value.clearValidate()
}
let projectPersonIds = []
for (const item of projectPersonUserList.value) {
projectPersonIds.push(parseInt(item.id))
}
let params = {
deploymentId: deploymentId.value,
requirementId: route.query.id,
fileList: files,
// singleFile: attachment.value.singleFile,
projectId: projectId.value,
preProcess: JSON.stringify(localFormData.value.preProcess)
}
if (sessionParams.value.preProcess && !localFormData.value.preProcess) {
params.preProcess = JSON.stringify(sessionParams.value.preProcess)
}
// console.log(params.preProcess)
let res
if (props.step === '20') {
if (projectChargePersonUserList.value && projectChargePersonUserList.value.length === 0) {
ElNotification({
title: '提示',
message: '请选择项目负责人!',
type: 'error'
})
return;
if (res.code === 1000) {
tagsViewStore.delVisitedViews(router.currentRoute.value.path)
if (props.step === '20') {
await router.push({
name: 'Initiation'
})
} else if (props.step === '40') {
await router.push({
name: 'Implementation'
})
} else if (props.step === '50') {
await router.push({
name: 'Filing'
})
}
}
if (projectPersonUserList.value && projectPersonUserList.value.length === 0) {
ElNotification({
title: '提示',
message: '请选择项目成员!',
type: 'error'
})
return;
}
params.projectChargePerson = parseInt(projectChargePersonUserList.value[0].id)
params.projectPersonIds = projectPersonIds
params.optionalChargeLeadership = optionalChargeLeadershipList.value
if (props.mode === 'resubmit') {
res = await resubmitApply(params)
} else {
res = await projectApply(params)
}
} else if (props.step === '40') {
params.optionalChargeLeadership = optionalChargeLeadershipList.value
if (props.mode === 'resubmit') {
res = await resubmitCheck(params)
} else {
res = await projectCheck(params)
}
} else if (props.step === '50') {
if (props.mode === 'resubmit') {
res = await resubmitConclusion(params)
} else {
res = await projectConclusion(params)
}
}
ElNotification({
title: '提示',
message: res.msg,
type: res.code === 1000 ? 'success' : 'error'
})
if (res.code === 1000) {
tagsViewStore.delVisitedViews(router.currentRoute.value.path)
if (props.step === '20') {
await router.push({
name: 'Initiation'
})
} else if (props.step === '40') {
await router.push({
name: 'Implementation'
})
} else if (props.step === '50') {
await router.push({
name: 'Filing'
})
}
}
}
const init = async () => {
let id = projectId.value

View File

@@ -1,27 +1,35 @@
<template>
<el-row style="padding-bottom: 20px">
<el-row >
<el-col :span="24">
<baseTitle :title="'项目附件'"></baseTitle>
</el-col>
<el-form :model="attachmentParam" inline style="margin-left: 15px">
<el-form-item label="标签" prop="tag">
<el-select v-model="attachmentParam.tag" placeholder="请选择标签" clearable filterable style="width: 300px">
<el-option
v-for="item in tagsOption"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item>
<el-button @click="handleSearch" color="#DED0B2">搜索</el-button>
<el-button v-if="uploadState&&isLineBtn" color="#DED0B2" @click="handleUpload">上传附件</el-button>
</el-form-item>
</el-form>
<el-col v-if="!isLineBtn" :span="24" style="margin-bottom: 8px;margin-left: 15px">
<el-button v-if="uploadState" color="#DED0B2" @click="handleUpload">上传附件</el-button>
</el-col>
<el-tabs v-model="activeName" class="demo-tabs" @tab-click="handleTabClick" style="margin-left: 15px;margin-top: -10px">
<el-tab-pane v-for="item in tagsOption"
:key="item.value"
:label="item.label"
:name="item.value">
<div class="tag-title">
<div></div>
{{item.label}}
</div>
</el-tab-pane>
<el-tab-pane name="plus" v-if="uploadState">
<template #label>
<div style="margin-top: 4px;">
<el-icon color="#BEA266">
<Plus/>
</el-icon>
</div>
</template>
</el-tab-pane>
</el-tabs>
</el-row>
<div style="margin-top:10px;margin-bottom: 8px;margin-left: 15px;display: flex">
<!-- <el-button color="#DED0B2" @click="handleUpload">上传附件</el-button>-->
<file-upload v-if="!isLineBtn&&uploadState" @getFile="getFile" />
<!-- <el-button color="#DED0B2" @click="handleEditTag" style="margin-left: 10px;">编辑</el-button>-->
</div>
<fvTable style="width: 100%;min-height:311px;max-height: 311px" v-if="showAttachmentTable" height="311"
:tableConfig="executeTableConfig" class="execute-apply-table"
:data="otherAttachmentList" :isSettingCol="false" :pagination="false">
@@ -29,24 +37,39 @@
<el-empty :image-size="90" description="暂无数据" style="padding: 0"/>
</template>
</fvTable>
</el-row>
<file-preview ref="filePreviewRef" :fullscreen="false" v-if="filePreviewShow" :fileName="filePreviewParam.fileName" :fileUrl="filePreviewParam.fileUrl"
<file-preview ref="filePreviewRef" :fullscreen="false" v-if="filePreviewShow" :fileName="filePreviewParam.fileName"
:fileUrl="filePreviewParam.fileUrl"
:fileType="filePreviewParam.fileType"/>
<el-dialog v-model="tagNameShow" center width="450" top="450px">
标签<el-input v-model="fileParam.tagName" placeholder="请输入标签名称" style="width: 335px;" clearable/>
<div class="oper" style="display: flex;justify-content: flex-end;margin-top: 10px">
<el-button color="#DED0B2" @click="changeTag()">确定</el-button>
<el-button @click="tagNameShow=false">取消</el-button>
</div>
</el-dialog>
</template>
<script setup lang="jsx">
import {getTags} from "@/api/project-manage";
import {ElLoading, ElNotification} from "element-plus";
import {searchImplementationFileList} from "@/api/project-manage/attachment";
import {ElLoading, ElMessageBox, ElNotification} from "element-plus";
import {searchImplementationFileList, uploadFileList} from "@/api/project-manage/attachment";
import {deleteFile} from "@/api/project-demand";
const router = useRouter()
const route = useRoute()
const attachmentParam = reactive({
tag: ''
})
const fileParam = ref({
tagName:''
})
const uploadState = ref(false)
const tagNameShow = ref(false)
const tagsOption = ref([])
const fileList = ref([])
const allFiles = ref([])
const showAttachmentTable = ref(true)
const activeName = ref('测试2')
const props = defineProps({
fileNameTableWidth: {
@@ -95,6 +118,11 @@ const executeTableConfig = reactive({
return (
<div>
<el-button type="primary" link onClick={() => handleDownload(row)}>下载</el-button>
{
row.newFile?
<popover-delete name={row.originalFileName} type={'文件'} btnType={'danger'}
onDelete={() => deleteSingleFile(row)}/> : ''
}
</div>
)
}
@@ -109,14 +137,79 @@ const filePreviewParam = ref({
fileType: 'pdf'
})
const filePreviewShow = ref(false)
const clickToPreview=(row)=>{
const deleteSingleFile = (row) => {
deleteFile(row.fileId).then(res => {
ElNotification({
title: '提示',
message: res.msg,
type: res.code === 1000 ? 'success' : 'error'
})
if (res.code === 1000) {
otherAttachmentList.value.splice(otherAttachmentList.value.findIndex((item) => item.fileId === row.fileId), 1);
}
});
}
const changeTag=()=>{
tagsOption.value.push({
value: fileParam.value.tagName,
label: fileParam.value.tagName
})
tagNameShow.value=false;
fileParam.value.tagName=''
}
const handleTabClick=(item)=>{
console.log('item.props.name',item.props.name)
tagNameShow.value = item.props.name == 'plus';
if(item.props.name!='plus'){
console.log()
otherAttachmentList.value=allFiles.value.filter(item1=>item1.tag==item.props.name)
showAttachmentTable.value = false
nextTick(() => {
showAttachmentTable.value = true
})
}
}
const compositeParam = (item) => {
return {
fileId: item.id,
size: item.size,
originalFileName: item.originalFilename,
fileType: item.fileType,
url: item.url,
newFile: true,
tag: activeName.value,
}
}
const getFile = (val) => {
// console.log('上传文件', val)
let fileObj = compositeParam(val)
fileList.value.push(fileObj)
otherAttachmentList.value.push(fileObj)
handleSubmit(fileList.value)
}
const handleSubmit = async (list) => {
let params = {
fileList: list,
projectId: route.query.projectId,
targetState: "30"
}
let res = await uploadFileList(params)
// ElNotification({
// title: '提示',
// message: res.msg,
// type: res.code === 1000 ? 'success' : 'error'
// })
}
const clickToPreview = (row) => {
filePreviewShow.value = false
filePreviewParam.value = {
fileUrl: row.url,
fileName: row.originalFileName,
fileType: row.fileType
}
nextTick(()=>{
nextTick(() => {
filePreviewShow.value = true
})
}
@@ -137,7 +230,9 @@ const handleSearch = () => {
searchImplementationFileList(params).then(res => {
showAttachmentTable.value = false
if (res.code === 1000) {
otherAttachmentList.value = res.data.fileList
// otherAttachmentList.value = res.data.fileList
otherAttachmentList.value= res.data.fileList.filter(item1=>item1.tag==activeName.value)
allFiles.value = res.data.fileList
uploadState.value = res.data.upload
nextTick(() => {
showAttachmentTable.value = true
@@ -158,6 +253,7 @@ const getTagsOption = () => {
getTags(route.query.projectId).then(res => {
if (res.code === 1000) {
tagsOption.value = res.data
activeName.value=res.data[0].value
} else {
ElNotification({
title: '提示',
@@ -178,11 +274,11 @@ const handleUpload = () => {
}
})
}
handleSearch()
getTagsOption()
onActivated(()=>{
handleSearch()
handleSearch()
onActivated(() => {
getTagsOption()
handleSearch()
})
</script>
<style lang="scss">
@@ -217,8 +313,46 @@ onActivated(()=>{
}
}
</style>
<style scoped>
<style scoped lang="scss">
:deep(.el-dialog__body){
padding: 0!important;
}
.tag-title{
display: flex;
align-items: center;
margin-top: 15px;
>div{
margin-right: 5px;
width: 4px;
height: 20px;
background-color: #BEA266;
}
}
:deep(.el-table--fit ) {
height: 311px !important;
}
:deep(.el-tabs__nav){
//width: 75vw;
}
:deep(.el-tabs__item){
flex: none!important;
}
:deep(.el-tabs__header) {
margin-bottom: 0;
}
:deep(.el-tabs__item.is-active) {
color: #BEA266;
}
:deep(.el-tabs__active-bar) {
background-color: #BEA266;
}
.file-tag {
width: 100%;
display: flex;
border-bottom: 2px solid #f6f6f6;
/*align-items: center;*/
}
</style>

View File

@@ -56,7 +56,6 @@ const props = defineProps({
plugins: {
type: [String, Array],
default:
//
"preview searchreplace autolink directionality visualblocks visualchars fullscreen image axupimgs link media template code codesample table pagebreak nonbreaking anchor insertdatetime advlist lists wordcount autosave",
},
toolbar: {

View File

@@ -279,7 +279,7 @@ const schema = computed(() => {
)
},
{
label: '经费预算(元)',
label: '预估经费预算',
prop: 'economicEstimate',
colProps: {
span: 6
@@ -334,7 +334,7 @@ const schema = computed(() => {
}
},
{
label: '申请总部专项资金(元)',
label: '预估专项资金(元)',
prop: 'specialFundAmount',
colProps: {
span: 6

View File

@@ -204,7 +204,7 @@ const tableConfig = reactive({
},
{
prop: 'economicEstimate',
label: '经费预算(元)',
label: '预估经费预算',
align: 'center',
width: 150,
currentRender:({row})=>{

View File

@@ -130,7 +130,7 @@
<div v-else>--</div>
</template>
</el-table-column>
<el-table-column prop="intellectualProperty" label="经费预算(元)" align="center">
<el-table-column prop="intellectualProperty" label="预估经费预算" align="center">
<template #default="scope">
<span>{{ toThousands(scope.row.economicEstimate) }}</span>
</template>

View File

@@ -157,7 +157,7 @@ const schema = computed(() => {
)
},
{
label: '经费预算(元)',
label: '预估经费预算',
prop: 'economicEstimate',
colProps: {
span: 6
@@ -212,7 +212,7 @@ const schema = computed(() => {
}
},
{
label: '申请总部专项资金(元)',
label: '预估专项资金(元)',
prop: 'specialFundAmount',
colProps: {
span: 6

View File

@@ -275,7 +275,7 @@ const tableConfig = reactive({
},
{
prop: 'economicEstimate',
label: '经费预算(元)',
label: '预估经费预算',
align: 'center',
width: 150,
currentRender:({row})=>{

View File

@@ -168,7 +168,7 @@ const schema = computed(() => {
)
},
{
label: '经费预算(元)',
label: '预估经费预算',
prop: 'economicEstimate',
colProps: {
span: 6
@@ -223,7 +223,7 @@ const schema = computed(() => {
}
},
{
label: '申请总部专项资金(元)',
label: '预估专项资金(元)',
prop: 'specialFundAmount',
colProps: {
span: 6

View File

@@ -163,7 +163,7 @@ const schema = computed(() => {
)
},
{
label: '经费预算(元)',
label: '预估经费预算',
prop: 'economicEstimate',
colProps: {
span: 6
@@ -218,7 +218,7 @@ const schema = computed(() => {
}
},
{
label: '申请总部专项资金(元)',
label: '预估专项资金(元)',
prop: 'specialFundAmount',
colProps: {
span: 6

View File

@@ -177,7 +177,7 @@ const schema = computed(() => {
)
},
{
label: '经费预算(元)',
label: '预估经费预算',
prop: 'economicEstimate',
colProps: {
span: 6
@@ -232,7 +232,7 @@ const schema = computed(() => {
}
},
{
label: '申请总部专项资金(元)',
label: '预估专项资金(元)',
prop: 'specialFundAmount',
colProps: {
span: 6

View File

@@ -292,7 +292,7 @@ const tableConfig = reactive({
},
{
prop: 'economicEstimate',
label: '经费预算(元)',
label: '预估经费预算',
align: 'center',
width: 150,
currentRender:({row})=>{

View File

@@ -230,7 +230,7 @@ const schema = computed(() => {
)
},
{
label: '经费预算(元)',
label: '预估经费预算',
prop: 'economicEstimate',
colProps: {
span: 6
@@ -285,7 +285,7 @@ const schema = computed(() => {
}
},
{
label: '申请总部专项资金(元)',
label: '预估专项资金(元)',
prop: 'specialFundAmount',
colProps: {
span: 6

View File

@@ -170,7 +170,7 @@ const schema = computed(() => {
)
},
{
label: '经费预算(元)',
label: '预估经费预算',
prop: 'economicEstimate',
colProps: {
span: 6
@@ -225,7 +225,7 @@ const schema = computed(() => {
}
},
{
label: '申请总部专项资金(元)',
label: '预估专项资金(元)',
prop: 'specialFundAmount',
colProps: {
span: 6

View File

@@ -145,7 +145,7 @@ const schema = computed(() => {
)
},
{
label: '经费预算(元)',
label: '预估经费预算',
prop: 'economicEstimate',
colProps: {
span: 6
@@ -200,7 +200,7 @@ const schema = computed(() => {
}
},
{
label: '申请总部专项资金(元)',
label: '预估专项资金(元)',
prop: 'specialFundAmount',
colProps: {
span: 6

View File

@@ -182,7 +182,7 @@ const schema = computed(() => {
)
},
{
label: '经费预算(元)',
label: '预估经费预算',
prop: 'economicEstimate',
colProps: {
span: 6
@@ -237,7 +237,7 @@ const schema = computed(() => {
}
},
{
label: '申请总部专项资金(元)',
label: '预估专项资金(元)',
prop: 'specialFundAmount',
colProps: {
span: 6

View File

@@ -253,7 +253,7 @@ const schema = computed(() => {
)
},
{
label: '经费预算(元)',
label: '预估经费预算',
prop: 'economicEstimate',
colProps: {
span: 6
@@ -315,7 +315,7 @@ const schema = computed(() => {
}
},
{
label: '申请总部专项资金(元)',
label: '预估专项资金(元)',
prop: 'specialFundAmount',
colProps: {
span: 6

View File

@@ -274,7 +274,7 @@ const tableConfig = reactive({
},
{
prop: 'economicEstimate',
label: '经费预算(元)',
label: '预估经费预算',
align: 'center',
width: 150,
currentRender:({row})=>{

View File

@@ -259,7 +259,7 @@ const schema = computed(() => {
)
},
{
label: '经费预算(元)',
label: '预估经费预算',
prop: 'economicEstimate',
colProps: {
span: 24
@@ -321,7 +321,7 @@ const schema = computed(() => {
}
},
{
label: '申请总部专项资金(元)',
label: '预估专项资金(元)',
prop: 'specialFundAmount',
colProps: {
span: 24

View File

@@ -167,7 +167,7 @@ const schema = computed(() => {
)
},
{
label: '经费预算(元)',
label: '预估经费预算',
prop: 'economicEstimate',
colProps: {
span: 24
@@ -222,7 +222,7 @@ const schema = computed(() => {
}
},
{
label: '申请总部专项资金(元)',
label: '预估专项资金(元)',
prop: 'specialFundAmount',
colProps: {
span: 24