f
This commit is contained in:
@@ -12,6 +12,8 @@
|
||||
"@vueuse/core": "^11.3.0",
|
||||
"axios": "^1.7.7",
|
||||
"echarts": "^5.5.1",
|
||||
"html2canvas": "^1.4.1",
|
||||
"jspdf": "^4.2.1",
|
||||
"lodash": "^4.17.21",
|
||||
"vant": "^4.9.9",
|
||||
"vue": "^3.5.12",
|
||||
|
||||
199
pnpm-lock.yaml
generated
199
pnpm-lock.yaml
generated
@@ -17,6 +17,12 @@ importers:
|
||||
echarts:
|
||||
specifier: ^5.5.1
|
||||
version: 5.6.0
|
||||
html2canvas:
|
||||
specifier: ^1.4.1
|
||||
version: 1.4.1
|
||||
jspdf:
|
||||
specifier: ^4.2.1
|
||||
version: 4.2.1
|
||||
lodash:
|
||||
specifier: ^4.17.21
|
||||
version: 4.17.21
|
||||
@@ -181,6 +187,10 @@ packages:
|
||||
peerDependencies:
|
||||
'@babel/core': ^7.0.0-0
|
||||
|
||||
'@babel/runtime@7.29.7':
|
||||
resolution: {integrity: sha512-Nq8OhGWiZIZGV6hLHoyAKLLcJihP/xFeBMGJoUrxTX2psI8dCifzLhZISFb+VWS3wFMRDmCGw5R+dOySCqPLhw==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
|
||||
'@babel/template@7.27.2':
|
||||
resolution: {integrity: sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
@@ -398,42 +408,36 @@ packages:
|
||||
engines: {node: '>= 10.0.0'}
|
||||
cpu: [arm]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@parcel/watcher-linux-arm-musl@2.5.1':
|
||||
resolution: {integrity: sha512-6E+m/Mm1t1yhB8X412stiKFG3XykmgdIOqhjWj+VL8oHkKABfu/gjFj8DvLrYVHSBNC+/u5PeNrujiSQ1zwd1Q==}
|
||||
engines: {node: '>= 10.0.0'}
|
||||
cpu: [arm]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@parcel/watcher-linux-arm64-glibc@2.5.1':
|
||||
resolution: {integrity: sha512-LrGp+f02yU3BN9A+DGuY3v3bmnFUggAITBGriZHUREfNEzZh/GO06FF5u2kx8x+GBEUYfyTGamol4j3m9ANe8w==}
|
||||
engines: {node: '>= 10.0.0'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@parcel/watcher-linux-arm64-musl@2.5.1':
|
||||
resolution: {integrity: sha512-cFOjABi92pMYRXS7AcQv9/M1YuKRw8SZniCDw0ssQb/noPkRzA+HBDkwmyOJYp5wXcsTrhxO0zq1U11cK9jsFg==}
|
||||
engines: {node: '>= 10.0.0'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@parcel/watcher-linux-x64-glibc@2.5.1':
|
||||
resolution: {integrity: sha512-GcESn8NZySmfwlTsIur+49yDqSny2IhPeZfXunQi48DMugKeZ7uy1FX83pO0X22sHntJ4Ub+9k34XQCX+oHt2A==}
|
||||
engines: {node: '>= 10.0.0'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@parcel/watcher-linux-x64-musl@2.5.1':
|
||||
resolution: {integrity: sha512-n0E2EQbatQ3bXhcH2D1XIAANAcTZkQICBPVaxMeaCVBtOpBZpWJuf7LwyWPSBDITb7In8mqQgJ7gH8CILCURXg==}
|
||||
engines: {node: '>= 10.0.0'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@parcel/watcher-win32-arm64@2.5.1':
|
||||
resolution: {integrity: sha512-RFzklRvmc3PkjKjry3hLF9wD7ppR4AKcWNzH7kXR7GUe0Igb3Nz8fyPwtZCSquGrhU5HhUNDr/mKBqj7tqA2Vw==}
|
||||
@@ -507,67 +511,56 @@ packages:
|
||||
resolution: {integrity: sha512-EPlb95nUsz6Dd9Qy13fI5kUPXNSljaG9FiJ4YUGU1O/Q77i5DYFW5KR8g1OzTcdZUqQQ1KdDqsTohdFVwCwjqg==}
|
||||
cpu: [arm]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@rollup/rollup-linux-arm-musleabihf@4.53.2':
|
||||
resolution: {integrity: sha512-BOmnVW+khAUX+YZvNfa0tGTEMVVEerOxN0pDk2E6N6DsEIa2Ctj48FOMfNDdrwinocKaC7YXUZ1pHlKpnkja/Q==}
|
||||
cpu: [arm]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@rollup/rollup-linux-arm64-gnu@4.53.2':
|
||||
resolution: {integrity: sha512-Xt2byDZ+6OVNuREgBXr4+CZDJtrVso5woFtpKdGPhpTPHcNG7D8YXeQzpNbFRxzTVqJf7kvPMCub/pcGUWgBjA==}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@rollup/rollup-linux-arm64-musl@4.53.2':
|
||||
resolution: {integrity: sha512-+LdZSldy/I9N8+klim/Y1HsKbJ3BbInHav5qE9Iy77dtHC/pibw1SR/fXlWyAk0ThnpRKoODwnAuSjqxFRDHUQ==}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@rollup/rollup-linux-loong64-gnu@4.53.2':
|
||||
resolution: {integrity: sha512-8ms8sjmyc1jWJS6WdNSA23rEfdjWB30LH8Wqj0Cqvv7qSHnvw6kgMMXRdop6hkmGPlyYBdRPkjJnj3KCUHV/uQ==}
|
||||
cpu: [loong64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@rollup/rollup-linux-ppc64-gnu@4.53.2':
|
||||
resolution: {integrity: sha512-3HRQLUQbpBDMmzoxPJYd3W6vrVHOo2cVW8RUo87Xz0JPJcBLBr5kZ1pGcQAhdZgX9VV7NbGNipah1omKKe23/g==}
|
||||
cpu: [ppc64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@rollup/rollup-linux-riscv64-gnu@4.53.2':
|
||||
resolution: {integrity: sha512-fMjKi+ojnmIvhk34gZP94vjogXNNUKMEYs+EDaB/5TG/wUkoeua7p7VCHnE6T2Tx+iaghAqQX8teQzcvrYpaQA==}
|
||||
cpu: [riscv64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@rollup/rollup-linux-riscv64-musl@4.53.2':
|
||||
resolution: {integrity: sha512-XuGFGU+VwUUV5kLvoAdi0Wz5Xbh2SrjIxCtZj6Wq8MDp4bflb/+ThZsVxokM7n0pcbkEr2h5/pzqzDYI7cCgLQ==}
|
||||
cpu: [riscv64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@rollup/rollup-linux-s390x-gnu@4.53.2':
|
||||
resolution: {integrity: sha512-w6yjZF0P+NGzWR3AXWX9zc0DNEGdtvykB03uhonSHMRa+oWA6novflo2WaJr6JZakG2ucsyb+rvhrKac6NIy+w==}
|
||||
cpu: [s390x]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@rollup/rollup-linux-x64-gnu@4.53.2':
|
||||
resolution: {integrity: sha512-yo8d6tdfdeBArzC7T/PnHd7OypfI9cbuZzPnzLJIyKYFhAQ8SvlkKtKBMbXDxe1h03Rcr7u++nFS7tqXz87Gtw==}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@rollup/rollup-linux-x64-musl@4.53.2':
|
||||
resolution: {integrity: sha512-ah59c1YkCxKExPP8O9PwOvs+XRLKwh/mV+3YdKqQ5AMQ0r4M4ZDuOrpWkUaqO7fzAHdINzV9tEVu8vNw48z0lA==}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@rollup/rollup-openharmony-arm64@4.53.2':
|
||||
resolution: {integrity: sha512-4VEd19Wmhr+Zy7hbUsFZ6YXEiP48hE//KPLCSVNY5RMGX2/7HZ+QkN55a3atM1C/BZCGIgqN+xrVgtdak2S9+A==}
|
||||
@@ -597,6 +590,15 @@ packages:
|
||||
'@types/estree@1.0.8':
|
||||
resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==}
|
||||
|
||||
'@types/pako@2.0.4':
|
||||
resolution: {integrity: sha512-VWDCbrLeVXJM9fihYodcLiIv0ku+AlOa/TQ1SvYOaBuyrSKgEcro95LJyIsJ4vSo6BXIxOKxiJAat04CmST9Fw==}
|
||||
|
||||
'@types/raf@3.4.3':
|
||||
resolution: {integrity: sha512-c4YAvMedbPZ5tEyxzQdMoOhhJ4RD3rngZIdwC2/qDN3d7JpEhB6fiBRKVY1lg5B7Wk+uPBjn5f39j1/2MY1oOw==}
|
||||
|
||||
'@types/trusted-types@2.0.7':
|
||||
resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==}
|
||||
|
||||
'@types/web-bluetooth@0.0.20':
|
||||
resolution: {integrity: sha512-g9gZnnXVq7gM7v3tJCWV/qw7w+KeOlSHAhgF9RytFyifW6AF61hdT2ucrYhPq9hLs5JIryeupHV3qGk95dH9ow==}
|
||||
|
||||
@@ -729,6 +731,10 @@ packages:
|
||||
balanced-match@1.0.2:
|
||||
resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
|
||||
|
||||
base64-arraybuffer@1.0.2:
|
||||
resolution: {integrity: sha512-I3yl4r9QB5ZRY3XuJVEPfc2XhZO6YweFPI+UovAzn+8/hb3oJ6lnysaFcjVpkCPfVWFUDvoZ8kmVDP7WyRtYtQ==}
|
||||
engines: {node: '>= 0.6.0'}
|
||||
|
||||
baseline-browser-mapping@2.8.29:
|
||||
resolution: {integrity: sha512-sXdt2elaVnhpDNRDz+1BDx1JQoJRuNk7oVlAlbGiFkLikHCAQiccexF/9e91zVi6RCgqspl04aP+6Cnl9zRLrA==}
|
||||
hasBin: true
|
||||
@@ -766,6 +772,10 @@ packages:
|
||||
caniuse-lite@1.0.30001756:
|
||||
resolution: {integrity: sha512-4HnCNKbMLkLdhJz3TToeVWHSnfJvPaq6vu/eRP0Ahub/07n484XHhBF5AJoSGHdVrS8tKFauUQz8Bp9P7LVx7A==}
|
||||
|
||||
canvg@3.0.11:
|
||||
resolution: {integrity: sha512-5ON+q7jCTgMp9cjpu4Jo6XbvfYwSB2Ow3kzHKfIyJfaCAOHLbdKPQqGKgfED/R5B+3TFFfe8pegYA+b423SRyA==}
|
||||
engines: {node: '>=10.0.0'}
|
||||
|
||||
chokidar@3.6.0:
|
||||
resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==}
|
||||
engines: {node: '>= 8.10.0'}
|
||||
@@ -804,10 +814,16 @@ packages:
|
||||
convert-source-map@2.0.0:
|
||||
resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==}
|
||||
|
||||
core-js@3.49.0:
|
||||
resolution: {integrity: sha512-es1U2+YTtzpwkxVLwAFdSpaIMyQaq0PBgm3YD1W3Qpsn1NAmO3KSgZfu+oGSWVu6NvLHoHCV/aYcsE5wiB7ALg==}
|
||||
|
||||
cross-spawn@7.0.6:
|
||||
resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==}
|
||||
engines: {node: '>= 8'}
|
||||
|
||||
css-line-break@2.1.0:
|
||||
resolution: {integrity: sha512-FHcKFCZcAha3LwfVBhCQbW2nCNbkZXn7KVUJcsT5/P8YmfsVja0FMPJr0B903j/E69HUphKiV9iQArX8SDYA4w==}
|
||||
|
||||
cssesc@3.0.0:
|
||||
resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==}
|
||||
engines: {node: '>=4'}
|
||||
@@ -840,6 +856,9 @@ packages:
|
||||
dlv@1.1.3:
|
||||
resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==}
|
||||
|
||||
dompurify@3.4.11:
|
||||
resolution: {integrity: sha512-zhlUV12GsaRzMsf9q5M254YhA4+VuF0fG+QFqu6aYpoGlKtz+w8//jBcGVYBgQkR5GHjUomejY84AV+/uPbWdw==}
|
||||
|
||||
dunder-proto@1.0.1:
|
||||
resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==}
|
||||
engines: {node: '>= 0.4'}
|
||||
@@ -905,9 +924,15 @@ packages:
|
||||
resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==}
|
||||
engines: {node: '>=8.6.0'}
|
||||
|
||||
fast-png@6.4.0:
|
||||
resolution: {integrity: sha512-kAqZq1TlgBjZcLr5mcN6NP5Rv4V2f22z00c3g8vRrwkcqjerx7BEhPbOnWCPqaHUl2XWQBJQvOT/FQhdMT7X/Q==}
|
||||
|
||||
fastq@1.19.1:
|
||||
resolution: {integrity: sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==}
|
||||
|
||||
fflate@0.8.3:
|
||||
resolution: {integrity: sha512-tbZNuJrLwGUp3zshBtdy4W+ORxZuIh8a5ilyIEQDC5rY1f3U20JMry0Ll3WBzU58EZKsEuJFXhb5gwv8CsPvgA==}
|
||||
|
||||
fill-range@7.1.1:
|
||||
resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==}
|
||||
engines: {node: '>=8'}
|
||||
@@ -984,9 +1009,16 @@ packages:
|
||||
resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
html2canvas@1.4.1:
|
||||
resolution: {integrity: sha512-fPU6BHNpsyIhr8yyMpTLLxAbkaK8ArIBcmZIRiBLiDhjeqvXolaEmDGmELFuX9I4xDcaKKcJl+TKZLqruBbmWA==}
|
||||
engines: {node: '>=8.0.0'}
|
||||
|
||||
immutable@5.1.4:
|
||||
resolution: {integrity: sha512-p6u1bG3YSnINT5RQmx/yRZBpenIl30kVxkTLDyHLIMk0gict704Q9n+thfDI7lTRm9vXdDYutVzXhzcThxTnXA==}
|
||||
|
||||
iobuffer@5.4.0:
|
||||
resolution: {integrity: sha512-DRebOWuqDvxunfkNJAlc3IzWIPD5xVxwUNbHr7xKB8E6aLJxIPfNX3CoMJghcFjpv6RWQsrcJbghtEwSPoJqMA==}
|
||||
|
||||
is-binary-path@2.1.0:
|
||||
resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==}
|
||||
engines: {node: '>=8'}
|
||||
@@ -1037,6 +1069,9 @@ packages:
|
||||
engines: {node: '>=6'}
|
||||
hasBin: true
|
||||
|
||||
jspdf@4.2.1:
|
||||
resolution: {integrity: sha512-YyAXyvnmjTbR4bHQRLzex3CuINCDlQnBqoSYyjJwTP2x9jDLuKDzy7aKUl0hgx3uhcl7xzg32agn5vlie6HIlQ==}
|
||||
|
||||
lilconfig@3.1.3:
|
||||
resolution: {integrity: sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==}
|
||||
engines: {node: '>=14'}
|
||||
@@ -1131,6 +1166,9 @@ packages:
|
||||
package-json-from-dist@1.0.1:
|
||||
resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==}
|
||||
|
||||
pako@2.1.0:
|
||||
resolution: {integrity: sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug==}
|
||||
|
||||
path-key@3.1.1:
|
||||
resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==}
|
||||
engines: {node: '>=8'}
|
||||
@@ -1145,6 +1183,9 @@ packages:
|
||||
pathe@2.0.3:
|
||||
resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==}
|
||||
|
||||
performance-now@2.1.0:
|
||||
resolution: {integrity: sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==}
|
||||
|
||||
picocolors@1.1.1:
|
||||
resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==}
|
||||
|
||||
@@ -1226,6 +1267,9 @@ packages:
|
||||
queue-microtask@1.2.3:
|
||||
resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
|
||||
|
||||
raf@3.4.1:
|
||||
resolution: {integrity: sha512-Sq4CW4QhwOHE8ucn6J34MqtZCeWFP2aQSmrlroYgqAV1PjStIhJXxYuTgUIfkEk7zTLjmIjLmU5q+fbD1NnOJA==}
|
||||
|
||||
read-cache@1.0.0:
|
||||
resolution: {integrity: sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==}
|
||||
|
||||
@@ -1237,6 +1281,9 @@ packages:
|
||||
resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==}
|
||||
engines: {node: '>= 14.18.0'}
|
||||
|
||||
regenerator-runtime@0.13.11:
|
||||
resolution: {integrity: sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==}
|
||||
|
||||
resolve@1.22.11:
|
||||
resolution: {integrity: sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==}
|
||||
engines: {node: '>= 0.4'}
|
||||
@@ -1246,6 +1293,10 @@ packages:
|
||||
resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==}
|
||||
engines: {iojs: '>=1.0.0', node: '>=0.10.0'}
|
||||
|
||||
rgbcolor@1.0.1:
|
||||
resolution: {integrity: sha512-9aZLIrhRaD97sgVhtJOW6ckOEh6/GnvQtdVNfdZ6s67+3/XwLS9lBcQYzEEhYVeUowN7pRzMLsyGhK2i/xvWbw==}
|
||||
engines: {node: '>= 0.8.15'}
|
||||
|
||||
rollup@4.53.2:
|
||||
resolution: {integrity: sha512-MHngMYwGJVi6Fmnk6ISmnk7JAHRNF0UkuucA0CUW3N3a4KnONPEZz+vUanQP/ZC/iY1Qkf3bwPWzyY84wEks1g==}
|
||||
engines: {node: '>=18.0.0', npm: '>=8.0.0'}
|
||||
@@ -1302,56 +1353,48 @@ packages:
|
||||
engines: {node: '>=14.0.0'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: glibc
|
||||
|
||||
sass-embedded-linux-arm@1.93.3:
|
||||
resolution: {integrity: sha512-yeiv2y+dp8B4wNpd3+JsHYD0mvpXSfov7IGyQ1tMIR40qv+ROkRqYiqQvAOXf76Qwh4Y9OaYZtLpnsPjfeq6mA==}
|
||||
engines: {node: '>=14.0.0'}
|
||||
cpu: [arm]
|
||||
os: [linux]
|
||||
libc: glibc
|
||||
|
||||
sass-embedded-linux-musl-arm64@1.93.3:
|
||||
resolution: {integrity: sha512-PS829l+eUng+9W4PFclXGb4uA2+965NHV3/Sa5U7qTywjeeUUYTZg70dJHSqvhrBEfCc2XJABeW3adLJbyQYkw==}
|
||||
engines: {node: '>=14.0.0'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: musl
|
||||
|
||||
sass-embedded-linux-musl-arm@1.93.3:
|
||||
resolution: {integrity: sha512-fU0fwAwbp7sBE3h5DVU5UPzvaLg7a4yONfFWkkcCp6ZrOiPuGRHXXYriWQ0TUnWy4wE+svsVuWhwWgvlb/tkKg==}
|
||||
engines: {node: '>=14.0.0'}
|
||||
cpu: [arm]
|
||||
os: [linux]
|
||||
libc: musl
|
||||
|
||||
sass-embedded-linux-musl-riscv64@1.93.3:
|
||||
resolution: {integrity: sha512-cK1oBY+FWQquaIGEeQ5H74KTO8cWsSWwXb/WaildOO9U6wmUypTgUYKQ0o5o/29nZbWWlM1PHuwVYTSnT23Jjg==}
|
||||
engines: {node: '>=14.0.0'}
|
||||
cpu: [riscv64]
|
||||
os: [linux]
|
||||
libc: musl
|
||||
|
||||
sass-embedded-linux-musl-x64@1.93.3:
|
||||
resolution: {integrity: sha512-A7wkrsHu2/I4Zpa0NMuPGkWDVV7QGGytxGyUq3opSXgAexHo/vBPlGoDXoRlSdex0cV+aTMRPjoGIfdmNlHwyg==}
|
||||
engines: {node: '>=14.0.0'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: musl
|
||||
|
||||
sass-embedded-linux-riscv64@1.93.3:
|
||||
resolution: {integrity: sha512-vWkW1+HTF5qcaHa6hO80gx/QfB6GGjJUP0xLbnAoY4pwEnw5ulGv6RM8qYr8IDhWfVt/KH+lhJ2ZFxnJareisQ==}
|
||||
engines: {node: '>=14.0.0'}
|
||||
cpu: [riscv64]
|
||||
os: [linux]
|
||||
libc: glibc
|
||||
|
||||
sass-embedded-linux-x64@1.93.3:
|
||||
resolution: {integrity: sha512-k6uFxs+e5jSuk1Y0niCwuq42F9ZC5UEP7P+RIOurIm8w/5QFa0+YqeW+BPWEW5M1FqVOsNZH3qGn4ahqvAEjPA==}
|
||||
engines: {node: '>=14.0.0'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: glibc
|
||||
|
||||
sass-embedded-unknown-all@1.93.3:
|
||||
resolution: {integrity: sha512-o5wj2rLpXH0C+GJKt/VpWp6AnMsCCbfFmnMAttcrsa+U3yrs/guhZ3x55KAqqUsE8F47e3frbsDL+1OuQM5DAA==}
|
||||
@@ -1409,6 +1452,10 @@ packages:
|
||||
resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
stackblur-canvas@2.7.0:
|
||||
resolution: {integrity: sha512-yf7OENo23AGJhBriGx0QivY5JP6Y1HbrrDI6WLt6C5auYZXlQrheoY8hD4ibekFKz1HOfE48Ww8kMWMnJD/zcQ==}
|
||||
engines: {node: '>=0.1.14'}
|
||||
|
||||
string-width@4.2.3:
|
||||
resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==}
|
||||
engines: {node: '>=8'}
|
||||
@@ -1441,6 +1488,10 @@ packages:
|
||||
resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
svg-pathdata@6.0.3:
|
||||
resolution: {integrity: sha512-qsjeeq5YjBZ5eMdFuUa4ZosMLxgr5RZ+F+Y1OrDhuOCEInRMA3x74XdBtggJcj9kOeInz0WE+LgCPDkZFlBYJw==}
|
||||
engines: {node: '>=12.0.0'}
|
||||
|
||||
sync-child-process@1.0.2:
|
||||
resolution: {integrity: sha512-8lD+t2KrrScJ/7KXCSyfhT3/hRq78rC0wBFqNJXv3mZyn6hW2ypM05JmlSvtqRbeq6jqA94oHbxAr2vYsJ8vDA==}
|
||||
engines: {node: '>=16.0.0'}
|
||||
@@ -1459,6 +1510,9 @@ packages:
|
||||
engines: {node: '>=10'}
|
||||
hasBin: true
|
||||
|
||||
text-segmentation@1.0.3:
|
||||
resolution: {integrity: sha512-iOiPUo/BGnZ6+54OsWxZidGCsdU8YbE4PSpdPinp7DeMtUJNJBoJ/ouUSTJjHkh1KntHaltHl/gDs2FC4i5+Nw==}
|
||||
|
||||
thenify-all@1.6.0:
|
||||
resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==}
|
||||
engines: {node: '>=0.8'}
|
||||
@@ -1523,6 +1577,9 @@ packages:
|
||||
util-deprecate@1.0.2:
|
||||
resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
|
||||
|
||||
utrie@1.0.2:
|
||||
resolution: {integrity: sha512-1MLa5ouZiOmQzUbjbu9VmjLzn1QLXBhwpUa7kdLUQK+KQ5KA9I1vk5U4YHe/X2Ch7PYnJfWuWT+VbuxbGwljhw==}
|
||||
|
||||
vant@4.9.21:
|
||||
resolution: {integrity: sha512-hXUoZMrLLjykimFRLDlGNd+K2iYSRh9YwLMKnsVdVZ+9inUKxpqnjhOqlZwocbnYkvJlS+febf9u9aJpDol4Pw==}
|
||||
peerDependencies:
|
||||
@@ -1779,6 +1836,8 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@babel/runtime@7.29.7': {}
|
||||
|
||||
'@babel/template@7.27.2':
|
||||
dependencies:
|
||||
'@babel/code-frame': 7.27.1
|
||||
@@ -2060,6 +2119,14 @@ snapshots:
|
||||
|
||||
'@types/estree@1.0.8': {}
|
||||
|
||||
'@types/pako@2.0.4': {}
|
||||
|
||||
'@types/raf@3.4.3':
|
||||
optional: true
|
||||
|
||||
'@types/trusted-types@2.0.7':
|
||||
optional: true
|
||||
|
||||
'@types/web-bluetooth@0.0.20': {}
|
||||
|
||||
'@vant/auto-import-resolver@1.3.0': {}
|
||||
@@ -2233,6 +2300,8 @@ snapshots:
|
||||
|
||||
balanced-match@1.0.2: {}
|
||||
|
||||
base64-arraybuffer@1.0.2: {}
|
||||
|
||||
baseline-browser-mapping@2.8.29: {}
|
||||
|
||||
binary-extensions@2.3.0: {}
|
||||
@@ -2266,6 +2335,18 @@ snapshots:
|
||||
|
||||
caniuse-lite@1.0.30001756: {}
|
||||
|
||||
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.7.0
|
||||
svg-pathdata: 6.0.3
|
||||
optional: true
|
||||
|
||||
chokidar@3.6.0:
|
||||
dependencies:
|
||||
anymatch: 3.1.3
|
||||
@@ -2305,12 +2386,19 @@ snapshots:
|
||||
|
||||
convert-source-map@2.0.0: {}
|
||||
|
||||
core-js@3.49.0:
|
||||
optional: true
|
||||
|
||||
cross-spawn@7.0.6:
|
||||
dependencies:
|
||||
path-key: 3.1.1
|
||||
shebang-command: 2.0.0
|
||||
which: 2.0.2
|
||||
|
||||
css-line-break@2.1.0:
|
||||
dependencies:
|
||||
utrie: 1.0.2
|
||||
|
||||
cssesc@3.0.0: {}
|
||||
|
||||
csstype@3.2.3: {}
|
||||
@@ -2328,6 +2416,11 @@ snapshots:
|
||||
|
||||
dlv@1.1.3: {}
|
||||
|
||||
dompurify@3.4.11:
|
||||
optionalDependencies:
|
||||
'@types/trusted-types': 2.0.7
|
||||
optional: true
|
||||
|
||||
dunder-proto@1.0.1:
|
||||
dependencies:
|
||||
call-bind-apply-helpers: 1.0.2
|
||||
@@ -2410,10 +2503,18 @@ snapshots:
|
||||
merge2: 1.4.1
|
||||
micromatch: 4.0.8
|
||||
|
||||
fast-png@6.4.0:
|
||||
dependencies:
|
||||
'@types/pako': 2.0.4
|
||||
iobuffer: 5.4.0
|
||||
pako: 2.1.0
|
||||
|
||||
fastq@1.19.1:
|
||||
dependencies:
|
||||
reusify: 1.1.0
|
||||
|
||||
fflate@0.8.3: {}
|
||||
|
||||
fill-range@7.1.1:
|
||||
dependencies:
|
||||
to-regex-range: 5.0.1
|
||||
@@ -2491,8 +2592,15 @@ snapshots:
|
||||
dependencies:
|
||||
function-bind: 1.1.2
|
||||
|
||||
html2canvas@1.4.1:
|
||||
dependencies:
|
||||
css-line-break: 2.1.0
|
||||
text-segmentation: 1.0.3
|
||||
|
||||
immutable@5.1.4: {}
|
||||
|
||||
iobuffer@5.4.0: {}
|
||||
|
||||
is-binary-path@2.1.0:
|
||||
dependencies:
|
||||
binary-extensions: 2.3.0
|
||||
@@ -2529,6 +2637,17 @@ snapshots:
|
||||
|
||||
json5@2.2.3: {}
|
||||
|
||||
jspdf@4.2.1:
|
||||
dependencies:
|
||||
'@babel/runtime': 7.29.7
|
||||
fast-png: 6.4.0
|
||||
fflate: 0.8.3
|
||||
optionalDependencies:
|
||||
canvg: 3.0.11
|
||||
core-js: 3.49.0
|
||||
dompurify: 3.4.11
|
||||
html2canvas: 1.4.1
|
||||
|
||||
lilconfig@3.1.3: {}
|
||||
|
||||
lines-and-columns@1.2.4: {}
|
||||
@@ -2609,6 +2728,8 @@ snapshots:
|
||||
|
||||
package-json-from-dist@1.0.1: {}
|
||||
|
||||
pako@2.1.0: {}
|
||||
|
||||
path-key@3.1.1: {}
|
||||
|
||||
path-parse@1.0.7: {}
|
||||
@@ -2620,6 +2741,9 @@ snapshots:
|
||||
|
||||
pathe@2.0.3: {}
|
||||
|
||||
performance-now@2.1.0:
|
||||
optional: true
|
||||
|
||||
picocolors@1.1.1: {}
|
||||
|
||||
picomatch@2.3.1: {}
|
||||
@@ -2685,6 +2809,11 @@ snapshots:
|
||||
|
||||
queue-microtask@1.2.3: {}
|
||||
|
||||
raf@3.4.1:
|
||||
dependencies:
|
||||
performance-now: 2.1.0
|
||||
optional: true
|
||||
|
||||
read-cache@1.0.0:
|
||||
dependencies:
|
||||
pify: 2.3.0
|
||||
@@ -2696,6 +2825,9 @@ snapshots:
|
||||
readdirp@4.1.2:
|
||||
optional: true
|
||||
|
||||
regenerator-runtime@0.13.11:
|
||||
optional: true
|
||||
|
||||
resolve@1.22.11:
|
||||
dependencies:
|
||||
is-core-module: 2.16.1
|
||||
@@ -2704,6 +2836,9 @@ snapshots:
|
||||
|
||||
reusify@1.1.0: {}
|
||||
|
||||
rgbcolor@1.0.1:
|
||||
optional: true
|
||||
|
||||
rollup@4.53.2:
|
||||
dependencies:
|
||||
'@types/estree': 1.0.8
|
||||
@@ -2858,6 +2993,9 @@ snapshots:
|
||||
|
||||
source-map@0.6.1: {}
|
||||
|
||||
stackblur-canvas@2.7.0:
|
||||
optional: true
|
||||
|
||||
string-width@4.2.3:
|
||||
dependencies:
|
||||
emoji-regex: 8.0.0
|
||||
@@ -2898,6 +3036,9 @@ snapshots:
|
||||
|
||||
supports-preserve-symlinks-flag@1.0.0: {}
|
||||
|
||||
svg-pathdata@6.0.3:
|
||||
optional: true
|
||||
|
||||
sync-child-process@1.0.2:
|
||||
dependencies:
|
||||
sync-message-port: 1.1.3
|
||||
@@ -2939,6 +3080,10 @@ snapshots:
|
||||
commander: 2.20.3
|
||||
source-map-support: 0.5.21
|
||||
|
||||
text-segmentation@1.0.3:
|
||||
dependencies:
|
||||
utrie: 1.0.2
|
||||
|
||||
thenify-all@1.6.0:
|
||||
dependencies:
|
||||
thenify: 3.3.1
|
||||
@@ -3025,6 +3170,10 @@ snapshots:
|
||||
|
||||
util-deprecate@1.0.2: {}
|
||||
|
||||
utrie@1.0.2:
|
||||
dependencies:
|
||||
base64-arraybuffer: 1.0.2
|
||||
|
||||
vant@4.9.21(vue@3.5.24):
|
||||
dependencies:
|
||||
'@vant/popperjs': 1.3.0
|
||||
|
||||
@@ -1,5 +1,17 @@
|
||||
<template>
|
||||
<div class="hy-report">
|
||||
<button
|
||||
v-if="showToolbar"
|
||||
type="button"
|
||||
class="export-fab no-print"
|
||||
:disabled="exporting"
|
||||
:aria-busy="exporting"
|
||||
@click="handleExport"
|
||||
>
|
||||
<span class="export-fab__icon">{{ exporting ? '…' : '↓' }}</span>
|
||||
<span class="export-fab__text">{{ exporting ? '生成中' : '下载 PDF' }}</span>
|
||||
</button>
|
||||
|
||||
<div ref="reportRef" class="hy-container">
|
||||
<ReportHeaderSection :report-time="reportTime" />
|
||||
|
||||
@@ -25,8 +37,8 @@
|
||||
|
||||
<script setup>
|
||||
import { computed, ref } from 'vue';
|
||||
import { parseRoot, extractReportUrl, REPORT_USAGE_NOTICE } from './reportHelper';
|
||||
import { printReportAsPdf } from './reportExport';
|
||||
import { parseRoot, REPORT_USAGE_NOTICE } from './reportHelper';
|
||||
import { downloadReportAsPdf } from './reportExport';
|
||||
import ReportHeaderSection from './components/ReportHeaderSection.vue';
|
||||
import RiskRatingSection from './components/RiskRatingSection.vue';
|
||||
import RiskOverviewSection from './components/RiskOverviewSection.vue';
|
||||
@@ -44,10 +56,10 @@ const props = defineProps({
|
||||
index: { type: Number, default: 0 },
|
||||
notifyRiskStatus: { type: Function, default: () => {} },
|
||||
reportDateTime: { type: String, default: '' },
|
||||
showToolbar: { type: Boolean, default: false },
|
||||
});
|
||||
|
||||
const root = computed(() => parseRoot(props.data));
|
||||
const reportUrl = computed(() => extractReportUrl(props.data));
|
||||
const reportRef = ref(null);
|
||||
const exporting = ref(false);
|
||||
|
||||
@@ -58,12 +70,26 @@ const reportTime = computed(
|
||||
async function handleExport() {
|
||||
exporting.value = true;
|
||||
try {
|
||||
await printReportAsPdf(reportRef.value);
|
||||
await downloadReportAsPdf(reportRef.value, {
|
||||
filename: `${props.apiId}_海宇个人风险报告_${formatFileDate(new Date())}.pdf`,
|
||||
});
|
||||
} finally {
|
||||
exporting.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
function formatFileDate(date) {
|
||||
const pad = (n) => String(n).padStart(2, '0');
|
||||
return [
|
||||
date.getFullYear(),
|
||||
pad(date.getMonth() + 1),
|
||||
pad(date.getDate()),
|
||||
pad(date.getHours()),
|
||||
pad(date.getMinutes()),
|
||||
pad(date.getSeconds()),
|
||||
].join('');
|
||||
}
|
||||
|
||||
defineExpose({ reportRef, handleExport });
|
||||
</script>
|
||||
|
||||
@@ -85,12 +111,70 @@ defineExpose({ reportRef, handleExport });
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
.export-fab {
|
||||
position: fixed;
|
||||
right: 24px;
|
||||
bottom: 32px;
|
||||
z-index: 1000;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
padding: 12px 18px;
|
||||
border: none;
|
||||
border-radius: 999px;
|
||||
background: #0a6e8e;
|
||||
color: #fff;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
cursor: pointer;
|
||||
box-shadow: 0 4px 16px rgba(10, 110, 142, 0.35);
|
||||
transition: transform 0.2s ease, box-shadow 0.2s ease, opacity 0.2s ease;
|
||||
|
||||
&:hover:not(:disabled) {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 6px 20px rgba(10, 110, 142, 0.45);
|
||||
}
|
||||
|
||||
&:disabled {
|
||||
opacity: 0.72;
|
||||
cursor: wait;
|
||||
}
|
||||
}
|
||||
|
||||
.export-fab__icon {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 22px;
|
||||
height: 22px;
|
||||
border-radius: 50%;
|
||||
background: rgba(255, 255, 255, 0.18);
|
||||
font-size: 16px;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.export-fab__text {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
@media (max-width: 900px) {
|
||||
.main-grid {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 640px) {
|
||||
.export-fab {
|
||||
right: 16px;
|
||||
bottom: 20px;
|
||||
padding: 12px 14px;
|
||||
}
|
||||
|
||||
.export-fab__text {
|
||||
font-size: 13px;
|
||||
}
|
||||
}
|
||||
|
||||
@media print {
|
||||
.no-print {
|
||||
display: none !important;
|
||||
|
||||
@@ -1,18 +1,109 @@
|
||||
import html2canvas from 'html2canvas';
|
||||
import { jsPDF } from 'jspdf';
|
||||
|
||||
const A4_WIDTH_MM = 210;
|
||||
const A4_HEIGHT_MM = 297;
|
||||
const PAGE_MARGIN_MM = 8;
|
||||
|
||||
/**
|
||||
* 通过浏览器打印对话框导出 PDF(目标打印机选「另存为 PDF」)。
|
||||
* 将报告 DOM 渲染为 PDF 文件并触发浏览器下载。
|
||||
*
|
||||
* @param {HTMLElement} reportElement
|
||||
* @param {{
|
||||
* filename?: string,
|
||||
* beforeCapture?: () => void | Promise<void>,
|
||||
* afterCapture?: () => void,
|
||||
* }} [options]
|
||||
*/
|
||||
export async function printReportAsPdf(reportElement) {
|
||||
export async function downloadReportAsPdf(reportElement, options = {}) {
|
||||
if (!reportElement) return;
|
||||
|
||||
document.body.classList.add('dwbg9fb2-printing');
|
||||
const {
|
||||
filename = `报告_${formatFileDate(new Date())}.pdf`,
|
||||
beforeCapture,
|
||||
afterCapture,
|
||||
} = options;
|
||||
|
||||
await new Promise((resolve) => requestAnimationFrame(resolve));
|
||||
if (beforeCapture) {
|
||||
await beforeCapture();
|
||||
}
|
||||
|
||||
const scrollLeft = window.scrollX;
|
||||
const scrollTop = window.scrollY;
|
||||
window.scrollTo(0, 0);
|
||||
await waitForPaint();
|
||||
|
||||
try {
|
||||
window.print();
|
||||
const canvas = await html2canvas(reportElement, {
|
||||
scale: 2,
|
||||
useCORS: true,
|
||||
logging: false,
|
||||
backgroundColor: '#ffffff',
|
||||
scrollX: 0,
|
||||
scrollY: -window.scrollY,
|
||||
windowWidth: document.documentElement.clientWidth,
|
||||
});
|
||||
|
||||
const pdf = new jsPDF({
|
||||
orientation: 'portrait',
|
||||
unit: 'mm',
|
||||
format: 'a4',
|
||||
});
|
||||
|
||||
const contentWidth = A4_WIDTH_MM - PAGE_MARGIN_MM * 2;
|
||||
const contentHeight = A4_HEIGHT_MM - PAGE_MARGIN_MM * 2;
|
||||
const imgWidth = contentWidth;
|
||||
const imgHeight = (canvas.height * imgWidth) / canvas.width;
|
||||
const imgData = canvas.toDataURL('image/jpeg', 0.92);
|
||||
|
||||
let heightLeft = imgHeight;
|
||||
let position = 0;
|
||||
|
||||
pdf.addImage(
|
||||
imgData,
|
||||
'JPEG',
|
||||
PAGE_MARGIN_MM,
|
||||
PAGE_MARGIN_MM + position,
|
||||
imgWidth,
|
||||
imgHeight,
|
||||
);
|
||||
heightLeft -= contentHeight;
|
||||
|
||||
while (heightLeft > 0) {
|
||||
position = heightLeft - imgHeight;
|
||||
pdf.addPage();
|
||||
pdf.addImage(
|
||||
imgData,
|
||||
'JPEG',
|
||||
PAGE_MARGIN_MM,
|
||||
PAGE_MARGIN_MM + position,
|
||||
imgWidth,
|
||||
imgHeight,
|
||||
);
|
||||
heightLeft -= contentHeight;
|
||||
}
|
||||
|
||||
pdf.save(filename);
|
||||
} finally {
|
||||
window.setTimeout(() => {
|
||||
document.body.classList.remove('dwbg9fb2-printing');
|
||||
}, 500);
|
||||
window.scrollTo(scrollLeft, scrollTop);
|
||||
if (afterCapture) afterCapture();
|
||||
}
|
||||
}
|
||||
|
||||
function formatFileDate(date) {
|
||||
const pad = (n) => String(n).padStart(2, '0');
|
||||
return [
|
||||
date.getFullYear(),
|
||||
pad(date.getMonth() + 1),
|
||||
pad(date.getDate()),
|
||||
pad(date.getHours()),
|
||||
pad(date.getMinutes()),
|
||||
pad(date.getSeconds()),
|
||||
].join('');
|
||||
}
|
||||
|
||||
function waitForPaint() {
|
||||
return new Promise((resolve) => {
|
||||
requestAnimationFrame(() => requestAnimationFrame(resolve));
|
||||
});
|
||||
}
|
||||
|
||||
@@ -129,7 +129,7 @@
|
||||
<span class="case-text">{{ caseListText(c) }}</span>
|
||||
<span class="case-arrow">{{ expandedIndex === i ? '∨' : '>' }}</span>
|
||||
</div>
|
||||
<div v-if="expandedIndex === i" class="case-block">
|
||||
<div v-if="isCaseExpanded(i)" class="case-block">
|
||||
<div class="case-info">
|
||||
<div><span>案件类型:</span><span>{{ c.sectionLabel }}</span></div>
|
||||
<div><span>诉讼地位:</span><span>{{ c.n_ssdw }}</span></div>
|
||||
@@ -361,11 +361,23 @@ const allCases = computed(() => {
|
||||
});
|
||||
|
||||
const expandedIndex = ref(null);
|
||||
const expandAllForPrint = ref(false);
|
||||
|
||||
function isCaseExpanded(index) {
|
||||
return expandAllForPrint.value || expandedIndex.value === index;
|
||||
}
|
||||
|
||||
function toggleCase(index) {
|
||||
if (expandAllForPrint.value) return;
|
||||
expandedIndex.value = expandedIndex.value === index ? null : index;
|
||||
}
|
||||
|
||||
function setExpandAllForPrint(expand) {
|
||||
expandAllForPrint.value = expand;
|
||||
}
|
||||
|
||||
defineExpose({ setExpandAllForPrint });
|
||||
|
||||
const dishonestList = computed(() =>
|
||||
extractJudicialList(props.data, [
|
||||
'dishonest',
|
||||
@@ -985,4 +997,16 @@ function partiesText(dsrxx) {
|
||||
overflow-x: auto;
|
||||
}
|
||||
}
|
||||
|
||||
@media print {
|
||||
.case-arrow {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.case-list-group,
|
||||
.case-block,
|
||||
.module-card {
|
||||
break-inside: avoid-page;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,5 +1,17 @@
|
||||
<template>
|
||||
<div class="gamma-report">
|
||||
<button
|
||||
v-if="showToolbar"
|
||||
type="button"
|
||||
class="export-fab no-print"
|
||||
:disabled="exporting"
|
||||
:aria-busy="exporting"
|
||||
@click="handleExport"
|
||||
>
|
||||
<span class="export-fab__icon">{{ exporting ? '…' : '↓' }}</span>
|
||||
<span class="export-fab__text">{{ exporting ? '生成中' : '下载 PDF' }}</span>
|
||||
</button>
|
||||
|
||||
<div ref="reportRef" class="gamma-container">
|
||||
<ReportHeaderSection :report-time="reportTime" />
|
||||
|
||||
@@ -26,15 +38,15 @@
|
||||
<OverdueSurveySection :data="root.loanRiskTagV10" />
|
||||
<CreditPanoramaSection :data="root.loanRiskTagV21" />
|
||||
<LoanIntentSection :data="root.loanRiskTagV11" />
|
||||
<JudicialCaseSection :data="root.personalLawsuit" />
|
||||
<JudicialCaseSection ref="judicialCaseRef" :data="root.personalLawsuit" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { computed, ref } from 'vue';
|
||||
import { parseRoot, extractReportUrl } from './reportHelper';
|
||||
import { printReportAsPdf } from './reportExport';
|
||||
import { parseRoot } from './reportHelper';
|
||||
import { downloadReportAsPdf } from './reportExport';
|
||||
import RiskAssessmentSection from './components/RiskAssessmentSection.vue';
|
||||
import RiskSummarySection from './components/RiskSummarySection.vue';
|
||||
import BasicInfoSection from './components/BasicInfoSection.vue';
|
||||
@@ -59,13 +71,40 @@ const props = defineProps({
|
||||
});
|
||||
|
||||
const root = computed(() => parseRoot(props.data));
|
||||
const reportUrl = computed(() => extractReportUrl(props.data));
|
||||
const reportRef = ref(null);
|
||||
const judicialCaseRef = ref(null);
|
||||
const exporting = ref(false);
|
||||
|
||||
const reportTime = computed(
|
||||
() => props.reportDateTime || new Date().toLocaleString('zh-CN'),
|
||||
);
|
||||
|
||||
async function handleExport() {
|
||||
exporting.value = true;
|
||||
try {
|
||||
await downloadReportAsPdf(reportRef.value, {
|
||||
filename: `${props.apiId}_海宇贷前风险档案_${formatFileDate(new Date())}.pdf`,
|
||||
beforeCapture: () => judicialCaseRef.value?.setExpandAllForPrint(true),
|
||||
afterCapture: () => judicialCaseRef.value?.setExpandAllForPrint(false),
|
||||
});
|
||||
} finally {
|
||||
exporting.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
function formatFileDate(date) {
|
||||
const pad = (n) => String(n).padStart(2, '0');
|
||||
return [
|
||||
date.getFullYear(),
|
||||
pad(date.getMonth() + 1),
|
||||
pad(date.getDate()),
|
||||
pad(date.getHours()),
|
||||
pad(date.getMinutes()),
|
||||
pad(date.getSeconds()),
|
||||
].join('');
|
||||
}
|
||||
|
||||
defineExpose({ reportRef, handleExport });
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
@@ -73,58 +112,61 @@ const reportTime = computed(
|
||||
</style>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.report-toolbar {
|
||||
max-width: 1200px;
|
||||
margin: 0 auto 16px;
|
||||
padding: 12px 20px;
|
||||
background: #fff;
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.05);
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
.export-fab {
|
||||
position: fixed;
|
||||
right: 24px;
|
||||
bottom: 32px;
|
||||
z-index: 1000;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.toolbar-title {
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
color: #8b4513;
|
||||
}
|
||||
|
||||
.toolbar-actions {
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.toolbar-btn {
|
||||
padding: 8px 18px;
|
||||
gap: 8px;
|
||||
padding: 12px 18px;
|
||||
border: none;
|
||||
border-radius: 6px;
|
||||
border-radius: 999px;
|
||||
background: #8b4513;
|
||||
color: #fff;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
cursor: pointer;
|
||||
box-shadow: 0 4px 16px rgba(139, 69, 19, 0.35);
|
||||
transition: transform 0.2s ease, box-shadow 0.2s ease, opacity 0.2s ease;
|
||||
|
||||
&:hover:not(:disabled) {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 6px 20px rgba(139, 69, 19, 0.45);
|
||||
}
|
||||
|
||||
&:disabled {
|
||||
opacity: 0.6;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
&--secondary {
|
||||
background: #fff;
|
||||
color: #8b4513;
|
||||
border: 1px solid #d4af37;
|
||||
opacity: 0.72;
|
||||
cursor: wait;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.report-toolbar {
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
gap: 8px;
|
||||
.export-fab__icon {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 22px;
|
||||
height: 22px;
|
||||
border-radius: 50%;
|
||||
background: rgba(255, 255, 255, 0.18);
|
||||
font-size: 16px;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.export-fab__text {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
@media (max-width: 640px) {
|
||||
.export-fab {
|
||||
right: 16px;
|
||||
bottom: 20px;
|
||||
padding: 12px 14px;
|
||||
}
|
||||
|
||||
.export-fab__text {
|
||||
font-size: 13px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,19 +1,109 @@
|
||||
import html2canvas from 'html2canvas';
|
||||
import { jsPDF } from 'jspdf';
|
||||
|
||||
const A4_WIDTH_MM = 210;
|
||||
const A4_HEIGHT_MM = 297;
|
||||
const PAGE_MARGIN_MM = 8;
|
||||
|
||||
/**
|
||||
* 通过浏览器打印对话框导出 PDF(目标打印机选「另存为 PDF」)。
|
||||
* 零依赖,适合当前纯前端报告查看器;复杂图表场景可改用服务端渲染 PDF。
|
||||
* 将报告 DOM 渲染为 PDF 文件并触发浏览器下载。
|
||||
*
|
||||
* @param {HTMLElement} reportElement
|
||||
* @param {{
|
||||
* filename?: string,
|
||||
* beforeCapture?: () => void | Promise<void>,
|
||||
* afterCapture?: () => void,
|
||||
* }} [options]
|
||||
*/
|
||||
export async function printReportAsPdf(reportElement) {
|
||||
export async function downloadReportAsPdf(reportElement, options = {}) {
|
||||
if (!reportElement) return;
|
||||
|
||||
document.body.classList.add('dwbg9fb3-printing');
|
||||
const {
|
||||
filename = `报告_${formatFileDate(new Date())}.pdf`,
|
||||
beforeCapture,
|
||||
afterCapture,
|
||||
} = options;
|
||||
|
||||
await new Promise((resolve) => requestAnimationFrame(resolve));
|
||||
if (beforeCapture) {
|
||||
await beforeCapture();
|
||||
}
|
||||
|
||||
const scrollLeft = window.scrollX;
|
||||
const scrollTop = window.scrollY;
|
||||
window.scrollTo(0, 0);
|
||||
await waitForPaint();
|
||||
|
||||
try {
|
||||
window.print();
|
||||
const canvas = await html2canvas(reportElement, {
|
||||
scale: 2,
|
||||
useCORS: true,
|
||||
logging: false,
|
||||
backgroundColor: '#ffffff',
|
||||
scrollX: 0,
|
||||
scrollY: -window.scrollY,
|
||||
windowWidth: document.documentElement.clientWidth,
|
||||
});
|
||||
|
||||
const pdf = new jsPDF({
|
||||
orientation: 'portrait',
|
||||
unit: 'mm',
|
||||
format: 'a4',
|
||||
});
|
||||
|
||||
const contentWidth = A4_WIDTH_MM - PAGE_MARGIN_MM * 2;
|
||||
const contentHeight = A4_HEIGHT_MM - PAGE_MARGIN_MM * 2;
|
||||
const imgWidth = contentWidth;
|
||||
const imgHeight = (canvas.height * imgWidth) / canvas.width;
|
||||
const imgData = canvas.toDataURL('image/jpeg', 0.92);
|
||||
|
||||
let heightLeft = imgHeight;
|
||||
let position = 0;
|
||||
|
||||
pdf.addImage(
|
||||
imgData,
|
||||
'JPEG',
|
||||
PAGE_MARGIN_MM,
|
||||
PAGE_MARGIN_MM + position,
|
||||
imgWidth,
|
||||
imgHeight,
|
||||
);
|
||||
heightLeft -= contentHeight;
|
||||
|
||||
while (heightLeft > 0) {
|
||||
position = heightLeft - imgHeight;
|
||||
pdf.addPage();
|
||||
pdf.addImage(
|
||||
imgData,
|
||||
'JPEG',
|
||||
PAGE_MARGIN_MM,
|
||||
PAGE_MARGIN_MM + position,
|
||||
imgWidth,
|
||||
imgHeight,
|
||||
);
|
||||
heightLeft -= contentHeight;
|
||||
}
|
||||
|
||||
pdf.save(filename);
|
||||
} finally {
|
||||
window.setTimeout(() => {
|
||||
document.body.classList.remove('dwbg9fb3-printing');
|
||||
}, 500);
|
||||
window.scrollTo(scrollLeft, scrollTop);
|
||||
if (afterCapture) afterCapture();
|
||||
}
|
||||
}
|
||||
|
||||
function formatFileDate(date) {
|
||||
const pad = (n) => String(n).padStart(2, '0');
|
||||
return [
|
||||
date.getFullYear(),
|
||||
pad(date.getMonth() + 1),
|
||||
pad(date.getDate()),
|
||||
pad(date.getHours()),
|
||||
pad(date.getMinutes()),
|
||||
pad(date.getSeconds()),
|
||||
].join('');
|
||||
}
|
||||
|
||||
function waitForPaint() {
|
||||
return new Promise((resolve) => {
|
||||
requestAnimationFrame(() => requestAnimationFrame(resolve));
|
||||
});
|
||||
}
|
||||
|
||||
@@ -12,6 +12,8 @@ export const RISK_LEVEL_DESC = [
|
||||
export const RISK_SUMMARY_CATEGORIES = [
|
||||
{ key: 'mobile4Verify', title: '基本信息', icon: '📛' },
|
||||
{ key: 'personalLawsuit', title: '司法案件', icon: '📑' },
|
||||
{ key: 'courtRiskTagV31', title: '限高被执行人', icon: '⚖️' },
|
||||
{ key: 'courtRiskTagV41', title: '失信被执行人', icon: '⚖️' },
|
||||
{ key: 'loanRiskTagV11', title: '借贷意向', icon: '📈' },
|
||||
{ key: 'loanRiskTagV10', title: '逾期勘测V3', icon: '📑' },
|
||||
{ key: 'loanRiskTagV12', title: '借贷行为验证', icon: '📊' },
|
||||
@@ -35,7 +37,7 @@ export function buildRiskSummaryCards(risks = {}) {
|
||||
return {
|
||||
key,
|
||||
title: meta?.title ?? key,
|
||||
icon: meta?.icon ?? '⚠️',
|
||||
icon: meta?.icon ?? '📋',
|
||||
items: Array.isArray(risks[key]) ? risks[key] : [],
|
||||
};
|
||||
});
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
:data="reportData"
|
||||
:params="reportParams"
|
||||
:report-date-time="reportDateTime"
|
||||
:show-toolbar="true"
|
||||
/>
|
||||
<div v-else class="loading-container">
|
||||
<div class="loading-spinner" />
|
||||
|
||||
Reference in New Issue
Block a user