ConversationItem.vue 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329
  1. <template>
  2. <u-swipe-action-item
  3. :index="source.conversationID"
  4. @click="clickConversationMenu($event, source)"
  5. :name="source.conversationID"
  6. :options="getSwipeActions || []"
  7. :disabled="disabled" v-if="source.userID">
  8. <view @tap.prevent="clickConversationItem" class="conversation_item">
  9. <view class="pinned" v-if="source.isPinned"></view>
  10. <view class="left_info">
  11. <my-avatar :isGroup="isGroup" :isNotify="true" :src="source.conversationType==4?'/static/logo.png':source.faceURL" :desc="source.showName" size="44">
  12. <image v-if="getRole()==1" class="taoj" src="/static/svg/doctor.svg"></image>
  13. <image v-if="getRole()==2" class="taoj" src="/static/svg/guanjia.svg"></image>
  14. <image v-if="isGroup" class="taoj" src="/static/svg/group.svg"></image>
  15. <u-badge v-if="!notAccept" style="position: absolute;top:-9rpx;right: -9rpx;" max="99" :value="source.unreadCount"></u-badge>
  16. </my-avatar>
  17. <view class="details">
  18. <text class="conversation_name">{{ source.conversationType==4?"系统通知":source.showName }}</text>
  19. <view class="lastest_msg_wrap">
  20. <text v-if="messagePrefix" class="lastest_msg_prefix" :class="{ lastest_msg_prefix_active: needActivePerfix }">{{ messagePrefix }}</text>
  21. <text class="lastest_msg_content">{{ latestMessage }}</text>
  22. </view>
  23. </view>
  24. </view>
  25. <view class="right_desc">
  26. <text class="send_time">{{ latestMessageTime }}</text>
  27. <image style="width: 16px; height: 16px" v-if="notAccept" src="../../../../static/images/conversation_not_accept.png" />
  28. <!-- <u-badge v-else max="99" :value="source.unreadCount"></u-badge> -->
  29. </view>
  30. </view>
  31. </u-swipe-action-item>
  32. </template>
  33. <script>
  34. import IMSDK, { GroupAtType, MessageReceiveOptType, SessionType } from 'openim-uniapp-polyfill';
  35. import MyAvatar from '../../../../components/MyAvatar/index.vue';
  36. import UParse from '../../../../components/gaoyia-parse/parse.vue';
  37. import { getConversationContent, formatConversionTime, prepareConversationState, parseAt } from '../../../../util/imCommon';
  38. import { formatInputHtml,isDoctorAction} from '../../../../util/common';
  39. export default {
  40. components: {
  41. MyAvatar,
  42. UParse
  43. },
  44. props: {
  45. source: {
  46. type: Object,
  47. default: () => {}
  48. },
  49. disabled: {
  50. type: Boolean,
  51. default: false
  52. }
  53. },
  54. computed: {
  55. messagePrefix() {
  56. let prefix = '';
  57. if (this.source?.recvMsgOpt !== MessageReceiveOptType.Normal && this.source.unreadCount > 0) {
  58. prefix = `[${this.source.unreadCount}条] `;
  59. }
  60. if (this.source.groupAtType !== GroupAtType.AtNormal) {
  61. switch (this.source.groupAtType) {
  62. case GroupAtType.AtAll:
  63. prefix = '[所有人]';
  64. break;
  65. case GroupAtType.AtMe:
  66. prefix = '[有人@你]';
  67. break;
  68. case GroupAtType.AtAllAtMe:
  69. prefix = '[有人@你]';
  70. break;
  71. case GroupAtType.AtGroupNotice:
  72. prefix = '[群公告]';
  73. break;
  74. }
  75. return prefix;
  76. }
  77. if (this.source.draftText !== '') {
  78. return '[草稿]';
  79. }
  80. return prefix;
  81. },
  82. latestMessage() {
  83. if (this.source.latestMsg === '') return '';
  84. if (this.source.draftText && this.source.groupAtType === GroupAtType.AtNormal) {
  85. return parseAt(formatInputHtml(this.source.draftText), true);
  86. }
  87. let parsedMessage;
  88. try {
  89. parsedMessage = JSON.parse(this.source.latestMsg);
  90. } catch (e) {}
  91. if (!parsedMessage) return '';
  92. return getConversationContent(parsedMessage);
  93. },
  94. needActivePerfix() {
  95. return this.source.groupAtType !== GroupAtType.AtNormal || this.source.draftText;
  96. },
  97. latestMessageTime() {
  98. return this.source.latestMsgSendTime ? formatConversionTime(this.source.latestMsgSendTime) : '';
  99. },
  100. notAccept() {
  101. return this.source.recvMsgOpt !== MessageReceiveOptType.Normal;
  102. },
  103. isGroup() {
  104. return this.source.conversationType === SessionType.WorkingGroup;
  105. },
  106. isNotify() {
  107. return this.source.conversationType === SessionType.Notification;
  108. },
  109. getSwipeActions() {
  110. let actions = [
  111. {
  112. text: `${this.source.isPinned ? '取消' : ''}置顶`,
  113. style: {
  114. backgroundColor: '#5856D6'
  115. }
  116. },
  117. {
  118. text: '移除',
  119. style: {
  120. backgroundColor: '#FF381F'
  121. }
  122. }
  123. ];
  124. if (this.source.unreadCount > 0) {
  125. actions = [
  126. {
  127. text: '标为已读',
  128. style: {
  129. backgroundColor: '#1485EE'
  130. }
  131. },
  132. ...actions
  133. ];
  134. }
  135. return actions;
  136. }
  137. },
  138. data() {
  139. return {
  140. defaultFaceUrl:"../../../../static/images/my_heads_icon.png"
  141. };
  142. },
  143. mounted() {
  144. },
  145. methods: {
  146. clickConversationItem() {
  147. console.log("qxj clickConversationItem:",this.source);
  148. let userId=this.source.userID;
  149. let isDoctor=isDoctorAction(userId);
  150. if(this.$companyUserIsLogin() || !isDoctor){
  151. this.$store.commit("timStore/setImType",1);
  152. }
  153. else{
  154. let ex=this.source.ex;
  155. if(this.source.latestMsg!=null && this.source.latestMsg!=''){
  156. let latestMsg=JSON.parse(this.source.latestMsg);
  157. if(!!latestMsg.ex && latestMsg.ex!=''){
  158. ex=latestMsg.ex;
  159. }
  160. }
  161. if(ex!=null || ex!=''){
  162. try{
  163. var json=JSON.parse(ex);
  164. this.$store.commit("timStore/setImType", json.imType);
  165. this.$store.commit("timStore/setOrderType", json.orderType);
  166. this.$store.commit("timStore/setOrderId", json.orderId);
  167. this.$store.commit("timStore/setFollowId", json.followId);
  168. this.$store.commit("timStore/setType", json.type);
  169. }
  170. catch(e){
  171. }
  172. }
  173. }
  174. this.$store.commit("timStore/setConversationID", this.source.conversationID);
  175. this.source.sourceTypeList=true
  176. prepareConversationState(this.source);
  177. },
  178. clickConversationMenu({ name, index }, item) {
  179. console.log('clickConversationMenu');
  180. const noUnRead = this.getSwipeActions.length === 2;
  181. if (index === 0 && !noUnRead) {
  182. IMSDK.asyncApi(IMSDK.IMMethods.MarkConversationMessageAsRead, IMSDK.uuid(), item.conversationID).catch(() => uni.$u.toast('操作失败'));
  183. }
  184. if ((index === 0 && noUnRead) || (index === 1 && !noUnRead)) {
  185. IMSDK.asyncApi(IMSDK.IMMethods.PinConversation, IMSDK.uuid(), {
  186. conversationID: item.conversationID,
  187. isPinned: !item.isPinned
  188. }).catch(() => uni.$u.toast('置顶失败'));
  189. }
  190. if ((index === 1 && noUnRead) || index === 2) {
  191. IMSDK.asyncApi(IMSDK.IMMethods.DeleteConversationAndDeleteAllMsg, IMSDK.uuid(), item.conversationID)
  192. .then(() => this.$store.dispatch('conversation/delConversationByCID', item.conversationID))
  193. .catch(() => uni.$u.toast('移除失败'));
  194. }
  195. this.$emit('closeAllSwipe');
  196. },
  197. getRole(){
  198. let userType=0;
  199. let userId=this.source.userID;
  200. if(userId!=undefined && (userId!="" || userId.length>0)){
  201. if(userId.indexOf('U')!==-1){
  202. userType=0;
  203. }
  204. if(userId.indexOf('D')!==-1){
  205. userType=1;
  206. }
  207. if(userId.indexOf('C')!==-1){
  208. userType=2;
  209. }
  210. }
  211. return userType;
  212. }
  213. }
  214. };
  215. </script>
  216. <style lang="scss" scoped>
  217. .conversation_item {
  218. @include btwBox();
  219. flex-direction: row;
  220. margin:0rpx 16rpx 0;
  221. padding: 16rpx 16rpx 16rpx;
  222. position: relative;
  223. border-radius: 16rpx;
  224. background: #fff;
  225. &::after {
  226. content: "";
  227. position: absolute;
  228. bottom: 0;
  229. left: 120rpx;
  230. border-bottom: 1px solid #ECECEC;
  231. width: 100%;
  232. transform: scaleY(0.5);
  233. border-top-color: #ECECEC;
  234. border-right-color: #ECECEC;
  235. border-left-color: #ECECEC;
  236. }
  237. &_active {
  238. background-color: #f3f3f3;
  239. }
  240. .left_info {
  241. position: relative;
  242. @include btwBox();
  243. .details {
  244. @include colBox(false);
  245. margin-left: 24rpx;
  246. height: 53px;
  247. color: $uni-text-color;
  248. justify-content: space-around;
  249. .conversation_name {
  250. @include nomalEllipsis();
  251. max-width: 50vw;
  252. font-size: 18px;
  253. font-weight: 400;
  254. color: #222;
  255. }
  256. .lastest_msg_wrap {
  257. display: flex;
  258. font-size: 15px;
  259. margin-top: 0px;
  260. margin-bottom: 10rpx;
  261. color: #666;
  262. .lastest_msg_prefix {
  263. margin-right: 3px;
  264. &_active {
  265. color: $u-primary;
  266. }
  267. }
  268. .lastest_msg_content {
  269. flex: 1;
  270. max-width: 78vw;
  271. color: #999;
  272. font-size: 16px;
  273. // margin-right: 160rpx;
  274. // /deep/uni-view {
  275. @include ellipsisWithLine(1);
  276. // }
  277. }
  278. }
  279. }
  280. }
  281. .right_desc {
  282. @include colBox(true);
  283. align-items: flex-end;
  284. width: max-content;
  285. justify-content: space-between;
  286. height: 46px;
  287. .send_time {
  288. width: max-content;
  289. font-size: 14px;
  290. color: #ccc;
  291. }
  292. .u-badge {
  293. width: fit-content;
  294. }
  295. }
  296. .pinned {
  297. position: absolute;
  298. top: 0;
  299. right: 24rpx;
  300. width: 17rpx;
  301. height: 17rpx;
  302. background-image: linear-gradient(to bottom left, #314ffe 50%, white 50%);
  303. }
  304. .taoj{
  305. position: absolute;
  306. left: 0px;
  307. top: 0px;
  308. right: 0px;
  309. bottom: 0px;
  310. width:100%;
  311. height: 100%;
  312. }
  313. }
  314. </style>