feat(数据库): 添加消息列表数据接口和表

refactor(聊天会话): 根据选中客服过滤会话列表

fix(聊天窗口): 移除重复的未读消息清除逻辑

refactor(侧边栏): 统一联系人点击处理逻辑

chore: 删除无用的数据库测试文件
This commit is contained in:
超级老白兔
2025-09-01 10:24:15 +08:00
parent 5437a47e37
commit 64c75772bb
8 changed files with 54 additions and 199 deletions

View File

@@ -36,7 +36,7 @@ import {
StarOutlined,
} from "@ant-design/icons";
import { ChatRecord, ContractData, weChatGroup } from "@/pages/pc/ckbox/data";
import { clearUnreadCount, getMessages } from "@/pages/pc/ckbox/api";
import { getMessages } from "@/pages/pc/ckbox/api";
import styles from "./ChatWindow.module.scss";
import { useWebSocketStore, WebSocketMessage } from "@/store/module/websocket";
import { formatWechatTime } from "@/utils/common";
@@ -68,30 +68,27 @@ const ChatWindow: React.FC<ChatWindowProps> = ({
>({});
const messagesEndRef = useRef<HTMLDivElement>(null);
const getKfSelectedUser = useCkChatStore(state => state.getKfSelectedUser());
useEffect(() => {
clearUnreadCount([contract.id]).then(() => {
setLoading(true);
const params: any = {
wechatAccountId: contract.wechatAccountId,
From: 1,
To: +new Date() + 1000,
Count: 100,
olderData: true,
};
if (contract.groupId == 1) {
params.wechatFriendId = contract.id;
} else {
params.wechatChatroomId = contract.id;
}
getMessages(params)
.then(msg => {
setMessages(msg);
})
.finally(() => {
setLoading(false);
});
});
setLoading(true);
const params: any = {
wechatAccountId: contract.wechatAccountId,
From: 1,
To: +new Date() + 1000,
Count: 100,
olderData: true,
};
if (contract.groupId == 1) {
params.wechatFriendId = contract.id;
} else {
params.wechatChatroomId = contract.id;
}
getMessages(params)
.then(msg => {
setMessages(msg);
})
.finally(() => {
setLoading(false);
});
}, [contract.id]);
useEffect(() => {

View File

@@ -7,13 +7,13 @@ import { formatWechatTime } from "@/utils/common";
interface MessageListProps {
chatSessions: ContractData[] | weChatGroup[];
currentChat: ContractData | weChatGroup;
onChatSelect: (chat: ContractData | weChatGroup) => void;
onContactClick: (chat: ContractData | weChatGroup) => void;
}
const MessageList: React.FC<MessageListProps> = ({
chatSessions,
currentChat,
onChatSelect,
onContactClick,
}) => {
return (
<div className={styles.messageList}>
@@ -25,7 +25,7 @@ const MessageList: React.FC<MessageListProps> = ({
className={`${styles.messageItem} ${
currentChat?.id === session.id ? styles.active : ""
}`}
onClick={() => onChatSelect(session)}
onClick={() => onContactClick(session)}
>
<div className={styles.messageInfo}>
<Badge count={session.unreadCount} size="small">

View File

@@ -10,13 +10,12 @@ import { ContractData, weChatGroup } from "@/pages/pc/ckbox/data";
import WechatFriends from "./WechatFriends";
import MessageList from "./MessageList/index";
import styles from "./SidebarMenu.module.scss";
import { getChatSessions } from "@/store/module/ckchat/ckchat";
import { useCkChatStore } from "@/store/module/ckchat/ckchat";
interface SidebarMenuProps {
contracts: ContractData[] | weChatGroup[];
currentChat: ContractData | weChatGroup;
onContactClick: (contract: ContractData | weChatGroup) => void;
onChatSelect: (chat: ContractData | weChatGroup) => void;
loading?: boolean;
}
@@ -24,10 +23,9 @@ const SidebarMenu: React.FC<SidebarMenuProps> = ({
contracts,
currentChat,
onContactClick,
onChatSelect,
loading = false,
}) => {
const chatSessions = getChatSessions();
const chatSessions = useCkChatStore(state => state.getChatSessions());
const [searchText, setSearchText] = useState("");
const [activeTab, setActiveTab] = useState("chats");
@@ -145,7 +143,7 @@ const SidebarMenu: React.FC<SidebarMenuProps> = ({
return (
<MessageList
chatSessions={getFilteredSessions()}
onChatSelect={onChatSelect}
onContactClick={onContactClick}
currentChat={currentChat}
/>
);

View File

@@ -16,22 +16,6 @@ const VerticalUserList: React.FC = () => {
};
const kfUserList = useCkChatStore(state => state.kfUserList);
const kfSelected = useCkChatStore(state => state.kfSelected);
const [kefuList, setKefuList] = useState([]);
// // 获取客服列表数据
// useEffect(() => {
// const fetchKfUserList = async () => {
// try {
// const data = await getkfUserList();
// setKefuList(data || []);
// } catch (error) {
// console.error("获取客服列表失败:", error);
// setKefuList([]);
// }
// };
// fetchKfUserList();
// }, [getkfUserList]);
return (
<div className={styles.verticalUserList}>
<div

View File

@@ -10,6 +10,7 @@ import styles from "./index.module.scss";
import { addChatSession } from "@/store/module/ckchat/ckchat";
const { Header, Content, Sider } = Layout;
import { chatInitAPIdata } from "./main";
import { clearUnreadCount } from "@/pages/pc/ckbox/api";
import {
KfUserListData,
weChatGroup,
@@ -57,9 +58,13 @@ const CkboxPage: React.FC = () => {
});
}, []);
//开始开启聊天
const handleContactClick = (contract: ContractData | weChatGroup) => {
addChatSession(contract);
setCurrentChat(contract);
clearUnreadCount([contract.id]).then(() => {
contract.unreadCount = 0;
addChatSession(contract);
setCurrentChat(contract);
});
};
const handleSendMessage = async (message: string) => {
@@ -107,7 +112,6 @@ const CkboxPage: React.FC = () => {
contracts={contracts}
currentChat={currentChat}
onContactClick={handleContactClick}
onChatSelect={setCurrentChat}
loading={loading}
/>
</Sider>

View File

@@ -16,7 +16,7 @@ export const useCkChatStore = createPersistStore<CkChatState>(
chatSessions: [], //聊天会话
kfUserList: [], //客服列表
newContractList: [], //联系人分组
kfSelected: 0,
kfSelected: 0, //选中的客服
//客服列表
asyncKfUserList: async data => {
set({ kfUserList: data });
@@ -80,7 +80,13 @@ export const useCkChatStore = createPersistStore<CkChatState>(
// 获取聊天会话
getChatSessions: () => {
const state = useCkChatStore.getState();
return state.chatSessions;
if (state.kfSelected != 0) {
return state.chatSessions.filter(
item => item.wechatAccountId === state.kfSelected,
);
} else {
return state.chatSessions;
}
},
// 添加聊天会话
addChatSession: (session: ContractData | weChatGroup) => {

View File

@@ -1,146 +0,0 @@
/**
* 数据库版本升级测试脚本
* 用于验证数据库版本升级逻辑是否正常工作
*/
import { db } from "./db";
// 重置数据库(完全删除并重新创建)
export async function resetDatabase() {
try {
console.log("开始重置数据库...");
// 关闭数据库连接
if (db.isOpen()) {
db.close();
}
// 删除数据库
await db.delete();
console.log("旧数据库已删除");
// 重新打开数据库(这会创建新的数据库)
await db.open();
console.log("数据库重置成功!");
console.log("当前数据库版本:", db.verno);
console.log("数据库名称:", db.name);
return {
success: true,
version: db.verno,
tables: db.tables.map(table => table.name),
message: "数据库重置成功",
};
} catch (error) {
console.error("数据库重置失败:", error);
return {
success: false,
error: error instanceof Error ? error.message : String(error),
message: "数据库重置失败",
};
}
}
// 测试数据库初始化和版本升级
export async function testDatabaseUpgrade() {
try {
console.log("开始测试数据库初始化...");
// 首先尝试正常打开数据库
try {
await db.open();
} catch (upgradeError) {
// 如果遇到升级错误,尝试重置数据库
if (
upgradeError.message &&
upgradeError.message.includes("primary key")
) {
console.log("检测到主键冲突,尝试重置数据库...");
const resetResult = await resetDatabase();
if (!resetResult.success) {
throw new Error(`数据库重置失败: ${resetResult.error}`);
}
} else {
throw upgradeError;
}
}
console.log("数据库初始化成功!");
console.log("当前数据库版本:", db.verno);
console.log("数据库名称:", db.name);
// 检查表是否存在
const tables = db.tables.map(table => table.name);
console.log("数据库表:", tables);
// 测试基本操作
const testData = {
tenantId: 1, // 修正为number类型
wechatId: "test-wechat-id",
nickname: "测试用户",
alias: "测试别名",
};
// 测试创建数据
const userId = await db.kfUsers.add({
...testData,
id: 0, // 添加必需的id字段
currentDeviceId: 0,
isDeleted: false,
deleteTime: "",
groupId: 0,
memo: "", // 备注信息
wechatVersion: "",
labels: [],
lastUpdateTime: new Date().toISOString(), // 修复语法错误,使用字符串类型
serverId: "test-server-id-001", // 提供有意义的测试值
// 移除不属于KfUserListData接口的字段
signature: "",
bindQQ: "",
bindEmail: "",
bindMobile: "",
bindWeixin: "",
bindAlipay: "",
bindTaobao: "",
bindJd: "",
bindDouyin: "",
bindKuaishou: "",
bindBilibili: "",
avatar: "",
gender: 0,
region: "",
createTime: new Date().toISOString(), // 使用字符串类型
});
console.log("创建测试用户成功ID:", userId);
// 测试查询数据
const user = await db.kfUsers.get(userId);
console.log("查询测试用户:", user);
// 清理测试数据
await db.kfUsers.delete(userId);
console.log("清理测试数据完成");
return {
success: true,
version: db.verno,
tables: tables,
message: "数据库版本升级测试通过",
};
} catch (error) {
console.error("数据库测试失败:", error);
return {
success: false,
error: error instanceof Error ? error.message : String(error),
message: "数据库版本升级测试失败",
};
}
}
// 如果直接运行此文件,执行测试
if (typeof window === "undefined") {
testDatabaseUpgrade().then(result => {
console.log("测试结果:", result);
});
}

View File

@@ -57,12 +57,24 @@ export interface NewContactListData {
weChatGroup: weChatGroup[];
}
// 消息列表数据接口
export interface MessageListData extends Omit<ContractData, "id"> {
serverId: number | string; // 服务器ID作为主键
id?: number; // 接口数据的原始ID字段
wechatAccountId: number; // 微信账号ID
chatroomAvatar?: string; // 群头像
chatroomName?: string; // 群名称
chatroomId?: number; // 群ID
[key: string]: any;
}
// 数据库类
class CunkebaoDatabase extends Dexie {
kfUsers!: Table<KfUserWithServerId>;
weChatGroup!: Table<weChatGroupServerId>;
contracts!: Table<ContractWithServerId>;
newContractList!: Table<NewContactListData>;
messageList!: Table<MessageListData>;
constructor() {
super("CunkebaoDatabase");