room.ts 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383
  1. // pages/room/room.ts
  2. import { fetchRoom, RoomDetailType } from '../../api/fetchRoom'
  3. import { shareRoom } from '../../api/shareRoom'
  4. import { getRTCSig } from '../../api/sign'
  5. import { server } from '../../config'
  6. import { authorizeRecord } from '../../utils/util'
  7. import { audioManger, AudioManger } from './libs/audioManager'
  8. // import Dialog from 'tdesign-miniprogram/dialog/index';
  9. // const { io } = require('../../utils/socket.io-v4-no-msgpack')
  10. const { io } = require('../../utils/socket.io-v4.msgpack')
  11. Page({
  12. socket: {} as SocketIOClient.Socket,
  13. audioManger: {} as AudioManger,
  14. /**
  15. * 页面的初始数据
  16. */
  17. data: {
  18. patchProfile: false,
  19. patchProfilePhone: false,
  20. role: 'customer',
  21. roomId: '',
  22. webUrl: '',
  23. userInfo: {} as GlobalUserInfo,
  24. webviewParams: {} as SocketParams,
  25. isTour: 0,
  26. m: '',
  27. showShare: false
  28. },
  29. /**
  30. * 生命周期函数--监听页面加载
  31. */
  32. async onLoad(options: { roomId: string, role: string, isTour: string }) {
  33. console.log('options', options)
  34. const auth = await authorizeRecord();
  35. console.log('auth', auth)
  36. await this.autoLogin();
  37. if (options.isTour) {
  38. this.setData({ isTour: Number(options.isTour) })
  39. }
  40. if (options.role) {
  41. this.setData({ role: options.role })
  42. }
  43. if (options.roomId) {
  44. await this.setRole(options.roomId);
  45. }
  46. const isSuccess = await this.setWebViewUrl();
  47. if (isSuccess) {
  48. this.handleJoinSocket();
  49. this.handleJoinRTC();
  50. }
  51. },
  52. async setRole(roomId: string) {
  53. let roomInfo: RoomDetailType
  54. roomInfo = await fetchRoom(roomId);
  55. let num = roomInfo.sceneData && roomInfo.sceneData?.length ? roomInfo?.sceneData[0].num :'';
  56. if (!num) {
  57. console.error('场景码不能为空!');
  58. wx.showModal({
  59. title: '提示',
  60. content: '服务器初始化异常,请稍后再试!',
  61. showCancel: false,
  62. success(res) {
  63. if (res.confirm) {
  64. console.log('用户点击确定')
  65. wx.redirectTo({
  66. url:"/pages/myScene/myScene"
  67. })
  68. }
  69. }
  70. });
  71. return
  72. }
  73. this.setData({ roomDetail: roomInfo, roomId: roomId, m: num })
  74. if (roomInfo && roomInfo.hostStatus === 0) {
  75. this.setData({
  76. isTour: 1
  77. })
  78. }
  79. //1.是加入带看
  80. if (roomInfo && roomInfo.hostStatus === 1) {
  81. this.setData({
  82. isTour: 0
  83. })
  84. }
  85. if (roomInfo && roomInfo.isHost === 1) {
  86. // wx.showModal({
  87. // title: '测试',
  88. // content: '当前是leader',
  89. // success(res) {
  90. // if (res.confirm) {
  91. // console.log('用户点击确定')
  92. // } else if (res.cancel) {
  93. // console.log('用户点击取消')
  94. // }
  95. // }
  96. // });
  97. this.setData({ role: 'leader' })
  98. } else {
  99. // wx.showModal({
  100. // title: '测试',
  101. // content: '当前不是leader',
  102. // success(res) {
  103. // if (res.confirm) {
  104. // console.log('用户点击确定')
  105. // } else if (res.cancel) {
  106. // console.log('用户点击取消')
  107. // }
  108. // }
  109. // });
  110. this.setData({ role: 'customer' })
  111. }
  112. },
  113. webViewParams() {
  114. // const regex = /^[\u4E00-\u9FA5A-Za-z0-9]+$/
  115. // '⎕'
  116. // if (!regex.test(this.data.userInfo.nickName)) {
  117. // this.setData({
  118. // 'userInfo.nickName': 'user_' + this.data.userInfo.wxUserId
  119. // })
  120. // }
  121. const filterNickname = (value: string) => {
  122. var reg = /\\|\/|\?|\?|\*|\"|\“|\”|\'|\‘|\’|\<|\>|\{|\}|\[|\]|\【|\】|\:|\:|\、|\^|\$|\#|\&|\%|\!|\~|\`|\|/g;
  123. var temp = value.replace(reg, "◻");
  124. this.setData({
  125. 'userInfo.nickName': temp
  126. })
  127. console.log('filterNickname', temp);
  128. }
  129. filterNickname(this.data.userInfo.nickName);
  130. const params: SocketParams = {
  131. vruserId: `${this.data.userInfo.wxUserId}`,
  132. roomId: `${this.data.roomId}`,
  133. role: this.data.role,
  134. avatar: encodeURIComponent(this.data.userInfo.avatarUrl),
  135. name: this.data.userInfo.nickName.length > 14 ? encodeURIComponent(this.data.userInfo.nickName.substr(0, 14) + '...') : encodeURIComponent(this.data.userInfo.nickName),
  136. isTour: this.data.isTour,
  137. m: this.data.m,
  138. fromMiniApp: 1,
  139. }
  140. this.setData({
  141. webviewParams: params
  142. })
  143. type Keys = keyof typeof params;
  144. return Object.keys(params).map(key => `${key}=${params[key as Keys]}`).join('&')
  145. },
  146. async autoLogin() {
  147. const app = getApp<IAppOption>();
  148. if (!app.globalData.isLogin) {
  149. const userInfo = await app.login(false)
  150. console.log('hehe', userInfo)
  151. userInfo && this.updateUserInfo(userInfo);
  152. }
  153. },
  154. async setWebViewUrl() {
  155. const app = getApp<IAppOption>();
  156. if (!this.data.userInfo.nickName || !this.data.userInfo.avatarUrl) {
  157. this.setData({
  158. patchProfile: true
  159. })
  160. if (!this.data.userInfo.phoneNumber) {
  161. this.setData({
  162. patchProfilePhone: true
  163. })
  164. }
  165. return Promise.resolve(false)
  166. }
  167. const params = this.webViewParams();
  168. const webURL = server.webview + '?' + params
  169. console.log('webviewServer', webURL)
  170. this.setData({
  171. webUrl: webURL
  172. })
  173. await app.sleep(100);
  174. return Promise.resolve(true)
  175. },
  176. async handleProfilePatch() {
  177. const app = getApp<IAppOption>();
  178. const roomId = this.data.roomId
  179. this.setRole(roomId);
  180. await app.sleep(200);
  181. const isSuccess = await this.setWebViewUrl();
  182. if (isSuccess) {
  183. this.handleJoinSocket();
  184. this.handleJoinRTC();
  185. }
  186. },
  187. updateUserInfo(data?: any) {
  188. console.log('webview-updateUserInfo')
  189. const app = getApp<IAppOption>();
  190. const updateUserInfo = app.globalData.userInfo
  191. const updateData = Object.assign({}, updateUserInfo, data)
  192. this.setData({
  193. userInfo: updateData
  194. })
  195. },
  196. handleJoinSocket() {
  197. this.socket = io(server.sokcet, {
  198. path: "/ws-sync",
  199. transport: ["websocket"],
  200. parser: false
  201. });
  202. this.socket.on('connect', async () => {
  203. const params = this.data.webviewParams
  204. this.socket.emit('join', {
  205. userId: params.vruserId,
  206. roomId: params.roomId,
  207. role: params.role,
  208. isClient: true
  209. })
  210. });
  211. this.socket.on('action', this.handleSocketAction)
  212. this.socket.on('signal', this.handleSocketSignal)
  213. },
  214. async handleJoinRTC() {
  215. const userId = wx.getStorageSync('wxUserId')
  216. const sign = await getRTCSig(userId);
  217. const isTour = this.data.isTour
  218. this.audioManger = audioManger({
  219. roomId: this.data.webviewParams.roomId,
  220. userId: userId,
  221. sdkAppID: sign.sdkAppId,
  222. sig: sign.sign,
  223. role: this.data.webviewParams.role,
  224. noMute: false,
  225. })
  226. if (!this.audioManger.ring) {
  227. this.audioManger.start()
  228. }
  229. },
  230. /**
  231. * 生命周期函数--监听页面初次渲染完成
  232. */
  233. onReady() {
  234. const app = getApp<IAppOption>();
  235. app.watch('userInfo', this.updateUserInfo)
  236. },
  237. /**
  238. * 生命周期函数--监听页面显示
  239. */
  240. onShow() {
  241. },
  242. /**
  243. * 生命周期函数--监听页面隐藏
  244. */
  245. onHide() {
  246. },
  247. /**
  248. * 生命周期函数--监听页面卸载
  249. */
  250. onUnload() {
  251. this.audioManger && this.audioManger.stop()
  252. if (this.socket) {
  253. this.socket.off('action', this.handleSocketAction)
  254. this.socket.off('signal', this.handleSocketSignal)
  255. this.socket && this.socket.disconnect()
  256. }
  257. },
  258. /**
  259. * 页面相关事件处理函数--监听用户下拉动作
  260. */
  261. onPullDownRefresh() {
  262. },
  263. /**
  264. * 页面上拉触底事件的处理函数
  265. */
  266. onReachBottom() {
  267. },
  268. onShareAppMessage: function (res) {
  269. const roomId = this.data.roomId
  270. const userId = this.data.userInfo.wxUserId
  271. const isTour = this.data.isTour
  272. const newPicUrl = this.data.roomDetail.roomCoverUrl || 'http://video.cgaii.com/new4dage/images/images/home_2_a.jpg'
  273. const base = {
  274. imageUrl: newPicUrl,
  275. path: `/pages/room/room?roomId=${roomId}&role=customer&isTour=${isTour}`
  276. }
  277. if (roomId && userId) {
  278. shareRoom(roomId, userId);
  279. }
  280. console.error('share', base, roomId, userId);
  281. if (res.from === 'button') {
  282. this.setData({
  283. showShare: false
  284. })
  285. return {
  286. ...base,
  287. title: '【好友邀请】一起来带看吧!',
  288. }
  289. } else {
  290. return {
  291. ...base,
  292. title: '【好友邀请】一起来带看吧!',
  293. }
  294. }
  295. },
  296. handleSocketAction(action: SocketAction) {
  297. console.warn('action', action)
  298. switch (action.type) {
  299. case 'users-muted':
  300. this.handleActionMuted(action.userId, action.muted)
  301. break;
  302. case 'users-inviteMember':
  303. this.handleInviteMember(action.userId, action.data)
  304. break;
  305. case 'changeScene':
  306. this.audioManger.changeMute(true);
  307. break;
  308. default:
  309. break;
  310. }
  311. },
  312. handleSocketSignal(data) {
  313. debugger
  314. },
  315. handleActionMuted(userId: string | undefined, muted: boolean | undefined) {
  316. console.error('handleActionMuted');
  317. if (userId && typeof muted !== "undefined") {
  318. const f_userId = userId.replace('user_', '')
  319. const app = getApp<IAppOption>();
  320. if (app.globalData.userInfo?.wxUserId == f_userId) {
  321. this.audioManger.changeMute(muted)
  322. }
  323. }
  324. },
  325. handleInviteMember(userId: string | undefined, data: any) {
  326. if (userId) {
  327. const f_userId = userId.replace('user_', '')
  328. const app = getApp<IAppOption>();
  329. if (app.globalData.userInfo?.wxUserId == f_userId) {
  330. this.setData({
  331. showShare: true
  332. })
  333. }
  334. }
  335. },
  336. cancelShare() {
  337. this.setData({
  338. showShare: false
  339. })
  340. }
  341. })