mirror of
https://gitee.com/bootx/dax-pay-h5
synced 2026-08-06 13:26:24 +08:00
feat 项目更新
This commit is contained in:
10
.env
10
.env
@@ -1,12 +1,12 @@
|
||||
# port
|
||||
VITE_PORT = 9100
|
||||
VITE_PORT=9100
|
||||
|
||||
# spa-title
|
||||
VITE_GLOB_APP_TITLE = DaxPay
|
||||
VITE_GLOB_APP_TITLE=DaxPay
|
||||
|
||||
# 系统中文名称
|
||||
VITE_GLOB_APP_TITLE_CN = DaxPay支付系统
|
||||
VITE_GLOB_APP_TITLE_CN=DaxPay支付系统
|
||||
|
||||
# spa shortname 不可出现空格数字等特殊字符
|
||||
VITE_GLOB_APP_SHORT_NAME = vantMobile
|
||||
# spa shortname 不可出现空格数字连接线等特殊字符
|
||||
VITE_GLOB_APP_SHORT_NAME=DaxPay
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ VITE_PORT=9100
|
||||
VITE_PUBLIC_PATH=/
|
||||
|
||||
# 跨域代理,可以配置多个,请注意不要换行
|
||||
VITE_PROXY=[["/server","http://localhost:10880"]]
|
||||
VITE_PROXY=[["/server","http://localhost:19999"]]
|
||||
|
||||
# API 接口地址
|
||||
VITE_GLOB_API_URL=
|
||||
|
||||
@@ -1,12 +1,8 @@
|
||||
# 独立部署模式
|
||||
VITE_PUBLIC_PATH = /
|
||||
# API 接口前缀
|
||||
VITE_GLOB_API_URL_PREFIX = /api
|
||||
|
||||
# 嵌入式模式 与网关部署在一起, 和 接口 (server) 前缀 这个是
|
||||
#VITE_PUBLIC_PATH=/h5
|
||||
## API 接口前缀
|
||||
#VITE_GLOB_API_URL_PREFIX=
|
||||
# 项目访问目录
|
||||
VITE_PUBLIC_PATH=/
|
||||
# API 接口前缀
|
||||
VITE_GLOB_API_URL_PREFIX=
|
||||
|
||||
# 是否删除console
|
||||
VITE_DROP_CONSOLE=true
|
||||
|
||||
21
LICENSE
21
LICENSE
@@ -1,21 +0,0 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2022 傲慢或香橙
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
59
README.md
59
README.md
@@ -1,55 +1,16 @@
|
||||
<p align="center">
|
||||
<img src="_doc/images/dax-pay.svg" width="45%">
|
||||
</p>
|
||||
# DaxPay移动H5端
|
||||
|
||||
# DaxPay H5端
|
||||
## 简绍
|
||||
vite5 + vue3.4 + vben admin2 + antd vue4 搭建
|
||||
|
||||
## 🍈项目介绍
|
||||
## 环境依赖
|
||||
|
||||
> axPay是一套开源支付网关系统,已经对接支付宝、微信支付、云闪付相关的接口。可以独立部署,提供接口供业务系统进行调用,不对原有系统产生影响
|
||||
| 环境 | 版本 | 备注 |
|
||||
|------|-----------|--------------------------|
|
||||
| Node | >=20.9.0 | 低版本会无法进行构建 |
|
||||
| pnpm | >=9.0.2 | 低版本会导致 pnpm-lock.yaml 失效 |
|
||||
|
||||
## 🍒 项目地址
|
||||
|
||||
| 项目 | GITEE | GITHUB |
|
||||
| ----------- | ------------------------------------------- | ----------------------------------------------- |
|
||||
| 后端地址 | [GITEE](https://gitee.com/dromara/dax-pay) | [GITHUB](https://github.com/dromara/dax-pay) |
|
||||
| Web前端地址 | [GITEE](https://gitee.com/bootx/dax-pay-ui) | [GITHUB](https://github.com/xxm1995/dax-pay-ui) |
|
||||
| H5前端地址 | [GITEE](https://gitee.com/bootx/dax-pay-h5) | [GITHUB](https://github.com/xxm1995/dax-pay-h5) |
|
||||
|
||||
## 🏬 系统演示
|
||||
|
||||
### 管理平台:
|
||||
|
||||
> 注:演示账号部分功能修改删除权限未开放。
|
||||
|
||||
地址:https://daxpay.demo.bootx.cn
|
||||
|
||||
账号:daxpay
|
||||
|
||||
密码:123456
|
||||
|
||||
### 网关接口
|
||||
|
||||
> 注:接口平台只开放支付网关相关的接口,不开放系统其他接口。
|
||||
|
||||
地址: https://daxpay.server.bootx.cn/doc.html
|
||||
|
||||
账号: daxpay
|
||||
|
||||
密码: 123456
|
||||
|
||||
### 收银台演示
|
||||
|
||||
> 请勿大额支付,可以通过后台管理端进行退款
|
||||
|
||||
电脑收银台地址: https://daxpay.demo.bootx.cn/#/cashier
|
||||
|
||||
手机收银台地址: https://daxpay.demo.bootx.cn/h5/#/cashier/uniCashier
|
||||
|
||||
## 项目启动
|
||||
|
||||
- 必须使用 [pnpm>=8.6.10](https://www.pnpm.cn/),否则依赖可能安装不上,推荐使用`8.6.10`。
|
||||
- [Node.js](http://nodejs.org/) 版本要求`18.x`以上,推荐使用 `^20.9.0`。
|
||||
## 启动命令
|
||||
|
||||
```shell
|
||||
# 安装项目依赖
|
||||
@@ -60,6 +21,6 @@ pnpm run dev
|
||||
pnpm build
|
||||
```
|
||||
|
||||
## 🍷License
|
||||
## License
|
||||
|
||||
Apache License Version 2.0
|
||||
|
||||
21
components.d.ts
vendored
21
components.d.ts
vendored
@@ -1,21 +0,0 @@
|
||||
/* eslint-disable */
|
||||
/* prettier-ignore */
|
||||
// @ts-nocheck
|
||||
// Generated by unplugin-vue-components
|
||||
// Read more: https://github.com/vuejs/core/pull/3399
|
||||
export {}
|
||||
|
||||
declare module 'vue' {
|
||||
export interface GlobalComponents {
|
||||
Loading: typeof import('./src/components/Loading.vue')['default']
|
||||
Logo: typeof import('./src/components/Logo.vue')['default']
|
||||
SvgIcon: typeof import('./src/components/SvgIcon.vue')['default']
|
||||
VanButton: typeof import('vant/es')['Button']
|
||||
VanConfigProvider: typeof import('vant/es')['ConfigProvider']
|
||||
VanDialog: typeof import('vant/es')['Dialog']
|
||||
VanField: typeof import('vant/es')['Field']
|
||||
VanLoading: typeof import('vant/es')['Loading']
|
||||
VanNumberKeyboard: typeof import('vant/es')['NumberKeyboard']
|
||||
VanTextEllipsis: typeof import('vant/es')['TextEllipsis']
|
||||
}
|
||||
}
|
||||
44
package.json
44
package.json
@@ -1,9 +1,9 @@
|
||||
{
|
||||
"name": "daxpay-h5",
|
||||
"name": "daxpay-gateway-ui",
|
||||
"type": "module",
|
||||
"version": "3.0.0",
|
||||
"engines": {
|
||||
"node": ">=18.12.0",
|
||||
"node": ">=20.6.0",
|
||||
"pnpm": ">=9.0.2"
|
||||
},
|
||||
"scripts": {
|
||||
@@ -27,62 +27,62 @@
|
||||
"@types/lodash-es": "^4.17.12",
|
||||
"@unocss/reset": "^0.58.9",
|
||||
"@vueuse/core": "^10.11.1",
|
||||
"axios": "^1.7.7",
|
||||
"axios": "^1.7.9",
|
||||
"date-fns": "^3.6.0",
|
||||
"lodash-es": "^4.17.21",
|
||||
"nprogress": "^0.2.0",
|
||||
"pinia": "^2.2.2",
|
||||
"pinia": "^2.3.0",
|
||||
"pinia-plugin-persist": "^1.0.0",
|
||||
"qs": "^6.13.0",
|
||||
"vant": "^4.9.7",
|
||||
"vue": "^3.5.8",
|
||||
"qs": "^6.13.1",
|
||||
"vant": "^4.9.10",
|
||||
"vue": "^3.5.13",
|
||||
"vue-router": "4.2.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@antfu/eslint-config": "^2.27.3",
|
||||
"@commitlint/cli": "^18.6.1",
|
||||
"@commitlint/config-conventional": "^18.6.3",
|
||||
"@iconify/json": "^2.2.252",
|
||||
"@iconify/json": "^2.2.281",
|
||||
"@types/fs-extra": "^11.0.4",
|
||||
"@types/mockjs": "^1.0.10",
|
||||
"@types/node": "^20.16.5",
|
||||
"@types/node": "^20.17.9",
|
||||
"@types/nprogress": "^0.2.3",
|
||||
"@types/qs": "^6.9.16",
|
||||
"@types/qs": "^6.9.17",
|
||||
"@unocss/eslint-plugin": "^0.58.9",
|
||||
"@unocss/preset-icons": "^0.58.9",
|
||||
"@unocss/preset-rem-to-px": "^0.58.9",
|
||||
"@unocss/transformer-directives": "^0.58.9",
|
||||
"@unocss/transformer-variant-group": "^0.58.9",
|
||||
"@vitejs/plugin-vue": "^5.1.4",
|
||||
"@vitejs/plugin-vue": "^5.2.1",
|
||||
"autoprefixer": "^10.4.20",
|
||||
"cross-env": "^7.0.3",
|
||||
"cz-git": "^1.9.4",
|
||||
"dotenv": "^16.4.5",
|
||||
"cz-git": "^1.11.0",
|
||||
"dotenv": "^16.4.7",
|
||||
"eslint": "^8.57.1",
|
||||
"eslint-plugin-format": "^0.1.2",
|
||||
"eslint-plugin-format": "^0.1.3",
|
||||
"esno": "^0.16.3",
|
||||
"fs-extra": "^11.2.0",
|
||||
"less": "^4.2.0",
|
||||
"less": "^4.2.1",
|
||||
"lint-staged": "^15.2.10",
|
||||
"only-allow": "^1.2.1",
|
||||
"picocolors": "^1.1.0",
|
||||
"postcss": "^8.4.47",
|
||||
"postcss-mobile-forever": "^4.1.6",
|
||||
"picocolors": "^1.1.1",
|
||||
"postcss": "^8.4.49",
|
||||
"postcss-mobile-forever": "^4.3.1",
|
||||
"rimraf": "^3.0.2",
|
||||
"rollup": "^4.22.4",
|
||||
"rollup": "^4.28.1",
|
||||
"rollup-plugin-visualizer": "^5.12.0",
|
||||
"simple-git-hooks": "^2.11.1",
|
||||
"typescript": "^5.6.2",
|
||||
"typescript": "^5.7.2",
|
||||
"unocss": "^0.58.9",
|
||||
"unplugin-auto-import": "^0.17.8",
|
||||
"unplugin-vue-components": "^0.26.0",
|
||||
"vconsole": "^3.15.1",
|
||||
"vite-plugin-vconsole": "^2.1.1",
|
||||
"vite": "5.2.6",
|
||||
"vite": "5.4.6",
|
||||
"vite-plugin-compression": "^0.5.1",
|
||||
"vite-plugin-html": "^3.2.2",
|
||||
"vite-plugin-mock": "^2.9.8",
|
||||
"vite-plugin-svg-icons": "^2.0.1",
|
||||
"vite-plugin-vconsole": "^2.1.1",
|
||||
"vue-tsc": "^1.8.27"
|
||||
},
|
||||
"lint-staged": {
|
||||
|
||||
2641
pnpm-lock.yaml
generated
2641
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@@ -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)
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ export enum ChannelEnum {
|
||||
/**
|
||||
* 支付方式
|
||||
*/
|
||||
export enum payMethodEnum {
|
||||
export enum PayMethodEnum {
|
||||
WAP = 'wap',
|
||||
APP = 'app',
|
||||
WEB = 'web',
|
||||
@@ -26,3 +26,21 @@ export enum CashierTypeEnum {
|
||||
WECHAT_PAY = 'wechat_pay',
|
||||
ALIPAY = 'alipay',
|
||||
}
|
||||
|
||||
/**
|
||||
* 收银台类型
|
||||
*/
|
||||
export enum CheckoutTypeEnum {
|
||||
H5 = 'h5',
|
||||
PC = 'pc',
|
||||
MINI_APP = 'mini_app',
|
||||
AGGREGATE = 'aggregate',
|
||||
}
|
||||
|
||||
/**
|
||||
* 收银台聚合支付类型
|
||||
*/
|
||||
export enum CheckoutAggregateEnum {
|
||||
ALI = 'alipay',
|
||||
WECHAT = 'wechat_pay',
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -50,3 +50,31 @@ export const routeModuleList: Array<RouteRecordRaw> = [
|
||||
],
|
||||
},
|
||||
]
|
||||
|
||||
/**
|
||||
* 业务模块路由
|
||||
*/
|
||||
export const BusinessRoute: RouteRecordRaw = {
|
||||
path: '/',
|
||||
name: '',
|
||||
redirect: PageEnum.BASE_HOME,
|
||||
component: Layout,
|
||||
children: [
|
||||
{
|
||||
path: '/result/success',
|
||||
name: 'SuccessResult',
|
||||
component: () => import('@/views/result/SuccessResult.vue'),
|
||||
meta: {
|
||||
title: '操作成功',
|
||||
},
|
||||
},
|
||||
{
|
||||
path: '/result/error',
|
||||
name: 'ErrorResult',
|
||||
component: () => import('@/views/result/ErrorResult.vue'),
|
||||
meta: {
|
||||
title: '错误页',
|
||||
},
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
import type { RouteRecordRaw } from 'vue-router'
|
||||
import { PageEnum } from '@/enums/pageEnum'
|
||||
|
||||
const Layout = () => import('@/layout/index.vue')
|
||||
|
||||
/**
|
||||
* 业务模块路由
|
||||
*/
|
||||
export const BusinessRoute: RouteRecordRaw = {
|
||||
path: '/',
|
||||
name: '',
|
||||
redirect: PageEnum.BASE_HOME,
|
||||
component: Layout,
|
||||
children: [
|
||||
{
|
||||
path: '/t/:key',
|
||||
name: 'DispatchRouter',
|
||||
component: () => import('@/views/system/dispatch/DispatchRouter.vue'),
|
||||
meta: {
|
||||
title: '中转页',
|
||||
},
|
||||
},
|
||||
{
|
||||
path: '/result/success',
|
||||
name: 'SuccessResult',
|
||||
component: () => import('@/views/result/SuccessResult.vue'),
|
||||
meta: {
|
||||
title: '操作成功',
|
||||
},
|
||||
},
|
||||
{
|
||||
path: '/result/error',
|
||||
name: 'ErrorResult',
|
||||
component: () => import('@/views/result/ErrorResult.vue'),
|
||||
meta: {
|
||||
title: '错误页',
|
||||
},
|
||||
},
|
||||
],
|
||||
}
|
||||
@@ -11,41 +11,49 @@ export const DaxPayRoute: RouteRecordRaw = {
|
||||
component: Layout,
|
||||
children: [
|
||||
{
|
||||
path: '/alipay/auth/:appId/:channel/:queryCode/:aliAppId',
|
||||
path: '/auth/alipay/: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: '支付宝信息获取',
|
||||
},
|
||||
},
|
||||
{
|
||||
path: '/wechat/auth/:appId/:channel/:queryCode',
|
||||
path: '/auth/wechat/:appId/:channel/:queryCode',
|
||||
name: 'WechatAuth',
|
||||
component: () => import('@/views/daxpay/channel/wechat/auth/WechatAuth.vue'),
|
||||
component: () => import('@/views/daxpay/auth/wechat/WechatAuth.vue'),
|
||||
meta: {
|
||||
title: '微信信息获取',
|
||||
},
|
||||
},
|
||||
{
|
||||
path: '/channel/cashier/:mchNo/:appId',
|
||||
name: 'ChannelCashier',
|
||||
component: () => import('@/views/daxpay/channel/ChannelCashier.vue'),
|
||||
path: '/cashier/:code',
|
||||
name: 'CashierCode',
|
||||
component: () => import('@/views/daxpay/cashier/Cashier.vue'),
|
||||
meta: {
|
||||
title: '收银台',
|
||||
},
|
||||
},
|
||||
{
|
||||
path: '/alipay/cashier/:mchNo/:appId',
|
||||
name: 'AlipayCashier',
|
||||
component: () => import('@/views/daxpay/channel/alipay/cashier/AlipayCashier.vue'),
|
||||
path: '/aggregate/:code',
|
||||
name: 'CheckAggregate',
|
||||
component: () => import('@/views/daxpay/aggregate/Aggregate.vue'),
|
||||
meta: {
|
||||
title: '聚合收银台',
|
||||
},
|
||||
},
|
||||
{
|
||||
path: '/aggregate/alipay/:code',
|
||||
name: 'AliCheckout',
|
||||
component: () => import('@/views/daxpay/aggregate/alipay/AlipayAggregate.vue'),
|
||||
meta: {
|
||||
title: '支付宝收银台',
|
||||
},
|
||||
},
|
||||
{
|
||||
path: '/wechat/cashier/:mchNo/:appId',
|
||||
name: 'WechatCashier',
|
||||
component: () => import('@/views/daxpay/channel/wechat/cashier/WechatCashier.vue'),
|
||||
path: '/aggregate/wechat/:code',
|
||||
name: 'WechatCheckout',
|
||||
component: () => import('@/views/daxpay/aggregate/wechat/WechatAggregate.vue'),
|
||||
meta: {
|
||||
title: '微信收银台',
|
||||
},
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
import type { App } from 'vue'
|
||||
import type { RouteRecordRaw } from 'vue-router'
|
||||
import { createRouter, createWebHashHistory, createWebHistory } from "vue-router";
|
||||
import { createRouterGuards } from './router-guards'
|
||||
import { ErrorPageRoute, routeModuleList } from '@/router/base'
|
||||
import { createRouter, createWebHistory } from 'vue-router'
|
||||
import { BusinessRoute, ErrorPageRoute, routeModuleList } from '@/router/base'
|
||||
import { useRouteStoreWidthOut } from '@/store/modules/route'
|
||||
|
||||
// 菜单
|
||||
import { BusinessRoute } from '@/router/business'
|
||||
import { DaxPayRoute } from '@/router/daxpay'
|
||||
|
||||
// 普通路由
|
||||
@@ -23,7 +21,7 @@ routeStore.setRouters(constantRouter.concat(routeModuleList))
|
||||
|
||||
const router = createRouter({
|
||||
// 重定向时hash模式有场景无法跳转,需要使用history模式
|
||||
history: createWebHistory(''),
|
||||
history: createWebHistory(import.meta.env.VITE_PUBLIC_PATH),
|
||||
routes: constantRouter.concat(...routeModuleList),
|
||||
strict: true,
|
||||
scrollBehavior: () => ({ left: 0, top: 0 }),
|
||||
@@ -31,7 +29,6 @@ const router = createRouter({
|
||||
|
||||
export function setupRouter(app: App) {
|
||||
app.use(router)
|
||||
createRouterGuards(router)
|
||||
}
|
||||
|
||||
export default router
|
||||
|
||||
@@ -1,49 +0,0 @@
|
||||
import type { Router } from 'vue-router'
|
||||
import { isNavigationFailure } from 'vue-router'
|
||||
import { useRouteStoreWidthOut } from '@/store/modules/route'
|
||||
|
||||
export function createRouterGuards(router: Router) {
|
||||
router.beforeEach(async (to, from, next) => {
|
||||
// 所有的的页面都可以访问
|
||||
next()
|
||||
})
|
||||
|
||||
// 进入某个路由之后触发的钩子
|
||||
router.afterEach((to, _, failure) => {
|
||||
// 设置每个页面的 title
|
||||
document.title = (to?.meta?.title as string) || document.title
|
||||
|
||||
if (isNavigationFailure(failure)) {
|
||||
console.log('failed navigation', failure)
|
||||
}
|
||||
|
||||
const routeStore = useRouteStoreWidthOut()
|
||||
// 在这里设置需要缓存的组件名称
|
||||
const keepAliveComponents = routeStore.keepAliveComponents
|
||||
// 获取当前组件名
|
||||
const currentComName: any = to.matched.find(item => item.name == to.name)?.name
|
||||
|
||||
// 如果 currentComName 且 keepAliveComponents 不包含 currentComName 且 即将要进入的路由 meta 属性里 keepAlive 为 true,则缓存该组件
|
||||
if (currentComName && !keepAliveComponents.includes(currentComName) && to.meta?.keepAlive) {
|
||||
// 需要缓存的组件
|
||||
keepAliveComponents.push(currentComName)
|
||||
// keepAlive 为 false 则不缓存
|
||||
}
|
||||
else if (!to.meta?.keepAlive) {
|
||||
// 不需要缓存的组件
|
||||
|
||||
// 这里的作用一开始组件设置为缓存,之后又设置不缓存但是它还是存在 keepAliveComponents 数组中
|
||||
// keepAliveComponents 使用 findIndex 与 当前路由对比,如果存在则返回具体下标位置,不存在返回 -1
|
||||
const index = routeStore.keepAliveComponents.findIndex(name => name == currentComName)
|
||||
if (index != -1) {
|
||||
// 通过返回具体下标位置删除 keepAliveComponents 数组中缓存的 元素
|
||||
keepAliveComponents.splice(index, 1)
|
||||
}
|
||||
}
|
||||
routeStore.setKeepAliveComponents(keepAliveComponents)
|
||||
})
|
||||
|
||||
router.onError((error) => {
|
||||
console.error(error, '路由错误')
|
||||
})
|
||||
}
|
||||
@@ -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
|
||||
},
|
||||
|
||||
@@ -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%;
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<div class="wel-box w-full flex flex-col items-center justify-between">
|
||||
<SvgIcon class="logo" :size="130" name="logo" />
|
||||
<div class="text-darkBlue dark:text-garyWhite mb-4 mt-12 text-center text-2xl font-black">
|
||||
欢迎使用DaxPay
|
||||
DaxPay支付网关
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,35 +1,24 @@
|
||||
import type { AuthResult } from './ChannelAuth.api'
|
||||
import type { AuthResult } from '../auth/ChannelAuth.api'
|
||||
import { http } from '@/utils/http/axios'
|
||||
import type { Result } from '#/axios'
|
||||
|
||||
/**
|
||||
* 获取商户名称
|
||||
* 获取收银台配置信息
|
||||
*/
|
||||
export function getMchName(mchNo: string) {
|
||||
return http.request<Result<string>>({
|
||||
url: '/unipay/ext/channel/cashier/getMchName',
|
||||
export function getCashierTypeConfig(cashierType: string, cashierCode: string) {
|
||||
return http.request<Result<CashierTypeConfigResult>>({
|
||||
url: '/unipay/cashier/code/findByCashierType',
|
||||
method: 'GET',
|
||||
params: { mchNo },
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取收银台信息
|
||||
*/
|
||||
export function getCashierInfo(cashierType: string, appId: string) {
|
||||
return http.request<Result<ChannelCashierConfigResult>>({
|
||||
url: '/unipay/ext/channel/cashier/getCashierType',
|
||||
method: 'GET',
|
||||
params: { cashierType, appId },
|
||||
params: { cashierType, cashierCode },
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取收银台所需授权链接, 用于获取OpenId一类的信息
|
||||
*/
|
||||
export function generateAuthUrl(param: CashierAuthParam) {
|
||||
export function generateAuthUrl(param: CashierAuthUrlParam) {
|
||||
return http.request<Result<string>>({
|
||||
url: '/unipay/ext/channel/cashier/generateAuthUrl',
|
||||
url: '/unipay/cashier/code/generateAuthUrl',
|
||||
method: 'POST',
|
||||
data: param,
|
||||
})
|
||||
@@ -38,9 +27,9 @@ export function generateAuthUrl(param: CashierAuthParam) {
|
||||
/**
|
||||
* 获取授权信息
|
||||
*/
|
||||
export function auth(param: CashierPayParam) {
|
||||
export function auth(param: CashierAuthParam) {
|
||||
return http.request<Result<AuthResult>>({
|
||||
url: '/unipay/ext/channel/cashier/auth',
|
||||
url: '/unipay/cashier/code/auth',
|
||||
method: 'POST',
|
||||
data: param,
|
||||
})
|
||||
@@ -51,20 +40,28 @@ export function auth(param: CashierPayParam) {
|
||||
*/
|
||||
export function cashierPay(param: CashierPayParam) {
|
||||
return http.request<Result<PayResult>>({
|
||||
url: '/unipay/ext/channel/cashier/pay',
|
||||
url: '/unipay/cashier/code/pay',
|
||||
method: 'POST',
|
||||
data: param,
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 通道认证参数
|
||||
* 获取认证URL参数
|
||||
*/
|
||||
export interface CashierAuthUrlParam {
|
||||
// 应用号
|
||||
cashierCode?: string
|
||||
// 收银台类型
|
||||
cashierType?: string
|
||||
}
|
||||
|
||||
/**
|
||||
* 认证参数
|
||||
*/
|
||||
export interface CashierAuthParam {
|
||||
// 商户号
|
||||
mchNo?: string
|
||||
// 应用号
|
||||
appId?: string
|
||||
cashierCode?: string
|
||||
// 收银台类型
|
||||
cashierType?: string
|
||||
// 授权码
|
||||
@@ -75,11 +72,8 @@ export interface CashierAuthParam {
|
||||
* 通道收银支付参数
|
||||
*/
|
||||
export interface CashierPayParam {
|
||||
|
||||
// 商户号
|
||||
mchNo?: string
|
||||
// 应用号
|
||||
appId?: string
|
||||
cashierCode?: string
|
||||
// 收银台类型
|
||||
cashierType?: string
|
||||
// 支付金额
|
||||
@@ -94,7 +88,6 @@ export interface CashierPayParam {
|
||||
* 支付结果
|
||||
*/
|
||||
export interface PayResult {
|
||||
|
||||
// 支付状态
|
||||
status: string
|
||||
// 支付参数体
|
||||
@@ -124,23 +117,17 @@ export interface WxJsapiSignResult {
|
||||
}
|
||||
|
||||
/**
|
||||
* 收银台配置信息
|
||||
* 收银码牌配置信息
|
||||
*/
|
||||
export interface ChannelCashierConfigResult {
|
||||
// 商户号
|
||||
mchNo?: string
|
||||
export interface CashierTypeConfigResult {
|
||||
// 应用号
|
||||
appId?: string
|
||||
// 收银台类型
|
||||
cashierType?: string
|
||||
// 收银台名称
|
||||
cashierName?: string
|
||||
// 码牌名称
|
||||
name?: string
|
||||
// 支付通道
|
||||
channel?: string
|
||||
// 支付方式
|
||||
payMethod?: string
|
||||
// 是否开启分账
|
||||
allocation?: boolean
|
||||
// 自动分账
|
||||
autoAllocation?: boolean
|
||||
}
|
||||
@@ -6,17 +6,17 @@ import { useRoute } from 'vue-router'
|
||||
import router from '@/router'
|
||||
|
||||
const route = useRoute()
|
||||
const { mchNo, appId } = route.params
|
||||
const { code } = route.params
|
||||
|
||||
const ua = navigator.userAgent
|
||||
if (ua.includes('MicroMessenger')) {
|
||||
router.push({ path: `/wechat/cashier/${mchNo}/${appId}`, replace: true })
|
||||
router.push({ path: `/aggregate/wechat/${code}`, replace: true })
|
||||
}
|
||||
else if (ua.includes('Alipay')) {
|
||||
router.push({ path: `/alipay/cashier/${mchNo}/${appId}`, replace: true })
|
||||
router.push({ path: `/aggregate/alipay/${code}`, replace: true })
|
||||
}
|
||||
else {
|
||||
router.push({ name: 'ErrorResult', query: { msg: '请使用支付宝、微信等支付程序进行扫码支付' }, replace: true })
|
||||
router.push({ name: 'ErrorResult', query: { msg: '请使用支付宝、微信等软件进行扫码支付' }, replace: true })
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
<template>
|
||||
支付超时
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
||||
</template>
|
||||
|
||||
<style scoped lang="less">
|
||||
|
||||
</style>
|
||||
11
src/views/daxpay/aggregate/wechat/WechatAggregate.vue
Normal file
11
src/views/daxpay/aggregate/wechat/WechatAggregate.vue
Normal file
@@ -0,0 +1,11 @@
|
||||
<script setup lang="ts">
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
||||
</template>
|
||||
|
||||
<style scoped lang="less">
|
||||
|
||||
</style>
|
||||
@@ -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>
|
||||
@@ -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(
|
||||
@@ -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;
|
||||
@@ -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>
|
||||
@@ -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
|
||||
@@ -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;
|
||||
0
src/views/daxpay/cashier/Cashier.api.ts
Normal file
0
src/views/daxpay/cashier/Cashier.api.ts
Normal file
11
src/views/daxpay/cashier/Cashier.vue
Normal file
11
src/views/daxpay/cashier/Cashier.vue
Normal file
@@ -0,0 +1,11 @@
|
||||
<script setup lang="ts">
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
||||
</template>
|
||||
|
||||
<style scoped lang="less">
|
||||
|
||||
</style>
|
||||
@@ -1,165 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="container">
|
||||
<div style="font-size: 28px;margin-top: 10px;">
|
||||
{{ cashierInfo.cashierName || '支付宝收银台' }}
|
||||
</div>
|
||||
<div class="amount-display">
|
||||
<p style="font-size: 20px">
|
||||
付款给{{ mchName }}
|
||||
</p>
|
||||
<p style="font-size: 32px;">
|
||||
¥ {{ amount }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<van-dialog
|
||||
v-model:show="showRemark"
|
||||
title="支付备注"
|
||||
confirm-button-text="保存"
|
||||
cancel-button-text="清除"
|
||||
confirm-button-color="#108ee9"
|
||||
cancel-button-color="red"
|
||||
show-cancel-button
|
||||
@cancel="description = ''"
|
||||
>
|
||||
<van-field
|
||||
v-model="description"
|
||||
rows="2"
|
||||
autosize
|
||||
label=""
|
||||
type="textarea"
|
||||
:maxlength="50"
|
||||
placeholder="请输入支付备注内容"
|
||||
show-word-limit
|
||||
/>
|
||||
</van-dialog>
|
||||
<van-number-keyboard
|
||||
:show="true"
|
||||
theme="custom"
|
||||
extra-key="."
|
||||
close-button-text="付款"
|
||||
@close="pay"
|
||||
@input="input"
|
||||
@delete="del"
|
||||
>
|
||||
<template #title-left>
|
||||
<div style="width: 100vw;display: flex; justify-content: center">
|
||||
<div class="remark" @click="showRemark = true">
|
||||
<div v-if="!description">
|
||||
添加备注
|
||||
</div>
|
||||
<div v-else style="max-width: 75vw;">
|
||||
<van-text-ellipsis :content="`备注: ${description}`" /><div />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</van-number-keyboard>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { onMounted, ref } from 'vue'
|
||||
import { useRoute } from 'vue-router'
|
||||
import { showNotify } from 'vant'
|
||||
import type {
|
||||
CashierPayParam,
|
||||
ChannelCashierConfigResult,
|
||||
} from '@/views/daxpay/channel/ChannelCashier.api'
|
||||
import {
|
||||
cashierPay,
|
||||
getCashierInfo,
|
||||
getMchName,
|
||||
} from '@/views/daxpay/channel/ChannelCashier.api'
|
||||
|
||||
import { CashierTypeEnum } from '@/enums/daxpay/DaxPayEnum'
|
||||
import router from '@/router'
|
||||
import { useKeyboard } from '@/hooks/daxpay/useKeyboard'
|
||||
|
||||
const route = useRoute()
|
||||
const { mchNo, appId } = route.params
|
||||
|
||||
const showRemark = ref<boolean>(false)
|
||||
const loading = ref<boolean>(false)
|
||||
const cashierInfo = ref<ChannelCashierConfigResult>({})
|
||||
const amount = ref<string>('0')
|
||||
const description = ref<string>('')
|
||||
const mchName = ref<string>('')
|
||||
|
||||
const { input, del } = useKeyboard(amount)
|
||||
|
||||
onMounted(() => {
|
||||
initData()
|
||||
})
|
||||
|
||||
/**
|
||||
* 初始化数据
|
||||
*/
|
||||
function initData() {
|
||||
getCashierInfo(CashierTypeEnum.ALIPAY, appId as string).then(({ data }) => {
|
||||
cashierInfo.value = data
|
||||
}).catch((res) => {
|
||||
router.push({ name: 'ErrorResult', query: { msg: res.message } })
|
||||
})
|
||||
getMchName(mchNo as string).then(({ data }) => {
|
||||
mchName.value = data
|
||||
}).catch((res) => {
|
||||
router.push({ name: 'ErrorResult', query: { msg: res.message } })
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 支付
|
||||
*/
|
||||
function pay() {
|
||||
const amountValue = Number(amount.value)
|
||||
if (amountValue === 0) {
|
||||
showNotify({ type: 'warning', message: '金额不可为0' })
|
||||
return
|
||||
}
|
||||
loading.value = true
|
||||
const from = {
|
||||
amount: amountValue,
|
||||
appId,
|
||||
cashierType: CashierTypeEnum.ALIPAY,
|
||||
description: description.value,
|
||||
mchNo,
|
||||
} as CashierPayParam
|
||||
cashierPay(from)
|
||||
.then(({ data }) => {
|
||||
loading.value = false
|
||||
// 跳转到H5/付款码支付页面
|
||||
location.replace(data.payBody)
|
||||
})
|
||||
}
|
||||
</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>
|
||||
@@ -1,230 +0,0 @@
|
||||
<template>
|
||||
<div v-if="show">
|
||||
<div class="container">
|
||||
<div style="font-size: 28px;margin-top: 10px;">
|
||||
{{ cashierInfo.cashierName || '微信收银台' }}
|
||||
</div>
|
||||
<div class="amount-display">
|
||||
<p style="font-size: 20px">
|
||||
付款给{{ mchName }}
|
||||
</p>
|
||||
<p style="font-size: 32px;">
|
||||
¥ {{ amount }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<van-dialog
|
||||
v-model:show="showRemark"
|
||||
title="支付备注"
|
||||
confirm-button-text="保存"
|
||||
cancel-button-text="清除"
|
||||
confirm-button-color="#4CAF50"
|
||||
cancel-button-color="red"
|
||||
show-cancel-button
|
||||
@cancel="description = ''"
|
||||
>
|
||||
<van-field
|
||||
v-model="description"
|
||||
rows="2"
|
||||
autosize
|
||||
label=""
|
||||
type="textarea"
|
||||
:maxlength="50"
|
||||
placeholder="请输入支付备注内容"
|
||||
show-word-limit
|
||||
/>
|
||||
</van-dialog>
|
||||
<van-number-keyboard
|
||||
:show="true"
|
||||
theme="custom"
|
||||
extra-key="."
|
||||
close-button-text="付款"
|
||||
@close="pay"
|
||||
@input="input"
|
||||
@delete="del"
|
||||
>
|
||||
<template #title-left>
|
||||
<div style="width: 100vw;display: flex; justify-content: center">
|
||||
<div class="remark" @click="showRemark = true">
|
||||
<div v-if="!description">
|
||||
添加备注
|
||||
</div>
|
||||
<div v-else style="max-width: 75vw;">
|
||||
<van-text-ellipsis :content="`备注: ${description}`" /><div />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</van-number-keyboard>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { onMounted, ref } from 'vue'
|
||||
import { useRoute } from 'vue-router'
|
||||
import { showNotify } from 'vant'
|
||||
import type {
|
||||
CashierAuthParam,
|
||||
CashierPayParam,
|
||||
ChannelCashierConfigResult,
|
||||
WxJsapiSignResult,
|
||||
} from '@/views/daxpay/channel/ChannelCashier.api'
|
||||
import {
|
||||
auth
|
||||
, cashierPay,
|
||||
generateAuthUrl,
|
||||
getCashierInfo,
|
||||
getMchName,
|
||||
} from '@/views/daxpay/channel/ChannelCashier.api'
|
||||
|
||||
import { CashierTypeEnum } from '@/enums/daxpay/DaxPayEnum'
|
||||
import router from '@/router'
|
||||
import { useKeyboard } from '@/hooks/daxpay/useKeyboard'
|
||||
|
||||
const route = useRoute()
|
||||
const { mchNo, appId } = route.params
|
||||
const { code } = route.query
|
||||
|
||||
const show = ref<boolean>(false)
|
||||
const showRemark = ref<boolean>(false)
|
||||
const loading = ref<boolean>(false)
|
||||
const cashierInfo = ref<ChannelCashierConfigResult>({})
|
||||
const amount = ref<string>('0')
|
||||
const description = ref<string>('')
|
||||
const mchName = ref<string>('')
|
||||
const openId = ref<string>('')
|
||||
|
||||
// 认证参数
|
||||
const authParam = ref<CashierAuthParam>({
|
||||
mchNo: mchNo as string,
|
||||
appId: appId as string,
|
||||
cashierType: CashierTypeEnum.WECHAT_PAY,
|
||||
})
|
||||
|
||||
const { input, del } = useKeyboard(amount)
|
||||
|
||||
onMounted(() => {
|
||||
init()
|
||||
})
|
||||
|
||||
/**
|
||||
* 初始化
|
||||
*/
|
||||
function init() {
|
||||
// 如果不是重定向跳转过来, 跳转到到重定向地址
|
||||
if (!code) {
|
||||
// 重定向跳转到微信授权地址
|
||||
generateAuthUrl(authParam.value).then((res) => {
|
||||
const url = res.data
|
||||
location.replace(url)
|
||||
}).catch((res) => {
|
||||
router.push({ name: 'ErrorResult', query: { msg: res.message } })
|
||||
})
|
||||
}
|
||||
else {
|
||||
authParam.value.authCode = code as string
|
||||
// 初始化数据
|
||||
initData()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化数据
|
||||
*/
|
||||
function initData() {
|
||||
show.value = true
|
||||
getCashierInfo(CashierTypeEnum.ALIPAY, appId as string).then(({ data }) => {
|
||||
cashierInfo.value = data
|
||||
}).catch((res) => {
|
||||
router.push({ name: 'ErrorResult', query: { msg: res.message } })
|
||||
})
|
||||
getMchName(mchNo as string).then(({ data }) => {
|
||||
mchName.value = data
|
||||
}).catch((res) => {
|
||||
router.push({ name: 'ErrorResult', query: { msg: res.message } })
|
||||
})
|
||||
auth(authParam.value).then(({ data }) => {
|
||||
openId.value = data.openId as string
|
||||
}).catch((res) => {
|
||||
router.push({ name: 'ErrorResult', query: { msg: res.message } })
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 微信jsapi方式支付
|
||||
*/
|
||||
function pay() {
|
||||
const amountValue = Number(amount.value)
|
||||
if (amountValue === 0) {
|
||||
showNotify({ type: 'warning', message: '金额不可为0' })
|
||||
return
|
||||
}
|
||||
|
||||
loading.value = true
|
||||
const from = {
|
||||
amount: amountValue,
|
||||
appId,
|
||||
openId: openId.value,
|
||||
cashierType: CashierTypeEnum.WECHAT_PAY,
|
||||
description: description.value,
|
||||
mchNo,
|
||||
} as CashierPayParam
|
||||
cashierPay(from)
|
||||
.then(({ data }) => {
|
||||
loading.value = false
|
||||
// 拉起jsapi支付
|
||||
const json = JSON.parse(data.payBody)
|
||||
jsapiPay(json)
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 拉起Jsapi支付窗口
|
||||
*/
|
||||
function jsapiPay(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') {
|
||||
// 跳转到成功页面
|
||||
router.push({ name: 'SuccessResult', query: { msg: '支付成功' }, replace: true })
|
||||
}
|
||||
})
|
||||
}
|
||||
</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>
|
||||
24
src/views/daxpay/checkout/CheckAggregate.vue
Normal file
24
src/views/daxpay/checkout/CheckAggregate.vue
Normal file
@@ -0,0 +1,24 @@
|
||||
<template>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useRoute } from 'vue-router'
|
||||
import router from '@/router'
|
||||
|
||||
const route = useRoute()
|
||||
const { orderNo } = route.params
|
||||
|
||||
const ua = navigator.userAgent
|
||||
if (ua.includes('MicroMessenger')) {
|
||||
router.push({ path: `/aggregate/wechat/${orderNo}`, replace: true })
|
||||
}
|
||||
else if (ua.includes('Alipay')) {
|
||||
router.push({ path: `/aggregate/alipay/${orderNo}`, replace: true })
|
||||
}
|
||||
else {
|
||||
router.push({ name: 'ErrorResult', query: { msg: '请使用支付宝、微信等软件进行扫码支付' }, replace: true })
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
</style>
|
||||
213
src/views/daxpay/checkout/CheckoutPay.api.ts
Normal file
213
src/views/daxpay/checkout/CheckoutPay.api.ts
Normal file
@@ -0,0 +1,213 @@
|
||||
import { http } from '@/utils/http/axios'
|
||||
import type { Result } from '#/axios'
|
||||
import type { AuthResult } from '@/views/daxpay/auth/ChannelAuth.api'
|
||||
import type { PayResult } from '@/views/daxpay/aggregate/Aggregate.api'
|
||||
|
||||
/**
|
||||
* 获取收银台订单和配置信息
|
||||
*/
|
||||
export function getOrderAndConfig(orderNo, checkoutType) {
|
||||
return http.request<Result<CheckoutOrderAndConfigResult>>({
|
||||
url: '/unipay/checkout/getOrderAndConfig',
|
||||
method: 'GET',
|
||||
params: {
|
||||
orderNo,
|
||||
checkoutType,
|
||||
},
|
||||
})
|
||||
}
|
||||
/**
|
||||
* 获取聚合支付配置
|
||||
*/
|
||||
export function getAggregateConfig(orderNo, aggregateType) {
|
||||
return http.request<Result<AggregateOrderAndConfigResult>>({
|
||||
url: '/unipay/checkout/getAggregateConfig',
|
||||
method: 'GET',
|
||||
params: {
|
||||
orderNo,
|
||||
aggregateType,
|
||||
},
|
||||
})
|
||||
}
|
||||
/**
|
||||
* 获取收银台所需授权链接, 用于获取OpenId一类的信息
|
||||
*/
|
||||
export function generateAuthUrl(param: CheckoutAuthUrlParam) {
|
||||
return http.request<Result<string>>({
|
||||
url: '/unipay/checkout/generateAuthUrl',
|
||||
method: 'post',
|
||||
data: param,
|
||||
})
|
||||
}
|
||||
/**
|
||||
* 获取授权结果
|
||||
*/
|
||||
export function auth(param: CheckoutAuthCodeParam) {
|
||||
return http.request<Result<AuthResult>>({
|
||||
url: '/unipay/checkout/auth',
|
||||
method: 'post',
|
||||
data: param,
|
||||
})
|
||||
}
|
||||
/**
|
||||
* 发起普通支付
|
||||
*/
|
||||
export function checkoutPay(param: CheckoutPayParam) {
|
||||
return http.request<Result<PayResult>>({
|
||||
url: '/unipay/checkout/pay',
|
||||
method: 'post',
|
||||
data: param,
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 发起聚合支付
|
||||
*/
|
||||
export function aggregatePay(param: CheckoutAggregatePayParam) {
|
||||
return http.request<Result<PayResult>>({
|
||||
url: '/unipay/checkout/aggregatePay',
|
||||
method: 'post',
|
||||
data: param,
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 收银台认证链接生成参数
|
||||
*/
|
||||
export interface CheckoutAuthUrlParam {
|
||||
/** 要支付的订单号 */
|
||||
orderNo?: string
|
||||
/** 聚合支付类型 */
|
||||
aggregateType?: string
|
||||
}
|
||||
/**
|
||||
* 获取收银台认证结果参数
|
||||
*/
|
||||
export interface CheckoutAuthCodeParam {
|
||||
/** 要支付的订单号 */
|
||||
orderNo?: string
|
||||
/** 聚合支付类型 */
|
||||
aggregateType?: string
|
||||
/** 认证Code */
|
||||
authCode?: string
|
||||
}
|
||||
|
||||
/**
|
||||
* 收银台支付参数
|
||||
*/
|
||||
export interface CheckoutPayParam {
|
||||
/** 订单号 */
|
||||
orderNo?: string
|
||||
/** 支付配置项ID */
|
||||
itemId?: string
|
||||
/** 唯一标识 */
|
||||
openId?: string
|
||||
/** 付款码 */
|
||||
barCode?: string
|
||||
}
|
||||
|
||||
/**
|
||||
* 聚合支付参数
|
||||
*/
|
||||
export interface CheckoutAggregatePayParam {
|
||||
/** 订单号 */
|
||||
orderNo?: string
|
||||
/** 聚合支付类型 */
|
||||
aggregateType?: string
|
||||
/** 唯一标识 */
|
||||
openId?: string
|
||||
}
|
||||
|
||||
/**
|
||||
* 收银台配置
|
||||
*/
|
||||
export interface CheckoutOrderAndConfigResult {
|
||||
/** 订单信息 */
|
||||
order: CheckoutOrderResult
|
||||
/** 收银台配置信息 */
|
||||
config: CheckoutConfigResult
|
||||
/** 收银台分类配置信息 */
|
||||
groupConfigs: CheckoutGroupConfigResult[]
|
||||
}
|
||||
|
||||
/**
|
||||
* 收银台聚合支付配置
|
||||
*/
|
||||
export interface AggregateOrderAndConfigResult {
|
||||
/** 订单信息 */
|
||||
order: CheckoutOrderResult
|
||||
/** 收银台配置信息 */
|
||||
config: CheckoutConfigResult
|
||||
/** 收银台聚合配置信息 */
|
||||
aggregateConfig: AggregateConfigResult
|
||||
}
|
||||
|
||||
/**
|
||||
* 订单信息
|
||||
*/
|
||||
export interface CheckoutOrderResult {
|
||||
/** 商户订单号 */
|
||||
bizOrderNo?: string
|
||||
/** 订单号 */
|
||||
orderNo?: string
|
||||
/** 标题 */
|
||||
title?: string
|
||||
/** 描述 */
|
||||
description?: string
|
||||
/** 金额(元) */
|
||||
amount?: number
|
||||
|
||||
}
|
||||
/**
|
||||
* 收银台配置信息
|
||||
*/
|
||||
export interface CheckoutConfigResult {
|
||||
/** 收银台名称 */
|
||||
name?: string
|
||||
/** PC收银台是否同时显示聚合收银码 */
|
||||
aggregateShow?: boolean
|
||||
/** h5收银台自动升级聚合支付 */
|
||||
h5AutoUpgrade?: boolean
|
||||
}
|
||||
|
||||
/**
|
||||
* 收银台分类配置
|
||||
*/
|
||||
export interface CheckoutGroupConfigResult {
|
||||
/** 主键 */
|
||||
id?: string
|
||||
/** 名称 */
|
||||
name?: string
|
||||
/** 配置项列表 */
|
||||
items?: CheckoutItemConfigResult[]
|
||||
}
|
||||
|
||||
/**
|
||||
* 收银台配置项
|
||||
*/
|
||||
export interface CheckoutItemConfigResult {
|
||||
/** 主键 */
|
||||
id?: string
|
||||
/** 发起调用的类型 */
|
||||
callType?: string
|
||||
/** 名称 */
|
||||
name?: string
|
||||
/** 支付通道 */
|
||||
channel?: string
|
||||
/** 支付方式 */
|
||||
payMethod?: string
|
||||
}
|
||||
|
||||
/**
|
||||
* 收银台聚合配置信息
|
||||
*/
|
||||
export interface AggregateConfigResult {
|
||||
/** 支付类型 */
|
||||
type?: string
|
||||
/** 通道 */
|
||||
channel?: string
|
||||
/** 支付方式 */
|
||||
payMethod?: string
|
||||
/** 自动拉起支付 */
|
||||
autoLaunch?: boolean
|
||||
}
|
||||
118
src/views/daxpay/checkout/CheckoutPay.vue
Normal file
118
src/views/daxpay/checkout/CheckoutPay.vue
Normal file
@@ -0,0 +1,118 @@
|
||||
<template>
|
||||
<div v-if="show">
|
||||
<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 v-for="group in orderAndConfig.groupConfigs" :key="group.id" inset :title="group.name">
|
||||
<van-space direction="vertical" fill>
|
||||
<van-button v-for="config in group.items" :key="config.id" type="primary" block @click="pay(config)">
|
||||
{{ 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 {
|
||||
CheckoutItemConfigResult,
|
||||
CheckoutOrderAndConfigResult,
|
||||
CheckoutPayParam,
|
||||
} from './CheckoutPay.api'
|
||||
import {
|
||||
checkoutPay
|
||||
, getOrderAndConfig,
|
||||
} from './CheckoutPay.api'
|
||||
|
||||
import { CheckoutTypeEnum } from '@/enums/daxpay/DaxPayEnum'
|
||||
import router from '@/router'
|
||||
|
||||
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: [],
|
||||
})
|
||||
|
||||
/**
|
||||
* 初始化
|
||||
*/
|
||||
onMounted(() => {
|
||||
initData()
|
||||
})
|
||||
|
||||
/**
|
||||
* 初始化数据
|
||||
*/
|
||||
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) {
|
||||
goAggregate()
|
||||
return
|
||||
}
|
||||
show.value = true
|
||||
}
|
||||
|
||||
/**
|
||||
* 跳转到聚合收银台
|
||||
*/
|
||||
function goAggregate() {
|
||||
if (ua.includes('MicroMessenger')) {
|
||||
router.push({ path: `/aggregate/wechat/${orderNo}`, replace: true })
|
||||
}
|
||||
else if (ua.includes('Alipay')) {
|
||||
router.push({ path: `/aggregate/alipay/${orderNo}`, replace: true })
|
||||
}
|
||||
else {
|
||||
show.value = true
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 发起支付
|
||||
*/
|
||||
function pay(config: CheckoutItemConfigResult) {
|
||||
loading.value = true
|
||||
const from = {
|
||||
orderNo,
|
||||
itemId: config.id,
|
||||
} as CheckoutPayParam
|
||||
checkoutPay(from).then(({ data }) => {
|
||||
loading.value = false
|
||||
// 跳转到支付页面
|
||||
location.replace(data.payBody)
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
</style>
|
||||
89
src/views/daxpay/checkout/alipay/AliAggregate.vue
Normal file
89
src/views/daxpay/checkout/alipay/AliAggregate.vue
Normal file
@@ -0,0 +1,89 @@
|
||||
<template>
|
||||
<div>
|
||||
<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">{{ 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>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { onMounted, ref } from 'vue'
|
||||
import { useRoute } from 'vue-router'
|
||||
|
||||
import { CheckoutAggregateEnum } from '@/enums/daxpay/DaxPayEnum'
|
||||
import router from '@/router'
|
||||
import type {
|
||||
AggregateOrderAndConfigResult,
|
||||
CheckoutAggregatePayParam,
|
||||
} from '@/views/daxpay/checkout/CheckoutPay.api'
|
||||
import {
|
||||
aggregatePay,
|
||||
getAggregateConfig,
|
||||
} from '@/views/daxpay/checkout/CheckoutPay.api'
|
||||
|
||||
const route = useRoute()
|
||||
const { orderNo } = route.params
|
||||
|
||||
const loading = ref<boolean>(false)
|
||||
const aggregateInfo = ref<AggregateOrderAndConfigResult>({
|
||||
aggregateConfig: {},
|
||||
config: {},
|
||||
order: {},
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
initData()
|
||||
})
|
||||
|
||||
/**
|
||||
* 初始化数据
|
||||
*/
|
||||
async function initData() {
|
||||
// 查询订单和配置
|
||||
await getAggregateConfig(orderNo, CheckoutAggregateEnum.ALI).then(({ data }) => {
|
||||
aggregateInfo.value = data
|
||||
}).catch((res) => {
|
||||
router.push({ name: 'ErrorResult', query: { msg: res.message }, replace: true })
|
||||
})
|
||||
// 判断是否自动拉起支付
|
||||
if (aggregateInfo.value.aggregateConfig.autoLaunch) {
|
||||
pay()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 支付
|
||||
*/
|
||||
function pay() {
|
||||
loading.value = true
|
||||
const from = {
|
||||
orderNo: aggregateInfo.value.order.orderNo,
|
||||
aggregateType: CheckoutAggregateEnum.ALI,
|
||||
} as CheckoutAggregatePayParam
|
||||
aggregatePay(from)
|
||||
.then(({ data }) => {
|
||||
loading.value = false
|
||||
// 跳转到H5/扫码支付页面
|
||||
location.replace(data.payBody)
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
</style>
|
||||
152
src/views/daxpay/checkout/wechat/WechatAggregate.vue
Normal file
152
src/views/daxpay/checkout/wechat/WechatAggregate.vue
Normal file
@@ -0,0 +1,152 @@
|
||||
<template>
|
||||
<div v-if="show">
|
||||
<van-overlay :show="loading">
|
||||
<div class="loading-wrapper" @click.stop>
|
||||
<van-loading size="24px">
|
||||
支付中...
|
||||
</van-loading>
|
||||
</div>
|
||||
</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>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { onMounted, ref } from 'vue'
|
||||
import { useRoute } from 'vue-router'
|
||||
|
||||
import { CheckoutAggregateEnum } from '@/enums/daxpay/DaxPayEnum'
|
||||
import router from '@/router'
|
||||
import type {
|
||||
AggregateOrderAndConfigResult, CheckoutAggregatePayParam,
|
||||
CheckoutAuthCodeParam} from '@/views/daxpay/checkout/CheckoutPay.api';
|
||||
import { aggregatePay,
|
||||
auth, generateAuthUrl, getAggregateConfig } from '@/views/daxpay/checkout/CheckoutPay.api'
|
||||
|
||||
|
||||
import type { WxJsapiSignResult } from '@/views/daxpay/aggregate/Aggregate.api'
|
||||
|
||||
const route = useRoute()
|
||||
const { orderNo } = route.params
|
||||
const { code: authCode } = route.query
|
||||
|
||||
const show = ref<boolean>(false)
|
||||
const loading = ref<boolean>(false)
|
||||
|
||||
const openId = ref<string>('')
|
||||
|
||||
// 认证参数
|
||||
const authParam = ref<CheckoutAuthCodeParam>({
|
||||
orderNo: orderNo as string,
|
||||
aggregateType: CheckoutAggregateEnum.WECHAT,
|
||||
})
|
||||
|
||||
const aggregateInfo = ref<AggregateOrderAndConfigResult>({
|
||||
aggregateConfig: {},
|
||||
config: {},
|
||||
order: {},
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
init()
|
||||
})
|
||||
|
||||
/**
|
||||
* 进入页面的初始化
|
||||
*/
|
||||
function init() {
|
||||
// 如果不是重定向跳转过来, 跳转到到重定向授权地址
|
||||
if (!authCode) {
|
||||
// 重定向跳转到微信授权地址
|
||||
generateAuthUrl({ orderNo: orderNo as string, aggregateType: CheckoutAggregateEnum.WECHAT }).then((res) => {
|
||||
const url = res.data
|
||||
location.replace(url)
|
||||
}).catch((res) => {
|
||||
router.push({ name: 'ErrorResult', query: { msg: res.message }, replace: true })
|
||||
})
|
||||
}
|
||||
else {
|
||||
authParam.value.authCode = authCode as string
|
||||
// 初始化数据
|
||||
initData()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化数据
|
||||
*/
|
||||
async function initData() {
|
||||
show.value = true
|
||||
// 获取聚合配置
|
||||
getAggregateConfig(orderNo, CheckoutAggregateEnum.WECHAT).then(({ data }) => {
|
||||
aggregateInfo.value = data
|
||||
}).catch((res) => {
|
||||
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 }, replace: true })
|
||||
})
|
||||
// 判断是否自动拉起支付
|
||||
if (aggregateInfo.value.aggregateConfig.autoLaunch) {
|
||||
pay()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 微信jsapi方式支付
|
||||
*/
|
||||
function pay() {
|
||||
loading.value = true
|
||||
const from = {
|
||||
orderNo: orderNo as string,
|
||||
aggregateType: CheckoutAggregateEnum.WECHAT,
|
||||
openId: openId.value,
|
||||
} as CheckoutAggregatePayParam
|
||||
aggregatePay(from)
|
||||
.then(({ data }) => {
|
||||
loading.value = false
|
||||
// 拉起jsapi支付
|
||||
const json = JSON.parse(data.payBody)
|
||||
jsapiPay(json)
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 拉起Jsapi支付窗口
|
||||
*/
|
||||
function jsapiPay(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') {
|
||||
// 跳转到成功页面
|
||||
router.push({ name: 'SuccessResult', query: { msg: '支付成功' }, replace: true })
|
||||
}
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
</style>
|
||||
11
src/views/daxpay/result/PayFail.vue
Normal file
11
src/views/daxpay/result/PayFail.vue
Normal file
@@ -0,0 +1,11 @@
|
||||
<script setup lang="ts">
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
||||
</template>
|
||||
|
||||
<style scoped lang="less">
|
||||
|
||||
</style>
|
||||
11
src/views/daxpay/result/PaySuccess.vue
Normal file
11
src/views/daxpay/result/PaySuccess.vue
Normal file
@@ -0,0 +1,11 @@
|
||||
<script setup lang="ts">
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
||||
</template>
|
||||
|
||||
<style scoped lang="less">
|
||||
|
||||
</style>
|
||||
@@ -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,25 +0,0 @@
|
||||
import { http } from '@/utils/http/axios'
|
||||
import type { Result } from '#/axios'
|
||||
|
||||
/**
|
||||
* 通过key获取信息路由信息
|
||||
*/
|
||||
export function getRouterByKey(key: string): Promise<Result<RouterInfo>> {
|
||||
return http.request({
|
||||
url: '/short/link/getRouterByKey',
|
||||
method: 'get',
|
||||
params: { key },
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 路由信息
|
||||
*/
|
||||
interface RouterInfo {
|
||||
// key值
|
||||
key: string
|
||||
// 路由键
|
||||
route: string
|
||||
// 数据信息
|
||||
data: string
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
<template>
|
||||
<div> 跳转中... </div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
// 获取路由参数
|
||||
import { useRouter } from 'vue-router'
|
||||
import { onMounted } from 'vue'
|
||||
import { getRouterByKey } from './Dispatch.api'
|
||||
import router from '@/router'
|
||||
|
||||
const { currentRoute } = useRouter()
|
||||
const { params } = unref(currentRoute)
|
||||
|
||||
onMounted(() => {
|
||||
const key = params.key as string
|
||||
getRouterByKey(key).then(({ data }) => {
|
||||
console.log(data)
|
||||
router.push({
|
||||
name: data.route,
|
||||
query: { data: data.data },
|
||||
})
|
||||
})
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
2
types/auto-imports.d.ts
vendored
2
types/auto-imports.d.ts
vendored
@@ -303,6 +303,6 @@ declare global {
|
||||
// for type re-export
|
||||
declare global {
|
||||
// @ts-ignore
|
||||
export type { Component, ComponentPublicInstance, ComputedRef, ExtractDefaultPropTypes, ExtractPropTypes, ExtractPublicPropTypes, InjectionKey, PropType, Ref, VNode, WritableComputedRef } from 'vue'
|
||||
export type { Component, ComponentPublicInstance, ComputedRef, DirectiveBinding, ExtractDefaultPropTypes, ExtractPropTypes, ExtractPublicPropTypes, InjectionKey, PropType, Ref, MaybeRef, MaybeRefOrGetter, VNode, WritableComputedRef } from 'vue'
|
||||
import('vue')
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user