actDetail.vue 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472
  1. <template>
  2. <view class="body">
  3. <view class="content uni-column">
  4. <view class="uni-column top" :style="getBannerStyle()">
  5. <my-topbar :title="actRs.config.matchInfo.compName" @btnBackClick="btnBack"
  6. :showBack="userlevel > 0"></my-topbar>
  7. <view class="top-content uni-row">
  8. </view>
  9. </view>
  10. <view class="main uni-column">
  11. <view class="compBox uni-column">
  12. <view class="compName">
  13. <uni-tag :circle="true" :text="pubState[actRs.otherInfo.pubState]"
  14. :type="actRs.otherInfo.pubState > 1 ? 'primary' : 'warning'" size="small" />
  15. {{actRs.config.matchInfo.compName}}
  16. </view>
  17. <view class="comp_time">赛事日期:{{getActtime()}}</view>
  18. <view v-if="userlevel > 0" class="comp_time">( 联系人:{{actRs.config.matchInfo.contactName}}
  19. &nbsp;&nbsp; 电话:<a :href="'tel:' + actRs.config.matchInfo.phone"
  20. style='color: #ff5500;'>{{actRs.config.matchInfo.phone}}</a> )</view>
  21. <view class="introduce uni-column">
  22. <!-- <text class="introduce-title">赛事介绍</text> -->
  23. <text class="introduce-content" v-html="actRs.config.matchInfo.description"></text>
  24. </view>
  25. <view v-if="actRs.config.matchInfo.rules.length > 0" class="activityRules uni-column">
  26. <text class="activityRules-title">活动规则</text>
  27. <text class="activityRules-content" v-html="actRs.config.matchInfo.rules"></text>
  28. </view>
  29. </view>
  30. <view class="uni-row uni-jcse qrImgBox">
  31. <view class="uni-column">
  32. <image class="imgQrCode" :src="imgQrCodeWx"></image>
  33. <view class="qrMemo">(微信扫码)</view>
  34. <view class="qrMemo">查看赛事详情</view>
  35. </view>
  36. <view v-if="userlevel > 0" class="uni-column">
  37. <image class="imgQrCode" :src="imgQrCodeApp"></image>
  38. <view class="qrMemo">(彩图奔跑APP扫码)</view>
  39. <view class="qrMemo">查看赛事卡片<text v-if="userlevel > 0" style="color: #ff5500;"
  40. @click="qrCodeReset"> [重置]</text></view>
  41. </view>
  42. </view>
  43. </view>
  44. <view class="bottom uni-row uni-jcc">
  45. <button v-if="userlevel > 0" class="bottom-button" @click="btnActEdit">赛事修改</button>
  46. <button v-if="userlevel > 0 && actRs.otherInfo.pubState == 1" class="bottom-button" @click="btnActPublish">赛事发布</button>
  47. <button class="bottom-button" @click="btnRankList">排行榜</button>
  48. <!-- <button class="bottom-button" @click="btnTrack">场地直播</button> -->
  49. </view>
  50. </view>
  51. <view class="qrcodeBox">
  52. <uv-qrcode ref="qrCodeWx" class="qrCode" size="300px" :value="qrCodeWx" :options="qrCodeOptWx"
  53. @complete="qrCodeWxComplete">
  54. </uv-qrcode>
  55. <uv-qrcode v-if="userlevel > 0" ref="qrCodeApp" class="qrCode" size="300px" :value="qrCodeApp"
  56. :options="qrCodeOptApp" @complete="qrCodeAppComplete">
  57. </uv-qrcode>
  58. </view>
  59. </view>
  60. </template>
  61. <script>
  62. import {
  63. mapState,
  64. mapGetters
  65. } from 'vuex';
  66. import tools from '/utils/tools.js';
  67. import card from '/utils/card.js';
  68. // import { tplStyleList, userLevel, pubState } from '/utils/define.js';
  69. import {
  70. pubState
  71. } from '/utils/define.js';
  72. import {
  73. apiCompInfoDetail,
  74. apiCompInfoPublish,
  75. apiCompQrCodeQuery,
  76. apiCompQrCodeReset,
  77. checkResCode
  78. } from '/utils/api.js';
  79. import {
  80. nextTick
  81. } from 'vue';
  82. export default {
  83. data() {
  84. return {
  85. pubState: pubState, //发布状态 0:审核中 1:内测 2:已发布
  86. queryObj: {},
  87. queryString: "",
  88. compId: 0, // 赛事ID
  89. qrCodeWx: "",
  90. qrCodeOptWx: {
  91. margin: 5,
  92. // areaColor: "#f1f1f1",
  93. foregroundImageSrc: '/static/logo/wechat.png' // 指定二维码前景,一般可在中间放logo
  94. },
  95. imgQrCodeWx: "",
  96. qrCodeApp: "",
  97. qrCodeOptApp: {
  98. margin: 5,
  99. // areaColor: "#f1f1f1",
  100. foregroundImageSrc: '/static/logo.png' // 指定二维码前景,一般可在中间放logo
  101. },
  102. imgQrCodeApp: "",
  103. actRs: card.actRs,
  104. /* actRs: {
  105. otherInfo: {
  106. compId: 1,
  107. pubState: "内测",
  108. playNum: 26,
  109. signupState: false,
  110. createTime: 1735530373
  111. },
  112. config: {
  113. "tplInfo": {
  114. "styleId": 0,
  115. "matchLogo": "/static/run.png",
  116. "matchBanner": "static/banner/banner1.png",
  117. },
  118. "matchInfo": {
  119. "compName": "小飞龙系列定向赛",
  120. "description": " · 小飞龙定向赛再次来袭!这次有五个场地哟~<br> · 神秘“蛋叔”闪亮登场~<br> · 蛋叔放大招,百味豆换鸡蛋!<br> · 时不可待!冲鸭!<br><br> · 能不能把蛋叔整郁闷,就看你的啦~<br> · 还等啥?火速报名吧!",
  121. "rules": "<li>随时参赛、不限完赛次数、起点任选、实时排名 <li>起点 -各途经点 -结束点完整打卡为一次有效完赛",
  122. "maxNum": 20,
  123. "contactName": "王老师",
  124. "phone": "13335116666",
  125. "regBeginSecond": 1735530373,
  126. "regEndSecond": 1735950373,
  127. "compBeginSecond": 1736050373,
  128. "compEndSecond": 1736950373,
  129. }
  130. }
  131. } */
  132. }
  133. },
  134. computed: {
  135. ...mapState([
  136. 'username', // 映射 this.username 为 store.state.username
  137. 'userlevel',
  138. 'token'
  139. ]),
  140. ...mapGetters([
  141. 'metadata'
  142. ]),
  143. },
  144. onLoad(query) {
  145. // console.log(query);
  146. this.queryObj = query;
  147. this.queryString = tools.objectToQueryString(this.queryObj);
  148. // console.log(queryString);
  149. this.compId = query["compId"] ?? 0;
  150. this.compInfoDetail();
  151. this.getQrCodeWx();
  152. },
  153. methods: {
  154. getBannerStyle() {
  155. return card.getBannerStyle(this.actRs);
  156. },
  157. getActtime() {
  158. return tools.fmtMcTime3(this.actRs.config.matchInfo.compBeginSecond, this.actRs.config.matchInfo
  159. .compEndSecond);
  160. },
  161. // 自助赛事详情查询
  162. compInfoDetail() {
  163. uni.request({
  164. url: apiCompInfoDetail,
  165. header: this.metadata,
  166. method: "POST",
  167. data: {
  168. compId: this.compId
  169. },
  170. success: (res) => {
  171. console.log("compInfoDetail", res);
  172. if (checkResCode(res)) {
  173. const data = res.data.data;
  174. this.actRs = data;
  175. if (this.userlevel > 0) {
  176. this.getQrCodeApp();
  177. }
  178. }
  179. },
  180. fail: (err) => {
  181. console.log("compInfoDetail err", err);
  182. },
  183. });
  184. },
  185. // 自助赛事发布
  186. compInfoPublish() {
  187. uni.request({
  188. url: apiCompInfoPublish,
  189. header: this.metadata,
  190. method: "POST",
  191. data: {
  192. compId: this.compId
  193. },
  194. success: (res) => {
  195. console.log("compInfoPublish", res);
  196. if (checkResCode(res)) {
  197. // const data = res.data.data;
  198. uni.showToast({
  199. title: `赛事发布成功`,
  200. icon: 'none',
  201. duration: 3000
  202. });
  203. setTimeout(() => {
  204. this.$router.go(0); // 刷新当前页面
  205. }, 1000);
  206. }
  207. },
  208. fail: (err) => {
  209. console.log("compInfoPublish err", err);
  210. },
  211. });
  212. },
  213. getQrCodeWx() {
  214. this.qrCodeWx = process.env.OSS_URL + "#/pages/actManage/actDetail?compId=" + this.compId;
  215. },
  216. getQrCodeApp() {
  217. uni.request({
  218. url: apiCompQrCodeQuery,
  219. header: this.metadata,
  220. method: "POST",
  221. data: {
  222. compId: this.compId
  223. },
  224. success: (res) => {
  225. console.log("getQrCodeApp", res);
  226. if (checkResCode(res)) {
  227. const data = res.data.data;
  228. this.qrCodeApp = "url:" + data.qrCode;
  229. }
  230. },
  231. fail: (err) => {
  232. console.log("getQrCodeApp err", err);
  233. },
  234. });
  235. },
  236. // 重置APP二维码
  237. qrCodeAppReset() {
  238. uni.request({
  239. url: apiCompQrCodeReset,
  240. header: this.metadata,
  241. method: "POST",
  242. data: {
  243. compId: this.compId
  244. },
  245. success: (res) => {
  246. console.log("qrCodeAppReset", res);
  247. if (checkResCode(res)) {
  248. this.getQrCodeApp(); // 重新获取二维码
  249. uni.showToast({
  250. title: `二维码重置成功`,
  251. icon: 'none',
  252. duration: 3000
  253. });
  254. }
  255. },
  256. fail: (err) => {
  257. console.log("qrCodeAppReset err", err);
  258. },
  259. });
  260. },
  261. btnBack() {
  262. const url = "/pages/actManage/index";
  263. tools.appAction(url, "uni.switchTab");
  264. },
  265. btnActEdit() {
  266. this.queryObj.from = "actDetail";
  267. this.queryString = tools.objectToQueryString(this.queryObj);
  268. const url = '/pages/actCreate/actEdit?' + this.queryString;
  269. tools.appAction(url, "uni.navigateTo");
  270. },
  271. btnActPublish() {
  272. let that = this;
  273. uni.showModal({
  274. title: '提示',
  275. content: `赛事发布后将无法修改赛事内容\r\n您确定要继续吗?`,
  276. confirmText: '确定', //确定文本的文字
  277. cancelText: '取消', //确定文本的文字
  278. showCancel: true, //没有取消按钮的弹框
  279. success: function(res) {
  280. if (res.confirm) {
  281. that.compInfoPublish();
  282. } else if (res.cancel) {}
  283. }
  284. });
  285. },
  286. btnRankList() {
  287. const url = '/pages/actManage/rankList?' + this.queryString;
  288. tools.appAction(url, "uni.navigateTo");
  289. },
  290. btnTrack() {
  291. const url = '/pages/actManage/track?' + this.queryString;
  292. tools.appAction(url, "uni.navigateTo");
  293. },
  294. qrCodeReset() {
  295. let that = this;
  296. uni.showModal({
  297. title: '重置二维码',
  298. content: `重置后生成新码,旧码会失效\r\n您确定要继续吗?`,
  299. confirmText: '确定', //确定文本的文字
  300. cancelText: '取消', //确定文本的文字
  301. showCancel: true, //没有取消按钮的弹框
  302. success: function(res) {
  303. if (res.confirm) {
  304. that.qrCodeAppReset();
  305. } else if (res.cancel) {}
  306. }
  307. });
  308. },
  309. qrCodeWxComplete(res) {
  310. // console.log("[qrCodeWxComplete] res", res);
  311. this.$refs.qrCodeWx.toTempFilePath({
  312. success: (res) => {
  313. // console.log(res);
  314. this.imgQrCodeWx = res.tempFilePath;
  315. }
  316. });
  317. },
  318. qrCodeAppComplete(res) {
  319. // console.log("[qrCodeAppComplete] res", res);
  320. this.$refs.qrCodeApp.toTempFilePath({
  321. success: (res) => {
  322. // console.log(res);
  323. this.imgQrCodeApp = res.tempFilePath;
  324. }
  325. });
  326. }
  327. }
  328. }
  329. </script>
  330. <style scoped>
  331. .top {
  332. height: 170px;
  333. padding-top: 16px;
  334. flex-shrink: 0;
  335. background-repeat: no-repeat;
  336. background-size: cover;
  337. background-position: center;
  338. }
  339. .main {
  340. margin-bottom: 60px;
  341. overflow: scroll;
  342. }
  343. .compBox {
  344. width: 76%;
  345. margin-top: 20px;
  346. }
  347. .compName {
  348. width: 90%;
  349. font-size: 19px;
  350. font-weight: 500;
  351. text-align: center;
  352. }
  353. .comp_time {
  354. margin-top: 8px;
  355. font-size: 12px;
  356. font-weight: 400;
  357. color: #808080;
  358. }
  359. .introduce {
  360. width: 100%;
  361. margin-top: 12px;
  362. margin-bottom: 10px;
  363. align-items: flex-start;
  364. justify-content: space-around;
  365. }
  366. .introduce-title {
  367. color: #333333;
  368. font-size: 15px;
  369. line-height: 30px;
  370. font-family: Source Han Sans CN;
  371. }
  372. .introduce-content {
  373. color: #333333;
  374. font-size: 14px;
  375. line-height: 23px;
  376. font-family: Source Han Sans CN;
  377. }
  378. .activityRules {
  379. width: 100%;
  380. margin-top: 5px;
  381. margin-bottom: 10px;
  382. padding: 10px 15px;
  383. align-items: flex-start;
  384. justify-content: space-around;
  385. border-radius: 9px;
  386. background: #EBEBEB;
  387. }
  388. .activityRules-title {
  389. color: #333333;
  390. font-size: 14px;
  391. line-height: 25px;
  392. font-weight: 500;
  393. font-family: Source Han Sans CN;
  394. }
  395. .activityRules-content {
  396. color: #333333;
  397. font-size: 13px;
  398. line-height: 23px;
  399. font-family: Source Han Sans CN;
  400. }
  401. .bottom {
  402. position: fixed;
  403. bottom: 0;
  404. width: 100%;
  405. height: 40px;
  406. background-color: #ffffff;
  407. border-top: #E5E5E5 solid 1px;
  408. }
  409. .bottom-button {
  410. height: 30px;
  411. background: #FFB40B;
  412. font-size: 14px;
  413. font-weight: 400;
  414. line-height: 30px;
  415. }
  416. .qrImgBox {
  417. width: 90%;
  418. }
  419. .qrCode {
  420. visibility: hidden;
  421. }
  422. .imgQrCode {
  423. width: 120px;
  424. height: 120px;
  425. margin-top: 20px;
  426. margin-bottom: 6px;
  427. border: 2px solid;
  428. }
  429. .qrMemo {
  430. font-size: 12px;
  431. line-height: 18px;
  432. }
  433. .qrcodeBox {
  434. height: 0px;
  435. overflow: hidden;
  436. }
  437. </style>