From 66069ef0f146cae26cefec9f5125dbb46f094e6e Mon Sep 17 00:00:00 2001 From: wintsa <770775984@qq.com> Date: Wed, 18 Mar 2026 17:57:20 +0800 Subject: [PATCH] =?UTF-8?q?=E6=AD=A3=E5=9C=A8=E4=BF=AE=E5=A4=8D=E4=B8=80?= =?UTF-8?q?=E4=BA=9B=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .claude/settings.local.json | 13 +- CLAUDE.md | 138 +++++++----------- debug-screenshot-1.png | Bin 0 -> 109408 bytes src/components/ht/zxFw.vue | 75 ++++++---- src/components/shared/WorkContentGrid.vue | 15 +- .../views/HtFeeMethodTypeLineView.vue | 2 +- src/components/views/ZxFwView.vue | 5 + src/layout/tab.vue | 11 +- src/pinia/zxFwPricing.ts | 26 ++-- src/sql.ts | 60 +++++++- src/style.css | 4 +- 11 files changed, 207 insertions(+), 142 deletions(-) create mode 100644 debug-screenshot-1.png diff --git a/.claude/settings.local.json b/.claude/settings.local.json index 566cfe0..142b08e 100644 --- a/.claude/settings.local.json +++ b/.claude/settings.local.json @@ -14,7 +14,18 @@ "mcp__context7__query-docs", "mcp__ag-mcp__detect_version", "WebSearch", - "WebFetch(domain:reka-ui.com)" + "WebFetch(domain:reka-ui.com)", + "mcp__ag-mcp__set_versions", + "mcp__ag-mcp__search_docs", + "Bash(find /c/Users/77077/Desktop/JGJS2026/node_modules/ag-grid-community -name *.css -exec grep -l auto-height {})", + "Bash(2)", + "Bash(bunx vue-tsc:*)", + "Bash(curl -s http://localhost:5173)", + "mcp__plugin_chrome-devtools-mcp_chrome-devtools__list_pages", + "mcp__plugin_chrome-devtools-mcp_chrome-devtools__navigate_page", + "mcp__plugin_chrome-devtools-mcp_chrome-devtools__take_screenshot", + "mcp__plugin_chrome-devtools-mcp_chrome-devtools__evaluate_script", + "mcp__plugin_chrome-devtools-mcp_chrome-devtools__press_key" ] } } diff --git a/CLAUDE.md b/CLAUDE.md index f921c53..7a4397c 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -1,115 +1,85 @@ - - # CLAUDE.md This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. -# 任何项目都务必遵守的规则(极其重要!!!) +## Project Overview +保持中文回复和中文询问 -## Communication +Offline, client-side Vue 3 application for calculating transportation infrastructure consulting fees (交通工程造价咨询收费). All data persists to IndexedDB via localforage — there is no backend API. -- 永远使用简体中文进行思考和对话 +## Tech Stack -## Documentation +- **Framework**: Vue 3 with Composition API (` diff --git a/src/layout/tab.vue b/src/layout/tab.vue index cf2b3c7..904ff0a 100644 --- a/src/layout/tab.vue +++ b/src/layout/tab.vue @@ -1637,9 +1637,8 @@ const exportReport = async () => { finishReportExportProgress(true, '报表导出完成', blobUrl) } catch (error) { console.error('export report failed:', error) - if (reportExportToastOpen.value) { - finishReportExportProgress(false, '报表导出失败,请重试') - } + finishReportExportProgress(false, '报表导出失败,请重试') + } finally { dataMenuOpen.value = false } @@ -2038,15 +2037,15 @@ watch( {{ reportExportStatus === 'running' ? '导出报表' : (reportExportStatus === 'success' ? '导出成功' : '导出失败') }} {{ reportExportText }} -
+ +
workload: toFiniteNumberOrNull(row.workload), hourly: toFiniteNumberOrNull(row.hourly), subtotal: toFiniteNumberOrNull(row.subtotal), + finalFee: toFiniteNumberOrNull(row.finalFee), actions: row.actions } }).filter(row => row.id) @@ -107,7 +109,6 @@ const applyRowSubtotals = (rows: ZxFwDetailRow[]): ZxFwDetailRow[] => { const totalWorkload = sumNullableNumbers(nonFixedRows.map(row => row.workload)) const totalHourly = sumNullableNumbers(nonFixedRows.map(row => row.hourly)) const fixedSubtotal = sumNullableNumbers([totalInvestScale, totalLandScale, totalWorkload, totalHourly]) - return normalized.map(row => { if (row.id === FIXED_ROW_ID) { return { @@ -116,7 +117,9 @@ const applyRowSubtotals = (rows: ZxFwDetailRow[]): ZxFwDetailRow[] => { landScale: round3Nullable(totalLandScale), workload: round3Nullable(totalWorkload), hourly: round3Nullable(totalHourly), - subtotal: round3Nullable(fixedSubtotal) + subtotal: round3Nullable(fixedSubtotal), + finalFee: row.finalFee, + } } const subtotal = sumNullableNumbers([ @@ -127,7 +130,9 @@ const applyRowSubtotals = (rows: ZxFwDetailRow[]): ZxFwDetailRow[] => { ]) return { ...row, - subtotal: round3Nullable(subtotal) + subtotal: round3Nullable(subtotal), + finalFee: round3Nullable(subtotal), + } }) } @@ -181,6 +186,7 @@ const isSameRows = (a: ZxFwDetailRow[] | undefined, b: ZxFwDetailRow[] | undefin if (!isSameNullableNumber(l.workload, r.workload)) return false if (!isSameNullableNumber(l.hourly, r.hourly)) return false if (!isSameNullableNumber(l.subtotal, r.subtotal)) return false + if (!isSameNullableNumber(l.finalFee, r.finalFee)) return false } return true } @@ -568,7 +574,7 @@ export const useZxFwPricingStore = defineStore('zxFwPricing', () => { mainStorageKeyRaw: string | number, force = false ): Promise | null> => { - + const mainStorageKey = toKey(mainStorageKeyRaw) if (!mainStorageKey) return null if (!force) { @@ -663,7 +669,7 @@ export const useZxFwPricingStore = defineStore('zxFwPricing', () => { ) => { const mainStorageKey = toKey(mainStorageKeyRaw) const rowId = toKey(rowIdRaw) - + if (!mainStorageKey || !rowId) return false const storageKey = getHtFeeMethodStorageKey(mainStorageKey, rowId, method) if (!storageKey) return false @@ -986,7 +992,10 @@ export const useZxFwPricingStore = defineStore('zxFwPricing', () => { : null const current = contracts.value[contractId] if (raw) { + console.log(raw,'init') + const normalized = normalizeState(raw) + console.log(normalized) if (!current || !isSameState(current, normalized)) { contracts.value[contractId] = normalized touchVersion(contractId) @@ -1039,12 +1048,10 @@ export const useZxFwPricingStore = defineStore('zxFwPricing', () => { field: ZxFwPricingField value: number | null | undefined }) => { + const contractId = toKey(params.contractId) if (!contractId) return false - - if (!contracts.value[contractId]) { - await loadContract(contractId) - } + const current = contracts.value[contractId] if (!current?.detailRows?.length) return false @@ -1090,7 +1097,6 @@ export const useZxFwPricingStore = defineStore('zxFwPricing', () => { if (!contractId) return null const state = contracts.value[contractId] if (!state?.detailRows?.length) return null - const fixedRow = state.detailRows.find(row => String(row.id || '') === FIXED_ROW_ID) const fixedFinalFee = toFiniteNumberOrNull(fixedRow?.finalFee) if (fixedFinalFee != null) return round3(fixedFinalFee) diff --git a/src/sql.ts b/src/sql.ts index 5ecd9c8..3763c5a 100644 --- a/src/sql.ts +++ b/src/sql.ts @@ -11,7 +11,16 @@ const toFiniteNumber = (value: unknown) => { const num = Number(value) return Number.isFinite(num) ? num : 0 } +export type WorkType = '基本工作' | '可选工作' | '日常顾问' | '专项顾问' | '附加工作' | '自定义' +export const TYPE_LABEL_MAP: Record = { + 0: '基本工作', + 1: '可选工作', + 2: '日常顾问', + 3: '专项顾问', + 4: '附加工作', + 5:'自定义' +} export const industryTypeList = [ { id: '0', name: '公路工程', type: 'isRoad' }, { id: '1', name: '铁路工程', type: 'isRailway' }, @@ -337,6 +346,56 @@ export const workList = { 146: { text: '作为造价咨询服务总体协调单位,依据造价技术标准的具体条款或委托方的个性化需求,进一步细化各项工作的具体要求,检查其他服务单位的造价文件的组成完整性、电子文件格式是否符合要求、电子版与纸质版是否对应、造价文件报表的规范性', serviceid: -1, order: 147, type: 4 }, 147: { text: '作为造价咨询服务总体协调单位,负责总体协调其他咨询人或专家团队的工作,确保各方在项目服务中的沟通顺畅,监控造价咨询服务的进展情况,确保各咨询人按时完成工作', serviceid: -1, order: 148, type: 4 }, } +//工作内容树形关系表 +export const wholeProcessTasks = [ + { + fid: 0, + industry: 0, + sid: [6, 7, 8, 9, 11, 13], + }, + { + fid: 0, + industry: 1, + sid: [6, 7, 8, 9, 10, 12, 13], + }, + { + fid: 0, + industry: 2, + sid: [6, 7, 8, 9, 11, 13], + }, + { + fid: 2, + industry: 0, + sid: [6, 7, 8], + }, + { + fid: 2, + industry: 1, + sid: [6, 7, 8], + }, + { + fid: 2, + industry: 2, + sid: [6, 7, 8], + }, + { + fid: 3, + industry: 0, + sid: [9, 11, 13], + }, + { + fid: 4, + industry: 1, + sid: [9, 10, 12, 13], + }, + { + fid: 3, + industry: 2, + sid: [9, 11, 13], + }, +]; + + let costScaleCal = [ { code: 'C1-1', staLine: 0, endLine: 100, basic: { staPrice: 0, rate: 0.01 }, optional: { staPrice: 0, rate: 0.002 } }, @@ -372,7 +431,6 @@ let areaScaleCal = [ -export type WorkType = '基本工作' | '可选工作' | '日常顾问' | '专项顾问' | '附加工作' | '自定义' export type IndustryType = (typeof industryTypeList)[number]['type'] type DictItem = Record diff --git a/src/style.css b/src/style.css index f8472f7..96c43ae 100644 --- a/src/style.css +++ b/src/style.css @@ -144,10 +144,10 @@ html { } /* When one column uses auto-height rows, keep other columns vertically centered. */ -.xmMx .ag-row .ag-cell-wrapper { +/* .xmMx .ag-row .ag-cell-wrapper { height: 100%; -} +} */ .xmMx .ag-row .ag-cell:not(.ag-cell-auto-height) .ag-cell-wrapper.ag-row-group { align-items: center;