From bac97bc41cb3fb795e7ac15eeb9e111f8e12ae32 Mon Sep 17 00:00:00 2001 From: lq1405 <2769838458@qq.com> Date: Mon, 24 Jun 2024 13:11:19 +0800 Subject: [PATCH] =?UTF-8?q?V=202.2.10=20=E6=96=B0=E5=A2=9EMJ=E7=9A=84?= =?UTF-8?q?=E4=BB=A3=E7=90=86=E6=A8=A1=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 1 + default.realm | Bin 0 -> 65536 bytes default.realm.lock | Bin 0 -> 1416 bytes package-lock.json | 264 +++- package.json | 14 +- resources/scripts/Lai.py | 11 +- .../scripts/__pycache__/clip.cpython-310.pyc | Bin 11533 -> 11506 bytes .../iamge_to_video.cpython-310.pyc | Bin 9029 -> 9027 bytes .../__pycache__/shotSplit.cpython-310.pyc | Bin 5039 -> 5390 bytes resources/scripts/db/book.realm | Bin 0 -> 65536 bytes resources/scripts/db/book.realm.lock | Bin 0 -> 1416 bytes resources/scripts/db/software.realm | Bin 0 -> 65536 bytes resources/scripts/db/software.realm.lock | Bin 0 -> 1416 bytes resources/scripts/shotSplit.py | 17 + src/api/discordApi.js | 6 + src/define/Tools/file.js | 82 ++ .../db/model/Book/BookBackTaskListModel.ts | 28 + src/define/db/model/Book/book.ts | 37 + src/define/db/model/Book/bookTask.ts | 43 + src/define/db/model/Book/bookTaskDetail.ts | 163 +++ src/define/db/model/SoftWare/logger.ts | 27 + src/define/db/model/SoftWare/mjSetting.ts | 136 ++ src/define/db/model/SoftWare/software.ts | 23 + .../service/Book/bookBackTaskListService.ts | 141 ++ src/define/db/service/Book/bookBasic.ts | 83 ++ src/define/db/service/Book/bookService.ts | 214 +++ .../db/service/Book/bookTaskDetailService.ts | 47 + src/define/db/service/Book/bookTaskService.ts | 139 ++ .../db/service/SoftWare/loggerService.ts | 80 + .../db/service/SoftWare/mjSettingService.ts | 611 ++++++++ .../db/service/SoftWare/softwareBasic.ts | 133 ++ .../db/service/SoftWare/softwareService.ts | 78 + src/define/db/service/baseService.ts | 36 + src/define/define.js | 6 + src/define/define_string.js | 19 +- src/define/enum/bookEnum.ts | 154 ++ src/define/enum/mjEnum.ts | 21 + src/define/enum/softwareEnum.ts | 42 + src/define/logger_define.js | 3 +- src/define/setting/mjSetting.js | 4 +- src/main/IPCEvent/bookIpc.js | 27 + src/main/IPCEvent/imageGenerateIpc.js | 2 +- src/main/IPCEvent/index.js | 4 +- src/main/IPCEvent/promptIpc.js | 3 + src/main/IPCEvent/settingIpc.js | 34 + src/main/IPCEvent/system.js | 17 - src/main/IPCEvent/systemIpc.js | 40 + src/main/IPCEvent/videoGenerateIpc.js | 2 +- src/main/IPCEvent/writingIpc.js | 2 +- src/main/Original/MJOriginalImageGenerate.js | 135 +- src/main/Public/Prompt.js | 44 + src/main/ReverseManage/Book/BooKBasic.js | 63 + src/main/ReverseManage/Book/ReverseBook.js | 49 + .../imageGenerate.js | 0 .../videoGenerate.js | 0 .../{backPrompt => ReverseManage}/writing.js | 0 src/main/Task/basicReverse.js | 95 ++ src/main/Task/mjReverse.js | 0 src/main/Task/sdReverse.js | 0 src/main/Task/taskScheduler.js | 41 + src/main/discord/discordSimple.js | 6 +- src/main/discord/discordWorker.js | 35 +- src/main/func.js | 1 + src/main/index.js | 10 +- src/main/logger.js | 2 +- src/main/setting/autoSync.js | 138 ++ src/main/setting/basicSetting.js | 67 + src/main/setting/bookSetting.js | 5 + src/main/setting/mjSetting.js | 155 ++ src/main/setting/setting.js | 4 +- src/preload/book.js | 28 + src/preload/index.js | 7 +- src/preload/prompt.js | 5 +- src/preload/setting.js | 28 + src/preload/system.js | 3 + src/renderer/src/App.vue | 48 +- src/renderer/src/assets/css/styles.less | 2 + .../src/components/Backstep/GetFrame.vue | 8 +- .../components/Backstep/oneImageReDrwa.vue | 1291 +++++++++-------- .../src/components/Components/Artplayer.vue | 36 + src/renderer/src/components/Home/Home.vue | 35 +- .../Components/DataTableParameterRow.vue | 51 +- .../Original/Components/ImportWordAndSrt.vue | 113 +- .../Original/Components/PromptSetting.vue | 106 +- .../src/components/Original/DataTable.vue | 2 +- .../src/components/Original/MainPage.vue | 66 +- .../src/components/Original/MenuButton.vue | 3 +- .../ReverseManage/Components/AddBook.vue | 263 ++++ .../Components/BookListAction.vue | 89 ++ .../Components/ManageBookButton.vue | 146 ++ .../Components/ManageBookDetailButton.vue | 60 + .../Components/ManageBookReverseTable.vue | 18 + .../Components/ManageBookShowLogger.vue | 87 ++ .../components/ReverseManage/ManageBook.vue | 207 +++ .../ReverseManage/ManageBookDetail.vue | 37 + .../ReverseManage/ManageBookTask.vue | 21 + .../ReverseManage/ReverseManage.vue | 48 + .../src/components/Setting/MJSetting.vue | 816 ++++++----- .../src/components/Setting/Setting.vue | 17 +- src/renderer/src/main.js | 2 + src/stores/reverseManage.js | 201 +++ src/stores/software.js | 58 + 102 files changed, 6374 insertions(+), 1172 deletions(-) create mode 100644 default.realm create mode 100644 default.realm.lock create mode 100644 resources/scripts/db/book.realm create mode 100644 resources/scripts/db/book.realm.lock create mode 100644 resources/scripts/db/software.realm create mode 100644 resources/scripts/db/software.realm.lock create mode 100644 src/define/db/model/Book/BookBackTaskListModel.ts create mode 100644 src/define/db/model/Book/book.ts create mode 100644 src/define/db/model/Book/bookTask.ts create mode 100644 src/define/db/model/Book/bookTaskDetail.ts create mode 100644 src/define/db/model/SoftWare/logger.ts create mode 100644 src/define/db/model/SoftWare/mjSetting.ts create mode 100644 src/define/db/model/SoftWare/software.ts create mode 100644 src/define/db/service/Book/bookBackTaskListService.ts create mode 100644 src/define/db/service/Book/bookBasic.ts create mode 100644 src/define/db/service/Book/bookService.ts create mode 100644 src/define/db/service/Book/bookTaskDetailService.ts create mode 100644 src/define/db/service/Book/bookTaskService.ts create mode 100644 src/define/db/service/SoftWare/loggerService.ts create mode 100644 src/define/db/service/SoftWare/mjSettingService.ts create mode 100644 src/define/db/service/SoftWare/softwareBasic.ts create mode 100644 src/define/db/service/SoftWare/softwareService.ts create mode 100644 src/define/db/service/baseService.ts create mode 100644 src/define/enum/bookEnum.ts create mode 100644 src/define/enum/mjEnum.ts create mode 100644 src/define/enum/softwareEnum.ts create mode 100644 src/main/IPCEvent/bookIpc.js delete mode 100644 src/main/IPCEvent/system.js create mode 100644 src/main/IPCEvent/systemIpc.js create mode 100644 src/main/ReverseManage/Book/BooKBasic.js create mode 100644 src/main/ReverseManage/Book/ReverseBook.js rename src/main/{backPrompt => ReverseManage}/imageGenerate.js (100%) rename src/main/{backPrompt => ReverseManage}/videoGenerate.js (100%) rename src/main/{backPrompt => ReverseManage}/writing.js (100%) create mode 100644 src/main/Task/basicReverse.js create mode 100644 src/main/Task/mjReverse.js create mode 100644 src/main/Task/sdReverse.js create mode 100644 src/main/Task/taskScheduler.js create mode 100644 src/main/setting/autoSync.js create mode 100644 src/main/setting/basicSetting.js create mode 100644 src/main/setting/bookSetting.js create mode 100644 src/main/setting/mjSetting.js create mode 100644 src/preload/book.js create mode 100644 src/renderer/src/components/Components/Artplayer.vue create mode 100644 src/renderer/src/components/ReverseManage/Components/AddBook.vue create mode 100644 src/renderer/src/components/ReverseManage/Components/BookListAction.vue create mode 100644 src/renderer/src/components/ReverseManage/Components/ManageBookButton.vue create mode 100644 src/renderer/src/components/ReverseManage/Components/ManageBookDetailButton.vue create mode 100644 src/renderer/src/components/ReverseManage/Components/ManageBookReverseTable.vue create mode 100644 src/renderer/src/components/ReverseManage/Components/ManageBookShowLogger.vue create mode 100644 src/renderer/src/components/ReverseManage/ManageBook.vue create mode 100644 src/renderer/src/components/ReverseManage/ManageBookDetail.vue create mode 100644 src/renderer/src/components/ReverseManage/ManageBookTask.vue create mode 100644 src/renderer/src/components/ReverseManage/ReverseManage.vue create mode 100644 src/stores/reverseManage.js create mode 100644 src/stores/software.js diff --git a/.gitignore b/.gitignore index d3ec3dd..7d823c7 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ node_modules dist out +project resources/scripts/build* resources/scripts/dist resources/scripts/model diff --git a/default.realm b/default.realm new file mode 100644 index 0000000000000000000000000000000000000000..a12894dbb39a6cd614078df27b9fea0e7cd76967 GIT binary patch literal 65536 zcmeIxJx^3Y6vpv0_pWFF-x3NN5*rdMHc>=atyY7&C5f0&n7Aukg+zt08>M6IEGaE1 zEh#N2{V0}}CdRDKnLFc}4Iklule_bBX3os~=I*zK#piobmmAHsM>lSmJ=AmAtaw)q zdfUB0ua4Tqt+%~?|K+p2*MpC}gUW)BQ!JLVDnC>Q{oTFyaenU4<(k=4yR&K5eIDal zI)s$i^C(`FhY#$9)$w-9JEd|o8XfsiA9t~Ct7~-R?Z;+Ub`<+;!M^A%?Zi&?>yPJu zVQX=oj#x~`-tqZ%w^K)5T<+^+8#~pzs%}qtepL%EwGU6x4tl+z%AKm& zy1%^KthQEH?yW4ZZr!U^H9YwE^Y(A$wX&^+JnsLCx4Un42J-T@+{)6{%WjJMd0s8G zZs+wYjT`EV$!(1Jb9j!h5`Wu5I_I{1Q0*~0R#|0009ILKmY** z5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0 z009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{ z1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009IL zKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~ z0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY** i5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0-ALf|hIPN{tW literal 0 HcmV?d00001 diff --git a/default.realm.lock b/default.realm.lock new file mode 100644 index 0000000000000000000000000000000000000000..7efaf534c6bd07ae1a1c9310bfa77a2c633fb859 GIT binary patch literal 1416 zcmZQ%=18" + } + }, "node_modules/@rollup/rollup-win32-x64-msvc": { "version": "4.9.4", "cpu": [ @@ -2935,6 +2945,14 @@ "version": "2.0.1", "license": "Python-2.0" }, + "node_modules/artplayer": { + "version": "5.1.6", + "resolved": "https://registry.npmmirror.com/artplayer/-/artplayer-5.1.6.tgz", + "integrity": "sha512-cqnVVLKCKWCryKl6Pmop50/Di9IQwOeNNQs5qWGzJDPiM0qTC7Q/Enusa+8JQid8p09fvp4Vc32ViSSYutdEeQ==", + "dependencies": { + "option-validator": "^2.0.6" + } + }, "node_modules/async": { "version": "3.2.5", "license": "MIT" @@ -3148,6 +3166,17 @@ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" } }, + "node_modules/bson": { + "version": "4.7.2", + "resolved": "https://registry.npmmirror.com/bson/-/bson-4.7.2.tgz", + "integrity": "sha512-Ry9wCtIZ5kGqkJoi6aD8KjxFZEx78guTQDnpXWiNthsxzrxAK/i8E6pCHAIZTbaEFWcOCvbecMukfK7XUvyLpQ==", + "dependencies": { + "buffer": "^5.6.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/buffer": { "version": "5.7.1", "funding": [ @@ -3931,6 +3960,14 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmmirror.com/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "engines": { + "node": ">=4.0.0" + } + }, "node_modules/deep-is": { "version": "0.1.4", "dev": true, @@ -4864,6 +4901,14 @@ "node_modules/exif-parser": { "version": "0.1.12" }, + "node_modules/expand-template": { + "version": "2.0.3", + "resolved": "https://registry.npmmirror.com/expand-template/-/expand-template-2.0.3.tgz", + "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==", + "engines": { + "node": ">=6" + } + }, "node_modules/extract-zip": { "version": "2.0.1", "license": "BSD-2-Clause", @@ -5214,6 +5259,11 @@ "omggif": "^1.0.10" } }, + "node_modules/github-from-package": { + "version": "0.0.0", + "resolved": "https://registry.npmmirror.com/github-from-package/-/github-from-package-0.0.0.tgz", + "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==" + }, "node_modules/glob": { "version": "7.2.3", "devOptional": true, @@ -6017,6 +6067,14 @@ "json-buffer": "3.0.1" } }, + "node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmmirror.com/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/kitx": { "version": "2.1.0", "license": "MIT", @@ -6430,6 +6488,11 @@ "node": ">=10" } }, + "node_modules/mkdirp-classic": { + "version": "0.5.3", + "resolved": "https://registry.npmmirror.com/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", + "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==" + }, "node_modules/moment": { "version": "2.30.1", "resolved": "https://registry.npmmirror.com/moment/-/moment-2.30.1.tgz", @@ -6463,8 +6526,9 @@ } }, "node_modules/naive-ui": { - "version": "2.37.3", - "license": "MIT", + "version": "2.38.2", + "resolved": "https://registry.npmmirror.com/naive-ui/-/naive-ui-2.38.2.tgz", + "integrity": "sha512-WhZ+6DW61aYSmFyfH7evcSGFmd2xR68Yq1mNRrVdJwBhZsnNdAUsMN9IeNCVEPMCND/jzYZghkStoNoR5Xa09g==", "dependencies": { "@css-render/plugin-bem": "^0.15.12", "@css-render/vue3-ssr": "^0.15.12", @@ -6512,6 +6576,11 @@ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, + "node_modules/napi-build-utils": { + "version": "1.0.2", + "resolved": "https://registry.npmmirror.com/napi-build-utils/-/napi-build-utils-1.0.2.tgz", + "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==" + }, "node_modules/natural-compare": { "version": "1.4.0", "dev": true, @@ -6532,6 +6601,28 @@ "node": ">= 4.4.x" } }, + "node_modules/node-abi": { + "version": "3.65.0", + "resolved": "https://registry.npmmirror.com/node-abi/-/node-abi-3.65.0.tgz", + "integrity": "sha512-ThjYBfoDNr08AWx6hGaRbfPwxKV9kVzAzOzlLKbk2CuqXE2xnCh+cbAGnwM3t8Lq4v9rUB7VfondlkBckcJrVA==", + "dependencies": { + "semver": "^7.3.5" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/node-abi/node_modules/semver": { + "version": "7.6.2", + "resolved": "https://registry.npmmirror.com/semver/-/semver-7.6.2.tgz", + "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/node-fetch": { "version": "2.7.0", "license": "MIT", @@ -9093,6 +9184,14 @@ "fn.name": "1.x.x" } }, + "node_modules/option-validator": { + "version": "2.0.6", + "resolved": "https://registry.npmmirror.com/option-validator/-/option-validator-2.0.6.tgz", + "integrity": "sha512-tmZDan2LRIRQyhUGvkff68/O0R8UmF+Btmiiz0SmSw2ng3CfPZB9wJlIjHpe/MKUZqyIZkVIXCrwr1tIN+0Dzg==", + "dependencies": { + "kind-of": "^6.0.3" + } + }, "node_modules/optionator": { "version": "0.9.3", "dev": true, @@ -9204,6 +9303,11 @@ "url": "https://github.com/inikulin/parse5?sponsor=1" } }, + "node_modules/path-browserify": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/path-browserify/-/path-browserify-1.0.1.tgz", + "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==" + }, "node_modules/path-exists": { "version": "4.0.0", "dev": true, @@ -9407,6 +9511,55 @@ "node": ">=4" } }, + "node_modules/prebuild-install": { + "version": "7.1.2", + "resolved": "https://registry.npmmirror.com/prebuild-install/-/prebuild-install-7.1.2.tgz", + "integrity": "sha512-UnNke3IQb6sgarcZIDU3gbMeTp/9SSU1DAIkil7PrqG1vZlBtY5msYccSKSHDqa3hNg436IXK+SNImReuA1wEQ==", + "dependencies": { + "detect-libc": "^2.0.0", + "expand-template": "^2.0.3", + "github-from-package": "0.0.0", + "minimist": "^1.2.3", + "mkdirp-classic": "^0.5.3", + "napi-build-utils": "^1.0.1", + "node-abi": "^3.3.0", + "pump": "^3.0.0", + "rc": "^1.2.7", + "simple-get": "^4.0.0", + "tar-fs": "^2.0.0", + "tunnel-agent": "^0.6.0" + }, + "bin": { + "prebuild-install": "bin.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/prebuild-install/node_modules/simple-get": { + "version": "4.0.1", + "resolved": "https://registry.npmmirror.com/simple-get/-/simple-get-4.0.1.tgz", + "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "decompress-response": "^6.0.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" + } + }, "node_modules/prelude-ls": { "version": "1.2.1", "dev": true, @@ -9561,6 +9714,28 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/rc": { + "version": "1.2.8", + "resolved": "https://registry.npmmirror.com/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "dependencies": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "bin": { + "rc": "cli.js" + } + }, + "node_modules/rc/node_modules/strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/read-config-file": { "version": "6.3.2", "dev": true, @@ -9612,6 +9787,31 @@ "minimatch": "^5.1.0" } }, + "node_modules/realm": { + "version": "12.9.0", + "resolved": "https://registry.npmmirror.com/realm/-/realm-12.9.0.tgz", + "integrity": "sha512-K7JblaSaqqFEu8kObgTCo1ITTYnR8rXYBdb5/5VXxD4VNKQVlrnO6Z4GhxDlohubmF8eNvRdC2wlHAsv2aUsOg==", + "hasInstallScript": true, + "dependencies": { + "@realm/fetch": "^0.1.1", + "bson": "^4.7.2", + "debug": "^4.3.4", + "node-machine-id": "^1.1.12", + "path-browserify": "^1.0.1", + "prebuild-install": "^7.1.1" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "react-native": ">=0.71.0" + }, + "peerDependenciesMeta": { + "react-native": { + "optional": true + } + } + }, "node_modules/regenerator-runtime": { "version": "0.14.1", "license": "MIT" @@ -9960,9 +10160,7 @@ "url": "https://feross.org/support" } ], - "license": "MIT", - "optional": true, - "peer": true + "license": "MIT" }, "node_modules/simple-get": { "version": "3.1.1", @@ -10275,6 +10473,47 @@ "node": ">=10" } }, + "node_modules/tar-fs": { + "version": "2.1.1", + "resolved": "https://registry.npmmirror.com/tar-fs/-/tar-fs-2.1.1.tgz", + "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", + "dependencies": { + "chownr": "^1.1.1", + "mkdirp-classic": "^0.5.2", + "pump": "^3.0.0", + "tar-stream": "^2.1.4" + } + }, + "node_modules/tar-fs/node_modules/bl": { + "version": "4.1.0", + "resolved": "https://registry.npmmirror.com/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/tar-fs/node_modules/chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmmirror.com/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" + }, + "node_modules/tar-fs/node_modules/tar-stream": { + "version": "2.2.0", + "resolved": "https://registry.npmmirror.com/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "dependencies": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/tar-stream": { "version": "1.6.2", "license": "MIT", @@ -10516,6 +10755,17 @@ "devOptional": true, "license": "0BSD" }, + "node_modules/tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmmirror.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", + "dependencies": { + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": "*" + } + }, "node_modules/type-check": { "version": "0.4.0", "dev": true, diff --git a/package.json b/package.json index f1df5f3..54c643d 100644 --- a/package.json +++ b/package.json @@ -1,9 +1,9 @@ { "name": "laitool", - "version": "2.2.9", - "description": "An Electron application with Vue", + "version": "2.2.10", + "description": "An AI tool for image processing, video processing, and other functions.", "main": "./out/main/index.js", - "author": "example.com", + "author": "laitool.cn", "homepage": "https://electron-vite.org", "scripts": { "format": "prettier --write .", @@ -25,6 +25,7 @@ "@vitejs/plugin-vue-jsx": "^3.1.0", "@volcengine/openapi": "^1.16.0", "7zip-min": "^1.4.4", + "artplayer": "^5.1.6", "awesome-js": "^2.0.0", "axios": "^1.6.5", "blob-to-buffer": "^1.2.9", @@ -44,6 +45,7 @@ "npm": "^10.7.0", "paddle": "^1.0.0", "pinia": "^2.1.7", + "realm": "^12.9.0", "sharp": "^0.33.2", "systeminformation": "^5.22.10", "tencentcloud-sdk-nodejs": "^4.0.821", @@ -65,7 +67,7 @@ "eslint": "^8.56.0", "eslint-plugin-vue": "^9.19.2", "less": "^4.2.0", - "naive-ui": "^2.37.3", + "naive-ui": "^2.38.2", "prettier": "^3.1.1", "vfonts": "^0.0.3", "vite": "^5.0.11", @@ -84,8 +86,6 @@ "resources/image/style/**", "resources/image/zhanwei.png", "resources/scripts/model/**", - "resources/scripts/Lai.exe", - "resources/scripts/_internal/**", "resources/scripts/discordScript.js", "resources/tmp/**", "resources/icon.ico" @@ -94,4 +94,4 @@ "icon": "./resources/icon.ico" } } -} +} \ No newline at end of file diff --git a/resources/scripts/Lai.py b/resources/scripts/Lai.py index 750ec29..a9da896 100644 --- a/resources/scripts/Lai.py +++ b/resources/scripts/Lai.py @@ -15,9 +15,10 @@ sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding="utf-8") if len(sys.argv) < 2: sys.argv = [ "C:\\Users\\27698\\Desktop\\LAITool\\resources\\scripts\\Lai.exe", - "-c", - "C:/Users/27698/Desktop/测试/mjTest/scripts/output_crop_00001.json", - "NVIDIA", + "-ka", + "C:\\Users\\27698\\Desktop\\测试\\123\\测试用 不删.mp4", + "C:\\Users\\27698\\Desktop\\测试\\123\\测试用 不删.json", + 30 ] print(sys.argv) @@ -84,6 +85,10 @@ elif sys.argv[1] == "-k": getgrame.init(sys.argv[2], sys.argv[3], sys.argv[4]) pass +elif sys.argv[1] == "-ka": + shotSplit.get_fram(sys.argv[2], sys.argv[3], sys.argv[4]) + pass + # 智能分镜。字幕识别 elif sys.argv[1] == "-a": print("开始算法分镜:" + sys.argv[2] + " -- 输出文件夹:" + sys.argv[3]) diff --git a/resources/scripts/__pycache__/clip.cpython-310.pyc b/resources/scripts/__pycache__/clip.cpython-310.pyc index e80c4de6483081420deb8ce0975b8b5cef0e6388..7b644968515fe21c04a697d6f0d4163a10ed203e 100644 GIT binary patch delta 358 zcmeB;`V`5V&&$ij00ggOQ_`F^@)`&+vTe2#%3%!TuVKg%N)gFsDmqfbvw%NEXdxpb z1DGWWXNkdBHEb|eia3l_!d=7B%n0M9NKEDz5oeT~EGuF-IYLB0UI1*C97sM-5N6i| z#v&Q8xcuaHkwnI($uC7b#goDrQW#i(u$h?=$O>jKWSGEMTs_%Sw4RkE!^q5J@-5M7 zP7V+&J~20Ka|p;;3nqUP51#BR;m^2r^IVC1CPtObywV>S8N)XJlTl`54BD(DXT!{x zvpHT-h?y~ObCF6b6I%{29Ex%$|5el0&Id8GK|}$FCMWQ?C2tg{OMC$wKR delta 319 zcmewq*&D^1&&$ij00f46BGVRbPNRCKO}X90hTz(Phw z1~5x>@ TVPxdnETFB<$e1|ULT48MxiVRf diff --git a/resources/scripts/__pycache__/iamge_to_video.cpython-310.pyc b/resources/scripts/__pycache__/iamge_to_video.cpython-310.pyc index 22ed7a5649a0cafa8b87ef95e1f0b9d49b6934ff..d80ab2400b2a4ae1f939906edb764c6d2fc960a3 100644 GIT binary patch delta 37 rcmX@=cG!(KpO=@50SF|1<)y`Ji delta 39 tcmX@?cGQhGpO=@50SLNwN2bMX|;{mlEG!Ql>q%bX%{>*fN#FW&e zCYoqeG9lpziBV4)f(N5UFCLA5Ks{ICY`kcqzPH4SJDJaW?>p~x-p*`a_C4(P6}?^$ zfoEXUPKS@K`#S0C^?^iH&FPlT2y4n2d9UTA1bkP{mv6S39be7)Ek9^lE|3peLD1aH zbB9}A}pY&YD?;~V?3>#yz`RZk_ruk#{3-iT8-No@;bm==uho6x;gKILfz_Q~ACT9a+c zs4dxYMXu2rjgT6p1T^Wuq6)E6p-iqxk9=#2t!_0{j(o82h^2fDOIQ|PNl+@^CeT|EwEr|cxI*KC3}%aFuT>sPG@o{-j1<@4ivS8 z6r3(k=D$Hy#-2PhOf?vW;EgtP60 zhy}YkzC&Ebe~3gqRQcmkBNER-Xm*G~aIbUJ2%TX&U`_F^tG$MK#HUi%n& m|243LT2{=5di(LyGbDrJz|NiS9Uo#vGc}hsrL}7#hVd7oipz!o delta 532 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 IFepL*03kR5F#rGn literal 0 HcmV?d00001 diff --git a/resources/scripts/db/software.realm b/resources/scripts/db/software.realm new file mode 100644 index 0000000000000000000000000000000000000000..615a1bb9c8d1a5e500205dc67e1b399eefa04c90 GIT binary patch literal 65536 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 0 ? parseInt(res.data.progress.slice(0, -1)) : 0; diff --git a/src/define/Tools/file.js b/src/define/Tools/file.js index 23d1091..22877b8 100644 --- a/src/define/Tools/file.js +++ b/src/define/Tools/file.js @@ -1,5 +1,6 @@ import fs from "fs" +import { isEmpty } from "lodash"; import path from "path"; const fspromises = fs.promises; @@ -17,6 +18,87 @@ export async function CheckFileOrDirExist(path) { } } +// 检查文件夹是不是存在,不存在的话,创建 +export async function CheckFolderExistsOrCreate(folderPath) { + try { + if (!(await CheckFileOrDirExist(folderPath))) { + await fspromises.mkdir(folderPath, { recursive: true }); + } + } catch (error) { + throw new Error(error); + } +} +/** + * 拼接两个地址,返回拼接后的地址 + * @param {*} rootPath 根目录的消息 + * @param {*} subPath 子目录的消息 + * @returns + */ +export function JoinPath(rootPath, subPath) { + // 判断第二个地址是不是存在,不存在返回null,存在返回拼接后的地址 + if (subPath && !isEmpty(subPath)) { + return path.resolve(rootPath, subPath) + } else { + return null + } +} + + +/** + * 拷贝一个文件或者是文件夹到指定的目标地址 + * @param {*} source 源文件或文件夹地址 + * @param {*} target 目标文件或文件夹地址 + * @param {*} checkParent 是否检查父文件夹是否存在,不存在的话创建,默认false,不检查,不存在直接创建 + */ +export async function CopyFileOrFolder(source, target, checkParent = false) { + try { + // 判断源文件或文件夹是不是存在 + if (!(await CheckFileOrDirExist(source))) { + throw new Error(`源文件或文件夹不存在: ${source}`); + } + // 判断父文件夹是否存在,不存在创建 + const parent_path = path.dirname(target); + let parentIsExist = await CheckFileOrDirExist(parent_path); + if (!parentIsExist) { + if (checkParent) { + throw new Error(`目的文件或文件夹的父文件夹不存在: ${parent_path}`); + } else { + await fspromises.mkdir(parent_path, { recursive: true }); + } + } + + // 判断是不是文件夹 + const isDirectory = await IsDirectory(source); + // 复制文件夹的逻辑 + async function copyDirectory(source, target) { + // 创建目标文件夹 + await fspromises.mkdir(target, { recursive: true }); + let entries = await fspromises.readdir(source, { withFileTypes: true }); + for (let entry of entries) { + let srcPath = path.join(source, entry.name); + let tgtPath = path.join(target, entry.name); + + if (entry.isDirectory()) { + await copyDirectory(srcPath, tgtPath); + } else { + await fspromises.copyFile(srcPath, tgtPath); + } + } + } + + if (isDirectory) { + // 创建目标文件夹 + await copyDirectory(source, target); + } else { + // 复制文件 + await fspromises.copyFile(source, target); + } + } catch (error) { + throw error; + } +} + + /** * 判断一个文件地址是不是文件夹 * @param {*} path 输入的文件地址 * @returns true 是 false 不是 diff --git a/src/define/db/model/Book/BookBackTaskListModel.ts b/src/define/db/model/Book/BookBackTaskListModel.ts new file mode 100644 index 0000000..fcb7548 --- /dev/null +++ b/src/define/db/model/Book/BookBackTaskListModel.ts @@ -0,0 +1,28 @@ +import Realm, { ObjectSchema } from 'realm' +import { BookBackTaskStatus, BookBackTaskType } from '../../../enum/bookEnum' + +export class BookBackTaskList extends Realm.Object { + id: string + bookId: string + bookTaskId: string + name: string + type: BookBackTaskType + status: BookBackTaskStatus + createTime: Date + updateTime: Date + + static schema: ObjectSchema = { + name: 'BookBackTaskList', + properties: { + id: 'string', + bookId: { type: 'string', indexed: true }, + bookTaskId: { type: 'string', indexed: true }, + name: 'string', + type: 'string', + status: 'string', + createTime: 'date', + updateTime: 'date' + }, + primaryKey: 'id' + } +} diff --git a/src/define/db/model/Book/book.ts b/src/define/db/model/Book/book.ts new file mode 100644 index 0000000..c61059f --- /dev/null +++ b/src/define/db/model/Book/book.ts @@ -0,0 +1,37 @@ +import Realm, { ObjectSchema } from 'realm' +import { BookType } from '../../../enum/bookEnum' + +export class BookModel extends Realm.Object { + id: string + no: number + name: string + bookFolderPath: string + imageFolder: string | null + type: BookType + oldVideoPath: string | null + srtPath: string | null + audioPath: string | null + updateTime: Date + createTime: Date + test: string | null + + static schema: ObjectSchema = { + name: 'Book', + properties: { + id: 'string', + no: 'int', + name: 'string', + bookFolderPath: 'string', + type: 'string', + oldVideoPath: 'string?', + srtPath: 'string?', + audioPath: 'string?', + imageFolder: 'string?', + updateTime: 'date', + createTime: 'date', + test: 'string?' + }, + // 主键为_id + primaryKey: 'id' + } +} diff --git a/src/define/db/model/Book/bookTask.ts b/src/define/db/model/Book/bookTask.ts new file mode 100644 index 0000000..b839635 --- /dev/null +++ b/src/define/db/model/Book/bookTask.ts @@ -0,0 +1,43 @@ +import Realm, { ObjectSchema } from 'realm' +import { BookTaskStatus, BookType } from '../../../enum/bookEnum' + +export class BookTaskModel extends Realm.Object { + id: string + no: number + bookId: string + name: string + generateVideoPath: string | null + srtPath: string | null + audioPath: string | null + imageFolder: string | null + styleList: Realm.List | null + prefix: string | null + status: BookTaskStatus + errorMsg: string | null + isAuto: boolean // 是否自动 + updateTime: Date + createTime: Date + + static schema: ObjectSchema = { + name: 'BookTask', + properties: { + id: 'string', + bookId: { type: 'string', indexed: true }, + no: 'int', + name: 'string', + generateVideoPath: 'string?', + srtPath: 'string?', + audioPath: 'string?', + imageFolder: 'string?', + styleList: 'string[]', + prefix: 'string?', + status: 'string', + errorMsg: 'string?', + isAuto: 'bool', + updateTime: 'date', + createTime: 'date' + }, + // 主键为_id + primaryKey: 'id' + } +} diff --git a/src/define/db/model/Book/bookTaskDetail.ts b/src/define/db/model/Book/bookTaskDetail.ts new file mode 100644 index 0000000..0165f1a --- /dev/null +++ b/src/define/db/model/Book/bookTaskDetail.ts @@ -0,0 +1,163 @@ +import Realm, { ObjectSchema } from 'realm' +import { + BookBackTaskStatus, + BookBackTaskType, + BookTaskStatus, + BookType, + MJAction, + MJCategroy +} from '../../../enum/bookEnum' + +export class Subtitle extends Realm.Object { + startTime: number + endTime: number + srtValue: string + id: string + static schema = { + name: 'Subtitle', + properties: { + startTime: 'int', + endTime: 'int', + srtValue: 'string', + id: 'string' + }, + primaryKey: 'id' + } +} + +export class MJMessage extends Realm.Object { + id: string + mjApiUrl: string | null + progress: number + category: MJCategroy + imageClick: string | null // 图片点击(显示的小的) + imageShow: string | null // 图片实际的地址 + messageId: string // 消息ID(可以是MJ中的,也可以是API中的) + action: MJAction // 动作(生图,反推之类) + status: string // 状态 + message: string | null // 消息 + static schema: ObjectSchema = { + name: 'MJMessage', + properties: { + id: 'string', + mjApiUrl: 'string?', + progress: 'int', + category: 'string', + imageClick: 'string?', + imageShow: 'string?', + messageId: 'string', + action: 'string', + status: 'string', + message: 'string?' + }, + primaryKey: 'id' + } +} + +export class WebuiConfig extends Realm.Object { + sampler_name: string // 采样器名称 + negative_prompt: string // 负面提示 + batch_size: number // 批次大小 + steps: number // 步数 + cfg_scale: number // 提示词相关性 + denoising_strength: number // 降噪强度 + width: number // 宽度 + height: number // 高度 + seed: number // 种子 + init_images: string // 初始图片(垫图的图片地址) + id: string + + static schema: ObjectSchema = { + name: 'WebuiConfig', + properties: { + sampler_name: 'string', + negative_prompt: 'string', + batch_size: 'int', + steps: 'int', + cfg_scale: 'int', + denoising_strength: 'int', + width: 'int', + height: 'int', + seed: 'int', + init_images: 'string', + id: 'string' + }, + primaryKey: 'id' + } +} + +export class SDConfig extends Realm.Object { + checkpoints: string // 大模型 + api: string // api地址 + model: string // 生图方式 + webuiConfig: WebuiConfig + id: string + static schema: ObjectSchema = { + name: 'SDConfig', + properties: { + checkpoints: 'string', + api: 'string', + model: 'string', + webuiConfig: 'WebuiConfig', + id: 'string' + }, + primaryKey: 'id' + } +} + +export class BookTaskDetailModel extends Realm.Object { + id: string + no: number + name: string + bookId: string + bookTaskId: string + videoPath: string | null // 视频地址 + word: string | null // 文案 + oldImage: string | null // 旧图片(用于SD的图生图) + afterGpt: string | null // GPT生成的文案 + startTime: number | null // 开始时间 + endTime: number | null // 结束时间 + timeLimit: string | null // 事件实现(0 -- 3000) + subValue: Realm.List | null // 包含的字幕数据 + characterTags: string[] | null // 角色标签 + gptPrompt: string | null // GPT提示词 + mjMessage: MJMessage | null // MJ消息 + outImagePath: string | null // 输出图片地址 + subImagePath: string[] | null // 字幕图片地址 + prompt: string | null // 提示 + adetailer: boolean // 是否开启修脸 + sdConifg: SDConfig | null // SD配置 + createTime: Date + updateTime: Date + + static schema: ObjectSchema = { + name: 'BookTaskDetail', + properties: { + id: 'string', + no: 'int', + name: 'string', + bookId: { type: 'string', indexed: true }, + bookTaskId: { type: 'string', indexed: true }, + videoPath: 'string?', + word: 'string?', + oldImage: 'string?', + afterGpt: 'string?', + startTime: 'int?', + endTime: 'int?', + timeLimit: 'string?', + subValue: { type: 'list', objectType: 'Subtitle' }, + characterTags: { type: 'list', objectType: 'string' }, + gptPrompt: 'string?', + mjMessage: 'MJMessage?', + outImagePath: 'string?', + subImagePath: 'string[]', + prompt: 'string?', + adetailer: 'bool', + sdConifg: 'SDConfig?', + createTime: 'date', + updateTime: 'date' + }, + // 主键为_id + primaryKey: 'id' + } +} diff --git a/src/define/db/model/SoftWare/logger.ts b/src/define/db/model/SoftWare/logger.ts new file mode 100644 index 0000000..ed1cef5 --- /dev/null +++ b/src/define/db/model/SoftWare/logger.ts @@ -0,0 +1,27 @@ +import Realm, { ObjectSchema } from 'realm' +import { LoggerStatus, LoggerType } from '../../../enum/softwareEnum' + +export class LoggerModel extends Realm.Object { + id: string + bookId: string // 小说ID + bookTaskId: string // 小说任务ID + type: LoggerType + status: LoggerStatus + date: Date + content: string + + static schema: ObjectSchema = { + name: 'Logger', + properties: { + id: 'string', + bookId: 'string', + bookTaskId: 'string', + type: 'string', + status: 'string', + date: 'date', + content: 'string' + }, + // 主键为_id + primaryKey: 'id' + } +} diff --git a/src/define/db/model/SoftWare/mjSetting.ts b/src/define/db/model/SoftWare/mjSetting.ts new file mode 100644 index 0000000..0b11be2 --- /dev/null +++ b/src/define/db/model/SoftWare/mjSetting.ts @@ -0,0 +1,136 @@ +import Realm, { ObjectSchema } from 'realm' +import { LoggerStatus, LoggerType } from '../../../enum/softwareEnum' +import { MJImageType, MJRobotType } from '../../../enum/mjEnum' + +export class BrowserMJModel extends Realm.Object { + id: string + serviceId: string + channelId: string + mjBotId: string + nijBotId: string + token: string + userAgent: string + userAgentCustom: boolean + createTime: Date + updateTime: Date + version: string + static schema: ObjectSchema = { + name: 'BrowserMJ', + properties: { + id: 'string', + serviceId: 'string', + channelId: 'string', + mjBotId: 'string?', + nijBotId: 'string?', + token: 'string', + userAgent: 'string', + userAgentCustom: 'bool', + createTime: 'date', + updateTime: 'date', + version: 'string' + }, + // 主键为_id + primaryKey: 'id' + } +} + +export class RemoteMJModel extends Realm.Object { + id: string + accountId: string | null + channelId: string + coreSize: number + guildId: string + mjBotChannelId: string + nijiBotChannelId: string + queueSize: number + remark: string + remixAutoSubmit: boolean + timeoutMinutes: number + userAgent: string + userToken: string + createTime: Date + updateTime: Date + version: string + static schema: ObjectSchema = { + name: 'RemoteMJ', + properties: { + id: 'string', + accountId: 'string?', + channelId: 'string', + coreSize: 'int', + guildId: 'string', + mjBotChannelId: 'string', + nijiBotChannelId: 'string', + queueSize: 'int', + remark: 'string', + remixAutoSubmit: 'bool', + timeoutMinutes: 'int', + userAgent: 'string', + userToken: 'string', + createTime: 'date', + updateTime: 'date', + version: 'string' + }, + // 主键为_id + primaryKey: 'id' + } +} + +export class APIMjModel extends Realm.Object { + id: string + mjApiUrl: string + mjSpeed: string // MJ出图的速度模式 + apiKey: string + createTime: Date + updateTime: Date + version: string + static schema: ObjectSchema = { + name: 'APIMj', + properties: { + id: 'string', + mjApiUrl: 'string', + mjSpeed: 'string', + apiKey: 'string', + createTime: 'date', + updateTime: 'date', + version: 'string' + }, + // 主键为_id + primaryKey: 'id' + } +} + +export class MjSettingModel extends Realm.Object { + id: string + type: MJImageType + requestModel: MJImageType + selectRobot: MJRobotType + imageScale: string + imageModel: string + imageSuffix: string + taskCount: number + spaceTime: number + createTime: Date + updateTime: Date + version: string + + static schema: ObjectSchema = { + name: 'MjSetting', + properties: { + id: 'string', + type: 'string', + requestModel: 'string', + selectRobot: 'string', + imageScale: 'string', + imageModel: 'string', + imageSuffix: 'string', + taskCount: 'int', + spaceTime: 'int', + createTime: 'date', + updateTime: 'date', + version: 'string' + }, + // 主键为_id + primaryKey: 'id' + } +} diff --git a/src/define/db/model/SoftWare/software.ts b/src/define/db/model/SoftWare/software.ts new file mode 100644 index 0000000..2e00944 --- /dev/null +++ b/src/define/db/model/SoftWare/software.ts @@ -0,0 +1,23 @@ +import Realm, { ObjectSchema } from 'realm' +import { ComponentSize, SoftwareThemeType } from '../../../enum/softwareEnum' + +export class SoftwareModel extends Realm.Object { + id: string + theme: SoftwareThemeType + reverse_display_show: boolean + reverse_show_book_striped: boolean + reverse_data_table_size: ComponentSize + + static schema: ObjectSchema = { + name: 'Software', + properties: { + id: 'string', + theme: 'string', + reverse_display_show: 'bool', + reverse_show_book_striped: 'bool', + reverse_data_table_size: 'string' + }, + // 主键为_id + primaryKey: 'id' + } +} diff --git a/src/define/db/service/Book/bookBackTaskListService.ts b/src/define/db/service/Book/bookBackTaskListService.ts new file mode 100644 index 0000000..72226e1 --- /dev/null +++ b/src/define/db/service/Book/bookBackTaskListService.ts @@ -0,0 +1,141 @@ +import Realm from 'realm' +import path from 'path' +import { BaseService } from '../baseService.js' +import { define } from '../../../define.js' +import { BookTaskModel } from '../../model/Book/bookTask.js' +import { BookTaskStatus } from '../../../enum/bookEnum.js' +import { errorMessage, successMessage } from '../../../../main/generalTools.js' +import { BaseRealmService } from './bookBasic' +import { isEmpty } from 'lodash' +const { v4: uuidv4 } = require('uuid') + +export class BookBackTaskListService extends BaseRealmService { + static instance: BookBackTaskListService | null = null + realm: Realm + + private constructor() { + super() + } + + /** + * 获取当前实例对象,为空则创建一个新的 + * @returns + */ + public static async getInstance() { + if (BookBackTaskListService.instance === null) { + BookBackTaskListService.instance = new BookBackTaskListService() + await super.getInstance() + } + return BookBackTaskListService.instance + } + + /** + * 新增一个小说相关的后台任务队列 + * @param bookBackTask 要添加的小说数据 + */ + async AddBookBackTaskList(bookBackTask) { + try { + // 判断数据是不是存在 + if ( + isEmpty(bookBackTask.bookId) || + isEmpty(bookBackTask.bookTaskId) || + isEmpty(bookBackTask.name) || + isEmpty(bookBackTask.type) + ) { + throw new Error('新增后台队列任务到数据库失败,数据不完整,缺少必要字段') + } + // 开始新建 + bookBackTask.id = uuidv4() + bookBackTask.createTime = new Date() + bookBackTask.updateTime = new Date() + bookBackTask.status = BookTaskStatus.WAIT + this.realm.write(() => { + this.realm.create('BookBackTaskList', bookBackTask) + }) + return successMessage( + bookBackTask, + '新增后台队列任务到数据库成功', + 'BookBackTaskList_AddBookBackTaskList' + ) + } catch (error) { + return errorMessage( + '新增后台队列任务到数据库失败,错误信息入校' + error.toString(), + 'BookBackTaskList_AddBookBackTaskList' + ) + } + } + + /** + * 修改一个小说相关的后台任务队列中的详细信息(对于后台的队列任务只能修改状态) + * @param bookBackTask 修改的数据 + */ + async ModifyBookBackTaskList(bookBackTask) { + try { + // 判断数据是不是存在 + if (isEmpty(bookBackTask.id) || isEmpty(bookBackTask.status)) { + throw new Error('修改后台队列任务失败,数据不完整,缺少必要字段') + } + // 开始修改 + this.realm.write(() => { + // 获取指定ID的队列任务 + let _bookBackTask = this.realm.objectForPrimaryKey('BookBackTaskList', bookBackTask.id) + // 判断数据是不是存在 + if (_bookBackTask == null) { + throw new Error('修改后台队列任务失败,数据不存在') + } + // 修改数据 + _bookBackTask.status = bookBackTask.status + }) + return successMessage( + bookBackTask, + '修改后台队列任务成功', + 'BookBackTaskList_ModifyBookBackTaskList' + ) + } catch (error) { + return errorMessage( + '修改后台队列任务失败,错误信息如下:' + error.toString(), + 'BookBackTaskList_ModifyBookBackTaskList' + ) + } + } + + /** + * 删除满足条件的数据,包含 id、bookId、bookTaskId + * @param bookBackTask 删除的数据 + */ + async DeleteBookBackTaskListBy(bookBackTask) { + try { + this.realm.write(() => { + // 构建查询条件 + let query = [] as string[] + if (bookBackTask.id) { + query.push(`id = ${bookBackTask.id}`) + } + if (bookBackTask.bookId) { + query.push(`bookId = ${bookBackTask.bookId}`) + } + if (bookBackTask.bookTaskId) { + query.push(`bookTaskId = ${bookBackTask.bookTaskId}`) + } + const queryString = query.join(' && ') + // 获取指定的数据 + if (queryString) { + const tasksToDelete = this.realm.objects('BookBackTaskList').filtered(queryString) + this.realm.delete(tasksToDelete) + } else { + throw new Error('删除后台队列任务失败,没有筛选条件') + } + return successMessage( + bookBackTask, + '删除后台队列任务成功', + 'BookBackTaskList_DeleteBookBackTaskListBy' + ) + }) + } catch (error) { + return errorMessage( + '删除后台队列任务失败,错误信息如下:' + error.toString(), + 'BookBackTaskList_DeleteBookBackTaskListBy' + ) + } + } +} diff --git a/src/define/db/service/Book/bookBasic.ts b/src/define/db/service/Book/bookBasic.ts new file mode 100644 index 0000000..88ecf4d --- /dev/null +++ b/src/define/db/service/Book/bookBasic.ts @@ -0,0 +1,83 @@ +import Realm from 'realm' +import { BookModel } from '../../model/Book/book' +import { BookTaskModel } from '../../model/Book/bookTask' +import { BaseService } from '../baseService' +import { define } from '../../../define' +import path from 'path' +import { + BookTaskDetailModel, + MJMessage, + SDConfig, + Subtitle, + WebuiConfig +} from '../../model/Book/bookTaskDetail' +import { BookBackTaskList } from '../../model/Book/BookBackTaskListModel' + +let dbPath = path.resolve(define.db_path, 'book.realm') + +// 版本迁移 +const migration = (oldRealm: Realm, newRealm: Realm) => { + if (oldRealm.schemaVersion < 1) { + const oldBooks = oldRealm.objects('Book') + const newBooks = newRealm.objects('Book') + + for (let i = 0; i < oldBooks.length; i++) { + newBooks[i].test = 'defaultValue' // 为新属性设置默认值 + } + } + if (oldRealm.schemaVersion < 2) { + const oldBookTask = oldRealm.objects('BookTask') + const newBookTask = newRealm.objects('BookTask') + for (let i = 0; i < oldBookTask.length; i++) { + newBookTask[i].isAuto = false // 为新属性设置默认值 + } + } +} + +export class BaseRealmService extends BaseService { + static instance: BaseRealmService | null = null + protected realm: Realm | null = null + dbpath: string + + protected constructor() { + super() + this.dbpath = dbPath + } + + public static async getInstance() { + if (BaseRealmService.instance === null) { + BaseRealmService.instance = new BaseRealmService() + await BaseRealmService.instance.open() + } + return BaseRealmService.instance + } + + /** + * 创建数据库连接,如果已经存在则直接返回 + * @returns + */ + async open() { + try { + if (this.realm != null) return + // 判断当前全局是不是又当前这个 + const config = { + schema: [ + BookModel, + Subtitle, + MJMessage, + BookBackTaskList, + SDConfig, + WebuiConfig, + BookTaskModel, + BookTaskDetailModel + ], + path: this.dbpath, + schemaVersion: 2, + migration: migration + } + this.realm = await Realm.open(config) + } catch (error) { + throw error + } + } +} diff --git a/src/define/db/service/Book/bookService.ts b/src/define/db/service/Book/bookService.ts new file mode 100644 index 0000000..1b6d468 --- /dev/null +++ b/src/define/db/service/Book/bookService.ts @@ -0,0 +1,214 @@ +import Realm, { UpdateMode } from 'realm' +import { BookModel } from '../../model/Book/book.js' +import path from 'path' +import { BaseService } from '../baseService.js' +import { define } from '../../../define.js' +import { BookTaskStatus, BookType } from '../../../enum/bookEnum.js' +import { successMessage } from '../../../../main/generalTools.js' +import { CheckFolderExistsOrCreate, CopyFileOrFolder } from '../../../Tools/file.js' +const { v4: uuidv4 } = require('uuid') +import { BookTaskService } from './bookTaskService' +import { BaseRealmService } from './bookBasic.js' +import { isEmpty } from 'lodash' + +class BooKService extends BaseRealmService { + static instance: BooKService | null = null + realm: Realm + + private constructor() { + super() + } + + /** + * 获取当前实例对象,为空则创建一个新的 + * @returns + */ + public static async getInstance() { + if (BooKService.instance === null) { + BooKService.instance = new BooKService() + await super.getInstance() + } + return BooKService.instance + } + + /** + * 获取小说信息,通过参数查询 + * @returns + */ + async GetBookData(bookQuery) { + try { + await this.open() + // 获取所有的小说数据,并进行时间降序排序 + let books = this.realm.objects('Book') + let book_length = books.length + + // 开始开始筛选 + if (bookQuery.bookId) { + // 查询对应的小说ID的数据 + books = books.filtered('id = $0', bookQuery.bookId) + } + + books = books.sorted('updateTime', true) + // 判断是不是有page和pageSize,有的话对查询返回的信息做分页 + if (bookQuery.page && bookQuery.pageSize) { + books = books.slice( + (bookQuery.page - 1) * bookQuery.pageSize, + bookQuery.page * bookQuery.pageSize + ) as unknown as Realm.Results + } + if (books.length <= 0) { + return successMessage( + { + res_book: [], + book_length: 0 + }, + '没有数据', + 'ReverseBook_GetBookData' + ) + } + + // 将realm对象数组转换为普通对象数组 + let res_book = Array.from(books).map((book) => { + // 这里可以直接操作普通对象 + let bookObj = { + ...book, + bookFolderPath: path.resolve( + define.project_path, + book.bookFolderPath.replace(/\\/g, '/') + ), + oldVideoPath: book.oldVideoPath + ? path.resolve(define.project_path, book.oldVideoPath.replace(/\\/g, '/')) + : '', + imageFolder: book.imageFolder + ? path.resolve(define.project_path, book.imageFolder.replace(/\\/g, '/')) + : '' + } + return bookObj + }) + + return successMessage( + { + res_book, + book_length + }, + '获取成功', + 'ReverseBook_GetBookData' + ) + } catch (error) { + throw error + } + } + + /** + * 新增或者是修小说数据 + * @param {*} book 小说信息 + * @returns + */ + async AddOrModifyBook(book) { + try { + await this.open() + if (book == null) { + throw new Error('小说数据为空,无法修改') + } + + // 当小说的类型是反推的时候,必须传入视频 + if (book.type == BookType.MJ_REVERSE || book.type == BookType.SD_REVERSE) { + // 判断视频是否存在 + if (book.oldVideoPath == null || book.oldVideoPath == '') { + throw new Error('反推必须传入视频') + } + } + + if (book.id == null) { + // 新增 + // 判断指定的名字在数据库中是否存在 + let books = this.realm.objects('Book').filtered('name = $0', book.name) + if (books.length > 0) { + throw new Error(`小说名字 ${book.name} 已经存在,请更换小说名字`) + } + console.log(this) + // 新增数据 + book.id = uuidv4() + book.createTime = new Date() + book.updateTime = new Date() + // 检查传入的视频文件是不是存在 + // 获取当前最大的no + let maxNo = this.realm.objects('Book').max('no') + book.no = maxNo == null ? 1 : Number(maxNo) + 1 + // 拼接项目文件夹 + book.bookFolderPath = book.id + book.imageFolder = `${book.id}/tmp` + let bookFolderPath = path.resolve(define.project_path, book.id) + let imageFolder = path.resolve(define.project_path, `${book.id}/tmp`) + let oldVideoPath = path.resolve(define.project_path, `${book.id}/data/${book.id}.mp4`) + + // 将视频拷贝一个到项目文件下面 + if (book.oldVideoPath) { + await CopyFileOrFolder(book.oldVideoPath, oldVideoPath) + } + + // 创建对应的文件夹 + await CheckFolderExistsOrCreate(bookFolderPath) + await CheckFolderExistsOrCreate(imageFolder) + // 修改数据 + book.oldVideoPath = path.relative(define.project_path, oldVideoPath) + this.realm.write(() => { + this.realm.create('Book', book) + let bookTaskImageFolder = path.resolve(imageFolder, 'output_00001') + // 添加一个任务 + let bookTask = { + id: uuidv4(), + bookId: book.id, + no: 1, + name: 'output_00001', + generateVideoPath: null, + srtPath: null, + audioPath: null, + imageFolder: path.relative(define.project_path, bookTaskImageFolder), // 获取文件输出对于项目的相对路径 + styleList: [], + prefix: null, + status: BookTaskStatus.WAIT, + errorMsg: null, + isAuto: false, + updateTime: new Date(), + createTime: new Date() + } + + // 添加任务 + this.realm.create('BookTask', bookTask) + }) + + // 保存成功,返回数据,但是要做处理 + book.bookFolderPath = bookFolderPath + book.imageFolder = imageFolder + book.oldVideoPath = oldVideoPath + + return successMessage(book, '新增成功', 'BookBasic_AddOrModifyBook') + } else { + // 修改 + // 判断指定的名字在数据库中是否存在(不算自己) + let books = this.realm + .objects('Book') + .filtered('name = $0 AND id != $1', book.name, book.id) + if (books.length > 0) { + throw new Error(`小说名字 ${book.name} 已经存在,请更换小说名字`) + } + // 两个文件夹地址不能改,删除两个属性 + delete book.bookFolderPath + delete book.imageFolder + // 修改数据 + book.updateTime = new Date() + this.realm.write(() => { + this.realm.create('Book', book, UpdateMode.Modified) + }) + + // 保存成功,返回数据,但是要做处理 + return successMessage(null, '修改成功', 'BookBasic_AddOrModifyBook') + } + } catch (error) { + throw error + } + } +} + +export default BooKService diff --git a/src/define/db/service/Book/bookTaskDetailService.ts b/src/define/db/service/Book/bookTaskDetailService.ts new file mode 100644 index 0000000..adb09ec --- /dev/null +++ b/src/define/db/service/Book/bookTaskDetailService.ts @@ -0,0 +1,47 @@ +import Realm from 'realm' +import path from 'path' +import { BaseService } from '../baseService.js' +import { define } from '../../../define.js' +import { BookTaskModel } from '../../model/Book/bookTask.js' +import { BookTaskStatus } from '../../../enum/bookEnum.js' +import { successMessage } from '../../../../main/generalTools.js' +import { BaseRealmService } from './bookBasic' +const { v4: uuidv4 } = require('uuid') + +let dbPath = path.resolve(define.db_path, 'book.realm') + +// 版本迁移 +const migration = (oldRealm: Realm, newRealm: Realm) => {} + +export class BookTaskDetailService extends BaseRealmService { + static instance: BookTaskDetailService | null = null + realm: Realm + + private constructor() { + super() + } + + /** + * 获取当前实例对象,为空则创建一个新的 + * @returns + */ + public static async getInstance() { + if (BookTaskDetailService.instance === null) { + BookTaskDetailService.instance = new BookTaskDetailService() + await super.getInstance() + } + return BookTaskDetailService.instance + } + + /** + * 添加一条小说人物对应的详细数据 + * @param BookTaskDetail + */ + public async AddBookTaskDetail(BookTaskDetail) { + try { + // 判断是不是又小说的ID + } catch (error) { + throw error + } + } +} diff --git a/src/define/db/service/Book/bookTaskService.ts b/src/define/db/service/Book/bookTaskService.ts new file mode 100644 index 0000000..6c9323a --- /dev/null +++ b/src/define/db/service/Book/bookTaskService.ts @@ -0,0 +1,139 @@ +import Realm from 'realm' +import path from 'path' +import { BaseService } from '../baseService.js' +import { define } from '../../../define.js' +import { BookTaskModel } from '../../model/Book/bookTask.js' +import { BookTaskStatus } from '../../../enum/bookEnum.js' +import { successMessage } from '../../../../main/generalTools.js' +import { BaseRealmService } from './bookBasic' +import { isEmpty } from 'lodash' +import { JoinPath } from '../../../Tools/file.js' +const { v4: uuidv4 } = require('uuid') + +let dbPath = path.resolve(define.db_path, 'book.realm') + +export class BookTaskService extends BaseRealmService { + static instance: BookTaskService | null = null + realm: Realm + + private constructor() { + super() + } + + /** + * 获取当前实例对象,为空则创建一个新的 + * @returns + */ + public static async getInstance() { + if (BookTaskService.instance === null) { + BookTaskService.instance = new BookTaskService() + await super.getInstance() + } + return BookTaskService.instance + } + + /** + * 查询满足条件的小说子任务信息 + * @param bookTaskCondition 查询条件 id,bookId,name,no,page, pageSize + */ + async GetBookTaskData(bookTaskCondition) { + try { + await this.open() + // 获取所有的小说数据,并进行时间降序排序 + let bookTasks = this.realm.objects('BookTask') + + // 开始开始筛选 + if (bookTaskCondition.id) { + // 查询对应的小说ID的数据 + bookTasks = bookTasks.filtered('id = $0', bookTaskCondition.id) + } + if (bookTaskCondition.bookId) { + // 查询对应的小说ID的数据 + bookTasks = bookTasks.filtered('bookId = $0', bookTaskCondition.bookId) + } + if (bookTaskCondition.name) { + // 查询对应的小说ID的数据 + bookTasks = bookTasks.filtered('name = $0', bookTaskCondition.name) + } + if (bookTaskCondition.no) { + // 查询对应的小说ID的数据 + bookTasks = bookTasks.filtered('no = $0', bookTaskCondition.no) + } + let bookTask_length = bookTasks.length + + bookTasks = bookTasks.sorted('updateTime', true) + // 判断是不是有page和pageSize,有的话对查询返回的信息做分页 + if (bookTaskCondition.page && bookTaskCondition.pageSize) { + bookTasks = bookTasks.slice( + (bookTaskCondition.page - 1) * bookTaskCondition.pageSize, + bookTaskCondition.page * bookTaskCondition.pageSize + ) as unknown as Realm.Results + } + + // 做一下数据转换 + // 将realm对象数组转换为普通对象数组 + let res_bookTasks = Array.from(bookTasks).map((bookTask) => { + // 这里可以直接操作普通对象 + let bookObj = { + ...bookTask, + styleList: bookTask.styleList ? Array.from(bookTask.styleList) : [], + generateVideoPath: JoinPath(define.project_path, bookTask.generateVideoPath), + srtPath: JoinPath(define.project_path, bookTask.srtPath), + audioPath: JoinPath(define.project_path, bookTask.audioPath), + imageFolder: JoinPath(define.project_path, bookTask.imageFolder) + } + return bookObj + }) + + return successMessage( + { + bookTasks: res_bookTasks, + total: bookTask_length + }, + '查询小说任务成功', + 'BookTaskService_GetBookTaskData' + ) + } catch (error) { + throw error + } + } + + // 添加一条数据 + async AddOrModifyBookTask(bookTask) { + try { + await this.open() + if (bookTask == null) { + throw new Error('添加的小说任务不能为空') + } + if (bookTask.id == null) { + // 新增 + if (bookTask.bookId == '' || bookTask.bookId == null) { + throw new Error('小说ID不能为空') + } + + bookTask.id = uuidv4() + + // 获取当前bookID对应的最大的no + let maxNo = this.realm + .objects('BookTask') + .filtered('bookId = $0', bookTask.bookId) + .max('no') + bookTask.no = maxNo == null ? 1 : Number(maxNo) + 1 + bookTask.name = 'output_0000' + bookTask.no + bookTask.status = BookTaskStatus.WAIT + + bookTask.updateTime = new Date() + bookTask.createTime = new Date() + + this.realm.write(() => { + this.realm.create('BookTask', bookTask) + }) + return successMessage(bookTask, '新增小说任务成功', 'BookTaskService_AddOrModifyBookTask') + } else { + // 修改 + } + } catch (error) { + throw error + } + } +} diff --git a/src/define/db/service/SoftWare/loggerService.ts b/src/define/db/service/SoftWare/loggerService.ts new file mode 100644 index 0000000..c5a2795 --- /dev/null +++ b/src/define/db/service/SoftWare/loggerService.ts @@ -0,0 +1,80 @@ +import Realm, { UpdateMode } from 'realm' +import path from 'path' +import { BaseService } from '../baseService.js' +import { define } from '../../../define.js' +import { SoftwareModel } from '../../model/SoftWare/software.js' +import { ComponentSize, SoftwareThemeType } from '../../../enum/softwareEnum.js' +import { errorMessage, successMessage } from '../../../../main/generalTools.js' +import { BaseSoftWareService } from './softwareBasic.js' +import { isEmpty } from 'lodash' +const { v4: uuidv4 } = require('uuid') + +export class LoggerService extends BaseSoftWareService { + static instance: LoggerService | null = null + realm: Realm + private constructor() { + super() + } + + /** + * 获取当前实例对象,为空则创建一个新的 + * @returns + */ + public static async getInstance() { + if (LoggerService.instance === null) { + LoggerService.instance = new LoggerService() + await super.getInstance() + } + return LoggerService.instance + } + + // 添加一条日志信息 + async AddLogger(logger) { + try { + await this.open() + // 判断数据是不是存在 bookId,bookTaskId,type,status,content + if ( + isEmpty(logger.bookId) || + isEmpty(logger.bookTaskId) || + isEmpty(logger.type) || + isEmpty(logger.status) || + isEmpty(logger.content) + ) { + throw new Error('新增日志信息到数据库失败,数据不完整,缺少必要字段') + } + + logger.id = uuidv4() + logger.date = new Date() + this.realm.write(() => { + this.realm.create('Logger', logger) + }) + return successMessage(logger, '新增日志信息成功', 'LoggerService_AddLogger') + } catch (error) { + return errorMessage( + '新增日志信息失败,错误信息如下:' + error.toString(), + 'LoggerService_AddLogger' + ) + } + } + + // 删除日志信息 (删除指定日期之前的) + async DeleteLogger(date) { + try { + await this.open() + this.realm.write(() => { + // 删除十五天之前的日志数据 + const currentDate = new Date() + currentDate.setDate(currentDate.getDate() - 5) + + let logger = this.realm.objects('Logger').filtered('date < $0', currentDate) + this.realm.delete(logger) + }) + return successMessage(null, '删除日志信息成功', 'LoggerService_DeleteLogger') + } catch (error) { + return errorMessage( + '删除日志信息失败,错误信息如下:' + error.toString(), + 'LoggerService_DeleteLogger' + ) + } + } +} diff --git a/src/define/db/service/SoftWare/mjSettingService.ts b/src/define/db/service/SoftWare/mjSettingService.ts new file mode 100644 index 0000000..8a682c8 --- /dev/null +++ b/src/define/db/service/SoftWare/mjSettingService.ts @@ -0,0 +1,611 @@ +import Realm, { UpdateMode } from 'realm' +import path from 'path' +import { BaseService } from '../baseService' +import { define } from '../../../define.js' +import { SoftwareModel } from '../../model/SoftWare/software.js' +import { ComponentSize, SoftwareThemeType } from '../../../enum/softwareEnum.js' +import { errorMessage, successMessage } from '../../../../main/generalTools.js' +import { BaseSoftWareService } from './softwareBasic.js' +import { isEmpty, isNumber } from 'lodash' +const { v4: uuidv4 } = require('uuid') +import { version } from '../../../../../package.json' + +export class MJSettingService extends BaseSoftWareService { + static instance: MJSettingService | null = null + realm: Realm + private constructor() { + super() + } + + /** + * 获取当前实例对象,为空则创建一个新的 + * @returns + */ + public static async getInstance() { + if (MJSettingService.instance === null) { + MJSettingService.instance = new MJSettingService() + await super.getInstance() + } + await MJSettingService.instance.open() + return MJSettingService.instance + } + + //#region 览器模式的MJ设置 + + /** + * 查询对应的浏览器的MJ设置 + * @param browserQuery 查询条件 Id ,null 返回全部 + */ + GetBrowserMJSetting(browserQuery) { + try { + let browserMjSettings = this.realm.objects('BrowserMJ') + + if (browserQuery?.id) { + browserMjSettings = this.realm.objects('BrowserMJ').filtered('id = $0', browserQuery.id) + } + + let resBrowserMj = Array.from(browserMjSettings).map((browserMj) => { + return { + ...browserMj + } + }) + + return successMessage( + resBrowserMj, + '获取浏览器配置成功', + 'MJSettingService_GetBrowserMJSetting' + ) + } catch (error) { + throw error + } + } + + /** + * 添加浏览器相关的MJ设置 + * @param browserMj 浏览器的MJ设置对象 + * @returns + */ + AddBrowserMJSetting(browserMj) { + try { + if (isEmpty(browserMj.serviceId) || isEmpty(browserMj.channelId)) { + throw new Error('服务器ID和频道ID必填') + } + if (isEmpty(browserMj.token) || isEmpty(browserMj.userAgent)) { + throw new Error('用户Agent和token必填') + } + browserMj.id = uuidv4() + browserMj.createTime = new Date() + browserMj.updateTime = new Date() + browserMj.version = version + browserMj.userAgentCustom = false + if (this.realm.isInTransaction) { + this.realm.create('BrowserMJ', browserMj) + } else { + this.realm.write(() => { + this.realm.create('BrowserMJ', browserMj) + }) + } + return successMessage( + browserMj, + '新增MJ浏览器模式配置成功', + 'MJSettingService_AddBrowserMJSetting' + ) + } catch (error) { + throw error + } + } + + /** + * 更新浏览器的MJ设置 + * @param browserMj + */ + UpdateBrowserMJSetting(browserMj) { + try { + if (isEmpty(browserMj.id)) { + throw new Error('更改浏览器模式配置,ID不能为空') + } + + if ( + isEmpty(browserMj.serviceId) || + isEmpty(browserMj.channelId) || + isEmpty(browserMj.token) + ) { + throw new Error('更改浏览器配置,服务器ID,频道ID,Token不能为空') + } + + // 判断是不是有数据 + let browserMjRes = this.realm.objects('BrowserMJ').filtered('id = $0', browserMj.id) + if (browserMjRes.length <= 0) { + throw new Error('没有找到对应的浏览器配置信息') + } + + browserMj.updateTime = new Date() + browserMj.version = version + if (this.realm.isInTransaction) { + this.realm.create('BrowserMJ', browserMj, UpdateMode.Modified) + } else { + this.realm.write(() => { + this.realm.create('BrowserMJ', browserMj, UpdateMode.Modified) + }) + } + + return successMessage( + browserMj, + '修改浏览器模式配置成功', + 'MJSettingService_UpdateBrowserMJSetting' + ) + } catch (error) { + throw error + } + } + + //#endregion + + //#region API 模式的相关配置 + + /** + * 获取API配置信息 + * @param apiQuery 查询条件 Id ,null 返回全部 + * @returns + */ + GetAPIMjSetting(apiQuery) { + try { + let apiMjSettings = this.realm.objects('APIMj') + + if (apiQuery?.id) { + apiMjSettings = this.realm.objects('APIMj').filtered('id = $0', apiQuery.id) + } + + let resApiMj = Array.from(apiMjSettings).map((apiMj) => { + return { + ...apiMj + } + }) + + return successMessage(resApiMj, '获取API配置成功', 'MJSettingService_GetAPIMjSetting') + } catch (error) { + throw error + } + } + + /** + * 添加API模式的配置 + * @param apiMj API的配置信息 + */ + AddAPIMjSetting(apiMj) { + try { + if (isEmpty(apiMj.mjApiUrl) || isEmpty(apiMj.mjSpeed) || isEmpty(apiMj.apiKey)) { + throw new Error('请求的API URL,对应的API Key,请求模式这些必填') + } + + apiMj.id = uuidv4() + apiMj.createTime = new Date() + apiMj.updateTime = new Date() + apiMj.version = version + if (this.realm.isInTransaction) { + this.realm.create('APIMj', apiMj) + } else { + this.realm.write(() => { + this.realm.create('APIMj', apiMj) + }) + } + return successMessage(apiMj, '添加API设置成功', 'MJSettingService_AddAPIMjSetting') + } catch (error) { + throw error + } + } + + /** + * 修改APIMJ的配置信息 + * @param apiSetting + */ + UpdateAPIMJSetting(apiSetting) { + try { + if (apiSetting.id == null) { + throw new Error('修改API配置数据,ID必填') + } + + // 判断必填的数据是不是为空 + if ( + isEmpty(apiSetting.mjApiUrl) || + isEmpty(apiSetting.mjSpeed) || + isEmpty(apiSetting.apiKey) + ) { + throw new Error('请求的API URL,对应的API Key,请求模式这些必填') + } + + // 判断对应的ID是不是存在 + let apiSettingRes = this.realm.objects('APIMj').filtered('id = $0', apiSetting.id) + if (apiSettingRes.length <= 0) { + throw new Error('没有找到对应的API配置信息') + } + apiSetting.updateTime = new Date() + apiSetting.version = version + if (this.realm.isInTransaction) { + this.realm.create('APIMj', apiSetting, UpdateMode.Modified) + } else { + this.realm.write(() => { + this.realm.create('APIMj', apiSetting, UpdateMode.Modified) + }) + } + return successMessage(apiSetting, '修改API设置成功', 'MJSettingService_UpdateAPIMJSetting') + } catch (error) { + throw error + } + } + + //#endregion + + //#region 代理模式的相关配置 + + /** + * 查询代理模式的配置信息 + * @param remoteMjQuery 查询条件,id,null-返回全部 + */ + GetRemoteMJSettings(remoteMjQuery) { + try { + let remoteMjSettings = this.realm.objects('RemoteMJ') + + if (remoteMjQuery?.id) { + remoteMjSettings = this.realm.objects('RemoteMJ').filtered('id = $0', remoteMjQuery.id) + } + + let resRemoteMj = Array.from(remoteMjSettings).map((remoteMj) => { + return { + ...remoteMj + } + }) + + return successMessage( + resRemoteMj, + '获取代理模式配置成功', + 'MJSettingService_GetRemoteMjSettings' + ) + } catch (error) { + throw error + } + } + + /** + * 添加代理API配置 + * @param remoteMjSetting 代理API的设置对象 + * @returns + */ + AddRemoteMjSetting(remoteMjSetting) { + try { + if ( + isEmpty(remoteMjSetting.channelId) || + isEmpty(remoteMjSetting.guildId) || + isEmpty(remoteMjSetting.userToken) + ) { + throw new Error('代理模式的频道ID,服务器ID,用户Token必填') + } + + let defaultSetting = { + coreSize: 3, + mjBotChannelId: null, + nijiBotChannelId: null, + queueSize: 5, + remark: global.machineId, + remixAutoSubmit: false, + timeoutMinutes: 6, + userAgent: + 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36' + } + // 覆盖 + remoteMjSetting = Object.assign(defaultSetting, remoteMjSetting) + remoteMjSetting.id = uuidv4() + remoteMjSetting.createTime = new Date() + remoteMjSetting.updateTime = new Date() + remoteMjSetting.version = version + remoteMjSetting.remark = global.machineId + + // 判断当前this.relam 是不是已经处于一个事务中 + if (this.realm.isInTransaction) { + this.realm.create('RemoteMJ', remoteMjSetting) + } else { + this.realm.write(() => { + this.realm.create('RemoteMJ', remoteMjSetting) + }) + } + + return successMessage( + remoteMjSetting, + '新增代理API配置成功', + 'MJSettingService_AddRemoteMjSetting' + ) + } catch (error) { + throw error + } + } + + /** + * 更新代理模式的配置信息 + * @param remoteMjSetting + */ + UpdateRemoteMjSetting(remoteMjSetting) { + try { + if (isEmpty(remoteMjSetting.id)) { + throw new Error('更改代理模式配置,ID不能为空') + } + if ( + isEmpty(remoteMjSetting.channelId) || + isEmpty(remoteMjSetting.guildId) || + isEmpty(remoteMjSetting.userToken) + ) { + throw new Error('代理模式的账号ID,服务ID,频道ID,用户Token不能为空') + } + + if ( + remoteMjSetting.coreSize == null || + remoteMjSetting.queueSize == null || + remoteMjSetting.timeoutMinutes == null + ) { + throw new Error('核心数量,队列数量,超时时间不能为空') + } + + let remoteMjSettingRes = this.realm + .objects('RemoteMJ') + .filtered('id = $0', remoteMjSetting.id) + if (remoteMjSettingRes.length <= 0) { + throw new Error('没有找到对应的代理模式配置信息') + } + + remoteMjSetting.updateTime = new Date() + remoteMjSetting.version = version + remoteMjSetting.remark = global.machineId + + // 判断relam是不是在事务中 + if (this.realm.isInTransaction) { + this.realm.create('RemoteMJ', remoteMjSetting, UpdateMode.Modified) + } else { + this.realm.write(() => { + this.realm.create('RemoteMJ', remoteMjSetting, UpdateMode.Modified) + }) + } + + return successMessage( + remoteMjSetting, + '修改代理API配置成功', + 'MJSettingService_UpdateRemoteMjSetting' + ) + } catch (error) { + throw error + } + } + + //#endregion + + //#region MJ设置的基础设置 + + /** + * 获取MJ的基础配置信息 + * @param mjSettingQuery 查询的条件 Id ,null 返回全部 + * @returns + */ + GetMjSetting(mjSettingQuery) { + try { + let mjSettings = this.realm.objects('MjSetting') + + if (mjSettingQuery?.id) { + mjSettings = this.realm.objects('MjSetting').filtered('id = $0', mjSettingQuery.id) + } + + let resMjSetting = Array.from(mjSettings).map((mjSetting) => { + return { + ...mjSetting + } + }) + + return successMessage(resMjSetting, '获取MJ基础设置成功', 'MJSettingService_getMjSetting') + } catch (error) { + throw error + } + } + + /** + * 添加MJ的基础配置到数据库 + * @param mjSetting 添加的mj基础配置的对象 + * @returns + */ + AddMJSetting(mjSetting) { + try { + mjSetting.type = mjSetting.requestModel + // 判断传入的必填数据是不是为空 + if (isEmpty(mjSetting.type) || isEmpty(mjSetting.requestModel)) { + throw new Error('MJ设置的类型和请求模型不能为空') + } + + if ( + isEmpty(mjSetting.imageScale) || + isEmpty(mjSetting.imageModel) || + isEmpty(mjSetting.imageSuffix) || + isEmpty(mjSetting.selectRobot) + ) { + throw new Error('MJ设置的图片比例、图片模型、生图后缀、选择机器人不能为空') + } + + mjSetting.id = uuidv4() + mjSetting.createTime = new Date() + mjSetting.updateTime = new Date() + mjSetting.version = version + + //TODO 还有一些判断条件,后面需要添加,比如选择生图模式,要保存对应的配置数据 + if (this.realm.isInTransaction) { + this.realm.create('MjSetting', mjSetting) + } else { + this.realm.write(() => { + this.realm.create('MjSetting', mjSetting) + }) + } + // 返回成功信息 + return successMessage(mjSetting, '添加MJ设置成功', 'MJSettingService_AddMJSetting') + } catch (error) { + throw error + } + } + + /** + * 更新MJ的基础配置信息 + * @param mjSetting + */ + UpdateMJSetting(mjSetting) { + try { + // 判断传入的数据中的必填数据是不是为空 + if (isEmpty(mjSetting.id)) { + throw new Error('更改MJ基础设置,ID不能为空') + } + if (isEmpty(mjSetting.requestModel)) { + throw new Error('MJ设置的请求模型不能为空') + } + mjSetting.type = mjSetting.requestModel + if ( + isEmpty(mjSetting.selectRobot) || + isEmpty(mjSetting.imageScale) || + isEmpty(mjSetting.imageModel) || + isEmpty(mjSetting.imageSuffix) + ) { + throw new Error('MJ设置的图片比例、图片模型、生图后缀、选择机器人不能为空') + } + + if (mjSetting.taskCount == null || mjSetting.spaceTime == null) { + throw new Error('任务数量和间隔时间不能为空') + } + + // 判断指定ID的数据是不是存在 + let mjSettingRes = this.realm.objects('MjSetting').filtered('id = $0', mjSetting.id) + if (mjSettingRes.length <= 0) { + throw new Error('没有找到对应的MJ配置信息') + } + mjSetting.updateTime = new Date() + mjSetting.version = version + + if (this.realm.isInTransaction) { + this.realm.create('MjSetting', mjSetting, UpdateMode.Modified) + } else { + this.realm.write(() => { + this.realm.create('MjSetting', mjSetting, UpdateMode.Modified) + }) + } + // 返回成功信息 + return successMessage(mjSetting, '修改MJ配置信息成功', 'MJSettingService_UpdateMJSetting') + } catch (error) { + throw error + } + } + //#endregion + + //#region 组合操作,组合返回前端的数据信息 + + /** + * 获取MJ的所有配置信息,包含所有的子项 + */ + GetMJSettingTreeData() { + try { + // 获取MJ的基础配置信息 + let mjSettings = this.GetMjSetting(null) + if (mjSettings.data.length <= 0) { + throw new Error('没有找到MJ的配置信息,请先添加') + } + // 获取API的配置信息 + let apiSettings = this.GetAPIMjSetting(null) + // 获取代理模式的配置信息 + let remoteSettings = this.GetRemoteMJSettings(null) + + // 获取浏览器模式的配置信息 + let browserSettings = this.GetBrowserMJSetting(null) + let mjSetting = mjSettings.data[0] + mjSetting.apiSetting = apiSettings.data.length > 0 ? apiSettings.data[0] : null + mjSetting.remoteSetting = remoteSettings.data.length > 0 ? remoteSettings.data[0] : null + mjSetting.browserSetting = browserSettings.data.length > 0 ? browserSettings.data[0] : null + + return successMessage( + mjSetting, + '获取MJ的所有配置信息成功', + 'MJSettingService_GetMJSettingTreeData' + ) + } catch (error) { + throw error + } + } + + /** + * 组合操作,保存数据 + * @param mjSetting + */ + SaveMJSettingTreeData(mjSetting) { + try { + if (mjSetting == null) { + throw new Error('保存的数据不能为空') + } + // 组合添加数据 + this.realm.write(() => { + // 先添加RemoteMJ的数据 + let remoteSetting = mjSetting.remoteSetting ? mjSetting.remoteSetting : null + if (remoteSetting != null) { + let remoteSettingRes: { code: number; data: any; message: any } + if (isEmpty(remoteSetting.id)) { + // 新增 + remoteSettingRes = this.AddRemoteMjSetting(remoteSetting) + } else { + // 修改 + remoteSettingRes = this.UpdateRemoteMjSetting(remoteSetting) + } + if (remoteSettingRes && remoteSettingRes.code == 1) { + mjSetting.remoteSetting = remoteSettingRes.data + } + } + + // 判断API设置的数据是不是存在 + let apiSetting = mjSetting.apiSetting ? mjSetting.apiSetting : null + if (apiSetting != null) { + let apiSettingRes: { code: number; data: any; message: any } + if (isEmpty(apiSetting.id)) { + // 新增 + apiSettingRes = this.AddAPIMjSetting(apiSetting) + } else { + // 修改 + apiSettingRes = this.UpdateAPIMJSetting(apiSetting) + } + if (apiSettingRes && apiSettingRes.code == 1) { + mjSetting.apiSetting = apiSettingRes.data + } + } + + // 判断浏览器模式的数据是不是存在 + let browserSetting = mjSetting.browserSetting ? mjSetting.browserSetting : null + if (browserSetting != null) { + let browserSettingRes: { code: number; data: any; message: any } + if (isEmpty(browserSetting.id)) { + // 新增 + browserSettingRes = this.AddBrowserMJSetting(browserSetting) + } else { + // 修改 + browserSettingRes = this.UpdateBrowserMJSetting(browserSetting) + } + if (browserSettingRes && browserSettingRes.code == 1) { + mjSetting.browserSetting = browserSettingRes.data + } + } + + // 添加MJ的基础配置信息 + let mjSettingRes: { code: number; data: any; message: any } + if (isEmpty(mjSetting.id)) { + // 新增 + mjSettingRes = this.AddMJSetting(mjSetting) + } else { + // 修改 + mjSettingRes = this.UpdateMJSetting(mjSetting) + } + if (mjSettingRes && mjSettingRes.code == 1) { + mjSetting = mjSettingRes.data + } + }) + return successMessage(mjSetting, '添加信息成功', 'MJSettingService_SaveMJSettingTreeData') + } catch (error) { + throw error + } + } + + //#endregion +} diff --git a/src/define/db/service/SoftWare/softwareBasic.ts b/src/define/db/service/SoftWare/softwareBasic.ts new file mode 100644 index 0000000..c23c29e --- /dev/null +++ b/src/define/db/service/SoftWare/softwareBasic.ts @@ -0,0 +1,133 @@ +import Realm from 'realm' +import { BaseService } from '../baseService' +import { define } from '../../../define' +import path from 'path' +import { ComponentSize, SoftwareThemeType } from '../../../enum/softwareEnum' +import { SoftwareModel } from '../../model/SoftWare/software' +import { LoggerModel } from '../../model/SoftWare/logger' +import { + APIMjModel, + BrowserMJModel, + MjSettingModel, + RemoteMJModel +} from '../../model/SoftWare/mjSetting' +import { MJImageType, MJRobotType } from '../../../enum/mjEnum' +const { v4: uuidv4 } = require('uuid') + +let dbPath = path.resolve(define.db_path, 'software.realm') + +// 版本迁移 +const migration = (oldRealm: Realm, newRealm: Realm) => { + const oldBooks = oldRealm.objects('Software') + const newBooks = newRealm.objects('Software') + if (oldRealm.schemaVersion < 1) { + } + // 第二个版本 + if (oldRealm.schemaVersion < 2) { + newRealm.write(() => { + const newSoftwares = newRealm.objects('Software') + for (let software of newSoftwares) { + software.theme = SoftwareThemeType.LIGHT // 为新属性设置默认值 + } + }) + } + // 第三个版本 + if (oldRealm.schemaVersion < 3) { + newRealm.write(() => { + const newSoftwares = newRealm.objects('Software') + for (let software of newSoftwares) { + software.reverse_display_show = false + software.reverse_show_book_striped = false + software.reverse_data_table_size = ComponentSize.SMALL + } + }) + } + if (oldRealm.schemaVersion < 6) { + newRealm.write(() => { + const newSoftwares = newRealm.objects('MjSetting') + for (let software of newSoftwares) { + software.requestModel = MJImageType.API_MJ + } + }) + } + if (oldRealm.schemaVersion < 8) { + newRealm.write(() => { + const newSoftwares = newRealm.objects('MjSetting') + for (let software of newSoftwares) { + software.imageModel = MJRobotType.MJ + } + }) + } + if (oldRealm.schemaVersion < 9) { + newRealm.write(() => { + const newSoftwares = newRealm.objects('MjSetting') + for (let software of newSoftwares) { + software.accountId = null + } + }) + } + if (oldRealm.schemaVersion < 10) { + newRealm.write(() => { + const newSoftwares = newRealm.objects('MjSetting') + for (let software of newSoftwares) { + software.accountId = null + } + }) + } +} + +export class BaseSoftWareService extends BaseService { + static instance: BaseSoftWareService | null = null + protected realm: Realm + dbpath: string + + protected constructor() { + super() + this.dbpath = dbPath + } + + public static async getInstance() { + if (BaseSoftWareService.instance === null) { + BaseSoftWareService.instance = new BaseSoftWareService() + await BaseSoftWareService.instance.open() + } + return BaseSoftWareService.instance + } + + /** + * 创建数据库连接,如果已经存在则直接返回 + * @param dbPath 数据库文件地址 + * @returns + */ + async open() { + try { + if (this.realm != null) return + let config = { + schema: [ + SoftwareModel, + LoggerModel, + BrowserMJModel, + RemoteMJModel, + APIMjModel, + MjSettingModel + ], + path: dbPath, + schemaVersion: 10, // 当前版本号 + migration: migration + } + // 判断当前全局是不是又当前这个 + this.realm = await Realm.open(config) + // 判断当前是不是有数据,一条都没有的话添加一条空白数据 + if (this.realm.objects('Software').length == 0) { + this.realm.write(() => { + this.realm.create('Software', { + id: uuidv4(), + theme: SoftwareThemeType.LIGHT // 默认是亮色主题 + }) + }) + } + } catch (error) { + console.log(error) + } + } +} diff --git a/src/define/db/service/SoftWare/softwareService.ts b/src/define/db/service/SoftWare/softwareService.ts new file mode 100644 index 0000000..a040fe1 --- /dev/null +++ b/src/define/db/service/SoftWare/softwareService.ts @@ -0,0 +1,78 @@ +import Realm, { UpdateMode } from 'realm' +import path from 'path' +import { BaseService } from '../baseService.js' +import { define } from '../../../define.js' +import { SoftwareModel } from '../../model/SoftWare/software.js' +import { ComponentSize, SoftwareThemeType } from '../../../enum/softwareEnum.js' +import { successMessage } from '../../../../main/generalTools.js' +import { BaseSoftWareService } from './softwareBasic.js' +const { v4: uuidv4 } = require('uuid') + +export class SoftwareService extends BaseSoftWareService { + static instance: SoftwareService | null = null + realm: Realm + private constructor() { + super() + } + + /** + * 获取当前实例对象,为空则创建一个新的 + * @returns + */ + public static async getInstance() { + if (SoftwareService.instance === null) { + SoftwareService.instance = new SoftwareService() + await super.getInstance() + } + return SoftwareService.instance + } + + // 修改数据库中行中的某个属性数据 + async UpdateSoftware(software) { + try { + await this.open() + this.realm.write(() => { + this.realm.create('Software', software, UpdateMode.Modified) + }) + // 返回成功信息 + return successMessage(null, '修改软件配置信息成功', 'SoftwareService_UpdateSoftware') + } catch (error) { + throw error + } + } + + async AddSfotware(software) { + try { + await this.open() + software.id = uuidv4() + this.realm.write(() => { + this.realm.create('Software', software) + }) + } catch (error) { + throw error + } + } + + /** + * 或软件基础配置信息 + */ + async GetSoftwareData() { + try { + await this.open() + let software = this.realm.objects('Software') + return successMessage( + software.toJSON(), + '获取软件配置信息成功', + 'SoftwareService_GetSoftwareData' + ) + } catch (error) { + global.logger.error( + 'SoftwareService_GetSoftwareData', + '获取软件的基础设置失败 ,错误信息如下:' + error.toString() + ) + throw error + } + } +} + +export default SoftwareService diff --git a/src/define/db/service/baseService.ts b/src/define/db/service/baseService.ts new file mode 100644 index 0000000..5f42dca --- /dev/null +++ b/src/define/db/service/baseService.ts @@ -0,0 +1,36 @@ +// 定义抽象基类 +import Realm from 'realm' + +export abstract class BaseService { + protected realm: Realm | null = null + // 抽象类的构造函数应该是protected,以防止外部直接实例化 + protected constructor() { + // 构造函数逻辑,使用someValue进行初始化 + } + + // 定义抽象方法,子类必须实现,打开数据库连接 + abstract open(dbPath: string): void + + // 关闭数据库连接 + close(): void { + // 关闭数据库的连接,防止内存溢出 + // 实现关闭数据库连接的逻辑 + if (this.realm != null) { + console.log('Closing database connection') + this.realm.close() + this.realm = null // 清理引用,确保垃圾回收 + } + } + transaction(func: () => unknown): void { + if (this.realm != null) { + // 判断当前的relam是不是在一个事务中 + if (this.realm.isInTransaction) { + func() + } else { + this.realm.write(() => { + func() + }) + } + } + } +} diff --git a/src/define/define.js b/src/define/define.js index e853d0c..177a442 100644 --- a/src/define/define.js +++ b/src/define/define.js @@ -13,6 +13,8 @@ if (!app.isPackaged) { img_base: path.join(__dirname, "../../resources/config/img_base.json"), video_config: path.join(__dirname, "../../resources/config/video_config.json"), scripts_path: path.join(__dirname, "../../resources/scripts"), + db_path: path.join(__dirname, "../../resources/scripts/db"), + project_path: path.join(__dirname, "../../project"), logger_path: path.join(__dirname, "../../resources/logger"), package_path: path.join(__dirname, "../../resources/package"), image_path: path.join(__dirname, "../../resources/image"), @@ -44,6 +46,8 @@ if (!app.isPackaged) { video_config: path.join(__dirname, "../../../resources/config/video_config.json"), img_base: path.join(__dirname, "../../../resources/config/img_base.json"), scripts_path: path.join(__dirname, "../../../resources/scripts"), + db_path: path.join(__dirname, "../../../resources/scripts/db"), + project_path: path.join(__dirname, "../../../project"), logger_path: path.join(__dirname, "../../../resources/logger"), package_path: path.join(__dirname, "../../../resources/package"), discordScript: path.join(__dirname, "../../../resources/scripts/discordScript.js"), @@ -67,6 +71,8 @@ if (!app.isPackaged) { } } +define["remotemj_api"] = "https://api.laitool.net/" +define["API"] = "f85d39ed5a40fd09966f13f12b6cf0f0" export { define }; \ No newline at end of file diff --git a/src/define/define_string.js b/src/define/define_string.js index 64b1bda..1b38441 100644 --- a/src/define/define_string.js +++ b/src/define/define_string.js @@ -189,17 +189,34 @@ export const DEFINE_STRING = { BATCH_PROCESS_IMAGE: "BATCH_PROCESS_IMAGE", BATCH_PROCESS_IMAGE_RESULT: "BATCH_PROCESS_IMAGE_RESULT" }, + BOOK: { + GET_BOOK_TYPE: "GET_BOOK_TYPE", + ADD_OR_MODIFY_BOOK: "ADD_OR_MODIFY_BOOK", + GET_BOOK_DATA: "GET_BOOK_DATA", + GET_FRAME_DATA: "GET_FRAME_DATA", + GET_BOOK_TASK_DATA: "GET_BOOK_TASK_DATA" + }, SYSTEM: { OPEN_FILE: "OPEN_FILE", + RETURN_LOGGER: "RETURN_LOGGER", }, SETTING: { GET_DATA_BY_TYPE_AND_PROPERTY: "GET_DATA_BY_TYPE_AND_PROPERTY", SAVE_DATA_BY_TYPE_AND_PROPERTY: "SAVE_DATA_BY_TYPE_AND_PROPERTY", DELETE_DATA_BY_TYPE_AND_PROPERTY: "DELETE_DATA_BY_TYPE_AND_PROPERTY", + GET_SOFTWARE_SETTING: "GET_SOFTWARE_SETTING", + SAVE_SOFT_WARE_SETTING: "SAVE_SOFT_WARE_SETTING", + GET_COMPONENT_SIZE: "GET_COMPONENT_SIZE", + GET_MJ_SETTING_TREE_DATA: "GET_MJ_SETTING_TREE_DATA", + SAVE_MJ_SETTING_TREE_DATA: "SAVE_MJ_SETTING_TREE_DATA", + MJ_REMOTE_ACCOUNT_SYNC: "MJ_REMOTE_ACCOUNT_SYNC", + GET_MJ_SETTING: "GET_MJ_SETTING", + UPDATE_MJ_SETTING: "UPDATE_MJ_SETTING" }, PROMPT: { GET_SORT_OPTIONS: "GET_SORT_OPTIONS", SAVE_PROMPT_SORT_DATA: "SAVE_PROMPT_SORT_DATA", - GET_PROMPT_SORT_DATA: "GET_PROMPT_SORT_DATA" + GET_PROMPT_SORT_DATA: "GET_PROMPT_SORT_DATA", + OPEN_PROMPT_FILE_TXT: "OPEN_PROMPT_FILE_TXT" } } \ No newline at end of file diff --git a/src/define/enum/bookEnum.ts b/src/define/enum/bookEnum.ts new file mode 100644 index 0000000..da639e7 --- /dev/null +++ b/src/define/enum/bookEnum.ts @@ -0,0 +1,154 @@ +export enum BookType { + // 原创 + ORIGINAL = 'original', + // 反推 + SD_REVERSE = 'sd_reverse', + // MJ 反推 + MJ_REVERSE = 'mj_reverse' +} + +export enum MJCategroy { + // 本地MJ + LOCAL_MJ = 'local_mj', + // 代理MJ + REMOTE_MJ = 'remote_mj', + // 浏览器模式 + BROWSER_MJ = 'browser_mj', + // API模式 + API_MJ = 'api_mj' +} + +export enum MJAction { + // 生图 + IMAGINE = 'IMAGINE', + + // 反推describe + DESCRIBE = 'DESCRIBE' +} + +export enum BookBackTaskType { + // 分镜计算 + STORYBOARD = 'storyboard', + // 分割视频 + SPLIT = 'split', + // 提取音频 + AUDIO = 'audio', + // 识别字幕 + RECOGNIZE = 'recognize', + // 抽帧 + FRAME = 'frame', + // 反推 + REVERSE = 'reverse', + // 生成图片 + IMAGE = 'image', + // 高清 + HD = 'hd', + // 合成视频 + COMPOSING = 'composing', + // 推理 + INFERENCE = 'inference', + // 翻译 + TRANSLATE = 'translate' +} + +export enum BookBackTaskStatus { + // 等待 + WAIT = 'wait', + // 运行中 + RUNNING = 'running', + // 暂停 + PAUSE = 'pause', + // 完成 + DONE = 'done', + // 失败 + FAIL = 'fail' +} + +/** + * 小说任务状态 + */ +export enum BookTaskStatus { + // 等待 + WAIT = 'wait', + + // 分镜中 + STORYBOARD = 'storyboard', + + // 分镜失败 + STORYBOARD_FAIL = 'storyboard_fail', + + // 分镜完成,等待分割视频 + STORYBOARD_DONE = 'storyboard_done', + + // 分割视频中 + SPLIT = 'split', + + // 分割视频失败 + SPLIT_FAIL = 'split_fail', + + // 分割视频完成,等待提取音频 + SPLIT_DONE = 'split_done', + + // 提取音频中 + AUDIO = 'audio', + + // 提取音频失败 + AUDIO_FAIL = 'audio_fail', + + // 提取音频完成,等待识别字幕 + AUDIO_DONE = 'audio_done', + + // 识别字幕中 + RECOGNIZE = 'recognize', + + // 识别字幕失败 + RECOGNIZE_FAIL = 'recognize_fail', + + // 识别字幕完成,等待抽帧 + RECOGNIZE_DONE = 'recognize_done', + + // 抽帧中 + FRAME = 'frame', + + // 抽帧完成,等待反推 + FRAME_DONE = 'frame_done', + + // 抽帧失败 + FRAME_FAIL = 'frame_fail', + + // 反推中 + REVERSE = 'reverse', + + // 反推失败 + REVERSE_FAIL = 'reverse_fail', + + // 反推完成,等待生成图片 + REVERSE_DONE = 'reverse_done', + + // 生成图片中 + IMAGE = 'image', + + // 图片生成完成,等待高清 + IMAGE_DONE = 'image_done', + + // 图片生成失败 + IMAGE_FAIL = 'image_fail', + + // 高清中 + HD = 'hd', + + // 高清失败 + HD_FAIL = 'hd_fail', + + // 高清完成,等待合成视频 + HD_DONE = 'hd_done', + + // 合成视频中 + COMPOSING = 'composing', + + // 合成视频完成 + COMPOSING_DONE = 'composing_done', + + // 合成视频失败 + COMPOSING_FAIL = 'composing_fail' +} diff --git a/src/define/enum/mjEnum.ts b/src/define/enum/mjEnum.ts new file mode 100644 index 0000000..a7a8228 --- /dev/null +++ b/src/define/enum/mjEnum.ts @@ -0,0 +1,21 @@ +export enum MJImageType { + //本地MJ + LOCAL_MJ = 'local_mj', + + // 代理MJ + REMOTE_MJ = 'remote_mj', + + // 浏览器模式 + BROWSER_MJ = 'browser_mj', + + // API模式 + API_MJ = 'api_mj' +} + +export enum MJRobotType { + // MJ + MJ = 'mj', + + // niji + NIJI = 'niji' +} diff --git a/src/define/enum/softwareEnum.ts b/src/define/enum/softwareEnum.ts new file mode 100644 index 0000000..45119c6 --- /dev/null +++ b/src/define/enum/softwareEnum.ts @@ -0,0 +1,42 @@ +export enum SoftwareThemeType { + // 暗 + DARK = 'dark', + // 亮 + LIGHT = 'light' +} + +export enum ComponentSize { + // 极小 + TINY = 'tiny', + // 小 + SMALL = 'small', + // 中 + MEDIUM = 'medium', + // 大 + LARGE = 'large' +} + +export enum LoggerType { + // SD反推 + SD_REVERSE = 'sd_reverse', + // 原创 + ORIGINAL = 'original', + // MJ反推 + MJ_REVERSE = 'mj_reverse' +} + +export enum LoggerStatus { + // 成功 + SUCCESS = 'success', + // 失败 + FAIL = 'fail', + // 进行中 + DOING = 'doing' +} + +export enum OtherData { + // 未知 + UNKNOWN = 'unknown', + //默认 + DEFAULT = 'default' +} diff --git a/src/define/logger_define.js b/src/define/logger_define.js index effea38..a21b59f 100644 --- a/src/define/logger_define.js +++ b/src/define/logger_define.js @@ -6,7 +6,8 @@ export const LOGGER_DEFINE = { PROMPT: { GET_PROMPT_SORT_OPTIONS: "获取所有的排序选项", SAVE_PROMPT_SORT_DATA: "保存提示词排序的数据", - GET_PROMPT_SORT_DATA: "获取提示词排序的数据" + GET_PROMPT_SORT_DATA: "获取提示词排序的数据", + OPEN_PROMPT_FILE_TXT: "获取提示词文件数据" }, GLOBAL: { diff --git a/src/define/setting/mjSetting.js b/src/define/setting/mjSetting.js index ccff0bf..4708ac4 100644 --- a/src/define/setting/mjSetting.js +++ b/src/define/setting/mjSetting.js @@ -96,9 +96,9 @@ export class MjSetting { disable: true }, { - label: "代理MJ(待开发)", + label: "代理MJ(token)", value: "remote_mj", - disable: true + disable: false }, { label: "浏览器模式", diff --git a/src/main/IPCEvent/bookIpc.js b/src/main/IPCEvent/bookIpc.js new file mode 100644 index 0000000..6b94817 --- /dev/null +++ b/src/main/IPCEvent/bookIpc.js @@ -0,0 +1,27 @@ +import { ipcMain } from "electron"; +import { DEFINE_STRING } from '../../define/define_string' +import { ReverseBook } from "../ReverseManage/Book/ReverseBook"; +import { BasicReverse } from "../Task/BasicReverse"; +let reverseBook = new ReverseBook(); +let basicReverse = new BasicReverse(); + +export function BookIpc() { + // 获取样式图片的子列表 + ipcMain.handle(DEFINE_STRING.BOOK.GET_BOOK_TYPE, async (event) => reverseBook.GetBookType()); + + // 新增或者是修改小说数据 + ipcMain.handle(DEFINE_STRING.BOOK.ADD_OR_MODIFY_BOOK, async (event, book) => reverseBook.AddOrModifyBook(book)); + + // 获取小说数据(通过传递的参数进行筛选) + ipcMain.handle(DEFINE_STRING.BOOK.GET_BOOK_DATA, async (event, bookQuery) => reverseBook.GetBookData(bookQuery)); + + //#region 一键反推 + + ipcMain.handle(DEFINE_STRING.BOOK.GET_BOOK_TASK_DATA, async (event, bookTaskCondition) => reverseBook.GetBookTaskData(bookTaskCondition)); + + // 获取抽帧数据 + ipcMain.handle(DEFINE_STRING.BOOK.GET_FRAME_DATA, async (event, bookId) => basicReverse.GetFrameData(bookId)); + + //#endregion + +} \ No newline at end of file diff --git a/src/main/IPCEvent/imageGenerateIpc.js b/src/main/IPCEvent/imageGenerateIpc.js index dfe1748..9f65c8d 100644 --- a/src/main/IPCEvent/imageGenerateIpc.js +++ b/src/main/IPCEvent/imageGenerateIpc.js @@ -4,7 +4,7 @@ import { import { DEFINE_STRING } from '../../define/define_string' import { ImageGenerate -} from '../backPrompt/imageGenerate' +} from '../ReverseManage/imageGenerate' let imageGenerate = new ImageGenerate(global); function ImageGenerateIpc() { diff --git a/src/main/IPCEvent/index.js b/src/main/IPCEvent/index.js index 1fe1677..9cd4f05 100644 --- a/src/main/IPCEvent/index.js +++ b/src/main/IPCEvent/index.js @@ -11,7 +11,8 @@ import { SdIpc } from './sdIpc.js' import { MainIpc } from './mainIpc.js' import { GlobalIpc } from "./globalIpc.js"; import { ImageIpc } from "./imageIpc.js"; -import { SystemIpc } from "./system.js"; +import { SystemIpc } from "./systemIpc.js"; +import { BookIpc } from "./bookIpc.js" export function RegisterIpc(createWindow) { PromptIpc() @@ -28,5 +29,6 @@ export function RegisterIpc(createWindow) { GlobalIpc(); ImageIpc(); SystemIpc(); + BookIpc(); } diff --git a/src/main/IPCEvent/promptIpc.js b/src/main/IPCEvent/promptIpc.js index 0cce8a8..fba6ee7 100644 --- a/src/main/IPCEvent/promptIpc.js +++ b/src/main/IPCEvent/promptIpc.js @@ -12,6 +12,9 @@ function PromptIpc() { // 获取已经保存的提示词数据 ipcMain.handle(DEFINE_STRING.PROMPT.GET_PROMPT_SORT_DATA, (event) => prompt.GetPromptSort()) + + // 获取提示词文件数据(txt,指定路径) + ipcMain.handle(DEFINE_STRING.PROMPT.OPEN_PROMPT_FILE_TXT, (event, value) => prompt.OpenPromptFileTxt(value)) } export { PromptIpc diff --git a/src/main/IPCEvent/settingIpc.js b/src/main/IPCEvent/settingIpc.js index 5589912..6194efd 100644 --- a/src/main/IPCEvent/settingIpc.js +++ b/src/main/IPCEvent/settingIpc.js @@ -7,6 +7,10 @@ import { Setting } from '../setting/setting' let setting = new Setting(global); +import { BasicSetting } from '../setting/basicSetting'; +let basicSetting = new BasicSetting(); +import { MJSetting } from '../setting/mjSetting'; +let mjSetting = new MJSetting(); async function SettingIpc() { @@ -82,6 +86,36 @@ async function SettingIpc() { //#endregion + //#region 基础设置 + // 获取软件的基础设置(初始的时候执行一次) + ipcMain.handle(DEFINE_STRING.SETTING.GET_SOFTWARE_SETTING, async (event) => await basicSetting.GetSoftwareSetting()); + + // 保存软件的基础设置 + ipcMain.handle(DEFINE_STRING.SETTING.SAVE_SOFT_WARE_SETTING, async (event, value) => await basicSetting.SaveSoftWareSetting(value)); + + // 返回组件尺寸的大小的数据(通用) + ipcMain.handle(DEFINE_STRING.SETTING.GET_COMPONENT_SIZE, async (event) => basicSetting.GetComponentSize()); + + //#endregion + + //#region MJ 设置 + + // 获取MJ基础设置信息 + ipcMain.handle(DEFINE_STRING.SETTING.GET_MJ_SETTING, async (event, value) => mjSetting.GetMJSetting(value)); + + // 保存MJ的基础设置信息 + ipcMain.handle(DEFINE_STRING.SETTING.UPDATE_MJ_SETTING, async (event, value) => mjSetting.UpdateMJSetting(value)); + + // 获取MJ的所有设置 + ipcMain.handle(DEFINE_STRING.SETTING.GET_MJ_SETTING_TREE_DATA, async (event) => mjSetting.GetMJSettingTreeData()); + + // 保存MJ的所有设置 + ipcMain.handle(DEFINE_STRING.SETTING.SAVE_MJ_SETTING_TREE_DATA, async (event, value) => mjSetting.SaveMJSettingTreeData(value)); + + // MJ代理模式账号同步 + ipcMain.handle(DEFINE_STRING.SETTING.MJ_REMOTE_ACCOUNT_SYNC, async (event) => mjSetting.MjRemoteAccountSync()); + //#endregion + } export { diff --git a/src/main/IPCEvent/system.js b/src/main/IPCEvent/system.js deleted file mode 100644 index 521c54e..0000000 --- a/src/main/IPCEvent/system.js +++ /dev/null @@ -1,17 +0,0 @@ -import { ipcMain } from "electron"; -import { DEFINE_STRING } from '../../define/define_string' -const { shell } = require('electron') - - - -function SystemIpc() { - - // 打开指定的文件 - ipcMain.on(DEFINE_STRING.SYSTEM.OPEN_FILE, async (event, value) => { - await shell.openPath(value); - }); - -} -export { - SystemIpc -} \ No newline at end of file diff --git a/src/main/IPCEvent/systemIpc.js b/src/main/IPCEvent/systemIpc.js new file mode 100644 index 0000000..a1e875f --- /dev/null +++ b/src/main/IPCEvent/systemIpc.js @@ -0,0 +1,40 @@ +import { ipcMain } from "electron"; +import { DEFINE_STRING } from '../../define/define_string' +import { CheckFileOrDirExist } from "../../define/Tools/file"; +import { errorMessage, successMessage } from "../generalTools"; +import path from 'path' +const { shell } = require('electron') + +function SystemIpc() { + + // 打开指定的文件 + ipcMain.on(DEFINE_STRING.SYSTEM.OPEN_FILE, async (event, value) => { + await shell.openPath(value); + }); + + // 试用文件资源打开指定的文件夹 + ipcMain.handle(DEFINE_STRING.OPEN_FOLDER, async (event, value) => { + try { + let openFolder = null + if (value.baseProject) { + openFolder = path.join(global.config.project_path, value.folderPath) + } + else { + openFolder = value.folderPath + } + // 判断文件夹是不是存在 + let isExist = await CheckFileOrDirExist(openFolder) + if (!isExist) { + throw new Error("文件夹不存在,请检查") + } + shell.openPath(openFolder) + return successMessage(null, '打开成功'); + } catch (error) { + return errorMessage("打开文件夹错误,错误信息如下:" + error.message, "SystemIpc_OPEN_FOLDER") + } + + }); +} +export { + SystemIpc +} \ No newline at end of file diff --git a/src/main/IPCEvent/videoGenerateIpc.js b/src/main/IPCEvent/videoGenerateIpc.js index eebfd17..acff0f2 100644 --- a/src/main/IPCEvent/videoGenerateIpc.js +++ b/src/main/IPCEvent/videoGenerateIpc.js @@ -1,6 +1,6 @@ import { ipcMain } from "electron"; import { DEFINE_STRING } from '../../define/define_string' -import { VideoGenerate } from "../backPrompt/videoGenerate"; +import { VideoGenerate } from "../ReverseManage/videoGenerate"; let videoGenerate = new VideoGenerate(global); function VideoGenerateIpc() { diff --git a/src/main/IPCEvent/writingIpc.js b/src/main/IPCEvent/writingIpc.js index 668dc1d..630e256 100644 --- a/src/main/IPCEvent/writingIpc.js +++ b/src/main/IPCEvent/writingIpc.js @@ -4,7 +4,7 @@ import { import { DEFINE_STRING } from '../../define/define_string' import { Writing -} from '../backPrompt/writing' +} from '../ReverseManage/writing' let writing = new Writing(global); function WritingIpc() { diff --git a/src/main/Original/MJOriginalImageGenerate.js b/src/main/Original/MJOriginalImageGenerate.js index 138a9b7..17c2f37 100644 --- a/src/main/Original/MJOriginalImageGenerate.js +++ b/src/main/Original/MJOriginalImageGenerate.js @@ -16,6 +16,8 @@ import { GPT } from "../Public/GPT"; import { TagDefine } from "../../define/tagDefine"; import { cloneDeep } from "lodash"; import { LOGGER_DEFINE } from "../../define/logger_define"; +import { MJImageType } from "../../define/enum/mjEnum"; +import { MJSettingService } from "../../define/db/service/SoftWare/mjSettingService"; const { v4: uuidv4 } = require('uuid'); /** @@ -226,7 +228,7 @@ export class MJOriginalImageGenerate { try { value = JSON.parse(value); let mjSetting = await this.InitMjSetting(); - let request_model = mjSetting.request_model; + let request_model = mjSetting.requestModel; let result = []; // 浏览器生图模式 if (request_model == "browser_mj") { @@ -260,7 +262,7 @@ export class MJOriginalImageGenerate { result = await discordSimple.ExecuteScript(define.discordScript, `GetGeneratedMJImageAndSplit(${JSON.stringify(param)})`); } else if (request_model == "api_mj") { - let mj_api = await this.InitMJAPIUrl(mjSetting.mj_api_url); + let mj_api = await this.InitMJAPIUrl(mjSetting.apiSetting.mjApiUrl); let once_get_task = mj_api.mj_url.once_get_task; // 请求 @@ -273,10 +275,10 @@ export class MJOriginalImageGenerate { continue } - let task_res = await this.discordAPI.GetMJAPITaskByID(element.mj_message.message_id, once_get_task, mjSetting.api_key); + let task_res = await this.discordAPI.GetMJAPITaskByID(element.mj_message.message_id, once_get_task, mjSetting.apiSetting.apiKey); if (task_res.code == 0) { task_res["id"] = element.id; - task_res["mj_api_url"] = mjSetting.mj_api_url; + task_res["mj_api_url"] = mjSetting.apiSetting.mjApiUrl; this.sendChangeMessage() } // 判断进度是不是百分百 @@ -380,14 +382,31 @@ export class MJOriginalImageGenerate { * @param {*} element * @param {*} mjSetting */ - async MJImagineRequest(element, mjSetting, prompt) { + async MJImagineRequest(element, mjSetting, prompt, tasK_id = null, batch = null) { try { - // 获取当前的API url - let apiUrl = await this.InitMJAPIUrl(mjSetting.mj_api_url); + if (mjSetting.apiSetting == null) { + throw new Error("没有API设置,请先设置API设置"); + } + let apiUrl; + if (mjSetting.requestModel == MJImageType.API_MJ) { + // 获取当前的API url + apiUrl = await this.InitMJAPIUrl(mjSetting.apiSetting.mjApiUrl); + } else if (mjSetting.requestModel == MJImageType.REMOTE_MJ) { + apiUrl = { + mj_url: { + imagine: define.remotemj_api + 'mj/submit/imagine', + once_get_task: define.remotemj_api + "mj/task/${id}/fetch" + } + } + + } else { + throw new Error("未知的生图模式,请检查配置") + } let imagine_url = apiUrl.mj_url.imagine; let once_get_task = apiUrl.mj_url.once_get_task; - let task_count = mjSetting.task_count ? mjSetting.task_count : 3; - let mj_speed = mjSetting.mj_speed ? mjSetting.mj_speed : "relaxed"; + + let task_count = mjSetting.taskCount ? mjSetting.taskCount : 3; + let mj_speed = mjSetting.apiSetting.mjSpeed ? mjSetting.apiSetting.mjSpeed : "relaxed"; let res; // 判断当前的API是哪个 if (imagine_url.includes("mjapi.deepwl.net")) { @@ -397,7 +416,7 @@ export class MJOriginalImageGenerate { mode: mj_speed == "fast" ? "FAST" : "RELAX", } let headers = { - "Authorization": mjSetting.api_key + "Authorization": mjSetting.apiSetting.apiKey } res = await this.discordAPI.mjApiImagine(imagine_url, data, headers); @@ -408,7 +427,7 @@ export class MJOriginalImageGenerate { } else if (imagine_url.includes("api.ephone.ai")) { // ePhoneAPI let headers = { - "Authorization": mjSetting.api_key + "Authorization": mjSetting.apiSetting.apiKey } let data = { prompt: prompt, @@ -420,15 +439,71 @@ export class MJOriginalImageGenerate { } } res = await this.discordAPI.mjApiImagine(imagine_url, data, headers); + } else if (imagine_url.includes(define.remotemj_api)) { + // 代理模式 + let headers = { + "mj-api-secret": define.API + } + + // 判断数据是不是存在 + if (!mjSetting.remoteSetting.channelId) { + throw new Error("请先设置channelId") + } + if (!mjSetting.remoteSetting.accountId) { + throw new Error("请先同步账号") + } + let data = { + prompt: prompt, + botType: "MID_JOURNEY", + accountFilter: { + channelId: mjSetting.remoteSetting.channelId, + instanceId: mjSetting.remoteSetting.accountId, + remark: this.global.machineId, + modes: [ + mj_speed == "fast" ? "FAST" : "RELAX" + ] + } + } + res = await this.discordAPI.mjApiImagine(imagine_url, data, headers); } + this.global.mjGenerateQuene.setCurrentCreateItem(null); // 错误检查 if (res.code == 23) { - throw new Error("生图队列已满,请稍后尝试"); + // 任务队列已满,及结束该任务,然后开始下一个任务,并将该任务重新排序 + this.global.mjGenerateQuene.removeTaskProgress((taskProgress) => { + return taskProgress.filter(item => item?.id != element.id) + }); + this.sendChangeMessage({ + code: 0, + status: "error", + message: "任务队列已满,任务结束会重新排序,并等待3分钟,开始后面的任务", + id: element.id + }) + await this.tools.delay(40000); + // 重新将当前任务加入队列 + this.global.mjGenerateQuene.enqueue(async () => { + this.global.mjGenerateQuene.setCurrentCreateItem(element) + await this.MJImagineRequest(element, mjSetting, prompt) + }, tasK_id, batch) + + this.global.mjGenerateQuene.startNextTask(task_count); + return; } if (res.code != 1 && res.code != 22) { - throw new Error("未知错误,可联系管理员排查" + res.description); + // 未知错误,将当前任务删除,开始下一个任务 + this.global.mjGenerateQuene.removeTaskProgress((taskProgress) => { + return taskProgress.filter(item => item?.id != element.id) + }); + this.global.mjGenerateQuene.startNextTask(task_count); + this.sendChangeMessage({ + code: 0, + status: "error", + message: "未知错误,可联系管理员排查," + res.description, + id: element.id + }) + return; } // 创建成功,开始下一个 this.sendChangeMessage({ @@ -440,16 +515,15 @@ export class MJOriginalImageGenerate { image_show: null, id: element.id, progress: 0, - mj_api_url: mjSetting.mj_api_url + mj_api_url: mjSetting.apiSetting.mjApiUrl }); - this.global.mjGenerateQuene.setCurrentCreateItem(null); // 开始监听当前ID是不是的生图任务完成 // 这边设置一个循环监听,每隔一段时间去请求一次 let timeoutId; let startInterval = () => { timeoutId = setTimeout(async () => { // 执行你的操作 - let task_res = await this.discordAPI.GetMJAPITaskByID(res.result, once_get_task, mjSetting.api_key) + let task_res = await this.discordAPI.GetMJAPITaskByID(res.result, once_get_task, mjSetting.apiSetting.apiKey) console.log(task_res) // 判断他的状态是不是成功 if (task_res.code == 0) { @@ -479,7 +553,7 @@ export class MJOriginalImageGenerate { } } task_res['id'] = element.id; - task_res["mj_api_url"] = mjSetting.mj_api_url; + task_res["mj_api_url"] = mjSetting.apiSetting.mjApiUrl; this.sendChangeMessage(task_res); }, 5000); } @@ -521,16 +595,19 @@ export class MJOriginalImageGenerate { let output_crop_00001 = path.join(this.global.config.project_path, `tmp\\output_crop_00001`); await this.tools.checkFolderExistsOrCreate(output_crop_00001); - // 获取MJ配置 - let mjSetting = await this.InitMjSetting(); + // 获取MJ配置,从数据库中 + let _mjSettingService = await MJSettingService.getInstance() + let mjSettings = _mjSettingService.GetMJSettingTreeData(); + if (mjSettings.code == 0) { + throw new Error(mjSettings.message) + } + let mjSetting = mjSettings.data; // 检查this.global中是不是又mj队列,没有的话创建一个 if (!this.global.mjGenerateQuene) { this.global.mjGenerateQuene = new AsyncQueue(this.global, 1, true); } - let style_ids = await this.pm.GetConfigJson(JSON.stringify(["image_style", []]), false); - // 替换风格的逻辑 let current_task = null; @@ -542,17 +619,25 @@ export class MJOriginalImageGenerate { // 拼接提示词 // 图生图的链接 // 获取风格词 + 命令后缀 - let prompt = old_prompt + (mjSetting.image_suffix ? mjSetting.image_suffix : ""); + let prompt = old_prompt + (mjSetting.imageSuffix ? mjSetting.imageSuffix : ""); // 判断当前生图模式 - let request_model = mjSetting.request_model + let request_model = mjSetting.requestModel switch (request_model) { case "api_mj": this.global.mjGenerateQuene.enqueue(async () => { this.global.mjGenerateQuene.setCurrentCreateItem(element) - await this.MJImagineRequest(element, mjSetting, prompt) + await this.MJImagineRequest(element, mjSetting, prompt, tasK_id, batch) }, tasK_id, batch) break; + + case MJImageType.REMOTE_MJ: + this.global.mjGenerateQuene.enqueue(async () => { + this.global.mjGenerateQuene.setCurrentCreateItem(element) + await this.MJImagineRequest(element, mjSetting, prompt, tasK_id, batch) + }, tasK_id, batch) + break; + case "browser_mj": this.global.mjGenerateQuene.enqueue(async () => { try { @@ -575,7 +660,7 @@ export class MJOriginalImageGenerate { } // 判断该当前正在执行的人物队列数(小于设置的数量,开始一个任务) - this.global.mjGenerateQuene.startNextTask(mjSetting.task_count ? mjSetting.task_count : 3); + this.global.mjGenerateQuene.startNextTask(mjSetting.taskCount ? mjSetting.taskCount : 3); this.global.requestQuene.setBatchCompletionCallback(batch, (failedTasks) => { if (failedTasks.length > 0) { diff --git a/src/main/Public/Prompt.js b/src/main/Public/Prompt.js index 16d09bc..e66b0a3 100644 --- a/src/main/Public/Prompt.js +++ b/src/main/Public/Prompt.js @@ -1,6 +1,12 @@ import { errorMessage, successMessage } from "../generalTools"; import { LOGGER_DEFINE } from '../../define/logger_define' import { Setting } from "../setting/setting"; +import { isEmpty } from "lodash"; +import fs from 'fs'; +import readline from 'readline'; +import { file } from '../../define/Tools/index' +import path from "path"; +let fspromises = fs.promises; export class Prompt { constructor() { @@ -79,4 +85,42 @@ export class Prompt { return errorMessage(error.toString(), LOGGER_DEFINE.PROMPT.GET_PROMPT_SORT_DATA) } } + + /** + * 获取txt文件的数据,将每行导出导致一个数组,返回一个数组 + * @param {string} value txt文件的地址 + */ + async OpenPromptFileTxt(value) { + try { + if (isEmpty(value)) { + throw new Error("传入的文件地址不能为空") + } + // 检查文件是不是存在 + if (!file.CheckFileOrDirExist(value)) { + throw new Error("传入的文件地址对应的文件不存在"); + } + + async function processLineByLine() { + const fileStream = fs.createReadStream(path.normalize(value)); + const rl = readline.createInterface({ + input: fileStream, + crlfDelay: Infinity + }); + const lines = []; + for await (const line of rl) { + lines.push(line); + } + rl.close(); // 确保关闭 readline 流 + return lines; + } + + let res = await processLineByLine() + // return successMessage(res, "获取数据成功", LOGGER_DEFINE.PROMPT.OPEN_PROMPT_FILE_TXT); + console.log(res); + return successMessage(res, "获取成功", LOGGER_DEFINE.PROMPT.OPEN_PROMPT_FILE_TXT) + + } catch (error) { + return errorMessage(error.toString(), LOGGER_DEFINE.PROMPT.OPEN_PROMPT_FILE_TXT); + } + } } \ No newline at end of file diff --git a/src/main/ReverseManage/Book/BooKBasic.js b/src/main/ReverseManage/Book/BooKBasic.js new file mode 100644 index 0000000..f35bc4e --- /dev/null +++ b/src/main/ReverseManage/Book/BooKBasic.js @@ -0,0 +1,63 @@ +import { BookType } from "../../../define/enum/bookEnum"; +import { errorMessage, successMessage } from "../../generalTools"; +import BooKService from "../../../define/db/service/Book/bookService"; +import { BookTaskService } from "../../../define/db/service/Book/bookTaskService"; +const { v4: uuidv4 } = require('uuid'); +import { define } from '../../../define/define' +import path from 'path' +import { CheckFolderExistsOrCreate } from "../../../define/Tools/file"; + +export class BookBasic { + constructor() { + } + + /** + * 获取路径中的最后一层或两层目录 + * @param {string} path 文件或目录的完整路径 + * @param {number} level 需要获取的层级数(1表示最后一层,2表示最后两层) + * @returns {string} 最后的一层或两层目录 + */ + getLastPathLevels(path, level = 1) { + // 根据操作系统的不同,路径分隔符可能不同 + const separator = path.includes('/') ? '/' : '\\'; + const parts = path.split(separator); + // 获取最后的一层或两层目录 + const lastLevels = parts.slice(-level); + // 重新组合成路径字符串 + return lastLevels.join(separator); + } + + /** + * 新增或者是修小说数据 + * @param {*} book 小说信息 + * @returns + */ + async AddOrModifyBook(book) { + try { + if (book == null) { + return errorMessage('小说数据为空,无法修改'); + } + // 处理一下数据,处理文件地址(删除前缀,转换为默认地址) + // 当前的小说的名字是不是在数据库中以存在 + let _bookService = await BooKService.getInstance(); + let res = await _bookService.AddOrModifyBook(book); + return res; + } catch (error) { + return errorMessage('修改数据错误,错误信息如下:' + error.message, 'BookBasic_AddOrModifyBook'); + } + } + + // 小说类型返回 + GetBookType() { + return successMessage([{ + label: 'SD反推', + value: BookType.SD_REVERSE + }, { + label: 'MJ反推', + value: BookType.MJ_REVERSE + }, { + label: "原创", + value: BookType.ORIGINAL + }], '获取小说类型成功'); + } +} \ No newline at end of file diff --git a/src/main/ReverseManage/Book/ReverseBook.js b/src/main/ReverseManage/Book/ReverseBook.js new file mode 100644 index 0000000..cf0e2a0 --- /dev/null +++ b/src/main/ReverseManage/Book/ReverseBook.js @@ -0,0 +1,49 @@ +import { successMessage, errorMessage } from "../../generalTools.js"; +import { BookBasic } from "./BooKBasic.js"; +import BooKService from "../../../define/db/service/Book/bookService"; +import { BookTaskService } from "../../../define/db/service/Book/bookTaskService"; +import { define } from '../../../define/define.js' +import path from 'path' + +export class ReverseBook extends BookBasic { + constructor() { + super() + + } + + /** + * 获取当前的小说数据 + * @param {*} bookQuery + */ + async GetBookData(bookQuery) { + try { + let _bookService = await BooKService.getInstance(); + // 添加小说 + let res = await _bookService.GetBookData(bookQuery) + if (res.code == 0) { + throw new Error(res.message) + } + return res + } catch (error) { + return errorMessage(error.message, 'ReverseBook_GetBookData'); + } + } + + /** + * 获取小说的任务列表 + * @param {*} bookTaskCondition 查询任务列表的条件 + */ + async GetBookTaskData(bookTaskCondition) { + try { + let _bookTaskService = await BookTaskService.getInstance(); + let res = await _bookTaskService.GetBookTaskData(bookTaskCondition) + if (res.code == 0) { + throw new Error(res.message) + } + return res; + } catch (error) { + return errorMessage("获取小说对应批次错误,错误信息入校:" + error.message, 'ReverseBook_GetBookTaskData'); + } + } + +} \ No newline at end of file diff --git a/src/main/backPrompt/imageGenerate.js b/src/main/ReverseManage/imageGenerate.js similarity index 100% rename from src/main/backPrompt/imageGenerate.js rename to src/main/ReverseManage/imageGenerate.js diff --git a/src/main/backPrompt/videoGenerate.js b/src/main/ReverseManage/videoGenerate.js similarity index 100% rename from src/main/backPrompt/videoGenerate.js rename to src/main/ReverseManage/videoGenerate.js diff --git a/src/main/backPrompt/writing.js b/src/main/ReverseManage/writing.js similarity index 100% rename from src/main/backPrompt/writing.js rename to src/main/ReverseManage/writing.js diff --git a/src/main/Task/basicReverse.js b/src/main/Task/basicReverse.js new file mode 100644 index 0000000..b93108d --- /dev/null +++ b/src/main/Task/basicReverse.js @@ -0,0 +1,95 @@ +import path from 'path'; +import fs from 'fs'; +const util = require('util'); +const { exec } = require('child_process'); +const execAsync = util.promisify(exec); +import { define } from '../../define/define'; +import BooKService from '../../define/db/service/Book/bookService'; +import { TaskScheduler } from './taskScheduler'; +import { LoggerStatus, LoggerType, OtherData } from '../../define/enum/softwareEnum'; +import { errorMessage } from '../generalTools'; +import { CheckFileOrDirExist } from '../../define/Tools/file'; +import { BookTaskDetailService } from '../../define/db/service/Book/bookTaskDetailService'; + +const fspromises = fs.promises; + +// 基础的反推(抽帧,分镜,提取字幕等) +export class BasicReverse { + constructor() { + this.taskScheduler = new TaskScheduler() + } + + /** + * 分镜(通过传入的bookId) + * @param {*} bookId 传入的bookId + * @returns + */ + async GetFrameData(bookId) { + try { + let _bookService = await BooKService.getInstance(); + let _bookTaskDetailService = await BookTaskDetailService.getInstance(); + // 获取对应的小说小说数据,找到对应的小说视频地址 + let bookQuery = { + bookId: bookId + } + let bookData = await _bookService.GetBookData(bookQuery) + if (bookData.code == 0) { + return bookData + } + + if (bookData.data.book_length <= 0 || bookData.data.res_book.length <= 0) { + throw new Error("没有找到对应的小说数据,请检查bookId是否正确") + } + + // 获取小说的视频地址 + let book = bookData.data.res_book[0] + let oldVideoPath = book.oldVideoPath + let frameJson = oldVideoPath + '.json' + + let sensitivity = 30 + // 开始之前,推送日志 + let log_content = `开始进行分镜操作,视频地址:${oldVideoPath},敏感度:${sensitivity},正在调用程序进行处理` + await this.taskScheduler.AddLogToDB(bookId, book.type, log_content, OtherData.DEFAULT, LoggerStatus.DOING) + + // 小说进行分镜(python进行,将结果写道一个json里面) + // 使用异步的方法调用一个python程序,然后写入到指定的json文件中k + let command = `"${path.join(define.scripts_path, "Lai.exe")}" "-ka" "${oldVideoPath}" "${frameJson}" "${sensitivity}"` + const output = await execAsync(command, { maxBuffer: 1024 * 1024 * 10, encoding: 'utf-8' }); + // 有错误输出 + if (output.stderr != '') { + await this.taskScheduler.AddLogToDB(bookId, book.type, `分镜失败,错误信息如下:${output.stderr}`, OtherData.DEFAULT, LoggerStatus.FAIL) + throw new Error(output.stderr); + } + // 分镜成功,处理输出 + let josnIsExist = CheckFileOrDirExist(frameJson) + if (!josnIsExist) { + let error_message = `分镜失败,没有找到对应的分镜输出文件:${frameJson}` + await this.taskScheduler.AddLogToDB(bookId, book.type, error_message, OtherData.DEFAULT, LoggerStatus.FAIL) + throw new Error(error_message) + } + + let frameJsonData = JSON.parse(await fspromises.readFile(frameJson, 'utf-8')) + if (frameJsonData.length <= 0) { + await this.taskScheduler.AddLogToDB(bookId, book.type, `分镜失败,没有找到对应的分镜数据`, OtherData.DEFAULT, LoggerStatus.FAIL) + throw new Error("分镜失败,没有找到对应的分镜数据") + } + // 循环写入小说人物详细数据 + for (let i = 0; i < frameJsonData.length; i++) { + let frameData = frameJsonData[i] + let bookTaskDetail = { + bookId: bookId, + } + await _bookTaskDetailService.AddBookTaskDetail(frameDataQuery) + } + + + console.log() + + console.log(output.stdout) + + + } catch (error) { + return errorMessage(error.message, 'BasicReverse_GetFrameData'); + } + } +} \ No newline at end of file diff --git a/src/main/Task/mjReverse.js b/src/main/Task/mjReverse.js new file mode 100644 index 0000000..e69de29 diff --git a/src/main/Task/sdReverse.js b/src/main/Task/sdReverse.js new file mode 100644 index 0000000..e69de29 diff --git a/src/main/Task/taskScheduler.js b/src/main/Task/taskScheduler.js new file mode 100644 index 0000000..bd8d60f --- /dev/null +++ b/src/main/Task/taskScheduler.js @@ -0,0 +1,41 @@ + +import { LoggerService } from '../../define/db/service/SoftWare/loggerService'; +import { DEFINE_STRING } from '../../define/define_string'; +import { LoggerStatus, OtherData } from '../../define/enum/softwareEnum'; +import { successMessage } from '../generalTools'; + +export class TaskScheduler { + constructor() { + + } + /** + * 添加日志到数据库,然后返回日志信息到前端,日志记录失败不会报错 + * @param {*} bookId 小说ID,必填 + * @param {*} type 日志类型,必填 LoggerType + * @param {*} content 日志记录内容,必填 + * @param {*} bookTaskId 小说子任务,选填,默认 OtherData.DEFAULT + * @param {*} status 状态,选填,默认 LoggerStatus.DOING + * @returns + */ + async AddLogToDB(bookId, type, content, bookTaskId = OtherData.DEFAULT, status = LoggerStatus.DOING) { + try { + let log = + { + bookId: bookId, + bookTaskId: bookTaskId, + type: type, + status: status, + content: content + } + + let _loggerService = await LoggerService.getInstance(); + let res = await _loggerService.AddLogger(log) + // 添加成功之后,将消息推动到前端 + global.newWindow[0].win.webContents.send(DEFINE_STRING.SYSTEM.RETURN_LOGGER, successMessage(res)) + + return res + } catch (error) { + return errorMessage(error.message, 'TaskScheduler_AddLogToDB'); + } + } +} \ No newline at end of file diff --git a/src/main/discord/discordSimple.js b/src/main/discord/discordSimple.js index feb05bf..9a008ca 100644 --- a/src/main/discord/discordSimple.js +++ b/src/main/discord/discordSimple.js @@ -104,7 +104,7 @@ export class DiscordSimple { async GetInputPosition() { try { await this.InitData(); - await this.tools.delay(this.mjSetting.space_time ? this.mjSetting.space_time * 1000 : 10000) + await this.tools.delay(this.mjSetting.spaceTime ? this.mjSetting.spaceTime * 1000 : 10000) let result = await this.ExecuteScript(this.script, 'GetMessageInputPosition()'); this.x = result.mouseX; this.y = result.mouseY; @@ -654,7 +654,7 @@ export class DiscordSimple { // 在将当前任务设置为空 global.mjGenerateQuene.setCurrentCreateItem(null); // 开始下一个任务 - global.mjGenerateQuene.startNextTask(this.mjSetting.task_count ? this.mjSetting.task_count : 3); + global.mjGenerateQuene.startNextTask(this.mjSetting.taskCount ? this.mjSetting.taskCount : 3); } @@ -704,7 +704,7 @@ export class DiscordSimple { global.mjGenerateQuene.setCurrentCreateItem(null); } - global.mjGenerateQuene.startNextTask(this.mjSetting.task_count ? this.mjSetting.task_count : 3); + global.mjGenerateQuene.startNextTask(this.mjSetting.taskCount ? this.mjSetting.taskCount : 3); } catch (error) { this.sendChangeMessage({ diff --git a/src/main/discord/discordWorker.js b/src/main/discord/discordWorker.js index 810fecb..aaf74d6 100644 --- a/src/main/discord/discordWorker.js +++ b/src/main/discord/discordWorker.js @@ -1,6 +1,7 @@ import { DiscordSimple } from "./discordSimple"; import { Tools } from "../tools"; import { define } from "../../define/define"; +import { MJSettingService } from "../../define/db/service/SoftWare/mjSettingService"; /** * discord中的一些公用的方法 @@ -15,16 +16,15 @@ export class DiscordWorker { */ async InitData() { if (this.mj_config) return; - // 初始化配置文件,若是没有配置文件,则创建一个配置文件 - let mj_config_default = { - serviceID: null, - channelID: null, - authorization: null, - userAgent: null + // 初始化MJ配置 + let _mjSettingService = await MJSettingService.getInstance(); + let mjSettings = _mjSettingService.GetMJSettingTreeData(); + if (mjSettings.code == 0) { + throw new Error(mjSettings.message); } - // 判断是不是有对应的mj的配置,没有的话就返回默认值 - let mj_config = await this.tools.getJsonFilePropertyValue(define.img_base, "mj_config", mj_config_default, false); - this.mj_config = mj_config; + let mjSetting = mjSettings.data; + + this.mj_config = mjSetting; } /** @@ -57,23 +57,26 @@ export class DiscordWorker { await mainSimple.WaitWindowFinishLoad(discordW); } // 切换到指定的界面 - // 获取当前配置serverID和channelID是不是当前界面是一样的 + // 获取当前配置serverID和channelId是不是当前界面是一样的 await this.InitData(); let url = discordW.webContents.getURL(); const regex = /\/channels\/(\d+)\/(\d+)/; const match = url.match(regex); - let serviceID = null; - let channelID = null; + let serviceId = null; + let channelId = null; if (match && match[1] && match[2]) { - serviceID = match[1]; - channelID = match[2]; + serviceId = match[1]; + channelId = match[2]; } - if (!(serviceID && channelID && this.mj_config.serviceID === serviceID && this.mj_config.channelID === channelID)) { + if (!(serviceId && + channelId && + this.mj_config.browserSetting.serviceId === serviceId && + this.mj_config.browserSetting.channelId === channelId)) { // 重新加载url // 重新拼接url - await discordW.webContents.loadURL(`https://discord.com/channels/${this.mj_config.serviceID}/${this.mj_config.channelID}`) + await discordW.webContents.loadURL(`https://discord.com/channels/${this.mj_config.browserSetting.serviceId}/${this.mj_config.browserSetting.channelId}`) // 等待界面加载完毕 } return discordW; diff --git a/src/main/func.js b/src/main/func.js index 4592d4d..e16cc4d 100644 --- a/src/main/func.js +++ b/src/main/func.js @@ -879,6 +879,7 @@ async function DeleteImageTaskList(value) { async function GetMachineId() { try { let id = await machineId(true); + global.machineId = id; return { code: 1, value: id diff --git a/src/main/index.js b/src/main/index.js index 2a421da..20312f3 100644 --- a/src/main/index.js +++ b/src/main/index.js @@ -13,9 +13,10 @@ import { func } from './func.js' import { AsyncQueue } from "./quene.js" import { DEFINE_STRING } from '../define/define_string.js' import { Tools } from './tools.js' -import { ImageGenerate } from './backPrompt/imageGenerate.js' +import { ImageGenerate } from './ReverseManage/imageGenerate.js' import { Setting } from './setting/setting.js' import { has, isEmpty } from 'lodash' +import { AutoSyncMJConfig2210 } from './setting/autoSync.js' // ipc import { DiscordIpc, RemoveDiscordIpc } from './IPCEvent/discordIpc.js' @@ -33,7 +34,6 @@ async function InitData(gl) { gl.config = res; gl.requestQuene = new AsyncQueue(gl, res.task_number); gl.fileQueue = new AsyncQueue(gl, 1); - gl.logger = new Logger(define.logger_path); return res; } @@ -148,7 +148,9 @@ app.whenReady().then(async () => { optimizer.watchWindowShortcuts(window) }) - // + global.logger = new Logger(define.logger_path); + // 同步数据 + await AutoSyncMJConfig2210(); global.newWindow = []; mainWindow = createWindow('ShowMessage', null) @@ -399,8 +401,6 @@ ipcMain.handle(DEFINE_STRING.GET_PERMISSION, async (event) => { } }) -// 试用文件资源打开指定的文件夹 -ipcMain.on(DEFINE_STRING.OPEN_FOLDER, (event, value) => shell.openPath(path.join(global.config.project_path, "tmp/" + value))); // 监听字幕的保存 ipcMain.handle(DEFINE_STRING.SAVE_NEW_WORD, async (event, value) => { diff --git a/src/main/logger.js b/src/main/logger.js index 6224f24..82bf55f 100644 --- a/src/main/logger.js +++ b/src/main/logger.js @@ -10,7 +10,7 @@ export class Logger { level: 'info', format: winston.format.combine( winston.format.timestamp(), - winston.format.printf(info => `${info.timestamp} [${info.level.toUpperCase()}] [${info.service}] ${info.message}`) + winston.format.printf(info => `${(new Date()).toLocaleString()} [${info.level.toUpperCase()}] [${info.service}] ${info.message}`) ), transports: [ new DailyRotateFile({ diff --git a/src/main/setting/autoSync.js b/src/main/setting/autoSync.js new file mode 100644 index 0000000..601315d --- /dev/null +++ b/src/main/setting/autoSync.js @@ -0,0 +1,138 @@ +import fs from 'fs'; +import { version } from '../../../package.json' +import { define } from '../../define/define'; +const fspromises = fs.promises; +import { MJSettingService } from '../../define/db/service/SoftWare/mjSettingService'; +import { isEmpty } from 'lodash'; +import { SoftwareService } from '../../define/db/service/SoftWare/softwareService'; + +//#region 2.2.10 版本 自动同步数据 + +/** + * 自动同步MJ配置数据 + */ + +export async function AutoSyncMJConfig2210() { + try { + // 判断版本 + if (version != '2.2.10') { + return + } + + // 同步MJ的配置到服务器中 + let mjConfigJson = JSON.parse(await fspromises.readFile(define.img_base, 'utf-8')); + // 开始同步APIMJsetting + let _mjSettingService = await MJSettingService.getInstance(); + + if (!mjConfigJson.mj_config) { + return; + } + + // 判断数据库中有没有API数据 + let dbApiSetting = _mjSettingService.GetAPIMjSetting(null); + if (dbApiSetting.code == 1 && dbApiSetting.data.length <= 0) { + // 同步API请求配置 + if (mjConfigJson.mj_config.mj_api_url && + mjConfigJson.mj_config.mj_speed && + mjConfigJson.mj_config.api_key) { + let apiSetting = { + mjApiUrl: mjConfigJson.mj_config.mj_api_url, + mjSpeed: mjConfigJson.mj_config.mj_speed, + apiKey: mjConfigJson.mj_config.api_key + }; + let res = _mjSettingService.AddAPIMjSetting(apiSetting); + if (res.code == 1) { + global.logger.info("AutoSyncMJConfig2210", '自动同步MJ API 配置数据成功'); + } else { + global.logger.error("AutoSyncMJConfig2210", '自动同步MJ API 配置数据失败,错误信息如下:' + '\n' + res.message); + } + } + } + + // 判断数据库中是不是存在浏览器配置数据,不存在同步 + let dbBrowserSetting = _mjSettingService.GetBrowserMJSetting(null); + if (dbBrowserSetting.code == 1 && dbBrowserSetting.data.length <= 0) { + // 同步浏览器配置,判断数据是不是存在 + if (isEmpty(mjConfigJson.mj_config.serviceID) || + isEmpty(mjConfigJson.mj_config.channelID) || + isEmpty(mjConfigJson.mj_config.token) || + (!mjConfigJson.mj_config.userAgent || + isEmpty(mjConfigJson.mj_config.userAgent) || + isEmpty(mjConfigJson.mj_config.userAgent.userAgent)) + ) { + return; + } + + // 开始添加浏览器配置 + let browserSetting = { + serviceId: mjConfigJson.mj_config.serviceID, + channelId: mjConfigJson.mj_config.channelID, + token: mjConfigJson.mj_config.token, + userAgent: mjConfigJson.mj_config.userAgent.userAgent + }; + let res = _mjSettingService.AddBrowserMJSetting(browserSetting); + if (res.code == 1) { + global.logger.info("AutoSyncMJConfig2210", '自动同步MJ 浏览器配置数据成功'); + } else { + global.logger.error("AutoSyncMJConfig2210", '自动同步MJ 浏览器配置数据失败,错误信息如下:' + '\n' + res.message); + } + } + + // 判断基础数据,不存在同步 + let mjSetting = _mjSettingService.GetMjSetting(null); + if (mjSetting.code == 1 && mjSetting.data.length <= 0) { + //判断数据然后选择同步 + if (isEmpty(mjConfigJson.mj_config.request_model) || + isEmpty(mjConfigJson.mj_config.select_robot) || + isEmpty(mjConfigJson.mj_config.image_scale) || + isEmpty(mjConfigJson.mj_config.image_model) || + isEmpty(mjConfigJson.mj_config.image_suffix) + ) { + return; + } + + // 开始添加基础配置 + let mjSettingData = { + requestModel: mjConfigJson.mj_config.request_model, + selectRobot: mjConfigJson.mj_config.select_robot, + imageScale: mjConfigJson.mj_config.image_scale, + imageModel: mjConfigJson.mj_config.image_model, + imageSuffix: mjConfigJson.mj_config.image_suffix, + taskCount: mjConfigJson.mj_config.task_count ? mjConfigJson.mj_config.task_count : 3, + spaceTime: mjConfigJson.mj_config.space_time ? mjConfigJson.mj_config.space_time : 5, + }; + let res = _mjSettingService.AddMJSetting(mjSettingData); + if (res.code == 1) { + global.logger.info("AutoSyncMJConfig2210", '自动同步MJ 基础配置数据成功'); + } else { + global.logger.error("AutoSyncMJConfig2210", '自动同步MJ 基础配置数据失败,错误信息如下:' + '\n' + res.message); + } + } + + // 初始化默认数据 + let _softwareService = await SoftwareService.getInstance(); + let softs = await _softwareService.GetSoftwareData(null); + if (softs.code == 1 && softs.data.length <= 0) { + // 添加 + let softData = { + theme: "light", + reverse_display_show: false, + reverse_show_book_striped: false, + reverse_data_table_size: "samll", + } + let res = await _softwareService.AddSfotware(softData); + if (res.code == 0) { + throw new Error(res.message) + } + + global.logger.info("AutoSyncMJConfig2210", '自动同步软件配置数据成功'); + + } + + return mjConfigJson; + } catch (error) { + // 同步数据不报错,只添加日志 + global.logger.error("AutoSyncMJConfig2210", '自动同步MJ配置数据失败,错误信息如下:' + '\n' + error.toString()); + } +} +//#endregion diff --git a/src/main/setting/basicSetting.js b/src/main/setting/basicSetting.js new file mode 100644 index 0000000..1d24dd6 --- /dev/null +++ b/src/main/setting/basicSetting.js @@ -0,0 +1,67 @@ +import SoftwareService from "../../define/db/service/SoftWare/softwareService"; +import { ComponentSize } from "../../define/enum/softwareEnum"; +import { errorMessage, successMessage } from "../generalTools"; + + +export class BasicSetting { + constructor() { + } + + // 初始化数据 + async init() { + this.setting = await SoftwareService.getInstance(); + } + + /** + * 获取修改尺寸的下拉菜单的尺寸 + * @returns + */ + GetComponentSize() { + return successMessage([ + { + value: ComponentSize.TINY, + key: ComponentSize.TINY, + label: "极小" + }, { + key: ComponentSize.SMALL, + value: ComponentSize.SMALL, + label: "小" + }, { + value: ComponentSize.MEDIUM, + key: ComponentSize.MEDIUM, + label: "中" + }, { + value: ComponentSize.LARGE, + key: ComponentSize.LARGE, + label: "大" + } + ], "选择尺寸的下拉菜单消息", 'BasicSetting_GetComponentSize') + } + + // 获取基础配置信息 + async GetSoftwareSetting() { + try { + await this.init() + let res = await this.setting.GetSoftwareData(); + return res; + } catch (error) { + return errorMessage(error.message, 'BasicSetting_GetSoftwareSetting'); + } + } + + /** + * 修改软件设置的所有的数据,直接修改全部的数据 + * @param {*} paramms + * @returns + */ + + async SaveSoftWareSetting(paramms) { + try { + await this.init() + let res = await this.setting.UpdateSoftware(paramms); + return res; + } catch (error) { + return errorMessage(error.message, 'BasicSetting_SaveSoftWareSetting'); + } + } +} diff --git a/src/main/setting/bookSetting.js b/src/main/setting/bookSetting.js new file mode 100644 index 0000000..89b52a3 --- /dev/null +++ b/src/main/setting/bookSetting.js @@ -0,0 +1,5 @@ + +export class BookSetting { + constructor() { + } +} \ No newline at end of file diff --git a/src/main/setting/mjSetting.js b/src/main/setting/mjSetting.js new file mode 100644 index 0000000..16126aa --- /dev/null +++ b/src/main/setting/mjSetting.js @@ -0,0 +1,155 @@ +import axios from 'axios'; +import { MJSettingService } from '../../define/db/service/SoftWare/mjSettingService' +import { define } from '../../define/define'; +import { errorMessage, successMessage } from '../generalTools'; + +export class MJSetting { + constructor() { + } + + /** + * 获取MJ的基础设置数据 + */ + async GetMJSetting(mjSettingQuery) { + try { + let _mjSetting = await MJSettingService.getInstance() + let res = _mjSetting.GetMjSetting(mjSettingQuery); + return res + } catch (error) { + return errorMessage("获取MJ的基础配置错误,错误信息如下:" + error.toString(), "MJSetting_GetMJSetting"); + } + } + + /** + * 保存MJ的基础设置 + * @param {*} mjSetting 保存的数据 + */ + async UpdateMJSetting(mjSetting) { + try { + let _mjSetting = await MJSettingService.getInstance() + let res = _mjSetting.UpdateMJSetting(mjSetting); + return res + + } catch (error) { + return errorMessage("保存MJ的基础配置错误,错误信息如下:" + error.toString(), "MJSetting_UpdateMJSetting"); + } + } + + /** + * 获取MJ配置的所有数据 + */ + async GetMJSettingTreeData() { + try { + let _mjSetting = await MJSettingService.getInstance() + let res = _mjSetting.GetMJSettingTreeData(); + return res + } catch (error) { + return errorMessage("获取MJ配置错误,详细错误信息如下:" + error.toString(), 'MJSetting_GetMJSettingTreeData'); + } + } + + /** + * 保存MJ设置的所有数据 + * @param {*} mjSetting + */ + async SaveMJSettingTreeData(mjSetting) { + try { + let _mjSetting = await MJSettingService.getInstance() + let res = _mjSetting.SaveMJSettingTreeData(mjSetting); + return res + } catch (error) { + return errorMessage("保存MJ配置错误,详细错误信息如下:" + error.toString(), 'MJSetting_SaveMJSettingTreeData'); + } + } + /** + * 同步MJ代理模式账号信息 + * @param {*} value + * @returns + */ + async MjRemoteAccountSync() { + try { + // 获取账号数据 + let _mjSettingService = await MJSettingService.getInstance() + let remoteMjSettings = _mjSettingService.GetRemoteMJSettings(null); + if (remoteMjSettings.data.length <= 0) { + throw new Error("没有找到保存的数据,请先保存") + } + + let remoteMjSetting = remoteMjSettings.data[0] + // 判断是不是同步过,就是有没有accountId + // 判断有没有accountId + if (remoteMjSetting.accountId) { + // 查找是不是有 + let accountRes = await axios.get(define.remotemj_api + `mj/account/${remoteMjSetting.accountId}/fetch`, { + headers: { + "mj-api-secret": define.API + } + }); + console.log(accountRes) + // 没有找到账号信息,重新添加 + if (accountRes.status == 200 && accountRes.data == "") { + // 添加账号 + // 找不到的话,直接添加账号 + let accountRes = await axios.post(define.remotemj_api + `mj/account/create`, remoteMjSetting, { + headers: { + "mj-api-secret": define.API + } + }); + console.log(accountRes); + + if (accountRes.data.code != 1) { + throw new Error(accountRes.data.description); + } + + // 添加成功,修改数据,将数据返回 + let accountId = accountRes.data.result; + remoteMjSetting.accountId = accountId; + let save_res = _mjSettingService.UpdateRemoteMjSetting(remoteMjSetting); + if (save_res.code != 1) { + throw new Error(save_res.message) + } + return successMessage(remoteMjSetting, "MJ新增账号同步成功", "MJSetting_MjRemoteAccountSync") + } else { + // 能找到的话,要更新一下账号信息,并重连 + remoteMjSetting["weight"] = 1 + let accountRes = await axios.put(define.remotemj_api + `mj/account/${remoteMjSetting.accountId}/update-reconnect`, remoteMjSetting, { + headers: { + "mj-api-secret": define.API + } + }); + console.log(accountRes) + if (accountRes.data.code == 0) { + throw new Error(accountRes.description) + } + return successMessage(remoteMjSetting, "MJ账号同步成功", "MJSetting_MjRemoteAccountSync") + } + } else { + // 没有accountId,直接添加 + // 添加账号 + let accountRes = await axios.post(define.remotemj_api + `mj/account/create`, remoteMjSetting, { + headers: { + "mj-api-secret": define.API + } + }); + console.log(accountRes); + + if (accountRes.data.code != 1) { + throw new Error(accountRes.data.description); + } + + // 添加成功,修改数据,将数据返回 + let accountId = accountRes.data.result; + remoteMjSetting.accountId = accountId; + let save_res = _mjSettingService.UpdateRemoteMjSetting(remoteMjSetting); + if (save_res.code != 1) { + throw new Error(save_res.message) + } + return successMessage(remoteMjSetting, "MJ账号同步成功", "MJSetting_MjRemoteAccountSync") + } + + + } catch (error) { + return errorMessage("MJ代理模式账号同步错误,详细错误信息如下:" + error.toString(), 'MJSetting_MjRemoteAccountSync'); + } + } +} \ No newline at end of file diff --git a/src/main/setting/setting.js b/src/main/setting/setting.js index 2bf2a9d..e16a7ef 100644 --- a/src/main/setting/setting.js +++ b/src/main/setting/setting.js @@ -8,6 +8,7 @@ import { ClipSetting } from "../../define/setting/clipSetting"; import { ImageSetting } from "../../define/setting/imageSetting"; import { DEFINE_STRING } from "../../define/define_string"; import { TagDefine } from "../../define/tagDefine"; +import { errorMessage } from "../generalTools"; let tagDefine = new TagDefine(global); export class Setting { @@ -271,6 +272,8 @@ export class Setting { let res = await axios.post('http://api.yu-zhile.com/GetMachineStatus', { machineId: value }) + + // let res = await axios.get('http://lapi.laitool.cn/api/Machine/GetMachineStatus?machineId=' + value); if (res.status != 200) { throw new Error("请求错误"); } @@ -340,6 +343,5 @@ export class Setting { return ImageSetting.SaveDefineConfigJsonByProperty(value); } - //#endregion } \ No newline at end of file diff --git a/src/preload/book.js b/src/preload/book.js new file mode 100644 index 0000000..6055ea0 --- /dev/null +++ b/src/preload/book.js @@ -0,0 +1,28 @@ +import { ipcRenderer } from "electron" +import { DEFINE_STRING } from "../define/define_string" + + +const book = { + // 获取小说操作类型(原创/SD反推/MJ反推) + GetBookType: async () => await ipcRenderer.invoke(DEFINE_STRING.BOOK.GET_BOOK_TYPE), + + // 新增或者是修改小说数据 + AddOrModifyBook: async (book) => await ipcRenderer.invoke(DEFINE_STRING.BOOK.ADD_OR_MODIFY_BOOK, book), + + + //#region 一键反推 + // 获取小说数据(通过传递的参数进行筛选) + GetBookData: async (bookQuery) => await ipcRenderer.invoke(DEFINE_STRING.BOOK.GET_BOOK_DATA, bookQuery), + + // 获取小说的任务列表(批次) + GetBookTaskData: async (bookTaskCondition) => await ipcRenderer.invoke(DEFINE_STRING.BOOK.GET_BOOK_TASK_DATA, bookTaskCondition), + + // 获取小说的分镜 + GetFrameData: async (bookId) => await ipcRenderer.invoke(DEFINE_STRING.BOOK.GET_FRAME_DATA, bookId), + + //#endregion + +} +export { + book +} \ No newline at end of file diff --git a/src/preload/index.js b/src/preload/index.js index c2afc12..a47ddaf 100644 --- a/src/preload/index.js +++ b/src/preload/index.js @@ -8,6 +8,7 @@ import { img } from './img.js'; import { system } from './system.js'; import { setting } from './setting.js' import { prompt } from './prompt.js'; +import { book } from './book.js' // Custom APIs for renderer let events = []; @@ -378,8 +379,6 @@ const api = { SaveTrialEndTime: (value) => ipcRenderer.send(DEFINE_STRING.SAVE_TRIAL_END_TIME, value), // 打开购买GPT地址 openGptBuyUrl: (value) => ipcRenderer.send(DEFINE_STRING.OPEN_GPT_BUY_URL, value), - // 打开指定的文件夹 - OpenFolder: (value) => ipcRenderer.send(DEFINE_STRING.OPEN_FOLDER, value), // 退出软件 QuitApp: () => ipcRenderer.send(DEFINE_STRING.QUIT_APP), // 获取当前的生图方式,包含sd,mj,d3等 @@ -413,7 +412,7 @@ const api = { if (process.contextIsolated) { try { - + contextBridge.exposeInMainWorld('electron', electronAPI) contextBridge.exposeInMainWorld('api', api) contextBridge.exposeInMainWorld('mj', mj) @@ -423,6 +422,7 @@ if (process.contextIsolated) { contextBridge.exposeInMainWorld("system", system) contextBridge.exposeInMainWorld("setting", setting) contextBridge.exposeInMainWorld("pmpt", prompt) + contextBridge.exposeInMainWorld("book", book) contextBridge.exposeInMainWorld('darkMode', { toggle: (value) => ipcRenderer.invoke('dark-mode:toggle', value), }) @@ -439,5 +439,6 @@ if (process.contextIsolated) { window.system = system; window.setting = setting; window.pmpt = prompt; + window.book = book; } diff --git a/src/preload/prompt.js b/src/preload/prompt.js index 36770e2..0837918 100644 --- a/src/preload/prompt.js +++ b/src/preload/prompt.js @@ -10,7 +10,10 @@ const prompt = { SavePromptSort: async (value, callback) => callback(await ipcRenderer.invoke(DEFINE_STRING.PROMPT.SAVE_PROMPT_SORT_DATA, value)), // 获取提示词排序数据 - GetPromptSort: async (callback) => callback(await ipcRenderer.invoke(DEFINE_STRING.PROMPT.GET_PROMPT_SORT_DATA)) + GetPromptSort: async (callback) => callback(await ipcRenderer.invoke(DEFINE_STRING.PROMPT.GET_PROMPT_SORT_DATA)), + + // 获取提示词文件数据(txt,指定路径) + OpenPromptFileTxt: async (value, callback) => callback(await ipcRenderer.invoke(DEFINE_STRING.PROMPT.OPEN_PROMPT_FILE_TXT, value)), } export { prompt diff --git a/src/preload/setting.js b/src/preload/setting.js index d79a08d..7045fab 100644 --- a/src/preload/setting.js +++ b/src/preload/setting.js @@ -11,6 +11,34 @@ const setting = { // 删除动态配置的的指定主分类,指定的属性的数据 DeleteDataByTypeAndProperty: async (value, callback) => callback(await ipcRenderer.invoke(DEFINE_STRING.SETTING.DELETE_DATA_BY_TYPE_AND_PROPERTY, value)), + + // 返回组件尺寸的大小的数据(通用) + GetComponentSize: async () => await ipcRenderer.invoke(DEFINE_STRING.SETTING.GET_COMPONENT_SIZE), + + // 获取软件的基础设置(初始的时候执行一次) + GetSoftwareSetting: async () => await ipcRenderer.invoke(DEFINE_STRING.SETTING.GET_SOFTWARE_SETTING), + + // 保存软件的基础设置 + SaveSoftWareSetting: async (value) => await ipcRenderer.invoke(DEFINE_STRING.SETTING.SAVE_SOFT_WARE_SETTING, value), + + //#region MJ的设置 + + // 获取MJ的基础设置数据 + GetMjSetting: async (value = null) => await ipcRenderer.invoke(DEFINE_STRING.SETTING.GET_MJ_SETTING, value), + + // 保存MJ的基础设置 + UpdateMJSetting: async (value) => await ipcRenderer.invoke(DEFINE_STRING.SETTING.UPDATE_MJ_SETTING, value), + + // 获取MJ的所有设置 + GetMJSettingTreeData: async () => await ipcRenderer.invoke(DEFINE_STRING.SETTING.GET_MJ_SETTING_TREE_DATA), + + // 保存MJ的所有设置 + SaveMJSettingTreeData: async (value) => await ipcRenderer.invoke(DEFINE_STRING.SETTING.SAVE_MJ_SETTING_TREE_DATA, value), + + // MJ代理模式账号同步 + MjRemoteAccountSync: async () => await ipcRenderer.invoke(DEFINE_STRING.SETTING.MJ_REMOTE_ACCOUNT_SYNC), + + //#endregion } export { setting diff --git a/src/preload/system.js b/src/preload/system.js index 56916ec..d75f728 100644 --- a/src/preload/system.js +++ b/src/preload/system.js @@ -5,6 +5,9 @@ import { DEFINE_STRING } from "../define/define_string" const system = { // 打开指定的文件 OpenFile: async (value, callback) => callback(ipcRenderer.send(DEFINE_STRING.SYSTEM.OPEN_FILE, value)), + + // 打开指定的文件夹 + OpenFolder: (value) => ipcRenderer.invoke(DEFINE_STRING.OPEN_FOLDER, value), } export { system diff --git a/src/renderer/src/App.vue b/src/renderer/src/App.vue index 91a7b11..bdfa750 100644 --- a/src/renderer/src/App.vue +++ b/src/renderer/src/App.vue @@ -1,5 +1,8 @@ diff --git a/src/renderer/src/components/Original/Components/ImportWordAndSrt.vue b/src/renderer/src/components/Original/Components/ImportWordAndSrt.vue index 220744e..0dd14b5 100644 --- a/src/renderer/src/components/Original/Components/ImportWordAndSrt.vue +++ b/src/renderer/src/components/Original/Components/ImportWordAndSrt.vue @@ -28,10 +28,11 @@ diff --git a/src/renderer/src/components/ReverseManage/Components/BookListAction.vue b/src/renderer/src/components/ReverseManage/Components/BookListAction.vue new file mode 100644 index 0000000..17e2ea6 --- /dev/null +++ b/src/renderer/src/components/ReverseManage/Components/BookListAction.vue @@ -0,0 +1,89 @@ + + + diff --git a/src/renderer/src/components/ReverseManage/Components/ManageBookButton.vue b/src/renderer/src/components/ReverseManage/Components/ManageBookButton.vue new file mode 100644 index 0000000..e8e1621 --- /dev/null +++ b/src/renderer/src/components/ReverseManage/Components/ManageBookButton.vue @@ -0,0 +1,146 @@ + + + diff --git a/src/renderer/src/components/ReverseManage/Components/ManageBookDetailButton.vue b/src/renderer/src/components/ReverseManage/Components/ManageBookDetailButton.vue new file mode 100644 index 0000000..5d31469 --- /dev/null +++ b/src/renderer/src/components/ReverseManage/Components/ManageBookDetailButton.vue @@ -0,0 +1,60 @@ + + + diff --git a/src/renderer/src/components/ReverseManage/Components/ManageBookReverseTable.vue b/src/renderer/src/components/ReverseManage/Components/ManageBookReverseTable.vue new file mode 100644 index 0000000..61900d3 --- /dev/null +++ b/src/renderer/src/components/ReverseManage/Components/ManageBookReverseTable.vue @@ -0,0 +1,18 @@ + + + diff --git a/src/renderer/src/components/ReverseManage/Components/ManageBookShowLogger.vue b/src/renderer/src/components/ReverseManage/Components/ManageBookShowLogger.vue new file mode 100644 index 0000000..796d427 --- /dev/null +++ b/src/renderer/src/components/ReverseManage/Components/ManageBookShowLogger.vue @@ -0,0 +1,87 @@ + + + diff --git a/src/renderer/src/components/ReverseManage/ManageBook.vue b/src/renderer/src/components/ReverseManage/ManageBook.vue new file mode 100644 index 0000000..e994600 --- /dev/null +++ b/src/renderer/src/components/ReverseManage/ManageBook.vue @@ -0,0 +1,207 @@ + + + diff --git a/src/renderer/src/components/ReverseManage/ManageBookDetail.vue b/src/renderer/src/components/ReverseManage/ManageBookDetail.vue new file mode 100644 index 0000000..78c473c --- /dev/null +++ b/src/renderer/src/components/ReverseManage/ManageBookDetail.vue @@ -0,0 +1,37 @@ + + + diff --git a/src/renderer/src/components/ReverseManage/ManageBookTask.vue b/src/renderer/src/components/ReverseManage/ManageBookTask.vue new file mode 100644 index 0000000..ece105d --- /dev/null +++ b/src/renderer/src/components/ReverseManage/ManageBookTask.vue @@ -0,0 +1,21 @@ + + + diff --git a/src/renderer/src/components/ReverseManage/ReverseManage.vue b/src/renderer/src/components/ReverseManage/ReverseManage.vue new file mode 100644 index 0000000..cddbfeb --- /dev/null +++ b/src/renderer/src/components/ReverseManage/ReverseManage.vue @@ -0,0 +1,48 @@ + + + diff --git a/src/renderer/src/components/Setting/MJSetting.vue b/src/renderer/src/components/Setting/MJSetting.vue index 41279b7..629f8ec 100644 --- a/src/renderer/src/components/Setting/MJSetting.vue +++ b/src/renderer/src/components/Setting/MJSetting.vue @@ -1,153 +1,271 @@