This commit is contained in:
zwgczx committed 2026-03-02 17:52:32 +08:00
1 parent 3950057707
commit a10359f7e0
19 files changed
+349 -299

No files matched your search

+2 -7
View File
@@ -4,6 +4,7 @@ import { AgGridVue } from 'ag-grid-vue3'
import type { ColDef, FirstDataRenderedEvent, GridApi, GridReadyEvent, GridSizeChangedEvent } from 'ag-grid-community'
import localforage from 'localforage'
import { myTheme, gridOptions } from '@/lib/diyAgGridOptions'
import { parseNumberOrNull } from '@/lib/number'
import { AG_GRID_LOCALE_CN } from '@ag-grid-community/locale'
interface DictItem {
@@ -41,12 +42,6 @@ const props = defineProps<{
const detailRows = ref<FactorRow[]>([])
const gridApi = ref<GridApi<FactorRow> | null>(null)
const parseNumberOrNull = (value: unknown) => {
if (value === '' || value == null) return null
const v = Number(value)
return Number.isFinite(v) ? v : null
}
const formatReadonlyFactor = (value: unknown) => {
if (value == null || value === '') return ''
return Number(value).toFixed(2)
@@ -277,7 +272,7 @@ onBeforeUnmount(() => {
<div class="rounded-lg border bg-card xmMx flex min-h-0 flex-1 flex-col">
<div class="flex items-center justify-between border-b px-4 py-3">
<h3 class="text-sm font-semibold text-foreground">{{ title }}</h3>
<div class="text-xs text-muted-foreground">导入导出</div>
<div class="text-xs text-muted-foreground"></div>
</div>
<div class="ag-theme-quartz h-full min-h-0 w-full flex-1">
+1 -1
View File
@@ -327,7 +327,7 @@ const processCellFromClipboard = (params:any) => {
<div class="rounded-lg border bg-card xmMx flex min-h-0 min-w-0 flex-1 flex-col overflow-hidden">
<div class="flex items-center justify-between border-b px-4 py-3">
<h3 class="text-sm font-semibold text-foreground">合同规模明细</h3>
<div class="text-xs text-muted-foreground">导入导出</div>
<div class="text-xs text-muted-foreground"></div>
</div>
<div class="ag-theme-quartz h-full min-h-0 min-w-0 w-full flex-1 overflow-hidden">
@@ -7,6 +7,7 @@ import { expertList } from '@/sql'
import { myTheme, gridOptions } from '@/lib/diyAgGridOptions'
import { decimalAggSum, roundTo, sumByNumber, toDecimal } from '@/lib/decimal'
import { formatThousands } from '@/lib/numberFormat'
import { parseNumberOrNull } from '@/lib/number'
import { syncPricingTotalToZxFw, ZXFW_RELOAD_SERVICE_KEY } from '@/lib/zxFwPricingSync'
import { usePricingPaneReloadStore } from '@/pinia/pricingPaneReload'
@@ -173,12 +174,6 @@ const mergeWithDictRows = (rowsFromDb: DetailRow[] | undefined): DetailRow[] =>
})
}
const parseNumberOrNull = (value: unknown) => {
if (value === '' || value == null) return null
const v = Number(value)
return Number.isFinite(v) ? v : null
}
const parseNonNegativeIntegerOrNull = (value: unknown) => {
if (value === '' || value == null) return null
if (typeof value === 'number') {
@@ -482,7 +477,7 @@ const handleGridReady = (params: any) => {
<div class="rounded-lg border bg-card xmMx flex min-h-0 flex-1 flex-col">
<div class="flex items-center justify-between border-b px-4 py-3">
<h3 class="text-sm font-semibold text-foreground">工时法明细</h3>
<div class="text-xs text-muted-foreground">导入导出</div>
<div class="text-xs text-muted-foreground"></div>
</div>
<div class="ag-theme-quartz h-full min-h-0 w-full flex-1">
@@ -3,13 +3,15 @@ import { computed, onBeforeUnmount, onMounted, ref, watch } from 'vue'
import { AgGridVue } from 'ag-grid-vue3'
import type { ColDef } from 'ag-grid-community'
import localforage from 'localforage'
import { getBasicFeeFromScale, majorList } from '@/sql'
import { majorList } from '@/sql'
import { myTheme, gridOptions } from '@/lib/diyAgGridOptions'
import { addNumbers, decimalAggSum, roundTo, sumByNumber, toDecimal } from '@/lib/decimal'
import { decimalAggSum, roundTo, sumByNumber } from '@/lib/decimal'
import { formatThousands } from '@/lib/numberFormat'
import { syncPricingTotalToZxFw, ZXFW_RELOAD_SERVICE_KEY } from '@/lib/zxFwPricingSync'
import { usePricingPaneReloadStore } from '@/pinia/pricingPaneReload'
import { loadConsultCategoryFactorMap, loadMajorFactorMap } from '@/lib/xmFactorDefaults'
import { parseNumberOrNull } from '@/lib/number'
import { getBenchmarkBudgetByScale, getScaleBudgetFee } from '@/lib/pricingScaleFee'
import { Button } from '@/components/ui/button'
import {
AlertDialogAction,
@@ -250,12 +252,6 @@ const mergeWithDictRows = (
})
}
const parseNumberOrNull = (value: unknown) => {
if (value === '' || value == null) return null
const v = Number(value)
return Number.isFinite(v) ? v : null
}
const formatEditableNumber = (params: any) => {
if (!params.node?.group && !params.node?.rowPinned && (params.value == null || params.value === '')) {
return '点击输入'
@@ -285,15 +281,15 @@ const formatReadonlyMoney = (params: any) => {
return formatThousands(roundTo(params.value, 2))
}
const getBenchmarkBudgetByAmount = (row?: Pick<DetailRow, 'amount'>) => {
const result = getBasicFeeFromScale(row?.amount, 'cost')
return result ? roundTo(addNumbers(result.basic, result.optional), 2) : null
}
const getBenchmarkBudgetByAmount = (row?: Pick<DetailRow, 'amount'>) =>
getBenchmarkBudgetByScale(row?.amount, 'cost')
const getBudgetFee = (row?: Pick<DetailRow, 'amount' | 'majorFactor' | 'consultCategoryFactor'>) => {
const benchmarkBudget = getBenchmarkBudgetByAmount(row)
if (benchmarkBudget == null || row?.majorFactor == null || row?.consultCategoryFactor == null) return null
return roundTo(toDecimal(benchmarkBudget).mul(row.majorFactor).mul(row.consultCategoryFactor), 2)
return getScaleBudgetFee({
benchmarkBudget: getBenchmarkBudgetByAmount(row),
majorFactor: row?.majorFactor,
consultCategoryFactor: row?.consultCategoryFactor
})
}
const columnDefs: ColDef<DetailRow>[] = [
@@ -3,13 +3,15 @@ import { computed, onBeforeUnmount, onMounted, ref, watch } from 'vue'
import { AgGridVue } from 'ag-grid-vue3'
import type { ColDef } from 'ag-grid-community'
import localforage from 'localforage'
import { getBasicFeeFromScale, majorList } from '@/sql'
import { majorList } from '@/sql'
import { myTheme, gridOptions } from '@/lib/diyAgGridOptions'
import { addNumbers, decimalAggSum, roundTo, sumByNumber, toDecimal } from '@/lib/decimal'
import { decimalAggSum, roundTo, sumByNumber } from '@/lib/decimal'
import { formatThousands } from '@/lib/numberFormat'
import { syncPricingTotalToZxFw, ZXFW_RELOAD_SERVICE_KEY } from '@/lib/zxFwPricingSync'
import { usePricingPaneReloadStore } from '@/pinia/pricingPaneReload'
import { loadConsultCategoryFactorMap, loadMajorFactorMap } from '@/lib/xmFactorDefaults'
import { parseNumberOrNull } from '@/lib/number'
import { getBenchmarkBudgetByScale, getScaleBudgetFee } from '@/lib/pricingScaleFee'
import { Button } from '@/components/ui/button'
import {
AlertDialogAction,
@@ -253,12 +255,6 @@ const mergeWithDictRows = (
})
}
const parseNumberOrNull = (value: unknown) => {
if (value === '' || value == null) return null
const v = Number(value)
return Number.isFinite(v) ? v : null
}
const formatEditableNumber = (params: any) => {
if (!params.node?.group && !params.node?.rowPinned && (params.value == null || params.value === '')) {
return '点击输入'
@@ -280,15 +276,15 @@ const formatReadonlyMoney = (params: any) => {
return formatThousands(roundTo(params.value, 2))
}
const getBenchmarkBudgetByLandArea = (row?: Pick<DetailRow, 'landArea'>) => {
const result = getBasicFeeFromScale(row?.landArea, 'area')
return result ? roundTo(addNumbers(result.basic, result.optional), 2) : null
}
const getBenchmarkBudgetByLandArea = (row?: Pick<DetailRow, 'landArea'>) =>
getBenchmarkBudgetByScale(row?.landArea, 'area')
const getBudgetFee = (row?: Pick<DetailRow, 'landArea' | 'majorFactor' | 'consultCategoryFactor'>) => {
const benchmarkBudget = getBenchmarkBudgetByLandArea(row)
if (benchmarkBudget == null || row?.majorFactor == null || row?.consultCategoryFactor == null) return null
return roundTo(toDecimal(benchmarkBudget).mul(row.majorFactor).mul(row.consultCategoryFactor), 2)
return getScaleBudgetFee({
benchmarkBudget: getBenchmarkBudgetByLandArea(row),
majorFactor: row?.majorFactor,
consultCategoryFactor: row?.consultCategoryFactor
})
}
const formatEditableFlexibleNumber = (params: any) => {
@@ -7,6 +7,7 @@ import { taskList } from '@/sql'
import { myTheme, gridOptions } from '@/lib/diyAgGridOptions'
import { decimalAggSum, roundTo, sumByNumber, toDecimal } from '@/lib/decimal'
import { formatThousands } from '@/lib/numberFormat'
import { parseNumberOrNull } from '@/lib/number'
import { syncPricingTotalToZxFw, ZXFW_RELOAD_SERVICE_KEY } from '@/lib/zxFwPricingSync'
import { usePricingPaneReloadStore } from '@/pinia/pricingPaneReload'
import { loadConsultCategoryFactorMap } from '@/lib/xmFactorDefaults'
@@ -180,12 +181,8 @@ const mergeWithDictRows = (rowsFromDb: DetailRow[] | undefined): DetailRow[] =>
})
}
const parseNumberOrNull = (value: unknown) => {
if (value === '' || value == null) return null
const normalized = typeof value === 'string' ? value.replace(/[^0-9.\-]/g, '') : value
const v = Number(normalized)
return Number.isFinite(v) ? v : null
}
const parseSanitizedNumberOrNull = (value: unknown) =>
parseNumberOrNull(value, { sanitize: true })
const calcServiceFee = (row: DetailRow | undefined) => {
if (!row || isNoTaskRow(row)) return null
@@ -281,7 +278,7 @@ const columnDefs: ColDef<DetailRow>[] = [
!isNoTaskRow(params.data) &&
(params.value == null || params.value === '')
},
valueParser: params => parseNumberOrNull(params.newValue),
valueParser: params => parseSanitizedNumberOrNull(params.newValue),
valueFormatter: params => {
if (isNoTaskRow(params.data)) return '无'
if (!params.node?.group && !params.node?.rowPinned && (params.value == null || params.value === '')) {
@@ -307,7 +304,7 @@ const columnDefs: ColDef<DetailRow>[] = [
(params.value == null || params.value === '')
},
aggFunc: decimalAggSum,
valueParser: params => parseNumberOrNull(params.newValue),
valueParser: params => parseSanitizedNumberOrNull(params.newValue),
valueFormatter: formatEditableNumber
},
{
@@ -325,7 +322,7 @@ const columnDefs: ColDef<DetailRow>[] = [
!isNoTaskRow(params.data) &&
(params.value == null || params.value === '')
},
valueParser: params => parseNumberOrNull(params.newValue),
valueParser: params => parseSanitizedNumberOrNull(params.newValue),
valueFormatter: formatEditableNumber
},
{
@@ -511,7 +508,7 @@ const mydiyTheme = myTheme.withParams({
<div class="rounded-lg border bg-card xmMx flex min-h-0 flex-1 flex-col">
<div class="flex items-center justify-between border-b px-4 py-3">
<h3 class="text-sm font-semibold text-foreground">工作量明细</h3>
<div class="text-xs text-muted-foreground">导入导出</div>
<div class="text-xs text-muted-foreground"></div>
</div>
<div v-if="isWorkloadMethodApplicable" class="ag-theme-quartz h-full min-h-0 w-full flex-1">
+1 -1
View File
@@ -433,7 +433,7 @@ const scrollToGridSection = () => {
>
项目明细
</h3>
<div class="text-xs text-muted-foreground">导入导出</div>
<div class="text-xs text-muted-foreground"></div>
</div>
<div ref="agGridRef" class="ag-theme-quartz w-full flex-1 min-h-0">