Files
cunkebao_v3/Cunkebao/src/store/module/ckchat/ckchat.ts
超级老白兔 b08086e3f5 feat
2025-09-02 17:36:53 +08:00

543 lines
18 KiB
TypeScript

import { createPersistStore } from "@/store/createPersistStore";
import { CkChatState, CkUserInfo, CkTenant } from "./ckchat.data";
import {
ContractData,
weChatGroup,
CkAccount,
KfUserListData,
ContactGroupByLabel,
} from "@/pages/pc/ckbox/data";
import { kfUserService, weChatGroupService, contractService } from "@/utils/db";
import { createContractList } from "@/store/module/ckchat/api";
export const useCkChatStore = createPersistStore<CkChatState>(
set => ({
userInfo: null,
isLoggedIn: false,
contractList: [], //联系人列表
chatSessions: [], //聊天会话
kfUserList: [], //客服列表
countLables: [], //标签列表
newContractList: [], //联系人分组
kfSelected: 0, //选中的客服
searchKeyword: "", //搜索关键词
//客服列表
asyncKfUserList: async data => {
set({ kfUserList: data });
// await kfUserService.createManyWithServerId(data);
},
// 获取客服列表
getkfUserList: async () => {
const state = useCkChatStore.getState();
return state.kfUserList;
// return await kfUserService.findAll();
},
// 异步设置标签列表
asyncCountLables: async (data: ContactGroupByLabel[]) => {
set({ countLables: data });
// 清除getNewContractList缓存
const state = useCkChatStore.getState();
if (
state.getNewContractList &&
typeof state.getNewContractList === "function"
) {
// 触发缓存重新计算
await state.getNewContractList();
}
},
// 设置搜索关键词
setSearchKeyword: (keyword: string) => {
set({ searchKeyword: keyword });
},
// 清除搜索关键词
clearSearchKeyword: () => {
set({ searchKeyword: "" });
},
asyncKfSelected: async (data: number) => {
set({ kfSelected: data });
// 清除getChatSessions、getContractList和getNewContractList缓存
const state = useCkChatStore.getState();
if (
state.getChatSessions &&
typeof state.getChatSessions === "function"
) {
// 触发缓存重新计算
state.getChatSessions();
}
if (
state.getContractList &&
typeof state.getContractList === "function"
) {
// 触发缓存重新计算
state.getContractList();
}
if (
state.getNewContractList &&
typeof state.getNewContractList === "function"
) {
// 触发缓存重新计算
await state.getNewContractList();
}
},
// 获取联系人分组列表 - 使用缓存避免无限循环
getNewContractList: (() => {
let cachedResult: any = null;
let lastKfSelected: number | null = null;
let lastCountLablesLength: number = 0;
let lastSearchKeyword: string = "";
return async () => {
const state = useCkChatStore.getState();
// 检查是否需要重新计算缓存
const shouldRecalculate =
cachedResult === null ||
lastKfSelected !== state.kfSelected ||
lastCountLablesLength !== (state.countLables?.length || 0) ||
lastSearchKeyword !== state.searchKeyword;
if (shouldRecalculate) {
// 使用createContractList构建联系人分组数据
let contractList = await createContractList(
state.kfSelected,
state.countLables,
);
// 根据搜索关键词筛选联系人分组
if (state.searchKeyword.trim()) {
const keyword = state.searchKeyword.toLowerCase();
contractList = contractList
.map(group => ({
...group,
contracts:
group.contracts?.filter(item => {
const nickname = (item.nickname || "").toLowerCase();
const conRemark = (item.conRemark || "").toLowerCase();
return (
nickname.includes(keyword) || conRemark.includes(keyword)
);
}) || [],
}))
.filter(group => group.contracts.length > 0);
}
cachedResult = contractList;
lastKfSelected = state.kfSelected;
lastCountLablesLength = state.countLables?.length || 0;
lastSearchKeyword = state.searchKeyword;
}
return cachedResult;
};
})(),
// 搜索好友和群组的新方法 - 从本地数据库查询并返回扁平化的搜索结果
searchContactsAndGroups: (() => {
let cachedResult: (ContractData | weChatGroup)[] = [];
let lastKfSelected: number | null = null;
let lastSearchKeyword: string = "";
return async () => {
const state = useCkChatStore.getState();
// 检查是否需要重新计算缓存
const shouldRecalculate =
lastKfSelected !== state.kfSelected ||
lastSearchKeyword !== state.searchKeyword;
if (shouldRecalculate) {
if (state.searchKeyword.trim()) {
const keyword = state.searchKeyword.toLowerCase();
// 从本地数据库查询联系人数据
let allContacts: ContractData[] = await contractService.findAll();
// 根据选中的客服筛选联系人
if (state.kfSelected !== 0) {
allContacts = allContacts.filter(
item => item.wechatAccountId === state.kfSelected,
);
}
// 从本地数据库查询群组数据
let allGroups: weChatGroup[] = await weChatGroupService.findAll();
// 根据选中的客服筛选群组
if (state.kfSelected !== 0) {
allGroups = allGroups.filter(
item => item.wechatAccountId === state.kfSelected,
);
}
// 搜索匹配的联系人
const matchedContacts = allContacts.filter(item => {
const nickname = (item.nickname || "").toLowerCase();
const conRemark = (item.conRemark || "").toLowerCase();
return nickname.includes(keyword) || conRemark.includes(keyword);
});
// 搜索匹配的群组
const matchedGroups = allGroups.filter(item => {
const nickname = (item.nickname || "").toLowerCase();
const conRemark = (item.conRemark || "").toLowerCase();
return nickname.includes(keyword) || conRemark.includes(keyword);
});
// 合并搜索结果
cachedResult = [...matchedContacts, ...matchedGroups];
} else {
cachedResult = [];
}
lastKfSelected = state.kfSelected;
lastSearchKeyword = state.searchKeyword;
}
return cachedResult;
};
})(),
// 异步设置联系人分组列表
asyncNewContractList: async (data: any[]) => {
set({ newContractList: data });
// 清除getNewContractList缓存
const state = useCkChatStore.getState();
if (
state.getNewContractList &&
typeof state.getNewContractList === "function"
) {
// 触发缓存重新计算
await state.getNewContractList();
}
},
// 异步设置会话列表
asyncChatSessions: data => {
set({ chatSessions: data });
// 清除getChatSessions缓存
const state = useCkChatStore.getState();
if (
state.getChatSessions &&
typeof state.getChatSessions === "function"
) {
// 触发缓存重新计算
state.getChatSessions();
}
},
// 异步设置联系人列表
asyncContractList: async (data: ContractData[]) => {
set({ contractList: data });
await contractService.createManyWithServerId(data);
// 清除getContractList缓存
const state = useCkChatStore.getState();
if (
state.getContractList &&
typeof state.getContractList === "function"
) {
// 触发缓存重新计算
state.getContractList();
}
},
// 获取联系人列表 - 使用缓存避免无限循环
getContractList: (() => {
let cachedResult: any = null;
let lastKfSelected: number | null = null;
let lastContractListLength: number = 0;
let lastSearchKeyword: string = "";
return () => {
const state = useCkChatStore.getState();
// 检查是否需要重新计算缓存
const shouldRecalculate =
cachedResult === null ||
lastKfSelected !== state.kfSelected ||
lastContractListLength !== state.contractList.length ||
lastSearchKeyword !== state.searchKeyword;
if (shouldRecalculate) {
let filteredContracts = state.contractList;
// 根据客服筛选
if (state.kfSelected !== 0) {
filteredContracts = filteredContracts.filter(
item => item.wechatAccountId === state.kfSelected,
);
}
// 根据搜索关键词筛选
if (state.searchKeyword.trim()) {
const keyword = state.searchKeyword.toLowerCase();
filteredContracts = filteredContracts.filter(item => {
const nickname = (item.nickname || "").toLowerCase();
const conRemark = (item.conRemark || "").toLowerCase();
return nickname.includes(keyword) || conRemark.includes(keyword);
});
}
cachedResult = filteredContracts;
lastKfSelected = state.kfSelected;
lastContractListLength = state.contractList.length;
lastSearchKeyword = state.searchKeyword;
}
return cachedResult;
};
})(),
//异步设置联系人分组
asyncWeChatGroup: async (data: weChatGroup[]) => {
await weChatGroupService.createManyWithServerId(data);
},
//获取选中的客服信息
getKfSelectedUser: () => {
const state = useCkChatStore.getState();
return state.kfUserList.find(item => item.id === state.kfSelected);
},
getKfUserInfo: (wechatAccountId: number) => {
const state = useCkChatStore.getState();
return state.kfUserList.find(item => item.id === wechatAccountId);
},
// 删除控制终端用户
deleteCtrlUser: (userId: number) => {
set(state => ({
kfUserList: state.kfUserList.filter(item => item.id !== userId),
}));
},
// 更新控制终端用户
updateCtrlUser: (user: KfUserListData) => {
set(state => ({
kfUserList: state.kfUserList.map(item =>
item.id === user.id ? user : item,
),
}));
},
// 清空控制终端用户列表
clearkfUserList: () => {
set({ kfUserList: [] });
},
// 获取聊天会话 - 使用缓存避免无限循环
getChatSessions: (() => {
let cachedResult: any = null;
let lastKfSelected: number | null = null;
let lastChatSessionsLength: number = 0;
let lastSearchKeyword: string = "";
return () => {
const state = useCkChatStore.getState();
// 检查是否需要重新计算缓存
const shouldRecalculate =
cachedResult === null ||
lastKfSelected !== state.kfSelected ||
lastChatSessionsLength !== state.chatSessions.length ||
lastSearchKeyword !== state.searchKeyword;
if (shouldRecalculate) {
let filteredSessions = state.chatSessions;
// 根据客服筛选
if (state.kfSelected !== 0) {
filteredSessions = filteredSessions.filter(
item => item.wechatAccountId === state.kfSelected,
);
}
// 根据搜索关键词筛选
if (state.searchKeyword.trim()) {
const keyword = state.searchKeyword.toLowerCase();
filteredSessions = filteredSessions.filter(item => {
const nickname = (item.nickname || "").toLowerCase();
const conRemark = (item.conRemark || "").toLowerCase();
return nickname.includes(keyword) || conRemark.includes(keyword);
});
}
cachedResult = filteredSessions;
lastKfSelected = state.kfSelected;
lastChatSessionsLength = state.chatSessions.length;
lastSearchKeyword = state.searchKeyword;
}
return cachedResult;
};
})(),
// 添加聊天会话
addChatSession: (session: ContractData | weChatGroup) => {
set(state => {
// 检查是否已存在相同id的会话
const exists = state.chatSessions.some(item => item.id === session.id);
// 如果已存在则不添加,否则添加到列表中
return {
chatSessions: exists
? state.chatSessions
: [...state.chatSessions, session as ContractData | weChatGroup],
};
});
// 清除getChatSessions缓存
const state = useCkChatStore.getState();
if (
state.getChatSessions &&
typeof state.getChatSessions === "function"
) {
// 触发缓存重新计算
state.getChatSessions();
}
},
// 更新聊天会话
updateChatSession: (session: ContractData | weChatGroup) => {
set(state => ({
chatSessions: state.chatSessions.map(item =>
item.id === session.id ? session : item,
),
}));
// 清除getChatSessions缓存
const state = useCkChatStore.getState();
if (
state.getChatSessions &&
typeof state.getChatSessions === "function"
) {
// 触发缓存重新计算
state.getChatSessions();
}
},
// 删除聊天会话
deleteChatSession: (sessionId: string) => {
set(state => ({
chatSessions: state.chatSessions.filter(item => item.id !== sessionId),
}));
// 清除getChatSessions缓存
const state = useCkChatStore.getState();
if (
state.getChatSessions &&
typeof state.getChatSessions === "function"
) {
// 触发缓存重新计算
state.getChatSessions();
}
},
// 设置用户信息
setUserInfo: (userInfo: CkUserInfo) => {
set({ userInfo, isLoggedIn: true });
},
// 清除用户信息
clearUserInfo: () => {
set({ userInfo: null, isLoggedIn: false });
},
// 更新账户信息
updateAccount: (account: Partial<CkAccount>) => {
set(state => ({
userInfo: state.userInfo
? {
...state.userInfo,
account: { ...state.userInfo.account, ...account },
}
: null,
}));
},
// 更新租户信息
updateTenant: (tenant: Partial<CkTenant>) => {
set(state => ({
userInfo: state.userInfo
? {
...state.userInfo,
tenant: { ...state.userInfo.tenant, ...tenant },
}
: null,
}));
},
// 获取账户ID
getAccountId: () => {
const state = useCkChatStore.getState();
return Number(state.userInfo?.account?.id) || null;
},
// 获取租户ID
getTenantId: () => {
const state = useCkChatStore.getState();
return state.userInfo?.tenant?.id || null;
},
// 获取账户名称
getAccountName: () => {
const state = useCkChatStore.getState();
return (
state.userInfo?.account?.realName ||
state.userInfo?.account?.userName ||
null
);
},
// 获取租户名称
getTenantName: () => {
const state = useCkChatStore.getState();
return state.userInfo?.tenant?.name || null;
},
}),
{
name: "ckchat-store",
partialize: state => ({
userInfo: state.userInfo,
isLoggedIn: state.isLoggedIn,
kfUserList: state.kfUserList,
}),
onRehydrateStorage: () => state => {
// console.log("CkChat store hydrated:", state);
},
},
);
// 导出便捷的获取方法
export const getCkAccountId = () => useCkChatStore.getState().getAccountId();
export const getCkTenantId = () => useCkChatStore.getState().getTenantId();
export const getCkAccountName = () =>
useCkChatStore.getState().getAccountName();
export const getCkTenantName = () => useCkChatStore.getState().getTenantName();
export const getChatSessions = () =>
useCkChatStore.getState().getChatSessions();
export const addChatSession = (session: ContractData | weChatGroup) =>
useCkChatStore.getState().addChatSession(session);
export const updateChatSession = (session: ContractData | weChatGroup) =>
useCkChatStore.getState().updateChatSession(session);
export const deleteChatSession = (sessionId: string) =>
useCkChatStore.getState().deleteChatSession(sessionId);
export const getkfUserList = () => useCkChatStore.getState().kfUserList;
export const addCtrlUser = (user: KfUserListData) =>
useCkChatStore.getState().addCtrlUser(user);
export const deleteCtrlUser = (userId: number) =>
useCkChatStore.getState().deleteCtrlUser(userId);
export const updateCtrlUser = (user: KfUserListData) =>
useCkChatStore.getState().updateCtrlUser(user);
export const asyncKfUserList = (data: KfUserListData[]) =>
useCkChatStore.getState().asyncKfUserList(data);
export const asyncContractList = (data: ContractData[]) =>
useCkChatStore.getState().asyncContractList(data);
export const asyncChatSessions = (data: ContractData[]) =>
useCkChatStore.getState().asyncChatSessions(data);
export const asyncKfSelected = (data: number) =>
useCkChatStore.getState().asyncKfSelected(data);
export const asyncWeChatGroup = (data: weChatGroup[]) =>
useCkChatStore.getState().asyncWeChatGroup(data);
export const getKfSelectedUser = () =>
useCkChatStore.getState().getKfSelectedUser();
export const getKfUserInfo = (wechatAccountId: number) =>
useCkChatStore.getState().getKfUserInfo(wechatAccountId);
export const getContractList = () =>
useCkChatStore.getState().getContractList();
export const getNewContractList = () =>
useCkChatStore.getState().getNewContractList();
export const asyncCountLables = (data: ContactGroupByLabel[]) =>
useCkChatStore.getState().asyncCountLables(data);
export const asyncNewContractList = (data: any[]) =>
useCkChatStore.getState().asyncNewContractList(data);
export const getCountLables = () => useCkChatStore.getState().countLables;
export const setSearchKeyword = (keyword: string) =>
useCkChatStore.getState().setSearchKeyword(keyword);
export const clearSearchKeyword = () =>
useCkChatStore.getState().clearSearchKeyword();
export const searchContactsAndGroups = () =>
useCkChatStore.getState().searchContactsAndGroups();
useCkChatStore.getState().getKfSelectedUser();