feat(代码生成): 支持直接同步菜单、同步网关路由

(cherry picked from commit d61b38419bc70139e40ea6e5e5fe494c66eaaee2)
This commit is contained in:
冷冷 committed 2024-08-16 15:11:28 +08:00
1 parent 04af734d83
commit c80178148a
16 files changed
+832 -428

No files matched your search

+2
View File
@@ -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 '子表关联键',
+2
View File
@@ -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 '子表关联键',
@@ -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);
}
@@ -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);
}
@@ -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
@@ -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));
}
}
@@ -37,4 +37,11 @@ public interface SysRouteConfService extends IService<SysRouteConf> {
*/
Mono<Void> addOrUpdateRoute(JSONObject route);
/**
* 保存路由
*
* @param routeConf 路由配置
* @return {@link SysRouteConf }
*/
SysRouteConf saveRoute(SysRouteConf routeConf);
}
@@ -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;
}
}
+5
View File
@@ -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>
@@ -73,4 +73,9 @@ public class PigxCodeGenDefaultProperties {
*/
private String generatorType = "0";
/**
* 是否同步路由
*/
private String syncRoute = "1";
}
@@ -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)) {
@@ -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;
}
@@ -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);
}
@@ -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;
}
}
@@ -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;
}
@@ -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";
}