pk.vue 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725
  1. <template>
  2. <div class="pages">
  3. <Headside></Headside>
  4. <div class="pageTitle">
  5. </div>
  6. <div class="progressContainer">
  7. <div class="valueDisplay">
  8. <div class="lt">
  9. <span :style="{'right': Redflag+'%'}">
  10. <em>CK {{ redSum }}</em>
  11. </span>
  12. </div>
  13. <div class="rt">
  14. <span :style="{'left': BlueFlag+'%'}">
  15. <em>CK {{ blueSum }}</em>
  16. </span>
  17. </div>
  18. <div class="md">
  19. <img src="../assets/imgs/pk/vs.png" alt="">
  20. </div>
  21. </div>
  22. <div class="lineContianer">
  23. <div class="lt">
  24. <span :style="{'width':RedProgress+'%'}">
  25. </span>
  26. <em>红队{{ redPeron }}人</em>
  27. </div>
  28. <div class="rt">
  29. <span :style="{'width':BlueProgress+'%'}">
  30. </span>
  31. <em>蓝队{{ bluePerson }}人</em>
  32. </div>
  33. </div>
  34. </div>
  35. <div class="userPart">
  36. <div class="lt">
  37. <pkstudent :students="students.redUnite"></pkstudent>
  38. <div class="bottomLine redBottom"></div>
  39. </div>
  40. <div class="md">
  41. {{ classInfo.endTime }}
  42. </div>
  43. <div class="rt">
  44. <pkstudent :students="students.blueUnite"></pkstudent>
  45. <div class="bottomLine blueBottom"></div>
  46. </div>
  47. </div>
  48. <div class="icons">
  49. <img src="../assets/imgs/pk/icons2.svg" alt="">
  50. </div>
  51. <!-- 突破纪录-->
  52. <newRecord :toper-info="toperInfo"></newRecord>
  53. <!-- 欢迎新同学-->
  54. <newStudent :student-info="studentInfo"></newStudent>
  55. </div>
  56. </template>
  57. <script>
  58. import '../libs/rem';
  59. import Headside from '@/components/Headside'
  60. import newRecord from '@/components/newRecord'
  61. import newStudent from '@/components/newStudent'
  62. import pkstudent from '@/components/pkstudent'
  63. import
  64. {
  65. getHello,
  66. getClassStat,
  67. getRecordBreak,
  68. getNewUser
  69. } from '@/api/getApiRes'
  70. import '../Global'
  71. let qs = require('qs');
  72. export default {
  73. data() {
  74. return {
  75. ClassOn: 1,
  76. trueDate: true,//真实数据 true false
  77. studentsClassName: [
  78. {name: 'max'}
  79. ],
  80. students: {
  81. redUnite: [],
  82. blueUnite: [],
  83. },
  84. thisClassName: '',
  85. redSum: 0,
  86. blueSum: 0,
  87. redPeron: 0,
  88. bluePerson: 0,
  89. pkVal: '50%',
  90. RedstudentsClassName: [
  91. {name: 'max'}
  92. ],
  93. BluestudentsClassName: [
  94. {name: 'max'}
  95. ],
  96. PlanName: '',
  97. num: 0,
  98. Teacher: '',
  99. classInfo: {
  100. name: '竞技课程',
  101. num: '0',
  102. btTime: '2020-11-13 09:00:00',//时间戳
  103. endTime: '00:00:00',
  104. redSum: 0,
  105. blueSum: 0,
  106. },
  107. // totalTime: 30,
  108. // studentTime: 15,
  109. toperInfo: {
  110. dialogVisible: false,
  111. toper: {},
  112. totalTime: 30,
  113. },
  114. studentInfo: {
  115. dialogVisible: false,
  116. Rs: [],
  117. percent: 0,
  118. studentTime: 15
  119. },
  120. Redflag: 0,
  121. BlueFlag: 0,
  122. RedProgress: 25,
  123. BlueProgress: 25,
  124. }
  125. },
  126. mounted() {
  127. this.init();
  128. },
  129. watch: {
  130. '$route': function (val) {
  131. let that = this;
  132. if (val.path == '/pk') {
  133. this.init();
  134. } else {
  135. clearInterval(this.PkTimer);
  136. // clearInterval(this.PkEgg);
  137. clearInterval(this.timer2);
  138. clearInterval(this.timer3);
  139. this.PkTimer = null;
  140. // this.PkEgg = null;
  141. this.timer2 = null;
  142. this.timer3 = null;
  143. }
  144. }
  145. },
  146. beforeDestroy() {
  147. clearInterval(this.PkTimer);
  148. // clearInterval(this.PkEgg);
  149. clearInterval(this.timer2);
  150. clearInterval(this.timer3);
  151. this.PkTimer = null;
  152. // this.PkEgg = null;
  153. this.timer2 = null;
  154. this.timer3 = null;
  155. },
  156. methods: {
  157. init() {
  158. this.GetgetUserList();
  159. this.createEgg();
  160. this.createNewStudent();
  161. this.PkTimer = setInterval(() => {
  162. this.GetgetUserList();
  163. this.ClacClassTime();
  164. this.curgetClassStat();
  165. }, 1000);
  166. this.timer2 = setInterval(() => {
  167. this.createEgg();
  168. }, 25000);
  169. this.timer3 = setInterval(() => {
  170. this.createNewStudent();
  171. }, 20000);
  172. },
  173. // 启动一个成就彩蛋
  174. createEgg() {
  175. let that = this;
  176. let param = {
  177. token: localStorage.token,
  178. eqSn: localStorage.eqSn
  179. };
  180. let postdata = qs.stringify(param);
  181. getRecordBreak(postdata).then(res => {
  182. let json = res;
  183. if (json.Code == 0) {
  184. console.log('破纪录了');
  185. that.OpenEgg(json.Rs);
  186. } else {
  187. // 并没有人破记录
  188. if (json.Code == 999) return false;
  189. if (json.Code != 999) that.$message.error(json.Memo + '[ 错误码]' + json.Code);
  190. }
  191. })
  192. },
  193. // 欢迎新同学
  194. createNewStudent() {
  195. let that = this;
  196. let param = {
  197. token: localStorage.token,
  198. eqSn: localStorage.eqSn
  199. };
  200. let postdata = qs.stringify(param);
  201. getNewUser(postdata).then(res => {
  202. let json = res;
  203. if (json.Code == 0) {
  204. console.log('来新生了');
  205. that.OpenStudent(json.Rs);
  206. } else {
  207. // 并没有人破记录
  208. if (json.Code == 999) return false;
  209. if (json.Code != 999) that.$message.error(json.Memo + '[ 错误码]' + json.Code);
  210. }
  211. })
  212. },
  213. OpenEgg(msg, reshowNum=0) {
  214. let that = this;
  215. if (that.ClassOn == 0) {
  216. console.log('[破纪录] 已下课,取消弹窗 reshowNum: ' + reshowNum);
  217. return false;
  218. }
  219. if (that.studentInfo.dialogVisible == true || that.toperInfo.dialogVisible == true) {
  220. console.log('[破纪录] 弹出窗口尚未关闭,5秒后重试');
  221. setTimeout(() => {
  222. reshowNum++;
  223. that.OpenEgg(msg, reshowNum);
  224. }, 5000);
  225. return false;
  226. }
  227. if (reshowNum > 0) {
  228. console.log('[破纪录] reshowNum: ' + reshowNum);
  229. }
  230. that.toperInfo.toper = msg;
  231. that.toperInfo.dialogVisible = true;
  232. // 倒计时20秒自动关闭
  233. that.toperInfo.totalTime = 20;
  234. let clock = window.setInterval(() => {
  235. that.toperInfo.totalTime--;
  236. if (parseInt(that.toperInfo.totalTime) <= 0) {
  237. that.toperInfo.dialogVisible = false;// 关闭 自动关闭彩蛋
  238. clearInterval(clock);
  239. }
  240. }, 1000)
  241. },
  242. OpenStudent(msg, reshowNum=0) {
  243. let that = this;
  244. if (that.ClassOn == 0) {
  245. console.log('[欢迎新同学] 已下课,取消弹窗 reshowNum: ' + reshowNum);
  246. return false;
  247. }
  248. if (that.studentInfo.dialogVisible == true || that.toperInfo.dialogVisible == true) {
  249. console.log('[欢迎新同学] 弹出窗口尚未关闭,5秒后重试');
  250. setTimeout(() => {
  251. reshowNum++;
  252. that.OpenStudent(msg, reshowNum);
  253. }, 5000);
  254. return false;
  255. }
  256. if (reshowNum > 0) {
  257. console.log('[欢迎新同学] reshowNum: ' + reshowNum);
  258. }
  259. that.studentInfo.Rs = msg;
  260. that.studentInfo.dialogVisible = true;
  261. // 倒计时15秒自动关闭
  262. that.studentInfo.studentTime = 15;
  263. let clock = window.setInterval(() => {
  264. that.studentInfo.studentTime--;
  265. if (parseInt(that.studentInfo.studentTime) <= 0) {
  266. that.studentInfo.dialogVisible = false; //关闭 自动关闭
  267. clearInterval(clock);
  268. }
  269. }, 1000)
  270. },
  271. // 载入课程信息
  272. ReadLessonInfo(Dp) {
  273. this.PlanName = Dp.PlanName;
  274. this.BeginTime = Dp.BeginTime;
  275. this.Teacher = Dp.Teacher;
  276. },
  277. // 分队展示
  278. UniteBreak(Rs) {
  279. let that = this;
  280. that.students.redUnite = [];
  281. that.students.blueUnite = [];
  282. if (!Rs) {
  283. that.students.redUnite = [];
  284. that.students.blueUnite = [];
  285. } else {
  286. Rs.map(function (item, t) {
  287. item.sportLevel = sportLevel(item.ActivePercent);
  288. if (item.GroupNo == 1) {
  289. that.students.redUnite.push(item);
  290. }
  291. if (item.GroupNo == 2) {
  292. that.students.blueUnite.push(item);
  293. }
  294. })
  295. }
  296. that.giveClassName(that.students.redUnite, 1);
  297. that.giveClassName(that.students.blueUnite, 2);
  298. that.calcSumCK(that.students);
  299. },
  300. // 计算各队总分
  301. calcSumCK(Rs) {
  302. let that = this;
  303. let redSum = 0;
  304. let blueSum = 0;
  305. // that.redSum
  306. Rs.redUnite.map(function (item, t) {
  307. redSum += parseFloat(item.Ck.toFixed(1));
  308. });
  309. Rs.blueUnite.map(function (item, t) {
  310. blueSum += parseFloat(item.Ck.toFixed(1));
  311. });
  312. that.redSum = redSum.toFixed(1);
  313. that.blueSum = blueSum.toFixed(1);
  314. // 进度条 FormatCk
  315. let redFmtSum = 0;
  316. let blueFmtSum = 0;
  317. let pkval = 0;
  318. Rs.redUnite.map(function (item, t) {
  319. redFmtSum += parseFloat(item.FormatCk);
  320. });
  321. Rs.blueUnite.map(function (item, t) {
  322. blueFmtSum += parseFloat(item.FormatCk);
  323. });
  324. let sumMax = 0;
  325. if (Rs.redUnite) {
  326. sumMax = (Rs.redUnite.length + Rs.blueUnite.length) * 1000;
  327. }
  328. // 当为0时均分
  329. if (redFmtSum == 0) {
  330. that.Redflag = 7;
  331. that.RedProgress = 25;
  332. } else {
  333. // 限制最大
  334. that.Redflag = parseInt((redFmtSum / sumMax) * 100) > 100 ? 100 : parseInt((redFmtSum / sumMax) * 100);
  335. that.RedProgress = that.Redflag + 18;
  336. if (that.RedProgress > 90) {
  337. that.RedProgress = 90
  338. }
  339. }
  340. if (blueFmtSum == 0) {
  341. that.BlueFlag = 7;
  342. that.BlueProgress = 25;
  343. } else {
  344. // 限制最大
  345. that.BlueFlag = parseInt((blueFmtSum / sumMax) * 100) > 100 ? 100 : parseInt((blueFmtSum / sumMax) * 100);
  346. that.BlueProgress = that.BlueFlag + 18;
  347. if (that.BlueProgress > 90) {
  348. that.BlueProgress = 90
  349. }
  350. }
  351. },
  352. // 获取上课学生信息
  353. GetgetUserList() {
  354. let that = this;
  355. let param = {
  356. token: localStorage.token,
  357. eqSn: localStorage.eqSn
  358. };
  359. let postdata = qs.stringify(param);
  360. getHello(postdata).then(res => {
  361. let json = res;
  362. if (json.Code == 0) {
  363. if (!json.Dp) {
  364. // that.$message.error('没有获取到课程信息');
  365. return false
  366. } else {
  367. that.ReadLessonInfo(json.Dp);
  368. }
  369. // 学生分队展示
  370. that.UniteBreak(json.Rs);
  371. // 人口总数
  372. that.num = json.Rs.length ? json.Rs.length : 0;
  373. this.ClacClassTime();
  374. } else {
  375. // 已下课
  376. // console.log("[getHello] 已下课 " + json.Code);
  377. if (json.Code == '999') {
  378. // that.$router.push({path: '/2pkRank'});
  379. } else {
  380. // 已出错
  381. that.$message.error(json.Memo);
  382. }
  383. }
  384. })
  385. },
  386. giveClassName(res, type) {
  387. let that = this;
  388. if (type == 1) {
  389. that.redPeron = parseInt(res.length);
  390. } else {
  391. that.bluePerson = parseInt(res.length)
  392. }
  393. },
  394. // 计算团队竞技课持续时间
  395. ClacClassTime() {
  396. let BeginTime = new Date(globalcurrent() + ' ' + this.BeginTime);//结束时间
  397. let nowDate = new Date();
  398. let date = new Date(nowDate - BeginTime - 8 * 60 * 60 * 1000);//减掉东八区时区问题
  399. let h = date.getHours() < 10 ? '0' + date.getHours() + ':' : date.getHours() + ':';
  400. let m = date.getMinutes() < 10 ? '0' + date.getMinutes() + ':' : date.getMinutes() + ':';
  401. let s = date.getSeconds() < 10 ? '0' + date.getSeconds() : date.getSeconds();
  402. this.classInfo.endTime = h + m + s;
  403. },
  404. // 当前课程状态
  405. curgetClassStat() {
  406. let that = this;
  407. let param = {
  408. token: localStorage.token,
  409. eqSn: localStorage.eqSn
  410. };
  411. let postdata = qs.stringify(param);
  412. getClassStat(postdata).then(res => {
  413. let json = res;
  414. if (json.Code == 0) {
  415. // 没开课
  416. if (json.ClassOn == 0) {
  417. that.ClassOn = 0;
  418. if (that.studentInfo.dialogVisible == true || that.toperInfo.dialogVisible == true) {
  419. console.log('[getClassStat] 下课了,等待弹出窗口关闭');
  420. return false
  421. }
  422. console.log("下课了");
  423. // 0: 下课 团课/私教 排名
  424. // 1:团课/私教 todo
  425. // 2:竞技课2PK
  426. // 3:竞技课3PK
  427. that.$router.push({path: '/2pkRank'});
  428. // switch (parseInt(json.dp)) {
  429. // case 2:
  430. // that.$router.push({path: '/2pkRank'});
  431. // break;
  432. // }
  433. }
  434. } else {
  435. // that.$message.error(json.Memo);
  436. }
  437. })
  438. },
  439. },
  440. filters: {
  441. fmtNum(val) {
  442. if (val == 0) {
  443. return '--'
  444. } else {
  445. if (parseInt(val) < 0) return 0;
  446. if (parseInt(val) > 0) return val
  447. }
  448. },
  449. fmtFloat(val) {
  450. if (val == 0) {
  451. return '0.0'
  452. } else {
  453. return parseFloat(val).toFixed(1);
  454. }
  455. },
  456. fmtInt(val) {
  457. if (val == 0) {
  458. return '0'
  459. } else {
  460. return parseInt(val);
  461. }
  462. },
  463. max100(val) {
  464. if (val <= 100) {
  465. return val
  466. } else {
  467. return 100
  468. }
  469. }
  470. },
  471. components: {
  472. Headside, newRecord, newStudent, pkstudent
  473. }
  474. }
  475. </script>
  476. <style lang="scss" scoped>
  477. @mixin cube {
  478. width: 100%;
  479. overflow: hidden;
  480. display: block;
  481. margin: 0 auto;
  482. }
  483. @mixin bg {
  484. height: 100%;
  485. background-color: #333;
  486. background-repeat: no-repeat;
  487. background-position: top center;
  488. background-size: 100% 100%;
  489. }
  490. .pages {
  491. background: url("../assets/imgs/pk/pkbg.png");
  492. @include bg;
  493. .pageTitle {
  494. background: url("../assets/imgs/pk/pageTitle.svg");
  495. background-repeat: no-repeat;
  496. background-position: top center;
  497. background-size: 100% 100%;
  498. @include cube;
  499. width: 2rem;
  500. height: 1rem;
  501. }
  502. .progressContainer {
  503. .valueDisplay {
  504. @include cube;
  505. height: 2rem;
  506. overflow: hidden;
  507. .lt {
  508. width: 50%;
  509. float: left;
  510. span {
  511. float: right;
  512. background: url("../assets/imgs/pk/redFlag.png");
  513. background-repeat: no-repeat;
  514. background-position: top center;
  515. background-size: 100%;
  516. }
  517. }
  518. .rt {
  519. width: 50%;
  520. float: right;
  521. span {
  522. background: url("../assets/imgs/pk/blueFlag.png");
  523. background-repeat: no-repeat;
  524. background-position: top center;
  525. background-size: 100%;
  526. }
  527. }
  528. span {
  529. position: relative;
  530. top: 0.1rem;
  531. width: 1.9rem;
  532. height: 0.9rem;
  533. float: left;
  534. em {
  535. @include cube;
  536. font-size: 0.3rem;
  537. color: white;
  538. text-align: center;
  539. font-style: normal;
  540. line-height: 0.6rem;
  541. }
  542. }
  543. .md {
  544. @include cube;
  545. width: 1.6rem;
  546. position: relative;
  547. bottom: 0.4rem;
  548. z-index: 444;
  549. img {
  550. @include cube;
  551. }
  552. }
  553. }
  554. }
  555. }
  556. .lineContianer {
  557. position: relative;
  558. @include cube;
  559. bottom: 1.2rem;
  560. z-index: 222;
  561. .lt {
  562. width: 50%;
  563. float: left;
  564. span {
  565. width: 4rem;
  566. float: right;
  567. background: linear-gradient(to right, #d11122 0%, rgba(209, 17, 34, 0.23) 100%);
  568. }
  569. em {
  570. position: absolute;
  571. float: left;
  572. left: 40%;
  573. width: 1.6rem;
  574. color: white;
  575. font-size: 0.3rem;
  576. font-style: normal;
  577. text-align: left;
  578. line-height: 0.5rem;
  579. }
  580. }
  581. .rt {
  582. width: 50%;
  583. float: right;
  584. span {
  585. width: 4rem;
  586. float: left;
  587. background: linear-gradient(to left, #4cbbfc 0%, rgba(0, 125, 198, 0.17) 100%);
  588. position: relative;
  589. top: 0.0rem;
  590. height: 0.485rem !important;
  591. }
  592. em {
  593. position: absolute;
  594. float: left;
  595. left: 54%;
  596. width: 1.6rem;
  597. color: white;
  598. font-size: 0.3rem;
  599. font-style: normal;
  600. text-align: left;
  601. line-height: 0.5rem;
  602. }
  603. }
  604. span {
  605. height: 0.48rem;
  606. }
  607. }
  608. .userPart {
  609. @include cube;
  610. width: 88%;
  611. position: relative;
  612. bottom: 1.1rem;
  613. height: 7.4rem;
  614. .lt {
  615. @include cube;
  616. position: relative;
  617. width: 45%;
  618. height: 100%;
  619. float: left;
  620. .bottomLine {
  621. position: absolute;
  622. bottom: 0;
  623. @include cube;
  624. height: 0.25rem;
  625. border-radius: 18px;
  626. opacity: 0.8;
  627. background: linear-gradient(rgba(0, 0, 0, 0) 0%, rgba(209, 17, 34, 0.62) 100%);
  628. }
  629. }
  630. .rt {
  631. @include cube;
  632. position: relative;
  633. width: 45%;
  634. height: 100%;
  635. float: right;
  636. .bottomLine {
  637. position: absolute;
  638. bottom: 0;
  639. @include cube;
  640. height: 0.25rem;
  641. border-radius: 18px;
  642. opacity: 0.8;
  643. background: linear-gradient(rgba(0, 0, 0, 0) 0%, rgba(0, 134, 232, 0.62) 100%);
  644. }
  645. }
  646. .md {
  647. width: 10%;
  648. float: left;
  649. color: white;
  650. text-align: center;
  651. font-size: 0.4rem;
  652. padding-top: 18%;
  653. }
  654. }
  655. .icons {
  656. @include cube;
  657. position: absolute;
  658. bottom: 0.2rem;
  659. img {
  660. @include cube;
  661. // width: 40%;
  662. width: 18%;
  663. }
  664. }
  665. /*响应式调整*/
  666. @media(min-width: 320px) and (max-width: 1025px) {
  667. .progressContainer {
  668. margin-top: 0.9rem;
  669. }
  670. .userPart {
  671. height: 10rem;
  672. overflow-y: scroll;
  673. }
  674. /deep/ .twentyFive .names {
  675. bottom: 0.4rem !important;
  676. }
  677. }
  678. </style>