rankList.vue 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554
  1. <!--
  2. 锦标赛排名列表
  3. http://localhost:5173/card/#/pages/jbs/rankList
  4. https://oss-mbh5.colormaprun.com/card/#/pages/jbs/rankList
  5. -->
  6. <template>
  7. <view class="body">
  8. <view class="content">
  9. <view class="uni-column" :class="cssTop">
  10. <view class="topbar uni-row">
  11. <image mode="aspectFit" class="topbar-back" @click="btnBack" src="/static/default/back.png"></image>
  12. <text class="mcName">{{mcName}}</text>
  13. <text class="topbar-rule" @click="btnInfo" >规则</text>
  14. <!-- <image mode="aspectFit" class="topbar-info" @click="btnInfo" src="/static/default/info.png"></image> -->
  15. </view>
  16. <view :class="cssLogo"></view>
  17. <view class="topcontent uni-row">
  18. <text class="countdown">结束倒计时:</text>
  19. <image mode="aspectFit" class="cal" src="/static/default/cal.png"></image>
  20. <text class="countdown">{{countdown}}</text>
  21. </view>
  22. <!-- <text class="mcName">{{ecId}} - {{mcId}} - {{token}}</text> -->
  23. </view>
  24. <view class="main uni-column">
  25. <my-ranklist :rankRs="rankList.totalRankRs"></my-ranklist>
  26. <button class="btnStart btnStart-disable" v-if="mcState==0">活动尚未开始</button>
  27. <button class="btnStart btnStart-enable" v-if="mcState==1" @click="btnStart">开始比赛</button>
  28. <button class="btnStart btnStart-disable" v-if="mcState==2">活动已结束</button>
  29. </view>
  30. <my-popup ref="mypopup" :dataList="popupDataList"></my-popup>
  31. </view>
  32. </view>
  33. </template>
  34. <script>
  35. import tools from '../../common/tools';
  36. import {
  37. defaultPopUpDataList
  38. } from '/common/define';
  39. import {
  40. token,
  41. apiCardDetailQuery,
  42. apiCardRankDetailQuery,
  43. apiUserCurrentRankNumQuery,
  44. apiCardConfigQuery,
  45. apiOnlineMcSignUp,
  46. checkResCode
  47. } from '../../common/api';
  48. export default {
  49. data() {
  50. return {
  51. pageName: "rankList",
  52. firstEnterKey: 'firstEnter-jbs_rankList',
  53. rankKey: "rank-jbs",
  54. queryObj: {},
  55. queryString: "",
  56. token: "",
  57. ecId: 0, // 卡片id
  58. coiId: 0, // 单位id
  59. mcId: 0, // 赛事id
  60. mcType: 0, // 赛事类型 1 普通活动 2 线下赛 3 线上赛
  61. mcName: "", // 赛事名称
  62. beginSecond: null, // 活动或赛事开始时间戳,单位秒
  63. endSecond: null, // 活动或赛事结束时间戳,单位秒
  64. ocaId: 0, // 关联id,带入到App活动详情页面
  65. mcState: 0, // 赛事/活动状态 0: 未开始 1: 进行中 2: 已结束
  66. countdown: "", // 倒计时
  67. rankList: { // 排名列表
  68. totalRankRs: [],
  69. teamRankRs: [],
  70. inTeamRs: [],
  71. },
  72. interval: null,
  73. dispArrStr: "total", // 要显示的集合范围 (total,team,in,other)
  74. cssTop: "",
  75. cssLogo: "",
  76. popupDataList: [],
  77. }
  78. },
  79. computed: {},
  80. onLoad(query) { // 类型非必填,可自动推导
  81. // console.log(query);
  82. this.queryObj = query;
  83. this.queryString = tools.objectToQueryString(this.queryObj);
  84. // console.log(queryString);
  85. this.token = query["token"] ?? token;
  86. this.ecId = query["id"] ?? 0;
  87. this.firstEnterKey += "-" + this.ecId;
  88. console.log("firstEnterKey:", this.firstEnterKey);
  89. this.rankKey += "-" + this.ecId;
  90. console.log("rankKey:", this.rankKey);
  91. tools.removeCssCode();
  92. this.getCardConfigQuery();
  93. this.getUserCurrentRankNumQuery();
  94. // this.getCardDetailQuery();
  95. },
  96. // 页面初次渲染完成,此时组件已挂载完成,DOM 树($el)已可用
  97. onReady() {
  98. // this.dealFirstEnter();
  99. },
  100. onUnload() {
  101. this.clear();
  102. },
  103. methods: {
  104. dealNotice(rank) {
  105. // console.log('[dealFirstEnter]');
  106. let that = this;
  107. uni.getStorage({
  108. key: that.rankKey,
  109. success: (res) => {
  110. console.log('[getStorage]', that.rankKey, res.data);
  111. const oldRank = res.data;
  112. if (oldRank != rank) {
  113. // that.notice = true;
  114. that.setRankValue(rank);
  115. }
  116. },
  117. fail: (e) => {
  118. console.log('[getStorage] fail', that.rankKey, e);
  119. // that.notice = false;
  120. that.setRankValue(rank);
  121. },
  122. })
  123. },
  124. setRankValue(data) {
  125. let that = this;
  126. uni.setStorage({
  127. key: that.rankKey,
  128. data: data,
  129. success: () => {
  130. console.log('[setStorage] success', that.rankKey, data);
  131. },
  132. fail: (e) => {
  133. console.log('[setStorage] fail', that.rankKey, e);
  134. },
  135. })
  136. },
  137. dealFirstEnter() {
  138. let that = this;
  139. uni.getStorage({
  140. key: that.firstEnterKey,
  141. success: (res) => {
  142. console.log('[getStorage]', that.firstEnterKey, res.data);
  143. },
  144. fail: (e) => {
  145. console.log('[getStorage] fail', that.firstEnterKey, e);
  146. that.btnInfo();
  147. that.setFirstEnterValue(true);
  148. },
  149. })
  150. },
  151. setFirstEnterValue(data) {
  152. let that = this;
  153. uni.setStorage({
  154. key: that.firstEnterKey,
  155. data: data,
  156. success: () => {
  157. console.log('[setStorage] success', that.firstEnterKey, data);
  158. },
  159. fail: (e) => {
  160. console.log('[setStorage] fail', that.firstEnterKey, e);
  161. },
  162. })
  163. },
  164. clear() {
  165. if (this.interval != null) {
  166. clearInterval(this.interval);
  167. this.interval = null;
  168. }
  169. },
  170. loadConfig(config) {
  171. // console.log("config", config);
  172. // 加载CSS样式
  173. const css = config.css;
  174. if (css != undefined && css.length > 0) {
  175. tools.loadCssCode(css);
  176. if (css.indexOf(".top{") >= 0) {
  177. this.cssTop = "top";
  178. }
  179. if (css.indexOf(".logo{") >= 0) {
  180. this.cssLogo = "logo";
  181. }
  182. }
  183. if (this.cssTop == "") {
  184. this.cssTop = "top-default";
  185. }
  186. if (this.cssLogo == "") {
  187. this.cssLogo = "logo-default";
  188. }
  189. console.log("[loadConfig] cssTop:", this.cssTop);
  190. console.log("[loadConfig] cssLogo:", this.cssLogo);
  191. // 加载弹窗数据
  192. const popupDataList = config.popupDataList;
  193. // console.log("[loadConfig] popupDataList:", popupDataList);
  194. if (popupDataList != undefined && popupDataList.length > 0) {
  195. for (var i = 0; i < popupDataList.length; i++) {
  196. // console.log("[loadConfig] popupDataList", i, popupDataList[i]);
  197. if (popupDataList[i] == 'default') {
  198. for (var j = 0; j < defaultPopUpDataList.length; j++) {
  199. this.popupDataList.push(defaultPopUpDataList[j]);
  200. }
  201. } else {
  202. this.popupDataList.push(popupDataList[i]);
  203. }
  204. }
  205. } else {
  206. this.popupDataList = defaultPopUpDataList;
  207. console.log("[loadConfig] popupDataList 加载默认列表");
  208. }
  209. // console.log("[loadConfig] popupDataList:", this.popupDataList);
  210. },
  211. // 获取倒计时
  212. getCountdown() {
  213. if (this.endSecond > 0) {
  214. const now = Date.now() / 1000;
  215. const dif = this.endSecond - now;
  216. // const dif = 3600*24 - 60;
  217. if (dif > 0) {
  218. this.countdown = tools.convertSecondsToDHM(dif);
  219. } else {
  220. this.countdown = "已结束";
  221. }
  222. // this.countdown = tools.convertSecondsToHMS(dif);
  223. } else {
  224. this.countdown = "--天--小时";
  225. }
  226. },
  227. getCardConfigQuery() {
  228. uni.request({
  229. url: apiCardConfigQuery,
  230. header: {
  231. "Content-Type": "application/x-www-form-urlencoded",
  232. "token": this.token,
  233. },
  234. method: "POST",
  235. data: {
  236. ecId: this.ecId,
  237. pageName: this.pageName
  238. },
  239. success: (res) => {
  240. // console.log("getCardConfigQuery", res)
  241. const data = res.data.data;
  242. const config = data.configJson != "" ? JSON.parse(data.configJson) : "";
  243. // console.log("configJson", data.configJson);
  244. /* const config = {
  245. "css": `
  246. .top{
  247. width: 100%;
  248. height: 26vh;
  249. padding-top: 36px;
  250. justify-content: space-between;
  251. background-image: url('static/backgroud/top_colorbar.png'), linear-gradient(180deg,#178bff 0%,#004d9b 100%);
  252. background-repeat: no-repeat;
  253. background-position: center, 0px 0px;
  254. background-size: auto 22vh , cover;
  255. }
  256. .logo{
  257. width: 150px;
  258. height: 150px;
  259. margin-top: 10px;
  260. background-image: url('static/logo/xfl.png');
  261. background-repeat: no-repeat;
  262. background-position-x: center;
  263. background-position-y: center;
  264. background-size: contain;
  265. }
  266. `,
  267. "popupDataList": [
  268. {
  269. "type": 1,
  270. "data": {
  271. "title": "山青活动",
  272. "img": "/static/logo/sqsj.png",
  273. "content": "山青世界为广大青少年提供了亲近自然、劳动实践、拓展培训、军事教育、科普体验、自然探索的平台和机会,也为企事业单位青年团队提供会议培训、拓展训练等服务",
  274. }
  275. },
  276. "default"
  277. ]
  278. }; */
  279. this.loadConfig(config);
  280. this.getCardDetailQuery();
  281. setTimeout(this.dealFirstEnter, 500);
  282. },
  283. fail: (err) => {
  284. console.log("getCardConfigQuery err", err)
  285. },
  286. });
  287. },
  288. // 卡片信息查询
  289. getCardDetailQuery() {
  290. uni.request({
  291. url: apiCardDetailQuery,
  292. header: {
  293. "Content-Type": "application/x-www-form-urlencoded",
  294. "token": this.token,
  295. },
  296. method: "POST",
  297. data: {
  298. ecId: this.ecId
  299. },
  300. success: (res) => {
  301. // console.log("getCardDetailQuery", res)
  302. const data = res.data.data;
  303. this.coiId = data.coiId;
  304. this.mcId = data.mcId;
  305. this.mcType = data.mcType;
  306. this.mcName = data.mcName;
  307. this.beginSecond = data.beginSecond;
  308. this.endSecond = data.endSecond;
  309. this.ocaId = data.ocaId;
  310. this.mcState = tools.checkMcState(this.beginSecond, this.endSecond);
  311. this.getCountdown();
  312. this.getCardRankDetailQuery();
  313. this.clear();
  314. this.interval = setInterval(this.getCountdown, 60000);
  315. },
  316. fail: (err) => {
  317. console.log("getCardDetailQuery err", err)
  318. },
  319. });
  320. },
  321. // 排名查询
  322. getCardRankDetailQuery() {
  323. uni.request({
  324. url: apiCardRankDetailQuery,
  325. header: {
  326. "Content-Type": "application/x-www-form-urlencoded",
  327. "token": this.token,
  328. },
  329. method: "POST",
  330. data: {
  331. mcIdListStr: this.mcId,
  332. mcType: this.mcType,
  333. dispArrStr: this.dispArrStr
  334. },
  335. success: (res) => {
  336. // console.log("getCardRankDetailQuery", res)
  337. const rankdata = res.data.data;
  338. this.rankList.totalRankRs = rankdata.totalRankRs;
  339. this.rankList.teamRankRs = rankdata.teamRankRs;
  340. this.rankList.inTeamRs = rankdata.inTeamRs;
  341. },
  342. fail: (err) => {
  343. console.log("getCardRankDetailQuery err", err)
  344. },
  345. });
  346. },
  347. // 卡片用户当前排名查询
  348. getUserCurrentRankNumQuery() {
  349. uni.request({
  350. url: apiUserCurrentRankNumQuery,
  351. header: {
  352. "Content-Type": "application/x-www-form-urlencoded",
  353. "token": this.token,
  354. },
  355. method: "POST",
  356. data: {
  357. ecId: this.ecId
  358. },
  359. success: (res) => {
  360. // console.log("getUserCurrentRankNumQuery", res)
  361. if (res.data.code == 0) {
  362. const data = res.data.data;
  363. const rankNum = data.rankNum;
  364. this.dealNotice(rankNum);
  365. }
  366. },
  367. fail: (err) => {
  368. console.log("getUserCurrentRankNumQuery err", err)
  369. },
  370. });
  371. },
  372. // 线上赛报名(重新分组)
  373. onlineMcSignUp() {
  374. uni.request({
  375. url: apiOnlineMcSignUp,
  376. header: {
  377. "Content-Type": "application/x-www-form-urlencoded",
  378. "token": this.token,
  379. },
  380. method: "POST",
  381. data: {
  382. mcId: this.mcId,
  383. coiId: this.coiId,
  384. selectTeam: 0
  385. },
  386. success: (res) => {
  387. // console.log("onlineMcSignUp", res)
  388. if (checkResCode(res)) {
  389. // uni.showToast({
  390. // title: '比赛报名成功!',
  391. // icon: 'none',
  392. // duration: 3000
  393. // });
  394. const url = `action://to_detail/?id=${this.ocaId}&matchType=${this.mcType}`;
  395. // window.location.href = url;
  396. tools.appAction(url);
  397. }
  398. },
  399. fail: (err) => {
  400. console.log("onlineMcSignUp err", err)
  401. uni.showToast({
  402. title: '出错了,比赛报名失败',
  403. icon: 'none',
  404. duration: 3000
  405. });
  406. },
  407. });
  408. },
  409. btnBack() {
  410. // window.history.back();
  411. const url = `action://to_home/`;
  412. // window.location.href = url;
  413. tools.appAction(url);
  414. },
  415. btnStart() {
  416. this.onlineMcSignUp();
  417. },
  418. btnInfo() {
  419. this.$refs.mypopup.popupOpen();
  420. },
  421. }
  422. }
  423. </script>
  424. <style scoped>
  425. .content {
  426. width: 100vw;
  427. height: 100vh;
  428. }
  429. .top-default {
  430. width: 100%;
  431. height: 28vh;
  432. /* height: 500rpx; */
  433. padding-top: 36px;
  434. justify-content: flex-start;
  435. background-image: url("/static/backgroud/top_medal.png"), url("/static/backgroud/top_bg1.png");
  436. background-repeat: no-repeat;
  437. background-position-x: center, center;
  438. background-position-y: 15vh, center;
  439. background-size: 55vw auto, cover;
  440. }
  441. .logo-default {
  442. /* width: 150px;
  443. height: 150px;
  444. margin-top: 10px;
  445. background-image: url('/static/logo/jbs.png');
  446. background-repeat: no-repeat;
  447. background-position-x: center;
  448. background-position-y: center;
  449. background-size: contain; */
  450. }
  451. .topbar {
  452. width: 90%;
  453. /* padding: 0rpx 30rpx; */
  454. justify-content: space-between;
  455. }
  456. .topbar-back {
  457. width: 43rpx;
  458. height: 43rpx;
  459. /* opacity: 0; */
  460. }
  461. .topbar-info {
  462. width: 46rpx;
  463. height: 46rpx;
  464. }
  465. .topbar-rule {
  466. color: white;
  467. font-size: 32rpx;
  468. }
  469. .mcName {
  470. color: white;
  471. /* font-size: 32rpx; */
  472. font-size: 39rpx;
  473. font-weight: bold;
  474. }
  475. .topcontent {
  476. min-width: 300rpx;
  477. height: 100rpx;
  478. justify-content: space-evenly;
  479. }
  480. .countdown {
  481. color: white;
  482. font-size: 32rpx;
  483. }
  484. .cal {
  485. width: 30rpx;
  486. margin-right: 20rpx;
  487. }
  488. .main {
  489. width: 100%;
  490. height: 66vh;
  491. justify-content: space-between;
  492. }
  493. .btnStart {
  494. width: 70%;
  495. height: 5vh;
  496. /* height: 80rpx; */
  497. margin-bottom: 1vh;
  498. font-weight: bold;
  499. line-height: 5vh;
  500. background-color: #ffb40b;
  501. }
  502. .btnStart-enable {
  503. background-color: #ffb40b;
  504. }
  505. .btnStart-disable {
  506. background-color: #c3c3c3;
  507. }
  508. </style>
  509. <style lang="scss" scoped>
  510. ::v-deep .list {
  511. height: 58vh;
  512. margin-top: 5px;
  513. }
  514. </style>