Skip to content

Commit 6224602

Browse files
committed
【代码优化】AI:聊天对话 index.vue 代码梳理 80%(message 部分)
1 parent 1a6afa3 commit 6224602

File tree

6 files changed

+137
-185
lines changed

6 files changed

+137
-185
lines changed

src/views/ai/chat/index/components/conversation/ConversationList.vue

Lines changed: 65 additions & 106 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
<!-- AI 对话 -->
22
<template>
3-
<el-aside width="260px" class="conversation-container" style="height: 100%">
3+
<el-aside width="260px" class="conversation-container h-100%">
44
<!-- 左顶部:对话 -->
5-
<div style="height: 100%">
5+
<div class="h-100%">
66
<el-button class="w-1/1 btn-new-conversation" type="primary" @click="createConversation">
77
<Icon icon="ep:plus" class="mr-5px" />
88
新建对话
@@ -23,8 +23,9 @@
2323

2424
<!-- 左中间:对话列表 -->
2525
<div class="conversation-list">
26+
<!-- 情况一:加载中 -->
2627
<el-empty v-if="loading" description="." :v-loading="loading" />
27-
28+
<!-- 情况二:按照 group 分组,展示聊天会话 list 列表 -->
2829
<div v-for="conversationKey in Object.keys(conversationMap)" :key="conversationKey">
2930
<div
3031
class="conversation-item classify-title"
@@ -50,7 +51,7 @@
5051
<span class="title">{{ conversation.title }}</span>
5152
</div>
5253
<div class="button-wrapper" v-show="hoverConversationId === conversation.id">
53-
<el-button class="btn" link @click.stop="handlerTop(conversation)">
54+
<el-button class="btn" link @click.stop="handleTop(conversation)">
5455
<el-icon title="置顶" v-if="!conversation.pinned"><Top /></el-icon>
5556
<el-icon title="置顶" v-if="conversation.pinned"><Bottom /></el-icon>
5657
</el-button>
@@ -68,13 +69,12 @@
6869
</div>
6970
</div>
7071
</div>
71-
<!-- 底部站位 -->
72-
<div style="height: 160px; width: 100%"></div>
72+
<!-- 底部占位 -->
73+
<div class="h-160px w-100%"></div>
7374
</div>
7475
</div>
7576

7677
<!-- 左底部:工具栏 -->
77-
<!-- TODO @fan:下面两个 icon,可以使用类似 <Icon icon="ep:question-filled" /> 替代哈 -->
7878
<div class="tool-box">
7979
<div @click="handleRoleRepository">
8080
<Icon icon="ep:user" />
@@ -86,31 +86,27 @@
8686
</div>
8787
</div>
8888

89-
<!-- ============= 额外组件 ============= -->
90-
9189
<!-- 角色仓库抽屉 -->
92-
<el-drawer v-model="drawer" title="角色仓库" size="754px">
93-
<Role />
90+
<el-drawer v-model="roleRepositoryOpen" title="角色仓库" size="754px">
91+
<RoleRepository />
9492
</el-drawer>
9593
</el-aside>
9694
</template>
9795

9896
<script setup lang="ts">
9997
import { ChatConversationApi, ChatConversationVO } from '@/api/ai/chat/conversation'
100-
import { ref } from 'vue'
101-
import Role from '../role/index.vue'
98+
import RoleRepository from '../role/RoleRepository.vue'
10299
import { Bottom, Top } from '@element-plus/icons-vue'
103100
import roleAvatarDefaultImg from '@/assets/ai/gpt.svg'
104101
105102
const message = useMessage() // 消息弹窗
106103
107104
// 定义属性
108105
const searchName = ref<string>('') // 对话搜索
109-
const activeConversationId = ref<string | null>(null) // 选中的对话,默认为 null
110-
const hoverConversationId = ref<string | null>(null) // 悬浮上去的对话
106+
const activeConversationId = ref<number | null>(null) // 选中的对话,默认为 null
107+
const hoverConversationId = ref<number | null>(null) // 悬浮上去的对话
111108
const conversationList = ref([] as ChatConversationVO[]) // 对话列表
112109
const conversationMap = ref<any>({}) // 对话分组 (置顶、今天、三天前、一星期前、一个月前)
113-
const drawer = ref<boolean>(false) // 角色仓库抽屉 TODO @fan:roleDrawer 会不会好点哈
114110
const loading = ref<boolean>(false) // 加载中
115111
const loadingTime = ref<any>() // 加载中定时器
116112
@@ -130,75 +126,58 @@ const emits = defineEmits([
130126
'onConversationDelete'
131127
])
132128
133-
/**
134-
* 对话 - 搜索
135-
*/
129+
/** 搜索对话 */
136130
const searchConversation = async (e) => {
137131
// 恢复数据
138132
if (!searchName.value.trim().length) {
139-
conversationMap.value = await conversationTimeGroup(conversationList.value)
133+
conversationMap.value = await getConversationGroupByCreateTime(conversationList.value)
140134
} else {
141135
// 过滤
142136
const filterValues = conversationList.value.filter((item) => {
143137
return item.title.includes(searchName.value.trim())
144138
})
145-
conversationMap.value = await conversationTimeGroup(filterValues)
139+
conversationMap.value = await getConversationGroupByCreateTime(filterValues)
146140
}
147141
}
148142
149-
/**
150-
* 对话 - 点击
151-
*/
152-
const handleConversationClick = async (id: string) => {
143+
/** 点击对话 */
144+
const handleConversationClick = async (id: number) => {
153145
// 过滤出选中的对话
154146
const filterConversation = conversationList.value.filter((item) => {
155147
return item.id === id
156148
})
157149
// 回调 onConversationClick
158-
// TODO @fan: 这里 idea 会报黄色警告,有办法解下么?
159-
const res = emits('onConversationClick', filterConversation[0])
150+
// noinspection JSVoidFunctionReturnValueUsed
151+
const success = emits('onConversationClick', filterConversation[0])
160152
// 切换对话
161-
if (res) {
153+
if (success) {
162154
activeConversationId.value = id
163155
}
164156
}
165157
166-
/**
167-
* 对话 - 获取列表
168-
*/
158+
/** 获取对话列表 */
169159
const getChatConversationList = async () => {
170160
try {
171-
// 0. 加载中
161+
// 加载中
172162
loadingTime.value = setTimeout(() => {
173163
loading.value = true
174164
}, 50)
175-
// 1. 获取 对话数据
176-
const res = await ChatConversationApi.getChatConversationMyList()
177-
// 2. 排序
178-
res.sort((a, b) => {
165+
166+
// 1.1 获取 对话数据
167+
conversationList.value = await ChatConversationApi.getChatConversationMyList()
168+
// 1.2 排序
169+
conversationList.value.sort((a, b) => {
179170
return b.createTime - a.createTime
180171
})
181-
conversationList.value = res
182-
// 3. 默认选中
183-
if (!activeId?.value) {
184-
// await handleConversationClick(res[0].id)
185-
} else {
186-
// tip: 删除的刚好是选中的,那么需要重新挑选一个来进行选中
187-
// const filterConversationList = conversationList.value.filter(item => {
188-
// return item.id === activeId.value
189-
// })
190-
// if (filterConversationList.length <= 0) {
191-
// await handleConversationClick(res[0].id)
192-
// }
193-
}
194-
// 4. 没有任何对话情况
172+
// 1.3 没有任何对话情况
195173
if (conversationList.value.length === 0) {
196174
activeConversationId.value = null
197175
conversationMap.value = {}
198176
return
199177
}
200-
// 5. 对话根据时间分组(置顶、今天、一天前、三天前、七天前、30天前)
201-
conversationMap.value = await conversationTimeGroup(conversationList.value)
178+
179+
// 2. 对话根据时间分组(置顶、今天、一天前、三天前、七天前、30 天前)
180+
conversationMap.value = await getConversationGroupByCreateTime(conversationList.value)
202181
} finally {
203182
// 清理定时器
204183
if (loadingTime.value) {
@@ -209,8 +188,10 @@ const getChatConversationList = async () => {
209188
}
210189
}
211190
212-
const conversationTimeGroup = async (list: ChatConversationVO[]) => {
191+
/** 按照 creteTime 创建时间,进行分组 */
192+
const getConversationGroupByCreateTime = async (list: ChatConversationVO[]) => {
213193
// 排序、指定、时间分组(今天、一天前、三天前、七天前、30天前)
194+
// noinspection NonAsciiCharacters
214195
const groupMap = {
215196
置顶: [],
216197
今天: [],
@@ -233,7 +214,7 @@ const conversationTimeGroup = async (list: ChatConversationVO[]) => {
233214
continue
234215
}
235216
// 计算时间差(单位:毫秒)
236-
const diff = now - conversation.updateTime
217+
const diff = now - conversation.createTime
237218
// 根据时间间隔判断
238219
if (diff < oneDay) {
239220
groupMap['今天'].push(conversation)
@@ -250,9 +231,7 @@ const conversationTimeGroup = async (list: ChatConversationVO[]) => {
250231
return groupMap
251232
}
252233
253-
/**
254-
* 对话 - 新建
255-
*/
234+
/** 新建对话 */
256235
const createConversation = async () => {
257236
// 1. 新建对话
258237
const conversationId = await ChatConversationApi.createChatConversationMy(
@@ -266,9 +245,7 @@ const createConversation = async () => {
266245
emits('onConversationCreate')
267246
}
268247
269-
/**
270-
* 对话 - 更新标题
271-
*/
248+
/** 修改对话的标题 */
272249
const updateConversationTitle = async (conversation: ChatConversationVO) => {
273250
// 1. 二次确认
274251
const { value } = await ElMessageBox.prompt('修改标题', {
@@ -296,9 +273,7 @@ const updateConversationTitle = async (conversation: ChatConversationVO) => {
296273
}
297274
}
298275
299-
/**
300-
* 删除聊天对话
301-
*/
276+
/** 删除聊天对话 */
302277
const deleteChatConversation = async (conversation: ChatConversationVO) => {
303278
try {
304279
// 删除的二次确认
@@ -313,72 +288,56 @@ const deleteChatConversation = async (conversation: ChatConversationVO) => {
313288
} catch {}
314289
}
315290
316-
/**
317-
* 对话置顶
318-
*/
319-
// TODO @fan:应该是 handleXXX,handler 是名词哈
320-
const handlerTop = async (conversation: ChatConversationVO) => {
291+
/** 清空对话 */
292+
const handleClearConversation = async () => {
293+
try {
294+
await message.confirm('确认后对话会全部清空,置顶的对话除外。')
295+
await ChatConversationApi.deleteChatConversationMyByUnpinned()
296+
ElMessage({
297+
message: '操作成功!',
298+
type: 'success'
299+
})
300+
// 清空 对话 和 对话内容
301+
activeConversationId.value = null
302+
// 获取 对话列表
303+
await getChatConversationList()
304+
// 回调 方法
305+
emits('onConversationClear')
306+
} catch {}
307+
}
308+
309+
/** 对话置顶 */
310+
const handleTop = async (conversation: ChatConversationVO) => {
321311
// 更新对话置顶
322312
conversation.pinned = !conversation.pinned
323313
await ChatConversationApi.updateChatConversationMy(conversation)
324314
// 刷新对话
325315
await getChatConversationList()
326316
}
327317
328-
// TODO @fan:类似 ============ 分块的,最后后面也有 ============ 哈
329-
// ============ 角色仓库
318+
// ============ 角色仓库 ============
330319
331-
/**
332-
* 角色仓库抽屉
333-
*/
320+
/** 角色仓库抽屉 */
321+
const roleRepositoryOpen = ref<boolean>(false) // 角色仓库是否打开
334322
const handleRoleRepository = async () => {
335-
drawer.value = !drawer.value
336-
}
337-
338-
// ============= 清空对话
339-
340-
/**
341-
* 清空对话
342-
*/
343-
const handleClearConversation = async () => {
344-
// TODO @fan:可以使用 await message.confirm( 简化,然后使用 await 改成同步的逻辑,会更简洁
345-
ElMessageBox.confirm('确认后对话会全部清空,置顶的对话除外。', '确认提示', {
346-
confirmButtonText: '确认',
347-
cancelButtonText: '取消',
348-
type: 'warning'
349-
})
350-
.then(async () => {
351-
await ChatConversationApi.deleteChatConversationMyByUnpinned()
352-
ElMessage({
353-
message: '操作成功!',
354-
type: 'success'
355-
})
356-
// 清空 对话 和 对话内容
357-
activeConversationId.value = null
358-
// 获取 对话列表
359-
await getChatConversationList()
360-
// 回调 方法
361-
emits('onConversationClear')
362-
})
363-
.catch(() => {})
323+
roleRepositoryOpen.value = !roleRepositoryOpen.value
364324
}
365325
366-
// ============ 组件 onMounted
367-
326+
/** 监听选中的对话 */
368327
const { activeId } = toRefs(props)
369328
watch(activeId, async (newValue, oldValue) => {
370-
// 更新选中
371329
activeConversationId.value = newValue as string
372330
})
373331
374332
// 定义 public 方法
375333
defineExpose({ createConversation })
376334
335+
/** 初始化 */
377336
onMounted(async () => {
378337
// 获取 对话列表
379338
await getChatConversationList()
380339
// 默认选中
381-
if (props.activeId != null) {
340+
if (props.activeId) {
382341
activeConversationId.value = props.activeId
383342
} else {
384343
// 首次默认选中第一个

src/views/ai/chat/index/components/role/RoleCategoryList.vue

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,20 @@
11
<template>
22
<div class="category-list">
3-
<div class="category" v-for="(category) in categoryList" :key="category">
4-
<el-button plain round size="small" v-if="category !== active" @click="handleCategoryClick(category)">{{ category }}</el-button>
5-
<el-button plain round size="small" v-else type="primary" @click="handleCategoryClick(category)">{{ category }}</el-button>
3+
<div class="category" v-for="category in categoryList" :key="category">
4+
<el-button
5+
plain
6+
round
7+
size="small"
8+
:type="category === active ? 'primary' : ''"
9+
@click="handleCategoryClick(category)"
10+
>
11+
{{ category }}
12+
</el-button>
613
</div>
714
</div>
815
</template>
916
<script setup lang="ts">
10-
import {PropType} from "vue";
17+
import { PropType } from 'vue'
1118
1219
// 定义属性
1320
defineProps({
@@ -25,11 +32,10 @@ defineProps({
2532
// 定义回调
2633
const emits = defineEmits(['onCategoryClick'])
2734
28-
// 处理分类点击事件
29-
const handleCategoryClick = async (category) => {
35+
/** 处理分类点击事件 */
36+
const handleCategoryClick = async (category: string) => {
3037
emits('onCategoryClick', category)
3138
}
32-
3339
</script>
3440
<style scoped lang="scss">
3541
.category-list {

0 commit comments

Comments
 (0)