Newer
Older
DH_Apicture / src / views / RongyunCommunication / RongYunBox / index.vue
@ZZJ ZZJ on 2 Dec 25 KB 更新融云样式
  1. <template>
  2. <div class="RongYun" id="RongYun">
  3. <div class="rong-container" id="rongContainer">
  4. <div class="rong-action" id="rong-action">
  5. <div class="textDiv2">
  6. <div class="textTitle">
  7. <span class="dote"></span>
  8. <span>接收用户:</span>
  9. </div>
  10. <div class="userList" v-if="allData.userList.length > 0">
  11. <template v-for="(item, index) in allData.userList" :key="index">
  12. <div class="user" v-if="item.phone != userId">
  13. <div class="userInfoClass">
  14. <span class="username">{{ item.name }}:</span>
  15. <div class="ceninfoBox">
  16. <div class="userphone" v-if="item.phone">
  17. {{ geTel(item.phone) }}
  18. </div>
  19. <div class="userphone userdept">{{ item.deptName }}</div>
  20. </div>
  21. </div>
  22. <div>
  23. <span style="margin-left: 10px" :class="'classType' + item.ClassType">{{ item.typeFont }}</span>
  24. </div>
  25. </div>
  26. </template>
  27. </div>
  28. </div>
  29. <div class="textDiv">
  30. <span class="dote"></span>
  31. <div class="text">
  32. <span>发起人:</span><span class="Rightvalue" @click="getToken()">{{ userinfo.userName }}</span>
  33. </div>
  34. </div>
  35. <div class="textDiv">
  36. <span class="dote"></span>
  37. <div class="text">
  38. <span>当前登录用户 ID:</span><span id="userId" class="Rightvalue" @click="getToken()">{{ userId + '_web' }}</span>
  39. </div>
  40. </div>
  41.  
  42. <div class="textDiv">
  43. <span class="dote"></span>
  44. <div class="text">
  45. <span>通话类型:</span>
  46.  
  47. <el-radio-group
  48. v-model="mediaType"
  49. style="display: flex; justify-content: center; align-items: center"
  50. @change="changeMediaType"
  51. >
  52. <el-radio :label="2">视频</el-radio>
  53. <el-radio :label="1">语音</el-radio>
  54. </el-radio-group>
  55. </div>
  56. </div>
  57. <div id="inviteList" class="textDiv">
  58. <span class="dote"></span>
  59. <div class="text">
  60. <span>选择邀请人:</span>
  61.  
  62. <el-select
  63. v-model="Getidinvite"
  64. placeholder="选择被邀请人"
  65. filterable
  66. multiple
  67. collapse-tags
  68. :popper-append-to-body="true"
  69. popper-class="eloption"
  70. >
  71. <el-option v-for="dict in inviteuserIdsList" :key="dict.id" :label="dict.name" :value="dict.id"></el-option>
  72. </el-select>
  73. </div>
  74. </div>
  75. <div class="rong-login-box">
  76. <div class="btn callBtn" id="call" @click="callHandler()">
  77. <img src="/src/assets/images/rongYunImg/callic.png" alt="" />
  78. 发起通话
  79. </div>
  80. <div class="btn hunupBtn hangBtn" id="hunup" @click="hungup()">
  81. <img src="/src/assets/images/rongYunImg/hangic.png" alt="" />
  82. 挂断
  83. </div>
  84. <div class="btn inviteBtn hunupBtn" id="invite" @click="inviteCall()">邀请</div>
  85. </div>
  86. </div>
  87. <div id="videoView" class="rong-video-box newbox"></div>
  88. </div>
  89. </div>
  90. </template>
  91. <script setup>
  92. import moment from 'moment';
  93. import useUserStore from '@/store/modules/user';
  94. import { ElMessageBox } from 'element-plus';
  95.  
  96. import bus from '@/utils/util';
  97. import rongyunStore from '@/store/modules/rongyunStore';
  98. import {
  99. listrcloudUnitUser,
  100. getUserStatus,
  101. rongyunGroupSave,
  102. groupJoinUsers,
  103. batchAdd,
  104. answer,
  105. hangUp,
  106. } from '@/views/RongyunCommunication/rongyunjs/rongyunApi.js';
  107. import { findCurrentTreeObj } from '@/utils/ruoyi';
  108.  
  109. import { RCCallErrorCode } from '@rongcloud/plugin-call';
  110.  
  111. const appStore = useUserStore();
  112. const useRongyunStore = rongyunStore();
  113. const { proxy } = getCurrentInstance();
  114. const inviteuserIdsList = ref([]); //被邀请人的列表
  115. const Getidinvite = ref([]);
  116. const allData = reactive({
  117. typeList: [
  118. {
  119. label: '视频',
  120. value: 2,
  121. },
  122. {
  123. label: '语音',
  124. value: 1,
  125. },
  126. ],
  127. userId: appStore.userInfo.phonenumber,
  128. userName: '',
  129. mediaType: useRongyunStore.mediaType,
  130. userList: [],
  131. idList: [],
  132. userinfo: appStore.userInfo,
  133. unitArr: [],
  134. });
  135. const { typeList, userId, userName, mediaType, userList, idList, userinfo, unitArr } = toRefs(allData);
  136. const props = defineProps({
  137. ryUser: Object,
  138. callType: Number,
  139. });
  140.  
  141. const paramSave = ref({
  142. groupId: undefined, //群聊Id
  143. promoterThridUserId: appStore.userInfo.phonenumber + '_web', //发起人id
  144. answerThridUserIds: '', //接收人id
  145. type: '', //通话类型 1是视频 2是语音
  146. createBy: localStorage.getItem('userNo'),
  147. });
  148.  
  149. onMounted(() => {
  150. nextTick(() => {
  151. initGroupData();
  152. });
  153. bus.on('removeEle', e => {
  154. removeVideoEl();
  155. });
  156. });
  157.  
  158. onBeforeUnmount(() => {
  159. close();
  160. });
  161. const geTel = tel => {
  162. var reg = /^(\d{3})\d{4}(\d{4})$/;
  163. return tel.replace(reg, '$1****$2');
  164. };
  165.  
  166. // 处理群呼数据
  167. const initGroupData = () => {
  168. console.log('props.ryUser 处理群呼/单呼数据', props.ryUser);
  169. allData.userList = [];
  170. if (props.callType == 2) {
  171. let arr = [].concat(props.ryUser.userList);
  172. arr.forEach(v => {
  173. allData.userList.push({
  174. name: v.name,
  175. phone: v.registerThridUserId,
  176. typeFont: null,
  177. ClassType: null,
  178. });
  179. });
  180. } else {
  181. allData.userList.push({
  182. name: props.ryUser.name,
  183. phone: props.ryUser.phone,
  184. typeFont: null,
  185. ClassType: null,
  186. });
  187. }
  188. console.log('allData.userList', allData.userList);
  189. };
  190.  
  191. const getDom = key => {
  192. return document.querySelector(key);
  193. };
  194. const changeMediaType = value => {
  195. console.log('value', value);
  196. useRongyunStore.SET_MediaType(value);
  197. };
  198. /**
  199. * CallSession 事件
  200. */
  201. const getCallSessionEvent = () => {
  202. return {
  203. onRinging: sender => {
  204. // 当远端用户已开始响铃, 该函数有 2 个参数: sender 是发送者,session 是通话实例。这时用户可以在业务层做响铃的 UI 展示。
  205. // ;
  206. proxy.$modal.msgWarning(` ${sender.userId} 振铃`);
  207. allData.userList.forEach(element => {
  208. if (element.phone == sender.userId) {
  209. element.typeFont = '对方已响铃';
  210. element.ClassType = 1;
  211. }
  212. });
  213. },
  214. onAccept: sender => {
  215. // 当远端用户已同意接听, 该函数有 2 个参数: sender 是发送者,session 是通话实例。这时用户可以把 UI 的‘响铃’变成‘通话中’。
  216. proxy.$modal.msgWarning(` ${sender.userId} 已接听`);
  217. console.log('接听监听,', allData.userList, sender);
  218. allData.userList.forEach(element => {
  219. if (element.phone == sender.userId) {
  220. element.typeFont = '已接听';
  221. element.ClassType = 2;
  222. element.answerType = 4;
  223. acceptApi(element);
  224. }
  225. });
  226. },
  227. onHungup: (sender, reason) => {
  228. // 当有远端用户挂断, 该函数有 3 个参数: sender 是发送者,reason 是挂断原因,session 是通话实例。这时用户可以在 UI 层提示‘xxx已挂断’。
  229. proxy.$modal.msgWarning(` ${sender.userId} 已挂断`);
  230. console.log('挂断监听,', allData.userList, sender);
  231. console.log('挂断监听挂断原因,', reason);
  232.  
  233. allData.userList.forEach(element => {
  234. if (element.phone == sender.userId) {
  235. element.typeFont = '已挂断';
  236. element.answerType = reason;
  237. // 挂断原因转义成后端所需字段
  238. // 1.未响铃 2.响铃未接听 3.响铃后挂断 4.已接听
  239.  
  240. // 响铃后挂断
  241. // if (reason == 12) {
  242. // element.answerType = 3;
  243. // }
  244.  
  245. // // 响铃未接听
  246. // if (reason == 15) {
  247. // element.answerType = 2;
  248. // }
  249.  
  250. // // 已接听
  251. // if (reason == 13) {
  252. // element.answerType = 4;
  253. // }
  254.  
  255. hungupApi(element);
  256. }
  257. });
  258. // 群组中移除相应节点
  259. const videoViewDom = getDom('#videoView');
  260. const videoDom = getDom(`#video-${sender.userId}`);
  261. videoDom && videoViewDom.removeChild(videoDom);
  262. const itemdomList = document.getElementsByClassName('video-item');
  263. if (itemdomList.length <= 1) {
  264. restore();
  265. }
  266. },
  267. onTrackReady: track => {
  268. // 当本端资源或远端资源已获取, 该函数有 2 个参数:track 是本端资源或远端资源, session 是通话实例。这时用户可以用拿到的 track 播放音频、视频。
  269. setTimeout(() => {
  270. appendVideoEl(track);
  271. }, 1500);
  272. // 当本端资源或远端资源已获取, 该函数有 2 个参数:track 是本端资源或远端资源, session 是通话实例。这时用户可以用拿到的 track 播放音频、视频。
  273. if (!track.isLocalTrack()) {
  274. proxy.$modal.msgWarning('通话已建立');
  275. }
  276. },
  277. onMemberModify: (sender, invitedUsers, session) => {
  278. console.log('触发邀请监听', sender, invitedUsers, session);
  279. console.log('触发邀请监听', allData.userList);
  280.  
  281. // 群组通话中有其他人被邀请加入, 该函数有 3 个参数: sender 是发送者,invitedUsers 是被邀请的用户列表, session 是通话实例。这时用户可以在 UI 层提示‘xxx加入通话’。
  282. },
  283. onMediaModify: sender => {
  284. // 通话类型改变时触发, 该函数有3个参数: sender 是发送者,mediaType 通话类型, session 是通话实例。这时用户可以在 UI 层提示‘已降级成音频通话’。
  285. },
  286. onAudioMuteChange: muteUser => {
  287. // 对方静音后触发, 该函数有2个参数: muteUser 是已静音的用户, session 是通话实例。这时用户可以在 UI 层提示‘xxx已静音’。
  288. proxy.$modal.msgWarning(` ${sender.userId} 已静音`);
  289. },
  290. onVideoMuteChange: muteUser => {
  291. // 对方禁用视频后触发, 该函数有2个参数: muteUser 是已禁用视频的用户, session 是通话实例。这时用户可以在 UI 层提示‘xxx已禁用视频’。
  292. proxy.$modal.msgWarning(` ${sender.userId} 已禁用视频`);
  293. },
  294. };
  295. };
  296. /**
  297. * callSession 事件注册
  298. */
  299. const registerCallSessionEvent = session => {
  300. const events = getCallSessionEvent();
  301. session.registerSessionListener(events);
  302. };
  303. const callHandler = () => {
  304. console.log('..??', props);
  305. props.callType == 1 ? rongYunCall() : groupCall();
  306. };
  307. // 单呼
  308. const call = () => {
  309. getDom('#call').style.display = 'none';
  310. getDom('#hunup').style.display = 'block';
  311. const events = getCallSessionEvent();
  312. console.log('props.ryUser', props.ryUser);
  313. console.log('props.ryUser.phone2', props.ryUser.phone);
  314. // 这里是传给融云拨打电话的传递userid
  315. const params = {
  316. targetId: props.ryUser.phone,
  317. mediaType: useRongyunStore.mediaType,
  318. listener: events,
  319. };
  320. useRongyunStore.callClient.call(params).then(({ code, session }) => {
  321. if (code === 10000) {
  322. registerCallSessionEvent(session);
  323. useRongyunStore.SET_CALLSESSION(session);
  324.  
  325. saveOnAccept();
  326. } else {
  327. proxy.$modal.msgWarning(`呼叫失败,错误原因:${code}`);
  328. }
  329. });
  330. };
  331. //单呼前判登录用户在线状态
  332. const rongYunCall = async item => {
  333. console.log('allData.userId', allData.userId, appStore.userInfo);
  334. let params = {
  335. registerThridUserId: allData.userId + '_web',
  336. };
  337.  
  338. let res1 = await getUserStatus(params);
  339. let flag1 = null;
  340. if (res1.code == 200) {
  341. flag1 = JSON.parse(res1.data);
  342. }
  343. if (flag1 != 1) {
  344. ElMessageBox.confirm(`${appStore.userInfo.userName || '当前'}用户视频会商不在线,是否重新连接?, "提示"`, {
  345. confirmButtonText: '确定',
  346. cancelButtonText: '取消',
  347. type: 'warning',
  348. })
  349. .then(() => {
  350. setTimeout(() => {
  351. bus.emit('rystatus');
  352. getCallStatus();
  353. }, 1500);
  354. })
  355. .catch(() => {});
  356. } else {
  357. setTimeout(() => {
  358. getCallStatus();
  359. }, 1500);
  360. }
  361. };
  362. //单呼前判对方用户在线状态
  363. const getCallStatus = async () => {
  364. let params = {
  365. registerThridUserId: props.ryUser.phone,
  366. };
  367.  
  368. let res = await getUserStatus(params);
  369. let flag = null;
  370. if (res.code == 200) {
  371. flag = JSON.parse(res.data);
  372. }
  373. if (flag != 1) {
  374. return proxy.$modal.msgWarning(`${props.ryUser.name}用户视频会商不在线!`);
  375. } else {
  376. call();
  377. }
  378. };
  379. //群呼
  380. const groupCall = () => {
  381. getDom('#call').style.display = 'none';
  382. getDom('#hunup').style.display = 'block';
  383. getDom('#invite').style.display = 'block';
  384. getDom('#inviteList').style.visibility = 'visible';
  385.  
  386. console.log('allData.userList', allData.userList, props.ryUser);
  387. allData.userList.forEach(v => {
  388. v.typeFont = '已拨号';
  389. v.ClassType = 0;
  390. v.answerType = 1;
  391. });
  392.  
  393. const events = getCallSessionEvent();
  394. const params = {
  395. targetId: props.ryUser.groupId,
  396. userIds: props.ryUser.userIds.split(','),
  397. mediaType: useRongyunStore.mediaType,
  398. listener: events,
  399. };
  400. console.log('param', params);
  401. useRongyunStore.callClient.callInGroup(params).then(({ code, session }) => {
  402. if (code === 10000) {
  403. registerCallSessionEvent(session);
  404. useRongyunStore.SET_CALLSESSION(session);
  405. saveOnAccept();
  406. GetallOnline();
  407. } else {
  408. const reason = code === RCCallErrorCode.NOT_IN_GROUP ? '当前用户未加入群组' : code;
  409. proxy.$modal.msgWarning(`呼叫失败,错误原因:${code}`);
  410. removeVideoEl();
  411. }
  412. });
  413. };
  414. let endids = ref([]);
  415.  
  416. // 邀请用户加入当前通话(仅限群组)
  417. const inviteCall = () => {
  418. if (Getidinvite.value && Getidinvite.value.length) {
  419. console.log('点击了邀请', Getidinvite.value, inviteuserIdsList.value);
  420. let ids = [];
  421. let GetuserList = [];
  422. Getidinvite.value.map(item => {
  423. inviteuserIdsList.value.map(p => {
  424. if (item == p.id) {
  425. GetuserList.push(p);
  426. }
  427. });
  428. });
  429. console.log('点击了邀请', GetuserList);
  430.  
  431. GetuserList.map(item => {
  432. item.userTokenList.length &&
  433. item.userTokenList.map(p => {
  434. if (p.isOnlion) {
  435. ids.push(p.registerThridUserId);
  436. }
  437. });
  438. });
  439.  
  440. endids.value = ids;
  441.  
  442. let params = {
  443. groupId: props.ryUser.groupId,
  444. ids: ids.join(','),
  445. };
  446. groupJoinUsers(params).then(res => {
  447. console.log(res);
  448.  
  449. console.log('点击了邀请', ids);
  450. useRongyunStore.callSession.invite(ids).then(({ code }) => {
  451. console.log(code);
  452. if (code === 10000) {
  453. proxy.$modal.msgSuccess(`邀请成功`);
  454. } else {
  455. proxy.$modal.msgWarning(`邀请失败,错误原因:${code}`);
  456. }
  457. });
  458. });
  459. } else {
  460. proxy.$modal.msgWarning(`请选择邀请人`);
  461. }
  462. };
  463.  
  464. // 批量新增融合通讯通话
  465. const saveOnAccept = () => {
  466. console.log('批量新增', props.ryUser);
  467. paramSave.value.type = useRongyunStore.mediaType;
  468. paramSave.value.groupId = props.callType == 1 ? -1 : props.ryUser.groupId;
  469. paramSave.value.answerThridUserIds = props.ryUser.phone || props.ryUser.userIds;
  470. //接听人单呼就是phone userIds 两个 数据不一样
  471.  
  472. console.log('paramSave.value', paramSave.value, props.ryUser);
  473.  
  474. batchAdd(paramSave.value).then(res => {
  475. if (res.code == 200) {
  476. console.log('批量新增融合通讯通话');
  477. }
  478. });
  479. };
  480.  
  481. // 接听后端接口
  482. const acceptApi = item => {
  483. console.log('调取了接听接口', item);
  484.  
  485. let params = {
  486. promoterThridUserId: appStore.userInfo.phonenumber + '_web', //发起人 当前登陆人
  487. answerThridUserId: item.phone, //接听人
  488. updateBy: localStorage.getItem('userNo'), //当前登录用户
  489. };
  490. answer(params).then(res => {
  491. console.log('调取了接听接口', res);
  492. });
  493. };
  494.  
  495. // 挂断融合通讯通话
  496. const hungupApi = item => {
  497. console.log('调取了挂断接口', item);
  498. let params = {
  499. promoterThridUserId: appStore.userInfo.phonenumber + '_web', //发起人
  500. answerThridUserId: item.phone, //接听人
  501. updateBy: localStorage.getItem('userNo'),
  502. answerType: item.answerType || null,
  503. };
  504.  
  505. hangUp(params).then(res => {
  506. console.log('调取了挂断接口', res);
  507. });
  508. };
  509.  
  510. // 获取所有注册用户
  511. const GetallOnline = item => {
  512. inviteuserIdsList.value = [];
  513. console.log('被邀请人', props.ryUser);
  514. // let havaUser = [];
  515.  
  516. // props.ryUser.userIds.map(item => {
  517. // havaUser.push(item.split('_')[0]);
  518. // });
  519.  
  520. // console.log('被邀请人', havaUser);
  521.  
  522. listrcloudUnitUser().then(res => {
  523. res.data.map(item => {
  524. if (item.isOnlion && !props.ryUser.userIds.includes(item.phone)) {
  525. inviteuserIdsList.value.push(item);
  526. }
  527. });
  528. console.log('被邀请人', inviteuserIdsList.value, props.ryUser.userIds);
  529. });
  530. };
  531.  
  532. /**
  533. * video 视图渲染
  534. */
  535. const appendVideoEl = async track => {
  536. const uid = track.getUserId();
  537. let params = {
  538. phone: uid.split('_')[0],
  539. };
  540. let mediaType = useRongyunStore.mediaType;
  541. let data = await listrcloudUnitUser(params);
  542. console.log('datar', data);
  543. if (data.code == 200) {
  544. const container = getDom('#videoView');
  545. const node = document.createElement('div');
  546. node.setAttribute('id', `video-${uid}`);
  547. if (allData.idList.findIndex(i => i == `video-${uid}`) == -1) {
  548. allData.idList.push(`video-${uid}`);
  549. }
  550. let videoTpl = null;
  551. if (mediaType == 1) {
  552. videoTpl = `<span class="video-user-id">${data.data[0].name}: ${uid} </span><span class="video-media-type"></span><video id="${uid}"></video>`;
  553. } else {
  554. videoTpl = `<span class="video-user-id">${data.data[0].name}: ${uid} </span><video id="${uid}"></video>`;
  555. }
  556. node.innerHTML = videoTpl;
  557. node.classList.add('video-item');
  558.  
  559. let length = allData.userList.length + endids.value.length;
  560. console.log('什么东西xxxxx', allData.userId, uid, props.callType, length);
  561.  
  562. // 根据人数判断渲染不同的视图样式
  563. if (allData.userId + '_web' == uid && length <= 2) {
  564. // 判断是当前用户 人数小于等于2人时给予单独样式
  565. node.classList.add('first-child');
  566. }
  567. if (length > 2 && length <= 4) {
  568. node.classList.add('video-item-4');
  569. }
  570. if (length > 4 && length <= 8) {
  571. node.classList.add('video-item-8');
  572. }
  573. if (track.isAudioTrack()) {
  574. if (mediaType == 1) {
  575. container.appendChild(node);
  576. }
  577. track.play();
  578. } else {
  579. container.appendChild(node);
  580. const videoEl = document.getElementById(`${track.getUserId()}`);
  581. track.play(videoEl);
  582. }
  583. const targetElements = document.querySelectorAll('.video-item');
  584. console.log('targetElements', targetElements);
  585.  
  586. targetElements.forEach(target => {
  587. target.classList.remove('video-item-4');
  588. target.classList.remove('video-item-8');
  589.  
  590. if (length > 2 && length <= 4) {
  591. target.classList.add('video-item-4');
  592. }
  593. if (length > 4 && length <= 8) {
  594. target.classList.add('video-item-8');
  595. }
  596. });
  597. }
  598. };
  599.  
  600. /**
  601. * 挂断当前 callSession
  602. */
  603. const hungup = () => {
  604. // console.log("1231------------------------", useRongyunStore.callSession);
  605. useRongyunStore.callSession.hungup().then(({ code }) => {
  606. if (code === 10000) {
  607. // proxy.$modal.msgWarning("挂断成功");
  608. getDom('#call').style.display = 'block';
  609. getDom('#hunup').style.display = 'none';
  610. getDom('#invite').style.display = 'none';
  611. getDom('#inviteList').style.visibility = 'hidden';
  612.  
  613. removeVideoEl();
  614. restore();
  615. } else {
  616. proxy.$modal.msgWarning(`挂断失败,错误原因:${code}`);
  617. }
  618.  
  619. allData.userList.forEach(element => {
  620. element.typeFont = '已挂断';
  621. element.ClassType = 3;
  622. element.answerType = code;
  623. hungupApi(element);
  624. });
  625. });
  626. };
  627. const removeVideoEl = () => {
  628. getDom('#videoView').innerHTML = '';
  629. getDom('#videoView').style = '';
  630. getDom('#call').style.display = 'block';
  631. getDom('#hunup').style.display = 'none';
  632. getDom('#invite').style.display = 'none';
  633. getDom('#inviteList').style.visibility = 'hidden';
  634. allData.idList = [];
  635. };
  636. const close = () => {
  637. if (useRongyunStore.callSession != null) {
  638. hungup();
  639. }
  640. restore();
  641. };
  642. // 输出组件的方法,让外部组件可以调用
  643. defineExpose({
  644. close,
  645. });
  646.  
  647. // 还原
  648. const restore = () => {
  649. let style = { width: '934px' };
  650. getDom('#rong-action').style.display = 'block';
  651. const dom = getDom('#RongYun');
  652. const dom1 = getDom('#videoView');
  653. getDom('#videoView').style = '';
  654. allData.idList.forEach((item, index) => {
  655. let videodom = getDom(`#${item}`);
  656. if (videodom) {
  657. videodom.style = null;
  658. }
  659. const titledom = getDom(`#${item} .video-user-id`);
  660. if (titledom) {
  661. titledom.style = null;
  662. }
  663. });
  664. };
  665. </script>
  666. <style lang="scss">
  667. @import '@/views/RongyunCommunication/rongyuncss/index.scss';
  668. .rong-container {
  669. padding: 0 20px;
  670. display: flex;
  671. width: 100%;
  672. height: 100%;
  673.  
  674. .rong-action {
  675. width: 35%;
  676. display: flex;
  677. flex-direction: column;
  678. margin-right: 20px;
  679.  
  680. #inviteList {
  681. visibility: hidden;
  682. }
  683.  
  684. .textDiv {
  685. min-height: 38px;
  686. line-height: 38px;
  687. display: flex;
  688. align-items: center;
  689. :deep(.el-radio) {
  690. color: #fff;
  691. }
  692. .dote {
  693. display: block;
  694. margin-right: 20px;
  695. width: 10px;
  696. height: 10px;
  697. background: #58fdff;
  698. border-radius: 10px;
  699. }
  700.  
  701. .text {
  702. display: flex;
  703. flex: 1;
  704. justify-content: space-between;
  705. font-size: 16px;
  706. font-family: Alibaba PuHuiTi;
  707. font-weight: 500;
  708. color: #81b6d4;
  709. }
  710. .Rightvalue {
  711. max-width: 160px;
  712. overflow: hidden; //溢出隐藏
  713. text-overflow: ellipsis; //超出显示省略号
  714. white-space: nowrap; //强制文本在一行内显示
  715. color: #fff;
  716. }
  717. }
  718.  
  719. .textDiv2 {
  720. // min-height: 45px;
  721. // line-height: 45px;
  722.  
  723. .dote {
  724. display: block;
  725. margin-right: 20px;
  726. width: 10px;
  727. height: 10px;
  728. background: #58fdff;
  729. border-radius: 10px;
  730. }
  731.  
  732. .textTitle {
  733. height: 40px;
  734. line-height: 40px;
  735. display: flex;
  736. align-items: center;
  737. font-size: 16px;
  738. font-weight: 500;
  739. color: #81b6d4;
  740. }
  741.  
  742. .userList {
  743. max-height: 220px;
  744. overflow-y: auto;
  745. .user {
  746. // background-color: #14306a;
  747. // padding: 0 10px;
  748. // margin-left: 20px;
  749. // border-bottom: 1px solid #0a0a0a;
  750. display: flex;
  751. justify-content: space-between;
  752. background: #093a73;
  753. align-items: center;
  754. border-radius: 1px;
  755. padding: 2px 8px;
  756. }
  757. .username {
  758. min-width: 52px;
  759. font-weight: 500;
  760. color: #13bfff;
  761. }
  762. .userphone {
  763. font-weight: bold;
  764. color: #ffffff;
  765. }
  766. .userInfoClass {
  767. display: flex;
  768. align-items: center;
  769. }
  770. .ceninfoBox {
  771. padding-left: 5px;
  772. .userdept {
  773. max-width: 140px;
  774. font-size: 12px;
  775. text-align: center;
  776. }
  777. }
  778. }
  779. }
  780.  
  781. .rong-login-box {
  782. // margin-left: 20px;
  783. display: flex;
  784. width: 300px;
  785. height: 40px;
  786. align-items: center;
  787. margin-top: 50px;
  788. .btn {
  789. margin-right: 20px;
  790. background: #14306a;
  791. border-radius: 4px;
  792. padding: 6px 10px;
  793. font-size: 16px;
  794. font-family: Alibaba PuHuiTi;
  795. font-weight: 400;
  796. display: flex;
  797. justify-content: space-around;
  798. align-items: center;
  799. color: #fff;
  800. margin: 0 auto;
  801. cursor: pointer;
  802. img {
  803. width: 18px;
  804. height: 18px;
  805. }
  806. }
  807. .callBtn {
  808. background: #67c23a;
  809. }
  810. .hangBtn {
  811. background: #ff3a5a;
  812. }
  813.  
  814. .inviteBtn {
  815. background: #158bd2;
  816. }
  817.  
  818. .hunupBtn {
  819. display: none;
  820. }
  821.  
  822. .acceptBtn {
  823. display: none;
  824. }
  825. }
  826. }
  827.  
  828. .rong-video-box {
  829. width: 70%;
  830. height: 600px;
  831. display: flex;
  832. flex-wrap: wrap;
  833. overflow: auto;
  834. position: relative;
  835.  
  836. .video-item {
  837. box-sizing: border-box;
  838. width: 100%;
  839. height: calc(100% - 10px);
  840. position: relative;
  841.  
  842. .video-user-id {
  843. position: absolute;
  844. top: 5px;
  845. padding: 0 5px;
  846. border-radius: 2px;
  847. z-index: 100;
  848. font-size: 14px;
  849. color: #58fdff;
  850. display: inline-block;
  851. width: 100%;
  852. text-align: center;
  853. }
  854.  
  855. .video-media-type {
  856. position: absolute;
  857. top: 30px;
  858. left: 0;
  859. display: block;
  860. width: 100%;
  861. height: calc(100% - 30px);
  862. background: url('@/assets/images/rongYunImg/yuyin_bg.png') no-repeat;
  863. background-size: 100% 100%;
  864. }
  865.  
  866. video {
  867. width: 100%;
  868. height: 100%;
  869. }
  870. }
  871.  
  872. .video-item-4 {
  873. width: 50%;
  874. height: calc(50% - 10px);
  875. }
  876.  
  877. .video-item-8 {
  878. width: 25%;
  879. height: calc(50% - 10px);
  880. }
  881.  
  882. .first-child {
  883. position: absolute;
  884. right: 0px;
  885. top: 0;
  886. width: 40%;
  887. height: 30%;
  888. z-index: 999;
  889. }
  890. }
  891. }
  892.  
  893. .eloption {
  894. z-index: 20000 !important;
  895. }
  896. </style>
  897.  
  898. <style lang="scss" scoped>
  899. .RongYun {
  900. width: 100%;
  901. height: calc(100% - 40px);
  902. position: relative;
  903.  
  904. .closeIcon {
  905. position: absolute;
  906. right: 0px;
  907. top: -30px;
  908.  
  909. &:hover {
  910. color: chocolate;
  911. }
  912. }
  913. }
  914. </style>