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

2021-02-26  本文已影响0人  gdlooker

年前初步的完成了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
上一篇下一篇

猜你喜欢

热点阅读