|
@@ -12,40 +12,64 @@
|
|
>
|
|
>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
- <!-- <div class="wepay">
|
|
|
|
- <h5>微信支付</h5>
|
|
|
|
- <div class="flex center middle">
|
|
|
|
- <div class="mr-20">
|
|
|
|
- <img class="wepay-qrcode" :src="payQRCode" />
|
|
|
|
- <div class="wepay-text">
|
|
|
|
- <div>请使用微信扫描</div>
|
|
|
|
- <div>二维码完成支付</div>
|
|
|
|
- </div>
|
|
|
|
|
|
+ <div class="code-panel">
|
|
|
|
+ <div>
|
|
|
|
+ <t-radio
|
|
|
|
+ :checked="payType === 0"
|
|
|
|
+ :disabled="user.amount < props.order.amount"
|
|
|
|
+ @click="
|
|
|
|
+ payType = 0;
|
|
|
|
+ hideQrPay();
|
|
|
|
+ "
|
|
|
|
+ >
|
|
|
|
+ <h5>余额支付</h5>
|
|
|
|
+ </t-radio>
|
|
|
|
+ <div class="pl-3 mt-3 ml-3">
|
|
|
|
+ 当前余额:<span class="bland">¥ {{ user.amount }} 元</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
- </div> -->
|
|
|
|
- <div class="code">
|
|
|
|
- <h4 style="color:#171b27;">扫码支付</h4>
|
|
|
|
- <div class="flex">
|
|
|
|
- <div>
|
|
|
|
- <img class="qrcode" :src="payQRCode.wepay" />
|
|
|
|
- <div class="text-center">
|
|
|
|
- <img src="/img/wepay.png" />
|
|
|
|
|
|
+
|
|
|
|
+ <div class="mt-5">
|
|
|
|
+ <t-radio
|
|
|
|
+ :checked="payType === 1"
|
|
|
|
+ @click="
|
|
|
|
+ payType = 1;
|
|
|
|
+ showQrPay();
|
|
|
|
+ "
|
|
|
|
+ >
|
|
|
|
+ <h5>扫码支付</h5>
|
|
|
|
+ </t-radio>
|
|
|
|
+ <div class="flex pl-3 ml-3" v-show="payType === 1">
|
|
|
|
+ <div class="code">
|
|
|
|
+ <img class="qrcode" :src="payQRCode.wepay" />
|
|
|
|
+ <div class="icon">
|
|
|
|
+ <img src="/img/wepay.png" />
|
|
|
|
+ </div>
|
|
</div>
|
|
</div>
|
|
- </div>
|
|
|
|
- <div>
|
|
|
|
- <iframe
|
|
|
|
- :src="payQRCode.alipay"
|
|
|
|
- frameborder="no"
|
|
|
|
- scrolling="no"
|
|
|
|
- allowtransparency="true"
|
|
|
|
- />
|
|
|
|
- <div class="text-center">
|
|
|
|
- <img src="/img/alipay.png" />
|
|
|
|
|
|
+ <div class="code">
|
|
|
|
+ <div class="qrcode">
|
|
|
|
+ <iframe
|
|
|
|
+ :src="payQRCode.alipay"
|
|
|
|
+ frameborder="no"
|
|
|
|
+ scrolling="no"
|
|
|
|
+ allowtransparency="true"
|
|
|
|
+ />
|
|
|
|
+ </div>
|
|
|
|
+ <div class="icon">
|
|
|
|
+ <img src="/img/alipay.png" />
|
|
|
|
+ </div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
- <div class="mt-3" style="color:#171b27;">【注意】不支持退款</div>
|
|
|
|
|
|
+
|
|
|
|
+ <div class="mt-5 bland">【注意】不支持退款</div>
|
|
|
|
+ </div>
|
|
|
|
+ <div style="padding: 20px"></div>
|
|
|
|
+ <div class="buttons">
|
|
|
|
+ <t-button v-if="payType === 0" @click="payByAmount" :loading="payLoading">
|
|
|
|
+ 确认支付
|
|
|
|
+ </t-button>
|
|
|
|
+ <t-button v-if="payType === 1" @click="getPayResult"> 支付完成 </t-button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
</template>
|
|
@@ -54,6 +78,7 @@
|
|
import { onBeforeMount, onUnmounted, ref } from 'vue';
|
|
import { onBeforeMount, onUnmounted, ref } from 'vue';
|
|
import axios from 'axios';
|
|
import axios from 'axios';
|
|
import QRCode from 'qrcode';
|
|
import QRCode from 'qrcode';
|
|
|
|
+import { useUser } from '@/services/user';
|
|
|
|
|
|
const props = defineProps<{
|
|
const props = defineProps<{
|
|
order: any;
|
|
order: any;
|
|
@@ -63,26 +88,45 @@ const props = defineProps<{
|
|
|
|
|
|
const emit = defineEmits(['success']);
|
|
const emit = defineEmits(['success']);
|
|
|
|
|
|
-const payType = ref('wechat');
|
|
|
|
|
|
+const { user, getUser } = useUser();
|
|
|
|
+
|
|
|
|
+const payType = ref(0);
|
|
|
|
|
|
const payQRCode = ref<any>({});
|
|
const payQRCode = ref<any>({});
|
|
|
|
|
|
|
|
+const payLoading = ref(false);
|
|
|
|
+
|
|
let timer: any;
|
|
let timer: any;
|
|
|
|
|
|
onBeforeMount(async () => {
|
|
onBeforeMount(async () => {
|
|
|
|
+ if (user.amount >= props.order.amount) {
|
|
|
|
+ payType.value = 0;
|
|
|
|
+ } else {
|
|
|
|
+ payType.value = 1;
|
|
|
|
+ }
|
|
payQRCode.value.alipay = props.alipayUrl;
|
|
payQRCode.value.alipay = props.alipayUrl;
|
|
|
|
|
|
payQRCode.value.wepay = await QRCode.toDataURL(props.codeUrl, {
|
|
payQRCode.value.wepay = await QRCode.toDataURL(props.codeUrl, {
|
|
margin: 0,
|
|
margin: 0,
|
|
});
|
|
});
|
|
|
|
+ if (payType.value === 1) {
|
|
|
|
+ showQrPay();
|
|
|
|
+ }
|
|
|
|
+});
|
|
|
|
+
|
|
|
|
+const hideQrPay = () => {
|
|
|
|
+ clearInterval(timer);
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+const showQrPay = async () => {
|
|
|
|
+ clearInterval(timer);
|
|
timer = setInterval(async () => {
|
|
timer = setInterval(async () => {
|
|
const success = await getPayResult();
|
|
const success = await getPayResult();
|
|
if (success) {
|
|
if (success) {
|
|
clearInterval(timer);
|
|
clearInterval(timer);
|
|
- emit('success', success);
|
|
|
|
}
|
|
}
|
|
}, 5000);
|
|
}, 5000);
|
|
-});
|
|
|
|
|
|
+};
|
|
|
|
|
|
onUnmounted(() => {
|
|
onUnmounted(() => {
|
|
clearInterval(timer);
|
|
clearInterval(timer);
|
|
@@ -92,10 +136,22 @@ const getPayResult = async () => {
|
|
const result: { state: number } = await axios.post('/api/order/pay/state', {
|
|
const result: { state: number } = await axios.post('/api/order/pay/state', {
|
|
id: props.order.id || props.order._id,
|
|
id: props.order.id || props.order._id,
|
|
});
|
|
});
|
|
- if (result && result.state) {
|
|
|
|
|
|
+ if (result && result.state === 8) {
|
|
|
|
+ emit('success', true);
|
|
return true;
|
|
return true;
|
|
}
|
|
}
|
|
};
|
|
};
|
|
|
|
+
|
|
|
|
+const payByAmount = async () => {
|
|
|
|
+ payLoading.value = true;
|
|
|
|
+ const result: any = await axios.post('/api/order/pay/by/amount', {
|
|
|
|
+ id: props.order.id,
|
|
|
|
+ });
|
|
|
|
+ payLoading.value = false;
|
|
|
|
+ if (result) {
|
|
|
|
+ emit('success', true);
|
|
|
|
+ }
|
|
|
|
+};
|
|
</script>
|
|
</script>
|
|
|
|
|
|
<style lang="postcss" scoped>
|
|
<style lang="postcss" scoped>
|
|
@@ -127,36 +183,65 @@ const getPayResult = async () => {
|
|
color: #ffffff;
|
|
color: #ffffff;
|
|
font-size: 13px;
|
|
font-size: 13px;
|
|
} */
|
|
} */
|
|
- .code {
|
|
|
|
|
|
+ .code-panel {
|
|
padding: 30px 40px;
|
|
padding: 30px 40px;
|
|
- color: var(--color-title);
|
|
|
|
|
|
+ color: #171b27;
|
|
background: #f7f8fa;
|
|
background: #f7f8fa;
|
|
margin-top: 8px;
|
|
margin-top: 8px;
|
|
- }
|
|
|
|
|
|
|
|
- .flex > div {
|
|
|
|
- flex: 1;
|
|
|
|
- margin-top: 8px;
|
|
|
|
- .text-center {
|
|
|
|
- width: 150px;
|
|
|
|
- text-align: center;
|
|
|
|
- & > img {
|
|
|
|
- height: 30px;
|
|
|
|
- margin: 8px auto;
|
|
|
|
|
|
+ .flex > div {
|
|
|
|
+ flex: 1;
|
|
|
|
+ .icon {
|
|
|
|
+ width: 100px;
|
|
|
|
+ text-align: center;
|
|
|
|
+ & > img {
|
|
|
|
+ height: 28px;
|
|
|
|
+ margin: 8px auto;
|
|
|
|
+ }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ .code {
|
|
|
|
+ height: 150px;
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
.qrcode {
|
|
.qrcode {
|
|
- width: 150px;
|
|
|
|
- margin-top: 20px;
|
|
|
|
|
|
+ width: 100px;
|
|
|
|
+ height: 100px;
|
|
|
|
+ margin-top: 16px;
|
|
}
|
|
}
|
|
|
|
|
|
iframe {
|
|
iframe {
|
|
width: 160px;
|
|
width: 160px;
|
|
height: 160px;
|
|
height: 160px;
|
|
- margin-top: 16px;
|
|
|
|
- transform: scale(0.9375);
|
|
|
|
|
|
+ /* margin-top: 16px; */
|
|
|
|
+ transform: scale(0.625);
|
|
|
|
+ transform-origin: 0 0;
|
|
|
|
+ }
|
|
|
|
+ .buttons {
|
|
|
|
+ position: absolute;
|
|
|
|
+ bottom: 32px;
|
|
|
|
+ right: 32px;
|
|
|
|
+ }
|
|
|
|
+ .pl-3{
|
|
|
|
+ padding-left: 0.75rem;
|
|
|
|
+ }
|
|
|
|
+ .mt-3{
|
|
|
|
+ margin-top: 0.75rem;
|
|
|
|
+ }
|
|
|
|
+ .ml-3{
|
|
|
|
+ margin-left: 0.75rem;
|
|
|
|
+ }
|
|
|
|
+ .mt-5{
|
|
|
|
+ margin-top: 1.25rem;
|
|
|
|
+ }
|
|
|
|
+ :deep(.t-radio__label){
|
|
|
|
+ color: #171b27;
|
|
|
|
+ }
|
|
|
|
+ :deep(.t-radio__input){
|
|
|
|
+ background-color: #fff0 !important;
|
|
}
|
|
}
|
|
|
|
+
|
|
}
|
|
}
|
|
</style>
|
|
</style>
|