calculator2026/src/lib/projectWorkspace.ts
2026-03-13 18:27:42 +08:00

113 lines
3.1 KiB
TypeScript

import {
getIndustryTypeValue,
getMajorDictEntries,
getServiceDictEntries,
isIndustryEnabledByType,
isMajorIdInIndustryScope
} from '@/sql'
interface KvStoreLike {
setItem: <T = unknown>(keyRaw: string | number, value: T) => Promise<void>
}
type DictItemLite = {
code?: string
name?: string
defCoe?: number | null
notshowByzxflxs?: boolean
}
type FactorPersistRow = {
id: string
code: string
name: string
standardFactor: number | null
budgetValue: number | null
remark: string
path: string[]
}
type FactorPersistState = {
detailRows: FactorPersistRow[]
}
const buildCodePath = (code: string, selfId: string, codeIdMap: Map<string, string>) => {
const parts = code.split('-').filter(Boolean)
if (!parts.length) return [selfId]
const path: string[] = []
let currentCode = parts[0]
const firstId = codeIdMap.get(currentCode)
if (firstId) path.push(firstId)
for (let index = 1; index < parts.length; index += 1) {
currentCode = `${currentCode}-${parts[index]}`
const id = codeIdMap.get(currentCode)
if (id) path.push(id)
}
if (!path.length || path[path.length - 1] !== selfId) path.push(selfId)
return path
}
const buildFactorRowsFromEntries = (entries: Array<{ id: string; item: DictItemLite }>): FactorPersistRow[] => {
const codeIdMap = new Map<string, string>()
for (const entry of entries) {
const code = String(entry.item?.code || '').trim()
if (!code) continue
codeIdMap.set(code, entry.id)
}
return entries
.map(entry => {
const code = String(entry.item?.code || '').trim()
const name = String(entry.item?.name || '').trim()
if (!code || !name) return null
const standardFactor =
typeof entry.item?.defCoe === 'number' && Number.isFinite(entry.item.defCoe)
? entry.item.defCoe
: null
return {
id: entry.id,
code,
name,
standardFactor,
budgetValue: standardFactor,
remark: '',
path: buildCodePath(code, entry.id, codeIdMap)
}
})
.filter((item): item is FactorPersistRow => Boolean(item))
}
export const initializeProjectFactorStates = async (
kvStore: KvStoreLike,
industry: string,
consultCategoryFactorKey: string,
majorFactorKey: string
) => {
const industryType = getIndustryTypeValue(industry)
const consultEntries = getServiceDictEntries()
.map(({ id, item }) => ({ id, item: item as DictItemLite }))
.filter(({ item }) => {
if (item.notshowByzxflxs === true) return false
return isIndustryEnabledByType(item as Record<string, unknown>, industryType)
})
const majorEntries = getMajorDictEntries()
.map(({ id, item }) => ({ id, item: item as DictItemLite }))
.filter(({ id, item }) => item.notshowByzxflxs !== true && isMajorIdInIndustryScope(id, industry))
const consultPayload: FactorPersistState = {
detailRows: buildFactorRowsFromEntries(consultEntries)
}
const majorPayload: FactorPersistState = {
detailRows: buildFactorRowsFromEntries(majorEntries)
}
await Promise.all([
kvStore.setItem(consultCategoryFactorKey, consultPayload),
kvStore.setItem(majorFactorKey, majorPayload)
])
}