refactor: 优化代码生成 POJO 逻辑及部分 freemarker 模板变量命名

This commit is contained in:
Charles7c 2023-08-19 22:34:56 +08:00
parent c1a6ef2304
commit cd3ac8a120
8 changed files with 66 additions and 50 deletions

View File

@ -61,5 +61,10 @@ public class GeneratorProperties {
* 包名称 * 包名称
*/ */
private String packageName; private String packageName;
/**
* 排除字段
*/
private String[] excludeFields;
} }
} }

View File

@ -18,7 +18,6 @@ package top.charles7c.cnadmin.tool.model.entity;
import java.io.Serializable; import java.io.Serializable;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.List;
import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull; import javax.validation.constraints.NotNull;
@ -138,13 +137,6 @@ public class GenConfigDO implements Serializable {
@TableField(exist = false) @TableField(exist = false)
private String classNamePrefix; private String classNamePrefix;
/**
* 字段配置信息
*/
@JsonIgnore
@TableField(exist = false)
private List<FieldConfigDO> fieldConfigs;
public GenConfigDO(String tableName) { public GenConfigDO(String tableName) {
this.tableName = tableName; this.tableName = tableName;
} }

View File

@ -40,7 +40,6 @@ import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil; import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil; import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.file.FileNameUtil; import cn.hutool.core.io.file.FileNameUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ClassUtil; import cn.hutool.core.util.ClassUtil;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import cn.hutool.db.meta.Column; import cn.hutool.db.meta.Column;
@ -212,7 +211,13 @@ public class GeneratorServiceImpl implements GeneratorService {
CheckUtils.throwIfNull(genConfig, "请先进行数据表 [{}] 生成配置", tableName); CheckUtils.throwIfNull(genConfig, "请先进行数据表 [{}] 生成配置", tableName);
List<FieldConfigDO> fieldConfigList = fieldConfigMapper.selectListByTableName(tableName); List<FieldConfigDO> fieldConfigList = fieldConfigMapper.selectListByTableName(tableName);
CheckUtils.throwIfEmpty(fieldConfigList, "请先进行数据表 [{}] 字段配置", tableName); CheckUtils.throwIfEmpty(fieldConfigList, "请先进行数据表 [{}] 字段配置", tableName);
Map<String, Object> genConfigMap = this.pretreatment(genConfig, fieldConfigList); Map<String, Object> genConfigMap = BeanUtil.beanToMap(genConfig);
genConfigMap.put("date", DateUtil.date().toString("yyyy/MM/dd HH:mm"));
String packageName = genConfig.getPackageName();
String apiModuleName =
StrUtil.subSuf(packageName, StrUtil.lastIndexOfIgnoreCase(packageName, StringConsts.DOT) + 1);
genConfigMap.put("apiModuleName", apiModuleName);
genConfigMap.put("apiName", StrUtil.lowerFirst(genConfig.getClassNamePrefix()));
try { try {
String classNamePrefix = genConfig.getClassNamePrefix(); String classNamePrefix = genConfig.getClassNamePrefix();
@ -232,13 +237,12 @@ public class GeneratorServiceImpl implements GeneratorService {
Map<String, TemplateConfig> templateConfigMap = generatorProperties.getTemplateConfigs(); Map<String, TemplateConfig> templateConfigMap = generatorProperties.getTemplateConfigs();
for (Map.Entry<String, TemplateConfig> templateConfigEntry : templateConfigMap.entrySet()) { for (Map.Entry<String, TemplateConfig> templateConfigEntry : templateConfigMap.entrySet()) {
// 例如D:/continew-admin/continew-admin-tool/src/main/java/top/charles7c/cnadmin/tool/service/impl/XxxServiceImpl.java // 例如D:/continew-admin/continew-admin-tool/src/main/java/top/charles7c/cnadmin/tool/service/impl/XxxServiceImpl.java
TemplateConfig templateConfig = templateConfigEntry.getValue(); this.pretreatment(genConfigMap, fieldConfigList, templateConfigEntry);
String subPackageName = templateConfig.getPackageName();
genConfigMap.put("subPackageName", subPackageName);
File classParentFile =
FileUtil.file(backendParentFile, StrUtil.splitToArray(subPackageName, StringConsts.DOT));
String className = classNamePrefix + StrUtil.nullToEmpty(templateConfigEntry.getKey()); String className = classNamePrefix + StrUtil.nullToEmpty(templateConfigEntry.getKey());
genConfigMap.put("className", className); genConfigMap.put("className", className);
TemplateConfig templateConfig = templateConfigEntry.getValue();
File classParentFile = FileUtil.file(backendParentFile,
StrUtil.splitToArray(templateConfig.getPackageName(), StringConsts.DOT));
File classFile = new File(classParentFile, className + FileNameUtil.EXT_JAVA); File classFile = new File(classParentFile, className + FileNameUtil.EXT_JAVA);
// 如果已经存在且不允许覆盖则跳过 // 如果已经存在且不允许覆盖则跳过
if (classFile.exists() && !isOverride) { if (classFile.exists() && !isOverride) {
@ -284,15 +288,22 @@ public class GeneratorServiceImpl implements GeneratorService {
/** /**
* 预处理生成配置 * 预处理生成配置
* *
* @param genConfig * @param genConfigMap
* 生成配置 * 生成配置
* @param fieldConfigList * @param originFieldConfigList
* 字段配置列表 * 原始字段配置列表
* @return 处理后的生成配置 * @param templateConfigEntry
* 模板配置
*/ */
private Map<String, Object> pretreatment(GenConfigDO genConfig, List<FieldConfigDO> fieldConfigList) { private void pretreatment(Map<String, Object> genConfigMap, List<FieldConfigDO> originFieldConfigList,
Map<String, Object> genConfigMap = MapUtil.newHashMap(); Map.Entry<String, TemplateConfig> templateConfigEntry) {
genConfigMap.put("date", DateUtil.date().toString("yyyy/MM/dd HH:mm")); TemplateConfig templateConfig = templateConfigEntry.getValue();
// 移除需要忽略的字段
List<FieldConfigDO> fieldConfigList = originFieldConfigList.stream()
.filter(fieldConfig -> !StrUtil.equalsAny(fieldConfig.getFieldName(), templateConfig.getExcludeFields()))
.collect(Collectors.toList());
genConfigMap.put("fieldConfigs", fieldConfigList);
// 统计部分特殊字段特征
genConfigMap.put("hasLocalDateTime", false); genConfigMap.put("hasLocalDateTime", false);
genConfigMap.put("hasBigDecimal", false); genConfigMap.put("hasBigDecimal", false);
genConfigMap.put("hasRequiredField", false); genConfigMap.put("hasRequiredField", false);
@ -303,7 +314,7 @@ public class GeneratorServiceImpl implements GeneratorService {
genConfigMap.put("hasLocalDateTime", true); genConfigMap.put("hasLocalDateTime", true);
} }
if ("BigDecimal".equals(fieldType)) { if ("BigDecimal".equals(fieldType)) {
genConfigMap.put("hasLocalDateTime", true); genConfigMap.put("hasBigDecimal", true);
} }
if (Boolean.TRUE.equals(fieldConfig.getIsRequired())) { if (Boolean.TRUE.equals(fieldConfig.getIsRequired())) {
genConfigMap.put("hasRequiredField", true); genConfigMap.put("hasRequiredField", true);
@ -314,13 +325,7 @@ public class GeneratorServiceImpl implements GeneratorService {
genConfigMap.put("hasListQueryField", true); genConfigMap.put("hasListQueryField", true);
} }
} }
genConfig.setFieldConfigs(fieldConfigList); String subPackageName = templateConfig.getPackageName();
genConfigMap.putAll(BeanUtil.beanToMap(genConfig)); genConfigMap.put("subPackageName", subPackageName);
String packageName = genConfig.getPackageName();
String moduleName =
StrUtil.subSuf(packageName, StrUtil.lastIndexOfIgnoreCase(packageName, StringConsts.DOT) + 1);
genConfigMap.put("moduleName", moduleName);
genConfigMap.put("apiName", StrUtil.lowerFirst(genConfig.getClassNamePrefix()));
return genConfigMap;
} }
} }

View File

@ -38,5 +38,5 @@ import ${packageName}.service.${classNamePrefix}Service;
*/ */
@Tag(name = "${businessName}管理 API") @Tag(name = "${businessName}管理 API")
@RestController @RestController
@CrudRequestMapping(value = "/${moduleName}/${apiName}", api = {Api.PAGE, Api.GET, Api.ADD, Api.UPDATE, Api.DELETE, Api.EXPORT}) @CrudRequestMapping(value = "/${apiModuleName}/${apiName}", api = {Api.PAGE, Api.GET, Api.ADD, Api.UPDATE, Api.DELETE, Api.EXPORT})
public class ${className} extends BaseController<${classNamePrefix}Service, ${classNamePrefix}VO, ${classNamePrefix}DetailVO, ${classNamePrefix}Query, ${classNamePrefix}Request> {} public class ${className} extends BaseController<${classNamePrefix}Service, ${classNamePrefix}VO, ${classNamePrefix}DetailVO, ${classNamePrefix}Query, ${classNamePrefix}Request> {}

View File

@ -1,7 +1,7 @@
import axios from 'axios'; import axios from 'axios';
import qs from 'query-string'; import qs from 'query-string';
const BASE_URL = '/${moduleName}/${apiName}'; const BASE_URL = '/${apiModuleName}/${apiName}';
export interface ${classNamePrefix}Record { export interface ${classNamePrefix}Record {
<#if fieldConfigs??> <#if fieldConfigs??>

View File

@ -1,7 +1,7 @@
<template> <template>
<div class="app-container"> <div class="app-container">
<Breadcrumb :items="['menu.${moduleName}', 'menu.${moduleName}.${apiName}.list']" /> <Breadcrumb :items="['menu.${apiModuleName}', 'menu.${apiModuleName}.${apiName}.list']" />
<a-card class="general-card" :title="$t('menu.${moduleName}.${apiName}.list')"> <a-card class="general-card" :title="$t('menu.${apiModuleName}.${apiName}.list')">
<!-- 头部区域 --> <!-- 头部区域 -->
<div class="header"> <div class="header">
<!-- 搜索栏 --> <!-- 搜索栏 -->
@ -38,14 +38,14 @@
<a-col :span="12"> <a-col :span="12">
<a-space> <a-space>
<a-button <a-button
v-permission="['${moduleName}:${apiName}:add']" v-permission="['${apiModuleName}:${apiName}:add']"
type="primary" type="primary"
@click="toAdd" @click="toAdd"
> >
<template #icon><icon-plus /></template>新增 <template #icon><icon-plus /></template>新增
</a-button> </a-button>
<a-button <a-button
v-permission="['${moduleName}:${apiName}:update']" v-permission="['${apiModuleName}:${apiName}:update']"
type="primary" type="primary"
status="success" status="success"
:disabled="single" :disabled="single"
@ -55,7 +55,7 @@
<template #icon><icon-edit /></template>修改 <template #icon><icon-edit /></template>修改
</a-button> </a-button>
<a-button <a-button
v-permission="['${moduleName}:${apiName}:delete']" v-permission="['${apiModuleName}:${apiName}:delete']"
type="primary" type="primary"
status="danger" status="danger"
:disabled="multiple" :disabled="multiple"
@ -65,7 +65,7 @@
<template #icon><icon-delete /></template>删除 <template #icon><icon-delete /></template>删除
</a-button> </a-button>
<a-button <a-button
v-permission="['${moduleName}:${apiName}:export']" v-permission="['${apiModuleName}:${apiName}:export']"
:loading="exportLoading" :loading="exportLoading"
type="primary" type="primary"
status="warning" status="warning"
@ -117,13 +117,13 @@
</#if> </#if>
</#list> </#list>
<a-table-column <a-table-column
v-if="checkPermission(['${moduleName}:${apiName}:update', '${moduleName}:${apiName}:delete'])" v-if="checkPermission(['${apiModuleName}:${apiName}:update', '${apiModuleName}:${apiName}:delete'])"
title="操作" title="操作"
align="center" align="center"
> >
<template #cell="{ record }"> <template #cell="{ record }">
<a-button <a-button
v-permission="['${moduleName}:${apiName}:update']" v-permission="['${apiModuleName}:${apiName}:update']"
type="text" type="text"
size="small" size="small"
title="修改" title="修改"
@ -137,7 +137,7 @@
@ok="handleDelete([record.id])" @ok="handleDelete([record.id])"
> >
<a-button <a-button
v-permission="['${moduleName}:${apiName}:delete']" v-permission="['${apiModuleName}:${apiName}:delete']"
type="text" type="text"
size="small" size="small"
title="删除" title="删除"
@ -244,7 +244,7 @@
add${classNamePrefix}, add${classNamePrefix},
update${classNamePrefix}, update${classNamePrefix},
delete${classNamePrefix}, delete${classNamePrefix},
} from '@/api/${moduleName}/${apiName}'; } from '@/api/${apiModuleName}/${apiName}';
import checkPermission from '@/utils/permission'; import checkPermission from '@/utils/permission';
const { proxy } = getCurrentInstance() as any; const { proxy } = getCurrentInstance() as any;
@ -442,7 +442,7 @@
if (exportLoading.value) return; if (exportLoading.value) return;
exportLoading.value = true; exportLoading.value = true;
proxy proxy
.download('/${moduleName}/${apiName}/export', { ...queryParams.value }, '${businessName}数据') .download('/${apiModuleName}/${apiName}/export', { ...queryParams.value }, '${businessName}数据')
.finally(() => { .finally(() => {
exportLoading.value = false; exportLoading.value = false;
}); });

View File

@ -55,12 +55,7 @@
{{ rowIndex + 1 + (queryParams.page - 1) * queryParams.size }} {{ rowIndex + 1 + (queryParams.page - 1) * queryParams.size }}
</template> </template>
</a-table-column> </a-table-column>
<a-table-column <a-table-column title="表名称" data-index="tableName" :width="225" />
title="表名称"
data-index="tableName"
:width="200"
tooltip
/>
<a-table-column title="描述" data-index="comment" tooltip /> <a-table-column title="描述" data-index="comment" tooltip />
<a-table-column title="存储引擎" data-index="engine" align="center" /> <a-table-column title="存储引擎" data-index="engine" align="center" />
<a-table-column title="字符集" data-index="charset" /> <a-table-column title="字符集" data-index="charset" />

View File

@ -245,8 +245,17 @@ generator:
# 模板配置 # 模板配置
templateConfigs: templateConfigs:
DO: DO:
# 模板路径
templatePath: generator/Entity.ftl templatePath: generator/Entity.ftl
# 包名称
packageName: model.entity packageName: model.entity
# 排除字段
excludeFields:
- id
- createUser
- createTime
- updateUser
- updateTime
Query: Query:
templatePath: generator/Query.ftl templatePath: generator/Query.ftl
packageName: model.query packageName: model.query
@ -256,9 +265,19 @@ generator:
VO: VO:
templatePath: generator/VO.ftl templatePath: generator/VO.ftl
packageName: model.vo packageName: model.vo
excludeFields:
- id
- createUser
- createTime
DetailVO: DetailVO:
templatePath: generator/DetailVO.ftl templatePath: generator/DetailVO.ftl
packageName: model.vo packageName: model.vo
excludeFields:
- id
- createUser
- createTime
- updateUser
- updateTime
Mapper: Mapper:
templatePath: generator/Mapper.ftl templatePath: generator/Mapper.ftl
packageName: mapper packageName: mapper