index.js 8.8 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 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
import $state from '@/uni_modules/uni-im/sdk/state/index.js';
import $methods from '@/uni_modules/uni-im/sdk/methods/index.js';
import appEvent from './appEvent';
import createObservable from './createObservable';
import toFriendlyTime from './toFriendlyTime';
import shortcutKey from './shortcut-key.js';
import parseHtml from './html-parser.js';
import markdownIt from './markdown-it.min.js';
import md5 from './md5.min.js'

export default {
  appEvent,
  createObservable,
  toFriendlyTime,
  shortcutKey,
  parseHtml,
  markdownIt,
  /**
   *深度合并多个对象的方法
   */
  deepAssign() {
    let len = arguments.length,
      target = arguments[0]
    if (!this.isPlainObject(target)) {
      target = {}
    }
    for (let i = 1; i < len; i++) {
      let source = arguments[i]
      if (this.isPlainObject(source)) {
        for (let s in source) {
          if (s === '__proto__' || target === source[s]) {
            continue
          }
          if (this.isPlainObject(source[s])) {
            target[s] = this.deepAssign(target[s], source[s])
          } else {
            target[s] = source[s]
          }
        }
      }
    }
    return target
  },
  /**
   * 替换文本中的url为套了html的a标签的方式
   */
  replaceUrlToLink(str) {
    // 找网址
    let urlPattern = /(https?:\/\/|www\.)[-A-Za-z0-9+&@#/%?=~_|!:,.;]+[-A-Za-z0-9+&@#/%=~_|]/g;
    return str.replace(urlPattern, function(match) {
      var href = match;
      if (match.indexOf("http") == -1) {
        //如果不带http://开头就带上
        href = "http://" + match;
      }
      return `<a class="link" target="_blank" href="${href}">${match}</a> `;
    });
  },
  /**
   *判断对象是否是一个纯粹的对象
   */
  isPlainObject(obj) {
    return typeof obj === 'object' && Object.prototype.toString.call(obj) === '[object Object]'
  },
  getScreenMetrics() {
    let metrics = {
      pageLeft: 0,
      pageTop: 0,
      pageWidth: $state.systemInfo.screenWidth,
      pageHeight: $state.systemInfo.screenHeight,
    };
    [
      'screenWidth',
      'screenHeight',
      'windowWidth',
      'windowHeight',
      'windowTop',
      'windowBottom',
      'statusBarHeight',
      'safeArea',
      'safeAreaInsets',
    ].forEach(name => { metrics[name] = $state.systemInfo[name] })
    try {
      uni.createSelectorQuery()
        .select('uni-page-body > #page, uni-page-body > .page')
        .boundingClientRect(data => {
          if (data) {
            metrics['pageLeft'] = data.left
            metrics['pageTop'] = data.top
            metrics['pageWidth'] = data.width
            metrics['pageHeight'] = data.height
          }
        })
        .exec()
    } catch (e) {
      console.error('调用 uni.createSelectorQuery 时机过早:', e)
    }
    return metrics
  },
  isMuteMsg(msg){
    return (
      // TODO:静默消息
      msg.is_mute === true
      ||
      // 加群消息
      msg.action === "join-group" 
      || 
      // 禁言通知
      msg.action === 'update-group-info-mute_all_members' 
    )
  },
  isReadableMsg(msg) {
    // 如果是扩展的消息类型,则由扩展程序决定结果
    let result = $methods.msgTypes.get(msg.type)?.isReadable()
    if (typeof result !== 'undefined') return result
    return msg.type !== 'revoke_msg' &&
      msg.action !== 'update-group-info-avatar_file' && 
DCloud_JSON's avatar
3.4.31  
DCloud_JSON 已提交
118
      msg.action !== 'set-group-member-ext-plugin-order-info' && 
DCloud_JSON's avatar
DCloud_JSON 已提交
119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141
      msg.type !== 'clear-conversation-unreadCount'
  },
  getMsgNote(_msg) {
    const msg = JSON.parse(JSON.stringify(_msg))
    const type = msg.type;
    let note = '[多媒体]'
    if (msg.is_revoke) {
      note = "消息已被撤回"
    } else if (msg.is_delete) {
      note = "消息已被删除"
    } else if (type === 'text') {
      note = msg.body.toString()
    } else if (type === 'userinfo-card') {
      note = `[${msg.body.name} 的名片]`
    } else {
      note = {
        "image": "[图片]",
        "sound": "[语音]",
        "video": "[视频]",
        "file": "[文件]",
        "location": "[位置]",
        "system": "[系统通知]",
        "code": "[代码]",
142 143
        "rich-text": "[富文本消息]",
        "revoke_msg": "[消息已被撤回]",
DCloud_JSON's avatar
3.4.31  
DCloud_JSON 已提交
144 145 146
        "history": "[转发的聊天记录]",
        "order": "[订单消息]",
        "pay-notify": "[支付成功通知]",
DCloud_JSON's avatar
DCloud_JSON 已提交
147 148 149 150 151 152 153 154 155 156 157 158 159 160 161
      } [type] || `[${type}]`
        
      if (type == "system") {
        note = {
          "join-group": "[新用户加入群聊]",
          "group-exit": "[退出群聊]",
          "group-expel": "[被踢出群聊]",
          "group-dissolved": "[此群聊已被解散]"
        } [msg.action] || '[系统消息]'
      } else if (type == "rich-text") {
        note = getRichTextText(msg.body)
        function getRichTextText(nodesList) {
          return getTextNode(nodesList)
          function getTextNode(nodesList) {
            let text = '';
DCloud_JSON's avatar
3.4.31  
DCloud_JSON 已提交
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
            try{
              nodesList.forEach(item => {
                if (item.type == "text") {
                  text += item.text.replace(/(\r\n|\n|\r)/gm, "")
                } else{
                  text += ({
                    'image': '[图片]',
                    'link': '[链接]',
                  })[item.type] || ''
                }
                if(item.name === 'img'){
                  text += ' [图片] '
                }
                if (item.attrs && item.attrs.class === 'nickname' && item.attrs.user_id) {
                  let userInfo = $state.users[item.attrs.user_id]
                  delete item.children
                  if(userInfo){
                    text += ` @${userInfo.nickname} `
                  }else if (item.attrs.user_id === "__ALL"){
                    text += '[@所有人]'
                  }
                  else{
                    text += "@" + $state.users.getNickname(item.attrs.user_id)
                    
                  }
DCloud_JSON's avatar
DCloud_JSON 已提交
187
                }
DCloud_JSON's avatar
3.4.31  
DCloud_JSON 已提交
188 189 190 191 192 193 194
                if (Array.isArray(item.children)) {
                  text += getTextNode(item.children)
                }
              })
            }catch(e){
              console.error('getRichTextText error', e)
            }
DCloud_JSON's avatar
DCloud_JSON 已提交
195 196 197 198 199 200
            // 替换换行为空格
            return text || '';
          }
        }
      }
    }
201 202 203 204 205 206
    // 去掉换行符
    note = note.replace(/(\r\n|\n|\r)/gm, "");
    // 改 &nbsp; &emsp; &ensp;等空格为普通空格
    note = note.replace(/&nbsp;|&emsp;|&ensp;/g, ' ')
    // 截取80个字符
    note = note.slice(0, 80).trim()
DCloud_JSON's avatar
DCloud_JSON 已提交
207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222
    return note
  },
  // 节流执行函数,用于控制频繁触发的事件。
  throttle(fn, delay) {
    fn.timer && clearTimeout(fn.timer);
    fn.timer = setTimeout(fn, delay);
  },
  async sleep(time) {
    return await new Promise((resolve, reject) => {
      setTimeout(() => {
        resolve()
      }, time)
    })
  },
  getConversationId(id, type = 'single') { //single,group
    if (type == 'single') {
DCloud_JSON's avatar
3.4.31  
DCloud_JSON 已提交
223
      let current_uid = $state.currentUser._id
DCloud_JSON's avatar
DCloud_JSON 已提交
224 225 226 227 228 229 230 231 232 233 234 235
      if (!current_uid) {
        console.error('错误current_uid不能为空', current_uid);
      }
      let param = [id, current_uid]
      return 'single_' + md5(param.sort().toString())
    } else {
      return 'group_' + id
    }
  },
  async getTempFileURL(fileid) {
    // console.log('getTempFileURL', fileid)
    // 如果不是fileid就直接返回。
DCloud_JSON's avatar
3.4.31  
DCloud_JSON 已提交
236 237 238 239 240 241 242
    if (
      !fileid || 
      fileid.indexOf('blob:') === 0 || 
      fileid.indexOf('data:image/png;base64,') === 0 || 
      fileid.substring(0, 8) != "cloud://" &&
      fileid.substring(0, 8) != "qiniu://"
    ) {
DCloud_JSON's avatar
DCloud_JSON 已提交
243 244
      return fileid
    }
DCloud_JSON's avatar
3.4.31  
DCloud_JSON 已提交
245 246 247 248 249 250 251 252
    try{
      let res = await uniCloud.getTempFileURL({
        fileList: [fileid]
      })
      return res.fileList[0].tempFileURL
    }catch(e){
      console.error('getTempFileURL error', e)
    }
253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273
  },
  openURL(href) {
  	// #ifdef APP-PLUS
  	plus.runtime.openURL(href);
    return
  	// #endif
    
  	// #ifdef H5
  	window.open(href)
    return
  	// #endif
    
    // 其他例如:鸿蒙或者小程序环境,直接复制链接
  	uni.setClipboardData({
  		data: href
  	});
  	uni.showModal({
  		content: '链接已复制到剪贴板,您可以粘贴到浏览器中打开',
  		showCancel: false
  	});
  },
274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299
  async reportError(error){
    // 上报错误
    const dbJQL = uniCloud.databaseForJQL()
    let content = {
      stack: error.stack,
      message: error.message,
      code: error.code
    }
    content = JSON.stringify(content)
    const content_md5 = md5(error.message)
    // 查询是否已经上报过
    let res = await dbJQL.collection('uni-im-error-log').where({
      content_md5
    }).get()
    if(res.data.length === 0){
      res = await dbJQL.collection('uni-im-error-log').add({
        content,
        content_md5
      })
    }else{
      res = await dbJQL.collection('uni-im-error-log').doc(res.data[0]._id).update({
        count: (res.data[0]?.count || 1) + 1
      })
    }
    console.warn('【bug已上报】uni-im-sdk error has reported',res,{error})
  }
DCloud_JSON's avatar
DCloud_JSON 已提交
300
}