Compare commits
11
Commits
b1776f66a0
...
5637af9798
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5637af9798 | ||
|
|
acdf580ba5 | ||
|
|
886fb7a7c0 | ||
|
|
0ac4e1b7ff | ||
|
|
8137808d44 | ||
|
|
d4b0f9f343 | ||
|
|
b7ae3c0cdb | ||
|
|
5e21c8d53d | ||
|
|
6598f7c67b | ||
|
|
c6b5d9861c | ||
|
|
3e67ebbe8a |
No files matched your search
@@ -355,7 +355,7 @@ export default {
|
||||
callerIdNumber:'Caller Number',
|
||||
calleeIdNumber:'Callee Number',
|
||||
startTime:'Start Time',
|
||||
answeredTime:'Answered Time',
|
||||
answeredTime:'Answered Time(s)',
|
||||
callDuration:'Call Duration',
|
||||
msdData:'MSD Info',
|
||||
},
|
||||
@@ -519,21 +519,27 @@ export default {
|
||||
vehicleType:'Vehicle Type',
|
||||
messageIdentifier: 'Message Identifier',
|
||||
numberOfOccupants: 'Number Of Occupants',
|
||||
n1latitudeDelta:'Recent Vehicle Location N1-Latitude Delta',
|
||||
n1longitudeDelta: 'Recent Vehicle Location N1-Longitude Delta',
|
||||
n2latitudeDelta:'Recent Vehicle Location N2-Latitude Delta',
|
||||
n2longitudeDelta: 'Recent Vehicle Location N2-Longitude Delta',
|
||||
n1latitudeDelta:'Latitude Delta',
|
||||
n1longitudeDelta: 'Longitude Delta',
|
||||
n2latitudeDelta:'Latitude Delta',
|
||||
n2longitudeDelta: 'Longitude Delta',
|
||||
timestamp: 'Timestamp',
|
||||
vehicleDirection: 'Vehicle Direction',
|
||||
isovds: 'Vehicle Descriptor Section',
|
||||
isovisModelyear:'Vehicle Identifier Section Year',
|
||||
isovisSeqPlant: 'Vehicle Identifier Section Serial Factory',
|
||||
isovisSeqPlant: 'Vehicle Identifier Section Plant & Serial',
|
||||
isowmi: 'World Manufacturer Identifier',
|
||||
positionLatitude: 'Position Latitude',
|
||||
positionLongitude: 'Position Longitude',
|
||||
dieselTankPresent: 'Diesel Tank Present',
|
||||
electricEnergyStorage: 'Electric Energy Storage',
|
||||
gasolineTankPresent: 'Gasoline Tank Present',
|
||||
control:'Control',
|
||||
recentVehicleLocationN1:'Recent Vehicle Location N1',
|
||||
recentVehicleLocationN2:'Recent Vehicle Location N2',
|
||||
vehicleIdentificationNumber:'Vehicle Identification Number',
|
||||
vehicleLocation:'Vehicle Location',
|
||||
vehiclePropulsionStorageType:'Vehicle Propulsion Storage Type',
|
||||
},
|
||||
ue: {
|
||||
eventType: "Event Type",
|
||||
|
||||
@@ -359,7 +359,7 @@ export default {
|
||||
callerIdNumber:'主叫号码',
|
||||
calleeIdNumber:'被叫号码',
|
||||
startTime:'开始时间',
|
||||
answeredTime:'接听时间',
|
||||
answeredTime:'接听时间(s)',
|
||||
callDuration:'通话时长',
|
||||
msdData:'MSD内容',
|
||||
},
|
||||
@@ -523,21 +523,27 @@ export default {
|
||||
vehicleType:'车辆类型',
|
||||
messageIdentifier: '消息标识',
|
||||
numberOfOccupants: '乘员数量',
|
||||
n1latitudeDelta:'最近车辆位置N1-纬度增量',
|
||||
n1longitudeDelta: '最近车辆位置N1-经度增量',
|
||||
n2latitudeDelta:' 最近车辆位置N2-纬度增量',
|
||||
n2longitudeDelta: '最近车辆位置N2-经度增量',
|
||||
n1latitudeDelta:'纬度增量',
|
||||
n1longitudeDelta: '经度增量',
|
||||
n2latitudeDelta:' 纬度增量',
|
||||
n2longitudeDelta: '经度增量',
|
||||
timestamp: '时间戳',
|
||||
vehicleDirection: '车辆行驶方向',
|
||||
isovds: '车辆描述段',
|
||||
isovisModelyear:'车辆描述段',
|
||||
isovisSeqPlant: '车辆标识段序列工厂',
|
||||
isovisModelyear:'车辆标识段年份',
|
||||
isovisSeqPlant: '车辆标识段的工厂编码与生产序号',
|
||||
isowmi: '世界制造商标识',
|
||||
positionLatitude: '位置纬度',
|
||||
positionLongitude: '位置经度',
|
||||
dieselTankPresent: '柴油罐存在',
|
||||
electricEnergyStorage: '电力储能',
|
||||
gasolineTankPresent: '汽油罐存在',
|
||||
control:'控制',
|
||||
recentVehicleLocationN1:'最近车辆位置N1',
|
||||
recentVehicleLocationN2:'最近车辆位置N2',
|
||||
vehicleIdentificationNumber:'车辆识别号码',
|
||||
vehicleLocation:'车辆位置',
|
||||
vehiclePropulsionStorageType:'车辆推进存储类型',
|
||||
},
|
||||
ue: {
|
||||
eventType: "事件类型",
|
||||
|
||||
+19
-11
@@ -29,12 +29,15 @@ import { MENU_PATH_INLINE } from '@/constants/menu-constants';
|
||||
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
|
||||
import { parseDateToStr } from '@/utils/date-utils';
|
||||
import { parseUrlPath } from '@/plugins/file-static-url';
|
||||
import useNeInfoStore from '@/store/modules/neinfo';
|
||||
|
||||
const { proConfig, waterMarkContent } = useLayoutStore();
|
||||
const { t, currentLocale } = useI18n();
|
||||
const routerStore = useRouterStore();
|
||||
const tabsStore = useTabsStore();
|
||||
const appStore = useAppStore();
|
||||
const router = useRouter();
|
||||
const neListStore = useNeInfoStore();
|
||||
|
||||
/**菜单面板 */
|
||||
const layoutState = reactive({
|
||||
@@ -65,18 +68,23 @@ watch(
|
||||
);
|
||||
|
||||
// 动态路由添加到菜单面板
|
||||
const rootRoute = router.getRoutes().find(r => r.name === 'Root');
|
||||
if (rootRoute) {
|
||||
const children = routerStore.setRootRouterData(rootRoute.children);
|
||||
const buildRouterData = routerStore.buildRouterData;
|
||||
if (buildRouterData.length > 0) {
|
||||
rootRoute.children = children.concat(buildRouterData);
|
||||
} else {
|
||||
rootRoute.children = children;
|
||||
const menuData = computed(() => {
|
||||
const rootRoute = router.getRoutes().find(r => r.name === 'Root');
|
||||
if (rootRoute) {
|
||||
const children = routerStore.setRootRouterData(rootRoute.children);
|
||||
const buildRouterData = routerStore.buildRouterData;
|
||||
if (buildRouterData.length > 0) {
|
||||
rootRoute.children = children.concat(buildRouterData);
|
||||
} else {
|
||||
rootRoute.children = children;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const { menuData } = getMenuData(clearMenuItem(router.getRoutes()));
|
||||
const neTypes = neListStore.getNeSelectOtions.map(v => v.value);
|
||||
let routes = clearMenuItem(router.getRoutes());
|
||||
routes = routerStore.clearMenuItemByNeList(routes, neTypes);
|
||||
const { menuData } = getMenuData(routes);
|
||||
return menuData;
|
||||
});
|
||||
|
||||
/**面包屑数据对象,排除根节点和首页不显示 */
|
||||
const breadcrumb = computed(() => {
|
||||
|
||||
+320
-13
@@ -13,6 +13,7 @@ import { validHttp } from '@/utils/regular-utils';
|
||||
import useUserStore from '@/store/modules/user';
|
||||
import useAppStore from '@/store/modules/app';
|
||||
import useRouterStore from '@/store/modules/router';
|
||||
import useNeInfoStore from '@/store/modules/neinfo';
|
||||
|
||||
// NProgress Configuration
|
||||
NProgress.configure({ showSpinner: false });
|
||||
@@ -144,10 +145,17 @@ const router = createRouter({
|
||||
});
|
||||
|
||||
/**全局路由-后置守卫 */
|
||||
// 在路由后置守卫中清理计数器
|
||||
router.afterEach((to, from, failure) => {
|
||||
NProgress.done();
|
||||
|
||||
// 清理成功导航的重定向计数
|
||||
if (!failure) {
|
||||
const redirectKey = `${from.path}->${to.path}`;
|
||||
redirectCount.delete(redirectKey);
|
||||
}
|
||||
|
||||
const title = to.meta?.title;
|
||||
// 设置标题
|
||||
if (!failure && title) {
|
||||
useAppStore().setTitle(to.meta.title);
|
||||
}
|
||||
@@ -163,10 +171,27 @@ const WHITE_LIST: string[] = [
|
||||
'/trace-task-hlr',
|
||||
];
|
||||
|
||||
const redirectCount = new Map<string, number>();
|
||||
const MAX_REDIRECT_COUNT = 3; // 最大重定向次数
|
||||
|
||||
/**全局路由-前置守卫 */
|
||||
router.beforeEach(async (to, from, next) => {
|
||||
NProgress.start();
|
||||
|
||||
// 检查是否是 F5 刷新(from.name 为 null 且 to.path 不是根路径)
|
||||
const isRefresh = !from.name && from.path === '/';
|
||||
|
||||
// 重定向计数检查
|
||||
const redirectKey = `${from.path}->${to.path}`;
|
||||
const currentCount = redirectCount.get(redirectKey) || 0;
|
||||
|
||||
if (currentCount > MAX_REDIRECT_COUNT) {
|
||||
console.warn(`检测到重定向循环: ${redirectKey},强制跳转到首页`);
|
||||
redirectCount.delete(redirectKey);
|
||||
next({ name: 'Index', replace: true });
|
||||
return;
|
||||
}
|
||||
|
||||
// 获取系统配置信息
|
||||
const appStore = useAppStore();
|
||||
if (!appStore.loginBackground) {
|
||||
@@ -202,39 +227,321 @@ router.beforeEach(async (to, from, next) => {
|
||||
|
||||
// 有Token
|
||||
if (token) {
|
||||
// 防止重复访问登录页面
|
||||
if (to.path === '/login') {
|
||||
next({ name: 'Index' });
|
||||
} else {
|
||||
// 判断当前用户是否有角色信息
|
||||
const user = useUserStore();
|
||||
if (user.roles && user.roles.length === 0) {
|
||||
try {
|
||||
// 获取用户信息
|
||||
await useNeInfoStore().fnNelist();
|
||||
await user.fnGetInfo();
|
||||
// 获取路由信息
|
||||
const accessRoutes = await useRouterStore().generateRoutes();
|
||||
// 根据后台配置生成可访问的路由表
|
||||
|
||||
if (accessRoutes && accessRoutes.length !== 0) {
|
||||
for (const route of accessRoutes) {
|
||||
// 动态添加可访问路由表,http开头会异常
|
||||
if (!validHttp(route.path)) {
|
||||
router.addRoute(route);
|
||||
}
|
||||
}
|
||||
|
||||
// F5 刷新时,如果目标路由有效,直接跳转,不进行重定向
|
||||
if (isRefresh && await isRouteAccessible(to, accessRoutes)) {
|
||||
console.log(`F5 刷新,目标路由有效,直接跳转: ${to.path}`);
|
||||
next({ ...to, replace: true });
|
||||
return;
|
||||
}
|
||||
|
||||
if (await isRouteAccessible(to, accessRoutes)) {
|
||||
next({ ...to, replace: true });
|
||||
} else {
|
||||
// F5 刷新时,如果目标路由无效,优先跳转到首页
|
||||
if (isRefresh) {
|
||||
console.log(`F5 刷新,目标路由无效,跳转到首页: ${to.path}`);
|
||||
next({ name: 'Index', replace: true });
|
||||
return;
|
||||
}
|
||||
|
||||
const validRedirect = findValidRedirect(to, accessRoutes);
|
||||
if (validRedirect && validRedirect !== to.path) {
|
||||
redirectCount.set(redirectKey, currentCount + 1);
|
||||
console.log(`重定向到有效路由: ${to.path} -> ${validRedirect}`);
|
||||
next({ path: validRedirect, replace: true });
|
||||
} else {
|
||||
next({ name: 'Index', replace: true });
|
||||
}
|
||||
}
|
||||
} else {
|
||||
next({ name: 'Index', replace: true });
|
||||
}
|
||||
// 刷新替换原先路由,确保addRoutes已完成
|
||||
next({ ...to, replace: true });
|
||||
} catch (error: any) {
|
||||
console.error(`[${to.path}]: ${error.message}`);
|
||||
await user.fnLogOut();
|
||||
next({ name: 'Login' });
|
||||
} catch (error) {
|
||||
console.error('Route guard error:', error);
|
||||
next(`/login?redirect=${to.fullPath}`);
|
||||
}
|
||||
} else if (
|
||||
to.meta.neType &&
|
||||
to.meta.neType.length > 0 &&
|
||||
!useNeInfoStore().fnHasNe(to.meta.neType)
|
||||
) {
|
||||
// 找到有效的替代路由
|
||||
const validRedirect = findValidAlternative(to);
|
||||
if (validRedirect && validRedirect !== to.path) {
|
||||
redirectCount.set(redirectKey, currentCount + 1);
|
||||
console.log(`403 重定向: ${to.path} -> ${validRedirect}`);
|
||||
next({ path: validRedirect, replace: true });
|
||||
} else {
|
||||
console.log(`无有效替代路由,跳转到权限错误页面: ${to.path}`);
|
||||
next({ name: 'NotPermission' });
|
||||
}
|
||||
} else {
|
||||
// 清除重定向计数
|
||||
redirectCount.clear();
|
||||
next();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* 检查路由是否可访问
|
||||
*/
|
||||
async function isRouteAccessible(to: any, accessRoutes: any[]): Promise<boolean> {
|
||||
// 检查路由是否存在于 accessRoutes 中
|
||||
const routeExists = findRouteInAccessRoutes(to.path, accessRoutes);
|
||||
|
||||
console.log(`检查路由可访问性: ${to.path}`, routeExists ? '找到' : '未找到');
|
||||
|
||||
if (!routeExists) return false;
|
||||
|
||||
// 检查网元类型
|
||||
if (to.meta?.neType && to.meta.neType.length > 0) {
|
||||
const hasNe = useNeInfoStore().fnHasNe(to.meta.neType);
|
||||
console.log(`网元类型检查: ${to.meta.neType}`, hasNe ? '有效' : '无效');
|
||||
return hasNe;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 在访问路由中查找指定路径
|
||||
*/
|
||||
function findRouteInAccessRoutes(targetPath: string, routes: any[], parentPath: string = ''): any {
|
||||
for (const route of routes) {
|
||||
// 构建完整路径
|
||||
let fullPath = route.path;
|
||||
|
||||
// 如果不是绝对路径,需要拼接父路径
|
||||
if (!fullPath.startsWith('/')) {
|
||||
const cleanParentPath = parentPath.replace(/\/$/, ''); // 移除末尾斜杠
|
||||
const cleanRoutePath = fullPath.replace(/^\//, ''); // 移除开头斜杠
|
||||
fullPath = cleanParentPath + '/' + cleanRoutePath;
|
||||
}
|
||||
|
||||
// 标准化路径,移除多余的斜杠
|
||||
fullPath = fullPath.replace(/\/+/g, '/');
|
||||
|
||||
console.log(`匹配路径: ${targetPath} vs ${fullPath}`);
|
||||
|
||||
if (fullPath === targetPath) {
|
||||
return route;
|
||||
}
|
||||
|
||||
// 递归查找子路由
|
||||
if (route.children && route.children.length > 0) {
|
||||
const found = findRouteInAccessRoutes(targetPath, route.children, fullPath);
|
||||
if (found) return found;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查找有效的重定向目标
|
||||
*/
|
||||
function findValidRedirect(to: any, accessRoutes: any[]): string | null {
|
||||
const neStore = useNeInfoStore();
|
||||
|
||||
console.log(`查找重定向目标: ${to.path}`);
|
||||
|
||||
// 1. 查找父路由的 redirect
|
||||
const parentRoute = findParentRouteWithRedirect(to.path, accessRoutes);
|
||||
|
||||
if (parentRoute?.redirect) {
|
||||
console.log(`找到父路由重定向: ${parentRoute.path} -> ${parentRoute.redirect}`);
|
||||
|
||||
// 验证 redirect 目标是否有效
|
||||
const redirectTarget = findRouteInAccessRoutes(parentRoute.redirect, accessRoutes);
|
||||
if (redirectTarget &&
|
||||
(!redirectTarget.meta?.neType || neStore.fnHasNe(redirectTarget.meta.neType))) {
|
||||
return parentRoute.redirect;
|
||||
}
|
||||
}
|
||||
|
||||
// 2. 查找同级的第一个有效路由
|
||||
const siblingRoute = findFirstValidSibling(to.path, accessRoutes);
|
||||
if (siblingRoute) {
|
||||
console.log(`找到同级有效路由: ${siblingRoute}`);
|
||||
return siblingRoute;
|
||||
}
|
||||
|
||||
// 3. 查找根级别的第一个有效路由
|
||||
const rootRoute = findFirstValidRootRoute(accessRoutes);
|
||||
if (rootRoute) {
|
||||
console.log(`找到根级有效路由: ${rootRoute}`);
|
||||
return rootRoute;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查找具有 redirect 的父路由
|
||||
*/
|
||||
function findParentRouteWithRedirect(targetPath: string, routes: any[], parentPath: string = ''): any {
|
||||
for (const route of routes) {
|
||||
let fullPath = route.path;
|
||||
|
||||
if (!fullPath.startsWith('/')) {
|
||||
const cleanParentPath = parentPath.replace(/\/$/, '');
|
||||
const cleanRoutePath = fullPath.replace(/^\//, '');
|
||||
fullPath = cleanParentPath + '/' + cleanRoutePath;
|
||||
}
|
||||
|
||||
fullPath = fullPath.replace(/\/+/g, '/');
|
||||
|
||||
// 检查是否是父路径且有 redirect
|
||||
if (targetPath.startsWith(fullPath) &&
|
||||
route.redirect &&
|
||||
fullPath !== targetPath) {
|
||||
return { ...route, path: fullPath };
|
||||
}
|
||||
|
||||
// 递归查找
|
||||
if (route.children && route.children.length > 0) {
|
||||
const found = findParentRouteWithRedirect(targetPath, route.children, fullPath);
|
||||
if (found) return found;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查找同级的第一个有效路由
|
||||
*/
|
||||
function findFirstValidSibling(targetPath: string, routes: any[], parentPath: string = ''): string | null {
|
||||
const neStore = useNeInfoStore();
|
||||
|
||||
// 获取父路径
|
||||
const parentRouteResult = findParentOfTarget(targetPath, routes, parentPath);
|
||||
if (!parentRouteResult) return null;
|
||||
|
||||
const { parentRoute, parentFullPath } = parentRouteResult;
|
||||
|
||||
if (parentRoute.children) {
|
||||
for (const sibling of parentRoute.children) {
|
||||
let siblingFullPath = sibling.path;
|
||||
|
||||
if (!siblingFullPath.startsWith('/')) {
|
||||
const cleanParentPath = parentFullPath.replace(/\/$/, '');
|
||||
const cleanSiblingPath = siblingFullPath.replace(/^\//, '');
|
||||
siblingFullPath = cleanParentPath + '/' + cleanSiblingPath;
|
||||
}
|
||||
|
||||
siblingFullPath = siblingFullPath.replace(/\/+/g, '/');
|
||||
|
||||
if (siblingFullPath !== targetPath &&
|
||||
(!sibling.meta?.neType || neStore.fnHasNe(sibling.meta.neType))) {
|
||||
return siblingFullPath;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查找目标路径的父路由
|
||||
*/
|
||||
function findParentOfTarget(targetPath: string, routes: any[], parentPath: string = ''): { parentRoute: any, parentFullPath: string } | null {
|
||||
for (const route of routes) {
|
||||
let fullPath = route.path;
|
||||
|
||||
if (!fullPath.startsWith('/')) {
|
||||
const cleanParentPath = parentPath.replace(/\/$/, '');
|
||||
const cleanRoutePath = fullPath.replace(/^\//, '');
|
||||
fullPath = cleanParentPath + '/' + cleanRoutePath;
|
||||
}
|
||||
|
||||
fullPath = fullPath.replace(/\/+/g, '/');
|
||||
|
||||
// 检查子路由
|
||||
if (route.children && route.children.length > 0) {
|
||||
for (const child of route.children) {
|
||||
let childFullPath = child.path;
|
||||
|
||||
if (!childFullPath.startsWith('/')) {
|
||||
const cleanParentPath = fullPath.replace(/\/$/, '');
|
||||
const cleanChildPath = childFullPath.replace(/^\//, '');
|
||||
childFullPath = cleanParentPath + '/' + cleanChildPath;
|
||||
}
|
||||
|
||||
childFullPath = childFullPath.replace(/\/+/g, '/');
|
||||
|
||||
if (childFullPath === targetPath) {
|
||||
return { parentRoute: route, parentFullPath: fullPath };
|
||||
}
|
||||
}
|
||||
|
||||
// 递归查找
|
||||
const found = findParentOfTarget(targetPath, route.children, fullPath);
|
||||
if (found) return found;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查找根级别的第一个有效路由
|
||||
*/
|
||||
function findFirstValidRootRoute(routes: any[]): string | null {
|
||||
const neStore = useNeInfoStore();
|
||||
|
||||
for (const route of routes) {
|
||||
if (!route.meta?.neType || neStore.fnHasNe(route.meta.neType)) {
|
||||
if (route.children && route.children.length > 0) {
|
||||
// 如果有子路由,返回第一个有效子路由的完整路径
|
||||
for (const child of route.children) {
|
||||
let childFullPath = child.path;
|
||||
|
||||
if (!childFullPath.startsWith('/')) {
|
||||
const cleanParentPath = route.path.replace(/\/$/, '');
|
||||
const cleanChildPath = childFullPath.replace(/^\//, '');
|
||||
childFullPath = cleanParentPath + '/' + cleanChildPath;
|
||||
}
|
||||
|
||||
childFullPath = childFullPath.replace(/\/+/g, '/');
|
||||
|
||||
if (!child.meta?.neType || neStore.fnHasNe(child.meta.neType)) {
|
||||
return childFullPath;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return route.path;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查找有效的替代路由(用于 403 情况)
|
||||
*/
|
||||
function findValidAlternative(to: any): string | null {
|
||||
const routerStore = useRouterStore();
|
||||
const buildRoutes = routerStore.buildRouterData;
|
||||
|
||||
return findValidRedirect(to, buildRoutes);
|
||||
}
|
||||
|
||||
export default router;
|
||||
@@ -109,6 +109,32 @@ const useNeInfoStore = defineStore('neinfo', {
|
||||
}
|
||||
return res;
|
||||
},
|
||||
/**
|
||||
* 含有网元
|
||||
* @param metaNeType ['udm', 'ims', 'udm+ims', 'SGWC'] 支持大小写
|
||||
* @returns boolean
|
||||
*/
|
||||
fnHasNe(metaNeType: string[]) {
|
||||
if (this.neList.length > 0) {
|
||||
const neTypes = this.neSelectOtions.map(item => item.value);
|
||||
let match = false; // 匹配
|
||||
for (const netype of metaNeType) {
|
||||
if (netype.indexOf('+') > -1) {
|
||||
metaNeType = netype.split('+');
|
||||
match = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (match) {
|
||||
// 同时匹配
|
||||
return metaNeType.every(item => neTypes.includes(item.toUpperCase()));
|
||||
}
|
||||
// 有一种
|
||||
return metaNeType.some(item => neTypes.includes(item.toUpperCase()));
|
||||
}
|
||||
return false;
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -3,9 +3,11 @@ import type {
|
||||
RouteComponent,
|
||||
RouteLocationRaw,
|
||||
RouteMeta,
|
||||
RouteRecord,
|
||||
RouteRecordRaw,
|
||||
} from 'vue-router';
|
||||
import { getRouters } from '@/api/router';
|
||||
import useNeInfoStore from '@/store/modules/neinfo';
|
||||
import BasicLayout from '@/layouts/BasicLayout.vue';
|
||||
import BlankLayout from '@/layouts/BlankLayout.vue';
|
||||
import LinkLayout from '@/layouts/LinkLayout.vue';
|
||||
@@ -48,19 +50,95 @@ const useRouterStore = defineStore('router', {
|
||||
async generateRoutes() {
|
||||
const res = await getRouters();
|
||||
if (res.code === RESULT_CODE_SUCCESS && Array.isArray(res.data)) {
|
||||
const buildRoutes = buildRouters(res.data.concat());
|
||||
// 获取当前网元类型
|
||||
const neTypes = useNeInfoStore().getNeSelectOtions.map(v => v.value);
|
||||
// 先过滤
|
||||
const filteredRoutes = this.clearMenuItemByNeList(res.data.concat(), neTypes);
|
||||
// 再 build
|
||||
const buildRoutes = buildRouters(filteredRoutes);
|
||||
this.buildRouterData = buildRoutes;
|
||||
return buildRoutes;
|
||||
}
|
||||
return [];
|
||||
},
|
||||
/**
|
||||
* 根据网元类型过滤菜单
|
||||
* @param routes 经过clearMenuItem(router.getRoutes())处理
|
||||
* @param neTypes 网元类型
|
||||
* @returns 过滤后的菜单
|
||||
*/
|
||||
clearMenuItemByNeList(
|
||||
routes: RouteRecord[] | RouteRecordRaw[],
|
||||
neTypes: string[]
|
||||
): RouteRecordRaw[] {
|
||||
return routes
|
||||
.map((item: RouteRecord | RouteRecordRaw) => {
|
||||
const finalItem = { ...item };
|
||||
// 过滤网元类型
|
||||
if (
|
||||
Array.isArray(finalItem.meta?.neType) &&
|
||||
finalItem.meta?.neType.length > 0
|
||||
) {
|
||||
let metaNeType: string[] = finalItem.meta.neType;
|
||||
let match = false; // 匹配
|
||||
for (const netype of metaNeType) {
|
||||
if (netype.indexOf('+') > -1) {
|
||||
metaNeType = netype.split('+');
|
||||
match = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (match && !metaNeType.every(item => neTypes.includes(item))) {
|
||||
// 同时匹配
|
||||
return null;
|
||||
} else if (!metaNeType.some(item => neTypes.includes(item))) {
|
||||
// 有一种
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// 有子菜单进行递归
|
||||
if (finalItem.children && finalItem.children.length > 0) {
|
||||
const children = this.clearMenuItemByNeList(
|
||||
finalItem.children,
|
||||
neTypes
|
||||
);
|
||||
// 如果子菜单都被过滤掉了,就不显示
|
||||
if (children.length === 0) {
|
||||
return null;
|
||||
}
|
||||
finalItem.children = children;
|
||||
|
||||
// 只重定向到第一个可用的子菜单
|
||||
// finalItem.redirect = finalItem.children[0].path;
|
||||
// console.log(`finalItem.redirect`, finalItem.redirect);
|
||||
// 如果有子菜单,且没有重定向,则设置重定向到第一个子菜单
|
||||
if (children.length > 0) {
|
||||
let childPath = children[0].path;
|
||||
if (!childPath.startsWith('/')) {
|
||||
// 确保父路径以 / 结尾,子路径不以 / 开头
|
||||
const parentPath = finalItem.path.replace(/\/$/, '');
|
||||
childPath = parentPath + '/' + childPath.replace(/^\//, '');
|
||||
}
|
||||
finalItem.redirect = childPath;
|
||||
}
|
||||
|
||||
return finalItem;
|
||||
}
|
||||
|
||||
delete finalItem.children;
|
||||
return finalItem;
|
||||
})
|
||||
.filter(item => item) as RouteRecordRaw[];
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
/**异步路由类型 */
|
||||
type RecordRaws = {
|
||||
path: string;
|
||||
name: string;
|
||||
name?: string;
|
||||
meta: RouteMeta;
|
||||
redirect: RouteLocationRaw;
|
||||
component: string;
|
||||
@@ -75,17 +153,18 @@ type RecordRaws = {
|
||||
* @param recordRaws 异步路由列表
|
||||
* @returns 可添加的路由列表
|
||||
*/
|
||||
function buildRouters(recordRaws: RecordRaws[]): RouteRecordRaw[] {
|
||||
function buildRouters(recordRaws: RouteRecordRaw[]): RouteRecordRaw[] {
|
||||
const routers: RouteRecordRaw[] = [];
|
||||
for (const item of recordRaws) {
|
||||
// 过滤旧前端菜单 是layui的菜单跳过
|
||||
if (['', '/page"'].includes(item.path)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// 路由页面组件
|
||||
let component: RouteComponent = {};
|
||||
if (item.component) {
|
||||
const comp = item.component;
|
||||
const comp = item.component as unknown as string; // 添加类型断言
|
||||
if (comp === MENU_COMPONENT_LAYOUT_BASIC) {
|
||||
component = BasicLayout;
|
||||
} else if (comp === MENU_COMPONENT_LAYOUT_BLANK) {
|
||||
@@ -102,6 +181,17 @@ function buildRouters(recordRaws: RecordRaws[]): RouteRecordRaw[] {
|
||||
let children: RouteRecordRaw[] = [];
|
||||
if (item.children && item.children.length > 0) {
|
||||
children = buildRouters(item.children);
|
||||
|
||||
// 如果没有 redirect 但有子菜单,设置 redirect 到第一个子菜单
|
||||
if (!item.redirect && children.length > 0) {
|
||||
let childPath = children[0].path;
|
||||
if (!childPath?.startsWith('/')) {
|
||||
childPath = item.path.replace(/\/$/, '') + '/' + (childPath || '').replace(/^\//, '');
|
||||
}
|
||||
|
||||
// 修改 item 的 redirect(需要类型断言)
|
||||
(item as any).redirect = childPath;
|
||||
}
|
||||
}
|
||||
|
||||
// 对元数据特殊参数进行处理
|
||||
@@ -109,7 +199,9 @@ function buildRouters(recordRaws: RecordRaws[]): RouteRecordRaw[] {
|
||||
if (!metaIcon.startsWith('icon-')) {
|
||||
metaIcon = '';
|
||||
}
|
||||
item.meta = Object.assign(item.meta, {
|
||||
|
||||
// 更新 meta(需要类型断言)
|
||||
(item as any).meta = Object.assign(item.meta || {}, {
|
||||
icon: metaIcon,
|
||||
});
|
||||
|
||||
|
||||
Vendored
+2
@@ -9,5 +9,7 @@ declare module 'vue-router' {
|
||||
permissions?: string[];
|
||||
/**角色 */
|
||||
roles?: string[];
|
||||
/**网元类型信息 */
|
||||
neType?: string[];
|
||||
}
|
||||
}
|
||||
@@ -426,7 +426,6 @@ function fnGetList(pageNum?: number) {
|
||||
) {
|
||||
queryParams.startTime = queryRangePicker.value[0].valueOf();
|
||||
queryParams.endTime = queryRangePicker.value[1].valueOf();
|
||||
console.log(queryRangePicker.value[0].valueOf());
|
||||
} else {
|
||||
queryParams.startTime = undefined;
|
||||
queryParams.endTime = undefined;
|
||||
@@ -568,8 +567,15 @@ function wsMessage(res: Record<string, any>) {
|
||||
function fnModalVisibleByEdit(record: Record<string, any>) {
|
||||
modalState.title = t('common.viewText') + t('views.dashboard.cdr.msd');
|
||||
modalState.openByView = true;
|
||||
modalState.from = Object.assign(modalState.from, record.cdrJSON.msdData);
|
||||
console.log(record, modalState.from);
|
||||
|
||||
let msdDataObj = {};
|
||||
|
||||
try {
|
||||
msdDataObj = JSON.parse(record.cdrJSON.msdData);
|
||||
} catch (e) {
|
||||
msdDataObj = {};
|
||||
}
|
||||
modalState.from = Object.assign(modalState.from, msdDataObj);
|
||||
// if (!record || !record.cdrJSON) return;
|
||||
// const cdrJSON = record.cdrJSON;
|
||||
// Modal.info({
|
||||
@@ -857,7 +863,11 @@ onBeforeUnmount(() => {
|
||||
>
|
||||
<template #bodyCell="{ column, record }">
|
||||
<template v-if="column.key === 'msdData'">
|
||||
<a-button type="link" @click.prevent="fnModalVisibleByEdit(record)">
|
||||
<a-button
|
||||
type="link"
|
||||
@click.prevent="fnModalVisibleByEdit(record)"
|
||||
:disabled="!record.cdrJSON.msdData"
|
||||
>
|
||||
<template #icon><InfoCircleOutlined /></template>
|
||||
</a-button>
|
||||
</template>
|
||||
@@ -1010,61 +1020,16 @@ onBeforeUnmount(() => {
|
||||
:title="modalState.title"
|
||||
:confirm-loading="modalState.confirmLoading"
|
||||
@cancel="fnModalCancel"
|
||||
:footer="null"
|
||||
:footer="null"
|
||||
>
|
||||
<a-form
|
||||
name="modalStateFrom"
|
||||
layout="horizontal"
|
||||
:label-col="{ span: 6 }"
|
||||
:labelWrap="true"
|
||||
layout="vertical"
|
||||
:label-col="{ style: { width: '100%' } }"
|
||||
:labelWrap="false"
|
||||
>
|
||||
<a-row>
|
||||
<a-col :lg="24" :md="24" :xs="24">
|
||||
<a-form-item
|
||||
:label="t('views.dashboard.cdr.automaticActivation')"
|
||||
name="automaticActivation"
|
||||
>
|
||||
<a-input
|
||||
:disabled="true"
|
||||
v-model:value="modalState.from.control.automaticActivation"
|
||||
></a-input>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :lg="24" :md="24" :xs="24">
|
||||
<a-form-item
|
||||
:label="t('views.dashboard.cdr.positionCanBeTrusted')"
|
||||
name="positionCanBeTrusted"
|
||||
>
|
||||
<a-input
|
||||
:disabled="true"
|
||||
v-model:value="modalState.from.control.positionCanBeTrusted"
|
||||
></a-input>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :lg="24" :md="24" :xs="24">
|
||||
<a-form-item
|
||||
:label="t('views.dashboard.cdr.testCall')"
|
||||
name="testCall"
|
||||
>
|
||||
<a-input
|
||||
:disabled="true"
|
||||
v-model:value="modalState.from.control.testCall"
|
||||
></a-input>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :lg="24" :md="24" :xs="24">
|
||||
<a-form-item
|
||||
:label="t('views.dashboard.cdr.vehicleType')"
|
||||
name="ticketId"
|
||||
>
|
||||
<a-input
|
||||
:disabled="true"
|
||||
v-model:value="modalState.from.control.vehicleType"
|
||||
></a-input>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
|
||||
<a-col :lg="24" :md="24" :xs="24">
|
||||
<a-row :gutter="[32, 4]">
|
||||
<a-col :lg="12" :md="12" :xs="24">
|
||||
<a-form-item
|
||||
:label="t('views.dashboard.cdr.messageIdentifier')"
|
||||
name="messageIdentifier"
|
||||
@@ -1076,7 +1041,7 @@ onBeforeUnmount(() => {
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
|
||||
<a-col :lg="24" :md="24" :xs="24">
|
||||
<a-col :lg="12" :md="12" :xs="24">
|
||||
<a-form-item
|
||||
:label="t('views.dashboard.cdr.numberOfOccupants')"
|
||||
name="ticketId"
|
||||
@@ -1088,7 +1053,84 @@ onBeforeUnmount(() => {
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
|
||||
<a-col :lg="24" :md="24" :xs="24">
|
||||
<a-col :lg="12" :md="12" :xs="24">
|
||||
<a-form-item
|
||||
:label="t('views.dashboard.cdr.timestamp')"
|
||||
name="timestamp"
|
||||
>
|
||||
<a-input
|
||||
:disabled="true"
|
||||
v-model:value="modalState.from.timestamp"
|
||||
></a-input>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
|
||||
<a-col :lg="12" :md="12" :xs="24">
|
||||
<a-form-item
|
||||
:label="t('views.dashboard.cdr.vehicleDirection')"
|
||||
name="vehicleDirection"
|
||||
>
|
||||
<a-input
|
||||
:disabled="true"
|
||||
v-model:value="modalState.from.vehicleDirection"
|
||||
></a-input>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
|
||||
<a-divider orientation="left">
|
||||
{{ t('views.dashboard.cdr.control') }}
|
||||
</a-divider>
|
||||
|
||||
<a-col :lg="12" :md="12" :xs="24">
|
||||
<a-form-item
|
||||
:label="t('views.dashboard.cdr.automaticActivation')"
|
||||
name="automaticActivation"
|
||||
>
|
||||
<a-input
|
||||
:disabled="true"
|
||||
v-model:value="modalState.from.control.automaticActivation"
|
||||
></a-input>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :lg="12" :md="12" :xs="24">
|
||||
<a-form-item
|
||||
:label="t('views.dashboard.cdr.positionCanBeTrusted')"
|
||||
name="positionCanBeTrusted"
|
||||
>
|
||||
<a-input
|
||||
:disabled="true"
|
||||
v-model:value="modalState.from.control.positionCanBeTrusted"
|
||||
></a-input>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :lg="12" :md="12" :xs="24">
|
||||
<a-form-item
|
||||
:label="t('views.dashboard.cdr.testCall')"
|
||||
name="testCall"
|
||||
>
|
||||
<a-input
|
||||
:disabled="true"
|
||||
v-model:value="modalState.from.control.testCall"
|
||||
></a-input>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :lg="12" :md="12" :xs="24">
|
||||
<a-form-item
|
||||
:label="t('views.dashboard.cdr.vehicleType')"
|
||||
name="ticketId"
|
||||
>
|
||||
<a-input
|
||||
:disabled="true"
|
||||
v-model:value="modalState.from.control.vehicleType"
|
||||
></a-input>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
|
||||
<a-divider orientation="left">
|
||||
{{ t('views.dashboard.cdr.recentVehicleLocationN1') }}
|
||||
</a-divider>
|
||||
|
||||
<a-col :lg="12" :md="12" :xs="24">
|
||||
<a-form-item
|
||||
:label="t('views.dashboard.cdr.n1latitudeDelta')"
|
||||
name="n1latitudeDelta"
|
||||
@@ -1102,7 +1144,7 @@ onBeforeUnmount(() => {
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
|
||||
<a-col :lg="24" :md="24" :xs="24">
|
||||
<a-col :lg="12" :md="12" :xs="24">
|
||||
<a-form-item
|
||||
:label="t('views.dashboard.cdr.n1longitudeDelta')"
|
||||
name="n1longitudeDelta"
|
||||
@@ -1116,7 +1158,11 @@ onBeforeUnmount(() => {
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
|
||||
<a-col :lg="24" :md="24" :xs="24">
|
||||
<a-divider orientation="left">
|
||||
{{ t('views.dashboard.cdr.recentVehicleLocationN2') }}
|
||||
</a-divider>
|
||||
|
||||
<a-col :lg="12" :md="12" :xs="24">
|
||||
<a-form-item
|
||||
:label="t('views.dashboard.cdr.n2latitudeDelta')"
|
||||
name="n2latitudeDelta"
|
||||
@@ -1130,7 +1176,7 @@ onBeforeUnmount(() => {
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
|
||||
<a-col :lg="24" :md="24" :xs="24">
|
||||
<a-col :lg="12" :md="12" :xs="24">
|
||||
<a-form-item
|
||||
:label="t('views.dashboard.cdr.n2longitudeDelta')"
|
||||
name="n2longitudeDelta"
|
||||
@@ -1144,31 +1190,11 @@ onBeforeUnmount(() => {
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
|
||||
<a-col :lg="24" :md="24" :xs="24">
|
||||
<a-form-item
|
||||
:label="t('views.dashboard.cdr.timestamp')"
|
||||
name="timestamp"
|
||||
>
|
||||
<a-input
|
||||
:disabled="true"
|
||||
v-model:value="modalState.from.timestamp"
|
||||
></a-input>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-divider orientation="left">
|
||||
{{ t('views.dashboard.cdr.vehicleIdentificationNumber') }}
|
||||
</a-divider>
|
||||
|
||||
<a-col :lg="24" :md="24" :xs="24">
|
||||
<a-form-item
|
||||
:label="t('views.dashboard.cdr.vehicleDirection')"
|
||||
name="vehicleDirection"
|
||||
>
|
||||
<a-input
|
||||
:disabled="true"
|
||||
v-model:value="modalState.from.vehicleDirection"
|
||||
></a-input>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
|
||||
<a-col :lg="24" :md="24" :xs="24">
|
||||
<a-col :lg="12" :md="12" :xs="24">
|
||||
<a-form-item :label="t('views.dashboard.cdr.isovds')" name="isovds">
|
||||
<a-input
|
||||
:disabled="true"
|
||||
@@ -1179,7 +1205,7 @@ onBeforeUnmount(() => {
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
|
||||
<a-col :lg="24" :md="24" :xs="24">
|
||||
<a-col :lg="12" :md="12" :xs="24">
|
||||
<a-form-item
|
||||
:label="t('views.dashboard.cdr.isovisModelyear')"
|
||||
name="isovisModelyear"
|
||||
@@ -1193,7 +1219,7 @@ onBeforeUnmount(() => {
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
|
||||
<a-col :lg="24" :md="24" :xs="24">
|
||||
<a-col :lg="12" :md="12" :xs="24">
|
||||
<a-form-item
|
||||
:label="t('views.dashboard.cdr.isovisSeqPlant')"
|
||||
name="isovisSeqPlant"
|
||||
@@ -1207,11 +1233,8 @@ onBeforeUnmount(() => {
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
|
||||
<a-col :lg="24" :md="24" :xs="24">
|
||||
<a-form-item
|
||||
:label="t('views.dashboard.cdr.isovisModelyear')"
|
||||
name="isowmi"
|
||||
>
|
||||
<a-col :lg="12" :md="12" :xs="24">
|
||||
<a-form-item :label="t('views.dashboard.cdr.isowmi')" name="isowmi">
|
||||
<a-input
|
||||
:disabled="true"
|
||||
v-model:value="
|
||||
@@ -1221,7 +1244,11 @@ onBeforeUnmount(() => {
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
|
||||
<a-col :lg="24" :md="24" :xs="24">
|
||||
<a-divider orientation="left">
|
||||
{{ t('views.dashboard.cdr.vehicleLocation') }}
|
||||
</a-divider>
|
||||
|
||||
<a-col :lg="12" :md="12" :xs="24">
|
||||
<a-form-item
|
||||
:label="t('views.dashboard.cdr.positionLatitude')"
|
||||
name="positionLatitude"
|
||||
@@ -1233,7 +1260,7 @@ onBeforeUnmount(() => {
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
|
||||
<a-col :lg="24" :md="24" :xs="24">
|
||||
<a-col :lg="12" :md="12" :xs="24">
|
||||
<a-form-item
|
||||
:label="t('views.dashboard.cdr.positionLongitude')"
|
||||
name="positionLongitude"
|
||||
@@ -1247,7 +1274,11 @@ onBeforeUnmount(() => {
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
|
||||
<a-col :lg="24" :md="24" :xs="24">
|
||||
<a-divider orientation="left">
|
||||
{{ t('views.dashboard.cdr.vehiclePropulsionStorageType') }}
|
||||
</a-divider>
|
||||
|
||||
<a-col :lg="12" :md="12" :xs="24">
|
||||
<a-form-item
|
||||
:label="t('views.dashboard.cdr.dieselTankPresent')"
|
||||
name="dieselTankPresent"
|
||||
@@ -1261,7 +1292,7 @@ onBeforeUnmount(() => {
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
|
||||
<a-col :lg="24" :md="24" :xs="24">
|
||||
<a-col :lg="12" :md="12" :xs="24">
|
||||
<a-form-item
|
||||
:label="t('views.dashboard.cdr.electricEnergyStorage')"
|
||||
name="electricEnergyStorage"
|
||||
@@ -1276,7 +1307,7 @@ onBeforeUnmount(() => {
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
|
||||
<a-col :lg="24" :md="24" :xs="24">
|
||||
<a-col :lg="12" :md="12" :xs="24">
|
||||
<a-form-item
|
||||
:label="t('views.dashboard.cdr.gasolineTankPresent')"
|
||||
name="gasolineTankPresent"
|
||||
|
||||
@@ -134,7 +134,7 @@ export default function useConfigList({
|
||||
/**指定每页可以显示多少条 */
|
||||
pageSizeOptions: ['10', '20', '50', '100'],
|
||||
/**只有一页时是否隐藏分页器 */
|
||||
hideOnSinglePage: true,
|
||||
hideOnSinglePage: false,
|
||||
/**是否可以快速跳转至某页 */
|
||||
showQuickJumper: true,
|
||||
/**是否可以改变 pageSize */
|
||||
|
||||
@@ -477,7 +477,7 @@ onMounted(() => {
|
||||
</a-card>
|
||||
</a-col>
|
||||
<a-col :lg="collapsible ? 18 : 24" :md="collapsible ? 18 : 24" :xs="24">
|
||||
<a-card size="small" :bordered="false" :body-style="{ maxHeight: '600px', 'overflow-y': 'auto' }"
|
||||
<a-card size="small" :bordered="false" :body-style="{ maxHeight: '700px', 'overflow-y': 'auto' }"
|
||||
:loading="treeState.selectLoading">
|
||||
<template #title>
|
||||
<a-button type="text" size="small" @click.prevent="changeCollapsible()">
|
||||
|
||||
+1
-1
@@ -21,7 +21,7 @@ export default defineConfig(({ mode }) => {
|
||||
// https://cn.vitejs.dev/config/#server-proxy
|
||||
[env.VITE_API_BASE_URL]: {
|
||||
// target: 'http://192.168.2.166:33030',
|
||||
target: 'http://192.168.5.58:33040',
|
||||
target: 'http://192.168.2.223:43030',
|
||||
changeOrigin: true,
|
||||
rewrite: p => p.replace(env.VITE_API_BASE_URL, ''),
|
||||
},
|
||||
|
||||
Reference in new issue
Block a user