环境
--
-
- 111 -
From fcad3681b40fd8a8c5ab4627b181174bfb0001b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=B0=A2=E4=BA=9A=E6=98=95?= <1549469775@qq.com> Date: Thu, 8 May 2025 09:58:36 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0fs-extra=E4=BE=9D?= =?UTF-8?q?=E8=B5=96=E5=B9=B6=E4=BC=98=E5=8C=96=E4=BB=A3=E7=A0=81=E7=BB=93?= =?UTF-8?q?=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 添加fs-extra依赖以增强文件操作功能 - 优化NavBar.vue,增加设置按钮 - 重构_ioc.ts和_ioc.main.ts,实现自动加载服务模块和命令模块 - 修复PopupMenu.ts中的点击事件逻辑 - 更新.vscode/settings.json中的默认格式化工具 --- .vscode/settings.json | 2 +- package.json | 1 + pnpm-lock.yaml | 32 ++++++++++++++++++ src/common/_ioc.main.ts | 26 ++++++++++----- src/common/event/Snippet/main/command.ts | 31 +++++++++++++++++- src/main/controller/_ioc.ts | 22 ++++++++++--- src/renderer/about.html | 56 +++++++++++++++++--------------- src/renderer/src/bridge/PopupMenu.ts | 13 ++++---- src/renderer/src/ui/NavBar.vue | 5 +++ 9 files changed, 141 insertions(+), 47 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 457ab0c..2571d5c 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,6 +1,6 @@ { "[typescript]": { - "editor.defaultFormatter": "esbenp.prettier-vscode" + "editor.defaultFormatter": "vscode.typescript-language-features" }, "[javascript]": { "editor.defaultFormatter": "esbenp.prettier-vscode" diff --git a/package.json b/package.json index 64941bb..0b1844d 100644 --- a/package.json +++ b/package.json @@ -28,6 +28,7 @@ "@electron-toolkit/preload": "^3.0.1", "@electron-toolkit/utils": "^3.0.0", "electron-updater": "^6.3.9", + "fs-extra": "^11.3.0", "inversify": "^6.2.2", "lowdb": "^7.0.1", "reflect-metadata": "^0.2.2" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e3edc57..cfc77cd 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -17,6 +17,9 @@ importers: electron-updater: specifier: ^6.3.9 version: 6.3.9 + fs-extra: + specifier: ^11.3.0 + version: 11.3.0 inversify: specifier: ^6.2.2 version: 6.2.2(reflect-metadata@0.2.2) @@ -886,21 +889,25 @@ packages: resolution: {integrity: sha512-eEwxY+0Cf76HnQwr1+Qy48qwf4dAebTHaKhzEgxLqLK6szbglnK6SThjY95YHrYWwsH1GujWiFoX51jwZNYfSw==} cpu: [arm64] os: [linux] + libc: [glibc] '@oxc-resolver/binding-linux-arm64-musl@3.0.3': resolution: {integrity: sha512-LdxbLv8qVkzro4/ZoP9MuytIL6NOVsbhoZ5Wl1KXOa/2DSxBiksrAPMSChCTyeLy6P3ebSHxQSb52ku18t1LBA==} cpu: [arm64] os: [linux] + libc: [musl] '@oxc-resolver/binding-linux-x64-gnu@3.0.3': resolution: {integrity: sha512-bN8elR9AV/DZZPdcteOWWElkz8KyxLtOvmfVl7Dnehcs6f9e+fWYKyqiKvva1jsxG4znGKCPT1gfMhpYW8QuKg==} cpu: [x64] os: [linux] + libc: [glibc] '@oxc-resolver/binding-linux-x64-musl@3.0.3': resolution: {integrity: sha512-Zy1U49BjriwbAds2ho6CGjZIk2KVn0+lrc/G5bvhQg7UJYxEkAueMGBuA5rULIhx9xVtIPsT9Q+J5Xhb4ffVNw==} cpu: [x64] os: [linux] + libc: [musl] '@oxc-resolver/binding-wasm32-wasi@3.0.3': resolution: {integrity: sha512-7rteQnn7i5f9nkFZs1VRdBqFhvOx3zWavyKkWjXYVxc9vsSLTg0moh2MRZw5dw5m/bEi1u/p3YAKJ9gdHyBhNQ==} @@ -946,36 +953,42 @@ packages: engines: {node: '>= 10.0.0'} cpu: [arm] os: [linux] + libc: [glibc] '@parcel/watcher-linux-arm-musl@2.5.0': resolution: {integrity: sha512-6uHywSIzz8+vi2lAzFeltnYbdHsDm3iIB57d4g5oaB9vKwjb6N6dRIgZMujw4nm5r6v9/BQH0noq6DzHrqr2pA==} engines: {node: '>= 10.0.0'} cpu: [arm] os: [linux] + libc: [musl] '@parcel/watcher-linux-arm64-glibc@2.5.0': resolution: {integrity: sha512-BfNjXwZKxBy4WibDb/LDCriWSKLz+jJRL3cM/DllnHH5QUyoiUNEp3GmL80ZqxeumoADfCCP19+qiYiC8gUBjA==} engines: {node: '>= 10.0.0'} cpu: [arm64] os: [linux] + libc: [glibc] '@parcel/watcher-linux-arm64-musl@2.5.0': resolution: {integrity: sha512-S1qARKOphxfiBEkwLUbHjCY9BWPdWnW9j7f7Hb2jPplu8UZ3nes7zpPOW9bkLbHRvWM0WDTsjdOTUgW0xLBN1Q==} engines: {node: '>= 10.0.0'} cpu: [arm64] os: [linux] + libc: [musl] '@parcel/watcher-linux-x64-glibc@2.5.0': resolution: {integrity: sha512-d9AOkusyXARkFD66S6zlGXyzx5RvY+chTP9Jp0ypSTC9d4lzyRs9ovGf/80VCxjKddcUvnsGwCHWuF2EoPgWjw==} engines: {node: '>= 10.0.0'} cpu: [x64] os: [linux] + libc: [glibc] '@parcel/watcher-linux-x64-musl@2.5.0': resolution: {integrity: sha512-iqOC+GoTDoFyk/VYSFHwjHhYrk8bljW6zOhPuhi5t9ulqiYq1togGJB5e3PwYVFFfeVgc6pbz3JdQyDoBszVaA==} engines: {node: '>= 10.0.0'} cpu: [x64] os: [linux] + libc: [musl] '@parcel/watcher-win32-arm64@2.5.0': resolution: {integrity: sha512-twtft1d+JRNkM5YbmexfcH/N4znDtjgysFaV9zvZmmJezQsKpkfLYJ+JFV3uygugK6AtIM2oADPkB2AdhBrNig==} @@ -1062,46 +1075,55 @@ packages: resolution: {integrity: sha512-paHF1bMXKDuizaMODm2bBTjRiHxESWiIyIdMugKeLnjuS1TCS54MF5+Y5Dx8Ui/1RBPVRE09i5OUlaLnv8OGnA==} cpu: [arm] os: [linux] + libc: [glibc] '@rollup/rollup-linux-arm-musleabihf@4.26.0': resolution: {integrity: sha512-cwxiHZU1GAs+TMxvgPfUDtVZjdBdTsQwVnNlzRXC5QzIJ6nhfB4I1ahKoe9yPmoaA/Vhf7m9dB1chGPpDRdGXg==} cpu: [arm] os: [linux] + libc: [musl] '@rollup/rollup-linux-arm64-gnu@4.26.0': resolution: {integrity: sha512-4daeEUQutGRCW/9zEo8JtdAgtJ1q2g5oHaoQaZbMSKaIWKDQwQ3Yx0/3jJNmpzrsScIPtx/V+1AfibLisb3AMQ==} cpu: [arm64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-arm64-musl@4.26.0': resolution: {integrity: sha512-eGkX7zzkNxvvS05ROzJ/cO/AKqNvR/7t1jA3VZDi2vRniLKwAWxUr85fH3NsvtxU5vnUUKFHKh8flIBdlo2b3Q==} cpu: [arm64] os: [linux] + libc: [musl] '@rollup/rollup-linux-powerpc64le-gnu@4.26.0': resolution: {integrity: sha512-Odp/lgHbW/mAqw/pU21goo5ruWsytP7/HCC/liOt0zcGG0llYWKrd10k9Fj0pdj3prQ63N5yQLCLiE7HTX+MYw==} cpu: [ppc64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-riscv64-gnu@4.26.0': resolution: {integrity: sha512-MBR2ZhCTzUgVD0OJdTzNeF4+zsVogIR1U/FsyuFerwcqjZGvg2nYe24SAHp8O5sN8ZkRVbHwlYeHqcSQ8tcYew==} cpu: [riscv64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-s390x-gnu@4.26.0': resolution: {integrity: sha512-YYcg8MkbN17fMbRMZuxwmxWqsmQufh3ZJFxFGoHjrE7bv0X+T6l3glcdzd7IKLiwhT+PZOJCblpnNlz1/C3kGQ==} cpu: [s390x] os: [linux] + libc: [glibc] '@rollup/rollup-linux-x64-gnu@4.26.0': resolution: {integrity: sha512-ZuwpfjCwjPkAOxpjAEjabg6LRSfL7cAJb6gSQGZYjGhadlzKKywDkCUnJ+KEfrNY1jH5EEoSIKLCb572jSiglA==} cpu: [x64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-x64-musl@4.26.0': resolution: {integrity: sha512-+HJD2lFS86qkeF8kNu0kALtifMpPCZU80HvwztIKnYwym3KnA1os6nsX4BGSTLtS2QVAGG1P3guRgsYyMA0Yhg==} cpu: [x64] os: [linux] + libc: [musl] '@rollup/rollup-win32-arm64-msvc@4.26.0': resolution: {integrity: sha512-WUQzVFWPSw2uJzX4j6YEbMAiLbs0BUysgysh8s817doAYhR5ybqTI1wtKARQKo6cGop3pHnrUJPFCsXdoFaimQ==} @@ -2337,6 +2359,10 @@ packages: resolution: {integrity: sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==} engines: {node: '>=12'} + fs-extra@11.3.0: + resolution: {integrity: sha512-Z4XaCL6dUDHfP/jT25jJKMmtxvuwbkrD1vNSMFlo9lNLY2c5FHYSQgHPRZUjAB26TpDEoW9HCOgplrdbaPV/ew==} + engines: {node: '>=14.14'} + fs-extra@8.1.0: resolution: {integrity: sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==} engines: {node: '>=6 <7 || >=8'} @@ -6270,6 +6296,12 @@ snapshots: jsonfile: 6.1.0 universalify: 2.0.1 + fs-extra@11.3.0: + dependencies: + graceful-fs: 4.2.11 + jsonfile: 6.1.0 + universalify: 2.0.1 + fs-extra@8.1.0: dependencies: graceful-fs: 4.2.11 diff --git a/src/common/_ioc.main.ts b/src/common/_ioc.main.ts index 724a017..7ba0ba9 100644 --- a/src/common/_ioc.main.ts +++ b/src/common/_ioc.main.ts @@ -1,16 +1,26 @@ import { Container, ContainerModule } from "inversify" -import UpdateCommand from "common/event/Update/main/command" -import PlatFormCommand from "common/event/PlatForm/main/command" -import SnippetCommand from "common/event/Snippet/main/command" -import TabsCommand from "common/event/Tabs/main/command" + +/** + * 自动加载所有命令模块 + */ +const commandModules = import.meta.glob("./event/**/main/command.{ts,js}", { eager: true }) const modules = new ContainerModule(bind => { - bind("TabsCommand").to(TabsCommand).inSingletonScope() - bind("PlatFormCommand").to(PlatFormCommand).inSingletonScope() - bind("SnippetCommand").to(SnippetCommand).inSingletonScope() - bind("UpdateCommand").to(UpdateCommand).inSingletonScope() + // 自动绑定所有命令类 + Object.values(commandModules).forEach(module => { + // 由于 module 类型为 unknown,先进行类型断言为包含 default 属性的对象 + const CommandClass = (module as { default: any }).default + if (CommandClass) { + const className = CommandClass.name.replace("Command", "") + bind(className + "Command").to(CommandClass).inSingletonScope() + } + }) }) +/** + * 销毁所有命令绑定 + * @param ioc - Inversify 容器实例 + */ async function destroyAllCommand(ioc: Container) { await ioc.unloadAsync(modules) } diff --git a/src/common/event/Snippet/main/command.ts b/src/common/event/Snippet/main/command.ts index a673753..3ae6136 100644 --- a/src/common/event/Snippet/main/command.ts +++ b/src/common/event/Snippet/main/command.ts @@ -1,3 +1,4 @@ +import fs from "fs-extra" import path from "path/posix" import Setting from "setting/main" @@ -8,8 +9,36 @@ import Setting from "setting/main" export default class SnippetCommand { storagePath: string = Setting.values("snippet.storagePath") + constructor() { + const handler = { + get: function (target, prop, receiver) { + if (!target["check"]()) { + throw new Error(`代码片段路径存在问题`) + } + const value = target[prop] + if (typeof value === "function") { + return (...args) => Reflect.apply(value, receiver, args) + } + return value + }, + } + return new Proxy(this, handler) + } + + async check() { + const stat = await fs.statSync(this.storagePath) + const inforFile = path.resolve(this.storagePath, "__snippet__.json") + if (stat.isDirectory() && stat.size == 0) { + await fs.writeJSON(inforFile, {}) + // 空文件夹, 初始化信息 + return true + } else { + const isExist = await fs.pathExists(inforFile) + return isExist + } + } + getTree() { - path.resolve(this.storagePath, "__snippet__.json") return this.storagePath } } diff --git a/src/main/controller/_ioc.ts b/src/main/controller/_ioc.ts index f568ca2..c5fb51a 100644 --- a/src/main/controller/_ioc.ts +++ b/src/main/controller/_ioc.ts @@ -1,12 +1,26 @@ import { Container, ContainerModule } from "inversify" -import BasicService from "./BasicService" -import TabsService from "./TabsService" + +/** + * 自动加载所有服务模块 + */ +const serviceModules = import.meta.glob("./*.{ts,js}", { eager: true }) const modules = new ContainerModule(bind => { - bind("BasicService").to(BasicService).inSingletonScope() - bind("TabsService").to(TabsService).inSingletonScope() + // 自动绑定所有服务类 + Object.values(serviceModules).forEach(module => { + // 由于 module 类型为 unknown,需要进行类型断言 + const ServiceClass = (module as { default: any }).default + if (ServiceClass && ServiceClass.name.endsWith("Service")) { + const serviceName = ServiceClass.name + bind(serviceName).to(ServiceClass).inSingletonScope() + } + }) }) +/** + * 销毁所有控制器绑定 + * @param ioc - Inversify 容器实例 + */ async function destroyAllController(ioc: Container) { await ioc.unloadAsync(modules) } diff --git a/src/renderer/about.html b/src/renderer/about.html index a458d63..9a4ea33 100644 --- a/src/renderer/about.html +++ b/src/renderer/about.html @@ -1,30 +1,32 @@ -
- - -