Compare commits

..

33 Commits

Author SHA1 Message Date
bunny 05a197d783 Merge branch 'master' of http://129.211.31.58:3000/auth/generator-code-server into dev 2025-07-18 00:25:31 +08:00
bunny c087925264 Merge branch 'dev' of http://129.211.31.58:3000/auth/generator-code-server into dev 2025-07-18 00:25:26 +08:00
bunny 41f765e61a Merge branch 'dev' 2025-07-18 00:25:06 +08:00
bunny 4b4275889d 📦 更新文件名称 2025-07-18 00:11:09 +08:00
bunny 9cb6e01753 📦 更新文件名称 2025-07-17 23:47:04 +08:00
bunny 38f9d54f97 💬 修改HTML标题h 2025-07-17 21:08:13 +08:00
Bunny 0bbdc45aed 🐛 SQL语句生成会有特殊字符 2025-07-11 14:25:20 +08:00
Bunny c0882ada7c 💄 调整UI页面平展开 2025-07-10 17:13:16 +08:00
Bunny 1afb95c602 🔧 添加跨域配置 2025-07-10 17:12:57 +08:00
Bunny c0ee8de27d 💬 修复后端生成文本找不到实体类 2025-07-10 12:05:57 +08:00
bunny edf8fbb13a 💬 更新生成后端文本内容 2025-07-08 21:48:40 +08:00
bunny 8bab7c6526 Merge branch 'dev' of http://129.211.31.58:3000/auth/generator-code-server into dev 2025-07-08 20:33:58 +08:00
bunny 0d95a5ff7f 🚑 后端文件生成报错 2025-07-08 20:33:22 +08:00
Bunny e5a8359fe9 📝 更新文档 2025-07-08 15:58:38 +08:00
bunny a6fa7761b4 💬 修改后端生成Entity类名 2025-07-06 14:27:25 +08:00
bunny e47acc4651 💬 修改后端生成模板;生成字段判断 2025-07-05 23:23:49 +08:00
Bunny ef2364d991 🐛 请求地址改为中划线 2025-07-04 15:54:35 +08:00
Bunny c478aa9418 🐛 完善後端生成模板 2025-07-04 14:24:46 +08:00
Bunny cadedad259 🔨 更新生成字段 2025-07-04 12:47:28 +08:00
Bunny 1ce2a7e210 持久化存储表单信息;放在前端localStorage中 2025-07-04 12:33:13 +08:00
Bunny 25c8e27e9b 🐛 修复前端复制按钮bug; 2025-07-04 12:32:38 +08:00
Bunny 2b3cddca52 💬 修改后端代码生成模板文本 2025-07-04 12:31:59 +08:00
Bunny 77745c42ed 📝 更新合并文档 2025-07-03 10:59:45 +08:00
Bunny 7ab534bde6
!1 Update README.md
Merge pull request !1 from gitee-agent/N/A
2025-07-03 02:54:53 +00:00
gitee-bot 2cbcbab877
Update README.md 2025-07-03 00:52:41 +00:00
bunny 83c61e9c42 Merge branch 'dev' 2025-07-02 23:23:59 +08:00
bunny c3cbe22543 🐛 复制失败;过滤表无法完成; 2025-07-02 23:23:51 +08:00
bunny 0f0f8aaeef Merge branch 'dev' 2025-07-02 21:36:12 +08:00
bunny ed66e2978e 🔥 删除不用图片 2025-07-02 21:36:02 +08:00
bunny d1371cac46 Merge branch 'dev' 2025-07-02 21:32:54 +08:00
bunny 5e0770af79 🔥 删除不用图片 2025-07-02 21:32:46 +08:00
bunny d9cced0eba Merge branch 'dev'
# Conflicts:
#	README.md
#	generator-code-server/generator-code/pom.xml
#	generator-code-server/generator-code/src/main/java/cn/bunny/core/factory/AbstractDatabaseInfo.java
#	generator-code-server/generator-code/src/main/java/cn/bunny/core/factory/ConcreteDatabaseInfo.java
#	generator-code-server/generator-code/src/main/java/cn/bunny/service/VmsService.java
#	generator-code-server/generator-code/src/main/java/cn/bunny/service/impl/SqlParserServiceImpl.java
#	generator-code-server/generator-code/src/main/java/cn/bunny/service/impl/TableServiceImpl.java
#	generator-code-server/generator-code/src/main/java/cn/bunny/service/impl/VmsServiceImpl.java
#	generator-code-server/generator-code/src/main/java/cn/bunny/utils/VmsUtil.java
#	src/main/java/cn/bunny/controller/IndexController.java
#	src/main/java/cn/bunny/controller/TableController.java
#	src/main/java/cn/bunny/controller/VmsController.java
#	src/main/java/cn/bunny/core/provider/SqlMetadataProvider.java
#	src/main/java/cn/bunny/core/template/VmsTBaseTemplateGenerator.java
#	src/main/java/cn/bunny/domain/dto/VmsArgumentDto.java
#	src/main/resources/application-prod.yml
#	src/main/resources/logback.xml
#	src/main/resources/static/src/components/AppGeneratorPage.js
#	src/main/resources/static/src/config/axios-config.js
#	src/main/resources/static/src/config/highlight-config.js
#	src/main/resources/static/src/config/popper-config.js
#	src/main/resources/static/src/lib/css/bootstrap/bootstrap.min.css
#	src/main/resources/static/src/lib/css/fonts/bootstrap-icons.woff
#	src/main/resources/static/src/lib/css/fonts/bootstrap-icons.woff2
#	src/main/resources/static/src/lib/css/highlight/atom-one-dark.min.css
#	src/main/resources/static/src/lib/js/axios/axios.min.js
#	src/main/resources/static/src/lib/js/boostrap/bootstrap.bundle.min.js
#	src/main/resources/static/src/lib/js/boostrap/popper.min.js
#	src/main/resources/static/src/lib/js/dayjs/advancedFormat.js
#	src/main/resources/static/src/lib/js/dayjs/antd.min.js
#	src/main/resources/static/src/lib/js/dayjs/customParseFormat.js
#	src/main/resources/static/src/lib/js/dayjs/dayjs.min.js
#	src/main/resources/static/src/lib/js/dayjs/localeData.js
#	src/main/resources/static/src/lib/js/dayjs/quarterOfYear.js
#	src/main/resources/static/src/lib/js/dayjs/weekOfYear.js
#	src/main/resources/static/src/lib/js/dayjs/weekYear.js
#	src/main/resources/static/src/lib/js/dayjs/weekday.js
#	src/main/resources/static/src/lib/js/highlightjs/highlight.min.js
#	src/main/resources/static/src/lib/js/highlightjs/javascript.min.js
#	src/main/resources/static/src/lib/js/vue/vue.global.js
#	src/main/resources/static/src/lib/js/vue/vue.global.prod.js
#	src/main/resources/static/src/views/database/DatabaseCard.js
#	src/main/resources/static/src/views/database/DatabaseForm.js
#	src/main/resources/templates/database.html
2025-07-02 21:28:51 +08:00
bunny 229cce3c31 保存master-v0.0.5 2025-07-02 21:23:40 +08:00
64 changed files with 409 additions and 300 deletions

17
.gitignore vendored
View File

@ -12,11 +12,6 @@ dist-ssr
.eslintcache
report.html
vite.config.*.timestamp*
application-prod.yml
bunny-web.site.csr
bunny-web.site.key
bunny-web.site_bundle.crt
bunny-web.site_bundle.pem
yarn.lock
npm-debug.log*
@ -68,4 +63,14 @@ lerna-debug.log*
.vscode/
# Editor directories and files
tsconfig.tsbuildinfo
tsconfig.tsbuildinfo
# 本地
bunny-web.site.csr
bunny-web.site.key
bunny-web.site_bundle.crt
bunny-web.site_bundle.pem
application-prod.yml
application-company.yml

View File

@ -2,6 +2,19 @@
[![License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)[![Java Version](https://img.shields.io/badge/JDK-17-green.svg)]()[![Spring Boot](https://img.shields.io/badge/Spring%20Boot-3.4.3-6DB33F.svg)]()
### 📁 项目结构说明
- `src/main/java/cn/bunny/controller`:包含所有控制器
- `src/main/java/cn/bunny/core`:核心模块,包含元数据提取、数据库方言等
- `src/main/java/cn/bunny/domain`:数据模型定义
- `src/main/java/cn/bunny/exception`:异常处理模块
- `src/main/java/cn/bunny/service`:接口定义
- `src/main/java/cn/bunny/service/impl`:接口实现
- `src/main/java/cn/bunny/utils`:工具类
- `src/main/resources/static/src`:前端组件和视图
- `src/main/resources/vms`Velocity 模板文件
- `src/main/resources/templates`:前端页面模板
## 1. 系统架构 🏗️
### 1.1 架构图
@ -41,6 +54,28 @@ graph TD
### 2.1 GeneratorController ⚡
#### 1. 核心控制器
- `GeneratorController`主控制器提供生成代码和下载ZIP文件的接口
- `TableController`:获取数据库元数据信息
- `SqlParserController`解析SQL语句提取表和列信息
- `WebController`:页面路由控制器
- `VmsController`:获取前端代码模板路径
#### 2. 元数据解析
- `DatabaseMetadataProvider`:数据库元数据提取器
- `SqlMetadataProvider`SQL语句元数据提取器
- `DatabaseDialect`:数据库方言接口,支持多数据库扩展
- `MySqlDialect`MySQL方言实现提取注释等信息
#### 3. 代码生成引擎
- `AbstractTemplateGenerator`:抽象模板生成器,定义模板方法
- `VmsTBaseTemplateGenerator`:具体模板实现,负责上下文填充和模板合并
- `ZipFileUtil`生成ZIP文件并下载
- `MysqlTypeConvertUtil`类型转换工具SQL → Java/JS
**核心业务流:**
```mermaid
@ -333,70 +368,10 @@ public static String processVmPath(VmsArgumentDto dto, String path, String table
| `mapper/UserMapper.xml` | 自动处理 | 系统会自动添加表名前缀 |
| `service/Service.java` | 自动处理 | 会转换为`UserService.java` |
## 7. 代码质量评估 🔍
### 7.1 后端代码评估85/100
**优势**
- ✅ 清晰的层次划分Controller/Service/Provider
- ✅ 合理使用设计模式(模板方法模式)
- ✅ 完善的异常处理体系
- ✅ 类型转换工具类封装良好
**待改进**
- ⚠️ 部分SQL解析逻辑可抽取为策略模式
- ⚠️ 元数据提供者接口可进一步抽象
- ⚠️ ZIP打包逻辑与业务耦合稍紧
**坏味道检测**
```mermaid
pie
title 后端代码坏味道分布
"重复代码" : 15
"过长方法" : 10
"过度耦合" : 5
"其他" : 70
```
### 7.2 前端代码评估78/100
**亮点**
- ✅ 组件化设计合理(表单/表格分离)
- ✅ 响应式状态管理有效
- ✅ 良好的用户交互反馈
- ✅ 类型提示完善
**问题点**
- ⚠️ 部分表单验证逻辑重复
- ⚠️ 表格分页逻辑可抽取为独立组件
**复杂度分析**
| 文件 | 方法数 | 平均行数 | 复杂度 |
| ------------------- | ------ | -------- | ------ |
| DatabaseTable.js | 12 | 18 | 中等 |
| DatabaseForm.js | 25 | 12 | 较高 |
| AppGeneratorPage.js | 8 | 15 | 低 |
### 7.3 总结评价
**整体评分**82/100
**可维护性**:⭐️⭐️⭐️⭐️
**扩展性**:⭐️⭐️⭐️⭐️
**代码规范**:⭐️⭐️⭐️⭐️⭐️
## 8. 支持项目☕
## 支持项目☕
如果这个项目对您有帮助,可以考虑支持我们:
![WeChat & Alipay](D:\Project\FullStack\GeneratorCode\images\wx_alipay.png)
![WeChat & Alipay](.\images\wx_alipay.png)
**Happy Coding!** 🎉

Binary file not shown.

Before

Width:  |  Height:  |  Size: 69 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 103 KiB

View File

@ -0,0 +1,19 @@
package cn.bunny.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**") // 所有接口
.allowedOrigins("*") // 允许所有来源
.allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS") // 允许方法
.allowedHeaders("*") // 允许所有头
// .allowCredentials(true) // 允许凭证
.maxAge(3600); // 预检请求缓存时间
}
}

View File

@ -1,8 +1,8 @@
package cn.bunny.controller;
import cn.bunny.domain.dto.VmsArgumentDto;
import cn.bunny.domain.result.Result;
import cn.bunny.domain.vo.GeneratorVo;
import cn.bunny.model.dto.VmsArgumentDto;
import cn.bunny.model.result.Result;
import cn.bunny.model.vo.GeneratorVo;
import cn.bunny.service.GeneratorService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
@ -30,12 +30,6 @@ public class GeneratorController {
private final GeneratorService generatorService;
/**
* 生成代码
*
* @param dto 生成参数DTO
* @return 生成的代码结果按表名分组
*/
@Operation(summary = "生成代码", description = "根据SQL或数据库表生成代码")
@PostMapping
public Result<Map<String, List<GeneratorVo>>> generator(@Valid @RequestBody VmsArgumentDto dto) {
@ -48,18 +42,12 @@ public class GeneratorController {
return Result.success(result);
}
/**
* 打包代码为ZIP下载
*
* @param dto 生成参数DTO
* @return ZIP文件响应实体
*/
@Operation(summary = "打包下载", description = "将生成的代码打包为ZIP文件下载")
@PostMapping("downloadByZip")
public ResponseEntity<byte[]> downloadByZip(@Valid @RequestBody VmsArgumentDto dto) {
// 判断当前是使用 SQL语句 生成还是 数据库生成
String sql = dto.getSql();
return Strings.isEmpty(sql)
? generatorService.downloadByZipByDatabase(dto)
: generatorService.downloadByZipBySqL(dto);

View File

@ -1,9 +1,9 @@
package cn.bunny.controller;
import cn.bunny.core.provider.SqlMetadataProvider;
import cn.bunny.domain.entity.ColumnMetaData;
import cn.bunny.domain.entity.TableMetaData;
import cn.bunny.domain.result.Result;
import cn.bunny.model.entity.ColumnMetaData;
import cn.bunny.model.entity.TableMetaData;
import cn.bunny.model.result.Result;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;

View File

@ -1,11 +1,11 @@
package cn.bunny.controller;
import cn.bunny.core.provider.DatabaseMetadataProvider;
import cn.bunny.domain.entity.ColumnMetaData;
import cn.bunny.domain.entity.DatabaseInfoMetaData;
import cn.bunny.domain.entity.TableMetaData;
import cn.bunny.domain.result.Result;
import cn.bunny.domain.result.ResultCodeEnum;
import cn.bunny.model.entity.ColumnMetaData;
import cn.bunny.model.entity.DatabaseInfoMetaData;
import cn.bunny.model.entity.TableMetaData;
import cn.bunny.model.result.Result;
import cn.bunny.model.result.ResultCodeEnum;
import cn.bunny.service.TableService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;

View File

@ -1,7 +1,7 @@
package cn.bunny.controller;
import cn.bunny.domain.result.Result;
import cn.bunny.domain.vo.VmsPathVo;
import cn.bunny.model.result.Result;
import cn.bunny.model.vo.VmsPathVo;
import cn.bunny.service.VmsService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;

View File

@ -5,7 +5,7 @@ import org.springframework.web.bind.annotation.GetMapping;
@Controller
public class WebController {
@GetMapping("/")
public String indexPage() {
return "redirect:/database";

View File

@ -1,11 +1,11 @@
package cn.bunny.core.provider;
import cn.bunny.domain.entity.ColumnMetaData;
import cn.bunny.domain.entity.DatabaseInfoMetaData;
import cn.bunny.domain.entity.TableMetaData;
import cn.bunny.exception.GeneratorCodeException;
import cn.bunny.exception.MetadataNotFoundException;
import cn.bunny.exception.MetadataProviderException;
import cn.bunny.model.entity.ColumnMetaData;
import cn.bunny.model.entity.DatabaseInfoMetaData;
import cn.bunny.model.entity.TableMetaData;
import cn.bunny.utils.MysqlTypeConvertUtil;
import com.zaxxer.hikari.HikariDataSource;
import lombok.RequiredArgsConstructor;

View File

@ -1,7 +1,7 @@
package cn.bunny.core.provider;
import cn.bunny.domain.entity.ColumnMetaData;
import cn.bunny.domain.entity.TableMetaData;
import cn.bunny.model.entity.ColumnMetaData;
import cn.bunny.model.entity.TableMetaData;
import java.util.List;

View File

@ -1,10 +1,10 @@
package cn.bunny.core.provider;
import cn.bunny.core.dialect.DatabaseDialect;
import cn.bunny.domain.entity.ColumnMetaData;
import cn.bunny.domain.entity.TableMetaData;
import cn.bunny.exception.GeneratorCodeException;
import cn.bunny.exception.SqlParseException;
import cn.bunny.model.entity.ColumnMetaData;
import cn.bunny.model.entity.TableMetaData;
import cn.bunny.utils.MysqlTypeConvertUtil;
import lombok.RequiredArgsConstructor;
import net.sf.jsqlparser.JSQLParserException;
@ -85,7 +85,8 @@ public class SqlMetadataProvider implements IMetadataProvider {
ColumnMetaData columnInfo = new ColumnMetaData();
// 列名称
columnInfo.setColumnName(column.getColumnName());
String columnName = column.getColumnName().replaceAll("`", "");
columnInfo.setColumnName(columnName);
// 设置 JDBC 类型
String dataType = column.getColDataType().getDataType();
@ -99,11 +100,11 @@ public class SqlMetadataProvider implements IMetadataProvider {
columnInfo.setJavascriptType(StringUtils.uncapitalize(javaType));
// 列字段转成 下划线 -> 小驼峰
String lowercaseName = MysqlTypeConvertUtil.convertToCamelCase(column.getColumnName(), false);
String lowercaseName = MysqlTypeConvertUtil.convertToCamelCase(columnName, false);
columnInfo.setLowercaseName(lowercaseName);
// 列字段转成 下划线 -> 大驼峰名称
String uppercaseName = MysqlTypeConvertUtil.convertToCamelCase(column.getColumnName(), true);
String uppercaseName = MysqlTypeConvertUtil.convertToCamelCase(columnName, true);
columnInfo.setUppercaseName(uppercaseName);
// 解析注释

View File

@ -1,7 +1,7 @@
package cn.bunny.core.template;
import cn.bunny.domain.entity.ColumnMetaData;
import cn.bunny.domain.entity.TableMetaData;
import cn.bunny.model.entity.ColumnMetaData;
import cn.bunny.model.entity.TableMetaData;
import org.apache.velocity.VelocityContext;
import java.io.StringWriter;

View File

@ -1,11 +1,13 @@
package cn.bunny.core.template;
import cn.bunny.domain.dto.VmsArgumentDto;
import cn.bunny.domain.entity.TableMetaData;
import cn.bunny.model.dto.VmsArgumentDto;
import cn.bunny.model.entity.TableMetaData;
import cn.bunny.utils.MysqlTypeConvertUtil;
import com.google.common.base.CaseFormat;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;
import org.springframework.util.StringUtils;
import java.io.StringWriter;
import java.text.SimpleDateFormat;
@ -27,6 +29,19 @@ public class VmsTBaseTemplateGenerator extends AbstractTemplateGenerator {
* @param tableMetaData 表名称
*/
public VmsTBaseTemplateGenerator(VmsArgumentDto dto, String path, TableMetaData tableMetaData) {
// 处理表名称替换前缀
String tableName = tableMetaData.getTableName();
String[] prefixes = dto.getTablePrefixes().split("[,]");
tableMetaData.setCleanTableName(tableName);
for (String prefix : prefixes) {
if (tableName.startsWith(prefix)) {
String handlerTableName = tableName.replace(prefix, "");
tableMetaData.setCleanTableName(handlerTableName);
}
}
this.dto = dto;
this.path = path;
this.tableMetaData = tableMetaData;
@ -40,7 +55,9 @@ public class VmsTBaseTemplateGenerator extends AbstractTemplateGenerator {
@Override
public void addContext(VelocityContext context) {
// 当前的表名
String tableName = tableMetaData.getTableName();
String cleanTableName = tableMetaData.getCleanTableName();
cleanTableName = StringUtils.hasText(cleanTableName) ? cleanTableName : tableMetaData.getTableName();
// 表的注释内容
String comment = tableMetaData.getComment();
@ -61,12 +78,16 @@ public class VmsTBaseTemplateGenerator extends AbstractTemplateGenerator {
context.put("package", dto.getPackageName());
// 将类名称转成小驼峰
String lowerCamelCase = MysqlTypeConvertUtil.convertToCamelCase(tableName, false);
String lowerCamelCase = MysqlTypeConvertUtil.convertToCamelCase(cleanTableName, false);
context.put("classLowercaseName", lowerCamelCase);
// 将类名称转成大驼峰
String upperCameCase = MysqlTypeConvertUtil.convertToCamelCase(tableName, true);
String upperCameCase = MysqlTypeConvertUtil.convertToCamelCase(cleanTableName, true);
context.put("classUppercaseName", upperCameCase);
// 添加中划线
String lowerHyphenName = CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_HYPHEN, lowerCamelCase);
context.put("lowerHyphenName", lowerHyphenName);
}
/**

View File

@ -1,6 +1,6 @@
package cn.bunny.exception;
import cn.bunny.domain.result.ResultCodeEnum;
import cn.bunny.model.result.ResultCodeEnum;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.ToString;

View File

@ -1,8 +1,8 @@
package cn.bunny.exception;
import cn.bunny.domain.result.Result;
import cn.bunny.domain.result.ResultCodeEnum;
import cn.bunny.model.result.Result;
import cn.bunny.model.result.ResultCodeEnum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.support.DefaultMessageSourceResolvable;
import org.springframework.util.StringUtils;

View File

@ -1,4 +1,4 @@
package cn.bunny.domain.dto;
package cn.bunny.model.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;

View File

@ -1,4 +1,4 @@
package cn.bunny.domain.entity;
package cn.bunny.model.entity;
import lombok.AllArgsConstructor;
import lombok.Builder;

View File

@ -1,4 +1,4 @@
package cn.bunny.domain.entity;
package cn.bunny.model.entity;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;

View File

@ -1,4 +1,4 @@
package cn.bunny.domain.entity;
package cn.bunny.model.entity;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
@ -6,6 +6,7 @@ import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
import java.util.List;
@Data
@ -13,11 +14,14 @@ import java.util.List;
@AllArgsConstructor
@NoArgsConstructor
@Schema(name = "TableMetaData", description = "表信息数据")
public class TableMetaData {
public class TableMetaData implements Serializable {
@Schema(name = "tableName", description = "表名")
private String tableName;
@Schema(name = "handlerTableName", description = "处理后的表名称")
private String cleanTableName;
@Schema(name = "comment", description = "注释内容")
private String comment;
@ -33,4 +37,5 @@ public class TableMetaData {
@Schema(name = "columns", description = "列名称")
private List<ColumnMetaData> columns = List.of();
}

View File

@ -1,4 +1,4 @@
package cn.bunny.domain.result;
package cn.bunny.model.result;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;

View File

@ -1,4 +1,4 @@
package cn.bunny.domain.result;
package cn.bunny.model.result;
import lombok.AllArgsConstructor;
import lombok.Data;

View File

@ -1,4 +1,4 @@
package cn.bunny.domain.result;
package cn.bunny.model.result;
import lombok.Getter;

View File

@ -1,4 +1,4 @@
package cn.bunny.domain.vo;
package cn.bunny.model.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;

View File

@ -1,4 +1,4 @@
package cn.bunny.domain.vo;
package cn.bunny.model.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;

View File

@ -1,7 +1,7 @@
package cn.bunny.service;
import cn.bunny.domain.dto.VmsArgumentDto;
import cn.bunny.domain.vo.GeneratorVo;
import cn.bunny.model.dto.VmsArgumentDto;
import cn.bunny.model.vo.GeneratorVo;
import jakarta.validation.Valid;
import org.springframework.http.ResponseEntity;

View File

@ -1,6 +1,6 @@
package cn.bunny.service;
import cn.bunny.domain.entity.DatabaseInfoMetaData;
import cn.bunny.model.entity.DatabaseInfoMetaData;
public interface TableService {
@ -10,5 +10,5 @@ public interface TableService {
* @return 当前连接的数据库信息属性
*/
DatabaseInfoMetaData databaseInfoMetaData();
}

View File

@ -1,6 +1,6 @@
package cn.bunny.service;
import cn.bunny.domain.vo.VmsPathVo;
import cn.bunny.model.vo.VmsPathVo;
import java.util.List;
import java.util.Map;

View File

@ -1,6 +1,5 @@
package cn.bunny.service.helper;
import cn.bunny.domain.dto.VmsArgumentDto;
import cn.bunny.utils.MysqlTypeConvertUtil;
import com.google.common.base.CaseFormat;
@ -17,42 +16,32 @@ public class VmsGeneratorPathHelper {
"mapper", "Mapper",
"resourceMapper", "Mapper",
"dto", "Dto",
"entity", "Entity",
"vo", "Vo"
);
/**
* 处理模板文件路径和命名
*
* @param dto 生成参数
* @param path 原始模板路径
* @param tableName 数据库表名
* @return 处理后的文件路径
*/
public static String processVmPath(VmsArgumentDto dto, String path, String tableName) {
String className = removeTablePrefixes(dto, tableName);
public static String processVmPath(String path, String tableName) {
String lowerCamelCase = MysqlTypeConvertUtil.convertToCamelCase(tableName, false);
String[] pathParts = path.replace("$className", lowerCamelCase).split("/");
// 处理文件名
pathParts[pathParts.length - 1] = processFilename(
pathParts[pathParts.length - 1],
className
);
if (lowerCamelCase != null) {
String[] pathParts = path.replace("$className", lowerCamelCase).split("/");
// 处理文件名
pathParts[pathParts.length - 1] = processFilename(
pathParts[pathParts.length - 1],
lowerCamelCase
);
return String.join("/", pathParts);
}
/**
* 移除表前缀
*/
private static String removeTablePrefixes(VmsArgumentDto dto, String tableName) {
String[] prefixes = dto.getTablePrefixes().split("[,]");
for (String prefix : prefixes) {
if (tableName.startsWith(prefix)) {
return tableName.substring(prefix.length());
}
return String.join("/", pathParts);
}
return tableName;
return path;
}
/**

View File

@ -2,10 +2,10 @@ package cn.bunny.service.impl;
import cn.bunny.core.provider.IMetadataProvider;
import cn.bunny.core.template.VmsTBaseTemplateGenerator;
import cn.bunny.domain.dto.VmsArgumentDto;
import cn.bunny.domain.entity.ColumnMetaData;
import cn.bunny.domain.entity.TableMetaData;
import cn.bunny.domain.vo.GeneratorVo;
import cn.bunny.model.dto.VmsArgumentDto;
import cn.bunny.model.entity.ColumnMetaData;
import cn.bunny.model.entity.TableMetaData;
import cn.bunny.model.vo.GeneratorVo;
import cn.bunny.service.GeneratorService;
import cn.bunny.service.helper.VmsGeneratorPathHelper;
import cn.bunny.utils.ZipFileUtil;
@ -56,10 +56,12 @@ public class GeneratorServiceImpl implements GeneratorService {
*/
@Override
public Map<String, List<GeneratorVo>> generateCodeBySql(VmsArgumentDto dto) {
// 根据Sql语句进行分析表的属性和表列字段
String sql = dto.getSql();
TableMetaData tableMeta = sqlMetadataProvider.getTableMetadata(sql);
List<ColumnMetaData> columns = sqlMetadataProvider.getColumnInfoList(sql);
// 生成代码
List<GeneratorVo> generatorVoList = getGeneratorStream(dto, tableMeta, columns).toList();
Map<String, List<GeneratorVo>> map = new HashMap<>();
@ -68,11 +70,23 @@ public class GeneratorServiceImpl implements GeneratorService {
return map;
}
/**
* 根据数据库进行生成
*
* @param dto 生成参数
* @return 生成的ZIP文件
*/
@Override
public ResponseEntity<byte[]> downloadByZipByDatabase(VmsArgumentDto dto) {
return downloadByZip(dto, this::generateCodeByDatabase);
}
/**
* 根据Sql语句及逆行生成
*
* @param dto 生成参数
* @return 生成的ZIP文件
*/
@Override
public ResponseEntity<byte[]> downloadByZipBySqL(VmsArgumentDto dto) {
return downloadByZip(dto, this::generateCodeBySql);
@ -117,16 +131,22 @@ public class GeneratorServiceImpl implements GeneratorService {
* @return 生成器流
*/
public Stream<GeneratorVo> getGeneratorStream(VmsArgumentDto dto, TableMetaData tableMeta, List<ColumnMetaData> columns) {
// 因为这里使用到了并行流 tableMeta 操作正常是会拿到修改后的值但是在并行流会有线程安全问题所以直接要手动实现深拷贝
return dto.getPath().parallelStream().map(path -> {
// 创建生成模板
VmsTBaseTemplateGenerator generator = new VmsTBaseTemplateGenerator(dto, path, tableMeta);
// 生成好的模板
String code = generator.generateCode(tableMeta, columns).toString();
String processVmPath = VmsGeneratorPathHelper.processVmPath(path, tableMeta.getCleanTableName());
return GeneratorVo.builder()
.id(UUID.randomUUID().toString())
.code(code)
.comment(tableMeta.getComment())
.tableName(tableMeta.getTableName())
.path(VmsGeneratorPathHelper.processVmPath(dto, path, tableMeta.getTableName()))
.path(processVmPath)
.build();
});
}

View File

@ -1,8 +1,8 @@
package cn.bunny.service.impl;
import cn.bunny.core.provider.DatabaseMetadataProvider;
import cn.bunny.domain.entity.DatabaseInfoMetaData;
import cn.bunny.domain.entity.TableMetaData;
import cn.bunny.model.entity.DatabaseInfoMetaData;
import cn.bunny.model.entity.TableMetaData;
import cn.bunny.service.TableService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

View File

@ -1,6 +1,6 @@
package cn.bunny.service.impl;
import cn.bunny.domain.vo.VmsPathVo;
import cn.bunny.model.vo.VmsPathVo;
import cn.bunny.service.VmsService;
import cn.bunny.utils.ResourceFileUtil;
import lombok.RequiredArgsConstructor;

View File

@ -1,6 +1,6 @@
package cn.bunny.utils;
import cn.bunny.domain.vo.GeneratorVo;
import cn.bunny.model.vo.GeneratorVo;
import java.io.ByteArrayOutputStream;
import java.io.IOException;

View File

@ -6,6 +6,11 @@ spring:
active: prod
application:
name: generator-code
devtools:
livereload:
enabled: true
port: 8880
thymeleaf:
check-template-location: false
@ -17,4 +22,8 @@ spring:
password: ${bunny.master.password}
hikari:
maximum-pool-size: 20
connection-timeout: 30000
connection-timeout: 30000
logging:
file:
path: "logs/${spring.application.name}"

View File

@ -2,7 +2,7 @@
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<title>400 错误 - phpstudy</title>
<title>400 错误 - generator-code</title>
<meta content="" name="keywords">
<meta content="" name="description">
<meta content="webkit" name="renderer">

View File

@ -2,7 +2,7 @@
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<title>403 错误 - phpstudy</title>
<title>403 错误 - generator-code</title>
<meta content="" name="keywords">
<meta content="" name="description">
<meta content="webkit" name="renderer">

View File

@ -2,7 +2,7 @@
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<title>404 错误 - phpstudy</title>
<title>404 错误 - generator-code</title>
<meta content="" name="keywords">
<meta content="" name="description">
<meta content="webkit" name="renderer">

View File

@ -2,7 +2,7 @@
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<title>501 错误 - phpstudy</title>
<title>501 错误 - generator-code</title>
<meta content="" name="keywords">
<meta content="" name="description">
<meta content="webkit" name="renderer">

View File

@ -2,7 +2,7 @@
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<title>502 错误 - phpstudy</title>
<title>502 错误 - generator-code</title>
<meta content="" name="keywords">
<meta content="" name="description">
<meta content="webkit" name="renderer">

View File

@ -2,7 +2,7 @@
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<title>503 错误 - phpstudy</title>
<title>503 错误 - generator-code</title>
<meta content="" name="keywords">
<meta content="" name="description">
<meta content="webkit" name="renderer">

View File

@ -2,7 +2,7 @@
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<title>504 错误 - phpstudy</title>
<title>504 错误 - generator-code</title>
<meta content="" name="keywords">
<meta content="" name="description">
<meta content="webkit" name="renderer">

View File

@ -2,7 +2,7 @@
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<title>505 错误 - phpstudy</title>
<title>505 错误 - generator-code</title>
<meta content="" name="keywords">
<meta content="" name="description">
<meta content="webkit" name="renderer">

View File

@ -2,7 +2,7 @@
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<title>506 错误 - phpstudy</title>
<title>506 错误 - generator-code</title>
<meta content="" name="keywords">
<meta content="" name="description">
<meta content="webkit" name="renderer">

View File

@ -2,7 +2,7 @@
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<title>507 错误 - phpstudy</title>
<title>507 错误 - generator-code</title>
<meta content="" name="keywords">
<meta content="" name="description">
<meta content="webkit" name="renderer">

View File

@ -2,7 +2,7 @@
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<title>509 错误 - phpstudy</title>
<title>509 错误 - generator-code</title>
<meta content="" name="keywords">
<meta content="" name="description">
<meta content="webkit" name="renderer">

View File

@ -2,7 +2,7 @@
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<title>510 错误 - phpstudy</title>
<title>510 错误 - generator-code</title>
<meta content="" name="keywords">
<meta content="" name="description">
<meta content="webkit" name="renderer">

View File

@ -94,40 +94,40 @@ const AppGeneratorPage = defineComponent({
* 点击复制图表
* 几秒后恢复原状
*/
onCopyToClipboard(code) {
const textarea = document.createElement('textarea');
textarea.value = code;
// 避免滚动到页面底部
textarea.style.position = 'fixed';
document.body.appendChild(textarea);
textarea.select();
async onCopyToClipboard(code) {
this.copied = true;
try {
const successful = document.execCommand('copy');
if (successful) {
this.copied = true;
antd.notification.open({
type: 'success',
message: '复制成功',
description: '已将内容复制至剪切板',
duration: 3,
});
// 几秒后恢复原状
setTimeout(() => {
this.copied = false;
}, 2000);
}
} catch (err) {
await navigator.clipboard.writeText(code);
antd.notification.open({
type: 'success',
message: '复制失败',
description: err.message,
message: '复制成功',
description: '已将内容复制至剪切板',
duration: 3,
});
} catch (err) {
antd.notification.open({
type: 'error',
message: '复制失败',
description: err.message``,
duration: 3,
});
console.error('复制失败:', err);
// 回退到传统方法
const textarea = document.createElement('textarea');
textarea.value = code;
document.body.appendChild(textarea);
textarea.select();
document.execCommand('copy');
document.body.removeChild(textarea);
}
document.body.removeChild(textarea);
// 显示已复制图标时长
if (this.copied) {
setTimeout(() => {
this.copied = false;
}, 2000)
}
},
/* 下载全部文件 */

View File

@ -34,6 +34,8 @@ axiosInstance.interceptors.response.use(
} else {
antd.message.error(message || '系统出错');
}
return error.response.data;
}
return Promise.reject(error.message);
}

View File

@ -288,11 +288,12 @@ const DatabaseForm = {
async onDownloadZip() {
this.downloadLoading = true;
try {
// 重要指定响应类型为blob
const response = await axiosInstance({
url: "/generator/downloadByZip",
method: "POST",
data: this.form,
responseType: 'blob' // 重要指定响应类型为blob
responseType: 'blob'
});
// 从响应头中获取文件名

View File

@ -28,7 +28,7 @@
<body>
<div id="app">
<div class="container my-4">
<div class="container-fluid my-4">
<!-- 主标题 -->
<app-header></app-header>
@ -169,21 +169,32 @@
},
watch: {
/* 数据表选择 */
dbSelect: {
handler() {
this.getDatabaseTableList();
}
},
dbSelect: "getDatabaseTableList",
/* 过滤数据表 */
tableSelect: {
handler(val) {
this.tableList = this.rawTableList;
// 根据表名进行过滤筛选或者根据注释内容进行筛选
this.tableList = this.tableList.filter(table => table.tableName.includes(val) || table.tablePrefixes.includes(val));
}
tableSelect(val) {
this.tableList = this.rawTableList;
// 根据表名进行过滤筛选或者根据注释内容进行筛选
this.tableList = this.tableList.filter(table => table.tableName.includes(val) || table.comment.includes(val));
},
/**
* 监听form表单放到 localStorage
* 不要使用 immediate 否则初始话加载的时候会将 localStorage 改成 原始表单
*/
form: {
deep: true,
handler(val) {
localStorage.setItem("form", JSON.stringify(val));
},
}
},
mounted() {
const form = localStorage.getItem("form");
if (form !== null) {
this.form = JSON.parse(form);
}
}
});
// 注册组件

View File

@ -28,7 +28,7 @@
<body>
<div id="app">
<div class="container my-4">
<div class="container-fluid my-4">
<!-- 主标题 -->
<app-header></app-header>

View File

@ -1,16 +1,20 @@
package ${package}.controller;
import cn.bunny.domain.pojo.result.Result;
import cn.bunny.domain.pojo.result.ResultCodeEnum;
import ${package}.model.dto.${classUppercaseName}Dto;
import ${package}.model.entity.${classUppercaseName}Entity;
import ${package}.model.vo.${classUppercaseName}Vo;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Mono;
import cn.bunny.domain.pojo.result.PageResult;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.RequiredArgsConstructor;
import ${package}.service.${classUppercaseName}Service;
import ${package}.model.vo.result.PageResult;
import ${package}.model.vo.result.Result;
import ${package}.model.vo.result.ResultCodeEnum;
import java.util.List;
/**
@ -21,42 +25,42 @@ import java.util.List;
* @author ${author}
* @since ${date}
*/
@Tag(name = "${comment}" , description = "${comment}相关接口" )
@Tag(name = "${comment}", description = "${comment}相关接口")
@RestController
@RequestMapping("${requestMapping}/${classLowercaseName}" )
@RequestMapping("${requestMapping}/${lowerHyphenName}")
@RequiredArgsConstructor
public class ${classUppercaseName}Controller {
@Resource
private ${classUppercaseName}Service ${classLowercaseName}Service;
private final ${classUppercaseName}Service ${classLowercaseName}Service;
@Operation(summary = "分页查询${comment}" , description = "分页${comment}" )
@GetMapping("{page}/{limit}" )
@Operation(summary = "分页查询${comment}", description = "分页${comment}")
@GetMapping("{page}/{limit}")
public Result<PageResult<${classUppercaseName}Vo>> get${classUppercaseName}Page(
@Parameter(name = "page" , description = "当前页" , required = true)
@PathVariable("page" ) Integer page,
@Parameter(name = "limit" , description = "每页记录数" , required = true)
@PathVariable("limit" ) Integer limit,
@Parameter(name = "page", description = "当前页", required = true)
@PathVariable("page") Integer page,
@Parameter(name = "limit", description = "每页记录数", required = true)
@PathVariable("limit") Integer limit,
${classUppercaseName}Dto dto) {
Page<${classUppercaseName}> pageParams = new Page<>(page, limit);
Page<${classUppercaseName}Entity> pageParams = new Page<>(page, limit);
PageResult<${classUppercaseName}Vo> pageResult = ${classLowercaseName}Service.get${classUppercaseName}Page(pageParams, dto);
return Result.success(pageResult);
}
@Operation(summary = "添加${comment}" , description = "添加${comment}" )
@Operation(summary = "添加${comment}", description = "添加${comment}")
@PostMapping()
public Result<String> add${classUppercaseName}(@Valid @RequestBody ${classUppercaseName}to dto) {
public Result<String> add${classUppercaseName}(@Valid @RequestBody ${classUppercaseName}Dto dto) {
${classLowercaseName}Service.add${classUppercaseName}(dto);
return Result.success(ResultCodeEnum.ADD_SUCCESS);
}
@Operation(summary = "更新${comment}" , description = "更新${comment}" )
@Operation(summary = "更新${comment}", description = "更新${comment}")
@PutMapping()
public Result<String> update${classUppercaseName}(@Valid @RequestBody ${classUppercaseName}Dto dto) {
${classLowercaseName}Service.update${classUppercaseName}(dto);
return Result.success(ResultCodeEnum.UPDATE_SUCCESS);
}
@Operation(summary = "删除${comment}" , description = "删除${comment}" )
@Operation(summary = "删除${comment}", description = "删除${comment}")
@DeleteMapping()
public Result<String> delete${classUppercaseName}(@RequestBody List<Long> ids) {
${classLowercaseName}Service.delete${classUppercaseName}(ids);

View File

@ -1,13 +0,0 @@
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
@Schema(name = "${classUppercaseName}DTO对象", title = "${comment}", description = "${comment}的DTO对象")
public class ${classUppercaseName}Dto {
#foreach($field in ${columnInfoList})
@Schema(name = "${field.lowercaseName}", title = "${field.comment}")
private ${field.javaType} ${field.lowercaseName};
#end
}

View File

@ -1,14 +0,0 @@
@EqualsAndHashCode(callSuper = true)
@Getter
@Setter
@Accessors(chain = true)
@TableName("${tableName}")
@Schema(name = "${classUppercaseName}对象", title = "${comment}", description = "${comment}的实体类对象")
public class ${classUppercaseName} extends BaseEntity {
#foreach($field in ${columnInfoList})
@Schema(name = "${field.lowercaseName}", title = "${field.comment}")
private ${field.javaType} ${field.lowercaseName};
#end
}

View File

@ -1,13 +0,0 @@
@Data
@AllArgsConstructor
@NoArgsConstructor
@Schema(name = "${classUppercaseName}VO对象", title = "${comment}", description = "${comment}的VO对象")
public class ${classUppercaseName}Vo {
#foreach($field in ${columnInfoList})
@Schema(name = "${field.lowercaseName}", title = "${field.comment}")
private ${field.javaType} ${field.lowercaseName};
#end
}

View File

@ -4,7 +4,14 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.ibatis.annotations.Param;
import ${package}.model.dto.${classUppercaseName}Dto;
import ${package}.model.entity.${classUppercaseName}Entity;
import ${package}.model.vo.${classUppercaseName}Vo;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.apache.ibatis.annotations.Param;
import ${package}.model.vo.result.PageResult;
import ${package}.model.vo.result.Result;
import ${package}.model.vo.result.ResultCodeEnum;
import java.util.List;
/**
@ -16,15 +23,15 @@ import java.util.List;
* @since ${date}
*/
@Mapper
public interface ${classUppercaseName}Mapper extends BaseMapper<${classUppercaseName}> {
public interface ${classUppercaseName}Mapper extends BaseMapper<${classUppercaseName}Entity> {
/**
* * 分页查询${comment}内容
* 分页查询${comment}内容
*
* @param pageParams ${comment}分页参数
* @param dto ${comment}查询表单
* @return ${comment}分页结果
*/
IPage<${classUppercaseName}Vo> selectListByPage(@Param("page" ) Page<${classUppercaseName}> pageParams, @Param("dto" ) ${classUppercaseName}Dto dto);
IPage<${classUppercaseName}Vo> selectListByPage(@Param("page") Page<${classUppercaseName}Entity> pageParams, @Param("dto") ${classUppercaseName}Dto dto);
}

View File

@ -3,7 +3,7 @@
<mapper namespace="${package}.mapper.${classUppercaseName}Mapper">
<!-- 通用查询映射结果 -->
<resultMap id="BaseResultMap" type="${classUppercaseName}">
<resultMap id="BaseResultMap" type="${package}.model.entity.${classUppercaseName}Entity">
#foreach($field in ${columnInfoList})
<id column="${field.columnName}" property="${field.lowercaseName}"/>
#end
@ -15,7 +15,7 @@
</sql>
<!-- 分页查询${comment}内容 -->
<select id="selectListByPage" resultType="${voClassType}">
<select id="selectListByPage" resultType="${package}.model.vo.${classUppercaseName}Vo">
select
base.*,
create_user.username as create_username,

View File

@ -0,0 +1,25 @@
package ${package}.domain.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.time.LocalDateTime;
import java.math.BigDecimal;
import java.util.Date;
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
@Schema(name = "${classUppercaseName}DTO对象", title = "${comment}", description = "${comment}的DTO对象")
public class ${classUppercaseName}Dto {
#foreach($field in ${columnInfoList})
@Schema(name = "${field.lowercaseName}", title = "${field.comment}")
private ${field.javaType} ${field.lowercaseName};
#end
}

View File

@ -0,0 +1,31 @@
package ${package}.domain.entity;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.v3.oas.annotations.media.Schema;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.Accessors;
import java.time.LocalDateTime;
import java.math.BigDecimal;
import java.util.Date;
@Getter
@Setter
@Accessors(chain = true)
@TableName("${tableName}")
@Schema(name = "${classUppercaseName}对象", title = "${comment}", description = "${comment}的实体类对象")
public class ${classUppercaseName}Entity {
#foreach($field in ${columnInfoList})
@Schema(name = "${field.lowercaseName}", title = "${field.comment}")
#if($field.isPrimaryKey)
@TableId(type = IdType.ASSIGN_ID)
#end
private ${field.javaType} ${field.lowercaseName};
#end
}

View File

@ -0,0 +1,26 @@
package ${package}.domain.vo;
import java.util.Date;
import java.math.BigDecimal;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.time.LocalDateTime;
@Data
@AllArgsConstructor
@NoArgsConstructor
@Schema(name = "${classUppercaseName}VO对象", title = "${comment}", description = "${comment}的VO对象")
public class ${classUppercaseName}Vo {
#foreach($field in ${columnInfoList})
@Schema(name = "${field.lowercaseName}", title = "${field.comment}")
private ${field.javaType} ${field.lowercaseName};
#end
}

View File

@ -1,6 +1,5 @@
package ${package}.service.impl;
import cn.bunny.domain.pojo.result.PageResult;
import ${package}.mapper.${classUppercaseName}Mapper;
import ${package}.service.${classUppercaseName}Service;
import com.baomidou.mybatisplus.core.metadata.IPage;
@ -8,7 +7,14 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import ${package}.service.${classUppercaseName}Service;
import ${package}.model.dto.${classUppercaseName}Dto;
import ${package}.model.entity.${classUppercaseName}Entity;
import ${package}.model.vo.${classUppercaseName}Vo;
import ${package}.model.vo.result.PageResult;
import ${package}.model.vo.result.Result;
import ${package}.model.vo.result.ResultCodeEnum;
import java.util.List;
/**
@ -20,17 +26,18 @@ import java.util.List;
* @since ${date}
*/
@Service
public class ${classUppercaseName}ServiceImpl extends ServiceImpl<${classUppercaseName}Mapper, ${classUppercaseName}> implements ${classUppercaseName}Service {
@Transactional
public class ${classUppercaseName}ServiceImpl extends ServiceImpl<${classUppercaseName}Mapper, ${classUppercaseName}Entity> implements ${classUppercaseName}Service {
/**
* * ${comment} 服务实现类
* ${comment} 服务实现类
*
* @param pageParams ${comment}分页查询page对象
* @param dto ${comment}分页查询对象
* @return 查询分页${comment}返回对象
*/
@Override
public PageResult<${classUppercaseName}Vo> get${classUppercaseName}Page(Page<${classUppercaseName}> pageParams, ${classUppercaseName}Dto dto) {
public PageResult<${classUppercaseName}Vo> get${classUppercaseName}Page(Page<${classUppercaseName}Entity> pageParams, ${classUppercaseName}Dto dto) {
IPage<${classUppercaseName}Vo> page = baseMapper.selectListByPage(pageParams, dto);
return PageResult.<${classUppercaseName}Vo>builder()
@ -47,8 +54,8 @@ public class ${classUppercaseName}ServiceImpl extends ServiceImpl<${classUpperca
* @param dto ${comment}添加
*/
@Override
public void add${classUppercaseName}(@Valid ${classUppercaseName}AddDto dto) {
${classUppercaseName} ${classLowercaseName} =new ${classUppercaseName}();
public void add${classUppercaseName}(${classUppercaseName}Dto dto) {
${classUppercaseName}Entity ${classLowercaseName} = new ${classUppercaseName}Entity();
BeanUtils.copyProperties(dto, ${classLowercaseName});
save(${classLowercaseName});
}
@ -59,8 +66,8 @@ public class ${classUppercaseName}ServiceImpl extends ServiceImpl<${classUpperca
* @param dto ${comment}更新
*/
@Override
public void update${classUppercaseName}(@Valid ${classUppercaseName}UpdateDto dto) {
${classUppercaseName} ${classLowercaseName} =new ${classUppercaseName}();
public void update${classUppercaseName}(${classUppercaseName}Dto dto) {
${classUppercaseName}Entity ${classLowercaseName} = new ${classUppercaseName}Entity();
BeanUtils.copyProperties(dto, ${classLowercaseName});
updateById(${classLowercaseName});
}

View File

@ -1,11 +1,14 @@
package ${package}.service;
import cn.bunny.domain.entity.system.MenuIcon;
import cn.bunny.domain.pojo.result.PageResult;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.IService;
import jakarta.validation.Valid;
import ${package}.model.dto.${classUppercaseName}Dto;
import ${package}.model.entity.${classUppercaseName}Entity;
import ${package}.model.vo.${classUppercaseName}Vo;
import ${package}.model.vo.result.PageResult;
import ${package}.model.vo.result.Result;
import ${package}.model.vo.result.ResultCodeEnum;
import java.util.List;
/**
@ -16,28 +19,28 @@ import java.util.List;
* @author Bunny
* @since ${date}
*/
public interface ${classUppercaseName}Service extends IService<${classUppercaseName}> {
public interface ${classUppercaseName}Service extends IService<${classUppercaseName}Entity> {
/**
* 分页查询${comment}
*
* @return {@link ${classUppercaseName}Vo}
*/
PageResult<${classUppercaseName}Vo> get${classUppercaseName}Page(Page<${classUppercaseName}> pageParams, ${classUppercaseName}Dto dto);
PageResult<${classUppercaseName}Vo> get${classUppercaseName}Page(Page<${classUppercaseName}Entity> pageParams, ${classUppercaseName}Dto dto);
/**
* 添加${comment}
*
* @param dto 添加表单
* @param dto {@link ${classUppercaseName}Dto} 添加表单
*/
void add${classUppercaseName}(${classUppercaseName}AddDto dto);
void add${classUppercaseName}(${classUppercaseName}Dto dto);
/**
* 更新${comment}
*
* @param dto {@link ${classUppercaseName}UpdateDto}
* @param dto {@link ${classUppercaseName}Dto} 更新表单
*/
void update${classUppercaseName}(${classUppercaseName}UpdateDto dto);
void update${classUppercaseName}(${classUppercaseName}Dto dto);
/**
* 删除|批量删除${comment}类型