diff --git a/src/components/common/HourlyFeeGrid.vue b/src/components/common/HourlyFeeGrid.vue index 63846c3..4d0b564 100644 --- a/src/components/common/HourlyFeeGrid.vue +++ b/src/components/common/HourlyFeeGrid.vue @@ -423,7 +423,17 @@ const columnDefs: (ColDef | ColGroupDef)[] = [ const totalPersonnelCount = computed(() => sumByNumber(detailRows.value, row => row.personnelCount)) const totalWorkdayCount = computed(() => sumByNumber(detailRows.value, row => row.workdayCount)) -const totalServiceBudget = computed(() => sumByNumber(detailRows.value, row => calcServiceBudget(row))) +const sumNullableBy = (rows: T[], pick: (row: T) => unknown): number | null => { + let hasValid = false + const total = sumByNumber(rows, row => { + const value = Number(pick(row)) + if (!Number.isFinite(value)) return null + hasValid = true + return value + }) + return hasValid ? total : null +} +const totalServiceBudget = computed(() => sumNullableBy(detailRows.value, row => calcServiceBudget(row))) const pinnedTopRowData = computed(() => [ { id: 'pinned-total-row', diff --git a/src/components/views/Ht.vue b/src/components/views/Ht.vue index d0b6fb5..239d90b 100644 --- a/src/components/views/Ht.vue +++ b/src/components/views/Ht.vue @@ -59,6 +59,12 @@ interface XmBaseInfoState { projectIndustry?: string } +interface XmScaleState { + detailRows?: unknown[] + roughCalcEnabled?: boolean + totalAmount?: number | null +} + const STORAGE_KEY = 'ht-card-v1' const CONTRACT_SEGMENT_FILE_EXTENSION = '.htzw' const CONTRACT_SEGMENT_VERSION = 2 @@ -68,6 +74,7 @@ const CONTRACT_CONSULT_FACTOR_KEY_PREFIX = 'ht-consult-category-factor-v1-' const CONTRACT_MAJOR_FACTOR_KEY_PREFIX = 'ht-major-factor-v1-' const PRICING_KEY_PREFIXES = ['tzGMF-', 'ydGMF-', 'gzlF-', 'hourlyPricing-', 'htExtraFee-'] const PROJECT_INFO_KEY = 'xm-base-info-v1' +const PROJECT_SCALE_KEY = 'xm-info-v3' const SERVICE_PRICING_METHODS = ['investScale', 'landScale', 'workload', 'hourly'] as const @@ -361,6 +368,19 @@ const saveContracts = async () => { } } +const initializeContractScaleData = async (contractId: string) => { + const source = await kvStore.getItem(PROJECT_SCALE_KEY) + const payload: XmScaleState = { + detailRows: Array.isArray(source?.detailRows) ? cloneJson(source.detailRows) : [], + roughCalcEnabled: Boolean(source?.roughCalcEnabled), + totalAmount: + typeof source?.totalAmount === 'number' && Number.isFinite(source.totalAmount) + ? source.totalAmount + : null + } + await kvStore.setItem(`${CONTRACT_KEY_PREFIX}${contractId}`, payload) +} + const normalizeContractsFromPayload = (value: unknown): ContractItem[] => { if (!Array.isArray(value)) return [] return value @@ -795,17 +815,20 @@ const createContract = async () => { return } - contracts.value = [ - ...contracts.value, - { - id: `ct-${Date.now()}-${Math.random().toString(16).slice(2, 6)}`, - name, - order: contracts.value.length, - createdAt: new Date().toISOString() - } - ] + const newContract: ContractItem = { + id: `ct-${Date.now()}-${Math.random().toString(16).slice(2, 6)}`, + name, + order: contracts.value.length, + createdAt: new Date().toISOString() + } + contracts.value = [...contracts.value, newContract] await saveContracts() + try { + await initializeContractScaleData(newContract.id) + } catch (error) { + console.error('initialize contract scale failed:', error) + } notify('新建成功') closeCreateModal() await nextTick() diff --git a/src/components/views/info.vue b/src/components/views/info.vue index 01cac97..5a22445 100644 --- a/src/components/views/info.vue +++ b/src/components/views/info.vue @@ -1,7 +1,14 @@