signup.vue 15 KB

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