Ver código fonte

Merge branch 'dev_1.1.5' of DeNet/de-net-official into master

zhangwei 2 anos atrás
pai
commit
a9bd59c001

+ 354 - 0
components/CustomCardCover.vue

@@ -0,0 +1,354 @@
+<!-- 自定义卡片红包封面 -->
+<!-- todo:目前只有自定义奖品类型,货币类型待添加 -->
+<template>
+    <!-- 改版之后的卡片 -->
+    <div class="not-open-custom-card custom-card">
+        <img class="customImg" v-if="posterType === 2 && !!customPosterInstalled" :src="customPosterInstalled" />
+        <div class="common-top" v-else>
+          <img class="cover" v-if="isLottaryCpd" :src="require('../static/svg/img-custom-lottary-bg.svg')"  />
+          <img class="cover" v-else :src="require('../static/svg/img-custom-common-bg.svg')"  />
+          <img class="gift" :src="require('../static/svg/icon-gift.gif')" />
+          <div class="prize">
+              <font-zoom width="340">
+                <img class="icon" :src="require('../static/svg/icon-gift-inline.svg')"/>
+                <span class="name" id="custom-name" >
+                  {{customizedReward}}
+                  <span class="total">X{{totalCount}}</span>
+                </span>
+              </font-zoom>
+          </div>
+        </div>
+
+        <!-- 底部公共模块 -->
+        <div class="common-bottom" v-if="showBottomInfo">
+            <div class="theme">
+                <img v-if="isLottaryCpd" class="theme-icon" :src="require('../static/svg/icon-last-time.svg')"/>
+                <span v-if="isLottaryCpd" class="theme-time" >{{validity || '00:00:00'}}</span>
+                <span class="theme-info">{{isLottaryCpd ? 'Left' : 'Instant Giveaway'}}</span>
+            </div>
+            <div class="winner-info">
+                <font-zoom width="340">
+                  <span class="count">{{totalCount}}Winners</span>
+                  <span>to Share </span>
+                  <span class="prize-name">{{isMoneyRewardCpd ? amountValue + ' ' + tokenSymbol : customizedReward}}</span>
+                </font-zoom>
+            </div>
+        </div>
+    </div>
+</template>
+
+<script>
+import { formatSecondsAsDaysOrTime } from "../utils/help";
+import FontZoom  from './FontZoom.vue';
+import { RewardType, PlayType } from "../types";
+export default {
+  name:'CustomCardCover',
+  props: {
+    totalCount: 0,
+    amountValue: 0,
+    tokenSymbol: "",
+    playType: 1,
+    validityDuration: "",
+    userInfo: {},
+    rewardType: 1,
+    customizedReward: "",
+    validity: "",
+    showBottomInfo: true,
+    customPosterInstalled: "",
+    posterType: 1
+  },
+  data() {
+      return {
+          amount_font_size: 22,
+      }
+  },
+  computed: {
+    isMoneyRewardCpd() {
+      return this.rewardType === RewardType.money
+    },
+    isLottaryCpd() {
+      return this.playType === PlayType.lottery
+    }
+  },
+  mounted() {
+      this.setFontSize()
+  },
+  methods: {
+      setFontSize() {
+          let lendom = document.querySelector('#custom-name');
+          if (lendom) {
+              let lenstr = lendom.innerText.length;
+              let num = parseInt(450 / lenstr);
+              this.amount_font_size = num < 22 ? num : 22;
+          }
+      }
+  },
+  components: { FontZoom }
+}
+</script>
+
+<style scoped lang="scss">
+.not-open-custom-card {
+    width: 100%;
+    height: 100%;
+    position: relative;
+    border-radius: 16px;
+    filter: drop-shadow(0px 2px 20px rgba(0, 0, 0, 0.1));
+
+    .customImg {
+        width: 100%;
+        min-height: 373px;
+    }
+    .common-top {
+      position: relative;
+    }
+
+    .money-area {
+        width: 100%;
+        position: absolute;
+        top: 65px;
+
+        .txt {
+            font-weight: 800;
+            font-size: 16px;
+            text-align: center;
+            letter-spacing: 0.3px;
+            color: #ffffff;
+        }
+
+        .coin {
+            text-align: center;
+            width: 100%;
+            padding: 6px 0;
+            margin: 0 auto;
+            display: flex;
+            align-items: center;
+            justify-content: center;
+
+            img {
+                width: 46px;
+                height: 46px;
+                border-radius: 50%;
+                border: 3px solid #ffffff;
+            }
+
+            span {
+                margin-left: 15px;
+                font-weight: 800;
+                font-size: 60px;
+                line-height: 76px;
+                color: #ffffff;
+            }
+        }
+
+        .people {
+            font-weight: 800;
+            font-size: 13px;
+            line-height: 16px;
+            letter-spacing: 0.05em;
+            color: #ffffff;
+            display: flex;
+            align-items: center;
+            justify-content: center;
+        }
+
+        .time-area {
+            display: flex;
+            justify-content: center;
+            align-items: center;
+            width: 100%;
+            height: 46px;
+            background: rgba(0,0,0,.15);
+            color: #FFCC4D;
+            font-weight: 900;
+            font-size: 26px;
+            margin-top: -10px;
+            .icon-clock {
+                width: 26px;
+                height: 26px;
+                margin-right: 10px;
+            }
+        }
+    }
+
+    .title {
+        position: absolute;
+        top: 15px;
+        left: 15px;
+        z-index: 3;
+        width: 100%;
+        display: flex;
+        align-items: center;
+
+        img {
+            width: 24px;
+            height: 24px;
+            border: 2px solid #fff;
+            border-radius: 50%;
+        }
+
+        span {
+            margin-left: 10px;
+            font-weight: 600;
+            font-size: 16px;
+            letter-spacing: 0.3px;
+            color: #fff;
+        }
+    }
+
+    // .txt {
+    //   width: 100%;
+    //   position: absolute;
+    //   font-style: normal;
+    //   font-weight: 700;
+    //   font-size: 42px;
+    //   line-height: 50px;
+    //   text-align: center;
+
+    //   color: #FFF2D3;
+    //   top: 90px;
+    //   z-index: 3;
+    // }
+
+    img {
+        width: 100%;
+    }
+
+    .cover {
+        border-radius: 16px;
+    }
+
+    .up {
+        position: absolute;
+        top: 0;
+        // box-shadow: 0px 4px 44px rgba(0, 0, 0, 0.1);
+        z-index: 1;
+    }
+
+    .down {
+        position: absolute;
+        top: 253px;
+    }
+
+    .open {
+        width: 335px;
+        height: 50px;
+        cursor: pointer;
+        position: absolute;
+        bottom: 28px;
+        left: 50%;
+        margin-left: -167.5px;
+        z-index: 2;
+    }
+
+    .open-gif {
+        width: 200px;
+        height: 200px;
+        text-align: center;
+        position: absolute;
+        bottom: 90px;
+        left: 50%;
+        margin-left: -100px;
+        z-index: 3;
+    }
+}
+.custom-card {
+    position: relative;
+    background:#111214;
+    width: 100%;
+    position: relative;
+    border-radius: 10px;
+    filter: drop-shadow(0px 2px 20px rgba(0, 0, 0, 0.1));
+    .cover {
+        width: 100%;
+        border-radius: 10px 10px 0 0;
+    }
+    .gift {
+        width: 210px;
+        position: absolute;
+        left: 50%;
+        top: 83px;
+        transform: translateX(-50%);
+    }
+    .prize {
+        width: 100%;
+        position: absolute;
+        top: 76%;
+        left: 0;
+        height: 47px;
+        display: flex;
+        flex-direction: row;
+        justify-content: center;
+        font-style: normal;
+        font-weight: 800;
+        font-size: 22px;
+        line-height: 47px;
+        letter-spacing: 0.3px;
+
+        .icon {
+            width: 24px;
+        }
+        .name {
+            padding: 0 7px;
+            color: #fff;
+        }
+        .total {
+            color: #F5C03F;
+        }
+    }
+    .common-bottom {
+        width: 100%;
+        height: 62px;
+        background:#111214;
+        border-radius: 0 0 10px 10px;
+        padding: 10px 16px;
+        font-weight: 500;
+        font-size: 12px;
+        line-height: 14px;
+        letter-spacing: 0.3px;
+        color: #838383;
+        line-height: 20px;
+        .theme {
+            display: flex;
+            height: 20px;
+            align-items: center;
+            justify-content: flex-start;
+            &-icon {
+                width: 12px;
+            }
+            &-time {
+                margin: 0 4px;
+                color: #1D9BF0;
+            }
+        }
+        .winner-info {
+            display: flex;
+            height: 20px;
+            align-items: center;
+            justify-content: flex-start;
+            margin-bottom: 13px;
+            .count{
+                color: #1D9BF0;
+                margin-right: 4px;
+            }
+            .prize-name {
+                color: #1D9BF0;
+                margin-left: 4px;
+            }
+        }
+        .open-btn {
+            width: 100%;
+            height: 45px;
+            background: linear-gradient(180deg, #4AB6FF 0%, #1D9BF0 100%, #1D9BF0 100%);
+            border: 1.5px solid rgba(255, 255, 255, 0.15);
+            border-radius: 52px;
+            line-height: 45px;
+            text-align: center;
+            cursor: pointer;
+            font-weight: 800;
+            font-size: 16px;
+            color: #FFFFFF;
+        }
+    }
+}
+</style>

+ 45 - 0
components/FontZoom.vue

@@ -0,0 +1,45 @@
+<!-- 组件确定最大宽度时 可等比缩放组件 -->
+<template>
+  <span class="zoom-wrap" ref="zoomDom" :style="{ zoom: zoom }">
+    <slot></slot>
+  </span>
+</template>
+
+<script>
+export default {
+    props: {
+        width: {
+            type: String,
+            default: '375'
+        }
+    },
+    data() {
+        return {
+            zoom: 1,
+        }
+    },
+    mounted() {
+        this.setFontZoom()
+    },
+    methods: {
+      setFontZoom() {
+        this.$nextTick(() => {
+          let offsetWidth = this.$refs.zoomDom.offsetWidth;
+          console.log(this.$refs)
+          console.log('refs', this.$refs.zoomDom.offsetWidth)
+          this.zoom = offsetWidth > this.width ? +this.width / offsetWidth : 1
+        })
+      }
+    }
+}
+</script>
+
+<style lang="scss" scoped>
+.zoom-wrap {
+  color: #fff;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  white-space: nowrap;
+}
+</style>

+ 46 - 0
components/InstallChrome.vue

@@ -0,0 +1,46 @@
+<template>
+    <div>
+        <img src="/svg/icon-install-chrome.svg" alt class="install_chrome" @click="clickOpenChrome()" />
+    </div>
+</template>
+<script>
+export default {
+    name: 'install_chrome',
+    data() {
+        return {
+        }
+    },
+    methods: {
+        clickOpenChrome() {
+            window.open('https://www.google.com/chrome')
+
+            // let extParams = this.isMobile() ? {} : { status: this.reportStatus }
+            // Report.reportLog({
+            //     baseInfo: {
+            //         appVersionCode: this.appVersionCode,
+            //         mid: this.mid,
+            //         pageSource: Report.pageSource.newUserLandingPage,
+            //         appType,
+            //         machineCode: this.mid
+            //     },
+            //     params: {
+            //         eventData: {
+            //             businessType: Report.businessType.buttonClick,
+            //             objectType: Report.objectType.installButton,
+            //             postId: this.detail.postId,
+            //             srcContentId: this.detail.srcContentId,
+            //             senderId: this.detail.srcUserId,
+            //         },
+            //         extParams: extParams
+            //     }
+            // })
+        },
+    }
+}
+
+</script>
+<style lang="scss" scoped>
+.install_chrome{
+    cursor: pointer;
+}
+</style>

+ 32 - 0
components/InstallExtension.vue

@@ -0,0 +1,32 @@
+<template>
+    <div>
+        <img @click="installExtension" src="/svg/icon-install-nft-plugin.svg" />
+    </div>
+</template>
+<script>
+export default {
+    name: 'install_chrome',
+    props: {
+        extensionsInstallUrl: {
+            type: String,
+            default: ''
+        } 
+    },
+    data() {
+        return {
+            config: {},
+        }
+    },
+    methods: {
+        installExtension() {
+            window.open(this.extensionsInstallUrl)
+        }
+    }
+}
+
+</script>
+<style lang="scss" scoped>
+img {
+    cursor: pointer;
+}
+</style>

+ 19 - 0
components/logo.vue

@@ -0,0 +1,19 @@
+<template>
+    <div>
+        <img src="/svg/icon-logo.svg" />
+    </div>
+</template>
+<script>
+</script>
+<style lang="scss" scoped>
+div {
+    position: fixed;
+    top: 20px;
+    left: 25px;
+    z-index: 99;
+    img {
+        width: 100px;
+        height: 32px;
+    }
+}
+</style>

+ 11 - 6
nuxt.config.js

@@ -3,7 +3,7 @@ const env = require('./env')
 export default {
   // Global page headers: https://go.nuxtjs.dev/config-head
   head: {
-    title: 'de-net-official1',
+    title: 'de-net-official',
     htmlAttrs: {
       lang: 'en'
     },
@@ -47,27 +47,32 @@ export default {
   router: {
     extendRoutes(routes, resolve) {
       routes.push({
-        name: 'index',
+        name: 'RedPackage',
         path: '/:id?',
         component: resolve(__dirname, 'pages/index.vue')
       },
       {
-        name: 'luckdraw',
+        name: 'LuckDraw',
         path: '/luckdraw/:id?',
         component: resolve(__dirname, 'pages/luckdraw.vue')
       },
       {
-        name: 'install',
+        name:'ToolBox',
+        path: '/toolbox/:id',
+        component: resolve(__dirname, 'pages/toolbox/index.vue')
+      },
+      {
+        name: 'Install',
         path: '/install',
         component: resolve(__dirname, 'pages/install.vue')
       },
       {
-        name: 'nft',
+        name: 'NFT',
         path: '/nft/:id/:account',
         component: resolve(__dirname, 'pages/nft/index.vue')
       },
       {
-        name: 'nft_group',
+        name: 'NftGroup',
         path: '/nft_group/:id',
         component: resolve(__dirname, 'pages/nft/group.vue')
       },

+ 151 - 46
pages/index.vue

@@ -1,6 +1,7 @@
+<!-- 普通玩法落地页 -->
 <template>
 	<div style="width: 100%; height: 100%;">
-		<div class="content" :style="{ 'background': `#F5FAFF` }" v-show="show_home" v-if="detail">
+		<div class="content" :style="{ 'background': `#fff` }" v-show="show_home" v-if="detail">
 			<div class="logo">
 				<img src="/img/icon-logo.png" alt />
 			</div>
@@ -8,13 +9,15 @@
 			<div class="not-open" v-show="status == 'not-open'">
 				<img src="/subject/001.gif">
 			</div>
-
+      <div class="head-in-custom" v-if="!isMoneyPrize">
+          <img :src="detail.postBizData.postUserInfo.avatarUrl" />
+          <span>{{ detail.postBizData.postUserInfo.nickName }}</span>
+      </div>
 			<!-- 红包打开 -->
-			<div class="redPacket" 
+			<div class="redPacket"
 				:class="{ redPacket2: status != 'open', key_packet: status == 'open' }"
 				v-if="status != 'nothing'"
 				v-show="status != 'not-open'">
-
 				<!-- 内容 -->
 				<div class="head">
 					<div class="head-title">
@@ -55,7 +58,7 @@
 				<div class="luck-list-title">
 					<div>{{ detail.postBizData.receiveCount || 0 }}/{{ detail.postBizData.totalCount || 0 }} Winners
 					</div>
-					<div> {{ detail.postBizData.receiveAmountValue }} / {{
+					<div v-if="isMoneyPrize"> {{ detail.postBizData.receiveAmountValue }} / {{
 							detail.postBizData.amountValue || ''
 					}} {{ detail.postBizData.currencySymbol || '' }}</div>
 				</div>
@@ -67,11 +70,12 @@
 							<div class="luck-title">{{ item.simpleUserInfoVO.nickName || 'Twitter User' }}</div>
 							<div class="luck-time">{{ formatTime(item.receiveTimestamp, 'MM-DD HH:mm') }}</div>
 						</div>
-						<div class="luck-money">
+						<div class="luck-money" v-if="isMoneyPrize">
 							<img :src="item.currencyIconPath" alt />
 							<div class="luck-money-txt">{{ item.amountValue || 0 }}</div>
 						</div>
-						<div class="luck-king" v-if="item.maxAmount">
+            <div class="luck-custom-prize" v-else>winner</div>
+						<div class="luck-king" v-if="isMoneyPrize && item.maxAmount">
 							<img src="/svg/icon-king-hat.svg" alt />
 							<span>Luckiest Draw</span>
 						</div>
@@ -80,7 +84,7 @@
 			</div>
 			<template v-else>
 				<div class="redBagCustom" v-if="detail.postBizData.posterType === 2 && detail.postBizData.customPosterInstalled">
-					<img class="customImg" :src="detail.postBizData.customPosterInstalled" />
+					<!-- <img class="customImg" :src="detail.postBizData.customPosterInstalled" />
 					<div class="customBottom">
 						<div class="theme">
 							<span class="info">Instant Giveaway</span>
@@ -90,23 +94,61 @@
 							<span>to Share </span>
 							<span class="prize-name">{{detail.postBizData.amountValue + ' ' + detail.postBizData.currencySymbol}}</span>
 						</div>
-					</div>
+					</div> -->
+          <custom-card-cover
+              :totalCount="detail.postBizData.totalCount"
+              :amountValue="detail.postBizData.amountValue"
+              :tokenSymbol="detail.postBizData.tokenSymbol"
+              :currencyIconUrl="detail.postBizData.iconPath"
+              :playType="1"
+              :posterType="2"
+              :customPosterInstalled="detail.postBizData.customPosterInstalled"
+              :validity="validity"
+              :userInfo="{
+                  nickName: detail.postBizData.postUserInfo.nickName,
+                  avatarUrl: detail.postBizData.postUserInfo.avatarUrl
+              }"
+              :rewardType="detail.postBizData.rewardType"
+              :customizedReward="detail.postBizData.customizedReward"
+              :showBottomInfo="true"
+            ></custom-card-cover>
 				</div>
-				<div class="redBag" v-else>
-					<img src="/subject/001-card.png" alt="">
-					<img class="open-gif" src="/subject/001.gif" />
-					<div class="title" v-if="detail.postBizData.postUserInfo">
-						<img :src="detail.postBizData.postUserInfo.avatarUrl" alt />
-						<span>{{ detail.postBizData.postUserInfo.nickName || 'FutureDoctor' }}</span>
-					</div>
-					<div class="money-area">
-						<div class="txt">{{ detail.postBizData.currencySymbol }} GIVEAWAY</div>
-						<div class="coin">
-							<img :src="detail.postBizData.currencyIconPath" alt />
-							<font-amount :amount="detail.postBizData.amountValue"></font-amount>
-						</div>
-						<div class="people">{{ detail.postBizData.totalCount }} WINNERS TO SHARE</div>
-					</div>
+				<div class="redBag" :class="{'auto-height': !isMoneyPrize}" v-else>
+					<!-- 货币类型 -->
+          <template v-if="isMoneyPrize">
+            <img src="/subject/001-card.png" alt="">
+            <img class="open-gif" src="/subject/001.gif" />
+            <div class="title" v-if="detail.postBizData.postUserInfo">
+              <img :src="detail.postBizData.postUserInfo.avatarUrl" alt />
+              <span>{{ detail.postBizData.postUserInfo.nickName || 'FutureDoctor' }}</span>
+            </div>
+            <div class="money-area">
+              <div class="txt">{{ detail.postBizData.currencySymbol }} GIVEAWAY</div>
+              <div class="coin">
+                <img :src="detail.postBizData.currencyIconPath" alt />
+                <font-amount :amount="detail.postBizData.amountValue"></font-amount>
+              </div>
+              <div class="people">{{ detail.postBizData.totalCount }} WINNERS TO SHARE</div>
+            </div>
+          </template>
+
+          <template v-else>
+            <custom-card-cover
+              :totalCount="detail.postBizData.totalCount"
+              :amountValue="detail.postBizData.amountValue"
+              :tokenSymbol="detail.postBizData.tokenSymbol"
+              :currencyIconUrl="detail.postBizData.iconPath"
+              :playType="1"
+              :validity="validity"
+              :userInfo="{
+                  nickName: detail.postBizData.postUserInfo.nickName,
+                  avatarUrl: detail.postBizData.postUserInfo.avatarUrl
+              }"
+              :rewardType="detail.postBizData.rewardType"
+              :customizedReward="detail.postBizData.customizedReward"
+              :showBottomInfo="true"
+            ></custom-card-cover>
+          </template>
 				</div>
 			</template>
 
@@ -186,11 +228,12 @@
 						<div class="luck-title">{{ item.simpleUserInfoVO.nickName || 'Twitter User' }}</div>
 						<div class="luck-time">{{ formatTime(item.receiveTimestamp) }}</div>
 					</div>
-					<div class="luck-money">
+					<div class="luck-money" v-if="isMoneyPrize">
 						<img :src="item.currencyIconPath" alt />
 						<div class="luck-money-txt">{{ item.amountValue || 0 }}</div>
 					</div>
-					<div class="luck-king" v-if="item.maxAmount">
+          <div class="luck-custom-prize" v-else>winner</div>
+					<div class="luck-king" v-if="isMoneyPrize && item.maxAmount">
 						<img src="/svg/icon-king-hat.svg" alt />
 						<span>Luckiest Draw</span>
 					</div>
@@ -198,16 +241,16 @@
 			</div>
 			<div class="area-cp-link">
 				<div class="area-list">
-                    <div class="item">
-                        <div class="icon"><img :src=" require('../static/subject/01.svg') " /></div>
-                        <div class="font">Complete the tasks on tweet</div>
-                    </div>
-                    <div class="item">
-                        <div class="icon"><img :src=" require('../static/subject/02.svg') " /></div>
-                        <div class="font">Open link on PC to draw</div>
-                        <div class="pc"><img :src=" require('../static/subject/pc.svg') " /></div>
-                    </div>
-                </div>
+            <div class="item">
+                <div class="icon"><img :src=" require('../static/subject/01.svg') " /></div>
+                <div class="font">Complete the tasks on tweet</div>
+            </div>
+            <div class="item">
+                <div class="icon"><img :src=" require('../static/subject/02.svg') " /></div>
+                <div class="font">Open link on PC to draw</div>
+                <div class="pc"><img :src=" require('../static/subject/pc.svg') " /></div>
+            </div>
+          </div>
 				<div class="area-content">
 					{{ cp_link }}
 				</div>
@@ -231,7 +274,9 @@ import Cookies from 'js-cookie'
 import { isBrowser } from '../utils/help.js'
 import Report from "../log-center/log"
 import { Toast } from 'vant';
-import FontAmount from '../components/FontAmount.vue'
+import FontAmount from '../components/FontAmount.vue';
+import CustomCardCover from '../components/CustomCardCover.vue'
+import { RewardType } from '../types';
 
 
 var moment = require('moment');
@@ -275,6 +320,8 @@ export default {
 				}
 			},
 			currencyIconPath: '',
+			customCover: '',
+			customGiveaway: '',
 			title: 'DeNet Giveaway',
 			metaTitle: 'DeNet: An Easy Web3 Tool For GIVEAWAY / AIRDROP',
 			jumpUrl: jumpUrl,
@@ -289,7 +336,13 @@ export default {
 				extensionsInstallUrl: ''
 			}
 		}
-	},
+  },
+  computed: {
+    // 货币类型的奖品
+    isMoneyPrize() {
+      return this.detail.postBizData.rewardType === RewardType.money;
+    }
+  },
 	components: {
 		FontAmount,
 	},
@@ -299,7 +352,7 @@ export default {
 			title: this.title,
 			appVersionCode: 3,
 			meta: [
-				// facebook 
+				// facebook
 				{
 					name: 'og:url',
 					content: this.jumpUrl + this.detail.postId
@@ -349,6 +402,8 @@ export default {
                         postId: this.detail.postId,
                         srcContentId: this.detail.srcContentId,
                         senderId: this.detail.srcUserId,
+						redPacketType: 0,
+						customCover: this.customCover,
 					}
 				}
 			})
@@ -372,6 +427,8 @@ export default {
                         postId: this.detail.postId,
                         srcContentId: this.detail.srcContentId,
                         senderId: this.detail.srcUserId,
+						redPacketType: 0,
+						customCover: this.customCover,
 					},
                     extParams: extParams
 				}
@@ -400,6 +457,8 @@ export default {
                         postId: this.detail.postId,
                         srcContentId: this.detail.srcContentId,
                         senderId: this.detail.srcUserId,
+						redPacketType: 0,
+						customCover: this.customCover,
 					},
                     extParams: extParams,
 				}
@@ -562,11 +621,12 @@ export default {
 		},
 		setPickupInfo() {
 			let pickupInfo = {
-				srcContentId: this.detail.srcContentId,
-				postNickName: this.detail.postBizData.postUserInfo.nickName,
+				srcContentId: this.detail.srcContentId || '',
+				postNickName: this.detail.postBizData.postUserInfo.nickName || '',
                 createTime: Date.now(),
+				jump_type: 'red_packet',
 			};
-			Cookies.set('pickup_info', JSON.stringify(pickupInfo), { expires: 100 });
+			Cookies.set('jump_info', JSON.stringify(pickupInfo), { expires: 100 });
 		},
 		async getDetail() {
 			let { data } = await axios.post(`${baseURL}/denet/post/getDetail`, {
@@ -580,6 +640,8 @@ export default {
 			})
 			if (data.code == 0) {
 				this.detail.postBizData = JSON.parse(data.data.postBizData)
+				this.customCover = this.detail.postBizData && this.detail.postBizData.posterType == 2 ? 1 : 0;
+				this.customGiveaway = this.detail.postBizData && this.detail.postBizData.rewardType == 2 ? 1 : 0;
 			}
 		},
 		async getConfig() {
@@ -616,7 +678,7 @@ export default {
 		if (data.code == 0) {
 			if (data.data && data.data.postBizData && typeof data.data.postBizData == 'string') {
 				data.data.postBizData = JSON.parse(data.data.postBizData)
-			} 
+			}
 			if(data.data.postBizData === null) {
 				data.data.postBizData = {
 					postUserInfo: {
@@ -625,6 +687,8 @@ export default {
 			}
 			return {
 				detail: data.data,
+				customCover: data.data.postBizData && data.data.postBizData.posterType == 2 ? 1 : 0,
+				customGiveaway: data.data.postBizData && data.data.postBizData.rewardType == 2 ? 1 : 0,
 			}
 		}
 	},
@@ -670,6 +734,8 @@ export default {
                             postId: this.detail.postId,
                             srcContentId: this.detail.srcContentId,
                             senderId: this.detail.srcUserId,
+							redPacketType: 0,
+							customCover: this.customCover,
                         }
                     }
                 })
@@ -699,7 +765,7 @@ export default {
 			this.setCookieMid()
 			// 是否被领完
 			if(this.detail.postBizData.receiveCount < this.detail.postBizData.totalCount){
-				this.getRedPacket()	
+				this.getRedPacket()
 			}else{
 				this.show_home = true
 				this.status = 'nothing'
@@ -721,6 +787,8 @@ export default {
                             postId: this.detail.postId,
                             srcContentId: this.detail.srcContentId,
                             senderId: this.detail.srcUserId,
+							redPacketType: 0,
+							customCover: this.customCover,
                         },
                         extParams: {
                             status: this.reportStatus,
@@ -746,6 +814,8 @@ export default {
                         postId: this.detail.postId,
                         srcContentId: this.detail.srcContentId,
                         senderId: this.detail.srcUserId,
+						redPacketType: 0,
+						customCover: this.customCover,
 					},
                     extParams: {
                         status: this.reportStatus,
@@ -942,6 +1012,12 @@ body,
 					color: #444444;
 				}
 			}
+      .luck-custom-prize {
+          font-weight: 500;
+          font-size: 14px;
+          letter-spacing: 0.3px;
+          color: #F5B945;
+      }
 		}
 
 		.luck-item:last-child {
@@ -1018,6 +1094,28 @@ body,
 	font-style: normal;
 	font-weight: 600;
 
+  .head-in-custom {
+        position: absolute;
+        top: 9rem;
+        left: 30rem;
+        background: #fff;
+        display: flex;
+        align-items: center;
+        font-weight: 500;
+        font-size: 15px;
+        color: #000;
+        height: 54px;
+        img {
+          width: 30px;
+          height: 30px;
+          border-radius: 50%;
+          margin-right: 10px;
+        }
+
+    }
+
+
+
 	.not-open {
 		display: flex;
 		align-items: center;
@@ -1118,6 +1216,9 @@ body,
 		overflow-y: hidden;
 		box-shadow: 0 0 5px #888888;
 		background: #fff;
+    &.auto-height {
+      height: auto;
+    }
 
 		.money-area {
 			width: 100%;
@@ -1249,8 +1350,6 @@ body,
 		box-shadow: 0px 3px 10px rgba(0, 0, 0, 0.1);
 		background: #fff;
 
-
-
 		.top {
 			top: 0;
 			position: absolute;
@@ -1446,6 +1545,12 @@ body,
 						color: #444444;
 					}
 				}
+        .luck-custom-prize {
+          font-weight: 500;
+          font-size: 14px;
+          letter-spacing: 0.3px;
+          color: #F5B945;
+        }
 			}
 
 			.luck-item:last-child {

+ 502 - 231
pages/luckdraw.vue

@@ -1,9 +1,8 @@
+<!-- 红包玩法落地页 -->
 <template>
     <div class="content">
         <template v-if="isLoading">
-            <img
-                class="loading"
-                src="../static/svg/icon-loading.svg" />
+            <img class="loading" src="../static/svg/icon-loading.svg" />
         </template>
         <template v-else>
             <template v-if="isMobile">
@@ -13,29 +12,46 @@
                     custom: detail.postBizData.posterType === 2 && detail.postBizData.customPosterInstalled,
                 }">
                     <template v-if="status === 'not-open'">
-                        <template v-if="detail.postBizData.posterType === 2 && detail.postBizData.customPosterInstalled">
+                        <template
+                            v-if="detail.postBizData.posterType === 2 && detail.postBizData.customPosterInstalled">
                             <img class="customImg" :src="detail.postBizData.customPosterInstalled" />
                         </template>
                         <template v-else>
-                            <img class="lottery" :src=" require('../static/svg/icon-luck-mark.svg') " />
-                            <div class="head">
-                                <img :src="detail.postBizData.postUserInfo.avatarUrl" />
-                                <span>{{ detail.postBizData.postUserInfo.nickName }}</span>
-                            </div>
-                            <div class="price">
-                                <div class="usdt">{{ detail.postBizData.currencySymbol }} GIVEAWAY</div>
-                                <div class="money">
-                                    <img :src="detail.postBizData.currencyIconPath" />
-                                    <font-amount :fontSize="60" :amount="detail.postBizData.amountValue"></font-amount>
+                            <template v-if="isMoneyPrize">
+                                <img class="lottery" :src=" require('../static/svg/icon-luck-mark.svg') " />
+                                <div class="head">
+                                    <img :src="detail.postBizData.postUserInfo.avatarUrl" />
+                                    <span>{{ detail.postBizData.postUserInfo.nickName }}</span>
                                 </div>
-                            </div>
-                            <div class="time">
-                                <img class="img" :src=" require('../static/svg/icon-time.svg') " />
-                                {{ validity || '00:00:00' }}
-                            </div>
-                            <div class="box">
-                                <img src="../static/subject/icon-box.png" />
-                            </div>
+                                <div class="price">
+                                    <div class="usdt">{{ detail.postBizData.currencySymbol }} GIVEAWAY</div>
+                                    <div class="money">
+                                        <img :src="detail.postBizData.currencyIconPath" />
+                                        <font-amount :fontSize="60" :amount="detail.postBizData.amountValue">
+                                        </font-amount>
+                                    </div>
+                                </div>
+                                <div class="time">
+                                    <img class="img" :src=" require('../static/svg/icon-time.svg') " />
+                                    {{ validity || '00:00:00' }}
+                                </div>
+                                <div class="box">
+                                    <img src="../static/subject/icon-box.png" />
+                                </div>
+                            </template>
+
+                            <template v-else>
+                                <custom-card-cover :totalCount="detail.postBizData.totalCount"
+                                    :amountValue="detail.postBizData.amountValue"
+                                    :tokenSymbol="detail.postBizData.tokenSymbol"
+                                    :currencyIconUrl="detail.postBizData.iconPath" :playType="2" :validity="validity"
+                                    :userInfo="{
+                                    nickName: detail.postBizData.postUserInfo.nickName,
+                                    avatarUrl: detail.postBizData.postUserInfo.avatarUrl
+                                }" :rewardType="detail.postBizData.rewardType"
+                                    :customizedReward="detail.postBizData.customizedReward" :showBottomInfo="false">
+                                </custom-card-cover>
+                            </template>
                         </template>
                     </template>
                     <template v-else>
@@ -47,10 +63,11 @@
                             <template v-else-if="status === 'expire'">
                                 <!-- <img class="img" :src=" require('../static/svg/icon-luck-complete.svg') " />
                                 <p class="tips">This Draw is Complete</p> -->
-                                <p class="expire">This Giveaways<br/>expired on {{ formatTime(detail.postBizData.endTimestamp, 'MM-DD') }}</p>
+                                <p class="expire">This Giveaways<br />expired on {{
+                                    formatTime(detail.postBizData.endTimestamp, 'MM-DD') }}</p>
                             </template>
                             <template v-else>
-                                <p class="win">🎉 Awesome! You are Winner!</p>
+                                <p class="win">🎉 Awesome! You Will Get</p>
                                 <div class="win-money">
                                     <img :src="detail.postBizData.currencyIconPath" />
                                     <font-amount :fontSize="46" :amount="receiveAmount"></font-amount>
@@ -58,25 +75,31 @@
                             </template>
                         </div>
                         <div class="succTitle">
-                            <span>{{ detail.postBizData.receiveCount || 0 }}/{{ detail.postBizData.totalCount || 0 }} Winners</span>
-                            <span>{{ detail.postBizData.receiveAmountValue }} / {{ detail.postBizData.amountValue || '' }} {{ detail.postBizData.currencySymbol || '' }}</span>
+                            <span>{{ detail.postBizData.receiveCount || 0 }}/{{ detail.postBizData.totalCount || 0 }}
+                                Winners</span>
+                            <span v-if="isMoneyPrize">{{ detail.postBizData.receiveAmountValue }} / {{
+                                detail.postBizData.amountValue || '' }} {{ detail.postBizData.currencySymbol || ''
+                                }}</span>
                         </div>
                         <div class="luck-list" @scroll="handleScroll($event)">
                             <div class="luck-item" v-for="item, i in luck_list" v-bind:key="i">
                                 <div class="userLogo">
-                                    <img class="medal" v-if="i < 2" :src=" require('../static/svg/icon-medal-' + i + '.svg') " />
-                                    <img class="header" v-if="item.simpleUserInfoVO.avatarUrl" :src="item.simpleUserInfoVO.avatarUrl" alt />
+                                    <img class="medal" v-if="i < 2"
+                                        :src=" require('../static/svg/icon-medal-' + i + '.svg') " />
+                                    <img class="header" v-if="item.simpleUserInfoVO.avatarUrl"
+                                        :src="item.simpleUserInfoVO.avatarUrl" alt />
                                     <img class="header" v-else src="/svg/icon-twitter.svg" alt />
                                 </div>
                                 <div class="luck-content">
                                     <div class="luck-title">{{ item.simpleUserInfoVO.nickName || 'Twitter User' }}</div>
                                     <div class="luck-time">{{ formatTime(item.receiveTimestamp, 'MM-DD HH:mm') }}</div>
                                 </div>
-                                <div class="luck-money">
+                                <div class="luck-money" v-if="isMoneyPrize">
                                     <img :src="item.currencyIconPath" alt />
                                     <div class="luck-money-txt">{{ item.amountValue || 0 }}</div>
                                 </div>
-                                <div class="luck-king" v-if="item.maxAmount">
+                                <div class="luck-custom-prize" v-else>winner</div>
+                                <div class="luck-king" v-if="isMoneyPrize && item.maxAmount">
                                     <img src="/svg/icon-king-hat.svg" alt />
                                     <span>Luckiest Draw</span>
                                 </div>
@@ -99,7 +122,7 @@
                             {{ linkHref }}
                         </div>
                         <div class="area-btn">
-                            <div class="btn" :data-clipboard-text="linkHref">Copy Link</div>
+                            <div class="btn" :data-clipboard-text="linkHref" @click="copyLinkHandle">Copy Link</div>
                         </div>
                     </div>
                     <div class="layer" v-show="layer_show">
@@ -109,56 +132,90 @@
                         </div>
                     </div>
                 </div>
-                <!-- 手机端 -->
             </template>
+            <!-- PC端 -->
             <template v-else>
                 <div class="logo">
                     <img src="/img/icon-logo.png" />
                 </div>
                 <div class="show">
                     <div class="center">
+                        <div class="head-in-custom" v-if="!isMoneyPrize">
+                            <img :src="detail.postBizData.postUserInfo.avatarUrl" />
+                            <span>{{ detail.postBizData.postUserInfo.nickName }}</span>
+                        </div>
                         <div class="giveaway" :class="{
                             bg: status === 'not-open',
                             custom: detail.postBizData.posterType === 2 && detail.postBizData.customPosterInstalled,
+                            'auto-height': !isMoneyPrize
                         }">
-                            <template v-if="status === 'not-open'">
-                                <template v-if="detail.postBizData.posterType === 2 && detail.postBizData.customPosterInstalled">
-                                    <img class="customImg" :src="detail.postBizData.customPosterInstalled" />
-                                    <div class="customBottom">
-                                        <div class="theme">
-                                            <img class="icon" :src="require('../static/svg/icon-last-time.svg')"/>
-                                            <span class="time2">{{ validity || '00:00:00' }}</span>
-                                            <span class="info">Left</span>
-                                        </div>
-                                        <div class="winner-info">
-                                            <span class="count">{{detail.postBizData.totalCount}} Winners</span>
-                                            <span>to Share </span>
-                                            <span class="prize-name">{{detail.postBizData.amountValue + ' ' + detail.postBizData.currencySymbol}}</span>
-                                        </div>
+                            <div v-if="status === 'not-open'">
+                                <template
+                                    v-if="detail.postBizData.posterType === 2 && detail.postBizData.customPosterInstalled">
+                                    <!-- <img class="customImg" :src="detail.postBizData.customPosterInstalled" />
+                                  <div class="customBottom">
+                                    <div class="theme">
+                                      <img class="icon" :src="require('../static/svg/icon-last-time.svg')"/>
+                                      <span class="time2">{{ validity || '00:00:00' }}</span>
+                                      <span class="info">Left</span>
+                                    </div>
+                                    <div class="winner-info">
+                                      <span class="count">{{detail.postBizData.totalCount}} Winners</span>
+                                      <span>to Share </span>
+                                      <span class="prize-name">{{detail.postBizData.amountValue + ' ' + detail.postBizData.currencySymbol}}</span>
                                     </div>
+                                  </div> -->
+                                    <custom-card-cover :totalCount="detail.postBizData.totalCount"
+                                        :amountValue="detail.postBizData.amountValue"
+                                        :tokenSymbol="detail.postBizData.tokenSymbol"
+                                        :currencyIconUrl="detail.postBizData.iconPath" :playType="2" :posterType="2"
+                                        :customPosterInstalled="detail.postBizData.customPosterInstalled"
+                                        :validity="validity" :userInfo="{
+                                        nickName: detail.postBizData.postUserInfo.nickName,
+                                        avatarUrl: detail.postBizData.postUserInfo.avatarUrl
+                                    }" :rewardType="detail.postBizData.rewardType"
+                                        :customizedReward="detail.postBizData.customizedReward" :showBottomInfo="true">
+                                    </custom-card-cover>
                                 </template>
                                 <template v-else>
-                                    <img class="lottery" :src=" require('../static/svg/icon-luck-mark.svg') " />
-                                    <div class="head">
-                                        <img :src="detail.postBizData.postUserInfo.avatarUrl" />
-                                        <span>{{ detail.postBizData.postUserInfo.nickName }}</span>
-                                    </div>
-                                    <div class="price">
-                                        <div class="usdt">{{ detail.postBizData.currencySymbol }} GIVEAWAY</div>
-                                        <div class="money">
-                                            <img :src="detail.postBizData.currencyIconPath" />
-                                            <font-amount :fontSize="60" :amount="detail.postBizData.amountValue"></font-amount>
+                                    <!-- 旧版 样式,后续更新时在 custom-card-cover 公共组件内维护-->
+                                    <template v-if="isMoneyPrize">
+                                        <img class="lottery" :src=" require('../static/svg/icon-luck-mark.svg') " />
+                                        <div class="head">
+                                            <img :src="detail.postBizData.postUserInfo.avatarUrl" />
+                                            <span>{{ detail.postBizData.postUserInfo.nickName }}</span>
                                         </div>
-                                    </div>
-                                    <div class="time">
-                                        <img class="img" :src=" require('../static/svg/icon-time.svg') " />
-                                        {{ validity || '00:00:00' }}
-                                    </div>
-                                    <div class="box">
-                                        <img src="../static/subject/icon-box.png" />
-                                    </div>
+                                        <div class="price">
+                                            <div class="usdt">{{ detail.postBizData.currencySymbol }} GIVEAWAY</div>
+                                            <div class="money">
+                                                <img :src="detail.postBizData.currencyIconPath" />
+                                                <font-amount :fontSize="60" :amount="detail.postBizData.amountValue">
+                                                </font-amount>
+                                            </div>
+                                        </div>
+                                        <div class="time">
+                                            <img class="img" :src=" require('../static/svg/icon-time.svg') " />
+                                            {{ validity || '00:00:00' }}
+                                        </div>
+                                        <div class="box">
+                                            <img src="../static/subject/icon-box.png" />
+                                        </div>
+                                    </template>
+
+                                    <template v-else>
+                                        <custom-card-cover :totalCount="detail.postBizData.totalCount"
+                                            :amountValue="detail.postBizData.amountValue"
+                                            :tokenSymbol="detail.postBizData.tokenSymbol"
+                                            :currencyIconUrl="detail.postBizData.iconPath" :playType="2"
+                                            :validity="validity" :userInfo="{
+                                            nickName: detail.postBizData.postUserInfo.nickName,
+                                            avatarUrl: detail.postBizData.postUserInfo.avatarUrl
+                                        }" :rewardType="detail.postBizData.rewardType"
+                                            :customizedReward="detail.postBizData.customizedReward"
+                                            :showBottomInfo="true"></custom-card-cover>
+                                    </template>
                                 </template>
-                            </template>
+                            </div>
                             <template v-else>
                                 <div class="succTop">
                                     <template v-if="status === 'opened'">
@@ -168,7 +225,8 @@
                                     <template v-else-if="status === 'expire'">
                                         <!-- <img class="img" :src=" require('../static/svg/icon-luck-complete.svg') " />
                                         <p class="tips">This Draw is Complete</p> -->
-                                        <p class="expire">This Giveaways<br/>expired on {{ formatTime(detail.postBizData.endTimestamp, 'MM-DD') }}</p>
+                                        <p class="expire">This Giveaways<br />expired on {{
+                                            formatTime(detail.postBizData.endTimestamp, 'MM-DD') }}</p>
                                     </template>
                                     <template v-else>
                                         <p class="win">🎉 Awesome! You are Winner!</p>
@@ -179,25 +237,33 @@
                                     </template>
                                 </div>
                                 <div class="succTitle">
-                                    <span>{{ detail.postBizData.receiveCount || 0 }}/{{ detail.postBizData.totalCount || 0 }} Winners</span>
-                                    <span>{{ detail.postBizData.receiveAmountValue }} / {{ detail.postBizData.amountValue || '' }} {{ detail.postBizData.currencySymbol || '' }}</span>
+                                    <span>{{ detail.postBizData.receiveCount || 0 }}/{{ detail.postBizData.totalCount ||
+                                        0 }} Winners</span>
+                                    <span v-if="isMoneyPrize">{{ detail.postBizData.receiveAmountValue }} / {{
+                                        detail.postBizData.amountValue || '' }} {{ detail.postBizData.currencySymbol ||
+                                        '' }}</span>
                                 </div>
                                 <div class="luck-list" @scroll="handleScroll($event)">
                                     <div class="luck-item" v-for="item, i in luck_list" v-bind:key="i">
                                         <div class="userLogo">
-                                            <img class="medal" v-if="i < 2" :src=" require('../static/svg/icon-medal-' + i + '.svg') " />
-                                            <img class="header" v-if="item.simpleUserInfoVO.avatarUrl" :src="item.simpleUserInfoVO.avatarUrl" alt />
+                                            <img class="medal" v-if="i < 2"
+                                                :src=" require('../static/svg/icon-medal-' + i + '.svg') " />
+                                            <img class="header" v-if="item.simpleUserInfoVO.avatarUrl"
+                                                :src="item.simpleUserInfoVO.avatarUrl" alt />
                                             <img class="header" v-else src="/svg/icon-twitter.svg" alt />
                                         </div>
                                         <div class="luck-content">
-                                            <div class="luck-title">{{ item.simpleUserInfoVO.nickName || 'Twitter User' }}</div>
-                                            <div class="luck-time">{{ formatTime(item.receiveTimestamp, 'MM-DD HH:mm') }}</div>
+                                            <div class="luck-title">{{ item.simpleUserInfoVO.nickName || 'Twitter User'
+                                                }}</div>
+                                            <div class="luck-time">{{ formatTime(item.receiveTimestamp, 'MM-DD HH:mm')
+                                                }}</div>
                                         </div>
-                                        <div class="luck-money">
+                                        <div class="luck-money" v-if="isMoneyPrize">
                                             <img :src="item.currencyIconPath" alt />
                                             <div class="luck-money-txt">{{ item.amountValue || 0 }}</div>
                                         </div>
-                                        <div class="luck-king" v-if="item.maxAmount">
+                                        <div class="luck-custom-prize" v-else>winner</div>
+                                        <div class="luck-king" v-if="isMoneyPrize && item.maxAmount">
                                             <img src="/svg/icon-king-hat.svg" alt />
                                             <span>Luckiest Draw</span>
                                         </div>
@@ -208,18 +274,20 @@
                         <div class="desc">
                             <template v-if="isChrome">
                                 <template v-if="status === 'not-open'">
-                                    <div class="title">Install DeNet Plugin<br/>to Draw Prizes</div>
+                                    <div class="title">Install DeNet Plugin<br />to Draw Prizes</div>
                                     <div class="issue">DeNet will detect task situation to issue Giveaway</div>
                                 </template>
                                 <template v-else>
-                                    <div class="title">Install the Denet plugin<br/>to not miss the next draw</div>
+                                    <div class="title">Install the Denet plugin<br />to not miss the next draw</div>
                                 </template>
-                                <img class="button" @click="installExtension" src="../static/svg/icon-install-nft-plugin.svg" />
+                                <img class="button" @click="installExtension"
+                                    src="../static/svg/icon-install-nft-plugin.svg" />
                             </template>
                             <template v-else>
                                 <div class="title">Get Giveaway<br />with chrome</div>
                                 <div class="issue">Only supports getting Giveaways through chrome</div>
-                                <img class="button" @click="clickOpenChrome" src="../static/svg/icon-install-nft-chrome.svg" />
+                                <img class="button" @click="clickOpenChrome"
+                                    src="../static/svg/icon-install-nft-chrome.svg" />
                             </template>
                         </div>
                     </div>
@@ -235,6 +303,9 @@ import Cookies from 'js-cookie'
 import { Toast } from 'vant';
 import { isBrowser, appType, appVersionCode, formatSecondsAsDaysOrTime } from '../utils/help.js'
 import FontAmount from '../components/FontAmount.vue'
+import CustomCardCover from '../components/CustomCardCover.vue'
+import Report from "../log-center/log"
+import { RewardType } from '../types';
 
 var moment = require('moment');
 var ClipboardJS = require('clipboard')
@@ -255,47 +326,47 @@ const baseURL = api[process.env.NUXT_ENV.MODE]
 export default {
     name: 'luckdraw',
     components: {
-		FontAmount,
+		FontAmount,CustomCardCover
 	},
     head() {
 		return {
 			type: '',
 			title: this.title,
-			appVersionCode: 3,
-			meta: [
-				// facebook 
-				{
-					name: 'og:url',
-					content: this.jumpUrl + 'luckdraw/' + this.detail.postId
-				},
-				{
-					name: 'og:title',
-					content: this.metaTitle
-				},
-				{
-					name: 'og:image',
-					content: this.detail.postBizData.imagePath || this.detail.postBizData.customPosterUninstalled || ''
-				},
-				// twitter
-				{
-					name: 'twitter:card',
-					content: 'summary_large_image'
-				},
-				{
-					name: 'twitter:url',
-					content: this.jumpUrl + 'luckdraw/' + this.detail.postId
-				},
-				{
-					name: 'twitter:title',
-					content: this.metaTitle
-				},
-				{
-					name: 'twitter:image',
-					content: this.detail.postBizData.imagePath || this.detail.postBizData.customPosterUninstalled || ''
-				}
-			]
-		}
-	},
+            appVersionCode: appVersionCode,
+            meta: [
+                // facebook
+                {
+                    name: 'og:url',
+                    content: this.jumpUrl + 'luckdraw/' + this.detail.postId
+                },
+                {
+                    name: 'og:title',
+                    content: this.metaTitle
+                },
+                {
+                    name: 'og:image',
+                    content: this.detail.postBizData.imagePath || this.detail.postBizData.customPosterUninstalled || ''
+                },
+                // twitter
+                {
+                    name: 'twitter:card',
+                    content: 'summary_large_image'
+                },
+                {
+                    name: 'twitter:url',
+                    content: this.jumpUrl + 'luckdraw/' + this.detail.postId
+                },
+                {
+                    name: 'twitter:title',
+                    content: this.metaTitle
+                },
+                {
+                    name: 'twitter:image',
+                    content: this.detail.postBizData.imagePath || this.detail.postBizData.customPosterUninstalled || ''
+                }
+            ]
+        }
+    },
     data() {
         return {
             detail: {
@@ -316,12 +387,21 @@ export default {
             mid: '',
             status: '',  // not-open->未打开   opened->没有抽中   success->抽中了   expire->过期
             page_index: 1,
-			page_size: 20,
+            page_size: 20,
             validity: '',
             receiveAmount: '0',
             title: 'DeNet Giveaway',
             jumpUrl: jumpUrl,
-			metaTitle: 'DeNet: An Easy Web3 Tool For GIVEAWAY / AIRDROP',
+            metaTitle: 'DeNet: An Easy Web3 Tool For GIVEAWAY / AIRDROP',
+            reportStatus: 'normal',
+            customCover: '',
+            customGiveaway: '',
+        }
+    },
+    computed: {
+        // 货币类型的奖品
+        isMoneyPrize() {
+            return this.detail.postBizData.rewardType === RewardType.money;
         }
     },
     mounted() {
@@ -342,103 +422,157 @@ export default {
         });
     },
     async asyncData(params) {
-		let { route } = params;
-		let { data } = await axios.post(`${baseURL}/denet/post/getDetail`, {
-			baseInfo: {
-				appVersionCode: appVersionCode,
-				mid: function () {
-					return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
-						var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
-						return v.toString(16);
-					});
-				}()
-			},
-			params: {
-				postId: route.params.id || ''
-			}
-		})
-		if (data.code == 0) {
-			if (data.data && data.data.postBizData && typeof data.data.postBizData == 'string') {
-				data.data.postBizData = JSON.parse(data.data.postBizData)
-			}
-			if(data.data.postBizData === null) {
-				data.data.postBizData = {
-					postUserInfo: {}
-				}
-			}
-            console.log('detail', data.data)
-
-			return {
-				detail: data.data,
-			}
-		}
-	},
+        let { route } = params;
+        let { data } = await axios.post(`${baseURL}/denet/post/getDetail`, {
+            baseInfo: {
+                appVersionCode: appVersionCode,
+                mid: function () {
+                    return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
+                        var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
+                        return v.toString(16);
+                    });
+                }()
+            },
+            params: {
+                postId: route.params.id || ''
+            }
+        })
+        if (data.code == 0) {
+            if (data.data && data.data.postBizData && typeof data.data.postBizData == 'string') {
+                data.data.postBizData = JSON.parse(data.data.postBizData)
+            }
+            if (data.data.postBizData === null) {
+                data.data.postBizData = {
+                    postUserInfo: {}
+                }
+            }
+            return {
+                detail: data.data,
+                customCover: data.data.postBizData && data.data.postBizData.posterType == 2 ? 1 : 0,
+                customGiveaway: data.data.postBizData && data.data.postBizData.rewardType == 2 ? 1 : 0,
+            }
+        }
+    },
     methods: {
         checkBrowser() {
             this.linkHref = window.location.href;
             this.isChrome = isBrowser() == 'chrome';
-			this.isMobile = navigator.userAgent.match(/(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone)/i);
+            this.isMobile = navigator.userAgent.match(/(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone)/i);
             if (!this.isChrome) {
                 this.status = 'no-chrome'
             } else {
                 this.setPickupInfo()
             }
-		},
+            // report
+            setTimeout(() => {
+                this.reportData()
+            }, 500)
+        },
         async getConfig() {
             let { data } = await axios.post(`${baseURL}/denet/base/config/getFrontConfig`, {
-				baseInfo: {
-					appVersionCode: appVersionCode,
-					mid: this.mid
-				},
-				params: {}
-			})
-			if (data.code == 0) {
-				this.config = data.data;
-			}
+                baseInfo: {
+                    appVersionCode: appVersionCode,
+                    mid: this.mid
+                },
+                params: {}
+            })
+            if (data.code == 0) {
+                this.config = data.data;
+            }
         },
         setCookieMid() {
             let _cookie_mid_arr = Cookies.get('mid') || []
-			if (_cookie_mid_arr.length > 0) {
-				this.mid = JSON.parse(_cookie_mid_arr)[0].mid
-			} else {
-				this.mid = this.guid()
-				Cookies.set('mid', JSON.stringify([{ mid: this.mid }]), { expires: 1000 })
-			}
+            if (_cookie_mid_arr.length > 0) {
+                this.mid = JSON.parse(_cookie_mid_arr)[0].mid
+            } else {
+                this.mid = this.guid()
+                Cookies.set('mid', JSON.stringify([{ mid: this.mid }]), { expires: 1000 })
+            }
         },
         guid() {
-			return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
-				var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
-				return v.toString(16);
-			});
-		},
+            return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
+                var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
+                return v.toString(16);
+            });
+        },
         clickOpenChrome() {
-			window.open('https://www.google.com/chrome')
-		},
+            window.open('https://www.google.com/chrome')
+
+            let extParams = this.isMobile ? {} : { status: this.reportStatus }
+            Report.reportLog({
+                baseInfo: {
+                    appVersionCode: appVersionCode,
+                    mid: this.mid,
+                    pageSource: Report.pageSource.newUserLandingPage,
+                    appType,
+                    machineCode: this.mid
+                },
+                params: {
+                    eventData: {
+                        businessType: Report.businessType.buttonClick,
+                        objectType: Report.objectType.installButton,
+                        postId: this.detail.postId,
+                        srcContentId: this.detail.srcContentId,
+                        senderId: this.detail.srcUserId,
+                        redPacketType: 1,
+                        customCover: this.customCover,
+                        customGiveaway: this.customGiveaway,
+                    },
+                    extParams: extParams
+                }
+            })
+        },
         installExtension() {
             let { extensionsInstallChannel, extensionsInstallUrl } = this.config;
+            let extParams = this.isMobile ? {} : { status: this.reportStatus }
+
+            Report.reportLog({
+                baseInfo: {
+                    appVersionCode: appVersionCode,
+                    mid: this.mid,
+                    pageSource: Report.pageSource.newUserLandingPage,
+                    appType,
+                    machineCode: this.mid
+                },
+                params: {
+                    eventData: {
+                        businessType: Report.businessType.buttonClick,
+                        objectType: Report.objectType.installButton,
+                        postId: this.detail.postId,
+                        srcContentId: this.detail.srcContentId,
+                        senderId: this.detail.srcUserId,
+                        redPacketType: 1,
+                        customCover: this.customCover,
+                        customGiveaway: this.customGiveaway,
+                    },
+                    extParams: extParams,
+                }
+            })
+
             switch (extensionsInstallChannel) {
-				case "officeDownload":
-					location.href = url;
-					this.$router.push({
-						path: '/install'
-					})
-					break;
-				case "chromeAppStore":
-					window.open(extensionsInstallUrl)
-					break;
-			}
+                case "officeDownload":
+                    location.href = url;
+                    this.$router.push({
+                        path: '/install'
+                    })
+                    break;
+                case "chromeAppStore":
+                    window.open(extensionsInstallUrl)
+                    break;
+            }
         },
         setPickupInfo() {
             let pickupInfo = {
-				srcContentId: this.detail.srcContentId,
-				postNickName: this.detail.postBizData.postUserInfo.nickName,
+                srcContentId: this.detail.srcContentId || '',
+                postNickName: this.detail.postBizData.postUserInfo.nickName || '',
                 createTime: Date.now(),
-			};
-			Cookies.set('pickup_info', JSON.stringify(pickupInfo), { expires: 100 });
+                jump_type: 'luck_draw',
+            };
+            Cookies.set('jump_info', JSON.stringify(pickupInfo), { expires: 100 });
         },
         formatTime(time, _type = 'MM-DD HH:mm:ss') {
-			return moment(time).format(_type)
-		},
+            return moment(time).format(_type)
+        },
         getValidity(end_time) {
             let timer = setInterval(() => {
                 let time = moment(new Date().getTime())
@@ -456,16 +590,16 @@ export default {
             }, 1000)
         },
         handleScroll(e) {
-			e = e.target
-			if (this.luck_list_end) {
-				return
-			}
-			if ((e.clientHeight + e.scrollTop) / e.scrollHeight > .8) {
-				this.luck_list_end = false
-				this.page_index++
-				this.getReceivedList()
-			}
-		},
+            e = e.target
+            if (this.luck_list_end) {
+                return
+            }
+            if ((e.clientHeight + e.scrollTop) / e.scrollHeight > .8) {
+                this.luck_list_end = false
+                this.page_index++
+                this.getReceivedList()
+            }
+        },
         handleStatusPage() {
             // 如果 我领取过了
             // taskFinishStatus  任务完成状态(0:未完成,1:已完成,2:已过期)
@@ -480,6 +614,7 @@ export default {
                     if (this.receiveAmount == 0) {
                         // 领取到空红包
                         this.status = `opened`
+                        this.reportStatus = `empty`
                     } else {
                         // 显示成功页面
                         this.status = `success`
@@ -492,6 +627,7 @@ export default {
                     } else {
                         // 显示已经过期页面
                         this.status = 'expire'
+                        this.reportStatus = `empty`
                     }
                 }
             } else {
@@ -502,6 +638,7 @@ export default {
                     if (this.detail.postBizData.receiveTimeExpired) {
                         // 显示过期页面
                         this.status = 'expire'
+                        this.reportStatus = `empty`
                     } else {
                         // 如果 过了红包的领取截止时间 = false
                         // 显示未打开页面
@@ -511,6 +648,7 @@ export default {
                     // 红包状态 = 已经结束了 | 已经终止 | 终止退款中
                     // 显示过期页面
                     this.status = 'expire'
+                    this.reportStatus = `empty`
                 }
             }
 
@@ -524,41 +662,141 @@ export default {
             }
         },
         async getDetail(fn) {
-			let { data } = await axios.post(`${baseURL}/denet/post/getDetail`, {
-				baseInfo: {
-					appVersionCode: appVersionCode,
-					mid: this.mid
-				},
-				params: {
-					postId: this.detail.postId
-				}
-			})
-			if (data.code == 0) {
-				this.detail.postBizData = JSON.parse(data.data.postBizData)
+            let { data } = await axios.post(`${baseURL}/denet/post/getDetail`, {
+                baseInfo: {
+                    appVersionCode: appVersionCode,
+                    mid: this.mid
+                },
+                params: {
+                    postId: this.detail.postId
+                }
+            })
+            if (data.code == 0) {
+                this.detail.postBizData = JSON.parse(data.data.postBizData)
+                this.customCover = this.detail.postBizData && this.detail.postBizData.posterType == 2 ? 1 : 0;
+                this.customGiveaway = this.detail.postBizData && this.detail.postBizData.rewardType == 2 ? 1 : 0;
                 if (fn) fn();
-			}
-		},
+            }
+        },
         async getReceivedList() {
-			let { data } = await axios.post(`${baseURL}/denet/post/luckdrop/getReceivedList`, {
-				baseInfo: {
-					appVersionCode: appVersionCode,
-					mid: this.mid
-				},
-				params: {
-					pageNum: this.page_index,
-					pageSize: this.page_size,
-					postId: this.detail.postId || ''
-				}
-			})
-			if (data.code == 0) {
-				if (data.data.length > 0) {
-					this.luck_list = this.luck_list.concat(data.data)
-					this.luck_list_end = false
-				} else {
-					this.luck_list_end = true
-				}
-			}
-		},
+            let { data } = await axios.post(`${baseURL}/denet/post/luckdrop/getReceivedList`, {
+                baseInfo: {
+                    appVersionCode: appVersionCode,
+                    mid: this.mid
+                },
+                params: {
+                    pageNum: this.page_index,
+                    pageSize: this.page_size,
+                    postId: this.detail.postId || ''
+                }
+            })
+            if (data.code == 0) {
+                if (data.data.length > 0) {
+                    this.luck_list = this.luck_list.concat(data.data)
+                    this.luck_list_end = false
+                } else {
+                    this.luck_list_end = true
+                }
+            }
+        },
+
+        copyLinkHandle() {
+            Report.reportLog({
+                baseInfo: {
+                    appVersionCode: appVersionCode,
+                    mid: this.mid,
+                    pageSource: Report.pageSource.mobileLandingPage,
+                    appType,
+                    machineCode: this.mid
+                },
+                params: {
+                    eventData: {
+                        businessType: Report.businessType.buttonClick,
+                        objectType: Report.objectType.copyLinkButton,
+                        postId: this.detail.postId || '',
+                        srcContentId: this.detail.srcContentId || '',
+                        senderId: this.detail.srcUserId || '',
+                        redPacketType: 1,
+                        customCover: this.customCover,
+                        customGiveaway: this.customGiveaway,
+                    }
+                }
+            })
+        },
+        reportData() {
+            if (this.isMobile) {
+                // 手机端
+                Report.reportLog({
+                    baseInfo: {
+                        appVersionCode: appVersionCode,
+                        mid: this.mid,
+                        pageSource: Report.pageSource.mobileLandingPage,
+                        appType,
+                        machineCode: this.mid
+                    },
+                    params: {
+                        eventData: {
+                            businessType: Report.businessType.pageView,
+                            postId: this.detail.postId,
+                            srcContentId: this.detail.srcContentId,
+                            senderId: this.detail.srcUserId,
+                            redPacketType: 1,
+                            customCover: this.customCover,
+                            customGiveaway: this.customGiveaway,
+                        }
+                    }
+                })
+            } else if (this.isChrome) {
+                // pc端
+                Report.reportLog({
+                    baseInfo: {
+                        appVersionCode: appVersionCode,
+                        mid: this.mid,
+                        pageSource: Report.pageSource.newUserLandingPage,
+                        appType,
+                        machineCode: this.mid
+                    },
+                    params: {
+                        eventData: {
+                            businessType: Report.businessType.pageView,
+                            postId: this.detail.postId,
+                            srcContentId: this.detail.srcContentId,
+                            senderId: this.detail.srcUserId,
+                            redPacketType: 1,
+                            customCover: this.customCover,
+                            customGiveaway: this.customGiveaway,
+                        },
+                        extParams: {
+                            status: this.reportStatus,
+                        }
+                    }
+                });
+            } else {
+                Report.reportLog({
+                    baseInfo: {
+                        appVersionCode: appVersionCode,
+                        mid: this.mid,
+                        pageSource: Report.pageSource.newUserLandingPage,
+                        appType,
+                        machineCode: this.mid
+                    },
+                    params: {
+                        eventData: {
+                            businessType: Report.businessType.pageView,
+                            postId: this.detail.postId,
+                            srcContentId: this.detail.srcContentId,
+                            senderId: this.detail.srcUserId,
+                            redPacketType: 1,
+                            customCover: this.customCover,
+                            customGiveaway: this.customGiveaway,
+                        },
+                        extParams: {
+                            status: 'not-chrome',
+                        }
+                    }
+                })
+            }
+        }
     }
 }
 </script>
@@ -578,7 +816,7 @@ body,
     overflow: hidden;
     width: 100%;
     height: 100%;
-    background: #F5FAFF;
+    background: #fff;
     .loading {
         position: absolute;
         transform: translate(-50%, -50%);
@@ -607,6 +845,26 @@ body,
             margin: -50px auto 0;
             justify-content: space-between;
             width: 1000px;
+            position: relative;
+            .head-in-custom {
+                position: absolute;
+                bottom: 100%;
+                left: 0;
+                background: #fff;
+                display: flex;
+                align-items: center;
+                font-weight: 500;
+                font-size: 15px;
+                color: #000;
+                height: 54px;
+                img {
+                  width: 30px;
+                  height: 30px;
+                  border-radius: 50%;
+                  margin-right: 10px;
+                }
+
+            }
             .giveaway {
                 position: relative;
                 overflow: hidden;
@@ -615,6 +873,7 @@ body,
                 border-radius: 20px;
                 background-color: #fff;
                 box-shadow: 0px 2px 20px rgba(0, 0, 0, 0.1);
+
                 &.bg {
                     background: linear-gradient(17.98deg, #3438FF 3.69%, #8B56FC 74.32%);
                 }
@@ -622,6 +881,12 @@ body,
                     background: unset;
                     height: auto!important;
                 }
+                &.auto-height {
+                  height: auto;
+                }
+
+
+
                 .lottery {
                     position: absolute;
                     top: 0;
@@ -1020,6 +1285,12 @@ body,
                 color: #444444;
             }
         }
+        .luck-custom-prize {
+          font-weight: 500;
+          font-size: 14px;
+          letter-spacing: 0.3px;
+          color: #F5B945;
+      }
     }
     .luck-item:last-child {
         border: 0;

+ 176 - 104
pages/nft/group.vue

@@ -1,9 +1,7 @@
 <template>
     <div class="nft-content">
         <template v-if="isLoading">
-            <img
-                class="loading"
-                src="../../static/svg/icon-loading.svg" />
+            <img class="loading" src="../../static/svg/icon-loading.svg" />
         </template>
         <template v-else>
             <template v-if="isMobile">
@@ -46,11 +44,13 @@
                         <div class="footer">
                             <template v-if="isChrome">
                                 <div class="font">Install DeNet to Join The Group</div>
-                                <img class="btn" @click="installExtension" src="../../static/svg/icon-install-nft-plugin.svg" />
+                                <img class="btn" @click="installExtension"
+                                    src="../../static/svg/icon-install-nft-plugin.svg" />
                             </template>
                             <template v-else>
-                                <div class="font">Only Support to Use Chrome<br/>to Join Group</div>
-                                <img class="btn" @click="installChrome" src="../../static/svg/icon-install-nft-chrome.svg" />
+                                <div class="font">Only Support to Use Chrome<br />to Join Group</div>
+                                <img class="btn" @click="installChrome"
+                                    src="../../static/svg/icon-install-nft-chrome.svg" />
                             </template>
                         </div>
                     </div>
@@ -64,21 +64,20 @@
 import axios from 'axios'
 import Cookies from 'js-cookie'
 import { Toast } from 'vant';
-import { isBrowser } from '../../utils/help.js'
-
+import { isBrowser, appVersionCode, appType } from '../../utils/help.js'
+import Report from "@/log-center/log"
 const api = {
-	prod: 'https://api.denetme.net',
-	pre: 'https://preapi.denetme.net',
-	test: 'https://testapi.denetme.net'
+    prod: 'https://api.denetme.net',
+    pre: 'https://preapi.denetme.net',
+    test: 'https://testapi.denetme.net'
 }
 const page = {
-	prod: "https://h5.denetme.net",
-	pre: "https://preh5.denetme.net",
-	test: 'https://testh5.denetme.net'
+    prod: "https://h5.denetme.net",
+    pre: "https://preh5.denetme.net",
+    test: 'https://testh5.denetme.net'
 }
 const jumpUrl = page[process.env.NUXT_ENV.MODE] + '/'
 const baseURL = api[process.env.NUXT_ENV.MODE]
-const appVersionCode = 6;
 const ClipboardJS = require('clipboard')
 
 export default {
@@ -101,66 +100,66 @@ export default {
         }
     },
     head() {
-		return {
-			type: '',
-			title: this.title,
-			appVersionCode: appVersionCode,
-			meta: [
-				// facebook 
-				{
-					name: 'og:url',
-					content: this.jumpUrl + 'nft_group/' + this.$route.params.id
-				},
-				{
-					name: 'og:title',
-					content: this.metaTitle
-				},
-				{
-					name: 'og:image',
-					content: this.postBizData.groupImagePath || ''
-				},
-				// twitter
-				{
-					name: 'twitter:card',
-					content: 'summary_large_image'
-				},
-				{
-					name: 'twitter:url',
-					content: this.jumpUrl + 'nft_group/' + this.$route.params.id
-				},
-				{
-					name: 'twitter:title',
-					content: this.metaTitle
-				},
-				{
-					name: 'twitter:image',
-					content: this.postBizData.groupImagePath || ''
-				}
-			]
-		}
-	},
+        return {
+            type: '',
+            title: this.title,
+            appVersionCode: appVersionCode,
+            meta: [
+                // facebook 
+                {
+                    name: 'og:url',
+                    content: this.jumpUrl + 'nft_group/' + this.$route.params.id
+                },
+                {
+                    name: 'og:title',
+                    content: this.metaTitle
+                },
+                {
+                    name: 'og:image',
+                    content: this.postBizData.groupImagePath || ''
+                },
+                // twitter
+                {
+                    name: 'twitter:card',
+                    content: 'summary_large_image'
+                },
+                {
+                    name: 'twitter:url',
+                    content: this.jumpUrl + 'nft_group/' + this.$route.params.id
+                },
+                {
+                    name: 'twitter:title',
+                    content: this.metaTitle
+                },
+                {
+                    name: 'twitter:image',
+                    content: this.postBizData.groupImagePath || ''
+                }
+            ]
+        }
+    },
     async asyncData(params) {
         let { route } = params;
-		let { data } = await axios.post(`${baseURL}/denet/post/getDetail`, {
-			baseInfo: {
-				appVersionCode: appVersionCode,
-				mid: function () {
-					return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
-						var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
-						return v.toString(16);
-					});
-				}()
-			},
-			params: {
-				postId: route.params.id || ''
-			}
-		})
-		if (data.code == 0 && data.data !== null) {
+        let { data } = await axios.post(`${baseURL}/denet/post/getDetail`, {
+            baseInfo: {
+                appVersionCode: appVersionCode,
+                mid: function () {
+                    return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
+                        var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
+                        return v.toString(16);
+                    });
+                }()
+            },
+            params: {
+                postId: route.params.id || ''
+            }
+        })
+        if (data.code == 0 && data.data !== null) {
             return {
                 detail: data.data,
                 postBizData: JSON.parse(data.data.postBizData),
             }
-		}
+        }
     },
     created() {
         this.setCookieMid();
@@ -172,28 +171,76 @@ export default {
         this.isLoading = false;
 
         var clipboard = new ClipboardJS('.btn');
+        let that = this
         clipboard.on('success', function (e) {
             Toast('copy success');
+            that.trackingClick()
             e.clearSelection();
         });
+
+        // 埋点
+        this.pageSource = Report.pageSource.newUserLandingPage
+        if (this.isMobile) {
+            this.pageSource = Report.pageSource.mobileLandingPage
+        }
+        Report.reportLog({
+            baseInfo: {
+                appVersionCode: appVersionCode,
+                mid: this.mid,
+                pageSource: this.pageSource,
+                appType,
+                machineCode: this.mid
+            },
+            params: {
+                eventData: {
+                    businessType: Report.businessType.pageView,
+                    postId: this.detail.postId,
+                    srcContentId: this.detail.srcContentId,
+                    senderId: this.detail.srcUserId,
+                    redPacketType: 3,
+                }
+            }
+        })
     },
     methods: {
+        trackingClick() {
+            Report.reportLog({
+                baseInfo: {
+                    appVersionCode: appVersionCode,
+                    mid: this.mid,
+                    pageSource: this.pageSource,
+                    appType,
+                    machineCode: this.mid
+                },
+                params: {
+                    eventData: {
+                        businessType: Report.businessType.buttonClick,
+                        postId: this.detail.postId,
+                        srcContentId: this.detail.srcContentId,
+                        senderId: this.detail.srcUserId,
+                        redPacketType: 3,
+                    }
+                }
+            })
+        },
         guid() {
-			return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
-				var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
-				return v.toString(16);
-			});
-		},
+            return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
+                var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
+                return v.toString(16);
+            });
+        },
         setCookieMid() {
-			let _cookie_mid_arr = Cookies.get('mid') || []
-			if (_cookie_mid_arr.length > 0) {
-				this.mid = JSON.parse(_cookie_mid_arr)[0].mid
-			} else {
-				this.mid = this.guid()
-				Cookies.set('mid', JSON.stringify([{ mid: this.mid }]), { expires: 1000 })
-			}
-		},
+            let _cookie_mid_arr = Cookies.get('mid') || []
+            if (_cookie_mid_arr.length > 0) {
+                this.mid = JSON.parse(_cookie_mid_arr)[0].mid
+            } else {
+                this.mid = this.guid()
+                Cookies.set('mid', JSON.stringify([{ mid: this.mid }]), { expires: 1000 })
+            }
+        },
         installExtension() {
+            // 埋点
+            this.trackingClick()
             let { extensionsInstallUrl } = this.config;
             window.open(extensionsInstallUrl)
         },
@@ -201,29 +248,30 @@ export default {
             window.open('https://www.google.com/chrome')
         },
         async getConfig() {
-			let { data } = await axios.post(`${baseURL}/denet/base/config/getFrontConfig`, {
-				baseInfo: {
-					appVersionCode: appVersionCode,
-					mid: this.mid
-				},
-				params: {}
-			})
-			if (data.code == 0) {
-				this.config = data.data;
-			}
-		},
+            let { data } = await axios.post(`${baseURL}/denet/base/config/getFrontConfig`, {
+                baseInfo: {
+                    appVersionCode: appVersionCode,
+                    mid: this.mid
+                },
+                params: {}
+            })
+            if (data.code == 0) {
+                this.config = data.data;
+            }
+        },
         checkBrowser() {
             this.linkHref = window.location.href;
             this.isChrome = isBrowser() == 'chrome';
-			this.isMobile = navigator.userAgent.match(/(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone)/i);
-		},
+            this.isMobile = navigator.userAgent.match(/(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone)/i);
+        },
         setNftInfo() {
-			let nftGroupInfo = {
-				twitterAccount: this.postBizData.defaultTwitterAccount || '',
+            let nftGroupInfo = {
+                twitterAccount: this.postBizData.defaultTwitterAccount || '',
                 createTime: Date.now(),
-			};
-			Cookies.set('nft_group_info', JSON.stringify(nftGroupInfo), { expires: 100 });
-		},
+                jump_type: 'nft_group_info',
+            };
+            Cookies.set('jump_info', JSON.stringify(nftGroupInfo), { expires: 100 });
+        },
     }
 }
 </script>
@@ -233,10 +281,10 @@ html,
 body,
 #__nuxt,
 #__layout {
-	width: 100%;
-	height: 100%;
-	padding: 0;
-	margin: 0;
+    width: 100%;
+    height: 100%;
+    padding: 0;
+    margin: 0;
 }
 
 .nft-content {
@@ -244,6 +292,7 @@ body,
     width: 100%;
     height: 100%;
     background: linear-gradient(180deg, #FFFFFF 0%, #F0F7FE 94.31%);
+
     .loading {
         position: absolute;
         transform: translate(-50%, -50%);
@@ -253,25 +302,30 @@ body,
         width: 40px;
         border-radius: 50%;
     }
+
     .logo {
         display: flex;
         align-items: center;
         height: 70px;
         margin-left: 25px;
+
         img {
             width: 99px;
             height: 32px;
         }
     }
+
     .show {
         display: flex;
         align-items: center;
         height: calc(100% - 70px);
+
         .center {
             display: flex;
             flex-direction: column;
             width: 505px;
             margin: -50px auto 0;
+
             .header {
                 display: flex;
                 flex-direction: column;
@@ -281,21 +335,25 @@ body,
                 justify-content: center;
                 border-radius: 16px 16px 0 0;
                 background: url('../../static/svg/icon-nft-group-pc.svg') no-repeat right bottom #48B1F7;
+
                 .core {
                     display: flex;
                     align-items: center;
+
                     .core_logo {
                         overflow: hidden;
                         width: 54px;
                         height: 54px;
                         border-radius: 6px;
                         background-color: #fff;
+
                         img {
                             width: 100%;
                             height: 100%;
                             border-radius: 8px;
                         }
                     }
+
                     .core_title {
                         color: #fff;
                         font-size: 26px;
@@ -303,13 +361,16 @@ body,
                         margin-left: 16px;
                     }
                 }
+
                 .member {
                     color: #fff;
                     font-size: 12px;
                     font-weight: 500;
                     margin-top: 24px;
+
                     label {
                         margin-right: 17px;
+
                         img {
                             margin-top: -3px;
                             vertical-align: middle;
@@ -317,6 +378,7 @@ body,
                     }
                 }
             }
+
             .footer {
                 display: flex;
                 align-items: center;
@@ -326,12 +388,14 @@ body,
                 height: 90px;
                 border-radius: 0 0 16px 16px;
                 border: solid 1px #E2E2E2;
+
                 .font {
                     flex: 1;
                     text-align: center;
                     font-size: 16px;
                     font-weight: 500;
                 }
+
                 .btn {
                     width: 200px;
                     box-sizing: unset;
@@ -348,12 +412,14 @@ body,
     padding: 0 16px;
     box-sizing: border-box;
     transform: translateY(-50%);
+
     .banner {
         position: relative;
         overflow: hidden;
         height: 180px;
         border-radius: 10px;
         background: url('../../static/svg/icon-nft-group-mobile.svg') no-repeat right bottom #48B1F7;
+
         .logo {
             position: absolute;
             display: flex;
@@ -368,6 +434,7 @@ body,
             transform: translateX(-50%);
             border-radius: 5px;
             background-color: #FFFFFF;
+
             .img {
                 position: unset;
                 width: 50px;
@@ -375,6 +442,7 @@ body,
                 border-radius: 5px;
             }
         }
+
         .desc {
             position: absolute;
             z-index: 2;
@@ -395,6 +463,7 @@ body,
             overflow: hidden;
         }
     }
+
     .title {
         color: #000000;
         font-weight: 600;
@@ -402,6 +471,7 @@ body,
         text-align: center;
         padding: 39px 0 7px;
     }
+
     .desc {
         color: #8A8A8A;
         font-size: 13px;
@@ -409,8 +479,10 @@ body,
         word-break: break-all;
         text-align: center;
     }
+
     .copy {
         margin-top: 35px;
+
         button {
             width: 100%;
             border: 0;

+ 170 - 103
pages/nft/index.vue

@@ -1,9 +1,7 @@
 <template>
     <div class="nft-content">
         <template v-if="isLoading">
-            <img
-                class="loading"
-                src="../../static/svg/icon-loading.svg" />
+            <img class="loading" src="../../static/svg/icon-loading.svg" />
         </template>
         <template v-else>
             <template v-if="isMobile">
@@ -27,12 +25,14 @@
                         </div>
                         <div class="info">
                             <template v-if="isChrome">
-                                <div class="title">Install DeNet Plugin<br/>to Buy NFT</div>
-                                <img class="buy" @click="installExtension" src="../../static/img/icon-install-plugin.svg" />
+                                <div class="title">Install DeNet Plugin<br />to Buy NFT</div>
+                                <img class="buy" @click="installExtension"
+                                    src="../../static/img/icon-install-plugin.svg" />
                             </template>
                             <template v-else>
                                 <div class="title">Only Support to Use Chrome to buy NFT</div>
-                                <img class="buy" @click="installChrome" src="../../static/img/icon-install-chrome.svg" />
+                                <img class="buy" @click="installChrome"
+                                    src="../../static/img/icon-install-chrome.svg" />
                             </template>
                         </div>
                     </div>
@@ -46,21 +46,21 @@
 import axios from 'axios'
 import Cookies from 'js-cookie'
 import { Toast } from 'vant';
-import { isBrowser } from '../../utils/help.js'
+import { isBrowser, appVersionCode, appType } from '../../utils/help.js'
+import Report from "@/log-center/log"
 
 const api = {
-	prod: 'https://api.denetme.net',
-	pre: 'https://preapi.denetme.net',
-	test: 'https://testapi.denetme.net'
+    prod: 'https://api.denetme.net',
+    pre: 'https://preapi.denetme.net',
+    test: 'https://testapi.denetme.net'
 }
 const page = {
-	prod: "https://h5.denetme.net",
-	pre: "https://preh5.denetme.net",
-	test: 'https://testh5.denetme.net'
+    prod: "https://h5.denetme.net",
+    pre: "https://preh5.denetme.net",
+    test: 'https://testh5.denetme.net'
 }
 const jumpUrl = page[process.env.NUXT_ENV.MODE] + '/'
 const baseURL = api[process.env.NUXT_ENV.MODE]
-const appVersionCode = 6;
 const ClipboardJS = require('clipboard')
 
 export default {
@@ -80,65 +80,65 @@ export default {
         }
     },
     head() {
-		return {
-			type: '',
-			title: this.title,
-			appVersionCode: appVersionCode,
-			meta: [
-				// facebook 
-				{
-					name: 'og:url',
-					content: this.jumpUrl + 'nft/' + this.$route.params.id + `/${this.$route.params.account}`
-				},
-				{
-					name: 'og:title',
-					content: this.metaTitle
-				},
-				{
-					name: 'og:image',
-					content: this.detail.linkImagePath || ''
-				},
-				// twitter
-				{
-					name: 'twitter:card',
-					content: 'summary_large_image'
-				},
-				{
-					name: 'twitter:url',
-					content: this.jumpUrl + 'nft/' + this.$route.params.id + `/${this.$route.params.account}`
-				},
-				{
-					name: 'twitter:title',
-					content: this.metaTitle
-				},
-				{
-					name: 'twitter:image',
-					content: this.detail.linkImagePath || ''
-				}
-			]
-		}
-	},
+        return {
+            type: '',
+            title: this.title,
+            appVersionCode: appVersionCode,
+            meta: [
+                // facebook 
+                {
+                    name: 'og:url',
+                    content: this.jumpUrl + 'nft/' + this.$route.params.id + `/${this.$route.params.account}`
+                },
+                {
+                    name: 'og:title',
+                    content: this.metaTitle
+                },
+                {
+                    name: 'og:image',
+                    content: this.detail.linkImagePath || ''
+                },
+                // twitter
+                {
+                    name: 'twitter:card',
+                    content: 'summary_large_image'
+                },
+                {
+                    name: 'twitter:url',
+                    content: this.jumpUrl + 'nft/' + this.$route.params.id + `/${this.$route.params.account}`
+                },
+                {
+                    name: 'twitter:title',
+                    content: this.metaTitle
+                },
+                {
+                    name: 'twitter:image',
+                    content: this.detail.linkImagePath || ''
+                }
+            ]
+        }
+    },
     async asyncData(params) {
         let { route } = params;
-		let { data } = await axios.post(`${baseURL}/denet/nft/project/getNftProjectInfo`, {
-			baseInfo: {
-				appVersionCode: appVersionCode,
-				mid: function () {
-					return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
-						var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
-						return v.toString(16);
-					});
-				}()
-			},
-			params: {
-				nftProjectId: route.params.id || ''
-			}
-		})
-		if (data.code == 0 && data.data !== null) {
+        let { data } = await axios.post(`${baseURL}/denet/nft/project/getNftProjectInfo`, {
+            baseInfo: {
+                appVersionCode: appVersionCode,
+                mid: function () {
+                    return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
+                        var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
+                        return v.toString(16);
+                    });
+                }()
+            },
+            params: {
+                nftProjectId: route.params.id || ''
+            }
+        })
+        if (data.code == 0 && data.data !== null) {
             return {
                 detail: data.data,
             }
-		}
+        }
     },
     created() {
         this.setCookieMid();
@@ -150,28 +150,77 @@ export default {
         this.isLoading = false;
 
         var clipboard = new ClipboardJS('.btn');
+        let that = this
         clipboard.on('success', function (e) {
             Toast('copy success');
+            // 埋点
+            that.trackingClick()
             e.clearSelection();
         });
+        this.pageSource = Report.pageSource.newUserLandingPage
+        // 埋点
+        if (this.isMobile) {
+            this.pageSource = Report.pageSource.mobileLandingPage
+        }
+        Report.reportLog({
+            baseInfo: {
+                appVersionCode: appVersionCode,
+                mid: this.mid,
+                pageSource: this.pageSource,
+                appType,
+                machineCode: this.mid
+            },
+            params: {
+                eventData: {
+                    businessType: Report.businessType.pageView,
+                    postId: this.detail.postId,
+                    srcContentId: this.detail.srcContentId,
+                    senderId: this.detail.srcUserId,
+                    redPacketType: 2,
+                }
+            }
+        })
     },
     methods: {
+        trackingClick() {
+            Report.reportLog({
+                baseInfo: {
+                    appVersionCode: appVersionCode,
+                    mid: this.mid,
+                    pageSource: this.pageSource,
+                    appType,
+                    machineCode: this.mid
+                },
+                params: {
+                    eventData: {
+                        businessType: Report.businessType.buttonClick,
+                        objectType: Report.objectType.installButton,
+                        postId: this.detail.postId,
+                        srcContentId: this.detail.srcContentId,
+                        senderId: this.detail.srcUserId,
+                        redPacketType: 2,
+                    }
+                }
+            })
+        },
         guid() {
-			return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
-				var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
-				return v.toString(16);
-			});
-		},
+            return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
+                var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
+                return v.toString(16);
+            });
+        },
         setCookieMid() {
-			let _cookie_mid_arr = Cookies.get('mid') || []
-			if (_cookie_mid_arr.length > 0) {
-				this.mid = JSON.parse(_cookie_mid_arr)[0].mid
-			} else {
-				this.mid = this.guid()
-				Cookies.set('mid', JSON.stringify([{ mid: this.mid }]), { expires: 1000 })
-			}
-		},
+            let _cookie_mid_arr = Cookies.get('mid') || []
+            if (_cookie_mid_arr.length > 0) {
+                this.mid = JSON.parse(_cookie_mid_arr)[0].mid
+            } else {
+                this.mid = this.guid()
+                Cookies.set('mid', JSON.stringify([{ mid: this.mid }]), { expires: 1000 })
+            }
+        },
         installExtension() {
+            // 埋点
+            this.trackingClick()
             let { extensionsInstallUrl } = this.config;
             window.open(extensionsInstallUrl)
         },
@@ -179,30 +228,31 @@ export default {
             window.open('https://www.google.com/chrome')
         },
         async getConfig() {
-			let { data } = await axios.post(`${baseURL}/denet/base/config/getFrontConfig`, {
-				baseInfo: {
-					appVersionCode: appVersionCode,
-					mid: this.mid
-				},
-				params: {}
-			})
-			if (data.code == 0) {
-				this.config = data.data;
-			}
-		},
+            let { data } = await axios.post(`${baseURL}/denet/base/config/getFrontConfig`, {
+                baseInfo: {
+                    appVersionCode: appVersionCode,
+                    mid: this.mid
+                },
+                params: {}
+            })
+            if (data.code == 0) {
+                this.config = data.data;
+            }
+        },
         checkBrowser() {
             this.linkHref = window.location.href;
             this.isChrome = isBrowser() == 'chrome';
-			this.isMobile = navigator.userAgent.match(/(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone)/i);
-		},
+            this.isMobile = navigator.userAgent.match(/(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone)/i);
+        },
         setNftInfo() {
-			let nftInfo = {
-				nftProjectId: this.detail.nftProjectId,
+            let nftInfo = {
+                nftProjectId: this.detail.nftProjectId || '',
                 twitterAccount: atob(this.$route.params.account || ''),
                 createTime: Date.now(),
-			};
-			Cookies.set('nft_info', JSON.stringify(nftInfo), { expires: 100 });
-		},
+                jump_type: 'nft_info',
+            };
+            Cookies.set('jump_info', JSON.stringify(nftInfo), { expires: 100 });
+        },
     }
 }
 </script>
@@ -212,10 +262,10 @@ html,
 body,
 #__nuxt,
 #__layout {
-	width: 100%;
-	height: 100%;
-	padding: 0;
-	margin: 0;
+    width: 100%;
+    height: 100%;
+    padding: 0;
+    margin: 0;
 }
 
 .nft-content {
@@ -223,6 +273,7 @@ body,
     width: 100%;
     height: 100%;
     background: linear-gradient(180deg, #FFFFFF 0%, #F0F7FE 94.31%);
+
     .loading {
         position: absolute;
         transform: translate(-50%, -50%);
@@ -232,40 +283,49 @@ body,
         width: 40px;
         border-radius: 50%;
     }
+
     .logo {
         display: flex;
         align-items: center;
         height: 70px;
         margin-left: 25px;
+
         img {
             width: 99px;
             height: 32px;
         }
     }
+
     .show {
         display: flex;
         align-items: center;
         height: calc(100% - 70px);
+
         .center {
             display: flex;
             margin: -50px auto 0;
             width: 1000px;
+
             .img {
                 width: 50%;
                 margin-right: 6%;
+
                 img {
                     width: 100%;
                 }
             }
+
             .info {
                 display: flex;
                 flex-direction: column;
                 justify-content: center;
                 width: 44%;
+
                 .tag {
                     width: 25%;
                     margin-bottom: 6px;
                 }
+
                 .title {
                     color: #3A4B56;
                     font-size: 2.2vw;
@@ -274,6 +334,7 @@ body,
                     word-break: break-word;
                     margin-bottom: 1vw;
                 }
+
                 .buy {
                     width: 75%;
                     max-width: 263px;
@@ -287,12 +348,15 @@ body,
 
 .small {
     padding: 30px 20px;
+
     .banner {
         width: 100%;
+
         img {
             width: 100%;
         }
     }
+
     .title {
         color: #000000;
         font-weight: 600;
@@ -300,6 +364,7 @@ body,
         text-align: center;
         padding: 17px 0 12px;
     }
+
     .desc {
         color: #8A8A8A;
         font-size: 13px;
@@ -307,8 +372,10 @@ body,
         word-break: break-all;
         text-align: center;
     }
+
     .copy {
         margin-top: 35px;
+
         button {
             width: 100%;
             border: 0;

+ 297 - 0
pages/toolbox/index.vue

@@ -0,0 +1,297 @@
+<template>
+    <div class="main">
+        <!-- pc -->
+        <div v-if="device == 'chrome' || device == 'no-chrome'" class="content">
+            <v-logo></v-logo>
+            <div class="tool-cover">
+                <img :src="detail.postBizData.linkImagePath" alt="">
+            </div>
+            <!-- 非chrome -->
+            <div v-if="device == 'no-chrome'">
+                <div class="txt">Use chrome browser to access Subway Surfers</div>
+                <install-chrome></install-chrome>
+            </div>
+            <!-- chrome -->
+            <div v-if="device == 'chrome'">
+                <div class="txt">Use chrome browser to access Subway Surfers</div>
+                <install-extension :extensionsInstallUrl="config.extensionsInstallUrl"></install-extension>
+            </div>
+        </div>
+
+        <!-- 移动端 -->
+        <div v-if="device == 'ios' || device == '安卓'" class="mobile">
+            <div class="mobile-content">
+                <img :src="detail.postBizData.linkImagePath" alt="">
+                <div class="title">Open link on PC to use Subway Surfers</div>
+            </div>
+            <div class="area-button">
+                <div class="btn1" @click="clickExtension">
+                    Install Chrome Extension
+                </div>
+                <div class="btn2" @click="clickCopy" :data-clipboard-text="copy_link">
+                    Copy Link
+                </div>
+            </div>
+        </div>
+    </div>
+</template>
+<script>
+import VLogo from '@/components/logo.vue'
+import InstallChrome from '@/components/InstallChrome.vue'
+import InstallExtension from '@/components/InstallExtension.vue'
+import { getBrowserType, baseURL, appVersionCode, jumpUrl } from '@/utils/help.js'
+import axios from 'axios'
+import Cookies from 'js-cookie'
+import { Toast } from 'vant';
+
+
+var ClipboardJS = require('clipboard')
+
+export default {
+    name: 'tool_box',
+    data() {
+        return {
+            config: {},
+            copy_link: '',
+            title: 'Install DeNet Plugin to Participate',
+            metaTitle: 'Install DeNet Plugin to Participate',
+            device: '',
+            detail: {}
+        }
+    },
+    head() {
+        return {
+            type: '',
+            title: this.title,
+            appVersionCode: appVersionCode,
+            meta: [
+                // facebook 
+                {
+                    name: 'og:url',
+                    content: jumpUrl + 'toolbox/' + this.$route.params.id
+                },
+                {
+                    name: 'og:title',
+                    content: this.metaTitle
+                },
+                {
+                    name: 'og:image',
+                    content: this.detail.postBizData.linkImagePath || ''
+                },
+                // twitter
+                {
+                    name: 'twitter:card',
+                    content: 'summary_large_image'
+                },
+                {
+                    name: 'twitter:url',
+                    content: jumpUrl + 'toolbox/' + this.$route.params.id
+                },
+                {
+                    name: 'twitter:title',
+                    content: this.detail.postBizData.linkTitle || this.metaTitle
+                },
+                {
+                    name: 'twitter:image',
+                    content: this.detail.postBizData.linkImagePath || ''
+                }
+            ]
+        }
+    },
+    components: {
+        VLogo,
+        InstallChrome,
+        InstallExtension
+    },
+    async asyncData(params) {
+        let { route } = params;
+        let { data } = await axios.post(`${baseURL}/denet/post/getDetail`, {
+            baseInfo: {
+                appVersionCode: appVersionCode,
+                mid: '00000000-0000-0000-0000-000000000000',
+            },
+            params: {
+                postId: route.params.id || ''
+            }
+        })
+        if (data.code == 0) {
+            if (data.data && data.data.postBizData && typeof data.data.postBizData == 'string') {
+                data.data.postBizData = JSON.parse(data.data.postBizData)
+            }
+            if (data.data.postBizData === null) {
+                data.data.postBizData = {
+                    postUserInfo: {}
+                }
+            }
+            console.log('detail', data.data)
+
+            return {
+                detail: data.data,
+            }
+        }
+    },
+    mounted() {
+        this.copy_link = window.location.href
+        this.device = getBrowserType()
+        this.getConfig()
+        console.log('device', this.device)
+        if (this.device == 'chrome') {
+            this.setCookie()
+        }
+    },
+
+    methods: {
+        setCookie() {
+            let pickupInfo = {
+                srcContentId: this.detail.srcContentId || '',
+                postNickName: this.detail.srcUserId || '',
+                createTime: Date.now(),
+                jump_type: 'jump_info',
+            };
+            Cookies.set('jump_info', JSON.stringify(pickupInfo), { expires: 1000 });
+        },
+        async getConfig() {
+            let { data } = await axios.post(`${baseURL}/denet/base/config/getFrontConfig`, {
+                baseInfo: {
+                    appVersionCode: this.appVersionCode,
+                    mid: this.mid
+                },
+                params: {
+                }
+            })
+            if (data.code == 0) {
+                this.config = data.data;
+            }
+        },
+        clickCopy() {
+            // 复制链接
+            var clipboard = new ClipboardJS('.btn2');
+            clipboard.on('success', function (e) {
+                Toast('copy success');
+                e.clearSelection();
+            });
+
+            clipboard.on('error', function (e) {
+                Toast('copy error');
+            });
+        },
+        clickExtension() {
+            window.open(this.config.extensionsInstallUrl)
+        }
+    }
+}
+
+</script>
+<style lang="scss" >
+html,
+body,
+#__nuxt,
+#__layout {
+    margin: 0;
+    padding: 0;
+    width: 100%;
+    height: 100%;
+    background: #F5FAFF;
+
+
+}
+
+.main {
+    width: 100%;
+    height: 100%;
+
+    .tool-cover {
+        min-width: 400px;
+        margin-right: 90px;
+
+        img {
+            max-height: 270px;
+        }
+    }
+
+    .content {
+        width: 100%;
+        height: 100%;
+        display: flex;
+        justify-content: center;
+        align-items: center;
+        padding-bottom: 70px;
+
+        .txt {
+            width: 400px;
+            font-weight: 700;
+            font-size: 36px;
+            line-height: 44px;
+            /* or 122% */
+
+            letter-spacing: 0.3px;
+
+            color: #323232;
+            margin-bottom: 40px;
+        }
+    }
+
+    .mobile {
+        .mobile-content {
+            padding: 36px 16px 0 16px;
+
+            img {
+                width: 100%;
+                margin-bottom: 25px;
+                border-radius: 5px;
+            }
+
+            .title {
+                font-weight: 700;
+                font-size: 22px;
+                line-height: 26px;
+                text-align: center;
+                letter-spacing: 0.3px;
+                color: #000000;
+                width: 240px;
+                margin: 0 auto;
+            }
+        }
+
+
+
+        .area-button {
+            position: fixed;
+            width: 100%;
+            padding: 27px 16px 25px 16px;
+            bottom: 0;
+            height: 170px;
+
+            .btn1 {
+                height: 50px;
+                line-height: 50px;
+                background: #1D9BF0;
+                border-radius: 100px;
+                width: 100%;
+                font-weight: 600;
+                font-size: 18px;
+                text-align: center;
+                letter-spacing: 0.3px;
+
+                color: #FFFFFF;
+                margin-bottom: 16px;
+            }
+
+            .btn2 {
+                height: 50px;
+                line-height: 50px;
+                background: rgba(29, 155, 240, 0.01);
+                border: 1px solid #1D9BF0;
+                border-radius: 100px;
+                width: 100%;
+                font-weight: 600;
+                font-size: 18px;
+                text-align: center;
+                letter-spacing: 0.3px;
+                color: #1D9BF0;
+
+            }
+        }
+    }
+}
+</style>

+ 3 - 0
static/svg/icon-gift-inline.svg

@@ -0,0 +1,3 @@
+<svg width="22" height="23" viewBox="0 0 22 23" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M2.93203 20.381C2.93203 20.7925 3.25974 21.125 3.66536 21.125H10.2195V12.3835H2.93203V20.381ZM11.7779 21.125H18.332C18.7377 21.125 19.0654 20.7925 19.0654 20.381V12.3835H11.7779V21.125ZM19.432 6.80374H16.0495C16.3612 6.30622 16.5445 5.7157 16.5445 5.08333C16.5445 3.3141 15.126 1.875 13.382 1.875C12.4333 1.875 11.5785 2.30278 10.9987 2.97699C10.4189 2.30278 9.56411 1.875 8.61536 1.875C6.87141 1.875 5.45286 3.3141 5.45286 5.08333C5.45286 5.7157 5.63391 6.30622 5.94786 6.80374H2.56536C2.15974 6.80374 1.83203 7.1362 1.83203 7.54771V10.8025H10.2195V6.80374H11.7779V10.8025H20.1654V7.54771C20.1654 7.1362 19.8377 6.80374 19.432 6.80374ZM10.2195 6.71075H8.61536C7.73078 6.71075 7.0112 5.98074 7.0112 5.08333C7.0112 4.18593 7.73078 3.45592 8.61536 3.45592C9.49995 3.45592 10.2195 4.18593 10.2195 5.08333V6.71075ZM13.382 6.71075H11.7779V5.08333C11.7779 4.18593 12.4974 3.45592 13.382 3.45592C14.2666 3.45592 14.9862 4.18593 14.9862 5.08333C14.9862 5.98074 14.2666 6.71075 13.382 6.71075Z" fill="#F5C03F"/>
+</svg>

BIN
static/svg/icon-gift.gif


Diferenças do arquivo suprimidas por serem muito extensas
+ 3 - 0
static/svg/icon-install-chrome.svg


+ 7 - 18
static/svg/icon-logo.svg

@@ -1,19 +1,8 @@
-<svg width="96" height="30" viewBox="0 0 96 30" fill="none" xmlns="http://www.w3.org/2000/svg">
-<path opacity="0.7" d="M41.2988 7.9082V22H46.2695C50.4688 22 52.9395 19.3828 52.9395 14.9297C52.9395 10.4863 50.459 7.9082 46.2695 7.9082H41.2988ZM43.4863 9.79297H46.0645C49.043 9.79297 50.7031 11.6289 50.7031 14.9492C50.7031 18.2793 49.0527 20.1055 46.0645 20.1055H43.4863V9.79297ZM59.0723 13.2402C60.5469 13.2402 61.543 14.3438 61.5918 15.916H56.4551C56.5625 14.3633 57.5977 13.2402 59.0723 13.2402ZM61.582 18.9824C61.2988 19.8809 60.4102 20.4863 59.209 20.4863C57.5195 20.4863 56.4453 19.3047 56.4453 17.5176V17.3906H63.7012V16.668C63.7012 13.5527 61.9238 11.541 59.0723 11.541C56.1719 11.541 54.3164 13.6895 54.3164 16.9121C54.3164 20.1543 56.1426 22.1953 59.1602 22.1953C61.5137 22.1953 63.291 20.8574 63.584 18.9824H61.582ZM67.7246 22V11.6191H67.8125L75.1172 22H77.0898V7.9082H74.9609V18.2988H74.8828L67.5781 7.9082H65.5957V22H67.7246ZM83.7402 13.2402C85.2148 13.2402 86.2109 14.3438 86.2598 15.916H81.123C81.2305 14.3633 82.2656 13.2402 83.7402 13.2402ZM86.25 18.9824C85.9668 19.8809 85.0781 20.4863 83.877 20.4863C82.1875 20.4863 81.1133 19.3047 81.1133 17.5176V17.3906H88.3691V16.668C88.3691 13.5527 86.5918 11.541 83.7402 11.541C80.8398 11.541 78.9844 13.6895 78.9844 16.9121C78.9844 20.1543 80.8105 22.1953 83.8281 22.1953C86.1816 22.1953 87.959 20.8574 88.252 18.9824H86.25ZM90.625 9.29492V11.7266H89.1309V13.3965H90.625V19.2949C90.625 21.2773 91.4355 22.0684 93.5156 22.0684C93.9844 22.0684 94.4531 22.0293 94.6875 21.9707V20.3008C94.5508 20.3301 94.209 20.3496 93.9941 20.3496C93.1348 20.3496 92.7441 19.9492 92.7441 19.0605V13.3965H94.6973V11.7266H92.7441V9.29492H90.625Z" fill="black"/>
-<g clip-path="url(#clip0_14299_11434)">
-<circle cx="14.6621" cy="14.0625" r="13.125" fill="url(#paint0_linear_14299_11434)" stroke="#28ACFC" stroke-width="1.875"/>
-<path opacity="0.7" fill-rule="evenodd" clip-rule="evenodd" d="M14.6602 24.375C20.3556 24.375 24.9727 19.7579 24.9727 14.0625C24.9727 8.36706 20.3556 3.75 14.6602 3.75V24.375Z" fill="#00A3FF"/>
-<path d="M3.41211 9.84375C5.22429 9.84375 6.69336 8.37468 6.69336 6.5625C6.69336 4.75032 5.22429 3.28125 3.41211 3.28125C1.59992 3.28125 0.130859 4.75032 0.130859 6.5625C0.130859 8.37468 1.59992 9.84375 3.41211 9.84375Z" fill="#44BBFF" stroke="#F7FCFF" stroke-width="0.9375"/>
-<path d="M14.6621 30.4688C16.4743 30.4688 17.9434 28.9997 17.9434 27.1875C17.9434 25.3753 16.4743 23.9062 14.6621 23.9062C12.8499 23.9062 11.3809 25.3753 11.3809 27.1875C11.3809 28.9997 12.8499 30.4688 14.6621 30.4688Z" fill="#44BBFF" stroke="#F7FCFF" stroke-width="0.9375"/>
-<path d="M26.8496 9.84375C28.6618 9.84375 30.1309 8.37468 30.1309 6.5625C30.1309 4.75032 28.6618 3.28125 26.8496 3.28125C25.0374 3.28125 23.5684 4.75032 23.5684 6.5625C23.5684 8.37468 25.0374 9.84375 26.8496 9.84375Z" fill="#44BBFF" stroke="#F7FCFF" stroke-width="0.9375"/>
-</g>
-<defs>
-<linearGradient id="paint0_linear_14299_11434" x1="14.6621" y1="0" x2="14.6621" y2="28.125" gradientUnits="userSpaceOnUse">
-<stop stop-color="#ADE0FF"/>
-<stop offset="1" stop-color="#ADE0FF" stop-opacity="0"/>
-</linearGradient>
-<clipPath id="clip0_14299_11434">
-<rect width="30" height="30" fill="white"/>
-</clipPath>
-</defs>
+<svg width="99" height="32" viewBox="0 0 99 32" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path fill-rule="evenodd" clip-rule="evenodd" d="M16 25.75C16 25.75 16 25.75 16 25.75C21.3848 25.75 25.75 21.3848 25.75 16C25.75 10.6152 21.3848 6.25 16 6.25C16 6.25 16 6.25 16 6.25V25.75Z" fill="#1D9BF0"/>
+<path fill-rule="evenodd" clip-rule="evenodd" d="M19.2664 27.6943C19.4175 28.1009 19.5 28.5408 19.5 29C19.5 29.1938 19.4853 29.3841 19.457 29.5699C25.5171 28.0308 30 22.5389 30 16C30 15.0837 29.912 14.1879 29.7439 13.3207C29.2229 13.5948 28.6296 13.75 28 13.75L27.9815 13.75C28.1196 14.4801 28.1917 15.2323 28.1917 16C28.1917 21.5357 24.4421 26.268 19.2664 27.6943ZM12.0241 29.4274C12.0082 29.2871 12 29.1445 12 29C12 28.4904 12.1017 28.0045 12.2858 27.5616C7.34302 25.9921 3.80833 21.3748 3.80833 16C3.80833 15.2299 3.8809 14.4753 4.01978 13.743C3.3848 13.7046 2.79247 13.5081 2.28159 13.1924C2.09694 14.0995 2 15.0384 2 16C2 22.3508 6.22874 27.714 12.0241 29.4274ZM16 3.86667C12.505 3.86667 9.37698 5.3215 7.16455 7.64016C6.77394 7.15834 6.26628 6.77529 5.68483 6.53429C8.24388 3.74708 11.9179 2 16 2C20.1206 2 23.8254 3.78022 26.3873 6.6135C25.8239 6.88227 25.3382 7.28749 24.9727 7.7864C22.7534 5.38284 19.5679 3.86667 16 3.86667Z" fill="#1D9BF0"/>
+<circle cx="28" cy="10" r="2.75" fill="#1D9BF0"/>
+<circle cx="4.25" cy="10" r="2.75" fill="#1D9BF0"/>
+<circle cx="15.75" cy="29" r="2.75" fill="#1D9BF0"/>
+<path d="M44.2988 9.9082V24H49.2695C53.4688 24 55.9395 21.3828 55.9395 16.9297C55.9395 12.4863 53.459 9.9082 49.2695 9.9082H44.2988ZM46.4863 11.793H49.0645C52.043 11.793 53.7031 13.6289 53.7031 16.9492C53.7031 20.2793 52.0527 22.1055 49.0645 22.1055H46.4863V11.793ZM62.0723 15.2402C63.5469 15.2402 64.543 16.3438 64.5918 17.916H59.4551C59.5625 16.3633 60.5977 15.2402 62.0723 15.2402ZM64.582 20.9824C64.2988 21.8809 63.4102 22.4863 62.209 22.4863C60.5195 22.4863 59.4453 21.3047 59.4453 19.5176V19.3906H66.7012V18.668C66.7012 15.5527 64.9238 13.541 62.0723 13.541C59.1719 13.541 57.3164 15.6895 57.3164 18.9121C57.3164 22.1543 59.1426 24.1953 62.1602 24.1953C64.5137 24.1953 66.291 22.8574 66.584 20.9824H64.582ZM70.7246 24V13.6191H70.8125L78.1172 24H80.0898V9.9082H77.9609V20.2988H77.8828L70.5781 9.9082H68.5957V24H70.7246ZM86.7402 15.2402C88.2148 15.2402 89.2109 16.3438 89.2598 17.916H84.123C84.2305 16.3633 85.2656 15.2402 86.7402 15.2402ZM89.25 20.9824C88.9668 21.8809 88.0781 22.4863 86.877 22.4863C85.1875 22.4863 84.1133 21.3047 84.1133 19.5176V19.3906H91.3691V18.668C91.3691 15.5527 89.5918 13.541 86.7402 13.541C83.8398 13.541 81.9844 15.6895 81.9844 18.9121C81.9844 22.1543 83.8105 24.1953 86.8281 24.1953C89.1816 24.1953 90.959 22.8574 91.252 20.9824H89.25ZM93.625 11.2949V13.7266H92.1309V15.3965H93.625V21.2949C93.625 23.2773 94.4355 24.0684 96.5156 24.0684C96.9844 24.0684 97.4531 24.0293 97.6875 23.9707V22.3008C97.5508 22.3301 97.209 22.3496 96.9941 22.3496C96.1348 22.3496 95.7441 21.9492 95.7441 21.0605V15.3965H97.6973V13.7266H95.7441V11.2949H93.625Z" fill="#313131"/>
 </svg>

Diferenças do arquivo suprimidas por serem muito extensas
+ 4 - 0
static/svg/img-custom-common-bg.svg


Diferenças do arquivo suprimidas por serem muito extensas
+ 4 - 0
static/svg/img-custom-lottary-bg.svg


+ 23 - 0
types/global.js

@@ -0,0 +1,23 @@
+/**
+ * 全局通用字段定义
+ */
+
+/**
+ * 玩法类型
+ * 普通任务:common=1;
+ * 抽奖:lottery=2
+ */
+export const PlayType = {
+  common: 1,
+  lottery: 2,
+};
+
+/**
+ * 奖品类型
+ * 货币:money=1;
+ * 自定义奖品:custom=2
+ */
+export const RewardType = {
+  money: 1,
+  custom: 2,
+};

+ 1 - 0
types/index.js

@@ -0,0 +1 @@
+export * from "@/types/global";

+ 30 - 1
utils/help.js

@@ -106,4 +106,33 @@ export function formatSecondsAsDaysOrTime(secs) {
 
 export const appVersionCode = 12;
 
-export const appType = 1;
+export const appType = 1;
+
+export function getBrowserType(){
+    let device =  '' // ios 安卓 chrome no-chrome
+    if(/android/i.test(navigator.userAgent)){
+        device = '安卓'
+	}else if(/(iPhone|iPad|iPod|iOS)/i.test(navigator.userAgent)){
+		 device = 'ios'
+	}else if(isBrowser() == 'chrome'){
+        device = 'chrome'
+    }else{
+        device = 'no-chrome'
+    }
+    return device
+}
+
+
+const api = {
+	prod: 'https://api.denetme.net',
+	pre: 'https://preapi.denetme.net',
+	test: 'https://testapi.denetme.net'
+}
+const page = {
+	prod: "https://h5.denetme.net",
+	pre: "https://preh5.denetme.net",
+	test: 'https://testh5.denetme.net'
+}
+
+export const jumpUrl = page[process.env.NUXT_ENV.MODE] + '/'
+export const baseURL = api[process.env.NUXT_ENV.MODE]

+ 46 - 1
yarn.lock

@@ -913,6 +913,13 @@
     "@babel/types" "^7.4.4"
     esutils "^2.0.2"
 
+"@babel/runtime@7.x":
+  version "7.18.6"
+  resolved "https://registry.npmmirror.com/@babel/runtime/-/runtime-7.18.6.tgz#6a1ef59f838debd670421f8c7f2cbb8da9751580"
+  integrity sha512-t9wi7/AW6XtKahAe20Yw0/mMljKq0B1r2fPdvaAdV/KPDZewFXdaaa6K7lxmZBZ8FBNpCiAT6iHPmd6QO9bKfQ==
+  dependencies:
+    regenerator-runtime "^0.13.4"
+
 "@babel/runtime@^7.14.0", "@babel/runtime@^7.8.4":
   version "7.17.8"
   resolved "https://registry.npmmirror.com/@babel/runtime/-/runtime-7.17.8.tgz#3e56e4aff81befa55ac3ac6a0967349fd1c5bca2"
@@ -1622,6 +1629,11 @@
   resolved "https://registry.npmmirror.com/@polka/url/-/url-1.0.0-next.21.tgz#5de5a2385a35309427f6011992b544514d559aa1"
   integrity sha512-a5Sab1C4/icpTZVzZc5Ghpz88yQtGOyNqYXcZgOssB2uuAr+wF/MvN6bgtW32q7HHrvBki+BsZ0OuNv6EV3K9g==
 
+"@popperjs/core@^2.9.2":
+  version "2.11.5"
+  resolved "https://registry.npmmirror.com/@popperjs/core/-/core-2.11.5.tgz#db5a11bf66bdab39569719555b0f76e138d7bd64"
+  integrity sha512-9X2obfABZuDVLCgPK9aX0a/x4jaOEweTTWE2+9sr0Qqqevj2Uv5XorvusThmc9XGYpS9yI+fhh8RTafBtGposw==
+
 "@sinonjs/commons@^1.7.0":
   version "1.8.3"
   resolved "https://registry.npmmirror.com/@sinonjs/commons/-/commons-1.8.3.tgz#3802ddd21a50a949b6721ddd72da36e67e7f1b2d"
@@ -1790,7 +1802,19 @@
   dependencies:
     "@types/yargs-parser" "*"
 
-"@vue/babel-helper-vue-jsx-merge-props@^1.2.1":
+"@vant/icons@^1.7.1":
+  version "1.8.0"
+  resolved "https://registry.npmmirror.com/@vant/icons/-/icons-1.8.0.tgz#36b13f2e628b533f6523a93a168cf02f07056674"
+  integrity sha512-sKfEUo2/CkQFuERxvkuF6mGQZDKu3IQdj5rV9Fm0weJXtchDSSQ+zt8qPCNUEhh9Y8shy5PzxbvAfOOkCwlCXg==
+
+"@vant/popperjs@^1.1.0":
+  version "1.2.1"
+  resolved "https://registry.npmmirror.com/@vant/popperjs/-/popperjs-1.2.1.tgz#1300c7c98573df577c21d3000712435edb8a877e"
+  integrity sha512-qzQlrPE4aOsBzfrktDVwzQy/QICCTKifmjrruhY58+Q2fobUYp/T9QINluIafzsD3VJwgP8+HFVLBsyDmy3VZQ==
+  dependencies:
+    "@popperjs/core" "^2.9.2"
+
+"@vue/babel-helper-vue-jsx-merge-props@^1.0.0", "@vue/babel-helper-vue-jsx-merge-props@^1.2.1":
   version "1.2.1"
   resolved "https://registry.npmmirror.com/@vue/babel-helper-vue-jsx-merge-props/-/babel-helper-vue-jsx-merge-props-1.2.1.tgz#31624a7a505fb14da1d58023725a4c5f270e6a81"
   integrity sha512-QOi5OW45e2R20VygMSNhyQHvpdUwQZqGPc748JLGCYEy+yp8fNFNdbNIGAgZmi9e+2JHPd6i6idRuqivyicIkA==
@@ -3741,6 +3765,11 @@ culvert@^0.1.2:
   resolved "https://registry.yarnpkg.com/culvert/-/culvert-0.1.2.tgz#9502f5f0154a2d5a22a023e79f71cc936fa6ef6f"
   integrity sha1-lQL18BVKLVoioCPnn3HMk2+m728=
 
+current-device@^0.10.2:
+  version "0.10.2"
+  resolved "https://registry.npmmirror.com/current-device/-/current-device-0.10.2.tgz#1e40176bee7da655383ab7245b853fae7d2dfc8e"
+  integrity sha512-FN223n2Cp1fRI/gyjJEAdagHhJ/2Z2STz3tUg1t4F259BhmVRCChkmxcgFtjYJsWuIacQEs7bqJpnAczIXIkWw==
+
 cyclist@^1.0.1:
   version "1.0.1"
   resolved "https://registry.npmmirror.com/cyclist/-/cyclist-1.0.1.tgz#596e9698fd0c80e12038c2b82d6eb1b35b6224d9"
@@ -10040,6 +10069,17 @@ v8-to-istanbul@^8.1.0:
     convert-source-map "^1.6.0"
     source-map "^0.7.3"
 
+vant@^2.12.47:
+  version "2.12.48"
+  resolved "https://registry.npmmirror.com/vant/-/vant-2.12.48.tgz#856cfb36741f331fc9087d97f00e88f7d62c412c"
+  integrity sha512-cTv5V8pYboLrryMAThTu9Nrjroc6z246ktvvRbQ6v+G/yUH2tJia4S/L8RaTCH6btiuoeKZbtFAjkeQUPYeOtQ==
+  dependencies:
+    "@babel/runtime" "7.x"
+    "@vant/icons" "^1.7.1"
+    "@vant/popperjs" "^1.1.0"
+    "@vue/babel-helper-vue-jsx-merge-props" "^1.0.0"
+    vue-lazyload "1.2.3"
+
 vary@^1.1.2, vary@~1.1.2:
   version "1.1.2"
   resolved "https://registry.npmmirror.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc"
@@ -10105,6 +10145,11 @@ vue-jest@^3.0.4:
     tsconfig "^7.0.0"
     vue-template-es2015-compiler "^1.6.0"
 
+vue-lazyload@1.2.3:
+  version "1.2.3"
+  resolved "https://registry.npmmirror.com/vue-lazyload/-/vue-lazyload-1.2.3.tgz#901f9ec15c7e6ca78781a2bae4a343686bdedb2c"
+  integrity sha512-DC0ZwxanbRhx79tlA3zY5OYJkH8FYp3WBAnAJbrcuoS8eye1P73rcgAZhyxFSPUluJUTelMB+i/+VkNU/qVm7g==
+
 vue-loader@^15.9.7:
   version "15.9.8"
   resolved "https://registry.npmmirror.com/vue-loader/-/vue-loader-15.9.8.tgz#4b0f602afaf66a996be1e534fb9609dc4ab10e61"

Alguns arquivos não foram mostrados porque muitos arquivos mudaram nesse diff