前端打包

This commit is contained in:
2025-11-24 16:53:17 +08:00
parent df57d05817
commit b51faf731a
10 changed files with 218 additions and 385 deletions

View File

@@ -1,6 +1,7 @@
import axios, { AxiosResponse, AxiosError, InternalAxiosRequestConfig } from "axios";
import { ElLoading, ElMessage } from "element-plus";
import type { ResultDomain } from "@/types";
import { API_BASE_URL } from "@/config";
/**
* 扩展AxiosRequestConfig以支持自定义配置
@@ -67,9 +68,13 @@ export const TokenManager = {
/**
* 创建axios实例
*
* 说明:
* - 统一使用配置模块提供的 API_BASE_URL 作为基础路径
* - API_BASE_URL 在开发环境来自 devConfig在生产环境来自 window.APP_RUNTIME_CONFIG
*/
const request = axios.create({
baseURL: import.meta.env.VITE_API_BASE_URL || "/api",
baseURL: API_BASE_URL,
timeout: 30000,
headers: {
'Content-Type': 'application/json;charset=UTF-8',

View File

@@ -9,6 +9,9 @@ import type { SysMenu } from '@/types';
import { MenuType } from '@/types/enums';
import { routes } from '@/router';
// 预注册所有视图组件,构建时由 Vite 解析并生成按需加载的 chunk
const VIEW_MODULES = import.meta.glob('../views/**/*.vue');
/**
* 布局组件映射
*/
@@ -281,69 +284,44 @@ function findFirstMenuWithUrl(menus: SysMenu[]): SysMenu | null {
* @returns 组件异步加载函数
*/
function getComponent(componentName: string) {
// 检查是否是布局组件
// 1. 若是布局组件,直接返回预定义映射
if (LAYOUT_MAP[componentName]) {
return LAYOUT_MAP[componentName];
}
// 处理页面组件路径
// 2. 将后台给的 component 字段转换为 ../views/**.vue 形式的 key
let componentPath = componentName;
// 如果不是以@/开头的完整路径,则添加@/views/前缀
// 如果不是以 @/ 开头,则认为是相对 views 根目录的路径,例如 "user/home/HomeView"
if (!componentPath.startsWith('@/')) {
// 确保路径以/开头
if (!componentPath.startsWith('/')) {
componentPath = '/' + componentPath;
}
// 添加@/views前缀
componentPath = '@/views' + componentPath;
componentPath = '@/views' + componentPath; // => '@/views/user/home/HomeView'
}
// 将@/别名转换为相对路径因为Vite动态导入可能无法正确解析别名
if (componentPath.startsWith('@/')) {
componentPath = componentPath.replace('@/', '../');
}
// 如果没有.vue扩展名添加它
// 将别名 @/ 转为相对于当前文件的路径,必须与 import.meta.glob 中的模式一致
componentPath = componentPath.replace(/^@\//, '../'); // => '../views/user/home/HomeView'
// 补全 .vue 后缀
if (!componentPath.endsWith('.vue')) {
componentPath += '.vue';
}
// 动态导入组件
return () => {
return import(/* @vite-ignore */ componentPath)
.then(module => {
return module;
})
.catch(error => {
console.error('[路由生成] 组件加载失败:', {
原始组件名: componentName,
最终路径: componentPath,
错误: error
});
// 返回404组件
return import('@/views/public/error/404.vue').catch(() =>
Promise.resolve({
template: `<div class="component-error">
<h3>组件加载失败</h3>
<p>无法加载组件: ${componentPath}</p>
<p>原始组件名: ${componentName}</p>
<p>错误: ${error instanceof Error ? error.message : String(error)}</p>
</div>`,
style: `
.component-error {
padding: 20px;
text-align: center;
color: #f56565;
background: #fed7d7;
border-radius: 4px;
}
`
})
);
});
};
// 3. 从 VIEW_MODULES 中查找对应的 loader
const loader = VIEW_MODULES[componentPath];
if (!loader) {
console.error('[路由生成] 未找到组件模块', {
原始组件名: componentName,
期望路径: componentPath,
可用模块: Object.keys(VIEW_MODULES)
});
// 找不到时退回到 404 组件
return () => import('@/views/public/error/404.vue');
}
return loader as () => Promise<any>;
}
/**