generated from template/vite-react-template
Compare commits
2 Commits
263218b481
...
f858d1aa5b
| Author | SHA1 | Date | |
|---|---|---|---|
| f858d1aa5b | |||
| 87d48e6fc3 |
2
.cnb.yml
2
.cnb.yml
@@ -4,7 +4,7 @@ include:
|
|||||||
|
|
||||||
.common_env: &common_env
|
.common_env: &common_env
|
||||||
env:
|
env:
|
||||||
TO_REPO: template/vite-react-template
|
TO_REPO: kevisual/pdf
|
||||||
TO_URL: git.xiongxiao.me
|
TO_URL: git.xiongxiao.me
|
||||||
imports:
|
imports:
|
||||||
- https://cnb.cool/kevisual/env/-/blob/main/.env.development
|
- https://cnb.cool/kevisual/env/-/blob/main/.env.development
|
||||||
|
|||||||
@@ -5,8 +5,7 @@
|
|||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
<link rel="icon" type="image/png" href="https://kevisual.xiongxiao.me/root/center/panda.png" />
|
<link rel="icon" type="image/png" href="https://kevisual.xiongxiao.me/root/center/panda.png" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<title>Vite + React + TS</title>
|
<title>PDF 模块</title>
|
||||||
<link rel="stylesheet" href="/src/index.css" />
|
|
||||||
<style>
|
<style>
|
||||||
html,
|
html,
|
||||||
body {
|
body {
|
||||||
|
|||||||
13
package.json
13
package.json
@@ -1,15 +1,15 @@
|
|||||||
{
|
{
|
||||||
"name": "vite-react",
|
"name": "@kevisual/pdf",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "0.0.1",
|
"version": "0.0.3",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"basename": "/",
|
"basename": "/root/pdf",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite",
|
"dev": "vite",
|
||||||
"build": "vite build",
|
"build": "vite build",
|
||||||
"preview": "vite preview",
|
"preview": "vite preview",
|
||||||
"ui": "pnpm dlx shadcn@latest add ",
|
"ui": "pnpm dlx shadcn@latest add ",
|
||||||
"pub": "envision deploy ./dist -k vite-react -v 0.0.1"
|
"pub": "envision deploy ./dist -k pdf -v 0.0.4 -y y -u"
|
||||||
},
|
},
|
||||||
"files": [
|
"files": [
|
||||||
"dist"
|
"dist"
|
||||||
@@ -20,14 +20,18 @@
|
|||||||
"@kevisual/router": "0.0.70",
|
"@kevisual/router": "0.0.70",
|
||||||
"@radix-ui/react-slot": "^1.2.4",
|
"@radix-ui/react-slot": "^1.2.4",
|
||||||
"@tanstack/react-router": "^1.158.0",
|
"@tanstack/react-router": "^1.158.0",
|
||||||
|
"class-variance-authority": "^0.7.1",
|
||||||
"clsx": "^2.1.1",
|
"clsx": "^2.1.1",
|
||||||
"dayjs": "^1.11.19",
|
"dayjs": "^1.11.19",
|
||||||
"es-toolkit": "^1.44.0",
|
"es-toolkit": "^1.44.0",
|
||||||
"lucide-react": "^0.563.0",
|
"lucide-react": "^0.563.0",
|
||||||
"nanoid": "^5.1.6",
|
"nanoid": "^5.1.6",
|
||||||
|
"pdfjs-dist": "^5.4.624",
|
||||||
"react": "^19.2.4",
|
"react": "^19.2.4",
|
||||||
"react-dom": "^19.2.4",
|
"react-dom": "^19.2.4",
|
||||||
|
"react-dropzone": "^14.4.0",
|
||||||
"react-hook-form": "^7.71.1",
|
"react-hook-form": "^7.71.1",
|
||||||
|
"react-pdf": "^10.3.0",
|
||||||
"zustand": "^5.0.11"
|
"zustand": "^5.0.11"
|
||||||
},
|
},
|
||||||
"publishConfig": {
|
"publishConfig": {
|
||||||
@@ -40,6 +44,7 @@
|
|||||||
"@tanstack/react-router-devtools": "^1.158.0",
|
"@tanstack/react-router-devtools": "^1.158.0",
|
||||||
"@tanstack/router-plugin": "^1.158.0",
|
"@tanstack/router-plugin": "^1.158.0",
|
||||||
"@types/node": "^25.2.0",
|
"@types/node": "^25.2.0",
|
||||||
|
"@types/pdfjs-dist": "^2.10.378",
|
||||||
"@types/react": "^19.2.10",
|
"@types/react": "^19.2.10",
|
||||||
"@types/react-dom": "^19.2.3",
|
"@types/react-dom": "^19.2.3",
|
||||||
"@vitejs/plugin-react": "^5.1.3",
|
"@vitejs/plugin-react": "^5.1.3",
|
||||||
|
|||||||
263
pnpm-lock.yaml
generated
263
pnpm-lock.yaml
generated
@@ -17,6 +17,9 @@ importers:
|
|||||||
'@tanstack/react-router':
|
'@tanstack/react-router':
|
||||||
specifier: ^1.158.0
|
specifier: ^1.158.0
|
||||||
version: 1.158.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
|
version: 1.158.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
|
||||||
|
class-variance-authority:
|
||||||
|
specifier: ^0.7.1
|
||||||
|
version: 0.7.1
|
||||||
clsx:
|
clsx:
|
||||||
specifier: ^2.1.1
|
specifier: ^2.1.1
|
||||||
version: 2.1.1
|
version: 2.1.1
|
||||||
@@ -32,15 +35,24 @@ importers:
|
|||||||
nanoid:
|
nanoid:
|
||||||
specifier: ^5.1.6
|
specifier: ^5.1.6
|
||||||
version: 5.1.6
|
version: 5.1.6
|
||||||
|
pdfjs-dist:
|
||||||
|
specifier: ^5.4.624
|
||||||
|
version: 5.4.624
|
||||||
react:
|
react:
|
||||||
specifier: ^19.2.4
|
specifier: ^19.2.4
|
||||||
version: 19.2.4
|
version: 19.2.4
|
||||||
react-dom:
|
react-dom:
|
||||||
specifier: ^19.2.4
|
specifier: ^19.2.4
|
||||||
version: 19.2.4(react@19.2.4)
|
version: 19.2.4(react@19.2.4)
|
||||||
|
react-dropzone:
|
||||||
|
specifier: ^14.4.0
|
||||||
|
version: 14.4.0(react@19.2.4)
|
||||||
react-hook-form:
|
react-hook-form:
|
||||||
specifier: ^7.71.1
|
specifier: ^7.71.1
|
||||||
version: 7.71.1(react@19.2.4)
|
version: 7.71.1(react@19.2.4)
|
||||||
|
react-pdf:
|
||||||
|
specifier: ^10.3.0
|
||||||
|
version: 10.3.0(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
|
||||||
zustand:
|
zustand:
|
||||||
specifier: ^5.0.11
|
specifier: ^5.0.11
|
||||||
version: 5.0.11(@types/react@19.2.10)(immer@10.1.1)(react@19.2.4)(use-sync-external-store@1.6.0(react@19.2.4))
|
version: 5.0.11(@types/react@19.2.10)(immer@10.1.1)(react@19.2.4)(use-sync-external-store@1.6.0(react@19.2.4))
|
||||||
@@ -63,6 +75,9 @@ importers:
|
|||||||
'@types/node':
|
'@types/node':
|
||||||
specifier: ^25.2.0
|
specifier: ^25.2.0
|
||||||
version: 25.2.0
|
version: 25.2.0
|
||||||
|
'@types/pdfjs-dist':
|
||||||
|
specifier: ^2.10.378
|
||||||
|
version: 2.10.378
|
||||||
'@types/react':
|
'@types/react':
|
||||||
specifier: ^19.2.10
|
specifier: ^19.2.10
|
||||||
version: 19.2.10
|
version: 19.2.10
|
||||||
@@ -622,6 +637,81 @@ packages:
|
|||||||
'@types/react':
|
'@types/react':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
|
'@napi-rs/canvas-android-arm64@0.1.89':
|
||||||
|
resolution: {integrity: sha512-CXxQTXsjtQqKGENS8Ejv9pZOFJhOPIl2goenS+aU8dY4DygvkyagDhy/I07D1YLqrDtPvLEX5zZHt8qUdnuIpQ==}
|
||||||
|
engines: {node: '>= 10'}
|
||||||
|
cpu: [arm64]
|
||||||
|
os: [android]
|
||||||
|
|
||||||
|
'@napi-rs/canvas-darwin-arm64@0.1.89':
|
||||||
|
resolution: {integrity: sha512-k29cR/Zl20WLYM7M8YePevRu2VQRaKcRedYr1V/8FFHkyIQ8kShEV+MPoPGi+znvmd17Eqjy2Pk2F2kpM2umVg==}
|
||||||
|
engines: {node: '>= 10'}
|
||||||
|
cpu: [arm64]
|
||||||
|
os: [darwin]
|
||||||
|
|
||||||
|
'@napi-rs/canvas-darwin-x64@0.1.89':
|
||||||
|
resolution: {integrity: sha512-iUragqhBrA5FqU13pkhYBDbUD1WEAIlT8R2+fj6xHICY2nemzwMUI8OENDhRh7zuL06YDcRwENbjAVxOmaX9jg==}
|
||||||
|
engines: {node: '>= 10'}
|
||||||
|
cpu: [x64]
|
||||||
|
os: [darwin]
|
||||||
|
|
||||||
|
'@napi-rs/canvas-linux-arm-gnueabihf@0.1.89':
|
||||||
|
resolution: {integrity: sha512-y3SM9sfDWasY58ftoaI09YBFm35Ig8tosZqgahLJ2WGqawCusGNPV9P0/4PsrLOCZqGg629WxexQMY25n7zcvA==}
|
||||||
|
engines: {node: '>= 10'}
|
||||||
|
cpu: [arm]
|
||||||
|
os: [linux]
|
||||||
|
|
||||||
|
'@napi-rs/canvas-linux-arm64-gnu@0.1.89':
|
||||||
|
resolution: {integrity: sha512-NEoF9y8xq5fX8HG8aZunBom1ILdTwt7ayBzSBIwrmitk7snj4W6Fz/yN/ZOmlM1iyzHDNX5Xn0n+VgWCF8BEdA==}
|
||||||
|
engines: {node: '>= 10'}
|
||||||
|
cpu: [arm64]
|
||||||
|
os: [linux]
|
||||||
|
libc: [glibc]
|
||||||
|
|
||||||
|
'@napi-rs/canvas-linux-arm64-musl@0.1.89':
|
||||||
|
resolution: {integrity: sha512-UQQkIEzV12/l60j1ziMjZ+mtodICNUbrd205uAhbyTw0t60CrC/EsKb5/aJWGq1wM0agvcgZV72JJCKfLS6+4w==}
|
||||||
|
engines: {node: '>= 10'}
|
||||||
|
cpu: [arm64]
|
||||||
|
os: [linux]
|
||||||
|
libc: [musl]
|
||||||
|
|
||||||
|
'@napi-rs/canvas-linux-riscv64-gnu@0.1.89':
|
||||||
|
resolution: {integrity: sha512-1/VmEoFaIO6ONeeEMGoWF17wOYZOl5hxDC1ios2Bkz/oQjbJJ8DY/X22vWTmvuUKWWhBVlo63pxLGZbjJU/heA==}
|
||||||
|
engines: {node: '>= 10'}
|
||||||
|
cpu: [riscv64]
|
||||||
|
os: [linux]
|
||||||
|
libc: [glibc]
|
||||||
|
|
||||||
|
'@napi-rs/canvas-linux-x64-gnu@0.1.89':
|
||||||
|
resolution: {integrity: sha512-ebLuqkCuaPIkKgKH9q4+pqWi1tkPOfiTk5PM1LKR1tB9iO9sFNVSIgwEp+SJreTSbA2DK5rW8lQXiN78SjtcvA==}
|
||||||
|
engines: {node: '>= 10'}
|
||||||
|
cpu: [x64]
|
||||||
|
os: [linux]
|
||||||
|
libc: [glibc]
|
||||||
|
|
||||||
|
'@napi-rs/canvas-linux-x64-musl@0.1.89':
|
||||||
|
resolution: {integrity: sha512-w+5qxHzplvA4BkHhCaizNMLLXiI+CfP84YhpHm/PqMub4u8J0uOAv+aaGv40rYEYra5hHRWr9LUd6cfW32o9/A==}
|
||||||
|
engines: {node: '>= 10'}
|
||||||
|
cpu: [x64]
|
||||||
|
os: [linux]
|
||||||
|
libc: [musl]
|
||||||
|
|
||||||
|
'@napi-rs/canvas-win32-arm64-msvc@0.1.89':
|
||||||
|
resolution: {integrity: sha512-DmyXa5lJHcjOsDC78BM3bnEECqbK3xASVMrKfvtT/7S7Z8NGQOugvu+L7b41V6cexCd34mBWgMOsjoEBceeB1Q==}
|
||||||
|
engines: {node: '>= 10'}
|
||||||
|
cpu: [arm64]
|
||||||
|
os: [win32]
|
||||||
|
|
||||||
|
'@napi-rs/canvas-win32-x64-msvc@0.1.89':
|
||||||
|
resolution: {integrity: sha512-WMej0LZrIqIncQcx0JHaMXlnAG7sncwJh7obs/GBgp0xF9qABjwoRwIooMWCZkSansapKGNUHhamY6qEnFN7gA==}
|
||||||
|
engines: {node: '>= 10'}
|
||||||
|
cpu: [x64]
|
||||||
|
os: [win32]
|
||||||
|
|
||||||
|
'@napi-rs/canvas@0.1.89':
|
||||||
|
resolution: {integrity: sha512-7GjmkMirJHejeALCqUnZY3QwID7bbumOiLrqq2LKgxrdjdmxWQBTc6rcASa2u8wuWrH7qo4/4n/VNrOwCoKlKg==}
|
||||||
|
engines: {node: '>= 10'}
|
||||||
|
|
||||||
'@popperjs/core@2.11.8':
|
'@popperjs/core@2.11.8':
|
||||||
resolution: {integrity: sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==}
|
resolution: {integrity: sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==}
|
||||||
|
|
||||||
@@ -1121,6 +1211,10 @@ packages:
|
|||||||
'@types/parse-json@4.0.2':
|
'@types/parse-json@4.0.2':
|
||||||
resolution: {integrity: sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==}
|
resolution: {integrity: sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==}
|
||||||
|
|
||||||
|
'@types/pdfjs-dist@2.10.378':
|
||||||
|
resolution: {integrity: sha512-TRdIPqdsvKmPla44kVy4jv5Nt5vjMfVjbIEke1CRULIrwKNRC4lIiZvNYDJvbUMNCFPNIUcOKhXTyMJrX18IMA==}
|
||||||
|
deprecated: This is a stub types definition. pdfjs-dist provides its own type definitions, so you do not need this installed.
|
||||||
|
|
||||||
'@types/prop-types@15.7.14':
|
'@types/prop-types@15.7.14':
|
||||||
resolution: {integrity: sha512-gNMvNH49DJ7OJYv+KAKn0Xp45p8PLl6zo2YnvDIbTd4J6MER2BmWN49TG7n9LvkyihINxeKW8+3bfS2yDC9dzQ==}
|
resolution: {integrity: sha512-gNMvNH49DJ7OJYv+KAKn0Xp45p8PLl6zo2YnvDIbTd4J6MER2BmWN49TG7n9LvkyihINxeKW8+3bfS2yDC9dzQ==}
|
||||||
|
|
||||||
@@ -1166,6 +1260,10 @@ packages:
|
|||||||
resolution: {integrity: sha512-6t10qk83GOG8p0vKmaCr8eiilZwO171AvbROMtvvNiwrTly62t+7XkA8RdIIVbpMhCASAsxgAzdRSwh6nw/5Dg==}
|
resolution: {integrity: sha512-6t10qk83GOG8p0vKmaCr8eiilZwO171AvbROMtvvNiwrTly62t+7XkA8RdIIVbpMhCASAsxgAzdRSwh6nw/5Dg==}
|
||||||
engines: {node: '>=4'}
|
engines: {node: '>=4'}
|
||||||
|
|
||||||
|
attr-accept@2.2.5:
|
||||||
|
resolution: {integrity: sha512-0bDNnY/u6pPwHDMoF0FieU354oBi0a8rD9FcsLwzcGWbc8KS8KPIi7y+s13OlVY+gMWc/9xEMUgNE6Qm8ZllYQ==}
|
||||||
|
engines: {node: '>=4'}
|
||||||
|
|
||||||
babel-dead-code-elimination@1.0.12:
|
babel-dead-code-elimination@1.0.12:
|
||||||
resolution: {integrity: sha512-GERT7L2TiYcYDtYk1IpD+ASAYXjKbLTDPhBtYj7X1NuRMDTMtAx9kyBenub1Ev41lo91OHCKdmP+egTDmfQ7Ig==}
|
resolution: {integrity: sha512-GERT7L2TiYcYDtYk1IpD+ASAYXjKbLTDPhBtYj7X1NuRMDTMtAx9kyBenub1Ev41lo91OHCKdmP+egTDmfQ7Ig==}
|
||||||
|
|
||||||
@@ -1197,6 +1295,9 @@ packages:
|
|||||||
resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==}
|
resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==}
|
||||||
engines: {node: '>= 8.10.0'}
|
engines: {node: '>= 8.10.0'}
|
||||||
|
|
||||||
|
class-variance-authority@0.7.1:
|
||||||
|
resolution: {integrity: sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg==}
|
||||||
|
|
||||||
clsx@1.2.1:
|
clsx@1.2.1:
|
||||||
resolution: {integrity: sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==}
|
resolution: {integrity: sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==}
|
||||||
engines: {node: '>=6'}
|
engines: {node: '>=6'}
|
||||||
@@ -1243,6 +1344,10 @@ packages:
|
|||||||
resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==}
|
resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==}
|
||||||
engines: {node: '>=0.10.0'}
|
engines: {node: '>=0.10.0'}
|
||||||
|
|
||||||
|
dequal@2.0.3:
|
||||||
|
resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==}
|
||||||
|
engines: {node: '>=6'}
|
||||||
|
|
||||||
detect-libc@2.0.4:
|
detect-libc@2.0.4:
|
||||||
resolution: {integrity: sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==}
|
resolution: {integrity: sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==}
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
@@ -1313,6 +1418,10 @@ packages:
|
|||||||
picomatch:
|
picomatch:
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
|
file-selector@2.1.2:
|
||||||
|
resolution: {integrity: sha512-QgXo+mXTe8ljeqUFaX3QVHc5osSItJ/Km+xpocx0aSqWGMSCf6qYs/VnzZgS864Pjn5iceMRFigeAV7AfTlaig==}
|
||||||
|
engines: {node: '>= 12'}
|
||||||
|
|
||||||
fill-range@7.1.1:
|
fill-range@7.1.1:
|
||||||
resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==}
|
resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==}
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
@@ -1527,6 +1636,20 @@ packages:
|
|||||||
magic-string@0.30.21:
|
magic-string@0.30.21:
|
||||||
resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==}
|
resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==}
|
||||||
|
|
||||||
|
make-cancellable-promise@2.0.0:
|
||||||
|
resolution: {integrity: sha512-3SEQqTpV9oqVsIWqAcmDuaNeo7yBO3tqPtqGRcKkEo0lrzD3wqbKG9mkxO65KoOgXqj+zH2phJ2LiAsdzlogSw==}
|
||||||
|
|
||||||
|
make-event-props@2.0.0:
|
||||||
|
resolution: {integrity: sha512-G/hncXrl4Qt7mauJEXSg3AcdYzmpkIITTNl5I+rH9sog5Yw0kK6vseJjCaPfOXqOqQuPUP89Rkhfz5kPS8ijtw==}
|
||||||
|
|
||||||
|
merge-refs@2.0.0:
|
||||||
|
resolution: {integrity: sha512-3+B21mYK2IqUWnd2EivABLT7ueDhb0b8/dGK8LoFQPrU61YITeCMn14F7y7qZafWNZhUEKb24cJdiT5Wxs3prg==}
|
||||||
|
peerDependencies:
|
||||||
|
'@types/react': ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
|
||||||
|
peerDependenciesMeta:
|
||||||
|
'@types/react':
|
||||||
|
optional: true
|
||||||
|
|
||||||
ms@2.1.3:
|
ms@2.1.3:
|
||||||
resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
|
resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
|
||||||
|
|
||||||
@@ -1540,6 +1663,9 @@ packages:
|
|||||||
engines: {node: ^18 || >=20}
|
engines: {node: ^18 || >=20}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
||||||
|
node-readable-to-web-readable-stream@0.4.2:
|
||||||
|
resolution: {integrity: sha512-/cMZNI34v//jUTrI+UIo4ieHAB5EZRY/+7OmXZgBxaWBMcW2tGdceIw06RFxWxrKZ5Jp3sI2i5TsRo+CBhtVLQ==}
|
||||||
|
|
||||||
node-releases@2.0.18:
|
node-releases@2.0.18:
|
||||||
resolution: {integrity: sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==}
|
resolution: {integrity: sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==}
|
||||||
|
|
||||||
@@ -1581,6 +1707,14 @@ 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.296:
|
||||||
|
resolution: {integrity: sha512-DlOzet0HO7OEnmUmB6wWGJrrdvbyJKftI1bhMitK7O2N8W2gc757yyYBbINy9IDafXAV9wmKr9t7xsTaNKRG5Q==}
|
||||||
|
engines: {node: '>=20.16.0 || >=22.3.0'}
|
||||||
|
|
||||||
|
pdfjs-dist@5.4.624:
|
||||||
|
resolution: {integrity: sha512-sm6TxKTtWv1Oh6n3C6J6a8odejb5uO4A4zo/2dgkHuC0iu8ZMAXOezEODkVaoVp8nX1Xzr+0WxFJJmUr45hQzg==}
|
||||||
|
engines: {node: '>=20.16.0 || >=22.3.0'}
|
||||||
|
|
||||||
picocolors@1.1.0:
|
picocolors@1.1.0:
|
||||||
resolution: {integrity: sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==}
|
resolution: {integrity: sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==}
|
||||||
|
|
||||||
@@ -1633,6 +1767,12 @@ packages:
|
|||||||
react: '>= 16.3.0'
|
react: '>= 16.3.0'
|
||||||
react-dom: '>= 16.3.0'
|
react-dom: '>= 16.3.0'
|
||||||
|
|
||||||
|
react-dropzone@14.4.0:
|
||||||
|
resolution: {integrity: sha512-8VvsHqg9WGAr+wAnP0oVErK5HOwAoTOzRsxLPzbBXrtXtFfukkxMyuvdI/lJ+5OxtsrzmvWE5Eoo3Y4hMsaxpA==}
|
||||||
|
engines: {node: '>= 10.13'}
|
||||||
|
peerDependencies:
|
||||||
|
react: '>= 16.8 || 18.0.0'
|
||||||
|
|
||||||
react-hook-form@7.56.4:
|
react-hook-form@7.56.4:
|
||||||
resolution: {integrity: sha512-Rob7Ftz2vyZ/ZGsQZPaRdIefkgOSrQSPXfqBdvOPwJfoGnjwRJUs7EM7Kc1mcoDv3NOtqBzPGbcMB8CGn9CKgw==}
|
resolution: {integrity: sha512-Rob7Ftz2vyZ/ZGsQZPaRdIefkgOSrQSPXfqBdvOPwJfoGnjwRJUs7EM7Kc1mcoDv3NOtqBzPGbcMB8CGn9CKgw==}
|
||||||
engines: {node: '>=18.0.0'}
|
engines: {node: '>=18.0.0'}
|
||||||
@@ -1667,6 +1807,16 @@ packages:
|
|||||||
react-is@19.1.0:
|
react-is@19.1.0:
|
||||||
resolution: {integrity: sha512-Oe56aUPnkHyyDxxkvqtd7KkdQP5uIUfHxd5XTb3wE9d/kRnZLmKbDB0GWk919tdQ+mxxPtG6EAs6RMT6i1qtHg==}
|
resolution: {integrity: sha512-Oe56aUPnkHyyDxxkvqtd7KkdQP5uIUfHxd5XTb3wE9d/kRnZLmKbDB0GWk919tdQ+mxxPtG6EAs6RMT6i1qtHg==}
|
||||||
|
|
||||||
|
react-pdf@10.3.0:
|
||||||
|
resolution: {integrity: sha512-2LQzC9IgNVAX8gM+6F+1t/70a9/5RWThYxc+CWAmT2LW/BRmnj+35x1os5j/nR2oldyf8L+hCAMBmVKU8wrYFA==}
|
||||||
|
peerDependencies:
|
||||||
|
'@types/react': ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
|
||||||
|
react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
|
||||||
|
react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
|
||||||
|
peerDependenciesMeta:
|
||||||
|
'@types/react':
|
||||||
|
optional: true
|
||||||
|
|
||||||
react-refresh@0.18.0:
|
react-refresh@0.18.0:
|
||||||
resolution: {integrity: sha512-QgT5//D3jfjJb6Gsjxv0Slpj23ip+HtOpnNgnb2S5zU3CB26G/IDPGoy4RJB42wzFE46DRsstbW6tKHoKbhAxw==}
|
resolution: {integrity: sha512-QgT5//D3jfjJb6Gsjxv0Slpj23ip+HtOpnNgnb2S5zU3CB26G/IDPGoy4RJB42wzFE46DRsstbW6tKHoKbhAxw==}
|
||||||
engines: {node: '>=0.10.0'}
|
engines: {node: '>=0.10.0'}
|
||||||
@@ -1878,6 +2028,9 @@ packages:
|
|||||||
resolution: {integrity: sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==}
|
resolution: {integrity: sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==}
|
||||||
engines: {node: '>=0.10.0'}
|
engines: {node: '>=0.10.0'}
|
||||||
|
|
||||||
|
warning@4.0.3:
|
||||||
|
resolution: {integrity: sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==}
|
||||||
|
|
||||||
webpack-virtual-modules@0.6.2:
|
webpack-virtual-modules@0.6.2:
|
||||||
resolution: {integrity: sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==}
|
resolution: {integrity: sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==}
|
||||||
|
|
||||||
@@ -2430,6 +2583,54 @@ snapshots:
|
|||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
'@types/react': 19.1.6
|
'@types/react': 19.1.6
|
||||||
|
|
||||||
|
'@napi-rs/canvas-android-arm64@0.1.89':
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@napi-rs/canvas-darwin-arm64@0.1.89':
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@napi-rs/canvas-darwin-x64@0.1.89':
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@napi-rs/canvas-linux-arm-gnueabihf@0.1.89':
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@napi-rs/canvas-linux-arm64-gnu@0.1.89':
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@napi-rs/canvas-linux-arm64-musl@0.1.89':
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@napi-rs/canvas-linux-riscv64-gnu@0.1.89':
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@napi-rs/canvas-linux-x64-gnu@0.1.89':
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@napi-rs/canvas-linux-x64-musl@0.1.89':
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@napi-rs/canvas-win32-arm64-msvc@0.1.89':
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@napi-rs/canvas-win32-x64-msvc@0.1.89':
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@napi-rs/canvas@0.1.89':
|
||||||
|
optionalDependencies:
|
||||||
|
'@napi-rs/canvas-android-arm64': 0.1.89
|
||||||
|
'@napi-rs/canvas-darwin-arm64': 0.1.89
|
||||||
|
'@napi-rs/canvas-darwin-x64': 0.1.89
|
||||||
|
'@napi-rs/canvas-linux-arm-gnueabihf': 0.1.89
|
||||||
|
'@napi-rs/canvas-linux-arm64-gnu': 0.1.89
|
||||||
|
'@napi-rs/canvas-linux-arm64-musl': 0.1.89
|
||||||
|
'@napi-rs/canvas-linux-riscv64-gnu': 0.1.89
|
||||||
|
'@napi-rs/canvas-linux-x64-gnu': 0.1.89
|
||||||
|
'@napi-rs/canvas-linux-x64-musl': 0.1.89
|
||||||
|
'@napi-rs/canvas-win32-arm64-msvc': 0.1.89
|
||||||
|
'@napi-rs/canvas-win32-x64-msvc': 0.1.89
|
||||||
|
optional: true
|
||||||
|
|
||||||
'@popperjs/core@2.11.8': {}
|
'@popperjs/core@2.11.8': {}
|
||||||
|
|
||||||
'@radix-ui/react-compose-refs@1.1.2(@types/react@19.2.10)(react@19.2.4)':
|
'@radix-ui/react-compose-refs@1.1.2(@types/react@19.2.10)(react@19.2.4)':
|
||||||
@@ -2821,6 +3022,10 @@ snapshots:
|
|||||||
|
|
||||||
'@types/parse-json@4.0.2': {}
|
'@types/parse-json@4.0.2': {}
|
||||||
|
|
||||||
|
'@types/pdfjs-dist@2.10.378':
|
||||||
|
dependencies:
|
||||||
|
pdfjs-dist: 5.4.624
|
||||||
|
|
||||||
'@types/prop-types@15.7.14': {}
|
'@types/prop-types@15.7.14': {}
|
||||||
|
|
||||||
'@types/react-dom@19.2.3(@types/react@19.2.10)':
|
'@types/react-dom@19.2.3(@types/react@19.2.10)':
|
||||||
@@ -2866,6 +3071,8 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
tslib: 2.8.1
|
tslib: 2.8.1
|
||||||
|
|
||||||
|
attr-accept@2.2.5: {}
|
||||||
|
|
||||||
babel-dead-code-elimination@1.0.12:
|
babel-dead-code-elimination@1.0.12:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@babel/core': 7.29.0
|
'@babel/core': 7.29.0
|
||||||
@@ -2910,6 +3117,10 @@ snapshots:
|
|||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
fsevents: 2.3.3
|
fsevents: 2.3.3
|
||||||
|
|
||||||
|
class-variance-authority@0.7.1:
|
||||||
|
dependencies:
|
||||||
|
clsx: 2.1.1
|
||||||
|
|
||||||
clsx@1.2.1: {}
|
clsx@1.2.1: {}
|
||||||
|
|
||||||
clsx@2.1.1: {}
|
clsx@2.1.1: {}
|
||||||
@@ -2942,6 +3153,8 @@ snapshots:
|
|||||||
|
|
||||||
deepmerge@4.3.1: {}
|
deepmerge@4.3.1: {}
|
||||||
|
|
||||||
|
dequal@2.0.3: {}
|
||||||
|
|
||||||
detect-libc@2.0.4: {}
|
detect-libc@2.0.4: {}
|
||||||
|
|
||||||
diff@8.0.3: {}
|
diff@8.0.3: {}
|
||||||
@@ -3013,6 +3226,10 @@ snapshots:
|
|||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
picomatch: 4.0.3
|
picomatch: 4.0.3
|
||||||
|
|
||||||
|
file-selector@2.1.2:
|
||||||
|
dependencies:
|
||||||
|
tslib: 2.8.1
|
||||||
|
|
||||||
fill-range@7.1.1:
|
fill-range@7.1.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
to-regex-range: 5.0.1
|
to-regex-range: 5.0.1
|
||||||
@@ -3177,12 +3394,23 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
'@jridgewell/sourcemap-codec': 1.5.5
|
'@jridgewell/sourcemap-codec': 1.5.5
|
||||||
|
|
||||||
|
make-cancellable-promise@2.0.0: {}
|
||||||
|
|
||||||
|
make-event-props@2.0.0: {}
|
||||||
|
|
||||||
|
merge-refs@2.0.0(@types/react@19.2.10):
|
||||||
|
optionalDependencies:
|
||||||
|
'@types/react': 19.2.10
|
||||||
|
|
||||||
ms@2.1.3: {}
|
ms@2.1.3: {}
|
||||||
|
|
||||||
nanoid@3.3.11: {}
|
nanoid@3.3.11: {}
|
||||||
|
|
||||||
nanoid@5.1.6: {}
|
nanoid@5.1.6: {}
|
||||||
|
|
||||||
|
node-readable-to-web-readable-stream@0.4.2:
|
||||||
|
optional: true
|
||||||
|
|
||||||
node-releases@2.0.18: {}
|
node-releases@2.0.18: {}
|
||||||
|
|
||||||
normalize-path@3.0.0: {}
|
normalize-path@3.0.0: {}
|
||||||
@@ -3210,6 +3438,15 @@ snapshots:
|
|||||||
|
|
||||||
pathe@2.0.3: {}
|
pathe@2.0.3: {}
|
||||||
|
|
||||||
|
pdfjs-dist@5.4.296:
|
||||||
|
optionalDependencies:
|
||||||
|
'@napi-rs/canvas': 0.1.89
|
||||||
|
|
||||||
|
pdfjs-dist@5.4.624:
|
||||||
|
optionalDependencies:
|
||||||
|
'@napi-rs/canvas': 0.1.89
|
||||||
|
node-readable-to-web-readable-stream: 0.4.2
|
||||||
|
|
||||||
picocolors@1.1.0: {}
|
picocolors@1.1.0: {}
|
||||||
|
|
||||||
picocolors@1.1.1: {}
|
picocolors@1.1.1: {}
|
||||||
@@ -3256,6 +3493,13 @@ snapshots:
|
|||||||
react: 19.1.0
|
react: 19.1.0
|
||||||
react-dom: 19.1.0(react@19.1.0)
|
react-dom: 19.1.0(react@19.1.0)
|
||||||
|
|
||||||
|
react-dropzone@14.4.0(react@19.2.4):
|
||||||
|
dependencies:
|
||||||
|
attr-accept: 2.2.5
|
||||||
|
file-selector: 2.1.2
|
||||||
|
prop-types: 15.8.1
|
||||||
|
react: 19.2.4
|
||||||
|
|
||||||
react-hook-form@7.56.4(react@19.1.0):
|
react-hook-form@7.56.4(react@19.1.0):
|
||||||
dependencies:
|
dependencies:
|
||||||
react: 19.1.0
|
react: 19.1.0
|
||||||
@@ -3278,6 +3522,21 @@ snapshots:
|
|||||||
|
|
||||||
react-is@19.1.0: {}
|
react-is@19.1.0: {}
|
||||||
|
|
||||||
|
react-pdf@10.3.0(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4):
|
||||||
|
dependencies:
|
||||||
|
clsx: 2.1.1
|
||||||
|
dequal: 2.0.3
|
||||||
|
make-cancellable-promise: 2.0.0
|
||||||
|
make-event-props: 2.0.0
|
||||||
|
merge-refs: 2.0.0(@types/react@19.2.10)
|
||||||
|
pdfjs-dist: 5.4.296
|
||||||
|
react: 19.2.4
|
||||||
|
react-dom: 19.2.4(react@19.2.4)
|
||||||
|
tiny-invariant: 1.3.3
|
||||||
|
warning: 4.0.3
|
||||||
|
optionalDependencies:
|
||||||
|
'@types/react': 19.2.10
|
||||||
|
|
||||||
react-refresh@0.18.0: {}
|
react-refresh@0.18.0: {}
|
||||||
|
|
||||||
react-transition-group@4.4.5(react-dom@19.1.0(react@19.1.0))(react@19.1.0):
|
react-transition-group@4.4.5(react-dom@19.1.0(react@19.1.0))(react@19.1.0):
|
||||||
@@ -3479,6 +3738,10 @@ snapshots:
|
|||||||
|
|
||||||
void-elements@3.1.0: {}
|
void-elements@3.1.0: {}
|
||||||
|
|
||||||
|
warning@4.0.3:
|
||||||
|
dependencies:
|
||||||
|
loose-envify: 1.4.0
|
||||||
|
|
||||||
webpack-virtual-modules@0.6.2: {}
|
webpack-virtual-modules@0.6.2: {}
|
||||||
|
|
||||||
ws@8.18.1:
|
ws@8.18.1:
|
||||||
|
|||||||
@@ -2,10 +2,12 @@ import ReactDOM from 'react-dom/client'
|
|||||||
import { RouterProvider, createRouter } from '@tanstack/react-router'
|
import { RouterProvider, createRouter } from '@tanstack/react-router'
|
||||||
import { routeTree } from './routeTree.gen'
|
import { routeTree } from './routeTree.gen'
|
||||||
import './index.css'
|
import './index.css'
|
||||||
|
import { basename } from './modules/basename'
|
||||||
|
|
||||||
// Set up a Router instance
|
// Set up a Router instance
|
||||||
const router = createRouter({
|
const router = createRouter({
|
||||||
routeTree,
|
routeTree,
|
||||||
|
basepath: basename,
|
||||||
defaultPreload: 'intent',
|
defaultPreload: 'intent',
|
||||||
scrollRestoration: true,
|
scrollRestoration: true,
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,2 +1,2 @@
|
|||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
export const basename = DEV_SERVER ? '/' : BASE_NAME;
|
export const basename = BASE_NAME;
|
||||||
|
|||||||
@@ -1,3 +1,208 @@
|
|||||||
|
import { useState, useCallback } from 'react'
|
||||||
|
import { useDropzone } from 'react-dropzone'
|
||||||
|
import * as pdfjsLib from 'pdfjs-dist'
|
||||||
|
import { Button } from '@/components/ui/button'
|
||||||
|
import { Upload, Download, FileText, Loader2 } from 'lucide-react'
|
||||||
|
import pdfjsWorker from 'pdfjs-dist/build/pdf.worker.min.mjs?url'
|
||||||
|
|
||||||
|
// 设置 PDF.js worker
|
||||||
|
pdfjsLib.GlobalWorkerOptions.workerSrc = pdfjsWorker
|
||||||
|
// pdfjsLib.GlobalWorkerOptions.workerSrc = "//cdn.jsdelivr.net/npm/pdfjs-dist@5.4.624/build/pdf.min.mjs"
|
||||||
|
// pdfjsLib.GlobalWorkerOptions.workerSrc = "//unpkg.com/pdfjs-dist@5.4.624/build/pdf.min.mjs"
|
||||||
|
|
||||||
export const Home = () => {
|
export const Home = () => {
|
||||||
return <div>Home Page</div>
|
const [pdfFile, setPdfFile] = useState<File | null>(null)
|
||||||
|
const [pdfName, setPdfName] = useState<string>('')
|
||||||
|
const [pageCount, setPageCount] = useState<number>(0)
|
||||||
|
const [loading, setLoading] = useState<boolean>(false)
|
||||||
|
const [converting, setConverting] = useState<boolean>(false)
|
||||||
|
|
||||||
|
const onDrop = useCallback(async (acceptedFiles: File[]) => {
|
||||||
|
const file = acceptedFiles[0]
|
||||||
|
if (file && file.type === 'application/pdf') {
|
||||||
|
setPdfFile(file)
|
||||||
|
setPdfName(file.name.replace('.pdf', ''))
|
||||||
|
|
||||||
|
// 读取 PDF 获取页数
|
||||||
|
setLoading(true)
|
||||||
|
try {
|
||||||
|
const arrayBuffer = await file.arrayBuffer()
|
||||||
|
const pdf = await pdfjsLib.getDocument({ data: arrayBuffer }).promise
|
||||||
|
setPageCount(pdf.numPages)
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error loading PDF:', error)
|
||||||
|
alert('加载 PDF 失败,请重试')
|
||||||
|
} finally {
|
||||||
|
setLoading(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
const { getRootProps, getInputProps, isDragActive } = useDropzone({
|
||||||
|
onDrop,
|
||||||
|
accept: {
|
||||||
|
'application/pdf': ['.pdf']
|
||||||
|
},
|
||||||
|
multiple: false
|
||||||
|
})
|
||||||
|
|
||||||
|
const handleDownload = async () => {
|
||||||
|
if (!pdfFile) return
|
||||||
|
|
||||||
|
setConverting(true)
|
||||||
|
try {
|
||||||
|
const arrayBuffer = await pdfFile.arrayBuffer()
|
||||||
|
const pdf = await pdfjsLib.getDocument({ data: arrayBuffer }).promise
|
||||||
|
|
||||||
|
// 遍历每一页
|
||||||
|
for (let pageNum = 1; pageNum <= pdf.numPages; pageNum++) {
|
||||||
|
const page = await pdf.getPage(pageNum)
|
||||||
|
|
||||||
|
// 设置缩放比例以获得高质量图片
|
||||||
|
const scale = 2.0
|
||||||
|
const viewport = page.getViewport({ scale })
|
||||||
|
|
||||||
|
// 创建 canvas
|
||||||
|
const canvas = document.createElement('canvas')
|
||||||
|
const context = canvas.getContext('2d')
|
||||||
|
canvas.height = viewport.height
|
||||||
|
canvas.width = viewport.width
|
||||||
|
|
||||||
|
if (!context) continue
|
||||||
|
|
||||||
|
// 渲染 PDF 页面到 canvas
|
||||||
|
await page.render({
|
||||||
|
canvasContext: context,
|
||||||
|
viewport: viewport,
|
||||||
|
canvas: canvas
|
||||||
|
}).promise
|
||||||
|
|
||||||
|
// 将 canvas 转换为 blob 并下载
|
||||||
|
canvas.toBlob((blob) => {
|
||||||
|
if (blob) {
|
||||||
|
const url = URL.createObjectURL(blob)
|
||||||
|
const link = document.createElement('a')
|
||||||
|
link.href = url
|
||||||
|
link.download = `${pdfName}_${pageNum}.png`
|
||||||
|
link.click()
|
||||||
|
URL.revokeObjectURL(url)
|
||||||
|
}
|
||||||
|
}, 'image/png')
|
||||||
|
|
||||||
|
// 添加延迟避免浏览器下载限制
|
||||||
|
await new Promise(resolve => setTimeout(resolve, 200))
|
||||||
|
}
|
||||||
|
|
||||||
|
alert(`成功转换并下载 ${pdf.numPages} 张图片!`)
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error converting PDF:', error)
|
||||||
|
alert('转换 PDF 失败,请重试')
|
||||||
|
} finally {
|
||||||
|
setConverting(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="h-full bg-linear-to-br from-blue-50 to-indigo-100 p-8 overflow-auto">
|
||||||
|
<div className="max-w-4xl mx-auto">
|
||||||
|
<div className="text-center mb-12">
|
||||||
|
<h1 className="text-4xl font-bold text-gray-800 mb-2">
|
||||||
|
PDF 转图片工具
|
||||||
|
</h1>
|
||||||
|
<p className="text-gray-600">
|
||||||
|
上传 PDF 文件,将每一页转换为单独的图片
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* 上传区域 */}
|
||||||
|
<div
|
||||||
|
{...getRootProps()}
|
||||||
|
className={`
|
||||||
|
border-2 border-dashed rounded-lg p-12 mb-8 text-center cursor-pointer
|
||||||
|
transition-all duration-200 ease-in-out
|
||||||
|
${isDragActive
|
||||||
|
? 'border-blue-500 bg-blue-50'
|
||||||
|
: 'border-gray-300 bg-white hover:border-blue-400 hover:bg-blue-50/50'
|
||||||
|
}
|
||||||
|
`}
|
||||||
|
>
|
||||||
|
<input {...getInputProps()} />
|
||||||
|
<div className="flex flex-col items-center gap-4">
|
||||||
|
<Upload className={`w-16 h-16 ${isDragActive ? 'text-blue-500' : 'text-gray-400'}`} />
|
||||||
|
{isDragActive ? (
|
||||||
|
<p className="text-lg text-blue-600 font-medium">
|
||||||
|
释放文件以上传...
|
||||||
|
</p>
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
<p className="text-lg text-gray-700 font-medium">
|
||||||
|
拖拽 PDF 文件到这里,或点击选择文件
|
||||||
|
</p>
|
||||||
|
<p className="text-sm text-gray-500">
|
||||||
|
仅支持 PDF 格式
|
||||||
|
</p>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* PDF 信息卡片 */}
|
||||||
|
{pdfFile && (
|
||||||
|
<div className="bg-white rounded-lg shadow-md p-6 mb-6">
|
||||||
|
<div className="flex items-start justify-between">
|
||||||
|
<div className="flex items-start gap-4 flex-1">
|
||||||
|
<FileText className="w-12 h-12 text-blue-500 shrink-0" />
|
||||||
|
<div className="flex-1 min-w-0">
|
||||||
|
<h3 className="text-lg font-semibold text-gray-800 truncate">
|
||||||
|
{pdfFile.name}
|
||||||
|
</h3>
|
||||||
|
<div className="mt-2 space-y-1 text-sm text-gray-600">
|
||||||
|
<p>
|
||||||
|
文件大小: {(pdfFile.size / 1024 / 1024).toFixed(2)} MB
|
||||||
|
</p>
|
||||||
|
{loading ? (
|
||||||
|
<p className="flex items-center gap-2">
|
||||||
|
<Loader2 className="w-4 h-4 animate-spin" />
|
||||||
|
正在加载 PDF...
|
||||||
|
</p>
|
||||||
|
) : (
|
||||||
|
<p>页数: {pageCount} 页</p>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<Button
|
||||||
|
onClick={handleDownload}
|
||||||
|
disabled={loading || converting || pageCount === 0}
|
||||||
|
className="flex items-center gap-2"
|
||||||
|
>
|
||||||
|
{converting ? (
|
||||||
|
<>
|
||||||
|
<Loader2 className="w-4 h-4 animate-spin" />
|
||||||
|
转换中...
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
<Download className="w-4 h-4" />
|
||||||
|
下载图片
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* 说明 */}
|
||||||
|
<div className="bg-white rounded-lg shadow-md p-6">
|
||||||
|
<h3 className="font-semibold text-gray-800 mb-3">使用说明:</h3>
|
||||||
|
<ol className="list-decimal list-inside space-y-2 text-gray-600 text-sm">
|
||||||
|
<li>点击或拖拽上传 PDF 文件</li>
|
||||||
|
<li>等待文件加载完成,查看页数信息</li>
|
||||||
|
<li>点击"下载图片"按钮,自动将每一页转换为 PNG 图片</li>
|
||||||
|
<li>图片将按顺序命名,如:文件名_1.png, 文件名_2.png...</li>
|
||||||
|
</ol>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
}
|
}
|
||||||
@@ -8,7 +8,7 @@ export const Route = createRootRoute({
|
|||||||
function RootComponent() {
|
function RootComponent() {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="p-2 flex gap-2 text-lg">
|
<div className="p-2 flex gap-2 text-lg h-16">
|
||||||
<Link
|
<Link
|
||||||
to="/"
|
to="/"
|
||||||
activeProps={{
|
activeProps={{
|
||||||
@@ -20,7 +20,9 @@ function RootComponent() {
|
|||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
<hr />
|
<hr />
|
||||||
<Outlet />
|
<main className='h-[calc(100vh-64px)] overflow-hidden'>
|
||||||
|
<Outlet />
|
||||||
|
</main>
|
||||||
<TanStackRouterDevtools position="bottom-right" />
|
<TanStackRouterDevtools position="bottom-right" />
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user