From cf63b056d59fea6916cdb18253fcbd5c9e0f646c Mon Sep 17 00:00:00 2001 From: EightMonth Date: Tue, 8 Apr 2025 09:20:00 +0800 Subject: [PATCH 1/6] =?UTF-8?q?=E6=96=B0=E5=A2=9Econtroller=E6=B5=8B?= =?UTF-8?q?=E8=AF=95=E7=94=A8=E4=BE=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../modules/system/test/SysUserApiTest.java | 177 ++++++++++++++++++ 1 file changed, 177 insertions(+) create mode 100644 jeecg-boot/jeecg-module-system/jeecg-system-start/src/test/java/org/jeecg/modules/system/test/SysUserApiTest.java diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/src/test/java/org/jeecg/modules/system/test/SysUserApiTest.java b/jeecg-boot/jeecg-module-system/jeecg-system-start/src/test/java/org/jeecg/modules/system/test/SysUserApiTest.java new file mode 100644 index 000000000..bb3d51669 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/src/test/java/org/jeecg/modules/system/test/SysUserApiTest.java @@ -0,0 +1,177 @@ +package org.jeecg.modules.system.test; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import org.jeecg.common.api.vo.Result; +import org.jeecg.common.modules.redis.client.JeecgRedisClient; +import org.jeecg.common.util.RedisUtil; +import org.jeecg.config.JeecgBaseConfig; +import org.jeecg.modules.base.service.BaseCommonService; +import org.jeecg.modules.system.controller.SysUserController; +import org.jeecg.modules.system.entity.SysUser; +import org.jeecg.modules.system.service.*; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.http.MediaType; +import org.springframework.test.web.servlet.MockMvc; + +import java.util.ArrayList; +import java.util.List; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.BDDMockito.given; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; + +/** + * 系统用户单元测试 + */ +@WebMvcTest(SysUserController.class) +public class SysUserApiTest { + + @Autowired + private MockMvc mockMvc; + + @MockBean + private ISysUserService sysUserService; + + @MockBean + private ISysDepartService sysDepartService; + + @MockBean + private ISysUserRoleService sysUserRoleService; + + @MockBean + private ISysUserDepartService sysUserDepartService; + + @MockBean + private ISysDepartRoleUserService departRoleUserService; + + @MockBean + private ISysDepartRoleService departRoleService; + + @MockBean + private RedisUtil redisUtil; + + @Value("${jeecg.path.upload}") + private String upLoadPath; + + @MockBean + private BaseCommonService baseCommonService; + + @MockBean + private ISysUserAgentService sysUserAgentService; + + @MockBean + private ISysPositionService sysPositionService; + + @MockBean + private ISysUserTenantService userTenantService; + + @MockBean + private JeecgRedisClient jeecgRedisClient; + + @MockBean + private JeecgBaseConfig jeecgBaseConfig; + /** + * 测试地址:实际使用时替换成你自己的地址 + */ + private final String BASE_URL = "/sys/user/"; + + /** + * 测试用例:查询记录 + */ + @Test + public void testQuery() throws Exception{ + // 请求地址 + String url = BASE_URL + "list"; + + Page sysUserPage = new Page<>(); + SysUser sysUser = new SysUser(); + sysUser.setUsername("admin"); + List users = new ArrayList<>(); + users.add(sysUser); + sysUserPage.setRecords(users); + sysUserPage.setCurrent(1); + sysUserPage.setSize(10); + sysUserPage.setTotal(1); + + given(this.sysUserService.queryPageList(any(), any(), any(), any())).willReturn(Result.OK(sysUserPage)); + + String result = mockMvc.perform(get(url)).andReturn().getResponse().getContentAsString(); + JSONObject jsonObject = JSON.parseObject(result); + Assertions.assertEquals("admin", jsonObject.getJSONObject("result").getJSONArray("records").getJSONObject(0).getString("username")); + } + + /** + * 测试用例:新增 + */ + @Test + public void testAdd() throws Exception { + // 请求地址 + String url = BASE_URL + "add" ; + + JSONObject params = new JSONObject(); + params.put("username", "wangwuTest"); + params.put("password", "123456"); + params.put("confirmpassword","123456"); + params.put("realname", "单元测试"); + params.put("activitiSync", "1"); + params.put("userIdentity","1"); + params.put("workNo","0025"); + + String result = mockMvc.perform(post(url).contentType(MediaType.APPLICATION_JSON_VALUE).content(params.toJSONString())) + .andReturn().getResponse().getContentAsString(); + JSONObject jsonObject = JSON.parseObject(result); + Assertions.assertTrue(jsonObject.getBoolean("success")); + } + + + /** + * 测试用例:修改 + */ + @Test + public void testEdit() throws Exception { + // 数据Id + String dataId = "1331795062924374018"; + // 请求地址 + String url = BASE_URL + "edit"; + + JSONObject params = new JSONObject(); + params.put("username", "wangwuTest"); + params.put("realname", "单元测试1111"); + params.put("activitiSync", "1"); + params.put("userIdentity","1"); + params.put("workNo","0025"); + params.put("id",dataId); + + SysUser sysUser = new SysUser(); + sysUser.setUsername("admin"); + + given(this.sysUserService.getById(any())).willReturn(sysUser); + + String result = mockMvc.perform(put(url).contentType(MediaType.APPLICATION_JSON_VALUE).content(params.toJSONString())) + .andReturn().getResponse().getContentAsString(); + JSONObject jsonObject = JSON.parseObject(result); + Assertions.assertTrue(jsonObject.getBoolean("success")); + } + + + /** + * 测试用例:删除 + */ + @Test + public void testDelete() throws Exception { + // 数据Id + String dataId = "1331795062924374018"; + // 请求地址 + String url = BASE_URL + "delete" + "?id=" + dataId; + String result = mockMvc.perform(delete(url)).andReturn().getResponse().getContentAsString(); + JSONObject jsonObject = JSON.parseObject(result); + Assertions.assertTrue(jsonObject.getBoolean("success")); + } +} From b77e9e25a38d491fb102ca572c5325c1dcc7f77a Mon Sep 17 00:00:00 2001 From: JEECG <445654970@qq.com> Date: Tue, 8 Apr 2025 15:51:11 +0800 Subject: [PATCH 2/6] =?UTF-8?q?AI=E5=8A=9F=E8=83=BD=E4=BB=8B=E7=BB=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 57 ++++++++++++++++++++++++++++--------------------------- 1 file changed, 29 insertions(+), 28 deletions(-) diff --git a/README.md b/README.md index 75fbc148b..04136ea94 100644 --- a/README.md +++ b/README.md @@ -41,6 +41,35 @@ JeecgBoot AI低代码平台,可以应用在任何J2EE项目的开发中,支 +项目说明 +----------------------------------- + +| 项目名 | 说明 | +|--------------------|------------------------| +| `jeecg-boot` | 后端源码JAVA(SpringBoot微服务架构) | +| `jeecgboot-vue3` | 前端源码VUE3(vue3+vite6+ts最新技术栈) | +| `JeecgUniapp` | [配套APP框架](https://github.com/jeecgboot/JeecgUniapp) 适配多个终端,支持APP、小程序、H5 | + + + +技术文档 +----------------------------------- + +- 官方网站: [http://www.jeecg.com](http://www.jeecg.com) +- 在线演示 : [平台演示](http://boot3.jeecg.com) | [APP演示](http://jeecg.com/appIndex) | [体验低代码](https://jeecg.blog.csdn.net/article/details/106079007) | [体验零代码](https://app.qiaoqiaoyun.com/myapps/index) +- 开发文档: [文档中心](https://help.jeecg.com) | [AIGC大模块](https://help.jeecg.com/aigc) +- 新手指南: [快速入门](http://www.jeecg.com/doc/quickstart) | [入门视频](http://jeecg.com/doc/video) | [如何反馈问题](https://github.com/jeecgboot/JeecgBoot/issues/new?template=bug_report.md) +- QQ交流群 : ⑩716488839、⑨808791225(满)、其他(满) + + + +启动项目 +----------------------------------- + +- [IDEA启动前后端项目](https://help.jeecg.com/java/setup/idea/startup) +- [Docker一键启动前后端](https://help.jeecg.com/java/docker/quick) + + AIGC应用平台介绍 ----------------------------------- @@ -91,34 +120,6 @@ AIGC应用平台介绍 | 等等。。 | √ | -项目说明 ------------------------------------ - -| 项目名 | 说明 | -|--------------------|------------------------| -| `jeecg-boot` | 后端源码JAVA(SpringBoot微服务架构) | -| `jeecgboot-vue3` | 前端源码VUE3(vue3+vite6+ts最新技术栈) | -| `JeecgUniapp` | [配套APP框架](https://github.com/jeecgboot/JeecgUniapp) 适配多个终端,支持APP、小程序、H5 | - - - -技术文档 ------------------------------------ - -- 官方网站: [http://www.jeecg.com](http://www.jeecg.com) -- 在线演示 : [平台演示](http://boot3.jeecg.com) | [APP演示](http://jeecg.com/appIndex) | [体验低代码](https://jeecg.blog.csdn.net/article/details/106079007) | [体验零代码](https://app.qiaoqiaoyun.com/myapps/index) -- 开发文档: [文档中心](https://help.jeecg.com) | [AIGC大模块](https://help.jeecg.com/aigc) -- 新手指南: [快速入门](http://www.jeecg.com/doc/quickstart) | [入门视频](http://jeecg.com/doc/video) | [如何反馈问题](https://github.com/jeecgboot/JeecgBoot/issues/new?template=bug_report.md) -- QQ交流群 : ⑩716488839、⑨808791225(满)、其他(满) - - - -启动项目 ------------------------------------ - -- [IDEA启动前后端项目](https://help.jeecg.com/java/setup/idea/startup) -- [Docker一键启动前后端](https://help.jeecg.com/java/docker/quick) - 技术架构: From 5f5970d7d517eaaa73628f8ea163e738182d018b Mon Sep 17 00:00:00 2001 From: JEECG <445654970@qq.com> Date: Tue, 8 Apr 2025 22:05:20 +0800 Subject: [PATCH 3/6] =?UTF-8?q?=E8=A7=A3=E5=86=B3=E9=92=89=E9=92=89?= =?UTF-8?q?=E7=99=BB=E5=BD=95=E6=8A=A5=E9=94=99=20class=20com.alibaba.fast?= =?UTF-8?q?json2.JSONObject=20cannot=20be=20cast=20to=20class=20com.alibab?= =?UTF-8?q?a.fastjson.JSONObject?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- jeecg-boot/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jeecg-boot/pom.xml b/jeecg-boot/pom.xml index e7a3144ef..e516dc2e7 100644 --- a/jeecg-boot/pom.xml +++ b/jeecg-boot/pom.xml @@ -359,7 +359,7 @@ org.jeecgframework weixin4j - 2.0.1 + 2.0.2 commons-beanutils From 1d18a54b8a148fca032e1c998f94b84e3553cef5 Mon Sep 17 00:00:00 2001 From: JEECG <445654970@qq.com> Date: Wed, 9 Apr 2025 09:36:49 +0800 Subject: [PATCH 4/6] =?UTF-8?q?=E8=A7=A3=E5=86=B3=E5=8D=87=E7=BA=A7underto?= =?UTF-8?q?w=E5=90=8E=EF=BC=8C=E6=80=A7=E8=83=BD=E7=9B=91=E6=8E=A7tomcat?= =?UTF-8?q?=E4=BF=A1=E6=81=AFtab=E9=A1=B9=E5=B1=95=E7=A4=BA=E7=9A=84?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../config/init/UndertowConfiguration.java | 15 +++- .../CustomUndertowMetricsHandler.java | 88 +++++++++++++++++++ .../src/views/monitor/server/index.vue | 3 +- .../src/views/monitor/server/server.api.ts | 55 ++++++++++++ 4 files changed, 159 insertions(+), 2 deletions(-) create mode 100644 jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/monitor/actuator/undertow/CustomUndertowMetricsHandler.java diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/config/init/UndertowConfiguration.java b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/config/init/UndertowConfiguration.java index 1e69b4936..3fd059aaf 100644 --- a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/config/init/UndertowConfiguration.java +++ b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/config/init/UndertowConfiguration.java @@ -1,7 +1,10 @@ package org.jeecg.config.init; import io.undertow.server.DefaultByteBufferPool; +import io.undertow.server.handlers.BlockingHandler; import io.undertow.websockets.jsr.WebSocketDeploymentInfo; +import org.jeecg.modules.monitor.actuator.undertow.CustomUndertowMetricsHandler; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.web.embedded.undertow.UndertowServletWebServerFactory; import org.springframework.boot.web.server.WebServerFactoryCustomizer; import org.springframework.context.annotation.Configuration; @@ -12,7 +15,14 @@ import org.springframework.context.annotation.Configuration; * 解决启动提示: WARN io.undertow.websockets.jsr:68 - UT026010: Buffer pool was not set on WebSocketDeploymentInfo, the default pool will be used */ @Configuration -public class UndertowConfiguration implements WebServerFactoryCustomizer{ +public class UndertowConfiguration implements WebServerFactoryCustomizer { + + /** + * 自定义undertow监控指标工具类 + * for [QQYUN-11902]tomcat 替换undertow 这里的功能还没修改 + */ + @Autowired + private CustomUndertowMetricsHandler customUndertowMetricsHandler; @Override public void customize(UndertowServletWebServerFactory factory) { @@ -24,6 +34,9 @@ public class UndertowConfiguration implements WebServerFactoryCustomizer new BlockingHandler(customUndertowMetricsHandler.wrap(next))); }); } } \ No newline at end of file diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/monitor/actuator/undertow/CustomUndertowMetricsHandler.java b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/monitor/actuator/undertow/CustomUndertowMetricsHandler.java new file mode 100644 index 000000000..b60432b3d --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/monitor/actuator/undertow/CustomUndertowMetricsHandler.java @@ -0,0 +1,88 @@ +package org.jeecg.modules.monitor.actuator.undertow; + +import io.micrometer.core.instrument.MeterRegistry; +import io.undertow.server.HttpHandler; +import io.undertow.server.HttpServerExchange; +import io.undertow.server.session.*; +import org.springframework.stereotype.Component; + +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.LongAdder; + +/** + * 自定义undertow监控指标工具类 + * for [QQYUN-11902]tomcat 替换undertow 这里的功能还没修改 + * @author chenrui + * @date 2025/4/8 19:06 + */ +@Component("jeecgCustomUndertowMetricsHandler") +public class CustomUndertowMetricsHandler { + + // 用于统计已创建的 session 数量 + private final LongAdder sessionsCreated = new LongAdder(); + + // 用于统计已销毁的 session 数量 + private final LongAdder sessionsExpired = new LongAdder(); + + // 当前活跃的 session 数量 + private final AtomicInteger activeSessions = new AtomicInteger(); + + // 历史最大活跃 session 数 + private final AtomicInteger maxActiveSessions = new AtomicInteger(); + + // Undertow 内存 session 管理器(用于创建与管理 session) + private final InMemorySessionManager sessionManager = new InMemorySessionManager("undertow-session-manager"); + + // 使用 Cookie 存储 session ID + private final SessionConfig sessionConfig = new SessionCookieConfig(); + + /** + * 构造函数 + * @param meterRegistry + * @author chenrui + * @date 2025/4/8 19:07 + */ + public CustomUndertowMetricsHandler(MeterRegistry meterRegistry) { + // 注册 Micrometer 指标 + meterRegistry.gauge("undertow.sessions.created", sessionsCreated, LongAdder::longValue); + meterRegistry.gauge("undertow.sessions.expired", sessionsExpired, LongAdder::longValue); + meterRegistry.gauge("undertow.sessions.active.current", activeSessions, AtomicInteger::get); + meterRegistry.gauge("undertow.sessions.active.max", maxActiveSessions, AtomicInteger::get); + + // 添加 session 生命周期监听器,统计 session 创建与销毁 + sessionManager.registerSessionListener(new SessionListener() { + @Override + public void sessionCreated(Session session, HttpServerExchange exchange) { + sessionsCreated.increment(); + int now = activeSessions.incrementAndGet(); + maxActiveSessions.getAndUpdate(max -> Math.max(max, now)); + } + + @Override + public void sessionDestroyed(Session session, HttpServerExchange exchange, SessionDestroyedReason reason) { + sessionsExpired.increment(); + activeSessions.decrementAndGet(); + } + }); + } + + /** + * 包装 Undertow 的 HttpHandler,实现 session 自动创建逻辑 + * @param next + * @return + * @author chenrui + * @date 2025/4/8 19:07 + */ + public HttpHandler wrap(HttpHandler next) { + return exchange -> { + // 获取当前 session,如果不存在则创建 + Session session = sessionManager.getSession(exchange, sessionConfig); + if (session == null) { + sessionManager.createSession(exchange, sessionConfig); + } + + // 执行下一个 Handler + next.handleRequest(exchange); + }; + } +} \ No newline at end of file diff --git a/jeecgboot-vue3/src/views/monitor/server/index.vue b/jeecgboot-vue3/src/views/monitor/server/index.vue index 67a2a1902..db015386b 100644 --- a/jeecgboot-vue3/src/views/monitor/server/index.vue +++ b/jeecgboot-vue3/src/views/monitor/server/index.vue @@ -4,7 +4,8 @@ - + + diff --git a/jeecgboot-vue3/src/views/monitor/server/server.api.ts b/jeecgboot-vue3/src/views/monitor/server/server.api.ts index 9f682566e..818419165 100644 --- a/jeecgboot-vue3/src/views/monitor/server/server.api.ts +++ b/jeecgboot-vue3/src/views/monitor/server/server.api.ts @@ -30,6 +30,11 @@ enum Api { tomcatSessionsRejected = '/actuator/metrics/tomcat.sessions.rejected', memoryInfo = '/sys/actuator/memory/info', + // undertow 监控 + undertowSessionsCreated = '/actuator/metrics/undertow.sessions.created', + undertowSessionsExpired = '/actuator/metrics/undertow.sessions.expired', + undertowSessionsActiveCurrent = '/actuator/metrics/undertow.sessions.active.current', + undertowSessionsActiveMax = '/actuator/metrics/undertow.sessions.active.max', } /** @@ -207,6 +212,34 @@ export const getTomcatSessionsRejected = () => { return defHttp.get({ url: Api.tomcatSessionsRejected }, { isTransformResponse: false }); }; +/** + *undertow 已创建 session 数 + */ +export const getUndertowSessionsCreated = () => { + return defHttp.get({ url: Api.undertowSessionsCreated }, { isTransformResponse: false }); +}; + +/** + *undertow 已过期 session 数 + */ +export const getUndertowSessionsExpired = () => { + return defHttp.get({ url: Api.undertowSessionsExpired }, { isTransformResponse: false }); +}; + +/** + *undertow 当前活跃 session 数 + */ +export const getUndertowSessionsActiveCurrent = () => { + return defHttp.get({ url: Api.undertowSessionsActiveCurrent }, { isTransformResponse: false }); +}; + +/** + *undertow 活跃 session 数峰值 + */ +export const getUndertowSessionsActiveMax = () => { + return defHttp.get({ url: Api.undertowSessionsActiveMax }, { isTransformResponse: false }); +}; + /** * 内存信息 */ @@ -230,6 +263,9 @@ export const getMoreInfo = (infoType) => { if (infoType == '5') { return {}; } + if (infoType == '6') { + return {}; + } }; export const getTextInfo = (infoType) => { @@ -293,6 +329,16 @@ export const getTextInfo = (infoType) => { 'memory.runtime.usage': { color: 'purple', text: 'JVM内存使用率', unit: '%', valueType: 'Number' }, }; } + if (infoType == '6') { + // undertow 监控 + return { + 'undertow.sessions.created': { color: 'green', text: 'undertow 已创建 session 数', unit: '个' }, + 'undertow.sessions.expired': { color: 'green', text: 'undertow 已过期 session 数', unit: '个' }, + 'undertow.sessions.active.current': { color: 'green', text: 'undertow 当前活跃 session 数', unit: '个' }, + 'undertow.sessions.active.max': { color: 'green', text: 'undertow 活跃 session 数峰值', unit: '个' }, + 'undertow.sessions.rejected': { color: 'green', text: '超过session 最大配置后,拒绝的 session 个数', unit: '个' }, + }; + } }; /** @@ -334,4 +380,13 @@ export const getServerInfo = (infoType) => { if (infoType == '5') { return Promise.all([getMemoryInfo()]); } + // undertow监控 + if (infoType == '6') { + return Promise.all([ + getUndertowSessionsActiveCurrent(), + getUndertowSessionsActiveMax(), + getUndertowSessionsCreated(), + getUndertowSessionsExpired(), + ]); + } }; From 73a5f64d7e963cb7c1ae54afb368aa4ffe2401c0 Mon Sep 17 00:00:00 2001 From: JEECG <445654970@qq.com> Date: Wed, 9 Apr 2025 09:39:34 +0800 Subject: [PATCH 5/6] =?UTF-8?q?=E3=80=90issues/8034=E3=80=91hash=E6=A8=A1?= =?UTF-8?q?=E5=BC=8F=E4=B8=8B=E9=80=80=E5=87=BA=E9=87=8D=E7=99=BB=E5=BD=95?= =?UTF-8?q?=E9=BB=98=E8=AE=A4=E8=B7=B3=E8=BD=AC=E5=9C=B0=E5=9D=80=E5=BC=82?= =?UTF-8?q?=E5=B8=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- jeecgboot-vue3/src/store/modules/user.ts | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/jeecgboot-vue3/src/store/modules/user.ts b/jeecgboot-vue3/src/store/modules/user.ts index 08044c8b7..099710d72 100644 --- a/jeecgboot-vue3/src/store/modules/user.ts +++ b/jeecgboot-vue3/src/store/modules/user.ts @@ -209,18 +209,11 @@ export const useUserStore = defineStore({ //update-begin---author:wangshuai ---date:20230424 for:【QQYUN-5195】登录之后直接刷新页面导致没有进入创建组织页面------------ if (redirect && goHome) { //update-end---author:wangshuai ---date:20230424 for:【QQYUN-5195】登录之后直接刷新页面导致没有进入创建组织页面------------ - // update-begin--author:liaozhiyang---date:20240104---for:【QQYUN-7804】部署生产环境,登录跳转404问题 - let publicPath = import.meta.env.VITE_PUBLIC_PATH; - if (publicPath && publicPath != '/') { - // update-begin--author:liaozhiyang---date:20240509---for:【issues/1147】登录跳转时去掉发布路径的最后一个/以解决404问题 - if (publicPath.endsWith('/')) { - publicPath = publicPath.slice(0, -1); - } - redirect = publicPath + redirect; - } - // update-end--author:liaozhiyang---date:20240509---for:【issues/1147】登录跳转时去掉发布路径的最后一个/以解决404问题 + // update-begin--author:liaozhiyang---date:20250407---for:【issues/8034】hash模式下退出重登录默认跳转地址异常 + // router.options.history.base可替代之前的publicPath // 当前页面打开 - window.open(redirect, '_self') + window.open(`${router.options.history.base}${redirect}`, '_self'); + // update-end--author:liaozhiyang---date:20250407---for:【issues/8034】hash模式下退出重登录默认跳转地址异常 return data; } // update-end-author:sunjianlei date:20230306 for: 修复登录成功后,没有正确重定向的问题 From 83b1c8692e63351a090642b2d66c5dab28b11999 Mon Sep 17 00:00:00 2001 From: JEECG <445654970@qq.com> Date: Wed, 9 Apr 2025 09:40:58 +0800 Subject: [PATCH 6/6] =?UTF-8?q?ApiSelect=E7=BB=84=E4=BB=B6=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E5=88=86=E9=A1=B5=E4=B8=8B=E6=8B=89=E6=96=B9=E6=A1=88?= =?UTF-8?q?=20#7883?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Form/src/components/ApiSelect.vue | 91 +++++++++++++++---- 1 file changed, 73 insertions(+), 18 deletions(-) diff --git a/jeecgboot-vue3/src/components/Form/src/components/ApiSelect.vue b/jeecgboot-vue3/src/components/Form/src/components/ApiSelect.vue index b9127e7ae..24d2753e9 100644 --- a/jeecgboot-vue3/src/components/Form/src/components/ApiSelect.vue +++ b/jeecgboot-vue3/src/components/Form/src/components/ApiSelect.vue @@ -1,5 +1,12 @@