Commit 2fadc55d 2fadc55dc6dcb0e2ad7a2f3e660fcec2edc76ee9 by lWoHvYe

基本代码生成

0 parents
1 HELP.md
2 target/
3 !.mvn/wrapper/maven-wrapper.jar
4 !**/src/main/**/target/
5 !**/src/test/**/target/
6
7 ### STS ###
8 .apt_generated
9 .classpath
10 .factorypath
11 .project
12 .settings
13 .springBeans
14 .sts4-cache
15
16 ### IntelliJ IDEA ###
17 .idea
18 *.iws
19 *.iml
20 *.ipr
21
22 ### NetBeans ###
23 /nbproject/private/
24 /nbbuild/
25 /dist/
26 /nbdist/
27 /.nb-gradle/
28 build/
29 !**/src/main/**/build/
30 !**/src/test/**/build/
31
32 ### VS Code ###
33 .vscode/
1 <?xml version="1.0" encoding="UTF-8"?>
2 <project xmlns="http://maven.apache.org/POM/4.0.0"
3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5 <!--可使用其他版本,但建议使用cronos-core中的版本-->
6 <parent>
7 <groupId>org.springframework.boot</groupId>
8 <artifactId>spring-boot-starter-parent</artifactId>
9 <version>2.2.10.RELEASE</version>
10 <relativePath/>
11 </parent>
12 <modelVersion>4.0.0</modelVersion>
13
14 <groupId>con.topdraw</groupId>
15 <artifactId>cronos-generator-code</artifactId>
16 <name>自动生成后端代码</name>
17
18 <properties>
19 <jjwt.version>0.9.1</jjwt.version>
20 </properties>
21
22 <dependencies>
23 <!--依赖引入-->
24 <dependency>
25 <groupId>com.topdraw</groupId>
26 <artifactId>cronos-generator</artifactId>
27 <version>1.1.0</version>
28 </dependency>
29 <dependency>
30 <groupId>com.topdraw</groupId>
31 <artifactId>cronos-logging</artifactId>
32 <version>1.1.0</version>
33 </dependency>
34
35 <!-- Spring boot 热部署 : 此热部署会遇到 java.lang.ClassCastException 异常 -->
36 <!-- optional=true,依赖不会传递-->
37 <dependency>
38 <groupId>org.springframework.boot</groupId>
39 <artifactId>spring-boot-devtools</artifactId>
40 <optional>true</optional>
41 <scope>runtime</scope>
42 </dependency>
43 <dependency>
44 <groupId>org.springframework.boot</groupId>
45 <artifactId>spring-boot-starter-test</artifactId>
46 </dependency>
47 <!--Mysql依赖包,版本差异,需单独引入-->
48 <dependency>
49 <groupId>mysql</groupId>
50 <artifactId>mysql-connector-java</artifactId>
51 <version>5.1.40</version>
52 </dependency>
53 <dependency>
54 <groupId>junit</groupId>
55 <artifactId>junit</artifactId>
56 <version>4.12</version>
57 <scope>test</scope>
58 </dependency>
59 </dependencies>
60
61 <build>
62 <plugins>
63 <plugin>
64 <groupId>org.springframework.boot</groupId>
65 <artifactId>spring-boot-maven-plugin</artifactId>
66 <configuration>
67 <fork>true</fork>
68 </configuration>
69 </plugin>
70 </plugins>
71 </build>
72 </project>
1 package com.topdraw;
2
3 import com.topdraw.utils.SpringContextHolder;
4 import org.springframework.boot.SpringApplication;
5 import org.springframework.boot.autoconfigure.SpringBootApplication;
6 import org.springframework.boot.builder.SpringApplicationBuilder;
7 import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
8 import org.springframework.context.annotation.Bean;
9 import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
10 import org.springframework.scheduling.annotation.EnableAsync;
11 import org.springframework.transaction.annotation.EnableTransactionManagement;
12
13 @EnableJpaAuditing
14 @EnableAsync
15 @SpringBootApplication
16 @EnableTransactionManagement
17 public class CronosGeneratorCodeApplication extends SpringBootServletInitializer {
18 @Override
19 protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
20 return builder.sources(CronosGeneratorCodeApplication.class);
21 }
22
23
24 public static void main(String[] args) {
25 SpringApplication.run(CronosGeneratorCodeApplication.class, args);
26 }
27
28 @Bean
29 public SpringContextHolder springContextHolder() {
30 return new SpringContextHolder();
31 }
32
33 }
1 #配置数据源
2 spring:
3 datasource:
4 # 测试/演示库
5 url: jdbc:log4jdbc:mysql://139.196.192.242:3306/cms_test?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false
6 username: root
7 password: Tjlh@2017
8 driverClassName: net.sf.log4jdbc.sql.jdbcapi.DriverSpy
9 #Druid
10 type: com.alibaba.druid.pool.DruidDataSource
11 druid:
12 # 初始化配置
13 initial-size: 3
14 # 最小连接数
15 min-idle: 3
16 # 最大连接数
17 max-active: 15
18 # 获取连接超时时间
19 max-wait: 5000
20 # 连接有效性检测时间
21 time-between-eviction-runs-millis: 90000
22 # 最大空闲时间
23 min-evictable-idle-time-millis: 1800000
24 test-while-idle: true
25 test-on-borrow: false
26 test-on-return: false
27
28 validation-query: select 1
29 # 配置监控统计拦截的filters
30 filters: stat
31 stat-view-servlet:
32 url-pattern: /druid/*
33 reset-enable: false
34
35 web-stat-filter:
36 url-pattern: /*
37 exclusions: "*.js,*.gif,*.jpg,*.bmp,*.png,*.css,*.ico,/druid/*"
38
39 #配置 Jpa
40 jpa:
41 hibernate:
42 # 生产环境设置成 none,避免程序运行时自动更新数据库结构
43 ddl-auto: none
44 servlet:
45 multipart:
46 file-size-threshold: 2KB
47 max-file-size: 100MB
48 max-request-size: 200MB
49 redis:
50 #数据库索引
51 database: 2
52 host: 10.100.6.140
53 port: 6379
54 password:
55 #连接超时时间
56 timeout: 5000
57 #jwt
58 jwt:
59 header: Authorization
60 secret: mySecret
61 # token 过期时间/毫秒,6小时 1小时 = 3600000 毫秒
62 expiration: 7200000
63 # 在线用户key
64 online: online-token
65 # 验证码
66 codeKey: code-key
67 # token 续期检查时间范围(60分钟,单位毫秒),在token即将过期的一段时间内用户操作了,则给用户的token续期
68 detect: 3600000
69 # 续期时间,2小时,单位毫秒
70 renew: 7200000
71
72 #是否允许生成代码,生产环境设置为false
73 generator:
74 enabled: true
75
76 #是否开启 swagger-ui
77 swagger:
78 enabled: true
79
80 # 文件存储路径(相对路径)
81 file:
82 path: system/file
83 avatar: system/avatar
84 upload: upload
85 # 文件大小 /M
86 maxSize: 100
87 avatarMaxSize: 5
1 server:
2 port: 8003
3
4 spring:
5 freemarker:
6 check-template-location: false
7 profiles:
8 active: dev
9 jackson:
10 time-zone: GMT+8
11 data:
12 redis:
13 repositories:
14 enabled: false
15
16 #配置 Jpa
17 jpa:
18 properties:
19 hibernate:
20 dialect: org.hibernate.dialect.MySQL5InnoDBDialect
21 open-in-view: true
22
23 task:
24 pool:
25 # 核心线程池大小
26 core-pool-size: 10
27 # 最大线程数
28 max-pool-size: 30
29 # 活跃时间
30 keep-alive-seconds: 60
31 # 队列容量
32 queue-capacity: 50
33
34 #登录图形验证码有效时间/分钟
35 loginCode:
36 expiration: 2
37
38 #默认上传图片类型
39 default-image-type: -1
1 #数据库类型转Java类型
2 tinyint=Integer
3 smallint=Integer
4 mediumint=Integer
5 int=Integer
6 integer=Integer
7
8 bigint=Long
9
10 float=Float
11
12 double=Double
13
14 decimal=BigDecimal
15
16 bit=Boolean
17
18 char=String
19 varchar=String
20 tinytext=String
21 text=String
22 mediumtext=String
23 longtext=String
24
25 date=Timestamp
26 datetime=Timestamp
27 timestamp=Timestamp
1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
2 <html xmlns="http://www.w3.org/1999/xhtml">
3 <head>
4 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
5 <style>
6 @page {
7 margin: 0;
8 }
9 </style>
10 </head>
11 <body style="margin: 0px;
12 padding: 0px;
13 font: 100% SimSun, Microsoft YaHei, Times New Roman, Verdana, Arial, Helvetica, sans-serif;
14 color: #000;">
15 <div style="height: auto;
16 width: 820px;
17 min-width: 820px;
18 margin: 0 auto;
19 margin-top: 20px;
20 border: 1px solid #eee;">
21 <div style="padding: 10px;padding-bottom: 0px;">
22 <p style="margin-bottom: 10px;padding-bottom: 0px;">尊敬的用户,您好:</p>
23 <p style="text-indent: 2em; margin-bottom: 10px;">您正在申请邮箱验证,您的验证码为:</p>
24 <p style="text-align: center;
25 font-family: Times New Roman;
26 font-size: 22px;
27 color: #C60024;
28 padding: 20px 0px;
29 margin-bottom: 10px;
30 font-weight: bold;
31 background: #ebebeb;">${code}</p>
32 <div style="list-style: none;
33 margin-top: 22px;
34 maigin-bottom: 10px;
35 font-size: 14px;
36 color: #555;">
37 <p style="line-height: 12px;">Github:<a hover="color: #DA251D;" style="color: #999;" href="https://github.com/elunez/eladmin" target="_blank">https://github.com/elunez/eladmin</a></p>
38 </div>
39 <div class="foot-hr hr" style="margin: 0 auto;
40 z-index: 111;
41 width: 800px;
42 margin-top: 30px;
43 border-top: 1px solid #DA251D;">
44 </div>
45 <div style="text-align: center;
46 font-size: 12px;
47 padding: 20px 0px;
48 font-family: Microsoft YaHei;">
49 Copyright &copy;${.now?string("yyyy")} EL-ADMIN 后台管理系统 All Rights Reserved.
50 </div>
51
52 </div>
53 </div>
54 </body>
55 </html>
1 package ${package}.rest;
2
3 import com.topdraw.aop.log.Log;
4 import ${package}.domain.${className};
5 import ${package}.service.${className}Service;
6 import ${package}.service.dto.${className}QueryCriteria;
7 import org.springframework.beans.factory.annotation.Autowired;
8 import org.springframework.data.domain.Pageable;
9 import org.springframework.http.HttpStatus;
10 import org.springframework.http.ResponseEntity;
11 import org.springframework.validation.annotation.Validated;
12 import org.springframework.web.bind.annotation.*;
13 import io.swagger.annotations.*;
14 import java.io.IOException;
15 import javax.servlet.http.HttpServletResponse;
16
17 /**
18 * @author ${author}
19 * @date ${date}
20 */
21 @Api(tags = "${className}管理")
22 @RestController
23 @RequestMapping("/api/${changeClassName}")
24 public class ${className}Controller {
25
26 @Autowired
27 private ${className}Service ${changeClassName}Service;
28
29 @GetMapping(value = "/download")
30 @Log("导出数据")
31 @ApiOperation("导出数据")
32 public void download(HttpServletResponse response, ${className}QueryCriteria criteria) throws IOException {
33 ${changeClassName}Service.download(${changeClassName}Service.queryAll(criteria), response);
34 }
35
36 @GetMapping
37 @Log("查询${className}")
38 @ApiOperation("查询${className}")
39 public ResponseEntity get${className}s(${className}QueryCriteria criteria, Pageable pageable) {
40 return new ResponseEntity<>(${changeClassName}Service.queryAll(criteria,pageable),HttpStatus.OK);
41 }
42
43 @GetMapping(value = "/all")
44 @Log("查询所有${className}")
45 @ApiOperation("查询所有${className}")
46 public ResponseEntity get${className}s(${className}QueryCriteria criteria) {
47 return new ResponseEntity<>(${changeClassName}Service.queryAll(criteria),HttpStatus.OK);
48 }
49
50 @PostMapping
51 @Log("新增${className}")
52 @ApiOperation("新增${className}")
53 public ResponseEntity create(@Validated @RequestBody ${className} resources) {
54 return new ResponseEntity<>(${changeClassName}Service.create(resources),HttpStatus.CREATED);
55 }
56
57 @PutMapping
58 @Log("修改${className}")
59 @ApiOperation("修改${className}")
60 public ResponseEntity update(@Validated @RequestBody ${className} resources) {
61 ${changeClassName}Service.update(resources);
62 return new ResponseEntity<>(HttpStatus.NO_CONTENT);
63 }
64
65 @DeleteMapping(value = "/{${pkChangeColName}}")
66 @Log("删除${className}")
67 @ApiOperation("删除${className}")
68 public ResponseEntity delete(@PathVariable ${pkColumnType} ${pkChangeColName}) {
69 ${changeClassName}Service.delete(${pkChangeColName});
70 return new ResponseEntity<>(HttpStatus.OK);
71 }
72
73 <#if columns??>
74 <#list columns as column>
75 <#if column.columnName == 'code'>
76 @GetMapping(value = "/getByCode/{code}")
77 @Log("根据标识查询")
78 @ApiOperation(value = "根据标识查询")
79 public ResponseEntity getByCode(@PathVariable String code) {
80 return new ResponseEntity(${changeClassName}Service.getByCode(code),HttpStatus.OK);
81 }
82 </#if>
83 </#list>
84 </#if>
85 }
1 package ${package}.service.dto;
2
3 import lombok.Data;
4 <#if hasTimestamp>
5 import java.sql.Timestamp;
6 </#if>
7 <#if hasBigDecimal>
8 import java.math.BigDecimal;
9 </#if>
10 import java.io.Serializable;
11 <#if !auto && pkColumnType = 'Long'>
12 import com.fasterxml.jackson.databind.annotation.JsonSerialize;
13 import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
14 </#if>
15
16
17 /**
18 * @author ${author}
19 * @date ${date}
20 */
21 @Data
22 public class ${className}DTO implements Serializable {
23 <#if columns??>
24 <#list columns as column>
25
26 <#if column.columnComment != ''>
27 // ${column.columnComment}
28 </#if>
29 <#if column.columnKey = 'PRI'>
30 <#if !auto && pkColumnType = 'Long'>
31 // 处理精度丢失问题
32 @JsonSerialize(using= ToStringSerializer.class)
33 </#if>
34 </#if>
35 private ${column.columnType} ${column.changeColumnName};
36 </#list>
37 </#if>
38 }
1 package ${package}.domain;
2
3 import lombok.Data;
4 import lombok.experimental.Accessors;
5 import cn.hutool.core.bean.BeanUtil;
6 import cn.hutool.core.bean.copier.CopyOptions;
7 import javax.persistence.*;
8 import org.springframework.data.annotation.CreatedDate;
9 import org.springframework.data.annotation.LastModifiedDate;
10 import org.springframework.data.jpa.domain.support.AuditingEntityListener;
11 <#if hasTimestamp>
12 import java.sql.Timestamp;
13 </#if>
14 <#if hasBigDecimal>
15 import java.math.BigDecimal;
16 </#if>
17 <#if hasCode>
18 import java.util.UUID;
19 </#if>
20
21 import java.io.Serializable;
22
23 /**
24 * @author ${author}
25 * @date ${date}
26 */
27 @Entity
28 @Data
29 @EntityListeners(AuditingEntityListener.class)
30 @Accessors(chain = true)
31 @Table(name="${tableName}")
32 public class ${className} implements Serializable {
33 <#if columns??>
34 <#list columns as column>
35
36 <#if column.columnComment != ''>
37 // ${column.columnComment}
38 </#if>
39 <#if column.columnKey = 'PRI'>
40 @Id
41 <#if auto>
42 @GeneratedValue(strategy = GenerationType.IDENTITY)
43 </#if>
44 </#if>
45 <#if column.columnName == 'create_time'>
46 @CreatedDate
47 </#if>
48 <#if column.columnName == 'update_time'>
49 @LastModifiedDate
50 </#if>
51 @Column(name = "${column.columnName}"<#if column.columnKey = 'UNI'>,unique = true</#if><#if column.isNullable = 'NO' && column.columnKey != 'PRI'>, nullable = false</#if>)
52 private ${column.columnType} ${column.changeColumnName};
53 </#list>
54 </#if>
55
56 public void copy(${className} source){
57 BeanUtil.copyProperties(source,this, CopyOptions.create().setIgnoreNullValue(true));
58 }
59 }
1 package ${package}.service.mapper;
2
3 import com.topdraw.base.BaseMapper;
4 import ${package}.domain.${className};
5 import ${package}.service.dto.${className}DTO;
6 import org.mapstruct.Mapper;
7 import org.mapstruct.ReportingPolicy;
8
9 /**
10 * @author ${author}
11 * @date ${date}
12 */
13 @Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.IGNORE)
14 public interface ${className}Mapper extends BaseMapper<${className}DTO, ${className}> {
15
16 }
1 package ${package}.service.dto;
2
3 import lombok.Data;
4 <#if queryHasTimestamp>
5 import java.sql.Timestamp;
6 </#if>
7 <#if queryHasBigDecimal>
8 import java.math.BigDecimal;
9 </#if>
10 <#if queryColumns??>
11 import com.topdraw.annotation.Query;
12 </#if>
13
14 /**
15 * @author ${author}
16 * @date ${date}
17 */
18 @Data
19 public class ${className}QueryCriteria{
20 <#if queryColumns??>
21 <#list queryColumns as column>
22
23 <#if column.columnQuery = '1'>
24 // 模糊
25 @Query(type = Query.Type.INNER_LIKE)
26 </#if>
27 <#if column.columnQuery = '2'>
28 // 精确
29 @Query
30 </#if>
31 private ${column.columnType} ${column.changeColumnName};
32 </#list>
33 </#if>
34 }
1 package ${package}.repository;
2
3 import ${package}.domain.${className};
4 import org.springframework.data.jpa.repository.JpaRepository;
5 import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
6
7 import java.util.Optional;
8
9 /**
10 * @author ${author}
11 * @date ${date}
12 */
13 public interface ${className}Repository extends JpaRepository<${className}, ${pkColumnType}>, JpaSpecificationExecutor<${className}> {
14 <#if columns??>
15 <#list columns as column>
16 <#if column.columnKey = 'UNI'>
17
18 ${className} findBy${column.capitalColumnName}(${column.columnType} ${column.columnName});
19 </#if>
20 </#list>
21 </#if>
22
23 <#if columns??>
24 <#list columns as column>
25 <#if column.columnName == 'code'>
26 Optional<${className}> findFirstByCode(String code);
27 </#if>
28 </#list>
29 </#if>
30 }
1 package ${package}.service;
2
3 import ${package}.domain.${className};
4 import ${package}.service.dto.${className}DTO;
5 import ${package}.service.dto.${className}QueryCriteria;
6 import org.springframework.data.domain.Pageable;
7 import java.util.Map;
8 import java.util.List;
9 import java.io.IOException;
10 import javax.servlet.http.HttpServletResponse;
11
12 /**
13 * @author ${author}
14 * @date ${date}
15 */
16 public interface ${className}Service {
17
18 /**
19 * 查询数据分页
20 * @param criteria 条件参数
21 * @param pageable 分页参数
22 * @return Map<String,Object>
23 */
24 Map<String,Object> queryAll(${className}QueryCriteria criteria, Pageable pageable);
25
26 /**
27 * 查询所有数据不分页
28 * @param criteria 条件参数
29 * @return List<${className}DTO>
30 */
31 List<${className}DTO> queryAll(${className}QueryCriteria criteria);
32
33 /**
34 * 根据ID查询
35 * @param ${pkChangeColName} ID
36 * @return ${className}DTO
37 */
38 ${className}DTO findById(${pkColumnType} ${pkChangeColName});
39
40 ${className}DTO create(${className} resources);
41
42 void update(${className} resources);
43
44 void delete(${pkColumnType} ${pkChangeColName});
45
46 void download(List<${className}DTO> all, HttpServletResponse response) throws IOException;
47
48 <#if columns??>
49 <#list columns as column>
50 <#if column.columnName == 'code'>
51 /**
52 * Code校验
53 * @param code
54 * @return ${className}DTO
55 */
56 ${className}DTO getByCode(String code);
57 </#if>
58 </#list>
59 </#if>
60 }
1 package ${package}.service.impl;
2
3 import ${package}.domain.${className};
4 <#if columns??>
5 <#list columns as column>
6 <#if column.columnKey = 'UNI'>
7 <#if column_index = 1>
8 import com.topdraw.exception.EntityExistException;
9 </#if>
10 </#if>
11 </#list>
12 </#if>
13 import com.topdraw.utils.ValidationUtil;
14 import com.topdraw.utils.FileUtil;
15 import ${package}.repository.${className}Repository;
16 import ${package}.service.${className}Service;
17 import ${package}.service.dto.${className}DTO;
18 import ${package}.service.dto.${className}QueryCriteria;
19 import ${package}.service.mapper.${className}Mapper;
20 import org.springframework.beans.factory.annotation.Autowired;
21 import org.springframework.stereotype.Service;
22 import org.springframework.transaction.annotation.Propagation;
23 import org.springframework.transaction.annotation.Transactional;
24 import org.springframework.dao.EmptyResultDataAccessException;
25 <#if !auto && pkColumnType = 'Long'>
26 import cn.hutool.core.lang.Snowflake;
27 import cn.hutool.core.util.IdUtil;
28 </#if>
29 <#if !auto && pkColumnType = 'String'>
30 import cn.hutool.core.util.IdUtil;
31 </#if>
32 import org.springframework.data.domain.Page;
33 import org.springframework.data.domain.Pageable;
34 import org.springframework.util.Assert;
35 import com.topdraw.utils.PageUtil;
36 import com.topdraw.utils.QueryHelp;
37 import com.topdraw.utils.StringUtils;
38
39 import java.util.List;
40 import java.util.Map;
41 import java.io.IOException;
42 import javax.servlet.http.HttpServletResponse;
43 import java.util.ArrayList;
44 import java.util.LinkedHashMap;
45
46 /**
47 * @author ${author}
48 * @date ${date}
49 */
50 @Service
51 @Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
52 public class ${className}ServiceImpl implements ${className}Service {
53
54 @Autowired
55 private ${className}Repository ${changeClassName}Repository;
56
57 @Autowired
58 private ${className}Mapper ${changeClassName}Mapper;
59
60 @Override
61 public Map<String, Object> queryAll(${className}QueryCriteria criteria, Pageable pageable) {
62 Page<${className}> page = ${changeClassName}Repository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder),pageable);
63 return PageUtil.toPage(page.map(${changeClassName}Mapper::toDto));
64 }
65
66 @Override
67 public List<${className}DTO> queryAll(${className}QueryCriteria criteria) {
68 return ${changeClassName}Mapper.toDto(${changeClassName}Repository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder)));
69 }
70
71 @Override
72 public ${className}DTO findById(${pkColumnType} ${pkChangeColName}) {
73 ${className} ${changeClassName} = ${changeClassName}Repository.findById(${pkChangeColName}).orElseGet(${className}::new);
74 ValidationUtil.isNull(${changeClassName}.get${pkCapitalColName}(),"${className}","${pkChangeColName}",${pkChangeColName});
75 return ${changeClassName}Mapper.toDto(${changeClassName});
76 }
77
78 @Override
79 @Transactional(rollbackFor = Exception.class)
80 public ${className}DTO create(${className} resources) {
81 <#if !auto && pkColumnType = 'Long'>
82 Snowflake snowflake = IdUtil.createSnowflake(1, 1);
83 resources.set${pkCapitalColName}(snowflake.nextId());
84 </#if>
85 <#if !auto && pkColumnType = 'String'>
86 resources.set${pkCapitalColName}(IdUtil.simpleUUID());
87 </#if>
88 <#if columns??>
89 <#list columns as column>
90 <#if column.columnKey = 'UNI'>
91 if(${changeClassName}Repository.findBy${column.capitalColumnName}(resources.get${column.capitalColumnName}()) != null) {
92 throw new EntityExistException(${className}.class,"${column.columnName}",resources.get${column.capitalColumnName}());
93 }
94 </#if>
95 </#list>
96 </#if>
97 return ${changeClassName}Mapper.toDto(${changeClassName}Repository.save(resources));
98 }
99
100 @Override
101 @Transactional(rollbackFor = Exception.class)
102 public void update(${className} resources) {
103 ${className} ${changeClassName} = ${changeClassName}Repository.findById(resources.get${pkCapitalColName}()).orElseGet(${className}::new);
104 ValidationUtil.isNull( ${changeClassName}.get${pkCapitalColName}(),"${className}","id",resources.get${pkCapitalColName}());
105 <#if columns??>
106 <#list columns as column>
107 <#if column.columnKey = 'UNI'>
108 <#if column_index = 1>
109 ${className} ${changeClassName}1 = null;
110 </#if>
111 ${changeClassName}1 = ${changeClassName}Repository.findBy${column.capitalColumnName}(resources.get${column.capitalColumnName}());
112 if(${changeClassName}1 != null && !${changeClassName}1.get${pkCapitalColName}().equals(${changeClassName}.get${pkCapitalColName}())){
113 throw new EntityExistException(${className}.class,"${column.columnName}",resources.get${column.capitalColumnName}());
114 }
115 </#if>
116 </#list>
117 </#if>
118 ${changeClassName}.copy(resources);
119 ${changeClassName}Repository.save(${changeClassName});
120 }
121
122 @Override
123 @Transactional(rollbackFor = Exception.class)
124 public void delete(${pkColumnType} ${pkChangeColName}) {
125 Assert.notNull(id, "The given id must not be null!");
126 ${className} ${changeClassName} = ${changeClassName}Repository.findById(id).orElseThrow(
127 () -> new EmptyResultDataAccessException(String.format("No %s entity " + "with id %s " + "exists!", ${className}.class, id), 1));
128 ${changeClassName}Repository.delete(${changeClassName});
129 }
130
131
132 @Override
133 public void download(List<${className}DTO> all, HttpServletResponse response) throws IOException {
134 List<Map<String, Object>> list = new ArrayList<>();
135 for (${className}DTO ${changeClassName} : all) {
136 Map<String, Object> map = new LinkedHashMap<>();
137 <#list columns as column>
138 <#if column.columnKey != 'PRI'>
139 <#if column.columnComment != ''>
140 map.put("${column.columnComment}", ${changeClassName}.get${column.capitalColumnName}());
141 <#else>
142 map.put("${column.changeColumnName}", ${changeClassName}.get${column.capitalColumnName}());
143 </#if>
144 </#if>
145 </#list>
146 list.add(map);
147 }
148 FileUtil.downloadExcel(list, response);
149 }
150
151
152 <#if columns??>
153 <#list columns as column>
154 <#if column.columnName == 'code'>
155 @Override
156 public ${className}DTO getByCode(String code) {
157 return StringUtils.isNotEmpty(code) ? ${changeClassName}Mapper.toDto(${changeClassName}Repository.findFirstByCode(code).orElseGet(${className}::new))
158 : new ${className}DTO();
159 }
160 </#if>
161 </#list>
162 </#if>
163 }
1 import request from '@/utils/request'
2
3 export function add(data) {
4 return request({
5 url: 'api/${changeClassName}',
6 method: 'post',
7 data
8 })
9 }
10
11 export function del(${pkChangeColName}) {
12 return request({
13 url: 'api/${changeClassName}/' + ${pkChangeColName},
14 method: 'delete'
15 })
16 }
17
18 export function edit(data) {
19 return request({
20 url: 'api/${changeClassName}',
21 method: 'put',
22 data
23 })
24 }
25
26 export function download${className}(params) {
27 return request({
28 url: 'api/${changeClassName}/download',
29 method: 'get',
30 params,
31 responseType: 'blob'
32 })
33 }
34
35 <#if columns??>
36 <#list columns as column>
37 <#if column.columnName == 'code'>
38 export function getByCode(code) {
39 return request({
40 url: 'api/${changeClassName}/getByCode/' + code,
41 method: 'get'
42 })
43 }
44 </#if>
45 </#list>
46 </#if>
1 <template>
2 <el-dialog :append-to-body="true" :close-on-click-modal="false" :visible.sync="dialog" :title="isAdd ? '新增' : '编辑'" width="960px" @closed="doClose">
3 <el-form ref="form" :model="form" :rules="rules" size="small" label-width="80px" style="padding: 30px;margin: -20px 0">
4 <el-row>
5 <#if columns??>
6 <#list columns as column>
7 <#if column.changeColumnName != '${pkChangeColName}'>
8 <#if column.columnName != 'images' && column.columnName != 'create_time' && column.columnName != 'update_time'>
9 <el-col :span="12">
10 <el-form-item label="<#if column.columnComment != ''>${column.columnComment}<#else>${column.changeColumnName}</#if>" <#if column.isNullable =
11 'NO'>prop="${column.changeColumnName}"</#if>>
12 <#if column.columnName = 'code'>
13 <el-input v-model="form.${column.changeColumnName}" prop="code"/>
14 <#elseif column.columnType = 'Timestamp'>
15 <el-date-picker v-model="form.${column.changeColumnName}" type="datetime"/>
16 <#elseif column.columnName = 'image'>
17 <images-upload ref="upload" :limit="5" :image.sync="form.image" :images.sync="form.images" upload-entity="${changeClassName}" />
18 <#else>
19 <el-input v-model="form.${column.changeColumnName}"/>
20 </#if>
21 </el-form-item>
22 </el-col>
23 </#if>
24 </#if>
25 </#list>
26 </#if>
27 </el-row>
28 </el-form>
29 <div slot="footer" class="dialog-footer">
30 <el-button type="text" @click="cancel">取消</el-button>
31 <el-button :loading="loading" type="primary" @click="doSubmit">确认</el-button>
32 </div>
33 </el-dialog>
34 </template>
35
36 <script>
37 import { add, edit } from '@/api/${changeClassName}'
38 <#if columns??>
39 <#list columns as column>
40 <#if column.columnName == 'code'>
41 import { getByCode } from '@/api/${changeClassName}'
42 </#if>
43 </#list>
44 </#if>
45 import ImagesUpload from '@/components/ImagesUpload/index'
46 export default {
47 components: { ImagesUpload },
48 props: {
49 isAdd: {
50 type: Boolean,
51 required: true
52 },
53 dictMap: {
54 type: Object,
55 required: true
56 }
57 },
58 data() {
59 return {
60 loading: false, dialog: false,
61 form: {
62 <#if columns??>
63 <#list columns as column>
64 ${column.changeColumnName}: ''<#if column_has_next>,</#if>
65 </#list>
66 </#if>
67 },
68 rules: {
69 <#if columns??>
70 <#list columns as column>
71 <#if column.columnName == 'code'>
72 code: [
73 { required: true, message: '请输入标识', trigger: 'blur' }, { validator: this.validateCode, trigger: 'blur' }
74 ],
75 </#if>
76 </#list>
77 </#if>
78 <#function filter columns>
79 <#local result = []>
80 <#list columns as column>
81 <#if column.columnKey != 'PRI' && column.isNullable = 'NO'>
82 <#local result = result + [column]>
83 </#if>
84 </#list>
85 <#return result>
86 </#function>
87 <#assign filteredData = filter(columns)>
88 <#list filteredData as column>
89 ${column.changeColumnName}: [
90 { required: true, message: '${column.columnComment}不能为空', trigger: 'blur' }
91 ]<#sep>,</#sep>
92 </#list>
93 }
94 }
95 },
96 methods: {
97 <#if columns??>
98 <#list columns as column>
99 <#if column.columnName == 'code'>
100 validateCode(rule, value, callback) {
101 // 当为编辑状态且code未改变时不进行校验
102 if (!this.isAdd && this.form.originalCode === value) {
103 callback()
104 } else {
105 getByCode(value)
106 .then(res => {
107 typeof (res) === 'undefined' || res.id === null || this.form.id === res.id
108 ? callback()
109 : callback(new Error('该code已存在!'))
110 })
111 .catch((err) => {
112 console.log(err)
113 callback()
114 })
115 }
116 },
117 </#if>
118 </#list>
119 </#if>
120 cancel() {
121 this.dialog = false
122 },
123 doSubmit() {
124 if (this.isAdd) {
125 this.doAdd()
126 } else this.doEdit()
127 },
128 doAdd() {
129 this.$refs['form'].validate((valid) => {
130 if (valid) {
131 this.loading = true
132 add(this.form).then(() => {
133 this.$notify({
134 title: '添加成功',
135 type: 'success',
136 duration: 2500
137 })
138 this.dialog = false
139 this.loading = false
140 this.$parent.init()
141 }).catch(err => {
142 this.loading = false
143 console.log(err)
144 })
145 } else {
146 this.$notify({
147 title: '警告',
148 message: '信息不合法',
149 type: 'warning',
150 duration: 2000
151 })
152 }
153 })
154 },
155 doEdit() {
156 this.$refs['form'].validate((valid) => {
157 if (valid) {
158 this.loading = true
159 edit(this.form).then(() => {
160 this.$notify({
161 title: '修改成功',
162 type: 'success',
163 duration: 2500
164 })
165 this.loading = false
166 this.dialog = false
167 this.$parent.init()
168 }).catch(err => {
169 console.log(err)
170 this.loading = false
171 })
172 } else {
173 this.$notify({
174 title: '警告',
175 message: '信息不合法',
176 type: 'warning',
177 duration: 2000
178 })
179 }
180 })
181 },
182 doClose() {
183 this.resetForm()
184 },
185 resetForm() {
186 this.$refs['form'].resetFields()
187 this.form = {
188 <#if columns??>
189 <#list columns as column>
190 <#if column.columnName == 'code'>
191 originalCode: '',
192 </#if>
193 ${column.changeColumnName}: ''<#if column_has_next>,</#if>
194 </#list>
195 </#if>
196 }
197 }
198 }
199 }
200 </script>
201
202 <style scoped>
203
204 </style>
1 <#--noinspection ALL-->
2 <template>
3 <div class="app-container">
4 <!--工具栏-->
5 <div class="head-container">
6 <#if hasQuery>
7 <!-- 搜索 -->
8 <el-select v-model="query.type" clearable placeholder="聚合筛选条件" class="filter-item" style="width: 130px">
9 <el-option v-for="item in queryTypeOptions" :key="item.key" :label="item.display_name" :value="item.key"/>
10 </el-select>
11 <el-input v-model="query.value" clearable placeholder="输入搜索内容" style="width: 200px;" class="filter-item" @keyup.enter.native="toQuery"/>
12 <el-button class="filter-item" size="mini" type="success" icon="el-icon-search" @click="toQuery">搜索</el-button>
13 </#if>
14 <!-- 新增 -->
15 <div style="display: inline-block;margin: 0 2px;">
16 <el-button
17 v-permission="['admin','${changeClassName}:add']"
18 class="filter-item"
19 size="mini"
20 type="primary"
21 icon="el-icon-plus"
22 @click="add">新增</el-button>
23 </div>
24 </div>
25 <!--表单组件-->
26 <eForm ref="form" :is-add="isAdd" :dict-map="dictMap"/>
27 <!--表格渲染-->
28 <el-table v-loading="loading" :data="data" size="small" style="width: 100%;" @row-dblclick="edit">
29 <#if columns??>
30 <#list columns as column>
31 <#if column.columnShow = 'true'>
32 <#if column.columnType != 'Timestamp'>
33 <el-table-column prop="${column.changeColumnName}" label="<#if column.columnComment != ''>${column.columnComment}<#else>${column.changeColumnName}</#if>" <#if column.columnName = 'id' || column.columnName = 'name' || column.columnName = 'code'>sortable </#if>/>
34 <#else>
35 <el-table-column prop="${column.changeColumnName}" label="<#if column.columnComment != ''>${column.columnComment}<#else>${column.changeColumnName}</#if>">
36 <template slot-scope="scope">
37 <span>{{ parseTime(scope.row.${column.changeColumnName}) }}</span>
38 </template>
39 </el-table-column>
40 </#if>
41 </#if>
42 </#list>
43 </#if>
44 <el-table-column label="操作" width="120px" fixed="right" align="center">
45 <template slot-scope="scope">
46 <el-button v-permission="['admin','${changeClassName}:edit']" size="mini" type="primary" icon="el-icon-edit" @click="edit(scope.row)"/>
47 <el-popover
48 v-permission="['admin','${changeClassName}:del']"
49 :ref="scope.row.${pkChangeColName}"
50 placement="top"
51 width="180">
52 <p>确定删除本条数据吗?</p>
53 <div style="text-align: right; margin: 0">
54 <el-button size="mini" type="text" @click="$refs[scope.row.${pkChangeColName}].doClose()">取消</el-button>
55 <el-button :loading="delLoading" type="primary" size="mini" @click="subDelete(scope.row.${pkChangeColName})">确定</el-button>
56 </div>
57 <el-button slot="reference" type="danger" icon="el-icon-delete" size="mini"/>
58 </el-popover>
59 </template>
60 </el-table-column>
61 </el-table>
62 <!--分页组件-->
63 <el-pagination
64 :total="total"
65 :current-page="page + 1"
66 style="margin-top: 8px;"
67 layout="total, prev, pager, next, sizes"
68 @size-change="sizeChange"
69 @current-change="pageChange"/>
70 </div>
71 </template>
72
73 <script>
74 import initData from '@/mixins/initData'
75 import initDict from '@/mixins/initDict'
76 import { getAttrByValueFromDict } from '@/utils/common-util'
77 import { del, download${className} } from '@/api/${changeClassName}'
78 <#if hasTimestamp>
79 import { parseTime, downloadFile } from '@/utils/index'
80 </#if>
81 import eForm from './form'
82 export default {
83 components: { eForm },
84 mixins: [initData, initDict],
85 data() {
86 return {
87 delLoading: false<#if hasQuery>,</#if>
88 <#if hasQuery>
89 queryTypeOptions: [
90 <#if queryColumns??>
91 <#list queryColumns as column>
92 { key: '${column.changeColumnName}', display_name: '<#if column.columnComment != ''>${column.columnComment}<#else>${column.changeColumnName}</#if>' }<#if column_has_next>,</#if>
93 </#list>
94 </#if>
95 ]
96 </#if>
97 }
98 },
99 created() {
100 this.$nextTick(() => {
101 this.init()
102 this.getDictMap('')
103 })
104 },
105 methods: {
106 <#if hasTimestamp>
107 parseTime,
108 </#if>
109 getAttrByValueFromDict,
110 beforeInit() {
111 this.url = 'api/${changeClassName}'
112 const sort = '${pkChangeColName},desc'
113 this.params = { page: this.page, size: this.size, sort: sort }
114 <#if hasQuery>
115 const query = this.query
116 const type = query.type
117 const value = query.value
118 if (type && value) { this.params[type] = value }
119 </#if>
120 return true
121 },
122 subDelete(${pkChangeColName}) {
123 this.delLoading = true
124 del(${pkChangeColName}).then(res => {
125 this.delLoading = false
126 this.$refs[${pkChangeColName}].doClose()
127 this.dleChangePage()
128 this.init()
129 this.$notify({
130 title: '删除成功',
131 type: 'success',
132 duration: 2500
133 })
134 }).catch(err => {
135 this.delLoading = false
136 this.$refs[${pkChangeColName}].doClose()
137 console.log(err.response.data.message)
138 })
139 },
140 add() {
141 this.isAdd = true
142 this.$refs.form.dialog = true
143 },
144 edit(data) {
145 this.isAdd = false
146 const _this = this.$refs.form
147 _this.form = {
148 <#if columns??>
149 <#list columns as column>
150 <#if column.columnName == 'code'>
151 originalCode: data.code,
152 </#if>
153 ${column.changeColumnName}: data.${column.changeColumnName}<#if column_has_next>,</#if>
154 </#list>
155 </#if>
156 }
157 _this.dialog = true
158 },
159 // 导出
160 download() {
161 this.beforeInit()
162 this.downloadLoading = true
163 download${className}(this.params).then(result => {
164 downloadFile(result, '${className}列表', 'xlsx')
165 this.downloadLoading = false
166 }).catch(() => {
167 this.downloadLoading = false
168 })
169 }
170 }
171 }
172 </script>
173
174 <style scoped>
175
176 </style>
1 package com.topdraw.modules;
2
3 import org.junit.jupiter.api.Test;
4 import org.springframework.boot.test.context.SpringBootTest;
5
6 @SpringBootTest
7 class CronosGeneratorCodeApplicationTests {
8
9 @Test
10 void contextLoads() {
11 }
12
13 }
1 package com.topdraw.modules;
2
3 import com.topdraw.CronosGeneratorCodeApplication;
4 import com.topdraw.domain.GenConfig;
5 import com.topdraw.domain.vo.ColumnInfo;
6 import com.topdraw.service.GeneratorService;
7 import lombok.var;
8 import org.junit.Test;
9 import org.junit.runner.RunWith;
10 import org.springframework.beans.factory.annotation.Autowired;
11 import org.springframework.boot.test.context.SpringBootTest;
12 import org.springframework.test.annotation.Rollback;
13 import org.springframework.test.context.junit4.SpringRunner;
14 import org.springframework.transaction.annotation.Transactional;
15
16 import java.util.List;
17 import java.util.Map;
18
19 /**
20 * @author Hongyan Wang
21 * @packageName PACKAGE_NAME
22 * @className TestGenerator
23 * @description
24 * @date 2020/12/30 0:11
25 */
26 @RunWith(SpringRunner.class)
27 @SpringBootTest(classes = CronosGeneratorCodeApplication.class)
28 public class TestGenerator {
29 @Autowired
30 private GeneratorService generatorService;
31
32 @Test
33 @Rollback(value = false)
34 @Transactional(rollbackFor = Exception.class)
35 public void generator() {
36 String tableName = "x_media";
37 // 拿参数
38 var columnsMap = (Map<String, Object>) generatorService.getColumns(tableName);
39 var columnInfos = (List<ColumnInfo>) columnsMap.get("content");
40 // 只生成后端的话,只需要配置下包名和是否覆盖,
41 var genConfig = new GenConfig()
42 // 未设置id无法生成
43 .setId(1L)
44 // 根据需求更改包路径
45 .setPack("com.topdraw.modules.xxx")
46 // 前端路径。
47 .setPath("")
48 // 作者
49 .setAuthor("why")
50 // 表前缀。生成实体时,会移除该前缀
51 .setPrefix("x_")
52 .setCover(true);
53
54 // 生成代码
55 generatorService.generator(columnInfos, genConfig, tableName);
56 }
57 }