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,960 @@
<template>
<div class="post-investment-evaluation-form">
<div class="form-section-title">{{ t('postInvestmentEvaluationForm.sectionTitle') }}</div>
<el-form :model="submitFormData" :rules="rules" ref="submitFormDataRef" label-width="200px" class="evaluation-form">
<el-row :gutter="20" class="form-row">
<el-col :span="12">
<el-form-item prop="actualTotalIncome" :label="t('postInvestmentEvaluationForm.actualTotalRevenue')" required>
<el-input v-model="submitFormData.actualTotalIncome"
:placeholder="t('postInvestmentEvaluationForm.inputPlaceholder')">
<template #append>{{ t('postInvestmentEvaluationForm.unitSuffix') }}</template>
</el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item prop="actualInvestmentGain" :label="t('postInvestmentEvaluationForm.actualInvestmentIncome')" required>
<el-input v-model="submitFormData.actualInvestmentGain"
:placeholder="t('postInvestmentEvaluationForm.inputPlaceholder')">
<template #append>{{ t('postInvestmentEvaluationForm.unitSuffix') }}</template>
</el-input>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20" class="form-row">
<el-col :span="24">
<el-form-item prop="actualInvestmentReturnRate" :label="t('postInvestmentEvaluationForm.actualInvestmentReturnRate')" required>
<el-input v-model="actualInvestmentReturnRate" readonly >
<template #suffix>%</template>
</el-input>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20" class="form-row">
<el-col :span="24">
<el-form-item :label="t('postInvestmentEvaluationForm.investmentResults')" >
<el-input v-model="submitFormData.investmentResults" type="text"
:placeholder="t('postInvestmentEvaluationForm.inputPlaceholder')">
</el-input>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20" class="form-row">
<el-col :span="24">
<el-form-item :label="t('postInvestmentEvaluationForm.profitLossSituation')">
<el-input v-model="submitFormData.profitLossSituation" type="text"
:placeholder="t('postInvestmentEvaluationForm.inputPlaceholder')">
</el-input>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20" class="form-row">
<el-col :span="24">
<el-form-item :label="t('postInvestmentEvaluationForm.existingProblems')">
<el-input v-model="submitFormData.existingProblems" type="text"
:placeholder="t('postInvestmentEvaluationForm.inputPlaceholder')">
</el-input>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20" class="form-row">
<el-col :span="24">
<el-form-item :label="t('postInvestmentEvaluationForm.improvementSuggestions')">
<el-input v-model="submitFormData.improvementSuggestions" type="text"
:placeholder="t('postInvestmentEvaluationForm.inputPlaceholder')">
</el-input>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20" class="form-row">
<el-col :span="24">
<el-form-item :label="t('postInvestmentEvaluationForm.conclusion')">
<el-input v-model="submitFormData.conclusion" type="text"
:placeholder="t('postInvestmentEvaluationForm.inputPlaceholder')">
</el-input>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20" class="form-row">
<el-col :span="24">
<el-form-item :label="t('postInvestmentEvaluationForm.attachmentUpload')">
<UploadFile :modelValue="submitFormData.attachmentUrl" @change="(_:any,data:any[])=>uploadChange(1,_,data)" :fileSize="20" type="simple" :limit="10"
:isShowTip="false" />
</el-form-item>
</el-col>
</el-row>
</el-form>
<div class="basic-info-section">
<div class="form-section-title">{{ t('postInvestmentEvaluationForm.basicInfo.title') }}</div>
<div class="basic-info-table">
<div class="info-row">
<div class="info-label">{{ t('postInvestmentEvaluationForm.basicInfo.projectName') }}</div>
<div class="info-value info-value-full">{{ formData.projectName || 'XXX' }}</div>
</div>
<div class="info-row">
<div class="info-label">{{ t('postInvestmentEvaluationForm.basicInfo.constructionStage') }}</div>
<div class="info-value">{{ initTypeString(constructionStageOptions,lastListItem.constructionStage) || 'XXX' }}</div>
<div class="info-label">{{ t('postInvestmentEvaluationForm.basicInfo.projectNature') }}</div>
<div class="info-value">{{ initTypeString(projectNatureOptions,formData.projectNature) || 'XXX' }}</div>
</div>
<div class="info-row">
<div class="info-label required">{{
t('postInvestmentEvaluationForm.basicInfo.projectImplementationUnit') }}
</div>
<div class="info-value">{{ formData.projectMainEntity || 'XXX' }}</div>
<div class="info-label">{{ t('postInvestmentEvaluationForm.basicInfo.projectOwnerUnit') }}</div>
<div class="info-value">{{ formData.projectOwnerUnit || 'XXX' }}</div>
</div>
<div class="info-row">
<div class="info-label required">{{ t('postInvestmentEvaluationForm.basicInfo.investmentCategory')
}}</div>
<div class="info-value required">{{ initTypeString(investmentCategoryOptions,formData.investmentCategory) || 'XXX' }}</div>
<div class="info-label required">{{ t('postInvestmentEvaluationForm.basicInfo.investmentRegion') }}
</div>
<div class="info-value required">{{ initTypeString(investmentAreaOptions,formData.investmentArea) || 'XXX' }}</div>
</div>
<div class="info-row">
<div class="info-label required">{{ t('postInvestmentEvaluationForm.basicInfo.projectAddress') }}
</div>
<div class="info-value required">{{ formData.projectAddress || 'XXX' }}</div>
<div class="info-label required">{{ t('postInvestmentEvaluationForm.basicInfo.projectDetailAddress')
}}
</div>
<div class="info-value required">{{ formData.projectAddressDetail || 'XXX' }}</div>
</div>
<div class="info-row">
<div class="info-label required">{{ t('postInvestmentEvaluationForm.basicInfo.projectDirection') }}
</div>
<div class="info-value required">{{ formData.projectInvestmentDirection || 'XXX' }}</div>
<div class="info-label required">{{ t('postInvestmentEvaluationForm.basicInfo.directionSubdivision')
}}
</div>
<div class="info-value required">{{initTypeString(projectDirectionDetailsOptions,formData.investmentDirectionSegmentation) || 'XXX' }}</div>
</div>
<div class="info-row">
<div class="info-label required">{{ t('postInvestmentEvaluationForm.basicInfo.projectSource') }}
</div>
<div class="info-value required">{{ initTypeString(projectSourceOptions,formData.projectSource) || 'XXX' }}</div>
<div class="info-label required">{{ t('postInvestmentEvaluationForm.basicInfo.constructionNature')
}}</div>
<div class="info-value required">{{ initTypeString(constructionNatureOptions,formData.constructionNature) || 'XXX' }}</div>
</div>
<div class="info-row">
<div class="info-label required">{{
t('postInvestmentEvaluationForm.basicInfo.majorInvestmentProject') }}
</div>
<div class="info-value required">{{ formData.majorInvestmentProjects || 'XXX' }}</div>
<div class="info-label required">{{ t('postInvestmentEvaluationForm.basicInfo.keyProject') }}</div>
<div class="info-value required">{{ initTypeString(projectImportantOptions,formData.keyProject) || 'XXX' }}</div>
</div>
<div class="info-row">
<div class="info-label required">{{ t('postInvestmentEvaluationForm.basicInfo.isWithinMainBusiness')
}}
</div>
<div class="info-value required">{{ formData.isMainBusiness || 'XXX' }}</div>
<div class="info-label required">{{ t('postInvestmentEvaluationForm.basicInfo.mainBusinessType') }}
</div>
<div class="info-value required">{{ initTypeString(mainBusinessOptions,formData.mainBusinessTypes) || 'XXX' }}</div>
</div>
<div class="info-row">
<div class="info-label required">{{ t('postInvestmentEvaluationForm.basicInfo.mainBusinessCode') }}
</div>
<div class="info-value required">{{ formData.mainBusinessCode || 'XXX' }}</div>
<div class="info-label required">{{ t('postInvestmentEvaluationForm.basicInfo.isManufacturing') }}
</div>
<div class="info-value required">{{ formData.isManufacturingIndustry || 'XXX' }}</div>
</div>
<div class="info-row">
<div class="info-label required">{{
t('postInvestmentEvaluationForm.basicInfo.strategicEmergingIndustry') }}
</div>
<div class="info-value required">{{ initTypeString(strategicIndustryOptions,formData.isStrategicEmergingIndustries) || 'XXX' }}</div>
<div class="info-label required">{{ t('postInvestmentEvaluationForm.basicInfo.cityStrategy') }}
</div>
<div class="info-value required">{{ initTypeString(cityStrategyOptions,formData.urbanStrategy) || 'XXX' }}</div>
</div>
<div class="info-row">
<div class="info-label required">{{
t('postInvestmentEvaluationForm.basicInfo.projectImplementationStart') }}
</div>
<div class="info-value">{{ formData.projectStartTime || 'XXX' }}</div>
<div class="info-label required">{{
t('postInvestmentEvaluationForm.basicInfo.projectImplementationEnd') }}
</div>
<div class="info-value">{{ formData.projectEndTime || 'XXX' }}</div>
</div>
</div>
<div class="additional-info-table">
<div class="info-row info-row-single">
<div class="info-label required">{{ t('postInvestmentEvaluationForm.additionalInfo.projectOverview')
}}
</div>
<div class="info-value">{{ formData.projectDesc || 'XXX' }}</div>
</div>
<div class="info-row info-row-single">
<div class="info-label">{{ t('postInvestmentEvaluationForm.additionalInfo.projectPreliminaryPlan')
}}</div>
<div class="info-value">
<UploadFile :modelValue="JSON.parse(formData.projectPreliminaryPlanAttachment || '[]') || []" :fileSize="20" type="simple"
:limit="10" :isShowTip="false" disabled/>
</div>
</div>
<div class="info-row info-row-single">
<div class="info-label">{{ t('postInvestmentEvaluationForm.additionalInfo.remark') }}</div>
<div class="info-value">{{ formData.remark || 'XXX' }}</div>
</div>
</div>
<div class="annual-investment-plan-section">
<div class="form-section-title">{{ t('postInvestmentEvaluationForm.annualPlan.title') }}</div>
<el-table :data="formData.projectInvestmentEntities" border style="width: 100%" class="annual-plan-table">
<el-table-column type="index" :label="t('postInvestmentEvaluationForm.annualPlan.index')" width="60"
align="center" />
<el-table-column :label="t('postInvestmentEvaluationForm.annualPlan.plannedInvestmentYear')"
prop="plannedInvestmentYear" min-width="120" align="center" />
<el-table-column :label="t('postInvestmentEvaluationForm.annualPlan.plannedImageAmount')"
prop="plannedImageAmount" min-width="140" align="center">
<template #default="{ row }">
{{ row.plannedImageAmount ? `${row.plannedImageAmount}
${t('postInvestmentEvaluationForm.unitSuffix')}` : '' }}
</template>
</el-table-column>
<el-table-column :label="t('postInvestmentEvaluationForm.annualPlan.plannedPaymentAmount')"
prop="plannedPaymentAmount" min-width="140" align="center">
<template #default="{ row }">
{{ row.plannedPaymentAmount ? `${row.plannedPaymentAmount}
${t('postInvestmentEvaluationForm.unitSuffix')}` : '' }}
</template>
</el-table-column>
<el-table-column :label="t('postInvestmentEvaluationForm.annualPlan.fundingSource')" align="center">
<el-table-column :label="t('postInvestmentEvaluationForm.annualPlan.ownFunds')" prop="ownFunds"
min-width="120" align="center">
<template #default="{ row }">
{{ row.selfFunding ? `${row.selfFunding} ${t('postInvestmentEvaluationForm.unitSuffix')}` : ''
}}
</template>
</el-table-column>
<el-table-column :label="t('postInvestmentEvaluationForm.annualPlan.fiscalFunds')"
prop="fiscalFunds" min-width="120" align="center">
<template #default="{ row }">
{{ row.fiscalFunding ? `${row.fiscalFunding}
${t('postInvestmentEvaluationForm.unitSuffix')}` : '' }}
</template>
</el-table-column>
<el-table-column :label="t('postInvestmentEvaluationForm.annualPlan.externalFundraising')"
prop="externalFundraising" min-width="140" align="center">
<template #default="{ row }">
{{ row.externalFunding ? `${row.externalFunding}
${t('postInvestmentEvaluationForm.unitSuffix')}` : '' }}
</template>
</el-table-column>
<el-table-column :label="t('postInvestmentEvaluationForm.annualPlan.otherFunds')"
prop="otherFunds" min-width="120" align="center">
<template #default="{ row }">
{{ row.otherFunding ? `${row.otherFunding} ${t('postInvestmentEvaluationForm.unitSuffix')}`
: '' }}
</template>
</el-table-column>
<el-table-column
:label="t('postInvestmentEvaluationForm.annualPlan.fiscalFundsSourceExplanation')"
prop="fiscalFundingSource" min-width="180" align="center" />
<el-table-column
:label="t('postInvestmentEvaluationForm.annualPlan.otherFundsSourceExplanation')"
prop="otherFundingSource" min-width="180" align="center" />
</el-table-column>
</el-table>
</div>
<div class="decision-info-section">
<div class="form-section-title">{{ t('postInvestmentEvaluationForm.decisionInfo.title') }}</div>
<div class="decision-info-table">
<div class="info-row">
<div class="info-label">{{ t('postInvestmentEvaluationForm.decisionInfo.decisionType') }}</div>
<div class="info-value">{{ formData.decisionType || 'XXX' }}</div>
<div class="info-label">{{
t('postInvestmentEvaluationForm.decisionInfo.isProjectApprovalProcedureCompleted') }}</div>
<div class="info-value">{{ formData.isProjectApprovalCompleted || 'XXX'
}}</div>
</div>
<div class="info-row">
<div class="info-label">{{
t('postInvestmentEvaluationForm.decisionInfo.projectApprovalDocumentNumber')
}}</div>
<div class="info-value">{{ formData.projectApprovalFileNo || 'XXX' }}
</div>
<div class="info-label">{{
t('postInvestmentEvaluationForm.decisionInfo.projectApprovalDocumentInfo') }}
</div>
<div class="info-value">{{ formData.projectApprovalFileInfo || 'XXX' }}</div>
</div>
<div class="info-row">
<div class="info-label">{{
t('postInvestmentEvaluationForm.decisionInfo.isDecisionProcedureCompleted')
}}</div>
<div class="info-value">{{ formData.isDecisionProcedureCompleted || 'XXX' }}</div>
<div class="info-label">{{
t('postInvestmentEvaluationForm.decisionInfo.decisionProcedureDocumentNumber') }}</div>
<div class="info-value">{{ formData.decisionProcedureFileNo || 'XXX' }}
</div>
</div>
<div class="info-row">
<div class="info-label">{{ t('postInvestmentEvaluationForm.decisionInfo.decisionDocumentInfo')
}}</div>
<div class="info-value">{{ formData.decisionFileInfo || 'XXX' }}</div>
<div class="info-label"></div>
<div class="info-value"></div>
</div>
</div>
</div>
<div class="progress-report-info-section">
<div class="form-section-title">{{ t('postInvestmentEvaluationForm.progressReportInfo.title') }}</div>
<div class="progress-report-info-table">
<div class="info-row">
<div class="info-label required">{{
t('postInvestmentEvaluationForm.progressReportInfo.projectStatus')
}}</div>
<div class="info-value">{{ initTypeString(projectStatusOptions,lastListItem.projectStatus) || 'XXX' }}</div>
<div class="info-label">{{
t('postInvestmentEvaluationForm.progressReportInfo.constructionStage') }}
</div>
<div class="info-value">{{ initTypeString(constructionStageOptions,lastListItem.constructionStage) || 'XXX' }}</div>
</div>
<div class="info-row info-row-single">
<div class="info-label required">{{
t('postInvestmentEvaluationForm.progressReportInfo.totalInvestmentAmount') }}</div>
<div class="info-value">{{ lastListItem.projectTotalAmount }}</div>
</div>
<div class="info-row">
<div class="info-label required">{{
t('postInvestmentEvaluationForm.progressReportInfo.cumulativeInvestmentToMonthEnd') }}</div>
<div class="info-value">{{ lastListItem.cumulativeInvestmentToDate
}}</div>
<div class="info-label required">{{
t('postInvestmentEvaluationForm.progressReportInfo.investmentCompletionRate') }}</div>
<div class="info-value">{{ lastListItem.investmentCompletionRate || 'XXX' }}
</div>
</div>
<div class="info-row">
<div class="info-label">{{
t('postInvestmentEvaluationForm.progressReportInfo.cumulativePaymentToMonthEnd') }}</div>
<div class="info-value">{{ lastListItem.cumulativeInvestmentToDate || 'XXX' }}
</div>
<div class="info-label">{{
t('postInvestmentEvaluationForm.progressReportInfo.paymentCompletionRate') }}
</div>
<div class="info-value">{{ lastListItem.paymentCompletionRate || 'XXX' }}</div>
</div>
<div class="info-row info-row-single">
<div class="info-label">{{ t('postInvestmentEvaluationForm.progressReportInfo.effectiveness') }}
</div>
<div class="info-value">{{ lastListItem.achievements || 'XXX' }}</div>
</div>
<div class="info-row info-row-single">
<div class="info-label">{{
t('postInvestmentEvaluationForm.progressReportInfo.coordinationMatters') }}
</div>
<div class="info-value">{{lastListItem.coordinationIssues || 'XXX' }}</div>
</div>
<div class="info-row info-row-single">
<div class="info-label">{{
t('postInvestmentEvaluationForm.progressReportInfo.nextWorkArrangements') }}
</div>
<div class="info-value">{{ lastListItem.nextWorkPlan || 'XXX' }}</div>
</div>
<div class="info-row info-row-single">
<div class="info-label">{{
t('postInvestmentEvaluationForm.progressReportInfo.currentStageEvidenceMaterials') }}</div>
<div class="info-value">
<UploadFile :modelValue="JSON.parse(lastListItem.supportingDocuments || '[]') || []"
:fileSize="20" type="simple" :limit="10" :isShowTip="false" disabled/>
</div>
</div>
<div class="info-row info-row-single">
<div class="info-label">{{ t('postInvestmentEvaluationForm.progressReportInfo.remark') }}</div>
<div class="info-value">{{ lastListItem.remarks || 'XXX' }}</div>
</div>
</div>
</div>
<div class="project-records-section">
<el-tabs v-model="activeTab" class="project-records-tabs">
<el-tab-pane :label="t('postInvestmentEvaluationForm.projectRecords.adjustmentRecord')"
name="adjustment">
<el-table :data="projectRecordsData.adjustmentRecords" border style="width: 100%"
class="project-records-table">
<el-table-column type="index"
:label="t('postInvestmentEvaluationForm.projectRecords.index')" width="60"
align="center" />
<el-table-column prop="projectName"
:label="t('postInvestmentEvaluationForm.projectRecords.projectName')" min-width="150"
align="center">
<template #default="{ row }">
<el-button link type="primary">{{ row.projectName || 'XXX' }}</el-button>
</template>
</el-table-column>
<el-table-column prop="projectOverview"
:label="t('postInvestmentEvaluationForm.projectRecords.projectOverview')"
min-width="150" align="center" />
<el-table-column prop="projectPlan"
:label="t('postInvestmentEvaluationForm.projectRecords.projectPlan')" min-width="120"
align="center" />
<el-table-column prop="attachments"
:label="t('postInvestmentEvaluationForm.projectRecords.attachments')" min-width="100"
align="center" />
<el-table-column prop="projectNature"
:label="t('postInvestmentEvaluationForm.projectRecords.projectNature')" min-width="120"
align="center" />
<el-table-column prop="projectDirection"
:label="t('postInvestmentEvaluationForm.projectRecords.projectDirection')"
min-width="120" align="center" />
<el-table-column prop="projectImplementationStart"
:label="t('postInvestmentEvaluationForm.projectRecords.projectImplementationStart')"
min-width="160" align="center" />
<el-table-column prop="projectImplementationEnd"
:label="t('postInvestmentEvaluationForm.projectRecords.projectImplementationEnd')"
min-width="160" align="center" />
<el-table-column prop="totalInvestmentAmount"
:label="t('postInvestmentEvaluationForm.projectRecords.totalInvestmentAmount')"
min-width="140" align="center" />
<el-table-column prop="handler"
:label="t('postInvestmentEvaluationForm.projectRecords.handler')" min-width="100"
align="center" />
<el-table-column prop="updateTime"
:label="t('postInvestmentEvaluationForm.projectRecords.updateTime')" min-width="160"
align="center" />
</el-table>
</el-tab-pane>
<el-tab-pane :label="t('postInvestmentEvaluationForm.projectRecords.progressDeclarationRecord')"
name="progress">
<el-table :data="projectRecordsData.progressRecords" border style="width: 100%"
class="project-records-table">
<el-table-column type="index"
:label="t('postInvestmentEvaluationForm.projectRecords.index')" width="60"
align="center" />
<el-table-column prop="projectName" :label="t('progressReportRecord.table.projectName')"
min-width="200" />
<el-table-column prop="annualReport" :label="t('progressReportRecord.table.reportDate')" min-width="120"
sortable />
<el-table-column prop="implementingBody"
:label="t('progressReportRecord.table.projectImplementationUnit')" min-width="200" />
<el-table-column prop="isFinalApplication" :label="t('progressReportRecord.table.isLastDeclaration')"
min-width="160" >
<template #default="{ row }">
{{row.isFinalApplication === 1 ? t('planApply.common.yes') : t('planApply.common.no')}}
</template>
</el-table-column>
<el-table-column prop="projectStatus" :label="t('progressReportRecord.table.projectStatus')"
min-width="120" >
<template #default="{row}">
{{initTypeString(projectStatusOptions,row.projectStatus)}}
</template>
</el-table-column>
<el-table-column prop="constructionStage" :label="t('progressReportRecord.table.constructionStage')"
min-width="120" >
<template #default="{row}">
{{initTypeString(constructionStageOptions,row.constructionStage)}}
</template>
</el-table-column>
<el-table-column prop="investmentPlanCompletionRate"
:label="t('progressReportRecord.table.currentYearPlannedImageTotal')" min-width="180" />
<el-table-column prop="ytdRemainingInvestment"
:label="t('progressReportRecord.table.enterpriseCumulativeInvestmentToMonthEnd')" min-width="200" />
<el-table-column prop="investmentCompletionRate"
:label="t('progressReportRecord.table.currentYearImageCompletion')" min-width="180" />
<el-table-column prop="projectTotalAmount"
:label="t('progressReportRecord.table.totalInvestmentAmount')" min-width="160" />
<el-table-column prop="cumulativeInvestmentToDate"
:label="t('progressReportRecord.table.cumulativeInvestmentToMonthEnd')" min-width="200" />
<el-table-column prop="completionRate" :label="t('progressReportRecord.table.totalCompletionRate')"
min-width="140" />
<el-table-column prop="achievements" :label="t('progressReportRecord.table.effectiveness')"
min-width="120" />
<el-table-column prop="coordinationIssues" :label="t('progressReportRecord.table.coordinationMatters')"
min-width="160" />
<el-table-column prop="nextWorkPlan"
:label="t('progressReportRecord.table.nextWorkArrangements')" min-width="160" />
<el-table-column prop="updateBy" :label="t('progressReportRecord.table.lastUpdater')"
min-width="140" />
<el-table-column prop="updateTime" :label="t('progressReportRecord.table.lastUpdateTime')"
min-width="180" />
</el-table>
</el-tab-pane>
<el-tab-pane
:label="t('postInvestmentEvaluationForm.projectRecords.postInvestmentEvaluationRecord')"
name="evaluation">
<el-table :data="projectRecordsData.evaluationRecords" border style="width: 100%"
class="project-records-table">
<el-table-column type="index"
:label="t('postInvestmentEvaluationForm.projectRecords.index')" width="60"
align="center" />
<el-table-column prop="actualTotalIncome"
:label="t('postInvestmentEvaluationForm.projectRecords.actualTotalIncome')"
min-width="140" align="center" />
<el-table-column prop="actualInvestmentGain"
:label="t('postInvestmentEvaluationForm.projectRecords.actualInvestmentIncome')"
min-width="140" align="center" />
<el-table-column prop="actualInvestmentReturnRate"
:label="t('postInvestmentEvaluationForm.projectRecords.actualInvestmentIncomeRate')"
min-width="160" align="center" />
<el-table-column prop="attachmentUrl"
:label="t('postInvestmentEvaluationForm.projectRecords.attachments')" min-width="100"
align="center" >
<template #default="{row}">
<UploadFile :modelValue="JSON.parse(row.attachmentUrl || '[]') || []" :fileSize="20" type="simple" :limit="10"
:isShowTip="false" disabled />
</template>
</el-table-column>
<el-table-column prop="createBy"
:label="t('postInvestmentEvaluationForm.projectRecords.handler')" min-width="100"
align="center" />
<el-table-column prop="createTime"
:label="t('postInvestmentEvaluationForm.projectRecords.reportingTime')" min-width="160"
align="center" />
</el-table>
</el-tab-pane>
</el-tabs>
</div>
</div>
</div>
</template>
<script lang="ts" setup>
import { reactive, watch, ref } from 'vue';
import { useI18n } from 'vue-i18n';
import UploadFile from '/@/components/Upload/index.vue';
import {
cityStrategyOptions,
constructionNatureOptions, constructionStageOptions,
Enums, investmentAreaOptions, investmentCategoryOptions, mainBusinessOptions, projectDirectionDetailsOptions,
projectImportantOptions, projectNatureOptions,
projectSourceOptions, projectStatusOptions, strategicIndustryOptions
} from '/@/hooks/enums';
import { PostInvestmentEvaluation, ProjectInvestmentInfo } from '/@/views/invBid/postInvestmentEvaluation/interface/type';
import { InvestmentProjectProgress } from '/@/views/invMid/progressReport/interface/type';
import { FormInstance, FormRules } from 'element-plus';
// 国际化
const { t } = useI18n();
/**
* 项目记录标签页状态
*/
const activeTab = ref('adjustment');
/**
* 项目记录数据
*/
const projectRecordsData:{
adjustmentRecords: InvestmentProjectProgress[];
progressRecords: InvestmentProjectProgress[];
evaluationRecords: PostInvestmentEvaluation[];
} = reactive({
// 调整记录
adjustmentRecords: [],
// 进度记录
progressRecords: [],
// 后评价记录
evaluationRecords: []
});
/**
* 组件属性定义
*/
const props = defineProps<{
/**
* 表单数据模型
*/
modelValue: ProjectInvestmentInfo;
}>();
/**
* 事件发射器定义
*/
const emit = defineEmits<{
/**
* 更新表单数据事件
* @param e
* @param value 新的表单数据
*/
(e: 'update:modelValue', value: ProjectInvestmentInfo): void;
}>();
/**
* 默认表单数据
*/
const defaultForm: ProjectInvestmentInfo = {
// 来自ProjectPlanApplyFormItem的字段这些字段已经在ProjectPlanApplyFormItem中定义
id: undefined,
projectName: '',
projectNature: '',
groupCompany: '',
projectOwnerUnit: '',
projectMainEntity: '',
investmentCategory: '',
investmentArea: '',
projectAddress: '',
projectAddressDetail: '',
projectInvestmentDirection: '',
investmentDirectionSegmentation: '',
constructionNature: '',
keyProject: '',
isMainBusiness: '',
mainBusinessTypes: '',
mainBusinessCode: '',
isManufacturingIndustry: '',
urbanStrategy: '',
projectSource: '',
majorInvestmentProjects: '',
isStrategicEmergingIndustries: '',
projectStartTime: '',
projectEndTime: '',
planInvestmentYear: '',
planPaymentLimit: '',
ownedFunds: '',
financialFunds: '',
externalRaisedCapital: '',
otherFunds: '',
governmentFundSourceDesc: '',
otherFundSourceDesc: '',
projectTotalAmount: '',
lastYearCompleted: '',
ourInvestmentTotalAmount: '',
ourLastYearCompleted: '',
projectDesc: '',
projectPreliminaryPlan: '',
projectPreliminaryPlanAttachment: '',
remark: '',
decisionType: '',
isProjectApprovalCompleted: '',
isDecisionProcedureCompleted: '',
projectApprovalFileNo: '',
projectApprovalFileInfo: '',
decisionProcedureFileNo: '',
decisionFileInfo: '',
planImageQuota:'',
// 其他字段
projectInvestmentEntities: [],
};
/**
* 表单响应式数据
*/
const formData = reactive<ProjectInvestmentInfo>({ ...defaultForm });
/**
* 提交数据表单
* */
const submitFormData = ref<PostInvestmentEvaluation>({} as PostInvestmentEvaluation);
const requiredRule = [{ required: true, message: `${t('该字段必填')}` },{validator: (rule: any, value:any,callback: (e?: Error) => void) => {
// 检查是否为空值
if (value === '' || value === null || value === undefined) {
callback()
return
}
// 检查是否为有效数字
const numValue = Number(value)
if (!isNaN(numValue) && isFinite(numValue)) {
callback()
} else {
callback(new Error(`${t('common.isNumber')}`))
}
}}]
const rules = ref<FormRules<PostInvestmentEvaluation>>({
actualTotalIncome: requiredRule,
actualInvestmentGain:requiredRule,
actualInvestmentReturnRate:[requiredRule[0]],
})
const submitFormDataRef = ref<FormInstance>()
/**
* 初始化时将props.modelValue映射到formData
*/
if (props.modelValue) {
const mappedData: ProjectInvestmentInfo = {
...props.modelValue,
};
Object.assign(formData, mappedData);
}
const lastListItem = ref<InvestmentProjectProgress>({} as InvestmentProjectProgress)
/**
* 监听 formData 变化,同步到父组件
*/
watch(
formData,
() => {
// 构造符合ProjectPlanApplyFormItem接口的数据
const projectPlanData: ProjectInvestmentInfo = {
...formData
};
emit('update:modelValue', projectPlanData as ProjectInvestmentInfo);
},
{ deep: true }
);
/**
* 监听 props.modelValue 变化,同步到 formData
*/
watch(
() => props.modelValue,
(newVal) => {
if (newVal) {
// 将ProjectPlanApplyFormItem的字段映射到PostInvestmentEvaluationFormData
const mappedData: ProjectInvestmentInfo = {
...newVal,
};
if (newVal.id != null) {
submitFormData.value.projectId = newVal.id;
}
lastListItem.value = (newVal.investmentProjectsProgressEntities && newVal.investmentProjectsProgressEntities.length > 0) ? newVal.investmentProjectsProgressEntities[newVal.investmentProjectsProgressEntities.length - 1] : {} as InvestmentProjectProgress;
Object.assign(formData, mappedData);
projectRecordsData.progressRecords = newVal.investmentProjectsProgressEntities || []
projectRecordsData.evaluationRecords = newVal.evaluationRecordEntities || []
}
},
{ immediate: true, deep: true }
);
const actualInvestmentReturnRate = ref('');
watch(()=>submitFormData.value,(newData)=>{
// actualInvestmentReturnRate = newData.actualInvestmentGain / newData.actualTotalIncome;
submitFormData.value.actualInvestmentReturnRate = calculateReturnRate(newData.actualInvestmentGain,newData.actualTotalIncome)
actualInvestmentReturnRate.value = submitFormData.value.actualInvestmentReturnRate.toFixed(2)
},{deep:true})
/**
* 根据枚举值获取对应的标签文本
* @param enums 枚举数组
* @param type 枚举值
* @returns 对应的标签文本
*/
const initTypeString = (enums: Enums[], type: string) => {
return enums.find(item => item.value === type)?.label;
}
// 计算实际投资收益率
const calculateReturnRate = (totalIncome: string | number,investmentIncome: string | number) => {
if (!investmentIncome || !totalIncome) {
return 0;
}
// 转换为数字
const income = parseFloat(investmentIncome as string);
const total = parseFloat(totalIncome as string);
// 检查是否为有效数字
if (isNaN(income) || isNaN(total)) {
return 0;
}
// 计算投资本金 = 总收入 - 投资收益
const principal = income;
// 避免除零错误
if (principal <= 0) {
return 0;
}
// 计算投资收益率:投资收益 / 投资本金
let rate = (total / income) * 100;
return rate;
};
defineExpose({
validateRefFn: async ()=>{
const res = await submitFormDataRef.value?.validate();
if (res){
return submitFormData.value;
}
return false;
},
})
const uploadChange = (type:number,_:any,data:any[],index?:number) => {
if (!data || Object.prototype.toString.call(data) !== '[object Array]' || data.length < 1){
if (type === 1){
submitFormData.value.attachmentUrl = []
}
if (type === 2){
formData.projectPreliminaryPlanAttachment = []
}
if (type === 3){
lastListItem.value.supportingDocuments = []
}
if (type === 4 && index != null){
projectRecordsData.evaluationRecords[index].attachmentUrl = []
}
}
const newData = data.map(item =>{
return {
name: item.name,
url: item.url,
}
})
if (type === 1){
submitFormData.value.attachmentUrl = newData
}
if (type === 2){
formData.projectPreliminaryPlanAttachment = newData
}
if (type === 3){
lastListItem.value.supportingDocuments = newData
}
if (type === 4 && index != null){
projectRecordsData.evaluationRecords[index].attachmentUrl = newData
}
}
</script>
<style scoped>
.post-investment-evaluation-form {
background: #fff;
border-radius: 4px;
padding: 20px;
border: 1px solid var(--el-border-color-light);
}
.form-section-title {
font-size: 16px;
font-weight: 600;
color: var(--el-text-color-primary);
margin: 0 0 20px;
padding-left: 10px;
border-left: 4px solid var(--el-color-primary);
}
.evaluation-form {
width: 100%;
}
/* 表单 label 左对齐 */
.evaluation-form :deep(.el-form-item__label) {
text-align: left;
justify-content: flex-start;
}
/* 必填字段标签显示为红色 */
.evaluation-form :deep(.el-form-item.is-required .el-form-item__label) {
color: var(--el-color-danger);
}
.form-row {
margin-bottom: 16px;
margin-top: 16px;
}
.form-row:last-of-type {
margin-bottom: 0;
}
.basic-info-section {
margin-top: 40px;
}
.basic-info-table,
.additional-info-table {
border: 1px solid var(--el-border-color-light);
border-radius: 4px;
overflow: hidden;
margin-top: 20px;
}
.additional-info-table {
margin-top: 0;
}
.decision-info-section {
margin-top: 40px;
}
.decision-info-table {
border: 1px solid var(--el-border-color-light);
border-radius: 4px;
overflow: hidden;
margin-top: 20px;
}
.progress-report-info-section {
margin-top: 40px;
}
.progress-report-info-table {
border: 1px solid var(--el-border-color-light);
border-radius: 4px;
overflow: hidden;
margin-top: 20px;
}
.project-records-section {
margin-top: 40px;
}
.project-records-tabs {
margin-top: 20px;
}
.project-records-table {
margin-top: 20px;
}
.annual-investment-plan-section {
margin-top: 40px;
}
.annual-plan-table {
margin-top: 20px;
}
.annual-plan-table :deep(.el-table__cell) {
padding: 8px 0;
}
.annual-plan-table :deep(.el-input) {
width: 100%;
}
.info-row {
display: grid;
grid-template-columns: 1fr 1fr 1fr 1fr;
border-bottom: 1px solid var(--el-border-color-lighter);
}
.info-row-full {
grid-template-columns: 1fr 3fr;
}
.info-row-single {
grid-template-columns: 1fr 3fr;
}
.info-row:last-child {
border-bottom: none;
}
.info-label {
background-color: #f0f7ff;
padding: 12px 16px;
border-right: 1px solid var(--el-border-color-lighter);
font-weight: 500;
color: var(--el-text-color-primary);
display: flex;
align-items: center;
}
.info-label.required {
color: var(--el-color-danger);
}
.info-value {
background-color: #fff;
padding: 12px 16px;
border-right: 1px solid var(--el-border-color-lighter);
color: var(--el-text-color-primary);
display: flex;
align-items: center;
}
.info-value-full {
border-right: none;
}
.info-row .info-value:last-child {
border-right: none;
}
</style>