From 600fe725775e28af1f86f7f7f1e2521f494252b1 Mon Sep 17 00:00:00 2001
From: liu <2021943741@qq.com>
Date: 星期二, 01 九月 2026 15:27:26 +0800
Subject: [PATCH] feat(mes): 新增管理驾驶舱页面
---
src/views/management-cockpit/modules/kpi-cards.vue | 125 ++++
src/views/management-cockpit/modules/quality-chart.vue | 67 ++
src/views/management-cockpit/modules/trace-chart.vue | 125 ++++
src/views/management-cockpit/modules/outbound-chart.vue | 77 ++
package.json | 2
src/views/management-cockpit/index.vue | 207 +++++++
src/api/mes/management-cockpit/index.ts | 158 ++++++
src/views/management-cockpit/modules/inventory-chart.vue | 82 +++
pnpm-lock.yaml | 497 ++++++++++++------
src/views/management-cockpit/chart-options.ts | 113 ++++
src/views/management-cockpit/modules/production-trend.vue | 56 ++
11 files changed, 1,330 insertions(+), 179 deletions(-)
diff --git a/package.json b/package.json
index 08c8f5e..a26e953 100644
--- a/package.json
+++ b/package.json
@@ -64,6 +64,8 @@
"fast-xml-parser": "catalog:",
"gsap": "^3.15.0",
"highlight.js": "catalog:",
+ "html-to-image": "^1.11.13",
+ "jspdf": "^4.2.1",
"livekit-client": "^2.20.0",
"pinia": "catalog:",
"sortablejs": "catalog:",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index af265b9..caab85b 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -119,7 +119,7 @@
version: 7.0.0
'@types/codemirror':
specifier: ^5.60.17
- version: 5.60.17
+ version: 5.60.18
'@types/crypto-js':
specifier: ^4.2.2
version: 4.2.2
@@ -134,7 +134,7 @@
version: 4.5.9
'@types/markdown-it':
specifier: ^14.1.2
- version: 14.1.2
+ version: 14.2.0
'@types/node':
specifier: ^25.9.4
version: 25.9.4
@@ -653,6 +653,12 @@
highlight.js:
specifier: 'catalog:'
version: 11.11.1
+ html-to-image:
+ specifier: ^1.11.13
+ version: 1.11.13
+ jspdf:
+ specifier: ^4.2.1
+ version: 4.2.1
livekit-client:
specifier: ^2.20.0
version: 2.20.0(@types/dom-mediacapture-record@1.0.22)
@@ -1625,10 +1631,10 @@
devDependencies:
'@types/codemirror':
specifier: 'catalog:'
- version: 5.60.17
+ version: 5.60.18
'@types/markdown-it':
specifier: 'catalog:'
- version: 14.1.2
+ version: 14.2.0
src/packages/effects/request:
dependencies:
@@ -3144,17 +3150,14 @@
'@jridgewell/source-map@0.3.11':
resolution: {integrity: sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==}
- '@jridgewell/sourcemap-codec@1.4.10':
- resolution: {integrity: sha512-Ht8wIW5v165atIX1p+JvKR5ONzUyF4Ac8DZIQ5kZs9zrb6M8SJNXpx1zn04rn65VjBMygRoMXcyYwNK0fT7bEg==}
-
- '@jridgewell/sourcemap-codec@1.4.14':
- resolution: {integrity: sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==}
-
'@jridgewell/sourcemap-codec@1.5.0':
resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==}
'@jridgewell/sourcemap-codec@1.5.5':
resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==}
+
+ '@jridgewell/sourcemap-codec@1.6.0':
+ resolution: {integrity: sha512-T7jf+5zgsZHwNJ4lvQ7/aezbyk0nNX+zJVWpmHA7VYsEx7a7qr5Rg5IbtJFqkgze5Y2sruq1RUY8Q837Od7iFw==}
'@jridgewell/trace-mapping@0.3.31':
resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==}
@@ -4419,8 +4422,8 @@
'@types/archiver@7.0.0':
resolution: {integrity: sha512-/3vwGwx9n+mCQdYZ2IKGGHEFL30I96UgBlk8EtRDDFQ9uxM1l4O5Ci6r00EMAkiDaTqD9DQ6nVrWRICnBPtzzg==}
- '@types/codemirror@5.60.17':
- resolution: {integrity: sha512-AZq2FIsUHVMlp7VSe2hTfl5w4pcUkoFkM3zVsRKsn1ca8CXRDYvnin04+HP2REkwsxemuHqvDofdlhUWNpbwfw==}
+ '@types/codemirror@5.60.18':
+ resolution: {integrity: sha512-aSBOPXH2PXRYixxUpVP1sJ5+S0vEfKDvR+lABZ7Kju/9Qb0SSbZk72NihWaKoQbANyibs92q4DBfYasywxnNkA==}
'@types/conventional-commits-parser@5.0.2':
resolution: {integrity: sha512-BgT2szDXnVypgpNxOK8aL5SGjUdaQbC++WZNjF1Qge3Og2+zhHj+RWhmehLhYyvQwqAmvezruVfOf8+3m74W+g==}
@@ -4476,8 +4479,8 @@
'@types/lodash@4.17.24':
resolution: {integrity: sha512-gIW7lQLZbue7lRSWEFql49QJJWThrTFFeIMJdp3eH4tKoxm1OvEPg02rm4wCCSHS0cL3/Fizimb35b7k8atwsQ==}
- '@types/markdown-it@14.1.2':
- resolution: {integrity: sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog==}
+ '@types/markdown-it@14.2.0':
+ resolution: {integrity: sha512-NoQ2yGlLWj4wpxMs+TYmRKk3thDrQ97agr7sFqfLsAlvoS8SNQuTrlObhFqG9iugdTtgOE9jpJ6FNM4ZGsa5xQ==}
'@types/mdurl@2.0.0':
resolution: {integrity: sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==}
@@ -4497,11 +4500,17 @@
'@types/nprogress@0.2.3':
resolution: {integrity: sha512-k7kRA033QNtC+gLc4VPlfnue58CM1iQLgn1IMAU8VPHGOj7oIHPp9UlhedEnD/Gl8evoCjwkZjlBORtZ3JByUA==}
+ '@types/pako@2.0.0':
+ resolution: {integrity: sha512-10+iaz93qR5WYxTo+PMifD5TSxiOtdRaxBf7INGGXMQgTCu8Z/7GYWYFUOS3q/G0nE5boj1r4FEB+WSy7s5gbA==}
+
'@types/qrcode@1.5.6':
resolution: {integrity: sha512-te7NQcV2BOvdj2b1hCAHzAoMNuj65kNBMz0KBaxM6c3VGBOhU0dURQKOtH8CFNI/dsKkwlv32p26qYQTWoB5bw==}
'@types/qs@6.15.1':
resolution: {integrity: sha512-GZHUBZR9hckSUhrxmp1nG6NwdpM9fCunJwyThLW1X3AyHgd9IlHb6VANpQQqDr2o/qQp6McZ3y/IA2rVzKzSbw==}
+
+ '@types/raf@3.4.3':
+ resolution: {integrity: sha512-c4YAvMedbPZ5tEyxzQdMoOhhJ4RD3rngZIdwC2/qDN3d7JpEhB6fiBRKVY1lg5B7Wk+uPBjn5f39j1/2MY1oOw==}
'@types/readdir-glob@1.1.5':
resolution: {integrity: sha512-raiuEPUYqXu+nvtY2Pe8s8FEmZ3x5yAH4VkLdihcPdalvsHltomrRC9BzuStrJ9yk06470hS0Crw0f1pXqD+Hg==}
@@ -4743,8 +4752,8 @@
'@vue/devtools-api@6.5.0':
resolution: {integrity: sha512-o9KfBeaBmCKl10usN4crU53fYtC1r7jJwdGKjPT24t348rHxgfpZ0xL3Xm/gLUYnc0oTp8LAmrxOeLyu6tbk2Q==}
- '@vue/devtools-api@7.5.2':
- resolution: {integrity: sha512-VxPbAQxJrYSIkoGVvQ2oOoKW8u4CMpvRLySTxhoJA38z8bQEGy9GO33eoRY/DulJbSFRfjZFNvH+dh8B4qpesQ==}
+ '@vue/devtools-api@7.7.10':
+ resolution: {integrity: sha512-KxtEpUOOpFz/qOGRrAwA36QF7DqIA+FXgCYit9mk9wjbaZt0sXOFz81ElOZtKA4HbWHUdwNjZHBFsFFyp5BZiA==}
'@vue/devtools-api@7.7.7':
resolution: {integrity: sha512-lwOnNBH2e7x1fIIbVT7yF5D+YWhqELm55/4ZKf45R9T8r9dE2AIOy8HKjfqzGsoTHFbWbr337O4E0A0QADnjBg==}
@@ -4757,8 +4766,8 @@
peerDependencies:
vue: ^3.0.0
- '@vue/devtools-kit@7.5.2':
- resolution: {integrity: sha512-0leUOE2HBfl8sHf9ePKzxqnCFskkU22tWWqd9OfeSlslAKE30/TViYvWcF4vgQmPlJnAAdHU0WfW5dYlCeOiuw==}
+ '@vue/devtools-kit@7.7.10':
+ resolution: {integrity: sha512-3WNi2Kq4tbpVbmhml7RiphmAt0279oh3fKNeWMQIrltfX8Q91b4i5PL8DtyNKdwmcsGrV4fg+erwWOmD05CLIw==}
'@vue/devtools-kit@7.7.7':
resolution: {integrity: sha512-wgoZtxcTta65cnZ1Q6MbAfePVFxfM+gq0saaeytoph7nEa7yMXoi6sCPy4ufO111B9msnw0VOWjPEFCXuAKRHA==}
@@ -4766,11 +4775,8 @@
'@vue/devtools-kit@8.1.3':
resolution: {integrity: sha512-cRn7GXiCQkMYU2Z3h3pM4YO/ndbx9FY1yLDAqIqPLcmIq4H6zAOJHein6tvZU3AfPwgrodqLiPBEF+YQaS8AxA==}
- '@vue/devtools-shared@7.5.2':
- resolution: {integrity: sha512-+zmcixnD6TAo+zwm30YuwZckhL9iIi4u+gFwbq9C8zpm3SMndTlEYZtNhAHUhOXB+bCkzyunxw80KQ/T0trF4w==}
-
- '@vue/devtools-shared@7.7.7':
- resolution: {integrity: sha512-+udSj47aRl5aKb0memBvcUG9koarqnxNM5yjuREvqwK6T3ap4mn3Zqqc17QrBFTqSMjr3HK1cvStEZpMDpfdyw==}
+ '@vue/devtools-shared@7.7.10':
+ resolution: {integrity: sha512-wOPslzB8vTvpxwdaOcR2qAbwmuSP0L+rhpoC6Cf56V3Jip+HWb7PQQXOUPgBNQARpXsbQX/+mvi8kKucmBGRwQ==}
'@vue/devtools-shared@8.1.3':
resolution: {integrity: sha512-CM3uIPL+v+lrJUk33+pxspYo0MhuMWlCvf7zC9fybifvCPyM2jUbYRPwoYEJgYbwRqPikm5HozbUhp60MF2QuA==}
@@ -4946,8 +4952,8 @@
resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==}
engines: {node: '>=8'}
- ansi-regex@6.2.2:
- resolution: {integrity: sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==}
+ ansi-regex@6.3.0:
+ resolution: {integrity: sha512-WpDfL7NO6j7tH88IDBNVdUJxDh9nmCteAVW9dsep846XdwF4naCBK+/tGLX3KJgcpgMRXCFlTM2hKGoK9FsdrQ==}
engines: {node: '>=12'}
ansi-styles@4.3.0:
@@ -5147,6 +5153,10 @@
bare-url@2.4.5:
resolution: {integrity: sha512-K+y9xF1tN+CdPu4qWwr0QiK1Al07eFPGYK5M2pDXcmHdMdgC/tT/bpmMe1hrmRHaidKLkXrC+cRNYf3XVDUhSQ==}
+ base64-arraybuffer@1.0.2:
+ resolution: {integrity: sha512-I3yl4r9QB5ZRY3XuJVEPfc2XhZO6YweFPI+UovAzn+8/hb3oJ6lnysaFcjVpkCPfVWFUDvoZ8kmVDP7WyRtYtQ==}
+ engines: {node: '>= 0.6.0'}
+
base64-js@1.5.1:
resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==}
@@ -5164,9 +5174,6 @@
bindings@1.5.0:
resolution: {integrity: sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==}
-
- birpc@0.2.19:
- resolution: {integrity: sha512-5WeXXAvTmitV1RqJFppT5QtUiz2p1mRSYU000Jkft5ZUCLJIk4uQriYNO50HknxKwM6jd8utNc66K1qGIwwWBQ==}
birpc@2.3.0:
resolution: {integrity: sha512-ijbtkn/F3Pvzb6jHypHRyve2QApOCZDR25D/VnkY2G/lBNcXCTsnsCxgY4k4PkVB7zfwzYbY3O9Lcqe3xufS5g==}
@@ -5306,6 +5313,10 @@
caniuse-lite@1.0.30001799:
resolution: {integrity: sha512-hG1bReV+OUU+MOqK4t/ZWI0tZOyz3rqS9XuhOUz1cIcbwBKjOyJEJuw9ER5JuNyqxNk8u/JUVbGibBOL1yrjFw==}
+ canvg@3.0.11:
+ resolution: {integrity: sha512-5ON+q7jCTgMp9cjpu4Jo6XbvfYwSB2Ow3kzHKfIyJfaCAOHLbdKPQqGKgfED/R5B+3TFFfe8pegYA+b423SRyA==}
+ engines: {node: '>=10.0.0'}
+
chalk@4.1.2:
resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==}
engines: {node: '>=10'}
@@ -5400,8 +5411,8 @@
color-name@1.1.4:
resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
- colord@2.9.3:
- resolution: {integrity: sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==}
+ colord@2.10.0:
+ resolution: {integrity: sha512-AidJptpBJmjTclAp9BkLwJi0T93fo5epJnbaZslpg6QVzpHjAiveF55mE9AcUJiGMqRHgMDY8soMsQtuNYMHfw==}
colorjs.io@0.5.0:
resolution: {integrity: sha512-qekjTiBLM3F/sXKks/ih5aWaHIGu+Ftel0yKEvmpbKvmxpNOhojKgha5uiWEUOqEpRjC1Tq3nJRT7WgdBOxIGg==}
@@ -5577,6 +5588,7 @@
crypto-js@4.2.0:
resolution: {integrity: sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==}
+ deprecated: Active development of CryptoJS has been discontinued. This library is no longer maintained.
crypto-random-string@2.0.0:
resolution: {integrity: sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==}
@@ -5585,6 +5597,9 @@
css-functions-list@3.3.3:
resolution: {integrity: sha512-8HFEBPKhOpJPEPu70wJJetjKta86Gw9+CCyCnB3sui2qQfOvRyqBy4IKLKKAwdMpWb2lHXWk9Wb4Z6AmaUT1Pg==}
engines: {node: '>=12'}
+
+ css-line-break@2.1.0:
+ resolution: {integrity: sha512-FHcKFCZcAha3LwfVBhCQbW2nCNbkZXn7KVUJcsT5/P8YmfsVja0FMPJr0B903j/E69HUphKiV9iQArX8SDYA4w==}
css-select@5.1.0:
resolution: {integrity: sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==}
@@ -5823,8 +5838,8 @@
resolution: {integrity: sha512-x1VCxdX4t+8wVfd1so/9w+vQ4vx7lKd2Qp5tDRutErwmR85OgmfX7RlLRMWafRMY7hbEiXIbudNrjOAPa/hL8Q==}
engines: {node: '>=18'}
- default-browser@5.5.0:
- resolution: {integrity: sha512-H9LMLr5zwIbSxrmvikGuI/5KGhZ8E2zH3stkMgM5LpOWDutGM2JZaj460Udnf1a+946zc7YBgrqEWwbk7zHvGw==}
+ default-browser@5.5.1:
+ resolution: {integrity: sha512-m1pAzaJgZ/gssEqlOhJkPJp8Xly7QyW6xcrkUa2KKcDeDSEMP7X8xipU3snUcfisTQx0w1AGae+9UtJSfVnXGw==}
engines: {node: '>=18'}
default-passive-events@2.0.0:
@@ -5942,8 +5957,8 @@
dot-case@3.0.4:
resolution: {integrity: sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==}
- dot-prop@10.1.0:
- resolution: {integrity: sha512-MVUtAugQMOff5RnBy2d9N31iG0lNwg1qAoAOn7pOK5wf94WIaE3My2p3uwTQuvS2AcqchkcR3bHByjaM0mmi7Q==}
+ dot-prop@10.2.0:
+ resolution: {integrity: sha512-BTJ9aZYL3vCfZlZOBLy9v8TUqWGQ0pzFnygKwFZt5udj6viBoFIBviKPUoZLDCPn1FoXffv6McQFDenrm5Krfw==}
engines: {node: '>=20'}
dot-prop@5.3.0:
@@ -6049,8 +6064,8 @@
error-stack-parser-es@1.0.5:
resolution: {integrity: sha512-5qucVt2XcuGMcEGgWI7i+yZpmpByQ8J1lHhcL7PwqCwu9FPP3VUXzT4ltHe5i2z9dePwEHcDVOAfSnHsOlCXRA==}
- errx@0.1.0:
- resolution: {integrity: sha512-fZmsRiDNv07K6s2KkKFTiD2aIvECa7++PKyD5NC32tpRw46qZA3sOz+aM+/V9V0GDHxVTKLziveV4JhzBHDp9Q==}
+ errx@0.1.2:
+ resolution: {integrity: sha512-chfpPHmCerdo/rXr/nNvPZRkV4WwDRwzwnsJ0Uzz3tVi8Z41tDctRjduYy1138ii77AFlts1qvWtX3g/Acg91Q==}
es-abstract-get@1.0.0:
resolution: {integrity: sha512-6PMWXpdhshVvFp+FoWYs1EvG1Nj0tvk0dZM+XcK0xMEM1czRVcP6ohqPWHy6qPagSpC8j4+p89WXlT+xXJs/fg==}
@@ -6265,11 +6280,6 @@
resolution: {integrity: sha512-r5EQJcYZ2oaGbeR0jR0fFVijGOcwai07/690YRXLINuhmVeRY4UKSAsQPe/0BNuDgwP7Ophoc1PRsr2E3tkbdQ==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
- esprima@2.7.3:
- resolution: {integrity: sha512-OarPfz0lFCiW4/AV2Oy1Rp9qu0iusTKqykwTspGCZtPxmF81JR4MmIebvF1F9+UOKth2ZubLQ4XGGaU+hSn99A==}
- engines: {node: '>=0.10.0'}
- hasBin: true
-
esprima@4.0.1:
resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==}
engines: {node: '>=4'}
@@ -6349,6 +6359,9 @@
fast-levenshtein@2.0.6:
resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==}
+
+ fast-png@6.2.0:
+ resolution: {integrity: sha512-fO4DewoEd9WwuP8DQcfj8Tlc88Jno6lJAjlDYzvJSqMIZwxUpRT4zuzPXgqygjJqngBdCbeQRaL/FVz3InExhA==}
fast-uri@3.1.2:
resolution: {integrity: sha512-rVjf7ArG3LTk+FS6Yw81V1DLuZl1bRbNrev6Tmd/9RaroeeRRJhAt7jg/6YFxbvAQXUCavSoZhPPj6oOx+5KjQ==}
@@ -6676,6 +6689,10 @@
resolution: {integrity: sha512-Xwwo44whKBVCYoliBQwaPvtd/2tYFkRQtXDWj1nackaV2JPXx3L0+Jvd8/qCJ2p+ML0/XVkJ2q+Mr+UVdpJK5w==}
engines: {node: '>=12.0.0'}
+ highlight.js@11.12.0:
+ resolution: {integrity: sha512-nbfWpyRMcMrPMmDwJB+dhX/eiaPKtc2RB+0QZskqJ3WjRA/FDS0e9hZrx8EC/lbEv8gXy98FcDbNa/dspAaJMg==}
+ engines: {node: '>=12.0.0'}
+
hookable@5.5.3:
resolution: {integrity: sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==}
@@ -6711,6 +6728,13 @@
html-tags@5.1.0:
resolution: {integrity: sha512-n6l5uca7/y5joxZ3LUePhzmBFUJ+U2YWzhMa8XUTecSeSlQiZdF5XAd/Q3/WUl0VsXgUwWi8I7CNIwdI5WN1SQ==}
engines: {node: '>=20.10'}
+
+ html-to-image@1.11.13:
+ resolution: {integrity: sha512-cuOPoI7WApyhBElTTb9oqsawRvZ0rHhaHwghRLlTuffoD1B2aDemlCruLeZrUIIdvG7gs9xeELEPm6PhuASqrg==}
+
+ html2canvas@1.4.1:
+ resolution: {integrity: sha512-fPU6BHNpsyIhr8yyMpTLLxAbkaK8ArIBcmZIRiBLiDhjeqvXolaEmDGmELFuX9I4xDcaKKcJl+TKZLqruBbmWA==}
+ engines: {node: '>=8.0.0'}
htmlparser2@10.1.0:
resolution: {integrity: sha512-VTZkM9GWRAtEpveh7MSF6SjjrpNVNNVJfFup7xTY3UpFtm67foy9HDVXneLtFVt4pMz5kZtgNcvCniNFb1hlEQ==}
@@ -6764,10 +6788,6 @@
ignore@5.3.2:
resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==}
- engines: {node: '>= 4'}
-
- ignore@7.0.5:
- resolution: {integrity: sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==}
engines: {node: '>= 4'}
ignore@7.0.6:
@@ -6827,6 +6847,9 @@
internmap@2.0.3:
resolution: {integrity: sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==}
engines: {node: '>=12'}
+
+ iobuffer@5.4.0:
+ resolution: {integrity: sha512-DRebOWuqDvxunfkNJAlc3IzWIPD5xVxwUNbHr7xKB8E6aLJxIPfNX3CoMJghcFjpv6RWQsrcJbghtEwSPoJqMA==}
ioredis@5.11.1:
resolution: {integrity: sha512-ehuGcf94bQXhfagULNXrJdfnWO38v070jxSx/qE87Kjzmu2fU7ro5EFAb+OPituLqgfyuQaym5DlrNydW2sJ9A==}
@@ -6966,8 +6989,8 @@
resolution: {integrity: sha512-Xnpx182SBMrr/aBik8y+GuR4U1L9FqMSojwDQwPMmxyC6bvEqly9UBCxhauBF5vNh2gwWJNX6oDV7O+OM4z34g==}
engines: {node: '>=0.10.0'}
- is-plain-object@5.0.0:
- resolution: {integrity: sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==}
+ is-plain-object@5.1.0:
+ resolution: {integrity: sha512-bUi/yjmtKYcRVUtWRGr0UA6xEFh2I6zWUwMrUXB3s7bmYCaZ8a+0ZsTRkrawh/mzlSD1Y0Ph8bp/U+TvBpWDNw==}
engines: {node: '>=0.10.0'}
is-reference@1.2.1:
@@ -7101,8 +7124,8 @@
js-tokens@9.0.1:
resolution: {integrity: sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==}
- js-yaml@3.6.1:
- resolution: {integrity: sha512-BLv3oxhfET+w5fjPwq3PsAsxzi9i3qzU//HMpWVz0A6KplF86HdR9x2TGnv9DXhSUrO7LO8czUiTd3yb3mLSvg==}
+ js-yaml@3.15.2:
+ resolution: {integrity: sha512-6EuL879VkRA+1Cz578mKMiKvjPNEuk6+r1JaFzoSWejZmtf7xWbIyw1e3KkxlkzTIt9Taw6JBhEppG7utc1P+w==}
hasBin: true
js-yaml@4.2.0:
@@ -7168,6 +7191,9 @@
jsonpointer@5.0.1:
resolution: {integrity: sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ==}
engines: {node: '>=0.10.0'}
+
+ jspdf@4.2.1:
+ resolution: {integrity: sha512-YyAXyvnmjTbR4bHQRLzex3CuINCDlQnBqoSYyjJwTP2x9jDLuKDzy7aKUl0hgx3uhcl7xzg32agn5vlie6HIlQ==}
katex@0.16.47:
resolution: {integrity: sha512-Eeo8Ys1doU1z+x8AZsPpQu+p/QcZBI5PeOo7QGQdy2x2m0MU/hYagBbGOmXwr5KVbEfVuWv9LpnQWeehogurjg==}
@@ -7492,8 +7518,8 @@
mdn-data@2.28.1:
resolution: {integrity: sha512-U9w+PzSZ00Z5m9rZ5ARVFL5xOfuCHdKYi/1RRwDCJsboFgJDNT3zT6PIPD7mZQYaQLhsZM3GfDRgSMRHhSmVng==}
- mdurl@2.0.0:
- resolution: {integrity: sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==}
+ mdurl@2.1.0:
+ resolution: {integrity: sha512-1+HBaOx0zi/dQWht8rNv9MYf9qqpqL/kxI0hXImU6Y547zM6Sni8BQibt7ifgMcYtQg41ao3Ivd6cnSM86inpg==}
meow@12.0.1:
resolution: {integrity: sha512-/QOqMALNoKQcJAOOdIXjNLtfcCdLXbMFyB1fOOPdm6RzfBTlsuodOCTBDjVbeUSmgDQb8UI2oONqYGtq1PKKKA==}
@@ -7669,8 +7695,8 @@
resolution: {integrity: sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==}
hasBin: true
- node-mock-http@1.0.4:
- resolution: {integrity: sha512-8DY+kFsDkNXy1sJglUfuODx1/opAGJGyrTuFqEoN90oRc2Vk0ZbD4K2qmKXBBEhZQzdKHIVfEJpDU8Ak2NJEvQ==}
+ node-mock-http@1.0.5:
+ resolution: {integrity: sha512-KQyt/wLjG3TAc7DOUhpqWzgd4ERxR80JOlTK5VE5R1S12IaPVN5qkj4klBce9HPG1Njuup4Sb5bljaT34lIyjw==}
node-releases@2.0.48:
resolution: {integrity: sha512-1uz8041X6LoI6ZSdZacM9lVY28vuzDlSKitnpbSNK0RfKoIJkX29NBPVEFXhnuSuEOA9Ww0xnPJ+ILWbGAv8DA==}
@@ -7736,8 +7762,8 @@
ofetch@1.5.1:
resolution: {integrity: sha512-2W4oUZlVaqAPAil6FUg/difl6YhqhUR7x2eZY4bQCko22UXg3hptq9KLQdqFClV+Wu85UX7hNtdGTngi/1BxcA==}
- ohash@2.0.11:
- resolution: {integrity: sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ==}
+ ohash@2.0.12:
+ resolution: {integrity: sha512-65S/5gk9YSsaRjcyf7Nfa6h/d3E8/1gslpXfI4W7Dxn/oap8IKRuNT5VXkLQ1YFKIEg4apRY4Pj6aiwFzrDdmw==}
on-finished@2.4.1:
resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==}
@@ -7747,8 +7773,8 @@
resolution: {integrity: sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==}
engines: {node: '>=18'}
- open@11.0.0:
- resolution: {integrity: sha512-smsWv2LzFjP03xmvFoJ331ss6h+jixfA4UUV/Bsiyuu4YJPfN+FIQGOIiv4w9/+MoHkfkJ22UIaQWRVFRfH6Vw==}
+ open@11.0.2:
+ resolution: {integrity: sha512-RWqF+pBSkqecEvCKOn8QYhaNdRMJDZRIrlS/7rTDdLHaPcfXGCZ/h8zb413NfvdeAV0MR7T1yJcA34/q+CSm1Q==}
engines: {node: '>=20'}
optionator@0.9.4:
@@ -7823,8 +7849,8 @@
package-json-from-dist@1.0.1:
resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==}
- package-manager-detector@1.6.0:
- resolution: {integrity: sha512-61A5ThoTiDG/C8s8UMZwSorAGwMJ0ERVGj2OjoW5pAalsNOg15+iQiPzrLJ4jhZ1HJzmC2PIHT2oEiH3R5fzNA==}
+ package-manager-detector@1.8.0:
+ resolution: {integrity: sha512-yQA4H19AmPEoMUeavPMDIe1higySl/gH/yaQrkT/s07Qp+7pp2hYz30N3z2l5BkjVkF9Ow6o0wjJamm2y7Sn0A==}
pako@2.2.0:
resolution: {integrity: sha512-zJq6RP/5q+TO2OpFV3FHzlPnFjmkb7Nc99a5SNjJE+uu/PkpChs+NIZSSzbBoD+6kjiISXjfYdwj1ZRQ81dz/w==}
@@ -7915,6 +7941,9 @@
perfect-debounce@2.1.0:
resolution: {integrity: sha512-LjgdTytVFXeUgtHZr9WYViYSM/g8MkcTPYDlPa3cDqMirHjKiSZPYd6DoL7pK8AJQr+uWkQvCjHNdiMqsrJs+g==}
+
+ performance-now@2.1.0:
+ resolution: {integrity: sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==}
picocolors@1.1.1:
resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==}
@@ -8034,6 +8063,10 @@
resolution: {integrity: sha512-dM0jVuXJPsDN6DvRpea484tCUaMiXWjuCn++HGTqUWzGDjv5tZkEZldAJ/UMlqRYGFrD/etByo4/xOuC/snX2A==}
engines: {node: '>=20'}
+ powershell-utils@0.2.1:
+ resolution: {integrity: sha512-C+y9x90UElAddDZmV4qOx9W53B61PO7cIqWz2dQsWlwswuq4mr8NEwytdGKboYbQlGZ3awrkTeNvcZiZNHnQ8A==}
+ engines: {node: '>=20'}
+
preact@10.29.2:
resolution: {integrity: sha512-7tNmwg/7mzzAoB/8kSg6Hl37JraAZw3Z3A0JSY7VXlZwo82Xn0G7wKbNNs2qoF4ZEEsQGTwDAroNdqKs1ofJxQ==}
@@ -8049,12 +8082,12 @@
resolution: {integrity: sha512-mQUvGU6aUFQ+rNvTIAcZuWGRT9a6f6Yrg9bHs4ImKF+HZCEK+plBvnAZYSIQztknZF2qnzNtr6F8s0+IuptdlQ==}
engines: {node: ^14.13.1 || >=16.0.0}
- pretty-bytes@7.1.0:
- resolution: {integrity: sha512-nODzvTiYVRGRqAOvE84Vk5JDPyyxsVk0/fbA/bq7RqlnhksGpset09XTxbpvLTIjoaF7K8Z8DG8yHtKGTPSYRw==}
+ pretty-bytes@7.1.2:
+ resolution: {integrity: sha512-spZIOSORH9joSPGN0L/tYfvINH+xbOpnI3kdcEkq0mzGMjFvDZzyRVbqEOV0wACF0gggdKE9RWO2mosGsBh/Rg==}
engines: {node: '>=20'}
- pretty-ms@9.3.0:
- resolution: {integrity: sha512-gjVS5hOP+M3wMm5nmNOucbIrqudzs9v/57bWRHQWLYklXqoXKrVfYW2W9+glfGsqtPgpiz5WwyEEB+ksXIx3gQ==}
+ pretty-ms@9.3.1:
+ resolution: {integrity: sha512-HzMy3Geq23nVALD/M2LliU+F+M+gVNsvkQWWqeBZ8HDiCgzo6YPJ/Omrmtq24EFrIsk0a3EkQGEd7bDOo+IhGA==}
engines: {node: '>=18'}
prismjs@1.30.0:
@@ -8071,11 +8104,11 @@
prosemirror-changeset@2.4.1:
resolution: {integrity: sha512-96WBLhOaYhJ+kPhLg3uW359Tz6I/MfcrQfL4EGv4SrcqKEMC1gmoGrXHecPE8eOwTVCJ4IwgfzM8fFad25wNfw==}
- prosemirror-commands@1.7.1:
- resolution: {integrity: sha512-rT7qZnQtx5c0/y/KlYaGvtG411S97UaL6gdp6RIZ23DLHanMYLyfGBV5DtSnZdthQql7W+lEVbpSfwtO8T+L2w==}
+ prosemirror-commands@1.7.2:
+ resolution: {integrity: sha512-q6Q6szxqdu9Xd6EcdKsqXghu5nQdZTpB4Q9yd04WRc7/jt763e/rT60Owh0L1GYY+T46o5rD+9lEN36dZS43tw==}
- prosemirror-dropcursor@1.8.2:
- resolution: {integrity: sha512-CCk6Gyx9+Tt2sbYk5NK0nB1ukHi2ryaRgadV/LvyNuO3ena1payM2z6Cg0vO1ebK8cxbzo41ku2DE5Axj1Zuiw==}
+ prosemirror-dropcursor@1.8.3:
+ resolution: {integrity: sha512-FoYbsJR8gK+DGlqhNoE29Loa38eIZPzQRIb1VMaDNBoo4OLP6vVof/jR8qFY/6XvUd6Dhug8MDCHl2a/h8RTfQ==}
prosemirror-gapcursor@1.4.1:
resolution: {integrity: sha512-pMdYaEnjNMSwl11yjEGtgTmLkR08m/Vl+Jj443167p9eB3HVQKhYCc4gmHVDsLPODfZfjr/MmirsdyZziXbQKw==}
@@ -8151,11 +8184,14 @@
radix3@1.1.2:
resolution: {integrity: sha512-b484I/7b8rDEdSDKckSSBA8knMpcdsXudlE/LNL639wFoHKwLbEkQFZHWEYwDC0wa0FKUcCY+GAF73Z7wxNVFA==}
+ raf@3.4.1:
+ resolution: {integrity: sha512-Sq4CW4QhwOHE8ucn6J34MqtZCeWFP2aQSmrlroYgqAV1PjStIhJXxYuTgUIfkEk7zTLjmIjLmU5q+fbD1NnOJA==}
+
randomcolor@0.6.2:
resolution: {integrity: sha512-Mn6TbyYpFgwFuQ8KJKqf3bqqY9O1y37/0jgSK/61PUxV4QfIMv0+K2ioq8DfOjkBslcjwSzRfIDEXfzA9aCx7A==}
- range-parser@1.2.1:
- resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==}
+ range-parser@1.3.0:
+ resolution: {integrity: sha512-hek2mFQpPuI4E1BBKrSto+BU3e3x4xuarsbiwr3+lf7p44juvFMV0XFWQAP3xUyqXA4RrXLIoaSUGbSt056ZMw==}
engines: {node: '>= 0.6'}
rc9@3.0.1:
@@ -8213,6 +8249,9 @@
regenerate@1.4.2:
resolution: {integrity: sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==}
+
+ regenerator-runtime@0.13.11:
+ resolution: {integrity: sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==}
regexp.prototype.flags@1.5.4:
resolution: {integrity: sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==}
@@ -8282,6 +8321,10 @@
rfdc@1.4.1:
resolution: {integrity: sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==}
+
+ rgbcolor@1.0.1:
+ resolution: {integrity: sha512-9aZLIrhRaD97sgVhtJOW6ckOEh6/GnvQtdVNfdZ6s67+3/XwLS9lBcQYzEEhYVeUowN7pRzMLsyGhK2i/xvWbw==}
+ engines: {node: '>= 0.8.15'}
rimraf@5.0.5:
resolution: {integrity: sha512-CqDakW+hMe/Bz202FPEymy68P+G50RfMQK+Qo5YUqc9SPipvbGjCGKd0RSKEelbsfQuw3g5NZDSrlZZAJurH1A==}
@@ -8704,6 +8747,10 @@
sprintf-js@1.0.3:
resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==}
+ stackblur-canvas@2.0.0:
+ resolution: {integrity: sha512-660gH1SpjeKyfUYnne9nuIya7CDGds6NdIrxzOToSgaSlOqbh7UYGP9VlxlQ8IX7af/nPuAHLkN03l84OesX7Q==}
+ deprecated: Fixed build bug in 2.2.0 as not converting ES6 source for older browsers
+
standard-as-callback@2.1.0:
resolution: {integrity: sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A==}
@@ -8749,8 +8796,8 @@
resolution: {integrity: sha512-IIaP0g3iy9Cyy18w3M9YcaDudujEAVHKt3a3QJg1+sr/oX96TbaGUubG0hJyCjCBThFH+tFpcIyoUHUn1ogaLA==}
engines: {node: '>=20'}
- string.prototype.matchall@4.0.12:
- resolution: {integrity: sha512-6CC9uyBL+/48dYizRf7H7VAYCMCNTBeM78x/VTUe9bFEaxBepPJDa1Ow99LqI/1yF7kuy7Q3cQsYMrcjGUcskA==}
+ string.prototype.matchall@4.1.0:
+ resolution: {integrity: sha512-tHNHTxInrYLCga9O9YGxWA3G9/nnzQw8UGAyqGx3Ar1pSTTzIuM4woFSq4SowkXCjJIwq5sIiQvEfRI9tCH1qQ==}
engines: {node: '>= 0.4'}
string.prototype.trim@1.2.11:
@@ -8825,12 +8872,12 @@
style-value-types@5.1.2:
resolution: {integrity: sha512-Vs9fNreYF9j6W2VvuDTP7kepALi7sk0xtk2Tu8Yxi9UoajJdEVpNpCov0HsLTqXvNGKX+Uv09pkozVITi1jf3Q==}
- stylelint-config-html@1.1.0:
- resolution: {integrity: sha512-IZv4IVESjKLumUGi+HWeb7skgO6/g4VMuAYrJdlqQFndgbj6WJAXPhaysvBiXefX79upBdQVumgYcdd17gCpjQ==}
- engines: {node: ^12 || >=14}
+ stylelint-config-html@2.0.0:
+ resolution: {integrity: sha512-Lk1NPEdUxzHkPv3ehktjpiOk4MPaqQ3H8fkvhxdWlQpaZCm9ze0SoMbRQLqkUxEMfPE1G9/x968uxm/+d2njoA==}
+ engines: {node: ^22.12 || >=24}
peerDependencies:
- postcss-html: ^1.0.0
- stylelint: '>=14.0.0'
+ postcss-html: ^2.0.0
+ stylelint: '>=16.0.0'
stylelint-config-recess-order@7.7.0:
resolution: {integrity: sha512-TWRkg+BrwHOki4pi9y1emWgx6pFwZXOYZhNsbEObke/mzYUJVJvDEzJJQXhH7ajslQJGcrExy8ZvJqDiUbhFpA==}
@@ -8930,6 +8977,10 @@
sver@2.0.1:
resolution: {integrity: sha512-zqIx4tK5+gR8xE8VgLNr+IA0mqKDgMNdsfX86DTfNNnVKyuVUhjGdz6KA0rO3q445WUfGpEeJym1m3Xym7ot6w==}
+ svg-pathdata@6.0.3:
+ resolution: {integrity: sha512-qsjeeq5YjBZ5eMdFuUa4ZosMLxgr5RZ+F+Y1OrDhuOCEInRMA3x74XdBtggJcj9kOeInz0WE+LgCPDkZFlBYJw==}
+ engines: {node: '>=12.0.0'}
+
svg-tags@1.0.0:
resolution: {integrity: sha512-ovssysQTa+luh7A5Weu3Rta6FJlFBBbInjOh722LIt6klpU2/HtdUbszju/G4devcvk8PGt7FCLv5wftu3THUA==}
@@ -9009,6 +9060,9 @@
text-extensions@2.4.0:
resolution: {integrity: sha512-te/NtwBwfiNRLf9Ijqx3T0nlqZiQ2XrrtBvu+cLL8ZRrGkO0NHTug8MYFKyoSrv/sHTaSKfilUkizV6XhxMJ3g==}
engines: {node: '>=8'}
+
+ text-segmentation@1.0.3:
+ resolution: {integrity: sha512-iOiPUo/BGnZ6+54OsWxZidGCsdU8YbE4PSpdPinp7DeMtUJNJBoJ/ouUSTJjHkh1KntHaltHl/gDs2FC4i5+Nw==}
theme-colors@0.1.0:
resolution: {integrity: sha512-6gTEHQqWlQNiOEGHCSSQmU//E5SnXHJ4H7oHQOD8x77CvNYNQAmt73dqR71mzw5ULV87zaHLxK5pIBnsToFuZw==}
@@ -9198,8 +9252,8 @@
ufo@1.6.4:
resolution: {integrity: sha512-JFNbkD1Svwe0KvGi8GOeLcP4kAWQ609twvCdcHxq1oSL8svv39ZuSvajcD8B+5D0eL4+s1Is2D/O6KN3qcTeRA==}
- ultrahtml@1.6.0:
- resolution: {integrity: sha512-R9fBn90VTJrqqLDwyMph+HGne8eqY1iPfYhPzZrvKpIfwkWZbcYlfpsb8B9dTvBfpy1/hqAD7Wi8EKfP9e8zdw==}
+ ultrahtml@1.7.0:
+ resolution: {integrity: sha512-2xRd0VHoAQE4M+vF/DvFFB7pUV0ZxTW1TLi7lHQWnF/Sb5TPeEUV/l+hxcNnGO00ZXGnR0voCMmYRKQf+rvJ2g==}
unbox-primitive@1.1.0:
resolution: {integrity: sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==}
@@ -9316,6 +9370,10 @@
unplugin-utils@0.3.1:
resolution: {integrity: sha512-5lWVjgi6vuHhJ526bI4nlCOmkCIF3nnfXkCMDeMJrtdvxTs6ZFCM8oNufGTsDbKv/tJ/xj8RpvXjRuPBZJuJog==}
+ engines: {node: '>=20.19.0'}
+
+ unplugin-utils@0.3.2:
+ resolution: {integrity: sha512-xVToRh2CTmLk2HnEG7ac4rl1MJTT3RFkpS8B++/SnB0kXvuaavD+n3m/vrzyWQOdJNSZQACnbz01pnppbwV5BA==}
engines: {node: '>=20.19.0'}
unplugin-vue@7.2.0:
@@ -9444,6 +9502,9 @@
util-deprecate@1.0.2:
resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
+
+ utrie@1.0.2:
+ resolution: {integrity: sha512-1MLa5ouZiOmQzUbjbu9VmjLzn1QLXBhwpUa7kdLUQK+KQ5KA9I1vk5U4YHe/X2Ch7PYnJfWuWT+VbuxbGwljhw==}
valibot@1.4.1:
resolution: {integrity: sha512-klCmFTz2jeDluy9RwX+F884TCiogtdBJ/YaxSx1EOBYXa3NXNWj8kR1jjN8rzluwojJVWWaHJ4r1U5LfICnM3g==}
@@ -9804,8 +9865,8 @@
resolution: {integrity: sha512-OTIk8iR8/aCRWBqvxrzxR0hgxWpnYBblY1S5hDWBQfk/VFmJwzmJgQFN3WsoUKHISv2eAwe+PpbUzyL1CKTLXg==}
engines: {node: ^20.17.0 || >=22.9.0}
- wsl-utils@0.3.1:
- resolution: {integrity: sha512-g/eziiSUNBSsdDJtCLB8bdYEUMj4jR7AGeUo96p/3dTafgjHhpF4RiCFPiRILwjQoDXx5MqkBr4fwWtR3Ky4Wg==}
+ wsl-utils@1.0.0:
+ resolution: {integrity: sha512-Hl0ZOAs672vg+06kfujwRhoS6/jehvULrlFkuF2dRu6pHgA8U06h3xqNIqNNU1LTXPcedxByAR4GS6pwQK0mgA==}
engines: {node: '>=20'}
xe-utils@3.9.1:
@@ -9868,16 +9929,16 @@
resolution: {integrity: sha512-GZtjxm/J/4TSxuL3FNYjCmLktBTnIw/rVmKSIyKeYAZpmJB2ig9VauCC5xsa82GNKVKDAqpOn3KVzNt0zmrU0g==}
engines: {node: '>=12'}
- yargs@18.0.0:
- resolution: {integrity: sha512-4UEqdc2RYGHZc7Doyqkrqiln3p9X2DZVxaGbwhn2pi7MrRagKaOcIKe8L3OxYcbhXLgLFUS3zAYuQjKBQgmuNg==}
+ yargs@18.1.0:
+ resolution: {integrity: sha512-2rAgRKu54VsHkqI0/tYkmluGXHD4KW7yZoycuqDQ15QOTnc2VVfy0nN/1eMhnQLO00A+dwtK20xuCnc1YGeUyg==}
engines: {node: ^20.19.0 || ^22.12.0 || >=23}
yocto-queue@1.2.2:
resolution: {integrity: sha512-4LCcse/U2MHZ63HAJVE+v71o7yOdIe4cZ70Wpf8D/IyjDKYQLV5GD46B+hSTjJsvV5PztjvHoU580EftxjDZFQ==}
engines: {node: '>=12.20'}
- yoctocolors@2.1.2:
- resolution: {integrity: sha512-CzhO+pFNo8ajLM2d2IW/R93ipy99LWjtwblvC1RsoSUMZgyLbYFr221TnSNT7GjGdYui6P459mw9JH/g/zW2ug==}
+ yoctocolors@2.2.0:
+ resolution: {integrity: sha512-xYqdZFUK/VYazNl/oCDYN+3WloWQwMfZxBoiNt6qNyk+xfOdi598muWE42rNZFp1kNOiqW936q5RhUdnpqElSg==}
engines: {node: '>=18'}
youch-core@0.3.3:
@@ -9923,7 +9984,7 @@
'@antfu/install-pkg@1.1.0':
dependencies:
- package-manager-detector: 1.6.0
+ package-manager-detector: 1.8.0
tinyexec: 1.2.4
'@apideck/better-ajv-errors@0.3.7(ajv@8.20.0)':
@@ -11185,7 +11246,7 @@
dependencies:
escape-string-regexp: 4.0.0
eslint: 10.5.0(jiti@2.7.0)
- ignore: 7.0.5
+ ignore: 7.0.6
'@eslint-community/eslint-utils@4.9.1(eslint@10.5.0(jiti@2.7.0))':
dependencies:
@@ -11456,13 +11517,13 @@
'@jridgewell/gen-mapping@0.3.13':
dependencies:
- '@jridgewell/sourcemap-codec': 1.5.0
+ '@jridgewell/sourcemap-codec': 1.6.0
'@jridgewell/trace-mapping': 0.3.31
'@jridgewell/gen-mapping@0.3.5':
dependencies:
'@jridgewell/set-array': 1.2.1
- '@jridgewell/sourcemap-codec': 1.4.10
+ '@jridgewell/sourcemap-codec': 1.6.0
'@jridgewell/trace-mapping': 0.3.31
'@jridgewell/remapping@2.3.5':
@@ -11479,18 +11540,16 @@
'@jridgewell/gen-mapping': 0.3.5
'@jridgewell/trace-mapping': 0.3.31
- '@jridgewell/sourcemap-codec@1.4.10': {}
-
- '@jridgewell/sourcemap-codec@1.4.14': {}
-
'@jridgewell/sourcemap-codec@1.5.0': {}
'@jridgewell/sourcemap-codec@1.5.5': {}
+ '@jridgewell/sourcemap-codec@1.6.0': {}
+
'@jridgewell/trace-mapping@0.3.31':
dependencies:
'@jridgewell/resolve-uri': 3.1.2
- '@jridgewell/sourcemap-codec': 1.4.14
+ '@jridgewell/sourcemap-codec': 1.6.0
'@jspm/fetch@0.1.0': {}
@@ -11633,14 +11692,14 @@
consola: 3.4.2
defu: 6.1.7
destr: 2.0.5
- errx: 0.1.0
+ errx: 0.1.2
exsolve: 1.1.0
ignore: 7.0.6
jiti: 2.7.0
klona: 2.0.6
knitwork: 1.3.0
mlly: 1.8.2
- ohash: 2.0.11
+ ohash: 2.0.12
pathe: 2.0.3
pkg-types: 2.3.1
rc9: 3.0.1
@@ -12416,8 +12475,8 @@
'@tiptap/pm@3.27.1':
dependencies:
prosemirror-changeset: 2.4.1
- prosemirror-commands: 1.7.1
- prosemirror-dropcursor: 1.8.2
+ prosemirror-commands: 1.7.2
+ prosemirror-dropcursor: 1.8.3
prosemirror-gapcursor: 1.4.1
prosemirror-history: 1.5.0
prosemirror-inputrules: 1.5.1
@@ -12471,7 +12530,7 @@
ejs: 3.1.10
json5: 2.2.3
magic-string: 0.30.21
- string.prototype.matchall: 4.0.12
+ string.prototype.matchall: 4.1.0
'@tybys/wasm-util@0.10.2':
dependencies:
@@ -12482,7 +12541,7 @@
dependencies:
'@types/readdir-glob': 1.1.5
- '@types/codemirror@5.60.17':
+ '@types/codemirror@5.60.18':
dependencies:
'@types/tern': 0.23.9
@@ -12535,7 +12594,7 @@
'@types/lodash@4.17.24': {}
- '@types/markdown-it@14.1.2':
+ '@types/markdown-it@14.2.0':
dependencies:
'@types/linkify-it': 5.0.0
'@types/mdurl': 2.0.0
@@ -12554,11 +12613,16 @@
'@types/nprogress@0.2.3': {}
+ '@types/pako@2.0.0': {}
+
'@types/qrcode@1.5.6':
dependencies:
'@types/node': 25.9.4
'@types/qs@6.15.1': {}
+
+ '@types/raf@3.4.3':
+ optional: true
'@types/readdir-glob@1.1.5':
dependencies:
@@ -12587,7 +12651,7 @@
'@typescript-eslint/utils': 8.62.0(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3)
'@typescript-eslint/visitor-keys': 8.62.0
eslint: 10.5.0(jiti@2.7.0)
- ignore: 7.0.5
+ ignore: 7.0.6
natural-compare: 1.4.0
ts-api-utils: 2.5.0(typescript@6.0.3)
typescript: 6.0.3
@@ -12891,9 +12955,9 @@
'@vue/devtools-api@6.5.0': {}
- '@vue/devtools-api@7.5.2':
+ '@vue/devtools-api@7.7.10':
dependencies:
- '@vue/devtools-kit': 7.5.2
+ '@vue/devtools-kit': 7.7.10
'@vue/devtools-api@7.7.7':
dependencies:
@@ -12909,10 +12973,10 @@
'@vue/devtools-shared': 8.1.3
vue: 3.5.38(typescript@6.0.3)
- '@vue/devtools-kit@7.5.2':
+ '@vue/devtools-kit@7.7.10':
dependencies:
- '@vue/devtools-shared': 7.5.2
- birpc: 0.2.19
+ '@vue/devtools-shared': 7.7.10
+ birpc: 2.3.0
hookable: 5.5.3
mitt: 3.0.1
perfect-debounce: 1.0.0
@@ -12921,7 +12985,7 @@
'@vue/devtools-kit@7.7.7':
dependencies:
- '@vue/devtools-shared': 7.7.7
+ '@vue/devtools-shared': 7.7.10
birpc: 2.3.0
hookable: 5.5.3
mitt: 3.0.1
@@ -12936,11 +13000,7 @@
hookable: 5.5.3
perfect-debounce: 2.1.0
- '@vue/devtools-shared@7.5.2':
- dependencies:
- rfdc: 1.4.1
-
- '@vue/devtools-shared@7.7.7':
+ '@vue/devtools-shared@7.7.10':
dependencies:
rfdc: 1.4.1
@@ -13127,7 +13187,7 @@
ansi-regex@5.0.1: {}
- ansi-regex@6.2.2: {}
+ ansi-regex@6.3.0: {}
ansi-styles@4.3.0:
dependencies:
@@ -13350,6 +13410,9 @@
dependencies:
bare-path: 3.0.1
+ base64-arraybuffer@1.0.2:
+ optional: true
+
base64-js@1.5.1: {}
baseline-browser-mapping@2.10.38: {}
@@ -13363,8 +13426,6 @@
bindings@1.5.0:
dependencies:
file-uri-to-path: 1.0.0
-
- birpc@0.2.19: {}
birpc@2.3.0: {}
@@ -13473,7 +13534,7 @@
exsolve: 1.1.0
giget: 3.3.0
jiti: 2.7.0
- ohash: 2.0.11
+ ohash: 2.0.12
pathe: 2.0.3
perfect-debounce: 2.1.0
pkg-types: 2.3.1
@@ -13539,6 +13600,18 @@
camunda-bpmn-moddle@7.0.1: {}
caniuse-lite@1.0.30001799: {}
+
+ canvg@3.0.11:
+ dependencies:
+ '@babel/runtime': 7.29.7
+ '@types/raf': 3.4.3
+ core-js: 3.49.0
+ raf: 3.4.1
+ regenerator-runtime: 0.13.11
+ rgbcolor: 1.0.1
+ stackblur-canvas: 2.0.0
+ svg-pathdata: 6.0.3
+ optional: true
chalk@4.1.2:
dependencies:
@@ -13652,7 +13725,7 @@
color-name@1.1.4: {}
- colord@2.9.3: {}
+ colord@2.10.0: {}
colorjs.io@0.5.0: {}
@@ -13800,6 +13873,11 @@
crypto-random-string@2.0.0: {}
css-functions-list@3.3.3: {}
+
+ css-line-break@2.1.0:
+ dependencies:
+ utrie: 1.0.2
+ optional: true
css-select@5.1.0:
dependencies:
@@ -14030,7 +14108,7 @@
default-browser-id@5.0.1: {}
- default-browser@5.5.0:
+ default-browser@5.5.1:
dependencies:
bundle-name: 4.1.0
default-browser-id: 5.0.1
@@ -14146,7 +14224,7 @@
no-case: 3.0.4
tslib: 2.8.1
- dot-prop@10.1.0:
+ dot-prop@10.2.0:
dependencies:
type-fest: 5.7.0
@@ -14231,7 +14309,7 @@
error-stack-parser-es@1.0.5: {}
- errx@0.1.0:
+ errx@0.1.2:
optional: true
es-abstract-get@1.0.0:
@@ -14607,8 +14685,6 @@
acorn-jsx: 5.3.2(acorn@8.17.0)
eslint-visitor-keys: 3.0.0
- esprima@2.7.3: {}
-
esprima@4.0.1: {}
esquery@1.7.0:
@@ -14617,7 +14693,7 @@
esrap@2.2.12(@typescript-eslint/types@8.62.0):
dependencies:
- '@jridgewell/sourcemap-codec': 1.5.0
+ '@jridgewell/sourcemap-codec': 1.6.0
optionalDependencies:
'@typescript-eslint/types': 8.62.0
@@ -14659,10 +14735,10 @@
is-plain-obj: 4.1.0
is-stream: 4.0.1
npm-run-path: 6.0.0
- pretty-ms: 9.3.0
+ pretty-ms: 9.3.1
signal-exit: 4.1.0
strip-final-newline: 4.0.0
- yoctocolors: 2.1.2
+ yoctocolors: 2.2.0
exsolve@1.1.0: {}
@@ -14683,6 +14759,12 @@
fast-json-stable-stringify@2.1.0: {}
fast-levenshtein@2.0.6: {}
+
+ fast-png@6.2.0:
+ dependencies:
+ '@types/pako': 2.0.0
+ iobuffer: 5.4.0
+ pako: 2.2.0
fast-uri@3.1.2: {}
@@ -14983,7 +15065,7 @@
dependencies:
'@sindresorhus/merge-streams': 4.0.0
fast-glob: 3.3.3
- ignore: 7.0.5
+ ignore: 7.0.6
is-path-inside: 4.0.0
slash: 5.1.0
unicorn-magic: 0.4.0
@@ -15009,7 +15091,7 @@
defu: 6.1.7
destr: 2.0.5
iron-webcrypto: 1.2.1
- node-mock-http: 1.0.4
+ node-mock-http: 1.0.5
radix3: 1.1.2
ufo: 1.6.4
uncrypto: 0.1.3
@@ -15048,6 +15130,8 @@
highlight.js@11.11.1: {}
+ highlight.js@11.12.0: {}
+
hookable@5.5.3: {}
hookable@6.1.1: {}
@@ -15079,6 +15163,14 @@
html-tags@3.3.1: {}
html-tags@5.1.0: {}
+
+ html-to-image@1.11.13: {}
+
+ html2canvas@1.4.1:
+ dependencies:
+ css-line-break: 2.1.0
+ text-segmentation: 1.0.3
+ optional: true
htmlparser2@10.1.0:
dependencies:
@@ -15145,10 +15237,7 @@
ignore@5.3.2: {}
- ignore@7.0.5: {}
-
- ignore@7.0.6:
- optional: true
+ ignore@7.0.6: {}
immutable@5.1.7: {}
@@ -15186,6 +15275,8 @@
side-channel: 1.1.1
internmap@2.0.3: {}
+
+ iobuffer@5.4.0: {}
ioredis@5.11.1:
dependencies:
@@ -15310,7 +15401,7 @@
is-plain-object@3.0.1: {}
- is-plain-object@5.0.0: {}
+ is-plain-object@5.1.0: {}
is-reference@1.2.1:
dependencies:
@@ -15430,10 +15521,10 @@
js-tokens@9.0.1: {}
- js-yaml@3.6.1:
+ js-yaml@3.15.2:
dependencies:
argparse: 1.0.10
- esprima: 2.7.3
+ esprima: 4.0.1
js-yaml@4.2.0:
dependencies:
@@ -15489,6 +15580,17 @@
jsonparse@1.3.1: {}
jsonpointer@5.0.1: {}
+
+ jspdf@4.2.1:
+ dependencies:
+ '@babel/runtime': 7.29.7
+ fast-png: 6.2.0
+ fflate: 0.8.3
+ optionalDependencies:
+ canvg: 3.0.11
+ core-js: 3.49.0
+ dompurify: 3.4.11
+ html2canvas: 1.4.1
katex@0.16.47:
dependencies:
@@ -15675,7 +15777,7 @@
log-symbols@7.0.1:
dependencies:
is-unicode-supported: 2.1.0
- yoctocolors: 2.1.2
+ yoctocolors: 2.2.0
loglevel@1.9.2: {}
@@ -15740,7 +15842,7 @@
argparse: 2.0.1
entities: 4.4.0
linkify-it: 5.0.1
- mdurl: 2.0.0
+ mdurl: 2.1.0
punycode.js: 2.3.1
uc.micro: 2.1.0
@@ -15762,7 +15864,7 @@
dependencies:
'@babel/runtime': 7.29.7
'@vscode/markdown-it-katex': 1.1.2
- highlight.js: 11.11.1
+ highlight.js: 11.12.0
katex: 0.16.47
markdown-it: 14.2.0
markdown-it-ins: 4.0.0
@@ -15797,7 +15899,7 @@
mdn-data@2.28.1: {}
- mdurl@2.0.0: {}
+ mdurl@2.1.0: {}
meow@12.0.1:
dependencies:
@@ -15957,7 +16059,7 @@
db0: 0.3.4
defu: 6.1.7
destr: 2.0.5
- dot-prop: 10.1.0
+ dot-prop: 10.2.0
esbuild: 0.28.1
escape-string-regexp: 5.0.0
etag: 1.8.1
@@ -15977,13 +16079,13 @@
mime: 4.1.0
mlly: 1.8.2
node-fetch-native: 1.6.7
- node-mock-http: 1.0.4
+ node-mock-http: 1.0.5
ofetch: 1.5.1
- ohash: 2.0.11
+ ohash: 2.0.12
pathe: 2.0.3
perfect-debounce: 2.1.0
pkg-types: 2.3.1
- pretty-bytes: 7.1.0
+ pretty-bytes: 7.1.2
radix3: 1.1.2
rollup: 4.62.2
rollup-plugin-visualizer: 7.0.1(rolldown@1.1.2)(rollup@4.62.2)
@@ -15994,12 +16096,12 @@
source-map: 0.7.6
std-env: 4.1.0
ufo: 1.6.4
- ultrahtml: 1.6.0
+ ultrahtml: 1.7.0
uncrypto: 0.1.3
unctx: 2.5.0
unenv: 2.0.0-rc.24
unimport: 6.3.0(rolldown@1.1.2)
- unplugin-utils: 0.3.1
+ unplugin-utils: 0.3.2
unstorage: 1.17.5(db0@0.3.4)(ioredis@5.11.1)
untyped: 2.0.0
unwasm: 0.5.3
@@ -16055,7 +16157,7 @@
node-gyp-build@4.8.4: {}
- node-mock-http@1.0.4: {}
+ node-mock-http@1.0.5: {}
node-releases@2.0.48: {}
@@ -16123,7 +16225,7 @@
node-fetch-native: 1.6.7
ufo: 1.6.4
- ohash@2.0.11: {}
+ ohash@2.0.12: {}
on-finished@2.4.1:
dependencies:
@@ -16133,14 +16235,14 @@
dependencies:
mimic-function: 5.0.1
- open@11.0.0:
+ open@11.0.2:
dependencies:
- default-browser: 5.5.0
+ default-browser: 5.5.1
define-lazy-prop: 3.0.0
is-in-ssh: 1.0.0
is-inside-container: 1.0.0
- powershell-utils: 0.1.0
- wsl-utils: 0.3.1
+ powershell-utils: 0.2.1
+ wsl-utils: 1.0.0
optionator@0.9.4:
dependencies:
@@ -16246,7 +16348,7 @@
package-json-from-dist@1.0.1: {}
- package-manager-detector@1.6.0: {}
+ package-manager-detector@1.8.0: {}
pako@2.2.0: {}
@@ -16330,6 +16432,9 @@
perfect-debounce@1.0.0: {}
perfect-debounce@2.1.0: {}
+
+ performance-now@2.1.0:
+ optional: true
picocolors@1.1.1: {}
@@ -16433,6 +16538,8 @@
powershell-utils@0.1.0: {}
+ powershell-utils@0.2.1: {}
+
preact@10.29.2: {}
prelude-ls@1.2.1: {}
@@ -16441,9 +16548,9 @@
pretty-bytes@6.1.1: {}
- pretty-bytes@7.1.0: {}
+ pretty-bytes@7.1.2: {}
- pretty-ms@9.3.0:
+ pretty-ms@9.3.1:
dependencies:
parse-ms: 4.0.0
@@ -16457,13 +16564,13 @@
dependencies:
prosemirror-transform: 1.12.0
- prosemirror-commands@1.7.1:
+ prosemirror-commands@1.7.2:
dependencies:
prosemirror-model: 1.25.9
prosemirror-state: 1.4.4
prosemirror-transform: 1.12.0
- prosemirror-dropcursor@1.8.2:
+ prosemirror-dropcursor@1.8.3:
dependencies:
prosemirror-state: 1.4.4
prosemirror-transform: 1.12.0
@@ -16559,9 +16666,14 @@
radix3@1.1.2: {}
+ raf@3.4.1:
+ dependencies:
+ performance-now: 2.1.0
+ optional: true
+
randomcolor@0.6.2: {}
- range-parser@1.2.1: {}
+ range-parser@1.3.0: {}
rc9@3.0.1:
dependencies:
@@ -16584,7 +16696,7 @@
read-yaml-file@1.1.0:
dependencies:
graceful-fs: 4.2.11
- js-yaml: 3.6.1
+ js-yaml: 3.15.2
pify: 4.0.1
strip-bom: 3.0.0
@@ -16645,6 +16757,9 @@
regenerate@1.4.2: {}
+ regenerator-runtime@0.13.11:
+ optional: true
+
regexp.prototype.flags@1.5.4:
dependencies:
call-bind: 1.0.9
@@ -16680,7 +16795,7 @@
'@vueuse/shared': 14.3.0(vue@3.5.38(typescript@6.0.3))
aria-hidden: 1.2.6
defu: 6.1.7
- ohash: 2.0.11
+ ohash: 2.0.12
vue: 3.5.38(typescript@6.0.3)
transitivePeerDependencies:
- '@vue/composition-api'
@@ -16718,6 +16833,9 @@
reusify@1.1.0: {}
rfdc@1.4.1: {}
+
+ rgbcolor@1.0.1:
+ optional: true
rimraf@5.0.5:
dependencies:
@@ -16791,10 +16909,10 @@
rollup-plugin-visualizer@7.0.1(rolldown@1.1.2)(rollup@4.62.2):
dependencies:
- open: 11.0.0
+ open: 11.0.2
picomatch: 4.0.4
source-map: 0.7.6
- yargs: 18.0.0
+ yargs: 18.1.0
optionalDependencies:
rolldown: 1.1.2
rollup: 4.62.2
@@ -17032,7 +17150,7 @@
mime-types: 3.0.2
ms: 2.1.3
on-finished: 2.4.1
- range-parser: 1.2.1
+ range-parser: 1.3.0
statuses: 2.0.2
transitivePeerDependencies:
- supports-color
@@ -17178,6 +17296,9 @@
sprintf-js@1.0.3: {}
+ stackblur-canvas@2.0.0:
+ optional: true
+
standard-as-callback@2.1.0: {}
statuses@2.0.2: {}
@@ -17231,7 +17352,7 @@
get-east-asian-width: 1.6.0
strip-ansi: 7.2.0
- string.prototype.matchall@4.0.12:
+ string.prototype.matchall@4.1.0:
dependencies:
call-bind: 1.0.9
call-bound: 1.0.4
@@ -17295,7 +17416,7 @@
strip-ansi@7.2.0:
dependencies:
- ansi-regex: 6.2.2
+ ansi-regex: 6.3.0
strip-bom@3.0.0: {}
@@ -17326,7 +17447,7 @@
hey-listen: 1.0.8
tslib: 2.4.0
- stylelint-config-html@1.1.0(postcss-html@1.8.1)(stylelint@17.13.0(typescript@6.0.3)):
+ stylelint-config-html@2.0.0(postcss-html@1.8.1)(stylelint@17.13.0(typescript@6.0.3)):
dependencies:
postcss-html: 1.8.1
stylelint: 17.13.0(typescript@6.0.3)
@@ -17350,7 +17471,7 @@
postcss-html: 1.8.1
semver: 7.8.5
stylelint: 17.13.0(typescript@6.0.3)
- stylelint-config-html: 1.1.0(postcss-html@1.8.1)(stylelint@17.13.0(typescript@6.0.3))
+ stylelint-config-html: 2.0.0(postcss-html@1.8.1)(stylelint@17.13.0(typescript@6.0.3))
stylelint-config-recommended: 18.0.0(stylelint@17.13.0(typescript@6.0.3))
stylelint-config-recommended@18.0.0(stylelint@17.13.0(typescript@6.0.3)):
@@ -17375,7 +17496,7 @@
'@csstools/css-syntax-patches-for-csstree': 1.1.5(css-tree@3.2.1)
'@csstools/css-tokenizer': 4.0.0
css-tree: 3.2.1
- is-plain-object: 5.0.0
+ is-plain-object: 5.1.0
known-css-properties: 0.37.0
postcss-media-query-parser: 0.2.3
postcss-resolve-nested-selector: 0.1.6
@@ -17392,7 +17513,7 @@
'@csstools/media-query-list-parser': 5.0.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0)
'@csstools/selector-resolve-nested': 4.0.0(postcss-selector-parser@7.1.4)
'@csstools/selector-specificity': 6.0.0(postcss-selector-parser@7.1.4)
- colord: 2.9.3
+ colord: 2.10.0
cosmiconfig: 9.0.2(typescript@6.0.3)
css-functions-list: 3.3.3
css-tree: 3.2.1
@@ -17404,7 +17525,7 @@
globby: 16.2.0
globjoin: 0.1.4
html-tags: 5.1.0
- ignore: 7.0.5
+ ignore: 7.0.6
import-meta-resolve: 4.2.0
mathml-tag-names: 4.0.0
meow: 14.1.0
@@ -17466,7 +17587,7 @@
svelte@5.56.3(@typescript-eslint/types@8.62.0):
dependencies:
'@jridgewell/remapping': 2.3.5
- '@jridgewell/sourcemap-codec': 1.5.0
+ '@jridgewell/sourcemap-codec': 1.6.0
'@sveltejs/acorn-typescript': 1.0.10(acorn@8.17.0)
'@types/estree': 1.0.9
'@types/trusted-types': 2.0.7
@@ -17485,6 +17606,9 @@
- '@typescript-eslint/types'
sver@2.0.1: {}
+
+ svg-pathdata@6.0.3:
+ optional: true
svg-tags@1.0.0: {}
@@ -17577,6 +17701,11 @@
- react-native-b4a
text-extensions@2.4.0: {}
+
+ text-segmentation@1.0.3:
+ dependencies:
+ utrie: 1.0.2
+ optional: true
theme-colors@0.1.0: {}
@@ -17740,7 +17869,7 @@
ufo@1.6.4: {}
- ultrahtml@1.6.0: {}
+ ultrahtml@1.7.0: {}
unbox-primitive@1.1.0:
dependencies:
@@ -17805,7 +17934,7 @@
strip-literal: 3.1.0
tinyglobby: 0.2.17
unplugin: 3.0.0
- unplugin-utils: 0.3.1
+ unplugin-utils: 0.3.2
optionalDependencies:
rolldown: 1.1.2
@@ -17839,6 +17968,11 @@
- supports-color
unplugin-utils@0.3.1:
+ dependencies:
+ pathe: 2.0.3
+ picomatch: 4.0.4
+
+ unplugin-utils@0.3.2:
dependencies:
pathe: 2.0.3
picomatch: 4.0.4
@@ -17952,6 +18086,11 @@
util-deprecate@1.0.2: {}
+ utrie@1.0.2:
+ dependencies:
+ base64-arraybuffer: 1.0.2
+ optional: true
+
valibot@1.4.1(typescript@6.0.3):
optionalDependencies:
typescript: 6.0.3
@@ -17965,7 +18104,7 @@
vee-validate@4.15.1(vue@3.5.38(typescript@6.0.3)):
dependencies:
- '@vue/devtools-api': 7.5.2
+ '@vue/devtools-api': 7.7.10
type-fest: 4.8.3
vue: 3.5.38(typescript@6.0.3)
@@ -18015,11 +18154,11 @@
ansis: 4.3.1
error-stack-parser-es: 1.0.5
obug: 2.1.3
- ohash: 2.0.11
- open: 11.0.0
+ ohash: 2.0.12
+ open: 11.0.2
perfect-debounce: 2.1.0
sirv: 3.0.2
- unplugin-utils: 0.3.1
+ unplugin-utils: 0.3.2
vite: 8.0.10(@types/node@25.9.4)(esbuild@0.28.1)(jiti@2.7.0)(sass-embedded@1.100.0)(sass@1.101.0)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0)
vite-dev-rpc: 2.0.0(vite@8.0.10(@types/node@25.9.4)(esbuild@0.28.1)(jiti@2.7.0)(sass-embedded@1.100.0)(sass@1.101.0)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))
@@ -18432,7 +18571,7 @@
dependencies:
signal-exit: 4.1.0
- wsl-utils@0.3.1:
+ wsl-utils@1.0.0:
dependencies:
is-wsl: 3.1.1
powershell-utils: 0.1.0
@@ -18499,18 +18638,18 @@
y18n: 5.0.8
yargs-parser: 21.1.1
- yargs@18.0.0:
+ yargs@18.1.0:
dependencies:
cliui: 9.0.1
escalade: 3.2.0
get-caller-file: 2.0.5
- string-width: 7.2.0
+ string-width: 8.2.1
y18n: 5.0.8
yargs-parser: 22.0.0
yocto-queue@1.2.2: {}
- yoctocolors@2.1.2: {}
+ yoctocolors@2.2.0: {}
youch-core@0.3.3:
dependencies:
diff --git a/src/api/mes/management-cockpit/index.ts b/src/api/mes/management-cockpit/index.ts
new file mode 100644
index 0000000..c85c268
--- /dev/null
+++ b/src/api/mes/management-cockpit/index.ts
@@ -0,0 +1,158 @@
+import { requestClient } from '#/api/request';
+
+export namespace ManagementCockpitApi {
+ /** 閫氱敤鍚嶇О-鏁伴噺鍒嗗竷椤� */
+ export interface NameCountItem {
+ name: string; // 鍚嶇О锛堜粨搴�/鍝佺/鐘舵��/缁忛攢鍟�/鐪佷唤/娓犻亾绛夛級
+ count: number; // 鏁伴噺
+ }
+
+ /** 鎸夋棩鏁伴噺瓒嬪娍椤� */
+ export interface DailyCountItem {
+ date: string; // 鏃ユ湡 yyyy-MM-dd
+ count: number; // 鏁伴噺
+ }
+
+ /** 璐ㄦ鎸囨爣鍧囧�奸」 */
+ export interface IndicatorAvgItem {
+ indicatorCode: string; // 鎸囨爣缂栫爜
+ indicatorName: string; // 鎸囨爣鍚嶇О锛堢函搴�/鍑�搴�/鍙戣娊鐜�/姘村垎锛�
+ checkCount: number; // 妫�楠屾鏁�
+ averageValue: number; // 鎸囨爣骞冲潎鍊�
+ passRate: number; // 鎸囨爣鍚堟牸鐜囷紙%锛�
+ }
+
+ /** 浜旂淮搴︽眹鎬荤粺璁� */
+ export interface Summary {
+ // 鐢熶骇
+ batchTotal: number; // 鎵规鎬绘暟
+ batchDraft: number; // 鑽夌鎵规
+ batchProducing: number; // 鐢熶骇涓壒娆�
+ batchFinished: number; // 宸插畬鎴愭壒娆�
+ batchCanceled: number; // 宸蹭綔搴熸壒娆�
+ bagCodeTotal: number; // 琚嬬爜鎬绘暟
+ bagCodeGenerated: number; // 宸茬敓鎴愯鐮�
+ bagCodePrinted: number; // 宸插鍑哄嵃鍒疯鐮�
+ bagCodeCanceled: number; // 宸蹭綔搴熻鐮�
+ palletTotal: number; // 鎵樼洏鐮佹�绘暟
+ todayInboundBagCount: number; // 浠婃棩鎵爜鍏ュ簱琚嬫暟
+ // 璐ㄦ
+ qualityTotal: number; // 妫�楠岃褰曟�绘暟
+ qualityPending: number; // 澶勭悊涓�
+ qualityPass: number; // 鍚堟牸
+ qualityFail: number; // 涓嶅悎鏍�
+ qualityPassRate: number; // 妫�楠屽悎鏍肩巼锛�%锛�
+ // 搴撳瓨
+ stockTotal: number; // 褰撳墠搴撳瓨鎬婚噺
+ stockTemporary: number; // 鏆傚瓨搴撳瓨閲�
+ stockQualified: number; // 鍚堟牸搴撳瓨閲�
+ stockOutbound: number; // 宸插嚭搴撴暟閲�
+ lowStockCount: number; // 浣庡簱瀛橀璀︽暟
+ // 鍑哄簱
+ outboundOrderTotal: number; // 鍑哄簱鍗曟�绘暟
+ outboundQuantityTotal: number; // 鍑哄簱鎬婚噺
+ todayOutboundQuantity: number; // 浠婃棩鍑哄簱閲�
+ // 杩芥函
+ scanTotal: number; // 鎵爜鎬绘暟
+ todayScanCount: number; // 浠婃棩鎵爜鏁�
+ scanSuccessCount: number; // 鎵爜鎴愬姛鏁�
+ crossRegionWarningTotal: number; // 绐滆揣棰勮鎬绘暟
+ crossRegionPendingCount: number; // 寰呭鐞嗙獪璐ч璀︽暟
+ }
+
+ /** 鐢熶骇瓒嬪娍椤� */
+ export interface ProductionTrendItem {
+ date: string;
+ batchCount: number; // 鏂板鎵规
+ bagCodeCount: number; // 鏂板琚嬬爜
+ palletCount: number; // 鏂板鎵樼洏
+ inboundBagQuantity: number; // 鎵爜鍏ュ簱琚嬫暟
+ }
+
+ /** 璐ㄦ缁村害缁熻 */
+ export interface QualityStatistics {
+ resultDistribution: NameCountItem[]; // 妫�楠岀粨鏋滃垎甯�
+ indicatorList: IndicatorAvgItem[]; // 鍥涢」鎸囨爣鍧囧��
+ }
+
+ /** 搴撳瓨缁村害缁熻 */
+ export interface InventoryStatistics {
+ warehouseDistribution: NameCountItem[]; // 鎸変粨搴�
+ itemDistribution: NameCountItem[]; // 鎸夊搧绉�
+ stateDistribution: NameCountItem[]; // 鎸夌姸鎬�
+ }
+
+ /** 鍑哄簱缁村害缁熻 */
+ export interface OutboundStatistics {
+ trend: DailyCountItem[]; // 鎸夋棩鍑哄簱瓒嬪娍
+ dealerDistribution: NameCountItem[]; // 鎸夌粡閿�鍟�
+ }
+
+ /** 绐滆揣棰勮姹囨�� */
+ export interface CrossRegionSummary {
+ total: number;
+ pending: number;
+ handled: number;
+ falseAlarm: number;
+ crossProvince: number;
+ crossCity: number;
+ }
+
+ /** 杩芥函缁村害缁熻 */
+ export interface TraceStatistics {
+ scanTrend: DailyCountItem[]; // 鎵爜鎸夋棩瓒嬪娍
+ provinceDistribution: NameCountItem[]; // 鐪佷唤鍒嗗竷
+ channelDistribution: NameCountItem[]; // 娓犻亾鍒嗗竷
+ crossRegionSummary: CrossRegionSummary; // 绐滆揣棰勮姹囨��
+ }
+}
+
+/** 鑾峰緱绠$悊椹鹃┒鑸变簲缁村害姹囨�荤粺璁� */
+export function getManagementCockpitSummary() {
+ return requestClient.get<ManagementCockpitApi.Summary>(
+ '/mes/dashboard/summary',
+ );
+}
+
+/** 鑾峰緱鐢熶骇瓒嬪娍 */
+export function getManagementCockpitProductionTrend(days?: number) {
+ return requestClient.get<ManagementCockpitApi.ProductionTrendItem[]>(
+ '/mes/dashboard/production-trend',
+ { params: { days } },
+ );
+}
+
+/** 鑾峰緱璐ㄦ缁村害缁熻 */
+export function getManagementCockpitQuality() {
+ return requestClient.get<ManagementCockpitApi.QualityStatistics>(
+ '/mes/dashboard/quality-statistics',
+ );
+}
+
+/** 鑾峰緱搴撳瓨缁村害缁熻 */
+export function getManagementCockpitInventory() {
+ return requestClient.get<ManagementCockpitApi.InventoryStatistics>(
+ '/mes/dashboard/inventory-statistics',
+ );
+}
+
+/** 鑾峰緱鍑哄簱缁村害缁熻 */
+export function getManagementCockpitOutbound(days?: number) {
+ return requestClient.get<ManagementCockpitApi.OutboundStatistics>(
+ '/mes/dashboard/outbound-statistics',
+ { params: { days } },
+ );
+}
+
+/** 鑾峰緱杩芥函缁村害缁熻 */
+export function getManagementCockpitTrace(days?: number) {
+ return requestClient.get<ManagementCockpitApi.TraceStatistics>(
+ '/mes/dashboard/trace-statistics',
+ { params: { days } },
+ );
+}
+
+/** 瀵煎嚭绠$悊椹鹃┒鑸� Excel 鎶ヨ〃锛堣繑鍥� Blob锛� */
+export function exportManagementCockpitExcel() {
+ return requestClient.download('/mes/dashboard/export-excel');
+}
diff --git a/src/views/management-cockpit/chart-options.ts b/src/views/management-cockpit/chart-options.ts
new file mode 100644
index 0000000..cb61b2a
--- /dev/null
+++ b/src/views/management-cockpit/chart-options.ts
@@ -0,0 +1,113 @@
+import type { EChartsOption } from '@vben/plugins/echarts';
+
+/** 鐢熶骇瓒嬪娍鍥鹃厤缃紙澶氱郴鍒楁煴鐘�/鎶樼嚎锛� */
+export function getProductionTrendChartOptions(
+ dates: string[],
+ batchCounts: number[],
+ bagCodeCounts: number[],
+ palletCounts: number[],
+ inboundCounts: number[],
+): EChartsOption {
+ return {
+ color: ['#409EFF', '#36cfc9', '#f59e0b', '#67c23a'],
+ grid: { bottom: 40, left: 50, right: 30, top: 30 },
+ legend: { bottom: 0, type: 'scroll' },
+ series: [
+ { barMaxWidth: 24, data: batchCounts, name: '鏂板鎵规', type: 'bar' },
+ { barMaxWidth: 24, data: bagCodeCounts, name: '鏂板琚嬬爜', type: 'bar' },
+ { barMaxWidth: 24, data: palletCounts, name: '鏂板鎵樼洏', type: 'bar' },
+ { data: inboundCounts, name: '鍏ュ簱琚嬫暟', smooth: true, type: 'line' },
+ ],
+ tooltip: { trigger: 'axis' },
+ xAxis: { axisTick: { show: false }, data: dates, type: 'category' },
+ yAxis: { minInterval: 1, type: 'value' },
+ };
+}
+
+/** 閫氱敤楗煎浘/鐜舰鍥鹃厤缃� */
+export function getPieChartOptions(
+ data: Array<{ name: string; value: number }>,
+): EChartsOption {
+ return {
+ legend: { bottom: 0, type: 'scroll' },
+ series: [
+ {
+ avoidLabelOverlap: true,
+ data,
+ emphasis: { label: { fontSize: 14, fontWeight: 'bold', show: true } },
+ itemStyle: { borderColor: '#fff', borderRadius: 6, borderWidth: 2 },
+ label: { formatter: '{b}\n{c}', show: true },
+ radius: ['40%', '70%'],
+ type: 'pie',
+ },
+ ],
+ tooltip: { formatter: '{b}: {c} ({d}%)', trigger: 'item' },
+ };
+}
+
+/** 閫氱敤鏌辩姸鍥鹃厤缃� */
+export function getBarChartOptions(
+ categories: string[],
+ values: number[],
+ name: string,
+ color = '#409EFF',
+): EChartsOption {
+ return {
+ grid: { bottom: 50, left: 60, right: 20, top: 30 },
+ series: [
+ {
+ barMaxWidth: 36,
+ data: values,
+ itemStyle: { borderRadius: 4, color },
+ name,
+ type: 'bar',
+ },
+ ],
+ tooltip: { axisPointer: { type: 'shadow' }, trigger: 'axis' },
+ xAxis: {
+ axisLabel: { interval: 0, rotate: categories.length > 6 ? 30 : 0 },
+ axisTick: { show: false },
+ data: categories,
+ type: 'category',
+ },
+ yAxis: { minInterval: 1, type: 'value' },
+ };
+}
+
+/** 閫氱敤鎶樼嚎鍥鹃厤缃� */
+export function getLineChartOptions(
+ dates: string[],
+ values: number[],
+ name: string,
+ color = '#36cfc9',
+): EChartsOption {
+ return {
+ grid: { bottom: 40, left: 60, right: 20, top: 30 },
+ series: [
+ { areaStyle: { opacity: 0.12 }, data: values, itemStyle: { color }, name, smooth: true, type: 'line' },
+ ],
+ tooltip: { trigger: 'axis' },
+ xAxis: { axisTick: { show: false }, data: dates, type: 'category' },
+ yAxis: { minInterval: 1, type: 'value' },
+ };
+}
+
+/** 璐ㄦ鎸囨爣鍧囧�� + 鍚堟牸鐜囧弻绯诲垪鏌辩姸鍥鹃厤缃� */
+export function getQualityIndicatorChartOptions(
+ labels: string[],
+ avgValues: number[],
+ passRates: number[],
+): EChartsOption {
+ return {
+ color: ['#409EFF', '#67c23a'],
+ grid: { bottom: 40, left: 60, right: 60, top: 30 },
+ legend: { bottom: 0, data: ['骞冲潎鍊�', '鍚堟牸鐜�(%)'] },
+ series: [
+ { barMaxWidth: 30, data: avgValues, name: '骞冲潎鍊�', type: 'bar' },
+ { barMaxWidth: 30, data: passRates, name: '鍚堟牸鐜�(%)', type: 'bar' },
+ ],
+ tooltip: { trigger: 'axis' },
+ xAxis: { axisTick: { show: false }, data: labels, type: 'category' },
+ yAxis: [{ minInterval: 1, type: 'value' }],
+ };
+}
diff --git a/src/views/management-cockpit/index.vue b/src/views/management-cockpit/index.vue
new file mode 100644
index 0000000..498c37f
--- /dev/null
+++ b/src/views/management-cockpit/index.vue
@@ -0,0 +1,207 @@
+<script lang="ts" setup>
+import type { ManagementCockpitApi } from '#/api/mes/management-cockpit';
+
+import { ref } from 'vue';
+
+import { Page } from '@vben/common-ui';
+import { IconifyIcon } from '@vben/icons';
+import { downloadFileFromBlobPart } from '@vben/utils';
+
+import { Button, message, Space } from 'ant-design-vue';
+// 鍙橀噺鍚� vPrint锛坴 寮�澶达級鍦� <script setup> 涓細琚� Vue 鑷姩娉ㄥ唽涓哄眬閮ㄦ寚浠� v-print
+// @ts-expect-error - vue3-print-nb 鏈彁渚涚被鍨嬪0鏄�
+import vPrint from 'vue3-print-nb';
+
+import {
+ exportManagementCockpitExcel,
+ getManagementCockpitSummary,
+} from '#/api/mes/management-cockpit';
+
+import KpiCards from './modules/kpi-cards.vue';
+import InventoryChart from './modules/inventory-chart.vue';
+import OutboundChart from './modules/outbound-chart.vue';
+import ProductionTrend from './modules/production-trend.vue';
+import QualityChart from './modules/quality-chart.vue';
+import TraceChart from './modules/trace-chart.vue';
+
+defineOptions({ name: 'ManagementCockpit' });
+
+// 鎵撳嵃閰嶇疆锛堟墦鍗版姤琛ㄥ鍣級
+const printObj = ref({
+ id: 'management-cockpit-report',
+ popTitle: ' ',
+ extraCss: '/print.css',
+ zIndex: 20_003,
+});
+
+const summary = ref<ManagementCockpitApi.Summary>({
+ batchTotal: 0,
+ batchDraft: 0,
+ batchProducing: 0,
+ batchFinished: 0,
+ batchCanceled: 0,
+ bagCodeTotal: 0,
+ bagCodeGenerated: 0,
+ bagCodePrinted: 0,
+ bagCodeCanceled: 0,
+ palletTotal: 0,
+ todayInboundBagCount: 0,
+ qualityTotal: 0,
+ qualityPending: 0,
+ qualityPass: 0,
+ qualityFail: 0,
+ qualityPassRate: 0,
+ stockTotal: 0,
+ stockTemporary: 0,
+ stockQualified: 0,
+ stockOutbound: 0,
+ lowStockCount: 0,
+ outboundOrderTotal: 0,
+ outboundQuantityTotal: 0,
+ todayOutboundQuantity: 0,
+ scanTotal: 0,
+ todayScanCount: 0,
+ scanSuccessCount: 0,
+ crossRegionWarningTotal: 0,
+ crossRegionPendingCount: 0,
+});
+
+// 閫氳繃閫掑 key 瑙﹀彂瀛愮粍浠堕噸鏂版寕杞藉疄鐜版暣浣撳埛鏂�
+const reloadKey = ref(0);
+
+const loading = ref(false);
+
+/** 鍔犺浇姹囨�荤粺璁� */
+async function loadSummary() {
+ try {
+ summary.value = await getManagementCockpitSummary();
+ } catch {
+ // 鎺ュ彛寮傚父鏃朵繚鐣欓粯璁ゅ�硷紝閬垮厤椤甸潰宕╂簝
+ }
+}
+
+/** 鍒锋柊鍏ㄩ儴鏁版嵁 */
+async function handleRefresh() {
+ loading.value = true;
+ try {
+ await Promise.all([loadSummary()]);
+ reloadKey.value += 1;
+ message.success('宸插埛鏂�');
+ } finally {
+ loading.value = false;
+ }
+}
+
+/** 瀵煎嚭 Excel 鎶ヨ〃锛堝悗绔敓鎴愬 sheet 宸ヤ綔绨匡級 */
+async function handleExportExcel() {
+ try {
+ const data = await exportManagementCockpitExcel();
+ downloadFileFromBlobPart({
+ fileName: `绠$悊椹鹃┒鑸辩粺璁℃姤琛�-${new Date().toLocaleDateString()}.xls`,
+ source: data,
+ });
+ message.success('Excel 鎶ヨ〃宸插鍑�');
+ } catch {
+ // 閿欒宸茬敱 requestClient 缁熶竴鎻愮ず
+ }
+}
+
+/** 瀵煎嚭 PDF 鎶ヨ〃锛堝墠绔� html2canvas + jspdf 鐢熸垚鍙笅杞芥枃浠讹級 */
+async function handleExportPdf() {
+ const target = document.getElementById('management-cockpit-report');
+ if (!target) {
+ message.warning('鎶ヨ〃鍖哄煙鏈氨缁�');
+ return;
+ }
+ const hide = message.loading('姝e湪鐢熸垚 PDF锛岃绋嶅�欌��', 0);
+ try {
+ // 鍔ㄦ�佸姞杞斤紝閬垮厤鎷栨參棣栧睆锛坔tml-to-image 閫氳繃 SVG foreignObject 璁╂祻瑙堝櫒鍘熺敓娓叉煋锛�
+ // 瑙勯伩 html2canvas 涓嶆敮鎸� oklch 绛夌幇浠� CSS 棰滆壊鍑芥暟鐨勯棶棰橈級
+ const [{ toPng }, { jsPDF }] = await Promise.all([
+ import('html-to-image'),
+ import('jspdf'),
+ ]);
+ const dataUrl = await toPng(target, {
+ backgroundColor: '#ffffff',
+ cacheBust: true,
+ pixelRatio: 2,
+ });
+ const pdf = new jsPDF({ compress: true, format: 'a4', orientation: 'p', unit: 'mm' });
+ const pageWidth = pdf.internal.pageSize.getWidth();
+ const pageHeight = pdf.internal.pageSize.getHeight();
+ const imgWidth = pageWidth;
+ const imgHeight = (target.offsetHeight * imgWidth) / target.offsetWidth;
+
+ let heightLeft = imgHeight;
+ let position = 0;
+ pdf.addImage(dataUrl, 'PNG', 0, position, imgWidth, imgHeight);
+ heightLeft -= pageHeight;
+ while (heightLeft > 0) {
+ position -= pageHeight;
+ pdf.addPage();
+ pdf.addImage(dataUrl, 'PNG', 0, position, imgWidth, imgHeight);
+ heightLeft -= pageHeight;
+ }
+ pdf.save(`绠$悊椹鹃┒鑸辩粺璁℃姤琛�-${new Date().toLocaleDateString()}.pdf`);
+ message.success('PDF 鎶ヨ〃宸插鍑�');
+ } catch (error) {
+ console.error('[management-cockpit] PDF 瀵煎嚭澶辫触锛�', error);
+ message.error(
+ `PDF 瀵煎嚭澶辫触锛�${error instanceof Error ? error.message : '鏈煡閿欒'}锛岃鎵撳紑娴忚鍣ㄦ帶鍒跺彴(F12)鏌ョ湅璇︽儏`,
+ );
+ } finally {
+ hide();
+ }
+}
+
+/** 鍔犺浇姹囨�荤粺璁� */
+async function loadInitial() {
+ await loadSummary();
+}
+loadInitial();
+</script>
+
+<template>
+ <Page>
+ <!-- 宸ュ叿鏍� -->
+ <div class="mb-4 flex flex-wrap items-center justify-between gap-3">
+ <div class="flex items-center gap-2">
+ <IconifyIcon class="text-xl text-blue-500" icon="lucide:gauge" />
+ <span class="text-base font-semibold">绠$悊椹鹃┒鑸变笌缁熻鍒嗘瀽</span>
+ </div>
+ <Space>
+ <Button :loading="loading" @click="handleRefresh">
+ <template #icon><IconifyIcon icon="lucide:refresh-cw" /></template>
+ 鍒锋柊
+ </Button>
+ <Button v-access:code="['mes:dashboard:export']" type="primary" @click="handleExportExcel">
+ <template #icon><IconifyIcon icon="lucide:file-spreadsheet" /></template>
+ 瀵煎嚭 Excel
+ </Button>
+ <Button v-access:code="['mes:dashboard:export']" type="primary" ghost @click="handleExportPdf">
+ <template #icon><IconifyIcon icon="lucide:file-down" /></template>
+ 瀵煎嚭 PDF
+ </Button>
+ <Button v-print="printObj">
+ <template #icon><IconifyIcon icon="lucide:printer" /></template>
+ 鎵撳嵃
+ </Button>
+ </Space>
+ </div>
+
+ <!-- 鎶ヨ〃鍐呭锛圗xcel/PDF/鎵撳嵃 鍧囧熀浜庢鍖哄煙锛� -->
+ <div id="management-cockpit-report" class="rounded-lg bg-white p-4 dark:bg-gray-800">
+ <!-- 浜旂淮搴� KPI -->
+ <KpiCards :key="`kpi-${reloadKey}`" :summary="summary" class="mb-2" />
+
+ <!-- 鐢熶骇瓒嬪娍 -->
+ <ProductionTrend :key="`pt-${reloadKey}`" class="mb-4" />
+
+ <QualityChart :key="`qc-${reloadKey}`" class="mb-4" />
+
+ <InventoryChart :key="`iv-${reloadKey}`" class="mb-4" />
+ <OutboundChart :key="`ob-${reloadKey}`" class="mb-4" />
+ <TraceChart :key="`tr-${reloadKey}`" class="mb-4" />
+ </div>
+ </Page>
+</template>
diff --git a/src/views/management-cockpit/modules/inventory-chart.vue b/src/views/management-cockpit/modules/inventory-chart.vue
new file mode 100644
index 0000000..61647c2
--- /dev/null
+++ b/src/views/management-cockpit/modules/inventory-chart.vue
@@ -0,0 +1,82 @@
+<script lang="ts" setup>
+import type { EchartsUIType } from '@vben/plugins/echarts';
+
+import { onMounted, ref } from 'vue';
+
+import { EchartsUI, useEcharts } from '@vben/plugins/echarts';
+
+import { Card, Col, Row, Spin } from 'ant-design-vue';
+
+import { getManagementCockpitInventory } from '#/api/mes/management-cockpit';
+
+import { getBarChartOptions, getPieChartOptions } from '../chart-options';
+
+defineOptions({ name: 'ManagementCockpitInventoryChart' });
+
+const loading = ref(false);
+const warehouseRef = ref<EchartsUIType>();
+const itemRef = ref<EchartsUIType>();
+const stateRef = ref<EchartsUIType>();
+const { renderEcharts: renderWarehouse } = useEcharts(warehouseRef);
+const { renderEcharts: renderItem } = useEcharts(itemRef);
+const { renderEcharts: renderState } = useEcharts(stateRef);
+
+/** 鍔犺浇搴撳瓨缁熻骞舵覆鏌� */
+async function loadData() {
+ loading.value = true;
+ try {
+ const data = await getManagementCockpitInventory();
+ const warehouses = data.warehouseDistribution || [];
+ const items = data.itemDistribution || [];
+ const states = data.stateDistribution || [];
+ await renderWarehouse(
+ getBarChartOptions(
+ warehouses.map((w) => w.name),
+ warehouses.map((w) => w.count),
+ '搴撳瓨鏁伴噺',
+ '#409EFF',
+ ),
+ );
+ await renderItem(
+ getBarChartOptions(
+ items.map((i) => i.name),
+ items.map((i) => i.count),
+ '搴撳瓨鏁伴噺',
+ '#36cfc9',
+ ),
+ );
+ await renderState(
+ getPieChartOptions(
+ states.map((s) => ({ name: s.name, value: s.count })),
+ ),
+ );
+ } finally {
+ loading.value = false;
+ }
+}
+
+onMounted(() => {
+ loadData();
+});
+</script>
+
+<template>
+ <Card title="搴撳瓨缁村害缁熻" class="h-full">
+ <Spin :spinning="loading">
+ <Row :gutter="16">
+ <Col :lg="9" :md="24" :sm="24" :xs="24">
+ <div class="mb-1 text-sm text-gray-500">鎸変粨搴撳垎甯�</div>
+ <EchartsUI ref="warehouseRef" class="h-[280px] w-full" />
+ </Col>
+ <Col :lg="9" :md="24" :sm="24" :xs="24">
+ <div class="mb-1 text-sm text-gray-500">鎸夊搧绉嶅垎甯�</div>
+ <EchartsUI ref="itemRef" class="h-[280px] w-full" />
+ </Col>
+ <Col :lg="6" :md="24" :sm="24" :xs="24">
+ <div class="mb-1 text-sm text-gray-500">鎸夊簱瀛樼姸鎬�</div>
+ <EchartsUI ref="stateRef" class="h-[280px] w-full" />
+ </Col>
+ </Row>
+ </Spin>
+ </Card>
+</template>
diff --git a/src/views/management-cockpit/modules/kpi-cards.vue b/src/views/management-cockpit/modules/kpi-cards.vue
new file mode 100644
index 0000000..d0878c2
--- /dev/null
+++ b/src/views/management-cockpit/modules/kpi-cards.vue
@@ -0,0 +1,125 @@
+<script lang="ts" setup>
+import type { ManagementCockpitApi } from '#/api/mes/management-cockpit';
+
+import { CountTo } from '@vben/common-ui';
+import { IconifyIcon } from '@vben/icons';
+
+import { Card, Col, Row } from 'ant-design-vue';
+
+defineOptions({ name: 'ManagementCockpitKpiCards' });
+
+const props = defineProps<{
+ summary: ManagementCockpitApi.Summary;
+}>();
+
+/** 淇濈暀涓や綅灏忔暟 */
+function fmt(value?: number): number {
+ return Number((value ?? 0).toFixed(2));
+}
+
+/** 浜旂淮搴� KPI 鍗¢厤缃� */
+const cards = [
+ {
+ dimension: '鐢熶骇',
+ gradient: 'linear-gradient(135deg, #0ea5e9, #38bdf8)',
+ icon: 'lucide:factory',
+ mainLabel: '鐢熶骇鎵规',
+ mainValue: () => props.summary.batchTotal,
+ items: [
+ { label: '琚嬬爜', value: () => props.summary.bagCodeTotal },
+ { label: '鎵樼洏鐮�', value: () => props.summary.palletTotal },
+ { label: '浠婃棩鍏ュ簱', value: () => props.summary.todayInboundBagCount },
+ ],
+ },
+ {
+ dimension: '璐ㄦ',
+ gradient: 'linear-gradient(135deg, #67c23a, #95d475)',
+ icon: 'lucide:clipboard-check',
+ mainLabel: '鍚堟牸鐜�(%)',
+ mainValue: () => fmt(props.summary.qualityPassRate),
+ items: [
+ { label: '鍚堟牸', value: () => props.summary.qualityPass },
+ { label: '涓嶅悎鏍�', value: () => props.summary.qualityFail },
+ { label: '澶勭悊涓�', value: () => props.summary.qualityPending },
+ ],
+ },
+ {
+ dimension: '搴撳瓨',
+ gradient: 'linear-gradient(135deg, #f59e0b, #fbbf24)',
+ icon: 'lucide:warehouse',
+ mainLabel: '搴撳瓨鎬婚噺',
+ mainValue: () => fmt(props.summary.stockTotal),
+ items: [
+ { label: '鏆傚瓨搴�', value: () => fmt(props.summary.stockTemporary) },
+ { label: '鍚堟牸搴�', value: () => fmt(props.summary.stockQualified) },
+ { label: '浣庡簱瀛橀璀�', value: () => props.summary.lowStockCount },
+ ],
+ },
+ {
+ dimension: '鍑哄簱',
+ gradient: 'linear-gradient(135deg, #ec4899, #f472b6)',
+ icon: 'lucide:package-open',
+ mainLabel: '鍑哄簱鎬婚噺',
+ mainValue: () => fmt(props.summary.outboundQuantityTotal),
+ items: [
+ { label: '鍑哄簱鍗曟暟', value: () => props.summary.outboundOrderTotal },
+ { label: '浠婃棩鍑哄簱', value: () => fmt(props.summary.todayOutboundQuantity) },
+ ],
+ },
+ {
+ dimension: '杩芥函',
+ gradient: 'linear-gradient(135deg, #14b8a6, #2dd4bf)',
+ icon: 'lucide:scan-search',
+ mainLabel: '鎵爜鎬绘暟',
+ mainValue: () => props.summary.scanTotal,
+ items: [
+ { label: '浠婃棩鎵爜', value: () => props.summary.todayScanCount },
+ { label: '绐滆揣棰勮', value: () => props.summary.crossRegionWarningTotal },
+ { label: '寰呭鐞�', value: () => props.summary.crossRegionPendingCount },
+ ],
+ },
+];
+</script>
+
+<template>
+ <Row :gutter="16">
+ <Col
+ v-for="card in cards"
+ :key="card.dimension"
+ :lg="8"
+ :md="12"
+ :sm="12"
+ :xl="8"
+ :xs="24"
+ class="mb-4"
+ >
+ <Card class="kpi-card h-full">
+ <div class="flex items-start justify-between">
+ <div class="flex items-center gap-3">
+ <div
+ class="flex size-12 flex-shrink-0 items-center justify-center rounded-xl text-white"
+ :style="{ background: card.gradient }"
+ >
+ <IconifyIcon class="size-6" :icon="card.icon" />
+ </div>
+ <div>
+ <div class="text-muted-foreground text-sm">{{ card.dimension }}</div>
+ <CountTo
+ class="text-xl font-bold leading-tight"
+ :end-val="card.mainValue()"
+ :duration="1200"
+ />
+ <div class="text-muted-foreground text-xs">{{ card.mainLabel }}</div>
+ </div>
+ </div>
+ </div>
+ <div class="mt-3 flex flex-wrap gap-x-4 gap-y-1 border-t border-dashed pt-3">
+ <span v-for="item in card.items" :key="item.label" class="text-xs text-gray-500">
+ {{ item.label }}锛�
+ <b class="text-sm text-gray-800 dark:text-gray-200">{{ item.value() }}</b>
+ </span>
+ </div>
+ </Card>
+ </Col>
+ </Row>
+</template>
diff --git a/src/views/management-cockpit/modules/outbound-chart.vue b/src/views/management-cockpit/modules/outbound-chart.vue
new file mode 100644
index 0000000..7be7864
--- /dev/null
+++ b/src/views/management-cockpit/modules/outbound-chart.vue
@@ -0,0 +1,77 @@
+<script lang="ts" setup>
+import type { EchartsUIType } from '@vben/plugins/echarts';
+
+import { onMounted, ref } from 'vue';
+
+import { EchartsUI, useEcharts } from '@vben/plugins/echarts';
+
+import { Card, Col, RadioButton, RadioGroup, Row, Spin } from 'ant-design-vue';
+
+import { getManagementCockpitOutbound } from '#/api/mes/management-cockpit';
+
+import { getLineChartOptions, getPieChartOptions } from '../chart-options';
+
+defineOptions({ name: 'ManagementCockpitOutboundChart' });
+
+const trendDays = ref(30);
+const loading = ref(false);
+const trendRef = ref<EchartsUIType>();
+const dealerRef = ref<EchartsUIType>();
+const { renderEcharts: renderTrend } = useEcharts(trendRef);
+const { renderEcharts: renderDealer } = useEcharts(dealerRef);
+
+/** 鍔犺浇鍑哄簱缁熻骞舵覆鏌� */
+async function loadData() {
+ loading.value = true;
+ try {
+ const data = await getManagementCockpitOutbound(trendDays.value);
+ const trend = data.trend || [];
+ const dealers = data.dealerDistribution || [];
+ await renderTrend(
+ getLineChartOptions(
+ trend.map((d) => d.date.slice(5)),
+ trend.map((d) => Number(d.count ?? 0)),
+ '鍑哄簱鏁伴噺',
+ ),
+ );
+ await renderDealer(
+ getPieChartOptions(dealers.map((d) => ({ name: d.name, value: d.count }))),
+ );
+ } finally {
+ loading.value = false;
+ }
+}
+
+/** 鍒囨崲澶╂暟鑼冨洿 */
+function handleDaysChange() {
+ loadData();
+}
+
+onMounted(() => {
+ loadData();
+});
+</script>
+
+<template>
+ <Card title="鍑哄簱缁村害缁熻" class="h-full">
+ <template #extra>
+ <RadioGroup v-model:value="trendDays" size="small" @change="handleDaysChange">
+ <RadioButton :value="7">杩� 7 澶�</RadioButton>
+ <RadioButton :value="30">杩� 30 澶�</RadioButton>
+ <RadioButton :value="90">杩� 90 澶�</RadioButton>
+ </RadioGroup>
+ </template>
+ <Spin :spinning="loading">
+ <Row :gutter="16">
+ <Col :lg="15" :md="24" :sm="24" :xs="24">
+ <div class="mb-1 text-sm text-gray-500">鍑哄簱瓒嬪娍</div>
+ <EchartsUI ref="trendRef" class="h-[280px] w-full" />
+ </Col>
+ <Col :lg="9" :md="24" :sm="24" :xs="24">
+ <div class="mb-1 text-sm text-gray-500">缁忛攢鍟嗗嚭搴撳崰姣旓紙TOP 20锛�</div>
+ <EchartsUI ref="dealerRef" class="h-[280px] w-full" />
+ </Col>
+ </Row>
+ </Spin>
+ </Card>
+</template>
diff --git a/src/views/management-cockpit/modules/production-trend.vue b/src/views/management-cockpit/modules/production-trend.vue
new file mode 100644
index 0000000..25fa5c8
--- /dev/null
+++ b/src/views/management-cockpit/modules/production-trend.vue
@@ -0,0 +1,56 @@
+<script lang="ts" setup>
+import type { EchartsUIType } from '@vben/plugins/echarts';
+
+import { onMounted, ref } from 'vue';
+
+import { EchartsUI, useEcharts } from '@vben/plugins/echarts';
+
+import { Card, RadioButton, RadioGroup } from 'ant-design-vue';
+
+import { getManagementCockpitProductionTrend } from '#/api/mes/management-cockpit';
+
+import { getProductionTrendChartOptions } from '../chart-options';
+
+defineOptions({ name: 'ManagementCockpitProductionTrend' });
+
+const trendDays = ref(30); // 褰撳墠澶╂暟鑼冨洿
+const chartRef = ref<EchartsUIType>();
+const { renderEcharts } = useEcharts(chartRef);
+
+/** 鍔犺浇鐢熶骇瓒嬪娍鏁版嵁骞舵覆鏌� */
+async function loadData() {
+ const data = await getManagementCockpitProductionTrend(trendDays.value);
+ const dates = data.map((d) => d.date.slice(5));
+ await renderEcharts(
+ getProductionTrendChartOptions(
+ dates,
+ data.map((d) => d.batchCount),
+ data.map((d) => d.bagCodeCount),
+ data.map((d) => d.palletCount),
+ data.map((d) => Number(d.inboundBagQuantity ?? 0)),
+ ),
+ );
+}
+
+/** 鍒囨崲澶╂暟鑼冨洿 */
+function handleDaysChange() {
+ loadData();
+}
+
+onMounted(() => {
+ loadData();
+});
+</script>
+
+<template>
+ <Card title="鐢熶骇瓒嬪娍锛堣繎 N 澶╋級" class="h-full">
+ <template #extra>
+ <RadioGroup v-model:value="trendDays" size="small" @change="handleDaysChange">
+ <RadioButton :value="7">杩� 7 澶�</RadioButton>
+ <RadioButton :value="30">杩� 30 澶�</RadioButton>
+ <RadioButton :value="90">杩� 90 澶�</RadioButton>
+ </RadioGroup>
+ </template>
+ <EchartsUI ref="chartRef" class="h-[320px] w-full" />
+ </Card>
+</template>
diff --git a/src/views/management-cockpit/modules/quality-chart.vue b/src/views/management-cockpit/modules/quality-chart.vue
new file mode 100644
index 0000000..38cc0e5
--- /dev/null
+++ b/src/views/management-cockpit/modules/quality-chart.vue
@@ -0,0 +1,67 @@
+<script lang="ts" setup>
+import type { EchartsUIType } from '@vben/plugins/echarts';
+
+import { onMounted, ref } from 'vue';
+
+import { EchartsUI, useEcharts } from '@vben/plugins/echarts';
+
+import { Card, Col, Row, Spin } from 'ant-design-vue';
+
+import { getManagementCockpitQuality } from '#/api/mes/management-cockpit';
+
+import { getPieChartOptions, getQualityIndicatorChartOptions } from '../chart-options';
+
+defineOptions({ name: 'ManagementCockpitQualityChart' });
+
+const loading = ref(false);
+const resultChartRef = ref<EchartsUIType>();
+const indicatorChartRef = ref<EchartsUIType>();
+const { renderEcharts: renderResult } = useEcharts(resultChartRef);
+const { renderEcharts: renderIndicator } = useEcharts(indicatorChartRef);
+
+/** 鍔犺浇璐ㄦ缁熻骞舵覆鏌� */
+async function loadData() {
+ loading.value = true;
+ try {
+ const data = await getManagementCockpitQuality();
+ // 1. 妫�楠岀粨鏋滃垎甯冪幆褰㈠浘
+ const pieData = (data.resultDistribution || []).map((item) => ({
+ name: item.name,
+ value: item.count,
+ }));
+ await renderResult(getPieChartOptions(pieData));
+ // 2. 鍥涢」鎸囨爣鍧囧�� + 鍚堟牸鐜囨煴鐘跺浘
+ const indicators = data.indicatorList || [];
+ await renderIndicator(
+ getQualityIndicatorChartOptions(
+ indicators.map((i) => i.indicatorName || i.indicatorCode),
+ indicators.map((i) => Number(i.averageValue ?? 0)),
+ indicators.map((i) => Number(i.passRate ?? 0)),
+ ),
+ );
+ } finally {
+ loading.value = false;
+ }
+}
+
+onMounted(() => {
+ loadData();
+});
+</script>
+
+<template>
+ <Card title="璐ㄦ缁村害缁熻" class="h-full">
+ <Spin :spinning="loading">
+ <Row :gutter="16">
+ <Col :lg="10" :md="24" :sm="24" :xs="24">
+ <div class="mb-1 text-sm text-gray-500">妫�楠岀粨鏋滃垎甯�</div>
+ <EchartsUI ref="resultChartRef" class="h-[280px] w-full" />
+ </Col>
+ <Col :lg="14" :md="24" :sm="24" :xs="24">
+ <div class="mb-1 text-sm text-gray-500">鍥涢」鎸囨爣鍧囧�间笌鍚堟牸鐜�</div>
+ <EchartsUI ref="indicatorChartRef" class="h-[280px] w-full" />
+ </Col>
+ </Row>
+ </Spin>
+ </Card>
+</template>
diff --git a/src/views/management-cockpit/modules/trace-chart.vue b/src/views/management-cockpit/modules/trace-chart.vue
new file mode 100644
index 0000000..3c06043
--- /dev/null
+++ b/src/views/management-cockpit/modules/trace-chart.vue
@@ -0,0 +1,125 @@
+<script lang="ts" setup>
+import type { EchartsUIType } from '@vben/plugins/echarts';
+
+import { onMounted, ref } from 'vue';
+
+import { EchartsUI, useEcharts } from '@vben/plugins/echarts';
+
+import { Card, Col, Row, Spin, Statistic } from 'ant-design-vue';
+
+import { getManagementCockpitTrace } from '#/api/mes/management-cockpit';
+
+import { getBarChartOptions, getLineChartOptions, getPieChartOptions } from '../chart-options';
+
+defineOptions({ name: 'ManagementCockpitTraceChart' });
+
+const loading = ref(false);
+const scanTrendRef = ref<EchartsUIType>();
+const provinceRef = ref<EchartsUIType>();
+const channelRef = ref<EchartsUIType>();
+const { renderEcharts: renderScanTrend } = useEcharts(scanTrendRef);
+const { renderEcharts: renderProvince } = useEcharts(provinceRef);
+const { renderEcharts: renderChannel } = useEcharts(channelRef);
+
+// 绐滆揣棰勮姹囨�伙紙鐢ㄤ簬灞曠ず鍗$墖锛�
+const crossRegion = ref({
+ total: 0,
+ pending: 0,
+ handled: 0,
+ falseAlarm: 0,
+ crossProvince: 0,
+ crossCity: 0,
+});
+
+/** 鍔犺浇杩芥函缁熻骞舵覆鏌� */
+async function loadData() {
+ loading.value = true;
+ try {
+ const data = await getManagementCockpitTrace(30);
+ const scanTrend = data.scanTrend || [];
+ const provinces = data.provinceDistribution || [];
+ const channels = data.channelDistribution || [];
+ crossRegion.value = data.crossRegionSummary || crossRegion.value;
+ await renderScanTrend(
+ getLineChartOptions(
+ scanTrend.map((d) => d.date.slice(5)),
+ scanTrend.map((d) => Number(d.count ?? 0)),
+ '鎵爜娆℃暟',
+ '#409EFF',
+ ),
+ );
+ await renderProvince(
+ getBarChartOptions(
+ provinces.map((p) => p.name),
+ provinces.map((p) => p.count),
+ '鎵爜娆℃暟',
+ '#67c23a',
+ ),
+ );
+ await renderChannel(
+ getPieChartOptions(channels.map((c) => ({ name: c.name, value: c.count }))),
+ );
+ } finally {
+ loading.value = false;
+ }
+}
+
+onMounted(() => {
+ loadData();
+});
+</script>
+
+<template>
+ <Card title="杩芥函缁村害缁熻" class="h-full">
+ <Spin :spinning="loading">
+ <!-- 绐滆揣棰勮姹囨�诲崱鐗� -->
+ <Row :gutter="16" class="mb-2">
+ <Col :lg="4" :md="8" :sm="12" :xs="24" class="mb-2">
+ <Card size="small">
+ <Statistic title="棰勮鎬绘暟" :value="crossRegion.total" />
+ </Card>
+ </Col>
+ <Col :lg="4" :md="8" :sm="12" :xs="24" class="mb-2">
+ <Card size="small">
+ <Statistic title="寰呭鐞�" :value="crossRegion.pending" :value-style="{ color: '#f5222d' }" />
+ </Card>
+ </Col>
+ <Col :lg="4" :md="8" :sm="12" :xs="24" class="mb-2">
+ <Card size="small">
+ <Statistic title="宸插鐞�" :value="crossRegion.handled" />
+ </Card>
+ </Col>
+ <Col :lg="4" :md="8" :sm="12" :xs="24" class="mb-2">
+ <Card size="small">
+ <Statistic title="璇姤" :value="crossRegion.falseAlarm" />
+ </Card>
+ </Col>
+ <Col :lg="4" :md="8" :sm="12" :xs="24" class="mb-2">
+ <Card size="small">
+ <Statistic title="璺ㄧ渷" :value="crossRegion.crossProvince" />
+ </Card>
+ </Col>
+ <Col :lg="4" :md="8" :sm="12" :xs="24" class="mb-2">
+ <Card size="small">
+ <Statistic title="璺ㄥ競" :value="crossRegion.crossCity" />
+ </Card>
+ </Col>
+ </Row>
+ <!-- 鎵爜瓒嬪娍 + 鐪佷唤鍒嗗竷 + 娓犻亾鍒嗗竷 -->
+ <Row :gutter="16">
+ <Col :lg="10" :md="24" :sm="24" :xs="24">
+ <div class="mb-1 text-sm text-gray-500">娑堣垂鑰呮壂鐮佽秼鍔�</div>
+ <EchartsUI ref="scanTrendRef" class="h-[280px] w-full" />
+ </Col>
+ <Col :lg="9" :md="24" :sm="24" :xs="24">
+ <div class="mb-1 text-sm text-gray-500">鎵爜鐪佷唤鍒嗗竷</div>
+ <EchartsUI ref="provinceRef" class="h-[280px] w-full" />
+ </Col>
+ <Col :lg="5" :md="24" :sm="24" :xs="24">
+ <div class="mb-1 text-sm text-gray-500">鎵爜娓犻亾鍒嗗竷</div>
+ <EchartsUI ref="channelRef" class="h-[280px] w-full" />
+ </Col>
+ </Row>
+ </Spin>
+ </Card>
+</template>
--
Gitblit v1.9.3