mirror of
https://gitee.com/bootx/dax-pay-h5.git
synced 2025-10-14 14:10:26 +00:00
feat 手机端收银台开发. vant安全区指令不生效修复
This commit is contained in:
12
components.d.ts
vendored
12
components.d.ts
vendored
@@ -9,12 +9,24 @@ declare module '@vue/runtime-core' {
|
|||||||
export interface GlobalComponents {
|
export interface GlobalComponents {
|
||||||
Loading: typeof import('./src/components/Loading/Loading.vue')['default']
|
Loading: typeof import('./src/components/Loading/Loading.vue')['default']
|
||||||
SvgIcon: typeof import('./src/components/SvgIcon/SvgIcon.vue')['default']
|
SvgIcon: typeof import('./src/components/SvgIcon/SvgIcon.vue')['default']
|
||||||
|
VanActionBar: typeof import('vant/es')['ActionBar']
|
||||||
|
VanActionBarButton: typeof import('vant/es')['ActionBarButton']
|
||||||
|
VanActionSheet: typeof import('vant/es')['ActionSheet']
|
||||||
VanButton: typeof import('vant/es')['Button']
|
VanButton: typeof import('vant/es')['Button']
|
||||||
|
VanCellGroup: typeof import('vant/es')['CellGroup']
|
||||||
VanConfigProvider: typeof import('vant/es')['ConfigProvider']
|
VanConfigProvider: typeof import('vant/es')['ConfigProvider']
|
||||||
|
VanField: typeof import('vant/es')['Field']
|
||||||
|
VanForm: typeof import('vant/es')['Form']
|
||||||
|
Vani: typeof import('vant/es')['i']
|
||||||
VanIcon: typeof import('vant/es')['Icon']
|
VanIcon: typeof import('vant/es')['Icon']
|
||||||
|
VanInput: typeof import('vant/es')['Input']
|
||||||
VanLoading: typeof import('vant/es')['Loading']
|
VanLoading: typeof import('vant/es')['Loading']
|
||||||
VanNavBar: typeof import('vant/es')['NavBar']
|
VanNavBar: typeof import('vant/es')['NavBar']
|
||||||
|
VanNumberKeyboard: typeof import('vant/es')['NumberKeyboard']
|
||||||
VanOverlay: typeof import('vant/es')['Overlay']
|
VanOverlay: typeof import('vant/es')['Overlay']
|
||||||
|
VanRadio: typeof import('vant/es')['Radio']
|
||||||
|
VanRadioGroup: typeof import('vant/es')['RadioGroup']
|
||||||
|
VanSwitch: typeof import('vant/es')['Switch']
|
||||||
VanTabbar: typeof import('vant/es')['Tabbar']
|
VanTabbar: typeof import('vant/es')['Tabbar']
|
||||||
VanTabbarItem: typeof import('vant/es')['TabbarItem']
|
VanTabbarItem: typeof import('vant/es')['TabbarItem']
|
||||||
}
|
}
|
||||||
|
@@ -3,7 +3,8 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
<link rel="icon" type="image/svg+xml" href="/logo.svg" />
|
<link rel="icon" type="image/svg+xml" href="/logo.svg" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<!-- 要使用安全区域,需要加上这个 viewport-fit=cover -->
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover" />
|
||||||
<title>
|
<title>
|
||||||
<%= title %>
|
<%= title %>
|
||||||
</title>
|
</title>
|
||||||
|
13
src/enums/payment/payChannelEnum.ts
Normal file
13
src/enums/payment/payChannelEnum.ts
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
/**
|
||||||
|
* 支付通道
|
||||||
|
*/
|
||||||
|
export enum payChannelEnum {
|
||||||
|
ALI = 'ali_pay',
|
||||||
|
WECHAT = 'wechat_pay',
|
||||||
|
UNION_PAY = 'union_pay',
|
||||||
|
CASH = 'cash_pay',
|
||||||
|
WALLET = 'wallet_pay',
|
||||||
|
VOUCHER = 'voucher_pay',
|
||||||
|
CREDIT_CARD = 'credit_pay',
|
||||||
|
AGGREGATION = 'aggregation_pay',
|
||||||
|
}
|
12
src/enums/payment/payWayEnum.ts
Normal file
12
src/enums/payment/payWayEnum.ts
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
/**
|
||||||
|
* 支付通道
|
||||||
|
*/
|
||||||
|
export enum payWayEnum {
|
||||||
|
NORMAL = 'normal',
|
||||||
|
WAP = 'wap',
|
||||||
|
APP = 'app',
|
||||||
|
WEB = 'web',
|
||||||
|
QRCODE = 'qrcode',
|
||||||
|
BARCODE = 'barcode',
|
||||||
|
JSAPI = 'jsapi',
|
||||||
|
}
|
@@ -42,7 +42,6 @@
|
|||||||
const currentRoute = useRoute()
|
const currentRoute = useRoute()
|
||||||
|
|
||||||
const getTitle = computed(() => currentRoute.meta.title as string)
|
const getTitle = computed(() => currentRoute.meta.title as string)
|
||||||
console.log(getTitle)
|
|
||||||
// 菜单
|
// 菜单
|
||||||
const getMenus = computed(() =>
|
const getMenus = computed(() =>
|
||||||
routeStore.menus.filter((item) => {
|
routeStore.menus.filter((item) => {
|
||||||
|
@@ -26,5 +26,13 @@ export const DemoRoute: RouteRecordRaw = {
|
|||||||
title: '微信聚合支付',
|
title: '微信聚合支付',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: '/cashier/uniCashier',
|
||||||
|
name: 'UniCashier',
|
||||||
|
component: () => import('@/views/demo/cashier/UniCashier.vue'),
|
||||||
|
meta: {
|
||||||
|
title: '手机收银台',
|
||||||
|
},
|
||||||
|
},
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
@@ -1,11 +0,0 @@
|
|||||||
<script setup lang="ts">
|
|
||||||
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<style scoped lang="less">
|
|
||||||
|
|
||||||
</style>
|
|
36
src/views/demo/cashier/Cashier.api.ts
Normal file
36
src/views/demo/cashier/Cashier.api.ts
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
import { http } from '@/utils/http/axios'
|
||||||
|
import { Result } from '#/axios'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取当前可用支付的环境
|
||||||
|
*/
|
||||||
|
export function getPayEnv(): Promise<Result<string>> {
|
||||||
|
return http.request({
|
||||||
|
url: '/demo/cashier/getPayEnv',
|
||||||
|
method: 'get',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 单独支付
|
||||||
|
*/
|
||||||
|
export function simplePayCashier(obj): Promise<Result<PayOrderResult>> {
|
||||||
|
return http.request({
|
||||||
|
url: '/demo/cashier/simplePayCashier',
|
||||||
|
method: 'post',
|
||||||
|
data: obj,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 发起支付后响应对象
|
||||||
|
*/
|
||||||
|
export interface PayOrderResult {
|
||||||
|
// 支付ID
|
||||||
|
paymentId: string
|
||||||
|
// 是否是异步支付
|
||||||
|
asyncPay: boolean
|
||||||
|
// 异步支付通道
|
||||||
|
asyncChannel: string
|
||||||
|
// 支付参数体(通常用于发起异步支付的参数)
|
||||||
|
payBody: string
|
||||||
|
}
|
193
src/views/demo/cashier/UniCashier.vue
Normal file
193
src/views/demo/cashier/UniCashier.vue
Normal file
@@ -0,0 +1,193 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<div class="flex justify-center h-screen pt-8">
|
||||||
|
<van-overlay lock-scroll :show="loading">
|
||||||
|
<Loading text="调起支付中..." />
|
||||||
|
</van-overlay>
|
||||||
|
<div class="flex flex-col w-full">
|
||||||
|
<div class="flex flex-col items-center justify-center">
|
||||||
|
<div class="logo my-35px enter-y">
|
||||||
|
<SvgIcon class="!h-250px !w-250px" name="logo" />
|
||||||
|
</div>
|
||||||
|
<div class="mb-80px text-darkBlue dark:text-garyWhite text-45px font-black enter-y">
|
||||||
|
手机收银台
|
||||||
|
</div>
|
||||||
|
<van-form ref="formRef">
|
||||||
|
<van-cell-group inset>
|
||||||
|
<van-field
|
||||||
|
v-model="amount"
|
||||||
|
type="number"
|
||||||
|
required
|
||||||
|
label="金额"
|
||||||
|
:rules="[
|
||||||
|
{ required: true, message: '请输入要支付的金额' },
|
||||||
|
{ pattern: /^\d+(\.\d{2})?$/, message: '金额最为多两位小数' },
|
||||||
|
{
|
||||||
|
validator: validatorAmount,
|
||||||
|
message: '请输入0.01-100之间的金额',
|
||||||
|
},
|
||||||
|
]"
|
||||||
|
/>
|
||||||
|
<van-field name="switch" label="过滤支付方式">
|
||||||
|
<template #input>
|
||||||
|
<van-switch v-model="filterChannelFlag" @change="initChannelList" size="24px" />
|
||||||
|
</template>
|
||||||
|
</van-field>
|
||||||
|
</van-cell-group>
|
||||||
|
</van-form>
|
||||||
|
<van-action-sheet
|
||||||
|
safe-area-inset-bottom
|
||||||
|
v-model:show="channelShow"
|
||||||
|
:actions="channelList"
|
||||||
|
@select="pay"
|
||||||
|
/>
|
||||||
|
<van-action-bar safe-area-inset-bottom>
|
||||||
|
<van-action-bar-button type="danger" text="支付" @click="paySelect" />
|
||||||
|
</van-action-bar>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script setup lang="ts">
|
||||||
|
import Loading from '@/components/Loading/Loading.vue'
|
||||||
|
import { onMounted, ref } from 'vue'
|
||||||
|
import SvgIcon from '@/components/SvgIcon/SvgIcon.vue'
|
||||||
|
import { getPayEnv, simplePayCashier } from '@/views/demo/cashier/Cashier.api'
|
||||||
|
import { ActionSheetAction } from 'vant'
|
||||||
|
import router from '@/router'
|
||||||
|
import { payChannelEnum } from '@/enums/payment/payChannelEnum'
|
||||||
|
import { payWayEnum } from "@/enums/payment/payWayEnum";
|
||||||
|
|
||||||
|
let loading = ref<boolean>(false)
|
||||||
|
let channelShow = ref<boolean>(false)
|
||||||
|
let filterChannelFlag = ref<boolean>(true)
|
||||||
|
let amount = ref<number>(0.01)
|
||||||
|
let formRef = ref<any>()
|
||||||
|
// 当前环境
|
||||||
|
let currentEnv = ref<string>('all')
|
||||||
|
|
||||||
|
const channelList = ref<ActionSheetAction[]>([])
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
init()
|
||||||
|
})
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 初始化
|
||||||
|
*/
|
||||||
|
async function init() {
|
||||||
|
await getPayEnv().then(({ data }) => {
|
||||||
|
currentEnv.value = data
|
||||||
|
})
|
||||||
|
initChannelList()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 初始化通道列表
|
||||||
|
*/
|
||||||
|
function initChannelList() {
|
||||||
|
channelList.value = [
|
||||||
|
{
|
||||||
|
name: '支付宝',
|
||||||
|
disabled: channelFilter(payChannelEnum.ALI),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '微信',
|
||||||
|
disabled: channelFilter(payChannelEnum.WECHAT),
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 过滤当前的状态是否可以使用
|
||||||
|
*/
|
||||||
|
function channelFilter(channel: string): boolean {
|
||||||
|
// 未开启过滤
|
||||||
|
if (!filterChannelFlag.value) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
// 返回为all
|
||||||
|
if (currentEnv.value === 'all') {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
// 如果返回通道, 只有当前符合环境的可以用
|
||||||
|
return currentEnv.value !== channel
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 校验支付金额
|
||||||
|
*/
|
||||||
|
function validatorAmount(input: string) {
|
||||||
|
if (parseFloat(input) >= 0.01 && parseFloat(input) <= 100) {
|
||||||
|
return Promise.resolve(true)
|
||||||
|
} else {
|
||||||
|
return Promise.resolve(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 调起支付选择
|
||||||
|
*/
|
||||||
|
function paySelect() {
|
||||||
|
// 校验表单
|
||||||
|
formRef.value.validate().then(() => {
|
||||||
|
// 拉起选择弹窗
|
||||||
|
channelShow.value = true
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发起支付
|
||||||
|
*/
|
||||||
|
function pay(value) {
|
||||||
|
if (value === '微信') {
|
||||||
|
wechatPay()
|
||||||
|
} else {
|
||||||
|
aliPay()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发起微信支付
|
||||||
|
* 1. 微信中使用jsapi
|
||||||
|
* 2. 外部浏览器使用wap支付
|
||||||
|
*/
|
||||||
|
function wechatPay() {
|
||||||
|
if (currentEnv.value === 'wechat_pay') {
|
||||||
|
wechatJsapiPay()
|
||||||
|
} else {
|
||||||
|
wechatH5Pay()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function wechatJsapiPay() {}
|
||||||
|
function wechatH5Pay() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 支付宝支付, 使用h5支付
|
||||||
|
*/
|
||||||
|
function aliPay() {
|
||||||
|
const from = {
|
||||||
|
businessNo: new Date().getTime(),
|
||||||
|
title: '测试H5支付',
|
||||||
|
amount: amount.value,
|
||||||
|
channel: payChannelEnum.ALI,
|
||||||
|
payWay: payWayEnum.WAP,
|
||||||
|
}
|
||||||
|
simplePayCashier(from)
|
||||||
|
.then(({ data }) => {
|
||||||
|
loading.value = false
|
||||||
|
// 跳转到H5支付页面
|
||||||
|
window.location.href = data.payBody
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
// 跳转到错误页
|
||||||
|
router.push({
|
||||||
|
name: 'PayErrorResult',
|
||||||
|
query: { msg: err.message },
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="less"></style>
|
@@ -1,11 +0,0 @@
|
|||||||
<script setup lang="ts">
|
|
||||||
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<style scoped lang="less">
|
|
||||||
|
|
||||||
</style>
|
|
Reference in New Issue
Block a user