diff --git a/db/0pigxx_boot.sql b/db/0pigxx_boot.sql index 42859cdc2..c28a3f24b 100644 --- a/db/0pigxx_boot.sql +++ b/db/0pigxx_boot.sql @@ -2398,6 +2398,8 @@ CREATE TABLE `gen_table` ( `version` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '项目版本号', `i18n` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '0' COMMENT '是否生成带有i18n 0 不带有 1带有', `style` bigint DEFAULT NULL COMMENT '代码风格', + `sync_menu_id` bigint DEFAULT NULL COMMENT '所属菜单ID', + `sync_route` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '0' COMMENT '是否自动同步路由', `child_table_name` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '子表名称', `main_field` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '主表关联键', `child_field` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '子表关联键', diff --git a/db/8pigxx_codegen.sql b/db/8pigxx_codegen.sql index 64816c65b..8c09cbbf4 100644 --- a/db/8pigxx_codegen.sql +++ b/db/8pigxx_codegen.sql @@ -152,6 +152,8 @@ CREATE TABLE `gen_table` ( `version` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '项目版本号', `i18n` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '0' COMMENT '是否生成带有i18n 0 不带有 1带有', `style` bigint DEFAULT NULL COMMENT '代码风格', + `sync_menu_id` bigint DEFAULT NULL COMMENT '所属菜单ID', + `sync_route` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '0' COMMENT '是否自动同步路由', `child_table_name` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '子表名称', `main_field` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '主表关联键', `child_field` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '子表关联键', diff --git a/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/feign/RemoteMenuService.java b/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/feign/RemoteMenuService.java new file mode 100644 index 000000000..7005c35f5 --- /dev/null +++ b/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/feign/RemoteMenuService.java @@ -0,0 +1,61 @@ +/* + * + * Copyright (c) 2018-2025, lengleng All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * Neither the name of the pig4cloud.com developer nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * Author: lengleng (wangiegie@gmail.com) + * + */ + +package com.pig4cloud.pigx.admin.api.feign; + +import com.pig4cloud.pigx.admin.api.entity.SysMenu; +import com.pig4cloud.pigx.common.core.constant.ServiceNameConstants; +import com.pig4cloud.pigx.common.core.util.R; +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.cloud.openfeign.SpringQueryMap; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; + +import java.util.List; + +/** + * 远程菜单服务 + * + * @author lengleng + * @date 2024/07/16 + */ +@FeignClient(contextId = "remoteMenuService", value = ServiceNameConstants.UPMS_SERVICE) +public interface RemoteMenuService { + + + /** + * 获取菜单详细信息 + * + * @param sysMenu SYS菜单 + * @return {@link R }<{@link List }<{@link SysMenu }>> + */ + @GetMapping("/menu/details") + R> getMenuDetails(@SpringQueryMap SysMenu sysMenu); + + + /** + * 保存菜单 + * + * @param sysMenu SYS菜单 + * @return {@link R }<{@link Boolean }> + */ + @PostMapping("/menu") + R saveMenu(@RequestBody SysMenu sysMenu); +} diff --git a/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/feign/RemoteRouteConfService.java b/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/feign/RemoteRouteConfService.java new file mode 100644 index 000000000..11c6174e4 --- /dev/null +++ b/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/feign/RemoteRouteConfService.java @@ -0,0 +1,59 @@ +/* + * + * Copyright (c) 2018-2025, lengleng All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * Neither the name of the pig4cloud.com developer nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * Author: lengleng (wangiegie@gmail.com) + * + */ + +package com.pig4cloud.pigx.admin.api.feign; + +import com.pig4cloud.pigx.admin.api.entity.SysRouteConf; +import com.pig4cloud.pigx.common.core.constant.ServiceNameConstants; +import com.pig4cloud.pigx.common.core.util.R; +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; + +import java.util.List; + +/** + * 远程路由 CONF 服务 + * + * @author lengleng + * @date 2024/07/16 + */ +@FeignClient(contextId = "remoteRouteConfService", value = ServiceNameConstants.UPMS_SERVICE) +public interface RemoteRouteConfService { + + + /** + * 获取路由详细信息 + * + * @return {@link R }<{@link List }<{@link SysRouteConf }>> + */ + @GetMapping("/route") + R> getRouteDetails(); + + + /** + * 保存 sys route conf + * + * @param SysRouteConf sys 路由配置 + * @return {@link R }<{@link Boolean }> + */ + @PostMapping("/route/save") + R saveSysRouteConf(@RequestBody SysRouteConf SysRouteConf); +} diff --git a/pigx-upms/pigx-upms-api/src/main/resources/META-INF/spring/org.springframework.cloud.openfeign.FeignClient.imports b/pigx-upms/pigx-upms-api/src/main/resources/META-INF/spring/org.springframework.cloud.openfeign.FeignClient.imports index 88c53286e..9c6fd9992 100644 --- a/pigx-upms/pigx-upms-api/src/main/resources/META-INF/spring/org.springframework.cloud.openfeign.FeignClient.imports +++ b/pigx-upms/pigx-upms-api/src/main/resources/META-INF/spring/org.springframework.cloud.openfeign.FeignClient.imports @@ -10,3 +10,5 @@ com.pig4cloud.pigx.admin.api.feign.RemoteRoleService com.pig4cloud.pigx.admin.api.feign.RemoteDeptService com.pig4cloud.pigx.admin.api.feign.RemoteDictService com.pig4cloud.pigx.admin.api.feign.RemoteAuditLogService +com.pig4cloud.pigx.admin.api.feign.RemoteMenuService +com.pig4cloud.pigx.admin.api.feign.RemoteRouteConfService diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysRouteConfController.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysRouteConfController.java index 3c1ecd7ba..471d65397 100755 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysRouteConfController.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysRouteConfController.java @@ -77,4 +77,10 @@ public class SysRouteConfController { return R.ok(sysRouteConfService.addOrUpdateRoute(route)); } + @SysLog("新增路由") + @PostMapping("/save") + @PreAuthorize("@pms.hasPermission('sys_route_manage')") + public R saveRoute(@RequestBody SysRouteConf routeConf) { + return R.ok(sysRouteConfService.saveRoute(routeConf)); + } } diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/SysRouteConfService.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/SysRouteConfService.java index 0fcd140d2..b921aa018 100644 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/SysRouteConfService.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/SysRouteConfService.java @@ -37,4 +37,11 @@ public interface SysRouteConfService extends IService { */ Mono addOrUpdateRoute(JSONObject route); + /** + * 保存路由 + * + * @param routeConf 路由配置 + * @return {@link SysRouteConf } + */ + SysRouteConf saveRoute(SysRouteConf routeConf); } diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysRouteConfServiceImpl.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysRouteConfServiceImpl.java index 13dc0b5a2..92d6e4cea 100755 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysRouteConfServiceImpl.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysRouteConfServiceImpl.java @@ -51,83 +51,96 @@ import java.util.Map; @AllArgsConstructor @Service("sysRouteConfService") public class SysRouteConfServiceImpl extends ServiceImpl - implements SysRouteConfService { + implements SysRouteConfService { - private final ApplicationEventPublisher applicationEventPublisher; + private final ApplicationEventPublisher applicationEventPublisher; - /** - * 更新路由信息 - * @param route 路由信息 - * @return - */ - @Override - @Transactional(rollbackFor = Exception.class) - public Mono addOrUpdateRoute(JSONObject route) { - try { - log.info("更新路由 ->{}", route); - RouteDefinitionVo vo = new RouteDefinitionVo(); + /** + * 更新路由信息 + * + * @param route 路由信息 + * @return + */ + @Override + @Transactional(rollbackFor = Exception.class) + public Mono addOrUpdateRoute(JSONObject route) { + try { + log.info("更新路由 ->{}", route); + RouteDefinitionVo vo = new RouteDefinitionVo(); - String id = route.getStr("routeId"); - if (StrUtil.isNotBlank(id)) { - vo.setId(id); - } + String id = route.getStr("routeId"); + if (StrUtil.isNotBlank(id)) { + vo.setId(id); + } - String routeName = route.getStr("routeName"); - if (StrUtil.isNotBlank(routeName)) { - vo.setRouteName(routeName); - } + String routeName = route.getStr("routeName"); + if (StrUtil.isNotBlank(routeName)) { + vo.setRouteName(routeName); + } - JSONArray predicates = route.getJSONArray("predicates"); - if (predicates != null) { - List predicateDefinitionList = predicates.toList(PredicateDefinition.class); - vo.setPredicates(predicateDefinitionList); - } + JSONArray predicates = route.getJSONArray("predicates"); + if (predicates != null) { + List predicateDefinitionList = predicates.toList(PredicateDefinition.class); + vo.setPredicates(predicateDefinitionList); + } - JSONArray filters = route.getJSONArray("filters"); - if (filters != null) { - List filterDefinitionList = filters.toList(FilterDefinition.class); - vo.setFilters(filterDefinitionList); - } + JSONArray filters = route.getJSONArray("filters"); + if (filters != null) { + List filterDefinitionList = filters.toList(FilterDefinition.class); + vo.setFilters(filterDefinitionList); + } - Object uri = route.getStr("uri"); - if (uri != null) { - vo.setUri(URI.create(String.valueOf(uri))); - } + Object uri = route.getStr("uri"); + if (uri != null) { + vo.setUri(URI.create(String.valueOf(uri))); + } - Integer order = route.getInt("order"); - if (order != null) { - vo.setOrder(order); - } + Integer order = route.getInt("order"); + if (order != null) { + vo.setOrder(order); + } - Map metadataMap = route.getBean("metadata", Map.class); - if (metadataMap != null) { - vo.setMetadata(metadataMap); - } + Map metadataMap = route.getBean("metadata", Map.class); + if (metadataMap != null) { + vo.setMetadata(metadataMap); + } - // 逻辑删除 ,不直接更新避免危险! - this.remove(Wrappers.lambdaQuery().eq(SysRouteConf::getRouteId, id)); + // 逻辑删除 ,不直接更新避免危险! + this.remove(Wrappers.lambdaQuery().eq(SysRouteConf::getRouteId, id)); - // 插入生效路由 - SysRouteConf routeConf = new SysRouteConf(); - routeConf.setRouteId(vo.getId()); - routeConf.setRouteName(vo.getRouteName()); - routeConf.setFilters(JSONUtil.toJsonStr(vo.getFilters())); - routeConf.setPredicates(JSONUtil.toJsonStr(vo.getPredicates())); - routeConf.setSortOrder(vo.getOrder()); - routeConf.setUri(vo.getUri().toString()); - routeConf.setMetadata(JSONUtil.toJsonStr(vo.getMetadata())); - this.save(routeConf); - log.debug("更新网关路由结束 "); - } - catch (Exception e) { - log.error("路由配置解析失败", e); - // 抛出异常 - throw new RuntimeException(e); - } - finally { - this.applicationEventPublisher.publishEvent(new DynamicRouteInitEvent(this)); - } - return Mono.empty(); - } + // 插入生效路由 + SysRouteConf routeConf = new SysRouteConf(); + routeConf.setRouteId(vo.getId()); + routeConf.setRouteName(vo.getRouteName()); + routeConf.setFilters(JSONUtil.toJsonStr(vo.getFilters())); + routeConf.setPredicates(JSONUtil.toJsonStr(vo.getPredicates())); + routeConf.setSortOrder(vo.getOrder()); + routeConf.setUri(vo.getUri().toString()); + routeConf.setMetadata(JSONUtil.toJsonStr(vo.getMetadata())); + this.save(routeConf); + log.debug("更新网关路由结束 "); + } catch (Exception e) { + log.error("路由配置解析失败", e); + // 抛出异常 + throw new RuntimeException(e); + } finally { + this.applicationEventPublisher.publishEvent(new DynamicRouteInitEvent(this)); + } + return Mono.empty(); + } + + /** + * 保存路由 + * + * @param routeConf 路由配置 + * @return {@link SysRouteConf } + */ + @Override + @Transactional(rollbackFor = Exception.class) + public SysRouteConf saveRoute(SysRouteConf routeConf) { + baseMapper.insert(routeConf); + this.applicationEventPublisher.publishEvent(new DynamicRouteInitEvent(this)); + return routeConf; + } } diff --git a/pigx-visual/pigx-codegen/pom.xml b/pigx-visual/pigx-codegen/pom.xml index ae3d0aeb2..d75e07227 100755 --- a/pigx-visual/pigx-codegen/pom.xml +++ b/pigx-visual/pigx-codegen/pom.xml @@ -113,6 +113,11 @@ com.pig4cloud pigx-common-core + + + com.pig4cloud + pigx-common-idempotent + commons-configuration commons-configuration diff --git a/pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/config/PigxCodeGenDefaultProperties.java b/pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/config/PigxCodeGenDefaultProperties.java index 82cf67fc3..6b473e832 100644 --- a/pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/config/PigxCodeGenDefaultProperties.java +++ b/pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/config/PigxCodeGenDefaultProperties.java @@ -73,4 +73,9 @@ public class PigxCodeGenDefaultProperties { */ private String generatorType = "0"; + /** + * 是否同步路由 + */ + private String syncRoute = "1"; + } diff --git a/pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/controller/GeneratorController.java b/pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/controller/GeneratorController.java index 8f56b03de..04856aa01 100755 --- a/pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/controller/GeneratorController.java +++ b/pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/controller/GeneratorController.java @@ -21,6 +21,7 @@ import cn.hutool.core.io.IoUtil; import cn.hutool.core.util.StrUtil; import com.pig4cloud.pigx.codegen.service.GeneratorService; import com.pig4cloud.pigx.common.core.util.R; +import com.pig4cloud.pigx.common.idempotent.annotation.Idempotent; import jakarta.servlet.http.HttpServletResponse; import lombok.RequiredArgsConstructor; import lombok.SneakyThrows; @@ -56,6 +57,7 @@ public class GeneratorController { */ @SneakyThrows @GetMapping("/download") + @Idempotent(key = "#tableIds", expireTime = 10, info = "正在生成代码,请勿重复操作") public void download(String tableIds, HttpServletResponse response) { ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); ZipOutputStream zip = new ZipOutputStream(outputStream); @@ -82,6 +84,7 @@ public class GeneratorController { */ @ResponseBody @GetMapping("/code") + @Idempotent(key = "#tableIds", expireTime = 10, info = "正在生成代码,请勿重复操作") public R code(String tableIds) throws Exception { // 生成代码 for (String tableId : tableIds.split(StrUtil.COMMA)) { diff --git a/pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/entity/GenTable.java b/pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/entity/GenTable.java index 8f5372aff..d64e56d83 100644 --- a/pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/entity/GenTable.java +++ b/pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/entity/GenTable.java @@ -25,6 +25,7 @@ import com.baomidou.mybatisplus.extension.activerecord.Model; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; +import lombok.experimental.FieldNameConstants; import java.time.LocalDateTime; import java.util.List; @@ -37,157 +38,170 @@ import java.util.List; */ @Data @TableName("gen_table") +@FieldNameConstants @EqualsAndHashCode(callSuper = true) @Schema(description = "列属性") public class GenTable extends Model { - private static final long serialVersionUID = 1L; + private static final long serialVersionUID = 1L; - /** - * id - */ - @TableId(type = IdType.ASSIGN_ID) - @Schema(description = "id") - private Long id; + /** + * id + */ + @TableId(type = IdType.ASSIGN_ID) + @Schema(description = "id") + private Long id; - /** - * 数据源名称 - */ - @Schema(description = "数据源名称") - private String dsName; + /** + * 数据源名称 + */ + @Schema(description = "数据源名称") + private String dsName; - /** - * 数据源类型 - */ - @Schema(description = "数据源类型") - private String dbType; + /** + * 数据源类型 + */ + @Schema(description = "数据源类型") + private String dbType; - /** - * 表名 - */ - @Schema(description = "表名") - private String tableName; + /** + * 表名 + */ + @Schema(description = "表名") + private String tableName; - /** - * 类名 - */ - @Schema(description = "类名") - private String className; + /** + * 类名 + */ + @Schema(description = "类名") + private String className; - /** - * 说明 - */ - @Schema(description = "说明") - private String tableComment; + /** + * 说明 + */ + @Schema(description = "说明") + private String tableComment; - /** - * 作者 - */ - @Schema(description = "作者") - private String author; + /** + * 作者 + */ + @Schema(description = "作者") + private String author; - /** - * 邮箱 - */ - @Schema(description = "邮箱") - private String email; + /** + * 邮箱 + */ + @Schema(description = "邮箱") + private String email; - /** - * 项目包名 - */ - @Schema(description = "项目包名") - private String packageName; + /** + * 项目包名 + */ + @Schema(description = "项目包名") + private String packageName; - /** - * 项目版本号 - */ - @Schema(description = "项目版本号") - private String version; + /** + * 项目版本号 + */ + @Schema(description = "项目版本号") + private String version; - /** - * 生成方式 0:zip压缩包 1:自定义目录 - */ - @Schema(description = "生成方式 0:zip压缩包 1:自定义目录") - private String generatorType; + /** + * 生成方式 0:zip压缩包 1:自定义目录 + */ + @Schema(description = "生成方式 0:zip压缩包 1:自定义目录") + private String generatorType; - /** - * 后端生成路径 - */ - @Schema(description = "后端生成路径") - private String backendPath; + /** + * 后端生成路径 + */ + @Schema(description = "后端生成路径") + private String backendPath; - /** - * 前端生成路径 - */ - @Schema(description = "前端生成路径") - private String frontendPath; + /** + * 前端生成路径 + */ + @Schema(description = "前端生成路径") + private String frontendPath; - /** - * 模块名 - */ - @Schema(description = "模块名") - private String moduleName; + /** + * 模块名 + */ + @Schema(description = "模块名") + private String moduleName; - /** - * 功能名 - */ - @Schema(description = "功能名") - private String functionName; + /** + * 功能名 + */ + @Schema(description = "功能名") + private String functionName; - /** - * 表单布局 1:一列 2:两列 - */ - @Schema(description = "表单布局 1:一列 2:两列") - private Integer formLayout; + /** + * 表单布局 1:一列 2:两列 + */ + @Schema(description = "表单布局 1:一列 2:两列") + private Integer formLayout; - /** - * 基类ID - */ - @Schema(description = "基类ID") - private Long baseclassId; + /** + * 所属菜单ID + */ + @Schema(description = "所属菜单ID") + private Long syncMenuId; - /** - * 创建时间 - */ - @Schema(description = "创建时间") - private LocalDateTime createTime; + /** + * 是否同步路由 + */ + @Schema + private String syncRoute; - /** - * 代码生成风格 - */ - private Long style; + /** + * 基类ID + */ + @Schema(description = "基类ID") + private Long baseclassId; - /** - * 子表名称 - */ - private String childTableName; + /** + * 创建时间 + */ + @Schema(description = "创建时间") + private LocalDateTime createTime; - /** - * 主表关联键 - */ - private String mainField; + /** + * 代码生成风格 + */ + private Long style; - /** - * 子表关联键 - */ - private String childField; + /** + * 子表名称 + */ + private String childTableName; - /** - * 字段列表 - */ - @TableField(exist = false) - private List fieldList; + /** + * 主表关联键 + */ + private String mainField; - /** - * 子表字段列表 - */ - @TableField(exist = false) - private List childFieldList; + /** + * 子表关联键 + */ + private String childField; - /** - * 代码风格(模版分组信息) - */ - @TableField(exist = false) - private List groupList; + /** + * 字段列表 + */ + @TableField(exist = false) + private List fieldList; + + /** + * 子表字段列表 + */ + @TableField(exist = false) + private List childFieldList; + + /** + * 代码风格(模版分组信息) + */ + @TableField(exist = false) + private List groupList; } diff --git a/pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/service/GeneratorService.java b/pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/service/GeneratorService.java index 990d37553..af5ca0653 100644 --- a/pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/service/GeneratorService.java +++ b/pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/service/GeneratorService.java @@ -27,39 +27,50 @@ import java.util.zip.ZipOutputStream; */ public interface GeneratorService { - /** - * 生成代码zip写出 - * @param tableId 表 - * @param zip 输出流 - */ - void downloadCode(Long tableId, ZipOutputStream zip); + /** + * 生成代码zip写出 + * + * @param tableId 表 + * @param zip 输出流 + */ + void downloadCode(Long tableId, ZipOutputStream zip); - /** - * 预览代码 - * @param tableId 表 - * @return [{模板名称:渲染结果}] - */ - List> preview(Long tableId); + /** + * 预览代码 + * + * @param tableId 表 + * @return [{模板名称:渲染结果}] + */ + List> preview(Long tableId); - /** - * 目标目录写入渲染结果 - * @param tableId 表 - */ - void generatorCode(Long tableId); + /** + * 目标目录写入渲染结果 + * + * @param tableId 表 + */ + void generatorCode(Long tableId); - /** - * 获取表单设计器需要的 JSON - * @param dsName 数据源名称 - * @param tableName 表名称 - * @return json string - */ - String vform(String dsName, String tableName); + /** + * 获取表单设计器需要的 JSON + * + * @param dsName 数据源名称 + * @param tableName 表名称 + * @return json string + */ + String vform(String dsName, String tableName); - /** - * 获取表单设计器需要的 JSON - * @param formId 数据源名称 - * @return json string - */ - String vformSfc(Long formId); + /** + * 获取表单设计器需要的 JSON + * + * @param formId 数据源名称 + * @return json string + */ + String vformSfc(Long formId); + /** + * 同步路由和菜单 + * + * @param tableId 表ID + */ + void syncRouteAndMenu(Long tableId); } diff --git a/pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/service/impl/GenTableServiceImpl.java b/pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/service/impl/GenTableServiceImpl.java index ec86008a5..23e8a1008 100644 --- a/pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/service/impl/GenTableServiceImpl.java +++ b/pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/service/impl/GenTableServiceImpl.java @@ -63,189 +63,196 @@ import java.util.Objects; @RequiredArgsConstructor public class GenTableServiceImpl extends ServiceImpl implements GenTableService { - private final PigxCodeGenDefaultProperties defaultProperties; + private final PigxCodeGenDefaultProperties defaultProperties; - private final GenTableColumnService columnService; + private final GenTableColumnService columnService; - private final GenGroupService genGroupService; + private final GenGroupService genGroupService; - /** - * 查询表ddl 语句 - * @param dsName 数据源名称 - * @param tableName 表名称 - * @return ddl 语句 - * @throws Exception - */ - @Override - public String queryTableDdl(String dsName, String tableName) throws Exception { - // 手动切换数据源 - DynamicDataSourceContextHolder.push(dsName); - Table table = ServiceProxy.metadata().table(tableName); // 获取表结构 - table.execute(false);// 不执行SQL - ServiceProxy.ddl().create(table); - return table.getDdl();// 返回创建表的DDL - } + /** + * 查询表ddl 语句 + * + * @param dsName 数据源名称 + * @param tableName 表名称 + * @return ddl 语句 + * @throws Exception + */ + @Override + public String queryTableDdl(String dsName, String tableName) throws Exception { + // 手动切换数据源 + DynamicDataSourceContextHolder.push(dsName); + Table table = ServiceProxy.metadata().table(tableName); // 获取表结构 + table.execute(false);// 不执行SQL + ServiceProxy.ddl().create(table); + return table.getDdl();// 返回创建表的DDL + } - /** - * 查询表的全部字段 - * @param dsName 数据源 - * @param tableName 表名称 - * @return column - */ - @Override - public List queryTableColumn(String dsName, String tableName) { - // 手动切换数据源 - DynamicDataSourceContextHolder.push(dsName); - return ServiceProxy.metadata().columns(tableName).values().stream().map(Column::getName).toList(); - } + /** + * 查询表的全部字段 + * + * @param dsName 数据源 + * @param tableName 表名称 + * @return column + */ + @Override + public List queryTableColumn(String dsName, String tableName) { + // 手动切换数据源 + DynamicDataSourceContextHolder.push(dsName); + return ServiceProxy.metadata().columns(tableName).values().stream().map(Column::getName).toList(); + } - /** - * 查询对应数据源的表 - * @param page 分页信息 - * @param table 查询条件 - * @return 表 - */ - @Override - public IPage queryTablePage(Page page, GenTable table) { - // 手动切换数据源 - DynamicDataSourceContextHolder.push(table.getDsName()); - List
tableList = ServiceProxy.metadata().tables().values().stream().filter(t -> { - if (StrUtil.isBlank(table.getTableName())) { - return true; - } - return StrUtil.containsIgnoreCase(t.getName(false), table.getTableName()); - }).toList(); + /** + * 查询对应数据源的表 + * + * @param page 分页信息 + * @param table 查询条件 + * @return 表 + */ + @Override + public IPage queryTablePage(Page
page, GenTable table) { + // 手动切换数据源 + DynamicDataSourceContextHolder.push(table.getDsName()); + List
tableList = ServiceProxy.metadata().tables().values().stream().filter(t -> { + if (StrUtil.isBlank(table.getTableName())) { + return true; + } + return StrUtil.containsIgnoreCase(t.getName(false), table.getTableName()); + }).toList(); - // 根据 page 进行分页 - List
records = CollUtil.page((int) page.getCurrent() - 1, (int) page.getSize(), tableList); - page.setTotal(tableList.size()); - page.setRecords(records); - return page; - } + // 根据 page 进行分页 + List
records = CollUtil.page((int) page.getCurrent() - 1, (int) page.getSize(), tableList); + page.setTotal(tableList.size()); + page.setRecords(records); + return page; + } - /** - * 查询数据源里面的全部表 - * @param dsName 数据源名称 - * @return table - */ - @Override - public List queryTableList(String dsName) { - // 手动切换数据源 - DynamicDataSourceContextHolder.push(dsName); - return ServiceProxy.metadata().tables().values().stream().map(Table::getName).toList(); - } + /** + * 查询数据源里面的全部表 + * + * @param dsName 数据源名称 + * @return table + */ + @Override + public List queryTableList(String dsName) { + // 手动切换数据源 + DynamicDataSourceContextHolder.push(dsName); + return ServiceProxy.metadata().tables().values().stream().map(Table::getName).toList(); + } - /** - * 查询表信息(列),然后插入到中间表中 - * @param dsName 数据源 - * @param tableName 表名 - * @return GenTable - */ - @Override - public GenTable queryOrBuildTable(String dsName, String tableName) { - GenTable genTable = baseMapper.selectOne( - Wrappers.lambdaQuery().eq(GenTable::getTableName, tableName).eq(GenTable::getDsName, dsName)); - // 如果 genTable 为空, 执行导入 - if (Objects.isNull(genTable)) { - genTable = this.tableImport(dsName, tableName); - } + /** + * 查询表信息(列),然后插入到中间表中 + * + * @param dsName 数据源 + * @param tableName 表名 + * @return GenTable + */ + @Override + public GenTable queryOrBuildTable(String dsName, String tableName) { + GenTable genTable = baseMapper.selectOne( + Wrappers.lambdaQuery().eq(GenTable::getTableName, tableName).eq(GenTable::getDsName, dsName)); + // 如果 genTable 为空, 执行导入 + if (Objects.isNull(genTable)) { + genTable = this.tableImport(dsName, tableName); + } - List fieldList = columnService.list(Wrappers.lambdaQuery() - .eq(GenTableColumnEntity::getDsName, dsName) - .eq(GenTableColumnEntity::getTableName, tableName) - .orderByAsc(GenTableColumnEntity::getSort)); - genTable.setFieldList(fieldList); + List fieldList = columnService.list(Wrappers.lambdaQuery() + .eq(GenTableColumnEntity::getDsName, dsName) + .eq(GenTableColumnEntity::getTableName, tableName) + .orderByAsc(GenTableColumnEntity::getSort)); + genTable.setFieldList(fieldList); - // 查询模板分组信息 - List groupEntities = genGroupService.list(); - genTable.setGroupList(groupEntities); - return genTable; - } + // 查询模板分组信息 + List groupEntities = genGroupService.list(); + genTable.setGroupList(groupEntities); + return genTable; + } - @Transactional(rollbackFor = Exception.class) - protected GenTable tableImport(String dsName, String tableName) { - // 手动切换数据源 - DynamicDataSourceContextHolder.push(dsName); + @Transactional(rollbackFor = Exception.class) + protected GenTable tableImport(String dsName, String tableName) { + // 手动切换数据源 + DynamicDataSourceContextHolder.push(dsName); - // 查询表是否存在 - GenTable table = new GenTable(); - // 从数据库获取表信息 - AnylineService service = ServiceProxy.service(); - Table tableMetadata = service.metadata().table(tableName); - Database database = service.metadata().database(); - // 获取默认表配置信息 () + // 查询表是否存在 + GenTable table = new GenTable(); + // 从数据库获取表信息 + AnylineService service = ServiceProxy.service(); + Table tableMetadata = service.metadata().table(tableName); + Database database = service.metadata().database(); + // 获取默认表配置信息 () - table.setPackageName(defaultProperties.getPackageName()); - table.setVersion(defaultProperties.getVersion()); - table.setBackendPath(defaultProperties.getBackendPath()); - table.setFrontendPath(defaultProperties.getFrontendPath()); - table.setAuthor(defaultProperties.getAuthor()); - table.setEmail(defaultProperties.getEmail()); - table.setTableName(tableName); - table.setDsName(dsName); - table.setTableComment(tableMetadata.getComment()); + table.setPackageName(defaultProperties.getPackageName()); + table.setVersion(defaultProperties.getVersion()); + table.setBackendPath(defaultProperties.getBackendPath()); + table.setFrontendPath(defaultProperties.getFrontendPath()); + table.setAuthor(defaultProperties.getAuthor()); + table.setEmail(defaultProperties.getEmail()); + table.setTableName(tableName); + table.setDsName(dsName); + table.setTableComment(tableMetadata.getComment()); - table.setDbType(database.getDatabase().title()); - table.setFormLayout(defaultProperties.getFormLayout()); - table.setGeneratorType(defaultProperties.getGeneratorType()); - table.setClassName(NamingCase.toPascalCase(tableName)); - // 模块名称默认为 admin - table.setModuleName("admin"); - table.setFunctionName(GenKit.getFunctionName(tableName)); - table.setCreateTime(LocalDateTime.now()); + table.setDbType(database.getDatabase().title()); + table.setFormLayout(defaultProperties.getFormLayout()); + table.setSyncRoute(defaultProperties.getSyncRoute()); + table.setGeneratorType(defaultProperties.getGeneratorType()); + table.setClassName(NamingCase.toPascalCase(tableName)); + // 模块名称默认为 admin + table.setModuleName(defaultProperties.getModuleName()); + table.setFunctionName(GenKit.getFunctionName(tableName)); + table.setCreateTime(LocalDateTime.now()); - // 使用默认数据源 - DynamicDataSourceContextHolder.clear(); - this.save(table); + // 使用默认数据源 + DynamicDataSourceContextHolder.clear(); + this.save(table); - // 获取原生字段数据 - List tableFieldList = getGenTableColumnEntities(dsName, tableName, tableMetadata); + // 获取原生字段数据 + List tableFieldList = getGenTableColumnEntities(dsName, tableName, tableMetadata); - // 初始化字段数据 - columnService.initFieldList(tableFieldList); - // 保存列数据 - columnService.saveOrUpdateBatch(tableFieldList); + // 初始化字段数据 + columnService.initFieldList(tableFieldList); + // 保存列数据 + columnService.saveOrUpdateBatch(tableFieldList); - table.setFieldList(tableFieldList); - return table; - } + table.setFieldList(tableFieldList); + return table; + } - /** - * 获取表字段信息 - * @param dsName 数据源信息 - * @param tableName 表名称 - * @param tableMetadata 表的元数据 - * @return list - */ - private static @NotNull List getGenTableColumnEntities(String dsName, String tableName, - Table tableMetadata) { - List tableFieldList = new ArrayList<>(); - LinkedHashMap columns = tableMetadata.getColumns(); - columns.forEach((columnName, column) -> { - GenTableColumnEntity genTableColumnEntity = new GenTableColumnEntity(); - genTableColumnEntity.setTableName(tableName); - genTableColumnEntity.setDsName(dsName); - genTableColumnEntity.setFieldName(column.getName()); - genTableColumnEntity.setFieldComment(column.getComment()); - genTableColumnEntity.setFieldType(column.getTypeName()); - genTableColumnEntity.setPrimaryPk( - column.isPrimaryKey() == 1 ? BoolFillEnum.TRUE.getValue() : BoolFillEnum.FALSE.getValue()); - genTableColumnEntity.setAutoFill(AutoFillEnum.DEFAULT.name()); - genTableColumnEntity.setFormItem(BoolFillEnum.TRUE.getValue()); - genTableColumnEntity.setGridItem(BoolFillEnum.TRUE.getValue()); + /** + * 获取表字段信息 + * + * @param dsName 数据源信息 + * @param tableName 表名称 + * @param tableMetadata 表的元数据 + * @return list + */ + private static @NotNull List getGenTableColumnEntities(String dsName, String tableName, + Table tableMetadata) { + List tableFieldList = new ArrayList<>(); + LinkedHashMap columns = tableMetadata.getColumns(); + columns.forEach((columnName, column) -> { + GenTableColumnEntity genTableColumnEntity = new GenTableColumnEntity(); + genTableColumnEntity.setTableName(tableName); + genTableColumnEntity.setDsName(dsName); + genTableColumnEntity.setFieldName(column.getName()); + genTableColumnEntity.setFieldComment(column.getComment()); + genTableColumnEntity.setFieldType(column.getTypeName()); + genTableColumnEntity.setPrimaryPk( + column.isPrimaryKey() == 1 ? BoolFillEnum.TRUE.getValue() : BoolFillEnum.FALSE.getValue()); + genTableColumnEntity.setAutoFill(AutoFillEnum.DEFAULT.name()); + genTableColumnEntity.setFormItem(BoolFillEnum.TRUE.getValue()); + genTableColumnEntity.setGridItem(BoolFillEnum.TRUE.getValue()); - // 审计字段处理 - if (EnumUtil.contains(CommonColumnFiledEnum.class, column.getName())) { - CommonColumnFiledEnum commonColumnFiledEnum = CommonColumnFiledEnum.valueOf(column.getName()); - genTableColumnEntity.setFormItem(commonColumnFiledEnum.getFormItem()); - genTableColumnEntity.setGridItem(commonColumnFiledEnum.getGridItem()); - genTableColumnEntity.setAutoFill(commonColumnFiledEnum.getAutoFill()); - genTableColumnEntity.setSort(commonColumnFiledEnum.getSort()); - } - tableFieldList.add(genTableColumnEntity); - }); - return tableFieldList; - } + // 审计字段处理 + if (EnumUtil.contains(CommonColumnFiledEnum.class, column.getName())) { + CommonColumnFiledEnum commonColumnFiledEnum = CommonColumnFiledEnum.valueOf(column.getName()); + genTableColumnEntity.setFormItem(commonColumnFiledEnum.getFormItem()); + genTableColumnEntity.setGridItem(commonColumnFiledEnum.getGridItem()); + genTableColumnEntity.setAutoFill(commonColumnFiledEnum.getAutoFill()); + genTableColumnEntity.setSort(commonColumnFiledEnum.getSort()); + } + tableFieldList.add(genTableColumnEntity); + }); + return tableFieldList; + } } diff --git a/pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/service/impl/GeneratorServiceImpl.java b/pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/service/impl/GeneratorServiceImpl.java index d00e03908..cd58d129c 100755 --- a/pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/service/impl/GeneratorServiceImpl.java +++ b/pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/service/impl/GeneratorServiceImpl.java @@ -21,21 +21,31 @@ import cn.hutool.core.collection.CollUtil; import cn.hutool.core.date.DateUtil; import cn.hutool.core.io.FileUtil; import cn.hutool.core.io.IoUtil; +import cn.hutool.core.map.MapUtil; import cn.hutool.core.text.NamingCase; import cn.hutool.core.util.BooleanUtil; import cn.hutool.core.util.StrUtil; import cn.hutool.json.JSONObject; import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.pig4cloud.pigx.admin.api.entity.SysMenu; +import com.pig4cloud.pigx.admin.api.entity.SysRouteConf; +import com.pig4cloud.pigx.admin.api.feign.RemoteMenuService; +import com.pig4cloud.pigx.admin.api.feign.RemoteRouteConfService; import com.pig4cloud.pigx.codegen.config.PigxCodeGenDefaultProperties; import com.pig4cloud.pigx.codegen.entity.GenFormConf; import com.pig4cloud.pigx.codegen.entity.GenTable; import com.pig4cloud.pigx.codegen.entity.GenTableColumnEntity; import com.pig4cloud.pigx.codegen.entity.GenTemplateEntity; import com.pig4cloud.pigx.codegen.service.*; +import com.pig4cloud.pigx.codegen.util.DataModelConstants; import com.pig4cloud.pigx.codegen.util.GeneratorStyleEnum; import com.pig4cloud.pigx.codegen.util.VelocityKit; import com.pig4cloud.pigx.codegen.util.vo.GroupVO; +import com.pig4cloud.pigx.common.core.constant.enums.MenuTypeEnum; +import com.pig4cloud.pigx.common.core.constant.enums.YesNoEnum; import com.pig4cloud.pigx.common.core.exception.CheckedException; +import com.pig4cloud.pigx.common.core.util.R; +import com.pig4cloud.pigx.common.core.util.RetOps; import lombok.RequiredArgsConstructor; import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; @@ -72,6 +82,10 @@ public class GeneratorServiceImpl implements GeneratorService { private final GenTemplateService genTemplateService; + private final RemoteMenuService menuService; + + private final RemoteRouteConfService routeService; + /** * 生成代码zip写出 * @@ -84,7 +98,7 @@ public class GeneratorServiceImpl implements GeneratorService { // 数据模型 Map dataModel = getDataModel(tableId); - Long style = (Long) dataModel.get("style"); + Long style = (Long) dataModel.get(GenTable.Fields.style); GroupVO groupVo = genGroupService.getGroupVoById(style); List templateList = groupVo.getTemplateList(); @@ -92,12 +106,15 @@ public class GeneratorServiceImpl implements GeneratorService { String frontendPath = defaultProperties.getFrontendPath(); String backendPath = defaultProperties.getBackendPath(); + // 同步数据 + this.syncRouteAndMenu(tableId); + for (GenTemplateEntity template : templateList) { String templateCode = template.getTemplateCode(); String generatorPath = template.getGeneratorPath(); - dataModel.put("frontendPath", frontendPath); - dataModel.put("backendPath", backendPath); + dataModel.put(GenTable.Fields.frontendPath, frontendPath); + dataModel.put(GenTable.Fields.backendPath, backendPath); String content = VelocityKit.renderStr(templateCode, dataModel); String path = VelocityKit.renderStr(generatorPath, dataModel); @@ -122,7 +139,7 @@ public class GeneratorServiceImpl implements GeneratorService { // 数据模型 Map dataModel = getDataModel(tableId); - Long style = (Long) dataModel.get("style"); + Long style = (Long) dataModel.get(GenTable.Fields.style); // 获取模板列表,Lambda 表达式简化代码 List templateList = genGroupService.getGroupVoById(style).getTemplateList(); @@ -130,24 +147,34 @@ public class GeneratorServiceImpl implements GeneratorService { String frontendPath = defaultProperties.getFrontendPath(); String backendPath = defaultProperties.getBackendPath(); - return templateList.stream().map(template -> { + // 如果是同步菜单的模式则不生成SQL + List> result = new ArrayList<>(); + Long syncMenuId = MapUtil.getLong(dataModel, GenTable.Fields.syncMenuId); + for (GenTemplateEntity template : templateList) { + // 跳过菜单文件生成 + if (Objects.nonNull(syncMenuId) && template.getGeneratorPath().contains("menu.sql")) { + continue; + } + String templateCode = template.getTemplateCode(); String generatorPath = template.getGeneratorPath(); // 预览模式下, 使用相对路径展示 - dataModel.put("frontendPath", frontendPath); - dataModel.put("backendPath", backendPath); + dataModel.put(GenTable.Fields.frontendPath, frontendPath); + dataModel.put(GenTable.Fields.backendPath, backendPath); String content = VelocityKit.renderStr(templateCode, dataModel); String path = VelocityKit.renderStr(generatorPath, dataModel); // 使用 map 简化代码 - return new HashMap(4) { + result.add(new HashMap<>(4) { { put("code", content); put("codePath", path); } - }; - }).collect(Collectors.toList()); + }); + } + + return result; } /** @@ -159,18 +186,24 @@ public class GeneratorServiceImpl implements GeneratorService { public void generatorCode(Long tableId) { // 数据模型 Map dataModel = getDataModel(tableId); - Long style = (Long) dataModel.get("style"); + Long style = (Long) dataModel.get(GenTable.Fields.style); // 获取模板列表,Lambda 表达式简化代码 List templateList = genGroupService.getGroupVoById(style).getTemplateList(); + Long syncMenuId = MapUtil.getLong(dataModel, GenTable.Fields.syncMenuId); + this.syncRouteAndMenu(tableId); + for (GenTemplateEntity template : templateList) { + // 跳过菜单文件生成 + if (Objects.nonNull(syncMenuId) && template.getGeneratorPath().contains("menu.sql")) { + continue; + } - templateList.forEach(template -> { String templateCode = template.getTemplateCode(); String generatorPath = template.getGeneratorPath(); String content = VelocityKit.renderStr(templateCode, dataModel); String path = VelocityKit.renderStr(generatorPath, dataModel); FileUtil.writeUtf8String(content, path); - }); + } } /** @@ -192,7 +225,7 @@ public class GeneratorServiceImpl implements GeneratorService { // 获取模板信息,Lambda 表达式简化代码 GenTemplateEntity genTemplateEntity = genTemplateService.getOneOpt(Wrappers.lambdaQuery() .likeRight(GenTemplateEntity::getTemplateName, GeneratorStyleEnum.VFORM_JSON.getDesc()) - .orderByDesc(GenTemplateEntity::getCreateTime) + .orderByDesc(GenTemplateEntity::getCreateTime), false ) .orElseThrow(() -> new CheckedException("模板不存在")); // 渲染模板并返回结果 @@ -226,7 +259,7 @@ public class GeneratorServiceImpl implements GeneratorService { // 获取模板信息 查询模板中最新的 vform.json 文件 GenTemplateEntity genTemplateEntity = genTemplateService.getOneOpt(Wrappers.lambdaQuery() .likeRight(GenTemplateEntity::getTemplateName, GeneratorStyleEnum.VFORM_VUE.getDesc()) - .orderByDesc(GenTemplateEntity::getCreateTime) + .orderByDesc(GenTemplateEntity::getCreateTime), false ) .orElseThrow(() -> new CheckedException("模板不存在")); @@ -234,6 +267,121 @@ public class GeneratorServiceImpl implements GeneratorService { return VelocityKit.renderStr(genTemplateEntity.getTemplateCode(), dataModel); } + /** + * 同步路由和菜单 + * + * @param tableId 表ID + */ + @Override + public void syncRouteAndMenu(Long tableId) { + GenTable table = tableService.getById(tableId); + syncMenu(table); + syncRoute(table); + } + + /** + * 同步菜单,同步按钮 + * + * @param table 表配置 + */ + private void syncMenu(GenTable table) { + if (Objects.isNull(table.getSyncMenuId())) { + return; + } + + String menuName = String.format("%s管理", table.getTableComment()); + SysMenu query = new SysMenu(); + query.setName(menuName); + query.setMenuType(MenuTypeEnum.LEFT_MENU.getType()); + + List existingMenus = RetOps.of(menuService.getMenuDetails(query)).getData().orElse(Collections.emptyList()); + + if (!CollUtil.isEmpty(existingMenus)) { + return; + } + + SysMenu sysMenu = createMenu(table, menuName); + R sysMenuR = menuService.saveMenu(sysMenu); + + if (sysMenuR.getData() != null) { + createButtons(table, sysMenuR.getData().getMenuId()); + } + } + + /** + * 创建菜单 + * + * @param table 表配置 + * @param menuName 菜单名称 + * @return {@link SysMenu } + */ + private SysMenu createMenu(GenTable table, String menuName) { + SysMenu sysMenu = new SysMenu(); + sysMenu.setParentId(table.getSyncMenuId()); + sysMenu.setName(menuName); + sysMenu.setMenuType(MenuTypeEnum.LEFT_MENU.getType()); + sysMenu.setPath(String.format("/%s/%s/index", table.getModuleName(), table.getFunctionName())); + return sysMenu; + } + + /** + * 创建按钮 + * + * @param table 表配置 + * @param parentId 父 ID + */ + private void createButtons(GenTable table, Long parentId) { + String[] buttonNames = {"查看", "新增", "编辑", "删除", "导入导出"}; + String[] permissions = {"view", "add", "edit", "del", "export"}; + + for (int i = 0; i < buttonNames.length; i++) { + SysMenu button = new SysMenu(); + button.setParentId(parentId); + button.setMenuType(MenuTypeEnum.BUTTON.getType()); + button.setName(buttonNames[i]); + button.setPermission(String.format("%s_%s_%s", table.getModuleName(), table.getFunctionName(), permissions[i])); + menuService.saveMenu(button); + } + } + + /** + * 同步路由 + * + * @param table 表配置 + */ + private void syncRoute(GenTable table) { + if (!YesNoEnum.YES.getCode().equals(table.getSyncRoute())) { + return; + } + + List existingRoutes = RetOps.of(routeService.getRouteDetails()).getData().orElse(Collections.emptyList()); + boolean exist = existingRoutes.stream() + .anyMatch(routeConf -> routeConf.getRouteId().equals(table.getModuleName())); + + if (exist) { + return; + } + + SysRouteConf sysRouteConf = createRoute(table); + routeService.saveSysRouteConf(sysRouteConf); + } + + /** + * 创建路由 + * + * @param table 表配置 + * @return {@link SysRouteConf } + */ + private SysRouteConf createRoute(GenTable table) { + SysRouteConf sysRouteConf = new SysRouteConf(); + sysRouteConf.setRouteId(table.getModuleName()); + sysRouteConf.setRouteName(table.getModuleName()); + sysRouteConf.setPredicates(String.format("[{\"args\": {\"_genkey_0\": \"/%s/**\"}, \"name\": \"Path\"}]", table.getModuleName())); + sysRouteConf.setFilters("[]"); + sysRouteConf.setUri(String.format("lb://%s-biz", table.getModuleName())); + return sysRouteConf; + } + /** * 通过 Lambda 表达式优化的获取数据模型方法 * @@ -256,33 +404,34 @@ public class GeneratorServiceImpl implements GeneratorService { Map dataModel = new HashMap<>(); // 填充数据模型 - dataModel.put("isSpringBoot3", isSpringBoot3()); - dataModel.put("dbType", table.getDbType()); - dataModel.put("package", table.getPackageName()); - dataModel.put("packagePath", table.getPackageName().replace(".", "/")); - dataModel.put("version", table.getVersion()); - dataModel.put("moduleName", table.getModuleName()); - dataModel.put("ModuleName", StrUtil.upperFirst(table.getModuleName())); - dataModel.put("functionName", table.getFunctionName()); - dataModel.put("FunctionName", StrUtil.upperFirst(table.getFunctionName())); - dataModel.put("formLayout", table.getFormLayout()); - dataModel.put("style", table.getStyle()); - dataModel.put("author", table.getAuthor()); - dataModel.put("datetime", DateUtil.now()); - dataModel.put("date", DateUtil.today()); + dataModel.put(DataModelConstants.IS_SPRING_BOOT_3, isSpringBoot3()); + dataModel.put(DataModelConstants.SYNC_MENU_ID, Objects.nonNull(table.getSyncMenuId())); + dataModel.put(DataModelConstants.DB_TYPE, table.getDbType()); + dataModel.put(DataModelConstants.PACKAGE, table.getPackageName()); + dataModel.put(DataModelConstants.PACKAGE_PATH, table.getPackageName().replace(".", "/")); + dataModel.put(DataModelConstants.VERSION, table.getVersion()); + dataModel.put(DataModelConstants.MODULE_NAME, table.getModuleName()); + dataModel.put(DataModelConstants.MODULE_NAME_UPPER_FIRST, StrUtil.upperFirst(table.getModuleName())); + dataModel.put(DataModelConstants.FUNCTION_NAME, table.getFunctionName()); + dataModel.put(DataModelConstants.FUNCTION_NAME_UPPER_FIRST, StrUtil.upperFirst(table.getFunctionName())); + dataModel.put(DataModelConstants.FORM_LAYOUT, table.getFormLayout()); + dataModel.put(DataModelConstants.STYLE, table.getStyle()); + dataModel.put(DataModelConstants.AUTHOR, table.getAuthor()); + dataModel.put(DataModelConstants.DATETIME, DateUtil.now()); + dataModel.put(DataModelConstants.DATE, DateUtil.today()); setFieldTypeList(dataModel, table); // 获取导入的包列表 Set importList = fieldTypeService.getPackageByTableId(table.getDsName(), table.getTableName()); - dataModel.put("importList", importList); - dataModel.put("tableName", table.getTableName()); - dataModel.put("tableComment", table.getTableComment()); - dataModel.put("className", StrUtil.lowerFirst(table.getClassName())); - dataModel.put("ClassName", table.getClassName()); - dataModel.put("fieldList", table.getFieldList()); + dataModel.put(DataModelConstants.IMPORT_LIST, importList); + dataModel.put(DataModelConstants.TABLE_NAME, table.getTableName()); + dataModel.put(DataModelConstants.TABLE_COMMENT, table.getTableComment()); + dataModel.put(DataModelConstants.CLASS_NAME, StrUtil.lowerFirst(table.getClassName())); + dataModel.put(DataModelConstants.CLASS_NAME_UPPER_FIRST, table.getClassName()); + dataModel.put(DataModelConstants.FIELD_LIST, table.getFieldList()); - dataModel.put("backendPath", table.getBackendPath()); - dataModel.put("frontendPath", table.getFrontendPath()); + dataModel.put(DataModelConstants.BACKEND_PATH, table.getBackendPath()); + dataModel.put(DataModelConstants.FRONTEND_PATH, table.getFrontendPath()); // 设置子表 String childTableName = table.getChildTableName(); @@ -291,20 +440,20 @@ public class GeneratorServiceImpl implements GeneratorService { .eq(GenTableColumnEntity::getDsName, table.getDsName()) .eq(GenTableColumnEntity::getTableName, table.getChildTableName()) .list(); - dataModel.put("childFieldList", childFieldList); - dataModel.put("childTableName", childTableName); - dataModel.put("mainField", NamingCase.toCamelCase(table.getMainField())); - dataModel.put("childField", NamingCase.toCamelCase(table.getChildField())); - dataModel.put("ChildClassName", NamingCase.toPascalCase(childTableName)); - dataModel.put("childClassName", StrUtil.lowerFirst(NamingCase.toPascalCase(childTableName))); + dataModel.put(DataModelConstants.CHILD_FIELD_LIST, childFieldList); + dataModel.put(DataModelConstants.CHILD_TABLE_NAME, childTableName); + dataModel.put(DataModelConstants.MAIN_FIELD, NamingCase.toCamelCase(table.getMainField())); + dataModel.put(DataModelConstants.CHILD_FIELD, NamingCase.toCamelCase(table.getChildField())); + dataModel.put(DataModelConstants.CHILD_CLASS_NAME_UPPER_FIRST, NamingCase.toPascalCase(childTableName)); + dataModel.put(DataModelConstants.CHILD_CLASS_NAME, StrUtil.lowerFirst(NamingCase.toPascalCase(childTableName))); // 设置是否是多租户模式 (判断字段列表中是否包含 tenant_id 字段) childFieldList.stream().filter(genTableColumnEntity -> genTableColumnEntity.getFieldName().equals("tenant_id")) - .findFirst().ifPresent(columnEntity -> dataModel.put("isChildTenant", true)); + .findFirst().ifPresent(columnEntity -> dataModel.put(DataModelConstants.IS_CHILD_TENANT, true)); } // 设置是否是多租户模式 (判断字段列表中是否包含 tenant_id 字段) table.getFieldList().stream().filter(genTableColumnEntity -> genTableColumnEntity.getFieldName().equals("tenant_id")) - .findFirst().ifPresent(columnEntity -> dataModel.put("isTenant", true)); + .findFirst().ifPresent(columnEntity -> dataModel.put(DataModelConstants.IS_TENANT, true)); return dataModel; } diff --git a/pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/util/DataModelConstants.java b/pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/util/DataModelConstants.java new file mode 100644 index 000000000..60d483453 --- /dev/null +++ b/pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/util/DataModelConstants.java @@ -0,0 +1,58 @@ +package com.pig4cloud.pigx.codegen.util; + +/** + * 代码生成模板中能使用的变量名称 + * + * @author lengleng + * @date 2024/7/16 + */ +public class DataModelConstants { + // 基本信息 + public static final String IS_SPRING_BOOT_3 = "isSpringBoot3"; + public static final String SYNC_MENU_ID = "syncMenuId"; + public static final String DB_TYPE = "dbType"; + public static final String PACKAGE = "package"; + public static final String PACKAGE_PATH = "packagePath"; + public static final String VERSION = "version"; + + // 模块和功能名称 + public static final String MODULE_NAME = "moduleName"; + public static final String MODULE_NAME_UPPER_FIRST = "ModuleName"; + public static final String FUNCTION_NAME = "functionName"; + public static final String FUNCTION_NAME_UPPER_FIRST = "FunctionName"; + + // 布局和样式 + public static final String FORM_LAYOUT = "formLayout"; + public static final String STYLE = "style"; + + // 作者和时间 + public static final String AUTHOR = "author"; + public static final String DATETIME = "datetime"; + public static final String DATE = "date"; + + // 导入列表 + public static final String IMPORT_LIST = "importList"; + + // 表信息 + public static final String TABLE_NAME = "tableName"; + public static final String TABLE_COMMENT = "tableComment"; + public static final String CLASS_NAME = "className"; + public static final String CLASS_NAME_UPPER_FIRST = "ClassName"; + public static final String FIELD_LIST = "fieldList"; + + // 路径 + public static final String BACKEND_PATH = "backendPath"; + public static final String FRONTEND_PATH = "frontendPath"; + + // 子表信息 + public static final String CHILD_FIELD_LIST = "childFieldList"; + public static final String CHILD_TABLE_NAME = "childTableName"; + public static final String MAIN_FIELD = "mainField"; + public static final String CHILD_FIELD = "childField"; + public static final String CHILD_CLASS_NAME_UPPER_FIRST = "ChildClassName"; + public static final String CHILD_CLASS_NAME = "childClassName"; + public static final String IS_CHILD_TENANT = "isChildTenant"; + + // 租户信息 + public static final String IS_TENANT = "isTenant"; +}