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

@@ -27,41 +27,45 @@
<!-- 标题描述上传附件 -->
<el-row class="mb10">
<el-form :model="headerForm" label-width="80px" class="w-full" :rules="headerRequiredRule" ref="headerFormRef">
<el-form :model="headerForm" label-width="80px" class="w-full" :rules="headerRequiredRule"
ref="headerFormRef">
<el-form-item :label="t('planApply.headerForm.title')" prop="title">
<el-input v-model="headerForm.title" :placeholder="t('planApply.headerForm.titlePlaceholder')"/>
<el-input v-model="headerForm.title"
:placeholder="t('planApply.headerForm.titlePlaceholder')" />
</el-form-item>
<el-form-item :label="t('planApply.headerForm.description')">
<el-input v-model="headerForm.description" :placeholder="t('planApply.headerForm.descriptionPlaceholder')"/>
<el-input v-model="headerForm.description"
:placeholder="t('planApply.headerForm.descriptionPlaceholder')" />
</el-form-item>
<el-form-item :label="t('planApply.headerForm.attachments')">
<UploadFile :modelValue="headerForm.attachments" :fileSize="20" type="simple" :limit="10"
@change="uploadChange"/>
@change="uploadChange" />
</el-form-item>
</el-form>
</el-row>
<ProjectPlanApplyForm v-model="formData" :rules="formDataRules" ref="formDataRef" :is-update="props.isUpdate"/>
<ProjectPlanApplyForm v-model="formData" :rules="formDataRules" ref="formDataRef"
:is-update="props.isUpdate" />
</div>
</div>
</template>
<script setup lang="ts">
import {reactive, ref} from 'vue';
import {useI18n} from 'vue-i18n';
import {useMessage} from '/@/hooks/message';
import { reactive, ref } from 'vue';
import { useI18n } from 'vue-i18n';
import { useMessage } from '/@/hooks/message';
import {
investmentProjectsPlanAdd, investmentProjectsPlanGetById,
investmentProjectsPlanUserDeptBelong
} from '/@/api/investment/investmentManagement';
import ProjectPlanApplyForm from '/@/components/investment/common/ProjectPlanApplyForm.vue';
import type {ProjectPlanApplyFormData} from '/@/components/investment/interface/types';
import type {FormInstance, FormRules} from 'element-plus';
import type { ProjectPlanApplyFormData } from '/@/components/investment/interface/types';
import type { FormInstance, FormRules } from 'element-plus';
import UploadFile from '/@/components/Upload/index.vue';
import {useRoute} from 'vue-router';
import {flowFn} from "/@/utils/flowFn";
import {addFlowForm} from "/@/api/flow/flow";
import {flowNameOptions} from "/@/hooks/enums";
import { useRoute } from 'vue-router';
import { flowFn } from "/@/utils/flowFn";
import { addFlowForm } from "/@/api/flow/flow";
import { flowNameOptions } from "/@/hooks/enums";
const props = defineProps({
isUpdate: {
@@ -69,7 +73,7 @@ const props = defineProps({
default: false
}
})
const {t} = useI18n();
const { t } = useI18n();
const message = useMessage();
const route = useRoute();
const submitLoading = ref(false);
@@ -78,7 +82,7 @@ const headerForm = reactive<{ title: string, description: string, attachments: a
description: '',
attachments: [] as any[],
});
const requiredRule = [{required: true, message: `${t('该字段必填')}`}];
const requiredRule = [{ required: true, message: `${t('该字段必填')}` }];
const headerRequiredRule = ref<FormRules<{ title: string, description: string, attachments: any[] | string }>>({
title: requiredRule,
});
@@ -150,9 +154,9 @@ const formData = ref<ProjectPlanApplyFormData>({
submitUnitLeadershipOpinion: '',
submitUnitMainLeadershipOpinion: '',
planImageQuota: '',
status:1,
processInstanceId:'',
deptId:0,
status: 1,
processInstanceId: '',
deptId: 0,
},
investmentProjects: [],
});
@@ -203,40 +207,51 @@ const formDataRules = ref<FormRules<ProjectPlanApplyFormData>>({
'entity.financialFunds': requiredRule,
'entity.planImageQuota': requiredRule,
'entity.planPaymentLimit': requiredRule,
'entity.projectApprovalFileNo':[{validator:(rule: any, value: any, callback: any) =>{
if (formData.value.entity.isProjectApprovalCompleted === '1' && !value){
callback(new Error(`${t('该字段必填')}`));
}else {
callback();
}
},required:true,trigger: ['blur', 'change']}],
'entity.projectApprovalFileInfo':[{validator:(rule: any, value: any, callback: any) =>{
if (formData.value.entity.isProjectApprovalCompleted === '1' && !value){
callback(new Error(`${t('该字段必填')}`));
}else {
callback();
}
},required: true,trigger: ['blur', 'change']}],
'entity.decisionProcedureFileNo':[{validator:(rule: any, value: any, callback: any) =>{
if (formData.value.entity.isDecisionProcedureCompleted === '1' && !value){
callback(new Error(`${t('该字段必填')}`));
}else {
callback();
}
},required:true,trigger: ['blur', 'change']}],
'entity.decisionFileInfo':[{validator:(rule: any, value: any, callback: any) =>{
if (formData.value.entity.isDecisionProcedureCompleted === '1' && !value){
callback(new Error(`${t('该字段必填')}`));
}else {
callback();
}
},required: true,trigger: ['blur', 'change']}],
'entity.projectApprovalFileNo': [{
validator: (rule: any, value: any, callback: any) => {
if (formData.value.entity.isProjectApprovalCompleted === '1' && !value) {
callback(new Error(`${t('该字段必填')}`));
} else {
callback();
}
}, required: true, trigger: ['blur', 'change']
}],
'entity.projectApprovalFileInfo': [{
validator: (rule: any, value: any, callback: any) => {
if (formData.value.entity.isProjectApprovalCompleted === '1' && !value) {
callback(new Error(`${t('该字段必填')}`));
} else {
callback();
}
}, required: true, trigger: ['blur', 'change']
}],
'entity.decisionProcedureFileNo': [{
validator: (rule: any, value: any, callback: any) => {
if (formData.value.entity.isDecisionProcedureCompleted === '1' && !value) {
callback(new Error(`${t('该字段必填')}`));
} else {
callback();
}
}, required: true, trigger: ['blur', 'change']
}],
'entity.decisionFileInfo': [{
validator: (rule: any, value: any, callback: any) => {
if (formData.value.entity.isDecisionProcedureCompleted === '1' && !value) {
callback(new Error(`${t('该字段必填')}`));
} else {
callback();
}
}, required: true, trigger: ['blur', 'change']
}],
});
const handleInitiateApproval = async () => {
try {
const headerValid = await headerFormRef.value?.validate();
const valid = await formDataRef.value?.validateForm();
if (!valid && !headerValid) return;
const headerValid = await headerFormRef.value?.validate().catch(() => false);
if (!headerValid) return;
const valid = await formDataRef.value?.validateForm().catch(() => false);
if (!valid) return;
submitLoading.value = true;
let flowIdKey = ''
const data = await investmentProjectsPlanUserDeptBelong()
@@ -256,7 +271,7 @@ const handleInitiateApproval = async () => {
default:
flowIdKey = props.isUpdate ? 'VITE_FLOWID_27' : 'VITE_FLOWID_23';
}
const {processInstanceId} = await flowFn(flowIdKey, {
const { processInstanceId } = await flowFn(flowIdKey, {
paramMap: {}
})
const flowName = props.isUpdate ? 'investmentPlanUpdates' : 'investmentPlanRegistration';
@@ -271,7 +286,7 @@ const handleInitiateApproval = async () => {
formData.value.entity.processInstanceId = processInstanceId;
formData.value.entity.projectPreliminaryPlanAttachment = JSON.stringify(formData.value.entity.projectPreliminaryPlanAttachment);
formData.value.entity.status = 1
Object.assign(formData.value.entity,{flowType:flowNameObj.value})
Object.assign(formData.value.entity, { flowType: flowNameObj.value })
const params = {
...formData.value,
entity: {
@@ -281,14 +296,14 @@ const handleInitiateApproval = async () => {
}
}
investmentProjectsPlanAdd(params)
.then(() => {
submitLoading.value = false;
message.success(t('planApply.messages.initiateApproval'));
})
.catch((err: any) => {
submitLoading.value = false;
message.error(err.msg);
});
.then(() => {
submitLoading.value = false;
message.success(t('planApply.messages.initiateApproval'));
})
.catch((err: any) => {
submitLoading.value = false;
message.error(err.msg);
});
} catch (error) {
console.log(error, 'error');
}
@@ -296,28 +311,32 @@ const handleInitiateApproval = async () => {
const saveLoading = ref<boolean>(false);
const handleSaveDraft = async () => {
const headerValid = await headerFormRef.value?.validate();
const valid = await formDataRef.value?.validateForm();
if (!valid && !headerValid) return;
saveLoading.value = true;
const flowName = props.isUpdate ? 'investmentPlanUpdates' : 'investmentPlanRegistration';
const flowNameObj = flowNameOptions.filter(item => item.label === flowName)[0]
formData.value.entity.projectPreliminaryPlanAttachment = JSON.stringify(formData.value.entity.projectPreliminaryPlanAttachment);
formData.value.entity.status = 1
Object.assign(formData.value.entity,{flowType:flowNameObj.value})
const params = {
...formData.value,
entity: {
...formData.value.entity,
attachments: formData.value.entity.attachments ? JSON.stringify(formData.value.entity.attachments) : '',
projectPreliminaryPlanAttachment: formData.value.entity.projectPreliminaryPlanAttachment ? JSON.stringify(formData.value.entity.projectPreliminaryPlanAttachment) : ''
},
temporaryStorage:{
title: headerForm.title,
businessType: flowNameObj.value,
try {
const headerValid = await headerFormRef.value?.validate().catch(() => false);
if (!headerValid) return;
const valid = await formDataRef.value?.validateForm().catch(() => false);
if (!valid) return;
saveLoading.value = true;
const flowName = props.isUpdate ? 'investmentPlanUpdates' : 'investmentPlanRegistration';
const flowNameObj = flowNameOptions.filter(item => item.label === flowName)[0]
formData.value.entity.projectPreliminaryPlanAttachment = JSON.stringify(formData.value.entity.projectPreliminaryPlanAttachment);
formData.value.entity.status = 1
Object.assign(formData.value.entity, { flowType: flowNameObj.value })
const params = {
...formData.value,
entity: {
...formData.value.entity,
attachments: formData.value.entity.attachments ? JSON.stringify(formData.value.entity.attachments) : '',
projectPreliminaryPlanAttachment: formData.value.entity.projectPreliminaryPlanAttachment ? JSON.stringify(formData.value.entity.projectPreliminaryPlanAttachment) : ''
},
temporaryStorage: {
title: headerForm.title,
businessType: flowNameObj.value,
}
}
}
investmentProjectsPlanAdd(params)
investmentProjectsPlanAdd(params)
.then(() => {
saveLoading.value = false;
message.success('保存代发成功');
@@ -326,6 +345,9 @@ const handleSaveDraft = async () => {
saveLoading.value = false;
message.error(err.msg);
});
} catch (error) {
console.log(error, 'error');
}
};
const handleLoadTemplate = () => {

View File

@@ -27,15 +27,19 @@
<!-- 标题描述上传附件 -->
<el-row class="mb10">
<el-form :model="headerForm" label-width="80px" class="w-full">
<el-form-item :label="t('progressReport.headerForm.title')">
<el-input v-model="headerForm.title" :placeholder="t('progressReport.headerForm.titlePlaceholder')" />
<el-form :model="headerForm" :rules="headerFormRules" ref="headerFormRef" label-width="80px"
class="w-full">
<el-form-item :label="t('progressReport.headerForm.title')" prop="title" required>
<el-input v-model="headerForm.title"
:placeholder="t('progressReport.headerForm.titlePlaceholder')" />
</el-form-item>
<el-form-item :label="t('progressReport.headerForm.description')">
<el-input v-model="headerForm.description" :placeholder="t('progressReport.headerForm.descriptionPlaceholder')" />
<el-input v-model="headerForm.description"
:placeholder="t('progressReport.headerForm.descriptionPlaceholder')" />
</el-form-item>
<el-form-item :label="t('progressReport.headerForm.attachments')">
<UploadFile :modelValue="headerForm.attachments" @change="uploadChange" :fileSize="20" type="simple" :limit="10" />
<UploadFile :modelValue="headerForm.attachments" @change="uploadChange" :fileSize="20"
type="simple" :limit="10" />
</el-form-item>
</el-form>
</el-row>
@@ -46,7 +50,7 @@
</template>
<script setup lang="ts">
import { reactive } from 'vue';
import { reactive, ref } from 'vue';
import { useI18n } from 'vue-i18n';
import { useMessage } from '/@/hooks/message';
import ProjectProgressReportForm from '/@/components/investment/common/ProjectProgressReportForm.vue';
@@ -57,14 +61,18 @@ import {
getInvestmentProjectsProgressUserDeptBelongAPI
} from '/@/api/investment/progressOfInvestmentProjects';
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 { t } = useI18n();
const message = useMessage();
const headerForm = reactive<{ title: string; description: string; attachments: any[] | string}>({
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: [],
@@ -103,6 +111,7 @@ const formData = reactive<InvestmentProjectProgress>({
delFlag: '',
processInstanceId: '',
status: '',
deptId: '',
});
// 必填规则
const requiredRule = [{ required: true, message: `${t('该字段必填')}` }];
@@ -118,6 +127,10 @@ const formDataRef = ref<FormRules<InvestmentProjectProgress>>({
const handleInitiateApproval = async () => {
// message.info(t('progressReport.messages.initiateApproval'));
try {
const headerValid = await headerFormRef.value?.validate().catch(() => false);
if (!headerValid) {
return;
}
const valid = await formRef.value?.validate();
submitLoading.value = true;
let flowIdKey = '';
@@ -139,10 +152,14 @@ const handleInitiateApproval = async () => {
flowIdKey = 'VITE_FLOWID_31';
}
headerForm.attachments = JSON.stringify(headerForm.attachments);
const {processInstanceId} = await flowFn(flowIdKey,{
paramMap:{
const flowResult = await flowFn(flowIdKey, {
paramMap: {
}
})
if (flowResult instanceof Error) {
throw flowResult;
}
const { processInstanceId } = flowResult;
const flowNameObj = flowNameOptions.filter(item => item.label === 'projectProgressDeclaration')[0]
await addFlowForm({
title: headerForm.title,
@@ -154,9 +171,9 @@ const handleInitiateApproval = async () => {
valid.processInstanceId = processInstanceId;
valid.supportingDocuments = JSON.stringify(valid.supportingDocuments);
valid.status = 1;
await addInvestmentProjectsProgressAPI(valid).then(()=>{
await addInvestmentProjectsProgressAPI(valid).then(() => {
message.success(t('common.success'));
}).finally(()=>{
}).finally(() => {
submitLoading.value = false;
}).catch((err: any) => {
submitLoading.value = false;
@@ -182,12 +199,12 @@ const handleSaveTemplate = () => {
const handleViewWorkflow = () => {
message.info(t('progressReport.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

View File

@@ -1,8 +1,8 @@
<!-- 进度申报审核-->
<script setup lang="ts">
import {onMounted} from 'vue';
import { onMounted } from 'vue';
import ApprovalAction from '/@//components/workbench/common/ApprovalAction.vue';
import {useRoute} from 'vue-router';
import { useRoute } from 'vue-router';
import ProjectProgressReportFormDeatils from '/@/components/investment/common/ProjectProgressReportFormDeatils.vue';
import {
getInvestmentProjectsProgressGetByProcessInstanceIdAPI,
@@ -15,13 +15,13 @@ const taskId = ref<string>('0');
const status = ref<'pending' | 'reviewed' | 'withdrawable'>('pending');
const projectId = ref<string>('0');
const detailFormData = ref<InvestmentProjectProgress>({} as InvestmentProjectProgress);
const getProjectDetail = (id:string) =>{
getInvestmentProjectsProgressGetByProcessInstanceIdAPI(id).then(res =>{
const getProjectDetail = (id: string) => {
getInvestmentProjectsProgressGetByProcessInstanceIdAPI(id).then(res => {
detailFormData.value = res.data
});
}
onMounted(() =>{
if (route.query.processInstanceId){
onMounted(() => {
if (route.query.processInstanceId) {
taskId.value = <string>route.query.tId;
projectId.value = <string>route.query.processInstanceId;
getProjectDetail(projectId.value);
@@ -33,11 +33,12 @@ onMounted(() =>{
<el-card>
<el-row :gutter="20">
<el-col :span="isPreview ? 24 : 18">
<FlowFormView :process-instance-id="projectId"/>
<ProjectProgressReportFormDeatils v-model="detailFormData" title="投资项目进度审核"/>
<FlowFormView :process-instance-id="projectId" />
<ProjectProgressReportFormDeatils v-model="detailFormData" title="投资项目进度审核" />
</el-col>
<el-col :span="6" v-if="!isPreview">
<ApprovalAction :status="status" :approval-records="[]" :task-id="taskId" :process-instance-id="projectId"/>
<ApprovalAction :status="status" :approval-records="[]" :task-id="taskId"
:process-instance-id="projectId" />
</el-col>
</el-row>
</el-card>

View File

@@ -26,8 +26,9 @@
</el-row>
<el-row class="mb10">
<el-form :model="headerForm" label-width="80px" class="w-full">
<el-form-item :label="t('projectExitFeedback.headerForm.title')">
<el-form :model="headerForm" :rules="headerFormRules" ref="headerFormRef" label-width="80px"
class="w-full">
<el-form-item :label="t('projectExitFeedback.headerForm.title')" prop="title" required>
<el-input v-model="headerForm.title"
:placeholder="t('projectExitFeedback.headerForm.titlePlaceholder')" />
</el-form-item>
@@ -36,7 +37,8 @@
:placeholder="t('projectExitFeedback.headerForm.descriptionPlaceholder')" />
</el-form-item>
<el-form-item :label="t('projectExitFeedback.headerForm.attachments')">
<UploadFile :modelValue="headerForm.attachments" @change="uploadChange" :fileSize="20" type="simple" :limit="10" />
<UploadFile :modelValue="headerForm.attachments" @change="uploadChange" :fileSize="20"
type="simple" :limit="10" />
</el-form-item>
</el-form>
</el-row>
@@ -47,20 +49,25 @@
</template>
<script setup lang="ts">
import { reactive } from 'vue';
import { reactive, ref } from 'vue';
import { useI18n } from 'vue-i18n';
import { useMessage } from '/@/hooks/message';
import ProjectExitFeedbackForm from '/@/components/investment/common/ProjectExitFeedbackForm.vue';
import { ProjectExitFeedback } from '/@/views/invMid/projectExitFeedback/interface/type';
import {addProjectExitPlanFeedback} from "/@/api/investment/projectExitPlan";
import { addProjectExitPlanFeedback } from "/@/api/investment/projectExitPlan";
import { ProjectTask } from "/@/views/invMid/projectExitPlan/interface/type";
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 { t } = useI18n();
const message = useMessage();
const headerForm = reactive<{ title: string, description: string, attachments: any[] | string}>({
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[],
@@ -68,47 +75,57 @@ const headerForm = reactive<{ title: string, description: string, attachments: a
const formData = ref<ProjectExitFeedback>({
exitTime: '',
exitExecutor: '',
exitRemark: '',
exitAttachment: '',
exitRemark: '',
exitAttachment: '',
deptId: '',
});
const submitLoading = ref(false);
const handleInitiateApproval = async () => {
if (!formData.value.projectId){
message.error('项目名称必填');
return
}
submitLoading.value = true;
const attachments = JSON.stringify(headerForm.attachments);
const {processInstanceId} = await flowFn('VITE_FLOWID_36',{
paramMap:{
// miu0ilc1tfa61_assignee_select: [
// {
// "type": "user",
// "id": "1",
// "name": "admin",
// "avatar": "/admin/sys-file/local/2a14ae08150e483c93e12ac8934173e2.png"
// }
// ]
}
})
const flowNameObj = flowNameOptions.filter(item => item.label === 'exitFeedback')[0]
await addFlowForm({
title: headerForm.title,
description: headerForm.description,
attachments,
processInstanceId,
flowType: flowNameObj.value
})
formData.value.processInstanceId = processInstanceId;
const exitAttachment = JSON.stringify(formData.value.exitAttachment);
const params = { ...formData.value, exitAttachment }
addProjectExitPlanFeedback(params).then(()=>{
message.success(t('common.success'));
}).catch((err: any) => {
message.error(err.msg);
}).finally(() => {
submitLoading.value = false;
});
const headerValid = await headerFormRef.value?.validate().catch(() => false);
if (!headerValid) {
return;
}
if (!formData.value.projectId) {
message.error('项目名称必填');
return
}
submitLoading.value = true;
const attachments = JSON.stringify(headerForm.attachments);
const flowResult = await flowFn('VITE_FLOWID_36', {
paramMap: {
// miu0ilc1tfa61_assignee_select: [
// {
// "type": "user",
// "id": "1",
// "name": "admin",
// "avatar": "/admin/sys-file/local/2a14ae08150e483c93e12ac8934173e2.png"
// }
// ]
}
})
if (flowResult instanceof Error) {
submitLoading.value = false;
throw flowResult;
}
const { processInstanceId } = flowResult;
const flowNameObj = flowNameOptions.filter(item => item.label === 'exitFeedback')[0]
await addFlowForm({
title: headerForm.title,
description: headerForm.description,
attachments,
processInstanceId,
flowType: flowNameObj.value
})
formData.value.processInstanceId = processInstanceId;
const exitAttachment = JSON.stringify(formData.value.exitAttachment);
const params = { ...formData.value, exitAttachment } as ProjectTask;
addProjectExitPlanFeedback(params).then(() => {
message.success(t('common.success'));
}).catch((err: any) => {
message.error(err.msg);
}).finally(() => {
submitLoading.value = false;
});
};
const handleSaveDraft = () => {
@@ -126,17 +143,17 @@ const handleSaveTemplate = () => {
const handleViewWorkflow = () => {
message.info(t('projectExitFeedback.messages.viewWorkflow'));
};
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) => {
return {
name: item.name,
url: item.url
}
})
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) => {
return {
name: item.name,
url: item.url
}
})
}
</script>

View File

@@ -34,10 +34,12 @@ export interface ProjectExitFeedback {
/** 状态 */
status?: string;
/** 项目id */
projectId?:number;
/** 项目名称*/
projectName?:string;
/** 项目id */
projectId?: number;
/** 项目名称*/
projectName?: string;
/** 部门id */
deptId: string;
}
export interface paramsDataProjectExitPlanFeedback {
@@ -48,31 +50,31 @@ export interface paramsDataProjectExitPlanFeedback {
exitRemark: string
}
export interface projectExitPlanFeedbackItem {
id?: number,
projectName?: string,
projectId?: number,
exitRecommendation?: string,
exitMethod?: string,
executionTask?: string,
taskDescription?: string,
executor?: string,
taskStartDate?: string,
taskEndDate?: string,
createBy?: string,
createTime?: string,
updateBy?: string,
updateTime?: string,
delFlag?: string,
processInstanceId?: string,
status?: string,
reviewNotes?: string,
applicationDept?: string
id?: number,
projectName?: string,
projectId?: number,
exitRecommendation?: string,
exitMethod?: string,
executionTask?: string,
taskDescription?: string,
executor?: string,
taskStartDate?: string,
taskEndDate?: string,
createBy?: string,
createTime?: string,
updateBy?: string,
updateTime?: string,
delFlag?: string,
processInstanceId?: string,
status?: string,
reviewNotes?: string,
applicationDept?: string
}
export interface feedbackResponseData {
total: number,
records: projectExitPlanFeedbackItem[];
current: number,
size: number,
pages: number,
total: number,
records: projectExitPlanFeedbackItem[];
current: number,
size: number,
pages: number,
}

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>