5 Commits

Author SHA1 Message Date
lai
5637af9798 取消隐藏分页 2025-09-15 16:20:45 +08:00
lai
acdf580ba5 卡片加高 2025-08-08 10:24:31 +08:00
lai
886fb7a7c0 修改msdData解析方法 2025-08-08 09:51:33 +08:00
zhangsz
0ac4e1b7ff fix... 2025-07-25 11:42:30 +08:00
zhangsz
8137808d44 fix: router error display 403 if the first children menu unavalaible 2025-07-25 11:42:00 +08:00
8 changed files with 376 additions and 47 deletions

View File

@@ -355,7 +355,7 @@ export default {
callerIdNumber:'Caller Number', callerIdNumber:'Caller Number',
calleeIdNumber:'Callee Number', calleeIdNumber:'Callee Number',
startTime:'Start Time', startTime:'Start Time',
answeredTime:'Answered Time', answeredTime:'Answered Time(s)',
callDuration:'Call Duration', callDuration:'Call Duration',
msdData:'MSD Info', msdData:'MSD Info',
}, },

View File

@@ -359,7 +359,7 @@ export default {
callerIdNumber:'主叫号码', callerIdNumber:'主叫号码',
calleeIdNumber:'被叫号码', calleeIdNumber:'被叫号码',
startTime:'开始时间', startTime:'开始时间',
answeredTime:'接听时间', answeredTime:'接听时间(s)',
callDuration:'通话时长', callDuration:'通话时长',
msdData:'MSD内容', msdData:'MSD内容',
}, },

View File

@@ -145,10 +145,17 @@ const router = createRouter({
}); });
/**全局路由-后置守卫 */ /**全局路由-后置守卫 */
// 在路由后置守卫中清理计数器
router.afterEach((to, from, failure) => { router.afterEach((to, from, failure) => {
NProgress.done(); NProgress.done();
// 清理成功导航的重定向计数
if (!failure) {
const redirectKey = `${from.path}->${to.path}`;
redirectCount.delete(redirectKey);
}
const title = to.meta?.title; const title = to.meta?.title;
// 设置标题
if (!failure && title) { if (!failure && title) {
useAppStore().setTitle(to.meta.title); useAppStore().setTitle(to.meta.title);
} }
@@ -164,10 +171,27 @@ const WHITE_LIST: string[] = [
'/trace-task-hlr', '/trace-task-hlr',
]; ];
const redirectCount = new Map<string, number>();
const MAX_REDIRECT_COUNT = 3; // 最大重定向次数
/**全局路由-前置守卫 */ /**全局路由-前置守卫 */
router.beforeEach(async (to, from, next) => { router.beforeEach(async (to, from, next) => {
NProgress.start(); 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(); const appStore = useAppStore();
if (!appStore.loginBackground) { if (!appStore.loginBackground) {
@@ -203,48 +227,321 @@ router.beforeEach(async (to, from, next) => {
// 有Token // 有Token
if (token) { if (token) {
// 防止重复访问登录页面
if (to.path === '/login') { if (to.path === '/login') {
next({ name: 'Index' }); next({ name: 'Index' });
} else { } else {
// 判断当前用户是否有角色信息
const user = useUserStore(); const user = useUserStore();
if (user.roles && user.roles.length === 0) { if (user.roles && user.roles.length === 0) {
try { try {
// 获取网元信息 await useNeInfoStore().fnNelist();
await useNeInfoStore().fnNelist();
// 获取用户信息
await user.fnGetInfo(); await user.fnGetInfo();
// 获取路由信息
const accessRoutes = await useRouterStore().generateRoutes(); const accessRoutes = await useRouterStore().generateRoutes();
// 根据后台配置生成可访问的路由表
if (accessRoutes && accessRoutes.length !== 0) { if (accessRoutes && accessRoutes.length !== 0) {
for (const route of accessRoutes) { for (const route of accessRoutes) {
// 动态添加可访问路由表http开头会异常
if (!validHttp(route.path)) { if (!validHttp(route.path)) {
router.addRoute(route); 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已完成 } catch (error) {
next({ ...to, replace: true }); console.error('Route guard error:', error);
} catch (error: any) { next(`/login?redirect=${to.fullPath}`);
console.error(`[${to.path}]: ${error.message}`);
await user.fnLogOut();
next({ name: 'Login' });
} }
} else if ( } else if (
to.meta.neType && to.meta.neType &&
//Array.isArray(to.meta.neType) &&
to.meta.neType.length > 0 && to.meta.neType.length > 0 &&
!useNeInfoStore().fnHasNe(to.meta.neType) !useNeInfoStore().fnHasNe(to.meta.neType)
) { ) {
next({ name: 'NotPermission' }); // 找到有效的替代路由
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 { } else {
// 清除重定向计数
redirectCount.clear();
next(); 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; export default router;

View File

@@ -7,6 +7,7 @@ import type {
RouteRecordRaw, RouteRecordRaw,
} from 'vue-router'; } from 'vue-router';
import { getRouters } from '@/api/router'; import { getRouters } from '@/api/router';
import useNeInfoStore from '@/store/modules/neinfo';
import BasicLayout from '@/layouts/BasicLayout.vue'; import BasicLayout from '@/layouts/BasicLayout.vue';
import BlankLayout from '@/layouts/BlankLayout.vue'; import BlankLayout from '@/layouts/BlankLayout.vue';
import LinkLayout from '@/layouts/LinkLayout.vue'; import LinkLayout from '@/layouts/LinkLayout.vue';
@@ -49,7 +50,12 @@ const useRouterStore = defineStore('router', {
async generateRoutes() { async generateRoutes() {
const res = await getRouters(); const res = await getRouters();
if (res.code === RESULT_CODE_SUCCESS && Array.isArray(res.data)) { 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; this.buildRouterData = buildRoutes;
return buildRoutes; return buildRoutes;
} }
@@ -103,6 +109,21 @@ const useRouterStore = defineStore('router', {
return null; return null;
} }
finalItem.children = children; 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; return finalItem;
} }
@@ -117,7 +138,7 @@ const useRouterStore = defineStore('router', {
/**异步路由类型 */ /**异步路由类型 */
type RecordRaws = { type RecordRaws = {
path: string; path: string;
name: string; name?: string;
meta: RouteMeta; meta: RouteMeta;
redirect: RouteLocationRaw; redirect: RouteLocationRaw;
component: string; component: string;
@@ -132,17 +153,18 @@ type RecordRaws = {
* @param recordRaws 异步路由列表 * @param recordRaws 异步路由列表
* @returns 可添加的路由列表 * @returns 可添加的路由列表
*/ */
function buildRouters(recordRaws: RecordRaws[]): RouteRecordRaw[] { function buildRouters(recordRaws: RouteRecordRaw[]): RouteRecordRaw[] {
const routers: RouteRecordRaw[] = []; const routers: RouteRecordRaw[] = [];
for (const item of recordRaws) { for (const item of recordRaws) {
// 过滤旧前端菜单 是layui的菜单跳过 // 过滤旧前端菜单 是layui的菜单跳过
if (['', '/page"'].includes(item.path)) { if (['', '/page"'].includes(item.path)) {
continue; continue;
} }
// 路由页面组件 // 路由页面组件
let component: RouteComponent = {}; let component: RouteComponent = {};
if (item.component) { if (item.component) {
const comp = item.component; const comp = item.component as unknown as string; // 添加类型断言
if (comp === MENU_COMPONENT_LAYOUT_BASIC) { if (comp === MENU_COMPONENT_LAYOUT_BASIC) {
component = BasicLayout; component = BasicLayout;
} else if (comp === MENU_COMPONENT_LAYOUT_BLANK) { } else if (comp === MENU_COMPONENT_LAYOUT_BLANK) {
@@ -159,6 +181,17 @@ function buildRouters(recordRaws: RecordRaws[]): RouteRecordRaw[] {
let children: RouteRecordRaw[] = []; let children: RouteRecordRaw[] = [];
if (item.children && item.children.length > 0) { if (item.children && item.children.length > 0) {
children = buildRouters(item.children); 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;
}
} }
// 对元数据特殊参数进行处理 // 对元数据特殊参数进行处理
@@ -166,7 +199,9 @@ function buildRouters(recordRaws: RecordRaws[]): RouteRecordRaw[] {
if (!metaIcon.startsWith('icon-')) { if (!metaIcon.startsWith('icon-')) {
metaIcon = ''; metaIcon = '';
} }
item.meta = Object.assign(item.meta, {
// 更新 meta需要类型断言
(item as any).meta = Object.assign(item.meta || {}, {
icon: metaIcon, icon: metaIcon,
}); });

View File

@@ -567,7 +567,15 @@ function wsMessage(res: Record<string, any>) {
function fnModalVisibleByEdit(record: Record<string, any>) { function fnModalVisibleByEdit(record: Record<string, any>) {
modalState.title = t('common.viewText') + t('views.dashboard.cdr.msd'); modalState.title = t('common.viewText') + t('views.dashboard.cdr.msd');
modalState.openByView = true; modalState.openByView = true;
modalState.from = Object.assign(modalState.from, record.cdrJSON.msdData);
let msdDataObj = {};
try {
msdDataObj = JSON.parse(record.cdrJSON.msdData);
} catch (e) {
msdDataObj = {};
}
modalState.from = Object.assign(modalState.from, msdDataObj);
// if (!record || !record.cdrJSON) return; // if (!record || !record.cdrJSON) return;
// const cdrJSON = record.cdrJSON; // const cdrJSON = record.cdrJSON;
// Modal.info({ // Modal.info({
@@ -855,9 +863,11 @@ onBeforeUnmount(() => {
> >
<template #bodyCell="{ column, record }"> <template #bodyCell="{ column, record }">
<template v-if="column.key === 'msdData'"> <template v-if="column.key === 'msdData'">
<a-button type="link" @click.prevent="fnModalVisibleByEdit(record)" <a-button
:disabled="!record.cdrJSON.msdData" type="link"
> @click.prevent="fnModalVisibleByEdit(record)"
:disabled="!record.cdrJSON.msdData"
>
<template #icon><InfoCircleOutlined /></template> <template #icon><InfoCircleOutlined /></template>
</a-button> </a-button>
</template> </template>
@@ -1019,8 +1029,7 @@ onBeforeUnmount(() => {
:labelWrap="false" :labelWrap="false"
> >
<a-row :gutter="[32, 4]"> <a-row :gutter="[32, 4]">
<a-col :lg="12" :md="12" :xs="24">
<a-col :lg="12" :md="12" :xs="24">
<a-form-item <a-form-item
:label="t('views.dashboard.cdr.messageIdentifier')" :label="t('views.dashboard.cdr.messageIdentifier')"
name="messageIdentifier" name="messageIdentifier"
@@ -1044,9 +1053,7 @@ onBeforeUnmount(() => {
</a-form-item> </a-form-item>
</a-col> </a-col>
<a-col :lg="12" :md="12" :xs="24">
<a-col :lg="12" :md="12" :xs="24">
<a-form-item <a-form-item
:label="t('views.dashboard.cdr.timestamp')" :label="t('views.dashboard.cdr.timestamp')"
name="timestamp" name="timestamp"
@@ -1070,9 +1077,6 @@ onBeforeUnmount(() => {
</a-form-item> </a-form-item>
</a-col> </a-col>
<a-divider orientation="left"> <a-divider orientation="left">
{{ t('views.dashboard.cdr.control') }} {{ t('views.dashboard.cdr.control') }}
</a-divider> </a-divider>
@@ -1122,8 +1126,6 @@ onBeforeUnmount(() => {
</a-form-item> </a-form-item>
</a-col> </a-col>
<a-divider orientation="left"> <a-divider orientation="left">
{{ t('views.dashboard.cdr.recentVehicleLocationN1') }} {{ t('views.dashboard.cdr.recentVehicleLocationN1') }}
</a-divider> </a-divider>
@@ -1188,8 +1190,6 @@ onBeforeUnmount(() => {
</a-form-item> </a-form-item>
</a-col> </a-col>
<a-divider orientation="left"> <a-divider orientation="left">
{{ t('views.dashboard.cdr.vehicleIdentificationNumber') }} {{ t('views.dashboard.cdr.vehicleIdentificationNumber') }}
</a-divider> </a-divider>
@@ -1234,10 +1234,7 @@ onBeforeUnmount(() => {
</a-col> </a-col>
<a-col :lg="12" :md="12" :xs="24"> <a-col :lg="12" :md="12" :xs="24">
<a-form-item <a-form-item :label="t('views.dashboard.cdr.isowmi')" name="isowmi">
:label="t('views.dashboard.cdr.isowmi')"
name="isowmi"
>
<a-input <a-input
:disabled="true" :disabled="true"
v-model:value=" v-model:value="

View File

@@ -134,7 +134,7 @@ export default function useConfigList({
/**指定每页可以显示多少条 */ /**指定每页可以显示多少条 */
pageSizeOptions: ['10', '20', '50', '100'], pageSizeOptions: ['10', '20', '50', '100'],
/**只有一页时是否隐藏分页器 */ /**只有一页时是否隐藏分页器 */
hideOnSinglePage: true, hideOnSinglePage: false,
/**是否可以快速跳转至某页 */ /**是否可以快速跳转至某页 */
showQuickJumper: true, showQuickJumper: true,
/**是否可以改变 pageSize */ /**是否可以改变 pageSize */

View File

@@ -477,7 +477,7 @@ onMounted(() => {
</a-card> </a-card>
</a-col> </a-col>
<a-col :lg="collapsible ? 18 : 24" :md="collapsible ? 18 : 24" :xs="24"> <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"> :loading="treeState.selectLoading">
<template #title> <template #title>
<a-button type="text" size="small" @click.prevent="changeCollapsible()"> <a-button type="text" size="small" @click.prevent="changeCollapsible()">

View File

@@ -21,7 +21,7 @@ export default defineConfig(({ mode }) => {
// https://cn.vitejs.dev/config/#server-proxy // https://cn.vitejs.dev/config/#server-proxy
[env.VITE_API_BASE_URL]: { [env.VITE_API_BASE_URL]: {
// target: 'http://192.168.2.166:33030', // target: 'http://192.168.2.166:33030',
target: 'http://192.168.5.58:33040', target: 'http://192.168.2.223:43030',
changeOrigin: true, changeOrigin: true,
rewrite: p => p.replace(env.VITE_API_BASE_URL, ''), rewrite: p => p.replace(env.VITE_API_BASE_URL, ''),
}, },