From 3cc21bcbd502f4562c687d6561e7edf2ca936e55 Mon Sep 17 00:00:00 2001 From: mmdctjj <984808285@qq.com> Date: Mon, 22 Jun 2026 12:54:23 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8Dweb=20mobile=20?= =?UTF-8?q?=E6=A8=A1=E5=BC=8F=E7=9A=84=E6=98=BE=E7=A4=BA=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/desktop/src/pages/Profile.tsx | 42 +++++++++++ apps/mobile/src/screens/ProfileScreen.tsx | 17 +++-- package.json | 5 +- pnpm-lock.yaml | 89 +++++++++++++++++++++++ 4 files changed, 143 insertions(+), 10 deletions(-) diff --git a/apps/desktop/src/pages/Profile.tsx b/apps/desktop/src/pages/Profile.tsx index 04fd8339..12507825 100644 --- a/apps/desktop/src/pages/Profile.tsx +++ b/apps/desktop/src/pages/Profile.tsx @@ -73,6 +73,7 @@ export default function Profile() { const [showCreateModal, setShowCreateModal] = useState(false); const [newCollectionName, setNewCollectionName] = useState(""); const [showDropdown, setShowDropdown] = useState(false); + const [syncing, setSyncing] = useState(null); const dropdownRef = useRef(null); // Close dropdown on click outside @@ -173,6 +174,31 @@ export default function Profile() { const downloadedBooks: Book[] = []; + const handleSync = async (type: "full" | "incremental") => { + const title = type === "full" ? "全量更新" : "增量更新"; + const message = + type === "full" + ? "扫描所有本地书籍,新增数据库不存在的,标记已删除的,重新抓取所有现有书籍的元数据。" + : "仅扫描新数据,现有数据不做处理。"; + + if (!window.confirm(`${title}\n\n${message}\n\n确认开始更新吗?`)) { + return; + } + + setSyncing(type); + try { + const { getApiClient } = await import("@bookdock/api-client"); + const api = getApiClient(); + const res = await api.syncBooks(type); + alert(res.data?.message || `${type === "full" ? "全量" : "增量"}更新成功`); + } catch (e: any) { + alert(e?.response?.data?.message || "同步失败"); + } finally { + setSyncing(null); + setShowDropdown(false); + } + }; + const handleCreateCollection = useCallback(async () => { if (!newCollectionName.trim()) return; try { @@ -479,6 +505,22 @@ export default function Profile() { 新建书单 + + setShowDropdown(false)} diff --git a/apps/mobile/src/screens/ProfileScreen.tsx b/apps/mobile/src/screens/ProfileScreen.tsx index ad6dd030..a8ef5d4f 100644 --- a/apps/mobile/src/screens/ProfileScreen.tsx +++ b/apps/mobile/src/screens/ProfileScreen.tsx @@ -379,6 +379,15 @@ export function ProfileScreen() { 新建书单 + + handleSync('incremental')} disabled={!!syncing}> + + 增量更新 + + handleSync('full')} disabled={!!syncing}> + + 全量更新 + {user?.role === 'admin' && ( <> @@ -386,14 +395,6 @@ export function ProfileScreen() { 用户管理 - handleSync('incremental')} disabled={!!syncing}> - - 增量更新 - - handleSync('full')} disabled={!!syncing}> - - 全量更新 - )} diff --git a/package.json b/package.json index dec1e335..d126c5de 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "private": true, "packageManager": "pnpm@10.33.4", "scripts": { - "dev": "pnpm -r dev", + "dev": "concurrently \"pnpm --filter @bookdock/server run dev\" \"pnpm --filter @bookdock/desktop run dev\"", "dev:desktop": "pnpm --filter @bookdock/desktop dev:desktop", "build": "pnpm -r build", "lint": "pnpm -r lint", @@ -15,6 +15,7 @@ "devDependencies": { "@tailwindcss/typography": "^0.5.19", "babel-plugin-module-resolver": "^5.0.3", + "concurrently": "^10.0.3", "vite-plugin-pwa": "^1.2.0", "workbox-window": "^7.4.0" }, @@ -24,4 +25,4 @@ "react": "18.3.1", "react-native": "0.76.9" } -} +} \ No newline at end of file diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9e73d924..5fe6dde0 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -32,6 +32,9 @@ importers: babel-plugin-module-resolver: specifier: ^5.0.3 version: 5.0.3 + concurrently: + specifier: ^10.0.3 + version: 10.0.3 vite-plugin-pwa: specifier: ^1.2.0 version: 1.3.0(vite@5.4.21(@types/node@24.12.3)(lightningcss@1.27.0)(terser@5.46.1))(workbox-build@7.4.1(@types/babel__core@7.20.5))(workbox-window@7.4.1) @@ -3879,6 +3882,10 @@ packages: resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} engines: {node: '>=12'} + cliui@9.0.1: + resolution: {integrity: sha512-k7ndgKhwoQveBL+/1tqGJYNz097I7WOvwbmmU2AR5+magtbjPWQTS1C5vzGkBC8Ym8UWRzfKUzUUqFLypY4Q+w==} + engines: {node: '>=20'} + clone-deep@4.0.1: resolution: {integrity: sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==} engines: {node: '>=6'} @@ -3985,6 +3992,11 @@ packages: resolution: {integrity: sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==} engines: {'0': node >= 6.0} + concurrently@10.0.3: + resolution: {integrity: sha512-hc3LH4UaKWd/bbyDK/IGVa4RB6PtQ3CUYwtrkzqHn+wIG3Hr5fhpRlk0L/gCa8ZE1L/Ufj50Zho69cI5w8SQBA==} + engines: {node: '>=22'} + hasBin: true + config-file-ts@0.2.8-rc1: resolution: {integrity: sha512-GtNECbVI82bT4RiDIzBSVuTKoSHufnU7Ce7/42bkWZJZFLjmDF2WBpVsvRkhKCfKBnTBb3qZrBwPpFBU/Myvhg==} @@ -4314,6 +4326,9 @@ packages: engines: {node: '>= 22.12.0'} hasBin: true + emoji-regex@10.6.0: + resolution: {integrity: sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==} + emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} @@ -4949,6 +4964,10 @@ packages: resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} engines: {node: 6.* || 8.* || >= 10.*} + get-east-asian-width@1.6.0: + resolution: {integrity: sha512-QRbvDIbx6YklUe6RxeTeleMR0yv3cYH6PsPZHcnVn7xv7zO1BHN8r0XETu8n6Ye3Q+ahtSarc3WgtNWmehIBfA==} + engines: {node: '>=18'} + get-intrinsic@1.3.0: resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} engines: {node: '>= 0.4'} @@ -7136,6 +7155,10 @@ packages: resolution: {integrity: sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw==} engines: {node: '>= 0.4'} + shell-quote@1.8.4: + resolution: {integrity: sha512-VsC6n6vz1ihYYyZZwX7YZSF5l5x36ca17OC+a69h94YqB7X6XLwf+5MOgynYir2SLFUbl8gIYvBo8K8RoNQ6bQ==} + engines: {node: '>= 0.4'} + side-channel-list@1.0.0: resolution: {integrity: sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==} engines: {node: '>= 0.4'} @@ -7305,6 +7328,10 @@ packages: resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} engines: {node: '>=12'} + string-width@7.2.0: + resolution: {integrity: sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==} + engines: {node: '>=18'} + string.prototype.matchall@4.0.12: resolution: {integrity: sha512-6CC9uyBL+/48dYizRf7H7VAYCMCNTBeM78x/VTUe9bFEaxBepPJDa1Ow99LqI/1yF7kuy7Q3cQsYMrcjGUcskA==} engines: {node: '>= 0.4'} @@ -7394,6 +7421,10 @@ packages: resolution: {integrity: sha512-MvjXzkz/BOfyVDkG0oFOtBxHX2u3gKbMHIF/dXblZsgD3BWOFLmHovIpZY7BykJdAjcqRCBi1WYBNdEC9yI7vg==} engines: {node: '>= 8.0'} + supports-color@10.2.2: + resolution: {integrity: sha512-SS+jx45GF1QjgEXQx4NJZV9ImqmO2NPz5FNsIHrsDjh2YsHnawpan7SNQ1o8NuhrbHZy9AZhIoCUiCeaW/C80g==} + engines: {node: '>=18'} + supports-color@5.5.0: resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} engines: {node: '>=4'} @@ -8026,6 +8057,10 @@ packages: resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} engines: {node: '>=12'} + wrap-ansi@9.0.2: + resolution: {integrity: sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==} + engines: {node: '>=18'} + wrappy@1.0.2: resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} @@ -8130,10 +8165,18 @@ packages: resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} engines: {node: '>=12'} + yargs-parser@22.0.0: + resolution: {integrity: sha512-rwu/ClNdSMpkSrUb+d6BRsSkLUq1fmfsY6TOpYzTwvwkg1/NRG85KBy3kq++A8LKQwX6lsu+aWad+2khvuXrqw==} + engines: {node: ^20.19.0 || ^22.12.0 || >=23} + yargs@17.7.2: resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} engines: {node: '>=12'} + yargs@18.0.0: + resolution: {integrity: sha512-4UEqdc2RYGHZc7Doyqkrqiln3p9X2DZVxaGbwhn2pi7MrRagKaOcIKe8L3OxYcbhXLgLFUS3zAYuQjKBQgmuNg==} + engines: {node: ^20.19.0 || ^22.12.0 || >=23} + yauzl@2.10.0: resolution: {integrity: sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==} @@ -12320,6 +12363,12 @@ snapshots: strip-ansi: 6.0.1 wrap-ansi: 7.0.0 + cliui@9.0.1: + dependencies: + string-width: 7.2.0 + strip-ansi: 7.2.0 + wrap-ansi: 9.0.2 + clone-deep@4.0.1: dependencies: is-plain-object: 2.0.4 @@ -12429,6 +12478,15 @@ snapshots: readable-stream: 3.6.2 typedarray: 0.0.6 + concurrently@10.0.3: + dependencies: + chalk: 5.6.2 + rxjs: 7.8.2 + shell-quote: 1.8.4 + supports-color: 10.2.2 + tree-kill: 1.2.2 + yargs: 18.0.0 + config-file-ts@0.2.8-rc1: dependencies: glob: 10.5.0 @@ -12796,6 +12854,8 @@ snapshots: transitivePeerDependencies: - supports-color + emoji-regex@10.6.0: {} + emoji-regex@8.0.0: {} emoji-regex@9.2.2: {} @@ -13668,6 +13728,8 @@ snapshots: get-caller-file@2.0.5: {} + get-east-asian-width@1.6.0: {} + get-intrinsic@1.3.0: dependencies: call-bind-apply-helpers: 1.0.2 @@ -16167,6 +16229,8 @@ snapshots: shell-quote@1.8.3: {} + shell-quote@1.8.4: {} + side-channel-list@1.0.0: dependencies: es-errors: 1.3.0 @@ -16337,6 +16401,12 @@ snapshots: emoji-regex: 9.2.2 strip-ansi: 7.2.0 + string-width@7.2.0: + dependencies: + emoji-regex: 10.6.0 + get-east-asian-width: 1.6.0 + strip-ansi: 7.2.0 + string.prototype.matchall@4.0.12: dependencies: call-bind: 1.0.9 @@ -16448,6 +16518,8 @@ snapshots: transitivePeerDependencies: - supports-color + supports-color@10.2.2: {} + supports-color@5.5.0: dependencies: has-flag: 3.0.0 @@ -17167,6 +17239,12 @@ snapshots: string-width: 5.1.2 strip-ansi: 7.2.0 + wrap-ansi@9.0.2: + dependencies: + ansi-styles: 6.2.3 + string-width: 7.2.0 + strip-ansi: 7.2.0 + wrappy@1.0.2: {} write-file-atomic@2.4.3: @@ -17220,6 +17298,8 @@ snapshots: yargs-parser@21.1.1: {} + yargs-parser@22.0.0: {} + yargs@17.7.2: dependencies: cliui: 8.0.1 @@ -17230,6 +17310,15 @@ snapshots: y18n: 5.0.8 yargs-parser: 21.1.1 + yargs@18.0.0: + dependencies: + cliui: 9.0.1 + escalade: 3.2.0 + get-caller-file: 2.0.5 + string-width: 7.2.0 + y18n: 5.0.8 + yargs-parser: 22.0.0 + yauzl@2.10.0: dependencies: buffer-crc32: 0.2.13