feat: ✨ 完善会话管理,新增回话管理详情接口和覆盖修改逻辑

This commit is contained in:
何嘉悦
2025-05-26 19:48:39 +08:00
parent b00380d617
commit edbb5ec5ba
11 changed files with 192 additions and 84 deletions
+116 -60
View File
@@ -3,7 +3,13 @@ import { ChatLineRound } from '@element-plus/icons-vue';
import { defineStore } from 'pinia';
import { markRaw } from 'vue';
import { useRouter } from 'vue-router';
import { create_session, delete_session, get_session_list, update_session } from '@/api/session';
import {
create_session,
delete_session,
get_session,
get_session_list,
update_session,
} from '@/api/session';
import { useUserStore } from './user';
export const useSessionStore = defineStore('session', () => {
@@ -28,49 +34,18 @@ export const useSessionStore = defineStore('session', () => {
// 创建新对话(按钮点击)
const createSessionBtn = async () => {
try {
// 清空当前选中会话信息
setCurrentSession(null);
router.replace({ name: 'chat' });
currentSession.value = null;
}
catch (error) {
console.error('createSessionBtn错误:', error);
}
};
// 发送消息后创建新会话(并插入列表顶部)
const createSessionList = async (data: Omit<CreateSessionDTO, 'id'>) => {
try {
const res = await create_session(data);
console.log('并插入列表顶部 res', res);
// 构造新会话对象(根据接口实际返回调整)
const newSession: ChatSessionVo = {
...data,
sessionTitle: data.sessionTitle || '新对话',
prefixIcon: markRaw(ChatLineRound),
};
// 插入到列表顶部(触发视图更新)
sessionList.value.unshift(newSession);
// 跳转聊天页
router.replace({
name: 'chatWithId',
params: { id: `${res.data}` },
});
// 重置分页状态(新增会话后,后续加载从第一页重新开始)
currentPage.value = 1;
hasMore.value = true;
}
catch (error) {
console.error('createSessionList错误:', error);
}
};
// 获取会话列表(核心分页方法)
const requestSessionList = async (page: number = currentPage.value) => {
if ((page > 1 && !hasMore.value) || isLoading.value || isLoadingMore.value)
const requestSessionList = async (page: number = currentPage.value, force: boolean = false) => {
if (!force && ((page > 1 && !hasMore.value) || isLoading.value || isLoadingMore.value))
return;
isLoading.value = page === 1; // 第一页时标记为全局加载
@@ -81,37 +56,42 @@ export const useSessionStore = defineStore('session', () => {
userId: userStore.userInfo?.userId as number,
pageNum: page,
pageSize: pageSize.value,
isAsc: 'desc',
orderByColumn: 'createTime',
};
const res = await get_session_list(params);
const resArr = await get_session_list(params);
// 第一页:覆盖原有数据;非第一页:合并新数据
// 预处理会话分组
const res = processSessions(resArr.rows);
const allSessions = new Map(sessionList.value.map(item => [item.id, item])); // 现有所有数据
res.forEach(item =>
allSessions.set(item.id, { ...item, prefixIcon: markRaw(ChatLineRound) }),
); // 更新/添加数据
// 按服务端排序重建列表(假设分页数据是按时间倒序,第一页是最新,后续页依次递减)
// 此处需根据接口返回的排序规则调整,假设每页数据是递增的(第一页最新,第二页次新,第三页 oldest)
if (page === 1) {
sessionList.value
= res.rows?.map((item: ChatSessionVo) => {
return {
...item,
prefixIcon: markRaw(ChatLineRound),
};
}) || [];
// 第一页是最新数据,应排在列表前面
sessionList.value = [
...res, // 新的第一页数据(最新)
...Array.from(allSessions.values()).filter(item => !res.some(r => r.id === item.id)), // 保留未被第一页覆盖的旧数据
];
}
else {
// 去重处理(避免接口返回重复数据)
const existingIds = new Set(sessionList.value.map(item => item.id));
const newRows = (
res.rows?.map((item: ChatSessionVo) => {
return {
...item,
prefixIcon: markRaw(ChatLineRound),
};
}) || []
).filter(item => !existingIds.has(item.id));
sessionList.value.push(...newRows);
// 非第一页数据是更旧的数据,追加到列表末尾
sessionList.value = [
...sessionList.value.filter(item => !res.some(r => r.id === item.id)), // 保留现有数据(除了被当前页更新的)
...res, // 追加当前页的新数据(更旧的)
];
}
// 判断是否还有更多数据(当前页数据量 < pageSize 则无更多)
hasMore.value = (res.rows?.length || 0) === pageSize.value;
currentPage.value = page;
if (!force)
hasMore.value = (res?.length || 0) === pageSize.value;
if (!force)
currentPage.value = page; // 仅非强制刷新时更新页码
}
catch (error) {
console.error('requestSessionList错误:', error);
@@ -122,6 +102,35 @@ export const useSessionStore = defineStore('session', () => {
}
};
// 发送消息后创建新会话
const createSessionList = async (data: Omit<CreateSessionDTO, 'id'>) => {
try {
const res = await create_session(data);
// 创建会话后立刻查询列表会话
// 1. 先找到被修改会话在 sessionList 中的索引(假设 sessionList 是按服务端排序的完整列表)
const targetIndex = sessionList.value.findIndex(session => session.id === `${res.data}`);
// 2. 计算该会话所在的页码(页大小固定为 pageSize.value)
const targetPage
= targetIndex >= 0
? Math.floor(targetIndex / pageSize.value) + 1 // 索引从0开始,页码从1开始
: 1; // 未找到时默认刷新第一页(可能因排序变化导致位置改变)
// 3. 刷新目标页数据
await requestSessionList(targetPage, true);
// 并将当前勾选信息设置为新增的会话信息
const newSessionRes = await get_session(`${res.data}`);
setCurrentSession(newSessionRes.data);
// 跳转聊天页
router.replace({
name: 'chatWithId',
params: { id: `${res.data}` },
});
}
catch (error) {
console.error('createSessionList错误:', error);
}
};
// 加载更多会话(供组件调用)
const loadMoreSessions = async () => {
if (hasMore.value)
@@ -132,7 +141,15 @@ export const useSessionStore = defineStore('session', () => {
const updateSession = async (item: ChatSessionVo) => {
try {
await update_session(item);
await requestSessionList(currentPage.value);
// 1. 先找到被修改会话在 sessionList 中的索引(假设 sessionList 是按服务端排序的完整列表)
const targetIndex = sessionList.value.findIndex(session => session.id === item.id);
// 2. 计算该会话所在的页码(页大小固定为 pageSize.value)
const targetPage
= targetIndex >= 0
? Math.floor(targetIndex / pageSize.value) + 1 // 索引从0开始,页码从1开始
: 1; // 未找到时默认刷新第一页(可能因排序变化导致位置改变)
// 3. 刷新目标页数据
await requestSessionList(targetPage, true);
}
catch (error) {
console.error('updateSession错误:', error);
@@ -143,13 +160,52 @@ export const useSessionStore = defineStore('session', () => {
const deleteSessions = async (ids: string[]) => {
try {
await delete_session(ids);
await requestSessionList(currentPage.value);
// 1. 先找到被修改会话在 sessionList 中的索引(假设 sessionList 是按服务端排序的完整列表)
const targetIndex = sessionList.value.findIndex(session => session.id === ids[0]);
// 2. 计算该会话所在的页码(页大小固定为 pageSize.value)
const targetPage
= targetIndex >= 0
? Math.floor(targetIndex / pageSize.value) + 1 // 索引从0开始,页码从1开始
: 1; // 未找到时默认刷新第一页(可能因排序变化导致位置改变)
// 3. 刷新目标页数据
await requestSessionList(targetPage, true);
}
catch (error) {
console.error('deleteSessions错误:', error);
}
};
// 在获取会话列表后添加预处理逻辑(示例)
function processSessions(sessions: ChatSessionVo[]) {
const currentDate = new Date();
return sessions.map((session) => {
const createDate = new Date(session.createTime!);
const diffDays = Math.floor(
(currentDate.getTime() - createDate.getTime()) / (1000 * 60 * 60 * 24),
);
// 生成原始分组键(用于排序和分组)
let group: string;
if (diffDays < 7) {
group = '7 天内'; // 用数字前缀确保排序正确
}
else if (diffDays < 30) {
group = '30 天内';
}
else {
const year = createDate.getFullYear();
const month = String(createDate.getMonth() + 1).padStart(2, '0');
group = `${year}-${month}`; // 格式:2025-05
}
return {
...session,
group, // 新增分组键字段
};
});
}
return {
// 当前选中的会话
currentSession,