|
@@ -1,134 +1,281 @@
|
|
|
<template>
|
|
|
- <div class="container">
|
|
|
+ <div v-loading="isLoading" class="container">
|
|
|
<div class="title">购买会员</div>
|
|
|
<!-- 会员套餐 -->
|
|
|
<div class="section">
|
|
|
<div class="subtitle">会员套餐<span class="tip">(基础服务功能)</span></div>
|
|
|
- <div class="list">
|
|
|
- <card :always-show-icon="false" :checked="true">
|
|
|
+ <radio-card
|
|
|
+ v-model="checkedPackage"
|
|
|
+ :list="packageList"
|
|
|
+ :show-un-active-icon="false"
|
|
|
+ @change="handlePackageChange"
|
|
|
+ >
|
|
|
+ <template #item="{ row }">
|
|
|
<div class="vip-package">
|
|
|
- <div class="time">1年</div>
|
|
|
+ <div class="time">{{ row.duration + (row.unit === 1 ? '月' : '年') }}</div>
|
|
|
<div>
|
|
|
<span>¥</span>
|
|
|
- <span class="price">5980</span>
|
|
|
- <span class="deleted">¥7980</span>
|
|
|
+ <span class="price">{{ row.price }}</span>
|
|
|
+ <span class="deleted">¥{{ row.originalPrice }}</span>
|
|
|
</div>
|
|
|
</div>
|
|
|
- </card>
|
|
|
- <card :always-show-icon="false">
|
|
|
- <div class="vip-package">
|
|
|
- <div class="time">1年</div>
|
|
|
- <div>
|
|
|
- <span>¥</span>
|
|
|
- <span class="price">5980</span>
|
|
|
- <span class="deleted">¥7980</span>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </card>
|
|
|
- </div>
|
|
|
+ </template>
|
|
|
+ </radio-card>
|
|
|
</div>
|
|
|
<el-divider class="divider" />
|
|
|
<!-- 定制服务 -->
|
|
|
<div class="section">
|
|
|
- <div class="subtitle">订制服务<span class="tip">(勾选且付费后,将会有专人与您进行沟通)</span></div>
|
|
|
- <div class="list">
|
|
|
- <card>
|
|
|
- <div class="service-package">
|
|
|
- <div class="name">认证授权图片模板</div>
|
|
|
- <div class="subname">定制要求与费用另议</div>
|
|
|
- </div>
|
|
|
- </card>
|
|
|
- <card>
|
|
|
- <div class="service-package">
|
|
|
- <div class="name">认证授权物料制作</div>
|
|
|
- <div class="subname">定制要求与费用另议</div>
|
|
|
- </div>
|
|
|
- </card>
|
|
|
- <card>
|
|
|
+ <div class="subtitle">定制服务<span class="tip">(勾选且付费后,将会有专人与您进行沟通)</span></div>
|
|
|
+ <radio-card v-model="checkedServiceList" :list="serviceList" type="checkbox">
|
|
|
+ <template #item="{ row }">
|
|
|
<div class="service-package">
|
|
|
- <div class="name">品牌资料库</div>
|
|
|
+ <div class="name">{{ row.name }}</div>
|
|
|
<div class="subname">定制要求与费用另议</div>
|
|
|
</div>
|
|
|
- </card>
|
|
|
- <card>
|
|
|
- <div class="service-package">
|
|
|
- <div class="name">其他</div>
|
|
|
- <div class="subname">定制要求与费用另议</div>
|
|
|
- </div>
|
|
|
- </card>
|
|
|
- </div>
|
|
|
+ </template>
|
|
|
+ </radio-card>
|
|
|
</div>
|
|
|
<el-divider class="divider" />
|
|
|
- <!-- 选择支付方式 -->
|
|
|
- <div class="section">
|
|
|
- <div class="subtitle">选择支付方式</div>
|
|
|
- <div class="list">
|
|
|
- <card v-for="item in payWayList" :key="item.id" :border="false" :always-show-icon="false" :checked="item.id === 0">
|
|
|
- <el-image :src="item.image" class="pay-way" @click="handleChoosePayWay(item)" />
|
|
|
- </card>
|
|
|
+ <template v-if="paySwitch">
|
|
|
+ <!-- 选择支付方式 -->
|
|
|
+ <div class="section">
|
|
|
+ <div class="subtitle">选择支付方式</div>
|
|
|
+ <radio-card v-model="checkedPayWay" :list="payWayList" :border="false" :show-un-active-icon="false">
|
|
|
+ <template #item="{ row }">
|
|
|
+ <el-image :src="row.image" class="pay-way" />
|
|
|
+ </template>
|
|
|
+ </radio-card>
|
|
|
</div>
|
|
|
- </div>
|
|
|
- <!-- 支付 -->
|
|
|
- <div class="pay-action">
|
|
|
+ <!-- 支付 -->
|
|
|
<!-- 阿里云支付 -->
|
|
|
- <pay-alipay v-if="selectPayWay === 0" class="pay-code" />
|
|
|
+ <pay-alipay
|
|
|
+ v-if="checkedPayWay === 1"
|
|
|
+ class="pay-code"
|
|
|
+ :data="orderInfo"
|
|
|
+ :pay-way="checkedPayWay"
|
|
|
+ @pay-confirm="handlePayConfirm"
|
|
|
+ @hook:created="handleScanPayStart"
|
|
|
+ />
|
|
|
<!-- 微信支付 -->
|
|
|
- <pay-wechat v-if="selectPayWay === 1" class="pay-code" />
|
|
|
+ <pay-wechat
|
|
|
+ v-if="checkedPayWay === 2"
|
|
|
+ class="pay-code"
|
|
|
+ :data="orderInfo"
|
|
|
+ :pay-way="checkedPayWay"
|
|
|
+ @pay-confirm="handlePayConfirm"
|
|
|
+ @hook:created="handleScanPayStart"
|
|
|
+ />
|
|
|
<!-- 企业网银支付 & 个人网银支付-->
|
|
|
- <pay-bank v-if="selectPayWay === 2 || selectPayWay === 3" class="pay-bank" />
|
|
|
- </div>
|
|
|
+ <template v-if="checkedPayWay === 3 || checkedPayWay === 4">
|
|
|
+ <pay-bank
|
|
|
+ :key="checkedPayWay"
|
|
|
+ class="pay-bank"
|
|
|
+ :data="orderInfo"
|
|
|
+ :pay-way="checkedPayWay"
|
|
|
+ @pay-confirm="handlePayConfirm"
|
|
|
+ @hook:created="handleOtherPayStart"
|
|
|
+ />
|
|
|
+ </template>
|
|
|
+ </template>
|
|
|
+ <template v-else>
|
|
|
+ <el-alert show-icon title="支付系统遇到点小问题,请稍后重试或联系管理员处理" type="error" effect="dark" />
|
|
|
+ </template>
|
|
|
</div>
|
|
|
</template>
|
|
|
|
|
|
<script>
|
|
|
+// 图标
|
|
|
import imgPayAli from '@/assets/pay/pay-ali.png'
|
|
|
import imgBank from '@/assets/pay/pay-bank.png'
|
|
|
import imgSelfBank from '@/assets/pay/pay-self-bank.png'
|
|
|
import imgWechat from '@/assets/pay/pay-wechat.png'
|
|
|
-
|
|
|
import PayAlipay from '@/views/components/payment/pay-alipay.vue'
|
|
|
import PayWechat from '@/views/components/payment/pay-wechat.vue'
|
|
|
import PayBank from '@/views/components/payment/pay-bank.vue'
|
|
|
|
|
|
-import Card from '@/components/Card'
|
|
|
+// 单选 / 多选
|
|
|
+import RadioCard from '@/views/components/RadioCard'
|
|
|
+
|
|
|
+// 接口
|
|
|
+import { fetchConfigureList } from '@/api/member'
|
|
|
+import { registerSuperPay, payOnlineChecked, checkedWinxinPaySuccess, checkedOtherPaySuccess } from '@/api/pay'
|
|
|
+
|
|
|
export default {
|
|
|
components: {
|
|
|
- Card,
|
|
|
+ RadioCard,
|
|
|
PayAlipay,
|
|
|
PayWechat,
|
|
|
PayBank
|
|
|
},
|
|
|
data() {
|
|
|
return {
|
|
|
- selectPayWay: 0,
|
|
|
+ isLoading: true,
|
|
|
+ orderInfo: {
|
|
|
+ pageType: 4,
|
|
|
+ payAmount: '',
|
|
|
+ vipId: '',
|
|
|
+ vipRecordId: ''
|
|
|
+ },
|
|
|
+ packageList: [],
|
|
|
+ serviceList: [],
|
|
|
+ checkedPackage: '',
|
|
|
+ checkedServiceList: [],
|
|
|
+ checkedPayWay: 0,
|
|
|
+ paySwitch: true,
|
|
|
+ redirectUrlQuery: {},
|
|
|
+ // 扫码支付倒计时
|
|
|
+ scanToPayStartTime: 0,
|
|
|
+ scanToPayEndTime: 0,
|
|
|
+ payType: '',
|
|
|
payWayList: [
|
|
|
{
|
|
|
image: imgPayAli,
|
|
|
name: '阿里云支付',
|
|
|
- id: 0
|
|
|
+ id: 1,
|
|
|
+ checked: true
|
|
|
},
|
|
|
{
|
|
|
image: imgWechat,
|
|
|
name: '微信支付',
|
|
|
- id: 1
|
|
|
+ id: 2,
|
|
|
+ checked: false
|
|
|
},
|
|
|
{
|
|
|
image: imgBank,
|
|
|
name: '企业网银支付',
|
|
|
- id: 2
|
|
|
+ id: 3,
|
|
|
+ checked: false
|
|
|
},
|
|
|
{
|
|
|
image: imgSelfBank,
|
|
|
name: '个人网银支付',
|
|
|
- id: 3
|
|
|
+ id: 4,
|
|
|
+ checked: false
|
|
|
}
|
|
|
]
|
|
|
}
|
|
|
},
|
|
|
+ created() {
|
|
|
+ this.fetchConfigureList()
|
|
|
+ this.payOnlineChecked()
|
|
|
+ },
|
|
|
methods: {
|
|
|
- handleChoosePayWay(item) {
|
|
|
- console.log(item)
|
|
|
- this.selectPayWay = item.id
|
|
|
+ // 获取套餐 服务配置列表
|
|
|
+ fetchConfigureList() {
|
|
|
+ fetchConfigureList()
|
|
|
+ .then(res => {
|
|
|
+ this.packageList = res.data.packageList
|
|
|
+ this.serviceList = res.data.serviceList
|
|
|
+ // 设置初始值
|
|
|
+ this.checkedPackage = this.packageList[0].id
|
|
|
+ this.registerSuperPay()
|
|
|
+ this.setOrderInfo()
|
|
|
+ })
|
|
|
+ .finally(() => {
|
|
|
+ this.isLoading = false
|
|
|
+ })
|
|
|
+ },
|
|
|
+ // 设置订单信息(这个假订单)
|
|
|
+ setOrderInfo() {
|
|
|
+ const findOne = this.packageList.find(item => item.id === this.checkedPackage)
|
|
|
+ if (findOne) {
|
|
|
+ this.orderInfo.payAmount = findOne.price
|
|
|
+ this.orderInfo.vipId = findOne.id
|
|
|
+ }
|
|
|
+ },
|
|
|
+ // 套餐修改
|
|
|
+ handlePackageChange() {
|
|
|
+ this.checkedPayWay = 0
|
|
|
+ this.registerSuperPay()
|
|
|
+ this.setOrderInfo()
|
|
|
+ },
|
|
|
+ // 在线支付开通会员预处理
|
|
|
+ registerSuperPay() {
|
|
|
+ registerSuperPay({
|
|
|
+ authUserId: this.$store.getters.authUserId,
|
|
|
+ packageId: this.checkedPackage
|
|
|
+ }).then(res => {
|
|
|
+ this.orderInfo.vipRecordId = res.data
|
|
|
+ })
|
|
|
+ },
|
|
|
+ // 在线支付开关检测
|
|
|
+ payOnlineChecked() {
|
|
|
+ payOnlineChecked().then(res => {
|
|
|
+ if (res.data === '1') {
|
|
|
+ this.paySwitch = true
|
|
|
+ } else {
|
|
|
+ this.paySwitch = false
|
|
|
+ }
|
|
|
+ })
|
|
|
+ },
|
|
|
+ // 确认支付是否完成
|
|
|
+ handlePayConfirm(e) {
|
|
|
+ this.redirectUrlQuery = {
|
|
|
+ payAmount: e.data.payAmount
|
|
|
+ }
|
|
|
+ this.payType = e.type
|
|
|
+ if (e.type === 'WEIXIN') {
|
|
|
+ this.checkedWinxinPaySuccess({ vipRecordId: e.data.vipRecordId })
|
|
|
+ } else {
|
|
|
+ this.checkedOtherPaySuccess({ mbOrderId: e.data.mbOrderId })
|
|
|
+ }
|
|
|
+ },
|
|
|
+ // 查询是否成功(微信支付专用)
|
|
|
+ checkedWinxinPaySuccess(params) {
|
|
|
+ checkedWinxinPaySuccess(params).then(res => {
|
|
|
+ this.handlePayResult(res)
|
|
|
+ })
|
|
|
+ },
|
|
|
+ // 查询支付是否成功 (支付宝 银联)
|
|
|
+ checkedOtherPaySuccess(params) {
|
|
|
+ checkedOtherPaySuccess(params).then(res => {
|
|
|
+ this.handlePayResult(res)
|
|
|
+ })
|
|
|
+ },
|
|
|
+ // 处理支付查询结果
|
|
|
+ handlePayResult(result) {
|
|
|
+ result = JSON.parse(result.data)
|
|
|
+ if (result.data.status === '1') {
|
|
|
+ this.$router.push({
|
|
|
+ path: '/pay/success',
|
|
|
+ query: this.redirectUrlQuery
|
|
|
+ })
|
|
|
+ } else {
|
|
|
+ this.diffScanOverTime(60, () => {
|
|
|
+ this.$router.push({
|
|
|
+ path: '/pay/faild',
|
|
|
+ query: this.redirectUrlQuery
|
|
|
+ })
|
|
|
+ })
|
|
|
+ }
|
|
|
+ },
|
|
|
+ // 扫码支付开始
|
|
|
+ handleScanPayStart() {
|
|
|
+ const h = this.$createElement
|
|
|
+ this.$notify({
|
|
|
+ title: '扫码支付提示',
|
|
|
+ message: h('span', { style: 'color: #ff6d6d' }, '请在5分钟内完成扫码支付')
|
|
|
+ })
|
|
|
+ this.scanToPayStartTime = new Date().getTime()
|
|
|
+ console.log('扫码支付开始', this.scanToPayStartTime)
|
|
|
+ },
|
|
|
+ // 其他支付方式(非扫码支付)
|
|
|
+ handleOtherPayStart() {
|
|
|
+ this.scanToPayStartTime = 0
|
|
|
+ },
|
|
|
+ diffScanOverTime(time, callback) {
|
|
|
+ if (this.scanToPayStartTime > 0) {
|
|
|
+ this.scanToPayEndTime = new Date().getTime()
|
|
|
+ const subTime = this.scanToPayEndTime - this.scanToPayStartTime
|
|
|
+ const maxTime = time * 1000
|
|
|
+ if (subTime > maxTime) {
|
|
|
+ console.log('放行')
|
|
|
+ callback()
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ console.log('放行')
|
|
|
+ callback()
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|
|
@@ -147,7 +294,7 @@ export default {
|
|
|
margin: 40px 0;
|
|
|
}
|
|
|
|
|
|
-.pay-bank{
|
|
|
+.pay-bank {
|
|
|
margin: 25px 0;
|
|
|
}
|
|
|
|
|
@@ -170,62 +317,62 @@ export default {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- .list {
|
|
|
- .pay-way {
|
|
|
- display: block;
|
|
|
- width: 128px;
|
|
|
- height: 44px;
|
|
|
- }
|
|
|
+ .vip-package {
|
|
|
+ height: 100%;
|
|
|
+ display: flex;
|
|
|
+ justify-content: center;
|
|
|
+ align-items: center;
|
|
|
+ flex-direction: column;
|
|
|
|
|
|
- .service-package {
|
|
|
- height: 100%;
|
|
|
- display: flex;
|
|
|
- justify-content: center;
|
|
|
- align-items: center;
|
|
|
- flex-direction: column;
|
|
|
+ width: 232px;
|
|
|
+ height: 128px;
|
|
|
|
|
|
- width: 232px;
|
|
|
- height: 128px;
|
|
|
+ .time {
|
|
|
+ margin-bottom: 16px;
|
|
|
+ font-size: 18px;
|
|
|
+ font-weight: bold;
|
|
|
+ color: #404040;
|
|
|
+ }
|
|
|
|
|
|
- .name {
|
|
|
- margin-bottom: 16px;
|
|
|
- font-size: 18px;
|
|
|
- color: #404040;
|
|
|
- }
|
|
|
- .subname {
|
|
|
- font-size: 14px;
|
|
|
- color: #ff6d6d;
|
|
|
- }
|
|
|
+ span {
|
|
|
+ color: #ff6d6d;
|
|
|
}
|
|
|
|
|
|
- .vip-package {
|
|
|
- height: 100%;
|
|
|
- display: flex;
|
|
|
- justify-content: center;
|
|
|
- align-items: center;
|
|
|
- flex-direction: column;
|
|
|
-
|
|
|
- width: 232px;
|
|
|
- height: 128px;
|
|
|
-
|
|
|
- .time {
|
|
|
- margin-bottom: 16px;
|
|
|
- font-size: 18px;
|
|
|
- font-weight: bold;
|
|
|
- color: #404040;
|
|
|
- }
|
|
|
+ .price {
|
|
|
+ font-size: 36px;
|
|
|
+ font-weight: bold;
|
|
|
+ color: #ff6d6d;
|
|
|
+ }
|
|
|
+ .deleted {
|
|
|
+ font-size: 14px;
|
|
|
+ color: #b2b2b2;
|
|
|
+ text-decoration: line-through;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .service-package {
|
|
|
+ height: 100%;
|
|
|
+ display: flex;
|
|
|
+ justify-content: center;
|
|
|
+ align-items: center;
|
|
|
+ flex-direction: column;
|
|
|
|
|
|
- .price {
|
|
|
- font-size: 36px;
|
|
|
- font-weight: bold;
|
|
|
- color: #ff6d6d;
|
|
|
- }
|
|
|
- .deleted {
|
|
|
- font-size: 14px;
|
|
|
- color: #b2b2b2;
|
|
|
- text-decoration: line-through;
|
|
|
- }
|
|
|
+ width: 232px;
|
|
|
+ height: 128px;
|
|
|
+
|
|
|
+ .name {
|
|
|
+ margin-bottom: 16px;
|
|
|
+ font-size: 18px;
|
|
|
+ color: #404040;
|
|
|
}
|
|
|
+ .subname {
|
|
|
+ font-size: 14px;
|
|
|
+ color: #ff6d6d;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .pay-way {
|
|
|
+ display: block;
|
|
|
+ width: 128px;
|
|
|
+ height: 44px;
|
|
|
}
|
|
|
}
|
|
|
</style>
|