message-model.tsx 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. import { defineComponent } from "vue";
  2. import { ElTag } from "element-plus";
  3. // import VirtualList from 'vue-virtual-list-v3';
  4. // import VirtualList from 'vue3-virtual-list'
  5. // import { RecycleScroller } from 'vue-virtual-scroller'
  6. import styles from './index.module.less'
  7. import request from '/src/helpers/request';
  8. import event, { LIVE_EVENT_MESSAGE } from '/src/components/live-broadcast/event';
  9. import { state } from '/src/state'
  10. import dayjs from 'dayjs';
  11. import Empty from "/src/components/empty";
  12. import runtime, * as RuntimeUtils from '/src/components/live-message/model/runtime'
  13. import runtimeCast, * as RuntimeUtilCast from "/src/components/live-broadcast/runtime";
  14. import { removeToken } from "/src/utils/auth";
  15. export default defineComponent({
  16. data() {
  17. return {
  18. messageList: [] as any[], // 回复学生列表
  19. loadingMessage: false, // 观看列表状态
  20. }
  21. },
  22. mounted() {
  23. this.loadingMessage = true
  24. event.on(LIVE_EVENT_MESSAGE["RC:TxtMsg"], this.onMessage);
  25. // event.on(LIVE_EVENT_MESSAGE["RC:Chatroom:Like"], this.onLike)
  26. event.on(LIVE_EVENT_MESSAGE["RC:ForcedOffline"], this.onForcedOffline)
  27. event.on('MESSAGE:Change', this.scrollToBottom) // 添加消息
  28. setTimeout(() => {
  29. this.loadingMessage = false;
  30. }, 2000);
  31. this.scrollToBottom()
  32. },
  33. beforeUnmount() {
  34. event.off(LIVE_EVENT_MESSAGE["RC:TxtMsg"], this.onMessage);
  35. // event.off(LIVE_EVENT_MESSAGE["RC:Chatroom:Like"], this.onLike);
  36. },
  37. methods: {
  38. async onForcedOffline() {
  39. // 强制退出登录
  40. try {
  41. await RuntimeUtilCast.leaveIMRoom()
  42. await request.post('/api-auth/exit', { data: {} });
  43. RuntimeUtilCast.closeDevice('camera')
  44. RuntimeUtilCast.closeDevice('microphone')
  45. state.user = null
  46. removeToken();
  47. (this as any).$router.push({
  48. path: '/login',
  49. query: {
  50. ...this.$route.query
  51. }
  52. });
  53. } catch (e) {
  54. // TODO: handle error
  55. }
  56. },
  57. onLike(value: any) {
  58. if (value && value.user) {
  59. const sendTime = dayjs(value.$EventMessage.sentTime || new Date()).format('HH:mm:ss')
  60. console.log(value, 'like')
  61. let tempObj = {
  62. name: value.user?.name,
  63. id: value.user.id,
  64. isSelf: false,
  65. content: '给您点了' + value.counts + '个赞',
  66. sendTime
  67. }
  68. RuntimeUtils.addMessage(tempObj);
  69. this.loadingMessage = false
  70. }
  71. this.scrollToBottom()
  72. },
  73. onMessage(value: any) {
  74. if (value && value.user) {
  75. const sendTime = dayjs(value.$EventMessage.sentTime || new Date()).format('HH:mm:ss')
  76. let tempObj = {
  77. name: value.user?.name,
  78. id: value.user.id,
  79. isSelf: false,
  80. content: value.content,
  81. sendTime
  82. }
  83. // 判断是否是主播
  84. if (value.user.id === state.user.speakerId) {
  85. tempObj.isSelf = true
  86. }
  87. // this.messageList.push(tempObj);
  88. RuntimeUtils.addMessage(tempObj);
  89. this.loadingMessage = false
  90. }
  91. this.scrollToBottom()
  92. },
  93. scrollToBottom() {
  94. // 默认滚动到底部
  95. this.$nextTick(() => {
  96. document.querySelector('#tabList')?.scrollTo(0, document.querySelector('#messageList')?.scrollHeight || 0)
  97. })
  98. }
  99. },
  100. render() {
  101. return (
  102. <div style={{ minHeight: '100%', position: 'relative' }} id="messageList">
  103. {runtime.messageList.length > 0 ? runtime.messageList.map((item: any) => (
  104. <div class={styles.itemContent}>
  105. <div class={styles.itemInfo}>
  106. <div class={styles.itemName}>
  107. <div class={styles.userName}>
  108. {item.isSelf ? <ElTag effect="dark" color="#01A79E">主讲人</ElTag> : null}
  109. <span class={styles['name-style']}>{item.name}{ item.system ? null : ':' }</span>
  110. <span class={[styles.itemText, item.isSelf ? styles.active : null]}>
  111. {item.content}
  112. </span>
  113. </div>
  114. <p class={styles.rightTime}>{item.sendTime}</p>
  115. </div>
  116. </div>
  117. </div>
  118. )) : (this.loadingMessage ? <div class={styles.loadingStyle}>
  119. <div class="el-loading-mask" style="background-color: rgba(0, 0, 0, 0.8);"><div class="el-loading-spinner"><svg class="circular" viewBox="25 25 50 50"><circle class="path" cx="50" cy="50" r="20" fill="none"></circle></svg></div></div>
  120. </div> : <Empty style={{ paddingTop: '120px' }} text="暂无学员互动!" icon="noData-no-message" />)}
  121. </div>
  122. )
  123. }
  124. })
  125. function source(source: any) {
  126. throw new Error("Function not implemented.");
  127. }