添加指导价法明细表

This commit is contained in:
lzm
2026-04-29 15:44:00 +08:00
parent 961c44f455
commit 422c42f19b
7 changed files with 626 additions and 201 deletions

View File

@@ -4,8 +4,6 @@ export interface ProjectPlanningVO {
id?: number id?: number
projectId: number projectId: number
ownershipType: string ownershipType: string
designPart?: string
buildingType?: string
calculationMethod: string calculationMethod: string
planningContent: string planningContent: string
planningAmount?: number planningAmount?: number

View File

@@ -0,0 +1,59 @@
import request from '@/config/axios'
export interface ProjectPlanningGuideDetailVO {
id?: number
planningId: number
projectId?: number
designPart?: string
buildingType?: string
designArea?: number
internalGuidanceUnitPrice?: number
buildingOrUnitCount?: number
drawingSetFactor?: number
scaleFactor?: number
modificationFactor?: number
complexityFactor?: number
totalAdjustmentFactor?: number
designRatio?: number
assessmentArea?: number
assessmentOutputValue?: number
sortNo?: number
remark?: string
createTime?: string
}
export interface ProjectPlanningGuideDetailBatchSaveVO {
planningId: number
details: Array<
Pick<
ProjectPlanningGuideDetailVO,
| 'id'
| 'designPart'
| 'buildingType'
| 'designArea'
| 'internalGuidanceUnitPrice'
| 'buildingOrUnitCount'
| 'drawingSetFactor'
| 'scaleFactor'
| 'modificationFactor'
| 'complexityFactor'
| 'designRatio'
| 'sortNo'
| 'remark'
>
>
}
export const getProjectPlanningGuideDetailListByPlanningId = (planningId: number) => {
return request.get({ url: '/tjt/planning-guide-detail/list-by-planning', params: { planningId } })
}
export const batchSaveProjectPlanningGuideDetail = (
data: ProjectPlanningGuideDetailBatchSaveVO
) => {
return request.post({ url: '/tjt/planning-guide-detail/batch-save', data })
}
export const deleteProjectPlanningGuideDetail = (id: number) => {
return request.delete({ url: '/tjt/planning-guide-detail/delete', params: { id } })
}

View File

@@ -1,5 +1,5 @@
<template> <template>
<Dialog v-model="dialogVisible" :title="dialogTitle" width="1120"> <Dialog v-model="dialogVisible" title="编辑测算参数" width="92%">
<el-form <el-form
ref="formRef" ref="formRef"
v-loading="formLoading" v-loading="formLoading"
@@ -11,7 +11,7 @@
<el-row :gutter="16"> <el-row :gutter="16">
<el-col :span="8"> <el-col :span="8">
<el-form-item label="归属类型"> <el-form-item label="归属类型">
<el-input :model-value="ownershipTypeLabel" disabled /> <el-input :model-value="getOwnershipTypeLabel(formData.ownershipType)" disabled />
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="8"> <el-col :span="8">
@@ -22,7 +22,7 @@
placeholder="请选择产值计算方式" placeholder="请选择产值计算方式"
> >
<el-option <el-option
v-for="item in calculationMethodOptions" v-for="item in CALCULATION_METHOD_OPTIONS"
:key="String(item.value)" :key="String(item.value)"
:label="item.label" :label="item.label"
:value="item.value" :value="item.value"
@@ -55,35 +55,6 @@
</el-col> </el-col>
</el-row> </el-row>
<el-row :gutter="16">
<el-col :span="8">
<el-form-item label="设计部位" prop="designPart">
<el-select
v-model="formData.designPart"
class="!w-1/1"
clearable
placeholder="请选择设计部位"
>
<el-option
v-for="item in DESIGN_PART_OPTIONS"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="建筑类型" prop="buildingType">
<el-input
v-model="formData.buildingType"
maxlength="100"
placeholder="请输入建筑类型"
/>
</el-form-item>
</el-col>
</el-row>
<el-divider content-position="left">测算参数</el-divider> <el-divider content-position="left">测算参数</el-divider>
<el-row :gutter="16"> <el-row :gutter="16">
<el-col :span="8"> <el-col :span="8">
@@ -99,7 +70,13 @@
</el-col> </el-col>
<el-col :span="8"> <el-col :span="8">
<el-form-item label="工程总面积(m²)" prop="planningArea"> <el-form-item label="工程总面积(m²)" prop="planningArea">
<el-input
v-if="showGuideDetailSection"
:model-value="formatAmountText(guideDetailSummary.designArea)"
disabled
/>
<el-input-number <el-input-number
v-else
v-model="formData.planningArea" v-model="formData.planningArea"
:min="0" :min="0"
:precision="2" :precision="2"
@@ -119,13 +96,9 @@
<el-row :gutter="16"> <el-row :gutter="16">
<el-col :span="8"> <el-col :span="8">
<el-form-item label="设计阶段" prop="designStage"> <el-form-item label="设计阶段" prop="designStage">
<el-select <el-select v-model="formData.designStage" class="!w-1/1" placeholder="请选择设计阶段">
v-model="formData.designStage"
class="!w-1/1"
placeholder="请选择设计阶段"
>
<el-option <el-option
v-for="item in designStageOptions" v-for="item in DESIGN_STAGE_OPTIONS"
:key="String(item.value)" :key="String(item.value)"
:label="item.label" :label="item.label"
:value="item.value" :value="item.value"
@@ -133,9 +106,6 @@
</el-select> </el-select>
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row>
<el-row :gutter="16">
<el-col :span="8"> <el-col :span="8">
<el-form-item label="本次设计阶段比例(%)" prop="currentDesignStageRatio"> <el-form-item label="本次设计阶段比例(%)" prop="currentDesignStageRatio">
<el-input-number <el-input-number
@@ -148,6 +118,9 @@
/> />
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row>
<el-row :gutter="16">
<el-col :span="8"> <el-col :span="8">
<el-form-item label="审核审定是否外包" prop="reviewOutsourceFlag"> <el-form-item label="审核审定是否外包" prop="reviewOutsourceFlag">
<el-switch <el-switch
@@ -170,9 +143,6 @@
/> />
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row>
<el-row :gutter="16">
<el-col v-if="showCalculationRatioField" :span="8"> <el-col v-if="showCalculationRatioField" :span="8">
<el-form-item :label="`${calculationRatioLabel}(%)`" prop="calculationRatio"> <el-form-item :label="`${calculationRatioLabel}(%)`" prop="calculationRatio">
<el-input-number <el-input-number
@@ -185,7 +155,10 @@
/> />
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="showCalculationRatioField ? 8 : 12"> </el-row>
<el-row :gutter="16">
<el-col :span="8">
<el-form-item label="总分配(%)" prop="totalDistributionAmount"> <el-form-item label="总分配(%)" prop="totalDistributionAmount">
<el-input-number <el-input-number
v-model="totalDistributionAmountPercent" v-model="totalDistributionAmountPercent"
@@ -199,7 +172,7 @@
</el-col> </el-col>
</el-row> </el-row>
<template v-if="showMajorFactorFields"> <template v-if="showParentMajorFactorFields">
<el-divider content-position="left">专业所测算参数</el-divider> <el-divider content-position="left">专业所测算参数</el-divider>
<el-row :gutter="16"> <el-row :gutter="16">
<el-col :span="8"> <el-col :span="8">
@@ -219,7 +192,7 @@
<el-input-number <el-input-number
v-model="formData.drawingSetFactor" v-model="formData.drawingSetFactor"
:min="0" :min="0"
:precision="2" :precision="4"
:step="0.01" :step="0.01"
class="!w-1/1" class="!w-1/1"
controls-position="right" controls-position="right"
@@ -231,7 +204,7 @@
<el-input-number <el-input-number
v-model="formData.scaleFactor" v-model="formData.scaleFactor"
:min="0" :min="0"
:precision="2" :precision="4"
:step="0.01" :step="0.01"
class="!w-1/1" class="!w-1/1"
controls-position="right" controls-position="right"
@@ -245,7 +218,7 @@
<el-input-number <el-input-number
v-model="formData.modificationFactor" v-model="formData.modificationFactor"
:min="0" :min="0"
:precision="2" :precision="4"
:step="0.01" :step="0.01"
class="!w-1/1" class="!w-1/1"
controls-position="right" controls-position="right"
@@ -267,18 +240,171 @@
</el-row> </el-row>
</template> </template>
<template v-if="showInternalGuidanceUnitPriceField"> <!-- 优化后的指导价法明细块 -->
<el-divider content-position="left">指导价法参数</el-divider> <template v-if="showGuideDetailSection">
<el-row :gutter="16"> <el-divider content-position="left">指导价法明细</el-divider>
<el-col :span="8"> <div class="mb-12px flex items-center justify-between gap-12px">
<el-form-item label="内部指导单价(元/m²)" prop="internalGuidanceUnitPrice"> <el-button plain type="primary" @click="addGuideDetailRow">
<template #icon><i class="el-icon-plus"></i></template>新增明细
</el-button>
<span class="text-12px text-gray-400">💡 提示数字字段已隐藏加减箭头以优化显示支持直接输入或复制粘贴</span>
</div>
<el-table :data="guideDetails" border max-height="460" class="optimized-table">
<!-- 1. 冻结核心上下文列 -->
<el-table-column align="center" label="序号" width="65" fixed="left">
<template #default="{ row }">
<el-input-number <el-input-number
v-model="formData.internalGuidanceUnitPrice" v-model="row.sortNo"
:min="1"
:precision="0"
:controls="false"
class="!w-1/1"
/>
</template>
</el-table-column>
<el-table-column align="center" label="设计部位" min-width="120" fixed="left">
<template #default="{ row }">
<el-select v-model="row.designPart" class="!w-1/1" placeholder="请选择">
<el-option
v-for="item in DESIGN_PART_OPTIONS"
:key="String(item.value)"
:label="item.label"
:value="item.value"
/>
</el-select>
</template>
</el-table-column>
<el-table-column align="center" label="建筑类型" min-width="140" fixed="left">
<template #default="{ row }">
<el-input v-model="row.buildingType" maxlength="100" placeholder="建筑类型" />
</template>
</el-table-column>
<!-- 2. 取消 controls 的核心数值列 -->
<el-table-column align="center" label="指导单价(元)" min-width="110">
<template #default="{ row }">
<el-input-number
v-model="row.internalGuidanceUnitPrice"
:min="0" :min="0"
:precision="2" :precision="2"
:step="1" :controls="false"
class="!w-1/1" class="!w-1/1"
controls-position="right" />
</template>
</el-table-column>
<el-table-column align="center" label="设计面积(m²)" min-width="110">
<template #default="{ row }">
<el-input-number
v-model="row.designArea"
:min="0"
:precision="2"
:controls="false"
class="!w-1/1"
/>
</template>
</el-table-column>
<el-table-column align="center" label="楼栋/户型数" min-width="100">
<template #default="{ row }">
<el-input-number
v-model="row.buildingOrUnitCount"
:min="0"
:precision="0"
:controls="false"
class="!w-1/1"
/>
</template>
</el-table-column>
<!-- 3. 多级表头折叠系数配置 -->
<el-table-column label="调整系数配置" align="center">
<el-table-column align="center" label="套图" min-width="85">
<template #default="{ row }">
<el-input-number v-model="row.drawingSetFactor" :min="0" :precision="4" :controls="false" class="!w-1/1" />
</template>
</el-table-column>
<el-table-column align="center" label="规模" min-width="85">
<template #default="{ row }">
<el-input-number v-model="row.scaleFactor" :min="0" :precision="4" :controls="false" class="!w-1/1" />
</template>
</el-table-column>
<el-table-column align="center" label="修改" min-width="85">
<template #default="{ row }">
<el-input-number v-model="row.modificationFactor" :min="0" :precision="4" :controls="false" class="!w-1/1" />
</template>
</el-table-column>
<el-table-column align="center" label="复杂(%)" min-width="90">
<template #default="{ row }">
<el-input-number
:model-value="toPercentValue(row.complexityFactor)"
:min="0"
:precision="2"
:controls="false"
class="!w-1/1"
@update:model-value="setGuideDetailPercentValue(row, 'complexityFactor', $event)"
/>
</template>
</el-table-column>
<el-table-column align="center" label="合计" min-width="80">
<template #default="{ row }">
<span class="text-gray-500">{{ formatFactorText(getGuideDetailTotalAdjustmentFactor(row)) }}</span>
</template>
</el-table-column>
</el-table-column>
<el-table-column align="center" label="设计占比(%)" min-width="100">
<template #default="{ row }">
<el-input-number
:model-value="toPercentValue(row.designRatio)"
:min="0"
:precision="2"
:controls="false"
class="!w-1/1"
@update:model-value="setGuideDetailPercentValue(row, 'designRatio', $event)"
/>
</template>
</el-table-column>
<!-- 4. 结果列靠右显示用浅色背景区分 -->
<el-table-column align="right" label="考核面积(m²)" min-width="110" class-name="bg-gray-50">
<template #default="{ row }">
<span class="font-bold">{{ formatAmountText(getGuideDetailAssessmentArea(row)) }}</span>
</template>
</el-table-column>
<el-table-column align="right" label="考核产值(元)" min-width="120" class-name="bg-gray-50">
<template #default="{ row }">
<span class="font-bold text-primary">{{ formatAmountText(getGuideDetailAssessmentOutputValue(row)) }}</span>
</template>
</el-table-column>
<el-table-column align="center" label="备注" min-width="130">
<template #default="{ row }">
<el-input v-model="row.remark" maxlength="500" placeholder="备注信息" />
</template>
</el-table-column>
<el-table-column align="center" fixed="right" label="操作" width="70">
<template #default="{ $index }">
<el-button link type="danger" @click="removeGuideDetailRow($index)">删除</el-button>
</template>
</el-table-column>
</el-table>
<el-row :gutter="16" class="mt-16px">
<el-col :span="8">
<el-form-item label="汇总设计面积(m²)">
<el-input :model-value="formatAmountText(guideDetailSummary.designArea)" disabled />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="汇总考核面积(m²)">
<el-input :model-value="formatAmountText(guideDetailSummary.assessmentArea)" disabled />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="汇总考核产值(元)">
<el-input
:model-value="formatAmountText(guideDetailSummary.assessmentOutputValue)"
disabled
/> />
</el-form-item> </el-form-item>
</el-col> </el-col>
@@ -296,7 +422,7 @@
placeholder="请选择虚拟产值计算方式" placeholder="请选择虚拟产值计算方式"
> >
<el-option <el-option
v-for="item in virtualCalculationMethodOptions" v-for="item in VIRTUAL_CALCULATION_METHOD_OPTIONS"
:key="String(item.value)" :key="String(item.value)"
:label="item.label" :label="item.label"
:value="item.value" :value="item.value"
@@ -359,6 +485,7 @@
</el-row> </el-row>
</template> </template>
</el-form> </el-form>
<template #footer> <template #footer>
<el-button :disabled="formLoading" type="primary" @click="submitForm">保存</el-button> <el-button :disabled="formLoading" type="primary" @click="submitForm">保存</el-button>
<el-button @click="dialogVisible = false">取消</el-button> <el-button @click="dialogVisible = false">取消</el-button>
@@ -367,19 +494,22 @@
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
// [原有的 Script 逻辑不变,直接粘贴原本的逻辑即可]
import type { FormRules } from 'element-plus' import type { FormRules } from 'element-plus'
import * as PlanningApi from '@/api/tjt/planning' import * as PlanningApi from '@/api/tjt/planning'
import * as PlanningGuideDetailApi from '@/api/tjt/planningGuideDetail'
import { import {
CALCULATION_METHOD_OPTIONS, CALCULATION_METHOD_OPTIONS,
DEFAULT_WORKING_DAY_UNIT_PRICE, DEFAULT_WORKING_DAY_UNIT_PRICE,
DESIGN_PART_OPTIONS,
DESIGN_STAGE_OPTIONS, DESIGN_STAGE_OPTIONS,
OWNERSHIP_TYPE_OPTIONS,
VIRTUAL_CALCULATION_METHOD_OPTIONS, VIRTUAL_CALCULATION_METHOD_OPTIONS,
formatAmountText, formatAmountText,
formatPercentText, formatPercentText,
fromPercentValue, fromPercentValue,
getCalculationRatioDefaultPercent, getCalculationRatioDefaultPercent,
getCalculationRatioLabel, getCalculationRatioLabel,
getOwnershipTypeLabel,
getReviewOutsourceDefaultPercent, getReviewOutsourceDefaultPercent,
isComprehensiveOwnership, isComprehensiveOwnership,
isContractPriceMethod, isContractPriceMethod,
@@ -399,90 +529,64 @@ import {
defineOptions({ name: 'TjtPlanningOutputForm' }) defineOptions({ name: 'TjtPlanningOutputForm' })
const DESIGN_PART_OPTIONS = [ type GuideDetailRow = PlanningGuideDetailApi.ProjectPlanningGuideDetailVO
{ label: '地上部分', value: '地上部分' },
{ label: '地下部分', value: '地下部分' }
]
const OWNERSHIP_TYPE_LABELS = ['专业所', '综合所', '专业分包']
const CALCULATION_METHOD_LABELS = ['指导价法', '合同价法', '虚拟产值法']
const DESIGN_STAGE_LABELS = ['方案', '施工图', '方案+施工图']
const VIRTUAL_CALCULATION_METHOD_LABELS = ['指导单价法', '指导总价法', '工日法']
const createDisplayOptions = (
source: Array<{ label: string; value: string }>,
labels: string[]
) => source.map((item, index) => ({ label: labels[index] || item.label, value: item.value }))
const ownershipTypeOptions = createDisplayOptions(OWNERSHIP_TYPE_OPTIONS, OWNERSHIP_TYPE_LABELS)
const calculationMethodOptions = createDisplayOptions(
CALCULATION_METHOD_OPTIONS,
CALCULATION_METHOD_LABELS
)
const designStageOptions = createDisplayOptions(DESIGN_STAGE_OPTIONS, DESIGN_STAGE_LABELS)
const virtualCalculationMethodOptions = createDisplayOptions(
VIRTUAL_CALCULATION_METHOD_OPTIONS,
VIRTUAL_CALCULATION_METHOD_LABELS
)
const { t } = useI18n()
const message = useMessage() const message = useMessage()
const dialogVisible = ref(false) const dialogVisible = ref(false)
const dialogTitle = ref('')
const formLoading = ref(false) const formLoading = ref(false)
const formRef = ref() const formRef = ref()
const formData = ref<PlanningApi.ProjectPlanningVO>({
const createFormData = (): PlanningApi.ProjectPlanningVO => ({
id: undefined,
projectId: 0, projectId: 0,
ownershipType: '', ownershipType: '',
calculationMethod: '', calculationMethod: '',
planningContent: '' planningContent: '',
planningAmount: undefined,
managementFeeRate: undefined,
managementFee: undefined,
implementationTeam: '',
planningStartYear: undefined,
planningArea: undefined,
designStage: undefined,
currentDesignStageRatio: undefined,
reviewOutsourceFlag: false,
reviewOutsourceRatio: undefined,
totalDistributionAmount: 1,
progressRemark: '',
allocatedAmount: undefined,
pendingAmount: undefined,
buildingOrUnitCount: undefined,
drawingSetFactor: undefined,
scaleFactor: undefined,
modificationFactor: undefined,
complexityFactor: undefined,
internalGuidanceUnitPrice: undefined,
virtualCalculationMethod: undefined,
workingDayCount: undefined,
workingDayUnitPrice: undefined,
guidanceUnitPrice: undefined,
guidanceTotalPrice: undefined,
calculationRatio: undefined,
contractUnitPrice: undefined,
totalAdjustmentFactor: undefined,
assessmentArea: undefined,
virtualOutputValue: undefined,
assessmentOutputValue: undefined,
createTime: undefined
}) })
const getOptionLabel = (options: Array<{ label: string; value: string }>, value?: string) => const formData = ref<PlanningApi.ProjectPlanningVO>(createFormData())
options.find((item) => item.value === value)?.label || value || '' const guideDetails = ref<GuideDetailRow[]>([])
const ownershipTypeLabel = computed(() =>
getOptionLabel(ownershipTypeOptions, formData.value.ownershipType)
)
const normalizeFormData = (data: PlanningApi.ProjectPlanningVO): PlanningApi.ProjectPlanningVO => ({
...data,
ownershipType: normalizeOwnershipType(data.ownershipType) || data.ownershipType || '',
calculationMethod: normalizeCalculationMethod(data.calculationMethod) || data.calculationMethod || '',
designPart: DESIGN_PART_OPTIONS.find((item) => item.value === data.designPart)?.value || undefined,
designStage: normalizeDesignStage(data.designStage),
virtualCalculationMethod: normalizeVirtualCalculationMethod(data.virtualCalculationMethod),
reviewOutsourceFlag: data.reviewOutsourceFlag ?? false,
totalDistributionAmount: data.totalDistributionAmount ?? 1,
progressRemark: data.progressRemark ?? '',
drawingSetFactor: data.drawingSetFactor ?? 1,
scaleFactor: data.scaleFactor ?? 1,
modificationFactor: data.modificationFactor ?? 1,
complexityFactor: data.complexityFactor ?? 1,
workingDayUnitPrice:
data.workingDayUnitPrice ??
(isWorkingDayMethod(data.virtualCalculationMethod) ? DEFAULT_WORKING_DAY_UNIT_PRICE : undefined),
guidanceTotalPrice: data.guidanceTotalPrice
})
const planningStartYearValue = computed({ const planningStartYearValue = computed({
get: () => get: () => (formData.value.planningStartYear ? String(formData.value.planningStartYear) : undefined),
formData.value.planningStartYear ? String(formData.value.planningStartYear) : undefined,
set: (value?: string) => { set: (value?: string) => {
formData.value.planningStartYear = value ? Number(value) : undefined formData.value.planningStartYear = value ? Number(value) : undefined
} }
}) })
const contractUnitPricePreview = computed(() => {
const planningAmount = Number(formData.value.planningAmount || 0)
const planningArea = Number(formData.value.planningArea || 0)
if (!planningArea) {
return formatAmountText(0)
}
return formatAmountText(planningAmount / planningArea)
})
const createPercentModel = (field: keyof PlanningApi.ProjectPlanningVO, digits = 2) => const createPercentModel = (field: keyof PlanningApi.ProjectPlanningVO, digits = 2) =>
computed({ computed({
get: () => toPercentValue(formData.value[field] as number | undefined, digits), get: () => toPercentValue(formData.value[field] as number | undefined, digits),
@@ -502,23 +606,25 @@ const showCalculationRatioField = computed(
isComprehensiveOwnership(formData.value.ownershipType) || isComprehensiveOwnership(formData.value.ownershipType) ||
isSubcontractOwnership(formData.value.ownershipType) isSubcontractOwnership(formData.value.ownershipType)
) )
const calculationRatioLabel = computed(() => getCalculationRatioLabel(formData.value.ownershipType))
const showMajorFactorFields = computed( const showGuideDetailSection = computed(
() =>
isMajorOwnership(formData.value.ownershipType) &&
(isGuidancePriceMethod(formData.value.calculationMethod) ||
isContractPriceMethod(formData.value.calculationMethod))
)
const showInternalGuidanceUnitPriceField = computed(
() => () =>
isMajorOwnership(formData.value.ownershipType) && isMajorOwnership(formData.value.ownershipType) &&
isGuidancePriceMethod(formData.value.calculationMethod) isGuidancePriceMethod(formData.value.calculationMethod)
) )
const showParentMajorFactorFields = computed(
() =>
isMajorOwnership(formData.value.ownershipType) &&
isContractPriceMethod(formData.value.calculationMethod)
)
const showVirtualOutputSection = computed( const showVirtualOutputSection = computed(
() => () =>
isMajorOwnership(formData.value.ownershipType) && isMajorOwnership(formData.value.ownershipType) &&
isVirtualOutputMethod(formData.value.calculationMethod) isVirtualOutputMethod(formData.value.calculationMethod)
) )
const showWorkingDayFields = computed(() => isWorkingDayMethod(formData.value.virtualCalculationMethod)) const showWorkingDayFields = computed(() => isWorkingDayMethod(formData.value.virtualCalculationMethod))
const showGuidanceUnitPriceField = computed( const showGuidanceUnitPriceField = computed(
() => isVirtualGuidanceMethod(formData.value.virtualCalculationMethod) () => isVirtualGuidanceMethod(formData.value.virtualCalculationMethod)
@@ -526,13 +632,188 @@ const showGuidanceUnitPriceField = computed(
const showGuidanceTotalPriceField = computed( const showGuidanceTotalPriceField = computed(
() => isVirtualGuidanceTotalPriceMethod(formData.value.virtualCalculationMethod) () => isVirtualGuidanceTotalPriceMethod(formData.value.virtualCalculationMethod)
) )
const calculationRatioLabel = computed(() => getCalculationRatioLabel(formData.value.ownershipType))
const normalizeFormData = (data: PlanningApi.ProjectPlanningVO): PlanningApi.ProjectPlanningVO => ({
...createFormData(),
...data,
ownershipType: normalizeOwnershipType(data.ownershipType) || data.ownershipType || '',
calculationMethod: normalizeCalculationMethod(data.calculationMethod) || data.calculationMethod || '',
designStage: normalizeDesignStage(data.designStage),
virtualCalculationMethod: normalizeVirtualCalculationMethod(data.virtualCalculationMethod),
reviewOutsourceFlag: data.reviewOutsourceFlag ?? false,
totalDistributionAmount: data.totalDistributionAmount ?? 1,
progressRemark: data.progressRemark ?? '',
workingDayUnitPrice:
data.workingDayUnitPrice ??
(isWorkingDayMethod(data.virtualCalculationMethod) ? DEFAULT_WORKING_DAY_UNIT_PRICE : undefined)
})
const createGuideDetailRow = (sortNo: number): GuideDetailRow => ({
planningId: formData.value.id || 0,
sortNo,
designPart: undefined,
buildingType: '',
designArea: undefined,
internalGuidanceUnitPrice: undefined,
buildingOrUnitCount: undefined,
drawingSetFactor: undefined,
scaleFactor: undefined,
modificationFactor: undefined,
complexityFactor: undefined,
totalAdjustmentFactor: undefined,
designRatio: undefined,
assessmentArea: undefined,
assessmentOutputValue: undefined,
remark: ''
})
const normalizeGuideDetailList = (
list: PlanningGuideDetailApi.ProjectPlanningGuideDetailVO[] | undefined
): GuideDetailRow[] =>
[...(list || [])]
.sort(
(a, b) =>
Number(a.sortNo ?? Number.MAX_SAFE_INTEGER) - Number(b.sortNo ?? Number.MAX_SAFE_INTEGER)
)
.map((item, index) => ({
...item,
planningId: item.planningId || formData.value.id || 0,
sortNo: item.sortNo ?? index + 1,
buildingType: item.buildingType ?? '',
remark: item.remark ?? ''
}))
const addGuideDetailRow = () => {
guideDetails.value.push(createGuideDetailRow(guideDetails.value.length + 1))
}
const removeGuideDetailRow = (index: number) => {
guideDetails.value.splice(index, 1)
resetGuideDetailSortNo()
}
const resetGuideDetailSortNo = () => {
guideDetails.value = guideDetails.value.map((item, index) => ({
...item,
sortNo: index + 1
}))
}
const getGuideDetailTotalAdjustmentFactor = (row: GuideDetailRow) => {
if (
row.drawingSetFactor === undefined ||
row.scaleFactor === undefined ||
row.modificationFactor === undefined ||
row.complexityFactor === undefined
) {
return undefined
}
return Number(
(
Number(row.drawingSetFactor) *
Number(row.scaleFactor) *
Number(row.modificationFactor) *
Number(row.complexityFactor)
).toFixed(4)
)
}
const getGuideDetailAssessmentArea = (row: GuideDetailRow) => {
const totalAdjustmentFactor = getGuideDetailTotalAdjustmentFactor(row)
if (row.designArea === undefined || totalAdjustmentFactor === undefined) {
return undefined
}
return Number((Number(row.designArea) * totalAdjustmentFactor).toFixed(2))
}
const getGuideDetailAssessmentOutputValue = (row: GuideDetailRow) => {
const assessmentArea = getGuideDetailAssessmentArea(row)
if (
row.internalGuidanceUnitPrice === undefined ||
row.designRatio === undefined ||
assessmentArea === undefined
) {
return undefined
}
return Number(
(
Number(row.internalGuidanceUnitPrice) *
assessmentArea *
Number(row.designRatio) *
(1 - Number(formData.value.reviewOutsourceRatio || 0))
).toFixed(2)
)
}
const guideDetailSummary = computed(() =>
guideDetails.value.reduce(
(summary, row) => ({
designArea: Number((summary.designArea + Number(row.designArea || 0)).toFixed(2)),
assessmentArea: Number(
(summary.assessmentArea + Number(getGuideDetailAssessmentArea(row) || 0)).toFixed(2)
),
assessmentOutputValue: Number(
(
summary.assessmentOutputValue + Number(getGuideDetailAssessmentOutputValue(row) || 0)
).toFixed(2)
)
}),
{
designArea: 0,
assessmentArea: 0,
assessmentOutputValue: 0
}
)
)
const contractUnitPricePreview = computed(() => {
const planningAmount = Number(formData.value.planningAmount || 0)
const planningArea = showGuideDetailSection.value
? Number(guideDetailSummary.value.designArea || 0)
: Number(formData.value.planningArea || 0)
if (!planningArea) {
return formatAmountText(0)
}
return formatAmountText(planningAmount / planningArea)
})
const formatFactorText = (value?: number, digits = 4) => {
if (value === undefined || value === null) {
return '-'
}
return Number(value).toFixed(digits)
}
const setGuideDetailPercentValue = (
row: GuideDetailRow,
field: 'complexityFactor' | 'designRatio',
value?: number | string | null
) => {
row[field] = fromPercentValue(value, 4)
}
const hasValue = (value: unknown) => value !== undefined && value !== null && value !== ''
const formRules = reactive<FormRules>({ const formRules = reactive<FormRules>({
calculationMethod: [{ required: true, message: '产值计算方式不能为空', trigger: 'change' }], calculationMethod: [{ required: true, message: '产值计算方式不能为空', trigger: 'change' }],
designPart: [{ required: true, message: '设计部位不能为空', trigger: 'change' }],
buildingType: [{ required: true, message: '建筑类型不能为空', trigger: 'blur' }],
planningStartYear: [{ required: true, message: '开始年度不能为空', trigger: 'change' }], planningStartYear: [{ required: true, message: '开始年度不能为空', trigger: 'change' }],
planningArea: [{ required: true, message: '工程总面积不能为空', trigger: 'blur' }], planningArea: [
{
validator: (_rule, value, callback) => {
if (showGuideDetailSection.value) {
callback()
return
}
if (!hasValue(value)) {
callback(new Error('工程总面积不能为空'))
return
}
callback()
},
trigger: 'blur'
}
],
designStage: [{ required: true, message: '设计阶段不能为空', trigger: 'change' }], designStage: [{ required: true, message: '设计阶段不能为空', trigger: 'change' }],
currentDesignStageRatio: [ currentDesignStageRatio: [
{ required: true, message: '本次设计阶段比例不能为空', trigger: 'blur' } { required: true, message: '本次设计阶段比例不能为空', trigger: 'blur' }
@@ -541,7 +822,7 @@ const formRules = reactive<FormRules>({
calculationRatio: [ calculationRatio: [
{ {
validator: (_rule, value, callback) => { validator: (_rule, value, callback) => {
if (showCalculationRatioField.value && (value === undefined || value === null || value === '')) { if (showCalculationRatioField.value && !hasValue(value)) {
callback(new Error(`${calculationRatioLabel.value}不能为空`)) callback(new Error(`${calculationRatioLabel.value}不能为空`))
return return
} }
@@ -550,21 +831,6 @@ const formRules = reactive<FormRules>({
trigger: 'blur' trigger: 'blur'
} }
], ],
internalGuidanceUnitPrice: [
{
validator: (_rule, value, callback) => {
if (
showInternalGuidanceUnitPriceField.value &&
(value === undefined || value === null || value === '')
) {
callback(new Error('内部指导单价不能为空'))
return
}
callback()
},
trigger: 'blur'
}
],
virtualCalculationMethod: [ virtualCalculationMethod: [
{ {
validator: (_rule, value, callback) => { validator: (_rule, value, callback) => {
@@ -580,7 +846,7 @@ const formRules = reactive<FormRules>({
workingDayCount: [ workingDayCount: [
{ {
validator: (_rule, value, callback) => { validator: (_rule, value, callback) => {
if (showWorkingDayFields.value && (value === undefined || value === null || value === '')) { if (showWorkingDayFields.value && !hasValue(value)) {
callback(new Error('工日不能为空')) callback(new Error('工日不能为空'))
return return
} }
@@ -592,7 +858,7 @@ const formRules = reactive<FormRules>({
workingDayUnitPrice: [ workingDayUnitPrice: [
{ {
validator: (_rule, value, callback) => { validator: (_rule, value, callback) => {
if (showWorkingDayFields.value && (value === undefined || value === null || value === '')) { if (showWorkingDayFields.value && !hasValue(value)) {
callback(new Error('工日单价不能为空')) callback(new Error('工日单价不能为空'))
return return
} }
@@ -604,10 +870,7 @@ const formRules = reactive<FormRules>({
guidanceUnitPrice: [ guidanceUnitPrice: [
{ {
validator: (_rule, value, callback) => { validator: (_rule, value, callback) => {
if ( if (showGuidanceUnitPriceField.value && !hasValue(value)) {
showGuidanceUnitPriceField.value &&
(value === undefined || value === null || value === '')
) {
callback(new Error('指导单价不能为空')) callback(new Error('指导单价不能为空'))
return return
} }
@@ -619,10 +882,7 @@ const formRules = reactive<FormRules>({
guidanceTotalPrice: [ guidanceTotalPrice: [
{ {
validator: (_rule, value, callback) => { validator: (_rule, value, callback) => {
if ( if (showGuidanceTotalPriceField.value && !hasValue(value)) {
showGuidanceTotalPriceField.value &&
(value === undefined || value === null || value === '')
) {
callback(new Error('指导总价不能为空')) callback(new Error('指导总价不能为空'))
return return
} }
@@ -668,31 +928,39 @@ watch(
} }
) )
watch(showGuideDetailSection, (value) => {
if (value && !guideDetails.value.length) {
addGuideDetailRow()
}
})
const buildSavePayload = (): PlanningApi.ProjectPlanningSaveVO => ({ const buildSavePayload = (): PlanningApi.ProjectPlanningSaveVO => ({
id: formData.value.id, id: formData.value.id,
projectId: formData.value.projectId, projectId: formData.value.projectId,
ownershipType: formData.value.ownershipType, ownershipType: formData.value.ownershipType,
designPart: formData.value.designPart,
buildingType: formData.value.buildingType,
calculationMethod: formData.value.calculationMethod, calculationMethod: formData.value.calculationMethod,
planningContent: formData.value.planningContent, planningContent: formData.value.planningContent,
planningAmount: formData.value.planningAmount, planningAmount: formData.value.planningAmount,
managementFeeRate: formData.value.managementFeeRate, managementFeeRate: formData.value.managementFeeRate,
implementationTeam: formData.value.implementationTeam, implementationTeam: formData.value.implementationTeam,
planningStartYear: formData.value.planningStartYear, planningStartYear: formData.value.planningStartYear,
planningArea: formData.value.planningArea, planningArea: showGuideDetailSection.value
? guideDetailSummary.value.designArea
: formData.value.planningArea,
designStage: formData.value.designStage, designStage: formData.value.designStage,
currentDesignStageRatio: formData.value.currentDesignStageRatio, currentDesignStageRatio: formData.value.currentDesignStageRatio,
reviewOutsourceFlag: formData.value.reviewOutsourceFlag, reviewOutsourceFlag: formData.value.reviewOutsourceFlag,
reviewOutsourceRatio: formData.value.reviewOutsourceRatio, reviewOutsourceRatio: formData.value.reviewOutsourceRatio,
totalDistributionAmount: formData.value.totalDistributionAmount, totalDistributionAmount: formData.value.totalDistributionAmount,
progressRemark: formData.value.progressRemark, progressRemark: formData.value.progressRemark,
buildingOrUnitCount: formData.value.buildingOrUnitCount, buildingOrUnitCount: showGuideDetailSection.value ? undefined : formData.value.buildingOrUnitCount,
drawingSetFactor: formData.value.drawingSetFactor, drawingSetFactor: showGuideDetailSection.value ? undefined : formData.value.drawingSetFactor,
scaleFactor: formData.value.scaleFactor, scaleFactor: showGuideDetailSection.value ? undefined : formData.value.scaleFactor,
modificationFactor: formData.value.modificationFactor, modificationFactor: showGuideDetailSection.value ? undefined : formData.value.modificationFactor,
complexityFactor: formData.value.complexityFactor, complexityFactor: showGuideDetailSection.value ? undefined : formData.value.complexityFactor,
internalGuidanceUnitPrice: formData.value.internalGuidanceUnitPrice, internalGuidanceUnitPrice: showGuideDetailSection.value
? undefined
: formData.value.internalGuidanceUnitPrice,
virtualCalculationMethod: formData.value.virtualCalculationMethod, virtualCalculationMethod: formData.value.virtualCalculationMethod,
workingDayCount: formData.value.workingDayCount, workingDayCount: formData.value.workingDayCount,
workingDayUnitPrice: formData.value.workingDayUnitPrice, workingDayUnitPrice: formData.value.workingDayUnitPrice,
@@ -701,21 +969,98 @@ const buildSavePayload = (): PlanningApi.ProjectPlanningSaveVO => ({
calculationRatio: formData.value.calculationRatio calculationRatio: formData.value.calculationRatio
}) })
const buildGuideDetailPayload = (): PlanningGuideDetailApi.ProjectPlanningGuideDetailBatchSaveVO => ({
planningId: formData.value.id!,
details: guideDetails.value
.map((item, index) => ({
id: item.id,
designPart: item.designPart,
buildingType: item.buildingType,
designArea: item.designArea,
internalGuidanceUnitPrice: item.internalGuidanceUnitPrice,
buildingOrUnitCount: item.buildingOrUnitCount,
drawingSetFactor: item.drawingSetFactor,
scaleFactor: item.scaleFactor,
modificationFactor: item.modificationFactor,
complexityFactor: item.complexityFactor,
designRatio: item.designRatio,
sortNo: item.sortNo ?? index + 1,
remark: item.remark
}))
.sort((a, b) => Number(a.sortNo || 0) - Number(b.sortNo || 0))
})
const validateGuideDetails = () => {
if (!guideDetails.value.length) {
message.warning('请至少维护一条指导价法明细')
return false
}
for (let index = 0; index < guideDetails.value.length; index++) {
const row = guideDetails.value[index]
const rowText = `${index + 1}`
if (!row.designPart) {
message.warning(`${rowText}设计部位不能为空`)
return false
}
if (!row.buildingType) {
message.warning(`${rowText}建筑类型不能为空`)
return false
}
if (!hasValue(row.designArea)) {
message.warning(`${rowText}设计面积不能为空`)
return false
}
if (!hasValue(row.internalGuidanceUnitPrice)) {
message.warning(`${rowText}内部指导单价不能为空`)
return false
}
if (!hasValue(row.drawingSetFactor)) {
message.warning(`${rowText}套图系数不能为空`)
return false
}
if (!hasValue(row.scaleFactor)) {
message.warning(`${rowText}规模系数不能为空`)
return false
}
if (!hasValue(row.modificationFactor)) {
message.warning(`${rowText}修改系数不能为空`)
return false
}
if (!hasValue(row.complexityFactor)) {
message.warning(`${rowText}复杂系数不能为空`)
return false
}
if (!hasValue(row.designRatio)) {
message.warning(`${rowText}设计占比不能为空`)
return false
}
}
return true
}
const open = async (id: number) => { const open = async (id: number) => {
dialogVisible.value = true dialogVisible.value = true
dialogTitle.value = t('action.update')
formLoading.value = true formLoading.value = true
try { try {
const data = await PlanningApi.getProjectPlanning(id) const data = await PlanningApi.getProjectPlanning(id)
formData.value = normalizeFormData(data) formData.value = normalizeFormData(data)
guideDetails.value = showGuideDetailSection.value
? normalizeGuideDetailList(
await PlanningGuideDetailApi.getProjectPlanningGuideDetailListByPlanningId(id)
)
: []
applyCalculationRatioDefault() applyCalculationRatioDefault()
if (formData.value.reviewOutsourceRatio === undefined || formData.value.reviewOutsourceRatio === null) { if (formData.value.reviewOutsourceRatio === undefined || formData.value.reviewOutsourceRatio === null) {
applyReviewOutsourceDefault() applyReviewOutsourceDefault()
} }
if (showGuideDetailSection.value && !guideDetails.value.length) {
addGuideDetailRow()
}
} finally { } finally {
formLoading.value = false formLoading.value = false
} }
} }
defineExpose({ open }) defineExpose({ open })
const emit = defineEmits(['success']) const emit = defineEmits(['success'])
@@ -728,10 +1073,17 @@ const submitForm = async () => {
if (!valid) { if (!valid) {
return return
} }
if (showGuideDetailSection.value && !validateGuideDetails()) {
return
}
formLoading.value = true formLoading.value = true
try { try {
await PlanningApi.updateProjectPlanning(buildSavePayload()) await PlanningApi.updateProjectPlanning(buildSavePayload())
message.success(t('common.updateSuccess')) if (showGuideDetailSection.value && formData.value.id) {
await PlanningGuideDetailApi.batchSaveProjectPlanningGuideDetail(buildGuideDetailPayload())
}
message.success('保存成功')
dialogVisible.value = false dialogVisible.value = false
emit('success') emit('success')
} finally { } finally {
@@ -739,3 +1091,17 @@ const submitForm = async () => {
} }
} }
</script> </script>
<style scoped>
/* 优化无控制按钮的 Input Number 显示样式 */
:deep(.optimized-table .el-input-number .el-input__inner) {
text-align: left;
}
/* 给只读计算结果列添加淡淡的背景色用于视觉区分 */
:deep(.bg-gray-50) {
background-color: #f9fafc !important;
}
:deep(.text-primary) {
color: var(--el-color-primary);
}
</style>

View File

@@ -227,25 +227,25 @@
{{ formatPercentText(currentPlanning.calculationRatio) }} {{ formatPercentText(currentPlanning.calculationRatio) }}
</el-descriptions-item> </el-descriptions-item>
<el-descriptions-item <el-descriptions-item
v-if="currentPlanning.buildingOrUnitCount" v-if="showParentBuildingOrUnitCount"
label="楼栋数/户型数" label="楼栋数/户型数"
> >
{{ currentPlanning.buildingOrUnitCount }} {{ currentPlanning.buildingOrUnitCount }}
</el-descriptions-item> </el-descriptions-item>
<el-descriptions-item v-if="showMajorFactorFields" label="套图系数"> <el-descriptions-item v-if="showParentMajorFactorFields" label="套图系数">
{{ formatFactorText(currentPlanning.drawingSetFactor, 2) }} {{ formatFactorText(currentPlanning.drawingSetFactor, 2) }}
</el-descriptions-item> </el-descriptions-item>
<el-descriptions-item v-if="showMajorFactorFields" label="规模系数"> <el-descriptions-item v-if="showParentMajorFactorFields" label="规模系数">
{{ formatFactorText(currentPlanning.scaleFactor, 2) }} {{ formatFactorText(currentPlanning.scaleFactor, 2) }}
</el-descriptions-item> </el-descriptions-item>
<el-descriptions-item v-if="showMajorFactorFields" label="修改系数"> <el-descriptions-item v-if="showParentMajorFactorFields" label="修改系数">
{{ formatFactorText(currentPlanning.modificationFactor, 2) }} {{ formatFactorText(currentPlanning.modificationFactor, 2) }}
</el-descriptions-item> </el-descriptions-item>
<el-descriptions-item v-if="showMajorFactorFields" label="复杂系数/复杂等级"> <el-descriptions-item v-if="showParentMajorFactorFields" label="复杂系数/复杂等级">
{{ formatPercentText(currentPlanning.complexityFactor) }} {{ formatPercentText(currentPlanning.complexityFactor) }}
</el-descriptions-item> </el-descriptions-item>
<el-descriptions-item <el-descriptions-item
v-if="currentPlanning.internalGuidanceUnitPrice" v-if="showParentInternalGuidanceUnitPrice"
label="内部指导单价(元/㎡)" label="内部指导单价(元/㎡)"
> >
{{ formatAmountText(currentPlanning.internalGuidanceUnitPrice) }} {{ formatAmountText(currentPlanning.internalGuidanceUnitPrice) }}
@@ -274,7 +274,7 @@
</el-descriptions> </el-descriptions>
<el-descriptions :column="2" border class="mt-16px" title="计算结果"> <el-descriptions :column="2" border class="mt-16px" title="计算结果">
<el-descriptions-item label="合计调整系数"> <el-descriptions-item v-if="!showGuideDetailScene" label="合计调整系数">
{{ formatFactorText(currentPlanning.totalAdjustmentFactor) }} {{ formatFactorText(currentPlanning.totalAdjustmentFactor) }}
</el-descriptions-item> </el-descriptions-item>
<el-descriptions-item label="考核面积(㎡)"> <el-descriptions-item label="考核面积(㎡)">
@@ -444,16 +444,32 @@ const showCalculationRatioField = computed(
isComprehensiveOwnership(currentPlanning.value?.ownershipType) || isComprehensiveOwnership(currentPlanning.value?.ownershipType) ||
isSubcontractOwnership(currentPlanning.value?.ownershipType) isSubcontractOwnership(currentPlanning.value?.ownershipType)
) )
const showMajorFactorFields = computed( const showGuideDetailScene = computed(
() => () =>
isMajorOwnership(currentPlanning.value?.ownershipType) && isMajorOwnership(currentPlanning.value?.ownershipType) &&
(isGuidancePriceMethod(currentPlanning.value?.calculationMethod) || isGuidancePriceMethod(currentPlanning.value?.calculationMethod)
isContractPriceMethod(currentPlanning.value?.calculationMethod)) )
const showParentMajorFactorFields = computed(
() =>
isMajorOwnership(currentPlanning.value?.ownershipType) &&
isContractPriceMethod(currentPlanning.value?.calculationMethod)
)
const showParentBuildingOrUnitCount = computed(
() =>
showParentMajorFactorFields.value &&
currentPlanning.value?.buildingOrUnitCount !== undefined &&
currentPlanning.value?.buildingOrUnitCount !== null
)
const showParentInternalGuidanceUnitPrice = computed(
() =>
!showGuideDetailScene.value &&
currentPlanning.value?.internalGuidanceUnitPrice !== undefined &&
currentPlanning.value?.internalGuidanceUnitPrice !== null
) )
const formatFactorText = (value?: number, digits = 4) => { const formatFactorText = (value?: number, digits = 4) => {
if (value === undefined || value === null) { if (value === undefined || value === null) {
return Number(0).toFixed(digits) return '-'
} }
return Number(value).toFixed(digits) return Number(value).toFixed(digits)
} }

View File

@@ -110,9 +110,6 @@
<div class="mb-16px flex items-center justify-between gap-12px"> <div class="mb-16px flex items-center justify-between gap-12px">
<div> <div>
<div class="text-16px font-600">{{ currentProject.projectName }}</div> <div class="text-16px font-600">{{ currentProject.projectName }}</div>
<div class="mt-4px text-13px text-[var(--el-text-color-secondary)]">
页面6导出 7.1.1 项目考核产值预算表
</div>
</div> </div>
<el-button <el-button
v-hasPermi="['tjt:report-budget:export']" v-hasPermi="['tjt:report-budget:export']"
@@ -191,8 +188,6 @@
{{ getOwnershipTypeLabel(scope.row.ownershipType) }} {{ getOwnershipTypeLabel(scope.row.ownershipType) }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column align="center" label="设计部位" width="110" prop="designPart" />
<el-table-column align="center" label="建筑类型" min-width="120" prop="buildingType" />
<el-table-column align="center" label="开始年度" width="100" prop="planningStartYear" /> <el-table-column align="center" label="开始年度" width="100" prop="planningStartYear" />
<el-table-column align="center" label="规划金额(元)" width="130"> <el-table-column align="center" label="规划金额(元)" width="130">
<template #default="scope"> <template #default="scope">

View File

@@ -93,12 +93,6 @@
<div class="mb-16px flex items-center justify-between gap-16px"> <div class="mb-16px flex items-center justify-between gap-16px">
<div> <div>
<div class="text-16px font-600">{{ currentPlanning.planningContent }}</div> <div class="text-16px font-600">{{ currentPlanning.planningContent }}</div>
<div class="mt-4px text-13px text-[var(--el-text-color-secondary)]">
页面7导出 7.1.2 / 7.1.3年度{{ formData.year || '-' }}考核产值{{
formatAmountText(formData.assessmentOutputValue)
}}
</div>
</div> </div>
<div class="flex items-center gap-12px"> <div class="flex items-center gap-12px">
<el-button <el-button

View File

@@ -95,9 +95,6 @@
<div class="mb-16px flex items-center justify-between gap-12px"> <div class="mb-16px flex items-center justify-between gap-12px">
<div> <div>
<div class="text-16px font-600">{{ currentPlanning.planningContent }}</div> <div class="text-16px font-600">{{ currentPlanning.planningContent }}</div>
<div class="mt-4px text-13px text-[var(--el-text-color-secondary)]">
页面8导出 7.1.4 当前专业人员年度/季度计取表
</div>
</div> </div>
<el-button <el-button
v-hasPermi="['tjt:report-specialty-person:export']" v-hasPermi="['tjt:report-specialty-person:export']"