refactor(daxpay): 重构收银台界面和支付流程- 更新了 AlipayAuth、WechatAuth、AlipayCashierCode、WechatCashierCode、AliAggregate、WechatAggregate 和 CheckoutPay 组件的结构和样式

- 优化了支付流程,增加了加载状态和错误处理
-调整了订单信息的展示方式,使其更加清晰和详细
- 统一了支付按钮的样式和行为
- 重构了部分 API 接口,增加了主键字段
This commit is contained in:
DaxPay
2024-12-04 19:22:55 +08:00
parent db4a87d3ae
commit 7f95a9bec3
10 changed files with 117 additions and 110 deletions

9
components.d.ts vendored
View File

@@ -11,8 +11,17 @@ declare module 'vue' {
Logo: typeof import('./src/components/Logo.vue')['default']
SvgIcon: typeof import('./src/components/SvgIcon.vue')['default']
VanButton: typeof import('vant/es')['Button']
VanCell: typeof import('vant/es')['Cell']
VanCellGroup: typeof import('vant/es')['CellGroup']
VanCol: typeof import('vant/es')['Col']
VanConfigProvider: typeof import('vant/es')['ConfigProvider']
VanField: typeof import('vant/es')['Field']
VanGrid: typeof import('vant/es')['Grid']
VanGridItem: typeof import('vant/es')['GridItem']
VanLoading: typeof import('vant/es')['Loading']
VanOverlay: typeof import('vant/es')['Overlay']
VanRow: typeof import('vant/es')['Row']
VanSpace: typeof import('vant/es')['Space']
VanSubmitBar: typeof import('vant/es')['SubmitBar']
}
}

View File

@@ -9,3 +9,10 @@ body {
.van-action-sheet__cancel {
color: var(--van-primary-color) !important;
}
.loading-wrapper {
display: flex;
align-items: center;
justify-content: center;
height: 100%;
}

View File

@@ -1,6 +1,6 @@
<template>
<van-overlay v-show="show" :show="true">
<div class="wrapper" @click.stop>
<div class="loading-wrapper" @click.stop>
<van-loading size="24px">
获取中...
</van-loading>
@@ -60,12 +60,6 @@ async function init() {
</script>
<style scoped lang="less">
.wrapper {
display: flex;
align-items: center;
justify-content: center;
height: 100%;
}
.block {
width: 120px;

View File

@@ -1,6 +1,6 @@
<template>
<van-overlay v-show="show" :show="true">
<div class="wrapper" @click.stop>
<div class="loading-wrapper" @click.stop>
<van-loading size="24px">
获取中...
</van-loading>
@@ -47,12 +47,6 @@ async function init() {
</script>
<style scoped lang="less">
.wrapper {
display: flex;
align-items: center;
justify-content: center;
height: 100%;
}
.block {
width: 120px;

View File

@@ -98,7 +98,7 @@ function initData() {
getCashierTypeConfig(CashierTypeEnum.ALIPAY, code as string).then(({ data }) => {
cashierTypeConfig.value = data
}).catch((res) => {
router.push({ name: 'ErrorResult', query: { msg: res.message } })
router.push({ name: 'ErrorResult', query: { msg: res.message }, replace: true })
})
}

View File

@@ -2,7 +2,7 @@
<div v-if="show">
<div class="container">
<div style="font-size: 28px;margin-top: 10px;">
{{ cashierTypeConfig.cashierName || '微信收银台' }}
{{ cashierTypeConfig.name || '微信收银台' }}
</div>
<div class="amount-display">
<p style="font-size: 20px">
@@ -114,7 +114,7 @@ function init() {
const url = res.data
location.replace(url)
}).catch((res) => {
router.push({ name: 'ErrorResult', query: { msg: res.message } })
router.push({ name: 'ErrorResult', query: { msg: res.message }, replace: true })
})
}
else {
@@ -133,14 +133,14 @@ function initData() {
getCashierTypeConfig(CashierTypeEnum.WECHAT_PAY, code as string).then(({ data }) => {
cashierTypeConfig.value = data
}).catch((res) => {
router.push({ name: 'ErrorResult', query: { msg: res.message } })
router.push({ name: 'ErrorResult', query: { msg: res.message }, replace: true })
})
// 认证获取OpenId
auth(authParam.value).then(({ data }) => {
openId.value = data.openId as string
}).catch((res) => {
router.push({ name: 'ErrorResult', query: { msg: res.message } })
router.push({ name: 'ErrorResult', query: { msg: res.message }, replace: true })
})
}

View File

@@ -174,8 +174,8 @@ export interface CheckoutConfigResult {
* 收银台分类配置
*/
export interface CheckoutGroupConfigResult {
/** 类型 */
type?: string
/** 主键 */
id?: string
/** 名称 */
name?: string
/** 配置项列表 */
@@ -186,6 +186,8 @@ export interface CheckoutGroupConfigResult {
* 收银台配置项
*/
export interface CheckoutItemConfigResult {
/** 主键 */
id?: string
/** 发起调用的类型 */
callType?: string
/** 名称 */

View File

@@ -1,13 +1,41 @@
<template>
<div v-if="show">
123
<van-overlay :show="loading">
<div class="loading-wrapper" @click.stop>
<van-loading size="24px">
支付中...
</van-loading>
</div>
</van-overlay>
<van-cell-group inset title="订单信息">
<van-cell title="金额" title-style="font-size: 22px;color: red">
<template #default>
<span style="font-size: 22px;color: red">{{ orderAndConfig.order.amount }}</span>
</template>
</van-cell>
<van-field label="标题" :model-value="orderAndConfig.order.title" readonly />
<van-field label="订单号" :model-value="orderAndConfig.order.bizOrderNo" readonly />
<van-field label="支付号" :model-value="orderAndConfig.order.orderNo" readonly />
<van-field label="描述" rows="2" type="textarea" :model-value="orderAndConfig.order.description" readonly />
</van-cell-group>
<van-cell-group inset :title="group.name" v-for="group in orderAndConfig.groupConfigs" :key="group.id">
<van-space direction="vertical" fill>
<van-button @click="pay(config)" type="primary" v-for="config in group.items" :key="config.id" block>{{ config.name }}</van-button>
</van-space>
</van-cell-group>
</div>
</template>
<script setup lang="ts">
import { useRoute } from 'vue-router'
import { onMounted, ref } from 'vue'
import type { CheckoutOrderAndConfigResult } from './CheckoutPay.api'
import {
CheckoutItemConfigResult,
CheckoutOrderAndConfigResult,
checkoutPay,
CheckoutPayParam
} from './CheckoutPay.api'
import { getOrderAndConfig } from './CheckoutPay.api'
import { CheckoutTypeEnum } from '@/enums/daxpay/DaxPayEnum'
import router from '@/router'
@@ -17,12 +45,14 @@ const route = useRoute()
const { orderNo } = route.params
const ua = navigator.userAgent
const show = ref(false)
const loading = ref(false)
const orderAndConfig = ref<CheckoutOrderAndConfigResult>({
order: {},
config: {},
groupConfigs: [],
})
/**
* 初始化
*/
@@ -37,10 +67,13 @@ async function initData() {
// 获取收银台配置
await getOrderAndConfig(orderNo, CheckoutTypeEnum.H5).then(({ data }) => {
orderAndConfig.value = data
}).catch((res) => {
router.push({ name: 'ErrorResult', query: { msg: res.message }, replace: true })
})
// 判断是否自动升级为聚合控制台
if (orderAndConfig.value.config.h5AutoUpgrade) {
await goAggregate()
goAggregate()
return
}
show.value = true
}
@@ -54,14 +87,25 @@ function goAggregate() {
}
else if (ua.includes('Alipay')) {
router.push({ path: `/aggregate/alipay/${orderNo}`, replace: true })
} else {
show.value = true
}
}
/**
* 发起支付
*/
function pay(){
function pay(config: CheckoutItemConfigResult){
loading.value = true
const from = {
orderNo: orderNo,
itemId: config.id
} as CheckoutPayParam
checkoutPay(from).then(({data}) => {
loading.value = false
// 跳转到支付页面
location.replace(data.payBody)
})
}
</script>

View File

@@ -1,19 +1,24 @@
<template>
<div>
<div class="container">
<div style="font-size: 28px;margin-top: 10px;">
{{ aggregateInfo.config.name || '支付宝收银台' }}
<van-overlay :show="loading">
<div class="loading-wrapper" @click.stop>
<van-loading size="24px">
支付中...
</van-loading>
</div>
<div class="amount-display">
<p style="font-size: 20px">
订单
</p>
<p style="font-size: 32px;">
¥ {{ aggregateInfo.order.amount || 0.00 }}
</p>
</div>
</div>
<van-submit-bar :price="(aggregateInfo.order.amount || 0)*100" button-text="支付" @submit="pay" />
</van-overlay>
<van-cell-group inset title="订单信息">
<van-cell title="金额" title-style="font-size: 22px;color: red">
<template #default>
<span style="font-size: 22px;color: red">{{ aggregateInfo.order.amount }}</span>
</template>
</van-cell>
<van-field label="标题" :model-value="aggregateInfo.order.title" readonly />
<van-field label="订单号" :model-value="aggregateInfo.order.bizOrderNo" readonly />
<van-field label="支付号" :model-value="aggregateInfo.order.orderNo" readonly />
<van-field label="描述" rows="2" type="textarea" :model-value="aggregateInfo.order.description" readonly />
</van-cell-group>
<van-submit-bar safe-area-inset-bottom :price="(aggregateInfo.order.amount || 0)*100" button-text="支付" @submit="pay" />
</div>
</template>
@@ -54,7 +59,7 @@ async function initData() {
await getAggregateConfig(orderNo, CheckoutAggregateEnum.ALI).then(({ data }) => {
aggregateInfo.value = data
}).catch((res) => {
router.push({ name: 'ErrorResult', query: { msg: res.message } })
router.push({ name: 'ErrorResult', query: { msg: res.message }, replace: true })
})
// 判断是否自动拉起支付
if (aggregateInfo.value.aggregateConfig.autoLaunch) {
@@ -81,30 +86,4 @@ function pay() {
</script>
<style scoped lang="less">
@color: #108ee9;
:deep(.van-key--blue) {
background: @color;
}
.container {
background-color: @color;
width: 100%;
padding: 10px;
border-radius: 10px;
text-align: center;
color: white;
.amount-display {
background-color: white;
color: @color;
border-radius: 20px;
padding: 20px;
margin: 20px 0;
}
.amount-display p {
margin: 5px 0;
}
}
.remark {
color: @color;
}
</style>

View File

@@ -1,19 +1,24 @@
<template>
<div v-if="show">
<div class="container">
<div style="font-size: 28px;margin-top: 10px;">
{{ aggregateInfo.config.name || '微信收银台' }}
<van-overlay :show="loading">
<div class="loading-wrapper" @click.stop>
<van-loading size="24px">
支付中...
</van-loading>
</div>
<div class="amount-display">
<p style="font-size: 20px">
金额
</p>
<p style="font-size: 32px;">
¥ {{ aggregateInfo.order.amount || 0.00 }}
</p>
</div>
</div>
<van-submit-bar :price="(aggregateInfo.order.amount || 0)*100" button-text="支付" @submit="pay" />
</van-overlay>
<van-cell-group inset>
<van-cell title="金额" title-style="font-size: 22px;color: red">
<template #default>
<span style="font-size: 22px;color: red">{{ aggregateInfo.order.amount }}</span>
</template>
</van-cell>
<van-field label="标题" :model-value="aggregateInfo.order.title" readonly />
<van-field label="订单号" :model-value="aggregateInfo.order.bizOrderNo" readonly />
<van-field label="支付号" :model-value="aggregateInfo.order.orderNo" readonly />
<van-field label="描述" rows="2" type="textarea" :model-value="aggregateInfo.order.description" readonly />
</van-cell-group>
<van-submit-bar safe-area-inset-bottom :price="(aggregateInfo.order.amount || 0)*100" button-text="支付" @submit="pay" />
</div>
</template>
@@ -26,9 +31,8 @@ import router from '@/router'
import {
AggregateOrderAndConfigResult, aggregatePay, CheckoutAggregatePayParam,
CheckoutAuthCodeParam,
CheckoutPayParam,
} from '@/views/daxpay/checkout/CheckoutPay.api'
import { auth, checkoutPay, generateAuthUrl, getAggregateConfig } from '@/views/daxpay/checkout/CheckoutPay.api'
import { auth, generateAuthUrl, getAggregateConfig } from '@/views/daxpay/checkout/CheckoutPay.api'
import type { WxJsapiSignResult } from '@/views/daxpay/cashier/CashierCode.api'
@@ -68,7 +72,7 @@ function init() {
const url = res.data
location.replace(url)
}).catch((res) => {
router.push({ name: 'ErrorResult', query: { msg: res.message } })
router.push({ name: 'ErrorResult', query: { msg: res.message }, replace: true })
})
}
else {
@@ -87,14 +91,14 @@ async function initData() {
getAggregateConfig(orderNo, CheckoutAggregateEnum.WECHAT).then(({ data }) => {
aggregateInfo.value = data
}).catch((res) => {
router.push({ name: 'ErrorResult', query: { msg: res.message } })
router.push({ name: 'ErrorResult', query: { msg: res.message }, replace: true })
})
// 认证获取OpenId
await auth(authParam.value).then(({ data }) => {
openId.value = data.openId as string
}).catch((res) => {
router.push({ name: 'ErrorResult', query: { msg: res.message } })
router.push({ name: 'ErrorResult', query: { msg: res.message }, replace: true })
})
// 判断是否自动拉起支付
if (aggregateInfo.value.aggregateConfig.autoLaunch) {
@@ -144,30 +148,4 @@ function jsapiPay(data: WxJsapiSignResult) {
</script>
<style scoped lang="less">
@color: #4caf50;
:deep(.van-key--blue) {
background: @color;
}
.container {
background-color: @color;
width: 100%;
padding: 10px;
border-radius: 10px;
text-align: center;
color: white;
.amount-display {
background-color: white;
color: @color;
border-radius: 20px;
padding: 20px;
margin: 20px 0;
}
.amount-display p {
margin: 5px 0;
}
}
.remark {
color: @color;
}
</style>