mirror of
https://gitee.com/bootx/dax-pay-h5.git
synced 2025-08-29 08:43:54 +00:00
Compare commits
2 Commits
eba5d77b45
...
33f0228655
Author | SHA1 | Date | |
---|---|---|---|
![]() |
33f0228655 | ||
![]() |
1e503b80b9 |
@@ -5,7 +5,7 @@ VITE_PORT=9100
|
||||
VITE_PUBLIC_PATH=/h5
|
||||
|
||||
# 跨域代理,可以配置多个,请注意不要换行
|
||||
VITE_PROXY=[["/server","http://localhost:10880"]]
|
||||
VITE_PROXY=[["/server","http://localhost:9999"]]
|
||||
|
||||
# API 接口地址
|
||||
VITE_GLOB_API_URL=
|
||||
|
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<vanConfigProvider :theme="getDarkMode" :theme-vars="getThemeVars()">
|
||||
<vanConfigProvider :theme="darkMode" :theme-vars="getThemeVars()">
|
||||
<routerView v-slot="{ Component }">
|
||||
<div class="absolute bottom-0 top-0 w-full overflow-hidden">
|
||||
<transition :name="getTransitionName" mode="out-in" appear>
|
||||
@@ -18,8 +18,10 @@ import { useRouteStore } from '@/store/modules/route'
|
||||
import { useDesignSetting } from '@/hooks/setting/useDesignSetting'
|
||||
|
||||
const routeStore = useRouteStore()
|
||||
const { getDarkMode, getAppTheme, getIsPageAnimate, getPageAnimateType } = useDesignSetting()
|
||||
|
||||
const { getAppTheme, getIsPageAnimate, getPageAnimateType } = useDesignSetting()
|
||||
// 读取是否为夜间模式
|
||||
const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)')
|
||||
const darkMode = mediaQuery.matches ? 'dark' : 'light'
|
||||
// 需要缓存的路由组件
|
||||
const keepAliveComponents = computed(() => routeStore.keepAliveComponents)
|
||||
|
||||
|
@@ -4,8 +4,6 @@ import { useDesignSettingStore } from '@/store/modules/designSetting'
|
||||
export function useDesignSetting() {
|
||||
const designStore = useDesignSettingStore()
|
||||
|
||||
const getDarkMode = computed(() => designStore.darkMode)
|
||||
|
||||
const getAppTheme = computed(() => designStore.appTheme)
|
||||
|
||||
const getAppThemeList = computed(() => designStore.appThemeList)
|
||||
@@ -15,7 +13,6 @@ export function useDesignSetting() {
|
||||
const getPageAnimateType = computed(() => designStore.pageAnimateType)
|
||||
|
||||
return {
|
||||
getDarkMode,
|
||||
getAppTheme,
|
||||
getAppThemeList,
|
||||
getIsPageAnimate,
|
||||
|
@@ -13,7 +13,7 @@ export const DaxPayRoute: RouteRecordRaw = {
|
||||
{
|
||||
path: '/alipay/auth/:appId/:channel/:queryCode/:aliAppId',
|
||||
name: 'AlipayAuth',
|
||||
component: () => import('@/views/daxpay/channel/alipay/auth/AlipayAuth.vue'),
|
||||
component: () => import('@/views/daxpay/auth/alipay/AlipayAuth.vue'),
|
||||
meta: {
|
||||
title: '支付宝信息获取',
|
||||
},
|
||||
@@ -21,7 +21,7 @@ export const DaxPayRoute: RouteRecordRaw = {
|
||||
{
|
||||
path: '/wechat/auth/:appId/:channel/:queryCode',
|
||||
name: 'WechatAuth',
|
||||
component: () => import('@/views/daxpay/channel/wechat/auth/WechatAuth.vue'),
|
||||
component: () => import('@/views/daxpay/auth/wechat/WechatAuth.vue'),
|
||||
meta: {
|
||||
title: '微信信息获取',
|
||||
},
|
||||
@@ -29,7 +29,7 @@ export const DaxPayRoute: RouteRecordRaw = {
|
||||
{
|
||||
path: '/channel/cashier/:appId',
|
||||
name: 'ChannelCashier',
|
||||
component: () => import('@/views/daxpay/channel/ChannelCashier.vue'),
|
||||
component: () => import('@/views/daxpay/cashier/ChannelCashier.vue'),
|
||||
meta: {
|
||||
title: '收银台',
|
||||
},
|
||||
@@ -37,7 +37,7 @@ export const DaxPayRoute: RouteRecordRaw = {
|
||||
{
|
||||
path: '/alipay/cashier/:appId',
|
||||
name: 'AlipayCashier',
|
||||
component: () => import('@/views/daxpay/channel/alipay/cashier/AlipayCashier.vue'),
|
||||
component: () => import('@/views/daxpay/cashier/alipay/AlipayCashier.vue'),
|
||||
meta: {
|
||||
title: '支付宝收银台',
|
||||
},
|
||||
@@ -45,7 +45,7 @@ export const DaxPayRoute: RouteRecordRaw = {
|
||||
{
|
||||
path: '/wechat/cashier/:appId',
|
||||
name: 'WechatCashier',
|
||||
component: () => import('@/views/daxpay/channel/wechat/cashier/WechatCashier.vue'),
|
||||
component: () => import('@/views/daxpay/cashier/wechat/WechatCashier.vue'),
|
||||
meta: {
|
||||
title: '微信收银台',
|
||||
},
|
||||
|
@@ -1,8 +1,6 @@
|
||||
// app theme preset color
|
||||
|
||||
export interface DesignSettingState {
|
||||
// 系统主题
|
||||
darkMode: 'light' | 'dark'
|
||||
// 系统风格
|
||||
appTheme: string
|
||||
// 系统内置风格
|
||||
@@ -36,8 +34,6 @@ export const appThemeList: string[] = [
|
||||
]
|
||||
|
||||
const setting: DesignSettingState = {
|
||||
// 深色主题
|
||||
darkMode: 'dark',
|
||||
// 系统主题色
|
||||
appTheme: '#5d9dfe',
|
||||
// 系统内置主题色列表
|
||||
|
@@ -3,21 +3,17 @@ import { store } from '@/store'
|
||||
import designSetting from '@/settings/designSetting'
|
||||
import type { DesignSettingState } from '@/settings/designSetting'
|
||||
|
||||
const { darkMode, appTheme, appThemeList, isPageAnimate, pageAnimateType } = designSetting
|
||||
const { appTheme, appThemeList, isPageAnimate, pageAnimateType } = designSetting
|
||||
|
||||
export const useDesignSettingStore = defineStore({
|
||||
id: 'app-design-setting',
|
||||
state: (): DesignSettingState => ({
|
||||
darkMode,
|
||||
appTheme,
|
||||
appThemeList,
|
||||
isPageAnimate,
|
||||
pageAnimateType,
|
||||
}),
|
||||
getters: {
|
||||
getDarkMode(): 'light' | 'dark' {
|
||||
return this.darkMode
|
||||
},
|
||||
getAppTheme(): string {
|
||||
return this.appTheme
|
||||
},
|
||||
@@ -32,9 +28,6 @@ export const useDesignSettingStore = defineStore({
|
||||
},
|
||||
},
|
||||
actions: {
|
||||
setDarkMode(mode: 'light' | 'dark'): void {
|
||||
this.darkMode = mode
|
||||
},
|
||||
setPageAnimateType(type: string): void {
|
||||
this.pageAnimateType = type
|
||||
},
|
||||
|
@@ -12,8 +12,8 @@
|
||||
import { useRoute } from 'vue-router'
|
||||
import { ref } from 'vue'
|
||||
import { showDialog } from 'vant'
|
||||
import type { AuthCodeParam } from '@/views/daxpay/channel/ChannelAuth.api'
|
||||
import { authAndSet } from '@/views/daxpay/channel/ChannelAuth.api'
|
||||
import type { AuthCodeParam } from '@/views/daxpay/auth/ChannelAuth.api'
|
||||
import { authAndSet } from '@/views/daxpay/auth/ChannelAuth.api'
|
||||
|
||||
const script = document.createElement('script')
|
||||
script.setAttribute(
|
@@ -12,8 +12,8 @@
|
||||
import { useRoute } from 'vue-router'
|
||||
import { onMounted, ref } from 'vue'
|
||||
import { showDialog } from 'vant'
|
||||
import type { AuthCodeParam } from '@/views/daxpay/channel/ChannelAuth.api'
|
||||
import { authAndSet } from '@/views/daxpay/channel/ChannelAuth.api'
|
||||
import type { AuthCodeParam } from '@/views/daxpay/auth/ChannelAuth.api'
|
||||
import { authAndSet } from '@/views/daxpay/auth/ChannelAuth.api'
|
||||
|
||||
const route = useRoute()
|
||||
const { appId, channel, queryCode } = route.params
|
@@ -1,4 +1,4 @@
|
||||
import type { AuthResult } from './ChannelAuth.api'
|
||||
import type { AuthResult } from '../auth/ChannelAuth.api'
|
||||
import { http } from '@/utils/http/axios'
|
||||
import type { Result } from '#/axios'
|
||||
|
@@ -66,11 +66,11 @@ import { showNotify } from 'vant'
|
||||
import type {
|
||||
CashierPayParam,
|
||||
ChannelCashierConfigResult,
|
||||
} from '@/views/daxpay/channel/ChannelCashier.api'
|
||||
} from '@/views/daxpay/cashier/ChannelCashier.api'
|
||||
import {
|
||||
cashierPay,
|
||||
getCashierInfo,
|
||||
} from '@/views/daxpay/channel/ChannelCashier.api'
|
||||
} from '@/views/daxpay/cashier/ChannelCashier.api'
|
||||
|
||||
import { CashierTypeEnum } from '@/enums/daxpay/DaxPayEnum'
|
||||
import router from '@/router'
|
@@ -68,13 +68,13 @@ import type {
|
||||
CashierPayParam,
|
||||
ChannelCashierConfigResult,
|
||||
WxJsapiSignResult,
|
||||
} from '@/views/daxpay/channel/ChannelCashier.api'
|
||||
} from '@/views/daxpay/cashier/ChannelCashier.api'
|
||||
import {
|
||||
auth
|
||||
, cashierPay,
|
||||
generateAuthUrl,
|
||||
getCashierInfo,
|
||||
} from '@/views/daxpay/channel/ChannelCashier.api'
|
||||
} from '@/views/daxpay/cashier/ChannelCashier.api'
|
||||
|
||||
import { CashierTypeEnum } from '@/enums/daxpay/DaxPayEnum'
|
||||
import router from '@/router'
|
@@ -1,63 +0,0 @@
|
||||
import { http } from '@/utils/http/axios'
|
||||
import type { Result } from '#/axios'
|
||||
|
||||
/**
|
||||
* 获取支付信息
|
||||
*/
|
||||
export function getInfo(code): Promise<Result<AggregatePayInfo>> {
|
||||
return http.request({
|
||||
url: '/demo/aggregate/getInfo',
|
||||
method: 'get',
|
||||
params: { code },
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 支付宝h5支付
|
||||
*/
|
||||
export function aliH5Pay(code): Promise<Result<PayOrderResult>> {
|
||||
return http.request({
|
||||
url: '/demo/aggregate/aliH5Pay',
|
||||
method: 'post',
|
||||
params: { code },
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取微信H5预支付签名信息
|
||||
*/
|
||||
export function getWxJsapiPay(aggregateCode, openId): Promise<Result<WxJsapiSignResult>> {
|
||||
return http.request({
|
||||
url: '/demo/aggregate/getWxJsapiPay',
|
||||
method: 'post',
|
||||
params: { aggregateCode, openId },
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
*支付信息
|
||||
*/
|
||||
export interface AggregatePayInfo {
|
||||
title?: string
|
||||
bizOrderNo?: string
|
||||
amount: number
|
||||
}
|
||||
|
||||
/**
|
||||
* 发起支付后响应对象
|
||||
*/
|
||||
export interface PayOrderResult {
|
||||
payBody: string
|
||||
}
|
||||
|
||||
/**
|
||||
* 微信Jsapi预支付签名返回信息
|
||||
*/
|
||||
export interface WxJsapiSignResult {
|
||||
appId?: string
|
||||
timeStamp?: string
|
||||
nonceStr?: string
|
||||
signType?: string
|
||||
paySign?: string
|
||||
package?: string
|
||||
}
|
@@ -1,95 +0,0 @@
|
||||
<template>
|
||||
<div class="page-container flex flex-col justify-center">
|
||||
<van-overlay lock-scroll :show="loading">
|
||||
<Loading text="调起支付中..." />
|
||||
</van-overlay>
|
||||
<div class="text-center">
|
||||
<h1>金额: {{ info.amount / 100.0 }} 元</h1>
|
||||
<h1>标题: {{ info.title }}</h1>
|
||||
<h1>业务号: {{ info.businessNo }}</h1>
|
||||
</div>
|
||||
<div class="text-center">
|
||||
<van-button type="primary" @click="pay">
|
||||
去支付
|
||||
</van-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { onMounted, ref, unref } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import type { AggregatePayInfo } from './Aggregate.api'
|
||||
import { aliH5Pay, getInfo } from './Aggregate.api'
|
||||
import router from '@/router'
|
||||
import Loading from '@/components/Loading.vue'
|
||||
|
||||
onMounted(() => {
|
||||
init()
|
||||
})
|
||||
|
||||
const { currentRoute } = useRouter()
|
||||
const { query } = unref(currentRoute)
|
||||
|
||||
const loading = ref<boolean>(false)
|
||||
const code = ref<string>(query.code as string)
|
||||
const info = ref<AggregatePayInfo>({ amount: 0 })
|
||||
|
||||
/**
|
||||
* 根据code获取支付信息
|
||||
*/
|
||||
async function init() {
|
||||
loading.value = true
|
||||
await getInfo(code.value)
|
||||
.then(({ data }) => {
|
||||
info.value = data
|
||||
loading.value = false
|
||||
})
|
||||
.catch((err) => {
|
||||
// 跳转到错误页
|
||||
router.push({
|
||||
name: 'PayErrorResult',
|
||||
query: { msg: err.message },
|
||||
})
|
||||
})
|
||||
// 调起支付
|
||||
pay()
|
||||
}
|
||||
|
||||
/**
|
||||
* 发起支付
|
||||
*/
|
||||
function pay() {
|
||||
loading.value = true
|
||||
aliH5Pay(code.value)
|
||||
.then(({ data }) => {
|
||||
loading.value = false
|
||||
// 跳转到H5支付页面
|
||||
window.location.href = data.payBody
|
||||
})
|
||||
.catch((err) => {
|
||||
// 跳转到错误页
|
||||
router.push({
|
||||
name: 'PayErrorResult',
|
||||
query: { msg: err.message },
|
||||
})
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.page-container {
|
||||
width: 100%;
|
||||
border-radius: 4px;
|
||||
padding: 50px 0;
|
||||
height: 100vh;
|
||||
|
||||
.text-center {
|
||||
h1 {
|
||||
color: #666;
|
||||
padding: 2vh 0;
|
||||
font-size: x-large;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
@@ -1,118 +0,0 @@
|
||||
<template>
|
||||
<div class="page-container flex flex-col justify-center">
|
||||
<van-overlay lock-scroll :show="loading">
|
||||
<Loading text="调起支付中..." />
|
||||
</van-overlay>
|
||||
<div class="text-center">
|
||||
<h1>金额: {{ info.amount / 100.0 }} 元</h1>
|
||||
<h1>标题: {{ info.title }}</h1>
|
||||
<h1>订单号: {{ info.bizOrderNo }}</h1>
|
||||
</div>
|
||||
<div class="text-center">
|
||||
<van-button type="primary" @click="pay">
|
||||
去支付
|
||||
</van-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { onMounted, ref, unref } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import type { AggregatePayInfo, WxJsapiSignResult } from './Aggregate.api'
|
||||
import { getInfo, getWxJsapiPay } from './Aggregate.api'
|
||||
import router from '@/router'
|
||||
import Loading from '@/components/Loading.vue'
|
||||
|
||||
const { currentRoute } = useRouter()
|
||||
const { query } = unref(currentRoute)
|
||||
|
||||
const aggregateCode = ref<string>(query.aggregateCode as string)
|
||||
const openId = ref<string>(query.openId as string)
|
||||
const info = ref<AggregatePayInfo>({ amount: 0 })
|
||||
const loading = ref<boolean>(false)
|
||||
|
||||
onMounted(() => {
|
||||
init()
|
||||
})
|
||||
|
||||
/**
|
||||
* 根据code获取支付信息
|
||||
*/
|
||||
async function init() {
|
||||
loading.value = true
|
||||
// 获取支付信息
|
||||
await getInfo(aggregateCode.value)
|
||||
.then(({ data }) => {
|
||||
loading.value = false
|
||||
info.value = data
|
||||
})
|
||||
.catch((err) => {
|
||||
// 跳转到错误页
|
||||
router.push({
|
||||
name: 'PayErrorResult',
|
||||
query: { msg: err.message },
|
||||
})
|
||||
})
|
||||
// 调起支付
|
||||
pay()
|
||||
}
|
||||
|
||||
/**
|
||||
* 发起支付
|
||||
*/
|
||||
function pay() {
|
||||
loading.value = true
|
||||
getWxJsapiPay(aggregateCode.value, openId.value)
|
||||
.then(({ data }) => {
|
||||
loading.value = false
|
||||
doPay(data)
|
||||
})
|
||||
.catch(() => {
|
||||
// 跳转到错误页
|
||||
router.push({
|
||||
name: 'PayErrorResult',
|
||||
query: { msg: '支付失败' },
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 拉起支付
|
||||
*/
|
||||
function doPay(data: WxJsapiSignResult) {
|
||||
const form = {
|
||||
appId: data.appId, // 公众号ID,由商户传入
|
||||
timeStamp: data.timeStamp, // 时间戳,自1970年以来的秒数
|
||||
nonceStr: data.nonceStr, // 随机串
|
||||
package: data.package, // 预支付ID
|
||||
signType: data.signType, // 微信签名方式:
|
||||
paySign: data.paySign, // 微信签名
|
||||
}
|
||||
// 使用微信JsSdk拉起支付
|
||||
WeixinJSBridge.invoke('getBrandWCPayRequest', form, (res) => {
|
||||
if (res.err_msg === 'get_brand_wcpay_request:ok') {
|
||||
setTimeout(() => {
|
||||
WeixinJSBridge.call('closeWindow')
|
||||
}, 0)
|
||||
}
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.page-container {
|
||||
width: 100%;
|
||||
border-radius: 4px;
|
||||
padding: 50px 0;
|
||||
height: 100vh;
|
||||
|
||||
.text-center {
|
||||
h1 {
|
||||
color: #666;
|
||||
padding: 2vh 0;
|
||||
font-size: x-large;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
@@ -1,41 +0,0 @@
|
||||
import { http } from '@/utils/http/axios'
|
||||
import type { Result } from '#/axios'
|
||||
|
||||
/**
|
||||
* 获取当前可用支付的环境
|
||||
*/
|
||||
export function getPayEnv(): Promise<Result<string>> {
|
||||
return http.request({
|
||||
url: '/demo/cashier/getPayEnv',
|
||||
method: 'get',
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取微信授权请求页URL
|
||||
*/
|
||||
export function getWxAuthUrl(): Promise<Result<string>> {
|
||||
return http.request({
|
||||
url: '/demo/cashier/getWxAuthUrl',
|
||||
method: 'get',
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 单独支付
|
||||
*/
|
||||
export function simplePayCashier(obj): Promise<Result<PayOrderResult>> {
|
||||
return http.request({
|
||||
url: '/demo/cashier/simplePayCashier',
|
||||
method: 'post',
|
||||
data: obj,
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 发起支付后响应对象
|
||||
*/
|
||||
export interface PayOrderResult {
|
||||
// 支付参数体(通常用于发起异步支付的参数)
|
||||
payBody: string
|
||||
}
|
@@ -1,295 +0,0 @@
|
||||
<template>
|
||||
<div v-show="pageShow">
|
||||
<div class="h-screen flex justify-center pt-8">
|
||||
<van-overlay lock-scroll :show="loading">
|
||||
<Loading text="调起支付中..." />
|
||||
</van-overlay>
|
||||
<div class="w-full flex flex-col">
|
||||
<div class="flex flex-col items-center justify-center">
|
||||
<div class="logo enter-y my-35px">
|
||||
<SvgIcon class="!h-150px !w-150px" name="logo" />
|
||||
</div>
|
||||
<div class="text-darkBlue dark:text-garyWhite enter-y mb-80px text-45px font-black">
|
||||
手机收银台
|
||||
</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" size="24px" @change="initChannelList" />
|
||||
</template>
|
||||
</van-field>
|
||||
</van-cell-group>
|
||||
</van-form>
|
||||
<van-action-sheet
|
||||
v-model:show="channelShow"
|
||||
safe-area-inset-bottom
|
||||
: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 { onMounted, ref, unref } from 'vue'
|
||||
import type { ActionSheetAction } from 'vant'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { getPayEnv, getWxAuthUrl, simplePayCashier } from '@/views/demo/cashier/Cashier.api'
|
||||
import router from '@/router'
|
||||
import { payChannelEnum } from '@/enums/payment/payChannelEnum'
|
||||
import { payMethodEnum } from '@/enums/payment/payMethodEnum'
|
||||
import type { WxJsapiSignResult } from '@/views/demo/aggregate/Aggregate.api'
|
||||
import Loading from '@/components/Loading.vue'
|
||||
|
||||
const pageShow = ref<boolean>(false)
|
||||
const loading = ref<boolean>(false)
|
||||
const channelShow = ref<boolean>(false)
|
||||
const filterChannelFlag = ref<boolean>(true)
|
||||
const amount = ref<number>(0.01)
|
||||
const formRef = ref<any>()
|
||||
// 当前环境
|
||||
const currentEnv = ref<string>('all')
|
||||
const openId = ref<string>('')
|
||||
|
||||
const channelList = ref<ActionSheetAction[]>([])
|
||||
|
||||
const { currentRoute } = useRouter()
|
||||
const { query } = unref(currentRoute)
|
||||
|
||||
onMounted(() => {
|
||||
init()
|
||||
})
|
||||
|
||||
/**
|
||||
* 初始化
|
||||
*/
|
||||
async function init() {
|
||||
await getPayEnv().then(({ data }) => {
|
||||
currentEnv.value = data
|
||||
})
|
||||
// 是否在微信环境中. 在的话获取微信授权
|
||||
if (currentEnv.value === payChannelEnum.WECHAT) {
|
||||
const source = query.source as string
|
||||
// 重定向则获取OpenId
|
||||
if (source === 'redirect') {
|
||||
openId.value = query.openId as string
|
||||
}
|
||||
else {
|
||||
// 跳转到微信授权地址
|
||||
const { data: url } = await getWxAuthUrl()
|
||||
location.replace(url)
|
||||
return
|
||||
}
|
||||
}
|
||||
initChannelList()
|
||||
pageShow.value = true
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化通道列表
|
||||
*/
|
||||
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 (Number.parseFloat(input) >= 0.01 && Number.parseFloat(input) <= 100) {
|
||||
return Promise.resolve(true)
|
||||
}
|
||||
else {
|
||||
return Promise.resolve(false)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 调起支付选择
|
||||
*/
|
||||
function paySelect() {
|
||||
// 校验表单
|
||||
formRef.value.validate().then(() => {
|
||||
// 拉起选择弹窗
|
||||
channelShow.value = true
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 发起支付
|
||||
*/
|
||||
function pay(action: ActionSheetAction) {
|
||||
if (action.name === '微信') {
|
||||
wechatPay()
|
||||
}
|
||||
else {
|
||||
aliPay()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 发起微信支付
|
||||
* 1. 微信中使用jsapi
|
||||
* 2. 外部浏览器使用wap支付
|
||||
*/
|
||||
function wechatPay() {
|
||||
if (currentEnv.value === 'wechat_pay') {
|
||||
wechatJsapiPay()
|
||||
}
|
||||
else {
|
||||
wechatH5Pay()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 微信jsapi方式支付
|
||||
*/
|
||||
function wechatJsapiPay() {
|
||||
loading.value = true
|
||||
const from = {
|
||||
bizOrderNo: `M${new Date().getTime()}`,
|
||||
title: '测试H5支付',
|
||||
amount: amount.value,
|
||||
channel: payChannelEnum.WECHAT,
|
||||
method: payMethodEnum.JSAPI,
|
||||
openId: openId.value,
|
||||
}
|
||||
simplePayCashier(from)
|
||||
.then(({ data }) => {
|
||||
loading.value = false
|
||||
// 拉起jsapi支付
|
||||
const json = JSON.parse(data.payBody)
|
||||
doJsapiPay(json)
|
||||
})
|
||||
.catch((err) => {
|
||||
// 跳转到错误页
|
||||
router.push({
|
||||
name: 'PayErrorResult',
|
||||
query: { msg: err.message },
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 拉起Jsapi支付窗口
|
||||
*/
|
||||
function doJsapiPay(data: WxJsapiSignResult) {
|
||||
const form = {
|
||||
appId: data.appId, // 公众号ID,由商户传入
|
||||
timeStamp: data.timeStamp, // 时间戳,自1970年以来的秒数
|
||||
nonceStr: data.nonceStr, // 随机串
|
||||
package: data.package, // 预支付ID
|
||||
signType: data.signType, // 微信签名方式:
|
||||
paySign: data.paySign, // 微信签名
|
||||
}
|
||||
// 使用微信JsSdk拉起支付
|
||||
WeixinJSBridge.invoke('getBrandWCPayRequest', form, (res) => {
|
||||
if (res.err_msg === 'get_brand_wcpay_request:ok') {
|
||||
setTimeout(() => {
|
||||
WeixinJSBridge.call('closeWindow')
|
||||
}, 0)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 微信h5支付
|
||||
*/
|
||||
function wechatH5Pay() {
|
||||
loading.value = true
|
||||
const from = {
|
||||
bizOrderNo: new Date().getTime(),
|
||||
title: '测试H5支付',
|
||||
amount: amount.value,
|
||||
channel: payChannelEnum.WECHAT,
|
||||
method: payMethodEnum.WAP,
|
||||
}
|
||||
simplePayCashier(from)
|
||||
.then(({ data }) => {
|
||||
loading.value = false
|
||||
// 跳转到H5支付页面
|
||||
location.replace(data.payBody)
|
||||
})
|
||||
.catch((err) => {
|
||||
// 跳转到错误页
|
||||
router.push({
|
||||
name: 'PayErrorResult',
|
||||
query: { msg: err.message },
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 支付宝支付, 使用h5支付
|
||||
*/
|
||||
function aliPay() {
|
||||
loading.value = true
|
||||
const from = {
|
||||
bizOrderNo: new Date().getTime(),
|
||||
title: '测试H5支付',
|
||||
amount: amount.value,
|
||||
channel: payChannelEnum.ALI,
|
||||
method: payMethodEnum.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 @@
|
||||
<template>
|
||||
支付超时
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
|
||||
</style>
|
Reference in New Issue
Block a user