index.vue 32 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043
  1. <template>
  2. <view class="conversation_container">
  3. <u-navbar :placeholder="true">
  4. <view slot="left">
  5. <u-icon name="arrow-left" color="#000" size="28" @click="gotoPage('/pages/index/index')"></u-icon>
  6. </view>
  7. <view slot="center">
  8. 消息
  9. </view>
  10. </u-navbar>
  11. <template v-if="pinConversationList.length || conversationList.length">
  12. <!-- 搜索会话列表相关 -->
  13. <view>
  14. <view class="search_container" v-if="isShowDefaultSearch">
  15. <view class="search_icon_box" @tap="openSearch">
  16. <icon type="search" size="22"></icon>
  17. <text class="search_text">搜索</text>
  18. </view>
  19. </view>
  20. </view>
  21. <view class="searching_container" v-if="!isShowDefaultSearch">
  22. <u-search
  23. class="searching_input"
  24. height="36"
  25. v-model.trim="searchInputKeywords"
  26. shape="square"
  27. placeholder="搜索"
  28. :actionText="'取消'"
  29. :actionStyle="{
  30. color: '#0873de',
  31. }"
  32. :clearabled="true"
  33. :focus="true"
  34. @search="actionSearch"
  35. @input="actionSearch"
  36. @custom="cancelSearch"
  37. ></u-search>
  38. </view>
  39. <!-- 展示搜索会话结果List -->
  40. <template v-if="!isShowDefaultSearch">
  41. <u-list
  42. v-if="searchResConversationList.length > 0"
  43. :height="conversationListHeight"
  44. >
  45. <u-list-item
  46. v-for="conversationItem in searchResConversationList"
  47. :key="conversationItem.conversationId"
  48. >
  49. <u-cell @click="entryChatPage(conversationItem)">
  50. <!-- 头像 -->
  51. <u-avatar
  52. slot="icon"
  53. shape="square"
  54. size="50"
  55. :src="showConversationAvatar(conversationItem)"
  56. customStyle="margin: -3px 5px -3px 0"
  57. ></u-avatar>
  58. <!-- name -->
  59. <view class="conversation_item_title" slot="title">
  60. <u--text
  61. class="conversation_item_title_text"
  62. :lines="1"
  63. :text="showConversationName(conversationItem)"
  64. :suffixIcon="
  65. conversationItemSilentStatus(
  66. conversationItem.conversationId
  67. )
  68. ? '/static/images/new_ui/no_disturbing.png'
  69. : ''
  70. "
  71. iconStyle="margin-left: 2px;"
  72. >
  73. </u--text>
  74. </view>
  75. <!-- lastmsg -->
  76. <u--text
  77. slot="label"
  78. :lines="1"
  79. :text="handleLastMsgContent(conversationItem.lastMessage)"
  80. ></u--text>
  81. <!-- time&unReadNum -->
  82. <view slot="value" class="conversation_item_right">
  83. <view>
  84. <view class="conversation_item_time">{{
  85. handleTime(conversationItem)
  86. }}</view>
  87. <view class="conversation_item_unread">
  88. <u-badge
  89. class="conversation_item_badge"
  90. type="primary"
  91. max="99"
  92. :isDot="
  93. (conversationItemSilentStatus(
  94. conversationItem.conversationId
  95. ) &&
  96. conversationItem.unReadCount > 0) ||
  97. conversationItem.isRead === false
  98. "
  99. :offset="[15, 0]"
  100. :absolute="true"
  101. :value="conversationItem.unReadCount"
  102. ></u-badge>
  103. </view>
  104. </view>
  105. </view>
  106. </u-cell>
  107. </u-list-item>
  108. </u-list>
  109. <u-empty v-if="searchResConversationList.length === 0" mode="search">
  110. </u-empty>
  111. </template>
  112. <!-- 会话列表展示相关 -->
  113. <template v-else>
  114. <u-list @scrolltolower="scrolltolower" :height="conversationListHeight">
  115. <!-- 系统通知 -->
  116. <!-- <u-list-item v-if="lastInformData">
  117. <u-cell title="系统通知" value="系统通知哈哈哈哈">
  118. <u-avatar
  119. slot="icon"
  120. shape="square"
  121. size="35"
  122. src="../../static/images/inform.png"
  123. customStyle="margin: -3px 5px -3px 0"
  124. ></u-avatar>
  125. <text slot="value" class="u-slot-value">{{
  126. handleTime(lastInformData)
  127. }}</text>
  128. </u-cell>
  129. </u-list-item> -->
  130. <!-- 置顶会话列表 -->
  131. <template v-if="pinConversationList.length">
  132. <u-list-item
  133. v-for="(conversationItem, index) in pinConversationList"
  134. :key="conversationItem.conversationId"
  135. >
  136. <view
  137. class="pinconversation_item"
  138. @longpress="onConversationMoreFunction(conversationItem)"
  139. @click="entryChatPage(conversationItem)"
  140. >
  141. <u-cell>
  142. <!-- 头像 -->
  143. <u-avatar
  144. slot="icon"
  145. shape="square"
  146. size="50"
  147. :src="showConversationAvatar(conversationItem)"
  148. customStyle="margin: -3px 5px -3px 0"
  149. ></u-avatar>
  150. <!-- name -->
  151. <view class="conversation_item_title" slot="title">
  152. <u--text
  153. class="conversation_item_title_text"
  154. :lines="1"
  155. :text="showConversationName(conversationItem)"
  156. :suffixIcon="
  157. conversationItemSilentStatus(
  158. conversationItem.conversationId
  159. )
  160. ? '/static/images/new_ui/no_disturbing.png'
  161. : ''
  162. "
  163. iconStyle="margin-left: 2px;"
  164. >
  165. </u--text>
  166. </view>
  167. <!-- lastmsg -->
  168. <u--text
  169. slot="label"
  170. :lines="1"
  171. :text="handleLastMsgContent(conversationItem.lastMessage)"
  172. ></u--text>
  173. <!-- time&unReadNum -->
  174. <view slot="value" class="conversation_item_right">
  175. <view>
  176. <view class="conversation_item_time">{{
  177. handleTime(conversationItem)
  178. }}</view>
  179. <view class="conversation_item_unread">
  180. <u-badge
  181. class="conversation_item_badge"
  182. type="primary"
  183. max="99"
  184. :isDot="
  185. (conversationItemSilentStatus(
  186. conversationItem.conversationId
  187. ) &&
  188. conversationItem.unReadCount > 0) ||
  189. conversationItem.isRead === false
  190. "
  191. :offset="[15, 0]"
  192. :absolute="true"
  193. :value="conversationItem.unReadCount"
  194. ></u-badge>
  195. </view>
  196. </view>
  197. </view>
  198. </u-cell>
  199. </view>
  200. </u-list-item>
  201. </template>
  202. <!-- 普通会话列表 -->
  203. <u-list-item
  204. class="conversation_item"
  205. v-for="(conversationItem, index) in conversationList"
  206. :key="conversationItem.conversationId"
  207. >
  208. <template>
  209. <!-- <swipe-delete @deleteChatItem="handleDelete(conversationItem)"> -->
  210. <swipe-delete>
  211. <view
  212. @longpress="onConversationMoreFunction(conversationItem)"
  213. @click="entryChatPage(conversationItem)"
  214. >
  215. <u-cell>
  216. <!-- 头像 -->
  217. <u-avatar
  218. slot="icon"
  219. shape="square"
  220. size="50"
  221. :src="showConversationAvatar(conversationItem)"
  222. customStyle="margin: -3px 5px -3px 0"
  223. ></u-avatar>
  224. <!-- name -->
  225. <view class="conversation_item_title" slot="title">
  226. <u--text
  227. class="conversation_item_title_text"
  228. :lines="1"
  229. :text="showConversationName(conversationItem)"
  230. :suffixIcon="
  231. conversationItemSilentStatus(
  232. conversationItem.conversationId
  233. )
  234. ? '/static/images/new_ui/no_disturbing.png'
  235. : ''
  236. "
  237. iconStyle="margin-left: 2px;"
  238. >
  239. </u--text>
  240. </view>
  241. <!-- lastmsg -->
  242. <u--text
  243. slot="label"
  244. :lines="1"
  245. :text="handleLastMsgContent(conversationItem.lastMessage)"
  246. ></u--text>
  247. <!-- time&unReadNum -->
  248. <view slot="value" class="conversation_item_right">
  249. <view>
  250. <view class="conversation_item_time">{{
  251. handleTime(conversationItem)
  252. }}</view>
  253. <view class="conversation_item_unread">
  254. <u-badge
  255. class="conversation_item_badge"
  256. type="primary"
  257. max="99"
  258. :isDot="
  259. (conversationItemSilentStatus(
  260. conversationItem.conversationId
  261. ) &&
  262. conversationItem.unReadCount > 0) ||
  263. conversationItem.isRead === false
  264. "
  265. :offset="[15, 0]"
  266. :absolute="true"
  267. :value="conversationItem.unReadCount"
  268. ></u-badge>
  269. </view>
  270. </view>
  271. </view>
  272. </u-cell>
  273. </view>
  274. </swipe-delete>
  275. </template>
  276. </u-list-item>
  277. </u-list>
  278. <u-action-sheet
  279. :actions="moreFunctionList"
  280. :closeOnClickOverlay="true"
  281. :closeOnClickAction="true"
  282. :safeAreaInsetBottom="true"
  283. :show="isShowMoreFunction"
  284. round="5"
  285. @select="onSelectClick"
  286. @close="onConversationMoreFunction"
  287. ></u-action-sheet>
  288. </template>
  289. </template>
  290. <u-empty v-else mode="history"> </u-empty>
  291. </view>
  292. </template>
  293. <script>
  294. import { EMClient } from "@/EaseIM";
  295. import {
  296. selectMerchant,
  297. selectMerchantOrder,
  298. payUserList
  299. } from '@/commit/shop.js'
  300. import {
  301. MESSAGE_TYPE,
  302. SESSION_MESSAGE_TYPE,
  303. CUSTOM_TYPE,
  304. CHAT_TYPE,
  305. } from '@/EaseIM/constant';
  306. // import swipeDelete from '../../components/swipedelete/swipedelete';
  307. import { emConversation,emConnect } from '@/EaseIM/emApis';
  308. // const { sendChannelAck } = emConversation();
  309. const tabBarHeight = 50;
  310. const navBarHeight = 44;
  311. const searchInputHeight = 45;
  312. const { loginWithPassword } = emConnect();
  313. import { emHandleReconnect } from "@/EaseIM/utils";
  314. export default {
  315. data() {
  316. return {
  317. nowConversationIntem:{},
  318. chatUserList:[],//会话列表用户数组
  319. loginEaseIMId:'',//环信的userid
  320. MESSAGE_TYPE,
  321. isShowDefaultSearch: true,
  322. searchResConversationList: [], //开启搜索时的会话列表
  323. searchInputKeywords: '',
  324. conversationListHeight: '100vh',
  325. // defaultAvatar: '/static/images/new_ui/defaultAvatar.png',
  326. // defaultAvatar: 'https://cdn.bjtdba.com/chuxubao/images/2024-04-24/2bc4c202404241807123503.jpg',
  327. defaultAvatar: ' https://app.bjtdba.com/uploads/logo.jpg',
  328. defaultGroupAvatar: '/static/images/new_ui/defaultGroupAvatar.png',
  329. longPressCheckedConversationItem: {},
  330. isShowMoreFunction: false,
  331. moreFunctionList: [
  332. {
  333. name: '会话置顶',
  334. type: 1,
  335. color: '#009EFF',
  336. fontSize: '15',
  337. },
  338. {
  339. name: '会话免打扰',
  340. type: 2,
  341. color: '#009EFF',
  342. fontSize: '15',
  343. },
  344. {
  345. name: '标记已读',
  346. type: 3,
  347. color: '#009EFF',
  348. fontSize: '15',
  349. },
  350. {
  351. name: '删除会话',
  352. type: 0,
  353. color: '#FF002B',
  354. fontSize: '15',
  355. },
  356. ],
  357. };
  358. },
  359. components: {
  360. // swipeDelete,
  361. },
  362. onShow() {
  363. let authorization = uni.getStorageSync('authorization')
  364. let userinfo = uni.getStorageSync('userinfo')
  365. let selectmerchant = uni.getStorageSync('selectmerchant')
  366. let uid = userinfo.uid
  367. if (authorization && uid) {
  368. if (selectmerchant.merId >= 0 && selectmerchant.status == -1) {
  369. uni.redirectTo({
  370. url: "/openmerchant/guide/index" //有或者没有商户 没有金额支付and激活码支付
  371. });
  372. return
  373. } else if (selectmerchant.merId > 0 && (selectmerchant.status == 1 || selectmerchant.status == 5)) {
  374. // uni.showLoading({
  375. // title: '加载中',
  376. // mask: true
  377. // });
  378. this.selectMerchant()
  379. this.selectMerchantOrder()
  380. this.payUserList()
  381. return
  382. } else if (selectmerchant.merId >= 0 && (selectmerchant.status == 3 || selectmerchant.status == 4)) {
  383. uni.redirectTo({
  384. url: '/openmerchant/shopentry/process?mer_id=' + selectmerchant.merId //已开通商户未填写资料
  385. });
  386. return
  387. } else if (selectmerchant.merId > 0 && selectmerchant.status == 0) {
  388. uni.redirectTo({
  389. url: '/openmerchant/shopentry/processaudit?submitCode=' + 3 //已开通商户待审核
  390. });
  391. return
  392. } else if (selectmerchant.merId > 0 && selectmerchant.status == 2) {
  393. uni.redirectTo({
  394. url: '/openmerchant/shopentry/processaudit?submitCode=' + 2 //已开通商户审核拒绝
  395. });
  396. return
  397. }
  398. } else {
  399. uni.redirectTo({
  400. url: "/pages/user/login/index"
  401. });
  402. }
  403. },
  404. computed: {
  405. loginUserProfiles() {
  406. return this.$store.state.LoginStore.loginUserProfiles;
  407. },
  408. //用户头像
  409. // loginUserAvatar() {
  410. // if (this.loginUserProfiles.avatarurl) {
  411. // return this.loginUserProfiles?.avatarurl;
  412. // } else {
  413. // return this.defaultAvatar;
  414. // }
  415. // },
  416. pinConversationList() {
  417. return this.$store.getters.sortedPinConversationList;
  418. },
  419. conversationList() {
  420. return this.$store.getters.sortedConversationList;
  421. },
  422. friendUserInfoCollection() {
  423. return this.$store.getters.friendUserInfoCollection;
  424. },
  425. //好友列表
  426. friendList() {
  427. return this.$store.state.ContactsStore.friendList;
  428. },
  429. //会话头像展示
  430. showConversationAvatar() {
  431. return (conversationItem) => {
  432. const { conversationId, conversationType } = conversationItem;
  433. console.log('conversationItem',conversationItem)
  434. if (conversationType === CHAT_TYPE.SINGLE_CHAT) {
  435. // if (
  436. // this.friendUserInfoCollection[conversationId] &&
  437. // this.friendUserInfoCollection[conversationId]?.avatarurl
  438. // ) {
  439. // return this.friendUserInfoCollection[conversationId].avatarurl;
  440. // } else {
  441. // return this.defaultAvatar;
  442. // }
  443. if (
  444. this.chatUserList[conversationId] &&
  445. this.chatUserList[conversationId].avatarurl
  446. ) {
  447. return this.chatUserList[conversationId].avatarurl;
  448. } else {
  449. return this.defaultAvatar;
  450. }
  451. } else if (conversationType === CHAT_TYPE.GROUP_CHAT) {
  452. return this.defaultGroupAvatar;
  453. }
  454. };
  455. },
  456. //会话name展示
  457. showConversationName() {
  458. return (conversationItem) => {
  459. const { conversationId, conversationType } = conversationItem;
  460. if (conversationType === CHAT_TYPE.SINGLE_CHAT) {
  461. if (
  462. this.friendList.some((f) => f.userId === conversationId)?.remark
  463. ) {
  464. return this.friendList.some((f) => f.userId === conversationId)
  465. .remark;
  466. } else if (
  467. this.chatUserList[conversationId]
  468. ) {
  469. return this.chatUserList[conversationId].nickname;
  470. } else {
  471. return this.chatUserList[conversationId].nickname||conversationId;
  472. // return 'nickname';
  473. }
  474. } else if (conversationType === CHAT_TYPE.GROUP_CHAT) {
  475. return this.getGroupName(conversationId);
  476. }
  477. };
  478. },
  479. //处理时间显示
  480. handleTime() {
  481. return (item) => {
  482. // return this.$u.timeFormat(item.time, 'mm/dd/hh:MM');
  483. // const {
  484. // lastMessage: { time },
  485. // } = item;
  486. // console.log(item.lastMessage.time);
  487. return this.$u.timeFrom(item?.time || item?.lastMessage?.time);
  488. };
  489. },
  490. //处理预览消息内容
  491. handleLastMsgContent() {
  492. return (msgBody) => {
  493. const { type, msg } = msgBody;
  494. let resultContent = '';
  495. //如果消息类型,在预设非展示文本类型中,就返回预设值
  496. if (SESSION_MESSAGE_TYPE[type]) {
  497. resultContent = SESSION_MESSAGE_TYPE[type];
  498. } else if (type === MESSAGE_TYPE.CUSTOM) {
  499. //如果为自定义类型消息就匹配自定义消息对应的lastmsg文本
  500. // if (msgBody.customEvent) {
  501. // (CUSTOM_TYPE[msgBody.customEvent] &&
  502. // (resultContent = CUSTOM_TYPE[msgBody.customEvent])) ||
  503. // '';
  504. // console.log(22222222222,msgBody.customEvent(productLink),CUSTOM_TYPE[msgBody.customEvent] ());
  505. // }
  506. if (msgBody.customEvent) {
  507. (CUSTOM_TYPE[msgBody.customEvent] &&
  508. (resultContent = CUSTOM_TYPE[msgBody.customEvent])) ||
  509. '';
  510. }
  511. } else {
  512. resultContent = msg;
  513. }
  514. return resultContent;
  515. };
  516. },
  517. //系统通知
  518. lastInformData() {
  519. return this.$store.getters.getAllInformsList[
  520. this.$store.getters.getAllInformsList.length - 1
  521. ];
  522. },
  523. unReadNoticeNum() {
  524. return this.$store.getters.getAllInformsList.filter(
  525. (inform) => !inform.isHandled
  526. ).length;
  527. },
  528. //会话未读数
  529. allConversationUnReadNum() {
  530. return (
  531. this.unReadNoticeNum +
  532. this.$store.getters.calcAllUnReadNumFromConversation
  533. );
  534. },
  535. //免打扰状态
  536. conversationItemSilentStatus() {
  537. return (conversationId) => {
  538. const silentStatus =
  539. this.$store.getters.silentConversationMap[conversationId]?.type ===
  540. 'NONE';
  541. return silentStatus;
  542. };
  543. },
  544. },
  545. created() {
  546. console.log('converstaion created');
  547. this.$store.dispatch('fetchPinConversationList');
  548. if (!this.conversationList.length) {
  549. this.$store.dispatch('fetchConversationList');
  550. }
  551. uni.hideHomeButton && uni.hideHomeButton();
  552. this.setConversationListHeigth();
  553. //得到会话列表用户属性数组
  554. const uidsarr1= JSON.parse(JSON.stringify(uni.getStorageSync('uIds')));
  555. EMClient.fetchUserInfoById(uidsarr1).then((resData)=>{
  556. this.chatUserList=resData.data;
  557. })
  558. },
  559. methods: {
  560. // 最新纪录列表
  561. payUserList() {
  562. payUserList({
  563. mer_id: this.mer_id,
  564. pageNum: this.page,
  565. pageSize: this.limit,
  566. }).then(res => {
  567. uni.stopPullDownRefresh();
  568. if (res.data.status == 200) {
  569. this.tihsi = res.data.data.pageInfo.list.length
  570. if (res.data.data.pageInfo.list.length > 0) { //分页处理
  571. if (this.page == 1) {
  572. this.List = res.data.data.pageInfo.list
  573. } else {
  574. this.List = this.List.concat(res.data.data.pageInfo.list)
  575. }
  576. } else {
  577. this.is_panudn = false
  578. }
  579. uni.hideLoading();
  580. }
  581. }, fail => {
  582. uni.hideLoading()
  583. console.log(fail)
  584. })
  585. },
  586. // 今日昨日收益
  587. selectMerchantOrder() {
  588. // uni.showLoading({
  589. // title: '加载中',
  590. // });
  591. selectMerchantOrder({
  592. start_time: this.start_time,
  593. end_time: this.start_time,
  594. mer_id: this.mer_id
  595. }).then(res => {
  596. if (res.data.status == 200) {
  597. this.dataList = res.data.data
  598. uni.hideLoading();
  599. }
  600. }, fail => {
  601. console.log(fail)
  602. uni.hideLoading();
  603. })
  604. },
  605. // 店铺信息头
  606. selectMerchant() {
  607. selectMerchant({
  608. mer_id: this.mer_id
  609. }).then(res => {
  610. console.log(res)
  611. if (res.data.status == 200) {
  612. this.merchantCashierShow = res.data.data.merchantCashierShow
  613. }
  614. }, fail => {
  615. console.log(fail)
  616. })
  617. },
  618. //登录环信
  619. async loginWithUserId() {
  620. this.loginEaseIMId =uni.getStorageSync('im_userid')
  621. try {
  622. const res = await loginWithPassword(
  623. this.loginEaseIMId,
  624. uni.getStorageSync('im_pass')
  625. );
  626. this.$store.commit('SET_LOGIN_USER_BASE_INFOS', {
  627. loginUserId: this.loginEaseIMId,
  628. });
  629. this.setEMUserLoginInfosToStorage(
  630. this.loginEaseIMId.toLowerCase(),
  631. res.accessToken
  632. );
  633. } catch (error) {
  634. console.log('>>>>>>环信登录失败', error);
  635. uni.showToast({
  636. title: '登录失败',
  637. icon: 'none',
  638. });
  639. } finally {
  640. this.loginEaseIMId = '';
  641. }
  642. },
  643. setEMUserLoginInfosToStorage(userId, token) {
  644. const params = {
  645. key: `EM_LOGIN_INFOS`,
  646. data: { userId: userId, token: token },
  647. };
  648. uni.setStorage({ ...params });
  649. },
  650. gotoPage(url){
  651. console.log(1111);
  652. uni.navigateTo({
  653. url: url,
  654. });
  655. },
  656. handleDelete(conversationItem){
  657. uni.showModal({
  658. title: '确认删除?',
  659. confirmText: '删除',
  660. success: async (res) => {
  661. if (res.confirm) {
  662. this.$store.dispatch('deleteConversation', {
  663. ...conversationItem,
  664. });
  665. }
  666. },
  667. fail: function (err) {
  668. uni.showToast({
  669. title: '删除失败',
  670. icon: 'none',
  671. duration: 2000,
  672. });
  673. console.log('删除失败', err);
  674. },
  675. });
  676. },
  677. setConversationListHeigth() {
  678. uni.getSystemInfo({
  679. success: (res) => {
  680. //顶部安全区高度
  681. const statusBarHeight = res.statusBarHeight;
  682. //底部安全区高度
  683. const safeAreaBottom = res.safeAreaInsets.bottom;
  684. console.log('safeAreaBottom', safeAreaBottom);
  685. this.conversationListHeight =
  686. res.windowHeight -
  687. (tabBarHeight +
  688. navBarHeight +
  689. searchInputHeight +
  690. statusBarHeight +
  691. safeAreaBottom);
  692. },
  693. });
  694. },
  695. scrolltolower() {
  696. console.log('>>>>>>list触底');
  697. },
  698. //群组名称
  699. getGroupName(groupid) {
  700. const joinedGroupList = this.$store.state.GroupStore.joinedGroupList;
  701. let groupName = '';
  702. if (joinedGroupList.length) {
  703. joinedGroupList.forEach((item) => {
  704. if (item.groupId == groupid) {
  705. return (groupName = item.groupName);
  706. }
  707. });
  708. return groupName;
  709. } else {
  710. return groupid;
  711. }
  712. },
  713. //开启搜索模式
  714. openSearch() {
  715. this.isShowDefaultSearch = false;
  716. },
  717. //取消搜索模式
  718. cancelSearch() {
  719. this.searchInputKeywords = '';
  720. this.searchResConversationList = [];
  721. this.isShowDefaultSearch = true;
  722. },
  723. //执行搜索并返回搜索结果
  724. actionSearch(val) {
  725. const sourceConversationList = [
  726. ...this.conversationList,
  727. ...this.pinConversationList,
  728. ];
  729. let keyWord = this.searchInputKeywords;
  730. let resConversationList = [];
  731. if (keyWord) {
  732. resConversationList = sourceConversationList.filter(
  733. (conversatonItem) => {
  734. const { conversationId, conversationType, lastMessage } =
  735. conversatonItem;
  736. if (conversationType === CHAT_TYPE.SINGLE_CHAT) {
  737. if (
  738. this.friendUserInfoCollection[conversationId] &&
  739. this.friendUserInfoCollection[conversationId]?.nickname
  740. ) {
  741. return (
  742. lastMessage?.msg?.indexOf(keyWord) > -1 ||
  743. conversationId?.indexOf(keyWord) > -1 ||
  744. this.friendUserInfoCollection[
  745. conversationId
  746. ].nickname?.indexOf(keyWord) > -1
  747. );
  748. } else {
  749. return (
  750. lastMessage?.msg?.indexOf(keyWord) > -1 ||
  751. conversationId.indexOf(keyWord) > -1
  752. );
  753. }
  754. }
  755. if (conversationType === CHAT_TYPE.GROUP_CHAT) {
  756. console.log('>>>>group chat lastMessage', lastMessage);
  757. return (
  758. conversationId.indexOf(keyWord) > -1 ||
  759. this.getGroupName(conversationId).indexOf(keyWord) > -1 ||
  760. lastMessage?.msg?.indexOf(keyWord) > -1
  761. );
  762. }
  763. }
  764. );
  765. }
  766. console.log('>>>>>执行搜索', resConversationList);
  767. this.searchResConversationList = [...resConversationList];
  768. },
  769. //长按会话事件
  770. onConversationMoreFunction(conversationItem) {
  771. if (conversationItem) {
  772. const silentStatus =
  773. this.$store.getters.silentConversationMap[
  774. conversationItem?.conversationId
  775. ]?.type === 'NONE';
  776. this.longPressCheckedConversationItem = { ...conversationItem };
  777. this.isShowMoreFunction = true;
  778. //长按时选项文本调整
  779. this.moreFunctionList.map((item) => {
  780. switch (item.type) {
  781. case 1:
  782. {
  783. if (conversationItem.isPinned) {
  784. item.name = '取消置顶';
  785. } else {
  786. item.name = '置顶';
  787. }
  788. }
  789. break;
  790. case 2:
  791. {
  792. if (silentStatus) {
  793. item.name = '取消免打扰';
  794. } else {
  795. item.name = '免打扰';
  796. }
  797. }
  798. break;
  799. case 3: {
  800. if (
  801. conversationItem?.unReadCount > 0 ||
  802. !conversationItem.isRead
  803. ) {
  804. item.name = '标记已读';
  805. } else {
  806. item.name = '标记未读';
  807. }
  808. }
  809. default:
  810. break;
  811. }
  812. });
  813. this.isShowMoreFunction = true;
  814. return;
  815. }
  816. this.isShowMoreFunction = false;
  817. },
  818. onSelectClick(item) {
  819. switch (item.type) {
  820. case 0:
  821. this.deleteConversationItem();
  822. break;
  823. case 1:
  824. this.handlePinConversationItem();
  825. break;
  826. case 2:
  827. this.handleConversationSilent();
  828. break;
  829. case 3:
  830. this.handleConversationUnRead();
  831. break;
  832. default:
  833. break;
  834. }
  835. },
  836. //置顶操作
  837. handlePinConversationItem() {
  838. const conversationItem = { ...this.longPressCheckedConversationItem };
  839. conversationItem.isPinned = !conversationItem.isPinned;
  840. this.$store.dispatch('pinConversationItem', conversationItem);
  841. },
  842. //删除会话
  843. deleteConversationItem: function () {
  844. uni.showModal({
  845. title: '确认删除?',
  846. confirmText: '删除',
  847. success: async (res) => {
  848. if (res.confirm) {
  849. this.$store.dispatch('deleteConversation', {
  850. ...this.longPressCheckedConversationItem,
  851. });
  852. }
  853. },
  854. fail: function (err) {
  855. uni.showToast({
  856. title: '删除失败',
  857. icon: 'none',
  858. duration: 2000,
  859. });
  860. console.log('删除失败', err);
  861. },
  862. });
  863. },
  864. //会话免打扰操作
  865. handleConversationSilent() {
  866. const { conversationId, conversationType } =
  867. this.longPressCheckedConversationItem;
  868. const silentStatus =
  869. this.$store.getters.silentConversationMap[conversationId]?.type ===
  870. 'NONE';
  871. const params = {
  872. conversationId,
  873. type: conversationType,
  874. };
  875. if (silentStatus) {
  876. this.$store.dispatch('setConversationSilentMode', {
  877. ...params,
  878. });
  879. } else {
  880. (params.options = {
  881. paramType: 0,
  882. remindType: 'NONE',
  883. }),
  884. this.$store.dispatch('setConversationSilentMode', {
  885. ...params,
  886. });
  887. }
  888. },
  889. /**
  890. * 会话已读未读状态变更
  891. * isRead: true表示已读,false表示未读
  892. * 实现原理为本地往会话数据中插入isRead字段从而标记实现手动标记会话已读状态
  893. * !需注意此功能为本地实现,并不记录远端会话列表接口,刷新状态重置。
  894. */
  895. handleConversationUnRead() {
  896. const { unReadCount } = this.longPressCheckedConversationItem;
  897. if (unReadCount > 0 || !this.longPressCheckedConversationItem?.isRead) {
  898. this.$store.dispatch('setConversationReadStatus', {
  899. conversationItem: this.longPressCheckedConversationItem,
  900. isRead: true,
  901. });
  902. } else {
  903. this.$store.dispatch('setConversationReadStatus', {
  904. conversationItem: this.longPressCheckedConversationItem,
  905. isRead: false,
  906. });
  907. }
  908. },
  909. //进入系统通知页面
  910. // entryInform() {
  911. // uni.navigateTo({
  912. // url: '../notification/notification',
  913. // });
  914. // },
  915. //进入聊天页面
  916. entryChatPage: async function (conversationItem) {
  917. console.log('进入聊天页面',conversationItem);
  918. const { conversationId, conversationType } = conversationItem;
  919. const uidsarr= JSON.parse(JSON.stringify(uni.getStorageSync('uIds')));
  920. EMClient.fetchUserInfoById(uidsarr).then((resData)=>{
  921. this.chatUserList=resData.data;
  922. for(var key in resData.data){
  923. if(key==conversationId){
  924. uni.setStorage({
  925. key: 'nowConversationIntem',
  926. data: resData.data[conversationId],
  927. });
  928. }
  929. }
  930. })
  931. if (conversationItem.unReadCount > 0) {
  932. this.$store.dispatch('sendConversatonReadedAck', {
  933. targetId: conversationId,
  934. chatType: conversationType,
  935. });
  936. }
  937. uni.navigateTo({
  938. url: `../../emChat/emChatContainer/index?targetId=${conversationId}&chatType=${conversationType}`,
  939. });
  940. },
  941. },
  942. };
  943. </script>
  944. <style>
  945. .but{
  946. width:80%;
  947. height:40px;
  948. line-height: 40px;
  949. text-align: center;
  950. border-radius: 20px;
  951. background-color:#007aff ;
  952. color:#fff;
  953. /* margin:0 auto;
  954. margin-top: 100px; */
  955. position:fixed;
  956. bottom:100px;
  957. left:50%;
  958. margin-left:-40%;
  959. }
  960. .conversation_container {
  961. /* height: 100vh; */
  962. background-color: #fff;
  963. width: 100%;
  964. }
  965. .search_container {
  966. height: 40px;
  967. width: 100%;
  968. box-sizing: border-box;
  969. padding: 4px;
  970. background: #fff;
  971. margin-bottom: 5px;
  972. }
  973. .searching_container {
  974. height: 40px;
  975. width: 100%;
  976. box-sizing: border-box;
  977. padding: 4px;
  978. background: #fff;
  979. margin-bottom: 5px;
  980. }
  981. .search_icon_box {
  982. width: 100%;
  983. height: 36px;
  984. background: #f1f2f3;
  985. display: flex;
  986. flex-direction: row;
  987. align-items: center;
  988. justify-content: center;
  989. border-radius: 4px;
  990. }
  991. .search_text {
  992. /* Input */
  993. width: 32px;
  994. height: 22px;
  995. /* 简体中文/文本/大 */
  996. font-family: 'PingFang SC';
  997. font-style: normal;
  998. font-weight: 400;
  999. font-size: 16px;
  1000. line-height: 22px;
  1001. /* identical to box height, or 138% */
  1002. /* Neutral/6 */
  1003. color: #919ba1;
  1004. /* Inside auto layout */
  1005. flex: none;
  1006. order: 1;
  1007. flex-grow: 0;
  1008. }
  1009. .pinconversation_item {
  1010. background: #eaeaea;
  1011. }
  1012. .conversation_item_title {
  1013. display: flex;
  1014. flex-direction: row;
  1015. justify-content: flex-start;
  1016. }
  1017. .conversation_item_right {
  1018. position: relative;
  1019. }
  1020. .conversation_item_time {
  1021. font-size: 12px;
  1022. font-weight: 600;
  1023. }
  1024. .conversation_navbar_center {
  1025. width: 52px;
  1026. height: 22px;
  1027. }
  1028. </style>