Browse Source

Merge branch 'kanban_table' of shuzhihua/pms-iot-vue into master

yanghao 1 day ago
parent
commit
3e42412d42
4 changed files with 593 additions and 134 deletions
  1. 1 1
      .env.local
  2. 157 31
      pnpm-lock.yaml
  3. 429 101
      src/views/pms/stat/rdkb.vue
  4. 6 1
      vite.config.ts

+ 1 - 1
.env.local

@@ -4,7 +4,7 @@ NODE_ENV=development
 VITE_DEV=true
 
 # 请求路径
-VITE_BASE_URL='http://localhost:48080'
+VITE_BASE_URL='https://iot.deepoil.cc'
 
 # 文件上传类型:server - 后端上传, client - 前端直连上传,仅支持 S3 服务
 VITE_UPLOAD_TYPE=server

+ 157 - 31
pnpm-lock.yaml

@@ -35,6 +35,9 @@ importers:
       '@microsoft/fetch-event-source':
         specifier: ^2.0.1
         version: 2.0.1
+      '@types/echarts':
+        specifier: ^5.0.0
+        version: 5.0.0
       '@videojs-player/vue':
         specifier: ^1.0.0
         version: 1.0.0(@types/video.js@7.3.58)(video.js@7.21.6)(vue@3.5.12(typescript@5.3.3))
@@ -74,21 +77,30 @@ importers:
       crypto-js:
         specifier: ^4.2.0
         version: 4.2.0
+      date-fns:
+        specifier: ^4.1.0
+        version: 4.1.0
+      date.js:
+        specifier: ^0.3.3
+        version: 0.3.3
       dayjs:
         specifier: ^1.11.10
         version: 1.11.13
       diagram-js:
         specifier: ^12.8.0
         version: 12.8.1
+      dingtalk-jsapi:
+        specifier: ^3.1.0
+        version: 3.2.2
       driver.js:
         specifier: ^1.3.1
         version: 1.3.1
       echarts:
-        specifier: ^5.5.0
-        version: 5.5.1
+        specifier: ^5.6.0
+        version: 5.6.0
       echarts-wordcloud:
         specifier: ^2.1.0
-        version: 2.1.0(echarts@5.5.1)
+        version: 2.1.0(echarts@5.6.0)
       element-plus:
         specifier: 2.9.1
         version: 2.9.1(vue@3.5.12(typescript@5.3.3))
@@ -125,6 +137,9 @@ importers:
       mitt:
         specifier: ^3.0.1
         version: 3.0.1
+      moment:
+        specifier: ^2.30.1
+        version: 2.30.1
       nprogress:
         specifier: ^0.2.0
         version: 0.2.0
@@ -134,6 +149,9 @@ importers:
       pinia-plugin-persistedstate:
         specifier: ^3.2.1
         version: 3.2.3(pinia@2.2.8(typescript@5.3.3)(vue@3.5.12(typescript@5.3.3)))
+      pinyin:
+        specifier: ^4.0.0
+        version: 4.0.0
       qrcode:
         specifier: ^1.5.3
         version: 1.5.4
@@ -161,6 +179,9 @@ importers:
       vue-dompurify-html:
         specifier: ^4.1.4
         version: 4.1.4(vue@3.5.12(typescript@5.3.3))
+      vue-echarts:
+        specifier: ^7.0.3
+        version: 7.0.3(@vue/runtime-core@3.5.12)(echarts@5.6.0)(vue@3.5.12(typescript@5.3.3))
       vue-i18n:
         specifier: 9.10.2
         version: 9.10.2(vue@3.5.12(typescript@5.3.3))
@@ -1431,42 +1452,36 @@ packages:
     engines: {node: '>= 10.0.0'}
     cpu: [arm]
     os: [linux]
-    libc: [glibc]
 
   '@parcel/watcher-linux-arm-musl@2.5.0':
     resolution: {integrity: sha512-6uHywSIzz8+vi2lAzFeltnYbdHsDm3iIB57d4g5oaB9vKwjb6N6dRIgZMujw4nm5r6v9/BQH0noq6DzHrqr2pA==}
     engines: {node: '>= 10.0.0'}
     cpu: [arm]
     os: [linux]
-    libc: [musl]
 
   '@parcel/watcher-linux-arm64-glibc@2.5.0':
     resolution: {integrity: sha512-BfNjXwZKxBy4WibDb/LDCriWSKLz+jJRL3cM/DllnHH5QUyoiUNEp3GmL80ZqxeumoADfCCP19+qiYiC8gUBjA==}
     engines: {node: '>= 10.0.0'}
     cpu: [arm64]
     os: [linux]
-    libc: [glibc]
 
   '@parcel/watcher-linux-arm64-musl@2.5.0':
     resolution: {integrity: sha512-S1qARKOphxfiBEkwLUbHjCY9BWPdWnW9j7f7Hb2jPplu8UZ3nes7zpPOW9bkLbHRvWM0WDTsjdOTUgW0xLBN1Q==}
     engines: {node: '>= 10.0.0'}
     cpu: [arm64]
     os: [linux]
-    libc: [musl]
 
   '@parcel/watcher-linux-x64-glibc@2.5.0':
     resolution: {integrity: sha512-d9AOkusyXARkFD66S6zlGXyzx5RvY+chTP9Jp0ypSTC9d4lzyRs9ovGf/80VCxjKddcUvnsGwCHWuF2EoPgWjw==}
     engines: {node: '>= 10.0.0'}
     cpu: [x64]
     os: [linux]
-    libc: [glibc]
 
   '@parcel/watcher-linux-x64-musl@2.5.0':
     resolution: {integrity: sha512-iqOC+GoTDoFyk/VYSFHwjHhYrk8bljW6zOhPuhi5t9ulqiYq1togGJB5e3PwYVFFfeVgc6pbz3JdQyDoBszVaA==}
     engines: {node: '>= 10.0.0'}
     cpu: [x64]
     os: [linux]
-    libc: [musl]
 
   '@parcel/watcher-win32-arm64@2.5.0':
     resolution: {integrity: sha512-twtft1d+JRNkM5YbmexfcH/N4znDtjgysFaV9zvZmmJezQsKpkfLYJ+JFV3uygugK6AtIM2oADPkB2AdhBrNig==}
@@ -1570,55 +1585,46 @@ packages:
     resolution: {integrity: sha512-9OwUnK/xKw6DyRlgx8UizeqRFOfi9mf5TYCw1uolDaJSbUmBxP85DE6T4ouCMoN6pXw8ZoTeZCSEfSaYo+/s1w==}
     cpu: [arm]
     os: [linux]
-    libc: [glibc]
 
   '@rollup/rollup-linux-arm-musleabihf@4.27.4':
     resolution: {integrity: sha512-Vgdo4fpuphS9V24WOV+KwkCVJ72u7idTgQaBoLRD0UxBAWTF9GWurJO9YD9yh00BzbkhpeXtm6na+MvJU7Z73A==}
     cpu: [arm]
     os: [linux]
-    libc: [musl]
 
   '@rollup/rollup-linux-arm64-gnu@4.27.4':
     resolution: {integrity: sha512-pleyNgyd1kkBkw2kOqlBx+0atfIIkkExOTiifoODo6qKDSpnc6WzUY5RhHdmTdIJXBdSnh6JknnYTtmQyobrVg==}
     cpu: [arm64]
     os: [linux]
-    libc: [glibc]
 
   '@rollup/rollup-linux-arm64-musl@4.27.4':
     resolution: {integrity: sha512-caluiUXvUuVyCHr5DxL8ohaaFFzPGmgmMvwmqAITMpV/Q+tPoaHZ/PWa3t8B2WyoRcIIuu1hkaW5KkeTDNSnMA==}
     cpu: [arm64]
     os: [linux]
-    libc: [musl]
 
   '@rollup/rollup-linux-powerpc64le-gnu@4.27.4':
     resolution: {integrity: sha512-FScrpHrO60hARyHh7s1zHE97u0KlT/RECzCKAdmI+LEoC1eDh/RDji9JgFqyO+wPDb86Oa/sXkily1+oi4FzJQ==}
     cpu: [ppc64]
     os: [linux]
-    libc: [glibc]
 
   '@rollup/rollup-linux-riscv64-gnu@4.27.4':
     resolution: {integrity: sha512-qyyprhyGb7+RBfMPeww9FlHwKkCXdKHeGgSqmIXw9VSUtvyFZ6WZRtnxgbuz76FK7LyoN8t/eINRbPUcvXB5fw==}
     cpu: [riscv64]
     os: [linux]
-    libc: [glibc]
 
   '@rollup/rollup-linux-s390x-gnu@4.27.4':
     resolution: {integrity: sha512-PFz+y2kb6tbh7m3A7nA9++eInGcDVZUACulf/KzDtovvdTizHpZaJty7Gp0lFwSQcrnebHOqxF1MaKZd7psVRg==}
     cpu: [s390x]
     os: [linux]
-    libc: [glibc]
 
   '@rollup/rollup-linux-x64-gnu@4.27.4':
     resolution: {integrity: sha512-Ni8mMtfo+o/G7DVtweXXV/Ol2TFf63KYjTtoZ5f078AUgJTmaIJnj4JFU7TK/9SVWTaSJGxPi5zMDgK4w+Ez7Q==}
     cpu: [x64]
     os: [linux]
-    libc: [glibc]
 
   '@rollup/rollup-linux-x64-musl@4.27.4':
     resolution: {integrity: sha512-5AeeAF1PB9TUzD+3cROzFTnAJAcVUGLuR8ng0E0WXGkYhp6RD6L+6szYVX+64Rs0r72019KHZS1ka1q+zU/wUw==}
     cpu: [x64]
     os: [linux]
-    libc: [musl]
 
   '@rollup/rollup-win32-arm64-msvc@4.27.4':
     resolution: {integrity: sha512-yOpVsA4K5qVwu2CaS3hHxluWIK5HQTjNV4tWjQXluMiiiu4pJj4BN98CvxohNCpcjMeTXk/ZMJBRbgRg8HBB6A==}
@@ -1664,28 +1670,24 @@ packages:
     engines: {node: '>=10'}
     cpu: [arm64]
     os: [linux]
-    libc: [glibc]
 
   '@swc/core-linux-arm64-musl@1.9.3':
     resolution: {integrity: sha512-tzVH480RY6RbMl/QRgh5HK3zn1ZTFsThuxDGo6Iuk1MdwIbdFYUY034heWUTI4u3Db97ArKh0hNL0xhO3+PZdg==}
     engines: {node: '>=10'}
     cpu: [arm64]
     os: [linux]
-    libc: [musl]
 
   '@swc/core-linux-x64-gnu@1.9.3':
     resolution: {integrity: sha512-ivXXBRDXDc9k4cdv10R21ccBmGebVOwKXT/UdH1PhxUn9m/h8erAWjz5pcELwjiMf27WokqPgaWVfaclDbgE+w==}
     engines: {node: '>=10'}
     cpu: [x64]
     os: [linux]
-    libc: [glibc]
 
   '@swc/core-linux-x64-musl@1.9.3':
     resolution: {integrity: sha512-ILsGMgfnOz1HwdDz+ZgEuomIwkP1PHT6maigZxaCIuC6OPEhKE8uYna22uU63XvYcLQvZYDzpR3ms47WQPuNEg==}
     engines: {node: '>=10'}
     cpu: [x64]
     os: [linux]
-    libc: [musl]
 
   '@swc/core-win32-arm64-msvc@1.9.3':
     resolution: {integrity: sha512-e+XmltDVIHieUnNJHtspn6B+PCcFOMYXNJB1GqoCcyinkEIQNwC8KtWgMqUucUbEWJkPc35NHy9k8aCXRmw9Kg==}
@@ -1826,6 +1828,10 @@ packages:
   '@types/d3@7.4.3':
     resolution: {integrity: sha512-lZXZ9ckh5R8uiFVt8ogUNf+pIrK4EsWrx2Np75WvF/eTpJ0FMHNhjXk8CKEx/+gpHbNQyJWehbFaTvqmHWB3ww==}
 
+  '@types/echarts@5.0.0':
+    resolution: {integrity: sha512-5uc/16BlYpzH8kU/u8aeRRgY2FV6yRY7RjPnYfUFPowl0F3kvNgfaz09PmeVdLkqdAtMft3XkCfqiJPJjG2DNQ==}
+    deprecated: This is a stub types definition. echarts provides its own type definitions, so you do not need this installed.
+
   '@types/eslint@8.56.12':
     resolution: {integrity: sha512-03ruubjWyOHlmljCVoxSuNDdmfZDzsrrz0P2LeJsOXr+ZwFQ+0yQIwNCwt/GYhV7Z31fgtXJTAEs+FYlEL851g==}
 
@@ -2656,6 +2662,10 @@ packages:
     resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==}
     engines: {node: '>= 0.8'}
 
+  commander@1.1.1:
+    resolution: {integrity: sha512-71Rod2AhcH3JhkBikVpNd0pA+fWsmAaVoti6OR38T76chA7vE3pSerS0Jor4wDw+tOueD2zLVvFOw5H0Rcj7rA==}
+    engines: {node: '>= 0.6.x'}
+
   commander@12.1.0:
     resolution: {integrity: sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==}
     engines: {node: '>=18'}
@@ -2931,12 +2941,26 @@ packages:
     resolution: {integrity: sha512-wAV9QHOsNbwnWdNW2FYvE1P56wtgSbM+3SZcdGiWQILwVjACCXDCI3Ai8QlCjMDB8YK5zySiXZYBiwGmNY3lnw==}
     engines: {node: '>=12'}
 
+  date-fns@4.1.0:
+    resolution: {integrity: sha512-Ukq0owbQXxa/U3EGtsdVBkR1w7KOQ5gIBqdH2hkvknzZPYvBxb/aa6E8L7tmjFtkwZBu3UXBbjIgPo/Ez4xaNg==}
+
+  date.js@0.3.3:
+    resolution: {integrity: sha512-HgigOS3h3k6HnW011nAb43c5xx5rBXk8P2v/WIT9Zv4koIaVXiH2BURguI78VVp+5Qc076T7OR378JViCnZtBw==}
+
   dayjs@1.11.13:
     resolution: {integrity: sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==}
 
   de-indent@1.0.2:
     resolution: {integrity: sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==}
 
+  debug@3.1.0:
+    resolution: {integrity: sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==}
+    peerDependencies:
+      supports-color: '*'
+    peerDependenciesMeta:
+      supports-color:
+        optional: true
+
   debug@4.3.7:
     resolution: {integrity: sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==}
     engines: {node: '>=6.0'}
@@ -2999,6 +3023,9 @@ packages:
   dijkstrajs@1.0.3:
     resolution: {integrity: sha512-qiSlmBq9+BCdCA/L46dw8Uy93mloxsPSbwnm5yrKn2vMPiy8KyAskTF6zuV/j5BMsmOGZDPs7KjU+mjb670kfA==}
 
+  dingtalk-jsapi@3.2.2:
+    resolution: {integrity: sha512-FglWzvdMJosOkX8k2MVavX3MiDIE6vAmAHqVE0bvXRfh3El4DVqACQRw1UIyKi3UloUS07XQXGRAG6S12eehgg==}
+
   dir-glob@3.0.1:
     resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==}
     engines: {node: '>=8'}
@@ -3057,8 +3084,8 @@ packages:
     peerDependencies:
       echarts: ^5.0.1
 
-  echarts@5.5.1:
-    resolution: {integrity: sha512-Fce8upazaAXUVUVsjgV6mBnGuqgO+JNDlcgF79Dksy4+wgGpQB2lmYoO4TSweFg/mZITdpGHomw/cNBJZj1icA==}
+  echarts@5.6.0:
+    resolution: {integrity: sha512-oTbVTsXfKuEhxftHqL5xprgLoc0k7uScAwtryCgWF6hPYFLRwOUHiFmHGCBKP5NPFNkDVopOieyUqYGH8Fa3kA==}
 
   ejs@3.1.10:
     resolution: {integrity: sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==}
@@ -3727,6 +3754,9 @@ packages:
   keycode@2.2.1:
     resolution: {integrity: sha512-Rdgz9Hl9Iv4QKi8b0OlCRQEzp4AgVxyCtz5S/+VIHezDmrDhkp2N2TqBWOLz0/gbeREXOOiI9/4b8BY9uw2vFg==}
 
+  keypress@0.1.0:
+    resolution: {integrity: sha512-x0yf9PL/nx9Nw9oLL8ZVErFAk85/lslwEP7Vz7s5SI1ODXZIgit3C5qyWjw4DxOuO/3Hb4866SQh28a1V1d+WA==}
+
   keyv@4.5.4:
     resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==}
 
@@ -4012,6 +4042,9 @@ packages:
   moddle@6.2.3:
     resolution: {integrity: sha512-bLVN+ZHL3aKnhxc19XtjUfvdJsS3EsiEJC7bT6YPD11qYmTzvsxrGgyYz1Ouof7TZuGw0lDJ1OLmEnxcpQWk3Q==}
 
+  moment@2.30.1:
+    resolution: {integrity: sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==}
+
   mpd-parser@0.22.1:
     resolution: {integrity: sha512-fwBebvpyPUU8bOzvhX0VQZgSohncbgYwUyJJoTSNpmy7ccD2ryiCvM7oRkn/xQH5cv73/xU7rJSNCLjdGFor0Q==}
     hasBin: true
@@ -4020,6 +4053,9 @@ packages:
     resolution: {integrity: sha512-eu38+hdgojoyq63s+yTpN4XMBdt5l8HhMhc4VKLO9KM5caLIBvUm4thi7fFaxyTmCKeNnXZ5pAlBwCUnhA09uw==}
     engines: {node: '>=10'}
 
+  ms@2.0.0:
+    resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==}
+
   ms@2.1.3:
     resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
 
@@ -4252,6 +4288,22 @@ packages:
       typescript:
         optional: true
 
+  pinyin@4.0.0:
+    resolution: {integrity: sha512-vHpV5K+vpp6XUUpZNGRDuHoN+1xcmieM3EWlH4QjSX2kkpG/gVOwpqwV9EOJ9x9c9UERFKeLml5XVSukE/PLgQ==}
+    engines: {install-node: ^18.0.0}
+    hasBin: true
+    peerDependencies:
+      '@node-rs/jieba': ^1.6.0
+      nodejieba: ^3.4.4
+      segmentit: ^2.0.3
+    peerDependenciesMeta:
+      '@node-rs/jieba':
+        optional: true
+      nodejieba:
+        optional: true
+      segmentit:
+        optional: true
+
   pkcs7@1.0.4:
     resolution: {integrity: sha512-afRERtHn54AlwaF2/+LFszyAANTCggGilmcmILUzEjvs3XgFZT+xE6+QWQcAGmu4xajy+Xtj7acLOPdx5/eXWQ==}
     hasBin: true
@@ -4355,6 +4407,9 @@ packages:
     resolution: {integrity: sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==}
     engines: {node: '>=0.4.0'}
 
+  promise-polyfill@7.1.2:
+    resolution: {integrity: sha512-FuEc12/eKqqoRYIGBrUptCBRhobL19PS2U31vMNTfyck1FxPyMfgsXyW4Mav85y/ZN1hop3hOwRlUDok23oYfQ==}
+
   proxy-from-env@1.1.0:
     resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==}
 
@@ -5007,6 +5062,17 @@ packages:
       terser:
         optional: true
 
+  vue-demi@0.13.11:
+    resolution: {integrity: sha512-IR8HoEEGM65YY3ZJYAjMlKygDQn25D5ajNFNoKh9RSDMQtlzCxtfQjdQgv9jjK+m3377SsJXY8ysq8kLCZL25A==}
+    engines: {node: '>=12'}
+    hasBin: true
+    peerDependencies:
+      '@vue/composition-api': ^1.0.0-rc.1
+      vue: ^3.0.0-0 || ^2.6.0
+    peerDependenciesMeta:
+      '@vue/composition-api':
+        optional: true
+
   vue-demi@0.14.10:
     resolution: {integrity: sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==}
     engines: {node: '>=12'}
@@ -5023,6 +5089,16 @@ packages:
     peerDependencies:
       vue: ^2.7.0 || ^3.0.0
 
+  vue-echarts@7.0.3:
+    resolution: {integrity: sha512-/jSxNwOsw5+dYAUcwSfkLwKPuzTQ0Cepz1LxCOpj2QcHrrmUa/Ql0eQqMmc1rTPQVrh2JQ29n2dhq75ZcHvRDw==}
+    peerDependencies:
+      '@vue/runtime-core': ^3.0.0
+      echarts: ^5.5.1
+      vue: ^2.7.0 || ^3.1.1
+    peerDependenciesMeta:
+      '@vue/runtime-core':
+        optional: true
+
   vue-eslint-parser@9.4.3:
     resolution: {integrity: sha512-2rYRLWlIpaiN8xbPiDyXZXRgLGOtWxERV7ND5fFAv5qo1D2N9Fu9MNajBNc6o13lZ+24DAWCkQCvj4klgmcITg==}
     engines: {node: ^14.17.0 || >=16.0.0}
@@ -5200,8 +5276,8 @@ packages:
   zeebe-bpmn-moddle@1.7.0:
     resolution: {integrity: sha512-eZ6OXSt0c4n9V/oN/46gTlwDIS3GhWQLt9jbM5uS/YryB4yN8wdrrKrtw+TpyNy0SSKWXNDHyC83nCA2blPO3Q==}
 
-  zrender@5.6.0:
-    resolution: {integrity: sha512-uzgraf4njmmHAbEUxMJ8Oxg+P3fT04O+9p7gY+wJRVxo8Ge+KmYv0WJev945EH4wFuc4OY2NLXz46FZrWS9xJg==}
+  zrender@5.6.1:
+    resolution: {integrity: sha512-OFXkDJKcrlx5su2XbzJvj/34Q3m6PvyCZkVPHGYpcCJ52ek4U/ymZyfuV1nKE23AyBJ51E/6Yr0mhZ7xGTO4ag==}
 
 snapshots:
 
@@ -6823,6 +6899,10 @@ snapshots:
       '@types/d3-transition': 3.0.9
       '@types/d3-zoom': 3.0.8
 
+  '@types/echarts@5.0.0':
+    dependencies:
+      echarts: 5.6.0
+
   '@types/eslint@8.56.12':
     dependencies:
       '@types/estree': 1.0.6
@@ -7960,6 +8040,10 @@ snapshots:
     dependencies:
       delayed-stream: 1.0.0
 
+  commander@1.1.1:
+    dependencies:
+      keypress: 0.1.0
+
   commander@12.1.0: {}
 
   commander@2.20.3: {}
@@ -8246,10 +8330,22 @@ snapshots:
 
   dargs@8.1.0: {}
 
+  date-fns@4.1.0: {}
+
+  date.js@0.3.3:
+    dependencies:
+      debug: 3.1.0
+    transitivePeerDependencies:
+      - supports-color
+
   dayjs@1.11.13: {}
 
   de-indent@1.0.2: {}
 
+  debug@3.1.0:
+    dependencies:
+      ms: 2.0.0
+
   debug@4.3.7:
     dependencies:
       ms: 2.1.3
@@ -8316,6 +8412,10 @@ snapshots:
 
   dijkstrajs@1.0.3: {}
 
+  dingtalk-jsapi@3.2.2:
+    dependencies:
+      promise-polyfill: 7.1.2
+
   dir-glob@3.0.1:
     dependencies:
       path-type: 4.0.0
@@ -8368,14 +8468,14 @@ snapshots:
 
   eastasianwidth@0.2.0: {}
 
-  echarts-wordcloud@2.1.0(echarts@5.5.1):
+  echarts-wordcloud@2.1.0(echarts@5.6.0):
     dependencies:
-      echarts: 5.5.1
+      echarts: 5.6.0
 
-  echarts@5.5.1:
+  echarts@5.6.0:
     dependencies:
       tslib: 2.3.0
-      zrender: 5.6.0
+      zrender: 5.6.1
 
   ejs@3.1.10:
     dependencies:
@@ -9086,6 +9186,8 @@ snapshots:
 
   keycode@2.2.1: {}
 
+  keypress@0.1.0: {}
+
   keyv@4.5.4:
     dependencies:
       json-buffer: 3.0.1
@@ -9392,6 +9494,8 @@ snapshots:
     dependencies:
       min-dash: 4.2.2
 
+  moment@2.30.1: {}
+
   mpd-parser@0.22.1:
     dependencies:
       '@babel/runtime': 7.26.0
@@ -9401,6 +9505,8 @@ snapshots:
 
   mrmime@2.0.0: {}
 
+  ms@2.0.0: {}
+
   ms@2.1.3: {}
 
   muggle-string@0.3.1: {}
@@ -9588,6 +9694,10 @@ snapshots:
     optionalDependencies:
       typescript: 5.3.3
 
+  pinyin@4.0.0:
+    dependencies:
+      commander: 1.1.1
+
   pkcs7@1.0.4:
     dependencies:
       '@babel/runtime': 7.26.0
@@ -9684,6 +9794,8 @@ snapshots:
 
   progress@2.0.3: {}
 
+  promise-polyfill@7.1.2: {}
+
   proxy-from-env@1.1.0: {}
 
   punycode.js@2.3.1: {}
@@ -10410,6 +10522,10 @@ snapshots:
       sass: 1.81.0
       terser: 5.36.0
 
+  vue-demi@0.13.11(vue@3.5.12(typescript@5.3.3)):
+    dependencies:
+      vue: 3.5.12(typescript@5.3.3)
+
   vue-demi@0.14.10(vue@3.5.12(typescript@5.3.3)):
     dependencies:
       vue: 3.5.12(typescript@5.3.3)
@@ -10422,6 +10538,16 @@ snapshots:
     transitivePeerDependencies:
       - '@vue/composition-api'
 
+  vue-echarts@7.0.3(@vue/runtime-core@3.5.12)(echarts@5.6.0)(vue@3.5.12(typescript@5.3.3)):
+    dependencies:
+      echarts: 5.6.0
+      vue: 3.5.12(typescript@5.3.3)
+      vue-demi: 0.13.11(vue@3.5.12(typescript@5.3.3))
+    optionalDependencies:
+      '@vue/runtime-core': 3.5.12
+    transitivePeerDependencies:
+      - '@vue/composition-api'
+
   vue-eslint-parser@9.4.3(eslint@8.57.1):
     dependencies:
       debug: 4.3.7
@@ -10614,6 +10740,6 @@ snapshots:
 
   zeebe-bpmn-moddle@1.7.0: {}
 
-  zrender@5.6.0:
+  zrender@5.6.1:
     dependencies:
       tslib: 2.3.0

+ 429 - 101
src/views/pms/stat/rdkb.vue

@@ -2,7 +2,7 @@
   <div class="page-container">
     <el-row :gutter="16" class="summary">
       <!-- 原有的统计卡片部分保持不变 -->
-      <el-col v-loading="loading" :sm="3" :xs="12">
+      <el-col v-loading="loading" :sm="3" :xs="24">
         <SummaryCard
           :value="device.total || 0"
           icon="fa-solid:project-diagram"
@@ -11,7 +11,7 @@
           :title="t('stat.deviceCount')"
         />
       </el-col>
-      <el-col v-loading="loading" :sm="3" :xs="12">
+      <el-col v-loading="loading" :sm="3" :xs="24">
         <SummaryCard
           :value="maintain.total || 0"
           icon="fa-solid:list"
@@ -20,7 +20,7 @@
           :title="t('stat.repairOrder')"
         />
       </el-col>
-      <el-col v-loading="loading" :sm="3" :xs="12">
+      <el-col v-loading="loading" :sm="3" :xs="24">
         <SummaryCard
           :value="fill.unfilledCount || 0"
           icon="fa-solid:times-circle"
@@ -29,7 +29,7 @@
           :title="t('stat.operationNotFilled')"
         />
       </el-col>
-      <el-col v-loading="loading" :sm="3" :xs="12">
+      <el-col v-loading="loading" :sm="3" :xs="24">
         <SummaryCard
           :value="fill.filledCount || 0"
           icon="fa-solid:award"
@@ -38,7 +38,7 @@
           :title="t('stat.operationFilled')"
         />
       </el-col>
-      <el-col v-loading="loading" :sm="3" :xs="12">
+      <el-col v-loading="loading" :sm="3" :xs="24">
         <SummaryCard
           :value="by.todo || 0"
           icon="fa-solid:times-circle"
@@ -47,7 +47,7 @@
           :title="t('stat.notMaintained')"
         />
       </el-col>
-      <el-col v-loading="loading" :sm="3" :xs="12">
+      <el-col v-loading="loading" :sm="3" :xs="24">
         <SummaryCard
           :value="by.finished || 0"
           icon="fa-solid:award"
@@ -56,7 +56,7 @@
           :title="t('stat.maintained')"
         />
       </el-col>
-      <el-col v-loading="loading" :sm="3" :xs="12">
+      <el-col v-loading="loading" :sm="3" :xs="24">
         <SummaryCard
           :value="inspect.todo || 0"
           icon="fa-solid:times-circle"
@@ -77,17 +77,58 @@
     </el-row>
     <el-row :gutter="16" class="mb-4">
       <!-- 设备状态统计和工单数量情况图表部分保持不变 -->
-      <el-col :span="10">
+      <el-col :span="6" :xs="24">
         <el-card class="chart-card" shadow="never">
           <template #header>
             <div class="flex items-center">
               <span class="text-base font-medium " style="color: #b6c8da">{{t('stat.deviceStatus')}}</span>
             </div>
           </template>
-          <div ref="statusChartRef" class="h-[290px]"></div>
+          <div style="display:flex; align-items:center;min-height: 292px;">
+            <div ref="statusChartRef" style="width:100%; max-width:250px; height:250px;"></div>
+            <div class="text-[12px]" style="width:100%; display:flex; flex-wrap:wrap; justify-content:center; gap:8px; color:#fff;margin-top: -50px;">
+              <div v-for="item in legendData" :key="item.name" style="display:flex; align-items:center; gap:12px; padding:0; min-width:160px; justify-content:space-between;">
+                <div style="display:flex; align-items:center; gap:8px;">
+                  <span :style="{display:'inline-block', width:'12px', height:'12px', 'border-radius':'50%', background:item.color}"></span>
+                  <span>{{ item.name }}</span>
+                </div>
+                <div style="display:flex; align-items:center; gap:10px; color:#fff;">
+                  <span style="font-weight:700">{{ item.value }} 台</span>
+                  <span>{{ item.percent }}%</span>
+                </div>
+              </div>
+            </div>
+          </div>
+        </el-card>
+      </el-col>
+      <el-col :span="10" :xs="24">
+          <el-card class="chart-card" shadow="never">
+          <template #header>
+            <div class="flex items-center justify-between">
+              <span class="text-base font-medium " style="color: #b6c8da">国内设备分布及价值(国内RMB)</span>
+            </div>
+          </template>
+          <div class="overflow-auto">
+            <el-table
+              :data="projectData"
+              border
+              @row-click="projectDataRowClick"
+              :header-cell-style="{color:'#fff'}"
+              :cell-style="{ color: '#fff', height: '65px' }"
+              style="width:100%"
+              
+              >
+              
+              <el-table-column prop="dept" label="地区" width="120" align="center" fixed="left" />
+              <el-table-column prop="count" label="设备数量" min-width="100" align="center" />
+              <el-table-column prop="orig_value" label="原值(万元)" min-width="100" align="center" />
+              <el-table-column prop="net_value" label="净值(万元)" min-width="120" align="center" />
+              <el-table-column prop="orig_ratio" label="原值占比" min-width="100" align="center" />
+            </el-table>
+          </div>
         </el-card>
       </el-col>
-      <el-col :span="14">
+      <el-col :span="8" :xs="24">
         <el-card class="chart-card" shadow="never">
           <template #header>
             <div class="flex items-center justify-between">
@@ -98,9 +139,10 @@
         </el-card>
       </el-col>
     </el-row>
+   
     <el-row :gutter="16" class="mb-4">
       <!-- 备件更换情况部分保持不变 -->
-      <el-col :span="10">
+      <el-col :span="10" :xs="24">
         <el-card class="chart-card" shadow="never">
           <template #header>
             <div style="display: flex; flex-direction: row; justify-content: space-between">
@@ -193,68 +235,53 @@
           </div>
         </el-card>
       </el-col>
-      <el-col :span="14">
-        <div class="flex flex-col justify-between">
-          <el-card class="chart-card" shadow="never">
-            <template #header>
-              <div class="flex items-center justify-between">
-                <span class="text-base font-medium " style="color: #b6c8da">{{t('stat.maintenanceStatus')}}</span>
-              </div>
-            </template>
-            <div class="flex mr-3">
-              <div ref="maintenanceChartRef" class="h-[167px] w-2/5"></div>
-              <div class="w-3/5 p-4 flex flex-col mt-5">
-                <div class="flex justify-between">
-                  <div class="flex flex-col items-center">
-                    <Icon icon="fa-solid:list" size="30" color="#f1d209" />
-                    <p style="font-size: 20px; margin-top: 5px;color: #91cc75">{{t('stat.totalOrder')}}</p>
-                    <span style="font-size: 20px;color: white">{{ (by.finished?by.finished:0) + (by.todo?by.todo:0) }}</span>
-                  </div>
-                  <div class="flex flex-col items-center">
-                    <Icon icon="fa-solid:check-circle" size="30" color="green" />
-                    <p style="font-size: 20px; margin-top: 5px;color: #91cc75">{{t('stat.finishedOrder')}}</p>
-                    <span style="font-size: 20px;color: white">{{ by.finished?by.finished:0 }}</span>
-                  </div>
-                  <div class="flex flex-col items-center">
-                    <Icon icon="fa-solid:hourglass-half" size="30" color="#e14f0f" />
-                    <p style="font-size: 20px; margin-top: 5px;color: #91cc75">{{t('stat.pendingOrder')}} </p>
-                    <span style="font-size: 20px;color: white">{{ by.todo?by.todo:0 }}</span>
-                  </div>
-                </div>
-              </div>
-            </div>
-          </el-card>
-          <el-card class="chart-card mt-2" shadow="never">
-            <template #header>
-              <div class="flex items-center justify-between">
-                <span class="text-base font-medium " style="color: #b6c8da">{{t('stat.inspectStatus')}}</span>
-              </div>
-            </template>
-            <div class="flex mr-3">
-              <div ref="inspectChartRef" class="h-[167px] w-2/5"></div>
-              <div class="w-3/5 p-4 flex flex-col mt-5">
-                <div class="flex justify-between">
-                  <div class="flex flex-col items-center">
-                    <Icon icon="fa-solid:list" size="30" color="#f1d209" />
-                    <p style="font-size: 20px; margin-top: 5px;color: #91cc75">{{t('stat.totalOrder')}}</p>
-                    <span style="font-size: 20px;color: white">{{ inspect.todo + inspect.finished }}</span>
-                  </div>
-                  <div class="flex flex-col items-center">
-                    <Icon icon="fa-solid:check-circle" size="30" color="green" />
-                    <p style="font-size: 20px; margin-top: 5px;color: #91cc75">{{t('stat.finishedOrder')}}</p>
-                    <span style="font-size: 20px;color: white">{{ inspect.finished }}</span>
-                  </div>
-                  <div class="flex flex-col items-center">
-                    <Icon icon="fa-solid:hourglass-half" size="30" color="#e14f0f" />
-                    <p style="font-size: 20px; margin-top: 5px;color: #91cc75">{{t('stat.pendingOrder')}}</p>
-                    <span style="font-size: 20px;color: white">{{ inspect.todo }}</span>
-                  </div>
-                </div>
-              </div>
+      <!-- 月度工作量表 -->
+      <el-col :span="14" :xs="24">
+        <el-card class="chart-card" shadow="never">
+          <template #header>
+            <div class="flex items-center justify-between">
+              <span class="text-base font-medium " style="color: #b6c8da">月度工作量表</span>
             </div>
-          </el-card>
-        </div>
+          </template>
+          <div class="overflow-auto">
+            <el-table
+              :data="monthData"
+              border
+              height="420px"
+              :disabled-affix="true"
+              style="width:100%"
+              :header-cell-style="{color:'#fff'}"
+              :cell-style="{ color: '#fff' }"
+              :summary-method="tableSummary"
+             
+              show-summary>
+              <el-table-column prop="month" label="月份" width="80" fixed="left"  align="center" />
+
+              <el-table-column label="2025年"  align="center">
+                <el-table-column prop="y2025_fractures" label="压裂井数"  align="center" width="110" />
+                <el-table-column prop="y2025_layers" label="压裂层数" width="110"  align="center" />
+                <el-table-column prop="y2025_pump_trips" label="泵车台次" width="110"  align="center" />
+                <el-table-column prop="y2025_oil_wells" label="连油井数" width="110"  align="center" />
+              </el-table-column>
+
+              <el-table-column label="2024年"  align="center">
+                <el-table-column prop="y2024_fractures" label="压裂井数" width="110"  align="center" />
+                <el-table-column prop="y2024_layers" label="压裂层数" width="110" align="center" />
+                <el-table-column prop="y2024_pump_trips" label="泵车台次" width="110"  align="center" />
+                <el-table-column prop="y2024_oil_wells" label="连油井数" width="110" align="center" />
+              </el-table-column>
+
+              <el-table-column label="同比增长量" align="center">
+                <el-table-column prop="diff_fractures" label="压裂井数" width="110" align="center" />
+                <el-table-column prop="diff_layers" label="压裂层数" width="110" align="center" />
+                <el-table-column prop="diff_pump_trips" label="泵车台次" width="110" align="center" />
+                <el-table-column prop="diff_oil_wells" label="连油井数" width="110" align="center" />
+              </el-table-column>
+            </el-table>
+          </div>
+        </el-card>
       </el-col>
+      <!-- 月度工作量表结束 -->
     </el-row>
   </div>
   <el-dialog
@@ -303,6 +330,111 @@
       </el-table>
     </div>
   </el-dialog>
+
+   <el-dialog
+    v-model="projectDataDialog"
+   
+    width="45vw"
+    
+    class="custom-scroll-dialog"
+  >
+    <div class="dialog-scroll-content">
+       <el-card class="bg-[#284d72]!" shadow="never">
+          <template #header>
+            <div class="flex items-center justify-between">
+              <span class="text-base font-medium " style="color: #b6c8da">国内设备分布及价值(国内RMB)</span>
+            </div>
+          </template>
+          <div class="overflow-auto" style="min-height:260px;">
+            <el-table
+              :data="domesticData"
+              border
+               :header-cell-style="{color:'#fff'}"
+              :cell-style="{ color: '#fff' }"
+              style="width:100%"
+              :summary-method="tableSummary"
+              show-summary>
+              <el-table-column prop="index" label="序号" width="60" align="center" fixed="left" />
+              <el-table-column prop="dept" label="项目部" width="120" align="center" fixed="left" />
+              <el-table-column prop="count" label="设备数量" min-width="100" align="center" />
+              <el-table-column prop="orig_value" label="原值(万元)" min-width="120" align="center" />
+              <el-table-column prop="net_value" label="净值(万元)" min-width="120" align="center" />
+              <el-table-column prop="orig_ratio" label="原值占比" min-width="100" align="center" />
+            </el-table>
+          </div>
+        </el-card>
+    </div>
+  </el-dialog>
+   <el-dialog
+    v-model="projectDataDialog2"
+   
+    width="45vw"
+    
+    class="custom-scroll-dialog"
+  >
+    <div class="dialog-scroll-content">
+       <el-card class="bg-[#284d72]!" shadow="never">
+          <template #header>
+            <div class="flex items-center justify-between">
+              <span class="text-base font-medium " style="color: #b6c8da">伊拉克设备分布及价值(美元)</span>
+            </div>
+          </template>
+          <div class="overflow-auto" style="min-height:260px;">
+            <el-table
+              :data="iraqTableData"
+              border
+              :header-cell-style="{color:'#fff'}"
+              :cell-style="{ color: '#fff' }"
+              style="width:100%"
+              
+              >
+              <el-table-column prop="index" label="序号" width="60" align="center" fixed="left" />
+              <el-table-column prop="dept" label="项目部" width="120" align="center" fixed="left" />
+              <el-table-column prop="count" label="设备数量" min-width="100" align="center" />
+              <el-table-column prop="orig_value_usd" label="原值(万元)" min-width="120" align="center" />
+              <el-table-column prop="net_value_usd" label="净值(万元)" min-width="120" align="center" />
+              <el-table-column prop="orig_ratio" label="原值占比" min-width="100" align="center" />
+            </el-table>
+          </div>
+        </el-card>
+    </div>
+  </el-dialog>
+
+   <el-dialog
+    v-model="projectDataDialog3"
+   
+    width="45vw"
+    
+    class="custom-scroll-dialog"
+  >
+    <div class="dialog-scroll-content">
+       <el-card class="bg-[#284d72]!" shadow="never">
+          <template #header>
+            <div class="flex items-center justify-between">
+              <span class="text-base font-medium " style="color: #b6c8da">利比亚设备分布及价值(第纳尔)</span>
+            </div>
+          </template>
+          <div class="overflow-auto" style="min-height:260px;">
+            <el-table
+              :data="libyaTableData"
+              border
+              :header-cell-style="{color:'#fff'}"
+              :cell-style="{ color: '#fff' }"
+              :row-class-name="tableRowClass"
+              style="width:100%"
+              :summary-method="tableSummary"
+              >
+              <el-table-column prop="index" label="序号" width="60" align="center" fixed="left" />
+              <el-table-column prop="dept" label="项目部" width="120" align="center" fixed="left" />
+              <el-table-column prop="count" label="设备数量" min-width="100" align="center" />
+              <el-table-column prop="orig_value" label="原值(万元)" min-width="120" align="center" />
+              <el-table-column prop="net_value" label="净值(万元)" min-width="120" align="center" />
+              <el-table-column prop="orig_ratio" label="原值占比" min-width="100" align="center" />
+            </el-table>
+          </div>
+        </el-card>
+    </div>
+  </el-dialog>
 </template>
 <script lang="ts" setup>
 import { MemberSummaryRespVO } from '@/api/mall/statistics/member'
@@ -358,6 +490,7 @@ const handleDialogClose = () => {
   teamDialogVisible.value = false
   teamTableData.value = [] // 清空表格数据
 }
+
 // 格式化利用率为百分比
 const formatRate = (row) => {
   return (row.utilizationRate * 100).toFixed(2) + '%'
@@ -383,6 +516,7 @@ const handleRowClick = (row, column, event) => {
 const dateRange = ref<[Date, Date] | null>(null)
 const summary = ref<MemberSummaryRespVO>() // 会员统计数据
 const statusChartRef = ref() // 设备数量统计的图表
+let statusChartInstance = null
 const qxRef = ref(null)
 let qxInstance = null
 const sparePartRef = ref(null)
@@ -396,7 +530,20 @@ let inspectionChartInstance = null
 const { t } = useI18n() // 国际化
 const maintenanceChartRef1 = ref(null)
 
-const typeData = ref({})
+const typeData = ref([])
+// 配色(与图表保持一致)
+const statusColors = ['#2ed3df', '#34d399', '#ff6b95', '#4aa3ff', '#f59e0b', '#ef4444', '#7dd3fc']
+
+const legendData = computed(() => {
+  const arr = Array.isArray(typeData.value) ? typeData.value : []
+  const total = arr.reduce((s, it) => s + (Number(it.value) || 0), 0)
+  return arr.map((it, idx) => ({
+    name: it.name,
+    value: it.value || 0,
+    percent: total ? ((Number(it.value) / total) * 100).toFixed(2) : '0.00',
+    color: statusColors[idx % statusColors.length]
+  }))
+})
 const orderSevenData = ref({})
 const device = ref({
   total: undefined,
@@ -878,45 +1025,187 @@ const initInspectionChart = () => {
 
 /** 初始化图表 */
 const initDeviceStatusCharts = () => {
-  // 设备数量统计
-  echarts.init(statusChartRef.value).setOption({
+  if (!statusChartRef.value) return
+  // dispose old instance
+  try {
+    if (statusChartInstance) {
+      statusChartInstance.dispose()
+      statusChartInstance = null
+    }
+  } catch (e) {
+    // ignore
+  }
+  statusChartInstance = echarts.init(statusChartRef.value)
+  const data = Array.isArray(typeData.value) ? typeData.value : []
+  const option = {
+    color: statusColors,
     tooltip: {
-      trigger: 'item'
-    },
-    legend: {
-      orient: 'horizontal', // 水平排列图例项
-      bottom: '0%', // 放置在底部
-      icon: 'circle',
-      textStyle: {
-        color: '#B6C8DA'
-      }
+      trigger: 'item',
+      formatter: '{b}: {c} ({d}%)'
     },
     series: [
       {
         name: '',
         type: 'pie',
-        radius: ['50%', '80%'],
+        radius: ['45%', '65%'],
+        center: ['50%', '36%'],
         avoidLabelOverlap: false,
-        center: ['50%', '44%'],
-        label: {
-          show: false,
-          position: 'outside'
-        },
-        emphasis: {
-          label: {
-            show: true,
-            fontSize: 15,
-            fontWeight: 'bold',
-            color: 'white'
-          }
-        },
-        labelLine: {
-          show: false
-        },
-        data: typeData.value
+        label: { show: false },
+        labelLine: { show: false },
+        data: data.map((it) => ({ name: it.name, value: it.value }))
       }
     ]
+  }
+  statusChartInstance.setOption(option)
+}
+
+// 月度工作量表数据
+const monthData = ref<any[]>([
+  { month: '1月', y2025_fractures: 49, y2025_layers: 102, y2025_pump_trips: 621, y2025_oil_wells: 17, y2024_fractures: 23, y2024_layers: 42, y2024_pump_trips: 347, y2024_oil_wells: 9 },
+  { month: '2月', y2025_fractures: 30, y2025_layers: 52, y2025_pump_trips: 438, y2025_oil_wells: 15, y2024_fractures: 14, y2024_layers: 41, y2024_pump_trips: 46, y2024_oil_wells: 11 },
+  { month: '3月', y2025_fractures: 48, y2025_layers: 127, y2025_pump_trips: 326, y2025_oil_wells: 30, y2024_fractures: 42, y2024_layers: 58, y2024_pump_trips: 321, y2024_oil_wells: 17 },
+  { month: '4月', y2025_fractures: 49, y2025_layers: 130, y2025_pump_trips: 1203, y2025_oil_wells: 45, y2024_fractures: 32, y2024_layers: 184, y2024_pump_trips: 1046, y2024_oil_wells: 30 },
+  { month: '5月', y2025_fractures: 13, y2025_layers: 76, y2025_pump_trips: 701, y2025_oil_wells: 18, y2024_fractures: 73, y2024_layers: 133, y2024_pump_trips: 414, y2024_oil_wells: 24 },
+  { month: '6月', y2025_fractures: 34, y2025_layers: 187, y2025_pump_trips: 831, y2025_oil_wells: 30, y2024_fractures: 29, y2024_layers: 113, y2024_pump_trips: 750, y2024_oil_wells: 35 },
+  { month: '7月', y2025_fractures: 30, y2025_layers: 230, y2025_pump_trips: 1157, y2025_oil_wells: 51, y2024_fractures: 24, y2024_layers: 47, y2024_pump_trips: 326, y2024_oil_wells: 17 },
+  { month: '8月', y2025_fractures: 59, y2025_layers: 218, y2025_pump_trips: 1163, y2025_oil_wells: 12, y2024_fractures: 36, y2024_layers: 121, y2024_pump_trips: 1107, y2024_oil_wells: 26 },
+  { month: '9月', y2025_fractures: 48, y2025_layers: 80, y2025_pump_trips: 440, y2025_oil_wells: 39, y2024_fractures: 35, y2024_layers: 162, y2024_pump_trips: 928, y2024_oil_wells: 36 },
+  { month: '10月', y2025_fractures: 45, y2025_layers: 99, y2025_pump_trips: 697, y2025_oil_wells: 49, y2024_fractures: 36, y2024_layers: 116, y2024_pump_trips: 891, y2024_oil_wells: 33 },
+  { month: '11月', y2025_fractures: null, y2025_layers: null, y2025_pump_trips: null, y2025_oil_wells: null, y2024_fractures: 19, y2024_layers: 102, y2024_pump_trips: 582, y2024_oil_wells: 36 },
+  { month: '12月', y2025_fractures: null, y2025_layers: null, y2025_pump_trips: null, y2025_oil_wells: null, y2024_fractures: 51, y2024_layers: 186, y2024_pump_trips: 971, y2024_oil_wells: 32 }
+])
+
+// 计算同比差值(2025 - 2024),保留 null 的情况
+monthData.value.forEach((row) => {
+  const f2025 = row.y2025_fractures
+  const f2024 = row.y2024_fractures
+  row.diff_fractures = (f2025 == null || f2024 == null) ? null : (f2025 - f2024)
+
+  const l2025 = row.y2025_layers
+  const l2024 = row.y2024_layers
+  row.diff_layers = (l2025 == null || l2024 == null) ? null : (l2025 - l2024)
+
+  const p2025 = row.y2025_pump_trips
+  const p2024 = row.y2024_pump_trips
+  row.diff_pump_trips = (p2025 == null || p2024 == null) ? null : (p2025 - p2024)
+
+  const o2025 = row.y2025_oil_wells
+  const o2024 = row.y2024_oil_wells
+  row.diff_oil_wells = (o2025 == null || o2024 == null) ? null : (o2025 - o2024)
+})
+
+// 表格合计方法
+const tableSummary = ({ columns, data }: any) => {
+  const sums: any[] = []
+  columns.forEach((column: any, index: number) => {
+    if (index === 0) {
+      sums[index] = '合计'
+      return
+    }
+    const property = column.property
+    if (!property) {
+      sums[index] = ''
+      return
+    }
+    let total = 0
+    let hasValue = false
+    data.forEach((row: any) => {
+      const val = row[property]
+      if (val != null && !isNaN(Number(val))) {
+        total += Number(val)
+        hasValue = true
+      }
+    })
+    // 针对国内表的 "原值占比" 列,按 全局合计 计算百分比
+    if (data === domesticData.value && property === 'orig_ratio') {
+      const domesticOrig = data.reduce((acc: number, r: any) => acc + (r.orig_value ? Number(r.orig_value) : 0), 0)
+      const overall = domesticOrig + Number(iraqRmbTotal.value || 0) + Number(libyaRmbTotal.value || 0)
+      sums[index] = overall > 0 ? ( (domesticOrig / overall) * 100 ).toFixed(2) + '%' : ''
+    } else {
+      sums[index] = hasValue ? total : ''
+    }
   })
+  return sums
+}
+
+
+const projectData = ref<any[]>([
+  { index: 1, dept: '国内', count: 224, orig_value: 44653.40, net_value: 9938.77, orig_ratio: '72.52%' },
+  { index: 2, dept: '伊拉克', count: 279, orig_value: 14279.83, net_value: 5760.03, orig_ratio: '23.19%' },
+  { index: 3, dept: '利比亚', count: 22, orig_value: 2641.07, net_value: 2557.84, orig_ratio: '4.29%' },
+  { index: 4, dept: '合计', count: 525, orig_value: 61574.30, net_value: 18256.63, orig_ratio: '' }
+])
+
+let projectDataDialog = ref(false)
+let projectDataDialog2 = ref(false)
+let projectDataDialog3 = ref(false)
+
+// projectDataRowClick
+const projectDataRowClick = (row, column, event) => {
+  console.log('点击的行数据:', row);
+  
+
+  if(row.dept === '国内') {
+    // 显示国内表格
+   projectDataDialog.value = true
+  } else if (row.dept === '伊拉克') {
+    // 显示伊拉克表格
+   projectDataDialog2.value = true
+  } else if (row.dept === '利比亚') {
+    // 显示利比亚表格
+    projectDataDialog3.value = true
+  } 
+ 
+
+};
+
+
+// 三张表的数据
+const domesticData = ref<any[]>([
+  { index: 1, dept: '公滩', count: 13, orig_value: 1506.88, net_value: 559.95, orig_ratio: '2.45%' },
+  { index: 2, dept: '新疆项目部', count: 58, orig_value: 5118.1, net_value: 1182.91, orig_ratio: '8.31%' },
+  { index: 3, dept: '青海项目', count: 33, orig_value: 14082.33, net_value: 736.94, orig_ratio: '22.87%' },
+  { index: 4, dept: '东部项目部', count: 49, orig_value: 5273.54, net_value: 683.58, orig_ratio: '8.56%' },
+  { index: 5, dept: '西南连油项目部', count: 24, orig_value: 4070.12, net_value: 743.99, orig_ratio: '6.61%' },
+  { index: 6, dept: '西南压裂项目部', count: 47, orig_value: 14602.44, net_value: 6031.39, orig_ratio: '23.72%' }
+])
+
+const iraqData = ref<any[]>([
+  { index: 1, dept: '伊拉克 哈法亚连油', count: 120, orig_value_usd: 694.78, net_value_usd: 94.44, orig_ratio: '8.02%' },
+  { index: 2, dept: '伊拉克 哈法亚压裂', count: 132, orig_value_usd: 1008.92, net_value_usd: 587.07, orig_ratio: '11.65%' },
+  { index: 3, dept: '伊拉克 B9增产', count: 27, orig_value_usd: 304.72, net_value_usd: 128.62, orig_ratio: '3.52%' }
+])
+
+const iraqTableData = computed(() => {
+  const base = iraqData.value.slice()
+  base.push({ index: '', dept: '合计', count: 279, orig_value: Number(279), orig_value_usd: Number(2008.41), net_value_usd: Number(810.13), orig_ratio: '' })
+  base.push({ index: '', dept: '折算RMB合计', count: '', orig_value: Number(61574.30), orig_value_usd: Number(14279.83), net_value_usd: Number(5760.03), orig_ratio: '23.19%' })
+  return base
+})
+
+// 折算RMB合计(数值)
+const iraqRmbTotal = ref(14279.83)
+
+const libyaData = ref<any[]>([
+  { index: 1, dept: '利比亚 连油8队', count: 22, orig_value: 2025.52, net_value: 1961.69, orig_ratio: '' }
+])
+
+const libyaRmbTotal = ref(2641.07)
+const libyaRmbNet = ref(2557.84)
+
+const libyaTableData = computed(() => {
+  const base = libyaData.value.slice()
+  base.push({ index: '', dept: '折算RMB合计', count: '', orig_value: Number(libyaRmbTotal.value), net_value: Number(libyaRmbNet.value), orig_ratio: '4.29%' })
+  base.push({ index: '', dept: '国内外合计', count: 525, orig_value: Number(61574.30), net_value: Number(18256.63), orig_ratio: '' })
+  return base
+})
+
+// 行样式:合计行与折算RMB合计高亮
+const tableRowClass = (row: any) => {
+  if (!row) return ''
+  if (row.dept === '合计') return 'summary-row'
+  if (row.dept && typeof row.dept === 'string' && row.dept.indexOf('折算') !== -1) return 'rmb-row'
+  return ''
 }
 
 /** 初始化 **/
@@ -927,6 +1216,45 @@ onMounted(async () => {
 })
 </script>
 <style lang="scss" scoped>
+/*最外层透明*/
+::v-deep .el-table,
+::v-deep .el-table__expanded-cell {
+  background-color: transparent !important;
+}
+/* 表格内背景颜色 */
+
+::v-deep .el-table tr,
+::v-deep .el-table td {
+  background-color: transparent !important;
+}
+
+
+::v-deep .el-table th {
+  background-color: #2196df !important;
+}
+
+::v-deep .el-table__footer {
+  color: #fff !important;
+}
+::v-deep .el-table__footer-wrapper {
+  color: #fff !important;
+  background-color: #42c5f9 !important;
+}
+
+::v-deep th.el-table-fixed-column--left {
+  background-color: #3fc1f7 !important;
+}
+
+
+
+::v-deep .el-table__footer-wrapper .is-leaf {
+  color: #fff !important;
+}
+
+::v-deep td.el-table-fixed-column--left {
+  background-color: #3fc1f7 !important;
+}
+
 .summary {
   .el-col {
     margin-bottom: 1rem;

+ 6 - 1
vite.config.ts

@@ -80,7 +80,12 @@ export default ({command, mode}: ConfigEnv): UserConfig => {
                     }
                 },
             },
+            commonjsOptions: {
+                // 将 fullcalendar 相关包强制转换为 CommonJS
+                include: [/@fullcalendar/, /node_modules/]
+            }
         },
-        optimizeDeps: {include, exclude}
+         // 排除 fullcalendar 相关包,避免依赖扫描
+        optimizeDeps: {include,  exclude: ['@fullcalendar/core', '@fullcalendar/common']}
     }
 }