mirror of
https://gitee.com/bootx/dax-pay-h5.git
synced 2025-10-14 06:04:51 +00:00
feat 多商户适配中
This commit is contained in:
@@ -21,7 +21,7 @@ VITE_GLOB_UPLOAD_URL =
|
||||
VITE_GLOB_IMG_URL =
|
||||
|
||||
# 接口前缀
|
||||
VITE_GLOB_API_URL_PREFIX = /server
|
||||
VITE_GLOB_API_URL_PREFIX = /
|
||||
|
||||
|
||||
|
||||
|
@@ -4,7 +4,7 @@
|
||||
|
||||
# 网站根目录(与PC部署在一起, 所以根目录不可以为 /) 和 接口 (server) 前缀 这个是独立部署模式
|
||||
VITE_PUBLIC_PATH=/h5
|
||||
VITE_GLOB_API_URL_PREFIX=/server
|
||||
VITE_GLOB_API_URL_PREFIX=
|
||||
|
||||
# 是否删除console
|
||||
VITE_DROP_CONSOLE=true
|
||||
|
@@ -11,13 +11,15 @@
|
||||
## 🍒 项目地址
|
||||
|
||||
| 项目 | 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
|
||||
@@ -27,6 +29,7 @@
|
||||
密码:123456
|
||||
|
||||
### 网关接口
|
||||
|
||||
> 注:接口平台只开放支付网关相关的接口,不开放系统其他接口。
|
||||
|
||||
地址: https://daxpay.server.bootx.cn/doc.html
|
||||
@@ -36,6 +39,7 @@
|
||||
密码: 123456
|
||||
|
||||
### 收银台演示
|
||||
|
||||
> 请勿大额支付,可以通过后台管理端进行退款
|
||||
|
||||
电脑收银台地址: https://daxpay.demo.bootx.cn/#/cashier
|
||||
|
@@ -6,7 +6,7 @@ import { viteMockServe } from 'vite-plugin-mock'
|
||||
|
||||
export function configMockPlugin(isBuild: boolean, prodMock: boolean) {
|
||||
return viteMockServe({
|
||||
ignore: /^\_/,
|
||||
ignore: /^_/,
|
||||
mockPath: 'mock',
|
||||
localEnabled: !isBuild,
|
||||
prodEnabled: isBuild && prodMock,
|
||||
|
@@ -19,10 +19,7 @@
|
||||
}
|
||||
|
||||
// 设置主题色变量
|
||||
document.documentElement.style.setProperty(
|
||||
'--app-theme-color',
|
||||
appTheme,
|
||||
)
|
||||
document.documentElement.style.setProperty('--app-theme-color', appTheme)
|
||||
})()
|
||||
</script>
|
||||
<style>
|
||||
|
97
package.json
97
package.json
@@ -1,25 +1,10 @@
|
||||
{
|
||||
"name": "vue3-vant4-mobile",
|
||||
"name": "daxpay-h5",
|
||||
"type": "module",
|
||||
"version": "2.1.0",
|
||||
"private": true,
|
||||
"packageManager": "pnpm@8.6.10",
|
||||
"author": {
|
||||
"name": "xiangshu233",
|
||||
"email": "xiangshu233@outlook.com",
|
||||
"url": "https://github.com/xiangshu233"
|
||||
},
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/xiangshu233/vue3-vant4-mobile.git"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/xiangshu233/vue3-vant4-mobile/issues"
|
||||
},
|
||||
"version": "3.0.0",
|
||||
"engines": {
|
||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0",
|
||||
"pnpm": ">=8.6.10"
|
||||
"node": ">=18.12.0",
|
||||
"pnpm": ">=9.0.2"
|
||||
},
|
||||
"scripts": {
|
||||
"preinstall": "npx only-allow pnpm",
|
||||
@@ -40,60 +25,58 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@types/lodash-es": "^4.17.12",
|
||||
"@unocss/reset": "^0.58.5",
|
||||
"@vueuse/core": "^10.7.0",
|
||||
"axios": "^1.4.0",
|
||||
"date-fns": "^3.0.6",
|
||||
"echarts": "^5.4.3",
|
||||
"@unocss/reset": "^0.58.9",
|
||||
"@vueuse/core": "^10.11.1",
|
||||
"axios": "^1.7.7",
|
||||
"date-fns": "^3.6.0",
|
||||
"lodash-es": "^4.17.21",
|
||||
"mockjs": "^1.1.0",
|
||||
"nprogress": "^0.2.0",
|
||||
"pinia": "^2.1.7",
|
||||
"pinia": "^2.2.2",
|
||||
"pinia-plugin-persist": "^1.0.0",
|
||||
"qs": "^6.11.2",
|
||||
"vant": "^4.8.1",
|
||||
"vue": "^3.3.13",
|
||||
"qs": "^6.13.0",
|
||||
"vant": "^4.9.7",
|
||||
"vue": "^3.5.8",
|
||||
"vue-router": "4.2.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@antfu/eslint-config": "^2.6.3",
|
||||
"@commitlint/cli": "^18.4.3",
|
||||
"@commitlint/config-conventional": "^18.4.3",
|
||||
"@iconify/json": "^2.2.188",
|
||||
"@antfu/eslint-config": "^2.27.3",
|
||||
"@commitlint/cli": "^18.6.1",
|
||||
"@commitlint/config-conventional": "^18.6.3",
|
||||
"@iconify/json": "^2.2.252",
|
||||
"@types/fs-extra": "^11.0.4",
|
||||
"@types/mockjs": "^1.0.10",
|
||||
"@types/node": "^20.10.5",
|
||||
"@types/node": "^20.16.5",
|
||||
"@types/nprogress": "^0.2.3",
|
||||
"@types/qs": "^6.9.11",
|
||||
"@unocss/eslint-plugin": "^0.58.4",
|
||||
"@unocss/preset-icons": "^0.58.5",
|
||||
"@unocss/preset-rem-to-px": "^0.58.5",
|
||||
"@unocss/transformer-directives": "^0.58.4",
|
||||
"@unocss/transformer-variant-group": "^0.58.4",
|
||||
"@vitejs/plugin-vue": "^5.0.0",
|
||||
"autoprefixer": "^10.4.16",
|
||||
"@types/qs": "^6.9.16",
|
||||
"@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",
|
||||
"autoprefixer": "^10.4.20",
|
||||
"cross-env": "^7.0.3",
|
||||
"cz-git": "^1.8.0",
|
||||
"dotenv": "^16.3.1",
|
||||
"eslint": "^8.56.0",
|
||||
"eslint-plugin-format": "^0.1.0",
|
||||
"cz-git": "^1.9.4",
|
||||
"dotenv": "^16.4.5",
|
||||
"eslint": "^8.57.1",
|
||||
"eslint-plugin-format": "^0.1.2",
|
||||
"esno": "^0.16.3",
|
||||
"fs-extra": "^11.2.0",
|
||||
"less": "^4.2.0",
|
||||
"lint-staged": "^15.2.0",
|
||||
"lint-staged": "^15.2.10",
|
||||
"only-allow": "^1.2.1",
|
||||
"picocolors": "^1.0.0",
|
||||
"postcss": "^8.4.32",
|
||||
"postcss-mobile-forever": "^4.0.0",
|
||||
"picocolors": "^1.1.0",
|
||||
"postcss": "^8.4.47",
|
||||
"postcss-mobile-forever": "^4.1.6",
|
||||
"rimraf": "^3.0.2",
|
||||
"rollup": "^4.9.1",
|
||||
"rollup-plugin-visualizer": "^5.11.0",
|
||||
"simple-git-hooks": "^2.9.0",
|
||||
"typescript": "^5.3.3",
|
||||
"unocss": "^0.58.5",
|
||||
"unplugin-auto-import": "^0.17.5",
|
||||
"rollup": "^4.22.4",
|
||||
"rollup-plugin-visualizer": "^5.12.0",
|
||||
"simple-git-hooks": "^2.11.1",
|
||||
"typescript": "^5.6.2",
|
||||
"unocss": "^0.58.9",
|
||||
"unplugin-auto-import": "^0.17.8",
|
||||
"unplugin-vue-components": "^0.26.0",
|
||||
"vite": "^5.0.10",
|
||||
"vite": "5.2.6",
|
||||
"vite-plugin-compression": "^0.5.1",
|
||||
"vite-plugin-html": "^3.2.2",
|
||||
"vite-plugin-mock": "^2.9.8",
|
||||
|
11002
pnpm-lock.yaml
generated
11002
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@@ -1,86 +0,0 @@
|
||||
import { Result } from '#/axios'
|
||||
import { http } from '@/utils/http/axios'
|
||||
|
||||
/**
|
||||
* 获取文件预览地址
|
||||
*/
|
||||
export const getFilePreviewUrl = (id) => {
|
||||
return http.request<Result<string>>({
|
||||
url: `/file/getFilePreviewUrl`,
|
||||
method: 'get',
|
||||
params: { id },
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取文件预览地址前缀
|
||||
*/
|
||||
export const getFilePreviewUrlPrefix = () => {
|
||||
return http.request<Result<string>>({
|
||||
method: 'get',
|
||||
url: `/file/getFilePreviewUrlPrefix`,
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取文件下载地址
|
||||
*/
|
||||
export const getFileDownloadUrl = (id) => {
|
||||
return http.request<Result<string>>({
|
||||
method: 'get',
|
||||
url: `/file/getFileDownloadUrl`,
|
||||
params: { id },
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传文件信息
|
||||
*/
|
||||
export interface UpdateFileInfo {
|
||||
// id
|
||||
id?: number
|
||||
// 文件访问地址
|
||||
url?: string
|
||||
// 文件大小,单位字节
|
||||
size?: string
|
||||
// 文件名称
|
||||
filename?: string
|
||||
// 原始文件名
|
||||
originalFilename?: string
|
||||
// 基础存储路径
|
||||
basePath?: string
|
||||
// 存储路径
|
||||
path?: string
|
||||
// 文件扩展名
|
||||
ext?: string
|
||||
// MIME类型
|
||||
contentType?: string
|
||||
// 存储平台
|
||||
platform?: string
|
||||
// 缩略图访问路径
|
||||
thUrl?: string
|
||||
// 缩略图名称
|
||||
thFilename?: string
|
||||
// 缩略图大小,单位字节
|
||||
thSize?: string
|
||||
// 缩略图MIME类型
|
||||
thContentType?: string
|
||||
// 文件所属对象id
|
||||
objectId?: string
|
||||
// 文件所属对象类型,例如用户头像,评价图片
|
||||
objectType?: string
|
||||
// 文件元数据
|
||||
metadata?: string
|
||||
// 文件用户元数据
|
||||
userMetadata?: string
|
||||
// 缩略图元数据
|
||||
thMetadata?: string
|
||||
// 缩略图用户元数据
|
||||
thUserMetadata?: string
|
||||
// 附加属性
|
||||
attr?: string
|
||||
// 文件ACL
|
||||
fileAcl?: string
|
||||
// 缩略图文件ACL
|
||||
thFileAcl?: string
|
||||
}
|
@@ -1,5 +1,5 @@
|
||||
import { http } from '@/utils/http/axios'
|
||||
import { Result } from '#/axios'
|
||||
import type { Result } from '#/axios'
|
||||
|
||||
export interface BasicResponseModel<T = any> {
|
||||
code: number
|
||||
|
@@ -1,14 +0,0 @@
|
||||
// token key
|
||||
export const TOKEN_KEY = 'TOKEN'
|
||||
|
||||
// user info key
|
||||
export const USER_INFO_KEY = 'USER__INFO__'
|
||||
|
||||
// role info key
|
||||
export const ROLES_KEY = 'ROLES__KEY__'
|
||||
|
||||
// base global local key
|
||||
export const BASE_LOCAL_CACHE_KEY = 'LOCAL__CACHE__KEY__'
|
||||
|
||||
// base global session key
|
||||
export const BASE_SESSION_CACHE_KEY = 'SESSION__CACHE__KEY__'
|
@@ -1,11 +1,9 @@
|
||||
/* eslint-disable ts/no-duplicate-enum-values */
|
||||
export enum PageEnum {
|
||||
// 登录
|
||||
BASE_LOGIN = '/login',
|
||||
BASE_LOGIN_NAME = 'Login',
|
||||
// 首页
|
||||
BASE_HOME = '/dashboard',
|
||||
BASE_HOME_REDIRECT = '/dashboard',
|
||||
// 错误
|
||||
ERROR_PAGE_NAME = 'ErrorPage',
|
||||
}
|
||||
|
@@ -10,11 +10,10 @@ export function useGlobSetting(): Readonly<GlobConfig> {
|
||||
VITE_GLOB_APP_SHORT_NAME,
|
||||
VITE_GLOB_API_URL_PREFIX,
|
||||
VITE_GLOB_UPLOAD_URL,
|
||||
VITE_GLOB_PROD_MOCK,
|
||||
VITE_GLOB_IMG_URL,
|
||||
} = getAppEnvConfig()
|
||||
|
||||
if (!/[a-zA-Z\_]*/.test(VITE_GLOB_APP_SHORT_NAME)) {
|
||||
if (!/[a-z_]*/i.test(VITE_GLOB_APP_SHORT_NAME)) {
|
||||
warn(
|
||||
`VITE_GLOB_APP_SHORT_NAME Variables can only be characters/underscores, please modify in the environment variables and re-running.`,
|
||||
)
|
||||
@@ -28,7 +27,6 @@ export function useGlobSetting(): Readonly<GlobConfig> {
|
||||
shortName: VITE_GLOB_APP_SHORT_NAME,
|
||||
urlPrefix: VITE_GLOB_API_URL_PREFIX,
|
||||
uploadUrl: VITE_GLOB_UPLOAD_URL,
|
||||
prodMock: VITE_GLOB_PROD_MOCK,
|
||||
imgUrl: VITE_GLOB_IMG_URL,
|
||||
}
|
||||
return glob as Readonly<GlobConfig>
|
||||
|
@@ -1,122 +0,0 @@
|
||||
import type { EChartsOption } from 'echarts'
|
||||
import type { Ref } from 'vue'
|
||||
|
||||
import type { Fn } from '@vueuse/core'
|
||||
import { tryOnUnmounted, useDebounceFn } from '@vueuse/core'
|
||||
import { computed, nextTick, ref, unref, watch } from 'vue'
|
||||
import { useTimeoutFn } from '@/hooks/core/useTimeout'
|
||||
|
||||
import { useEventListener } from '@/hooks/event/useEventListener'
|
||||
import { useBreakpoint } from '@/hooks/event/useBreakpoint'
|
||||
import { useDesignSettingStore } from '@/store/modules/designSetting'
|
||||
import echarts from '@/utils/lib/echarts'
|
||||
|
||||
export function useECharts(
|
||||
elRef: Ref<HTMLDivElement>,
|
||||
theme: 'light' | 'dark' | 'default' = 'default',
|
||||
) {
|
||||
const designStore = useDesignSettingStore()
|
||||
|
||||
const getDarkMode = computed(() => {
|
||||
return theme === 'default' ? designStore.getDarkMode : theme
|
||||
})
|
||||
|
||||
let chartInstance: echarts.ECharts | null = null
|
||||
let resizeFn: Fn = resize
|
||||
const cacheOptions = ref({})
|
||||
let removeResizeFn: Fn = () => {}
|
||||
resizeFn = useDebounceFn(resize, 200)
|
||||
|
||||
const getOptions = computed((): EChartsOption => {
|
||||
if (getDarkMode.value !== 'dark') {
|
||||
return cacheOptions.value
|
||||
}
|
||||
return {
|
||||
backgroundColor: 'transparent',
|
||||
...cacheOptions.value,
|
||||
}
|
||||
})
|
||||
|
||||
function initCharts(t = theme) {
|
||||
const el = unref(elRef)
|
||||
if (!el || !unref(el)) {
|
||||
return
|
||||
}
|
||||
|
||||
chartInstance = echarts.init(el, t)
|
||||
const { removeEvent } = useEventListener({
|
||||
el: window,
|
||||
name: 'resize',
|
||||
listener: resizeFn,
|
||||
})
|
||||
removeResizeFn = removeEvent
|
||||
const { widthRef, screenEnum } = useBreakpoint()
|
||||
if (unref(widthRef) <= screenEnum.MD || el.offsetHeight === 0) {
|
||||
useTimeoutFn(() => {
|
||||
resizeFn()
|
||||
}, 30)
|
||||
}
|
||||
}
|
||||
|
||||
function setOptions(options: EChartsOption, clear = true) {
|
||||
cacheOptions.value = options
|
||||
if (unref(elRef)?.offsetHeight === 0) {
|
||||
useTimeoutFn(() => {
|
||||
setOptions(unref(getOptions))
|
||||
}, 30)
|
||||
return
|
||||
}
|
||||
nextTick(() => {
|
||||
useTimeoutFn(() => {
|
||||
if (!chartInstance) {
|
||||
initCharts(getDarkMode.value as 'default')
|
||||
|
||||
if (!chartInstance) {
|
||||
return
|
||||
}
|
||||
}
|
||||
clear && chartInstance?.clear()
|
||||
|
||||
chartInstance?.setOption(unref(getOptions))
|
||||
}, 30)
|
||||
})
|
||||
}
|
||||
|
||||
function resize() {
|
||||
chartInstance?.resize()
|
||||
}
|
||||
|
||||
watch(
|
||||
() => getDarkMode.value,
|
||||
(theme) => {
|
||||
if (chartInstance) {
|
||||
chartInstance.dispose()
|
||||
initCharts(theme as 'default')
|
||||
setOptions(cacheOptions.value)
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
tryOnUnmounted(() => {
|
||||
if (!chartInstance) {
|
||||
return
|
||||
}
|
||||
removeResizeFn()
|
||||
chartInstance.dispose()
|
||||
chartInstance = null
|
||||
})
|
||||
|
||||
function getInstance(): echarts.ECharts | null {
|
||||
if (!chartInstance) {
|
||||
initCharts(getDarkMode.value as 'default')
|
||||
}
|
||||
return chartInstance
|
||||
}
|
||||
|
||||
return {
|
||||
setOptions,
|
||||
resize,
|
||||
echarts,
|
||||
getInstance,
|
||||
}
|
||||
}
|
@@ -24,12 +24,3 @@ export const ErrorPageRoute: RouteRecordRaw = {
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
export const RootRoute: RouteRecordRaw = {
|
||||
path: '/',
|
||||
name: 'Root',
|
||||
redirect: PageEnum.BASE_HOME,
|
||||
meta: {
|
||||
title: 'Root',
|
||||
},
|
||||
}
|
||||
|
@@ -1,4 +1,5 @@
|
||||
import { RouteRecordRaw } from 'vue-router'
|
||||
import type { RouteRecordRaw } from 'vue-router'
|
||||
import { PageEnum } from '@/enums/pageEnum'
|
||||
|
||||
const Layout = () => import('@/layout/index.vue')
|
||||
|
||||
@@ -8,6 +9,7 @@ const Layout = () => import('@/layout/index.vue')
|
||||
export const BusinessRoute: RouteRecordRaw = {
|
||||
path: '/',
|
||||
name: '',
|
||||
redirect: PageEnum.BASE_HOME,
|
||||
component: Layout,
|
||||
children: [
|
||||
{
|
||||
|
@@ -1,4 +1,4 @@
|
||||
import { RouteRecordRaw } from 'vue-router'
|
||||
import type { RouteRecordRaw } from 'vue-router'
|
||||
|
||||
const Layout = () => import('@/layout/index.vue')
|
||||
|
||||
@@ -6,8 +6,8 @@ const Layout = () => import('@/layout/index.vue')
|
||||
* 演示模块路由
|
||||
*/
|
||||
export const DemoRoute: RouteRecordRaw = {
|
||||
path: '/',
|
||||
name: '',
|
||||
path: '/demo',
|
||||
name: 'demo',
|
||||
component: Layout,
|
||||
children: [
|
||||
{
|
||||
|
@@ -3,7 +3,7 @@ import type { RouteRecordRaw } from 'vue-router'
|
||||
import { createRouter, createWebHashHistory } from 'vue-router'
|
||||
import { createRouterGuards } from './router-guards'
|
||||
import routeModuleList from './modules'
|
||||
import { ErrorPageRoute, RootRoute } from '@/router/base'
|
||||
import { ErrorPageRoute } from '@/router/base'
|
||||
import { useRouteStoreWidthOut } from '@/store/modules/route'
|
||||
|
||||
// 菜单
|
||||
@@ -13,7 +13,6 @@ import { DemoRoute } from '@/router/demo'
|
||||
// 普通路由
|
||||
export const constantRouter: RouteRecordRaw[] = [
|
||||
DemoRoute,
|
||||
RootRoute,
|
||||
ErrorPageRoute,
|
||||
BusinessRoute,
|
||||
]
|
||||
|
@@ -19,7 +19,7 @@ export function getBoundingClientRect(element: Element): DOMRect | number {
|
||||
}
|
||||
|
||||
function trim(string: string) {
|
||||
return (string || '').replace(/^[\s\uFEFF]+|[\s\uFEFF]+$/g, '')
|
||||
return (string || '').replace(/^\s+|\s+$/g, '')
|
||||
}
|
||||
|
||||
/* istanbul ignore next */
|
||||
|
@@ -33,7 +33,7 @@ export function getAppEnvConfig() {
|
||||
VITE_GLOB_IMG_URL,
|
||||
} = ENV
|
||||
|
||||
if (!/^[a-zA-Z\_]*$/.test(VITE_GLOB_APP_SHORT_NAME)) {
|
||||
if (!/^[a-z_]*$/i.test(VITE_GLOB_APP_SHORT_NAME)) {
|
||||
warn(
|
||||
`VITE_GLOB_APP_SHORT_NAME Variables can only be characters/underscores, please modify in the environment variables and re-running.`,
|
||||
)
|
||||
|
@@ -55,7 +55,6 @@ export class VAxios {
|
||||
request<T = any>(config: AxiosRequestConfig, options?: RequestOptions): Promise<T> {
|
||||
let conf: any = cloneDeep(config)
|
||||
const transform = this.getTransform()
|
||||
|
||||
const { requestOptions } = this.options
|
||||
|
||||
const opt: RequestOptions = { ...requestOptions, ...options }
|
||||
@@ -69,7 +68,6 @@ export class VAxios {
|
||||
conf.requestOptions = opt
|
||||
// 支持 FormData
|
||||
conf = this.supportFormData(conf)
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
this.axiosInstance
|
||||
.request<any, AxiosResponse<Result>>(conf)
|
||||
|
@@ -1,10 +1,13 @@
|
||||
// axios配置 可自行根据项目进行更改,只需更改该文件即可,其他文件可以不动
|
||||
import type { AxiosResponse } from 'axios'
|
||||
import axios from 'axios'
|
||||
import { showDialog, showFailToast } from 'vant'
|
||||
import { VAxios } from './Axios'
|
||||
import { AxiosTransform } from './axiosTransform'
|
||||
import axios, { AxiosResponse } from 'axios'
|
||||
import type { AxiosTransform } from './axiosTransform'
|
||||
import { checkStatus } from './checkStatus'
|
||||
import { joinTimestamp, formatRequestDate } from './helper'
|
||||
import { RequestEnum, ResultEnum, ContentTypeEnum } from '@/enums/httpEnum'
|
||||
import { formatRequestDate, joinTimestamp } from './helper'
|
||||
import type { CreateAxiosOptions, RequestOptions } from './types'
|
||||
import { ContentTypeEnum, RequestEnum, ResultEnum } from '@/enums/httpEnum'
|
||||
import { PageEnum } from '@/enums/pageEnum'
|
||||
import { useGlobSetting } from '@/hooks/setting'
|
||||
|
||||
@@ -12,17 +15,14 @@ import { isString } from '@/utils/is/'
|
||||
import { deepMerge, isUrl } from '@/utils'
|
||||
import { setObjToUrlParams } from '@/utils/urlUtils'
|
||||
|
||||
import { RequestOptions, CreateAxiosOptions } from './types'
|
||||
|
||||
import { useUserStoreWidthOut } from '@/store/modules/user'
|
||||
|
||||
const globSetting = useGlobSetting()
|
||||
const urlPrefix = globSetting.urlPrefix || ''
|
||||
|
||||
import router from '@/router'
|
||||
import { storage } from '@/utils/Storage'
|
||||
import { showFailToast, showDialog } from 'vant'
|
||||
import { Result } from '#/axios'
|
||||
import type { Result } from '#/axios'
|
||||
|
||||
const globSetting = useGlobSetting()
|
||||
const urlPrefix = globSetting.urlPrefix
|
||||
|
||||
/**
|
||||
* @description: 数据处理,方便区分多种处理方式
|
||||
@@ -70,10 +70,12 @@ const transform: AxiosTransform = {
|
||||
}).then(() => {
|
||||
// on close
|
||||
})
|
||||
} else if (!hasSuccess && (errorMessageText || isShowErrorMessage)) {
|
||||
}
|
||||
else if (!hasSuccess && (errorMessageText || isShowErrorMessage)) {
|
||||
// 是否显示自定义信息提示
|
||||
showFailToast(msg || errorMessageText || '操作失败!')
|
||||
} else if (!hasSuccess && options.errorMessageMode === 'modal') {
|
||||
}
|
||||
else if (!hasSuccess && options.errorMessageMode === 'modal') {
|
||||
// errorMessageMode=‘custom-modal’的时候会显示modal错误弹窗,而不是消息提示,用于一些比较重要的错误
|
||||
showDialog({
|
||||
title: '提示',
|
||||
@@ -100,7 +102,9 @@ const transform: AxiosTransform = {
|
||||
case ResultEnum.TOKEN_EXPIRED:
|
||||
const LoginName = PageEnum.BASE_LOGIN_NAME
|
||||
const LoginPath = PageEnum.BASE_LOGIN
|
||||
if (router.currentRoute.value?.name === LoginName) return
|
||||
if (router.currentRoute.value?.name === LoginName) {
|
||||
return
|
||||
}
|
||||
// 到登录页
|
||||
errorMsg = '登录超时,请重新登录!'
|
||||
showDialog({
|
||||
@@ -122,7 +126,6 @@ const transform: AxiosTransform = {
|
||||
// 请求之前处理config
|
||||
beforeRequestHook: (config, options) => {
|
||||
const { apiUrl, joinPrefix, joinParamsToUrl, formatDate, joinTime = true, urlPrefix } = options
|
||||
|
||||
const isUrlStr = isUrl(config.url as string)
|
||||
|
||||
if (!isUrlStr && joinPrefix) {
|
||||
@@ -138,22 +141,25 @@ const transform: AxiosTransform = {
|
||||
if (!isString(params)) {
|
||||
// 给 get 请求加上时间戳参数,避免从缓存中拿数据。
|
||||
config.params = Object.assign(params || {}, joinTimestamp(joinTime, false))
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
// 兼容restful风格
|
||||
config.url = config.url + params + `${joinTimestamp(joinTime, true)}`
|
||||
config.url = `${config.url + params}${joinTimestamp(joinTime, true)}`
|
||||
config.params = undefined
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
if (!isString(params)) {
|
||||
formatDate && formatRequestDate(params)
|
||||
if (
|
||||
Reflect.has(config, 'data') &&
|
||||
config.data &&
|
||||
(Object.keys(config.data).length > 0 || config.data instanceof FormData)
|
||||
Reflect.has(config, 'data')
|
||||
&& config.data
|
||||
&& (Object.keys(config.data).length > 0 || config.data instanceof FormData)
|
||||
) {
|
||||
config.data = data
|
||||
config.params = params
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
config.data = data
|
||||
// params 是添加到 url 的请求字符串中的,用于 get 请求
|
||||
config.params = params
|
||||
@@ -161,10 +167,11 @@ const transform: AxiosTransform = {
|
||||
if (joinParamsToUrl) {
|
||||
config.url = setObjToUrlParams(
|
||||
config.url as string,
|
||||
Object.assign({}, config.params, config.data),
|
||||
{ ...config.params, ...config.data },
|
||||
)
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
// 兼容restful风格
|
||||
config.url = config.url + params
|
||||
config.params = undefined
|
||||
@@ -192,11 +199,11 @@ const transform: AxiosTransform = {
|
||||
responseInterceptorsCatch: (error: any) => {
|
||||
const { response, code, message } = error || {}
|
||||
// TODO 此处要根据后端接口返回格式修改
|
||||
const msg: string =
|
||||
response && response.data && response.data.message ? response.data.message : ''
|
||||
const msg: string
|
||||
= response && response.data && response.data.message ? response.data.message : ''
|
||||
const err: string = error.toString()
|
||||
try {
|
||||
if (code === 'ECONNABORTED' && message.indexOf('timeout') !== -1) {
|
||||
if (code === 'ECONNABORTED' && message.includes('timeout')) {
|
||||
showFailToast('接口请求超时,请刷新页面重试!')
|
||||
return
|
||||
}
|
||||
@@ -209,7 +216,8 @@ const transform: AxiosTransform = {
|
||||
.catch(() => {})
|
||||
return Promise.reject(error)
|
||||
}
|
||||
} catch (error) {
|
||||
}
|
||||
catch (error) {
|
||||
console.log(error)
|
||||
throw new Error(error as any)
|
||||
}
|
||||
@@ -217,10 +225,11 @@ const transform: AxiosTransform = {
|
||||
const isCancel = axios.isCancel(error)
|
||||
if (!isCancel) {
|
||||
checkStatus(error.response && error.response.status, msg)
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
console.warn(error, '请求被取消!')
|
||||
}
|
||||
//return Promise.reject(error);
|
||||
// return Promise.reject(error);
|
||||
return Promise.reject(response?.data)
|
||||
},
|
||||
}
|
||||
@@ -257,7 +266,7 @@ function createAxios(opt?: Partial<CreateAxiosOptions>) {
|
||||
// 接口地址
|
||||
apiUrl: globSetting.apiUrl,
|
||||
// 接口拼接地址
|
||||
urlPrefix: urlPrefix,
|
||||
urlPrefix,
|
||||
// 是否加入时间戳
|
||||
joinTime: true,
|
||||
// 忽略重复请求
|
||||
|
@@ -1,57 +0,0 @@
|
||||
import * as echarts from 'echarts/core'
|
||||
|
||||
import {
|
||||
BarChart,
|
||||
GaugeChart,
|
||||
LineChart,
|
||||
MapChart,
|
||||
PictorialBarChart,
|
||||
PieChart,
|
||||
RadarChart,
|
||||
} from 'echarts/charts'
|
||||
|
||||
import {
|
||||
AriaComponent,
|
||||
CalendarComponent,
|
||||
DataZoomComponent,
|
||||
GridComponent,
|
||||
LegendComponent,
|
||||
MarkLineComponent,
|
||||
ParallelComponent,
|
||||
PolarComponent,
|
||||
RadarComponent,
|
||||
TimelineComponent,
|
||||
TitleComponent,
|
||||
ToolboxComponent,
|
||||
TooltipComponent,
|
||||
VisualMapComponent,
|
||||
} from 'echarts/components'
|
||||
|
||||
import { SVGRenderer } from 'echarts/renderers'
|
||||
|
||||
echarts.use([
|
||||
LegendComponent,
|
||||
TitleComponent,
|
||||
TooltipComponent,
|
||||
GridComponent,
|
||||
PolarComponent,
|
||||
AriaComponent,
|
||||
ParallelComponent,
|
||||
BarChart,
|
||||
LineChart,
|
||||
PieChart,
|
||||
MapChart,
|
||||
RadarChart,
|
||||
GaugeChart,
|
||||
SVGRenderer,
|
||||
PictorialBarChart,
|
||||
RadarComponent,
|
||||
ToolboxComponent,
|
||||
DataZoomComponent,
|
||||
VisualMapComponent,
|
||||
TimelineComponent,
|
||||
CalendarComponent,
|
||||
MarkLineComponent,
|
||||
])
|
||||
|
||||
export default echarts
|
4
types/auto-imports.d.ts
vendored
4
types/auto-imports.d.ts
vendored
@@ -74,6 +74,7 @@ declare global {
|
||||
const onStartTyping: typeof import('@vueuse/core')['onStartTyping']
|
||||
const onUnmounted: typeof import('vue')['onUnmounted']
|
||||
const onUpdated: typeof import('vue')['onUpdated']
|
||||
const onWatcherCleanup: typeof import('vue')['onWatcherCleanup']
|
||||
const pausableWatch: typeof import('@vueuse/core')['pausableWatch']
|
||||
const provide: typeof import('vue')['provide']
|
||||
const provideLocal: typeof import('@vueuse/core')['provideLocal']
|
||||
@@ -185,6 +186,7 @@ declare global {
|
||||
const useFullscreen: typeof import('@vueuse/core')['useFullscreen']
|
||||
const useGamepad: typeof import('@vueuse/core')['useGamepad']
|
||||
const useGeolocation: typeof import('@vueuse/core')['useGeolocation']
|
||||
const useId: typeof import('vue')['useId']
|
||||
const useIdle: typeof import('@vueuse/core')['useIdle']
|
||||
const useImage: typeof import('@vueuse/core')['useImage']
|
||||
const useInfiniteScroll: typeof import('@vueuse/core')['useInfiniteScroll']
|
||||
@@ -201,6 +203,7 @@ declare global {
|
||||
const useMediaQuery: typeof import('@vueuse/core')['useMediaQuery']
|
||||
const useMemoize: typeof import('@vueuse/core')['useMemoize']
|
||||
const useMemory: typeof import('@vueuse/core')['useMemory']
|
||||
const useModel: typeof import('vue')['useModel']
|
||||
const useMounted: typeof import('@vueuse/core')['useMounted']
|
||||
const useMouse: typeof import('@vueuse/core')['useMouse']
|
||||
const useMouseInElement: typeof import('@vueuse/core')['useMouseInElement']
|
||||
@@ -248,6 +251,7 @@ declare global {
|
||||
const useStyleTag: typeof import('@vueuse/core')['useStyleTag']
|
||||
const useSupported: typeof import('@vueuse/core')['useSupported']
|
||||
const useSwipe: typeof import('@vueuse/core')['useSwipe']
|
||||
const useTemplateRef: typeof import('vue')['useTemplateRef']
|
||||
const useTemplateRefsList: typeof import('@vueuse/core')['useTemplateRefsList']
|
||||
const useTextDirection: typeof import('@vueuse/core')['useTextDirection']
|
||||
const useTextSelection: typeof import('@vueuse/core')['useTextSelection']
|
||||
|
18
types/axios.d.ts
vendored
18
types/axios.d.ts
vendored
@@ -2,19 +2,19 @@
|
||||
* 通用响应类
|
||||
*/
|
||||
export interface Result<T = any> {
|
||||
code: number;
|
||||
type: 'success' | 'error' | 'warning';
|
||||
msg: string;
|
||||
traceId: string | null | undefined;
|
||||
data: T;
|
||||
code: number
|
||||
type: 'success' | 'error' | 'warning'
|
||||
msg: string
|
||||
traceId: string | null | undefined
|
||||
data: T
|
||||
}
|
||||
|
||||
/**
|
||||
* 分页响应类
|
||||
*/
|
||||
export interface PageResult<T = any> {
|
||||
current: number;
|
||||
records: Array<T>;
|
||||
size: number;
|
||||
total: number;
|
||||
current: number
|
||||
records: Array<T>
|
||||
size: number
|
||||
total: number
|
||||
}
|
||||
|
28
types/config.d.ts
vendored
28
types/config.d.ts
vendored
@@ -1,26 +1,26 @@
|
||||
export interface GlobConfig {
|
||||
title: string;
|
||||
titleCN: string;
|
||||
apiUrl: string;
|
||||
shortName: string;
|
||||
urlPrefix?: string;
|
||||
uploadUrl?: string;
|
||||
imgUrl?: string;
|
||||
title: string
|
||||
titleCN: string
|
||||
apiUrl: string
|
||||
shortName: string
|
||||
urlPrefix?: string
|
||||
uploadUrl?: string
|
||||
imgUrl?: string
|
||||
}
|
||||
|
||||
export interface GlobEnvConfig {
|
||||
// 标题
|
||||
VITE_GLOB_APP_TITLE: string;
|
||||
VITE_GLOB_APP_TITLE: string
|
||||
// 中文标题
|
||||
VITE_GLOB_APP_TITLE_CN: string;
|
||||
VITE_GLOB_APP_TITLE_CN: string
|
||||
// 接口地址
|
||||
VITE_GLOB_API_URL: string;
|
||||
VITE_GLOB_API_URL: string
|
||||
// 接口前缀
|
||||
VITE_GLOB_API_URL_PREFIX?: string;
|
||||
VITE_GLOB_API_URL_PREFIX?: string
|
||||
// Project abbreviation
|
||||
VITE_GLOB_APP_SHORT_NAME: string;
|
||||
VITE_GLOB_APP_SHORT_NAME: string
|
||||
// 图片上传地址
|
||||
VITE_GLOB_UPLOAD_URL?: string;
|
||||
VITE_GLOB_UPLOAD_URL?: string
|
||||
// 图片前缀地址
|
||||
VITE_GLOB_IMG_URL?: string;
|
||||
VITE_GLOB_IMG_URL?: string
|
||||
}
|
||||
|
74
types/global.d.ts
vendored
74
types/global.d.ts
vendored
@@ -1,9 +1,9 @@
|
||||
import type {
|
||||
VNodeChild,
|
||||
ComponentPublicInstance,
|
||||
FunctionalComponent,
|
||||
VNodeChild,
|
||||
PropType as VuePropType,
|
||||
} from 'vue';
|
||||
} from 'vue'
|
||||
|
||||
// declare global 在具有 import 或 export 声明全局范围内的事物的文件中使用。
|
||||
// 这在包含 import 或 export 因为此类文件被视为模块的文件中是必需的,并且在模块中声明的任何内容都在模块范围内。
|
||||
@@ -12,64 +12,64 @@ import type {
|
||||
declare global {
|
||||
const __APP_INFO__: {
|
||||
pkg: {
|
||||
name: string;
|
||||
version: string;
|
||||
dependencies: Recordable<string>;
|
||||
devDependencies: Recordable<string>;
|
||||
};
|
||||
lastBuildTime: string;
|
||||
};
|
||||
name: string
|
||||
version: string
|
||||
dependencies: Recordable<string>
|
||||
devDependencies: Recordable<string>
|
||||
}
|
||||
lastBuildTime: string
|
||||
}
|
||||
|
||||
// vue
|
||||
type PropType<T> = VuePropType<T>;
|
||||
type VueNode = VNodeChild | JSX.Element;
|
||||
type PropType<T> = VuePropType<T>
|
||||
type VueNode = VNodeChild | JSX.Element
|
||||
|
||||
export type Writable<T> = {
|
||||
-readonly [P in keyof T]: T[P];
|
||||
};
|
||||
}
|
||||
|
||||
type Nullable<T> = T | null;
|
||||
type NonNullable<T> = T extends null | undefined ? never : T;
|
||||
type Recordable<T = any> = Record<string, T>;
|
||||
type ReadonlyRecordable<T = any> = {
|
||||
readonly [key: string]: T;
|
||||
};
|
||||
type Indexable<T = any> = {
|
||||
[key: string]: T;
|
||||
};
|
||||
type Nullable<T> = T | null
|
||||
type NonNullable<T> = T extends null | undefined ? never : T
|
||||
type Recordable<T = any> = Record<string, T>
|
||||
interface ReadonlyRecordable<T = any> {
|
||||
readonly [key: string]: T
|
||||
}
|
||||
interface Indexable<T = any> {
|
||||
[key: string]: T
|
||||
}
|
||||
type DeepPartial<T> = {
|
||||
[P in keyof T]?: DeepPartial<T[P]>;
|
||||
};
|
||||
type TimeoutHandle = ReturnType<typeof setTimeout>;
|
||||
type IntervalHandle = ReturnType<typeof setInterval>;
|
||||
}
|
||||
type TimeoutHandle = ReturnType<typeof setTimeout>
|
||||
type IntervalHandle = ReturnType<typeof setInterval>
|
||||
|
||||
interface ChangeEvent extends Event {
|
||||
target: HTMLInputElement;
|
||||
target: HTMLInputElement
|
||||
}
|
||||
|
||||
interface WheelEvent {
|
||||
path?: EventTarget[];
|
||||
path?: EventTarget[]
|
||||
}
|
||||
|
||||
interface ImportMetaEnv extends ViteEnv {
|
||||
__: unknown;
|
||||
__: unknown
|
||||
}
|
||||
|
||||
interface ViteEnv {
|
||||
VITE_PORT: number;
|
||||
VITE_PUBLIC_PATH: string;
|
||||
VITE_GLOB_APP_TITLE: string;
|
||||
VITE_GLOB_APP_SHORT_NAME: string;
|
||||
VITE_DROP_CONSOLE: boolean;
|
||||
VITE_GLOB_IMG_URL: string;
|
||||
VITE_PROXY: [string, string][];
|
||||
VITE_BUILD_COMPRESS: 'gzip' | 'brotli' | 'none';
|
||||
VITE_BUILD_COMPRESS_DELETE_ORIGIN_FILE: boolean;
|
||||
VITE_PORT: number
|
||||
VITE_PUBLIC_PATH: string
|
||||
VITE_GLOB_APP_TITLE: string
|
||||
VITE_GLOB_APP_SHORT_NAME: string
|
||||
VITE_DROP_CONSOLE: boolean
|
||||
VITE_GLOB_IMG_URL: string
|
||||
VITE_PROXY: [string, string][]
|
||||
VITE_BUILD_COMPRESS: 'gzip' | 'brotli' | 'none'
|
||||
VITE_BUILD_COMPRESS_DELETE_ORIGIN_FILE: boolean
|
||||
}
|
||||
}
|
||||
|
||||
declare module 'vue' {
|
||||
export type JSXComponent<Props = any> =
|
||||
| { new (): ComponentPublicInstance<Props> }
|
||||
| FunctionalComponent<Props>;
|
||||
| FunctionalComponent<Props>
|
||||
}
|
||||
|
26
types/index.d.ts
vendored
26
types/index.d.ts
vendored
@@ -1,29 +1,29 @@
|
||||
declare interface Fn<T = any, R = T> {
|
||||
(...arg: T[]): R;
|
||||
(...arg: T[]): R
|
||||
}
|
||||
|
||||
declare interface PromiseFn<T = any, R = T> {
|
||||
(...arg: T[]): Promise<R>;
|
||||
(...arg: T[]): Promise<R>
|
||||
}
|
||||
|
||||
declare type RefType<T> = T | null;
|
||||
declare type RefType<T> = T | null
|
||||
|
||||
// 就是数组里的 value 是这个对象类型
|
||||
declare type LabelValueOptions = {
|
||||
label: string;
|
||||
value: any;
|
||||
disabled: boolean;
|
||||
[key: string]: string | number | boolean;
|
||||
}[];
|
||||
label: string
|
||||
value: any
|
||||
disabled: boolean
|
||||
[key: string]: string | number | boolean
|
||||
}[]
|
||||
|
||||
declare type EmitType = (event: string, ...args: any[]) => void;
|
||||
declare type EmitType = (event: string, ...args: any[]) => void
|
||||
|
||||
declare type TargetContext = '_self' | '_blank';
|
||||
declare type TargetContext = '_self' | '_blank'
|
||||
|
||||
declare interface ComponentElRef<T extends HTMLElement = HTMLDivElement> {
|
||||
$el: T;
|
||||
$el: T
|
||||
}
|
||||
|
||||
declare type ComponentRef<T extends HTMLElement = HTMLDivElement> = ComponentElRef<T> | null;
|
||||
declare type ComponentRef<T extends HTMLElement = HTMLDivElement> = ComponentElRef<T> | null
|
||||
|
||||
declare type ElRef<T extends HTMLElement = HTMLDivElement> = Nullable<T>;
|
||||
declare type ElRef<T extends HTMLElement = HTMLDivElement> = Nullable<T>
|
||||
|
7
types/modules.d.ts
vendored
7
types/modules.d.ts
vendored
@@ -1,7 +1,8 @@
|
||||
/// <reference types="vite/client" />
|
||||
|
||||
declare module '*.vue' {
|
||||
import { DefineComponent } from 'vue';
|
||||
const Component: DefineComponent<{}, {}, any>;
|
||||
export default Component;
|
||||
import type { DefineComponent } from 'vue'
|
||||
|
||||
const Component: DefineComponent<{}, {}, any>
|
||||
export default Component
|
||||
}
|
||||
|
18
types/web.d.ts
vendored
18
types/web.d.ts
vendored
@@ -1,13 +1,13 @@
|
||||
import { PageResult } from "@/types/axios";
|
||||
import type { PageResult } from '@/types/axios'
|
||||
|
||||
/**
|
||||
* 分页参数
|
||||
*/
|
||||
export interface PageParam {
|
||||
// 每页数量
|
||||
size: number;
|
||||
size: number
|
||||
// 当前页数
|
||||
current: number;
|
||||
current: number
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -15,24 +15,24 @@ export interface PageParam {
|
||||
*/
|
||||
export interface TablePageModel<T = any> {
|
||||
// 分页参数
|
||||
pages: PageParam;
|
||||
pages: PageParam
|
||||
// 查询参数
|
||||
queryParam: object;
|
||||
queryParam: object
|
||||
// 结果
|
||||
pagination: PageResult<T>;
|
||||
pagination: PageResult<T>
|
||||
}
|
||||
|
||||
/**
|
||||
* 基础实体对象
|
||||
*/
|
||||
export interface BaseEntity {
|
||||
id?: number | string | null;
|
||||
id?: number | string | null
|
||||
}
|
||||
|
||||
/**
|
||||
* 键值对对象
|
||||
*/
|
||||
export interface KeyValue {
|
||||
key: string;
|
||||
value: string;
|
||||
key: string
|
||||
value: string
|
||||
}
|
||||
|
@@ -48,12 +48,12 @@ export default ({ command, mode }: ConfigEnv): UserConfig => {
|
||||
alias: [
|
||||
// @/xxxx => src/xxxx
|
||||
{
|
||||
find: /\@\//,
|
||||
find: /@\//,
|
||||
replacement: `${pathResolve('src')}/`,
|
||||
},
|
||||
// #/xxxx => types/xxxx
|
||||
{
|
||||
find: /\#\//,
|
||||
find: /#\//,
|
||||
replacement: `${pathResolve('types')}/`,
|
||||
},
|
||||
],
|
||||
|
Reference in New Issue
Block a user