This commit is contained in:
zwgczx committed 2026-03-09 10:55:08 +08:00
1 parent fc26a87bee
commit 8a15587d30
8 files changed
+348 -216

No files matched your search

+138 -57
View File
@@ -89,6 +89,28 @@ interface PricingMethodTotalsOptions {
excludeInvestmentCostAndAreaRows?: boolean
}
interface PricingMethodDetailDbKeys {
investScale: string
landScale: string
workload: string
hourly: string
}
interface PricingMethodDefaultDetailRows {
investScale: unknown[]
landScale: unknown[]
workload: unknown[]
hourly: unknown[]
}
interface PricingMethodDefaultBuildContext {
htData: StoredDetailRowsState | null
consultCategoryFactorMap: Map<string, number | null>
majorFactorMap: Map<string, number | null>
industryId: string
excludeInvestmentCostAndAreaRows: boolean
}
const ONLY_COST_SCALE_ROW_ID = '__only-cost-scale-total__'
const hasOwn = (obj: unknown, key: string) =>
@@ -494,6 +516,105 @@ const resolveScaleRows = (
return buildDefaultScaleRows(serviceId, consultCategoryFactorMap, majorFactorMap)
}
export const getPricingMethodDetailDbKeys = (
contractId: string,
serviceId: string | number
): PricingMethodDetailDbKeys => {
const normalizedServiceId = String(serviceId)
return {
investScale: `tzGMF-${contractId}-${normalizedServiceId}`,
landScale: `ydGMF-${contractId}-${normalizedServiceId}`,
workload: `gzlF-${contractId}-${normalizedServiceId}`,
hourly: `hourlyPricing-${contractId}-${normalizedServiceId}`
}
}
const loadPricingMethodDefaultBuildContext = async (
contractId: string,
options?: PricingMethodTotalsOptions
): Promise<PricingMethodDefaultBuildContext> => {
const htDbKey = `ht-info-v3-${contractId}`
const consultFactorDbKey = `ht-consult-category-factor-v1-${contractId}`
const majorFactorDbKey = `ht-major-factor-v1-${contractId}`
const baseInfoDbKey = 'xm-base-info-v1'
const [htData, consultFactorData, majorFactorData, baseInfo] = await Promise.all([
localforage.getItem<StoredDetailRowsState>(htDbKey),
localforage.getItem<StoredFactorState>(consultFactorDbKey),
localforage.getItem<StoredFactorState>(majorFactorDbKey),
localforage.getItem<XmBaseInfoState>(baseInfoDbKey)
])
return {
htData,
consultCategoryFactorMap: buildConsultCategoryFactorMap(consultFactorData),
majorFactorMap: buildMajorFactorMap(majorFactorData),
industryId: typeof baseInfo?.projectIndustry === 'string' ? baseInfo.projectIndustry.trim() : '',
excludeInvestmentCostAndAreaRows: options?.excludeInvestmentCostAndAreaRows === true
}
}
const buildDefaultPricingMethodDetailRows = (
serviceId: string,
context: PricingMethodDefaultBuildContext
): PricingMethodDefaultDetailRows => {
const onlyCostScale = isOnlyCostScaleService(serviceId)
const scaleRows = resolveScaleRows(
serviceId,
null,
context.htData,
context.consultCategoryFactorMap,
context.majorFactorMap
)
const investScale = onlyCostScale
? buildOnlyCostScaleDetailRows(
serviceId,
context.htData?.detailRows as Array<Record<string, unknown>> | undefined,
context.consultCategoryFactorMap,
context.majorFactorMap,
context.industryId
)
: scaleRows.filter(row => {
if (!isCostMajorById(row.id)) return false
if (context.excludeInvestmentCostAndAreaRows && isDualScaleMajorById(row.id)) return false
return true
})
const landScale = scaleRows.filter(row => isAreaMajorById(row.id))
return {
investScale,
landScale,
workload: buildDefaultWorkloadRows(serviceId, context.consultCategoryFactorMap),
hourly: buildDefaultHourlyRows()
}
}
export const persistDefaultPricingMethodDetailRowsForServices = async (params: {
contractId: string
serviceIds: Array<string | number>
options?: PricingMethodTotalsOptions
}) => {
const uniqueServiceIds = Array.from(new Set(params.serviceIds.map(serviceId => String(serviceId))))
if (uniqueServiceIds.length === 0) return
const context = await loadPricingMethodDefaultBuildContext(params.contractId, params.options)
await Promise.all(
uniqueServiceIds.map(async serviceId => {
const dbKeys = getPricingMethodDetailDbKeys(params.contractId, serviceId)
const defaultRows = buildDefaultPricingMethodDetailRows(serviceId, context)
console.log(dbKeys,defaultRows)
await Promise.all([
localforage.setItem(dbKeys.investScale, { detailRows: defaultRows.investScale }),
localforage.setItem(dbKeys.landScale, { detailRows: defaultRows.landScale }),
localforage.setItem(dbKeys.workload, { detailRows: defaultRows.workload }),
localforage.setItem(dbKeys.hourly, { detailRows: defaultRows.hourly })
])
})
)
}
export const getPricingMethodTotalsForService = async (params: {
contractId: string
serviceId: string | number
@@ -593,34 +714,16 @@ export const ensurePricingMethodDetailRowsForServices = async (params: {
const uniqueServiceIds = Array.from(new Set(params.serviceIds.map(serviceId => String(serviceId))))
if (uniqueServiceIds.length === 0) return
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 baseInfoDbKey = 'xm-base-info-v1'
const [htData, consultFactorData, majorFactorData, baseInfo] = await Promise.all([
localforage.getItem<StoredDetailRowsState>(htDbKey),
localforage.getItem<StoredFactorState>(consultFactorDbKey),
localforage.getItem<StoredFactorState>(majorFactorDbKey),
localforage.getItem<XmBaseInfoState>(baseInfoDbKey)
])
const consultCategoryFactorMap = buildConsultCategoryFactorMap(consultFactorData)
const majorFactorMap = buildMajorFactorMap(majorFactorData)
const industryId = typeof baseInfo?.projectIndustry === 'string' ? baseInfo.projectIndustry.trim() : ''
const excludeInvestmentCostAndAreaRows = params.options?.excludeInvestmentCostAndAreaRows === true
const context = await loadPricingMethodDefaultBuildContext(params.contractId, params.options)
await Promise.all(
uniqueServiceIds.map(async serviceId => {
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 dbKeys = getPricingMethodDetailDbKeys(params.contractId, serviceId)
const [investData, landData, workloadData, hourlyData] = await Promise.all([
localforage.getItem<StoredDetailRowsState>(investDbKey),
localforage.getItem<StoredDetailRowsState>(landDbKey),
localforage.getItem<StoredDetailRowsState>(workloadDbKey),
localforage.getItem<StoredDetailRowsState>(hourlyDbKey)
localforage.getItem<StoredDetailRowsState>(dbKeys.investScale),
localforage.getItem<StoredDetailRowsState>(dbKeys.landScale),
localforage.getItem<StoredDetailRowsState>(dbKeys.workload),
localforage.getItem<StoredDetailRowsState>(dbKeys.hourly)
])
const shouldInitInvest = !Array.isArray(investData?.detailRows) || investData!.detailRows!.length === 0
@@ -629,50 +732,28 @@ export const ensurePricingMethodDetailRowsForServices = async (params: {
const shouldInitHourly = !Array.isArray(hourlyData?.detailRows) || hourlyData!.detailRows!.length === 0
const writeTasks: Promise<unknown>[] = []
let defaultRows: PricingMethodDefaultDetailRows | null = null
const getDefaultRows = () => {
if (!defaultRows) {
defaultRows = buildDefaultPricingMethodDetailRows(serviceId, context)
}
return defaultRows
}
if (shouldInitInvest) {
const onlyCostScale = isOnlyCostScaleService(serviceId)
const investRows = onlyCostScale
? buildOnlyCostScaleDetailRows(
serviceId,
(htData?.detailRows as Array<Record<string, unknown>> | undefined),
consultCategoryFactorMap,
majorFactorMap,
industryId
)
: resolveScaleRows(
serviceId,
null,
htData,
consultCategoryFactorMap,
majorFactorMap
).filter(row => {
if (!isCostMajorById(row.id)) return false
if (excludeInvestmentCostAndAreaRows && isDualScaleMajorById(row.id)) return false
return true
})
writeTasks.push(localforage.setItem(investDbKey, { detailRows: investRows }))
writeTasks.push(localforage.setItem(dbKeys.investScale, { detailRows: getDefaultRows().investScale }))
}
if (shouldInitLand) {
const landRows = resolveScaleRows(
serviceId,
null,
htData,
consultCategoryFactorMap,
majorFactorMap
).filter(row => isAreaMajorById(row.id))
writeTasks.push(localforage.setItem(landDbKey, { detailRows: landRows }))
writeTasks.push(localforage.setItem(dbKeys.landScale, { detailRows: getDefaultRows().landScale }))
}
if (shouldInitWorkload) {
const workloadRows = buildDefaultWorkloadRows(serviceId, consultCategoryFactorMap)
writeTasks.push(localforage.setItem(workloadDbKey, { detailRows: workloadRows }))
writeTasks.push(localforage.setItem(dbKeys.workload, { detailRows: getDefaultRows().workload }))
}
if (shouldInitHourly) {
const hourlyRows = buildDefaultHourlyRows()
writeTasks.push(localforage.setItem(hourlyDbKey, { detailRows: hourlyRows }))
writeTasks.push(localforage.setItem(dbKeys.hourly, { detailRows: getDefaultRows().hourly }))
}
if (writeTasks.length > 0) {