Grid.vue 43 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629
  1. <template>
  2. <div class="pb_content g_body">
  3. <div>
  4. <el-image
  5. class="coin coin1"
  6. :src="require('../../assets/grid/coin1.png')"
  7. fit="cover"
  8. ></el-image>
  9. <el-image
  10. class="coin coin2"
  11. :src="require('../../assets/grid/coin2.png')"
  12. fit="cover"
  13. ></el-image>
  14. <el-image
  15. class="coin coin3"
  16. :src="require('../../assets/grid/coin3.png')"
  17. fit="cover"
  18. ></el-image>
  19. <el-image
  20. class="coin coin4"
  21. :src="require('../../assets/grid/coin4.png')"
  22. fit="cover"
  23. ></el-image>
  24. </div>
  25. <div class="grid_member">
  26. <!-- <div class="member_imgbox">
  27. <el-image
  28. v-for="item in 4"
  29. :key="item"
  30. class="member_img"
  31. :src="require('../../assets/grid/portal.png')"
  32. fit="cover"
  33. ></el-image>
  34. </div>-->
  35. <el-button type="text" @click="dialogVisible2 = true">邀请成员</el-button>
  36. <!-- <el-button type="text">成员</el-button> -->
  37. <el-button type="text" v-if="RoomInfo.userid == userid" @click="dismiss"
  38. >解散房间</el-button
  39. >
  40. </div>
  41. <draggable
  42. element="div"
  43. v-model="data"
  44. class="g_body"
  45. @change="handleDraggableFormItemChange"
  46. @end="dragEnd"
  47. :move="checkMove"
  48. >
  49. <div
  50. v-for="(item, index) in data"
  51. :key="index"
  52. class="g_box"
  53. @mouseover="pIndex = index"
  54. @mouseleave="pIndex = ''"
  55. @dragstart="handleDragStart($event, index)"
  56. @dragover.prevent="handleDragOver($event, index)"
  57. @dragenter="handleDragEnter($event, index)"
  58. @dragend="handleDragEnd($event, index)"
  59. >
  60. <div
  61. :class="{
  62. 'left-popover': index < 3,
  63. 'right-popover': index == 3,
  64. 'top-popover': index > 3,
  65. visibleO: pIndex === index && item && (item.video || item.photo),
  66. }"
  67. >
  68. <div class="pChild" @click="check(index)">
  69. <el-image
  70. :src="require('../../assets/grid/upload.png')"
  71. fit="cover"
  72. ></el-image>
  73. <span>修改</span>
  74. </div>
  75. <div class="pChild" @click="deleteGrid(index)">
  76. <el-image
  77. :src="require('../../assets/grid/deleteT.png')"
  78. fit="cover"
  79. ></el-image>
  80. <span>删除</span>
  81. </div>
  82. <div class="pChild" @click="check(index, 2)">
  83. <el-image
  84. :src="require('../../assets/grid/edit.png')"
  85. fit="cover"
  86. ></el-image>
  87. <span>添加备注</span>
  88. </div>
  89. </div>
  90. <div class="rrrrbox" v-if="item && item.remarks && !item.photo && !item.video" @click="check(index, 3)">
  91. <div class="Rbox" v-for="(x, y) in item.remarks" :key="y">
  92. <div v-if="x.remarks != ''" style="display: flex">
  93. <el-image
  94. class="Rportal"
  95. :src="require('../../assets/grid/portal.png')"
  96. fit="cover"
  97. ></el-image>
  98. <div class="RContent">
  99. <div>{{ x.username }}</div>
  100. <div>{{ x.remarks }}</div>
  101. </div>
  102. </div>
  103. </div>
  104. </div>
  105. <div
  106. v-else-if="item && item.remarks"
  107. :class="{
  108. 'remark-right-popover': index > 11 && index != 15,
  109. 'remark-left-popover': index == 15,
  110. 'remark-bottom-popover': index < 12,
  111. visibleO: pIndex === index && item && item.remarks,
  112. }"
  113. >
  114. <div class="Rbox" v-for="(x, y) in item.remarks" :key="y">
  115. <div v-if="x.remarks != ''" style="display: flex">
  116. <el-image
  117. class="Rportal"
  118. :src="require('../../assets/grid/portal.png')"
  119. fit="cover"
  120. ></el-image>
  121. <div class="RContent">
  122. <div>{{ x.username }}</div>
  123. <div>{{ x.remarks }}</div>
  124. </div>
  125. </div>
  126. <div v-else-if="x.remarks == '' && y == 0">
  127. {{ x.username }}暂无备注
  128. </div>
  129. </div>
  130. </div>
  131. <el-image
  132. v-if="item && item.photo"
  133. v-viewer
  134. class="photo_img"
  135. :src="item.photo"
  136. fit="cover"
  137. ></el-image>
  138. <video-player
  139. v-else-if="item && item.video"
  140. class="video-player vjs-custom-skin"
  141. ref="videoPlayer"
  142. :playsinline="true"
  143. :options="item.video"
  144. style="width: 85%"
  145. ></video-player>
  146. <el-image
  147. v-else
  148. class="add_img"
  149. :src="require('../../assets/grid/add.png')"
  150. fit="cover"
  151. @click="check(index, 3)"
  152. ></el-image>
  153. </div>
  154. </draggable>
  155. <el-dialog
  156. title="上传文件"
  157. :visible.sync="dialogVisible"
  158. :append-to-body="true"
  159. width="800px"
  160. :before-close="handleClose"
  161. class="look_notice"
  162. >
  163. <div slot="title" class="header-title">
  164. <div class="title_add_student">上传文件</div>
  165. </div>
  166. <div>
  167. <div class="upload_box" v-show="!file.userid || file.userid == userid">
  168. <el-image
  169. class="list_img"
  170. :src="require('../../assets/grid/list.png')"
  171. fit="cover"
  172. ></el-image>
  173. <div class="upload_content">
  174. <div
  175. @click="addEvent($event)"
  176. @mouseover="file.photo ? (deleteVisible1 = true) : ''"
  177. @mouseleave="file.photo ? (deleteVisible1 = false) : ''"
  178. >
  179. <el-image
  180. class="delete_img"
  181. :src="require('../../assets/grid/delete.png')"
  182. fit="cover"
  183. v-if="deleteVisible1"
  184. @click.stop="deleteFile(1)"
  185. ></el-image>
  186. <el-image
  187. class="upload_img"
  188. :src="
  189. file.photo
  190. ? file.photo
  191. : require('../../assets/grid/image.png')
  192. "
  193. fit="cover"
  194. ></el-image>
  195. <input
  196. type="file"
  197. accept="image/*"
  198. style="display: none"
  199. ref="pathClear1"
  200. @change="beforeUpload($event, 1)"
  201. />
  202. </div>
  203. <div
  204. style="margin-left: 20px"
  205. @click="addEvent($event)"
  206. @mouseover="file.video ? (deleteVisible2 = true) : ''"
  207. @mouseleave="file.video ? (deleteVisible2 = false) : ''"
  208. >
  209. <el-image
  210. class="delete_img"
  211. :src="require('../../assets/grid/delete.png')"
  212. fit="cover"
  213. v-if="deleteVisible2"
  214. @click.stop="deleteFile(2)"
  215. ></el-image>
  216. <el-image
  217. class="upload_img"
  218. :src="
  219. file.video
  220. ? require('../../assets/grid/videoH.png')
  221. : require('../../assets/grid/video.png')
  222. "
  223. fit="cover"
  224. ></el-image>
  225. <input
  226. type="file"
  227. accept="video/mp4, video/quicktime, video/x-msvideo"
  228. style="display: none"
  229. ref="pathClear2"
  230. @change="beforeUpload($event, 2)"
  231. />
  232. </div>
  233. </div>
  234. </div>
  235. <div class="textarea_box">
  236. <div class="textarea_title">添加描述</div>
  237. <el-input
  238. type="textarea"
  239. v-model="remarks"
  240. placeholder="请输入描述..."
  241. class="textarea_content"
  242. :rows="5"
  243. resize="none"
  244. ></el-input>
  245. </div>
  246. </div>
  247. <span slot="footer" class="dialog-footer">
  248. <el-button class="close" @click="addGrid()" type="primary"
  249. >确定</el-button
  250. >
  251. </span>
  252. </el-dialog>
  253. <el-dialog
  254. title="邀请成员"
  255. :visible.sync="dialogVisible2"
  256. :append-to-body="true"
  257. width="400px"
  258. :before-close="handleClose"
  259. class="look_notice invite_dialog"
  260. >
  261. <div slot="title" class="header-title">
  262. <div class="title_add_student">邀请成员</div>
  263. </div>
  264. <div>
  265. <div class="invite_box">
  266. <div class="invite_title" ref="inviteT">
  267. {{ userinfo ? this.userinfo.name : "用户" }}邀请您参加思维网格
  268. </div>
  269. <div class="line"></div>
  270. <div class="invite_link">
  271. <div ref="invite1">复制链接加入房间:</div>
  272. <div ref="invite2" style="color:#3E8DE6;">https://cloud.cocorobo.cn/</div>
  273. </div>
  274. <div class="invite_num" ref="invite3">
  275. 房间号:
  276. <span style="color:#3E8DE6;">{{ goNum }}</span>
  277. </div>
  278. <div class="invite_num" ref="invite4">
  279. 复制房间号信息,打开思维网格输入即可加入。
  280. </div>
  281. </div>
  282. </div>
  283. <span slot="footer" class="dialog-footer">
  284. <el-button
  285. class="close tag-read"
  286. @click="copy"
  287. type="primary"
  288. :data-clipboard-text="copyText"
  289. >一键复制信息</el-button
  290. >
  291. </span>
  292. </el-dialog>
  293. <el-dialog
  294. title="创建/加入房间"
  295. :visible.sync="dialogVisible3"
  296. :append-to-body="true"
  297. width="400px"
  298. :before-close="handleClose2"
  299. class="look_notice invite_dialog room_dialog"
  300. >
  301. <div slot="title" class="header-title">
  302. <div class="title_add_student">创建/加入房间</div>
  303. </div>
  304. <div class="addRoom_box">
  305. <div>
  306. <el-input
  307. v-model="goNum"
  308. placeholder="请输入要加入的房间号"
  309. ></el-input>
  310. <div class="room_b">
  311. 备注:输入房间号点击加入房间或点击创建房间直接创建房间
  312. </div>
  313. <div class="room_btn">
  314. <el-button class="roomBtn" type="primary" @click="goRoom(goNum)"
  315. >加入房间</el-button
  316. >
  317. <el-button class="roomBtn" type="primary" @click="checkNum"
  318. >创建房间</el-button
  319. >
  320. </div>
  321. </div>
  322. </div>
  323. </el-dialog>
  324. <div v-if="proVisible" class="mask">
  325. <div class="progressBox">
  326. <div class="lbox">
  327. <img :src="require('../../assets/loading.gif')" />上传中,请稍后
  328. </div>
  329. <el-progress
  330. :text-inside="true"
  331. :stroke-width="20"
  332. :percentage="progress"
  333. style="width: 80%"
  334. ></el-progress>
  335. </div>
  336. </div>
  337. </div>
  338. </template>
  339. <script>
  340. import Clipboard from "clipboard";
  341. import draggable from "vuedraggable";
  342. export default {
  343. components: {
  344. //调用组件
  345. draggable,
  346. },
  347. data() {
  348. return {
  349. timer: null,
  350. userinfo: [],
  351. RoomInfo: [],
  352. copyText: "",
  353. userid: this.$route.query.userid,
  354. data: [],
  355. dialogVisible: false,
  356. dialogVisible2: false,
  357. dialogVisible3: true,
  358. deleteVisible1: false,
  359. deleteVisible2: false,
  360. dialogImgVisible: false,
  361. dialogImageUrl: "",
  362. remarks: "",
  363. goNum: this.$route.query.goNum ? this.$route.query.goNum : "",
  364. numNum: "",
  365. file: {},
  366. gIndex: "",
  367. pIndex: "",
  368. proVisible: false,
  369. progress: 0,
  370. playerOptions: {
  371. playbackRates: [0.7, 1.0, 1.5, 2.0], //播放速度
  372. autoplay: false, //如果true,浏览器准备好时开始回放。
  373. muted: false, // 默认情况下将会消除任何音频。
  374. loop: false, // 导致视频一结束就重新开始。
  375. preload: "auto", // 建议浏览器在<video>加载元素后是否应该开始下载视频数据。auto浏览器选择最佳行为,立即开始加载视频(如果浏览器支持)
  376. language: "zh-CN",
  377. aspectRatio: "16:9", // 将播放器置于流畅模式,并在计算播放器的动态大小时使用该值。值应该代表一个比例 - 用冒号分隔的两个数字(例如"16:9"或"4:3")
  378. fluid: true, // 当true时,Video.js player将拥有流体大小。换句话说,它将按比例缩放以适应其容器。
  379. sources: [
  380. {
  381. type: "video/mp4", //这里的种类支持很多种:基本视频格式、直播、流媒体等,具体可以参看git网址项目 || "video/ogg"|| "video/webm"
  382. src: "", //url地址require("../../assets/media/aaa.mp4")
  383. },
  384. ],
  385. // poster: require("../../assets/tu31.png"), //你的封面地址
  386. // poster: dataRes.imgUrl, //你的封面地址
  387. notSupportedMessage: "此视频暂无法播放,请稍后再试", //允许覆盖Video.js无法播放媒体源时显示的默认信息。
  388. controlBar: {
  389. timeDivider: true, //当前时间和持续时间的分隔符
  390. durationDisplay: true, //显示持续时间
  391. remainingTimeDisplay: false, //是否显示剩余时间功能
  392. fullscreenToggle: true, //全屏按钮
  393. },
  394. },
  395. playerO: {},
  396. dragging: null,
  397. draggingE: null,
  398. };
  399. },
  400. methods: {
  401. handleDragStart(e, items) {
  402. this.dragging = items; //开始拖动时,暂时保存当前拖动的数据。
  403. if (!this.data[items]) {
  404. return;
  405. }
  406. },
  407. handleDragEnd(e, items) {
  408. if (!this.data[this.dragging]) {
  409. return;
  410. }
  411. e.dataTransfer.effectAllowed = "move"; //为需要移动的元素设置dragstart事件
  412. if (this.draggingE == this.dragging) return;
  413. var newItems = [...JSON.parse(JSON.stringify(this.data))]; //拷贝一份数据进行交换操作。
  414. var src = newItems[this.dragging]; //获取数组下标
  415. var dst = newItems[this.draggingE];
  416. // newItems[this.dragging] = dst;
  417. // newItems[this.draggingE] = src;
  418. // // newItems2.splice(dst, 0, ...newItems.splice(src, 1)); //交换位置
  419. // this.data = newItems;
  420. this.data[this.dragging] = dst;
  421. this.data[this.draggingE] = src;
  422. let mindinfo = this.mindInfo2(
  423. this.dragging,
  424. "move",
  425. dst,
  426. "us.mindNetwork",
  427. this.userinfo ? this.userinfo.userid : this.userid,
  428. this.RoomInfo.id,
  429. this.draggingE,
  430. src
  431. );
  432. this.updateSocket(mindinfo);
  433. this.updateRoomData();
  434. this.dragging = null; //拖动结束后,清除数据
  435. this.draggingE = null;
  436. },
  437. handleDragOver(e) {
  438. e.dataTransfer.dropEffect = "move"; //在dragenter中针对放置目标来设置!
  439. },
  440. handleDragEnter(e, items) {
  441. this.draggingE = items;
  442. e.dataTransfer.effectAllowed = "move"; //为需要移动的元素设置dragstart事件
  443. // if (items == this.dragging) return;
  444. // var newItems = [...JSON.parse(JSON.stringify(this.data))]; //拷贝一份数据进行交换操作。
  445. // var src = this.dragging; //获取数组下标
  446. // var dst = items;
  447. // newItems.splice(dst, 0, ...newItems.splice(src, 1)); //交换位置
  448. // this.data = newItems;
  449. // this.updateRoomData();
  450. },
  451. handleDraggableFormItemChange(val) {
  452. // console.log(val);
  453. // console.log(this.data[val.moved.newIndex]);
  454. // console.log(this.data[val.moved.oldIndex]);
  455. },
  456. dragEnd(val) {
  457. // if (this.data[val.newIndex].userid != this.userinfo.userid) {
  458. // this.$message.error("不是您上传的作品不能拖动哦");
  459. // return;
  460. // }
  461. // this.updateRoomData();
  462. },
  463. checkMove(evt) {
  464. // console.log(evt);
  465. // if (evt.draggedContext.element.userid != this.userinfo.userid) {
  466. // return false;
  467. // } else {
  468. // return true;
  469. // }
  470. return false;
  471. },
  472. copy() {
  473. this.copyText =
  474. this.$refs.inviteT.innerHTML +
  475. "\n" +
  476. this.$refs.invite1.innerHTML +
  477. "\n" +
  478. this.$refs.invite2.innerHTML +
  479. "\n" +
  480. this.$refs.invite3.innerText +
  481. "\n" +
  482. this.$refs.invite4.innerHTML;
  483. var clipboard = new Clipboard(".tag-read");
  484. clipboard.on("success", (e) => {
  485. this.$message.success("复制成功");
  486. console.log("复制成功");
  487. clipboard.destroy(); // 释放内存
  488. });
  489. clipboard.on("error", (e) => {
  490. console.log("不支持复制,该浏览器不支持自动复制");
  491. clipboard.destroy(); // 释放内存
  492. });
  493. },
  494. handleClose(done) {
  495. this.restart();
  496. done();
  497. },
  498. handleClose2(done) {
  499. // done();
  500. },
  501. restart() {
  502. this.file = {};
  503. this.gIndex = "";
  504. this.remarks = "";
  505. if (this.$refs.pathClear1) {
  506. this.$refs.pathClear1.value = "";
  507. this.$refs.pathClear2.value = "";
  508. }
  509. },
  510. deleteGrid(index) {
  511. if (this.data[index].userid != this.userid) {
  512. this.$message.error("你不是上传人无权限删除");
  513. return;
  514. }
  515. this.$confirm("确定删除吗?", "提示", {
  516. confirmButtonText: "确定",
  517. cancelButtonText: "取消",
  518. type: "warning",
  519. })
  520. .then(() => {
  521. this.data[index] = "";
  522. let mindinfo = this.mindInfo(
  523. index,
  524. "delete",
  525. this.data[index],
  526. "us.mindNetwork",
  527. this.userinfo ? this.userinfo.userid : this.userid,
  528. this.RoomInfo.id,
  529. ""
  530. );
  531. this.updateSocket(mindinfo);
  532. this.updateRoomData();
  533. this.$forceUpdate();
  534. })
  535. .catch(() => {});
  536. },
  537. updateRoomData() {
  538. let params = [
  539. {
  540. data: JSON.stringify(this.data),
  541. idL: this.RoomInfo.id,
  542. },
  543. ];
  544. this.ajax
  545. .post(this.$store.state.api + "updateRoomData", params)
  546. .then((res) => {})
  547. .catch((err) => {});
  548. },
  549. check(index, type) {
  550. this.gIndex = index;
  551. if (this.data[index].userid != this.userid && type != 2 && type != 3) {
  552. this.$message.error("你不是上传人无权限修改");
  553. return;
  554. }
  555. if (this.data[index] && this.data[index].userid == this.userid) {
  556. if (this.data[index].userid != this.userid) {
  557. this.$message.error("你不是上传人无权限修改");
  558. return;
  559. }
  560. this.file = {
  561. photo: this.data[index].photo,
  562. userid: this.data[index].userid,
  563. video:
  564. this.data[index].video &&
  565. this.data[index].video.sources &&
  566. this.data[index].video.sources[0].src,
  567. };
  568. this.remarks = this.data[index].remarks[0].remarks;
  569. } else if (this.data[index] && type == 2) {
  570. this.file = {
  571. userid: this.data[index].userid,
  572. };
  573. for (var i = 0; i < this.data[index].remarks.length; i++) {
  574. if (this.data[index].remarks[i].userid == this.userid) {
  575. this.remarks = this.data[index].remarks[i].remarks;
  576. break;
  577. }
  578. }
  579. this.remarks = this.remarks ? this.remarks : "";
  580. }
  581. this.dialogVisible = true;
  582. },
  583. addEvent(e) {
  584. var el = e.currentTarget;
  585. el.getElementsByTagName("input")[0].click();
  586. },
  587. deleteFile(type) {
  588. if (type == 1) {
  589. this.file.photo = "";
  590. this.deleteVisible1 = false;
  591. this.$refs.pathClear1.value = "";
  592. } else {
  593. this.file.video = "";
  594. this.deleteVisible2 = false;
  595. this.$refs.pathClear2.value = "";
  596. }
  597. this.$forceUpdate();
  598. },
  599. addGrid() {
  600. if (!this.file.userid || this.file.userid == this.userid) {
  601. if (!this.file.video && !this.file.photo && this.remarks == "") {
  602. this.$message.error("至少上传一个视频、一张图片或者备注");
  603. return;
  604. }
  605. if (!this.data[this.gIndex]) {
  606. this.data[this.gIndex] = {};
  607. }
  608. if (this.file.photo) {
  609. this.data[this.gIndex].photo = this.file.photo;
  610. } else if (this.file.video) {
  611. // this.playerOptions.sources[0].src = ""
  612. var video = JSON.parse(JSON.stringify(this.playerOptions));
  613. video.sources[0].src = this.file.video;
  614. this.data[this.gIndex].video = video;
  615. }
  616. if (this.data[this.gIndex].remarks) {
  617. this.data[this.gIndex].remarks[0] = {
  618. remarks: this.remarks,
  619. userid: this.userinfo ? this.userinfo.userid : this.userid,
  620. username: this.userinfo ? this.userinfo.name : "用户",
  621. };
  622. } else {
  623. this.data[this.gIndex].remarks = [
  624. {
  625. remarks: this.remarks,
  626. userid: this.userinfo ? this.userinfo.userid : this.userid,
  627. username: this.userinfo ? this.userinfo.name : "用户",
  628. },
  629. ];
  630. }
  631. this.data[this.gIndex].userid = this.userinfo
  632. ? this.userinfo.userid
  633. : this.userid;
  634. } else {
  635. if (!this.remarks) {
  636. this.$message.error("备注不能为空");
  637. return;
  638. }
  639. var a = 0;
  640. for (var i = 0; i < this.data[this.gIndex].remarks.length; i++) {
  641. if (this.data[this.gIndex].remarks[i].userid == this.userid) {
  642. a++;
  643. this.data[this.gIndex].remarks[i] = {
  644. remarks: this.remarks,
  645. userid: this.userinfo ? this.userinfo.userid : this.userid,
  646. username: this.userinfo ? this.userinfo.name : "用户",
  647. };
  648. break;
  649. }
  650. }
  651. if (a < 1) {
  652. this.data[this.gIndex].remarks.push({
  653. remarks: this.remarks,
  654. userid: this.userinfo ? this.userinfo.userid : this.userid,
  655. username: this.userinfo ? this.userinfo.name : "用户",
  656. });
  657. }
  658. }
  659. let mindinfo = this.mindInfo(
  660. this.gIndex,
  661. "update",
  662. this.data[this.gIndex],
  663. "us.mindNetwork",
  664. this.userinfo ? this.userinfo.userid : this.userid,
  665. this.RoomInfo.id,
  666. ""
  667. );
  668. this.updateSocket(mindinfo);
  669. this.updateRoomData();
  670. this.dialogVisible = false;
  671. this.$forceUpdate();
  672. this.restart();
  673. },
  674. beforeUpload(event, type) {
  675. // debugger;
  676. if (this.file.photo && type != 1) {
  677. this.$message.error("只能上传一个视频或者一张图片");
  678. this.$refs.pathClear2.value = "";
  679. return;
  680. } else if (this.file.video && type != 2) {
  681. this.$message.error("只能上传一个视频或者一张图片");
  682. this.$refs.pathClear1.value = "";
  683. return;
  684. }
  685. var file = event.target.files[0];
  686. var credentials = {
  687. accessKeyId: "AKIATLPEDU37QV5CHLMH",
  688. secretAccessKey: "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",
  689. }; //秘钥形式的登录上传
  690. window.AWS.config.update(credentials);
  691. window.AWS.config.region = "cn-northwest-1"; //设置区域
  692. var bucket = new window.AWS.S3({ params: { Bucket: "ccrb" } }); //选择桶
  693. var _this = this;
  694. if (type == 1) {
  695. var mediaFormatList = ["png", "jpg", "jpeg"];
  696. if (
  697. mediaFormatList.indexOf(
  698. file.name
  699. .split(".")
  700. [file.name.split(".").length - 1].toLocaleLowerCase()
  701. ) == "-1"
  702. ) {
  703. _this.$message.error("请上传jpg或者png的图片格式文件");
  704. return;
  705. }
  706. } else {
  707. var mediaFormatList = ["mp4"];
  708. if (
  709. mediaFormatList.indexOf(
  710. file.name
  711. .split(".")
  712. [file.name.split(".").length - 1].toLocaleLowerCase()
  713. ) == "-1"
  714. ) {
  715. _this.$message.error("请上传mp4视频格式文件");
  716. return;
  717. }
  718. }
  719. _this.progress = 0;
  720. _this.proVisible = true;
  721. if (file) {
  722. var params = {
  723. Key:
  724. file.name.split(".")[0] +
  725. new Date().getTime() +
  726. "." +
  727. file.name.split(".")[1],
  728. ContentType: file.type,
  729. Body: file,
  730. "Access-Control-Allow-Credentials": "*",
  731. ACL: "public-read",
  732. }; //key可以设置为桶的相抵路径,Body为文件, ACL最好要设置
  733. var options = {
  734. partSize: 2048 * 1024 * 1024,
  735. queueSize: 2,
  736. leavePartsOnError: true,
  737. };
  738. bucket
  739. .upload(params, options)
  740. .on("httpUploadProgress", function (evt) {
  741. //这里可以写进度条
  742. // console.log("Uploaded : " + parseInt((evt.loaded * 80) / evt.total) + '%');
  743. _this.progress = parseInt((evt.loaded * 80) / evt.total);
  744. })
  745. .send(function (err, data) {
  746. this.progress = 100;
  747. setTimeout(() => {
  748. _this.proVisible = false;
  749. }, 1000);
  750. if (err) {
  751. _this.$message.error("上传失败");
  752. } else {
  753. if (type == 1) {
  754. _this.file.photo = data.Location;
  755. } else {
  756. _this.file.video = data.Location;
  757. }
  758. _this.$forceUpdate();
  759. console.log(data.Location);
  760. }
  761. });
  762. }
  763. },
  764. getUser() {
  765. let params = { uid: this.userid };
  766. this.ajax
  767. .get(this.$store.state.api + "getUser", params)
  768. .then((res) => {
  769. this.userinfo = res.data[0][0];
  770. if(this.goNum != ""){
  771. this.goRoom(this.goNum);
  772. }else{
  773. this.checkNum();
  774. }
  775. console.log(res.data[0][0]);
  776. })
  777. .catch((err) => {
  778. console.error(err);
  779. });
  780. },
  781. MathRand() {
  782. var Num = "";
  783. for (var i = 0; i < 6; i++) {
  784. Num += Math.floor(Math.random() * 10);
  785. }
  786. return Num;
  787. },
  788. checkNum() {
  789. this.numNum = this.MathRand();
  790. this.goNum = this.numNum;
  791. let params = {
  792. num: this.numNum,
  793. };
  794. this.ajax
  795. .get(this.$store.state.api + "checkRoomNum", params)
  796. .then((res) => {
  797. console.log(res.data[0].length);
  798. if (res.data[0].length) {
  799. this.checkNum();
  800. } else {
  801. this.addRoom();
  802. }
  803. })
  804. .catch((err) => {
  805. console.error(err);
  806. });
  807. },
  808. addRoom() {
  809. let params = [
  810. {
  811. uid: this.userid,
  812. n: this.numNum,
  813. d: JSON.stringify(this.data),
  814. },
  815. ];
  816. this.ajax
  817. .post(this.$store.state.api + "insertRoom", params)
  818. .then((res) => {
  819. this.$message.success("创建成功");
  820. this.getRoom(res.data[0][0].fid);
  821. })
  822. .catch((err) => {
  823. this.$message.error("创建失败");
  824. console.error(err);
  825. });
  826. },
  827. getRoom(fid) {
  828. let params = {
  829. fid: fid,
  830. };
  831. this.ajax
  832. .get(this.$store.state.api + "getRoom", params)
  833. .then((res) => {
  834. if (res.data[0].length) {
  835. // this.RoomInfo = res.data[0][0];
  836. this.data = JSON.parse(res.data[0][0].data);
  837. this.dialogVisible3 = false;
  838. this.dialogVisible2 = true;
  839. // this.getMindNetwork(res.data[0][0].id, this.userinfo.userid);
  840. // this.data.splice(0,1)
  841. // this.updateRoomData()
  842. // this.timer = setInterval(() => {
  843. // this.selectRoom2(uid);
  844. // }, 5000);
  845. } else {
  846. // this.$message.error("此房间不存在或已被解散");
  847. }
  848. })
  849. .catch((err) => {
  850. console.error(err);
  851. });
  852. },
  853. selectRoom(uid) {
  854. let params = {
  855. uid: uid,
  856. };
  857. this.ajax
  858. .get(this.$store.state.api + "selectRoom", params)
  859. .then((res) => {
  860. if (res.data[0].length) {
  861. // this.RoomInfo = res.data[0][0];
  862. // this.data = JSON.parse(res.data[0][0].data);
  863. // this.dialogVisible3 = false;
  864. // this.dialogVisible2 = true;
  865. this.getMindNetwork(res.data[0][0].id, this.userinfo.userid);
  866. // this.data.splice(0,1)
  867. // this.updateRoomData()
  868. // this.timer = setInterval(() => {
  869. // this.selectRoom2(uid);
  870. // }, 5000);
  871. } else {
  872. // this.$message.error("此房间不存在或已被解散");
  873. }
  874. })
  875. .catch((err) => {
  876. console.error(err);
  877. });
  878. },
  879. goRoom(uid) {
  880. let params = {
  881. uid: uid,
  882. };
  883. this.ajax
  884. .get(this.$store.state.api + "selectRoom", params)
  885. .then((res) => {
  886. if (res.data[0].length) {
  887. this.$message.success("加入成功");
  888. // this.RoomInfo = res.data[0][0];
  889. this.data = JSON.parse(res.data[0][0].data);
  890. this.dialogVisible3 = false;
  891. this.dialogVisible2 = true;
  892. // this.getMindNetwork(res.data[0][0].id, this.userinfo.userid);
  893. // this.timer = setInterval(() => {
  894. // this.selectRoom2(uid);
  895. // }, 5000);
  896. } else {
  897. this.$message.error("此房间不存在或已被解散");
  898. }
  899. })
  900. .catch((err) => {
  901. console.error(err);
  902. });
  903. },
  904. selectRoom2(uid) {
  905. let params = {
  906. uid: uid,
  907. };
  908. this.ajax
  909. .get(this.$store.state.api + "selectRoom", params)
  910. .then((res) => {
  911. this.RoomInfo = res.data[0][0];
  912. this.data = JSON.parse(res.data[0][0].data);
  913. })
  914. .catch((err) => {
  915. console.error(err);
  916. });
  917. },
  918. dismiss() {
  919. this.$confirm("确定解散房间吗?", "提示", {
  920. confirmButtonText: "确定",
  921. cancelButtonText: "取消",
  922. type: "warning",
  923. })
  924. .then(() => {
  925. let params = [
  926. {
  927. id: this.RoomInfo.id,
  928. },
  929. ];
  930. this.ajax
  931. .post(this.$store.state.api + "dismiss", params)
  932. .then((res) => {
  933. this.$message.success("解散成功");
  934. this.$router.go(0);
  935. })
  936. .catch((err) => {
  937. console.error(err);
  938. });
  939. })
  940. .catch(() => {});
  941. },
  942. /*
  943. * mind 消息类
  944. * 参数一 : 第几个网格
  945. * 参数二 : type 操作类型
  946. * 参数三 : content 行内容
  947. * 参数四 : next 下一行
  948. */
  949. // messageInfo: {
  950. // sendId: userid,
  951. // moveIndex1: id, //第几个网格
  952. // moveIndex2: moveIndex, //移动到的网格
  953. // type: type, //类型
  954. // data: content, //内容
  955. // docId: roomid, //文档id
  956. // // pageId: US.pageId, //当前页面id
  957. // },
  958. mindInfo(id, type, content, navid, userid, roomid, moveIndex) {
  959. var _data = {
  960. "us.mindNetwork": [
  961. {
  962. sendId: userid, //发送人id
  963. receiveId: roomid, //文件id
  964. type: navid, //消息类型
  965. messageInfo: {
  966. id: id, //操作ID
  967. type: type, //类型
  968. content: content, //内容
  969. docId: roomid, //文档id
  970. pageId: top.US.pageId, //当前页面id
  971. },
  972. },
  973. ],
  974. };
  975. return _data;
  976. },
  977. mindInfo2(id, type, content, navid, userid, roomid, moveIndex, moveData) {
  978. var _data = {
  979. "us.mindNetwork": [
  980. {
  981. sendId: userid, //发送人id
  982. receiveId: roomid, //文件id
  983. type: navid, //消息类型
  984. messageInfo: {
  985. id: id, //操作ID
  986. type: type, //类型
  987. content: content, //内容
  988. docId: roomid, //文档id
  989. pageId: top.US.pageId, //当前页面id
  990. },
  991. },
  992. {
  993. sendId: userid, //发送人id
  994. receiveId: roomid, //文件id
  995. type: navid, //消息类型
  996. messageInfo: {
  997. id: moveIndex, //操作ID
  998. type: type, //类型
  999. content: moveData, //内容
  1000. docId: roomid, //文档id
  1001. pageId: top.US.pageId, //当前页面id
  1002. },
  1003. },
  1004. ],
  1005. };
  1006. return _data;
  1007. },
  1008. updateSocket(mindinfo) {
  1009. let params = [
  1010. {
  1011. type: "send",
  1012. mindinfo: encodeURIComponent(
  1013. encodeURIComponent(JSON.stringify(mindinfo))
  1014. ),
  1015. post: 1,
  1016. },
  1017. ];
  1018. this.ajax
  1019. .post(this.$store.state.socket, params)
  1020. .then((res) => {
  1021. console.log(res);
  1022. })
  1023. .catch((err) => {
  1024. console.error(err);
  1025. });
  1026. },
  1027. getMindNetwork(id, uid) {
  1028. let params = [
  1029. {
  1030. type: "getMindNetwork",
  1031. docid: id,
  1032. pageid: window.parent.US.pageId,
  1033. userid: uid,
  1034. post: "1",
  1035. },
  1036. ];
  1037. this.ajax
  1038. .post(this.$store.state.socket, params)
  1039. .then((res) => {
  1040. if (res.data[0].length) {
  1041. this.RoomInfo = res.data[0][0];
  1042. try {
  1043. this.data = JSON.parse(res.data[0][0].data);
  1044. } catch (error) {
  1045. this.data = res.data[0][0].data;
  1046. }
  1047. this.dialogVisible3 = false;
  1048. this.dialogVisible2 = true;
  1049. }
  1050. console.log(res);
  1051. })
  1052. .catch((err) => {
  1053. console.error(err);
  1054. });
  1055. },
  1056. },
  1057. beforeDestroy() {
  1058. // clearInterval(this.timer);
  1059. window.removeEventListener("message");
  1060. },
  1061. created() {
  1062. document.domain = "cocorobo.cn";
  1063. // window.parent.postMessage({ cid: cid, type: "U.MD.O.P.pollingAsyn" }, "*");
  1064. for (var i = 0; i < 16; i++) {
  1065. this.data.push("");
  1066. }
  1067. this.getUser();
  1068. let _this = this;
  1069. window.addEventListener("message", function (e) {
  1070. // 监听 message 事件
  1071. if (
  1072. e.data.type &&
  1073. e.data.type == "mindNetwork_update" &&
  1074. e.data.info.docId == _this.RoomInfo.id &&
  1075. !(e.data.sendId == _this.userinfo.userid)
  1076. ) {
  1077. _this.data[e.data.info.id] = e.data.info.content;
  1078. } else if (
  1079. e.data.type &&
  1080. e.data.type == "mindNetwork_delete" &&
  1081. e.data.info.docId == _this.RoomInfo.id &&
  1082. !(e.data.sendId == _this.userinfo.userid)
  1083. ) {
  1084. _this.data[e.data.info.id] = "";
  1085. } else if (
  1086. e.data.type &&
  1087. e.data.type == "mindNetwork_move" &&
  1088. e.data.info.docId == _this.RoomInfo.id &&
  1089. !(e.data.sendId == _this.userinfo.userid)
  1090. ) {
  1091. _this.data[e.data.info.id] = e.data.info.content;
  1092. // var newItems = [...JSON.parse(JSON.stringify(_this.data))]; //拷贝一份数据进行交换操作。
  1093. // _this.data[e.data.info.id] = newItems[e.data.info.moveIndex2];
  1094. // _this.data[e.data.info.moveIndex2] = newItems[e.data.info.moveIndex1];
  1095. }
  1096. _this.$forceUpdate();
  1097. });
  1098. },
  1099. };
  1100. </script>
  1101. <style scoped>
  1102. .g_body {
  1103. width: 100%;
  1104. height: 100%;
  1105. background: #fff;
  1106. border-radius: 5px;
  1107. display: flex;
  1108. align-items: center;
  1109. justify-content: center;
  1110. flex-wrap: wrap;
  1111. position: relative;
  1112. min-height: 750px;
  1113. }
  1114. .coin {
  1115. position: absolute;
  1116. width: 50px;
  1117. z-index: 1;
  1118. user-select: none;
  1119. }
  1120. .coin1 {
  1121. top: 10px;
  1122. left: 20px;
  1123. }
  1124. .coin2 {
  1125. top: 10px;
  1126. right: 20px;
  1127. }
  1128. .coin3 {
  1129. bottom: 10px;
  1130. left: 20px;
  1131. }
  1132. .coin4 {
  1133. bottom: 10px;
  1134. right: 20px;
  1135. }
  1136. .g_box {
  1137. background: rgb(227 228 232);
  1138. width: calc(100% / 4 - 15px);
  1139. height: calc(100% / 4 - 15px);
  1140. margin: 5px;
  1141. border-radius: 5px;
  1142. cursor: pointer;
  1143. display: flex;
  1144. align-items: center;
  1145. justify-content: center;
  1146. /* overflow: hidden; */
  1147. position: relative;
  1148. user-select: none;
  1149. }
  1150. .photo_img {
  1151. width: 100%;
  1152. height: 100%;
  1153. border-radius: 5px;
  1154. }
  1155. .g_box .add_img {
  1156. width: 100px;
  1157. display: none;
  1158. }
  1159. .g_box:hover .add_img {
  1160. display: block;
  1161. }
  1162. .look_notice >>> .el-dialog__header {
  1163. padding: 10px 20px;
  1164. text-align: center;
  1165. background: #32455b;
  1166. }
  1167. .look_notice >>> .el-dialog__title {
  1168. font-size: 14px !important;
  1169. color: #fff !important;
  1170. }
  1171. .look_notice >>> .el-dialog__headerbtn {
  1172. font-size: 20px !important;
  1173. top: 10px;
  1174. }
  1175. .look_notice >>> .el-form-item__label {
  1176. margin-left: 65px;
  1177. }
  1178. .look_notice >>> .el-form-item {
  1179. display: flex;
  1180. }
  1181. .look_notice >>> .el-form-item__content {
  1182. margin: 0 !important;
  1183. }
  1184. .look_notice >>> .el-dialog__footer {
  1185. text-align: center !important;
  1186. }
  1187. .look_notice >>> .el-dialog {
  1188. min-width: 450px;
  1189. background: #f3f3f3;
  1190. }
  1191. .notice_content {
  1192. width: 100%;
  1193. word-wrap: break-word;
  1194. word-break: break-all;
  1195. overflow: hidden;
  1196. font-size: 18px;
  1197. line-height: 35px;
  1198. text-indent: 35px;
  1199. min-width: 385px;
  1200. }
  1201. .roomBtn {
  1202. background: rgb(112 183 79);
  1203. /* padding: 0 !important; */
  1204. border: none;
  1205. }
  1206. .close {
  1207. width: 150px;
  1208. height: 40px;
  1209. border-radius: 30px;
  1210. line-height: 30px;
  1211. font-size: 14px;
  1212. background: rgb(112 183 79);
  1213. padding: 0 !important;
  1214. border: none;
  1215. }
  1216. .header-title {
  1217. display: flex;
  1218. }
  1219. .logoImg {
  1220. width: 30px;
  1221. }
  1222. .logoImg > img {
  1223. width: 100%;
  1224. height: 100%;
  1225. }
  1226. .title_add_student {
  1227. /* margin: 0 auto; */
  1228. color: #fff;
  1229. }
  1230. .grid_member {
  1231. position: absolute;
  1232. background: #fff;
  1233. right: 70px;
  1234. top: 18px;
  1235. /* min-width: 320px; */
  1236. height: 50px;
  1237. border-radius: 5px;
  1238. padding: 0 10px;
  1239. display: flex;
  1240. align-items: center;
  1241. z-index: 1;
  1242. user-select: none;
  1243. }
  1244. .member_imgbox {
  1245. display: flex;
  1246. align-items: center;
  1247. margin: 0 10px;
  1248. width: 185px;
  1249. }
  1250. .member_img {
  1251. height: 40px;
  1252. width: 40px;
  1253. border-radius: 50px;
  1254. overflow: hidden;
  1255. display: block;
  1256. background: aliceblue;
  1257. }
  1258. .member_img + .member_img {
  1259. margin-left: 8px;
  1260. }
  1261. .upload_box {
  1262. border-radius: 5px;
  1263. background: #fff;
  1264. position: relative;
  1265. }
  1266. .upload_box .list_img {
  1267. position: absolute;
  1268. top: 10px;
  1269. left: 10px;
  1270. }
  1271. .upload_box .upload_content {
  1272. display: flex;
  1273. align-items: center;
  1274. justify-content: center;
  1275. padding: 50px 0 20px;
  1276. }
  1277. .upload_box .upload_content div {
  1278. display: flex;
  1279. align-items: center;
  1280. justify-content: center;
  1281. cursor: pointer;
  1282. position: relative;
  1283. }
  1284. .delete_img {
  1285. position: absolute !important;
  1286. width: 25px;
  1287. transform: translate(50%, -50%);
  1288. top: 0;
  1289. z-index: 1;
  1290. right: 0;
  1291. }
  1292. .upload_img {
  1293. width: 306px;
  1294. height: 206px;
  1295. }
  1296. .textarea_box {
  1297. background: #fff;
  1298. margin-top: 20px;
  1299. display: flex;
  1300. flex-direction: column;
  1301. align-items: center;
  1302. padding: 20px 0;
  1303. }
  1304. .textarea_title {
  1305. width: 95%;
  1306. margin: 0 auto;
  1307. font-size: 16px;
  1308. }
  1309. .textarea_content {
  1310. width: 95%;
  1311. margin: 10px auto 0;
  1312. border-radius: 10px;
  1313. }
  1314. .textarea_content >>> .el-textarea__inner {
  1315. background: rgb(243, 243, 243);
  1316. border: none;
  1317. }
  1318. .invite_dialog >>> .el-dialog__body {
  1319. padding: 15px 20px;
  1320. }
  1321. .room_dialog >>> .el-dialog {
  1322. margin-top: 50vh !important;
  1323. transform: translateY(-50%);
  1324. min-width: unset;
  1325. }
  1326. .invite_box {
  1327. font-size: 16px;
  1328. background: #fff;
  1329. border-radius: 5px;
  1330. padding: 30px 0 150px;
  1331. }
  1332. .invite_title {
  1333. width: 90%;
  1334. margin: 0 auto 20px;
  1335. }
  1336. .line {
  1337. width: 95%;
  1338. border-top: 1px solid rgb(230, 230, 230);
  1339. margin: 0 auto;
  1340. }
  1341. .invite_link {
  1342. width: 90%;
  1343. margin: 20px auto 30px;
  1344. }
  1345. .invite_link div + div {
  1346. margin-top: 15px;
  1347. }
  1348. .invite_num {
  1349. width: 90%;
  1350. margin: 0 auto 50px;
  1351. }
  1352. .invite_num span {
  1353. color: rgb(112 183 79);
  1354. font-size: 28px;
  1355. }
  1356. .addRoom_box {
  1357. background: #fff;
  1358. padding: 30px 20px;
  1359. border-radius: 5px;
  1360. }
  1361. .room_b {
  1362. margin: 5px 0 30px;
  1363. /* width:300px; */
  1364. }
  1365. .room_btn {
  1366. display: flex;
  1367. justify-content: space-around;
  1368. }
  1369. .mask {
  1370. background-color: rgba(0, 0, 0, 0);
  1371. position: fixed;
  1372. top: 0;
  1373. left: 0;
  1374. width: 100%;
  1375. height: 100%;
  1376. z-index: 20000;
  1377. display: flex;
  1378. align-items: center;
  1379. justify-content: center;
  1380. }
  1381. .progressBox {
  1382. width: 500px;
  1383. height: 180px;
  1384. background: #fff;
  1385. border-radius: 10px;
  1386. box-shadow: 0 0 6px 1px #bfbfbf;
  1387. display: flex;
  1388. align-items: center;
  1389. justify-content: center;
  1390. flex-direction: column;
  1391. }
  1392. .progressBox .lbox {
  1393. height: 100px;
  1394. font-size: 19px;
  1395. display: flex;
  1396. align-items: center;
  1397. }
  1398. .progressBox .lbox img {
  1399. width: 40px;
  1400. margin-right: 20px;
  1401. }
  1402. .progressBox >>> .el-progress-bar__outer {
  1403. background-color: #d1dfff !important;
  1404. }
  1405. .top-popover {
  1406. position: absolute;
  1407. top: -50px;
  1408. left: 0;
  1409. background: #fff;
  1410. display: flex;
  1411. height: 45px;
  1412. align-items: center;
  1413. padding: 0px 10px 0 20px;
  1414. border-radius: 5px;
  1415. box-shadow: 0 1px 3px 1px rgb(202, 202, 202);
  1416. z-index: 10;
  1417. transition: 0.5s all;
  1418. opacity: 0;
  1419. visibility: hidden;
  1420. }
  1421. .top-popover .pChild {
  1422. display: flex;
  1423. align-items: center;
  1424. }
  1425. .top-popover .pChild + .pChild {
  1426. margin-left: 10px;
  1427. }
  1428. .left-popover {
  1429. position: absolute;
  1430. top: 0px;
  1431. right: -65px;
  1432. background: #fff;
  1433. display: flex;
  1434. width: 45px;
  1435. align-items: center;
  1436. padding: 10px 5px 20px;
  1437. border-radius: 5px;
  1438. box-shadow: 0 1px 3px 1px rgb(202, 202, 202);
  1439. z-index: 10;
  1440. flex-direction: column;
  1441. justify-content: center;
  1442. transition: 0.5s all;
  1443. opacity: 0;
  1444. visibility: hidden;
  1445. }
  1446. .left-popover .pChild {
  1447. display: flex;
  1448. align-items: center;
  1449. flex-direction: column;
  1450. }
  1451. .left-popover .pChild span {
  1452. display: flex;
  1453. align-items: center;
  1454. flex-direction: column;
  1455. text-align: center;
  1456. }
  1457. .left-popover .pChild + .pChild {
  1458. margin-top: 10px;
  1459. }
  1460. .right-popover {
  1461. position: absolute;
  1462. top: 0px;
  1463. left: -65px;
  1464. background: #fff;
  1465. display: flex;
  1466. width: 45px;
  1467. align-items: center;
  1468. padding: 10px 5px 20px;
  1469. border-radius: 5px;
  1470. box-shadow: 0 1px 3px 1px rgb(202, 202, 202);
  1471. z-index: 10;
  1472. flex-direction: column;
  1473. justify-content: center;
  1474. transition: 0.5s all;
  1475. opacity: 0;
  1476. visibility: hidden;
  1477. }
  1478. .right-popover .pChild {
  1479. display: flex;
  1480. align-items: center;
  1481. flex-direction: column;
  1482. }
  1483. .right-popover .pChild span {
  1484. display: flex;
  1485. align-items: center;
  1486. flex-direction: column;
  1487. text-align: center;
  1488. }
  1489. .right-popover .pChild + .pChild {
  1490. margin-top: 10px;
  1491. }
  1492. .visibleO {
  1493. opacity: 1 !important;
  1494. visibility: visible !important;
  1495. }
  1496. .remark-bottom-popover {
  1497. position: absolute;
  1498. bottom: 0px;
  1499. left: 0;
  1500. background: #fff;
  1501. max-height: 150px;
  1502. width: 100%;
  1503. padding: 10px 20px;
  1504. border-radius: 5px;
  1505. box-shadow: 0 1px 3px 1px rgb(202, 202, 202);
  1506. z-index: 10;
  1507. transition: 0.5s all;
  1508. box-sizing: border-box;
  1509. transform: translateY(calc(100% + 5px));
  1510. overflow: auto;
  1511. opacity: 0;
  1512. visibility: hidden;
  1513. }
  1514. .Rbox {
  1515. display: flex;
  1516. word-break: break-all;
  1517. }
  1518. .Rbox + .Rbox {
  1519. border-top: 1px solid rgb(233, 233, 233);
  1520. margin-top: 10px;
  1521. padding-top: 10px;
  1522. }
  1523. .Rportal {
  1524. height: 45px;
  1525. min-width: 45px;
  1526. border-radius: 50px;
  1527. overflow: hidden;
  1528. display: block;
  1529. background: aliceblue;
  1530. user-select: none;
  1531. }
  1532. .RContent {
  1533. margin-left: 10px;
  1534. }
  1535. .RContent div:nth-child(1) {
  1536. user-select: none;
  1537. color: rgb(80, 80, 80);
  1538. margin-bottom: 5px;
  1539. font-size: 14px;
  1540. }
  1541. .RContent div:nth-child(2) {
  1542. font-family: "微软雅黑";
  1543. font-size: 15px;
  1544. }
  1545. .remark-right-popover {
  1546. position: absolute;
  1547. top: 0;
  1548. right: 0;
  1549. background: #fff;
  1550. max-height: 100%;
  1551. width: 300px;
  1552. padding: 10px 20px;
  1553. border-radius: 5px;
  1554. box-shadow: 0 1px 3px 1px rgb(202, 202, 202);
  1555. z-index: 10;
  1556. transition: 0.5s all;
  1557. box-sizing: border-box;
  1558. transform: translateX(calc(100% + 5px));
  1559. overflow: auto;
  1560. opacity: 0;
  1561. visibility: hidden;
  1562. }
  1563. .remark-left-popover {
  1564. position: absolute;
  1565. top: 0;
  1566. left: 0;
  1567. background: #fff;
  1568. max-height: 100%;
  1569. width: 300px;
  1570. padding: 10px 20px;
  1571. border-radius: 5px;
  1572. box-shadow: 0 1px 3px 1px rgb(202, 202, 202);
  1573. z-index: 10;
  1574. transition: 0.5s all;
  1575. box-sizing: border-box;
  1576. transform: translateX(calc(-100% - 5px));
  1577. overflow: auto;
  1578. opacity: 0;
  1579. visibility: hidden;
  1580. }
  1581. .rrrrbox {
  1582. width: 95%;
  1583. height: 95%;
  1584. background: #fff;
  1585. padding: 10px 20px;
  1586. box-sizing: border-box;
  1587. border-radius: 5px;
  1588. position: absolute;
  1589. z-index: 9;
  1590. overflow: auto;
  1591. }
  1592. </style>