This commit is contained in:
zwgczx committed 2026-03-06 16:06:37 +08:00
1 parent d8f8b629d2
commit 626513bc21
4 files changed
+338 -471

No files matched your search

+1 -171
View File
@@ -1,183 +1,13 @@
<script setup lang="ts">
import { onActivated, onMounted, ref } from 'vue'
import localforage from 'localforage'
import { getMajorDictEntries, isMajorIdInIndustryScope } from '@/sql'
import CommonAgGrid from '@/components/common/xmCommonAgGrid.vue'
interface DictLeaf {
id: string
code: string
name: string
hasCost: boolean
hasArea: boolean
}
interface DictGroup {
id: string
code: string
name: string
children: DictLeaf[]
}
interface DetailRow {
id: string
groupCode: string
groupName: string
majorCode: string
majorName: string
hasCost: boolean
hasArea: boolean
amount: number | null
landArea: number | null
path: string[]
}
interface XmScaleState {
detailRows?: DetailRow[]
}
interface XmBaseInfoState {
projectIndustry?: string
}
const DB_KEY = 'xm-info-v3'
const BASE_INFO_KEY = 'xm-base-info-v1'
type MajorLite = { code: string; name: string; hasCost?: boolean; hasArea?: boolean }
const detailRows = ref<DetailRow[]>([])
const activeIndustryCode = ref('')
const detailDict = ref<DictGroup[]>([])
const majorEntries = getMajorDictEntries().map(({ id, item }) => [id, item] as [string, MajorLite])
const majorIdAliasMap = new Map(getMajorDictEntries().map(({ rawId, id }) => [rawId, id]))
const buildDetailDict = (entries: Array<[string, MajorLite]>) => {
const groupMap = new Map<string, DictGroup>()
const groupOrder: string[] = []
const codeLookup = new Map(entries.map(([key, item]) => [item.code, { id: key, ...item }]))
for (const [key, item] of entries) {
const isGroup = !item.code.includes('-')
if (isGroup) {
if (!groupMap.has(item.code)) groupOrder.push(item.code)
groupMap.set(item.code, {
id: key,
code: item.code,
name: item.name,
children: []
})
continue
}
const parentCode = item.code.split('-')[0]
if (!groupMap.has(parentCode)) {
const parent = codeLookup.get(parentCode)
if (!groupOrder.includes(parentCode)) groupOrder.push(parentCode)
groupMap.set(parentCode, {
id: parent?.id || `group-${parentCode}`,
code: parentCode,
name: parent?.name || parentCode,
children: []
})
}
groupMap.get(parentCode)!.children.push({
id: key,
code: item.code,
name: item.name,
hasCost: item.hasCost !== false,
hasArea: item.hasArea !== false
})
}
return groupOrder.map(code => groupMap.get(code)).filter((group): group is DictGroup => Boolean(group))
}
const rebuildDictByIndustry = (industryCode: string) => {
if (!industryCode) {
detailDict.value = []
return
}
const filteredEntries = majorEntries.filter(([id]) => isMajorIdInIndustryScope(id, industryCode))
detailDict.value = buildDetailDict(filteredEntries)
}
const buildDefaultRows = (): DetailRow[] => {
const rows: DetailRow[] = []
for (const group of detailDict.value) {
for (const child of group.children) {
rows.push({
id: child.id,
groupCode: group.code,
groupName: group.name,
majorCode: child.code,
majorName: child.name,
hasCost: child.hasCost,
hasArea: child.hasArea,
amount: null,
landArea: null,
path: [`${group.code} ${group.name}`, `${child.code} ${child.name}`]
})
}
}
return rows
}
const mergeWithDictRows = (rowsFromDb: DetailRow[] | undefined): DetailRow[] => {
const dbValueMap = new Map<string, DetailRow>()
for (const row of rowsFromDb || []) {
const rowId = String(row.id)
dbValueMap.set(rowId, row)
const aliasId = majorIdAliasMap.get(rowId)
if (aliasId && !dbValueMap.has(aliasId)) {
dbValueMap.set(aliasId, row)
}
}
return buildDefaultRows().map(row => {
const fromDb = dbValueMap.get(row.id)
if (!fromDb) return row
return {
...row,
amount: row.hasCost && typeof fromDb.amount === 'number' ? fromDb.amount : null,
landArea: row.hasArea && typeof fromDb.landArea === 'number' ? fromDb.landArea : null
}
})
}
const loadFromIndexedDB = async () => {
try {
const baseInfo = await localforage.getItem<XmBaseInfoState>(BASE_INFO_KEY)
activeIndustryCode.value =
typeof baseInfo?.projectIndustry === 'string' ? baseInfo.projectIndustry.trim() : ''
rebuildDictByIndustry(activeIndustryCode.value)
if (!activeIndustryCode.value) {
detailRows.value = []
return
}
const data = await localforage.getItem<XmScaleState>(DB_KEY)
if (data?.detailRows) {
detailRows.value = mergeWithDictRows(data.detailRows)
return
}
detailRows.value = buildDefaultRows()
} catch (error) {
console.error('loadFromIndexedDB failed:', error)
detailRows.value = []
}
}
onMounted(async () => {
await loadFromIndexedDB()
})
onActivated(() => {
void loadFromIndexedDB()
})
</script>
<template>
<CommonAgGrid title="项目明细" :rowData="detailRows" :dbKey="DB_KEY" />
<CommonAgGrid title="项目明细" :dbKey="DB_KEY" />
</template>