Commit 2b8bc5a5 authored by chenqikuai's avatar chenqikuai

merge feature-hdPay and fix conflicts

parents 30ceef74 e1b0be05
mv dist tracesourcemb-pay
tar -czf tracesourcemb-pay.tar tracesourcemb-pay
rm -rf tracesourcemb-pay
scp tracesourcemb-pay.tar root@120.26.174.69:/usr/share/nginx/html/tracesourcemb-pay.tar
rm -rf tracesourcemb-pay.tar
ssh root@120.26.174.69 'cd /usr/share/nginx/html && rm -rf tracesourcemb-pay && tar -xzf tracesourcemb-pay.tar && rm -rf tracesourcemb-pay.tar'
echo 'done. 👉 http://120.26.174.69:9092'
\ No newline at end of file
......@@ -12,7 +12,7 @@ const order = {
...params,
});
},
add(planId: number, method: number, params: any) {
add(planId: number, method: number, params: {[name: string]: any}) {
return axios.post(`${base}/add`, {
plan_id: planId,
promo_code: '',
......@@ -34,5 +34,11 @@ const order = {
},
});
},
payMethods() {
return axios({
url: `${base}/pay/methods`,
method: 'get',
});
},
};
export default order;
......@@ -120,7 +120,12 @@ const routes: RouteConfig[] = [
// this generates a separate chunk (about.[hash].js) for this route
// which is lazy-loaded when the route is visited.
component: () => import(/* webpackChunkName: "view-code" */ '@/views/ViewCode.vue'),
props: ({ query }) => ({ locationUrl: query.locationUrl }),
props: ({query}) => ({
locationUrl: query.locationUrl,
isPayment: query.payment ? JSON.parse(query.payment as string) : undefined,
coin: query.coin,
downloadUrl: query.downloadUrl,
}),
meta: { requiresAuth: true },
},
{
......
......@@ -2,16 +2,22 @@
<div class="view-code">
<!-- {{hash}} -->
<div class="container">
<div v-if="isPayment" class="title">
应付{{ coin }}<span class="count">{{ count }}</span
>
</div>
<VueQr
class="qr-code"
:text="locationUrl"
:size="220"
:size="180"
:callback="vueQrCb"
/>
<div v-if="isPayment" class="tip">
<div>使用{{ coin }}钱包扫一扫扫描二维码支付</div>
<div>下载链接:{{ downloadUrl }}</div>
</div>
<div>
<a class="btn-save" download="存证二维码.png" :href="dataUrl"
>保存二维码</a
>
<a class="btn-save" download="二维码.png" :href="dataUrl">保存二维码</a>
</div>
</div>
</div>
......@@ -28,7 +34,20 @@ import { Component, Prop, Vue } from 'vue-property-decorator';
},
})
export default class ViewCode extends Vue {
@Prop() locationUrl!: string;
@Prop() private locationUrl!: string;
@Prop() private isPayment!: boolean;
@Prop() private coin!: string;
@Prop() private downloadUrl!: string;
get count() {
try {
const payUrl = JSON.parse(this.locationUrl);
const amount = payUrl.amount;
return amount;
} catch (err) {
return '--';
}
}
private dataUrl = '';
......@@ -46,8 +65,8 @@ export default class ViewCode extends Vue {
background: #333648;
display: flex;
justify-content: center;
padding-top: 52px;
.container {
margin-top: 52px;
text-align: center;
width: 332px;
height: 408px;
......@@ -55,12 +74,29 @@ export default class ViewCode extends Vue {
box-shadow: 0px 2px 10px 0px rgba(0, 0, 0, 0.09);
border-radius: 5px;
border-radius: 10px;
.title {
margin-top: 37px;
margin-bottom: 13px;
font-size: 16px;
font-family: PingFangSC-Medium, PingFang SC;
font-weight: 500;
color: #1f292d;
.count {
color: #ff1818;
}
}
.qr-code {
margin-top: 45px;
margin-bottom: 33px;
}
.tip {
font-size: 12px;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #929292;
line-height: 20px;
}
.btn-save {
display: inline-block;
margin-top: 28px;
width: 200px;
height: 40px;
background: linear-gradient(180deg, #4667fa 0%, #5b77f4 100%);
......
......@@ -19,7 +19,7 @@
v-model="videoBase64"
:rules="[{ required: true, message: '请填上传视频' }]" class="videoInput margintop10">
<template #input>
<input type="file" accept="video/*" id="video" @change="handleFileChange" style="display:none;">
<input type="file" accept="video/*" id="video" capture="camcorder" @change="handleFileChange" style="display:none;">
<label for="video" v-if="!videoBase64" style="width:100%;padding: 30px;text-align:center" class="add-video">
<common-svg name="shipin1" width="34px" height="34px"></common-svg>
<div style="color:#3F79FE;font-size:16px;line-height:1.5em;">添加视频</div>
......
......@@ -22,23 +22,25 @@
</section>
<section class="method">
<p class="title">选择支付方式</p>
<van-radio-group v-model="method">
<van-radio-group v-model="selectedMethodId">
<van-cell
v-for="(item, key) in payMethods"
:key="key"
:title="item.title"
@click="method = item.method"
@click="handleClickPayMethod(item)"
center clickable>
<template #icon>
<common-svg :name="item.icon" style="margin-right:10px;"></common-svg>
<img :src="item.s_image_url" style="height:20px">
<div style="flex-grow: 1">
</div>
</template>
<template #right-icon>
<van-radio :name="item.method" />
<van-radio :name="item.id" />
</template>
</van-cell>
</van-radio-group>
</section>
<div @click="recharge" class="slc-btn-common btn">充值</div>
<div @click="recharge" class="slc-btn-common btn btn-recharge">充值</div>
<section style="display:flex;align-items:center;justify-content:center;color:#3F79FE;font-size:12px;margin-top:15px;">
<router-link tag="span" to="/rechargeRecord">充值记录</router-link>
<router-link to="/contect" tag="span" style="margin-left:10px;">联系客服</router-link>
......@@ -57,7 +59,8 @@
<div style="font-size: 40px;margin-top:60px;">¥{{selectedPlan.price}}</div>
<div style="color:#B6B7B9;font-size: 16px;">燃料次数:{{selectedPlan.chain_times}}次</div>
<div style="text-align:left;margin-top:42px">
<common-svg :name="payMethods[method].icon" style="margin-right:10px;"></common-svg>{{payMethods[method].title}}
<img :src="selectedMethodImgUrl" alt="">
<!-- <common-svg :name="payMethods[method].icon" style="margin-right:10px;"></common-svg>{{payMethods[method].title}} -->
</div>
<div @click="payHandler" class="slc-btn-common" style="display:inline-block;width:200px;height:40px;line-height:40px;margin-top:12px;">立即充值</div>
</div>
......@@ -79,6 +82,9 @@ import { Component, Prop, Vue } from 'vue-property-decorator';
import { Cell, Form, Field, CellGroup, Button, Image, RadioGroup, Radio, Popup, Dialog } from 'vant';
import { Getter, State } from 'vuex-class';
import { Route } from 'vue-router';
import { EPayMethod } from "./const"
import { IMethod } from "./types"
@Component({
components: {
[Form.name]: Form,
......@@ -94,21 +100,19 @@ import { Route } from 'vue-router';
})
export default class Recharge extends Vue {
@State('userInfo') private userInfo!: any;
private redirectUrl: string = '';
@Prop()
private isCallback!: boolean;
private readonly payMethods: any = {
0: {
title: '支付宝',
icon: 'gerenzhongxin-zhifubaozhifu',
method: 0,
},
1: {
title: '微信',
icon: 'gerenzhongxin-weixinzhifu2',
method: 1,
},
};
// private payMethods: any = {
// 0: {
// title: '支付宝',
// icon: 'gerenzhongxin-zhifubaozhifu',
// method: 0,
// },
// 1: {
// title: '微信',
// icon: 'gerenzhongxin-weixinzhifu2',
// method: 1,
// },
// };
private payMethods: IMethod[] = [];
private planList: any[] = [];
private selectedPlan: any = {
planId: -1,
......@@ -116,6 +120,27 @@ export default class Recharge extends Vue {
chain_times: 0,
};
private method: number = 0;
private selectedMethodId: null | number = null;
private getSelectedPayMethod(){
return this.payMethods.find((item: any) => item.id === this.selectedMethodId) as any
}
get selectedMethodImgUrl(){
if(this.selectedMethodId !== null){
return (this.getSelectedPayMethod()).s_image_url;
}
return "";
}
get getSelectedPayMethodType(): EPayMethod{
const selectedPayMethod = this.getSelectedPayMethod();
if(selectedPayMethod){
return selectedPayMethod.type;
}else{
throw new Error("没有选中方法")
}
}
private orderId: string = '';
......@@ -130,9 +155,19 @@ export default class Recharge extends Vue {
chain_times,
};
});
this.$api.order.payMethods().then((ret: any) => {
const methods = ret.pay_methods || [];
this.payMethods = methods;
this.selectedMethodId = methods[0].id;
})
}
private handleClickPayMethod(method: any){
this.selectedMethodId = method.id;
}
private beforeRouteLeave(to: Route, from: Route, next: (params?: any) => void) {
if (!this.confirm) { return next(); }
if (!this.confirm || to.name === "ViewCode") { return next(); }
this.$dialog.confirm({
title: '提示',
message: '点击“返回”将中断操作,确定返回?',
......@@ -145,64 +180,38 @@ export default class Recharge extends Vue {
});
}
private async recharge() {
try {
const { id } = await this.$api.order.add(this.selectedPlan.id, this.method);
this.confirm = true;
this.orderId = id;
} catch (err) {
if (err.code === 10603) {
this.$dialog.confirm({
title: '提示',
message: '您的账户还很充足请剩余少量余额时进行充值',
confirmButtonText: '确定',
cancelButtonText: '取消',
});
}
}
const { id } = await this.$api.order.add(this.selectedPlan.id);
this.confirm = true;
this.orderId = id;
}
private async payHandler() {
const { protocol, host } = location;
const { pay_url } = await this.$api.order.pay(this.orderId, this.method);
localStorage.setItem('orderId', this.orderId);
const redirectUrl = encodeURIComponent(`${protocol}//${host}/#/recharge?isCallback=true`);
this.redirectUrl = this.method === 0 ? pay_url : `${pay_url}&redirect_url=${redirectUrl}`;
console.log(this.redirectUrl);
localStorage.setItem('payUrl', this.redirectUrl);
// location.href = this.redirectUrl;
// (window as any).appslc.toPay(this.redirectUrl);
}
private async confrimPayed() {
const { protocol, host } = location;
this.orderId = String(localStorage.getItem('orderId'));
this.redirectUrl = String(localStorage.getItem('payUrl'));
if (!this.orderId || !this.redirectUrl) {
return this.redirectToRecharge();
}
const { status } = await this.$api.order.get(this.orderId);
if (status === 2) { // 0:未支付 1:支付中 2:支付成功 3:支付失败
this.$router.replace({name: 'RechargeSuccess'});
} else {
this.$dialog.confirm({
title: '提示',
message: '您当前还没有完成付款,请点击[继续付款]进行支付',
confirmButtonText: '继续付款',
cancelButtonText: '取消',
}).then(() => {
location.href = this.redirectUrl;
}).catch((err) => {
this.$router.push({path: '/userCenter/index'});
});
const params:any = {};
if(this.getSelectedPayMethodType === EPayMethod.biqianbaopay) params.coin = this.getSelectedPayMethod().coin;
const { pay_url } = await this.$api.order.pay(this.orderId, this.getSelectedPayMethodType, params);
const redirectUrl = encodeURIComponent(`${protocol}//${host}/#/rechargeSuccess`);
if(this.getSelectedPayMethodType === EPayMethod.biqianbaopay){
// 币钱包 需要展示二维码
const method = this.payMethods.find((method: any)=> method.id === this.selectedMethodId) as IMethod;
const coin = method.coin;
const downloadUrl = method.download_url;
this.$router.push({
name: 'ViewCode',
query: {
locationUrl: pay_url,
payment: JSON.stringify(true),
coin,
downloadUrl
}
})
}else{
// 支付宝和微信支付走👇流程
location.href = this.getSelectedPayMethodType === EPayMethod.alipay ? pay_url : `${pay_url}&redirect_url=${redirectUrl}`;
}
}
private redirectToRecharge() {
localStorage.setItem('orderId', '');
localStorage.setItem('payUrl', '');
this.$router.replace({name: 'Recharge'});
}
private rePay() {
this.redirectToRecharge();
}
}
</script>
<style scoped lang="scss">
......@@ -260,6 +269,9 @@ export default class Recharge extends Vue {
font-weight: 500;
}
}
.btn-recharge{
margin-top: 30px;
}
.btn{
width: 200px;
height: 40px;
......
export enum EPayMethod {
alipay = 0,
weixinpay = 1,
biqianbaopay = 2,
}
export interface IMethod {
coin: string;
download_url: string;
[props: string]: any;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment