V2.2.4 版本
This commit is contained in:
parent
74009113fa
commit
17709c1a0b
1
.gitignore
vendored
1
.gitignore
vendored
@ -5,6 +5,7 @@ resources/scripts/build*
|
|||||||
resources/scripts/dist
|
resources/scripts/dist
|
||||||
resources/scripts/model
|
resources/scripts/model
|
||||||
resources/scripts/Temp
|
resources/scripts/Temp
|
||||||
|
resources/image/Temp*
|
||||||
resources/package/ffmpeg*
|
resources/package/ffmpeg*
|
||||||
resources/config*
|
resources/config*
|
||||||
*Lai.exe*
|
*Lai.exe*
|
||||||
|
|||||||
@ -5,9 +5,7 @@ import Jsx from '@vitejs/plugin-vue-jsx'
|
|||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
main: {
|
main: {
|
||||||
plugins: [externalizeDepsPlugin(), bytecodePlugin({
|
plugins: [externalizeDepsPlugin(), bytecodePlugin()]
|
||||||
exclude: ['src/main/discord/discordScript.js']
|
|
||||||
})]
|
|
||||||
},
|
},
|
||||||
discord: {
|
discord: {
|
||||||
plugins: [externalizeDepsPlugin(), bytecodePlugin()]
|
plugins: [externalizeDepsPlugin(), bytecodePlugin()]
|
||||||
|
|||||||
261
package-lock.json
generated
261
package-lock.json
generated
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "laitool",
|
"name": "laitool",
|
||||||
"version": "2.2.2",
|
"version": "2.2.4",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
@ -21,6 +21,7 @@
|
|||||||
"axios": "^1.6.5",
|
"axios": "^1.6.5",
|
||||||
"compressing": "^1.10.0",
|
"compressing": "^1.10.0",
|
||||||
"crypto-js": "^4.2.0",
|
"crypto-js": "^4.2.0",
|
||||||
|
"electron-store": "^9.0.0",
|
||||||
"electron-updater": "^6.1.7",
|
"electron-updater": "^6.1.7",
|
||||||
"fluent-ffmpeg": "^2.1.2",
|
"fluent-ffmpeg": "^2.1.2",
|
||||||
"highlight.js": "^11.9.0",
|
"highlight.js": "^11.9.0",
|
||||||
@ -2548,7 +2549,9 @@
|
|||||||
},
|
},
|
||||||
"node_modules/abbrev": {
|
"node_modules/abbrev": {
|
||||||
"version": "1.1.1",
|
"version": "1.1.1",
|
||||||
"license": "ISC"
|
"license": "ISC",
|
||||||
|
"optional": true,
|
||||||
|
"peer": true
|
||||||
},
|
},
|
||||||
"node_modules/acorn": {
|
"node_modules/acorn": {
|
||||||
"version": "8.11.3",
|
"version": "8.11.3",
|
||||||
@ -2594,6 +2597,42 @@
|
|||||||
"url": "https://github.com/sponsors/epoberezkin"
|
"url": "https://github.com/sponsors/epoberezkin"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/ajv-formats": {
|
||||||
|
"version": "2.1.1",
|
||||||
|
"resolved": "https://registry.npmmirror.com/ajv-formats/-/ajv-formats-2.1.1.tgz",
|
||||||
|
"integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==",
|
||||||
|
"dependencies": {
|
||||||
|
"ajv": "^8.0.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"ajv": "^8.0.0"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"ajv": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/ajv-formats/node_modules/ajv": {
|
||||||
|
"version": "8.13.0",
|
||||||
|
"resolved": "https://registry.npmmirror.com/ajv/-/ajv-8.13.0.tgz",
|
||||||
|
"integrity": "sha512-PRA911Blj99jR5RMeTunVbNXMF6Lp4vZXnk5GQjcnUWUTsrXtekg/pnmFFI2u/I36Y/2bITGS30GZCXei6uNkA==",
|
||||||
|
"dependencies": {
|
||||||
|
"fast-deep-equal": "^3.1.3",
|
||||||
|
"json-schema-traverse": "^1.0.0",
|
||||||
|
"require-from-string": "^2.0.2",
|
||||||
|
"uri-js": "^4.4.1"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/epoberezkin"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/ajv-formats/node_modules/json-schema-traverse": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmmirror.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug=="
|
||||||
|
},
|
||||||
"node_modules/ajv-keywords": {
|
"node_modules/ajv-keywords": {
|
||||||
"version": "3.5.2",
|
"version": "3.5.2",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
@ -2612,6 +2651,7 @@
|
|||||||
},
|
},
|
||||||
"node_modules/ansi-styles": {
|
"node_modules/ansi-styles": {
|
||||||
"version": "4.3.0",
|
"version": "4.3.0",
|
||||||
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"color-convert": "^2.0.1"
|
"color-convert": "^2.0.1"
|
||||||
@ -2894,6 +2934,15 @@
|
|||||||
"node": ">= 4.0.0"
|
"node": ">= 4.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/atomically": {
|
||||||
|
"version": "2.0.3",
|
||||||
|
"resolved": "https://registry.npmmirror.com/atomically/-/atomically-2.0.3.tgz",
|
||||||
|
"integrity": "sha512-kU6FmrwZ3Lx7/7y3hPS5QnbJfaohcIul5fGqf7ok+4KklIEk9tJ0C2IQPdacSbVUWv6zVHXEBWoWd6NrVMT7Cw==",
|
||||||
|
"dependencies": {
|
||||||
|
"stubborn-fs": "^1.2.5",
|
||||||
|
"when-exit": "^2.1.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/awesome-js": {
|
"node_modules/awesome-js": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmmirror.com/awesome-js/-/awesome-js-2.0.0.tgz",
|
"resolved": "https://registry.npmmirror.com/awesome-js/-/awesome-js-2.0.0.tgz",
|
||||||
@ -2914,6 +2963,7 @@
|
|||||||
},
|
},
|
||||||
"node_modules/balanced-match": {
|
"node_modules/balanced-match": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
|
"devOptional": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/base64-js": {
|
"node_modules/base64-js": {
|
||||||
@ -3014,6 +3064,7 @@
|
|||||||
},
|
},
|
||||||
"node_modules/brace-expansion": {
|
"node_modules/brace-expansion": {
|
||||||
"version": "2.0.1",
|
"version": "2.0.1",
|
||||||
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"balanced-match": "^1.0.0"
|
"balanced-match": "^1.0.0"
|
||||||
@ -3272,6 +3323,7 @@
|
|||||||
},
|
},
|
||||||
"node_modules/chalk": {
|
"node_modules/chalk": {
|
||||||
"version": "4.1.2",
|
"version": "4.1.2",
|
||||||
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"ansi-styles": "^4.1.0",
|
"ansi-styles": "^4.1.0",
|
||||||
@ -3286,6 +3338,7 @@
|
|||||||
},
|
},
|
||||||
"node_modules/chownr": {
|
"node_modules/chownr": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
|
"devOptional": true,
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=10"
|
"node": ">=10"
|
||||||
@ -3298,6 +3351,7 @@
|
|||||||
},
|
},
|
||||||
"node_modules/ci-info": {
|
"node_modules/ci-info": {
|
||||||
"version": "3.9.0",
|
"version": "3.9.0",
|
||||||
|
"dev": true,
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
"type": "github",
|
"type": "github",
|
||||||
@ -3455,8 +3509,73 @@
|
|||||||
},
|
},
|
||||||
"node_modules/concat-map": {
|
"node_modules/concat-map": {
|
||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
|
"devOptional": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/conf": {
|
||||||
|
"version": "12.0.0",
|
||||||
|
"resolved": "https://registry.npmmirror.com/conf/-/conf-12.0.0.tgz",
|
||||||
|
"integrity": "sha512-fIWyWUXrJ45cHCIQX+Ck1hrZDIf/9DR0P0Zewn3uNht28hbt5OfGUq8rRWsxi96pZWPyBEd0eY9ama01JTaknA==",
|
||||||
|
"dependencies": {
|
||||||
|
"ajv": "^8.12.0",
|
||||||
|
"ajv-formats": "^2.1.1",
|
||||||
|
"atomically": "^2.0.2",
|
||||||
|
"debounce-fn": "^5.1.2",
|
||||||
|
"dot-prop": "^8.0.2",
|
||||||
|
"env-paths": "^3.0.0",
|
||||||
|
"json-schema-typed": "^8.0.1",
|
||||||
|
"semver": "^7.5.4",
|
||||||
|
"uint8array-extras": "^0.3.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/conf/node_modules/ajv": {
|
||||||
|
"version": "8.13.0",
|
||||||
|
"resolved": "https://registry.npmmirror.com/ajv/-/ajv-8.13.0.tgz",
|
||||||
|
"integrity": "sha512-PRA911Blj99jR5RMeTunVbNXMF6Lp4vZXnk5GQjcnUWUTsrXtekg/pnmFFI2u/I36Y/2bITGS30GZCXei6uNkA==",
|
||||||
|
"dependencies": {
|
||||||
|
"fast-deep-equal": "^3.1.3",
|
||||||
|
"json-schema-traverse": "^1.0.0",
|
||||||
|
"require-from-string": "^2.0.2",
|
||||||
|
"uri-js": "^4.4.1"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/epoberezkin"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/conf/node_modules/env-paths": {
|
||||||
|
"version": "3.0.0",
|
||||||
|
"resolved": "https://registry.npmmirror.com/env-paths/-/env-paths-3.0.0.tgz",
|
||||||
|
"integrity": "sha512-dtJUTepzMW3Lm/NPxRf3wP4642UWhjL2sQxc+ym2YMj1m/H2zDNQOlezafzkHwn6sMstjHTwG6iQQsctDW/b1A==",
|
||||||
|
"engines": {
|
||||||
|
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/conf/node_modules/json-schema-traverse": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmmirror.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug=="
|
||||||
|
},
|
||||||
|
"node_modules/conf/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/config-file-ts": {
|
"node_modules/config-file-ts": {
|
||||||
"version": "0.2.6",
|
"version": "0.2.6",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
@ -3676,6 +3795,20 @@
|
|||||||
"version": "1.11.10",
|
"version": "1.11.10",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/debounce-fn": {
|
||||||
|
"version": "5.1.2",
|
||||||
|
"resolved": "https://registry.npmmirror.com/debounce-fn/-/debounce-fn-5.1.2.tgz",
|
||||||
|
"integrity": "sha512-Sr4SdOZ4vw6eQDvPYNxHogvrxmCIld/VenC5JbNrFwMiwd7lY/Z18ZFfo+EWNG4DD9nFlAujWAo/wGuOPHmy5A==",
|
||||||
|
"dependencies": {
|
||||||
|
"mimic-fn": "^4.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/debug": {
|
"node_modules/debug": {
|
||||||
"version": "4.3.4",
|
"version": "4.3.4",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
@ -3887,6 +4020,31 @@
|
|||||||
"node_modules/dom-walk": {
|
"node_modules/dom-walk": {
|
||||||
"version": "0.1.2"
|
"version": "0.1.2"
|
||||||
},
|
},
|
||||||
|
"node_modules/dot-prop": {
|
||||||
|
"version": "8.0.2",
|
||||||
|
"resolved": "https://registry.npmmirror.com/dot-prop/-/dot-prop-8.0.2.tgz",
|
||||||
|
"integrity": "sha512-xaBe6ZT4DHPkg0k4Ytbvn5xoxgpG0jOS1dYxSOwAHPuNLjP3/OzN0gH55SrLqpx8cBfSaVt91lXYkApjb+nYdQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"type-fest": "^3.8.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=16"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/dot-prop/node_modules/type-fest": {
|
||||||
|
"version": "3.13.1",
|
||||||
|
"resolved": "https://registry.npmmirror.com/type-fest/-/type-fest-3.13.1.tgz",
|
||||||
|
"integrity": "sha512-tLq3bSNx+xSpwvAJnzrK0Ep5CLNWjvFTOp71URMaAEWBfRb9nnJiBoUe0tF8bI4ZFO3omgBR6NvnbzVUT3Ly4g==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=14.16"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/dotenv": {
|
"node_modules/dotenv": {
|
||||||
"version": "9.0.2",
|
"version": "9.0.2",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
@ -4109,6 +4267,32 @@
|
|||||||
"node": ">= 10.0.0"
|
"node": ">= 10.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/electron-store": {
|
||||||
|
"version": "9.0.0",
|
||||||
|
"resolved": "https://registry.npmmirror.com/electron-store/-/electron-store-9.0.0.tgz",
|
||||||
|
"integrity": "sha512-7LZ2dR3N3bF93G2c4x+1NZ/8fpsKv6bKrMxeOQWLqdRbxvopxVqy9QXQy9axSV2O3P1kVGTj1q2wq5/W4isiOg==",
|
||||||
|
"dependencies": {
|
||||||
|
"conf": "^12.0.0",
|
||||||
|
"type-fest": "^4.18.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=20"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/electron-store/node_modules/type-fest": {
|
||||||
|
"version": "4.18.2",
|
||||||
|
"resolved": "https://registry.npmmirror.com/type-fest/-/type-fest-4.18.2.tgz",
|
||||||
|
"integrity": "sha512-+suCYpfJLAe4OXS6+PPXjW3urOS4IoP9waSiLuXfLgqZODKw/aWwASvzqE886wA0kQgGy0mIWyhd87VpqIy6Xg==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=16"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/electron-to-chromium": {
|
"node_modules/electron-to-chromium": {
|
||||||
"version": "1.4.628",
|
"version": "1.4.628",
|
||||||
"license": "ISC"
|
"license": "ISC"
|
||||||
@ -4615,7 +4799,6 @@
|
|||||||
},
|
},
|
||||||
"node_modules/fast-deep-equal": {
|
"node_modules/fast-deep-equal": {
|
||||||
"version": "3.1.3",
|
"version": "3.1.3",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/fast-diff": {
|
"node_modules/fast-diff": {
|
||||||
@ -4810,6 +4993,7 @@
|
|||||||
},
|
},
|
||||||
"node_modules/fs-minipass": {
|
"node_modules/fs-minipass": {
|
||||||
"version": "2.1.0",
|
"version": "2.1.0",
|
||||||
|
"devOptional": true,
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"minipass": "^3.0.0"
|
"minipass": "^3.0.0"
|
||||||
@ -4820,6 +5004,7 @@
|
|||||||
},
|
},
|
||||||
"node_modules/fs-minipass/node_modules/minipass": {
|
"node_modules/fs-minipass/node_modules/minipass": {
|
||||||
"version": "3.3.6",
|
"version": "3.3.6",
|
||||||
|
"devOptional": true,
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"yallist": "^4.0.0"
|
"yallist": "^4.0.0"
|
||||||
@ -4830,10 +5015,12 @@
|
|||||||
},
|
},
|
||||||
"node_modules/fs-minipass/node_modules/yallist": {
|
"node_modules/fs-minipass/node_modules/yallist": {
|
||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
|
"devOptional": true,
|
||||||
"license": "ISC"
|
"license": "ISC"
|
||||||
},
|
},
|
||||||
"node_modules/fs.realpath": {
|
"node_modules/fs.realpath": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
|
"devOptional": true,
|
||||||
"license": "ISC"
|
"license": "ISC"
|
||||||
},
|
},
|
||||||
"node_modules/function-bind": {
|
"node_modules/function-bind": {
|
||||||
@ -4926,6 +5113,7 @@
|
|||||||
},
|
},
|
||||||
"node_modules/glob": {
|
"node_modules/glob": {
|
||||||
"version": "7.2.3",
|
"version": "7.2.3",
|
||||||
|
"devOptional": true,
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"fs.realpath": "^1.0.0",
|
"fs.realpath": "^1.0.0",
|
||||||
@ -4955,6 +5143,7 @@
|
|||||||
},
|
},
|
||||||
"node_modules/glob/node_modules/brace-expansion": {
|
"node_modules/glob/node_modules/brace-expansion": {
|
||||||
"version": "1.1.11",
|
"version": "1.1.11",
|
||||||
|
"devOptional": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"balanced-match": "^1.0.0",
|
"balanced-match": "^1.0.0",
|
||||||
@ -4963,6 +5152,7 @@
|
|||||||
},
|
},
|
||||||
"node_modules/glob/node_modules/minimatch": {
|
"node_modules/glob/node_modules/minimatch": {
|
||||||
"version": "3.1.2",
|
"version": "3.1.2",
|
||||||
|
"devOptional": true,
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"brace-expansion": "^1.1.7"
|
"brace-expansion": "^1.1.7"
|
||||||
@ -5091,6 +5281,7 @@
|
|||||||
},
|
},
|
||||||
"node_modules/has-flag": {
|
"node_modules/has-flag": {
|
||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
@ -5155,6 +5346,7 @@
|
|||||||
},
|
},
|
||||||
"node_modules/hosted-git-info": {
|
"node_modules/hosted-git-info": {
|
||||||
"version": "4.1.0",
|
"version": "4.1.0",
|
||||||
|
"dev": true,
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"lru-cache": "^6.0.0"
|
"lru-cache": "^6.0.0"
|
||||||
@ -5165,6 +5357,7 @@
|
|||||||
},
|
},
|
||||||
"node_modules/hosted-git-info/node_modules/lru-cache": {
|
"node_modules/hosted-git-info/node_modules/lru-cache": {
|
||||||
"version": "6.0.0",
|
"version": "6.0.0",
|
||||||
|
"dev": true,
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"yallist": "^4.0.0"
|
"yallist": "^4.0.0"
|
||||||
@ -5175,6 +5368,7 @@
|
|||||||
},
|
},
|
||||||
"node_modules/hosted-git-info/node_modules/yallist": {
|
"node_modules/hosted-git-info/node_modules/yallist": {
|
||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
|
"dev": true,
|
||||||
"license": "ISC"
|
"license": "ISC"
|
||||||
},
|
},
|
||||||
"node_modules/html-encoding-sniffer": {
|
"node_modules/html-encoding-sniffer": {
|
||||||
@ -5334,6 +5528,7 @@
|
|||||||
},
|
},
|
||||||
"node_modules/inflight": {
|
"node_modules/inflight": {
|
||||||
"version": "1.0.6",
|
"version": "1.0.6",
|
||||||
|
"devOptional": true,
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"once": "^1.3.0",
|
"once": "^1.3.0",
|
||||||
@ -5680,6 +5875,11 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/json-schema-typed": {
|
||||||
|
"version": "8.0.1",
|
||||||
|
"resolved": "https://registry.npmmirror.com/json-schema-typed/-/json-schema-typed-8.0.1.tgz",
|
||||||
|
"integrity": "sha512-XQmWYj2Sm4kn4WeTYvmpKEbyPsL7nBsb647c7pMe6l02/yx2+Jfc4dT6UZkEXnIUb5LhD55r2HPsJ1milQ4rDg=="
|
||||||
|
},
|
||||||
"node_modules/json-stable-stringify-without-jsonify": {
|
"node_modules/json-stable-stringify-without-jsonify": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
@ -6017,6 +6217,17 @@
|
|||||||
"node": ">= 0.6"
|
"node": ">= 0.6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/mimic-fn": {
|
||||||
|
"version": "4.0.0",
|
||||||
|
"resolved": "https://registry.npmmirror.com/mimic-fn/-/mimic-fn-4.0.0.tgz",
|
||||||
|
"integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/mimic-response": {
|
"node_modules/mimic-response": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
@ -6032,6 +6243,7 @@
|
|||||||
},
|
},
|
||||||
"node_modules/minimatch": {
|
"node_modules/minimatch": {
|
||||||
"version": "5.1.6",
|
"version": "5.1.6",
|
||||||
|
"dev": true,
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"brace-expansion": "^2.0.1"
|
"brace-expansion": "^2.0.1"
|
||||||
@ -6049,6 +6261,7 @@
|
|||||||
},
|
},
|
||||||
"node_modules/minipass": {
|
"node_modules/minipass": {
|
||||||
"version": "5.0.0",
|
"version": "5.0.0",
|
||||||
|
"devOptional": true,
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
@ -6056,6 +6269,7 @@
|
|||||||
},
|
},
|
||||||
"node_modules/minizlib": {
|
"node_modules/minizlib": {
|
||||||
"version": "2.1.2",
|
"version": "2.1.2",
|
||||||
|
"devOptional": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"minipass": "^3.0.0",
|
"minipass": "^3.0.0",
|
||||||
@ -6067,6 +6281,7 @@
|
|||||||
},
|
},
|
||||||
"node_modules/minizlib/node_modules/minipass": {
|
"node_modules/minizlib/node_modules/minipass": {
|
||||||
"version": "3.3.6",
|
"version": "3.3.6",
|
||||||
|
"devOptional": true,
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"yallist": "^4.0.0"
|
"yallist": "^4.0.0"
|
||||||
@ -6077,10 +6292,12 @@
|
|||||||
},
|
},
|
||||||
"node_modules/minizlib/node_modules/yallist": {
|
"node_modules/minizlib/node_modules/yallist": {
|
||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
|
"devOptional": true,
|
||||||
"license": "ISC"
|
"license": "ISC"
|
||||||
},
|
},
|
||||||
"node_modules/mkdirp": {
|
"node_modules/mkdirp": {
|
||||||
"version": "1.0.4",
|
"version": "1.0.4",
|
||||||
|
"devOptional": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"bin": {
|
"bin": {
|
||||||
"mkdirp": "bin/cmd.js"
|
"mkdirp": "bin/cmd.js"
|
||||||
@ -6219,6 +6436,8 @@
|
|||||||
"node_modules/nopt": {
|
"node_modules/nopt": {
|
||||||
"version": "5.0.0",
|
"version": "5.0.0",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
|
"optional": true,
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"abbrev": "1"
|
"abbrev": "1"
|
||||||
},
|
},
|
||||||
@ -8839,6 +9058,7 @@
|
|||||||
},
|
},
|
||||||
"node_modules/path-is-absolute": {
|
"node_modules/path-is-absolute": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
|
"devOptional": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
@ -9198,6 +9418,14 @@
|
|||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/require-from-string": {
|
||||||
|
"version": "2.0.2",
|
||||||
|
"resolved": "https://registry.npmmirror.com/require-from-string/-/require-from-string-2.0.2.tgz",
|
||||||
|
"integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.10.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/requires-port": {
|
"node_modules/requires-port": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
@ -9736,6 +9964,11 @@
|
|||||||
"url": "https://github.com/sponsors/Borewit"
|
"url": "https://github.com/sponsors/Borewit"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/stubborn-fs": {
|
||||||
|
"version": "1.2.5",
|
||||||
|
"resolved": "https://registry.npmmirror.com/stubborn-fs/-/stubborn-fs-1.2.5.tgz",
|
||||||
|
"integrity": "sha512-H2N9c26eXjzL/S/K+i/RHHcFanE74dptvvjM8iwzwbVcWY/zjBbgRqF3K0DY4+OD+uTTASTBvDoxPDaPN02D7g=="
|
||||||
|
},
|
||||||
"node_modules/sumchecker": {
|
"node_modules/sumchecker": {
|
||||||
"version": "3.0.1",
|
"version": "3.0.1",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
@ -9748,6 +9981,7 @@
|
|||||||
},
|
},
|
||||||
"node_modules/supports-color": {
|
"node_modules/supports-color": {
|
||||||
"version": "7.2.0",
|
"version": "7.2.0",
|
||||||
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"has-flag": "^4.0.0"
|
"has-flag": "^4.0.0"
|
||||||
@ -9780,6 +10014,7 @@
|
|||||||
},
|
},
|
||||||
"node_modules/tar": {
|
"node_modules/tar": {
|
||||||
"version": "6.2.0",
|
"version": "6.2.0",
|
||||||
|
"devOptional": true,
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"chownr": "^2.0.0",
|
"chownr": "^2.0.0",
|
||||||
@ -9835,6 +10070,7 @@
|
|||||||
},
|
},
|
||||||
"node_modules/tar/node_modules/yallist": {
|
"node_modules/tar/node_modules/yallist": {
|
||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
|
"devOptional": true,
|
||||||
"license": "ISC"
|
"license": "ISC"
|
||||||
},
|
},
|
||||||
"node_modules/temp-file": {
|
"node_modules/temp-file": {
|
||||||
@ -9922,6 +10158,7 @@
|
|||||||
},
|
},
|
||||||
"node_modules/text-table": {
|
"node_modules/text-table": {
|
||||||
"version": "0.2.0",
|
"version": "0.2.0",
|
||||||
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/timm": {
|
"node_modules/timm": {
|
||||||
@ -10053,6 +10290,17 @@
|
|||||||
"node": ">=14.17"
|
"node": ">=14.17"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/uint8array-extras": {
|
||||||
|
"version": "0.3.0",
|
||||||
|
"resolved": "https://registry.npmmirror.com/uint8array-extras/-/uint8array-extras-0.3.0.tgz",
|
||||||
|
"integrity": "sha512-erJsJwQ0tKdwuqI0359U8ijkFmfiTcq25JvvzRVc1VP+2son1NJRXhxcAKJmAW3ajM8JSGAfsAXye8g4s+znxA==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/undici-types": {
|
"node_modules/undici-types": {
|
||||||
"version": "5.26.5",
|
"version": "5.26.5",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
@ -10094,7 +10342,6 @@
|
|||||||
},
|
},
|
||||||
"node_modules/uri-js": {
|
"node_modules/uri-js": {
|
||||||
"version": "4.4.1",
|
"version": "4.4.1",
|
||||||
"dev": true,
|
|
||||||
"license": "BSD-2-Clause",
|
"license": "BSD-2-Clause",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"punycode": "^2.1.0"
|
"punycode": "^2.1.0"
|
||||||
@ -10368,8 +10615,14 @@
|
|||||||
"webidl-conversions": "^3.0.0"
|
"webidl-conversions": "^3.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/when-exit": {
|
||||||
|
"version": "2.1.2",
|
||||||
|
"resolved": "https://registry.npmmirror.com/when-exit/-/when-exit-2.1.2.tgz",
|
||||||
|
"integrity": "sha512-u9J+toaf3CCxCAzM/484qNAxQE75rFdVgiFEEV8Xps2gzYhf0tx73s1WXDQhkwV17E3MxRMz40m7Ekd2/121Lg=="
|
||||||
|
},
|
||||||
"node_modules/which": {
|
"node_modules/which": {
|
||||||
"version": "2.0.2",
|
"version": "2.0.2",
|
||||||
|
"dev": true,
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"isexe": "^2.0.0"
|
"isexe": "^2.0.0"
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "laitool",
|
"name": "laitool",
|
||||||
"version": "2.2.2",
|
"version": "2.2.4",
|
||||||
"description": "An Electron application with Vue",
|
"description": "An Electron application with Vue",
|
||||||
"main": "./out/main/index.js",
|
"main": "./out/main/index.js",
|
||||||
"author": "example.com",
|
"author": "example.com",
|
||||||
@ -29,6 +29,7 @@
|
|||||||
"axios": "^1.6.5",
|
"axios": "^1.6.5",
|
||||||
"compressing": "^1.10.0",
|
"compressing": "^1.10.0",
|
||||||
"crypto-js": "^4.2.0",
|
"crypto-js": "^4.2.0",
|
||||||
|
"electron-store": "^9.0.0",
|
||||||
"electron-updater": "^6.1.7",
|
"electron-updater": "^6.1.7",
|
||||||
"fluent-ffmpeg": "^2.1.2",
|
"fluent-ffmpeg": "^2.1.2",
|
||||||
"highlight.js": "^11.9.0",
|
"highlight.js": "^11.9.0",
|
||||||
@ -72,7 +73,8 @@
|
|||||||
],
|
],
|
||||||
"extraResources": [
|
"extraResources": [
|
||||||
"resources/package/**",
|
"resources/package/**",
|
||||||
"resources/image/**",
|
"resources/image/style/**",
|
||||||
|
"resources/image/zhanwei.png",
|
||||||
"resources/scripts/model/**",
|
"resources/scripts/model/**",
|
||||||
"resources/scripts/Lai.exe",
|
"resources/scripts/Lai.exe",
|
||||||
"resources/scripts/discordScript.js",
|
"resources/scripts/discordScript.js",
|
||||||
|
|||||||
BIN
resources/image/c_s/36069560-f403-47a4-923a-db1269e91d40.png
Normal file
BIN
resources/image/c_s/36069560-f403-47a4-923a-db1269e91d40.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.4 MiB |
BIN
resources/image/c_s/4e634611-e833-47b0-8aa6-a836933dc851.png
Normal file
BIN
resources/image/c_s/4e634611-e833-47b0-8aa6-a836933dc851.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.6 MiB |
BIN
resources/image/c_s/67a962df-12e3-4188-a201-e2643590a479.png
Normal file
BIN
resources/image/c_s/67a962df-12e3-4188-a201-e2643590a479.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.2 MiB |
BIN
resources/image/c_s/c8fc2c21-54ea-4d07-b7f8-af64744aba70.png
Normal file
BIN
resources/image/c_s/c8fc2c21-54ea-4d07-b7f8-af64744aba70.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.3 MiB |
BIN
resources/image/c_s/e8503820-e13c-430a-bb22-0ab0c0468eec.png
Normal file
BIN
resources/image/c_s/e8503820-e13c-430a-bb22-0ab0c0468eec.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 44 KiB |
@ -11,7 +11,7 @@ import shotSplit
|
|||||||
|
|
||||||
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding="utf-8")
|
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding="utf-8")
|
||||||
|
|
||||||
# sys.argv = ["C:\\Users\\27698\\Desktop\\LAITool\\resources\\scripts\\Lai.exe","-c","D:/父爱如山倒/scripts/output_crop_00001.json"]
|
# sys.argv = ["C:\\Users\\27698\\Desktop\\LAITool\\resources\\scripts\\Lai.exe","-c","C:/Users/27698/Desktop/测试/123/scripts/output_crop_00001.json"]
|
||||||
print(sys.argv)
|
print(sys.argv)
|
||||||
|
|
||||||
if len(sys.argv) < 2:
|
if len(sys.argv) < 2:
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -376,11 +376,19 @@ class ImageToVideo:
|
|||||||
proportion_height = img_height / 3200
|
proportion_height = img_height / 3200
|
||||||
proportion_width = img_height / 3200
|
proportion_width = img_height / 3200
|
||||||
|
|
||||||
if offset["name"] == "KFTypePositionY":
|
key_frame = offset["name"]
|
||||||
|
offset_list = ["KFTypePositionY", "KFTypePositionX"]
|
||||||
|
real_key_frame = key_frame
|
||||||
|
|
||||||
|
if key_frame == "KFTypeRandom":
|
||||||
|
# 随机获取 offset_list 中的一个数据
|
||||||
|
real_key_frame = offset_list[np.random.randint(0, 2)]
|
||||||
|
|
||||||
|
if real_key_frame == "KFTypePositionY":
|
||||||
offsetValue = offset["up_down"] * proportion_height
|
offsetValue = offset["up_down"] * proportion_height
|
||||||
elif offset["name"] == "KFTypePositionX":
|
elif real_key_frame == "KFTypePositionX":
|
||||||
offsetValue = offset["left_right"] * proportion_width
|
offsetValue = offset["left_right"] * proportion_width
|
||||||
elif offset["name"] == "KFTypeScale":
|
elif real_key_frame == "KFTypeScale":
|
||||||
offsetValue = offset["scale"]
|
offsetValue = offset["scale"]
|
||||||
else:
|
else:
|
||||||
return ValueError("关键帧没有设置正确的参数")
|
return ValueError("关键帧没有设置正确的参数")
|
||||||
@ -402,7 +410,7 @@ class ImageToVideo:
|
|||||||
end_offset,
|
end_offset,
|
||||||
self.fps,
|
self.fps,
|
||||||
self.video_size,
|
self.video_size,
|
||||||
offset["name"],
|
real_key_frame,
|
||||||
)
|
)
|
||||||
video_arr.append(video_path)
|
video_arr.append(video_path)
|
||||||
print(video_path)
|
print(video_path)
|
||||||
|
|||||||
2
resources/scripts/install.bat
Normal file
2
resources/scripts/install.bat
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
@echo off
|
||||||
|
pyinstaller Lai.spec
|
||||||
@ -4,7 +4,6 @@
|
|||||||
{
|
{
|
||||||
"curveType": "Line",
|
"curveType": "Line",
|
||||||
"graphID": "",
|
"graphID": "",
|
||||||
"id": "389CE3AB-19DF-4EC8-B712-454C224D0D92",
|
|
||||||
"left_control": {
|
"left_control": {
|
||||||
"x": 0.0,
|
"x": 0.0,
|
||||||
"y": 0.0
|
"y": 0.0
|
||||||
@ -21,7 +20,6 @@
|
|||||||
{
|
{
|
||||||
"curveType": "Line",
|
"curveType": "Line",
|
||||||
"graphID": "",
|
"graphID": "",
|
||||||
"id": "3F5A033A-9088-4AED-BBF6-50DEBE67BCA5",
|
|
||||||
"left_control": {
|
"left_control": {
|
||||||
"x": 0.0,
|
"x": 0.0,
|
||||||
"y": 0.0
|
"y": 0.0
|
||||||
|
|||||||
116
src/api/apiBasic.js
Normal file
116
src/api/apiBasic.js
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
|
||||||
|
const { net } = require('electron');
|
||||||
|
|
||||||
|
let basicApi = {
|
||||||
|
/**
|
||||||
|
* 使用electron的net模块实现的get方法
|
||||||
|
* @param {*} url 请求的url
|
||||||
|
* @param {*} headers 请求头
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
get: (url, headers = {}) => {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const request = net.request({ url, method: 'GET', headers });
|
||||||
|
request.on('response', (response) => {
|
||||||
|
let data = '';
|
||||||
|
response.on('data', (chunk) => {
|
||||||
|
data += chunk;
|
||||||
|
});
|
||||||
|
response.on('end', () => {
|
||||||
|
// 结束的时候检查请求的状态码,是不是成功的请求,不是返回错误,有些其他的状态码也是成功的请求,并且返回错误提示
|
||||||
|
if (response.statusCode != 200) {
|
||||||
|
reject(new Error(`请求失败,状态码:${response.statusCode},错误信息:${response.statusMessage}`));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let parsedData;
|
||||||
|
if (response.headers['content-type'].includes('application/json')) {
|
||||||
|
parsedData = JSON.parse(data);
|
||||||
|
} else {
|
||||||
|
parsedData = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
resolve({
|
||||||
|
data: parsedData,
|
||||||
|
status: response.statusCode,
|
||||||
|
statusText: response.statusMessage,
|
||||||
|
headers: response.headers,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
response.on('error', (error) => {
|
||||||
|
reject(error);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
request.on('error', (error) => {
|
||||||
|
console.log('request error', error);
|
||||||
|
reject(error);
|
||||||
|
});
|
||||||
|
request.end();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 使用electron的net模块实现的post方法
|
||||||
|
* @param {*} url 请求的url
|
||||||
|
* @param {*} data 传输的数据(json格式)
|
||||||
|
* @param {*} headers 请求头
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
post: (url, data = {}, headers = {}) => {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const request = net.request({
|
||||||
|
method: 'POST',
|
||||||
|
url: url,
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
...headers
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
request.write(JSON.stringify(data));
|
||||||
|
|
||||||
|
request.on('response', (response) => {
|
||||||
|
let responseData = '';
|
||||||
|
|
||||||
|
response.on('data', (chunk) => {
|
||||||
|
responseData += chunk;
|
||||||
|
});
|
||||||
|
|
||||||
|
response.on('end', () => {
|
||||||
|
if (response.statusCode != 200) {
|
||||||
|
reject(new Error(`请求失败,状态码:${response.statusCode},错误信息:${response.statusMessage}`));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let parsedData;
|
||||||
|
if (response.headers['content-type'].includes('application/json')) {
|
||||||
|
parsedData = JSON.parse(responseData);
|
||||||
|
} else {
|
||||||
|
parsedData = responseData;
|
||||||
|
}
|
||||||
|
|
||||||
|
resolve({
|
||||||
|
data: parsedData,
|
||||||
|
status: response.statusCode,
|
||||||
|
statusText: response.statusMessage,
|
||||||
|
headers: response.headers
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
response.on('error', (error) => {
|
||||||
|
console.log('error', error);
|
||||||
|
reject(error);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
request.on('error', (error) => {
|
||||||
|
console.log('request error', error);
|
||||||
|
reject(error);
|
||||||
|
});
|
||||||
|
request.end();
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export {
|
||||||
|
basicApi
|
||||||
|
}
|
||||||
90
src/api/sdApi.js
Normal file
90
src/api/sdApi.js
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
import { basicApi } from "./apiBasic";
|
||||||
|
import { define } from "../define/define";
|
||||||
|
import { promises as fspromises } from 'fs'
|
||||||
|
import { errorMessage, successMessage } from "../main/generalTools";
|
||||||
|
|
||||||
|
|
||||||
|
export class SdApi {
|
||||||
|
constructor() {
|
||||||
|
this.baseUrl = global.config?.webui_api_url;
|
||||||
|
this.sd_setting = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取当前SD的服务器中所有的lora信息
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
async getAllLoras(baseURL = null) {
|
||||||
|
let url = this.baseUrl + "sdapi/v1/loras";
|
||||||
|
if (baseURL != null) {
|
||||||
|
url = baseURL + "sdapi/v1/loras";
|
||||||
|
}
|
||||||
|
return await basicApi.get(url);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取当前的所有的checkpoint模型
|
||||||
|
* @param {*} baseURL
|
||||||
|
*/
|
||||||
|
async getAllSDModel(baseURL = null) {
|
||||||
|
let url = this.baseUrl + "sdapi/v1/sd-models";
|
||||||
|
if (baseURL != null) {
|
||||||
|
url = baseURL + "sdapi/v1/sd-models";
|
||||||
|
}
|
||||||
|
return await basicApi.get(url);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取当前连接的所有的samplers(采样器)
|
||||||
|
* @param {*} baseURL
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
async getAllSamplers(baseURL = null) {
|
||||||
|
try {
|
||||||
|
|
||||||
|
let url = this.baseUrl + "sdapi/v1/samplers";
|
||||||
|
if (baseURL != null) {
|
||||||
|
url = baseURL + "sdapi/v1/samplers";
|
||||||
|
}
|
||||||
|
return await basicApi.get(url);
|
||||||
|
} catch (error) {
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async txt2img(data, baseURL = null) {
|
||||||
|
try {
|
||||||
|
|
||||||
|
if (this.sd_setting == null) {
|
||||||
|
this.sd_setting = JSON.parse(await fspromises.readFile(define.sd_setting, 'utf-8'));
|
||||||
|
this.baseUrl = this.sd_setting.setting.webui_api_url;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 加上通用前缀
|
||||||
|
data.prompt = this.sd_setting.webui.prompt + data.prompt
|
||||||
|
|
||||||
|
data.negative_prompt = this.sd_setting.webui.negative_prompt;
|
||||||
|
data.sampler_name = this.sd_setting.webui.sampler_name;
|
||||||
|
data.cfg_scale = this.sd_setting.webui.cfg_scale;
|
||||||
|
data.n_iter = 1;
|
||||||
|
data.steps = this.sd_setting.webui.steps;
|
||||||
|
data.save_images = false;
|
||||||
|
data.batch_size = data.batch_size ? data.batch_size : 1;
|
||||||
|
if (data.width == null) {
|
||||||
|
data.width = 512;
|
||||||
|
}
|
||||||
|
if (data.height == null) {
|
||||||
|
data.height = 512;
|
||||||
|
}
|
||||||
|
|
||||||
|
let url = this.baseUrl + "sdapi/v1/txt2img";
|
||||||
|
if (baseURL != null) {
|
||||||
|
url = baseURL + "sdapi/v1/txt2img";
|
||||||
|
}
|
||||||
|
let res = await basicApi.post(url, data);
|
||||||
|
return res;
|
||||||
|
} catch (error) {
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -15,6 +15,7 @@ if (!app.isPackaged) {
|
|||||||
scripts_path: path.join(__dirname, "../../resources/scripts"),
|
scripts_path: path.join(__dirname, "../../resources/scripts"),
|
||||||
package_path: path.join(__dirname, "../../resources/package"),
|
package_path: path.join(__dirname, "../../resources/package"),
|
||||||
image_path: path.join(__dirname, "../../resources/image"),
|
image_path: path.join(__dirname, "../../resources/image"),
|
||||||
|
temp_sd_image: path.join(__dirname, "../../resources/image/TempSDImage"),
|
||||||
draft_temp_path: path.join(__dirname, "../../resources/tmp/temp.zip"),
|
draft_temp_path: path.join(__dirname, "../../resources/tmp/temp.zip"),
|
||||||
clip_speed_temp_path: path.join(__dirname, "../../resources/tmp/Clip/speeds_tmp.json"),
|
clip_speed_temp_path: path.join(__dirname, "../../resources/tmp/Clip/speeds_tmp.json"),
|
||||||
add_canvases_temp_path: path.join(__dirname, "../../resources/tmp/Clip/canvases_tmp.json"),
|
add_canvases_temp_path: path.join(__dirname, "../../resources/tmp/Clip/canvases_tmp.json"),
|
||||||
@ -45,6 +46,7 @@ if (!app.isPackaged) {
|
|||||||
package_path: path.join(__dirname, "../../../resources/package"),
|
package_path: path.join(__dirname, "../../../resources/package"),
|
||||||
discordScript: path.join(__dirname, "../../../resources/scripts/discordScript.js"),
|
discordScript: path.join(__dirname, "../../../resources/scripts/discordScript.js"),
|
||||||
image_path: path.join(__dirname, "../../../resources/image"),
|
image_path: path.join(__dirname, "../../../resources/image"),
|
||||||
|
temp_sd_image: path.join(__dirname, "../../../resources/image/TempSDImage"),
|
||||||
draft_temp_path: path.join(__dirname, "../../../resources/tmp/temp.zip"),
|
draft_temp_path: path.join(__dirname, "../../../resources/tmp/temp.zip"),
|
||||||
clip_speed_temp_path: path.join(__dirname, "../../../resources/tmp/Clip/speeds_tmp.json"),
|
clip_speed_temp_path: path.join(__dirname, "../../../resources/tmp/Clip/speeds_tmp.json"),
|
||||||
add_canvases_temp_path: path.join(__dirname, "../../../resources/tmp/Clip/canvases_tmp.json"),
|
add_canvases_temp_path: path.join(__dirname, "../../../resources/tmp/Clip/canvases_tmp.json"),
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
export const DEFINE_STRING = {
|
export const DEFINE_STRING = {
|
||||||
|
GET_FILE_BASE64: "GET_FILE_BASE64",
|
||||||
SAVE_DEFINE_CONFIG_JSON_BY_PROPERTY: "SAVE_DEFINE_CONFIG_JSON_BY_PROPERTY",
|
SAVE_DEFINE_CONFIG_JSON_BY_PROPERTY: "SAVE_DEFINE_CONFIG_JSON_BY_PROPERTY",
|
||||||
GET_DEFINE_CONFIG_JSON_BY_PROPERTY: "GET_DEFINE_CONFIG_JSON_BY_PROPERTY",
|
GET_DEFINE_CONFIG_JSON_BY_PROPERTY: "GET_DEFINE_CONFIG_JSON_BY_PROPERTY",
|
||||||
GET_IMAGE_GENERATE_CATEGORY: "GET_IMAGE_GENERATE_CATEGORY",
|
GET_IMAGE_GENERATE_CATEGORY: "GET_IMAGE_GENERATE_CATEGORY",
|
||||||
@ -134,6 +135,10 @@ export const DEFINE_STRING = {
|
|||||||
NORMAL_PERMISSION: "NORMAL_PERMISSION",
|
NORMAL_PERMISSION: "NORMAL_PERMISSION",
|
||||||
AUTO_SAVE_IMAGE_PERMISSION: "AUTO_SAVE_IMAGE_PERMISSION",
|
AUTO_SAVE_IMAGE_PERMISSION: "AUTO_SAVE_IMAGE_PERMISSION",
|
||||||
},
|
},
|
||||||
|
SD: {
|
||||||
|
LOAD_SD_SERVICE_DATA: "LOAD_SD_SERVICE_DATA",
|
||||||
|
TXT2IMG: "TXT2IMG",
|
||||||
|
},
|
||||||
MJ: {
|
MJ: {
|
||||||
SAVE_WORD_SRT: "SAVE_WORD_SRT",
|
SAVE_WORD_SRT: "SAVE_WORD_SRT",
|
||||||
GET_MJ_CONFIG_SRT_INFORMATION: "GET_MJ_CONFIG_SRT_INFORMATION",
|
GET_MJ_CONFIG_SRT_INFORMATION: "GET_MJ_CONFIG_SRT_INFORMATION",
|
||||||
|
|||||||
@ -39,6 +39,9 @@ export const ClipSetting = {
|
|||||||
}, {
|
}, {
|
||||||
label: "缩放",
|
label: "缩放",
|
||||||
value: "KFTypeScale"
|
value: "KFTypeScale"
|
||||||
|
}, {
|
||||||
|
label: "随机",
|
||||||
|
value: "KFTypeRandom"
|
||||||
}]
|
}]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@ -1,6 +1,9 @@
|
|||||||
import { get } from "lodash";
|
import { get } from "lodash";
|
||||||
import { define } from "../define";
|
import { define } from "../define";
|
||||||
let fspromises = require("fs").promises;
|
let fspromises = require("fs").promises;
|
||||||
|
import { Tools } from "../../main/tools";
|
||||||
|
import { errorMessage } from "../../main/generalTools";
|
||||||
|
let tools = new Tools();
|
||||||
|
|
||||||
// Create a shared object
|
// Create a shared object
|
||||||
export const SdSettingDefine = {
|
export const SdSettingDefine = {
|
||||||
@ -42,6 +45,26 @@ export const SdSettingDefine = {
|
|||||||
return get(setting, "webui", null);
|
return get(setting, "webui", null);
|
||||||
} else
|
} else
|
||||||
return get(setting.webui, property, null);
|
return get(setting.webui, property, null);
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 保存一个大的属性添加到配置文件中
|
||||||
|
* @param {*} property
|
||||||
|
* @param {*} value
|
||||||
|
*/
|
||||||
|
SavePropertyValue: async function (property, value) {
|
||||||
|
try {
|
||||||
|
global.fileQueue.enqueue(async () => {
|
||||||
|
// 复制文件到指定的文件夹
|
||||||
|
await tools.writeJsonFilePropertyValue(define.sd_setting, property, value);
|
||||||
|
|
||||||
|
})
|
||||||
|
} catch (error) {
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|||||||
@ -2,11 +2,14 @@
|
|||||||
let fspromises = require('fs').promises;
|
let fspromises = require('fs').promises;
|
||||||
import { get, cloneDeep } from 'lodash';
|
import { get, cloneDeep } from 'lodash';
|
||||||
import { define } from './define';
|
import { define } from './define';
|
||||||
|
import path from 'path';
|
||||||
|
import { Tools } from '../main/tools';
|
||||||
const { v4: uuidv4 } = require('uuid');
|
const { v4: uuidv4 } = require('uuid');
|
||||||
|
|
||||||
export class TagDefine {
|
export class TagDefine {
|
||||||
constructor(global) {
|
constructor(global) {
|
||||||
this.global = global;
|
this.global = global;
|
||||||
|
this.tools = new Tools();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -54,6 +57,30 @@ export class TagDefine {
|
|||||||
else {
|
else {
|
||||||
throw new Error(`不存在的类型 : ${value}`);
|
throw new Error(`不存在的类型 : ${value}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 返回之前,判断里面是不是有预览图片路径
|
||||||
|
if (res.hasOwnProperty("character_tags")) {
|
||||||
|
res.character_tags.forEach(item => {
|
||||||
|
if (item.show_image && item.show_image != "") {
|
||||||
|
item.show_image = path.join(define.image_path, item.show_image);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (res.hasOwnProperty("scene_tags")) {
|
||||||
|
res.scene_tags.forEach(item => {
|
||||||
|
if (item.show_image && item.show_image != "") {
|
||||||
|
item.show_image = path.join(define.image_path, item.show_image);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (res.hasOwnProperty("style_tags")) {
|
||||||
|
res.style_tags.forEach(item => {
|
||||||
|
if (item.show_image && item.show_image != "") {
|
||||||
|
item.show_image = path.join(define.image_path, item.show_image);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
code: 1,
|
code: 1,
|
||||||
data: res
|
data: res
|
||||||
@ -75,6 +102,22 @@ export class TagDefine {
|
|||||||
try {
|
try {
|
||||||
let property = value[1];
|
let property = value[1];
|
||||||
value = JSON.parse(value[0]);
|
value = JSON.parse(value[0]);
|
||||||
|
let tmp_key = uuidv4();
|
||||||
|
|
||||||
|
// 特殊操作。为角色和场景的时候,需要copy图片
|
||||||
|
if (property == "character_tags" || property == "scene_tags" || property == "style_tags") {
|
||||||
|
let show_image = value.show_image;
|
||||||
|
if (show_image && show_image != "") {
|
||||||
|
let file_name = `c_s/${value.key ? value.key : tmp_key}.png`
|
||||||
|
let new_image_path = path.join(define.image_path, file_name);
|
||||||
|
await this.tools.copyFileOrDirectory(show_image, new_image_path);
|
||||||
|
value.show_image = file_name;
|
||||||
|
value.children?.forEach(item => {
|
||||||
|
item.show_image = file_name;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 获取自定义的GPT数据
|
// 获取自定义的GPT数据
|
||||||
let tag_setting = JSON.parse(await fspromises.readFile(define.tag_setting, 'utf-8'));
|
let tag_setting = JSON.parse(await fspromises.readFile(define.tag_setting, 'utf-8'));
|
||||||
let tag = get(tag_setting, property, []);
|
let tag = get(tag_setting, property, []);
|
||||||
@ -96,7 +139,7 @@ export class TagDefine {
|
|||||||
if (tag.some(item => item.label == value.label)) {
|
if (tag.some(item => item.label == value.label)) {
|
||||||
throw new Error("已存在相同名称的数据,请修改名称后再保存");
|
throw new Error("已存在相同名称的数据,请修改名称后再保存");
|
||||||
}
|
}
|
||||||
value.key = uuidv4();
|
value.key = tmp_key;
|
||||||
value.value = value.key;
|
value.value = value.key;
|
||||||
tag.push(value);
|
tag.push(value);
|
||||||
}
|
}
|
||||||
@ -107,7 +150,6 @@ export class TagDefine {
|
|||||||
code: 1,
|
code: 1,
|
||||||
message: "保存成功"
|
message: "保存成功"
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
return {
|
return {
|
||||||
code: 0,
|
code: 0,
|
||||||
|
|||||||
34
src/main/IPCEvent/globalIpc.js
Normal file
34
src/main/IPCEvent/globalIpc.js
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
import {
|
||||||
|
ipcMain
|
||||||
|
} from "electron";
|
||||||
|
import { DEFINE_STRING } from '../../define/define_string'
|
||||||
|
import { Tools } from "../tools";
|
||||||
|
import path from "path";
|
||||||
|
import { errorMessage, successMessage } from "../generalTools";
|
||||||
|
let tools = new Tools();
|
||||||
|
|
||||||
|
function GlobalIpc() {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将传入的文件地址修改为base64
|
||||||
|
*/
|
||||||
|
ipcMain.handle(DEFINE_STRING.GET_FILE_BASE64, async (event, value) => {
|
||||||
|
try {
|
||||||
|
value = path.normalize(value)
|
||||||
|
//检查文件或者时文件夹是不是存在
|
||||||
|
let isExists = await tools.checkExists(value);
|
||||||
|
console.log("isExists", value, isExists);
|
||||||
|
// 获取文件,将其转换为base64
|
||||||
|
if (!isExists) {
|
||||||
|
throw new Error("文件不存在");
|
||||||
|
}
|
||||||
|
return successMessage(await tools.readFileBase64(value));
|
||||||
|
} catch (error) {
|
||||||
|
return errorMessage("获取文件失败" + error)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export {
|
||||||
|
GlobalIpc
|
||||||
|
}
|
||||||
@ -12,6 +12,12 @@ function SdIpc() {
|
|||||||
|
|
||||||
// 获取图片样式菜单
|
// 获取图片样式菜单
|
||||||
ipcMain.handle(DEFINE_STRING.GET_IMAGE_STYLE_MENU, async (event) => await sd.GetImageStyleMenu());
|
ipcMain.handle(DEFINE_STRING.GET_IMAGE_STYLE_MENU, async (event) => await sd.GetImageStyleMenu());
|
||||||
|
|
||||||
|
// 加载当前链接的SD服务数据
|
||||||
|
ipcMain.handle(DEFINE_STRING.SD.LOAD_SD_SERVICE_DATA, async (event, value) => await sd.LoadSDServiceData(value));
|
||||||
|
|
||||||
|
// 文生图,单张
|
||||||
|
ipcMain.handle(DEFINE_STRING.SD.TXT2IMG, async (event, value) => await sd.txt2img(value));
|
||||||
}
|
}
|
||||||
export {
|
export {
|
||||||
SdIpc
|
SdIpc
|
||||||
|
|||||||
@ -9,6 +9,7 @@ import path from 'path'
|
|||||||
import sharp from 'sharp'
|
import sharp from 'sharp'
|
||||||
import { define } from "../../define/define";
|
import { define } from "../../define/define";
|
||||||
import { AwesomeRegx } from "awesome-js";
|
import { AwesomeRegx } from "awesome-js";
|
||||||
|
import { checkStringValueAddSuffix } from "../generalTools";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* MJ原创生图的类
|
* MJ原创生图的类
|
||||||
@ -196,13 +197,15 @@ export class MJOriginalImageGenerate {
|
|||||||
|
|
||||||
// 判断存放的文件夹是不是存在,不存在的话创建
|
// 判断存放的文件夹是不是存在,不存在的话创建
|
||||||
let outputDir = path.join(this.global.config.project_path, `data\\MJOriginalImage`);
|
let outputDir = path.join(this.global.config.project_path, `data\\MJOriginalImage`);
|
||||||
|
|
||||||
await this.tools.checkFolderExistsOrCreate(outputDir);
|
await this.tools.checkFolderExistsOrCreate(outputDir);
|
||||||
|
|
||||||
let fileExist = await this.tools.checkExists(outputDir);
|
let fileExist = await this.tools.checkExists(outputDir);
|
||||||
if (!fileExist) {
|
if (!fileExist) {
|
||||||
await this.tools.createDirectory(outputDir);
|
await this.tools.createDirectory(outputDir);
|
||||||
}
|
}
|
||||||
|
// 判断该当前tmp\output_crop_00001文件夹是不是存在,不存在创建
|
||||||
|
let output_crop_00001 = path.join(this.global.config.project_path, `tmp\\output_crop_00001`);
|
||||||
|
await this.tools.checkFolderExistsOrCreate(output_crop_00001);
|
||||||
|
|
||||||
|
|
||||||
// 检查this.global中是不是又mj队列,没有的话创建一个
|
// 检查this.global中是不是又mj队列,没有的话创建一个
|
||||||
if (!this.global.mjGenerateQuene) {
|
if (!this.global.mjGenerateQuene) {
|
||||||
@ -210,7 +213,7 @@ export class MJOriginalImageGenerate {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let style_ids = await this.pm.GetConfigJson(JSON.stringify(["image_style", []]), false);
|
let style_ids = await this.pm.GetConfigJson(JSON.stringify(["image_style", []]), false);
|
||||||
// let image_styles = await ImageStyleDefine.getImageStyleStringByIds(style_ids.data);
|
let image_styles = await ImageStyleDefine.getImageStyleStringByIds(style_ids.data);
|
||||||
|
|
||||||
// 替换风格的逻辑
|
// 替换风格的逻辑
|
||||||
let current_task = null;
|
let current_task = null;
|
||||||
@ -219,11 +222,17 @@ export class MJOriginalImageGenerate {
|
|||||||
const element = data[i];
|
const element = data[i];
|
||||||
let tasK_id = `${batch}_${element.name}_${element.id}`;
|
let tasK_id = `${batch}_${element.name}_${element.id}`;
|
||||||
|
|
||||||
|
let old_prompt = element.prompt;
|
||||||
|
// 拼接提示词
|
||||||
|
// 图生图的链接
|
||||||
|
// 获取风格词
|
||||||
|
let prompt = " " + image_styles + old_prompt;
|
||||||
|
|
||||||
|
|
||||||
this.global.mjGenerateQuene.enqueue(async () => {
|
this.global.mjGenerateQuene.enqueue(async () => {
|
||||||
try {
|
try {
|
||||||
this.global.mjGenerateQuene.setCurrentCreateItem(element)
|
this.global.mjGenerateQuene.setCurrentCreateItem(element)
|
||||||
// 开始进行mj生图
|
// 开始进行mj生图
|
||||||
let prompt = element.prompt;
|
|
||||||
current_task = element.name;
|
current_task = element.name;
|
||||||
// 判断窗口是不是开启
|
// 判断窗口是不是开启
|
||||||
|
|
||||||
|
|||||||
@ -12,7 +12,6 @@ const { spawn, exec } = require('child_process');
|
|||||||
const execAsync = util.promisify(exec);
|
const execAsync = util.promisify(exec);
|
||||||
const { v4: uuidv4 } = require('uuid'); // 引入UUID库来生成唯一标识符
|
const { v4: uuidv4 } = require('uuid'); // 引入UUID库来生成唯一标识符
|
||||||
let fspromises = require("fs").promises;
|
let fspromises = require("fs").promises;
|
||||||
import { MD5 } from "crypto-js";
|
|
||||||
import { ImageStyleDefine } from "../../define/iamgeStyleDefine";
|
import { ImageStyleDefine } from "../../define/iamgeStyleDefine";
|
||||||
|
|
||||||
|
|
||||||
@ -64,26 +63,21 @@ export class OriginalImageGenerate {
|
|||||||
|
|
||||||
let style_ids = await this.pm.GetConfigJson(JSON.stringify(["image_style", []]), false);
|
let style_ids = await this.pm.GetConfigJson(JSON.stringify(["image_style", []]), false);
|
||||||
let image_styles = await ImageStyleDefine.getImageStyleStringByIds(style_ids.data);
|
let image_styles = await ImageStyleDefine.getImageStyleStringByIds(style_ids.data);
|
||||||
//
|
|
||||||
console.log(image_styles);
|
|
||||||
|
|
||||||
for (let i = 0; i < data.length; i++) {
|
for (let i = 0; i < data.length; i++) {
|
||||||
const element = data[i];
|
const element = data[i];
|
||||||
let adetailer = element.adetailer;
|
let adetailer = element.adetailer;
|
||||||
|
|
||||||
let imageJson = JSON.parse(await fspromises.readFile(path.normalize(element.prompt_json), 'utf-8'));
|
let imageJson = JSON.parse(await fspromises.readFile(path.normalize(element.prompt_json), 'utf-8'));
|
||||||
// let prompt = image_styles + sd_setting.webui.prompt + ',' + element.prompt;
|
let prompt = sd_setting.webui.prompt + image_styles + ',' + element.prompt;
|
||||||
// // 添加前缀
|
// 添加前缀
|
||||||
// if (prefix_prompt) {
|
if (prefix_prompt) {
|
||||||
// prompt = prefix_prompt + ',' + prompt;
|
prompt = prefix_prompt + ',' + prompt;
|
||||||
// }
|
}
|
||||||
// // 添加后缀
|
// 添加后缀
|
||||||
// if (suffix_prompt) {
|
if (suffix_prompt) {
|
||||||
// prompt = prompt + ',' + suffix_prompt;
|
prompt = prompt + ',' + suffix_prompt;
|
||||||
// }
|
}
|
||||||
let prompt = imageJson.webui_config.prompt;
|
// let prompt = imageJson.webui_config.prompt;
|
||||||
|
|
||||||
|
|
||||||
this.global.requestQuene.enqueue(async () => {
|
this.global.requestQuene.enqueue(async () => {
|
||||||
try {
|
try {
|
||||||
// 开始请求
|
// 开始请求
|
||||||
@ -91,7 +85,7 @@ export class OriginalImageGenerate {
|
|||||||
"prompt": prompt,
|
"prompt": prompt,
|
||||||
"negative_prompt": imageJson.webui_config.negative_prompt,
|
"negative_prompt": imageJson.webui_config.negative_prompt,
|
||||||
"seed": seed,
|
"seed": seed,
|
||||||
"sampler_name": imageJson.webui_config.sampler_name,
|
"sampler_name": sd_setting.webui.sampler_name,
|
||||||
// 提示词相关性
|
// 提示词相关性
|
||||||
"cfg_scale": sd_setting.webui.cfg_scale,
|
"cfg_scale": sd_setting.webui.cfg_scale,
|
||||||
"width": sd_setting.webui.width,
|
"width": sd_setting.webui.width,
|
||||||
@ -258,7 +252,15 @@ export class OriginalImageGenerate {
|
|||||||
if (element.outImagePath && file_regex.test(element.outImagePath)) {
|
if (element.outImagePath && file_regex.test(element.outImagePath)) {
|
||||||
// 删除 "file://" 开头
|
// 删除 "file://" 开头
|
||||||
element.outImagePath = decodeURI(element.outImagePath);
|
element.outImagePath = decodeURI(element.outImagePath);
|
||||||
element.outImagePath = element.outImagePath.replace(/^file:\/\//, '').replace(/\?time=.*$/, '');
|
// 判断element.outImagePath是不是不是以file://开头的,是的话,删除
|
||||||
|
if (element.outImagePath.startsWith("file://")) {
|
||||||
|
element.outImagePath = element.outImagePath.substring(7);
|
||||||
|
}
|
||||||
|
element.outImagePath = element.outImagePath.replace(/\?time=.*$/, '');
|
||||||
|
// 判断element.outImagePath是不是以/开头的,是的话,删除
|
||||||
|
if (element.outImagePath.startsWith("/")) {
|
||||||
|
element.outImagePath = element.outImagePath.substring(1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (element.subImagePath && element.subImagePath.length > 0) {
|
if (element.subImagePath && element.subImagePath.length > 0) {
|
||||||
for (let j = 0; j < element.subImagePath.length; j++) {
|
for (let j = 0; j < element.subImagePath.length; j++) {
|
||||||
@ -308,9 +310,7 @@ export class OriginalImageGenerate {
|
|||||||
data: path.join(this.global.config.project_path, "tmp/input_crop")
|
data: path.join(this.global.config.project_path, "tmp/input_crop")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let sd_config = JSON.parse(await fspromises.readFile(define.sd_setting, 'utf-8'));
|
let sd_config = JSON.parse(await fspromises.readFile(define.sd_setting, 'utf-8'));
|
||||||
|
|
||||||
for (let i = 0; i < data.length; i++) {
|
for (let i = 0; i < data.length; i++) {
|
||||||
const element = data[i];
|
const element = data[i];
|
||||||
let name = String(element.no).padStart(5, '0') + ".png";
|
let name = String(element.no).padStart(5, '0') + ".png";
|
||||||
|
|||||||
@ -6,19 +6,112 @@ import { ImageStyleDefine } from "../../define/iamgeStyleDefine";
|
|||||||
import { cloneDeep } from 'lodash';
|
import { cloneDeep } from 'lodash';
|
||||||
let fspromises = require("fs").promises;
|
let fspromises = require("fs").promises;
|
||||||
const sharp = require('sharp');
|
const sharp = require('sharp');
|
||||||
// const {
|
|
||||||
// createCanvas,
|
|
||||||
// loadImage
|
|
||||||
// } = require('canvas');
|
|
||||||
import { SdSettingDefine } from "../../define/setting/sdSettingDefine";
|
import { SdSettingDefine } from "../../define/setting/sdSettingDefine";
|
||||||
import { PublicMethod } from "./publicMethod";
|
import { PublicMethod } from "./publicMethod";
|
||||||
import { Tools } from "../tools";
|
import { Tools } from "../tools";
|
||||||
|
import { errorMessage, successMessage } from "../generalTools";
|
||||||
|
import { SdApi } from "../../api/sdApi";
|
||||||
|
const { v4: uuidv4 } = require('uuid');
|
||||||
|
|
||||||
export class SD {
|
export class SD {
|
||||||
constructor(global) {
|
constructor(global) {
|
||||||
this.global = global;
|
this.global = global;
|
||||||
this.pm = new PublicMethod(global);
|
this.pm = new PublicMethod(global);
|
||||||
this.tools = new Tools();
|
this.tools = new Tools();
|
||||||
|
this.sdApi = new SdApi();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取当前SD服务器所有的lora信息
|
||||||
|
*/
|
||||||
|
async GetAllLoras(baseURL = null) {
|
||||||
|
try {
|
||||||
|
let data = await this.sdApi.getAllLoras(baseURL);
|
||||||
|
return successMessage(data);
|
||||||
|
} catch (error) {
|
||||||
|
return errorMessage(error.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取所有的checkpoint模型
|
||||||
|
* @param {*} baseURL
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
async GetAllSDModel(baseURL = null) {
|
||||||
|
try {
|
||||||
|
let data = await this.sdApi.getAllSDModel(baseURL);
|
||||||
|
return successMessage(data);
|
||||||
|
} catch (error) {
|
||||||
|
return errorMessage(error.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取所有的采样器
|
||||||
|
* @param {*} baseURL
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
async GetAllSamplers(baseURL = null) {
|
||||||
|
try {
|
||||||
|
let data = await this.sdApi.getAllSamplers(baseURL);
|
||||||
|
return successMessage(data);
|
||||||
|
} catch (error) {
|
||||||
|
return errorMessage(error.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 加载所有的SD数据
|
||||||
|
* @param {*} baseURL
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
async LoadSDServiceData(baseURL = null) {
|
||||||
|
try {
|
||||||
|
// 加载大模型
|
||||||
|
let sd_model = await this.GetAllSDModel(baseURL);
|
||||||
|
// 往sd_model中添加一个默认的选项
|
||||||
|
sd_model.data.data.unshift({
|
||||||
|
title: "无",
|
||||||
|
name: "无",
|
||||||
|
description: "无",
|
||||||
|
})
|
||||||
|
// 加载Lora
|
||||||
|
let lora = await this.GetAllLoras(baseURL);
|
||||||
|
lora.data.data.unshift({
|
||||||
|
Key: "无",
|
||||||
|
name: "无",
|
||||||
|
description: "无",
|
||||||
|
})
|
||||||
|
// 加载采样器
|
||||||
|
let sampler = await this.GetAllSamplers(baseURL);
|
||||||
|
sampler.data.data.unshift({
|
||||||
|
name: "无",
|
||||||
|
description: "无",
|
||||||
|
})
|
||||||
|
|
||||||
|
if (!(sd_model.code & lora.code & sampler.code)) {
|
||||||
|
throw new Error("获取SD数据错误,请检查SD WEBUI链接!");
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let i = 0; i < lora.data.data.length; i++) {
|
||||||
|
delete lora.data.data[i].metadata;
|
||||||
|
}
|
||||||
|
let data = {
|
||||||
|
sd_model: sd_model.data.data,
|
||||||
|
lora: lora.data.data,
|
||||||
|
sampler: sampler.data.data
|
||||||
|
}
|
||||||
|
// 处理当前获取的数据,保存到配置文件中
|
||||||
|
await SdSettingDefine.SavePropertyValue("sd_model", data.sd_model);
|
||||||
|
await SdSettingDefine.SavePropertyValue("lora", data.lora);
|
||||||
|
await SdSettingDefine.SavePropertyValue("sampler", data.sampler);
|
||||||
|
|
||||||
|
return successMessage(data);
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
return errorMessage(error.toString());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -34,7 +127,10 @@ export class SD {
|
|||||||
data: style
|
data: style
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
return {
|
||||||
|
code: 0,
|
||||||
|
message: "不可能出现错误"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -106,6 +202,37 @@ export class SD {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 单张生图
|
||||||
|
* @param {*} value 0 生图的参数,1 图片的表示,用于保存 ,2 baseUrl
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
async txt2img(value) {
|
||||||
|
try {
|
||||||
|
value = JSON.parse(value);
|
||||||
|
let data = value[0];
|
||||||
|
let res = await this.sdApi.txt2img(data);
|
||||||
|
// 将base· 64的图片转换为图片
|
||||||
|
// 将当前的图片保存到指定的文件夹中,然后返回文件路径,并且可以复制到指定的文件,删除exif信息
|
||||||
|
let image_paths = [];
|
||||||
|
for (let i = 0; res.data.images && i < res.data.images.length; i++) {
|
||||||
|
const element = res.data.images[i];
|
||||||
|
let image_data = {
|
||||||
|
base64: element
|
||||||
|
}
|
||||||
|
// 将保存图片添加到队列中
|
||||||
|
let image_name = `sd_${Date.now()}_${uuidv4()}.png`;
|
||||||
|
let image_path = path.join(define.temp_sd_image, image_name);
|
||||||
|
image_path = await this.tools.saveBase64ToImage(element, image_path);
|
||||||
|
image_data["image_path"] = image_path;
|
||||||
|
image_paths.push(image_data);
|
||||||
|
}
|
||||||
|
return successMessage(image_paths);
|
||||||
|
} catch (error) {
|
||||||
|
return errorMessage("生图失败,错误信息如下:" + error.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 生成一次图片的方法。可以区分模式
|
* 生成一次图片的方法。可以区分模式
|
||||||
* @param {图片名称 } image
|
* @param {图片名称 } image
|
||||||
@ -120,7 +247,6 @@ export class SD {
|
|||||||
let image_json = JSON.parse(await fspromises.readFile(image + '.json', 'utf-8'));
|
let image_json = JSON.parse(await fspromises.readFile(image + '.json', 'utf-8'));
|
||||||
let image_path = "";
|
let image_path = "";
|
||||||
let target_image_path = "";
|
let target_image_path = "";
|
||||||
|
|
||||||
if (image_json.name) {
|
if (image_json.name) {
|
||||||
image_path = path.join(this.global.config.project_path, `tmp/${task_list.out_folder}/tmp_${image_json.name}`)
|
image_path = path.join(this.global.config.project_path, `tmp/${task_list.out_folder}/tmp_${image_json.name}`)
|
||||||
target_image_path = path.join(this.global.config.project_path, `tmp/${task_list.out_folder}/${image_json.name}`)
|
target_image_path = path.join(this.global.config.project_path, `tmp/${task_list.out_folder}/${image_json.name}`)
|
||||||
@ -128,25 +254,20 @@ export class SD {
|
|||||||
image_path = image.replaceAll("input_crop", task_list.out_folder).split(".png")[0] + "_tmp.png";
|
image_path = image.replaceAll("input_crop", task_list.out_folder).split(".png")[0] + "_tmp.png";
|
||||||
target_image_path = image.replaceAll("input_crop", task_list.out_folder);
|
target_image_path = image.replaceAll("input_crop", task_list.out_folder);
|
||||||
}
|
}
|
||||||
|
let image_styles = await ImageStyleDefine.getImageStyleStringByIds(task_list.image_style_list ? task_list.image_style_list : []);
|
||||||
// let prompt = "";
|
let prompt = sd_setting.webui.prompt + image_styles;
|
||||||
// // 拼接提示词
|
// 拼接提示词
|
||||||
// if (task_list.image_style != null) {
|
if (task_list.image_style != null) {
|
||||||
// prompt += `((${task_list.image_style})),`;
|
prompt += `((${task_list.image_style})), `;
|
||||||
// }
|
}
|
||||||
// if (task_list.lora != null) {
|
if (task_list.lora != null) {
|
||||||
// prompt += `${task_list.lora},`;
|
prompt += `${task_list.lora}, `;
|
||||||
// }
|
}
|
||||||
// let image_styles = await ImageStyleDefine.getImageStyleStringByIds(task_list.image_style_list ? task_list.image_style_list : []);
|
prompt += imageJson.webui_config.prompt;
|
||||||
|
|
||||||
// prompt = `${prompt}, ${image_styles}, ${imageJson.webui_config.prompt}`;
|
|
||||||
let prompt = imageJson.webui_config.prompt;
|
|
||||||
|
|
||||||
// 判断当前是不是有开修脸修手
|
// 判断当前是不是有开修脸修手
|
||||||
let ADetailer = {
|
let ADetailer = {
|
||||||
args: sd_setting.adetailer
|
args: sd_setting.adetailer
|
||||||
};
|
};
|
||||||
|
|
||||||
if (model == "img2img") {
|
if (model == "img2img") {
|
||||||
let web_api = this.global.config.webui_api_url + 'sdapi/v1/img2img'
|
let web_api = this.global.config.webui_api_url + 'sdapi/v1/img2img'
|
||||||
let sd_config = imageJson["webui_config"];
|
let sd_config = imageJson["webui_config"];
|
||||||
@ -154,7 +275,6 @@ export class SD {
|
|||||||
sd_config.seed = seed;
|
sd_config.seed = seed;
|
||||||
let im = await fspromises.readFile(image, 'binary');
|
let im = await fspromises.readFile(image, 'binary');
|
||||||
sd_config.init_images = [new Buffer.from(im, 'binary').toString('base64')];
|
sd_config.init_images = [new Buffer.from(im, 'binary').toString('base64')];
|
||||||
|
|
||||||
if (imageJson.adetailer) {
|
if (imageJson.adetailer) {
|
||||||
let ta = {
|
let ta = {
|
||||||
ADetailer: ADetailer
|
ADetailer: ADetailer
|
||||||
@ -163,13 +283,11 @@ export class SD {
|
|||||||
}
|
}
|
||||||
sd_config.height = sd_setting.webui.height;
|
sd_config.height = sd_setting.webui.height;
|
||||||
sd_config.width = sd_setting.webui.width;
|
sd_config.width = sd_setting.webui.width;
|
||||||
|
|
||||||
const response = await axios.post(web_api, sd_config);
|
const response = await axios.post(web_api, sd_config);
|
||||||
let info = JSON.parse(response.data.info);
|
let info = JSON.parse(response.data.info);
|
||||||
if (seed == -1) {
|
if (seed == -1) {
|
||||||
seed = info.seed;
|
seed = info.seed;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 目前是单图出图
|
// 目前是单图出图
|
||||||
let images = response.data.images;
|
let images = response.data.images;
|
||||||
let imageData = Buffer.from(images[0].split(",", 1)[0], 'base64');
|
let imageData = Buffer.from(images[0].split(",", 1)[0], 'base64');
|
||||||
@ -253,22 +371,4 @@ export class SD {
|
|||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
*文生图
|
|
||||||
* @param {SD 请求的地址} url
|
|
||||||
* @param {SD请求的body} body
|
|
||||||
*/
|
|
||||||
async txt2img(url, body) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
*图生图
|
|
||||||
* @param {SD 请求的地址} url
|
|
||||||
* @param {SD请求的body} body
|
|
||||||
*/
|
|
||||||
async img2img(url, body) {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@ -662,12 +662,12 @@ export class ClipDraft {
|
|||||||
* 通过 key_frame 返回关键帧数据
|
* 通过 key_frame 返回关键帧数据
|
||||||
* @param {*} key_frame 关键帧配置
|
* @param {*} key_frame 关键帧配置
|
||||||
*/
|
*/
|
||||||
async GetFrameData(key_frame) {
|
async GetFrameData(key_frame_key, key_frame) {
|
||||||
if (key_frame.key_frame == "KFTypePositionY") {
|
if (key_frame_key == "KFTypePositionY") {
|
||||||
return key_frame.up_down_key_frame;
|
return key_frame.up_down_key_frame;
|
||||||
} else if (key_frame.key_frame == "KFTypePositionX") {
|
} else if (key_frame_key == "KFTypePositionX") {
|
||||||
return key_frame.left_right_key_frame;
|
return key_frame.left_right_key_frame;
|
||||||
} else if (key_frame.key_frame == "KFTypeScale") {
|
} else if (key_frame_key == "KFTypeScale") {
|
||||||
return key_frame.scale_key_frame;
|
return key_frame.scale_key_frame;
|
||||||
} else {
|
} else {
|
||||||
return {
|
return {
|
||||||
@ -683,7 +683,8 @@ export class ClipDraft {
|
|||||||
*/
|
*/
|
||||||
async AddKeyFarme() {
|
async AddKeyFarme() {
|
||||||
let img_nodes = (await this.find_draft_node(this.draft_json.tracks, "type", "video")).segments;
|
let img_nodes = (await this.find_draft_node(this.draft_json.tracks, "type", "video")).segments;
|
||||||
let key_frame_tmp_data = JSON.parse(await fspromises.readFile(define.add_keyframe_tmp_path, "utf-8"));
|
let key_frame_tmp_data = await fspromises.readFile(define.add_keyframe_tmp_path, "utf-8");
|
||||||
|
|
||||||
// 添加关键帧
|
// 添加关键帧
|
||||||
// 将最后一个数据修改为背景音乐的最后时间
|
// 将最后一个数据修改为背景音乐的最后时间
|
||||||
this.srt_information[this.srt_information.length - 1].end_time = this.audios_duration_time / 1000;
|
this.srt_information[this.srt_information.length - 1].end_time = this.audios_duration_time / 1000;
|
||||||
@ -693,34 +694,42 @@ export class ClipDraft {
|
|||||||
if (key_frame_setting == null) {
|
if (key_frame_setting == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let key_frame_pos = await this.GetFrameData(key_frame_setting);
|
|
||||||
let isFixedSpeed = key_frame_setting.isFixedSpeed;
|
let isFixedSpeed = key_frame_setting.isFixedSpeed;
|
||||||
let key_frame_time = key_frame_setting.key_frame_time * 1000000;
|
|
||||||
let isDown = true;
|
let isDown = true;
|
||||||
let scale_rate = key_frame_pos.default_scale / 100;
|
|
||||||
|
|
||||||
// 获取通用的关键帧配置,然后添加到每一个图片上面(可以设置时间。当前图片的持续实现小于设置的时间。会计算不要过快)
|
// 获取通用的关键帧配置,然后添加到每一个图片上面(可以设置时间。当前图片的持续实现小于设置的时间。会计算不要过快)
|
||||||
for (let i = 0; i < img_nodes.length; i++) {
|
for (let i = 0; i < img_nodes.length; i++) {
|
||||||
let element = img_nodes[i];
|
let element = img_nodes[i];
|
||||||
let image_duartion = cloneDeep(element.source_timerange.duration);
|
let image_duartion = cloneDeep(element.source_timerange.duration);
|
||||||
|
let key_frame = key_frame_setting.key_frame;
|
||||||
|
// 做随机处理
|
||||||
|
let real_key_frame = key_frame;
|
||||||
|
let key_frame_list = ["KFTypePositionY", "KFTypePositionX", "KFTypeScale"];
|
||||||
|
if (key_frame == "KFTypeRandom") {
|
||||||
|
// 随机获取 key_frame_list 里面的一个数据
|
||||||
|
const randomIndex = Math.floor(Math.random() * key_frame_list.length);
|
||||||
|
real_key_frame = key_frame_list[randomIndex];
|
||||||
|
}
|
||||||
|
|
||||||
|
let key_frame_pos = await this.GetFrameData(real_key_frame, key_frame_setting);
|
||||||
|
|
||||||
|
let key_frame_time = key_frame_setting.key_frame_time * 1000000;
|
||||||
|
let scale_rate = key_frame_pos.default_scale / 100;
|
||||||
|
|
||||||
let up_pos = Math.abs(key_frame_pos.start_position);
|
let up_pos = Math.abs(key_frame_pos.start_position);
|
||||||
let down_pos = Math.abs(key_frame_pos.end_position);
|
let down_pos = Math.abs(key_frame_pos.end_position);
|
||||||
|
let key_frame_tmp = JSON.parse(key_frame_tmp_data)
|
||||||
|
|
||||||
if (key_frame_setting.key_frame == "KFTypePositionY") {
|
if (real_key_frame == "KFTypePositionY") {
|
||||||
|
|
||||||
|
|
||||||
// 勾选了匀速。需要计算时间(计算比例)
|
// 勾选了匀速。需要计算时间(计算比例)
|
||||||
|
|
||||||
if (isFixedSpeed && image_duartion < key_frame_time) {
|
if (isFixedSpeed && image_duartion < key_frame_time) {
|
||||||
let time_rate = image_duartion / key_frame_time;
|
let time_rate = image_duartion / key_frame_time;
|
||||||
up_pos = up_pos * time_rate;
|
up_pos = up_pos * time_rate;
|
||||||
down_pos = down_pos * time_rate;
|
down_pos = down_pos * time_rate;
|
||||||
}
|
}
|
||||||
let key_frame_tmp = cloneDeep(key_frame_tmp_data)
|
|
||||||
let up_pos_rate = isDown ? (up_pos / this.draft_json.canvas_config.height) : (0 - up_pos / this.draft_json.canvas_config.height)
|
let up_pos_rate = isDown ? (up_pos / this.draft_json.canvas_config.height) : (0 - up_pos / this.draft_json.canvas_config.height)
|
||||||
key_frame_tmp.id = uuidv4();
|
key_frame_tmp.id = uuidv4();
|
||||||
key_frame_tmp.keyframe_list[0].id == uuidv4();
|
key_frame_tmp.keyframe_list[0].id = uuidv4(); // Corrected assignment
|
||||||
key_frame_tmp.keyframe_list[0].values = [up_pos_rate];
|
key_frame_tmp.keyframe_list[0].values = [up_pos_rate];
|
||||||
|
|
||||||
let dow_pos_rate = isDown ? (0 - down_pos / this.draft_json.canvas_config.height) : (down_pos / this.draft_json.canvas_config.height)
|
let dow_pos_rate = isDown ? (0 - down_pos / this.draft_json.canvas_config.height) : (down_pos / this.draft_json.canvas_config.height)
|
||||||
@ -728,22 +737,20 @@ export class ClipDraft {
|
|||||||
key_frame_tmp.keyframe_list[1].time_offset = image_duartion;
|
key_frame_tmp.keyframe_list[1].time_offset = image_duartion;
|
||||||
key_frame_tmp.keyframe_list[1].values = [dow_pos_rate];
|
key_frame_tmp.keyframe_list[1].values = [dow_pos_rate];
|
||||||
|
|
||||||
key_frame_tmp.property_type = key_frame_setting.key_frame;
|
key_frame_tmp.property_type = real_key_frame;
|
||||||
|
|
||||||
// 修改缩放倍率
|
// 修改缩放倍率
|
||||||
element.clip.scale.x = scale_rate;
|
element.clip.scale.x = scale_rate;
|
||||||
element.clip.scale.y = scale_rate;
|
element.clip.scale.y = scale_rate;
|
||||||
element.clip.transform.y = dow_pos_rate;
|
element.clip.transform.y = dow_pos_rate;
|
||||||
isDown = !isDown;
|
isDown = !isDown;
|
||||||
element.common_keyframes.push(key_frame_tmp);
|
} else if (real_key_frame == "KFTypePositionX") {
|
||||||
} else if (key_frame_setting.key_frame == "KFTypePositionX") {
|
|
||||||
// 勾选了匀速。需要计算时间(计算比例)
|
// 勾选了匀速。需要计算时间(计算比例)
|
||||||
if (isFixedSpeed && image_duartion < key_frame_time) {
|
if (isFixedSpeed && image_duartion < key_frame_time) {
|
||||||
let time_rate = image_duartion / key_frame_time;
|
let time_rate = image_duartion / key_frame_time;
|
||||||
up_pos = up_pos * time_rate;
|
up_pos = up_pos * time_rate;
|
||||||
down_pos = down_pos * time_rate;
|
down_pos = down_pos * time_rate;
|
||||||
}
|
}
|
||||||
let key_frame_tmp = cloneDeep(key_frame_tmp_data)
|
|
||||||
let up_pos_rate = isDown ? (up_pos / this.draft_json.canvas_config.width) : (0 - up_pos / this.draft_json.canvas_config.width)
|
let up_pos_rate = isDown ? (up_pos / this.draft_json.canvas_config.width) : (0 - up_pos / this.draft_json.canvas_config.width)
|
||||||
key_frame_tmp.id = uuidv4();
|
key_frame_tmp.id = uuidv4();
|
||||||
key_frame_tmp.keyframe_list[0].id == uuidv4();
|
key_frame_tmp.keyframe_list[0].id == uuidv4();
|
||||||
@ -754,16 +761,15 @@ export class ClipDraft {
|
|||||||
key_frame_tmp.keyframe_list[1].time_offset = image_duartion;
|
key_frame_tmp.keyframe_list[1].time_offset = image_duartion;
|
||||||
key_frame_tmp.keyframe_list[1].values = [dow_pos_rate];
|
key_frame_tmp.keyframe_list[1].values = [dow_pos_rate];
|
||||||
|
|
||||||
key_frame_tmp.property_type = key_frame_setting.key_frame;
|
key_frame_tmp.property_type = real_key_frame;
|
||||||
|
|
||||||
// 修改缩放倍率
|
// 修改缩放倍率
|
||||||
element.clip.scale.x = scale_rate;
|
element.clip.scale.x = scale_rate;
|
||||||
element.clip.scale.y = scale_rate;
|
element.clip.scale.y = scale_rate;
|
||||||
element.clip.transform.x = dow_pos_rate;
|
element.clip.transform.x = dow_pos_rate;
|
||||||
isDown = !isDown;
|
isDown = !isDown;
|
||||||
element.common_keyframes.push(key_frame_tmp);
|
|
||||||
}
|
}
|
||||||
else if (key_frame_setting.key_frame == "KFTypeScale") {
|
else if (real_key_frame == "KFTypeScale") {
|
||||||
if (isFixedSpeed && image_duartion < key_frame_time) {
|
if (isFixedSpeed && image_duartion < key_frame_time) {
|
||||||
let time_rate = image_duartion / key_frame_time;
|
let time_rate = image_duartion / key_frame_time;
|
||||||
// 计算方式和上面的不同
|
// 计算方式和上面的不同
|
||||||
@ -774,7 +780,6 @@ export class ClipDraft {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 修改上面的数据,添加Y轴缩放
|
// 修改上面的数据,添加Y轴缩放
|
||||||
let key_frame_tmp = cloneDeep(key_frame_tmp_data)
|
|
||||||
let up_pos_rate = isDown ? up_pos / 100 : down_pos / 100;
|
let up_pos_rate = isDown ? up_pos / 100 : down_pos / 100;
|
||||||
key_frame_tmp.id = uuidv4();
|
key_frame_tmp.id = uuidv4();
|
||||||
key_frame_tmp.keyframe_list[0].id == uuidv4();
|
key_frame_tmp.keyframe_list[0].id == uuidv4();
|
||||||
@ -785,7 +790,7 @@ export class ClipDraft {
|
|||||||
key_frame_tmp.keyframe_list[1].time_offset = image_duartion;
|
key_frame_tmp.keyframe_list[1].time_offset = image_duartion;
|
||||||
key_frame_tmp.keyframe_list[1].values = [dow_pos_rate];
|
key_frame_tmp.keyframe_list[1].values = [dow_pos_rate];
|
||||||
|
|
||||||
key_frame_tmp.property_type = key_frame_setting.key_frame + "X";
|
key_frame_tmp.property_type = real_key_frame + "X";
|
||||||
|
|
||||||
// 修改上面的数据,添加Y轴缩放
|
// 修改上面的数据,添加Y轴缩放
|
||||||
// 修改缩放倍率
|
// 修改缩放倍率
|
||||||
@ -794,15 +799,15 @@ export class ClipDraft {
|
|||||||
element.clip.transform.x = 0;
|
element.clip.transform.x = 0;
|
||||||
element.common_keyframes.push(key_frame_tmp);
|
element.common_keyframes.push(key_frame_tmp);
|
||||||
|
|
||||||
key_frame_tmp = cloneDeep(key_frame_tmp)
|
|
||||||
|
key_frame_tmp = JSON.parse(JSON.stringify(key_frame_tmp))
|
||||||
key_frame_tmp.id = uuidv4();
|
key_frame_tmp.id = uuidv4();
|
||||||
key_frame_tmp.keyframe_list[0].id == uuidv4();
|
key_frame_tmp.keyframe_list[0].id == uuidv4();
|
||||||
key_frame_tmp.keyframe_list[1].id = uuidv4();
|
key_frame_tmp.keyframe_list[1].id = uuidv4();
|
||||||
key_frame_tmp.property_type = key_frame_setting.key_frame + "Y";
|
key_frame_tmp.property_type = real_key_frame + "Y";
|
||||||
element.common_keyframes.push(key_frame_tmp);
|
|
||||||
|
|
||||||
isDown = !isDown;
|
isDown = !isDown;
|
||||||
}
|
}
|
||||||
|
element.common_keyframes.push(key_frame_tmp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -12,7 +12,6 @@ const sharp = require('sharp');
|
|||||||
const execAsync = util.promisify(exec);
|
const execAsync = util.promisify(exec);
|
||||||
const { v4: uuidv4 } = require('uuid'); // 引入UUID库来生成唯一标识符
|
const { v4: uuidv4 } = require('uuid'); // 引入UUID库来生成唯一标识符
|
||||||
let fspromises = require("fs").promises;
|
let fspromises = require("fs").promises;
|
||||||
import { MD5 } from "crypto-js";
|
|
||||||
import { ImageSetting } from "../../define/setting/imageSetting";
|
import { ImageSetting } from "../../define/setting/imageSetting";
|
||||||
|
|
||||||
|
|
||||||
@ -257,7 +256,7 @@ export class ImageGenerate {
|
|||||||
if (images.length <= 0) {
|
if (images.length <= 0) {
|
||||||
throw new Error("未检测到抽帧图片。请检查");
|
throw new Error("未检测到抽帧图片。请检查");
|
||||||
}
|
}
|
||||||
if (images.length > auto_save_image.save_match_count) {
|
if (auto_save_image.save_match_count && auto_save_image.auto_match && images.length > auto_save_image.save_match_count) {
|
||||||
png_files = await this.tools.getFilesWithExtensions(auto_save_image.main_save_folder, '.png');
|
png_files = await this.tools.getFilesWithExtensions(auto_save_image.main_save_folder, '.png');
|
||||||
}
|
}
|
||||||
this.global.requestQuene.enqueue(async () => {
|
this.global.requestQuene.enqueue(async () => {
|
||||||
|
|||||||
@ -1,14 +1,6 @@
|
|||||||
const axios = require('axios');
|
const axios = require('axios');
|
||||||
// import { Midjourney as mApi} from "midjourney";
|
|
||||||
// const MJapi2 = require('midjourney');
|
|
||||||
// const { midjourney } = require('midjourney')
|
|
||||||
// const Midjourney = require('midjourney');
|
|
||||||
// ES5 的模块引入方式
|
|
||||||
const fetch = require("node-fetch");
|
const fetch = require("node-fetch");
|
||||||
|
|
||||||
// ES6 的模块引入方式
|
|
||||||
// import fetch from "node-fetch";
|
|
||||||
|
|
||||||
export class DiscordAPI {
|
export class DiscordAPI {
|
||||||
constructor(mj_setting) {
|
constructor(mj_setting) {
|
||||||
// https://discord.com/api/v9/channels/1208362852482809939/messages?limit=20
|
// https://discord.com/api/v9/channels/1208362852482809939/messages?limit=20
|
||||||
|
|||||||
@ -134,7 +134,7 @@ async function ReGenerateImageOne(window, value) {
|
|||||||
|
|
||||||
let image_styles = await ImageStyleDefine.getImageStyleStringByIds(value[1].image_style_list ? value[1].image_style_list : []);
|
let image_styles = await ImageStyleDefine.getImageStyleStringByIds(value[1].image_style_list ? value[1].image_style_list : []);
|
||||||
|
|
||||||
let prompt = image_styles;
|
let prompt = sd_setting.webui.prompt + image_styles;
|
||||||
// 拼接提示词
|
// 拼接提示词
|
||||||
if (value[1].image_style != null) {
|
if (value[1].image_style != null) {
|
||||||
prompt += `((${value[1].image_style})),`;
|
prompt += `((${value[1].image_style})),`;
|
||||||
@ -143,6 +143,8 @@ async function ReGenerateImageOne(window, value) {
|
|||||||
prompt += `${value[1].lora},`;
|
prompt += `${value[1].lora},`;
|
||||||
}
|
}
|
||||||
prompt += value[1].prompt;
|
prompt += value[1].prompt;
|
||||||
|
|
||||||
|
|
||||||
let model = value[1].model;
|
let model = value[1].model;
|
||||||
|
|
||||||
// 判断当前是不是有开修脸修手
|
// 判断当前是不是有开修脸修手
|
||||||
@ -624,8 +626,12 @@ async function SaveSDConfig(value) {
|
|||||||
try {
|
try {
|
||||||
let sd_config = JSON.parse((await fspromises.readFile(define.sd_setting, "utf-8")).toString());
|
let sd_config = JSON.parse((await fspromises.readFile(define.sd_setting, "utf-8")).toString());
|
||||||
global.config.webui_api_url = value.webui_api_url || value.webui_api_url == '' ? value.webui_api_url : global.config.webui_api_url;
|
global.config.webui_api_url = value.webui_api_url || value.webui_api_url == '' ? value.webui_api_url : global.config.webui_api_url;
|
||||||
|
|
||||||
sd_config.setting.webui_api_url = value.webui_api_url || value.webui_api_url == "" ? value.webui_api_url : sd_config.setting.webui_api_url;
|
sd_config.setting.webui_api_url = value.webui_api_url || value.webui_api_url == "" ? value.webui_api_url : sd_config.setting.webui_api_url;
|
||||||
sd_config.setting.type = value.type ? value.type : sd_config.setting.type;
|
sd_config.setting.type = value.type ? value.type : sd_config.setting.type;
|
||||||
|
sd_config.setting.batch_size = value.batch_size ? value.batch_size : sd_config.setting.batch_size;
|
||||||
|
sd_config.setting.style_weight = value.style_weight ? value.style_weight : sd_config.setting.style_weight;
|
||||||
|
|
||||||
sd_config.webui.prompt = value.prompt || value.prompt == "" ? value.prompt : sd_config.webui.prompt;
|
sd_config.webui.prompt = value.prompt || value.prompt == "" ? value.prompt : sd_config.webui.prompt;
|
||||||
sd_config.webui.negative_prompt = value.negative_prompt || value.negative_prompt == "" ? value.negative_prompt : sd_config.webui.negative_prompt;
|
sd_config.webui.negative_prompt = value.negative_prompt || value.negative_prompt == "" ? value.negative_prompt : sd_config.webui.negative_prompt;
|
||||||
sd_config.webui.denoising_strength = value.denoising_strength || value.denoising_strength == "" ? value.denoising_strength : sd_config.webui.denoising_strength;
|
sd_config.webui.denoising_strength = value.denoising_strength || value.denoising_strength == "" ? value.denoising_strength : sd_config.webui.denoising_strength;
|
||||||
@ -635,8 +641,6 @@ async function SaveSDConfig(value) {
|
|||||||
sd_config.webui.height = value.height ? value.height : sd_config.webui.height;
|
sd_config.webui.height = value.height ? value.height : sd_config.webui.height;
|
||||||
sd_config.webui.cfg_scale = value.cfg_scale ? value.cfg_scale : sd_config.webui.cfg_scale;
|
sd_config.webui.cfg_scale = value.cfg_scale ? value.cfg_scale : sd_config.webui.cfg_scale;
|
||||||
sd_config.webui.adetailer = value.adetailer ? value.adetailer : sd_config.webui.adetailer;
|
sd_config.webui.adetailer = value.adetailer ? value.adetailer : sd_config.webui.adetailer;
|
||||||
sd_config.setting.batch_size = value.batch_size ? value.batch_size : sd_config.setting.batch_size;
|
|
||||||
sd_config.setting.style_weight = value.style_weight ? value.style_weight : sd_config.setting.style_weight;
|
|
||||||
|
|
||||||
await fspromises.writeFile(define.sd_setting, JSON.stringify(sd_config));
|
await fspromises.writeFile(define.sd_setting, JSON.stringify(sd_config));
|
||||||
return {
|
return {
|
||||||
|
|||||||
102
src/main/generalTools.js
Normal file
102
src/main/generalTools.js
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
/**
|
||||||
|
* 判断字符串的值是不是存在,不是null,不是undefined,不是空字符串,存在的话添加指定的后缀
|
||||||
|
* @param {*} value 要检查的字符串
|
||||||
|
* @param {*} suffix 要添加的后缀
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
function checkStringValueAddSuffix(value, suffix) {
|
||||||
|
if (value && value !== null && value !== undefined && value !== '') {
|
||||||
|
return value + suffix;
|
||||||
|
} else {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断字符串的值是不是存在,不是null,不是undefined,不是空字符串,存在的话添加指定的前缀
|
||||||
|
* @param {*} value 要检查的值
|
||||||
|
* @param {*} prefix 要添加的前缀
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
|
||||||
|
function checkStringValueAddPrefix(value, prefix) {
|
||||||
|
if (value && value !== null && value !== undefined && value !== '') {
|
||||||
|
return prefix + value;
|
||||||
|
} else {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新建一个函数,判断传入的字符串的值是不是存在,存在的话删除后面指定数量的字符
|
||||||
|
* @param {*} value 要删除的字符串
|
||||||
|
* @param {*} suffix 删除的后缀
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
function checkStringValueDeleteSuffix(value, suffix) {
|
||||||
|
// 增加一个判断,当前删除的数量是不是大于字符串的长度
|
||||||
|
if (value && value !== null && value !== undefined && value !== '') {
|
||||||
|
if (suffix.length > value.length) {
|
||||||
|
return '';
|
||||||
|
} else {
|
||||||
|
return value.slice(0, value.length - suffix.length);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新建一个函数,判断传入的字符串的值是不是存在,存在的话删除前面指定数量的字符
|
||||||
|
* @param {*} value 操作的字符串
|
||||||
|
* @param {*} prefix 要删除的字符串
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
function checkStringValueDeletePrefix(value, prefix) {
|
||||||
|
// 增加一个判断,当前删除的数量是不是大于字符串的长度
|
||||||
|
if (value && value !== null && value !== undefined && value !== '') {
|
||||||
|
if (prefix.length > value.length) {
|
||||||
|
return '';
|
||||||
|
} else {
|
||||||
|
return value.slice(prefix.length);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 返回成功的消息,包含code,data,message
|
||||||
|
* @param {*} code
|
||||||
|
* @param {*} data
|
||||||
|
* @param {*} message
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
function successMessage(data, message = null) {
|
||||||
|
return {
|
||||||
|
code: 1,
|
||||||
|
data: data,
|
||||||
|
message: message
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 返回失败的消息,包含code,message
|
||||||
|
* @param {*} code
|
||||||
|
* @param {*} message
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
function errorMessage(message) {
|
||||||
|
return {
|
||||||
|
code: 0,
|
||||||
|
message: message
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export {
|
||||||
|
checkStringValueAddSuffix,
|
||||||
|
checkStringValueAddPrefix,
|
||||||
|
checkStringValueDeletePrefix,
|
||||||
|
checkStringValueDeleteSuffix,
|
||||||
|
successMessage,
|
||||||
|
errorMessage
|
||||||
|
}
|
||||||
@ -1,3 +1,8 @@
|
|||||||
|
import fspromises from "fs/promises";
|
||||||
|
import { v4 as uuidv4 } from 'uuid';
|
||||||
|
import { version } from '../../package.json'
|
||||||
|
|
||||||
|
|
||||||
import { app, shell, BrowserWindow, ipcMain, dialog, nativeTheme } from 'electron'
|
import { app, shell, BrowserWindow, ipcMain, dialog, nativeTheme } from 'electron'
|
||||||
import path, { join } from 'path'
|
import path, { join } from 'path'
|
||||||
import { electronApp, optimizer, is } from '@electron-toolkit/utils'
|
import { electronApp, optimizer, is } from '@electron-toolkit/utils'
|
||||||
@ -6,10 +11,6 @@ import { define } from '../define/define.js'
|
|||||||
import { func } from './func.js'
|
import { func } from './func.js'
|
||||||
import { AsyncQueue } from "./quene.js"
|
import { AsyncQueue } from "./quene.js"
|
||||||
import { DEFINE_STRING } from '../define/define_string.js'
|
import { DEFINE_STRING } from '../define/define_string.js'
|
||||||
const fspromises = require("fs").promises;
|
|
||||||
const { v4: uuidv4 } = require('uuid');
|
|
||||||
const { version } = require('../../package.json')
|
|
||||||
|
|
||||||
import { Tools } from './tools.js'
|
import { Tools } from './tools.js'
|
||||||
import { ImageGenerate } from './backPrompt/imageGenerate.js'
|
import { ImageGenerate } from './backPrompt/imageGenerate.js'
|
||||||
import { Setting } from './setting/setting.js'
|
import { Setting } from './setting/setting.js'
|
||||||
@ -27,12 +28,14 @@ import { OriginalImageGenerateIpc } from './IPCEvent/originalImageGenerateIpc'
|
|||||||
import { SdIpc } from './IPCEvent/sdIpc.js'
|
import { SdIpc } from './IPCEvent/sdIpc.js'
|
||||||
import { DiscordIpc, RemoveDiscordIpc } from './IPCEvent/discordIpc.js'
|
import { DiscordIpc, RemoveDiscordIpc } from './IPCEvent/discordIpc.js'
|
||||||
import { MainIpc } from './IPCEvent/mainIpc.js'
|
import { MainIpc } from './IPCEvent/mainIpc.js'
|
||||||
|
import { GlobalIpc } from "./IPCEvent/globalIpc.js";
|
||||||
|
|
||||||
let tools = new Tools();
|
let tools = new Tools();
|
||||||
let imageGenerate = new ImageGenerate(global);
|
let imageGenerate = new ImageGenerate(global);
|
||||||
let setting = new Setting(global);
|
let setting = new Setting(global);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
async function InitData(gl) {
|
async function InitData(gl) {
|
||||||
let res = await setting.getSettingDafultData();
|
let res = await setting.getSettingDafultData();
|
||||||
gl.config = res;
|
gl.config = res;
|
||||||
@ -55,11 +58,17 @@ function removeIpcHandler(hash) {
|
|||||||
|
|
||||||
async function createWindow(hash = "ShowMessage", data, url = null) {
|
async function createWindow(hash = "ShowMessage", data, url = null) {
|
||||||
// Create the browser window.
|
// Create the browser window.
|
||||||
|
await InitData(global);
|
||||||
global.currentHash = hash;
|
global.currentHash = hash;
|
||||||
|
// 判断当前是不是有设置的宽高,用的话记忆
|
||||||
|
let isRe = global.config.window_wh_bm_remember && hash == "ShowMessage" && global.config.window_wh_bm;
|
||||||
|
|
||||||
|
|
||||||
let mainWindow = new BrowserWindow({
|
let mainWindow = new BrowserWindow({
|
||||||
width: 900,
|
width: isRe ? global.config.window_wh_bm.width : 900,
|
||||||
height: 670,
|
height: isRe ? global.config.window_wh_bm.height : 675,
|
||||||
|
x: isRe ? global.config.window_wh_bm.x : 100,
|
||||||
|
y: isRe ? global.config.window_wh_bm.y : 100,
|
||||||
title: 'LAITool',
|
title: 'LAITool',
|
||||||
icon: '../../resources/icon.ico',
|
icon: '../../resources/icon.ico',
|
||||||
show: false,
|
show: false,
|
||||||
@ -104,10 +113,16 @@ async function createWindow(hash = "ShowMessage", data, url = null) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mainWindow.on("closed", () => {
|
mainWindow.on("close", async () => {
|
||||||
// 判断指定的窗口,移除指定的监听
|
// 判断指定的窗口,移除指定的监听
|
||||||
removeIpcHandler(hash);
|
removeIpcHandler(hash);
|
||||||
global.newWindow = global.newWindow.filter(item => item.id != mainWindow.id)
|
global.newWindow = global.newWindow.filter(item => item.id != mainWindow.id)
|
||||||
|
// 判断当前的是不是开启了记录功能
|
||||||
|
if (global.config.window_wh_bm_remember && hash == "ShowMessage") {
|
||||||
|
let window_wh_bm = mainWindow.getBounds();
|
||||||
|
// 记录到文件中
|
||||||
|
await setting.ModifySampleSetting(JSON.stringify({ window_wh_bm: window_wh_bm }))
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
// 创建一个新的窗口,添加对应的监听
|
// 创建一个新的窗口,添加对应的监听
|
||||||
@ -120,7 +135,6 @@ async function createWindow(hash = "ShowMessage", data, url = null) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
setIpcHandler(hash);
|
setIpcHandler(hash);
|
||||||
await InitData(global);
|
|
||||||
return mainWindow;
|
return mainWindow;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -141,6 +155,8 @@ app.whenReady().then(async () => {
|
|||||||
optimizer.watchWindowShortcuts(window)
|
optimizer.watchWindowShortcuts(window)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
global.newWindow = [];
|
global.newWindow = [];
|
||||||
mainWindow = createWindow('ShowMessage', null)
|
mainWindow = createWindow('ShowMessage', null)
|
||||||
|
|
||||||
@ -173,9 +189,12 @@ app.whenReady().then(async () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 判断动态文件是不是存在
|
// 判断动态文件是不是存在
|
||||||
tools.checkJsonFileExistsOrCreate(path.join(define.dynamic_setting));
|
tools.checkJsonFileExistsOrCreate(path.normalize(define.dynamic_setting));
|
||||||
// 判断标签文件是不是存在
|
// 判断标签文件是不是存在
|
||||||
tools.checkJsonFileExistsOrCreate(path.join(define.tag_setting));
|
tools.checkJsonFileExistsOrCreate(path.normalize(define.tag_setting));
|
||||||
|
// 判断SD图片缓存文件是不是存在(不存在创建)
|
||||||
|
tools.checkFolderExistsOrCreate(path.normalize(define.temp_sd_image));
|
||||||
|
tools.checkFolderExistsOrCreate(path.normalize(path.join(define.image_path, "c_s")));
|
||||||
|
|
||||||
app.on('activate', function () {
|
app.on('activate', function () {
|
||||||
// On macOS it's common to re-create a window in the app when the
|
// On macOS it's common to re-create a window in the app when the
|
||||||
@ -204,6 +223,7 @@ SdIpc();
|
|||||||
MjIpc();
|
MjIpc();
|
||||||
MainIpc(createWindow);
|
MainIpc(createWindow);
|
||||||
OriginalImageGenerateIpc();
|
OriginalImageGenerateIpc();
|
||||||
|
GlobalIpc();
|
||||||
|
|
||||||
|
|
||||||
ipcMain.handle('dark-mode:toggle', (event, value) => {
|
ipcMain.handle('dark-mode:toggle', (event, value) => {
|
||||||
|
|||||||
@ -162,6 +162,9 @@ export class Setting {
|
|||||||
seed: sd_config.setting.seed,
|
seed: sd_config.setting.seed,
|
||||||
style_weight: sd_config.setting.style_weight,
|
style_weight: sd_config.setting.style_weight,
|
||||||
cfg_scale: sd_config.webui.cfg_scale,
|
cfg_scale: sd_config.webui.cfg_scale,
|
||||||
|
sd_model: sd_config.sd_model,
|
||||||
|
lora: sd_config.lora,
|
||||||
|
sampler: sd_config.sampler,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@ -226,6 +229,7 @@ export class Setting {
|
|||||||
let sd_data = await fspromises.readFile(define.sd_setting, 'utf-8');
|
let sd_data = await fspromises.readFile(define.sd_setting, 'utf-8');
|
||||||
let config_json_date = JSON.parse(data);
|
let config_json_date = JSON.parse(data);
|
||||||
config_json_date.webui_api_url = JSON.parse(sd_data).setting.webui_api_url;
|
config_json_date.webui_api_url = JSON.parse(sd_data).setting.webui_api_url;
|
||||||
|
config_json_date["space_image"] = define.zhanwei_image;
|
||||||
return config_json_date;
|
return config_json_date;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -25,6 +25,21 @@ export class Tools {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取指定的文件,然后将其转换为base64
|
||||||
|
* @param {*} filePath 文件地址
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
async readFileBase64(filePath) {
|
||||||
|
try {
|
||||||
|
let data = await fspromises.readFile(filePath);
|
||||||
|
return data.toString('base64');
|
||||||
|
}
|
||||||
|
catch (error) {
|
||||||
|
throw new Error(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 判断json文件是不是存在,不存在的话,协议一个空的json文件
|
* 判断json文件是不是存在,不存在的话,协议一个空的json文件
|
||||||
@ -301,7 +316,6 @@ export class Tools {
|
|||||||
method: 'GET',
|
method: 'GET',
|
||||||
url: url
|
url: url
|
||||||
});
|
});
|
||||||
|
|
||||||
request.on('response', (response) => {
|
request.on('response', (response) => {
|
||||||
const chunks = [];
|
const chunks = [];
|
||||||
response.on('data', (chunk) => chunks.push(chunk));
|
response.on('data', (chunk) => chunks.push(chunk));
|
||||||
@ -323,4 +337,29 @@ export class Tools {
|
|||||||
request.end();
|
request.end();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将base64保存为图片,然后删除图片的exif信息
|
||||||
|
* @param {*} base64 图片的base64数据
|
||||||
|
* @param {*} filePath 保存文件地址
|
||||||
|
* @param {*} isDeleteExif 是不是要删除exif信息(默认为true)
|
||||||
|
*/
|
||||||
|
async saveBase64ToImage(base64, filePath, isDeleteExif = true) {
|
||||||
|
try {
|
||||||
|
let base64Data = base64.replace(/^data:image\/\w+;base64,/, "");
|
||||||
|
let dataBuffer = Buffer.from(base64Data, 'base64');
|
||||||
|
if (isDeleteExif) {
|
||||||
|
// 先将图片写道一个缓存位置,清除数据的时候,将原图片的exif信息删除,然后将原图片复制到目标图片地址
|
||||||
|
let dir = path.dirname(filePath);
|
||||||
|
let tempFilePath = path.join(dir, `temp_${Date.now()}.png`);
|
||||||
|
await fspromises.writeFile(tempFilePath, dataBuffer);
|
||||||
|
this.deletePngAndDeleteExifData(tempFilePath, filePath);
|
||||||
|
} else {
|
||||||
|
await fspromises.writeFile(filePath, dataBuffer);
|
||||||
|
}
|
||||||
|
return filePath;
|
||||||
|
} catch (error) {
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -1,9 +1,7 @@
|
|||||||
import { contextBridge, ipcRenderer } from 'electron'
|
import { ipcRenderer } from 'electron'
|
||||||
import { DEFINE_STRING } from '../define/define_string.js';
|
import { DEFINE_STRING } from '../define/define_string.js';
|
||||||
// Custom APIs for renderer
|
// Custom APIs for renderer
|
||||||
|
const discord = {
|
||||||
let events = [];
|
|
||||||
const api = {
|
|
||||||
// 创建MJ消息
|
// 创建MJ消息
|
||||||
CreateMessage: (value) => ipcRenderer.send(DEFINE_STRING.DISCORD.CREATE_MESSAGE, value),
|
CreateMessage: (value) => ipcRenderer.send(DEFINE_STRING.DISCORD.CREATE_MESSAGE, value),
|
||||||
|
|
||||||
@ -13,16 +11,7 @@ const api = {
|
|||||||
// MJ消息删除
|
// MJ消息删除
|
||||||
DeleteMessage: (value) => ipcRenderer.send(DEFINE_STRING.DISCORD.DELETE_MESSAGE, value),
|
DeleteMessage: (value) => ipcRenderer.send(DEFINE_STRING.DISCORD.DELETE_MESSAGE, value),
|
||||||
}
|
}
|
||||||
// Use `contextBridge` APIs to expose Electron APIs to
|
|
||||||
// renderer only if context isolation is enabled, otherwise
|
|
||||||
// just add to the DOM global.
|
|
||||||
if (process.contextIsolated) {
|
|
||||||
try {
|
|
||||||
contextBridge.exposeInMainWorld('api', api)
|
|
||||||
} catch (error) {
|
|
||||||
console.error(error)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
window.api = api
|
|
||||||
}
|
|
||||||
|
|
||||||
|
export {
|
||||||
|
discord
|
||||||
|
}
|
||||||
@ -1,6 +1,9 @@
|
|||||||
import { contextBridge, ipcRenderer } from 'electron'
|
import { contextBridge, ipcRenderer } from 'electron'
|
||||||
import { electronAPI } from '@electron-toolkit/preload'
|
import { electronAPI } from '@electron-toolkit/preload'
|
||||||
import { DEFINE_STRING } from '../define/define_string.js';
|
import { DEFINE_STRING } from '../define/define_string.js';
|
||||||
|
import { discord } from './discord.js';
|
||||||
|
import { mj } from './mj.js';
|
||||||
|
import { sd } from './sd.js';
|
||||||
// Custom APIs for renderer
|
// Custom APIs for renderer
|
||||||
|
|
||||||
let events = [];
|
let events = [];
|
||||||
@ -389,56 +392,11 @@ const api = {
|
|||||||
|
|
||||||
// 打开全局通知框
|
// 打开全局通知框
|
||||||
showGlobalNotificationDialog: (value) => ipcRenderer.send(DEFINE_STRING.SHOW_MAIN_NOTIFICATION, value),
|
showGlobalNotificationDialog: (value) => ipcRenderer.send(DEFINE_STRING.SHOW_MAIN_NOTIFICATION, value),
|
||||||
|
|
||||||
|
// 知道文件地址,获取文件base64编码
|
||||||
|
GetFileBase64: async (value, callback) => callback(await ipcRenderer.invoke(DEFINE_STRING.GET_FILE_BASE64, value)),
|
||||||
}
|
}
|
||||||
|
|
||||||
const mj = {
|
|
||||||
// 保存文案信息到mj的配置文件
|
|
||||||
SvaeMJWordSrt: async (value, callback) => callback(await ipcRenderer.invoke(DEFINE_STRING.MJ.SAVE_WORD_SRT, value)),
|
|
||||||
// 获取MJ配置文件的字幕信息
|
|
||||||
GetMJConfigSrtInformation: async (callback) => callback(await ipcRenderer.invoke(DEFINE_STRING.MJ.GET_MJ_CONFIG_SRT_INFORMATION)),
|
|
||||||
// 获取标签集的基础信息
|
|
||||||
GetTagDataByTypeAndProperty: async (value, callback) => callback(await ipcRenderer.invoke(DEFINE_STRING.MJ.GET_TAG_DATA_BY_TYPE_AND_PROPERTY, value)),
|
|
||||||
// 保存数据到标签集中
|
|
||||||
SaveTagPropertyData: async (value, callback) => callback(await ipcRenderer.invoke(DEFINE_STRING.MJ.SAVE_TAG_PROPERTY_DATA, value)),
|
|
||||||
// 删除指定的标签数据
|
|
||||||
DeleteTagPropertyData: async (value, callback) => callback(await ipcRenderer.invoke(DEFINE_STRING.MJ.DELETE_TAG_PROPERTY_DATA, value)),
|
|
||||||
// 获取选择标签的模式option列表
|
|
||||||
GetTagSelectModel: async (callback) => callback(await ipcRenderer.invoke(DEFINE_STRING.MJ.GET_TAG_SELECT_MODEL)),
|
|
||||||
// 将翻译任务添加到后台队列中
|
|
||||||
TranslateReturnNowTask: async (value, callback) => callback(await ipcRenderer.invoke(DEFINE_STRING.MJ.TRANSLATE_RETURN_NOW_TASK, value)),
|
|
||||||
// MJ原创生图
|
|
||||||
OriginalMJImageGenerate: async (value, callback) => callback(await ipcRenderer.invoke(DEFINE_STRING.MJ.ORIGINAL_MJ_IMAGE_GENERATE, value)),
|
|
||||||
// 获取当前对话频道的机器人列表
|
|
||||||
GetChannelRobots: async (value, callback) => callback(await ipcRenderer.invoke(DEFINE_STRING.MJ.GET_CHANNEL_ROBOTS, value)),
|
|
||||||
|
|
||||||
// 获取MJ生图的方式
|
|
||||||
GetMJGenerateCategory: async (callback) => callback(await ipcRenderer.invoke(DEFINE_STRING.MJ.GET_MJ_GENERATE_CATEGORY)),
|
|
||||||
|
|
||||||
// MJ生成的图片分割
|
|
||||||
ImageSplit: async (value, callback) => callback(await ipcRenderer.invoke(DEFINE_STRING.MJ.IMAGE_SPLIT, value)),
|
|
||||||
|
|
||||||
// 添加MJ敏感词
|
|
||||||
AddMjBadPrompt: async (value, callback) => callback(await ipcRenderer.invoke(DEFINE_STRING.MJ.ADD_MJ_BAD_PROMPT, value)),
|
|
||||||
// 添加MJ敏感词检查
|
|
||||||
MJBadPromptCheck: async (value, callback) => callback(await ipcRenderer.invoke(DEFINE_STRING.MJ.MJ_BAD_PROMPT_CHECK, value)),
|
|
||||||
|
|
||||||
// 获取已经生图完成的数据,并获取图片
|
|
||||||
GetGeneratedMJImageAndSplit: async (value, callback) => callback(await ipcRenderer.invoke(DEFINE_STRING.MJ.GET_GENERATED_MJ_IMAGE_AND_SPLIT, value)),
|
|
||||||
|
|
||||||
// 给图片链接,下载指定的图片并分割保存
|
|
||||||
DownloadImageUrlAndSplit : async (value, callback) => callback(await ipcRenderer.invoke(DEFINE_STRING.MJ.DOWNLOAD_IMAGE_URL_AND_SPLIT, value)),
|
|
||||||
}
|
|
||||||
|
|
||||||
const discord = {
|
|
||||||
// 创建MJ消息
|
|
||||||
CreateMessage: (value) => ipcRenderer.send(DEFINE_STRING.DISCORD.CREATE_MESSAGE, value),
|
|
||||||
|
|
||||||
// MJ消息更新
|
|
||||||
UpdateMessage: (value) => ipcRenderer.send(DEFINE_STRING.DISCORD.UPDATE_MESSAGE, value),
|
|
||||||
|
|
||||||
// MJ消息删除
|
|
||||||
DeleteMessage: (value) => ipcRenderer.send(DEFINE_STRING.DISCORD.DELETE_MESSAGE, value),
|
|
||||||
}
|
|
||||||
// Use `contextBridge` APIs to expose Electron APIs to
|
// Use `contextBridge` APIs to expose Electron APIs to
|
||||||
// renderer only if context isolation is enabled, otherwise
|
// renderer only if context isolation is enabled, otherwise
|
||||||
// just add to the DOM global.
|
// just add to the DOM global.
|
||||||
@ -448,6 +406,7 @@ if (process.contextIsolated) {
|
|||||||
contextBridge.exposeInMainWorld('api', api)
|
contextBridge.exposeInMainWorld('api', api)
|
||||||
contextBridge.exposeInMainWorld('mj', mj)
|
contextBridge.exposeInMainWorld('mj', mj)
|
||||||
contextBridge.exposeInMainWorld('discord', discord)
|
contextBridge.exposeInMainWorld('discord', discord)
|
||||||
|
contextBridge.exposeInMainWorld("sd", sd)
|
||||||
contextBridge.exposeInMainWorld('darkMode', {
|
contextBridge.exposeInMainWorld('darkMode', {
|
||||||
toggle: (value) => ipcRenderer.invoke('dark-mode:toggle', value),
|
toggle: (value) => ipcRenderer.invoke('dark-mode:toggle', value),
|
||||||
})
|
})
|
||||||
@ -459,5 +418,6 @@ if (process.contextIsolated) {
|
|||||||
window.api = api;
|
window.api = api;
|
||||||
window.mj = mj;
|
window.mj = mj;
|
||||||
window.discord = discord;
|
window.discord = discord;
|
||||||
|
window.sd = sd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
44
src/preload/mj.js
Normal file
44
src/preload/mj.js
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
import { ipcRenderer } from "electron";
|
||||||
|
import { DEFINE_STRING } from "../define/define_string";
|
||||||
|
|
||||||
|
const mj = {
|
||||||
|
// 保存文案信息到mj的配置文件
|
||||||
|
SvaeMJWordSrt: async (value, callback) => callback(await ipcRenderer.invoke(DEFINE_STRING.MJ.SAVE_WORD_SRT, value)),
|
||||||
|
// 获取MJ配置文件的字幕信息
|
||||||
|
GetMJConfigSrtInformation: async (callback) => callback(await ipcRenderer.invoke(DEFINE_STRING.MJ.GET_MJ_CONFIG_SRT_INFORMATION)),
|
||||||
|
// 获取标签集的基础信息
|
||||||
|
GetTagDataByTypeAndProperty: async (value, callback) => callback(await ipcRenderer.invoke(DEFINE_STRING.MJ.GET_TAG_DATA_BY_TYPE_AND_PROPERTY, value)),
|
||||||
|
// 保存数据到标签集中
|
||||||
|
SaveTagPropertyData: async (value, callback) => callback(await ipcRenderer.invoke(DEFINE_STRING.MJ.SAVE_TAG_PROPERTY_DATA, value)),
|
||||||
|
// 删除指定的标签数据
|
||||||
|
DeleteTagPropertyData: async (value, callback) => callback(await ipcRenderer.invoke(DEFINE_STRING.MJ.DELETE_TAG_PROPERTY_DATA, value)),
|
||||||
|
// 获取选择标签的模式option列表
|
||||||
|
GetTagSelectModel: async (callback) => callback(await ipcRenderer.invoke(DEFINE_STRING.MJ.GET_TAG_SELECT_MODEL)),
|
||||||
|
// 将翻译任务添加到后台队列中
|
||||||
|
TranslateReturnNowTask: async (value, callback) => callback(await ipcRenderer.invoke(DEFINE_STRING.MJ.TRANSLATE_RETURN_NOW_TASK, value)),
|
||||||
|
// MJ原创生图
|
||||||
|
OriginalMJImageGenerate: async (value, callback) => callback(await ipcRenderer.invoke(DEFINE_STRING.MJ.ORIGINAL_MJ_IMAGE_GENERATE, value)),
|
||||||
|
// 获取当前对话频道的机器人列表
|
||||||
|
GetChannelRobots: async (value, callback) => callback(await ipcRenderer.invoke(DEFINE_STRING.MJ.GET_CHANNEL_ROBOTS, value)),
|
||||||
|
|
||||||
|
// 获取MJ生图的方式
|
||||||
|
GetMJGenerateCategory: async (callback) => callback(await ipcRenderer.invoke(DEFINE_STRING.MJ.GET_MJ_GENERATE_CATEGORY)),
|
||||||
|
|
||||||
|
// MJ生成的图片分割
|
||||||
|
ImageSplit: async (value, callback) => callback(await ipcRenderer.invoke(DEFINE_STRING.MJ.IMAGE_SPLIT, value)),
|
||||||
|
|
||||||
|
// 添加MJ敏感词
|
||||||
|
AddMjBadPrompt: async (value, callback) => callback(await ipcRenderer.invoke(DEFINE_STRING.MJ.ADD_MJ_BAD_PROMPT, value)),
|
||||||
|
// 添加MJ敏感词检查
|
||||||
|
MJBadPromptCheck: async (value, callback) => callback(await ipcRenderer.invoke(DEFINE_STRING.MJ.MJ_BAD_PROMPT_CHECK, value)),
|
||||||
|
|
||||||
|
// 获取已经生图完成的数据,并获取图片
|
||||||
|
GetGeneratedMJImageAndSplit: async (value, callback) => callback(await ipcRenderer.invoke(DEFINE_STRING.MJ.GET_GENERATED_MJ_IMAGE_AND_SPLIT, value)),
|
||||||
|
|
||||||
|
// 给图片链接,下载指定的图片并分割保存
|
||||||
|
DownloadImageUrlAndSplit: async (value, callback) => callback(await ipcRenderer.invoke(DEFINE_STRING.MJ.DOWNLOAD_IMAGE_URL_AND_SPLIT, value)),
|
||||||
|
}
|
||||||
|
|
||||||
|
export {
|
||||||
|
mj
|
||||||
|
}
|
||||||
14
src/preload/sd.js
Normal file
14
src/preload/sd.js
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
import { ipcRenderer } from "electron"
|
||||||
|
import { DEFINE_STRING } from "../define/define_string"
|
||||||
|
|
||||||
|
|
||||||
|
const sd = {
|
||||||
|
// 加载当前链接的SD服务数据
|
||||||
|
LoadSDServiceData: async (value, callback) => callback(await ipcRenderer.invoke(DEFINE_STRING.SD.LOAD_SD_SERVICE_DATA, value)),
|
||||||
|
|
||||||
|
// 文生图,单张
|
||||||
|
txt2img: async (value, callback) => callback(await ipcRenderer.invoke(DEFINE_STRING.SD.TXT2IMG, value)),
|
||||||
|
}
|
||||||
|
export {
|
||||||
|
sd
|
||||||
|
}
|
||||||
@ -1,78 +1,106 @@
|
|||||||
<template>
|
<template>
|
||||||
<div id="word_option"
|
<div
|
||||||
style=" margin-left: 20px; position:absolute; left: 0; top: 0; z-index: 100; height: 30px; width: 100%;">
|
id="word_option"
|
||||||
<n-button color="#1e90ff" size="small" style=" margin-left: 20px;" @click="AIModifyWord">一键洗稿</n-button>
|
style="
|
||||||
<n-button color="#1e90ff" size="small" style=" margin-left: 20px;"
|
margin-left: 20px;
|
||||||
@click="ContinueAIModifyWord">继续写稿(勾选了没有出来的)</n-button>
|
position: absolute;
|
||||||
<n-button color="#1e90ff" size="small" style=" margin-left: 20px;" @click="SaveNewWord">保存洗稿后文件</n-button>
|
left: 0;
|
||||||
<n-button color="#1e90ff" size="small" style=" margin-left: 20px;" @click="ImportSrtAndGetTime">导入字幕</n-button>
|
top: 0;
|
||||||
<n-button color="#1e90ff" size="small" style=" margin-left: 20px;"
|
z-index: 100;
|
||||||
@click="SaveCopywritingInformation">保存文案信息</n-button>
|
height: 30px;
|
||||||
|
width: 100%;
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<n-button color="#1e90ff" size="small" style="margin-left: 20px" @click="AIModifyWord"
|
||||||
|
>一键洗稿</n-button
|
||||||
|
>
|
||||||
|
<n-button color="#1e90ff" size="small" style="margin-left: 20px" @click="ContinueAIModifyWord"
|
||||||
|
>继续写稿(勾选了没有出来的)</n-button
|
||||||
|
>
|
||||||
|
<n-button color="#1e90ff" size="small" style="margin-left: 20px" @click="SaveNewWord"
|
||||||
|
>保存洗稿后文件</n-button
|
||||||
|
>
|
||||||
|
<n-button color="#1e90ff" size="small" style="margin-left: 20px" @click="ImportSrtAndGetTime"
|
||||||
|
>导入字幕</n-button
|
||||||
|
>
|
||||||
|
<n-button
|
||||||
|
color="#1e90ff"
|
||||||
|
size="small"
|
||||||
|
style="margin-left: 20px"
|
||||||
|
@click="SaveCopywritingInformation"
|
||||||
|
>保存文案信息</n-button
|
||||||
|
>
|
||||||
</div>
|
</div>
|
||||||
<n-data-table style="margin-top: 15px;" :row-key="rowKey" :columns="columns" :data="data" :pagination="pagination"
|
<n-data-table
|
||||||
:bordered="false" @update:checked-row-keys="handleCheck" />
|
style="margin-top: 15px"
|
||||||
|
:row-key="rowKey"
|
||||||
|
:columns="columns"
|
||||||
|
:data="data"
|
||||||
|
:pagination="pagination"
|
||||||
|
:bordered="false"
|
||||||
|
@update:checked-row-keys="handleCheck"
|
||||||
|
/>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { h, defineComponent, onMounted, ref, toRaw } from "vue";
|
import { h, defineComponent, onMounted, ref, toRaw } from 'vue'
|
||||||
import { NButton, NDataTable, useMessage, NInput, NImage, useDialog } from "naive-ui";
|
import { NButton, NDataTable, useMessage, NInput, NImage, useDialog } from 'naive-ui'
|
||||||
|
|
||||||
const buttonArr = [
|
const buttonArr = [
|
||||||
{
|
{
|
||||||
title: "切换",
|
title: '切换',
|
||||||
key: "switch",
|
key: 'switch',
|
||||||
color: "#8a2be2"
|
color: '#8a2be2'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "洗稿",
|
title: '洗稿',
|
||||||
key: 'aiWord',
|
key: 'aiWord',
|
||||||
color: "#8a2be2"
|
color: '#8a2be2'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "下对齐",
|
title: '下对齐',
|
||||||
key: 'AlignNextWord',
|
key: 'AlignNextWord',
|
||||||
color: "#8a2be0"
|
color: '#8a2be0'
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
components: {
|
components: {
|
||||||
NButton, NDataTable, NInput, NImage
|
NButton,
|
||||||
|
NDataTable,
|
||||||
|
NInput,
|
||||||
|
NImage
|
||||||
},
|
},
|
||||||
setup() {
|
setup() {
|
||||||
const message = useMessage();
|
const message = useMessage()
|
||||||
let data = ref([]);
|
let data = ref([])
|
||||||
let selectKey = ref([]);
|
let selectKey = ref([])
|
||||||
let textData = [];
|
let textData = []
|
||||||
let dialog = useDialog();
|
let dialog = useDialog()
|
||||||
let replace_before = ref("");
|
let replace_before = ref('')
|
||||||
let replace_after = ref("");
|
let replace_after = ref('')
|
||||||
|
|
||||||
const createColumns = ({
|
const createColumns = ({ AIModifyOneWord, SwitchOldWord }) => {
|
||||||
AIModifyOneWord,
|
|
||||||
SwitchOldWord
|
|
||||||
}) => {
|
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
type: "selection",
|
type: 'selection',
|
||||||
disabled(row) {
|
disabled(row) {
|
||||||
return row.name === "Edward King 3";
|
return row.name === 'Edward King 3'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "编号",
|
title: '编号',
|
||||||
key: 'no',
|
key: 'no',
|
||||||
width: 50
|
width: 50
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "文案",
|
title: '文案',
|
||||||
key: "word",
|
key: 'word',
|
||||||
width: 250,
|
width: 250,
|
||||||
render(row, index) {
|
render(row, index) {
|
||||||
return h(NInput, {
|
return h(NInput, {
|
||||||
value: row.word,
|
value: row.word,
|
||||||
type: "textarea",
|
type: 'textarea',
|
||||||
autosize: true,
|
autosize: true,
|
||||||
onUpdateValue(v) {
|
onUpdateValue(v) {
|
||||||
data.value[index].word = v
|
data.value[index].word = v
|
||||||
@ -81,79 +109,97 @@ export default defineComponent({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "操作",
|
title: '操作',
|
||||||
key: "options",
|
key: 'options',
|
||||||
width: 130,
|
width: 130,
|
||||||
render(row) {
|
render(row) {
|
||||||
const btn = buttonArr.map(item => {
|
const btn = buttonArr.map((item) => {
|
||||||
return h(
|
return h(
|
||||||
NButton, {
|
NButton,
|
||||||
style: "margin : 2px",
|
{
|
||||||
|
style: 'margin : 2px',
|
||||||
strong: true,
|
strong: true,
|
||||||
size: "tiny",
|
size: 'tiny',
|
||||||
color: item.color,
|
color: item.color,
|
||||||
onClick: () => {
|
onClick: () => {
|
||||||
if (item.key == "aiWord") {
|
if (item.key == 'aiWord') {
|
||||||
AIModifyOneWord(row);
|
AIModifyOneWord(row)
|
||||||
} else if (item.key == "switch") {
|
} else if (item.key == 'switch') {
|
||||||
SwitchOldWord(row);
|
SwitchOldWord(row)
|
||||||
} else if (item.key == "AlignNextWord") {
|
} else if (item.key == 'AlignNextWord') {
|
||||||
AlignNextWord(row);
|
AlignNextWord(row)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
default: () => item.title
|
default: () => item.title
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
});
|
})
|
||||||
return btn;
|
return btn
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title(row) {
|
title(row) {
|
||||||
return h("div", {
|
return h(
|
||||||
style: "display : flex; align-items: center;"
|
'div',
|
||||||
}, [
|
{
|
||||||
h("span", {
|
style: 'display : flex; align-items: center;'
|
||||||
style: "margin-right : 2px; width : 80px "
|
},
|
||||||
}, "洗稿后"),
|
[
|
||||||
h("div", {
|
h(
|
||||||
style: " margin-right : 5px"
|
'span',
|
||||||
}, [
|
{
|
||||||
|
style: 'margin-right : 2px; width : 80px '
|
||||||
|
},
|
||||||
|
'洗稿后'
|
||||||
|
),
|
||||||
|
h(
|
||||||
|
'div',
|
||||||
|
{
|
||||||
|
style: ' margin-right : 5px'
|
||||||
|
},
|
||||||
|
[
|
||||||
h(NInput, {
|
h(NInput, {
|
||||||
size: "tiny",
|
size: 'tiny',
|
||||||
placeholder: "替换前的值",
|
placeholder: '替换前的值',
|
||||||
value: replace_before.value,
|
value: replace_before.value,
|
||||||
onUpdateValue(v) {
|
onUpdateValue(v) {
|
||||||
replace_before.value = v
|
replace_before.value = v
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
h(NInput, {
|
h(NInput, {
|
||||||
size: "tiny",
|
size: 'tiny',
|
||||||
placeholder: "替换后的值",
|
placeholder: '替换后的值',
|
||||||
value: replace_after.value,
|
value: replace_after.value,
|
||||||
onUpdateValue(v) {
|
onUpdateValue(v) {
|
||||||
replace_after.value = v
|
replace_after.value = v
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
]),
|
]
|
||||||
h("div", {}, [
|
),
|
||||||
h(NButton, {
|
h('div', {}, [
|
||||||
style: "",
|
h(
|
||||||
size: "tiny",
|
NButton,
|
||||||
color: "#70a1ff",
|
{
|
||||||
|
style: '',
|
||||||
|
size: 'tiny',
|
||||||
|
color: '#70a1ff',
|
||||||
onClick: () => ReplaceText()
|
onClick: () => ReplaceText()
|
||||||
}, { default: () => "替换" }),
|
|
||||||
])
|
|
||||||
])
|
|
||||||
},
|
},
|
||||||
key: "after_gpt",
|
{ default: () => '替换' }
|
||||||
|
)
|
||||||
|
])
|
||||||
|
]
|
||||||
|
)
|
||||||
|
},
|
||||||
|
key: 'after_gpt',
|
||||||
width: 300,
|
width: 300,
|
||||||
render(row, index) {
|
render(row, index) {
|
||||||
return h(NInput, {
|
return h(NInput, {
|
||||||
value: row.after_gpt,
|
value: row.after_gpt,
|
||||||
placeholder: "洗稿后的值",
|
placeholder: '洗稿后的值',
|
||||||
type: "textarea",
|
type: 'textarea',
|
||||||
autosize: true,
|
autosize: true,
|
||||||
onUpdateValue(v) {
|
onUpdateValue(v) {
|
||||||
data.value[index].after_gpt = v
|
data.value[index].after_gpt = v
|
||||||
@ -162,64 +208,74 @@ export default defineComponent({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "字幕",
|
title: '字幕',
|
||||||
key: "srt",
|
key: 'srt',
|
||||||
render(row) {
|
render(row) {
|
||||||
let tmp = row.subValue.map(item => h("div", { style: "display:flex; height : auto; margin: 2px 0" }, [
|
let tmp = row.subValue.map((item) =>
|
||||||
|
h('div', { style: 'display:flex; height : auto; margin: 2px 0' }, [
|
||||||
h(NInput, {
|
h(NInput, {
|
||||||
size: "tiny",
|
size: 'tiny',
|
||||||
value: item.srt_value
|
value: item.srt_value
|
||||||
|
|
||||||
}),
|
}),
|
||||||
h(NButton, {
|
h(
|
||||||
style: "margin : 0 2px",
|
NButton,
|
||||||
size: "tiny",
|
{
|
||||||
color: "#5f4321",
|
style: 'margin : 0 2px',
|
||||||
|
size: 'tiny',
|
||||||
|
color: '#5f4321',
|
||||||
onClick: () => Upper(row, item, true)
|
onClick: () => Upper(row, item, true)
|
||||||
}, { default: () => "向上" }),
|
},
|
||||||
h(NButton, {
|
{ default: () => '向上' }
|
||||||
style: "margin : 0 2px",
|
),
|
||||||
size: "tiny",
|
h(
|
||||||
color: "#ee7959",
|
NButton,
|
||||||
|
{
|
||||||
|
style: 'margin : 0 2px',
|
||||||
|
size: 'tiny',
|
||||||
|
color: '#ee7959',
|
||||||
onClick: () => Down(row, item)
|
onClick: () => Down(row, item)
|
||||||
}, { default: () => "向下" })
|
},
|
||||||
]))
|
{ default: () => '向下' }
|
||||||
|
)
|
||||||
|
])
|
||||||
|
)
|
||||||
return tmp
|
return tmp
|
||||||
}
|
}
|
||||||
}, {
|
},
|
||||||
title: "时间范围",
|
{
|
||||||
key: "timeLimit",
|
title: '时间范围',
|
||||||
|
key: 'timeLimit',
|
||||||
width: 120
|
width: 120
|
||||||
}, {
|
},
|
||||||
title: "原图",
|
{
|
||||||
|
title: '原图',
|
||||||
width: 120,
|
width: 120,
|
||||||
render(row) {
|
render(row) {
|
||||||
return h(NImage, {
|
return h(NImage, {
|
||||||
src: "file:\\" + (row.old_image ? row.old_image : row.outImagePath),
|
src: 'file:\\' + (row.old_image ? row.old_image : row.outImagePath),
|
||||||
alt: 'Image',
|
alt: 'Image',
|
||||||
width: '120'
|
width: '120'
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
];
|
]
|
||||||
};
|
}
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
// 初始化加载项目下面的分镜好的文案
|
// 初始化加载项目下面的分镜好的文案
|
||||||
// 并判断是不是有洗稿后的文件。一并加载
|
// 并判断是不是有洗稿后的文件。一并加载
|
||||||
await window.api.GetProjectWord(value => {
|
await window.api.GetProjectWord((value) => {
|
||||||
debugger;
|
debugger
|
||||||
data.value = value.data;
|
data.value = value.data
|
||||||
})
|
})
|
||||||
|
|
||||||
let div = document.getElementById("word_option");
|
let div = document.getElementById('word_option')
|
||||||
if (window.config.theme == "dark") {
|
if (window.config.theme == 'dark') {
|
||||||
div.style.backgroundColor = "#24242c"
|
div.style.backgroundColor = '#24242c'
|
||||||
} else {
|
} else {
|
||||||
div.style.backgroundColor = "#FFF"
|
div.style.backgroundColor = '#FFF'
|
||||||
}
|
}
|
||||||
|
})
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 替换洗稿后的所有数据
|
* 替换洗稿后的所有数据
|
||||||
@ -227,7 +283,10 @@ export default defineComponent({
|
|||||||
async function ReplaceText() {
|
async function ReplaceText() {
|
||||||
// 开始替换
|
// 开始替换
|
||||||
for (let i = 0; i < data.value.length; i++) {
|
for (let i = 0; i < data.value.length; i++) {
|
||||||
data.value[i].after_gpt = data.value[i].after_gpt.replaceAll(replace_before.value, replace_after.value);
|
data.value[i].after_gpt = data.value[i].after_gpt.replaceAll(
|
||||||
|
replace_before.value,
|
||||||
|
replace_after.value
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -236,18 +295,18 @@ export default defineComponent({
|
|||||||
* @param {data value 值的索引} index
|
* @param {data value 值的索引} index
|
||||||
*/
|
*/
|
||||||
function modifyTime(index) {
|
function modifyTime(index) {
|
||||||
let s_v = data.value[index].subValue;
|
let s_v = data.value[index].subValue
|
||||||
let len = s_v.length;
|
let len = s_v.length
|
||||||
if (len > 0) {
|
if (len > 0) {
|
||||||
let s_t = s_v[0].start_time;
|
let s_t = s_v[0].start_time
|
||||||
let e_t = s_v[len - 1].end_time;
|
let e_t = s_v[len - 1].end_time
|
||||||
data.value[index].start_time = s_t;
|
data.value[index].start_time = s_t
|
||||||
data.value[index].end_time = e_t;
|
data.value[index].end_time = e_t
|
||||||
data.value[index].timeLimit = `${s_t} -- ${e_t}`;
|
data.value[index].timeLimit = `${s_t} -- ${e_t}`
|
||||||
} else {
|
} else {
|
||||||
data.value[index].start_time = null;
|
data.value[index].start_time = null
|
||||||
data.value[index].end_time = null;
|
data.value[index].end_time = null
|
||||||
data.value[index].timeLimit = ``;
|
data.value[index].timeLimit = ``
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -256,7 +315,7 @@ export default defineComponent({
|
|||||||
* @param {data value 的索引} index
|
* @param {data value 的索引} index
|
||||||
*/
|
*/
|
||||||
function moveUp(index) {
|
function moveUp(index) {
|
||||||
let s_v = data.value[index].subValue;
|
let s_v = data.value[index].subValue
|
||||||
if (s_v.length == 0) {
|
if (s_v.length == 0) {
|
||||||
// 将下面所有的字幕数据往上移动
|
// 将下面所有的字幕数据往上移动
|
||||||
for (let i = index; i < data.value.length; i++) {
|
for (let i = index; i < data.value.length; i++) {
|
||||||
@ -266,9 +325,14 @@ export default defineComponent({
|
|||||||
} else {
|
} else {
|
||||||
// 检查当前这个是不是为空。为空直接删除
|
// 检查当前这个是不是为空。为空直接删除
|
||||||
// 判断当前行的文案、洗稿后文件、以及字幕是不是还有。(没有的话直接删除)
|
// 判断当前行的文案、洗稿后文件、以及字幕是不是还有。(没有的话直接删除)
|
||||||
if (data.value[i].word == null || data.value[i].word == "" || data.value[i].after_gpt == null || data.value[i].after_gpt == "") {
|
if (
|
||||||
|
data.value[i].word == null ||
|
||||||
|
data.value[i].word == '' ||
|
||||||
|
data.value[i].after_gpt == null ||
|
||||||
|
data.value[i].after_gpt == ''
|
||||||
|
) {
|
||||||
// 直接删除
|
// 直接删除
|
||||||
data.value.splice(i, 1);
|
data.value.splice(i, 1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -285,48 +349,50 @@ export default defineComponent({
|
|||||||
// 若是当前只有一个。判断当前文案和洗稿后文件是不是存在。存在不删除。没有的话直接删除。
|
// 若是当前只有一个。判断当前文案和洗稿后文件是不是存在。存在不删除。没有的话直接删除。
|
||||||
// 向下合并。逻辑相同。
|
// 向下合并。逻辑相同。
|
||||||
|
|
||||||
if (row.lastId == null || row.lastId == "") {
|
if (row.lastId == null || row.lastId == '') {
|
||||||
message.error("当前是第一个。不能向上合并");
|
message.error('当前是第一个。不能向上合并')
|
||||||
return;
|
return
|
||||||
}
|
}
|
||||||
//判断当前行是不是第一个
|
//判断当前行是不是第一个
|
||||||
let itemId = item.id;
|
let itemId = item.id
|
||||||
let itemIndex = row.subValue.findIndex(item => item.id == itemId);
|
let itemIndex = row.subValue.findIndex((item) => item.id == itemId)
|
||||||
let thisIndex = data.value.findIndex(item => item.id == row.id);
|
let thisIndex = data.value.findIndex((item) => item.id == row.id)
|
||||||
if (itemIndex < 0 && isM) {
|
if (itemIndex < 0 && isM) {
|
||||||
debugger
|
debugger
|
||||||
message.error("数据错误");
|
message.error('数据错误')
|
||||||
return;
|
return
|
||||||
} else {
|
} else {
|
||||||
// 先获取上一行的数据
|
// 先获取上一行的数据
|
||||||
let lastRowIndex = data.value.findIndex(item => item.id == row.lastId);
|
let lastRowIndex = data.value.findIndex((item) => item.id == row.lastId)
|
||||||
//将当前及之前的数据向上合并
|
//将当前及之前的数据向上合并
|
||||||
for (let i = 0; i <= itemIndex; i++) {
|
for (let i = 0; i <= itemIndex; i++) {
|
||||||
const element = row.subValue[i];
|
const element = row.subValue[i]
|
||||||
data.value[lastRowIndex].subValue.push(element);
|
data.value[lastRowIndex].subValue.push(element)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 删除指定的数据
|
// 删除指定的数据
|
||||||
data.value[lastRowIndex + 1].subValue.splice(0, itemIndex + 1)
|
data.value[lastRowIndex + 1].subValue.splice(0, itemIndex + 1)
|
||||||
moveUp(thisIndex);
|
moveUp(thisIndex)
|
||||||
|
|
||||||
// 判断当前行的文案和洗稿后文件是不是还有。(没有的话直接删除)
|
// 判断当前行的文案和洗稿后文件是不是还有。(没有的话直接删除)
|
||||||
if ((data.value[thisIndex].subValue == null) && (row.word == null || row.word == "" || row.after_gpt == null || row.after_gpt == "")) {
|
if (
|
||||||
|
data.value[thisIndex].subValue == null &&
|
||||||
|
(row.word == null || row.word == '' || row.after_gpt == null || row.after_gpt == '')
|
||||||
|
) {
|
||||||
// 先调整lastId (判断下一行是不是存在。存在的话修改lastId为当前的lastId)
|
// 先调整lastId (判断下一行是不是存在。存在的话修改lastId为当前的lastId)
|
||||||
if (data.value[thisIndex + 1] != null) {
|
if (data.value[thisIndex + 1] != null) {
|
||||||
data.value[thisIndex + 1].lastId = row.lastId;
|
data.value[thisIndex + 1].lastId = row.lastId
|
||||||
}
|
}
|
||||||
// 直接删除
|
// 直接删除
|
||||||
data.value.splice(thisIndex, 1);
|
data.value.splice(thisIndex, 1)
|
||||||
// 调整下面的所有的编号
|
// 调整下面的所有的编号
|
||||||
for (let i = thisIndex; i < data.value.length; i++) {
|
for (let i = thisIndex; i < data.value.length; i++) {
|
||||||
data.value[i].no = data.value[i].no - 1;
|
data.value[i].no = data.value[i].no - 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 合并之后重新计算时间(计算上一个和当前的)
|
// 合并之后重新计算时间(计算上一个和当前的)
|
||||||
modifyTime(lastRowIndex);
|
modifyTime(lastRowIndex)
|
||||||
modifyTime(thisIndex);
|
modifyTime(thisIndex)
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -339,61 +405,63 @@ export default defineComponent({
|
|||||||
// 不是第一个的话。将下面的所有的合并。
|
// 不是第一个的话。将下面的所有的合并。
|
||||||
// 若是当前只有一个。判断当前文案和洗稿后文件是不是存在。存在不删除。没有的话直接删除。
|
// 若是当前只有一个。判断当前文案和洗稿后文件是不是存在。存在不删除。没有的话直接删除。
|
||||||
//判断当前行是不是第一个
|
//判断当前行是不是第一个
|
||||||
let itemId = item.id;
|
let itemId = item.id
|
||||||
let itemIndex = row.subValue.findIndex(item => item.id == itemId);
|
let itemIndex = row.subValue.findIndex((item) => item.id == itemId)
|
||||||
let thisIndex = data.value.findIndex(item => item.id == row.id);
|
let thisIndex = data.value.findIndex((item) => item.id == row.id)
|
||||||
// 判断下一个是不是存在
|
// 判断下一个是不是存在
|
||||||
if (data.value[thisIndex + 1] == null) {
|
if (data.value[thisIndex + 1] == null) {
|
||||||
message.error("当前已经是最后一个。不能向下合并");
|
message.error('当前已经是最后一个。不能向下合并')
|
||||||
return;
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (itemIndex < 0) {
|
if (itemIndex < 0) {
|
||||||
message.error("数据错误 2222");
|
message.error('数据错误 2222')
|
||||||
return;
|
return
|
||||||
} else {
|
} else {
|
||||||
// 获取下一行数据
|
// 获取下一行数据
|
||||||
let nextRowIndex = data.value.findIndex(item => item.lastId == row.id);
|
let nextRowIndex = data.value.findIndex((item) => item.lastId == row.id)
|
||||||
|
|
||||||
//将当前以及下面的所有进行合并
|
//将当前以及下面的所有进行合并
|
||||||
for (let i = row.subValue.length - 1; i >= itemIndex; i--) {
|
for (let i = row.subValue.length - 1; i >= itemIndex; i--) {
|
||||||
const element = row.subValue[i];
|
const element = row.subValue[i]
|
||||||
data.value[nextRowIndex].subValue.unshift(element);
|
data.value[nextRowIndex].subValue.unshift(element)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 删除指定的数据
|
// 删除指定的数据
|
||||||
data.value[thisIndex].subValue.splice(itemIndex)
|
data.value[thisIndex].subValue.splice(itemIndex)
|
||||||
|
|
||||||
// 判断该当前字幕是不是为空(为空的话。下面的往上移动)
|
// 判断该当前字幕是不是为空(为空的话。下面的往上移动)
|
||||||
moveUp(thisIndex);
|
moveUp(thisIndex)
|
||||||
|
|
||||||
// 判断当前行的文案、洗稿后文件、以及字幕是不是还有。(没有的话直接删除)
|
// 判断当前行的文案、洗稿后文件、以及字幕是不是还有。(没有的话直接删除)
|
||||||
if ((data.value[thisIndex].subValue == null) && (row.word == null || row.word == "" || row.after_gpt == null || row.after_gpt == "")) {
|
if (
|
||||||
|
data.value[thisIndex].subValue == null &&
|
||||||
|
(row.word == null || row.word == '' || row.after_gpt == null || row.after_gpt == '')
|
||||||
|
) {
|
||||||
// 先调整lastId (判断下一行是不是存在。存在的话修改lastId为当前的lastId)
|
// 先调整lastId (判断下一行是不是存在。存在的话修改lastId为当前的lastId)
|
||||||
if (data.value[nextRowIndex] != null) {
|
if (data.value[nextRowIndex] != null) {
|
||||||
data.value[nextRowIndex].lastId = row.lastId;
|
data.value[nextRowIndex].lastId = row.lastId
|
||||||
}
|
}
|
||||||
// 直接删除
|
// 直接删除
|
||||||
data.value.splice(thisIndex, 1);
|
data.value.splice(thisIndex, 1)
|
||||||
// 调整下面的所有的编号
|
// 调整下面的所有的编号
|
||||||
for (let i = thisIndex; i < data.value.length; i++) {
|
for (let i = thisIndex; i < data.value.length; i++) {
|
||||||
data.value[i].no = data.value[i].no - 1;
|
data.value[i].no = data.value[i].no - 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 合并之后重新计算时间(计算上一个和当前的)
|
// 合并之后重新计算时间(计算上一个和当前的)
|
||||||
modifyTime(nextRowIndex);
|
modifyTime(nextRowIndex)
|
||||||
modifyTime(thisIndex);
|
modifyTime(thisIndex)
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function removePunctuationIncludingEllipsis(sentence) {
|
function removePunctuationIncludingEllipsis(sentence) {
|
||||||
// 扩展正则表达式以包含中文标点符号和省略号
|
// 扩展正则表达式以包含中文标点符号和省略号
|
||||||
// 注意英文省略号可能由三个连续点表示,也可能直接使用特殊的省略号字符
|
// 注意英文省略号可能由三个连续点表示,也可能直接使用特殊的省略号字符
|
||||||
const punctuationRegExp = /[., \/#!$%\^&\*;:{}=\-_`~()\[\],。、;:?!‘’“”()【】《》…]+/g;
|
const punctuationRegExp = /[., \/#!$%\^&\*;:{}=\-_`~()\[\],。、;:?!‘’“”()【】《》…]+/g
|
||||||
|
|
||||||
// 使用正则表达式的replace方法替换掉所有匹配到的标点符号为空字符串
|
// 使用正则表达式的replace方法替换掉所有匹配到的标点符号为空字符串
|
||||||
return sentence.replace(punctuationRegExp, '');
|
return sentence.replace(punctuationRegExp, '')
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -402,57 +470,66 @@ export default defineComponent({
|
|||||||
async function AlignNextWord(row) {
|
async function AlignNextWord(row) {
|
||||||
// 判断是不是已经到到导入过字幕了
|
// 判断是不是已经到到导入过字幕了
|
||||||
dialog.create({
|
dialog.create({
|
||||||
type: "warning",
|
type: 'warning',
|
||||||
title: "警告",
|
title: '警告',
|
||||||
showIcon: true,
|
showIcon: true,
|
||||||
content: "会自动对齐下面的数据。没有对齐成功就要手动调整在自动对齐",
|
content: '会自动对齐下面的数据。没有对齐成功就要手动调整在自动对齐',
|
||||||
style: `width : 400px;`,
|
style: `width : 400px;`,
|
||||||
maskClosable: false,
|
maskClosable: false,
|
||||||
positiveText: "确定",
|
positiveText: '确定',
|
||||||
negativeText: "取消",
|
negativeText: '取消',
|
||||||
onPositiveClick: async () => {
|
onPositiveClick: async () => {
|
||||||
// 下对齐
|
// 下对齐
|
||||||
let itemId = row.id;
|
let itemId = row.id
|
||||||
let thisIndex = data.value.findIndex(item => item.id == itemId);
|
let thisIndex = data.value.findIndex((item) => item.id == itemId)
|
||||||
if (thisIndex < 0) {
|
if (thisIndex < 0) {
|
||||||
message.error("数据错误");
|
message.error('数据错误')
|
||||||
return;
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
let nextSrt = [];
|
let nextSrt = []
|
||||||
// 先将当前行下面的所有的数据拿出来
|
// 先将当前行下面的所有的数据拿出来
|
||||||
for (let i = thisIndex; i < data.value.length; i++) {
|
for (let i = thisIndex; i < data.value.length; i++) {
|
||||||
const element = data.value[i];
|
const element = data.value[i]
|
||||||
nextSrt = nextSrt.concat(element.subValue);
|
nextSrt = nextSrt.concat(element.subValue)
|
||||||
}
|
}
|
||||||
let init_num = thisIndex;
|
let init_num = thisIndex
|
||||||
// let data
|
// let data
|
||||||
let tmp_str = "";
|
let tmp_str = ''
|
||||||
for (let i = 0; i < nextSrt.length;) {
|
for (let i = 0; i < nextSrt.length; ) {
|
||||||
const element = nextSrt[i];
|
const element = nextSrt[i]
|
||||||
let current_text = `第 ${thisIndex + 1} 数据。字幕:${element.srt_value}与文案不匹配。亲检查上下文。`
|
let current_text = `第 ${thisIndex + 1} 数据。字幕:${
|
||||||
tmp_str += element.srt_value;
|
element.srt_value
|
||||||
|
}与文案不匹配。亲检查上下文。`
|
||||||
|
tmp_str += element.srt_value
|
||||||
|
|
||||||
if (removePunctuationIncludingEllipsis(data.value[thisIndex].after_gpt).startsWith(removePunctuationIncludingEllipsis(tmp_str))) {
|
if (
|
||||||
|
removePunctuationIncludingEllipsis(data.value[thisIndex].after_gpt).startsWith(
|
||||||
|
removePunctuationIncludingEllipsis(tmp_str)
|
||||||
|
)
|
||||||
|
) {
|
||||||
// data.value[thisIndex].subValue.push(element);
|
// data.value[thisIndex].subValue.push(element);
|
||||||
if (init_num < thisIndex || i > 0) {
|
if (init_num < thisIndex || i > 0) {
|
||||||
Upper(data.value[thisIndex + 1], element, false);
|
Upper(data.value[thisIndex + 1], element, false)
|
||||||
}
|
}
|
||||||
i++;
|
i++
|
||||||
} else {
|
} else {
|
||||||
if (removePunctuationIncludingEllipsis(data.value[thisIndex + 1].after_gpt).startsWith(removePunctuationIncludingEllipsis(element.srt_value))) {
|
if (
|
||||||
thisIndex++;
|
removePunctuationIncludingEllipsis(data.value[thisIndex + 1].after_gpt).startsWith(
|
||||||
tmp_str = "";
|
removePunctuationIncludingEllipsis(element.srt_value)
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
thisIndex++
|
||||||
|
tmp_str = ''
|
||||||
} else {
|
} else {
|
||||||
window.api.showGlobalMessageDialog({
|
window.api.showGlobalMessageDialog({
|
||||||
code: 0,
|
code: 0,
|
||||||
message: current_text
|
message: current_text
|
||||||
})
|
})
|
||||||
return;
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -461,9 +538,9 @@ export default defineComponent({
|
|||||||
* 将原本的文案替换洗稿后
|
* 将原本的文案替换洗稿后
|
||||||
*/
|
*/
|
||||||
async function SwitchOldWord(row) {
|
async function SwitchOldWord(row) {
|
||||||
data.value.forEach(item => {
|
data.value.forEach((item) => {
|
||||||
if (item.no == row.no) {
|
if (item.no == row.no) {
|
||||||
item.after_gpt = item.word;
|
item.after_gpt = item.word
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -474,12 +551,12 @@ export default defineComponent({
|
|||||||
async function AIModifyOneWord(row) {
|
async function AIModifyOneWord(row) {
|
||||||
await window.api.AIModifyOneWord([row.no, row.word], (value) => {
|
await window.api.AIModifyOneWord([row.no, row.word], (value) => {
|
||||||
if (value.code != 1) {
|
if (value.code != 1) {
|
||||||
message.error("未知错误");
|
message.error('未知错误')
|
||||||
return;
|
return
|
||||||
}
|
}
|
||||||
// 修改数据
|
// 修改数据
|
||||||
let filter_data = data.value.filter(item => item.no == value.data.no);
|
let filter_data = data.value.filter((item) => item.no == value.data.no)
|
||||||
filter_data[0].after_gpt = value.data.content;
|
filter_data[0].after_gpt = value.data.content
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -487,45 +564,45 @@ export default defineComponent({
|
|||||||
* 一键洗稿,AI修改选择的
|
* 一键洗稿,AI修改选择的
|
||||||
*/
|
*/
|
||||||
async function AIModifyWord() {
|
async function AIModifyWord() {
|
||||||
let word_data = [];
|
let word_data = []
|
||||||
for (let i = 0; i < selectKey.value.length; i++) {
|
for (let i = 0; i < selectKey.value.length; i++) {
|
||||||
const item = selectKey.value[i];
|
const item = selectKey.value[i]
|
||||||
let obj = {
|
let obj = {
|
||||||
no: data.value[item - 1].no,
|
no: data.value[item - 1].no,
|
||||||
word: data.value[item - 1].word
|
word: data.value[item - 1].word
|
||||||
}
|
}
|
||||||
word_data.push(obj);
|
word_data.push(obj)
|
||||||
}
|
}
|
||||||
for (let i = 0; i < word_data.length; i++) {
|
for (let i = 0; i < word_data.length; i++) {
|
||||||
const item = word_data[i];
|
const item = word_data[i]
|
||||||
await AIModifyOneWord(item)
|
await AIModifyOneWord(item)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 洗完稿之后全局提示
|
// 洗完稿之后全局提示
|
||||||
window.api.showGlobalMessageDialog({ code: 1, message: "一键洗稿完成" })
|
window.api.showGlobalMessageDialog({ code: 1, message: '一键洗稿完成' })
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 保存洗稿后文件
|
* 保存洗稿后文件
|
||||||
*/
|
*/
|
||||||
async function SaveNewWord() {
|
async function SaveNewWord() {
|
||||||
let new_data_word = [];
|
let new_data_word = []
|
||||||
// 先填充没有洗稿的
|
// 先填充没有洗稿的
|
||||||
for (let i = 0; i < data.value.length; i++) {
|
for (let i = 0; i < data.value.length; i++) {
|
||||||
const item = data.value[i];
|
const item = data.value[i]
|
||||||
if (!item.after_gpt) {
|
if (!item.after_gpt) {
|
||||||
item.after_gpt = item.word;
|
item.after_gpt = item.word
|
||||||
}
|
}
|
||||||
new_data_word.push(item.after_gpt);
|
new_data_word.push(item.after_gpt)
|
||||||
}
|
}
|
||||||
textData = new_data_word;
|
textData = new_data_word
|
||||||
// 开始保存
|
// 开始保存
|
||||||
await window.api.SaveNewWord(new_data_word, (value) => {
|
await window.api.SaveNewWord(new_data_word, (value) => {
|
||||||
if (value.code != 1) {
|
if (value.code != 1) {
|
||||||
message.error("未知错误");
|
message.error('未知错误')
|
||||||
return;
|
return
|
||||||
}
|
}
|
||||||
message.success("保存成功,并写入到了剪贴板");
|
message.success('保存成功,并写入到了剪贴板')
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -533,13 +610,16 @@ export default defineComponent({
|
|||||||
* 保存字幕文案信息,用于自动生成视频
|
* 保存字幕文案信息,用于自动生成视频
|
||||||
*/
|
*/
|
||||||
async function SaveCopywritingInformation() {
|
async function SaveCopywritingInformation() {
|
||||||
await window.api.SaveCopywritingInformation([toRaw(data.value), "srt_time_information"], (value) => {
|
await window.api.SaveCopywritingInformation(
|
||||||
|
[toRaw(data.value), 'srt_time_information'],
|
||||||
|
(value) => {
|
||||||
if (value.code != 1) {
|
if (value.code != 1) {
|
||||||
message.error("未知错误");
|
message.error('未知错误')
|
||||||
return;
|
return
|
||||||
}
|
}
|
||||||
message.success("保存成功");
|
message.success('保存成功')
|
||||||
})
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -547,54 +627,53 @@ export default defineComponent({
|
|||||||
*/
|
*/
|
||||||
async function ImportSrtAndGetTime() {
|
async function ImportSrtAndGetTime() {
|
||||||
if (textData.length <= 0) {
|
if (textData.length <= 0) {
|
||||||
message.error("请先保存洗稿后文件,不洗稿也要保存一下");
|
message.error('请先保存洗稿后文件,不洗稿也要保存一下')
|
||||||
return;
|
return
|
||||||
}
|
}
|
||||||
await window.api.ImportSrtAndGetTime([toRaw(data.value)], (value) => {
|
await window.api.ImportSrtAndGetTime([toRaw(data.value)], (value) => {
|
||||||
if (value.code == 0) {
|
if (value.code == 0) {
|
||||||
message.error(value.message);
|
message.error(value.message)
|
||||||
return;
|
return
|
||||||
}
|
}
|
||||||
// 写入时间
|
// 写入时间
|
||||||
for (let i = 0; i < value.data.length; i++) {
|
for (let i = 0; i < value.data.length; i++) {
|
||||||
const item = value.data[i];
|
const item = value.data[i]
|
||||||
if (i >= data.value.length) {
|
if (i >= data.value.length) {
|
||||||
item.no = i + 1;
|
item.no = i + 1
|
||||||
item.timeLimit = `${item.start_time} -- ${item.end_time}`
|
item.timeLimit = `${item.start_time} -- ${item.end_time}`
|
||||||
data.value.push(item)
|
data.value.push(item)
|
||||||
} else {
|
} else {
|
||||||
data.value[i].start_time = item.start_time;
|
data.value[i].start_time = item.start_time
|
||||||
data.value[i].end_time = item.end_time;
|
data.value[i].end_time = item.end_time
|
||||||
data.value[i].timeLimit = `${item.start_time} -- ${item.end_time}`
|
data.value[i].timeLimit = `${item.start_time} -- ${item.end_time}`
|
||||||
data.value[i].subValue = item.subValue;
|
data.value[i].subValue = item.subValue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
};
|
}
|
||||||
/**
|
/**
|
||||||
* 继续写被勾选的但是没有出来的
|
* 继续写被勾选的但是没有出来的
|
||||||
*/
|
*/
|
||||||
async function ContinueAIModifyWord() {
|
async function ContinueAIModifyWord() {
|
||||||
// 获取所有被选中的data
|
// 获取所有被选中的data
|
||||||
let word_data = [];
|
let word_data = []
|
||||||
for (let i = 0; i < selectKey.value.length; i++) {
|
for (let i = 0; i < selectKey.value.length; i++) {
|
||||||
const item = selectKey.value[i];
|
const item = selectKey.value[i]
|
||||||
|
|
||||||
if (!data.value[item - 1].after_gpt) {
|
if (!data.value[item - 1].after_gpt) {
|
||||||
let obj = {
|
let obj = {
|
||||||
no: data.value[item - 1].no,
|
no: data.value[item - 1].no,
|
||||||
word: data.value[item - 1].word
|
word: data.value[item - 1].word
|
||||||
}
|
}
|
||||||
word_data.push(obj);
|
word_data.push(obj)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (let i = 0; i < word_data.length; i++) {
|
for (let i = 0; i < word_data.length; i++) {
|
||||||
const item = word_data[i];
|
const item = word_data[i]
|
||||||
await AIModifyOneWord(item)
|
await AIModifyOneWord(item)
|
||||||
}
|
}
|
||||||
// 洗完稿之后全局提示
|
// 洗完稿之后全局提示
|
||||||
window.api.showGlobalMessageDialog({ code: 1, message: "继续写稿完成" })
|
window.api.showGlobalMessageDialog({ code: 1, message: '继续写稿完成' })
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@ -605,7 +684,7 @@ export default defineComponent({
|
|||||||
}),
|
}),
|
||||||
rowKey: (row) => row.no,
|
rowKey: (row) => row.no,
|
||||||
handleCheck(rowKeys) {
|
handleCheck(rowKeys) {
|
||||||
selectKey.value = rowKeys;
|
selectKey.value = rowKeys
|
||||||
},
|
},
|
||||||
pagination: false,
|
pagination: false,
|
||||||
AIModifyWord,
|
AIModifyWord,
|
||||||
@ -617,7 +696,7 @@ export default defineComponent({
|
|||||||
replace_before,
|
replace_before,
|
||||||
replace_after,
|
replace_after,
|
||||||
ReplaceText
|
ReplaceText
|
||||||
};
|
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
@ -1,116 +1,241 @@
|
|||||||
<template>
|
<template>
|
||||||
<n-layout id="layout_height" has-sider style="height: 300px;">
|
<n-layout id="layout_height" has-sider style="height: 300px">
|
||||||
<n-layout-sider bordered :width="240" :native-scrollbar="false">
|
<n-layout-sider bordered :width="240" :native-scrollbar="false">
|
||||||
<n-menu @update:value="SelectMenu" :options="menuOptions" v-model:value="selectedKeyRef" />
|
<n-menu @update:value="SelectMenu" :options="menuOptions" v-model:value="selectedKeyRef" />
|
||||||
</n-layout-sider>
|
</n-layout-sider>
|
||||||
<n-layout :native-scrollbar="false" style="margin-top: 30px;">
|
<n-layout :native-scrollbar="false" style="margin-top: 10px">
|
||||||
<div style="margin-left: 20px;">
|
<n-tabs
|
||||||
|
class="card-tabs"
|
||||||
|
default-value="select"
|
||||||
|
size="large"
|
||||||
|
style="margin-left: 20px"
|
||||||
|
animated
|
||||||
|
pane-wrapper-style="margin: 0 -4px"
|
||||||
|
pane-style="padding-left: 4px; padding-right: 4px; box-sizing: border-box;"
|
||||||
|
>
|
||||||
|
<n-tab-pane name="select" tab="选择风格">
|
||||||
|
<div>
|
||||||
<div>选择的风格:</div>
|
<div>选择的风格:</div>
|
||||||
<ShowImageTag :selectStyle="selectStyle"></ShowImageTag>
|
<ShowImageTag :selectStyle="selectStyle"></ShowImageTag>
|
||||||
<div style="margin-top: 5px;">
|
<div style="margin-top: 5px">
|
||||||
<div class="image-container" style="display: flex;">
|
<div class="image-container" style="display: flex">
|
||||||
<n-image-group show-toolbar-tooltip>
|
<n-image-group show-toolbar-tooltip>
|
||||||
<div style="display: flex; flex-wrap: wrap;">
|
<div style="display: flex; flex-wrap: wrap">
|
||||||
<div v-for="(image, index) in style_image_list " style="margin: 0 5px 5px 5px;"
|
<div
|
||||||
:key="image.id">
|
v-for="(image, index) in style_image_list"
|
||||||
<n-image @contextmenu.prevent="handleContextMenu($event, image)" :width="150"
|
style="margin: 0 5px 5px 5px"
|
||||||
:height="150" :src="image.image" alt="图片描述" lazy style="display: block;" />
|
:key="image.id"
|
||||||
|
>
|
||||||
|
<n-image
|
||||||
|
@contextmenu.prevent="handleContextMenu($event, image)"
|
||||||
|
:width="150"
|
||||||
|
:height="150"
|
||||||
|
:src="image.image ? image.image : image.show_image"
|
||||||
|
alt="图片描述"
|
||||||
|
lazy
|
||||||
|
style="display: block"
|
||||||
|
/>
|
||||||
|
<n-popover trigger="hover" v-if="image.type == 'style_main'">
|
||||||
|
<template #trigger>
|
||||||
|
<span
|
||||||
|
style="
|
||||||
|
display: block;
|
||||||
|
text-align: center;
|
||||||
|
width: 120px;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
"
|
||||||
|
>{{ image.prompt }}</span
|
||||||
|
>
|
||||||
|
</template>
|
||||||
|
<span>{{ image.prompt }}</span>
|
||||||
|
</n-popover>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</n-image-group>
|
</n-image-group>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</n-tab-pane>
|
||||||
|
<n-tab-pane name="add" tab="添加风格">
|
||||||
|
<AddStyleTags
|
||||||
|
:currentStyle="null"
|
||||||
|
:initFunc="null"
|
||||||
|
:lora_options="lora_options"
|
||||||
|
></AddStyleTags>
|
||||||
|
</n-tab-pane>
|
||||||
|
</n-tabs>
|
||||||
</n-layout>
|
</n-layout>
|
||||||
</n-layout>
|
</n-layout>
|
||||||
|
|
||||||
<n-dropdown style="z-index: 100;" trigger="manual" :x="x" :y="y" :options="dropOption" :show="showDropdownRef"
|
<n-dropdown
|
||||||
:on-clickoutside="onClickoutside" @select="handleSelect" />
|
style="z-index: 100"
|
||||||
|
trigger="manual"
|
||||||
|
:x="x"
|
||||||
|
:y="y"
|
||||||
|
:options="dropOption"
|
||||||
|
:show="showDropdownRef"
|
||||||
|
:on-clickoutside="onClickoutside"
|
||||||
|
@select="handleSelect"
|
||||||
|
/>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { defineComponent, ref, onMounted, watch, nextTick } from "vue";
|
import { defineComponent, ref, onMounted, watch, nextTick } from 'vue'
|
||||||
import { NDropdown, NImage, NLayout, NLayoutContent, NLayoutSider, NMenu, NSpace, NTag, NTooltip, messageDark, useMessage } from "naive-ui"
|
import {
|
||||||
import ShowImageTag from "./ShowImageTag.vue";
|
NDropdown,
|
||||||
|
NImage,
|
||||||
|
NLayout,
|
||||||
|
NLayoutContent,
|
||||||
|
NLayoutSider,
|
||||||
|
NMenu,
|
||||||
|
NSpace,
|
||||||
|
NTabPane,
|
||||||
|
NTabs,
|
||||||
|
NTag,
|
||||||
|
NTooltip,
|
||||||
|
messageDark,
|
||||||
|
useMessage,
|
||||||
|
NPopover
|
||||||
|
} from 'naive-ui'
|
||||||
|
import ShowImageTag from './ShowImageTag.vue'
|
||||||
|
import AddStyleTags from '../Original/Components/AddStyleTags.vue'
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
components: {
|
components: {
|
||||||
NSpace, NLayout, NLayoutSider, NLayoutContent, NMenu, NTag, NTooltip, NImage, NDropdown, ShowImageTag
|
NSpace,
|
||||||
|
NLayout,
|
||||||
|
NLayoutSider,
|
||||||
|
NLayoutContent,
|
||||||
|
NMenu,
|
||||||
|
NTag,
|
||||||
|
NTooltip,
|
||||||
|
NImage,
|
||||||
|
NDropdown,
|
||||||
|
ShowImageTag,
|
||||||
|
NTabs,
|
||||||
|
NTabPane,
|
||||||
|
AddStyleTags,
|
||||||
|
NPopover
|
||||||
},
|
},
|
||||||
props: ["selectStyle", "height"],
|
props: ['selectStyle', 'height', 'tags'],
|
||||||
setup(props) {
|
setup(props) {
|
||||||
let current_menu = null;
|
let current_menu = null
|
||||||
let selectedKeyRef = ref(null);
|
let selectedKeyRef = ref(null)
|
||||||
|
|
||||||
let selectStyle = ref(props.selectStyle ? props.selectStyle : []);
|
let selectStyle = ref(props.selectStyle ? props.selectStyle : [])
|
||||||
let style_image_list = ref([]);
|
let style_image_list = ref([])
|
||||||
let message = useMessage();
|
let message = useMessage()
|
||||||
let showDropdownRef = ref(false);
|
let showDropdownRef = ref(false)
|
||||||
let current_img = ref(null);
|
let current_img = ref(null)
|
||||||
let menuOptions = ref([]);
|
let menuOptions = ref([])
|
||||||
|
let tags = ref(props.tags)
|
||||||
|
let lora_options = ref([])
|
||||||
|
|
||||||
const x = ref(0);
|
const x = ref(0)
|
||||||
const y = ref(0);
|
const y = ref(0)
|
||||||
|
|
||||||
let dropOption = [{
|
let dropOption = [
|
||||||
label: "选择风格",
|
{
|
||||||
key: "selectStyle"
|
label: '选择风格',
|
||||||
}];
|
key: 'selectStyle'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
// 监听props.selectStyle修改
|
// 监听props.selectStyle修改
|
||||||
watch(() => props.selectStyle, (value) => {
|
watch(
|
||||||
selectStyle.value = value;
|
() => props.selectStyle,
|
||||||
|
(value) => {
|
||||||
|
selectStyle.value = value
|
||||||
if (!selectStyle.value) {
|
if (!selectStyle.value) {
|
||||||
selectStyle.value = [];
|
selectStyle.value = []
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
)
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
setLayoutHeight("layout_height");
|
await window.api.GetDefineConfigJsonByProperty(
|
||||||
|
JSON.stringify(['sd_setting', 'lora', false, []]),
|
||||||
|
(value) => {
|
||||||
|
if (value.code == 0) {
|
||||||
|
message.error(value.message)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// 判断是不是有数据
|
||||||
|
if (value.data) {
|
||||||
|
for (let i = 0; i < value.data.length; i++) {
|
||||||
|
const element = value.data[i]
|
||||||
|
lora_options.value.push({
|
||||||
|
label: element.name,
|
||||||
|
value: element.name
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
setLayoutHeight('layout_height')
|
||||||
await window.api.GetImageStyleMenu((value) => {
|
await window.api.GetImageStyleMenu((value) => {
|
||||||
debugger
|
debugger
|
||||||
if (value.code == 0) {
|
if (value.code == 0) {
|
||||||
message.error(value.message);
|
message.error(value.message)
|
||||||
return;
|
return
|
||||||
}
|
}
|
||||||
menuOptions.value = value.data;
|
menuOptions.value = value.data
|
||||||
current_menu = value.data[0].id;
|
menuOptions.value.unshift({
|
||||||
});
|
label: '自定义样式',
|
||||||
await getStyleImageSubList();
|
id: 'tag',
|
||||||
selectedKeyRef.value = current_menu;
|
key: 'tag'
|
||||||
|
})
|
||||||
|
current_menu = menuOptions.value[0].id
|
||||||
|
})
|
||||||
|
await getStyleImageSubList()
|
||||||
|
selectedKeyRef.value = current_menu
|
||||||
})
|
})
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 菜单选中事件
|
* 菜单选中事件
|
||||||
*/
|
*/
|
||||||
async function SelectMenu(key, item) {
|
async function SelectMenu(key, item) {
|
||||||
current_menu = key;
|
debugger
|
||||||
await getStyleImageSubList();
|
current_menu = key
|
||||||
|
await getStyleImageSubList()
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getStyleImageSubList() {
|
async function getStyleImageSubList() {
|
||||||
|
style_image_list.value = []
|
||||||
|
if (current_menu == 'tag') {
|
||||||
|
for (let i = 0; i < tags.value.style_tags.length; i++) {
|
||||||
|
const element = tags.value.style_tags[i]
|
||||||
|
tags.value.style_tags[i].image = tags.value.style_tags[i].show_image
|
||||||
|
tags.value.style_tags[i].id = tags.value.style_tags[i].key
|
||||||
|
}
|
||||||
|
// 获取当前风格风格中图片显示
|
||||||
|
style_image_list.value = tags.value.style_tags
|
||||||
|
} else {
|
||||||
await window.api.getStyleImageSubList(current_menu, (value) => {
|
await window.api.getStyleImageSubList(current_menu, (value) => {
|
||||||
debugger;
|
debugger
|
||||||
console.log(value)
|
console.log(value)
|
||||||
if (value.code == 0) {
|
if (value.code == 0) {
|
||||||
message.error(value.message);
|
message.error(value.message)
|
||||||
return;
|
return
|
||||||
|
}
|
||||||
|
style_image_list.value = value.data
|
||||||
|
})
|
||||||
}
|
}
|
||||||
style_image_list.value = value.data;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 将指定ID的元素的的高度设置到和当前组件一样高
|
// 将指定ID的元素的的高度设置到和当前组件一样高
|
||||||
function setLayoutHeight(id) {
|
function setLayoutHeight(id) {
|
||||||
let layout_height = document.getElementById(id);
|
let layout_height = document.getElementById(id)
|
||||||
layout_height.style.height = props.height - 40 + "px";
|
layout_height.style.height = props.height - 40 + 'px'
|
||||||
}
|
}
|
||||||
|
|
||||||
async function closeTag(image) {
|
async function closeTag(image) {
|
||||||
debugger;
|
debugger
|
||||||
let index = selectStyle.value.findIndex(item => item.id == image.id);
|
let index = selectStyle.value.findIndex((item) => item.id == image.id)
|
||||||
if (index != -1) {
|
if (index != -1) {
|
||||||
selectStyle.value.splice(index, 1);
|
selectStyle.value.splice(index, 1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -123,28 +248,30 @@ export default defineComponent({
|
|||||||
showDropdownRef,
|
showDropdownRef,
|
||||||
dropOption,
|
dropOption,
|
||||||
current_img,
|
current_img,
|
||||||
|
lora_options,
|
||||||
|
tags,
|
||||||
x: x,
|
x: x,
|
||||||
y: y,
|
y: y,
|
||||||
closeTag,
|
closeTag,
|
||||||
handleContextMenu(e, image) {
|
handleContextMenu(e, image) {
|
||||||
e.preventDefault();
|
e.preventDefault()
|
||||||
current_img.value = image;
|
current_img.value = image
|
||||||
nextTick().then(() => {
|
nextTick().then(() => {
|
||||||
showDropdownRef.value = true;
|
showDropdownRef.value = true
|
||||||
x.value = e.clientX;
|
x.value = e.clientX
|
||||||
y.value = e.clientY;
|
y.value = e.clientY
|
||||||
});
|
})
|
||||||
},
|
},
|
||||||
onClickoutside() {
|
onClickoutside() {
|
||||||
showDropdownRef.value = false;
|
showDropdownRef.value = false
|
||||||
},
|
},
|
||||||
handleSelect(key) {
|
handleSelect(key) {
|
||||||
|
showDropdownRef.value = false
|
||||||
|
if (key == 'selectStyle') {
|
||||||
debugger
|
debugger
|
||||||
showDropdownRef.value = false;
|
|
||||||
if (key == "selectStyle") {
|
|
||||||
// 将当前的风格添加到选择的风格中
|
// 将当前的风格添加到选择的风格中
|
||||||
if (current_img.value) {
|
if (current_img.value) {
|
||||||
selectStyle.value.push(current_img.value);
|
selectStyle.value.push(current_img.value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,56 +1,71 @@
|
|||||||
<template>
|
<template>
|
||||||
<div style="margin-top: 10px; min-height: 40px;">
|
<div style="margin-top: 10px; min-height: 40px">
|
||||||
<n-tooltip trigger="hover" v-for="item in selectStyle" placement="bottom-start">
|
<n-tooltip trigger="hover" v-for="item in selectStyle" placement="bottom-start">
|
||||||
<template #trigger>
|
<template #trigger>
|
||||||
<n-tag @close="closeTag(item)" :key="item.id" type="success"
|
<n-tag
|
||||||
style="margin-right: 10px; margin-bottom: 10px" closable>
|
@close="closeTag(item)"
|
||||||
{{ item.id.split("-")[0] }}
|
:key="item.id"
|
||||||
|
type="success"
|
||||||
|
style="margin-right: 10px; margin-bottom: 10px"
|
||||||
|
closable
|
||||||
|
>
|
||||||
|
{{
|
||||||
|
item.type && item.type == 'style_main'
|
||||||
|
? '自定义_' + item.key.split('-')[0]
|
||||||
|
: item.id.split('-')[0]
|
||||||
|
}}
|
||||||
</n-tag>
|
</n-tag>
|
||||||
</template>
|
</template>
|
||||||
<div>
|
<div>
|
||||||
<n-image :src="item.image" :width="200" :preview-disabled="true"></n-image>
|
<n-image
|
||||||
|
:src="item.image ? item.image : item.show_image"
|
||||||
|
:width="200"
|
||||||
|
:preview-disabled="true"
|
||||||
|
></n-image>
|
||||||
</div>
|
</div>
|
||||||
</n-tooltip>
|
</n-tooltip>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { defineComponent, ref, onMounted, watch, nextTick } from "vue";
|
import { defineComponent, ref, onMounted, watch, nextTick } from 'vue'
|
||||||
import { NImage, NTag, NTooltip, useMessage } from "naive-ui"
|
import { NImage, NTag, NTooltip, useMessage } from 'naive-ui'
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
components: {
|
components: {
|
||||||
NTag, NTooltip, NImage
|
NTag,
|
||||||
|
NTooltip,
|
||||||
|
NImage
|
||||||
},
|
},
|
||||||
props: ["selectStyle"],
|
props: ['selectStyle'],
|
||||||
setup(props) {
|
setup(props) {
|
||||||
let selectStyle = ref(props.selectStyle ? props.selectStyle : []);
|
let selectStyle = ref(props.selectStyle ? props.selectStyle : [])
|
||||||
let message = useMessage();
|
let message = useMessage()
|
||||||
|
|
||||||
|
|
||||||
// 监听props.selectStyle修改
|
// 监听props.selectStyle修改
|
||||||
watch(() => props.selectStyle, (value) => {
|
watch(
|
||||||
selectStyle.value = value;
|
() => props.selectStyle,
|
||||||
|
(value) => {
|
||||||
|
selectStyle.value = value
|
||||||
if (!selectStyle.value) {
|
if (!selectStyle.value) {
|
||||||
selectStyle.value = [];
|
selectStyle.value = []
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
)
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {})
|
||||||
})
|
|
||||||
|
|
||||||
async function closeTag(image) {
|
async function closeTag(image) {
|
||||||
debugger;
|
debugger
|
||||||
let index = selectStyle.value.findIndex(item => item.id == image.id);
|
let index = selectStyle.value.findIndex((item) => item.id == image.id)
|
||||||
if (index != -1) {
|
if (index != -1) {
|
||||||
selectStyle.value.splice(index, 1);
|
selectStyle.value.splice(index, 1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
selectStyle,
|
selectStyle,
|
||||||
closeTag,
|
closeTag
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@ -1,163 +1,297 @@
|
|||||||
<template>
|
<template>
|
||||||
<div style="width: 500px;">
|
<div>
|
||||||
|
<div style="width: 500px; position: relative">
|
||||||
<n-form ref="formRef" label-placement="top" :model="characterData" :rules="rules">
|
<n-form ref="formRef" label-placement="top" :model="characterData" :rules="rules">
|
||||||
<n-form-item label="人物名称" path="label">
|
<n-form-item label="人物名称" path="label">
|
||||||
<n-input v-model:value="characterData.label" placeholder="请输入人物名称" />
|
<n-input v-model:value="characterData.label" placeholder="请输入人物名称" />
|
||||||
|
<n-image
|
||||||
|
style="position: absolute; left: 520px; top: 0"
|
||||||
|
width="120"
|
||||||
|
height="120"
|
||||||
|
:src="png_base64 ? png_base64 : characterData.show_image"
|
||||||
|
/>
|
||||||
</n-form-item>
|
</n-form-item>
|
||||||
<n-form-item label="人物别名(可多个)">
|
<n-form-item label="人物别名(可多个)">
|
||||||
<n-dynamic-tags type="success" v-model:value="alias_tags" />
|
<n-dynamic-tags type="success" v-model:value="alias_tags" />
|
||||||
</n-form-item>
|
</n-form-item>
|
||||||
<n-form-item label="人物提示词(中文)">
|
<n-form-item label="人物提示词(中文)">
|
||||||
<n-input type="textarea" :rows="2" v-model:value="characterData.chinese_prompt"
|
<n-input
|
||||||
placeholder="请输入人物提示词" />
|
type="textarea"
|
||||||
<n-button type="info" size="small" style="margin-left: 20px;" @click="TranslatePrompt"
|
:rows="2"
|
||||||
:loading="loading">翻译提示词</n-button>
|
v-model:value="characterData.chinese_prompt"
|
||||||
|
placeholder="请输入人物提示词"
|
||||||
|
/>
|
||||||
|
<!-- 里面的按钮设置上下居中 -->
|
||||||
|
|
||||||
|
<div style="width: 100px; margin-left: 20px">
|
||||||
|
<n-button color="#a76283" size="tiny" @click="TranslatePrompt" :loading="loading"
|
||||||
|
>翻译提示词</n-button
|
||||||
|
>
|
||||||
|
<n-button
|
||||||
|
color="#e18a3b"
|
||||||
|
size="tiny"
|
||||||
|
style="margin-top: 10px"
|
||||||
|
@click="GenerateCharacterImage"
|
||||||
|
:loading="imageLoading"
|
||||||
|
>生成图片</n-button
|
||||||
|
>
|
||||||
|
</div>
|
||||||
</n-form-item>
|
</n-form-item>
|
||||||
<n-form-item label="人物提示词(英文)" path="prompt">
|
<n-form-item label="人物提示词(英文)" path="prompt">
|
||||||
<n-input type="textarea" :rows="2" v-model:value="characterData.prompt" placeholder="请输入人物提示词" />
|
<n-input
|
||||||
|
type="textarea"
|
||||||
|
:rows="2"
|
||||||
|
v-model:value="characterData.prompt"
|
||||||
|
placeholder="请输入人物提示词"
|
||||||
|
/>
|
||||||
</n-form-item>
|
</n-form-item>
|
||||||
<n-form-item label="MJ:人物图片链接(cref)">
|
<n-form-item label="MJ:人物图片链接(cref)">
|
||||||
<n-input v-model:value="characterData.image_url" placeholder="请输入人物图片链接" style="margin-right: 20px;" />
|
<n-input
|
||||||
<n-image v-if="characterData.image_url" :src="characterData.image_url"
|
v-model:value="characterData.image_url"
|
||||||
style="width: 80px; height: 80px" />
|
placeholder="请输入人物图片链接"
|
||||||
|
style="margin-right: 20px"
|
||||||
|
/>
|
||||||
|
<n-image
|
||||||
|
v-if="characterData.image_url"
|
||||||
|
:src="characterData.image_url"
|
||||||
|
style="width: 80px; height: 80px"
|
||||||
|
:alt="characterData.image_url"
|
||||||
|
/>
|
||||||
</n-form-item>
|
</n-form-item>
|
||||||
<n-form-item label="MJ:角色迁移 cw 值(0-100)">
|
<n-form-item label="MJ:角色迁移 cw 值(0-100)">
|
||||||
<n-input-number :show-button="false" v-model:value="characterData.cref_cw" min="0" max="100"
|
<n-input-number
|
||||||
placeholder="请输入人物风格迁移的CW值" />
|
:show-button="false"
|
||||||
|
v-model:value="characterData.cref_cw"
|
||||||
|
min="0"
|
||||||
|
max="100"
|
||||||
|
placeholder="请输入人物风格迁移的CW值"
|
||||||
|
/>
|
||||||
</n-form-item>
|
</n-form-item>
|
||||||
<n-form-item label="SD:Lora选择">
|
<n-form-item label="SD:Lora选择">
|
||||||
<n-input v-model:value="characterData.lora" placeholder="请输入人物Lora选择" />
|
<n-select
|
||||||
<!-- <n-button color="#e18a3b" style="margin-left: 20px;">选择</n-button> -->
|
v-model:value="characterData.lora"
|
||||||
|
style="width: 250px"
|
||||||
|
:options="lora_options"
|
||||||
|
placeholder="选择人物lora"
|
||||||
|
/>
|
||||||
|
<n-input-number
|
||||||
|
style="width: 120px; margin-left: 10px"
|
||||||
|
placeholder="权重"
|
||||||
|
v-model:value="characterData.lora_weight"
|
||||||
|
:show-button="false"
|
||||||
|
:max="2"
|
||||||
|
:step="0.01"
|
||||||
|
:precision="2"
|
||||||
|
S
|
||||||
|
:min="0"
|
||||||
|
/>
|
||||||
</n-form-item>
|
</n-form-item>
|
||||||
</n-form>
|
</n-form>
|
||||||
<div style="text-align: right;">
|
<div style="text-align: right">
|
||||||
<n-button type="success" @click="SaveCharacterTag">保存</n-button>
|
<n-button type="success" @click="SaveCharacterTag">保存</n-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { ref, h, onMounted, defineComponent, toRaw, watch } from "vue"
|
import { ref, h, onMounted, defineComponent, toRaw, watch, nextTick } from 'vue'
|
||||||
import { NImage, useMessage, NButton, useDialog, NInput, NForm, NFormItem, NDynamicTags, NInputNumber } from "naive-ui";
|
import {
|
||||||
import { DEFINE_STRING } from "../../../../../define/define_string";
|
NImage,
|
||||||
import { v4 as uuidv4 } from "uuid";
|
useMessage,
|
||||||
|
NButton,
|
||||||
|
useDialog,
|
||||||
|
NInput,
|
||||||
|
NForm,
|
||||||
|
NFormItem,
|
||||||
|
NDynamicTags,
|
||||||
|
NInputNumber,
|
||||||
|
NSelect
|
||||||
|
} from 'naive-ui'
|
||||||
|
import { v4 as uuidv4 } from 'uuid'
|
||||||
|
import { isEmpty } from 'lodash'
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
components: {
|
components: {
|
||||||
NImage, NButton, NInput, NForm, NFormItem, NDynamicTags, NInputNumber
|
NImage,
|
||||||
|
NButton,
|
||||||
|
NInput,
|
||||||
|
NForm,
|
||||||
|
NFormItem,
|
||||||
|
NDynamicTags,
|
||||||
|
NInputNumber,
|
||||||
|
NSelect
|
||||||
},
|
},
|
||||||
props: ["currentCharacter", "initFunc", "currentTags"],
|
props: ['currentCharacter', 'initFunc', 'currentTags', 'lora_options'],
|
||||||
setup(props) {
|
setup(props) {
|
||||||
let message = useMessage();
|
let message = useMessage()
|
||||||
let alias_tags = ref(props.currentTags);
|
let alias_tags = ref(props.currentTags)
|
||||||
let characterData = ref(props.currentCharacter);
|
let characterData = ref(props.currentCharacter)
|
||||||
let loading = ref(false);
|
let lora_options = ref(props.lora_options)
|
||||||
|
let loading = ref(false)
|
||||||
|
let imageLoading = ref(false)
|
||||||
let formRef = ref(null)
|
let formRef = ref(null)
|
||||||
|
|
||||||
|
let png_base64 = ref(null)
|
||||||
|
|
||||||
// 监听数据变化
|
// 监听数据变化
|
||||||
watch(() => props.currentCharacter, (value) => {
|
watch(
|
||||||
characterData.value = value;
|
() => props.currentCharacter,
|
||||||
}, { deep: true })
|
(value) => {
|
||||||
|
characterData.value = value
|
||||||
|
},
|
||||||
|
{ deep: true }
|
||||||
|
)
|
||||||
|
|
||||||
watch(() => props.currentTags, (value) => {
|
watch(
|
||||||
alias_tags.value = value;
|
() => props.currentTags,
|
||||||
}, { deep: true })
|
(value) => {
|
||||||
|
alias_tags.value = value
|
||||||
|
},
|
||||||
|
{ deep: true }
|
||||||
|
)
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {})
|
||||||
|
|
||||||
})
|
|
||||||
|
|
||||||
async function SaveCharacterTag(e) {
|
async function SaveCharacterTag(e) {
|
||||||
e.preventDefault();
|
e.preventDefault()
|
||||||
formRef.value?.validate(async (errors) => {
|
formRef.value?.validate(async (errors) => {
|
||||||
if (errors) {
|
if (errors) {
|
||||||
message.error("请检查必填字段");
|
message.error('请检查必填字段')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// 保存之前要处理数据(判断该当前的将别名数组中的数据进行拆分)
|
// 保存之前要处理数据(判断该当前的将别名数组中的数据进行拆分)
|
||||||
let children = [];
|
let children = []
|
||||||
alias_tags.value.forEach((item) => {
|
alias_tags.value.forEach((item) => {
|
||||||
children.push({
|
children.push({
|
||||||
label: item,
|
label: item,
|
||||||
key: uuidv4(),
|
key: uuidv4(),
|
||||||
type: "min",
|
type: 'min',
|
||||||
chinese_prompt: characterData.value.chinese_prompt,
|
chinese_prompt: characterData.value.chinese_prompt,
|
||||||
prompt: characterData.value.prompt,
|
prompt: characterData.value.prompt,
|
||||||
image_url: characterData.value.image_url,
|
image_url: characterData.value.image_url,
|
||||||
|
show_image: characterData.value.show_image,
|
||||||
cref_cw: characterData.value.cref_cw,
|
cref_cw: characterData.value.cref_cw,
|
||||||
lora: characterData.value.lora,
|
lora: characterData.value.lora,
|
||||||
|
lora_weight: characterData.value.lora_weight
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
characterData.value["children"] = children;
|
characterData.value['children'] = children
|
||||||
|
console.log(characterData.value)
|
||||||
debugger;
|
characterData.value['type'] = 'character_main'
|
||||||
console.log(characterData.value);
|
|
||||||
characterData.value['type'] = "character_main";
|
|
||||||
|
|
||||||
// 开始保存
|
// 开始保存
|
||||||
await window.mj.SaveTagPropertyData([JSON.stringify(characterData.value), "character_tags"], (value) => {
|
await window.mj.SaveTagPropertyData(
|
||||||
debugger;
|
[JSON.stringify(characterData.value), 'character_tags'],
|
||||||
console.log(value);
|
(value) => {
|
||||||
|
debugger
|
||||||
|
console.log(value)
|
||||||
if (value.code == 0) {
|
if (value.code == 0) {
|
||||||
message.error(value.message);
|
message.error(value.message)
|
||||||
return;
|
return
|
||||||
}
|
}
|
||||||
message.success(value.message);
|
message.success(value.message)
|
||||||
//保存成功在initFunc
|
//保存成功在initFunc
|
||||||
props.initFunc();
|
props.initFunc()
|
||||||
// 清楚数据
|
// 清楚数据
|
||||||
characterData.value = {
|
characterData.value = {
|
||||||
label: null,
|
label: null,
|
||||||
key: null,
|
key: null,
|
||||||
type: "character_main",
|
type: 'character_main',
|
||||||
|
chinese_prompt: null,
|
||||||
prompt: null,
|
prompt: null,
|
||||||
image_url: null,
|
image_url: null,
|
||||||
|
show_image: window.config.space_image,
|
||||||
cref_cw: 20,
|
cref_cw: 20,
|
||||||
lora: null,
|
chinese_prompt: null,
|
||||||
};
|
lora: '无',
|
||||||
alias_tags.value = [];
|
lora_weight: 1
|
||||||
|
}
|
||||||
|
png_base64.value = null
|
||||||
|
alias_tags.value = []
|
||||||
|
}
|
||||||
|
)
|
||||||
})
|
})
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 翻译提示词
|
// 翻译提示词
|
||||||
async function TranslatePrompt() {
|
async function TranslatePrompt() {
|
||||||
loading.value = true;
|
loading.value = true
|
||||||
if (characterData.value.chinese_prompt == "" || characterData.value.chinese_prompt == null) {
|
if (characterData.value.chinese_prompt == '' || characterData.value.chinese_prompt == null) {
|
||||||
message.error("请输入中文提示词");
|
message.error('请输入中文提示词')
|
||||||
loading.value = false;
|
loading.value = false
|
||||||
return;
|
return
|
||||||
}
|
}
|
||||||
await window.api.TranslateReturnNow([characterData.value.chinese_prompt, 'zh', 'en', false], (value) => {
|
await window.api.TranslateReturnNow(
|
||||||
|
[characterData.value.chinese_prompt, 'zh', 'en', false],
|
||||||
|
(value) => {
|
||||||
if (value.code == 0) {
|
if (value.code == 0) {
|
||||||
message.error(value.message);
|
message.error(value.message)
|
||||||
return;
|
return
|
||||||
}
|
}
|
||||||
debugger
|
characterData.value.prompt = value.data[0].src
|
||||||
//
|
}
|
||||||
console.log(value.data);
|
)
|
||||||
characterData.value.prompt = value.data[0].src;
|
loading.value = false
|
||||||
})
|
|
||||||
loading.value = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
let ruleObj = (errorMessage) => {
|
let ruleObj = (errorMessage) => {
|
||||||
return [{
|
return [
|
||||||
|
{
|
||||||
required: true,
|
required: true,
|
||||||
validator(rule, value) {
|
validator(rule, value) {
|
||||||
if (value == null || value == "")
|
if (value == null || value == '') return new Error(errorMessage)
|
||||||
return new Error(errorMessage);
|
return true
|
||||||
return true;
|
|
||||||
},
|
},
|
||||||
trigger: ["input", "blur", "change"]
|
trigger: ['input', 'blur', 'change']
|
||||||
}]
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
let rules = {
|
let rules = {
|
||||||
label: ruleObj("必填人物名称"),
|
label: ruleObj('必填人物名称'),
|
||||||
prompt: ruleObj("必填英文提示词")
|
prompt: ruleObj('必填英文提示词')
|
||||||
};
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 单张生成角色图片,预览
|
||||||
|
*/
|
||||||
|
async function GenerateCharacterImage() {
|
||||||
|
// 判断lora是不是存在
|
||||||
|
let lora = ''
|
||||||
|
if (
|
||||||
|
characterData.value.lora != null &&
|
||||||
|
characterData.value.lora != '' &&
|
||||||
|
characterData.value.lora != '无'
|
||||||
|
) {
|
||||||
|
lora = `<lora:${characterData.value.lora}:${characterData.value.lora_weight}>`
|
||||||
|
}
|
||||||
|
let d = {
|
||||||
|
prompt: `${characterData.value.prompt}, ${lora}`,
|
||||||
|
width: 1024,
|
||||||
|
height: 1024
|
||||||
|
}
|
||||||
|
if (isEmpty(characterData.value.prompt)) {
|
||||||
|
message.error('请填写英文提示词')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
imageLoading.value = true
|
||||||
|
await window.sd.txt2img(JSON.stringify([d]), async (value) => {
|
||||||
|
debugger
|
||||||
|
if (value.code == 0) {
|
||||||
|
message.error(value.message)
|
||||||
|
imageLoading.value = false
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (value.data && value.data.length > 0) {
|
||||||
|
let d = value.data[0]
|
||||||
|
characterData.value.show_image = d.image_path.replaceAll('\\', '/')
|
||||||
|
png_base64.value = 'data:image/png;base64,' + d.base64
|
||||||
|
console.log(characterData.value.show_image)
|
||||||
|
imageLoading.value = false
|
||||||
|
}
|
||||||
|
// 使用 Vue.nextTick 等待 Vue 更新视图
|
||||||
|
imageLoading.value = false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
characterData,
|
characterData,
|
||||||
@ -166,7 +300,11 @@ export default defineComponent({
|
|||||||
TranslatePrompt,
|
TranslatePrompt,
|
||||||
loading,
|
loading,
|
||||||
rules,
|
rules,
|
||||||
formRef
|
formRef,
|
||||||
|
lora_options,
|
||||||
|
imageLoading,
|
||||||
|
GenerateCharacterImage,
|
||||||
|
png_base64
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@ -1,143 +1,280 @@
|
|||||||
<template>
|
<template>
|
||||||
<div style="width: 500px;">
|
<div style="width: 500px">
|
||||||
<n-form label-placement="top" ref="formRef" :rules="rules" :model="styleData">
|
<n-form label-placement="top" ref="formRef" :rules="rules" :model="styleData">
|
||||||
<n-form-item label="风格名称" path="label">
|
<n-form-item label="风格名称" path="label">
|
||||||
<n-input v-model:value="styleData.label" placeholder="请输入风格名称" />
|
<n-input v-model:value="styleData.label" placeholder="请输入风格名称" />
|
||||||
|
<n-image
|
||||||
|
style="position: absolute; left: 520px; top: 0"
|
||||||
|
width="120"
|
||||||
|
height="120"
|
||||||
|
:src="png_base64 ? png_base64 : styleData.show_image"
|
||||||
|
/>
|
||||||
</n-form-item>
|
</n-form-item>
|
||||||
<n-form-item label="风格提示词描述(中文)">
|
<n-form-item label="风格提示词描述(中文)">
|
||||||
<n-input type="textarea" :rows="3" v-model:value="styleData.chinese_prompt"
|
<n-input
|
||||||
placeholder="请输入风格提示词描述(中文)" />
|
type="textarea"
|
||||||
<n-button type="info" size="small" style="margin-left: 20px;" @click="TranslatePrompt"
|
:rows="2"
|
||||||
:loading="loading">翻译提示词</n-button>
|
v-model:value="styleData.chinese_prompt"
|
||||||
|
placeholder="请输入风格提示词描述(中文)"
|
||||||
|
/>
|
||||||
|
<div style="width: 100px; margin-left: 20px">
|
||||||
|
<n-button type="info" size="tiny" @click="TranslatePrompt" :loading="loading"
|
||||||
|
>翻译提示词</n-button
|
||||||
|
>
|
||||||
|
<n-tooltip trigger="hover">
|
||||||
|
<template #trigger>
|
||||||
|
<n-button
|
||||||
|
color="#e18a3b"
|
||||||
|
size="tiny"
|
||||||
|
style="margin-top: 10px"
|
||||||
|
@click="GenerateStyleImage"
|
||||||
|
:loading="imageLoading"
|
||||||
|
>生成图片</n-button
|
||||||
|
>
|
||||||
|
</template>
|
||||||
|
使用SD出图模式生成风格图片,提示词为1gril加上风格提示词
|
||||||
|
</n-tooltip>
|
||||||
|
</div>
|
||||||
</n-form-item>
|
</n-form-item>
|
||||||
<n-form-item label="风格提示词描述(英文)" path ="prompt">
|
<n-form-item label="风格提示词描述(英文)" path="prompt">
|
||||||
<n-input type="textarea" :rows="3" v-model:value="styleData.prompt" placeholder="请输入风格提示词描述(英文)" />
|
<n-input
|
||||||
|
type="textarea"
|
||||||
|
:rows="3"
|
||||||
|
v-model:value="styleData.prompt"
|
||||||
|
placeholder="请输入风格提示词描述(英文)"
|
||||||
|
/>
|
||||||
</n-form-item>
|
</n-form-item>
|
||||||
<n-form-item label="MJ:风格垫图链接(sref)">
|
<n-form-item label="MJ:风格垫图链接(sref)">
|
||||||
<n-input v-model:value="styleData.image_url" placeholder="请输入风格垫图链接" style="margin-right: 20px;" />
|
<n-input
|
||||||
<n-image v-if="styleData.image_url" :src="styleData.image_url" style="width: 80px; height: 80px" />
|
v-model:value="styleData.image_url"
|
||||||
|
placeholder="请输入风格垫图链接"
|
||||||
|
style="margin-right: 20px"
|
||||||
|
/>
|
||||||
|
<n-image
|
||||||
|
v-if="styleData.image_url"
|
||||||
|
:src="styleData.image_url"
|
||||||
|
style="width: 80px; height: 80px"
|
||||||
|
/>
|
||||||
</n-form-item>
|
</n-form-item>
|
||||||
<n-form-item label="MJ:风格迁移 cw 值(0-1000)">
|
<n-form-item label="MJ:风格迁移 sw 值(0-1000)">
|
||||||
<n-input-number :show-button="false" v-model:value="styleData.sref_cw" min="0" max="1000"
|
<n-input-number
|
||||||
placeholder="请输入人物风格迁移的CW值" />
|
:show-button="false"
|
||||||
|
v-model:value="styleData.sref_sw"
|
||||||
|
min="0"
|
||||||
|
max="1000"
|
||||||
|
placeholder="请输入人物风格迁移的SW值"
|
||||||
|
/>
|
||||||
</n-form-item>
|
</n-form-item>
|
||||||
<n-form-item label="SD:Lora选择">
|
<n-form-item label="SD:Lora选择">
|
||||||
<n-input v-model:value="styleData.lora" placeholder="请输入风格Lora" />
|
<n-select :options="lora_options" v-model:value="styleData.lora"> </n-select>
|
||||||
<!-- <n-button color="#e18a3b" style="margin-left: 20px;">选择</n-button> -->
|
<n-input-number
|
||||||
|
style="width: 120px; margin-left: 10px"
|
||||||
|
placeholder="权重"
|
||||||
|
v-model:value="styleData.lora_weight"
|
||||||
|
:show-button="false"
|
||||||
|
:max="2"
|
||||||
|
:step="0.01"
|
||||||
|
:precision="2"
|
||||||
|
S
|
||||||
|
:min="0"
|
||||||
|
/>
|
||||||
</n-form-item>
|
</n-form-item>
|
||||||
</n-form>
|
</n-form>
|
||||||
|
|
||||||
<div style="text-align: right;">
|
<div style="text-align: right">
|
||||||
<n-button type="success" @click="SaveStyleTag">保存</n-button>
|
<n-button type="success" @click="SaveStyleTag">保存</n-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { ref, h, onMounted, defineComponent, toRaw, watch } from "vue"
|
import { ref, h, onMounted, defineComponent, toRaw, watch } from 'vue'
|
||||||
import { NImage, useMessage, NButton, useDialog, NInput, NForm, NFormItem, NDynamicTags, NInputNumber } from "naive-ui";
|
import {
|
||||||
import { DEFINE_STRING } from "../../../../../define/define_string";
|
NImage,
|
||||||
import { v4 as uuidv4 } from "uuid";
|
useMessage,
|
||||||
|
NButton,
|
||||||
|
useDialog,
|
||||||
|
NInput,
|
||||||
|
NForm,
|
||||||
|
NFormItem,
|
||||||
|
NDynamicTags,
|
||||||
|
NInputNumber,
|
||||||
|
NSelect,
|
||||||
|
NTooltip
|
||||||
|
} from 'naive-ui'
|
||||||
|
import { isEmpty } from 'lodash'
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
components: {
|
components: {
|
||||||
NImage, NButton, NInput, NForm, NFormItem, NDynamicTags, NInputNumber
|
NImage,
|
||||||
|
NButton,
|
||||||
|
NInput,
|
||||||
|
NForm,
|
||||||
|
NFormItem,
|
||||||
|
NDynamicTags,
|
||||||
|
NInputNumber,
|
||||||
|
NSelect,
|
||||||
|
NTooltip
|
||||||
},
|
},
|
||||||
props: ["currentStyle", "initFunc"],
|
props: ['currentStyle', 'initFunc', 'lora_options'],
|
||||||
setup(props) {
|
setup(props) {
|
||||||
let message = useMessage();
|
let message = useMessage()
|
||||||
let styleData = ref(props.currentStyle);
|
let styleData = ref(
|
||||||
let loading = ref(false);
|
props.currentStyle
|
||||||
|
? props.currentStyle
|
||||||
|
: { show_image: window.config.space_image, lora_weight: 1, sref_sw: 50, lora: '无' }
|
||||||
|
)
|
||||||
|
let loading = ref(false)
|
||||||
|
let imageLoading = ref(false)
|
||||||
let formRef = ref(null)
|
let formRef = ref(null)
|
||||||
|
let lora_options = ref(props.lora_options)
|
||||||
|
let png_base64 = ref(null)
|
||||||
|
|
||||||
// 监听数据变化
|
// 监听数据变化
|
||||||
watch(() => props.currentStyle, (value) => {
|
watch(
|
||||||
styleData.value = value;
|
() => props.currentStyle,
|
||||||
}, { deep: true })
|
(value) => {
|
||||||
|
styleData.value = value
|
||||||
|
},
|
||||||
|
{ deep: true }
|
||||||
|
)
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {})
|
||||||
|
|
||||||
})
|
|
||||||
|
|
||||||
async function SaveStyleTag(e) {
|
async function SaveStyleTag(e) {
|
||||||
e.preventDefault();
|
e.preventDefault()
|
||||||
formRef.value?.validate(async (errors) => {
|
formRef.value?.validate(async (errors) => {
|
||||||
if (errors) {
|
if (errors) {
|
||||||
message.error("请检查必填字段");
|
message.error('请检查必填字段')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
styleData.value["type"] = "style_main";
|
styleData.value['type'] = 'style_main'
|
||||||
// 直接保存
|
// 直接保存
|
||||||
// 开始保存
|
// 开始保存
|
||||||
await window.mj.SaveTagPropertyData([JSON.stringify(styleData.value), "style_tags"], (value) => {
|
await window.mj.SaveTagPropertyData(
|
||||||
debugger;
|
[JSON.stringify(styleData.value), 'style_tags'],
|
||||||
console.log(value);
|
(value) => {
|
||||||
|
debugger
|
||||||
|
console.log(value)
|
||||||
if (value.code == 0) {
|
if (value.code == 0) {
|
||||||
message.error(value.message);
|
message.error(value.message)
|
||||||
return;
|
return
|
||||||
}
|
}
|
||||||
message.success(value.message);
|
message.success(value.message)
|
||||||
//保存成功在initFunc
|
//保存成功在initFunc
|
||||||
props.initFunc();
|
props.initFunc()
|
||||||
// 清楚数据
|
// 清楚数据
|
||||||
styleData.value = {
|
styleData.value = {
|
||||||
label: null,
|
label: null,
|
||||||
key: null,
|
key: null,
|
||||||
type: "style_main",
|
type: 'style_main',
|
||||||
prompt: null,
|
prompt: null,
|
||||||
|
show_image: window.config.space_image,
|
||||||
image_url: null,
|
image_url: null,
|
||||||
cref_cw: 20,
|
cref_cw: 20,
|
||||||
lora: null,
|
lora: '无'
|
||||||
};
|
}
|
||||||
|
png_base64.value = null
|
||||||
|
}
|
||||||
|
)
|
||||||
})
|
})
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 翻译中文提示词
|
* 翻译中文提示词
|
||||||
*/
|
*/
|
||||||
async function TranslatePrompt(){
|
async function TranslatePrompt() {
|
||||||
loading.value = true;
|
loading.value = true
|
||||||
if (styleData.value.chinese_prompt == "" || styleData.value.chinese_prompt == null) {
|
if (styleData.value.chinese_prompt == '' || styleData.value.chinese_prompt == null) {
|
||||||
message.error("请输入中文提示词");
|
message.error('请输入中文提示词')
|
||||||
loading.value = false;
|
loading.value = false
|
||||||
return;
|
return
|
||||||
}
|
}
|
||||||
await window.api.TranslateReturnNow([styleData.value.chinese_prompt, 'zh', 'en', false], (value) => {
|
await window.api.TranslateReturnNow(
|
||||||
|
[styleData.value.chinese_prompt, 'zh', 'en', false],
|
||||||
|
(value) => {
|
||||||
if (value.code == 0) {
|
if (value.code == 0) {
|
||||||
message.error(value.message);
|
message.error(value.message)
|
||||||
return;
|
return
|
||||||
}
|
}
|
||||||
//
|
console.log(value.data)
|
||||||
console.log(value.data);
|
styleData.value.prompt = value.data[0].src
|
||||||
styleData.value.prompt = value.data[0].src;
|
}
|
||||||
})
|
)
|
||||||
loading.value = false;
|
loading.value = false
|
||||||
}
|
}
|
||||||
|
|
||||||
let ruleObj = (errorMessage) => {
|
let ruleObj = (errorMessage) => {
|
||||||
return [{
|
return [
|
||||||
|
{
|
||||||
required: true,
|
required: true,
|
||||||
validator(rule, value) {
|
validator(rule, value) {
|
||||||
if (value == null || value == "")
|
if (value == null || value == '') return new Error(errorMessage)
|
||||||
return new Error(errorMessage);
|
return true
|
||||||
return true;
|
|
||||||
},
|
},
|
||||||
trigger: ["input", "blur", "change"]
|
trigger: ['input', 'blur', 'change']
|
||||||
}]
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
let rules = {
|
let rules = {
|
||||||
label: ruleObj("必填人物名称"),
|
label: ruleObj('必填人物名称'),
|
||||||
prompt: ruleObj("必填英文提示词")
|
prompt: ruleObj('必填英文提示词')
|
||||||
};
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生成风格图片
|
||||||
|
*/
|
||||||
|
async function GenerateStyleImage() {
|
||||||
|
if (isEmpty(styleData.value.prompt)) {
|
||||||
|
message.error('请输入提示词')
|
||||||
|
imageLoading.value = false
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// 判断lora是不是存在
|
||||||
|
let lora = ''
|
||||||
|
if (
|
||||||
|
styleData.value.lora != null &&
|
||||||
|
styleData.value.lora != '' &&
|
||||||
|
styleData.value.lora != '无'
|
||||||
|
) {
|
||||||
|
lora = `<lora:${styleData.value.lora}:${styleData.value.lora_weight}>`
|
||||||
|
}
|
||||||
|
let d = {
|
||||||
|
prompt: `1gril, ${styleData.value.prompt}, ${lora}`,
|
||||||
|
width: 1024,
|
||||||
|
height: 1024
|
||||||
|
}
|
||||||
|
imageLoading.value = true
|
||||||
|
await window.sd.txt2img(JSON.stringify([d]), async (value) => {
|
||||||
|
debugger
|
||||||
|
if (value.code == 0) {
|
||||||
|
message.error(value.message)
|
||||||
|
imageLoading.value = false
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (value.data && value.data.length > 0) {
|
||||||
|
let d = value.data[0]
|
||||||
|
styleData.value.show_image = d.image_path.replaceAll('\\', '/')
|
||||||
|
png_base64.value = 'data:image/png;base64,' + d.base64
|
||||||
|
console.log(styleData.value.show_image)
|
||||||
|
imageLoading.value = false
|
||||||
|
}
|
||||||
|
// 使用 Vue.nextTick 等待 Vue 更新视图
|
||||||
|
imageLoading.value = false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
styleData,
|
styleData,
|
||||||
SaveStyleTag,
|
SaveStyleTag,
|
||||||
loading,
|
loading,
|
||||||
|
imageLoading,
|
||||||
rules,
|
rules,
|
||||||
formRef,
|
formRef,
|
||||||
TranslatePrompt
|
TranslatePrompt,
|
||||||
|
lora_options,
|
||||||
|
png_base64,
|
||||||
|
GenerateStyleImage
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@ -1,24 +1,48 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
|
|
||||||
<n-split direction="horizontal" :max="0.3" :min="0.18" :default-size="0.18">
|
<n-split direction="horizontal" :max="0.3" :min="0.18" :default-size="0.18">
|
||||||
<template #1>
|
<template #1>
|
||||||
<div id="tree_define_content" style="display: flex; overflow-y: auto;">
|
<div id="tree_define_content" style="display: flex; overflow-y: auto">
|
||||||
<n-tree :node-props="nodeProps" style="width: 200px;" block-line :data="treeData" />
|
<n-tree :node-props="nodeProps" style="width: 200px" block-line :data="treeData" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template #2>
|
<template #2>
|
||||||
<div style="margin-left: 20px;">
|
<div style="margin-left: 20px">
|
||||||
<AddCharacterTag v-if="currentType.startsWith('character')" :currentCharacter="currentCharacter"
|
<AddCharacterTag
|
||||||
:currentTags="currentTags" :initFunc="InitData" />
|
v-if="currentType.startsWith('character')"
|
||||||
<AddStyleTags v-else-if="currentType.startsWith('style')" :currentStyle="currentStyle"
|
:currentCharacter="currentCharacter"
|
||||||
:initFunc="InitData" />
|
:currentTags="currentTags"
|
||||||
<AddSceneTags v-else-if="currentType.startsWith('scene')" :currentScene="currentScene"
|
:initFunc="InitData"
|
||||||
:initFunc="InitData" />
|
:lora_options="lora_options"
|
||||||
<AddPrefixTags v-else-if="currentType.startsWith('prefix')" :currentPrefix="currentPrefix"
|
/>
|
||||||
:initFunc="InitData" />
|
<AddStyleTags
|
||||||
<AddSuffixTags v-else-if="currentType.startsWith('suffix')" :currentSuffix="currentSuffix"
|
v-else-if="currentType.startsWith('style')"
|
||||||
:initFunc="InitData" />
|
:currentStyle="currentStyle"
|
||||||
|
:initFunc="InitData"
|
||||||
|
:lora_options="lora_options"
|
||||||
|
/>
|
||||||
|
<AddSceneTags
|
||||||
|
v-else-if="currentType.startsWith('scene')"
|
||||||
|
:currentScene="currentScene"
|
||||||
|
:initFunc="InitData"
|
||||||
|
/>
|
||||||
|
<AddPrefixTags
|
||||||
|
v-else-if="currentType.startsWith('prefix')"
|
||||||
|
:currentPrefix="currentPrefix"
|
||||||
|
:initFunc="InitData"
|
||||||
|
/>
|
||||||
|
<AddSuffixTags
|
||||||
|
v-else-if="currentType.startsWith('suffix')"
|
||||||
|
:currentSuffix="currentSuffix"
|
||||||
|
:initFunc="InitData"
|
||||||
|
/>
|
||||||
|
<n-empty v-else description="是一个飞机">
|
||||||
|
<template #icon>
|
||||||
|
<n-icon>
|
||||||
|
<airplane />
|
||||||
|
</n-icon>
|
||||||
|
</template>
|
||||||
|
</n-empty>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</n-split>
|
</n-split>
|
||||||
@ -26,146 +50,234 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { ref, h, onMounted, defineComponent, toRaw } from "vue"
|
import { ref, h, onMounted, defineComponent, toRaw } from 'vue'
|
||||||
import { NImage, useMessage, NButton, useDialog, NInput, NCard, NTabs, NTabPane, NTree, NSplit, NIcon } from "naive-ui";
|
import {
|
||||||
import { DEFINE_STRING } from "../../../../../define/define_string";
|
NImage,
|
||||||
import { v4 as uuidv4 } from "uuid";
|
useMessage,
|
||||||
import AddCharacterTag from "./AddCharacterTag.vue";
|
NButton,
|
||||||
import AddStyleTags from "./AddStyleTags.vue";
|
useDialog,
|
||||||
import AddSceneTags from "./AddSceneTags.vue";
|
NInput,
|
||||||
import AddPrefixTags from "./AddPrefixTags.vue";
|
NCard,
|
||||||
import AddSuffixTags from "./AddSuffixTags.vue";
|
NTabs,
|
||||||
import { Trash } from "@vicons/ionicons5"
|
NTabPane,
|
||||||
|
NTree,
|
||||||
|
NSplit,
|
||||||
|
NIcon,
|
||||||
|
NEmpty
|
||||||
|
} from 'naive-ui'
|
||||||
|
import { DEFINE_STRING } from '../../../../../define/define_string'
|
||||||
|
import { v4 as uuidv4 } from 'uuid'
|
||||||
|
import AddCharacterTag from './AddCharacterTag.vue'
|
||||||
|
import AddStyleTags from './AddStyleTags.vue'
|
||||||
|
import AddSceneTags from './AddSceneTags.vue'
|
||||||
|
import AddPrefixTags from './AddPrefixTags.vue'
|
||||||
|
import AddSuffixTags from './AddSuffixTags.vue'
|
||||||
|
import { Trash, Airplane } from '@vicons/ionicons5'
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
components: {
|
components: {
|
||||||
NImage, NButton, NInput, NCard, NTabs, NTabPane, NTree, NSplit, AddCharacterTag, AddStyleTags, AddSceneTags, AddPrefixTags, AddSuffixTags, NIcon, Trash
|
NImage,
|
||||||
|
NButton,
|
||||||
|
NInput,
|
||||||
|
NCard,
|
||||||
|
NTabs,
|
||||||
|
NTabPane,
|
||||||
|
NTree,
|
||||||
|
NSplit,
|
||||||
|
AddCharacterTag,
|
||||||
|
AddStyleTags,
|
||||||
|
AddSceneTags,
|
||||||
|
AddPrefixTags,
|
||||||
|
AddSuffixTags,
|
||||||
|
NIcon,
|
||||||
|
Trash,
|
||||||
|
NEmpty,
|
||||||
|
Airplane
|
||||||
},
|
},
|
||||||
props: ["height"],
|
props: ['height'],
|
||||||
setup(props) {
|
setup(props) {
|
||||||
let message = useMessage();
|
let message = useMessage()
|
||||||
let currentCharacter = ref({});
|
let currentCharacter = ref({})
|
||||||
let currentStyle = ref({});
|
let currentStyle = ref({})
|
||||||
let currentScene = ref({});
|
let currentScene = ref({})
|
||||||
let currentPrefix = ref({});
|
let currentPrefix = ref({})
|
||||||
let currentSuffix = ref({});
|
let currentSuffix = ref({})
|
||||||
let currentTags = ref([]);
|
let currentTags = ref([])
|
||||||
let currentType = ref("character");
|
let currentType = ref('default')
|
||||||
let treeData = ref([{
|
|
||||||
|
let lora_options = ref([])
|
||||||
|
|
||||||
|
let treeData = ref([
|
||||||
|
{
|
||||||
label: '人物',
|
label: '人物',
|
||||||
key: uuidv4(),
|
key: uuidv4(),
|
||||||
children: [],
|
children: [],
|
||||||
type: "character",
|
type: 'character',
|
||||||
suffix: () => h(NButton,
|
suffix: () =>
|
||||||
|
h(
|
||||||
|
NButton,
|
||||||
{
|
{
|
||||||
text: true, color: "#e18a3b",
|
text: true,
|
||||||
onClick: (e) => { AddCharacterTags(e) }
|
color: '#e18a3b',
|
||||||
|
onClick: (e) => {
|
||||||
|
AddCharacterTags(e)
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{ default: () => "新加" })
|
{ default: () => '新加' }
|
||||||
|
)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: '场景',
|
label: '场景',
|
||||||
key: uuidv4(),
|
key: uuidv4(),
|
||||||
children: [],
|
children: [],
|
||||||
type: "scene",
|
type: 'scene',
|
||||||
suffix: () => h(NButton,
|
suffix: () =>
|
||||||
|
h(
|
||||||
|
NButton,
|
||||||
{
|
{
|
||||||
text: true, color: "#e18a3b",
|
text: true,
|
||||||
onClick: (e) => { AddSceneTags(e) }
|
color: '#e18a3b',
|
||||||
|
onClick: (e) => {
|
||||||
|
AddSceneTags(e)
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{ default: () => "新加" })
|
{ default: () => '新加' }
|
||||||
|
)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: '风格迁移预设',
|
label: '风格预设',
|
||||||
key: uuidv4(),
|
key: uuidv4(),
|
||||||
children: [],
|
children: [],
|
||||||
type: "style",
|
type: 'style',
|
||||||
suffix: () => h(NButton,
|
suffix: () =>
|
||||||
|
h(
|
||||||
|
NButton,
|
||||||
{
|
{
|
||||||
text: true, color: "#e18a3b",
|
text: true,
|
||||||
onClick: (e) => { AddStyleTags(e) }
|
color: '#e18a3b',
|
||||||
|
onClick: (e) => {
|
||||||
|
AddStyleTags(e)
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{ default: () => "新加" })
|
{ default: () => '新加' }
|
||||||
|
)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: '前缀',
|
label: '前缀',
|
||||||
key: uuidv4(),
|
key: uuidv4(),
|
||||||
children: [],
|
children: [],
|
||||||
type: "prefix",
|
type: 'prefix',
|
||||||
suffix: () => h(NButton,
|
suffix: () =>
|
||||||
|
h(
|
||||||
|
NButton,
|
||||||
{
|
{
|
||||||
text: true, color: "#e18a3b",
|
text: true,
|
||||||
onClick: (e) => { AddPrefixTags(e) }
|
color: '#e18a3b',
|
||||||
|
onClick: (e) => {
|
||||||
|
AddPrefixTags(e)
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{ default: () => "新加" })
|
{ default: () => '新加' }
|
||||||
|
)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: '后缀',
|
label: '后缀',
|
||||||
key: uuidv4(),
|
key: uuidv4(),
|
||||||
children: [],
|
children: [],
|
||||||
type: "suffix",
|
type: 'suffix',
|
||||||
suffix: () => h(NButton,
|
suffix: () =>
|
||||||
|
h(
|
||||||
|
NButton,
|
||||||
{
|
{
|
||||||
text: true, color: "#e18a3b",
|
text: true,
|
||||||
onClick: (e) => { AddSuffixTags(e) }
|
color: '#e18a3b',
|
||||||
},
|
onClick: (e) => {
|
||||||
{ default: () => "新加" })
|
AddSuffixTags(e)
|
||||||
}
|
}
|
||||||
]);
|
},
|
||||||
|
{ default: () => '新加' }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
])
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 初始化标签数据
|
* 初始化标签数据
|
||||||
*/
|
*/
|
||||||
async function InitData() {
|
async function InitData() {
|
||||||
// 获取动态配置里面是不是又标签数(有加载,没有设置默认值)
|
// 获取动态配置里面是不是又标签数(有加载,没有设置默认值)
|
||||||
await window.mj.GetTagDataByTypeAndProperty(["dynamic", null], (value) => {
|
await window.mj.GetTagDataByTypeAndProperty(['dynamic', null], (value) => {
|
||||||
if (value.code == 0) {
|
if (value.code == 0) {
|
||||||
message.error(value.message);
|
message.error(value.message)
|
||||||
return;
|
return
|
||||||
}
|
}
|
||||||
// 判断是不是包含指定的属性
|
// 判断是不是包含指定的属性
|
||||||
if (value.data.hasOwnProperty("character_tags")) {
|
if (value.data.hasOwnProperty('character_tags')) {
|
||||||
treeData.value[0].children = value.data.character_tags;
|
treeData.value[0].children = value.data.character_tags
|
||||||
}
|
}
|
||||||
if (value.data.hasOwnProperty("scene_tags")) {
|
if (value.data.hasOwnProperty('scene_tags')) {
|
||||||
treeData.value[1].children = value.data.scene_tags;
|
treeData.value[1].children = value.data.scene_tags
|
||||||
}
|
}
|
||||||
if (value.data.hasOwnProperty("style_tags")) {
|
if (value.data.hasOwnProperty('style_tags')) {
|
||||||
treeData.value[2].children = value.data.style_tags;
|
treeData.value[2].children = value.data.style_tags
|
||||||
}
|
}
|
||||||
if (value.data.hasOwnProperty("prefix_tags")) {
|
if (value.data.hasOwnProperty('prefix_tags')) {
|
||||||
treeData.value[3].children = value.data.prefix_tags;
|
treeData.value[3].children = value.data.prefix_tags
|
||||||
}
|
}
|
||||||
if (value.data.hasOwnProperty("suffix_tags")) {
|
if (value.data.hasOwnProperty('suffix_tags')) {
|
||||||
treeData.value[4].children = value.data.suffix_tags;
|
treeData.value[4].children = value.data.suffix_tags
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let i = 0; i < treeData.value.length; i++) {
|
for (let i = 0; i < treeData.value.length; i++) {
|
||||||
treeData.value[i].children.map(item => {
|
treeData.value[i].children.map((item) => {
|
||||||
item.suffix = () => h(NButton,
|
item.suffix = () =>
|
||||||
|
h(
|
||||||
|
NButton,
|
||||||
{
|
{
|
||||||
text: true, type: "error", size: "medium",
|
text: true,
|
||||||
onClick: (e) => { DeleteTags(e, item) }
|
type: 'error',
|
||||||
},
|
size: 'medium',
|
||||||
{ default: () => h(NIcon, null, { default: () => h(Trash) }) });
|
onClick: (e) => {
|
||||||
});
|
DeleteTags(e, item)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{ default: () => h(NIcon, null, { default: () => h(Trash) }) }
|
||||||
|
)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
})
|
||||||
|
// 加载lora数据
|
||||||
|
// 获取当前mj配置信息
|
||||||
|
await window.api.GetDefineConfigJsonByProperty(
|
||||||
|
JSON.stringify(['sd_setting', 'lora', false, []]),
|
||||||
|
(value) => {
|
||||||
|
if (value.code == 0) {
|
||||||
|
message.error(value.message)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// 判断是不是有数据
|
||||||
|
if (value.data) {
|
||||||
|
for (let i = 0; i < value.data.length; i++) {
|
||||||
|
const element = value.data[i]
|
||||||
|
lora_options.value.push({
|
||||||
|
label: element.name,
|
||||||
|
value: element.name
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
SetAutoHeight();
|
SetAutoHeight()
|
||||||
await InitData();
|
await InitData()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
// 设置标签集的自动高度,传一个外面的高度进来
|
// 设置标签集的自动高度,传一个外面的高度进来
|
||||||
function SetAutoHeight() {
|
function SetAutoHeight() {
|
||||||
debugger
|
debugger
|
||||||
let div = document.getElementById("tree_define_content");
|
let div = document.getElementById('tree_define_content')
|
||||||
div.style.height = props.height - 180 + "px";
|
div.style.height = props.height - 180 + 'px'
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -173,19 +285,18 @@ export default defineComponent({
|
|||||||
*/
|
*/
|
||||||
async function DeleteTags(e, value) {
|
async function DeleteTags(e, value) {
|
||||||
if (e) {
|
if (e) {
|
||||||
e.stopPropagation();
|
e.stopPropagation()
|
||||||
}
|
}
|
||||||
|
|
||||||
let type = value.type.replace("main", "tags");
|
let type = value.type.replace('main', 'tags')
|
||||||
await window.mj.DeleteTagPropertyData([value.key, type], async (value) => {
|
await window.mj.DeleteTagPropertyData([value.key, type], async (value) => {
|
||||||
if (value.code == 0) {
|
if (value.code == 0) {
|
||||||
message.error(value.message);
|
message.error(value.message)
|
||||||
return;
|
return
|
||||||
}
|
}
|
||||||
message.success(value.message);
|
message.success(value.message)
|
||||||
await InitData();
|
await InitData()
|
||||||
})
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -193,21 +304,24 @@ export default defineComponent({
|
|||||||
*/
|
*/
|
||||||
async function AddCharacterTags(e) {
|
async function AddCharacterTags(e) {
|
||||||
if (e) {
|
if (e) {
|
||||||
e.stopPropagation();
|
e.stopPropagation()
|
||||||
}
|
}
|
||||||
// 初始化值,然后赋值给当前添加人物的组件
|
// 初始化值,然后赋值给当前添加人物的组件
|
||||||
currentCharacter.value = {
|
currentCharacter.value = {
|
||||||
label: null,
|
label: null,
|
||||||
key: uuidv4(),
|
key: uuidv4(),
|
||||||
children: [],
|
children: [],
|
||||||
type: "character_main",
|
type: 'character_main',
|
||||||
|
chinese_prompt: null,
|
||||||
prompt: null,
|
prompt: null,
|
||||||
image_url: null,
|
image_url: null,
|
||||||
|
show_image: window.config.space_image,
|
||||||
cref_cw: 50,
|
cref_cw: 50,
|
||||||
lora: null,
|
lora: '无',
|
||||||
|
lora_weight: 1
|
||||||
}
|
}
|
||||||
currentTags.value = [];
|
currentTags.value = []
|
||||||
currentType.value = "character_main";
|
currentType.value = 'character_main'
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -215,15 +329,15 @@ export default defineComponent({
|
|||||||
*/
|
*/
|
||||||
function AddSceneTags(e) {
|
function AddSceneTags(e) {
|
||||||
if (e) {
|
if (e) {
|
||||||
e.stopPropagation();
|
e.stopPropagation()
|
||||||
}
|
}
|
||||||
currentScene.value = {
|
currentScene.value = {
|
||||||
label: null,
|
label: null,
|
||||||
key: uuidv4(),
|
key: uuidv4(),
|
||||||
type: "scene_main",
|
type: 'scene_main',
|
||||||
prompt: null,
|
prompt: null
|
||||||
}
|
}
|
||||||
currentType.value = "scene_main";
|
currentType.value = 'scene_main'
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -232,15 +346,18 @@ export default defineComponent({
|
|||||||
*/
|
*/
|
||||||
function AddStyleTags(e) {
|
function AddStyleTags(e) {
|
||||||
if (e) {
|
if (e) {
|
||||||
e.stopPropagation();
|
e.stopPropagation()
|
||||||
}
|
}
|
||||||
currentStyle.value = {
|
currentStyle.value = {
|
||||||
label: null,
|
label: null,
|
||||||
key: uuidv4(),
|
key: uuidv4(),
|
||||||
type: "style_main",
|
type: 'style_main',
|
||||||
|
show_image: window.config.space_image,
|
||||||
prompt: null,
|
prompt: null,
|
||||||
image_url: null,
|
image_url: null,
|
||||||
sref_cw: 50,
|
sref_sw: 50,
|
||||||
|
lora: '无',
|
||||||
|
lora_weight: 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -249,13 +366,13 @@ export default defineComponent({
|
|||||||
*/
|
*/
|
||||||
function AddPrefixTags(e) {
|
function AddPrefixTags(e) {
|
||||||
if (e) {
|
if (e) {
|
||||||
e.stopPropagation();
|
e.stopPropagation()
|
||||||
}
|
}
|
||||||
currentPrefix.value = {
|
currentPrefix.value = {
|
||||||
label: null,
|
label: null,
|
||||||
key: uuidv4(),
|
key: uuidv4(),
|
||||||
type: "prefix_main",
|
type: 'prefix_main',
|
||||||
prompt: null,
|
prompt: null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -265,73 +382,69 @@ export default defineComponent({
|
|||||||
*/
|
*/
|
||||||
function AddSuffixTags(e) {
|
function AddSuffixTags(e) {
|
||||||
if (e) {
|
if (e) {
|
||||||
e.stopPropagation();
|
e.stopPropagation()
|
||||||
}
|
}
|
||||||
currentSuffix.value = {
|
currentSuffix.value = {
|
||||||
label: null,
|
label: null,
|
||||||
key: uuidv4(),
|
key: uuidv4(),
|
||||||
type: "suffix_main",
|
type: 'suffix_main',
|
||||||
prompt: null,
|
prompt: null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function nodeProps({ option }) {
|
function nodeProps({ option }) {
|
||||||
return {
|
return {
|
||||||
onClick() {
|
onClick() {
|
||||||
debugger;
|
debugger
|
||||||
// 执行切换组件和数据
|
// 执行切换组件和数据
|
||||||
if (option.type == "style") {
|
if (option.type == 'style') {
|
||||||
currentType.value = "style";
|
currentType.value = 'style'
|
||||||
AddStyleTags(null);
|
AddStyleTags(null)
|
||||||
return;
|
return
|
||||||
} else if (option.type == "scene") {
|
} else if (option.type == 'scene') {
|
||||||
AddSceneTags(null);
|
AddSceneTags(null)
|
||||||
currentType.value = "scene";
|
currentType.value = 'scene'
|
||||||
// message.error("主节点不允许操作");
|
// message.error("主节点不允许操作");
|
||||||
return;
|
return
|
||||||
} else if (option.type == "character") {
|
} else if (option.type == 'character') {
|
||||||
AddCharacterTags(null);
|
AddCharacterTags(null)
|
||||||
currentType.value = "character";
|
currentType.value = 'character'
|
||||||
return;
|
return
|
||||||
} else if (option.type == "prefix") {
|
} else if (option.type == 'prefix') {
|
||||||
AddPrefixTags(null);
|
AddPrefixTags(null)
|
||||||
currentType.value = "prefix";
|
currentType.value = 'prefix'
|
||||||
return;
|
return
|
||||||
} else if (option.type == "suffix") {
|
} else if (option.type == 'suffix') {
|
||||||
AddSuffixTags(null);
|
AddSuffixTags(null)
|
||||||
currentType.value = "suffix";
|
currentType.value = 'suffix'
|
||||||
return;
|
return
|
||||||
}
|
} else if (option.type == 'min') {
|
||||||
else if (option.type == "min") {
|
message.error('别名节点不允许操作')
|
||||||
message.error("别名节点不允许操作");
|
|
||||||
} else {
|
} else {
|
||||||
debugger
|
debugger
|
||||||
console.log(option);
|
console.log(option)
|
||||||
currentType.value = option.type;
|
currentType.value = option.type
|
||||||
// 修改当前属性
|
// 修改当前属性
|
||||||
if (currentType.value.startsWith("character")) {
|
if (currentType.value.startsWith('character')) {
|
||||||
// 修改tags的值
|
// 修改tags的值
|
||||||
currentCharacter.value = option;
|
currentCharacter.value = option
|
||||||
currentTags.value = option.children.map((item) => {
|
currentTags.value = option.children.map((item) => {
|
||||||
return item.label;
|
return item.label
|
||||||
})
|
})
|
||||||
} else if (currentType.value.startsWith("scene")) {
|
} else if (currentType.value.startsWith('scene')) {
|
||||||
currentScene.value = option;
|
currentScene.value = option
|
||||||
}
|
} else if (currentType.value.startsWith('style')) {
|
||||||
else if (currentType.value.startsWith("style")) {
|
currentStyle.value = option
|
||||||
currentStyle.value = option;
|
} else if (currentType.value.startsWith('prefix')) {
|
||||||
} else if (currentType.value.startsWith("prefix")) {
|
currentPrefix.value = option
|
||||||
currentPrefix.value = option;
|
} else if (currentType.value.startsWith('suffix')) {
|
||||||
} else if (currentType.value.startsWith("suffix")) {
|
currentSuffix.value = option
|
||||||
currentSuffix.value = option;
|
} else {
|
||||||
}
|
message.error('未知的类型')
|
||||||
else {
|
|
||||||
message.error("未知的类型");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@ -347,7 +460,8 @@ export default defineComponent({
|
|||||||
currentStyle,
|
currentStyle,
|
||||||
currentScene,
|
currentScene,
|
||||||
currentPrefix,
|
currentPrefix,
|
||||||
currentSuffix
|
currentSuffix,
|
||||||
|
lora_options
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div v-if="type == 'title'" style="display: flex">
|
<div v-if="type == 'title'" style="display: flex">
|
||||||
<span style="margin-right: 5px">参数</span>
|
<span style="margin-right: 5px">人物/场景</span>
|
||||||
<n-select
|
<n-select
|
||||||
style="width: 75px"
|
style="width: 75px"
|
||||||
size="tiny"
|
size="tiny"
|
||||||
@ -56,6 +56,7 @@
|
|||||||
filterable
|
filterable
|
||||||
:options="character_tags"
|
:options="character_tags"
|
||||||
placeholder="选择人物"
|
placeholder="选择人物"
|
||||||
|
@update:value="UpdateCharacterSelect"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div style="margin-top: 3px">
|
<div style="margin-top: 3px">
|
||||||
@ -69,6 +70,7 @@
|
|||||||
filterable
|
filterable
|
||||||
:options="scene_tags"
|
:options="scene_tags"
|
||||||
placeholder="选择场景"
|
placeholder="选择场景"
|
||||||
|
@update:value="UpdateSceneSelect"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -236,8 +238,12 @@ export default defineComponent({
|
|||||||
character_tags.value[index].checked = true
|
character_tags.value[index].checked = true
|
||||||
// 将当前选中的数据生成到select_character_tags中
|
// 将当前选中的数据生成到select_character_tags中
|
||||||
select_character_tags.value.push(character_tags.value[index].key)
|
select_character_tags.value.push(character_tags.value[index].key)
|
||||||
|
} else {
|
||||||
|
// 不存在 移除
|
||||||
|
row.value.character_tags.splice(i, 1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let i = 0; row.value.scene_tags && i < row.value.scene_tags.length; i++) {
|
for (let i = 0; row.value.scene_tags && i < row.value.scene_tags.length; i++) {
|
||||||
const element = row.value.scene_tags[i]
|
const element = row.value.scene_tags[i]
|
||||||
let index = scene_tags.value.findIndex((tag) => tag.key == element.key)
|
let index = scene_tags.value.findIndex((tag) => tag.key == element.key)
|
||||||
@ -245,6 +251,9 @@ export default defineComponent({
|
|||||||
scene_tags.value[index].checked = true
|
scene_tags.value[index].checked = true
|
||||||
// 将当前选中的数据生成到select_scene_tags中
|
// 将当前选中的数据生成到select_scene_tags中
|
||||||
select_scene_tags.value.push(scene_tags.value[index].key)
|
select_scene_tags.value.push(scene_tags.value[index].key)
|
||||||
|
} else {
|
||||||
|
// 不存在 移除
|
||||||
|
row.value.scene_tags.splice(i, 1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -265,6 +274,36 @@ export default defineComponent({
|
|||||||
props.func.refreshTagData()
|
props.func.refreshTagData()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新人物选择,修改对应的tag
|
||||||
|
*/
|
||||||
|
function UpdateCharacterSelect(value, option) {
|
||||||
|
console.log('人物更新下拉框', value, option)
|
||||||
|
// 先将之前row中的数据全部移除
|
||||||
|
row.value.character_tags = []
|
||||||
|
// 将当前选中的option修改checked为true,并将数据添加到row中
|
||||||
|
for (let i = 0; i < option.length; i++) {
|
||||||
|
const element = option[i]
|
||||||
|
element.checked = true
|
||||||
|
row.value.character_tags.push(element)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新场景时,显示的数据
|
||||||
|
*/
|
||||||
|
function UpdateSceneSelect(value, option) {
|
||||||
|
console.log('场景更新下拉框', value, option)
|
||||||
|
// 先将之前row中的数据全部移除
|
||||||
|
row.value.scene_tags = []
|
||||||
|
// 将当前选中的option修改checked为true,并将数据添加到row中
|
||||||
|
for (let i = 0; i < option.length; i++) {
|
||||||
|
const element = option[i]
|
||||||
|
element.checked = true
|
||||||
|
row.value.scene_tags.push(element)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
characterData,
|
characterData,
|
||||||
row,
|
row,
|
||||||
@ -280,7 +319,9 @@ export default defineComponent({
|
|||||||
InitCharacterAndSceneData,
|
InitCharacterAndSceneData,
|
||||||
UpdateImageGenerateCategory,
|
UpdateImageGenerateCategory,
|
||||||
title_character_select_model,
|
title_character_select_model,
|
||||||
RefreshTagData
|
RefreshTagData,
|
||||||
|
UpdateCharacterSelect,
|
||||||
|
UpdateSceneSelect
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@ -4,18 +4,18 @@
|
|||||||
<n-popover trigger="hover">
|
<n-popover trigger="hover">
|
||||||
<template #trigger>
|
<template #trigger>
|
||||||
<n-button color="#7c461e" style="margin-left: 5px" size="tiny" @click="AddPrefix"
|
<n-button color="#7c461e" style="margin-left: 5px" size="tiny" @click="AddPrefix"
|
||||||
>添加前缀</n-button
|
>通用前缀</n-button
|
||||||
>
|
>
|
||||||
</template>
|
</template>
|
||||||
<span>添加前缀,只能添加英文,并且通用前缀不为空,推理会自动添加前缀</span>
|
<span>添加通用前缀,只能添加英文,并且通用前缀不为空,推理会自动添加前缀</span>
|
||||||
</n-popover>
|
</n-popover>
|
||||||
<n-popover trigger="hover">
|
<n-popover trigger="hover">
|
||||||
<template #trigger>
|
<template #trigger>
|
||||||
<n-button color="#e18a3b" style="margin-left: 5px" size="tiny" @click="AddSuffix"
|
<n-button color="#e18a3b" style="margin-left: 5px" size="tiny" @click="AddSuffix"
|
||||||
>添加后缀</n-button
|
>通用后缀</n-button
|
||||||
>
|
>
|
||||||
</template>
|
</template>
|
||||||
<span>添加后缀,只能添加英文,并且通用后缀不为空,推理会自动添加后缀</span>
|
<span>添加通用后缀,只能添加英文,并且通用后缀不为空,推理会自动添加后缀</span>
|
||||||
</n-popover>
|
</n-popover>
|
||||||
<n-popover trigger="hover">
|
<n-popover trigger="hover">
|
||||||
<template #trigger>
|
<template #trigger>
|
||||||
@ -77,10 +77,6 @@
|
|||||||
<script>
|
<script>
|
||||||
import { ref, h, onMounted, defineComponent, toRaw, watch } from 'vue'
|
import { ref, h, onMounted, defineComponent, toRaw, watch } from 'vue'
|
||||||
import { NButton, NDropdown, NInput, NPopover, useMessage } from 'naive-ui'
|
import { NButton, NDropdown, NInput, NPopover, useMessage } from 'naive-ui'
|
||||||
import { DEFINE_STRING } from '../../../../../define/define_string'
|
|
||||||
import { v4 as uuidv4 } from 'uuid'
|
|
||||||
import { cloneDeep } from 'lodash'
|
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
components: {
|
components: {
|
||||||
NButton,
|
NButton,
|
||||||
@ -192,7 +188,6 @@ export default defineComponent({
|
|||||||
*/
|
*/
|
||||||
async function SinglePrompt() {
|
async function SinglePrompt() {
|
||||||
await props.func.singlePrompt(row.value)
|
await props.func.singlePrompt(row.value)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -1,37 +1,23 @@
|
|||||||
<template>
|
<template>
|
||||||
<div v-if="type == 'title'">
|
<div v-if="type == 'title'">
|
||||||
<span style="margin-right: 5px">提示词命令</span>
|
<span style="margin-right: 5px">提示词命令</span>
|
||||||
|
<n-dropdown trigger="hover" :options="MergePromptOptions" @select="MergePromptSelect">
|
||||||
<n-button size="tiny" @click="MergePrompt" color="#7c461e">合并命令</n-button>
|
<n-button size="tiny" @click="MergePrompt" color="#7c461e">合并命令</n-button>
|
||||||
<n-button
|
</n-dropdown>
|
||||||
color="#e18a3b"
|
<n-button color="#e18a3b" size="tiny" style="margin-left: 5px" @click="MJBadPromptCheck"
|
||||||
size="tiny"
|
|
||||||
style="margin-left: 5px"
|
|
||||||
@click="MJBadPromptCheck"
|
|
||||||
>敏感词检查</n-button
|
>敏感词检查</n-button
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
<div v-else-if="type == 'data'">
|
<div v-else-if="type == 'data'">
|
||||||
<n-button
|
<n-button size="tiny" color="#dd7694" style="margin-right: 5px" @click="SingleGenerateImage"
|
||||||
size="tiny"
|
|
||||||
color="#dd7694"
|
|
||||||
style="margin-right: 5px"
|
|
||||||
@click="SingleGenerateImage"
|
|
||||||
>单句生图</n-button
|
>单句生图</n-button
|
||||||
>
|
>
|
||||||
<n-button
|
<n-button size="tiny" color="#a76283" style="margin-right: 5px" @click="NextGenerateImage"
|
||||||
size="tiny"
|
|
||||||
color="#a76283"
|
|
||||||
style="margin-right: 5px"
|
|
||||||
@click="NextGenerateImage"
|
|
||||||
>下生图</n-button
|
>下生图</n-button
|
||||||
>
|
>
|
||||||
<n-popover trigger="hover">
|
<n-popover trigger="hover">
|
||||||
<template #trigger>
|
<template #trigger>
|
||||||
<n-button
|
<n-button color="#a46244" style="margin-right: 5px" size="tiny" @click="ImportMJImageUrl"
|
||||||
color="#a46244"
|
|
||||||
style="margin-right: 5px"
|
|
||||||
size="tiny"
|
|
||||||
@click="ImportMJImageUrl"
|
|
||||||
>导入图片</n-button
|
>导入图片</n-button
|
||||||
>
|
>
|
||||||
</template>
|
</template>
|
||||||
@ -40,7 +26,6 @@
|
|||||||
|
|
||||||
<n-input
|
<n-input
|
||||||
:status="input_status"
|
:status="input_status"
|
||||||
readonly
|
|
||||||
size="tiny"
|
size="tiny"
|
||||||
placeholder="请生成出图命令或是提示词"
|
placeholder="请生成出图命令或是提示词"
|
||||||
type="textarea"
|
type="textarea"
|
||||||
@ -51,25 +36,26 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { ref, h, onMounted, defineComponent, toRaw, watch } from "vue";
|
import { ref, h, onMounted, defineComponent, toRaw, watch } from 'vue'
|
||||||
import { NButton, NInput, NPopover, useMessage, useDialog } from "naive-ui";
|
import { NButton, NInput, NPopover, useMessage, useDialog, NDropdown } from 'naive-ui'
|
||||||
import { DEFINE_STRING } from "../../../../../define/define_string";
|
import { DEFINE_STRING } from '../../../../../define/define_string'
|
||||||
import InputDialogContent from "./InputDialogContent.vue";
|
import InputDialogContent from './InputDialogContent.vue'
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
components: {
|
components: {
|
||||||
NButton,
|
NButton,
|
||||||
NInput,
|
NInput,
|
||||||
NPopover,
|
NPopover,
|
||||||
|
NDropdown
|
||||||
},
|
},
|
||||||
props: ["type", "row", "index", "func"],
|
props: ['type', 'row', 'index', 'func'],
|
||||||
setup(props) {
|
setup(props) {
|
||||||
let message = useMessage();
|
let message = useMessage()
|
||||||
let dialog = useDialog();
|
let dialog = useDialog()
|
||||||
let type = ref(props.type);
|
let type = ref(props.type)
|
||||||
let row = ref(props.row);
|
let row = ref(props.row)
|
||||||
let input_status = ref("default");
|
let input_status = ref('default')
|
||||||
let image_url_ref = ref(null);
|
let image_url_ref = ref(null)
|
||||||
|
|
||||||
// let input_image_
|
// let input_image_
|
||||||
|
|
||||||
@ -79,63 +65,62 @@ export default defineComponent({
|
|||||||
watch(
|
watch(
|
||||||
() => props.row,
|
() => props.row,
|
||||||
(newVal) => {
|
(newVal) => {
|
||||||
row.value = newVal;
|
row.value = newVal
|
||||||
},
|
},
|
||||||
{ deep: true }
|
{ deep: true }
|
||||||
);
|
)
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => props.row.mj_message,
|
() => props.row.mj_message,
|
||||||
(newVal) => {
|
(newVal) => {
|
||||||
if (newVal && newVal["hasBadPrompt"]) {
|
if (newVal && newVal['hasBadPrompt']) {
|
||||||
input_status.value = "error";
|
input_status.value = 'error'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{ deep: true }
|
{ deep: true }
|
||||||
);
|
)
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
if (row.value["mj_message"]?.hasBadPrompt) {
|
if (row.value['mj_message']?.hasBadPrompt) {
|
||||||
input_status.value = "error";
|
input_status.value = 'error'
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SD单句生图
|
* SD单句生图
|
||||||
* @param {*} row 要生图的行数据
|
* @param {*} row 要生图的行数据
|
||||||
*/
|
*/
|
||||||
async function SingleGenerateImage() {
|
async function SingleGenerateImage() {
|
||||||
debugger;
|
let ca = window.config.image_generate_category ? window.config.image_generate_category : 'sd'
|
||||||
let ca = window.config.image_generate_category;
|
|
||||||
// 判断当前的生图模式
|
// 判断当前的生图模式
|
||||||
if (ca == "sd") {
|
if (ca == 'sd') {
|
||||||
// 生成SD生图
|
// 生成SD生图
|
||||||
await window.api.OriginalSDImageGenerate(
|
await window.api.OriginalSDImageGenerate(
|
||||||
[JSON.stringify([toRaw(row.value)]), true, false],
|
[JSON.stringify([toRaw(row.value)]), true, false],
|
||||||
(value) => {
|
(value) => {
|
||||||
if (value.code == 0) {
|
if (value.code == 0) {
|
||||||
message.error(value.message);
|
message.error(value.message)
|
||||||
return;
|
return
|
||||||
}
|
}
|
||||||
message.success("添加SD生图任务成功");
|
message.success('添加SD生图任务成功')
|
||||||
}
|
}
|
||||||
);
|
)
|
||||||
} else if (ca == "mj") {
|
} else if (ca == 'mj') {
|
||||||
// MJ生图
|
// MJ生图
|
||||||
await window.mj.OriginalMJImageGenerate(
|
await window.mj.OriginalMJImageGenerate(
|
||||||
[JSON.stringify([toRaw(row.value)]), true, false],
|
[JSON.stringify([toRaw(row.value)]), true, false],
|
||||||
(value) => {
|
(value) => {
|
||||||
if (value.code == 0) {
|
if (value.code == 0) {
|
||||||
message.error(value.message);
|
message.error(value.message)
|
||||||
return;
|
return
|
||||||
}
|
}
|
||||||
message.success("添加MJ生图任务成功");
|
message.success('添加MJ生图任务成功')
|
||||||
}
|
}
|
||||||
);
|
)
|
||||||
} else if (ca == "d3") {
|
} else if (ca == 'd3') {
|
||||||
// D3 生图
|
// D3 生图
|
||||||
} else {
|
} else {
|
||||||
message.error("生图的类别错误");
|
message.error('生图的类别错误')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -143,21 +128,22 @@ export default defineComponent({
|
|||||||
* 下生图
|
* 下生图
|
||||||
*/
|
*/
|
||||||
async function NextGenerateImage() {
|
async function NextGenerateImage() {
|
||||||
props.func.nextGenerateImage(row.value, window.config.image_generate_category);
|
let ca = window.config.image_generate_category ? window.config.image_generate_category : 'sd'
|
||||||
|
props.func.nextGenerateImage(row.value, ca)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* MJ敏感词检测
|
* MJ敏感词检测
|
||||||
*/
|
*/
|
||||||
async function MJBadPromptCheck() {
|
async function MJBadPromptCheck() {
|
||||||
props.func.mJBadPromptCheck();
|
props.func.mJBadPromptCheck()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 合并提示词
|
* 合并提示词
|
||||||
*/
|
*/
|
||||||
async function MergePrompt() {
|
async function MergePrompt() {
|
||||||
props.func.mergePrompt();
|
props.func.mergePrompt(null)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -166,43 +152,51 @@ export default defineComponent({
|
|||||||
async function ImportMJImageUrl() {
|
async function ImportMJImageUrl() {
|
||||||
// 判断当前数据是不是存在
|
// 判断当前数据是不是存在
|
||||||
// 处理数据。获取当前的所有的数据
|
// 处理数据。获取当前的所有的数据
|
||||||
let dialogWidth = 400;
|
let dialogWidth = 400
|
||||||
let dialogHeight = 150;
|
let dialogHeight = 150
|
||||||
dialog.create({
|
dialog.create({
|
||||||
title: "添加图片链接",
|
title: '添加图片链接',
|
||||||
showIcon: false,
|
showIcon: false,
|
||||||
closeOnEsc: false,
|
closeOnEsc: false,
|
||||||
content: () =>
|
content: () =>
|
||||||
h(InputDialogContent, {
|
h(InputDialogContent, {
|
||||||
ref: image_url_ref,
|
ref: image_url_ref,
|
||||||
initData: null,
|
initData: null,
|
||||||
placeholder: "请输入图片链接",
|
placeholder: '请输入图片链接'
|
||||||
}),
|
}),
|
||||||
style: `width : ${dialogWidth}px; min-height : ${dialogHeight}px`,
|
style: `width : ${dialogWidth}px; min-height : ${dialogHeight}px`,
|
||||||
maskClosable: false,
|
maskClosable: false,
|
||||||
onClose: async () => {
|
onClose: async () => {
|
||||||
debugger;
|
debugger
|
||||||
let row_image_url = image_url_ref.value.data;
|
let row_image_url = image_url_ref.value.data
|
||||||
|
|
||||||
// 下载指定的图片地址并且分割
|
// 下载指定的图片地址并且分割
|
||||||
await window.mj.DownloadImageUrlAndSplit(
|
await window.mj.DownloadImageUrlAndSplit(
|
||||||
JSON.stringify([toRaw(row.value), row_image_url]),
|
JSON.stringify([toRaw(row.value), row_image_url]),
|
||||||
(value) => {
|
(value) => {
|
||||||
if (value.code == 0) {
|
if (value.code == 0) {
|
||||||
message.error(value.message);
|
message.error(value.message)
|
||||||
return;
|
return
|
||||||
}
|
}
|
||||||
// 更新当前的数据
|
// 更新当前的数据
|
||||||
row.value.outImagePath = value.data.outImagePath;
|
row.value.outImagePath = value.data.outImagePath
|
||||||
row.value.subImagePath = value.data.subImagePath;
|
row.value.subImagePath = value.data.subImagePath
|
||||||
row.value.mj_message = value.data.mj_message ? value.data.mj_message : {};
|
row.value.mj_message = value.data.mj_message ? value.data.mj_message : {}
|
||||||
row.value.mj_message.image_click = value.data.image_click;
|
row.value.mj_message.image_click = value.data.image_click
|
||||||
row.value.mj_message.image_path = value.data.image_path;
|
row.value.mj_message.image_path = value.data.image_path
|
||||||
row.value.mj_message.progress = 100;
|
row.value.mj_message.progress = 100
|
||||||
}
|
}
|
||||||
);
|
)
|
||||||
},
|
}
|
||||||
});
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 点击合并下拉框实现功能的方式
|
||||||
|
* @param key
|
||||||
|
*/
|
||||||
|
async function MergePromptSelect(key) {
|
||||||
|
props.func.mergePrompt(key)
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@ -215,7 +209,12 @@ export default defineComponent({
|
|||||||
MergePrompt,
|
MergePrompt,
|
||||||
ImportMJImageUrl,
|
ImportMJImageUrl,
|
||||||
image_url_ref,
|
image_url_ref,
|
||||||
};
|
MergePromptSelect,
|
||||||
},
|
MergePromptOptions: [
|
||||||
});
|
{ label: 'SD模式合并', key: 'sd_merge' },
|
||||||
|
{ label: 'MJ模式合并', key: 'mj_merge' }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -32,8 +32,7 @@
|
|||||||
v-if="outImagePath"
|
v-if="outImagePath"
|
||||||
:src="outImagePath"
|
:src="outImagePath"
|
||||||
fit="cover"
|
fit="cover"
|
||||||
width="120px"
|
style="width: 120px; height: 120px"
|
||||||
height="120px"
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
|
|||||||
@ -1,11 +1,71 @@
|
|||||||
<template>
|
<template>
|
||||||
<div style="margin-top: 30px">
|
<div style="margin-top: 30px">
|
||||||
|
<div style="display: flex; align-items: center">
|
||||||
|
<n-button color="#b6a014" size="small" @click="formateWrite">一键格式化</n-button>
|
||||||
|
<n-popover trigger="hover">
|
||||||
|
<template #trigger>
|
||||||
|
<n-button quaternary circle size="tiny" color="#b6a014" @click="AddSplitChar">
|
||||||
|
<template #icon>
|
||||||
|
<n-icon size="25"> <AddCircleOutline /> </n-icon>
|
||||||
|
</template>
|
||||||
|
</n-button>
|
||||||
|
</template>
|
||||||
|
<span>添加分割标识符</span>
|
||||||
|
</n-popover>
|
||||||
|
|
||||||
|
<n-popover trigger="hover">
|
||||||
|
<template #trigger>
|
||||||
|
<n-input-number
|
||||||
|
style="margin-left: 10px; width: 130px"
|
||||||
|
size="small"
|
||||||
|
placeholder="输入合并的行数"
|
||||||
|
:max="10000"
|
||||||
|
:min="1"
|
||||||
|
@update:value="mergeCountChange"
|
||||||
|
:show-button="false"
|
||||||
|
v-model:value="write_setting.merge_count"
|
||||||
|
></n-input-number>
|
||||||
|
</template>
|
||||||
|
<span>设置将多少行进行合并</span>
|
||||||
|
</n-popover>
|
||||||
|
<n-popover trigger="hover">
|
||||||
|
<template #trigger>
|
||||||
<n-input
|
<n-input
|
||||||
|
style="margin-left: 10px; width: 80px"
|
||||||
|
size="small"
|
||||||
|
placeholder="输入中间拼接的字符"
|
||||||
|
@update:value="mergeCountChange"
|
||||||
|
:show-button="false"
|
||||||
|
v-model:value="write_setting.merge_char"
|
||||||
|
></n-input>
|
||||||
|
</template>
|
||||||
|
<span>设置中间拼接的字符</span>
|
||||||
|
</n-popover>
|
||||||
|
<n-popover trigger="hover">
|
||||||
|
<template #trigger>
|
||||||
|
<n-input
|
||||||
|
style="margin-left: 10px; width: 80px"
|
||||||
|
size="small"
|
||||||
|
placeholder="输入结尾拼接的字符"
|
||||||
|
@update:value="mergeCountChange"
|
||||||
|
:show-button="false"
|
||||||
|
v-model:value="write_setting.end_char"
|
||||||
|
></n-input>
|
||||||
|
</template>
|
||||||
|
<span>设置结尾拼接的字符</span>
|
||||||
|
</n-popover>
|
||||||
|
|
||||||
|
<n-button color="#80a492" size="small" style="margin-left: 10px" @click="mergeWord"
|
||||||
|
>合并</n-button
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
<n-input
|
||||||
|
style="margin-top: 5px"
|
||||||
v-model:value="word"
|
v-model:value="word"
|
||||||
:autosize="{ minRows: 30, maxRows: 30 }"
|
:autosize="{ minRows: 30, maxRows: 30 }"
|
||||||
type="textarea"
|
type="textarea"
|
||||||
placeholder="输入分镜文案"
|
placeholder="输入分镜文案"
|
||||||
@input="ChangeWordInput"
|
@update:value="ChangeWordInput"
|
||||||
/>
|
/>
|
||||||
<div style="margin-top: 5px; display: flex">
|
<div style="margin-top: 5px; display: flex">
|
||||||
<div style="flex: 1">共 {{ rowCount }} 行分镜(当前数量不是最后数量,最后会删除空行)</div>
|
<div style="flex: 1">共 {{ rowCount }} 行分镜(当前数量不是最后数量,最后会删除空行)</div>
|
||||||
@ -15,26 +75,49 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { ref, h, onMounted, defineComponent, toRaw } from 'vue'
|
import { ref, h, onMounted, defineComponent, toRaw } from 'vue'
|
||||||
import { NImage, useMessage, NButton, useDialog, NInput } from 'naive-ui'
|
import {
|
||||||
|
NImage,
|
||||||
|
useMessage,
|
||||||
|
NButton,
|
||||||
|
useDialog,
|
||||||
|
NInput,
|
||||||
|
NIcon,
|
||||||
|
NPopover,
|
||||||
|
NInputNumber
|
||||||
|
} from 'naive-ui'
|
||||||
import { DEFINE_STRING } from '../../../../../define/define_string'
|
import { DEFINE_STRING } from '../../../../../define/define_string'
|
||||||
|
import { AddCircleOutline } from '@vicons/ionicons5'
|
||||||
|
import InputDialogContent from './InputDialogContent.vue'
|
||||||
|
import { max } from 'lodash'
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
components: {
|
components: {
|
||||||
NImage,
|
NImage,
|
||||||
NButton,
|
NButton,
|
||||||
NInput
|
NInput,
|
||||||
|
NInputNumber,
|
||||||
|
NIcon,
|
||||||
|
AddCircleOutline,
|
||||||
|
NPopover
|
||||||
},
|
},
|
||||||
props: ['initData'],
|
props: ['initData'],
|
||||||
setup(props) {
|
setup(props) {
|
||||||
let message = useMessage()
|
let message = useMessage()
|
||||||
|
let dialog = useDialog()
|
||||||
let rowCount = ref(0)
|
let rowCount = ref(0)
|
||||||
let data = ref(props.initData)
|
let data = ref(props.initData)
|
||||||
let word = ref(null)
|
let word = ref(null)
|
||||||
let word_arr = ref([])
|
let word_arr = ref([])
|
||||||
|
let split_ref = ref(null)
|
||||||
|
|
||||||
|
let write_setting = ref({
|
||||||
|
split_char: '。,“”‘’!?【】《》()…—:;.,\'\'""!?[]<>()...-:;',
|
||||||
|
merge_count: 3,
|
||||||
|
merge_char: ',',
|
||||||
|
end_char: '。'
|
||||||
|
})
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
debugger
|
|
||||||
console.log(data)
|
|
||||||
// 拼接word
|
// 拼接word
|
||||||
let tmp_arr = []
|
let tmp_arr = []
|
||||||
for (let i = 0; i < data.value.length; i++) {
|
for (let i = 0; i < data.value.length; i++) {
|
||||||
@ -43,6 +126,20 @@ export default defineComponent({
|
|||||||
}
|
}
|
||||||
word.value = tmp_arr.join('\n')
|
word.value = tmp_arr.join('\n')
|
||||||
ChangeWordInput()
|
ChangeWordInput()
|
||||||
|
|
||||||
|
// 加载初始配置数据
|
||||||
|
await window.api.GetDefineConfigJsonByProperty(
|
||||||
|
JSON.stringify(['clip_setting', 'write_setting', false, null]),
|
||||||
|
(value) => {
|
||||||
|
if (value.code == 0) {
|
||||||
|
message.error(value.message)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (value.data) {
|
||||||
|
write_setting.value = value.data
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -58,12 +155,137 @@ export default defineComponent({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加分割符号
|
||||||
|
*/
|
||||||
|
async function AddSplitChar() {
|
||||||
|
// 判断当前数据是不是存在
|
||||||
|
// 处理数据。获取当前的所有的数据
|
||||||
|
let dialogWidth = 400
|
||||||
|
let dialogHeight = 150
|
||||||
|
dialog.create({
|
||||||
|
title: '添加分割符',
|
||||||
|
showIcon: false,
|
||||||
|
closeOnEsc: false,
|
||||||
|
content: () =>
|
||||||
|
h(InputDialogContent, {
|
||||||
|
ref: split_ref,
|
||||||
|
initData: write_setting.value.split_char,
|
||||||
|
placeholder: '请输入分割符'
|
||||||
|
}),
|
||||||
|
style: `width : ${dialogWidth}px; min-height : ${dialogHeight}px`,
|
||||||
|
maskClosable: false,
|
||||||
|
onClose: async () => {
|
||||||
|
debugger
|
||||||
|
write_setting.value.split_char = split_ref.value.data
|
||||||
|
// 保存数据
|
||||||
|
await window.api.SaveDefineConfigJsonByProperty(
|
||||||
|
JSON.stringify(['clip_setting', 'write_setting', toRaw(write_setting.value), false]),
|
||||||
|
(value) => {
|
||||||
|
debugger
|
||||||
|
console.log(value)
|
||||||
|
if (value.code == 0) {
|
||||||
|
message.error(value.message)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
message.success(value.message)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新input-number事件
|
||||||
|
*/
|
||||||
|
let timer = null
|
||||||
|
async function mergeCountChange(value) {
|
||||||
|
// 添加一个防抖函数,防止修改次数太多导致卡顿
|
||||||
|
clearTimeout(timer)
|
||||||
|
timer = setTimeout(async () => {
|
||||||
|
// 执行你的逻辑代码
|
||||||
|
//
|
||||||
|
await window.api.SaveDefineConfigJsonByProperty(
|
||||||
|
JSON.stringify(['clip_setting', 'write_setting', toRaw(write_setting.value), false]),
|
||||||
|
(value) => {
|
||||||
|
debugger
|
||||||
|
console.log(value)
|
||||||
|
if (value.code == 0) {
|
||||||
|
message.error(value.message)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
message.success(value.message)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}, 500)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 一键格式化
|
||||||
|
*/
|
||||||
|
async function formateWrite() {
|
||||||
|
debugger
|
||||||
|
let split_arr = Array.from(write_setting.value.split_char)
|
||||||
|
split_arr.forEach((item) => {
|
||||||
|
let specialCharacters = [
|
||||||
|
'.',
|
||||||
|
'*',
|
||||||
|
'?',
|
||||||
|
'+',
|
||||||
|
'^',
|
||||||
|
'$',
|
||||||
|
'[',
|
||||||
|
']',
|
||||||
|
'(',
|
||||||
|
')',
|
||||||
|
'{',
|
||||||
|
'}',
|
||||||
|
'|',
|
||||||
|
'\\'
|
||||||
|
]
|
||||||
|
let regex
|
||||||
|
|
||||||
|
if (specialCharacters.includes(item)) {
|
||||||
|
regex = new RegExp('\\' + item, 'g')
|
||||||
|
} else {
|
||||||
|
regex = new RegExp(item, 'g')
|
||||||
|
}
|
||||||
|
word.value = word.value.replace(regex, '\n')
|
||||||
|
})
|
||||||
|
// 删除空行
|
||||||
|
let word_arr = word.value.split('\n')
|
||||||
|
word_arr = word_arr.filter((item) => item != '' && item != null)
|
||||||
|
word.value = word_arr.join('\n')
|
||||||
|
ChangeWordInput()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 合并数据
|
||||||
|
*/
|
||||||
|
async function mergeWord() {
|
||||||
|
let step = write_setting.value.merge_count ? write_setting.value.merge_count : 3
|
||||||
|
let tmp_arr = []
|
||||||
|
let word_arr = word.value.split('\n')
|
||||||
|
for (let i = 0; i < word_arr.length; i += step) {
|
||||||
|
let group = word_arr.slice(i, i + step)
|
||||||
|
tmp_arr.push(group.join(write_setting.value.merge_char) + write_setting.value.end_char)
|
||||||
|
}
|
||||||
|
word.value = tmp_arr.join('\n')
|
||||||
|
ChangeWordInput()
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
data,
|
data,
|
||||||
rowCount,
|
rowCount,
|
||||||
ChangeWordInput,
|
ChangeWordInput,
|
||||||
word,
|
word,
|
||||||
word_arr
|
word_arr,
|
||||||
|
AddSplitChar,
|
||||||
|
split_ref,
|
||||||
|
write_setting,
|
||||||
|
mergeCountChange,
|
||||||
|
formateWrite,
|
||||||
|
mergeWord
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@ -506,11 +506,8 @@ export default defineComponent({
|
|||||||
positiveText: '保存',
|
positiveText: '保存',
|
||||||
negativeText: '取消',
|
negativeText: '取消',
|
||||||
onPositiveClick: async () => {
|
onPositiveClick: async () => {
|
||||||
debugger
|
data.value = []
|
||||||
console.log(editWordRef)
|
|
||||||
debugger
|
|
||||||
let word_arr = editWordRef.value.word.split('\n')
|
let word_arr = editWordRef.value.word.split('\n')
|
||||||
let new_arr = []
|
|
||||||
let lastId = ''
|
let lastId = ''
|
||||||
for (let i = 0; i < word_arr.length; i++) {
|
for (let i = 0; i < word_arr.length; i++) {
|
||||||
const element = word_arr[i]
|
const element = word_arr[i]
|
||||||
|
|||||||
@ -1,12 +1,14 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<n-data-table
|
<n-data-table
|
||||||
|
id="1111"
|
||||||
:max-height="maxHeight"
|
:max-height="maxHeight"
|
||||||
:row-key="rowKey"
|
:row-key="rowKey"
|
||||||
:columns="columns"
|
:columns="columns"
|
||||||
:data="data"
|
:data="data"
|
||||||
:pagination="false"
|
:pagination="false"
|
||||||
:bordered="false"
|
:bordered="false"
|
||||||
|
:scroll-x="0"
|
||||||
@update:checked-row-keys="handleCheck"
|
@update:checked-row-keys="handleCheck"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@ -41,13 +43,18 @@ import { DEFINE_STRING } from '../../../../define/define_string'
|
|||||||
import ModifyPromptChinese from '../Components/ModifyPromptChinese.vue'
|
import ModifyPromptChinese from '../Components/ModifyPromptChinese.vue'
|
||||||
import InputDialogContent from './Components/InputDialogContent.vue'
|
import InputDialogContent from './Components/InputDialogContent.vue'
|
||||||
import DataTableShowGenerateImage from './Components/DataTableShowGenerateImage.vue'
|
import DataTableShowGenerateImage from './Components/DataTableShowGenerateImage.vue'
|
||||||
import { cloneDeep, debounce, min } from 'lodash'
|
import { cloneDeep, debounce, isEmpty, min } from 'lodash'
|
||||||
import SelectImageStyle from '../Components/SelectImageStyle.vue'
|
import SelectImageStyle from '../Components/SelectImageStyle.vue'
|
||||||
import DataTableCharacterAndScene from './Components/DataTableCharacterAndScene.vue'
|
import DataTableCharacterAndScene from './Components/DataTableCharacterAndScene.vue'
|
||||||
import DataTablePromptRow from './Components/DataTablePromptRow.vue'
|
import DataTablePromptRow from './Components/DataTablePromptRow.vue'
|
||||||
import DataTableGptPromptRow from './Components/DataTableGptPromptRow.vue'
|
import DataTableGptPromptRow from './Components/DataTableGptPromptRow.vue'
|
||||||
import DataTableParameterRow from './Components/DataTableParameterRow.vue'
|
import DataTableParameterRow from './Components/DataTableParameterRow.vue'
|
||||||
import { Reload } from '@vicons/ionicons5'
|
import { Reload } from '@vicons/ionicons5'
|
||||||
|
import {
|
||||||
|
checkStringValueAddPrefix,
|
||||||
|
checkStringValueAddSuffix,
|
||||||
|
checkStringValueDeletePrefix
|
||||||
|
} from '../../../../main/generalTools'
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
components: {
|
components: {
|
||||||
@ -63,15 +70,15 @@ export default defineComponent({
|
|||||||
Reload,
|
Reload,
|
||||||
NIcon
|
NIcon
|
||||||
},
|
},
|
||||||
props: ['initData', 'prefix_prompt', 'suffix_prompt'],
|
props: ['initData', 'prefix_prompt', 'suffix_prompt', 'tags', 'InitTags'],
|
||||||
setup(props) {
|
setup(props) {
|
||||||
console.log('输出文件夹位置', props.initData)
|
console.log('输出文件夹位置', props.initData)
|
||||||
let data = ref(props.initData)
|
let data = ref(props.initData)
|
||||||
|
let tags = ref(props.tags)
|
||||||
let message = useMessage()
|
let message = useMessage()
|
||||||
let dialog = useDialog()
|
let dialog = useDialog()
|
||||||
let selectKey = ref([])
|
let selectKey = ref([])
|
||||||
let promptChineseRef = ref(null)
|
let promptChineseRef = ref(null)
|
||||||
let zhAutoTranslate = ref(false)
|
|
||||||
let maxHeight = ref(null)
|
let maxHeight = ref(null)
|
||||||
let prefix_prompt = ref(props.prefix_prompt)
|
let prefix_prompt = ref(props.prefix_prompt)
|
||||||
let suffix_prompt = ref(props.suffix_prompt)
|
let suffix_prompt = ref(props.suffix_prompt)
|
||||||
@ -86,8 +93,6 @@ export default defineComponent({
|
|||||||
window.config.character_select_model ? window.config.character_select_model : 'tag'
|
window.config.character_select_model ? window.config.character_select_model : 'tag'
|
||||||
)
|
)
|
||||||
|
|
||||||
let tags = ref({})
|
|
||||||
|
|
||||||
let AutoSaveDataJsonDebounced = debounce(AutoSaveDataJson, 3000)
|
let AutoSaveDataJsonDebounced = debounce(AutoSaveDataJson, 3000)
|
||||||
let SaveDataJsonDebounced = debounce(AutoSaveDataJson, 1000)
|
let SaveDataJsonDebounced = debounce(AutoSaveDataJson, 1000)
|
||||||
|
|
||||||
@ -107,6 +112,23 @@ export default defineComponent({
|
|||||||
{ deep: true }
|
{ deep: true }
|
||||||
)
|
)
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.tags,
|
||||||
|
async (newVal) => {
|
||||||
|
debugger
|
||||||
|
tags.value = newVal
|
||||||
|
// 同步修改 selectStyle.value 的值
|
||||||
|
for (let i = 0; i < selectStyle.value.length; i++) {
|
||||||
|
let index = tags.value.style_tags?.findIndex(
|
||||||
|
(item) => item.key == selectStyle.value[i].key
|
||||||
|
)
|
||||||
|
if (selectStyle.value[i].type == 'style_main' && index != null && index != -1) {
|
||||||
|
selectStyle.value[i] = tags.value.style_tags[index]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => props.prefix_prompt,
|
() => props.prefix_prompt,
|
||||||
(newVal) => {
|
(newVal) => {
|
||||||
@ -138,20 +160,16 @@ export default defineComponent({
|
|||||||
const createColumns = ({}) => {
|
const createColumns = ({}) => {
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
type: 'selection',
|
title: 'No.',
|
||||||
disabled(row) {
|
|
||||||
return row.name === 'Edward King 3'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '',
|
|
||||||
key: 'no',
|
key: 'no',
|
||||||
width: 50
|
width: 50,
|
||||||
|
fixed: 'left'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '字幕',
|
title: '字幕',
|
||||||
key: 'srt',
|
key: 'srt',
|
||||||
width: '180',
|
width: '180',
|
||||||
|
fixed: 'left',
|
||||||
render(row) {
|
render(row) {
|
||||||
let tmp
|
let tmp
|
||||||
if (row.subValue.length > 0) {
|
if (row.subValue.length > 0) {
|
||||||
@ -187,10 +205,10 @@ export default defineComponent({
|
|||||||
func: {
|
func: {
|
||||||
refreshTagData: async () => {
|
refreshTagData: async () => {
|
||||||
try {
|
try {
|
||||||
await InitTags()
|
await props.InitTags()
|
||||||
message.success('人物角色刷新成功')
|
message.success('人物角色刷新成功')
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
message.success('人物角色刷新失败,请重试')
|
message.error('人物角色刷新失败,请重试' + error.toString())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -215,6 +233,7 @@ export default defineComponent({
|
|||||||
type: 'title',
|
type: 'title',
|
||||||
row: row,
|
row: row,
|
||||||
index: index,
|
index: index,
|
||||||
|
tags: tags,
|
||||||
func: {
|
func: {
|
||||||
translateAll: TranslateAll,
|
translateAll: TranslateAll,
|
||||||
addPrefix: AddPrefix,
|
addPrefix: AddPrefix,
|
||||||
@ -225,6 +244,9 @@ export default defineComponent({
|
|||||||
},
|
},
|
||||||
key: 'gpt_prompt',
|
key: 'gpt_prompt',
|
||||||
className: 'prompt_row',
|
className: 'prompt_row',
|
||||||
|
resizable: true,
|
||||||
|
minWidth: 300,
|
||||||
|
width: '500',
|
||||||
render(row, index) {
|
render(row, index) {
|
||||||
return h(DataTableGptPromptRow, {
|
return h(DataTableGptPromptRow, {
|
||||||
type: 'data',
|
type: 'data',
|
||||||
@ -326,32 +348,31 @@ export default defineComponent({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function InitTags() {
|
|
||||||
await window.mj.GetTagDataByTypeAndProperty(['dynamic', null], (value) => {
|
|
||||||
if (value.code == 0) {
|
|
||||||
message.error(value.message)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
tags.value = value.data
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
zhAutoTranslate.value = window.config.translation_auto
|
// 直接或整个cinfig文件
|
||||||
|
await window.api.GetConfigJson(JSON.stringify([null, {}]), async (value) => {
|
||||||
await window.api.GetConfigJson(JSON.stringify(['image_style', []]), async (value) => {
|
|
||||||
debugger
|
debugger
|
||||||
if (value.code == 0) {
|
if (value.code == 0) {
|
||||||
message.error(value.message)
|
message.error(value.message)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
await window.api.GetImageStyleInfomation(JSON.stringify(toRaw(value.data)), (value) => {
|
let image_style_list = value.data.image_style
|
||||||
|
let customize_image_style_list = value.data.customize_image_style
|
||||||
|
await window.api.GetImageStyleInfomation(JSON.stringify(image_style_list), (value) => {
|
||||||
if (value.code == 0) {
|
if (value.code == 0) {
|
||||||
message.error(value.message)
|
message.error(value.message)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
selectStyle.value = value.data
|
selectStyle.value = value.data
|
||||||
})
|
})
|
||||||
|
|
||||||
|
for (let i = 0; i < customize_image_style_list.length; i++) {
|
||||||
|
const element = customize_image_style_list[i]
|
||||||
|
selectStyle.value.push({
|
||||||
|
key: element,
|
||||||
|
type: 'style_main'
|
||||||
|
})
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
// 判断data中的数据是不是有chinese text
|
// 判断data中的数据是不是有chinese text
|
||||||
@ -410,7 +431,7 @@ export default defineComponent({
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
await InitTags()
|
await props.InitTags()
|
||||||
})
|
})
|
||||||
|
|
||||||
onBeforeUnmount(async () => {
|
onBeforeUnmount(async () => {
|
||||||
@ -438,11 +459,9 @@ export default defineComponent({
|
|||||||
}
|
}
|
||||||
delete value.type
|
delete value.type
|
||||||
delete value.code
|
delete value.code
|
||||||
|
|
||||||
data.value[index]['mj_message'] = value
|
data.value[index]['mj_message'] = value
|
||||||
} else if (value.type == 'updated') {
|
} else if (value.type == 'updated') {
|
||||||
console.log('接收Discord的更新消息', value)
|
console.log('接收Discord的更新消息', value)
|
||||||
debugger
|
|
||||||
// 修改对应的数据
|
// 修改对应的数据
|
||||||
let index = data.value.findIndex((item) => item.mj_message?.message_id == value.message_id)
|
let index = data.value.findIndex((item) => item.mj_message?.message_id == value.message_id)
|
||||||
if (index < 0) {
|
if (index < 0) {
|
||||||
@ -461,8 +480,6 @@ export default defineComponent({
|
|||||||
console.log('接收Discord的删除消息', value)
|
console.log('接收Discord的删除消息', value)
|
||||||
} else if (value.type == 'finished') {
|
} else if (value.type == 'finished') {
|
||||||
console.log('接收Discord的完成消息', value)
|
console.log('接收Discord的完成消息', value)
|
||||||
debugger
|
|
||||||
|
|
||||||
// 修改对应的数据
|
// 修改对应的数据
|
||||||
let index = data.value.findIndex((item) => item.mj_message?.image_id == value.image_id)
|
let index = data.value.findIndex((item) => item.mj_message?.image_id == value.image_id)
|
||||||
if (index < 0) {
|
if (index < 0) {
|
||||||
@ -567,6 +584,7 @@ export default defineComponent({
|
|||||||
* 选择生成图片的风格
|
* 选择生成图片的风格
|
||||||
*/
|
*/
|
||||||
async function SelectGenerateImagesStyle() {
|
async function SelectGenerateImagesStyle() {
|
||||||
|
debugger
|
||||||
// 判断当前数据是不是存在
|
// 判断当前数据是不是存在
|
||||||
// 处理数据。获取当前的所有的数据
|
// 处理数据。获取当前的所有的数据
|
||||||
let dialogWidth = window.innerWidth * 0.8
|
let dialogWidth = window.innerWidth * 0.8
|
||||||
@ -578,21 +596,40 @@ export default defineComponent({
|
|||||||
content: () =>
|
content: () =>
|
||||||
h(SelectImageStyle, {
|
h(SelectImageStyle, {
|
||||||
selectStyle: toRaw(selectStyle.value),
|
selectStyle: toRaw(selectStyle.value),
|
||||||
height: dialogHeight
|
height: dialogHeight,
|
||||||
|
tags: tags
|
||||||
}),
|
}),
|
||||||
style: `width : ${dialogWidth}px; height : ${dialogHeight}px`,
|
style: `width : ${dialogWidth}px; height : ${dialogHeight}px`,
|
||||||
maskClosable: false,
|
maskClosable: false,
|
||||||
onClose: async () => {
|
onClose: async () => {
|
||||||
// 重新加载数据
|
// 重新加载数据
|
||||||
let tmp_arr = []
|
let tmp_arr = []
|
||||||
|
|
||||||
|
let cus_arr = []
|
||||||
|
|
||||||
for (let i = 0; i < selectStyle.value.length; i++) {
|
for (let i = 0; i < selectStyle.value.length; i++) {
|
||||||
|
debugger
|
||||||
const element = selectStyle.value[i]
|
const element = selectStyle.value[i]
|
||||||
|
// 判断是不是主风格
|
||||||
|
if (element.type == 'style_main') {
|
||||||
|
cus_arr.push(element.key)
|
||||||
|
} else {
|
||||||
tmp_arr.push(element.id)
|
tmp_arr.push(element.id)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 将当前的风格保存
|
// 将当前的风格保存
|
||||||
await window.api.SaveCopywritingInformation(
|
await window.api.SaveCopywritingInformation(
|
||||||
[JSON.stringify(tmp_arr), 'image_style', true],
|
[JSON.stringify(tmp_arr), 'image_style', true],
|
||||||
(value) => {
|
async (value) => {
|
||||||
|
if (value.code == 0) {
|
||||||
|
message.error(value.message)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
await window.api.SaveCopywritingInformation(
|
||||||
|
[JSON.stringify(cus_arr), 'customize_image_style', true],
|
||||||
|
() => {
|
||||||
if (value.code == 0) {
|
if (value.code == 0) {
|
||||||
message.error(value.message)
|
message.error(value.message)
|
||||||
return
|
return
|
||||||
@ -601,6 +638,8 @@ export default defineComponent({
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -808,12 +847,128 @@ export default defineComponent({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SD 模式合并名并
|
||||||
|
* @param character_string
|
||||||
|
* @param scene_string
|
||||||
|
* @param gpt_prompt
|
||||||
|
*/
|
||||||
|
function SDMergePrompt(element) {
|
||||||
|
let character_string = ''
|
||||||
|
element.character_tags?.forEach((item) => {
|
||||||
|
character_string += ', ' + item.prompt
|
||||||
|
if (item.lora && item.lora != '无' && item.lora_weight) {
|
||||||
|
character_string += `, <lora:${item.lora}:${item.lora_weight}>`
|
||||||
|
}
|
||||||
|
})
|
||||||
|
// 判断 character_string 有数据,有的话删除第一个逗号
|
||||||
|
character_string = checkStringValueDeletePrefix(character_string, ',')
|
||||||
|
|
||||||
|
// 获取当前的场景提示词
|
||||||
|
let scene_string = ''
|
||||||
|
element.scene_tags?.forEach((item) => {
|
||||||
|
scene_string += ', ' + item.prompt
|
||||||
|
})
|
||||||
|
|
||||||
|
let style_string = ''
|
||||||
|
|
||||||
|
selectStyle.value.forEach((item) => {
|
||||||
|
if (item.type && item.type == 'style_main') {
|
||||||
|
style_string += ', ' + item.prompt
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// 判断 scene_string 有数据,有的话删除第一个逗号
|
||||||
|
scene_string = checkStringValueDeletePrefix(scene_string, ',')
|
||||||
|
style_string = checkStringValueDeletePrefix(style_string, ',')
|
||||||
|
style_string = checkStringValueAddSuffix(style_string, ',')
|
||||||
|
|
||||||
|
return `${style_string} ${checkStringValueAddSuffix(
|
||||||
|
character_string,
|
||||||
|
', '
|
||||||
|
)}${checkStringValueAddSuffix(scene_string, ', ')}${checkStringValueAddSuffix(
|
||||||
|
element.gpt_prompt,
|
||||||
|
', '
|
||||||
|
)}`
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将所有的数据进行拼接
|
||||||
|
* @param prefix 前缀
|
||||||
|
* @param character_string 人物提示词
|
||||||
|
* @param scene_string 场景提示词
|
||||||
|
* @param gpt_prompt GPT提示词
|
||||||
|
* @param suffix 后缀
|
||||||
|
*/
|
||||||
|
function MJMergePrompt(prefix, element, suffix) {
|
||||||
|
debugger
|
||||||
|
let character_string = ''
|
||||||
|
let cref_url = ''
|
||||||
|
element.character_tags?.forEach((item) => {
|
||||||
|
character_string += ', ' + item.prompt
|
||||||
|
if (item.image_url && item.image_url != '' && item.cref_cw) {
|
||||||
|
cref_url += ` ${item.image_url} `
|
||||||
|
}
|
||||||
|
})
|
||||||
|
// 判断cref_url 是不是有数据,有的话添加 --cref
|
||||||
|
cref_url = checkStringValueAddPrefix(cref_url, ' --cref ')
|
||||||
|
|
||||||
|
if (element.character_tags && element.character_tags.length > 0) {
|
||||||
|
cref_url = checkStringValueAddSuffix(cref_url, ` --cw ${element.character_tags[0].cref_cw} `)
|
||||||
|
}
|
||||||
|
// 判断 character_string 有数据,有的话删除第一个逗号
|
||||||
|
character_string = checkStringValueDeletePrefix(character_string, ',')
|
||||||
|
|
||||||
|
// 获取当前的场景提示词
|
||||||
|
let scene_string = ''
|
||||||
|
element.scene_tags?.forEach((item) => {
|
||||||
|
scene_string += ', ' + item.prompt
|
||||||
|
})
|
||||||
|
// 判断 scene_string 有数据,有的话删除第一个逗号
|
||||||
|
scene_string = checkStringValueDeletePrefix(scene_string, ',')
|
||||||
|
|
||||||
|
// 获取当前的自定义风格
|
||||||
|
|
||||||
|
let style_string = ''
|
||||||
|
let style_url = ''
|
||||||
|
let sw = 0
|
||||||
|
|
||||||
|
selectStyle.value.forEach((item) => {
|
||||||
|
if (item.type && item.type == 'style_main') {
|
||||||
|
style_string += ', ' + item.prompt
|
||||||
|
if (sw == 0) {
|
||||||
|
sw = item.sref_sw
|
||||||
|
}
|
||||||
|
if (!isEmpty(item.image_url)) {
|
||||||
|
let url = item.image_url ? item.image_url : ''
|
||||||
|
style_url += ' ' + url
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
style_url = checkStringValueAddPrefix(style_url, '--sref ')
|
||||||
|
style_url = checkStringValueAddSuffix(style_url, ` --sw ${sw}`)
|
||||||
|
style_string = checkStringValueDeletePrefix(style_string, ',')
|
||||||
|
style_string = checkStringValueAddSuffix(style_string, ', ')
|
||||||
|
|
||||||
|
return ` ${style_string} ${checkStringValueAddSuffix(
|
||||||
|
prefix,
|
||||||
|
', '
|
||||||
|
)}${checkStringValueAddSuffix(character_string, ', ')}${checkStringValueAddSuffix(
|
||||||
|
scene_string,
|
||||||
|
', '
|
||||||
|
)}${checkStringValueAddSuffix(element.gpt_prompt, ', ')} ${checkStringValueAddSuffix(
|
||||||
|
suffix,
|
||||||
|
' '
|
||||||
|
)} ${cref_url} ${style_url}`
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 生成提示词
|
* 生成提示词
|
||||||
*/
|
*/
|
||||||
async function MergePrompt() {
|
async function MergePrompt(key) {
|
||||||
debugger
|
|
||||||
try {
|
try {
|
||||||
|
debugger
|
||||||
// 判断该当前是不是有风格
|
// 判断该当前是不是有风格
|
||||||
// 获取当前的风格ID
|
// 获取当前的风格ID
|
||||||
let style_str = ''
|
let style_str = ''
|
||||||
@ -823,29 +978,34 @@ export default defineComponent({
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 获取当前的前缀和后缀
|
// 获取当前的前缀和后缀
|
||||||
let prefix = prefix_prompt.value
|
let prefix = prefix_prompt.value ? prefix_prompt.value : ''
|
||||||
let suffix = suffix_prompt.value
|
let suffix = suffix_prompt.value ? suffix_prompt.value : ''
|
||||||
|
|
||||||
for (let i = 0; i < data.value.length; i++) {
|
for (let i = 0; i < data.value.length; i++) {
|
||||||
const element = data.value[i]
|
const element = data.value[i]
|
||||||
// 匹配提示词
|
let end_prompt = ''
|
||||||
// 拼接当前选择的人物
|
if (key == null) {
|
||||||
let character_string = ''
|
// 判断当前的分类是什么,通过分类来判断合并提示词
|
||||||
element.character_tags?.forEach((item) => {
|
if (image_generate_category.value == 'sd') {
|
||||||
character_string += item.prompt + ', '
|
end_prompt = SDMergePrompt(element)
|
||||||
})
|
} else if (image_generate_category.value == 'mj') {
|
||||||
|
end_prompt = MJMergePrompt(prefix, element, suffix)
|
||||||
// 获取当前的场景提示词
|
} else if (image_generate_category.value == 'd3') {
|
||||||
let scene_string = ''
|
message.error('该分类暂时不可用')
|
||||||
element.scene_tags?.forEach((item) => {
|
return
|
||||||
scene_string += item.prompt + ', '
|
} else {
|
||||||
})
|
message.error('合并提示词错误:未知的合并提示词类型')
|
||||||
|
return
|
||||||
// 开始拼接提示词
|
}
|
||||||
|
} else if (key == 'mj_merge') {
|
||||||
|
end_prompt = MJMergePrompt(prefix, element, suffix)
|
||||||
|
} else if (key == 'sd_merge') {
|
||||||
|
end_prompt = SDMergePrompt(element)
|
||||||
|
} else {
|
||||||
|
message.error('合并提示词错误:未知的合并提示词类型')
|
||||||
|
return
|
||||||
|
}
|
||||||
// 风格 + 前缀 + 人物 + 场景 + 词 + 后缀
|
// 风格 + 前缀 + 人物 + 场景 + 词 + 后缀
|
||||||
let end_prompt = ` ${style_str} ${
|
|
||||||
prefix ? prefix : ''
|
|
||||||
}, ${character_string} ${scene_string} ${element.gpt_prompt}, ${suffix ? suffix : ''}`
|
|
||||||
data.value[i].prompt = end_prompt
|
data.value[i].prompt = end_prompt
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@ -910,7 +1070,6 @@ export default defineComponent({
|
|||||||
selectKey.value = rowKeys
|
selectKey.value = rowKeys
|
||||||
},
|
},
|
||||||
promptChineseRef,
|
promptChineseRef,
|
||||||
zhAutoTranslate,
|
|
||||||
TranslatePrompt,
|
TranslatePrompt,
|
||||||
TranslateAll,
|
TranslateAll,
|
||||||
maxHeight,
|
maxHeight,
|
||||||
|
|||||||
@ -1,91 +1,136 @@
|
|||||||
<template>
|
<template>
|
||||||
<div id="menu">
|
<div id="menu">
|
||||||
<MenuButton :initData="data" :initDataFunction="InitData" :Character="AnalyzeCharacter" :treeData="TagTreeData">
|
<MenuButton
|
||||||
|
:initData="data"
|
||||||
|
:initDataFunction="InitData"
|
||||||
|
:Character="AnalyzeCharacter"
|
||||||
|
:treeData="TagTreeData"
|
||||||
|
>
|
||||||
</MenuButton>
|
</MenuButton>
|
||||||
</div>
|
</div>
|
||||||
<div id="data-table" style="margin-top: 10px;">
|
<div id="data-table" style="margin-top: 10px">
|
||||||
<DataTable :initData="data" :suffix_prompt="suffix_prompt" :prefix_prompt="prefix_prompt"></DataTable>
|
<DataTable
|
||||||
|
:tags="tags"
|
||||||
|
:initData="data"
|
||||||
|
:suffix_prompt="suffix_prompt"
|
||||||
|
:prefix_prompt="prefix_prompt"
|
||||||
|
:InitTags="InitTags"
|
||||||
|
></DataTable>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { ref, h, onMounted, defineComponent, onUnmounted, toRaw } from "vue"
|
import { ref, h, onMounted, defineComponent, onUnmounted, toRaw } from 'vue'
|
||||||
import { NImage, useMessage } from "naive-ui";
|
import { NImage, useMessage } from 'naive-ui'
|
||||||
import { DEFINE_STRING } from "../../../../define/define_string";
|
import { DEFINE_STRING } from '../../../../define/define_string'
|
||||||
import MenuButton from './MenuButton.vue'
|
import MenuButton from './MenuButton.vue'
|
||||||
import DataTable from './DataTable.vue'
|
import DataTable from './DataTable.vue'
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
components: {
|
components: {
|
||||||
NImage, DataTable, MenuButton
|
NImage,
|
||||||
|
DataTable,
|
||||||
|
MenuButton
|
||||||
},
|
},
|
||||||
setup() {
|
setup() {
|
||||||
let message = useMessage();
|
let message = useMessage()
|
||||||
let data = ref([]);
|
let data = ref([])
|
||||||
let AnalyzeCharacter = ref("");
|
let tags = ref({})
|
||||||
let TagTreeData = ref([]);
|
let AnalyzeCharacter = ref('')
|
||||||
let suffix_prompt = ref(null);
|
let TagTreeData = ref([])
|
||||||
let prefix_prompt = ref(null);
|
let suffix_prompt = ref(null)
|
||||||
let promptError = true;
|
let prefix_prompt = ref(null)
|
||||||
|
let promptError = true
|
||||||
|
|
||||||
async function InitData() {
|
async function InitData() {
|
||||||
// 加载
|
// 加载
|
||||||
// 初始化加载项目下面的分镜好的文案
|
// 初始化加载项目下面的分镜好的文案
|
||||||
// 并判断是不是有洗稿后的文件。一并加载
|
// 并判断是不是有洗稿后的文件。一并加载
|
||||||
await window.api.GetProjectWord(value => {
|
await window.api.GetProjectWord((value) => {
|
||||||
data.value = value.data;
|
data.value = value.data
|
||||||
})
|
})
|
||||||
if (!data.value) {
|
if (!data.value) {
|
||||||
data.value = [];
|
data.value = []
|
||||||
}
|
}
|
||||||
|
|
||||||
// 重新加载数据
|
// 重新加载数据
|
||||||
// 判断是不是已经有生成(有有生成显示)
|
// 判断是不是已经有生成(有有生成显示)
|
||||||
await window.api.GetConfigJson(JSON.stringify(['auto_analyze_character', ""]), (value) => {
|
await window.api.GetConfigJson(JSON.stringify(['auto_analyze_character', '']), (value) => {
|
||||||
if (value.code == 0) {
|
if (value.code == 0) {
|
||||||
message.error(value.message);
|
message.error(value.message)
|
||||||
return;
|
return
|
||||||
}
|
}
|
||||||
AnalyzeCharacter.value = value.data;
|
AnalyzeCharacter.value = value.data
|
||||||
})
|
})
|
||||||
|
|
||||||
// 判断是不是有前缀
|
// 判断是不是有前缀
|
||||||
await window.api.GetConfigJson(JSON.stringify([null, {}]), async (value) => {
|
await window.api.GetConfigJson(JSON.stringify([null, {}]), async (value) => {
|
||||||
debugger
|
debugger
|
||||||
if (value.code == 0) {
|
if (value.code == 0) {
|
||||||
message.error(value.message);
|
message.error(value.message)
|
||||||
return;
|
return
|
||||||
}
|
}
|
||||||
suffix_prompt.value = value.data.suffix_prompt;
|
suffix_prompt.value = value.data.suffix_prompt
|
||||||
prefix_prompt.value = value.data.prefix_prompt;
|
prefix_prompt.value = value.data.prefix_prompt
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
// 读取data数据对应的prompt文件
|
// 读取data数据对应的prompt文件
|
||||||
for (let i = 0; i < data.value.length; i++) {
|
for (let i = 0; i < data.value.length; i++) {
|
||||||
const item = data.value[i];
|
const item = data.value[i]
|
||||||
await window.api.GetPromptJson(item.name, (value) => {
|
await window.api.GetPromptJson(item.name, (value) => {
|
||||||
debugger
|
debugger
|
||||||
console.log(value);
|
console.log(value)
|
||||||
if (value.code == 0 && promptError) {
|
if (value.code == 0 && promptError) {
|
||||||
message.error(value.message);
|
message.error(value.message)
|
||||||
promptError = false;
|
promptError = false
|
||||||
}
|
}
|
||||||
data.value[i].prompt = value.data.webui_config.prompt;
|
data.value[i].prompt = value.data.webui_config.prompt
|
||||||
data.value[i].chinese_prompt = value.data?.chinese_prompt;
|
data.value[i].chinese_prompt = value.data?.chinese_prompt
|
||||||
// data.value[i].gpt_prompt = value.data?.gpt_prompt;
|
// data.value[i].gpt_prompt = value.data?.gpt_prompt;
|
||||||
data.value[i].adetailer = value.data?.adetailer;
|
data.value[i].adetailer = value.data?.adetailer
|
||||||
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function InitTags() {
|
||||||
|
await window.mj.GetTagDataByTypeAndProperty(['dynamic', null], (value) => {
|
||||||
|
if (value.code == 0) {
|
||||||
|
message.error(value.message)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
debugger
|
||||||
|
tags.value = value.data
|
||||||
|
// 加载完毕之后,需要刷新当前的data中的tag数据
|
||||||
|
console.log(data, tags)
|
||||||
|
for (let i = 0; i < data.value.length; i++) {
|
||||||
|
const element = data.value[i]
|
||||||
|
if (
|
||||||
|
element.character_tags &&
|
||||||
|
tags.value.character_tags &&
|
||||||
|
tags.value.character_tags.length > 0
|
||||||
|
) {
|
||||||
|
// 循环判断当前的character_tags对应的key在tags.character_tags中是否存在,存在覆盖,不存在删除
|
||||||
|
for (let j = element.character_tags.length - 1; j >= 0; j--) {
|
||||||
|
const item = element.character_tags[j]
|
||||||
|
let index = tags.value.character_tags.findIndex((tag) => tag.key == item.key)
|
||||||
|
if (index != -1) {
|
||||||
|
element.character_tags[j] = tags.value.character_tags[index]
|
||||||
|
} else {
|
||||||
|
element.character_tags.splice(j, 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
element.character_tags = []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
await InitData();
|
await InitData()
|
||||||
|
await InitTags()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
data,
|
data,
|
||||||
AnalyzeCharacter,
|
AnalyzeCharacter,
|
||||||
@ -93,6 +138,8 @@ export default defineComponent({
|
|||||||
prefix_prompt,
|
prefix_prompt,
|
||||||
suffix_prompt,
|
suffix_prompt,
|
||||||
InitData,
|
InitData,
|
||||||
|
InitTags,
|
||||||
|
tags
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@ -168,7 +168,6 @@ export default defineComponent({
|
|||||||
mjSetting.value = value.data;
|
mjSetting.value = value.data;
|
||||||
modifyOption(value.data);
|
modifyOption(value.data);
|
||||||
}
|
}
|
||||||
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -3,10 +3,21 @@
|
|||||||
<n-tab-pane name="normal setting" tab="基础设置">
|
<n-tab-pane name="normal setting" tab="基础设置">
|
||||||
<n-form ref="formRef" :label-width="80" :model="formValue">
|
<n-form ref="formRef" :label-width="80" :model="formValue">
|
||||||
<n-form-item label="SD请求地址" path="webui_api_url">
|
<n-form-item label="SD请求地址" path="webui_api_url">
|
||||||
<n-input v-model:value="formValue.webui_api_url" placeholder="输入SD地址" />
|
<n-input
|
||||||
|
v-model:value="formValue.webui_api_url"
|
||||||
|
style="width: 250px"
|
||||||
|
placeholder="输入SD地址"
|
||||||
|
/>
|
||||||
|
<n-button style="margin-left: 10px" type="primary" @click="LoadSDServiceData"
|
||||||
|
>加载数据</n-button
|
||||||
|
>
|
||||||
</n-form-item>
|
</n-form-item>
|
||||||
<n-form-item label="出图方式(文生图、图生图)" path="type">
|
<n-form-item label="出图方式(文生图、图生图)" path="type">
|
||||||
<n-select v-model:value="formValue.type" :options="modelOption" placeholder="输入采样方法" />
|
<n-select
|
||||||
|
v-model:value="formValue.type"
|
||||||
|
:options="modelOption"
|
||||||
|
placeholder="输入采样方法"
|
||||||
|
/>
|
||||||
</n-form-item>
|
</n-form-item>
|
||||||
<n-form-item label="正向提示词(和推导出来的tag进行拼接)" path="prompt">
|
<n-form-item label="正向提示词(和推导出来的tag进行拼接)" path="prompt">
|
||||||
<n-input v-model:value="formValue.prompt" placeholder="输入正向提示词" />
|
<n-input v-model:value="formValue.prompt" placeholder="输入正向提示词" />
|
||||||
@ -15,38 +26,68 @@
|
|||||||
<n-input v-model:value="formValue.negative_prompt" placeholder="输入反向提示词" />
|
<n-input v-model:value="formValue.negative_prompt" placeholder="输入反向提示词" />
|
||||||
</n-form-item>
|
</n-form-item>
|
||||||
<div style="display: flex">
|
<div style="display: flex">
|
||||||
<n-form-item label="CFG Scale" style="margin-right: 30px;">
|
<n-form-item label="CFG Scale" style="margin-right: 30px">
|
||||||
<n-input-number :min="0" :max="30" :step="0.05" v-model:value="formValue.cfg_scale"
|
<n-input-number
|
||||||
placeholder="输入重绘幅度" />
|
:min="0"
|
||||||
|
:max="30"
|
||||||
|
:step="0.05"
|
||||||
|
v-model:value="formValue.cfg_scale"
|
||||||
|
placeholder="输入重绘幅度"
|
||||||
|
/>
|
||||||
</n-form-item>
|
</n-form-item>
|
||||||
<n-form-item label="重绘幅度" path="denoising_strength">
|
<n-form-item label="重绘幅度" path="denoising_strength">
|
||||||
<n-input-number :precision="2" :step="0.05" v-model:value="formValue.denoising_strength"
|
<n-input-number
|
||||||
placeholder="输入重绘幅度" />
|
:precision="2"
|
||||||
<n-checkbox style="margin-left: 30px;" size="large" v-model:checked="formValue.adetailer"
|
:step="0.05"
|
||||||
label="是否开启修脸/修手" />
|
v-model:value="formValue.denoising_strength"
|
||||||
|
placeholder="输入重绘幅度"
|
||||||
|
/>
|
||||||
|
<n-checkbox
|
||||||
|
style="margin-left: 30px"
|
||||||
|
size="large"
|
||||||
|
v-model:checked="formValue.adetailer"
|
||||||
|
label="是否开启修脸/修手"
|
||||||
|
/>
|
||||||
</n-form-item>
|
</n-form-item>
|
||||||
</div>
|
</div>
|
||||||
<n-form-item label="采样方式" path="sampler_name">
|
<n-form-item label="采样方式" path="sampler_name">
|
||||||
<n-input v-model:value="formValue.sampler_name" placeholder="输入模型" />
|
<n-input v-model:value="formValue.sampler_name" placeholder="输入模型" />
|
||||||
</n-form-item>
|
</n-form-item>
|
||||||
<div style="display: flex;">
|
<div style="display: flex">
|
||||||
<n-form-item label="迭代步数" path="steps">
|
<n-form-item label="迭代步数" path="steps">
|
||||||
<n-input-number style="width: 150px;" v-model:value="formValue.steps" placeholder="输入迭代步数" />
|
<n-input-number
|
||||||
|
style="width: 150px"
|
||||||
|
v-model:value="formValue.steps"
|
||||||
|
placeholder="输入迭代步数"
|
||||||
|
/>
|
||||||
</n-form-item>
|
</n-form-item>
|
||||||
<n-form-item label="风格词权重" path="style_weight" style="margin-left: 10px;">
|
<n-form-item label="风格词权重" path="style_weight" style="margin-left: 10px">
|
||||||
<n-input-number :min="1" :max="4" :step="0.05" :precision="2" style="width: 150px;"
|
<n-input-number
|
||||||
v-model:value="formValue.style_weight" placeholder="输入风格词权重" />
|
:min="1"
|
||||||
|
:max="4"
|
||||||
|
:step="0.05"
|
||||||
|
:precision="2"
|
||||||
|
style="width: 150px"
|
||||||
|
v-model:value="formValue.style_weight"
|
||||||
|
placeholder="输入风格词权重"
|
||||||
|
/>
|
||||||
</n-form-item>
|
</n-form-item>
|
||||||
</div>
|
</div>
|
||||||
<n-form-item label="图片分辨率" path="resolution">
|
<n-form-item label="图片分辨率" path="resolution">
|
||||||
<n-input-number :show-button="false" v-model:value="formValue.width" placeholder="输入迭代步数" />
|
<n-input-number
|
||||||
<span style="margin: 0 10px;"> * </span>
|
:show-button="false"
|
||||||
<n-input-number :show-button="false" v-model:value="formValue.height" placeholder="输入迭代步数" />
|
v-model:value="formValue.width"
|
||||||
|
placeholder="输入迭代步数"
|
||||||
|
/>
|
||||||
|
<span style="margin: 0 10px"> * </span>
|
||||||
|
<n-input-number
|
||||||
|
:show-button="false"
|
||||||
|
v-model:value="formValue.height"
|
||||||
|
placeholder="输入迭代步数"
|
||||||
|
/>
|
||||||
</n-form-item>
|
</n-form-item>
|
||||||
<n-form-item>
|
<n-form-item>
|
||||||
<n-button attr-type="button" type="primary" @click="SaveSDConfig">
|
<n-button attr-type="button" type="primary" @click="SaveSDConfig"> 保存设置 </n-button>
|
||||||
保存设置
|
|
||||||
</n-button>
|
|
||||||
</n-form-item>
|
</n-form-item>
|
||||||
</n-form>
|
</n-form>
|
||||||
</n-tab-pane>
|
</n-tab-pane>
|
||||||
@ -57,13 +98,33 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { defineComponent, ref, h, onMounted, toRaw } from "vue";
|
import { defineComponent, ref, h, onMounted, toRaw } from 'vue'
|
||||||
import { NForm, NFormItem, NInput, NButton, useMessage, NInputNumber, NSelect, NTabs, NTabPane, NCheckbox } from "naive-ui"
|
import {
|
||||||
import SDADetailerSetting from "../Components/SDADetailerSetting.vue"
|
NForm,
|
||||||
|
NFormItem,
|
||||||
|
NInput,
|
||||||
|
NButton,
|
||||||
|
useMessage,
|
||||||
|
NInputNumber,
|
||||||
|
NSelect,
|
||||||
|
NTabs,
|
||||||
|
NTabPane,
|
||||||
|
NCheckbox
|
||||||
|
} from 'naive-ui'
|
||||||
|
import SDADetailerSetting from '../Components/SDADetailerSetting.vue'
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
components: {
|
components: {
|
||||||
NForm, NFormItem, NInput, NButton, NInputNumber, NSelect, NTabs, NTabPane, SDADetailerSetting, NCheckbox
|
NForm,
|
||||||
|
NFormItem,
|
||||||
|
NInput,
|
||||||
|
NButton,
|
||||||
|
NInputNumber,
|
||||||
|
NSelect,
|
||||||
|
NTabs,
|
||||||
|
NTabPane,
|
||||||
|
SDADetailerSetting,
|
||||||
|
NCheckbox
|
||||||
},
|
},
|
||||||
setup() {
|
setup() {
|
||||||
let formValue = ref({
|
let formValue = ref({
|
||||||
@ -78,28 +139,62 @@ export default defineComponent({
|
|||||||
height: 0,
|
height: 0,
|
||||||
adetailer: false,
|
adetailer: false,
|
||||||
style_weight: 1,
|
style_weight: 1,
|
||||||
cfg_scale: 1
|
cfg_scale: 1,
|
||||||
|
sd_models: null,
|
||||||
|
lora: null
|
||||||
})
|
})
|
||||||
|
|
||||||
let modelOption = ref([{
|
let samplers_options = ref([])
|
||||||
label: "文生图",
|
let lora_options = ref([])
|
||||||
value: "txt2img"
|
let sd_models_options = ref([])
|
||||||
}, {
|
|
||||||
label: "图生图",
|
let modelOption = ref([
|
||||||
value: "img2img"
|
{
|
||||||
}]);
|
label: '文生图',
|
||||||
|
value: 'txt2img'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '图生图',
|
||||||
|
value: 'img2img'
|
||||||
|
}
|
||||||
|
])
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
await window.api.InitSDConfig((value) => {
|
await window.api.InitSDConfig((value) => {
|
||||||
if (value.code == 0) {
|
if (value.code == 0) {
|
||||||
message.error(value.message);
|
message.error(value.message)
|
||||||
return;
|
return
|
||||||
|
}
|
||||||
|
formValue.value = value.data
|
||||||
|
|
||||||
|
let samplers = value.data.samplers
|
||||||
|
for (let i = 0; i < samplers.length; i++) {
|
||||||
|
const element = samplers[i]
|
||||||
|
samplers_options.value.push({
|
||||||
|
label: element.name,
|
||||||
|
value: element.name
|
||||||
|
})
|
||||||
|
}
|
||||||
|
let loras = value.data.loras
|
||||||
|
for (let i = 0; i < loras.length; i++) {
|
||||||
|
const element = loras[i]
|
||||||
|
lora_options.value.push({
|
||||||
|
label: element.name,
|
||||||
|
value: element.name
|
||||||
|
})
|
||||||
|
}
|
||||||
|
let sd_models = value.data.sd_models
|
||||||
|
for (let i = 0; i < sd_models.length; i++) {
|
||||||
|
const element = sd_models[i]
|
||||||
|
sd_models_options.value.push({
|
||||||
|
label: element.title,
|
||||||
|
value: element.title
|
||||||
|
})
|
||||||
}
|
}
|
||||||
formValue.value = value.data;
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
let message = useMessage();
|
let message = useMessage()
|
||||||
/**
|
/**
|
||||||
* 保存SD设置
|
* 保存SD设置
|
||||||
*/
|
*/
|
||||||
@ -107,26 +202,43 @@ export default defineComponent({
|
|||||||
// 保存SD配置
|
// 保存SD配置
|
||||||
await window.api.SaveSDConfig(toRaw(formValue.value), (value) => {
|
await window.api.SaveSDConfig(toRaw(formValue.value), (value) => {
|
||||||
if (value.code == 0) {
|
if (value.code == 0) {
|
||||||
window.api.showGlobalMessageDialog(value);
|
window.api.showGlobalMessageDialog(value)
|
||||||
return;
|
return
|
||||||
} else if (value.code == 1) {
|
} else if (value.code == 1) {
|
||||||
window.api.showGlobalMessageDialog(value);
|
window.api.showGlobalMessageDialog(value)
|
||||||
window.api.getSettingDafultData((value) => {
|
window.api.getSettingDafultData((value) => {
|
||||||
window.config = value;
|
window.config = value
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
} else {
|
} else {
|
||||||
window.api.showGlobalMessageDialog({ code: 0, message: "未知错误" });
|
window.api.showGlobalMessageDialog({ code: 0, message: '未知错误' })
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 加载SD数据
|
||||||
|
*/
|
||||||
|
async function LoadSDServiceData() {
|
||||||
|
await window.sd.LoadSDServiceData(toRaw(formValue.value).webui_api_url, (value) => {
|
||||||
|
if (value.code == 0) {
|
||||||
|
message.error(value.message)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// formValue.value = value.data
|
||||||
|
message.success('加载成功')
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
formValue,
|
formValue,
|
||||||
SaveSDConfig,
|
SaveSDConfig,
|
||||||
modelOption,
|
modelOption,
|
||||||
|
LoadSDServiceData,
|
||||||
|
samplers_options,
|
||||||
|
lora_options,
|
||||||
|
sd_models_options
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
@ -1,18 +1,20 @@
|
|||||||
<template>
|
<template>
|
||||||
<NSpace vertical>
|
<NSpace vertical>
|
||||||
<n-spin :show="show">
|
<n-spin :show="show">
|
||||||
<template #description>
|
<template #description> 保存中 </template>
|
||||||
保存中
|
|
||||||
</template>
|
|
||||||
<n-form ref="formRef" :model="formValue" :rules="rules">
|
<n-form ref="formRef" :model="formValue" :rules="rules">
|
||||||
<n-form-item path="draft_path" label="剪映草稿地址">
|
<n-form-item path="draft_path" label="剪映草稿地址">
|
||||||
<n-input v-model:value="formValue.draft_path" @keydown.enter.prevent />
|
<n-input v-model:value="formValue.draft_path" @keydown.enter.prevent />
|
||||||
</n-form-item>
|
</n-form-item>
|
||||||
<n-form-item path="project_path" label="项目地址(帧,图片等输出的地址)">
|
<n-form-item path="project_path" label="项目地址(帧,图片等输出的地址)">
|
||||||
<div>
|
<div>
|
||||||
<n-input style="width: 400px;" v-model:value="formValue.project_path" @keydown.enter.prevent />
|
<n-input
|
||||||
|
style="width: 400px"
|
||||||
|
v-model:value="formValue.project_path"
|
||||||
|
@keydown.enter.prevent
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<n-button color="#e5a84b" @click="SelectProjectFolder" style="margin-left: 10px;">
|
<n-button color="#e5a84b" @click="SelectProjectFolder" style="margin-left: 10px">
|
||||||
<n-icon :size="20">
|
<n-icon :size="20">
|
||||||
<folder-open />
|
<folder-open />
|
||||||
</n-icon>
|
</n-icon>
|
||||||
@ -23,78 +25,150 @@
|
|||||||
</n-form-item>
|
</n-form-item>
|
||||||
<n-form-item path="system_setting" label="系统设置">
|
<n-form-item path="system_setting" label="系统设置">
|
||||||
<n-form-item path="task_number" label="后台并行任务数(量力而行)">
|
<n-form-item path="task_number" label="后台并行任务数(量力而行)">
|
||||||
<n-input-number v-model:value="formValue.task_number" @keydown.enter.prevent :min="1" :max="10"
|
<n-input-number
|
||||||
placeholder="输入后台并行任务数" />
|
v-model:value="formValue.task_number"
|
||||||
|
@keydown.enter.prevent
|
||||||
|
:min="1"
|
||||||
|
:max="10"
|
||||||
|
placeholder="输入后台并行任务数"
|
||||||
|
/>
|
||||||
</n-form-item>
|
</n-form-item>
|
||||||
<n-form-item label="系统主题" style="margin-left: 20px;">
|
<n-form-item label="系统主题" style="margin-left: 20px">
|
||||||
<n-switch :rail-style="railStyle" v-model:value="formValue.theme" size="medium"
|
<n-switch
|
||||||
checked-value="dark" unchecked-value="light" @update:value="ChangeMode">
|
:rail-style="railStyle"
|
||||||
<template #checked>
|
v-model:value="formValue.theme"
|
||||||
暗
|
size="medium"
|
||||||
</template>
|
checked-value="dark"
|
||||||
<template #unchecked>
|
unchecked-value="light"
|
||||||
亮
|
@update:value="ChangeMode"
|
||||||
</template>
|
>
|
||||||
|
<template #checked> 暗 </template>
|
||||||
|
<template #unchecked> 亮 </template>
|
||||||
</n-switch>
|
</n-switch>
|
||||||
</n-form-item>
|
</n-form-item>
|
||||||
<n-form-item label="人物场景选择模式" style="margin-left: 20px;">
|
<n-form-item label="人物场景选择模式" style="margin-left: 20px">
|
||||||
<n-select size="small" placeholder="请选择" :options="character_select_model_options"
|
<n-select
|
||||||
v-model:value="formValue.character_select_model" style="width: 120px;" />
|
size="small"
|
||||||
|
placeholder="请选择"
|
||||||
|
:options="character_select_model_options"
|
||||||
|
v-model:value="formValue.character_select_model"
|
||||||
|
style="width: 120px"
|
||||||
|
/>
|
||||||
|
</n-form-item>
|
||||||
|
<n-form-item style="margin-left: 20px"
|
||||||
|
><n-checkbox v-model:checked="formValue.window_wh_bm_remember"
|
||||||
|
>开启窗口大小/位置记忆</n-checkbox
|
||||||
|
>
|
||||||
</n-form-item>
|
</n-form-item>
|
||||||
</n-form-item>
|
</n-form-item>
|
||||||
<n-form-item path="gpt_setting" label="GPT设置">
|
<n-form-item path="gpt_setting" label="GPT设置">
|
||||||
<n-form-item path="gpt_business" label="GPT接口服务商">
|
<n-form-item path="gpt_business" label="GPT接口服务商">
|
||||||
<n-select v-model:value="formValue.gpt_business" :options="gpt_options" placeholder="GPT接口服务商"
|
<n-select
|
||||||
style="width: 200px;" />
|
v-model:value="formValue.gpt_business"
|
||||||
|
:options="gpt_options"
|
||||||
|
placeholder="GPT接口服务商"
|
||||||
|
style="width: 200px"
|
||||||
|
/>
|
||||||
</n-form-item>
|
</n-form-item>
|
||||||
<n-button type="info" @click="openGptBuyUrl">
|
<n-button type="info" @click="openGptBuyUrl"> 购买 </n-button>
|
||||||
购买
|
<n-form-item style="width: 300px; margin-left: 30px" path="gpt_key" label="GPT Key">
|
||||||
</n-button>
|
<n-input
|
||||||
<n-form-item style="width: 300px; margin-left: 30px;" path="gpt_key" label="GPT Key">
|
type="password"
|
||||||
<n-input type="password" show-password-on="mousedown" v-model:value="formValue.gpt_key"
|
show-password-on="mousedown"
|
||||||
@keydown.enter.prevent placeholder="GPT Key" />
|
v-model:value="formValue.gpt_key"
|
||||||
|
@keydown.enter.prevent
|
||||||
|
placeholder="GPT Key"
|
||||||
|
/>
|
||||||
</n-form-item>
|
</n-form-item>
|
||||||
<n-form-item style="margin-left: 30px;" path="gpt_model" label="GPT模型">
|
<n-form-item style="margin-left: 30px" path="gpt_model" label="GPT模型">
|
||||||
<n-select v-model:value="formValue.gpt_model" :options="gpt_model_options" placeholder="GPT模型"
|
<n-select
|
||||||
style="width: 160px;" />
|
v-model:value="formValue.gpt_model"
|
||||||
|
:options="gpt_model_options"
|
||||||
|
placeholder="GPT模型"
|
||||||
|
style="width: 160px"
|
||||||
|
/>
|
||||||
</n-form-item>
|
</n-form-item>
|
||||||
|
|
||||||
<n-form-item style="margin-left: 30px;" path="gpt_count" label="推理上下文行数">
|
<n-form-item style="margin-left: 30px" path="gpt_count" label="推理上下文行数">
|
||||||
<n-input-number v-model:value="formValue.gpt_count" placeholder="GPT模型" style="width: 150px;"
|
<n-input-number
|
||||||
:show-button="false" :min="1" :max="100" />
|
v-model:value="formValue.gpt_count"
|
||||||
|
placeholder="GPT模型"
|
||||||
|
style="width: 150px"
|
||||||
|
:show-button="false"
|
||||||
|
:min="1"
|
||||||
|
:max="100"
|
||||||
|
/>
|
||||||
</n-form-item>
|
</n-form-item>
|
||||||
<n-button color="#e18a3b" @click="addGptOption" style="margin-left: 10px;">
|
<n-button color="#e18a3b" @click="addGptOption" style="margin-left: 10px">
|
||||||
添加GPT
|
添加GPT
|
||||||
</n-button>
|
</n-button>
|
||||||
<n-button color="#779649" @click="TestGPTConnection" :loading="loading" style="margin-left: 10px;">
|
<n-button
|
||||||
|
color="#779649"
|
||||||
|
@click="TestGPTConnection"
|
||||||
|
:loading="loading"
|
||||||
|
style="margin-left: 10px"
|
||||||
|
>
|
||||||
测试链接
|
测试链接
|
||||||
</n-button>
|
</n-button>
|
||||||
<n-button color="#ba5b49" @click="AddGptPrompt" style="margin-left: 10px;">
|
<n-button color="#ba5b49" @click="AddGptPrompt" style="margin-left: 10px">
|
||||||
添加GPT提示词
|
添加GPT提示词
|
||||||
</n-button>
|
</n-button>
|
||||||
|
|
||||||
</n-form-item>
|
</n-form-item>
|
||||||
<n-form-item path="translation_setting" label="翻译设置">
|
<n-form-item path="translation_setting" label="翻译设置">
|
||||||
<n-form-item path="translation_business" label="翻译服务商">
|
<n-form-item path="translation_business" label="翻译服务商">
|
||||||
<n-select v-model:value="formValue.translation_business" :options="translation_options"
|
<n-select
|
||||||
@update:value="SwitchTranslate" placeholder="翻译服务商" style="width: 200px;" />
|
v-model:value="formValue.translation_business"
|
||||||
|
:options="translation_options"
|
||||||
|
@update:value="SwitchTranslate"
|
||||||
|
placeholder="翻译服务商"
|
||||||
|
style="width: 200px"
|
||||||
|
/>
|
||||||
</n-form-item>
|
</n-form-item>
|
||||||
<n-form-item path="translation_app_id" label="APP ID" style="width: 300px; margin-left: 30px;">
|
<n-form-item
|
||||||
<n-input type="password" show-password-on="mousedown"
|
path="translation_app_id"
|
||||||
v-model:value="formValue.translation_app_id" @keydown.enter.prevent placeholder="APP ID" />
|
label="APP ID"
|
||||||
|
style="width: 300px; margin-left: 30px"
|
||||||
|
>
|
||||||
|
<n-input
|
||||||
|
type="password"
|
||||||
|
show-password-on="mousedown"
|
||||||
|
v-model:value="formValue.translation_app_id"
|
||||||
|
@keydown.enter.prevent
|
||||||
|
placeholder="APP ID"
|
||||||
|
/>
|
||||||
</n-form-item>
|
</n-form-item>
|
||||||
<n-form-item path="translation_secret" label="产品密钥" style="width: 300px; margin-left: 30px;">
|
<n-form-item
|
||||||
<n-input type="password" show-password-on="mousedown"
|
path="translation_secret"
|
||||||
v-model:value="formValue.translation_secret" placeholder="请输入产品密钥"></n-input>
|
label="产品密钥"
|
||||||
|
style="width: 300px; margin-left: 30px"
|
||||||
|
>
|
||||||
|
<n-input
|
||||||
|
type="password"
|
||||||
|
show-password-on="mousedown"
|
||||||
|
v-model:value="formValue.translation_secret"
|
||||||
|
placeholder="请输入产品密钥"
|
||||||
|
></n-input>
|
||||||
</n-form-item>
|
</n-form-item>
|
||||||
<n-form-item path="translation_secret" label="自动翻译" style="width: 300px; margin-left: 30px;">
|
<n-form-item
|
||||||
<n-checkbox v-model:checked="formValue.translation_auto" placeholder="请输入产品密钥"></n-checkbox>
|
path="translation_secret"
|
||||||
|
label="自动翻译"
|
||||||
|
style="width: 300px; margin-left: 30px"
|
||||||
|
>
|
||||||
|
<n-checkbox v-model:checked="formValue.translation_auto"></n-checkbox>
|
||||||
</n-form-item>
|
</n-form-item>
|
||||||
</n-form-item>
|
</n-form-item>
|
||||||
<n-form-item>
|
<n-form-item>
|
||||||
<n-button
|
<n-button
|
||||||
:disabled="formValue.draft_path == null || formValue.draft_path == '' || formValue.project_path == null || formValue.project_path == ''"
|
:disabled="
|
||||||
round type="primary" @click="handleValidateButtonClick">
|
formValue.draft_path == null ||
|
||||||
|
formValue.draft_path == '' ||
|
||||||
|
formValue.project_path == null ||
|
||||||
|
formValue.project_path == ''
|
||||||
|
"
|
||||||
|
round
|
||||||
|
type="primary"
|
||||||
|
@click="handleValidateButtonClick"
|
||||||
|
>
|
||||||
保存
|
保存
|
||||||
</n-button>
|
</n-button>
|
||||||
</n-form-item>
|
</n-form-item>
|
||||||
@ -104,18 +178,43 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { ref, toRaw, onMounted, defineComponent, h } from "vue"
|
import { ref, toRaw, onMounted, defineComponent, h } from 'vue'
|
||||||
import { NForm, NFormItem, NInput, NInputNumber, useDialog, NButton, NSpace, NSpin, useMessage, NSelect, NCheckbox, NSwitch, NIcon } from "naive-ui"
|
import {
|
||||||
import AddGptOption from "./Components/AddGptOption.vue";
|
NForm,
|
||||||
|
NFormItem,
|
||||||
|
NInput,
|
||||||
|
NInputNumber,
|
||||||
|
useDialog,
|
||||||
|
NButton,
|
||||||
|
NSpace,
|
||||||
|
NSpin,
|
||||||
|
useMessage,
|
||||||
|
NSelect,
|
||||||
|
NCheckbox,
|
||||||
|
NSwitch,
|
||||||
|
NIcon
|
||||||
|
} from 'naive-ui'
|
||||||
|
import AddGptOption from './Components/AddGptOption.vue'
|
||||||
import { FolderOpenSharp as FolderOpen } from '@vicons/ionicons5'
|
import { FolderOpenSharp as FolderOpen } from '@vicons/ionicons5'
|
||||||
import AddGptPrompts from './Components/AddGptPrompts.vue'
|
import AddGptPrompts from './Components/AddGptPrompts.vue'
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
components: {
|
components: {
|
||||||
NForm, NFormItem, NInput, NInputNumber, NButton, NSpace, NSpin, NSelect, NCheckbox, NSwitch, FolderOpen, NIcon
|
NForm,
|
||||||
|
NFormItem,
|
||||||
|
NInput,
|
||||||
|
NInputNumber,
|
||||||
|
NButton,
|
||||||
|
NSpace,
|
||||||
|
NSpin,
|
||||||
|
NSelect,
|
||||||
|
NCheckbox,
|
||||||
|
NSwitch,
|
||||||
|
FolderOpen,
|
||||||
|
NIcon
|
||||||
},
|
},
|
||||||
setup() {
|
setup() {
|
||||||
let formRef = ref(null);
|
let formRef = ref(null)
|
||||||
let message = useMessage()
|
let message = useMessage()
|
||||||
let formValue = ref({
|
let formValue = ref({
|
||||||
draft_path: window.config.draft_path,
|
draft_path: window.config.draft_path,
|
||||||
@ -131,145 +230,144 @@ export default defineComponent({
|
|||||||
translation_secret: window.config.translation_secret,
|
translation_secret: window.config.translation_secret,
|
||||||
translation_auto: window.config.translation_auto,
|
translation_auto: window.config.translation_auto,
|
||||||
theme: window.config.theme,
|
theme: window.config.theme,
|
||||||
character_select_model: window.config.character_select_model
|
character_select_model: window.config.character_select_model,
|
||||||
});
|
window_wh_bm_remember: window.config.window_wh_bm_remember
|
||||||
|
})
|
||||||
let show = ref(false)
|
let show = ref(false)
|
||||||
let gpt_options = ref([]);
|
let gpt_options = ref([])
|
||||||
let gpt_model_options = ref([]);
|
let gpt_model_options = ref([])
|
||||||
let character_select_model_options = ref([])
|
let character_select_model_options = ref([])
|
||||||
let dialog = useDialog();
|
let dialog = useDialog()
|
||||||
let loading = ref(false);
|
let loading = ref(false)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 加载GPT的配置信息
|
* 加载GPT的配置信息
|
||||||
*/
|
*/
|
||||||
async function InitGptOptions() {
|
async function InitGptOptions() {
|
||||||
debugger;
|
debugger
|
||||||
await window.api.getGptBusinessOption("all", (value) => {
|
await window.api.getGptBusinessOption('all', (value) => {
|
||||||
if (value.code == 0) {
|
if (value.code == 0) {
|
||||||
message.error(value.message);
|
message.error(value.message)
|
||||||
return;
|
return
|
||||||
}
|
}
|
||||||
gpt_options.value = value.data;
|
gpt_options.value = value.data
|
||||||
})
|
})
|
||||||
|
|
||||||
await window.api.getGptModelOption("all", (value) => {
|
await window.api.getGptModelOption('all', (value) => {
|
||||||
if (value.code == 0) {
|
if (value.code == 0) {
|
||||||
message.error(value.message);
|
message.error(value.message)
|
||||||
return;
|
return
|
||||||
}
|
}
|
||||||
gpt_model_options.value = value.data;
|
gpt_model_options.value = value.data
|
||||||
})
|
})
|
||||||
|
|
||||||
await window.mj.GetTagSelectModel(value => {
|
await window.mj.GetTagSelectModel((value) => {
|
||||||
character_select_model_options.value = value.data;
|
character_select_model_options.value = value.data
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
await InitGptOptions();
|
await InitGptOptions()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
let translation_options = [
|
||||||
let translation_options = [{
|
{
|
||||||
label: "百度翻译",
|
label: '百度翻译',
|
||||||
value: "https://fanyi-api.baidu.com/api/trans/vip/translate"
|
value: 'https://fanyi-api.baidu.com/api/trans/vip/translate'
|
||||||
}, {
|
|
||||||
label: "火山引擎",
|
|
||||||
value: "https://translate.volcengineapi.com?"
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "腾讯翻译",
|
label: '火山引擎',
|
||||||
value: "https://tmt.tencentcloudapi.com"
|
value: 'https://translate.volcengineapi.com?'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "阿里翻译",
|
label: '腾讯翻译',
|
||||||
value: "https://mt.cn-hangzhou.aliyuncs.com"
|
value: 'https://tmt.tencentcloudapi.com'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '阿里翻译',
|
||||||
|
value: 'https://mt.cn-hangzhou.aliyuncs.com'
|
||||||
}
|
}
|
||||||
];
|
]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// 切换翻译服务商事件
|
// 切换翻译服务商事件
|
||||||
function SwitchTranslate(value, option) {
|
function SwitchTranslate(value, option) {
|
||||||
// 将之前的数据全部删除
|
// 将之前的数据全部删除
|
||||||
formValue.value.translation_app_id = null;
|
formValue.value.translation_app_id = null
|
||||||
formValue.value.translation_secret = null;
|
formValue.value.translation_secret = null
|
||||||
}
|
}
|
||||||
|
|
||||||
let ruleObj = (errorMessage) => {
|
let ruleObj = (errorMessage) => {
|
||||||
return [{
|
return [
|
||||||
|
{
|
||||||
required: true,
|
required: true,
|
||||||
validator(rule, value) {
|
validator(rule, value) {
|
||||||
if (value == null || value == "")
|
if (value == null || value == '') return new Error(errorMessage)
|
||||||
return new Error(errorMessage);
|
return true
|
||||||
return true;
|
|
||||||
},
|
},
|
||||||
trigger: ["input", "blur", "change"]
|
trigger: ['input', 'blur', 'change']
|
||||||
}]
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
let rules = {
|
let rules = {
|
||||||
draft_path: ruleObj("必填剪映草稿地址"),
|
draft_path: ruleObj('必填剪映草稿地址'),
|
||||||
project_path: ruleObj("必填项目地址"),
|
project_path: ruleObj('必填项目地址'),
|
||||||
project_name: ruleObj("必填项目名称"),
|
project_name: ruleObj('必填项目名称'),
|
||||||
task_number: ruleObj("必填后台并行任务数"),
|
task_number: ruleObj('必填后台并行任务数'),
|
||||||
gpt_business: ruleObj("必填GPT接口服务商"),
|
gpt_business: ruleObj('必填GPT接口服务商'),
|
||||||
gpt_key: ruleObj("必填GPT Key"),
|
gpt_key: ruleObj('必填GPT Key'),
|
||||||
gpt_model: ruleObj("必填GPT模型"),
|
gpt_model: ruleObj('必填GPT模型'),
|
||||||
gpt_count: ruleObj("必填自动推理上下文行数"),
|
gpt_count: ruleObj('必填自动推理上下文行数'),
|
||||||
translation_secret: ruleObj("必填产品密钥"),
|
translation_secret: ruleObj('必填产品密钥'),
|
||||||
translation_app_id: ruleObj("必填APP ID"),
|
translation_app_id: ruleObj('必填APP ID'),
|
||||||
translation_business: ruleObj("必填翻译服务商"),
|
translation_business: ruleObj('必填翻译服务商')
|
||||||
};
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 保存配置信息
|
* 保存配置信息
|
||||||
*/
|
*/
|
||||||
function handleValidateButtonClick(e) {
|
function handleValidateButtonClick(e) {
|
||||||
e.preventDefault();
|
e.preventDefault()
|
||||||
formRef.value?.validate((errors) => {
|
formRef.value?.validate((errors) => {
|
||||||
if (errors) {
|
if (errors) {
|
||||||
message.error("请检查必填字段");
|
message.error('请检查必填字段')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// 保存文件
|
// 保存文件
|
||||||
window.api.ModifySampleSetting(JSON.stringify(toRaw(formValue.value)), (value) => {
|
window.api.ModifySampleSetting(JSON.stringify(toRaw(formValue.value)), (value) => {
|
||||||
if (value.code == 1) {
|
if (value.code == 1) {
|
||||||
window.api.getSettingDafultData((value) => {
|
window.api.getSettingDafultData((value) => {
|
||||||
window.config = value;
|
window.config = value
|
||||||
})
|
})
|
||||||
window.api.showGlobalMessageDialog({ code: 1, message: value.message })
|
window.api.showGlobalMessageDialog({ code: 1, message: value.message })
|
||||||
} else {
|
} else {
|
||||||
window.api.showGlobalMessageDialog({ code: 0, message: value.message })
|
window.api.showGlobalMessageDialog({ code: 0, message: value.message })
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
let railStyle = (focused,
|
let railStyle = (focused, checked) => {
|
||||||
checked) => {
|
const style = {}
|
||||||
const style = {};
|
|
||||||
if (checked) {
|
if (checked) {
|
||||||
style.background = "#f3a694";
|
style.background = '#f3a694'
|
||||||
if (focused) {
|
if (focused) {
|
||||||
style.boxShadow = "0 0 0 2px #f3a694";
|
style.boxShadow = '0 0 0 2px #f3a694'
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
style.background = "#775039";
|
style.background = '#775039'
|
||||||
if (focused) {
|
if (focused) {
|
||||||
style.boxShadow = "0 0 0 2px #775039";
|
style.boxShadow = '0 0 0 2px #775039'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return style;
|
return style
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 打开购买GPT的地址
|
* 打开购买GPT的地址
|
||||||
*/
|
*/
|
||||||
async function openGptBuyUrl() {
|
async function openGptBuyUrl() {
|
||||||
window.api.openGptBuyUrl(toRaw(formValue.value.gpt_business));
|
window.api.openGptBuyUrl(toRaw(formValue.value.gpt_business))
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -288,19 +386,19 @@ export default defineComponent({
|
|||||||
async function addGptOption() {
|
async function addGptOption() {
|
||||||
// 判断当前数据是不是存在
|
// 判断当前数据是不是存在
|
||||||
// 处理数据。获取当前的所有的数据
|
// 处理数据。获取当前的所有的数据
|
||||||
let dialogWidth = 600;
|
let dialogWidth = 600
|
||||||
let dialogHeight = 450;
|
let dialogHeight = 450
|
||||||
// ImportWordAndSrt
|
// ImportWordAndSrt
|
||||||
dialog.create({
|
dialog.create({
|
||||||
showIcon: false,
|
showIcon: false,
|
||||||
closeOnEsc: false,
|
closeOnEsc: false,
|
||||||
title: "添加GPT地址或者模型",
|
title: '添加GPT地址或者模型',
|
||||||
content: () => h(AddGptOption, {}),
|
content: () => h(AddGptOption, {}),
|
||||||
style: `width : ${dialogWidth}px; min-height : ${dialogHeight}px`,
|
style: `width : ${dialogWidth}px; min-height : ${dialogHeight}px`,
|
||||||
maskClosable: false,
|
maskClosable: false,
|
||||||
onClose: async () => {
|
onClose: async () => {
|
||||||
// 刷新界面数据
|
// 刷新界面数据
|
||||||
await InitGptOptions();
|
await InitGptOptions()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -309,15 +407,18 @@ export default defineComponent({
|
|||||||
* 测试当前GPT是不是可以链接成功
|
* 测试当前GPT是不是可以链接成功
|
||||||
*/
|
*/
|
||||||
async function TestGPTConnection() {
|
async function TestGPTConnection() {
|
||||||
loading.value = true;
|
loading.value = true
|
||||||
// 测试链接
|
// 测试链接
|
||||||
await window.api.TestGPTConnection(JSON.stringify(formValue.value), (value) => {
|
await window.api.TestGPTConnection(JSON.stringify(formValue.value), (value) => {
|
||||||
loading.value = false;
|
loading.value = false
|
||||||
if (value.code == 0) {
|
if (value.code == 0) {
|
||||||
window.api.showGlobalMessageDialog({ code: 0, message: "GPT链接失败,错误信息: " + value.message })
|
window.api.showGlobalMessageDialog({
|
||||||
return;
|
code: 0,
|
||||||
|
message: 'GPT链接失败,错误信息: ' + value.message
|
||||||
|
})
|
||||||
|
return
|
||||||
}
|
}
|
||||||
window.api.showGlobalMessageDialog({ code: 1, message: "gpt链接测试成功,可以正常使用!" })
|
window.api.showGlobalMessageDialog({ code: 1, message: 'gpt链接测试成功,可以正常使用!' })
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -325,11 +426,14 @@ export default defineComponent({
|
|||||||
* 选择项目文件夹
|
* 选择项目文件夹
|
||||||
*/
|
*/
|
||||||
async function SelectProjectFolder() {
|
async function SelectProjectFolder() {
|
||||||
await window.api.selectFolder({ default_paht: toRaw(formValue.value).project_path }, (value) => {
|
await window.api.selectFolder(
|
||||||
|
{ default_paht: toRaw(formValue.value).project_path },
|
||||||
|
(value) => {
|
||||||
if (value.length > 0) {
|
if (value.length > 0) {
|
||||||
formValue.value.project_path = value[0]
|
formValue.value.project_path = value[0]
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -338,18 +442,17 @@ export default defineComponent({
|
|||||||
async function AddGptPrompt() {
|
async function AddGptPrompt() {
|
||||||
// 判断当前数据是不是存在
|
// 判断当前数据是不是存在
|
||||||
// 处理数据。获取当前的所有的数据
|
// 处理数据。获取当前的所有的数据
|
||||||
let dialogWidth = 600;
|
let dialogWidth = 600
|
||||||
let dialogHeight = window.innerHeight * 0.9;
|
let dialogHeight = window.innerHeight * 0.9
|
||||||
// ImportWordAndSrt
|
// ImportWordAndSrt
|
||||||
dialog.create({
|
dialog.create({
|
||||||
showIcon: false,
|
showIcon: false,
|
||||||
closeOnEsc: false,
|
closeOnEsc: false,
|
||||||
title: "添加GPT提示词预设",
|
title: '添加GPT提示词预设',
|
||||||
content: () => h(AddGptPrompts, { height: dialogHeight }),
|
content: () => h(AddGptPrompts, { height: dialogHeight }),
|
||||||
style: `width : ${dialogWidth}px; height : ${dialogHeight}px; padding-right : 3px `,
|
style: `width : ${dialogWidth}px; height : ${dialogHeight}px; padding-right : 3px `,
|
||||||
maskClosable: false,
|
maskClosable: false,
|
||||||
onClose: () => {
|
onClose: () => {}
|
||||||
}
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -371,9 +474,8 @@ export default defineComponent({
|
|||||||
loading,
|
loading,
|
||||||
SelectProjectFolder,
|
SelectProjectFolder,
|
||||||
AddGptPrompt,
|
AddGptPrompt,
|
||||||
character_select_model_options,
|
character_select_model_options
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
Loading…
x
Reference in New Issue
Block a user