signup.vue 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552
  1. <!--
  2. [模板] 样式1 - 报名
  3. http://localhost:5173/card/#/pages/tpl/style1/signup
  4. https://oss-mbh5.colormaprun.com/card/#/pages/tpl/style1/signup
  5. -->
  6. <template>
  7. <view class="body">
  8. <view v-if="pageReady" class="content uni-column">
  9. <view class="uni-column page-top">
  10. <my-topbar :mcName="mcName" class="topbar-color"
  11. @btnBackClick="btnBack" @btnInfoClick="btnInfo"></my-topbar>
  12. </view>
  13. <view class="main uni-column">
  14. <view class="timebar uni-row">
  15. <image mode="aspectFit" class="clock" src="/static/default/clock.png"></image>
  16. <text class="acttime">{{acttime}}</text>
  17. </view>
  18. <input class="uni-input" maxlength="12" placeholder="请填写昵称或姓名" v-model="nickName" @click="nickNameClick" />
  19. <view class="introduce uni-column">
  20. <text class="introduce-title">{{introduce.title}}</text>
  21. <text class="introduce-content" v-html="introduce.content"></text>
  22. </view>
  23. <view v-if="activityRules.content.length > 0" class="activityRules uni-column">
  24. <text class="activityRules-title">{{activityRules.title}}</text>
  25. <text class="activityRules-content" v-html="activityRules.content"></text>
  26. </view>
  27. <button class="btnSignup bgcolor-main" v-if="mcState<=1" @click="btnSignup">报 名</button>
  28. <button class="btnSignup btnSignup-disable" v-if="mcState==2">活动已结束</button>
  29. </view>
  30. <my-popup ref="mypopup" :config="cardConfigData.popupRuleConfig" :dataList="cardConfigData.popupRuleList" :acttime="acttime"></my-popup>
  31. <uni-popup ref="alertDialog" type="dialog">
  32. <uni-popup-dialog type="info" cancelText="取消" confirmText="确认" title="您填写的姓名:" @confirm="dialogConfirm"
  33. @close="dialogClose">
  34. <view class="dialog-content uni-column">
  35. <text class="dialog-content-1">{{nickName}}</text>
  36. </view>
  37. </uni-popup-dialog>
  38. </uni-popup>
  39. </view>
  40. </view>
  41. </template>
  42. <script>
  43. import tools from '../../../common/tools';
  44. import cardfunc from '../../../common/cardfunc';
  45. import { localCardConfig } from "./cardconfig/test.js";
  46. import {
  47. token,
  48. apiCardDetailQuery,
  49. apiOnlineMcSignUp,
  50. apiMatchRsDetailQuery,
  51. checkResCode,
  52. checkToken
  53. } from '../../../common/api';
  54. export default {
  55. data() {
  56. return {
  57. cardConfigData: cardfunc.cardConfigData,
  58. pageReady: false,
  59. pageName: "signup",
  60. firstEnterKey: 'firstEnter-tpl-style1',
  61. rankKey: "rank-tpl-style1",
  62. queryObj: {},
  63. queryString: "",
  64. from: "", // 来源页面
  65. token: "",
  66. ecId: 0, // 卡片id
  67. mcId: 0, // 赛事id
  68. mcType: 0, // 赛事类型 1 普通活动 2 线下赛 3 线上赛
  69. mcName: "", // 赛事名称
  70. acttime: "", // 活动时间
  71. beginSecond: null, // 活动或赛事开始时间戳,单位秒
  72. endSecond: null, // 活动或赛事结束时间戳,单位秒
  73. coiId: 0, // 已报名单位id
  74. coiName: "", // 已报名单位名称,可为空
  75. teamNum: 0, // 已报名队伍编号,可为0
  76. nickName: "", // 昵称
  77. // coiRs: [], // 组织信息集合
  78. // orgList: [], // 分组下拉列表数据源
  79. // teamList: [], //
  80. interval: null,
  81. mcState: 0, // 赛事/活动状态 0: 未开始 1: 进行中 2: 已结束
  82. // teamType: 0, // 队伍类型 0: 红黄蓝紫 1: 学生/家长
  83. introduce: {
  84. title: "",
  85. content: ""
  86. },
  87. activityRules: {
  88. title: "",
  89. content: ""
  90. },
  91. }
  92. },
  93. computed: {},
  94. onLoad(query) { // 类型非必填,可自动推导
  95. // console.log(query);
  96. this.queryObj = query;
  97. this.queryString = tools.objectToQueryString(this.queryObj);
  98. // console.log(queryString);
  99. this.from = query["from"] ?? "";
  100. this.token = query["token"] ?? token;
  101. this.ecId = query["id"] ?? 0;
  102. this.firstEnterKey += "-" + this.ecId;
  103. console.log("firstEnterKey:", this.firstEnterKey);
  104. this.rankKey += "-" + this.ecId;
  105. console.log("rankKey:", this.rankKey);
  106. cardfunc.init(this, this.token, this.ecId);
  107. cardfunc.getCardConfig(this.cardConfigQueryCallback, localCardConfig);
  108. this.getCardDetailQuery();
  109. this.matchRsDetailQuery();
  110. },
  111. // 页面初次渲染完成,此时组件已挂载完成,DOM 树($el)已可用
  112. onReady() {
  113. // this.dealFirstEnter();
  114. },
  115. onUnload() {
  116. this.clear();
  117. },
  118. methods: {
  119. dealNotice(rank) {
  120. // console.log('[dealNotice]');
  121. let that = this;
  122. uni.getStorage({
  123. key: that.rankKey,
  124. success: (res) => {
  125. // console.log('[getStorage]', that.rankKey, res.data);
  126. const oldRank = res.data;
  127. if (oldRank != rank) {
  128. // that.notice = true;
  129. that.setRankValue(rank);
  130. }
  131. },
  132. fail: (e) => {
  133. console.log('[getStorage] fail', that.rankKey, e);
  134. // that.notice = false;
  135. that.setRankValue(rank);
  136. },
  137. })
  138. },
  139. setRankValue(data) {
  140. let that = this;
  141. uni.setStorage({
  142. key: that.rankKey,
  143. data: data,
  144. success: () => {
  145. console.log('[setStorage] success', that.rankKey, data);
  146. },
  147. fail: (e) => {
  148. console.log('[setStorage] fail', that.rankKey, e);
  149. },
  150. })
  151. },
  152. dealFirstEnter() {
  153. // console.log('[dealFirstEnter]');
  154. let that = this;
  155. uni.getStorage({
  156. key: that.firstEnterKey,
  157. success: (res) => {
  158. console.log('[getStorage]', that.firstEnterKey, res.data);
  159. },
  160. fail: (e) => {
  161. console.log('[getStorage] fail', that.firstEnterKey, e);
  162. that.btnInfo();
  163. that.setFirstEnterValue(true);
  164. },
  165. })
  166. },
  167. setFirstEnterValue(data) {
  168. let that = this;
  169. uni.setStorage({
  170. key: that.firstEnterKey,
  171. data: data,
  172. success: () => {
  173. console.log('[setStorage] success', that.firstEnterKey, data);
  174. },
  175. fail: (e) => {
  176. console.log('[setStorage] fail', that.firstEnterKey, e);
  177. },
  178. })
  179. },
  180. clear() {
  181. if (this.interval != null) {
  182. clearInterval(this.interval);
  183. this.interval = null;
  184. }
  185. },
  186. cardConfigQueryCallback(cardconfig) {
  187. this.loadConfig(cardconfig);
  188. setTimeout(this.dealFirstEnter, 500);
  189. },
  190. loadConfig(cardconfig) {
  191. cardconfig = cardfunc.parseCardConfig(cardconfig);
  192. // console.log("[loadCardConfig] cardconfig:", cardconfig);
  193. // 加载卡片通用配置
  194. if (cardconfig.common != undefined) {
  195. cardfunc.loadCardCommonConfig(cardconfig.common);
  196. }
  197. // -------- 加载当前页面的配置 --------
  198. const config = cardfunc.parseCardConfig(cardconfig[this.pageName]);
  199. // console.log("[loadConfig] config_page:", config); if (config == undefined || config == null) {
  200. this.pageReady = true; return; }
  201. // 加载CSS样式
  202. const css = config.css;
  203. if (css != undefined && css.length > 0) {
  204. tools.loadCssCode(css);
  205. }
  206. // 加载队伍类型 0: 红黄蓝紫 1: 学生/家长
  207. /* if (config.teamType != undefined && config.teamType >= 0) {
  208. this.teamType = config.teamType;
  209. } */
  210. // 加载介绍内容
  211. const introduce = config.introduce;
  212. if (introduce != undefined) {
  213. if (introduce.title != undefined) {
  214. this.introduce.title = introduce.title;
  215. }
  216. if (introduce.content != undefined) {
  217. this.introduce.content = introduce.content;
  218. }
  219. }
  220. // 加载活动规则
  221. const activityRules = config.activityRules;
  222. if (activityRules != undefined) {
  223. if (activityRules.title != undefined) {
  224. this.activityRules.title = activityRules.title;
  225. }
  226. if (activityRules.content != undefined) {
  227. this.activityRules.content = activityRules.content;
  228. }
  229. }
  230. this.pageReady = true;
  231. },
  232. fmtMcTime(timestamp) {
  233. return tools.fmtMcTime(timestamp);
  234. },
  235. // 获取倒计时
  236. getActtime() {
  237. this.acttime = tools.getActtime(this.beginSecond, this.endSecond);
  238. },
  239. // 卡片信息查询
  240. getCardDetailQuery() {
  241. uni.request({
  242. url: apiCardDetailQuery,
  243. header: {
  244. "Content-Type": "application/x-www-form-urlencoded",
  245. "token": this.token
  246. },
  247. method: "POST",
  248. data: {
  249. ecId: this.ecId
  250. },
  251. success: (res) => {
  252. // console.log("getCardDetailQuery", res);
  253. const data = res.data.data;
  254. this.mcType = data.mcType;
  255. this.mcId = data.mcId;
  256. this.mcName = data.mcName;
  257. this.beginSecond = data.beginSecond;
  258. this.endSecond = data.endSecond;
  259. this.coiId = data.coiId;
  260. this.coiName = data.coiName;
  261. this.teamNum = data.teamNum;
  262. this.mcState = tools.checkMcState(this.beginSecond, this.endSecond);
  263. this.getActtime();
  264. // this.getOnlineMcSignUpDetail();
  265. this.clear();
  266. this.interval = setInterval(this.getActtime, 60000);
  267. },
  268. fail: (err) => {
  269. console.log("getCardDetailQuery err", err)
  270. },
  271. });
  272. },
  273. // 卡片对应线上赛多个活动查询
  274. matchRsDetailQuery() {
  275. uni.request({
  276. url: apiMatchRsDetailQuery,
  277. header: {
  278. "Content-Type": "application/x-www-form-urlencoded",
  279. "token": this.token,
  280. },
  281. method: "POST",
  282. data: {
  283. ecId: this.ecId
  284. },
  285. success: (res) => {
  286. // console.log("matchRsDetailQuery", res);
  287. if (res.data.code == 0) {
  288. const data = res.data.data;
  289. const rank = JSON.stringify(data);
  290. this.dealNotice(rank);
  291. }
  292. },
  293. fail: (err) => {
  294. console.log("matchRsDetailQuery err", err)
  295. },
  296. });
  297. },
  298. // 线上赛报名
  299. onlineMcSignUp() {
  300. uni.request({
  301. url: apiOnlineMcSignUp,
  302. header: {
  303. "Content-Type": "application/x-www-form-urlencoded",
  304. "token": this.token,
  305. },
  306. method: "POST",
  307. data: {
  308. mcId: this.mcId,
  309. coiId: this.coiId,
  310. selectTeam: this.teamNum,
  311. nickName: this.nickName
  312. },
  313. success: (res) => {
  314. // console.log("onlineMcSignUp", res);
  315. if (checkResCode(res)) {
  316. uni.showToast({
  317. title: '比赛报名成功!',
  318. icon: 'none',
  319. duration: 3000
  320. });
  321. const url = '/pages/tpl/style1/rankList?' + this.queryString;
  322. tools.appAction(url, "uni.navigateTo");
  323. }
  324. },
  325. fail: (err) => {
  326. console.log("onlineMcSignUp err", err);
  327. uni.showToast({
  328. title: '出错了,报名失败',
  329. icon: 'none',
  330. duration: 3000
  331. });
  332. },
  333. });
  334. },
  335. btnBack() {
  336. // console.log("from:", this.from)
  337. if (this.from != '') {
  338. // window.history.back();
  339. const url = '/pages/tpl/style1/rankList?' + this.queryString;
  340. tools.appAction(url, "uni.navigateTo");
  341. } else {
  342. const url = `action://to_home/`;
  343. tools.appAction(url);
  344. }
  345. },
  346. btnInfo() {
  347. this.$refs.mypopup.popupOpen();
  348. },
  349. nickNameClick() {
  350. checkToken(this.token);
  351. },
  352. btnSignup() {
  353. if (!checkToken(this.token)) {
  354. return;
  355. }
  356. if (!(this.nickName.trim().length > 0)) {
  357. uni.showToast({
  358. title: '请填写姓名',
  359. icon: 'none',
  360. duration: 2000
  361. });
  362. return;
  363. }
  364. this.nickName = this.nickName.trim();
  365. this.$refs.alertDialog.open();
  366. },
  367. dialogConfirm() {
  368. this.onlineMcSignUp();
  369. },
  370. dialogClose() {}
  371. }
  372. }
  373. </script>
  374. <style scoped>
  375. .content {
  376. width: 100vw;
  377. min-height: 100vh;
  378. }
  379. .page-top {
  380. width: 100%;
  381. height: 170px;
  382. padding-top: 36px;
  383. justify-content: space-between;
  384. background-image: url("/static/backgroud/top_bg_egg3.png");
  385. background-repeat: no-repeat;
  386. background-position: center;
  387. background-size: cover;
  388. }
  389. .topbar-color {
  390. color: #333333;
  391. }
  392. .main {
  393. width: 76%;
  394. min-height: 800rpx;
  395. /* margin-top: 20rpx; */
  396. justify-content: space-around;
  397. }
  398. .timebar {
  399. width: 90%;
  400. height: 32px;
  401. margin-top: 10px;
  402. padding: 0 15px;
  403. justify-content: center;
  404. background: #ffffff;
  405. border: 0.5px solid;
  406. border-color: #e7e7e7;
  407. border-radius: 20px;
  408. box-shadow: 0px 4px 4px rgba(0, 0, 0, 0.13);
  409. }
  410. .acttime {
  411. font-weight: 550;
  412. color: #333333;
  413. font-size: 14px;
  414. text-wrap: nowrap;
  415. }
  416. .clock {
  417. width: 15px;
  418. height: 15px;
  419. margin-right: 10px;
  420. }
  421. .uni-input {
  422. width: 90%;
  423. height: 43px;
  424. margin-top: 15px;
  425. padding: 0 15px;
  426. background: #f1f1f1;
  427. border-radius: 9px;
  428. }
  429. .input-placeholder {
  430. color: #333333;
  431. font-size: 16px;
  432. }
  433. .introduce {
  434. width: 100%;
  435. margin-top: 10px;
  436. margin-bottom: 10px;
  437. align-items: flex-start;
  438. justify-content: space-around;
  439. }
  440. .introduce-title {
  441. color: #333333;
  442. font-size: 15px;
  443. line-height: 30px;
  444. font-family: Source Han Sans CN;
  445. }
  446. .introduce-content {
  447. color: #333333;
  448. font-size: 13px;
  449. line-height: 23px;
  450. font-family: Source Han Sans CN;
  451. }
  452. .activityRules {
  453. width: 100%;
  454. margin-top: 5px;
  455. margin-bottom: 10px;
  456. padding: 10px 15px;
  457. align-items: flex-start;
  458. justify-content: space-around;
  459. border-radius: 9px;
  460. background: #EBEBEB;
  461. }
  462. .activityRules-title {
  463. color: #333333;
  464. font-size: 14px;
  465. line-height: 25px;
  466. font-weight: 500;
  467. font-family: Source Han Sans CN;
  468. }
  469. .activityRules-content {
  470. color: #333333;
  471. font-size: 13px;
  472. line-height: 23px;
  473. font-family: Source Han Sans CN;
  474. }
  475. .btnSignup {
  476. width: 100%;
  477. height: 100rpx;
  478. margin-top: 30rpx;
  479. margin-bottom: 30rpx;
  480. color: white;
  481. font-weight: bold;
  482. line-height: 100rpx;
  483. border-radius: 55rpx;
  484. }
  485. .bgcolor-main {
  486. background-color: #81cd00;
  487. }
  488. .btnSignup-disable {
  489. background-color: #c3c3c3;
  490. }
  491. .dialog-content {
  492. width: 279px;
  493. height: 110px;
  494. background: #f1f1f1;
  495. border-radius: 9px;
  496. justify-content: center;
  497. text-align: center;
  498. font-weight: 550;
  499. color: #333333;
  500. }
  501. .dialog-content-1 {
  502. font-size: 40rpx;
  503. }
  504. </style>