join-model.tsx 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  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. const userId = value.userId || value.fromUserId
  53. if(runtimeModel.joinList[userId]) {
  54. RuntimeModelUtils.removeJoin(userId)
  55. }
  56. if(runtimeModel.lookList[userId]) {
  57. RuntimeModelUtils.removeLook(userId)
  58. // 判断是否有学生
  59. runtime.lookCount = runtime.lookCount - 1 >= 0 ? runtime.lookCount - 1 : 0
  60. }
  61. // 同步移动端观看人数
  62. await RuntimeUtils.sendMessage({ count: runtime.lookCount }, 'MemberCount')
  63. },
  64. onSeatApply(evt: any) {
  65. // console.log(evt, 'onSeatApply joinModel')
  66. if (Array.isArray(evt)) {
  67. for (const id of evt) {
  68. console.log('onSeatApply', id)
  69. RuntimeModelUtils.removeJoin(id)
  70. }
  71. return
  72. }
  73. const response = evt.$EventMessage.messageType === 'RC:Chatroom:SeatResponse'
  74. const userRoomType = response ? 4 : 3
  75. // if(evt.$EventMessage.messageType === 'RC:Chatroom:SeatResponse')
  76. const sendTime = dayjs(evt.$EventMessage.sentTime || new Date()).format('HH:mm:ss')
  77. let tempObj = {
  78. name: evt.audienceName,
  79. id: String(evt.audienceId),
  80. system: 1,
  81. isSelf: false,
  82. content: '',
  83. sendTime
  84. }
  85. // 申请连麦
  86. if (evt.type === 3) {
  87. console.log(evt, '申请连麦')
  88. const params = {
  89. name: evt.audienceName,
  90. id: evt.audienceId,
  91. userRoomType: userRoomType,
  92. type: evt.type,
  93. }
  94. RuntimeModelUtils.addJoin(evt.audienceId, params)
  95. RuntimeModelUtils.addLook(evt.audienceId, params)
  96. tempObj.content = response ? '同意了连麦申请' : '发起了连麦申请'
  97. RuntimeModelUtils.addMessage(tempObj);
  98. event.emit('MESSAGE:Change')
  99. }
  100. // 取消连麦
  101. if (evt.type === 4) {
  102. console.log(evt, '取消连麦')
  103. if (runtimeModel.joinList[evt.audienceId]) {
  104. RuntimeModelUtils.removeJoin(evt.audienceId)
  105. }
  106. if (runtimeModel.lookList[evt.audienceId]) {
  107. let userLook = runtimeModel.lookList[evt.audienceId]
  108. userLook.userRoomType = 1
  109. RuntimeModelUtils.addLook(evt.audienceId, userLook)
  110. }
  111. //
  112. tempObj.content = response ? '拒绝了连麦申请' : '取消了连麦申请'
  113. RuntimeModelUtils.addMessage(tempObj);
  114. event.emit('MESSAGE:Change')
  115. }
  116. },
  117. agree(item: any) {
  118. if (this.count > 3 || this.upStatus) {
  119. console.log(true, 2323)
  120. return
  121. }
  122. this.upStatus = true
  123. const data = {
  124. ...item,
  125. audienceName: item.name,
  126. audienceId: String(item.id),
  127. teacherId: String(state.user?.id),
  128. teacherName: state.user?.speakerName,
  129. userRoomType: 4,
  130. type: 1,
  131. }
  132. RuntimeModelUtils.addJoin(item.id, data)
  133. RuntimeModelUtils.addLook(item.id, data)
  134. RuntimeUtils.sendMessage(data, 'SeatResponse')
  135. setTimeout(() => {
  136. this.upStatus = false
  137. }, 300);
  138. },
  139. refuse(item: any) {
  140. if(this.downStatus) {
  141. return
  142. }
  143. this.downStatus = true
  144. const data = {
  145. ...item,
  146. audienceName: item.name,
  147. audienceId: String(item.id),
  148. teacherId: String(state.user?.id),
  149. teacherName: state.user?.speakerName,
  150. userRoomType: 4,
  151. type: 5,
  152. }
  153. RuntimeModelUtils.addJoin(item.id, data)
  154. RuntimeUtils.sendMessage(data, 'SeatApply')
  155. setTimeout(() => {
  156. this.downStatus = false
  157. }, 300);
  158. },
  159. onSwitchRole(evt: any) {
  160. console.log(evt, 'onSwitchRole')
  161. if (runtimeModel.joinList[evt.userId] && evt.role === 2) {
  162. const user = runtimeModel.joinList[evt.userId]
  163. const sendTime = dayjs(new Date()).format('HH:mm:ss')
  164. let tempObj = {
  165. name: user.audienceName,
  166. id: user.audienceId,
  167. system: 1,
  168. isSelf: false,
  169. content: '发起了连麦申请',
  170. sendTime
  171. }
  172. RuntimeModelUtils.addMessage(tempObj);
  173. event.emit('MESSAGE:Change')
  174. RuntimeModelUtils.removeJoin(evt.userId)
  175. }
  176. if (runtimeModel.lookList[evt.userId] && evt.role === 2) {
  177. let userLook = runtimeModel.lookList[evt.userId]
  178. userLook.userRoomType = 1
  179. RuntimeModelUtils.addLook(evt.userId, userLook)
  180. }
  181. }
  182. },
  183. render() {
  184. const list = Object.values(runtimeModel.joinList)
  185. return (
  186. <div style={{ minHeight: '100%', position: 'relative' }}>
  187. {list.length > 0 ? list.map((item: any) => (
  188. <div class={styles.itemContent}>
  189. <div class={styles.itemInfo}>
  190. <div class={styles.itemName}>
  191. <p class={styles.userName}>
  192. <span class={styles['name-style']}>{item.name}</span>
  193. {item.userRoomType !== 4 ? <span style={{ paddingLeft: '10px' }}>申请连麦</span> : <span style={{ paddingLeft: '10px', color: 'var(--live-text-color)' }}>正在连麦</span>}
  194. </p>
  195. {item.userRoomType !== 4 ? (
  196. <div class={styles.joinText}>
  197. <div class={styles.join}>
  198. {/* 申请连麦 */}
  199. </div>
  200. <ElButton size="small" type="primary" disabled={this.count > 3} class={styles.btn} onClick={() => this.agree(item)}>上麦</ElButton>
  201. </div>
  202. ) : (
  203. <div class={styles.joinText}>
  204. <div class={styles.join}>
  205. {/* 正在连麦 */}
  206. </div>
  207. <ElButton size="small" plain class={[styles.btn, styles.downBtn]} onClick={() => this.refuse(item)}>下麦</ElButton>
  208. </div>
  209. )}
  210. </div>
  211. </div>
  212. </div>
  213. )) : 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" />}
  214. </div>
  215. )
  216. }
  217. })