mock数据,AI对话,全部应用

This commit is contained in:
2025-12-12 18:17:38 +08:00
parent 8b211fbad6
commit 0a72416365
41 changed files with 5667 additions and 205 deletions

View File

@@ -0,0 +1,261 @@
import { RouteRecordRaw, RouteLocationNormalized } from 'vue-router';
import { getDeviceType, DeviceType } from './deviceUtils';
/**
* 路由适配器接口
*/
export interface RouteAdapter {
original: () => Promise<any>; // web桌面端
mobile?: () => Promise<any>; // h5移动端
}
/**
* 移动端路由映射表
*/
export const MOBILE_ROUTES_MAP: Record<string, string> = {
// User Views
'/home': '@/views/user/home/HomeView.mobile.vue',
'/resource-center': '@/views/user/resource-center/ResourceCenterView.mobile.vue',
'/resource-hot': '@/views/user/resource-center/HotResourceView.mobile.vue',
'/search': '@/views/user/resource-center/SearchView.mobile.vue',
'/course-center': '@/views/user/study-plan/CourseCenterView.mobile.vue',
'/course-detail': '@/views/user/study-plan/CourseDetailView.mobile.vue',
'/course-study': '@/views/user/study-plan/CourseStudyView.mobile.vue',
'/study-tasks': '@/views/user/study-plan/StudyTasksView.mobile.vue',
'/learning-task-detail': '@/views/user/study-plan/LearningTaskDetailView.mobile.vue',
'/user-center': '@/views/user/user-center/UserCenterLayout.mobile.vue',
'/personal-info': '@/views/user/user-center/profile/PersonalInfoView.mobile.vue',
'/account-settings': '@/views/user/user-center/profile/AccountSettingsView.mobile.vue',
'/my-achievements': '@/views/user/user-center/MyAchievementsView.mobile.vue',
'/my-favorites': '@/views/user/user-center/MyFavoritesView.mobile.vue',
'/learning-records': '@/views/user/user-center/LearningRecordsView.mobile.vue',
'/my-messages': '@/views/user/message/MyMessageListView.mobile.vue',
'/message-detail': '@/views/user/message/MyMessageDetailView.mobile.vue',
// Public Views
'/login': '@/views/public/login/Login.mobile.vue',
'/register': '@/views/public/login/Register.mobile.vue',
'/forgot-password': '@/views/public/login/ForgotPassword.mobile.vue',
'/article-show': '@/views/public/article/ArticleShowView.mobile.vue',
'/article-add': '@/views/public/article/ArticleAddView.mobile.vue'
};
/**
* Layout映射表
*/
export const LAYOUT_MAP: Record<string, Record<DeviceType, string>> = {
'NavigationLayout': {
[DeviceType.MOBILE]: '@/layouts/MobileLayout.vue', // h5移动端
[DeviceType.DESKTOP]: '@/layouts/NavigationLayout.vue' // web桌面端
},
'SidebarLayout': {
[DeviceType.MOBILE]: '@/layouts/MobileLayout.vue', // h5移动端
[DeviceType.DESKTOP]: '@/layouts/SidebarLayout.vue' // web桌面端
},
'BasicLayout': {
[DeviceType.MOBILE]: '@/layouts/MobileLayout.vue', // h5移动端
[DeviceType.DESKTOP]: '@/layouts/BasicLayout.vue' // web桌面端
},
'BlankLayout': {
[DeviceType.MOBILE]: '@/layouts/BlankLayout.vue', // h5移动端
[DeviceType.DESKTOP]: '@/layouts/BlankLayout.vue' // web桌面端
},
'PageLayout': {
[DeviceType.MOBILE]: '@/layouts/MobileLayout.vue', // h5移动端
[DeviceType.DESKTOP]: '@/layouts/PageLayout.vue' // web桌面端
}
};
/**
* 创建响应式路由组件
*/
export function createResponsiveRoute(adapter: RouteAdapter): () => Promise<any> {
return async () => {
const deviceType = getDeviceType();
try {
// 尝试加载设备特定的组件
if (deviceType === DeviceType.MOBILE && adapter.mobile) {
return await adapter.mobile();
}
} catch (error) {
console.warn(`Failed to load device-specific component for ${deviceType}, falling back to original:`, error);
}
// 回退到原始组件(桌面端/web)
return await adapter.original();
};
}
/**
* 获取响应式Layout组件
*/
export function getResponsiveLayout(layoutName: string): () => Promise<any> {
const deviceType = getDeviceType();
const layoutMap = LAYOUT_MAP[layoutName];
if (!layoutMap) {
console.warn(`Unknown layout: ${layoutName}, using original`);
// 使用具体的导入路径
switch (layoutName) {
case 'BlankLayout':
return () => import('@/layouts/BlankLayout.vue');
case 'NavigationLayout':
return () => import('@/layouts/NavigationLayout.vue');
case 'SidebarLayout':
return () => import('@/layouts/SidebarLayout.vue');
case 'BasicLayout':
return () => import('@/layouts/BasicLayout.vue');
case 'PageLayout':
return () => import('@/layouts/PageLayout.vue');
default:
throw new Error(`Unknown layout: ${layoutName}`);
}
}
const targetLayout = layoutMap[deviceType];
return async () => {
try {
// 使用具体的导入路径而不是动态路径
switch (targetLayout) {
case '@/layouts/BlankLayout.vue':
return await import('@/layouts/BlankLayout.vue');
case '@/layouts/NavigationLayout.vue':
return await import('@/layouts/NavigationLayout.vue');
case '@/layouts/SidebarLayout.vue':
return await import('@/layouts/SidebarLayout.vue');
case '@/layouts/BasicLayout.vue':
return await import('@/layouts/BasicLayout.vue');
case '@/layouts/MobileLayout.vue':
return await import('@/layouts/MobileLayout.vue');
case '@/layouts/PageLayout.vue':
return await import('@/layouts/PageLayout.vue');
default:
throw new Error(`Unknown layout path: ${targetLayout}`);
}
} catch (error) {
console.warn(`Failed to load responsive layout ${targetLayout}, falling back to original:`, error);
// 回退到原始layout
switch (layoutName) {
case 'BlankLayout':
return await import('@/layouts/BlankLayout.vue');
case 'NavigationLayout':
return await import('@/layouts/NavigationLayout.vue');
case 'SidebarLayout':
return await import('@/layouts/SidebarLayout.vue');
case 'BasicLayout':
return await import('@/layouts/BasicLayout.vue');
case 'PageLayout':
return await import('@/layouts/PageLayout.vue');
default:
throw new Error(`Unknown layout: ${layoutName}`);
}
}
};
}
/**
* 创建自适应路由配置
*/
export function createAdaptiveRoute(
path: string,
originalComponent: string,
layoutName?: string,
meta?: any
): RouteRecordRaw {
// 创建具体的导入函数而不是使用动态路径
const getOriginalComponent = () => {
switch (originalComponent) {
case '@/views/public/login/Login.vue':
return import('@/views/public/login/Login.vue');
case '@/views/public/login/Register.vue':
return import('@/views/public/login/Register.vue');
case '@/views/public/login/ForgotPassword.vue':
return import('@/views/public/login/ForgotPassword.vue');
default:
throw new Error(`Unknown component: ${originalComponent}`);
}
};
const getMobileComponent = (): (() => Promise<any>) | null => {
const mobilePath = MOBILE_ROUTES_MAP[path];
if (!mobilePath) return null;
switch (mobilePath) {
case '@/views/public/login/Login.mobile.vue':
return () => import('@/views/public/login/Login.mobile.vue');
case '@/views/public/login/Register.mobile.vue':
return () => import('@/views/public/login/Register.mobile.vue');
case '@/views/public/login/ForgotPassword.mobile.vue':
return () => import('@/views/public/login/ForgotPassword.mobile.vue');
default:
return null;
}
};
const adapter: RouteAdapter = {
original: getOriginalComponent
};
// 检查是否有移动端版本
const mobileImportFunction = getMobileComponent();
if (mobileImportFunction) {
adapter.mobile = mobileImportFunction;
}
// 如果指定了Layout应用响应式Layout
if (layoutName) {
const route: RouteRecordRaw = {
path,
component: getResponsiveLayout(layoutName),
children: [
{
path: '',
component: createResponsiveRoute(adapter),
meta
}
],
meta
};
return route;
}
const route: RouteRecordRaw = {
path,
component: createResponsiveRoute(adapter),
meta
};
return route;
}
/**
* 监听屏幕尺寸变化,重新加载路由
*/
export function setupRouteWatcher(router: any) {
let currentDeviceType = getDeviceType();
const handleResize = () => {
const newDeviceType = getDeviceType();
if (newDeviceType !== currentDeviceType) {
currentDeviceType = newDeviceType;
// 重新加载当前路由以应用新的组件
const currentRoute = router.currentRoute.value;
router.replace({
...currentRoute,
query: {
...currentRoute.query,
_refresh: Date.now() // 强制重新加载
}
});
}
};
window.addEventListener('resize', handleResize);
// 返回清理函数
return () => {
window.removeEventListener('resize', handleResize);
};
}