├── .gitignore ├── App.vue ├── README.md ├── commen ├── commen.js └── tim │ ├── GenerateTestUserSig.js │ ├── tim.js │ └── user.js ├── components └── avator-group.vue ├── main.js ├── manifest.json ├── package-lock.json ├── package.json ├── pages.json ├── pages ├── index │ └── index.vue └── tim │ ├── HM-details │ └── HM-details.vue │ ├── HM-hand │ └── HM-hand.vue │ ├── record.vue │ └── room.vue ├── static ├── HM-chat │ └── css │ │ └── style.scss ├── img │ ├── emoji │ │ ├── 100.gif │ │ ├── 101.gif │ │ ├── 102.gif │ │ ├── 103.gif │ │ ├── 104.gif │ │ ├── 105.gif │ │ ├── 106.gif │ │ ├── 107.gif │ │ ├── 108.gif │ │ ├── 109.gif │ │ ├── 110.gif │ │ ├── 111.gif │ │ ├── 112.gif │ │ ├── 113.gif │ │ ├── 114.gif │ │ ├── 115.gif │ │ ├── 116.gif │ │ ├── 117.gif │ │ ├── 118.gif │ │ ├── 119.gif │ │ ├── 120.gif │ │ ├── 121.gif │ │ ├── 122.gif │ │ ├── 123.gif │ │ ├── 124.gif │ │ ├── 125.gif │ │ ├── 126.gif │ │ ├── 127.gif │ │ ├── 128.gif │ │ ├── 129.gif │ │ ├── 130.gif │ │ ├── 131.gif │ │ ├── 132.gif │ │ ├── 133.gif │ │ ├── 134.gif │ │ ├── 135.gif │ │ ├── 136.gif │ │ ├── 137.gif │ │ ├── 138.gif │ │ ├── 139.gif │ │ ├── 140.gif │ │ ├── 141.gif │ │ ├── 142.gif │ │ ├── 143.gif │ │ ├── 144.gif │ │ ├── 145.gif │ │ ├── 146.gif │ │ ├── 147.gif │ │ ├── 148.gif │ │ ├── 149.gif │ │ ├── 150.gif │ │ ├── 151.gif │ │ ├── 152.gif │ │ ├── 153.gif │ │ ├── 154.gif │ │ ├── 155.gif │ │ ├── 156.gif │ │ ├── 157.gif │ │ ├── 158.gif │ │ ├── 159.gif │ │ ├── 160.gif │ │ ├── 161.gif │ │ ├── 162.gif │ │ ├── 163.gif │ │ ├── 164.gif │ │ ├── 165.gif │ │ ├── 166.gif │ │ ├── 167.gif │ │ ├── 168.gif │ │ ├── 169.gif │ │ ├── 170.gif │ │ ├── 171.gif │ │ ├── 172.gif │ │ ├── 173.gif │ │ ├── 174.gif │ │ ├── 175.gif │ │ ├── 176.gif │ │ ├── 177.gif │ │ ├── 178.gif │ │ ├── 179.gif │ │ ├── 180.gif │ │ ├── 181.gif │ │ ├── 182.gif │ │ ├── 183.gif │ │ ├── 184.gif │ │ ├── 185.gif │ │ ├── 186.gif │ │ ├── 187.gif │ │ ├── 188.gif │ │ ├── 189.gif │ │ ├── 190.gif │ │ ├── 191.gif │ │ ├── 192.gif │ │ ├── 193.gif │ │ ├── 194.gif │ │ ├── 195.gif │ │ ├── 196.gif │ │ ├── 197.gif │ │ ├── 198.gif │ │ ├── 199.gif │ │ ├── 200.png │ │ ├── 201.png │ │ ├── 202.png │ │ ├── 203.png │ │ ├── 204.png │ │ ├── 205.png │ │ ├── 206.png │ │ ├── 207.png │ │ ├── 208.png │ │ ├── 209.png │ │ ├── 210.png │ │ ├── 211.png │ │ ├── 212.png │ │ ├── 213.png │ │ ├── 214.png │ │ ├── 215.png │ │ ├── 216.png │ │ ├── 217.png │ │ ├── 218.png │ │ └── 219.png │ ├── face.jpg │ ├── im │ │ └── face │ │ │ ├── face_1.jpg │ │ │ ├── face_10.jpg │ │ │ ├── face_11.jpg │ │ │ ├── face_12.jpg │ │ │ ├── face_13.jpg │ │ │ ├── face_14.jpg │ │ │ ├── face_15.jpg │ │ │ ├── face_2.jpg │ │ │ ├── face_3.jpg │ │ │ ├── face_4.jpg │ │ │ ├── face_5.jpg │ │ │ ├── face_6.jpg │ │ │ ├── face_7.jpg │ │ │ ├── face_8.jpg │ │ │ └── face_9.jpg │ ├── p10.jpg │ ├── q.jpg │ ├── red-envelope-chat.png │ └── red-envelope.png ├── logo.png └── voice │ ├── 1.mp3 │ └── 2.mp3 ├── store └── index.js └── uni.scss /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | dist/ 3 | bin/ 4 | build/ 5 | log/ 6 | logs/ 7 | target/ 8 | .gradle/ 9 | .settings/ 10 | .classpath 11 | .project 12 | .vertx/ 13 | .idea 14 | unpackage/ -------------------------------------------------------------------------------- /App.vue: -------------------------------------------------------------------------------- 1 | 46 | 47 | 50 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## TIM-uniapp 使用说明 2 | 3 | 简介:使用uniapp 对接腾讯云IM功能实现基于uniapp的多端即时通讯,一套代码开发ios/安卓/h5 的即时通讯功能 4 | 5 | #### 更新日志 6 | 7 | ### 1.1 版本 2020/3/25 8 | 9 | - 修复聊天页 --上拉加载更多动画 10 | 11 | ### 1.2 版本 2020/5/17 12 | 13 | - 修复聊天页 -- 初始化聊天记录是报错 14 | - 修复聊天页 -- 上滑到顶部加载历史聊天记录 定位动画 15 | - 会话列表页 -- 新增在登陆成后 且SDK Ready 后,将当前登录用户的头像,昵称提交到IM服务,借此优化了会话列表页的会话列表展示的性能 16 | 17 | ### 1.3 版本 2020/6/11 18 | 19 | - 修复聊天页 --修复APP中底部输入法弹起 挡住聊天输入框的BUG 20 | 21 | ### 1.4 版本 2020/6/18 22 | 23 | - 修复小程序会话列表页报错 24 | 25 | #### 运行环境 26 | 27 | - node 11.11.0 28 | - HbuilderX 29 | 30 | #### 启动项目 31 | 32 | ###### 方式一 33 | 34 | ``` 35 | git clone https://github.com/cometang/tim-uniapp.git 36 | 37 | npm install 38 | 39 | 使用HbuilderX打开后即可运行[支持 APP 小程序 h5] 40 | ``` 41 | 42 | ###### 方式二 43 | 44 | ``` 45 | 直接进入uni-app插件市场将项目导入到hbuilderx 中即可运行 46 | 地址:https://ext.dcloud.net.cn/plugin?id=1421 47 | ``` 48 | 49 | #### 开发注意事项 50 | 51 | ##### 1.替换腾讯云SDKAPPID以及SECRETKEY 52 | 53 | ``` 54 | 将commen/tim/tim.js 中 SDKAPPID以及 SECRETKEY 替换为自己的服务相关账户 55 | 自带账号只是作为体验使用。 56 | ``` 57 | 58 | ![image](https://s1.ax1x.com/2020/03/25/8XnsYQ.png) 59 | 60 | 61 | 62 | ##### 2.修改基础用户数据 63 | 64 | ``` 65 | 将 commen/tim/user.js 中的用户数据替换为自己在腾讯云IM控制台生成的用户信息及用户秘钥 66 | 控制台手动生成用户秘钥注意使用 “userId” 字段生成。 67 | 正式开发有后端可以直接通过后端接口直接生成userSign,走接口就不需要手动在控制台生成用户秘钥。 68 | ``` 69 | 70 | ![image](https://s1.ax1x.com/2020/03/25/8XnrFg.png) 71 | 72 | ##### 3.注意TIM的动态监听--数据动态更新问题 73 | 74 | ``` 75 | App.vue 中写入了一些常用的监听事件,如有新的消息,会话列表动态更新等,其他的更多的监听事件可以按按需接入。 76 | ``` 77 | 78 | #### 未完成功能 79 | 80 | - 发送文件语音图片(通过发送TIM的自定义消息可以解决,多端开发时不建议使用cos) 81 | - 黑名单 (TIM支持黑名单功能,TIM有现成的api) 82 | - 添加好友 (好友相关的功能只能做到自己的数据库里面,TIM是不支持好友关系建立的) 83 | - 群组聊天(群聊功能和私聊实现非常类似,将消息类型由“C2C”更改为“GROUP”即可) 84 | 85 | #### 点赞支持一下 86 | 87 | - 项目地址 https://github.com/cometang/tim-uniapp.git 点赞支持一下吧 88 | - uni-app插件市场地址:https://ext.dcloud.net.cn/plugin?id=1421 89 | 90 | #### 致谢 91 | 92 | 聊天详情页使用 [回梦無痕](https://ext.dcloud.net.cn/publisher?id=5536) 的《聊天模板》https://ext.dcloud.net.cn/plugin?id=324 93 | 94 | -------------------------------------------------------------------------------- /commen/commen.js: -------------------------------------------------------------------------------- 1 | const commen = {} 2 | 3 | 4 | commen.emojiList = [ 5 | [{ 6 | "url": "100.gif", 7 | alt: "[微笑]" 8 | }, { 9 | "url": "101.gif", 10 | alt: "[伤心]" 11 | }, { 12 | "url": "102.gif", 13 | alt: "[美女]" 14 | }, { 15 | "url": "103.gif", 16 | alt: "[发呆]" 17 | }, { 18 | "url": "104.gif", 19 | alt: "[墨镜]" 20 | }, { 21 | "url": "105.gif", 22 | alt: "[哭]" 23 | }, { 24 | "url": "106.gif", 25 | alt: "[羞]" 26 | }, { 27 | "url": "107.gif", 28 | alt: "[哑]" 29 | }, { 30 | "url": "108.gif", 31 | alt: "[睡]" 32 | }, { 33 | "url": "109.gif", 34 | alt: "[哭]" 35 | }, { 36 | "url": "110.gif", 37 | alt: "[囧]" 38 | }, { 39 | "url": "111.gif", 40 | alt: "[怒]" 41 | }, { 42 | "url": "112.gif", 43 | alt: "[调皮]" 44 | }, { 45 | "url": "113.gif", 46 | alt: "[笑]" 47 | }, { 48 | "url": "114.gif", 49 | alt: "[惊讶]" 50 | }, { 51 | "url": "115.gif", 52 | alt: "[难过]" 53 | }, { 54 | "url": "116.gif", 55 | alt: "[酷]" 56 | }, { 57 | "url": "117.gif", 58 | alt: "[汗]" 59 | }, { 60 | "url": "118.gif", 61 | alt: "[抓狂]" 62 | }, { 63 | "url": "119.gif", 64 | alt: "[吐]" 65 | }, { 66 | "url": "120.gif", 67 | alt: "[笑]" 68 | }, { 69 | "url": "121.gif", 70 | alt: "[快乐]" 71 | }, { 72 | "url": "122.gif", 73 | alt: "[奇]" 74 | }, { 75 | "url": "123.gif", 76 | alt: "[傲]" 77 | }], 78 | [{ 79 | "url": "124.gif", 80 | alt: "[饿]" 81 | }, { 82 | "url": "125.gif", 83 | alt: "[累]" 84 | }, { 85 | "url": "126.gif", 86 | alt: "[吓]" 87 | }, { 88 | "url": "127.gif", 89 | alt: "[汗]" 90 | }, { 91 | "url": "128.gif", 92 | alt: "[高兴]" 93 | }, { 94 | "url": "129.gif", 95 | alt: "[闲]" 96 | }, { 97 | "url": "130.gif", 98 | alt: "[努力]" 99 | }, { 100 | "url": "131.gif", 101 | alt: "[骂]" 102 | }, { 103 | "url": "132.gif", 104 | alt: "[疑问]" 105 | }, { 106 | "url": "133.gif", 107 | alt: "[秘密]" 108 | }, { 109 | "url": "134.gif", 110 | alt: "[乱]" 111 | }, { 112 | "url": "135.gif", 113 | alt: "[疯]" 114 | }, { 115 | "url": "136.gif", 116 | alt: "[哀]" 117 | }, { 118 | "url": "137.gif", 119 | alt: "[鬼]" 120 | }, { 121 | "url": "138.gif", 122 | alt: "[打击]" 123 | }, { 124 | "url": "139.gif", 125 | alt: "[bye]" 126 | }, { 127 | "url": "140.gif", 128 | alt: "[汗]" 129 | }, { 130 | "url": "141.gif", 131 | alt: "[抠]" 132 | }, { 133 | "url": "142.gif", 134 | alt: "[鼓掌]" 135 | }, { 136 | "url": "143.gif", 137 | alt: "[糟糕]" 138 | }, { 139 | "url": "144.gif", 140 | alt: "[恶搞]" 141 | }, { 142 | "url": "145.gif", 143 | alt: "[什么]" 144 | }, { 145 | "url": "146.gif", 146 | alt: "[什么]" 147 | }, { 148 | "url": "147.gif", 149 | alt: "[累]" 150 | }], 151 | [{ 152 | "url": "148.gif", 153 | alt: "[看]" 154 | }, { 155 | "url": "149.gif", 156 | alt: "[难过]" 157 | }, { 158 | "url": "150.gif", 159 | alt: "[难过]" 160 | }, { 161 | "url": "151.gif", 162 | alt: "[坏]" 163 | }, { 164 | "url": "152.gif", 165 | alt: "[亲]" 166 | }, { 167 | "url": "153.gif", 168 | alt: "[吓]" 169 | }, { 170 | "url": "154.gif", 171 | alt: "[可怜]" 172 | }, { 173 | "url": "155.gif", 174 | alt: "[刀]" 175 | }, { 176 | "url": "156.gif", 177 | alt: "[水果]" 178 | }, { 179 | "url": "157.gif", 180 | alt: "[酒]" 181 | }, { 182 | "url": "158.gif", 183 | alt: "[篮球]" 184 | }, { 185 | "url": "159.gif", 186 | alt: "[乒乓]" 187 | }, { 188 | "url": "160.gif", 189 | alt: "[咖啡]" 190 | }, { 191 | "url": "161.gif", 192 | alt: "[美食]" 193 | }, { 194 | "url": "162.gif", 195 | alt: "[动物]" 196 | }, { 197 | "url": "163.gif", 198 | alt: "[鲜花]" 199 | }, { 200 | "url": "164.gif", 201 | alt: "[枯]" 202 | }, { 203 | "url": "165.gif", 204 | alt: "[唇]" 205 | }, { 206 | "url": "166.gif", 207 | alt: "[爱]" 208 | }, { 209 | "url": "167.gif", 210 | alt: "[分手]" 211 | }, { 212 | "url": "168.gif", 213 | alt: "[生日]" 214 | }, { 215 | "url": "169.gif", 216 | alt: "[电]" 217 | }, { 218 | "url": "170.gif", 219 | alt: "[炸弹]" 220 | }, { 221 | "url": "171.gif", 222 | alt: "[刀子]" 223 | }], 224 | [{ 225 | "url": "172.gif", 226 | alt: "[足球]" 227 | }, { 228 | "url": "173.gif", 229 | alt: "[瓢虫]" 230 | }, { 231 | "url": "174.gif", 232 | alt: "[翔]" 233 | }, { 234 | "url": "175.gif", 235 | alt: "[月亮]" 236 | }, { 237 | "url": "176.gif", 238 | alt: "[太阳]" 239 | }, { 240 | "url": "177.gif", 241 | alt: "[礼物]" 242 | }, { 243 | "url": "178.gif", 244 | alt: "[抱抱]" 245 | }, { 246 | "url": "179.gif", 247 | alt: "[拇指]" 248 | }, { 249 | "url": "180.gif", 250 | alt: "[贬低]" 251 | }, { 252 | "url": "181.gif", 253 | alt: "[握手]" 254 | }, { 255 | "url": "182.gif", 256 | alt: "[剪刀手]" 257 | }, { 258 | "url": "183.gif", 259 | alt: "[抱拳]" 260 | }, { 261 | "url": "184.gif", 262 | alt: "[勾引]" 263 | }, { 264 | "url": "185.gif", 265 | alt: "[拳头]" 266 | }, { 267 | "url": "186.gif", 268 | alt: "[小拇指]" 269 | }, { 270 | "url": "187.gif", 271 | alt: "[拇指八]" 272 | }, { 273 | "url": "188.gif", 274 | alt: "[食指]" 275 | }, { 276 | "url": "189.gif", 277 | alt: "[ok]" 278 | }, { 279 | "url": "190.gif", 280 | alt: "[情侣]" 281 | }, { 282 | "url": "191.gif", 283 | alt: "[爱心]" 284 | }, { 285 | "url": "192.gif", 286 | alt: "[蹦哒]" 287 | }, { 288 | "url": "193.gif", 289 | alt: "[颤抖]" 290 | }, { 291 | "url": "194.gif", 292 | alt: "[怄气]" 293 | }, { 294 | "url": "195.gif", 295 | alt: "[跳舞]" 296 | }], 297 | [{ 298 | "url": "196.gif", 299 | alt: "[发呆]" 300 | }, { 301 | "url": "197.gif", 302 | alt: "[背着]" 303 | }, { 304 | "url": "198.gif", 305 | alt: "[伸手]" 306 | }, { 307 | "url": "199.gif", 308 | alt: "[耍帅]" 309 | }, { 310 | "url": "200.png", 311 | alt: "[微笑]" 312 | }, { 313 | "url": "201.png", 314 | alt: "[生病]" 315 | }, { 316 | "url": "202.png", 317 | alt: "[哭泣]" 318 | }, { 319 | "url": "203.png", 320 | alt: "[吐舌]" 321 | }, { 322 | "url": "204.png", 323 | alt: "[迷糊]" 324 | }, { 325 | "url": "205.png", 326 | alt: "[瞪眼]" 327 | }, { 328 | "url": "206.png", 329 | alt: "[恐怖]" 330 | }, { 331 | "url": "207.png", 332 | alt: "[忧愁]" 333 | }, { 334 | "url": "208.png", 335 | alt: "[眨眉]" 336 | }, { 337 | "url": "209.png", 338 | alt: "[闭眼]" 339 | }, { 340 | "url": "210.png", 341 | alt: "[鄙视]" 342 | }, { 343 | "url": "211.png", 344 | alt: "[阴暗]" 345 | }, { 346 | "url": "212.png", 347 | alt: "[小鬼]" 348 | }, { 349 | "url": "213.png", 350 | alt: "[礼物]" 351 | }, { 352 | "url": "214.png", 353 | alt: "[拜佛]" 354 | }, { 355 | "url": "215.png", 356 | alt: "[力量]" 357 | }, { 358 | "url": "216.png", 359 | alt: "[金钱]" 360 | }, { 361 | "url": "217.png", 362 | alt: "[蛋糕]" 363 | }, { 364 | "url": "218.png", 365 | alt: "[彩带]" 366 | }, { 367 | "url": "219.png", 368 | alt: "[礼物]" 369 | }, ] 370 | ] 371 | 372 | /**@dateTimeFliter 转换格林日期时间格式为常用日期格式 373 | * @time[必填] Date 格林日期格式 374 | * @part[可选,默认:0] Number 选择返回日期时间部分 列:0:返回所有 1:只返回日期 2:只返回时间 375 | * @dateComplete[可选,默认:true] Boolean 日期位数不足是否添0补齐:true:补齐,false:不补齐 376 | * @timeComplete[可选,默认:true] Boolean 时间位数不足是否添0补齐:true:补齐,false:不补齐 377 | * @dateConnector[可选,默认:-] String 年月日连接符 例: - : / 378 | * @timeConnector[可选,默认::] String 时间连接符 例: - : / 379 | * @hour12[可选,默认:false] Boolean 是否返回12小时制时间 例: true:返回12小时制时间 false:返回24小时制时间 380 | * @return '2019-11-25 15:05:54' String 返回示例 381 | * **/ 382 | commen.dateTimeFliter = function(time, part = 0, dateComplete = true, timeComplete = true, dateConnector = '-', 383 | timeConnector = ':', hour12 = false) { 384 | let year = time.getFullYear() 385 | let month = time.getMonth() + 1 386 | let day = time.getDate() 387 | let hour = time.getHours() 388 | let minute = time.getMinutes() 389 | let second = time.getSeconds() 390 | let dateStr = '' 391 | let timeStr = '' 392 | //转换日期 393 | if (dateComplete) { //添0补齐 394 | if (month < 10) { 395 | month = '0' + month 396 | } 397 | if (day < 10) { 398 | day = '0' + day 399 | } 400 | } 401 | dateStr = year + dateConnector + month + dateConnector + day 402 | //转换时间 403 | //修改小时制 404 | if (hour12) { 405 | if (hour > 12) { 406 | hour = hour - 12 407 | if (timeComplete) { 408 | if (hour < 10) { 409 | hour = '下午 ' + '0' + hour 410 | } else { 411 | hour = '下午 ' + hour 412 | } 413 | } 414 | } else { 415 | if (timeComplete) { 416 | if (hour < 10) { 417 | hour = '上午 ' + '0' + hour 418 | } else { 419 | hour = '上午 ' + hour 420 | } 421 | } 422 | } 423 | } 424 | //判断分钟与秒 425 | if (timeComplete) { //添0补齐 426 | if (minute < 10) { 427 | minute = '0' + minute 428 | } 429 | if (second < 10) { 430 | second = '0' + second 431 | } 432 | } 433 | timeStr = hour + timeConnector + minute + timeConnector + second 434 | //合成输出值 435 | if (part == 0) { 436 | return dateStr + ' ' + timeStr 437 | } else if (part == 1) { 438 | return dateStr 439 | } else if (part == 2) { 440 | return timeStr 441 | } 442 | return '传参有误' 443 | } 444 | 445 | 446 | 447 | export default commen 448 | -------------------------------------------------------------------------------- /commen/tim/GenerateTestUserSig.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable require-jsdoc */ 2 | /* 3 | * Module: GenerateTestUserSig 4 | * 5 | * Function: 用于生成测试用的 UserSig,UserSig 是腾讯云为其云服务设计的一种安全保护签名。 6 | * 其计算方法是对 SDKAppID、UserID 和 EXPIRETIME 进行加密,加密算法为 HMAC-SHA256。 7 | * 8 | * Attention: 请不要将如下代码发布到您的线上正式版本的 App 中,原因如下: 9 | * 10 | * 本文件中的代码虽然能够正确计算出 UserSig,但仅适合快速调通 SDK 的基本功能,不适合线上产品, 11 | * 这是因为客户端代码中的 SECRETKEY 很容易被反编译逆向破解,尤其是 Web 端的代码被破解的难度几乎为零。 12 | * 一旦您的密钥泄露,攻击者就可以计算出正确的 UserSig 来盗用您的腾讯云流量。 13 | * 14 | * 正确的做法是将 UserSig 的计算代码和加密密钥放在您的业务服务器上,然后由 App 按需向您的服务器获取实时算出的 UserSig。 15 | * 由于破解服务器的成本要高于破解客户端 App,所以服务器计算的方案能够更好地保护您的加密密钥。 16 | * 17 | * Reference:https://cloud.tencent.com/document/product/647/17275#Server 18 | */ 19 | function genTestUserSig(userID) { 20 | /** 21 | * 腾讯云 SDKAppId,需要替换为您自己账号下的 SDKAppId。 22 | * 23 | * 进入腾讯云实时音视频[控制台](https://console.cloud.tencent.com/rav ) 创建应用,即可看到 SDKAppId, 24 | * 它是腾讯云用于区分客户的唯一标识。 25 | */ 26 | const SDKAPPID = 0; 27 | 28 | /** 29 | * 签名过期时间,建议不要设置的过短 30 | *

31 | * 时间单位:秒 32 | * 默认时间:7 x 24 x 60 x 60 = 604800 = 7 天 33 | */ 34 | const EXPIRETIME = 604800; 35 | 36 | /** 37 | * 计算签名用的加密密钥,获取步骤如下: 38 | * 39 | * step1. 进入腾讯云实时音视频[控制台](https://console.cloud.tencent.com/rav ),如果还没有应用就创建一个, 40 | * step2. 单击“应用配置”进入基础配置页面,并进一步找到“帐号体系集成”部分。 41 | * step3. 点击“查看密钥”按钮,就可以看到计算 UserSig 使用的加密的密钥了,请将其拷贝并复制到如下的变量中 42 | * 43 | * 注意:该方案仅适用于调试Demo,正式上线前请将 UserSig 计算代码和密钥迁移到您的后台服务器上,以避免加密密钥泄露导致的流量盗用。 44 | * 文档:https://cloud.tencent.com/document/product/647/17275#Server 45 | */ 46 | const SECRETKEY = ''; 47 | 48 | // a soft reminder to guide developer to configure sdkAppId/secretKey 49 | if (SDKAPPID === '' || SECRETKEY === '') { 50 | alert( 51 | '请先配置好您的账号信息: SDKAPPID 及 SECRETKEY ' + 52 | '\r\n\r\nPlease configure your SDKAPPID/SECRETKEY in js/debug/GenerateTestUserSig.js' 53 | ); 54 | } 55 | const generator = new LibGenerateTestUserSig(SDKAPPID, SECRETKEY, EXPIRETIME); 56 | const userSig = generator.genTestUserSig(userID); 57 | return { 58 | sdkAppId: SDKAPPID, 59 | userSig: userSig 60 | }; 61 | } 62 | -------------------------------------------------------------------------------- /commen/tim/tim.js: -------------------------------------------------------------------------------- 1 | import TIM from 'tim-js-sdk'; 2 | // import COS from "cos-js-sdk-v5"; 3 | 4 | 5 | const options = { 6 | SDKAppID: 1400277699 // 接入时需要将0替换为您的即时通信应用的 SDKAppID 7 | }; 8 | // 创建 SDK 实例,TIM.create() 方法对于同一个 SDKAppID 只会返回同一份实例 9 | const tim = TIM.create(options); // SDK 实例通常用 tim 表示 10 | const TIMData = TIM 11 | // 注册 COS SDK 插件 12 | // tim.registerPlugin({'cos-js-sdk': COS}); 13 | 14 | 15 | 16 | /* eslint-disable require-jsdoc */ 17 | function genTestUserSig(userID) { 18 | const SDKAPPID = 1400277699; 19 | const EXPIRETIME = 604800; 20 | const SECRETKEY = '281d8830bb13fa0923bc5c34cc13690faac214906fd5342782daba5a3e645f3c'; 21 | 22 | if (SDKAPPID === '' || SECRETKEY === '') { 23 | alert( 24 | '请先配置好您的账号信息: SDKAPPID 及 SECRETKEY ' + 25 | '\r\n\r\nPlease configure your SDKAPPID/SECRETKEY in js/debug/GenerateTestUserSig.js' 26 | ); 27 | } 28 | const generator = new LibGenerateTestUserSig(SDKAPPID, SECRETKEY, EXPIRETIME); 29 | const userSig = generator.genTestUserSig(userID); 30 | return { 31 | sdkAppId: SDKAPPID, 32 | userSig: userSig 33 | }; 34 | } 35 | 36 | export default { 37 | tim, 38 | TIMData, 39 | genTestUserSig 40 | } -------------------------------------------------------------------------------- /commen/tim/user.js: -------------------------------------------------------------------------------- 1 | const userList = [{ 2 | user: 'tsj', 3 | userId: '1', 4 | userSig: 'eJyrVgrxCdYrSy1SslIy0jNQ0gHzM1NS80oy0zLBwoZQweKU7MSCgswUJStDEwMDI3NzM0tLiExqRUFmUSpQ3NTU1MjAwAAiWpKZCxazMLYwMbI0NYGakpkONDPPI0Y-OcctwjIp0izIsLg4Mdjb28e9ytu02NUl3zsnNNwis7I0u7TULbfCwFapFgBCAjBt', 5 | img:'https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=1735490596,2760195857&fm=26&gp=0.jpg' 6 | }, 7 | { 8 | user: 'user1', 9 | userId: '2', 10 | img:'https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=2262632647,543198910&fm=26&gp=0.jpg', 11 | userSig: 'eJyrVgrxCdYrSy1SslIy0jNQ0gHzM1NS80oy0zIhwlDB4pTsxIKCzBQlK0MTAwMjc3MzS0uITGpFQWZRKlDc1NTUyMDAACJakpkLFrMwtjAxsjCCqi3OTAeaGZUe6GnglGVh5uQZUWbo4ucW7BulbeiZE2GZ6FtkkuHvb64dklfibu5qUmyrVAsA7bAuSQ__' 12 | }, 13 | { 14 | user: 'user2', 15 | userId: '3', 16 | img:'https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=366135374,1364401596&fm=26&gp=0.jpg', 17 | userSig: 'eJyrVgrxCdYrSy1SslIy0jNQ0gHzM1NS80oy0zLBwsZQweKU7MSCgswUJStDEwMDI3NzM0tLiExqRUFmUSpQ3NTU1MjAwAAiWpKZCxazMDEwMjWwNISakpkONDM5y8e-2M*syqfcIqPMUTvb1SnMNcs4yDDRpTik2DWyzL200D05oDzVsyjfVqkWABWxMCc_' 18 | }, 19 | { 20 | user: 'user3', 21 | userId: '4', 22 | img:'https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=275868592,2250122918&fm=26&gp=0.jpg', 23 | userSig: 'eJyrVgrxCdYrSy1SslIy0jNQ0gHzM1NS80oy0zLBwiZQweKU7MSCgswUJStDEwMDI3NzM0tLiExqRUFmUSpQ3NTU1MjAwAAiWpKZCxazMDEwMjUyg4oWZ6YDzQzzNvYsD3dPz0qP9Ekqci8xM832LXNJ90wxDkwKywsM8jbPjsjRdoosrIy0VaoFABNEL9E_' 24 | }, 25 | { 26 | user: 'user4', 27 | userId: '5', 28 | img:'https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=2473035870,2692619587&fm=26&gp=0.jpg', 29 | userSig: 'eJwtzMEKgkAUheF3mXXIdfTqjNDCCgMTCnLTcmBm5BbmYGZi9O6Jujzfgf-LyuLq9aZlCeMesM28SZtnR5ZmxhVf*qGcI80SPwTgcRxJuTxmcNSayRGRA8CiHdWziRA4*gGuFaqmZncZpLDv-FzCfd9-MmcOQp2a0d4iJY9Z4dd5M*6CRqTVlv3*F5svpQ__' 30 | }, 31 | { 32 | user: 'user5', 33 | userId: '6', 34 | img:'https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=3293099503,606929711&fm=26&gp=0.jpg', 35 | userSig: 'eJyrVgrxCdYrSy1SslIy0jNQ0gHzM1NS80oy0zLBwmZQweKU7MSCgswUJStDEwMDI3NzM0tLiExqRUFmUSpQ3NTU1MjAwAAiWpKZCxazMDEwMjU0NYSakpkONNPSx7Sw0DOlyKcqOTMtwMw42dxS2w9oZJJbVUBigUW4u5OXc3J*eUWYUbatUi0AAvUvMA__' 36 | }, 37 | { 38 | user: 'user6', 39 | userId: '7', 40 | img:'https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=1643922863,2228588017&fm=26&gp=0.jpg', 41 | userSig: 'eJwtzD0PgjAUheH-0tmQ2xtKKYmDAxgjGzLIprSQm-rRIBJT43*XFMbznOT9slNZRZMZWMYwArYJm7R5jNRRYLniS9uLc6RZxmMAlDJRannMx9FgZhdCIAAsOtI9WBoDCp6ItUL93OTnqa-8Uzv*vub21lq-zw*l7xtVpDV6lNjtsNZNcmy37PcHIzwvpA__' 42 | }, 43 | { 44 | user: 'user7', 45 | userId: '8', 46 | img:'https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=1179876196,102524513&fm=26&gp=0.jpg', 47 | userSig: 'eJwtzF0LwiAYhuH-4nGMd07TDTrpYBBGMCoWnQW69dKXbCJi9N8bbofP9cD9Jaf9MfNmIBWhGZBV2qjN22GHieWCo37crEVNqpwBUCHWZTk-JlgczOSccwoAszp8JZMMKM*lWCrYT81r8wySFWrbqbqt78Xl48c22hgRNHNeWH1W4rDjoZEb8vsDGUUv4A__' 48 | }, 49 | { 50 | user: 'user8', 51 | userId: '9', 52 | img:'https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=3206878631,547916318&fm=26&gp=0.jpg', 53 | userSig: 'eJyrVgrxCdYrSy1SslIy0jNQ0gHzM1NS80oy0zLBwpZQweKU7MSCgswUJStDEwMDI3NzM0tLiExqRUFmUSpQ3NTU1MjAwAAiWpKZCxazMDEwMjU2M4GakpkONLPILNDQ3CLYtCQ3NCq50qDS3aXcySdGPyuyOCg9PMqowNPHuaCgoCrHIrWw3FapFgA*NjBr' 54 | }, 55 | { 56 | user: 'user9', 57 | userId: '10', 58 | img:'https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=1779444511,689185070&fm=26&gp=0.jpg', 59 | userSig: 'eJyrVgrxCdYrSy1SslIy0jNQ0gHzM1NS80oy0zLBwoYw0eKU7MSCgswUJStDEwMDI3NzM0tLiExqRUFmUSpQ3NTU1MjAwAAiWpKZCxazMDEwMjUytoCakpkONNQv0ihbOzPPI9Q-LTcy39EpszI1PNI9wihGvzzI3z-FsdjLuSg-oiK8stQr0lapFgBoUDC1' 60 | }, 61 | ] 62 | 63 | 64 | 65 | 66 | export default userList 67 | -------------------------------------------------------------------------------- /components/avator-group.vue: -------------------------------------------------------------------------------- 1 | 16 | 17 | 27 | 28 | -------------------------------------------------------------------------------- /main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import App from './App' 3 | import tim from './commen/tim/tim.js' 4 | import commen from './commen/commen.js' 5 | import TIM from 'tim-js-sdk' 6 | import store from './store/index.js' 7 | 8 | 9 | Vue.config.productionTip = false 10 | Vue.prototype.tim = tim.tim //tim sdk 引入后生成的tim服务 11 | Vue.prototype.$TIM = TIM //tim 的状态/事件 常量 12 | Vue.prototype.$store = store 13 | Vue.prototype.$commen = commen 14 | 15 | App.mpType = 'app' 16 | 17 | const app = new Vue({ 18 | ...App 19 | }) 20 | app.$mount() 21 | -------------------------------------------------------------------------------- /manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name" : "tim-uniapp", 3 | "appid" : "__UNI__F11EA97", 4 | "description": "", 5 | "versionName": "1.0.0", 6 | "versionCode": "100", 7 | "transformPx": false, 8 | /* 5+App特有相关 */ 9 | "app-plus": { 10 | "usingComponents": true, 11 | "nvueCompiler": "uni-app", 12 | "splashscreen": { 13 | "alwaysShowBeforeRender": true, 14 | "waiting": true, 15 | "autoclose": true, 16 | "delay": 0 17 | }, 18 | /* 模块配置 */ 19 | "modules": { 20 | 21 | }, 22 | /* 应用发布信息 */ 23 | "distribute": { 24 | /* android打包配置 */ 25 | "android": { 26 | "permissions": ["", 27 | "", 28 | "", 29 | "", 30 | "", 31 | "", 32 | "", 33 | "", 34 | "", 35 | "", 36 | "", 37 | "", 38 | "", 39 | "", 40 | "", 41 | "", 42 | "", 43 | "", 44 | "", 45 | "", 46 | "", 47 | "" 48 | ] 49 | }, 50 | /* ios打包配置 */ 51 | "ios": { 52 | 53 | }, 54 | /* SDK配置 */ 55 | "sdkConfigs": { 56 | 57 | } 58 | } 59 | }, 60 | /* 快应用特有相关 */ 61 | "quickapp": { 62 | 63 | }, 64 | /* 小程序特有相关 */ 65 | "mp-weixin": { 66 | "appid": "", 67 | "setting": { 68 | "urlCheck": false 69 | }, 70 | "usingComponents": true 71 | }, 72 | "mp-alipay" : { 73 | "usingComponents" : true 74 | }, 75 | "mp-baidu" : { 76 | "usingComponents" : true 77 | }, 78 | "mp-toutiao" : { 79 | "usingComponents" : true 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "tim-uniapp", 3 | "version": "1.0.0", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "cos-js-sdk-v5": { 8 | "version": "0.5.20", 9 | "resolved": "https://registry.npm.taobao.org/cos-js-sdk-v5/download/cos-js-sdk-v5-0.5.20.tgz?cache=0&sync_timestamp=1568174173125&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcos-js-sdk-v5%2Fdownload%2Fcos-js-sdk-v5-0.5.20.tgz", 10 | "integrity": "sha1-KhtEZQzYJ6EIvu1aDva2B96rQwc=", 11 | "requires": { 12 | "xmldom": "^0.1.27" 13 | } 14 | }, 15 | "tim-js-sdk": { 16 | "version": "2.1.4", 17 | "resolved": "https://registry.npm.taobao.org/tim-js-sdk/download/tim-js-sdk-2.1.4.tgz", 18 | "integrity": "sha1-AWBevOnLC9zxE5i+YfnsP9PtCgw=" 19 | }, 20 | "xmldom": { 21 | "version": "0.1.27", 22 | "resolved": "http://registry.npm.taobao.org/xmldom/download/xmldom-0.1.27.tgz", 23 | "integrity": "sha1-1QH5ezvbQDr4757MIFcxh6rawOk=" 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "tim-uniapp", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "main.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC", 12 | "dependencies": { 13 | "cos-js-sdk-v5": "^0.5.20", 14 | "tim-js-sdk": "^2.1.4" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /pages.json: -------------------------------------------------------------------------------- 1 | { 2 | "pages": [ //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages 3 | { 4 | "path": "pages/index/index", 5 | "style": { 6 | "navigationBarTitleText": "uni-app" 7 | } 8 | }, 9 | { 10 | "path": "pages/tim/record", 11 | "style": { 12 | "navigationBarTitleText": "uni-app" 13 | } 14 | }, 15 | { 16 | "path": "pages/tim/room", 17 | "style": { 18 | "navigationBarTitleText": "聊天室", 19 | "app-plus": { //修复聊天页 app端输入法上顶问题 20 | "softinputMode": "adjustResize" 21 | } 22 | } 23 | } 24 | ], 25 | "globalStyle": { 26 | "navigationBarTextStyle": "black", 27 | "navigationBarTitleText": "uni-app", 28 | "navigationBarBackgroundColor": "#F8F8F8", 29 | "backgroundColor": "#F8F8F8" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /pages/index/index.vue: -------------------------------------------------------------------------------- 1 | 20 | 21 | 93 | 94 | 115 | -------------------------------------------------------------------------------- /pages/tim/HM-details/HM-details.vue: -------------------------------------------------------------------------------- 1 | 47 | 48 | 82 | 83 | 188 | -------------------------------------------------------------------------------- /pages/tim/HM-hand/HM-hand.vue: -------------------------------------------------------------------------------- 1 | 65 | 66 | 117 | 118 | 235 | -------------------------------------------------------------------------------- /pages/tim/record.vue: -------------------------------------------------------------------------------- 1 | 63 | 64 | 220 | 221 | 391 | -------------------------------------------------------------------------------- /pages/tim/room.vue: -------------------------------------------------------------------------------- 1 |