KnowledgeBase_frontend/src/store/chat/chat.slice.js

191 lines
6.8 KiB
JavaScript

import { createSlice } from '@reduxjs/toolkit';
import { fetchChats, createChat, deleteChat, updateChat } from './chat.thunks';
import { fetchMessages, sendMessage } from './chat.messages.thunks';
// 初始状态
const initialState = {
// 聊天列表
list: {
items: [],
total: 0,
page: 1,
page_size: 10,
status: 'idle', // 'idle' | 'loading' | 'succeeded' | 'failed'
error: null,
},
// 当前聊天
currentChat: {
data: null,
status: 'idle', // 'idle' | 'loading' | 'succeeded' | 'failed'
error: null,
},
// 聊天消息
messages: {
items: [],
status: 'idle', // 'idle' | 'loading' | 'succeeded' | 'failed'
error: null,
},
// 发送消息状态
sendMessage: {
status: 'idle', // 'idle' | 'loading' | 'succeeded' | 'failed'
error: null,
},
// 操作状态(创建、更新、删除)
operations: {
status: 'idle', // 'idle' | 'loading' | 'succeeded' | 'failed'
error: null,
},
};
// 创建 slice
const chatSlice = createSlice({
name: 'chat',
initialState,
reducers: {
// 重置操作状态
resetOperationStatus: (state) => {
state.operations.status = 'idle';
state.operations.error = null;
},
// 重置当前聊天
resetCurrentChat: (state) => {
state.currentChat.data = null;
state.currentChat.status = 'idle';
state.currentChat.error = null;
},
// 设置当前聊天
setCurrentChat: (state, action) => {
state.currentChat.data = action.payload;
state.currentChat.status = 'succeeded';
},
// 重置消息状态
resetMessages: (state) => {
state.messages.items = [];
state.messages.status = 'idle';
state.messages.error = null;
},
// 重置发送消息状态
resetSendMessageStatus: (state) => {
state.sendMessage.status = 'idle';
state.sendMessage.error = null;
},
},
extraReducers: (builder) => {
// 获取聊天列表
builder
.addCase(fetchChats.pending, (state) => {
state.list.status = 'loading';
})
.addCase(fetchChats.fulfilled, (state, action) => {
state.list.status = 'succeeded';
state.list.items = action.payload.results;
state.list.total = action.payload.total;
state.list.page = action.payload.page;
state.list.page_size = action.payload.page_size;
})
.addCase(fetchChats.rejected, (state, action) => {
state.list.status = 'failed';
state.list.error = action.payload || action.error.message;
})
// 创建聊天
.addCase(createChat.pending, (state) => {
state.operations.status = 'loading';
})
.addCase(createChat.fulfilled, (state, action) => {
state.operations.status = 'succeeded';
state.list.items.unshift(action.payload);
state.list.total += 1;
state.currentChat.data = action.payload;
state.currentChat.status = 'succeeded';
})
.addCase(createChat.rejected, (state, action) => {
state.operations.status = 'failed';
state.operations.error = action.payload || action.error.message;
})
// 删除聊天
.addCase(deleteChat.pending, (state) => {
state.operations.status = 'loading';
})
.addCase(deleteChat.fulfilled, (state, action) => {
state.operations.status = 'succeeded';
state.list.items = state.list.items.filter((chat) => chat.id !== action.payload);
state.list.total -= 1;
if (state.currentChat.data && state.currentChat.data.id === action.payload) {
state.currentChat.data = null;
}
})
.addCase(deleteChat.rejected, (state, action) => {
state.operations.status = 'failed';
state.operations.error = action.payload || action.error.message;
})
// 更新聊天
.addCase(updateChat.pending, (state) => {
state.operations.status = 'loading';
})
.addCase(updateChat.fulfilled, (state, action) => {
state.operations.status = 'succeeded';
const index = state.list.items.findIndex((chat) => chat.id === action.payload.id);
if (index !== -1) {
state.list.items[index] = action.payload;
}
if (state.currentChat.data && state.currentChat.data.id === action.payload.id) {
state.currentChat.data = action.payload;
}
})
.addCase(updateChat.rejected, (state, action) => {
state.operations.status = 'failed';
state.operations.error = action.payload || action.error.message;
})
// 获取聊天消息
.addCase(fetchMessages.pending, (state) => {
state.messages.status = 'loading';
})
.addCase(fetchMessages.fulfilled, (state, action) => {
state.messages.status = 'succeeded';
state.messages.items = action.payload;
})
.addCase(fetchMessages.rejected, (state, action) => {
state.messages.status = 'failed';
state.messages.error = action.payload || action.error.message;
})
// 发送聊天消息
.addCase(sendMessage.pending, (state) => {
state.sendMessage.status = 'loading';
})
.addCase(sendMessage.fulfilled, (state, action) => {
state.sendMessage.status = 'succeeded';
// 添加用户消息和机器人回复
if (action.payload.user_message) {
state.messages.items.push(action.payload.user_message);
}
if (action.payload.bot_message) {
state.messages.items.push(action.payload.bot_message);
}
})
.addCase(sendMessage.rejected, (state, action) => {
state.sendMessage.status = 'failed';
state.sendMessage.error = action.payload || action.error.message;
});
},
});
// 导出 actions
export const { resetOperationStatus, resetCurrentChat, setCurrentChat, resetMessages, resetSendMessageStatus } =
chatSlice.actions;
// 导出 reducer
export default chatSlice.reducer;