fix: 网页版增加对话文件支持
This commit is contained in:
@@ -44,7 +44,9 @@
|
|||||||
"fingerprintjs": "^0.5.3",
|
"fingerprintjs": "^0.5.3",
|
||||||
"hook-fetch": "^2.0.4-beta.1",
|
"hook-fetch": "^2.0.4-beta.1",
|
||||||
"lodash-es": "^4.17.21",
|
"lodash-es": "^4.17.21",
|
||||||
|
"mammoth": "^1.11.0",
|
||||||
"nprogress": "^0.2.0",
|
"nprogress": "^0.2.0",
|
||||||
|
"pdfjs-dist": "^5.4.449",
|
||||||
"pinia": "^3.0.3",
|
"pinia": "^3.0.3",
|
||||||
"pinia-plugin-persistedstate": "^4.4.1",
|
"pinia-plugin-persistedstate": "^4.4.1",
|
||||||
"qrcode": "^1.5.4",
|
"qrcode": "^1.5.4",
|
||||||
@@ -52,7 +54,8 @@
|
|||||||
"reset-css": "^5.0.2",
|
"reset-css": "^5.0.2",
|
||||||
"vue": "^3.5.17",
|
"vue": "^3.5.17",
|
||||||
"vue-element-plus-x": "1.3.7",
|
"vue-element-plus-x": "1.3.7",
|
||||||
"vue-router": "4"
|
"vue-router": "4",
|
||||||
|
"xlsx": "^0.18.5"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@antfu/eslint-config": "^4.16.2",
|
"@antfu/eslint-config": "^4.16.2",
|
||||||
|
|||||||
333
Yi.Ai.Vue3/pnpm-lock.yaml
generated
333
Yi.Ai.Vue3/pnpm-lock.yaml
generated
@@ -53,9 +53,15 @@ importers:
|
|||||||
lodash-es:
|
lodash-es:
|
||||||
specifier: ^4.17.21
|
specifier: ^4.17.21
|
||||||
version: 4.17.21
|
version: 4.17.21
|
||||||
|
mammoth:
|
||||||
|
specifier: ^1.11.0
|
||||||
|
version: 1.11.0
|
||||||
nprogress:
|
nprogress:
|
||||||
specifier: ^0.2.0
|
specifier: ^0.2.0
|
||||||
version: 0.2.0
|
version: 0.2.0
|
||||||
|
pdfjs-dist:
|
||||||
|
specifier: ^5.4.449
|
||||||
|
version: 5.4.449
|
||||||
pinia:
|
pinia:
|
||||||
specifier: ^3.0.3
|
specifier: ^3.0.3
|
||||||
version: 3.0.3(typescript@5.8.3)(vue@3.5.17(typescript@5.8.3))
|
version: 3.0.3(typescript@5.8.3)(vue@3.5.17(typescript@5.8.3))
|
||||||
@@ -80,6 +86,9 @@ importers:
|
|||||||
vue-router:
|
vue-router:
|
||||||
specifier: '4'
|
specifier: '4'
|
||||||
version: 4.5.1(vue@3.5.17(typescript@5.8.3))
|
version: 4.5.1(vue@3.5.17(typescript@5.8.3))
|
||||||
|
xlsx:
|
||||||
|
specifier: ^0.18.5
|
||||||
|
version: 0.18.5
|
||||||
devDependencies:
|
devDependencies:
|
||||||
'@antfu/eslint-config':
|
'@antfu/eslint-config':
|
||||||
specifier: ^4.16.2
|
specifier: ^4.16.2
|
||||||
@@ -736,6 +745,70 @@ packages:
|
|||||||
'@manypkg/get-packages@1.1.3':
|
'@manypkg/get-packages@1.1.3':
|
||||||
resolution: {integrity: sha512-fo+QhuU3qE/2TQMQmbVMqaQ6EWbMhi4ABWP+O4AM1NqPBuy0OrApV5LO6BrrgnhtAHS2NH6RrVk9OL181tTi8A==}
|
resolution: {integrity: sha512-fo+QhuU3qE/2TQMQmbVMqaQ6EWbMhi4ABWP+O4AM1NqPBuy0OrApV5LO6BrrgnhtAHS2NH6RrVk9OL181tTi8A==}
|
||||||
|
|
||||||
|
'@napi-rs/canvas-android-arm64@0.1.84':
|
||||||
|
resolution: {integrity: sha512-pdvuqvj3qtwVryqgpAGornJLV6Ezpk39V6wT4JCnRVGy8I3Tk1au8qOalFGrx/r0Ig87hWslysPpHBxVpBMIww==}
|
||||||
|
engines: {node: '>= 10'}
|
||||||
|
cpu: [arm64]
|
||||||
|
os: [android]
|
||||||
|
|
||||||
|
'@napi-rs/canvas-darwin-arm64@0.1.84':
|
||||||
|
resolution: {integrity: sha512-A8IND3Hnv0R6abc6qCcCaOCujTLMmGxtucMTZ5vbQUrEN/scxi378MyTLtyWg+MRr6bwQJ6v/orqMS9datIcww==}
|
||||||
|
engines: {node: '>= 10'}
|
||||||
|
cpu: [arm64]
|
||||||
|
os: [darwin]
|
||||||
|
|
||||||
|
'@napi-rs/canvas-darwin-x64@0.1.84':
|
||||||
|
resolution: {integrity: sha512-AUW45lJhYWwnA74LaNeqhvqYKK/2hNnBBBl03KRdqeCD4tKneUSrxUqIv8d22CBweOvrAASyKN3W87WO2zEr/A==}
|
||||||
|
engines: {node: '>= 10'}
|
||||||
|
cpu: [x64]
|
||||||
|
os: [darwin]
|
||||||
|
|
||||||
|
'@napi-rs/canvas-linux-arm-gnueabihf@0.1.84':
|
||||||
|
resolution: {integrity: sha512-8zs5ZqOrdgs4FioTxSBrkl/wHZB56bJNBqaIsfPL4ZkEQCinOkrFF7xIcXiHiKp93J3wUtbIzeVrhTIaWwqk+A==}
|
||||||
|
engines: {node: '>= 10'}
|
||||||
|
cpu: [arm]
|
||||||
|
os: [linux]
|
||||||
|
|
||||||
|
'@napi-rs/canvas-linux-arm64-gnu@0.1.84':
|
||||||
|
resolution: {integrity: sha512-i204vtowOglJUpbAFWU5mqsJgH0lVpNk/Ml4mQtB4Lndd86oF+Otr6Mr5KQnZHqYGhlSIKiU2SYnUbhO28zGQA==}
|
||||||
|
engines: {node: '>= 10'}
|
||||||
|
cpu: [arm64]
|
||||||
|
os: [linux]
|
||||||
|
|
||||||
|
'@napi-rs/canvas-linux-arm64-musl@0.1.84':
|
||||||
|
resolution: {integrity: sha512-VyZq0EEw+OILnWk7G3ZgLLPaz1ERaPP++jLjeyLMbFOF+Tr4zHzWKiKDsEV/cT7btLPZbVoR3VX+T9/QubnURQ==}
|
||||||
|
engines: {node: '>= 10'}
|
||||||
|
cpu: [arm64]
|
||||||
|
os: [linux]
|
||||||
|
|
||||||
|
'@napi-rs/canvas-linux-riscv64-gnu@0.1.84':
|
||||||
|
resolution: {integrity: sha512-PSMTh8DiThvLRsbtc/a065I/ceZk17EXAATv9uNvHgkgo7wdEfTh2C3aveNkBMGByVO3tvnvD5v/YFtZL07cIg==}
|
||||||
|
engines: {node: '>= 10'}
|
||||||
|
cpu: [riscv64]
|
||||||
|
os: [linux]
|
||||||
|
|
||||||
|
'@napi-rs/canvas-linux-x64-gnu@0.1.84':
|
||||||
|
resolution: {integrity: sha512-N1GY3noO1oqgEo3rYQIwY44kfM11vA0lDbN0orTOHfCSUZTUyiYCY0nZ197QMahZBm1aR/vYgsWpV74MMMDuNA==}
|
||||||
|
engines: {node: '>= 10'}
|
||||||
|
cpu: [x64]
|
||||||
|
os: [linux]
|
||||||
|
|
||||||
|
'@napi-rs/canvas-linux-x64-musl@0.1.84':
|
||||||
|
resolution: {integrity: sha512-vUZmua6ADqTWyHyei81aXIt9wp0yjeNwTH0KdhdeoBb6azHmFR8uKTukZMXfLCC3bnsW0t4lW7K78KNMknmtjg==}
|
||||||
|
engines: {node: '>= 10'}
|
||||||
|
cpu: [x64]
|
||||||
|
os: [linux]
|
||||||
|
|
||||||
|
'@napi-rs/canvas-win32-x64-msvc@0.1.84':
|
||||||
|
resolution: {integrity: sha512-YSs8ncurc1xzegUMNnQUTYrdrAuaXdPMOa+iYYyAxydOtg0ppV386hyYMsy00Yip1NlTgLCseRG4sHSnjQx6og==}
|
||||||
|
engines: {node: '>= 10'}
|
||||||
|
cpu: [x64]
|
||||||
|
os: [win32]
|
||||||
|
|
||||||
|
'@napi-rs/canvas@0.1.84':
|
||||||
|
resolution: {integrity: sha512-88FTNFs4uuiFKP0tUrPsEXhpe9dg7za9ILZJE08pGdUveMIDeana1zwfVkqRHJDPJFAmGY3dXmJ99dzsy57YnA==}
|
||||||
|
engines: {node: '>= 10'}
|
||||||
|
|
||||||
'@nodelib/fs.scandir@2.1.5':
|
'@nodelib/fs.scandir@2.1.5':
|
||||||
resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==}
|
resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==}
|
||||||
engines: {node: '>= 8'}
|
engines: {node: '>= 8'}
|
||||||
@@ -1307,6 +1380,10 @@ packages:
|
|||||||
'@vueuse/shared@9.13.0':
|
'@vueuse/shared@9.13.0':
|
||||||
resolution: {integrity: sha512-UrnhU+Cnufu4S6JLCPZnkWh0WwZGUp72ktOF2DFptMlOs3TOdVv8xJN53zhHGARmVOsz5KqOls09+J1NR6sBKw==}
|
resolution: {integrity: sha512-UrnhU+Cnufu4S6JLCPZnkWh0WwZGUp72ktOF2DFptMlOs3TOdVv8xJN53zhHGARmVOsz5KqOls09+J1NR6sBKw==}
|
||||||
|
|
||||||
|
'@xmldom/xmldom@0.8.11':
|
||||||
|
resolution: {integrity: sha512-cQzWCtO6C8TQiYl1ruKNn2U6Ao4o4WBBcbL61yJl84x+j5sOWWFU9X7DpND8XZG3daDppSsigMdfAIl2upQBRw==}
|
||||||
|
engines: {node: '>=10.0.0'}
|
||||||
|
|
||||||
JSONStream@1.3.5:
|
JSONStream@1.3.5:
|
||||||
resolution: {integrity: sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==}
|
resolution: {integrity: sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
@@ -1326,6 +1403,10 @@ packages:
|
|||||||
engines: {node: '>=0.4.0'}
|
engines: {node: '>=0.4.0'}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
||||||
|
adler-32@1.3.1:
|
||||||
|
resolution: {integrity: sha512-ynZ4w/nUUv5rrsR8UUGoe1VC9hZj6V5hU9Qw1HlMDJGEJw5S7TfTErWTjMys6M7vr0YWcPqs3qAr4ss0nDfP+A==}
|
||||||
|
engines: {node: '>=0.8'}
|
||||||
|
|
||||||
ajv@6.12.6:
|
ajv@6.12.6:
|
||||||
resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==}
|
resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==}
|
||||||
|
|
||||||
@@ -1470,6 +1551,9 @@ packages:
|
|||||||
birpc@2.3.0:
|
birpc@2.3.0:
|
||||||
resolution: {integrity: sha512-ijbtkn/F3Pvzb6jHypHRyve2QApOCZDR25D/VnkY2G/lBNcXCTsnsCxgY4k4PkVB7zfwzYbY3O9Lcqe3xufS5g==}
|
resolution: {integrity: sha512-ijbtkn/F3Pvzb6jHypHRyve2QApOCZDR25D/VnkY2G/lBNcXCTsnsCxgY4k4PkVB7zfwzYbY3O9Lcqe3xufS5g==}
|
||||||
|
|
||||||
|
bluebird@3.4.7:
|
||||||
|
resolution: {integrity: sha512-iD3898SR7sWVRHbiQv+sHUtHnMvC1o3nW5rAcqnq3uOn07DSAppZYUkIGslDz6gXC7HfunPe7YVBgoEJASPcHA==}
|
||||||
|
|
||||||
bluebird@3.7.2:
|
bluebird@3.7.2:
|
||||||
resolution: {integrity: sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==}
|
resolution: {integrity: sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==}
|
||||||
|
|
||||||
@@ -1550,6 +1634,10 @@ packages:
|
|||||||
ccount@2.0.1:
|
ccount@2.0.1:
|
||||||
resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==}
|
resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==}
|
||||||
|
|
||||||
|
cfb@1.2.2:
|
||||||
|
resolution: {integrity: sha512-KfdUZsSOw19/ObEWasvBP/Ac4reZvAGauZhs6S/gqNhXhI7cKwvlH7ulj+dOEYnca4bm4SGo8C1bTAQvnTjgQA==}
|
||||||
|
engines: {node: '>=0.8'}
|
||||||
|
|
||||||
chalk@1.1.3:
|
chalk@1.1.3:
|
||||||
resolution: {integrity: sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A==}
|
resolution: {integrity: sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A==}
|
||||||
engines: {node: '>=0.10.0'}
|
engines: {node: '>=0.10.0'}
|
||||||
@@ -1623,6 +1711,10 @@ packages:
|
|||||||
resolution: {integrity: sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==}
|
resolution: {integrity: sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==}
|
||||||
engines: {node: '>=0.8'}
|
engines: {node: '>=0.8'}
|
||||||
|
|
||||||
|
codepage@1.15.0:
|
||||||
|
resolution: {integrity: sha512-3g6NUTPd/YtuuGrhMnOMRjFc+LJw/bnMp3+0r/Wcz3IXUuCosKRJvMphm5+Q+bvTVGcJJuRvVLuYba+WojaFaA==}
|
||||||
|
engines: {node: '>=0.8'}
|
||||||
|
|
||||||
collection-visit@1.0.0:
|
collection-visit@1.0.0:
|
||||||
resolution: {integrity: sha512-lNkKvzEeMBBjUGHZ+q6z9pSJla0KWAQPvtzhEV9+iGyQYG+pBpl7xKDhxoNSOZH2hhv0v5k0y2yAM4o4SjoSkw==}
|
resolution: {integrity: sha512-lNkKvzEeMBBjUGHZ+q6z9pSJla0KWAQPvtzhEV9+iGyQYG+pBpl7xKDhxoNSOZH2hhv0v5k0y2yAM4o4SjoSkw==}
|
||||||
engines: {node: '>=0.10.0'}
|
engines: {node: '>=0.10.0'}
|
||||||
@@ -1710,6 +1802,9 @@ packages:
|
|||||||
core-js-compat@3.42.0:
|
core-js-compat@3.42.0:
|
||||||
resolution: {integrity: sha512-bQasjMfyDGyaeWKBIu33lHh9qlSR0MFE/Nmc6nMjf/iU9b3rSMdAYz1Baxrv4lPdGUsTqZudHA4jIGSJy0SWZQ==}
|
resolution: {integrity: sha512-bQasjMfyDGyaeWKBIu33lHh9qlSR0MFE/Nmc6nMjf/iU9b3rSMdAYz1Baxrv4lPdGUsTqZudHA4jIGSJy0SWZQ==}
|
||||||
|
|
||||||
|
core-util-is@1.0.3:
|
||||||
|
resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==}
|
||||||
|
|
||||||
cors@2.8.5:
|
cors@2.8.5:
|
||||||
resolution: {integrity: sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==}
|
resolution: {integrity: sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==}
|
||||||
engines: {node: '>= 0.10'}
|
engines: {node: '>= 0.10'}
|
||||||
@@ -1731,6 +1826,11 @@ packages:
|
|||||||
typescript:
|
typescript:
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
|
crc-32@1.2.2:
|
||||||
|
resolution: {integrity: sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==}
|
||||||
|
engines: {node: '>=0.8'}
|
||||||
|
hasBin: true
|
||||||
|
|
||||||
cross-spawn@7.0.6:
|
cross-spawn@7.0.6:
|
||||||
resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==}
|
resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==}
|
||||||
engines: {node: '>= 8'}
|
engines: {node: '>= 8'}
|
||||||
@@ -1878,6 +1978,9 @@ packages:
|
|||||||
dijkstrajs@1.0.3:
|
dijkstrajs@1.0.3:
|
||||||
resolution: {integrity: sha512-qiSlmBq9+BCdCA/L46dw8Uy93mloxsPSbwnm5yrKn2vMPiy8KyAskTF6zuV/j5BMsmOGZDPs7KjU+mjb670kfA==}
|
resolution: {integrity: sha512-qiSlmBq9+BCdCA/L46dw8Uy93mloxsPSbwnm5yrKn2vMPiy8KyAskTF6zuV/j5BMsmOGZDPs7KjU+mjb670kfA==}
|
||||||
|
|
||||||
|
dingbat-to-unicode@1.0.1:
|
||||||
|
resolution: {integrity: sha512-98l0sW87ZT58pU4i61wa2OHwxbiYSbuxsCBozaVnYX2iCnr3bLM3fIes1/ej7h1YdOKuKt/MLs706TVnALA65w==}
|
||||||
|
|
||||||
dir-glob@3.0.1:
|
dir-glob@3.0.1:
|
||||||
resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==}
|
resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==}
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
@@ -1931,6 +2034,9 @@ packages:
|
|||||||
driver.js@1.3.6:
|
driver.js@1.3.6:
|
||||||
resolution: {integrity: sha512-g2nNuu+tWmPpuoyk3ffpT9vKhjPz4NrJzq6mkRDZIwXCrFhrKdDJ9TX5tJOBpvCTBrBYjgRQ17XlcQB15q4gMg==}
|
resolution: {integrity: sha512-g2nNuu+tWmPpuoyk3ffpT9vKhjPz4NrJzq6mkRDZIwXCrFhrKdDJ9TX5tJOBpvCTBrBYjgRQ17XlcQB15q4gMg==}
|
||||||
|
|
||||||
|
duck@0.1.12:
|
||||||
|
resolution: {integrity: sha512-wkctla1O6VfP89gQ+J/yDesM0S7B7XLXjKGzXxMDVFg7uEn706niAtyYovKbyq1oT9YwDcly721/iUWoc8MVRg==}
|
||||||
|
|
||||||
dunder-proto@1.0.1:
|
dunder-proto@1.0.1:
|
||||||
resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==}
|
resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==}
|
||||||
engines: {node: '>= 0.4'}
|
engines: {node: '>= 0.4'}
|
||||||
@@ -2384,6 +2490,10 @@ packages:
|
|||||||
resolution: {integrity: sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww==}
|
resolution: {integrity: sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww==}
|
||||||
engines: {node: '>=0.4.x'}
|
engines: {node: '>=0.4.x'}
|
||||||
|
|
||||||
|
frac@1.1.2:
|
||||||
|
resolution: {integrity: sha512-w/XBfkibaTl3YDqASwfDUqkna4Z2p9cFSr1aHDt0WoMTECnRfBOv2WArlZILlqgWlmdIlALXGpM2AOhEk5W3IA==}
|
||||||
|
engines: {node: '>=0.8'}
|
||||||
|
|
||||||
fragment-cache@0.2.1:
|
fragment-cache@0.2.1:
|
||||||
resolution: {integrity: sha512-GMBAbW9antB8iZRHLoGw0b3HANt57diZYFO/HL1JGIC1MjKrdmhxvrJbupnVvpys0zsz7yBApXdQyfepKly2kA==}
|
resolution: {integrity: sha512-GMBAbW9antB8iZRHLoGw0b3HANt57diZYFO/HL1JGIC1MjKrdmhxvrJbupnVvpys0zsz7yBApXdQyfepKly2kA==}
|
||||||
engines: {node: '>=0.10.0'}
|
engines: {node: '>=0.10.0'}
|
||||||
@@ -2673,6 +2783,9 @@ packages:
|
|||||||
engines: {node: '>=0.10.0'}
|
engines: {node: '>=0.10.0'}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
||||||
|
immediate@3.0.6:
|
||||||
|
resolution: {integrity: sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==}
|
||||||
|
|
||||||
immutable@5.1.2:
|
immutable@5.1.2:
|
||||||
resolution: {integrity: sha512-qHKXW1q6liAk1Oys6umoaZbDRqjcjgSrbnrifHsfsttza7zcvRAsL7mMV6xWcyhwQy7Xj5v4hhbr6b+iDYwlmQ==}
|
resolution: {integrity: sha512-qHKXW1q6liAk1Oys6umoaZbDRqjcjgSrbnrifHsfsttza7zcvRAsL7mMV6xWcyhwQy7Xj5v4hhbr6b+iDYwlmQ==}
|
||||||
|
|
||||||
@@ -2988,6 +3101,9 @@ packages:
|
|||||||
resolution: {integrity: sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==}
|
resolution: {integrity: sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==}
|
||||||
engines: {'0': node >= 0.2.0}
|
engines: {'0': node >= 0.2.0}
|
||||||
|
|
||||||
|
jszip@3.10.1:
|
||||||
|
resolution: {integrity: sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==}
|
||||||
|
|
||||||
katex@0.16.22:
|
katex@0.16.22:
|
||||||
resolution: {integrity: sha512-XCHRdUw4lf3SKBaJe4EvgqIuWwkPSo9XoeO8GjQW94Bp7TWv9hNhzZjZ+OH9yf1UmLygb7DIT5GSFQiyt16zYg==}
|
resolution: {integrity: sha512-XCHRdUw4lf3SKBaJe4EvgqIuWwkPSo9XoeO8GjQW94Bp7TWv9hNhzZjZ+OH9yf1UmLygb7DIT5GSFQiyt16zYg==}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
@@ -3034,6 +3150,9 @@ packages:
|
|||||||
resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==}
|
resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==}
|
||||||
engines: {node: '>= 0.8.0'}
|
engines: {node: '>= 0.8.0'}
|
||||||
|
|
||||||
|
lie@3.3.0:
|
||||||
|
resolution: {integrity: sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==}
|
||||||
|
|
||||||
lilconfig@3.1.3:
|
lilconfig@3.1.3:
|
||||||
resolution: {integrity: sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==}
|
resolution: {integrity: sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==}
|
||||||
engines: {node: '>=14'}
|
engines: {node: '>=14'}
|
||||||
@@ -3120,9 +3239,17 @@ packages:
|
|||||||
longest-streak@3.1.0:
|
longest-streak@3.1.0:
|
||||||
resolution: {integrity: sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==}
|
resolution: {integrity: sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==}
|
||||||
|
|
||||||
|
lop@0.4.2:
|
||||||
|
resolution: {integrity: sha512-RefILVDQ4DKoRZsJ4Pj22TxE3omDO47yFpkIBoDKzkqPRISs5U1cnAdg/5583YPkWPaLIYHOKRMQSvjFsO26cw==}
|
||||||
|
|
||||||
magic-string@0.30.17:
|
magic-string@0.30.17:
|
||||||
resolution: {integrity: sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==}
|
resolution: {integrity: sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==}
|
||||||
|
|
||||||
|
mammoth@1.11.0:
|
||||||
|
resolution: {integrity: sha512-BcEqqY/BOwIcI1iR5tqyVlqc3KIaMRa4egSoK83YAVrBf6+yqdAAbtUcFDCWX8Zef8/fgNZ6rl4VUv+vVX8ddQ==}
|
||||||
|
engines: {node: '>=12.0.0'}
|
||||||
|
hasBin: true
|
||||||
|
|
||||||
map-cache@0.2.2:
|
map-cache@0.2.2:
|
||||||
resolution: {integrity: sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg==}
|
resolution: {integrity: sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg==}
|
||||||
engines: {node: '>=0.10.0'}
|
engines: {node: '>=0.10.0'}
|
||||||
@@ -3452,6 +3579,9 @@ packages:
|
|||||||
resolution: {integrity: sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==}
|
resolution: {integrity: sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==}
|
||||||
engines: {node: '>=12'}
|
engines: {node: '>=12'}
|
||||||
|
|
||||||
|
option@0.2.4:
|
||||||
|
resolution: {integrity: sha512-pkEqbDyl8ou5cpq+VsnQbe/WlEy5qS7xPzMS1U55OCG9KPvwFD46zDbxQIj3egJSFc3D+XhYOPUzz49zQAVy7A==}
|
||||||
|
|
||||||
optionator@0.9.4:
|
optionator@0.9.4:
|
||||||
resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==}
|
resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==}
|
||||||
engines: {node: '>= 0.8.0'}
|
engines: {node: '>= 0.8.0'}
|
||||||
@@ -3509,6 +3639,9 @@ packages:
|
|||||||
package-manager-detector@1.3.0:
|
package-manager-detector@1.3.0:
|
||||||
resolution: {integrity: sha512-ZsEbbZORsyHuO00lY1kV3/t72yp6Ysay6Pd17ZAlNGuGwmWDLCJxFpRs0IzfXfj1o4icJOkUEioexFHzyPurSQ==}
|
resolution: {integrity: sha512-ZsEbbZORsyHuO00lY1kV3/t72yp6Ysay6Pd17ZAlNGuGwmWDLCJxFpRs0IzfXfj1o4icJOkUEioexFHzyPurSQ==}
|
||||||
|
|
||||||
|
pako@1.0.11:
|
||||||
|
resolution: {integrity: sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==}
|
||||||
|
|
||||||
parent-module@1.0.1:
|
parent-module@1.0.1:
|
||||||
resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==}
|
resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==}
|
||||||
engines: {node: '>=6'}
|
engines: {node: '>=6'}
|
||||||
@@ -3545,6 +3678,10 @@ packages:
|
|||||||
resolution: {integrity: sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==}
|
resolution: {integrity: sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==}
|
||||||
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
|
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
|
||||||
|
|
||||||
|
path-is-absolute@1.0.1:
|
||||||
|
resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==}
|
||||||
|
engines: {node: '>=0.10.0'}
|
||||||
|
|
||||||
path-key@3.1.1:
|
path-key@3.1.1:
|
||||||
resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==}
|
resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==}
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
@@ -3559,6 +3696,10 @@ packages:
|
|||||||
pathe@2.0.3:
|
pathe@2.0.3:
|
||||||
resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==}
|
resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==}
|
||||||
|
|
||||||
|
pdfjs-dist@5.4.449:
|
||||||
|
resolution: {integrity: sha512-CegnUaT0QwAyQMS+7o2POr4wWUNNe8VaKKlcuoRHeYo98cVnqPpwOXNSx6Trl6szH02JrRcsPgletV6GmF3LtQ==}
|
||||||
|
engines: {node: '>=20.16.0 || >=22.3.0'}
|
||||||
|
|
||||||
perfect-debounce@1.0.0:
|
perfect-debounce@1.0.0:
|
||||||
resolution: {integrity: sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==}
|
resolution: {integrity: sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==}
|
||||||
|
|
||||||
@@ -3730,6 +3871,9 @@ packages:
|
|||||||
resolution: {integrity: sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw==}
|
resolution: {integrity: sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw==}
|
||||||
engines: {node: '>=6'}
|
engines: {node: '>=6'}
|
||||||
|
|
||||||
|
process-nextick-args@2.0.1:
|
||||||
|
resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==}
|
||||||
|
|
||||||
property-information@6.5.0:
|
property-information@6.5.0:
|
||||||
resolution: {integrity: sha512-PgTgs/BlvHxOu8QuEN7wi5A0OmXaBcHpmCSTehcs6Uuu9IkDIEo13Hy7n898RHfrQ49vKCoGeWZSaAK01nwVig==}
|
resolution: {integrity: sha512-PgTgs/BlvHxOu8QuEN7wi5A0OmXaBcHpmCSTehcs6Uuu9IkDIEo13Hy7n898RHfrQ49vKCoGeWZSaAK01nwVig==}
|
||||||
|
|
||||||
@@ -3774,6 +3918,9 @@ packages:
|
|||||||
resolution: {integrity: sha512-VIMnQi/Z4HT2Fxuwg5KrY174U1VdUIASQVWXXyqtNRtxSr9IYkn1rsI6Tb6HsrHCmB7gVpNwX6JxPTHcH6IoTA==}
|
resolution: {integrity: sha512-VIMnQi/Z4HT2Fxuwg5KrY174U1VdUIASQVWXXyqtNRtxSr9IYkn1rsI6Tb6HsrHCmB7gVpNwX6JxPTHcH6IoTA==}
|
||||||
engines: {node: '>=6'}
|
engines: {node: '>=6'}
|
||||||
|
|
||||||
|
readable-stream@2.3.8:
|
||||||
|
resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==}
|
||||||
|
|
||||||
readable-stream@3.6.2:
|
readable-stream@3.6.2:
|
||||||
resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==}
|
resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==}
|
||||||
engines: {node: '>= 6'}
|
engines: {node: '>= 6'}
|
||||||
@@ -3930,6 +4077,9 @@ packages:
|
|||||||
resolution: {integrity: sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==}
|
resolution: {integrity: sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==}
|
||||||
engines: {node: '>=0.4'}
|
engines: {node: '>=0.4'}
|
||||||
|
|
||||||
|
safe-buffer@5.1.2:
|
||||||
|
resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==}
|
||||||
|
|
||||||
safe-buffer@5.2.1:
|
safe-buffer@5.2.1:
|
||||||
resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==}
|
resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==}
|
||||||
|
|
||||||
@@ -4079,6 +4229,9 @@ packages:
|
|||||||
resolution: {integrity: sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==}
|
resolution: {integrity: sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==}
|
||||||
engines: {node: '>=0.10.0'}
|
engines: {node: '>=0.10.0'}
|
||||||
|
|
||||||
|
setimmediate@1.0.5:
|
||||||
|
resolution: {integrity: sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==}
|
||||||
|
|
||||||
shebang-command@2.0.0:
|
shebang-command@2.0.0:
|
||||||
resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==}
|
resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==}
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
@@ -4199,6 +4352,10 @@ packages:
|
|||||||
sprintf-js@1.0.3:
|
sprintf-js@1.0.3:
|
||||||
resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==}
|
resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==}
|
||||||
|
|
||||||
|
ssf@0.11.2:
|
||||||
|
resolution: {integrity: sha512-+idbmIXoYET47hH+d7dfm2epdOMUDjqcB4648sTZ+t2JwoyBFL/insLfB/racrDmsKB3diwsDA696pZMieAC5g==}
|
||||||
|
engines: {node: '>=0.8'}
|
||||||
|
|
||||||
stable@0.1.8:
|
stable@0.1.8:
|
||||||
resolution: {integrity: sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==}
|
resolution: {integrity: sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==}
|
||||||
deprecated: 'Modern JS already guarantees Array#sort() is a stable sort, so this library is deprecated. See the compatibility table on MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#browser_compatibility'
|
deprecated: 'Modern JS already guarantees Array#sort() is a stable sort, so this library is deprecated. See the compatibility table on MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#browser_compatibility'
|
||||||
@@ -4242,6 +4399,9 @@ packages:
|
|||||||
resolution: {integrity: sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==}
|
resolution: {integrity: sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==}
|
||||||
engines: {node: '>= 0.4'}
|
engines: {node: '>= 0.4'}
|
||||||
|
|
||||||
|
string_decoder@1.1.1:
|
||||||
|
resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==}
|
||||||
|
|
||||||
string_decoder@1.3.0:
|
string_decoder@1.3.0:
|
||||||
resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==}
|
resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==}
|
||||||
|
|
||||||
@@ -4536,6 +4696,9 @@ packages:
|
|||||||
unctx@2.4.1:
|
unctx@2.4.1:
|
||||||
resolution: {integrity: sha512-AbaYw0Nm4mK4qjhns67C+kgxR2YWiwlDBPzxrN8h8C6VtAdCgditAY5Dezu3IJy4XVqAnbrXt9oQJvsn3fyozg==}
|
resolution: {integrity: sha512-AbaYw0Nm4mK4qjhns67C+kgxR2YWiwlDBPzxrN8h8C6VtAdCgditAY5Dezu3IJy4XVqAnbrXt9oQJvsn3fyozg==}
|
||||||
|
|
||||||
|
underscore@1.13.7:
|
||||||
|
resolution: {integrity: sha512-GMXzWtsc57XAtguZgaQViUOzs0KTkk8ojr3/xAxXLITqf/3EMwxC0inyETfDFjH/Krbhuep0HNbbjI9i/q3F3g==}
|
||||||
|
|
||||||
undici-types@6.21.0:
|
undici-types@6.21.0:
|
||||||
resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==}
|
resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==}
|
||||||
|
|
||||||
@@ -4814,10 +4977,18 @@ packages:
|
|||||||
engines: {node: '>= 8'}
|
engines: {node: '>= 8'}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
||||||
|
wmf@1.0.2:
|
||||||
|
resolution: {integrity: sha512-/p9K7bEh0Dj6WbXg4JG0xvLQmIadrner1bi45VMJTfnbVHsc7yIajZyoSoK60/dtVBs12Fm6WkUI5/3WAVsNMw==}
|
||||||
|
engines: {node: '>=0.8'}
|
||||||
|
|
||||||
word-wrap@1.2.5:
|
word-wrap@1.2.5:
|
||||||
resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==}
|
resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==}
|
||||||
engines: {node: '>=0.10.0'}
|
engines: {node: '>=0.10.0'}
|
||||||
|
|
||||||
|
word@0.3.0:
|
||||||
|
resolution: {integrity: sha512-OELeY0Q61OXpdUfTp+oweA/vtLVg5VDOXh+3he3PNzLGG/y0oylSOC1xRVj0+l4vQ3tj/bB1HVHv1ocXkQceFA==}
|
||||||
|
engines: {node: '>=0.8'}
|
||||||
|
|
||||||
wordwrap@1.0.0:
|
wordwrap@1.0.0:
|
||||||
resolution: {integrity: sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==}
|
resolution: {integrity: sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==}
|
||||||
|
|
||||||
@@ -4837,10 +5008,19 @@ packages:
|
|||||||
resolution: {integrity: sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==}
|
resolution: {integrity: sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==}
|
||||||
engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
|
engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
|
||||||
|
|
||||||
|
xlsx@0.18.5:
|
||||||
|
resolution: {integrity: sha512-dmg3LCjBPHZnQp5/F/+nnTa+miPJxUXB6vtk42YjBBKayDNagxGEeIdWApkYPOf3Z3pm3k62Knjzp7lMeTEtFQ==}
|
||||||
|
engines: {node: '>=0.8'}
|
||||||
|
hasBin: true
|
||||||
|
|
||||||
xml-name-validator@4.0.0:
|
xml-name-validator@4.0.0:
|
||||||
resolution: {integrity: sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==}
|
resolution: {integrity: sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==}
|
||||||
engines: {node: '>=12'}
|
engines: {node: '>=12'}
|
||||||
|
|
||||||
|
xmlbuilder@10.1.1:
|
||||||
|
resolution: {integrity: sha512-OyzrcFLL/nb6fMGHbiRDuPup9ljBycsdCypwuyg5AAHvyWzGfChJpCXMG88AGTIMFhGZ9RccFN1e6lhg3hkwKg==}
|
||||||
|
engines: {node: '>=4.0'}
|
||||||
|
|
||||||
y18n@4.0.3:
|
y18n@4.0.3:
|
||||||
resolution: {integrity: sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==}
|
resolution: {integrity: sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==}
|
||||||
|
|
||||||
@@ -5522,6 +5702,50 @@ snapshots:
|
|||||||
globby: 11.1.0
|
globby: 11.1.0
|
||||||
read-yaml-file: 1.1.0
|
read-yaml-file: 1.1.0
|
||||||
|
|
||||||
|
'@napi-rs/canvas-android-arm64@0.1.84':
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@napi-rs/canvas-darwin-arm64@0.1.84':
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@napi-rs/canvas-darwin-x64@0.1.84':
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@napi-rs/canvas-linux-arm-gnueabihf@0.1.84':
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@napi-rs/canvas-linux-arm64-gnu@0.1.84':
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@napi-rs/canvas-linux-arm64-musl@0.1.84':
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@napi-rs/canvas-linux-riscv64-gnu@0.1.84':
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@napi-rs/canvas-linux-x64-gnu@0.1.84':
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@napi-rs/canvas-linux-x64-musl@0.1.84':
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@napi-rs/canvas-win32-x64-msvc@0.1.84':
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@napi-rs/canvas@0.1.84':
|
||||||
|
optionalDependencies:
|
||||||
|
'@napi-rs/canvas-android-arm64': 0.1.84
|
||||||
|
'@napi-rs/canvas-darwin-arm64': 0.1.84
|
||||||
|
'@napi-rs/canvas-darwin-x64': 0.1.84
|
||||||
|
'@napi-rs/canvas-linux-arm-gnueabihf': 0.1.84
|
||||||
|
'@napi-rs/canvas-linux-arm64-gnu': 0.1.84
|
||||||
|
'@napi-rs/canvas-linux-arm64-musl': 0.1.84
|
||||||
|
'@napi-rs/canvas-linux-riscv64-gnu': 0.1.84
|
||||||
|
'@napi-rs/canvas-linux-x64-gnu': 0.1.84
|
||||||
|
'@napi-rs/canvas-linux-x64-musl': 0.1.84
|
||||||
|
'@napi-rs/canvas-win32-x64-msvc': 0.1.84
|
||||||
|
optional: true
|
||||||
|
|
||||||
'@nodelib/fs.scandir@2.1.5':
|
'@nodelib/fs.scandir@2.1.5':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@nodelib/fs.stat': 2.0.5
|
'@nodelib/fs.stat': 2.0.5
|
||||||
@@ -6216,6 +6440,8 @@ snapshots:
|
|||||||
- '@vue/composition-api'
|
- '@vue/composition-api'
|
||||||
- vue
|
- vue
|
||||||
|
|
||||||
|
'@xmldom/xmldom@0.8.11': {}
|
||||||
|
|
||||||
JSONStream@1.3.5:
|
JSONStream@1.3.5:
|
||||||
dependencies:
|
dependencies:
|
||||||
jsonparse: 1.3.1
|
jsonparse: 1.3.1
|
||||||
@@ -6233,6 +6459,8 @@ snapshots:
|
|||||||
|
|
||||||
acorn@8.15.0: {}
|
acorn@8.15.0: {}
|
||||||
|
|
||||||
|
adler-32@1.3.1: {}
|
||||||
|
|
||||||
ajv@6.12.6:
|
ajv@6.12.6:
|
||||||
dependencies:
|
dependencies:
|
||||||
fast-deep-equal: 3.1.3
|
fast-deep-equal: 3.1.3
|
||||||
@@ -6353,6 +6581,8 @@ snapshots:
|
|||||||
|
|
||||||
birpc@2.3.0: {}
|
birpc@2.3.0: {}
|
||||||
|
|
||||||
|
bluebird@3.4.7: {}
|
||||||
|
|
||||||
bluebird@3.7.2: {}
|
bluebird@3.7.2: {}
|
||||||
|
|
||||||
boolbase@1.0.0: {}
|
boolbase@1.0.0: {}
|
||||||
@@ -6461,6 +6691,11 @@ snapshots:
|
|||||||
|
|
||||||
ccount@2.0.1: {}
|
ccount@2.0.1: {}
|
||||||
|
|
||||||
|
cfb@1.2.2:
|
||||||
|
dependencies:
|
||||||
|
adler-32: 1.3.1
|
||||||
|
crc-32: 1.2.2
|
||||||
|
|
||||||
chalk@1.1.3:
|
chalk@1.1.3:
|
||||||
dependencies:
|
dependencies:
|
||||||
ansi-styles: 2.2.1
|
ansi-styles: 2.2.1
|
||||||
@@ -6546,6 +6781,8 @@ snapshots:
|
|||||||
|
|
||||||
clone@2.1.2: {}
|
clone@2.1.2: {}
|
||||||
|
|
||||||
|
codepage@1.15.0: {}
|
||||||
|
|
||||||
collection-visit@1.0.0:
|
collection-visit@1.0.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
map-visit: 1.0.0
|
map-visit: 1.0.0
|
||||||
@@ -6621,6 +6858,8 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
browserslist: 4.25.0
|
browserslist: 4.25.0
|
||||||
|
|
||||||
|
core-util-is@1.0.3: {}
|
||||||
|
|
||||||
cors@2.8.5:
|
cors@2.8.5:
|
||||||
dependencies:
|
dependencies:
|
||||||
object-assign: 4.1.1
|
object-assign: 4.1.1
|
||||||
@@ -6642,6 +6881,8 @@ snapshots:
|
|||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
typescript: 5.8.3
|
typescript: 5.8.3
|
||||||
|
|
||||||
|
crc-32@1.2.2: {}
|
||||||
|
|
||||||
cross-spawn@7.0.6:
|
cross-spawn@7.0.6:
|
||||||
dependencies:
|
dependencies:
|
||||||
path-key: 3.1.1
|
path-key: 3.1.1
|
||||||
@@ -6771,6 +7012,8 @@ snapshots:
|
|||||||
|
|
||||||
dijkstrajs@1.0.3: {}
|
dijkstrajs@1.0.3: {}
|
||||||
|
|
||||||
|
dingbat-to-unicode@1.0.1: {}
|
||||||
|
|
||||||
dir-glob@3.0.1:
|
dir-glob@3.0.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
path-type: 4.0.0
|
path-type: 4.0.0
|
||||||
@@ -6838,6 +7081,10 @@ snapshots:
|
|||||||
|
|
||||||
driver.js@1.3.6: {}
|
driver.js@1.3.6: {}
|
||||||
|
|
||||||
|
duck@0.1.12:
|
||||||
|
dependencies:
|
||||||
|
underscore: 1.13.7
|
||||||
|
|
||||||
dunder-proto@1.0.1:
|
dunder-proto@1.0.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
call-bind-apply-helpers: 1.0.2
|
call-bind-apply-helpers: 1.0.2
|
||||||
@@ -7458,6 +7705,8 @@ snapshots:
|
|||||||
|
|
||||||
format@0.2.2: {}
|
format@0.2.2: {}
|
||||||
|
|
||||||
|
frac@1.1.2: {}
|
||||||
|
|
||||||
fragment-cache@0.2.1:
|
fragment-cache@0.2.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
map-cache: 0.2.2
|
map-cache: 0.2.2
|
||||||
@@ -7818,6 +8067,8 @@ snapshots:
|
|||||||
|
|
||||||
image-size@0.5.5: {}
|
image-size@0.5.5: {}
|
||||||
|
|
||||||
|
immediate@3.0.6: {}
|
||||||
|
|
||||||
immutable@5.1.2: {}
|
immutable@5.1.2: {}
|
||||||
|
|
||||||
import-fresh@3.3.1:
|
import-fresh@3.3.1:
|
||||||
@@ -8094,6 +8345,13 @@ snapshots:
|
|||||||
|
|
||||||
jsonparse@1.3.1: {}
|
jsonparse@1.3.1: {}
|
||||||
|
|
||||||
|
jszip@3.10.1:
|
||||||
|
dependencies:
|
||||||
|
lie: 3.3.0
|
||||||
|
pako: 1.0.11
|
||||||
|
readable-stream: 2.3.8
|
||||||
|
setimmediate: 1.0.5
|
||||||
|
|
||||||
katex@0.16.22:
|
katex@0.16.22:
|
||||||
dependencies:
|
dependencies:
|
||||||
commander: 8.3.0
|
commander: 8.3.0
|
||||||
@@ -8135,6 +8393,10 @@ snapshots:
|
|||||||
prelude-ls: 1.2.1
|
prelude-ls: 1.2.1
|
||||||
type-check: 0.4.0
|
type-check: 0.4.0
|
||||||
|
|
||||||
|
lie@3.3.0:
|
||||||
|
dependencies:
|
||||||
|
immediate: 3.0.6
|
||||||
|
|
||||||
lilconfig@3.1.3: {}
|
lilconfig@3.1.3: {}
|
||||||
|
|
||||||
lines-and-columns@1.2.4: {}
|
lines-and-columns@1.2.4: {}
|
||||||
@@ -8227,10 +8489,29 @@ snapshots:
|
|||||||
|
|
||||||
longest-streak@3.1.0: {}
|
longest-streak@3.1.0: {}
|
||||||
|
|
||||||
|
lop@0.4.2:
|
||||||
|
dependencies:
|
||||||
|
duck: 0.1.12
|
||||||
|
option: 0.2.4
|
||||||
|
underscore: 1.13.7
|
||||||
|
|
||||||
magic-string@0.30.17:
|
magic-string@0.30.17:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@jridgewell/sourcemap-codec': 1.5.0
|
'@jridgewell/sourcemap-codec': 1.5.0
|
||||||
|
|
||||||
|
mammoth@1.11.0:
|
||||||
|
dependencies:
|
||||||
|
'@xmldom/xmldom': 0.8.11
|
||||||
|
argparse: 1.0.10
|
||||||
|
base64-js: 1.5.1
|
||||||
|
bluebird: 3.4.7
|
||||||
|
dingbat-to-unicode: 1.0.1
|
||||||
|
jszip: 3.10.1
|
||||||
|
lop: 0.4.2
|
||||||
|
path-is-absolute: 1.0.1
|
||||||
|
underscore: 1.13.7
|
||||||
|
xmlbuilder: 10.1.1
|
||||||
|
|
||||||
map-cache@0.2.2: {}
|
map-cache@0.2.2: {}
|
||||||
|
|
||||||
map-visit@1.0.0:
|
map-visit@1.0.0:
|
||||||
@@ -8777,6 +9058,8 @@ snapshots:
|
|||||||
is-docker: 2.2.1
|
is-docker: 2.2.1
|
||||||
is-wsl: 2.2.0
|
is-wsl: 2.2.0
|
||||||
|
|
||||||
|
option@0.2.4: {}
|
||||||
|
|
||||||
optionator@0.9.4:
|
optionator@0.9.4:
|
||||||
dependencies:
|
dependencies:
|
||||||
deep-is: 0.1.4
|
deep-is: 0.1.4
|
||||||
@@ -8834,6 +9117,8 @@ snapshots:
|
|||||||
|
|
||||||
package-manager-detector@1.3.0: {}
|
package-manager-detector@1.3.0: {}
|
||||||
|
|
||||||
|
pako@1.0.11: {}
|
||||||
|
|
||||||
parent-module@1.0.1:
|
parent-module@1.0.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
callsites: 3.1.0
|
callsites: 3.1.0
|
||||||
@@ -8865,6 +9150,8 @@ snapshots:
|
|||||||
|
|
||||||
path-exists@5.0.0: {}
|
path-exists@5.0.0: {}
|
||||||
|
|
||||||
|
path-is-absolute@1.0.1: {}
|
||||||
|
|
||||||
path-key@3.1.1: {}
|
path-key@3.1.1: {}
|
||||||
|
|
||||||
path-type@4.0.0: {}
|
path-type@4.0.0: {}
|
||||||
@@ -8873,6 +9160,10 @@ snapshots:
|
|||||||
|
|
||||||
pathe@2.0.3: {}
|
pathe@2.0.3: {}
|
||||||
|
|
||||||
|
pdfjs-dist@5.4.449:
|
||||||
|
optionalDependencies:
|
||||||
|
'@napi-rs/canvas': 0.1.84
|
||||||
|
|
||||||
perfect-debounce@1.0.0: {}
|
perfect-debounce@1.0.0: {}
|
||||||
|
|
||||||
picocolors@1.1.1: {}
|
picocolors@1.1.1: {}
|
||||||
@@ -9020,6 +9311,8 @@ snapshots:
|
|||||||
|
|
||||||
prismjs@1.30.0: {}
|
prismjs@1.30.0: {}
|
||||||
|
|
||||||
|
process-nextick-args@2.0.1: {}
|
||||||
|
|
||||||
property-information@6.5.0: {}
|
property-information@6.5.0: {}
|
||||||
|
|
||||||
property-information@7.1.0: {}
|
property-information@7.1.0: {}
|
||||||
@@ -9062,6 +9355,16 @@ snapshots:
|
|||||||
pify: 4.0.1
|
pify: 4.0.1
|
||||||
strip-bom: 3.0.0
|
strip-bom: 3.0.0
|
||||||
|
|
||||||
|
readable-stream@2.3.8:
|
||||||
|
dependencies:
|
||||||
|
core-util-is: 1.0.3
|
||||||
|
inherits: 2.0.4
|
||||||
|
isarray: 1.0.0
|
||||||
|
process-nextick-args: 2.0.1
|
||||||
|
safe-buffer: 5.1.2
|
||||||
|
string_decoder: 1.1.1
|
||||||
|
util-deprecate: 1.0.2
|
||||||
|
|
||||||
readable-stream@3.6.2:
|
readable-stream@3.6.2:
|
||||||
dependencies:
|
dependencies:
|
||||||
inherits: 2.0.4
|
inherits: 2.0.4
|
||||||
@@ -9277,6 +9580,8 @@ snapshots:
|
|||||||
has-symbols: 1.1.0
|
has-symbols: 1.1.0
|
||||||
isarray: 2.0.5
|
isarray: 2.0.5
|
||||||
|
|
||||||
|
safe-buffer@5.1.2: {}
|
||||||
|
|
||||||
safe-buffer@5.2.1: {}
|
safe-buffer@5.2.1: {}
|
||||||
|
|
||||||
safe-push-apply@1.0.0:
|
safe-push-apply@1.0.0:
|
||||||
@@ -9413,6 +9718,8 @@ snapshots:
|
|||||||
is-plain-object: 2.0.4
|
is-plain-object: 2.0.4
|
||||||
split-string: 3.1.0
|
split-string: 3.1.0
|
||||||
|
|
||||||
|
setimmediate@1.0.5: {}
|
||||||
|
|
||||||
shebang-command@2.0.0:
|
shebang-command@2.0.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
shebang-regex: 3.0.0
|
shebang-regex: 3.0.0
|
||||||
@@ -9553,6 +9860,10 @@ snapshots:
|
|||||||
|
|
||||||
sprintf-js@1.0.3: {}
|
sprintf-js@1.0.3: {}
|
||||||
|
|
||||||
|
ssf@0.11.2:
|
||||||
|
dependencies:
|
||||||
|
frac: 1.1.2
|
||||||
|
|
||||||
stable@0.1.8: {}
|
stable@0.1.8: {}
|
||||||
|
|
||||||
static-extend@0.1.2:
|
static-extend@0.1.2:
|
||||||
@@ -9607,6 +9918,10 @@ snapshots:
|
|||||||
define-properties: 1.2.1
|
define-properties: 1.2.1
|
||||||
es-object-atoms: 1.1.1
|
es-object-atoms: 1.1.1
|
||||||
|
|
||||||
|
string_decoder@1.1.1:
|
||||||
|
dependencies:
|
||||||
|
safe-buffer: 5.1.2
|
||||||
|
|
||||||
string_decoder@1.3.0:
|
string_decoder@1.3.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
safe-buffer: 5.2.1
|
safe-buffer: 5.2.1
|
||||||
@@ -9975,6 +10290,8 @@ snapshots:
|
|||||||
unplugin: 2.3.5
|
unplugin: 2.3.5
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
|
underscore@1.13.7: {}
|
||||||
|
|
||||||
undici-types@6.21.0: {}
|
undici-types@6.21.0: {}
|
||||||
|
|
||||||
unicorn-magic@0.1.0: {}
|
unicorn-magic@0.1.0: {}
|
||||||
@@ -10359,8 +10676,12 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
isexe: 2.0.0
|
isexe: 2.0.0
|
||||||
|
|
||||||
|
wmf@1.0.2: {}
|
||||||
|
|
||||||
word-wrap@1.2.5: {}
|
word-wrap@1.2.5: {}
|
||||||
|
|
||||||
|
word@0.3.0: {}
|
||||||
|
|
||||||
wordwrap@1.0.0: {}
|
wordwrap@1.0.0: {}
|
||||||
|
|
||||||
wrap-ansi@6.2.0:
|
wrap-ansi@6.2.0:
|
||||||
@@ -10386,8 +10707,20 @@ snapshots:
|
|||||||
imurmurhash: 0.1.4
|
imurmurhash: 0.1.4
|
||||||
signal-exit: 4.1.0
|
signal-exit: 4.1.0
|
||||||
|
|
||||||
|
xlsx@0.18.5:
|
||||||
|
dependencies:
|
||||||
|
adler-32: 1.3.1
|
||||||
|
cfb: 1.2.2
|
||||||
|
codepage: 1.15.0
|
||||||
|
crc-32: 1.2.2
|
||||||
|
ssf: 0.11.2
|
||||||
|
wmf: 1.0.2
|
||||||
|
word: 0.3.0
|
||||||
|
|
||||||
xml-name-validator@4.0.0: {}
|
xml-name-validator@4.0.0: {}
|
||||||
|
|
||||||
|
xmlbuilder@10.1.1: {}
|
||||||
|
|
||||||
y18n@4.0.3: {}
|
y18n@4.0.3: {}
|
||||||
|
|
||||||
y18n@5.0.8: {}
|
y18n@5.0.8: {}
|
||||||
|
|||||||
@@ -220,4 +220,16 @@ export interface ChatMessageVo {
|
|||||||
* 用户id
|
* 用户id
|
||||||
*/
|
*/
|
||||||
userId?: number;
|
userId?: number;
|
||||||
|
/**
|
||||||
|
* 用户消息中的图片列表(前端扩展字段)
|
||||||
|
*/
|
||||||
|
images?: Array<{ url: string; name?: string }>;
|
||||||
|
/**
|
||||||
|
* 用户消息中的文件列表(前端扩展字段)
|
||||||
|
*/
|
||||||
|
files?: Array<{ name: string; size: number }>;
|
||||||
|
/**
|
||||||
|
* 创建时间(前端显示用)
|
||||||
|
*/
|
||||||
|
creationTime?: string;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,35 +3,52 @@
|
|||||||
import type { FileItem } from '@/stores/modules/files';
|
import type { FileItem } from '@/stores/modules/files';
|
||||||
import { useFileDialog } from '@vueuse/core';
|
import { useFileDialog } from '@vueuse/core';
|
||||||
import { ElMessage } from 'element-plus';
|
import { ElMessage } from 'element-plus';
|
||||||
|
import mammoth from 'mammoth';
|
||||||
|
import * as pdfjsLib from 'pdfjs-dist';
|
||||||
|
import * as XLSX from 'xlsx';
|
||||||
import Popover from '@/components/Popover/index.vue';
|
import Popover from '@/components/Popover/index.vue';
|
||||||
import SvgIcon from '@/components/SvgIcon/index.vue';
|
import SvgIcon from '@/components/SvgIcon/index.vue';
|
||||||
import { useFilesStore } from '@/stores/modules/files';
|
import { useFilesStore } from '@/stores/modules/files';
|
||||||
|
|
||||||
|
// 配置 PDF.js worker - 使用稳定的 CDN
|
||||||
|
pdfjsLib.GlobalWorkerOptions.workerSrc = `https://cdn.jsdelivr.net/npm/pdfjs-dist@${pdfjsLib.version}/build/pdf.worker.min.mjs`;
|
||||||
|
|
||||||
const filesStore = useFilesStore();
|
const filesStore = useFilesStore();
|
||||||
|
|
||||||
// 文件大小限制 3MB
|
// 文件大小限制 3MB
|
||||||
const MAX_FILE_SIZE = 3 * 1024 * 1024;
|
const MAX_FILE_SIZE = 3 * 1024 * 1024;
|
||||||
|
|
||||||
/* 弹出面板 开始 */
|
// 单个文件内容长度限制
|
||||||
const popoverStyle = ref({
|
const MAX_TEXT_FILE_LENGTH = 50000; // 文本文件最大字符数
|
||||||
padding: '4px',
|
const MAX_WORD_LENGTH = 30000; // Word 文档最大字符数
|
||||||
height: 'fit-content',
|
const MAX_EXCEL_ROWS = 100; // Excel 最大行数
|
||||||
background: 'var(--el-bg-color, #fff)',
|
const MAX_PDF_PAGES = 10; // PDF 最大页数
|
||||||
border: '1px solid var(--el-border-color-light)',
|
|
||||||
borderRadius: '8px',
|
// 整个消息总长度限制(所有文件内容加起来,预估 token 安全限制)
|
||||||
boxShadow: '0 2px 12px 0 rgba(0, 0, 0, 0.1)',
|
// 272000 tokens * 0.55 安全系数 ≈ 150000 字符
|
||||||
});
|
const MAX_TOTAL_CONTENT_LENGTH = 150000;
|
||||||
const popoverRef = ref();
|
|
||||||
/* 弹出面板 结束 */
|
|
||||||
|
|
||||||
const { reset, open, onChange } = useFileDialog({
|
const { reset, open, onChange } = useFileDialog({
|
||||||
// 允许图片和文件
|
// 支持图片、文档、文本文件等
|
||||||
accept: 'image/*,application/pdf,application/msword,application/vnd.openxmlformats-officedocument.wordprocessingml.document',
|
accept: 'image/*,.txt,.log,.csv,.tsv,.md,.markdown,.json,.xml,.yaml,.yml,.toml,.ini,.conf,.config,.properties,.prop,.env,'
|
||||||
directory: false, // 是否允许选择文件夹
|
+ '.js,.jsx,.ts,.tsx,.vue,.html,.htm,.css,.scss,.sass,.less,.styl,'
|
||||||
multiple: true, // 是否允许多选
|
+ '.java,.c,.cpp,.h,.hpp,.cs,.py,.rb,.go,.rs,.swift,.kt,.php,.sh,.bash,.zsh,.fish,.bat,.cmd,.ps1,'
|
||||||
|
+ '.sql,.graphql,.proto,.thrift,'
|
||||||
|
+ '.dockerfile,.gitignore,.gitattributes,.editorconfig,.npmrc,.nvmrc,'
|
||||||
|
+ '.sln,.csproj,.vbproj,.fsproj,.props,.targets,'
|
||||||
|
+ '.xlsx,.xls,.csv,.docx,.pdf',
|
||||||
|
directory: false,
|
||||||
|
multiple: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
// 压缩图片
|
/**
|
||||||
|
* 压缩图片
|
||||||
|
* @param {File} file - 原始图片文件
|
||||||
|
* @param {number} maxWidth - 最大宽度,默认 1024px
|
||||||
|
* @param {number} maxHeight - 最大高度,默认 1024px
|
||||||
|
* @param {number} quality - 压缩质量,0-1之间,默认 0.8
|
||||||
|
* @returns {Promise<Blob>} 压缩后的图片 Blob
|
||||||
|
*/
|
||||||
function compressImage(file: File, maxWidth = 1024, maxHeight = 1024, quality = 0.8): Promise<Blob> {
|
function compressImage(file: File, maxWidth = 1024, maxHeight = 1024, quality = 0.8): Promise<Blob> {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
const reader = new FileReader();
|
const reader = new FileReader();
|
||||||
@@ -60,12 +77,13 @@ function compressImage(file: File, maxWidth = 1024, maxHeight = 1024, quality =
|
|||||||
(blob) => {
|
(blob) => {
|
||||||
if (blob) {
|
if (blob) {
|
||||||
resolve(blob);
|
resolve(blob);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
reject(new Error('压缩失败'));
|
reject(new Error('压缩失败'));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
file.type,
|
file.type,
|
||||||
quality
|
quality,
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
img.onerror = reject;
|
img.onerror = reject;
|
||||||
@@ -76,7 +94,11 @@ function compressImage(file: File, maxWidth = 1024, maxHeight = 1024, quality =
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// 将 Blob 转换为 base64
|
/**
|
||||||
|
* 将 Blob 转换为 base64 格式
|
||||||
|
* @param {Blob} blob - 要转换的 Blob 对象
|
||||||
|
* @returns {Promise<string>} base64 编码的字符串(包含 data:xxx;base64, 前缀)
|
||||||
|
*/
|
||||||
function blobToBase64(blob: Blob): Promise<string> {
|
function blobToBase64(blob: Blob): Promise<string> {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
const reader = new FileReader();
|
const reader = new FileReader();
|
||||||
@@ -88,11 +110,289 @@ function blobToBase64(blob: Blob): Promise<string> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 读取文本文件内容
|
||||||
|
* @param {File} file - 文本文件
|
||||||
|
* @returns {Promise<string>} 文件内容字符串
|
||||||
|
*/
|
||||||
|
function readTextFile(file: File): Promise<string> {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const reader = new FileReader();
|
||||||
|
reader.onload = () => {
|
||||||
|
resolve(reader.result as string);
|
||||||
|
};
|
||||||
|
reader.onerror = reject;
|
||||||
|
reader.readAsText(file, 'UTF-8');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断是否为文本文件
|
||||||
|
* 通过 MIME 类型或文件扩展名判断
|
||||||
|
* @param {File} file - 要判断的文件
|
||||||
|
* @returns {boolean} 是否为文本文件
|
||||||
|
*/
|
||||||
|
function isTextFile(file: File): boolean {
|
||||||
|
// 通过 MIME type 判断
|
||||||
|
if (file.type.startsWith('text/')) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 通过扩展名判断(更全面的列表)
|
||||||
|
const textExtensions = [
|
||||||
|
// 通用文本
|
||||||
|
'txt',
|
||||||
|
'log',
|
||||||
|
'md',
|
||||||
|
'markdown',
|
||||||
|
'rtf',
|
||||||
|
// 配置文件
|
||||||
|
'json',
|
||||||
|
'xml',
|
||||||
|
'yaml',
|
||||||
|
'yml',
|
||||||
|
'toml',
|
||||||
|
'ini',
|
||||||
|
'conf',
|
||||||
|
'config',
|
||||||
|
'properties',
|
||||||
|
'prop',
|
||||||
|
'env',
|
||||||
|
// 前端
|
||||||
|
'js',
|
||||||
|
'jsx',
|
||||||
|
'ts',
|
||||||
|
'tsx',
|
||||||
|
'vue',
|
||||||
|
'html',
|
||||||
|
'htm',
|
||||||
|
'css',
|
||||||
|
'scss',
|
||||||
|
'sass',
|
||||||
|
'less',
|
||||||
|
'styl',
|
||||||
|
// 编程语言
|
||||||
|
'java',
|
||||||
|
'c',
|
||||||
|
'cpp',
|
||||||
|
'h',
|
||||||
|
'hpp',
|
||||||
|
'cs',
|
||||||
|
'py',
|
||||||
|
'rb',
|
||||||
|
'go',
|
||||||
|
'rs',
|
||||||
|
'swift',
|
||||||
|
'kt',
|
||||||
|
'php',
|
||||||
|
// 脚本
|
||||||
|
'sh',
|
||||||
|
'bash',
|
||||||
|
'zsh',
|
||||||
|
'fish',
|
||||||
|
'bat',
|
||||||
|
'cmd',
|
||||||
|
'ps1',
|
||||||
|
// 数据库/API
|
||||||
|
'sql',
|
||||||
|
'graphql',
|
||||||
|
'proto',
|
||||||
|
'thrift',
|
||||||
|
// 版本控制/工具
|
||||||
|
'dockerfile',
|
||||||
|
'gitignore',
|
||||||
|
'gitattributes',
|
||||||
|
'editorconfig',
|
||||||
|
'npmrc',
|
||||||
|
'nvmrc',
|
||||||
|
// .NET 项目文件
|
||||||
|
'sln',
|
||||||
|
'csproj',
|
||||||
|
'vbproj',
|
||||||
|
'fsproj',
|
||||||
|
'props',
|
||||||
|
'targets',
|
||||||
|
// 数据文件
|
||||||
|
'csv',
|
||||||
|
'tsv',
|
||||||
|
];
|
||||||
|
|
||||||
|
const ext = file.name.split('.').pop()?.toLowerCase();
|
||||||
|
return ext ? textExtensions.includes(ext) : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 解析 Excel 文件,提取前 N 行数据转为 CSV 格式
|
||||||
|
* @param {File} file - Excel 文件 (.xlsx, .xls)
|
||||||
|
* @returns {Promise<{content: string, totalRows: number, extractedRows: number}>}
|
||||||
|
* - content: CSV 格式的文本内容
|
||||||
|
* - totalRows: 文件总行数
|
||||||
|
* - extractedRows: 实际提取的行数(受 MAX_EXCEL_ROWS 限制)
|
||||||
|
*/
|
||||||
|
async function parseExcel(file: File): Promise<{ content: string; totalRows: number; extractedRows: number }> {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const reader = new FileReader();
|
||||||
|
reader.onload = (e) => {
|
||||||
|
try {
|
||||||
|
const data = new Uint8Array(e.target?.result as ArrayBuffer);
|
||||||
|
const workbook = XLSX.read(data, { type: 'array' });
|
||||||
|
|
||||||
|
let result = '';
|
||||||
|
let totalRows = 0;
|
||||||
|
let extractedRows = 0;
|
||||||
|
|
||||||
|
workbook.SheetNames.forEach((sheetName, index) => {
|
||||||
|
const worksheet = workbook.Sheets[sheetName];
|
||||||
|
|
||||||
|
// 获取工作表的范围
|
||||||
|
const range = XLSX.utils.decode_range(worksheet['!ref'] || 'A1');
|
||||||
|
const sheetTotalRows = range.e.r - range.s.r + 1;
|
||||||
|
totalRows += sheetTotalRows;
|
||||||
|
|
||||||
|
// 限制行数
|
||||||
|
const rowsToExtract = Math.min(sheetTotalRows, MAX_EXCEL_ROWS);
|
||||||
|
extractedRows += rowsToExtract;
|
||||||
|
|
||||||
|
// 创建新的范围,只包含前 N 行
|
||||||
|
const limitedRange = {
|
||||||
|
s: { r: range.s.r, c: range.s.c },
|
||||||
|
e: { r: range.s.r + rowsToExtract - 1, c: range.e.c },
|
||||||
|
};
|
||||||
|
|
||||||
|
// 提取限制范围内的数据
|
||||||
|
const limitedData: any[][] = [];
|
||||||
|
for (let row = limitedRange.s.r; row <= limitedRange.e.r; row++) {
|
||||||
|
const rowData: any[] = [];
|
||||||
|
for (let col = limitedRange.s.c; col <= limitedRange.e.c; col++) {
|
||||||
|
const cellAddress = XLSX.utils.encode_cell({ r: row, c: col });
|
||||||
|
const cell = worksheet[cellAddress];
|
||||||
|
rowData.push(cell ? cell.v : '');
|
||||||
|
}
|
||||||
|
limitedData.push(rowData);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 转换为 CSV
|
||||||
|
const csvData = limitedData.map(row => row.join(',')).join('\n');
|
||||||
|
|
||||||
|
if (workbook.SheetNames.length > 1) {
|
||||||
|
result += `=== Sheet: ${sheetName} ===\n`;
|
||||||
|
}
|
||||||
|
result += csvData;
|
||||||
|
if (index < workbook.SheetNames.length - 1) {
|
||||||
|
result += '\n\n';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
resolve({ content: result, totalRows, extractedRows });
|
||||||
|
}
|
||||||
|
catch (error) {
|
||||||
|
reject(error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
reader.onerror = reject;
|
||||||
|
reader.readAsArrayBuffer(file);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 解析 Word 文档,提取纯文本内容
|
||||||
|
* @param {File} file - Word 文档 (.docx)
|
||||||
|
* @returns {Promise<{content: string, totalLength: number, extracted: boolean}>}
|
||||||
|
* - content: 提取的文本内容
|
||||||
|
* - totalLength: 原始文本总长度
|
||||||
|
* - extracted: 是否被截断(超过 MAX_WORD_LENGTH)
|
||||||
|
*/
|
||||||
|
async function parseWord(file: File): Promise<{ content: string; totalLength: number; extracted: boolean }> {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const reader = new FileReader();
|
||||||
|
reader.onload = async (e) => {
|
||||||
|
try {
|
||||||
|
const arrayBuffer = e.target?.result as ArrayBuffer;
|
||||||
|
const result = await mammoth.extractRawText({ arrayBuffer });
|
||||||
|
const fullText = result.value;
|
||||||
|
const totalLength = fullText.length;
|
||||||
|
|
||||||
|
if (totalLength > MAX_WORD_LENGTH) {
|
||||||
|
const truncated = fullText.substring(0, MAX_WORD_LENGTH);
|
||||||
|
resolve({ content: truncated, totalLength, extracted: true });
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
resolve({ content: fullText, totalLength, extracted: false });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (error) {
|
||||||
|
reject(error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
reader.onerror = reject;
|
||||||
|
reader.readAsArrayBuffer(file);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 解析 PDF 文件,提取前 N 页的文本内容
|
||||||
|
* @param {File} file - PDF 文件
|
||||||
|
* @returns {Promise<{content: string, totalPages: number, extractedPages: number}>}
|
||||||
|
* - content: 提取的文本内容
|
||||||
|
* - totalPages: 文件总页数
|
||||||
|
* - extractedPages: 实际提取的页数(受 MAX_PDF_PAGES 限制)
|
||||||
|
*/
|
||||||
|
async function parsePDF(file: File): Promise<{ content: string; totalPages: number; extractedPages: number }> {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const reader = new FileReader();
|
||||||
|
reader.onload = async (e) => {
|
||||||
|
try {
|
||||||
|
const typedArray = new Uint8Array(e.target?.result as ArrayBuffer);
|
||||||
|
const pdf = await pdfjsLib.getDocument(typedArray).promise;
|
||||||
|
const totalPages = pdf.numPages;
|
||||||
|
const pagesToExtract = Math.min(totalPages, MAX_PDF_PAGES);
|
||||||
|
|
||||||
|
let fullText = '';
|
||||||
|
for (let i = 1; i <= pagesToExtract; i++) {
|
||||||
|
const page = await pdf.getPage(i);
|
||||||
|
const textContent = await page.getTextContent();
|
||||||
|
const pageText = textContent.items.map((item: any) => item.str).join(' ');
|
||||||
|
fullText += `${pageText}\n`;
|
||||||
|
}
|
||||||
|
|
||||||
|
resolve({ content: fullText, totalPages, extractedPages: pagesToExtract });
|
||||||
|
}
|
||||||
|
catch (error) {
|
||||||
|
reject(error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
reader.onerror = reject;
|
||||||
|
reader.readAsArrayBuffer(file);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取文件扩展名
|
||||||
|
* @param {string} filename - 文件名
|
||||||
|
* @returns {string} 小写的扩展名,无点号
|
||||||
|
*/
|
||||||
|
function getFileExtension(filename: string): string {
|
||||||
|
return filename.split('.').pop()?.toLowerCase() || '';
|
||||||
|
}
|
||||||
|
|
||||||
onChange(async (files) => {
|
onChange(async (files) => {
|
||||||
if (!files)
|
if (!files)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const arr = [] as FileItem[];
|
const arr = [] as FileItem[];
|
||||||
|
let totalContentLength = 0; // 跟踪总内容长度
|
||||||
|
|
||||||
|
// 先计算已有文件的总内容长度
|
||||||
|
filesStore.filesList.forEach((f) => {
|
||||||
|
if (f.fileType === 'text' && f.fileContent) {
|
||||||
|
totalContentLength += f.fileContent.length;
|
||||||
|
}
|
||||||
|
// 图片 base64 也计入(虽然转 token 时不同,但也要计算)
|
||||||
|
if (f.fileType === 'image' && f.base64) {
|
||||||
|
// base64 转 token 比例约 1:1.5,这里保守估计
|
||||||
|
totalContentLength += Math.floor(f.base64.length * 0.5);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
for (let i = 0; i < files!.length; i++) {
|
for (let i = 0; i < files!.length; i++) {
|
||||||
const file = files![i];
|
const file = files![i];
|
||||||
@@ -103,143 +403,261 @@ onChange(async (files) => {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const ext = getFileExtension(file.name);
|
||||||
const isImage = file.type.startsWith('image/');
|
const isImage = file.type.startsWith('image/');
|
||||||
|
const isExcel = ['xlsx', 'xls'].includes(ext);
|
||||||
|
const isWord = ext === 'docx';
|
||||||
|
const isPDF = ext === 'pdf';
|
||||||
|
const isText = isTextFile(file);
|
||||||
|
|
||||||
// 压缩并转换为base64
|
// 处理图片文件
|
||||||
let base64 = '';
|
|
||||||
let previewUrl = '';
|
|
||||||
if (isImage) {
|
if (isImage) {
|
||||||
try {
|
try {
|
||||||
// 先压缩图片
|
// 先压缩图片
|
||||||
const compressedBlob = await compressImage(file, 1024, 1024, 0.8);
|
const compressedBlob = await compressImage(file, 1024, 1024, 0.8);
|
||||||
// 再转换为 base64
|
// 再转换为 base64
|
||||||
base64 = await blobToBase64(compressedBlob);
|
const base64 = await blobToBase64(compressedBlob);
|
||||||
// 使用压缩后的图片作为预览
|
|
||||||
previewUrl = base64;
|
// 检查总长度(base64 保守估计占用)
|
||||||
|
const estimatedLength = Math.floor(base64.length * 0.5);
|
||||||
|
if (totalContentLength + estimatedLength > MAX_TOTAL_CONTENT_LENGTH) {
|
||||||
|
ElMessage.error(`添加 ${file.name} 会超过消息总长度限制(${MAX_TOTAL_CONTENT_LENGTH} 字符),已跳过`);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
totalContentLength += estimatedLength;
|
||||||
|
|
||||||
// 计算压缩比例
|
// 计算压缩比例
|
||||||
const originalSize = (file.size / 1024).toFixed(2);
|
const originalSize = (file.size / 1024).toFixed(2);
|
||||||
const compressedSize = (compressedBlob.size / 1024).toFixed(2);
|
const compressedSize = (compressedBlob.size / 1024).toFixed(2);
|
||||||
console.log(`图片压缩: ${file.name} - 原始: ${originalSize}KB, 压缩后: ${compressedSize}KB`);
|
console.log(`图片压缩: ${file.name} - 原始: ${originalSize}KB, 压缩后: ${compressedSize}KB`);
|
||||||
} catch (error) {
|
|
||||||
|
arr.push({
|
||||||
|
uid: crypto.randomUUID(),
|
||||||
|
name: file.name,
|
||||||
|
fileSize: file.size,
|
||||||
|
file,
|
||||||
|
maxWidth: '200px',
|
||||||
|
showDelIcon: true,
|
||||||
|
imgPreview: true,
|
||||||
|
imgVariant: 'square',
|
||||||
|
url: base64, // 使用压缩后的 base64 作为预览地址
|
||||||
|
isUploaded: true,
|
||||||
|
base64,
|
||||||
|
fileType: 'image',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
catch (error) {
|
||||||
console.error('压缩图片失败:', error);
|
console.error('压缩图片失败:', error);
|
||||||
ElMessage.error(`${file.name} 压缩失败`);
|
ElMessage.error(`${file.name} 压缩失败`);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// 处理 Excel 文件
|
||||||
|
else if (isExcel) {
|
||||||
|
try {
|
||||||
|
const result = await parseExcel(file);
|
||||||
|
|
||||||
|
// 检查总长度
|
||||||
|
if (totalContentLength + result.content.length > MAX_TOTAL_CONTENT_LENGTH) {
|
||||||
|
ElMessage.error(`添加 ${file.name} 会超过消息总长度限制(${MAX_TOTAL_CONTENT_LENGTH} 字符),已跳过`);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
totalContentLength += result.content.length;
|
||||||
|
|
||||||
arr.push({
|
arr.push({
|
||||||
uid: crypto.randomUUID(), // 不写 uid,文件列表展示不出来,elx 1.2.0 bug 待修复
|
uid: crypto.randomUUID(),
|
||||||
name: file.name,
|
name: file.name,
|
||||||
fileSize: file.size,
|
fileSize: file.size,
|
||||||
file,
|
file,
|
||||||
maxWidth: '200px',
|
maxWidth: '200px',
|
||||||
showDelIcon: true, // 显示删除图标
|
showDelIcon: true,
|
||||||
imgPreview: isImage, // 图片才显示预览
|
imgPreview: false,
|
||||||
imgVariant: 'square', // 图片预览的形状
|
isUploaded: true,
|
||||||
url: isImage ? previewUrl : undefined, // 使用压缩后的 base64 作为预览地址
|
fileContent: result.content,
|
||||||
isUploaded: true, // 直接标记为已完成
|
fileType: 'text',
|
||||||
base64: isImage ? base64 : undefined, // 保存压缩后的base64
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 提示信息
|
||||||
|
if (result.totalRows > MAX_EXCEL_ROWS) {
|
||||||
|
ElMessage.warning(`${file.name} 共 ${result.totalRows} 行,已提取前 ${result.extractedRows} 行`);
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(`Excel 解析: ${file.name} - 大小: ${(file.size / 1024).toFixed(2)}KB, 总行数: ${result.totalRows}, 已提取: ${result.extractedRows} 行, 内容长度: ${result.content.length} 字符`);
|
||||||
|
}
|
||||||
|
catch (error) {
|
||||||
|
console.error('解析 Excel 失败:', error);
|
||||||
|
ElMessage.error(`${file.name} 解析失败`);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 处理 Word 文档
|
||||||
|
else if (isWord) {
|
||||||
|
try {
|
||||||
|
const result = await parseWord(file);
|
||||||
|
|
||||||
|
// 检查总长度
|
||||||
|
if (totalContentLength + result.content.length > MAX_TOTAL_CONTENT_LENGTH) {
|
||||||
|
ElMessage.error(`添加 ${file.name} 会超过消息总长度限制(${MAX_TOTAL_CONTENT_LENGTH} 字符),已跳过`);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
totalContentLength += result.content.length;
|
||||||
|
|
||||||
|
arr.push({
|
||||||
|
uid: crypto.randomUUID(),
|
||||||
|
name: file.name,
|
||||||
|
fileSize: file.size,
|
||||||
|
file,
|
||||||
|
maxWidth: '200px',
|
||||||
|
showDelIcon: true,
|
||||||
|
imgPreview: false,
|
||||||
|
isUploaded: true,
|
||||||
|
fileContent: result.content,
|
||||||
|
fileType: 'text',
|
||||||
|
});
|
||||||
|
|
||||||
|
// 提示信息
|
||||||
|
if (result.extracted) {
|
||||||
|
ElMessage.warning(`${file.name} 共 ${result.totalLength} 字符,已提取前 ${MAX_WORD_LENGTH} 字符`);
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(`Word 解析: ${file.name} - 大小: ${(file.size / 1024).toFixed(2)}KB, 总长度: ${result.totalLength}, 已提取: ${result.content.length} 字符`);
|
||||||
|
}
|
||||||
|
catch (error) {
|
||||||
|
console.error('解析 Word 失败:', error);
|
||||||
|
ElMessage.error(`${file.name} 解析失败`);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 处理 PDF 文件
|
||||||
|
else if (isPDF) {
|
||||||
|
try {
|
||||||
|
const result = await parsePDF(file);
|
||||||
|
|
||||||
|
// 检查总长度
|
||||||
|
if (totalContentLength + result.content.length > MAX_TOTAL_CONTENT_LENGTH) {
|
||||||
|
ElMessage.error(`添加 ${file.name} 会超过消息总长度限制(${MAX_TOTAL_CONTENT_LENGTH} 字符),已跳过`);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
totalContentLength += result.content.length;
|
||||||
|
|
||||||
|
arr.push({
|
||||||
|
uid: crypto.randomUUID(),
|
||||||
|
name: file.name,
|
||||||
|
fileSize: file.size,
|
||||||
|
file,
|
||||||
|
maxWidth: '200px',
|
||||||
|
showDelIcon: true,
|
||||||
|
imgPreview: false,
|
||||||
|
isUploaded: true,
|
||||||
|
fileContent: result.content,
|
||||||
|
fileType: 'text',
|
||||||
|
});
|
||||||
|
|
||||||
|
// 提示信息
|
||||||
|
if (result.totalPages > MAX_PDF_PAGES) {
|
||||||
|
ElMessage.warning(`${file.name} 共 ${result.totalPages} 页,已提取前 ${result.extractedPages} 页`);
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(`PDF 解析: ${file.name} - 大小: ${(file.size / 1024).toFixed(2)}KB, 总页数: ${result.totalPages}, 已提取: ${result.extractedPages} 页, 内容长度: ${result.content.length} 字符`);
|
||||||
|
}
|
||||||
|
catch (error) {
|
||||||
|
console.error('解析 PDF 失败:', error);
|
||||||
|
ElMessage.error(`${file.name} 解析失败`);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 处理文本文件
|
||||||
|
else if (isText) {
|
||||||
|
try {
|
||||||
|
// 读取文本文件内容
|
||||||
|
const content = await readTextFile(file);
|
||||||
|
|
||||||
|
// 限制单个文本文件长度
|
||||||
|
let finalContent = content;
|
||||||
|
let truncated = false;
|
||||||
|
if (content.length > MAX_TEXT_FILE_LENGTH) {
|
||||||
|
finalContent = content.substring(0, MAX_TEXT_FILE_LENGTH);
|
||||||
|
truncated = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查总长度
|
||||||
|
if (totalContentLength + finalContent.length > MAX_TOTAL_CONTENT_LENGTH) {
|
||||||
|
ElMessage.error(`添加 ${file.name} 会超过消息总长度限制(${MAX_TOTAL_CONTENT_LENGTH} 字符),已跳过`);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
totalContentLength += finalContent.length;
|
||||||
|
|
||||||
|
arr.push({
|
||||||
|
uid: crypto.randomUUID(),
|
||||||
|
name: file.name,
|
||||||
|
fileSize: file.size,
|
||||||
|
file,
|
||||||
|
maxWidth: '200px',
|
||||||
|
showDelIcon: true,
|
||||||
|
imgPreview: false,
|
||||||
|
isUploaded: true,
|
||||||
|
fileContent: finalContent,
|
||||||
|
fileType: 'text',
|
||||||
|
});
|
||||||
|
|
||||||
|
// 提示信息
|
||||||
|
if (truncated) {
|
||||||
|
ElMessage.warning(`${file.name} 共 ${content.length} 字符,已提取前 ${MAX_TEXT_FILE_LENGTH} 字符`);
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(`文本文件读取: ${file.name} - 大小: ${(file.size / 1024).toFixed(2)}KB, 内容长度: ${content.length} 字符`);
|
||||||
|
}
|
||||||
|
catch (error) {
|
||||||
|
console.error('读取文件失败:', error);
|
||||||
|
ElMessage.error(`${file.name} 读取失败`);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 不支持的文件类型
|
||||||
|
else {
|
||||||
|
ElMessage.warning(`${file.name} 不是支持的文件类型`);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (arr.length > 0) {
|
if (arr.length > 0) {
|
||||||
filesStore.setFilesList([...filesStore.filesList, ...arr]);
|
filesStore.setFilesList([...filesStore.filesList, ...arr]);
|
||||||
ElMessage.success(`已添加 ${arr.length} 个文件`);
|
ElMessage.success(`已添加 ${arr.length} 个文件,当前总内容长度约 ${totalContentLength} 字符`);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 重置文件选择器
|
// 重置文件选择器
|
||||||
nextTick(() => reset());
|
nextTick(() => reset());
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 打开文件选择对话框
|
||||||
|
*/
|
||||||
function handleUploadFiles() {
|
function handleUploadFiles() {
|
||||||
open();
|
open();
|
||||||
popoverRef.value.hide();
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="files-select">
|
<div class="files-select">
|
||||||
<Popover
|
<!-- 直接点击上传,添加 tooltip 提示 -->
|
||||||
ref="popoverRef"
|
<el-tooltip
|
||||||
placement="top-start"
|
content="上传文件或图片(支持 Excel、Word、PDF、代码文件等,最大3MB)"
|
||||||
:offset="[4, 0]"
|
placement="top"
|
||||||
popover-class="popover-content"
|
|
||||||
:popover-style="popoverStyle"
|
|
||||||
trigger="clickTarget"
|
|
||||||
>
|
>
|
||||||
<template #trigger>
|
|
||||||
<div
|
<div
|
||||||
class="flex items-center gap-4px p-10px rounded-10px cursor-pointer font-size-14px border-1px border-[rgba(0,0,0,0.08)] border-solid hover:bg-[rgba(0,0,0,.04)]"
|
class="flex items-center gap-4px p-10px rounded-10px cursor-pointer font-size-14px border-1px border-[rgba(0,0,0,0.08)] border-solid hover:bg-[rgba(0,0,0,.04)]"
|
||||||
|
@click="handleUploadFiles"
|
||||||
>
|
>
|
||||||
<el-icon>
|
<el-icon>
|
||||||
<Paperclip />
|
<Paperclip />
|
||||||
</el-icon>
|
</el-icon>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</el-tooltip>
|
||||||
|
|
||||||
<div class="popover-content-box">
|
|
||||||
<div
|
|
||||||
class="popover-content-item flex items-center gap-4px p-10px rounded-10px cursor-pointer font-size-14px hover:bg-[rgba(0,0,0,.04)]"
|
|
||||||
@click="handleUploadFiles"
|
|
||||||
>
|
|
||||||
<el-icon>
|
|
||||||
<Upload />
|
|
||||||
</el-icon>
|
|
||||||
<div class="font-size-14px">
|
|
||||||
上传文件或图片
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<Popover
|
|
||||||
placement="right-end"
|
|
||||||
:offset="[8, 4]"
|
|
||||||
popover-class="popover-content"
|
|
||||||
:popover-style="popoverStyle"
|
|
||||||
trigger="hover"
|
|
||||||
:hover-delay="100"
|
|
||||||
>
|
|
||||||
<template #trigger>
|
|
||||||
<div
|
|
||||||
class="popover-content-item flex items-center gap-4px p-10px rounded-10px cursor-pointer font-size-14px hover:bg-[rgba(0,0,0,.04)]"
|
|
||||||
>
|
|
||||||
<SvgIcon name="code" size="16" />
|
|
||||||
<div class="font-size-14px">
|
|
||||||
上传代码
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<el-icon class="ml-auto">
|
|
||||||
<ArrowRight />
|
|
||||||
</el-icon>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<div class="popover-content-box">
|
|
||||||
<div
|
|
||||||
class="popover-content-item flex items-center gap-4px p-10px rounded-10px cursor-pointer font-size-14px hover:bg-[rgba(0,0,0,.04)]"
|
|
||||||
@click="
|
|
||||||
() => {
|
|
||||||
ElMessage.warning('暂未开放');
|
|
||||||
}
|
|
||||||
"
|
|
||||||
>
|
|
||||||
代码文件
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div
|
|
||||||
class="popover-content-item flex items-center gap-4px p-10px rounded-10px cursor-pointer font-size-14px hover:bg-[rgba(0,0,0,.04)]"
|
|
||||||
@click="
|
|
||||||
() => {
|
|
||||||
ElMessage.warning('暂未开放');
|
|
||||||
}
|
|
||||||
"
|
|
||||||
>
|
|
||||||
代码文件夹
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</Popover>
|
|
||||||
</div>
|
|
||||||
</Popover>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import type { BubbleProps } from 'vue-element-plus-x/types/Bubble';
|
|||||||
import type { BubbleListInstance } from 'vue-element-plus-x/types/BubbleList';
|
import type { BubbleListInstance } from 'vue-element-plus-x/types/BubbleList';
|
||||||
import type { FilesCardProps } from 'vue-element-plus-x/types/FilesCard';
|
import type { FilesCardProps } from 'vue-element-plus-x/types/FilesCard';
|
||||||
import type { ThinkingStatus } from 'vue-element-plus-x/types/Thinking';
|
import type { ThinkingStatus } from 'vue-element-plus-x/types/Thinking';
|
||||||
import { ArrowLeftBold, ArrowRightBold, Loading } from '@element-plus/icons-vue';
|
import { ArrowLeftBold, ArrowRightBold, Document, Loading } from '@element-plus/icons-vue';
|
||||||
import { ElIcon, ElMessage } from 'element-plus';
|
import { ElIcon, ElMessage } from 'element-plus';
|
||||||
import { useHookFetch } from 'hook-fetch/vue';
|
import { useHookFetch } from 'hook-fetch/vue';
|
||||||
import { computed, nextTick, ref, watch } from 'vue';
|
import { computed, nextTick, ref, watch } from 'vue';
|
||||||
@@ -30,6 +30,7 @@ type MessageItem = BubbleProps & {
|
|||||||
thinlCollapse?: boolean;
|
thinlCollapse?: boolean;
|
||||||
reasoning_content?: string;
|
reasoning_content?: string;
|
||||||
images?: Array<{ url: string; name?: string }>; // 用户消息中的图片列表
|
images?: Array<{ url: string; name?: string }>; // 用户消息中的图片列表
|
||||||
|
files?: Array<{ name: string; size: number }>; // 用户消息中的文件列表
|
||||||
};
|
};
|
||||||
|
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
@@ -114,7 +115,11 @@ watch(
|
|||||||
{ immediate: true, deep: true },
|
{ immediate: true, deep: true },
|
||||||
);
|
);
|
||||||
|
|
||||||
// 封装数据处理逻辑
|
/**
|
||||||
|
* 处理流式响应的数据块
|
||||||
|
* 解析 AI 返回的数据,更新消息内容和思考状态
|
||||||
|
* @param {AnyObject} chunk - 流式响应的数据块
|
||||||
|
*/
|
||||||
function handleDataChunk(chunk: AnyObject) {
|
function handleDataChunk(chunk: AnyObject) {
|
||||||
try {
|
try {
|
||||||
// 安全获取 delta 和 content
|
// 安全获取 delta 和 content
|
||||||
@@ -170,11 +175,19 @@ function handleDataChunk(chunk: AnyObject) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 封装错误处理逻辑
|
/**
|
||||||
|
* 处理错误信息
|
||||||
|
* @param {any} err - 错误对象
|
||||||
|
*/
|
||||||
function handleError(err: any) {
|
function handleError(err: any) {
|
||||||
console.error('Fetch error:', err);
|
console.error('Fetch error:', err);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发送消息并处理流式响应
|
||||||
|
* 支持发送文本、图片和文件
|
||||||
|
* @param {string} chatContent - 用户输入的文本内容
|
||||||
|
*/
|
||||||
async function startSSE(chatContent: string) {
|
async function startSSE(chatContent: string) {
|
||||||
if (isSending.value)
|
if (isSending.value)
|
||||||
return;
|
return;
|
||||||
@@ -192,14 +205,21 @@ async function startSSE(chatContent: string) {
|
|||||||
// 清空输入框
|
// 清空输入框
|
||||||
inputValue.value = '';
|
inputValue.value = '';
|
||||||
|
|
||||||
// 获取当前上传的图片(在清空之前保存)
|
// 获取当前上传的图片和文件(在清空之前保存)
|
||||||
const imageFiles = filesStore.filesList.filter(f => f.isUploaded && f.file.type.startsWith('image/'));
|
const imageFiles = filesStore.filesList.filter(f => f.isUploaded && f.fileType === 'image');
|
||||||
|
const textFiles = filesStore.filesList.filter(f => f.isUploaded && f.fileType === 'text');
|
||||||
|
|
||||||
const images = imageFiles.map(f => ({
|
const images = imageFiles.map(f => ({
|
||||||
url: f.base64!, // 使用base64作为URL
|
url: f.base64!, // 使用base64作为URL
|
||||||
name: f.name,
|
name: f.name,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
addMessage(chatContent, true, images);
|
const files = textFiles.map(f => ({
|
||||||
|
name: f.name!,
|
||||||
|
size: f.fileSize!,
|
||||||
|
}));
|
||||||
|
|
||||||
|
addMessage(chatContent, true, images, files);
|
||||||
addMessage('', false);
|
addMessage('', false);
|
||||||
|
|
||||||
// 立即清空文件列表(不要等到响应完成)
|
// 立即清空文件列表(不要等到响应完成)
|
||||||
@@ -208,13 +228,13 @@ async function startSSE(chatContent: string) {
|
|||||||
// 这里有必要调用一下 BubbleList 组件的滚动到底部 手动触发 自动滚动
|
// 这里有必要调用一下 BubbleList 组件的滚动到底部 手动触发 自动滚动
|
||||||
bubbleListRef.value?.scrollToBottom();
|
bubbleListRef.value?.scrollToBottom();
|
||||||
|
|
||||||
// 组装消息内容,支持图片
|
// 组装消息内容,支持图片和文件
|
||||||
const messagesContent = bubbleItems.value.slice(0, -1).slice(-6).map((item: MessageItem) => {
|
const messagesContent = bubbleItems.value.slice(0, -1).slice(-6).map((item: MessageItem) => {
|
||||||
const baseMessage: any = {
|
const baseMessage: any = {
|
||||||
role: item.role,
|
role: item.role,
|
||||||
};
|
};
|
||||||
|
|
||||||
// 如果是用户消息且有附件(图片),组装成数组格式
|
// 如果是用户消息且有附件(图片或文件),组装成数组格式
|
||||||
if (item.role === 'user' && item.key === bubbleItems.value.length - 2) {
|
if (item.role === 'user' && item.key === bubbleItems.value.length - 2) {
|
||||||
// 当前发送的消息
|
// 当前发送的消息
|
||||||
const contentArray: any[] = [];
|
const contentArray: any[] = [];
|
||||||
@@ -227,6 +247,26 @@ async function startSSE(chatContent: string) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 添加文本文件内容(使用XML格式)
|
||||||
|
if (textFiles.length > 0) {
|
||||||
|
let fileContent = '\n\n';
|
||||||
|
textFiles.forEach((fileItem, index) => {
|
||||||
|
fileContent += `<ATTACHMENT_FILE>\n`;
|
||||||
|
fileContent += `<FILE_INDEX>File ${index + 1}</FILE_INDEX>\n`;
|
||||||
|
fileContent += `<FILE_NAME>${fileItem.name}</FILE_NAME>\n`;
|
||||||
|
fileContent += `<FILE_CONTENT>\n${fileItem.fileContent}\n</FILE_CONTENT>\n`;
|
||||||
|
fileContent += `</ATTACHMENT_FILE>\n`;
|
||||||
|
if (index < textFiles.length - 1) {
|
||||||
|
fileContent += '\n';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
contentArray.push({
|
||||||
|
type: 'text',
|
||||||
|
text: fileContent,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// 添加图片内容(使用之前保存的 imageFiles)
|
// 添加图片内容(使用之前保存的 imageFiles)
|
||||||
imageFiles.forEach((fileItem) => {
|
imageFiles.forEach((fileItem) => {
|
||||||
if (fileItem.base64) {
|
if (fileItem.base64) {
|
||||||
@@ -240,7 +280,7 @@ async function startSSE(chatContent: string) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// 如果有图片或文件,使用数组格式
|
// 如果有图片或文件,使用数组格式
|
||||||
if (contentArray.length > 1 || imageFiles.length > 0) {
|
if (contentArray.length > 1 || imageFiles.length > 0 || textFiles.length > 0) {
|
||||||
baseMessage.content = contentArray;
|
baseMessage.content = contentArray;
|
||||||
} else {
|
} else {
|
||||||
baseMessage.content = item.content;
|
baseMessage.content = item.content;
|
||||||
@@ -287,10 +327,18 @@ async function startSSE(chatContent: string) {
|
|||||||
latest.thinkingStatus = 'end';
|
latest.thinkingStatus = 'end';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 保存聊天记录到 chatMap(本地缓存,刷新后可恢复)
|
||||||
|
if (route.params?.id && route.params.id !== 'not_login') {
|
||||||
|
chatStore.chatMap[`${route.params.id}`] = bubbleItems.value as any;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 中断请求
|
/**
|
||||||
|
* 中断正在进行的请求
|
||||||
|
* 停止流式响应并重置状态
|
||||||
|
*/
|
||||||
async function cancelSSE() {
|
async function cancelSSE() {
|
||||||
try {
|
try {
|
||||||
cancel(); // 直接调用,无需参数
|
cancel(); // 直接调用,无需参数
|
||||||
@@ -309,8 +357,14 @@ async function cancelSSE() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 添加消息 - 维护聊天记录
|
/**
|
||||||
function addMessage(message: string, isUser: boolean, images?: Array<{ url: string; name?: string }>) {
|
* 添加消息到聊天列表
|
||||||
|
* @param {string} message - 消息内容
|
||||||
|
* @param {boolean} isUser - 是否为用户消息
|
||||||
|
* @param {Array<{url: string, name?: string}>} images - 图片列表(可选)
|
||||||
|
* @param {Array<{name: string, size: number}>} files - 文件列表(可选)
|
||||||
|
*/
|
||||||
|
function addMessage(message: string, isUser: boolean, images?: Array<{ url: string; name?: string }>, files?: Array<{ name: string; size: number }>) {
|
||||||
const i = bubbleItems.value.length;
|
const i = bubbleItems.value.length;
|
||||||
const obj: MessageItem = {
|
const obj: MessageItem = {
|
||||||
key: i,
|
key: i,
|
||||||
@@ -328,14 +382,25 @@ function addMessage(message: string, isUser: boolean, images?: Array<{ url: stri
|
|||||||
thinlCollapse: false,
|
thinlCollapse: false,
|
||||||
noStyle: !isUser,
|
noStyle: !isUser,
|
||||||
images: images && images.length > 0 ? images : undefined,
|
images: images && images.length > 0 ? images : undefined,
|
||||||
|
files: files && files.length > 0 ? files : undefined,
|
||||||
};
|
};
|
||||||
bubbleItems.value.push(obj);
|
bubbleItems.value.push(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 展开收起 事件展示
|
/**
|
||||||
|
* 处理思考链展开/收起状态变化
|
||||||
|
* @param {Object} payload - 状态变化的载荷
|
||||||
|
* @param {boolean} payload.value - 展开/收起状态
|
||||||
|
* @param {ThinkingStatus} payload.status - 思考状态
|
||||||
|
*/
|
||||||
function handleChange(payload: { value: boolean; status: ThinkingStatus }) {
|
function handleChange(payload: { value: boolean; status: ThinkingStatus }) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除文件卡片
|
||||||
|
* @param {FilesCardProps} _item - 文件卡片项(未使用)
|
||||||
|
* @param {number} index - 要删除的文件索引
|
||||||
|
*/
|
||||||
function handleDeleteCard(_item: FilesCardProps, index: number) {
|
function handleDeleteCard(_item: FilesCardProps, index: number) {
|
||||||
filesStore.deleteFileByIndex(index);
|
filesStore.deleteFileByIndex(index);
|
||||||
}
|
}
|
||||||
@@ -356,14 +421,21 @@ watch(
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
// 复制
|
/**
|
||||||
|
* 复制消息内容到剪贴板
|
||||||
|
* @param {any} item - 消息项
|
||||||
|
*/
|
||||||
function copy(item: any) {
|
function copy(item: any) {
|
||||||
navigator.clipboard.writeText(item.content || '')
|
navigator.clipboard.writeText(item.content || '')
|
||||||
.then(() => ElMessage.success('已复制到剪贴板'))
|
.then(() => ElMessage.success('已复制到剪贴板'))
|
||||||
.catch(() => ElMessage.error('复制失败'));
|
.catch(() => ElMessage.error('复制失败'));
|
||||||
}
|
}
|
||||||
|
|
||||||
// 图片预览
|
/**
|
||||||
|
* 图片预览
|
||||||
|
* 在新窗口中打开图片
|
||||||
|
* @param {string} url - 图片 URL
|
||||||
|
*/
|
||||||
function handleImagePreview(url: string) {
|
function handleImagePreview(url: string) {
|
||||||
window.open(url, '_blank');
|
window.open(url, '_blank');
|
||||||
}
|
}
|
||||||
@@ -383,7 +455,7 @@ function handleImagePreview(url: string) {
|
|||||||
<template #content="{ item }">
|
<template #content="{ item }">
|
||||||
<!-- chat 内容走 markdown -->
|
<!-- chat 内容走 markdown -->
|
||||||
<XMarkdown v-if="item.content && (item.role === 'assistant' || item.role === 'system')" class="markdown-body" :markdown="item.content" :themes="{ light: 'github-light', dark: 'github-dark' }" default-theme-mode="dark" />
|
<XMarkdown v-if="item.content && (item.role === 'assistant' || item.role === 'system')" class="markdown-body" :markdown="item.content" :themes="{ light: 'github-light', dark: 'github-dark' }" default-theme-mode="dark" />
|
||||||
<!-- user 内容 纯文本 + 图片 -->
|
<!-- user 内容 纯文本 + 图片 + 文件 -->
|
||||||
<div v-if="item.role === 'user'" class="user-content-wrapper">
|
<div v-if="item.role === 'user'" class="user-content-wrapper">
|
||||||
<!-- 图片列表 -->
|
<!-- 图片列表 -->
|
||||||
<div v-if="item.images && item.images.length > 0" class="user-images">
|
<div v-if="item.images && item.images.length > 0" class="user-images">
|
||||||
@@ -396,6 +468,20 @@ function handleImagePreview(url: string) {
|
|||||||
@click="() => handleImagePreview(image.url)"
|
@click="() => handleImagePreview(image.url)"
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
|
<!-- 文件列表 -->
|
||||||
|
<div v-if="item.files && item.files.length > 0" class="user-files">
|
||||||
|
<div
|
||||||
|
v-for="(file, index) in item.files"
|
||||||
|
:key="index"
|
||||||
|
class="user-file-item"
|
||||||
|
>
|
||||||
|
<el-icon class="file-icon">
|
||||||
|
<Document />
|
||||||
|
</el-icon>
|
||||||
|
<span class="file-name">{{ file.name }}</span>
|
||||||
|
<span class="file-size">{{ (file.size / 1024).toFixed(2) }} KB</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<!-- 文本内容 -->
|
<!-- 文本内容 -->
|
||||||
<div v-if="item.content" class="user-content">
|
<div v-if="item.content" class="user-content">
|
||||||
{{ item.content }}
|
{{ item.content }}
|
||||||
@@ -523,6 +609,35 @@ function handleImagePreview(url: string) {
|
|||||||
transform: scale(1.05);
|
transform: scale(1.05);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.user-files {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 6px;
|
||||||
|
margin-bottom: 4px;
|
||||||
|
}
|
||||||
|
.user-file-item {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
padding: 8px 12px;
|
||||||
|
background: rgba(0, 0, 0, 0.05);
|
||||||
|
border-radius: 6px;
|
||||||
|
font-size: 13px;
|
||||||
|
.file-icon {
|
||||||
|
font-size: 16px;
|
||||||
|
color: #409eff;
|
||||||
|
}
|
||||||
|
.file-name {
|
||||||
|
flex: 1;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
.file-size {
|
||||||
|
color: #909399;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
}
|
||||||
.user-content {
|
.user-content {
|
||||||
// 换行
|
// 换行
|
||||||
white-space: pre-wrap;
|
white-space: pre-wrap;
|
||||||
|
|||||||
@@ -37,6 +37,9 @@ export const useChatStore = defineStore('chat', () => {
|
|||||||
thinkingStatus: 'end',
|
thinkingStatus: 'end',
|
||||||
content: extractThkContentAfter(item.content as string),
|
content: extractThkContentAfter(item.content as string),
|
||||||
thinlCollapse: false,
|
thinlCollapse: false,
|
||||||
|
// 保留图片和文件信息
|
||||||
|
images: item.images,
|
||||||
|
files: item.files,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -8,6 +8,8 @@ export interface FileItem extends FilesCardProps {
|
|||||||
isUploaded?: boolean; // 是否已上传
|
isUploaded?: boolean; // 是否已上传
|
||||||
uploadProgress?: number; // 上传进度
|
uploadProgress?: number; // 上传进度
|
||||||
base64?: string; // 图片的base64编码
|
base64?: string; // 图片的base64编码
|
||||||
|
fileContent?: string; // 文本文件的内容
|
||||||
|
fileType?: 'image' | 'text'; // 文件类型
|
||||||
}
|
}
|
||||||
|
|
||||||
export const useFilesStore = defineStore('files', () => {
|
export const useFilesStore = defineStore('files', () => {
|
||||||
|
|||||||
Reference in New Issue
Block a user