feat(数据库): 添加消息列表数据接口和表
refactor(聊天会话): 根据选中客服过滤会话列表 fix(聊天窗口): 移除重复的未读消息清除逻辑 refactor(侧边栏): 统一联系人点击处理逻辑 chore: 删除无用的数据库测试文件
This commit is contained in:
@@ -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(() => {
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -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}
|
||||
/>
|
||||
);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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) => {
|
||||
|
||||
@@ -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);
|
||||
});
|
||||
}
|
||||
@@ -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");
|
||||
|
||||
Reference in New Issue
Block a user