feat: remove code generator module (controller/service/mapper/btl templates/menu data)

This commit is contained in:
张家训
2026-08-21 14:25:24 +08:00
parent 345f4964b2
commit 1e3f062cd6
18 changed files with 4 additions and 1485 deletions
+2 -21
View File
@@ -1,6 +1,6 @@
# Freedom Admin
基于 **Spring Boot 2.7.10** 的后台管理系统后端服务,提供用户、角色、部门、权限等基础管理能力,并内置基于 Beetl 模板引擎的代码生成器。
基于 **Spring Boot 2.7.10** 的后台管理系统后端服务,提供用户、角色、部门、权限等基础管理能力。
## 技术栈
@@ -9,7 +9,7 @@
| 核心框架 | Spring Boot 2.7.10 |
| 安全框架 | Spring Security 3.3.2 + JWT(jjwt 0.9.1) |
| ORM | MyBatis-Plus 3.5.7 + PageHelper 2.1.0 |
| 模板引擎 | Thymeleaf(登录页等)、Beetl 3.16.2(代码生成) |
| 模板引擎 | Thymeleaf(登录页等) |
| 数据库 | MySQL 8.0(utf8mb4) |
| 连接池 | HikariCP |
| 其他 | Lombok、Fastjson、Guava、Spring Mail |
@@ -32,7 +32,6 @@ freedom-admin
│ └── util/ # 工具类
└── src/main/resources/
├── mapper/ # MyBatis XML 映射文件
├── btl/ # 代码生成 Beetl 模板
├── logback-spring.xml # 日志配置(控制台 UTF-8)
└── application.yml # 应用配置
```
@@ -54,7 +53,6 @@ freedom-admin
- **角色管理**:角色 CRUD、角色-权限绑定
- **部门管理**:树形部门结构
- **权限管理**:菜单 / 权限点维护,驱动前端动态路由
- **代码生成器**:读取数据库表结构,一键生成 Controller / Service / Mapper / Entity / Vue 等全套代码
- **邮件服务**:基于 Spring Mail 的邮件发送能力
- **系统特性**:统一异常处理、PageHelper 分页、逻辑删除、接口权限控制
@@ -101,23 +99,6 @@ java -jar target/freedom-admin-1.0.1.jar
启动后服务地址:`http://localhost:8800`
## 代码生成器 API
| 接口 | 方法 | 说明 |
| ---- | ---- | ---- |
| `/generator/findListWithPage` | GET | 分页查询数据库表列表 |
| `/generator/getTableSelectList` | GET | 获取表下拉列表 |
| `/generator/execute` | POST | 执行代码生成 |
生成参数示例:
```
POST /generator/execute
Content-Type: application/x-www-form-urlencoded
tableName=your_table_name&ruleStr=[{"rule":"value"}]
```
## 注意事项
- JWT 密钥与过期时间在 `application.yml` 的 `jwt` 节点配置,生产环境请务必更换密钥。
-21
View File
@@ -96,27 +96,6 @@ erDiagram
boolean delFlag
}
%% 生成器配置表
GeneratorConfig {
bigint id PK
varchar tableName
varchar tableComment
varchar author
varchar packageName
varchar moduleName
varchar functionName
varchar entityName
varchar mapperName
varchar serviceName
varchar serviceImplName
varchar controllerName
varchar createBy
datetime createDate
varchar updateBy
datetime updateDate
boolean delFlag
}
%% 关系定义
TSysUser ||--o{ TSysUserRole : "拥有"
TSysRole ||--o{ TSysUserRole : "分配"
+2 -6
View File
@@ -158,9 +158,7 @@ VALUES
(2, 1, 'sys:user', '用户管理', '用户管理', 2, 'ios-person', '/sys/user', 'sys/user/user-list', 1, 'admin', NOW(), 0),
(3, 1, 'sys:role', '角色管理', '角色管理', 2, 'ios-people', '/sys/role', 'sys/role/role-list', 2, 'admin', NOW(), 0),
(4, 1, 'sys:dept', '部门管理', '部门管理', 2, 'ios-home', '/sys/dept', 'sys/dept/dept-list', 3, 'admin', NOW(), 0),
(5, 1, 'sys:permission', '权限管理', '权限管理', 2, 'ios-key', '/sys/permission', 'sys/permission/permission-list', 4, 'admin', NOW(), 0),
(6, 0, 'generator', '代码生成', '代码生成器', 1, 'ios-hammer', '', '', 2, 'admin', NOW(), 0),
(7, 6, 'gen:code', '代码生成', '代码生成器', 2, 'ios-cog', '/code/index', 'code/index', 1, 'admin', NOW(), 0);
(5, 1, 'sys:permission', '权限管理', '权限管理', 2, 'ios-key', '/sys/permission', 'sys/permission/permission-list', 4, 'admin', NOW(), 0);
-- 用户-角色关联:admin -> 超级管理员
INSERT INTO `t_sys_user_role` (`id`, `user_id`, `role_id`, `create_by`, `create_time`)
@@ -173,6 +171,4 @@ VALUES
(2, 1, 2, 'admin', NOW()),
(3, 1, 3, 'admin', NOW()),
(4, 1, 4, 'admin', NOW()),
(5, 1, 5, 'admin', NOW()),
(6, 1, 6, 'admin', NOW()),
(7, 1, 7, 'admin', NOW());
(5, 1, 5, 'admin', NOW());
@@ -1,541 +0,0 @@
package com.freedom.admin.controller;
import com.alibaba.fastjson.JSON;
import com.freedom.admin.base.BaseController;
import com.freedom.admin.common.Result;
import com.freedom.admin.entity.GeneratorConfig;
import com.freedom.admin.entity.GeneratorTableVO;
import com.freedom.admin.service.GeneratorService;
import com.github.pagehelper.PageInfo;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.annotations.Param;
import org.beetl.core.Configuration;
import org.beetl.core.GroupTemplate;
import org.beetl.core.Template;
import org.beetl.core.resource.ClasspathResourceLoader;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.security.PermitAll;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* @description: TODO
* @author: zhangjiaxun
* @date: 2021年03月20日 20:05:00
*/
@RestController
@RequestMapping("generator")
public class GeneratorController extends BaseController {
@Autowired
private GeneratorService generatorService;
/**
* 列表查询
*
* @param pageNum 当前页
* @param pageSize 页数
* @return Result
*/
@RequestMapping("findListWithPage")
@PermitAll
public Result<GeneratorTableVO> findListWithPage(@Param("pageNum") int pageNum,
@Param("pageSize") int pageSize,
GeneratorTableVO generatorTableVO) {
PageInfo<GeneratorTableVO> pageInfo = generatorService.getTableListWithPage(pageNum, pageSize, generatorTableVO);
return Result.ok().setData(pageInfo);
}
/**
* 获取table下拉列表数据
*
* @return Result
*/
@RequestMapping("getTableSelectList")
@PermitAll
public Result<Result> getTableSelectList() {
List<Map<String, Object>> tableSelectList = generatorService.getTableSelectList();
return Result.ok().setData(tableSelectList);
}
/**
* 执行代码生成操作
* @param tableName
* @param ruleStr
* @return
*/
@RequestMapping("execute")
@PermitAll
public Result<GeneratorTableVO> execute(String tableName, String ruleStr) {
// 转换
List<Map<String, Object>> ruleList = (List<Map<String, Object>>) JSON.parse(ruleStr);
//模板路径
ClasspathResourceLoader resourceLoader = new ClasspathResourceLoader("/btl/");
Configuration cfg = null;
try {
cfg = Configuration.defaultConfiguration();
} catch (IOException e) {
e.printStackTrace();
}
GroupTemplate gt = new GroupTemplate(resourceLoader, cfg);
// 生成代码
Map<String,Object> result = null;
try {
result = generateCode(gt, tableName, ruleList);
} catch (Exception e) {
e.printStackTrace();
}
return Result.ok().setData(result);
}
/**
* 生成代码
*
* @param gt
* @throws IOException
*/
private Map<String,Object> generateCode(GroupTemplate gt,
String tableName,
List<Map<String, Object>> ruleList) throws Exception {
GeneratorConfig generatorConfig = new GeneratorConfig();
// 前端代码文件生成配置
generatorConfig.setFrontProjectDir("D:/workspace-sfzbs/freedom-web");
generatorConfig.setViewParentDir("info");
// 后端代码文件生成配置
generatorConfig.setAfterProjectDir("D:/workspace-sfzbs/freedom-admin");
generatorConfig.setMapperPackage("com.freedom.admin.mapper");
generatorConfig.setEntityPackage("com.freedom.admin.entity");
generatorConfig.setServicePackage("com.freedom.admin.service");
generatorConfig.setServiceImplPackage("com.freedom.admin.service.impl");
generatorConfig.setControllerPackage("com.freedom.admin.controller");
generatorConfig.setBasePackage("com.freedom.admin.base");
generatorConfig.setAuthor("zhangjiaxun");
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy/MM/dd hh:mm");
generatorConfig.setDate(simpleDateFormat.toString());
// 选用模板
generatorConfig.setUsingTemplate("apiJsTemplate,viewTemplate,mapperXmlTemplate,mapperTemplate,entityTemplate,serviceTemplate,serviceImplTemplate,controllerTemplate");
generatorConfig.setTableName(tableName);
generatorConfig.setClassName(underlineToCamel(tableName,false));
generatorConfig.setClassNameLowerCase(underlineToCamel(tableName,true));
generatorConfig.setResourceName(underlineToHyphen(tableName));
Map<String,Object> result = new HashMap<>();
if (generatorConfig.getUsingTemplate().contains("apiJsTemplate")){
Template apiJsTemplate = gt.getTemplate("apiJs.btl");
result.put(".js",generateApiJs(apiJsTemplate, generatorConfig, ruleList));
}
if (generatorConfig.getUsingTemplate().contains("viewTemplate")){
Template viewTemplate = gt.getTemplate("view.btl");
result.put(".vue",generateView(viewTemplate, generatorConfig, ruleList));
}
if (generatorConfig.getUsingTemplate().contains("mapperXmlTemplate")){
Template mapperXmlTemplate = gt.getTemplate("mapperXml.btl");
result.put("mapper.xml",generateMapperXml(mapperXmlTemplate, generatorConfig, ruleList));
}
if (generatorConfig.getUsingTemplate().contains("mapperTemplate")){
Template mapperTemplate = gt.getTemplate("mapper.btl");
result.put("mapper.java",generateMapper(mapperTemplate, generatorConfig));
}
if (generatorConfig.getUsingTemplate().contains("entityTemplate")){
Template entityTemplate= gt.getTemplate("entity.btl");
result.put("entity.java",generateEntity(entityTemplate, generatorConfig, ruleList));
}
if (generatorConfig.getUsingTemplate().contains("serviceTemplate")){
Template serviceTemplate = gt.getTemplate("service.btl");
result.put("service.java",generateService(serviceTemplate, generatorConfig));
}
if (generatorConfig.getUsingTemplate().contains("serviceImplTemplate")){
Template serviceImplTemplate = gt.getTemplate("serviceImpl.btl");
result.put("serviceImpl.java",generateServiceImpl(serviceImplTemplate, generatorConfig));
}
if (generatorConfig.getUsingTemplate().contains("controllerTemplate")){
Template controllerTemplate = gt.getTemplate("controller.btl");
result.put("controller.java",generateController(controllerTemplate, generatorConfig));
}
return result;
}
/**
* 代码生成:generateApiJs
*/
private String generateApiJs(Template apiJsTemplate,
GeneratorConfig generatorConfig,
List<Map<String,Object>> ruleList) throws IOException {
OutputStream out = null;
//生成mapper代码
apiJsTemplate.binding("generatorConfig", generatorConfig);
apiJsTemplate.binding("ruleList", ruleList);
String apiJsResult = apiJsTemplate.render();
//创建文件
String apiJsFileUrl = generatorConfig.getFrontProjectDir() + "/src/api/"+ generatorConfig.getViewParentDir() +"/" + generatorConfig.getResourceName() + ".js";
File apiJsFile = new File(apiJsFileUrl);
File apiJsDir = apiJsFile.getParentFile();
if (!apiJsDir.exists()) {
apiJsDir.mkdirs();
}
if (apiJsFile.exists()) {
apiJsFile.delete();
}
if (!apiJsFile.exists()) {
// 若文件存在则不重新生成
apiJsFile.createNewFile();
out = new FileOutputStream(apiJsFile);
apiJsTemplate.renderTo(out);
}
if (out != null) {
out.close();
}
return apiJsFileUrl;
}
/**
* 代码生成:generateView
*/
private String generateView(Template viewTemplate,
GeneratorConfig generatorConfig,
List<Map<String,Object>> ruleList) throws IOException {
OutputStream out = null;
//生成mapper代码
viewTemplate.binding("generatorConfig", generatorConfig);
viewTemplate.binding("ruleList", ruleList);
String viewResult = viewTemplate.render();
//创建文件
String viewFileUrl = generatorConfig.getFrontProjectDir() + "/src/view/" + generatorConfig.getViewParentDir() + "/" + generatorConfig.getResourceName() + ".vue";
File viewFile = new File(viewFileUrl);
File viewDir = viewFile.getParentFile();
if (!viewDir.exists()) {
viewDir.mkdirs();
}
if (viewFile.exists()) {
viewFile.delete();
}
if (!viewFile.exists()) {
// 若文件存在则不重新生成
viewFile.createNewFile();
out = new FileOutputStream(viewFile);
viewTemplate.renderTo(out);
}
if (out != null) {
out.close();
}
return viewFileUrl;
}
/**
* 代码生成:generateMapperXml
*/
private String generateMapperXml(Template mapperXmlTemplate,
GeneratorConfig generatorConfig,
List<Map<String,Object>> ruleList) throws IOException {
OutputStream out = null;
//生成mapper代码
mapperXmlTemplate.binding("generatorConfig", generatorConfig);
mapperXmlTemplate.binding("ruleList", ruleList);
String mapperXmlResult = mapperXmlTemplate.render();
//创建文件
String mapperXmlFileUrl = generatorConfig.getAfterProjectDir() + "/src/main/resources/mapper/" + generatorConfig.getClassName() + "Mapper.xml";
File mapperXmlFile = new File(mapperXmlFileUrl);
File mapperXmlDir = mapperXmlFile.getParentFile();
if (!mapperXmlDir.exists()) {
mapperXmlDir.mkdirs();
}
if (mapperXmlFile.exists()) {
mapperXmlFile.delete();
}
if (!mapperXmlFile.exists()) {
// 若文件存在则不重新生成
mapperXmlFile.createNewFile();
out = new FileOutputStream(mapperXmlFile);
mapperXmlTemplate.renderTo(out);
}
if (out != null) {
out.close();
}
return mapperXmlFileUrl;
}
/**
* 代码生成:generateMapper
*/
private String generateMapper(Template mapperTemplate, GeneratorConfig generatorConfig) throws IOException {
OutputStream out = null;
//生成mapper代码
mapperTemplate.binding("generatorConfig", generatorConfig);
String mapperResult = mapperTemplate.render();
//创建文件
String mapperFileUrl = generatorConfig.getAfterProjectDir() + "/src/main/java/" + dotToLine(generatorConfig.getMapperPackage()) + "/" + generatorConfig.getClassName() + "Mapper.java";
File mapperFile = new File(mapperFileUrl);
File mapperDir = mapperFile.getParentFile();
if (!mapperDir.exists()) {
mapperDir.mkdirs();
}
if (mapperFile.exists()) {
mapperFile.delete();
}
if (!mapperFile.exists()) {
// 若文件存在则不重新生成
mapperFile.createNewFile();
out = new FileOutputStream(mapperFile);
mapperTemplate.renderTo(out);
}
if (out != null) {
out.close();
}
return mapperFileUrl;
}
/**
* 代码生成:generateEntity
*/
private String generateEntity(Template entityTemplate,
GeneratorConfig generatorConfig,
List<Map<String,Object>> ruleList) throws IOException {
OutputStream out = null;
//生成generatorConfig代码
entityTemplate.binding("generatorConfig", generatorConfig);
entityTemplate.binding("ruleList", ruleList);
String generatorConfigResult = entityTemplate.render();
//创建文件
String entityFileUrl = generatorConfig.getAfterProjectDir() + "/src/main/java/" + dotToLine(generatorConfig.getEntityPackage()) + "/" + generatorConfig.getClassName() + ".java";
File entityFile = new File(entityFileUrl);
File entityDir = entityFile.getParentFile();
if (!entityDir.exists()) {
entityDir.mkdirs();
}
if (entityFile.exists()) {
entityFile.delete();
}
if (!entityFile.exists()) {
// 若文件存在则不重新生成
entityFile.createNewFile();
out = new FileOutputStream(entityFile);
entityTemplate.renderTo(out);
}
if (out != null) {
out.close();
}
return entityFileUrl;
}
/**
* 代码生成:generateService
*/
private String generateService(Template serviceTemplate, GeneratorConfig generatorConfig) throws IOException {
OutputStream out = null;
//生成service代码
serviceTemplate.binding("generatorConfig", generatorConfig);
String serviceResult = serviceTemplate.render();
//创建文件
String serviceFileUrl = generatorConfig.getAfterProjectDir() + "/src/main/java/" + dotToLine(generatorConfig.getServicePackage()) + "/" + generatorConfig.getClassName() + "Service.java";
File serviceFile = new File(serviceFileUrl);
File serviceDir = serviceFile.getParentFile();
if (!serviceDir.exists()) {
serviceDir.mkdirs();
}
if (serviceFile.exists()) {
serviceFile.delete();
}
if (!serviceFile.exists()) {
// 若文件存在则不重新生成
serviceFile.createNewFile();
out = new FileOutputStream(serviceFile);
serviceTemplate.renderTo(out);
}
if (out != null) {
out.close();
}
return serviceFileUrl;
}
/**
* 代码生成:generateServiceImpl
*/
private String generateServiceImpl(Template serviceImplTemplate, GeneratorConfig generatorConfig) throws IOException {
OutputStream out = null;
//生成serviceImpl代码
serviceImplTemplate.binding("generatorConfig", generatorConfig);
String serviceImplResult = serviceImplTemplate.render();
//创建文件
String serviceImplFileUrl = generatorConfig.getAfterProjectDir() + "/src/main/java/" + dotToLine(generatorConfig.getServiceImplPackage()) + "/" + generatorConfig.getClassName() + "ServiceImpl.java";
File serviceImplFile = new File(serviceImplFileUrl);
File serviceImplDir = serviceImplFile.getParentFile();
if (!serviceImplDir.exists()) {
serviceImplDir.mkdirs();
}
if (serviceImplFile.exists()) {
serviceImplFile.delete();
}
if (!serviceImplFile.exists()) {
// 若文件存在则不重新生成
serviceImplFile.createNewFile();
out = new FileOutputStream(serviceImplFile);
serviceImplTemplate.renderTo(out);
}
if (out != null) {
out.close();
}
return serviceImplFileUrl;
}
/**
* 代码生成:generateController
*/
private String generateController(Template controllerTemplate, GeneratorConfig generatorConfig) throws IOException {
OutputStream out = null;
//生成controller代码
controllerTemplate.binding("generatorConfig", generatorConfig);
String controllerResult = controllerTemplate.render();
//创建文件
String controllerFileUrl = generatorConfig.getAfterProjectDir() + "/src/main/java/" + dotToLine(generatorConfig.getControllerPackage()) + "/" + generatorConfig.getClassName() + "Controller.java";
File controllerFile = new File(controllerFileUrl);
File controllerDir = controllerFile.getParentFile();
if (!controllerDir.exists()) {
controllerDir.mkdirs();
}
if (controllerFile.exists()) {
controllerFile.delete();
}
if (!controllerFile.exists()) {
// 若文件存在则不重新生成
controllerFile.createNewFile();
out = new FileOutputStream(controllerFile);
controllerTemplate.renderTo(out);
}
if (out != null) {
out.close();
}
return controllerFileUrl;
}
/**
* 工具方法:点转斜线
*
* @param str
*/
private String dotToLine(String str) {
return str.replace(".", "/");
}
/**
* 工具方法:下划线_转连字符-
*
* @param str
*/
private String underlineToHyphen(String str) {
return str.replace("_", "-");
}
/**
* 下划线转驼峰法
* @param line 源字符串
* @param smallCamel 大小驼峰,是否为小驼峰
* @return 转换后的字符串
*/
private String underlineToCamel(String line,boolean smallCamel){
if(line==null||"".equals(line)){
return "";
}
StringBuffer sb = new StringBuffer();
Pattern pattern = Pattern.compile("([A-Za-z\\d]+)(_)?");
Matcher matcher = pattern.matcher(line);
while(matcher.find()){
String word = matcher.group();
sb.append(smallCamel&&matcher.start()==0?Character.toLowerCase(word.charAt(0)):Character.toUpperCase(word.charAt(0)));
int index=word.lastIndexOf('_');
if(index>0){
sb.append(word.substring(1, index).toLowerCase());
}else{
sb.append(word.substring(1).toLowerCase());
}
}
return sb.toString();
}
/**
* 工具方法:驼峰法转下划线
*
* @param str
*/
private String cameltoUnderline(String str) {
if (StringUtils.isBlank(str)) {
return "";
}
if (str.length() == 1) {
return str.toLowerCase();
}
StringBuffer sb = new StringBuffer();
for (int i = 1; i < str.length(); i++) {
if (Character.isUpperCase(str.charAt(i))) {
sb.append("_" + Character.toLowerCase(str.charAt(i)));
} else {
sb.append(str.charAt(i));
}
}
return (str.charAt(0) + sb.toString()).toLowerCase();
}
/**
* 工具方法:首字母小写
*
* @param str
*/
private String first2LowerCase(String str) {
if (StringUtils.isBlank(str)) {
return "";
}
if (str.length() == 1) {
return str.toLowerCase();
}
StringBuffer sb = new StringBuffer();
sb.append(Character.toLowerCase(str.charAt(0)));
sb.append(str.substring(1, str.length()));
return sb.toString();
}
}
@@ -1,103 +0,0 @@
package com.freedom.admin.entity;
import lombok.Data;
/**
* @author zhangjiaxun
* @date 2020/06/19 14:00
* @description 生成代码的配置
*/
@Data
public class GeneratorConfig {
/**
* 前端项目所在系统路径
* */
private String frontProjectDir;
/**
* 后端项目所在系统路径
* */
private String afterProjectDir;
/**
* mapper文件生成路径
* */
private String mapperPackage;
/**
* entity文件生成路径
* */
private String entityPackage;
/**
* service文件生成路径
* */
private String servicePackage;
/**
* serviceImpl文件生成路径
* */
private String serviceImplPackage;
/**
* controller文件生成路径
* */
private String controllerPackage;
/**
* 通用mapper文件路径
* */
private String basePackage;
/**
* config文件路径
* */
private String configPackage;
/**
* author作者名称
* */
private String author;
/**
* date日期
* */
private String date;
/**
* viewParentDir描述
* */
private String description;
/**
* 类名
* */
private String className;
/**
* 类名-小驼峰
* */
private String classNameLowerCase;
/**
* 表名
* */
private String tableName;
/**
* 资源名
* */
private String resourceName;
/**
* 视图父目录
* */
private String viewParentDir;
/**
* 使用模板
* */
private String usingTemplate;
}
@@ -1,58 +0,0 @@
package com.freedom.admin.entity;
import lombok.Data;
/**
* @description: 生成数据表的信息-值对象
* @author: zhangjiaxun
* @date: 2021年03月20日 20:23:00
*/
@Data
public class GeneratorTableVO {
/**
* 表名
*/
private String tableName;
/**
* 字段名
*/
private String columnName;
/**
* 字段类型
*/
private String columnType;
/**
* 数据类型
*/
private String dataType;
/**
* 字段长度
*/
private Double characterMaximumLength;
/**
* 是否主键
*/
private String isColumnKey;
/**
* 是否为空
*/
private String isNullable;
/**
* 字段默认值
*/
private String columnDefault;
/**
* 注释
*/
private String columnComment;
}
@@ -1,29 +0,0 @@
package com.freedom.admin.mapper;
import com.freedom.admin.entity.GeneratorTableVO;
import java.util.List;
import java.util.Map;
/**
* @description: TODO
* @author: zhangjiaxun
* @date: 2021年03月20日 22:28:00
*/
public interface GeneratorMapper {
/**
* 分页查询mysql数据表
*
* @return List<Map<String, String>>
* */
List<GeneratorTableVO> getTableListWithPage(GeneratorTableVO generatorTableVO);
/**
* 获取mysql表数据下拉列表数据
*
* @return List<Map<String, String>>
* */
List<Map<String, Object>> getTableSelectList();
}
@@ -1,30 +0,0 @@
package com.freedom.admin.service;
import com.freedom.admin.entity.GeneratorTableVO;
import com.github.pagehelper.PageInfo;
import java.util.List;
import java.util.Map;
/**
* @author: zhangjiaxun
* @date: 2021年03月20日 22:21:00
* @description: 业务层接口-代码生成业务接口
*/
public interface GeneratorService {
/**
* 分页查询mysql数据表
*
* @return List<Map<String, String>>
* */
PageInfo<GeneratorTableVO> getTableListWithPage(int pageNum, int pageSize, GeneratorTableVO generatorTableVO);
/**
* 获取mysql表数据下拉列表数据
*
* @return List<Map<String, String>>
* */
List<Map<String, Object>> getTableSelectList();
}
@@ -1,40 +0,0 @@
package com.freedom.admin.service.impl;
import com.freedom.admin.entity.GeneratorTableVO;
import com.freedom.admin.mapper.GeneratorMapper;
import com.freedom.admin.service.GeneratorService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Map;
/**
* @author zhangjiaxun
* @date 2021/2/4 9:29
* @description 业务层实现-代码生成业务
*/
@Service
@Log4j2
public class GeneratorServiceImpl implements GeneratorService {
@Autowired
private GeneratorMapper generatorMapper;
@Override
public PageInfo<GeneratorTableVO> getTableListWithPage(int pageNum, int pageSize, GeneratorTableVO generatorTableVO) {
PageHelper.startPage(pageNum, pageSize);
List<GeneratorTableVO> list = generatorMapper.getTableListWithPage(generatorTableVO);
PageInfo<GeneratorTableVO> pageInfo = new PageInfo<>(list);
return pageInfo;
}
@Override
public List<Map<String, Object>> getTableSelectList() {
return generatorMapper.getTableSelectList();
}
}
-50
View File
@@ -1,50 +0,0 @@
import axios from '@/libs/api.request'
import {getToken} from "@/libs/util"
/** 获取列表 **/
export const getDataList = (data) => {
return axios.request({
url: '${generatorConfig.resourceName}/findPageList',
headers: {
"Authorization": getToken()
},
data: data,
method: 'post'
})
}
/** 新增 **/
export const add = (data) => {
return axios.request({
url: '${generatorConfig.resourceName}/add',
headers: {
"Authorization": getToken()
},
data: data,
method: 'post'
})
}
/** 更新 **/
export const update = (data) => {
return axios.request({
url: '${generatorConfig.resourceName}/update',
headers: {
"Authorization": getToken()
},
data: data,
method: 'post'
})
}
/** 删除 **/
export const remove = (data) => {
return axios.request({
url: '${generatorConfig.resourceName}/remove',
headers: {
"Authorization": getToken()
},
data: data,
method: 'post'
})
}
-98
View File
@@ -1,98 +0,0 @@
package com.freedom.admin.controller;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import ${generatorConfig.basePackage}.BaseController;
import com.freedom.admin.common.Result;
import ${generatorConfig.entityPackage}.${generatorConfig.className};
import ${generatorConfig.servicePackage}.${generatorConfig.className}Service;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.annotations.Param;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.security.PermitAll;
import java.util.Date;
import java.util.List;
import java.util.Map;
/**
* @author ${generatorConfig.author}
* @date ${generatorConfig.date}
* @description 控制层-${generatorConfig.description}
*/
@RestController
@RequestMapping("${generatorConfig.resourceName}")
@Log4j2
public class ${generatorConfig.className}Controller extends BaseController {
@Autowired
private ${generatorConfig.className}Service ${generatorConfig.classNameLowerCase}Service;
/**
* 获取数据列表
* */
@RequestMapping("/findPageList")
@PermitAll
public Result<${generatorConfig.className}> findPageList(@Param("pageNum") long pageNum,
@Param("pageSize") long pageSize,
${generatorConfig.className} ${generatorConfig.classNameLowerCase}){
QueryWrapper<${generatorConfig.className}> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("del_flag",0);
Page<${generatorConfig.className}> page = ${generatorConfig.classNameLowerCase}Service.page(new Page<>(pageNum,pageSize), queryWrapper);
return Result.ok().setData(page);
}
/**
* 新增
* */
@RequestMapping("/add")
@PermitAll
public Result<${generatorConfig.className}> add(${generatorConfig.className} ${generatorConfig.classNameLowerCase}){
try {
${generatorConfig.classNameLowerCase}.setCreateBy(getUsername());
${generatorConfig.classNameLowerCase}.setCreateDate(new Date());
boolean save = ${generatorConfig.classNameLowerCase}Service.save(${generatorConfig.classNameLowerCase});
return Result.ok().setData(save);
} catch (Exception e) {
return Result.error();
}
}
/**
* 更新
* */
@RequestMapping("/update")
@PermitAll
public Result update(${generatorConfig.className} ${generatorConfig.classNameLowerCase}){
try {
${generatorConfig.classNameLowerCase}.setUpdateBy(getUsername());
${generatorConfig.classNameLowerCase}.setUpdateDate(new Date());
boolean update = ${generatorConfig.classNameLowerCase}Service.updateById(${generatorConfig.classNameLowerCase});
return Result.ok().setData(update);
} catch (Exception e) {
return Result.error();
}
}
/**
* 删除
* */
@RequestMapping("/remove")
@PermitAll
public Result remove(${generatorConfig.className} ${generatorConfig.classNameLowerCase}){
try {
${generatorConfig.classNameLowerCase}.setUpdateBy(getUsername());
${generatorConfig.classNameLowerCase}.setUpdateDate(new Date());
boolean remove = ${generatorConfig.classNameLowerCase}Service.removeById(${generatorConfig.classNameLowerCase}.getId());
return Result.ok().setData(remove);
} catch (Exception e) {
return Result.error();
}
}
}
-27
View File
@@ -1,27 +0,0 @@
package com.freedom.admin.entity;
import java.io.Serializable;
import java.util.Date;
import lombok.Data;
/**
* @author ${generatorConfig.author}
* @date ${generatorConfig.date}
* @description ${generatorConfig.tableName} ${generatorConfig.description}
*/
@Data
public class ${generatorConfig.className} implements Serializable {
<%
for(rule in ruleList){
%>
/**
* ${rule.variableComment}
*
*/
private ${rule.variableType} ${rule.variableName};
<%
}
%>
private static final long serialVersionUID = 1L;
}
-13
View File
@@ -1,13 +0,0 @@
package com.freedom.admin.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import ${generatorConfig.entityPackage}.${generatorConfig.className};
/**
* @author ${generatorConfig.author}
* @date ${generatorConfig.date}
* @description 数据访问层-${generatorConfig.description}
*/
public interface ${generatorConfig.className}Mapper extends BaseMapper<${generatorConfig.className}> {
}
-30
View File
@@ -1,30 +0,0 @@
<?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="${generatorConfig.mapperPackage}.${generatorConfig.className}Mapper">
<resultMap id="BaseResultMap" type="${generatorConfig.entityPackage}.${generatorConfig.className}">
<%
for(rule in ruleList){
%>
<result column="${rule.columnName}" jdbcType="${rule.variableJdbcType}" property="${rule.variableName}" />
<%
}
%>
</resultMap>
<sql id="Base_Column_List">
<%
for(rule in ruleList){
if(rule.index == ruleList.~size){
%>
a.${rule.columnName} AS ${rule.variableName}
<%
}else{
%>
a.${rule.columnName} AS ${rule.variableName},
<%
}
}
%>
</sql>
</mapper>
-13
View File
@@ -1,13 +0,0 @@
package com.freedom.admin.service;
import com.baomidou.mybatisplus.extension.service.IService;
import ${generatorConfig.entityPackage}.${generatorConfig.className};
/**
* @author ${generatorConfig.author}
* @date ${generatorConfig.date}
* @description 业务接口层-${generatorConfig.description}
*/
public interface ${generatorConfig.className}Service extends IService<${generatorConfig.className}> {
}
-18
View File
@@ -1,18 +0,0 @@
package com.freedom.admin.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import ${generatorConfig.entityPackage}.${generatorConfig.className};
import ${generatorConfig.mapperPackage}.${generatorConfig.className}Mapper;
import ${generatorConfig.servicePackage}.${generatorConfig.className}Service;
import lombok.extern.log4j.Log4j2;
import org.springframework.stereotype.Service;
/**
* @author ${generatorConfig.author}
* @date ${generatorConfig.date}
* @description 业务层实现-${generatorConfig.description}
*/
@Service
public class ${generatorConfig.className}ServiceImpl extends ServiceImpl<${generatorConfig.className}Mapper, ${generatorConfig.className}> implements ${generatorConfig.className}Service {
}
-350
View File
@@ -1,350 +0,0 @@
<template>
<div>
<!-- 查询区域 start -->
<div class="option">
<%
for(rule in ruleList){
if(rule.variableIsQuery == true && rule.variableName != 'id'){
%>
<Input v-model="search.${rule.variableName}" class="short-input" clearable placeholder="${rule.variableComment}"/>
<%
}
}
%>
<Button class="free" type="primary" icon="ios-search" @click="getDataList()">查询</Button>
<Button class="free" type="primary" icon="md-refresh" @click="refresh()">重置</Button>
</div>
<!-- 查询区域 end -->
<!-- 列表区域 start -->
<div class="table-button-list">
<Button class="free" type="info" icon="md-add" @click="toAdd">添加</Button>
</div>
<Table :height="fixedHeader ? autoHeight : ''"
border ref="table"
:columns="listColumns"
:data="dataList"
:loading="tableLoading">
<template slot-scope="{ row, index }" slot="action">
<Button type="primary"
size="small"
style="margin-right: 5px"
icon="ios-create"
@click="toEdit(index)">编辑
</Button>
<Poptip
confirm
title="您确定要删除吗?"
:transfer="true"
@on-ok="toDelete(index)"
>
<Button type="error" size="small" icon="md-trash">删除</Button>
</Poptip>
</template>
</Table>
<div class="pagination">
<Page show-elevator show-sizer show-total
:total="pageTotal" :page-size="pageParam.pageSize"
:current="pageParam.pageNum"
@on-page-size-change="changePageSize" @on-change="changePage"></Page>
</div>
<!-- 列表区域 end -->
<!-- Modal区域 start -->
<Modal v-model="modal" :title="modalTitle" width="1000" :mask-closable="false" @on-cancel="cancel()">
<Form :rules="ruleCustom" :model="formItem" ref="formItem" :label-width="120">
<Row :gutter="24">
<%
for(rule in ruleList){
if(rule.variableIsFormItem == true){
if(rule.variableType == 'String' && rule.variableName != 'id'){
if(rule.variableName == 'remark' || rule.variableName == 'content'){
%>
<Col span="24">
<FormItem label="${rule.variableComment}" prop="${rule.variableName}">
<Input type="textarea" maxlength="500" show-word-limit :rows="4" class="form-textarea"
v-model="formItem.${rule.variableName}" placeholder="请输入${rule.variableComment}"/>
</FormItem>
</Col>
<%
}else{
%>
<Col span="12">
<FormItem label="${rule.variableComment}" prop="${rule.variableName}">
<Input type="text" class="form-input" v-model="formItem.${rule.variableName}" placeholder="请输入${rule.variableComment}"/>
</FormItem>
</Col>
<%
}
}
if(rule.gVariableType == 'Integer' || rule.gVariableType == 'Float' || rule.gVariableType == 'Double'){
%>
<Col span="12">
<FormItem label="${rule.variableComment}" prop="${rule.variableName}">
<InputNumber class="short-input"
v-model="formItem.${rule.variableName}"
:step="100"
:formatter="value => `\${value}`.replace(/\B(?=(\d{3})+(?!\d))/g, ',')"
:parser="value => value.replace(/\$\s?|(,*)/g, '')"
placeholder="请输入${rule.variableComment}"/>
</FormItem>
</Col>
<%
}
if(rule.gVariableType == 'Date'){
%>
<Col span="12">
<FormItem label="${rule.variableComment}" prop="${rule.variableName}">
<DatePicker type="date"
class="form-input"
format="yyyy-MM-dd"
v-model="formItem.${rule.variableName}"
placeholder="${rule.variableComment}">
</DatePicker>
</FormItem>
</Col>
<%
}
}
}
%>
</Row>
</Form>
<div slot="footer">
<Button type="text" size="large" @click="cancel">取消</Button>
<Button type="primary" size="large"
:loading="submitLoading"
@click="submit('formItem')">确定
</Button>
</div>
</Modal>
<!-- Modal区域 end -->
</div>
</template>
<script>
import { getDataList, add, update, remove } from '@/api/${generatorConfig.viewParentDir}/${generatorConfig.resourceName}'
import { objectUtil } from "@/common/js/util"
export default {
name: "${generatorConfig.resourceName}",
data() {
return {
fixedHeader: true,// 高度自适应
autoHeight: `\${window.innerHeight} ` * 0.58,// 获取当前可视高度-定义Table高度
search: {
<%
for(rule in ruleList){
if(rule.variableIsQuery == true && rule.variableName != 'id'){
%>
${rule.variableName}: '',
<%
}
}
%>
},
listColumns: [
{
title: "#",
type: 'index',
width: 60,
align: 'center',
indexMethod: (row) => {
return (row._index + 1) + ((this.pageParam.pageNum - 1) * this.pageParam.pageSize);
}
},
<%
for(rule in ruleList){
if(rule.variableIsList == true){
%>
{
title: '${rule.variableComment}',
key: '${rule.variableName}',
width: 100,
},
<%
}
}
%>
{
title: '操作区',
slot: 'action',
width: 300,
fixed: 'right',
align: 'center'
}
],
dataList: [],
tableLoading: false,
pageTotal: 0, // 总页数
pageSize: 10, // 每页显示条数
pageCurrent: 1, // 当前页
pageParam: { // 调用时候的分页参数
pageNum: 1,
pageSize: 10
},
modal: false,
modalTitle: '',
addModal: false, // 添加
editModal: false, // 编辑
submitLoading: false,
formItem: {
<%
for(rule in ruleList){
if(rule.variableIsFormItem == true){
%>
${rule.variableName}: '${rule.variableDefault}',
<%
}
}
%>
},
ruleCustom: {
<%
for(rule in ruleList){
if(rule.variableIsCheck == true){
%>
${rule.variableName}: [{required: true, type: '${rule.variableCheckType}', message: '请输入${rule.variableComment}', trigger: 'blur'}],
<%
}
}
%>
},
}
},
methods: {
getDataList() {
let temp = JSON.parse(JSON.stringify(this.pageParam))
let data = objectUtil.trimJoin(temp, this.search)
this.tableLoading = true
getDataList(data).then(res => {
let page = res.data.data;
this.pageTotal = page.size
this.dataList = page.records
// 延迟300毫秒,给它更流畅的感觉
setTimeout(() => {
this.tableLoading = false
}, 300)
})
},
toAdd() {
this.modalTitle = "添加"
this.modal = true
this.addModal = true
this.editModal = false
},
toEdit(index) {
this.modalTitle = "编辑"
<%
for(rule in ruleList){
if(rule.gVariableIsFormItem == true){
%>
this.formItem.${rule.gVariableName} = this.dataList[index].${rule.gVariableName}
<%
}
}
%>
this.modal = true
this.addModal = false
this.editModal = true
},
submit(formItem) {
// modal 提交
this.$refs[formItem].validate((valid) => {
let data = this.formItem
if (valid) {
if (this.addModal) {//添加
console.log("add")
add(data).then(res => {
this.getDataList()
this.$Message.success("添加成功!")
})
} else {//编辑
console.log("edit")
update(data).then(res => {
this.getDataList()
this.$Message.success("编辑成功!")
})
}
this.cancel()
}
})
},
cancel() {
// Modal cancel
this.modal = false
this.refresh()
},
toDelete(index) {
let temp = this.dataList[index]
let data = {
id: temp.id
}
remove(data).then(res => {
this.refresh()
this.getDataList()
this.$Message.success("删除成功!")
})
},
refresh() {
this.pageParam = {
pageNum: 1,
pageSize: 10
};
this.search = {
<%
for(rule in ruleList){
if(rule.variableIsQuery == true && rule.variableName != 'id'){
%>
${rule.variableName}: '',
<%
}
}
%>
};
this.formItem = {
<%
for(rule in ruleList){
if(rule.variableIsFormItem == true){
%>
${rule.variableName}: '${rule.variableDefault}',
<%
}
}
%>
};
},
changePage(index) {
// 需要显示开始数据的index,(因为数据是从0开始的,页码是从1开始的,需要-1)
this.pageParam.pageNum = index;
this.getDataList();
},
changePageSize(page) {
// 切换分页条数
this.pageParam.pageNum = 1;
this.pageParam.pageSize = page;
this.getDataList();
},
},
created() {
this.getDataList()
},
mounted() {
//this.getDataList()
}
}
</script>
<style lang="less" scoped>
.form-input {
width: 280px
}
</style>
@@ -1,37 +0,0 @@
<?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="com.freedom.admin.mapper.GeneratorMapper">
<select id="getTableListWithPage"
resultType="com.freedom.admin.entity.GeneratorTableVO"
parameterType="com.freedom.admin.entity.GeneratorTableVO">
select
`table_name` as 'tableName',
`column_name` as 'columnName',
`column_type` as 'columnType',
`data_type` as 'dataType',
`character_maximum_length` as 'characterMaximumLength',
( case when `column_key` = 'PRI' then 'YES' else 'NO' end ) as 'isColumnKey',
`is_nullable` as 'isNullable',
`column_default` as 'columnDefault',
`column_comment` as 'columnComment'
from information_schema.columns
<where>
table_schema = 'freedom_db'
<if test="tableName != null and tableName != ''">
and `table_name` = #{tableName}
</if>
</where>
</select>
<select id="getTableSelectList"
resultType="java.util.Map">
select
`table_name` as 'value',
concat(`table_name`,' [ ',table_comment,' ] ') as 'label'
from information_schema.TABLES
where table_schema = 'freedom_db'
order by current_time desc
</select>
</mapper>