first commit

This commit is contained in:
2025-12-26 23:19:09 +08:00
commit b29d128e41
788 changed files with 100922 additions and 0 deletions

View File

@@ -0,0 +1,484 @@
<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.selectPlaceholder')" readonly>
<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 () => {
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>