feat:部分功能优化
All checks were successful
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 2m1s
All checks were successful
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 2m1s
This commit is contained in:
parent
bfde0250e3
commit
e3f81d4f7b
519
package-lock.json
generated
519
package-lock.json
generated
@ -11,6 +11,7 @@
|
|||||||
"@bddh/starling-realtime-client": "^2.0.9",
|
"@bddh/starling-realtime-client": "^2.0.9",
|
||||||
"crypto-js": "^4.2.0",
|
"crypto-js": "^4.2.0",
|
||||||
"element-plus": "^2.9.7",
|
"element-plus": "^2.9.7",
|
||||||
|
"opencc-js": "^1.4.0",
|
||||||
"uuid": "^9.0.1",
|
"uuid": "^9.0.1",
|
||||||
"vue": "^3.5.13"
|
"vue": "^3.5.13"
|
||||||
},
|
},
|
||||||
@ -2010,24 +2011,6 @@
|
|||||||
"node": ">=12"
|
"node": ">=12"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@esbuild/netbsd-arm64": {
|
|
||||||
"version": "0.28.0",
|
|
||||||
"resolved": "https://registry.npmmirror.com/@esbuild/netbsd-arm64/-/netbsd-arm64-0.28.0.tgz",
|
|
||||||
"integrity": "sha512-CR/RYotgtCKwtftMwJlUU7xCVNg3lMYZ0RzTmAHSfLCXw3NtZtNpswLEj/Kkf6kEL3Gw+BpOekRX0BYCtklhUw==",
|
|
||||||
"cpu": [
|
|
||||||
"arm64"
|
|
||||||
],
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"optional": true,
|
|
||||||
"os": [
|
|
||||||
"netbsd"
|
|
||||||
],
|
|
||||||
"peer": true,
|
|
||||||
"engines": {
|
|
||||||
"node": ">=18"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@esbuild/netbsd-x64": {
|
"node_modules/@esbuild/netbsd-x64": {
|
||||||
"version": "0.21.5",
|
"version": "0.21.5",
|
||||||
"resolved": "https://registry.npmmirror.com/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz",
|
"resolved": "https://registry.npmmirror.com/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz",
|
||||||
@ -2045,24 +2028,6 @@
|
|||||||
"node": ">=12"
|
"node": ">=12"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@esbuild/openbsd-arm64": {
|
|
||||||
"version": "0.28.0",
|
|
||||||
"resolved": "https://registry.npmmirror.com/@esbuild/openbsd-arm64/-/openbsd-arm64-0.28.0.tgz",
|
|
||||||
"integrity": "sha512-cXb5vApOsRsxsEl4mcZ1XY3D4DzcoMxR/nnc4IyqYs0rTI8ZKmW6kyyg+11Z8yvgMfAEldKzP7AdP64HnSC/6g==",
|
|
||||||
"cpu": [
|
|
||||||
"arm64"
|
|
||||||
],
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"optional": true,
|
|
||||||
"os": [
|
|
||||||
"openbsd"
|
|
||||||
],
|
|
||||||
"peer": true,
|
|
||||||
"engines": {
|
|
||||||
"node": ">=18"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@esbuild/openbsd-x64": {
|
"node_modules/@esbuild/openbsd-x64": {
|
||||||
"version": "0.21.5",
|
"version": "0.21.5",
|
||||||
"resolved": "https://registry.npmmirror.com/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz",
|
"resolved": "https://registry.npmmirror.com/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz",
|
||||||
@ -2080,24 +2045,6 @@
|
|||||||
"node": ">=12"
|
"node": ">=12"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@esbuild/openharmony-arm64": {
|
|
||||||
"version": "0.28.0",
|
|
||||||
"resolved": "https://registry.npmmirror.com/@esbuild/openharmony-arm64/-/openharmony-arm64-0.28.0.tgz",
|
|
||||||
"integrity": "sha512-FLGfyizszcef5C3YtoyQDACyg95+dndv79i2EekILBofh5wpCa1KuBqOWKrEHZg3zrL3t5ouE5jgr94vA+Wb2w==",
|
|
||||||
"cpu": [
|
|
||||||
"arm64"
|
|
||||||
],
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"optional": true,
|
|
||||||
"os": [
|
|
||||||
"openharmony"
|
|
||||||
],
|
|
||||||
"peer": true,
|
|
||||||
"engines": {
|
|
||||||
"node": ">=18"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@esbuild/sunos-x64": {
|
"node_modules/@esbuild/sunos-x64": {
|
||||||
"version": "0.21.5",
|
"version": "0.21.5",
|
||||||
"resolved": "https://registry.npmmirror.com/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz",
|
"resolved": "https://registry.npmmirror.com/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz",
|
||||||
@ -4546,6 +4493,12 @@
|
|||||||
"node": ">=12.20.0"
|
"node": ">=12.20.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/opencc-js": {
|
||||||
|
"version": "1.4.0",
|
||||||
|
"resolved": "https://registry.npmmirror.com/opencc-js/-/opencc-js-1.4.0.tgz",
|
||||||
|
"integrity": "sha512-SEb4huI5+lT4CFPA4sgs+NAOOgpcmdHZ+vYxhRLR1bQWIt6VRwpFPjWgTJAWAg1MviDcXTBe5zVoUOVxVxNK8w==",
|
||||||
|
"license": "MIT AND Apache-2.0"
|
||||||
|
},
|
||||||
"node_modules/path-parse": {
|
"node_modules/path-parse": {
|
||||||
"version": "1.0.7",
|
"version": "1.0.7",
|
||||||
"resolved": "https://registry.npmmirror.com/path-parse/-/path-parse-1.0.7.tgz",
|
"resolved": "https://registry.npmmirror.com/path-parse/-/path-parse-1.0.7.tgz",
|
||||||
@ -5258,420 +5211,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/vitest/node_modules/@esbuild/aix-ppc64": {
|
|
||||||
"version": "0.28.0",
|
|
||||||
"resolved": "https://registry.npmmirror.com/@esbuild/aix-ppc64/-/aix-ppc64-0.28.0.tgz",
|
|
||||||
"integrity": "sha512-lhRUCeuOyJQURhTxl4WkpFTjIsbDayJHih5kZC1giwE+MhIzAb7mEsQMqMf18rHLsrb5qI1tafG20mLxEWcWlA==",
|
|
||||||
"cpu": [
|
|
||||||
"ppc64"
|
|
||||||
],
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"optional": true,
|
|
||||||
"os": [
|
|
||||||
"aix"
|
|
||||||
],
|
|
||||||
"peer": true,
|
|
||||||
"engines": {
|
|
||||||
"node": ">=18"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/vitest/node_modules/@esbuild/android-arm": {
|
|
||||||
"version": "0.28.0",
|
|
||||||
"resolved": "https://registry.npmmirror.com/@esbuild/android-arm/-/android-arm-0.28.0.tgz",
|
|
||||||
"integrity": "sha512-wqh0ByljabXLKHeWXYLqoJ5jKC4XBaw6Hk08OfMrCRd2nP2ZQ5eleDZC41XHyCNgktBGYMbqnrJKq/K/lzPMSQ==",
|
|
||||||
"cpu": [
|
|
||||||
"arm"
|
|
||||||
],
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"optional": true,
|
|
||||||
"os": [
|
|
||||||
"android"
|
|
||||||
],
|
|
||||||
"peer": true,
|
|
||||||
"engines": {
|
|
||||||
"node": ">=18"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/vitest/node_modules/@esbuild/android-arm64": {
|
|
||||||
"version": "0.28.0",
|
|
||||||
"resolved": "https://registry.npmmirror.com/@esbuild/android-arm64/-/android-arm64-0.28.0.tgz",
|
|
||||||
"integrity": "sha512-+WzIXQOSaGs33tLEgYPYe/yQHf0WTU0X42Jca3y8NWMbUVhp7rUnw+vAsRC/QiDrdD31IszMrZy+qwPOPjd+rw==",
|
|
||||||
"cpu": [
|
|
||||||
"arm64"
|
|
||||||
],
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"optional": true,
|
|
||||||
"os": [
|
|
||||||
"android"
|
|
||||||
],
|
|
||||||
"peer": true,
|
|
||||||
"engines": {
|
|
||||||
"node": ">=18"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/vitest/node_modules/@esbuild/android-x64": {
|
|
||||||
"version": "0.28.0",
|
|
||||||
"resolved": "https://registry.npmmirror.com/@esbuild/android-x64/-/android-x64-0.28.0.tgz",
|
|
||||||
"integrity": "sha512-+VJggoaKhk2VNNqVL7f6S189UzShHC/mR9EE8rDdSkdpN0KflSwWY/gWjDrNxxisg8Fp1ZCD9jLMo4m0OUfeUA==",
|
|
||||||
"cpu": [
|
|
||||||
"x64"
|
|
||||||
],
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"optional": true,
|
|
||||||
"os": [
|
|
||||||
"android"
|
|
||||||
],
|
|
||||||
"peer": true,
|
|
||||||
"engines": {
|
|
||||||
"node": ">=18"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/vitest/node_modules/@esbuild/darwin-arm64": {
|
|
||||||
"version": "0.28.0",
|
|
||||||
"resolved": "https://registry.npmmirror.com/@esbuild/darwin-arm64/-/darwin-arm64-0.28.0.tgz",
|
|
||||||
"integrity": "sha512-0T+A9WZm+bZ84nZBtk1ckYsOvyA3x7e2Acj1KdVfV4/2tdG4fzUp91YHx+GArWLtwqp77pBXVCPn2We7Letr0Q==",
|
|
||||||
"cpu": [
|
|
||||||
"arm64"
|
|
||||||
],
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"optional": true,
|
|
||||||
"os": [
|
|
||||||
"darwin"
|
|
||||||
],
|
|
||||||
"peer": true,
|
|
||||||
"engines": {
|
|
||||||
"node": ">=18"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/vitest/node_modules/@esbuild/darwin-x64": {
|
|
||||||
"version": "0.28.0",
|
|
||||||
"resolved": "https://registry.npmmirror.com/@esbuild/darwin-x64/-/darwin-x64-0.28.0.tgz",
|
|
||||||
"integrity": "sha512-fyzLm/DLDl/84OCfp2f/XQ4flmORsjU7VKt8HLjvIXChJoFFOIL6pLJPH4Yhd1n1gGFF9mPwtlN5Wf82DZs+LQ==",
|
|
||||||
"cpu": [
|
|
||||||
"x64"
|
|
||||||
],
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"optional": true,
|
|
||||||
"os": [
|
|
||||||
"darwin"
|
|
||||||
],
|
|
||||||
"peer": true,
|
|
||||||
"engines": {
|
|
||||||
"node": ">=18"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/vitest/node_modules/@esbuild/freebsd-arm64": {
|
|
||||||
"version": "0.28.0",
|
|
||||||
"resolved": "https://registry.npmmirror.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.28.0.tgz",
|
|
||||||
"integrity": "sha512-l9GeW5UZBT9k9brBYI+0WDffcRxgHQD8ShN2Ur4xWq/NFzUKm3k5lsH4PdaRgb2w7mI9u61nr2gI2mLI27Nh3Q==",
|
|
||||||
"cpu": [
|
|
||||||
"arm64"
|
|
||||||
],
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"optional": true,
|
|
||||||
"os": [
|
|
||||||
"freebsd"
|
|
||||||
],
|
|
||||||
"peer": true,
|
|
||||||
"engines": {
|
|
||||||
"node": ">=18"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/vitest/node_modules/@esbuild/freebsd-x64": {
|
|
||||||
"version": "0.28.0",
|
|
||||||
"resolved": "https://registry.npmmirror.com/@esbuild/freebsd-x64/-/freebsd-x64-0.28.0.tgz",
|
|
||||||
"integrity": "sha512-BXoQai/A0wPO6Es3yFJ7APCiKGc1tdAEOgeTNy3SsB491S3aHn4S4r3e976eUnPdU+NbdtmBuLncYir2tMU9Nw==",
|
|
||||||
"cpu": [
|
|
||||||
"x64"
|
|
||||||
],
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"optional": true,
|
|
||||||
"os": [
|
|
||||||
"freebsd"
|
|
||||||
],
|
|
||||||
"peer": true,
|
|
||||||
"engines": {
|
|
||||||
"node": ">=18"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/vitest/node_modules/@esbuild/linux-arm": {
|
|
||||||
"version": "0.28.0",
|
|
||||||
"resolved": "https://registry.npmmirror.com/@esbuild/linux-arm/-/linux-arm-0.28.0.tgz",
|
|
||||||
"integrity": "sha512-CjaaREJagqJp7iTaNQjjidaNbCKYcd4IDkzbwwxtSvjI7NZm79qiHc8HqciMddQ6CKvJT6aBd8lO9kN/ZudLlw==",
|
|
||||||
"cpu": [
|
|
||||||
"arm"
|
|
||||||
],
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"optional": true,
|
|
||||||
"os": [
|
|
||||||
"linux"
|
|
||||||
],
|
|
||||||
"peer": true,
|
|
||||||
"engines": {
|
|
||||||
"node": ">=18"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/vitest/node_modules/@esbuild/linux-arm64": {
|
|
||||||
"version": "0.28.0",
|
|
||||||
"resolved": "https://registry.npmmirror.com/@esbuild/linux-arm64/-/linux-arm64-0.28.0.tgz",
|
|
||||||
"integrity": "sha512-RVyzfb3FWsGA55n6WY0MEIEPURL1FcbhFE6BffZEMEekfCzCIMtB5yyDcFnVbTnwk+CLAgTujmV/Lgvih56W+A==",
|
|
||||||
"cpu": [
|
|
||||||
"arm64"
|
|
||||||
],
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"optional": true,
|
|
||||||
"os": [
|
|
||||||
"linux"
|
|
||||||
],
|
|
||||||
"peer": true,
|
|
||||||
"engines": {
|
|
||||||
"node": ">=18"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/vitest/node_modules/@esbuild/linux-ia32": {
|
|
||||||
"version": "0.28.0",
|
|
||||||
"resolved": "https://registry.npmmirror.com/@esbuild/linux-ia32/-/linux-ia32-0.28.0.tgz",
|
|
||||||
"integrity": "sha512-KBnSTt1kxl9x70q+ydterVdl+Cn0H18ngRMRCEQfrbqdUuntQQ0LoMZv47uB97NljZFzY6HcfqEZ2SAyIUTQBQ==",
|
|
||||||
"cpu": [
|
|
||||||
"ia32"
|
|
||||||
],
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"optional": true,
|
|
||||||
"os": [
|
|
||||||
"linux"
|
|
||||||
],
|
|
||||||
"peer": true,
|
|
||||||
"engines": {
|
|
||||||
"node": ">=18"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/vitest/node_modules/@esbuild/linux-loong64": {
|
|
||||||
"version": "0.28.0",
|
|
||||||
"resolved": "https://registry.npmmirror.com/@esbuild/linux-loong64/-/linux-loong64-0.28.0.tgz",
|
|
||||||
"integrity": "sha512-zpSlUce1mnxzgBADvxKXX5sl8aYQHo2ezvMNI8I0lbblJtp8V4odlm3Yzlj7gPyt3T8ReksE6bK+pT3WD+aJRg==",
|
|
||||||
"cpu": [
|
|
||||||
"loong64"
|
|
||||||
],
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"optional": true,
|
|
||||||
"os": [
|
|
||||||
"linux"
|
|
||||||
],
|
|
||||||
"peer": true,
|
|
||||||
"engines": {
|
|
||||||
"node": ">=18"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/vitest/node_modules/@esbuild/linux-mips64el": {
|
|
||||||
"version": "0.28.0",
|
|
||||||
"resolved": "https://registry.npmmirror.com/@esbuild/linux-mips64el/-/linux-mips64el-0.28.0.tgz",
|
|
||||||
"integrity": "sha512-2jIfP6mmjkdmeTlsX/9vmdmhBmKADrWqN7zcdtHIeNSCH1SqIoNI63cYsjQR8J+wGa4Y5izRcSHSm8K3QWmk3w==",
|
|
||||||
"cpu": [
|
|
||||||
"mips64el"
|
|
||||||
],
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"optional": true,
|
|
||||||
"os": [
|
|
||||||
"linux"
|
|
||||||
],
|
|
||||||
"peer": true,
|
|
||||||
"engines": {
|
|
||||||
"node": ">=18"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/vitest/node_modules/@esbuild/linux-ppc64": {
|
|
||||||
"version": "0.28.0",
|
|
||||||
"resolved": "https://registry.npmmirror.com/@esbuild/linux-ppc64/-/linux-ppc64-0.28.0.tgz",
|
|
||||||
"integrity": "sha512-bc0FE9wWeC0WBm49IQMPSPILRocGTQt3j5KPCA8os6VprfuJ7KD+5PzESSrJ6GmPIPJK965ZJHTUlSA6GNYEhg==",
|
|
||||||
"cpu": [
|
|
||||||
"ppc64"
|
|
||||||
],
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"optional": true,
|
|
||||||
"os": [
|
|
||||||
"linux"
|
|
||||||
],
|
|
||||||
"peer": true,
|
|
||||||
"engines": {
|
|
||||||
"node": ">=18"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/vitest/node_modules/@esbuild/linux-riscv64": {
|
|
||||||
"version": "0.28.0",
|
|
||||||
"resolved": "https://registry.npmmirror.com/@esbuild/linux-riscv64/-/linux-riscv64-0.28.0.tgz",
|
|
||||||
"integrity": "sha512-SQPZOwoTTT/HXFXQJG/vBX8sOFagGqvZyXcgLA3NhIqcBv1BJU1d46c0rGcrij2B56Z2rNiSLaZOYW5cUk7yLQ==",
|
|
||||||
"cpu": [
|
|
||||||
"riscv64"
|
|
||||||
],
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"optional": true,
|
|
||||||
"os": [
|
|
||||||
"linux"
|
|
||||||
],
|
|
||||||
"peer": true,
|
|
||||||
"engines": {
|
|
||||||
"node": ">=18"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/vitest/node_modules/@esbuild/linux-s390x": {
|
|
||||||
"version": "0.28.0",
|
|
||||||
"resolved": "https://registry.npmmirror.com/@esbuild/linux-s390x/-/linux-s390x-0.28.0.tgz",
|
|
||||||
"integrity": "sha512-SCfR0HN8CEEjnYnySJTd2cw0k9OHB/YFzt5zgJEwa+wL/T/raGWYMBqwDNAC6dqFKmJYZoQBRfHjgwLHGSrn3Q==",
|
|
||||||
"cpu": [
|
|
||||||
"s390x"
|
|
||||||
],
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"optional": true,
|
|
||||||
"os": [
|
|
||||||
"linux"
|
|
||||||
],
|
|
||||||
"peer": true,
|
|
||||||
"engines": {
|
|
||||||
"node": ">=18"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/vitest/node_modules/@esbuild/linux-x64": {
|
|
||||||
"version": "0.28.0",
|
|
||||||
"resolved": "https://registry.npmmirror.com/@esbuild/linux-x64/-/linux-x64-0.28.0.tgz",
|
|
||||||
"integrity": "sha512-us0dSb9iFxIi8srnpl931Nvs65it/Jd2a2K3qs7fz2WfGPHqzfzZTfec7oxZJRNPXPnNYZtanmRc4AL/JwVzHQ==",
|
|
||||||
"cpu": [
|
|
||||||
"x64"
|
|
||||||
],
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"optional": true,
|
|
||||||
"os": [
|
|
||||||
"linux"
|
|
||||||
],
|
|
||||||
"peer": true,
|
|
||||||
"engines": {
|
|
||||||
"node": ">=18"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/vitest/node_modules/@esbuild/netbsd-x64": {
|
|
||||||
"version": "0.28.0",
|
|
||||||
"resolved": "https://registry.npmmirror.com/@esbuild/netbsd-x64/-/netbsd-x64-0.28.0.tgz",
|
|
||||||
"integrity": "sha512-nU1yhmYutL+fQ71Kxnhg8uEOdC0pwEW9entHykTgEbna2pw2dkbFSMeqjjyHZoCmt8SBkOSvV+yNmm94aUrrqw==",
|
|
||||||
"cpu": [
|
|
||||||
"x64"
|
|
||||||
],
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"optional": true,
|
|
||||||
"os": [
|
|
||||||
"netbsd"
|
|
||||||
],
|
|
||||||
"peer": true,
|
|
||||||
"engines": {
|
|
||||||
"node": ">=18"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/vitest/node_modules/@esbuild/openbsd-x64": {
|
|
||||||
"version": "0.28.0",
|
|
||||||
"resolved": "https://registry.npmmirror.com/@esbuild/openbsd-x64/-/openbsd-x64-0.28.0.tgz",
|
|
||||||
"integrity": "sha512-8wZM2qqtv9UP3mzy7HiGYNH/zjTA355mpeuA+859TyR+e+Tc08IHYpLJuMsfpDJwoLo1ikIJI8jC3GFjnRClzA==",
|
|
||||||
"cpu": [
|
|
||||||
"x64"
|
|
||||||
],
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"optional": true,
|
|
||||||
"os": [
|
|
||||||
"openbsd"
|
|
||||||
],
|
|
||||||
"peer": true,
|
|
||||||
"engines": {
|
|
||||||
"node": ">=18"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/vitest/node_modules/@esbuild/sunos-x64": {
|
|
||||||
"version": "0.28.0",
|
|
||||||
"resolved": "https://registry.npmmirror.com/@esbuild/sunos-x64/-/sunos-x64-0.28.0.tgz",
|
|
||||||
"integrity": "sha512-1ZgjUoEdHZZl/YlV76TSCz9Hqj9h9YmMGAgAPYd+q4SicWNX3G5GCyx9uhQWSLcbvPW8Ni7lj4gDa1T40akdlw==",
|
|
||||||
"cpu": [
|
|
||||||
"x64"
|
|
||||||
],
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"optional": true,
|
|
||||||
"os": [
|
|
||||||
"sunos"
|
|
||||||
],
|
|
||||||
"peer": true,
|
|
||||||
"engines": {
|
|
||||||
"node": ">=18"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/vitest/node_modules/@esbuild/win32-arm64": {
|
|
||||||
"version": "0.28.0",
|
|
||||||
"resolved": "https://registry.npmmirror.com/@esbuild/win32-arm64/-/win32-arm64-0.28.0.tgz",
|
|
||||||
"integrity": "sha512-Q9StnDmQ/enxnpxCCLSg0oo4+34B9TdXpuyPeTedN/6+iXBJ4J+zwfQI28u/Jl40nOYAxGoNi7mFP40RUtkmUA==",
|
|
||||||
"cpu": [
|
|
||||||
"arm64"
|
|
||||||
],
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"optional": true,
|
|
||||||
"os": [
|
|
||||||
"win32"
|
|
||||||
],
|
|
||||||
"peer": true,
|
|
||||||
"engines": {
|
|
||||||
"node": ">=18"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/vitest/node_modules/@esbuild/win32-ia32": {
|
|
||||||
"version": "0.28.0",
|
|
||||||
"resolved": "https://registry.npmmirror.com/@esbuild/win32-ia32/-/win32-ia32-0.28.0.tgz",
|
|
||||||
"integrity": "sha512-zF3ag/gfiCe6U2iczcRzSYJKH1DCI+ByzSENHlM2FcDbEeo5Zd2C86Aq0tKUYAJJ1obRP84ymxIAksZUcdztHA==",
|
|
||||||
"cpu": [
|
|
||||||
"ia32"
|
|
||||||
],
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"optional": true,
|
|
||||||
"os": [
|
|
||||||
"win32"
|
|
||||||
],
|
|
||||||
"peer": true,
|
|
||||||
"engines": {
|
|
||||||
"node": ">=18"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/vitest/node_modules/@esbuild/win32-x64": {
|
|
||||||
"version": "0.28.0",
|
|
||||||
"resolved": "https://registry.npmmirror.com/@esbuild/win32-x64/-/win32-x64-0.28.0.tgz",
|
|
||||||
"integrity": "sha512-pEl1bO9mfAmIC+tW5btTmrKaujg3zGtUmWNdCw/xs70FBjwAL3o9OEKNHvNmnyylD6ubxUERiEhdsL0xBQ9efw==",
|
|
||||||
"cpu": [
|
|
||||||
"x64"
|
|
||||||
],
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"optional": true,
|
|
||||||
"os": [
|
|
||||||
"win32"
|
|
||||||
],
|
|
||||||
"peer": true,
|
|
||||||
"engines": {
|
|
||||||
"node": ">=18"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/vitest/node_modules/@vitest/mocker": {
|
"node_modules/vitest/node_modules/@vitest/mocker": {
|
||||||
"version": "4.1.8",
|
"version": "4.1.8",
|
||||||
"resolved": "https://registry.npmmirror.com/@vitest/mocker/-/mocker-4.1.8.tgz",
|
"resolved": "https://registry.npmmirror.com/@vitest/mocker/-/mocker-4.1.8.tgz",
|
||||||
@ -5699,50 +5238,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/vitest/node_modules/esbuild": {
|
|
||||||
"version": "0.28.0",
|
|
||||||
"resolved": "https://registry.npmmirror.com/esbuild/-/esbuild-0.28.0.tgz",
|
|
||||||
"integrity": "sha512-sNR9MHpXSUV/XB4zmsFKN+QgVG82Cc7+/aaxJ8Adi8hyOac+EXptIp45QBPaVyX3N70664wRbTcLTOemCAnyqw==",
|
|
||||||
"dev": true,
|
|
||||||
"hasInstallScript": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"optional": true,
|
|
||||||
"peer": true,
|
|
||||||
"bin": {
|
|
||||||
"esbuild": "bin/esbuild"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=18"
|
|
||||||
},
|
|
||||||
"optionalDependencies": {
|
|
||||||
"@esbuild/aix-ppc64": "0.28.0",
|
|
||||||
"@esbuild/android-arm": "0.28.0",
|
|
||||||
"@esbuild/android-arm64": "0.28.0",
|
|
||||||
"@esbuild/android-x64": "0.28.0",
|
|
||||||
"@esbuild/darwin-arm64": "0.28.0",
|
|
||||||
"@esbuild/darwin-x64": "0.28.0",
|
|
||||||
"@esbuild/freebsd-arm64": "0.28.0",
|
|
||||||
"@esbuild/freebsd-x64": "0.28.0",
|
|
||||||
"@esbuild/linux-arm": "0.28.0",
|
|
||||||
"@esbuild/linux-arm64": "0.28.0",
|
|
||||||
"@esbuild/linux-ia32": "0.28.0",
|
|
||||||
"@esbuild/linux-loong64": "0.28.0",
|
|
||||||
"@esbuild/linux-mips64el": "0.28.0",
|
|
||||||
"@esbuild/linux-ppc64": "0.28.0",
|
|
||||||
"@esbuild/linux-riscv64": "0.28.0",
|
|
||||||
"@esbuild/linux-s390x": "0.28.0",
|
|
||||||
"@esbuild/linux-x64": "0.28.0",
|
|
||||||
"@esbuild/netbsd-arm64": "0.28.0",
|
|
||||||
"@esbuild/netbsd-x64": "0.28.0",
|
|
||||||
"@esbuild/openbsd-arm64": "0.28.0",
|
|
||||||
"@esbuild/openbsd-x64": "0.28.0",
|
|
||||||
"@esbuild/openharmony-arm64": "0.28.0",
|
|
||||||
"@esbuild/sunos-x64": "0.28.0",
|
|
||||||
"@esbuild/win32-arm64": "0.28.0",
|
|
||||||
"@esbuild/win32-ia32": "0.28.0",
|
|
||||||
"@esbuild/win32-x64": "0.28.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/vitest/node_modules/estree-walker": {
|
"node_modules/vitest/node_modules/estree-walker": {
|
||||||
"version": "3.0.3",
|
"version": "3.0.3",
|
||||||
"resolved": "https://registry.npmmirror.com/estree-walker/-/estree-walker-3.0.3.tgz",
|
"resolved": "https://registry.npmmirror.com/estree-walker/-/estree-walker-3.0.3.tgz",
|
||||||
|
|||||||
@ -14,6 +14,7 @@
|
|||||||
"@bddh/starling-realtime-client": "^2.0.9",
|
"@bddh/starling-realtime-client": "^2.0.9",
|
||||||
"crypto-js": "^4.2.0",
|
"crypto-js": "^4.2.0",
|
||||||
"element-plus": "^2.9.7",
|
"element-plus": "^2.9.7",
|
||||||
|
"opencc-js": "^1.4.0",
|
||||||
"uuid": "^9.0.1",
|
"uuid": "^9.0.1",
|
||||||
"vue": "^3.5.13"
|
"vue": "^3.5.13"
|
||||||
},
|
},
|
||||||
|
|||||||
764
src/App.vue
764
src/App.vue
File diff suppressed because it is too large
Load Diff
BIN
src/assets/avatar.png
Normal file
BIN
src/assets/avatar.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 281 KiB |
@ -1,10 +1,8 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="subtitle-panel">
|
<div class="subtitle-panel">
|
||||||
<div
|
<!-- AI字幕 -->
|
||||||
class="subtitle-content ai-only-mode"
|
<div class="subtitle-content ai-only-mode" ref="scrollContainerRef">
|
||||||
ref="scrollContainerRef"
|
<div v-if="aiSubtitle" class="ai-subtitle-bar" ref="aiSubtitleBarRef">
|
||||||
>
|
|
||||||
<div v-if="aiSubtitle" class="ai-subtitle-bar" ref="aiSubtitleBarRef" @scroll="handleScroll">
|
|
||||||
<div
|
<div
|
||||||
class="ai-subtitle-text"
|
class="ai-subtitle-text"
|
||||||
ref="aiSubtitleTextRef"
|
ref="aiSubtitleTextRef"
|
||||||
@ -12,6 +10,24 @@
|
|||||||
>
|
>
|
||||||
{{ aiSubtitle }}
|
{{ aiSubtitle }}
|
||||||
</div>
|
</div>
|
||||||
|
<!-- 滚动指示器 -->
|
||||||
|
<div
|
||||||
|
v-if="aiTextOverflow"
|
||||||
|
class="scroll-hint"
|
||||||
|
@click="scrollAIToBottom"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
width="14"
|
||||||
|
height="14"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
stroke-width="2"
|
||||||
|
stroke-linecap="round"
|
||||||
|
>
|
||||||
|
<polyline points="6 9 12 15 18 9" />
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-else class="subtitle-placeholder">
|
<div v-else class="subtitle-placeholder">
|
||||||
<svg
|
<svg
|
||||||
@ -27,54 +43,138 @@
|
|||||||
d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"
|
d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"
|
||||||
/>
|
/>
|
||||||
</svg>
|
</svg>
|
||||||
等待AI回复...
|
等待AI回覆...
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import {ref, watch, nextTick, onMounted} from "vue";
|
import { ref, watch, nextTick, onMounted, onBeforeUnmount } from "vue";
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
aiSubtitle: string;
|
aiSubtitle: string;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
|
// 滚动容器ref:指向 .subtitle-content(实际可滚动容器)
|
||||||
const scrollContainerRef = ref<HTMLElement | null>(null);
|
const scrollContainerRef = ref<HTMLElement | null>(null);
|
||||||
const aiSubtitleBarRef = ref<HTMLElement | null>(null);
|
const aiSubtitleBarRef = ref<HTMLElement | null>(null);
|
||||||
const aiSubtitleTextRef = ref<HTMLElement | null>(null);
|
const aiSubtitleTextRef = ref<HTMLElement | null>(null);
|
||||||
|
|
||||||
|
// ===== AI字幕自适应字号 =====
|
||||||
const aiFontSize = ref(18);
|
const aiFontSize = ref(18);
|
||||||
const isUserScrolling = ref(false);
|
const aiTextOverflow = ref(false);
|
||||||
|
|
||||||
|
// 检测是否为 1440×2560 目标分辨率
|
||||||
|
const isTargetResolution = ref(false);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检测当前视口是否为 1440×2560 分辨率
|
||||||
|
* 使用 window.innerWidth 和 innerHeight 精确匹配
|
||||||
|
*/
|
||||||
|
const checkResolution = () => {
|
||||||
|
const TARGET_WIDTH = 1440;
|
||||||
|
const TARGET_HEIGHT = 2560;
|
||||||
|
console.log("------------", window.innerWidth, window.innerHeight);
|
||||||
|
isTargetResolution.value =
|
||||||
|
(window.innerWidth === TARGET_WIDTH &&
|
||||||
|
window.innerHeight === TARGET_HEIGHT) ||
|
||||||
|
(window.innerWidth > 1000 && window.innerHeight > 1680);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取目标分辨率下的字号基准值
|
||||||
|
* 1440×2560 下使用更大的字号以确保清晰可读
|
||||||
|
*/
|
||||||
|
const getTargetFontSizeBase = (textLength: number): number => {
|
||||||
|
if (textLength <= 50) return 36;
|
||||||
|
if (textLength <= 100) return 32;
|
||||||
|
if (textLength <= 200) return 28;
|
||||||
|
if (textLength <= 400) return 24;
|
||||||
|
return 22;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取普通分辨率下的字号基准值
|
||||||
|
*/
|
||||||
|
const getNormalFontSizeBase = (textLength: number): number => {
|
||||||
|
if (textLength <= 50) return 18;
|
||||||
|
if (textLength <= 100) return 16;
|
||||||
|
if (textLength <= 200) return 14;
|
||||||
|
if (textLength <= 400) return 13;
|
||||||
|
return 12;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 计算AI字幕字号:根据分辨率和文本长度动态调整
|
||||||
const computeAIFontSize = () => {
|
const computeAIFontSize = () => {
|
||||||
const text = props.aiSubtitle;
|
const text = props.aiSubtitle;
|
||||||
|
console.log("------------", text);
|
||||||
if (!text) {
|
if (!text) {
|
||||||
aiFontSize.value = 18;
|
aiFontSize.value = isTargetResolution.value ? 36 : 18;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const len = text.length;
|
const len = text.length;
|
||||||
if (len <= 50) aiFontSize.value = 18;
|
aiFontSize.value = isTargetResolution.value
|
||||||
else if (len <= 100) aiFontSize.value = 16;
|
? getTargetFontSizeBase(len)
|
||||||
else if (len <= 200) aiFontSize.value = 14;
|
: getNormalFontSizeBase(len);
|
||||||
else if (len <= 400) aiFontSize.value = 13;
|
|
||||||
else aiFontSize.value = 12;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleScroll = () => {
|
// 检测AI字幕是否溢出
|
||||||
if (!aiSubtitleBarRef.value) return;
|
const checkAIOverflow = () => {
|
||||||
const { scrollTop, scrollHeight, clientHeight } = aiSubtitleBarRef.value;
|
nextTick(() => {
|
||||||
const isAtBottom = scrollTop + clientHeight >= scrollHeight - 10;
|
const bar = aiSubtitleBarRef.value;
|
||||||
isUserScrolling.value = !isAtBottom;
|
const textEl = aiSubtitleTextRef.value;
|
||||||
|
if (bar && textEl) {
|
||||||
|
aiTextOverflow.value = textEl.scrollHeight > bar.clientHeight + 4;
|
||||||
|
}
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const scrollAIToBottom = () => {
|
||||||
|
if (aiSubtitleBarRef.value) {
|
||||||
|
aiSubtitleBarRef.value.scrollTo({
|
||||||
|
top: aiSubtitleBarRef.value.scrollHeight,
|
||||||
|
behavior: "smooth",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理视口尺寸变化:重新检测分辨率并更新字号
|
||||||
|
*/
|
||||||
|
const handleResize = () => {
|
||||||
|
const wasTarget = isTargetResolution.value;
|
||||||
|
checkResolution();
|
||||||
|
// 如果分辨率状态变化,重新计算字号
|
||||||
|
if (wasTarget !== isTargetResolution.value) {
|
||||||
|
computeAIFontSize();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
// 初始检测分辨率
|
||||||
|
checkResolution();
|
||||||
|
computeAIFontSize();
|
||||||
|
// 监听视口尺寸变化
|
||||||
|
window.addEventListener("resize", handleResize);
|
||||||
|
});
|
||||||
|
|
||||||
|
onBeforeUnmount(() => {
|
||||||
|
window.removeEventListener("resize", handleResize);
|
||||||
|
});
|
||||||
|
|
||||||
|
// ===== 监听变化 =====
|
||||||
|
|
||||||
|
// AI字幕变化时:自适应字号 + 检测溢出 + 自动滚动
|
||||||
watch(
|
watch(
|
||||||
() => props.aiSubtitle,
|
() => props.aiSubtitle,
|
||||||
() => {
|
() => {
|
||||||
computeAIFontSize();
|
computeAIFontSize();
|
||||||
|
checkAIOverflow();
|
||||||
|
// 自动滚动AI字幕到底部
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
if (aiSubtitleBarRef.value && !isUserScrolling.value) {
|
if (aiSubtitleBarRef.value) {
|
||||||
aiSubtitleBarRef.value.scrollTo({
|
aiSubtitleBarRef.value.scrollTo({
|
||||||
top: aiSubtitleBarRef.value.scrollHeight,
|
top: aiSubtitleBarRef.value.scrollHeight,
|
||||||
behavior: "smooth",
|
behavior: "smooth",
|
||||||
@ -92,6 +192,7 @@ watch(
|
|||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ===== 字幕内容 ===== */
|
||||||
.subtitle-content {
|
.subtitle-content {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
min-height: 0;
|
min-height: 0;
|
||||||
@ -129,16 +230,16 @@ watch(
|
|||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ===== AI字幕 ===== */
|
||||||
.ai-only-mode {
|
.ai-only-mode {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
align-items: flex-end;
|
||||||
padding-bottom: 4px;
|
padding-bottom: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ai-subtitle-bar {
|
.ai-subtitle-bar {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
flex: 1;
|
max-height: 100%;
|
||||||
min-height: 0;
|
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
background: linear-gradient(
|
background: linear-gradient(
|
||||||
135deg,
|
135deg,
|
||||||
@ -171,4 +272,64 @@ watch(
|
|||||||
transition: font-size 0.3s ease;
|
transition: font-size 0.3s ease;
|
||||||
text-shadow: 0 1px 4px rgba(0, 0, 0, 0.6);
|
text-shadow: 0 1px 4px rgba(0, 0, 0, 0.6);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.scroll-hint {
|
||||||
|
position: sticky;
|
||||||
|
bottom: 0;
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
width: 28px;
|
||||||
|
height: 28px;
|
||||||
|
border-radius: 50%;
|
||||||
|
background: rgba(108, 140, 255, 0.3);
|
||||||
|
color: rgba(255, 255, 255, 0.8);
|
||||||
|
cursor: pointer;
|
||||||
|
margin: 8px auto 0;
|
||||||
|
transition: all 0.2s;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: rgba(108, 140, 255, 0.5);
|
||||||
|
transform: translateX(-50%) scale(1.1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ===== 1440×2560 分辨率专用样式 ===== */
|
||||||
|
@media (min-width: 1000px) and (min-height: 1680px) {
|
||||||
|
.subtitle-placeholder {
|
||||||
|
font-size: 24px;
|
||||||
|
line-height: 1.75;
|
||||||
|
letter-spacing: 0.5px;
|
||||||
|
font-weight: 400;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* AI字幕:字号由 JavaScript 动态控制,此处仅设置辅助样式 */
|
||||||
|
.ai-subtitle-text {
|
||||||
|
line-height: 1.75;
|
||||||
|
letter-spacing: 0.6px;
|
||||||
|
font-weight: 400;
|
||||||
|
text-shadow: 0 2px 8px rgba(0, 0, 0, 0.7);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 字幕容器:背景与边框适配大字号 */
|
||||||
|
.ai-subtitle-bar {
|
||||||
|
padding: 18px 24px;
|
||||||
|
border-radius: 12px;
|
||||||
|
background: linear-gradient(
|
||||||
|
135deg,
|
||||||
|
rgba(108, 140, 255, 0.12) 0%,
|
||||||
|
rgba(79, 110, 247, 0.06) 100%
|
||||||
|
);
|
||||||
|
border: 1px solid rgba(108, 140, 255, 0.15);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 滚动指示器:尺寸适配 */
|
||||||
|
.scroll-hint {
|
||||||
|
width: 40px;
|
||||||
|
height: 40px;
|
||||||
|
margin-top: 12px;
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@ -4,10 +4,9 @@ import RealTimeHuman from "@bddh/starling-realtime-client";
|
|||||||
import { checkPlayUnMute } from "@/utils/audioUtils";
|
import { checkPlayUnMute } from "@/utils/audioUtils";
|
||||||
import { SilenceDetector } from "@/utils/SilenceDetector";
|
import { SilenceDetector } from "@/utils/SilenceDetector";
|
||||||
import { TokenManager } from "@/utils/tokenManager";
|
import { TokenManager } from "@/utils/tokenManager";
|
||||||
import type { ChatMessage, SubtitleMode } from "@/types";
|
import type { ChatMessage } from "@/types";
|
||||||
|
|
||||||
const DEFAULT_TEXT =
|
const DEFAULT_TEXT = "你好!我是皮特教授,歡迎向我提問任何有關電池的問題。";
|
||||||
"你好!我是皮特教授,欢迎向我提问任何有关电池的问题。";
|
|
||||||
const OPENING_TTS_DELAY_MS = 200;
|
const OPENING_TTS_DELAY_MS = 200;
|
||||||
const SILENCE_TIMEOUT_MS = 5000;
|
const SILENCE_TIMEOUT_MS = 5000;
|
||||||
// 最短有效语音时长(秒),低于此时长视为无效输入
|
// 最短有效语音时长(秒),低于此时长视为无效输入
|
||||||
@ -17,7 +16,15 @@ const BROADCAST_TIMEOUT_MS = 60000;
|
|||||||
const APPID = "i-sfyrkdr0ubepa";
|
const APPID = "i-sfyrkdr0ubepa";
|
||||||
const APP_KEY = "72vpdansbpg8nxjbxzhp";
|
const APP_KEY = "72vpdansbpg8nxjbxzhp";
|
||||||
// 打断词列表:识别到这些词时自动打断播报
|
// 打断词列表:识别到这些词时自动打断播报
|
||||||
const INTERRUPT_KEYWORDS = ["稍等一下", "停一下", "抱歉打断一下", "不好意思", "对不起", "停", "闭嘴"];
|
const INTERRUPT_KEYWORDS = [
|
||||||
|
"稍等一下",
|
||||||
|
"停一下",
|
||||||
|
"抱歉打断一下",
|
||||||
|
"不好意思",
|
||||||
|
"对不起",
|
||||||
|
"停",
|
||||||
|
"闭嘴",
|
||||||
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 检测文本是否包含实质内容(去除空白和标点后仍有字符)
|
* 检测文本是否包含实质内容(去除空白和标点后仍有字符)
|
||||||
@ -127,7 +134,6 @@ export function useDigitalHuman(options?: {
|
|||||||
const isBroadcasting = ref(false);
|
const isBroadcasting = ref(false);
|
||||||
|
|
||||||
// 字幕相关
|
// 字幕相关
|
||||||
const subtitleMode = ref<SubtitleMode>("ai-only");
|
|
||||||
const currentAISubtitle = ref("");
|
const currentAISubtitle = ref("");
|
||||||
const currentUserSubtitle = ref("");
|
const currentUserSubtitle = ref("");
|
||||||
const chatMessages = ref<ChatMessage[]>([]);
|
const chatMessages = ref<ChatMessage[]>([]);
|
||||||
@ -329,10 +335,14 @@ export function useDigitalHuman(options?: {
|
|||||||
if (pickPhase.value === "broadcasting") {
|
if (pickPhase.value === "broadcasting") {
|
||||||
const hasInterrupt = containsInterruptKeyword(subtitleContent);
|
const hasInterrupt = containsInterruptKeyword(subtitleContent);
|
||||||
if (hasInterrupt) {
|
if (hasInterrupt) {
|
||||||
console.info(`[打断词检测] 播报中识别到打断词: "${subtitleContent}",自动打断(仅中断播报,不调用LLM)`);
|
console.info(
|
||||||
|
`[打断词检测] 播报中识别到打断词: "${subtitleContent}",自动打断(仅中断播报,不调用LLM)`,
|
||||||
|
);
|
||||||
interrupt();
|
interrupt();
|
||||||
} else {
|
} else {
|
||||||
console.info(`[打断词检测] 播报中收到ASR结果: "${subtitleContent}",非打断词,忽略`);
|
console.info(
|
||||||
|
`[打断词检测] 播报中收到ASR结果: "${subtitleContent}",非打断词,忽略`,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -348,9 +358,7 @@ export function useDigitalHuman(options?: {
|
|||||||
if (pickPhase.value === "idle") {
|
if (pickPhase.value === "idle") {
|
||||||
// 忽略打断后3秒内到达的延迟ASR结果(避免打断词被当作新输入)
|
// 忽略打断后3秒内到达的延迟ASR结果(避免打断词被当作新输入)
|
||||||
if (Date.now() - lastInterruptTime < 3000) {
|
if (Date.now() - lastInterruptTime < 3000) {
|
||||||
console.info(
|
console.info("[状态机] 打断后延迟到达的ASR结果,忽略");
|
||||||
"[状态机] 打断后延迟到达的ASR结果,忽略",
|
|
||||||
);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
const hasSubstance = hasSubstantialContent(subtitleContent);
|
const hasSubstance = hasSubstantialContent(subtitleContent);
|
||||||
@ -846,7 +854,6 @@ export function useDigitalHuman(options?: {
|
|||||||
// 播报状态
|
// 播报状态
|
||||||
isBroadcasting,
|
isBroadcasting,
|
||||||
// 字幕
|
// 字幕
|
||||||
subtitleMode,
|
|
||||||
currentAISubtitle,
|
currentAISubtitle,
|
||||||
currentUserSubtitle,
|
currentUserSubtitle,
|
||||||
chatMessages,
|
chatMessages,
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
import { ref } from "vue";
|
import { ref } from "vue";
|
||||||
|
import OpenCC from "opencc-js";
|
||||||
|
|
||||||
// 火山方舟 Chat Completions API 配置
|
// 火山方舟 Chat Completions API 配置
|
||||||
const LLM_API_URL =
|
const LLM_API_URL =
|
||||||
@ -51,7 +52,7 @@ export function useLLM() {
|
|||||||
|
|
||||||
const SYSTEM_PROMPT: LLMMessage = {
|
const SYSTEM_PROMPT: LLMMessage = {
|
||||||
role: "system",
|
role: "system",
|
||||||
content: "你是一个友好的数字人助手,请用简洁自然的语言回答用户的问题。",
|
content: "你是一個友善的數位人助手,請用簡潔自然的語言回答使用者的問題。",
|
||||||
};
|
};
|
||||||
|
|
||||||
const sendToLLM = async (userMessage: string): Promise<string> => {
|
const sendToLLM = async (userMessage: string): Promise<string> => {
|
||||||
@ -102,7 +103,7 @@ export function useLLM() {
|
|||||||
|
|
||||||
return aiReply;
|
return aiReply;
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
const errorMsg = err.message || "请求失败";
|
const errorMsg = err.message || "請求失敗";
|
||||||
error.value = errorMsg;
|
error.value = errorMsg;
|
||||||
console.error("LLM请求错误:", err);
|
console.error("LLM请求错误:", err);
|
||||||
throw err;
|
throw err;
|
||||||
@ -143,7 +144,9 @@ export function useLLM() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const data = await response.json();
|
const data = await response.json();
|
||||||
const aiReply = data.text || "";
|
// 将简体中文回复转换为繁体中文
|
||||||
|
const rawText = data.text || "";
|
||||||
|
const aiReply = OpenCC.Converter({ from: "cn", to: "tw" })(rawText);
|
||||||
|
|
||||||
conversationHistory.value.push({
|
conversationHistory.value.push({
|
||||||
role: "user",
|
role: "user",
|
||||||
@ -157,7 +160,7 @@ export function useLLM() {
|
|||||||
|
|
||||||
return aiReply;
|
return aiReply;
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
const errorMsg = err.message || "请求失败";
|
const errorMsg = err.message || "請求失敗";
|
||||||
error.value = errorMsg;
|
error.value = errorMsg;
|
||||||
console.error("ChatBase请求错误:", err);
|
console.error("ChatBase请求错误:", err);
|
||||||
throw err;
|
throw err;
|
||||||
|
|||||||
@ -5,11 +5,3 @@ export interface ChatMessage {
|
|||||||
timestamp: number;
|
timestamp: number;
|
||||||
completed: boolean;
|
completed: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type SubtitleMode = 'ai-only' | 'bubble' | 'merged';
|
|
||||||
|
|
||||||
export const SUBTITLE_MODE_LABELS: Record<SubtitleMode, string> = {
|
|
||||||
'ai-only': 'AI字幕',
|
|
||||||
'bubble': '对话气泡',
|
|
||||||
'merged': '合并气泡',
|
|
||||||
};
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user