This commit is contained in:
oneao committed 2026-03-27 17:22:22 +08:00
1 parent 26721a142e
commit 840d33ef3b
32 files changed
+2068 -590

No files matched your search

+3 -3
View File
@@ -1,15 +1,15 @@
# Application
# 应用名称(用于标题、日志等)
PUBLIC_APP_NAME=g3hy2026
PUBLIC_APP_NAME=g3ocr
# Server
# 应用部署基础路径(路由和静态资源 base)
PUBLIC_SERVER_PATH=/
PUBLIC_SERVER_PATH=/g3ocr/
# 本地开发服务器端口
PUBLIC_SERVER_PORT=8080
# API
# 后端 API 基础地址
PUBLIC_API_BASE_URL=http://127.0.0.1:8085/api
PUBLIC_API_BASE_URL=http://ser369.g3soft.cn:80/api
PUBLIC_ALIYUN_BUCKET = g3hd
+2
View File
@@ -25,6 +25,8 @@
"nprogress": "^0.2.0",
"pinia": "^3.0.4",
"pinia-plugin-persistedstate": "^4.7.1",
"qrcode": "^1.5.4",
"qrcode.vue": "^3.8.0",
"uuid": "^13.0.0",
"vue": "^3.5.26",
"vue-router": "^5.0.3",
+207
View File
@@ -56,6 +56,12 @@ importers:
pinia-plugin-persistedstate:
specifier: ^4.7.1
version: 4.7.1(pinia@3.0.4(vue@3.5.30))
qrcode:
specifier: ^1.5.4
version: 1.5.4
qrcode.vue:
specifier: ^3.8.0
version: 3.8.0(vue@3.5.30)
uuid:
specifier: ^13.0.0
version: 13.0.0
@@ -918,6 +924,10 @@ packages:
engines: {node: '>=0.4.0'}
hasBin: true
ansi-regex@5.0.1:
resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==}
engines: {node: '>=8'}
ansi-styles@4.3.0:
resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==}
engines: {node: '>=8'}
@@ -1020,6 +1030,10 @@ packages:
resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==}
engines: {node: '>= 0.4'}
camelcase@5.3.1:
resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==}
engines: {node: '>=6'}
caniuse-lite@1.0.30001778:
resolution: {integrity: sha512-PN7uxFL+ExFJO61aVmP1aIEG4i9whQd4eoSCebav62UwDyp5OHh06zN4jqKSMePVgxHifCw1QJxdRkA1Pisekg==}
@@ -1038,6 +1052,9 @@ packages:
resolution: {integrity: sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==}
engines: {node: '>= 20.19.0'}
cliui@6.0.0:
resolution: {integrity: sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==}
color-convert@2.0.1:
resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==}
engines: {node: '>=7.0.0'}
@@ -1109,6 +1126,10 @@ packages:
supports-color:
optional: true
decamelize@1.2.0:
resolution: {integrity: sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==}
engines: {node: '>=0.10.0'}
deepmerge@4.3.1:
resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==}
engines: {node: '>=0.10.0'}
@@ -1124,6 +1145,9 @@ packages:
resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==}
engines: {node: '>=8'}
dijkstrajs@1.0.3:
resolution: {integrity: sha512-qiSlmBq9+BCdCA/L46dw8Uy93mloxsPSbwnm5yrKn2vMPiy8KyAskTF6zuV/j5BMsmOGZDPs7KjU+mjb670kfA==}
dom-serializer@2.0.0:
resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==}
@@ -1161,6 +1185,9 @@ packages:
peerDependencies:
vue: ^3.3.0
emoji-regex@8.0.0:
resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==}
emojis-list@3.0.0:
resolution: {integrity: sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==}
engines: {node: '>= 4'}
@@ -1254,6 +1281,10 @@ packages:
file-saver@2.0.5:
resolution: {integrity: sha512-P9bmyZ3h/PRG+Nzga+rbdI4OEpNDzAVyy74uVO9ATgzLK6VtAsYybF/+TOCvrc0MO793d6+42lLyZTw7/ArVzA==}
find-up@4.1.0:
resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==}
engines: {node: '>=8'}
follow-redirects@1.15.11:
resolution: {integrity: sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==}
engines: {node: '>=4.0'}
@@ -1285,6 +1316,10 @@ packages:
resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==}
engines: {node: '>=6.9.0'}
get-caller-file@2.0.5:
resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==}
engines: {node: 6.* || 8.* || >= 10.*}
get-intrinsic@1.3.0:
resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==}
engines: {node: '>= 0.4'}
@@ -1355,6 +1390,10 @@ packages:
resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==}
engines: {node: '>=0.10.0'}
is-fullwidth-code-point@3.0.0:
resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==}
engines: {node: '>=8'}
is-glob@4.0.3:
resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==}
engines: {node: '>=0.10.0'}
@@ -1417,6 +1456,10 @@ packages:
resolution: {integrity: sha512-arhlxbFRmoQHl33a0Zkle/YWlmNwoyt6QNZEIJcqNbdrsix5Lvc4HyyI3EnwxTYlZYc32EbYrQ8SzEZ7dqgg9A==}
engines: {node: '>=14'}
locate-path@5.0.0:
resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==}
engines: {node: '>=8'}
lodash-es@4.17.23:
resolution: {integrity: sha512-kVI48u3PZr38HdYz98UmfPnXl2DXrpdctLrFLCd3kOx1xUkOmpFPx7gCWWM5MPkL/fD8zb+Ph0QzjGFs4+hHWg==}
@@ -1580,12 +1623,28 @@ packages:
engines: {node: ^20.19.0 || >=22.12.0}
hasBin: true
p-limit@2.3.0:
resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==}
engines: {node: '>=6'}
p-locate@4.1.0:
resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==}
engines: {node: '>=8'}
p-try@2.2.0:
resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==}
engines: {node: '>=6'}
package-manager-detector@1.6.0:
resolution: {integrity: sha512-61A5ThoTiDG/C8s8UMZwSorAGwMJ0ERVGj2OjoW5pAalsNOg15+iQiPzrLJ4jhZ1HJzmC2PIHT2oEiH3R5fzNA==}
pako@1.0.11:
resolution: {integrity: sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==}
path-exists@4.0.0:
resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==}
engines: {node: '>=8'}
path-is-absolute@1.0.1:
resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==}
engines: {node: '>=0.10.0'}
@@ -1635,6 +1694,10 @@ packages:
pkg-types@2.3.0:
resolution: {integrity: sha512-SIqCzDRg0s9npO5XQ3tNZioRY1uK06lA41ynBC1YmFTmnY6FjUjVt6s4LoADmwoig1qqD0oK8h1p/8mlMx8Oig==}
pngjs@5.0.0:
resolution: {integrity: sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw==}
engines: {node: '>=10.13.0'}
postcss@8.5.8:
resolution: {integrity: sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg==}
engines: {node: ^10 || ^12 || >=14}
@@ -1652,6 +1715,16 @@ packages:
proxy-from-env@1.1.0:
resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==}
qrcode.vue@3.8.0:
resolution: {integrity: sha512-+XKbSKvQu158zlHsJm+HObGUQM3Q+9Oq6yb2op/6lMM2gwOiiG9uIhujvrSV5UoTjrzR0BcNxCdW2kk7KE4NEg==}
peerDependencies:
vue: ^3.0.0
qrcode@1.5.4:
resolution: {integrity: sha512-1ca71Zgiu6ORjHqFBDpnSMTR2ReToX4l1Au1VFLyVeBTFavzQnv5JxMFr3ukHVKpSrSA2MCk0lNJSykjUfz7Zg==}
engines: {node: '>=10.13.0'}
hasBin: true
quansync@0.2.11:
resolution: {integrity: sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA==}
@@ -1676,6 +1749,13 @@ packages:
reduce-configs@1.1.1:
resolution: {integrity: sha512-EYtsVGAQarE8daT54cnaY1PIknF2VB78ug6Zre2rs36EsJfC40EG6hmTU2A2P1ZuXnKAt2KI0fzOGHcX7wzdPw==}
require-directory@2.1.1:
resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==}
engines: {node: '>=0.10.0'}
require-main-filename@2.0.0:
resolution: {integrity: sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==}
resize-observer-polyfill@1.5.1:
resolution: {integrity: sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==}
@@ -1846,6 +1926,9 @@ packages:
resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==}
hasBin: true
set-blocking@2.0.0:
resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==}
setimmediate@1.0.5:
resolution: {integrity: sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==}
@@ -1876,12 +1959,20 @@ packages:
ssr-window@3.0.0:
resolution: {integrity: sha512-q+8UfWDg9Itrg0yWK7oe5p/XRCJpJF9OBtXfOPgSJl+u3Xd5KI328RUEvUqSMVM9CiQUEf1QdBzJMkYGErj9QA==}
string-width@4.2.3:
resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==}
engines: {node: '>=8'}
string_decoder@1.1.1:
resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==}
string_decoder@1.3.0:
resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==}
strip-ansi@6.0.1:
resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==}
engines: {node: '>=8'}
strip-literal@3.1.0:
resolution: {integrity: sha512-8r3mkIM/2+PpjHoOtiAW8Rg3jJLHaV7xPwG+YRGrv6FP0wwk/toTpATxWYOW0BKdWwl82VT2tFYi5DlROa0Mxg==}
@@ -2056,9 +2147,16 @@ packages:
webpack-virtual-modules@0.6.2:
resolution: {integrity: sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==}
which-module@2.0.1:
resolution: {integrity: sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==}
wildcard@1.1.2:
resolution: {integrity: sha512-DXukZJxpHA8LuotRwL0pP1+rS6CS7FF2qStDDE1C7DDg2rLud2PXRMuEDYIPhgEezwnlHNL4c+N6MfMTjCGTng==}
wrap-ansi@6.2.0:
resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==}
engines: {node: '>=8'}
wrappy@1.0.2:
resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==}
@@ -2071,6 +2169,9 @@ packages:
xmlchars@2.2.0:
resolution: {integrity: sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==}
y18n@4.0.3:
resolution: {integrity: sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==}
yallist@3.1.1:
resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==}
@@ -2079,6 +2180,14 @@ packages:
engines: {node: '>= 14.6'}
hasBin: true
yargs-parser@18.1.3:
resolution: {integrity: sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==}
engines: {node: '>=6'}
yargs@15.4.1:
resolution: {integrity: sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==}
engines: {node: '>=8'}
zip-stream@4.1.1:
resolution: {integrity: sha512-9qv4rlDiopXg4E69k+vMHjNN63YFMe9sZMrdlvKnCjlCRWeCBswPPMPUfx+ipsAWq1LXHe70RcbaHdJJpS6hyQ==}
engines: {node: '>= 10'}
@@ -2995,6 +3104,8 @@ snapshots:
acorn@8.16.0: {}
ansi-regex@5.0.1: {}
ansi-styles@4.3.0:
dependencies:
color-convert: 2.0.1
@@ -3128,6 +3239,8 @@ snapshots:
es-errors: 1.3.0
function-bind: 1.1.2
camelcase@5.3.1: {}
caniuse-lite@1.0.30001778: {}
chainsaw@0.1.0:
@@ -3148,6 +3261,12 @@ snapshots:
dependencies:
readdirp: 5.0.0
cliui@6.0.0:
dependencies:
string-width: 4.2.3
strip-ansi: 6.0.1
wrap-ansi: 6.2.0
color-convert@2.0.1:
dependencies:
color-name: 1.1.4
@@ -3205,6 +3324,8 @@ snapshots:
dependencies:
ms: 2.1.3
decamelize@1.2.0: {}
deepmerge@4.3.1: {}
defu@6.1.4: {}
@@ -3214,6 +3335,8 @@ snapshots:
detect-libc@2.1.2:
optional: true
dijkstrajs@1.0.3: {}
dom-serializer@2.0.0:
dependencies:
domelementtype: 2.3.0
@@ -3275,6 +3398,8 @@ snapshots:
transitivePeerDependencies:
- typescript
emoji-regex@8.0.0: {}
emojis-list@3.0.0: {}
end-of-stream@1.4.5:
@@ -3371,6 +3496,11 @@ snapshots:
file-saver@2.0.5: {}
find-up@4.1.0:
dependencies:
locate-path: 5.0.0
path-exists: 4.0.0
follow-redirects@1.15.11: {}
form-data@4.0.5:
@@ -3396,6 +3526,8 @@ snapshots:
gensync@1.0.0-beta.2: {}
get-caller-file@2.0.5: {}
get-intrinsic@1.3.0:
dependencies:
call-bind-apply-helpers: 1.0.2
@@ -3472,6 +3604,8 @@ snapshots:
is-extglob@2.1.1:
optional: true
is-fullwidth-code-point@3.0.0: {}
is-glob@4.0.3:
dependencies:
is-extglob: 2.1.1
@@ -3526,6 +3660,10 @@ snapshots:
pkg-types: 2.3.0
quansync: 0.2.11
locate-path@5.0.0:
dependencies:
p-locate: 4.1.0
lodash-es@4.17.23: {}
lodash-unified@1.0.3(@types/lodash-es@4.17.12)(lodash-es@4.17.23)(lodash@4.17.23):
@@ -3674,10 +3812,22 @@ snapshots:
'@oxfmt/binding-win32-ia32-msvc': 0.40.0
'@oxfmt/binding-win32-x64-msvc': 0.40.0
p-limit@2.3.0:
dependencies:
p-try: 2.2.0
p-locate@4.1.0:
dependencies:
p-limit: 2.3.0
p-try@2.2.0: {}
package-manager-detector@1.6.0: {}
pako@1.0.11: {}
path-exists@4.0.0: {}
path-is-absolute@1.0.1: {}
pathe@2.0.3: {}
@@ -3713,6 +3863,8 @@ snapshots:
exsolve: 1.0.8
pathe: 2.0.3
pngjs@5.0.0: {}
postcss@8.5.8:
dependencies:
nanoid: 3.3.11
@@ -3727,6 +3879,16 @@ snapshots:
proxy-from-env@1.1.0: {}
qrcode.vue@3.8.0(vue@3.5.30):
dependencies:
vue: 3.5.30
qrcode@1.5.4:
dependencies:
dijkstrajs: 1.0.3
pngjs: 5.0.0
yargs: 15.4.1
quansync@0.2.11: {}
readable-stream@2.3.8:
@@ -3756,6 +3918,10 @@ snapshots:
reduce-configs@1.1.1: {}
require-directory@2.1.1: {}
require-main-filename@2.0.0: {}
resize-observer-polyfill@1.5.1: {}
rfdc@1.4.1: {}
@@ -3889,6 +4055,8 @@ snapshots:
semver@6.3.1: {}
set-blocking@2.0.0: {}
setimmediate@1.0.5: {}
slate-history@0.66.0(slate@0.72.8):
@@ -3912,6 +4080,12 @@ snapshots:
ssr-window@3.0.0: {}
string-width@4.2.3:
dependencies:
emoji-regex: 8.0.0
is-fullwidth-code-point: 3.0.0
strip-ansi: 6.0.1
string_decoder@1.1.1:
dependencies:
safe-buffer: 5.1.2
@@ -3920,6 +4094,10 @@ snapshots:
dependencies:
safe-buffer: 5.2.1
strip-ansi@6.0.1:
dependencies:
ansi-regex: 5.0.1
strip-literal@3.1.0:
dependencies:
js-tokens: 9.0.1
@@ -4117,8 +4295,16 @@ snapshots:
webpack-virtual-modules@0.6.2: {}
which-module@2.0.1: {}
wildcard@1.1.2: {}
wrap-ansi@6.2.0:
dependencies:
ansi-styles: 4.3.0
string-width: 4.2.3
strip-ansi: 6.0.1
wrappy@1.0.2: {}
xe-utils@3.9.1: {}
@@ -4127,10 +4313,31 @@ snapshots:
xmlchars@2.2.0: {}
y18n@4.0.3: {}
yallist@3.1.1: {}
yaml@2.8.2: {}
yargs-parser@18.1.3:
dependencies:
camelcase: 5.3.1
decamelize: 1.2.0
yargs@15.4.1:
dependencies:
cliui: 6.0.0
decamelize: 1.2.0
find-up: 4.1.0
get-caller-file: 2.0.5
require-directory: 2.1.1
require-main-filename: 2.0.0
set-blocking: 2.0.0
string-width: 4.2.3
which-module: 2.0.1
y18n: 4.0.3
yargs-parser: 18.1.3
zip-stream@4.1.1:
dependencies:
archiver-utils: 3.0.4
@@ -124,7 +124,6 @@ const gridInnerLabelStyle = computed(() => {
background-color: #f9f9f9;
border-right: 1px solid #ccc;
font-size: 14px;
height: 100%;
display: flex;
position: relative;
min-width: 0;
@@ -26,6 +26,11 @@ const menuList = ref([
icon: "lucide:box",
path: "/container",
},
{
label: "手机二维码",
icon: "lucide:scan-qr-code",
path: "/phone",
},
{
label: "系统管理",
icon: "lucide:settings",
@@ -87,6 +87,40 @@ export function loadPageDataApi(
);
}
/**
* 分页加载表格数据
* @param {Object} params 参数对象
* @param {number} params.start 当前页
* @param {number} params.end 每页条数
* @param {string} params.viewName 视图名称
* @param {string} [params.searchCondition] 搜索条件
* @param {string} [params.orderField] 排序字段
* @param {string[]} [params.searchColumns] 搜索列
* @returns {Promise<{
* success: boolean,
* data: Array<Record<string, any>>,
* code: number,
* message: string
* }>} 返回 Promise 对象
*/
export function loadRangeDataApi(
{ start, end, viewName, searchCondition = "", orderField = "", searchColumns = [] },
config = {},
) {
return httpPost(
"/data/range",
{
start,
end,
viewName,
searchCondition,
orderField,
searchColumns,
},
config,
);
}
export function saveObjectApi(data) {
return httpPost("/data/saveObject", data);
}
@@ -23,6 +23,15 @@ export const routes = [
moduleId: "v_container",
},
},
// ==================== Phone ====================
{
path: "/phone",
component: () => import("@/views/phone/index.vue"),
meta: {
title: "手机二维码",
keepAlive: true,
},
},
// ==================== 系统管理 ====================
{
path: "/system/field",
@@ -13,7 +13,7 @@ const userStore = useUserStore();
const permissionStore = usePermissionStore();
const form = ref({
orgid: userStore.userInfo.orgid,
orgid: 'g3hd',
userid: userStore.userInfo.userid,
password: "",
});
@@ -130,7 +130,7 @@ async function onVcodeSuccess() {
<div class="tip">登录</div>
<div class="split"></div>
<div class="form">
<div class="form-item">
<!-- <div class="form-item">
<div class="label required">机构码</div>
<el-input v-model="form.orgid">
@@ -138,7 +138,7 @@ async function onVcodeSuccess() {
<G3Icon icon="lucide:building" size="18" />
</template>
</el-input>
</div>
</div> -->
<div class="form-item">
<div class="label required">账号</div>
<el-input v-model="form.userid">
@@ -1,7 +1,13 @@
<script lang="js" setup>
import { loadDataBySqlApi } from "@/request/api";
import { loadDataApi, loadDataBySqlApi, loadRangeDataApi } from "@/request/api";
import { useThrottle } from "@/utils/throttle";
import { ElMessage } from "element-plus";
import { saveAs } from "file-saver";
import JSZip from "jszip";
import { getAliyunFileBlob } from "@/utils/file";
import { formatToDate } from "@/utils/time";
const viewName = "v_container";
const visible = defineModel(false);
@@ -22,7 +28,7 @@ const chunkModeForm = ref({
pageSize: 100,
});
const total = ref(0);
const allTotal = ref(0);
const loadingTotal = ref(false);
function handleResetForm() {
@@ -65,12 +71,7 @@ const fetchTotalThrottle = useThrottle(async () => {
await fetchTotal();
}, 300);
async function fetchTotal() {
if (!visible.value) {
return;
}
loadingTotal.value = true;
function buildSearchCondition() {
let searchCondition = [];
if (searchForm.value.startTime) {
@@ -82,9 +83,7 @@ async function fetchTotal() {
}
if (searchForm.value.containerNo) {
searchCondition.push(
`b_container_no LIKE '%${searchForm.value.containerNo}%'`,
);
searchCondition.push(`b_container_no LIKE '%${searchForm.value.containerNo}%'`);
}
if (searchForm.value.username) {
@@ -92,33 +91,320 @@ async function fetchTotal() {
}
// 拼接 WHERE 条件
const whereClause = searchCondition.length
? "WHERE " + searchCondition.join(" AND ")
: "";
const whereClause = searchCondition.length ? "WHERE " + searchCondition.join(" AND ") : "";
return whereClause;
}
async function fetchTotal() {
if (!visible.value) {
return;
}
loadingTotal.value = true;
// 构建 SQL 获取总数
const sql = `SELECT COUNT(*) as total FROM v_container ${whereClause}`;
const sql = `SELECT COUNT(*) as total FROM ${viewName} ${buildSearchCondition()}`;
try {
const res = await loadDataBySqlApi(sql);
if (res.success) {
total.value = res.data[0]?.total || 0;
allTotal.value = res.data[0]?.total || 0;
}
} catch (err) {
console.error("获取总数失败", err);
total.value = 0;
allTotal.value = 0;
} finally {
loadingTotal.value = false;
}
}
function handleExport() {
if (total === 0) {
async function fetchDatas() {
const response = await loadDataApi(
viewName,
buildSearchCondition(),
"b_inputdatetime DESC, b_id DESC",
["b_id", "b_container_no", "b_inputdatetime"],
);
if (response.success) {
return response.data;
} else {
return [];
}
}
function handleDownload() {
if (allTotal.value === 0) {
ElMessage.warning("无有效数据可操作");
return;
}
if (searchForm.value.mode === "ALL") {
downloadAll();
} else if (searchForm.value.mode === "SLICE") {
downloadSlice();
} else if (searchForm.value.mode === "CHUNK") {
downloadChunk();
}
}
async function runWithLimit(tasks, limit = 3) {
const results = [];
const executing = [];
for (const task of tasks) {
const p = task().then((res) => {
executing.splice(executing.indexOf(p), 1);
return res;
});
results.push(p);
executing.push(p);
if (executing.length >= limit) {
await Promise.race(executing);
}
}
return Promise.all(results);
}
async function downloadAll() {
const loading = ElLoading.service({
lock: true,
text: "正在下载并打包文件,请稍候...",
});
try {
// 获取所有记录
const records = await fetchDatas();
if (!records.length) {
ElMessage.warning("无有效数据");
return;
}
const zip = new JSZip();
let finished = 0;
let totalFiles = 0;
// 1. 收集所有下载任务
const allTasks = [];
for (const item of records) {
const fileRes = await loadDataApi("bf_file", `father='${item.b_id}'`, "mx_xh asc");
const files = (fileRes.success && fileRes.data) || [];
totalFiles += files.length;
// 按 年/月/日/集装箱号 生成层级文件夹
const ymdFolderName = formatToDate(item.b_inputdatetime, "YYYY/MM/DD"); // 2026/03/27
const containerFolderName = item.b_container_no;
let folder = zip.folder(ymdFolderName);
folder = folder ? folder.folder(containerFolderName) : zip.folder(containerFolderName);
files.forEach((file, idx) => {
allTasks.push(async () => {
try {
const blob = await getAliyunFileBlob(file.mx_mapfilename);
const fileName = buildFileName(item.b_container_no, idx + 1, file.mx_filename) || "未命名文件";
folder.file(fileName, blob);
} catch (e) {
console.error(item.b_container_no + "下载失败:", file.mx_mapfilename, e);
} finally {
finished++;
loading.setText(`正在下载 ${finished}/${totalFiles} 个文件...`);
}
});
});
}
// 2. 并发执行下载任务,限制同时 3 个
await runWithLimit(allTasks, 3);
loading.setText("正在生成压缩包...");
const content = await zip.generateAsync({ type: "blob" });
// 3. 保存压缩包
saveAs(content, buildZipName("ALL"));
ElMessage.success("下载完成");
} catch (e) {
console.error(e);
} finally {
loading.close();
}
}
// 按区间下载
async function downloadSlice() {
const loading = ElLoading.service({
lock: true,
text: "正在下载并打包文件,请稍候...",
});
try {
let start = Math.max(1, Math.min(sliceModeForm.value.startPage || 1, allTotal.value));
let end = Math.max(1, Math.min(sliceModeForm.value.endPage || 1, allTotal.value));
if (start > end) [start, end] = [end, start];
sliceModeForm.value.startPage = start;
sliceModeForm.value.endPage = end;
const dataRes = await loadRangeDataApi({
start,
end,
viewName,
searchCondition: buildSearchCondition(),
orderField: "b_inputdatetime DESC, b_id DESC",
searchColumns: ["b_id", "b_container_no", "b_inputdatetime"],
});
if (!dataRes.success || !dataRes.data.length) {
ElMessage.warning("无有效数据");
return;
}
const records = dataRes.data;
const zip = new JSZip();
let finished = 0;
const allTasks = [];
records.forEach((item) => {
const ymdFolderName = formatToDate(item.b_inputdatetime, "YYYY/MM/DD");
const containerFolderName = item.b_container_no;
const folderPromise = loadDataApi("bf_file", `father='${item.b_id}'`, "mx_xh asc");
allTasks.push(async () => {
const fileRes = await folderPromise;
if (!fileRes.success) {
console.error("获取附件失败:", item.b_container_no);
return;
}
const folder = zip.folder(ymdFolderName)?.folder(containerFolderName) || zip.folder(containerFolderName);
const files = fileRes.data || [];
const fileTasks = files.map((file, idx) => async () => {
try {
const blob = await getAliyunFileBlob(file.mx_mapfilename);
const fileName = buildFileName(item.b_container_no, idx + 1, file.mx_filename) || "未命名文件";
folder.file(fileName, blob);
} catch (e) {
console.error(item.b_container_no + "下载失败:", file.mx_mapfilename, e);
} finally {
finished++;
loading.setText(`正在下载 ${finished} / ${records.length} 个文件...`);
}
});
await runWithLimit(fileTasks, 3);
});
});
await runWithLimit(allTasks, 3);
loading.setText("正在生成压缩包...");
const content = await zip.generateAsync({ type: "blob" });
saveAs(content, buildZipName("SLICE"));
ElMessage.success("下载完成");
} catch (e) {
console.error(e);
ElMessage.error("下载失败");
} finally {
loading.close();
}
}
// 分页拆分导出
async function downloadChunk() {
const loading = ElLoading.service({
lock: true,
text: "正在下载并打包文件,请稍候...",
});
try {
const records = await fetchDatas();
if (!records?.length) {
ElMessage.warning("无有效数据");
return;
}
const zip = new JSZip();
const pageSize = chunkModeForm.value.pageSize || 10;
const totalPages = Math.ceil(records.length / pageSize);
let finished = 0;
const allPageTasks = [];
for (let pageIndex = 0; pageIndex < totalPages; pageIndex++) {
const startIndex = pageIndex * pageSize;
const endIndex = Math.min((pageIndex + 1) * pageSize, records.length);
const pageRecords = records.slice(startIndex, endIndex);
const pageFolderName = `${startIndex + 1}-${endIndex}`;
const pageFolder = zip.folder(pageFolderName);
pageRecords.forEach((item) => {
allPageTasks.push(async () => {
const fileRes = await loadDataApi("bf_file", `father='${item.b_id}'`, "mx_xh asc");
if (!fileRes.success) {
console.error("获取附件失败:", item.b_container_no);
return;
}
const ymdFolderName = formatToDate(item.b_inputdatetime, "YYYY/MM/DD");
const containerFolderName = item.b_container_no;
const folder = pageFolder.folder(ymdFolderName)?.folder(containerFolderName) || pageFolder.folder(containerFolderName);
const files = fileRes.data || [];
const fileTasks = files.map((file, idx) => async () => {
try {
const blob = await getAliyunFileBlob(file.mx_mapfilename);
const fileName = buildFileName(item.b_container_no, idx + 1, file.mx_filename) || "未命名文件";
folder.file(fileName, blob);
} catch (e) {
console.error(item.b_container_no + "下载失败:", file.mx_mapfilename, e);
} finally {
finished++;
loading.setText(`正在下载 ${finished} 个文件...`);
}
});
await runWithLimit(fileTasks, 3);
});
});
}
await runWithLimit(allPageTasks, 3);
loading.setText("正在生成压缩包...");
const content = await zip.generateAsync({ type: "blob" });
saveAs(content, buildZipName("CHUNK"));
ElMessage.success("下载完成");
} catch (e) {
console.error(e);
ElMessage.error("下载失败");
} finally {
loading.close();
}
}
function buildFileName(containerNo, index, fileName) {
const formattedIndex = String(index).padStart(2, "0");
return `${containerNo}_${formattedIndex}.${fileName.split(".").pop()}`;
}
function buildZipName(mode) {
const dateStr = new Date().toISOString().slice(0, 10).replace(/-/g, "");
switch (mode) {
case "ALL":
return `全部下载_${dateStr}.zip`;
case "SLICE":
return `下载第${sliceModeForm.value.startPage}-${sliceModeForm.value.endPage}条_${dateStr}.zip`;
case "CHUNK":
return `分页下载_每${chunkModeForm.value.pageSize}条_${dateStr}.zip`;
default:
return `下载数据_${dateStr}.zip`;
}
}
</script>
@@ -137,7 +423,7 @@ function handleExport() {
<div class="total">
共
<span class="num" v-loading="loadingTotal">
{{ total }}
{{ allTotal }}
</span>
条数据
</div>
@@ -195,9 +481,9 @@ function handleExport() {
<div class="label">模式</div>
<div class="content">
<el-radio-group v-model="searchForm.mode">
<el-radio label="ALL">全部导出</el-radio>
<el-radio label="SLICE">按页区间导出</el-radio>
<el-radio label="CHUNK">分页拆分导出</el-radio>
<el-radio value="ALL">全部导出</el-radio>
<el-radio value="SLICE">按区间导出</el-radio>
<el-radio value="CHUNK">分页拆分导出</el-radio>
</el-radio-group>
</div>
@@ -205,16 +491,16 @@ function handleExport() {
v-if="searchForm.mode === 'SLICE'"
style="margin-top: 8px; display: flex; align-items: center"
>
<el-input placeholder="起始页" />
<el-input placeholder="起始页" v-model="sliceModeForm.startPage" />
<el-divider direction="vertical" />
<el-input placeholder="终止页" />
<el-input placeholder="终止页" v-model="sliceModeForm.endPage" />
</div>
<div
v-if="searchForm.mode === 'CHUNK'"
style="margin-top: 8px; display: flex; align-items: center"
>
<el-input placeholder="分页大小" />
<el-input placeholder="分页大小" v-model="chunkModeForm.pageSize" />
</div>
</div>
</div>
@@ -226,7 +512,7 @@ function handleExport() {
</el-icon>
重置
</el-button>
<el-button type="primary">
<el-button type="primary" @click="handleDownload">
<el-icon class="el-icon--left">
<G3Icon icon="lucide:cloud-download" />
</el-icon>
@@ -17,6 +17,8 @@ import { usePermissionStore } from "@/store/permission";
import { ExportVxeTableExcel, exportExcel } from "@/utils/excel";
import HighDownloadDialog from "./high-download-dialog.vue";
const viewName = "v_container";
const tableRef = ref();
const permissionStore = usePermissionStore();
@@ -55,14 +57,10 @@ const fileCategories = [
},
];
const viewName = "v_container";
const showPreview = ref(false);
const previewIndex = ref(-1);
const previewImageList = computed(() => {
return tableData.value
.map((item) => item.b_container_img)
.filter((img) => img);
return tableData.value.map((item) => item.b_container_img).filter((img) => img);
});
const currentRow = ref({});
@@ -195,12 +193,9 @@ async function deleteRows(rows = []) {
const safeDeleteIds = deleteIds.map((id) => Number(id));
// 使用安全的 SQL 查询
const fileRes = await loadDataApi(
"bf_file",
`father IN (${safeDeleteIds.join(",")})`,
"",
["subid"],
);
const fileRes = await loadDataApi("bf_file", `father IN (${safeDeleteIds.join(",")})`, "", [
"subid",
]);
if (!fileRes.success) {
return;
@@ -276,11 +271,7 @@ async function handleDownloadOne(data) {
});
try {
const fileRes = await loadDataApi(
"bf_file",
`father = ${data.b_id}`,
"mx_xh asc",
);
const fileRes = await loadDataApi("bf_file", `father = ${data.b_id}`, "mx_xh asc");
if (!fileRes.success) {
ElMessage.error("获取附件失败");
@@ -288,11 +279,7 @@ async function handleDownloadOne(data) {
}
const downloadFiles = fileRes.data.map((item, index) => ({
mx_filename: buildFileName(
data.b_container_no,
index + 1,
item.mx_filename,
),
mx_filename: buildFileName(data.b_container_no, index + 1, item.mx_filename),
mx_mapfilename: item.mx_mapfilename,
}));
@@ -347,73 +334,54 @@ async function handleDownloadBatch() {
text: "正在下载并打包文件,请稍候...",
});
const zip = new JSZip();
try {
let total = 0;
const zip = new JSZip();
let finished = 0;
let totalFiles = 0;
// 1. 收集所有下载任务
const allTasks = [];
for (const item of records) {
const fileRes = await loadDataApi(
"bf_file",
`father = '${item.b_id}'`,
"",
);
if (fileRes.success) {
total += (fileRes.data || []).length;
}
}
const fileRes = await loadDataApi("bf_file", `father='${item.b_id}'`, "mx_xh asc");
const files = (fileRes.success && fileRes.data) || [];
totalFiles += files.length;
for (const item of records) {
const folderName = `${item.b_container_no}_${formatToDate(item.b_inputdatetime)}`;
// 按 年/月/日/集装箱号 生成层级文件夹
const ymdFolderName = formatToDate(item.b_inputdatetime, "YYYY/MM/DD"); // 2026/03/27
const containerFolderName = item.b_container_no;
let folder = zip.folder(ymdFolderName);
folder = folder ? folder.folder(containerFolderName) : zip.folder(containerFolderName);
const folder = zip.folder(folderName);
const fileRes = await loadDataApi(
"bf_file",
`father = '${item.b_id}'`,
"mx_xh asc",
);
if (!fileRes.success) {
ElMessage.error("获取附件失败");
continue;
}
const files = fileRes.data || [];
const tasks = files.map((file, index) => async () => {
const fileUrl = file.mx_mapfilename;
try {
const blob = getAliyunFileBlob(fileUrl);
const fileName =
buildFileName(item.b_container_no, index + 1, file.mx_filename) ||
"未命名文件";
folder.file(fileName, blob);
} catch (e) {
ElMessage.error(item.b_container_no + "箱号部分图片下载失败");
console.error("下载失败:", fileUrl);
} finally {
finished++;
loading.setText(`正在下载 ${finished}/${total} 个文件...`);
}
files.forEach((file, idx) => {
allTasks.push(async () => {
try {
const blob = await getAliyunFileBlob(file.mx_mapfilename);
const fileName =
buildFileName(item.b_container_no, idx + 1, file.mx_filename) || "未命名文件";
folder.file(fileName, blob);
} catch (e) {
console.error(item.b_container_no + "下载失败:", file.mx_mapfilename, e);
} finally {
finished++;
loading.setText(`正在下载 ${finished}/${totalFiles} 个文件...`);
}
});
});
await runWithLimit(tasks, 3);
}
// 2. 并发执行下载任务,限制同时 3 个
await runWithLimit(allTasks, 3);
loading.setText("正在生成压缩包...");
const content = await zip.generateAsync({ type: "blob" });
saveAs(content, "批量下载.zip");
// 3. 保存压缩包
saveAs(content, "批量下载");
ElMessage.success("下载完成");
} catch (error) {
console.error(error);
ElMessage.error("打包失败");
} catch (e) {
console.error(e);
} finally {
loading.close();
}
@@ -424,109 +392,6 @@ function buildFileName(containerNo, index, fileName) {
return `${containerNo}_${formattedIndex}.${fileName.split(".").pop()}`;
}
function testExport() {
const options = {
columns: [
{
label: "基础信息",
field: "basicInfo",
width: 120,
children: [
{
label: "姓名",
field: "name",
width: 120,
},
{
label: "年龄",
field: "age",
width: 80,
},
{
label: "头像",
field: "avatar",
width: 100,
type: "image",
imageWidth: 80,
imageHeight: 80,
},
],
},
{
label: "联系方式",
field: "contactInfo",
width: 160,
children: [
{
label: "电话",
field: "phone",
width: 120,
},
{
label: "邮箱",
field: "email",
width: 200,
},
],
},
{
label: "其他信息",
field: "otherInfo",
width: 100,
children: [
{
label: "地址信息",
field: "address",
width: 150,
children: [
{ label: "省份", field: "province", width: 80 },
{ label: "城市", field: "city", width: 80 },
],
},
{ label: "备注", field: "remark", width: 200 },
],
},
],
data: [
{
name: "张三",
age: 25,
phone: "13800138000",
email: "zhangsan@example.com",
province: "浙江",
city: "杭州",
remark: "测试数据1",
avatar:
"data:image/png;base64,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 truncated
},
{
name: "李四",
age: 30,
phone: "13900139000",
email: "lisi@example.com",
province: "江苏",
city: "南京",
remark: "测试数据2",
avatar:
"data:image/png;base64,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 truncated
},
],
footer: [
{
name: "总计",
age: 55,
phone: "",
email: "",
province: "",
city: "",
remark: "2条记录",
},
],
};
exportExcel(options);
}
</script>
<template>
@@ -649,9 +514,6 @@ function testExport() {
<el-dropdown-item @click="ExportVxeTableExcel(tableRef)">
导出Execl
</el-dropdown-item>
<el-dropdown-item @click="ExportVxeTableExcel(tableRef)">
高级导出
</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
@@ -683,14 +545,7 @@ function testExport() {
show-overflow
show-header-overflow
>
<vxe-column
field="seq"
type="seq"
width="50"
align="center"
title=" "
fixed="left"
/>
<vxe-column field="seq" type="seq" width="50" align="center" title=" " fixed="left" />
<vxe-column type="checkbox" width="50" align="center" fixed="left" />
<vxe-column
v-for="column in columns"
@@ -711,12 +566,7 @@ function testExport() {
/>
</template>
<template v-else>
{{
formatValueByFormat(
row[column.col_FieldName],
column.col_DisplayFormat,
)
}}
{{ formatValueByFormat(row[column.col_FieldName], column.col_DisplayFormat) }}
</template>
</template>
</vxe-column>
@@ -0,0 +1,136 @@
<script lang="js" setup>
import QrcodeVue from "qrcode.vue";
import QRCode from "qrcode";
import { loadDataApi } from "@/request/api";
import { useUserStore } from "@/store/user";
const userStore = useUserStore();
// 用户二维码数据
const userData = ref([]);
// 主二维码链接
const mainUrl = "http://ser215.g3soft.cn:8088/g3ocr-app/#/pages-sub/upload/index";
// Element Plus 图片查看器控制
const showPreview = ref(false);
const previewIndex = ref(0);
const srcList = ref([]);
onMounted(() => {
// loadUserDatas();
});
async function loadUserDatas() {
const response = await loadDataApi("b_user", `b_id <> 'g3soft' AND b_canuse = '1'`, "", ["b_id"]);
if (response.success) {
response.data.forEach((item) => {
userData.value.push({
account: item.b_id,
url: `${mainUrl}?orgid=${encodeURIComponent(userStore.userInfo.orgid)}&bid=${encodeURIComponent(item.b_id)}`,
});
});
}
}
// 生成 base64
async function generateQrBase64(urls) {
srcList.value = [];
for (const item of urls) {
const dataUrl = await QRCode.toDataURL(item, { width: 400 });
srcList.value.push(dataUrl);
}
}
// 打开预览
async function openPreview(index) {
const urls = [mainUrl, ...userData.value.map((u) => u.url)];
await generateQrBase64(urls);
previewIndex.value = index;
showPreview.value = true;
}
</script>
<template>
<div class="page-container">
<!-- 主二维码 -->
<div class="qr-section main-qr">
<h2>统一入口</h2>
<qrcode-vue :value="mainUrl" :size="220" :margin="2" @click.native="openPreview(0)" />
</div>
<el-divider />
<!-- 用户二维码 -->
<!-- <div class="qr-section user-qr">
<h2>用户二维码(免登录,需要启用该账户!)</h2>
<div class="user-qr-list">
<div v-for="(user, index) in userData" :key="index" class="user-qr-item">
<div class="account-name">{{ user.account }}</div>
<qrcode-vue
:value="user.url"
:size="200"
@click.native="openPreview(index + 1)"
:margin="2"
/>
</div>
</div>
</div> -->
<!-- Element Plus 图片查看器 -->
<el-image-viewer
v-if="showPreview"
:url-list="srcList"
:initial-index="previewIndex"
show-progress
@close="showPreview = false"
/>
</div>
</template>
<style scoped lang="scss">
@use "@/styles/mixins.scss" as *;
.page-container {
display: flex;
flex-direction: column;
align-items: center;
height: 100%;
overflow-y: auto;
}
.qr-section {
display: flex;
flex-direction: column;
align-items: center;
width: 100%;
margin-top: 16px;
}
.user-qr {
margin-top: 16px;
}
.qr-section h2 {
margin-bottom: 12px;
font-size: 18px;
font-weight: 600;
}
.user-qr-list {
@include flexGapWrap(10px, 36px);
}
.user-qr-item {
display: flex;
flex-direction: column;
align-items: center;
cursor: pointer;
}
.account-name {
margin-bottom: 6px;
font-size: 14px;
font-weight: 500;
color: #333;
}
</style>
@@ -75,6 +75,18 @@ async function loadTableDatas() {
searchCondition += `b_inputdatetime <= '${searchForm.value.endTime}' AND `;
}
if (searchForm.value.datas) {
searchCondition += `b_datas LIKE '${searchForm.value.datas}' AND `;
}
if (searchForm.value.option) {
searchCondition += `b_option LIKE '${searchForm.value.option}' AND `;
}
if (searchForm.value.table) {
searchCondition += `b_table LIKE '${searchForm.value.table}' AND `;
}
if (searchCondition.endsWith(" AND ")) {
searchCondition = searchCondition.slice(0, -4);
}
@@ -163,16 +175,16 @@ function handleSearchReset() {
</G3Grid>
<div class="search-extra">
<el-button type="primary">
<el-button type="primary" @click="handleSearch">
<el-icon class="el-icon--left">
<G3Icon icon="lucide:search" @click="handleSearch" />
<G3Icon icon="lucide:search" />
</el-icon>
搜索
</el-button>
<el-button>
<el-button @click="handleSearchReset">
<el-icon class="el-icon--left">
<G3Icon icon="lucide:refresh-ccw" @click="handleSearchReset" />
<G3Icon icon="lucide:refresh-ccw" />
</el-icon>
重置
</el-button>
File diff suppressed because it is too large. Load diff