V 2.2.10 新增MJ的代理模式
This commit is contained in:
parent
79a1929e79
commit
bac97bc41c
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,6 +1,7 @@
|
||||
node_modules
|
||||
dist
|
||||
out
|
||||
project
|
||||
resources/scripts/build*
|
||||
resources/scripts/dist
|
||||
resources/scripts/model
|
||||
|
||||
BIN
default.realm
Normal file
BIN
default.realm
Normal file
Binary file not shown.
BIN
default.realm.lock
Normal file
BIN
default.realm.lock
Normal file
Binary file not shown.
264
package-lock.json
generated
264
package-lock.json
generated
@ -6,7 +6,7 @@
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "laitool",
|
||||
"version": "2.2.8",
|
||||
"version": "2.2.9",
|
||||
"hasInstallScript": true,
|
||||
"dependencies": {
|
||||
"@alicloud/alimt20181012": "^1.2.0",
|
||||
@ -17,6 +17,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",
|
||||
@ -36,6 +37,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",
|
||||
@ -57,7 +59,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",
|
||||
@ -2084,6 +2086,14 @@
|
||||
"version": "1.1.0",
|
||||
"license": "BSD-3-Clause"
|
||||
},
|
||||
"node_modules/@realm/fetch": {
|
||||
"version": "0.1.1",
|
||||
"resolved": "https://registry.npmmirror.com/@realm/fetch/-/fetch-0.1.1.tgz",
|
||||
"integrity": "sha512-hkTprw79RXGv54Je0DrjpQPLaz4QID2dO3FmthAQQWAkqwyrqMzrCGzJzLlmTKWZFsgLrN8KQyNewod27P+nJg==",
|
||||
"engines": {
|
||||
"node": ">=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,
|
||||
|
||||
12
package.json
12
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"
|
||||
|
||||
@ -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])
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
resources/scripts/db/book.realm
Normal file
BIN
resources/scripts/db/book.realm
Normal file
Binary file not shown.
BIN
resources/scripts/db/book.realm.lock
Normal file
BIN
resources/scripts/db/book.realm.lock
Normal file
Binary file not shown.
BIN
resources/scripts/db/software.realm
Normal file
BIN
resources/scripts/db/software.realm
Normal file
Binary file not shown.
BIN
resources/scripts/db/software.realm.lock
Normal file
BIN
resources/scripts/db/software.realm.lock
Normal file
Binary file not shown.
@ -6,6 +6,7 @@ from scenedetect.stats_manager import StatsManager
|
||||
from scenedetect.detectors.content_detector import ContentDetector
|
||||
import os
|
||||
import sys
|
||||
import json
|
||||
import subprocess
|
||||
from huggingface_hub import hf_hub_download
|
||||
from faster_whisper import WhisperModel
|
||||
@ -228,6 +229,22 @@ def GetText(out_folder, mp3_list):
|
||||
sys.stdout.flush()
|
||||
|
||||
|
||||
def get_fram(video_path, out_path, sensitivity):
|
||||
try:
|
||||
shijian_list = find_scenes(video_path, sensitivity) # 多组时间列表
|
||||
print("总共有%s个场景" % str(len(shijian_list)))
|
||||
print("开始输出json")
|
||||
print(shijian_list)
|
||||
# 将数组中的消息写道json文件中
|
||||
with open(out_path, "w") as file:
|
||||
# 将数组写入到指定的json文件
|
||||
json.dump(shijian_list, file)
|
||||
print("输出完成")
|
||||
except Exception as e:
|
||||
print("出现错误" + str(e))
|
||||
exit(0)
|
||||
|
||||
|
||||
def init(video_path, video_out_folder, image_out_folder, sensitivity, gpu_type):
|
||||
v_l = ClipVideo(
|
||||
video_path, video_out_folder, image_out_folder, sensitivity, gpu_type
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
|
||||
import { basicApi } from "./apiBasic";
|
||||
import { Tools } from "../main/tools";
|
||||
import { define } from "../define/define";
|
||||
|
||||
export class DiscordAPI {
|
||||
constructor() {
|
||||
@ -19,6 +20,11 @@ export class DiscordAPI {
|
||||
let headers = {
|
||||
"Authorization": key
|
||||
}
|
||||
if (url.includes(define.remotemj_api)) {
|
||||
headers = {
|
||||
"mj-api-secret": define.API
|
||||
}
|
||||
}
|
||||
res = await basicApi.get(url, headers);
|
||||
|
||||
let progress = res.data.progress && res.data.progress.length > 0 ? parseInt(res.data.progress.slice(0, -1)) : 0;
|
||||
|
||||
@ -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 不是
|
||||
|
||||
28
src/define/db/model/Book/BookBackTaskListModel.ts
Normal file
28
src/define/db/model/Book/BookBackTaskListModel.ts
Normal file
@ -0,0 +1,28 @@
|
||||
import Realm, { ObjectSchema } from 'realm'
|
||||
import { BookBackTaskStatus, BookBackTaskType } from '../../../enum/bookEnum'
|
||||
|
||||
export class BookBackTaskList extends Realm.Object<BookBackTaskList> {
|
||||
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'
|
||||
}
|
||||
}
|
||||
37
src/define/db/model/Book/book.ts
Normal file
37
src/define/db/model/Book/book.ts
Normal file
@ -0,0 +1,37 @@
|
||||
import Realm, { ObjectSchema } from 'realm'
|
||||
import { BookType } from '../../../enum/bookEnum'
|
||||
|
||||
export class BookModel extends Realm.Object<BookModel> {
|
||||
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'
|
||||
}
|
||||
}
|
||||
43
src/define/db/model/Book/bookTask.ts
Normal file
43
src/define/db/model/Book/bookTask.ts
Normal file
@ -0,0 +1,43 @@
|
||||
import Realm, { ObjectSchema } from 'realm'
|
||||
import { BookTaskStatus, BookType } from '../../../enum/bookEnum'
|
||||
|
||||
export class BookTaskModel extends Realm.Object<BookTaskModel> {
|
||||
id: string
|
||||
no: number
|
||||
bookId: string
|
||||
name: string
|
||||
generateVideoPath: string | null
|
||||
srtPath: string | null
|
||||
audioPath: string | null
|
||||
imageFolder: string | null
|
||||
styleList: Realm.List<string> | 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'
|
||||
}
|
||||
}
|
||||
163
src/define/db/model/Book/bookTaskDetail.ts
Normal file
163
src/define/db/model/Book/bookTaskDetail.ts
Normal file
@ -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<Subtitle> {
|
||||
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<MJMessage> {
|
||||
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<WebuiConfig> {
|
||||
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<SDConfig> {
|
||||
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<BookTaskDetailModel> {
|
||||
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<Subtitle> | 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'
|
||||
}
|
||||
}
|
||||
27
src/define/db/model/SoftWare/logger.ts
Normal file
27
src/define/db/model/SoftWare/logger.ts
Normal file
@ -0,0 +1,27 @@
|
||||
import Realm, { ObjectSchema } from 'realm'
|
||||
import { LoggerStatus, LoggerType } from '../../../enum/softwareEnum'
|
||||
|
||||
export class LoggerModel extends Realm.Object<LoggerModel> {
|
||||
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'
|
||||
}
|
||||
}
|
||||
136
src/define/db/model/SoftWare/mjSetting.ts
Normal file
136
src/define/db/model/SoftWare/mjSetting.ts
Normal file
@ -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<BrowserMJModel> {
|
||||
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<RemoteMJModel> {
|
||||
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<APIMjModel> {
|
||||
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<MjSettingModel> {
|
||||
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'
|
||||
}
|
||||
}
|
||||
23
src/define/db/model/SoftWare/software.ts
Normal file
23
src/define/db/model/SoftWare/software.ts
Normal file
@ -0,0 +1,23 @@
|
||||
import Realm, { ObjectSchema } from 'realm'
|
||||
import { ComponentSize, SoftwareThemeType } from '../../../enum/softwareEnum'
|
||||
|
||||
export class SoftwareModel extends Realm.Object<SoftwareModel> {
|
||||
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'
|
||||
}
|
||||
}
|
||||
141
src/define/db/service/Book/bookBackTaskListService.ts
Normal file
141
src/define/db/service/Book/bookBackTaskListService.ts
Normal file
@ -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'
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
83
src/define/db/service/Book/bookBasic.ts
Normal file
83
src/define/db/service/Book/bookBasic.ts
Normal file
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
214
src/define/db/service/Book/bookService.ts
Normal file
214
src/define/db/service/Book/bookService.ts
Normal file
@ -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<BookModel>('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<BookModel>
|
||||
}
|
||||
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
|
||||
47
src/define/db/service/Book/bookTaskDetailService.ts
Normal file
47
src/define/db/service/Book/bookTaskDetailService.ts
Normal file
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
139
src/define/db/service/Book/bookTaskService.ts
Normal file
139
src/define/db/service/Book/bookTaskService.ts
Normal file
@ -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<BookTaskModel>('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<BookTaskModel>
|
||||
}
|
||||
|
||||
// 做一下数据转换
|
||||
// 将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
|
||||
}
|
||||
}
|
||||
}
|
||||
80
src/define/db/service/SoftWare/loggerService.ts
Normal file
80
src/define/db/service/SoftWare/loggerService.ts
Normal file
@ -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'
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
611
src/define/db/service/SoftWare/mjSettingService.ts
Normal file
611
src/define/db/service/SoftWare/mjSettingService.ts
Normal file
@ -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
|
||||
}
|
||||
133
src/define/db/service/SoftWare/softwareBasic.ts
Normal file
133
src/define/db/service/SoftWare/softwareBasic.ts
Normal file
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
78
src/define/db/service/SoftWare/softwareService.ts
Normal file
78
src/define/db/service/SoftWare/softwareService.ts
Normal file
@ -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
|
||||
36
src/define/db/service/baseService.ts
Normal file
36
src/define/db/service/baseService.ts
Normal file
@ -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()
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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
|
||||
};
|
||||
@ -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"
|
||||
}
|
||||
}
|
||||
154
src/define/enum/bookEnum.ts
Normal file
154
src/define/enum/bookEnum.ts
Normal file
@ -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'
|
||||
}
|
||||
21
src/define/enum/mjEnum.ts
Normal file
21
src/define/enum/mjEnum.ts
Normal file
@ -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'
|
||||
}
|
||||
42
src/define/enum/softwareEnum.ts
Normal file
42
src/define/enum/softwareEnum.ts
Normal file
@ -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'
|
||||
}
|
||||
@ -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: {
|
||||
|
||||
@ -96,9 +96,9 @@ export class MjSetting {
|
||||
disable: true
|
||||
},
|
||||
{
|
||||
label: "代理MJ(待开发)",
|
||||
label: "代理MJ(token)",
|
||||
value: "remote_mj",
|
||||
disable: true
|
||||
disable: false
|
||||
},
|
||||
{
|
||||
label: "浏览器模式",
|
||||
|
||||
27
src/main/IPCEvent/bookIpc.js
Normal file
27
src/main/IPCEvent/bookIpc.js
Normal file
@ -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
|
||||
|
||||
}
|
||||
@ -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() {
|
||||
|
||||
@ -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();
|
||||
}
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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
|
||||
}
|
||||
40
src/main/IPCEvent/systemIpc.js
Normal file
40
src/main/IPCEvent/systemIpc.js
Normal file
@ -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
|
||||
}
|
||||
@ -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() {
|
||||
|
||||
@ -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() {
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
63
src/main/ReverseManage/Book/BooKBasic.js
Normal file
63
src/main/ReverseManage/Book/BooKBasic.js
Normal file
@ -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
|
||||
}], '获取小说类型成功');
|
||||
}
|
||||
}
|
||||
49
src/main/ReverseManage/Book/ReverseBook.js
Normal file
49
src/main/ReverseManage/Book/ReverseBook.js
Normal file
@ -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');
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
95
src/main/Task/basicReverse.js
Normal file
95
src/main/Task/basicReverse.js
Normal file
@ -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');
|
||||
}
|
||||
}
|
||||
}
|
||||
0
src/main/Task/mjReverse.js
Normal file
0
src/main/Task/mjReverse.js
Normal file
0
src/main/Task/sdReverse.js
Normal file
0
src/main/Task/sdReverse.js
Normal file
41
src/main/Task/taskScheduler.js
Normal file
41
src/main/Task/taskScheduler.js
Normal file
@ -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');
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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({
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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) => {
|
||||
|
||||
@ -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({
|
||||
|
||||
138
src/main/setting/autoSync.js
Normal file
138
src/main/setting/autoSync.js
Normal file
@ -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
|
||||
67
src/main/setting/basicSetting.js
Normal file
67
src/main/setting/basicSetting.js
Normal file
@ -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');
|
||||
}
|
||||
}
|
||||
}
|
||||
5
src/main/setting/bookSetting.js
Normal file
5
src/main/setting/bookSetting.js
Normal file
@ -0,0 +1,5 @@
|
||||
|
||||
export class BookSetting {
|
||||
constructor() {
|
||||
}
|
||||
}
|
||||
155
src/main/setting/mjSetting.js
Normal file
155
src/main/setting/mjSetting.js
Normal file
@ -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');
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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
|
||||
}
|
||||
28
src/preload/book.js
Normal file
28
src/preload/book.js
Normal file
@ -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
|
||||
}
|
||||
@ -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等
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -1,5 +1,8 @@
|
||||
<template>
|
||||
<n-config-provider :hljs="hljs" :theme="themeData == 'dark' ? darkTheme : null">
|
||||
<n-config-provider
|
||||
:hljs="hljs"
|
||||
:theme="softwareStore.softWare.theme == 'dark' ? darkTheme : null"
|
||||
>
|
||||
<n-message-provider>
|
||||
<n-dialog-provider>
|
||||
<n-notification-provider>
|
||||
@ -21,6 +24,8 @@ import {
|
||||
darkTheme,
|
||||
NNotificationProvider
|
||||
} from 'naive-ui'
|
||||
import { useSoftwareStore } from '../../stores/software'
|
||||
|
||||
hljs.registerLanguage('javascript', javascript)
|
||||
export default defineComponent({
|
||||
components: {
|
||||
@ -30,20 +35,32 @@ export default defineComponent({
|
||||
NNotificationProvider
|
||||
},
|
||||
setup() {
|
||||
let themeData = ref('')
|
||||
let softwareStore = useSoftwareStore()
|
||||
|
||||
onMounted(() => {
|
||||
onMounted(async () => {
|
||||
window.api.getSettingDafultData(async (value) => {
|
||||
themeData.value = value.theme
|
||||
await window.darkMode.toggle(value.theme)
|
||||
})
|
||||
let software = await window.setting.GetSoftwareSetting()
|
||||
if (software.code == 0) {
|
||||
throw new Error('初始化信息错误: ' + software.message)
|
||||
}
|
||||
if (software.data == null) {
|
||||
throw new Error('初始化信息错误: 未获取到数据')
|
||||
}
|
||||
debugger
|
||||
if (software.data.length == 0) {
|
||||
throw new Error('初始化信息错误: 未获取到数据')
|
||||
}
|
||||
softwareStore.softWare = software.data[0]
|
||||
await window.darkMode.toggle(softwareStore.softWare.theme)
|
||||
})
|
||||
|
||||
return {
|
||||
javascript,
|
||||
hljs,
|
||||
darkTheme,
|
||||
themeData
|
||||
softwareStore
|
||||
}
|
||||
}
|
||||
})
|
||||
@ -51,4 +68,25 @@ export default defineComponent({
|
||||
|
||||
<style lang="less">
|
||||
@import './assets/css/styles.less';
|
||||
|
||||
/* Customize the scrollbar */
|
||||
::-webkit-scrollbar {
|
||||
width: 2px;
|
||||
height: 4px;
|
||||
}
|
||||
|
||||
/* Track */
|
||||
::-webkit-scrollbar-track {
|
||||
background: #f1f1f1;
|
||||
}
|
||||
|
||||
/* Handle */
|
||||
::-webkit-scrollbar-thumb {
|
||||
background: #ddd;
|
||||
}
|
||||
|
||||
/* Handle on hover */
|
||||
::-webkit-scrollbar-thumb:hover {
|
||||
background: #ccc;
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -1,4 +1,6 @@
|
||||
body {
|
||||
min-width: 500px;
|
||||
min-height: 500px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
font-family:
|
||||
|
||||
@ -175,7 +175,6 @@ export default defineComponent({
|
||||
*/
|
||||
async function GetVideoFile() {
|
||||
await window.api.SelectFile(['mp4'], (value) => {
|
||||
|
||||
if (value.code == 0) {
|
||||
message.error(value.message)
|
||||
return
|
||||
@ -216,7 +215,10 @@ export default defineComponent({
|
||||
}
|
||||
|
||||
function openExportFolder() {
|
||||
window.api.OpenFolder("input_crop")
|
||||
window.system.OpenFolder({
|
||||
folderPath: 'tmp/input_crop',
|
||||
baseProject: true
|
||||
})
|
||||
}
|
||||
|
||||
return {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
36
src/renderer/src/components/Components/Artplayer.vue
Normal file
36
src/renderer/src/components/Components/Artplayer.vue
Normal file
@ -0,0 +1,36 @@
|
||||
<template>
|
||||
<div ref="artRef"></div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Artplayer from 'artplayer'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
instance: null
|
||||
}
|
||||
},
|
||||
props: {
|
||||
option: {
|
||||
type: Object,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.instance = new Artplayer({
|
||||
...this.option,
|
||||
container: this.$refs.artRef
|
||||
})
|
||||
|
||||
this.$nextTick(() => {
|
||||
this.$emit('get-instance', this.instance)
|
||||
})
|
||||
},
|
||||
beforeDestroy() {
|
||||
if (this.instance && this.instance.destroy) {
|
||||
this.instance.destroy(false)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@ -20,7 +20,7 @@
|
||||
:expand-icon="expandIcon"
|
||||
/>
|
||||
</n-layout-sider>
|
||||
<n-layout-content content-style="padding:30px">
|
||||
<n-layout-content content-style="padding: 20px 5px 5px 20px; height:100%">
|
||||
<!-- <Setting></Setting> -->
|
||||
<router-view></router-view>
|
||||
</n-layout-content>
|
||||
@ -45,7 +45,13 @@ import {
|
||||
NButton
|
||||
} from 'naive-ui'
|
||||
|
||||
import { BookmarkOutline, CaretDownOutline } from '@vicons/ionicons5'
|
||||
import {
|
||||
CaretDownOutline,
|
||||
PaperPlaneOutline,
|
||||
SettingsOutline,
|
||||
DuplicateOutline,
|
||||
GridOutline
|
||||
} from '@vicons/ionicons5'
|
||||
import CheckMachineId from '../Components/CheckMachineId.vue'
|
||||
import axios from 'axios'
|
||||
import { DEFINE_STRING } from '../../../../define/define_string.js'
|
||||
@ -77,7 +83,12 @@ export default defineComponent({
|
||||
function renderMenuIcon(option) {
|
||||
if (option.key === 'sheep-man') return true
|
||||
if (option.key === 'food') return null
|
||||
return h(NIcon, null, { default: () => h(BookmarkOutline) })
|
||||
if (option.key == 'sdoriginal') return h(NIcon, null, { default: () => h(PaperPlaneOutline) })
|
||||
if (option.key == 'setting') return h(NIcon, null, { default: () => h(SettingsOutline) })
|
||||
if (option.key == 'reverse_management')
|
||||
return h(NIcon, null, { default: () => h(GridOutline) })
|
||||
if (option.key == 'backward_matrix')
|
||||
return h(NIcon, null, { default: () => h(DuplicateOutline) })
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
@ -306,6 +317,21 @@ export default defineComponent({
|
||||
]
|
||||
},
|
||||
// {
|
||||
// label: () =>
|
||||
// h(
|
||||
// RouterLink,
|
||||
// {
|
||||
// to: {
|
||||
// name: 'reverse_management'
|
||||
// }
|
||||
// },
|
||||
// {
|
||||
// default: () => '一键反推'
|
||||
// }
|
||||
// ),
|
||||
// key: 'reverse_management'
|
||||
// },
|
||||
// {
|
||||
// label: "剪辑",
|
||||
// key: "clip_options",
|
||||
// children: [
|
||||
@ -386,7 +412,8 @@ export default defineComponent({
|
||||
{
|
||||
to: {
|
||||
name: 'sd_setting'
|
||||
}
|
||||
},
|
||||
class: 'sd_setting'
|
||||
},
|
||||
{ default: () => 'SD设置' }
|
||||
),
|
||||
|
||||
@ -15,66 +15,65 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { ref, h, onMounted, defineComponent, toRaw, watch, computed } from "vue";
|
||||
import { NButton, NCheckbox, NInput, useMessage } from "naive-ui";
|
||||
import { DEFINE_STRING } from "../../../../../define/define_string";
|
||||
import { cloneDeep } from "lodash";
|
||||
import { ref, h, onMounted, defineComponent, toRaw, watch, computed } from 'vue'
|
||||
import { NButton, NCheckbox, NInput, useMessage } from 'naive-ui'
|
||||
import { DEFINE_STRING } from '../../../../../define/define_string'
|
||||
import { cloneDeep } from 'lodash'
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
NButton,
|
||||
NInput,
|
||||
NCheckbox,
|
||||
NCheckbox
|
||||
},
|
||||
props: ["type", "row", "index", "func"],
|
||||
props: ['type', 'row', 'index', 'func'],
|
||||
setup(props) {
|
||||
let message = useMessage();
|
||||
let type = ref(props.type);
|
||||
let row = ref(props.row);
|
||||
let input_status = ref("default");
|
||||
let message = useMessage()
|
||||
let type = ref(props.type)
|
||||
let row = ref(props.row)
|
||||
let input_status = ref('default')
|
||||
|
||||
// 重新计算命令
|
||||
watch(
|
||||
() => props.type,
|
||||
(newVal) => {
|
||||
type.value = newVal;
|
||||
type.value = newVal
|
||||
},
|
||||
{ deep: true }
|
||||
);
|
||||
)
|
||||
// 监听数据变化
|
||||
watch(
|
||||
() => props.row,
|
||||
(newVal) => {
|
||||
row.value = newVal;
|
||||
row.value = newVal
|
||||
},
|
||||
{ deep: true }
|
||||
);
|
||||
)
|
||||
watch(
|
||||
() => props.row.mj_message,
|
||||
(newVal) => {
|
||||
if (newVal && newVal["hasBadPrompt"]) {
|
||||
input_status.value = "error";
|
||||
if (newVal && newVal['hasBadPrompt']) {
|
||||
input_status.value = 'error'
|
||||
}
|
||||
},
|
||||
{ deep: true }
|
||||
);
|
||||
)
|
||||
|
||||
onMounted(async () => {
|
||||
if (row.value["mj_message"]?.hasBadPrompt) {
|
||||
input_status.value = "error";
|
||||
if (row.value['mj_message']?.hasBadPrompt) {
|
||||
input_status.value = 'error'
|
||||
}
|
||||
});
|
||||
})
|
||||
|
||||
async function onUpdateChecked(v) {
|
||||
|
||||
row.adetailer = v;
|
||||
row.value.adetailer = v
|
||||
}
|
||||
|
||||
return {
|
||||
type,
|
||||
row,
|
||||
onUpdateChecked,
|
||||
};
|
||||
},
|
||||
});
|
||||
onUpdateChecked
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
@ -28,10 +28,11 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { h, defineComponent, onMounted, ref, toRaw, watch } from 'vue'
|
||||
import { h, defineComponent, onMounted, ref, toRaw, watch, onUnmounted } from 'vue'
|
||||
import { NButton, NDataTable, useMessage, NInput, NImage, useDialog } from 'naive-ui'
|
||||
import { v4 as uuidv4 } from 'uuid'
|
||||
import EditWord from './EditWord.vue'
|
||||
import { checkStringValueDeleteSuffix } from '../../../../../main/generalTools'
|
||||
const buttonArr = [
|
||||
{
|
||||
title: '下对齐',
|
||||
@ -39,6 +40,7 @@ const buttonArr = [
|
||||
color: '#8a2be0'
|
||||
}
|
||||
]
|
||||
import InputDialogContent from './InputDialogContent.vue'
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
@ -53,9 +55,10 @@ export default defineComponent({
|
||||
let maxHeight = props.height - 80
|
||||
let data = ref(props.initData)
|
||||
const message = useMessage()
|
||||
let selectKey = ref([])
|
||||
let dialog = useDialog()
|
||||
let selectKey = ref([])
|
||||
let editWordRef = ref(null)
|
||||
let wenkeRef = ref(null)
|
||||
|
||||
const createColumns = ({ AlignNextWord }) => {
|
||||
return [
|
||||
@ -158,18 +161,115 @@ export default defineComponent({
|
||||
|
||||
// 设置窗体的高度
|
||||
function setHeight() {
|
||||
|
||||
let div = document.getElementById('import_word_and_srt')
|
||||
div.style.height = hh + 'px'
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
setHeight()
|
||||
|
||||
// 监听 ctrl + alt + w 键盘的按键事件
|
||||
window.addEventListener('keydown', ImportWenKeSrt)
|
||||
})
|
||||
|
||||
onUnmounted(() => {
|
||||
window.removeEventListener('keydown', ImportWenKeSrt)
|
||||
})
|
||||
|
||||
/**
|
||||
* 导入文刻软件里面的srt
|
||||
*/
|
||||
async function ImportWenKeSrt(e) {
|
||||
if (!(e.ctrlKey && e.altKey && e.key == 'k')) {
|
||||
return
|
||||
}
|
||||
let dialogWidth = 400
|
||||
let dialogHeight = 150
|
||||
dialog.create({
|
||||
name: 'importWenkeWord',
|
||||
title: '导入外部对齐文件',
|
||||
showIcon: false,
|
||||
closeOnEsc: false,
|
||||
content: () =>
|
||||
h(InputDialogContent, {
|
||||
ref: wenkeRef,
|
||||
initData: null,
|
||||
placeholder: '请导入外部对齐文件'
|
||||
}),
|
||||
style: `width : ${dialogWidth}px; min-height : ${dialogHeight}px`,
|
||||
maskClosable: false,
|
||||
onClose: async () => {
|
||||
debugger
|
||||
console.log(wenkeRef.value.word)
|
||||
let word = wenkeRef.value.data
|
||||
if (word == null || word == '') {
|
||||
message.error('数据为空')
|
||||
return
|
||||
}
|
||||
word = JSON.parse(word)
|
||||
// 将文案数据写入到本地
|
||||
data.value = []
|
||||
let word_arr = word.rows
|
||||
let lastId = ''
|
||||
let end_word = []
|
||||
for (let i = 0; i < word_arr.length; i++) {
|
||||
const element = word_arr[i]
|
||||
// 判断下面的text是不是存在,存在的话,获取数据然后记录事件
|
||||
let row_text = ''
|
||||
let start_time = 0
|
||||
let end_time = 0
|
||||
let subValue = []
|
||||
if (element.texts) {
|
||||
for (let j = 0; j < element.texts.length; j++) {
|
||||
const text = element.texts[j]
|
||||
row_text += text.text + ','
|
||||
if (j == 0) {
|
||||
start_time = text.start
|
||||
}
|
||||
if (j == element.texts.length - 1) {
|
||||
end_time = text.start + text.duration
|
||||
}
|
||||
subValue.push({
|
||||
id: uuidv4(),
|
||||
srt_value: text.text,
|
||||
start_time: text.start / 1000,
|
||||
end_time: text.start / 1000 + text.duration / 1000
|
||||
})
|
||||
}
|
||||
}
|
||||
let id = uuidv4()
|
||||
lastId = id
|
||||
|
||||
data.value.push({
|
||||
no: i + 1,
|
||||
id: id,
|
||||
lastId: lastId,
|
||||
word: checkStringValueDeleteSuffix(row_text, ','),
|
||||
after_gpt: checkStringValueDeleteSuffix(row_text, ','),
|
||||
start_time: start_time / 1000,
|
||||
end_time: end_time / 1000,
|
||||
timeLimit: `${start_time / 1000} -- ${end_time / 1000}`,
|
||||
subValue: subValue
|
||||
})
|
||||
end_word.push(checkStringValueDeleteSuffix(row_text, ','))
|
||||
}
|
||||
|
||||
// 将文案数据写入到本地
|
||||
let local_word = end_word.filter((item) => item != '' && item != null)
|
||||
await window.api.saveWordTxt(toRaw(local_word), (value) => {
|
||||
if (value.code == 0) {
|
||||
message.error('文案写入失败' + value.message)
|
||||
return
|
||||
}
|
||||
})
|
||||
return true
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 重新计算指定索引值的时间
|
||||
* @param {data value 值的索引} index
|
||||
* @param {int} index
|
||||
*/
|
||||
function modifyTime(index) {
|
||||
let s_v = data.value[index].subValue
|
||||
@ -423,7 +523,6 @@ export default defineComponent({
|
||||
})
|
||||
return
|
||||
} else {
|
||||
|
||||
// 先保存单个文件(然后在config文件中指向对应的文件)
|
||||
await window.api.OriginalAddWebuiJson(JSON.stringify(data.value), async (value) => {
|
||||
if (value.code == 0) {
|
||||
@ -466,7 +565,6 @@ export default defineComponent({
|
||||
})
|
||||
|
||||
await window.api.ImportSrtAndGetTime([toRaw(data.value), srt_path], (value) => {
|
||||
|
||||
if (value.code == 0) {
|
||||
message.error(value.message)
|
||||
return
|
||||
@ -552,7 +650,8 @@ export default defineComponent({
|
||||
SaveCopywritingInformation,
|
||||
OpenOneDialog,
|
||||
maxHeight,
|
||||
hh
|
||||
hh,
|
||||
wenkeRef
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
@ -85,44 +85,33 @@
|
||||
size="small"
|
||||
placeholder="请选择"
|
||||
:options="request_model_options"
|
||||
v-model:value="mjSetting.request_model"
|
||||
v-model:value="mjSetting.requestModel"
|
||||
style="width: 120px"
|
||||
>
|
||||
</n-select>
|
||||
</div>
|
||||
<div style="margin-left: 10px; display: flex; flex-wrap: wrap; width: 80px">
|
||||
<div style="margin-bottom: 3px">出图机器人</div>
|
||||
<n-select
|
||||
size="small"
|
||||
placeholder="请选择"
|
||||
:options="select_robot_options"
|
||||
v-model:value="mjSetting.select_robot"
|
||||
style="width: 80px"
|
||||
>
|
||||
</n-select>
|
||||
</div>
|
||||
|
||||
<div style="margin-left: 10px; display: flex; flex-wrap: wrap; width: 100px">
|
||||
<div style="margin-bottom: 3px">出图速度模式</div>
|
||||
<n-select
|
||||
size="small"
|
||||
placeholder="请选择"
|
||||
:options="mj_speed_options"
|
||||
v-model:value="mjSetting.mj_speed"
|
||||
style="width: 100px"
|
||||
>
|
||||
</n-select>
|
||||
</div>
|
||||
|
||||
<div style="margin-left: 10px; display: flex; flex-wrap: wrap; width: 80px">
|
||||
<div style="margin-bottom: 3px">MJ并发数量</div>
|
||||
<div style="margin-bottom: 3px">MJ并发</div>
|
||||
<n-input-number
|
||||
size="small"
|
||||
style="width: 80px"
|
||||
v-model:value="mjSetting.task_count"
|
||||
v-model:value="mjSetting.taskCount"
|
||||
:show-button="false"
|
||||
:min="1"
|
||||
:max="10"
|
||||
:max="20"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div style="margin-left: 10px; display: flex; flex-wrap: wrap; width: 80px">
|
||||
<div style="margin-bottom: 3px">间隔时间</div>
|
||||
<n-input-number
|
||||
size="small"
|
||||
style="width: 80px"
|
||||
v-model:value="mjSetting.spaceTime"
|
||||
:show-button="false"
|
||||
:min="1"
|
||||
:max="30"
|
||||
/>
|
||||
</div>
|
||||
|
||||
@ -198,13 +187,11 @@ export default defineComponent({
|
||||
let character_select_model = ref(window.config.character_select_model)
|
||||
let character_select_model_options = ref([])
|
||||
let mjSetting = ref({
|
||||
select_robot: null,
|
||||
task_count: 1,
|
||||
request_model: null,
|
||||
mj_speed: 'relaxed'
|
||||
selectRobot: null,
|
||||
taskCount: 3,
|
||||
spaceTime: 1
|
||||
})
|
||||
let request_model_options = ref([])
|
||||
let select_robot_options = ref([])
|
||||
let mj_speed_options = ref([])
|
||||
|
||||
/**
|
||||
@ -248,21 +235,19 @@ export default defineComponent({
|
||||
* 初始化MJ的option
|
||||
*/
|
||||
async function InitMjOptions() {
|
||||
// 获取当前mj配置信息
|
||||
await window.api.GetDefineConfigJsonByProperty(
|
||||
JSON.stringify(['img_base', 'mj_config', false, null]),
|
||||
(value) => {
|
||||
console.log(value)
|
||||
if (value.code == 0) {
|
||||
message.error(value.message)
|
||||
return
|
||||
}
|
||||
// 判断是不是有数据
|
||||
if (value.data) {
|
||||
mjSetting.value = value.data
|
||||
}
|
||||
}
|
||||
)
|
||||
// 获取当前mj配置信息,加载基础信息
|
||||
let res = await window.setting.GetMjSetting()
|
||||
if (res.code == 0) {
|
||||
message.error(res.message)
|
||||
return
|
||||
}
|
||||
|
||||
if (res.data.length <= 0) {
|
||||
message.error('当前没有MJ配置信息,请先配置MJ信息')
|
||||
return
|
||||
}
|
||||
|
||||
mjSetting.value = Object.assign(mjSetting.value, res.data[0])
|
||||
|
||||
await window.mj.GetMJGenerateCategory((value) => {
|
||||
if (value.code == 0) {
|
||||
@ -274,16 +259,6 @@ export default defineComponent({
|
||||
mjSetting.value.request_model = request_model_options.value[0].value
|
||||
}
|
||||
})
|
||||
select_robot_options.value = [
|
||||
{
|
||||
label: 'MJ',
|
||||
value: 'mj'
|
||||
},
|
||||
{
|
||||
label: 'NIJI',
|
||||
value: 'niji'
|
||||
}
|
||||
]
|
||||
|
||||
mj_speed_options.value = [
|
||||
{
|
||||
@ -348,17 +323,11 @@ export default defineComponent({
|
||||
}
|
||||
})
|
||||
|
||||
// 保存MJ配置
|
||||
|
||||
await window.api.SaveDefineConfigJsonByProperty(
|
||||
JSON.stringify(['img_base', 'mj_config', toRaw(mjSetting.value), false]),
|
||||
(value) => {
|
||||
if (value.code == 0) {
|
||||
message.error(value.message)
|
||||
return
|
||||
}
|
||||
}
|
||||
)
|
||||
// 保存MJ的基础设置
|
||||
let saveMjRes = await window.setting.UpdateMJSetting(toRaw(mjSetting.value))
|
||||
if (saveMjRes.code == 0) {
|
||||
throw new Error(saveMjRes.message)
|
||||
}
|
||||
|
||||
message.success('保存成功')
|
||||
} catch (error) {
|
||||
@ -425,7 +394,6 @@ export default defineComponent({
|
||||
bad_prompt_ref,
|
||||
mjSetting,
|
||||
request_model_options,
|
||||
select_robot_options,
|
||||
mj_speed_options
|
||||
}
|
||||
}
|
||||
|
||||
@ -563,7 +563,7 @@ export default defineComponent({
|
||||
// 计算当前程序界面的高度,减去上下的高度,设置maxHegiht
|
||||
async function getMaxHeight() {
|
||||
let height = window.innerHeight
|
||||
maxHeight.value = height - 150
|
||||
maxHeight.value = height - 120
|
||||
}
|
||||
|
||||
// 监听程序界面的高度变化
|
||||
|
||||
@ -15,11 +15,12 @@
|
||||
|
||||
<script>
|
||||
import { ref, h, onMounted, defineComponent, onUnmounted, toRaw } from 'vue'
|
||||
import { NImage, useMessage } from 'naive-ui'
|
||||
import { NImage, useMessage, useDialog } from 'naive-ui'
|
||||
import { DEFINE_STRING } from '../../../../define/define_string'
|
||||
import MenuButton from './MenuButton.vue'
|
||||
import DataTable from './DataTable.vue'
|
||||
import { usePromptStore } from '../../../../stores/prompt'
|
||||
import InputDialogContent from './Components/InputDialogContent.vue'
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
@ -28,6 +29,7 @@ export default defineComponent({
|
||||
MenuButton
|
||||
},
|
||||
setup() {
|
||||
let dialog = useDialog()
|
||||
let promptStore = usePromptStore()
|
||||
let message = useMessage()
|
||||
let data = ref([])
|
||||
@ -35,9 +37,9 @@ export default defineComponent({
|
||||
let AnalyzeCharacter = ref('')
|
||||
let TagTreeData = ref([])
|
||||
let promptError = true
|
||||
let wenkeRef = ref(null)
|
||||
|
||||
async function InitData() {
|
||||
|
||||
// 加载
|
||||
// 初始化加载项目下面的分镜好的文案
|
||||
// 并判断是不是有洗稿后的文件。一并加载
|
||||
@ -125,7 +127,6 @@ export default defineComponent({
|
||||
* 初始化数据
|
||||
*/
|
||||
async function InItPromptSort() {
|
||||
|
||||
await window.pmpt.GetPromptSort((value) => {
|
||||
if (value.code == 0) {
|
||||
message.error(value.message)
|
||||
@ -135,10 +136,66 @@ export default defineComponent({
|
||||
})
|
||||
}
|
||||
|
||||
// 导入提示词
|
||||
async function ImportWenKePrompt(e) {
|
||||
if (!(e.ctrlKey && e.altKey && e.key == 'm')) {
|
||||
return
|
||||
}
|
||||
// 弹窗选择文件
|
||||
window.api.SelectFile(['txt'], async (value) => {
|
||||
if (value.code == 0) {
|
||||
message.error(value.message)
|
||||
return
|
||||
}
|
||||
debugger
|
||||
console.log(value.value)
|
||||
// 拿到提示词文件地址,然后还是获取
|
||||
await window.pmpt.OpenPromptFileTxt(value.value, (res) => {
|
||||
debugger
|
||||
console.log(res)
|
||||
if (res.code == 0) {
|
||||
message.error(res.message)
|
||||
return
|
||||
}
|
||||
// 修改数据
|
||||
// 判断获取的数据是不是小于当前的data的行
|
||||
if (res.data.length > data.value.length) {
|
||||
dialog.warning({
|
||||
title: '提示',
|
||||
content: '导入的数据行数大于当前的数据行数,多余的数据会被删除,是否继续导入?',
|
||||
positiveText: '继续',
|
||||
negativeText: '取消',
|
||||
onPositiveClick: async () => {
|
||||
debugger
|
||||
// 开始导入
|
||||
for (let i = 0; i < data.value.length && i < res.data.length; i++) {
|
||||
const element = res.data[i]
|
||||
// 开始修改
|
||||
data.value[i].gpt_prompt = element
|
||||
}
|
||||
}
|
||||
})
|
||||
} else {
|
||||
// 开始导入
|
||||
for (let i = 0; i < data.value.length && i < res.data.length; i++) {
|
||||
const element = res.data[i]
|
||||
// 开始修改
|
||||
data.value[i].gpt_prompt = element
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
await InitData()
|
||||
await InitTags()
|
||||
await InItPromptSort()
|
||||
window.addEventListener('keydown', ImportWenKePrompt)
|
||||
})
|
||||
|
||||
onUnmounted(() => {
|
||||
window.removeEventListener('keydown', ImportWenKePrompt)
|
||||
})
|
||||
|
||||
return {
|
||||
@ -147,7 +204,8 @@ export default defineComponent({
|
||||
TagTreeData,
|
||||
InitData,
|
||||
InitTags,
|
||||
tags
|
||||
tags,
|
||||
wenkeRef
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
@ -349,7 +349,6 @@ export default defineComponent({
|
||||
auto_save,
|
||||
railStyle,
|
||||
AutoSaveUpdate: (value) => {
|
||||
|
||||
auto_save.value = value
|
||||
window.config.auto_save = value
|
||||
},
|
||||
|
||||
263
src/renderer/src/components/ReverseManage/Components/AddBook.vue
Normal file
263
src/renderer/src/components/ReverseManage/Components/AddBook.vue
Normal file
@ -0,0 +1,263 @@
|
||||
<template>
|
||||
<div style="margin: 30px 30px 30px 0">
|
||||
<n-form
|
||||
ref="bookRef"
|
||||
:model="data"
|
||||
:rules="rules"
|
||||
label-placement="left"
|
||||
label-width="auto"
|
||||
require-mark-placement="right-hanging"
|
||||
>
|
||||
<n-form-item label="书名" path="name">
|
||||
<n-input v-model:value="data.name" placeholder="请输入书名" />
|
||||
</n-form-item>
|
||||
<n-form-item label="视频文件" path="oldVideoPath">
|
||||
<n-input
|
||||
disabled="true"
|
||||
v-model:value="data.oldVideoPath"
|
||||
placeholder="请选择反推的视频文件"
|
||||
clearable
|
||||
>
|
||||
<template #suffix>
|
||||
<n-button @click="ClearInputData('oldVideoPath')" text style="font-size: 20px">
|
||||
<n-icon>
|
||||
<CloseSharp />
|
||||
</n-icon>
|
||||
</n-button>
|
||||
</template>
|
||||
</n-input>
|
||||
<n-button type="info" @click="SelectMP4File('oldVideoPath')" style="margin-left: 10px"
|
||||
>选择视频</n-button
|
||||
>
|
||||
</n-form-item>
|
||||
<n-form-item label="小说类型" path="type">
|
||||
<n-select
|
||||
v-model:value="data.type"
|
||||
:disabled="reverseManageStore.selectBook.id != null"
|
||||
:options="reverseManageStore.bookType"
|
||||
style="width: 200px"
|
||||
>
|
||||
</n-select>
|
||||
</n-form-item>
|
||||
<n-form-item label="配音地址" path="audioPath">
|
||||
<n-input
|
||||
v-model:value="data.audioPath"
|
||||
disabled="true"
|
||||
placeholder="没有选择的话则使用原视频的"
|
||||
>
|
||||
<template #suffix>
|
||||
<n-button @click="ClearInputData('audioPath')" text style="font-size: 20px">
|
||||
<n-icon>
|
||||
<CloseSharp />
|
||||
</n-icon>
|
||||
</n-button> </template
|
||||
></n-input>
|
||||
<n-button type="info" @click="SelectMP4File('audioPath')" style="margin-left: 10px"
|
||||
>选择配音</n-button
|
||||
>
|
||||
</n-form-item>
|
||||
<n-form-item label="SRT地址" path="srtPath">
|
||||
<n-input
|
||||
v-model:value="data.srtPath"
|
||||
disabled="true"
|
||||
placeholder="没有选择的话则使用原视频的"
|
||||
>
|
||||
<template #suffix>
|
||||
<n-button @click="ClearInputData('srtPath')" text style="font-size: 20px">
|
||||
<n-icon>
|
||||
<CloseSharp />
|
||||
</n-icon>
|
||||
</n-button> </template
|
||||
></n-input>
|
||||
<n-button type="info" @click="SelectMP4File('srtPath')" style="margin-left: 10px"
|
||||
>选择SRT</n-button
|
||||
>
|
||||
</n-form-item>
|
||||
<n-form-item label="小说项目文件夹" path="bookFolderPath">
|
||||
<n-input
|
||||
v-model:value="data.bookFolderPath"
|
||||
disabled="true"
|
||||
placeholder="不用选择,添加小说自动生成"
|
||||
>
|
||||
</n-input>
|
||||
<n-button type="info" @click="OpenFolder('bookFolderPath')" style="margin-left: 10px"
|
||||
>打开</n-button
|
||||
>
|
||||
</n-form-item>
|
||||
<n-form-item label="图片输出文件夹" path="imageFolder">
|
||||
<n-input
|
||||
v-model:value="data.imageFolder"
|
||||
disabled="true"
|
||||
placeholder="不用选择,添加小说自动生成"
|
||||
>
|
||||
</n-input>
|
||||
<n-button type="info" @click="OpenFolder('imageFolder')" style="margin-left: 10px"
|
||||
>打开</n-button
|
||||
>
|
||||
</n-form-item>
|
||||
<div style="margin-left: 10px; display: flex; justify-content: flex-end">
|
||||
<n-button type="success" @click="AddOrModifyBook">添加</n-button>
|
||||
</div>
|
||||
</n-form>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { ref, onMounted, defineComponent, onUnmounted, toRaw, watch } from 'vue'
|
||||
import { useMessage, NButton, NForm, NFormItem, NInput, NSelect, NIcon } from 'naive-ui'
|
||||
import { useReverseManageStore } from '../../../../../stores/reverseManage.js'
|
||||
import { CloseSharp } from '@vicons/ionicons5'
|
||||
import { cloneDeep } from 'lodash'
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
NButton,
|
||||
NForm,
|
||||
NFormItem,
|
||||
NInput,
|
||||
NSelect,
|
||||
NIcon,
|
||||
CloseSharp
|
||||
},
|
||||
|
||||
setup() {
|
||||
let message = useMessage()
|
||||
let reverseManageStore = useReverseManageStore()
|
||||
let bookRef = ref(null)
|
||||
let data = ref(cloneDeep(reverseManageStore.selectBook))
|
||||
onMounted(async () => {
|
||||
// 初始化小说类型
|
||||
let res = await reverseManageStore.SetBookType()
|
||||
if (res.code == 0) {
|
||||
message.error(res.message)
|
||||
return
|
||||
}
|
||||
})
|
||||
|
||||
/**
|
||||
* 选择 MP4 视频文件
|
||||
*/
|
||||
async function SelectMP4File(propertyName) {
|
||||
let ext = ['mp4']
|
||||
if (propertyName == 'audioPath') {
|
||||
ext = ['mp3', 'wav']
|
||||
} else if (propertyName == 'srtPath') {
|
||||
ext = ['srt']
|
||||
}
|
||||
// 选择MP4文件夹
|
||||
await window.api.SelectFile(ext, (value) => {
|
||||
debugger
|
||||
if (value.code == 0) {
|
||||
message.error(value.message)
|
||||
return
|
||||
}
|
||||
if (value.value == null) {
|
||||
message.error('没有选中的数据')
|
||||
return
|
||||
}
|
||||
if (propertyName == 'oldVideoPath') {
|
||||
data.value.oldVideoPath = value.value
|
||||
} else if (propertyName == 'audioPath') {
|
||||
data.value.UpdateSelectBook = value.value
|
||||
} else if (propertyName == 'srtPath') {
|
||||
data.value.srtPath = value.value
|
||||
} else {
|
||||
message.error('没有找到对应的属性')
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
let ruleObj = (errorMessage) => {
|
||||
return [
|
||||
{
|
||||
required: true,
|
||||
validator(rule, value) {
|
||||
if (value == null || value == '') return new Error(errorMessage)
|
||||
return true
|
||||
},
|
||||
trigger: ['input', 'blur', 'change']
|
||||
}
|
||||
]
|
||||
}
|
||||
let rules = {
|
||||
name: ruleObj('书名必填'),
|
||||
oldVideoPath: ruleObj('反推的视频文件地址必填'),
|
||||
type: ruleObj('小说类型必填')
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加或者是修改数据(通过ID判断)
|
||||
*/
|
||||
async function AddOrModifyBook(e) {
|
||||
// 校验数据
|
||||
e.preventDefault()
|
||||
bookRef.value?.validate(async (errors) => {
|
||||
if (errors) {
|
||||
message.error('请检查必填字段')
|
||||
return
|
||||
}
|
||||
debugger
|
||||
let res = await reverseManageStore.SaveSelectBook(toRaw(data.value))
|
||||
// 判断当前的数据是不是有ID
|
||||
if (res.code == 0) {
|
||||
message.error(res.message)
|
||||
return
|
||||
}
|
||||
message.success('添加/修改成功')
|
||||
data.value = reverseManageStore.selectBook
|
||||
})
|
||||
}
|
||||
|
||||
//清空MP4路劲信息
|
||||
function ClearInputData(propertyName) {
|
||||
if (propertyName == 'oldVideoPath') {
|
||||
reverseManageStore.UpdateSelectBook({ oldVideoPath: null })
|
||||
} else if (propertyName == 'audioPath') {
|
||||
reverseManageStore.UpdateSelectBook({ audioPath: null })
|
||||
} else if (propertyName == 'srtPath') {
|
||||
reverseManageStore.UpdateSelectBook({ srtPath: null })
|
||||
} else {
|
||||
message.error('没有找到对应的属性')
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 打开指定的文件夹
|
||||
* @param param
|
||||
*/
|
||||
async function OpenFolder(param) {
|
||||
let res = null
|
||||
debugger
|
||||
if (param == 'imageFolder') {
|
||||
res = await window.system.OpenFolder({
|
||||
folderPath: data.value.imageFolder,
|
||||
baseProject: false
|
||||
})
|
||||
} else if (param == 'bookFolderPath') {
|
||||
res = await window.system.OpenFolder({
|
||||
folderPath: data.value.bookFolderPath,
|
||||
baseProject: false
|
||||
})
|
||||
} else {
|
||||
message.error('未知的参数')
|
||||
return
|
||||
}
|
||||
if (res.code == 0) {
|
||||
message.error(res.message)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
reverseManageStore,
|
||||
rules,
|
||||
ClearInputData,
|
||||
SelectMP4File,
|
||||
AddOrModifyBook,
|
||||
bookRef,
|
||||
OpenFolder,
|
||||
data
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
@ -0,0 +1,89 @@
|
||||
<template>
|
||||
<n-button
|
||||
:size="softwareStore.softWare.reverse_data_table_size"
|
||||
strong
|
||||
secondary
|
||||
type="primary"
|
||||
@click="EditBook"
|
||||
>编辑</n-button
|
||||
>
|
||||
<n-button
|
||||
:size="softwareStore.softWare.reverse_data_table_size"
|
||||
strong
|
||||
secondary
|
||||
style="margin-left: 5px"
|
||||
type="info"
|
||||
>任务</n-button
|
||||
>
|
||||
<n-button
|
||||
:size="softwareStore.softWare.reverse_data_table_size"
|
||||
strong
|
||||
secondary
|
||||
style="margin-left: 5px"
|
||||
type="warning"
|
||||
@click="EditBook"
|
||||
>重置</n-button
|
||||
>
|
||||
<n-button
|
||||
:size="softwareStore.softWare.reverse_data_table_size"
|
||||
style="margin-left: 5px"
|
||||
strong
|
||||
secondary
|
||||
type="error"
|
||||
>删除
|
||||
</n-button>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { ref, onMounted, defineComponent, h, onUnmounted, toRaw, watch } from 'vue'
|
||||
import { useMessage, NButton, useDialog } from 'naive-ui'
|
||||
import { useReverseManageStore } from '../../../../../stores/reverseManage'
|
||||
import { useSoftwareStore } from '../../../../../stores/software'
|
||||
import { BookType } from '../../../../../define/enum/bookEnum'
|
||||
import AddBook from './AddBook.vue'
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
NButton
|
||||
},
|
||||
|
||||
props: ['book'],
|
||||
setup(props) {
|
||||
let message = useMessage()
|
||||
let dialog = useDialog()
|
||||
let book = ref(props.book)
|
||||
let reverseManageStore = useReverseManageStore()
|
||||
let softwareStore = useSoftwareStore()
|
||||
|
||||
onMounted(async () => {})
|
||||
|
||||
/**
|
||||
* 编辑小说数据
|
||||
*/
|
||||
async function EditBook(e) {
|
||||
e.stopPropagation()
|
||||
// 修改选中的数据
|
||||
debugger
|
||||
reverseManageStore.SetSelectBook(toRaw(book.value))
|
||||
|
||||
// 一个弹窗添加数据
|
||||
let dialogWidth = 600
|
||||
// ImportWordAndSrt
|
||||
dialog.create({
|
||||
showIcon: false,
|
||||
closeOnEsc: false,
|
||||
title: '新增小说',
|
||||
content: () => h(AddBook),
|
||||
style: `width : ${dialogWidth}px;`,
|
||||
maskClosable: false
|
||||
})
|
||||
}
|
||||
return {
|
||||
book,
|
||||
reverseManageStore,
|
||||
softwareStore,
|
||||
EditBook
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
@ -0,0 +1,146 @@
|
||||
<template>
|
||||
<div style="display: flex; justify-content: space-between">
|
||||
<n-button :render-icon="renderIcon" type="info" @click="AddBookDialog">新增</n-button>
|
||||
<div style="display: flex; justify-content: flex-end; margin-right: 10px; align-items: center">
|
||||
<n-popover trigger="hover">
|
||||
<template #trigger>
|
||||
<n-switch
|
||||
v-model:value="softwareStore.softWare.reverse_show_book_striped"
|
||||
@update:value="DataTableStripedUpdate"
|
||||
/>
|
||||
</template>
|
||||
<span>显示斑马纹</span>
|
||||
</n-popover>
|
||||
<n-popover trigger="hover">
|
||||
<template #trigger>
|
||||
<n-button text style="font-size: 20px; margin-left: 10px">
|
||||
<n-icon>
|
||||
<ReloadSharp />
|
||||
</n-icon>
|
||||
</n-button>
|
||||
</template>
|
||||
<span>刷新数据</span>
|
||||
</n-popover>
|
||||
|
||||
<n-dropdown trigger="click" :options="softwareStore.componentSize" @select="SelectDropdown">
|
||||
<n-button text style="font-size: 20px; margin-left: 10px; font-weight: bold">
|
||||
Size</n-button
|
||||
>
|
||||
</n-dropdown>
|
||||
|
||||
<n-button text style="margin-left: 10px; font-size: 20px" @click="SwitchShowTemp">
|
||||
<n-icon>
|
||||
<SwapHorizontalSharp />
|
||||
</n-icon>
|
||||
</n-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { ref, onMounted, defineComponent, onUnmounted, h, toRaw, computed } from 'vue'
|
||||
import { useMessage, NButton, NIcon, useDialog, NPopover, NSwitch, NDropdown } from 'naive-ui'
|
||||
import { AddSharp, ReloadSharp, ResizeSharp, SwapHorizontalSharp } from '@vicons/ionicons5'
|
||||
import AddBook from './AddBook.vue'
|
||||
import { useSoftwareStore } from '../../../../../stores/software'
|
||||
import { useReverseManageStore } from '../../../../../stores/reverseManage.js'
|
||||
import { BookType } from '../../../../../define/enum/bookEnum'
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
NButton,
|
||||
AddSharp,
|
||||
NIcon,
|
||||
ReloadSharp,
|
||||
NPopover,
|
||||
NSwitch,
|
||||
NDropdown,
|
||||
ResizeSharp,
|
||||
SwapHorizontalSharp
|
||||
},
|
||||
|
||||
setup() {
|
||||
let message = useMessage()
|
||||
let dialog = useDialog()
|
||||
let softwareStore = useSoftwareStore()
|
||||
let reverseManageStore = useReverseManageStore()
|
||||
let book = ref(null)
|
||||
|
||||
onMounted(async () => {
|
||||
// 初始化一下吧
|
||||
await softwareStore.GetComponentSize()
|
||||
})
|
||||
|
||||
async function SwitchShowTemp() {
|
||||
// 判断当前显示的状态
|
||||
// 显示加载1秒
|
||||
softwareStore.softWare.reverse_display_show = !softwareStore.softWare.reverse_display_show
|
||||
}
|
||||
|
||||
// 新增新增小说
|
||||
async function AddBookDialog() {
|
||||
// 将选中数据清空
|
||||
reverseManageStore.SetSelectBook({
|
||||
name: null,
|
||||
id: null,
|
||||
type: BookType.MJ_REVERSE
|
||||
})
|
||||
// 一个弹窗添加数据
|
||||
let dialogWidth = 600
|
||||
// ImportWordAndSrt
|
||||
dialog.create({
|
||||
showIcon: false,
|
||||
closeOnEsc: false,
|
||||
title: '新增小说',
|
||||
content: () => h(AddBook),
|
||||
style: `width : ${dialogWidth}px;`,
|
||||
maskClosable: false
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改设置
|
||||
*/
|
||||
async function DataTableStripedUpdate() {
|
||||
// 修改数据
|
||||
debugger
|
||||
// 直接提交修改
|
||||
let res = await softwareStore.SaveSoftware()
|
||||
console.log(res)
|
||||
if (res.code == 0) {
|
||||
message.error(res.message)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// 选择下拉菜单
|
||||
async function SelectDropdown(key) {
|
||||
debugger
|
||||
console.log(key)
|
||||
softwareStore.softWare.reverse_data_table_size = key
|
||||
// 直接提交修改
|
||||
let res = await softwareStore.SaveSoftware()
|
||||
if (res.code == 0) {
|
||||
message.error(res.message)
|
||||
return
|
||||
}
|
||||
message.success('切换成功')
|
||||
}
|
||||
|
||||
return {
|
||||
SwitchShowTemp,
|
||||
renderIcon() {
|
||||
return h(NIcon, null, {
|
||||
default: () => h(AddSharp, { size: '40', color: 'white' }, {})
|
||||
})
|
||||
},
|
||||
AddBookDialog,
|
||||
book,
|
||||
reverseManageStore,
|
||||
softwareStore,
|
||||
DataTableStripedUpdate,
|
||||
SelectDropdown
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
@ -0,0 +1,60 @@
|
||||
<template>
|
||||
<div>
|
||||
<n-button strong secondary @click="RetuenMain"> 返回 </n-button>
|
||||
<n-dropdown trigger="hover" :options="AutoOptions" @select="SelectAutoAction">
|
||||
<n-button color="#ee7959" @click="AutoAction" style="margin-left: 5px"> 自动开始 </n-button>
|
||||
</n-dropdown>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { ref, onMounted, defineComponent, onUnmounted, toRaw, watch } from 'vue'
|
||||
import { useMessage, NButton, NCheckbox, NDropdown } from 'naive-ui'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { useReverseManageStore } from '../../../../../stores/reverseManage'
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
NButton,
|
||||
NCheckbox,
|
||||
NDropdown
|
||||
},
|
||||
|
||||
setup() {
|
||||
let router = useRouter()
|
||||
let reverseManageStore = useReverseManageStore()
|
||||
// 获取当前这个界面的数据
|
||||
onMounted(async () => {})
|
||||
|
||||
// 返回主页
|
||||
function RetuenMain() {
|
||||
router.push('/reverse_management')
|
||||
}
|
||||
|
||||
// 自动开始
|
||||
async function AutoAction() {
|
||||
// 开始自动执行。先分镜,后面在添加任务中
|
||||
let res_frame = await window.book.GetFrameData(reverseManageStore.selectBook.id)
|
||||
}
|
||||
|
||||
// 选择自动开始的操作(停止或者是继续)
|
||||
async function SelectAutoAction() {}
|
||||
|
||||
return {
|
||||
RetuenMain,
|
||||
AutoAction,
|
||||
reverseManageStore,
|
||||
AutoOptions: [
|
||||
{
|
||||
label: '停止任务',
|
||||
value: 'auto_stop'
|
||||
},
|
||||
{
|
||||
label: '继续任务',
|
||||
value: 'auto_continue'
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
@ -0,0 +1,18 @@
|
||||
<template>
|
||||
<div>ManageBookReverseTable</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { ref, onMounted, defineComponent, onUnmounted, toRaw, watch } from 'vue'
|
||||
import { useMessage } from 'naive-ui'
|
||||
|
||||
export default defineComponent({
|
||||
components: {},
|
||||
|
||||
setup() {
|
||||
onMounted(async () => {})
|
||||
|
||||
return {}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
@ -0,0 +1,87 @@
|
||||
<template>
|
||||
<div class="artplayer-app" style="height: 100%">
|
||||
<Artplayer @get-instance="getInstance" :option="option" :style="palyarStyle" />
|
||||
<n-log
|
||||
style="height: 60%; background-color: #f8f8f8"
|
||||
ref="logInst"
|
||||
:log="logger"
|
||||
:loading="loading"
|
||||
trim
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { ref, onMounted, defineComponent, onUnmounted, toRaw, nextTick, watchEffect } from 'vue'
|
||||
import { useMessage, NLog } from 'naive-ui'
|
||||
import Artplayer from '../../Components/Artplayer.vue'
|
||||
import { useReverseManageStore } from '../../../../../stores/reverseManage'
|
||||
import { DEFINE_STRING } from '../../../../../define/define_string'
|
||||
|
||||
export default defineComponent({
|
||||
components: { Artplayer, NLog },
|
||||
|
||||
setup() {
|
||||
let message = useMessage()
|
||||
let reverseManageStore = useReverseManageStore()
|
||||
let option = {
|
||||
container: '.artplayer-app',
|
||||
id: reverseManageStore.selectBook.id,
|
||||
url: reverseManageStore.selectBook.oldVideoPath,
|
||||
playbackRate: true,
|
||||
aspectRatio: true,
|
||||
mutex: true,
|
||||
setting: true,
|
||||
hotkey: true,
|
||||
autoSize: true,
|
||||
fullscreen: true
|
||||
}
|
||||
let palyarStyle = {
|
||||
width: '300px',
|
||||
height: '300px',
|
||||
margin: '0 auto'
|
||||
}
|
||||
let logger = ref('')
|
||||
const logInst = ref(null)
|
||||
let loading = ref(false)
|
||||
onMounted(async () => {
|
||||
// 监听返回的日志数据
|
||||
window.api.setEventListen([DEFINE_STRING.SYSTEM.RETURN_LOGGER], (value) => {
|
||||
debugger
|
||||
if (value.code == 0) {
|
||||
message.error('添加日志输出失败,但是不影响使用')
|
||||
logger.value += value.message + '\n'
|
||||
return
|
||||
}
|
||||
let temp_logger = value.data
|
||||
// 将成功的日志数据添加到日志组件
|
||||
let log = `[${temp_logger.type}] [${temp_logger.date.toLocaleString()}] [${
|
||||
temp_logger.status
|
||||
}] [${temp_logger.content}]`
|
||||
logger.value += log + '\n'
|
||||
})
|
||||
|
||||
// 监听,将新添加的日志滚动在最下面
|
||||
watchEffect(() => {
|
||||
if (logger.value) {
|
||||
nextTick(() => {
|
||||
logInst.value?.scrollTo({ position: 'bottom', silent: true })
|
||||
})
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
return {
|
||||
reverseManageStore,
|
||||
option,
|
||||
getInstance(art) {
|
||||
// console.info(art)
|
||||
},
|
||||
palyarStyle,
|
||||
logger,
|
||||
logInst,
|
||||
loading
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
207
src/renderer/src/components/ReverseManage/ManageBook.vue
Normal file
207
src/renderer/src/components/ReverseManage/ManageBook.vue
Normal file
@ -0,0 +1,207 @@
|
||||
<template>
|
||||
<div style="margin-bottom: 10px">
|
||||
<ManageBookButton />
|
||||
</div>
|
||||
<div style="margin-right: 10px">
|
||||
<n-data-table
|
||||
:columns="columns"
|
||||
:size="softwareStore.softWare.reverse_data_table_size"
|
||||
:data="data"
|
||||
:pagination="pagination"
|
||||
:bordered="false"
|
||||
:remote="true"
|
||||
:striped="softwareStore.softWare.reverse_show_book_striped"
|
||||
:scroll-x="1000"
|
||||
:row-props="rowProps"
|
||||
:max-height="maxHeight"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { ref, onMounted, defineComponent, onUnmounted, toRaw, reactive, computed, h } from 'vue'
|
||||
import { useMessage, NButton, NDataTable, NTag, NEllipsis } from 'naive-ui'
|
||||
import ManageBookButton from './Components/ManageBookButton.vue'
|
||||
import { useSoftwareStore } from '../../../../stores/software'
|
||||
import { useReverseManageStore } from '../../../../stores/reverseManage.js'
|
||||
import { BookType } from '../../../../define/enum/bookEnum'
|
||||
import BookListAction from './Components/BookListAction.vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
NButton,
|
||||
ManageBookButton,
|
||||
NDataTable,
|
||||
NEllipsis
|
||||
},
|
||||
|
||||
setup() {
|
||||
let message = useMessage()
|
||||
let softwareStore = useSoftwareStore()
|
||||
let reverseManageStore = useReverseManageStore()
|
||||
let data = computed(() => reverseManageStore.GetBookData())
|
||||
const router = useRouter()
|
||||
let maxHeight = ref(0)
|
||||
// 分页设置
|
||||
const paginationReactive = (() => {
|
||||
return reactive({
|
||||
page: 1,
|
||||
pageSize: 10,
|
||||
showSizePicker: true,
|
||||
pageSizes: [10, 20, 50, 100],
|
||||
onChange: async (page) => {
|
||||
// 加载数据。切换,重新架子啊数据
|
||||
paginationReactive.page = page
|
||||
await GetBookByCondition()
|
||||
},
|
||||
onUpdatePageSize: async (pageSize) => {
|
||||
paginationReactive.pageSize = pageSize
|
||||
paginationReactive.page = 1
|
||||
await GetBookByCondition()
|
||||
}
|
||||
})
|
||||
})()
|
||||
|
||||
let pagination = computed(() => {
|
||||
return paginationReactive
|
||||
})
|
||||
|
||||
async function GetBookByCondition() {
|
||||
try {
|
||||
debugger
|
||||
let res = await reverseManageStore.GetBookDataFromDB({
|
||||
page: paginationReactive.page,
|
||||
pageSize: paginationReactive.pageSize
|
||||
})
|
||||
if (res.code == 0) {
|
||||
message.error(res.message)
|
||||
return
|
||||
}
|
||||
let res_count = res.data.book_length / pagination.value.pageSize
|
||||
if (!Number.isInteger(res_count)) {
|
||||
res_count = Math.ceil(res_count)
|
||||
}
|
||||
pagination.value.pageCount = res_count
|
||||
|
||||
// 开始获取批次任务
|
||||
let bookTask = await reverseManageStore.GetBookTaskDataFromDB({
|
||||
bookId: reverseManageStore.selectBook.id
|
||||
})
|
||||
if (bookTask.code == 0) {
|
||||
message.error(bookTask.message)
|
||||
return
|
||||
}
|
||||
} catch (error) {
|
||||
message.error('获取小说数据失败')
|
||||
}
|
||||
}
|
||||
|
||||
async function InitData() {
|
||||
try {
|
||||
// 初始化数据
|
||||
debugger
|
||||
await GetBookByCondition()
|
||||
} catch (error) {
|
||||
message.error(error.message)
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
await InitData()
|
||||
getMaxHeight()
|
||||
// 监听窗口的大小变化
|
||||
window.addEventListener('resize', getMaxHeight)
|
||||
})
|
||||
// 计算当前程序界面的高度,减去上下的高度,设置maxHegiht
|
||||
function getMaxHeight() {
|
||||
let height = window.innerHeight
|
||||
maxHeight.value = height - 180
|
||||
}
|
||||
|
||||
const createColumns = () => {
|
||||
return [
|
||||
{
|
||||
title: 'No.',
|
||||
key: 'no',
|
||||
width: 50
|
||||
},
|
||||
{
|
||||
title: '小说名',
|
||||
key: 'name',
|
||||
render: (row) => {
|
||||
return h(
|
||||
'div',
|
||||
{
|
||||
style:
|
||||
'overflow: hidden; max-width : 100px; white-space: nowrap; text-overflow: ellipsis;'
|
||||
},
|
||||
{ default: () => row.name }
|
||||
)
|
||||
},
|
||||
width: 100
|
||||
},
|
||||
{
|
||||
title: '类型',
|
||||
key: 'type',
|
||||
width: 80,
|
||||
render: (row) => {
|
||||
return h(
|
||||
NTag,
|
||||
{ type: 'success', size: softwareStore.softWare.reverse_data_table_size },
|
||||
{
|
||||
default: () => getTyleLabel(row.type)
|
||||
}
|
||||
)
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '原视频',
|
||||
key: 'oldVideoPath'
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
key: 'action',
|
||||
width: 310,
|
||||
fixed: 'right',
|
||||
render: (row) => {
|
||||
return h(BookListAction, { book: row })
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
function getTyleLabel(value) {
|
||||
if (value == BookType.MJ_REVERSE) {
|
||||
return 'MJ反推'
|
||||
} else if (value == BookType.SD_REVERSE) {
|
||||
return 'SD反推'
|
||||
} else if (value == BookType.ORIGINAL) {
|
||||
return '原创'
|
||||
} else {
|
||||
return '未知'
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
softwareStore,
|
||||
reverseManageStore,
|
||||
data,
|
||||
pagination,
|
||||
maxHeight,
|
||||
columns: createColumns(),
|
||||
rowProps: (row) => {
|
||||
return {
|
||||
style: 'cursor: pointer;',
|
||||
onClick: () => {
|
||||
debugger
|
||||
message.info(row.id)
|
||||
reverseManageStore.selectBook = row
|
||||
router.push({ name: 'manage_book', params: { id: row.id } })
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
@ -0,0 +1,37 @@
|
||||
<template>
|
||||
<div style="height: 100%; display: flex; width: 100%; overflow: auto">
|
||||
<div v-if="true" class="left_container" style="flex: 10; min-width: 600px">
|
||||
<ManageBookDetailButton />
|
||||
<ManageBookReverseTable style="margin-top: 10px" />
|
||||
</div>
|
||||
<div >
|
||||
<n-divider vertical style="height: 100%"></n-divider>
|
||||
</div>
|
||||
<div class="right_container" style="flex: 3; min-width: 250px">
|
||||
<ManageBookShowLogger />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { ref, onMounted, defineComponent, onUnmounted, toRaw, watch } from 'vue'
|
||||
import { useMessage, NDivider } from 'naive-ui'
|
||||
import ManageBookDetailButton from './Components/ManageBookDetailButton.vue'
|
||||
import ManageBookReverseTable from './Components/ManageBookReverseTable.vue'
|
||||
import ManageBookShowLogger from './Components/ManageBookShowLogger.vue'
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
ManageBookDetailButton,
|
||||
ManageBookReverseTable,
|
||||
ManageBookShowLogger,
|
||||
NDivider
|
||||
},
|
||||
|
||||
setup() {
|
||||
onMounted(async () => {})
|
||||
|
||||
return {}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
21
src/renderer/src/components/ReverseManage/ManageBookTask.vue
Normal file
21
src/renderer/src/components/ReverseManage/ManageBookTask.vue
Normal file
@ -0,0 +1,21 @@
|
||||
<template>
|
||||
<div>按钮</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { ref, onMounted, defineComponent, onUnmounted, toRaw, watch } from 'vue'
|
||||
import { useMessage, NButton, NDataTable } from 'naive-ui'
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
NButton,
|
||||
NDataTable
|
||||
},
|
||||
|
||||
setup() {
|
||||
onMounted(async () => {})
|
||||
|
||||
return {}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
48
src/renderer/src/components/ReverseManage/ReverseManage.vue
Normal file
48
src/renderer/src/components/ReverseManage/ReverseManage.vue
Normal file
@ -0,0 +1,48 @@
|
||||
<template>
|
||||
<div style="height: 100%">
|
||||
<ManageBook style="height: 100%" v-if="softwareStore.softWare.reverse_display_show" />
|
||||
<n-split v-else direction="horizontal" :min="0.4" :max="0.8" :default-size="0.6" height="100%">
|
||||
<template #1> <ManageBook style="height: 100%" /> </template>
|
||||
<template #2>
|
||||
<ManageBookTask style="height: 100%" />
|
||||
</template>
|
||||
</n-split>
|
||||
|
||||
<n-float-button :right="30" :bottom="30" shape="circle">
|
||||
<n-badge :value="100" :max="99" :offset="[6, -8]">
|
||||
<n-icon :size="large">
|
||||
<Layers />
|
||||
</n-icon>
|
||||
</n-badge>
|
||||
</n-float-button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { ref, onMounted, defineComponent, onUnmounted, toRaw, watch, onBeforeMount } from 'vue'
|
||||
import { useMessage, NSplit, NSpin, NFloatButton, NIcon, NBadge } from 'naive-ui'
|
||||
import ManageBook from './ManageBook.vue'
|
||||
import ManageBookTask from './ManageBookTask.vue'
|
||||
import { useSoftwareStore } from '../../../../stores/software'
|
||||
import { useReverseManageStore } from '../../../../stores/reverseManage.js'
|
||||
import { Layers } from '@vicons/ionicons5'
|
||||
|
||||
export default defineComponent({
|
||||
components: { NSplit, ManageBook, ManageBookTask, NSpin, NFloatButton, NIcon, Layers, NBadge },
|
||||
|
||||
setup() {
|
||||
let message = useMessage()
|
||||
let isShowTask = ref(false)
|
||||
let softwareStore = useSoftwareStore()
|
||||
let reverseManageStore = useReverseManageStore()
|
||||
|
||||
onMounted(() => {})
|
||||
|
||||
return {
|
||||
isShowTask,
|
||||
softwareStore,
|
||||
reverseManageStore
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
@ -1,153 +1,271 @@
|
||||
<template>
|
||||
<n-button type="info" round @click="OpenDiscordWindow">打开登录MJ</n-button>
|
||||
<n-button type="info" round @click="GetChannelRobots" style="margin-left: 10px"
|
||||
>获取频道机器人</n-button
|
||||
>
|
||||
<n-button type="info" round @click="SaveMjSetting" style="margin-left: 10px">保存MJ配置</n-button>
|
||||
<n-divider />
|
||||
<n-form ref="formRef" label-placement="top" :model="mjSetting" :rules="rules">
|
||||
<div style="display: flex">
|
||||
<n-form-item label="服务器ID" style="width: 400px" path="serviceID">
|
||||
<n-input v-model:value="mjSetting.serviceID" placeholder="登录MJ后切换服务器自动获取" />
|
||||
</n-form-item>
|
||||
<n-form-item label="频道ID" style="width: 400px; margin-left: 10px" path="channelID">
|
||||
<n-input v-model:value="mjSetting.channelID" placeholder="登录MJ后切换频道自动获取" />
|
||||
</n-form-item>
|
||||
</div>
|
||||
<!-- <div style="display: flex">
|
||||
<n-form-item label="MJ机器ID" path="mj.botId">
|
||||
<n-input v-model:value="mjSetting.mj.botId" placeholder="MJ机器ID" />
|
||||
</n-form-item>
|
||||
<n-form-item label="MJ命令ID" style="margin-left: 10px" path="mj.commandId">
|
||||
<n-input v-model:value="mjSetting.mj.commandId" placeholder="MJ命令ID" />
|
||||
</n-form-item>
|
||||
<n-form-item label="MJ命令名称" style="margin-left: 10px" path="mj.commandName">
|
||||
<n-input v-model:value="mjSetting.mj.commandName" placeholder="MJ命令名称" />
|
||||
</n-form-item>
|
||||
<n-form-item label="MJ版本ID" style="margin-left: 10px" path="mj.versionId">
|
||||
<n-input v-model:value="mjSetting.mj.versionId" placeholder="MJ版本ID" />
|
||||
</n-form-item>
|
||||
</div>
|
||||
<n-spin :show="show" size="large">
|
||||
<div style="overflow: auto; height: 100%">
|
||||
<n-card title="基础设置" size="medium" hoverable style="min-width: 850px">
|
||||
<n-form :model="mjSetting" ref="sampleRef" :rules="sampleRules">
|
||||
<div style="display: flex; align-items: center">
|
||||
<n-form-item label="出图模式" style="width: 150px" path="requestModel">
|
||||
<n-select
|
||||
:options="request_model_options"
|
||||
v-model:value="mjSetting.requestModel"
|
||||
placeholder="请选择出图模式"
|
||||
></n-select>
|
||||
</n-form-item>
|
||||
<n-form-item
|
||||
label="选择生图机器人"
|
||||
path="selectRobot"
|
||||
style="width: 120px; margin-left: 10px"
|
||||
>
|
||||
<n-select
|
||||
:options="select_robot_options"
|
||||
v-model:value="mjSetting.selectRobot"
|
||||
@update:value="UpdateSelectRobot"
|
||||
></n-select>
|
||||
</n-form-item>
|
||||
<n-form-item
|
||||
label="机器人模型"
|
||||
style="width: 120px; margin-left: 10px"
|
||||
path="imageModel"
|
||||
>
|
||||
<n-select
|
||||
placeholder="请选择机器人模型"
|
||||
:options="image_model_options"
|
||||
v-model:value="mjSetting.imageModel"
|
||||
></n-select>
|
||||
</n-form-item>
|
||||
<n-form-item label="生图尺寸" style="width: 120px; margin-left: 10px" path="imageScale">
|
||||
<n-select
|
||||
placeholder="请选择生图尺寸"
|
||||
:options="image_scale_options"
|
||||
v-model:value="mjSetting.imageScale"
|
||||
></n-select>
|
||||
</n-form-item>
|
||||
<n-form-item
|
||||
label="命令后缀"
|
||||
style="width: 160px; margin-left: 10px"
|
||||
path="image_suffix"
|
||||
>
|
||||
<n-input v-model:value="image_suffix" placeholder="请输入后缀命令"></n-input>
|
||||
</n-form-item>
|
||||
<n-form-item
|
||||
label="生图任务量"
|
||||
style="width: 100px; margin-left: 10px"
|
||||
path="taskCount"
|
||||
>
|
||||
<n-input-number
|
||||
v-model:value="mjSetting.taskCount"
|
||||
:show-button="false"
|
||||
placeholder="MJ并发出图数量"
|
||||
:min="1"
|
||||
:max="20"
|
||||
></n-input-number>
|
||||
</n-form-item>
|
||||
<n-form-item
|
||||
label="间隔时间(s)"
|
||||
style="width: 100px; margin-left: 10px"
|
||||
path="spaceTime"
|
||||
>
|
||||
<n-input-number
|
||||
v-model:value="mjSetting.spaceTime"
|
||||
:show-button="false"
|
||||
placeholder="请输入间隔时间(s)"
|
||||
:min="1"
|
||||
:max="30"
|
||||
></n-input-number>
|
||||
</n-form-item>
|
||||
</div>
|
||||
</n-form>
|
||||
</n-card>
|
||||
<n-card
|
||||
title="API模式设置"
|
||||
hoverable
|
||||
style="margin-top: 10px; min-width: 850px"
|
||||
size="medium"
|
||||
>
|
||||
<n-form :model="mjSetting.apiSetting">
|
||||
<div style="display: flex">
|
||||
<n-form-item
|
||||
label="选择出图的API"
|
||||
style="width: 160px; margin-left: 10px"
|
||||
path="mjApiUrl"
|
||||
>
|
||||
<n-select
|
||||
:options="mj_api_options"
|
||||
v-model:value="mjSetting.apiSetting.mjApiUrl"
|
||||
placeholder="选择出图的中转API"
|
||||
/>
|
||||
</n-form-item>
|
||||
<n-form-item style="margin-left: 10px" path="mj_api_url">
|
||||
<n-button type="success" @click="openGptBuyUrl">购买</n-button>
|
||||
</n-form-item>
|
||||
<n-form-item
|
||||
label="选择出图速度模式"
|
||||
style="width: 160px; margin-left: 10px"
|
||||
path="mjSpeed"
|
||||
>
|
||||
<n-select
|
||||
:options="mj_speed_options"
|
||||
v-model:value="mjSetting.apiSetting.mjSpeed"
|
||||
placeholder="选择出图速度模式"
|
||||
/>
|
||||
</n-form-item>
|
||||
<n-form-item label="输入API密钥" style="width: 160px; margin-left: 10px" path="apiKey">
|
||||
<n-input
|
||||
type="password"
|
||||
placeholder="请输入密钥"
|
||||
v-model:value="mjSetting.apiSetting.apiKey"
|
||||
></n-input>
|
||||
</n-form-item>
|
||||
</div>
|
||||
</n-form>
|
||||
</n-card>
|
||||
|
||||
<div style="display: flex">
|
||||
<n-form-item label="NIJI机器ID" path="niji.botId">
|
||||
<n-input v-model:value="mjSetting.niji.botId" placeholder="NIJI机器ID" />
|
||||
</n-form-item>
|
||||
<n-form-item label="NIJI命令ID" style="margin-left: 10px" path="niji.commandId">
|
||||
<n-input v-model:value="mjSetting.niji.commandId" placeholder="NIJI命令ID" />
|
||||
</n-form-item>
|
||||
<n-form-item label="NIJI命令名称" style="margin-left: 10px" path="niji.commandName">
|
||||
<n-input v-model:value="mjSetting.niji.commandName" placeholder="NIJI命令名称" />
|
||||
</n-form-item>
|
||||
<n-form-item label="NIJI版本ID" style="margin-left: 10px" path="niji.versionId">
|
||||
<n-input v-model:value="mjSetting.niji.versionId" placeholder="NIJI版本ID" />
|
||||
</n-form-item>
|
||||
</div> -->
|
||||
<n-card title="代理模式设置" hoverable style="margin-top: 10px; min-width: 850px">
|
||||
<n-form :model="mjSetting.remoteSetting">
|
||||
<div style="display: flex; margin-top: 10px">
|
||||
<n-form-item label="服务器ID" style="width: 200px; margin-left: 5px" path="guildId">
|
||||
<n-input
|
||||
v-model:value="mjSetting.remoteSetting.guildId"
|
||||
placeholder="请填写服务器ID"
|
||||
/>
|
||||
</n-form-item>
|
||||
<n-form-item label="频道ID" style="width: 200px; margin-left: 10px" path="channelId">
|
||||
<n-input
|
||||
v-model:value="mjSetting.remoteSetting.channelId"
|
||||
placeholder="请填写频道ID"
|
||||
/>
|
||||
</n-form-item>
|
||||
<n-form-item
|
||||
label="MJ私信ID"
|
||||
style="width: 200px; margin-left: 10px"
|
||||
path="mjBotChannelId"
|
||||
>
|
||||
<n-input
|
||||
v-model:value="mjSetting.remoteSetting.mjBotChannelId"
|
||||
placeholder="请填写MJ私信ID"
|
||||
/>
|
||||
</n-form-item>
|
||||
<n-form-item
|
||||
label="Niji私信ID"
|
||||
style="width: 200px; margin-left: 10px"
|
||||
path="nijiBotChannelId"
|
||||
>
|
||||
<n-input
|
||||
v-model:value="mjSetting.remoteSetting.nijiBotChannelId"
|
||||
placeholder="请填写NIJI私信ID"
|
||||
/>
|
||||
</n-form-item>
|
||||
<n-form-item style="width: 200px; margin-left: 10px">
|
||||
<n-button type="info" @click="AccountSync">账号同步</n-button>
|
||||
</n-form-item>
|
||||
</div>
|
||||
<div style="display: flex; margin-top: 10px">
|
||||
<n-form-item label="用户token" style="width: 240px" path="token">
|
||||
<n-input
|
||||
v-model:value="mjSetting.remoteSetting.userToken"
|
||||
placeholder="请填写MJtoken"
|
||||
/>
|
||||
</n-form-item>
|
||||
<n-form-item label="用户Agent" style="width: 250px; margin-left: 10px" path="userAgent">
|
||||
<n-input
|
||||
v-model:value="mjSetting.remoteSetting.userAgent"
|
||||
placeholder="请填写用户Agent"
|
||||
/>
|
||||
</n-form-item>
|
||||
<n-form-item label="账号并发数" style="width: 100px; margin-left: 10px" path="coreSize">
|
||||
<n-input-number
|
||||
v-model:value="mjSetting.remoteSetting.coreSize"
|
||||
:show-button="false"
|
||||
placeholder="请填写账号并发数"
|
||||
:min="1"
|
||||
:max="20"
|
||||
></n-input-number>
|
||||
</n-form-item>
|
||||
<n-form-item label="等待队列" style="width: 100px; margin-left: 10px" path="queueSize">
|
||||
<n-input-number
|
||||
v-model:value="mjSetting.remoteSetting.queueSize"
|
||||
:show-button="false"
|
||||
placeholder="请填写等待队列数量"
|
||||
:min="1"
|
||||
:max="20"
|
||||
></n-input-number>
|
||||
</n-form-item>
|
||||
<n-form-item
|
||||
label="任务超时时间"
|
||||
style="width: 100px; margin-left: 10px"
|
||||
path="timeoutMinutes"
|
||||
>
|
||||
<n-input-number
|
||||
v-model:value="mjSetting.remoteSetting.timeoutMinutes"
|
||||
:show-button="false"
|
||||
placeholder="请填写任务超时时间"
|
||||
:min="1"
|
||||
:max="20"
|
||||
></n-input-number>
|
||||
</n-form-item>
|
||||
</div>
|
||||
</n-form>
|
||||
</n-card>
|
||||
|
||||
<n-form-item label="用户token" style="width: 810px" path="token">
|
||||
<n-input v-model:value="mjSetting.token" placeholder="登录MJ后切换服务器自动获取" />
|
||||
</n-form-item>
|
||||
<n-form-item label="用户Agent" style="width: 810px" path="userAgent.userAgent">
|
||||
<n-input
|
||||
v-model:value="mjSetting.userAgent.userAgent"
|
||||
placeholder="登录MJ后切换服务器自动获取(可自定义)"
|
||||
style="margin-right: 10px"
|
||||
/>
|
||||
<n-tooltip trigger="hover" style="background-color: aliceblue; color: black">
|
||||
<template #trigger>
|
||||
<n-checkbox v-model:checked="mjSetting.userAgent.customize" style="width: 100px">
|
||||
自定义
|
||||
</n-checkbox>
|
||||
</template>
|
||||
开启自定义需要手动填写userAgent。可以填入浏览器的userAgent
|
||||
</n-tooltip>
|
||||
</n-form-item>
|
||||
<div style="display: flex; align-items: center">
|
||||
<n-form-item label="选择生图机器人" path="select_robot" style="width: 120px">
|
||||
<n-select
|
||||
:options="select_robot_options"
|
||||
v-model:value="mjSetting.select_robot"
|
||||
@update:value="UpdateSelectRobot"
|
||||
></n-select>
|
||||
</n-form-item>
|
||||
<n-form-item label="机器人模型" style="width: 120px; margin-left: 10px" path="image_scale">
|
||||
<n-select
|
||||
placeholder="请选择机器人模型"
|
||||
:options="image_model_options"
|
||||
v-model:value="mjSetting.image_model"
|
||||
></n-select>
|
||||
</n-form-item>
|
||||
<n-form-item label="生图尺寸" style="width: 120px; margin-left: 10px" path="image_scale">
|
||||
<n-select
|
||||
placeholder="请选择生图尺寸"
|
||||
:options="image_scale_options"
|
||||
v-model:value="mjSetting.image_scale"
|
||||
></n-select>
|
||||
</n-form-item>
|
||||
<n-form-item label="命令后缀" style="width: 160px; margin-left: 10px" path="image_suffix">
|
||||
<n-input v-model:value="image_suffix" placeholder="请输入后缀命令"></n-input>
|
||||
</n-form-item>
|
||||
<n-form-item label="生图任务量" style="width: 100px; margin-left: 10px" path="task_count">
|
||||
<n-input-number
|
||||
v-model:value="mjSetting.task_count"
|
||||
:show-button="false"
|
||||
placeholder="MJ并发出图数量"
|
||||
:min="1"
|
||||
:max="10"
|
||||
></n-input-number>
|
||||
</n-form-item>
|
||||
<n-form-item label="间隔时间(s)" style="width: 100px; margin-left: 10px" path="space_time">
|
||||
<n-input-number
|
||||
v-model:value="mjSetting.space_time"
|
||||
:show-button="false"
|
||||
placeholder="请输入间隔时间(s)"
|
||||
:min="1"
|
||||
:max="20"
|
||||
></n-input-number>
|
||||
</n-form-item>
|
||||
<n-card title="浏览器模式设置" hoverable style="margin-top: 10px; min-width: 850px">
|
||||
<n-form :model="mjSetting.browserSetting">
|
||||
<div style="display: flex; margin-top: 10px">
|
||||
<n-form-item>
|
||||
<n-button type="info" @click="OpenDiscordWindow">打开登录MJ</n-button>
|
||||
</n-form-item>
|
||||
<n-form-item label="服务器ID" style="width: 200px; margin-left: 5px" path="serviceId">
|
||||
<n-input
|
||||
v-model:value="mjSetting.browserSetting.serviceId"
|
||||
placeholder="登录MJ后切换服务器自动获取"
|
||||
/>
|
||||
</n-form-item>
|
||||
<n-form-item label="频道ID" style="width: 200px; margin-left: 10px" path="channelId">
|
||||
<n-input
|
||||
v-model:value="mjSetting.browserSetting.channelId"
|
||||
placeholder="登录MJ后切换频道自动获取"
|
||||
/>
|
||||
</n-form-item>
|
||||
<n-form-item label="用户token" style="width: 300px; margin-left: 10px" path="token">
|
||||
<n-input
|
||||
v-model:value="mjSetting.browserSetting.token"
|
||||
placeholder="登录MJ后切换服务器自动获取"
|
||||
/>
|
||||
</n-form-item>
|
||||
</div>
|
||||
<n-form-item label="用户Agent" style="width: 810px" path="userAgent">
|
||||
<n-input
|
||||
v-model:value="mjSetting.browserSetting.userAgent"
|
||||
placeholder="登录MJ后切换服务器自动获取(可自定义)"
|
||||
style="margin-right: 10px"
|
||||
/>
|
||||
<n-tooltip trigger="hover" style="background-color: aliceblue; color: black">
|
||||
<template #trigger>
|
||||
<n-checkbox
|
||||
v-model:checked="mjSetting.browserSetting.userAgentCustom"
|
||||
style="width: 100px"
|
||||
>
|
||||
自定义
|
||||
</n-checkbox>
|
||||
</template>
|
||||
开启自定义需要手动填写userAgent。可以填入浏览器的userAgent
|
||||
</n-tooltip>
|
||||
</n-form-item>
|
||||
</n-form>
|
||||
</n-card>
|
||||
<n-button type="info" round @click="SaveMjSetting" style="margin-top: 10px"
|
||||
>保存MJ配置</n-button
|
||||
>
|
||||
</div>
|
||||
|
||||
<div style="display: flex">
|
||||
<n-form-item label="出图模式" style="width: 150px" path="request_model">
|
||||
<n-select
|
||||
:options="request_model_options"
|
||||
v-model:value="mjSetting.request_model"
|
||||
placeholder="请选择出图模式"
|
||||
></n-select>
|
||||
</n-form-item>
|
||||
<n-form-item label="选择出图的API" style="width: 160px; margin-left: 10px" path="mj_api_url">
|
||||
<n-select
|
||||
:options="mj_api_options"
|
||||
v-model:value="mjSetting.mj_api_url"
|
||||
placeholder="选择出图的中转API"
|
||||
/>
|
||||
</n-form-item>
|
||||
<n-form-item style="margin-left: 10px" path="mj_api_url">
|
||||
<n-button type="success" @click="openGptBuyUrl">购买</n-button>
|
||||
</n-form-item>
|
||||
<n-form-item label="选择出图速度模式" style="width: 160px; margin-left: 10px" path="mj_speed">
|
||||
<n-select
|
||||
:options="mj_speed_options"
|
||||
v-model:value="mjSetting.mj_speed"
|
||||
placeholder="选择出图速度模式"
|
||||
/>
|
||||
</n-form-item>
|
||||
<n-form-item label="输入API密钥" style="width: 160px; margin-left: 10px" path="mj_speed">
|
||||
<n-input
|
||||
type="password"
|
||||
placeholder="请输入密钥"
|
||||
v-model:value="mjSetting.api_key"
|
||||
></n-input>
|
||||
</n-form-item>
|
||||
</div>
|
||||
</n-form>
|
||||
<template #description> 正在添加或同步MJ账号信息 </template>
|
||||
</n-spin>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { defineComponent, ref, onMounted, computed, toRaw } from 'vue'
|
||||
import { defineComponent, ref, onMounted, computed, toRaw, h } from 'vue'
|
||||
import {
|
||||
NButton,
|
||||
useMessage,
|
||||
useDialog,
|
||||
NDataTable,
|
||||
NForm,
|
||||
NFormItem,
|
||||
@ -157,11 +275,14 @@ import {
|
||||
NSelect,
|
||||
NTooltip,
|
||||
NIcon,
|
||||
NInputNumber
|
||||
NInputNumber,
|
||||
NCard,
|
||||
NSpin
|
||||
} from 'naive-ui'
|
||||
import { DEFINE_STRING } from '../../../../define/define_string'
|
||||
import { Reload } from '@vicons/ionicons5'
|
||||
import { isEmpty, max, min } from 'lodash'
|
||||
import { MJImageType } from '../../../../define/enum/mjEnum'
|
||||
export default defineComponent({
|
||||
components: {
|
||||
NButton,
|
||||
@ -175,11 +296,15 @@ export default defineComponent({
|
||||
NTooltip,
|
||||
NIcon,
|
||||
Reload,
|
||||
NInputNumber
|
||||
NInputNumber,
|
||||
NCard,
|
||||
NSpin
|
||||
},
|
||||
setup() {
|
||||
let message = useMessage()
|
||||
let formRef = ref(null)
|
||||
let dialog = useDialog()
|
||||
let sampleRef = ref(null)
|
||||
let show = ref(false)
|
||||
let select_robot_options = ref([
|
||||
{
|
||||
label: 'MJ',
|
||||
@ -203,35 +328,48 @@ export default defineComponent({
|
||||
])
|
||||
|
||||
let mjSetting = ref({
|
||||
serviceID: null,
|
||||
channelID: null,
|
||||
mj: {
|
||||
botId: null,
|
||||
commandId: null,
|
||||
commandName: null,
|
||||
versionId: null
|
||||
},
|
||||
niji: {
|
||||
botId: null,
|
||||
commandId: null,
|
||||
commandName: null,
|
||||
versionId: null
|
||||
},
|
||||
token: null,
|
||||
userAgent: {
|
||||
id: null,
|
||||
imageModel: null,
|
||||
imageScale: null,
|
||||
imageSuffix: null,
|
||||
requestModel: null,
|
||||
type: null,
|
||||
selectRobot: null,
|
||||
spaceTime: 6,
|
||||
taskCount: 3,
|
||||
createTime: null,
|
||||
updateTime: null,
|
||||
version: null,
|
||||
remoteSetting: {
|
||||
accountId: null,
|
||||
channelId: null,
|
||||
coreSize: 3,
|
||||
guildId: null,
|
||||
mjBotChannelId: null,
|
||||
nijiBotChannelId: null,
|
||||
queueSize: 6,
|
||||
remark: null, // 机器码
|
||||
remixAutoSubmit: false,
|
||||
timeoutMinutes: 6,
|
||||
userAgent: null,
|
||||
customize: false
|
||||
userToken: null
|
||||
},
|
||||
select_robot: null,
|
||||
image_scale: null,
|
||||
image_model: null,
|
||||
image_suffix: null,
|
||||
task_count: 3,
|
||||
space_time: 5,
|
||||
request_model: null,
|
||||
mj_api_url: null,
|
||||
mj_speed: null,
|
||||
api_key: null
|
||||
apiSetting: {
|
||||
id: null,
|
||||
mjApiUrl: null,
|
||||
mjSpeed: null,
|
||||
apiKey: null
|
||||
},
|
||||
browserSetting: {
|
||||
id: null,
|
||||
serviceId: null,
|
||||
channelId: null,
|
||||
mjBotId: null,
|
||||
nijBotId: null,
|
||||
token: null,
|
||||
userAgent: null,
|
||||
userAgentCustom: false
|
||||
}
|
||||
})
|
||||
|
||||
let image_scale_options = ref([])
|
||||
@ -241,42 +379,43 @@ export default defineComponent({
|
||||
let mj_api_options = ref([])
|
||||
|
||||
let image_suffix = computed(() => {
|
||||
|
||||
let text = image_model_options.value.findIndex((item) => {
|
||||
return item.value == mjSetting.value.image_model
|
||||
return item.value == mjSetting.value.imageModel
|
||||
})
|
||||
if (text == -1) {
|
||||
return
|
||||
}
|
||||
let sc = image_scale_options.value.findIndex((item) => {
|
||||
return item.value == mjSetting.value.image_scale
|
||||
return item.value == mjSetting.value.imageScale
|
||||
})
|
||||
let dd = ` --${image_model_options.value[text].text} --ar ${image_scale_options.value[sc].text}`
|
||||
mjSetting.value.image_suffix = dd
|
||||
mjSetting.value.imageSuffix = dd
|
||||
return dd
|
||||
})
|
||||
|
||||
// 初始化现在设置的数据
|
||||
async function InitData() {
|
||||
// 获取当前mj配置信息
|
||||
await window.api.GetDefineConfigJsonByProperty(
|
||||
JSON.stringify(['img_base', 'mj_config', false, null]),
|
||||
(value) => {
|
||||
debugger
|
||||
// 获取到的是当前的配置信息
|
||||
let res = await window.setting.GetMJSettingTreeData()
|
||||
if (res.code == 0) {
|
||||
message.error(res.message)
|
||||
return
|
||||
}
|
||||
|
||||
console.log(value)
|
||||
if (value.code == 0) {
|
||||
message.error(value.message)
|
||||
return
|
||||
}
|
||||
// 判断是不是有数据
|
||||
if (value.data) {
|
||||
mjSetting.value = Object.assign(mjSetting.value, value.data)
|
||||
if (mjSetting.value.select_robot != 'mj' && mjSetting.value.select_robot != 'niji') {
|
||||
mjSetting.value.select_robot = null
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
if (!res.data.apiSetting) {
|
||||
delete res.data.apiSetting
|
||||
}
|
||||
if (!res.data.remoteSetting) {
|
||||
delete res.data.remoteSetting
|
||||
}
|
||||
if (!res.data.browserSetting) {
|
||||
delete res.data.browserSetting
|
||||
}
|
||||
|
||||
mjSetting.value = Object.assign(mjSetting.value, res.data)
|
||||
|
||||
console.log(res)
|
||||
|
||||
await window.mj.GetMJImageScale((value) => {
|
||||
if (value.code == 0) {
|
||||
@ -284,8 +423,8 @@ export default defineComponent({
|
||||
return
|
||||
}
|
||||
image_scale_options.value = value.data
|
||||
if (image_scale_options.value.length > 0 && mjSetting.value.image_scale == null) {
|
||||
mjSetting.value.image_scale = image_scale_options.value[0].value
|
||||
if (image_scale_options.value.length > 0 && mjSetting.value.imageScale == null) {
|
||||
mjSetting.value.imageScale = image_scale_options.value[0].value
|
||||
}
|
||||
})
|
||||
|
||||
@ -296,8 +435,8 @@ export default defineComponent({
|
||||
}
|
||||
image_model_options.value = value.data
|
||||
tmp_image_model_options = value.data
|
||||
if (image_model_options.value.length > 0 && mjSetting.value.image_model == null) {
|
||||
mjSetting.value.image_model = image_model_options.value[0].value
|
||||
if (image_model_options.value.length > 0 && mjSetting.value.imageModel == null) {
|
||||
mjSetting.value.imageModel = image_model_options.value[0].value
|
||||
}
|
||||
})
|
||||
|
||||
@ -307,8 +446,8 @@ export default defineComponent({
|
||||
return
|
||||
}
|
||||
request_model_options.value = value.data.filter((item) => !item.disable)
|
||||
if (request_model_options.value.length > 0 && mjSetting.value.request_model == null) {
|
||||
mjSetting.value.request_model = request_model_options.value[0].value
|
||||
if (request_model_options.value.length > 0 && mjSetting.value.requestModel == null) {
|
||||
mjSetting.value.requestModel = request_model_options.value[0].value
|
||||
}
|
||||
})
|
||||
|
||||
@ -318,15 +457,16 @@ export default defineComponent({
|
||||
return
|
||||
}
|
||||
mj_api_options.value = value.data.filter((item) => item.mj_url)
|
||||
if (mj_api_options.value.length > 0 && mjSetting.value.mj_api_url == null) {
|
||||
mjSetting.value.mj_api_url = mj_api_options.value[0].value
|
||||
if (mj_api_options.value.length > 0 && mjSetting.value.apiSetting.mjApiUrl == null) {
|
||||
mjSetting.value.apiSetting.mjApiUrl = mj_api_options.value[0].value
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
// 监听修改当前界面的数据,后续可以将数据保存到本地配置
|
||||
// 监听浏览器设置的中信息
|
||||
window.api.setEventListen([DEFINE_STRING.DISCORD.OPERATE_REFRASH_DISCORD_URL], (value) => {
|
||||
debugger
|
||||
if (value.code == 0) {
|
||||
message.error(value.message)
|
||||
return
|
||||
@ -334,12 +474,12 @@ export default defineComponent({
|
||||
// 保存数据
|
||||
console.log(value)
|
||||
if (value.type == DEFINE_STRING.DISCORD_SIMPLE_DATA_TYPE.URL) {
|
||||
mjSetting.value.serviceID = value.data.serviceID
|
||||
mjSetting.value.channelID = value.data.channelID
|
||||
mjSetting.value.browserSetting.serviceId = value.data.serviceID
|
||||
mjSetting.value.browserSetting.channelId = value.data.channelID
|
||||
} else if (value.type == DEFINE_STRING.DISCORD_SIMPLE_DATA_TYPE.TOKEN) {
|
||||
mjSetting.value.token = value.data.authorization
|
||||
if (!mjSetting.value.userAgent.customize) {
|
||||
mjSetting.value.userAgent.userAgent = value.data.userAgent
|
||||
mjSetting.value.browserSetting.token = value.data.authorization
|
||||
if (!mjSetting.value.browserSetting.userAgentCustom) {
|
||||
mjSetting.value.browserSetting.userAgent = value.data.userAgent
|
||||
}
|
||||
} else {
|
||||
message.error('未知的数据类型')
|
||||
@ -348,8 +488,8 @@ export default defineComponent({
|
||||
|
||||
await InitData()
|
||||
|
||||
if (mjSetting.value.mj_speed == null) {
|
||||
mjSetting.value.mj_speed = mj_speed_options.value[0].value
|
||||
if (mjSetting.value.apiSetting.mjSpeed == null) {
|
||||
mjSetting.value.apiSetting.mjSpeed = mj_speed_options.value[0].value
|
||||
}
|
||||
})
|
||||
|
||||
@ -365,135 +505,98 @@ export default defineComponent({
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取频道机器人
|
||||
*/
|
||||
async function GetChannelRobots() {
|
||||
// 判断是不是有数据(服务器ID,频道ID,用户token,用户Agent)
|
||||
if (
|
||||
isEmpty(mjSetting.value.serviceID) &&
|
||||
isEmpty(mjSetting.value.channelID) &&
|
||||
isEmpty(mjSetting.value.token) &&
|
||||
isEmpty(mjSetting.value.userAgent.userAgent)
|
||||
) {
|
||||
message.error('请先填写或获取完整的数据(服务器ID,频道ID,用户token,用户Agent)')
|
||||
return
|
||||
}
|
||||
|
||||
const headers = {
|
||||
authorization: mjSetting.value.token
|
||||
}
|
||||
|
||||
await fetch(
|
||||
`https://discord.com/api/v9/guilds/${mjSetting.value.serviceID}/application-command-index`,
|
||||
{
|
||||
method: 'GET',
|
||||
headers: headers
|
||||
}
|
||||
)
|
||||
.then((response) => response.json())
|
||||
.then((data) => {
|
||||
|
||||
// 修改配置信息(判断是不是niji或者是mj)
|
||||
// 填充mj,niji数据
|
||||
if (data.applications && data.application_commands) {
|
||||
let mj_inedx = data.applications.findIndex((item) => {
|
||||
return item.name.toLowerCase().startsWith('midjourney')
|
||||
})
|
||||
if (mj.index != -1) {
|
||||
mjSetting.value.mj.botId = data.applications[mj_inedx].id
|
||||
let f = data.application_commands.find((a) => {
|
||||
return a.name == 'imagine' && a.application_id == data.applications[mj_inedx].id
|
||||
})
|
||||
mjSetting.value.mj.commandId = f?.id
|
||||
mjSetting.value.mj.commandName = 'imagine'
|
||||
mjSetting.value.mj.versionId = f?.version
|
||||
}
|
||||
|
||||
let niji_inedx = data.applications.findIndex((item) => {
|
||||
return item.name.toLowerCase().startsWith('niji')
|
||||
})
|
||||
if (mj.index != -1) {
|
||||
mjSetting.value.niji.botId = data.applications[niji_inedx].id
|
||||
let f = data.application_commands.find((a) => {
|
||||
return a.name == 'imagine' && a.application_id == data.applications[niji_inedx].id
|
||||
})
|
||||
mjSetting.value.niji.commandId = f?.id
|
||||
mjSetting.value.niji.commandName = 'imagine'
|
||||
mjSetting.value.niji.versionId = f?.version
|
||||
}
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
window.api.showGlobalNotificationDialog({
|
||||
code: 0,
|
||||
message: '获取频道机器人请求失败,错误信息如下: ' + error.message.toString()
|
||||
})
|
||||
return
|
||||
})
|
||||
// 基础配置的必填检测
|
||||
let sampleRules = {
|
||||
imageModel: [{ required: true, message: '请选择机器人模型', trigger: 'blur' }],
|
||||
imageScale: [{ required: true, message: '请选择生图尺寸', trigger: 'blur' }],
|
||||
requestModel: [{ required: true, message: '请选择出图模式', trigger: 'blur' }],
|
||||
selectRobot: [{ required: true, message: '请选择生图机器人', trigger: 'blur' }]
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存MJ配置
|
||||
*/
|
||||
async function SaveMjSetting(e) {
|
||||
// 在保存的时候要进行数据保存
|
||||
debugger
|
||||
e.preventDefault()
|
||||
formRef.value?.validate(async (errors) => {
|
||||
sampleRef.value?.validate(async (errors) => {
|
||||
if (errors) {
|
||||
message.error('请检查必填字段')
|
||||
return
|
||||
}
|
||||
mjSetting.value.image_suffix = image_suffix.value
|
||||
await window.api.SaveDefineConfigJsonByProperty(
|
||||
JSON.stringify(['img_base', 'mj_config', toRaw(mjSetting.value), false]),
|
||||
(value) => {
|
||||
mjSetting.value.imageSuffix = image_suffix.value
|
||||
|
||||
console.log(value)
|
||||
if (value.code == 0) {
|
||||
message.error(value.message)
|
||||
return
|
||||
}
|
||||
message.success(value.message)
|
||||
// 通过选择的请求模式判断哪些是要校验的
|
||||
let request_model = mjSetting.value.requestModel
|
||||
if (request_model == MJImageType.API_MJ) {
|
||||
// API模式,检查必填数据
|
||||
if (
|
||||
mjSetting.value.apiSetting == null ||
|
||||
mjSetting.value.apiSetting.mjApiUrl == null ||
|
||||
mjSetting.value.apiSetting.mjSpeed == null ||
|
||||
mjSetting.value.apiSetting.apiKey == null
|
||||
) {
|
||||
message.error('请检查API模式设置的必填字段')
|
||||
return
|
||||
}
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
let ruleObj = (errorMessage) => {
|
||||
return [
|
||||
{
|
||||
required: true,
|
||||
validator(rule, value) {
|
||||
if (value == null || value == '') return new Error(errorMessage)
|
||||
return true
|
||||
},
|
||||
trigger: ['input', 'blur', 'change']
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
let rules = {
|
||||
serviceID: ruleObj('必填服务器ID'),
|
||||
channelID: ruleObj('必填频道ID'),
|
||||
'mj.botId': ruleObj('必填MJ机器人ID'),
|
||||
'mj.commandId': ruleObj('必填MJ命令ID'),
|
||||
'mj.commandName': ruleObj('必填Mj命令名称'),
|
||||
'mj.versionId': ruleObj('必填MJ版本ID'),
|
||||
'niji.botId': ruleObj('必填NIJI机器人ID'),
|
||||
'niji.commandId': ruleObj('必填NIJI命令ID'),
|
||||
'niji.commandName': ruleObj('必填NIJI命令名称'),
|
||||
'niji.versionId': ruleObj('必填NIJI版本ID'),
|
||||
token: ruleObj('必填用户token'),
|
||||
'userAgent.userAgent': ruleObj('必填用户Agent'),
|
||||
select_robot: ruleObj('必填选择生图机器人'),
|
||||
image_scale: ruleObj('必填生图尺寸'),
|
||||
image_model: ruleObj('必填机器人模型'),
|
||||
image_suffix: ruleObj('必填命令后缀'),
|
||||
task_count: ruleObj('必填生图任务量'),
|
||||
space_time: ruleObj('必填间隔时间(s)'),
|
||||
request_model: ruleObj('必填出图模式'),
|
||||
mj_api_url: ruleObj('必填选择出图的API'),
|
||||
mj_speed: ruleObj('必填选择出图速度模式')
|
||||
if (request_model == MJImageType.REMOTE_MJ) {
|
||||
if (mjSetting.value.remoteSetting == null) {
|
||||
message.error('请先添加代理模式的配置')
|
||||
return
|
||||
}
|
||||
|
||||
// if (mjSetting.value.remoteSetting.accountId == null) {
|
||||
// message.error('请先同步账号')
|
||||
// return
|
||||
// }
|
||||
|
||||
// 代理模式,检查必填数据
|
||||
if (
|
||||
mjSetting.value.remoteSetting == null ||
|
||||
mjSetting.value.remoteSetting.guildId == null ||
|
||||
mjSetting.value.remoteSetting.channelId == null ||
|
||||
mjSetting.value.remoteSetting.userToken == null ||
|
||||
mjSetting.value.remoteSetting.userAgent == null
|
||||
) {
|
||||
message.error('请检查代理模式设置的必填字段')
|
||||
return
|
||||
}
|
||||
}
|
||||
if (request_model == MJImageType.BROWSER_MJ) {
|
||||
// 浏览器模式,检查必填数据
|
||||
if (
|
||||
mjSetting.value.browserSetting == null ||
|
||||
mjSetting.value.browserSetting.serviceId == null ||
|
||||
mjSetting.value.browserSetting.channelId == null ||
|
||||
mjSetting.value.browserSetting.token == null ||
|
||||
mjSetting.value.browserSetting.userAgent == null
|
||||
) {
|
||||
message.error('请检查浏览器模式设置的必填字段')
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// 开始保存数据
|
||||
let res = await window.setting.SaveMJSettingTreeData(toRaw(mjSetting.value))
|
||||
if (res.code == 0) {
|
||||
window.api.showGlobalMessageDialog({ code: 0, message: res.message })
|
||||
return
|
||||
}
|
||||
mjSetting.value = res.data
|
||||
// 判断当前的模式
|
||||
if (mjSetting.value.requestModel == MJImageType.REMOTE_MJ) {
|
||||
window.api.showGlobalMessageDialog({
|
||||
code: 1,
|
||||
message: `数据保存成功,
|
||||
当前生图模式为代理模式,若有修改配置请手动同步账号数据,但是不要频繁同步,有封号风险 `
|
||||
})
|
||||
} else {
|
||||
window.api.showGlobalMessageDialog({ code: 1, message: '添加成功' })
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
@ -508,10 +611,10 @@ export default defineComponent({
|
||||
// 判断当前选中的机器人是不是在当前的数据中
|
||||
if (
|
||||
image_model_options.value.findIndex((item) => {
|
||||
return item.value == mjSetting.value.image_model
|
||||
return item.value == mjSetting.value.imageModel
|
||||
}) == -1
|
||||
) {
|
||||
mjSetting.value.image_model =
|
||||
mjSetting.value.imageModel =
|
||||
image_model_options.value.length > 0 ? image_model_options.value[0].value : null
|
||||
}
|
||||
}
|
||||
@ -520,8 +623,9 @@ export default defineComponent({
|
||||
* 打开购买GPT的地址
|
||||
*/
|
||||
async function openGptBuyUrl() {
|
||||
|
||||
let tmp_gb = mj_api_options.value.filter((item) => item.value == mjSetting.value.mj_api_url)
|
||||
let tmp_gb = mj_api_options.value.filter(
|
||||
(item) => item.value == mjSetting.value.apiSetting.mjApiUrl
|
||||
)
|
||||
if (tmp_gb.length == 0) {
|
||||
message.error('当前选择的服务商没有购买地址!')
|
||||
return
|
||||
@ -534,14 +638,59 @@ export default defineComponent({
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 账号同步
|
||||
*/
|
||||
async function AccountSync() {
|
||||
dialog.warning({
|
||||
title: '警告',
|
||||
content: () =>
|
||||
h('div', {}, [
|
||||
h(
|
||||
'span',
|
||||
{},
|
||||
{
|
||||
default: () => '同步数据的信息是保存后的数据'
|
||||
}
|
||||
),
|
||||
h('br'),
|
||||
h(
|
||||
'span',
|
||||
{ style: 'color : red;font-size : 18px' },
|
||||
{
|
||||
default: () => '修改数据后请先保存,请先保存再执行同步操作'
|
||||
}
|
||||
),
|
||||
h('br'),
|
||||
h(
|
||||
'span',
|
||||
{},
|
||||
{
|
||||
default: () => '同步操作不要频繁,有封号风险'
|
||||
}
|
||||
)
|
||||
]),
|
||||
positiveText: '确定',
|
||||
negativeText: '取消',
|
||||
onPositiveClick: async () => {
|
||||
show.value = true
|
||||
let res = await window.setting.MjRemoteAccountSync()
|
||||
show.value = false
|
||||
if (res.code == 0) {
|
||||
message.error(res.message)
|
||||
return
|
||||
}
|
||||
message.success('MJ账号同步成功,可以开始使用')
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
return {
|
||||
OpenDiscordWindow,
|
||||
mjSetting,
|
||||
select_robot_options,
|
||||
GetChannelRobots,
|
||||
SaveMjSetting,
|
||||
rules,
|
||||
formRef,
|
||||
sampleRef,
|
||||
image_scale_options,
|
||||
image_model_options,
|
||||
UpdateSelectRobot,
|
||||
@ -549,7 +698,10 @@ export default defineComponent({
|
||||
request_model_options,
|
||||
mj_api_options,
|
||||
mj_speed_options,
|
||||
openGptBuyUrl
|
||||
openGptBuyUrl,
|
||||
sampleRules,
|
||||
AccountSync,
|
||||
show
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
@ -198,6 +198,7 @@ import AddGptOption from './Components/AddGptOption.vue'
|
||||
import { FolderOpenSharp as FolderOpen } from '@vicons/ionicons5'
|
||||
import AddGptPrompts from './Components/AddGptPrompts.vue'
|
||||
import { isEmpty } from 'lodash'
|
||||
import { useSoftwareStore } from '../../../../stores/software'
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
@ -216,6 +217,7 @@ export default defineComponent({
|
||||
},
|
||||
setup() {
|
||||
let formRef = ref(null)
|
||||
let softwareStore = useSoftwareStore()
|
||||
let message = useMessage()
|
||||
let formValue = ref({
|
||||
draft_path: window.config.draft_path,
|
||||
@ -230,7 +232,7 @@ export default defineComponent({
|
||||
translation_app_id: window.config.translation_app_id,
|
||||
translation_secret: window.config.translation_secret,
|
||||
translation_auto: window.config.translation_auto,
|
||||
theme: window.config.theme,
|
||||
theme: softwareStore.softWare.theme,
|
||||
character_select_model: window.config.character_select_model,
|
||||
window_wh_bm_remember: window.config.window_wh_bm_remember
|
||||
})
|
||||
@ -240,12 +242,10 @@ export default defineComponent({
|
||||
let character_select_model_options = ref([])
|
||||
let dialog = useDialog()
|
||||
let loading = ref(false)
|
||||
|
||||
/**
|
||||
* 加载GPT的配置信息
|
||||
*/
|
||||
async function InitGptOptions() {
|
||||
|
||||
await window.api.getGptBusinessOption('all', (value) => {
|
||||
if (value.code == 0) {
|
||||
message.error(value.message)
|
||||
@ -327,9 +327,9 @@ export default defineComponent({
|
||||
/**
|
||||
* 保存配置信息
|
||||
*/
|
||||
function handleValidateButtonClick(e) {
|
||||
async function handleValidateButtonClick(e) {
|
||||
e.preventDefault()
|
||||
formRef.value?.validate((errors) => {
|
||||
formRef.value?.validate(async (errors) => {
|
||||
if (errors) {
|
||||
message.error('请检查必填字段')
|
||||
return
|
||||
@ -345,6 +345,8 @@ export default defineComponent({
|
||||
window.api.showGlobalMessageDialog({ code: 0, message: value.message })
|
||||
}
|
||||
})
|
||||
softwareStore.SetSoftware({ theme: formValue.value.theme })
|
||||
await softwareStore.SaveSoftware()
|
||||
})
|
||||
}
|
||||
|
||||
@ -368,7 +370,6 @@ export default defineComponent({
|
||||
* 打开购买GPT的地址
|
||||
*/
|
||||
async function openGptBuyUrl() {
|
||||
|
||||
let tmp_gb = gpt_options.value.filter((item) => item.value == formValue.value.gpt_business)
|
||||
if (tmp_gb.length == 0) {
|
||||
message.error('当前选择的服务商没有购买地址!')
|
||||
@ -387,7 +388,6 @@ export default defineComponent({
|
||||
* @param {*} value 主题名称
|
||||
*/
|
||||
async function ChangeMode(value) {
|
||||
|
||||
console.log(value)
|
||||
const isDarkMode = await window.darkMode.toggle(value)
|
||||
}
|
||||
@ -486,7 +486,8 @@ export default defineComponent({
|
||||
loading,
|
||||
SelectProjectFolder,
|
||||
AddGptPrompt,
|
||||
character_select_model_options
|
||||
character_select_model_options,
|
||||
softwareStore
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
@ -26,6 +26,8 @@ const routes = [
|
||||
{ path: "/ShowMessage", name: "ShowMessage", component: () => import('./components/Home/ShowMessage.vue') },
|
||||
{ path: "/sdoriginal", name: "sdoriginal", component: () => import('./components/Original/MainPage.vue') },
|
||||
{ path: "/mj_setting", name: "mj_setting", component: () => import('./components/Setting/MJSetting.vue') },
|
||||
{ path: '/reverse_management', name: "reverse_management", component: () => import('./components/ReverseManage/ReverseManage.vue') },
|
||||
{ path: '/manage_book/:id', name: "manage_book", component: () => import('./components/ReverseManage/ManageBookDetail.vue') },
|
||||
]
|
||||
},
|
||||
{ path: "/ReDrawImage", component: () => import('./components/Home/ReDrawImageWD.vue'), },
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user