一、PageDTO<T>
import com. baomidou. mybatisplus. extension. plugins. pagination. Page ;
import com. fasterxml. jackson. annotation. JsonIgnore ;
import com. tianji. common. utils. BeanUtils ;
import com. tianji. common. utils. CollUtils ;
import com. tianji. common. utils. Convert ;
import io. swagger. annotations. ApiModel ;
import io. swagger. annotations. ApiModelProperty ;
import lombok. AllArgsConstructor ;
import lombok. Data ;
import lombok. NoArgsConstructor ; import java. util. List ;
import java. util. function. Function ;
import java. util. stream. Collectors ; @Data
@NoArgsConstructor
@AllArgsConstructor
@ApiModel ( description = "分页结果" )
public class PageDTO < T > { @ApiModelProperty ( "总条数" ) protected Long total; @ApiModelProperty ( "总页码数" ) protected Long pages; @ApiModelProperty ( "当前页数据" ) protected List < T > list; public static < T > PageDTO < T > empty ( Long total, Long pages) { return new PageDTO < > ( total, pages, CollUtils . emptyList ( ) ) ; } public static < T > PageDTO < T > empty ( Page < ? > page) { return new PageDTO < > ( page. getTotal ( ) , page. getPages ( ) , CollUtils . emptyList ( ) ) ; } public static < T > PageDTO < T > of ( Page < T > page) { if ( page == null ) { return new PageDTO < > ( ) ; } if ( CollUtils . isEmpty ( page. getRecords ( ) ) ) { return empty ( page) ; } return new PageDTO < > ( page. getTotal ( ) , page. getPages ( ) , page. getRecords ( ) ) ; } public static < T , R > PageDTO < T > of ( Page < R > page, Function < R , T > mapper) { if ( page == null ) { return new PageDTO < > ( ) ; } if ( CollUtils . isEmpty ( page. getRecords ( ) ) ) { return empty ( page) ; } return new PageDTO < > ( page. getTotal ( ) , page. getPages ( ) , page. getRecords ( ) . stream ( ) . map ( mapper) . collect ( Collectors . toList ( ) ) ) ; } public static < T > PageDTO < T > of ( Page < ? > page, List < T > list) { return new PageDTO < > ( page. getTotal ( ) , page. getPages ( ) , list) ; } public static < T , R > PageDTO < T > of ( Page < R > page, Class < T > clazz) { return new PageDTO < > ( page. getTotal ( ) , page. getPages ( ) , BeanUtils . copyList ( page. getRecords ( ) , clazz) ) ; } public static < T , R > PageDTO < T > of ( Page < R > page, Class < T > clazz, Convert < R , T > convert) { return new PageDTO < > ( page. getTotal ( ) , page. getPages ( ) , BeanUtils . copyList ( page. getRecords ( ) , clazz, convert) ) ; } @ApiModelProperty ( hidden = true ) @JsonIgnore public boolean isEmpty ( ) { return list == null || list. size ( ) == 0 ; }
}
二、 PageQuery
2.1 PageQuery代码
import com. baomidou. mybatisplus. core. metadata. OrderItem ;
import com. baomidou. mybatisplus. extension. plugins. pagination. Page ;
import com. xxx. common. constants. Constant ;
import com. xxx. common. utils. StringUtils ;
import io. swagger. annotations. ApiModel ;
import io. swagger. annotations. ApiModelProperty ;
import lombok. Data ;
import lombok. experimental. Accessors ; import javax. validation. constraints. Min ; @Data
@ApiModel ( description = "分页请求参数" )
@Accessors ( chain = true )
public class PageQuery { public static final Integer DEFAULT_PAGE_SIZE = 20 ; public static final Integer DEFAULT_PAGE_NUM = 1 ; @ApiModelProperty ( value = "页码" , example = "1" ) @Min ( value = 1 , message = "页码不能小于1" ) private Integer pageNo = DEFAULT_PAGE_NUM ; @ApiModelProperty ( value = "每页大小" , example = "5" ) @Min ( value = 1 , message = "每页查询数量不能小于1" ) private Integer pageSize = DEFAULT_PAGE_SIZE ; @ApiModelProperty ( value = "是否升序" , example = "true" ) private Boolean isAsc = true ; @ApiModelProperty ( value = "排序字段" , example = "id" ) private String sortBy; public int from ( ) { return ( pageNo - 1 ) * pageSize; } public < T > Page < T > toMpPage ( OrderItem . . . orderItems) { Page < T > page = new Page < > ( pageNo, pageSize) ; if ( orderItems != null && orderItems. length > 0 ) { for ( OrderItem orderItem : orderItems) { page. addOrder ( orderItem) ; } return page; } if ( StringUtils . isNotEmpty ( sortBy) ) { OrderItem orderItem = new OrderItem ( ) ; orderItem. setAsc ( isAsc) ; orderItem. setColumn ( sortBy) ; page. addOrder ( orderItem) ; } return page; } public < T > Page < T > toMpPage ( String defaultSortBy, boolean isAsc) { if ( StringUtils . isBlank ( sortBy) ) { sortBy = defaultSortBy; this . isAsc = isAsc; } Page < T > page = new Page < > ( pageNo, pageSize) ; OrderItem orderItem = new OrderItem ( ) ; orderItem. setAsc ( this . isAsc) ; orderItem. setColumn ( sortBy) ; page. addOrder ( orderItem) ; return page; } public < T > Page < T > toMpPageDefaultSortByCreateTimeDesc ( ) { return toMpPage ( Constant . DATA_FIELD_NAME_CREATE_TIME , false ) ; }
}
2.2 使用举例
@EqualsAndHashCode ( callSuper = true )
@Data
@ApiModel ( description = "互动问题分页查询条件" )
public class QuestionPageQuery extends PageQuery { @ApiModelProperty ( value = "课程id" ) private Long courseId; @ApiModelProperty ( value = "小节id" , example = "1" ) private Long sectionId; @ApiModelProperty ( value = "是否只查询我的问题" , example = "1" ) private Boolean onlyMine;
} -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
Long userId = UserContext . getUser ( ) ; Boolean onlyMine = query. getOnlyMine ( ) ;
Long sectionId = query. getSectionId ( ) ;
Long courseId = query. getCourseId ( ) ;
Page < InteractionQuestion > page = this . lambdaQuery ( ) . eq ( onlyMine, InteractionQuestion :: getUserId , userId) . eq ( courseId != null , InteractionQuestion :: getCourseId , courseId) . eq ( sectionId != null , InteractionQuestion :: getSectionId , sectionId) . eq ( InteractionQuestion :: getHidden , false ) . page ( query. toMpPageDefaultSortByCreateTimeDesc ( ) ) ;
List < InteractionQuestion > records = page. getRecords ( ) ;
if ( CollUtils . isEmpty ( records) ) { return PageDTO . empty ( page) ;
}
Long userId = UserContext . getUser ( ) ;
Page < LearningLesson > page = this . lambdaQuery ( ) . eq ( LearningLesson :: getUserId , userId) . page ( query. toMpPage ( "latest_learn_time" , false ) ) ;
List < LearningLesson > records = page. getRecords ( ) ;
if ( CollUtils . isEmpty ( records) ) { return PageDTO . empty ( page) ;
}
三、BeanUtils
3.1 BeanUtils代码
import cn. hutool. core. bean. BeanUtil ; import java. util. List ;
import java. util. stream. Collectors ;
public class BeanUtils extends BeanUtil { public static < R , T > T copyBean ( R source, Class < T > clazz, Convert < R , T > convert) { T target = copyBean ( source, clazz) ; if ( convert != null ) { convert. convert ( source, target) ; } return target; } public static < R , T > T copyBean ( R source, Class < T > clazz) { if ( source == null ) { return null ; } return toBean ( source, clazz) ; } public static < R , T > List < T > copyList ( List < R > list, Class < T > clazz) { if ( list == null || list. size ( ) == 0 ) { return CollUtils . emptyList ( ) ; } return copyToList ( list, clazz) ; } public static < R , T > List < T > copyList ( List < R > list, Class < T > clazz, Convert < R , T > convert) { if ( list == null || list. size ( ) == 0 ) { return CollUtils . emptyList ( ) ; } return list. stream ( ) . map ( r -> copyBean ( r, clazz, convert) ) . collect ( Collectors . toList ( ) ) ; }
}
package com. xxx. common. utils ;
public interface Convert < R , T > { void convert ( R origin, T target) ;
}
3.2 举例
public void save ( CourseTeacherSaveDTO courseTeacherSaveDTO) { LambdaUpdateWrapper < CourseTeacherDraft > updateWrapper = Wrappers . lambdaUpdate ( CourseTeacherDraft . class ) . eq ( CourseTeacherDraft :: getCourseId , courseTeacherSaveDTO. getId ( ) ) ; baseMapper. delete ( updateWrapper) ; List < CourseTeacherDraft > courseTeacherDrafts = BeanUtils . copyList ( courseTeacherSaveDTO. getTeachers ( ) , CourseTeacherDraft . class , ( teacherInfo, teacherDraft) -> { teacherDraft. setCourseId ( courseTeacherSaveDTO. getId ( ) ) ; teacherDraft. setTeacherId ( teacherInfo. getId ( ) ) ; teacherDraft. setCIndex ( courseTeacherSaveDTO. getTeachers ( ) . indexOf ( teacherInfo) ) ; } ) ; saveBatch ( courseTeacherDrafts) ; courseDraftService. updateStep ( courseTeacherSaveDTO. getId ( ) , CourseConstants. CourseStep . TEACHER ) ; } -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -
@ApiModel ( "课程老师关系模型" )
public class CourseTeacherSaveDTO { @ApiModelProperty ( "课程id" ) @NotNull ( message = CourseErrorInfo. Msg . COURSE_TEACHER_SAVE_COURSE_ID_NULL ) private Long id; @ApiModelProperty ( "老师id和用户端是否展示,该列表按照界面上的顺序" ) @NotNull ( message = CourseErrorInfo. Msg . COURSE_TEACHER_SAVE_TEACHERS_NULL )
@Size ( min = 1 , max = 5 , message = CourseErrorInfo. Msg . COURSE_TEACHER_SAVE_TEACHERS_NUM_MAX ) private List < TeacherInfo > teachers; @Data @ApiModel ( "老师id和用户端是否显示" ) public static class TeacherInfo { @ApiModelProperty ( "老师id" ) @NotNull ( message = CourseErrorInfo. Msg . COURSE_TEACHER_SAVE_TEACHER_ID_NULL ) private Long id; @ApiModelProperty ( "用户端是否展示" ) @NotNull ( message = CourseErrorInfo. Msg . COURSE_TEACHER_SAVE_TEACHER_SHOW ) private Boolean isShow; }
}
四、CollUtils
4.1 CollUtils代码
import cn. hutool. core. collection. CollectionUtil ;
import cn. hutool. core. collection. IterUtil ;
import com. xxx. common. validate. Checker ; import java. util. * ;
import java. util. function. Function ;
import java. util. stream. Collectors ;
public class CollUtils extends CollectionUtil { public static < T > List < T > emptyList ( ) { return Collections . emptyList ( ) ; } public static < T > Set < T > emptySet ( ) { return Collections . emptySet ( ) ; } public static < K , V > Map < K , V > emptyMap ( ) { return Collections . emptyMap ( ) ; } public static < T > Set < T > singletonSet ( T t) { return Collections . singleton ( t) ; } public static < T > List < T > singletonList ( T t) { return Collections . singletonList ( t) ; } public static List < Integer > convertToInteger ( List < String > originList) { return CollUtils . isNotEmpty ( originList) ? originList. stream ( ) . map ( NumberUtils :: parseInt ) . collect ( Collectors . toList ( ) ) : null ; } public static List < Long > convertToLong ( List < String > originLIst) { return CollUtils . isNotEmpty ( originLIst) ? originLIst. stream ( ) . map ( NumberUtils :: parseLong ) . collect ( Collectors . toList ( ) ) : null ; } public static < T > String join ( Collection < T > collection, CharSequence conjunction) { if ( null == collection || collection. isEmpty ( ) ) { return null ; } return IterUtil . join ( collection. iterator ( ) , conjunction) ; } public static < T > String joinIgnoreNull ( Collection < T > collection, CharSequence conjunction) { if ( null == collection || collection. isEmpty ( ) ) { return null ; } StringBuilder sb = new StringBuilder ( ) ; for ( T t : collection) { if ( t == null ) continue ; sb. append ( t) . append ( "," ) ; } if ( sb. length ( ) <= 0 ) { return null ; } return sb. deleteCharAt ( sb. length ( ) - 1 ) . toString ( ) ; } public static < T > void check ( List < T > data, Checker < T > checker) { if ( data == null ) { return ; } for ( T t : data) { checker. check ( t) ; } } public static < T extends Checker < T > > void check ( List < T > data) { if ( data == null ) { return ; } for ( T t : data) { t. check ( ) ; } } public static < T > void add ( Collection < T > list, T . . . data) { if ( list == null || ArrayUtils . isEmpty ( data) ) { return ; } for ( T t : data) { if ( ObjectUtils . isNotEmpty ( t) ) { list. add ( t) ; } } } public static Map < Long , Integer > union ( Map < Long , Integer > map1, Map < Long , Integer > map2) { if ( CollUtils . isEmpty ( map1) ) { return map2; } else if ( CollUtils . isEmpty ( map2) ) { return map1; } for ( Map. Entry < Long , Integer > entry : map1. entrySet ( ) ) { Integer num = map2. get ( entry. getKey ( ) ) ; map2. put ( entry. getKey ( ) , NumberUtils . null2Zero ( num) + entry. getValue ( ) ) ; } return map2; } public static < T , R > R getFiledOfFirst ( List < T > list, Function < T , R > function) { if ( CollUtils . isEmpty ( list) ) { return null ; } return function. apply ( list. get ( 0 ) ) ; }
}
public interface Checker < T > { default void check ( ) { } default void check ( T data) { }
}
4.2 checker举例
@ApiModel ( description = "章节" )
public class CataSaveDTO implements Checker { @ApiModelProperty ( "章、节、练习id" ) private Long id; @ApiModelProperty ( "目录类型1:章,2:节,3:测试" ) @NotNull ( message = "" ) private Integer type; @ApiModelProperty ( "章节练习名称" ) private String name; @ApiModelProperty ( "章排序,章一定要传,小节和练习不需要传" ) private Integer index; @ApiModelProperty ( "当前章的小节或练习" ) @Size ( min = 1 , message = "不能出现空章" ) private List < CataSaveDTO > sections; @Override public void check ( ) { if ( type == CourseConstants. CataType . CHAPTER && StringUtils . isEmpty ( name) ) { throw new BadRequestException ( CourseErrorInfo. Msg . COURSE_CATAS_SAVE_NAME_NULL ) ; } else if ( StringUtils . isEmpty ( name) ) { throw new BadRequestException ( CourseErrorInfo. Msg . COURSE_CATAS_SAVE_NAME_NULL2 ) ; } if ( type == CourseConstants. CataType . CHAPTER && name. length ( ) > 30 ) { throw new BadRequestException ( CourseErrorInfo. Msg . COURSE_CATAS_SAVE_NAME_SIZE ) ; } else if ( name. length ( ) > 30 ) { throw new BadRequestException ( CourseErrorInfo. Msg . COURSE_CATAS_SAVE_NAME_SIZE2 ) ; } if ( CollUtils . isEmpty ( sections) ) { throw new BadRequestException ( "不能出现空章" ) ; } }
}
@ApiModel ( "题目保存模型" )
@Data
public class SubjectSaveDTO implements Checker { @ApiModelProperty ( "题目id,为空新增,不为空更新" ) private Long id; @ApiModelProperty ( "名称" ) @NotNull ( message = "题目为空,请设置题目" ) @Size ( max = 200 , min = 5 , message = "题目长度为5-200" ) private String name; @ApiModelProperty ( "所属题目分类" ) @NotNull ( message = "题目分类为空,请设置题目分类" ) private List < List < Long > > cates; @ApiModelProperty ( "题目类型" ) @NotNull ( message = "题目类型为空,请设置题目类型" ) @EnumValid ( enumeration = { 1 , 2 , 3 , 4 , 5 } , message = "题目类型只有单选题,多选题,不定向选择题,判断题,您的题目超出题纲" ) private Integer subjectType; @ApiModelProperty ( "题目难易度" ) @NotNull ( message = "难度不能为空" ) @EnumValid ( enumeration = { 1 , 2 , 3 } , message = "题目难度只有简单,中等,困难" ) private Integer difficulty; @ApiModelProperty ( "分值" ) private Integer score; @ApiModelProperty ( "课程id" ) private List < Long > courseIds; @ApiModelProperty ( "选项,最多10个" ) private List < String > options; @ApiModelProperty ( "答案,判断题,数组第一个如果是1,代表正确,其他代表错误" ) @NotNull ( message = "题目答案不能为空" ) private List < Integer > answers; @ApiModelProperty ( "解析" ) private String analysis; @Override public void check ( ) { if ( subjectType == SubjectConstants. Type . SIGNLE_CHOICE . getType ( ) || subjectType == SubjectConstants. Type. MUtiple_CHOICE . getType ( ) || subjectType == SubjectConstants. Type . NON_DIRECTIONAL_CHOICE . getType ( ) ) { Integer answerOptionMax = answers. stream ( ) . max ( Integer :: compare ) . get ( ) ; if ( CollUtils . isEmpty ( options) || options. size ( ) > 10 ) { throw new BizIllegalException ( "最少1个选项,最多10个选项" ) ; } if ( answerOptionMax > options. size ( ) ) { throw new BizIllegalException ( "存在正确的答案找不到选项" ) ; } if ( StringUtils . isNotEmpty ( analysis) && ( StringUtils . length ( analysis) < 5 || StringUtils . length ( analysis) > 300 ) ) { throw new BadRequestException ( "答案解析长度为5-300" ) ; } } }
}