diff --git a/.cnb.yml b/.cnb.yml index d469410..0469405 100644 --- a/.cnb.yml +++ b/.cnb.yml @@ -4,7 +4,7 @@ include: .common_env: &common_env env: - TO_REPO: template/vite-react-template + TO_REPO: kevisual/pdf TO_URL: git.xiongxiao.me imports: - https://cnb.cool/kevisual/env/-/blob/main/.env.development diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..5f4c4d9 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,4 @@ +# 代码 + +- @tanstack/react-router" +- shadcn/ui \ No newline at end of file diff --git a/package.json b/package.json index 3488cbf..74aadbd 100644 --- a/package.json +++ b/package.json @@ -1,15 +1,15 @@ { - "name": "vite-react", + "name": "@kevisual/pdf", "private": true, "version": "0.0.1", "type": "module", - "basename": "/", + "basename": "/root/pdf", "scripts": { "dev": "vite", "build": "vite build", "preview": "vite preview", "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.1 -y y -u" }, "files": [ "dist" @@ -20,14 +20,18 @@ "@kevisual/router": "0.0.70", "@radix-ui/react-slot": "^1.2.4", "@tanstack/react-router": "^1.158.0", + "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", "dayjs": "^1.11.19", "es-toolkit": "^1.44.0", "lucide-react": "^0.563.0", "nanoid": "^5.1.6", + "pdfjs-dist": "^5.4.624", "react": "^19.2.4", "react-dom": "^19.2.4", + "react-dropzone": "^14.4.0", "react-hook-form": "^7.71.1", + "react-pdf": "^10.3.0", "zustand": "^5.0.11" }, "publishConfig": { @@ -40,6 +44,7 @@ "@tanstack/react-router-devtools": "^1.158.0", "@tanstack/router-plugin": "^1.158.0", "@types/node": "^25.2.0", + "@types/pdfjs-dist": "^2.10.378", "@types/react": "^19.2.10", "@types/react-dom": "^19.2.3", "@vitejs/plugin-react": "^5.1.3", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 063480f..d731827 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -17,6 +17,9 @@ importers: '@tanstack/react-router': specifier: ^1.158.0 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: specifier: ^2.1.1 version: 2.1.1 @@ -32,15 +35,24 @@ importers: nanoid: specifier: ^5.1.6 version: 5.1.6 + pdfjs-dist: + specifier: ^5.4.624 + version: 5.4.624 react: specifier: ^19.2.4 version: 19.2.4 react-dom: specifier: ^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: specifier: ^7.71.1 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: 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)) @@ -63,6 +75,9 @@ importers: '@types/node': specifier: ^25.2.0 version: 25.2.0 + '@types/pdfjs-dist': + specifier: ^2.10.378 + version: 2.10.378 '@types/react': specifier: ^19.2.10 version: 19.2.10 @@ -622,6 +637,81 @@ packages: '@types/react': 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': resolution: {integrity: sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==} @@ -1121,6 +1211,10 @@ packages: '@types/parse-json@4.0.2': 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': resolution: {integrity: sha512-gNMvNH49DJ7OJYv+KAKn0Xp45p8PLl6zo2YnvDIbTd4J6MER2BmWN49TG7n9LvkyihINxeKW8+3bfS2yDC9dzQ==} @@ -1166,6 +1260,10 @@ packages: resolution: {integrity: sha512-6t10qk83GOG8p0vKmaCr8eiilZwO171AvbROMtvvNiwrTly62t+7XkA8RdIIVbpMhCASAsxgAzdRSwh6nw/5Dg==} 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: resolution: {integrity: sha512-GERT7L2TiYcYDtYk1IpD+ASAYXjKbLTDPhBtYj7X1NuRMDTMtAx9kyBenub1Ev41lo91OHCKdmP+egTDmfQ7Ig==} @@ -1197,6 +1295,9 @@ packages: resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} engines: {node: '>= 8.10.0'} + class-variance-authority@0.7.1: + resolution: {integrity: sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg==} + clsx@1.2.1: resolution: {integrity: sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==} engines: {node: '>=6'} @@ -1243,6 +1344,10 @@ packages: resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} engines: {node: '>=0.10.0'} + dequal@2.0.3: + resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} + engines: {node: '>=6'} + detect-libc@2.0.4: resolution: {integrity: sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==} engines: {node: '>=8'} @@ -1313,6 +1418,10 @@ packages: picomatch: optional: true + file-selector@2.1.2: + resolution: {integrity: sha512-QgXo+mXTe8ljeqUFaX3QVHc5osSItJ/Km+xpocx0aSqWGMSCf6qYs/VnzZgS864Pjn5iceMRFigeAV7AfTlaig==} + engines: {node: '>= 12'} + fill-range@7.1.1: resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} engines: {node: '>=8'} @@ -1527,6 +1636,20 @@ packages: magic-string@0.30.21: 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: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} @@ -1540,6 +1663,9 @@ packages: engines: {node: ^18 || >=20} hasBin: true + node-readable-to-web-readable-stream@0.4.2: + resolution: {integrity: sha512-/cMZNI34v//jUTrI+UIo4ieHAB5EZRY/+7OmXZgBxaWBMcW2tGdceIw06RFxWxrKZ5Jp3sI2i5TsRo+CBhtVLQ==} + node-releases@2.0.18: resolution: {integrity: sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==} @@ -1581,6 +1707,14 @@ packages: pathe@2.0.3: 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: resolution: {integrity: sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==} @@ -1633,6 +1767,12 @@ packages: react: '>= 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: resolution: {integrity: sha512-Rob7Ftz2vyZ/ZGsQZPaRdIefkgOSrQSPXfqBdvOPwJfoGnjwRJUs7EM7Kc1mcoDv3NOtqBzPGbcMB8CGn9CKgw==} engines: {node: '>=18.0.0'} @@ -1667,6 +1807,16 @@ packages: react-is@19.1.0: 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: resolution: {integrity: sha512-QgT5//D3jfjJb6Gsjxv0Slpj23ip+HtOpnNgnb2S5zU3CB26G/IDPGoy4RJB42wzFE46DRsstbW6tKHoKbhAxw==} engines: {node: '>=0.10.0'} @@ -1878,6 +2028,9 @@ packages: resolution: {integrity: sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==} engines: {node: '>=0.10.0'} + warning@4.0.3: + resolution: {integrity: sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==} + webpack-virtual-modules@0.6.2: resolution: {integrity: sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==} @@ -2430,6 +2583,54 @@ snapshots: optionalDependencies: '@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': {} '@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/pdfjs-dist@2.10.378': + dependencies: + pdfjs-dist: 5.4.624 + '@types/prop-types@15.7.14': {} '@types/react-dom@19.2.3(@types/react@19.2.10)': @@ -2866,6 +3071,8 @@ snapshots: dependencies: tslib: 2.8.1 + attr-accept@2.2.5: {} + babel-dead-code-elimination@1.0.12: dependencies: '@babel/core': 7.29.0 @@ -2910,6 +3117,10 @@ snapshots: optionalDependencies: fsevents: 2.3.3 + class-variance-authority@0.7.1: + dependencies: + clsx: 2.1.1 + clsx@1.2.1: {} clsx@2.1.1: {} @@ -2942,6 +3153,8 @@ snapshots: deepmerge@4.3.1: {} + dequal@2.0.3: {} + detect-libc@2.0.4: {} diff@8.0.3: {} @@ -3013,6 +3226,10 @@ snapshots: optionalDependencies: picomatch: 4.0.3 + file-selector@2.1.2: + dependencies: + tslib: 2.8.1 + fill-range@7.1.1: dependencies: to-regex-range: 5.0.1 @@ -3177,12 +3394,23 @@ snapshots: dependencies: '@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: {} nanoid@3.3.11: {} nanoid@5.1.6: {} + node-readable-to-web-readable-stream@0.4.2: + optional: true + node-releases@2.0.18: {} normalize-path@3.0.0: {} @@ -3210,6 +3438,15 @@ snapshots: 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.1: {} @@ -3256,6 +3493,13 @@ snapshots: 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): dependencies: react: 19.1.0 @@ -3278,6 +3522,21 @@ snapshots: 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-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: {} + warning@4.0.3: + dependencies: + loose-envify: 1.4.0 + webpack-virtual-modules@0.6.2: {} ws@8.18.1: diff --git a/src/pages/Home.tsx b/src/pages/Home.tsx index a16f8e1..ce66c41 100644 --- a/src/pages/Home.tsx +++ b/src/pages/Home.tsx @@ -1,3 +1,206 @@ +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 + export const Home = () => { - return
+ 上传 PDF 文件,将每一页转换为单独的图片 +
++ 释放文件以上传... +
+ ) : ( + <> ++ 拖拽 PDF 文件到这里,或点击选择文件 +
++ 仅支持 PDF 格式 +
+ > + )} ++ 文件大小: {(pdfFile.size / 1024 / 1024).toFixed(2)} MB +
+ {loading ? ( +
+
页数: {pageCount} 页
+ )} +