feat(代码生成): 支持直接同步菜单、同步网关路由
(cherry picked from commit d61b38419bc70139e40ea6e5e5fe494c66eaaee2)
This commit is contained in:
1 parent
04af734d83
commit
c80178148a
16 files changed
+832
-428
No files matched your search
@@ -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 '子表关联键',
|
||||
|
||||
@@ -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 '子表关联键',
|
||||
|
||||
+61
@@ -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<List<SysMenu>> getMenuDetails(@SpringQueryMap SysMenu sysMenu);
|
||||
|
||||
|
||||
/**
|
||||
* 保存菜单
|
||||
*
|
||||
* @param sysMenu SYS菜单
|
||||
* @return {@link R }<{@link Boolean }>
|
||||
*/
|
||||
@PostMapping("/menu")
|
||||
R<SysMenu> saveMenu(@RequestBody SysMenu sysMenu);
|
||||
}
|
||||
+59
@@ -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<List<SysRouteConf>> getRouteDetails();
|
||||
|
||||
|
||||
/**
|
||||
* 保存 sys route conf
|
||||
*
|
||||
* @param SysRouteConf sys 路由配置
|
||||
* @return {@link R }<{@link Boolean }>
|
||||
*/
|
||||
@PostMapping("/route/save")
|
||||
R<SysRouteConf> saveSysRouteConf(@RequestBody SysRouteConf SysRouteConf);
|
||||
}
|
||||
+2
@@ -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
|
||||
+6
@@ -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));
|
||||
}
|
||||
}
|
||||
+7
@@ -37,4 +37,11 @@ public interface SysRouteConfService extends IService<SysRouteConf> {
|
||||
*/
|
||||
Mono<Void> addOrUpdateRoute(JSONObject route);
|
||||
|
||||
/**
|
||||
* 保存路由
|
||||
*
|
||||
* @param routeConf 路由配置
|
||||
* @return {@link SysRouteConf }
|
||||
*/
|
||||
SysRouteConf saveRoute(SysRouteConf routeConf);
|
||||
}
|
||||
+80
-67
@@ -51,83 +51,96 @@ import java.util.Map;
|
||||
@AllArgsConstructor
|
||||
@Service("sysRouteConfService")
|
||||
public class SysRouteConfServiceImpl extends ServiceImpl<SysRouteConfMapper, SysRouteConf>
|
||||
implements SysRouteConfService {
|
||||
implements SysRouteConfService {
|
||||
|
||||
private final ApplicationEventPublisher applicationEventPublisher;
|
||||
private final ApplicationEventPublisher applicationEventPublisher;
|
||||
|
||||
/**
|
||||
* 更新路由信息
|
||||
* @param route 路由信息
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Mono<Void> addOrUpdateRoute(JSONObject route) {
|
||||
try {
|
||||
log.info("更新路由 ->{}", route);
|
||||
RouteDefinitionVo vo = new RouteDefinitionVo();
|
||||
/**
|
||||
* 更新路由信息
|
||||
*
|
||||
* @param route 路由信息
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Mono<Void> 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<PredicateDefinition> predicateDefinitionList = predicates.toList(PredicateDefinition.class);
|
||||
vo.setPredicates(predicateDefinitionList);
|
||||
}
|
||||
JSONArray predicates = route.getJSONArray("predicates");
|
||||
if (predicates != null) {
|
||||
List<PredicateDefinition> predicateDefinitionList = predicates.toList(PredicateDefinition.class);
|
||||
vo.setPredicates(predicateDefinitionList);
|
||||
}
|
||||
|
||||
JSONArray filters = route.getJSONArray("filters");
|
||||
if (filters != null) {
|
||||
List<FilterDefinition> filterDefinitionList = filters.toList(FilterDefinition.class);
|
||||
vo.setFilters(filterDefinitionList);
|
||||
}
|
||||
JSONArray filters = route.getJSONArray("filters");
|
||||
if (filters != null) {
|
||||
List<FilterDefinition> 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<String, Object> metadataMap = route.getBean("metadata", Map.class);
|
||||
if (metadataMap != null) {
|
||||
vo.setMetadata(metadataMap);
|
||||
}
|
||||
Map<String, Object> metadataMap = route.getBean("metadata", Map.class);
|
||||
if (metadataMap != null) {
|
||||
vo.setMetadata(metadataMap);
|
||||
}
|
||||
|
||||
// 逻辑删除 ,不直接更新避免危险!
|
||||
this.remove(Wrappers.<SysRouteConf>lambdaQuery().eq(SysRouteConf::getRouteId, id));
|
||||
// 逻辑删除 ,不直接更新避免危险!
|
||||
this.remove(Wrappers.<SysRouteConf>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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -113,6 +113,11 @@
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-common-core</artifactId>
|
||||
</dependency>
|
||||
<!-- 幂等插件使用 -->
|
||||
<dependency>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-common-idempotent</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-configuration</groupId>
|
||||
<artifactId>commons-configuration</artifactId>
|
||||
|
||||
+5
@@ -73,4 +73,9 @@ public class PigxCodeGenDefaultProperties {
|
||||
*/
|
||||
private String generatorType = "0";
|
||||
|
||||
/**
|
||||
* 是否同步路由
|
||||
*/
|
||||
private String syncRoute = "1";
|
||||
|
||||
}
|
||||
+3
@@ -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<String> code(String tableIds) throws Exception {
|
||||
// 生成代码
|
||||
for (String tableId : tableIds.split(StrUtil.COMMA)) {
|
||||
|
||||
+137
-123
@@ -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<GenTable> {
|
||||
|
||||
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<GenTableColumnEntity> fieldList;
|
||||
/**
|
||||
* 主表关联键
|
||||
*/
|
||||
private String mainField;
|
||||
|
||||
/**
|
||||
* 子表字段列表
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
private List<GenTableColumnEntity> childFieldList;
|
||||
/**
|
||||
* 子表关联键
|
||||
*/
|
||||
private String childField;
|
||||
|
||||
/**
|
||||
* 代码风格(模版分组信息)
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
private List<GenGroupEntity> groupList;
|
||||
/**
|
||||
* 字段列表
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
private List<GenTableColumnEntity> fieldList;
|
||||
|
||||
/**
|
||||
* 子表字段列表
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
private List<GenTableColumnEntity> childFieldList;
|
||||
|
||||
/**
|
||||
* 代码风格(模版分组信息)
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
private List<GenGroupEntity> groupList;
|
||||
|
||||
}
|
||||
+41
-30
@@ -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<Map<String, String>> preview(Long tableId);
|
||||
/**
|
||||
* 预览代码
|
||||
*
|
||||
* @param tableId 表
|
||||
* @return [{模板名称:渲染结果}]
|
||||
*/
|
||||
List<Map<String, String>> 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);
|
||||
}
|
||||
+170
-163
@@ -63,189 +63,196 @@ import java.util.Objects;
|
||||
@RequiredArgsConstructor
|
||||
public class GenTableServiceImpl extends ServiceImpl<GenTableMapper, GenTable> 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<String> 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<String> 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<Table> page, GenTable table) {
|
||||
// 手动切换数据源
|
||||
DynamicDataSourceContextHolder.push(table.getDsName());
|
||||
List<Table> 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<Table> page, GenTable table) {
|
||||
// 手动切换数据源
|
||||
DynamicDataSourceContextHolder.push(table.getDsName());
|
||||
List<Table> 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<Table> records = CollUtil.page((int) page.getCurrent() - 1, (int) page.getSize(), tableList);
|
||||
page.setTotal(tableList.size());
|
||||
page.setRecords(records);
|
||||
return page;
|
||||
}
|
||||
// 根据 page 进行分页
|
||||
List<Table> 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<String> queryTableList(String dsName) {
|
||||
// 手动切换数据源
|
||||
DynamicDataSourceContextHolder.push(dsName);
|
||||
return ServiceProxy.metadata().tables().values().stream().map(Table::getName).toList();
|
||||
}
|
||||
/**
|
||||
* 查询数据源里面的全部表
|
||||
*
|
||||
* @param dsName 数据源名称
|
||||
* @return table
|
||||
*/
|
||||
@Override
|
||||
public List<String> 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.<GenTable>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.<GenTable>lambdaQuery().eq(GenTable::getTableName, tableName).eq(GenTable::getDsName, dsName));
|
||||
// 如果 genTable 为空, 执行导入
|
||||
if (Objects.isNull(genTable)) {
|
||||
genTable = this.tableImport(dsName, tableName);
|
||||
}
|
||||
|
||||
List<GenTableColumnEntity> fieldList = columnService.list(Wrappers.<GenTableColumnEntity>lambdaQuery()
|
||||
.eq(GenTableColumnEntity::getDsName, dsName)
|
||||
.eq(GenTableColumnEntity::getTableName, tableName)
|
||||
.orderByAsc(GenTableColumnEntity::getSort));
|
||||
genTable.setFieldList(fieldList);
|
||||
List<GenTableColumnEntity> fieldList = columnService.list(Wrappers.<GenTableColumnEntity>lambdaQuery()
|
||||
.eq(GenTableColumnEntity::getDsName, dsName)
|
||||
.eq(GenTableColumnEntity::getTableName, tableName)
|
||||
.orderByAsc(GenTableColumnEntity::getSort));
|
||||
genTable.setFieldList(fieldList);
|
||||
|
||||
// 查询模板分组信息
|
||||
List<GenGroupEntity> groupEntities = genGroupService.list();
|
||||
genTable.setGroupList(groupEntities);
|
||||
return genTable;
|
||||
}
|
||||
// 查询模板分组信息
|
||||
List<GenGroupEntity> 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<GenTableColumnEntity> tableFieldList = getGenTableColumnEntities(dsName, tableName, tableMetadata);
|
||||
// 获取原生字段数据
|
||||
List<GenTableColumnEntity> 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<GenTableColumnEntity> getGenTableColumnEntities(String dsName, String tableName,
|
||||
Table tableMetadata) {
|
||||
List<GenTableColumnEntity> tableFieldList = new ArrayList<>();
|
||||
LinkedHashMap<String, Column> 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<GenTableColumnEntity> getGenTableColumnEntities(String dsName, String tableName,
|
||||
Table tableMetadata) {
|
||||
List<GenTableColumnEntity> tableFieldList = new ArrayList<>();
|
||||
LinkedHashMap<String, Column> 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;
|
||||
}
|
||||
|
||||
}
|
||||
+194
-45
@@ -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<String, Object> dataModel = getDataModel(tableId);
|
||||
|
||||
Long style = (Long) dataModel.get("style");
|
||||
Long style = (Long) dataModel.get(GenTable.Fields.style);
|
||||
|
||||
GroupVO groupVo = genGroupService.getGroupVoById(style);
|
||||
List<GenTemplateEntity> 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<String, Object> dataModel = getDataModel(tableId);
|
||||
|
||||
Long style = (Long) dataModel.get("style");
|
||||
Long style = (Long) dataModel.get(GenTable.Fields.style);
|
||||
|
||||
// 获取模板列表,Lambda 表达式简化代码
|
||||
List<GenTemplateEntity> 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<Map<String, String>> 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<String, String>(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<String, Object> dataModel = getDataModel(tableId);
|
||||
Long style = (Long) dataModel.get("style");
|
||||
Long style = (Long) dataModel.get(GenTable.Fields.style);
|
||||
|
||||
// 获取模板列表,Lambda 表达式简化代码
|
||||
List<GenTemplateEntity> 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.<GenTemplateEntity>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.<GenTemplateEntity>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<SysMenu> existingMenus = RetOps.of(menuService.getMenuDetails(query)).getData().orElse(Collections.emptyList());
|
||||
|
||||
if (!CollUtil.isEmpty(existingMenus)) {
|
||||
return;
|
||||
}
|
||||
|
||||
SysMenu sysMenu = createMenu(table, menuName);
|
||||
R<SysMenu> 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<SysRouteConf> 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<String, Object> 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<String> 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;
|
||||
}
|
||||
|
||||
+58
@@ -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";
|
||||
}
|
||||
Reference in new issue
Block a user