diff --git a/.codex_uploads/abe79621-4358-4474-afd5-31bb408bbab9-企业微信截图_17742463974454.png b/.codex_uploads/abe79621-4358-4474-afd5-31bb408bbab9-企业微信截图_17742463974454.png new file mode 100644 index 0000000..4ae25f6 Binary files /dev/null and b/.codex_uploads/abe79621-4358-4474-afd5-31bb408bbab9-企业微信截图_17742463974454.png differ diff --git a/codex.exe b/codex.exe index 32fefcc..14e563b 100644 Binary files a/codex.exe and b/codex.exe differ diff --git a/src/components/ht/HtContractSummary.vue b/src/components/ht/HtContractSummary.vue index 8c4a0d6..f4139c3 100644 --- a/src/components/ht/HtContractSummary.vue +++ b/src/components/ht/HtContractSummary.vue @@ -322,7 +322,9 @@ const columnDefs: ColDef[] = [ minWidth: 120, flex: 1.2, headerClass: 'ag-right-aligned-header', - cellClass: 'ag-right-aligned-cell', + cellClassRules: { + 'ag-right-aligned-cell': () => true + }, colSpan: params => { if (!params.data) return 1 if (params.data.rowType === 'total') return 4 @@ -340,7 +342,9 @@ const columnDefs: ColDef[] = [ minWidth: 120, flex: 1.2, headerClass: 'ag-right-aligned-header', - cellClass: 'ag-right-aligned-cell', + cellClassRules: { + 'ag-right-aligned-cell': () => true + }, valueFormatter: params => { if (params.data?.rowType === 'total') return '' return params.value == null ? '' : formatThousandsFlexible(params.value, 3) @@ -352,7 +356,9 @@ const columnDefs: ColDef[] = [ minWidth: 110, flex: 1.2, headerClass: 'ag-right-aligned-header', - cellClass: 'ag-right-aligned-cell', + cellClassRules: { + 'ag-right-aligned-cell': () => true + }, valueFormatter: params => { if (params.data?.rowType === 'total') return '' return params.value == null ? '' : formatThousandsFlexible(params.value, 3) @@ -364,7 +370,9 @@ const columnDefs: ColDef[] = [ minWidth: 110, flex: 1.2, headerClass: 'ag-right-aligned-header', - cellClass: 'ag-right-aligned-cell', + cellClassRules: { + 'ag-right-aligned-cell': () => true + }, valueFormatter: params => { if (params.data?.rowType === 'total') return '' return params.value == null ? '' : formatThousandsFlexible(params.value, 3) @@ -376,7 +384,9 @@ const columnDefs: ColDef[] = [ minWidth: 120, flex: 1.2, headerClass: 'ag-right-aligned-header', - cellClass: 'ag-right-aligned-cell', + cellClassRules: { + 'ag-right-aligned-cell': () => true + }, valueFormatter: params => (params.value == null ? '' : formatThousands(params.value, 2)) }, { @@ -385,7 +395,9 @@ const columnDefs: ColDef[] = [ minWidth: 120, flex: 1.2, headerClass: 'ag-right-aligned-header', - cellClass: 'ag-right-aligned-cell', + cellClassRules: { + 'ag-right-aligned-cell': () => true + }, valueFormatter: params => (params.value == null ? '' : formatThousands(params.value, 2)) } ] diff --git a/src/components/ht/htCard.vue b/src/components/ht/htCard.vue index 111f696..42ce7c8 100644 --- a/src/components/ht/htCard.vue +++ b/src/components/ht/htCard.vue @@ -335,11 +335,11 @@ const summaryView = markRaw( // 4. 给分类数组添加严格类型标注 const xmCategories: XmCategoryItem[] = [ - { key: 'base-info', label: '基础信息', component: htBaseInfoView }, + { key: 'base-info', label: '基础信息', component: htBaseInfoView }, { key: 'info', label: '规模信息', component: htView }, + { key: 'contract', label: '咨询服务', component: zxfwView }, { key: 'consult-category-factor', label: '咨询分类系数', component: consultCategoryFactorView }, { key: 'major-factor', label: '工程专业系数', component: majorFactorView }, - { key: 'contract', label: '咨询服务', component: zxfwView }, { key: 'additional-work-fee', label: '附加工作费', component: additionalWorkFeeView }, { key: 'reserve-fee', label: '预备费', component: reserveFeeView }, { key: 'all', label: '汇总', component: summaryView }, diff --git a/src/components/ht/zxFw.vue b/src/components/ht/zxFw.vue index 16fb147..a36246f 100644 --- a/src/components/ht/zxFw.vue +++ b/src/components/ht/zxFw.vue @@ -401,8 +401,10 @@ const createMethodColumn = ( headerClass: 'ag-right-aligned-header', minWidth, flex: 1.5, - cellClass: 'ag-right-aligned-cell', editable: false, + cellClassRules: { + 'ag-right-aligned-cell': () => true + }, valueGetter: params => { if (!params.data) return null if (isFixedRow(params.data)) return getMethodTotal(field) @@ -656,8 +658,10 @@ const columnDefs: ColDef[] = [ headerClass: 'ag-right-aligned-header', flex: 2, minWidth: 100, - cellClass: 'ag-right-aligned-cell', editable: false, + cellClassRules: { + 'ag-right-aligned-cell': () => true + }, valueGetter: params => { if (!params.data) return null return params.data.subtotal @@ -665,13 +669,16 @@ const columnDefs: ColDef[] = [ valueFormatter: params => (params.value == null ? '' : formatThousands(params.value, 2)) }, { - headerName: '确认金额', + headerName: '确认金额 ✎', field: 'finalFee', headerClass: 'ag-right-aligned-header', + headerTooltip: '该列支持手动修改,修改后会自动汇总到固定小计行', flex: 2, minWidth: 110, - cellClass: 'ag-right-aligned-cell', editable: params => !isFixedRow(params.data), + cellClassRules: { + 'ag-right-aligned-cell': () => true + }, valueGetter: params => { if (!params.data) return null return params.data.finalFee diff --git a/src/components/pricing/InvestmentScalePricingPane.vue b/src/components/pricing/InvestmentScalePricingPane.vue index a03259a..286cf6d 100644 --- a/src/components/pricing/InvestmentScalePricingPane.vue +++ b/src/components/pricing/InvestmentScalePricingPane.vue @@ -1,5 +1,5 @@ + + + + diff --git a/src/layout/tab.vue b/src/layout/tab.vue index 93d4439..62b7f6a 100644 --- a/src/layout/tab.vue +++ b/src/layout/tab.vue @@ -126,6 +126,8 @@ interface ZxFwStorageLike { } interface ScaleMethodRowLike extends ScaleRowLike { + benchmarkBudgetBasicChecked?: unknown + benchmarkBudgetOptionalChecked?: unknown basicFormula?: unknown optionalFormula?: unknown budgetFee?: unknown @@ -482,6 +484,7 @@ const userGuideSteps: UserGuideStep[] = [ const componentMap: Record = { ProjectCalcView: markRaw(defineAsyncComponent(() => import('@/components/xm/xmCard.vue'))), QuickCalcView: markRaw(defineAsyncComponent(() => import('@/components/ht/htCard.vue'))), + QuickCalcWorkbenchView: markRaw(defineAsyncComponent(() => import('@/components/views/QuickCalcWorkbenchView.vue'))), ZxFwView: markRaw(defineAsyncComponent(() => import('@/components/views/ZxFwView.vue'))), HtFeeMethodTypeLineView: markRaw(defineAsyncComponent(() => import('@/components/views/HtFeeMethodTypeLineView.vue'))), } @@ -1105,25 +1108,30 @@ const resolveTaskRowServiceId = (row: WorkContentRowLike): number | null => const resolveScaleMethodFee = (row: ScaleMethodRowLike, mode: 'cost' | 'area') => { const scaleValue = mode === 'cost' ? toFiniteNumber(row.amount) : toFiniteNumber(row.landArea) const benchmarkSplit = getBenchmarkBudgetSplitByScale(scaleValue, mode) + const basicChecked = row.benchmarkBudgetBasicChecked !== false + const optionalChecked = row.benchmarkBudgetOptionalChecked !== false + const allUnchecked = !basicChecked && !optionalChecked + const benchmarkBudgetBasic = benchmarkSplit ? (basicChecked ? benchmarkSplit.basic : 0) : null + const benchmarkBudgetOptional = benchmarkSplit ? (optionalChecked ? benchmarkSplit.optional : 0) : null const computedSplit = benchmarkSplit ? getScaleBudgetFeeSplit({ - benchmarkBudgetBasic: benchmarkSplit.basic, - benchmarkBudgetOptional: benchmarkSplit.optional, + benchmarkBudgetBasic, + benchmarkBudgetOptional, majorFactor: row.majorFactor, consultCategoryFactor: row.consultCategoryFactor, workStageFactor: row.workStageFactor, workRatio: row.workRatio }) : null - const basicFee = toFiniteNumber(row.budgetFee) ?? computedSplit?.total ?? null - const basicFeeBasic = toFiniteNumber(row.budgetFeeBasic) ?? computedSplit?.basic ?? null - const basicFeeOptional = toFiniteNumber(row.budgetFeeOptional) ?? computedSplit?.optional ?? null + const basicFee = allUnchecked ? null : (toFiniteNumber(row.budgetFee) ?? computedSplit?.total ?? null) + const basicFeeBasic = allUnchecked ? null : (toFiniteNumber(row.budgetFeeBasic) ?? computedSplit?.basic ?? null) + const basicFeeOptional = allUnchecked ? null : (toFiniteNumber(row.budgetFeeOptional) ?? computedSplit?.optional ?? null) const basicFormula = typeof row.basicFormula === 'string' && row.basicFormula.trim() ? row.basicFormula - : (benchmarkSplit?.basicFormula ?? '') + : (basicChecked ? (benchmarkSplit?.basicFormula ?? '') : '') const optionalFormula = typeof row.optionalFormula === 'string' && row.optionalFormula.trim() ? row.optionalFormula - : (benchmarkSplit?.optionalFormula ?? '') + : (optionalChecked ? (benchmarkSplit?.optionalFormula ?? '') : '') return { basicFee, basicFeeBasic, @@ -1251,13 +1259,7 @@ const buildMethod1 = (rows: ScaleMethodRowLike[] | undefined): ExportMethod1 | n const basicFeeBasic = feeResolved.basicFeeBasic const basicFeeOptional = feeResolved.basicFeeOptional const remark = typeof row.remark === 'string' ? row.remark : '' - const hasValue = - cost != null || - basicFee != null || - basicFeeBasic != null || - basicFeeOptional != null || - isNonEmptyString(remark) - if (!hasValue) return null + if (basicFee == null) return null return { proNum, major, @@ -1306,13 +1308,7 @@ const buildMethod2 = (rows: ScaleMethodRowLike[] | undefined): ExportMethod2 | n const basicFeeBasic = feeResolved.basicFeeBasic const basicFeeOptional = feeResolved.basicFeeOptional const remark = typeof row.remark === 'string' ? row.remark : '' - const hasValue = - area != null || - basicFee != null || - basicFeeBasic != null || - basicFeeOptional != null || - isNonEmptyString(remark) - if (!hasValue) return null + if (basicFee == null) return null return { proNum, major, @@ -2149,7 +2145,7 @@ watch(
-
+
-