first commit
This commit is contained in:
406
src/views/investment/reserveRegistration/index.vue
Normal file
406
src/views/investment/reserveRegistration/index.vue
Normal file
@@ -0,0 +1,406 @@
|
||||
<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('reserveRegistration.initiateApproval') }}
|
||||
</el-button>
|
||||
<el-button icon="Document" @click="handleSaveDraft" :loading="saveLoading">
|
||||
{{ t('reserveRegistration.saveDraft') }}
|
||||
</el-button>
|
||||
<el-button icon="FolderOpened" @click="handleLoadTemplate">
|
||||
{{ t('reserveRegistration.loadTemplate') }}
|
||||
</el-button>
|
||||
<el-button icon="FolderAdd" @click="handleSaveTemplate">
|
||||
{{ t('reserveRegistration.saveTemplate') }}
|
||||
</el-button>
|
||||
</div>
|
||||
<div style="margin-left:auto;">
|
||||
<el-button icon="View" @click="handleViewWorkflow" :loading="viewLoading">
|
||||
{{ t('reserveRegistration.viewWorkflow') }}
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</el-row>
|
||||
|
||||
<!-- 标题、描述、上传附件 -->
|
||||
<el-row class="mb10">
|
||||
<el-form :model="headerForm" label-width="80px" class="w-full" :rules="headerRequiredRule" ref="headerFormRef">
|
||||
<el-form-item :label="t('reserveRegistration.formTitle')" prop="title">
|
||||
<el-input v-model="headerForm.title" :placeholder="t('reserveRegistration.titlePlaceholder')" maxlength="255"/>
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('reserveRegistration.description')">
|
||||
<el-input v-model="headerForm.description"
|
||||
:placeholder="t('reserveRegistration.descriptionPlaceholder')" maxlength="255"/>
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('reserveRegistration.uploadAttachment')">
|
||||
<UploadFile :modelValue="headerForm.attachments" :fileSize="20" type="simple" :limit="10"
|
||||
@change="(url: string, files: any[]) => headerForm.attachments = files?.map((item: any) => ({ name: item.name, url: item.url })) || []" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-row>
|
||||
|
||||
<!-- 项目基本信息表单 -->
|
||||
<ProjectBasicInfoForm
|
||||
ref="basicInfoFormRef"
|
||||
:model-value="projectFormData"
|
||||
:mainTitle="isUpdate ? t('reserveRegistration.updateTitle') : t('reserveRegistration.title')"
|
||||
:is-update="isUpdate"
|
||||
/>
|
||||
<template-table-common />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import {computed, reactive, ref, watch} from 'vue';
|
||||
import {useI18n} from 'vue-i18n';
|
||||
import {useMessage} from '/@/hooks/message';
|
||||
import type {ProjectBasicInfoFormData} from '/@/components/investment/common/ProjectBasicInfoForm.vue';
|
||||
import ProjectBasicInfoForm from '/@/components/investment/common/ProjectBasicInfoForm.vue';
|
||||
import {
|
||||
addReserveInvestmentProjectAPI,
|
||||
getReserveInvestmentProjectsByTemplateIdAPI
|
||||
} from '/@/api/investment/reserveRegistration';
|
||||
import templateTableCommon from "/@/components/templetTableComom/index.vue"
|
||||
import {useUserInfo} from '/@/stores/userInfo';
|
||||
import {formatDate} from '/@/utils/formatTime';
|
||||
import {flowFn} from "/@/utils/flowFn";
|
||||
import {addFlowForm} from '/@/api/flow/flow';
|
||||
import {flowNameOptions} from '/@/hooks/enums';
|
||||
import {addTemplate, getUserDeptBelong} from "/@/api/common";
|
||||
import {templateStore} from "/@/stores/template";
|
||||
import type {FormInstance, FormRules} from "element-plus";
|
||||
|
||||
const temp = templateStore();
|
||||
const props = defineProps({
|
||||
isUpdate: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
})
|
||||
|
||||
const { t } = useI18n();
|
||||
const message = useMessage();
|
||||
const submitLoading = ref(false);
|
||||
|
||||
const headerForm = reactive({
|
||||
id: '',
|
||||
title: '',
|
||||
description: '',
|
||||
attachments: [] as any[],
|
||||
});
|
||||
const headerRequiredRule = ref<FormRules>({
|
||||
title: [{ required: true, message: t('该字段必传'), trigger: 'blur' }],
|
||||
});
|
||||
const headerFormRef = ref<FormInstance>();
|
||||
const userInfoStore = useUserInfo();
|
||||
const currentApplicant = computed(() => userInfoStore.userInfos.user?.username || '');
|
||||
const currentApplicationUnit = computed(() => userInfoStore.userInfos.user?.deptName || '');
|
||||
const currentApplicationDate = computed(() => formatDate(new Date(), 'YYYY-mm-dd'));
|
||||
|
||||
const createDefaultProjectFormData = (): ProjectBasicInfoFormData => ({
|
||||
applicant: currentApplicant.value,
|
||||
applicationUnit: currentApplicationUnit.value,
|
||||
projectName: '',
|
||||
projectMainUnit: '',
|
||||
projectStartDate: '',
|
||||
investmentCategory: '',
|
||||
projectManagerName: '',
|
||||
projectSource: '',
|
||||
keyProject: '',
|
||||
withinMainBusiness: '',
|
||||
mainBusinessType: '',
|
||||
projectDirection: '',
|
||||
strategicEmergingIndustry: '',
|
||||
isManufacturing: '',
|
||||
projectAddress: '',
|
||||
isControllingShareholder: '',
|
||||
totalInvestmentAmount: '',
|
||||
ourTotalInvestmentAmount: '',
|
||||
projectDesc: '',
|
||||
progressDesc: '',
|
||||
projectProposal: [],
|
||||
applicationDate: currentApplicationDate.value,
|
||||
projectOwnerUnit: '',
|
||||
projectEndDate: '',
|
||||
projectNature: '',
|
||||
contactNumber: '',
|
||||
constructionNature: '',
|
||||
majorInvestmentProject: '',
|
||||
mainBusinessCode: '',
|
||||
directionSubdivision: '',
|
||||
urbanStrategy: '',
|
||||
investmentRegion: '',
|
||||
projectDetailedAddress: '',
|
||||
ourShareholdingRatio: '',
|
||||
cumulativeInvestmentLastYear: '',
|
||||
ourCumulativeInvestmentLastYear: '',
|
||||
enterpriseSelfFund: '',
|
||||
externalRaisedFund: '',
|
||||
governmentInvestmentFund: '',
|
||||
otherFunds: '',
|
||||
partnerInfos: [],
|
||||
decisionType: '',
|
||||
isCompleteEstablishmentProcedures: '',
|
||||
establishmentDocumentNumber: '',
|
||||
establishmentDocumentInfo: '',
|
||||
decisionProgramDocumentNumber: '',
|
||||
decisionDocumentInfo: '',
|
||||
isCompleteDecisionProcedures: '',
|
||||
reviewOpinions: {
|
||||
submitUnitOpinion: '',
|
||||
groupInvestmentDeptOpinion: '',
|
||||
submitUnitLeadershipOpinion: '',
|
||||
submitUnitMainLeadershipOpinion: '',
|
||||
},
|
||||
processInstanceId: '',
|
||||
status: 1
|
||||
});
|
||||
|
||||
const projectFormData = reactive<ProjectBasicInfoFormData>(createDefaultProjectFormData());
|
||||
|
||||
watch(currentApplicant, val => {
|
||||
if (!projectFormData.applicant) {
|
||||
projectFormData.applicant = val;
|
||||
}
|
||||
});
|
||||
watch(currentApplicationUnit, val => {
|
||||
if (!projectFormData.applicationUnit) {
|
||||
projectFormData.applicationUnit = val;
|
||||
}
|
||||
});
|
||||
watch(currentApplicationDate, val => {
|
||||
if (!projectFormData.applicationDate) {
|
||||
projectFormData.applicationDate = val;
|
||||
}
|
||||
});
|
||||
|
||||
const resetHeaderForm = () => {
|
||||
headerForm.id = '';
|
||||
headerForm.title = '';
|
||||
headerForm.description = '';
|
||||
headerForm.attachments = [];
|
||||
};
|
||||
|
||||
const resetProjectForm = () => {
|
||||
const defaults = createDefaultProjectFormData();
|
||||
Object.assign(projectFormData, defaults);
|
||||
projectFormData.projectProposal = [];
|
||||
if (projectFormData.partnerInfos?.length) {
|
||||
projectFormData.partnerInfos.splice(0, projectFormData.partnerInfos.length);
|
||||
}
|
||||
Object.assign(projectFormData.reviewOpinions, defaults.reviewOpinions);
|
||||
};
|
||||
|
||||
|
||||
const toNumber = (value: string | number | undefined | null) => {
|
||||
if (value === '' || value === undefined || value === null) return undefined;
|
||||
const num = Number(value);
|
||||
return Number.isFinite(num) ? num : undefined;
|
||||
};
|
||||
|
||||
const extractPartnerIds = () => {
|
||||
if (!Array.isArray(projectFormData.partnerInfos)) return [] as Array<string | number>;
|
||||
return projectFormData.partnerInfos
|
||||
.map(item => item?.id)
|
||||
.filter((id): id is string | number => id !== undefined && id !== null && id !== '');
|
||||
};
|
||||
|
||||
const buildSubmitPayload = () => ({
|
||||
id: headerForm.id || undefined,
|
||||
parentId: projectFormData.parentId || undefined,
|
||||
projectName: projectFormData.projectName,
|
||||
projectOwnerUnit: projectFormData.projectOwnerUnit,
|
||||
projectMainEntity: projectFormData.projectMainUnit,
|
||||
projectStartTime: projectFormData.projectStartDate,
|
||||
projectEndTime: projectFormData.projectEndDate,
|
||||
investmentCategory: projectFormData.investmentCategory,
|
||||
projectNature: projectFormData.projectNature,
|
||||
projectLeaderName: projectFormData.projectManagerName,
|
||||
projectLeaderPhone: projectFormData.contactNumber,
|
||||
projectSource: projectFormData.projectSource,
|
||||
constructionNature: projectFormData.constructionNature,
|
||||
keyProject: projectFormData.keyProject,
|
||||
majorInvestmentProjects: projectFormData.majorInvestmentProject,
|
||||
isMainBusiness: projectFormData.withinMainBusiness,
|
||||
mainBusinessTypes: projectFormData.mainBusinessType,
|
||||
mainBusinessCode: projectFormData.mainBusinessCode,
|
||||
projectInvestmentDirection: projectFormData.projectDirection,
|
||||
investmentDirectionSegmentation: projectFormData.directionSubdivision,
|
||||
isStrategicEmergingIndustries: projectFormData.strategicEmergingIndustry,
|
||||
urbanStrategy: projectFormData.urbanStrategy,
|
||||
isManufacturingIndustry: projectFormData.isManufacturing,
|
||||
investmentArea: projectFormData.investmentRegion,
|
||||
projectAddress: projectFormData.projectAddress,
|
||||
projectAddressDetail: projectFormData.projectDetailedAddress,
|
||||
isControllingStake: projectFormData.isControllingShareholder,
|
||||
shareholdingRatio: toNumber(projectFormData.ourShareholdingRatio),
|
||||
projectTotalAmount: toNumber(projectFormData.totalInvestmentAmount),
|
||||
lastYearCompleted: toNumber(projectFormData.cumulativeInvestmentLastYear),
|
||||
ourInvestmentTotalAmount: toNumber(projectFormData.ourTotalInvestmentAmount),
|
||||
ourLastYearCompleted: toNumber(projectFormData.ourCumulativeInvestmentLastYear),
|
||||
projectDesc: projectFormData.projectDesc,
|
||||
attachmentUrl: projectFormData.projectProposal,
|
||||
enterpriseOwnFunds: toNumber(projectFormData.enterpriseSelfFund),
|
||||
governmentInvestmentFunds: toNumber(projectFormData.governmentInvestmentFund),
|
||||
externalRaisedFunds: toNumber(projectFormData.externalRaisedFund),
|
||||
otherFunds: toNumber(projectFormData.otherFunds),
|
||||
decisionType: projectFormData.decisionType,
|
||||
isProjectApprovalCompleted: projectFormData.isCompleteEstablishmentProcedures,
|
||||
projectApprovalFileNo: projectFormData.establishmentDocumentNumber,
|
||||
projectApprovalFileInfo: projectFormData.establishmentDocumentInfo,
|
||||
isDecisionProcedureCompleted: projectFormData.isCompleteDecisionProcedures,
|
||||
decisionProcedureFileNo: projectFormData.decisionProgramDocumentNumber,
|
||||
decisionFileInfo: projectFormData.decisionDocumentInfo,
|
||||
processInstanceId: projectFormData.processInstanceId,
|
||||
progressDesc: projectFormData.progressDesc,
|
||||
partnerIds: extractPartnerIds(),
|
||||
status:1,
|
||||
flowType: 0,
|
||||
temporaryStorage:undefined,
|
||||
templateId:undefined,
|
||||
businessType:undefined,
|
||||
deptId:projectFormData.deptId
|
||||
});
|
||||
|
||||
const basicInfoFormRef = ref()
|
||||
const handleInitiateApproval = async () => {
|
||||
if (submitLoading.value) return;
|
||||
const re = await headerFormRef.value?.validate()
|
||||
if (!re) return;
|
||||
const basicInfoFormData = await basicInfoFormRef.value?.validate()
|
||||
Object.assign(projectFormData, basicInfoFormData)
|
||||
submitLoading.value = true;
|
||||
try {
|
||||
let flowIdKey = props.isUpdate ? 'VITE_FLOWID_5' : 'VITE_FLOWID_1'
|
||||
const data = await getUserDeptBelong()
|
||||
if(data.data === 1){
|
||||
flowIdKey = props.isUpdate ?'VITE_FLOWID_5' : 'VITE_FLOWID_1'
|
||||
}else if (data.data === 2){
|
||||
flowIdKey = props.isUpdate ?'VITE_FLOWID_6' : 'VITE_FLOWID_2'
|
||||
}else if (data.data === 3){
|
||||
flowIdKey = props.isUpdate ?'VITE_FLOWID_7' : 'VITE_FLOWID_3'
|
||||
}else if (data.data === 4){
|
||||
flowIdKey = props.isUpdate ?'VITE_FLOWID_8' : 'VITE_FLOWID_4'
|
||||
}
|
||||
const { processInstanceId } = await flowFn(flowIdKey, { paramMap: {} });
|
||||
const flowName = props.isUpdate ? 'reserveUpdate' : 'reserveRegistration'
|
||||
const flowNameObj = flowNameOptions.filter(item => item.label === flowName)[0]
|
||||
await addFlowForm({
|
||||
title: headerForm.title,
|
||||
description: headerForm.description,
|
||||
attachments: JSON.stringify(headerForm.attachments),
|
||||
processInstanceId,
|
||||
flowType: flowNameObj.value
|
||||
})
|
||||
const payload = buildSubmitPayload();
|
||||
payload.processInstanceId = processInstanceId
|
||||
payload.flowType = flowNameObj.value
|
||||
if (payload) {
|
||||
await addReserveInvestmentProjectAPI({
|
||||
...payload,
|
||||
attachmentUrl: payload.attachmentUrl ? JSON.stringify(payload.attachmentUrl) : '',
|
||||
});
|
||||
message.success(t('common.success'));
|
||||
resetHeaderForm();
|
||||
resetProjectForm();
|
||||
}
|
||||
} catch (error: any) {
|
||||
message.error(error?.msg || error?.message || t('common.fail'));
|
||||
} finally {
|
||||
submitLoading.value = false;
|
||||
}
|
||||
};
|
||||
const saveLoading = ref(false);
|
||||
const handleSaveDraft = async () => {
|
||||
if (saveLoading.value) return;
|
||||
const basicInfoFormData = await basicInfoFormRef.value?.validate()
|
||||
Object.assign(projectFormData, basicInfoFormData)
|
||||
saveLoading.value = true;
|
||||
try {
|
||||
const flowName = props.isUpdate ? 'reserveUpdate' : 'reserveRegistration'
|
||||
const flowNameObj = flowNameOptions.filter(item => item.label === flowName)[0]
|
||||
const payload = buildSubmitPayload();
|
||||
payload.flowType = flowNameObj.value
|
||||
payload.status = 0
|
||||
if (payload) {
|
||||
await addReserveInvestmentProjectAPI({
|
||||
...payload,
|
||||
attachmentUrl: payload.attachmentUrl ? JSON.stringify(payload.attachmentUrl) : '',
|
||||
temporaryStorage: {
|
||||
id: payload.id,
|
||||
businessType:flowNameObj.value,
|
||||
title:headerForm.title,
|
||||
}
|
||||
});
|
||||
message.success(t('common.success'));
|
||||
resetHeaderForm();
|
||||
resetProjectForm();
|
||||
}
|
||||
}catch (error: any){
|
||||
message.error(error?.msg || error?.message || t('common.fail'));
|
||||
} finally{
|
||||
saveLoading.value = false;
|
||||
}
|
||||
};
|
||||
const tempId = computed(() => temp.temp_id);
|
||||
const handleLoadTemplate = () => {
|
||||
const flowName = props.isUpdate ? 'reserveUpdate' : 'reserveRegistration'
|
||||
const flowNameObj = flowNameOptions.filter(item => item.label === flowName)[0]
|
||||
temp.changeTempShow(true,flowNameObj.value);
|
||||
};
|
||||
watch(()=> tempId.value,()=>{
|
||||
getReserveInvestmentProjectsByTemplateIdAPI(tempId.value).then(data => {
|
||||
Object.assign(projectFormData, data);
|
||||
})
|
||||
})
|
||||
const viewLoading = ref(false);
|
||||
const handleSaveTemplate = async () => {
|
||||
const re = await headerFormRef.value?.validate()
|
||||
if (!re) return;
|
||||
if (viewLoading.value) return;
|
||||
const basicInfoFormData = await basicInfoFormRef.value?.validate()
|
||||
Object.assign(projectFormData, basicInfoFormData)
|
||||
viewLoading.value = true;
|
||||
try {
|
||||
const flowName = props.isUpdate ? 'reserveUpdate' : 'reserveRegistration'
|
||||
const flowNameObj = flowNameOptions.filter(item => item.label === flowName)[0]
|
||||
const {data: templateId}= await addTemplate({templateName:headerForm.title,templateType:flowNameObj.value});
|
||||
const payload = buildSubmitPayload();
|
||||
payload.templateId = templateId;
|
||||
payload.flowType = flowNameObj.value
|
||||
payload.status = 0;
|
||||
if (payload) {
|
||||
await addReserveInvestmentProjectAPI(payload);
|
||||
message.success(t('common.success'));
|
||||
resetHeaderForm();
|
||||
resetProjectForm();
|
||||
}
|
||||
}catch (error: any){
|
||||
message.error(error?.msg || error?.message || t('common.fail'));
|
||||
} finally{
|
||||
viewLoading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
const handleViewWorkflow = () => {
|
||||
message.info(t('reserveRegistration.viewWorkflowClicked'));
|
||||
// TODO: 实现查看流程逻辑
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.layout-container .layout-padding-view {
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.form-header-actions {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user