101 lines
3.0 KiB
TypeScript
101 lines
3.0 KiB
TypeScript
import { getMajorDictById, getMajorIdAliasMap, getServiceDictById } from '@/sql'
|
|
import { toFiniteNumberOrNull } from '@/lib/decimal'
|
|
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 hasUsableFactorRows = (state: XmFactorState | null | undefined) =>
|
|
Array.isArray(state?.detailRows) &&
|
|
state.detailRows.some(row => {
|
|
const hasFactor =
|
|
toFiniteNumberOrNull(row?.budgetValue) != null ||
|
|
toFiniteNumberOrNull(row?.standardFactor) != null
|
|
return hasFactor || String(row?.id || '').trim() !== ''
|
|
})
|
|
|
|
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
|
|
if (Object.prototype.hasOwnProperty.call(row, 'budgetValue')) {
|
|
return toFiniteNumberOrNull(row.budgetValue)
|
|
}
|
|
if (Object.prototype.hasOwnProperty.call(row, 'standardFactor')) {
|
|
return toFiniteNumberOrNull(row.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 kvData = kvStore ? await kvStore.getItem<XmFactorState>(storageKey) : null
|
|
const data = hasUsableFactorRows(piniaData)
|
|
? piniaData
|
|
: hasUsableFactorRows(kvData)
|
|
? kvData
|
|
: (piniaData ?? kvData)
|
|
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())
|