Compare commits
16 Commits
main
...
release-xg
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d5f0a21f96 | ||
|
|
1be7759250 | ||
|
|
36cd9aeaf0 | ||
|
|
e3f81d4f7b | ||
|
|
bfde0250e3 | ||
|
|
3b280eb579 | ||
|
|
4bf7369f92 | ||
|
|
beba6b81ce | ||
|
|
89c261e13f | ||
|
|
afdcae1e8e | ||
|
|
b198d73f9e | ||
|
|
9360d598b0 | ||
|
|
7a47b4d7ab | ||
|
|
55502295ca | ||
|
|
bb7fea71f1 | ||
|
|
006aa04a7f |
@ -3,7 +3,7 @@ run-name: ${{ gitea.actor }} is testing out Gitea Actions 🚀
|
|||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- 'main**'
|
- 'release-xg'
|
||||||
|
|
||||||
env:
|
env:
|
||||||
BUILD: staging
|
BUILD: staging
|
||||||
@ -35,12 +35,12 @@ jobs:
|
|||||||
uses: https://gitea.yantootech.com/neil/build-push-action@v6
|
uses: https://gitea.yantootech.com/neil/build-push-action@v6
|
||||||
with:
|
with:
|
||||||
push: true
|
push: true
|
||||||
tags: hub.kce.ksyun.com/yantoo/yantoo-repository/baidu-digital-human-app:${{ gitea.run_id }}
|
tags: hub.kce.ksyun.com/yantoo/yantoo-repository/xg-digital-human-app:${{ gitea.run_id }}
|
||||||
- name: Install
|
- name: Install
|
||||||
run: |
|
run: |
|
||||||
helm upgrade --install baidu-digital-human-app ./.gitea/charts \
|
helm upgrade --install xg-digital-human-app ./.gitea/charts \
|
||||||
--namespace digital-human-prod \
|
--namespace digital-human-prod \
|
||||||
--create-namespace \
|
--create-namespace \
|
||||||
--set image.repository=hub.kce.ksyun.com/yantoo/yantoo-repository/baidu-digital-human-app \
|
--set image.repository=hub.kce.ksyun.com/yantoo/yantoo-repository/xg-digital-human-app \
|
||||||
--set image.tag=${{ gitea.run_id }}
|
--set image.tag=${{ gitea.run_id }}
|
||||||
- run: echo "🍏 This job's status is ${{ job.status }}."
|
- run: echo "🍏 This job's status is ${{ job.status }}."
|
||||||
|
|||||||
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"
|
||||||
},
|
},
|
||||||
|
|||||||
1170
src/App.vue
1170
src/App.vue
File diff suppressed because it is too large
Load Diff
BIN
src/GP.webp
Normal file
BIN
src/GP.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 5.5 KiB |
BIN
src/assets/avatar.png
Normal file
BIN
src/assets/avatar.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 281 KiB |
BIN
src/assets/background.jpg
Normal file
BIN
src/assets/background.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 5.6 MiB |
@ -1,60 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="subtitle-panel">
|
<div class="subtitle-panel">
|
||||||
<!-- 字幕模式下拉框 -->
|
<!-- AI字幕 -->
|
||||||
<div class="subtitle-header">
|
<div class="subtitle-content ai-only-mode" ref="scrollContainerRef">
|
||||||
<div class="dropdown-wrapper" :class="{ open: dropdownOpen }">
|
|
||||||
<button class="dropdown-trigger" @click="dropdownOpen = !dropdownOpen">
|
|
||||||
<span class="dropdown-label">{{ modeLabel }}</span>
|
|
||||||
<svg
|
|
||||||
class="dropdown-arrow"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
width="14"
|
|
||||||
height="14"
|
|
||||||
fill="none"
|
|
||||||
stroke="currentColor"
|
|
||||||
stroke-width="2.5"
|
|
||||||
stroke-linecap="round"
|
|
||||||
stroke-linejoin="round"
|
|
||||||
>
|
|
||||||
<polyline points="6 9 12 15 18 9" />
|
|
||||||
</svg>
|
|
||||||
</button>
|
|
||||||
<Transition name="dropdown">
|
|
||||||
<div v-if="dropdownOpen" class="dropdown-menu">
|
|
||||||
<button
|
|
||||||
v-for="opt in modeOptions"
|
|
||||||
:key="opt.value"
|
|
||||||
class="dropdown-item"
|
|
||||||
:class="{ active: currentMode === opt.value }"
|
|
||||||
@click="selectMode(opt.value)"
|
|
||||||
>
|
|
||||||
<span class="item-icon">{{ opt.icon }}</span>
|
|
||||||
<span class="item-label">{{ opt.label }}</span>
|
|
||||||
<svg
|
|
||||||
v-if="currentMode === opt.value"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
width="14"
|
|
||||||
height="14"
|
|
||||||
fill="none"
|
|
||||||
stroke="currentColor"
|
|
||||||
stroke-width="3"
|
|
||||||
stroke-linecap="round"
|
|
||||||
stroke-linejoin="round"
|
|
||||||
>
|
|
||||||
<polyline points="20 6 9 17 4 12" />
|
|
||||||
</svg>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</Transition>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 模式1:仅AI字幕 -->
|
|
||||||
<div
|
|
||||||
v-if="currentMode === 'ai-only'"
|
|
||||||
class="subtitle-content ai-only-mode"
|
|
||||||
ref="scrollContainerRef"
|
|
||||||
>
|
|
||||||
<div v-if="aiSubtitle" class="ai-subtitle-bar" ref="aiSubtitleBarRef">
|
<div v-if="aiSubtitle" class="ai-subtitle-bar" ref="aiSubtitleBarRef">
|
||||||
<div
|
<div
|
||||||
class="ai-subtitle-text"
|
class="ai-subtitle-text"
|
||||||
@ -96,128 +43,19 @@
|
|||||||
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>
|
|
||||||
|
|
||||||
<!-- 模式2:对话气泡 -->
|
|
||||||
<div
|
|
||||||
v-if="currentMode === 'bubble'"
|
|
||||||
class="subtitle-content bubble-mode"
|
|
||||||
ref="scrollContainerRef"
|
|
||||||
>
|
|
||||||
<div v-if="messages.length === 0" class="subtitle-placeholder">
|
|
||||||
<svg
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
width="20"
|
|
||||||
height="20"
|
|
||||||
fill="none"
|
|
||||||
stroke="currentColor"
|
|
||||||
stroke-width="1.5"
|
|
||||||
stroke-linecap="round"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
等待对话开始...
|
|
||||||
</div>
|
|
||||||
<div class="chat-list" ref="chatListRef">
|
|
||||||
<div
|
|
||||||
v-for="msg in messages"
|
|
||||||
:key="msg.id"
|
|
||||||
:class="[
|
|
||||||
'chat-bubble',
|
|
||||||
msg.role === 'user' ? 'bubble-user' : 'bubble-ai',
|
|
||||||
]"
|
|
||||||
>
|
|
||||||
<div class="bubble-body">
|
|
||||||
<div
|
|
||||||
class="bubble-text"
|
|
||||||
:class="{
|
|
||||||
'text-user': msg.role === 'user',
|
|
||||||
'text-ai': msg.role === 'ai',
|
|
||||||
}"
|
|
||||||
>
|
|
||||||
{{ msg.content }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 模式3:合并气泡 -->
|
|
||||||
<div
|
|
||||||
v-if="currentMode === 'merged'"
|
|
||||||
class="subtitle-content merged-mode"
|
|
||||||
ref="scrollContainerRef"
|
|
||||||
>
|
|
||||||
<div v-if="messages.length === 0" class="subtitle-placeholder">
|
|
||||||
<svg
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
width="20"
|
|
||||||
height="20"
|
|
||||||
fill="none"
|
|
||||||
stroke="currentColor"
|
|
||||||
stroke-width="1.5"
|
|
||||||
stroke-linecap="round"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
等待对话开始...
|
|
||||||
</div>
|
|
||||||
<div class="merged-list" ref="mergedListRef">
|
|
||||||
<div
|
|
||||||
v-for="(pair, idx) in pairedMessages"
|
|
||||||
:key="idx"
|
|
||||||
class="merged-bubble"
|
|
||||||
>
|
|
||||||
<div v-if="pair.user" class="merged-user-section">
|
|
||||||
<div class="merged-text text-user">
|
|
||||||
{{ pair.user.content }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div v-if="pair.ai" class="merged-ai-section">
|
|
||||||
<div class="merged-text text-ai">
|
|
||||||
{{ pair.ai.content }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import {
|
import { ref, watch, nextTick, onMounted, onBeforeUnmount } from "vue";
|
||||||
ref,
|
|
||||||
computed,
|
|
||||||
watch,
|
|
||||||
nextTick,
|
|
||||||
onMounted,
|
|
||||||
onBeforeUnmount,
|
|
||||||
} from "vue";
|
|
||||||
import type { ChatMessage, SubtitleMode } from "@/types";
|
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
mode: SubtitleMode;
|
|
||||||
aiSubtitle: string;
|
aiSubtitle: string;
|
||||||
userSubtitle: string;
|
|
||||||
messages: ChatMessage[];
|
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const emit = defineEmits<{
|
|
||||||
"update:mode": [value: SubtitleMode];
|
|
||||||
}>();
|
|
||||||
|
|
||||||
const currentMode = computed({
|
|
||||||
get: () => props.mode,
|
|
||||||
set: (val: SubtitleMode) => emit("update:mode", val),
|
|
||||||
});
|
|
||||||
|
|
||||||
const dropdownOpen = ref(false);
|
|
||||||
// 滚动容器ref:指向 .subtitle-content(实际可滚动容器)
|
// 滚动容器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);
|
||||||
@ -302,31 +140,6 @@ const scrollAIToBottom = () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// ===== 下拉框 =====
|
|
||||||
const modeOptions = [
|
|
||||||
{ value: "ai-only" as SubtitleMode, label: "AI字幕", icon: "💬" },
|
|
||||||
{ value: "bubble" as SubtitleMode, label: "对话气泡", icon: "💭" },
|
|
||||||
{ value: "merged" as SubtitleMode, label: "合并气泡", icon: "📋" },
|
|
||||||
];
|
|
||||||
|
|
||||||
const modeLabel = computed(() => {
|
|
||||||
return (
|
|
||||||
modeOptions.find((o) => o.value === currentMode.value)?.label || "AI字幕"
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
const selectMode = (val: SubtitleMode) => {
|
|
||||||
currentMode.value = val;
|
|
||||||
dropdownOpen.value = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleClickOutside = (e: MouseEvent) => {
|
|
||||||
const target = e.target as HTMLElement;
|
|
||||||
if (!target.closest(".dropdown-wrapper")) {
|
|
||||||
dropdownOpen.value = false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 处理视口尺寸变化:重新检测分辨率并更新字号
|
* 处理视口尺寸变化:重新检测分辨率并更新字号
|
||||||
*/
|
*/
|
||||||
@ -340,7 +153,6 @@ const handleResize = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
document.addEventListener("click", handleClickOutside);
|
|
||||||
// 初始检测分辨率
|
// 初始检测分辨率
|
||||||
checkResolution();
|
checkResolution();
|
||||||
computeAIFontSize();
|
computeAIFontSize();
|
||||||
@ -349,59 +161,11 @@ onMounted(() => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
onBeforeUnmount(() => {
|
onBeforeUnmount(() => {
|
||||||
document.removeEventListener("click", handleClickOutside);
|
|
||||||
window.removeEventListener("resize", handleResize);
|
window.removeEventListener("resize", handleResize);
|
||||||
});
|
});
|
||||||
|
|
||||||
// ===== 消息配对 =====
|
|
||||||
const pairedMessages = computed(() => {
|
|
||||||
const pairs: { user: ChatMessage | null; ai: ChatMessage | null }[] = [];
|
|
||||||
let currentPair: { user: ChatMessage | null; ai: ChatMessage | null } = {
|
|
||||||
user: null,
|
|
||||||
ai: null,
|
|
||||||
};
|
|
||||||
|
|
||||||
for (const msg of props.messages) {
|
|
||||||
if (msg.role === "user") {
|
|
||||||
if (currentPair.user) {
|
|
||||||
pairs.push(currentPair);
|
|
||||||
currentPair = { user: msg, ai: null };
|
|
||||||
} else {
|
|
||||||
currentPair.user = msg;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
currentPair.ai = msg;
|
|
||||||
pairs.push(currentPair);
|
|
||||||
currentPair = { user: null, ai: null };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (currentPair.user || currentPair.ai) {
|
|
||||||
pairs.push(currentPair);
|
|
||||||
}
|
|
||||||
return pairs;
|
|
||||||
});
|
|
||||||
|
|
||||||
// ===== 监听变化 =====
|
// ===== 监听变化 =====
|
||||||
|
|
||||||
// 模式切换时:立即刷新内容并滚动到底部
|
|
||||||
watch(
|
|
||||||
() => props.mode,
|
|
||||||
() => {
|
|
||||||
computeAIFontSize();
|
|
||||||
nextTick(() => {
|
|
||||||
checkAIOverflow();
|
|
||||||
scrollToBottom();
|
|
||||||
// AI模式切换后确保字幕滚动到底部
|
|
||||||
if (props.mode === "ai-only" && aiSubtitleBarRef.value) {
|
|
||||||
aiSubtitleBarRef.value.scrollTo({
|
|
||||||
top: aiSubtitleBarRef.value.scrollHeight,
|
|
||||||
behavior: "instant" as ScrollBehavior,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
// AI字幕变化时:自适应字号 + 检测溢出 + 自动滚动
|
// AI字幕变化时:自适应字号 + 检测溢出 + 自动滚动
|
||||||
watch(
|
watch(
|
||||||
() => props.aiSubtitle,
|
() => props.aiSubtitle,
|
||||||
@ -419,44 +183,6 @@ watch(
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
// 消息变化时:自动滚动到底部
|
|
||||||
watch(
|
|
||||||
() => props.messages.length,
|
|
||||||
() => {
|
|
||||||
nextTick(() => {
|
|
||||||
scrollToBottom();
|
|
||||||
});
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
// 流式内容更新时:自动滚动到底部(消息数量不变但内容变化)
|
|
||||||
watch(
|
|
||||||
() => {
|
|
||||||
const msgs = props.messages;
|
|
||||||
if (msgs.length === 0) return "";
|
|
||||||
// 监听最后一条消息的内容变化,用于流式更新时自动滚动
|
|
||||||
return msgs[msgs.length - 1].content;
|
|
||||||
},
|
|
||||||
() => {
|
|
||||||
nextTick(() => {
|
|
||||||
scrollToBottom();
|
|
||||||
});
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 将对话列表滚动到底部
|
|
||||||
* 兼容不同内容量:内容少时无需滚动,内容超出可见区域时平滑滚动到底部
|
|
||||||
*/
|
|
||||||
const scrollToBottom = () => {
|
|
||||||
const el = scrollContainerRef.value;
|
|
||||||
if (!el) return;
|
|
||||||
el.scrollTo({
|
|
||||||
top: el.scrollHeight,
|
|
||||||
behavior: "smooth",
|
|
||||||
});
|
|
||||||
};
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
@ -466,108 +192,6 @@ const scrollToBottom = () => {
|
|||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ===== 下拉框 ===== */
|
|
||||||
.subtitle-header {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
padding-bottom: 8px;
|
|
||||||
border-bottom: 1px solid rgba(255, 255, 255, 0.06);
|
|
||||||
margin-bottom: 8px;
|
|
||||||
flex-shrink: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dropdown-wrapper {
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dropdown-trigger {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 8px;
|
|
||||||
padding: 8px 14px;
|
|
||||||
background: rgba(255, 255, 255, 0.06);
|
|
||||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
|
||||||
border-radius: 10px;
|
|
||||||
color: rgba(255, 255, 255, 0.75);
|
|
||||||
cursor: pointer;
|
|
||||||
font-size: 13px;
|
|
||||||
font-weight: 500;
|
|
||||||
transition: all 0.2s;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
background: rgba(255, 255, 255, 0.1);
|
|
||||||
border-color: rgba(255, 255, 255, 0.18);
|
|
||||||
}
|
|
||||||
|
|
||||||
.dropdown-wrapper.open & {
|
|
||||||
background: rgba(255, 255, 255, 0.1);
|
|
||||||
border-color: rgba(108, 140, 255, 0.4);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.dropdown-arrow {
|
|
||||||
transition: transform 0.2s ease;
|
|
||||||
.dropdown-wrapper.open & {
|
|
||||||
transform: rotate(180deg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.dropdown-menu {
|
|
||||||
position: absolute;
|
|
||||||
bottom: calc(100% + 8px);
|
|
||||||
left: 0;
|
|
||||||
min-width: 180px;
|
|
||||||
background: rgba(20, 25, 50, 0.97);
|
|
||||||
backdrop-filter: blur(12px);
|
|
||||||
border: 1px solid rgba(255, 255, 255, 0.12);
|
|
||||||
border-radius: 12px;
|
|
||||||
padding: 6px;
|
|
||||||
z-index: 100;
|
|
||||||
box-shadow: 0 -8px 32px rgba(0, 0, 0, 0.5);
|
|
||||||
}
|
|
||||||
|
|
||||||
.dropdown-item {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 10px;
|
|
||||||
width: 100%;
|
|
||||||
padding: 10px 14px;
|
|
||||||
border-radius: 8px;
|
|
||||||
border: none;
|
|
||||||
background: none;
|
|
||||||
color: rgba(255, 255, 255, 0.65);
|
|
||||||
cursor: pointer;
|
|
||||||
font-size: 13px;
|
|
||||||
font-weight: 500;
|
|
||||||
transition: all 0.15s;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
background: rgba(255, 255, 255, 0.08);
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
&.active {
|
|
||||||
background: rgba(108, 140, 255, 0.15);
|
|
||||||
color: #6c8cff;
|
|
||||||
}
|
|
||||||
.item-icon {
|
|
||||||
font-size: 14px;
|
|
||||||
}
|
|
||||||
.item-label {
|
|
||||||
flex: 1;
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.dropdown-enter-active,
|
|
||||||
.dropdown-leave-active {
|
|
||||||
transition: all 0.2s ease;
|
|
||||||
}
|
|
||||||
.dropdown-enter-from,
|
|
||||||
.dropdown-leave-to {
|
|
||||||
opacity: 0;
|
|
||||||
transform: translateY(6px) scale(0.96);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ===== 字幕内容 ===== */
|
/* ===== 字幕内容 ===== */
|
||||||
.subtitle-content {
|
.subtitle-content {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
@ -606,7 +230,7 @@ const scrollToBottom = () => {
|
|||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ===== 模式1:AI字幕 ===== */
|
/* ===== AI字幕 ===== */
|
||||||
.ai-only-mode {
|
.ai-only-mode {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: flex-end;
|
align-items: flex-end;
|
||||||
@ -672,125 +296,8 @@ const scrollToBottom = () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ===== 模式2:对话气泡 ===== */
|
|
||||||
.bubble-mode {
|
|
||||||
.chat-list {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
gap: 8px;
|
|
||||||
padding: 2px 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.chat-bubble {
|
|
||||||
animation: bubbleSlide 0.35s ease;
|
|
||||||
|
|
||||||
&.bubble-user {
|
|
||||||
.bubble-body {
|
|
||||||
background: rgba(240, 242, 255, 0.92);
|
|
||||||
border-color: rgba(79, 110, 247, 0.12);
|
|
||||||
border-radius: 14px 14px 4px 14px;
|
|
||||||
margin-left: 24px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.bubble-ai {
|
|
||||||
.bubble-body {
|
|
||||||
background: rgba(20, 30, 50, 0.85);
|
|
||||||
border-color: rgba(52, 211, 153, 0.12);
|
|
||||||
border-radius: 14px 14px 14px 4px;
|
|
||||||
margin-right: 24px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes bubbleSlide {
|
|
||||||
from {
|
|
||||||
opacity: 0;
|
|
||||||
transform: translateY(10px) scale(0.96);
|
|
||||||
}
|
|
||||||
to {
|
|
||||||
opacity: 1;
|
|
||||||
transform: translateY(0) scale(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.bubble-body {
|
|
||||||
padding: 8px 12px;
|
|
||||||
border: 1px solid;
|
|
||||||
min-width: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.bubble-text {
|
|
||||||
font-size: 14px;
|
|
||||||
line-height: 1.6;
|
|
||||||
letter-spacing: 0.2px;
|
|
||||||
word-break: break-word;
|
|
||||||
overflow: hidden;
|
|
||||||
transition: max-height 0.35s ease;
|
|
||||||
|
|
||||||
&.text-user {
|
|
||||||
color: #1a1a1a;
|
|
||||||
text-shadow: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.text-ai {
|
|
||||||
color: #ffffff;
|
|
||||||
text-shadow: 0 1px 3px rgba(0, 0, 0, 0.5);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ===== 模式3:合并气泡 ===== */
|
|
||||||
.merged-mode {
|
|
||||||
.merged-list {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
gap: 8px;
|
|
||||||
padding: 2px 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.merged-bubble {
|
|
||||||
background: rgba(255, 255, 255, 0.02);
|
|
||||||
border: 1px solid rgba(255, 255, 255, 0.04);
|
|
||||||
border-radius: 12px;
|
|
||||||
overflow: hidden;
|
|
||||||
animation: bubbleSlide 0.35s ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
.merged-user-section {
|
|
||||||
padding: 8px 12px;
|
|
||||||
border-bottom: 1px solid rgba(79, 110, 247, 0.08);
|
|
||||||
}
|
|
||||||
|
|
||||||
.merged-ai-section {
|
|
||||||
padding: 8px 12px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.merged-text {
|
|
||||||
font-size: 14px;
|
|
||||||
line-height: 1.6;
|
|
||||||
letter-spacing: 0.2px;
|
|
||||||
word-break: break-word;
|
|
||||||
overflow: hidden;
|
|
||||||
transition: max-height 0.35s ease;
|
|
||||||
|
|
||||||
&.text-user {
|
|
||||||
color: #303030ab;
|
|
||||||
text-shadow: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.text-ai {
|
|
||||||
color: #ffffff;
|
|
||||||
text-shadow: 0 1px 3px rgba(0, 0, 0, 0.5);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ===== 1440×2560 分辨率专用样式 ===== */
|
/* ===== 1440×2560 分辨率专用样式 ===== */
|
||||||
@media (min-width: 1000px) and (min-height: 1680px) {
|
@media (min-width: 1000px) and (min-height: 1680px) {
|
||||||
/* 一级正文:气泡/合并文本/占位符 */
|
|
||||||
.bubble-text,
|
|
||||||
.merged-text,
|
|
||||||
.subtitle-placeholder {
|
.subtitle-placeholder {
|
||||||
font-size: 24px;
|
font-size: 24px;
|
||||||
line-height: 1.75;
|
line-height: 1.75;
|
||||||
@ -806,13 +313,6 @@ const scrollToBottom = () => {
|
|||||||
text-shadow: 0 2px 8px rgba(0, 0, 0, 0.7);
|
text-shadow: 0 2px 8px rgba(0, 0, 0, 0.7);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 二级UI:下拉框/菜单项 */
|
|
||||||
.dropdown-trigger,
|
|
||||||
.dropdown-item {
|
|
||||||
font-size: 20px;
|
|
||||||
font-weight: 500;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 字幕容器:背景与边框适配大字号 */
|
/* 字幕容器:背景与边框适配大字号 */
|
||||||
.ai-subtitle-bar {
|
.ai-subtitle-bar {
|
||||||
padding: 18px 24px;
|
padding: 18px 24px;
|
||||||
@ -825,72 +325,11 @@ const scrollToBottom = () => {
|
|||||||
border: 1px solid rgba(108, 140, 255, 0.15);
|
border: 1px solid rgba(108, 140, 255, 0.15);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 气泡容器:间距与圆角适配 */
|
|
||||||
.bubble-body {
|
|
||||||
padding: 16px 20px;
|
|
||||||
border-radius: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.chat-bubble.bubble-user .bubble-body {
|
|
||||||
border-radius: 20px 20px 6px 20px;
|
|
||||||
margin-left: 36px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.chat-bubble.bubble-ai .bubble-body {
|
|
||||||
border-radius: 20px 20px 20px 6px;
|
|
||||||
margin-right: 36px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.merged-bubble {
|
|
||||||
border-radius: 18px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.merged-user-section,
|
|
||||||
.merged-ai-section {
|
|
||||||
padding: 16px 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 头部区域:间距放大 */
|
|
||||||
.subtitle-header {
|
|
||||||
padding-bottom: 14px;
|
|
||||||
margin-bottom: 14px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dropdown-trigger {
|
|
||||||
padding: 14px 22px;
|
|
||||||
border-radius: 14px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dropdown-item {
|
|
||||||
padding: 16px 22px;
|
|
||||||
border-radius: 12px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 下拉菜单宽度适配 */
|
|
||||||
.dropdown-menu {
|
|
||||||
min-width: 240px;
|
|
||||||
padding: 8px;
|
|
||||||
border-radius: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 滚动指示器:尺寸适配 */
|
/* 滚动指示器:尺寸适配 */
|
||||||
.scroll-hint {
|
.scroll-hint {
|
||||||
width: 40px;
|
width: 40px;
|
||||||
height: 40px;
|
height: 40px;
|
||||||
margin-top: 12px;
|
margin-top: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 聊天列表间距 */
|
|
||||||
.chat-list {
|
|
||||||
gap: 12px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.merged-list {
|
|
||||||
gap: 12px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.bubble-text {
|
|
||||||
font-size: 28px !important;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@ -4,20 +4,27 @@ 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;
|
||||||
// 最短有效语音时长(秒),低于此时长视为无效输入
|
// 最短有效语音时长(秒),低于此时长视为无效输入
|
||||||
const MIN_VALID_DURATION_SEC = 0.5;
|
const MIN_VALID_DURATION_SEC = 0.5;
|
||||||
// 播报超时保护(毫秒):如果FINISHED回调未触发,自动恢复状态
|
// 播报超时保护(毫秒):如果FINISHED回调未触发,自动恢复状态
|
||||||
const BROADCAST_TIMEOUT_MS = 60000;
|
const BROADCAST_TIMEOUT_MS = 60000;
|
||||||
const APPID = "i-sfyjfm4jw2q2g";
|
const APPID = "i-sfyrkdr0ubepa";
|
||||||
const APP_KEY = "f6mgtnb0abt6ph3rihwm";
|
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);
|
||||||
@ -528,8 +536,8 @@ export function useDigitalHuman(options?: {
|
|||||||
token: token.value,
|
token: token.value,
|
||||||
wrapperId: "human-wrapper",
|
wrapperId: "human-wrapper",
|
||||||
connectParams: {
|
connectParams: {
|
||||||
ttsPer: "CAP_4189",
|
ttsPer: "20007751",
|
||||||
figureId: "4000748",
|
figureId: "4000821",
|
||||||
resolutionHeight: 1920,
|
resolutionHeight: 1920,
|
||||||
resolutionWidth: 1080,
|
resolutionWidth: 1080,
|
||||||
inactiveDisconnectSec: 300,
|
inactiveDisconnectSec: 300,
|
||||||
@ -846,7 +854,6 @@ export function useDigitalHuman(options?: {
|
|||||||
// 播报状态
|
// 播报状态
|
||||||
isBroadcasting,
|
isBroadcasting,
|
||||||
// 字幕
|
// 字幕
|
||||||
subtitleMode,
|
|
||||||
currentAISubtitle,
|
currentAISubtitle,
|
||||||
currentUserSubtitle,
|
currentUserSubtitle,
|
||||||
chatMessages,
|
chatMessages,
|
||||||
|
|||||||
@ -1,15 +1,26 @@
|
|||||||
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 =
|
||||||
"https://ai.yantootech.com/polyhedron/api/ark/chat/completions";
|
"https://ai.yantootech.com/polyhedron/api/ark/chat/completions";
|
||||||
const DEFAULT_MODEL = "bot-20260605135355-68pth";
|
const DEFAULT_MODEL = "bot-20260605135355-68pth";
|
||||||
|
|
||||||
|
// ChatBase API 配置
|
||||||
|
const CHATBASE_API_URL = "https://www.chatbase.co/api/v1/chat";
|
||||||
|
const CHATBASE_API_KEY = "ca4616db-417c-4dce-8c65-b9909621f53e";
|
||||||
|
const CHATBASE_CHATBOT_ID = "TRIe58TuVExBm6K0HKTfz";
|
||||||
|
|
||||||
interface LLMMessage {
|
interface LLMMessage {
|
||||||
role: "system" | "user" | "assistant";
|
role: "system" | "user" | "assistant";
|
||||||
content: string;
|
content: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface ChatBaseMessage {
|
||||||
|
content: string;
|
||||||
|
role: "user";
|
||||||
|
}
|
||||||
|
|
||||||
interface LLMChoice {
|
interface LLMChoice {
|
||||||
index: number;
|
index: number;
|
||||||
message: {
|
message: {
|
||||||
@ -41,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> => {
|
||||||
@ -92,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;
|
||||||
@ -105,11 +116,65 @@ export function useLLM() {
|
|||||||
conversationHistory.value = [];
|
conversationHistory.value = [];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const sendToChatBase = async (userMessage: string): Promise<string> => {
|
||||||
|
if (!userMessage.trim()) return "";
|
||||||
|
|
||||||
|
isLoading.value = true;
|
||||||
|
error.value = "";
|
||||||
|
|
||||||
|
try {
|
||||||
|
const messages: ChatBaseMessage[] = [
|
||||||
|
{ content: userMessage, role: "user" },
|
||||||
|
];
|
||||||
|
|
||||||
|
const response = await fetch(CHATBASE_API_URL, {
|
||||||
|
method: "POST",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
Authorization: `Bearer ${CHATBASE_API_KEY}`,
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
messages,
|
||||||
|
chatbotId: CHATBASE_CHATBOT_ID,
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error(`HTTP错误: ${response.status}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const data = await response.json();
|
||||||
|
// 将简体中文回复转换为繁体中文
|
||||||
|
const rawText = data.text || "";
|
||||||
|
const aiReply = OpenCC.Converter({ from: "cn", to: "tw" })(rawText);
|
||||||
|
|
||||||
|
conversationHistory.value.push({
|
||||||
|
role: "user",
|
||||||
|
content: userMessage,
|
||||||
|
});
|
||||||
|
|
||||||
|
conversationHistory.value.push({
|
||||||
|
role: "assistant",
|
||||||
|
content: aiReply,
|
||||||
|
});
|
||||||
|
|
||||||
|
return aiReply;
|
||||||
|
} catch (err: any) {
|
||||||
|
const errorMsg = err.message || "請求失敗";
|
||||||
|
error.value = errorMsg;
|
||||||
|
console.error("ChatBase请求错误:", err);
|
||||||
|
throw err;
|
||||||
|
} finally {
|
||||||
|
isLoading.value = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
isLoading,
|
isLoading,
|
||||||
error,
|
error,
|
||||||
conversationHistory,
|
conversationHistory,
|
||||||
sendToLLM,
|
sendToLLM,
|
||||||
|
sendToChatBase,
|
||||||
clearHistory,
|
clearHistory,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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': '合并气泡',
|
|
||||||
};
|
|
||||||
|
|||||||
@ -4,7 +4,7 @@ import legacy from "@vitejs/plugin-legacy";
|
|||||||
import path from "path";
|
import path from "path";
|
||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
base: "/baidu-digital-human-app",
|
base: "/xg-digital-human-app",
|
||||||
plugins: [
|
plugins: [
|
||||||
vue(),
|
vue(),
|
||||||
legacy({
|
legacy({
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user