From 9b4ceb2f7896bb8fc4f61e9065b9d81d0a0ceac3 Mon Sep 17 00:00:00 2001 From: yanghuanglin Date: Mon, 8 Jan 2024 11:55:41 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E8=B0=83=E6=95=B4=EF=BC=8C?= =?UTF-8?q?=E7=94=9F=E6=88=90=E4=BB=A3=E7=A0=81=E7=AC=A6=E5=90=88cemis?= =?UTF-8?q?=E8=A7=84=E8=8C=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 93 +++-- .../optima/cemis/base/bean/CommonResult.java | 351 ++++++++++++++++++ .../java/com/optima/cemis/base/bean/Page.java | 120 ++++++ src/test/java/GeberatorUIServer.java | 6 +- .../resources/codetpls/controller.java.btl | 32 +- 5 files changed, 552 insertions(+), 50 deletions(-) create mode 100644 src/main/java/com/optima/cemis/base/bean/CommonResult.java create mode 100644 src/main/java/com/optima/cemis/base/bean/Page.java diff --git a/pom.xml b/pom.xml index ebebe72..72d3d96 100644 --- a/pom.xml +++ b/pom.xml @@ -3,68 +3,93 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 com.optima.cemis - code-generator + cemis-code-generator 0.0.1-SNAPSHOT - code-generator - code-generator + cemis-code-generator + cemis-code-generator 1.8 2.7.18 2.0.5 - 8.0.33 - 1.18.30 3.5.5 - 2.16.1 2.10.5 + 1.4.7.2 + 1.5.14 - com.github.davidfantasy - mybatis-plus-generator-ui - ${mybatis-plus-generator-ui.version} - test - - - mysql - mysql-connector-java - ${mysql-connector-java.version} + com.mysql + mysql-connector-j provided org.projectlombok lombok - ${lombok.version} provided + + com.fasterxml.jackson.core + jackson-core + provided + + + com.fasterxml.jackson.core + jackson-annotations + provided + + + com.fasterxml.jackson.core + jackson-databind + provided + + + org.springframework + spring-webmvc + provided + + + + com.github.davidfantasy + mybatis-plus-generator-ui + ${mybatis-plus-generator-ui.version} + test + com.baomidou mybatis-plus ${mybatis-plus.version} provided - - com.fasterxml.jackson.core - jackson-core - ${jackson.version} - provided - - - com.fasterxml.jackson.core - jackson-annotations - ${jackson.version} - provided - - - com.fasterxml.jackson.core - jackson-databind - ${jackson.version} - provided - io.springfox springfox-swagger-ui ${springfox-swagger-ui.version} provided + + com.github.yulichang + mybatis-plus-join-boot-starter + ${mybatis-plus-join.version} + provided + + + io.swagger + swagger-annotations + ${swagger-annotations.version} + provided + + + + + + + org.springframework.boot + spring-boot-dependencies + ${spring-boot.version} + pom + import + + + diff --git a/src/main/java/com/optima/cemis/base/bean/CommonResult.java b/src/main/java/com/optima/cemis/base/bean/CommonResult.java new file mode 100644 index 0000000..4e8337a --- /dev/null +++ b/src/main/java/com/optima/cemis/base/bean/CommonResult.java @@ -0,0 +1,351 @@ +package com.optima.cemis.base.bean; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonValue; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.ToString; + +import java.io.Serializable; +import java.util.Collection; + +/** + * 全局通用返回数据结构,支持链式写法 + * + *
+ *     不带数据的返回:
+ *     
+ *          CommonResult.None none =  CommonResult.None.init().success();
+ *     
+ *     带单个数据对象的返回(带泛型初始化方式一):
+ *     
+ *         CommonResult.Single<String> single = CommonResult.Single.init(String.class).data("我是一个字符串");
+ *     
+ *      带列表数据对象的返回(带泛型初始化方法二):
+ *      
+ *          List<String> data = new ArrayList<>();
+ *          data.add("你");
+ *          data.add("我");
+ *          data.add("他");
+ *          CommonResult.Multiple<String> multiple = new CommonResult.Multiple<>()
+ *          multiple.data(data);
+ *      
+ * 
+ */ +public class CommonResult { + /** + * 状态枚举 + */ + public enum Status { + SUCCESS("success", 200), + ERROR("error", 500); + + @JsonValue + private final String name; + private final Integer code; + + Status(String name, Integer code) { + this.name = name; + this.code = code; + } + + public Integer code() { + return this.code; + } + + @Override + public String toString() { + return this.name; + } + } + + /** + * 数据结构基类 + * + * @param 数据类型 + * @param 继承此基类的类 + */ + @SuppressWarnings("unchecked") + @Getter() + @ToString + private static abstract class Base> { + /** + * 接口调用结果,默认为success + */ + @ApiModelProperty(value = "接口调用结果,默认成功为success,失败为error", required = true, example = "error") + protected Status status = Status.SUCCESS; + + /** + * 接口返回状态码,默认status为success时为200,status为error时为500 + */ + @ApiModelProperty(value = "接口返回状态码,默认成功为200,失败为500", required = true, example = "200") + protected Integer code = Status.SUCCESS.code(); + + /** + * 接口返回简略信息,默认为空字符串 + */ + @ApiModelProperty(value = "接口返回简略信息,默认为空字符串", example = "登录失败") + protected String message = ""; + + /** + * 接口返回详细信息,默认为空字符串 + */ + @ApiModelProperty(value = "接口返回详细信息,默认为空字符串", example = "用户名不能为空") + protected String detail = ""; + + public Status status() { + return this.status; + } + + public T status(Status status) { + this.status = status; + this.code = status.code; + return (T) this; + } + + public Integer code() { + return this.code; + } + + public T code(Integer code) { + this.code = code; + return (T) this; + } + + public String message() { + return this.message; + } + + public T message(String message) { + this.message = message; + return (T) this; + } + + public String detail() { + return this.detail; + } + + public T detail(String detail) { + this.detail = detail; + return (T) this; + } + + public T success() { + this.status = Status.SUCCESS; + this.code = this.status.code(); + return (T) this; + } + + public T success(String message) { + return this.success().message(message); + } + + public T success(Integer code, String message) { + return (T) this.success(message).code(code); + } + + public T success(String message, String detail) { + return this.success(message).detail(detail); + } + + public T success(Integer code, String message, String detail) { + return this.success(message, detail).code(code); + } + + public T error() { + this.status = Status.ERROR; + this.code = this.status.code(); + return (T) this; + } + + public T error(String message) { + return this.error().message(message); + } + + public T error(Integer code, String message) { + return this.error(message).code(code); + } + + public T error(String message, String detail) { + return this.error(message).detail(detail); + } + + public T error(Integer code, String message, String detail) { + return this.error(message, detail).code(code); + } + + @ApiModelProperty(hidden = true) + @JsonIgnore + public Boolean isSuccess() { + return this.status == Status.SUCCESS; + } + } + + /** + * 无返回数据时的返回结构 + */ + @Getter + @ToString(callSuper = true) + @EqualsAndHashCode(callSuper = true) + @ApiModel(value = "返回结果") + public static class None extends Base { + public static None init() { + return new None(); + } + } + + /** + * 有单个类型返回数据时的返回结构,基于无返回数据时的结构,多一个data字段 + */ + @Getter + @ToString(callSuper = true) + @EqualsAndHashCode(callSuper = true) + @ApiModel(value = "返回结果", description = "接口单个数据") + public static class Single extends Base> { + /** + * 接口返回数据,默认为空对象 + */ + @ApiModelProperty(value = "接口返回数据,没有数据则为空对象", allowEmptyValue = true) + private D data; + + public D data() { + return this.data; + } + + public Single data(D data) { + this.data = data; + return this; + } + + public static Single init() { + return new Single<>(); + } + } + + /** + * 有多个同类型返回数据时的返回结构基类 + * + * @param + * @param + */ + @SuppressWarnings("unchecked") + @Getter + @ToString(callSuper = true) + @EqualsAndHashCode(callSuper = true) + private static class MultipleBase> extends Base { + /** + * 接口返回数据,默认为空列表 + */ + @ApiModelProperty(value = "接口返回数据列表,没有数据则为空列表", allowEmptyValue = true) + protected Collection data; + + public Collection data() { + return this.data; + } + + public T data(Collection data) { + this.data = data; + return (T) this; + } + } + + /** + * 有多个同类型返回数据时的返回结构,基于无返回数据时的结构,多一个data字段 + */ + @Getter + @ToString(callSuper = true) + @EqualsAndHashCode(callSuper = true) + @ApiModel(value = "返回结果", description = "接口返回列表数据") + public static class Multiple extends MultipleBase> { + public static Multiple init() { + return new Multiple<>(); + } + } + + /** + * 自定义分页对象,继承于Multiple对象 + */ + @Getter + @ToString(callSuper = true) + @EqualsAndHashCode(callSuper = true) + @ApiModel(value = "返回结果", description = "接口返回分页列表数据") + public static class Pagination extends MultipleBase> { + /** + * 当前页数,仅用于分页 + */ + @ApiModelProperty(value = "当前页数") + private Long current = 1L; + + /** + * 每页记录数,仅用于分页 + */ + @ApiModelProperty(value = "每页记录数") + private Long size = 10L; + + /** + * 总记录数,仅用于分页 + */ + @ApiModelProperty(value = "总记录数") + private Long count = 0L; + + public Long current() { + return this.current; + } + + public Pagination current(Long current) { + this.current = current; + return this; + } + + public Pagination current(Integer current) { + this.current = current.longValue(); + return this; + } + + public Long size() { + return this.size; + } + + public Pagination size(Long size) { + this.size = size; + return this; + } + + public Pagination size(Integer size) { + this.size = size.longValue(); + return this; + } + + public Long count() { + return this.count; + } + + public Pagination count(Long count) { + this.count = count; + return this; + } + + public Pagination count(Integer count) { + this.count = count.longValue(); + return this; + } + + public static Pagination init() { + return new Pagination<>(); + } + + /** + * 根据分页数据转换 + * @param page + * @return + */ + public Pagination ofPage(Page page) { + return this.data(page.getRecords()) + .count(page.getCount()) + .size(page.getSize()) + .current(page.getCurrent()); + } + } +} diff --git a/src/main/java/com/optima/cemis/base/bean/Page.java b/src/main/java/com/optima/cemis/base/bean/Page.java new file mode 100644 index 0000000..f5a4c22 --- /dev/null +++ b/src/main/java/com/optima/cemis/base/bean/Page.java @@ -0,0 +1,120 @@ +package com.optima.cemis.base.bean; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.core.metadata.OrderItem; +import com.baomidou.mybatisplus.core.toolkit.StringUtils; +import com.optima.cemis.base.entity.BaseEntity; + +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.List; + +/** + * 自定义的基于MybatisPlus的分页组件的类,用于增加一些字段 + * Created by IntelliJ IDEA. + * User: yanghuanglin + * Date: 2021/4/30 + */ +public class Page extends com.baomidou.mybatisplus.extension.plugins.pagination.Page { + private static final long serialVersionUID = 526167319704940805L; + + /** + * 是否自动拼接分页参数、排序参数 + */ + private boolean autoConcat = true; + + public Page() { + super(); + } + + public Page(long current, long size) { + super(current, size); + } + + public Page(long current, long size, long total) { + super(current, size, total); + } + + public Page(long current, long size, boolean isSearchCount) { + super(current, size, isSearchCount); + } + + public Page(long current, long size, long total, boolean isSearchCount) { + super(current, size, total, isSearchCount); + } + + public boolean getAutoConcat() { + return autoConcat; + } + + public void setAutoConcat(boolean autoConcat) { + this.autoConcat = autoConcat; + } + + public long getCount() { + return this.total; + } + + public Page setCount(long count) { + this.total = count; + return this; + } + + /** + * 获取到BaseEntity为止的所有基类列表 + * + * @param clazz 需要获取基类列表的类 + * @param list 基类列表 + */ + private static List> getSupers(Class clazz, List> list) { + Class superClass = clazz.getSuperclass(); + if (superClass.isAssignableFrom(BaseEntity.class)) + list.add(superClass); + if (superClass.equals(BaseEntity.class)) { + return list; + } + return getSupers(superClass, list); + } + + /** + * 从所有基类列表中查找某个名称的字段 + * + * @param list 基类列表 + * @param name 需要查找的字段名 + * @return 查找到的字段,未找到则为null + */ + private static Field getField(List> list, String name) { + Field field = null; + for (Class supperClass : list) { + try { + field = supperClass.getDeclaredField(name); + break; + } catch (NoSuchFieldException ignored) { + } + } + return field; + } + + /** + * 排序字段名称转换,将驼峰命名转为下划线形式:如果实体中字段没有@TableField注解,则userId转为user_id,否则转为该注解中的数据库字段名。主要用于搜索时转换参数名 + * + * @param entityClass 字段所在实体的类 + */ + public void transferOrderField(Class entityClass) { + List> classList = getSupers(entityClass, new ArrayList<>()); + //将本身放入 + classList.add(entityClass); + List orderItems = orders(); + for (OrderItem orderItem : orderItems) { + String fieldName = orderItem.getColumn(); + Field declaredField = getField(classList, fieldName); + if (declaredField != null) { + TableField annotation = declaredField.getAnnotation(TableField.class); + if (annotation != null) + orderItem.setColumn(annotation.value()); + else + orderItem.setColumn(StringUtils.camelToUnderline(fieldName)); + } + } + } +} diff --git a/src/test/java/GeberatorUIServer.java b/src/test/java/GeberatorUIServer.java index a09b204..1408d20 100644 --- a/src/test/java/GeberatorUIServer.java +++ b/src/test/java/GeberatorUIServer.java @@ -10,16 +10,16 @@ public class GeberatorUIServer { /** * 数据库相关配置 */ - private static final String dbName = "cemis-examine"; + private static final String dbName = "cemis-qujing"; private static final String url = "jdbc:mysql://localhost:3306/" + dbName + "?useUnicode=true&useSSL=false&characterEncoding=utf8"; private static final String username = "root"; private static final String password = "root"; private static final String driverClassName = "com.mysql.cj.jdbc.Driver"; //项目父包名,service、controller等包会建在这个包下 - private static final String parent = "com.optima.cemis"; + private static final String parent = "com.optima.cemis.free"; //表名前缀,生成表时会删除 - private static final String tablePrefix = "exam_"; + private static final String tablePrefix = "sys_"; public static void main(String[] args) { GeneratorConfig config = GeneratorConfig.builder() diff --git a/src/test/resources/codetpls/controller.java.btl b/src/test/resources/codetpls/controller.java.btl index 750113f..623a336 100644 --- a/src/test/resources/codetpls/controller.java.btl +++ b/src/test/resources/codetpls/controller.java.btl @@ -2,7 +2,7 @@ <% var serviceInstanceName = @cn.hutool.core.util.StrUtil.lowerFirst(table.serviceName); %> package ${package.Controller}; -import cn.cdhncy.cemis.common.core.util.R; +import com.optima.cemis.base.bean.CommonResult; import org.springframework.web.bind.annotation.*; <% if(!restControllerStyle){ %> import org.springframework.stereotype.Controller; @@ -11,7 +11,7 @@ import org.springframework.stereotype.Controller; import ${superControllerClassPackage}; <% } %> <% if(isNotEmpty(controllerMethods.list)){ %> -import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.optima.cemis.base.bean.Page; <% } %> <% if(isNotEmpty(controllerMethods.hasMethod)){ %> import ${package.Service}.${table.serviceName}; @@ -51,39 +51,45 @@ public class ${table.controllerName} { <% if(isNotEmpty(controllerMethods.list)){ %> @GetMapping(value = "/list") - public R> list(Page<${table.entityName}> page) { - return R.ok(${serviceInstanceName}.page(page), "查询成功"); + public CommonResult.Pagination<${table.entityName}> list(Page<${table.entityName}> page) { + CommonResult.Pagination<${table.entityName}> pagination = CommonResult.Pagination.init(); + ${serviceInstanceName}.page(page); + return pagination.ofPage(page).message("查询成功"); } <% } %> <% if(isNotEmpty(controllerMethods.getById)){ %> @GetMapping(value = "/{id}") - public R<${table.entityName}> getById(@PathVariable("id") Serializable id) { - return R.ok(${serviceInstanceName}.getById(id), "查询成功"); + public CommonResult.Single<${table.entityName}> getById(@PathVariable("id") Serializable id) { + CommonResult.Single<${table.entityName}> single = CommonResult.Single.init(); + return single.data(${serviceInstanceName}.getById(id)).message("查询成功"); } <% } %> <% if(isNotEmpty(controllerMethods.create)){ %> - @PostMapping(value = "/create") - public R<${table.entityName}> create(${table.entityName} ${entityInstanceName}) { + @PostMapping(value = "/insert") + public CommonResult.Single<${table.entityName}> insert(${table.entityName} ${entityInstanceName}) { + CommonResult.Single<${table.entityName}> single = CommonResult.Single.init(); ${serviceInstanceName}.save(${entityInstanceName}); - return R.ok(${entityInstanceName}, "保存成功"); + return single.data(${entityInstanceName}).message("保存成功"); } <% } %> <% if(isNotEmpty(controllerMethods.delete)){ %> @GetMapping(value = "/delete/{id}") - public R delete(@PathVariable("id") Serializable id) { + public CommonResult.Single delete(@PathVariable("id") Serializable id) { + CommonResult.Single single = CommonResult.Single.init(); ${serviceInstanceName}.removeById(id); - return R.ok(id, "删除成功"); + return single.data(id).message("删除成功"); } <% } %> <% if(isNotEmpty(controllerMethods.update)){ %> @PostMapping(value = "/update") - public R<${table.entityName}> update(${table.entityName} ${entityInstanceName}) { + public CommonResult.Single<${table.entityName}> update(${table.entityName} ${entityInstanceName}) { + CommonResult.Single<${table.entityName}> single = CommonResult.Single.init(); ${serviceInstanceName}.updateById(${entityInstanceName}); - return R.ok(${serviceInstanceName}.getById(${entityInstanceName}.getId()), "更新成功"); + return single.data(${serviceInstanceName}.getById(${entityInstanceName}.getId())).message("更新成功"); } <% } %> }