index.vue 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692
  1. <template>
  2. <div class="page">
  3. <div class="page-top">
  4. <div class="top-tip-container">
  5. <transition name="fade">
  6. <div class="top-tip" v-show="showMobileStatus">{{ showMobile }} 已报名参赛!</div>
  7. </transition>
  8. </div>
  9. </div>
  10. <div class="page-content">
  11. <!-- 视频列表 -->
  12. <template v-if="videoList.length > 0">
  13. <div class="section-title">
  14. <div class="title">视频排名</div>
  15. <div class="more" @click="onMoreClick">
  16. <span>更多</span>
  17. <span class="iconfont icon-arrow-right"></span>
  18. </div>
  19. </div>
  20. <SimpleVideoList :list="videoList" @praise="onPraise" />
  21. </template>
  22. <!-- 活动介绍 -->
  23. <div class="section-title">
  24. <div class="title">活动介绍</div>
  25. </div>
  26. <div class="activity-content">
  27. <div class="title">赛事活动介绍</div>
  28. <dl>
  29. <dt><div>活动介绍</div></dt>
  30. <dd>采美平台和云进通在跨境物流领域达成战略合作,为广大采美客户提供轻松无忧的跨境体验!</dd>
  31. <dt><div>活动时间</div></dt>
  32. <dd>2022.10月10日——2022.12月31日</dd>
  33. <dt><div>活动奖励</div></dt>
  34. <dd>a、一等奖1000元;b、二等奖500元;c、三等奖300元</dd>
  35. <dt><div>参与方式</div></dt>
  36. <dd>
  37. 第一步:申请认证和上传相关资料可以登录ROSS官方网站或品牌授权的正品认证通入口申请;第二步:通过手机号码、机构
  38. 名称,注册账号;第三步:通过上传机构门头照片、营业地址等相关信息,进行机构认证;第四步:通过填写设备
  39. 相关名称、图片、相关购买凭证,进行设备认证。完成后登录上传视频且抖音分享成功即可!
  40. </dd>
  41. <dt><div>评奖规则</div></dt>
  42. <dd>用户登录商城注册成功后,按在规定的时间内完成点赞数最高的评定等级</dd>
  43. <dt><div>奖项公布</div></dt>
  44. <dd>用户在规定时间内完成后10个工作日将公布排名以及颁发奖品</dd>
  45. <dt><div>注意事项</div></dt>
  46. <dd>一个抖音账号只能参与一次</dd>
  47. </dl>
  48. </div>
  49. <div class="control">
  50. <div class="btn type1" @click="onToSingUp">点击报名参赛</div>
  51. <div class="btn type2" @click="onToUpload">上传抖音视频</div>
  52. </div>
  53. </div>
  54. <!-- 资质上传框 -->
  55. <GeneralDialog v-model="showDialog" title="上传营业执照" @confirm="onConfirm">
  56. <div class="general-content">
  57. <SimpleUploadImage @success="onImageSuccess" @remove="onImageRemove" :imageList="imageList" />
  58. <div class="tip">提示:请上传您的真实营业执照,以免影响 您的评奖结果!</div>
  59. </div>
  60. </GeneralDialog>
  61. <!-- 提示框 -->
  62. <GeneralDialog
  63. v-model="promptDialog"
  64. title="提示"
  65. :content="promptContent"
  66. :confirmText="promptConfirmText"
  67. @confirm="onPromptConfirm"
  68. ></GeneralDialog>
  69. </div>
  70. </template>
  71. <script>
  72. import { mapGetters } from 'vuex'
  73. export default {
  74. layout: 'app-ross',
  75. data() {
  76. const promptContentMap = {
  77. 0: '恭喜您,报名成功,请去上传您的抖音视频!',
  78. 1: '抱歉!活动还未开始,暂无法报名!',
  79. 2: '抱歉!活动已结束,暂无法报名!',
  80. 3: '抱歉!您已报名,请勿重复操作!',
  81. 4: '抱歉!请完善您的营业执照!',
  82. 5: '抱歉!您还未报名,请先报名后再来上传视频!',
  83. 6: '抱歉!活动还未开始,暂无法上传视频!',
  84. 7: '抱歉!活动已结束,暂无法上传视频!',
  85. }
  86. return {
  87. dialog: true,
  88. activityState: 0,
  89. videoList: [],
  90. // 用户报名状态
  91. signUpStatus: 0, // 0:未报名 1:已报名
  92. // 营业执照
  93. showDialog: false,
  94. imageList: [],
  95. qualificationUrl: '',
  96. // 提示框信息
  97. promptDialog: false,
  98. promptContentMap,
  99. promptStatus: -1,
  100. // 非认证机构报名提交资质报名表单
  101. formData: {
  102. mobile: '',
  103. licenseOssUrl: '',
  104. authUserId: '',
  105. licenseOssName: '',
  106. authId: '',
  107. },
  108. listQuery: {
  109. clubUserId: '',
  110. clubUserName: '',
  111. authUserId: '',
  112. pageNum: 1,
  113. pageSize: 12,
  114. status: 1,
  115. },
  116. // 参赛用户列表
  117. singInClubList: [],
  118. showMobile: '',
  119. showMobileStatus: false,
  120. }
  121. },
  122. computed: {
  123. ...mapGetters(['routePrefix', 'authUserId', 'accessToken', 'userInfo', 'authId']),
  124. // 提示框内容
  125. promptContent() {
  126. return this.promptContentMap[this.promptStatus]
  127. },
  128. // 确定按钮内容
  129. promptConfirmText() {
  130. return this.promptStatus === 2 ? '上传抖音视频' : '确定'
  131. },
  132. // 参赛机构手机号
  133. signInClubMobileList() {
  134. return this.singInClubList.map((item) => item.userName.replace(/^(\w{3})\w+(\w{4})$/, '$1****$2'))
  135. },
  136. },
  137. created() {
  138. this.fetchActivityStatus()
  139. this.fetchVideoList()
  140. this.fetchSignInClubList()
  141. },
  142. mounted() {
  143. // 分享当前页面
  144. this.initAppMessageShareData()
  145. },
  146. methods: {
  147. // 参赛机构手机号滚动
  148. mobileLoop() {
  149. if (this.signInClubMobileList.length > 0) {
  150. let i = 0
  151. this.showMobile = this.signInClubMobileList[i]
  152. this.showMobileStatus = true
  153. console.log('显示')
  154. setTimeout(() => {
  155. this.showMobileStatus = false
  156. console.log('隐藏')
  157. }, 1500)
  158. const timer = setInterval(() => {
  159. i++
  160. setTimeout(() => {
  161. this.showMobileStatus = false
  162. console.log('隐藏')
  163. }, 1500)
  164. if (i > this.signInClubMobileList.length - 1) {
  165. clearInterval(timer)
  166. console.log('结束')
  167. return
  168. }
  169. console.log('显示')
  170. this.showMobile = this.signInClubMobileList[i]
  171. this.showMobileStatus = true
  172. }, 2000)
  173. }
  174. },
  175. // 查看更多视频
  176. onMoreClick() {
  177. this.$router.push(`${this.routePrefix}/activity/challenge/list`)
  178. },
  179. // 点击报名
  180. onToSingUp() {
  181. // 活动未开启
  182. if (this.activityState === 0) {
  183. this.promptStatus = 1
  184. this.promptDialog = true
  185. return
  186. }
  187. // 活动已结束
  188. if (this.activityState === 2) {
  189. this.promptStatus = 2
  190. this.promptDialog = true
  191. return
  192. }
  193. // 未登录
  194. if (!this.accessToken) {
  195. this.$store.commit('app/SHOW_LOGIN')
  196. return
  197. }
  198. // 已经报名
  199. if (this.signUpStatus === 1) {
  200. this.promptStatus = 3
  201. this.promptDialog = true
  202. return
  203. }
  204. // 未认证机构
  205. if (!this.authId) {
  206. this.promptStatus = 4
  207. this.promptDialog = true
  208. return
  209. }
  210. // 已认证机构
  211. if (this.authId) {
  212. this.clubSignUpActivity()
  213. }
  214. },
  215. // 上传抖音视频
  216. onToUpload() {
  217. // 活动未开启
  218. if (this.activityState === 0) {
  219. this.promptStatus = 6
  220. this.promptDialog = true
  221. return
  222. }
  223. // 活动已结束
  224. if (this.activityState === 2) {
  225. this.promptStatus = 7
  226. this.promptDialog = true
  227. return
  228. }
  229. // 未登录
  230. if (!this.accessToken) {
  231. this.$store.commit('app/SHOW_LOGIN')
  232. return
  233. }
  234. // 未报名
  235. if (this.signUpStatus === 0) {
  236. this.promptDialog = true
  237. this.promptStatus = 5
  238. return
  239. }
  240. this.$router.push(`${this.routePrefix}/activity/challenge/publish`)
  241. },
  242. // 机构用户报名
  243. async clubSignUpActivity() {
  244. try {
  245. this.formData.mobile = this.userInfo.mobile
  246. this.formData.authUserId = this.authUserId
  247. this.formData.authId = this.userInfo.authId
  248. await this.$http.api.clubSignUpActivity(this.formData)
  249. // 报名成功
  250. this.promptStatus = 0
  251. this.signUpStatus = 1
  252. this.promptDialog = true
  253. } catch (error) {
  254. console.log(error)
  255. }
  256. },
  257. // 提示框确定事件
  258. onPromptConfirm() {
  259. this.promptDialog = false
  260. // 上传资质
  261. if (this.promptStatus === 4) {
  262. this.showDialog = true
  263. return
  264. }
  265. // 去上传抖音视频
  266. if (this.promptStatus === 0) {
  267. this.$router.push(`${this.routePrefix}/activity/challenge/publish`)
  268. return
  269. }
  270. },
  271. // 提交资质文件
  272. onConfirm() {
  273. this.showDialog = false
  274. this.clubSignUpActivity()
  275. },
  276. // 文件上传成功
  277. onImageSuccess({ response, fileList }) {
  278. this.imageList = fileList
  279. this.formData.licenseOssUrl = response.data
  280. },
  281. // 文件移除
  282. onImageRemove() {
  283. this.imageList = []
  284. this.formData.licenseOssUrl = ''
  285. },
  286. // 视频点赞
  287. async onPraise(video) {
  288. try {
  289. if (!this.accessToken) {
  290. this.$toast('请先登录')
  291. this.$store.commit('app/SHOW_LOGIN')
  292. return
  293. }
  294. const status = video.diggStatus === 0 ? 1 : 0
  295. const { clubUserId } = this.userInfo
  296. await this.$http.api.diggcountVideo({
  297. id: video.id,
  298. diggStatus: status,
  299. clubUserId,
  300. clubUserIds: video.clubUserIds,
  301. })
  302. video.diggStatus = status
  303. let tip = ''
  304. if (video.diggStatus === 0) {
  305. tip = '已取消点赞'
  306. video.diggCount--
  307. } else {
  308. tip = '点赞成功'
  309. video.diggCount++
  310. }
  311. this.$toast.success(tip)
  312. } catch (error) {
  313. console.log(error)
  314. }
  315. },
  316. // 获取视频列表
  317. async fetchVideoList() {
  318. try {
  319. this.listQuery.authUserId = this.authUserId
  320. this.listQuery.clubUserId = this.userInfo.clubUserId
  321. const res = await this.$http.api.fetchClubVideoList(this.listQuery)
  322. console.log(res)
  323. this.videoList = res.data.list
  324. } catch (error) {
  325. console.log(error)
  326. }
  327. },
  328. // 获取用户活动报名状态
  329. async fetchContestInfo() {
  330. try {
  331. const res = await this.$http.api.checkContestInfo({ mobile: this.userInfo.mobile })
  332. this.signUpStatus = res.data.contestStatus
  333. } catch (error) {
  334. console.log(error)
  335. }
  336. },
  337. // 获取参赛的用户
  338. async fetchSignInClubList() {
  339. try {
  340. const res = await this.$http.api.fetchEnteredClubList({ authUserId: this.authUserId })
  341. this.singInClubList = res.data
  342. this.mobileLoop()
  343. } catch (error) {
  344. console.log(error)
  345. }
  346. },
  347. // 获取活动状态
  348. async fetchActivityStatus() {
  349. try {
  350. const res = await this.$http.api.fetchActivityStatus({
  351. authUserId: this.authUserId,
  352. })
  353. if (!res.data) return
  354. this.activityState = res.data.activityState
  355. if (!this.accessToken) return
  356. this.fetchContestInfo()
  357. } catch (error) {
  358. console.log(error)
  359. }
  360. },
  361. // 分享当前页面
  362. initAppMessageShareData() {
  363. // 重试次数
  364. let retryCount = 1
  365. this.$wxReady((wx) => {
  366. //需在用户可能点击分享按钮前就先调用
  367. wx.updateAppMessageShareData({
  368. title: '认证通', // 分享标题
  369. desc: '您的好友邀请您一起来参与认证通挑战赛,赢大奖,快来参与吧!', // 分享描述
  370. link: window.location.href, // 分享链接,该链接域名或路径必须与当前页面对应的公众号 JS 安全域名一致
  371. imgUrl: window.location.origin + '/activity.png', // 分享图标
  372. fail: () => {
  373. if (retryCount === 0) return
  374. this.initAppMessageShareData()
  375. retryCount--
  376. },
  377. })
  378. })
  379. },
  380. },
  381. }
  382. </script>
  383. <style lang="scss" scoped>
  384. .fade-enter-active,
  385. .fade-leave-active {
  386. transition: opacity 0.5s;
  387. }
  388. .fade-enter, .fade-leave-to /* .fade-leave-active below version 2.1.8 */ {
  389. opacity: 0;
  390. }
  391. @media screen and (min-width: 768px) {
  392. .general-content {
  393. display: flex;
  394. flex-direction: column;
  395. align-items: center;
  396. .tip {
  397. width: 266px;
  398. margin: 0 auto;
  399. margin-top: 36px;
  400. line-height: 24px;
  401. font-size: 14px;
  402. color: #b2b2b2;
  403. text-align: center;
  404. }
  405. }
  406. .page {
  407. padding-bottom: 120px;
  408. background: #fff;
  409. .page-top {
  410. width: 100%;
  411. height: 530px;
  412. background: url(~assets/theme-images/ross/pc-banner-activity.png) no-repeat center;
  413. background-size: auto 530px;
  414. .top-tip-container {
  415. position: relative;
  416. width: 870px;
  417. margin: 0 auto;
  418. .top-tip {
  419. position: absolute;
  420. left: 0;
  421. top: 32px;
  422. width: 200px;
  423. height: 32px;
  424. background: rgba(0, 0, 0, 0.4);
  425. border-radius: 2px;
  426. font-size: 14px;
  427. color: #fff;
  428. text-align: center;
  429. line-height: 32px;
  430. }
  431. }
  432. }
  433. .page-content {
  434. width: 1196px;
  435. margin: 0 auto;
  436. .section-title {
  437. display: flex;
  438. justify-content: space-between;
  439. align-items: center;
  440. padding: 32px 0 16px;
  441. .title {
  442. font-size: 16px;
  443. font-weight: bold;
  444. color: #282828;
  445. }
  446. .more {
  447. font-size: 14px;
  448. color: #999;
  449. cursor: pointer;
  450. &:hover {
  451. color: #f3920d;
  452. }
  453. }
  454. }
  455. .activity-content {
  456. min-height: 1170px;
  457. .title {
  458. font-size: 40px;
  459. color: #333;
  460. height: 80px;
  461. box-sizing: border-box;
  462. text-align: center;
  463. margin-bottom: 70px;
  464. padding-top: 20px;
  465. font-weight: bold;
  466. background: url(~assets/theme-images/ross/pc_activity_title_01.png) no-repeat center;
  467. background-size: auto 80px;
  468. }
  469. dl {
  470. width: 872px;
  471. margin: 0 auto;
  472. dt {
  473. font-size: 30px;
  474. text-align: center;
  475. margin-bottom: 24px;
  476. div {
  477. line-height: 24px;
  478. display: inline-block;
  479. border-bottom: 5px;
  480. border-bottom-color: #ffd7c5;
  481. border-bottom-style: solid;
  482. }
  483. }
  484. dd {
  485. font-size: 16px;
  486. color: #666666;
  487. text-align: center;
  488. line-height: 32px;
  489. margin-bottom: 64px;
  490. }
  491. }
  492. }
  493. .control {
  494. .btn {
  495. width: 295px;
  496. height: 50px;
  497. line-height: 50px;
  498. font-size: 16px;
  499. text-align: center;
  500. margin: 16px auto 0;
  501. cursor: pointer;
  502. border-radius: 4px;
  503. &.type1 {
  504. background: #f3920d;
  505. color: #ffffff;
  506. }
  507. &.type2 {
  508. border: 1px solid #f3920d;
  509. box-sizing: border-box;
  510. line-height: 48px;
  511. color: #f3920d;
  512. }
  513. }
  514. }
  515. }
  516. }
  517. }
  518. @media screen and (max-width: 768px) {
  519. .general-content {
  520. display: flex;
  521. flex-direction: column;
  522. align-items: center;
  523. .tip {
  524. width: 57vw;
  525. margin: 0 auto;
  526. margin-top: 4.8vw;
  527. line-height: 5.6vw;
  528. font-size: 3.2vw;
  529. color: #b2b2b2;
  530. text-align: center;
  531. }
  532. }
  533. .page {
  534. padding-bottom: 10vw;
  535. .page-top {
  536. width: 100%;
  537. height: 100vw;
  538. background: url(~assets/theme-images/ross/h5-banner-activity.png) no-repeat center;
  539. background-size: auto 100vw;
  540. .top-tip-container {
  541. position: relative;
  542. width: 100%;
  543. margin: 0 auto;
  544. .top-tip {
  545. position: absolute;
  546. left: 4vw;
  547. top: 6.4vw;
  548. width: 46vw;
  549. height: 7.2vw;
  550. background: rgba(0, 0, 0, 0.4);
  551. border-radius: 0.2vw;
  552. font-size: 3.2vw;
  553. color: #fff;
  554. text-align: center;
  555. line-height: 7.2vw;
  556. }
  557. }
  558. }
  559. .page-content {
  560. width: 85.6vw;
  561. margin: 0 auto;
  562. margin-top: 3.2vw;
  563. .section-title {
  564. display: flex;
  565. justify-content: space-between;
  566. align-items: center;
  567. padding: 32px 0 16px;
  568. .title {
  569. font-size: 16px;
  570. font-weight: bold;
  571. color: #282828;
  572. }
  573. .more {
  574. font-size: 14px;
  575. color: #999;
  576. cursor: pointer;
  577. &:hover {
  578. color: #f3920d;
  579. }
  580. }
  581. }
  582. .activity-content {
  583. min-height: 116.3vw;
  584. margin-top: 8vw;
  585. .title {
  586. font-size: 5vw;
  587. color: #333;
  588. height: 9vw;
  589. box-sizing: border-box;
  590. text-align: center;
  591. margin-bottom: 8vw;
  592. padding-top: 2.4vw;
  593. font-weight: bold;
  594. background: url(~assets/theme-images/ross/h5_activity_title_01.png) no-repeat center;
  595. background-size: auto 9vw;
  596. }
  597. dl {
  598. dt {
  599. font-size: 4.8vw;
  600. text-align: center;
  601. margin-bottom: 4.8vw;
  602. div {
  603. line-height: 3.2vw;
  604. display: inline-block;
  605. border-bottom: 0.8vw;
  606. border-bottom-color: #ffd7c5;
  607. border-bottom-style: solid;
  608. }
  609. }
  610. dd {
  611. font-size: 3.4vw;
  612. color: #666666;
  613. text-align: center;
  614. line-height: 5.6vw;
  615. margin-bottom: 8.8vw;
  616. }
  617. }
  618. }
  619. .control {
  620. .btn {
  621. width: 85.5vw;
  622. height: 12vw;
  623. line-height: 12vw;
  624. font-size: 3.6vw;
  625. text-align: center;
  626. margin: 2.4vw auto 0;
  627. cursor: pointer;
  628. border-radius: 0.4vw;
  629. &.type1 {
  630. background: #f3920d;
  631. color: #ffffff;
  632. }
  633. &.type2 {
  634. border: 0.1vw solid #f3920d;
  635. box-sizing: border-box;
  636. line-height: 11.8vw;
  637. color: #f3920d;
  638. }
  639. }
  640. }
  641. }
  642. }
  643. }
  644. </style>