528 lines
18 KiB
TypeScript
528 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 { weChatGroupService, contractService } from "@/utils/db";
|
|
import { createContractList } from "@/store/module/ckchat/api";
|
|
import { useWeChatStore } from "@/store/module/weChat/weChat";
|
|
// 从weChat store获取clearCurrentContact方法
|
|
const getClearCurrentContact = () =>
|
|
useWeChatStore.getState().clearCurrentContact;
|
|
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: any[] = await contractService.findAll();
|
|
|
|
// 从本地数据库查询群组数据
|
|
let allGroups: any[] = await weChatGroupService.findAll();
|
|
|
|
// 根据选中的客服筛选联系人
|
|
if (state.kfSelected !== 0) {
|
|
allContacts = allContacts.filter(
|
|
item => item.wechatAccountId === state.kfSelected,
|
|
);
|
|
}
|
|
|
|
// 根据选中的客服筛选群组
|
|
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();
|
|
}
|
|
},
|
|
//获取特定联系人
|
|
getSomeContractList: (kfSelected: number) => {
|
|
const state = useCkChatStore.getState();
|
|
return state.contractList.filter(
|
|
item => item.wechatAccountId === kfSelected,
|
|
);
|
|
},
|
|
// 获取联系人列表 - 使用缓存避免无限循环
|
|
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],
|
|
};
|
|
});
|
|
},
|
|
// 更新聊天会话
|
|
updateChatSession: (session: ContractData | weChatGroup) => {
|
|
set(state => ({
|
|
chatSessions: state.chatSessions.map(item =>
|
|
item.id === session.id ? { ...item, ...session } : item,
|
|
),
|
|
}));
|
|
},
|
|
// 删除聊天会话
|
|
deleteChatSession: (sessionId: number) => {
|
|
set(state => ({
|
|
chatSessions: state.chatSessions.filter(item => item.id !== sessionId),
|
|
}));
|
|
//当前选中的客户清空
|
|
getClearCurrentContact();
|
|
},
|
|
// 设置用户信息
|
|
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();
|