Merge branch 'develop'
Showing
15 changed files
with
1420 additions
and
941 deletions
... | @@ -7,3 +7,5 @@ VUE_APP_API_SECRET='eb219c4b42bdbbf5dca38f21f5be26ab38f1c157d0ba4277d5acce6507f2 | ... | @@ -7,3 +7,5 @@ VUE_APP_API_SECRET='eb219c4b42bdbbf5dca38f21f5be26ab38f1c157d0ba4277d5acce6507f2 |
7 | #VUE_APP_API_KEY=1400514886 | 7 | #VUE_APP_API_KEY=1400514886 |
8 | #VUE_APP_API_SECRET='9c0cbbb0f08e4087e1b06295cd32fc1f9f368c011539123517f769c59274147a' | 8 | #VUE_APP_API_SECRET='9c0cbbb0f08e4087e1b06295cd32fc1f9f368c011539123517f769c59274147a' |
9 | VUE_APP_API_EXPIRETIME=604800 | 9 | VUE_APP_API_EXPIRETIME=604800 |
10 | |||
11 | VUE_APP_API_UNI_URL='https://spread-dev.hikoon.com/api' | ... | ... |
... | @@ -5,3 +5,5 @@ VUE_APP_API_URL='http://spread.hikoon.com/mapi' | ... | @@ -5,3 +5,5 @@ VUE_APP_API_URL='http://spread.hikoon.com/mapi' |
5 | VUE_APP_API_KEY=1400514886 | 5 | VUE_APP_API_KEY=1400514886 |
6 | VUE_APP_API_SECRET='9c0cbbb0f08e4087e1b06295cd32fc1f9f368c011539123517f769c59274147a' | 6 | VUE_APP_API_SECRET='9c0cbbb0f08e4087e1b06295cd32fc1f9f368c011539123517f769c59274147a' |
7 | VUE_APP_API_EXPIRETIME=604800 | 7 | VUE_APP_API_EXPIRETIME=604800 |
8 | #VUE_APP_API_UNI_URL='https://spread.hikoon.com/api' | ||
9 | VUE_APP_API_UNI_URL='https://spread-dev.hikoon.com/api' | ... | ... |
... | @@ -8,9 +8,9 @@ | ... | @@ -8,9 +8,9 @@ |
8 | "eslint:recommended" | 8 | "eslint:recommended" |
9 | ], | 9 | ], |
10 | "rules": { | 10 | "rules": { |
11 | "no-console": 'off', | 11 | // "no-console": 'off', |
12 | "quotes": ["error", "single"], | 12 | // "quotes": ["error", "single"], |
13 | "semi": ["error","never"], | 13 | // "semi": ["error","never"], |
14 | "space-before-blocks": "error", | 14 | "space-before-blocks": "error", |
15 | "space-unary-ops": "error" | 15 | "space-unary-ops": "error" |
16 | }, | 16 | }, | ... | ... |
dist.zip
0 → 100644
No preview for this file type
1 | <template> | 1 | <template> |
2 | <div | 2 | <div |
3 | class="conversation-item-container" | 3 | class="conversation-item-container" |
4 | :class="{ 'choose': conversation.conversationID === currentConversation.conversationID }" | 4 | :class="{ |
5 | @click="selectConversation" | 5 | choose: |
6 | conversation.conversationID === currentConversation.conversationID, | ||
7 | }" | ||
8 | @click="selectConversation" | ||
6 | > | 9 | > |
7 | <div class="close-btn"> | 10 | <div class="close-btn"> |
8 | <span class="tim-icon-close" title="删除会话" @click="deleteConversation"></span> | 11 | <span |
12 | class="tim-icon-close" | ||
13 | title="删除会话" | ||
14 | @click="deleteConversation" | ||
15 | ></span> | ||
9 | </div> | 16 | </div> |
10 | <div class="warp"> | 17 | <div class="warp"> |
11 | <avatar :src="avatar" :type="conversation.type"/> | 18 | <avatar :src="avatar" :type="conversation.type" /> |
12 | <div class="content"> | 19 | <div class="content"> |
13 | <div class="row-1"> | 20 | <div class="row-1"> |
14 | <div class="name"> | 21 | <div class="name"> |
15 | <div class="text-ellipsis"> | 22 | <div class="text-ellipsis"> |
16 | <span :title="conversation.userProfile.nick || conversation.userProfile.userID" | ||
17 | v-if="conversation.type === TIM.TYPES.CONV_C2C" | ||
18 | >{{ conversation.userProfile.nick || conversation.userProfile.userID }} | ||
19 | </span> | ||
20 | <span :title="conversation.groupProfile.name || conversation.groupProfile.groupID" | ||
21 | v-else-if="conversation.type === TIM.TYPES.CONV_GROUP" | ||
22 | >{{ conversation.groupProfile.name || conversation.groupProfile.groupID }} | ||
23 | </span> | ||
24 | <span | 23 | <span |
25 | v-else-if="conversation.type === TIM.TYPES.CONV_SYSTEM" | 24 | :title=" |
26 | >系统通知 | 25 | conversation.userProfile.nick || |
27 | </span> | 26 | conversation.userProfile.userID |
27 | " | ||
28 | v-if="conversation.type === TIM.TYPES.CONV_C2C" | ||
29 | >{{ | ||
30 | conversation.userProfile.nick || | ||
31 | conversation.userProfile.userID | ||
32 | }} | ||
33 | </span> | ||
34 | <span | ||
35 | :title=" | ||
36 | conversation.groupProfile.name || | ||
37 | conversation.groupProfile.groupID | ||
38 | " | ||
39 | v-else-if="conversation.type === TIM.TYPES.CONV_GROUP" | ||
40 | >{{ | ||
41 | conversation.groupProfile.name || | ||
42 | conversation.groupProfile.groupID | ||
43 | }} | ||
44 | </span> | ||
45 | <span v-else-if="conversation.type === TIM.TYPES.CONV_SYSTEM" | ||
46 | >系统通知 | ||
47 | </span> | ||
28 | </div> | 48 | </div> |
29 | </div> | 49 | </div> |
30 | <div class="unread-count"> | 50 | <div class="unread-count"> |
31 | <span class="badge" v-if="showUnreadCount"> | 51 | <span class="badge" v-if="showUnreadCount"> |
32 | {{ conversation.unreadCount > 99 ? '99+' : conversation.unreadCount }} | 52 | {{ |
33 | </span> | 53 | conversation.unreadCount > 99 ? "99+" : conversation.unreadCount |
54 | }} | ||
55 | </span> | ||
34 | </div> | 56 | </div> |
35 | </div> | 57 | </div> |
36 | <div class="row-2"> | 58 | <div class="row-2"> |
37 | <div class="summary"> | 59 | <div class="summary"> |
38 | <div v-if="conversation.lastMessage" class="text-ellipsis"> | 60 | <div v-if="conversation.lastMessage" class="text-ellipsis"> |
39 | <span class="remind" style="color:red;" v-if="hasMessageAtMe">[有人提到我]</span> | 61 | <span class="remind" style="color: red" v-if="hasMessageAtMe" |
40 | <span class="text" :title="conversation.lastMessage.messageForShow"> | 62 | >[有人提到我]</span |
41 | {{ messageForShow }} | 63 | > |
42 | </span> | 64 | <span |
65 | class="text" | ||
66 | :title="conversation.lastMessage.messageForShow" | ||
67 | > | ||
68 | {{ messageForShow }} | ||
69 | </span> | ||
43 | </div> | 70 | </div> |
44 | </div> | 71 | </div> |
45 | <div class="date"> | 72 | <div class="date"> |
... | @@ -49,158 +76,172 @@ | ... | @@ -49,158 +76,172 @@ |
49 | </div> | 76 | </div> |
50 | </div> | 77 | </div> |
51 | </div> | 78 | </div> |
52 | |||
53 | </template> | 79 | </template> |
54 | 80 | ||
55 | <script> | 81 | <script> |
56 | import {mapGetters, mapState} from 'vuex' | 82 | import { mapGetters, mapState } from "vuex"; |
57 | import _ from 'loadsh' | 83 | import _ from "loadsh"; |
58 | import {getDate, getTime, isToday} from '../../utils/date' | 84 | import { getDate, getTime, isToday } from "../../utils/date"; |
59 | 85 | ||
60 | export default { | 86 | export default { |
61 | name: 'conversation-item', | 87 | name: "conversation-item", |
62 | props: ['conversation'], | 88 | props: ["conversation"], |
63 | filters: {}, | 89 | filters: {}, |
64 | data() { | 90 | data() { |
65 | return { | 91 | return { |
66 | popoverVisible: false, | 92 | popoverVisible: false, |
67 | hasMessageAtMe: false | 93 | hasMessageAtMe: false, |
68 | } | 94 | }; |
69 | }, | 95 | }, |
70 | computed: { | 96 | computed: { |
71 | showUnreadCount() { | 97 | showUnreadCount() { |
72 | if (this.$store.getters.hidden) { | 98 | if (this.$store.getters.hidden) { |
73 | return this.conversation.unreadCount > 0 | 99 | return this.conversation.unreadCount > 0; |
74 | } | 100 | } |
75 | // 是否显示未读计数。当前会话和未读计数为0的会话,不显示。 | 101 | // 是否显示未读计数。当前会话和未读计数为0的会话,不显示。 |
76 | return ( | 102 | return ( |
77 | this.currentConversation.conversationID !== | 103 | this.currentConversation.conversationID !== |
78 | this.conversation.conversationID && this.conversation.unreadCount > 0 | 104 | this.conversation.conversationID && this.conversation.unreadCount > 0 |
79 | ) | 105 | ); |
80 | }, | 106 | }, |
81 | date() { | 107 | date() { |
82 | if ( | 108 | if ( |
83 | !this.conversation.lastMessage || | 109 | !this.conversation.lastMessage || |
84 | !this.conversation.lastMessage.lastTime | 110 | !this.conversation.lastMessage.lastTime |
85 | ) { | 111 | ) { |
86 | return '' | 112 | return ""; |
87 | } | 113 | } |
88 | const date = new Date(this.conversation.lastMessage.lastTime * 1000) | 114 | const date = new Date(this.conversation.lastMessage.lastTime * 1000); |
89 | if (isToday(date)) { | 115 | if (isToday(date)) { |
90 | return getTime(date) | 116 | return getTime(date); |
91 | } | 117 | } |
92 | return getDate(date) | 118 | return getDate(date); |
93 | }, | 119 | }, |
94 | avatar: function () { | 120 | avatar: function () { |
95 | switch (this.conversation.type) { | 121 | switch (this.conversation.type) { |
96 | case 'GROUP': | 122 | case "GROUP": |
97 | return this.conversation.groupProfile.avatar | 123 | return this.conversation.groupProfile.avatar; |
98 | case 'C2C': | 124 | case "C2C": |
99 | return this.conversation.userProfile.avatar | 125 | return this.conversation.userProfile.avatar; |
100 | default: | 126 | default: |
101 | return '' | 127 | return ""; |
102 | } | 128 | } |
103 | }, | 129 | }, |
104 | conversationName: function () { | 130 | conversationName: function () { |
105 | if (this.conversation.type === this.TIM.TYPES.CONV_C2C) { | 131 | if (this.conversation.type === this.TIM.TYPES.CONV_C2C) { |
106 | return this.conversation.userProfile.nick || this.conversation.userProfile.userID | 132 | return ( |
133 | this.conversation.userProfile.nick || | ||
134 | this.conversation.userProfile.userID | ||
135 | ); | ||
107 | } | 136 | } |
108 | if (this.conversation.type === this.TIM.TYPES.CONV_GROUP) { | 137 | if (this.conversation.type === this.TIM.TYPES.CONV_GROUP) { |
109 | return this.conversation.groupProfile.name || this.conversation.groupProfile.groupID | 138 | return ( |
139 | this.conversation.groupProfile.name || | ||
140 | this.conversation.groupProfile.groupID | ||
141 | ); | ||
110 | } | 142 | } |
111 | if (this.conversation.type === this.TIM.TYPES.CONV_SYSTEM) { | 143 | if (this.conversation.type === this.TIM.TYPES.CONV_SYSTEM) { |
112 | return '系统通知' | 144 | return "系统通知"; |
113 | } | 145 | } |
114 | return '' | 146 | return ""; |
115 | }, | 147 | }, |
116 | showGrayBadge() { | 148 | showGrayBadge() { |
117 | if (this.conversation.type !== this.TIM.TYPES.CONV_GROUP) { | 149 | if (this.conversation.type !== this.TIM.TYPES.CONV_GROUP) { |
118 | return false | 150 | return false; |
119 | } | 151 | } |
120 | return ( | 152 | return ( |
121 | this.conversation.groupProfile.selfInfo.messageRemindType === | 153 | this.conversation.groupProfile.selfInfo.messageRemindType === |
122 | 'AcceptNotNotify' | 154 | "AcceptNotNotify" |
123 | ) | 155 | ); |
124 | }, | 156 | }, |
125 | messageForShow() { | 157 | messageForShow() { |
126 | if (this.conversation.lastMessage.isRevoked) { | 158 | if (this.conversation.lastMessage.isRevoked) { |
127 | if (this.conversation.lastMessage.fromAccount === this.currentUserProfile.userID) { | 159 | if ( |
128 | return '你撤回了一条消息' | 160 | this.conversation.lastMessage.fromAccount === |
161 | this.currentUserProfile.userID | ||
162 | ) { | ||
163 | return "你撤回了一条消息"; | ||
129 | } | 164 | } |
130 | if (this.conversation.type === this.TIM.TYPES.CONV_C2C) { | 165 | if (this.conversation.type === this.TIM.TYPES.CONV_C2C) { |
131 | return '对方撤回了一条消息' | 166 | return "对方撤回了一条消息"; |
132 | } | 167 | } |
133 | return `${this.conversation.lastMessage.fromAccount}撤回了一条消息` | 168 | return `${ |
169 | this.conversation.lastMessage.nick || | ||
170 | this.conversation.lastMessage.fromAccount | ||
171 | }撤回了一条消息`; | ||
134 | } else { | 172 | } else { |
135 | switch (_.get(this.conversation.lastMessage, 'payload.data', 'other')) { | 173 | switch (_.get(this.conversation.lastMessage, "payload.data", "other")) { |
136 | case 'image': | 174 | case "image": |
137 | return '[图片]' | 175 | return "[图片]"; |
138 | case 'video': | 176 | case "video": |
139 | return '[视频]' | 177 | return "[视频]"; |
140 | default: | 178 | default: |
141 | return this.conversation.lastMessage.messageForShow | 179 | return this.conversation.lastMessage.messageForShow; |
142 | } | 180 | } |
143 | } | 181 | } |
144 | }, | 182 | }, |
145 | ...mapState({ | 183 | ...mapState({ |
146 | currentConversation: state => state.conversation.currentConversation, | 184 | currentConversation: (state) => state.conversation.currentConversation, |
147 | currentUserProfile: state => state.user.currentUserProfile | 185 | currentUserProfile: (state) => state.user.currentUserProfile, |
148 | }), | 186 | }), |
149 | ...mapGetters(['toAccount']) | 187 | ...mapGetters(["toAccount"]), |
150 | }, | 188 | }, |
151 | mounted() { | 189 | mounted() { |
152 | this.$bus.$on('new-messsage-at-me', event => { | 190 | this.$bus.$on("new-messsage-at-me", (event) => { |
153 | if ( | 191 | if ( |
154 | event.data.conversationID === this.conversation.conversationID && | 192 | event.data.conversationID === this.conversation.conversationID && |
155 | this.conversation.conversationID !== | 193 | this.conversation.conversationID !== |
156 | this.currentConversation.conversationID | 194 | this.currentConversation.conversationID |
157 | ) { | 195 | ) { |
158 | this.hasMessageAtMe = true | 196 | this.hasMessageAtMe = true; |
159 | } | 197 | } |
160 | }) | 198 | }); |
161 | }, | 199 | }, |
162 | methods: { | 200 | methods: { |
163 | selectConversation() { | 201 | selectConversation() { |
164 | if (this.conversation.conversationID !== this.currentConversation.conversationID) { | 202 | if ( |
203 | this.conversation.conversationID !== | ||
204 | this.currentConversation.conversationID | ||
205 | ) { | ||
165 | this.$store.dispatch( | 206 | this.$store.dispatch( |
166 | 'checkoutConversation', | 207 | "checkoutConversation", |
167 | this.conversation.conversationID | 208 | this.conversation.conversationID |
168 | ) | 209 | ); |
169 | } | 210 | } |
170 | }, | 211 | }, |
171 | deleteConversation(event) { | 212 | deleteConversation(event) { |
172 | // 停止冒泡,避免和点击会话的事件冲突 | 213 | // 停止冒泡,避免和点击会话的事件冲突 |
173 | event.stopPropagation() | 214 | event.stopPropagation(); |
174 | this.tim | 215 | this.tim |
175 | .deleteConversation(this.conversation.conversationID) | 216 | .deleteConversation(this.conversation.conversationID) |
176 | .then(() => { | 217 | .then(() => { |
177 | this.$store.commit('showMessage', { | 218 | this.$store.commit("showMessage", { |
178 | message: `会话【${this.conversationName}】删除成功!`, | 219 | message: `会话【${this.conversationName}】删除成功!`, |
179 | type: 'success' | 220 | type: "success", |
180 | }) | 221 | }); |
181 | this.popoverVisible = false | 222 | this.popoverVisible = false; |
182 | this.$store.commit('resetCurrentConversation') | 223 | this.$store.commit("resetCurrentConversation"); |
183 | }) | 224 | }) |
184 | .catch(error => { | 225 | .catch((error) => { |
185 | this.$store.commit('showMessage', { | 226 | this.$store.commit("showMessage", { |
186 | message: `会话【${this.conversationName}】删除失败!, error=${error.message}`, | 227 | message: `会话【${this.conversationName}】删除失败!, error=${error.message}`, |
187 | type: 'error' | 228 | type: "error", |
188 | }) | 229 | }); |
189 | this.popoverVisible = false | 230 | this.popoverVisible = false; |
190 | }) | 231 | }); |
191 | }, | 232 | }, |
192 | showContextMenu() { | 233 | showContextMenu() { |
193 | this.popoverVisible = true | 234 | this.popoverVisible = true; |
194 | }, | 235 | }, |
195 | }, | 236 | }, |
196 | watch: { | 237 | watch: { |
197 | currentConversation(next) { | 238 | currentConversation(next) { |
198 | if (next.conversationID === this.conversation.conversationID) { | 239 | if (next.conversationID === this.conversation.conversationID) { |
199 | this.hasMessageAtMe = false | 240 | this.hasMessageAtMe = false; |
200 | } | 241 | } |
201 | } | 242 | }, |
202 | } | 243 | }, |
203 | } | 244 | }; |
204 | </script> | 245 | </script> |
205 | 246 | ||
206 | <style lang="stylus" scoped> | 247 | <style lang="stylus" scoped> | ... | ... |
... | @@ -3,34 +3,42 @@ | ... | @@ -3,34 +3,42 @@ |
3 | <div> | 3 | <div> |
4 | <span class="label">ID:</span> | 4 | <span class="label">ID:</span> |
5 | {{ member.userID }} | 5 | {{ member.userID }} |
6 | <el-button v-if="showCancelBan" type="text" @click="cancelMute">取消禁言</el-button> | 6 | <el-button v-if="showCancelBan" type="text" @click="cancelMute" |
7 | >取消禁言</el-button | ||
8 | > | ||
7 | <el-popover title="禁言" v-model="popoverVisible" v-show="showBan"> | 9 | <el-popover title="禁言" v-model="popoverVisible" v-show="showBan"> |
8 | <el-input | 10 | <el-input |
9 | v-model="muteTime" | 11 | v-model="muteTime" |
10 | placeholder="请输入禁言时间" | 12 | placeholder="请输入禁言时间" |
11 | @keydown.enter.native="setGroupMemberMuteTime" | 13 | @keydown.enter.native="setGroupMemberMuteTime" |
12 | /> | 14 | /> |
13 | <el-button slot="reference" type="text" style="color:red;">禁言</el-button> | 15 | <el-button slot="reference" type="text" style="color: red" |
16 | >禁言</el-button | ||
17 | > | ||
14 | </el-popover> | 18 | </el-popover> |
15 | </div> | 19 | </div> |
16 | <div> | 20 | <div> |
17 | <span class="label">昵称:</span> | 21 | <span class="label">昵称:</span> |
18 | {{ member.nick || '暂无' }} | 22 | {{ member.nick || "暂无" }} |
19 | </div> | 23 | </div> |
20 | <div> | 24 | <div> |
21 | <span class="label">名片:</span> | 25 | <span class="label">名片:</span> |
22 | {{ member.nameCard || '暂无' }} | 26 | {{ member.nameCard || "暂无" }} |
23 | <el-popover title="修改群名片" v-model="nameCardPopoverVisible" v-show="showEditNameCard"> | 27 | <el-popover |
28 | title="修改群名片" | ||
29 | v-model="nameCardPopoverVisible" | ||
30 | v-show="showEditNameCard" | ||
31 | > | ||
24 | <el-input | 32 | <el-input |
25 | v-model="nameCard" | 33 | v-model="nameCard" |
26 | placeholder="请输入群名片" | 34 | placeholder="请输入群名片" |
27 | @keydown.enter.native="setGroupMemberNameCard" | 35 | @keydown.enter.native="setGroupMemberNameCard" |
28 | /> | 36 | /> |
29 | <i | 37 | <i |
30 | class="el-icon-edit" | 38 | class="el-icon-edit" |
31 | title="修改群名片" | 39 | title="修改群名片" |
32 | slot="reference" | 40 | slot="reference" |
33 | style="cursor:pointer; font-size:1.6rem;" | 41 | style="cursor: pointer; font-size: 1.6rem" |
34 | ></i> | 42 | ></i> |
35 | </el-popover> | 43 | </el-popover> |
36 | </div> | 44 | </div> |
... | @@ -42,119 +50,144 @@ | ... | @@ -42,119 +50,144 @@ |
42 | <span class="label">禁言至:</span> | 50 | <span class="label">禁言至:</span> |
43 | <span class="content">{{ muteUntil }}</span> | 51 | <span class="content">{{ muteUntil }}</span> |
44 | </div> | 52 | </div> |
45 | <el-button type="text" v-if="canChangeRole" @click="changeMemberRole"> | 53 | <!-- <el-button type="text" v-if="canChangeRole" @click="changeMemberRole">--> |
46 | {{ | 54 | <!-- {{--> |
47 | member.role === 'Admin' ? '取消管理员' : '设为管理员' | 55 | <!-- member.role === 'Admin' ? '取消管理员' : '设为管理员'--> |
48 | }} | 56 | <!-- }}--> |
49 | </el-button> | 57 | <!-- </el-button>--> |
50 | <!-- <el-button type="text" v-if="showKickout" style="color:red;" @click="kickoutGroupMember">踢出群组</el-button>--> | 58 | <!-- <el-button type="text" v-if="showKickout" style="color:red;" @click="kickoutGroupMember">踢出群组</el-button>--> |
51 | <el-button type="text" style="color:red;" @click="kickoutGroupMember">踢出群组</el-button> | 59 | <!-- <el-button type="text" style="color:red;" @click="kickoutGroupMember">踢出群组</el-button>--> |
52 | </div> | 60 | </div> |
53 | </template> | 61 | </template> |
54 | 62 | ||
55 | <script> | 63 | <script> |
56 | import {mapState} from 'vuex' | 64 | import { mapState } from "vuex"; |
57 | import {Popover} from 'element-ui' | 65 | import { Popover } from "element-ui"; |
58 | import {getFullDate} from '../../../utils/date' | 66 | import { getFullDate } from "../../../utils/date"; |
59 | import Helper from '../../../utils/helper' | 67 | import Helper from "../../../utils/helper"; |
60 | 68 | ||
61 | export default { | 69 | export default { |
62 | components: { | 70 | components: { |
63 | ElPopover: Popover | 71 | ElPopover: Popover, |
64 | }, | 72 | }, |
65 | props: ['member'], | 73 | props: ["member"], |
66 | filters: { | 74 | filters: { |
67 | role: val => val === 'Member' ? '成员' : (val === 'Admin' ? '管理员' : '群主') | 75 | role: (val) => |
76 | val === "Member" ? "成员" : val === "Admin" ? "管理员" : "群主", | ||
68 | }, | 77 | }, |
69 | data() { | 78 | data() { |
70 | return { | 79 | return { |
71 | muteTime: '', | 80 | muteTime: "", |
72 | popoverVisible: false, | 81 | popoverVisible: false, |
73 | nameCardPopoverVisible: false, | 82 | nameCardPopoverVisible: false, |
74 | nameCard: this.member.nameCard | 83 | nameCard: this.member.nameCard, |
75 | } | 84 | }; |
85 | }, | ||
86 | mounted() { | ||
87 | // 初始化监听器 | ||
88 | console.log("this.currentUserProfile is ", this.currentUserProfile); | ||
89 | console.log( | ||
90 | "this.currentConversation.groupProfile.selfInfo is ", | ||
91 | this.currentConversation.groupProfile.selfInfo | ||
92 | ); | ||
76 | }, | 93 | }, |
77 | computed: { | 94 | computed: { |
78 | ...mapState({ | 95 | ...mapState({ |
79 | currentConversation: state => state.conversation.currentConversation, | 96 | currentConversation: (state) => state.conversation.currentConversation, |
80 | currentUserProfile: state => state.user.currentUserProfile, | 97 | currentUserProfile: (state) => state.user.currentUserProfile, |
81 | current: state => state.current | 98 | current: (state) => state.current, |
82 | }), | 99 | }), |
83 | // 是否显示踢出群成员按钮 | 100 | // 是否显示踢出群成员按钮 |
84 | showKickout() { | 101 | showKickout() { |
85 | return (this.isOwner || this.isAdmin) && !this.isMine | 102 | return (this.isOwner || this.isAdmin) && !this.isMine; |
86 | }, | 103 | }, |
87 | isOwner() { | 104 | isOwner() { |
88 | return this.currentConversation.groupProfile.selfInfo.role === 'Owner' | 105 | return this.currentConversation.groupProfile.selfInfo.role === "Owner"; |
89 | }, | 106 | }, |
90 | isAdmin() { | 107 | isAdmin() { |
91 | return this.currentConversation.groupProfile.selfInfo.role === 'Admin' | 108 | let isA = false; |
109 | if (this.currentConversation.groupProfile.selfInfo.role === "Admin") { | ||
110 | isA = true; | ||
111 | } else if ( | ||
112 | this.currentUserProfile.userID.substr(0, 13) == "Administrator" && | ||
113 | this.currentUserProfile.nick == "超级管理员" | ||
114 | ) { | ||
115 | isA = true; | ||
116 | } | ||
117 | return isA; | ||
92 | }, | 118 | }, |
93 | isMine() { | 119 | isMine() { |
94 | return this.currentUserProfile.userID === this.member.userID | 120 | console.log("in isMine ", this.member.userID); |
121 | return this.currentUserProfile.userID === this.member.userID; | ||
95 | }, | 122 | }, |
96 | canChangeRole() { | 123 | canChangeRole() { |
97 | return ( | 124 | return ( |
98 | this.isOwner && | 125 | this.isOwner && |
99 | ['ChatRoom', 'Public'].includes(this.currentConversation.subType) | 126 | ["ChatRoom", "Public"].includes(this.currentConversation.subType) |
100 | ) | 127 | ); |
101 | }, | 128 | }, |
102 | changeRoleTitle() { | 129 | changeRoleTitle() { |
103 | if (!this.canChangeRole) { | 130 | if (!this.canChangeRole) { |
104 | return '' | 131 | return ""; |
105 | } | 132 | } |
106 | return this.isOwner && this.member.role === 'Admin' | 133 | return this.isOwner && this.member.role === "Admin" |
107 | ? '设为:Member' | 134 | ? "设为:Member" |
108 | : '设为:Admin' | 135 | : "设为:Admin"; |
109 | }, | 136 | }, |
110 | // 是否显示禁言时间 | 137 | // 是否显示禁言时间 |
111 | showMuteUntil() { | 138 | showMuteUntil() { |
112 | // 禁言时间小于当前时间 | 139 | // 禁言时间小于当前时间 |
113 | return this.member.muteUntil * 1000 > this.current | 140 | return this.member.muteUntil * 1000 > this.current; |
114 | }, | 141 | }, |
115 | // 是否显示取消禁言按钮 | 142 | // 是否显示取消禁言按钮 |
116 | showCancelBan() { | 143 | showCancelBan() { |
117 | if ( | 144 | if ( |
118 | this.showMuteUntil && | 145 | this.showMuteUntil && |
119 | this.currentConversation.type === this.TIM.TYPES.CONV_GROUP && | 146 | this.currentConversation.type === this.TIM.TYPES.CONV_GROUP && |
120 | !this.isMine | 147 | !this.isMine |
121 | ) { | 148 | ) { |
122 | return this.isOwner || this.isAdmin | 149 | return this.isOwner || this.isAdmin; |
123 | } | 150 | } |
124 | return false | 151 | return false; |
125 | }, | 152 | }, |
126 | // 是否显示禁言按钮 | 153 | // 是否显示禁言按钮 |
127 | showBan() { | 154 | showBan() { |
128 | if (this.currentConversation.type === this.TIM.TYPES.CONV_GROUP) { | 155 | if (this.currentConversation.type === this.TIM.TYPES.CONV_GROUP) { |
129 | return this.isOwner || this.isAdmin | 156 | return this.isOwner || this.isAdmin; |
130 | } | 157 | } |
131 | return false | 158 | return false; |
132 | }, | 159 | }, |
133 | // 是否显示编辑群名片按钮 | 160 | // 是否显示编辑群名片按钮 |
134 | showEditNameCard() { | 161 | showEditNameCard() { |
135 | return this.isOwner || this.isAdmin | 162 | return this.isOwner || this.isAdmin; |
136 | }, | 163 | }, |
137 | // 日期格式化后的禁言时间 | 164 | // 日期格式化后的禁言时间 |
138 | muteUntil() { | 165 | muteUntil() { |
139 | return getFullDate(new Date(this.member.muteUntil * 1000)) | 166 | return getFullDate(new Date(this.member.muteUntil * 1000)); |
140 | } | 167 | }, |
141 | }, | 168 | }, |
142 | methods: { | 169 | methods: { |
143 | kickoutGroupMember() { | 170 | kickoutGroupMember() { |
144 | Helper.groupMemberDelete(this.currentConversation.groupProfile.groupID, this.member.userID) | 171 | Helper.groupMemberDelete( |
145 | .then(() => { | 172 | this.currentConversation.groupProfile.groupID, |
146 | this.$store.commit('deleteGroupMember', this.member.userID) | 173 | this.member.userID |
147 | this.$store.commit('updateCurrentUnMemberList', [{ | 174 | ) |
175 | .then(() => { | ||
176 | this.$store.commit("deleteGroupMember", this.member.userID); | ||
177 | this.$store.commit("updateCurrentUnMemberList", [ | ||
178 | { | ||
148 | esm_id: this.member.userID, | 179 | esm_id: this.member.userID, |
149 | name: this.member.nick, | 180 | name: this.member.nick, |
150 | avatar: this.member.avatar | 181 | avatar: this.member.avatar, |
151 | }]) | 182 | }, |
152 | }).catch(error => { | 183 | ]); |
153 | this.$store.commit('showMessage', { | ||
154 | type: 'error', | ||
155 | message: error.message | ||
156 | }) | 184 | }) |
157 | }) | 185 | .catch((error) => { |
186 | this.$store.commit("showMessage", { | ||
187 | type: "error", | ||
188 | message: error.message, | ||
189 | }); | ||
190 | }); | ||
158 | // this.tim | 191 | // this.tim |
159 | // .deleteGroupMember({ | 192 | // .deleteGroupMember({ |
160 | // groupID: this.currentConversation.groupProfile.groupID, | 193 | // groupID: this.currentConversation.groupProfile.groupID, |
... | @@ -173,87 +206,92 @@ export default { | ... | @@ -173,87 +206,92 @@ export default { |
173 | }, | 206 | }, |
174 | changeMemberRole() { | 207 | changeMemberRole() { |
175 | if (!this.canChangeRole) { | 208 | if (!this.canChangeRole) { |
176 | return | 209 | return; |
177 | } | 210 | } |
178 | let currentRole = this.member.role | 211 | let currentRole = this.member.role; |
179 | this.tim | 212 | this.tim |
180 | .setGroupMemberRole({ | 213 | .setGroupMemberRole({ |
181 | groupID: this.currentConversation.groupProfile.groupID, | 214 | groupID: this.currentConversation.groupProfile.groupID, |
182 | userID: this.member.userID, | 215 | userID: this.member.userID, |
183 | role: currentRole === 'Admin' ? 'Member' : 'Admin' | 216 | role: currentRole === "Admin" ? "Member" : "Admin", |
184 | }) | 217 | }) |
185 | .catch(error => { | 218 | .catch((error) => { |
186 | this.$store.commit('showMessage', { | 219 | this.$store.commit("showMessage", { |
187 | type: 'error', | 220 | type: "error", |
188 | message: error.message | 221 | message: error.message, |
189 | }) | 222 | }); |
190 | }) | 223 | }); |
191 | }, | 224 | }, |
192 | setGroupMemberMuteTime() { | 225 | setGroupMemberMuteTime() { |
226 | // console.log('Number(this.muteTime) is ',Number(this.muteTime)) | ||
227 | let _muteTime = Number(this.muteTime) | ||
228 | if(_muteTime > 99999999) { | ||
229 | _muteTime = 99999999 | ||
230 | } | ||
193 | this.tim | 231 | this.tim |
194 | .setGroupMemberMuteTime({ | 232 | .setGroupMemberMuteTime({ |
195 | groupID: this.currentConversation.groupProfile.groupID, | 233 | groupID: this.currentConversation.groupProfile.groupID, |
196 | userID: this.member.userID, | 234 | userID: this.member.userID, |
197 | muteTime: Number(this.muteTime) | 235 | muteTime: _muteTime, |
198 | }) | 236 | }) |
199 | .then(() => { | 237 | .then(() => { |
200 | this.muteTime = '' | 238 | this.muteTime = ""; |
201 | this.popoverVisible = false | 239 | this.popoverVisible = false; |
202 | }) | 240 | }) |
203 | .catch(error => { | 241 | .catch((error) => { |
204 | this.$store.commit('showMessage', { | 242 | this.$store.commit("showMessage", { |
205 | type: 'error', | 243 | type: "error", |
206 | message: error.message | 244 | message: error.message, |
207 | }) | 245 | }); |
208 | }) | 246 | }); |
209 | }, | 247 | }, |
210 | // 取消禁言 | 248 | // 取消禁言 |
211 | cancelMute() { | 249 | cancelMute() { |
212 | this.tim | 250 | this.tim |
213 | .setGroupMemberMuteTime({ | 251 | .setGroupMemberMuteTime({ |
214 | groupID: this.currentConversation.groupProfile.groupID, | 252 | groupID: this.currentConversation.groupProfile.groupID, |
215 | userID: this.member.userID, | 253 | userID: this.member.userID, |
216 | muteTime: 0 | 254 | muteTime: 0, |
217 | }) | 255 | }) |
218 | .then(() => { | 256 | .then(() => { |
219 | this.muteTime = '' | 257 | this.muteTime = ""; |
220 | }) | 258 | }) |
221 | .catch(error => { | 259 | .catch((error) => { |
222 | this.$store.commit('showMessage', { | 260 | this.$store.commit("showMessage", { |
223 | type: 'error', | 261 | type: "error", |
224 | message: error.message | 262 | message: error.message, |
225 | }) | 263 | }); |
226 | }) | 264 | }); |
227 | }, | 265 | }, |
228 | setGroupMemberNameCard() { | 266 | setGroupMemberNameCard() { |
229 | if (this.nameCard.trim().length === 0) { | 267 | if (this.nameCard.trim().length === 0) { |
230 | this.$store.commit('showMessage', { | 268 | this.$store.commit("showMessage", { |
231 | message: '不能设置空的群名片', | 269 | message: "不能设置空的群名片", |
232 | type: 'warning' | 270 | type: "warning", |
233 | }) | 271 | }); |
234 | return | 272 | return; |
235 | } | 273 | } |
236 | this.tim | 274 | this.tim |
237 | .setGroupMemberNameCard({ | 275 | .setGroupMemberNameCard({ |
238 | groupID: this.currentConversation.groupProfile.groupID, | 276 | groupID: this.currentConversation.groupProfile.groupID, |
239 | userID: this.member.userID, | 277 | userID: this.member.userID, |
240 | nameCard: this.nameCard | 278 | nameCard: this.nameCard, |
241 | }) | 279 | }) |
242 | .then(() => { | 280 | .then(() => { |
243 | this.nameCardPopoverVisible = false | 281 | this.nameCardPopoverVisible = false; |
244 | this.$store.commit('showMessage', { | 282 | this.$store.commit("showMessage", { |
245 | message: '修改成功' | 283 | message: "修改成功", |
246 | }) | 284 | }); |
247 | }) | 285 | }) |
248 | .catch(error => { | 286 | .catch((error) => { |
249 | this.$store.commit('showMessage', { | 287 | this.$store.commit("showMessage", { |
250 | type: 'error', | 288 | type: "error", |
251 | message: error.message | 289 | message: error.message, |
252 | }) | 290 | }); |
253 | }) | 291 | }); |
254 | } | 292 | }, |
255 | } | 293 | }, |
256 | } | 294 | }; |
257 | </script> | 295 | </script> |
258 | 296 | ||
259 | <style lang="stylus" scoped> | 297 | <style lang="stylus" scoped> | ... | ... |
1 | <template> | 1 | <template> |
2 | <div class="group-member-list-wrapper"> | 2 | <div class="group-member-list-wrapper"> |
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" |
5 | <popover v-show="currentUnMemberList.length !== 0" v-model="addGroupMemberVisible"> | 5 | >群成员:{{ currentConversation.groupProfile.memberCount }}</span |
6 | <add-group-member :group="currentConversation.groupProfile.groupID"/> | 6 | > |
7 | <popover | ||
8 | v-show="currentUnMemberList.length !== 0" | ||
9 | v-model="addGroupMemberVisible" | ||
10 | > | ||
11 | <add-group-member :group="currentConversation.groupProfile.groupID" /> | ||
7 | <div slot="reference" class="btn-add-member" title="添加群成员"> | 12 | <div slot="reference" class="btn-add-member" title="添加群成员"> |
8 | <span class="tim-icon-friend-add"></span> | 13 | <span class="tim-icon-friend-add"></span> |
9 | </div> | 14 | </div> |
... | @@ -13,13 +18,24 @@ | ... | @@ -13,13 +18,24 @@ |
13 | <div class="group-member-list"> | 18 | <div class="group-member-list"> |
14 | <div v-for="member in members" :key="member.userID"> | 19 | <div v-for="member in members" :key="member.userID"> |
15 | <popover placement="right" :key="member.userID"> | 20 | <popover placement="right" :key="member.userID"> |
16 | <group-member-info :member="member"/> | 21 | <group-member-info :member="member" /> |
17 | <div slot="reference" class="group-member" @click="currentMemberID = member.userID"> | 22 | <div |
18 | <avatar :title=getGroupMemberAvatarText(member.role) :src="member.avatar"/> | 23 | slot="reference" |
24 | class="group-member" | ||
25 | @click="currentMemberID = member.userID" | ||
26 | > | ||
27 | <avatar | ||
28 | :title="getGroupMemberAvatarText(member.role)" | ||
29 | :src="member.avatar" | ||
30 | /> | ||
19 | <div class="member-name text-ellipsis"> | 31 | <div class="member-name text-ellipsis"> |
20 | <span v-if="member.nameCard" :title=member.nameCard>{{ member.nameCard }}</span> | 32 | <span v-if="member.nameCard" :title="member.nameCard">{{ |
21 | <span v-else-if="member.nick" :title=member.nick>{{ member.nick }}</span> | 33 | member.nameCard |
22 | <span v-else :title=member.userID>{{ member.userID }}</span> | 34 | }}</span> |
35 | <span v-else-if="member.nick" :title="member.nick">{{ | ||
36 | member.nick | ||
37 | }}</span> | ||
38 | <span v-else :title="member.userID">{{ member.userID }}</span> | ||
23 | </div> | 39 | </div> |
24 | </div> | 40 | </div> |
25 | </popover> | 41 | </popover> |
... | @@ -27,66 +43,71 @@ | ... | @@ -27,66 +43,71 @@ |
27 | </div> | 43 | </div> |
28 | </div> | 44 | </div> |
29 | <div class="more"> | 45 | <div class="more"> |
30 | <el-button v-if="showLoadMore" type="text" | 46 | <el-button v-if="showLoadMore" type="text" @click="loadMore" |
31 | @click="loadMore">查看更多 | 47 | >查看更多 |
32 | </el-button> | 48 | </el-button> |
33 | </div> | 49 | </div> |
34 | </div> | 50 | </div> |
35 | </template> | 51 | </template> |
36 | 52 | ||
37 | <script> | 53 | <script> |
38 | import {Popover} from 'element-ui' | 54 | import { Popover } from "element-ui"; |
39 | import {mapState} from 'vuex' | 55 | import { mapState } from "vuex"; |
40 | import AddGroupMember from './add-group-member.vue' | 56 | import AddGroupMember from "./add-group-member.vue"; |
41 | import GroupMemberInfo from './group-member-info.vue' | 57 | import GroupMemberInfo from "./group-member-info.vue"; |
42 | 58 | ||
43 | export default { | 59 | export default { |
44 | data() { | 60 | data() { |
45 | return { | 61 | return { |
46 | addGroupMemberVisible: false, | 62 | addGroupMemberVisible: false, |
47 | addGroupMemberList: [], | 63 | addGroupMemberList: [], |
48 | currentMemberID: '', | 64 | currentMemberID: "", |
49 | count: 30 // 显示的群成员数量 | 65 | count: 30, // 显示的群成员数量 |
50 | } | 66 | }; |
51 | }, | 67 | }, |
52 | props: ['groupProfile'], | 68 | props: ["groupProfile"], |
53 | components: { | 69 | components: { |
54 | Popover, | 70 | Popover, |
55 | AddGroupMember, | 71 | AddGroupMember, |
56 | GroupMemberInfo | 72 | GroupMemberInfo, |
57 | }, | 73 | }, |
58 | computed: { | 74 | computed: { |
59 | ...mapState({ | 75 | ...mapState({ |
60 | currentConversation: state => state.conversation.currentConversation, | 76 | currentConversation: (state) => state.conversation.currentConversation, |
61 | currentMemberList: state => state.group.currentMemberList, | 77 | currentMemberList: (state) => state.group.currentMemberList, |
62 | currentUnMemberList: state => state.group.currentUnMemberList | 78 | currentUnMemberList: (state) => state.group.currentUnMemberList, |
63 | }), | 79 | }), |
64 | showLoadMore() { | 80 | showLoadMore() { |
65 | return this.members.length < this.groupProfile.memberCount | 81 | return this.members.length < this.groupProfile.memberCount; |
66 | }, | 82 | }, |
67 | members() { | 83 | members() { |
68 | return this.currentMemberList.slice(0, this.count) | 84 | console.log( |
69 | } | 85 | "currentMemberList is ", |
86 | this.currentMemberList.slice(0, this.count) | ||
87 | ); | ||
88 | return this.currentMemberList.slice(0, this.count); | ||
89 | }, | ||
70 | }, | 90 | }, |
71 | methods: { | 91 | methods: { |
72 | getGroupMemberAvatarText(role) { | 92 | getGroupMemberAvatarText(role) { |
73 | switch (role) { | 93 | switch (role) { |
74 | case 'Owner': | 94 | case "Owner": |
75 | return '群主' | 95 | return "群主"; |
76 | case 'Admin': | 96 | case "Admin": |
77 | return '管理员' | 97 | return "管理员"; |
78 | default: | 98 | default: |
79 | return '群成员' | 99 | return "群成员"; |
80 | } | 100 | } |
81 | }, | 101 | }, |
82 | loadMore() { | 102 | loadMore() { |
83 | this.$store.dispatch('getGroupMemberList', this.groupProfile.groupID) | 103 | this.$store |
84 | .then(() => { | 104 | .dispatch("getGroupMemberList", this.groupProfile.groupID) |
85 | this.count += 30 | 105 | .then(() => { |
86 | }) | 106 | this.count += 30; |
107 | }); | ||
87 | }, | 108 | }, |
88 | } | 109 | }, |
89 | } | 110 | }; |
90 | </script> | 111 | </script> |
91 | 112 | ||
92 | <style lang="stylus" scoped> | 113 | <style lang="stylus" scoped> |
... | @@ -167,6 +188,4 @@ export default { | ... | @@ -167,6 +188,4 @@ export default { |
167 | // text-align: center; | 188 | // text-align: center; |
168 | // line-height: 30px; | 189 | // line-height: 30px; |
169 | // } | 190 | // } |
170 | |||
171 | |||
172 | </style> | 191 | </style> | ... | ... |
1 | <template> | 1 | <template> |
2 | <div class="chat-bubble" @mousedown.stop @contextmenu.prevent> | 2 | <div class="chat-bubble" @mousedown.stop @contextmenu.prevent> |
3 | <el-dropdown trigger="" ref="dropdown" v-if="!message.isRevoked" @command="handleCommand"> | 3 | <el-dropdown |
4 | trigger="" | ||
5 | ref="dropdown" | ||
6 | v-if="!message.isRevoked" | ||
7 | @command="handleCommand" | ||
8 | > | ||
4 | <div style="display: flex"> | 9 | <div style="display: flex"> |
5 | <div v-if="isMine && messageReadByPeer" class="message-status"> | 10 | <div v-if="isMine && messageReadByPeer" class="message-status"> |
6 | <span>{{messageReadByPeer}}</span> | 11 | <span>{{ messageReadByPeer }}</span> |
7 | </div> | 12 | </div> |
8 | <div class="message-content" :class="bubbleStyle"> | 13 | <div class="message-content" :class="bubbleStyle"> |
9 | <slot></slot> | 14 | <slot></slot> |
... | @@ -15,136 +20,165 @@ | ... | @@ -15,136 +20,165 @@ |
15 | </el-dropdown-menu> | 20 | </el-dropdown-menu> |
16 | </el-dropdown> | 21 | </el-dropdown> |
17 | <div class="group-tip-element-wrapper" v-if="message.isRevoked"> | 22 | <div class="group-tip-element-wrapper" v-if="message.isRevoked"> |
18 | {{text}} | 23 | {{ text }} |
19 | <el-button type="text" size="mini" class="edit-button" v-show="isEdit" @click="reEdit"> 重新编辑</el-button> | 24 | <el-button |
25 | type="text" | ||
26 | size="mini" | ||
27 | class="edit-button" | ||
28 | v-show="isEdit" | ||
29 | @click="reEdit" | ||
30 | > 重新编辑</el-button | ||
31 | > | ||
20 | </div> | 32 | </div> |
21 | </div> | 33 | </div> |
22 | </template> | 34 | </template> |
23 | 35 | ||
24 | <script> | 36 | <script> |
25 | export default { | 37 | export default { |
26 | name: 'MessageBubble', | 38 | name: "MessageBubble", |
27 | data() { | 39 | data() { |
28 | return { | 40 | return { |
29 | isTimeout: false | 41 | isTimeout: false, |
30 | } | 42 | }; |
31 | }, | 43 | }, |
32 | props: { | 44 | props: { |
33 | isMine: { | 45 | isMine: { |
34 | type: Boolean | 46 | type: Boolean, |
35 | }, | 47 | }, |
36 | isNew: { | 48 | isNew: { |
37 | type: Boolean | 49 | type: Boolean, |
38 | }, | 50 | }, |
39 | message: { | 51 | message: { |
40 | type: Object, | 52 | type: Object, |
41 | required: true | 53 | required: true, |
42 | } | 54 | }, |
43 | }, | 55 | }, |
44 | created() { | 56 | created() { |
45 | this.isTimeoutHandler() | 57 | this.isTimeoutHandler(); |
46 | }, | 58 | }, |
47 | mounted() { | 59 | mounted() { |
48 | if (this.$refs.dropdown && this.$refs.dropdown.$el) { | 60 | if (this.$refs.dropdown && this.$refs.dropdown.$el) { |
49 | this.$refs.dropdown.$el.addEventListener('mousedown', this.handleDropDownMousedown) | 61 | this.$refs.dropdown.$el.addEventListener( |
62 | "mousedown", | ||
63 | this.handleDropDownMousedown | ||
64 | ); | ||
50 | } | 65 | } |
51 | }, | 66 | }, |
52 | beforeDestroy() { | 67 | beforeDestroy() { |
53 | if (this.$refs.dropdown && this.$refs.dropdown.$el) { | 68 | if (this.$refs.dropdown && this.$refs.dropdown.$el) { |
54 | this.$refs.dropdown.$el.removeEventListener('mousedown', this.handleDropDownMousedown) | 69 | this.$refs.dropdown.$el.removeEventListener( |
70 | "mousedown", | ||
71 | this.handleDropDownMousedown | ||
72 | ); | ||
55 | } | 73 | } |
56 | }, | 74 | }, |
57 | computed: { | 75 | computed: { |
58 | bubbleStyle() { | 76 | bubbleStyle() { |
59 | let classString = '' | 77 | let classString = ""; |
60 | if (this.isMine) { | 78 | if (this.isMine) { |
61 | classString += 'message-send' | 79 | classString += "message-send"; |
62 | } else { | 80 | } else { |
63 | classString += 'message-received' | 81 | classString += "message-received"; |
64 | } | 82 | } |
65 | if (this.isNew) { | 83 | if (this.isNew) { |
66 | classString += 'new' | 84 | classString += "new"; |
67 | } | 85 | } |
68 | return classString | 86 | return classString; |
69 | }, | 87 | }, |
70 | text() { | 88 | text() { |
71 | if (this.message.conversationType === this.TIM.TYPES.CONV_C2C && !this.isMine) { | 89 | if ( |
72 | return '对方撤回了一条消息' | 90 | this.message.conversationType === this.TIM.TYPES.CONV_C2C && |
91 | !this.isMine | ||
92 | ) { | ||
93 | return "对方撤回了一条消息"; | ||
73 | } | 94 | } |
74 | if (this.message.conversationType === this.TIM.TYPES.CONV_GROUP && !this.isMine) { | 95 | if ( |
75 | return `${this.message.from}撤回了一条消息` | 96 | this.message.conversationType === this.TIM.TYPES.CONV_GROUP && |
97 | !this.isMine | ||
98 | ) { | ||
99 | return `${this.message.nick || this.message.from}撤回了一条消息`; | ||
76 | } | 100 | } |
77 | return '你撤回了一条消息' | 101 | return "你撤回了一条消息"; |
78 | }, | 102 | }, |
79 | messageReadByPeer() { | 103 | messageReadByPeer() { |
80 | if (this.message.status !== 'success') { | 104 | if (this.message.status !== "success") { |
81 | return false | 105 | return false; |
82 | } | 106 | } |
83 | if (this.message.conversationType === this.TIM.TYPES.CONV_C2C && this.message.isPeerRead) { | 107 | if ( |
84 | return '已读' | 108 | this.message.conversationType === this.TIM.TYPES.CONV_C2C && |
109 | this.message.isPeerRead | ||
110 | ) { | ||
111 | return "已读"; | ||
85 | } | 112 | } |
86 | if (this.message.conversationType === this.TIM.TYPES.CONV_C2C && !this.message.isPeerRead) { | 113 | if ( |
87 | return '未读' | 114 | this.message.conversationType === this.TIM.TYPES.CONV_C2C && |
115 | !this.message.isPeerRead | ||
116 | ) { | ||
117 | return "未读"; | ||
88 | } | 118 | } |
89 | return '' | 119 | return ""; |
90 | }, | 120 | }, |
91 | isEdit() { | 121 | isEdit() { |
92 | if (!this.isMine) { | 122 | if (!this.isMine) { |
93 | return false | 123 | return false; |
94 | } | 124 | } |
95 | if (this.message.type !== this.TIM.TYPES.MSG_TEXT) { | 125 | if (this.message.type !== this.TIM.TYPES.MSG_TEXT) { |
96 | return false | 126 | return false; |
97 | } | 127 | } |
98 | if (this.isTimeout) { | 128 | if (this.isTimeout) { |
99 | return false | 129 | return false; |
100 | } | 130 | } |
101 | return true | 131 | return true; |
102 | }, | 132 | }, |
103 | }, | 133 | }, |
104 | methods: { | 134 | methods: { |
105 | handleDropDownMousedown(e) { | 135 | handleDropDownMousedown(e) { |
106 | if (!this.isMine || this.isTimeout) { | 136 | if (!this.isMine || this.isTimeout) { |
107 | return | 137 | return; |
108 | } | 138 | } |
109 | if (e.buttons === 2) { | 139 | if (e.buttons === 2) { |
110 | if (this.$refs.dropdown.visible) { | 140 | if (this.$refs.dropdown.visible) { |
111 | this.$refs.dropdown.hide() | 141 | this.$refs.dropdown.hide(); |
112 | } else { | 142 | } else { |
113 | this.$refs.dropdown.show() | 143 | this.$refs.dropdown.show(); |
114 | } | 144 | } |
115 | } | 145 | } |
116 | }, | 146 | }, |
117 | handleCommand(command) { | 147 | handleCommand(command) { |
118 | switch (command) { | 148 | switch (command) { |
119 | case 'revoke': | 149 | case "revoke": |
120 | this.tim.revokeMessage(this.message).then(() => { | 150 | this.tim |
121 | this.isTimeoutHandler() | 151 | .revokeMessage(this.message) |
122 | }).catch((err) => { | 152 | .then(() => { |
123 | this.$store.commit('showMessage', { | 153 | this.isTimeoutHandler(); |
124 | message: err, | ||
125 | type: 'warning' | ||
126 | }) | 154 | }) |
127 | }) | 155 | .catch((err) => { |
128 | break | 156 | this.$store.commit("showMessage", { |
129 | case 'delete': | 157 | message: err, |
130 | break | 158 | type: "warning", |
159 | }); | ||
160 | }); | ||
161 | break; | ||
162 | case "delete": | ||
163 | break; | ||
131 | default: | 164 | default: |
132 | break | 165 | break; |
133 | } | 166 | } |
134 | }, | 167 | }, |
135 | isTimeoutHandler() { // 从发送消息时间开始算起,两分钟内可以编辑 | 168 | isTimeoutHandler() { |
136 | let now = new Date() | 169 | // 从发送消息时间开始算起,两分钟内可以编辑 |
170 | let now = new Date(); | ||
137 | if (parseInt(now.getTime() / 1000) - this.message.time > 2 * 60) { | 171 | if (parseInt(now.getTime() / 1000) - this.message.time > 2 * 60) { |
138 | this.isTimeout = true | 172 | this.isTimeout = true; |
139 | return | 173 | return; |
140 | } | 174 | } |
141 | setTimeout(this.isTimeoutHandler, 1000) | 175 | setTimeout(this.isTimeoutHandler, 1000); |
142 | }, | 176 | }, |
143 | reEdit() { | 177 | reEdit() { |
144 | this.$bus.$emit('reEditMessage', this.message.payload.text) | 178 | this.$bus.$emit("reEditMessage", this.message.payload.text); |
145 | } | 179 | }, |
146 | } | 180 | }, |
147 | } | 181 | }; |
148 | </script> | 182 | </script> |
149 | 183 | ||
150 | <style lang="stylus" scoped> | 184 | <style lang="stylus" scoped> | ... | ... |
1 | <template> | ||
2 | <message-bubble :isMine="isMine" :message="message"> | ||
3 | <div class="m-e-content" @click="goAudioDetail"> | ||
4 | <img :src="coverUrl" class="covor" /> | ||
5 | <span class="title" v-if="name">{{ name }}</span> | ||
6 | <span class="title" v-else>未命名音乐文件</span> | ||
7 | <!-- <div style="position: absolute; right: 15px"> | ||
8 | <u-icon name="list" color="#fff" size="32"></u-icon> | ||
9 | |||
10 | </div> --> | ||
11 | </div> | ||
12 | </message-bubble> | ||
13 | <!-- <div class="chat-bubble"> | ||
14 | <div class="message-content" :class="isMine ? 'message-send' : 'message-received'"> | ||
15 | <template v-for="(item, index) in contentList"> | ||
16 | <span :key="index" v-if="item.name === 'text'">{{ item.text }}</span> | ||
17 | <img v-else-if="item.name === 'img'" :src="item.src" width="20px" height="20px" :key="index"/> | ||
18 | </template> | ||
19 | </div> | ||
20 | </div> --> | ||
21 | </template> | ||
22 | |||
23 | <script> | ||
24 | import MessageBubble from "../message-bubble"; | ||
25 | |||
26 | export default { | ||
27 | name: "AudioElement", | ||
28 | components: { | ||
29 | MessageBubble, | ||
30 | }, | ||
31 | props: { | ||
32 | payload: { | ||
33 | type: Object, | ||
34 | required: true, | ||
35 | }, | ||
36 | message: { | ||
37 | type: Object, | ||
38 | required: true, | ||
39 | }, | ||
40 | isMine: { | ||
41 | type: Boolean, | ||
42 | }, | ||
43 | }, | ||
44 | methods: { | ||
45 | goAudioDetail() { | ||
46 | console.log("in goAudioDetail"); | ||
47 | // this.$emit("goAudioDetail"); | ||
48 | }, | ||
49 | // previewImage() { | ||
50 | // uni.previewImage({ | ||
51 | // current: 0, | ||
52 | // urls: [this.imagePath] | ||
53 | // }); | ||
54 | // }, | ||
55 | }, | ||
56 | computed: { | ||
57 | audioUrl() { | ||
58 | return this.payload.description; | ||
59 | }, | ||
60 | coverUrl() { | ||
61 | try { | ||
62 | let res = JSON.parse(this.payload.extension); | ||
63 | return res.cover_url; | ||
64 | } catch (e) {} | ||
65 | return ""; | ||
66 | }, | ||
67 | name() { | ||
68 | try { | ||
69 | let res = JSON.parse(this.payload.extension); | ||
70 | return res.name; | ||
71 | } catch (e) {} | ||
72 | return ""; | ||
73 | }, | ||
74 | }, | ||
75 | |||
76 | mounted() { | ||
77 | console.log("this.message is ", this.message); | ||
78 | }, | ||
79 | }; | ||
80 | </script> | ||
81 | |||
82 | <style lang="stylus" scoped> | ||
83 | .covor{ | ||
84 | width: 80px; | ||
85 | height: 80px; | ||
86 | // border-top-left-radius: 10px; | ||
87 | // border-bottom-left-radius: 10px; | ||
88 | border-radius:6px; | ||
89 | } | ||
90 | .m-e-content{ | ||
91 | display: flex; | ||
92 | flex-direction: row; | ||
93 | align-items: center; | ||
94 | width:250px; | ||
95 | height: 80px | ||
96 | // background-color: #2D2F39; | ||
97 | position: relative; | ||
98 | } | ||
99 | |||
100 | .title{ | ||
101 | width: 150px; | ||
102 | // color: #E9E9EA; | ||
103 | font-size: 13px; | ||
104 | overflow: hidden; | ||
105 | |||
106 | text-overflow: ellipsis; | ||
107 | /* #ifndef APP-PLUS-NVUE */ | ||
108 | display: -webkit-box; | ||
109 | word-break: break-all; | ||
110 | -webkit-box-orient: vertical; | ||
111 | -webkit-line-clamp: 2; | ||
112 | /* #endif */ | ||
113 | /* #ifdef APP-PLUS-NVUE */ | ||
114 | lines: 2; | ||
115 | text-overflow:ellipsis; | ||
116 | /* #endif */ | ||
117 | margin-left: 15px | ||
118 | |||
119 | } | ||
120 | </style> |
1 | <template> | 1 | <template> |
2 | <div class="custom-element-wrapper"> | 2 | <div class="custom-element-wrapper"> |
3 | <image-element | 3 | <image-element |
4 | v-if="this.payload.data === 'image'" | 4 | v-if="this.payload.data === 'image'" |
5 | :isMine=isMine | 5 | :isMine="isMine" |
6 | :payload="Object.assign(message.payload,{ imageInfoArray:[ { url: message.payload.description } ] })" | 6 | :payload=" |
7 | :message="message"/> | 7 | Object.assign(message.payload, { |
8 | imageInfoArray: [{ url: message.payload.description }], | ||
9 | }) | ||
10 | " | ||
11 | :message="message" | ||
12 | /> | ||
8 | <video-element | 13 | <video-element |
9 | v-else-if="this.payload.data === 'video'" | 14 | v-else-if="this.payload.data === 'video'" |
10 | :isMine="isMine" | 15 | :isMine="isMine" |
11 | :payload="Object.assign(message.payload,{ videoUrl: message.payload.description })" | 16 | :payload=" |
12 | :message="message" | 17 | Object.assign(message.payload, { |
18 | videoUrl: message.payload.description, | ||
19 | }) | ||
20 | " | ||
21 | :message="message" | ||
22 | /> | ||
23 | <audio-element | ||
24 | v-else-if="this.payload.data === 'audio'" | ||
25 | :isMine="isMine" | ||
26 | :payload="message.payload" | ||
27 | :message="message" | ||
13 | /> | 28 | /> |
14 | <template v-else> | 29 | <template v-else> |
15 | <message-bubble :isMine=isMine :message=message> | 30 | <message-bubble :isMine="isMine" :message="message"> |
16 | <message-group-live-status v-if="text.isFromGroupLive && text.isFromGroupLive === 1" :liveInfo='text'/> | 31 | <message-group-live-status |
32 | v-if="text.isFromGroupLive && text.isFromGroupLive === 1" | ||
33 | :liveInfo="text" | ||
34 | /> | ||
17 | <template v-else>{{ text }}</template> | 35 | <template v-else>{{ text }}</template> |
18 | </message-bubble> | 36 | </message-bubble> |
19 | </template> | 37 | </template> |
... | @@ -21,74 +39,79 @@ | ... | @@ -21,74 +39,79 @@ |
21 | </template> | 39 | </template> |
22 | 40 | ||
23 | <script> | 41 | <script> |
24 | import {mapState} from 'vuex' | 42 | import { mapState } from "vuex"; |
25 | import MessageBubble from '../message-bubble' | 43 | import MessageBubble from "../message-bubble"; |
26 | import MessageGroupLiveStatus from '../message-group-live-status' | 44 | import MessageGroupLiveStatus from "../message-group-live-status"; |
27 | import ImageElement from '../message-elements/image-element.vue' | 45 | import ImageElement from "../message-elements/image-element.vue"; |
28 | import VideoElement from './video-element' | 46 | import VideoElement from "./video-element"; |
29 | 47 | import AudioElement from "./audio-element.vue"; | |
30 | export default { | 48 | export default { |
31 | name: 'CustomElement', | 49 | name: "CustomElement", |
32 | props: { | 50 | props: { |
33 | payload: { | 51 | payload: { |
34 | type: Object, | 52 | type: Object, |
35 | required: true | 53 | required: true, |
36 | }, | 54 | }, |
37 | message: { | 55 | message: { |
38 | type: Object, | 56 | type: Object, |
39 | required: true | 57 | required: true, |
40 | }, | 58 | }, |
41 | isMine: { | 59 | isMine: { |
42 | type: Boolean | 60 | type: Boolean, |
43 | } | 61 | }, |
44 | }, | 62 | }, |
45 | components: { | 63 | components: { |
46 | VideoElement, | 64 | VideoElement, |
47 | MessageBubble, | 65 | MessageBubble, |
48 | MessageGroupLiveStatus, | 66 | MessageGroupLiveStatus, |
49 | ImageElement, | 67 | ImageElement, |
68 | AudioElement, | ||
50 | }, | 69 | }, |
51 | computed: { | 70 | computed: { |
52 | ...mapState({ | 71 | ...mapState({ |
53 | currentUserProfile: state => state.user.currentUserProfile | 72 | currentUserProfile: (state) => state.user.currentUserProfile, |
54 | }), | 73 | }), |
55 | text() { | 74 | text() { |
56 | return this.translateCustomMessage(this.payload) | 75 | return this.translateCustomMessage(this.payload); |
57 | }, | 76 | }, |
58 | rate() { | 77 | rate() { |
59 | return parseInt(this.payload.description) | 78 | return parseInt(this.payload.description); |
60 | } | 79 | }, |
61 | }, | 80 | }, |
62 | methods: { | 81 | methods: { |
63 | guid() { | 82 | guid() { |
64 | return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) { | 83 | return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace( |
65 | let r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8) | 84 | /[xy]/g, |
66 | return v.toString(16) | 85 | function (c) { |
67 | }) | 86 | let r = (Math.random() * 16) | 0, |
87 | v = c == "x" ? r : (r & 0x3) | 0x8; | ||
88 | return v.toString(16); | ||
89 | } | ||
90 | ); | ||
68 | }, | 91 | }, |
69 | translateCustomMessage(payload) { | 92 | translateCustomMessage(payload) { |
70 | let videoPayload = {} | 93 | let videoPayload = {}; |
71 | try { | 94 | try { |
72 | videoPayload = JSON.parse(payload.data) | 95 | videoPayload = JSON.parse(payload.data); |
73 | } catch (e) { | 96 | } catch (e) { |
74 | videoPayload = {} | 97 | videoPayload = {}; |
75 | } | 98 | } |
76 | if (payload.data === 'group_create') { | 99 | if (payload.data === "group_create") { |
77 | return `${payload.extension}` | 100 | return `${payload.extension}`; |
78 | } | 101 | } |
79 | if (videoPayload.roomId) { | 102 | if (videoPayload.roomId) { |
80 | videoPayload.roomId = videoPayload.roomId.toString() | 103 | videoPayload.roomId = videoPayload.roomId.toString(); |
81 | videoPayload.isFromGroupLive = 1 | 104 | videoPayload.isFromGroupLive = 1; |
82 | return videoPayload | 105 | return videoPayload; |
83 | } | 106 | } |
84 | if (payload.text) { | 107 | if (payload.text) { |
85 | return payload.text | 108 | return payload.text; |
86 | } else { | 109 | } else { |
87 | return '[自定义消息]' | 110 | return "[自定义消息]"; |
88 | } | 111 | } |
89 | }, | 112 | }, |
90 | } | 113 | }, |
91 | } | 114 | }; |
92 | </script> | 115 | </script> |
93 | 116 | ||
94 | <style lang="stylus" scoped> | 117 | <style lang="stylus" scoped> | ... | ... |
1 | <template> | 1 | <template> |
2 | <div id="message-send-box-wrapper" :style="focus ? {'backgroundColor': 'white'} : {}" @drop="dropHandler"> | 2 | <div |
3 | id="message-send-box-wrapper" | ||
4 | :style="focus ? { backgroundColor: 'white' } : {}" | ||
5 | @drop="dropHandler" | ||
6 | > | ||
3 | <div class="send-header-bar"> | 7 | <div class="send-header-bar"> |
4 | <el-popover placement="top" width="400" trigger="click"> | 8 | <el-popover placement="top" width="400" trigger="click"> |
5 | <div class="emojis"> | 9 | <div class="emojis"> |
6 | <div v-for="item in emojiName" class="emoji" :key="item" @click="chooseEmoji(item)"> | 10 | <div |
7 | <img :src="emojiUrl + emojiMap[item]" style="width:30px;height:30px" alt=""/> | 11 | v-for="item in emojiName" |
12 | class="emoji" | ||
13 | :key="item" | ||
14 | @click="chooseEmoji(item)" | ||
15 | > | ||
16 | <img | ||
17 | :src="emojiUrl + emojiMap[item]" | ||
18 | style="width: 30px; height: 30px" | ||
19 | alt="" | ||
20 | /> | ||
8 | </div> | 21 | </div> |
9 | </div> | 22 | </div> |
10 | <i class="iconfont icon-smile" slot="reference" title="发表情"></i> | 23 | <i class="iconfont icon-smile" slot="reference" title="发表情"></i> |
11 | </el-popover> | 24 | </el-popover> |
12 | <i class="iconfont icon-tupian" title="发图片" @click="handleSendImageClick"></i> | 25 | <i |
13 | <i class="el-icon-camera" title="发视频" @click="handleSendVideoClick"></i> | 26 | class="iconfont icon-tupian" |
14 | <!-- <i class="iconfont icon-wenjian" title="发文件" @click="handleSendFileClick"></i>--> | 27 | title="发图片" |
28 | @click="handleSendImageClick" | ||
29 | ></i> | ||
30 | <i | ||
31 | class="el-icon-camera" | ||
32 | title="发视频" | ||
33 | @click="handleSendVideoClick" | ||
34 | ></i> | ||
35 | <!-- <i--> | ||
36 | <!-- class="el-icon-link"--> | ||
37 | <!-- v-if="currentConversationType === TIM.TYPES.CONV_GROUP"--> | ||
38 | <!-- title="发歌曲详情"--> | ||
39 | <!-- @click="handleSendAudio"--> | ||
40 | <!-- ></i>--> | ||
41 | |||
42 | <!-- <i class="iconfont icon-wenjian" title="发文件" @click="handleSendFileClick"></i>--> | ||
15 | <!-- <i class="iconfont icon-zidingyi" title="发自定义消息" @click="sendCustomDialogVisible = true"></i>--> | 43 | <!-- <i class="iconfont icon-zidingyi" title="发自定义消息" @click="sendCustomDialogVisible = true"></i>--> |
16 | <!-- <el-dropdown>--> | 44 | <!-- <el-dropdown>--> |
17 | <!-- <span class="el-dropdown-link">--> | 45 | <!-- <span class="el-dropdown-link">--> |
... | @@ -29,7 +57,11 @@ | ... | @@ -29,7 +57,11 @@ |
29 | <!-- <i class="group-live-icon-hover"></i>--> | 57 | <!-- <i class="group-live-icon-hover"></i>--> |
30 | <!-- </div>--> | 58 | <!-- </div>--> |
31 | </div> | 59 | </div> |
32 | <el-dialog title="发自定义消息" :visible.sync="sendCustomDialogVisible" width="30%"> | 60 | <el-dialog |
61 | title="发自定义消息" | ||
62 | :visible.sync="sendCustomDialogVisible" | ||
63 | width="30%" | ||
64 | > | ||
33 | <el-form label-width="100px"> | 65 | <el-form label-width="100px"> |
34 | <el-form-item label="data"> | 66 | <el-form-item label="data"> |
35 | <el-input v-model="form.data"></el-input> | 67 | <el-input v-model="form.data"></el-input> |
... | @@ -46,7 +78,11 @@ | ... | @@ -46,7 +78,11 @@ |
46 | <el-button type="primary" @click="sendCustomMessage">确 定</el-button> | 78 | <el-button type="primary" @click="sendCustomMessage">确 定</el-button> |
47 | </span> | 79 | </span> |
48 | </el-dialog> | 80 | </el-dialog> |
49 | <el-dialog title="对IM Web demo的建议和使用感受" :visible.sync="surveyDialogVisible" width="30%"> | 81 | <el-dialog |
82 | title="对IM Web demo的建议和使用感受" | ||
83 | :visible.sync="surveyDialogVisible" | ||
84 | width="30%" | ||
85 | > | ||
50 | <el-form label-width="100px"> | 86 | <el-form label-width="100px"> |
51 | <el-form-item label="评分"> | 87 | <el-form-item label="评分"> |
52 | <div class="block"> | 88 | <div class="block"> |
... | @@ -55,11 +91,11 @@ | ... | @@ -55,11 +91,11 @@ |
55 | </el-form-item> | 91 | </el-form-item> |
56 | <el-form-item label="建议"> | 92 | <el-form-item label="建议"> |
57 | <el-input | 93 | <el-input |
58 | type="textarea" | 94 | type="textarea" |
59 | :rows="2" | 95 | :rows="2" |
60 | placeholder="请输入内容" | 96 | placeholder="请输入内容" |
61 | resize="none" | 97 | resize="none" |
62 | v-model="suggestion" | 98 | v-model="suggestion" |
63 | ></el-input> | 99 | ></el-input> |
64 | </el-form-item> | 100 | </el-form-item> |
65 | </el-form> | 101 | </el-form> |
... | @@ -69,41 +105,43 @@ | ... | @@ -69,41 +105,43 @@ |
69 | </span> | 105 | </span> |
70 | </el-dialog> | 106 | </el-dialog> |
71 | <el-popover | 107 | <el-popover |
72 | trigger="manual" | 108 | trigger="manual" |
73 | v-model="showAtGroupMember" | 109 | v-model="showAtGroupMember" |
74 | placement="top" | 110 | placement="top" |
75 | style="max-height:500px;overflow-y:scroll;" | 111 | style="max-height: 500px; overflow-y: scroll" |
76 | > | 112 | > |
77 | <el-radio-group | 113 | <el-radio-group |
78 | v-model="atUserID" | 114 | v-model="atUserID" |
79 | style="display:flex;flex-decoration: column;" | 115 | style="display: flex; flex-decoration: column" |
80 | v-for="member in memberList" | 116 | v-for="member in memberList" |
81 | :key="member.userID" | 117 | :key="member.userID" |
82 | @change="handleSelectAtUser" | 118 | @change="handleSelectAtUser" |
83 | > | 119 | > |
84 | <el-radio :label="member.userID">{{ member.nameCard || member.nick || member.userID }}</el-radio> | 120 | <el-radio :label="member.userID">{{ |
121 | member.nameCard || member.nick || member.userID | ||
122 | }}</el-radio> | ||
85 | </el-radio-group> | 123 | </el-radio-group> |
86 | </el-popover> | 124 | </el-popover> |
87 | <div class="bottom"> | 125 | <div class="bottom"> |
88 | <textarea | 126 | <textarea |
89 | ref="text-input" | 127 | ref="text-input" |
90 | rows="4" | 128 | rows="4" |
91 | resize="false" | 129 | resize="false" |
92 | v-model="messageContent" | 130 | v-model="messageContent" |
93 | class="text-input" | 131 | class="text-input" |
94 | @focus="focus = true" | 132 | @focus="focus = true" |
95 | @blur="focus = false" | 133 | @blur="focus = false" |
96 | @keydown.enter.exact.prevent="handleEnter" | 134 | @keydown.enter.exact.prevent="handleEnter" |
97 | @keyup.ctrl.enter.prevent.exact="handleLine" | 135 | @keyup.ctrl.enter.prevent.exact="handleLine" |
98 | @keydown.up.stop="handleUp" | 136 | @keydown.up.stop="handleUp" |
99 | @keydown.down.stop="handleDown" | 137 | @keydown.down.stop="handleDown" |
100 | > | 138 | > |
101 | </textarea> | 139 | </textarea> |
102 | <el-tooltip | 140 | <el-tooltip |
103 | class="item" | 141 | class="item" |
104 | effect="dark" | 142 | effect="dark" |
105 | content="按Enter发送消息,Ctrl+Enter换行" | 143 | content="按Enter发送消息,Ctrl+Enter换行" |
106 | placement="left-start" | 144 | placement="left-start" |
107 | > | 145 | > |
108 | <div class="btn-send" @click="sendTextMessage"> | 146 | <div class="btn-send" @click="sendTextMessage"> |
109 | <div class="tim-icon-send"></div> | 147 | <div class="tim-icon-send"></div> |
... | @@ -111,16 +149,34 @@ | ... | @@ -111,16 +149,34 @@ |
111 | </el-tooltip> | 149 | </el-tooltip> |
112 | </div> | 150 | </div> |
113 | <input | 151 | <input |
114 | type="file" | 152 | type="file" |
115 | id="imagePicker" | 153 | id="imagePicker" |
116 | ref="imagePicker" | 154 | ref="imagePicker" |
117 | accept=".jpg, .jpeg, .png, .gif, .bmp" | 155 | accept=".jpg, .jpeg, .png, .gif, .bmp" |
118 | @change="sendImage" | 156 | @change="sendImage" |
119 | style="display:none" | 157 | style="display: none" |
158 | /> | ||
159 | <input | ||
160 | type="file" | ||
161 | id="filePicker" | ||
162 | ref="filePicker" | ||
163 | @change="sendFile" | ||
164 | style="display: none" | ||
120 | /> | 165 | /> |
121 | <input type="file" id="filePicker" ref="filePicker" @change="sendFile" style="display:none"/> | 166 | <input |
122 | <input type="file" id="videoPicker" ref="videoPicker" @change="sendVideo" style="display:none" accept=".mp4"/> | 167 | type="file" |
123 | <div class="calling-member-list" v-if="currentConversationType === TIM.TYPES.CONV_GROUP && showCallingMember"> | 168 | id="videoPicker" |
169 | ref="videoPicker" | ||
170 | @change="sendVideo" | ||
171 | style="display: none" | ||
172 | accept=".mp4" | ||
173 | /> | ||
174 | <div | ||
175 | class="calling-member-list" | ||
176 | v-if=" | ||
177 | currentConversationType === TIM.TYPES.CONV_GROUP && showCallingMember | ||
178 | " | ||
179 | > | ||
124 | <calling-member-list @getList="getList"></calling-member-list> | 180 | <calling-member-list @getList="getList"></calling-member-list> |
125 | <div class="calling-list-btn"> | 181 | <div class="calling-list-btn"> |
126 | <span class="calling-btn" @click="cancelCalling">取消</span> | 182 | <span class="calling-btn" @click="cancelCalling">取消</span> |
... | @@ -131,14 +187,24 @@ | ... | @@ -131,14 +187,24 @@ |
131 | </template> | 187 | </template> |
132 | 188 | ||
133 | <script> | 189 | <script> |
134 | import {mapGetters, mapState} from 'vuex' | 190 | import { mapGetters, mapState } from "vuex"; |
135 | import callingMemberList from './trtc-calling/group-member-list' | 191 | import callingMemberList from "./trtc-calling/group-member-list"; |
136 | import {Dialog, Form, FormItem, Input, Popover, Radio, RadioGroup, Rate, Tooltip} from 'element-ui' | 192 | import { |
137 | import {emojiMap, emojiName, emojiUrl} from '../../utils/emojiMap' | 193 | Dialog, |
138 | 194 | Form, | |
195 | FormItem, | ||
196 | Input, | ||
197 | Popover, | ||
198 | Radio, | ||
199 | RadioGroup, | ||
200 | Rate, | ||
201 | Tooltip, | ||
202 | } from "element-ui"; | ||
203 | import { emojiMap, emojiName, emojiUrl } from "../../utils/emojiMap"; | ||
204 | import hrequest from "../../utils/hrequest"; | ||
139 | export default { | 205 | export default { |
140 | name: 'message-send-box', | 206 | name: "message-send-box", |
141 | props: ['scrollMessageListToButtom'], | 207 | props: ["scrollMessageListToButtom"], |
142 | components: { | 208 | components: { |
143 | callingMemberList: callingMemberList, | 209 | callingMemberList: callingMemberList, |
144 | ElInput: Input, | 210 | ElInput: Input, |
... | @@ -149,286 +215,287 @@ export default { | ... | @@ -149,286 +215,287 @@ export default { |
149 | ElRadioGroup: RadioGroup, | 215 | ElRadioGroup: RadioGroup, |
150 | ElRadio: Radio, | 216 | ElRadio: Radio, |
151 | ElTooltip: Tooltip, | 217 | ElTooltip: Tooltip, |
152 | ElRate: Rate | 218 | ElRate: Rate, |
153 | }, | 219 | }, |
154 | data() { | 220 | data() { |
155 | return { | 221 | return { |
156 | callingList: [], | 222 | callingList: [], |
157 | callingType: '', | 223 | callingType: "", |
158 | showCallingMember: false, | 224 | showCallingMember: false, |
159 | colors: ['#99A9BF', '#F7BA2A', '#FF9900'], | 225 | colors: ["#99A9BF", "#F7BA2A", "#FF9900"], |
160 | messageContent: '', | 226 | messageContent: "", |
161 | isSendCustomMessage: false, | 227 | isSendCustomMessage: false, |
162 | sendCustomDialogVisible: false, | 228 | sendCustomDialogVisible: false, |
163 | surveyDialogVisible: false, | 229 | surveyDialogVisible: false, |
164 | form: { | 230 | form: { |
165 | data: '', | 231 | data: "", |
166 | description: '', | 232 | description: "", |
167 | extension: '' | 233 | extension: "", |
168 | }, | 234 | }, |
169 | rate: 5, // 评分 | 235 | rate: 5, // 评分 |
170 | suggestion: '', // 建议 | 236 | suggestion: "", // 建议 |
171 | file: '', | 237 | file: "", |
172 | emojiMap: emojiMap, | 238 | emojiMap: emojiMap, |
173 | emojiName: emojiName, | 239 | emojiName: emojiName, |
174 | emojiUrl: emojiUrl, | 240 | emojiUrl: emojiUrl, |
175 | showAtGroupMember: false, | 241 | showAtGroupMember: false, |
176 | atUserID: '', | 242 | atUserID: "", |
177 | focus: false | 243 | focus: false, |
178 | } | 244 | }; |
179 | }, | 245 | }, |
180 | computed: { | 246 | computed: { |
181 | ...mapGetters(['toAccount', 'currentConversationType']), | 247 | ...mapGetters(["toAccount", "currentConversationType"]), |
182 | ...mapState({ | 248 | ...mapState({ |
183 | memberList: state => state.group.currentMemberList, | 249 | memberList: (state) => state.group.currentMemberList, |
184 | userID: state => state.user.userID, | 250 | userID: (state) => state.user.userID, |
185 | groupProfile: state => state.conversation.currentConversation.groupProfile | 251 | groupProfile: (state) => |
186 | }) | 252 | state.conversation.currentConversation.groupProfile, |
253 | }), | ||
187 | }, | 254 | }, |
188 | mounted() { | 255 | mounted() { |
189 | this.$refs['text-input'].addEventListener('paste', this.handlePaste) | 256 | this.$refs["text-input"].addEventListener("paste", this.handlePaste); |
190 | this.$bus.$on('reEditMessage', this.reEditMessage) | 257 | this.$bus.$on("reEditMessage", this.reEditMessage); |
191 | }, | 258 | }, |
192 | beforeDestroy() { | 259 | beforeDestroy() { |
193 | this.$refs['text-input'].removeEventListener('paste', this.handlePaste) | 260 | this.$refs["text-input"].removeEventListener("paste", this.handlePaste); |
194 | }, | 261 | }, |
195 | methods: { | 262 | methods: { |
196 | getList(value) { | 263 | getList(value) { |
197 | this.callingList = value | 264 | this.callingList = value; |
198 | }, | 265 | }, |
199 | cancelCalling() { | 266 | cancelCalling() { |
200 | this.showCallingMember = false | 267 | this.showCallingMember = false; |
201 | }, | 268 | }, |
202 | callingHandler() { | 269 | callingHandler() { |
203 | if (this.callingList.length < 1) { | 270 | if (this.callingList.length < 1) { |
204 | this.$store.commit('showMessage', { | 271 | this.$store.commit("showMessage", { |
205 | type: 'warning', | 272 | type: "warning", |
206 | message: '请选择成员' | 273 | message: "请选择成员", |
207 | }) | 274 | }); |
208 | return | 275 | return; |
209 | } | 276 | } |
210 | this.showCallingMember = false | 277 | this.showCallingMember = false; |
211 | let callingData = { | 278 | let callingData = { |
212 | memberList: this.callingList, | 279 | memberList: this.callingList, |
213 | type: this.TIM.TYPES.CONV_GROUP | 280 | type: this.TIM.TYPES.CONV_GROUP, |
281 | }; | ||
282 | this.$store.commit("setCallingList", callingData); | ||
283 | if (this.callingType === "video") { | ||
284 | this.$bus.$emit("video-call"); | ||
285 | return; | ||
214 | } | 286 | } |
215 | this.$store.commit('setCallingList', callingData) | 287 | if (this.callingType === "audio") { |
216 | if (this.callingType === 'video') { | 288 | this.$bus.$emit("audio-call"); |
217 | this.$bus.$emit('video-call') | 289 | return; |
218 | return | ||
219 | } | ||
220 | if (this.callingType === 'audio') { | ||
221 | this.$bus.$emit('audio-call') | ||
222 | return | ||
223 | } | 290 | } |
224 | }, | 291 | }, |
225 | trtcCalling(type) { | 292 | trtcCalling(type) { |
226 | if (type === 'video') { | 293 | if (type === "video") { |
227 | this.callingType = 'video' | 294 | this.callingType = "video"; |
228 | } | 295 | } |
229 | if (type === 'audio') { | 296 | if (type === "audio") { |
230 | this.callingType = 'audio' | 297 | this.callingType = "audio"; |
231 | } | 298 | } |
232 | // 呼叫方设置 | 299 | // 呼叫方设置 |
233 | if (this.currentConversationType === 'C2C') { | 300 | if (this.currentConversationType === "C2C") { |
234 | let member = [this.toAccount] | 301 | let member = [this.toAccount]; |
235 | let callingData = { | 302 | let callingData = { |
236 | memberList: member, | 303 | memberList: member, |
237 | type: 'C2C' | 304 | type: "C2C", |
238 | } | 305 | }; |
239 | this.$store.commit('setCallingList', callingData) | 306 | this.$store.commit("setCallingList", callingData); |
240 | this.$bus.$emit(`${type}-call`) | 307 | this.$bus.$emit(`${type}-call`); |
241 | return | 308 | return; |
242 | } | 309 | } |
243 | if (this.currentConversationType === this.TIM.TYPES.CONV_GROUP) { | 310 | if (this.currentConversationType === this.TIM.TYPES.CONV_GROUP) { |
244 | this.showCallingMember = true | 311 | this.showCallingMember = true; |
245 | } | 312 | } |
246 | // this.$store.commit('pushCurrentMessageList', true) | 313 | // this.$store.commit('pushCurrentMessageList', true) |
247 | }, | 314 | }, |
248 | audioCall() { | 315 | audioCall() { |
249 | this.$bus.$emit('audio-call') | 316 | this.$bus.$emit("audio-call"); |
250 | this.$store.commit('showAudioCall', true) | 317 | this.$store.commit("showAudioCall", true); |
251 | }, | 318 | }, |
252 | handleEmojiShow() { | 319 | handleEmojiShow() { |
253 | this.emojiShow = true | 320 | this.emojiShow = true; |
254 | this.bigEmojiShow = false | 321 | this.bigEmojiShow = false; |
255 | }, | 322 | }, |
256 | handleBigEmojiShow(index) { | 323 | handleBigEmojiShow(index) { |
257 | let elm = document.getElementById('bigEmojiBox') | 324 | let elm = document.getElementById("bigEmojiBox"); |
258 | elm && (elm.scrollTop = 0) | 325 | elm && (elm.scrollTop = 0); |
259 | this.curItemIndex = index | 326 | this.curItemIndex = index; |
260 | this.curBigEmojiItemList = this.bigEmojiList[index].list | 327 | this.curBigEmojiItemList = this.bigEmojiList[index].list; |
261 | this.emojiShow = false | 328 | this.emojiShow = false; |
262 | this.bigEmojiShow = true | 329 | this.bigEmojiShow = true; |
263 | }, | 330 | }, |
264 | chooseBigEmoji(item) { | 331 | chooseBigEmoji(item) { |
265 | this.popoverVisible = false | 332 | this.popoverVisible = false; |
266 | let message = this.tim.createFaceMessage({ | 333 | let message = this.tim.createFaceMessage({ |
267 | to: this.toAccount, | 334 | to: this.toAccount, |
268 | conversationType: this.currentConversationType, | 335 | conversationType: this.currentConversationType, |
269 | payload: { | 336 | payload: { |
270 | index: this.curItemIndex + 1, | 337 | index: this.curItemIndex + 1, |
271 | data: `${item}@2x` | 338 | data: `${item}@2x`, |
272 | } | 339 | }, |
273 | }) | 340 | }); |
274 | this.$store.commit('pushCurrentMessageList', message) | 341 | this.$store.commit("pushCurrentMessageList", message); |
275 | this.$bus.$emit('scroll-bottom') | 342 | this.$bus.$emit("scroll-bottom"); |
276 | this.tim.sendMessage(message).catch(error => { | 343 | this.tim.sendMessage(message).catch((error) => { |
277 | this.$store.commit('showMessage', { | 344 | this.$store.commit("showMessage", { |
278 | type: 'error', | 345 | type: "error", |
279 | message: error.message | 346 | message: error.message, |
280 | }) | 347 | }); |
281 | }) | 348 | }); |
282 | }, | 349 | }, |
283 | reEditMessage(payload) { | 350 | reEditMessage(payload) { |
284 | this.messageContent = payload | 351 | this.messageContent = payload; |
285 | }, | 352 | }, |
286 | handleSelectAtUser() { | 353 | handleSelectAtUser() { |
287 | this.messageContent += this.atUserID + ' ' | 354 | this.messageContent += this.atUserID + " "; |
288 | this.showAtGroupMember = false | 355 | this.showAtGroupMember = false; |
289 | }, | 356 | }, |
290 | handleUp() { | 357 | handleUp() { |
291 | const index = this.memberList.findIndex( | 358 | const index = this.memberList.findIndex( |
292 | member => member.userID === this.atUserID | 359 | (member) => member.userID === this.atUserID |
293 | ) | 360 | ); |
294 | if (index - 1 < 0) { | 361 | if (index - 1 < 0) { |
295 | return | 362 | return; |
296 | } | 363 | } |
297 | this.atUserID = this.memberList[index - 1].userID | 364 | this.atUserID = this.memberList[index - 1].userID; |
298 | }, | 365 | }, |
299 | handleDown() { | 366 | handleDown() { |
300 | const index = this.memberList.findIndex( | 367 | const index = this.memberList.findIndex( |
301 | member => member.userID === this.atUserID | 368 | (member) => member.userID === this.atUserID |
302 | ) | 369 | ); |
303 | if (index + 1 >= this.memberList.length) { | 370 | if (index + 1 >= this.memberList.length) { |
304 | return | 371 | return; |
305 | } | 372 | } |
306 | this.atUserID = this.memberList[index + 1].userID | 373 | this.atUserID = this.memberList[index + 1].userID; |
307 | }, | 374 | }, |
308 | handleEnter() { | 375 | handleEnter() { |
309 | if (this.showAtGroupMember) { | 376 | if (this.showAtGroupMember) { |
310 | this.handleSelectAtUser() | 377 | this.handleSelectAtUser(); |
311 | } else { | 378 | } else { |
312 | this.sendTextMessage() | 379 | this.sendTextMessage(); |
313 | } | 380 | } |
314 | }, | 381 | }, |
315 | handleLine() { | 382 | handleLine() { |
316 | this.messageContent += '\n' | 383 | this.messageContent += "\n"; |
317 | }, | 384 | }, |
318 | handlePaste(e) { | 385 | handlePaste(e) { |
319 | let clipboardData = e.clipboardData | 386 | let clipboardData = e.clipboardData; |
320 | let file | 387 | let file; |
321 | if ( | 388 | if ( |
322 | clipboardData && | 389 | clipboardData && |
323 | clipboardData.files && | 390 | clipboardData.files && |
324 | clipboardData.files.length > 0 | 391 | clipboardData.files.length > 0 |
325 | ) { | 392 | ) { |
326 | file = clipboardData.files[0] | 393 | file = clipboardData.files[0]; |
327 | } | 394 | } |
328 | 395 | ||
329 | if (typeof file === 'undefined') { | 396 | if (typeof file === "undefined") { |
330 | return | 397 | return; |
331 | } | 398 | } |
332 | // 1. 创建消息实例,接口返回的实例可以上屏 | 399 | // 1. 创建消息实例,接口返回的实例可以上屏 |
333 | let message = this.tim.createImageMessage({ | 400 | let message = this.tim.createImageMessage({ |
334 | to: this.toAccount, | 401 | to: this.toAccount, |
335 | conversationType: this.currentConversationType, | 402 | conversationType: this.currentConversationType, |
336 | payload: { | 403 | payload: { |
337 | file: file | 404 | file: file, |
338 | }, | 405 | }, |
339 | onProgress: percent => { | 406 | onProgress: (percent) => { |
340 | this.$set(message, 'progress', percent) // 手动给message 实例加个响应式属性: progress | 407 | this.$set(message, "progress", percent); // 手动给message 实例加个响应式属性: progress |
341 | } | 408 | }, |
342 | }) | 409 | }); |
343 | this.$store.commit('pushCurrentMessageList', message) | 410 | this.$store.commit("pushCurrentMessageList", message); |
344 | 411 | ||
345 | // 2. 发送消息 | 412 | // 2. 发送消息 |
346 | let promise = this.tim.sendMessage(message) | 413 | let promise = this.tim.sendMessage(message); |
347 | promise.catch(error => { | 414 | promise.catch((error) => { |
348 | this.$store.commit('showMessage', { | 415 | this.$store.commit("showMessage", { |
349 | type: 'error', | 416 | type: "error", |
350 | message: error.message | 417 | message: error.message, |
351 | }) | 418 | }); |
352 | }) | 419 | }); |
353 | }, | 420 | }, |
354 | dropHandler(e) { | 421 | dropHandler(e) { |
355 | e.preventDefault() | 422 | e.preventDefault(); |
356 | let file = e.dataTransfer.files[0] | 423 | let file = e.dataTransfer.files[0]; |
357 | let message = {} | 424 | let message = {}; |
358 | if (file.type === 'video/mp4') { | 425 | if (file.type === "video/mp4") { |
359 | message = this.tim.createVideoMessage({ | 426 | message = this.tim.createVideoMessage({ |
360 | to: this.toAccount, | 427 | to: this.toAccount, |
361 | conversationType: this.currentConversationType, | 428 | conversationType: this.currentConversationType, |
362 | payload: { | 429 | payload: { |
363 | file: file | 430 | file: file, |
364 | }, | 431 | }, |
365 | onProgress: percent => { | 432 | onProgress: (percent) => { |
366 | this.$set(message, 'progress', percent) // 手动给message 实例加个响应式属性: progress | 433 | this.$set(message, "progress", percent); // 手动给message 实例加个响应式属性: progress |
367 | } | 434 | }, |
368 | }) | 435 | }); |
369 | } else { | 436 | } else { |
370 | message = this.tim.createFileMessage({ | 437 | message = this.tim.createFileMessage({ |
371 | to: this.toAccount, | 438 | to: this.toAccount, |
372 | conversationType: this.currentConversationType, | 439 | conversationType: this.currentConversationType, |
373 | payload: { | 440 | payload: { |
374 | file: file | 441 | file: file, |
375 | }, | 442 | }, |
376 | onProgress: percent => { | 443 | onProgress: (percent) => { |
377 | this.$set(message, 'progress', percent) // 手动给message 实例加个响应式属性: progress | 444 | this.$set(message, "progress", percent); // 手动给message 实例加个响应式属性: progress |
378 | } | 445 | }, |
379 | }) | 446 | }); |
380 | } | 447 | } |
381 | this.$store.commit('pushCurrentMessageList', message) | 448 | this.$store.commit("pushCurrentMessageList", message); |
382 | this.tim | 449 | this.tim |
383 | .sendMessage(message) | 450 | .sendMessage(message) |
384 | .then(() => { | 451 | .then(() => { |
385 | this.$refs.videoPicker.value = null | 452 | this.$refs.videoPicker.value = null; |
386 | }) | 453 | }) |
387 | .catch(imError => { | 454 | .catch((imError) => { |
388 | this.$store.commit('showMessage', { | 455 | this.$store.commit("showMessage", { |
389 | message: imError.message, | 456 | message: imError.message, |
390 | type: 'error' | 457 | type: "error", |
391 | }) | 458 | }); |
392 | }) | 459 | }); |
393 | }, | 460 | }, |
394 | sendTextMessage() { | 461 | sendTextMessage() { |
395 | if ( | 462 | if ( |
396 | this.messageContent === '' || | 463 | this.messageContent === "" || |
397 | this.messageContent.trim().length === 0 | 464 | this.messageContent.trim().length === 0 |
398 | ) { | 465 | ) { |
399 | this.messageContent = '' | 466 | this.messageContent = ""; |
400 | this.$store.commit('showMessage', { | 467 | this.$store.commit("showMessage", { |
401 | message: '不能发送空消息哦!', | 468 | message: "不能发送空消息哦!", |
402 | type: 'info' | 469 | type: "info", |
403 | }) | 470 | }); |
404 | return | 471 | return; |
405 | } | 472 | } |
406 | const message = this.tim.createTextMessage({ | 473 | const message = this.tim.createTextMessage({ |
407 | to: this.toAccount, | 474 | to: this.toAccount, |
408 | conversationType: this.currentConversationType, | 475 | conversationType: this.currentConversationType, |
409 | payload: {text: this.messageContent} | 476 | payload: { text: this.messageContent }, |
410 | }) | 477 | }); |
411 | this.$store.commit('pushCurrentMessageList', message) | 478 | this.$store.commit("pushCurrentMessageList", message); |
412 | this.$bus.$emit('scroll-bottom') | 479 | this.$bus.$emit("scroll-bottom"); |
413 | this.tim.sendMessage(message).catch(error => { | 480 | this.tim.sendMessage(message).catch((error) => { |
414 | this.$store.commit('showMessage', { | 481 | this.$store.commit("showMessage", { |
415 | type: 'error', | 482 | type: "error", |
416 | message: error.message | 483 | message: error.message, |
417 | }) | 484 | }); |
418 | }) | 485 | }); |
419 | this.messageContent = '' | 486 | this.messageContent = ""; |
420 | }, | 487 | }, |
421 | sendCustomMessage() { | 488 | sendCustomMessage() { |
422 | if ( | 489 | if ( |
423 | this.form.data.length === 0 && | 490 | this.form.data.length === 0 && |
424 | this.form.description.length === 0 && | 491 | this.form.description.length === 0 && |
425 | this.form.extension.length === 0 | 492 | this.form.extension.length === 0 |
426 | ) { | 493 | ) { |
427 | this.$store.commit('showMessage', { | 494 | this.$store.commit("showMessage", { |
428 | message: '不能发送空消息', | 495 | message: "不能发送空消息", |
429 | type: 'info' | 496 | type: "info", |
430 | }) | 497 | }); |
431 | return | 498 | return; |
432 | } | 499 | } |
433 | const message = this.tim.createCustomMessage({ | 500 | const message = this.tim.createCustomMessage({ |
434 | to: this.toAccount, | 501 | to: this.toAccount, |
... | @@ -436,151 +503,222 @@ export default { | ... | @@ -436,151 +503,222 @@ export default { |
436 | payload: { | 503 | payload: { |
437 | data: this.form.data, | 504 | data: this.form.data, |
438 | description: this.form.description, | 505 | description: this.form.description, |
439 | extension: this.form.extension | 506 | extension: this.form.extension, |
440 | } | 507 | }, |
441 | }) | 508 | }); |
442 | this.$store.commit('pushCurrentMessageList', message) | 509 | this.$store.commit("pushCurrentMessageList", message); |
443 | this.tim.sendMessage(message).catch(error => { | 510 | this.tim.sendMessage(message).catch((error) => { |
444 | this.$store.commit('showMessage', { | 511 | this.$store.commit("showMessage", { |
445 | type: 'error', | 512 | type: "error", |
446 | message: error.message | 513 | message: error.message, |
447 | }) | 514 | }); |
448 | }) | 515 | }); |
449 | Object.assign(this.form, { | 516 | Object.assign(this.form, { |
450 | data: '', | 517 | data: "", |
451 | description: '', | 518 | description: "", |
452 | extension: '' | 519 | extension: "", |
453 | }) | 520 | }); |
454 | this.sendCustomDialogVisible = false | 521 | this.sendCustomDialogVisible = false; |
455 | }, | 522 | }, |
456 | random(min, max) { | 523 | random(min, max) { |
457 | return Math.floor(Math.random() * (max - min + 1) + min) | 524 | return Math.floor(Math.random() * (max - min + 1) + min); |
458 | }, | 525 | }, |
459 | sendSurvey() { | 526 | sendSurvey() { |
460 | const message = this.tim.createCustomMessage({ | 527 | const message = this.tim.createCustomMessage({ |
461 | to: this.toAccount, | 528 | to: this.toAccount, |
462 | conversationType: this.currentConversationType, | 529 | conversationType: this.currentConversationType, |
463 | payload: { | 530 | payload: { |
464 | data: 'survey', | 531 | data: "survey", |
465 | description: String(this.rate), | 532 | description: String(this.rate), |
466 | extension: this.suggestion | 533 | extension: this.suggestion, |
467 | } | 534 | }, |
468 | }) | 535 | }); |
469 | this.$store.commit('pushCurrentMessageList', message) | 536 | this.$store.commit("pushCurrentMessageList", message); |
470 | Object.assign(this.form, { | 537 | Object.assign(this.form, { |
471 | data: '', | 538 | data: "", |
472 | description: '', | 539 | description: "", |
473 | extension: '' | 540 | extension: "", |
474 | }) | 541 | }); |
475 | this.tim | 542 | this.tim |
476 | .sendMessage(message) | 543 | .sendMessage(message) |
477 | .then(() => { | 544 | .then(() => { |
478 | Object.assign(this, { | 545 | Object.assign(this, { |
479 | rate: 5, | 546 | rate: 5, |
480 | suggestion: '' | 547 | suggestion: "", |
481 | }) | 548 | }); |
482 | }) | 549 | }) |
483 | .catch(error => { | 550 | .catch((error) => { |
484 | this.$store.commit('showMessage', { | 551 | this.$store.commit("showMessage", { |
485 | type: 'error', | 552 | type: "error", |
486 | message: error.message | 553 | message: error.message, |
487 | }) | 554 | }); |
488 | }) | 555 | }); |
489 | this.surveyDialogVisible = false | 556 | this.surveyDialogVisible = false; |
490 | }, | 557 | }, |
491 | chooseEmoji(item) { | 558 | chooseEmoji(item) { |
492 | this.messageContent += item | 559 | this.messageContent += item; |
493 | }, | 560 | }, |
494 | handleSendImageClick() { | 561 | handleSendImageClick() { |
495 | this.$refs.imagePicker.click() | 562 | this.$refs.imagePicker.click(); |
496 | }, | 563 | }, |
497 | handleSendFileClick() { | 564 | handleSendFileClick() { |
498 | this.$refs.filePicker.click() | 565 | this.$refs.filePicker.click(); |
499 | }, | 566 | }, |
500 | handleSendVideoClick() { | 567 | handleSendVideoClick() { |
501 | this.$refs.videoPicker.click() | 568 | this.$refs.videoPicker.click(); |
569 | }, | ||
570 | handleSendAudio() { | ||
571 | this.sendActivityAudio(); | ||
502 | }, | 572 | }, |
573 | |||
503 | groupLive() { | 574 | groupLive() { |
504 | this.$store.commit('updateGroupLiveInfo', { | 575 | this.$store.commit("updateGroupLiveInfo", { |
505 | groupID: this.toAccount, | 576 | groupID: this.toAccount, |
506 | anchorID: this.userID, | 577 | anchorID: this.userID, |
507 | }) | 578 | }); |
508 | this.$bus.$emit('open-group-live', {channel: 1}) | 579 | this.$bus.$emit("open-group-live", { channel: 1 }); |
509 | }, | 580 | }, |
510 | sendImage() { | 581 | sendImage() { |
511 | const message = this.tim.createImageMessage({ | 582 | const message = this.tim.createImageMessage({ |
512 | to: this.toAccount, | 583 | to: this.toAccount, |
513 | conversationType: this.currentConversationType, | 584 | conversationType: this.currentConversationType, |
514 | payload: { | 585 | payload: { |
515 | file: document.getElementById('imagePicker') // 或者用event.target | 586 | file: document.getElementById("imagePicker"), // 或者用event.target |
516 | }, | 587 | }, |
517 | onProgress: percent => { | 588 | onProgress: (percent) => { |
518 | this.$set(message, 'progress', percent) // 手动给message 实例加个响应式属性: progress | 589 | this.$set(message, "progress", percent); // 手动给message 实例加个响应式属性: progress |
519 | } | 590 | }, |
520 | }) | 591 | }); |
521 | this.$store.commit('pushCurrentMessageList', message) | 592 | this.$store.commit("pushCurrentMessageList", message); |
522 | this.tim | 593 | this.tim |
523 | .sendMessage(message) | 594 | .sendMessage(message) |
524 | .then(() => { | 595 | .then(() => { |
525 | this.$refs.imagePicker.value = null | 596 | this.$refs.imagePicker.value = null; |
526 | }) | 597 | }) |
527 | .catch(imError => { | 598 | .catch((imError) => { |
528 | this.$store.commit('showMessage', { | 599 | this.$store.commit("showMessage", { |
529 | message: imError.message, | 600 | message: imError.message, |
530 | type: 'error' | 601 | type: "error", |
531 | }) | 602 | }); |
532 | }) | 603 | }); |
533 | }, | 604 | }, |
534 | sendFile() { | 605 | sendFile() { |
535 | const message = this.tim.createFileMessage({ | 606 | const message = this.tim.createFileMessage({ |
536 | to: this.toAccount, | 607 | to: this.toAccount, |
537 | conversationType: this.currentConversationType, | 608 | conversationType: this.currentConversationType, |
538 | payload: { | 609 | payload: { |
539 | file: document.getElementById('filePicker') // 或者用event.target | 610 | file: document.getElementById("filePicker"), // 或者用event.target |
540 | }, | 611 | }, |
541 | onProgress: percent => { | 612 | onProgress: (percent) => { |
542 | this.$set(message, 'progress', percent) // 手动给message 实例加个响应式属性: progress | 613 | this.$set(message, "progress", percent); // 手动给message 实例加个响应式属性: progress |
543 | } | 614 | }, |
544 | }) | 615 | }); |
545 | this.$store.commit('pushCurrentMessageList', message) | 616 | this.$store.commit("pushCurrentMessageList", message); |
546 | this.tim | 617 | this.tim |
547 | .sendMessage(message) | 618 | .sendMessage(message) |
548 | .then(() => { | 619 | .then(() => { |
549 | this.$refs.filePicker.value = null | 620 | this.$refs.filePicker.value = null; |
550 | }) | 621 | }) |
551 | .catch(imError => { | 622 | .catch((imError) => { |
552 | this.$store.commit('showMessage', { | 623 | this.$store.commit("showMessage", { |
553 | message: imError.message, | 624 | message: imError.message, |
554 | type: 'error' | 625 | type: "error", |
555 | }) | 626 | }); |
556 | }) | 627 | }); |
557 | }, | 628 | }, |
558 | sendVideo() { | 629 | sendVideo() { |
559 | const message = this.tim.createVideoMessage({ | 630 | const message = this.tim.createVideoMessage({ |
560 | to: this.toAccount, | 631 | to: this.toAccount, |
561 | conversationType: this.currentConversationType, | 632 | conversationType: this.currentConversationType, |
562 | payload: { | 633 | payload: { |
563 | file: document.getElementById('videoPicker') // 或者用event.target | 634 | file: document.getElementById("videoPicker"), // 或者用event.target |
564 | }, | 635 | }, |
565 | onProgress: percent => { | 636 | onProgress: (percent) => { |
566 | this.$set(message, 'progress', percent) // 手动给message 实例加个响应式属性: progress | 637 | this.$set(message, "progress", percent); // 手动给message 实例加个响应式属性: progress |
638 | }, | ||
639 | }); | ||
640 | this.$store.commit("pushCurrentMessageList", message); | ||
641 | this.tim | ||
642 | .sendMessage(message) | ||
643 | .then(() => { | ||
644 | this.$refs.videoPicker.value = null; | ||
645 | }) | ||
646 | .catch((imError) => { | ||
647 | this.$store.commit("showMessage", { | ||
648 | message: imError.message, | ||
649 | type: "error", | ||
650 | }); | ||
651 | }); | ||
652 | }, | ||
653 | sendActivityAudio() { | ||
654 | console.log("in sendActivityAudio", this.groupProfile); | ||
655 | let activityID = ""; | ||
656 | this.groupProfile.groupCustomField.forEach((item) => { | ||
657 | const { key, value } = item; | ||
658 | |||
659 | if (key == "ActivityKey") { | ||
660 | console.log("get activityID is ", key); | ||
661 | activityID = value; | ||
567 | } | 662 | } |
568 | }) | 663 | }); |
569 | this.$store.commit('pushCurrentMessageList', message) | 664 | if (!activityID) { |
665 | return; | ||
666 | } | ||
667 | |||
668 | hrequest.get(`v3/activitys/${activityID}`).then((res) => { | ||
669 | if (res && res.data && res.data.data && res.data.data.activity) { | ||
670 | let activity = res.data.data.activity; | ||
671 | const { activity_name, banner, audio_file } = activity; | ||
672 | let imageUrl = ""; | ||
673 | let audioUrl = ""; | ||
674 | if (banner && banner.length >= 1) { | ||
675 | let innerBanner = banner[0]; | ||
676 | imageUrl = innerBanner.url; | ||
677 | } | ||
678 | if (audio_file) { | ||
679 | audioUrl = audio_file.url; | ||
680 | } | ||
681 | // console.log("activity_name is ", activity_name); | ||
682 | // console.log("imageUrl is ", imageUrl); | ||
683 | // console.log("audioUrl is ", audioUrl); | ||
684 | |||
685 | this.sendMatiral(activityID, activity_name, imageUrl, audioUrl); | ||
686 | } | ||
687 | }); | ||
688 | }, | ||
689 | sendMatiral(id, activityName, imageUrl, audioUrl) { | ||
690 | let extension = JSON.stringify({ | ||
691 | cover_url: imageUrl, | ||
692 | name: activityName, | ||
693 | activity_id: id, | ||
694 | }); | ||
695 | // 3.创建伪消息 用于展示 | ||
696 | let message = this.tim.createCustomMessage({ | ||
697 | to: this.toAccount, | ||
698 | conversationType: this.currentConversationType, | ||
699 | |||
700 | payload: { | ||
701 | data: "audio", // 用于标识该消息是骰子类型消息 | ||
702 | description: audioUrl, // 获取骰子点数 | ||
703 | extension: extension, | ||
704 | }, | ||
705 | }); | ||
706 | this.$store.commit("pushCurrentMessageList", message); | ||
707 | |||
570 | this.tim | 708 | this.tim |
571 | .sendMessage(message) | 709 | .sendMessage(message) |
572 | .then(() => { | 710 | .then((res) => { |
573 | this.$refs.videoPicker.value = null | 711 | console.log("res is ", res); |
574 | }) | 712 | }) |
575 | .catch(imError => { | 713 | .catch((imError) => { |
576 | this.$store.commit('showMessage', { | 714 | this.$store.commit("showMessage", { |
577 | message: imError.message, | 715 | message: imError.message, |
578 | type: 'error' | 716 | type: "error", |
579 | }) | 717 | }); |
580 | }) | 718 | }); |
581 | } | 719 | }, |
582 | } | 720 | }, |
583 | } | 721 | }; |
584 | </script> | 722 | </script> |
585 | <style lang="stylus" scoped> | 723 | <style lang="stylus" scoped> |
586 | #message-send-box-wrapper { | 724 | #message-send-box-wrapper { | ... | ... |
1 | <template> | 1 | <template> |
2 | <div class="container"> | 2 | <div class="container"> |
3 | <div class="loading" v-loading="showLoading" element-loading-text="正在拼命初始化..." | 3 | <div |
4 | element-loading-background="rgba(0, 0, 0, 0.8)"> | 4 | class="loading" |
5 | v-loading="showLoading" | ||
6 | element-loading-text="正在拼命初始化..." | ||
7 | element-loading-background="rgba(0, 0, 0, 0.8)" | ||
8 | > | ||
5 | <div class="chat-wrapper"> | 9 | <div class="chat-wrapper"> |
6 | <el-row> | 10 | <el-row> |
7 | <el-col :xs="10" :sm="10" :md="8" :lg="8" :xl="7"> | 11 | <el-col :xs="10" :sm="10" :md="8" :lg="8" :xl="7"> |
8 | <side-bar/> | 12 | <side-bar /> |
9 | </el-col> | 13 | </el-col> |
10 | <el-col :xs="14" :sm="14" :md="16" :lg="16" :xl="17"> | 14 | <el-col :xs="14" :sm="14" :md="16" :lg="16" :xl="17"> |
11 | <current-conversation/> | 15 | <current-conversation /> |
12 | </el-col> | 16 | </el-col> |
13 | </el-row> | 17 | </el-row> |
14 | </div> | 18 | </div> |
15 | <calling ref="callLayer" class="chat-wrapper"/> | 19 | <calling ref="callLayer" class="chat-wrapper" /> |
16 | <image-previewer/> | 20 | <image-previewer /> |
17 | <group-live/> | 21 | <group-live /> |
18 | </div> | 22 | </div> |
19 | <div class="bg"></div> | 23 | <div class="bg"></div> |
20 | </div> | 24 | </div> |
21 | </template> | 25 | </template> |
22 | 26 | ||
23 | <script> | 27 | <script> |
24 | import {Notification} from 'element-ui' | 28 | import { Notification } from "element-ui"; |
25 | import {mapState} from 'vuex' | 29 | import { mapState } from "vuex"; |
26 | import CurrentConversation from './components/conversation/current-conversation' | 30 | import CurrentConversation from "./components/conversation/current-conversation"; |
27 | import SideBar from './components/layout/side-bar' | 31 | import SideBar from "./components/layout/side-bar"; |
28 | import ImagePreviewer from './components/message/image-previewer.vue' | 32 | import ImagePreviewer from "./components/message/image-previewer.vue"; |
29 | import {translateGroupSystemNotice} from './utils/common' | 33 | import { translateGroupSystemNotice } from "./utils/common"; |
30 | import GroupLive from './components/group-live/index' | 34 | import GroupLive from "./components/group-live/index"; |
31 | import Calling from './components/message/trtc-calling/calling-index' | 35 | import Calling from "./components/message/trtc-calling/calling-index"; |
32 | import {ACTION} from './utils/trtcCustomMessageMap' | 36 | import { ACTION } from "./utils/trtcCustomMessageMap"; |
33 | import MTA from './utils/mta' | 37 | import MTA from "./utils/mta"; |
34 | import Helper from './utils/helper' | 38 | import Helper from "./utils/helper"; |
35 | 39 | ||
36 | export default { | 40 | export default { |
37 | title: '星斗推', | 41 | title: "星斗推", |
38 | components: { | 42 | components: { |
39 | SideBar, | 43 | SideBar, |
40 | CurrentConversation, | 44 | CurrentConversation, |
... | @@ -44,49 +48,54 @@ export default { | ... | @@ -44,49 +48,54 @@ export default { |
44 | }, | 48 | }, |
45 | computed: { | 49 | computed: { |
46 | ...mapState({ | 50 | ...mapState({ |
47 | currentUserProfile: state => state.user.currentUserProfile, | 51 | currentUserProfile: (state) => state.user.currentUserProfile, |
48 | currentConversation: state => state.conversation.currentConversation, | 52 | currentConversation: (state) => state.conversation.currentConversation, |
49 | videoCall: state => state.conversation.videoCall, | 53 | videoCall: (state) => state.conversation.videoCall, |
50 | audioCall: state => state.conversation.audioCall, | 54 | audioCall: (state) => state.conversation.audioCall, |
51 | isLogin: state => state.user.isLogin, | 55 | isLogin: (state) => state.user.isLogin, |
52 | isSDKReady: state => state.user.isSDKReady, | 56 | isSDKReady: (state) => state.user.isSDKReady, |
53 | isBusy: state => state.video.isBusy, | 57 | isBusy: (state) => state.video.isBusy, |
54 | userID: state => state.user.userID, | 58 | userID: (state) => state.user.userID, |
55 | userSig: state => state.user.userSig, | 59 | userSig: (state) => state.user.userSig, |
56 | sdkAppID: state => state.user.sdkAppID | 60 | sdkAppID: (state) => state.user.sdkAppID, |
57 | }), | 61 | }), |
58 | // 是否显示 Loading 状态 | 62 | // 是否显示 Loading 状态 |
59 | showLoading() { | 63 | showLoading() { |
60 | return !this.isSDKReady | 64 | return !this.isSDKReady; |
61 | } | 65 | }, |
62 | }, | 66 | }, |
63 | mounted() { | 67 | mounted() { |
64 | // 初始化监听器 | 68 | // 初始化监听器 |
65 | this.initListener() | 69 | this.initListener(); |
66 | |||
67 | }, | 70 | }, |
68 | created() { | 71 | created() { |
69 | Helper.verifyToken().then(user => this.tim.login({userID: user.id, userSig: user.sign}) | 72 | Helper.verifyToken().then((user) => |
73 | this.tim | ||
74 | .login({ userID: user.id, userSig: user.sign }) | ||
70 | .then(() => { | 75 | .then(() => { |
71 | this.loading = false | 76 | this.loading = false; |
72 | this.$store.commit('toggleIsLogin', true) | 77 | this.$store.commit("toggleIsLogin", true); |
73 | this.$store.commit('startComputeCurrent') | 78 | this.$store.commit("startComputeCurrent"); |
74 | this.$store.commit('GET_USER_INFO', { | 79 | this.$store.commit("GET_USER_INFO", { |
75 | userID: user.id, | 80 | userID: user.id, |
76 | userSig: user.sign, | 81 | userSig: user.sign, |
77 | sdkAppID: process.env.VUE_APP_API_KEY | 82 | sdkAppID: process.env.VUE_APP_API_KEY, |
78 | }) | 83 | }); |
79 | // this.$store.commit('showMessage', {type: 'success', message: '登录成功'}) | 84 | // this.$store.commit('showMessage', {type: 'success', message: '登录成功'}) |
80 | }) | 85 | }) |
81 | .catch(error => { | 86 | .catch((error) => { |
82 | this.loading = false | 87 | this.loading = false; |
83 | this.$store.commit('showMessage', {message: '登录失败:' + error.message, type: 'error'}) | 88 | this.$store.commit("showMessage", { |
84 | })) | 89 | message: "登录失败:" + error.message, |
90 | type: "error", | ||
91 | }); | ||
92 | }) | ||
93 | ); | ||
85 | }, | 94 | }, |
86 | watch: { | 95 | watch: { |
87 | isLogin(next) { | 96 | isLogin(next) { |
88 | if (next) { | 97 | if (next) { |
89 | MTA.clickStat('link_two', {show: 'true'}) | 98 | MTA.clickStat("link_two", { show: "true" }); |
90 | } | 99 | } |
91 | }, | 100 | }, |
92 | }, | 101 | }, |
... | @@ -94,54 +103,65 @@ export default { | ... | @@ -94,54 +103,65 @@ export default { |
94 | methods: { | 103 | methods: { |
95 | initListener() { | 104 | initListener() { |
96 | // 登录成功后会触发 SDK_READY 事件,该事件触发后,可正常使用 SDK 接口 | 105 | // 登录成功后会触发 SDK_READY 事件,该事件触发后,可正常使用 SDK 接口 |
97 | this.tim.on(this.TIM.EVENT.SDK_READY, this.onReadyStateUpdate, this) | 106 | this.tim.on(this.TIM.EVENT.SDK_READY, this.onReadyStateUpdate, this); |
98 | // SDK NOT READT | 107 | // SDK NOT READT |
99 | this.tim.on(this.TIM.EVENT.SDK_NOT_READY, this.onReadyStateUpdate, this) | 108 | this.tim.on(this.TIM.EVENT.SDK_NOT_READY, this.onReadyStateUpdate, this); |
100 | // 被踢出 | 109 | // 被踢出 |
101 | this.tim.on(this.TIM.EVENT.KICKED_OUT, this.onKickOut) | 110 | this.tim.on(this.TIM.EVENT.KICKED_OUT, this.onKickOut); |
102 | // SDK内部出错 | 111 | // SDK内部出错 |
103 | this.tim.on(this.TIM.EVENT.ERROR, this.onError) | 112 | this.tim.on(this.TIM.EVENT.ERROR, this.onError); |
104 | // 收到新消息 | 113 | // 收到新消息 |
105 | this.tim.on(this.TIM.EVENT.MESSAGE_RECEIVED, this.onReceiveMessage) | 114 | this.tim.on(this.TIM.EVENT.MESSAGE_RECEIVED, this.onReceiveMessage); |
106 | // 会话列表更新 | 115 | // 会话列表更新 |
107 | this.tim.on(this.TIM.EVENT.CONVERSATION_LIST_UPDATED, this.onUpdateConversationList) | 116 | this.tim.on( |
117 | this.TIM.EVENT.CONVERSATION_LIST_UPDATED, | ||
118 | this.onUpdateConversationList | ||
119 | ); | ||
108 | // 群组列表更新 | 120 | // 群组列表更新 |
109 | // this.tim.on(this.TIM.EVENT.GROUP_LIST_UPDATED, this.onUpdateGroupList) | 121 | // this.tim.on(this.TIM.EVENT.GROUP_LIST_UPDATED, this.onUpdateGroupList) |
110 | // 网络监测 | 122 | // 网络监测 |
111 | this.tim.on(this.TIM.EVENT.NET_STATE_CHANGE, this.onNetStateChange) | 123 | this.tim.on(this.TIM.EVENT.NET_STATE_CHANGE, this.onNetStateChange); |
112 | // 已读回执 | 124 | // 已读回执 |
113 | this.tim.on(this.TIM.EVENT.MESSAGE_READ_BY_PEER, this.onMessageReadByPeer) | 125 | this.tim.on( |
114 | 126 | this.TIM.EVENT.MESSAGE_READ_BY_PEER, | |
127 | this.onMessageReadByPeer | ||
128 | ); | ||
115 | }, | 129 | }, |
116 | 130 | ||
117 | onReceiveMessage({data: messageList}) { | 131 | onReceiveMessage({ data: messageList }) { |
118 | this.handleVideoMessage(messageList) | 132 | this.handleVideoMessage(messageList); |
119 | this.handleAt(messageList) | 133 | this.handleAt(messageList); |
120 | this.handleQuitGroupTip(messageList) | 134 | this.handleQuitGroupTip(messageList); |
121 | this.handleCloseGroupLive(messageList) | 135 | this.handleCloseGroupLive(messageList); |
122 | this.$store.commit('pushCurrentMessageList', messageList) | 136 | this.$store.commit("pushCurrentMessageList", messageList); |
123 | this.$store.commit('pushAvChatRoomMessageList', messageList) | 137 | this.$store.commit("pushAvChatRoomMessageList", messageList); |
124 | }, | 138 | }, |
125 | onError({data}) { | 139 | onError({ data }) { |
126 | if (data.message !== 'Network Error') { | 140 | if (data.message !== "Network Error") { |
127 | this.$store.commit('showMessage', { | 141 | this.$store.commit("showMessage", { |
128 | message: data.message, | 142 | message: data.message, |
129 | type: 'error' | 143 | type: "error", |
130 | }) | 144 | }); |
131 | } | 145 | } |
132 | }, | 146 | }, |
133 | onMessageReadByPeer() { | 147 | onMessageReadByPeer() {}, |
134 | 148 | onReadyStateUpdate({ name }) { | |
135 | }, | 149 | const isSDKReady = name === this.TIM.EVENT.SDK_READY; |
136 | onReadyStateUpdate({name}) { | 150 | this.$store.commit("toggleIsSDKReady", isSDKReady); |
137 | const isSDKReady = name === this.TIM.EVENT.SDK_READY | ||
138 | this.$store.commit('toggleIsSDKReady', isSDKReady) | ||
139 | 151 | ||
140 | if (isSDKReady) { | 152 | if (isSDKReady) { |
141 | this.tim.getMyProfile() | 153 | this.tim |
142 | .then(({data}) => this.$store.commit('updateCurrentUserProfile', data)) | 154 | .getMyProfile() |
143 | .catch(error => this.$store.commit('showMessage', {type: 'error', message: error.message})) | 155 | .then(({ data }) => |
144 | this.$store.dispatch('getBlacklist') | 156 | this.$store.commit("updateCurrentUserProfile", data) |
157 | ) | ||
158 | .catch((error) => | ||
159 | this.$store.commit("showMessage", { | ||
160 | type: "error", | ||
161 | message: error.message, | ||
162 | }) | ||
163 | ); | ||
164 | this.$store.dispatch("getBlacklist"); | ||
145 | // Helper.contactList({type: 'admin'}).then(res => this.$store.commit('updateAdminList', res.data)) | 165 | // Helper.contactList({type: 'admin'}).then(res => this.$store.commit('updateAdminList', res.data)) |
146 | // Helper.contactList({ | 166 | // Helper.contactList({ |
147 | // type: 'scheme', | 167 | // type: 'scheme', |
... | @@ -155,62 +175,65 @@ export default { | ... | @@ -155,62 +175,65 @@ export default { |
155 | kickedOutReason(type) { | 175 | kickedOutReason(type) { |
156 | switch (type) { | 176 | switch (type) { |
157 | case this.TIM.TYPES.KICKED_OUT_MULT_ACCOUNT: | 177 | case this.TIM.TYPES.KICKED_OUT_MULT_ACCOUNT: |
158 | return '由于多实例登录' | 178 | return "由于多实例登录"; |
159 | case this.TIM.TYPES.KICKED_OUT_MULT_DEVICE: | 179 | case this.TIM.TYPES.KICKED_OUT_MULT_DEVICE: |
160 | return '由于多设备登录' | 180 | return "由于多设备登录"; |
161 | case this.TIM.TYPES.KICKED_OUT_USERSIG_EXPIRED: | 181 | case this.TIM.TYPES.KICKED_OUT_USERSIG_EXPIRED: |
162 | return '由于 userSig 过期' | 182 | return "由于 userSig 过期"; |
163 | default: | 183 | default: |
164 | return '' | 184 | return ""; |
165 | } | 185 | } |
166 | }, | 186 | }, |
167 | checkoutNetState(state) { | 187 | checkoutNetState(state) { |
168 | switch (state) { | 188 | switch (state) { |
169 | case this.TIM.TYPES.NET_STATE_CONNECTED: | 189 | case this.TIM.TYPES.NET_STATE_CONNECTED: |
170 | return {message: '已接入网络', type: 'success'} | 190 | return { message: "已接入网络", type: "success" }; |
171 | case this.TIM.TYPES.NET_STATE_CONNECTING: | 191 | case this.TIM.TYPES.NET_STATE_CONNECTING: |
172 | return {message: '当前网络不稳定', type: 'warning'} | 192 | return { message: "当前网络不稳定", type: "warning" }; |
173 | case this.TIM.TYPES.NET_STATE_DISCONNECTED: | 193 | case this.TIM.TYPES.NET_STATE_DISCONNECTED: |
174 | return {message: '当前网络不可用', type: 'error'} | 194 | return { message: "当前网络不可用", type: "error" }; |
175 | default: | 195 | default: |
176 | return '' | 196 | return ""; |
177 | } | 197 | } |
178 | }, | 198 | }, |
179 | onNetStateChange(event) { | 199 | onNetStateChange(event) { |
180 | this.$store.commit('showMessage', this.checkoutNetState(event.data.state)) | 200 | this.$store.commit( |
201 | "showMessage", | ||
202 | this.checkoutNetState(event.data.state) | ||
203 | ); | ||
181 | }, | 204 | }, |
182 | onKickOut(event) { | 205 | onKickOut(event) { |
183 | this.$store.commit('showMessage', { | 206 | this.$store.commit("showMessage", { |
184 | message: `${this.kickedOutReason(event.data.type)}被踢出,请重新登录。`, | 207 | message: `${this.kickedOutReason(event.data.type)}被踢出,请重新登录。`, |
185 | type: 'error' | 208 | type: "error", |
186 | }) | 209 | }); |
187 | this.$store.commit('toggleIsLogin', false) | 210 | this.$store.commit("toggleIsLogin", false); |
188 | this.$store.commit('reset') | 211 | this.$store.commit("reset"); |
189 | }, | 212 | }, |
190 | onUpdateConversationList(event) { | 213 | onUpdateConversationList(event) { |
191 | this.$store.commit('updateConversationList', event.data) | 214 | this.$store.commit("updateConversationList", event.data); |
192 | }, | 215 | }, |
193 | // onUpdateGroupList(event) { | 216 | // onUpdateGroupList(event) { |
194 | // this.$store.commit('updateGroupList', event.data) | 217 | // this.$store.commit('updateGroupList', event.data) |
195 | // }, | 218 | // }, |
196 | onReceiveGroupSystemNotice(event) { | 219 | onReceiveGroupSystemNotice(event) { |
197 | const isKickedout = event.data.type === 4 | 220 | const isKickedout = event.data.type === 4; |
198 | const isCurrentConversation = | 221 | const isCurrentConversation = |
199 | `GROUP${event.data.message.payload.groupProfile.groupID}` === | 222 | `GROUP${event.data.message.payload.groupProfile.groupID}` === |
200 | this.currentConversation.conversationID | 223 | this.currentConversation.conversationID; |
201 | // 在当前会话被踢,需reset当前会话 | 224 | // 在当前会话被踢,需reset当前会话 |
202 | if (isKickedout && isCurrentConversation) { | 225 | if (isKickedout && isCurrentConversation) { |
203 | this.$store.commit('resetCurrentConversation') | 226 | this.$store.commit("resetCurrentConversation"); |
204 | } | 227 | } |
205 | Notification({ | 228 | Notification({ |
206 | title: '新系统通知', | 229 | title: "新系统通知", |
207 | message: translateGroupSystemNotice(event.data.message), | 230 | message: translateGroupSystemNotice(event.data.message), |
208 | duration: 3000, | 231 | duration: 3000, |
209 | onClick: () => { | 232 | onClick: () => { |
210 | const SystemConversationID = '@TIM#SYSTEM' | 233 | const SystemConversationID = "@TIM#SYSTEM"; |
211 | this.$store.dispatch('checkoutConversation', SystemConversationID) | 234 | this.$store.dispatch("checkoutConversation", SystemConversationID); |
212 | } | 235 | }, |
213 | }) | 236 | }); |
214 | }, | 237 | }, |
215 | /** | 238 | /** |
216 | * 处理 @ 我的消息 | 239 | * 处理 @ 我的消息 |
... | @@ -219,83 +242,85 @@ export default { | ... | @@ -219,83 +242,85 @@ export default { |
219 | handleAt(messageList) { | 242 | handleAt(messageList) { |
220 | // 筛选有 @ 符号的文本消息 | 243 | // 筛选有 @ 符号的文本消息 |
221 | const atTextMessageList = messageList.filter( | 244 | const atTextMessageList = messageList.filter( |
222 | message => | 245 | (message) => |
223 | message.type === this.TIM.TYPES.MSG_TEXT && | 246 | message.type === this.TIM.TYPES.MSG_TEXT && |
224 | message.payload.text.includes('@') | 247 | message.payload.text.includes("@") |
225 | ) | 248 | ); |
226 | for (let i = 0; i < atTextMessageList.length; i++) { | 249 | for (let i = 0; i < atTextMessageList.length; i++) { |
227 | const message = atTextMessageList[i] | 250 | const message = atTextMessageList[i]; |
228 | const matched = message.payload.text.match(/@\w+/g) | 251 | const matched = message.payload.text.match(/@\w+/g); |
229 | if (!matched) { | 252 | if (!matched) { |
230 | continue | 253 | continue; |
231 | } | 254 | } |
232 | // @ 我的 | 255 | // @ 我的 |
233 | if (matched.includes(`@${this.currentUserProfile.userID}`)) { | 256 | if (matched.includes(`@${this.currentUserProfile.userID}`)) { |
234 | // 当前页面不可见时,调用window.Notification接口,系统级别通知。 | 257 | // 当前页面不可见时,调用window.Notification接口,系统级别通知。 |
235 | if (this.$store.getters.hidden) { | 258 | if (this.$store.getters.hidden) { |
236 | this.notifyMe(message) | 259 | this.notifyMe(message); |
237 | } | 260 | } |
238 | Notification({ | 261 | Notification({ |
239 | title: `有人在群${message.conversationID.slice(5)}提到了你`, | 262 | title: `有人在群${message.conversationID.slice(5)}提到了你`, |
240 | message: message.payload.text, | 263 | message: message.payload.text, |
241 | duration: 3000 | 264 | duration: 3000, |
242 | }) | 265 | }); |
243 | this.$bus.$emit('new-messsage-at-me', { | 266 | this.$bus.$emit("new-messsage-at-me", { |
244 | data: {conversationID: message.conversationID} | 267 | data: { conversationID: message.conversationID }, |
245 | }) | 268 | }); |
246 | } | 269 | } |
247 | } | 270 | } |
248 | }, | 271 | }, |
249 | selectConversation(conversationID) { | 272 | selectConversation(conversationID) { |
250 | if (conversationID !== this.currentConversation.conversationID) { | 273 | if (conversationID !== this.currentConversation.conversationID) { |
251 | this.$store.dispatch('checkoutConversation', conversationID) | 274 | this.$store.dispatch("checkoutConversation", conversationID); |
252 | } | 275 | } |
253 | }, | 276 | }, |
254 | isJsonStr(str) { | 277 | isJsonStr(str) { |
255 | try { | 278 | try { |
256 | JSON.parse(str) | 279 | JSON.parse(str); |
257 | return true | 280 | return true; |
258 | } catch { | 281 | } catch { |
259 | return false | 282 | return false; |
260 | } | 283 | } |
261 | }, | 284 | }, |
262 | handleVideoMessage(messageList) { | 285 | handleVideoMessage(messageList) { |
263 | const videoMessageList = messageList.filter( | 286 | const videoMessageList = messageList.filter( |
264 | message => message.type === this.TIM.TYPES.MSG_CUSTOM && this.isJsonStr(message.payload.data) | 287 | (message) => |
265 | ) | 288 | message.type === this.TIM.TYPES.MSG_CUSTOM && |
266 | if (videoMessageList.length === 0) return | 289 | this.isJsonStr(message.payload.data) |
267 | const videoPayload = JSON.parse(videoMessageList[0].payload.data) | 290 | ); |
291 | if (videoMessageList.length === 0) return; | ||
292 | const videoPayload = JSON.parse(videoMessageList[0].payload.data); | ||
268 | if (videoPayload.action === ACTION.VIDEO_CALL_ACTION_DIALING) { | 293 | if (videoPayload.action === ACTION.VIDEO_CALL_ACTION_DIALING) { |
269 | if (this.isBusy) { | 294 | if (this.isBusy) { |
270 | this.$bus.$emit('busy', videoPayload, videoMessageList[0]) | 295 | this.$bus.$emit("busy", videoPayload, videoMessageList[0]); |
271 | return | 296 | return; |
272 | } | 297 | } |
273 | this.$store.commit('GENERATE_VIDEO_ROOM', videoPayload.room_id) | 298 | this.$store.commit("GENERATE_VIDEO_ROOM", videoPayload.room_id); |
274 | this.selectConversation(videoMessageList[0].conversationID) // 切换当前会话页 | 299 | this.selectConversation(videoMessageList[0].conversationID); // 切换当前会话页 |
275 | if (videoMessageList[0].from !== this.userID) { | 300 | if (videoMessageList[0].from !== this.userID) { |
276 | this.$bus.$emit('isCalled') | 301 | this.$bus.$emit("isCalled"); |
277 | } | 302 | } |
278 | } | 303 | } |
279 | if (videoPayload.action === ACTION.VIDEO_CALL_ACTION_SPONSOR_CANCEL) { | 304 | if (videoPayload.action === ACTION.VIDEO_CALL_ACTION_SPONSOR_CANCEL) { |
280 | this.$bus.$emit('missCall') | 305 | this.$bus.$emit("missCall"); |
281 | } | 306 | } |
282 | if (videoPayload.action === ACTION.VIDEO_CALL_ACTION_REJECT) { | 307 | if (videoPayload.action === ACTION.VIDEO_CALL_ACTION_REJECT) { |
283 | this.$bus.$emit('isRefused') | 308 | this.$bus.$emit("isRefused"); |
284 | } | 309 | } |
285 | if (videoPayload.action === ACTION.VIDEO_CALL_ACTION_SPONSOR_TIMEOUT) { | 310 | if (videoPayload.action === ACTION.VIDEO_CALL_ACTION_SPONSOR_TIMEOUT) { |
286 | this.$bus.$emit('missCall') | 311 | this.$bus.$emit("missCall"); |
287 | } | 312 | } |
288 | if (videoPayload.action === ACTION.VIDEO_CALL_ACTION_ACCEPTED) { | 313 | if (videoPayload.action === ACTION.VIDEO_CALL_ACTION_ACCEPTED) { |
289 | this.$bus.$emit('isAccept') | 314 | this.$bus.$emit("isAccept"); |
290 | } | 315 | } |
291 | if (videoPayload.action === ACTION.VIDEO_CALL_ACTION_HANGUP) { | 316 | if (videoPayload.action === ACTION.VIDEO_CALL_ACTION_HANGUP) { |
292 | this.$bus.$emit('isHungUp') | 317 | this.$bus.$emit("isHungUp"); |
293 | } | 318 | } |
294 | if (videoPayload.action === ACTION.VIDEO_CALL_ACTION_LINE_BUSY) { | 319 | if (videoPayload.action === ACTION.VIDEO_CALL_ACTION_LINE_BUSY) { |
295 | this.$bus.$emit('isRefused') | 320 | this.$bus.$emit("isRefused"); |
296 | } | 321 | } |
297 | if (videoPayload.action === ACTION.VIDEO_CALL_ACTION_ERROR) { | 322 | if (videoPayload.action === ACTION.VIDEO_CALL_ACTION_ERROR) { |
298 | this.$bus.$emit('isRefused') | 323 | this.$bus.$emit("isRefused"); |
299 | } | 324 | } |
300 | }, | 325 | }, |
301 | /** | 326 | /** |
... | @@ -304,32 +329,32 @@ export default { | ... | @@ -304,32 +329,32 @@ export default { |
304 | */ | 329 | */ |
305 | notifyMe(message) { | 330 | notifyMe(message) { |
306 | // 需检测浏览器支持和用户授权 | 331 | // 需检测浏览器支持和用户授权 |
307 | if (!('Notification' in window)) { | 332 | if (!("Notification" in window)) { |
308 | return | 333 | return; |
309 | } else if (window.Notification.permission === 'granted') { | 334 | } else if (window.Notification.permission === "granted") { |
310 | this.handleNotify(message) | 335 | this.handleNotify(message); |
311 | } else if (window.Notification.permission !== 'denied') { | 336 | } else if (window.Notification.permission !== "denied") { |
312 | window.Notification.requestPermission().then(permission => { | 337 | window.Notification.requestPermission().then((permission) => { |
313 | // 如果用户同意,就可以向他们发送通知 | 338 | // 如果用户同意,就可以向他们发送通知 |
314 | if (permission === 'granted') { | 339 | if (permission === "granted") { |
315 | this.handleNotify(message) | 340 | this.handleNotify(message); |
316 | } | 341 | } |
317 | }) | 342 | }); |
318 | } | 343 | } |
319 | }, | 344 | }, |
320 | handleNotify(message) { | 345 | handleNotify(message) { |
321 | const notification = new window.Notification('有人提到了你', { | 346 | const notification = new window.Notification("有人提到了你", { |
322 | icon: 'https://webim-1252463788.file.myqcloud.com/demo/img/logo.dc3be0d4.png', | 347 | icon: "https://webim-1252463788.file.myqcloud.com/demo/img/logo.dc3be0d4.png", |
323 | body: message.payload.text | 348 | body: message.payload.text, |
324 | }) | 349 | }); |
325 | notification.onclick = () => { | 350 | notification.onclick = () => { |
326 | window.focus() | 351 | window.focus(); |
327 | this.$store.dispatch('checkoutConversation', message.conversationID) | 352 | this.$store.dispatch("checkoutConversation", message.conversationID); |
328 | notification.close() | 353 | notification.close(); |
329 | } | 354 | }; |
330 | }, | 355 | }, |
331 | handleLinkClick() { | 356 | handleLinkClick() { |
332 | MTA.clickStat('link_two', {click: 'true'}) | 357 | MTA.clickStat("link_two", { click: "true" }); |
333 | }, | 358 | }, |
334 | /** | 359 | /** |
335 | * 收到有群成员退群/被踢出的groupTip时,需要将相关群成员从当前会话的群成员列表中移除 | 360 | * 收到有群成员退群/被踢出的groupTip时,需要将相关群成员从当前会话的群成员列表中移除 |
... | @@ -337,19 +362,28 @@ export default { | ... | @@ -337,19 +362,28 @@ export default { |
337 | */ | 362 | */ |
338 | handleQuitGroupTip(messageList) { | 363 | handleQuitGroupTip(messageList) { |
339 | // 筛选出当前会话的退群/被踢群的 groupTip | 364 | // 筛选出当前会话的退群/被踢群的 groupTip |
340 | const groupTips = messageList.filter(message => { | 365 | const groupTips = messageList.filter((message) => { |
341 | return this.currentConversation.conversationID === message.conversationID && | 366 | return ( |
342 | message.type === this.TIM.TYPES.MSG_GRP_TIP && | 367 | this.currentConversation.conversationID === message.conversationID && |
343 | (message.payload.operationType === this.TIM.TYPES.GRP_TIP_MBR_QUIT || | 368 | message.type === this.TIM.TYPES.MSG_GRP_TIP && |
344 | message.payload.operationType === this.TIM.TYPES.GRP_TIP_MBR_KICKED_OUT) | 369 | (message.payload.operationType === this.TIM.TYPES.GRP_TIP_MBR_QUIT || |
345 | }) | 370 | message.payload.operationType === |
371 | this.TIM.TYPES.GRP_TIP_MBR_KICKED_OUT) | ||
372 | ); | ||
373 | }); | ||
346 | // 清理当前会话的群成员列表 | 374 | // 清理当前会话的群成员列表 |
347 | if (groupTips.length > 0) { | 375 | if (groupTips.length > 0) { |
348 | groupTips.forEach(groupTip => { | 376 | groupTips.forEach((groupTip) => { |
349 | if (Array.isArray(groupTip.payload.userIDList) || groupTip.payload.userIDList.length > 0) { | 377 | if ( |
350 | this.$store.commit('deleteGroupMemberList', groupTip.payload.userIDList) | 378 | Array.isArray(groupTip.payload.userIDList) || |
379 | groupTip.payload.userIDList.length > 0 | ||
380 | ) { | ||
381 | this.$store.commit( | ||
382 | "deleteGroupMemberList", | ||
383 | groupTip.payload.userIDList | ||
384 | ); | ||
351 | } | 385 | } |
352 | }) | 386 | }); |
353 | } | 387 | } |
354 | }, | 388 | }, |
355 | /** | 389 | /** |
... | @@ -357,22 +391,25 @@ export default { | ... | @@ -357,22 +391,25 @@ export default { |
357 | * @param {Message[]} messageList | 391 | * @param {Message[]} messageList |
358 | */ | 392 | */ |
359 | handleCloseGroupLive(messageList) { | 393 | handleCloseGroupLive(messageList) { |
360 | messageList.forEach(message => { | 394 | messageList.forEach((message) => { |
361 | if (this.currentConversation.conversationID === message.conversationID && message.type === this.TIM.TYPES.MSG_CUSTOM) { | 395 | if ( |
362 | let data = {} | 396 | this.currentConversation.conversationID === message.conversationID && |
397 | message.type === this.TIM.TYPES.MSG_CUSTOM | ||
398 | ) { | ||
399 | let data = {}; | ||
363 | try { | 400 | try { |
364 | data = JSON.parse(message.payload.data) | 401 | data = JSON.parse(message.payload.data); |
365 | } catch (e) { | 402 | } catch (e) { |
366 | data = {} | 403 | data = {}; |
367 | } | 404 | } |
368 | if (data.roomId && Number(data.roomStatus) === 0) { | 405 | if (data.roomId && Number(data.roomStatus) === 0) { |
369 | this.$bus.$emit('close-group-live') | 406 | this.$bus.$emit("close-group-live"); |
370 | } | 407 | } |
371 | } | 408 | } |
372 | }) | 409 | }); |
373 | }, | 410 | }, |
374 | } | 411 | }, |
375 | } | 412 | }; |
376 | </script> | 413 | </script> |
377 | 414 | ||
378 | <style lang="stylus"> | 415 | <style lang="stylus"> | ... | ... |
1 | import request from './request' | 1 | import request from "./request"; |
2 | 2 | ||
3 | export default class Helper { | 3 | export default class Helper { |
4 | static getKey() { | ||
5 | return parseInt(process.env.VUE_APP_API_KEY); | ||
6 | } | ||
4 | 7 | ||
5 | static getKey() { | 8 | static getSecret() { |
6 | return parseInt(process.env.VUE_APP_API_KEY) | 9 | return process.env.VUE_APP_API_SECRET; |
7 | } | 10 | } |
8 | 11 | ||
9 | static getSecret() { | 12 | static getExpire() { |
10 | return process.env.VUE_APP_API_SECRET | 13 | return parseInt(process.env.VUE_APP_API_EXPIRETIME); |
11 | } | 14 | } |
12 | 15 | ||
13 | static getExpire() { | 16 | static getUrlKey(name) { |
14 | return parseInt(process.env.VUE_APP_API_EXPIRETIME) | 17 | return ( |
15 | } | 18 | decodeURIComponent( |
16 | 19 | (new RegExp("[?|&]" + name + "=" + "([^&;]+?)(&|#|;|$)").exec( | |
17 | 20 | location.href | |
18 | static getUrlKey(name) { | 21 | ) || [, ""])[1].replace(/\+/g, "%20") |
19 | return decodeURIComponent((new RegExp('[?|&]' + name + '=' + '([^&;]+?)(&|#|;|$)').exec(location.href) || [, ''])[1].replace(/\+/g, '%20')) || null | 22 | ) || null |
20 | } | 23 | ); |
21 | 24 | } | |
22 | static getToken() { | 25 | |
23 | return this.getUrlKey('token') | 26 | static getToken() { |
24 | } | 27 | return this.getUrlKey("token"); |
25 | 28 | } | |
26 | static getSignature(userID) { | 29 | |
27 | const generator = new window.LibGenerateTestUserSig(this.getKey(), this.getSecret(), this.getExpire()) | 30 | static getSignature(userID) { |
28 | return generator.genTestUserSig(userID) | 31 | const generator = new window.LibGenerateTestUserSig( |
29 | } | 32 | this.getKey(), |
30 | 33 | this.getSecret(), | |
31 | /** | 34 | this.getExpire() |
32 | * | 35 | ); |
33 | * @returns {Promise<never>|Promise<{sign, id}>} | 36 | return generator.genTestUserSig(userID); |
34 | */ | 37 | } |
35 | static verifyToken() { | 38 | |
36 | return request.get('auth').then(res => { | 39 | /** |
37 | const {esm_id} = res.data | 40 | * |
38 | return Promise.resolve({id: esm_id, sign: this.getSignature(esm_id)}) | 41 | * @returns {Promise<never>|Promise<{sign, id}>} |
39 | }) | 42 | */ |
40 | } | 43 | static verifyToken() { |
41 | 44 | return request.get("auth").then((res) => { | |
42 | static contactList(params = {}) { | 45 | const { esm_id } = res.data; |
43 | return request.get('im/contacts', {params}) | 46 | return Promise.resolve({ id: esm_id, sign: this.getSignature(esm_id) }); |
44 | } | 47 | }); |
45 | 48 | } | |
46 | static groupList(params = {}) { | 49 | |
47 | return request.get('im/groups', {params}) | 50 | static contactList(params = {}) { |
48 | } | 51 | return request.get("im/contacts", { params }); |
49 | 52 | } | |
50 | static groupMemberList(group, params = {}) { | 53 | |
51 | return request.get(`im/groups/${group}/members`, {params}) | 54 | static groupList(params = {}) { |
52 | } | 55 | return request.get("im/groups", { params }); |
53 | 56 | } | |
54 | static groupMemberDelete(group, member) { | 57 | |
55 | return request.delete(`im/groups/${group}/members/${member}`) | 58 | static groupMemberList(group, params = {}) { |
56 | } | 59 | return request.get(`im/groups/${group}/members`, { params }); |
57 | 60 | } | |
58 | static joinGroup(id, member) { | 61 | |
59 | return request.post(`im/groups/${id}/members`, {member}) | 62 | static groupMemberDelete(group, member) { |
60 | } | 63 | return request.delete(`im/groups/${group}/members/${member}`); |
64 | } | ||
65 | |||
66 | static joinGroup(id, member) { | ||
67 | return request.post(`im/groups/${id}/members`, { member }); | ||
68 | } | ||
61 | } | 69 | } | ... | ... |
src/utils/hrequest.js
0 → 100644
1 | import axios from 'axios' | 1 | import axios from "axios"; |
2 | import Helper from './helper' | 2 | import Helper from "./helper"; |
3 | import Store from '../store' | 3 | import Store from "../store"; |
4 | import tim from '../tim' | 4 | import tim from "../tim"; |
5 | |||
6 | 5 | ||
7 | const service = axios.create({ | 6 | const service = axios.create({ |
8 | baseURL: process.env.VUE_APP_API_URL, | 7 | baseURL: process.env.VUE_APP_API_URL, |
9 | // withCredentials: true, // send cookies when cross-domain requests | 8 | // withCredentials: true, // send cookies when cross-domain requests |
10 | timeout: 5000 // request timeout | 9 | timeout: 5000, // request timeout |
11 | }) | 10 | }); |
12 | 11 | ||
13 | service.interceptors.request.use(config => { | 12 | service.interceptors.request.use( |
14 | config.headers['Authorization'] = 'Bearer ' + Helper.getToken() | 13 | (config) => { |
15 | config.headers['Accept'] = 'application/json' | 14 | config.headers["Authorization"] = "Bearer " + Helper.getToken(); |
16 | return config | 15 | config.headers["Accept"] = "application/json"; |
17 | }, error => { | 16 | return config; |
18 | return Promise.reject(error) | 17 | }, |
19 | }) | 18 | (error) => { |
19 | return Promise.reject(error); | ||
20 | } | ||
21 | ); | ||
20 | 22 | ||
21 | service.interceptors.response.use(response => { | 23 | service.interceptors.response.use( |
24 | (response) => { | ||
22 | switch (response.data.code) { | 25 | switch (response.data.code) { |
23 | case 200: | 26 | case 200: |
24 | return response.data | 27 | return response.data; |
25 | case 401: | 28 | case 401: |
26 | Store.commit('showMessage', {type: 'error', message: '身份信息已失效,请重新登录'}) | 29 | Store.commit("showMessage", { |
27 | tim.logout().then(() => { | 30 | type: "error", |
28 | Store.commit('user/toggleIsLogin') | 31 | message: "身份信息已失效,请重新登录", |
29 | Store.commit('user/stopComputeCurrent') | 32 | }); |
30 | Store.commit('user/reset') | 33 | tim.logout().then(() => { |
31 | }) | 34 | Store.commit("user/toggleIsLogin"); |
32 | break | 35 | Store.commit("user/stopComputeCurrent"); |
33 | default: | 36 | Store.commit("user/reset"); |
34 | return Promise.reject(response.data) | 37 | }); |
38 | break; | ||
39 | default: | ||
40 | return Promise.reject(response.data); | ||
35 | } | 41 | } |
36 | }, error => { | 42 | }, |
37 | return Promise.reject(error) | 43 | (error) => { |
38 | }) | 44 | return Promise.reject(error); |
45 | } | ||
46 | ); | ||
39 | 47 | ||
40 | export default service | 48 | export default service; | ... | ... |
-
Please register or sign in to post a comment