Commit ef808ca3 ef808ca31dd105637fd549812f6ac2f6fd74822c by yangjun@hikoon.cn

更新

1 parent 2c6e46e5
...@@ -9,10 +9,12 @@ ...@@ -9,10 +9,12 @@
9 "lint": "node node_modules/@vue/cli-service/bin/vue-cli-service.js lint src --ext .vue,.js --fix" 9 "lint": "node node_modules/@vue/cli-service/bin/vue-cli-service.js lint src --ext .vue,.js --fix"
10 }, 10 },
11 "dependencies": { 11 "dependencies": {
12 "add": "^2.0.6",
12 "axios": "^0.21.0", 13 "axios": "^0.21.0",
13 "core-js": "^2.6.11", 14 "core-js": "^2.6.11",
14 "cos-js-sdk-v5": "^0.5.22", 15 "cos-js-sdk-v5": "^0.5.22",
15 "element-ui": "^2.13.0", 16 "element-ui": "^2.13.0",
17 "loadsh": "^0.0.4",
16 "md5": "^2.3.0", 18 "md5": "^2.3.0",
17 "mta-h5-analysis": "^2.0.15", 19 "mta-h5-analysis": "^2.0.15",
18 "tim-js-sdk": "^2.10.2", 20 "tim-js-sdk": "^2.10.2",
...@@ -23,7 +25,8 @@ ...@@ -23,7 +25,8 @@
23 "vue": "^2.6.11", 25 "vue": "^2.6.11",
24 "vue-clipboard2": "^0.3.1", 26 "vue-clipboard2": "^0.3.1",
25 "vue-infinite-scroll": "^2.0.2", 27 "vue-infinite-scroll": "^2.0.2",
26 "vuex": "^3.1.2" 28 "vuex": "^3.1.2",
29 "yarn": "^1.22.10"
27 }, 30 },
28 "devDependencies": { 31 "devDependencies": {
29 "@vue/cli-plugin-babel": "^3.12.1", 32 "@vue/cli-plugin-babel": "^3.12.1",
......
1 /*eslint-disable*/ 1 /*eslint-disable*/
2
2 /* 3 /*
3 * Module: GenerateTestUserSig 4 * Module: GenerateTestUserSig
4 * 5 *
...@@ -17,38 +18,38 @@ ...@@ -17,38 +18,38 @@
17 * Reference:https://cloud.tencent.com/document/product/647/17275#Server 18 * Reference:https://cloud.tencent.com/document/product/647/17275#Server
18 */ 19 */
19 function genTestUserSig(userID) { 20 function genTestUserSig(userID) {
20 /** 21 /**
21 * 腾讯云 SDKAppId,需要替换为您自己账号下的 SDKAppId。 22 * 腾讯云 SDKAppId,需要替换为您自己账号下的 SDKAppId。
22 * 23 *
23 * 进入腾讯云实时音视频[控制台](https://console.cloud.tencent.com/rav ) 创建应用,即可看到 SDKAppId, 24 * 进入腾讯云实时音视频[控制台](https://console.cloud.tencent.com/rav ) 创建应用,即可看到 SDKAppId,
24 * 它是腾讯云用于区分客户的唯一标识。 25 * 它是腾讯云用于区分客户的唯一标识。
25 */ 26 */
26 var SDKAPPID = 1400514950; 27 var SDKAPPID = 0
27 28
28 /** 29 /**
29 * 签名过期时间,建议不要设置的过短 30 * 签名过期时间,建议不要设置的过短
30 * <p> 31 * <p>
31 * 时间单位:秒 32 * 时间单位:秒
32 * 默认时间:7 x 24 x 60 x 60 = 604800 = 7 天 33 * 默认时间:7 x 24 x 60 x 60 = 604800 = 7 天
33 */ 34 */
34 var EXPIRETIME = 604800; 35 var EXPIRETIME = 604800
35 36
36 /** 37 /**
37 * 计算签名用的加密密钥,获取步骤如下: 38 * 计算签名用的加密密钥,获取步骤如下:
38 * 39 *
39 * step1. 进入腾讯云实时音视频[控制台](https://console.cloud.tencent.com/rav ),如果还没有应用就创建一个, 40 * step1. 进入腾讯云实时音视频[控制台](https://console.cloud.tencent.com/rav ),如果还没有应用就创建一个,
40 * step2. 单击“应用配置”进入基础配置页面,并进一步找到“帐号体系集成”部分。 41 * step2. 单击“应用配置”进入基础配置页面,并进一步找到“帐号体系集成”部分。
41 * step3. 点击“查看密钥”按钮,就可以看到计算 UserSig 使用的加密的密钥了,请将其拷贝并复制到如下的变量中 42 * step3. 点击“查看密钥”按钮,就可以看到计算 UserSig 使用的加密的密钥了,请将其拷贝并复制到如下的变量中
42 * 43 *
43 * 注意:该方案仅适用于调试Demo,正式上线前请将 UserSig 计算代码和密钥迁移到您的后台服务器上,以避免加密密钥泄露导致的流量盗用。 44 * 注意:该方案仅适用于调试Demo,正式上线前请将 UserSig 计算代码和密钥迁移到您的后台服务器上,以避免加密密钥泄露导致的流量盗用。
44 * 文档:https://cloud.tencent.com/document/product/647/17275#Server 45 * 文档:https://cloud.tencent.com/document/product/647/17275#Server
45 */ 46 */
46 var SECRETKEY = 'eb219c4b42bdbbf5dca38f21f5be26ab38f1c157d0ba4277d5acce6507f2d727'; 47 var SECRETKEY = ''
47 48
48 var generator = new window.LibGenerateTestUserSig(SDKAPPID, SECRETKEY, EXPIRETIME);
49 var userSig = generator.genTestUserSig(userID);
50 return {
51 SDKAppID: SDKAPPID,
52 userSig: userSig
53 };
54 }
...\ No newline at end of file ...\ No newline at end of file
49 var generator = new window.LibGenerateTestUserSig(SDKAPPID, SECRETKEY, EXPIRETIME)
50 var userSig = generator.genTestUserSig(userID)
51 return {
52 SDKAppID: SDKAPPID,
53 userSig: userSig
54 }
55 }
......
...@@ -37,11 +37,7 @@ ...@@ -37,11 +37,7 @@
37 <div class="summary"> 37 <div class="summary">
38 <div v-if="conversation.lastMessage" class="text-ellipsis"> 38 <div v-if="conversation.lastMessage" class="text-ellipsis">
39 <span class="remind" style="color:red;" v-if="hasMessageAtMe">[有人提到我]</span> 39 <span class="remind" style="color:red;" v-if="hasMessageAtMe">[有人提到我]</span>
40 <span class="text" title="图片" 40 <span class="text" :title="conversation.lastMessage.messageForShow">
41 v-if="conversation.lastMessage.type === 'TIMCustomElem' && conversation.lastMessage.payload.data === 'image'">
42 [图片]
43 </span>
44 <span v-else class="text" :title="conversation.lastMessage.messageForShow">
45 {{ messageForShow }} 41 {{ messageForShow }}
46 </span> 42 </span>
47 </div> 43 </div>
...@@ -58,6 +54,7 @@ ...@@ -58,6 +54,7 @@
58 54
59 <script> 55 <script>
60 import {mapGetters, mapState} from 'vuex' 56 import {mapGetters, mapState} from 'vuex'
57 import _ from 'loadsh'
61 import {getDate, getTime, isToday} from '../../utils/date' 58 import {getDate, getTime, isToday} from '../../utils/date'
62 59
63 export default { 60 export default {
...@@ -134,8 +131,16 @@ export default { ...@@ -134,8 +131,16 @@ export default {
134 return '对方撤回了一条消息' 131 return '对方撤回了一条消息'
135 } 132 }
136 return `${this.conversation.lastMessage.fromAccount}撤回了一条消息` 133 return `${this.conversation.lastMessage.fromAccount}撤回了一条消息`
134 } else {
135 switch (_.get(this.conversation.lastMessage, 'payload.data', 'other')) {
136 case 'image':
137 return '[图片]'
138 case 'video':
139 return '[视频]'
140 default:
141 return this.conversation.lastMessage.messageForShow
142 }
137 } 143 }
138 return this.conversation.lastMessage.messageForShow
139 }, 144 },
140 ...mapState({ 145 ...mapState({
141 currentConversation: state => state.conversation.currentConversation, 146 currentConversation: state => state.conversation.currentConversation,
......
...@@ -22,14 +22,21 @@ import {mapState} from 'vuex' ...@@ -22,14 +22,21 @@ import {mapState} from 'vuex'
22 import Helper from '../../../utils/helper' 22 import Helper from '../../../utils/helper'
23 23
24 export default { 24 export default {
25 props: {
26 group: {
27 type: String, required: true
28 }
29 },
25 computed: { 30 computed: {
26 ...mapState({ 31 ...mapState({
27 users: state => state.friend.userList,
28 currentConversation: state => state.conversation.currentConversation, 32 currentConversation: state => state.conversation.currentConversation,
29 currentMemberList: state => state.group.currentMemberList 33 currentMemberList: state => state.group.currentMemberList,
34 currentUnMemberList: state => state.group.currentUnMemberList
30 }), 35 }),
31 currentUnMemberList() { 36 },
32 return this.users.filter(item => this.currentMemberList.filter(data => data.userID === item.esm_id).length === 0) 37 data() {
38 return {
39 list: []
33 } 40 }
34 }, 41 },
35 methods: { 42 methods: {
...@@ -67,6 +74,9 @@ export default { ...@@ -67,6 +74,9 @@ export default {
67 // this.$store.commit('showMessage', {type: 'error', message: error.message}) 74 // this.$store.commit('showMessage', {type: 'error', message: error.message})
68 // }) 75 // })
69 } 76 }
77 },
78 mounted() {
79 console.log(12312321)
70 } 80 }
71 } 81 }
72 </script> 82 </script>
......
...@@ -6,9 +6,9 @@ ...@@ -6,9 +6,9 @@
6 <el-button v-if="showCancelBan" type="text" @click="cancelMute">取消禁言</el-button> 6 <el-button v-if="showCancelBan" type="text" @click="cancelMute">取消禁言</el-button>
7 <el-popover title="禁言" v-model="popoverVisible" v-show="showBan"> 7 <el-popover title="禁言" v-model="popoverVisible" v-show="showBan">
8 <el-input 8 <el-input
9 v-model="muteTime" 9 v-model="muteTime"
10 placeholder="请输入禁言时间" 10 placeholder="请输入禁言时间"
11 @keydown.enter.native="setGroupMemberMuteTime" 11 @keydown.enter.native="setGroupMemberMuteTime"
12 /> 12 />
13 <el-button slot="reference" type="text" style="color:red;">禁言</el-button> 13 <el-button slot="reference" type="text" style="color:red;">禁言</el-button>
14 </el-popover> 14 </el-popover>
...@@ -22,15 +22,15 @@ ...@@ -22,15 +22,15 @@
22 {{ member.nameCard || '暂无' }} 22 {{ member.nameCard || '暂无' }}
23 <el-popover title="修改群名片" v-model="nameCardPopoverVisible" v-show="showEditNameCard"> 23 <el-popover title="修改群名片" v-model="nameCardPopoverVisible" v-show="showEditNameCard">
24 <el-input 24 <el-input
25 v-model="nameCard" 25 v-model="nameCard"
26 placeholder="请输入群名片" 26 placeholder="请输入群名片"
27 @keydown.enter.native="setGroupMemberNameCard" 27 @keydown.enter.native="setGroupMemberNameCard"
28 /> 28 />
29 <i 29 <i
30 class="el-icon-edit" 30 class="el-icon-edit"
31 title="修改群名片" 31 title="修改群名片"
32 slot="reference" 32 slot="reference"
33 style="cursor:pointer; font-size:1.6rem;" 33 style="cursor:pointer; font-size:1.6rem;"
34 ></i> 34 ></i>
35 </el-popover> 35 </el-popover>
36 </div> 36 </div>
...@@ -44,7 +44,7 @@ ...@@ -44,7 +44,7 @@
44 </div> 44 </div>
45 <el-button type="text" v-if="canChangeRole" @click="changeMemberRole"> 45 <el-button type="text" v-if="canChangeRole" @click="changeMemberRole">
46 {{ 46 {{
47 member.role === 'Admin' ? '取消管理员' : '设为管理员' 47 member.role === 'Admin' ? '取消管理员' : '设为管理员'
48 }} 48 }}
49 </el-button> 49 </el-button>
50 <el-button type="text" v-if="showKickout" style="color:red;" @click="kickoutGroupMember">踢出群组</el-button> 50 <el-button type="text" v-if="showKickout" style="color:red;" @click="kickoutGroupMember">踢出群组</el-button>
...@@ -52,9 +52,10 @@ ...@@ -52,9 +52,10 @@
52 </template> 52 </template>
53 53
54 <script> 54 <script>
55 import { mapState } from 'vuex' 55 import {mapState} from 'vuex'
56 import { Popover } from 'element-ui' 56 import {Popover} from 'element-ui'
57 import { getFullDate } from '../../../utils/date' 57 import {getFullDate} from '../../../utils/date'
58
58 export default { 59 export default {
59 components: { 60 components: {
60 ElPopover: Popover 61 ElPopover: Popover
...@@ -89,8 +90,8 @@ export default { ...@@ -89,8 +90,8 @@ export default {
89 }, 90 },
90 canChangeRole() { 91 canChangeRole() {
91 return ( 92 return (
92 this.isOwner && 93 this.isOwner &&
93 ['ChatRoom', 'Public'].includes(this.currentConversation.subType) 94 ['ChatRoom', 'Public'].includes(this.currentConversation.subType)
94 ) 95 )
95 }, 96 },
96 changeRoleTitle() { 97 changeRoleTitle() {
...@@ -98,8 +99,8 @@ export default { ...@@ -98,8 +99,8 @@ export default {
98 return '' 99 return ''
99 } 100 }
100 return this.isOwner && this.member.role === 'Admin' 101 return this.isOwner && this.member.role === 'Admin'
101 ? '设为:Member' 102 ? '设为:Member'
102 : '设为:Admin' 103 : '设为:Admin'
103 }, 104 },
104 // 是否显示禁言时间 105 // 是否显示禁言时间
105 showMuteUntil() { 106 showMuteUntil() {
...@@ -109,9 +110,9 @@ export default { ...@@ -109,9 +110,9 @@ export default {
109 // 是否显示取消禁言按钮 110 // 是否显示取消禁言按钮
110 showCancelBan() { 111 showCancelBan() {
111 if ( 112 if (
112 this.showMuteUntil && 113 this.showMuteUntil &&
113 this.currentConversation.type === this.TIM.TYPES.CONV_GROUP && 114 this.currentConversation.type === this.TIM.TYPES.CONV_GROUP &&
114 !this.isMine 115 !this.isMine
115 ) { 116 ) {
116 return this.isOwner || this.isAdmin 117 return this.isOwner || this.isAdmin
117 } 118 }
...@@ -136,20 +137,20 @@ export default { ...@@ -136,20 +137,20 @@ export default {
136 methods: { 137 methods: {
137 kickoutGroupMember() { 138 kickoutGroupMember() {
138 this.tim 139 this.tim
139 .deleteGroupMember({ 140 .deleteGroupMember({
140 groupID: this.currentConversation.groupProfile.groupID, 141 groupID: this.currentConversation.groupProfile.groupID,
141 reason: '我要踢你出群', 142 reason: '我要踢你出群',
142 userIDList: [this.member.userID] 143 userIDList: [this.member.userID]
143 }) 144 })
144 .then(() => { 145 .then(() => {
145 this.$store.commit('deleteGroupMemeber', this.member.userID) 146 this.$store.commit('deleteGroupMember', this.member.userID)
146 }) 147 })
147 .catch(error => { 148 .catch(error => {
148 this.$store.commit('showMessage', { 149 this.$store.commit('showMessage', {
149 type: 'error', 150 type: 'error',
150 message: error.message 151 message: error.message
152 })
151 }) 153 })
152 })
153 }, 154 },
154 changeMemberRole() { 155 changeMemberRole() {
155 if (!this.canChangeRole) { 156 if (!this.canChangeRole) {
...@@ -157,53 +158,53 @@ export default { ...@@ -157,53 +158,53 @@ export default {
157 } 158 }
158 let currentRole = this.member.role 159 let currentRole = this.member.role
159 this.tim 160 this.tim
160 .setGroupMemberRole({ 161 .setGroupMemberRole({
161 groupID: this.currentConversation.groupProfile.groupID, 162 groupID: this.currentConversation.groupProfile.groupID,
162 userID: this.member.userID, 163 userID: this.member.userID,
163 role: currentRole === 'Admin' ? 'Member' : 'Admin' 164 role: currentRole === 'Admin' ? 'Member' : 'Admin'
164 }) 165 })
165 .catch(error => { 166 .catch(error => {
166 this.$store.commit('showMessage', { 167 this.$store.commit('showMessage', {
167 type: 'error', 168 type: 'error',
168 message: error.message 169 message: error.message
170 })
169 }) 171 })
170 })
171 }, 172 },
172 setGroupMemberMuteTime() { 173 setGroupMemberMuteTime() {
173 this.tim 174 this.tim
174 .setGroupMemberMuteTime({ 175 .setGroupMemberMuteTime({
175 groupID: this.currentConversation.groupProfile.groupID, 176 groupID: this.currentConversation.groupProfile.groupID,
176 userID: this.member.userID, 177 userID: this.member.userID,
177 muteTime: Number(this.muteTime) 178 muteTime: Number(this.muteTime)
178 }) 179 })
179 .then(() => { 180 .then(() => {
180 this.muteTime = '' 181 this.muteTime = ''
181 this.popoverVisible = false 182 this.popoverVisible = false
182 }) 183 })
183 .catch(error => { 184 .catch(error => {
184 this.$store.commit('showMessage', { 185 this.$store.commit('showMessage', {
185 type: 'error', 186 type: 'error',
186 message: error.message 187 message: error.message
188 })
187 }) 189 })
188 })
189 }, 190 },
190 // 取消禁言 191 // 取消禁言
191 cancelMute() { 192 cancelMute() {
192 this.tim 193 this.tim
193 .setGroupMemberMuteTime({ 194 .setGroupMemberMuteTime({
194 groupID: this.currentConversation.groupProfile.groupID, 195 groupID: this.currentConversation.groupProfile.groupID,
195 userID: this.member.userID, 196 userID: this.member.userID,
196 muteTime: 0 197 muteTime: 0
197 }) 198 })
198 .then(() => { 199 .then(() => {
199 this.muteTime = '' 200 this.muteTime = ''
200 }) 201 })
201 .catch(error => { 202 .catch(error => {
202 this.$store.commit('showMessage', { 203 this.$store.commit('showMessage', {
203 type: 'error', 204 type: 'error',
204 message: error.message 205 message: error.message
206 })
205 }) 207 })
206 })
207 }, 208 },
208 setGroupMemberNameCard() { 209 setGroupMemberNameCard() {
209 if (this.nameCard.trim().length === 0) { 210 if (this.nameCard.trim().length === 0) {
...@@ -214,23 +215,23 @@ export default { ...@@ -214,23 +215,23 @@ export default {
214 return 215 return
215 } 216 }
216 this.tim 217 this.tim
217 .setGroupMemberNameCard({ 218 .setGroupMemberNameCard({
218 groupID: this.currentConversation.groupProfile.groupID, 219 groupID: this.currentConversation.groupProfile.groupID,
219 userID: this.member.userID, 220 userID: this.member.userID,
220 nameCard: this.nameCard 221 nameCard: this.nameCard
221 })
222 .then(() => {
223 this.nameCardPopoverVisible = false
224 this.$store.commit('showMessage', {
225 message: '修改成功'
226 }) 222 })
227 }) 223 .then(() => {
228 .catch(error => { 224 this.nameCardPopoverVisible = false
229 this.$store.commit('showMessage', { 225 this.$store.commit('showMessage', {
230 type: 'error', 226 message: '修改成功'
231 message: error.message 227 })
228 })
229 .catch(error => {
230 this.$store.commit('showMessage', {
231 type: 'error',
232 message: error.message
233 })
232 }) 234 })
233 })
234 } 235 }
235 } 236 }
236 } 237 }
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
3 <div class="header"> 3 <div class="header">
4 <span class="member-count text-ellipsis">群成员:{{ currentConversation.groupProfile.memberCount }}</span> 4 <span class="member-count text-ellipsis">群成员:{{ currentConversation.groupProfile.memberCount }}</span>
5 <popover v-model="addGroupMemberVisible"> 5 <popover v-model="addGroupMemberVisible">
6 <add-group-member style="width: 200px;max-height: 70vh;overflow: auto"></add-group-member> 6 <add-group-member class="add-member-list" :group="currentConversation.groupProfile.groupID"/>
7 <div slot="reference" class="btn-add-member" title="添加群成员"> 7 <div slot="reference" class="btn-add-member" title="添加群成员">
8 <span class="tim-icon-friend-add"></span> 8 <span class="tim-icon-friend-add"></span>
9 </div> 9 </div>
...@@ -42,6 +42,7 @@ export default { ...@@ -42,6 +42,7 @@ export default {
42 data() { 42 data() {
43 return { 43 return {
44 addGroupMemberVisible: false, 44 addGroupMemberVisible: false,
45 addGroupMemberList: [],
45 currentMemberID: '', 46 currentMemberID: '',
46 count: 30 // 显示的群成员数量 47 count: 30 // 显示的群成员数量
47 } 48 }
...@@ -76,12 +77,11 @@ export default { ...@@ -76,12 +77,11 @@ export default {
76 } 77 }
77 }, 78 },
78 loadMore() { 79 loadMore() {
79 this.$store 80 this.$store.dispatch('getGroupMemberList', this.groupProfile.groupID)
80 .dispatch('getGroupMemberList', this.groupProfile.groupID)
81 .then(() => { 81 .then(() => {
82 this.count += 30 82 this.count += 30
83 }) 83 })
84 } 84 },
85 } 85 }
86 } 86 }
87 </script> 87 </script>
...@@ -93,6 +93,11 @@ export default { ...@@ -93,6 +93,11 @@ export default {
93 padding 10px 16px 10px 20px 93 padding 10px 16px 10px 20px
94 border-bottom 1px solid $border-base 94 border-bottom 1px solid $border-base
95 95
96 >>> .add-member-list
97 width: 200px;
98 max-height: 70vh;
99 overflow: auto
100
96 .member-count 101 .member-count
97 display inline-block 102 display inline-block
98 max-width 130px 103 max-width 130px
......
...@@ -203,15 +203,15 @@ ...@@ -203,15 +203,15 @@
203 @keydown.enter.native="editNameCard" 203 @keydown.enter.native="editNameCard"
204 /> 204 />
205 </div> 205 </div>
206 <div class="info-item"> 206 <!-- <div class="info-item">-->
207 <div class="label" :class="{'active' : active}">全体禁言</div> 207 <!-- <div class="label" :class="{'active' : active}">全体禁言</div>-->
208 <el-switch 208 <!-- <el-switch-->
209 v-model="muteAllMembers" 209 <!-- v-model="muteAllMembers"-->
210 active-color="#409eff" 210 <!-- active-color="#409eff"-->
211 inactive-color="#dcdfe6" 211 <!-- inactive-color="#dcdfe6"-->
212 @change='changeMuteStatus'> 212 <!-- @change='changeMuteStatus'>-->
213 </el-switch> 213 <!-- </el-switch>-->
214 </div> 214 <!-- </div>-->
215 <div v-if="isOwner"> 215 <div v-if="isOwner">
216 <el-button type="text" @click="showChangeGroupOwner = true">转让群组</el-button> 216 <el-button type="text" @click="showChangeGroupOwner = true">转让群组</el-button>
217 <el-input 217 <el-input
......
...@@ -28,7 +28,6 @@ export default { ...@@ -28,7 +28,6 @@ export default {
28 }, 28 },
29 computed: { 29 computed: {
30 ...mapState({ 30 ...mapState({
31 friendList: state => state.friend.friendList,
32 adminList(state) { 31 adminList(state) {
33 const list = state.friend.adminList || [] 32 const list = state.friend.adminList || []
34 return this.select.length === 0 ? list : list.filter(item => item.name.indexOf(this.select) > -1) 33 return this.select.length === 0 ? list : list.filter(item => item.name.indexOf(this.select) > -1)
......
...@@ -3,16 +3,20 @@ ...@@ -3,16 +3,20 @@
3 <div class="group-item"> 3 <div class="group-item">
4 <avatar src=""/> 4 <avatar src=""/>
5 <div class="group-name text-ellipsis">{{ group.title }}</div> 5 <div class="group-name text-ellipsis">{{ group.title }}</div>
6 <el-tag v-if="group.is_stated===1" effect="dark" type="danger" size="mini">已结算</el-tag>
6 </div> 7 </div>
7 </div> 8 </div>
8 </template> 9 </template>
9 10
10 <script> 11 <script>
11 import {MessageBox} from 'element-ui' 12 import {MessageBox, Tag} from 'element-ui'
12 import Helper from '../../utils/helper' 13 import Helper from '../../utils/helper'
13 14
14 export default { 15 export default {
15 props: ['group'], 16 props: ['group'],
17 components: {
18 ElTag: Tag
19 },
16 data() { 20 data() {
17 return { 21 return {
18 visible: false, 22 visible: false,
......
1 <template> 1 <template>
2 <message-bubble :isMine=isMine :message=message> 2 <div class="custom-element-wrapper">
3 <div class="custom-element-wrapper"> 3 <image-element
4 <div class="survey" v-if="this.payload.data === 'survey'"> 4 v-if="this.payload.data === 'image'"
5 <div class="title">对IM DEMO的评分和建议</div> 5 :isMine=isMine
6 <el-rate 6 :payload="Object.assign(message.payload,{ imageInfoArray:[ { url: message.payload.description } ] })"
7 v-model="rate" 7 :message="message"/>
8 disabled 8 <video-element
9 show-score 9 v-else-if="this.payload.data === 'video'"
10 text-color="#ff9900" 10 :isMine="isMine"
11 score-template="{value}"> 11 :payload="Object.assign(message.payload,{ videoUrl: message.payload.description })"
12 </el-rate> 12 :message="message"
13 <div class="suggestion">{{ this.payload.extension }}</div> 13 />
14 </div> 14 <template v-else>
15 <span class="text" title="您可以自行解析自定义消息" v-else> 15 <message-bubble :isMine=isMine :message=message>
16 <template v-if="text.isFromGroupLive && text.isFromGroupLive === 1"> 16 <message-group-live-status v-if="text.isFromGroupLive && text.isFromGroupLive === 1" :liveInfo='text'/>
17 <message-group-live-status :liveInfo='text'/> 17 <template v-else>{{ text }}</template>
18 </template> 18 </message-bubble>
19 <template v-else-if="this.payload.data === 'image'"> 19 </template>
20 <el-image :src="this.payload.description" :preview-src-list="[this.payload.description]"/> 20 </div>
21 <!-- <img alt="image" class="image-element" :src="this.payload.description" @load="onImageLoaded"-->
22 <!-- @click="handlePreview"/>-->
23 </template>
24 <template v-else>{{ text }}</template>
25 </span>
26 </div>
27 </message-bubble>
28 </template> 21 </template>
29 22
30 <script> 23 <script>
31 import {mapState} from 'vuex' 24 import {mapState} from 'vuex'
32 import MessageBubble from '../message-bubble' 25 import MessageBubble from '../message-bubble'
33 import {Rate} from 'element-ui'
34 import MessageGroupLiveStatus from '../message-group-live-status' 26 import MessageGroupLiveStatus from '../message-group-live-status'
35 import ImageElement from '../message-elements/image-element.vue' 27 import ImageElement from '../message-elements/image-element.vue'
28 import VideoElement from './video-element'
36 29
37 export default { 30 export default {
38 name: 'CustomElement', 31 name: 'CustomElement',
...@@ -50,8 +43,8 @@ export default { ...@@ -50,8 +43,8 @@ export default {
50 } 43 }
51 }, 44 },
52 components: { 45 components: {
46 VideoElement,
53 MessageBubble, 47 MessageBubble,
54 ElRate: Rate,
55 MessageGroupLiveStatus, 48 MessageGroupLiveStatus,
56 ImageElement, 49 ImageElement,
57 }, 50 },
...@@ -94,14 +87,6 @@ export default { ...@@ -94,14 +87,6 @@ export default {
94 return '[自定义消息]' 87 return '[自定义消息]'
95 } 88 }
96 }, 89 },
97 onImageLoaded(event) {
98 this.$bus.$emit('image-loaded', event)
99 },
100 handlePreview() {
101 this.$bus.$emit('image-preview', {
102 url: this.payload.description
103 })
104 }
105 } 90 }
106 } 91 }
107 </script> 92 </script>
......
...@@ -55,9 +55,7 @@ export default { ...@@ -55,9 +55,7 @@ export default {
55 this.$bus.$emit('image-loaded', event) 55 this.$bus.$emit('image-loaded', event)
56 }, 56 },
57 handlePreview() { 57 handlePreview() {
58 this.$bus.$emit('image-preview', { 58 this.$bus.$emit('image-preview', {url: this.payload.imageInfoArray[0].url})
59 url: this.payload.imageInfoArray[0].url
60 })
61 } 59 }
62 } 60 }
63 } 61 }
......
1 <template> 1 <template>
2 <message-bubble :isMine=isMine :message=message> 2 <message-bubble :isMine=isMine :message=message>
3 <video 3 <video
4 :src="payload.videoUrl" 4 :src="payload.videoUrl"
5 controls 5 controls
6 class="video" 6 class="video"
7 @error="videoError" 7 @error="videoError"
8 ></video> 8 ></video>
9 <el-progress 9 <el-progress
10 v-if="showProgressBar" 10 v-if="showProgressBar"
11 :percentage="percentage" 11 :percentage="percentage"
12 :color="percentage => (percentage === 100 ? '#67c23a' : '#409eff')" 12 :color="percentage => (percentage === 100 ? '#67c23a' : '#409eff')"
13 /> 13 />
14 </message-bubble> 14 </message-bubble>
15 </template> 15 </template>
16 16
17 <script> 17 <script>
18 import MessageBubble from '../message-bubble' 18 import MessageBubble from '../message-bubble'
19 import { Progress } from 'element-ui' 19 import {Progress} from 'element-ui'
20
20 export default { 21 export default {
21 name: 'VideoElement', 22 name: 'VideoElement',
22 components: { 23 components: {
...@@ -47,7 +48,7 @@ export default { ...@@ -47,7 +48,7 @@ export default {
47 }, 48 },
48 methods: { 49 methods: {
49 videoError(e) { 50 videoError(e) {
50 this.$store.commit('showMessage', { type: 'error', message: '视频出错,错误原因:' + e.target.error.message }) 51 this.$store.commit('showMessage', {type: 'error', message: '视频出错,错误原因:' + e.target.error.message})
51 }, 52 },
52 } 53 }
53 } 54 }
......
...@@ -90,7 +90,7 @@ ...@@ -90,7 +90,7 @@
90 <avatar class="group-member-avatar" :src="avatar" @click.native="showGroupMemberProfile"/> 90 <avatar class="group-member-avatar" :src="avatar" @click.native="showGroupMemberProfile"/>
91 </div> 91 </div>
92 <div class="col-2"> 92 <div class="col-2">
93 <!-- 消息主体 --> 93 <!-- 消息主体 -->
94 <message-header v-if="showMessageHeader" :message="message"/> 94 <message-header v-if="showMessageHeader" :message="message"/>
95 <div class="content-wrapper"> 95 <div class="content-wrapper">
96 <message-status-icon v-if="isMine" :message="message"/> 96 <message-status-icon v-if="isMine" :message="message"/>
......
1 <template> 1 <template>
2 <div class="login-wrapper"> 2 <div class="login-wrapper">
3 <img class="logo" :src="logo" /> 3 <img class="logo" :src="logo"/>
4 <el-form 4 <el-form
5 ref="login" 5 ref="login"
6 :rules="rules" 6 :rules="rules"
7 :model="form" 7 :model="form"
8 label-width="0" 8 label-width="0"
9 style="width:100%;" 9 style="width:100%;"
10 @keydown.enter.native="submit" 10 @keydown.enter.native="submit"
11 > 11 >
12 <!-- Github登录方式 --> 12 <!-- Github登录方式 -->
13 <el-form-item prop="userID"> 13 <el-form-item prop="userID">
14 <el-select v-model="form.userID" class="user-selector"> 14 <el-select v-model="form.userID" class="user-selector">
15 <el-option 15 <el-option
16 v-for="index in 30" 16 v-for="index in 30"
17 :key="index" 17 :key="index"
18 :label="`user${index-1}`" 18 :label="`user${index-1}`"
19 :value="`user${index-1}`" 19 :value="`user${index-1}`"
20 ></el-option> 20 ></el-option>
21 </el-select> 21 </el-select>
22 </el-form-item> 22 </el-form-item>
...@@ -35,19 +35,20 @@ ...@@ -35,19 +35,20 @@
35 </el-form-item>--> 35 </el-form-item>-->
36 </el-form> 36 </el-form>
37 <el-button 37 <el-button
38 type="primary" 38 type="primary"
39 @click="submit" 39 @click="submit"
40 style="width:100%; margin-top: 6px;" 40 style="width:100%; margin-top: 6px;"
41 :loading="loading" 41 :loading="loading"
42 >登录</el-button> 42 >登录
43 </el-button>
43 </div> 44 </div>
44 </template> 45 </template>
45 46
46 <script> 47 <script>
47 import { Form, FormItem, Select, Option } from 'element-ui' 48 import {Form, FormItem, Option, Select} from 'element-ui'
48 import logo from '../../assets/image/logo.png' 49 import logo from '../../assets/image/logo.png'
49 import { errorMap } from '../../utils/common' 50 import Helper from '../../utils/helper'
50 import md5 from 'md5' 51
51 export default { 52 export default {
52 name: 'Login', 53 name: 'Login',
53 components: { 54 components: {
...@@ -72,10 +73,10 @@ export default { ...@@ -72,10 +73,10 @@ export default {
72 }, 73 },
73 rules: { 74 rules: {
74 userID: [ 75 userID: [
75 { required: true, message: '请输入 userID', trigger: 'blur' }, 76 {required: true, message: '请输入 userID', trigger: 'blur'},
76 { validator: checkUserID, trigger: 'blur' } 77 {validator: checkUserID, trigger: 'blur'}
77 ], 78 ],
78 password: [{ required: true, message: '请输入密码', trigger: 'blur' }] 79 password: [{required: true, message: '请输入密码', trigger: 'blur'}]
79 }, 80 },
80 logo: logo, 81 logo: logo,
81 registerVisible: false, 82 registerVisible: false,
...@@ -93,33 +94,33 @@ export default { ...@@ -93,33 +94,33 @@ export default {
93 login() { 94 login() {
94 this.loading = true 95 this.loading = true
95 this.tim 96 this.tim
96 .login({ 97 .login({
97 userID: this.form.userID,
98 userSig: window.genTestUserSig(this.form.userID).userSig
99 })
100 .then(() => {
101 this.loading = false
102 this.$store.commit('toggleIsLogin', true)
103 this.$store.commit('startComputeCurrent')
104 this.$store.commit('showMessage', { type: 'success', message: '登录成功' })
105 this.$store.commit({
106 type: 'GET_USER_INFO',
107 userID: this.form.userID, 98 userID: this.form.userID,
108 userSig: window.genTestUserSig(this.form.userID).userSig, 99 userSig: Helper.getSignature(this.form.userID)
109 sdkAppID: window.genTestUserSig('').SDKAppID
110 }) 100 })
111 this.$store.commit('showMessage', { 101 .then(() => {
112 type: 'success', 102 this.loading = false
113 message: '登录成功' 103 this.$store.commit('toggleIsLogin', true)
104 this.$store.commit('startComputeCurrent')
105 this.$store.commit('showMessage', {type: 'success', message: '登录成功'})
106 this.$store.commit({
107 type: 'GET_USER_INFO',
108 userID: this.form.userID,
109 userSig: Helper.getSignature(this.form.userID),
110 sdkAppID: process.env.VUE_APP_API_KEY
111 })
112 this.$store.commit('showMessage', {
113 type: 'success',
114 message: '登录成功'
115 })
114 }) 116 })
115 }) 117 .catch(error => {
116 .catch(error => { 118 this.loading = false
117 this.loading = false 119 this.$store.commit('showMessage', {
118 this.$store.commit('showMessage', { 120 message: '登录失败:' + error.message,
119 message: '登录失败:' + error.message, 121 type: 'error'
120 type: 'error' 122 })
121 }) 123 })
122 })
123 }, 124 },
124 } 125 }
125 } 126 }
...@@ -134,27 +135,34 @@ export default { ...@@ -134,27 +135,34 @@ export default {
134 background $white 135 background $white
135 color $black 136 color $black
136 border-radius 5px 137 border-radius 5px
137 box-shadow: 0 11px 20px 0 rgba(0,0,0,0.3) 138 box-shadow: 0 11px 20px 0 rgba(0, 0, 0, 0.3)
139
138 .row-div 140 .row-div
139 display flex 141 display flex
140 justify-content center 142 justify-content center
141 align-items center 143 align-items center
142 flex-direction row 144 flex-direction row
145
143 .logo 146 .logo
144 width 110px 147 width 110px
145 height 110px 148 height 110px
149
146 .loginBox 150 .loginBox
147 width 320px 151 width 320px
148 margin 0 0 20px 0 152 margin 0 0 20px 0
153
149 .send-code 154 .send-code
150 width 112px 155 width 112px
156
151 .login-im-btn 157 .login-im-btn
152 width 100% 158 width 100%
159
153 .loginFooter 160 .loginFooter
154 color: #8c8a8ac7 161 color: #8c8a8ac7
155 text-align: center 162 text-align: center
156 padding: 0 0 20px 0 163 padding: 0 0 20px 0
157 cursor: pointer 164 cursor: pointer
165
158 .login-wrapper { 166 .login-wrapper {
159 display: flex; 167 display: flex;
160 align-items: center; 168 align-items: center;
......
...@@ -71,14 +71,11 @@ export default { ...@@ -71,14 +71,11 @@ export default {
71 this.loading = false 71 this.loading = false
72 this.$store.commit('toggleIsLogin', true) 72 this.$store.commit('toggleIsLogin', true)
73 this.$store.commit('startComputeCurrent') 73 this.$store.commit('startComputeCurrent')
74 this.$store.commit({ 74 this.$store.commit('GET_USER_INFO', {
75 type: 'GET_USER_INFO',
76 userID: user.id, 75 userID: user.id,
77 userSig: user.sign, 76 userSig: user.sign,
78 sdkAppID: window.genTestUserSig('').SDKAppID 77 sdkAppID: process.env.VUE_APP_API_KEY
79 }) 78 })
80 Helper.contactList().then(res => this.$store.commit('updateFriendList', res.data))
81 // Helper.groupList({size: 20}).then(res => this.$store.commit('updateGroupList', res.data))
82 // this.$store.commit('showMessage', {type: 'success', message: '登录成功'}) 79 // this.$store.commit('showMessage', {type: 'success', message: '登录成功'})
83 }) 80 })
84 .catch(error => { 81 .catch(error => {
...@@ -142,15 +139,14 @@ export default { ...@@ -142,15 +139,14 @@ export default {
142 139
143 if (isSDKReady) { 140 if (isSDKReady) {
144 this.tim.getMyProfile() 141 this.tim.getMyProfile()
145 .then(({data}) => { 142 .then(({data}) => this.$store.commit('updateCurrentUserProfile', data))
146 this.$store.commit('updateCurrentUserProfile', data) 143 .catch(error => this.$store.commit('showMessage', {type: 'error', message: error.message}))
147 })
148 .catch(error => {
149 this.$store.commit('showMessage', {type: 'error', message: error.message})
150 })
151 this.$store.dispatch('getBlacklist') 144 this.$store.dispatch('getBlacklist')
145 Helper.contactList({type: 'admin'}).then(res => this.$store.commit('updateAdminList', res.data))
146 Helper.contactList({type: 'scheme'}).then(res => this.$store.commit('updateSchemeList', res.data))
147 Helper.contactList({type: 'user'}).then(res => this.$store.commit('updateUserList', res.data))
152 // 登录trtc calling 148 // 登录trtc calling
153 this.trtcCalling.login({sdkAppID: this.sdkAppID, userID: this.userID, userSig: this.userSig}) 149 // this.trtcCalling.login({sdkAppID: this.sdkAppID, userID: this.userID, userSig: this.userSig})
154 } 150 }
155 }, 151 },
156 kickedOutReason(type) { 152 kickedOutReason(type) {
......
1 import tim from 'tim' 1 import tim from 'tim'
2 import TIM from 'tim-js-sdk' 2 import TIM from 'tim-js-sdk'
3 import _ from 'loadsh'
3 import store from '..' 4 import store from '..'
4 import { titleNotify } from '../../utils' 5 import {titleNotify} from '../../utils'
5 import { filterCallingMessage } from '../../utils/common' 6 import {filterCallingMessage} from '../../utils/common'
7
6 const conversationModules = { 8 const conversationModules = {
7 state: { 9 state: {
8 currentConversation: {}, 10 currentConversation: {},
9 currentMessageList: [], 11 currentMessageList: [],
10 nextReqMessageID: '', 12 nextReqMessageID: '',
11 isCompleted: false, // 当前会话消息列表是否已经拉完了所有消息 13 isCompleted: false, // 当前会话消息列表是否已经拉完了所有消息
12 conversationList: [], 14 conversationList: [],
13 callingInfo: { 15 callingInfo: {
14 memberList: [], 16 memberList: [],
15 type: 'C2C', //C2C,GROUP 17 type: 'C2C', //C2C,GROUP
16 }, 18 },
17 audioCall: false 19 audioCall: false
18 },
19 getters: {
20 toAccount: state => {
21 if (!state.currentConversation || !state.currentConversation.conversationID) {
22 return ''
23 }
24 switch (state.currentConversation.type) {
25 case 'C2C':
26 return state.currentConversation.conversationID.replace('C2C', '')
27 case 'GROUP':
28 return state.currentConversation.conversationID.replace('GROUP', '')
29 default:
30 return state.currentConversation.conversationID
31 }
32 },
33 currentConversationType: state => {
34 if (!state.currentConversation || !state.currentConversation.type) {
35 return ''
36 }
37 return state.currentConversation.type
38 }, 20 },
39 totalUnreadCount: state => { 21 getters: {
40 const result = state.conversationList.reduce((count, conversation) => { 22 toAccount: state => {
41 // 当前会话不计算总未读 23 if (!state.currentConversation || !state.currentConversation.conversationID) {
42 if (!store.getters.hidden && state.currentConversation.conversationID === conversation.conversationID) { 24 return ''
43 return count 25 }
26 switch (state.currentConversation.type) {
27 case 'C2C':
28 return state.currentConversation.conversationID.replace('C2C', '')
29 case 'GROUP':
30 return state.currentConversation.conversationID.replace('GROUP', '')
31 default:
32 return state.currentConversation.conversationID
33 }
34 },
35 currentConversationType: state => {
36 if (!state.currentConversation || !state.currentConversation.type) {
37 return ''
38 }
39 return state.currentConversation.type
40 },
41 totalUnreadCount: state => {
42 const result = state.conversationList.reduce((count, conversation) => {
43 // 当前会话不计算总未读
44 if (!store.getters.hidden && state.currentConversation.conversationID === conversation.conversationID) {
45 return count
46 }
47 return count + conversation.unreadCount
48 }, 0)
49 titleNotify(result)
50 return result
51 },
52 // 用于当前会话的图片预览
53 imgUrlList: state => {
54 return state.currentMessageList
55 .filter(message => (message.type === TIM.TYPES.MSG_IMAGE || (message.type === TIM.TYPES.MSG_CUSTOM && _.get(message, 'payload.data', 'custom') === 'image')) && !message.isRevoked) // 筛选出没有撤回并且类型是图片类型的消息
56 .map(message => message.payload.imageInfoArray[0].url || message.payload.description)
44 } 57 }
45 return count + conversation.unreadCount
46 }, 0)
47 titleNotify(result)
48 return result
49 }, 58 },
50 // 用于当前会话的图片预览 59 mutations: {
51 imgUrlList: state => { 60 /**
52 return state.currentMessageList 61 * 显示trtcCalling 群通话成员列表
53 .filter(message => message.type === TIM.TYPES.MSG_IMAGE && !message.isRevoked) // 筛选出没有撤回并且类型是图片类型的消息 62 * @param {Object} state
54 .map(message => message.payload.imageInfoArray[0].url) 63 * @param {Conversation} setCallingList
55 } 64 */
56 },
57 mutations: {
58 /**
59 * 显示trtcCalling 群通话成员列表
60 * @param {Object} state
61 * @param {Conversation} setCallingList
62 */
63 65
64 setCallingList(state, value) { 66 setCallingList(state, value) {
65 state.callingInfo.memberList = value.memberList 67 state.callingInfo.memberList = value.memberList
66 state.callingInfo.type = value.type 68 state.callingInfo.type = value.type
67 }, 69 },
68 70
69 /** 71 /**
70 * 显示trtcCalling 语音通话 72 * 显示trtcCalling 语音通话
71 * @param {Object} state 73 * @param {Object} state
72 * @param {Conversation} showAudioCall 74 * @param {Conversation} showAudioCall
73 */ 75 */
74 76
75 showAudioCall(state, value) { 77 showAudioCall(state, value) {
76 state.audioCall = value 78 state.audioCall = value
77 }, 79 },
78 80
79 /** 81 /**
80 * 更新当前会话 82 * 更新当前会话
81 * 调用时机: 切换会话时 83 * 调用时机: 切换会话时
82 * @param {Object} state 84 * @param {Object} state
83 * @param {Conversation} conversation 85 * @param {Conversation} conversation
84 */ 86 */
85 updateCurrentConversation(state, conversation) { 87 updateCurrentConversation(state, conversation) {
86 state.currentConversation = conversation 88 state.currentConversation = conversation
87 state.currentMessageList = [] 89 state.currentMessageList = []
88 state.nextReqMessageID = '' 90 state.nextReqMessageID = ''
89 state.isCompleted = false 91 state.isCompleted = false
90 }, 92 },
91 /** 93 /**
92 * 更新会话列表 94 * 更新会话列表
93 * 调用时机:触发会话列表更新事件时。CONVERSATION_LIST_UPDATED 95 * 调用时机:触发会话列表更新事件时。CONVERSATION_LIST_UPDATED
94 * @param {Object} state 96 * @param {Object} state
95 * @param {Conversation[]} conversationList 97 * @param {Conversation[]} conversationList
96 */ 98 */
97 updateConversationList(state, conversationList) { 99 updateConversationList(state, conversationList) {
98 state.conversationList = conversationList 100 state.conversationList = conversationList
99 }, 101 },
100 /** 102 /**
101 * 重置当前会话 103 * 重置当前会话
102 * 调用时机:需要重置当前会话时,例如:当前会话是一个群组,正好被踢出群时(被踢群事件触发),重置当前会话 104 * 调用时机:需要重置当前会话时,例如:当前会话是一个群组,正好被踢出群时(被踢群事件触发),重置当前会话
103 * @param {Object} state 105 * @param {Object} state
104 */ 106 */
105 resetCurrentConversation(state) { 107 resetCurrentConversation(state) {
106 state.currentConversation = {} 108 state.currentConversation = {}
107 }, 109 },
108 /** 110 /**
109 * 将消息插入当前会话列表 111 * 将消息插入当前会话列表
110 * 调用时机:收/发消息事件触发时 112 * 调用时机:收/发消息事件触发时
111 * @param {Object} state 113 * @param {Object} state
112 * @param {Message[]|Message} data 114 * @param {Message[]|Message} data
113 * @returns 115 * @returns
114 */ 116 */
115 pushCurrentMessageList(state, data) { 117 pushCurrentMessageList(state, data) {
116 // 还没当前会话,则跳过 118 // 还没当前会话,则跳过
117 if (!state.currentConversation.conversationID) { 119 if (!state.currentConversation.conversationID) {
118 return 120 return
119 } 121 }
120 if (Array.isArray(data)) { 122 if (Array.isArray(data)) {
121 // 筛选出当前会话的消息 123 // 筛选出当前会话的消息
122 const result = data.filter(item => item.conversationID === state.currentConversation.conversationID) 124 const result = data.filter(item => item.conversationID === state.currentConversation.conversationID)
123 state.currentMessageList = [...state.currentMessageList, ...result] 125 state.currentMessageList = [...state.currentMessageList, ...result]
124 filterCallingMessage(state.currentMessageList) 126 filterCallingMessage(state.currentMessageList)
125 } else if (data.conversationID === state.currentConversation.conversationID) { 127 } else if (data.conversationID === state.currentConversation.conversationID) {
126 state.currentMessageList = [...state.currentMessageList, data] 128 state.currentMessageList = [...state.currentMessageList, data]
127 filterCallingMessage(state.currentMessageList) 129 filterCallingMessage(state.currentMessageList)
128 } 130 }
129 }, 131 },
130 /** 132 /**
131 * 从当前消息列表中删除某条消息 133 * 从当前消息列表中删除某条消息
132 * @param {Object} state 134 * @param {Object} state
133 * @param {Message} message 135 * @param {Message} message
134 */ 136 */
135 removeMessage(state, message) { 137 removeMessage(state, message) {
136 const index = state.currentMessageList.findIndex(({ ID }) => ID === message.ID) 138 const index = state.currentMessageList.findIndex(({ID}) => ID === message.ID)
137 if (index >= 0) { 139 if (index >= 0) {
138 state.currentMessageList.splice(index, 1) 140 state.currentMessageList.splice(index, 1)
139 } 141 }
142 },
143 reset(state) {
144 Object.assign(state, {
145 currentConversation: {},
146 currentMessageList: [],
147 nextReqMessageID: '',
148 isCompleted: false, // 当前会话消息列表是否已经拉完了所有消息
149 conversationList: []
150 })
151 }
140 }, 152 },
141 reset(state) { 153 actions: {
142 Object.assign(state, { 154 /**
143 currentConversation: {}, 155 * 获取消息列表
144 currentMessageList: [], 156 * 调用时机:打开某一会话时或下拉获取历史消息时
145 nextReqMessageID: '', 157 * @param {Object} context
146 isCompleted: false, // 当前会话消息列表是否已经拉完了所有消息 158 * @param {String} conversationID
147 conversationList: [] 159 */
148 }) 160 getMessageList(context, conversationID) {
149 } 161 if (context.state.isCompleted) {
150 }, 162 context.commit('showMessage', {
151 actions: { 163 message: '已经没有更多的历史消息了哦',
152 /** 164 type: 'info'
153 * 获取消息列表 165 })
154 * 调用时机:打开某一会话时或下拉获取历史消息时 166 return
155 * @param {Object} context 167 }
156 * @param {String} conversationID 168 const {nextReqMessageID, currentMessageList} = context.state
157 */ 169 tim.getMessageList({conversationID, nextReqMessageID, count: 15}).then(imReponse => {
158 getMessageList(context, conversationID) { 170 // 更新messageID,续拉时要用到
159 if (context.state.isCompleted) { 171 context.state.nextReqMessageID = imReponse.data.nextReqMessageID
160 context.commit('showMessage', { 172 context.state.isCompleted = imReponse.data.isCompleted
161 message: '已经没有更多的历史消息了哦', 173 // 更新当前消息列表,从头部插入
162 type: 'info' 174 context.state.currentMessageList = [...imReponse.data.messageList, ...currentMessageList]
163 }) 175 filterCallingMessage(context.state.currentMessageList)
164 return
165 }
166 const { nextReqMessageID, currentMessageList } = context.state
167 tim.getMessageList({ conversationID, nextReqMessageID, count: 15 }).then(imReponse => {
168 // 更新messageID,续拉时要用到
169 context.state.nextReqMessageID = imReponse.data.nextReqMessageID
170 context.state.isCompleted = imReponse.data.isCompleted
171 // 更新当前消息列表,从头部插入
172 context.state.currentMessageList = [...imReponse.data.messageList, ...currentMessageList]
173 filterCallingMessage(context.state.currentMessageList)
174 176
175 }) 177 })
176 }, 178 },
177 /** 179 /**
178 * 切换会话 180 * 切换会话
179 * 调用时机:切换会话时 181 * 调用时机:切换会话时
180 * @param {Object} context 182 * @param {Object} context
181 * @param {String} conversationID 183 * @param {String} conversationID
182 */ 184 */
183 checkoutConversation(context, conversationID) { 185 checkoutConversation(context, conversationID) {
184 context.commit('resetCurrentMemberList') 186 context.commit('resetCurrentMemberList')
185 // 1.切换会话前,将切换前的会话进行已读上报 187 // 1.切换会话前,将切换前的会话进行已读上报
186 if (context.state.currentConversation.conversationID) { 188 if (context.state.currentConversation.conversationID) {
187 const prevConversationID = context.state.currentConversation.conversationID 189 const prevConversationID = context.state.currentConversation.conversationID
188 tim.setMessageRead({ conversationID: prevConversationID }) 190 tim.setMessageRead({conversationID: prevConversationID})
189 } 191 }
190 // 2.待切换的会话也进行已读上报 192 // 2.待切换的会话也进行已读上报
191 tim.setMessageRead({ conversationID }) 193 tim.setMessageRead({conversationID})
192 // 3. 获取会话信息 194 // 3. 获取会话信息
193 return tim.getConversationProfile(conversationID).then(({ data }) => { 195 return tim.getConversationProfile(conversationID).then(({data}) => {
194 // 3.1 更新当前会话 196 // 3.1 更新当前会话
195 context.commit('updateCurrentConversation', data.conversation) 197 context.commit('updateCurrentConversation', data.conversation)
196 // 3.2 获取消息列表 198 // 3.2 获取消息列表
197 context.dispatch('getMessageList', conversationID) 199 context.dispatch('getMessageList', conversationID)
198 // 3.3 拉取第一页群成员列表 200 // 3.3 拉取第一页群成员列表
199 if (data.conversation.type === TIM.TYPES.CONV_GROUP) { 201 if (data.conversation.type === TIM.TYPES.CONV_GROUP) {
200 return context.dispatch('getGroupMemberList', data.conversation.groupProfile.groupID) 202 context.dispatch('getGroupUnMemberList', data.conversation.groupProfile.groupID)
203 return context.dispatch('getGroupMemberList', data.conversation.groupProfile.groupID)
204 }
205 return Promise.resolve()
206 })
201 } 207 }
202 return Promise.resolve()
203 })
204 } 208 }
205 }
206 } 209 }
207 210
208 export default conversationModules 211 export default conversationModules
......
...@@ -9,10 +9,16 @@ const friendModules = { ...@@ -9,10 +9,16 @@ const friendModules = {
9 getters: {}, 9 getters: {},
10 mutations: { 10 mutations: {
11 updateFriendList(state, friendList) { 11 updateFriendList(state, friendList) {
12 // state.friendList = friendList 12 state.friendList = friendList
13 state.userList = friendList.user 13 },
14 state.adminList = friendList.admin 14 updateAdminList(state, friendList) {
15 state.schemeList = friendList.scheme 15 state.adminList = friendList
16 },
17 updateSchemeList(state, friendList) {
18 state.schemeList = friendList
19 },
20 updateUserList(state, friendList) {
21 state.userList = friendList
16 }, 22 },
17 reset(state) { 23 reset(state) {
18 Object.assign(state, {friendList: [], createGroupModelVisible: false}) 24 Object.assign(state, {friendList: [], createGroupModelVisible: false})
......
1 import tim from 'tim' 1 import tim from 'tim'
2 import Helper from '../../utils/helper'
2 3
3 const groupModules = { 4 const groupModules = {
4 state: { 5 state: {
5 groupList: [],
6 currentMemberList: [],
7 createGroupModelVisible: false
8 },
9 getters: {
10 hasGroupList: state => state.groupList.length > 0
11 },
12 mutations: {
13 updateGroupList(state, groupList) {
14 state.groupList = groupList
15 },
16 updateCreateGroupModelVisible(state, visible) {
17 state.createGroupModelVisible = visible
18 },
19 updateCurrentMemberList(state, memberList) {
20 state.currentMemberList = [...state.currentMemberList, ...memberList]
21 },
22 deleteGroupMemeber(state, userID) {
23 state.currentMemberList = state.currentMemberList.filter((member) => member.userID !== userID)
24 },
25 deleteGroupMemberList(state, userIDList) {
26 state.currentMemberList = state.currentMemberList.filter((member) => !userIDList.includes(member.userID))
27 },
28 resetCurrentMemberList(state) {
29 state.currentMemberList = []
30 },
31 reset(state) {
32 Object.assign(state, {
33 groupList: [], 6 groupList: [],
34 currentMemberList: [], 7 currentMemberList: [],
8 currentUnMemberList: [],
9 currentUnMemberPage: 1,
35 createGroupModelVisible: false 10 createGroupModelVisible: false
36 })
37 }
38 },
39 actions: {
40 updateGroupList(context, groupList) {
41 context.commit('updateGroupList', groupList)
42 }, 11 },
43 getGroupMemberList(context, groupID) { 12 getters: {
44 return tim.getGroupMemberList({ 13 hasGroupList: state => state.groupList.length > 0
45 groupID: groupID, 14 },
46 offset: context.state.currentMemberList.length, 15 mutations: {
47 count: 30 16 updateGroupList(state, groupList) {
48 }).then((imResponse) => { 17 state.groupList = groupList
49 context.commit('updateCurrentMemberList', imResponse.data.memberList) 18 },
50 return imResponse 19 updateCreateGroupModelVisible(state, visible) {
51 }) 20 state.createGroupModelVisible = visible
21 },
22 updateCurrentMemberList(state, memberList) {
23 state.currentMemberList = [...state.currentMemberList, ...memberList]
24 },
25 updateCurrentUnMemberList(state, memberList) {
26 state.currentUnMemberList = [...state.currentUnMemberList, ...memberList]
27 state.currentUnMemberPage = state.currentUnMemberPage + 1
28 },
29 deleteGroupMember(state, userID) {
30 state.currentMemberList = state.currentMemberList.filter((member) => member.userID !== userID)
31 },
32 deleteGroupMemberList(state, userIDList) {
33 state.currentMemberList = state.currentMemberList.filter((member) => !userIDList.includes(member.userID))
34 },
35 resetCurrentMemberList(state) {
36 state.currentMemberList = []
37 state.currentUnMemberList = []
38 state.currentUnMemberPage = 1
39 },
40 reset(state) {
41 Object.assign(state, {
42 groupList: [],
43 currentMemberList: [],
44 createGroupModelVisible: false
45 })
46 }
47 },
48 actions: {
49 updateGroupList(context, groupList) {
50 context.commit('updateGroupList', groupList)
51 },
52 getGroupMemberList(context, groupID) {
53 return tim.getGroupMemberList({
54 groupID: groupID,
55 offset: context.state.currentMemberList.length,
56 count: 30
57 }).then((imResponse) => {
58 context.commit('updateCurrentMemberList', imResponse.data.memberList)
59 return imResponse
60 })
61 },
62 getGroupUnMemberList(context, groupID) {
63 Helper.groupMemberList(groupID, {page: context.state.currentUnMemberPage, size: 20}).then(res => {
64 context.commit('updateCurrentUnMemberList', res.data)
65 })
66 }
52 } 67 }
53 }
54 } 68 }
55 69
56 export default groupModules 70 export default groupModules
......
1 import tim from '../../tim' 1 import tim from '../../tim'
2 import Helper from '../../utils/helper'
2 3
3 const user = { 4 const user = {
4 state: { 5 state: {
...@@ -36,7 +37,7 @@ const user = { ...@@ -36,7 +37,7 @@ const user = {
36 login(context, userID) { 37 login(context, userID) {
37 tim.login({ 38 tim.login({
38 userID, 39 userID,
39 userSig: window.genTestUserSig(userID).userSig 40 userSig: Helper.getSignature(userID)
40 }).then(() => { 41 }).then(() => {
41 context.commit('toggleIsLogin', true) 42 context.commit('toggleIsLogin', true)
42 context.commit('startComputeCurrent') 43 context.commit('startComputeCurrent')
......
...@@ -2,9 +2,7 @@ import TIM from 'tim-js-sdk' ...@@ -2,9 +2,7 @@ import TIM from 'tim-js-sdk'
2 import COSSDK from 'cos-js-sdk-v5' 2 import COSSDK from 'cos-js-sdk-v5'
3 3
4 // 初始化 SDK 实例 4 // 初始化 SDK 实例
5 const tim = TIM.create({ 5 const tim = TIM.create({SDKAppID: parseInt(process.env.VUE_APP_API_KEY)})
6 SDKAppID: window.genTestUserSig('').SDKAppID
7 })
8 6
9 window.setLogLevel = tim.setLogLevel 7 window.setLogLevel = tim.setLogLevel
10 8
......
1 import TRTCCalling from 'trtc-calling-js' 1 import TRTCCalling from 'trtc-calling-js'
2 2
3 let options = { 3 let options = {SDKAppID: parseInt(process.env.VUE_APP_API_KEY)}
4 SDKAppID: window.genTestUserSig('').SDKAppID // 接入时需要将0替换为您的云通信应用的 SDKAppID
5 }
6 4
7 const trtcCalling = new TRTCCalling(options) 5 const trtcCalling = new TRTCCalling(options)
8 6
......
1 import request from './request' 1 import request from './request'
2 2
3 export default class Helper { 3 export default class Helper {
4 constructor() { 4
5 static getKey() {
6 return parseInt(process.env.VUE_APP_API_KEY)
7 }
8
9 static getSecret() {
10 return process.env.VUE_APP_API_SECRET
11 }
12
13 static getExpire() {
14 return parseInt(process.env.VUE_APP_API_EXPIRETIME)
5 } 15 }
6 16
17
7 static getUrlKey(name) { 18 static getUrlKey(name) {
8 return decodeURIComponent((new RegExp('[?|&]' + name + '=' + '([^&;]+?)(&|#|;|$)').exec(location.href) || [, ''])[1].replace(/\+/g, '%20')) || null 19 return decodeURIComponent((new RegExp('[?|&]' + name + '=' + '([^&;]+?)(&|#|;|$)').exec(location.href) || [, ''])[1].replace(/\+/g, '%20')) || null
9 } 20 }
...@@ -12,6 +23,11 @@ export default class Helper { ...@@ -12,6 +23,11 @@ export default class Helper {
12 return this.getUrlKey('token') 23 return this.getUrlKey('token')
13 } 24 }
14 25
26 static getSignature(userID) {
27 const generator = new window.LibGenerateTestUserSig(this.getKey(), this.getSecret(), this.getExpire())
28 return generator.genTestUserSig(userID)
29 }
30
15 /** 31 /**
16 * 32 *
17 * @returns {Promise<never>|Promise<{sign, id}>} 33 * @returns {Promise<never>|Promise<{sign, id}>}
...@@ -19,18 +35,22 @@ export default class Helper { ...@@ -19,18 +35,22 @@ export default class Helper {
19 static verifyToken() { 35 static verifyToken() {
20 return request.get('auth').then(res => { 36 return request.get('auth').then(res => {
21 const {esm_id} = res.data 37 const {esm_id} = res.data
22 return Promise.resolve({id: esm_id, sign: window.genTestUserSig(esm_id).userSig}) 38 return Promise.resolve({id: esm_id, sign: this.getSignature(esm_id)})
23 }) 39 })
24 } 40 }
25 41
26 static contactList() { 42 static contactList(params = {}) {
27 return request.get('im/contacts') 43 return request.get('im/contacts', {params})
28 } 44 }
29 45
30 static groupList(params = {}) { 46 static groupList(params = {}) {
31 return request.get('im/groups', {params}) 47 return request.get('im/groups', {params})
32 } 48 }
33 49
50 static groupMemberList(group, params = {}) {
51 return request.get(`im/groups/${group}/members`, {params})
52 }
53
34 static joinGroup(id, member) { 54 static joinGroup(id, member) {
35 return request.post(`im/groups/${id}/members`, {member}) 55 return request.post(`im/groups/${id}/members`, {member})
36 } 56 }
......
...@@ -5,7 +5,7 @@ import tim from '../tim' ...@@ -5,7 +5,7 @@ import tim from '../tim'
5 5
6 6
7 const service = axios.create({ 7 const service = axios.create({
8 baseURL: 'http://spread_dev.hikoon.com/mapi', 8 baseURL: process.env.VUE_APP_API_URL,
9 // withCredentials: true, // send cookies when cross-domain requests 9 // withCredentials: true, // send cookies when cross-domain requests
10 timeout: 5000 // request timeout 10 timeout: 5000 // request timeout
11 }) 11 })
......
1 const path = require('path') 1 const path = require('path')
2 2
3 function resolve(dir) { 3 function resolve(dir) {
4 return path.join(__dirname, dir) 4 return path.join(__dirname, dir)
5 } 5 }
6
6 module.exports = { 7 module.exports = {
7 publicPath: './', 8 publicPath: './',
8 assetsDir: './', 9 assetsDir: './',
9 productionSourceMap: false, 10 productionSourceMap: false,
10 chainWebpack: config => { 11 chainWebpack: config => {
11 config.resolve.alias 12 config.resolve.alias
12 .set('@', resolve('src')) 13 .set('@', resolve('src'))
13 .set('tim', resolve('src/tim.js')) 14 .set('tim', resolve('src/tim.js'))
14 // 删除预加载 15 // 删除预加载
15 config.plugins.delete('preload') 16 config.plugins.delete('preload')
16 config.plugins.delete('prefetch') 17 config.plugins.delete('prefetch')
17 // 压缩代码 18 // 压缩代码
18 config.optimization.minimize(true) 19 config.optimization.minimize(true)
19 // 分割代码 20 // 分割代码
20 config.optimization.splitChunks({ 21 config.optimization.splitChunks({
21 chunks: 'all' 22 chunks: 'all'
22 }) 23 })
23 }, 24 },
24 css: { 25 css: {
25 extract: true, 26 extract: true,
26 sourceMap: false, 27 sourceMap: false,
27 loaderOptions: { 28 loaderOptions: {
28 stylus: { 29 stylus: {
29 'resolve url': true, 30 'resolve url': true,
30 // 自定义主题场景 31 // 自定义主题场景
31 import: [path.resolve(__dirname, './src/assets/css/base.styl')] 32 import: [path.resolve(__dirname, './src/assets/css/base.styl')]
32 } 33 }
34 }
33 } 35 }
34 }
35 } 36 }
......
...@@ -1249,6 +1249,11 @@ acorn@^7.1.1: ...@@ -1249,6 +1249,11 @@ acorn@^7.1.1:
1249 resolved "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" 1249 resolved "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa"
1250 integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== 1250 integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==
1251 1251
1252 add@^2.0.6:
1253 version "2.0.6"
1254 resolved "https://registry.npmjs.org/add/-/add-2.0.6.tgz#248f0a9f6e5a528ef2295dbeec30532130ae2235"
1255 integrity sha1-JI8Kn25aUo7yKV2+7DBTITCuIjU=
1256
1252 address@^1.0.3: 1257 address@^1.0.3:
1253 version "1.1.2" 1258 version "1.1.2"
1254 resolved "https://registry.npmjs.org/address/-/address-1.1.2.tgz#bf1116c9c758c51b7a933d296b72c221ed9428b6" 1259 resolved "https://registry.npmjs.org/address/-/address-1.1.2.tgz#bf1116c9c758c51b7a933d296b72c221ed9428b6"
...@@ -5100,6 +5105,11 @@ loader-utils@^1.0.2, loader-utils@^1.1.0, loader-utils@^1.2.3, loader-utils@^1.4 ...@@ -5100,6 +5105,11 @@ loader-utils@^1.0.2, loader-utils@^1.1.0, loader-utils@^1.2.3, loader-utils@^1.4
5100 emojis-list "^3.0.0" 5105 emojis-list "^3.0.0"
5101 json5 "^1.0.1" 5106 json5 "^1.0.1"
5102 5107
5108 loadsh@^0.0.4:
5109 version "0.0.4"
5110 resolved "https://registry.npmjs.org/loadsh/-/loadsh-0.0.4.tgz#5314babd12bb13315dde024a4ca70758c5489d2d"
5111 integrity sha512-U+wLL8InpfRalWrr+0SuhWgGt10M4OyAk6G8xCYo2rwpiHtxZkWiFpjei0vO463ghW8LPCdhqQxXlMy2qicAEw==
5112
5103 locate-path@^2.0.0: 5113 locate-path@^2.0.0:
5104 version "2.0.0" 5114 version "2.0.0"
5105 resolved "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" 5115 resolved "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e"
...@@ -8689,6 +8699,11 @@ yargs@^16.0.0: ...@@ -8689,6 +8699,11 @@ yargs@^16.0.0:
8689 y18n "^5.0.5" 8699 y18n "^5.0.5"
8690 yargs-parser "^20.2.2" 8700 yargs-parser "^20.2.2"
8691 8701
8702 yarn@^1.22.10:
8703 version "1.22.10"
8704 resolved "https://registry.npmjs.org/yarn/-/yarn-1.22.10.tgz#c99daa06257c80f8fa2c3f1490724e394c26b18c"
8705 integrity sha512-IanQGI9RRPAN87VGTF7zs2uxkSyQSrSPsju0COgbsKQOOXr5LtcVPeyXWgwVa0ywG3d8dg6kSYKGBuYK021qeA==
8706
8692 yorkie@^2.0.0: 8707 yorkie@^2.0.0:
8693 version "2.0.0" 8708 version "2.0.0"
8694 resolved "https://registry.npmjs.org/yorkie/-/yorkie-2.0.0.tgz#92411912d435214e12c51c2ae1093e54b6bb83d9" 8709 resolved "https://registry.npmjs.org/yorkie/-/yorkie-2.0.0.tgz#92411912d435214e12c51c2ae1093e54b6bb83d9"
......