join-model.tsx 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. import { defineComponent } from "vue";
  2. import styles from './index.module.less'
  3. import { ElButton } from 'element-plus'
  4. import event, { LIVE_EVENT_MESSAGE } from '/src/components/live-broadcast/event';
  5. import { state } from '/src/state'
  6. import dayjs from 'dayjs';
  7. import Empty from "/src/components/empty";
  8. import runtime, * as RuntimeUtils from '/src/components/live-broadcast/runtime'
  9. import runtimeModel, * as RuntimeModelUtils from '/src/components/live-message/model/runtime'
  10. export default defineComponent({
  11. data() {
  12. return {
  13. joinList: {} as { [key: string]: any }, // 连麦学生列表
  14. loadingJoin: false, // 连麦列表状态
  15. upStatus: false,
  16. downStatus: false,
  17. }
  18. },
  19. computed: {
  20. count() {
  21. let count = 0
  22. for (const key in runtimeModel.joinList) {
  23. if (Object.prototype.hasOwnProperty.call(runtimeModel.joinList, key)) {
  24. const item = runtimeModel.joinList[key];
  25. if (item.userRoomType === 4) {
  26. count += 1
  27. }
  28. if (count > 3) {
  29. break
  30. }
  31. }
  32. }
  33. return count
  34. },
  35. },
  36. mounted() {
  37. // userRoomType
  38. // 1 普通
  39. // 2 老师邀请
  40. // 3 学生申请
  41. // 4 连麦中
  42. event.on(LIVE_EVENT_MESSAGE['RC:Chatroom:SeatApply'], this.onSeatApply);
  43. event.on(LIVE_EVENT_MESSAGE['RC:Chatroom:SeatResponse'], this.onSeatApply);
  44. event.on(LIVE_EVENT_MESSAGE['RM:RTC:UserLeave'], this.onSeatApply);
  45. event.on(LIVE_EVENT_MESSAGE['RM:RTC:SwitchRole'], this.onSwitchRole);
  46. event.on(LIVE_EVENT_MESSAGE['RC:Chatroom:Leave'], this.onLeave); // 移动端接收的消息
  47. event.on(LIVE_EVENT_MESSAGE['RC:LookerLoginOut'], this.onLeave); // 后台接收的消息
  48. },
  49. methods: {
  50. async onLeave(value: any) {
  51. // 学生离开时处理
  52. runtime.lookCount = runtime.lookCount - 1 >= 0 ? runtime.lookCount - 1 : 0
  53. const userId = value.userId || value.fromUserId
  54. if(runtimeModel.joinList[userId]) {
  55. RuntimeModelUtils.removeJoin(userId)
  56. }
  57. if(runtimeModel.lookList[userId]) {
  58. RuntimeModelUtils.removeLook(userId)
  59. }
  60. // 同步移动端观看人数
  61. await RuntimeUtils.sendMessage({ count: runtime.lookCount }, 'MemberCount')
  62. },
  63. onSeatApply(evt: any) {
  64. // console.log(evt, 'onSeatApply joinModel')
  65. if (Array.isArray(evt)) {
  66. for (const id of evt) {
  67. console.log('onSeatApply', id)
  68. RuntimeModelUtils.removeJoin(id)
  69. }
  70. return
  71. }
  72. const response = evt.$EventMessage.messageType === 'RC:Chatroom:SeatResponse'
  73. const userRoomType = response ? 4 : 3
  74. // if(evt.$EventMessage.messageType === 'RC:Chatroom:SeatResponse')
  75. const sendTime = dayjs(evt.$EventMessage.sentTime || new Date()).format('HH:mm:ss')
  76. let tempObj = {
  77. name: evt.audienceName,
  78. id: String(evt.audienceId),
  79. system: 1,
  80. isSelf: false,
  81. content: '',
  82. sendTime
  83. }
  84. // 申请连麦
  85. if (evt.type === 3) {
  86. console.log(evt, '申请连麦')
  87. const params = {
  88. name: evt.audienceName,
  89. id: evt.audienceId,
  90. userRoomType: userRoomType,
  91. type: evt.type,
  92. }
  93. RuntimeModelUtils.addJoin(evt.audienceId, params)
  94. RuntimeModelUtils.addLook(evt.audienceId, params)
  95. tempObj.content = response ? '同意了连麦申请' : '发起了连麦申请'
  96. RuntimeModelUtils.addMessage(tempObj);
  97. event.emit('MESSAGE:Change')
  98. }
  99. // 取消连麦
  100. if (evt.type === 4) {
  101. console.log(evt, '取消连麦')
  102. if (runtimeModel.joinList[evt.audienceId]) {
  103. RuntimeModelUtils.removeJoin(evt.audienceId)
  104. }
  105. if (runtimeModel.lookList[evt.audienceId]) {
  106. let userLook = runtimeModel.lookList[evt.audienceId]
  107. userLook.userRoomType = 1
  108. RuntimeModelUtils.addLook(evt.audienceId, userLook)
  109. }
  110. //
  111. tempObj.content = response ? '拒绝了连麦申请' : '取消了连麦申请'
  112. RuntimeModelUtils.addMessage(tempObj);
  113. event.emit('MESSAGE:Change')
  114. }
  115. },
  116. agree(item: any) {
  117. if (this.count > 3 || this.upStatus) {
  118. console.log(true, 2323)
  119. return
  120. }
  121. this.upStatus = true
  122. const data = {
  123. ...item,
  124. audienceName: item.name,
  125. audienceId: String(item.id),
  126. teacherId: String(state.user?.id),
  127. teacherName: state.user?.speakerName,
  128. userRoomType: 4,
  129. type: 1,
  130. }
  131. RuntimeModelUtils.addJoin(item.id, data)
  132. RuntimeModelUtils.addLook(item.id, data)
  133. RuntimeUtils.sendMessage(data, 'SeatResponse')
  134. setTimeout(() => {
  135. this.upStatus = false
  136. }, 300);
  137. },
  138. refuse(item: any) {
  139. if(this.downStatus) {
  140. return
  141. }
  142. this.downStatus = true
  143. const data = {
  144. ...item,
  145. audienceName: item.name,
  146. audienceId: String(item.id),
  147. teacherId: String(state.user?.id),
  148. teacherName: state.user?.speakerName,
  149. userRoomType: 4,
  150. type: 5,
  151. }
  152. RuntimeModelUtils.addJoin(item.id, data)
  153. RuntimeUtils.sendMessage(data, 'SeatApply')
  154. setTimeout(() => {
  155. this.downStatus = false
  156. }, 300);
  157. },
  158. onSwitchRole(evt: any) {
  159. console.log(evt, 'onSwitchRole')
  160. if (runtimeModel.joinList[evt.userId] && evt.role === 2) {
  161. const user = runtimeModel.joinList[evt.userId]
  162. const sendTime = dayjs(new Date()).format('HH:mm:ss')
  163. let tempObj = {
  164. name: user.audienceName,
  165. id: user.audienceId,
  166. system: 1,
  167. isSelf: false,
  168. content: '发起了连麦申请',
  169. sendTime
  170. }
  171. RuntimeModelUtils.addMessage(tempObj);
  172. event.emit('MESSAGE:Change')
  173. RuntimeModelUtils.removeJoin(evt.userId)
  174. }
  175. if (runtimeModel.lookList[evt.userId] && evt.role === 2) {
  176. let userLook = runtimeModel.lookList[evt.userId]
  177. userLook.userRoomType = 1
  178. RuntimeModelUtils.addLook(evt.userId, userLook)
  179. }
  180. }
  181. },
  182. render() {
  183. const list = Object.values(runtimeModel.joinList)
  184. return (
  185. <div style={{ minHeight: '100%', position: 'relative' }}>
  186. {list.length > 0 ? list.map((item: any) => (
  187. <div class={styles.itemContent}>
  188. <div class={styles.itemInfo}>
  189. <div class={styles.itemName}>
  190. <p class={styles.userName}>
  191. <span class={styles['name-style']}>{item.name}</span>
  192. {item.userRoomType !== 4 ? <span style={{ paddingLeft: '10px' }}>申请连麦</span> : <span style={{ paddingLeft: '10px', color: 'var(--live-text-color)' }}>正在连麦</span>}
  193. </p>
  194. {item.userRoomType !== 4 ? (
  195. <div class={styles.joinText}>
  196. <div class={styles.join}>
  197. {/* 申请连麦 */}
  198. </div>
  199. <ElButton size="small" type="primary" disabled={this.count > 3} class={styles.btn} onClick={() => this.agree(item)}>上麦</ElButton>
  200. </div>
  201. ) : (
  202. <div class={styles.joinText}>
  203. <div class={styles.join}>
  204. {/* 正在连麦 */}
  205. </div>
  206. <ElButton size="small" plain class={[styles.btn, styles.downBtn]} onClick={() => this.refuse(item)}>下麦</ElButton>
  207. </div>
  208. )}
  209. </div>
  210. </div>
  211. </div>
  212. )) : this.loadingJoin ? <div class={styles.loadingStyle}><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></div> : <Empty style={{ paddingTop: '120px' }} text="暂无学员发起连麦!" icon="noData-no-join" />}
  213. </div>
  214. )
  215. }
  216. })