美文网首页
2021-02-26 Web-im js-sdk开发打包流程

2021-02-26 Web-im js-sdk开发打包流程

作者: gdlooker | 来源:发表于2021-02-26 11:37 被阅读0次

    年前初步的完成了im基本版,像单聊,群聊,消息的收发,图片视频,消息右键撤回等功能,年后就开始主要集中精力进行sdk的开发了。
    说下我个人的开发思路:
    第一步 新建一个工程不使用脚手架编译js文件,执行npm init -y 生成package.json文件
    第二步 由于我原来的im工程代码是用的ts+mobx+react开发的im,所以我这边需要新建一个tsconfig.json来进行响应的配置。具体示例参考官方文档(这里给出链接):
    https://www.tslang.cn/docs/handbook/compiler-options.html
    如果对官方文档给出的选项可能不理解,这里给出更详细的说明链接:
    https://my.oschina.net/u/4564900/blog/4893389
    接下来给出我这边的webpack.config.js文件的配置示例代码如下:

    const path = require("path");
    module.exports = {
      entry: ["./src/index.ts"],
      output: {
        path: path.join(__dirname, "dist"), //打包输出文件的路径跟文件夹目录
        filename: "bundle.js", //打包输出的文件名字
        library: "webpackNumbers", //表示支持的类型 最终会在打出的js文件下
        libraryTarget: "this",
        umdNamedDefine: true,
        globalObject: "this",
      },
      mode: "production",
      module: {
        rules: [
          {
            test: /\.tsx?$/,
            use: "ts-loader",
            exclude: /node_modules/,
          },
        ],
      },
      resolve: {
        // Add ".ts" and ".tsx" as resolvable extensions.
        extensions: [".ts", ".tsx", ".js"],
      },
    };
    
    

    webpack配置library等参考文章https://zhuanlan.zhihu.com/p/108216236
    接下来给出tsconfig.json文件配置的示例代码如下:

    {
      "compilerOptions": {
        "target": "es5",
        "lib": [
          "dom",
          "dom.iterable",
          "esnext"
        ],
        "outDir": "./outDir/",   
        "allowJs": true,
        "skipLibCheck": true,
        "esModuleInterop": true,
        "allowSyntheticDefaultImports": true,
        "forceConsistentCasingInFileNames": true,
        "experimentalDecorators": true,
        "module": "esnext",
        "moduleResolution": "node",
        "resolveJsonModule": true,
        "isolatedModules": true,
        "noImplicitAny":false,
        "noImplicitThis":false,
        "noEmit": false,
        "jsx": "react",
        "baseUrl": "."
      },
      "exclude": [ // 排除那些文件不打包
        "node_modules",
        "*.test.ts"
      ]
    }
    
    

    接下来简单给出我的项目入口文件index.ts示例代码如下:

    import HomeStore from './routes/ZxHome/store'
    var store=new HomeStore()
    

    然后再进入store文件看下示例代码:

    import {  storage, pinyin, navigate, getSensitiveMsg, getRandomKey, StringKey } from '../../../utils';
    import moment from 'moment';
    import GdchentWebSocket from './GdchentWebSocket';
    import { request } from '../../../config/zxAxios';
    import api from '../../../config/apiConfig';
    import proToObject from '../../../proto/proto';
    import ParseMsgUtil from "../../../utils/ParseMsgUtil";
    import ArrayBufferUtil from '../../../utils/ArrayBufferUtil'
    import AesUtil from '../../../utils/AesUtil'
    import { randomKey } from '../../../utils/secret';
    import ChatItemEnum from '../../../enum/ChatItemEnum';
    import CommunicationTypeEnum from '../../../enum/CommunicationTypeEnum'
    import CommandEnum from '../../../enum/CommandEnum'
    import CreateChatGroup from '../../../interface/CreateChatGroup';
    
    
    const currentTime = moment().valueOf();
    
    let sendHeartTimer: any; //心跳包的定时器
    
    const WEB_SOCKET_TIMEOUT = 50000; //50秒
    
    export default class Store {
    
      public arrayBufferUtil: ArrayBufferUtil = new ArrayBufferUtil();
      public parseMsgUtil: ParseMsgUtil = new ParseMsgUtil();
      // Socket实例
      gdchentWebSocket: GdchentWebSocket = null;
      // 当前用户的id
      defaultId: string = storage.get('im_defaultId');
      // 当前登录的token
      token: string = '';
      // 当前时间
      currentDate: string = moment(currentTime).format('YYYY-MM-DD');
      // 已收到消息缓存,用于检测消息是否重复,key为msgId
      cacheMessages: { [key: string]: boolean } = {};
      // 可展示聊天消息的类型
      messageTypes = [
        1, // 文字
        2, // 语音
        3, // 图片
        4, // 视频
        5, // 表情
        6, // 链接
        7, // 位置
        8, // 聊天记录
        9, // 文件
        10, // 发红包
        12, // 名片
        20, // 位置共享
        48, // 回复
        51, // 邀请加入群聊
        77, // 群公告
      ];
    
      // 根据好友id获取好友信息
      friendData = {};
    
      // 是否触发接收好友,当有值时,跳转到聊天模块,并打新好友的聊天
      acceptFriendDefaultId: any = null;
    
      // 敏感词
      sensitiveKeywords: any = [];
    
      // 用户信息
      userInfo: any = {};
    
      userInfoList: any = [];
      // 聊天列表
      chats: any[] = [];
      // 选中菜单数据
      activeChatData: any = {};
      // 新的好友列表
      newFriends: any[] = [];
    
      // 好友列表
      friends: any[] = [];
    
      creatChatGroupsList: any[] = [];
    
      allGroupMembers: any[] = [];
      // 群组列表
      groups: any = [];
    
      // 好友列表id和备注名键值对
      remarkNameData = {};
    
      contextMessage: any = null;
    
      // 表情列表
      emojis: any = [{ icon: 'love', data: [] }];
    
      // 用于更新收藏列表
      collectKey: number = 0;
    
      // 敏感词发送次数
      sensitiveCount: number = 0;
    
      // 禁止聊天
      disabled: number = 0;
    
      // websocket连接状态 0表示断开连接
      connect: number = 1;
    
      //联系人分组的key
      contact_tag: string = 'CONTACT_TAG'
    
      topList: any[] = []
    
      //storage的key的常量
      public SDK_ACCT_LOGIN_KEY = 'sdkacctLogin'
      public CACHE_CHATS_KEY = `im_${this.defaultId}_chats`
      public LAST_MESSAGE_KEY: string = 'lastmessageKey'
      public ACTIVE_CHAT_DATA_KEY: string = 'activeChatDataKey'
      public CHAT_TOP_DATA = 'CONVERSATION_PIN_TAG'
      //websocket
      webWocketUrl: string = '';//服务器地址
    
      appId: string = '9eb745a14c44b7f5badbbb92092ee8e9#Jiao-IM-Demo';
    
      //用户id
      userId: string = '';
      //设备id
      deviceId: string = 'deviceId1'
    
      private isFirstActiveChatData: boolean = false;
      public sdkacctLogin: any;
      public aes = new AesUtil()
    
      constructor() {
        this.init()
      }
      public async init() {
        await this.getNewFriends()
        await this.getFriendList()
        await this.getLocalChatList()
        await this.getChatGroupLists()
        //await this.setDemoKvDataSet([])
        this.getDemoKvDataGet()
        this.initWebSocket()
        await this.getChatTopData()
        const userInfo = await storage.getF(StringKey.USER_INFO)
        if (!userInfo) {
          navigate('/zxlogin')
        } else {
          this.userInfo = userInfo
        }
      }
    
      //获取本地的会话列表
      public getLocalChatList = async () => {
        let cacheChats = await storage.getF(this.CACHE_CHATS_KEY)
        if (!cacheChats) {
          console.log('当前没有离线缓存列表')
          return;
        }
        if (cacheChats) {
          this.chats = cacheChats;
          if (!this.isFirstActiveChatData && Array.isArray(cacheChats) && cacheChats.length > 0) {
            cacheChats[0][StringKey.ACTIVE] = ChatItemEnum.CHAT_ITEM_ACTIVE
            cacheChats[0][StringKey.UN_READ_COUNT] = ChatItemEnum.CHAT_ITEM_UN_READ_COUNT_DEFAULT_ZERO
            this.activeChatData = cacheChats[0]
            let newChats: any = []
            newChats = newChats.concat(cacheChats)
            cacheChats.forEach(async (item, index) => {
              const { conversationId }: any = cacheChats[index];
              if (conversationId) {
                //console.log('获取的离线消息id', conversationId)
                //通过会话id拉取离线消息
                await this.getPullOfflineMessageList({
                  communicationId: conversationId
                })
              }
            })
          }
          this.isFirstActiveChatData = true;
        }
      }
    
      public getPullOfflineMessageList = async ({
        communicationId,
        count = 20,
        deviceType = 2, //2表示web端
      }: any) => {
        //拉取离线消息
        const protoTime = await storage.getF(this.LAST_MESSAGE_KEY);
        if (protoTime) {
          const { lastMsgReceiveTime, lastMsgSequenceId }: any = protoTime
          const params = {
            count: count,
            deviceType: deviceType,
            lastMsgReceiveTime: lastMsgReceiveTime,
            endMsgId: lastMsgSequenceId,
            communicationId: communicationId,
          }
          const messageRes = await request({
            method: 'GET',
            url: api.GET.zxGetPullOfflineMessageList,
            data: params
          })
          const { code, hasError, data } = messageRes
          if (code == '0' && !hasError) {
            //清理7天前会话
            // 截取20条
            if (data) {
              let { msgList } = data;
              if (!msgList || msgList.length <= 0) {
                console.log('拉取的离线消息为空')
                return;
              }
              //将离线消息拼接入本地在线消息
              let cacheChats = await storage.getF(this.CACHE_CHATS_KEY)
              if (cacheChats && Array.isArray(cacheChats)) {
                const findCacheChat: any = cacheChats.find((item, index) => {
                  return item['conversationId'] === communicationId
                })
                if (findCacheChat) {
                  if (findCacheChat && Array.isArray(findCacheChat[StringKey.MESSAGES_KEY])) {
                    findCacheChat.messages.forEach((itemMessage: any, index: number) => {
                      msgList = msgList.filter((itemMsg: any, index: number) => {
                        return itemMsg['messageId'] !== itemMessage['messageId']
                      })
                    })
                    findCacheChat.messages = findCacheChat.messages.concat(msgList)
                    if (findCacheChat['conversationId'] === this.activeChatData['conversationId']) {
                      //console.log('findCacheChat',JSON.stringify(findCacheChat))
                      this.setRefreshActiveChatData(findCacheChat)
                    }
                    this.setObserverChatList(findCacheChat, false)
                  } else {
                    console.log('搞操作前不是数组')
                  }
                }
    
              }
            }
          }
        }
      }
    
    
      public getCacheActiveGroupToActiveData = async (contactItem: any) => {
        let cacheChats: any = await storage.getF(this.CACHE_CHATS_KEY)
        if (cacheChats && Array.isArray(cacheChats) && cacheChats.length > 0) {
          let cacheItem = cacheChats.find((item, index) => {
            return item[StringKey.COMMUNICATIONID] === contactItem[StringKey.COMMUNICATIONID]
          })
          if (cacheItem) {
            return cacheItem;
          }
        }
        return contactItem
      }
    
      public getCacheActiveToActiveData = async (contactItem: any) => {
        let cacheChats: any = await storage.getF(this.CACHE_CHATS_KEY)
        if (cacheChats && Array.isArray(cacheChats) && cacheChats.length > 0) {
          let cacheItem = cacheChats.find((item, index) => {
            return item['userId'] === contactItem['userId'] && item[StringKey.CONVERSATIONID] === contactItem[StringKey.CONVERSATIONID]
          })
          if (cacheItem) {
            return cacheItem;
          }
        }
        return contactItem
      }
    
      //联系人到会话
      public setActiveContactAndRefreshChatList = async (chatItem: any, isCreateTop = false) => {
        if (!chatItem) {
          if (process.env.NODE_ENV === 'development') {
            console.log('setActiveContactAndRefreshChatList——chatItem传入有问题', chatItem)
          }
          return;
        }
        chatItem[StringKey.ACTIVE] = ChatItemEnum.CHAT_ITEM_ACTIVE
        chatItem[StringKey.UN_READ_COUNT] = ChatItemEnum.CHAT_ITEM_UN_READ_COUNT_DEFAULT_ZERO
        const createChatTime = new Date().getTime()
        chatItem[StringKey.CREATE_CHAT_TIME] = createChatTime
        let cacheChats: any = await storage.getF(this.CACHE_CHATS_KEY)
        if (cacheChats && Array.isArray(cacheChats) && cacheChats.length > 0) {
          let newActiveIndex = cacheChats.findIndex((value, index) => {
            if (value[StringKey.ACTIVE] == ChatItemEnum.CHAT_ITEM_ACTIVE) {
              value[StringKey.ACTIVE] = ChatItemEnum.CHAT_ITEM_NO_ACTIVE;
            }
            return chatItem[StringKey.COMMUNICATIONID] === value[StringKey.COMMUNICATIONID]
            //return chatItem['userId'] === value['userId']
          })
    
          if (newActiveIndex != -1) {
            this.activeChatData = cacheChats[newActiveIndex]
            this.activeChatData[StringKey.UN_READ_COUNT] = ChatItemEnum.CHAT_ITEM_UN_READ_COUNT_DEFAULT_ZERO
            this.activeChatData[StringKey.ACTIVE] = ChatItemEnum.CHAT_ITEM_ACTIVE
            if (!this.activeChatData[StringKey.CREATE_CHAT_TIME]) {
              this.activeChatData[StringKey.CREATE_CHAT_TIME] = createChatTime
            }
            this.setRefreshActiveChatData(this.activeChatData)
          } else {
            cacheChats.unshift(chatItem)
            await storage.setF(this.CACHE_CHATS_KEY, cacheChats)
            this.getLocalChatList()
          }
        } else {
          cacheChats = []
          cacheChats.unshift(chatItem)
          await storage.setF(this.CACHE_CHATS_KEY, cacheChats)
          this.getLocalChatList()
        }
      }
    
      public deleteChatItem = async (chatItem: any) => {
        let cacheChats: any = await storage.getF(this.CACHE_CHATS_KEY)
        if (cacheChats && cacheChats.length > 0) {
          cacheChats = cacheChats.filter((item: any, index: number) => {
            return chatItem['conversationId'] !== item['conversationId']
          })
          await storage.setF(this.CACHE_CHATS_KEY, cacheChats)
          this.getLocalChatList()
        }
      }
      public setObserverChatList =
        async (chatItem: any, isCreateTop = false, isUpdateMessage = false) => {
          let cacheChats: any = await storage.getF(this.CACHE_CHATS_KEY)
          if (cacheChats && cacheChats.length > 0) {
            cacheChats.forEach((item: any, index: number) => {
              if (item[StringKey.ACTIVE] === ChatItemEnum.CHAT_ITEM_ACTIVE) {
                item[StringKey.ACTIVE] = ChatItemEnum.CHAT_ITEM_NO_ACTIVE
              }
            })
            let existIndex = -1
            let cacheConversationChat: any;
            cacheChats.forEach((item: any, index: number) => {
              if (chatItem[StringKey.COMMUNICATIONID] === item[StringKey.COMMUNICATIONID]) {
                cacheConversationChat = item
                existIndex = index;
              }
            })
            if (isCreateTop) {
              if (!cacheConversationChat) {
                chatItem[StringKey.IS_TOP] = isCreateTop
                cacheChats.unshift(chatItem)
              } else {
                chatItem[StringKey.IS_TOP] = isCreateTop
                let deleteChat = cacheChats.splice(existIndex, 1)
                cacheChats.unshift(chatItem)
              }
              this.addRefreshTopList(chatItem)
            } else {
              chatItem[StringKey.ACTIVE] = ChatItemEnum.CHAT_ITEM_ACTIVE
              chatItem[StringKey.UN_READ_COUNT] = ChatItemEnum.CHAT_ITEM_UN_READ_COUNT_DEFAULT_ZERO
              if (!cacheConversationChat) {
                cacheChats.unshift(chatItem)
              } else {
                cacheConversationChat[StringKey.ACTIVE] = ChatItemEnum.CHAT_ITEM_ACTIVE
                cacheConversationChat[StringKey.UN_READ_COUNT] = ChatItemEnum.CHAT_ITEM_UN_READ_COUNT_DEFAULT_ZERO
                let jsChatMessages = chatItem[StringKey.MESSAGES_KEY]
                if (jsChatMessages && Array.isArray(jsChatMessages) && jsChatMessages.length > 0) {
                  // console.log('cacheConversationChat:', cacheConversationChat)
                  cacheConversationChat[StringKey.MESSAGES_KEY] = jsChatMessages
                  if (isUpdateMessage) {
                    let deleteChat = cacheChats.splice(existIndex, 1)
                    cacheChats.unshift(chatItem)
                  }
                }
              }
            }
          } else {
            chatItem[StringKey.ACTIVE] = ChatItemEnum.CHAT_ITEM_ACTIVE
            chatItem[StringKey.UN_READ_COUNT] = ChatItemEnum.CHAT_ITEM_UN_READ_COUNT_DEFAULT_ZERO
            cacheChats = []
            cacheChats.unshift(chatItem)
          }
          const topArray: any = []
          const sendTimeSortArray: any = []
          cacheChats.forEach((cacheChatItem: any, index: number) => {
            const { isPin } = cacheChatItem
            if (isPin) {
              topArray.push(cacheChatItem)
            } else {
              sendTimeSortArray.push(cacheChatItem)
            }
          })
          sendTimeSortArray.sort((itemA: any, itemB: any) => {
            const { sendTime: sendTimeA } = itemA
            const { sendTime: sendTimeB } = itemB
            if (sendTimeA > sendTimeB) {
              return -1;
            }
            return 0;
          })
          cacheChats = topArray.concat(sendTimeSortArray)
          await storage.setF(this.CACHE_CHATS_KEY, cacheChats)
          this.getLocalChatList()
        }
    
      //添加多端同步置顶数据
      public addRefreshTopList = async (chatItem: any) => {
        if (chatItem) {
          let findHaveItem = this.topList.find((item, index) => {
            return chatItem[StringKey.COMMUNICATIONID] === item[StringKey.COMMUNICATIONID]
          })
          if (!findHaveItem) {
            this.topList.unshift(chatItem)
          }
          this.setChatTopData()
        }
      }
    
      public deleteTopItemData = async (chatItem: any) => {
        if (chatItem) {
          this.topList = this.topList.filter((item, index) => {
            return chatItem[StringKey.COMMUNICATIONID] !== item[StringKey.COMMUNICATIONID]
          })
          let cacheChats: any = await storage.getF(this.CACHE_CHATS_KEY)
          if (cacheChats && cacheChats.length > 0) {
            let existIndex = -1
            const findActiveChat = cacheChats.find((item: any, index: number) => {
              if (chatItem[StringKey.COMMUNICATIONID] === item[StringKey.COMMUNICATIONID]) {
                existIndex = index;
              }
              return chatItem[StringKey.COMMUNICATIONID] === item[StringKey.COMMUNICATIONID];
            })
            if (findActiveChat) {
              chatItem[StringKey.IS_TOP] = false
              console.log('开始取消置顶', chatItem)
              let deleteChat = cacheChats.splice(existIndex, 1)
              cacheChats.push(chatItem)
              cacheChats = this.chatSort(cacheChats)
              await storage.setF(this.CACHE_CHATS_KEY, cacheChats)
              this.getLocalChatList()
            }
          }
        }
      }
    
      public chatSort = (cacheChats: any[]) => {
        const topArray: any = []
        const sendTimeSortArray: any = []
        cacheChats.forEach((cacheChatItem, index) => {
          const { isPin } = cacheChatItem
          if (isPin) {
            topArray.push(cacheChatItem)
          } else {
            sendTimeSortArray.push(cacheChatItem)
          }
        })
        sendTimeSortArray.sort((itemA: any, itemB: any) => {
          const { sendTime: sendTimeA } = itemA
          const { sendTime: sendTimeB } = itemB
          if (sendTimeA > sendTimeB) {
            return -1;
          }
          return 0;
        })
        cacheChats = topArray.concat(sendTimeSortArray)
        return cacheChats
      }
    
      public groupExit = async (groupId: string) => {
        const res = await request({
          method: 'POST',
          url: api.POST.zxGroupExit,
          data: {
            groupId: groupId
          }
        })
        const { code, hasError, data } = res;
        if (code === '0' && !hasError) {
          this.getChatGroupLists()
        }
      }
      //选中会话
      public setRefreshActiveChatData = async (activeChatData: any) => {
        if (!activeChatData) {
          if (process.env.NODE_ENV === 'development') {
            console.log('保存的activeChatData为空')
          }
          return
        }
        activeChatData[StringKey.ACTIVE] = ChatItemEnum.CHAT_ITEM_ACTIVE
        activeChatData[StringKey.UN_READ_COUNT] = ChatItemEnum.CHAT_ITEM_UN_READ_COUNT_DEFAULT_ZERO
        await storage.setF(this.ACTIVE_CHAT_DATA_KEY, activeChatData);
        this.activeChatData = activeChatData
      }
    
      public recallMessage = async ({ conversationId = '', messageId = '' }) => {
        const dataParams = {
          conversationId: conversationId,
          messageId: messageId
        }
        const res = await request({
          method: 'POST',
          url: api.POST.zxMsgRecall,
          data: dataParams
        })
        const { code, hasError, data } = res
        if (code == '0' && !hasError) {
          this.deleteMessages(messageId)
        } else {
          const { error } = res
        }
      }
      // 删除消息
      public deleteMessages = async (messageIds: string | string[]) => {
        messageIds = [].concat(messageIds);
        this.chats = this.chats.map((item) => {
          if (item.active === ChatItemEnum.CHAT_ITEM_ACTIVE) {
            let messages = item.messages.filter(({ messageId }: any) => {
              return !messageIds.includes(messageId)
            })
            let itemObject = {
              ...item, messages: messages
            }
            this.setRefreshActiveChatData(itemObject)
            return itemObject;
          }
          return item;
        });
        await storage.setF(this.CACHE_CHATS_KEY, this.chats)
        this.getLocalChatList()
      }
      // 初始化websocket
      public initWebSocket = async () => {
        const sdkLogin = await storage.getF(this.SDK_ACCT_LOGIN_KEY)
        if (!!sdkLogin) {
          this.sdkacctLogin = sdkLogin;
          if (!!this.sdkacctLogin) {
            const { user_id, access_token } = this.sdkacctLogin
            this.userId = user_id;
            this.token = access_token;
            this.sendReqBindUserChannel()
          }
        }
      }
      public async sendReqBindUserChannel() {
        const params = {
          appId: this.appId,    //应用ID
          userId: this.userId,  //用户ID
          token: this.token,    //验证码
          manufacturer: 'web',  // 手机厂商
          deviceId: this.deviceId,  // 手机厂商
          osVersion: 'web',     // 系统版本
        }
        const proto: any = proToObject
        const { ReqBindUserChannel }: any = proto
        let protoName = 'ReqBindUserChannel';
        let command = CommandEnum.COMMAND_BIND_USER_REQ
        this.sendWebSocketMessage(
          params,
          ReqBindUserChannel,
          protoName,
          command
        )
      }
    
      public sendMessage = async ({
        content,
        messageType = 1,
        communicationType = CommunicationTypeEnum.PERSON_MESSAGE,
        communicationId = '',
        toUserId = ''
      }: any) => {
    
        if (!this.activeChatData || !this.activeChatData[StringKey.COMMUNICATIONID]) {
          return;
        }
        if (process.env.NODE_ENV === 'development') {
          console.log('激活的会话数据', this.activeChatData)
        }
        const {
          conversationId,
          userId,
        }: any = this.activeChatData
    
        const userInfo = await storage.getF('userInfo')
        const { avatar, nickname } = userInfo
        const otherInfo = {
          userInfo: {
            "userId": userInfo['userId'],
            "avatarUrl": avatar,
            "username": nickname
          }
        }
    
        if (!communicationId && this.activeChatData[StringKey.COMMUNICATIONID]) {
          communicationId = this.activeChatData[StringKey.COMMUNICATIONID]
        }
        if (!toUserId) {
          if (userId) {
            toUserId = userId
          } else {
            toUserId = ''
          }
        }
        if (this.activeChatData[StringKey.COMMUNICATION_Type]
          && communicationType !== this.activeChatData[StringKey.COMMUNICATION_Type]) {
          communicationType = this.activeChatData[StringKey.COMMUNICATION_Type]
        }
        if (!communicationId || !this.userId) {
          console.log('发送消息有参数为空了')
          return;
        }
        let tag = getRandomKey(16)
        const params = {
          appId: this.appId,    //string 对应平台产品APP_ID
          communicationId: communicationId, //string 所在会话ID
          fromUserId: this.userId,  // string 发送方用户ID
          toUserId: toUserId,   // string接收方用户ID
          sendTime: new Date().getTime(),   //int64 发送时间 时间戳
          communicationType: communicationType,     // int32 消息类型:1=个人消息;2=群组消息;3=公众号消息
          messageType: messageType,     // 消息类型:1=文本消息;2=表情消息;3=文件;4=图片;5=语音消息;6=视频消息;7=位置消息;8=命令;9=自定义消息;10=系统消息;11=音视频消息;12=红包消息
          content: content, // string消息文本
          setting: '',  //string 消息设置
          other: JSON.stringify(otherInfo),
          tag: tag,
        }
        const proto: any = proToObject
        //console.log('proto', proto)
        const { CommunicationMessageProto }: any = proto
        let protoName = 'CommunicationMessageProto';
        let command = CommandEnum.COMMAND_SEND_MSG_REQ
        storage.setF(tag, params)
        await this.createSendMessageChats(params, command)
        let that = this;
        setTimeout(() => {
          that.sendWebSocketMessage(
            params,
            CommunicationMessageProto,
            protoName,
            command,
          )
        }, 1000);
    
      }
    
    
      public createSendMessageChats = async (sendData: any, command: number) => {
        const {
          appId,    //string 对应平台产品APP_ID
          communicationId,  //string 所在会话ID
          fromUserId,   // string 发送方用户ID
          toUserId, // string接收方用户ID
          sendTime, //int64 发送时间 时间戳
          communicationType,    // int32 消息类型:1=个人消息;2=群组消息;3=公众号消息
          messageType,      // 消息类型:1=文本消息;2=表情消息;3=文件;4=图片;5=语音消息;6=视频消息;7=位置消息;8=命令;9=自定义消息;10=系统消息;11=音视频消息;12=红包消息
          content,  // string消息文本
          setting,  //string 消息设置
          other,
          tag,
        } = sendData
    
        const itemMessage = JSON.parse(JSON.stringify(sendData))
        itemMessage[StringKey.SEND_MESSAGE_STATUS] = StringKey.SEND_MESSAGE_FAIRED
        itemMessage[StringKey.COMMAND_KEY] = command
    
        this.chats.forEach((value, index) => {
          if (value[StringKey.ACTIVE] == ChatItemEnum.CHAT_ITEM_ACTIVE) {
            value[StringKey.ACTIVE] = ChatItemEnum.CHAT_ITEM_NO_ACTIVE
          }
        })
        if (communicationType == CommunicationTypeEnum.PERSON_MESSAGE
          || communicationType == CommunicationTypeEnum.GROUP_MESSAGE) {
          // 检测聊天列表是否存在
          const findChatIndex = this.chats.findIndex((item) => item.communicationId === communicationId);
          //console.log('findChatIndex', findChatIndex)
          const findChat = this.chats[findChatIndex];
          //console.log('findChatIndex', findChat)
          if (findChat) {
            // 创建聊天后,选中聊天
            // 设置未读数量
            // 自己发的消息不计算
            // 非选中聊天才展示未读数量
            // 追加消息
            let messages = []
            itemMessage[StringKey.ACTIVE] = ChatItemEnum.CHAT_ITEM_ACTIVE
            messages.push(itemMessage)
            if (findChat.messages) {
              findChat.messages?.push(...messages)
            } else {
              findChat.messages = messages
            }
            //让当前激活的active会话item插入消息列表数据
            this.activeChatData.messages = findChat.messages
            let toJsActiveChatData = this.activeChatData
            console.log("toJsActiveChatData" + command, toJsActiveChatData)
            await this.setRefreshActiveChatData(toJsActiveChatData)
            // 聊天已经置顶则不做处理,如果未置顶则将其移动至置顶的后面
            //this.chats.splice(findChatIndex, 1);
            //this.chats.unshift(findChat);
            this.setObserverChatList(findChat, false)
          } else {
            //会话聊天列表不存在 创建会话
            const findFriendChatIndex = this.friends.findIndex((item) => item.communicationId === communicationId);
            const findFriendChat = this.friends[findFriendChatIndex];
            //console.log('command11-联系人找会话消息', findFriendChat)
            if (findFriendChat) {
              let messages = []
              messages.push(itemMessage)
              findFriendChat[StringKey.ACTIVE] = ChatItemEnum.CHAT_ITEM_ACTIVE
              findFriendChat[StringKey.UN_READ_COUNT] = ChatItemEnum.CHAT_ITEM_UN_READ_COUNT_DEFAULT_ZERO
              findFriendChat[StringKey.MESSAGES_KEY] = messages
              this.activeChatData.messages = messages
              let toJsActiveChatData = this.activeChatData
              //console.log(toJsActiveChatData)
              this.setRefreshActiveChatData(toJsActiveChatData)
              this.setObserverChatList(findFriendChat, true)
            } else {
              if (communicationType == CommunicationTypeEnum.GROUP_MESSAGE) {
                let messages = []
                messages.push(itemMessage)
                itemMessage[StringKey.ACTIVE] = ChatItemEnum.CHAT_ITEM_ACTIVE
                itemMessage[StringKey.UN_READ_COUNT] = ChatItemEnum.CHAT_ITEM_UN_READ_COUNT_DEFAULT_ZERO
                itemMessage[StringKey.MESSAGE_ID] = itemMessage[StringKey.MESSAGE_ID]
                itemMessage[StringKey.MESSAGES_KEY] = messages
                this.activeChatData.messages = messages
                let toJsActiveChatData = this.activeChatData
                //console.log(toJsActiveChatData)
                this.setRefreshActiveChatData(toJsActiveChatData)
                this.setObserverChatList(findFriendChat, true)
              } else if (communicationType == CommunicationTypeEnum.PERSON_MESSAGE) {
                console.log('command联系人中找不到该好友')
              } else {
                console.log('command联系人中找不到该好友else情况')
              }
            }
          }
        }
      }
    
      public sendWebSocketMessage = async (
        params: any,
        method: any,
        protoName: string,
        command: number
      ) => {
        const sdkacctLogin = await storage.getF(this.SDK_ACCT_LOGIN_KEY)
        if (!!sdkacctLogin) {
          const { im_module } = sdkacctLogin
          if (!!im_module) {
            //console.log('im_module', im_module)
            const { server_addr, wssocket_port, }: any = im_module
            this.webWocketUrl = `ws://${server_addr}:${wssocket_port}`
            if (this.webWocketUrl) {
              const ret: ArrayBuffer = this.templateFun(
                this.appId,
                this.userId,
                this.deviceId,
                params,
                method,
                protoName,
                command
              )
              this.getWebSocketInstance().createSocket(this.webWocketUrl, ret)
            }
          } else {
            console.log('sdk登录信息-json数据解析异常!')
          }
        } else {
          console.log('获取登录信息失败-跳到登录页面')
          navigate('/zxlogin')
        }
      }
      //proto模板函数
      public templateFun(
        appId: string,
        userId: string,
        deviceId: string,
        param: string,
        method: any,
        protoName: any,
        command: number,
      ): ArrayBuffer {
        //console.log("methodName", methodName, protoName);
        // 函数模板
        let createProto = method.create(param); //  开始创建
        console.log("编码前createProto", createProto);
        let encodeProto = method.encode(createProto).finish(); // 对proto对象进行编码
        console.log("编码后的东西", encodeProto);
        const proto: any = proToObject;
        let protoData = proto[protoName].decode(encodeProto);
        console.log("解码protoData", protoData);
        let encryptionResult = encodeProto;
        // if (command !== COMMAND_PING) {
        //   console.log("aes解密", this.aes.socketDecrypt(encryptionResult));
        // }
        //改交由后台来处理加密了 主要这里会出现前端加密图片地址之类 后端那边会出现解密出错情况
        //let encryptionResult = aes.socketEncrypt(encodeProto); // 编码后的结果拿来加密
        //console.log("encryptionResult解码前的长度", encryptionResult.length);
        //console.log("encryptionResult加密后", encryptionResult);
        //let Base64 = require("js-base64").Base64;
        //encryptionResult = Base64.decode(encryptionResult); //Base64解密
        //console.log("base64解码后", encryptionResult);
        //console.log("encryptionResult解码后的长度",encryptionResult.length);
        //ParseMsgUtil.bindUserDecodeMessage(encryptionResult); //解密消息
        const ret = this.arrayBufferUtil.generateDataPacket(
          protoName,
          encryptionResult,
          appId,
          userId,
          deviceId,
          command
        );
        return ret;
      }
    
      public getWebSocketInstance(): GdchentWebSocket {
        if (!this.gdchentWebSocket) {
          this.gdchentWebSocket = new GdchentWebSocket(
            this.webSocketMessageCallBack,
            this.connectSuccessCallBack,
            this.connectErrorCallBack
          )
        }
        return this.gdchentWebSocket;
      }
      public connectErrorCallBack = () => {
        this.connect = 0;
      }
      public webSocketMessageCallBack = (event: any) => {
        this.connect = 1
        if (this.parseMsgUtil) {
          console.log('接收到服务器消息', event)
          this.parseMsgUtil.parseMsg(event.data, (protoData: any, command: number) => {
            console.log('接收到消息页面', protoData, command)
            if (command == CommandEnum.COMMAND_BIND_USER_RESP) {
              //绑定成功
              //console.log('websocket绑定成功', JSON.stringify(protoData))
              const { lastMsgReceiveTime, lastMsgSequenceId } = protoData
              storage.setF(this.LAST_MESSAGE_KEY, {
                lastMsgReceiveTime: lastMsgReceiveTime,
                lastMsgSequenceId: lastMsgSequenceId,
              });
            }
            if (command == CommandEnum.COMMAND_SEND_MSG_REQ) { //10
              console.log('command10', JSON.stringify(protoData))
              const {
                appId,
                communicationId,
                fromUserId,
                toUserId,
                sendTime,
                communicationType,
                messageType,
                content,
                setting,//json字符串
                messageId,
                updateTime,
              } = protoData;
              storage.setF(this.LAST_MESSAGE_KEY, {
                lastMsgReceiveTime: updateTime,
                lastMsgSequenceId: messageId,
              });
              this.createChats(protoData, command)
            }
            if (command == CommandEnum.COMMAND_SEND_MSG_RSP) {
              //11
              console.log('command' + command, JSON.stringify(protoData))
              this.createChatsByCommand11(protoData, command)
            }
            if (command == CommandEnum.COMMAND_PULL_MSG_RESP) {
              console.log('websocket心跳消息' + command, protoData)
              this.createChatsByHeart(protoData, command)
            }
          })
        } else {
          console.log('this.parseUtil不存在', this)
        }
      }
    
    
      public createChatsByCommand11 = async (protoData: any, command: number) => {
        /**
         *  "resp":{
            "ret":1218,
            "errorCode":"用户给自己发送消息"
           },
         */
        const {
          resp,
          appId,
          userId,
          communicationId,
          sendTime,
          toUserId,
          tag,
          communicationType,
          messageType
        } = protoData
        if (resp && resp['ret'] == 1218) {
          const { errorCode }: any = resp
          return;
        }
        const itemMessage = JSON.parse(JSON.stringify(protoData))
        const tagInfo = await storage.getF(tag)
        const { content } = tagInfo
        itemMessage['content'] = content
        console.log('发出去的消息自己响应', JSON.stringify(itemMessage))
        this.chats.forEach((value, index) => {
          if (value[StringKey.ACTIVE] == ChatItemEnum.CHAT_ITEM_ACTIVE) {
            value[StringKey.ACTIVE] = ChatItemEnum.CHAT_ITEM_NO_ACTIVE
          }
        })
        if (communicationType == CommunicationTypeEnum.PERSON_MESSAGE
          || communicationType == CommunicationTypeEnum.GROUP_MESSAGE) {
          // 检测聊天列表是否存在
          const findChat = this.chats.find((item) => item.communicationId === communicationId);
          //console.log('findChatIndex', findChat)
          if (findChat && findChat[StringKey.MESSAGES_KEY]) {
            findChat[StringKey.SEND_TIME] = sendTime
            let messages = []
            messages = findChat[StringKey.MESSAGES_KEY]
            let itemFindMessage = messages.find((value: any, index: number) => {
              return value[StringKey.TAG] === tag
            })
            console.log('发出去的消息', itemFindMessage)
            if (itemFindMessage) {
              itemFindMessage[StringKey.ACTIVE] = ChatItemEnum.CHAT_ITEM_ACTIVE
              itemFindMessage[StringKey.SEND_TIME] = sendTime
              itemFindMessage[StringKey.SEND_MESSAGE_STATUS] = StringKey.SEND_MESSAGE_SUCCESS
              itemFindMessage[StringKey.COMMAND_KEY] = command
              itemFindMessage[StringKey.MESSAGE_ID] = itemMessage[StringKey.MESSAGE_ID]
              this.activeChatData[StringKey.SEND_TIME] = sendTime
              //让当前激活的active会话item插入消息列表数据
              this.activeChatData.messages = findChat.messages
              let toJsActiveChatData = this.activeChatData
              console.log("发出前toJsActiveChatData" + command, toJsActiveChatData)
              await this.setRefreshActiveChatData(toJsActiveChatData)
              // 聊天已经置顶则不做处理,如果未置顶则将其移动至置顶的后面
              //this.chats.splice(findChatIndex, 1);
              //this.chats.unshift(findChat);
              this.setObserverChatList(findChat, false, true)
            } else {
              //假设用户在发送消息的时候删除本地会话的情况的业务逻辑 保存发送消息 也是几乎不可能发生的情况 预防万一
              //导致本地消息tag找不到
              this.createNewChatByNoCurrentChat(protoData, command)
            }
          } else {
            this.createNewChatByNoCurrentChat(protoData, command)
          }
        }
      }
      ////假设在发消息的时候跟收到消息之前这段时间突然删除会话 几乎不可能发生的情况
      //发出消息如果还没收到消息之前突然删除 执行创建的逻辑
      createNewChatByNoCurrentChat = async (protoData: any, command: number) => {
        const {
          resp,
          appId,
          userId,
          communicationId,
          sendTime,
          toUserId,
          tag,
          communicationType,
          messageType
        } = protoData
        const itemMessage = JSON.parse(JSON.stringify(protoData))
        const tagInfo = await storage.getF(tag)
        const { content } = tagInfo
        const userInfo = await storage.getF('userInfo')
        const { avatar, nickname } = userInfo
        const otherInfo = {
          userInfo: {
            "userId": userInfo['userId'],
            "avatarUrl": avatar,
            "username": nickname
          }
        }
        itemMessage['other'] = JSON.stringify(otherInfo)
        itemMessage['content'] = content
        itemMessage[StringKey.COMMAND_KEY] = command
        itemMessage[StringKey.SEND_TIME] = sendTime
        itemMessage[StringKey.SEND_MESSAGE_STATUS] = StringKey.SEND_MESSAGE_SUCCESS
        // 检测聊天列表是否存在
        const findChatIndex = this.chats.findIndex((item) => item.communicationId === communicationId);
        //console.log('findChatIndex', findChatIndex)
        const findChat = this.chats[findChatIndex];
        //console.log('findChatIndex', findChat)
        if (findChat) {
          // 创建聊天后,选中聊天
          // 设置未读数量
          // 自己发的消息不计算
          // 非选中聊天才展示未读数量
          // 追加消息
          let messages = []
          messages.push(itemMessage)
          //[]
          if (findChat.messages) {
            findChat.messages?.push(...messages)
          } else {
            findChat.messages = messages
          }
          //让当前激活的active会话item插入消息列表数据
          this.activeChatData.messages = findChat.messages
          let toJsActiveChatData = this.activeChatData
          //console.log("toJsActiveChatData" + command, toJsActiveChatData)
          await this.setRefreshActiveChatData(toJsActiveChatData)
          this.setObserverChatList(findChat, false)
        } else {
          //会话聊天列表不存在 创建会话
          const findFriendChatIndex = this.friends.findIndex((item) => item.userId === toUserId);
          const findFriendChat = this.friends[findFriendChatIndex];
          if (findFriendChat) {
            let messages = []
            messages.push(itemMessage)
            findFriendChat[StringKey.ACTIVE] = ChatItemEnum.CHAT_ITEM_ACTIVE
            findFriendChat[StringKey.UN_READ_COUNT] = ChatItemEnum.CHAT_ITEM_UN_READ_COUNT_DEFAULT_ZERO
            findFriendChat[StringKey.MESSAGE_ID] = itemMessage[StringKey.MESSAGE_ID]
            findFriendChat[StringKey.MESSAGES_KEY] = messages
            this.activeChatData.messages = messages
            let toJsActiveChatData = this.activeChatData
            //console.log(toJsActiveChatData)
            this.setRefreshActiveChatData(toJsActiveChatData)
            this.setObserverChatList(findFriendChat, true)
          } else {
            if (communicationType == CommunicationTypeEnum.GROUP_MESSAGE) {
              let messages = []
              messages.push(itemMessage)
              itemMessage[StringKey.ACTIVE] = ChatItemEnum.CHAT_ITEM_ACTIVE
              itemMessage[StringKey.UN_READ_COUNT] = ChatItemEnum.CHAT_ITEM_UN_READ_COUNT_DEFAULT_ZERO
              itemMessage[StringKey.MESSAGE_ID] = itemMessage[StringKey.MESSAGE_ID]
              itemMessage[StringKey.MESSAGES_KEY] = messages
              this.activeChatData.messages = messages
              let toJsActiveChatData = this.activeChatData
              //console.log(toJsActiveChatData)
              this.setRefreshActiveChatData(toJsActiveChatData)
              this.setObserverChatList(findFriendChat, true)
            } else if (communicationType == CommunicationTypeEnum.PERSON_MESSAGE) {
              console.log('command联系人中找不到该好友')
            } else {
              console.log('command联系人中找不到该好友else情况')
            }
    
          }
        }
    
      }
    
      public createChatsByHeart = (protoData: any, command: number) => {
        const { lastMsgSequenceId, lastMsgReceiveTime, chatMsg } = protoData
        if (lastMsgSequenceId && lastMsgReceiveTime) {
          storage.setF(this.LAST_MESSAGE_KEY, {
            lastMsgReceiveTime: lastMsgReceiveTime,
            lastMsgSequenceId: lastMsgSequenceId,
          });
        }
        if (!chatMsg) {
          return;
        }
        for (let i = 0; i < chatMsg.length; i++) {
          let itemMessage = chatMsg[i];
          const {
            resp,
            appId,
            userId,
            communicationId,
            messageId,
            sendTime,
            toUserId,
            communicationType,
            messageType,
            tag,
            deviceType,
            content,
          } = itemMessage
          itemMessage[StringKey.COMMAND_KEY] = command
          itemMessage[StringKey.SEND_TIME] = sendTime
          if (messageType == 1101) {
            this.getChatTopData()
            return;
          }
          if (communicationType == CommunicationTypeEnum.PERSON_MESSAGE
            || communicationType == CommunicationTypeEnum.GROUP_MESSAGE) {
            // 检测聊天列表是否存在
            const findChatIndex = this.chats.findIndex((item) => {
              return item.communicationId === communicationId
            });
            const findChat = this.chats[findChatIndex];
            if (findChat) {
              // 创建聊天后,选中聊天
              // 设置未读数量
              // 自己发的消息不计算
              // 非选中聊天才展示未读数量
              // 追加消息
              let messages = []
              messages.push(itemMessage)
              console.log('心跳接收到的消息', itemMessage)
              if (findChat.messages) {
                let findChatItemMessage = findChat.messages.find((item: any) => item.tag = itemMessage['tag'])
                //let findChatItemMessage = findChat.messages.find((item) => item.messageId = itemMessage['messageId'])
                if (findChatItemMessage) {
                  console.log('心跳消息已经存在终止本轮消息', findChatItemMessage)
                  continue;
                }
                console.log('消息不存在开始插入消息')
                findChat.messages = findChat.messages.concat(messages)
              } else {
                findChat.messages = messages
              }
              //心跳有重复 所以要放在后面一点
              if (this.chats.length <= 0 || (userId !== this.defaultId && findChat['conversationId'] !== this.activeChatData['conversationId'])) {
                findChat.active = ChatItemEnum.CHAT_ITEM_ACTIVE
                findChat.unReadCount = ChatItemEnum.CHAT_ITEM_UN_READ_COUNT_DEFAULT_ZERO
              } else {
                findChat.active = ChatItemEnum.CHAT_ITEM_NO_ACTIVE;
                findChat.unReadCount += 1;
              }
              // this.activeChatData.messages = findChat.messages
              //let toJsActiveChatData = toJS(this.activeChatData)
              //console.log(toJsActiveChatData)
              //this.setRefreshActiveChatData(toJsActiveChatData)
              // 聊天已经置顶则不做处理,如果未置顶则将其移动至置顶的后面
              //this.chats.splice(findChatIndex, 1);
              //this.chats.unshift(findChat);
              this.setObserverChatList(findChat, false)
            } else {
              //会话聊天列表不存在 创建会话
              const findFriendChatIndex = this.friends.findIndex((item) => item.userId === toUserId);
              const findFriendChat = this.friends[findFriendChatIndex];
              console.log('联系人找会话消息', findFriendChat)
              if (findFriendChat) {
                let messages = []
                messages.push(itemMessage)
                findFriendChat[StringKey.ACTIVE] = ChatItemEnum.CHAT_ITEM_ACTIVE
                findFriendChat[StringKey.UN_READ_COUNT] = ChatItemEnum.CHAT_ITEM_UN_READ_COUNT_DEFAULT_ZERO
                findFriendChat[StringKey.MESSAGES_KEY] = messages
                this.activeChatData.messages = messages
                let toJsActiveChatData = this.activeChatData
                //console.log(toJsActiveChatData)
                this.setRefreshActiveChatData(toJsActiveChatData)
                this.setObserverChatList(findFriendChat, true)
              } else {
                console.log('联系人中找不到该好友')
              }
            }
          }
        }
    
      }
    
      public createChats = async (protoData: any, command: number) => {
        const {
          appId,
          communicationId,
          fromUserId,
          toUserId,
          sendTime,
          communicationType, // 消息类型:1=个人消息;2=群组消息;3=公众号消息
          messageType,//1=文本消息;2=表情消息;3=文件;4=图片;5=语音消息;6=视频消息;7=位置消息;8=命令;9=自定义消息;10=红包消息
          content,
          setting,//json字符串
          messageId,
          updateTime,
          tag,
        } = protoData;
    
        const itemMessage = JSON.parse(JSON.stringify(protoData))
    
        itemMessage[StringKey.COMMAND_KEY] = command
        itemMessage[StringKey.SEND_TIME] = sendTime
        if (messageType == 1101) {
          this.getChatTopData()
          return;
        }
        let cacheTag = await storage.getF(tag)
        if (cacheTag) {
          return;
        }
        // 消息类型:1=个人消息;2=群组消息;3=公众号消息
        if (communicationType == CommunicationTypeEnum.PERSON_MESSAGE ||
          communicationType == CommunicationTypeEnum.GROUP_MESSAGE
        ) {
          // 检测聊天列表是否存在
          const findChatIndex = this.chats.findIndex((item) => item.communicationId === communicationId);
          //console.log('findChatIndex', findChatIndex)
          const findChat = this.chats[findChatIndex];
          //console.log('findChatIndex', findChat)
          if (findChat) {
            // 创建聊天后,选中聊天
            // 设置未读数量
            // 自己发的消息不计算
            // 非选中聊天才展示未读数量
            let isCreateTop = false;
            //如果会话列表长度是1个 并且选中的userId跟
            if (this.chats.length <= 0 || (fromUserId !== this.defaultId && findChat[StringKey.COMMUNICATIONID] !== this.activeChatData[StringKey.COMMUNICATIONID])) {
              isCreateTop = true
              findChat[StringKey.ACTIVE] = ChatItemEnum.CHAT_ITEM_ACTIVE
              findChat[StringKey.UN_READ_COUNT] = ChatItemEnum.CHAT_ITEM_UN_READ_COUNT_DEFAULT_ZERO;
            } else {
              findChat[StringKey.ACTIVE] = ChatItemEnum.CHAT_ITEM_NO_ACTIVE;
              findChat[StringKey.UN_READ_COUNT] += 1
            }
            // 追加消息
            let messages = []
            messages.push(itemMessage)
            if (findChat.messages) {
              findChat.messages = findChat.messages.concat(messages)
            } else {
              findChat.messages = messages
            }
            findChat[StringKey.IS_TOP] = false;
            this.activeChatData = findChat;
            let toJsActiveChatData = this.activeChatData
            //console.log(toJsActiveChatData)
            this.setRefreshActiveChatData(toJsActiveChatData)
            // 聊天已经置顶则不做处理,如果未置顶则将其移动至置顶的后面
            //this.chats.splice(findChatIndex, 1);
            //this.chats.unshift(findChat);
            this.setObserverChatList(findChat, false, true)
          } else {
            //会话聊天列表不存在 创建会话
            const findFriendChatIndex = this.friends.findIndex((item) => item.userId === fromUserId);
            const findFriendChat = this.friends[findFriendChatIndex];
            //console.log('联系人找会话消息', findFriendChat)
            if (findFriendChat) {
              let messages = []
              messages.push(itemMessage)
              findFriendChat[StringKey.MESSAGES_KEY] = messages
              findFriendChat[StringKey.ACTIVE] = ChatItemEnum.CHAT_ITEM_ACTIVE
              findFriendChat[StringKey.UN_READ_COUNT] = ChatItemEnum.CHAT_ITEM_UN_READ_COUNT_DEFAULT_ZERO
              findFriendChat[StringKey.IS_TOP] = false;
              this.activeChatData = findFriendChat
              let toJsActiveChatData = this.activeChatData
              //console.log(toJsActiveChatData)
              this.setRefreshActiveChatData(toJsActiveChatData)
              this.setObserverChatList(findFriendChat, false, true)
            } else {
              console.log('联系人中找不到该好友')
            }
          }
        }
      }
      //websocket请求成功
      public connectSuccessCallBack = () => {
        console.log('连接成功,开始发心跳', this)
        this.connect = 1
        sendHeartTimer = setInterval(() => {
          if (sendHeartTimer) {
            if (this.sendHeart && typeof this.sendHeart === 'function') {
              this.sendHeart(); //发送心跳包
              //this.sendHeartEmpty()
            } else {
              console.log('this.sendHeart不是一个函数')
            }
          }
        }, WEB_SOCKET_TIMEOUT);
      }
    
      //发websocket心跳包
      public sendHeartEmpty = async () => {
        //console.log("开始发送心跳包");
        const protoName = "EmptyResp";
        const protoData = await storage.getF(this.LAST_MESSAGE_KEY)
        let params: any = {
        }
        if (!protoData) {
          params = {
            lastMsgSequenceId: '',
            lastMsgReceiveTime: '',
          }
        } else {
          const { lastMsgSequenceId, lastMsgReceiveTime } = protoData
          params = {
            lastMsgSequenceId: lastMsgSequenceId ? lastMsgSequenceId : '',
            lastMsgReceiveTime: lastMsgReceiveTime ? lastMsgReceiveTime : '',
          };
        }
        //区分全局变量 改成局部变量
        let command: number = CommandEnum.COMMAND_PING; //发出指令码 98
        const proto: any = proToObject;
        const { EmptyResp }: any = proto;
        const ret: ArrayBuffer = this.templateFun(
          this.appId,
          this.userId,
          this.deviceId,
          params,
          EmptyResp,
          protoName,
          command
        );
        this.getWebSocketInstance().createSocket(this.webWocketUrl, ret)
      }
      //发websocket心跳包
      public sendHeart = async () => {
        //console.log("开始发送心跳包");
        const protoName = "HeartBeatMsg";
        const protoData = await storage.getF(this.LAST_MESSAGE_KEY)
        let params: any = {}
        if (!protoData) {
          params = {
            lastMsgSequenceId: '',
            lastMsgReceiveTime: '',
          }
        } else {
          const { lastMsgSequenceId, lastMsgReceiveTime } = protoData
          params = {
            lastMsgSequenceId: lastMsgSequenceId ? lastMsgSequenceId : '',
            lastMsgReceiveTime: lastMsgReceiveTime ? lastMsgReceiveTime : '',
          };
        }
        //区分全局变量 改成局部变量
        const command = CommandEnum.COMMAND_PULL_MSG_REQ;
        const proto: any = proToObject;
        const { HeartBeatMsg }: any = proto;
        const ret: ArrayBuffer = this.templateFun(
          this.appId,
          this.userId,
          this.deviceId,
          params,
          HeartBeatMsg,
          protoName,
          command
        );
        this.getWebSocketInstance().createSocket(this.webWocketUrl, ret)
      }
    
      public setChatTopData = async () => {
        /**
       * //会话置顶
        key : "CONVERSATION_PIN_TAG"
        value :
       [
         {
            "communicationId": "179qa90yburad3k7gjiuk",
            "isPin": true,
            "pinTime": 1608190636682
       },
       {
           "communicationId": "aaaaa90yburad3k7wwwww",
           "isPin": true,
           "pinTime": 1608190612345
       }
       ]
       */
        const jsonDataArray = this.topList
        const res = await request({
          method: 'POST',
          url: api.POST.zxSetChatTopData,
          data: {
            data: JSON.stringify(jsonDataArray),
            dataType: this.CHAT_TOP_DATA
          }
        })
        const { code, hasError, data } = res;
        if (code === '0' && !hasError) {
          storage.setF(this.CHAT_TOP_DATA, jsonDataArray)
        }
      }
      //获取顶部数据
      public getChatTopData = async () => {
        const res: any = await request({
          method: 'GET',
          url: api.GET.zxGetChatTopData,
          data: {
            dataType: this.CHAT_TOP_DATA
          }
        })
        const { code, hasError, data }: any = res;
        if (code == '0' && !hasError) {
          const { dataValue } = data;
          if (dataValue && typeof dataValue === 'string') {
            let topArray = JSON.parse(dataValue)
            if (topArray) {
              let cacheChats: any = await storage.getF(this.CACHE_CHATS_KEY)
              if (cacheChats && Array.isArray(cacheChats) && cacheChats.length > 0) {
                topArray.forEach((element: any) => {
                  cacheChats.forEach((item: any, index: number) => {
                    if (item['conversationId'] === element['communicationId']) {
                      if (item[StringKey.IS_TOP] != element[StringKey.IS_TOP]) {
                        item[StringKey.IS_TOP] = true
                        item['communicationId'] = element['communicationId']
                        this.setObserverChatList(item, item[StringKey.IS_TOP])
                      }
                    }
                  })
                });
              }
              this.topList = topArray
            }
          }
        }
      }
    
      //添加用户到指定的联系组
      public addUserToContactGroup = async (groupId: string, userId: string) => {
        //通过groupId找到对应的组
        let jsGroups = this.groups
        let groupList = this.userInfoList
        if (jsGroups) {
          for (let i in jsGroups) {
            let value = jsGroups[i]
            if (value['groupId'] == groupId) {
              let { userIds } = value;
              if (userIds) {
                let itemUserId = userIds.find((itemUserId: string, index: number) => {
                  return userId === itemUserId
                })
                if (!itemUserId) {
                  userIds.push(userId);
                  value['userIds'] = userIds
                  let itemUser = await this.getUserInfoById(userId)
                  if (itemUser && itemUser['userId']) {
                    itemUser[StringKey.COMMUNICATIONID] = itemUser[StringKey.CONVERSATIONID]
                  }
                  //添加到groupArray中
                  for (let m in groupList) {
                    let groupItem = groupList[m]
                    if (groupItem['groupId'] === groupId) {
                      let itemInfo = groupItem['groups'].find((itemInfo: any, index: number) => {
                        return itemInfo['userId'] === userId
                      })
                      if (!itemInfo) {
                        groupItem['groups'].push(itemUser)
                      }
                    }
                  }
                }
              }
            }
          }
          this.userInfoList = groupList
          this.groups = jsGroups
          this.setDemoKvDataSet(this.groups)
        }
      }
    
      //删除用户到指定的联系组
      public async deleteUserToContactGroup(groupId: string, userId: string) {
        //通过groupId找到对应的组
        if (this.groups) {
          this.groups.forEach((value: any, index: number) => {
            if (value['groupId'] == groupId) {
              let { userIds } = value;
              if (userIds) {
                userIds = userIds.filter((itemUserId: string, index: number) => {
                  return userId != itemUserId;
                })
                value['userIds'] = userIds;
              }
            }
          })
          this.setDemoKvDataSet(
            this.groups
          )
        }
      }
      //通过分组名字来创建分组
      public createGroupByName = async (groupName: string) => {
        if (this.groups) {
          let isHave: boolean = false;
          //如果数组里面有该数组就创建数组
          this.groups.forEach((item: any, index: number) => {
            if (item['groupName'] == groupName) {
              isHave = true
            }
          })
          if (!isHave) {
            const item: any = {
              groupId: randomKey(16),
              groupName: groupName,
              userIds: []
            }
            this.groups.push(item)
            //console.log('groups', this.groups)
            this.setDemoKvDataSet(this.groups)
          } else {
            console.log('已经创建过该组了')
          }
        }
      }
    
      //创建分组
      public async createContactGroup(item: any) {
        if (this.groups) {
          let isHave: boolean = false;
          this.groups.forEach((itemValue: any, index: number) => {
            if (item['groupId'] == itemValue['groupId']) {
              isHave = true;
            }
          })
          if (!isHave) {
            this.groups.push(item)
          } else {
            console.log('该用户组已经创建了')
          }
          await this.setDemoKvDataSet(this.groups)
          this.getDemoKvDataGet()
        }
      }
      //通过id删除联系组
      public async deleteContactGroupById(groupId: string) {
        //如果当前数组中有该元素那就删除
        if (this.groups) {
          this.groups = this.groups.filter((value: any, index: number) => {
            return value['groupId'] != groupId
          })
          this.setDemoKvDataSet(this.groups)
        }
      }
    
      //设置好友分组
      public async setDemoKvDataSet(groupArray: any) {
        const dataParams = {
          key: this.contact_tag,
          protocolVersion: 1,
          value: JSON.stringify(groupArray)
        };
        const res = await request({
          method: 'POST',
          url: api.POST.zxPostDemoKvDataSet,
          data: dataParams
        })
        const { code, hasError, data } = res;
        if (code == '0' && !hasError) {
          this.getDemoKvDataGet()
        }
      }
      //获取或者更新好友分组
      public getDemoKvDataGet = async () => {
        const res = await request({
          method: 'GET',
          url: api.GET.zxGetDemoKvDataGet,
          data: {
            key: this.contact_tag
          }
        })
        const { code, hasError, data } = res;
        if (code == '0' && !hasError) {
          const { key, value, version, userId } = data;
          if (value && typeof value == 'string') {
            let groups = JSON.parse(value)
            if (groups && Array.isArray(groups)) {
              this.groups = groups
              let groupList = []
              for (let m in groups) {
                let item = groups[m]
                let userIds = item['userIds']
                let groupId = item['groupId']
                let groupName = item['groupName']
    
                let promiseList = []
                if (userIds && Array.isArray(userIds) && userIds.length > 0) {
                  for (let itemId of userIds) {
                    if (itemId) {
                      let itemUser = await this.getUserInfoById(itemId)
                      if (itemUser && itemUser['userId']) {
                        itemUser[StringKey.COMMUNICATIONID] = itemUser[StringKey.CONVERSATIONID]
                      }
                      promiseList.push(itemUser)
                    }
                  }
                }
                const groupItem = {
                  groupId: groupId,
                  groupName: groupName,
                  groups: promiseList
                }
                groupList.push(groupItem)
              }
              this.userInfoList = groupList
    
            }
          }
        }
      }
    
      public getUserInfoById = async (user_id: string) => {
        const res = await request({
          method: 'GET',
          url: api.GET.zxGetUserInfoById,
          data: {
            userId: user_id
          }
        })
        const { code, hasError, data } = res;
        if (code == '0' && !hasError) {
          return data;
        } else {
          return {}
        }
      }
    
      //sdk 获取新的好友
      public async getNewFriends() {
        const res = await request({
          method: 'GET',
          url: api.GET.zxSdkNewFriendList,
          data: {}
        })
        //console.log('newFriendList', res)
        const { code, data, hasError } = res;
        if (code == '0' && !hasError) {
          if (data && Array.isArray(data)) {
            data.forEach((item, index) => {
              item[StringKey.COMMUNICATIONID] = item[StringKey.CONVERSATIONID]
            })
            this.newFriends = data;
          }
    
        }
      }
    
      //sdk 获取联系人列表
      public async getFriendList() {
        const res = await request({
          method: 'GET',
          url: api.GET.zxSdkGetFriendList,
          data: {}
        })
        //console.log('getFriendList', res)
        let { code, data, hasError } = res;
        if (code == '0' && !hasError) {
          if (Array.isArray(data)) {
            const userInfo = await storage.getF('userInfo')
            if (userInfo) {
              const { userId } = userInfo
              data = data.filter((item, index, array) => {
                if (!item[StringKey.MESSAGES_KEY]) {
                  item[StringKey.MESSAGES_KEY] = []
                }
                if (!item[StringKey.ACTIVE]) {
                  item[StringKey.ACTIVE] = ChatItemEnum.CHAT_ITEM_NO_ACTIVE
                }
                if (!item[StringKey.UN_READ_COUNT]) {
                  item[StringKey.UN_READ_COUNT] = ChatItemEnum.CHAT_ITEM_UN_READ_COUNT_DEFAULT_ZERO
                }
                if (!item[StringKey.IS_TOP]) {
                  item[StringKey.IS_TOP] = false;
                }
                if (!item[StringKey.COMMUNICATIONID]) {
                  item[StringKey.COMMUNICATIONID] = item[StringKey.CONVERSATIONID]
                }
                if (!item[StringKey.COMMUNICATION_Type]) {
                  item[StringKey.COMMUNICATION_Type] = CommunicationTypeEnum.PERSON_MESSAGE
                }
                return userId != item.userId
              })
              this.friends = data;
            }
    
          }
        }
      }
    
      //sdk 添加好友
      public async addFriend({ remark, userId }: any) {
        //12618400093    179gxkj9wg3g3hhvij9n6
        //12618400094   179gxkjhisvwn56zrzdeb
        //12618400095   179gxkjoo9vh5lcaf8y38
        //zxSdkPostAddFriend
        const res = await request({
          method: 'POST',
          url: api.POST.zxSdkPostAddFriend,
          data: {
            remark: remark,
            userId: userId,
          }
        })
        //console.log('添加好友成功', res)
        const { code, data, hasError } = res;
        if (code == '0' && !hasError) {
        }
      }
      //sdk 接受好友邀请
      public async acceptFriend(userId: string) {
        ///sdk/v1/user/friend/add/accept
        const res = await request({
          method: 'POST',
          url: api.POST.zxSdkAcceptFriend,
          data: {
            userId: userId,
          }
        })
        console.log('params', userId)
        console.log('接受好友成功', res)
        const { code, data, hasError } = res;
        if (code == '0' && !hasError) {
        }
      }
    
      public getChatGroupLists = async (isCreateChat = false) => {
        const res = await request({
          method: 'GET',
          url: api.GET.zxgroupLists,
          data: {}
        })
        const { code, data, hasError } = res;
        if (code == '0' && !hasError) {
          if (data && Array.isArray(data)) {
            this.creatChatGroupsList = data;
            this.allGroupMembers = []
            for (let i in data) {
              const item = data[i]
              await this.getAllChatGroupMember(item)
            }
            if (isCreateChat && this.allGroupMembers.length > 0) {
              let length = this.allGroupMembers.length
              this.setRefreshActiveChatData(this.allGroupMembers[length - 1])
              this.setObserverChatList(this.allGroupMembers[length - 1], false, true)
            }
          }
        }
      }
    
      public getAllChatGroupMember = async (item:any) => {
        const {
          communicationId,
          managerList,//群管理员ID列表
        } = item;
        const res: any = await request({
          method: 'GET',
          url: api.GET.zxGetAllGroupMember,
          data: {
            groupId: communicationId
          },
        })
        const { code, hasError, data } = res
        if (res.code == '0' && !hasError) {
          if (!item[StringKey.MESSAGES_KEY]) {
            item[StringKey.MESSAGES_KEY] = []
          }
          if (!item[StringKey.ACTIVE]) {
            item[StringKey.ACTIVE] = ChatItemEnum.CHAT_ITEM_NO_ACTIVE
          }
          if (!item[StringKey.UN_READ_COUNT]) {
            item[StringKey.UN_READ_COUNT] = ChatItemEnum.CHAT_ITEM_UN_READ_COUNT_DEFAULT_ZERO
          }
          if (!item[StringKey.IS_TOP]) {
            item[StringKey.IS_TOP] = false;
          }
    
          if (!item[StringKey.COMMUNICATIONID]) {
            item[StringKey.COMMUNICATIONID] = item[StringKey.CONVERSATIONID]
          }
          if (!item[StringKey.COMMUNICATION_Type]) {
            item[StringKey.COMMUNICATION_Type] = CommunicationTypeEnum.GROUP_MESSAGE
          }
          let chatGroupItem = {
            ...item,
            members: data
          }
          this.allGroupMembers.push(chatGroupItem);
        }
      }
    
      public createChatGroup = async (chatGroup: CreateChatGroup, isCreateChat:boolean) => {
        const res = await request({
          method: 'POST',
          url: api.POST.createChatGroup,
          data: chatGroup
        })
        const { code, hasError, data } = res
        if (code === '0' && !hasError) {
          console.log('创建群组成功', res, chatGroup)
          this.getChatGroupLists(isCreateChat)
        }
      }
    
      //demo 分组
      public async postTagList() {
        const res = await request({
          method: 'POST',
          url: api.POST.zxPostDemoTagList,
          data: {}
        })
      }
      //demo 创建分组
      public async postTagCreate() {
        let userIdArray = [
          '179gxkics21lq1qedh4ej',
          '179gxkigcsjdz9t1p3wr0',
          '179gxkijxj168hvp0qp3h',
          '179gxkio9p7ejoq1yx3f2',
          '179gxkisdfh6u9si4087j',
          '179gxkiw2dx73sr3u6nbk',
          '179gxkj0tbx7g1pb79rbl',
          '179gxkj9wg3g3hhvij9n6',
          '179gxkjhisvwn56zrzdeb',
          '179gxkjoo9vh5lcaf8y38',
          '179gxkjtf7vhhuahsc239'
        ];
        let userIdsString = '';
        for (let i = 0; i < userIdArray.length; i++) {
          if (i < userIdArray.length - 1) {
            userIdsString = userIdsString + userIdArray[i] + ','
          } else {
            userIdsString = userIdsString + userIdArray[i];
          }
        }
        //let arrayString=JSON.stringify(userIdArray)
        const res = await request({
          method: 'POST',
          url: api.POST.zxPostDemoTagCreate,
          data: {
            name: 'test1',
            userIds: userIdsString,
          }
        })
        const { code, hasError, data } = res
        if (code == '0' && !hasError) {
          const { members } = data
        }
      }
    }
    

    整个项目的大部分逻辑都在这个store文件里面
    最后给出我这边sdk的package.json文件的配置代码如下:

    {
      "name": "ImSdk",
      "version": "1.0.0",
      "description": "ImSdk",
      "main": "index.js",
      "scripts": {
        "test": "echo \"Error: no test specified\" && exit 1",
        "build": "webpack",
        "proto": "pbjs -t static-module -w commonjs -o src/proto/proto.js src/proto/*.proto"
      },
      "keywords": [],
      "author": "gdchent",
      "license": "ISC",
      "dependencies": {
        "@babel/core": "^7.13.1",
        "ali-oss": "^6.13.2",
        "axios": "^0.21.1",
        "babel-plugin-named-asset-import": "^0.3.7",
        "crypto-js": "4.0.0",
        "html-webpack-plugin": "^5.2.0",
        "js-base64": "^3.6.0",
        "jsencrypt": "3.0.0-rc.1",
        "localforage": "^1.9.0",
        "moment": "^2.29.1",
        "postcss-preset-env": "6.7.0",
        "protobufjs": "^6.10.2",
        "typescript": "3.7.2",
        "webpack": "4.42.0",
        "webpack-cli": "^4.5.0",
        "webpack-dev-server": "3.10.3",
        "webpack-manifest-plugin": "2.2.0",
        "workbox-webpack-plugin": "4.3.1"
      },
      "devDependencies": {
        "@babel/plugin-proposal-decorators": "^7.13.5",
        "@babel/plugin-proposal-optional-chaining": "^7.13.0",
        "@babel/preset-env": "^7.13.5",
        "awesome-typescript-loader": "^5.2.1",
        "babel-loader": "^8.2.2",
        "babel-plugin-import": "^1.13.3",
        "source-map-loader": "^2.0.1",
        "ts-loader": "^8.0.17"
      }
    }
    
    

    通过上述配置可以看到,执行npm run build 就可以愉快的正常的打包了,然后就是坐等打包成功了...
    示例效果如下:


    打包输出效果图.png

    由于我在webpack.config.js文件里面配置了LibraryTarget为umd模式,也就是通用,所以我这里可以直接用index.html引入,接下来我们看下刚刚打包成功的dist文件夹截图如下:


    bundleJs.png
    接下来我们在dist文件夹下新建index.html文件引入js,示例代码如下:
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>测试打包出来的js文件</title>
        <script type="text/javascript" src="./bundle.js"></script>
    </head>
    <body>
        
    </body>
    </html>
    

    接下来运行当前html文件,按下f12,由于我这里调用了我公司的后台接口,这个时候肯定会出现跨域之类的,没关系,说明目的达到了就成,截图如下:


    js-sdk打包运行效果.png

    相关文章

      网友评论

          本文标题:2021-02-26 Web-im js-sdk开发打包流程

          本文链接:https://www.haomeiwen.com/subject/sysmfltx.html