Skip to content

Commit d3e73e2

Browse files
committed
2.0.2 新增看板娘功能
1 parent 99d7481 commit d3e73e2

File tree

11 files changed

+265
-41
lines changed

11 files changed

+265
-41
lines changed

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ THChatUI V2 是一个专为**数据敏感型个人/组织/公司**设计的**开
4444
- 支持图片绘制模型
4545
- 国际化:支持简中、英文
4646
- APIKEY管理:支持APIKEY的添加、删除、编辑
47+
- 看板娘:支持看板娘,提供了200+模型
4748

4849
### 设计特性
4950
本项目具有以下特性:
@@ -78,7 +79,7 @@ PC端界面如下:
7879

7980
公众号
8081

81-
![Description](thchat-ui/src/assets/docs_img/qr_code.png)
82+
![Description](https://i.miji.bid/2025/02/25/a91b0353789a3195638a127cf84b6c67.png)
8283

8384
## 快速开发
8485

thchat-ui/package-lock.json

Lines changed: 6 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

thchat-ui/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
"@microsoft/fetch-event-source": "^2.0.1",
1414
"crypto-js": "^4.2.0",
1515
"element-plus": "^2.7.0",
16+
"live2d-helper": "^1.0.1",
1617
"mammoth": "^1.9.0",
1718
"marked": "^15.0.6",
1819
"openai": "^4.77.4",

thchat-ui/src/assets/docs/senior.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,12 @@
44

55
请参考:[THChatUI V2 代码视频讲解教程](https://www.bilibili.com/video/BV1xTcVezEKP/)
66

7+
## 看板娘
8+
9+
请参考:[https://npm.io/package/live2d-helper](https://npm.io/package/live2d-helper)
10+
11+
封装的live2d-helper,可以方便的调用看板娘,并且支持自定义模型。但是功能有限,且用且珍惜。
12+
713
## 数据schema
814

915
THChatUI运行时,数据存储在两个地方:

thchat-ui/src/plugins/locales/en-US.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ export default {
1616
general: 'General',
1717
key: 'API Key',
1818
knowledge: 'Knowledge Base',
19-
web_search: 'Web Search'
19+
web_search: 'Web Search',
20+
live2d: 'Live2D'
2021
},
2122
model: {
2223
platform: 'Platform',
@@ -62,6 +63,10 @@ export default {
6263
},
6364
web_search: {
6465
enable: 'Enable'
66+
},
67+
live2d: {
68+
enable: 'Enable',
69+
model: 'Model'
6570
}
6671
},
6772
AppAside: {

thchat-ui/src/plugins/locales/zh-CN.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ export default {
1616
general: "通用",
1717
key: "API Key",
1818
knowledge: "知识库",
19-
web_search: "联网搜索"
19+
web_search: "联网搜索",
20+
live2d: "动漫人物"
2021
},
2122
model: {
2223
platform: "平台",
@@ -62,6 +63,10 @@ export default {
6263
},
6364
web_search: {
6465
enable: "启用"
66+
},
67+
live2d: {
68+
enable: "启用",
69+
model: "模型"
6570
}
6671
},
6772
AppAside: {

thchat-ui/src/store/setting.js

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,14 @@ const defaultSettings = {
7676
kb_enabled: false,
7777
/******************************** 联网搜索参数 ********************************/
7878
// 是否启用联网搜索
79-
web_search_enabled: false
79+
web_search_enabled: false,
80+
/******************************** 看板娘设置 ********************************/
81+
// 是否启用看板娘
82+
live2d_enabled: true,
83+
// 看板娘模型索引
84+
live2d_model_index: 0,
85+
// 看板娘模型
86+
live2d_model: "https://raw.githubusercontent.com/zenghongtu/live2d-model-assets/master/assets/moc/22.xmas.1/22.2017.newyear.model.json"
8087
}
8188

8289
const setting = {

thchat-ui/src/views/AppMain.vue

Lines changed: 109 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
<div class="home" ref="homeRef">
33

44
<el-row :gutter="24" justify="center" style="margin-left: 0;margin-right: 0;">
5+
56
<el-col :md="18" :sm="22" :xs="22">
67
<ChatCard :qaId="c['qaId']" :query="c['query']" :answer="c['answer']" :modelName="c['modelName']"
78
:series="c['series']" :responseTime="c['responseTime']" :finishTime="c['finishTime']"
@@ -19,14 +20,24 @@
1920
</div>
2021
</div>
2122
</el-col>
23+
24+
<canvas id="live2d"></canvas>
2225
</el-row>
2326
</div>
2427
</template>
2528

2629
<script>
30+
import loadLive2d from 'live2d-helper'
2731
2832
export default {
2933
name: 'AppMain',
34+
data() {
35+
return {
36+
isLive2dLoading: false,
37+
live2dError: null,
38+
live2dInstance: null // 添加实例引用
39+
}
40+
},
3041
computed: {
3142
// 当前激活的聊天记录uuid
3243
active() {
@@ -40,55 +51,103 @@ export default {
4051
// 等app数据加载之后再执行逻辑 否则会闪屏
4152
is_show() {
4253
return this.$store.state.app.ready && this.active_session_qa_data.length === 0;
54+
},
55+
// 看板娘启用状态
56+
live2dEnabled() {
57+
return this.$store.state.setting.live2d_enabled || false;
58+
},
59+
// 当前看板娘模型
60+
currentLive2dModel() {
61+
return this.$store.state.setting.live2d_model || null;
4362
}
4463
},
45-
watch: {
46-
// 监听chat的变化,当变化时,表示在Bot回答,此时需要刷新滚动条的位置
47-
"$store.state.app.chat": {
48-
deep: true, //深度监听设置为 true
49-
handler: function (newVal, oldVal) {
50-
// 检查是否滚动到底部 给200px的误差控制 这里的200px可以根据实际需求调整
51-
let isAtBottom = this.$refs.homeRef.scrollTop + this.$refs.homeRef.clientHeight >= this.$refs.homeRef.scrollHeight - 200;
52-
if (!isAtBottom) {
53-
return;
64+
methods: {
65+
// 统一处理滚动
66+
scrollToBottom() {
67+
this.$nextTick(() => {
68+
if (this.$refs.homeRef) {
69+
this.$refs.homeRef.scrollTop = this.$refs.homeRef.scrollHeight;
5470
}
55-
// 内容更新时,保持滚动条的位置
56-
this.$nextTick(() => {
57-
this.$refs.homeRef.scrollTop = this.$refs.homeRef.scrollHeight
58-
});
59-
}
71+
});
6072
},
61-
// 监听active的变化,当变化时,表示切换了聊天选项卡,此时需要把滚动条的位置设置到最下方
62-
"$store.state.app.active": {
63-
deep: true, //深度监听设置为 true
64-
handler: function (newVal, oldVal) {
65-
// 内容更新时,保持滚动条的位置
66-
this.$nextTick(() => {
67-
this.$refs.homeRef.scrollTop = this.$refs.homeRef.scrollHeight
73+
// 初始化Live2D
74+
async initLive2d() {
75+
if (window.innerWidth <= 768 || !this.live2dEnabled || !this.currentLive2dModel) {
76+
if (this.live2dInstance) {
77+
// 清理现有实例
78+
this.live2dInstance.dispose && this.live2dInstance.dispose();
79+
this.live2dInstance = null;
80+
}
81+
return;
82+
}
83+
84+
this.isLive2dLoading = true;
85+
this.live2dError = null;
86+
87+
try {
88+
// 清理现有实例
89+
if (this.live2dInstance) {
90+
this.live2dInstance.dispose && this.live2dInstance.dispose();
91+
}
92+
93+
this.live2dInstance = await loadLive2d({
94+
canvas: "live2d",
95+
baseUrl: this.currentLive2dModel.substring(0, this.currentLive2dModel.lastIndexOf('/')),
96+
model: this.currentLive2dModel,
97+
globalFollowPointer: true,
98+
allowSound: true,
99+
height: "800"
68100
});
101+
} catch (error) {
102+
console.error('Live2D 加载失败:', error);
103+
this.live2dError = error.message || '初始化失败';
104+
} finally {
105+
this.isLive2dLoading = false;
69106
}
70107
},
71-
query: function (newVal, oldVal) {
72-
// 内容更新时,保持滚动条的位置
73-
this.$nextTick(() => {
74-
this.$refs.homeRef.scrollTop = this.$refs.homeRef.scrollHeight
75-
});
76-
}
77-
},
78-
created() {
79-
// 内容更新时,保持滚动条的位置
80-
this.$nextTick(() => {
81-
this.$refs.homeRef.scrollTop = this.$refs.homeRef.scrollHeight
82-
});
83-
},
84-
methods: {
85108
/**
86109
* 跳转页面函数
87110
* @param path
88111
*/
89112
goTo(path) {
90113
this.$router.push(path)
91114
}
115+
},
116+
watch: {
117+
"$store.state.app.chat": {
118+
deep: true,
119+
handler: function(newVal, oldVal) {
120+
const isAtBottom = this.$refs.homeRef.scrollTop + this.$refs.homeRef.clientHeight >= this.$refs.homeRef.scrollHeight - 200;
121+
if (isAtBottom) {
122+
this.scrollToBottom();
123+
}
124+
}
125+
},
126+
"$store.state.app.active": {
127+
deep: true,
128+
handler: function() {
129+
this.scrollToBottom();
130+
}
131+
},
132+
query() {
133+
this.scrollToBottom();
134+
},
135+
currentLive2dModel: {
136+
handler: function() {
137+
this.initLive2d();
138+
}
139+
},
140+
live2dEnabled: {
141+
handler: function() {
142+
this.initLive2d();
143+
}
144+
}
145+
},
146+
mounted() {
147+
this.initLive2d();
148+
},
149+
created() {
150+
this.scrollToBottom();
92151
}
93152
}
94153
</script>
@@ -151,4 +210,19 @@ export default {
151210
.title-container .sub-title-line {
152211
font-size: 15px;
153212
}
213+
214+
/* 修改live2d容器样式 */
215+
#live2d {
216+
// border: 1px solid #000;
217+
width: 200px;
218+
position: fixed; /* 改为固定定位 */
219+
bottom: 82px; /* 固定在底部 */
220+
right: -20px; /* 固定在右侧 */
221+
z-index: 100; /* 确保在其他元素上层 */
222+
223+
/* 在小屏幕设备上隐藏live2d */
224+
@media screen and (max-width: 768px) {
225+
display: none;
226+
}
227+
}
154228
</style>

thchat-ui/src/views/about/index.vue

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
>
2626
<template #content>
2727
<img
28-
:src="require('@/assets/docs_img/qr_code.png')"
28+
:src="require('https://i.miji.bid/2025/02/25/a91b0353789a3195638a127cf84b6c67.png')"
2929
alt="公众号二维码"
3030
class="qrcode-image"
3131
/>
@@ -39,6 +39,14 @@
3939
<div class="changelog-section">
4040
<h2>更新日志</h2>
4141

42+
<div class="version-block">
43+
<h3>v2.0.2 - 2025.02.25</h3>
44+
<ul>
45+
<li>[add] 新增了对看板娘的支持</li>
46+
<li>[add] 新增了200+看板娘模型,感谢 https://github.com/zenghongtu/live2d-model-assets</li>
47+
</ul>
48+
</div>
49+
4250
<div class="version-block">
4351
<h3>v2.0.1 - 2025.02.16</h3>
4452
<ul>

0 commit comments

Comments
 (0)