Merge branch 'develop'
Showing
15 changed files
with
408 additions
and
183 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
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
| 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 |
| 104 | .dispatch("getGroupMemberList", this.groupProfile.groupID) | ||
| 84 | .then(() => { | 105 | .then(() => { |
| 85 | this.count += 30 | 106 | this.count += 30; |
| 86 | }) | 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 | }) | ||
| 127 | }) | 154 | }) |
| 128 | break | 155 | .catch((err) => { |
| 129 | case 'delete': | 156 | this.$store.commit("showMessage", { |
| 130 | break | 157 | message: err, |
| 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> |
| ... | @@ -2,18 +2,36 @@ | ... | @@ -2,18 +2,36 @@ |
| 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=" |
| 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" | ||
| 12 | :message="message" | 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> | ... | ... |
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
| 1 | import request from './request' | 1 | import request from "./request"; |
| 2 | 2 | ||
| 3 | export default class Helper { | 3 | export default class Helper { |
| 4 | |||
| 5 | static getKey() { | 4 | static getKey() { |
| 6 | return parseInt(process.env.VUE_APP_API_KEY) | 5 | return parseInt(process.env.VUE_APP_API_KEY); |
| 7 | } | 6 | } |
| 8 | 7 | ||
| 9 | static getSecret() { | 8 | static getSecret() { |
| 10 | return process.env.VUE_APP_API_SECRET | 9 | return process.env.VUE_APP_API_SECRET; |
| 11 | } | 10 | } |
| 12 | 11 | ||
| 13 | static getExpire() { | 12 | static getExpire() { |
| 14 | return parseInt(process.env.VUE_APP_API_EXPIRETIME) | 13 | return parseInt(process.env.VUE_APP_API_EXPIRETIME); |
| 15 | } | 14 | } |
| 16 | 15 | ||
| 17 | |||
| 18 | static getUrlKey(name) { | 16 | static getUrlKey(name) { |
| 19 | return decodeURIComponent((new RegExp('[?|&]' + name + '=' + '([^&;]+?)(&|#|;|$)').exec(location.href) || [, ''])[1].replace(/\+/g, '%20')) || null | 17 | return ( |
| 18 | decodeURIComponent( | ||
| 19 | (new RegExp("[?|&]" + name + "=" + "([^&;]+?)(&|#|;|$)").exec( | ||
| 20 | location.href | ||
| 21 | ) || [, ""])[1].replace(/\+/g, "%20") | ||
| 22 | ) || null | ||
| 23 | ); | ||
| 20 | } | 24 | } |
| 21 | 25 | ||
| 22 | static getToken() { | 26 | static getToken() { |
| 23 | return this.getUrlKey('token') | 27 | return this.getUrlKey("token"); |
| 24 | } | 28 | } |
| 25 | 29 | ||
| 26 | static getSignature(userID) { | 30 | static getSignature(userID) { |
| 27 | const generator = new window.LibGenerateTestUserSig(this.getKey(), this.getSecret(), this.getExpire()) | 31 | const generator = new window.LibGenerateTestUserSig( |
| 28 | return generator.genTestUserSig(userID) | 32 | this.getKey(), |
| 33 | this.getSecret(), | ||
| 34 | this.getExpire() | ||
| 35 | ); | ||
| 36 | return generator.genTestUserSig(userID); | ||
| 29 | } | 37 | } |
| 30 | 38 | ||
| 31 | /** | 39 | /** |
| ... | @@ -33,29 +41,29 @@ export default class Helper { | ... | @@ -33,29 +41,29 @@ export default class Helper { |
| 33 | * @returns {Promise<never>|Promise<{sign, id}>} | 41 | * @returns {Promise<never>|Promise<{sign, id}>} |
| 34 | */ | 42 | */ |
| 35 | static verifyToken() { | 43 | static verifyToken() { |
| 36 | return request.get('auth').then(res => { | 44 | return request.get("auth").then((res) => { |
| 37 | const {esm_id} = res.data | 45 | const { esm_id } = res.data; |
| 38 | return Promise.resolve({id: esm_id, sign: this.getSignature(esm_id)}) | 46 | return Promise.resolve({ id: esm_id, sign: this.getSignature(esm_id) }); |
| 39 | }) | 47 | }); |
| 40 | } | 48 | } |
| 41 | 49 | ||
| 42 | static contactList(params = {}) { | 50 | static contactList(params = {}) { |
| 43 | return request.get('im/contacts', {params}) | 51 | return request.get("im/contacts", { params }); |
| 44 | } | 52 | } |
| 45 | 53 | ||
| 46 | static groupList(params = {}) { | 54 | static groupList(params = {}) { |
| 47 | return request.get('im/groups', {params}) | 55 | return request.get("im/groups", { params }); |
| 48 | } | 56 | } |
| 49 | 57 | ||
| 50 | static groupMemberList(group, params = {}) { | 58 | static groupMemberList(group, params = {}) { |
| 51 | return request.get(`im/groups/${group}/members`, {params}) | 59 | return request.get(`im/groups/${group}/members`, { params }); |
| 52 | } | 60 | } |
| 53 | 61 | ||
| 54 | static groupMemberDelete(group, member) { | 62 | static groupMemberDelete(group, member) { |
| 55 | return request.delete(`im/groups/${group}/members/${member}`) | 63 | return request.delete(`im/groups/${group}/members/${member}`); |
| 56 | } | 64 | } |
| 57 | 65 | ||
| 58 | static joinGroup(id, member) { | 66 | static joinGroup(id, member) { |
| 59 | return request.post(`im/groups/${id}/members`, {member}) | 67 | return request.post(`im/groups/${id}/members`, { member }); |
| 60 | } | 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", { |
| 30 | type: "error", | ||
| 31 | message: "身份信息已失效,请重新登录", | ||
| 32 | }); | ||
| 27 | tim.logout().then(() => { | 33 | tim.logout().then(() => { |
| 28 | Store.commit('user/toggleIsLogin') | 34 | Store.commit("user/toggleIsLogin"); |
| 29 | Store.commit('user/stopComputeCurrent') | 35 | Store.commit("user/stopComputeCurrent"); |
| 30 | Store.commit('user/reset') | 36 | Store.commit("user/reset"); |
| 31 | }) | 37 | }); |
| 32 | break | 38 | break; |
| 33 | default: | 39 | default: |
| 34 | return Promise.reject(response.data) | 40 | return Promise.reject(response.data); |
| 41 | } | ||
| 42 | }, | ||
| 43 | (error) => { | ||
| 44 | return Promise.reject(error); | ||
| 35 | } | 45 | } |
| 36 | }, error => { | 46 | ); |
| 37 | return Promise.reject(error) | ||
| 38 | }) | ||
| 39 | 47 | ||
| 40 | export default service | 48 | export default service; | ... | ... |
-
Please register or sign in to post a comment