rankList.vue 14 KB

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