diff --git a/jeecg-boot/jeecg-boot-base-core/src/main/java/org/jeecg/config/Swagger3Config.java b/jeecg-boot/jeecg-boot-base-core/src/main/java/org/jeecg/config/Swagger3Config.java index adb47621e..1dd4f2855 100644 --- a/jeecg-boot/jeecg-boot-base-core/src/main/java/org/jeecg/config/Swagger3Config.java +++ b/jeecg-boot/jeecg-boot-base-core/src/main/java/org/jeecg/config/Swagger3Config.java @@ -3,7 +3,6 @@ package org.jeecg.config; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.models.Components; import io.swagger.v3.oas.models.OpenAPI; -import io.swagger.v3.oas.models.Paths; import io.swagger.v3.oas.models.info.Contact; import io.swagger.v3.oas.models.info.Info; import io.swagger.v3.oas.models.info.License; @@ -11,10 +10,11 @@ import io.swagger.v3.oas.models.security.SecurityRequirement; import io.swagger.v3.oas.models.security.SecurityScheme; import lombok.extern.slf4j.Slf4j; import org.jeecg.common.constant.CommonConstant; -import org.springdoc.core.GroupedOpenApi; import org.springdoc.core.customizers.GlobalOpenApiCustomizer; +import org.springdoc.core.filters.GlobalOpenApiMethodFilter; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.PropertySource; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @@ -27,6 +27,7 @@ import java.util.Set; */ @Slf4j @Configuration +@PropertySource("classpath:config/default-spring-doc.properties") public class Swagger3Config implements WebMvcConfigurer { // 定义不需要注入安全要求的路径集合 Set excludedPaths = new HashSet<>(Arrays.asList( @@ -55,16 +56,8 @@ public class Swagger3Config implements WebMvcConfigurer { } @Bean - public GroupedOpenApi swaggerOpenApi() { - return GroupedOpenApi.builder() - .group("default") - .packagesToScan("org.jeecg") - // 剔除以下几个包路径的接口生成文档 - .packagesToExclude("org.jeecg.modules.drag", "org.jeecg.modules.online", "org.jeecg.modules.jmreport") - // 加了Operation注解的方法,才生成接口文档 - .addOpenApiMethodFilter(method -> method.isAnnotationPresent(Operation.class)) - .addOpenApiCustomiser(globalOpenApiCustomizer()) - .build(); + public GlobalOpenApiMethodFilter globalOpenApiMethodFilter() { + return method -> method.isAnnotationPresent(Operation.class); } @Bean diff --git a/jeecg-boot/jeecg-boot-base-core/src/main/java/org/jeecg/config/WebMvcConfiguration.java b/jeecg-boot/jeecg-boot-base-core/src/main/java/org/jeecg/config/WebMvcConfiguration.java index 1fce8270b..2515f5d03 100644 --- a/jeecg-boot/jeecg-boot-base-core/src/main/java/org/jeecg/config/WebMvcConfiguration.java +++ b/jeecg-boot/jeecg-boot-base-core/src/main/java/org/jeecg/config/WebMvcConfiguration.java @@ -13,9 +13,11 @@ import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer; import io.micrometer.prometheus.PrometheusMeterRegistry; import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.config.BeanPostProcessor; import org.springframework.boot.actuate.trace.http.InMemoryHttpTraceRepository; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Conditional; import org.springframework.context.annotation.Configuration; @@ -148,6 +150,7 @@ public class WebMvcConfiguration implements WebMvcConfigurer { * 解决metrics端点不显示jvm信息的问题(zyf) */ @Bean + @ConditionalOnBean(name = "meterRegistryPostProcessor") InitializingBean forcePrometheusPostProcessor(BeanPostProcessor meterRegistryPostProcessor) { return () -> meterRegistryPostProcessor.postProcessAfterInitialization(prometheusMeterRegistry, ""); } diff --git a/jeecg-boot/jeecg-boot-base-core/src/main/resources/config/default-spring-doc.properties b/jeecg-boot/jeecg-boot-base-core/src/main/resources/config/default-spring-doc.properties new file mode 100644 index 000000000..91f214b50 --- /dev/null +++ b/jeecg-boot/jeecg-boot-base-core/src/main/resources/config/default-spring-doc.properties @@ -0,0 +1,2 @@ +springdoc.auto-tag-classes: false +springdoc.packages-to-scan: org.jeecg \ No newline at end of file diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/src/main/resources/application-dev.yml b/jeecg-boot/jeecg-module-system/jeecg-system-start/src/main/resources/application-dev.yml index 99bc91498..c6a1241ab 100644 --- a/jeecg-boot/jeecg-module-system/jeecg-system-start/src/main/resources/application-dev.yml +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/src/main/resources/application-dev.yml @@ -281,7 +281,6 @@ logging: level: org.flywaydb: debug org.jeecg.modules.system.mapper: info -#swagger knife4j: #开启增强配置 enable: true diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/src/test/java/org/jeecg/modules/system/test/MockControllerTest.java b/jeecg-boot/jeecg-module-system/jeecg-system-start/src/test/java/org/jeecg/modules/system/test/MockControllerTest.java new file mode 100644 index 000000000..55087b690 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/src/test/java/org/jeecg/modules/system/test/MockControllerTest.java @@ -0,0 +1,37 @@ +package org.jeecg.modules.system.test; + +import org.jeecg.config.JeecgBaseConfig; +import org.jeecg.modules.base.service.BaseCommonService; +import org.jeecg.modules.demo.mock.MockController; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.result.MockMvcResultHandlers; +import org.springframework.test.web.servlet.result.MockMvcResultMatchers; + +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; + +/** + * 单个controller测试 + * @date 2025/4/7 11:21 + */ +@WebMvcTest(value = MockController.class) +public class MockControllerTest { + @Autowired + private MockMvc mockMvc; + + @MockBean + private BaseCommonService baseCommonService; + @MockBean + private JeecgBaseConfig jeecgBaseConfig; + + @Test + public void testSave() throws Exception { + mockMvc.perform(get("/mock/api/json/area")) + .andDo(MockMvcResultHandlers.print()) + .andExpect(MockMvcResultMatchers.status().isOk()); + } + +} diff --git a/jeecg-boot/jeecg-server-cloud/jeecg-cloud-gateway/pom.xml b/jeecg-boot/jeecg-server-cloud/jeecg-cloud-gateway/pom.xml index b823f40ca..844fc7e30 100644 --- a/jeecg-boot/jeecg-server-cloud/jeecg-cloud-gateway/pom.xml +++ b/jeecg-boot/jeecg-server-cloud/jeecg-cloud-gateway/pom.xml @@ -73,7 +73,7 @@ com.github.xiaoymin - knife4j-gateway-spring-boot-starter + knife4j-openapi2-spring-boot-starter ${knife4j-spring-boot-starter.version} diff --git a/jeecg-boot/jeecg-server-cloud/jeecg-cloud-gateway/src/main/java/org/jeecg/handler/swagger/MySwaggerResourceProvider.java b/jeecg-boot/jeecg-server-cloud/jeecg-cloud-gateway/src/main/java/org/jeecg/handler/swagger/MySwaggerResourceProvider.java index 37937f40f..438a07224 100644 --- a/jeecg-boot/jeecg-server-cloud/jeecg-cloud-gateway/src/main/java/org/jeecg/handler/swagger/MySwaggerResourceProvider.java +++ b/jeecg-boot/jeecg-server-cloud/jeecg-cloud-gateway/src/main/java/org/jeecg/handler/swagger/MySwaggerResourceProvider.java @@ -1,160 +1,160 @@ -//package org.jeecg.handler.swagger; -// -//import cn.hutool.core.util.ArrayUtil; -//import cn.hutool.core.util.ObjectUtil; -//import com.alibaba.nacos.api.naming.NamingFactory; -//import com.alibaba.nacos.api.naming.NamingService; -//import com.alibaba.nacos.api.naming.pojo.Instance; -//import lombok.extern.slf4j.Slf4j; -//import org.springframework.beans.factory.annotation.Autowired; -//import org.springframework.beans.factory.annotation.Value; -//import org.springframework.cloud.gateway.route.RouteLocator; -//import org.springframework.context.annotation.Primary; -//import org.springframework.stereotype.Component; -// -//import springfox.documentation.swagger.web.SwaggerResource; -//import springfox.documentation.swagger.web.SwaggerResourcesProvider; -// -//import java.util.*; -// -///** -// * 聚合各个服务的swagger接口 -// * @author zyf -// * @date: 2022/4/21 10:55 -// */ -//@Component -//@Slf4j -//@Primary -//public class MySwaggerResourceProvider implements SwaggerResourcesProvider { -// /** -// * swagger2默认的url后缀 -// */ -// private static final String SWAGGER2URL = "/v2/api-docs"; -// -// /** -// * 网关路由 -// */ -// private final RouteLocator routeLocator; -// /** -// * Nacos名字服务 -// */ -// private NamingService naming; -// -// /** -// * nacos服务地址 -// */ -// @Value("${spring.cloud.nacos.discovery.server-addr}") -// private String serverAddr; -// /** -// * nacos namespace -// */ -// @Value("${spring.cloud.nacos.discovery.namespace:#{null}}") -// private String namespace; -// -// /** -// * nacos groupName -// */ -// @Value("${spring.cloud.nacos.config.group:DEFAULT_GROUP:#{null}}") -// private String group; -// -// /** -// * nacos username -// */ -// @Value("${spring.cloud.nacos.discovery.username:#{null}}") -// private String username; -// /** -// * nacos password -// */ -// @Value("${spring.cloud.nacos.discovery.password:#{null}}") -// private String password; -// -// /** -// * Swagger中需要排除的服务 -// */ -// private String[] excludeServiceIds=new String[]{"jeecg-cloud-monitor"}; -// -// -// /** -// * 网关应用名称 -// */ -// @Value("${spring.application.name}") -// private String self; -// -// @Autowired -// public MySwaggerResourceProvider(RouteLocator routeLocator) { -// this.routeLocator = routeLocator; -// } -// -// @Override -// public List get() { -// List resources = new ArrayList<>(); -// List routeHosts = new ArrayList<>(); -// // 获取所有可用的host:serviceId -// routeLocator.getRoutes().filter(route -> route.getUri().getHost() != null) -// .filter(route -> !self.equals(route.getUri().getHost())) -// .subscribe(route ->{ -// //update-begin---author:zyf ---date:20220413 for:过滤掉无效路由,避免接口文档报错无法打开 -// boolean hasRoute=checkRoute(route.getId()); -// if(hasRoute){ -// routeHosts.add(route.getUri().getHost()); -// } -// //update-end---author:zyf ---date:20220413 for:过滤掉无效路由,避免接口文档报错无法打开 -// }); -// -// // 记录已经添加过的server,存在同一个应用注册了多个服务在nacos上 -// Set dealed = new HashSet<>(); -// routeHosts.forEach(instance -> { -// // 拼接url -// String url = "/" + instance.toLowerCase() + SWAGGER2URL; -// if (!dealed.contains(url)) { -// dealed.add(url); -// log.info(" Gateway add SwaggerResource: {}",url); -// SwaggerResource swaggerResource = new SwaggerResource(); -// swaggerResource.setUrl(url); -// swaggerResource.setSwaggerVersion("2.0"); -// swaggerResource.setName(instance); -// //Swagger排除不展示的服务 -// if(!ArrayUtil.contains(excludeServiceIds,instance)){ -// resources.add(swaggerResource); -// } -// } -// }); -// return resources; -// } -// -// /** -// * 检测nacos中是否有健康实例 -// * @param routeId -// * @return -// */ -// private Boolean checkRoute(String routeId) { -// Boolean hasRoute = false; -// try { -// //修复使用带命名空间启动网关swagger看不到接口文档的问题 -// Properties properties=new Properties(); -// properties.setProperty("serverAddr",serverAddr); -// if(namespace!=null && !"".equals(namespace)){ -// log.info("nacos.discovery.namespace = {}", namespace); -// properties.setProperty("namespace",namespace); -// } -// if(username!=null && !"".equals(username)){ -// properties.setProperty("username",username); -// } -// if(password!=null && !"".equals(password)){ -// properties.setProperty("password",password); -// } -// //【issues/5115】因swagger文档导致gateway内存溢出 -// if (this.naming == null) { -// this.naming = NamingFactory.createNamingService(properties); -// } -// log.info(" config.group : {}", group); -// List list = this.naming.selectInstances(routeId, group , true); -// if (ObjectUtil.isNotEmpty(list)) { -// hasRoute = true; -// } -// } catch (Exception e) { -// e.printStackTrace(); -// } -// return hasRoute; -// } -//} \ No newline at end of file +package org.jeecg.handler.swagger; + +import cn.hutool.core.util.ArrayUtil; +import cn.hutool.core.util.ObjectUtil; +import com.alibaba.nacos.api.naming.NamingFactory; +import com.alibaba.nacos.api.naming.NamingService; +import com.alibaba.nacos.api.naming.pojo.Instance; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.cloud.gateway.route.RouteLocator; +import org.springframework.context.annotation.Primary; +import org.springframework.stereotype.Component; + +import springfox.documentation.swagger.web.SwaggerResource; +import springfox.documentation.swagger.web.SwaggerResourcesProvider; + +import java.util.*; + +/** 已使用knife4j-gateway支持该功能 + * 聚合各个服务的swagger接口 + * @author zyf + * @date: 2022/4/21 10:55 + */ +@Component +@Slf4j +@Primary +public class MySwaggerResourceProvider implements SwaggerResourcesProvider { + /** + * swagger2默认的url后缀 + */ + private static final String SWAGGER2URL = "/v3/api-docs"; + + /** + * 网关路由 + */ + private final RouteLocator routeLocator; + /** + * Nacos名字服务 + */ + private NamingService naming; + + /** + * nacos服务地址 + */ + @Value("${spring.cloud.nacos.discovery.server-addr}") + private String serverAddr; + /** + * nacos namespace + */ + @Value("${spring.cloud.nacos.discovery.namespace:#{null}}") + private String namespace; + + /** + * nacos groupName + */ + @Value("${spring.cloud.nacos.config.group:DEFAULT_GROUP:#{null}}") + private String group; + + /** + * nacos username + */ + @Value("${spring.cloud.nacos.discovery.username:#{null}}") + private String username; + /** + * nacos password + */ + @Value("${spring.cloud.nacos.discovery.password:#{null}}") + private String password; + + /** + * Swagger中需要排除的服务 + */ + private String[] excludeServiceIds=new String[]{"jeecg-cloud-monitor"}; + + + /** + * 网关应用名称 + */ + @Value("${spring.application.name}") + private String self; + + @Autowired + public MySwaggerResourceProvider(RouteLocator routeLocator) { + this.routeLocator = routeLocator; + } + + @Override + public List get() { + List resources = new ArrayList<>(); + List routeHosts = new ArrayList<>(); + // 获取所有可用的host:serviceId + routeLocator.getRoutes().filter(route -> route.getUri().getHost() != null) + .filter(route -> !self.equals(route.getUri().getHost())) + .subscribe(route ->{ + //update-begin---author:zyf ---date:20220413 for:过滤掉无效路由,避免接口文档报错无法打开 + boolean hasRoute=checkRoute(route.getId()); + if(hasRoute){ + routeHosts.add(route.getUri().getHost()); + } + //update-end---author:zyf ---date:20220413 for:过滤掉无效路由,避免接口文档报错无法打开 + }); + + // 记录已经添加过的server,存在同一个应用注册了多个服务在nacos上 + Set dealed = new HashSet<>(); + routeHosts.forEach(instance -> { + // 拼接url + String url = "/" + instance.toLowerCase() + SWAGGER2URL; + if (!dealed.contains(url)) { + dealed.add(url); + log.info(" Gateway add SwaggerResource: {}",url); + SwaggerResource swaggerResource = new SwaggerResource(); + swaggerResource.setUrl(url); + swaggerResource.setSwaggerVersion("2.0"); + swaggerResource.setName(instance); + //Swagger排除不展示的服务 + if(!ArrayUtil.contains(excludeServiceIds,instance)){ + resources.add(swaggerResource); + } + } + }); + return resources; + } + + /** + * 检测nacos中是否有健康实例 + * @param routeId + * @return + */ + private Boolean checkRoute(String routeId) { + Boolean hasRoute = false; + try { + //修复使用带命名空间启动网关swagger看不到接口文档的问题 + Properties properties=new Properties(); + properties.setProperty("serverAddr",serverAddr); + if(namespace!=null && !"".equals(namespace)){ + log.info("nacos.discovery.namespace = {}", namespace); + properties.setProperty("namespace",namespace); + } + if(username!=null && !"".equals(username)){ + properties.setProperty("username",username); + } + if(password!=null && !"".equals(password)){ + properties.setProperty("password",password); + } + //【issues/5115】因swagger文档导致gateway内存溢出 + if (this.naming == null) { + this.naming = NamingFactory.createNamingService(properties); + } + log.info(" config.group : {}", group); + List list = this.naming.selectInstances(routeId, group , true); + if (ObjectUtil.isNotEmpty(list)) { + hasRoute = true; + } + } catch (Exception e) { + e.printStackTrace(); + } + return hasRoute; + } +} \ No newline at end of file diff --git a/jeecg-boot/jeecg-server-cloud/jeecg-cloud-gateway/src/main/java/org/jeecg/handler/swagger/SwaggerResourceController.java b/jeecg-boot/jeecg-server-cloud/jeecg-cloud-gateway/src/main/java/org/jeecg/handler/swagger/SwaggerResourceController.java index 1268d7200..6a6391101 100644 --- a/jeecg-boot/jeecg-server-cloud/jeecg-cloud-gateway/src/main/java/org/jeecg/handler/swagger/SwaggerResourceController.java +++ b/jeecg-boot/jeecg-server-cloud/jeecg-cloud-gateway/src/main/java/org/jeecg/handler/swagger/SwaggerResourceController.java @@ -1,52 +1,41 @@ -//package org.jeecg.handler.swagger; -// -//import org.springframework.beans.factory.annotation.Autowired; -//import org.springframework.beans.factory.annotation.Value; -//import org.springframework.http.HttpStatus; -//import org.springframework.http.ResponseEntity; -//import org.springframework.web.bind.annotation.RequestMapping; -//import org.springframework.web.bind.annotation.RestController; -//import springfox.documentation.swagger.web.*; -// -//import java.util.ArrayList; -//import java.util.List; -// -///** -// * swagger聚合接口,三个接口都是 doc.html需要访问的接口 -// * @author zyf -// * @date: 2022/4/21 10:55 -// */ -//@RestController -//@RequestMapping("/swagger-resources") -//public class SwaggerResourceController { -// private MySwaggerResourceProvider swaggerResourceProvider; -// /** -// * 生产环境,关闭swagger文档 -// */ -// @Value("${knife4j.production:#{null}}") -// private Boolean production; -// -// @Autowired -// public SwaggerResourceController(MySwaggerResourceProvider swaggerResourceProvider) { -// this.swaggerResourceProvider = swaggerResourceProvider; -// } -// -// @RequestMapping(value = "/configuration/security") -// public ResponseEntity securityConfiguration() { -// return new ResponseEntity<>(SecurityConfigurationBuilder.builder().build(), HttpStatus.OK); -// } -// -// @RequestMapping(value = "/configuration/ui") -// public ResponseEntity uiConfiguration() { -// return new ResponseEntity<>(UiConfigurationBuilder.builder().build(), HttpStatus.OK); -// } -// -// @RequestMapping -// public ResponseEntity> swaggerResources() { -// // 是否开启生产环境屏蔽swagger -// if (production != null && production) { -// return new ResponseEntity<>(new ArrayList<>(), HttpStatus.OK); -// } -// return new ResponseEntity<>(swaggerResourceProvider.get(), HttpStatus.OK); -// } -//} \ No newline at end of file +package org.jeecg.handler.swagger; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import springfox.documentation.swagger.web.*; + +import java.util.List; + +/** 已使用knife4j-gateway支持该功能 + * swagger聚合接口,三个接口都是 doc.html需要访问的接口 + * @author zyf + * @date: 2022/4/21 10:55 + */ +@RestController +@RequestMapping("/swagger-resources") +public class SwaggerResourceController { + private MySwaggerResourceProvider swaggerResourceProvider; + + @Autowired + public SwaggerResourceController(MySwaggerResourceProvider swaggerResourceProvider) { + this.swaggerResourceProvider = swaggerResourceProvider; + } + + @RequestMapping(value = "/configuration/security") + public ResponseEntity securityConfiguration() { + return new ResponseEntity<>(SecurityConfigurationBuilder.builder().build(), HttpStatus.OK); + } + + @RequestMapping(value = "/configuration/ui") + public ResponseEntity uiConfiguration() { + return new ResponseEntity<>(UiConfigurationBuilder.builder().build(), HttpStatus.OK); + } + + @RequestMapping + public ResponseEntity> swaggerResources() { + return new ResponseEntity<>(swaggerResourceProvider.get(), HttpStatus.OK); + } +} \ No newline at end of file diff --git a/jeecg-boot/jeecg-server-cloud/jeecg-system-cloud-start/src/main/resources/application.yml b/jeecg-boot/jeecg-server-cloud/jeecg-system-cloud-start/src/main/resources/application.yml index 9841caa38..21d0336f8 100644 --- a/jeecg-boot/jeecg-server-cloud/jeecg-system-cloud-start/src/main/resources/application.yml +++ b/jeecg-boot/jeecg-server-cloud/jeecg-system-cloud-start/src/main/resources/application.yml @@ -1,11 +1,6 @@ server: port: 7001 -springdoc: - packages-to-exclude: - - org.jeecg.modules.drag - - org.jeecg.modules.online - - org.jeecg.modules.jmreport spring: application: name: jeecg-system diff --git a/jeecgboot-vue3/src/components/Table/src/components/settings/ColumnSetting.vue b/jeecgboot-vue3/src/components/Table/src/components/settings/ColumnSetting.vue index 92dcd618c..28feed5e0 100644 --- a/jeecgboot-vue3/src/components/Table/src/components/settings/ColumnSetting.vue +++ b/jeecgboot-vue3/src/components/Table/src/components/settings/ColumnSetting.vue @@ -188,7 +188,7 @@ const sortableOrder = ref(); const localeStore = useLocaleStoreWithOut(); // 列表字段配置缓存 - const { saveSetting, resetSetting } = useColumnsCache( + const { saveSetting, resetSetting, getCache } = useColumnsCache( { state, popoverVisible, @@ -204,8 +204,7 @@ watchEffect(() => { setTimeout(() => { - const columns = table.getColumns(); - if (columns.length && !state.isInit) { + if (!state.isInit) { init(); } }, 0); @@ -227,7 +226,13 @@ function getColumns() { const ret: Options[] = []; - table.getColumns({ ignoreIndex: true, ignoreAction: true }).forEach((item) => { + // update-begin--author:liaozhiyang---date:20250403---for:【issues/7996】表格列组件取消所有或者只勾选中间,显示非预期 + let t = table.getColumns({ ignoreIndex: true, ignoreAction: true }); + if (!t.length) { + t = table.getCacheColumns(); + } + // update-end--author:liaozhiyang---date:20250403---for:【issues/7996】表格列组件取消所有或者只勾选中间,显示非预期 + t.forEach((item) => { ret.push({ label: (item.title as string) || (item.customTitle as string), value: (item.dataIndex || item.title) as string, @@ -237,7 +242,7 @@ return ret; } - function init() { + async function init() { const columns = getColumns(); const checkList = table @@ -249,11 +254,22 @@ return item.dataIndex || item.title; }) .filter(Boolean) as string[]; - + // update-begin--author:liaozhiyang---date:20250403---for:【issues/7996】表格列组件取消所有或者只勾选中间,显示非预期 + const { sortedList = [] } = getCache() || {}; + await nextTick(); + // update-end--author:liaozhiyang---date:20250403---for:【issues/7996】表格列组件取消所有或者只勾选中间,显示非预期 if (!plainOptions.value.length) { - plainOptions.value = columns; - plainSortOptions.value = columns; - cachePlainOptions.value = columns; + // update-begin--author:liaozhiyang---date:20250403---for:【issues/7996】表格列组件取消所有或者只勾选中间,显示非预期 + let tmp = columns; + if (sortedList?.length) { + tmp = columns.sort((prev, next) => { + return sortedList.indexOf(prev.value) - sortedList.indexOf(next.value); + }); + } + // update-end--author:liaozhiyang---date:20250403---for:【issues/7996】表格列组件取消所有或者只勾选中间,显示非预期 + plainOptions.value = tmp; + plainSortOptions.value = tmp; + cachePlainOptions.value = tmp; state.defaultCheckList = checkList; } else { // const fixedColumns = columns.filter((item) => @@ -266,6 +282,13 @@ item.fixed = findItem.fixed; } }); + // update-begin--author:liaozhiyang---date:20250403---for:【issues/7996】表格列组件取消所有或者只勾选中间,显示非预期 + if (sortedList?.length) { + plainOptions.value.sort((prev, next) => { + return sortedList.indexOf(prev.value) - sortedList.indexOf(next.value); + }); + } + // update-end--author:liaozhiyang---date:20250403---for:【issues/7996】表格列组件取消所有或者只勾选中间,显示非预期 } state.isInit = true; state.checkedList = checkList; diff --git a/jeecgboot-vue3/src/components/Table/src/hooks/useColumnsCache.ts b/jeecgboot-vue3/src/components/Table/src/hooks/useColumnsCache.ts index bd1020c49..2d5f8e8e5 100644 --- a/jeecgboot-vue3/src/components/Table/src/hooks/useColumnsCache.ts +++ b/jeecgboot-vue3/src/components/Table/src/hooks/useColumnsCache.ts @@ -144,5 +144,6 @@ export function useColumnsCache(opt, setColumns, handleColumnFixed) { return { saveSetting, resetSetting, + getCache: () => $ls.get(cacheKey.value), }; } diff --git a/jeecgboot-vue3/src/components/jeecg/JVxeTable/src/hooks/useColumns.ts b/jeecgboot-vue3/src/components/jeecg/JVxeTable/src/hooks/useColumns.ts index c88e5c23b..bd5669d95 100644 --- a/jeecgboot-vue3/src/components/jeecg/JVxeTable/src/hooks/useColumns.ts +++ b/jeecgboot-vue3/src/components/jeecg/JVxeTable/src/hooks/useColumns.ts @@ -1,5 +1,5 @@ import type { JVxeColumn, JVxeDataProps, JVxeTableProps } from '../types'; -import { computed, nextTick } from 'vue'; +import { computed, nextTick, toRaw } from 'vue'; import { isArray, isEmpty, isPromise } from '/@/utils/is'; import { cloneDeep } from 'lodash-es'; import { JVxeTypePrefix, JVxeTypes } from '../types/JVxeTypes'; @@ -25,6 +25,11 @@ export interface HandleArgs { export function useColumns(props: JVxeTableProps, data: JVxeDataProps, methods: JVxeTableMethods, slots) { data.vxeColumns = computed(() => { + // update-begin--author:liaozhiyang---date:20250403---for:【issues/7812】linkageConfig改变了,vxetable没更新 + // linkageConfig变化时也需要执行 + const linkageConfig = toRaw(props.linkageConfig); + console.log(linkageConfig); + // update-end--author:liaozhiyang---date:20250403---for:【issues/7812】linkageConfig改变了,vxetable没更新 let columns: JVxeColumn[] = []; if (isArray(props.columns)) { // handle 方法参数