feat: 新增投资项目退出反馈、进度报告、计划申请及退出计划等管理功能模块及相关组件

This commit is contained in:
2025-12-27 01:11:47 +08:00
parent b29d128e41
commit 915cb66b40
11 changed files with 968 additions and 684 deletions

View File

@@ -1,53 +1,55 @@
<template>
<div class="layout-padding">
<div class="layout-padding-auto layout-padding-view">
<el-row class="mb10">
<div class="form-header-actions" style="width: 100%;">
<div>
<el-button type="primary" icon="Check" :loading="submitLoading" @click="handleInitiateApproval">
{{ t('projectExitPlan.actions.initiateApproval') }}
</el-button>
<el-button icon="Document" @click="handleSaveDraft">
{{ t('projectExitPlan.actions.saveDraft') }}
</el-button>
<el-button icon="FolderOpened" @click="handleLoadTemplate">
{{ t('projectExitPlan.actions.loadTemplate') }}
</el-button>
<el-button icon="FolderAdd" @click="handleSaveTemplate">
{{ t('projectExitPlan.actions.saveTemplate') }}
</el-button>
</div>
<div style="margin-left:auto;">
<el-button icon="View" @click="handleViewWorkflow">
{{ t('projectExitPlan.actions.viewWorkflow') }}
</el-button>
</div>
</div>
</el-row>
<div class="layout-padding">
<div class="layout-padding-auto layout-padding-view">
<el-row class="mb10">
<div class="form-header-actions" style="width: 100%;">
<div>
<el-button type="primary" icon="Check" :loading="submitLoading" @click="handleInitiateApproval">
{{ t('projectExitPlan.actions.initiateApproval') }}
</el-button>
<el-button icon="Document" @click="handleSaveDraft">
{{ t('projectExitPlan.actions.saveDraft') }}
</el-button>
<el-button icon="FolderOpened" @click="handleLoadTemplate">
{{ t('projectExitPlan.actions.loadTemplate') }}
</el-button>
<el-button icon="FolderAdd" @click="handleSaveTemplate">
{{ t('projectExitPlan.actions.saveTemplate') }}
</el-button>
</div>
<div style="margin-left:auto;">
<el-button icon="View" @click="handleViewWorkflow">
{{ t('projectExitPlan.actions.viewWorkflow') }}
</el-button>
</div>
</div>
</el-row>
<el-row class="mb10">
<el-form :model="headerForm" label-width="80px" class="w-full">
<el-form-item :label="t('projectExitPlan.headerForm.title')">
<el-input v-model="headerForm.title"
:placeholder="t('projectExitPlan.headerForm.titlePlaceholder')" />
</el-form-item>
<el-form-item :label="t('projectExitPlan.headerForm.description')">
<el-input v-model="headerForm.description"
:placeholder="t('projectExitPlan.headerForm.descriptionPlaceholder')" />
</el-form-item>
<el-form-item :label="t('projectExitPlan.headerForm.attachments')">
<UploadFile :modelValue="headerForm.attachments" @change="uploadChange" :fileSize="20" type="simple" :limit="10" />
</el-form-item>
</el-form>
</el-row>
<el-row class="mb10">
<el-form :model="headerForm" :rules="headerFormRules" ref="headerFormRef" label-width="80px"
class="w-full">
<el-form-item :label="t('projectExitPlan.headerForm.title')" prop="title" required>
<el-input v-model="headerForm.title"
:placeholder="t('projectExitPlan.headerForm.titlePlaceholder')" />
</el-form-item>
<el-form-item :label="t('projectExitPlan.headerForm.description')">
<el-input v-model="headerForm.description"
:placeholder="t('projectExitPlan.headerForm.descriptionPlaceholder')" />
</el-form-item>
<el-form-item :label="t('projectExitPlan.headerForm.attachments')">
<UploadFile :modelValue="headerForm.attachments" @change="uploadChange" :fileSize="20"
type="simple" :limit="10" />
</el-form-item>
</el-form>
</el-row>
<ProjectExitPlanForm v-model="formData" :rules="rules" ref="formDataRef"/>
</div>
</div>
<ProjectExitPlanForm v-model="formData" :rules="rules" ref="formDataRef" />
</div>
</div>
</template>
<script setup lang="ts">
import { reactive } from 'vue';
import { reactive, ref } from 'vue';
import { useI18n } from 'vue-i18n';
import { useMessage } from '/@/hooks/message';
@@ -56,28 +58,33 @@ import ProjectExitPlanForm from '/@/components/investment/common/ProjectExitPlan
import { FormRules } from 'element-plus';
import { addProjectExitPlan } from '/@/api/investment/projectExitPlan';
import UploadFile from "/@/components/Upload/index.vue";
import {flowFn} from "/@/utils/flowFn";
import {addFlowForm} from "/@/api/flow/flow";
import {flowNameOptions} from "/@/hooks/enums";
import { flowFn } from "/@/utils/flowFn";
import { addFlowForm } from "/@/api/flow/flow";
import { flowNameOptions } from "/@/hooks/enums";
const formDataRef = ref<HTMLFormElement | null>()
const { t } = useI18n();
const message = useMessage();
const headerForm = reactive<{ title: string, description: string, attachments: any[] | string}>({
title: '',
description: '',
attachments: [] as any[],
const headerFormRef = ref<any>();
const headerFormRules = {
title: [{ required: true, message: '标题必填', trigger: ['blur', 'change'] }]
};
const headerForm = reactive<{ title: string, description: string, attachments: any[] | string }>({
title: '',
description: '',
attachments: [] as any[],
});
const formData = ref<ProjectTask>({
id: undefined,
projectName: '',
exitRecommendation: '',
executionTask:'',
taskDescription:'',
executor:'',
taskStartDate:new Date().toISOString().substring(0,10),
taskEndDate:new Date().toISOString().substring(0,10),
executionTask: '',
taskDescription: '',
executor: '',
taskStartDate: new Date().toISOString().substring(0, 10),
taskEndDate: new Date().toISOString().substring(0, 10),
deptId: ''
});
const requiredRule = [{ required: true, message: `${t('该字段必填')}` }]
const rules = reactive<FormRules<ProjectTask>>({
@@ -87,13 +94,17 @@ const rules = reactive<FormRules<ProjectTask>>({
const submitLoading = ref<boolean>(false);
const handleInitiateApproval = async () => {
try {
const valid = await formDataRef?.value?.validateRef();
const headerValid = await headerFormRef.value?.validate().catch(() => false);
if (!headerValid) {
return;
}
const valid = await formDataRef?.value?.validateRef();
if (!valid) return;
submitLoading.value = true;
const folowIdKey = 'VITE_FLOWID_35'
const attachments = JSON.stringify(headerForm.attachments);
const {processInstanceId} = await flowFn(folowIdKey,{
paramMap:{
const flowResult = await flowFn(folowIdKey, {
paramMap: {
// miu0ilc1tfa61_assignee_select: [
// {
// "type": "user",
@@ -104,6 +115,11 @@ const handleInitiateApproval = async () => {
// ]
}
})
if (flowResult instanceof Error) {
submitLoading.value = false;
throw flowResult;
}
const { processInstanceId } = flowResult;
const flowNameObj = flowNameOptions.filter(item => item.label === 'exitPlan')[0]
await addFlowForm({
title: headerForm.title,
@@ -113,14 +129,14 @@ const handleInitiateApproval = async () => {
flowType: flowNameObj.value
})
formData.value.processInstanceId = processInstanceId;
addProjectExitPlan(formData.value).then((res:any) => {
addProjectExitPlan(formData.value).then((res: any) => {
useMessage().success(t('common.success'));
}).catch((err:any) => {
}).catch((err: any) => {
useMessage().error(err.msg);
}).finally(() => {
submitLoading.value = false;
});
}catch (e) {
} catch (e) {
console.log(e);
submitLoading.value = false;
}
@@ -128,26 +144,26 @@ const handleInitiateApproval = async () => {
};
const handleSaveDraft = () => {
message.info(t('projectExitPlan.messages.saveDraft'));
message.info(t('projectExitPlan.messages.saveDraft'));
};
const handleLoadTemplate = () => {
message.info(t('projectExitPlan.messages.loadTemplate'));
message.info(t('projectExitPlan.messages.loadTemplate'));
};
const handleSaveTemplate = () => {
message.info(t('projectExitPlan.messages.saveTemplate'));
message.info(t('projectExitPlan.messages.saveTemplate'));
};
const handleViewWorkflow = () => {
message.info(t('projectExitPlan.messages.viewWorkflow'));
message.info(t('projectExitPlan.messages.viewWorkflow'));
};
const uploadChange = (_:any,data:any[]) =>{
if (!data || Object.prototype.toString.call(data) !== '[object Array]' || data.length === 0){
const uploadChange = (_: any, data: any[]) => {
if (!data || Object.prototype.toString.call(data) !== '[object Array]' || data.length === 0) {
headerForm.attachments = [];
return;
}
headerForm.attachments = data.map((item:any) => {
headerForm.attachments = data.map((item: any) => {
return {
name: item.name,
url: item.url
@@ -158,13 +174,13 @@ const uploadChange = (_:any,data:any[]) =>{
<style scoped>
.layout-container .layout-padding {
height: auto;
overflow: auto;
height: auto;
overflow: auto;
}
.form-header-actions {
display: flex;
justify-content: space-between;
align-items: center;
display: flex;
justify-content: space-between;
align-items: center;
}
</style>