486 lines
15 KiB
Vue
486 lines
15 KiB
Vue
<template>
|
|
<div class="committee-review-page">
|
|
<div class="layout-padding-auto layout-padding-view">
|
|
<el-row class="mb10">
|
|
<div class="form-header-actions">
|
|
<div class="action-left">
|
|
<el-button type="primary" icon="Check" @click="handleInitiate" :loading="submitLoading">
|
|
{{ t('committeeReview.actions.initiate') }}
|
|
</el-button>
|
|
<el-button icon="Document" @click="handleSaveDraft" :loading="saveDraftLoading">
|
|
{{ t('committeeReview.actions.saveDraft') }}
|
|
</el-button>
|
|
<el-button icon="Operation" @click="handleTransferTemplate">
|
|
调用模板
|
|
</el-button>
|
|
<el-button icon="FolderAdd" @click="handleSaveTemplate" :loading="saveTemplateLoading">
|
|
{{ t('committeeReview.actions.saveTemplate') }}
|
|
</el-button>
|
|
</div>
|
|
<div class="action-right">
|
|
<el-button icon="View" @click="handleViewWorkflow">
|
|
{{ t('committeeReview.actions.viewWorkflow') }}
|
|
</el-button>
|
|
</div>
|
|
</div>
|
|
</el-row>
|
|
|
|
<el-card class="header-card" shadow="never">
|
|
<el-form :model="headerForm" label-width="70px" class="header-form" :rules="headerRequiredRule" ref="headerFormRef">
|
|
<el-form-item :label="t('committeeReview.header.title')" prop="title">
|
|
<el-input v-model="headerForm.title" :placeholder="t('committeeReview.header.titlePlaceholder')" />
|
|
</el-form-item>
|
|
<el-form-item :label="t('committeeReview.header.description')">
|
|
<el-input v-model="headerForm.description" :placeholder="t('committeeReview.header.descriptionPlaceholder')" />
|
|
</el-form-item>
|
|
<el-form-item :label="t('committeeReview.header.attachments')">
|
|
<UploadFile :modelValue="headerForm.attachments" @change="(_: any,data: any[])=>uploadChange(1,_,data)" :fileSize="20" type="simple" :limit="10" />
|
|
</el-form-item>
|
|
</el-form>
|
|
</el-card>
|
|
|
|
<el-card class="form-card" shadow="never">
|
|
<div class="form-title">
|
|
<div class="form-title-text">{{ isUpdate ? t('committeeReview.form.updateTitle') : t('committeeReview.form.title') }}</div>
|
|
<div class="form-title-sub">
|
|
<span class="subtitle-left">{{ t('committeeReview.form.departmentPrefix') }}{{ headerForm.department }}</span>
|
|
<span class="subtitle-right">{{ t('committeeReview.form.datePrefix') }}{{ headerForm.date }}</span>
|
|
</div>
|
|
</div>
|
|
|
|
<el-form :model="formData" ref="formDataRef" label-width="0px" class="review-form">
|
|
<el-row class="form-row">
|
|
<el-col :span="4" class="form-label-col">
|
|
<div class="table-label">{{ t('committeeReview.form.departmentPrefix') }}</div>
|
|
</el-col>
|
|
<el-col :span="20">
|
|
<el-form-item>
|
|
<el-input v-model="formData.applicationDept" :placeholder="t('committeeReview.form.inputPlaceholder')" />
|
|
</el-form-item>
|
|
</el-col>
|
|
</el-row>
|
|
<el-row class="form-row">
|
|
<el-col :span="4" class="form-label-col">
|
|
<div class="table-label">{{ t('committeeReview.form.submitItems') }}</div>
|
|
</el-col>
|
|
<el-col :span="20">
|
|
<el-form-item>
|
|
<el-input v-model="formData.reviewNotes" :placeholder="t('committeeReview.form.inputPlaceholder')" />
|
|
</el-form-item>
|
|
</el-col>
|
|
</el-row>
|
|
|
|
<el-row class="form-row">
|
|
<el-col :span="4" class="form-label-col">
|
|
<div class="table-label">{{ t('committeeReview.form.projectName') }}</div>
|
|
</el-col>
|
|
<el-col :span="20">
|
|
<el-form-item>
|
|
<el-input v-model="formData.projectName" :placeholder="t('committeeReview.form.inputPlaceholder')">
|
|
<!-- <template #append>-->
|
|
<!-- <el-icon class="cursor-pointer interactive-icon" @click="handleSelect">-->
|
|
<!-- <FolderOpened />-->
|
|
<!-- </el-icon>-->
|
|
<!-- </template>-->
|
|
</el-input>
|
|
</el-form-item>
|
|
</el-col>
|
|
</el-row>
|
|
|
|
<el-row class="form-row">
|
|
<el-col :span="4" class="form-label-col">
|
|
<div class="table-label">{{ t('committeeReview.form.materials') }}</div>
|
|
</el-col>
|
|
<el-col :span="20">
|
|
<el-form-item>
|
|
<UploadFile :modelValue="formData.attachmentList" @change="(_:any,data: any[])=>uploadChange(2,_,data)" :fileSize="30" type="simple" :limit="10" />
|
|
</el-form-item>
|
|
</el-col>
|
|
</el-row>
|
|
|
|
<el-row class="form-row">
|
|
<el-col :span="4" class="form-label-col">
|
|
<div class="table-label">{{ t('committeeReview.form.applyOpinion') }}</div>
|
|
</el-col>
|
|
<el-col :span="20">
|
|
<el-form-item>
|
|
<el-input
|
|
v-model="formData.applicationDeptOpinion"
|
|
type="textarea"
|
|
:rows="2"
|
|
:placeholder="t('committeeReview.form.inputPlaceholder')"
|
|
/>
|
|
</el-form-item>
|
|
</el-col>
|
|
</el-row>
|
|
|
|
<el-row class="form-row">
|
|
<el-col :span="4" class="form-label-col">
|
|
<div class="table-label">{{ t('committeeReview.form.investmentOpinion') }}</div>
|
|
</el-col>
|
|
<el-col :span="20">
|
|
<el-form-item>
|
|
<el-input
|
|
v-model="formData.investmentDeptOpinion"
|
|
type="textarea"
|
|
:rows="2"
|
|
:placeholder="t('committeeReview.form.inputPlaceholder')"
|
|
/>
|
|
</el-form-item>
|
|
</el-col>
|
|
</el-row>
|
|
|
|
<el-row class="form-row">
|
|
<el-col :span="4" class="form-label-col">
|
|
<div class="table-label">{{ t('committeeReview.form.relatedOpinion') }}</div>
|
|
</el-col>
|
|
<el-col :span="20">
|
|
<el-form-item>
|
|
<el-input
|
|
v-model="formData.cooperationDeptOpinion"
|
|
type="textarea"
|
|
:rows="2"
|
|
:placeholder="t('committeeReview.form.inputPlaceholder')"
|
|
/>
|
|
</el-form-item>
|
|
</el-col>
|
|
</el-row>
|
|
|
|
<el-row class="form-row">
|
|
<el-col :span="4" class="form-label-col">
|
|
<div class="table-label">{{ t('committeeReview.form.groupLeaderOpinion') }}</div>
|
|
</el-col>
|
|
<el-col :span="20">
|
|
<el-form-item>
|
|
<el-input
|
|
v-model="formData.groupLeaderOpinion"
|
|
type="textarea"
|
|
:rows="2"
|
|
:placeholder="t('committeeReview.form.inputPlaceholder')"
|
|
/>
|
|
</el-form-item>
|
|
</el-col>
|
|
</el-row>
|
|
<div class="flex items-center justify-center footer-input">
|
|
<span>第</span>
|
|
<el-input class="w-20 mx-2" v-model="formData.xxx" :placeholder="t('committeeReview.form.inputPlaceholder')" />
|
|
<span>次专委会</span>
|
|
</div>
|
|
</el-form>
|
|
</el-card>
|
|
</div>
|
|
|
|
<!-- 使用新创建的ProjectSelect组件 -->
|
|
<ProjectSelect
|
|
v-model="projectSelectVisible"
|
|
:is-update="isUpdate"
|
|
@select="handleProjectSelect"
|
|
/>
|
|
|
|
<!-- <LibrarySelect-->
|
|
<!-- v-model="librarySelectVisible"-->
|
|
<!-- @select="handleLibrarySelect"-->
|
|
<!-- />-->
|
|
<templet-table-comom/>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import templetTableComom from '/@/components/templetTableComom/index.vue'
|
|
import {computed, reactive, ref} from 'vue';
|
|
import { useI18n } from 'vue-i18n';
|
|
|
|
// 第三方组件与工具
|
|
import { FolderOpened } from '@element-plus/icons-vue';
|
|
import { useMessage } from '/@/hooks/message';
|
|
import { flowFn } from "/@/utils/flowFn";
|
|
|
|
// 本地组件
|
|
import UploadFile from '/@/components/Upload/index.vue';
|
|
import ProjectSelect from './components/ProjectSelect.vue';
|
|
|
|
// API 服务
|
|
import { investmentProjectsPlanPage } from '/@/api/investment/investmentManagement';
|
|
import { addCommitteeApplication,getByTemplateId } from '/@/api/investment/committeeApplication';
|
|
import { addFlowForm } from "/@/api/flow/flow";
|
|
|
|
// 枚举与常量
|
|
import {
|
|
flowNameOptions
|
|
} from '/@/hooks/enums';
|
|
|
|
// 类型定义
|
|
import { ProjectExitFeedback } from '/@/views/invMid/committeeReview/interface/type';
|
|
import { investmentProjectsPlanList } from '/@/views/invMid/projectLibrary/interface/types';
|
|
import { ProjectPlanApplyFormItem } from '/@/components/investment/interface/types';
|
|
import LibrarySelect from './components/LibrarySelect.vue';
|
|
import type {FormInstance, FormRules} from "element-plus";
|
|
import {addTemplate} from "/@/api/common";
|
|
// Store
|
|
import {templateStore} from "/@/stores/template";
|
|
import {useUserInfo} from "/@/stores/userInfo";
|
|
const temp = templateStore();
|
|
const props = defineProps({ isUpdate: { type: Boolean, default: false } })
|
|
const submitLoading = ref<boolean>(false);
|
|
const { t } = useI18n();
|
|
const message = useMessage();
|
|
const projectSelectVisible = ref<boolean>(false);
|
|
const librarySelectVisible = ref<boolean>(false)
|
|
const queryForm = ref<investmentProjectsPlanList>({
|
|
page: 1,
|
|
size: 10,
|
|
projectName: '',
|
|
});
|
|
const tableData = ref<ProjectPlanApplyFormItem[]>([]);
|
|
const total = ref<number>(0);
|
|
const handleSelect = () => {
|
|
if (props.isUpdate) {
|
|
librarySelectVisible.value = true;
|
|
} else {
|
|
projectSelectVisible.value = true;
|
|
}
|
|
}
|
|
const headerForm = reactive<{ title: string; description: string; attachments: any[]|string; department: string; date: string}>({
|
|
title: '',
|
|
description: '',
|
|
attachments: [] as any[],
|
|
department: useUserInfo().userInfos.user.deptName || '',
|
|
date: new Date().toLocaleString('zh-CN',{ year: 'numeric', month: '2-digit', day: '2-digit'}),
|
|
});
|
|
const headerRequiredRule = ref<FormRules>({
|
|
title: [{ required: true, message: t('该字段必传'), trigger: 'blur' }],
|
|
});
|
|
const headerFormRef = ref<FormInstance>();
|
|
const formData = ref<ProjectExitFeedback>({
|
|
reviewNotes: '',
|
|
projectName: '',
|
|
attachmentList: '',
|
|
// 将接口中定义的字段名映射到实际使用的字段名
|
|
applicationDeptOpinion: '',
|
|
investmentDeptOpinion: '',
|
|
cooperationDeptOpinion: '',
|
|
groupLeaderOpinion: '',
|
|
deptId: useUserInfo().userInfos.user.deptId,
|
|
});
|
|
|
|
const getListOfProjects = async () => {
|
|
try {
|
|
const res = await investmentProjectsPlanPage(queryForm.value);
|
|
total.value = res.data.total as number;
|
|
tableData.value = res.data.records;
|
|
} catch (error: any) {
|
|
console.log(error);
|
|
}
|
|
};
|
|
getListOfProjects()
|
|
const handleInitiate = async () => {
|
|
const valid = await headerFormRef.value?.validate();
|
|
if (!valid) return;
|
|
submitLoading.value = true;
|
|
const attachments = JSON.stringify(headerForm.attachments);
|
|
const flowIdKey = props.isUpdate ? 'VITE_FLOWID_39':'VITE_FLOWID_37'
|
|
const {processInstanceId} = await flowFn(flowIdKey,{
|
|
paramMap:{
|
|
// miu0ilc1tfa61_assignee_select: [
|
|
// {
|
|
// "type": "user",
|
|
// "id": "1",
|
|
// "name": "admin",
|
|
// "avatar": "/admin/sys-file/local/2a14ae08150e483c93e12ac8934173e2.png"
|
|
// }
|
|
// ]
|
|
}
|
|
})
|
|
const flowName = props.isUpdate ? 'theSpecialCommitteeReviewAndUpdate':'theSpecialCommitteeReviewsAndRegisters';
|
|
const flowNameObj = flowNameOptions.filter(item => item.label === flowName)[0]
|
|
await addFlowForm({
|
|
title: headerForm.title,
|
|
description: headerForm.description,
|
|
attachments,
|
|
processInstanceId,
|
|
flowType: flowNameObj.value
|
|
})
|
|
formData.value.processInstanceId = processInstanceId;
|
|
const attachmentList = JSON.stringify(formData.value.attachmentList);
|
|
addCommitteeApplication({ ...formData.value, attachmentList }).then(() => {
|
|
projectSelectVisible.value = false;
|
|
message.success(t('common.success'));
|
|
}).catch((err) => {
|
|
message.error(err.msg)
|
|
}).finally(() => {
|
|
submitLoading.value = false;
|
|
});
|
|
|
|
};
|
|
// 保存代发
|
|
const saveDraftLoading = ref<boolean>(false)
|
|
const handleSaveDraft = async () => {
|
|
const valid = await headerFormRef.value?.validate();
|
|
if (!valid) return;
|
|
saveDraftLoading.value = true;
|
|
const attachments = JSON.stringify(headerForm.attachments);
|
|
const flowName = props.isUpdate ? 'theSpecialCommitteeReviewAndUpdate':'theSpecialCommitteeReviewsAndRegisters';
|
|
const flowNameObj = flowNameOptions.filter(item => item.label === flowName)[0];
|
|
await addFlowForm({
|
|
title: headerForm.title,
|
|
description: headerForm.description,
|
|
attachments,
|
|
processInstanceId:'',
|
|
flowType: flowNameObj.value
|
|
})
|
|
const attachmentList = JSON.stringify(formData.value.attachmentList);
|
|
addCommitteeApplication({ ...formData.value, attachmentList,status:0,temporaryStorage:{
|
|
businessType:flowNameObj.value,
|
|
title:headerForm.title,
|
|
} }).then(() => {
|
|
projectSelectVisible.value = false;
|
|
message.success(t('成功'));
|
|
}).catch((err) => {
|
|
message.error(err.msg || '失败')
|
|
}).finally(() => {
|
|
saveDraftLoading.value = false;
|
|
});
|
|
};
|
|
const tmpId = computed(()=>temp.temp_id);
|
|
const handleTransferTemplate = () => {
|
|
const flowName = props.isUpdate ? 'theSpecialCommitteeReviewAndUpdate':'theSpecialCommitteeReviewsAndRegisters';
|
|
const flowNameObj = flowNameOptions.filter(item => item.label === flowName)[0]
|
|
console.log(flowNameObj.value,'flowNameObj.value');
|
|
temp.changeTempShow(true, flowNameObj.value);
|
|
};
|
|
watch(()=>tmpId.value,async ()=>{
|
|
const res = await getByTemplateId(tmpId.value)
|
|
headerForm.title = res.data;
|
|
formData.value = res.data;
|
|
})
|
|
const saveTemplateLoading = ref<boolean>(false);
|
|
// 处理保存模板事件
|
|
const handleSaveTemplate = async () => {
|
|
const valid = await headerFormRef.value?.validate();
|
|
if (!valid) return;
|
|
if (saveTemplateLoading.value) return;
|
|
try {
|
|
const isUpdate = props.isUpdate;
|
|
const flowName = isUpdate ? 'theSpecialCommitteeReviewAndUpdate':'theSpecialCommitteeReviewsAndRegisters';
|
|
const flowNameObj = flowNameOptions.filter(item => item.label === flowName)[0]
|
|
const {data: templateId}= await addTemplate({templateName:headerForm.title,templateType:flowNameObj.value});
|
|
const newData ={ ...formData.value,status:0,templateId}
|
|
await addCommitteeApplication(newData);
|
|
message.success('保存模板成功');
|
|
}catch (error: any){
|
|
message.error(error.msg || '保存模板失败')
|
|
}finally {
|
|
saveTemplateLoading.value = false;
|
|
}
|
|
};
|
|
|
|
const handleViewWorkflow = () => {
|
|
message.info(t('committeeReview.messages.viewWorkflow'));
|
|
};
|
|
|
|
// 处理项目选择事件
|
|
const handleProjectSelect = (projectName: string, projectId: number) => {
|
|
formData.value.projectName = projectName;
|
|
formData.value.projectId = projectId;
|
|
};
|
|
// 处理专委会评审信息库选择事件
|
|
const handleLibrarySelect = (row: ProjectExitFeedback) => {
|
|
formData.value.projectName = row.projectName
|
|
formData.value.projectId = row.projectId
|
|
formData.value.parentId = row.id
|
|
}
|
|
const uploadChange = (type: number,_:any,data:any[]) =>{
|
|
if (!data || Object.prototype.toString.call(data) !== '[object Array]' || data.length === 0){
|
|
if (type === 1){
|
|
headerForm.attachments = [];
|
|
return;
|
|
}
|
|
formData.value.attachmentList = [];
|
|
return;
|
|
}
|
|
const newData = data.map((item:any) => {
|
|
return {
|
|
name: item.name,
|
|
url: item.url
|
|
}
|
|
})
|
|
if (type === 1){
|
|
headerForm.attachments = newData;
|
|
}else {
|
|
formData.value.attachmentList = newData;
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style scoped>
|
|
.committee-review-page .form-header-actions {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
}
|
|
|
|
.header-card {
|
|
margin-bottom: 16px;
|
|
}
|
|
|
|
.form-card {
|
|
padding-bottom: 16px;
|
|
}
|
|
|
|
.form-title {
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
gap: 8px;
|
|
margin-bottom: 16px;
|
|
}
|
|
|
|
.form-title-text {
|
|
font-size: 20px;
|
|
font-weight: 600;
|
|
text-align: center;
|
|
}
|
|
|
|
.form-title-sub {
|
|
width: 100%;
|
|
display: flex;
|
|
justify-content: space-between;
|
|
color: var(--el-text-color-secondary);
|
|
}
|
|
|
|
.subtitle-left,
|
|
.subtitle-right {
|
|
font-size: 14px;
|
|
}
|
|
|
|
.form-row {
|
|
margin-bottom: 18px;
|
|
display: flex;
|
|
align-items: center;
|
|
}
|
|
|
|
.form-label-col {
|
|
}
|
|
|
|
.table-label {
|
|
font-weight: 500;
|
|
}
|
|
|
|
.review-form :deep(.el-form-item) {
|
|
margin-bottom: 0;
|
|
}
|
|
|
|
.review-form :deep(.el-form-item__content) {
|
|
flex-wrap: nowrap;
|
|
}
|
|
|
|
.review-form :deep(.el-input__wrapper) {
|
|
border-top-left-radius: 0;
|
|
border-bottom-left-radius: 0;
|
|
}
|
|
.review-form .footer-input :deep(.el-input__wrapper) {
|
|
border-top-left-radius: 4px;
|
|
border-bottom-left-radius: 4px;
|
|
}
|
|
|
|
</style> |