Sfoglia il codice sorgente

feat: 新增附件下载包购买页面

zhangyuhan 3 anni fa
parent
commit
c70a828ccb
4 ha cambiato i file con 556 aggiunte e 0 eliminazioni
  1. 21 0
      src/api/modules/file.js
  2. 1 0
      src/api/modules/index.js
  3. 6 0
      src/router/svip-routers.js
  4. 528 0
      src/views/public/Buy.vue

+ 21 - 0
src/api/modules/file.js

@@ -0,0 +1,21 @@
+import request from '@/api'
+import qs from 'qs'
+
+export function createOrder (data) {
+  return request({
+    baseURL: '/jypay',
+    url: '/resourcePack/createOrder',
+    method: 'POST',
+    data
+  })
+}
+
+export function getFilePackList (data) {
+  data = qs.stringify(data)
+  return request({
+    baseURL: '/jypay',
+    url: '/resourcePack/price',
+    method: 'POST',
+    data
+  })
+}

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

@@ -9,3 +9,4 @@ export * from './potential'
 export * from './project'
 export * from './coupon'
 export * from './svip'
+export * from './file'

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

@@ -5,5 +5,11 @@ export default [
     path: '/free/svip/buy',
     name: 'svip_buy',
     component: () => import('@/views/vipsubscribe/Buy.vue')
+  },
+  // 购买附件下载包
+  {
+    path: '/free/filePack/buy',
+    name: 'file_buy',
+    component: () => import('@/views/public/Buy.vue')
   }
 ]

+ 528 - 0
src/views/public/Buy.vue

@@ -0,0 +1,528 @@
+<template>
+  <Layout class="vip-subscribe-buy" contentWithState="full" :needAd="false">
+    <div class="vip-subscribe-title">{{ buyTypeText }}</div>
+    <div class="vip-subscribe-content">
+      <div class="vip-sub-list">
+        <SelectorCard
+          class="vip-sub-list-item"
+          v-if="moduleShow.specList"
+          :cardType="conf.selectorType">
+          <div slot="header" class="vip-sub-item-title">{{ buySpecLabel }}</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="computedPrice.total"
+              @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">
+            <CouponGiftList
+              :productionId="specActiveItem.productionId"
+              @loaded="giftListLoaded" />
+          </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"
+      >
+        <template v-slot:buy-tip-group>
+          <p class="buy-tip">购买须知:
+            <br>1.仅限超级订阅用户充值附件下载个数时使用,可多次购买。
+            <br>2.使用有效期仅限超级订阅服务周期内的当月,次月清零,不可转赠。
+          </p>
+        </template>
+      </BuySubmit>
+    </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 CouponGiftList from '@/components/coupon/CouponGiftList.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 {
+  getFilePackList,
+  createOrder,
+  getUserAccountInfo,
+  getUserPower
+} from '@/api/modules/'
+
+export default {
+  name: 'vip-subscribe-buy',
+  components: {
+    Layout,
+    SelectorCard,
+    AreaSelector,
+    SpecList,
+    CouponCardList,
+    CouponGiftList,
+    CheckPhone,
+    BuySubmit,
+    Contrast,
+    [Dialog.name]: Dialog
+  },
+  data () {
+    return {
+      preTitle: '',
+      buyType: 'buy', // buy/upgrade
+      buySpecLabel: '选择附件个数',
+      conf: {
+        selectorType: 'line',
+        maxAreaCount: 15
+      },
+      dialog: {
+        area: false
+      },
+      moduleShow: {
+        specList: true,
+        coupon: false,
+        gift: false
+      },
+      phoneRegPass: false,
+      powerInfo: {
+        viper: true
+      },
+      userInfo: {
+        phone: ''
+      },
+      selectInfo: {
+        area: ''
+      },
+      buyInfo: {
+        buyset: {}
+      },
+      priceRules: {},
+      couponActiveItem: {},
+      specIdActive: 1,
+      specActiveItem: {},
+      specList: [
+        {
+          id: 1,
+          cycleType: 1, // 月
+          label: '5个附件',
+          value: 5,
+          price: 0,
+          desc: '',
+          perDayPrice: 0,
+          productionId: 1141, // 产品id,后台配置
+          tipText: ''
+        },
+        {
+          id: 2,
+          cycleType: 2, // 季
+          label: '10个附件',
+          value: 10,
+          price: 0,
+          desc: '',
+          perDayPrice: 0,
+          productionId: 1142,
+          tipText: ''
+        },
+        {
+          id: 3,
+          cycleType: 3, // 年
+          label: '20个附件',
+          value: 20,
+          price: 0,
+          desc: '',
+          perDayPrice: 0,
+          productionId: 1143,
+          tipText: ''
+        }
+      ],
+      computedPrice: {
+        total: 0,
+        discount: 0,
+        pay: 0
+      }
+    }
+  },
+  computed: {
+    oldVip () { // 是否是老版本超级订阅
+      return !this.powerInfo.viper
+    },
+    isCanPay () {
+      return this.powerInfo.viper && this.powerInfo.vipStatus > 0
+    },
+    upgradeTipShow () {
+      if (this.buyType === 'buy') {
+        return false
+      } else {
+        return !this.canUpgrade && !this.oldVip
+      }
+    },
+    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 () {
+      return '附件下载包充值'
+    },
+    noSelect () {
+      return !this.selectInfo.area
+    },
+    selectedCountInfo () {
+      const area = this.selectInfo.area
+      const count = Object.keys(area).length
+      return {
+        text: (count === 0 || count > this.conf.maxAreaCount) ? '全国' : `${count}个省`,
+        detail: (count === 0 || count > this.conf.maxAreaCount) ? '全国' : 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.isCanPay
+      return basicReg
+    }
+  },
+  created () {
+    this.getType()
+    this.getGoods()
+    this.getUserPower() // 获取最新的power
+    this.getUserAccountInfo()
+  },
+  beforeRouteEnter (to, from, next) {
+    const title = document.title
+    // 修改头部高亮
+    document.title = '附件下载包充值'
+    next(vm => {
+      vm.preTitle = title
+    })
+  },
+  beforeRouteLeave (to, from, next) {
+    document.title = this.preTitle
+    next()
+  },
+  mounted () {
+    $('#public-nav .jynav-list').find('span[name=大会员]').removeClass('active')
+    try {
+      window.trySelectNav('招标订阅')
+    } catch (error) {}
+  },
+  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()
+      }
+    },
+    setPriceItem (index, id, price, num) {
+      this.specList[index].productionId = id
+      this.specList[index].desc = ''
+      this.specList[index].price = price / 100
+      this.specList[index].label = num + '个附件'
+    },
+    async getGoods () {
+      const priceInfo = await getFilePackList({
+        product: 'attachmentDownPack'
+      })
+      console.log(priceInfo)
+      if (priceInfo.error_msg === '' && priceInfo.data) {
+          this.setPriceItem(0, 1141, priceInfo.data[5], 5)
+          this.setPriceItem(1, 1142, priceInfo.data[10], 10)
+          this.setPriceItem(2, 1143, priceInfo.data[20], 20)
+      }
+      this.specChange(this.specList[0])
+    },
+    async getUserAccountInfo () {
+      const { data, error_code: code } = await getUserAccountInfo()
+      if (code === 0) {
+        Object.assign(this.userInfo, data)
+      }
+    },
+    async getUserPower () {
+      const { data, error_code: code } = await getUserPower()
+      if (code === 0) {
+        Object.assign(this.powerInfo, data)
+      }
+    },
+    async getUserBuyInfo () {
+      const { data, success } = await getUserAccountInfo()
+      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.resetCouponList()
+    },
+    onAreaCancel () {
+      this.dialog.area = false
+    },
+    specChange (spec) {
+      this.specActiveItem = spec
+      this.resetCouponList()
+      this.resetGiftInfo()
+      this.updatePrice()
+    },
+    resetGiftInfo () {
+      this.specActiveItem.tipText = ''
+      this.specActiveItem.discountId = ''
+    },
+    resetCouponList () {
+      this.couponActiveItem = {}
+    },
+    couponCardLoaded ({ data }) {
+      this.moduleShow.coupon = !!data
+    },
+    couponCardChange (coupon) {
+      this.couponActiveItem = coupon
+    },
+    giftListLoaded ({ list }) {
+      if (Array.isArray(list) && list.length) {
+        const gift = list[0]
+        this.specActiveItem.tipText = `加赠${gift.giftInfo}`
+        this.$set(this.specActiveItem, 'discountId', gift.discountId)
+      } else {
+        this.specActiveItem.tipText = ''
+        this.$set(this.specActiveItem, 'discountId', '')
+      }
+    },
+    showAreaDialog () {
+      this.dialog.area = true
+      this.$nextTick(() => {
+        this.$refs.areaSelector.setCitySelected(this.selectInfo.area)
+      })
+    },
+    commonGetPrice (buyAreaCount, cycleType) {
+      if (buyAreaCount > this.conf.maxAreaCount) {
+        buyAreaCount = -1
+      }
+      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
+    },
+    async updatePrice () {
+      // TODO 获取优惠价格
+      const tempPrice = {
+        original_price: this.specActiveItem.price * 100,
+        pay_price: this.specActiveItem.price * 100
+      }
+      this.computedPrice.total = tempPrice.original_price
+      this.computedPrice.pay = tempPrice.pay_price
+      this.computedPrice.discount = tempPrice.original_price - tempPrice.pay_price
+    },
+    getSubmitParam () {
+      const buyInfo = this.buyInfo
+      const coupon = this.couponActiveItem
+      const param = {
+        "product":"attachmentDownPack",
+        "data":{
+          "num": this.specActiveItem.value
+        },
+        order_phone: this.userInfo.phone,
+        userLotteryId: coupon.userLotteryId,
+        lotteryId: coupon.lotteryId,
+        useProduct: this.specActiveItem.productionId,
+        discountId: this.specActiveItem.discountId
+      }
+      return param
+    },
+    async submitXHR () {
+      const params = this.getSubmitParam()
+      params.price = this.computedPrice.total
+      return createOrder(params)
+
+    },
+    async submit () {
+      const res = await this.submitXHR()
+      if (res && res.msg === '') {
+        const orderCode = res.order_code
+        if (this.computedPrice.pay !== 0) {
+          window.open(`/front/filePack/orderPay/${orderCode}`)
+        } else {
+          window.open(`/front/filePack/paySuccess/${orderCode}?payTime=${parseInt(Date.now() / 1000)}`)
+        }
+      } else {
+        this.$toast(res.msg || '创建订单失败')
+      }
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+::v-deep {
+  .font-red {
+    color: #FF3A20;
+  }
+}
+::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;
+  }
+}
+.buy-tip {
+  margin-top: 28px;
+  font-size: 12px;
+  font-weight: 400;
+  color: #888888;
+  line-height: 14px;
+}
+.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;
+  font-size: 12px;
+  line-height: 40px;
+}
+</style>