This commit is contained in:
zwgczx committed 2026-03-12 16:52:39 +08:00
1 parent f4f6e5c618
commit 1c600e64d0
8 files changed
+549 -179

No files matched your search

+41 -20
View File
@@ -28,7 +28,7 @@ import {
} from 'reka-ui'
import { decodeZwArchive, encodeZwArchive, ZW_FILE_EXTENSION } from '@/lib/zwArchive'
import { addNumbers, roundTo } from '@/lib/decimal'
import { exportFile, serviceList, additionalWorkList } from '@/sql'
import { exportFile, serviceList, additionalWorkList, reserveList } from '@/sql'
interface DataEntry {
key: string
@@ -104,6 +104,9 @@ interface ZxFwStorageLike {
interface ScaleMethodRowLike extends ScaleRowLike {
basicFormula?: unknown
optionalFormula?: unknown
benchmarkBudget?: unknown
benchmarkBudgetBasic?: unknown
benchmarkBudgetOptional?: unknown
budgetFee?: unknown
budgetFeeBasic?: unknown
budgetFeeOptional?: unknown
@@ -878,6 +881,14 @@ const getPiniaPersistStores = () =>
}
})
const flushPiniaPersistNow = async () => {
await Promise.all([
tabStore.$persistNow?.(),
zxFwPricingStore.$persistNow?.(),
kvStore.$persistNow?.()
])
}
const readForage = async (store: ForageStore): Promise<DataEntry[]> => {
const keys = await store.keys()
const entries: DataEntry[] = []
@@ -1070,18 +1081,20 @@ const buildMethod1 = (rows: ScaleMethodRowLike[] | undefined): ExportMethod1 | n
const det = rows
.map(row => {
const major = toSafeInteger(row.id)
if (major == null || row.budgetFee == null) return null
if (major == null) return null
const cost = toFiniteNumber(row.amount)
const basicFee = toFiniteNumber(row.budgetFee)
if (basicFee != null) hasTotalValue = true
const basicFeeBasic = toFiniteNumber(row.budgetFeeBasic)
const basicFeeOptional = toFiniteNumber(row.budgetFeeOptional)
const basicFee = toFiniteNumber(row.benchmarkBudget)
const basicFeeBasic = toFiniteNumber(row.benchmarkBudgetBasic)
const basicFeeOptional = toFiniteNumber(row.benchmarkBudgetOptional)
const fee = toFiniteNumber(row.budgetFee)
if (basicFee != null || fee != null) hasTotalValue = true
const remark = typeof row.remark === 'string' ? row.remark : ''
const hasValue =
cost != null ||
basicFee != null ||
basicFeeBasic != null ||
basicFeeOptional != null ||
fee != null ||
isNonEmptyString(remark)
if (!hasValue) return null
return {
@@ -1096,7 +1109,7 @@ const buildMethod1 = (rows: ScaleMethodRowLike[] | undefined): ExportMethod1 | n
majorCoe: toFiniteNumberOrZero(row.majorFactor),
processCoe: toFiniteNumber(row.workStageFactor) ?? 1,
proportion: toFiniteNumber(row.workRatio) ?? 1,
fee: basicFee ?? 0,
fee: fee ?? 0,
remark
}
})
@@ -1119,18 +1132,20 @@ const buildMethod2 = (rows: ScaleMethodRowLike[] | undefined): ExportMethod2 | n
const det = rows
.map(row => {
const major = toSafeInteger(row.id)
if (major == null || row.budgetFee == null) return null
if (major == null) return null
const area = toFiniteNumber(row.landArea)
const basicFee = toFiniteNumber(row.budgetFee)
if (basicFee != null) hasTotalValue = true
const basicFeeBasic = toFiniteNumber(row.budgetFeeBasic)
const basicFeeOptional = toFiniteNumber(row.budgetFeeOptional)
const basicFee = toFiniteNumber(row.benchmarkBudget)
const basicFeeBasic = toFiniteNumber(row.benchmarkBudgetBasic)
const basicFeeOptional = toFiniteNumber(row.benchmarkBudgetOptional)
const fee = toFiniteNumber(row.budgetFee)
if (basicFee != null || fee != null) hasTotalValue = true
const remark = typeof row.remark === 'string' ? row.remark : ''
const hasValue =
area != null ||
basicFee != null ||
basicFeeBasic != null ||
basicFeeOptional != null ||
fee != null ||
isNonEmptyString(remark)
if (!hasValue) return null
return {
@@ -1145,7 +1160,7 @@ const buildMethod2 = (rows: ScaleMethodRowLike[] | undefined): ExportMethod2 | n
majorCoe: toFiniteNumberOrZero(row.majorFactor),
processCoe: toFiniteNumber(row.workStageFactor) ?? 1,
proportion: toFiniteNumber(row.workRatio) ?? 1,
fee: basicFee ?? 0,
fee: fee ?? 0,
remark
}
})
@@ -1337,8 +1352,9 @@ const loadHtFeeMethodsByRow = async (mainStorageKey: string, rowId: string) => {
}
const buildAdditionalDetailCode = (index: number, name: string): unknown => {
const dictionaryIndex = additionalWorkList.findIndex(item => item === name)
const useIndex = dictionaryIndex >= 0 ? dictionaryIndex : index
const dictItem = additionalWorkList.find(item => String(item?.name || '').trim() === String(name || '').trim())
if (dictItem?.code) return dictItem.code
const useIndex = index
const suffix = useIndex === 0 ? 'F' : useIndex === 1 ? 'X' : String(useIndex + 1)
return createRichTextCode('C', suffix)
}
@@ -1356,8 +1372,7 @@ const buildAdditionalExport = async (contractId: string): Promise<ExportAddition
if (!methodPayload) return null
const item: ExportAdditionalDetail = {
id: index,
code: { richText: [{ font: { charset: 134, color: { theme: 1 }, italic: true, name: '宋体', size: 10 }, text: 'C' }, { font: { charset: 134, color: { theme: 1 }, italic: true, name: 'Calibri', size: 10, vertAlign: 'subscript' }, text: 'F' }] },
code: buildAdditionalDetailCode(index, row.name),
name: row.name,
fee: methodPayload.fee
}
@@ -1371,8 +1386,7 @@ const buildAdditionalExport = async (contractId: string): Promise<ExportAddition
if (det.length === 0) return null
return {
code: { richText: [{ font: { charset: 134, color: { theme: 1 }, italic: true, name: '宋体', size: 10 }, text: 'C' }, { font: { charset: 134, color: { theme: 1 }, italic: true, name: 'Calibri', size: 10, vertAlign: 'subscript' }, text: 'C' }] },
code: createRichTextCode('C', 'C'),
name: '附加工作',
fee: sumNumbers(det.map(item => item.fee)),
det
@@ -1389,6 +1403,7 @@ const buildReserveExport = async (contractId: string): Promise<ExportReserve | n
const methodPayload = await loadHtFeeMethodsByRow(storageKey, row.id)
if (!methodPayload) continue
const reserve: ExportReserve = {
code: reserveList[0]?.code || createRichTextCode('Y', 'B'),
name: row.name || '预备费',
fee: methodPayload.fee
}
@@ -1577,6 +1592,8 @@ const buildExportReportPayload = async (): Promise<ExportReportPayload> => {
const exportData = async () => {
try {
// 先把 Pinia 内存态强制落盘,避免导出快照缺失附加工作费/预备费最新值。
await flushPiniaPersistNow()
const now = new Date()
const piniaForageStores = await Promise.all(
getPiniaPersistStores().map(async ({ storeName, store }) => ({
@@ -1623,6 +1640,7 @@ const exportReport = async () => {
const payload = await buildExportReportPayload()
showReportExportProgress(80, '正在生成并写出报表文件...')
const fileName = `${sanitizeFileNamePart(payload.name)}-报表-${formatExportTimestamp(now)}`
console.log(payload)
await exportFile(fileName, payload)
finishReportExportProgress(true, '报表导出完成')
} catch (error) {
@@ -1683,7 +1701,10 @@ const confirmImportOverride = async () => {
const readPersistedState = (storeId: string) => {
const storeName = getPiniaPersistStoreName(storeId)
const entries = snapshotMap.get(storeName) || []
const hit = entries.find(entry => entry.key === storeName)
const hit =
entries.find(entry => entry.key === storeName) ||
entries.find(entry => entry.key === storeId) ||
entries.find(entry => entry.value && typeof entry.value === 'object')
return hit && hit.value && typeof hit.value === 'object' ? hit.value : null
}