fix someone

This commit is contained in:
zwgczx committed 2026-03-07 11:47:07 +08:00
1 parent c482faacbf
commit ad4e9cdee0
17 files changed
+1084 -311

No files matched your search

+131 -23
View File
@@ -14,6 +14,14 @@ interface StoredDetailRowsState<T = any> {
detailRows?: T[]
}
interface StoredFactorState {
detailRows?: Array<{
id: string
standardFactor?: number | null
budgetValue?: number | null
}>
}
type MaybeNumber = number | null | undefined
interface ScaleRow {
@@ -22,6 +30,8 @@ interface ScaleRow {
landArea: number | null
consultCategoryFactor: number | null
majorFactor: number | null
workStageFactor: number | null
workRatio: number | null
}
interface WorkloadRow {
@@ -92,25 +102,74 @@ const getDefaultMajorFactorById = (id: string) => {
return toFiniteNumberOrNull(major?.defCoe)
}
const resolveFactorValue = (
row: { budgetValue?: number | null; standardFactor?: number | null } | undefined,
fallback: number | null
) => {
if (!row) return fallback
const budgetValue = toFiniteNumberOrNull(row.budgetValue)
if (budgetValue != null) return budgetValue
const standardFactor = toFiniteNumberOrNull(row.standardFactor)
if (standardFactor != null) return standardFactor
return fallback
}
const buildConsultCategoryFactorMap = (state: StoredFactorState | null) => {
const map = new Map<string, number | null>()
const serviceDict = getServiceDictById() as Record<string, ServiceLite | undefined>
for (const [id, item] of Object.entries(serviceDict)) {
map.set(String(id), toFiniteNumberOrNull(item?.defCoe))
}
for (const row of state?.detailRows || []) {
if (!row?.id) continue
const id = String(row.id)
map.set(id, resolveFactorValue(row, map.get(id) ?? null))
}
return map
}
const buildMajorFactorMap = (state: StoredFactorState | null) => {
const map = new Map<string, number | null>()
for (const [id, item] of majorById.entries()) {
map.set(String(id), toFiniteNumberOrNull(item?.defCoe))
}
for (const row of state?.detailRows || []) {
if (!row?.id) continue
const rowId = String(row.id)
const id = map.has(rowId) ? rowId : majorIdAliasMap.get(rowId) || rowId
map.set(id, resolveFactorValue(row, map.get(id) ?? null))
}
return map
}
const getMajorLeafIds = () =>
getMajorDictEntries()
.filter(({ item }) => Boolean(item?.code && String(item.code).includes('-')))
.map(({ id }) => id)
const buildDefaultScaleRows = (serviceId: string | number): ScaleRow[] => {
const defaultConsultCategoryFactor = getDefaultConsultCategoryFactor(serviceId)
const buildDefaultScaleRows = (
serviceId: string | number,
consultCategoryFactorMap?: Map<string, number | null>,
majorFactorMap?: Map<string, number | null>
): ScaleRow[] => {
const defaultConsultCategoryFactor =
consultCategoryFactorMap?.get(String(serviceId)) ?? getDefaultConsultCategoryFactor(serviceId)
return getMajorLeafIds().map(id => ({
id,
amount: null,
landArea: null,
consultCategoryFactor: defaultConsultCategoryFactor,
majorFactor: getDefaultMajorFactorById(id)
majorFactor: majorFactorMap?.get(id) ?? getDefaultMajorFactorById(id),
workStageFactor: 1,
workRatio: 100
}))
}
const mergeScaleRows = (
serviceId: string | number,
rowsFromDb: Array<Partial<ScaleRow> & Pick<ScaleRow, 'id'>> | undefined
rowsFromDb: Array<Partial<ScaleRow> & Pick<ScaleRow, 'id'>> | undefined,
consultCategoryFactorMap?: Map<string, number | null>,
majorFactorMap?: Map<string, number | null>
): ScaleRow[] => {
const dbValueMap = toRowMap(rowsFromDb)
for (const row of rowsFromDb || []) {
@@ -121,13 +180,16 @@ const mergeScaleRows = (
}
}
const defaultConsultCategoryFactor = getDefaultConsultCategoryFactor(serviceId)
return buildDefaultScaleRows(serviceId).map(row => {
const defaultConsultCategoryFactor =
consultCategoryFactorMap?.get(String(serviceId)) ?? getDefaultConsultCategoryFactor(serviceId)
return buildDefaultScaleRows(serviceId, consultCategoryFactorMap, majorFactorMap).map(row => {
const fromDb = dbValueMap.get(row.id)
if (!fromDb) return row
const hasConsultCategoryFactor = hasOwn(fromDb, 'consultCategoryFactor')
const hasMajorFactor = hasOwn(fromDb, 'majorFactor')
const hasWorkStageFactor = hasOwn(fromDb, 'workStageFactor')
const hasWorkRatio = hasOwn(fromDb, 'workRatio')
return {
...row,
@@ -138,7 +200,13 @@ const mergeScaleRows = (
(hasConsultCategoryFactor ? null : defaultConsultCategoryFactor),
majorFactor:
toFiniteNumberOrNull(fromDb.majorFactor) ??
(hasMajorFactor ? null : getDefaultMajorFactorById(row.id))
(hasMajorFactor ? null : (majorFactorMap?.get(row.id) ?? getDefaultMajorFactorById(row.id))),
workStageFactor:
toFiniteNumberOrNull((fromDb as Partial<ScaleRow>).workStageFactor) ??
(hasWorkStageFactor ? null : row.workStageFactor),
workRatio:
toFiniteNumberOrNull((fromDb as Partial<ScaleRow>).workRatio) ??
(hasWorkRatio ? null : row.workRatio)
}
})
}
@@ -153,7 +221,9 @@ const getInvestmentBudgetFee = (row: ScaleRow) => {
return getScaleBudgetFee({
benchmarkBudget: getBenchmarkBudgetByAmount(row.amount),
majorFactor: row.majorFactor,
consultCategoryFactor: row.consultCategoryFactor
consultCategoryFactor: row.consultCategoryFactor,
workStageFactor: row.workStageFactor,
workRatio: row.workRatio
})
}
@@ -161,7 +231,9 @@ const getLandBudgetFee = (row: ScaleRow) => {
return getScaleBudgetFee({
benchmarkBudget: getBenchmarkBudgetByLandArea(row.landArea),
majorFactor: row.majorFactor,
consultCategoryFactor: row.consultCategoryFactor
consultCategoryFactor: row.consultCategoryFactor,
workStageFactor: row.workStageFactor,
workRatio: row.workRatio
})
}
@@ -170,8 +242,12 @@ const getTaskEntriesByServiceId = (serviceId: string | number) =>
.sort((a, b) => Number(a[0]) - Number(b[0]))
.filter(([, task]) => Number(task.serviceID) === Number(serviceId))
const buildDefaultWorkloadRows = (serviceId: string | number): WorkloadRow[] => {
const defaultConsultCategoryFactor = getDefaultConsultCategoryFactor(serviceId)
const buildDefaultWorkloadRows = (
serviceId: string | number,
consultCategoryFactorMap?: Map<string, number | null>
): WorkloadRow[] => {
const defaultConsultCategoryFactor =
consultCategoryFactorMap?.get(String(serviceId)) ?? getDefaultConsultCategoryFactor(serviceId)
return getTaskEntriesByServiceId(serviceId).map(([taskId, task], order) => ({
id: `task-${taskId}-${order}`,
conversion: toFiniteNumberOrNull(task.conversion),
@@ -184,11 +260,12 @@ const buildDefaultWorkloadRows = (serviceId: string | number): WorkloadRow[] =>
const mergeWorkloadRows = (
serviceId: string | number,
rowsFromDb: Array<Partial<WorkloadRow> & Pick<WorkloadRow, 'id'>> | undefined
rowsFromDb: Array<Partial<WorkloadRow> & Pick<WorkloadRow, 'id'>> | undefined,
consultCategoryFactorMap?: Map<string, number | null>
): WorkloadRow[] => {
const dbValueMap = toRowMap(rowsFromDb)
return buildDefaultWorkloadRows(serviceId).map(row => {
return buildDefaultWorkloadRows(serviceId, consultCategoryFactorMap).map(row => {
const fromDb = dbValueMap.get(row.id)
if (!fromDb) return row
@@ -270,15 +347,27 @@ const calcHourlyServiceBudget = (row: HourlyRow) => {
const resolveScaleRows = (
serviceId: string,
pricingData: StoredDetailRowsState | null,
htData: StoredDetailRowsState | null
htData: StoredDetailRowsState | null,
consultCategoryFactorMap?: Map<string, number | null>,
majorFactorMap?: Map<string, number | null>
) => {
if (pricingData?.detailRows != null) {
return mergeScaleRows(serviceId, pricingData.detailRows as any)
return mergeScaleRows(
serviceId,
pricingData.detailRows as any,
consultCategoryFactorMap,
majorFactorMap
)
}
if (htData?.detailRows != null) {
return mergeScaleRows(serviceId, htData.detailRows as any)
return mergeScaleRows(
serviceId,
htData.detailRows as any,
consultCategoryFactorMap,
majorFactorMap
)
}
return buildDefaultScaleRows(serviceId)
return buildDefaultScaleRows(serviceId, consultCategoryFactorMap, majorFactorMap)
}
export const getPricingMethodTotalsForService = async (params: {
@@ -287,33 +376,52 @@ export const getPricingMethodTotalsForService = async (params: {
}): Promise<PricingMethodTotals> => {
const serviceId = String(params.serviceId)
const htDbKey = `ht-info-v3-${params.contractId}`
const consultFactorDbKey = `ht-consult-category-factor-v1-${params.contractId}`
const majorFactorDbKey = `ht-major-factor-v1-${params.contractId}`
const investDbKey = `tzGMF-${params.contractId}-${serviceId}`
const landDbKey = `ydGMF-${params.contractId}-${serviceId}`
const workloadDbKey = `gzlF-${params.contractId}-${serviceId}`
const hourlyDbKey = `hourlyPricing-${params.contractId}-${serviceId}`
const [investData, landData, workloadData, hourlyData, htData] = await Promise.all([
const [investData, landData, workloadData, hourlyData, htData, consultFactorData, majorFactorData] = await Promise.all([
localforage.getItem<StoredDetailRowsState>(investDbKey),
localforage.getItem<StoredDetailRowsState>(landDbKey),
localforage.getItem<StoredDetailRowsState>(workloadDbKey),
localforage.getItem<StoredDetailRowsState>(hourlyDbKey),
localforage.getItem<StoredDetailRowsState>(htDbKey)
localforage.getItem<StoredDetailRowsState>(htDbKey),
localforage.getItem<StoredFactorState>(consultFactorDbKey),
localforage.getItem<StoredFactorState>(majorFactorDbKey)
])
const consultCategoryFactorMap = buildConsultCategoryFactorMap(consultFactorData)
const majorFactorMap = buildMajorFactorMap(majorFactorData)
// 优先使用对应计费页的数据;不存在时回退合同段规模信息,再回退默认字典行。
const investRows = resolveScaleRows(serviceId, investData, htData)
const investRows = resolveScaleRows(
serviceId,
investData,
htData,
consultCategoryFactorMap,
majorFactorMap
)
const investScale = sumByNumber(investRows, row => getInvestmentBudgetFee(row))
const landRows = resolveScaleRows(serviceId, landData, htData)
const landRows = resolveScaleRows(
serviceId,
landData,
htData,
consultCategoryFactorMap,
majorFactorMap
)
const landScale = sumByNumber(landRows, row => getLandBudgetFee(row))
const defaultWorkloadRows = buildDefaultWorkloadRows(serviceId)
const defaultWorkloadRows = buildDefaultWorkloadRows(serviceId, consultCategoryFactorMap)
const workload =
defaultWorkloadRows.length === 0
? null
: sumByNumber(
workloadData?.detailRows != null
? mergeWorkloadRows(serviceId, workloadData.detailRows as any)
? mergeWorkloadRows(serviceId, workloadData.detailRows as any, consultCategoryFactorMap)
: defaultWorkloadRows,
row => calcWorkloadServiceFee(row)
)