瀏覽代碼

feat: 超级订阅购买和升级页面

cuiyalong 3 年之前
父節點
當前提交
18b3a096ff

+ 36 - 0
src/api/modules/coupon.js

@@ -0,0 +1,36 @@
+import request from '@/api'
+import qs from 'qs'
+
+// 1. 查询当前价格产品可以使用的优惠券
+// 2. 自动领券功能JYR: 1
+export function getCouponList (data) {
+  data = qs.stringify(data)
+  return request({
+    baseURL: '/jyCoupon',
+    url: '/showCoupons',
+    method: 'POST',
+    data
+  })
+}
+
+// 优惠券最优选择接口
+export function optimalCoupon (data) {
+  data = qs.stringify(data)
+  return request({
+    baseURL: '/jyCoupon',
+    url: '/optimalCoupon',
+    method: 'POST',
+    data
+  })
+}
+
+// 产品下的赠品
+export function getGiftList (data) {
+  data = qs.stringify(data)
+  return request({
+    baseURL: '/jyCoupon',
+    url: '/giveInfo',
+    method: 'POST',
+    data
+  })
+}

+ 2 - 0
src/api/modules/index.js

@@ -7,3 +7,5 @@ export * from './analysis'
 export * from './subscribe'
 export * from './potential'
 export * from './project'
+export * from './coupon'
+export * from './svip'

+ 53 - 0
src/api/modules/svip.js

@@ -0,0 +1,53 @@
+import request from '@/api'
+import qs from 'qs'
+
+// 获取用户超级订阅购买信息
+export function getSVIPBuyInfo () {
+  return request({
+    baseURL: '/subscribepay',
+    url: '/vipsubscribe/getSubBuyMsg',
+    method: 'POST'
+  })
+}
+
+// 获取超级订阅价格表
+export function getGoodsPrice () {
+  return request({
+    baseURL: '/subscribepay',
+    url: '/vipsubscribe/getPrice',
+    method: 'POST'
+  })
+}
+
+// 获取超级订阅价格
+export function getSelectPrice (data) {
+  data = qs.stringify(data)
+  return request({
+    baseURL: '/subscribepay',
+    url: '/vipsubscribe/getSelectPrice',
+    method: 'POST',
+    data
+  })
+}
+
+// 超级订阅购买
+export function createSVIPOrder (data) {
+  data = qs.stringify(data)
+  return request({
+    baseURL: '/subscribepay',
+    url: '/vipsubscribe/createOrder',
+    method: 'POST',
+    data
+  })
+}
+
+// 超级订阅升级
+export function svipUpgrade (data) {
+  data = qs.stringify(data)
+  return request({
+    baseURL: '/subscribepay',
+    url: '/vipsubscribe/upgrade',
+    method: 'POST',
+    data
+  })
+}

+ 8 - 0
src/api/modules/user.js

@@ -8,6 +8,14 @@ export function getUserPower () {
   })
 }
 
+export function getUserAccountInfo () {
+  return request({
+    baseURL: '/jypay',
+    url: '/user/getAccountInfo',
+    method: 'get'
+  })
+}
+
 // 获取entSearch权限信息
 export function getEntSearchPower () {
   return request({

二進制
src/assets/images/icon/guan.png


二進制
src/assets/images/icon/right.png


二進制
src/assets/images/spec-active.png


二進制
src/assets/images/sub-compare.png


二進制
src/assets/images/vip/mengban.png


+ 82 - 0
src/components/common/SpecCard.vue

@@ -0,0 +1,82 @@
+<template>
+  <div class="spec-card" :class="{ active: active }" @click="clickCard">
+    <span class="float-tip" :class="floatTipClass" v-if="showFloatTip">
+      <slot name="float-tip">
+        <span v-if="defaultFloatTipText">{{ defaultFloatTipText }}</span>
+      </slot>
+    </span>
+    <slot name="default"></slot>
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'spec-card-active',
+  props: {
+    defaultFloatTipText: {
+      type: String,
+      default: ''
+    },
+    floatTipClass: {
+      type: String,
+      default: ''
+    },
+    showFloatTip: {
+      type: Boolean,
+      default: false
+    },
+    active: {
+      type: Boolean,
+      default: false
+    }
+  },
+  methods: {
+    clickCard () {
+      this.$emit('onClick')
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.spec-card {
+  position: relative;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  justify-content: space-between;
+  padding: 16px;
+  background-color: #f5f6f7;
+  border-radius: 8px;
+  border: 2px solid transparent;
+  cursor: pointer;
+  &.active {
+    border-color: #2abed1;
+    background-color: #fff;
+    &::after {
+      content: '';
+      position: absolute;
+      right: -2px;
+      bottom: -2px;
+      width: 26px;
+      height: 26px;
+      background-image: url(~@/assets/images/spec-active.png);
+      background-repeat: no-repeat;
+      background-size: contain;
+    }
+  }
+
+  .float-tip {
+    position: absolute;
+    left: -2px;
+    top: -2px;
+    padding: 0 8px;
+    color: #fff;
+    font-size: 12px;
+    line-height: 20px;
+    border-radius: 8px 2px 10px 2px;
+    background-color: #2abed1;
+    z-index: 9;
+  }
+}
+</style>

+ 193 - 0
src/components/coupon/BuySubmit.vue

@@ -0,0 +1,193 @@
+<template>
+  <div class="buy-submit">
+    <div class="price-preview">
+      <slot name="preview">
+        <div class="preview-item total">
+          <div class="p-label">商品总价:</div>
+          <div class="p-value">&yen; {{ useFormatPrice ? formatPrice(productionTotal, -1, true) : productionTotal }}</div>
+        </div>
+        <div class="preview-item discount" v-if="productionDiscount">
+          <div class="p-label">优惠金额:</div>
+          <div class="p-value">-&yen; {{ useFormatPrice ? formatPrice(productionDiscount, -1, true) : productionDiscount }}</div>
+        </div>
+        <div class="preview-item pay">
+          <div class="p-label">实付金额:</div>
+          <div class="p-value">&yen; {{ useFormatPrice ? formatPrice(productionPay, -1, true) : productionPay }}</div>
+        </div>
+      </slot>
+    </div>
+    <div class="price-agreement">
+      <el-checkbox v-model="agreement">
+        <span>已阅读并同意</span>
+        <div class="links">
+          <el-link
+            type="primary"
+            v-for="(link, index) in agreementLinks"
+            :key="index"
+            target="_black"
+            :href="link.url">{{ link.label }}</el-link>
+        </div>
+      </el-checkbox>
+    </div>
+    <div class="price-submit-container">
+      <button class="price-submit" :disabled="confirmButtonDisabled" @click="buySubmit">确定支付</button>
+    </div>
+  </div>
+</template>
+
+<script>
+import { Checkbox, Link } from 'element-ui'
+import { formatPrice } from '@/utils/'
+
+export default {
+  name: 'buy-submit',
+  components: {
+    [Checkbox.name]: Checkbox,
+    [Link.name]: Link
+  },
+  props: {
+    productionTotal: {
+      type: [String, Number],
+      default: 0
+    },
+    productionDiscount: {
+      type: [String, Number],
+      default: 0
+    },
+    productionPay: {
+      type: [String, Number],
+      default: 0
+    },
+    useFormatPrice: {
+      type: Boolean,
+      default: true
+    },
+    pass: {
+      type: Boolean,
+      default: true
+    }
+  },
+  computed: {
+    confirmButtonDisabled () {
+      const state = this.pass && this.agreement
+      return !state
+    }
+  },
+  data () {
+    return {
+      agreementLinks: [
+        {
+          label: '《剑鱼标讯线上购买与服务条款》',
+          url: '/front/staticPage/serviceterms.html'
+        }
+      ],
+      agreement: false
+    }
+  },
+  methods: {
+    formatPrice,
+    buySubmit () {
+      this.$emit('submit')
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.buy-submit {
+  padding: 12px 0;
+  .price-preview {
+    display: flex;
+    flex-direction: column;
+    align-items: flex-end;
+    padding: 22px;
+    background-color: #F5F5FB;
+    .preview-item {
+      display: flex;
+      align-items: center;
+      justify-content: space-between;
+      color: #1D1D1D;
+      min-width: 400px;
+      .p- {
+        &label {
+          font-size: 14px;
+          line-height: 16px;
+        }
+        &value {
+          font-size: 18px;
+          line-height: 28px;
+        }
+      }
+      &:not(:last-of-type) {
+        margin-bottom: 20px;
+      }
+      &.pay .p-value {
+        font-weight: bold;
+        font-size: 36px;
+        color: #FF3A20;
+        line-height: 36px;
+      }
+    }
+  }
+  .price-agreement {
+    margin: 26px 0;
+    display: flex;
+    align-items: center;
+    justify-content: flex-end;
+    ::v-deep {
+      .el-checkbox {
+        display: flex;
+        flex-wrap: nowrap;
+        align-items: center;
+      }
+      .el-checkbox__label {
+        display: flex;
+        max-width: 500px;
+        flex-wrap: wrap;
+      }
+    }
+  }
+  .price-submit-container {
+    display: flex;
+    align-items: center;
+    justify-content: flex-end;
+    .price-submit {
+      display: inline-block;
+      width: 180px;
+      height: 46px;
+      line-height: 1;
+      text-align: center;
+      font-size: 16px;
+      color: #fff;
+      border-radius: 6px;
+      background-color: #2CB7CA;
+      cursor: pointer;
+      &[disabled] {
+        opacity: 0.5;
+      }
+    }
+  }
+}
+
+::v-deep {
+  .el-link {
+    &:hover {
+      text-decoration: none;
+    }
+    &--primary {
+      color: $color-text--highlight;
+    }
+  }
+
+  .el-checkbox__inner:hover {
+    border-color: $color-text--highlight;
+  }
+  .el-checkbox__input.is-checked .el-checkbox__inner {
+    background-color: $color-text--highlight;
+  }
+  .el-checkbox__label,
+  .el-checkbox__input.is-checked+.el-checkbox__label {
+    color: #888;
+  }
+}
+</style>

+ 68 - 0
src/components/coupon/CheckPhone.vue

@@ -0,0 +1,68 @@
+<template>
+  <el-form class="check-phone">
+    <el-form-item :error="error">
+      <el-input
+        :value="value"
+        maxlength="13"
+        size="small"
+        placeholder="请输入手机号码"
+        @input="onInput"
+      />
+    </el-form-item>
+  </el-form>
+</template>
+
+<script>
+import { Form, FormItem, Input } from 'element-ui'
+export default {
+  name: 'check-phone',
+  components: {
+    [Form.name]: Form,
+    [FormItem.name]: FormItem,
+    [Input.name]: Input
+  },
+  props: {
+    value: String
+  },
+  watch: {
+    value (newVal) {
+      this.regPhone(newVal)
+    }
+  },
+  data () {
+    return {
+      error: ''
+    }
+  },
+  methods: {
+    onInput (val) {
+      this.$emit('input', val)
+    },
+    regPhone (val) {
+      if (val) {
+        const reg = /^[1][3-9][0-9]{9}$/
+        if (reg.test(val)) {
+          this.error = ''
+        } else {
+          this.error = '手机号码输入错误'
+        }
+      } else {
+        this.error = ''
+      }
+      this.$emit('update:pass', !this.error)
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.check-phone {
+  display: flex;
+  align-items: center;
+  ::v-deep {
+    .el-form-item {
+      min-width: 590px;
+    }
+  }
+}
+</style>

+ 264 - 0
src/components/coupon/CouponCardList.vue

@@ -0,0 +1,264 @@
+<template>
+  <div class="spec-list">
+    <SpecCard
+      v-for="coupon in couponList"
+      :key="coupon.id"
+      :class="coupon.className"
+      :showFloatTip="true"
+      :defaultFloatTipText="coupon.lotteryAttribute"
+      :active="coupon[activeType] === active"
+      @onClick="clickItem(coupon)">
+      <div class="spec-content flex-r-c center">
+        <div class="s-c-info">
+          <span class="info-denomination" v-if="coupon.lotteryAttribute.indexOf('满减') != -1">
+            <span class="s-c-yen">&yen;</span>
+            <span class="s-c-num" style="margin-left: 4px">{{ coupon.reduce }}</span>
+          </span>
+          <span class="info-denomination" v-else-if="coupon.lotteryAttribute.indexOf('折扣') != -1">
+            <span class="s-c-num">{{ coupon.disCount }}</span>
+            <span class="s-c-yen">折</span>
+          </span>
+          <span class="info-condition">满{{ coupon.full }}可用</span>
+        </div>
+      </div>
+      <div class="spec-footer">
+        <span class="spec-time">
+          <span class="spec-start">{{ dateFormatter(coupon.lotteryBeginDate.replace(/-/g, '/'), 'yyyy.MM.dd') }}</span>
+          <span class="spec-split">-</span>
+          <span class="spec-end">{{ dateFormatter(coupon.lotteryEndDate.replace(/-/g, '/'), 'yyyy.MM.dd') }}</span>
+        </span>
+        <span class="spec-expire" v-if="coupon.expireTime">{{ coupon.expireTime }}</span>
+      </div>
+    </SpecCard>
+  </div>
+</template>
+
+<script>
+import SpecCard from '@/components/common/SpecCard.vue'
+import { dateFormatter } from '@/utils/'
+import {
+  getCouponList,
+  optimalCoupon
+} from '@/api/modules/'
+export default {
+  name: 'coupon-list',
+  components: {
+    SpecCard
+  },
+  props: {
+    productionId: [String, Number],
+    price: {
+      type: Number,
+      default: 0
+    },
+    activeType: {
+      type: String,
+      default: 'lotteryId'
+    }
+  },
+  data () {
+    return {
+      active: '',
+      loading: false,
+      couponList: []
+    }
+  },
+  computed: {
+    activeItem () {
+      return this.getActiveItem()
+    }
+  },
+  watch: {
+    // active更新顺序:子组件触发activeChange,更新父组件v-model内容。父组件内容改变在触发子组件内容修改
+    active (newVal, oldVal) {
+      this.$emit('change', this.activeItem)
+    },
+    productionId (newVal, oldVal) {
+      this.getCouponList()
+    }
+  },
+  methods: {
+    dateFormatter,
+    // 获取优惠券
+    async getCouponList () {
+      var info = {
+        pId: this.productionId,
+        price: this.price,
+        JYR: 1
+      }
+      if (!info.pId || !info.price) {
+        this.loading = false
+        return this.couponListLoaded(0)
+      }
+      const { data, error_code: code } = await getCouponList(info)
+      this.loading = false
+      if (code === 1) {
+        if (Array.isArray(data)) {
+          this.couponList = this.resortList(data)
+        }
+      }
+      this.couponListLoaded(this.couponList.length)
+    },
+    // 优惠券最优
+    async optCoupon () {
+      var info = {
+        pId: this.productionId,
+        price: this.price,
+        priceBool: true
+      }
+      if (!info.pId || !info.price) return
+      const { data, error_code: code } = await optimalCoupon(info)
+      console.log(data, code)
+    },
+    resortList (list) {
+      if (!Array.isArray(list)) return []
+      return list.map(c => {
+        const expireTime = this.getExpireTime(c)
+        return {
+          ...c,
+          expireTime,
+          className: this.getClassName(c)
+        }
+      })
+    },
+    getClassName (item) {
+      var type = item.lotteryAttribute
+      if (type.includes('折扣')) {
+        return 'orange'
+      } else {
+        return 'blue'
+      }
+    },
+    clickItem (item) {
+      this.active = item[this.activeType]
+    },
+    getActiveItem () {
+      return this.couponList.find(c => c[this.activeType] === this.active)
+    },
+    getExpireTime ({ lotteryEndDate: end }) {
+      const endStamp = +new Date(end.replace(/-/g, '/'))
+      const nowStamp = Date.now()
+      const diffStamp = endStamp - nowStamp
+      const diffDay = parseInt(diffStamp / (24 * 60 * 60 * 1000)) + 1
+      if (diffDay <= 10 && diffDay > 0) {
+        return `${diffDay}天后到期`
+      } else {
+        return ''
+      }
+    },
+    couponListLoaded (length) {
+      this.$emit('loaded', { data: length })
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.spec-list {
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  ::v-deep {
+    .spec-card {
+      padding: 0;
+      width: 240px;
+      height: 108px;
+    }
+    .spec-card:not(:last-of-type) {
+      margin-right: 16px;
+    }
+  }
+}
+
+.spec-c {
+  &-label {
+    color: #686868;
+    font-size: 14px;
+    line-height: 22px;
+  }
+  &-price {
+    color: #161826;
+    &-text {
+      font-size: 32px;
+      font-weight: bold;
+      line-height: 40px;
+    }
+  }
+  &-desc {
+    .font-red {
+      color: #FF3A20;
+    }
+  }
+}
+
+.spec-content {
+  width: 100%;
+  height: 72px;
+  color: #fff;
+  border-top-left-radius: 6px;
+  border-top-right-radius: 6px;
+  .s-c {
+    &-info {
+      display: flex;
+      align-items: flex-end;
+    }
+    &-yen {
+      font-size: 16px;
+      line-height: 24px;
+    }
+    &-num {
+      font-size: 36px;
+      line-height: 48px;
+      font-weight: bold;
+    }
+  }
+  .info-condition {
+    margin-left: 8px;
+    font-size: 12px;
+    line-height: 28px;
+  }
+}
+
+.spec-footer {
+  display: flex;
+  align-items: center;
+  width: 100%;
+  padding: 0 18px;
+  flex: 1;
+  font-size: 12px;
+  line-height: 20px;
+  background-color: #fff;
+  border-bottom-left-radius: 6px;
+  border-bottom-right-radius: 6px;
+  .spec-time {
+    color: #686868;
+  }
+  .spec-expire {
+    color: #FF3A20;
+  }
+}
+
+.blue {
+  ::v-deep {
+    .float-tip {
+      color: #0DA6BB;
+      background-color: rgba(255, 255, 255, 0.6);
+    }
+  }
+  .spec-content {
+    background: linear-gradient(315deg, #27C0E2 0%, #5ED4E3 99%);
+  }
+}
+
+.orange {
+  ::v-deep {
+    .float-tip {
+      color: #FF9F3F;
+      background-color: rgba(255, 255, 255, 0.6);
+    }
+  }
+  .spec-content {
+    background: linear-gradient(313deg, #FF9F3F 0%, #FFC046 100%);
+  }
+}
+</style>

+ 116 - 0
src/components/coupon/SpecList.vue

@@ -0,0 +1,116 @@
+<template>
+  <div class="spec-list">
+    <SpecCard
+      v-for="spec in list"
+      :key="spec.id"
+      :showFloatTip="!!spec.tipText && spec[activeType] === active"
+      floatTipClass="spec-c-tip"
+      :defaultFloatTipText="spec.tipText"
+      :active="spec[activeType] === active"
+      @onClick="clickSpec(spec)">
+      <div class="spec-c-label">{{ spec.label }}</div>
+      <div class="spec-c-price">
+        <span>&yen;</span>
+        <span class="spec-c-price-text">{{ spec.price }}</span>
+      </div>
+      <div class="spec-c-desc" v-html="spec.desc"></div>
+    </SpecCard>
+  </div>
+</template>
+
+<script>
+import SpecCard from '@/components/common/SpecCard.vue'
+export default {
+  name: 'spec-list',
+  components: {
+    SpecCard
+  },
+  props: {
+    active: [String, Number, Boolean],
+    activeType: {
+      type: String,
+      default: 'id'
+    },
+    list: {
+      type: Array,
+      default () {
+        return []
+      }
+    }
+  },
+  model: {
+    prop: 'active',
+    event: 'activeChange'
+  },
+  data () {
+    return {}
+  },
+  computed: {
+    activeItem () {
+      return this.getActiveItem()
+    }
+  },
+  watch: {
+    // active更新顺序:子组件触发activeChange,更新父组件v-model内容。父组件内容改变在触发子组件内容修改
+    active: function (newVal, oldVal) {
+      this.$emit('change', this.activeItem)
+    }
+  },
+  created () {
+    this.getActiveItem()
+  },
+  methods: {
+    clickSpec (spec) {
+      // v-model专用自定义事件
+      this.$emit('activeChange', spec.id)
+      // activeItem的值不能在此处获取,因为active的更新顺序问题
+    },
+    getActiveItem () {
+      return this.list.find(spec => spec[this.activeType] === this.active)
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.spec-list {
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  ::v-deep {
+    .spec-card {
+      width: 240px;
+      height: 120px;
+    }
+    .spec-card:not(:last-of-type) {
+      margin-right: 16px;
+    }
+    .spec-c-tip {
+      top: -10px;
+      border-radius: 2px 10px 2px 2px;
+      background: linear-gradient(90deg, #FF3A20 0%, #FF621F 100%);
+    }
+  }
+}
+
+.spec-c {
+  &-label {
+    color: #686868;
+    font-size: 14px;
+    line-height: 22px;
+  }
+  &-price {
+    color: #161826;
+    &-text {
+      font-size: 32px;
+      font-weight: bold;
+      line-height: 40px;
+    }
+  }
+  &-desc {
+    .font-red {
+      color: #FF3A20;
+    }
+  }
+}
+</style>

+ 2 - 0
src/router/router.js

@@ -1,6 +1,7 @@
 import Vue from 'vue'
 import Router from 'vue-router'
 import routers from './routers'
+import vipRouters from './svip-routers'
 
 Vue.use(Router)
 
@@ -9,6 +10,7 @@ const router = new Router({
   base: process.env.VUE_APP_BASE_URL,
   routes: [
     ...routers,
+    ...vipRouters,
     {
       path: '*',
       name: '404',

+ 9 - 0
src/router/svip-routers.js

@@ -0,0 +1,9 @@
+// 超级订阅相关路由
+export default [
+  // 购买
+  {
+    path: '/free/svip/buy',
+    name: 'svip_buy',
+    component: () => import('@/views/vipsubscribe/Buy.vue')
+  }
+]

+ 522 - 0
src/views/vipsubscribe/Buy.vue

@@ -0,0 +1,522 @@
+<template>
+  <Layout class="vip-subscribe-buy" contentWithState="full" :needAd="false">
+    <div class="vip-subscribe-title">开通超级订阅</div>
+    <div class="vip-subscribe-content">
+      <div class="vip-sub-list">
+        <SelectorCard
+          class="vip-sub-list-item"
+          :cardType="conf.selectorType">
+          <div slot="header" class="vip-sub-item-title">购买区域</div>
+          <div class="vip-sub-item-content area-container" @click="showAreaDialog">
+            <div class="pre-tag" v-if="!noSelect">已选:{{ selectedCountInfo.text }}</div>
+            <div class="area-container-placeholder" v-if="noSelect">请选择订阅区域</div>
+            <div class="area-container-content" v-else>{{ selectedCountInfo.detail }}</div>
+          </div>
+          <div class="tip-content" v-if="upgradeTipShow">
+            请增加购买区域进行升级,当前选择省份数量未高于原套餐数,无法升级
+          </div>
+        </SelectorCard>
+        <SelectorCard
+          class="vip-sub-list-item"
+          v-if="moduleShow.specList"
+          :cardType="conf.selectorType">
+          <div slot="header" class="vip-sub-item-title">选择购买周期</div>
+          <div class="vip-sub-item-content">
+            <SpecList :list="specList" v-model="specIdActive" @change="specChange" />
+          </div>
+        </SelectorCard>
+        <SelectorCard
+          class="vip-sub-list-item"
+          v-show="moduleShow.coupon"
+          :cardType="conf.selectorType">
+          <div slot="header" class="vip-sub-item-title">选择优惠券</div>
+          <div class="vip-sub-item-content">
+            <CouponCardList
+              :productionId="specActiveItem.productionId"
+              :price="specActiveItem.price * 100"
+              @loaded="couponCardLoaded"
+              @change="couponCardChange" />
+          </div>
+        </SelectorCard>
+        <SelectorCard
+          class="vip-sub-list-item"
+          v-show="moduleShow.gift"
+          :cardType="conf.selectorType">
+          <div slot="header" class="vip-sub-item-title">赠品</div>
+          <div class="vip-sub-item-content"></div>
+        </SelectorCard>
+        <SelectorCard
+          class="vip-sub-list-item"
+          :cardType="conf.selectorType">
+          <div slot="header" class="vip-sub-item-title">手机号码</div>
+          <div class="vip-sub-item-content">
+            <CheckPhone v-model="userInfo.phone" :pass.sync="phoneRegPass" />
+          </div>
+        </SelectorCard>
+      </div>
+      <BuySubmit
+        :pass="allPass"
+        :productionTotal="computedPrice.total / 100"
+        :productionDiscount="computedPrice.discount / 100"
+        :productionPay="computedPrice.pay / 100"
+        @submit="submit"
+      ></BuySubmit>
+    </div>
+    <!-- 设置常用功能dialog -->
+    <el-dialog
+      custom-class="custom-dialog"
+      top="0"
+      :visible.sync="dialog.area"
+      :close-on-click-modal="false"
+      :show-close="false"
+      center>
+      <AreaSelector
+        ref="areaSelector"
+        :showSearchInput="false"
+        :onlyProvince="true"
+        :showSelectResult="true"
+        @onConfirm="onAreaConfirm"
+        @onCancel="onAreaCancel">
+        <div slot="header">选择订阅区域</div>
+      </AreaSelector>
+    </el-dialog>
+    <div class="vip-subscribe-desc">
+      <Contrast></Contrast>
+    </div>
+  </Layout>
+</template>
+
+<script>
+import Layout from '@/components/common/ContentLayout.vue'
+import SelectorCard from '@/components/selector/SelectorCard.vue'
+import AreaSelector from '@/components/selector/AreaSelector.vue'
+import SpecList from '@/components/coupon/SpecList.vue'
+import CouponCardList from '@/components/coupon/CouponCardList.vue'
+import CheckPhone from '@/components/coupon/CheckPhone.vue'
+import BuySubmit from '@/components/coupon/BuySubmit.vue'
+import Contrast from '@/views/vipsubscribe/components/Contrast.vue'
+import { Dialog } from 'element-ui'
+
+import {
+  getGoodsPrice,
+  createSVIPOrder,
+  getSelectPrice,
+  getSVIPBuyInfo,
+  svipUpgrade,
+  getUserAccountInfo
+} from '@/api/modules/'
+
+export default {
+  name: 'vip-subscribe-buy',
+  components: {
+    Layout,
+    SelectorCard,
+    AreaSelector,
+    SpecList,
+    CouponCardList,
+    CheckPhone,
+    BuySubmit,
+    Contrast,
+    [Dialog.name]: Dialog
+  },
+  data () {
+    return {
+      buyType: 'buy', // buy/upgrade
+      conf: {
+        selectorType: 'line'
+      },
+      dialog: {
+        area: false
+      },
+      moduleShow: {
+        specList: true,
+        coupon: false,
+        gift: false
+      },
+      phoneRegPass: false,
+      userInfo: {
+        phone: ''
+      },
+      selectInfo: {
+        area: ''
+      },
+      buyInfo: {
+        buyset: {}
+      },
+      priceRules: {},
+      couponActiveItem: {},
+      specIdActive: 0,
+      specActiveItem: {},
+      specList: [
+        {
+          id: 1,
+          cycleType: 1, // 月
+          label: '1月',
+          value: '1个月',
+          price: 0,
+          desc: '每天仅需0元',
+          perDayPrice: 0,
+          productionId: 1012, // 产品id,后台配置
+          tipText: ''
+        },
+        {
+          id: 2,
+          cycleType: 2, // 季
+          label: '1季',
+          value: '1季',
+          price: 0,
+          desc: '每天仅需0元',
+          perDayPrice: 0,
+          productionId: 1013,
+          tipText: ''
+        },
+        {
+          id: 3,
+          cycleType: 3, // 年
+          label: '1年',
+          value: '1年',
+          price: 0,
+          desc: '每天仅需0元',
+          perDayPrice: 0,
+          productionId: 1014,
+          tipText: ''
+        }
+      ],
+      computedPrice: {
+        total: 0,
+        discount: 0,
+        pay: 0
+      }
+    }
+  },
+  computed: {
+    upgradeTipShow () {
+      if (this.buyType === 'buy') {
+        return false
+      } else {
+        return !this.canUpgrade
+      }
+    },
+    canUpgrade () {
+      const buyset = this.buyInfo.buyset
+      if (this.buyType === 'buy') {
+        return false
+      } else {
+        if (buyset.areacount === -1) {
+          return false
+        } else {
+          const selectCount = this.selectedCount
+          if (selectCount === -1) {
+            return true
+          } else {
+            return selectCount > buyset.areacount
+          }
+        }
+      }
+    },
+    buyTypeText () {
+      const map = {
+        buy: '购买',
+        upgrade: '升级'
+      }
+      return map[this.buyType]
+    },
+    noSelect () {
+      return !this.selectInfo.area
+    },
+    selectedCountInfo () {
+      const area = this.selectInfo.area
+      const count = Object.keys(area).length
+      return {
+        text: count === 0 ? '全国' : `${count}个省`,
+        detail: count === 0 ? '全国' : Object.keys(area).join('、')
+      }
+    },
+    selectedCount () {
+      const area = this.selectInfo.area
+      const length = Object.keys(area).length
+      return length === 0 ? -1 : length
+    },
+    allPass () {
+      const basicReg = this.phoneRegPass && !this.noSelect
+      if (this.buyType === 'buy') {
+        return basicReg
+      } else if (this.buyType === 'upgrade') {
+        return basicReg && this.canUpgrade
+      } else {
+        return false
+      }
+    }
+  },
+  created () {
+    this.getType()
+    this.getGoodsPrice()
+    this.getUserAccountInfo()
+  },
+  methods: {
+    getType () {
+      var type = this.$route.query.type
+      var types = ['buy', 'upgrade']
+      if (types.includes(type)) {
+        this.buyType = type || types[0]
+      } else {
+        this.buyType = types[0]
+      }
+      if (this.buyType === 'upgrade') {
+        this.moduleShow.specList = false
+        this.getUserBuyInfo()
+      }
+    },
+    init () {
+      this.specIdActive = this.specList[2].id
+      this.specChange(this.specList[2])
+      this.calcSpecPrice(1)
+    },
+    async getGoodsPrice () {
+      const priceInfo = await getGoodsPrice()
+      const newPriceInfo = priceInfo.new
+      for (const key in newPriceInfo) {
+        this.$set(this.priceRules, key, newPriceInfo[key])
+      }
+      this.init()
+    },
+    async getUserAccountInfo () {
+      const { data, error_code: code } = await getUserAccountInfo()
+      if (code === 0) {
+        Object.assign(this.userInfo, data)
+      }
+    },
+    async getUserBuyInfo () {
+      const { data, success } = await getSVIPBuyInfo()
+      if (success && data) {
+        Object.assign(this.buyInfo, data)
+        this.selectInfo.area = this.buyInfo.area
+      }
+    },
+    onAreaConfirm (area) {
+      this.dialog.area = false
+      this.selectInfo.area = area
+      this.calcSpecPrice(this.selectedCount)
+      this.updatePrice()
+    },
+    onAreaCancel () {
+      this.dialog.area = false
+    },
+    specChange (spec) {
+      this.specActiveItem = spec
+      this.updatePrice()
+    },
+    couponCardLoaded ({ data }) {
+      this.moduleShow.coupon = !!data
+    },
+    couponCardChange (coupon) {
+      this.couponActiveItem = coupon
+      this.updatePrice()
+    },
+    showAreaDialog () {
+      this.dialog.area = true
+      this.$nextTick(() => {
+        this.$refs.areaSelector.setCitySelected(this.selectInfo.area)
+      })
+    },
+    commonGetPrice (buyAreaCount, cycleType) {
+      const info = this.priceRules
+      const isGreaterThanMaxArea = buyAreaCount === -1 // 是否购买全国
+
+      const priceInfo = {
+        price: 0,
+        perDayPrice: 0
+      }
+
+      switch (cycleType) {
+        // 1个月
+        case 1: {
+          const monthPriceFen = isGreaterThanMaxArea ? info.month.allProvince_allBuyerClass : info.month.oneProvince_allBuyerClass * buyAreaCount
+          priceInfo.price = monthPriceFen / 100
+          priceInfo.perDayPrice = buyAreaCount === 0 ? 0 : (priceInfo.price / 30).toFixed(2)
+          break
+        }
+        // 1个季度
+        case 2: {
+          const quarterPriceFen = isGreaterThanMaxArea ? info.quarter.allProvince_allBuyerClass : info.quarter.oneProvince_allBuyerClass * buyAreaCount
+          priceInfo.price = quarterPriceFen / 100
+          priceInfo.perDayPrice = buyAreaCount === 0 ? 0 : (priceInfo.price / (30 * 3)).toFixed(2)
+          break
+        }
+        // 1年
+        case 3: {
+          const yearPriceFen = isGreaterThanMaxArea ? info.year.allProvince_allBuyerClass : info.year.oneProvince_allBuyerClass * buyAreaCount
+          priceInfo.price = yearPriceFen / 100
+          priceInfo.perDayPrice = buyAreaCount === 0 ? 0 : (priceInfo.price / 365).toFixed(2)
+          break
+        }
+        default: {
+          return priceInfo
+        }
+      }
+
+      return priceInfo
+    },
+    // 计算卡片价格
+    calcSpecPrice (buyAreaCount) {
+      this.specList = this.specList.map(spec => {
+        const priceInfo = this.commonGetPrice(buyAreaCount, spec.cycleType)
+        spec.price = priceInfo.price
+        spec.perDayPrice = priceInfo.perDayPrice
+        spec.desc = '每天仅需' + priceInfo.perDayPrice + '元'
+        return spec
+      })
+    },
+    async updatePrice () {
+      const params = this.getSubmitParam()
+      const { data, success } = await getSelectPrice(params)
+      if (success) {
+        this.computedPrice.total = data.original_price
+        this.computedPrice.pay = data.order_price
+        this.computedPrice.discount = data.original_price - data.order_price
+      } else {
+        this.computedPrice.total = 0
+        this.computedPrice.pay = 0
+        this.computedPrice.discount = 0
+      }
+    },
+    getSubmitParam () {
+      const buyInfo = this.buyInfo
+      const coupon = this.couponActiveItem
+      const selectArea = this.selectInfo.area ? this.selectInfo.area : { 北京: [] }
+      const param = {
+        userLotteryId: coupon.userLotteryId,
+        lotteryId: coupon.lotteryId,
+        useProduct: this.specActiveItem.productionId,
+        discountId: ''
+      }
+
+      // orderType: 1购买、2续费、3升级
+      if (this.buyType === 'buy') {
+        return {
+          ...param,
+          area: JSON.stringify(selectArea),
+          time: this.specActiveItem.value,
+          orderType: 1
+        }
+      } else if (this.buyType === 'upgrade') {
+        if (buyInfo.buyset && buyInfo.buyset.upgrade === 1) {
+          // buyInfo.buyset.upgrade === 1新版本升级
+        } else {
+          // 旧版本超级订阅升级
+        }
+
+        return {
+          ...param,
+          area: JSON.stringify(selectArea),
+          orderType: 3
+        }
+      } else {
+        return {}
+      }
+    },
+    async submitXHR () {
+      const params = this.getSubmitParam()
+      params.price = this.computedPrice.pay
+      if (this.buyType === 'buy') {
+        return createSVIPOrder(params)
+      } else if (this.buyType === 'upgrade') {
+        return svipUpgrade(params)
+      }
+    },
+    async submit () {
+      const { data, success, errMsg } = await this.submitXHR()
+      if (success) {
+        const orderCode = data.code
+        window.open(`/front/vipsubscribe/orderPay/${orderCode}`)
+      } else {
+        if (errMsg) {
+          this.$toast(errMsg)
+        }
+      }
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+::v-deep .custom-dialog {
+  margin: 0 auto;
+  top: 50%;
+  transform: translateY(-50%);
+  background-color: transparent;
+  box-shadow: none;
+  .el-dialog__header,
+  .el-dialog__body {
+    padding: 0;
+  }
+  .el-dialog__body {
+    display: flex;
+    align-items: center;
+    justify-content: center;
+  }
+}
+
+.vip-sub-list .vip-sub-list-item {
+  padding: 40px 0;
+}
+.vip-sub-list .vip-sub-list-item:not(:last-of-type) {
+  border-bottom: 1px solid #E0E0E0;
+}
+.vip-sub-list .vip-sub-item-title {
+  width: 120px;
+}
+.vip-sub-item-content {
+  line-height: 26px;
+}
+
+.pre-tag {
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  padding: 2px 10px;
+  color: #fff;
+  font-size: 14px;
+  line-height: 20px;
+  border-radius: 12px;
+  background-color: #2CB7CA;
+}
+.vip-subscribe-title {
+  font-size: 18px;
+  color: #1D1D1D;
+  line-height: 28px;
+}
+.vip-subscribe-content {
+  margin-top: 12px;
+  padding: 0 32px;
+  background-color: #fff;
+  border-top: 2px solid #2CB7CA;
+}
+.area-container {
+  display: flex;
+  width: 600px;
+  padding: 6px 10px;
+  border: 1px solid #E0E0E0;
+  border-radius: 4px;
+  .pre-tag {
+    margin-right: 10px;
+    height: 26px;
+  }
+}
+.area-container {
+  &-content {
+    flex: 1;
+    cursor: pointer;
+  }
+  &-placeholder {
+    color: #aaa;
+    cursor: pointer;
+  }
+}
+.tip-content {
+  margin-left: 16px;
+  color: #FF3A20;
+  font-size: 12px;
+  line-height: 40px;
+}
+</style>

+ 483 - 0
src/views/vipsubscribe/components/Contrast.vue

@@ -0,0 +1,483 @@
+<template>
+  <div class="sub-contrast">
+    <div class="contrast-header">
+      <div class="line-flex">
+        <span class="split-box--before"></span>
+        <div class="second-desc">免费订阅</div>
+        <img class="text-vs" src="@/assets/images/sub-compare.png" alt="对比">
+        <div class="second-desc">超级订阅</div>
+        <span class="split-box--after"></span>
+      </div>
+    </div>
+    <div class="contrast-main">
+      <div class="contrast-main-center">
+        <div class="center-left">
+          <ul class="clearfix">
+            <li class="top-title modify-left">功能/产品</li>
+            <li class="double"><div>标讯高级搜索</div><div>按联系方式、附件、项目名称/标的物、发布时间搜索</div></li>
+            <li class="gray double"><div>企业搜索</div><div>按中标项目/标的物、联系方式等搜索企业信息</div></li>
+            <li>订阅关键词</li>
+            <li>中标企业联系方式</li>
+            <li>订阅区域</li>
+            <li>订阅推送</li>
+            <li>匹配方式</li>
+            <li class="double"><div>推送设置</div><div>固定时间/实时推送</div></li>
+            <li class="gray double"><div>企业画像</div><div>提供企业中标项目分析、重点客户等多维分析</div></li>
+            <li class="double"><div>采购单位画像</div><div>提供重点供应商、采购预算/方式等分析</div></li>
+            <li class="gray double"><div>附件下载</div><div>招标文件/采购清单一键下载</div></li>
+            <li>月报/周报</li>
+            <li class="gray double"><div>标讯收藏</div><div>关注项目一键收藏,重要信息不遗漏</div></li>
+            <li>专属资源社群对接</li>
+          </ul>
+        </div>
+        <div class="center-center">
+          <ul class="clearfix">
+            <li class="top-title modify-center gray">免费订阅</li>
+            <li class="double"><i class="wrong"></i></li>
+            <li class="gray double">4条/次</li>
+            <li>10组</li>
+            <li>公告公示</li>
+            <li>免费订阅1个省</li>
+            <li>300条/天</li>
+            <li>标题</li>
+            <li class="double"><i class="wrong"></i></li>
+            <li class="gray double"><i class="wrong"></i></li>
+            <li class="double"><i class="wrong"></i></li>
+            <li class="gray double"><i class="wrong"></i></li>
+            <li><i class="wrong"></i></li>
+            <li class="gray double">100条</li>
+            <li><i class="wrong"></i></li>
+          </ul>
+        </div>
+        <div class="center-right">
+          <ul class="clearfix">
+              <li class="top-title modify-right">超级订阅</li>
+              <li class="double"><i class="right"></i></li>
+              <li class="gold double">150条/次</li>
+              <li>300组</li>
+              <li>招标公告+国家企业公示</li>
+              <li>根据套餐类型可选</li>
+              <li>2000条/天</li>
+              <li>标题+全文</li>
+              <li class="double">可选</li>
+              <li class="gold double">50个画像/省</li>
+              <li class="double">5个画像/省</li>
+              <li class="gold double">10次/月</li>
+              <li><i class="right"></i></li>
+              <li class="gold double">5000条</li>
+              <li><i class="right"></i></li>
+            </ul>
+          </div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'contrast',
+  data () {
+    return {
+      tableList: [
+        [
+          {
+            label: '宫娥能'
+          }
+        ]
+      ]
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.split-box {
+  &--before {
+    margin-right: 25px;
+    &::before {
+      content: "";
+      display: inline-block;
+      width: 120px;
+      height: 1px;
+      margin-bottom: 4px;
+      background: linear-gradient(90deg, rgba(204, 173, 135, 0), #CCAD87 100%);
+    }
+    &::after {
+      content: "";
+      display: inline-block;
+      width: 8px;
+      height: 8px;
+      background: #CCAD87;
+      transform: rotate(45deg);
+    }
+  }
+  &--after {
+    margin-left: 25px;
+    &::before {
+      content: "";
+      display: inline-block;
+      width: 8px;
+      height: 8px;
+      background: #CCAD87;
+      transform: rotate(45deg);
+    }
+    &::after {
+      content: "";
+      display: inline-block;
+      width: 120px;
+      height: 1px;
+      margin-bottom: 4px;
+      background: linear-gradient(90deg, #CCAD87, rgba(204, 173, 135, 0) 100%);
+    }
+  }
+}
+.line-flex {
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  height: 100%;
+}
+.text-vs {
+  width: 39px;
+  height: 18px;
+  margin: 0 10px;
+}
+.sub-contrast {
+  width: 100%;
+  min-height: 1020px;
+  padding-top: 79px;
+  background-color: #fff;
+  .contrast-header {
+    width: 100%;
+    height: 31px;
+  }
+  .contrast-main {
+    width: 100%;
+    height: 1020px;
+    margin-top: 32px;
+
+    i {
+      &.wrong {
+        width: 100%;
+        height: 100%;
+        &::before {
+          display: block;
+          width: 100%;
+          height: 100%;
+          content: "";
+          background: url(~@/assets/images/icon/guan.png) no-repeat center;
+          background-size: 16px 16px;
+        }
+      }
+      &.right::before {
+        display: block;
+        width: 100%;
+        height: 100%;
+        content: "";
+        background-image: url(~@/assets/images/icon/right.png);
+        background-size: 24px 24px;
+        background-repeat: no-repeat;
+        background-position: center;
+      }
+    }
+    .contrast-main-center {
+      display: flex;
+      justify-content: center;
+      .gray {
+        background: #F5F5FB;
+      }
+      .gold {
+        background: #FBF5EB !important;
+      }
+
+      .top-title {
+        height: 68px;
+        text-align: center;
+        transition: all 0.5s;
+        line-height: 68px;
+        font-size: 20px;
+        font-family: Microsoft YaHei;
+        font-weight: 400;
+        color: rgba(29, 29, 29, 1);
+        opacity: 1;
+        border-bottom: 1px solid rgba(224, 224, 224, 1);
+      }
+
+      /* 功能/价格 */
+      /* li+li表示选中除第一个li其他所有的li */
+      .center-left {
+        width: 468px;
+        & > ul {
+          width: 468px;
+          margin: 0;
+          li + li {
+            color: rgba(29, 29, 29, 1);
+            padding-left: 24px;
+            width: 468px;
+            opacity: 1;
+            border-left: 1px solid rgba(224, 224, 224, 1);
+            border-bottom: 1px solid rgba(224, 224, 224, 1);
+            border-right: 1px solid rgba(224, 224, 224, 1);
+            font-family: Microsoft YaHei;
+            &.double {
+              height: 74px;
+              font-size: 16px;
+              font-weight: 400;
+              color: rgba(29, 29, 29, 1);
+              display: flex;
+              flex-direction: column;
+              justify-content: center;
+              & > div:nth-child(1){
+                font-size: 16px;
+                line-height: 24px;
+                color: #1D1D1D;
+                font-weight: 400;
+              }
+            }
+            &:not(.double) {
+              height: 52px;
+              line-height: 52px;
+              font-size: 16px;
+              font-weight: 400;
+              color: rgba(29, 29, 29, 1);
+            }
+
+            &.double,
+            &.double > div:nth-child(2) {
+              font-size: 14px;
+              font-weight: 400;
+              color: #686868;
+              line-height: 22px;
+            }
+          }
+        }
+        .modify-left {
+          width: 100%;
+          border-left: 1px solid rgba(224, 224, 224, 1);
+          border-top: 1px solid rgba(224, 224, 224, 1);
+        }
+      }
+
+      // 免费版
+      .center-center {
+        width: 336px;
+        transition: all 0.5s;
+        & > ul {
+          width: 336px;
+          transition: all 0.5s;
+          margin: 0;
+          li + li {
+            transition: all 0.5s;
+            width: 336px;
+            text-align: center;
+            font-size: 14px;
+            font-family: Microsoft YaHei;
+            font-weight: 400;
+            color: rgba(29, 29, 29, 1);
+            opacity: 1;
+            border-bottom: 1px solid rgba(224, 224, 224, 1);
+            border-right: 1px solid rgba(224, 224, 224, 1);
+
+            &.double {
+              height: 74px;
+              line-height: 74px;
+            }
+            &:not(.double) {
+              height: 52px;
+              line-height: 52px;
+            }
+          }
+
+          li {
+            &:last-of-type {
+              display: flex;
+              transition: all 0.5s;
+              justify-content: center;
+              align-items: center;
+
+              .btn-free {
+                display: block;
+                cursor: pointer;
+                transition: all 0.5s;
+                width: 90px;
+                height: 30px;
+                background: rgba(246, 246, 246, 1);
+                opacity: 1;
+                border-radius: 4px;
+                font-size: 16px;
+                font-family: Microsoft YaHei;
+                font-weight: 400;
+                line-height: 26px;
+                color: rgba(104, 104, 104, 1);
+              }
+            }
+          }
+        }
+
+        /* 免费版滑过特效 */
+        &:hover {
+          position: relative;
+          ul {
+            transition: 0.5s;
+            box-shadow: 0px 0px 20px rgba(0, 0, 0, 0.2);
+            margin-top: -22px;
+
+            .modify-center {
+              height: 90px;
+              line-height: 90px;
+              transition: 0.5s;
+            }
+
+            li {
+              &:last-of-type {
+                height: 65px;
+                transition: 0.5s;
+                line-height: 80px;
+                display: flex;
+                justify-content: center;
+                align-items: center;
+
+                .btn-free {
+                  transition: 0.5s;
+                  background: rgba(44, 183, 202, 1);
+                  color: white;
+                }
+              }
+            }
+          }
+        }
+      }
+
+      /* VIP订阅专属服务 */
+      .center-right {
+        width: 336px;
+        transition: all 0.5s;
+        border-right: 1px solid rgba(224, 224, 224, 1);
+
+        & > ul {
+          width: 336px;
+          margin: 0;
+          transition: all 0.5s;
+
+          li + li {
+            width: 336px;
+            text-align: center;
+            transition: all 0.5s;
+            font-size: 14px;
+            font-family: Microsoft YaHei;
+            font-weight: 400;
+            color: #714402;
+            background: rgba(255, 226, 193, 0.08);
+            opacity: 1;
+            border-bottom: 1px solid rgba(224, 224, 224, 1);
+
+            &.double {
+              height: 74px;
+              line-height: 74px;
+            }
+            &:not(.double) {
+              height: 52px;
+              line-height: 52px;
+            }
+          }
+
+          li {
+            &:last-of-type {
+              align-items: center;
+              transition: all 0.5s;
+
+              .On-trial {
+                width: 90px;
+                height: 30px;
+                border: 1px solid rgba(207, 173, 137, 1);
+                transition: all 0.5s;
+                opacity: 1;
+                border-radius: 4px;
+                display: block;
+                text-align: center;
+                line-height: 30px;
+                font-size: 14px;
+                font-family: MicrosoftYaHei;
+                color: rgba(207, 173, 137, 1);
+                margin-left: 16px;
+                text-decoration: none !important;
+              }
+            }
+          }
+        }
+
+        /* VIP订阅滑过特效 */
+        &:hover {
+          position: relative;
+          ul {
+            margin-top: -22px;
+            box-shadow: 0px 0px 20px rgba(0, 0, 0, 0.2);
+            transition: all 0.5s;
+
+            .modify-right {
+              height: 90px;
+              line-height: 90px;
+              transition: all 0.5s;
+            }
+
+            li {
+              &:last-of-type {
+                height: 65px;
+                line-height: 80px;
+                transition: all 0.5s;
+
+                .On-trial {
+                  background: #34355A;
+                  font-size: 14px;
+                  font-family: MicrosoftYaHei;
+                  line-height: 30px;
+                  color: rgba(255, 218, 177, 1);
+                  transition: all 0.5s;
+                  opacity: 1;
+                  text-decoration: none;
+                }
+              }
+            }
+          }
+        }
+      }
+
+      ul {
+        /* 选中免费版 */
+        .modify-center {
+          background: #F5F5FB;
+          width: 100%;
+        }
+        /* 选中VIP订阅专属服务 */
+        .modify-right {
+          background: rgba(52, 53, 90, 1);
+          color: rgba(255, 218, 177, 1);
+          position: relative;
+          border-right: 0;
+          width: 100%;
+          background-image: url(~@/assets/images/vip/mengban.png);
+          background-size: 200px 36px;
+          background-repeat: no-repeat;
+          background-position: right bottom;
+          img {
+            background: rgba(52, 53, 90, 1);
+            color: rgba(255, 218, 177, 1);
+            position: absolute;
+            right: 0;
+            bottom: 0;
+            width: 174px;
+          }
+        }
+
+        li > p {
+          font-size: 14px;
+          font-family: Microsoft YaHei-Regular, Microsoft YaHei;
+          font-weight: 400;
+          color: #686868;
+          line-height: 22px;
+        }
+      }
+    }
+  }
+}
+</style>