refactor(h5): 重构为 mobile/pc/shared 三层目录并实现双端入口分发

- 目录三层化:移动端代码集中 src/mobile/(App.vue/router/layout/views),
  PC 端 src/pc/,公共层 src/shared/(api/components/store/utils/styles 等);
  批量改写 @/<共享目录> → @/shared/<共享目录>
- 双端入口:index.html 内联脚本探测设备写 window.__DEVICE__,main.ts 据此
  挂载移动端(#app) 或 PC(#pc-app),零闪烁;PC 走 scoped px,
  postcss-mobile-forever 排除 src/pc/
- 路由切 history 模式,两端首页统一 /,/home* 兼容重定向;
  PC catch-all 渲染独立 NotFound 组件(非 redirect)
- 构建配置同步:svg iconDirs、less additionalData、Components dirs、warmup 路径
This commit is contained in:
bootx
2026-06-24 12:02:57 +08:00
parent 7789c8a981
commit eb99deb803
62 changed files with 424 additions and 97 deletions

View File

@@ -20,6 +20,8 @@ export function createVitePlugins(viteEnv: ViteEnv, isBuild: boolean) {
vue(),
// 按需引入VantUi且自动创建组件声明
Components({
// 共享组件目录移动端使用PC 端独立,不扫描此处)
dirs: ['src/shared/components'],
dts: true,
resolvers: [VantResolver()],
types: [],

View File

@@ -9,7 +9,7 @@ import { createSvgIconsPlugin } from 'vite-plugin-svg-icons'
export function configSvgIconsPlugin(isBuild: boolean) {
// 指定需要缓存的图标文件夹
const svgIconsPlugin = createSvgIconsPlugin({
iconDirs: [path.resolve(process.cwd(), 'src/assets/icons')],
iconDirs: [path.resolve(process.cwd(), 'src/shared/assets/icons')],
// 是否压缩
svgoOptions: isBuild,
// 指定symbolId格式

View File

@@ -10,6 +10,22 @@
<div id="app">
<script>
;(() => {
// 设备类型探测:移动端 UA含 iPadOS 13+ 伪装桌面 UA 的情况)判定为 mobile其余为 pc
// 开发期可用 ?device=pc|mobile 查询参数强制覆盖,便于切端调试
const params = new URLSearchParams(window.location.search)
const override = params.get('device')
const ua = navigator.userAgent
const isTouch = navigator.maxTouchPoints > 0
const isMobileUA =
/(Mobile|Android|iPhone|iPod|Windows Phone)/i.test(ua) || (isTouch && /Macintosh/i.test(ua))
window.__DEVICE__ = override === 'pc' || override === 'mobile' ? override : isMobileUA ? 'mobile' : 'pc'
// PC 端只挂载 #pc-app隐藏 #app 内的移动端首屏 loading避免残留转圈
if (window.__DEVICE__ === 'pc') {
const appEl = document.getElementById('app')
if (appEl) appEl.style.display = 'none'
}
// 主题色从本地存储读取(用户可配置项持久化)
const { appTheme = '#5d9dfe' } = JSON.parse(window.localStorage.getItem('DESIGN-SETTING')) || {}
@@ -125,6 +141,8 @@
</div>
</div>
</div>
<!-- PC 端挂载点(与移动端 #app 并列,同一时刻仅其一被挂载) -->
<div id="pc-app"></div>
<script type="module" src="/src/main.ts"></script>
</body>
</html>

View File

@@ -45,8 +45,9 @@ export default {
autoprefixer(),
viewport({
...baseViewportOpts,
// 只将 vant 转为 375 设计稿的 viewport其它样式的视图宽度为 750
// viewportWidth: file => (file.includes('node_modules/vant/') ? 375 : 750),
// PC 端源码不转 vwPC 页面用 scoped 原生 px + 媒体查询写样式
// 见 AGENTS.md「PC/移动端双端支持」约束
exclude: [/src\/pc\//],
}),
],
}

View File

@@ -1,40 +1,23 @@
import { createApp } from 'vue'
import { setupStore } from '@/store'
import { useDesignSettingWithOut } from '@/store/modules/designSetting'
import App from './App.vue'
import router, { setupRouter } from './router'
import { createMobileApp } from '@/mobile/app'
import { createPCApp } from '@/pc/app'
// UnoCSS 全局样式与重置在入口统一导入一次PC/移动端共用
import 'virtual:uno.css'
import 'vant/es/toast/style'
import 'vant/es/dialog/style'
import 'vant/es/notify/style'
import 'vant/es/image-preview/style'
// https://unocss.dev/guide/style-reset#tailwind-compat
// 此重置基于 Tailwind 重置,减去按钮的背景颜色覆盖,以避免与 UI 框架发生冲突。请参阅链接的问题。
// 此重置基于 Tailwind 重置,减去按钮的背景颜色覆盖,以避免与 UI 框架发生冲突。
import '@unocss/reset/tailwind-compat.css'
// Register icon sprite
import 'virtual:svg-icons-register'
// 开发环境启用 vconsole 移动端调试面板(由 VITE_V_CONSOLE 控制,默认开启)
if (import.meta.env.DEV && import.meta.env.VITE_V_CONSOLE !== 'false') {
import('vconsole').then(({ default: VConsole }) => {
// eslint-disable-next-line no-new -- vconsole 以副作用方式实例化以挂载调试面板
new VConsole()
})
}
/**
* 应用入口分发器
*
* 由 index.html 内联脚本在 Vue 挂载前写入 window.__DEVICE__'pc' | 'mobile'
* 此处据此挂载对应应用,首屏即为正确设备 UI无重定向、无布局闪烁。
* - mobile → 挂载到 #app受 postcss-mobile-forever 限宽 600px 居中)
* - pc → 挂载到 #pc-app全宽px 不被转 vw
*/
async function bootstrap() {
const app = createApp(App)
// 挂载状态管理
setupStore(app)
// 初始化全局主题:跟随系统 prefers-color-scheme不支持手动修改
useDesignSettingWithOut().initSystemListener()
// 挂载路由
setupRouter(app)
await router.isReady()
// 路由准备就绪后挂载APP实例
app.mount('#app', true)
const isPC = window.__DEVICE__ === 'pc'
const app = isPC ? await createPCApp() : await createMobileApp()
app.mount(isPC ? '#pc-app' : '#app', true)
}
void bootstrap()

View File

@@ -1,7 +1,7 @@
<script setup lang="ts">
import { useDesignSetting } from '@/hooks/setting/useDesignSetting'
import { useRouteStore } from '@/store/modules/route'
import { darken, lighten } from '@/utils'
import { useDesignSetting } from '@/shared/hooks/setting/useDesignSetting'
import { useRouteStore } from '@/shared/store/modules/route'
import { darken, lighten } from '@/shared/utils'
const routeStore = useRouteStore()
const { getDarkMode, getAppTheme, getIsPageAnimate, getPageAnimateType } = useDesignSetting()
@@ -73,5 +73,5 @@ const getTransitionName = computed(() => {
</template>
<style lang="less">
@import './styles/index.less';
@import '../shared/styles/index.less';
</style>

36
src/mobile/app.ts Normal file
View File

@@ -0,0 +1,36 @@
import { createApp } from 'vue'
import MobileApp from '@/mobile/App.vue'
import router, { setupRouter } from '@/mobile/router'
import { setupStore } from '@/shared/store'
import { useDesignSettingWithOut } from '@/shared/store/modules/designSetting'
import 'vant/es/toast/style'
import 'vant/es/dialog/style'
import 'vant/es/notify/style'
import 'vant/es/image-preview/style'
// Register icon sprite
import 'virtual:svg-icons-register'
// 开发环境启用 vconsole 移动端调试面板(由 VITE_V_CONSOLE 控制,默认开启)
if (import.meta.env.DEV && import.meta.env.VITE_V_CONSOLE !== 'false') {
import('vconsole').then(({ default: VConsole }) => {
// eslint-disable-next-line no-new -- vconsole 以副作用方式实例化以挂载调试面板
new VConsole()
})
}
/**
* 创建移动端应用实例
* 挂载点:#app受 postcss-mobile-forever 的 appSelector 限宽 600px 居中)
*/
export async function createMobileApp() {
const app = createApp(MobileApp)
// 挂载状态管理
setupStore(app)
// 初始化全局主题:跟随系统 prefers-color-scheme不支持手动修改
useDesignSettingWithOut().initSystemListener()
// 挂载路由
setupRouter(app)
await router.isReady()
return app
}

View File

@@ -1,7 +1,7 @@
<script setup lang="ts">
import { computed } from 'vue'
import { useDesignSettingStore } from '@/store/modules/designSetting'
import { useRouteStore } from '@/store/modules/route'
import { useDesignSettingStore } from '@/shared/store/modules/designSetting'
import { useRouteStore } from '@/shared/store/modules/route'
defineOptions({ name: 'BasicLayout' })

View File

@@ -1,12 +1,11 @@
import type { RouteRecordRaw } from 'vue-router'
import { PageEnum } from '@/enums/pageEnum'
const Layout = () => import('@/layout/index.vue')
const Layout = () => import('@/mobile/layout/index.vue')
// 404 on a page
export const ErrorPageRoute: RouteRecordRaw = {
path: '/:path(.*)*',
name: PageEnum.ERROR_PAGE_NAME,
name: 'ErrorPage',
component: Layout,
meta: {
title: 'ErrorPage',
@@ -16,7 +15,7 @@ export const ErrorPageRoute: RouteRecordRaw = {
{
path: '/:path(.*)*',
name: 'ErrorPageSon',
component: () => import('@/views/exception/404.vue'),
component: () => import('@/mobile/views/exception/404.vue'),
meta: {
title: 'ErrorPage',
hideBreadcrumb: true,
@@ -24,12 +23,3 @@ export const ErrorPageRoute: RouteRecordRaw = {
},
],
}
export const RootRoute: RouteRecordRaw = {
path: '/',
name: 'Root',
redirect: PageEnum.BASE_HOME,
meta: {
title: 'Root',
},
}

View File

@@ -1,15 +1,13 @@
import type { App } from 'vue'
import type { RouteRecordRaw } from 'vue-router'
import { createRouter, createWebHashHistory } from 'vue-router'
import { ErrorPageRoute, RootRoute } from '@/router/base'
import { useRouteStoreWithOut } from '@/store/modules/route'
import { createRouter, createWebHistory } from 'vue-router'
import { useRouteStoreWithOut } from '@/shared/store/modules/route'
import { ErrorPageRoute } from './base'
import routeModuleList from './modules'
import { createRouterGuards } from './router-guards'
// 菜单
// 普通路由
export const constantRouter: RouteRecordRaw[] = [RootRoute, ErrorPageRoute]
export const constantRouter: RouteRecordRaw[] = [ErrorPageRoute]
const routeStore = useRouteStoreWithOut()
@@ -17,7 +15,7 @@ routeStore.setMenus(routeModuleList)
routeStore.setRouters(constantRouter.concat(routeModuleList))
const router = createRouter({
history: createWebHashHistory(''),
history: createWebHistory(import.meta.env.BASE_URL),
routes: constantRouter.concat(...routeModuleList),
strict: true,
scrollBehavior: () => ({ left: 0, top: 0 }),

View File

@@ -1,13 +1,13 @@
import type { RouteRecordRaw } from 'vue-router'
const Layout = () => import('@/layout/index.vue')
const Layout = () => import('@/mobile/layout/index.vue')
// 业务路由模块(等待业务开发,当前仅保留占位首页)
const routeModuleList: Array<RouteRecordRaw> = [
// 首页(根路径 /,与 PC 端首页地址统一)
{
path: '/home',
path: '/',
name: 'Home',
redirect: '/home/index',
component: Layout,
meta: {
title: '首页',
@@ -15,12 +15,12 @@ const routeModuleList: Array<RouteRecordRaw> = [
},
children: [
{
path: 'index',
path: '',
name: 'HomePage',
meta: {
keepAlive: true,
},
component: () => import('@/views/home/index.vue'),
component: () => import('@/mobile/views/home/index.vue'),
},
],
},

View File

@@ -1,7 +1,7 @@
import type { Router } from 'vue-router'
import NProgress from 'nprogress'
import { isNavigationFailure } from 'vue-router'
import { useRouteStoreWithOut } from '@/store/modules/route'
import { useRouteStoreWithOut } from '@/shared/store/modules/route'
import 'nprogress/nprogress.css'
NProgress.configure({ parent: '#app' })

View File

@@ -10,7 +10,7 @@ function goHome() {
<template>
<div class="page-container flex flex-col justify-center">
<div class="text-center">
<img src="~@/assets/icons/exception/404.svg" alt="">
<img src="~@/shared/assets/icons/exception/404.svg" alt="">
</div>
<div class="text-center">
<p class="m-4 text-base">

View File

@@ -1,5 +1,5 @@
<script setup lang="ts">
import Logo from '@/components/Logo.vue'
import Logo from '@/shared/components/Logo.vue'
defineOptions({ name: 'HomePage' })

7
src/pc/App.vue Normal file
View File

@@ -0,0 +1,7 @@
<script setup lang="ts">
defineOptions({ name: 'PcApp' })
</script>
<template>
<RouterView />
</template>

32
src/pc/app.ts Normal file
View File

@@ -0,0 +1,32 @@
import type { App } from 'vue'
import { createPinia } from 'pinia'
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'
import { createApp } from 'vue'
import PcApp from '@/pc/App.vue'
import { pcRouter, setupPCRouter } from '@/pc/router'
// PC 端独立的 pinia 实例(与移动端状态隔离,同一时刻仅一套应用运行)
const pcStore = createPinia()
pcStore.use(piniaPluginPersistedstate)
function setupPCStore(app: App) {
app.use(pcStore)
}
/**
* 创建 PC 端应用实例
*
* 挂载点:#pc-app独立于 #app不受 postcss-mobile-forever 的 appSelector 限宽影响)
*
* 样式约束PC 页面所有尺寸用 scoped <style>(原生 px + 媒体查询),
* 禁止使用 UnoCSS 的 px 原子类(如 p-4 / w-100 / text-2xl
* 它们会进入全局 UnoCSS 样式被 mobile-forever 转 vw在宽屏下错乱。
* UnoCSS 在 PC 仅限用非长度类flex / grid / hidden / 颜色 / 文字对齐等)。
*/
export async function createPCApp() {
const app = createApp(PcApp)
setupPCStore(app)
setupPCRouter(app)
await pcRouter.isReady()
return app
}

51
src/pc/layout/index.vue Normal file
View File

@@ -0,0 +1,51 @@
<script setup lang="ts">
defineOptions({ name: 'PcLayout' })
</script>
<template>
<div class="pc-shell">
<header class="pc-header">
<span class="pc-header__title">DaxPay · PC</span>
</header>
<main class="pc-main">
<RouterView />
</main>
</div>
</template>
<style scoped>
/* PC 端样式示范scoped 原生 px + 媒体查询,不使用 UnoCSS 的 px 原子类 */
.pc-shell {
min-height: 100vh;
background: #f5f6f8;
}
.pc-header {
height: 56px;
padding: 0 32px;
display: flex;
align-items: center;
background: #ffffff;
border-bottom: 1px solid #ebedf0;
}
.pc-header__title {
font-size: 18px;
font-weight: 600;
color: #1d2129;
}
.pc-main {
width: 100%;
max-width: 1200px;
margin: 0 auto;
padding: 32px;
box-sizing: border-box;
}
@media (max-width: 768px) {
.pc-main {
padding: 16px;
}
}
</style>

32
src/pc/router/index.ts Normal file
View File

@@ -0,0 +1,32 @@
import type { App } from 'vue'
import type { RouteRecordRaw } from 'vue-router'
import { createRouter, createWebHistory } from 'vue-router'
// PC 端路由树(独立于移动端,按需在此扩展业务路由,例如收银台 PC 版)
// 内页(收银台等)建议套 PcLayout首页为全屏独立页贴合移动端首页视觉
const routes: RouteRecordRaw[] = [
{
path: '/',
name: 'PcHome',
component: () => import('@/pc/views/Home.vue'),
},
// 兜底:移动端专属路径(如 /home/index或任何未匹配路径渲染 PC 404 页
// 用 component 而非 redirect——vue-router 5 下 catch-all + redirect 在初始导航不触发
{
path: '/:pathMatch(.*)*',
name: 'PcNotFound',
component: () => import('@/pc/views/NotFound.vue'),
},
]
const pcRouter = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
routes,
scrollBehavior: () => ({ left: 0, top: 0 }),
})
export function setupPCRouter(app: App) {
app.use(pcRouter)
}
export { pcRouter }

89
src/pc/views/Home.vue Normal file
View File

@@ -0,0 +1,89 @@
<script setup lang="ts">
defineOptions({ name: 'PcHome' })
// 由 vite define 注入的项目信息(与移动端首页一致)
const { pkg, lastBuildTime } = __APP_INFO__
const version = pkg.version
</script>
<template>
<div class="pc-home">
<div class="pc-home__body">
<div class="pc-home__welcome">
<!-- DaxPay 文字徽标与移动端首页默认 logo 一致public/logo.svg -->
<img class="pc-home__logo" src="/logo.svg" alt="DaxPay">
<!-- 欢迎语 -->
<div class="pc-home__title">
欢迎使用 DaxPay
</div>
</div>
</div>
<!-- 底部项目信息 -->
<div class="pc-home__footer">
<p>版本号: v{{ version }}</p>
<p>构建时间: {{ lastBuildTime }}</p>
</div>
</div>
</template>
<style scoped>
/* PC 端首页scoped 原生 px + 媒体查询,复刻移动端首页布局(全屏居中 + 底部信息) */
.pc-home {
min-height: 100vh;
display: flex;
flex-direction: column;
background: #f7f8fa;
}
.pc-home__body {
flex: 1;
display: flex;
align-items: center;
justify-content: center;
}
.pc-home__welcome {
display: flex;
flex-direction: column;
align-items: center;
}
.pc-home__logo {
width: 180px;
height: auto;
}
.pc-home__title {
margin-top: 16px;
text-align: center;
font-size: 28px;
font-weight: 900;
color: #1d2129;
}
.pc-home__footer {
position: fixed;
bottom: 24px;
left: 0;
right: 0;
text-align: center;
font-size: 12px;
opacity: 0.5;
line-height: 1.6;
color: #4e5969;
}
.pc-home__footer p {
margin: 0;
}
@media (max-width: 768px) {
.pc-home__logo {
width: 140px;
}
.pc-home__title {
font-size: 22px;
}
}
</style>

80
src/pc/views/NotFound.vue Normal file
View File

@@ -0,0 +1,80 @@
<script lang="ts" setup>
defineOptions({ name: 'PcNotFound' })
const router = useRouter()
function goHome() {
router.push('/')
}
</script>
<template>
<div class="pc-notfound">
<img class="pc-notfound__logo" src="/logo.svg" alt="DaxPay">
<p class="pc-notfound__code">
404
</p>
<p class="pc-notfound__text">
抱歉你访问的页面不存在
</p>
<button class="pc-notfound__btn" type="button" @click="goHome">
返回首页
</button>
</div>
</template>
<style scoped>
/* PC 端 404 页scoped 原生 px + 媒体查询,不使用 UnoCSS 的 px 原子类 */
.pc-notfound {
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
background: #f7f8fa;
}
.pc-notfound__logo {
width: 160px;
height: auto;
}
.pc-notfound__code {
margin: 24px 0 8px;
font-size: 56px;
font-weight: 900;
line-height: 1;
color: #1d2129;
}
.pc-notfound__text {
margin: 0 0 32px;
font-size: 16px;
color: #4e5969;
}
.pc-notfound__btn {
padding: 10px 28px;
font-size: 14px;
color: #ffffff;
background: #5d9dfe;
border: none;
border-radius: 6px;
cursor: pointer;
transition: opacity 0.2s ease;
}
.pc-notfound__btn:hover {
opacity: 0.85;
}
@media (max-width: 768px) {
.pc-notfound__logo {
width: 120px;
}
.pc-notfound__code {
font-size: 44px;
}
}
</style>

View File

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 20 KiB

View File

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 32 KiB

View File

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 34 KiB

View File

Before

Width:  |  Height:  |  Size: 4.1 KiB

After

Width:  |  Height:  |  Size: 4.1 KiB

View File

@@ -1,7 +1,7 @@
<script setup lang="ts">
import { appThemeList } from '@/settings/designSetting'
import { useDesignSettingStore } from '@/store/modules/designSetting'
import { hexToRgba } from '@/utils'
import { appThemeList } from '@/shared/settings/designSetting'
import { useDesignSettingStore } from '@/shared/store/modules/designSetting'
import { hexToRgba } from '@/shared/utils'
defineOptions({ name: 'Logo' })

View File

@@ -1,8 +1,8 @@
/* eslint-disable ts/no-duplicate-enum-values */
export enum PageEnum {
// 首页
BASE_HOME = '/home',
BASE_HOME_REDIRECT = '/home',
BASE_HOME = '/',
BASE_HOME_REDIRECT = '/',
// 错误
ERROR_PAGE_NAME = 'ErrorPage',
}

View File

@@ -1,6 +1,6 @@
import type { GlobConfig } from '#/config'
import { getAppEnvConfig } from '@/utils/env'
import { warn } from '@/utils/log'
import { getAppEnvConfig } from '@/shared/utils/env'
import { warn } from '@/shared/utils/log'
export function useGlobSetting(): Readonly<GlobConfig> {
const {

View File

@@ -1,5 +1,5 @@
import { computed } from 'vue'
import { useDesignSettingStore } from '@/store/modules/designSetting'
import { useDesignSettingStore } from '@/shared/store/modules/designSetting'
export function useDesignSetting() {
const designStore = useDesignSettingStore()

View File

@@ -1,7 +1,7 @@
import type { DesignSettingState } from '@/settings/designSetting'
import type { DesignSettingState } from '@/shared/settings/designSetting'
import { defineStore } from 'pinia'
import designSetting from '@/settings/designSetting'
import { store } from '@/store'
import designSetting from '@/shared/settings/designSetting'
import { store } from '@/shared/store'
const { systemPrefersDark, appTheme, appThemeList, isPageAnimate, pageAnimateType } = designSetting

View File

@@ -1,6 +1,6 @@
import type { RouteRecordRaw } from 'vue-router'
import { defineStore } from 'pinia'
import { store } from '@/store'
import { store } from '@/shared/store'
export interface IRouteState {
menus: RouteRecordRaw[]

View File

@@ -1,8 +1,8 @@
import type { GlobEnvConfig } from '#/config'
import { warn } from '@/utils/log'
import { getConfigFileName } from '../../build/getConfigFileName'
import { warn } from '@/shared/utils/log'
import { getConfigFileName } from '../../../build/getConfigFileName'
import pkg from '../../package.json'
import pkg from '../../../package.json'
export function getCommonStoragePrefix() {
const { VITE_GLOB_APP_SHORT_NAME } = getAppEnvConfig()

View File

@@ -5,8 +5,8 @@ import type { CreateAxiosOptions, RequestOptions, Result, UploadFileParams } fro
import axios from 'axios'
import { cloneDeep } from 'lodash-es'
import qs from 'qs'
import { ContentTypeEnum, RequestEnum } from '@/enums/httpEnum'
import { isFunction } from '@/utils/is'
import { ContentTypeEnum, RequestEnum } from '@/shared/enums/httpEnum'
import { isFunction } from '@/shared/utils/is'
import { AxiosCanceler } from './axiosCancel'

View File

@@ -3,7 +3,7 @@ import axios from 'axios'
import qs from 'qs'
import { isFunction } from '@/utils/is'
import { isFunction } from '@/shared/utils/is'
// 声明一个 Map 用于存储每个请求的标识 和 取消函数
let pendingMap = new Map<string, Canceler>()

View File

@@ -1,4 +1,4 @@
import { isObject, isString } from '@/utils/is'
import { isObject, isString } from '@/shared/utils/is'
const DATE_TIME_FORMAT = 'YYYY-MM-DD HH:mm'

View File

@@ -4,11 +4,11 @@ import type { AxiosTransform } from './axiosTransform'
import type { CreateAxiosOptions, RequestOptions, Result } from './types'
import axios from 'axios'
import { showDialog, showFailToast } from 'vant'
import { ContentTypeEnum, RequestEnum, ResultEnum } from '@/enums/httpEnum'
import { useGlobSetting } from '@/hooks/setting'
import { deepMerge, isUrl } from '@/utils'
import { isString } from '@/utils/is/'
import { setObjToUrlParams } from '@/utils/urlUtils'
import { ContentTypeEnum, RequestEnum, ResultEnum } from '@/shared/enums/httpEnum'
import { useGlobSetting } from '@/shared/hooks/setting'
import { deepMerge, isUrl } from '@/shared/utils'
import { isString } from '@/shared/utils/is/'
import { setObjToUrlParams } from '@/shared/utils/urlUtils'
import { VAxios } from './Axios'
import { checkStatus } from './checkStatus'
@@ -253,7 +253,7 @@ export const http = createAxios()
// 项目,多个不同 api 地址,直接在这里导出多个
// src/api ts 里面接口,就可以单独使用这个请求,
// import { httpTwo } from '@/utils/http/axios'
// import { httpTwo } from '@/shared/utils/http/axios'
// export const httpTwo = createAxios({
// requestOptions: {
// apiUrl: 'http://localhost:9001',

8
types/global.d.ts vendored
View File

@@ -10,6 +10,14 @@ import type {
// 在不是模块的文件中使用 declare global即不包含import / export是错误的因为这样的文件中的所有内容都在全局范围内。
declare global {
// 设备类型:由 index.html 内联脚本在 Vue 挂载前写入,'pc' | 'mobile'
const __DEVICE__: 'pc' | 'mobile'
interface Window {
// 设备类型:由 index.html 内联脚本在 Vue 挂载前写入,'pc' | 'mobile'
__DEVICE__: 'pc' | 'mobile'
}
const __APP_INFO__: {
pkg: {
name: string

View File

@@ -131,7 +131,7 @@ export default ({ command, mode }: ConfigEnv): UserConfig => {
modifyVars: {},
javascriptEnabled: true,
// 注入全局 less 变量
additionalData: `@import "src/styles/var.less";`,
additionalData: `@import "src/shared/styles/var.less";`,
},
},
},
@@ -145,8 +145,8 @@ export default ({ command, mode }: ConfigEnv): UserConfig => {
proxy: createProxy(VITE_PROXY),
// 预热文件以降低启动期间的初始页面加载时长
warmup: {
// 预热的客户端文件首页、views、 components
clientFiles: ['./index.html', './src/{views,components}/*'],
// 预热的客户端文件:首页、移动端 views、共享 components
clientFiles: ['./index.html', './src/{mobile/views,shared/components}/*'],
},
// proxy: {
// '/api': {