grid.vue 15 KB

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