|
@@ -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>
|