From 5734cfa5340e4bfe5778aa925235d2e8bea264e4 Mon Sep 17 00:00:00 2001 From: wintsa <770775984@qq.com> Date: Wed, 25 Feb 2026 14:26:40 +0800 Subject: [PATCH] fix more --- index.html | 4 +- public/favicon.ico | Bin 0 -> 9662 bytes src/components/ui/button/index.ts | 2 +- src/components/views/ContractDetailView.vue | 60 +++ src/components/views/Ht.vue | 284 +++++++++++-- src/components/views/Xm.vue | 2 +- src/components/views/htInfo.vue | 428 ++++++++++++++++++++ src/components/views/xmInfo.vue | 70 +--- src/components/views/zxFw.vue | 377 +++++++++++++++++ src/layout/tab.vue | 395 ++++++++++++++++-- src/layout/typeLine.vue | 2 +- src/pinia/tab.ts | 94 ++++- 12 files changed, 1584 insertions(+), 134 deletions(-) create mode 100644 public/favicon.ico create mode 100644 src/components/views/ContractDetailView.vue create mode 100644 src/components/views/htInfo.vue create mode 100644 src/components/views/zxFw.vue diff --git a/index.html b/index.html index 70ad674..973ca0d 100644 --- a/index.html +++ b/index.html @@ -2,9 +2,9 @@ - + - my-vue-app + 造价计算工具
diff --git a/public/favicon.ico b/public/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..0b5169c55c3a3cb7cb279c8841a001171771f196 GIT binary patch literal 9662 zcmds63sjX=7XG=QB7rEGky-M(fPhGXh>ARg0}+pYk_lH;GBi zgKpDmC>!eKlJuzKeQ+E;mZ(F$EOm{)rU~Y`n!j^~jD{J`98E-*Jp?$#IB zQ`5EIfA;AKE3fgMtwV!$vbJJhn~Qur+aK5~X&17}-oI%V=BjCP5%kPa&@v}M z$NU~tv3Ga2`plRy`@T?$1uR7Uo6jk2)$e&`t}fia9G(?4`uoE!o-G z(dc``kGLthxHz{SIdE?DbSHHy9~=5WKPNG93|OXwV=5tuV;i+Wo3K4^E7fC}*U9_x zxwt+lyy^^M$G^?lO>u5RRid3}BleA%q^|$w^hHZ=Z|^#2(uEyuu&}UTFTC*L{KVj@ zLufP2&+(EEC7Z|&ZXdT3b%+fU#zD%HAEb8Nb{+$agK}^sTc3Glkq93CJNemdi^qM` zjW{Ncsg{icPHxHlDRO31WG?v~CE5Zz8k;o9|76ax%h7H_D`ohJC(_*Vm~foL2lS&9 zBjOV2cv%{Uup!UGJXCETmE5o<{3sVC=yy6Q)G(%A^uLptn$3^W?=LJY^s}?GGx9&$ zVE>?fXW?6W9U{DRjZPvjrI_>Blm96m#E1UzlPz*d_#I)c)YzIMa_pEdexuQUf*szaXUHQ z-tu178U}lIpeg?EzQ3u6oS-?2dxVGuFu4NHvX@<+n~;!@hImbF81LnEe#f6${Jck~ zpbzIB;paRco1{9zPxyFyUN7mYy7ofTaU#d-bY&$s6sGvGyku_mQfG@w@DchS=hm|L zVD*W2_7#sBJ$iJTDSjJk8@6s;uHO>@stRchQw${ja16wCtT(pDv`luOH0ld`GN zIXz)V-QJ?+kpYir+C~3koFN8NA60i8D7rBkIP`%jek{+9i+eX?LETDcb36e_Nxy1wUA%HI_a*uQG0pbZ zoI6@lHdv`tUWIlt8w56Z&=8iDwIUhLlT&gY5PrGr39q~!=i+nHI+t+}&ia>AFQ*aC z-emdF2Fvhqs%vzP;eP6UznZ<3-|QV09$wfJhr+@_Kh4glOLZGU9HRBpJD()1QXA6A z?c}l1vuVy1?IrJB8`&Ffxqg1MZa40;IG&h*PYY)0HmzN|Ho)52TIPR#o;f%;bd-Jg zoqNQ1T^pSRaty{kmew)(TB?`UtGvG>oJCKESC`2#_LbkZu_4IIMh)u`_X(U&#~z=c zzI6OplZB6ukIFO#=H?3a{PWK(eI`=Bho2n=yP+TVA7Q5Pcp2{n5_Tys$Bub7OBLI& zvOc~q%<{T3Uw0^C{Iq%+2RY<^UnR@SY?v`8Va^&n3-As>c0ga|KiU8Ljc~4b*wB4~ zxGdSy6;DH4X?>aMsZ4i|2v1G(mnUvn$}#qr|6{T~&sn^a8qO9o9h(=e`(Wp;9ZvT4 z_MLM4Xvh8c+p)sJ9o|p)YwFOa-0$Rn&I<`I_q8#9q&Cz}90Tq&&poNz)gNBd`hB}v z-2EP^6uHB(RIwnXy5-n`cB{a^z%%4~xr~dOmH$#w?ItJl3Ip%B9fXJQ5-&;5Im)?( z_fXC$ZjbkfO169Z^&nGx11Zl5s``gB_#NYkb0`OC*z#v3{Efx^s03RQ z!!>8i%gcr^NO|k8fbHJTN370bZ!`WMX z`O#lSg(}q@6i>tu0PnWagEu{*qGp!L@na0ohM=J7dtP2}X_2!9?q57^gi+2Dd0xWK zIYhPvj8S)#9QehxH+%!pr$kkMOlO(+Mp9_m%L}V>($mueEiElY%(Mm&zoVmL%fWY4 zqo+Bl+xa~N`Ai(-lDN{7p6bxP_-VS61Hsr=o4gebv99p8#BurB(!sb@HQ%1Prf_p} z(-C%(=H}*X-n@B9Ni#I1{49{xBgKI*Qe1hQjMs$g;0m_##oDC4unnZ{uV3G?f;;zB z@%?Y`<9N95zx`HANOVk8KIaWT3q(G_I`;GTJDIzp@hNwBThe=uVcq_0ye?HFuRA@9ny79$^F^m6+$YWwcStJC6f7nt zI(x}Y~4 zcdCDHSDXD5cuVs2g;=yK#J#e;{OHY5fq~P?jPY|@Vq;?qmoBKzRf64wo6cMbGv^ce z#dnm3?ce>A*PY_*t6#!&-3gip@hjnsTCuoxG5p1wzAbSrxVyVI9y`+L?f+0^m)(S) z^PR90pR{aFi27V#81AMndrAFV{B}pa!}BRVxax1ErKOf`Zm!p0Y#E2l*pMMZ*oqY^ zL7(xOVXSFmjLXb9~>Sm?zV2;%}{v-%o-pC?~){z&@|j+q>xFTY!S{q=u6w>c8` zXO4sOHr8LOKYi+g!q?ZgM(%se<6A8?H8pKcSjBEf!`>@lmpFuH_3HGx$o}TP+xl<6 zVTxEkZ5{vJf^)&kwvz2AxE7e4oSbKhANM6cKfkm2uQmmF*w9(PaZ@aiKQp~`&0l{0 z>)^Y^H<11>#9zvHf_<9v7C0<^*VFIX`}RI}cw2VyN3;d-Kk&dvw(a#dTp#z==sAZt z?-9Saj^X=4N^I5kfz18iXtTfgh7W$rqjiTkB0O~0zW$=ka`NQKr%Ypj9D+AnQc8?2 z5ARX(vp@-Vk_p3AY|Gl~_;cw!`@`S(__@mO1QYFlWS^A&?2wX@G9T~IavR2s8Pj>_ z(4jGJZfy3LI8x#e*&pktI)BfA8z#z1t4((i_e8#jz?u*-6c-m;jU79-MUFo-H1sco z@5!m!^NtWNih(nn&5NI|x#Kq?jr&{W;e8!;fzE39-4Zwq=T3UE^iGBE6MG3ip3BRZ zFP~52FPVQS9lurM9U0GqDUYZ--zjPxL-qGk#s_PU;O|jW9#M53kYUKk$Oyx?CE5V* z$;RWyk6RJ0BYWCLO>Z_-Q%!N? zWi};|Xo*e$CtPgTpp zC-vPcyS4s(6emxf6pD(9dj0OV{Mnkl+cq@zTL1f?9{8-Ee$+7Xu(ca4s#myp3PWvjyR{HDo|C3y=&Y07R)UNC1pq{@6MNmjGBS z17LI1f0e@}02RyCYlR`G2f(5Pz_wVv9umT(1D61JEb0L;m&3UPz`>}$W$z=(+x9-$ fSiT*Q#bqFuEHI0qo~^pY + + + + + diff --git a/src/components/views/Ht.vue b/src/components/views/Ht.vue index 063360b..d5633eb 100644 --- a/src/components/views/Ht.vue +++ b/src/components/views/Ht.vue @@ -1,70 +1,292 @@ \ No newline at end of file + diff --git a/src/components/views/Xm.vue b/src/components/views/Xm.vue index 2c6d8f5..450dda1 100644 --- a/src/components/views/Xm.vue +++ b/src/components/views/Xm.vue @@ -16,7 +16,7 @@ const xmView = markRaw(defineAsyncComponent(() => import('@/components/views/xmI const htView = markRaw(defineAsyncComponent(() => import('@/components/views/Ht.vue'))) const xmCategories = [ - { key: 'info', label: '分类信息', component: xmView }, + { key: 'info', label: '基础信息', component: xmView }, { key: 'contract', label: '合同段管理', component: htView } ] diff --git a/src/components/views/htInfo.vue b/src/components/views/htInfo.vue new file mode 100644 index 0000000..1c3b563 --- /dev/null +++ b/src/components/views/htInfo.vue @@ -0,0 +1,428 @@ + + + + + diff --git a/src/components/views/xmInfo.vue b/src/components/views/xmInfo.vue index 4b93043..8fc0f78 100644 --- a/src/components/views/xmInfo.vue +++ b/src/components/views/xmInfo.vue @@ -2,6 +2,7 @@ import { computed, onBeforeUnmount, onMounted, ref, watch } from 'vue' import { AgGridVue } from 'ag-grid-vue3' import type { ColDef, GridOptions } from 'ag-grid-community' +import localforage from 'localforage' import 'ag-grid-enterprise' import { @@ -62,8 +63,6 @@ interface XmInfoState { detailRows: DetailRow[] } -const DB_NAME = 'jgjs-pricing-db' -const DB_STORE = 'form-state' const DB_KEY = 'xm-info-v3' const DEFAULT_PROJECT_NAME = 'xxx造价咨询服务' @@ -282,41 +281,15 @@ const pinnedTopRowData = computed(() => [ } ]) -const openDB = () => - new Promise((resolve, reject) => { - const request = window.indexedDB.open(DB_NAME, 1) - request.onupgradeneeded = () => { - const db = request.result - if (!db.objectStoreNames.contains(DB_STORE)) { - db.createObjectStore(DB_STORE) - } - } - - request.onsuccess = () => resolve(request.result) - request.onerror = () => reject(request.error) - }) const saveToIndexedDB = async () => { try { - const db = await openDB() - const tx = db.transaction(DB_STORE, 'readwrite') - const store = tx.objectStore(DB_STORE) - const payload: XmInfoState = { projectName: projectName.value, - detailRows: detailRows.value + detailRows: JSON.parse(JSON.stringify(detailRows.value)) } - - store.put(payload, DB_KEY) - - await new Promise((resolve, reject) => { - tx.oncomplete = () => resolve() - tx.onerror = () => reject(tx.error) - tx.onabort = () => reject(tx.error) - }) - - db.close() + await localforage.setItem(DB_KEY, payload) } catch (error) { console.error('saveToIndexedDB failed:', error) } @@ -324,24 +297,8 @@ const saveToIndexedDB = async () => { const loadFromIndexedDB = async () => { try { - const db = await openDB() - const tx = db.transaction(DB_STORE, 'readonly') - const store = tx.objectStore(DB_STORE) - const request = store.get(DB_KEY) - - const data = await new Promise((resolve, reject) => { - request.onsuccess = () => resolve(request.result as XmInfoState | undefined) - request.onerror = () => reject(request.error) - }) - - await new Promise((resolve, reject) => { - tx.oncomplete = () => resolve() - tx.onerror = () => reject(tx.error) - tx.onabort = () => reject(tx.error) - }) - - db.close() - + const data = await localforage.getItem(DB_KEY) +console.log(data) if (data) { projectName.value = data.projectName || DEFAULT_PROJECT_NAME detailRows.value = mergeWithDictRows(data.detailRows) @@ -363,24 +320,29 @@ const schedulePersist = () => { }, 250) } -const handleBeforeUnload = () => { - void saveToIndexedDB() -} +// const handleBeforeUnload = () => { +// void saveToIndexedDB() +// } +let gridPersistTimer: ReturnType | null = null const handleCellValueChanged = () => { - schedulePersist() + if (gridPersistTimer) clearTimeout(gridPersistTimer) + gridPersistTimer = setTimeout(() => { + void saveToIndexedDB() + }, 1000) } watch(projectName, schedulePersist) onMounted(async () => { await loadFromIndexedDB() - window.addEventListener('beforeunload', handleBeforeUnload) + // window.addEventListener('beforeunload', handleBeforeUnload) }) onBeforeUnmount(() => { - window.removeEventListener('beforeunload', handleBeforeUnload) + // window.removeEventListener('beforeunload', handleBeforeUnload) if (persistTimer) clearTimeout(persistTimer) + if (gridPersistTimer) clearTimeout(gridPersistTimer) void saveToIndexedDB() }) const processCellForClipboard = (params:any) => { diff --git a/src/components/views/zxFw.vue b/src/components/views/zxFw.vue new file mode 100644 index 0000000..0161f72 --- /dev/null +++ b/src/components/views/zxFw.vue @@ -0,0 +1,377 @@ + + + + + diff --git a/src/layout/tab.vue b/src/layout/tab.vue index 98a4a8b..21a6c56 100644 --- a/src/layout/tab.vue +++ b/src/layout/tab.vue @@ -1,62 +1,387 @@ - - \ No newline at end of file + diff --git a/src/layout/typeLine.vue b/src/layout/typeLine.vue index 89036e6..630c43a 100644 --- a/src/layout/typeLine.vue +++ b/src/layout/typeLine.vue @@ -57,7 +57,7 @@ const activeComponent = computed(() => {