项目初始化
This commit is contained in:
295
pages/pay/index.vue
Normal file
295
pages/pay/index.vue
Normal file
@@ -0,0 +1,295 @@
|
||||
<!-- 收银台 -->
|
||||
<template>
|
||||
<s-layout title="收银台">
|
||||
<view class="bg-white ss-modal-box ss-flex-col">
|
||||
<!-- 订单信息 -->
|
||||
<view class="modal-header ss-flex-col ss-col-center ss-row-center">
|
||||
<view class="money-box ss-m-b-20">
|
||||
<text class="money-text">{{ fen2yuan(state.orderInfo.price) }}</text>
|
||||
</view>
|
||||
<view class="time-text">
|
||||
<text>{{ payDescText }}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 支付方式 -->
|
||||
<view class="modal-content ss-flex-1">
|
||||
<view class="pay-title ss-p-l-30 ss-m-y-30">选择支付方式</view>
|
||||
<radio-group @change="onTapPay">
|
||||
<label class="pay-type-item" v-for="item in state.payMethods" :key="item.title">
|
||||
<view
|
||||
v-if="!item.disabled"
|
||||
class="pay-item ss-flex ss-col-center ss-row-between ss-p-x-30 border-bottom"
|
||||
:class="{ 'disabled-pay-item': item.disabled }"
|
||||
>
|
||||
<view class="ss-flex ss-col-center">
|
||||
<image
|
||||
class="pay-icon"
|
||||
v-if="item.disabled"
|
||||
:src="sheep.$url.static('/static/img/shop/pay/cod_disabled.png')"
|
||||
mode="aspectFit"
|
||||
/>
|
||||
<image
|
||||
class="pay-icon"
|
||||
v-else
|
||||
:src="sheep.$url.static(item.icon)"
|
||||
mode="aspectFit"
|
||||
/>
|
||||
<text class="pay-title">{{ item.title }}</text>
|
||||
</view>
|
||||
<view class="check-box ss-flex ss-col-center ss-p-l-10">
|
||||
<view class="userInfo-money ss-m-r-10" v-if="item.value === 'wallet'">
|
||||
余额: {{ fen2yuan(userWallet.balance) }}元
|
||||
</view>
|
||||
<radio
|
||||
:value="item.value"
|
||||
color="var(--ui-BG-Main)"
|
||||
style="transform: scale(0.8)"
|
||||
:disabled="item.disabled"
|
||||
:checked="state.payment === item.value"
|
||||
/>
|
||||
</view>
|
||||
</view>
|
||||
</label>
|
||||
</radio-group>
|
||||
</view>
|
||||
|
||||
<!-- 工具 -->
|
||||
<view class="modal-footer ss-flex ss-row-center ss-col-center ss-m-t-80 ss-m-b-40">
|
||||
<button v-if="state.payStatus === 0" class="ss-reset-button past-due-btn">
|
||||
检测支付环境中
|
||||
</button>
|
||||
<button v-else-if="state.payStatus === -1" class="ss-reset-button past-due-btn" disabled>
|
||||
支付已过期
|
||||
</button>
|
||||
<button
|
||||
v-else
|
||||
class="ss-reset-button save-btn"
|
||||
@tap="onPay"
|
||||
:disabled="state.payStatus !== 1"
|
||||
:class="{ 'disabled-btn': state.payStatus !== 1 }"
|
||||
>
|
||||
立即支付
|
||||
</button>
|
||||
</view>
|
||||
</view>
|
||||
</s-layout>
|
||||
</template>
|
||||
<script setup>
|
||||
import { computed, reactive } from 'vue';
|
||||
import { onLoad } from '@dcloudio/uni-app';
|
||||
import sheep from '@/sheep';
|
||||
import { fen2yuan, useDurationTime } from '@/sheep/hooks/useGoods';
|
||||
import PayOrderApi from '@/sheep/api/pay/order';
|
||||
import PayChannelApi from '@/sheep/api/pay/channel';
|
||||
import { getPayMethods } from '@/sheep/platform/pay';
|
||||
|
||||
const userWallet = computed(() => sheep.$store('user').userWallet);
|
||||
|
||||
// 检测支付环境
|
||||
const state = reactive({
|
||||
orderType: 'goods', // 订单类型; goods - 商品订单, recharge - 充值订单
|
||||
orderInfo: {}, // 支付单信息
|
||||
payStatus: 0, // 0=检测支付环境, -2=未查询到支付单信息, -1=支付已过期, 1=待支付,2=订单已支付
|
||||
payMethods: [], // 可选的支付方式
|
||||
payment: '', // 选中的支付方式
|
||||
});
|
||||
|
||||
const onPay = () => {
|
||||
if (state.payment === '') {
|
||||
sheep.$helper.toast('请选择支付方式');
|
||||
return;
|
||||
}
|
||||
if (state.payment === 'wallet') {
|
||||
uni.showModal({
|
||||
title: '提示',
|
||||
content: '确定要支付吗?',
|
||||
success: function (res) {
|
||||
if (res.confirm) {
|
||||
sheep.$platform.pay(state.payment, state.orderType, state.orderInfo.id);
|
||||
}
|
||||
},
|
||||
});
|
||||
} else {
|
||||
sheep.$platform.pay(state.payment, state.orderType, state.orderInfo.id);
|
||||
}
|
||||
};
|
||||
|
||||
// 支付文案提示
|
||||
const payDescText = computed(() => {
|
||||
if (state.payStatus === 2) {
|
||||
return '该订单已支付';
|
||||
}
|
||||
if (state.payStatus === 1) {
|
||||
const time = useDurationTime(state.orderInfo.expireTime);
|
||||
if (time.ms <= 0) {
|
||||
state.payStatus = -1;
|
||||
return '';
|
||||
}
|
||||
return `剩余支付时间 ${time.h}:${time.m}:${time.s} `;
|
||||
}
|
||||
if (state.payStatus === -2) {
|
||||
return '未查询到支付单信息';
|
||||
}
|
||||
return '';
|
||||
});
|
||||
|
||||
// 状态转换:payOrder.status => payStatus
|
||||
function checkPayStatus() {
|
||||
if (state.orderInfo.status === 10
|
||||
|| state.orderInfo.status === 20 ) { // 支付成功
|
||||
state.payStatus = 2;
|
||||
return;
|
||||
}
|
||||
if (state.orderInfo.status === 30) { // 支付关闭
|
||||
state.payStatus = -1;
|
||||
return;
|
||||
}
|
||||
state.payStatus = 1; // 待支付
|
||||
}
|
||||
|
||||
// 切换支付方式
|
||||
function onTapPay(e) {
|
||||
state.payment = e.detail.value;
|
||||
}
|
||||
|
||||
// 设置支付订单信息
|
||||
async function setOrder(id) {
|
||||
// 获得支付订单信息
|
||||
const { data, code } = await PayOrderApi.getOrder(id);
|
||||
if (code !== 0 || !data) {
|
||||
state.payStatus = -2;
|
||||
return;
|
||||
}
|
||||
state.orderInfo = data;
|
||||
// 获得支付方式
|
||||
await setPayMethods();
|
||||
// 设置支付状态
|
||||
checkPayStatus();
|
||||
}
|
||||
|
||||
// 获得支付方式
|
||||
async function setPayMethods() {
|
||||
const { data, code } = await PayChannelApi.getEnableChannelCodeList(state.orderInfo.appId)
|
||||
if (code !== 0) {
|
||||
return
|
||||
}
|
||||
state.payMethods = getPayMethods(data)
|
||||
state.payMethods.find(item => {
|
||||
if (item.value && !item.disabled) {
|
||||
state.payment = item.value;
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
onLoad((options) => {
|
||||
if (sheep.$platform.name === 'WechatOfficialAccount'
|
||||
&& sheep.$platform.os === 'ios'
|
||||
&& !sheep.$platform.landingPage.includes('pages/pay/index')) {
|
||||
location.reload();
|
||||
return;
|
||||
}
|
||||
// 获得支付订单信息
|
||||
let id = options.id;
|
||||
if (options.orderType) {
|
||||
state.orderType = options.orderType;
|
||||
}
|
||||
setOrder(id);
|
||||
// 刷新钱包的缓存
|
||||
sheep.$store('user').getWallet();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.pay-icon {
|
||||
width: 36rpx;
|
||||
height: 36rpx;
|
||||
margin-right: 26rpx;
|
||||
}
|
||||
|
||||
.ss-modal-box {
|
||||
// max-height: 1000rpx;
|
||||
|
||||
.modal-header {
|
||||
position: relative;
|
||||
padding: 60rpx 20rpx 40rpx;
|
||||
|
||||
|
||||
.money-text {
|
||||
color: $red;
|
||||
font-size: 46rpx;
|
||||
font-weight: bold;
|
||||
font-family: OPPOSANS;
|
||||
|
||||
&::before {
|
||||
content: '¥';
|
||||
font-size: 30rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.time-text {
|
||||
font-size: 26rpx;
|
||||
color: $gray-b;
|
||||
}
|
||||
|
||||
.close-icon {
|
||||
position: absolute;
|
||||
top: 10rpx;
|
||||
right: 20rpx;
|
||||
font-size: 46rpx;
|
||||
opacity: 0.2;
|
||||
}
|
||||
}
|
||||
|
||||
.modal-content {
|
||||
overflow-y: auto;
|
||||
|
||||
.pay-title {
|
||||
font-size: 26rpx;
|
||||
font-weight: 500;
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
.pay-tip {
|
||||
font-size: 26rpx;
|
||||
color: #bbbbbb;
|
||||
}
|
||||
|
||||
.pay-item {
|
||||
height: 86rpx;
|
||||
}
|
||||
.disabled-pay-item {
|
||||
.pay-title {
|
||||
color: #999999;
|
||||
}
|
||||
}
|
||||
|
||||
.userInfo-money {
|
||||
font-size: 26rpx;
|
||||
color: #bbbbbb;
|
||||
line-height: normal;
|
||||
}
|
||||
}
|
||||
|
||||
.save-btn {
|
||||
width: 710rpx;
|
||||
height: 80rpx;
|
||||
border-radius: 40rpx;
|
||||
background: linear-gradient(90deg, var(--ui-BG-Main), var(--ui-BG-Main-gradient));
|
||||
color: $white;
|
||||
}
|
||||
.disabled-btn {
|
||||
background: #e5e5e5;
|
||||
color: #999999;
|
||||
}
|
||||
|
||||
.past-due-btn {
|
||||
width: 710rpx;
|
||||
height: 80rpx;
|
||||
border-radius: 40rpx;
|
||||
background-color: #999;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
</style>
|
308
pages/pay/point/index.vue
Normal file
308
pages/pay/point/index.vue
Normal file
@@ -0,0 +1,308 @@
|
||||
<!-- 收银台 -->
|
||||
<template>
|
||||
<s-layout title="收银台">
|
||||
<view class="bg-white ss-modal-box ss-flex-col">
|
||||
<!-- 订单信息 -->
|
||||
<view class="modal-header ss-flex-col ss-col-center ss-row-center">
|
||||
<view class="money-box ss-m-b-20">
|
||||
<text class="money-text">{{ fen2yuan(state.orderInfo.price) }}</text>
|
||||
</view>
|
||||
<view class="time-text">
|
||||
<text>{{ payDescText }}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 支付方式 -->
|
||||
<view class="modal-content ss-flex-1">
|
||||
<view class="pay-title ss-p-l-30 ss-m-y-30">选择支付方式</view>
|
||||
<radio-group @change="onTapPay">
|
||||
<label class="pay-type-item" v-for="item in state.payMethods" :key="item.title">
|
||||
<view
|
||||
v-if="!item.disabled"
|
||||
class="pay-item ss-flex ss-col-center ss-row-between ss-p-x-30 border-bottom"
|
||||
:class="{ 'disabled-pay-item': item.disabled }"
|
||||
>
|
||||
<view class="ss-flex ss-col-center">
|
||||
<image
|
||||
class="pay-icon"
|
||||
v-if="item.disabled"
|
||||
:src="sheep.$url.static('/static/img/shop/pay/cod_disabled.png')"
|
||||
mode="aspectFit"
|
||||
/>
|
||||
<image
|
||||
class="pay-icon"
|
||||
v-else
|
||||
:src="sheep.$url.static(item.icon)"
|
||||
mode="aspectFit"
|
||||
/>
|
||||
<text class="pay-title">{{ item.title }}</text>
|
||||
</view>
|
||||
<view class="check-box ss-flex ss-col-center ss-p-l-10">
|
||||
<view class="userInfo-money ss-m-r-10" v-if="item.value === 'wallet'">
|
||||
余额: {{ fen2yuan(userWallet.balance) }}元
|
||||
</view>
|
||||
<radio
|
||||
:value="item.value"
|
||||
color="var(--ui-BG-Main)"
|
||||
style="transform: scale(0.8)"
|
||||
:disabled="item.disabled"
|
||||
:checked="state.payment === item.value"
|
||||
/>
|
||||
</view>
|
||||
</view>
|
||||
</label>
|
||||
</radio-group>
|
||||
</view>
|
||||
|
||||
<!-- 工具 -->
|
||||
<view class="modal-footer ss-flex ss-row-center ss-col-center ss-m-t-80 ss-m-b-40">
|
||||
<button v-if="state.payStatus === 0" class="ss-reset-button past-due-btn">
|
||||
检测支付环境中
|
||||
</button>
|
||||
<button v-else-if="state.payStatus === -1" class="ss-reset-button past-due-btn" disabled>
|
||||
支付已过期
|
||||
</button>
|
||||
<button
|
||||
v-else
|
||||
class="ss-reset-button save-btn"
|
||||
@tap="onPay"
|
||||
:disabled="state.payStatus !== 1"
|
||||
:class="{ 'disabled-btn': state.payStatus !== 1 }"
|
||||
>
|
||||
立即支付
|
||||
</button>
|
||||
</view>
|
||||
</view>
|
||||
</s-layout>
|
||||
</template>
|
||||
<script setup>
|
||||
import { computed, reactive } from 'vue';
|
||||
import { onLoad } from '@dcloudio/uni-app';
|
||||
import sheep from '@/sheep';
|
||||
import { fen2yuan, useDurationTime } from '@/sheep/hooks/useGoods';
|
||||
import PayOrderApi from '@/sheep/api/pay/order';
|
||||
import PayChannelApi from '@/sheep/api/pay/channel';
|
||||
import { getPayMethods } from '@/sheep/platform/pay';
|
||||
|
||||
const userWallet = computed(() => sheep.$store('user').userWallet);
|
||||
|
||||
// 检测支付环境
|
||||
const state = reactive({
|
||||
orderType: 'goods', // 订单类型; goods - 商品订单, recharge - 充值订单
|
||||
orderInfo: {}, // 支付单信息
|
||||
payStatus: 0, // 0=检测支付环境, -2=未查询到支付单信息, -1=支付已过期, 1=待支付,2=订单已支付
|
||||
payMethods: [], // 可选的支付方式
|
||||
payment: '', // 选中的支付方式
|
||||
});
|
||||
|
||||
const onPay = () => {
|
||||
if (state.payment === '') {
|
||||
sheep.$helper.toast('请选择支付方式');
|
||||
return;
|
||||
}
|
||||
if (state.payment === 'wallet') {
|
||||
if(state.orderInfo.price > userWallet.value.balance){
|
||||
uni.showModal({
|
||||
title: '账户余额不足',
|
||||
confirmText: '去充值',
|
||||
success: function (res) {
|
||||
if (res.confirm) {
|
||||
sheep.$router.go('/pages/pay/recharge');
|
||||
}
|
||||
},
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
uni.showModal({
|
||||
title: '提示',
|
||||
content: '确定要支付吗?',
|
||||
success: function (res) {
|
||||
if (res.confirm) {
|
||||
sheep.$platform.pay(state.payment, state.orderType, state.orderInfo.id, 'point');
|
||||
}
|
||||
},
|
||||
});
|
||||
} else {
|
||||
sheep.$platform.pay(state.payment, state.orderType, state.orderInfo.id, 'point');
|
||||
}
|
||||
};
|
||||
|
||||
// 支付文案提示
|
||||
const payDescText = computed(() => {
|
||||
if (state.payStatus === 2) {
|
||||
return '该订单已支付';
|
||||
}
|
||||
if (state.payStatus === 1) {
|
||||
const time = useDurationTime(state.orderInfo.expireTime);
|
||||
if (time.ms <= 0) {
|
||||
state.payStatus = -1;
|
||||
return '';
|
||||
}
|
||||
return `剩余支付时间 ${time.h}:${time.m}:${time.s} `;
|
||||
}
|
||||
if (state.payStatus === -2) {
|
||||
return '未查询到支付单信息';
|
||||
}
|
||||
return '';
|
||||
});
|
||||
|
||||
// 状态转换:payOrder.status => payStatus
|
||||
function checkPayStatus() {
|
||||
if (state.orderInfo.status === 10
|
||||
|| state.orderInfo.status === 20 ) { // 支付成功
|
||||
state.payStatus = 2;
|
||||
return;
|
||||
}
|
||||
if (state.orderInfo.status === 30) { // 支付关闭
|
||||
state.payStatus = -1;
|
||||
return;
|
||||
}
|
||||
state.payStatus = 1; // 待支付
|
||||
}
|
||||
|
||||
// 切换支付方式
|
||||
function onTapPay(e) {
|
||||
state.payment = e.detail.value;
|
||||
}
|
||||
|
||||
// 设置支付订单信息
|
||||
async function setOrder(id) {
|
||||
// 获得支付订单信息
|
||||
const { data, code } = await PayOrderApi.getOrder(id);
|
||||
if (code !== 0 || !data) {
|
||||
state.payStatus = -2;
|
||||
return;
|
||||
}
|
||||
state.orderInfo = data;
|
||||
// 获得支付方式
|
||||
await setPayMethods();
|
||||
// 设置支付状态
|
||||
checkPayStatus();
|
||||
}
|
||||
|
||||
// 获得支付方式
|
||||
async function setPayMethods() {
|
||||
const { data, code } = await PayChannelApi.getEnableChannelCodeList(state.orderInfo.appId)
|
||||
if (code !== 0) {
|
||||
return
|
||||
}
|
||||
state.payMethods = getPayMethods(data)
|
||||
state.payMethods.find(item => {
|
||||
if (item.value && !item.disabled) {
|
||||
state.payment = item.value;
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
onLoad((options) => {
|
||||
if (sheep.$platform.name === 'WechatOfficialAccount'
|
||||
&& sheep.$platform.os === 'ios'
|
||||
&& !sheep.$platform.landingPage.includes('pages/pay/point/index')) {
|
||||
location.reload();
|
||||
return;
|
||||
}
|
||||
// 获得支付订单信息
|
||||
let id = options.id;
|
||||
if (options.orderType) {
|
||||
state.orderType = options.orderType;
|
||||
}
|
||||
setOrder(id);
|
||||
// 刷新钱包的缓存
|
||||
sheep.$store('user').getWallet();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.pay-icon {
|
||||
width: 36rpx;
|
||||
height: 36rpx;
|
||||
margin-right: 26rpx;
|
||||
}
|
||||
|
||||
.ss-modal-box {
|
||||
// max-height: 1000rpx;
|
||||
|
||||
.modal-header {
|
||||
position: relative;
|
||||
padding: 60rpx 20rpx 40rpx;
|
||||
|
||||
|
||||
.money-text {
|
||||
color: $red;
|
||||
font-size: 46rpx;
|
||||
font-weight: bold;
|
||||
font-family: OPPOSANS;
|
||||
|
||||
&::before {
|
||||
content: '¥';
|
||||
font-size: 30rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.time-text {
|
||||
font-size: 26rpx;
|
||||
color: $gray-b;
|
||||
}
|
||||
|
||||
.close-icon {
|
||||
position: absolute;
|
||||
top: 10rpx;
|
||||
right: 20rpx;
|
||||
font-size: 46rpx;
|
||||
opacity: 0.2;
|
||||
}
|
||||
}
|
||||
|
||||
.modal-content {
|
||||
overflow-y: auto;
|
||||
|
||||
.pay-title {
|
||||
font-size: 26rpx;
|
||||
font-weight: 500;
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
.pay-tip {
|
||||
font-size: 26rpx;
|
||||
color: #bbbbbb;
|
||||
}
|
||||
|
||||
.pay-item {
|
||||
height: 86rpx;
|
||||
}
|
||||
.disabled-pay-item {
|
||||
.pay-title {
|
||||
color: #999999;
|
||||
}
|
||||
}
|
||||
|
||||
.userInfo-money {
|
||||
font-size: 26rpx;
|
||||
color: #bbbbbb;
|
||||
line-height: normal;
|
||||
}
|
||||
}
|
||||
|
||||
.save-btn {
|
||||
width: 710rpx;
|
||||
height: 80rpx;
|
||||
border-radius: 40rpx;
|
||||
background: linear-gradient(90deg, var(--ui-BG-Main), var(--ui-BG-Main-gradient));
|
||||
color: $white;
|
||||
}
|
||||
.disabled-btn {
|
||||
background: #e5e5e5;
|
||||
color: #999999;
|
||||
}
|
||||
|
||||
.past-due-btn {
|
||||
width: 710rpx;
|
||||
height: 80rpx;
|
||||
border-radius: 40rpx;
|
||||
background-color: #999;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
</style>
|
167
pages/pay/recharge-log.vue
Normal file
167
pages/pay/recharge-log.vue
Normal file
@@ -0,0 +1,167 @@
|
||||
<!-- 充值记录 -->
|
||||
<template>
|
||||
<s-layout class="widthdraw-log-wrap" title="充值记录">
|
||||
<!-- 记录卡片 -->
|
||||
<view class="wallet-log-box ss-p-b-30">
|
||||
<view class="log-list" v-for="item in state.pagination.list" :key="item">
|
||||
<view class="head ss-flex ss-col-center ss-row-between">
|
||||
<view class="title">充值钻石</view>
|
||||
<view class="num" :class="item.refundStatus === 10 ? 'danger-color' : 'success-color'">
|
||||
{{ fen2yuan(item.payPrice) }} 钻
|
||||
<text v-if="item.bonusPrice > 0">(赠送 {{ fen2yuan(item.bonusPrice) }} 钻)</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="status-box item ss-flex ss-col-center ss-row-between">
|
||||
<view class="item-title">支付状态</view>
|
||||
<view
|
||||
class="status-text"
|
||||
:class="item.refundStatus === 10 ? 'danger-color' : 'success-color'"
|
||||
>
|
||||
{{ item.refundStatus === 10 ? '已退款' : '已支付' }}
|
||||
</view>
|
||||
</view>
|
||||
<view class="time-box item ss-flex ss-col-center ss-row-between">
|
||||
<text class="item-title">充值渠道</text>
|
||||
<view class="time ss-ellipsis-1">{{ item.payChannelName }}</view>
|
||||
</view>
|
||||
<view class="time-box item ss-flex ss-col-center ss-row-between">
|
||||
<text class="item-title">充值单号</text>
|
||||
<view class="time"> {{ item.payOrderChannelOrderNo }} </view>
|
||||
</view>
|
||||
<view class="time-box item ss-flex ss-col-center ss-row-between">
|
||||
<text class="item-title">充值时间</text>
|
||||
<view class="time">
|
||||
{{ sheep.$helper.timeFormat(item.payTime, 'yyyy-mm-dd hh:MM:ss') }}</view
|
||||
>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<s-empty
|
||||
v-if="state.pagination.total === 0"
|
||||
icon="/static/comment-empty.png"
|
||||
text="暂无充值记录"
|
||||
/>
|
||||
<uni-load-more
|
||||
v-if="state.pagination.total > 0"
|
||||
:status="state.loadStatus"
|
||||
:content-text="{
|
||||
contentdown: '上拉加载更多',
|
||||
}"
|
||||
@tap="loadMore"
|
||||
/>
|
||||
</s-layout>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { reactive } from 'vue';
|
||||
import { onLoad, onReachBottom } from '@dcloudio/uni-app';
|
||||
import _ from 'lodash-es';
|
||||
import PayWalletApi from '@/sheep/api/pay/wallet';
|
||||
import sheep from '@/sheep';
|
||||
import { fen2yuan } from '../../sheep/hooks/useGoods';
|
||||
|
||||
const state = reactive({
|
||||
pagination: {
|
||||
list: [],
|
||||
total: 0,
|
||||
pageNo: 1,
|
||||
pageSize: 5,
|
||||
},
|
||||
loadStatus: '',
|
||||
});
|
||||
|
||||
async function getLogList(page = 1, list_rows = 5) {
|
||||
const { code, data } = await PayWalletApi.getWalletRechargePage({
|
||||
pageNo: page,
|
||||
pageSize: list_rows,
|
||||
});
|
||||
if (code !== 0) {
|
||||
return;
|
||||
}
|
||||
state.pagination.list = _.concat(state.pagination.list, data.list);
|
||||
state.pagination.total = data.total;
|
||||
state.loadStatus = state.pagination.list.length < state.pagination.total ? 'more' : 'noMore';
|
||||
}
|
||||
|
||||
// 加载更多
|
||||
function loadMore() {
|
||||
if (state.loadStatus === 'noMore') {
|
||||
return;
|
||||
}
|
||||
state.pagination.pageNo++;
|
||||
getLogList();
|
||||
}
|
||||
|
||||
onLoad(() => {
|
||||
getLogList();
|
||||
});
|
||||
|
||||
onReachBottom(() => {
|
||||
loadMore();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
// 记录卡片
|
||||
.log-list {
|
||||
min-height: 213rpx;
|
||||
background: $white;
|
||||
margin-bottom: 10rpx;
|
||||
padding-bottom: 10rpx;
|
||||
|
||||
.head {
|
||||
padding: 0 35rpx;
|
||||
height: 80rpx;
|
||||
border-bottom: 1rpx solid $gray-e;
|
||||
margin-bottom: 20rpx;
|
||||
|
||||
.title {
|
||||
font-size: 28rpx;
|
||||
font-weight: 500;
|
||||
color: $dark-3;
|
||||
}
|
||||
|
||||
.num {
|
||||
font-size: 28rpx;
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
|
||||
.item {
|
||||
padding: 0 30rpx 10rpx;
|
||||
|
||||
.item-icon {
|
||||
color: $gray-d;
|
||||
font-size: 36rpx;
|
||||
margin-right: 8rpx;
|
||||
}
|
||||
|
||||
.item-title {
|
||||
width: 180rpx;
|
||||
font-size: 24rpx;
|
||||
font-weight: 400;
|
||||
color: #666666;
|
||||
}
|
||||
|
||||
.status-text {
|
||||
font-size: 24rpx;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.time {
|
||||
font-size: 24rpx;
|
||||
font-weight: 400;
|
||||
color: #c0c0c0;
|
||||
}
|
||||
}
|
||||
}
|
||||
.warning-color {
|
||||
color: #faad14;
|
||||
}
|
||||
.danger-color {
|
||||
color: #ff4d4f;
|
||||
}
|
||||
.success-color {
|
||||
color: #67c23a;
|
||||
}
|
||||
</style>
|
264
pages/pay/recharge.vue
Normal file
264
pages/pay/recharge.vue
Normal file
@@ -0,0 +1,264 @@
|
||||
<!-- 充值界面 -->
|
||||
<template>
|
||||
<s-layout title="充值钻石" class="withdraw-wrap" navbar="inner">
|
||||
<view class="wallet-num-box ss-flex ss-col-center ss-row-between" :style="[
|
||||
{
|
||||
marginTop: '-' + Number(statusBarHeight + 88 + 22) + 'rpx',
|
||||
paddingTop: Number(statusBarHeight + 108 + 22) + 'rpx',
|
||||
},
|
||||
]">
|
||||
<view class="">
|
||||
<view class="num-title">当前钻石(钻)</view>
|
||||
<view class="wallet-num">{{ fen2yuan(userWallet.balance) }}</view>
|
||||
</view>
|
||||
<button class="ss-reset-button log-btn" @tap="sheep.$router.go('/pages/user/wallet/money')">
|
||||
钻石明细
|
||||
</button>
|
||||
</view>
|
||||
<view class="recharge-box">
|
||||
<view class="recharge-card-box">
|
||||
<view class="input-label ss-m-b-50">充值钻石</view>
|
||||
<!-- <view class="input-box ss-flex border-bottom ss-p-b-20">
|
||||
<view class="unit">¥</view>
|
||||
<uni-easyinput v-model="state.recharge_money" type="digit" placeholder="请输入充值金额"
|
||||
:inputBorder="false" />
|
||||
</view> -->
|
||||
<view class="face-value-box ss-flex ss-flex-wrap ss-m-y-40">
|
||||
<button class="ss-reset-button face-value-btn" v-for="item in state.packageList" :key="item.money"
|
||||
:class="[{ 'btn-active': state.recharge_money === fen2yuan(item.payPrice) }]"
|
||||
@tap="onCard(item.payPrice)">
|
||||
<text class="face-value-title">{{ fen2yuan(item.payPrice) }}</text>
|
||||
<view v-if="item.bonusPrice" class="face-value-tag">
|
||||
送 {{ fen2yuan(item.bonusPrice) }} 钻
|
||||
</view>
|
||||
</button>
|
||||
</view>
|
||||
<button class="ss-reset-button save-btn ui-BG-Main-Gradient ss-m-t-60 ui-Shadow-Main" @tap="onConfirm">
|
||||
确认充值
|
||||
</button>
|
||||
</view>
|
||||
</view>
|
||||
</s-layout>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { computed, reactive } from 'vue';
|
||||
import sheep from '@/sheep';
|
||||
import { onLoad } from '@dcloudio/uni-app';
|
||||
import { fen2yuan } from '@/sheep/hooks/useGoods';
|
||||
import PayWalletApi from '@/sheep/api/pay/wallet';
|
||||
import { WxaSubscribeTemplate } from '@/sheep/util/const';
|
||||
|
||||
const userWallet = computed(() => sheep.$store('user').userWallet);
|
||||
const statusBarHeight = sheep.$platform.device.statusBarHeight * 2;
|
||||
const headerBg = sheep.$url.css('/static/img/shop/user/withdraw_bg.png');
|
||||
|
||||
const state = reactive({
|
||||
recharge_money: '', // 输入的充值金额
|
||||
packageList: [],
|
||||
});
|
||||
|
||||
// 点击卡片,选择充值金额
|
||||
function onCard(e) {
|
||||
state.recharge_money = fen2yuan(e);
|
||||
}
|
||||
|
||||
// 获得钱包充值套餐列表
|
||||
async function getRechargeTabs() {
|
||||
const { code, data } = await PayWalletApi.getWalletRechargePackageList();
|
||||
if (code !== 0) {
|
||||
return;
|
||||
}
|
||||
state.packageList = data;
|
||||
}
|
||||
|
||||
// 发起支付
|
||||
async function onConfirm() {
|
||||
if(state.recharge_money == 0){
|
||||
sheep.$helper.toast('请选择充值套餐');
|
||||
return;
|
||||
}
|
||||
const { code, data } = await PayWalletApi.createWalletRecharge({
|
||||
packageId: state.packageList.find((item) => fen2yuan(item.payPrice) === state.recharge_money)?.id,
|
||||
payPrice: state.recharge_money * 100,
|
||||
});
|
||||
if (code !== 0) {
|
||||
return;
|
||||
}
|
||||
// #ifdef MP
|
||||
sheep.$platform.useProvider('wechat').subscribeMessage(WxaSubscribeTemplate.PAY_WALLET_RECHARGER_SUCCESS);
|
||||
// #endif
|
||||
sheep.$router.go('/pages/pay/index', {
|
||||
id: data.payOrderId,
|
||||
orderType: 'recharge',
|
||||
});
|
||||
}
|
||||
|
||||
onLoad(() => {
|
||||
getRechargeTabs();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
:deep() {
|
||||
.uni-input-input {
|
||||
font-family: OPPOSANS !important;
|
||||
}
|
||||
}
|
||||
|
||||
.wallet-num-box {
|
||||
padding: 0 40rpx 80rpx;
|
||||
background: var(--ui-BG-Main) v-bind(headerBg) center/750rpx 100% no-repeat;
|
||||
border-radius: 0 0 5% 5%;
|
||||
|
||||
.num-title {
|
||||
font-size: 26rpx;
|
||||
font-weight: 500;
|
||||
color: $white;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.wallet-num {
|
||||
font-size: 60rpx;
|
||||
font-weight: 500;
|
||||
color: $white;
|
||||
font-family: OPPOSANS;
|
||||
}
|
||||
|
||||
.log-btn {
|
||||
width: 170rpx;
|
||||
height: 60rpx;
|
||||
line-height: 60rpx;
|
||||
border: 1rpx solid $white;
|
||||
border-radius: 30rpx;
|
||||
padding: 0;
|
||||
font-size: 26rpx;
|
||||
font-weight: 500;
|
||||
color: $white;
|
||||
}
|
||||
}
|
||||
|
||||
.recharge-box {
|
||||
position: relative;
|
||||
padding: 0 30rpx;
|
||||
margin-top: -60rpx;
|
||||
}
|
||||
|
||||
.save-btn {
|
||||
width: 620rpx;
|
||||
height: 86rpx;
|
||||
border-radius: 44rpx;
|
||||
font-size: 30rpx;
|
||||
}
|
||||
|
||||
.recharge-card-box {
|
||||
width: 690rpx;
|
||||
background: var(--ui-BG);
|
||||
border-radius: 20rpx;
|
||||
padding: 30rpx;
|
||||
box-sizing: border-box;
|
||||
|
||||
.input-label {
|
||||
font-size: 30rpx;
|
||||
font-weight: 500;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.unit {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 48rpx;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.uni-easyinput__placeholder-class {
|
||||
font-size: 30rpx;
|
||||
height: 60rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
:deep(.uni-easyinput__content-input) {
|
||||
font-size: 48rpx;
|
||||
}
|
||||
|
||||
.face-value-btn {
|
||||
width: 200rpx;
|
||||
height: 144rpx;
|
||||
border: 1px solid var(--ui-BG-Main);
|
||||
border-radius: 10rpx;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
margin-bottom: 15rpx;
|
||||
margin-right: 15rpx;
|
||||
|
||||
&:nth-of-type(3n) {
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
.face-value-title {
|
||||
font-size: 36rpx;
|
||||
font-weight: 500;
|
||||
color: var(--ui-BG-Main);
|
||||
font-family: OPPOSANS;
|
||||
|
||||
&::after {
|
||||
content: '钻';
|
||||
font-size: 24rpx;
|
||||
margin-left: 6rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.face-value-tag {
|
||||
position: absolute;
|
||||
z-index: 2;
|
||||
height: 40rpx;
|
||||
line-height: 40rpx;
|
||||
background: var(--ui-BG-Main);
|
||||
opacity: 0.8;
|
||||
border-radius: 10rpx 0 20rpx 0;
|
||||
top: 0;
|
||||
left: -2rpx;
|
||||
padding: 0 16rpx;
|
||||
font-size: 22rpx;
|
||||
color: $white;
|
||||
font-family: OPPOSANS;
|
||||
}
|
||||
|
||||
&::before {
|
||||
position: absolute;
|
||||
content: ' ';
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: var(--ui-BG-Main);
|
||||
opacity: 0.1;
|
||||
z-index: 0;
|
||||
left: 0;
|
||||
top: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.btn-active {
|
||||
z-index: 1;
|
||||
|
||||
&::before {
|
||||
content: '';
|
||||
background: var(--ui-BG-Main);
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.face-value-title {
|
||||
color: $white;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
font-family: OPPOSANS;
|
||||
}
|
||||
|
||||
.face-value-tag {
|
||||
background: $white;
|
||||
color: var(--ui-BG-Main);
|
||||
font-family: OPPOSANS;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
318
pages/pay/result.vue
Normal file
318
pages/pay/result.vue
Normal file
@@ -0,0 +1,318 @@
|
||||
<!-- 支付结果页面 -->
|
||||
<template>
|
||||
<s-layout title="支付结果" :bgStyle="{ color: '#FFF' }">
|
||||
<view class="pay-result-box ss-flex-col ss-row-center ss-col-center">
|
||||
<!-- 信息展示 -->
|
||||
<view class="pay-waiting ss-m-b-30" v-if="payResult === 'waiting'" />
|
||||
<image
|
||||
class="pay-img ss-m-b-30"
|
||||
v-if="payResult === 'success'"
|
||||
:src="sheep.$url.static('/static/img/shop/order/order_pay_success.gif')"
|
||||
/>
|
||||
<image
|
||||
class="pay-img ss-m-b-30"
|
||||
v-if="['failed', 'closed'].includes(payResult)"
|
||||
:src="sheep.$url.static('/static/img/shop/order/order_paty_fail.gif')"
|
||||
/>
|
||||
<view class="tip-text ss-m-b-30" v-if="payResult === 'success'">支付成功</view>
|
||||
<view class="tip-text ss-m-b-30" v-if="payResult === 'failed'">支付失败</view>
|
||||
<view class="tip-text ss-m-b-30" v-if="payResult === 'closed'">该订单已关闭</view>
|
||||
<view class="tip-text ss-m-b-30" v-if="payResult === 'waiting'">检测支付结果...</view>
|
||||
<view class="pay-total-num ss-flex" v-if="payResult === 'success'">
|
||||
<view>¥{{ fen2yuan(state.orderInfo.price) }}</view>
|
||||
</view>
|
||||
|
||||
<!-- 操作区 -->
|
||||
<view class="btn-box ss-flex ss-row-center ss-m-t-50">
|
||||
<button class="back-btn ss-reset-button" @tap="sheep.$router.go('/pages/tabbar/index')">
|
||||
返回首页
|
||||
</button>
|
||||
<button
|
||||
class="check-btn ss-reset-button"
|
||||
v-if="payResult === 'failed'"
|
||||
@tap="
|
||||
sheep.$router.redirect('/pages/pay/index', { id: state.id, orderType: state.orderType })
|
||||
"
|
||||
>
|
||||
重新支付
|
||||
</button>
|
||||
<button class="check-btn ss-reset-button" v-if="payResult === 'success'" @tap="onOrder">
|
||||
查看订单
|
||||
</button>
|
||||
<button
|
||||
class="check-btn ss-reset-button"
|
||||
v-if="payResult === 'success' && state.tradeOrder.type === 3"
|
||||
@tap="sheep.$router.redirect('/pages/activity/groupon/order')"
|
||||
>
|
||||
我的拼团
|
||||
</button>
|
||||
</view>
|
||||
|
||||
<!-- #ifdef MP -->
|
||||
<view
|
||||
class="subscribe-box ss-flex ss-m-t-44"
|
||||
v-if="showSubscribeBtn && state.orderType === 'goods'"
|
||||
>
|
||||
<image class="subscribe-img" :src="sheep.$url.static('/static/img/shop/order/cargo.png')" />
|
||||
<view class="subscribe-title ss-m-r-48 ss-m-l-16">获取实时发货信息与订单状态</view>
|
||||
<view class="subscribe-start" @tap="subscribeMessage">立即订阅</view>
|
||||
</view>
|
||||
<!-- #endif -->
|
||||
</view>
|
||||
</s-layout>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { onLoad, onHide, onShow } from '@dcloudio/uni-app';
|
||||
import { reactive, computed, ref } from 'vue';
|
||||
import { isEmpty } from 'lodash-es';
|
||||
import sheep from '@/sheep';
|
||||
import PayOrderApi from '@/sheep/api/pay/order';
|
||||
import { fen2yuan } from '@/sheep/hooks/useGoods';
|
||||
import OrderApi from '@/sheep/api/trade/order';
|
||||
import { WxaSubscribeTemplate } from '@/sheep/util/const';
|
||||
|
||||
const state = reactive({
|
||||
id: 0, // 支付单号
|
||||
orderType: 'goods', // 订单类型
|
||||
result: 'unpaid', // 支付状态
|
||||
orderInfo: {}, // 支付订单信息
|
||||
tradeOrder: {}, // 商品订单信息,只有在 orderType 为 goods 才会请求。目的:【我的拼团】按钮的展示
|
||||
counter: 0, // 获取结果次数
|
||||
});
|
||||
|
||||
// 支付结果 result => payResult
|
||||
const payResult = computed(() => {
|
||||
if (state.result === 'unpaid') {
|
||||
return 'waiting';
|
||||
}
|
||||
if (state.result === 'paid') {
|
||||
return 'success';
|
||||
}
|
||||
if (state.result === 'failed') {
|
||||
return 'failed';
|
||||
}
|
||||
if (state.result === 'closed') {
|
||||
return 'closed';
|
||||
}
|
||||
});
|
||||
|
||||
// 获得订单信息
|
||||
async function getOrderInfo(id) {
|
||||
state.counter++;
|
||||
// 1. 加载订单信息
|
||||
const { data, code } = await PayOrderApi.getOrder(id);
|
||||
if (code === 0) {
|
||||
state.orderInfo = data;
|
||||
if (!state.orderInfo || state.orderInfo.status === 30) {
|
||||
// 支付关闭
|
||||
state.result = 'closed';
|
||||
return;
|
||||
}
|
||||
if (state.orderInfo.status !== 0) {
|
||||
sheep.$store('user').getWallet();
|
||||
// 非待支付,可能是已支付,可能是已退款
|
||||
state.result = 'paid';
|
||||
// #ifdef MP
|
||||
uni.showModal({
|
||||
title: '支付结果',
|
||||
showCancel: false, // 不要取消按钮
|
||||
content: '支付成功',
|
||||
success: () => {
|
||||
// 订阅只能由用户主动触发,只能包一层 showModal 诱导用户点击
|
||||
autoSubscribeMessage();
|
||||
},
|
||||
});
|
||||
|
||||
// #endif
|
||||
// 特殊:获得商品订单信息
|
||||
if (state.orderType === 'goods') {
|
||||
const { data, code } = await OrderApi.getOrder(state.orderInfo.merchantOrderId);
|
||||
if (code === 0) {
|
||||
state.tradeOrder = data;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
// 2.1 情况三一:未支付,且轮询次数小于三次,则继续轮询
|
||||
if (state.counter < 3 && state.result === 'unpaid') {
|
||||
setTimeout(() => {
|
||||
getOrderInfo(id);
|
||||
}, 1500);
|
||||
}
|
||||
// 2.2 情况二:超过三次检测才判断为支付失败
|
||||
if (state.counter >= 3) {
|
||||
state.result = 'failed';
|
||||
}
|
||||
}
|
||||
|
||||
function onOrder() {
|
||||
if (state.orderType === 'recharge') {
|
||||
sheep.$router.redirect('/pages/pay/recharge-log');
|
||||
} else {
|
||||
sheep.$router.redirect('/pages/order/list');
|
||||
}
|
||||
}
|
||||
|
||||
// #ifdef MP
|
||||
const showSubscribeBtn = ref(false); // 默认隐藏
|
||||
const SUBSCRIBE_BTN_STATUS_STORAGE_KEY = 'subscribe_btn_status';
|
||||
function subscribeMessage() {
|
||||
if (state.orderType !== 'goods') {
|
||||
return;
|
||||
}
|
||||
const event = [WxaSubscribeTemplate.TRADE_ORDER_DELIVERY];
|
||||
if (state.tradeOrder.type === 3) {
|
||||
event.push(WxaSubscribeTemplate.PROMOTION_COMBINATION_SUCCESS);
|
||||
}
|
||||
sheep.$platform.useProvider('wechat').subscribeMessage(event, () => {
|
||||
// 订阅后记录一下订阅状态
|
||||
uni.removeStorageSync(SUBSCRIBE_BTN_STATUS_STORAGE_KEY);
|
||||
uni.setStorageSync(SUBSCRIBE_BTN_STATUS_STORAGE_KEY, '已订阅');
|
||||
// 隐藏订阅按钮
|
||||
showSubscribeBtn.value = false;
|
||||
});
|
||||
}
|
||||
async function autoSubscribeMessage() {
|
||||
// 1. 校验是否手动订阅过
|
||||
const subscribeBtnStatus = uni.getStorageSync(SUBSCRIBE_BTN_STATUS_STORAGE_KEY);
|
||||
if (!subscribeBtnStatus) {
|
||||
showSubscribeBtn.value = true;
|
||||
return;
|
||||
}
|
||||
|
||||
// 2. 订阅消息
|
||||
subscribeMessage();
|
||||
}
|
||||
// #endif
|
||||
|
||||
onLoad(async (options) => {
|
||||
// 支付订单号
|
||||
if (options.id) {
|
||||
state.id = options.id;
|
||||
}
|
||||
// 订单类型
|
||||
if (options.orderType) {
|
||||
state.orderType = options.orderType;
|
||||
}
|
||||
|
||||
// 支付结果传值过来是失败,则直接显示失败界面
|
||||
if (options.payState === 'fail') {
|
||||
state.result = 'failed';
|
||||
} else {
|
||||
// 轮询三次检测订单支付结果
|
||||
await getOrderInfo(state.id);
|
||||
}
|
||||
});
|
||||
|
||||
onShow(() => {
|
||||
if (isEmpty(state.orderInfo)) {
|
||||
return;
|
||||
}
|
||||
getOrderInfo(state.id);
|
||||
});
|
||||
|
||||
onHide(() => {
|
||||
state.result = 'unpaid';
|
||||
state.counter = 0;
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@keyframes rotation {
|
||||
0% {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
|
||||
100% {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
.score-img {
|
||||
width: 36rpx;
|
||||
height: 36rpx;
|
||||
margin: 0 4rpx;
|
||||
}
|
||||
|
||||
.pay-result-box {
|
||||
padding: 60rpx 0;
|
||||
|
||||
.pay-waiting {
|
||||
margin-top: 20rpx;
|
||||
width: 60rpx;
|
||||
height: 60rpx;
|
||||
border: 10rpx solid rgb(233, 231, 231);
|
||||
border-bottom-color: rgb(204, 204, 204);
|
||||
border-radius: 50%;
|
||||
display: inline-block;
|
||||
// -webkit-animation: rotation 1s linear infinite;
|
||||
animation: rotation 1s linear infinite;
|
||||
}
|
||||
|
||||
.pay-img {
|
||||
width: 130rpx;
|
||||
height: 130rpx;
|
||||
}
|
||||
|
||||
.tip-text {
|
||||
font-size: 30rpx;
|
||||
font-weight: bold;
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
.pay-total-num {
|
||||
font-size: 36rpx;
|
||||
font-weight: 500;
|
||||
color: #333333;
|
||||
font-family: OPPOSANS;
|
||||
}
|
||||
|
||||
.btn-box {
|
||||
width: 100%;
|
||||
|
||||
.back-btn {
|
||||
width: 190rpx;
|
||||
height: 70rpx;
|
||||
font-size: 28rpx;
|
||||
border: 2rpx solid #dfdfdf;
|
||||
border-radius: 35rpx;
|
||||
font-weight: 400;
|
||||
color: #595959;
|
||||
}
|
||||
|
||||
.check-btn {
|
||||
width: 190rpx;
|
||||
height: 70rpx;
|
||||
font-size: 28rpx;
|
||||
border: 2rpx solid #dfdfdf;
|
||||
border-radius: 35rpx;
|
||||
font-weight: 400;
|
||||
color: #595959;
|
||||
margin-left: 32rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.subscribe-box {
|
||||
.subscribe-img {
|
||||
width: 44rpx;
|
||||
height: 44rpx;
|
||||
}
|
||||
|
||||
.subscribe-title {
|
||||
font-weight: 500;
|
||||
font-size: 32rpx;
|
||||
line-height: 36rpx;
|
||||
color: #434343;
|
||||
}
|
||||
|
||||
.subscribe-start {
|
||||
color: var(--ui-BG-Main);
|
||||
font-weight: 700;
|
||||
font-size: 32rpx;
|
||||
line-height: 36rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
308
pages/pay/reward/index.vue
Normal file
308
pages/pay/reward/index.vue
Normal file
@@ -0,0 +1,308 @@
|
||||
<!-- 收银台 -->
|
||||
<template>
|
||||
<s-layout title="收银台">
|
||||
<view class="bg-white ss-modal-box ss-flex-col">
|
||||
<!-- 订单信息 -->
|
||||
<view class="modal-header ss-flex-col ss-col-center ss-row-center">
|
||||
<view class="money-box ss-m-b-20">
|
||||
<text class="money-text">{{ fen2yuan(state.orderInfo.price) }}</text>
|
||||
</view>
|
||||
<view class="time-text">
|
||||
<text>{{ payDescText }}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 支付方式 -->
|
||||
<view class="modal-content ss-flex-1">
|
||||
<view class="pay-title ss-p-l-30 ss-m-y-30">选择支付方式</view>
|
||||
<radio-group @change="onTapPay">
|
||||
<label class="pay-type-item" v-for="item in state.payMethods" :key="item.title">
|
||||
<view
|
||||
v-if="!item.disabled"
|
||||
class="pay-item ss-flex ss-col-center ss-row-between ss-p-x-30 border-bottom"
|
||||
:class="{ 'disabled-pay-item': item.disabled }"
|
||||
>
|
||||
<view class="ss-flex ss-col-center">
|
||||
<image
|
||||
class="pay-icon"
|
||||
v-if="item.disabled"
|
||||
:src="sheep.$url.static('/static/img/shop/pay/cod_disabled.png')"
|
||||
mode="aspectFit"
|
||||
/>
|
||||
<image
|
||||
class="pay-icon"
|
||||
v-else
|
||||
:src="sheep.$url.static(item.icon)"
|
||||
mode="aspectFit"
|
||||
/>
|
||||
<text class="pay-title">{{ item.title }}</text>
|
||||
</view>
|
||||
<view class="check-box ss-flex ss-col-center ss-p-l-10">
|
||||
<view class="userInfo-money ss-m-r-10" v-if="item.value === 'wallet'">
|
||||
余额: {{ fen2yuan(userWallet.balance) }}元
|
||||
</view>
|
||||
<radio
|
||||
:value="item.value"
|
||||
color="var(--ui-BG-Main)"
|
||||
style="transform: scale(0.8)"
|
||||
:disabled="item.disabled"
|
||||
:checked="state.payment === item.value"
|
||||
/>
|
||||
</view>
|
||||
</view>
|
||||
</label>
|
||||
</radio-group>
|
||||
</view>
|
||||
|
||||
<!-- 工具 -->
|
||||
<view class="modal-footer ss-flex ss-row-center ss-col-center ss-m-t-80 ss-m-b-40">
|
||||
<button v-if="state.payStatus === 0" class="ss-reset-button past-due-btn">
|
||||
检测支付环境中
|
||||
</button>
|
||||
<button v-else-if="state.payStatus === -1" class="ss-reset-button past-due-btn" disabled>
|
||||
支付已过期
|
||||
</button>
|
||||
<button
|
||||
v-else
|
||||
class="ss-reset-button save-btn"
|
||||
@tap="onPay"
|
||||
:disabled="state.payStatus !== 1"
|
||||
:class="{ 'disabled-btn': state.payStatus !== 1 }"
|
||||
>
|
||||
立即支付
|
||||
</button>
|
||||
</view>
|
||||
</view>
|
||||
</s-layout>
|
||||
</template>
|
||||
<script setup>
|
||||
import { computed, reactive } from 'vue';
|
||||
import { onLoad } from '@dcloudio/uni-app';
|
||||
import sheep from '@/sheep';
|
||||
import { fen2yuan, useDurationTime } from '@/sheep/hooks/useGoods';
|
||||
import PayOrderApi from '@/sheep/api/pay/order';
|
||||
import PayChannelApi from '@/sheep/api/pay/channel';
|
||||
import { getPayMethods } from '@/sheep/platform/pay';
|
||||
|
||||
const userWallet = computed(() => sheep.$store('user').userWallet);
|
||||
|
||||
// 检测支付环境
|
||||
const state = reactive({
|
||||
orderType: 'goods', // 订单类型; goods - 商品订单, recharge - 充值订单
|
||||
orderInfo: {}, // 支付单信息
|
||||
payStatus: 0, // 0=检测支付环境, -2=未查询到支付单信息, -1=支付已过期, 1=待支付,2=订单已支付
|
||||
payMethods: [], // 可选的支付方式
|
||||
payment: '', // 选中的支付方式
|
||||
});
|
||||
|
||||
const onPay = () => {
|
||||
if (state.payment === '') {
|
||||
sheep.$helper.toast('请选择支付方式');
|
||||
return;
|
||||
}
|
||||
if (state.payment === 'wallet') {
|
||||
if(state.orderInfo.price > userWallet.value.balance){
|
||||
uni.showModal({
|
||||
title: '账户余额不足',
|
||||
confirmText: '去充值',
|
||||
success: function (res) {
|
||||
if (res.confirm) {
|
||||
sheep.$router.go('/pages/pay/recharge');
|
||||
}
|
||||
},
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
uni.showModal({
|
||||
title: '提示',
|
||||
content: '确定要支付吗?',
|
||||
success: function (res) {
|
||||
if (res.confirm) {
|
||||
sheep.$platform.pay(state.payment, state.orderType, state.orderInfo.id, 'reward');
|
||||
}
|
||||
},
|
||||
});
|
||||
} else {
|
||||
sheep.$platform.pay(state.payment, state.orderType, state.orderInfo.id, 'reward');
|
||||
}
|
||||
};
|
||||
|
||||
// 支付文案提示
|
||||
const payDescText = computed(() => {
|
||||
if (state.payStatus === 2) {
|
||||
return '该订单已支付';
|
||||
}
|
||||
if (state.payStatus === 1) {
|
||||
const time = useDurationTime(state.orderInfo.expireTime);
|
||||
if (time.ms <= 0) {
|
||||
state.payStatus = -1;
|
||||
return '';
|
||||
}
|
||||
return `剩余支付时间 ${time.h}:${time.m}:${time.s} `;
|
||||
}
|
||||
if (state.payStatus === -2) {
|
||||
return '未查询到支付单信息';
|
||||
}
|
||||
return '';
|
||||
});
|
||||
|
||||
// 状态转换:payOrder.status => payStatus
|
||||
function checkPayStatus() {
|
||||
if (state.orderInfo.status === 10
|
||||
|| state.orderInfo.status === 20 ) { // 支付成功
|
||||
state.payStatus = 2;
|
||||
return;
|
||||
}
|
||||
if (state.orderInfo.status === 30) { // 支付关闭
|
||||
state.payStatus = -1;
|
||||
return;
|
||||
}
|
||||
state.payStatus = 1; // 待支付
|
||||
}
|
||||
|
||||
// 切换支付方式
|
||||
function onTapPay(e) {
|
||||
state.payment = e.detail.value;
|
||||
}
|
||||
|
||||
// 设置支付订单信息
|
||||
async function setOrder(id) {
|
||||
// 获得支付订单信息
|
||||
const { data, code } = await PayOrderApi.getOrder(id);
|
||||
if (code !== 0 || !data) {
|
||||
state.payStatus = -2;
|
||||
return;
|
||||
}
|
||||
state.orderInfo = data;
|
||||
// 获得支付方式
|
||||
await setPayMethods();
|
||||
// 设置支付状态
|
||||
checkPayStatus();
|
||||
}
|
||||
|
||||
// 获得支付方式
|
||||
async function setPayMethods() {
|
||||
const { data, code } = await PayChannelApi.getEnableChannelCodeList(state.orderInfo.appId)
|
||||
if (code !== 0) {
|
||||
return
|
||||
}
|
||||
state.payMethods = getPayMethods(data)
|
||||
state.payMethods.find(item => {
|
||||
if (item.value && !item.disabled) {
|
||||
state.payment = item.value;
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
onLoad((options) => {
|
||||
if (sheep.$platform.name === 'WechatOfficialAccount'
|
||||
&& sheep.$platform.os === 'ios'
|
||||
&& !sheep.$platform.landingPage.includes('pages/pay/reward/index')) {
|
||||
location.reload();
|
||||
return;
|
||||
}
|
||||
// 获得支付订单信息
|
||||
let id = options.id;
|
||||
if (options.orderType) {
|
||||
state.orderType = options.orderType;
|
||||
}
|
||||
setOrder(id);
|
||||
// 刷新钱包的缓存
|
||||
sheep.$store('user').getWallet();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.pay-icon {
|
||||
width: 36rpx;
|
||||
height: 36rpx;
|
||||
margin-right: 26rpx;
|
||||
}
|
||||
|
||||
.ss-modal-box {
|
||||
// max-height: 1000rpx;
|
||||
|
||||
.modal-header {
|
||||
position: relative;
|
||||
padding: 60rpx 20rpx 40rpx;
|
||||
|
||||
|
||||
.money-text {
|
||||
color: $red;
|
||||
font-size: 46rpx;
|
||||
font-weight: bold;
|
||||
font-family: OPPOSANS;
|
||||
|
||||
&::before {
|
||||
content: '¥';
|
||||
font-size: 30rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.time-text {
|
||||
font-size: 26rpx;
|
||||
color: $gray-b;
|
||||
}
|
||||
|
||||
.close-icon {
|
||||
position: absolute;
|
||||
top: 10rpx;
|
||||
right: 20rpx;
|
||||
font-size: 46rpx;
|
||||
opacity: 0.2;
|
||||
}
|
||||
}
|
||||
|
||||
.modal-content {
|
||||
overflow-y: auto;
|
||||
|
||||
.pay-title {
|
||||
font-size: 26rpx;
|
||||
font-weight: 500;
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
.pay-tip {
|
||||
font-size: 26rpx;
|
||||
color: #bbbbbb;
|
||||
}
|
||||
|
||||
.pay-item {
|
||||
height: 86rpx;
|
||||
}
|
||||
.disabled-pay-item {
|
||||
.pay-title {
|
||||
color: #999999;
|
||||
}
|
||||
}
|
||||
|
||||
.userInfo-money {
|
||||
font-size: 26rpx;
|
||||
color: #bbbbbb;
|
||||
line-height: normal;
|
||||
}
|
||||
}
|
||||
|
||||
.save-btn {
|
||||
width: 710rpx;
|
||||
height: 80rpx;
|
||||
border-radius: 40rpx;
|
||||
background: linear-gradient(90deg, var(--ui-BG-Main), var(--ui-BG-Main-gradient));
|
||||
color: $white;
|
||||
}
|
||||
.disabled-btn {
|
||||
background: #e5e5e5;
|
||||
color: #999999;
|
||||
}
|
||||
|
||||
.past-due-btn {
|
||||
width: 710rpx;
|
||||
height: 80rpx;
|
||||
border-radius: 40rpx;
|
||||
background-color: #999;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
</style>
|
308
pages/pay/vip/index.vue
Normal file
308
pages/pay/vip/index.vue
Normal file
@@ -0,0 +1,308 @@
|
||||
<!-- 收银台 -->
|
||||
<template>
|
||||
<s-layout title="收银台">
|
||||
<view class="bg-white ss-modal-box ss-flex-col">
|
||||
<!-- 订单信息 -->
|
||||
<view class="modal-header ss-flex-col ss-col-center ss-row-center">
|
||||
<view class="money-box ss-m-b-20">
|
||||
<text class="money-text">{{ fen2yuan(state.orderInfo.price) }}</text>
|
||||
</view>
|
||||
<view class="time-text">
|
||||
<text>{{ payDescText }}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 支付方式 -->
|
||||
<view class="modal-content ss-flex-1">
|
||||
<view class="pay-title ss-p-l-30 ss-m-y-30">选择支付方式</view>
|
||||
<radio-group @change="onTapPay">
|
||||
<label class="pay-type-item" v-for="item in state.payMethods" :key="item.title">
|
||||
<view
|
||||
v-if="!item.disabled"
|
||||
class="pay-item ss-flex ss-col-center ss-row-between ss-p-x-30 border-bottom"
|
||||
:class="{ 'disabled-pay-item': item.disabled }"
|
||||
>
|
||||
<view class="ss-flex ss-col-center">
|
||||
<image
|
||||
class="pay-icon"
|
||||
v-if="item.disabled"
|
||||
:src="sheep.$url.static('/static/img/shop/pay/cod_disabled.png')"
|
||||
mode="aspectFit"
|
||||
/>
|
||||
<image
|
||||
class="pay-icon"
|
||||
v-else
|
||||
:src="sheep.$url.static(item.icon)"
|
||||
mode="aspectFit"
|
||||
/>
|
||||
<text class="pay-title">{{ item.title }}</text>
|
||||
</view>
|
||||
<view class="check-box ss-flex ss-col-center ss-p-l-10">
|
||||
<view class="userInfo-money ss-m-r-10" v-if="item.value === 'wallet'">
|
||||
余额: {{ fen2yuan(userWallet.balance) }}元
|
||||
</view>
|
||||
<radio
|
||||
:value="item.value"
|
||||
color="var(--ui-BG-Main)"
|
||||
style="transform: scale(0.8)"
|
||||
:disabled="item.disabled"
|
||||
:checked="state.payment === item.value"
|
||||
/>
|
||||
</view>
|
||||
</view>
|
||||
</label>
|
||||
</radio-group>
|
||||
</view>
|
||||
|
||||
<!-- 工具 -->
|
||||
<view class="modal-footer ss-flex ss-row-center ss-col-center ss-m-t-80 ss-m-b-40">
|
||||
<button v-if="state.payStatus === 0" class="ss-reset-button past-due-btn">
|
||||
检测支付环境中
|
||||
</button>
|
||||
<button v-else-if="state.payStatus === -1" class="ss-reset-button past-due-btn" disabled>
|
||||
支付已过期
|
||||
</button>
|
||||
<button
|
||||
v-else
|
||||
class="ss-reset-button save-btn"
|
||||
@tap="onPay"
|
||||
:disabled="state.payStatus !== 1"
|
||||
:class="{ 'disabled-btn': state.payStatus !== 1 }"
|
||||
>
|
||||
立即支付
|
||||
</button>
|
||||
</view>
|
||||
</view>
|
||||
</s-layout>
|
||||
</template>
|
||||
<script setup>
|
||||
import { computed, reactive } from 'vue';
|
||||
import { onLoad } from '@dcloudio/uni-app';
|
||||
import sheep from '@/sheep';
|
||||
import { fen2yuan, useDurationTime } from '@/sheep/hooks/useGoods';
|
||||
import PayOrderApi from '@/sheep/api/pay/order';
|
||||
import PayChannelApi from '@/sheep/api/pay/channel';
|
||||
import { getPayMethods } from '@/sheep/platform/pay';
|
||||
|
||||
const userWallet = computed(() => sheep.$store('user').userWallet);
|
||||
|
||||
// 检测支付环境
|
||||
const state = reactive({
|
||||
orderType: 'goods', // 订单类型; goods - 商品订单, recharge - 充值订单
|
||||
orderInfo: {}, // 支付单信息
|
||||
payStatus: 0, // 0=检测支付环境, -2=未查询到支付单信息, -1=支付已过期, 1=待支付,2=订单已支付
|
||||
payMethods: [], // 可选的支付方式
|
||||
payment: '', // 选中的支付方式
|
||||
});
|
||||
|
||||
const onPay = () => {
|
||||
if (state.payment === '') {
|
||||
sheep.$helper.toast('请选择支付方式');
|
||||
return;
|
||||
}
|
||||
if (state.payment === 'wallet') {
|
||||
if(state.orderInfo.price > userWallet.value.balance){
|
||||
uni.showModal({
|
||||
title: '账户余额不足',
|
||||
confirmText: '去充值',
|
||||
success: function (res) {
|
||||
if (res.confirm) {
|
||||
sheep.$router.go('/pages/pay/recharge');
|
||||
}
|
||||
},
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
uni.showModal({
|
||||
title: '提示',
|
||||
content: '确定要支付吗?',
|
||||
success: function (res) {
|
||||
if (res.confirm) {
|
||||
sheep.$platform.pay(state.payment, state.orderType, state.orderInfo.id, 'vip');
|
||||
}
|
||||
},
|
||||
});
|
||||
} else {
|
||||
sheep.$platform.pay(state.payment, state.orderType, state.orderInfo.id, 'vip');
|
||||
}
|
||||
};
|
||||
|
||||
// 支付文案提示
|
||||
const payDescText = computed(() => {
|
||||
if (state.payStatus === 2) {
|
||||
return '该订单已支付';
|
||||
}
|
||||
if (state.payStatus === 1) {
|
||||
const time = useDurationTime(state.orderInfo.expireTime);
|
||||
if (time.ms <= 0) {
|
||||
state.payStatus = -1;
|
||||
return '';
|
||||
}
|
||||
return `剩余支付时间 ${time.h}:${time.m}:${time.s} `;
|
||||
}
|
||||
if (state.payStatus === -2) {
|
||||
return '未查询到支付单信息';
|
||||
}
|
||||
return '';
|
||||
});
|
||||
|
||||
// 状态转换:payOrder.status => payStatus
|
||||
function checkPayStatus() {
|
||||
if (state.orderInfo.status === 10
|
||||
|| state.orderInfo.status === 20 ) { // 支付成功
|
||||
state.payStatus = 2;
|
||||
return;
|
||||
}
|
||||
if (state.orderInfo.status === 30) { // 支付关闭
|
||||
state.payStatus = -1;
|
||||
return;
|
||||
}
|
||||
state.payStatus = 1; // 待支付
|
||||
}
|
||||
|
||||
// 切换支付方式
|
||||
function onTapPay(e) {
|
||||
state.payment = e.detail.value;
|
||||
}
|
||||
|
||||
// 设置支付订单信息
|
||||
async function setOrder(id) {
|
||||
// 获得支付订单信息
|
||||
const { data, code } = await PayOrderApi.getOrder(id);
|
||||
if (code !== 0 || !data) {
|
||||
state.payStatus = -2;
|
||||
return;
|
||||
}
|
||||
state.orderInfo = data;
|
||||
// 获得支付方式
|
||||
await setPayMethods();
|
||||
// 设置支付状态
|
||||
checkPayStatus();
|
||||
}
|
||||
|
||||
// 获得支付方式
|
||||
async function setPayMethods() {
|
||||
const { data, code } = await PayChannelApi.getEnableChannelCodeList(state.orderInfo.appId)
|
||||
if (code !== 0) {
|
||||
return
|
||||
}
|
||||
state.payMethods = getPayMethods(data)
|
||||
state.payMethods.find(item => {
|
||||
if (item.value && !item.disabled) {
|
||||
state.payment = item.value;
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
onLoad((options) => {
|
||||
if (sheep.$platform.name === 'WechatOfficialAccount'
|
||||
&& sheep.$platform.os === 'ios'
|
||||
&& !sheep.$platform.landingPage.includes('pages/pay/vip/index')) {
|
||||
location.reload();
|
||||
return;
|
||||
}
|
||||
// 获得支付订单信息
|
||||
let id = options.id;
|
||||
if (options.orderType) {
|
||||
state.orderType = options.orderType;
|
||||
}
|
||||
setOrder(id);
|
||||
// 刷新钱包的缓存
|
||||
sheep.$store('user').getWallet();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.pay-icon {
|
||||
width: 36rpx;
|
||||
height: 36rpx;
|
||||
margin-right: 26rpx;
|
||||
}
|
||||
|
||||
.ss-modal-box {
|
||||
// max-height: 1000rpx;
|
||||
|
||||
.modal-header {
|
||||
position: relative;
|
||||
padding: 60rpx 20rpx 40rpx;
|
||||
|
||||
|
||||
.money-text {
|
||||
color: $red;
|
||||
font-size: 46rpx;
|
||||
font-weight: bold;
|
||||
font-family: OPPOSANS;
|
||||
|
||||
&::before {
|
||||
content: '¥';
|
||||
font-size: 30rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.time-text {
|
||||
font-size: 26rpx;
|
||||
color: $gray-b;
|
||||
}
|
||||
|
||||
.close-icon {
|
||||
position: absolute;
|
||||
top: 10rpx;
|
||||
right: 20rpx;
|
||||
font-size: 46rpx;
|
||||
opacity: 0.2;
|
||||
}
|
||||
}
|
||||
|
||||
.modal-content {
|
||||
overflow-y: auto;
|
||||
|
||||
.pay-title {
|
||||
font-size: 26rpx;
|
||||
font-weight: 500;
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
.pay-tip {
|
||||
font-size: 26rpx;
|
||||
color: #bbbbbb;
|
||||
}
|
||||
|
||||
.pay-item {
|
||||
height: 86rpx;
|
||||
}
|
||||
.disabled-pay-item {
|
||||
.pay-title {
|
||||
color: #999999;
|
||||
}
|
||||
}
|
||||
|
||||
.userInfo-money {
|
||||
font-size: 26rpx;
|
||||
color: #bbbbbb;
|
||||
line-height: normal;
|
||||
}
|
||||
}
|
||||
|
||||
.save-btn {
|
||||
width: 710rpx;
|
||||
height: 80rpx;
|
||||
border-radius: 40rpx;
|
||||
background: linear-gradient(90deg, var(--ui-BG-Main), var(--ui-BG-Main-gradient));
|
||||
color: $white;
|
||||
}
|
||||
.disabled-btn {
|
||||
background: #e5e5e5;
|
||||
color: #999999;
|
||||
}
|
||||
|
||||
.past-due-btn {
|
||||
width: 710rpx;
|
||||
height: 80rpx;
|
||||
border-radius: 40rpx;
|
||||
background-color: #999;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
</style>
|
308
pages/pay/worker/index.vue
Normal file
308
pages/pay/worker/index.vue
Normal file
@@ -0,0 +1,308 @@
|
||||
<!-- 收银台 -->
|
||||
<template>
|
||||
<s-layout title="收银台">
|
||||
<view class="bg-white ss-modal-box ss-flex-col">
|
||||
<!-- 订单信息 -->
|
||||
<view class="modal-header ss-flex-col ss-col-center ss-row-center">
|
||||
<view class="money-box ss-m-b-20">
|
||||
<text class="money-text">{{ fen2yuan(state.orderInfo.price) }}</text>
|
||||
</view>
|
||||
<view class="time-text">
|
||||
<text>{{ payDescText }}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 支付方式 -->
|
||||
<view class="modal-content ss-flex-1">
|
||||
<view class="pay-title ss-p-l-30 ss-m-y-30">选择支付方式</view>
|
||||
<radio-group @change="onTapPay">
|
||||
<label class="pay-type-item" v-for="item in state.payMethods" :key="item.title">
|
||||
<view
|
||||
v-if="!item.disabled"
|
||||
class="pay-item ss-flex ss-col-center ss-row-between ss-p-x-30 border-bottom"
|
||||
:class="{ 'disabled-pay-item': item.disabled }"
|
||||
>
|
||||
<view class="ss-flex ss-col-center">
|
||||
<image
|
||||
class="pay-icon"
|
||||
v-if="item.disabled"
|
||||
:src="sheep.$url.static('/static/img/shop/pay/cod_disabled.png')"
|
||||
mode="aspectFit"
|
||||
/>
|
||||
<image
|
||||
class="pay-icon"
|
||||
v-else
|
||||
:src="sheep.$url.static(item.icon)"
|
||||
mode="aspectFit"
|
||||
/>
|
||||
<text class="pay-title">{{ item.title }}</text>
|
||||
</view>
|
||||
<view class="check-box ss-flex ss-col-center ss-p-l-10">
|
||||
<view class="userInfo-money ss-m-r-10" v-if="item.value === 'wallet'">
|
||||
余额: {{ fen2yuan(userWallet.balance) }}元
|
||||
</view>
|
||||
<radio
|
||||
:value="item.value"
|
||||
color="var(--ui-BG-Main)"
|
||||
style="transform: scale(0.8)"
|
||||
:disabled="item.disabled"
|
||||
:checked="state.payment === item.value"
|
||||
/>
|
||||
</view>
|
||||
</view>
|
||||
</label>
|
||||
</radio-group>
|
||||
</view>
|
||||
|
||||
<!-- 工具 -->
|
||||
<view class="modal-footer ss-flex ss-row-center ss-col-center ss-m-t-80 ss-m-b-40">
|
||||
<button v-if="state.payStatus === 0" class="ss-reset-button past-due-btn">
|
||||
检测支付环境中
|
||||
</button>
|
||||
<button v-else-if="state.payStatus === -1" class="ss-reset-button past-due-btn" disabled>
|
||||
支付已过期
|
||||
</button>
|
||||
<button
|
||||
v-else
|
||||
class="ss-reset-button save-btn"
|
||||
@tap="onPay"
|
||||
:disabled="state.payStatus !== 1"
|
||||
:class="{ 'disabled-btn': state.payStatus !== 1 }"
|
||||
>
|
||||
立即支付
|
||||
</button>
|
||||
</view>
|
||||
</view>
|
||||
</s-layout>
|
||||
</template>
|
||||
<script setup>
|
||||
import { computed, reactive } from 'vue';
|
||||
import { onLoad } from '@dcloudio/uni-app';
|
||||
import sheep from '@/sheep';
|
||||
import { fen2yuan, useDurationTime } from '@/sheep/hooks/useGoods';
|
||||
import PayOrderApi from '@/sheep/api/pay/order';
|
||||
import PayChannelApi from '@/sheep/api/pay/channel';
|
||||
import { getPayMethods } from '@/sheep/platform/pay';
|
||||
|
||||
const userWallet = computed(() => sheep.$store('user').userWallet);
|
||||
|
||||
// 检测支付环境
|
||||
const state = reactive({
|
||||
orderType: 'goods', // 订单类型; goods - 商品订单, recharge - 充值订单
|
||||
orderInfo: {}, // 支付单信息
|
||||
payStatus: 0, // 0=检测支付环境, -2=未查询到支付单信息, -1=支付已过期, 1=待支付,2=订单已支付
|
||||
payMethods: [], // 可选的支付方式
|
||||
payment: '', // 选中的支付方式
|
||||
});
|
||||
|
||||
const onPay = () => {
|
||||
if (state.payment === '') {
|
||||
sheep.$helper.toast('请选择支付方式');
|
||||
return;
|
||||
}
|
||||
if (state.payment === 'wallet') {
|
||||
if(state.orderInfo.price > userWallet.value.balance){
|
||||
uni.showModal({
|
||||
title: '账户余额不足',
|
||||
confirmText: '去充值',
|
||||
success: function (res) {
|
||||
if (res.confirm) {
|
||||
sheep.$router.go('/pages/pay/recharge');
|
||||
}
|
||||
},
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
uni.showModal({
|
||||
title: '提示',
|
||||
content: '确定要支付吗?',
|
||||
success: function (res) {
|
||||
if (res.confirm) {
|
||||
sheep.$platform.pay(state.payment, state.orderType, state.orderInfo.id, 'worker');
|
||||
}
|
||||
},
|
||||
});
|
||||
} else {
|
||||
sheep.$platform.pay(state.payment, state.orderType, state.orderInfo.id, 'worker');
|
||||
}
|
||||
};
|
||||
|
||||
// 支付文案提示
|
||||
const payDescText = computed(() => {
|
||||
if (state.payStatus === 2) {
|
||||
return '该订单已支付';
|
||||
}
|
||||
if (state.payStatus === 1) {
|
||||
const time = useDurationTime(state.orderInfo.expireTime);
|
||||
if (time.ms <= 0) {
|
||||
state.payStatus = -1;
|
||||
return '';
|
||||
}
|
||||
return `剩余支付时间 ${time.h}:${time.m}:${time.s} `;
|
||||
}
|
||||
if (state.payStatus === -2) {
|
||||
return '未查询到支付单信息';
|
||||
}
|
||||
return '';
|
||||
});
|
||||
|
||||
// 状态转换:payOrder.status => payStatus
|
||||
function checkPayStatus() {
|
||||
if (state.orderInfo.status === 10
|
||||
|| state.orderInfo.status === 20 ) { // 支付成功
|
||||
state.payStatus = 2;
|
||||
return;
|
||||
}
|
||||
if (state.orderInfo.status === 30) { // 支付关闭
|
||||
state.payStatus = -1;
|
||||
return;
|
||||
}
|
||||
state.payStatus = 1; // 待支付
|
||||
}
|
||||
|
||||
// 切换支付方式
|
||||
function onTapPay(e) {
|
||||
state.payment = e.detail.value;
|
||||
}
|
||||
|
||||
// 设置支付订单信息
|
||||
async function setOrder(id) {
|
||||
// 获得支付订单信息
|
||||
const { data, code } = await PayOrderApi.getOrder(id);
|
||||
if (code !== 0 || !data) {
|
||||
state.payStatus = -2;
|
||||
return;
|
||||
}
|
||||
state.orderInfo = data;
|
||||
// 获得支付方式
|
||||
await setPayMethods();
|
||||
// 设置支付状态
|
||||
checkPayStatus();
|
||||
}
|
||||
|
||||
// 获得支付方式
|
||||
async function setPayMethods() {
|
||||
const { data, code } = await PayChannelApi.getEnableChannelCodeList(state.orderInfo.appId)
|
||||
if (code !== 0) {
|
||||
return
|
||||
}
|
||||
state.payMethods = getPayMethods(data)
|
||||
state.payMethods.find(item => {
|
||||
if (item.value && !item.disabled) {
|
||||
state.payment = item.value;
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
onLoad((options) => {
|
||||
if (sheep.$platform.name === 'WechatOfficialAccount'
|
||||
&& sheep.$platform.os === 'ios'
|
||||
&& !sheep.$platform.landingPage.includes('pages/pay/worker/index')) {
|
||||
location.reload();
|
||||
return;
|
||||
}
|
||||
// 获得支付订单信息
|
||||
let id = options.id;
|
||||
if (options.orderType) {
|
||||
state.orderType = options.orderType;
|
||||
}
|
||||
setOrder(id);
|
||||
// 刷新钱包的缓存
|
||||
sheep.$store('user').getWallet();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.pay-icon {
|
||||
width: 36rpx;
|
||||
height: 36rpx;
|
||||
margin-right: 26rpx;
|
||||
}
|
||||
|
||||
.ss-modal-box {
|
||||
// max-height: 1000rpx;
|
||||
|
||||
.modal-header {
|
||||
position: relative;
|
||||
padding: 60rpx 20rpx 40rpx;
|
||||
|
||||
|
||||
.money-text {
|
||||
color: $red;
|
||||
font-size: 46rpx;
|
||||
font-weight: bold;
|
||||
font-family: OPPOSANS;
|
||||
|
||||
&::before {
|
||||
content: '¥';
|
||||
font-size: 30rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.time-text {
|
||||
font-size: 26rpx;
|
||||
color: $gray-b;
|
||||
}
|
||||
|
||||
.close-icon {
|
||||
position: absolute;
|
||||
top: 10rpx;
|
||||
right: 20rpx;
|
||||
font-size: 46rpx;
|
||||
opacity: 0.2;
|
||||
}
|
||||
}
|
||||
|
||||
.modal-content {
|
||||
overflow-y: auto;
|
||||
|
||||
.pay-title {
|
||||
font-size: 26rpx;
|
||||
font-weight: 500;
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
.pay-tip {
|
||||
font-size: 26rpx;
|
||||
color: #bbbbbb;
|
||||
}
|
||||
|
||||
.pay-item {
|
||||
height: 86rpx;
|
||||
}
|
||||
.disabled-pay-item {
|
||||
.pay-title {
|
||||
color: #999999;
|
||||
}
|
||||
}
|
||||
|
||||
.userInfo-money {
|
||||
font-size: 26rpx;
|
||||
color: #bbbbbb;
|
||||
line-height: normal;
|
||||
}
|
||||
}
|
||||
|
||||
.save-btn {
|
||||
width: 710rpx;
|
||||
height: 80rpx;
|
||||
border-radius: 40rpx;
|
||||
background: linear-gradient(90deg, var(--ui-BG-Main), var(--ui-BG-Main-gradient));
|
||||
color: $white;
|
||||
}
|
||||
.disabled-btn {
|
||||
background: #e5e5e5;
|
||||
color: #999999;
|
||||
}
|
||||
|
||||
.past-due-btn {
|
||||
width: 710rpx;
|
||||
height: 80rpx;
|
||||
border-radius: 40rpx;
|
||||
background-color: #999;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
</style>
|
310
pages/pay/worker/result.vue
Normal file
310
pages/pay/worker/result.vue
Normal file
@@ -0,0 +1,310 @@
|
||||
<!-- 支付结果页面 -->
|
||||
<template>
|
||||
<s-layout title="支付结果" :bgStyle="{ color: '#FFF' }">
|
||||
<view class="pay-result-box ss-flex-col ss-row-center ss-col-center">
|
||||
<!-- 信息展示 -->
|
||||
<view class="pay-waiting ss-m-b-30" v-if="payResult === 'waiting'" />
|
||||
<image
|
||||
class="pay-img ss-m-b-30"
|
||||
v-if="payResult === 'success'"
|
||||
:src="sheep.$url.static('/static/img/shop/order/order_pay_success.gif')"
|
||||
/>
|
||||
<image
|
||||
class="pay-img ss-m-b-30"
|
||||
v-if="['failed', 'closed'].includes(payResult)"
|
||||
:src="sheep.$url.static('/static/img/shop/order/order_paty_fail.gif')"
|
||||
/>
|
||||
<view class="tip-text ss-m-b-30" v-if="payResult === 'success'">支付成功</view>
|
||||
<view class="tip-text ss-m-b-30" v-if="payResult === 'failed'">支付失败</view>
|
||||
<view class="tip-text ss-m-b-30" v-if="payResult === 'closed'">该订单已关闭</view>
|
||||
<view class="tip-text ss-m-b-30" v-if="payResult === 'waiting'">检测支付结果...</view>
|
||||
<view class="pay-total-num ss-flex" v-if="payResult === 'success'">
|
||||
<view>¥{{ fen2yuan(state.orderInfo.price) }}</view>
|
||||
</view>
|
||||
|
||||
<!-- 操作区 -->
|
||||
<view class="btn-box ss-flex ss-row-center ss-m-t-50">
|
||||
<button class="back-btn ss-reset-button" @tap="sheep.$router.go('/pages/tabbar/index')">
|
||||
返回首页
|
||||
</button>
|
||||
<button
|
||||
class="check-btn ss-reset-button"
|
||||
v-if="payResult === 'failed'"
|
||||
@tap="
|
||||
sheep.$router.redirect('/pages/pay/worker/index', { id: state.id, orderType: state.orderType })
|
||||
"
|
||||
>
|
||||
重新支付
|
||||
</button>
|
||||
<button class="check-btn ss-reset-button" v-if="payResult === 'success'" @tap="onOrder">
|
||||
查看订单
|
||||
</button>
|
||||
</view>
|
||||
|
||||
<!-- #ifdef MP -->
|
||||
<view
|
||||
class="subscribe-box ss-flex ss-m-t-44"
|
||||
v-if="showSubscribeBtn && state.orderType === 'goods'"
|
||||
>
|
||||
<u-icon name="bell-fill" color="var(--ui-BG-Main)" size="44"></u-icon>
|
||||
<view class="subscribe-title ss-m-r-48 ss-m-l-16">获取实时接单信息与订单状态</view>
|
||||
<view class="subscribe-start" @tap="subscribeMessage">立即订阅</view>
|
||||
</view>
|
||||
<!-- #endif -->
|
||||
</view>
|
||||
</s-layout>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { onLoad, onHide, onShow } from '@dcloudio/uni-app';
|
||||
import { reactive, computed, ref } from 'vue';
|
||||
import { isEmpty } from 'lodash-es';
|
||||
import sheep from '@/sheep';
|
||||
import PayOrderApi from '@/sheep/api/pay/order';
|
||||
import { fen2yuan } from '@/sheep/hooks/useGoods';
|
||||
import OrderApi from '@/sheep/api/trade/order';
|
||||
import { WxaSubscribeTemplate } from '@/sheep/util/const';
|
||||
|
||||
const state = reactive({
|
||||
id: 0, // 支付单号
|
||||
orderType: 'goods', // 订单类型
|
||||
result: 'unpaid', // 支付状态
|
||||
orderInfo: {}, // 支付订单信息
|
||||
tradeOrder: {}, // 商品订单信息,只有在 orderType 为 goods 才会请求。目的:【我的拼团】按钮的展示
|
||||
counter: 0, // 获取结果次数
|
||||
});
|
||||
|
||||
// 支付结果 result => payResult
|
||||
const payResult = computed(() => {
|
||||
if (state.result === 'unpaid') {
|
||||
return 'waiting';
|
||||
}
|
||||
if (state.result === 'paid') {
|
||||
return 'success';
|
||||
}
|
||||
if (state.result === 'failed') {
|
||||
return 'failed';
|
||||
}
|
||||
if (state.result === 'closed') {
|
||||
return 'closed';
|
||||
}
|
||||
});
|
||||
|
||||
// 获得订单信息
|
||||
async function getOrderInfo(id) {
|
||||
state.counter++;
|
||||
// 1. 加载订单信息
|
||||
const { data, code } = await PayOrderApi.getOrder(id);
|
||||
if (code === 0) {
|
||||
state.orderInfo = data;
|
||||
if (!state.orderInfo || state.orderInfo.status === 30) {
|
||||
// 支付关闭
|
||||
state.result = 'closed';
|
||||
return;
|
||||
}
|
||||
if (state.orderInfo.status !== 0) {
|
||||
// 非待支付,可能是已支付,可能是已退款
|
||||
state.result = 'paid';
|
||||
// #ifdef MP
|
||||
uni.showModal({
|
||||
title: '支付结果',
|
||||
showCancel: false, // 不要取消按钮
|
||||
content: '支付成功',
|
||||
success: () => {
|
||||
// 订阅只能由用户主动触发,只能包一层 showModal 诱导用户点击
|
||||
autoSubscribeMessage();
|
||||
},
|
||||
});
|
||||
|
||||
// #endif
|
||||
// 特殊:获得商品订单信息
|
||||
if (state.orderType === 'goods') {
|
||||
const { data, code } = await OrderApi.getOrder(state.orderInfo.merchantOrderId);
|
||||
if (code === 0) {
|
||||
state.tradeOrder = data;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
// 2.1 情况三一:未支付,且轮询次数小于三次,则继续轮询
|
||||
if (state.counter < 3 && state.result === 'unpaid') {
|
||||
setTimeout(() => {
|
||||
getOrderInfo(id);
|
||||
}, 1500);
|
||||
}
|
||||
// 2.2 情况二:超过三次检测才判断为支付失败
|
||||
if (state.counter >= 3) {
|
||||
state.result = 'failed';
|
||||
}
|
||||
}
|
||||
|
||||
function onOrder() {
|
||||
if (state.orderType === 'recharge') {
|
||||
sheep.$router.redirect('/pages/pay/recharge-log');
|
||||
} else {
|
||||
sheep.$router.redirect('/pages/order/my/list');
|
||||
}
|
||||
}
|
||||
|
||||
// #ifdef MP
|
||||
const showSubscribeBtn = ref(false); // 默认隐藏
|
||||
const SUBSCRIBE_BTN_STATUS_STORAGE_KEY = 'subscribe_btn_status';
|
||||
function subscribeMessage() {
|
||||
if (state.orderType !== 'goods') {
|
||||
return;
|
||||
}
|
||||
const event = [WxaSubscribeTemplate.TRADE_ORDER_DELIVERY];
|
||||
if (state.tradeOrder.type === 3) {
|
||||
event.push(WxaSubscribeTemplate.PROMOTION_COMBINATION_SUCCESS);
|
||||
}
|
||||
sheep.$platform.useProvider('wechat').subscribeMessage(event, () => {
|
||||
// 订阅后记录一下订阅状态
|
||||
uni.removeStorageSync(SUBSCRIBE_BTN_STATUS_STORAGE_KEY);
|
||||
uni.setStorageSync(SUBSCRIBE_BTN_STATUS_STORAGE_KEY, '已订阅');
|
||||
// 隐藏订阅按钮
|
||||
showSubscribeBtn.value = false;
|
||||
});
|
||||
}
|
||||
async function autoSubscribeMessage() {
|
||||
// 1. 校验是否手动订阅过
|
||||
const subscribeBtnStatus = uni.getStorageSync(SUBSCRIBE_BTN_STATUS_STORAGE_KEY);
|
||||
if (!subscribeBtnStatus) {
|
||||
showSubscribeBtn.value = true;
|
||||
return;
|
||||
}
|
||||
|
||||
// 2. 订阅消息
|
||||
subscribeMessage();
|
||||
}
|
||||
// #endif
|
||||
|
||||
onLoad(async (options) => {
|
||||
// 支付订单号
|
||||
if (options.id) {
|
||||
state.id = options.id;
|
||||
}
|
||||
// 订单类型
|
||||
if (options.orderType) {
|
||||
state.orderType = options.orderType;
|
||||
}
|
||||
|
||||
// 支付结果传值过来是失败,则直接显示失败界面
|
||||
if (options.payState === 'fail') {
|
||||
state.result = 'failed';
|
||||
} else {
|
||||
// 轮询三次检测订单支付结果
|
||||
await getOrderInfo(state.id);
|
||||
}
|
||||
});
|
||||
|
||||
onShow(() => {
|
||||
if (isEmpty(state.orderInfo)) {
|
||||
return;
|
||||
}
|
||||
getOrderInfo(state.id);
|
||||
});
|
||||
|
||||
onHide(() => {
|
||||
state.result = 'unpaid';
|
||||
state.counter = 0;
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@keyframes rotation {
|
||||
0% {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
|
||||
100% {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
.score-img {
|
||||
width: 36rpx;
|
||||
height: 36rpx;
|
||||
margin: 0 4rpx;
|
||||
}
|
||||
|
||||
.pay-result-box {
|
||||
padding: 60rpx 0;
|
||||
|
||||
.pay-waiting {
|
||||
margin-top: 20rpx;
|
||||
width: 60rpx;
|
||||
height: 60rpx;
|
||||
border: 10rpx solid rgb(233, 231, 231);
|
||||
border-bottom-color: rgb(204, 204, 204);
|
||||
border-radius: 50%;
|
||||
display: inline-block;
|
||||
// -webkit-animation: rotation 1s linear infinite;
|
||||
animation: rotation 1s linear infinite;
|
||||
}
|
||||
|
||||
.pay-img {
|
||||
width: 130rpx;
|
||||
height: 130rpx;
|
||||
}
|
||||
|
||||
.tip-text {
|
||||
font-size: 30rpx;
|
||||
font-weight: bold;
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
.pay-total-num {
|
||||
font-size: 36rpx;
|
||||
font-weight: 500;
|
||||
color: #333333;
|
||||
font-family: OPPOSANS;
|
||||
}
|
||||
|
||||
.btn-box {
|
||||
width: 100%;
|
||||
|
||||
.back-btn {
|
||||
width: 190rpx;
|
||||
height: 70rpx;
|
||||
font-size: 28rpx;
|
||||
border: 2rpx solid #dfdfdf;
|
||||
border-radius: 35rpx;
|
||||
font-weight: 400;
|
||||
color: #595959;
|
||||
}
|
||||
|
||||
.check-btn {
|
||||
width: 190rpx;
|
||||
height: 70rpx;
|
||||
font-size: 28rpx;
|
||||
border: 2rpx solid #dfdfdf;
|
||||
border-radius: 35rpx;
|
||||
font-weight: 400;
|
||||
color: #595959;
|
||||
margin-left: 32rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.subscribe-box {
|
||||
.subscribe-img {
|
||||
width: 44rpx;
|
||||
height: 44rpx;
|
||||
}
|
||||
|
||||
.subscribe-title {
|
||||
font-weight: 500;
|
||||
font-size: 32rpx;
|
||||
line-height: 36rpx;
|
||||
color: #434343;
|
||||
}
|
||||
|
||||
.subscribe-start {
|
||||
color: var(--ui-BG-Main);
|
||||
font-weight: 700;
|
||||
font-size: 32rpx;
|
||||
line-height: 36rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
Reference in New Issue
Block a user