fix someone
This commit is contained in:
1 parent
c482faacbf
commit
ad4e9cdee0
17 files changed
+1084
-311
No files matched your search
+131
-23
@@ -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)
|
||||
)
|
||||
|
||||
Reference in new issue
Block a user