grid.vue 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566
  1. <!--
  2. [游戏] 网格赛事 - 网格拼图
  3. http://localhost:5173/card/#/pages/game/grid/grid
  4. https://oss-mbh5.colormaprun.com/card/#/pages/game/grid/grid
  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="compName" class="topbar-color" :showRule="true" @btnBackClick="btnBack"
  11. @btnInfoClick="btnInfo"></my-topbar>
  12. </view>
  13. <view class="main uni-column">
  14. <view v-if="grid.state <= 1" class="mt-content">开始你的挑战吧</view>
  15. <view v-if="grid.state == 2" class="mt-content">很棒!继续你的挑战吧</view>
  16. <view v-if="grid.state >= 3" class="mt-content" style="color: #FF5733;">挑战成功!</view>
  17. <view class="grid uni-column uni-jcse" :style="getGridStyle()">
  18. <view class="grid-row uni-row uni-jcse" :style="getGridRowStyle()" v-for="rowId in grid.heightNum"
  19. :key="rowId">
  20. <view class="grid-cell" :style="getGridCellStyle(rowId, colId)" v-for="colId in grid.widthNum"
  21. :key="colId" @click="onCellClick(rowId, colId)">
  22. <template v-for="(item, index) in grid.detailRs" :key="index">
  23. <view class="cell-name"
  24. :class="item.isComplete ? 'cell-name-complete' : 'cell-name-uncomplete'"
  25. v-if="item.orderNum == getCellOrderNum(rowId, colId)">
  26. {{item.showName}}
  27. </view>
  28. </template>
  29. </view>
  30. </view>
  31. </view>
  32. <view class="introduce uni-column">
  33. <text class="introduce-title">{{introduce.title}}</text>
  34. <text class="introduce-content" v-html="introduce.content"></text>
  35. </view>
  36. <view v-if="activityRules.content.length > 0" class="activityRules uni-column">
  37. <text class="activityRules-title">{{activityRules.title}}</text>
  38. <text class="activityRules-content" v-html="activityRules.content"></text>
  39. </view>
  40. </view>
  41. <my-popup ref="mypopup" :config="popupDataConfig" :dataList="popupDataList"
  42. @popup-start="startGame"></my-popup>
  43. <my-popup ref="mypopupRule" :config="cardConfigData.popupRuleConfig"
  44. :dataList="cardConfigData.popupRuleList"></my-popup>
  45. </view>
  46. </view>
  47. </template>
  48. <script>
  49. import tools from '../../../common/tools';
  50. import cardfunc from '../../../common/cardfunc';
  51. import {
  52. localCardConfig
  53. } from "./cardconfig/test.js";
  54. import {
  55. token,
  56. apiGridsQuery,
  57. apiUserJoinCardQuery,
  58. apiOnlineMcSignUp,
  59. checkResCode,
  60. checkToken
  61. } from '../../../common/api';
  62. export default {
  63. data() {
  64. return {
  65. cardConfigData: cardfunc.cardConfigData,
  66. pageReady: false,
  67. pageName: "grid",
  68. queryObj: {},
  69. queryString: "",
  70. token: "",
  71. ecId: 0, // 卡片id
  72. compId: 0, // 赛事id
  73. compName: "", // 赛事名称
  74. mcState: 0, // 赛事/活动状态 0: 未开始 1: 进行中 2: 已结束
  75. isJoin: false, // 是否报名
  76. // acttime: "", // 活动时间
  77. // beginSecond: null, // 活动或赛事开始时间戳,单位秒
  78. // endSecond: null, // 活动或赛事结束时间戳,单位秒
  79. sltCellOrderNum: 0, // 用户选中网格的序号
  80. sltCellRs: {}, // 用户选中网格对应的活动记录
  81. popupDataConfig: {
  82. "height": "530px"
  83. },
  84. popupDataList: [],
  85. grid: { // 网格数据
  86. widthNum: 0, // 横向网格数量
  87. heightNum: 0, // 竖向网格数量
  88. maskImgPic: "", // 遮罩图url
  89. actualImgPic: "", // 真实图url
  90. state: 0, // 网格赛事状态 1 未开始 2 进行中 3 已完成
  91. detailRs: [{
  92. orderNum: 0, //序号
  93. ocaId: 0, //活动id
  94. mcType: 0, //活动类型 1普通 2线下 3线上
  95. isComplete: 0, //是否完赛
  96. showName: "", //显示名称
  97. description: "", //描述
  98. longitude: 0, //导航起点经度
  99. latitude: 0, //导航起点纬度
  100. popupImg: "" // 弹窗图片
  101. }]
  102. },
  103. grid0: { // 网格数据
  104. widthNum: 1, // 横向网格数量
  105. heightNum: 1, // 竖向网格数量
  106. maskImgPic: "static/backgroud/grid4_mask.png", // 遮罩图url
  107. actualImgPic: "static/backgroud/grid_bg.jpg", // 真实图url
  108. state: 0, // 网格赛事状态 1 未开始 2 进行中 3 已完成
  109. },
  110. grid1: { // 网格数据
  111. widthNum: 2, // 横向网格数量
  112. heightNum: 2, // 竖向网格数量
  113. maskImgPic: "static/backgroud/grid4_mask.png", // 遮罩图url
  114. actualImgPic: "static/backgroud/grid_bg.jpg", // 真实图url
  115. state: 0, // 网格赛事状态 1 未开始 2 进行中 3 已完成
  116. detailRs: [{
  117. orderNum: 1, //序号
  118. ocaId: 0, //活动id
  119. mcType: 0, //活动类型 1普通 2线下 3线上
  120. isComplete: 1, //是否完赛
  121. showName: "", //显示名称
  122. description: "", //描述
  123. longitude: 0, //导航起点经度
  124. latitude: 0 //导航起点纬度
  125. }]
  126. },
  127. grid2: { // 网格数据
  128. widthNum: 3, // 横向网格数量
  129. heightNum: 3, // 竖向网格数量
  130. maskImgPic: "static/backgroud/grid9_mask.png", // 遮罩图url
  131. actualImgPic: "static/backgroud/grid_bg.jpg", // 真实图url
  132. state: 2, // 网格赛事状态 1 未开始 2 进行中 3 已完成
  133. detailRs: [{
  134. orderNum: 1, //序号
  135. ocaId: 0, //活动id
  136. mcType: 0, //活动类型 1普通 2线下 3线上
  137. isComplete: 1, //是否完赛
  138. showName: "asdf", //显示名称
  139. description: "", //描述
  140. longitude: 0, //导航起点经度
  141. latitude: 0 //导航起点纬度
  142. }]
  143. },
  144. grid3: { // 网格数据
  145. widthNum: 4, // 横向网格数量
  146. heightNum: 4, // 竖向网格数量
  147. maskImgPic: "static/backgroud/grid4_mask.png", // 遮罩图url
  148. actualImgPic: "static/backgroud/grid_bg.jpg", // 真实图url
  149. state: 0, // 网格赛事状态 1 未开始 2 进行中 3 已完成
  150. detailRs: [{
  151. orderNum: 1, //序号
  152. ocaId: 0, //活动id
  153. mcType: 0, //活动类型 1普通 2线下 3线上
  154. isComplete: 0, //是否完赛
  155. showName: "", //显示名称
  156. description: "", //描述
  157. longitude: 0, //导航起点经度
  158. latitude: 0, //导航起点纬度
  159. }]
  160. },
  161. introduce: {
  162. title: "",
  163. content: ""
  164. },
  165. activityRules: {
  166. title: "",
  167. content: ""
  168. }
  169. }
  170. },
  171. computed: {},
  172. onLoad(query) { // 类型非必填,可自动推导
  173. // console.log(query);
  174. this.queryObj = query;
  175. this.queryString = tools.objectToQueryString(this.queryObj);
  176. // console.log(queryString);
  177. this.token = query["token"] ?? token;
  178. this.ecId = query["id"] ?? 0;
  179. cardfunc.init(this, this.token, this.ecId);
  180. cardfunc.getCardConfig(this.cardConfigQueryCallback, localCardConfig);
  181. },
  182. // 页面初次渲染完成,此时组件已挂载完成,DOM 树($el)已可用
  183. onReady() {},
  184. onUnload() {},
  185. methods: {
  186. // 获取网格序号 1-9
  187. getCellOrderNum(rowId, colId) {
  188. return (rowId - 1) * this.grid.widthNum + colId;
  189. },
  190. getGridStyle() {
  191. let style = "";
  192. // 网格赛事状态 1 未开始 2 进行中 3 已完成
  193. // if (this.grid.state >= 3) {
  194. // style = `background-image: url("${this.grid.actualImgPic}");`;
  195. // } else {
  196. style = `background-image: url("${this.grid.maskImgPic}");`;
  197. // }
  198. // console.log("getGridStyle", style);
  199. return style;
  200. },
  201. getGridRowStyle() {
  202. let style = "";
  203. let height = "";
  204. if (this.grid.heightNum == 1) {
  205. height = "98%";
  206. } else if (this.grid.heightNum == 2) {
  207. height = "49%";
  208. } else if (this.grid.heightNum == 3) {
  209. height = "32.5%";
  210. } else if (this.grid.heightNum == 4) {
  211. height = "24.2%";
  212. }
  213. style = `height: ${height};`;
  214. // console.log("getGridRowStyle", style);
  215. return style;
  216. },
  217. getGridCellStyle(rowId, colId) {
  218. let style = "";
  219. let width = "";
  220. let pos = "";
  221. const orderNum = this.getCellOrderNum(rowId, colId);
  222. const rs = tools.objArrGetObjByValue(this.grid.detailRs, "orderNum", orderNum);
  223. // console.log("[getGridCellStyle] rs ", rs);
  224. if (this.grid.widthNum == 1) {
  225. width = "98%";
  226. pos = "100%";
  227. } else if (this.grid.widthNum == 2) {
  228. width = "49%";
  229. pos = "100%";
  230. } else if (this.grid.widthNum == 3) {
  231. width = "32.5%";
  232. pos = "50%";
  233. } else if (this.grid.widthNum == 4) {
  234. width = "24.2%";
  235. pos = "33.33%";
  236. }
  237. style = `width: ${width};`;
  238. // if (this.grid.state < 3 && rs && rs.isComplete) {
  239. if (rs && rs.isComplete) {
  240. style += `background-image: url("${this.grid.actualImgPic}");`;
  241. style += `background-position: calc(${pos} * ${colId-1}) calc(${pos} * ${rowId-1});`;
  242. }
  243. // console.log("getGridCellStyle", style);
  244. return style;
  245. },
  246. cardConfigQueryCallback(cardconfig) {
  247. this.loadConfig(cardconfig);
  248. this.gridsQuery();
  249. },
  250. loadConfig(cardconfig) {
  251. cardconfig = cardfunc.parseCardConfig(cardconfig);
  252. console.log("[loadCardConfig] cardconfig:", cardconfig);
  253. // 加载卡片通用配置
  254. if (cardconfig.common != undefined) {
  255. cardfunc.loadCardCommonConfig(cardconfig.common);
  256. }
  257. // -------- 加载当前页面的配置 --------
  258. const config = cardfunc.parseCardConfig(cardconfig[this.pageName]);
  259. // console.log("[loadConfig] config_page:", config);
  260. if (config == undefined || config == null) {
  261. this.pageReady = true;
  262. return;
  263. }
  264. // 加载CSS样式
  265. const css = config.css;
  266. if (css != undefined && css.length > 0) {
  267. tools.loadCssCode(css);
  268. }
  269. // 加载介绍内容
  270. const introduce = config.introduce;
  271. if (introduce != undefined) {
  272. if (introduce.title != undefined) {
  273. this.introduce.title = introduce.title;
  274. }
  275. if (introduce.content != undefined) {
  276. this.introduce.content = introduce.content;
  277. }
  278. }
  279. // 加载活动规则
  280. const activityRules = config.activityRules;
  281. if (activityRules != undefined) {
  282. if (activityRules.title != undefined) {
  283. this.activityRules.title = activityRules.title;
  284. }
  285. if (activityRules.content != undefined) {
  286. this.activityRules.content = activityRules.content;
  287. }
  288. }
  289. this.pageReady = true;
  290. },
  291. // 网格卡片信息查询
  292. gridsQuery() {
  293. uni.request({
  294. url: apiGridsQuery,
  295. header: {
  296. "Content-Type": "application/x-www-form-urlencoded",
  297. "token": this.token
  298. },
  299. method: "POST",
  300. data: {
  301. ecId: this.ecId
  302. },
  303. success: (res) => {
  304. // console.log("gridsQuery", res);
  305. const data = res.data.data;
  306. this.compId = data.compId,
  307. this.compName = data.compName;
  308. this.grid.widthNum = data.widthNum;
  309. this.grid.heightNum = data.heightNum;
  310. this.grid.maskImgPic = data.maskImgPic;
  311. this.grid.actualImgPic = data.actualImgPic;
  312. this.grid.state = data.state;
  313. this.grid.detailRs = data.detailRs;
  314. this.getUserJoinCardQuery();
  315. },
  316. fail: (err) => {
  317. console.log("gridsQuery err", err)
  318. },
  319. });
  320. },
  321. // 用户是否已经报名卡片对应赛事查询
  322. getUserJoinCardQuery() {
  323. uni.request({
  324. url: apiUserJoinCardQuery,
  325. header: {
  326. "Content-Type": "application/x-www-form-urlencoded",
  327. "token": this.token
  328. },
  329. method: "POST",
  330. data: {
  331. ecId: this.ecId
  332. },
  333. success: (res) => {
  334. // console.log("getUserJoinCardQuery", res)
  335. if (checkResCode(res)) {
  336. const data = res.data.data;
  337. this.isJoin = data.isJoin;
  338. if (!this.isJoin) { // 未报名,则自动给用户报名
  339. this.onlineMcSignUp();
  340. }
  341. }
  342. },
  343. fail: (err) => {
  344. console.log("getUserJoinCardQuery err", err)
  345. },
  346. });
  347. },
  348. // 线上赛报名
  349. onlineMcSignUp() {
  350. uni.request({
  351. url: apiOnlineMcSignUp,
  352. header: {
  353. "Content-Type": "application/x-www-form-urlencoded",
  354. "token": this.token,
  355. },
  356. method: "POST",
  357. data: {
  358. mcId: this.compId,
  359. // coiId: 0,
  360. // selectTeam: 0,
  361. // nickName: ''
  362. },
  363. success: (res) => {
  364. // console.log("onlineMcSignUp", res);
  365. if (checkResCode(res)) {
  366. // uni.showToast({
  367. // title: '比赛报名成功!',
  368. // icon: 'none',
  369. // duration: 3000
  370. // });
  371. }
  372. },
  373. fail: (err) => {
  374. console.log("onlineMcSignUp err", err);
  375. uni.showToast({
  376. title: '出错了,报名失败',
  377. icon: 'none',
  378. duration: 3000
  379. });
  380. },
  381. });
  382. },
  383. onCellClick(rowId, colId) {
  384. this.sltCellOrderNum = this.getCellOrderNum(rowId, colId);
  385. this.sltCellRs = tools.objArrGetObjByValue(this.grid.detailRs, "orderNum", this.sltCellOrderNum);
  386. if (this.sltCellRs && this.sltCellRs.ocaId > 0) {
  387. this.popupDataList = [{
  388. "type": 11,
  389. "data": {
  390. "title": this.sltCellRs.showName,
  391. "img": this.sltCellRs.popupImg,
  392. "content": this.sltCellRs.description,
  393. "point": {
  394. "longitude": this.sltCellRs.longitude,
  395. "latitude": this.sltCellRs.latitude,
  396. "name": this.sltCellRs.showName
  397. }
  398. }
  399. }];
  400. this.$nextTick(() => {
  401. this.$refs.mypopup.popupOpen();
  402. });
  403. } else {
  404. uni.showToast({
  405. icon: "none",
  406. title: "该格子未绑定赛事活动"
  407. })
  408. }
  409. },
  410. startGame() {
  411. if (this.sltCellRs) {
  412. const url = `action://to_detail/?id=${this.sltCellRs.ocaId}&matchType=${this.sltCellRs.mcType}`;
  413. tools.appAction(url);
  414. }
  415. },
  416. btnBack() {
  417. const url = `action://to_home/`;
  418. tools.appAction(url);
  419. },
  420. btnInfo() {
  421. this.$refs.mypopupRule.popupOpen();
  422. }
  423. }
  424. }
  425. </script>
  426. <style scoped>
  427. .content {
  428. width: 100vw;
  429. min-height: 100vh;
  430. }
  431. .page-top {
  432. width: 100%;
  433. height: 60px;
  434. padding-top: 36px;
  435. justify-content: space-between;
  436. background: linear-gradient(135deg, #FFEF9E 0%, #FFFCF2 45.14%, #FFF4D4 100%);
  437. }
  438. .topbar-color {
  439. color: #000000;
  440. }
  441. .main {
  442. width: 88%;
  443. min-height: 300px;
  444. justify-content: space-around;
  445. }
  446. .mt-content {
  447. margin: 20px 0px;
  448. font-size: 20px;
  449. font-weight: 400;
  450. color: #333333;
  451. }
  452. .grid {
  453. width: 90vw;
  454. height: 90vw;
  455. border-radius: 10px;
  456. border: #FFC300 solid 10px;
  457. background-repeat: no-repeat;
  458. background-position: 2px 2px;
  459. background-size: calc(90vw - 4px) calc(90vw - 4px);
  460. }
  461. .grid-row {
  462. width: 100%;
  463. }
  464. .grid-cell {
  465. position: relative;
  466. height: 100%;
  467. background-repeat: no-repeat;
  468. background-size: calc(90vw - 4px) calc(90vw - 4px);
  469. }
  470. .cell-name {
  471. position: absolute;
  472. left: 5px;
  473. bottom: 2px;
  474. font-size: 12px;
  475. font-weight: 400;
  476. }
  477. .cell-name-uncomplete {
  478. color: #CF6B00;
  479. }
  480. .cell-name-complete {
  481. color: #CF6B00;
  482. }
  483. .introduce {
  484. width: 96%;
  485. margin-top: 10px;
  486. margin-bottom: 10px;
  487. align-items: flex-start;
  488. justify-content: space-around;
  489. }
  490. .introduce-title {
  491. color: #333333;
  492. font-size: 20px;
  493. line-height: 50px;
  494. font-family: Source Han Sans CN;
  495. }
  496. .introduce-content {
  497. color: #333333;
  498. font-size: 16px;
  499. line-height: 23px;
  500. font-family: Source Han Sans CN;
  501. }
  502. .activityRules {
  503. width: 96%;
  504. margin-top: 5px;
  505. margin-bottom: 10px;
  506. padding: 10px 15px;
  507. align-items: flex-start;
  508. justify-content: space-around;
  509. border-radius: 9px;
  510. background: #FAF5E6;
  511. }
  512. .activityRules-title {
  513. color: #333333;
  514. font-size: 16px;
  515. line-height: 25px;
  516. font-weight: 500;
  517. font-family: Source Han Sans CN;
  518. }
  519. .activityRules-content {
  520. color: #333333;
  521. font-size: 14px;
  522. line-height: 23px;
  523. font-family: Source Han Sans CN;
  524. }
  525. </style>