feat: 添加通用附件管理功能,包括实体、服务、控制器及相关模板

This commit is contained in:
2026-01-10 15:05:25 +08:00
parent 2e2697140c
commit 4ee3ebcbec
16 changed files with 572 additions and 34 deletions

View File

@@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.generator.FastAutoGenerator;
import com.baomidou.mybatisplus.generator.config.OutputFile;
import com.baomidou.mybatisplus.generator.config.TemplateType;
import com.baomidou.mybatisplus.generator.config.rules.DateType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
@@ -20,6 +21,11 @@ import java.util.Collections;
* 3. 修改输出路径和包名
* 4. 运行 main 方法
* </p>
* <p>
* 生成规则:
* - Entity: XxxDO (数据对象)
* - Controller: /v1/xxx (RESTful 风格,包含 CRUD)
* </p>
*
* @author meowrain
* @since 1.0.0
@@ -28,11 +34,11 @@ public class CodeGenerator {
// ==================== 数据库配置 ====================
/** 数据库地址 */
private static final String DB_URL = "jdbc:mysql://10.0.0.10:3306/aioj?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai";
private static final String DB_URL = "jdbc:mysql://10.0.0.10:3306/aioj_dev?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai";
/** 数据库用户名 */
private static final String DB_USERNAME = "root";
/** 数据库密码 */
private static final String DB_PASSWORD = "123456";
private static final String DB_PASSWORD = "root";
// ==================== 代码生成配置 ====================
/** 作者名 */
@@ -40,17 +46,17 @@ public class CodeGenerator {
/** 父包名 */
private static final String PARENT_PACKAGE = "cn.meowrain.aioj.backend";
/** 模块名 (如: userservice, questionservice) */
private static final String MODULE_NAME = "userservice";
private static final String MODULE_NAME = "fileservice";
/** 要生成的表名 (多个表用逗号分隔) */
private static final String[] TABLE_NAMES = {"sys_user", "sys_role"};
private static final String[] TABLE_NAMES = {"attachment"};
/** 表前缀 (生成时会去掉前缀) */
private static final String[] TABLE_PREFIX = {"sys_", "t_"};
private static final String[] TABLE_PREFIX = {""};
// ==================== 输出路径配置 ====================
/** 代码输出目录 (默认当前项目的 src/main/java) */
private static final String OUTPUT_DIR = System.getProperty("user.dir") + "/src/main/java";
private static final String OUTPUT_DIR = System.getProperty("user.dir") + "/generator/src/main/java";
/** Mapper XML 输出目录 */
private static final String MAPPER_XML_DIR = System.getProperty("user.dir") + "/src/main/resources/mapper";
private static final String MAPPER_XML_DIR = System.getProperty("user.dir") + "/generator/src/main/resources/mapper";
public static void main(String[] args) {
generateCode();
@@ -85,8 +91,9 @@ public class CodeGenerator {
.strategyConfig(builder -> builder
.addInclude(TABLE_NAMES)
.addTablePrefix(TABLE_PREFIX)
// Entity 策略
// Entity 策略: 生成 XxxDO
.entityBuilder()
.formatFileName("%sDO") // 实体类后缀改为 DO
.enableLombok()
.enableTableFieldAnnotation()
.naming(NamingStrategy.underline_to_camel)
@@ -108,6 +115,15 @@ public class CodeGenerator {
.controllerBuilder()
.enableRestStyle()
)
// 自定义模板 (使用 /templates/ 目录下的模板)
.templateConfig(builder -> builder
.entity("/templates/entityDO.java")
.controller("/templates/controller.java")
.service("/templates/service.java")
.serviceImpl("/templates/serviceImpl.java")
.mapper("/templates/mapper.java")
.xml("/templates/mapper.xml")
)
// 模板引擎
.templateEngine(new FreemarkerTemplateEngine())
.execute();
@@ -115,5 +131,9 @@ public class CodeGenerator {
System.out.println("========== 代码生成完成 ==========");
System.out.println("输出目录: " + OUTPUT_DIR);
System.out.println("Mapper XML: " + MAPPER_XML_DIR);
System.out.println();
System.out.println("生成规则:");
System.out.println(" - Entity: XxxDO");
System.out.println(" - Controller: /v1/xxx (包含 CRUD 增删改查)");
}
}

View File

@@ -17,6 +17,11 @@ import java.util.Scanner;
* <p>
* 运行后会在控制台提示输入相关配置信息
* </p>
* <p>
* 生成规则:
* - Entity: XxxDO (数据对象)
* - Controller: /v1/xxx (RESTful 风格,包含 CRUD)
* </p>
*
* @author meowrain
* @since 1.0.0
@@ -118,8 +123,9 @@ public class InteractiveCodeGenerator {
builder.addTablePrefix(tablePrefixes);
}
builder
// Entity 策略
// Entity 策略: 生成 XxxDO
.entityBuilder()
.formatFileName("%sDO") // 实体类后缀改为 DO
.enableLombok()
.enableTableFieldAnnotation()
.naming(NamingStrategy.underline_to_camel)
@@ -141,6 +147,15 @@ public class InteractiveCodeGenerator {
.controllerBuilder()
.enableRestStyle();
})
// 自定义模板 (使用 /templates/ 目录下的模板)
.templateConfig(builder -> builder
.entity("/templates/entityDO.java")
.controller("/templates/controller.java")
.service("/templates/service.java")
.serviceImpl("/templates/serviceImpl.java")
.mapper("/templates/mapper.java")
.xml("/templates/mapper.xml")
)
// 模板引擎
.templateEngine(new FreemarkerTemplateEngine())
.execute();
@@ -149,5 +164,9 @@ public class InteractiveCodeGenerator {
System.out.println("========== 代码生成完成 ==========");
System.out.println("Java 代码: " + outputDir);
System.out.println("Mapper XML: " + mapperXmlDir);
System.out.println();
System.out.println("生成规则:");
System.out.println(" - Entity: XxxDO");
System.out.println(" - Controller: /v1/xxx (包含 CRUD 增删改查)");
}
}

View File

@@ -0,0 +1,97 @@
package ${package.Controller};
import ${package.Entity}.${entity}DO;
import ${package.Service}.${table.serviceName};
import cn.meowrain.aioj.backend.framework.result.Result;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* ${table.comment!} 控制器
*
* @author ${author}
* @since ${date}
*/
@Tag(name = "${table.comment!}管理")
@RestController
@RequestMapping("/v1/<#if controllerMappingHyphenStyle>${controllerMappingHyphen}<#else>${table.entityPath}</#if>")
@RequiredArgsConstructor
public class ${table.controllerName} {
private final ${table.serviceName} ${table.entityPath}Service;
/**
* 分页查询${table.comment!}列表
*/
@Operation(summary = "分页查询${table.comment!}列表")
@GetMapping("/page")
public Result<Page<${entity}DO>> page(
@Parameter(description = "当前页码") @RequestParam(defaultValue = "1") Integer current,
@Parameter(description = "每页数量") @RequestParam(defaultValue = "10") Integer size) {
Page<${entity}DO> page = new Page<>(current, size);
return Result.success(${table.entityPath}Service.page(page));
}
/**
* 查询所有${table.comment!}列表
*/
@Operation(summary = "查询所有${table.comment!}列表")
@GetMapping("/list")
public Result<List<${entity}DO>> list() {
return Result.success(${table.entityPath}Service.list());
}
/**
* 根据ID查询${table.comment!}详情
*/
@Operation(summary = "根据ID查询${table.comment!}详情")
@GetMapping("/{id}")
public Result<${entity}DO> getById(
@Parameter(description = "${table.comment!}ID") @PathVariable Long id) {
return Result.success(${table.entityPath}Service.getById(id));
}
/**
* 新增${table.comment!}
*/
@Operation(summary = "新增${table.comment!}")
@PostMapping
public Result<Boolean> save(@RequestBody ${entity}DO entity) {
return Result.success(${table.entityPath}Service.save(entity));
}
/**
* 修改${table.comment!}
*/
@Operation(summary = "修改${table.comment!}")
@PutMapping
public Result<Boolean> update(@RequestBody ${entity}DO entity) {
return Result.success(${table.entityPath}Service.updateById(entity));
}
/**
* 删除${table.comment!}
*/
@Operation(summary = "删除${table.comment!}")
@DeleteMapping("/{id}")
public Result<Boolean> delete(
@Parameter(description = "${table.comment!}ID") @PathVariable Long id) {
return Result.success(${table.entityPath}Service.removeById(id));
}
/**
* 批量删除${table.comment!}
*/
@Operation(summary = "批量删除${table.comment!}")
@DeleteMapping("/batch")
public Result<Boolean> deleteBatch(@RequestBody List<Long> ids) {
return Result.success(${table.entityPath}Service.removeByIds(ids));
}
}

View File

@@ -0,0 +1,68 @@
package ${package.Entity};
<#list table.importPackages as pkg>
import ${pkg};
</#list>
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.io.Serial;
import java.io.Serializable;
/**
* ${table.comment!} 数据访问对象
*
* @author ${author}
* @since ${date}
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("${table.name}")
public class ${entity}DO implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
<#-- 遍历字段 -->
<#list table.fields as field>
<#if field.keyFlag>
/**
* ${field.comment}
*/
@TableId(value = "${field.annotationColumnName}", type = IdType.ASSIGN_ID)
private ${field.propertyType} ${field.propertyName};
<#elseif field.propertyName == "delFlag">
/**
* ${field.comment}
*/
@TableLogic
@TableField("${field.annotationColumnName}")
private ${field.propertyType} ${field.propertyName};
<#elseif field.propertyName == "createTime">
/**
* ${field.comment}
*/
@TableField(value = "${field.annotationColumnName}", fill = FieldFill.INSERT)
private ${field.propertyType} ${field.propertyName};
<#elseif field.propertyName == "updateTime">
/**
* ${field.comment}
*/
@TableField(value = "${field.annotationColumnName}", fill = FieldFill.INSERT_UPDATE)
private ${field.propertyType} ${field.propertyName};
<#else>
/**
* ${field.comment}
*/
@TableField("${field.annotationColumnName}")
private ${field.propertyType} ${field.propertyName};
</#if>
</#list>
}

View File

@@ -0,0 +1,16 @@
package ${package.Mapper};
import ${package.Entity}.${entity}DO;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
/**
* ${table.comment!} Mapper 接口
*
* @author ${author}
* @since ${date}
*/
@Mapper
public interface ${table.mapperName} extends BaseMapper<${entity}DO> {
}

View File

@@ -0,0 +1,33 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="${package.Mapper}.${table.mapperName}">
<#if enableCache>
<!-- 开启二级缓存 -->
<cache type="org.mybatis.caches.ehcache.LoggingEhcache"/>
</#if>
<#if baseResultMap>
<!-- 通用查询映射结果 -->
<resultMap id="BaseResultMap" type="${package.Entity}.${entity}DO">
<#list table.fields as field>
<#if field.keyFlag>
<id column="${field.name}" property="${field.propertyName}" />
<#else>
<result column="${field.name}" property="${field.propertyName}" />
</#if>
</#list>
</resultMap>
</#if>
<#if baseColumnList>
<!-- 通用查询结果列 -->
<sql id="Base_Column_List">
<#list table.commonFields as field>
${field.columnName},
</#list>
${table.fieldNames}
</sql>
</#if>
</mapper>

View File

@@ -0,0 +1,14 @@
package ${package.Service};
import ${package.Entity}.${entity}DO;
import com.baomidou.mybatisplus.extension.service.IService;
/**
* ${table.comment!} 服务接口
*
* @author ${author}
* @since ${date}
*/
public interface ${table.serviceName} extends IService<${entity}DO> {
}

View File

@@ -0,0 +1,22 @@
package ${package.Service}.impl;
import ${package.Entity}.${entity}DO;
import ${package.Mapper}.${table.mapperName};
import ${package.Service}.${table.serviceName};
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
/**
* ${table.comment!} 服务实现类
*
* @author ${author}
* @since ${date}
*/
@Slf4j
@Service
@RequiredArgsConstructor
public class ${table.serviceImplName} extends ServiceImpl<${table.mapperName}, ${entity}DO> implements ${table.serviceName} {
}