Pārlūkot izejas kodu

v1.7.5版本bug修改

yuwenjun1997 2 gadi atpakaļ
vecāks
revīzija
11d1a4b826

+ 2 - 2
.env.development

@@ -2,8 +2,8 @@
 EVN = 'development'
 
 # 网站地址
-LOCALHOSE = 'https://zp-b.caimei365.com'
-# LOCALHOSE = 'http://192.168.2.92:8888'
+# LOCALHOSE = 'https://zp-b.caimei365.com'
+LOCALHOSE = 'http://192.168.2.92:8888'
 
 # 接口api地址
 BASE_URL = 'https://zplma-b.caimei365.com'

+ 2 - 0
apis/index.js

@@ -3,6 +3,7 @@ import commonApi from './module/common'
 import userApi from './module/user'
 import docApi from './module/doc'
 import challengeApi from './module/challenge'
+import jssdkApi from './module/jssdk'
 
 export default ($axios) => {
   return {
@@ -11,5 +12,6 @@ export default ($axios) => {
     ...userApi($axios),
     ...docApi($axios),
     ...challengeApi($axios),
+    ...jssdkApi($axios),
   }
 }

+ 13 - 0
apis/module/jssdk.js

@@ -0,0 +1,13 @@
+export default ($axios) => {
+  // $axios.setBaseURL('https://api.weixin.qq.com')
+  const jssdkApis = {}
+  // 判断用户手机号是否绑定了机构信息
+  jssdkApis.getAccessToken = (params = {}) =>
+    $axios.get('https://api.weixin.qq.com/cgi-bin/token', { params })
+
+  // 判断用户手机号是否绑定了机构信息
+  jssdkApis.getTicket = (params = {}) =>
+    $axios.get('https://api.weixin.qq.com/cgi-bin/ticket/getticket', { params })
+
+  return jssdkApis
+}

BIN
assets/theme-images/ross/activity-entry-bg.png


BIN
assets/theme-images/ross/h5-banner-activity.png


BIN
assets/theme-images/ross/h5_activity_title_01.png


BIN
assets/theme-images/ross/h5_activity_title_02.png


BIN
assets/theme-images/ross/pc-banner-activity.png


BIN
assets/theme-images/ross/pc-link-entry-challenge-active.png


BIN
assets/theme-images/ross/pc_activity_title_01.png


BIN
assets/theme-images/ross/pc_activity_title_02.png


+ 62 - 2
components/SimpleVideoPlayer/index.vue

@@ -2,7 +2,14 @@
   <div class="simple-video-player">
     <van-popup v-model="show" position="center" :closeable="true">
       <div class="pupup-content">
-        <video :src="videoSrc" controls ref="video" class="video"></video>
+        <video
+          :src="videoSrc"
+          controls
+          ref="video"
+          class="video"
+          :style="{ height: videoHeight }"
+        ></video>
+        <div class="desc" v-if="description">{{ description }}</div>
       </div>
     </van-popup>
   </div>
@@ -15,12 +22,21 @@ export default {
       type: String,
       default: '',
     },
+    description: {
+      type: String,
+      default: '',
+    },
   },
   data() {
     return {
       show: false,
     }
   },
+  computed: {
+    videoHeight() {
+      return this.description ? '92vh' : '100vh'
+    },
+  },
   watch: {
     show(nVal) {
       this.$nextTick(() => {
@@ -37,14 +53,58 @@ export default {
 </script>
 
 <style scoped lang="scss">
+@mixin ellipsis($line: 1) {
+  overflow: hidden;
+  text-overflow: ellipsis;
+  display: -webkit-box;
+  -webkit-line-clamp: $line;
+  -webkit-box-orient: vertical;
+}
+
 .simple-video-player {
   .pupup-content {
+    position: relative;
     width: 100vw;
+    height: 100vh;
     background: #000;
   }
   .video {
     margin: 0 auto;
-    height: 100vh;
+    height: 92vh;
+  }
+
+  @media screen and (min-width: 768px) {
+    .desc {
+      position: absolute;
+      height: 48px;
+      left: 0;
+      bottom: 16px;
+      padding: 0 32px;
+      line-height: 24px;
+      font-size: 14px;
+      color: #fff;
+      box-sizing: border-box;
+      background: rgba(0, 0, 0, 0.5);
+      text-align: justify;
+      @include ellipsis(2);
+    }
+  }
+
+  @media screen and (max-width: 768px) {
+    .desc {
+      position: absolute;
+      height: 10.4vw;
+      left: 0;
+      bottom: 4vw;
+      padding: 0 4vw;
+      line-height: 5.2vw;
+      font-size: 3.2vw;
+      color: #fff;
+      box-sizing: border-box;
+      background: rgba(0, 0, 0, 0.5);
+      text-align: justify;
+      @include ellipsis(2);
+    }
   }
 }
 </style>

+ 5 - 0
configs/jssdk.js

@@ -0,0 +1,5 @@
+export const appId = 'wx6512b1dfb84c28e1'
+
+export const appSecret = '10f94918f59f630351319382bb29cab1'
+
+export const jsApiList = ['updateAppMessageShareData']

+ 3 - 1
layouts/app-ldm.vue

@@ -43,12 +43,14 @@ export default {
   },
   methods: {
     // 初始化数据页面公共数据
-    initPageData() {
+    async initPageData() {
       // this.$store.commit('app/SET_PAGE_THEME', 'app')
       // 获取用户信息
       let userInfo = this.$getStorage(this.routePrefix, 'userInfo')
       if (userInfo && userInfo.authUserId === this.authUserId) {
         this.$store.commit('user/SET_USER_INFO', userInfo)
+        const res = await this.$http.api.checkTokenResult()
+        this.$store.commit('user/SET_USER_INFO', res.data)
       }
       this.isMounted = true
     },

+ 3 - 1
layouts/app-normal.vue

@@ -161,12 +161,14 @@ export default {
     },
 
     // 初始化数据页面公共数据
-    initPageData() {
+    async initPageData() {
       this.$store.commit('app/SET_PAGE_THEME', 'normal')
       // 获取用户信息
       let userInfo = this.$getStorage(this.routePrefix, 'userInfo')
       if (userInfo && userInfo.authUserId === this.authUserId) {
         this.$store.commit('user/SET_USER_INFO', userInfo)
+        const res = await this.$http.api.checkTokenResult()
+        this.$store.commit('user/SET_USER_INFO', res.data)
       }
       this.isMounted = true
     },

+ 3 - 1
layouts/app-ph.vue

@@ -120,12 +120,14 @@ export default {
     },
 
     // 初始化数据页面公共数据
-    initPageData() {
+    async initPageData() {
       this.$store.commit('app/SET_PAGE_THEME', 'ph')
       // 获取用户信息
       let userInfo = this.$getStorage(this.routePrefix, 'userInfo')
       if (userInfo && userInfo.authUserId === this.authUserId) {
         this.$store.commit('user/SET_USER_INFO', userInfo)
+        const res = await this.$http.api.checkTokenResult()
+        this.$store.commit('user/SET_USER_INFO', res.data)
       }
       this.isMounted = true
     },

+ 41 - 5
layouts/app-ross.vue

@@ -87,6 +87,7 @@
 
 <script>
 import { mapGetters } from 'vuex'
+import { isWeChat } from '~/utils/validator'
 export default {
   computed: {
     ...mapGetters([
@@ -100,6 +101,7 @@ export default {
       'showHeader',
       'showFooter',
       'supplierInfo',
+      'wxConfig',
     ]),
     themeClass() {
       return `theme-${this.themeName}`
@@ -156,13 +158,42 @@ export default {
   mounted() {
     this.responseWidth()
     this.initPageData()
-    // this.checkAccountType()
+    this.initAppMessageShareData()
+  },
+  watch: {
+    $route: {
+      handler: function () {
+        setTimeout(() => {
+          this.$nextTick(this.initAppMessageShareData)
+        }, 1000)
+      },
+      deep: true,
+    },
   },
   beforeDestroy() {
     window.removeEventListener('resize', () => {})
     this.refreshCacheData()
   },
   methods: {
+    // 全局分享事件
+    initAppMessageShareData() {
+      // 判断是否为微信浏览器环境
+      // if (!isWeChat()) return
+      // 网站主机地址
+      const HOST = process.env.LOCALHOSE
+      this.$wxReady((wx) => {
+        //需在用户可能点击分享按钮前就先调用
+        wx.updateAppMessageShareData({
+          title: '认证通', // 分享标题
+          desc: '一款专业的正品认证软件系统', // 分享描述
+          link: HOST + this.routePrefix, // 分享链接,该链接域名或路径必须与当前页面对应的公众号 JS 安全域名一致
+          imgUrl: HOST + '/share-icon.png', // 分享图标
+          success: function () {
+            // 设置成功
+          },
+        })
+      })
+    },
     // 跳转
     onJumpTo(item) {
       this.drawer = false
@@ -189,12 +220,14 @@ export default {
     },
 
     // 初始化数据页面公共数据
-    initPageData() {
+    async initPageData() {
       this.$store.commit('app/SET_PAGE_THEME', 'ross')
       // 获取用户信息
       let userInfo = this.$getStorage(this.routePrefix, 'userInfo')
       if (userInfo && userInfo.authUserId === this.authUserId) {
         this.$store.commit('user/SET_USER_INFO', userInfo)
+        const res = await this.$http.api.checkTokenResult()
+        this.$store.commit('user/SET_USER_INFO', res.data)
       }
       this.isMounted = true
     },
@@ -338,9 +371,9 @@ export default {
               &.icon-feedback {
                 background-image: url(~assets/theme-images/ross/pc-link-entry-feedback-active.png);
               }
-              // &.icon-challenge {
-              //   // background-image: url(~assets/theme-images/ross/pc-link-entry-challenge-active.png);
-              // }
+              &.icon-challenge {
+                background-image: url(~assets/theme-images/ross/pc-link-entry-challenge-active.png);
+              }
             }
           }
         }
@@ -649,6 +682,9 @@ export default {
         &.icon-feedback {
           background-image: url(~assets/theme-images/ross/h5-link-entry-feedback-active.png);
         }
+        &.icon-challenge {
+          background-image: url(~assets/theme-images/ross/h5-link-entry-challenge.png);
+        }
       }
       .text {
         font-size: 3.4vw;

+ 4 - 0
nuxt.config.js

@@ -36,6 +36,9 @@ export default {
       {
         src: 'https://api.map.baidu.com/api?v=2.0&&type=webgl&ak=9kNcqnkFxlS0Kv9jEbDgwG2BAMrD6wPb',
       },
+      {
+        src: 'https://res.wx.qq.com/open/js/jweixin-1.6.0.js',
+      },
     ],
   },
 
@@ -56,6 +59,7 @@ export default {
     '~/plugins/axios',
     '~/plugins/vue-filters',
     '~/plugins/storage',
+    '~/plugins/jssdk',
   ],
 
   // Auto import components: https://go.nuxtjs.dev/config-components

+ 62 - 0
package-lock.json

@@ -17,7 +17,9 @@
         "element-ui": "^2.15.9",
         "jquery": "^3.6.0",
         "js-cookie": "^3.0.1",
+        "moment": "^2.29.4",
         "nuxt": "^2.15.8",
+        "sha1": "^1.1.1",
         "swiper": "^5.4.5",
         "three-dots": "^0.2.3",
         "uuid": "^9.0.0",
@@ -5342,6 +5344,14 @@
       "resolved": "https://registry.npmmirror.com/chardet/-/chardet-0.7.0.tgz",
       "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA=="
     },
+    "node_modules/charenc": {
+      "version": "0.0.2",
+      "resolved": "https://registry.npmmirror.com/charenc/-/charenc-0.0.2.tgz",
+      "integrity": "sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA==",
+      "engines": {
+        "node": "*"
+      }
+    },
     "node_modules/chokidar": {
       "version": "3.5.3",
       "resolved": "https://registry.npmmirror.com/chokidar/-/chokidar-3.5.3.tgz",
@@ -6006,6 +6016,14 @@
         "node": ">= 8"
       }
     },
+    "node_modules/crypt": {
+      "version": "0.0.2",
+      "resolved": "https://registry.npmmirror.com/crypt/-/crypt-0.0.2.tgz",
+      "integrity": "sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow==",
+      "engines": {
+        "node": "*"
+      }
+    },
     "node_modules/crypto-browserify": {
       "version": "3.12.0",
       "resolved": "https://registry.npmmirror.com/crypto-browserify/-/crypto-browserify-3.12.0.tgz",
@@ -11231,6 +11249,14 @@
         "node": ">=6"
       }
     },
+    "node_modules/moment": {
+      "version": "2.29.4",
+      "resolved": "https://registry.npmmirror.com/moment/-/moment-2.29.4.tgz",
+      "integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==",
+      "engines": {
+        "node": "*"
+      }
+    },
     "node_modules/move-concurrently": {
       "version": "1.0.1",
       "resolved": "https://registry.npmmirror.com/move-concurrently/-/move-concurrently-1.0.1.tgz",
@@ -16819,6 +16845,18 @@
         "sha.js": "bin.js"
       }
     },
+    "node_modules/sha1": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmmirror.com/sha1/-/sha1-1.1.1.tgz",
+      "integrity": "sha512-dZBS6OrMjtgVkopB1Gmo4RQCDKiZsqcpAQpkV/aaj+FCrCg8r4I4qMkDPQjBgLIxlmu9k4nUbWq6ohXahOneYA==",
+      "dependencies": {
+        "charenc": ">= 0.0.1",
+        "crypt": ">= 0.0.1"
+      },
+      "engines": {
+        "node": "*"
+      }
+    },
     "node_modules/shebang-command": {
       "version": "2.0.0",
       "resolved": "https://registry.npmmirror.com/shebang-command/-/shebang-command-2.0.0.tgz",
@@ -24106,6 +24144,11 @@
       "resolved": "https://registry.npmmirror.com/chardet/-/chardet-0.7.0.tgz",
       "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA=="
     },
+    "charenc": {
+      "version": "0.0.2",
+      "resolved": "https://registry.npmmirror.com/charenc/-/charenc-0.0.2.tgz",
+      "integrity": "sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA=="
+    },
     "chokidar": {
       "version": "3.5.3",
       "resolved": "https://registry.npmmirror.com/chokidar/-/chokidar-3.5.3.tgz",
@@ -24674,6 +24717,11 @@
         "which": "^2.0.1"
       }
     },
+    "crypt": {
+      "version": "0.0.2",
+      "resolved": "https://registry.npmmirror.com/crypt/-/crypt-0.0.2.tgz",
+      "integrity": "sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow=="
+    },
     "crypto-browserify": {
       "version": "3.12.0",
       "resolved": "https://registry.npmmirror.com/crypto-browserify/-/crypto-browserify-3.12.0.tgz",
@@ -28886,6 +28934,11 @@
       "integrity": "sha512-2lMlY1Yc1+CUy0gw4H95uNN7vjbpoED7NNRSBHE25nWfLBdmMzFCsPshlzbxHz+gYMcBEUN8V4pU16prcdPSgA==",
       "dev": true
     },
+    "moment": {
+      "version": "2.29.4",
+      "resolved": "https://registry.npmmirror.com/moment/-/moment-2.29.4.tgz",
+      "integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w=="
+    },
     "move-concurrently": {
       "version": "1.0.1",
       "resolved": "https://registry.npmmirror.com/move-concurrently/-/move-concurrently-1.0.1.tgz",
@@ -33473,6 +33526,15 @@
         "safe-buffer": "^5.0.1"
       }
     },
+    "sha1": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmmirror.com/sha1/-/sha1-1.1.1.tgz",
+      "integrity": "sha512-dZBS6OrMjtgVkopB1Gmo4RQCDKiZsqcpAQpkV/aaj+FCrCg8r4I4qMkDPQjBgLIxlmu9k4nUbWq6ohXahOneYA==",
+      "requires": {
+        "charenc": ">= 0.0.1",
+        "crypt": ">= 0.0.1"
+      }
+    },
     "shebang-command": {
       "version": "2.0.0",
       "resolved": "https://registry.npmmirror.com/shebang-command/-/shebang-command-2.0.0.tgz",

+ 2 - 0
package.json

@@ -23,7 +23,9 @@
     "element-ui": "^2.15.9",
     "jquery": "^3.6.0",
     "js-cookie": "^3.0.1",
+    "moment": "^2.29.4",
     "nuxt": "^2.15.8",
+    "sha1": "^1.1.1",
     "swiper": "^5.4.5",
     "three-dots": "^0.2.3",
     "uuid": "^9.0.0",

+ 159 - 24
pages/_template/ross/activity/challenge/index.vue

@@ -2,14 +2,40 @@
   <div class="page">
     <div class="page-top"></div>
     <div class="page-content">
-      <div class="content"></div>
+      <div class="content">
+        <div class="title">赛事活动介绍</div>
+        <dl>
+          <dt><div>活动介绍</div></dt>
+          <dd>
+            采美平台和云进通在跨境物流领域达成战略合作,为广大采美客户提供轻松无忧的跨境体验!
+          </dd>
+          <dt><div>活动时间</div></dt>
+          <dd>2022.10月10日——2022.12月31日</dd>
+          <dt><div>活动奖励</div></dt>
+          <dd>a、一等奖1000元;b、二等奖500元;c、三等奖300元</dd>
+          <dt><div>参与方式</div></dt>
+          <dd>
+            第一步:申请认证和上传相关资料可以登录ROSS官方网站或品牌授权的正品认证通入口申请;第二步:通过手机号码、机构
+            名称,注册账号;第三步:通过上传机构门头照片、营业地址等相关信息,进行机构认证;第四步:通过填写设备
+            相关名称、图片、相关购买凭证,进行设备认证。完成后登录上传视频且抖音分享成功即可!
+          </dd>
+          <dt><div>评奖规则</div></dt>
+          <dd>
+            用户登录商城注册成功后,按在规定的时间内完成点赞数最高的评定等级
+          </dd>
+          <dt><div>奖项公布</div></dt>
+          <dd>用户在规定时间内完成后10个工作日将公布排名以及颁发奖品</dd>
+          <dt><div>注意事项</div></dt>
+          <dd>一个抖音账号只能参与一次</dd>
+        </dl>
+      </div>
       <div class="entry">
         <div class="title">活动入口</div>
         <div class="list">
           <div class="cover" @click="toDetail">
-            <span class="status" :class="activity.type">{{
-              activity.text
-            }}</span>
+            <span class="status" :class="activity.type">
+              {{ activity.text }}
+            </span>
           </div>
         </div>
       </div>
@@ -28,6 +54,7 @@ export default {
   },
   computed: {
     ...mapGetters(['routePrefix', 'authUserId']),
+    // 活动状态
     activity() {
       const result = {
         2: { type: 'end', text: '已结束' },
@@ -40,15 +67,28 @@ export default {
   created() {
     this.fetchActivityStatus()
   },
+  mounted() {
+    this.$wxReady((wx) => {
+      //需在用户可能点击分享按钮前就先调用
+      wx.updateAppMessageShareData({
+        title: '认证通', // 分享标题
+        desc: '您的好友邀请您一起来参与认证通挑战赛,赢大奖,快来参与吧!', // 分享描述
+        link: window.location.href, // 分享链接,该链接域名或路径必须与当前页面对应的公众号 JS 安全域名一致
+        imgUrl: window.location.origin + '/activity.png', // 分享图标
+        success: function () {
+          // 设置成功
+        },
+      })
+    })
+  },
   methods: {
+    // 活动详情
     toDetail() {
-      if (this.activityState !== 1) {
-        this.$toast(`活动${this.activity.text}`)
-        return
-      }
       const url = `${this.routePrefix}/activity/challenge/list`
       this.$router.push(url)
     },
+
+    // 获取活动状态
     async fetchActivityStatus() {
       try {
         const res = await this.$http.api.fetchActivityStatus({
@@ -67,31 +107,76 @@ export default {
 <style lang="scss" scoped>
 @media screen and (min-width: 768px) {
   .page {
-    padding-bottom: 269px;
+    padding-bottom: 120px;
+    background: #fff;
     .page-top {
       width: 100%;
       height: 530px;
-      background-position: center;
-      background: #ddd;
+      background: url(~assets/theme-images/ross/pc-banner-activity.png)
+        no-repeat center;
+      background-size: auto 530px;
     }
 
     .page-content {
-      width: 1200px;
+      width: 872px;
       margin: 0 auto;
       margin-top: 16px;
 
       .content {
         min-height: 1170px;
-        background: #fff5e8;
+
+        .title {
+          font-size: 40px;
+          color: #333;
+          height: 80px;
+          box-sizing: border-box;
+          text-align: center;
+          margin-bottom: 70px;
+          padding-top: 20px;
+          font-weight: bold;
+          background: url(~assets/theme-images/ross/pc_activity_title_01.png)
+            no-repeat center;
+          background-size: auto 80px;
+        }
+
+        dl {
+          dt {
+            font-size: 30px;
+            text-align: center;
+            margin-bottom: 24px;
+
+            div {
+              line-height: 24px;
+              display: inline-block;
+              border-bottom: 5px;
+              border-bottom-color: #ffd7c5;
+              border-bottom-style: solid;
+            }
+          }
+          dd {
+            font-size: 16px;
+            color: #666666;
+            text-align: center;
+            line-height: 32px;
+            margin-bottom: 64px;
+          }
+        }
       }
 
       .entry {
+        margin-top: 120px;
         .title {
-          font-size: 24px;
+          font-size: 40px;
+          color: #333;
+          height: 80px;
+          box-sizing: border-box;
           text-align: center;
+          margin-bottom: 70px;
+          padding-top: 20px;
           font-weight: bold;
-          color: #282828;
-          margin: 85px 0 48px;
+          background: url(~assets/theme-images/ross/pc_activity_title_02.png)
+            no-repeat center;
+          background-size: auto 80px;
         }
 
         .cover {
@@ -99,8 +184,10 @@ export default {
           width: 856px;
           height: 340px;
           margin: 0 auto;
-          background: pink;
           cursor: pointer;
+          background: url(~assets/theme-images/ross/activity-entry-bg.png)
+            no-repeat center;
+          background-size: 856px 340px;
 
           .status {
             position: absolute;
@@ -135,8 +222,9 @@ export default {
     .page-top {
       width: 100%;
       height: 100vw;
-      background-position: center;
-      background: #ddd;
+      background: url(~assets/theme-images/ross/h5-banner-activity.png)
+        no-repeat center;
+      background-size: auto 100vw;
     }
 
     .page-content {
@@ -146,16 +234,60 @@ export default {
 
       .content {
         min-height: 116.3vw;
-        background: #fff5e8;
+        margin-top: 8vw;
+
+        .title {
+          font-size: 5vw;
+          color: #333;
+          height: 9vw;
+          box-sizing: border-box;
+          text-align: center;
+          margin-bottom: 8vw;
+          padding-top: 2.4vw;
+          font-weight: bold;
+          background: url(~assets/theme-images/ross/h5_activity_title_01.png)
+            no-repeat center;
+          background-size: auto 9vw;
+        }
+
+        dl {
+          dt {
+            font-size: 4.8vw;
+            text-align: center;
+            margin-bottom: 4.8vw;
+
+            div {
+              line-height: 3.2vw;
+              display: inline-block;
+              border-bottom: 0.8vw;
+              border-bottom-color: #ffd7c5;
+              border-bottom-style: solid;
+            }
+          }
+          dd {
+            font-size: 3.4vw;
+            color: #666666;
+            text-align: center;
+            line-height: 5.6vw;
+            margin-bottom: 8.8vw;
+          }
+        }
       }
 
       .entry {
+        margin-top: 15vw;
         .title {
-          font-size: 4.2vw;
+          font-size: 5vw;
+          color: #333;
+          height: 9vw;
+          box-sizing: border-box;
           text-align: center;
+          margin-bottom: 8vw;
+          padding-top: 2.4vw;
           font-weight: bold;
-          color: #282828;
-          margin: 7.2vw 0 4.3vw;
+          background: url(~assets/theme-images/ross/h5_activity_title_02.png)
+            no-repeat center;
+          background-size: auto 9vw;
         }
 
         .cover {
@@ -163,8 +295,11 @@ export default {
           width: 85.6vw;
           height: 34vw;
           margin: 0 auto;
-          background: pink;
+          // background: pink;
           cursor: pointer;
+          background: url(~assets/theme-images/ross/activity-entry-bg.png)
+            no-repeat center;
+          background-size: 85.6vw 34vw;
 
           .status {
             position: absolute;

+ 157 - 85
pages/_template/ross/activity/challenge/list.vue

@@ -1,82 +1,92 @@
 <template>
   <div class="page">
-    <div class="page-top"></div>
-    <div class="page-content">
-      <div class="control">
-        <div class="search">
-          <el-input
-            placeholder="搜索登录账户后四位或所属机构"
-            @keyup.enter="getList"
-            v-model="listQuery.clubUserName"
-          >
-            <i slot="prefix" class="el-input__icon el-icon-search"></i>
-          </el-input>
+    <van-list
+      v-model="loadingMore"
+      :finished="finished"
+      :immediate-check="false"
+      :finished-text="total ? '没有更多了' : ''"
+      @load="fetchVideoList"
+    >
+      <div class="page-top"></div>
+      <div class="page-content">
+        <!-- 操作区域 -->
+        <div class="control">
+          <div class="search">
+            <el-input
+              placeholder="搜索登录账户后四位或所属机构"
+              @keyup.enter.native="getList"
+              v-model="listQuery.clubUserName"
+              clearable
+              @clear="getList"
+            >
+              <i slot="prefix" class="el-input__icon el-icon-search"></i>
+            </el-input>
+          </div>
+          <div class="publish" @click="onPublish">发布视频</div>
         </div>
-        <div class="publish" @click="onPublish">发布视频</div>
-      </div>
-      <div class="video-content">
-        <div class="title">视频排名</div>
-        <div class="video-list">
-          <div
-            class="video"
-            v-for="(item, index) in list"
-            :key="index"
-            @click="onPlay(item)"
-          >
-            <div class="cover">
-              <img :src="item.cover" alt="" />
-              <div class="name">{{ item.title }}</div>
-              <div class="rank" :class="'rank-0' + (index + 1)">
-                {{ index + 1 }}
+        <!-- 视频列表区域 -->
+        <div class="video-content">
+          <div class="title">视频排名</div>
+          <div class="video-list">
+            <div
+              class="video"
+              v-for="(item, index) in list"
+              :key="index"
+              @click="onPlay(item)"
+            >
+              <div class="cover">
+                <img :src="item.cover" alt="" />
+                <div class="name">{{ item.title }}</div>
+                <div class="rank" :class="'rank-0' + (index + 1)">
+                  {{ index + 1 }}
+                </div>
+                <div class="play" @click="onPlay(item)"></div>
+              </div>
+              <div class="info">
+                <div class="club-name">{{ item.authParty }}</div>
+                <div class="mobile">{{ item.userName | mobileFormat }}</div>
+              </div>
+              <div class="foot">
+                <div class="date">{{ item.releaseTime | dateFormat }}</div>
+                <div class="praise">{{ item.diggCount }}</div>
+                <div class="pv">{{ item.diggCount }}</div>
               </div>
-              <div class="play" @click="onPlay(item)"></div>
-            </div>
-            <div class="info">
-              <div class="club-name">{{ item.authParty }}</div>
-              <div class="mobile">{{ item.userName | mobileFormat }}</div>
-            </div>
-            <div class="foot">
-              <div class="date">{{ item.releaseTime | dateFormat }}</div>
-              <div class="praise">{{ item.diggCount }}</div>
-              <div class="pv">{{ item.diggCount }}</div>
             </div>
           </div>
+          <!-- 列表为空 -->
+          <SimpleEmpty
+            v-if="!total && !isRequest"
+            name="icon-empty-video.png"
+            description="暂无视频~"
+          ></SimpleEmpty>
         </div>
-        <!-- 列表为空 -->
-        <SimpleEmpty
-          v-if="!total"
-          name="icon-empty-video.png"
-          description="敬请期待~"
-        ></SimpleEmpty>
-
-        <SimpleDialog
-          v-model="dialog"
-          :confirmText="dialogOption.confirmText"
-          :description="dialogOption.description"
-          :cancel="dialogOption.cancel"
-          @confirm="onConfirm"
-          @cancel="onCancel"
-        ></SimpleDialog>
-
-        <SimpleVideoPlayer
-          :videoSrc="videoUrl"
-          ref="videoPlayer"
-        ></SimpleVideoPlayer>
       </div>
-    </div>
+    </van-list>
+
+    <div class="publish" @click="onPublish">发布视频</div>
+
+    <!-- 发布提示对话框 -->
+    <SimpleDialog
+      v-model="dialog"
+      :confirmText="dialogOption.confirmText"
+      :description="dialogOption.description"
+      :cancel="dialogOption.cancel"
+      @confirm="onConfirm"
+      @cancel="onCancel"
+    ></SimpleDialog>
+
+    <!-- 视频播放组件 -->
+    <SimpleVideoPlayer
+      :videoSrc="videoUrl"
+      :description="description"
+      ref="videoPlayer"
+    ></SimpleVideoPlayer>
   </div>
 </template>
 
 <script>
-/**
- * 抱歉,活动已结束,暂无法发布视频!
- * 抱歉,由于您未认证机构,无法参与!
- * 抱歉,平台规定每个用户只能发布一个视频,由于您已发布过视频,请勿再次发布!
- *
- * 确认证
- */
-
 import { mapGetters } from 'vuex'
+import { debounce } from '~/utils'
 export default {
   layout: 'app-ross',
   filters: {
@@ -86,10 +96,13 @@ export default {
   },
   data() {
     return {
+      isRequest: true,
+      finished: true, // 列表加载是否完毕(加载完了所有数据)
+      loadingMore: false, // 是否正在加载
       listQuery: {
         clubUserName: '',
         pageNum: 1,
-        pageSize: 10,
+        pageSize: 20,
         status: 1,
       },
       list: [],
@@ -100,37 +113,54 @@ export default {
         description: '抱歉,活动已结束,暂无法发布视频!',
         cancel: false,
       },
-      publishStatus: {},
       publishInfo: {},
       videoUrl: '',
+      description: '',
     }
   },
   computed: {
     ...mapGetters(['routePrefix', 'accessToken', 'userInfo', 'authUserId']),
   },
   created() {
-    this.checkActivityPublish()
     this.getList()
   },
+  beforeDestroy() {
+    this.$toast.clear()
+  },
   methods: {
     // 获取列表
     getList() {
+      this.$toast.loading({
+        message: '正在获取视频列表...',
+        duration: 0,
+      })
       this.listQuery.pageNum = 1
+      this.isRequest = true
       this.list = []
       this.fetchVideoList()
     },
+
     // 获取视频列表
-    async fetchVideoList() {
+    fetchVideoList: debounce(async function () {
       try {
+        this.loadingMore = true
+        this.isRequest = true
         this.listQuery.authUserId = this.authUserId
         const res = await this.$http.api.fetchVideoList(this.listQuery)
-        this.list = res.data.list
+        this.list = [...this.list, ...res.data.list]
         this.total = res.data.total
         this.listQuery.pageNum++
+        this.finished = !res.data.hasNextPage
+        this.loadingMore = false
+        this.isRequest = false
       } catch (error) {
         console.log(error)
+      } finally {
+        this.$toast.clear()
       }
-    },
+    }, 500),
+
+    // 提示框确定
     onConfirm() {
       this.dialog = false
       if (this.dialogOption.confirmText === '去认证') {
@@ -138,34 +168,40 @@ export default {
         this.$router.push(path)
       }
     },
+
+    // 提示框取消
     onCancel() {
       this.dialog = false
     },
+
     // 去发布视频
-    onPublish() {
+    async onPublish() {
       if (!this.accessToken) {
         this.$toast('请先登录')
         this.formType = 'login'
         this.$store.commit('app/SHOW_LOGIN')
         return
       }
+
       if (!this.userInfo.authId) {
         this.dialogOption.description = '抱歉,由于您未认证机构,无法参与!'
         this.dialogOption.confirmText = '去认证'
         this.dialog = true
         return
       }
+
+      // 查询活动状态
+      await this.checkActivityPublish()
+
       if (this.publishInfo.activityState === 0) {
         this.dialogOption.description = '抱歉,活动未开始!'
         this.dialog = true
         return
-      }
-      if (this.publishInfo.activityState === 2) {
+      } else if (this.publishInfo.activityState === 2) {
         this.dialogOption.description = '抱歉,活动已结束,暂无法发布视频!'
         this.dialog = true
         return
-      }
-      if (this.publishInfo.releaseStatus === 1) {
+      } else if (this.publishInfo.releaseStatus === 1) {
         this.dialogOption.description =
           '抱歉,平台规定每个用户只能发布一个视频,由于您已发布过视频,请勿再次发布!'
         this.dialog = true
@@ -174,12 +210,14 @@ export default {
       const url = `${this.routePrefix}/activity/challenge/publish`
       this.$router.push(url)
     },
+
     // 验证发布状态
     async checkActivityPublish() {
       if (!this.accessToken) return
       const { authId, mobile } = this.userInfo
       try {
         const res = await this.$http.api.checkActivityPublish({
+          authUserId: this.authUserId,
           authId,
           userName: mobile,
         })
@@ -188,9 +226,11 @@ export default {
         console.log(error)
       }
     },
+
     // 播放视频
     onPlay(row) {
       this.videoUrl = row.ossUrl
+      this.description = row.title
       this.$refs.videoPlayer.open()
     },
   },
@@ -206,27 +246,41 @@ export default {
   -webkit-box-orient: vertical;
 }
 
+::v-deep {
+  .el-input.is-active .el-input__inner,
+  .el-input__inner:focus {
+    border-color: #f3920d;
+  }
+}
+
 @media screen and (min-width: 768px) {
   .page {
     background: #fff;
     min-height: calc(100vh - 80px - 80px);
+    padding-bottom: 20px;
+
     .page-top {
       width: 100%;
       height: 530px;
-      background-position: center;
-      background: #ddd;
+      background: url(~assets/theme-images/ross/pc-banner-activity.png)
+        no-repeat center;
+      background-size: auto 530px;
+    }
+
+    .publish {
+      display: none;
     }
 
     .page-content {
       width: 1200px;
       margin: 0 auto;
-      padding-bottom: 80px;
 
       .control {
         display: flex;
         align-items: center;
         padding: 32px 0;
         .publish {
+          display: block;
           width: 120px;
           height: 46px;
           text-align: center;
@@ -479,17 +533,35 @@ export default {
 @media screen and (max-width: 768px) {
   .page {
     background: #fff;
+    position: relative;
+    position: relative;
+    // padding-bottom: 20vw;
     .page-top {
       width: 100%;
       height: 100vw;
-      background-position: center;
-      background: #ddd;
+      background: url(~assets/theme-images/ross/h5-banner-activity.png)
+        no-repeat center;
+      background-size: auto 100vw;
+    }
+
+    .publish {
+      // position: fixed;
+      // bottom: 14vw;
+      // left: 7.4vw;
+      width: 85.6vw;
+      margin: 4vw auto;
+      height: 12vw;
+      background: #f3920d;
+      color: #fff;
+      text-align: center;
+      font-size: 3.6vw;
+      line-height: 12vw;
     }
 
     .page-content {
+      position: relative;
       width: 93.6vw;
       margin: 0 auto;
-      padding-bottom: 6.5vw;
 
       .control {
         display: flex;
@@ -498,7 +570,6 @@ export default {
         .publish {
           display: none;
         }
-
         .search {
           flex: 1;
           flex-shrink: 0;
@@ -558,7 +629,7 @@ export default {
               img {
                 display: block;
                 width: 100%;
-                height: 100%;
+                height: 31.3vw;
               }
 
               &::after {
@@ -597,6 +668,7 @@ export default {
                 text-align: center;
                 width: 100%;
                 line-height: 6.4vw;
+                height: 6.4vw;
                 @include ellipsis(1);
                 box-sizing: border-box;
                 padding: 0 1.2vw;

+ 3 - 1
pages/_template/ross/activity/challenge/message.vue

@@ -23,6 +23,7 @@ export default {
     ...mapGetters(['routePrefix']),
   },
   methods: {
+    // 返回
     onBack() {
       const path = `${this.routePrefix}/activity/challenge`
       this.$router.push(path)
@@ -126,7 +127,8 @@ export default {
     text-align: center;
     line-height: 12vw;
     font-size: 3.6vw;
-    margin-top: 25.9vw;
+    margin-top: 24vw;
+    margin-bottom: 24vw;
   }
 }
 </style>

+ 26 - 4
pages/_template/ross/activity/challenge/publish.vue

@@ -2,10 +2,10 @@
   <div class="page">
     <div class="page-content">
       <el-form label-position="top" :model="formData" :rules="rules" ref="form">
-        <el-form-item label="发布抖音视:" prop="description">
+        <el-form-item label="发布抖音视:" prop="description">
           <el-input
             type="textarea"
-            rows="6"
+            rows="10"
             v-model="formData.description"
             placeholder="添加作品描述,能让更多的人看到..."
             maxlength="300"
@@ -19,6 +19,7 @@
               :limit="1"
               :image-list="coverList"
               :before-upload="beforeCoverImageUpload"
+              tip="建议尺寸 286 * 198px"
               @success="uploadCoverImageSuccess"
               @remove="handleCoverImageRemove"
             ></SimpleUploadImage>
@@ -40,7 +41,7 @@
         </div>
       </div>
       <div class="control">
-        <div class="button cancel">取消</div>
+        <div class="button cancel" @click="onBack">取消</div>
         <div class="button publish" @click="onPublish">发布</div>
       </div>
     </div>
@@ -54,7 +55,7 @@ export default {
   data() {
     return {
       formData: {
-        coverImage: '111',
+        coverImage: '',
         fileUrl: '',
         description: '',
         ossName: '',
@@ -117,6 +118,7 @@ export default {
         console.log(error)
       }
     },
+
     // 视频封面上传
     beforeCoverImageUpload(file) {
       const flag = file.size / 1024 / 1024 < 5
@@ -133,11 +135,17 @@ export default {
       this.coverList = []
       this.formData.coverImage = ''
     },
+
     // 视频上传成功
     onVideoUploadSuccess({ file, fileList }) {
       this.formData.fileUrl = file.url
       this.formData.ossName = file.uuid
     },
+
+    // 返回
+    onBack() {
+      this.$router.back()
+    },
   },
 }
 </script>
@@ -148,6 +156,20 @@ export default {
     .el-form-item__label {
       font-size: 16px;
     }
+    .el-textarea .el-input__count {
+      bottom: -32px;
+      background: transparent;
+    }
+  }
+
+  ::v-deep {
+    .el-input.is-active .el-input__inner,
+    .el-input__inner:focus,
+    .el-textarea__inner:focus,
+    .el-upload--picture-card:hover,
+    .el-upload:focus {
+      border-color: #f3920d;
+    }
   }
 
   .page {

+ 32 - 0
plugins/jssdk.js

@@ -0,0 +1,32 @@
+import Vue from 'vue'
+import { appId, jsApiList } from '@/configs/jssdk'
+const dev = process.env.EVN
+
+Vue.prototype.$wxReady = async function (callback, apiList = []) {
+  try {
+    const url = window.location.href.split('#')[0]
+    // console.log('当前页面地址:', url)
+    const res = await Vue.prototype.$http.api.initWxConfig({ url, appId })
+    console.log(res)
+    const wx = window.wx
+    if (!wx) return
+    wx.config({
+      debug: dev === 'development', // 开启调试模式,调用的所有 api 的返回值会在客户端 alert 出来,若要查看传入的参数,可以在 pc 端打开,参数信息会通过 log 打出,仅在 pc 端时才会打印。
+      appId: appId, // 必填,公众号的唯一标识
+      timestamp: res.data.timestamp, // 必填,生成签名的时间戳
+      nonceStr: res.data.noncestr, // 必填,生成签名的随机串
+      signature: res.data.signature, // 必填,签名
+      jsApiList: [...jsApiList, ...apiList], // 必填,需要使用的 JS 接口列表
+    })
+    wx.ready(callback(wx))
+    wx.fail(function (error) {
+      throw error
+    })
+  } catch (error) {
+    if (dev === 'development') {
+      console.warn('jssdk init error:' + error.msg || error.message)
+    } else {
+      console.warn('jssdk init error')
+    }
+  }
+}

+ 2 - 2
plugins/vue-filters.js

@@ -1,9 +1,9 @@
-import { dateFormat as formatDate } from '@/utils'
 import Vue from 'vue'
+import moment from 'moment'
 
 // 日期格式化
 const dateFormat = (value) => {
-  return formatDate(new Date(value), 'yyyy-MM-dd')
+  return moment(value).format('yyyy-MM-DD')
 }
 
 const fileSize = (size) => {

BIN
static/activity.png


BIN
static/share-icon.png


+ 5 - 0
store/app.js

@@ -8,6 +8,8 @@ const state = () => ({
   screenWidth: 0,
   showHeader: true,
   showFooter: true,
+  accessToken: '',
+  wxConfig: {},
 })
 
 const mutations = {
@@ -45,6 +47,9 @@ const mutations = {
     state.showHeader = true
     state.showFooter = true
   },
+  SET_WXCONFIG(state, config) {
+    state.wxConfig = config
+  },
 }
 
 const actions = {}

+ 1 - 0
store/getters.js

@@ -9,6 +9,7 @@ export default {
   screenWidth: (state) => state.app.screenWidth,
   showHeader: (state) => state.app.showHeader,
   showFooter: (state) => state.app.showFooter,
+  wxConfig: (state) => state.app.wxConfig,
   // 用户相关
   userInfo: (state) => state.user.userInfo,
   authId: (state) => state.user.userInfo.authId,