index.js 9.3 KB
Newer Older
DCloud_JSON's avatar
DCloud_JSON 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98
// #ifdef VUE3
import {watch,computed} from 'vue'
// #endif

/**
 * 会话对象
 * data:会话对象数据模型(conversationDatas是原始数据,data为经过转化的数据)
 * loadMore:加载更多数据方法
 */
import Conversation from './Conversation.class.js';
import $state from '@/uni_modules/uni-im/sdk/state/index.js';
import $utils from '@/uni_modules/uni-im/sdk/utils/index.js';
import MsgManager from '@/uni_modules/uni-im/sdk/ext/MsgManager.class.js';

import $extensions from '../extensions.js';
import $users from '../users.js';
import $group from '../group.js';

const uniImCo = uniCloud.importObject("uni-im-co")
import {
  store as uniIdStore,
} from '@/uni_modules/uni-id-pages/common/store'

const current_uid = () => uniIdStore.userInfo._id
// console.log('current_uid', current_uid())

export default {
  // 同步获取已经缓存在本地的会话信息,适用于在能够确定会话信息已经拉到本地的上下文中调用。
  getCached(conversation_id) {
    return $state.conversation.dataList.find(c => c.id == conversation_id)
  },

  async get(param) {
    /**
     *  字符串	会话id
     * 	数组		一组会话id(暂不支持)
     * 	对象类型	会话对方信息(用于如果本地不存在则需要自动创建的场景),包括:{friend_uid,to_uid,from_uid,group_id,user_info}
     */
    let conversationId = false
    if (param) {
      if (typeof param == 'object') {
        let {
          friend_uid,
          user_id,
          group_id,
          conversation_id
        } = param
        conversationId = conversation_id
        if (user_id) {
          friend_uid = user_id
          param.friend_uid = user_id
        }
        if (!conversationId) {
          if (!group_id && !friend_uid) {
            console.log('param---------', param);
            throw new Error("会话对象不详,请检查参数", param)
          }
          conversationId = $utils.getConversationId(friend_uid || group_id, friend_uid ? 'single' : 'group')
        }
      } else if (typeof param == 'string') {
        conversationId = param
      } else {
        throw new Error("会话对象不详,请检查参数", param)
      }
    }
    let conversationDatas = $state.conversation.dataList
    if (conversationId) {
      conversationDatas = conversationDatas.filter(i => i.id == conversationId)
      if (conversationDatas.length == 0) {
        // 本地没有没有就联网查找
        let conversationData = await this.loadMore(conversationId)
        if (conversationData) {
          conversationDatas = [conversationData]
        } else if (param.friend_uid) {
          //  普通用户会话,云端没有可以本地创建一个
          if (!param.user_info) {
            let res = await uniCloud.database()
              .collection('uni-id-users')
              .doc(param.friend_uid)
              .field('_id,nickname,avatar_file')
              .get()
            console.log('user_info', res)
            param.user_info = res.result.data[0]
            // console.log('param.user_info', param.user_info);
            if (!param.user_info) {
              throw new Error("用户查找失败")
            }
          }
          let conversationData = {
            "friend_uid": param.friend_uid,
            "unread_count": 0,
            "user_id": current_uid(),
            "id": conversationId,
            "user_info": param.user_info,
            "type": param.friend_uid ? 1 : 2,
            "msgList": [],
            "update_time": Date.now()
          }
99 100 101 102 103 104 105 106 107 108
          
          /**
           * 存在source字段的会话,表示此会话基于某个来源而被创建。
           * 比如:群聊会话,可能是从群聊列表中创建的,此时source字段会记录群聊的id
           * 用于在云端同步创建会话时的判断依据,比如:限制只能群成员和群管理员才能发起私聊时,确定指的是哪个群
           */
          if(param.source){
            conversationData.source = param.source
          }
          
DCloud_JSON's avatar
DCloud_JSON 已提交
109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272
          this.add(conversationData)
          conversationDatas.push(conversationData)
        } else {
          throw new Error("未找到此群会话")
        }
      }

      let conversationData = conversationDatas[0]
      // console.error('conversationData',conversationData,conversationData.group_member)
      // 指定获取某个id的群会话时,判断如果群会话的 群成员为空就从云端拉取
      if (conversationData.group_id && Object.keys(conversationData.group_member).length == 0 && !conversationData
        .leave) {
        uni.showLoading({
          title: '加载中',
          mask: true
        });
        await $group.loadMember(conversationData.group_id)
        uni.hideLoading()
      }

      // console.log('conversationData*-*--*-**-',conversationData)
      // #ifdef APP
      // if (!conversationData.isInit) {
      //   conversationData.msgManager = new MsgManager(conversationData)
      // }
      // #endif
      return conversationData
    } else {
      return conversationDatas
    }
  },
  async loadMore(conversation_id) {
    // console.log('loadMore-----','loadMore')
    if (!conversation_id) {
      // console.log('$state.conversation.loading',$state.conversation.loading)
      //上一次正在调用,下一次不能马上开始
      if ($state.conversation.loading) {
        // console.log('加载中')
        return []
      } else {
        $state.conversation.loading = true
      }
    }

    let conversationDatas = await this.get()
    let lastConversation = [...conversationDatas].sort((a, b) => a.update_time - b.update_time)[0]
    // console.log('conversationDatas.length',conversationDatas.length,lastConversation)
    let maxUpdateTime = lastConversation ? lastConversation.update_time : ''
    if (conversation_id) {
      // 已有会话id的情况下,不设置更新时间条件
      maxUpdateTime = ''
    }
    let res = {
      data: []
    }
    // console.log('maxUpdateTime', maxUpdateTime);
    try {
      res = await uniImCo.getConversationList({
        maxUpdateTime,
        limit: 30,
        conversation_id
      })
    } catch (e) {
      console.log(e)
      if (!conversation_id) {
        $state.conversation.loading = false
      }
    }

    if (res.data.length) {
      // console.log('getConversationList res', res, {
      // 	maxUpdateTime,
      // 	limit: 30,
      // 	conversation_id
      // });
      // console.log('res.data',JSON.parse(JSON.stringify(res.data)))
      res.data = this.add(res.data)
    }
    if (!conversation_id) {
      $state.conversation.loading = false
      $state.conversation.hasMore = (res.data.length == 30)
      return res.data
    } else {
      return res.data[0]
    }
  },
  add(datas) {
    if (!Array.isArray(datas)) {
      datas = [datas]
    }
    return datas.reduce((resList, item, index) => {
      // console.log('resList',resList);
      // 判断是否存在,再新增。
      let conversation_item = $state.conversation.dataList.find(conversation => conversation.id == item.id)
      if (conversation_item) {
        // 此会话已经存在,返回给add方法调用者,不重复插到$state.conversation.dataList
        resList.push(conversation_item)
        return resList
      }
      // console.log('新增会话', item)
      
      const conversation = new Conversation(item)
      // console.log('新增会话', conversation)
      const usersInfo = conversation.getUsersInfo()
      // 把会话相关的用户信息合并到 $users
      $users.merge(usersInfo)
      // 插入到会话列表
      $state.conversation.dataList.push(conversation)
      
      // 拿到响应式的conversation对象
      const _conversation = $state.conversation.dataList.find(i => i.id === conversation.id)
      // 设置字段为响应式
      let activeProperty = _conversation.activeProperty()
      Object.keys(activeProperty).forEach(key => {
        conversation[key] = computed(activeProperty[key])
      })
      
      resList.push(_conversation)
      // #ifdef H5
        // // 将会话数据存入indexDB
        // let data = JSON.parse(JSON.stringify(_conversation))
        // let request = $state.indexDB.transaction(['uni-im-convasation'], 'readwrite')
        //   .objectStore("uni-im-convasation")
        //   .put(data)
        // request.onsuccess = function(event) {
        //   // console.error('indexDB success',event);
        // }
        // request.onerror = function(event) {
        //   console.error('add convasation data to indexDB error',event);
        // };
      // #endif
      return resList
    }, [])
  },
  // 统计所有消息的未读数
  unreadCount() {
    let conversationDatas = $state.conversation.dataList
    const unreadCount = conversationDatas.reduce((sum, item, index, array) => {
      if (!item.hidden && !item.mute) {
        sum += item.unread_count
      }
      return sum
    }, 0)
    return unreadCount
  },
  remove(id) {
    let index = $state.conversation.dataList.findIndex(i => i.id == id)
    $state.conversation.dataList.splice(index, 1)
  },
  /**
   * 清空所有未读消息数
   */
  clearUnreadCount(){
    uniImCo.clearUnreadCount().then(res => {
      let conversationDatas = $state.conversation.dataList.filter(i => i.unread_count > 0)
      conversationDatas.forEach(i => {
        i.unread_count = 0
        // console.log('i',i)
      })
    }).catch(err => {
      console.error('clearUnreadCount err',err)
    })
  }
}