85 lines
2.5 KiB
TypeScript
85 lines
2.5 KiB
TypeScript
import { getMajorDictById, getMajorIdAliasMap, getServiceDictById } from '@/sql'
|
|
import { toFiniteNumberOrNull } from '@/lib/number'
|
|
import { useKvStore } from '@/pinia/kv'
|
|
import { useZxFwPricingStore } from '@/pinia/zxFwPricing'
|
|
|
|
const CONSULT_CATEGORY_FACTOR_KEY = 'xm-consult-category-factor-v1'
|
|
const MAJOR_FACTOR_KEY = 'xm-major-factor-v1'
|
|
|
|
type XmFactorRow = {
|
|
id: string
|
|
standardFactor: number | null
|
|
budgetValue: number | null
|
|
}
|
|
|
|
type XmFactorState = {
|
|
detailRows?: XmFactorRow[]
|
|
}
|
|
|
|
type FactorDictItem = {
|
|
defCoe?: number | null
|
|
}
|
|
|
|
type FactorDict = Record<string, FactorDictItem>
|
|
|
|
const buildStandardFactorMap = (dict: FactorDict): Map<string, number | null> => {
|
|
const map = new Map<string, number | null>()
|
|
for (const [id, item] of Object.entries(dict)) {
|
|
map.set(String(id), toFiniteNumberOrNull(item?.defCoe))
|
|
}
|
|
return map
|
|
}
|
|
|
|
const resolveFactorValue = (
|
|
row: Partial<XmFactorRow> | undefined,
|
|
fallbackStandard: number | null
|
|
): number | null => {
|
|
if (!row) return null
|
|
const budgetValue = toFiniteNumberOrNull(row.budgetValue)
|
|
if (budgetValue != null) return budgetValue
|
|
const standardFactor = toFiniteNumberOrNull(row.standardFactor)
|
|
if (standardFactor != null) return standardFactor
|
|
return fallbackStandard
|
|
}
|
|
|
|
const getKvStoreSafely = () => {
|
|
try {
|
|
return useKvStore()
|
|
} catch {
|
|
return null
|
|
}
|
|
}
|
|
|
|
const getZxFwPricingStoreSafely = () => {
|
|
try {
|
|
return useZxFwPricingStore()
|
|
} catch {
|
|
return null
|
|
}
|
|
}
|
|
|
|
const loadFactorMap = async (
|
|
storageKey: string,
|
|
dict: FactorDict,
|
|
aliases?: Map<string, string>
|
|
): Promise<Map<string, number | null>> => {
|
|
const zxFwPricingStore = getZxFwPricingStoreSafely()
|
|
const kvStore = getKvStoreSafely()
|
|
const piniaData = zxFwPricingStore ? await zxFwPricingStore.loadKeyState<XmFactorState>(storageKey) : null
|
|
const data = piniaData ?? (kvStore ? await kvStore.getItem<XmFactorState>(storageKey) : null)
|
|
const map = buildStandardFactorMap(dict)
|
|
for (const row of data?.detailRows || []) {
|
|
if (!row?.id) continue
|
|
const rowId = String(row.id)
|
|
const id = map.has(rowId) ? rowId : aliases?.get(rowId) || rowId
|
|
map.set(id, resolveFactorValue(row, map.get(id) ?? null))
|
|
}
|
|
return map
|
|
}
|
|
|
|
export const loadConsultCategoryFactorMap = async (storageKey = CONSULT_CATEGORY_FACTOR_KEY) =>
|
|
loadFactorMap(storageKey, getServiceDictById() as FactorDict)
|
|
|
|
export const loadMajorFactorMap = async (storageKey = MAJOR_FACTOR_KEY) =>
|
|
loadFactorMap(storageKey, getMajorDictById() as FactorDict, getMajorIdAliasMap())
|