Commit 0be7138eefe3f3922765f8e5b3aef04eb7f4c09b

Authored by YunaiV
1 parent 58f83a2b

实现数据库字段的解析

ruoyi-common/src/main/java/com/ruoyi/common/constant/GenConstants.java
... ... @@ -33,81 +33,8 @@ public class GenConstants {
33 33 public static final String PARENT_MENU_NAME = "parentMenuName";
34 34  
35 35 /**
36   - * 数据库字符串类型
37   - */
38   - public static final String[] COLUMNTYPE_STR = {"char", "varchar", "nvarchar", "varchar2"};
39   -
40   - /**
41   - * 数据库文本类型
42   - */
43   - public static final String[] COLUMNTYPE_TEXT = {"tinytext", "text", "mediumtext", "longtext"};
44   -
45   - /**
46   - * 数据库时间类型
47   - */
48   - public static final String[] COLUMNTYPE_TIME = {"datetime", "time", "date", "timestamp"};
49   -
50   - /**
51   - * 数据库数字类型
52   - */
53   - public static final String[] COLUMNTYPE_NUMBER = {"tinyint", "smallint", "mediumint", "int", "number", "integer",
54   - "bit", "bigint", "float", "double", "decimal"};
55   -
56   - /**
57   - * 页面不需要编辑字段
58   - */
59   - public static final String[] COLUMNNAME_NOT_EDIT = {"id", "create_by", "create_time", "del_flag"};
60   -
61   - /**
62   - * 页面不需要显示的列表字段
63   - */
64   - public static final String[] COLUMNNAME_NOT_LIST = {"id", "create_by", "create_time", "del_flag", "update_by",
65   - "update_time"};
66   -
67   - /**
68   - * 页面不需要查询字段
69   - */
70   - public static final String[] COLUMNNAME_NOT_QUERY = {"id", "create_by", "create_time", "del_flag", "update_by",
71   - "update_time", "remark"};
72   -
73   - /**
74   - * Entity基类字段
75   - */
76   - public static final String[] BASE_ENTITY = {"createBy", "createTime", "updateBy", "updateTime", "remark"};
77   -
78   - /**
79 36 * Tree基类字段
80 37 */
81 38 public static final String[] TREE_ENTITY = {"parentName", "parentId", "orderNum", "ancestors", "children"};
82 39  
83   - /**
84   - * 字符串类型
85   - */
86   - public static final String TYPE_STRING = "String";
87   -
88   - /**
89   - * 整型
90   - */
91   - public static final String TYPE_INTEGER = "Integer";
92   -
93   - /**
94   - * 长整型
95   - */
96   - public static final String TYPE_LONG = "Long";
97   -
98   - /**
99   - * 浮点型
100   - */
101   - public static final String TYPE_DOUBLE = "Double";
102   -
103   - /**
104   - * 高精度计算类型
105   - */
106   - public static final String TYPE_BIGDECIMAL = "BigDecimal";
107   -
108   - /**
109   - * 时间类型
110   - */
111   - public static final String TYPE_DATE = "Date";
112   -
113 40 }
... ...
ruoyi-generator/src/main/java/com/ruoyi/generator/util/GenUtils.java deleted
1   -package com.ruoyi.generator.util;
2   -
3   -import java.util.Arrays;
4   -
5   -import org.apache.commons.lang3.RegExUtils;
6   -import com.ruoyi.common.constant.GenConstants;
7   -import com.ruoyi.common.utils.StringUtils;
8   -import com.ruoyi.generator.config.GenConfig;
9   -import com.ruoyi.generator.domain.GenTable;
10   -import com.ruoyi.generator.domain.GenTableColumn;
11   -
12   -/**
13   - * 代码生成器 工具类
14   - *
15   - * @author ruoyi
16   - */
17   -public class GenUtils {
18   - /**
19   - * 初始化表信息
20   - */
21   - public static void initTable(GenTable genTable, String operName) {
22   - genTable.setClassName(convertClassName(genTable.getTableName()));
23   - genTable.setPackageName(GenConfig.getPackageName());
24   - genTable.setModuleName(getModuleName(GenConfig.getPackageName()));
25   - genTable.setBusinessName(getBusinessName(genTable.getTableName()));
26   - genTable.setFunctionName(replaceText(genTable.getTableComment()));
27   - genTable.setFunctionAuthor(GenConfig.getAuthor());
28   - genTable.setCreateBy(operName);
29   - }
30   -
31   - /**
32   - * 初始化列属性字段
33   - */
34   - public static void initColumnField(GenTableColumn column, GenTable table) {
35   - String dataType = getDbType(column.getColumnType());
36   - String columnName = column.getColumnName();
37   - column.setTableId(table.getTableId());
38   - column.setCreateBy(table.getCreateBy());
39   - // 设置java字段名
40   - column.setJavaField(StringUtils.toCamelCase(columnName));
41   - // 设置默认类型
42   - column.setJavaType(GenConstants.TYPE_STRING);
43   -
44   - if (arraysContains(GenConstants.COLUMNTYPE_STR, dataType) || arraysContains(GenConstants.COLUMNTYPE_TEXT, dataType)) {
45   - // 字符串长度超过500设置为文本域
46   - Integer columnLength = getColumnLength(column.getColumnType());
47   - String htmlType = columnLength >= 500 || arraysContains(GenConstants.COLUMNTYPE_TEXT, dataType) ? GenConstants.HTML_TEXTAREA : GenConstants.HTML_INPUT;
48   - column.setHtmlType(htmlType);
49   - } else if (arraysContains(GenConstants.COLUMNTYPE_TIME, dataType)) {
50   - column.setJavaType(GenConstants.TYPE_DATE);
51   - column.setHtmlType(GenConstants.HTML_DATETIME);
52   - } else if (arraysContains(GenConstants.COLUMNTYPE_NUMBER, dataType)) {
53   - column.setHtmlType(GenConstants.HTML_INPUT);
54   -
55   - // 如果是浮点型 统一用BigDecimal
56   - String[] str = StringUtils.split(StringUtils.substringBetween(column.getColumnType(), "(", ")"), ",");
57   - if (str != null && str.length == 2 && Integer.parseInt(str[1]) > 0) {
58   - column.setJavaType(GenConstants.TYPE_BIGDECIMAL);
59   - }
60   - // 如果是整形
61   - else if (str != null && str.length == 1 && Integer.parseInt(str[0]) <= 10) {
62   - column.setJavaType(GenConstants.TYPE_INTEGER);
63   - }
64   - // 长整形
65   - else {
66   - column.setJavaType(GenConstants.TYPE_LONG);
67   - }
68   - }
69   -
70   - // 插入字段(默认所有字段都需要插入)
71   - column.setIsInsert(GenConstants.REQUIRE);
72   -
73   - // 编辑字段
74   - if (!arraysContains(GenConstants.COLUMNNAME_NOT_EDIT, columnName) && !column.isPk()) {
75   - column.setIsEdit(GenConstants.REQUIRE);
76   - }
77   - // 列表字段
78   - if (!arraysContains(GenConstants.COLUMNNAME_NOT_LIST, columnName) && !column.isPk()) {
79   - column.setIsList(GenConstants.REQUIRE);
80   - }
81   - // 查询字段
82   - if (!arraysContains(GenConstants.COLUMNNAME_NOT_QUERY, columnName) && !column.isPk()) {
83   - column.setIsQuery(GenConstants.REQUIRE);
84   - }
85   -
86   - // 查询字段类型
87   - if (StringUtils.endsWithIgnoreCase(columnName, "name")) {
88   - column.setQueryType(GenConstants.QUERY_LIKE);
89   - }
90   - // 状态字段设置单选框
91   - if (StringUtils.endsWithIgnoreCase(columnName, "status")) {
92   - column.setHtmlType(GenConstants.HTML_RADIO);
93   - }
94   - // 类型&性别字段设置下拉框
95   - else if (StringUtils.endsWithIgnoreCase(columnName, "type")
96   - || StringUtils.endsWithIgnoreCase(columnName, "sex")) {
97   - column.setHtmlType(GenConstants.HTML_SELECT);
98   - }
99   - // 文件字段设置上传控件
100   - else if (StringUtils.endsWithIgnoreCase(columnName, "image")) {
101   - column.setHtmlType(GenConstants.HTML_UPLOAD_IMAGE);
102   - }
103   - // 内容字段设置富文本控件
104   - else if (StringUtils.endsWithIgnoreCase(columnName, "content")) {
105   - column.setHtmlType(GenConstants.HTML_EDITOR);
106   - }
107   - }
108   -
109   - /**
110   - * 校验数组是否包含指定值
111   - *
112   - * @param arr 数组
113   - * @param targetValue 值
114   - * @return 是否包含
115   - */
116   - public static boolean arraysContains(String[] arr, String targetValue) {
117   - return Arrays.asList(arr).contains(targetValue);
118   - }
119   -
120   - /**
121   - * 获取模块名
122   - *
123   - * @param packageName 包名
124   - * @return 模块名
125   - */
126   - public static String getModuleName(String packageName) {
127   - int lastIndex = packageName.lastIndexOf(".");
128   - int nameLength = packageName.length();
129   - String moduleName = StringUtils.substring(packageName, lastIndex + 1, nameLength);
130   - return moduleName;
131   - }
132   -
133   - /**
134   - * 获取业务名
135   - *
136   - * @param tableName 表名
137   - * @return 业务名
138   - */
139   - public static String getBusinessName(String tableName) {
140   - int lastIndex = tableName.lastIndexOf("_");
141   - int nameLength = tableName.length();
142   - String businessName = StringUtils.substring(tableName, lastIndex + 1, nameLength);
143   - return businessName;
144   - }
145   -
146   - /**
147   - * 表名转换成Java类名
148   - *
149   - * @param tableName 表名称
150   - * @return 类名
151   - */
152   - public static String convertClassName(String tableName) {
153   - boolean autoRemovePre = GenConfig.getAutoRemovePre();
154   - String tablePrefix = GenConfig.getTablePrefix();
155   - if (autoRemovePre && StringUtils.isNotEmpty(tablePrefix)) {
156   - String[] searchList = StringUtils.split(tablePrefix, ",");
157   - tableName = replaceFirst(tableName, searchList);
158   - }
159   - return StringUtils.convertToCamelCase(tableName);
160   - }
161   -
162   - /**
163   - * 批量替换前缀
164   - *
165   - * @param replacementm 替换值
166   - * @param searchList 替换列表
167   - * @return
168   - */
169   - public static String replaceFirst(String replacementm, String[] searchList) {
170   - String text = replacementm;
171   - for (String searchString : searchList) {
172   - if (replacementm.startsWith(searchString)) {
173   - text = replacementm.replaceFirst(searchString, "");
174   - break;
175   - }
176   - }
177   - return text;
178   - }
179   -
180   - /**
181   - * 关键字替换
182   - *
183   - * @param text 需要被替换的名字
184   - * @return 替换后的名字
185   - */
186   - public static String replaceText(String text) {
187   - return RegExUtils.replaceAll(text, "(?:表|若依)", "");
188   - }
189   -
190   - /**
191   - * 获取数据库类型字段
192   - *
193   - * @param columnType 列类型
194   - * @return 截取后的列类型
195   - */
196   - public static String getDbType(String columnType) {
197   - if (StringUtils.indexOf(columnType, "(") > 0) {
198   - return StringUtils.substringBefore(columnType, "(");
199   - } else {
200   - return columnType;
201   - }
202   - }
203   -
204   - /**
205   - * 获取字段长度
206   - *
207   - * @param columnType 列类型
208   - * @return 截取后的列类型
209   - */
210   - public static Integer getColumnLength(String columnType) {
211   - if (StringUtils.indexOf(columnType, "(") > 0) {
212   - String length = StringUtils.substringBetween(columnType, "(", ")");
213   - return Integer.valueOf(length);
214   - } else {
215   - return 0;
216   - }
217   - }
218   -}
src/main/java/cn/iocoder/dashboard/modules/tool/controller/codegen/ToolCodeGenController.java
... ... @@ -3,19 +3,31 @@ package cn.iocoder.dashboard.modules.tool.controller.codegen;
3 3 import cn.iocoder.dashboard.common.pojo.CommonResult;
4 4 import cn.iocoder.dashboard.common.pojo.PageResult;
5 5 import cn.iocoder.dashboard.modules.tool.controller.codegen.vo.ToolCodeGenTablePageItemRespVO;
6   -import org.springframework.web.bind.annotation.GetMapping;
7   -import org.springframework.web.bind.annotation.RequestMapping;
8   -import org.springframework.web.bind.annotation.RestController;
  6 +import cn.iocoder.dashboard.modules.tool.service.codegen.ToolCodegenService;
  7 +import io.swagger.annotations.ApiOperation;
  8 +import org.springframework.web.bind.annotation.*;
  9 +
  10 +import javax.annotation.Resource;
9 11  
10 12 import static cn.iocoder.dashboard.common.pojo.CommonResult.success;
11 13  
12 14 @RestController
13   -@RequestMapping("/tool/code-gen")
  15 +@RequestMapping("/tool/codegen")
14 16 public class ToolCodeGenController {
15 17  
  18 + @Resource
  19 + private ToolCodegenService codegenService;
  20 +
16 21 @GetMapping("/table/page")
17 22 public CommonResult<PageResult<ToolCodeGenTablePageItemRespVO>> getCodeGenTablePage() {
18 23 return success(null);
19 24 }
20 25  
  26 + @ApiOperation("基于数据库的表结构,创建代码生成器的表定义")
  27 + @PostMapping("/table/create")
  28 + // TODO 权限
  29 + public CommonResult<Long> createCodeGenTable(@RequestParam("tableName") String tableName) {
  30 + return success(codegenService.createCodegenTable(tableName));
  31 + }
  32 +
21 33 }
... ...
src/main/java/cn/iocoder/dashboard/modules/tool/convert/codegen/CodegenConvert.java 0 → 100644
  1 +package cn.iocoder.dashboard.modules.tool.convert.codegen;
  2 +
  3 +import cn.iocoder.dashboard.modules.tool.dal.mysql.dataobject.codegen.ToolCodegenColumnDO;
  4 +import cn.iocoder.dashboard.modules.tool.dal.mysql.dataobject.codegen.ToolCodegenTableDO;
  5 +import cn.iocoder.dashboard.modules.tool.dal.mysql.dataobject.codegen.ToolInformationSchemaColumnDO;
  6 +import cn.iocoder.dashboard.modules.tool.dal.mysql.dataobject.codegen.ToolInformationSchemaTableDO;
  7 +import org.mapstruct.Mapper;
  8 +import org.mapstruct.factory.Mappers;
  9 +
  10 +import java.util.List;
  11 +
  12 +@Mapper
  13 +public interface CodegenConvert {
  14 +
  15 + CodegenConvert INSTANCE = Mappers.getMapper(CodegenConvert.class);
  16 +
  17 + ToolCodegenTableDO convert(ToolInformationSchemaTableDO bean);
  18 +
  19 + List<ToolCodegenColumnDO> convertList(List<ToolInformationSchemaColumnDO> list);
  20 +
  21 +}
... ...
src/main/java/cn/iocoder/dashboard/modules/tool/convert/package-info.java 0 → 100644
  1 +package cn.iocoder.dashboard.modules.tool.convert;
... ...
src/main/java/cn/iocoder/dashboard/modules/tool/dal/mysql/dao/coegen/ToolCodegenColumnMapper.java 0 → 100644
  1 +package cn.iocoder.dashboard.modules.tool.dal.mysql.dao.coegen;
  2 +
  3 +import cn.iocoder.dashboard.framework.mybatis.core.mapper.BaseMapperX;
  4 +import cn.iocoder.dashboard.modules.tool.dal.mysql.dataobject.codegen.ToolCodegenColumnDO;
  5 +import org.apache.ibatis.annotations.Mapper;
  6 +
  7 +@Mapper
  8 +public interface ToolCodegenColumnMapper extends BaseMapperX<ToolCodegenColumnDO> {
  9 +}
... ...
src/main/java/cn/iocoder/dashboard/modules/tool/dal/mysql/dao/coegen/ToolCodegenTableMapper.java 0 → 100644
  1 +package cn.iocoder.dashboard.modules.tool.dal.mysql.dao.coegen;
  2 +
  3 +import cn.iocoder.dashboard.framework.mybatis.core.mapper.BaseMapperX;
  4 +import cn.iocoder.dashboard.modules.tool.dal.mysql.dataobject.codegen.ToolCodegenTableDO;
  5 +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
  6 +import org.apache.ibatis.annotations.Mapper;
  7 +
  8 +@Mapper
  9 +public interface ToolCodegenTableMapper extends BaseMapperX<ToolCodegenTableDO> {
  10 +
  11 + default ToolCodegenTableDO selectByTableName(String tableName) {
  12 + return selectOne(new QueryWrapper<ToolCodegenTableDO>().eq("table_name", tableName));
  13 + }
  14 +
  15 +}
... ...
src/main/java/cn/iocoder/dashboard/modules/tool/dal/mysql/dao/coegen/ToolInformationSchemaTableMapper.java
... ... @@ -14,4 +14,8 @@ public interface ToolInformationSchemaTableMapper extends BaseMapperX&lt;ToolInform
14 14 return selectList(new QueryWrapper<ToolInformationSchemaTableDO>().eq("table_schema", tableSchema));
15 15 }
16 16  
  17 + default ToolInformationSchemaTableDO selectByTableName(String tableName) {
  18 + return selectOne(new QueryWrapper<ToolInformationSchemaTableDO>().eq("table_name", tableName));
  19 + }
  20 +
17 21 }
... ...
src/main/java/cn/iocoder/dashboard/modules/tool/enums/codegen/ToolCodegenColumnHtmlTypeEnum.java
... ... @@ -16,13 +16,14 @@ public enum ToolCodegenColumnHtmlTypeEnum {
16 16 RADIO("radio"), // 单选框
17 17 CHECKBOX("checkbox"), // 复选框
18 18 DATETIME("datetime"), // 日期控件
19   - UPLOAD_IMAGE("upload_image"), // 上传控件
  19 + UPLOAD_IMAGE("upload_image"), // 上传图片
  20 + UPLOAD_FILE("upload_file"), // 上传文件
20 21 EDITOR("editor"), // 富文本控件
21 22 ;
22 23  
23 24 /**
24 25 * 条件
25 26 */
26   - private final String condition;
  27 + private final String type;
27 28  
28 29 }
... ...
src/main/java/cn/iocoder/dashboard/modules/tool/service/codegen/ToolCodegenService.java 0 → 100644
  1 +package cn.iocoder.dashboard.modules.tool.service.codegen;
  2 +
  3 +/**
  4 + * 代码生成 Service 接口
  5 + *
  6 + * @author 芋道源码
  7 + */
  8 +public interface ToolCodegenService {
  9 +
  10 + /**
  11 + * 基于数据库的表结构,创建代码生成器的表定义
  12 + *
  13 + * @param tableName 表名称
  14 + * @return 表定义的编号
  15 + */
  16 + Long createCodegenTable(String tableName);
  17 +
  18 +}
... ...
src/main/java/cn/iocoder/dashboard/modules/tool/service/codegen/impl/ToolCodegenServiceImpl.java 0 → 100644
  1 +package cn.iocoder.dashboard.modules.tool.service.codegen.impl;
  2 +
  3 +import cn.hutool.core.collection.CollUtil;
  4 +import cn.hutool.core.map.MapUtil;
  5 +import cn.hutool.core.util.StrUtil;
  6 +import cn.iocoder.dashboard.framework.mybatis.core.dataobject.BaseDO;
  7 +import cn.iocoder.dashboard.modules.tool.convert.codegen.CodegenConvert;
  8 +import cn.iocoder.dashboard.modules.tool.dal.mysql.dao.coegen.ToolCodegenColumnMapper;
  9 +import cn.iocoder.dashboard.modules.tool.dal.mysql.dao.coegen.ToolCodegenTableMapper;
  10 +import cn.iocoder.dashboard.modules.tool.dal.mysql.dao.coegen.ToolInformationSchemaColumnMapper;
  11 +import cn.iocoder.dashboard.modules.tool.dal.mysql.dao.coegen.ToolInformationSchemaTableMapper;
  12 +import cn.iocoder.dashboard.modules.tool.dal.mysql.dataobject.codegen.ToolCodegenColumnDO;
  13 +import cn.iocoder.dashboard.modules.tool.dal.mysql.dataobject.codegen.ToolCodegenTableDO;
  14 +import cn.iocoder.dashboard.modules.tool.dal.mysql.dataobject.codegen.ToolInformationSchemaColumnDO;
  15 +import cn.iocoder.dashboard.modules.tool.dal.mysql.dataobject.codegen.ToolInformationSchemaTableDO;
  16 +import cn.iocoder.dashboard.modules.tool.enums.codegen.ToolCodegenColumnHtmlTypeEnum;
  17 +import cn.iocoder.dashboard.modules.tool.enums.codegen.ToolCodegenColumnListConditionEnum;
  18 +import cn.iocoder.dashboard.modules.tool.service.codegen.ToolCodegenService;
  19 +import com.google.common.collect.Sets;
  20 +import org.springframework.stereotype.Service;
  21 +import org.springframework.transaction.annotation.Transactional;
  22 +
  23 +import javax.annotation.Resource;
  24 +import java.math.BigDecimal;
  25 +import java.util.*;
  26 +
  27 +/**
  28 + * 代码生成 Service 实现类
  29 + *
  30 + * @author 芋道源码
  31 + */
  32 +@Service
  33 +public class ToolCodegenServiceImpl implements ToolCodegenService {
  34 +
  35 + /**
  36 + * 字段名与 {@link ToolCodegenColumnListConditionEnum} 的默认映射
  37 + * 注意,字段的匹配以后缀的方式
  38 + */
  39 + private static final Map<String, ToolCodegenColumnListConditionEnum> columnListOperationConditionMappings =
  40 + MapUtil.<String, ToolCodegenColumnListConditionEnum>builder()
  41 + .put("name", ToolCodegenColumnListConditionEnum.LIKE)
  42 + .put("time", ToolCodegenColumnListConditionEnum.BETWEEN)
  43 + .put("date", ToolCodegenColumnListConditionEnum.BETWEEN)
  44 + .build();
  45 +
  46 + /**
  47 + * 字段名与 {@link ToolCodegenColumnHtmlTypeEnum} 的默认映射
  48 + * 注意,字段的匹配以后缀的方式
  49 + */
  50 + private static final Map<String, ToolCodegenColumnHtmlTypeEnum> columnHtmlTypeMappings =
  51 + MapUtil.<String, ToolCodegenColumnHtmlTypeEnum>builder()
  52 + .put("status", ToolCodegenColumnHtmlTypeEnum.RADIO)
  53 + .put("sex", ToolCodegenColumnHtmlTypeEnum.RADIO)
  54 + .put("type", ToolCodegenColumnHtmlTypeEnum.SELECT)
  55 + .put("image", ToolCodegenColumnHtmlTypeEnum.UPLOAD_IMAGE)
  56 + .put("file", ToolCodegenColumnHtmlTypeEnum.UPLOAD_FILE)
  57 + .put("content", ToolCodegenColumnHtmlTypeEnum.EDITOR)
  58 + .build();
  59 +
  60 + /**
  61 + * 新增操作,不需要传递的字段
  62 + */
  63 + private static final Set<String> CREATE_OPERATION_EXCLUDE_COLUMN = Sets.newHashSet(
  64 + "id");
  65 + /**
  66 + * 修改操作,不需要传递的字段
  67 + */
  68 + private static final Set<String> UPDATE_OPERATION_EXCLUDE_COLUMN = Sets.newHashSet();
  69 + /**
  70 + * 列表操作的条件,不需要传递的字段
  71 + */
  72 + private static final Set<String> LIST_OPERATION_CONDITION_COLUMN = Sets.newHashSet();
  73 + /**
  74 + * 列表操作的结果,不需要返回的字段
  75 + */
  76 + private static final Set<String> LIST_OPERATION_RESULT_COLUMN = Sets.newHashSet();
  77 +
  78 + /**
  79 + * Java 类型与 MySQL 类型的映射关系
  80 + */
  81 + private static final Map<String, Set<String>> javaTypeMappings = MapUtil.<String, Set<String>>builder()
  82 + .put(Boolean.class.getSimpleName(), Sets.newHashSet("bit"))
  83 + .put(Integer.class.getSimpleName(), Sets.newHashSet("tinyint", "smallint", "mediumint", "int"))
  84 + .put(Long.class.getSimpleName(), Collections.singleton("bigint"))
  85 + .put(Double.class.getSimpleName(), Sets.newHashSet("float", "double"))
  86 + .put(BigDecimal.class.getSimpleName(), Sets.newHashSet("decimal", "numeric"))
  87 + .put(String.class.getSimpleName(), Sets.newHashSet("tinytext", "text", "mediumtext", "longtext", // 长文本
  88 + "char", "varchar", "nvarchar", "varchar2")) // 短文本
  89 + .put(Date.class.getSimpleName(), Sets.newHashSet("datetime", "time", "date", "timestamp"))
  90 + .build();
  91 +
  92 + static {
  93 + Arrays.stream(BaseDO.class.getDeclaredFields()).forEach(field -> {
  94 + CREATE_OPERATION_EXCLUDE_COLUMN.add(field.getName());
  95 + UPDATE_OPERATION_EXCLUDE_COLUMN.add(field.getName());
  96 + LIST_OPERATION_CONDITION_COLUMN.add(field.getName());
  97 + LIST_OPERATION_RESULT_COLUMN.add(field.getName());
  98 + });
  99 + LIST_OPERATION_RESULT_COLUMN.remove("create_time"); // 创建时间,还是需要返回的
  100 + }
  101 +
  102 + @Resource
  103 + private ToolInformationSchemaTableMapper informationSchemaTableMapper;
  104 + @Resource
  105 + private ToolInformationSchemaColumnMapper informationSchemaColumnMapper;
  106 + @Resource
  107 + private ToolCodegenTableMapper codegenTableMapper;
  108 + @Resource
  109 + private ToolCodegenColumnMapper codegenColumnMapper;
  110 +
  111 + @Override
  112 + @Transactional
  113 + public Long createCodegenTable(String tableName) {
  114 + // 从数据库中,获得数据库表结构
  115 + ToolInformationSchemaTableDO schemaTable = informationSchemaTableMapper.selectByTableName(tableName);
  116 + if (schemaTable == null) {
  117 + throw new RuntimeException(""); // TODO
  118 + }
  119 + List<ToolInformationSchemaColumnDO> schemaColumns = informationSchemaColumnMapper.selectListByTableName(tableName);
  120 + if (CollUtil.isEmpty(schemaColumns)) {
  121 + throw new RuntimeException(""); // TODO
  122 + }
  123 + // 校验是否已经存在
  124 + if (codegenTableMapper.selectByTableName(tableName) != null) {
  125 + throw new RuntimeException(""); // TODO
  126 + }
  127 +
  128 + // 将 table 插入到数据库
  129 + ToolCodegenTableDO table = CodegenConvert.INSTANCE.convert(schemaTable);
  130 + initTableDefault(table);
  131 + codegenTableMapper.insert(table);
  132 + // 将 column 插入到数据库
  133 + List<ToolCodegenColumnDO> columns = CodegenConvert.INSTANCE.convertList(schemaColumns);
  134 + columns.forEach(column -> {
  135 + initColumnDefault(column);
  136 + column.setTableId(table.getId());
  137 + codegenColumnMapper.insert(column);
  138 + });
  139 + return table.getId();
  140 + }
  141 +
  142 + /**
  143 + * 初始化 Table 表的默认字段
  144 + *
  145 + * @param table 表定义
  146 + */
  147 + private void initTableDefault(ToolCodegenTableDO table) {
  148 + table.setModuleName(StrUtil.subBefore(table.getTableName(),
  149 + '_', false)); // 第一个 _ 前缀的前面,作为 module 名字
  150 + table.setBusinessName(StrUtil.subAfter(table.getTableName(),
  151 + '_', false)); // 第一个 _ 前缀的后面,作为 module 名字
  152 + table.setBusinessName(StrUtil.toCamelCase(table.getBusinessName())); // 可能存在多个 _ 的情况,转换成驼峰
  153 + table.setClassName(StrUtil.toCamelCase(table.getClassName())); // 驼峰
  154 + table.setClassComment(StrUtil.subBefore(table.getClassComment(), // 去除结尾的表,作为类描述
  155 + '表', true));
  156 + table.setAuthor("芋艿"); // TODO 稍后改成创建人
  157 + }
  158 +
  159 + /**
  160 + * 初始化 Column 列的默认字段
  161 + *
  162 + * @param column 列定义
  163 + */
  164 + private void initColumnDefault(ToolCodegenColumnDO column) {
  165 + // 处理 Java 相关的字段的默认值
  166 + processColumnJava(column);
  167 + // 处理 CRUD 相关的字段的默认值
  168 + processColumnOperation(column);
  169 + // 处理 UI 相关的字段的默认值
  170 + processColumnUI(column);
  171 + }
  172 +
  173 + private void processColumnJava(ToolCodegenColumnDO column) {
  174 + // 处理 javaField 字段
  175 + column.setJavaField(StrUtil.toCamelCase(column.getColumnName()));
  176 + // 处理 dictType 字段,暂无
  177 + // 处理 javaType 字段
  178 + String dbType = StrUtil.subBefore(column.getColumnName(), ')', false);
  179 + javaTypeMappings.entrySet().stream()
  180 + .filter(entry -> entry.getValue().contains(dbType))
  181 + .findFirst().ifPresent(entry -> column.setJavaType(entry.getKey()));
  182 + if (column.getJavaType() == null) {
  183 + throw new IllegalStateException(String.format("column(%s) 的数据库类型(%s) 找不到匹配的 Java 类型",
  184 + column.getColumnName(), column.getColumnType()));
  185 + }
  186 + }
  187 +
  188 + private void processColumnOperation(ToolCodegenColumnDO column) {
  189 + // 处理 createOperation 字段
  190 + column.setCreateOperation(!CREATE_OPERATION_EXCLUDE_COLUMN.contains(column.getColumnName())
  191 + && !column.getPrimaryKey()); // 非主键
  192 + // 处理 updateOperation 字段
  193 + column.setUpdateOperation(!UPDATE_OPERATION_EXCLUDE_COLUMN.contains(column.getColumnName()));
  194 + // 处理 listOperationResult 字段
  195 + column.setListOperationResult(!LIST_OPERATION_RESULT_COLUMN.contains(column.getColumnName()));
  196 + // 处理 listOperationCondition 字段。默认设置为需要过滤的条件,手动进行取消
  197 + if (!LIST_OPERATION_CONDITION_COLUMN.contains(column.getColumnName())
  198 + && !column.getPrimaryKey()) { // 非主键
  199 + column.setListOperationCondition(ToolCodegenColumnListConditionEnum.EQ.getCondition());
  200 + }
  201 + columnListOperationConditionMappings.entrySet().stream()
  202 + .filter(entry -> StrUtil.endWithIgnoreCase(column.getColumnName(), entry.getKey()))
  203 + .findFirst().ifPresent(entry -> column.setListOperationCondition(entry.getValue().getCondition()));
  204 + }
  205 +
  206 + private void processColumnUI(ToolCodegenColumnDO column) {
  207 + // 基于后缀进行匹配
  208 + columnHtmlTypeMappings.entrySet().stream()
  209 + .filter(entry -> StrUtil.endWithIgnoreCase(column.getColumnName(), entry.getKey()))
  210 + .findFirst().ifPresent(entry -> column.setHtmlType(entry.getValue().getType()));
  211 + // 如果是 Boolean 类型时,设置为 radio 类型.
  212 + // 其它类型,因为字段名可以相对保障,所以不进行处理。例如说 date 对应 datetime 类型.
  213 + if (Boolean.class.getSimpleName().equals(column.getJavaType())) {
  214 + column.setHtmlType(ToolCodegenColumnHtmlTypeEnum.RADIO.getType());
  215 + }
  216 + // 兜底,设置默认为 input 类型
  217 + if (column.getHtmlType() == null) {
  218 + column.setHtmlType(ToolCodegenColumnHtmlTypeEnum.INPUT.getType());
  219 + }
  220 + }
  221 +
  222 +}
... ...
src/main/java/cn/iocoder/dashboard/modules/tool/service/package-info.java 0 → 100644
  1 +package cn.iocoder.dashboard.modules.tool.service;
... ...