gaoluyang
2026-06-29 27cd042df9aca0383a49f3514bc21958dd890912
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
import type { MallKefuConversationApi } from '#/api/mall/promotion/kefu/conversation';
import type { MallKefuMessageApi } from '#/api/mall/promotion/kefu/message';
 
import { isEmpty } from '../../packages/utils/src';
 
import { acceptHMRUpdate, defineStore } from 'pinia';
 
import {
  getConversation,
  getConversationList,
} from '#/api/mall/promotion/kefu/conversation';
 
interface MallKefuInfoVO {
  conversationList: MallKefuConversationApi.Conversation[]; // 会话列表
  conversationMessageList: Map<number, MallKefuMessageApi.Message[]>; // 会话消息
}
 
export const useMallKefuStore = defineStore('mall-kefu', {
  state: (): MallKefuInfoVO => ({
    conversationList: [],
    conversationMessageList: new Map<number, MallKefuMessageApi.Message[]>(), // key 会话,value 会话消息列表
  }),
  getters: {
    getConversationList(): MallKefuConversationApi.Conversation[] {
      return this.conversationList;
    },
    getConversationMessageList(): (
      conversationId: number,
    ) => MallKefuMessageApi.Message[] | undefined {
      return (conversationId: number) =>
        this.conversationMessageList.get(conversationId);
    },
  },
  actions: {
    // ======================= 会话消息相关 =======================
    /** 缓存历史消息 */
    saveMessageList(
      conversationId: number,
      messageList: MallKefuMessageApi.Message[],
    ) {
      this.conversationMessageList.set(conversationId, messageList);
    },
 
    // ======================= 会话相关 =======================
    /** 加载会话缓存列表 */
    async setConversationList() {
      this.conversationList = await getConversationList();
      this.conversationSort();
    },
    /** 更新会话缓存已读 */
    async updateConversationStatus(conversationId: number) {
      if (isEmpty(this.conversationList)) {
        return;
      }
      const conversationList = this
        .conversationList as MallKefuConversationApi.Conversation[];
      const conversation = conversationList.find(
        (item: MallKefuConversationApi.Conversation) =>
          item.id === conversationId,
      );
      conversation && (conversation.adminUnreadMessageCount = 0);
    },
    /** 更新会话缓存 */
    async updateConversation(conversationId: number) {
      if (isEmpty(this.conversationList)) {
        return;
      }
 
      const conversation = await getConversation(conversationId);
      this.deleteConversation(conversationId);
      if (conversation && this.conversationList) {
        const conversationList = this
          .conversationList as MallKefuConversationApi.Conversation[];
        this.conversationList = [
          ...conversationList,
          conversation as MallKefuConversationApi.Conversation,
        ];
      }
      this.conversationSort();
    },
    /** 删除会话缓存 */
    deleteConversation(conversationId: number) {
      const index = this.conversationList.findIndex(
        (item) => item.id === conversationId,
      );
      // 存在则删除
      if (index !== -1) {
        this.conversationList.splice(index, 1);
      }
    },
    conversationSort() {
      // 按置顶属性和最后消息时间排序
      this.conversationList = this.conversationList.toSorted((a, b) => {
        // 按照置顶排序,置顶的会在前面
        if (a.adminPinned !== b.adminPinned) {
          return a.adminPinned ? -1 : 1;
        }
        // 按照最后消息时间排序,最近的会在前面
        return (
          (b.lastMessageTime as unknown as number) -
          (a.lastMessageTime as unknown as number)
        );
      });
    },
  },
});
 
// 解决热更新问题
const hot = import.meta.hot;
if (hot) {
  hot.accept(acceptHMRUpdate(useMallKefuStore, hot));
}