index.vue 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292
  1. <template>
  2. <view class="message-v">
  3. <view class="search-box">
  4. <u-search :placeholder=" $t('app.apply.pleaseKeyword')" v-model="keyword" height="72" :show-action="false"
  5. @change="search" bg-color="#f0f2f6" shape="square" style="width: 100%;">
  6. </u-search>
  7. </view>
  8. <mescroll-body ref="mescrollRef" @init="mescrollInit" @down="downCallback" @up="upCallback" :sticky="false"
  9. :down="downOption" :up="upOption" :bottombar="false">
  10. <view class="message-list">
  11. <view class="message-list-box">
  12. <SwipeItem :list="list" :buttons="options" @action="handleRelocation" ref="swipeItem">
  13. <template v-slot="{ item }">
  14. <view class="reply-item u-border-bottom u-flex" @click="toIm(item)">
  15. <view class="reply-item-img">
  16. <u-avatar :src="baseURL+item.headIcon" mode="square" size="96" />
  17. </view>
  18. <view class="reply-item-txt u-flex-1">
  19. <view class="reply-item-cell reply-item-title u-flex u-row-between">
  20. <text class="title">{{item.realName}}/{{item.account}}</text>
  21. <text class="u-font-24 againColor">{{jnpf.toDateText(item.latestDate)}}</text>
  22. </view>
  23. <view class="reply-item-cell u-flex u-row-between">
  24. <text
  25. class="reply-item-txt-msg u-line-1 againColor">{{getMsgText(item.latestMessage,item.messageType)}}</text>
  26. <u-badge type="error" :count="item.unreadMessage" :absolute="false" />
  27. </view>
  28. </view>
  29. </view>
  30. </template>
  31. </SwipeItem>
  32. </view>
  33. </view>
  34. </mescroll-body>
  35. <!-- -->
  36. </view>
  37. </template>
  38. <script>
  39. import MescrollMixin from "@/uni_modules/mescroll-uni/components/mescroll-uni/mescroll-mixins.js";
  40. import SwipeItem from "@/components/SwipeItem/index"
  41. import resources from '@/libs/resources.js'
  42. import {
  43. useChatStore
  44. } from '@/store/modules/chat'
  45. import {
  46. getIMReply,
  47. relocation
  48. } from '@/api/message.js'
  49. export default {
  50. mixins: [MescrollMixin],
  51. components: {
  52. SwipeItem
  53. },
  54. data() {
  55. return {
  56. downOption: {
  57. use: true,
  58. auto: true
  59. },
  60. upOption: {
  61. page: {
  62. num: 0,
  63. size: 20,
  64. time: null
  65. },
  66. empty: {
  67. use: true,
  68. icon: resources.message.nodata,
  69. tip: this.$t('common.noData'),
  70. fixed: true,
  71. top: "300rpx",
  72. }
  73. },
  74. key: +new Date(),
  75. keyword: '',
  76. list: [],
  77. options: [{
  78. text: '移除',
  79. style: {
  80. backgroundColor: '#dd524d',
  81. },
  82. value: 'delete'
  83. }],
  84. swipeAction: false
  85. }
  86. },
  87. computed: {
  88. msgInfo() {
  89. const chatStore = useChatStore()
  90. return chatStore.getMsgInfo
  91. },
  92. baseURL() {
  93. return this.define.baseURL
  94. },
  95. },
  96. onLoad() {
  97. this.keyword = ''
  98. uni.$on('updateList', data => {
  99. this.$nextTick(() => {
  100. this.mescroll.triggerDownScroll()
  101. })
  102. })
  103. uni.$on('updateMsgNum', id => {
  104. this.updateMsgNum(id)
  105. })
  106. },
  107. onUnload() {
  108. uni.$off('updateList')
  109. uni.$off('updateMsgNum')
  110. },
  111. methods: {
  112. handleRelocation(data) {
  113. let {
  114. index,
  115. action,
  116. btn,
  117. item
  118. } = data
  119. this.list.splice(index, 1)
  120. relocation(item.id).then(res => {
  121. this.init({
  122. ...this.upOption.page
  123. })
  124. })
  125. },
  126. upCallback(page) {
  127. this.init(page)
  128. },
  129. init(page) {
  130. let query = {
  131. currentPage: page.num,
  132. pageSize: page.size,
  133. keyword: this.keyword
  134. }
  135. getIMReply(query).then(res => {
  136. this.mescroll.endSuccess(res.data.list.length, false);
  137. this.list = res.data.list || [];
  138. this.swipeAction = true
  139. uni.hideLoading()
  140. }).catch(() => {
  141. this.mescroll && this.mescroll.endErr();
  142. })
  143. },
  144. search() {
  145. this.searchTimer && clearTimeout(this.searchTimer)
  146. this.searchTimer = setTimeout(() => {
  147. this.list = [];
  148. this.mescroll.resetUpScroll();
  149. }, 300)
  150. },
  151. updateMsgNum(id) {
  152. const chatStore = useChatStore()
  153. const len = this.list.length
  154. for (let i = 0; i < len; i++) {
  155. if (id === this.list[i].id) {
  156. const num = this.list[i].unreadMessage
  157. chatStore.reduceBadgeNum(num)
  158. this.list[i].unreadMessage = 0
  159. break
  160. }
  161. }
  162. },
  163. getMsgText(text, type) {
  164. if (type === 'voice') return '[语音]';
  165. if (type === 'image') return '[图片]';
  166. return text;
  167. },
  168. toIm(item) {
  169. const chatStore = useChatStore()
  170. const name = item.realName + '/' + item.account
  171. if (item.unreadMessage) {
  172. chatStore.reduceBadgeNum(item.unreadMessage)
  173. item.unreadMessage = 0
  174. }
  175. this.$nextTick(() => {
  176. this.$refs.swipeItem.closeSwipe()
  177. })
  178. uni.navigateTo({
  179. url: '/pages/message/im/index?name=' + item.realName + '/' + item.account + '&formUserId=' +
  180. item.id + '&headIcon=' + item.headIcon
  181. })
  182. }
  183. }
  184. }
  185. </script>
  186. <style lang="scss">
  187. page {
  188. background-color: #f0f2f6;
  189. }
  190. .message-v {
  191. .search-box {
  192. height: 120rpx;
  193. padding: 0rpx 20rpx;
  194. display: flex;
  195. align-items: center;
  196. background-color: #fff;
  197. margin-bottom: 16rpx;
  198. }
  199. .replyList {
  200. padding: 0 20rpx;
  201. background-color: #fff;
  202. .againColor {
  203. color: #909399;
  204. }
  205. }
  206. .reply-item {
  207. height: 142rpx;
  208. background-color: #fff;
  209. padding: 0 20rpx;
  210. .reply-item-img-sysMsg {
  211. width: 96rpx;
  212. height: 96rpx;
  213. border-radius: 16rpx;
  214. overflow: hidden;
  215. margin-right: 16rpx;
  216. flex-shrink: 0;
  217. }
  218. .reply-item-img {
  219. width: 96rpx;
  220. height: 96rpx;
  221. border-radius: 50%;
  222. overflow: hidden;
  223. margin-right: 16rpx;
  224. flex-shrink: 0;
  225. }
  226. .reply-item-icon-color {
  227. background-color: #2bd34f;
  228. }
  229. .reply-item-icon-color2 {
  230. background-color: #3B87F7;
  231. }
  232. .reply-item-icon {
  233. .icon-ym {
  234. color: #fff;
  235. font-size: 50rpx;
  236. }
  237. }
  238. .reply-item-txt {
  239. .reply-item-cell {
  240. height: 40rpx;
  241. color: #C6C6C6;
  242. font-size: 24rpx;
  243. &.reply-item-title {
  244. height: 44rpx;
  245. margin-bottom: 4px;
  246. .title {
  247. font-size: 28rpx;
  248. color: #303133;
  249. }
  250. }
  251. .reply-item-txt-msg {
  252. width: 480rpx;
  253. }
  254. }
  255. }
  256. }
  257. }
  258. .search-box_sticky {
  259. padding: 0 32rpx;
  260. }
  261. .message-list .uni-swipe {
  262. margin-bottom: 0px !important;
  263. border-radius: 0px !important;
  264. }
  265. .message-list {
  266. .message-list-box {
  267. margin: 0px !important;
  268. ::v-deep .u-swipe-action {
  269. border-radius: 0;
  270. }
  271. }
  272. }
  273. </style>