Browse Source

初始化

master
fengshuonan 6 years ago
commit
900eef7b4a
  1. 4
      .gitattributes
  2. 33
      .gitignore
  3. 13
      LICENSE
  4. 190
      README.md
  5. 81
      pom.xml
  6. 33
      src/main/java/cn/stylefeng/guns/generator/config/GeneratorAutoConfiguration.java
  7. 39
      src/main/java/cn/stylefeng/guns/generator/db/DbInfoInitializer.java
  8. 70
      src/main/java/cn/stylefeng/guns/generator/engine/SimpleTemplateEngine.java
  9. 115
      src/main/java/cn/stylefeng/guns/generator/engine/base/AbstractTemplateEngine.java
  10. 126
      src/main/java/cn/stylefeng/guns/generator/engine/base/GunsTemplateEngine.java
  11. 214
      src/main/java/cn/stylefeng/guns/generator/engine/config/ContextConfig.java
  12. 70
      src/main/java/cn/stylefeng/guns/generator/engine/config/ControllerConfig.java
  13. 55
      src/main/java/cn/stylefeng/guns/generator/engine/config/DaoConfig.java
  14. 203
      src/main/java/cn/stylefeng/guns/generator/engine/config/Menu.java
  15. 74
      src/main/java/cn/stylefeng/guns/generator/engine/config/PageConfig.java
  16. 91
      src/main/java/cn/stylefeng/guns/generator/engine/config/ServiceConfig.java
  17. 194
      src/main/java/cn/stylefeng/guns/generator/engine/config/SqlConfig.java
  18. 30
      src/main/java/cn/stylefeng/guns/generator/executor/GunsCodeGenerator.java
  19. 109
      src/main/java/cn/stylefeng/guns/generator/executor/config/AbstractGeneratorConfig.java
  20. 81
      src/main/java/cn/stylefeng/guns/generator/executor/config/GunsGeneratorConfig.java
  21. 97
      src/main/java/cn/stylefeng/guns/generator/executor/config/WebGeneratorConfig.java
  22. 297
      src/main/java/cn/stylefeng/guns/generator/executor/model/GenQo.java
  23. 59
      src/main/java/cn/stylefeng/guns/generator/modular/controller/CodeController.java
  24. 71
      src/main/java/cn/stylefeng/guns/generator/modular/entity/CodeDbInfo.java
  25. 59
      src/main/java/cn/stylefeng/guns/generator/modular/factory/DefaultTemplateFactory.java
  26. 29
      src/main/java/cn/stylefeng/guns/generator/modular/service/TableService.java
  27. 3
      src/main/resources/META-INF/spring.factories
  28. 96
      src/main/resources/gunsTemplate/advanced/Controller.java.btl
  29. 3
      src/main/resources/gunsTemplate/advanced/menu_sql.sql.btl
  30. 38
      src/main/resources/gunsTemplate/advanced/page.html.btl
  31. 102
      src/main/resources/gunsTemplate/advanced/page.js.btl
  32. 41
      src/main/resources/gunsTemplate/advanced/page_add.html.btl
  33. 41
      src/main/resources/gunsTemplate/advanced/page_edit.html.btl
  34. 98
      src/main/resources/gunsTemplate/advanced/page_info.js.btl

4
.gitattributes vendored

@ -0,0 +1,4 @@
*.js linguist-language=java
*.css linguist-language=java
*.html linguist-language=java
*.btl linguist-language=java

33
.gitignore vendored

@ -0,0 +1,33 @@
# Compiled class file
*.class
*.iml
*.idea
target/
logs/
# Log file
*.log
# BlueJ files
*.ctxt
# Mobile Tools for Java (J2ME)
.mtj.tmp/
# Package Files #
*.jar
*.war
*.ear
*.zip
*.tar.gz
*.rar
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
*velocity.log*
# Eclipse #
.classpath
.project
.settings/

13
LICENSE

@ -0,0 +1,13 @@
Copyright 2018 StyleFeng
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

190
README.md

@ -0,0 +1,190 @@
# Guns V5.0
## 介绍
Guns基于SpringBoot 2,致力于做更简洁的后台管理系统,完美整合springmvc + shiro + mybatis-plus + beetl!Guns项目代码简洁,注释丰富,上手容易,同时Guns包含许多基础模块(用户管理,角色管理,部门管理,字典管理等10个模块),可以直接作为一个后台管理系统的脚手架! 2018目标 `更简洁`,`更规范`!
### Guns v5.0更新内容
> * 剔除了shiro,集成自研单点登陆框架,详情见`sso`分支(shiro版本还是在master分支),点击进入sso分支[https://gitee.com/stylefeng/guns/tree/sso/](https://gitee.com/stylefeng/guns/tree/sso/)
### Guns v4.0更新内容
> * guns-admin提供rest api服务,并以jwt方式鉴权,所有以`/gunsApi`开头的接口走这种鉴权方式,其他接口仍为shiro鉴权
> * spring boot升级到2.0版本!
> * 简化前端所有的html,js,css等资源文件,由11.8MB缩减为4.8MB!
> * 新增手动增加标签页的方法,Feng.newCrontab(href,menuName);
> * laydate时间插件和layer弹出层插件更新为官网最新,可以看着layui官网的文档直接开发啦!
> * 去掉animate动画效果,加快页面响应速度!
> * 修复登陆后重启应用造成404的bug!
> * 增强core模块的功能,拿来即用开发新的模块的后端管理系统!
> * 升级各个依赖包的版本!
> * 简化applicatioin.yml的配置,一些固定不变的配置写在core模块的default-config.properties!
> * 简化多数据源配置,简化mybatis-plus的配置!
> * 优化日志记录格式和策略,详情见logback-spring.xml!
> * 修复菜单折叠无法折叠子菜单的子菜单的bug!
> * 感谢Guns and Roses技术交流2群网友摇了摇头(931483459)提供的oracle版本的Guns,现在已上传到oracle分支
### Guns v3.0更新内容
> * Guns v3.0新增rest api服务,提供对接服务端接口的支持,并利用jwt token鉴权机制给予客户端的访问权限,传输数据进行md5签名保证传输过程数据的安全性!
> * Guns v3.1新增集成工作流引擎flowable6.2.0!
## 最新Guns技术文档
Guns框架有作者在业余时间整理的技术文档,详情点击[查看详情](https://gitee.com/stylefeng/guns/wikis/pages?title=Guns%E6%8A%80%E6%9C%AF%E6%96%87%E6%A1%A3&parent=)
## 最新Guns视频教程
Guns框架有作者在业余时间录制的视频教程,详情点击[教程介绍](https://gitee.com/stylefeng/guns/wikis/pages?title=Guns%E8%A7%86%E9%A2%91%E6%95%99%E7%A8%8B&parent=)
## 技术讨论 & [wiki地址](https://gitee.com/stylefeng/guns/wikis/Home)
如果对项目有任何疑问或者建议,欢迎加入Guns技术交流1群:254550081,Guns技术交流2群:684163663,Guns技术交流3群:207434260(加之前先看下文档guns-admin/doc/Guns技术文档 v1.0.pdf)
## 管理系统功能
1.用户管理 2.角色管理 3.部门管理 4.菜单管理 5.字典管理 6.业务日志 7.登录日志 8.监控管理 9.通知管理 10.代码生成
## 项目特点
1. 基于SpringBoot,简化了大量项目配置和maven依赖,让您更专注于业务开发,独特的分包方式,代码多而不乱。
2. 完善的日志记录体系,可记录登录日志,业务操作日志(可记录操作前和操作后的数据),异常日志到数据库,通过@BussinessLog注解和LogObjectHolder.me().set()方法,业务操作日志可具体记录哪个用户,执行了哪些业务,修改了哪些数据,并且日志记录为异步执行,详情请见@BussinessLog注解和LogObjectHolder,LogManager,LogAop类。
3. 利用beetl模板引擎对前台页面进行封装和拆分,使臃肿的html代码变得简洁,更加易维护。
4. 对常用js插件进行二次封装,使js代码变得简洁,更加易维护,具体请见webapp/static/js/common文件夹内js代码。
5. 利用ehcache框架对经常调用的查询进行缓存,提升运行速度,具体请见ConstantFactory类中@Cacheable标记的方法。
6. controller层采用map + warpper方式的返回结果,返回给前端更为灵活的数据,具体参见com.stylefeng.guns.modular.system.warpper包中具体类。
7. 防止XSS攻击,通过XssFilter类对所有的输入的非法字符串进行过滤以及替换。
8. 简单可用的代码生成体系,通过SimpleTemplateEngine可生成带有主页跳转和增删改查的通用控制器、html页面以及相关的js,还可以生成Service和Dao,并且这些生成项都为可选的,通过ContextConfig下的一些列xxxSwitch开关,可灵活控制生成模板代码,让您把时间放在真正的业务上。
9. 控制器层统一的异常拦截机制,利用@ControllerAdvice统一对异常拦截,具体见com.stylefeng.guns.core.aop.GlobalExceptionHandler类。
10. 页面统一的js key-value单例模式写法,每个页面生成一个唯一的全局变量,提高js的利用效率,并且有效防止多个人员开发引起的函数名/类名冲突,并且可以更好地去维护代码。
## 基于javabean方式的spring配置
Guns以简洁为核心,抛弃了传统的易错,臃肿xml配置,采用javabean的方式配置spring,简化了项目的配置,如下示例为配置mybatis-plus和数据源:
```
@Configuration
@MapperScan(basePackages = {"com.stylefeng.guns.modular.*.dao", "com.stylefeng.guns.common.persistence.dao"})
public class MybatisPlusConfig {
@Autowired
DruidProperties druidProperties;
/**
* mybatis-plus分页插件
*/
@Bean
public PaginationInterceptor paginationInterceptor() {
PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
paginationInterceptor.setDialectType(DBType.MYSQL.getDb());
return paginationInterceptor;
}
}
```
## 业务日志记录
日志记录采用aop(LogAop类)方式对所有包含@BussinessLog注解的方法进行aop切入,会记录下当前用户执行了哪些操作(即@BussinessLog value属性的内容),如果涉及到数据修改,会取当前http请求的所有requestParameters与LogObjectHolder类中缓存的Object对象的所有字段作比较(所以在编辑之前的获取详情接口中需要缓存被修改对象之前的字段信息),日志内容会异步存入数据库中(通过ScheduledThreadPoolExecutor类)。
## beetl对前台页面的拆分与包装
例如,把主页拆分成三部分,每个部分单独一个页面,更加便于维护
```
<!--左侧导航开始-->
@include("/common/_tab.html"){}
<!--左侧导航结束-->
<!--右侧部分开始-->
@include("/common/_right.html"){}
<!--右侧部分结束-->
<!--右侧边栏开始-->
@include("/common/_theme.html"){}
<!--右侧边栏结束-->
```
以及对重复的html进行包装,使前端页面更加专注于业务实现,例如,把所有页面引用包进行提取
```
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="renderer" content="webkit" /><!-- 让360浏览器默认选择webkit内核 -->
<!-- 全局css -->
<link rel="shortcut icon" href="${ctxPath}/static/favicon.ico">
<!-- 全局js -->
<script src="${ctxPath}/static/js/jquery.min.js?v=2.1.4"></script>
<body class="gray-bg">
<div class="wrapper wrapper-content">
${layoutContent}
</div>
<script src="${ctxPath}/static/js/content.js?v=1.0.0"></script>
</body>
</html>
```
开发页面时,只需编写如下代码即可
```
@layout("/common/_container.html"){
<div class="row">
<div class="col-sm-12">
<div class="ibox float-e-margins">
<div class="ibox-title">
<h5>部门管理</h5>
</div>
<div class="ibox-content">
//自定义内容
</div>
</div>
</div>
</div>
<script src="${ctxPath}/static/modular/system/dept/dept.js"></script>
@}
```
以上beetl的用法请参考beetl说明文档。
## 对js常用代码的封装
在webapp/static/js/common目录中,有对常用js代码的封装,例如Feng.js,其中Feng.info(),Feng.success(),Feng.error()三个方法,分别封装了普通提示,成功提示,错误提示的代码,简化了layer提示层插件的使用。
## 极简的图片上传方法
guns对web-upload进行二次封装,让图片的上传功能呢只用2行代码即可实现,如下
```
var avatarUp = new $WebUpload("avatar");
avatarUp.init();
```
具体实现请参考static/js/common/web-upload-object.js
## 独创controller层,map+warpper返回方式
map+warpper方式即为把controller层的返回结果使用BeanKit工具类把原有bean转化为Map的的形式(或者原有bean直接是map的形式),再用单独写的一个包装类再包装一次这个map,使里面的参数更加具体,更加有含义,下面举一个例子,例如,在返回给前台一个性别时,数据库查出来1是男2是女,假如直接返回给前台,那么前台显示的时候还需要增加一次判断,并且前后端分离开发时又增加了一次交流和文档的成本,但是采用warpper包装的形式,可以直接把返回结果包装一下,例如动态增加一个字段sexName直接返回给前台性别的中文名称即可。
## 独创mybatis数据范围拦截器,实现对数据权限的过滤
Guns的数据范围控制是指,对拥有相同角色的用户,根据部门的不同进行相应的数据筛选,如果部门不相同,那么有可能展示出的具体数据是不一致的.所以说Guns对数据范围控制是以部门id为单位来标识的,如何增加数据范围拦截呢?只需在相关的mapper接口的参数中增加一个DataScope对象即可,DataScope中有两个字段,scopeName用来标识sql语句中部门id的字段名称,例如deptiid或者id,另一个字段deptIds就是具体需要过滤的部门id的集合.拦截器原理如下:拦截mapper中包含DataScope对象的方法,获取其原始sql,并做一个包装限制部门id在deptIds范围内的数据进行展示.
## swagger api管理使用说明
swagger会管理所有包含@ApiOperation注解的控制器方法,同时,可利用@ApiImplicitParams注解标记接口中的参数,具体用法请参考CodeController类中的用法。
```
@ApiOperation("生成代码")
@ApiImplicitParams({
@ApiImplicitParam(name = "moduleName", value = "模块名称", required = true, dataType = "String"),
@ApiImplicitParam(name = "bizChName", value = "业务名称", required = true, dataType = "String"),
@ApiImplicitParam(name = "bizEnName", value = "业务英文名称", required = true, dataType = "String"),
@ApiImplicitParam(name = "path", value = "项目生成类路径", required = true, dataType = "String")
})
@RequestMapping(value = "/generate", method = RequestMethod.POST)
```
## jwt token鉴权机制
jwt token鉴权机制是指若需要请求服务器接口,必须通过AuthController获取一个请求令牌(jwt token),持有jwt token的用户才可以访问服务器的其他资源,如果没有此令牌,则访问接口会直接忽略,请求获取jwt token时,需要携带credenceName和credenceCode(可以是账号密码,可以是手机号验证码等等),校验credenceName和credenceCode成功后,会颁发给客户端一个jwt token还有一个随机字符串,用于传输过程中对数据进行签名用,签名机制请见下面介绍.基于token的鉴权机制类似于http协议也是无状态的,它不需要在服务端去保留用户的认证信息或者会话信息.这就意味着基于token认证机制的应用不需要去考虑用户在哪一台服务器登录了,这就为应用的扩展提供了便利.
## 签名机制
签名机制是指客户端向服务端传输数据中,对传输数据进行md5加密,并且加密过程中利用Auth接口返回的随机字符串进行混淆加密,并把md5值同时附带给服务端,服务端通获取数据之后对数据再进行一次md5加密,若加密结果和客户端传来的数据一致,则认定客户端请求的数据是没有被篡改的,若不一致,则认为被加密的数据是被篡改的
## 效果图
![输入图片说明](https://git.oschina.net/uploads/images/2017/0604/194616_36ed7fd6_551203.png "在这里输入图片标题")
![输入图片说明](https://git.oschina.net/uploads/images/2017/0604/194623_a0761bc3_551203.png "在这里输入图片标题")
![输入图片说明](https://git.oschina.net/uploads/images/2017/0604/194630_640dfd35_551203.png "在这里输入图片标题")
![输入图片说明](https://git.oschina.net/uploads/images/2017/0526/104015_bdb14c74_551203.png "在这里输入图片标题")
![输入图片说明](https://git.oschina.net/uploads/images/2017/0516/000735_b83c5c46_551203.png "在这里输入图片标题")
![输入图片说明](https://git.oschina.net/uploads/images/2017/0526/103734_bd3e8f6b_551203.png "在这里输入图片标题")
![输入图片说明](https://git.oschina.net/uploads/images/2017/0604/194539_f9bb482a_551203.png "在这里输入图片标题")
![输入图片说明](https://git.oschina.net/uploads/images/2017/0526/103746_6b4129ed_551203.png "在这里输入图片标题")
![输入图片说明](https://git.oschina.net/uploads/images/2017/0526/103755_7729b916_551203.png "在这里输入图片标题")
![输入图片说明](https://git.oschina.net/uploads/images/2017/0526/103801_b8216865_551203.png "在这里输入图片标题")
![输入图片说明](https://git.oschina.net/uploads/images/2017/0526/103807_20bfb868_551203.png "在这里输入图片标题")
![输入图片说明](https://git.oschina.net/uploads/images/2017/0526/103814_67e078bb_551203.png "在这里输入图片标题")
![输入图片说明](https://git.oschina.net/uploads/images/2017/0526/103822_58fd5d91_551203.png "在这里输入图片标题")
![输入图片说明](https://git.oschina.net/uploads/images/2017/0526/103827_d6218c74_551203.png "在这里输入图片标题")
## 曾获荣誉
![输入图片说明](https://gitee.com/uploads/images/2017/1015/151932_f1593f87_551203.jpeg "initpintu_副本_副本.jpg")

81
pom.xml

@ -0,0 +1,81 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>cn.stylefeng.guns</groupId>
<artifactId>guns-generator</artifactId>
<version>1.0.0</version>
<packaging>jar</packaging>
<name>guns-generator</name>
<description>代码生成器</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.1.RELEASE</version>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>cn.stylefeng.roses</groupId>
<artifactId>kernel-core</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>com.ibeetl</groupId>
<artifactId>beetl</artifactId>
<version>2.9.3</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generate</artifactId>
<version>2.3</version>
</dependency>
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity-engine-core</artifactId>
<version>2.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
</configuration>
</plugin>
</plugins>
<resources>
<resource>
<directory>src/main/resources</directory>
</resource>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
</resource>
</resources>
</build>
</project>

33
src/main/java/cn/stylefeng/guns/generator/config/GeneratorAutoConfiguration.java

@ -0,0 +1,33 @@
package cn.stylefeng.guns.generator.config;
import cn.stylefeng.guns.generator.modular.controller.CodeController;
import cn.stylefeng.roses.core.db.DbInitializer;
import cn.stylefeng.guns.generator.db.DbInfoInitializer;
import cn.stylefeng.guns.generator.modular.service.TableService;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* 代码生成器的自动配置
*
* @author fengshuonan
* @date 2018-10-09-下午3:27
*/
@Configuration
public class GeneratorAutoConfiguration {
@Bean
public CodeController codeController() {
return new CodeController();
}
@Bean
public TableService tableService() {
return new TableService();
}
@Bean
public DbInitializer dbInitializer() {
return new DbInfoInitializer();
}
}

39
src/main/java/cn/stylefeng/guns/generator/db/DbInfoInitializer.java

@ -0,0 +1,39 @@
package cn.stylefeng.guns.generator.db;
import cn.stylefeng.guns.generator.modular.entity.CodeDbInfo;
import cn.stylefeng.roses.core.db.DbInitializer;
/**
* 数据库链接信息表初始化
*
* @author fengshuonan
* @date 2018-07-30-上午9:29
*/
public class DbInfoInitializer extends DbInitializer {
@Override
public String getTableInitSql() {
return "CREATE TABLE `code_dbinfo` (\n" +
" `id` int(10) unsigned NOT NULL AUTO_INCREMENT,\n" +
" `name` varchar(20) DEFAULT NULL COMMENT '别名',\n" +
" `db_driver` varchar(100) NOT NULL COMMENT '数据库驱动',\n" +
" `db_url` varchar(200) NOT NULL COMMENT '数据库地址',\n" +
" `db_user_name` varchar(100) NOT NULL COMMENT '数据库账户',\n" +
" `db_password` varchar(100) NOT NULL COMMENT '连接密码',\n" +
" `db_type` varchar(10) DEFAULT NULL COMMENT '数据库类型',\n" +
" `create_time` datetime DEFAULT NULL COMMENT '创建时间',\n" +
" `update_time` datetime DEFAULT NULL COMMENT '修改时间',\n" +
" PRIMARY KEY (`id`) USING BTREE\n" +
") ENGINE=InnoDB AUTO_INCREMENT=14 DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='数据库链接信息'";
}
@Override
public String getTableName() {
return "code_dbinfo";
}
@Override
public Class<?> getEntityClass() {
return CodeDbInfo.class;
}
}

70
src/main/java/cn/stylefeng/guns/generator/engine/SimpleTemplateEngine.java

@ -0,0 +1,70 @@
package cn.stylefeng.guns.generator.engine;
import cn.hutool.core.util.StrUtil;
import cn.stylefeng.guns.generator.engine.base.GunsTemplateEngine;
/**
* 通用的模板生成引擎
*
* @author fengshuonan
* @date 2017-05-09 20:32
*/
public class SimpleTemplateEngine extends GunsTemplateEngine {
@Override
protected void generatePageEditHtml() {
String path = StrUtil.format(super.getContextConfig().getProjectPath() + getPageConfig().getPageEditPathTemplate(),
super.getContextConfig().getBizEnName(), super.getContextConfig().getBizEnName());
generateFile(super.getContextConfig().getTemplatePrefixPath() + "/page_edit.html.btl", path);
System.out.println("生成编辑页面成功!");
}
@Override
protected void generatePageAddHtml() {
String path = StrUtil.format(super.getContextConfig().getProjectPath() + getPageConfig().getPageAddPathTemplate(),
super.getContextConfig().getBizEnName(), super.getContextConfig().getBizEnName());
generateFile(super.getContextConfig().getTemplatePrefixPath() + "/page_add.html.btl", path);
System.out.println("生成添加页面成功!");
}
@Override
protected void generatePageInfoJs() {
String path = StrUtil.format(super.getContextConfig().getProjectPath() + getPageConfig().getPageInfoJsPathTemplate(),
super.getContextConfig().getBizEnName(), super.getContextConfig().getBizEnName());
generateFile(super.getContextConfig().getTemplatePrefixPath() + "/page_info.js.btl", path);
System.out.println("生成页面详情js成功!");
}
@Override
protected void generatePageJs() {
String path = StrUtil.format(super.getContextConfig().getProjectPath() + getPageConfig().getPageJsPathTemplate(),
super.getContextConfig().getBizEnName(), super.getContextConfig().getBizEnName());
generateFile(super.getContextConfig().getTemplatePrefixPath() + "/page.js.btl", path);
System.out.println("生成页面js成功!");
}
@Override
protected void generatePageHtml() {
String path = StrUtil.format(super.getContextConfig().getProjectPath() + getPageConfig().getPagePathTemplate(),
super.getContextConfig().getBizEnName(), super.getContextConfig().getBizEnName());
generateFile(super.getContextConfig().getTemplatePrefixPath() + "/page.html.btl", path);
System.out.println("生成页面成功!");
}
@Override
protected void generateController() {
String controllerPath = StrUtil.format(super.getContextConfig().getProjectPath() + super.getControllerConfig().getControllerPathTemplate(),
StrUtil.upperFirst(super.getContextConfig().getBizEnName()));
generateFile(super.getContextConfig().getTemplatePrefixPath() + "/Controller.java.btl", controllerPath);
System.out.println("生成控制器成功!");
}
@Override
protected void generateSqls() {
String path = StrUtil.format(super.getContextConfig().getProjectPath() + super.sqlConfig.getSqlPathTemplate(),
StrUtil.upperFirst(super.getContextConfig().getBizEnName()));
generateFile(super.getContextConfig().getTemplatePrefixPath() + "/menu_sql.sql.btl", path);
System.out.println("生成sql成功!");
}
}

115
src/main/java/cn/stylefeng/guns/generator/engine/base/AbstractTemplateEngine.java

@ -0,0 +1,115 @@
package cn.stylefeng.guns.generator.engine.base;
import cn.stylefeng.guns.generator.engine.config.*;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
/**
* 模板生成父类
*
* @author fengshuonan
* @date 2017-05-08 20:17
*/
public class AbstractTemplateEngine {
protected ContextConfig contextConfig; //全局配置
protected ControllerConfig controllerConfig; //控制器的配置
protected PageConfig pageConfig; //页面的控制器
protected DaoConfig daoConfig; //Dao配置
protected ServiceConfig serviceConfig; //Service配置
protected SqlConfig sqlConfig; //sql配置
protected TableInfo tableInfo; //表的信息
public void initConfig() {
if (this.contextConfig == null) {
this.contextConfig = new ContextConfig();
}
if (this.controllerConfig == null) {
this.controllerConfig = new ControllerConfig();
}
if (this.pageConfig == null) {
this.pageConfig = new PageConfig();
}
if (this.daoConfig == null) {
this.daoConfig = new DaoConfig();
}
if (this.serviceConfig == null) {
this.serviceConfig = new ServiceConfig();
}
if (this.sqlConfig == null) {
this.sqlConfig = new SqlConfig();
}
this.contextConfig.init();
this.controllerConfig.setContextConfig(this.contextConfig);
this.controllerConfig.init();
this.serviceConfig.setContextConfig(this.contextConfig);
this.serviceConfig.init();
this.daoConfig.setContextConfig(this.contextConfig);
this.daoConfig.init();
this.pageConfig.setContextConfig(this.contextConfig);
this.pageConfig.init();
this.sqlConfig.setContextConfig(this.contextConfig);
this.sqlConfig.init();
}
public PageConfig getPageConfig() {
return pageConfig;
}
public void setPageConfig(PageConfig pageConfig) {
this.pageConfig = pageConfig;
}
public ContextConfig getContextConfig() {
return contextConfig;
}
public void setContextConfig(ContextConfig contextConfig) {
this.contextConfig = contextConfig;
}
public ControllerConfig getControllerConfig() {
return controllerConfig;
}
public void setControllerConfig(ControllerConfig controllerConfig) {
this.controllerConfig = controllerConfig;
}
public DaoConfig getDaoConfig() {
return daoConfig;
}
public void setDaoConfig(DaoConfig daoConfig) {
this.daoConfig = daoConfig;
}
public ServiceConfig getServiceConfig() {
return serviceConfig;
}
public void setServiceConfig(ServiceConfig serviceConfig) {
this.serviceConfig = serviceConfig;
}
public SqlConfig getSqlConfig() {
return sqlConfig;
}
public void setSqlConfig(SqlConfig sqlConfig) {
this.sqlConfig = sqlConfig;
}
public TableInfo getTableInfo() {
return tableInfo;
}
public void setTableInfo(TableInfo tableInfo) {
this.tableInfo = tableInfo;
}
}

126
src/main/java/cn/stylefeng/guns/generator/engine/base/GunsTemplateEngine.java

@ -0,0 +1,126 @@
package cn.stylefeng.guns.generator.engine.base;
import cn.stylefeng.roses.core.util.ToolUtil;
import com.sun.javafx.PlatformUtil;
import org.beetl.core.Configuration;
import org.beetl.core.GroupTemplate;
import org.beetl.core.Template;
import org.beetl.core.resource.ClasspathResourceLoader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Properties;
/**
* ADI项目模板生成 引擎
*
* @author fengshuonan
* @date 2017-05-07 22:15
*/
public abstract class GunsTemplateEngine extends AbstractTemplateEngine {
private GroupTemplate groupTemplate;
public GunsTemplateEngine() {
initBeetlEngine();
}
protected void initBeetlEngine() {
Properties properties = new Properties();
properties.put("RESOURCE.root", "");
properties.put("DELIMITER_STATEMENT_START", "<%");
properties.put("DELIMITER_STATEMENT_END", "%>");
properties.put("HTML_TAG_FLAG", "##");
Configuration cfg = null;
try {
cfg = new Configuration(properties);
} catch (IOException e) {
e.printStackTrace();
}
ClasspathResourceLoader resourceLoader = new ClasspathResourceLoader();
groupTemplate = new GroupTemplate(resourceLoader, cfg);
groupTemplate.registerFunctionPackage("tool", new ToolUtil());
}
protected void configTemplate(Template template) {
template.binding("controller", super.controllerConfig);
template.binding("context", super.contextConfig);
template.binding("dao", super.daoConfig);
template.binding("service", super.serviceConfig);
template.binding("sqls", super.sqlConfig);
template.binding("table", super.tableInfo);
}
protected void generateFile(String template, String filePath) {
Template pageTemplate = groupTemplate.getTemplate(template);
configTemplate(pageTemplate);
if (PlatformUtil.isWindows()) {
filePath = filePath.replaceAll("/+|\\\\+", "\\\\");
} else {
filePath = filePath.replaceAll("/+|\\\\+", "/");
}
File file = new File(filePath);
File parentFile = file.getParentFile();
if (!parentFile.exists()) {
parentFile.mkdirs();
}
FileOutputStream fileOutputStream = null;
try {
fileOutputStream = new FileOutputStream(file);
pageTemplate.renderTo(fileOutputStream);
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
try {
fileOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public void start() {
//配置之间的相互依赖
super.initConfig();
//生成模板
if (super.contextConfig.getControllerSwitch()) {
generateController();
}
if (super.contextConfig.getIndexPageSwitch()) {
generatePageHtml();
}
if (super.contextConfig.getAddPageSwitch()) {
generatePageAddHtml();
}
if (super.contextConfig.getEditPageSwitch()) {
generatePageEditHtml();
}
if (super.contextConfig.getJsSwitch()) {
generatePageJs();
}
if (super.contextConfig.getInfoJsSwitch()) {
generatePageInfoJs();
}
if (super.contextConfig.getSqlSwitch()) {
generateSqls();
}
}
protected abstract void generatePageEditHtml();
protected abstract void generatePageAddHtml();
protected abstract void generatePageInfoJs();
protected abstract void generatePageJs();
protected abstract void generatePageHtml();
protected abstract void generateController();
protected abstract void generateSqls();
}

214
src/main/java/cn/stylefeng/guns/generator/engine/config/ContextConfig.java

@ -0,0 +1,214 @@
package cn.stylefeng.guns.generator.engine.config;
import cn.hutool.core.util.StrUtil;
/**
* 全局配置
*
* @author fengshuonan
* @date 2017-05-08 20:21
*/
public class ContextConfig {
private String templatePrefixPath = "gunsTemplate/advanced";
private String projectPath = "D:\\ideaSpace\\guns";//模板输出的项目目录
private String bizChName; //业务名称
private String bizEnName; //业务英文名称
private String bizEnBigName;//业务英文名称(大写)
private String moduleName = "system"; //模块名称
private String proPackage = "cn.stylefeng.guns.admin";
private String coreBasePackage = "cn.stylefeng.guns.core";
private String modelPackageName = "cn.stylefeng.guns.modular.system.model"; //model的包名
private String modelMapperPackageName = "cn.stylefeng.guns.modular.system.dao"; //model的dao
private String entityName; //实体的名称
private Boolean controllerSwitch = true; //是否生成控制器代码开关
private Boolean indexPageSwitch = true; //主页
private Boolean addPageSwitch = true; //添加页面
private Boolean editPageSwitch = true; //编辑页面
private Boolean jsSwitch = true; //js
private Boolean infoJsSwitch = true; //详情页面js
private Boolean daoSwitch = true; //dao
private Boolean serviceSwitch = true; //service
private Boolean entitySwitch = true; //生成实体的开关
private Boolean sqlSwitch = true; //生成sql的开关
public void init() {
if (entityName == null) {
entityName = bizEnBigName;
}
modelPackageName = proPackage + "." + "modular.system.model";
modelMapperPackageName = proPackage + "." + "modular.system.dao";
}
public String getBizEnBigName() {
return bizEnBigName;
}
public void setBizEnBigName(String bizEnBigName) {
this.bizEnBigName = bizEnBigName;
}
public String getBizChName() {
return bizChName;
}
public void setBizChName(String bizChName) {
this.bizChName = bizChName;
}
public String getBizEnName() {
return bizEnName;
}
public void setBizEnName(String bizEnName) {
this.bizEnName = bizEnName;
this.bizEnBigName = StrUtil.upperFirst(this.bizEnName);
}
public String getProjectPath() {
return projectPath;
}
public void setProjectPath(String projectPath) {
this.projectPath = projectPath;
}
public String getModuleName() {
return moduleName;
}
public void setModuleName(String moduleName) {
this.moduleName = moduleName;
}
public Boolean getControllerSwitch() {
return controllerSwitch;
}
public void setControllerSwitch(Boolean controllerSwitch) {
this.controllerSwitch = controllerSwitch;
}
public Boolean getIndexPageSwitch() {
return indexPageSwitch;
}
public void setIndexPageSwitch(Boolean indexPageSwitch) {
this.indexPageSwitch = indexPageSwitch;
}
public Boolean getAddPageSwitch() {
return addPageSwitch;
}
public void setAddPageSwitch(Boolean addPageSwitch) {
this.addPageSwitch = addPageSwitch;
}
public Boolean getEditPageSwitch() {
return editPageSwitch;
}
public void setEditPageSwitch(Boolean editPageSwitch) {
this.editPageSwitch = editPageSwitch;
}
public Boolean getJsSwitch() {
return jsSwitch;
}
public void setJsSwitch(Boolean jsSwitch) {
this.jsSwitch = jsSwitch;
}
public Boolean getInfoJsSwitch() {
return infoJsSwitch;
}
public void setInfoJsSwitch(Boolean infoJsSwitch) {
this.infoJsSwitch = infoJsSwitch;
}
public Boolean getDaoSwitch() {
return daoSwitch;
}
public void setDaoSwitch(Boolean daoSwitch) {
this.daoSwitch = daoSwitch;
}
public Boolean getServiceSwitch() {
return serviceSwitch;
}
public void setServiceSwitch(Boolean serviceSwitch) {
this.serviceSwitch = serviceSwitch;
}
public String getTemplatePrefixPath() {
return templatePrefixPath;
}
public void setTemplatePrefixPath(String templatePrefixPath) {
this.templatePrefixPath = templatePrefixPath;
}
public String getModelPackageName() {
return modelPackageName;
}
public void setModelPackageName(String modelPackageName) {
this.modelPackageName = modelPackageName;
}
public String getEntityName() {
return entityName;
}
public void setEntityName(String entityName) {
this.entityName = entityName;
}
public String getModelMapperPackageName() {
return modelMapperPackageName;
}
public void setModelMapperPackageName(String modelMapperPackageName) {
this.modelMapperPackageName = modelMapperPackageName;
}
public Boolean getEntitySwitch() {
return entitySwitch;
}
public void setEntitySwitch(Boolean entitySwitch) {
this.entitySwitch = entitySwitch;
}
public Boolean getSqlSwitch() {
return sqlSwitch;
}
public void setSqlSwitch(Boolean sqlSwitch) {
this.sqlSwitch = sqlSwitch;
}
public String getProPackage() {
return proPackage;
}
public void setProPackage(String proPackage) {
this.proPackage = proPackage;
}
public String getCoreBasePackage() {
return coreBasePackage;
}
public void setCoreBasePackage(String coreBasePackage) {
this.coreBasePackage = coreBasePackage;
}
}

70
src/main/java/cn/stylefeng/guns/generator/engine/config/ControllerConfig.java

@ -0,0 +1,70 @@
package cn.stylefeng.guns.generator.engine.config;
import java.util.ArrayList;
import java.util.List;
/**
* 控制器模板生成的配置
*
* @author fengshuonan
* @date 2017-05-07 22:12
*/
public class ControllerConfig {
private ContextConfig contextConfig;
private String controllerPathTemplate;
private String packageName;//包名称
private List<String> imports;//所引入的包
public void init() {
ArrayList<String> imports = new ArrayList<>();
imports.add("cn.stylefeng.roses.core.base.controller.BaseController");
imports.add("org.springframework.stereotype.Controller");
imports.add("org.springframework.web.bind.annotation.RequestMapping");
imports.add("org.springframework.web.bind.annotation.ResponseBody");
imports.add("org.springframework.ui.Model");
imports.add("org.springframework.web.bind.annotation.PathVariable");
imports.add("org.springframework.beans.factory.annotation.Autowired");
imports.add(contextConfig.getProPackage() + ".core.log.LogObjectHolder");
imports.add("org.springframework.web.bind.annotation.RequestParam");
imports.add(contextConfig.getModelPackageName() + "." + contextConfig.getEntityName());
imports.add(contextConfig.getProPackage() + ".modular." + contextConfig.getModuleName() + ".service" + ".I" + contextConfig.getEntityName() + "Service");
this.imports = imports;
this.packageName = contextConfig.getProPackage() + ".modular." + contextConfig.getModuleName() + ".controller";
this.controllerPathTemplate = "/src/main/java/"+contextConfig.getProPackage().replaceAll("\\.","/")+"/modular/" + contextConfig.getModuleName() + "/controller/{}Controller.java";
}
public String getPackageName() {
return packageName;
}
public void setPackageName(String packageName) {
this.packageName = packageName;
}
public List<String> getImports() {
return imports;
}
public void setImports(List<String> imports) {
this.imports = imports;
}
public String getControllerPathTemplate() {
return controllerPathTemplate;
}
public void setControllerPathTemplate(String controllerPathTemplate) {
this.controllerPathTemplate = controllerPathTemplate;
}
public ContextConfig getContextConfig() {
return contextConfig;
}
public void setContextConfig(ContextConfig contextConfig) {
this.contextConfig = contextConfig;
}
}

55
src/main/java/cn/stylefeng/guns/generator/engine/config/DaoConfig.java

@ -0,0 +1,55 @@
package cn.stylefeng.guns.generator.engine.config;
/**
* Dao模板生成的配置
*
* @author fengshuonan
* @date 2017-05-07 22:12
*/
public class DaoConfig {
private ContextConfig contextConfig;
private String daoPathTemplate;
private String xmlPathTemplate;
private String packageName;
public void init() {
this.daoPathTemplate = "/src/main/java/" + contextConfig.getProPackage().replaceAll("\\.", "/") + "/modular/" + contextConfig.getModuleName() + "/dao/{}Dao.java";
this.xmlPathTemplate = "/src/main/java/" + contextConfig.getProPackage().replaceAll("\\.", "/") + "/modular/" + contextConfig.getModuleName() + "/dao/mapping/{}Dao.xml";
this.packageName = contextConfig.getProPackage() + ".modular." + contextConfig.getModuleName() + ".dao";
}
public String getPackageName() {
return packageName;
}
public void setPackageName(String packageName) {
this.packageName = packageName;
}
public String getDaoPathTemplate() {
return daoPathTemplate;
}
public void setDaoPathTemplate(String daoPathTemplate) {
this.daoPathTemplate = daoPathTemplate;
}
public String getXmlPathTemplate() {
return xmlPathTemplate;
}
public void setXmlPathTemplate(String xmlPathTemplate) {
this.xmlPathTemplate = xmlPathTemplate;
}
public ContextConfig getContextConfig() {
return contextConfig;
}
public void setContextConfig(ContextConfig contextConfig) {
this.contextConfig = contextConfig;
}
}

203
src/main/java/cn/stylefeng/guns/generator/engine/config/Menu.java

@ -0,0 +1,203 @@
package cn.stylefeng.guns.generator.engine.config;
import com.baomidou.mybatisplus.activerecord.Model;
import com.baomidou.mybatisplus.annotations.TableId;
import com.baomidou.mybatisplus.enums.IdType;
import java.io.Serializable;
/**
* <p>
* 菜单表
* </p>
*
* @author stylefeng
* @since 2017-07-11
*/
public class Menu extends Model<Menu> {
private static final long serialVersionUID = 1L;
/**
* 主键id
*/
@TableId(value = "id", type = IdType.AUTO)
private Long id;
/**
* 菜单编号
*/
private String code;
/**
* 菜单父编号
*/
private String pcode;
/**
* 当前菜单的所有父菜单编号
*/
private String pcodes;
/**
* 菜单名称
*/
private String name;
/**
* 菜单图标
*/
private String icon;
/**
* url地址
*/
private String url;
/**
* 菜单排序号
*/
private Integer num;
/**
* 菜单层级
*/
private Integer levels;
/**
* 是否是菜单1 0不是
*/
private Integer ismenu;
/**
* 备注
*/
private String tips;
/**
* 菜单状态 : 1:启用 0:不启用
*/
private Integer status;
/**
* 是否打开: 1:打开 0:不打开
*/
private Integer isopen;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getPcode() {
return pcode;
}
public void setPcode(String pcode) {
this.pcode = pcode;
}
public String getPcodes() {
return pcodes;
}
public void setPcodes(String pcodes) {
this.pcodes = pcodes;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getIcon() {
return icon;
}
public void setIcon(String icon) {
this.icon = icon;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public Integer getNum() {
return num;
}
public void setNum(Integer num) {
this.num = num;
}
public Integer getLevels() {
return levels;
}
public void setLevels(Integer levels) {
this.levels = levels;
}
public Integer getIsmenu() {
return ismenu;
}
public void setIsmenu(Integer ismenu) {
this.ismenu = ismenu;
}
public String getTips() {
return tips;
}
public void setTips(String tips) {
this.tips = tips;
}
public Integer getStatus() {
return status;
}
public void setStatus(Integer status) {
this.status = status;
}
public Integer getIsopen() {
return isopen;
}
public void setIsopen(Integer isopen) {
this.isopen = isopen;
}
@Override
protected Serializable pkVal() {
return this.id;
}
@Override
public String toString() {
return "Menu{" +
"id=" + id +
", code=" + code +
", pcode=" + pcode +
", pcodes=" + pcodes +
", name=" + name +
", icon=" + icon +
", url=" + url +
", num=" + num +
", levels=" + levels +
", ismenu=" + ismenu +
", tips=" + tips +
", status=" + status +
", isopen=" + isopen +
"}";
}
}

74
src/main/java/cn/stylefeng/guns/generator/engine/config/PageConfig.java

@ -0,0 +1,74 @@
package cn.stylefeng.guns.generator.engine.config;
/**
* 页面 模板生成的配置
*
* @author fengshuonan
* @date 2017-05-07 22:12
*/
public class PageConfig {
private ContextConfig contextConfig;
private String pagePathTemplate;
private String pageAddPathTemplate;
private String pageEditPathTemplate;
private String pageJsPathTemplate;
private String pageInfoJsPathTemplate;
public void init() {
pagePathTemplate = "/src/main/webapp/WEB-INF/view/" + contextConfig.getModuleName() + "/{}/{}.html";
pageAddPathTemplate = "/src/main/webapp/WEB-INF/view/" + contextConfig.getModuleName() + "/{}/{}_add.html";
pageEditPathTemplate = "/src/main/webapp/WEB-INF/view/" + contextConfig.getModuleName() + "/{}/{}_edit.html";
pageJsPathTemplate = "/src/main/webapp/static/modular/" + contextConfig.getModuleName() + "/{}/{}.js";
pageInfoJsPathTemplate = "/src/main/webapp/static/modular/" + contextConfig.getModuleName() + "/{}/{}_info.js";
}
public String getPagePathTemplate() {
return pagePathTemplate;
}
public void setPagePathTemplate(String pagePathTemplate) {
this.pagePathTemplate = pagePathTemplate;
}
public String getPageJsPathTemplate() {
return pageJsPathTemplate;
}
public void setPageJsPathTemplate(String pageJsPathTemplate) {
this.pageJsPathTemplate = pageJsPathTemplate;
}
public String getPageAddPathTemplate() {
return pageAddPathTemplate;
}
public void setPageAddPathTemplate(String pageAddPathTemplate) {
this.pageAddPathTemplate = pageAddPathTemplate;
}
public String getPageEditPathTemplate() {
return pageEditPathTemplate;
}
public void setPageEditPathTemplate(String pageEditPathTemplate) {
this.pageEditPathTemplate = pageEditPathTemplate;
}
public String getPageInfoJsPathTemplate() {
return pageInfoJsPathTemplate;
}
public void setPageInfoJsPathTemplate(String pageInfoJsPathTemplate) {
this.pageInfoJsPathTemplate = pageInfoJsPathTemplate;
}
public ContextConfig getContextConfig() {
return contextConfig;
}
public void setContextConfig(ContextConfig contextConfig) {
this.contextConfig = contextConfig;
}
}

91
src/main/java/cn/stylefeng/guns/generator/engine/config/ServiceConfig.java

@ -0,0 +1,91 @@
package cn.stylefeng.guns.generator.engine.config;
import java.util.ArrayList;
import java.util.List;
/**
* Service模板生成的配置
*
* @author fengshuonan
* @date 2017-05-07 22:12
*/
public class ServiceConfig {
private ContextConfig contextConfig;
private String servicePathTemplate;
private String serviceImplPathTemplate;
private String packageName;
private List<String> serviceInterfaceImports;
private List<String> serviceImplImports;
public void init() {
ArrayList<String> imports = new ArrayList<>();
imports.add("org.springframework.stereotype.Service");
imports.add("com.baomidou.mybatisplus.service.impl.ServiceImpl");
imports.add(contextConfig.getModelPackageName() + "." + contextConfig.getEntityName());
imports.add(contextConfig.getModelMapperPackageName() + "." + contextConfig.getEntityName() + "Mapper");
imports.add(contextConfig.getProPackage() + ".modular." + contextConfig.getModuleName() + ".service.I" + contextConfig.getBizEnBigName() + "Service");
this.serviceImplImports = imports;
ArrayList<String> interfaceImports = new ArrayList<>();
interfaceImports.add("com.baomidou.mybatisplus.service.IService");
interfaceImports.add(contextConfig.getModelPackageName() + "." + contextConfig.getEntityName());
this.serviceInterfaceImports = interfaceImports;
this.servicePathTemplate = "/src/main/java/" + contextConfig.getProPackage().replaceAll("\\.", "/") + "/modular/" + contextConfig.getModuleName() + "/service/I{}Service.java";
this.serviceImplPathTemplate = "/src/main/java/" + contextConfig.getProPackage().replaceAll("\\.", "/") + "/modular/" + contextConfig.getModuleName() + "/service/impl/{}ServiceImpl.java";
this.packageName = contextConfig.getProPackage() + ".modular." + contextConfig.getModuleName() + ".service";
}
public String getServicePathTemplate() {
return servicePathTemplate;
}
public void setServicePathTemplate(String servicePathTemplate) {
this.servicePathTemplate = servicePathTemplate;
}
public String getPackageName() {
return packageName;
}
public void setPackageName(String packageName) {
this.packageName = packageName;
}
public String getServiceImplPathTemplate() {
return serviceImplPathTemplate;
}
public void setServiceImplPathTemplate(String serviceImplPathTemplate) {
this.serviceImplPathTemplate = serviceImplPathTemplate;
}
public List<String> getServiceImplImports() {
return serviceImplImports;
}
public void setServiceImplImports(List<String> serviceImplImports) {
this.serviceImplImports = serviceImplImports;
}
public ContextConfig getContextConfig() {
return contextConfig;
}
public void setContextConfig(ContextConfig contextConfig) {
this.contextConfig = contextConfig;
}
public List<String> getServiceInterfaceImports() {
return serviceInterfaceImports;
}
public void setServiceInterfaceImports(List<String> serviceInterfaceImports) {
this.serviceInterfaceImports = serviceInterfaceImports;
}
}

194
src/main/java/cn/stylefeng/guns/generator/engine/config/SqlConfig.java

@ -0,0 +1,194 @@
package cn.stylefeng.guns.generator.engine.config;
import cn.stylefeng.roses.core.util.ToolUtil;
import cn.stylefeng.roses.kernel.model.enums.YesOrNotEnum;
import com.baomidou.mybatisplus.toolkit.IdWorker;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
/**
* 全局配置
*
* @author fengshuonan
* @date 2017-05-08 20:21
*/
public class SqlConfig {
private String sqlPathTemplate;
private ContextConfig contextConfig;
private Connection connection;
private String parentMenuName;
private List<Menu> menus = new ArrayList<>(6);
public void init() {
this.sqlPathTemplate = "/src/main/java/{}.sql";
if (parentMenuName == null) {
return;
}
//根据父菜单查询数据库中的pcode和pcodes
String[] pcodeAndPcodes = getPcodeAndPcodes();
if (pcodeAndPcodes == null) {
System.err.println("父级菜单名称输入有误!!!!");
return;
}
//业务菜单
Menu menu = new Menu();
menu.setId(IdWorker.getId());
menu.setCode(contextConfig.getBizEnName());
menu.setPcode(pcodeAndPcodes[0]);
menu.setPcodes(pcodeAndPcodes[1] + "[" + pcodeAndPcodes[0] + "],");
menu.setName(contextConfig.getBizChName());
menu.setIcon("");
menu.setUrl("/" + contextConfig.getBizEnName());
menu.setNum(99);
if (parentMenuName.equals("顶级")) {
menu.setLevels(1);
} else {
menu.setLevels(2);
}
menu.setIsmenu(YesOrNotEnum.Y.getCode());
menu.setStatus(1);
menu.setIsopen(0);
menus.add(menu);
//列表
Menu list = createSubMenu(menu);
list.setCode(contextConfig.getBizEnName() + "_list");
list.setName(contextConfig.getBizChName() + "列表");
list.setUrl("/" + contextConfig.getBizEnName() + "/list");
menus.add(list);
//添加
Menu add = createSubMenu(menu);
add.setCode(contextConfig.getBizEnName() + "_add");
add.setName(contextConfig.getBizChName() + "添加");
add.setUrl("/" + contextConfig.getBizEnName() + "/add");
menus.add(add);
//更新
Menu update = createSubMenu(menu);
update.setCode(contextConfig.getBizEnName() + "_update");
update.setName(contextConfig.getBizChName() + "更新");
update.setUrl("/" + contextConfig.getBizEnName() + "/update");
menus.add(update);
//删除
Menu delete = createSubMenu(menu);
delete.setCode(contextConfig.getBizEnName() + "_delete");
delete.setName(contextConfig.getBizChName() + "删除");
delete.setUrl("/" + contextConfig.getBizEnName() + "/delete");
menus.add(delete);
//详情
Menu detail = createSubMenu(menu);
detail.setCode(contextConfig.getBizEnName() + "_detail");
detail.setName(contextConfig.getBizChName() + "详情");
detail.setUrl("/" + contextConfig.getBizEnName() + "/detail");
menus.add(detail);
}
private Menu createSubMenu(Menu parentMenu) {
Menu menu = new Menu();
menu.setId(IdWorker.getId());
menu.setPcode(parentMenu.getCode());
menu.setPcodes(parentMenu.getPcodes() + "[" + parentMenu.getCode() + "],");
menu.setIcon("");
menu.setNum(99);
menu.setLevels(parentMenu.getLevels() + 1);
menu.setIsmenu(YesOrNotEnum.N.getCode());
menu.setStatus(1);
menu.setIsopen(0);
return menu;
}
public String[] getPcodeAndPcodes() {
if (parentMenuName.equals("顶级")) {
return new String[]{"0", ""};
}
PreparedStatement preparedStatement = null;
try {
preparedStatement = connection.prepareStatement("select * from sys_menu where name like ?");
preparedStatement.setString(1, "%" + parentMenuName + "%");
ResultSet results = preparedStatement.executeQuery();
while (results.next()) {
String pcode = results.getString("code");
String pcodes = results.getString("pcodes");
if (ToolUtil.isNotEmpty(pcode) && ToolUtil.isNotEmpty(pcodes)) {
String[] strings = {pcode, pcodes};
return strings;
} else {
return null;
}
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
// 释放资源
try {
if (preparedStatement != null) {
preparedStatement.close();
}
if (connection != null) {
connection.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
return null;
}
public ContextConfig getContextConfig() {
return contextConfig;
}
public void setContextConfig(ContextConfig contextConfig) {
this.contextConfig = contextConfig;
}
public String getParentMenuName() {
return parentMenuName;
}
public void setParentMenuName(String parentMenuName) {
this.parentMenuName = parentMenuName;
}
public Connection getConnection() {
return connection;
}
public void setConnection(Connection connection) {
this.connection = connection;
}
public String getSqlPathTemplate() {
return sqlPathTemplate;
}
public void setSqlPathTemplate(String sqlPathTemplate) {
this.sqlPathTemplate = sqlPathTemplate;
}
public List<Menu> getMenus() {
return menus;
}
public void setMenus(List<Menu> menus) {
this.menus = menus;
}
}

30
src/main/java/cn/stylefeng/guns/generator/executor/GunsCodeGenerator.java

@ -0,0 +1,30 @@
package cn.stylefeng.guns.generator.executor;
import cn.stylefeng.guns.generator.executor.config.GunsGeneratorConfig;
/**
* 代码生成器,可以生成实体,dao,service,controller,html,js
*
* @author stylefeng
* @Date 2017/5/21 12:38
*/
public class GunsCodeGenerator {
public static void main(String[] args) {
/**
* Mybatis-Plus的代码生成器:
* mp的代码生成器可以生成实体,mapper,mapper对应的xml,service
*/
GunsGeneratorConfig gunsGeneratorConfig = new GunsGeneratorConfig();
gunsGeneratorConfig.doMpGeneration();
/**
* guns的生成器:
* guns的代码生成器可以生成controller,html页面,页面对应的js
*/
gunsGeneratorConfig.doGunsGeneration();
}
}

109
src/main/java/cn/stylefeng/guns/generator/executor/config/AbstractGeneratorConfig.java

@ -0,0 +1,109 @@
package cn.stylefeng.guns.generator.executor.config;
import cn.hutool.core.io.FileUtil;
import cn.stylefeng.guns.generator.engine.base.GunsTemplateEngine;
import cn.stylefeng.guns.generator.engine.config.SqlConfig;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
import com.baomidou.mybatisplus.generator.config.GlobalConfig;
import com.baomidou.mybatisplus.generator.config.PackageConfig;
import com.baomidou.mybatisplus.generator.config.StrategyConfig;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import cn.stylefeng.guns.generator.engine.SimpleTemplateEngine;
import cn.stylefeng.guns.generator.engine.config.ContextConfig;
import java.io.File;
import java.util.List;
/**
* 代码生成的抽象配置
*
* @author fengshuonan
* @date 2017-10-28-下午8:22
*/
public abstract class AbstractGeneratorConfig {
/**
* mybatis-plus代码生成器配置
*/
GlobalConfig globalConfig = new GlobalConfig();
DataSourceConfig dataSourceConfig = new DataSourceConfig();
StrategyConfig strategyConfig = new StrategyConfig();
PackageConfig packageConfig = new PackageConfig();
TableInfo tableInfo = null;
/**
* Guns代码生成器配置
*/
ContextConfig contextConfig = new ContextConfig();
SqlConfig sqlConfig = new SqlConfig();
protected abstract void config();
public void init() {
config();
packageConfig.setService(contextConfig.getProPackage() + ".modular." + contextConfig.getModuleName() + ".service");
packageConfig.setServiceImpl(contextConfig.getProPackage() + ".modular." + contextConfig.getModuleName() + ".service.impl");
//controller没用掉,生成之后会自动删掉
packageConfig.setController("TTT");
if (!contextConfig.getEntitySwitch()) {
packageConfig.setEntity("TTT");
}
if (!contextConfig.getDaoSwitch()) {
packageConfig.setMapper("TTT");
packageConfig.setXml("TTT");
}
if (!contextConfig.getServiceSwitch()) {
packageConfig.setService("TTT");
packageConfig.setServiceImpl("TTT");
}
}
/**
* 删除不必要的代码
*/
public void destory() {
String outputDir = globalConfig.getOutputDir() + "/TTT";
FileUtil.del(new File(outputDir));
}
public AbstractGeneratorConfig() {
}
public void doMpGeneration() {
init();
AutoGenerator autoGenerator = new AutoGenerator();
autoGenerator.setGlobalConfig(globalConfig);
autoGenerator.setDataSource(dataSourceConfig);
autoGenerator.setStrategy(strategyConfig);
autoGenerator.setPackageInfo(packageConfig);
autoGenerator.execute();
destory();
//获取table信息,用于guns代码生成
List<TableInfo> tableInfoList = autoGenerator.getConfig().getTableInfoList();
if (tableInfoList != null && tableInfoList.size() > 0) {
this.tableInfo = tableInfoList.get(0);
}
}
public void doGunsGeneration() {
GunsTemplateEngine GunsTemplateEngine = new SimpleTemplateEngine();
GunsTemplateEngine.setContextConfig(contextConfig);
sqlConfig.setConnection(dataSourceConfig.getConn());
GunsTemplateEngine.setSqlConfig(sqlConfig);
GunsTemplateEngine.setTableInfo(tableInfo);
GunsTemplateEngine.start();
}
}

81
src/main/java/cn/stylefeng/guns/generator/executor/config/GunsGeneratorConfig.java

@ -0,0 +1,81 @@
package cn.stylefeng.guns.generator.executor.config;
import com.baomidou.mybatisplus.generator.config.rules.DbType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
/**
* 默认的代码生成的配置
*
* @author fengshuonan
* @date 2017-10-28-下午8:27
*/
public class GunsGeneratorConfig extends AbstractGeneratorConfig {
protected void globalConfig() {
globalConfig.setOutputDir("D:\\ttt");//写自己项目的绝对路径,注意具体到java目录
globalConfig.setFileOverride(true);
globalConfig.setEnableCache(false);
globalConfig.setBaseResultMap(true);
globalConfig.setBaseColumnList(true);
globalConfig.setOpen(false);
globalConfig.setAuthor("stylefeng");
}
protected void dataSourceConfig() {
dataSourceConfig.setDbType(DbType.MYSQL);
dataSourceConfig.setDriverName("com.mysql.jdbc.Driver");
dataSourceConfig.setUsername("root");
dataSourceConfig.setPassword("root");
dataSourceConfig.setUrl("jdbc:mysql://127.0.0.1:3306/guns?characterEncoding=utf8");
}
protected void strategyConfig() {
strategyConfig.setTablePrefix(new String[]{"sys_"});// 此处可以修改为您的表前缀
strategyConfig.setNaming(NamingStrategy.underline_to_camel);
}
protected void packageConfig() {
packageConfig.setParent(null);
packageConfig.setEntity("cn.stylefeng.guns.admin.common.persistence.model");
packageConfig.setMapper("cn.stylefeng.guns.admin.common.persistence.dao");
packageConfig.setXml("cn.stylefeng.guns.admin.common.persistence.dao.mapping");
}
protected void contextConfig() {
contextConfig.setProPackage("cn.stylefeng.guns.admin");
contextConfig.setCoreBasePackage("cn.stylefeng.guns.core");
contextConfig.setBizChName("字典管理");
contextConfig.setBizEnName("sysDict");
contextConfig.setModuleName("system");
contextConfig.setProjectPath("D:\\ideaSpace\\guns\\guns-admin");//写自己项目的绝对路径
contextConfig.setEntityName("SysDict");
sqlConfig.setParentMenuName(null);//这里写已有菜单的名称,当做父节点
/**
* mybatis-plus 生成器开关
*/
contextConfig.setEntitySwitch(true);
contextConfig.setDaoSwitch(true);
contextConfig.setServiceSwitch(true);
/**
* guns 生成器开关
*/
contextConfig.setControllerSwitch(true);
contextConfig.setIndexPageSwitch(true);
contextConfig.setAddPageSwitch(true);
contextConfig.setEditPageSwitch(true);
contextConfig.setJsSwitch(true);
contextConfig.setInfoJsSwitch(true);
contextConfig.setSqlSwitch(true);
}
@Override
protected void config() {
globalConfig();
dataSourceConfig();
strategyConfig();
packageConfig();
contextConfig();
}
}

97
src/main/java/cn/stylefeng/guns/generator/executor/config/WebGeneratorConfig.java

@ -0,0 +1,97 @@
package cn.stylefeng.guns.generator.executor.config;
import cn.hutool.core.util.StrUtil;
import cn.stylefeng.roses.core.util.ToolUtil;
import com.baomidou.mybatisplus.generator.config.rules.DbType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import cn.stylefeng.guns.generator.executor.model.GenQo;
import java.io.File;
/**
* 默认的代码生成的配置
*
* @author fengshuonan
* @date 2017-10-28-下午8:27
*/
public class WebGeneratorConfig extends AbstractGeneratorConfig {
private GenQo genQo;
public WebGeneratorConfig(GenQo genQo) {
this.genQo = genQo;
}
@Override
protected void config() {
/**
* 数据库配置
*/
dataSourceConfig.setDbType(DbType.MYSQL);
dataSourceConfig.setDriverName("com.mysql.cj.jdbc.Driver");
dataSourceConfig.setUsername(genQo.getUserName());
dataSourceConfig.setPassword(genQo.getPassword());
dataSourceConfig.setUrl(genQo.getUrl());
/**
* 全局配置
*/
globalConfig.setOutputDir(genQo.getProjectPath() + File.separator + "src" + File.separator + "main" + File.separator + "java");
globalConfig.setFileOverride(true);
globalConfig.setEnableCache(false);
globalConfig.setBaseResultMap(true);
globalConfig.setBaseColumnList(true);
globalConfig.setOpen(false);
globalConfig.setAuthor(genQo.getAuthor());
contextConfig.setProPackage(genQo.getProjectPackage());
contextConfig.setCoreBasePackage(genQo.getCorePackage());
/**
* 生成策略
*/
if (genQo.getIgnoreTabelPrefix() != null) {
strategyConfig.setTablePrefix(new String[]{genQo.getIgnoreTabelPrefix()});
}
strategyConfig.setInclude(new String[]{genQo.getTableName()});
strategyConfig.setNaming(NamingStrategy.underline_to_camel);
packageConfig.setParent(null);
packageConfig.setEntity(genQo.getProjectPackage() + ".modular.system.model");
packageConfig.setMapper(genQo.getProjectPackage() + ".modular.system.dao");
packageConfig.setXml(genQo.getProjectPackage() + ".modular.system.dao.mapping");
/**
* 业务代码配置
*/
contextConfig.setBizChName(genQo.getBizName());
contextConfig.setModuleName(genQo.getModuleName());
contextConfig.setProjectPath(genQo.getProjectPath());//写自己项目的绝对路径
if(ToolUtil.isEmpty(genQo.getIgnoreTabelPrefix())){
String entityName = StrUtil.toCamelCase(genQo.getTableName());
contextConfig.setEntityName(StrUtil.upperFirst(entityName));
contextConfig.setBizEnName(StrUtil.lowerFirst(entityName));
}else{
String entiyName = StrUtil.toCamelCase(StrUtil.removePrefix(genQo.getTableName(), genQo.getIgnoreTabelPrefix()));
contextConfig.setEntityName(StrUtil.upperFirst(entiyName));
contextConfig.setBizEnName(StrUtil.lowerFirst(entiyName));
}
sqlConfig.setParentMenuName(genQo.getParentMenuName());//这里写已有菜单的名称,当做父节点
/**
* mybatis-plus 生成器开关
*/
contextConfig.setEntitySwitch(genQo.getEntitySwitch());
contextConfig.setDaoSwitch(genQo.getDaoSwitch());
contextConfig.setServiceSwitch(genQo.getServiceSwitch());
/**
* guns 生成器开关
*/
contextConfig.setControllerSwitch(genQo.getControllerSwitch());
contextConfig.setIndexPageSwitch(genQo.getIndexPageSwitch());
contextConfig.setAddPageSwitch(genQo.getAddPageSwitch());
contextConfig.setEditPageSwitch(genQo.getEditPageSwitch());
contextConfig.setJsSwitch(genQo.getJsSwitch());
contextConfig.setInfoJsSwitch(genQo.getInfoJsSwitch());
contextConfig.setSqlSwitch(genQo.getSqlSwitch());
}
}

297
src/main/java/cn/stylefeng/guns/generator/executor/model/GenQo.java

@ -0,0 +1,297 @@
package cn.stylefeng.guns.generator.executor.model;
/**
* 代码生成的查询参数
*
* @author fengshuonan
* @date 2017-11-30-下午2:05
*/
public class GenQo {
/**
* 数据库账号
*/
private String userName;
/**
* 数据库密码
*/
private String password;
/**
* 数据库url
*/
private String url;
/**
* 项目地址
*/
private String projectPath;
/**
* 作者
*/
private String author;
/**
* 项目的包
*/
private String projectPackage;
/**
* 核心模块的包
*/
private String corePackage;
/**
* 表名称
*/
private String tableName;
/**
* 忽略的表前缀
*/
private String ignoreTabelPrefix;
/**
* 业务名称
*/
private String bizName;
/**
* 模块名
*/
private String moduleName;
/**
* 父级菜单名称
*/
private String parentMenuName;
/**
* 是否生成控制器代码开关
*/
private Boolean controllerSwitch = false;
/**
* 主页
*/
private Boolean indexPageSwitch = false;
/**
* 添加页面
*/
private Boolean addPageSwitch = false;
/**
* 编辑页面
*/
private Boolean editPageSwitch = false;
/**
* 主页的js
*/
private Boolean jsSwitch = false;
/**
* 详情页面js
*/
private Boolean infoJsSwitch = false;
/**
* dao的开关
*/
private Boolean daoSwitch = false;
/**
* service
*/
private Boolean serviceSwitch = false;
/**
* 生成实体的开关
*/
private Boolean entitySwitch = false;
/**
* 生成sql的开关
*/
private Boolean sqlSwitch = false;
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getProjectPath() {
return projectPath;
}
public void setProjectPath(String projectPath) {
this.projectPath = projectPath;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public String getCorePackage() {
return corePackage;
}
public void setCorePackage(String corePackage) {
this.corePackage = corePackage;
}
public String getProjectPackage() {
return projectPackage;
}
public void setProjectPackage(String projectPackage) {
this.projectPackage = projectPackage;
}
public String getTableName() {
return tableName;
}
public void setTableName(String tableName) {
this.tableName = tableName;
}
public String getIgnoreTabelPrefix() {
return ignoreTabelPrefix;
}
public void setIgnoreTabelPrefix(String ignoreTabelPrefix) {
this.ignoreTabelPrefix = ignoreTabelPrefix;
}
public String getBizName() {
return bizName;
}
public void setBizName(String bizName) {
this.bizName = bizName;
}
public String getModuleName() {
return moduleName;
}
public void setModuleName(String moduleName) {
this.moduleName = moduleName;
}
public Boolean getControllerSwitch() {
return controllerSwitch;
}
public void setControllerSwitch(Boolean controllerSwitch) {
this.controllerSwitch = controllerSwitch;
}
public Boolean getIndexPageSwitch() {
return indexPageSwitch;
}
public void setIndexPageSwitch(Boolean indexPageSwitch) {
this.indexPageSwitch = indexPageSwitch;
}
public Boolean getAddPageSwitch() {
return addPageSwitch;
}
public void setAddPageSwitch(Boolean addPageSwitch) {
this.addPageSwitch = addPageSwitch;
}
public Boolean getEditPageSwitch() {
return editPageSwitch;
}
public void setEditPageSwitch(Boolean editPageSwitch) {
this.editPageSwitch = editPageSwitch;
}
public Boolean getJsSwitch() {
return jsSwitch;
}
public void setJsSwitch(Boolean jsSwitch) {
this.jsSwitch = jsSwitch;
}
public Boolean getInfoJsSwitch() {
return infoJsSwitch;
}
public void setInfoJsSwitch(Boolean infoJsSwitch) {
this.infoJsSwitch = infoJsSwitch;
}
public Boolean getDaoSwitch() {
return daoSwitch;
}
public void setDaoSwitch(Boolean daoSwitch) {
this.daoSwitch = daoSwitch;
}
public Boolean getServiceSwitch() {
return serviceSwitch;
}
public void setServiceSwitch(Boolean serviceSwitch) {
this.serviceSwitch = serviceSwitch;
}
public Boolean getEntitySwitch() {
return entitySwitch;
}
public void setEntitySwitch(Boolean entitySwitch) {
this.entitySwitch = entitySwitch;
}
public Boolean getSqlSwitch() {
return sqlSwitch;
}
public void setSqlSwitch(Boolean sqlSwitch) {
this.sqlSwitch = sqlSwitch;
}
public String getParentMenuName() {
return parentMenuName;
}
public void setParentMenuName(String parentMenuName) {
this.parentMenuName = parentMenuName;
}
}

59
src/main/java/cn/stylefeng/guns/generator/modular/controller/CodeController.java

@ -0,0 +1,59 @@
package cn.stylefeng.guns.generator.modular.controller;
import cn.stylefeng.roses.core.base.controller.BaseController;
import cn.stylefeng.roses.core.config.properties.DruidProperties;
import cn.stylefeng.guns.generator.executor.config.WebGeneratorConfig;
import cn.stylefeng.guns.generator.executor.model.GenQo;
import cn.stylefeng.guns.generator.modular.factory.DefaultTemplateFactory;
import cn.stylefeng.guns.generator.modular.service.TableService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
/**
* 代码生成控制器
*
* @author fengshuonan
* @Date 2017年11月30日16:39:19
*/
@Controller
@RequestMapping("/code")
public class CodeController extends BaseController {
private static String PREFIX = "/code";
@Autowired
private TableService tableService;
@Autowired
private DruidProperties druidProperties;
/**
* 跳转到代码生成主页
*/
@RequestMapping("")
public String blackboard(Model model) {
model.addAttribute("tables", tableService.getAllTables());
model.addAttribute("params", DefaultTemplateFactory.getDefaultParams());
model.addAttribute("templates", DefaultTemplateFactory.getDefaultTemplates());
return PREFIX + "/code.html";
}
/**
* 生成代码
*/
@RequestMapping(value = "/generate", method = RequestMethod.POST)
@ResponseBody
public Object generate(GenQo genQo) {
genQo.setUrl(druidProperties.getUrl());
genQo.setUserName(druidProperties.getUsername());
genQo.setPassword(druidProperties.getPassword());
WebGeneratorConfig webGeneratorConfig = new WebGeneratorConfig(genQo);
webGeneratorConfig.doMpGeneration();
webGeneratorConfig.doGunsGeneration();
return SUCCESS_TIP;
}
}

71
src/main/java/cn/stylefeng/guns/generator/modular/entity/CodeDbInfo.java

@ -0,0 +1,71 @@
package cn.stylefeng.guns.generator.modular.entity;
import com.baomidou.mybatisplus.annotations.TableField;
import com.baomidou.mybatisplus.annotations.TableId;
import com.baomidou.mybatisplus.annotations.TableName;
import com.baomidou.mybatisplus.enums.FieldFill;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
/**
* <p>
* 数据库链接信息
* </p>
*
* @author fengshuonan
* @since 2018-07-27
*/
@TableName("code_dbinfo")
@Data
public class CodeDbInfo implements Serializable {
private static final long serialVersionUID = 1L;
/**
* ID
*/
@TableId("id")
private Long id;
/**
* 别名
*/
private String name;
/**
* 数据库驱动
*/
@TableField("db_driver")
private String dbDriver;
/**
* 数据库地址
*/
@TableField("db_url")
private String dbUrl;
/**
* 数据库账户
*/
@TableField("db_user_name")
private String dbUserName;
/**
* 连接密码
*/
@TableField("db_password")
private String dbPassword;
/**
* 数据库类型
*/
@TableField("db_type")
private String dbType;
/**
* 创建时间
*/
@TableField(value = "create_time", fill = FieldFill.INSERT)
private Date createTime;
/**
* 更新时间
*/
@TableField(value = "update_time", fill = FieldFill.UPDATE)
private Date updateTime;
}

59
src/main/java/cn/stylefeng/guns/generator/modular/factory/DefaultTemplateFactory.java

@ -0,0 +1,59 @@
package cn.stylefeng.guns.generator.modular.factory;
import cn.stylefeng.roses.core.util.ToolUtil;
import cn.stylefeng.guns.generator.executor.model.GenQo;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 模板种类构建器
*
* @author fengshuonan
* @date 2017-12-04-下午2:59
*/
public class DefaultTemplateFactory {
/**
* 获取所有的模板种类
*/
public static List<Map<String, Object>> getDefaultTemplates() {
ArrayList<Map<String, Object>> templates = new ArrayList<>();
templates.add(create("controllerSwitch", "controller-控制器模板"));
templates.add(create("entitySwitch", "entity-实体模板"));
templates.add(create("serviceSwitch", "service-service模板"));
templates.add(create("daoSwitch", "dao-dao模板"));
templates.add(create("indexPageSwitch", "indexPage-首页模板"));
templates.add(create("addPageSwitch", "addPage-添加页面模板"));
templates.add(create("editPageSwitch", "editPage-编辑页面模板"));
templates.add(create("jsSwitch", "indexJs-主页js模板"));
templates.add(create("infoJsSwitch", "infoJs-详情页js模板"));
templates.add(create("sqlSwitch", "sql-sql语句模板"));
return templates;
}
/**
* 获取默认的参数
*/
public static GenQo getDefaultParams() {
GenQo genQo = new GenQo();
genQo.setProjectPath(ToolUtil.getWebRootPath(null));
genQo.setAuthor("stylefeng");
genQo.setProjectPackage("cn.stylefeng.guns");
genQo.setCorePackage("cn.stylefeng.guns.core");
genQo.setIgnoreTabelPrefix("sys_");
genQo.setModuleName("system");
genQo.setParentMenuName("系统管理");
return genQo;
}
private static Map<String, Object> create(String key, String desc) {
HashMap<String, Object> template = new HashMap<>();
template.put("key", key);
template.put("desc", desc);
return template;
}
}

29
src/main/java/cn/stylefeng/guns/generator/modular/service/TableService.java

@ -0,0 +1,29 @@
package cn.stylefeng.guns.generator.modular.service;
import com.baomidou.mybatisplus.mapper.SqlRunner;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Map;
/**
* 获取数据库所有的表
*
* @author fengshuonan
* @date 2017-12-04-下午1:37
*/
@Service
public class TableService {
@Value("${spring.datasource.db-name:guns}")
private String dbName;
/**
* 获取当前数据库所有的表信息
*/
public List<Map<String, Object>> getAllTables() {
String sql = "select TABLE_NAME as tableName,TABLE_COMMENT as tableComment from information_schema.`TABLES` where TABLE_SCHEMA = '" + dbName + "'";
return SqlRunner.db().selectList(sql);
}
}

3
src/main/resources/META-INF/spring.factories

@ -0,0 +1,3 @@
# AutoConfiguration
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
cn.stylefeng.guns.generator.config.GeneratorAutoConfiguration

96
src/main/resources/gunsTemplate/advanced/Controller.java.btl

@ -0,0 +1,96 @@
package ${controller.packageName};
<% for(import in controller.imports!){ %>
import ${import};
<% } %>
/**
* ${context.bizChName}控制器
*
* @author fengshuonan
* @Date ${tool.currentTime()}
*/
@Controller
@RequestMapping("/${context.bizEnName}")
public class ${context.bizEnBigName}Controller extends BaseController {
private String PREFIX = "/${context.moduleName}/${context.bizEnName}/";
@Autowired
private I${context.entityName}Service ${context.bizEnName}Service;
/**
* 跳转到${context.bizChName}首页
*/
@RequestMapping("")
public String index() {
return PREFIX + "${context.bizEnName}.html";
}
/**
* 跳转到添加${context.bizChName}
*/
@RequestMapping("/${context.bizEnName}_add")
public String ${context.bizEnName}Add() {
return PREFIX + "${context.bizEnName}_add.html";
}
/**
* 跳转到修改${context.bizChName}
*/
@RequestMapping("/${context.bizEnName}_update/{${context.bizEnName}Id}")
public String ${context.bizEnName}Update(@PathVariable Integer ${context.bizEnName}Id, Model model) {
${context.entityName} ${context.bizEnName} = ${context.bizEnName}Service.selectById(${context.bizEnName}Id);
model.addAttribute("item",${context.bizEnName});
LogObjectHolder.me().set(${context.bizEnName});
return PREFIX + "${context.bizEnName}_edit.html";
}
/**
* 获取${context.bizChName}列表
*/
@RequestMapping(value = "/list")
@ResponseBody
public Object list(String condition) {
return ${context.bizEnName}Service.selectList(null);
}
/**
* 新增${context.bizChName}
*/
@RequestMapping(value = "/add")
@ResponseBody
public Object add(${context.entityName} ${context.bizEnName}) {
${context.bizEnName}Service.insert(${context.bizEnName});
return SUCCESS_TIP;
}
/**
* 删除${context.bizChName}
*/
@RequestMapping(value = "/delete")
@ResponseBody
public Object delete(@RequestParam Integer ${context.bizEnName}Id) {
${context.bizEnName}Service.deleteById(${context.bizEnName}Id);
return SUCCESS_TIP;
}
/**
* 修改${context.bizChName}
*/
@RequestMapping(value = "/update")
@ResponseBody
public Object update(${context.entityName} ${context.bizEnName}) {
${context.bizEnName}Service.updateById(${context.bizEnName});
return SUCCESS_TIP;
}
/**
* ${context.bizChName}详情
*/
@RequestMapping(value = "/detail/{${context.bizEnName}Id}")
@ResponseBody
public Object detail(@PathVariable("${context.bizEnName}Id") Integer ${context.bizEnName}Id) {
return ${context.bizEnName}Service.selectById(${context.bizEnName}Id);
}
}

3
src/main/resources/gunsTemplate/advanced/menu_sql.sql.btl

@ -0,0 +1,3 @@
<% for(menu in sqls.menus!){ %>
INSERT INTO `guns`.`sys_menu` (`id`, `code`, `pcode`, `pcodes`, `name`, `icon`, `url`, `num`, `levels`, `ismenu`, `tips`, `status`, `isopen`) VALUES ('${menu.id}', '${menu.code}', '${menu.pcode}', '${menu.pcodes}', '${menu.name}', '${menu.icon}', '${menu.url}', '${menu.num}', '${menu.levels}', '${menu.ismenu}', NULL, '${menu.status}', '${menu.isopen}');
<% } %>

38
src/main/resources/gunsTemplate/advanced/page.html.btl

@ -0,0 +1,38 @@
@layout("/common/_container.html"){
<div class="row">
<div class="col-sm-12">
<div class="ibox float-e-margins">
<div class="ibox-title">
<h5>${context.bizChName}管理</h5>
</div>
<div class="ibox-content">
<div class="row row-lg">
<div class="col-sm-12">
<div class="row">
<div class="col-sm-3">
<#NameCon id="condition" name="名称" />
</div>
<div class="col-sm-3">
<#button name="搜索" icon="fa-search" clickFun="${context.bizEnBigName}.search()"/>
</div>
</div>
<div class="hidden-xs" id="${context.bizEnBigName}TableToolbar" role="group">
@if(shiro.hasPermission("/${context.bizEnName}/add")){
<#button name="添加" icon="fa-plus" clickFun="${context.bizEnBigName}.openAdd${context.bizEnBigName}()"/>
@}
@if(shiro.hasPermission("/${context.bizEnName}/update")){
<#button name="修改" icon="fa-edit" clickFun="${context.bizEnBigName}.open${context.bizEnBigName}Detail()" space="true"/>
@}
@if(shiro.hasPermission("/${context.bizEnName}/delete")){
<#button name="删除" icon="fa-remove" clickFun="${context.bizEnBigName}.delete()" space="true"/>
@}
</div>
<#table id="${context.bizEnBigName}Table"/>
</div>
</div>
</div>
</div>
</div>
</div>
<script src="\${ctxPath}/static/modular/${context.moduleName}/${context.bizEnName}/${context.bizEnName}.js"></script>
@}

102
src/main/resources/gunsTemplate/advanced/page.js.btl

@ -0,0 +1,102 @@
/**
* ${context.bizChName}管理初始化
*/
var ${context.bizEnBigName} = {
id: "${context.bizEnBigName}Table", //表格id
seItem: null, //选中的条目
table: null,
layerIndex: -1
};
/**
* 初始化表格的列
*/
${context.bizEnBigName}.initColumn = function () {
return [
{field: 'selectItem', radio: true},
<% for(item in table.fields!){ %>
<% if(itemLP.last != true){ %>
{title: '${item.comment}', field: '${item.propertyName}', visible: true, align: 'center', valign: 'middle'},
<% }else{ %>
{title: '${item.comment}', field: '${item.propertyName}', visible: true, align: 'center', valign: 'middle'}
<% }} %>
];
};
/**
* 检查是否选中
*/
${context.bizEnBigName}.check = function () {
var selected = $('#' + this.id).bootstrapTable('getSelections');
if(selected.length == 0){
Feng.info("请先选中表格中的某一记录!");
return false;
}else{
${context.bizEnBigName}.seItem = selected[0];
return true;
}
};
/**
* 点击添加${context.bizChName}
*/
${context.bizEnBigName}.openAdd${context.bizEnBigName} = function () {
var index = layer.open({
type: 2,
title: '添加${context.bizChName}',
area: ['800px', '420px'], //宽高
fix: false, //不固定
maxmin: true,
content: Feng.ctxPath + '/${context.bizEnName}/${context.bizEnName}_add'
});
this.layerIndex = index;
};
/**
* 打开查看${context.bizChName}详情
*/
${context.bizEnBigName}.open${context.bizEnBigName}Detail = function () {
if (this.check()) {
var index = layer.open({
type: 2,
title: '${context.bizChName}详情',
area: ['800px', '420px'], //宽高
fix: false, //不固定
maxmin: true,
content: Feng.ctxPath + '/${context.bizEnName}/${context.bizEnName}_update/' + ${context.bizEnBigName}.seItem.id
});
this.layerIndex = index;
}
};
/**
* 删除${context.bizChName}
*/
${context.bizEnBigName}.delete = function () {
if (this.check()) {
var ajax = new $ax(Feng.ctxPath + "/${context.bizEnName}/delete", function (data) {
Feng.success("删除成功!");
${context.bizEnBigName}.table.refresh();
}, function (data) {
Feng.error("删除失败!" + data.responseJSON.message + "!");
});
ajax.set("${context.bizEnName}Id",this.seItem.id);
ajax.start();
}
};
/**
* 查询${context.bizChName}列表
*/
${context.bizEnBigName}.search = function () {
var queryData = {};
queryData['condition'] = $("#condition").val();
${context.bizEnBigName}.table.refresh({query: queryData});
};
$(function () {
var defaultColunms = ${context.bizEnBigName}.initColumn();
var table = new BSTable(${context.bizEnBigName}.id, "/${context.bizEnName}/list", defaultColunms);
table.setPaginationType("client");
${context.bizEnBigName}.table = table.init();
});

41
src/main/resources/gunsTemplate/advanced/page_add.html.btl

@ -0,0 +1,41 @@
@layout("/common/_container.html"){
<div class="ibox float-e-margins">
<div class="ibox-content">
<div class="form-horizontal">
<div class="row">
<div class="col-sm-6 b-r">
<% var leftSize = tool.toInt((table.fields.~size + 1) / 2); %>
<% var rightSize = tool.toInt(table.fields.~size - leftSize); %>
<% for(var i=0;i<leftSize;i++){ %>
<% if(i != (leftSize-1) ){ %>
<#input id="${table.fields[i].propertyName}" name="${table.fields[i].comment}" underline="true"/>
<% }else{ %>
<#input id="${table.fields[i].propertyName}" name="${table.fields[i].comment}"/>
<% } %>
<% } %>
</div>
<div class="col-sm-6">
<% for(var i=leftSize;i<table.fields.~size;i++){ %>
<% if(i != (rightSize-1) ){ %>
<#input id="${table.fields[i].propertyName}" name="${table.fields[i].comment}" underline="true"/>
<% }else{ %>
<#input id="${table.fields[i].propertyName}" name="${table.fields[i].comment}"/>
<% } %>
<% } %>
</div>
</div>
<div class="row btn-group-m-t">
<div class="col-sm-10">
<#button btnCss="info" name="提交" id="ensure" icon="fa-check" clickFun="${context.bizEnBigName}InfoDlg.addSubmit()"/>
<#button btnCss="danger" name="取消" id="cancel" icon="fa-eraser" clickFun="${context.bizEnBigName}InfoDlg.close()"/>
</div>
</div>
</div>
</div>
</div>
<script src="\${ctxPath}/static/modular/${context.moduleName}/${context.bizEnName}/${context.bizEnName}_info.js"></script>
@}

41
src/main/resources/gunsTemplate/advanced/page_edit.html.btl

@ -0,0 +1,41 @@
@layout("/common/_container.html"){
<div class="ibox float-e-margins">
<div class="ibox-content">
<div class="form-horizontal">
<div class="row">
<div class="col-sm-6 b-r">
<% var leftSize = tool.toInt((table.fields.~size + 1) / 2); %>
<% var rightSize = tool.toInt(table.fields.~size - leftSize); %>
<% for(var i=0;i<leftSize;i++){ %>
<% if(i != (leftSize-1) ){ %>
<#input id="${table.fields[i].propertyName}" name="${table.fields[i].comment}" value="\${item.${table.fields[i].propertyName}}" underline="true"/>
<% }else{ %>
<#input id="${table.fields[i].propertyName}" name="${table.fields[i].comment}" value="\${item.${table.fields[i].propertyName}}" />
<% } %>
<% } %>
</div>
<div class="col-sm-6">
<% for(var i=leftSize;i<table.fields.~size;i++){ %>
<% if(i != (table.fields.~size-1) ){ %>
<#input id="${table.fields[i].propertyName}" name="${table.fields[i].comment}" value="\${item.${table.fields[i].propertyName}}" underline="true"/>
<% }else{ %>
<#input id="${table.fields[i].propertyName}" name="${table.fields[i].comment}" value="\${item.${table.fields[i].propertyName}}" />
<% } %>
<% } %>
</div>
</div>
<div class="row btn-group-m-t">
<div class="col-sm-10">
<#button btnCss="info" name="提交" id="ensure" icon="fa-check" clickFun="${context.bizEnBigName}InfoDlg.editSubmit()"/>
<#button btnCss="danger" name="取消" id="cancel" icon="fa-eraser" clickFun="${context.bizEnBigName}InfoDlg.close()"/>
</div>
</div>
</div>
</div>
</div>
<script src="\${ctxPath}/static/modular/${context.moduleName}/${context.bizEnName}/${context.bizEnName}_info.js"></script>
@}

98
src/main/resources/gunsTemplate/advanced/page_info.js.btl

@ -0,0 +1,98 @@
/**
* 初始化${context.bizChName}详情对话框
*/
var ${context.bizEnBigName}InfoDlg = {
${context.bizEnName}InfoData : {}
};
/**
* 清除数据
*/
${context.bizEnBigName}InfoDlg.clearData = function() {
this.${context.bizEnName}InfoData = {};
}
/**
* 设置对话框中的数据
*
* @param key 数据的名称
* @param val 数据的具体值
*/
${context.bizEnBigName}InfoDlg.set = function(key, val) {
this.${context.bizEnName}InfoData[key] = (typeof val == "undefined") ? $("#" + key).val() : val;
return this;
}
/**
* 设置对话框中的数据
*
* @param key 数据的名称
* @param val 数据的具体值
*/
${context.bizEnBigName}InfoDlg.get = function(key) {
return $("#" + key).val();
}
/**
* 关闭此对话框
*/
${context.bizEnBigName}InfoDlg.close = function() {
parent.layer.close(window.parent.${context.bizEnBigName}.layerIndex);
}
/**
* 收集数据
*/
${context.bizEnBigName}InfoDlg.collectData = function() {
this
<% for(item in table.fields!){ %>
<% if(itemLP.last != true){ %>
.set('${item.propertyName}')
<% }else{ %>
.set('${item.propertyName}');
<% }} %>
}
/**
* 提交添加
*/
${context.bizEnBigName}InfoDlg.addSubmit = function() {
this.clearData();
this.collectData();
//提交信息
var ajax = new $ax(Feng.ctxPath + "/${context.bizEnName}/add", function(data){
Feng.success("添加成功!");
window.parent.${context.bizEnBigName}.table.refresh();
${context.bizEnBigName}InfoDlg.close();
},function(data){
Feng.error("添加失败!" + data.responseJSON.message + "!");
});
ajax.set(this.${context.bizEnName}InfoData);
ajax.start();
}
/**
* 提交修改
*/
${context.bizEnBigName}InfoDlg.editSubmit = function() {
this.clearData();
this.collectData();
//提交信息
var ajax = new $ax(Feng.ctxPath + "/${context.bizEnName}/update", function(data){
Feng.success("修改成功!");
window.parent.${context.bizEnBigName}.table.refresh();
${context.bizEnBigName}InfoDlg.close();
},function(data){
Feng.error("修改失败!" + data.responseJSON.message + "!");
});
ajax.set(this.${context.bizEnName}InfoData);
ajax.start();
}
$(function() {
});
Loading…
Cancel
Save