From eb9ba8ad7ce6e9f3ccd4d46503cb023abf58d29a Mon Sep 17 00:00:00 2001 From: secret <1029693356@qq.com> Date: Sun, 6 Jun 2021 00:29:25 +0800 Subject: [PATCH 01/11] =?UTF-8?q?jpa=E6=89=A9=E5=B1=95api,=E5=8F=82?= =?UTF-8?q?=E6=95=B0=E6=A0=A1=E9=AA=8C=E6=93=8D=E4=BD=9C,=E6=96=B0?= =?UTF-8?q?=E5=A2=9Email=E5=B0=81=E8=A3=85=E6=A8=A1=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 6 + pom.xml | 3 +- secret-boot-framework-all/pom.xml | 9 +- secret-boot-framework-cache/pom.xml | 3 +- secret-boot-framework-captcha/pom.xml | 3 +- secret-boot-framework-core/pom.xml | 7 +- .../framework/core/context/SecretBanner.java | 2 +- .../core/model/response/AjaxResult.java | 6 + .../chenc/framework/core/util/AssertUtil.java | 48 ++ .../framework/core/util/ValidatorUtil.java | 92 ++++ .../common-demo/pom.xml | 2 +- secret-boot-framework-demo/jpa-demo/pom.xml | 2 +- .../security-demo/pom.xml | 2 +- secret-boot-framework-demo/shiro-demo/pom.xml | 2 +- secret-boot-framework-dependencies/pom.xml | 4 +- secret-boot-framework-excel/pom.xml | 3 +- secret-boot-framework-ffmpeg/pom.xml | 3 +- secret-boot-framework-jpa/pom.xml | 3 +- .../jpa/exception/RepositoryException.java | 96 ++++ .../jpa/exception/ServiceException.java | 95 ++++ .../jpa/repository/BaseRepository.java | 80 +++ .../jpa/repository/BaseRepositoryImpl.java | 483 ++++++++++++++++++ .../framework/jpa/service/BaseService.java | 95 ++++ .../jpa/service/BaseServiceImpl.java | 339 ++++++++++++ .../support/BaseJpaRepositoryFactoryBean.java | 48 ++ .../cn/chenc/framework/jpa/util/PageUtil.java | 132 +++++ .../framework/jpa/util/PageableUtil.java | 26 + .../chenc/framework/jpa/util/SqlHelper.java | 162 ++++++ secret-boot-framework-mail/pom.xml | 27 + .../mail/config/MailConfiguration.java | 37 ++ .../framework/mail/core/MailTemplate.java | 58 +++ .../mail/core/SecretMailTemplate.java | 94 ++++ secret-boot-framework-mybatisplus/pom.xml | 3 +- secret-boot-framework-security/pom.xml | 3 +- secret-boot-framework-shiro/pom.xml | 3 +- 35 files changed, 1948 insertions(+), 33 deletions(-) create mode 100644 secret-boot-framework-core/src/main/java/cn/chenc/framework/core/util/AssertUtil.java create mode 100644 secret-boot-framework-core/src/main/java/cn/chenc/framework/core/util/ValidatorUtil.java create mode 100644 secret-boot-framework-jpa/src/main/java/cn/chenc/framework/jpa/exception/RepositoryException.java create mode 100644 secret-boot-framework-jpa/src/main/java/cn/chenc/framework/jpa/exception/ServiceException.java create mode 100644 secret-boot-framework-jpa/src/main/java/cn/chenc/framework/jpa/repository/BaseRepository.java create mode 100644 secret-boot-framework-jpa/src/main/java/cn/chenc/framework/jpa/repository/BaseRepositoryImpl.java create mode 100644 secret-boot-framework-jpa/src/main/java/cn/chenc/framework/jpa/service/BaseService.java create mode 100644 secret-boot-framework-jpa/src/main/java/cn/chenc/framework/jpa/service/BaseServiceImpl.java create mode 100644 secret-boot-framework-jpa/src/main/java/cn/chenc/framework/jpa/support/BaseJpaRepositoryFactoryBean.java create mode 100644 secret-boot-framework-jpa/src/main/java/cn/chenc/framework/jpa/util/PageUtil.java create mode 100644 secret-boot-framework-jpa/src/main/java/cn/chenc/framework/jpa/util/PageableUtil.java create mode 100644 secret-boot-framework-jpa/src/main/java/cn/chenc/framework/jpa/util/SqlHelper.java create mode 100644 secret-boot-framework-mail/pom.xml create mode 100644 secret-boot-framework-mail/src/main/java/cn/chenc/framework/mail/config/MailConfiguration.java create mode 100644 secret-boot-framework-mail/src/main/java/cn/chenc/framework/mail/core/MailTemplate.java create mode 100644 secret-boot-framework-mail/src/main/java/cn/chenc/framework/mail/core/SecretMailTemplate.java diff --git a/README.md b/README.md index 9ff2456..3b58083 100644 --- a/README.md +++ b/README.md @@ -35,6 +35,12 @@ secret-boot脚手架(根据核心依赖版本长期更新,正常更新周期 **关于本框架详情介绍请看 [wiki说明文档](https://gitee.com/SecretOpen/secret-boot-framework/wikis/%E7%AE%80%E4%BB%8B?sort_id=3220070)** +#### 互动交流群 + +**企鹅群:635508577** + +![avatar](https://images.gitee.com/uploads/images/2021/0307/150703_c5b23743_1815246.png) + #### 使用方法 已发布到maven中央仓库,建议使用1.4.0+版本 diff --git a/pom.xml b/pom.xml index b779e5a..fba5a1a 100644 --- a/pom.xml +++ b/pom.xml @@ -15,6 +15,7 @@ secret-boot-framework-security secret-boot-framework-dependencies secret-boot-framework-shiro + secret-boot-framework-mail @@ -22,7 +23,7 @@ com.gitee.secretopen secret-boot-framework - 1.5.0 + 1.6.0 ${project.groupId}:${project.artifactId} secret-boot-framework是一个基于springboot的快速开发框架,实现开发中最基础的springboot、mybatis、redis整合,内置丰富的基础工具类,开箱即用 diff --git a/secret-boot-framework-all/pom.xml b/secret-boot-framework-all/pom.xml index cf06cf5..3196b55 100644 --- a/secret-boot-framework-all/pom.xml +++ b/secret-boot-framework-all/pom.xml @@ -5,7 +5,7 @@ secret-boot-framework com.gitee.secretopen - 1.5.0 + 1.6.0 4.0.0 @@ -15,37 +15,30 @@ com.gitee.secretopen secret-boot-framework-core - ${project.parent.version} com.gitee.secretopen secret-boot-framework-cache - ${project.parent.version} com.gitee.secretopen secret-boot-framework-jpa - ${project.parent.version} com.gitee.secretopen secret-boot-framework-captcha - ${project.parent.version} com.gitee.secretopen secret-boot-framework-ffmpeg - ${project.parent.version} com.gitee.secretopen secret-boot-framework-excel - ${project.parent.version} com.gitee.secretopen secret-boot-framework-security - ${project.parent.version} diff --git a/secret-boot-framework-cache/pom.xml b/secret-boot-framework-cache/pom.xml index e611448..6ffbf70 100644 --- a/secret-boot-framework-cache/pom.xml +++ b/secret-boot-framework-cache/pom.xml @@ -5,7 +5,7 @@ secret-boot-framework com.gitee.secretopen - 1.5.0 + 1.6.0 ${project.artifactId} 4.0.0 @@ -16,7 +16,6 @@ com.gitee.secretopen secret-boot-framework-core - ${project.parent.version} diff --git a/secret-boot-framework-captcha/pom.xml b/secret-boot-framework-captcha/pom.xml index 7c3a904..201d138 100644 --- a/secret-boot-framework-captcha/pom.xml +++ b/secret-boot-framework-captcha/pom.xml @@ -5,7 +5,7 @@ secret-boot-framework com.gitee.secretopen - 1.5.0 + 1.6.0 ${project.artifactId} 4.0.0 @@ -15,7 +15,6 @@ com.gitee.secretopen secret-boot-framework-core - ${project.parent.version} diff --git a/secret-boot-framework-core/pom.xml b/secret-boot-framework-core/pom.xml index c11bf1e..fe3d2a9 100644 --- a/secret-boot-framework-core/pom.xml +++ b/secret-boot-framework-core/pom.xml @@ -5,7 +5,7 @@ secret-boot-framework com.gitee.secretopen - 1.5.0 + 1.6.0 ${project.artifactId} jar @@ -37,6 +37,11 @@ spring-boot-starter-data-redis true + + + org.springframework.boot + spring-boot-starter-validation + com.google.guava diff --git a/secret-boot-framework-core/src/main/java/cn/chenc/framework/core/context/SecretBanner.java b/secret-boot-framework-core/src/main/java/cn/chenc/framework/core/context/SecretBanner.java index fb27bed..08e5901 100644 --- a/secret-boot-framework-core/src/main/java/cn/chenc/framework/core/context/SecretBanner.java +++ b/secret-boot-framework-core/src/main/java/cn/chenc/framework/core/context/SecretBanner.java @@ -7,7 +7,7 @@ package cn.chenc.framework.core.context; * */ public class SecretBanner { - public static final String INIT_VERSION = "1.5.0"; + public static final String INIT_VERSION = "1.6.0"; public static final String LOGO = " ________ _______ ________ ________ _______ _________\n" + diff --git a/secret-boot-framework-core/src/main/java/cn/chenc/framework/core/model/response/AjaxResult.java b/secret-boot-framework-core/src/main/java/cn/chenc/framework/core/model/response/AjaxResult.java index ec54e7b..fcfe853 100644 --- a/secret-boot-framework-core/src/main/java/cn/chenc/framework/core/model/response/AjaxResult.java +++ b/secret-boot-framework-core/src/main/java/cn/chenc/framework/core/model/response/AjaxResult.java @@ -146,4 +146,10 @@ public class AjaxResult extends HashMap { return new AjaxResult(code, msg, null); } + + @Override + public AjaxResult put(String key, Object value){ + super.put(key,value); + return this; + } } diff --git a/secret-boot-framework-core/src/main/java/cn/chenc/framework/core/util/AssertUtil.java b/secret-boot-framework-core/src/main/java/cn/chenc/framework/core/util/AssertUtil.java new file mode 100644 index 0000000..e3cf848 --- /dev/null +++ b/secret-boot-framework-core/src/main/java/cn/chenc/framework/core/util/AssertUtil.java @@ -0,0 +1,48 @@ +package cn.chenc.framework.core.util; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.ArrayUtil; +import cn.hutool.core.util.StrUtil; + +import java.util.Collection; +import java.util.Map; + +/** + *  @description: TODO + *  @author secret + *  @date 2021/6/5 23:17 + * + */ +public class AssertUtil { + + public static void isTrue(boolean expression, String message) { + if (!expression) { + throw new IllegalArgumentException(StrUtil.format(message, new Object[0])); + } + } + + public static void isFalse(boolean expression, String message) { + isTrue(!expression, message); + } + + public static void isNull(Object object, String message) { + isTrue(object == null, message); + } + + public static void notNull(Object object, String message) { + isTrue(object != null, message); + } + + public static void notEmpty(Collection collection, String message) { + isTrue(CollectionUtil.isNotEmpty(collection), message); + } + + public static void notEmpty(Map map, String message) { + isTrue(CollectionUtil.isNotEmpty(map), message); + } + + public static void notEmpty(Object[] array, String message) { + isTrue(ArrayUtil.isNotEmpty(array), message); + } + +} diff --git a/secret-boot-framework-core/src/main/java/cn/chenc/framework/core/util/ValidatorUtil.java b/secret-boot-framework-core/src/main/java/cn/chenc/framework/core/util/ValidatorUtil.java new file mode 100644 index 0000000..59fc5a8 --- /dev/null +++ b/secret-boot-framework-core/src/main/java/cn/chenc/framework/core/util/ValidatorUtil.java @@ -0,0 +1,92 @@ +package cn.chenc.framework.core.util; + + +import javax.validation.ConstraintViolation; +import javax.validation.Validation; +import javax.validation.Validator; +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +/** + *  @description: TODO + *  @author secret + *  @date 2021/3/22 11:42 + * + */ +public class ValidatorUtil { + + private static Validator validator; + + static { + validator = Validation.buildDefaultValidatorFactory().getValidator(); + } + + /** + * 校验对象 + * + * @param object 待校验对象 + * @param groups 待校验的组 + * @return 返回消息list + */ + public static List validateEntityAll(Object object, Class... groups) { + List list=new ArrayList<>(); + Set> constraintViolations = validator.validate(object, groups); + if (!constraintViolations.isEmpty()) { + constraintViolations.forEach(o -> { + list.add(o.getMessage()); + }); + } + return list; + } + + /** + * 校验对象 + * + * @param object 待校验对象 + */ + public static List validateEntityAll(Object object) { + List list=new ArrayList<>(); + Set> constraintViolations = validator.validate(object); + if (!constraintViolations.isEmpty()) { + constraintViolations.forEach(o -> { + list.add(o.getMessage()); + }); + } + return list; + } + + /** + * 校验对象 + * + * @param object 待校验对象 + * @param groups 待校验的组 + * @return 返回单个校验消息 + */ + public static String validateEntityFirst(Object object, Class... groups) { + Set> constraintViolations = validator.validate(object, groups); + if (!constraintViolations.isEmpty()) { + for(ConstraintViolation o:constraintViolations){ + return o.getMessage(); + } + } + return null; + } + + /** + * 校验对象 + * @param object 待校验对象 + * @return 返回单个校验消息 + */ + public static String validateEntityFirst(Object object) { + Set> constraintViolations = validator.validate(object); + if (!constraintViolations.isEmpty()) { + for(ConstraintViolation o:constraintViolations){ + return o.getMessage(); + } + } + return null; + } + + +} diff --git a/secret-boot-framework-demo/common-demo/pom.xml b/secret-boot-framework-demo/common-demo/pom.xml index 4ecb170..4b0d847 100644 --- a/secret-boot-framework-demo/common-demo/pom.xml +++ b/secret-boot-framework-demo/common-demo/pom.xml @@ -18,7 +18,7 @@ com.gitee.secretopen secret-boot-framework-dependencies - 1.5.0 + 1.6.0 pom import diff --git a/secret-boot-framework-demo/jpa-demo/pom.xml b/secret-boot-framework-demo/jpa-demo/pom.xml index 3c5319a..d3676d6 100644 --- a/secret-boot-framework-demo/jpa-demo/pom.xml +++ b/secret-boot-framework-demo/jpa-demo/pom.xml @@ -13,7 +13,7 @@ com.gitee.secretopen secret-boot-framework-dependencies - 1.5.0 + 1.6.0 pom import diff --git a/secret-boot-framework-demo/security-demo/pom.xml b/secret-boot-framework-demo/security-demo/pom.xml index be2a508..1399ec8 100644 --- a/secret-boot-framework-demo/security-demo/pom.xml +++ b/secret-boot-framework-demo/security-demo/pom.xml @@ -14,7 +14,7 @@ com.gitee.secretopen secret-boot-framework-dependencies - 1.5.0 + 1.6.0 pom import diff --git a/secret-boot-framework-demo/shiro-demo/pom.xml b/secret-boot-framework-demo/shiro-demo/pom.xml index 77e9c5e..4ce60a2 100644 --- a/secret-boot-framework-demo/shiro-demo/pom.xml +++ b/secret-boot-framework-demo/shiro-demo/pom.xml @@ -13,7 +13,7 @@ com.gitee.secretopen secret-boot-framework-dependencies - 1.5.0 + 1.6.0 pom import diff --git a/secret-boot-framework-dependencies/pom.xml b/secret-boot-framework-dependencies/pom.xml index bf1aada..50d4ac2 100644 --- a/secret-boot-framework-dependencies/pom.xml +++ b/secret-boot-framework-dependencies/pom.xml @@ -9,7 +9,7 @@ 4.0.0 - 1.5.0 + 1.6.0 com.gitee.secretopen secret-boot-framework-dependencies pom @@ -20,7 +20,7 @@ 1.8 - 1.5.0 + 1.6.0 2.4.3.RELEASE 1.2.6 8.0.25 diff --git a/secret-boot-framework-excel/pom.xml b/secret-boot-framework-excel/pom.xml index 047fd4c..70cdcc3 100644 --- a/secret-boot-framework-excel/pom.xml +++ b/secret-boot-framework-excel/pom.xml @@ -5,7 +5,7 @@ secret-boot-framework com.gitee.secretopen - 1.5.0 + 1.6.0 4.0.0 @@ -15,7 +15,6 @@ com.gitee.secretopen secret-boot-framework-core - ${project.parent.version} diff --git a/secret-boot-framework-ffmpeg/pom.xml b/secret-boot-framework-ffmpeg/pom.xml index 39136b4..dad057d 100644 --- a/secret-boot-framework-ffmpeg/pom.xml +++ b/secret-boot-framework-ffmpeg/pom.xml @@ -5,7 +5,7 @@ secret-boot-framework com.gitee.secretopen - 1.5.0 + 1.6.0 4.0.0 @@ -15,7 +15,6 @@ com.gitee.secretopen secret-boot-framework-core - ${project.parent.version} diff --git a/secret-boot-framework-jpa/pom.xml b/secret-boot-framework-jpa/pom.xml index b3e490d..b24d282 100644 --- a/secret-boot-framework-jpa/pom.xml +++ b/secret-boot-framework-jpa/pom.xml @@ -5,7 +5,7 @@ secret-boot-framework com.gitee.secretopen - 1.5.0 + 1.6.0 4.0.0 @@ -15,7 +15,6 @@ com.gitee.secretopen secret-boot-framework-core - ${project.parent.version} diff --git a/secret-boot-framework-jpa/src/main/java/cn/chenc/framework/jpa/exception/RepositoryException.java b/secret-boot-framework-jpa/src/main/java/cn/chenc/framework/jpa/exception/RepositoryException.java new file mode 100644 index 0000000..6489305 --- /dev/null +++ b/secret-boot-framework-jpa/src/main/java/cn/chenc/framework/jpa/exception/RepositoryException.java @@ -0,0 +1,96 @@ +package cn.chenc.framework.jpa.exception; + +/** + *  @description: jpa异常 + *  @author secret + *  @date 2021/6/5 22:16 + * + */ +public class RepositoryException extends Exception { + + private static final long serialVersionUID = 1L; + private String module; + private String code = "500"; + private Object[] args; + private String msg; + + public RepositoryException(String msg) { + super(msg); + this.msg = msg; + } + + public RepositoryException(String code, Object[] args) { + this.code = code; + this.args = args; + } + + public RepositoryException(String code, String msg) { + this.code = code; + this.msg = msg; + } + + public RepositoryException(String module, String code, Object[] args) { + this.module = module; + this.code = code; + this.args = args; + } + + public RepositoryException(String module, String code, Object[] args, String msg) { + this.module = module; + this.code = code; + this.args = args; + this.msg = msg; + } + + public RepositoryException(Throwable throwable) { + super(throwable); + } + + public RepositoryException(String msg, Throwable e) { + super(msg, e); + this.msg = msg; + } + + public RepositoryException(String msg, String code, Throwable e) { + super(msg, e); + this.msg = msg; + this.code = code; + } + + @Override + public String toString() { + return this.getClass() + "{" + "module='" + this.module + '\'' + ", message='" + this.getMessage() + '\'' + '}'; + } + + public String getModule() { + return this.module; + } + + public String getCode() { + return this.code; + } + + public Object[] getArgs() { + return this.args; + } + + public String getMsg() { + return this.msg; + } + + public void setModule(final String module) { + this.module = module; + } + + public void setCode(final String code) { + this.code = code; + } + + public void setArgs(final Object[] args) { + this.args = args; + } + + public void setMsg(final String msg) { + this.msg = msg; + } +} diff --git a/secret-boot-framework-jpa/src/main/java/cn/chenc/framework/jpa/exception/ServiceException.java b/secret-boot-framework-jpa/src/main/java/cn/chenc/framework/jpa/exception/ServiceException.java new file mode 100644 index 0000000..73bbfa5 --- /dev/null +++ b/secret-boot-framework-jpa/src/main/java/cn/chenc/framework/jpa/exception/ServiceException.java @@ -0,0 +1,95 @@ +package cn.chenc.framework.jpa.exception; + +/** + *  @description: service 异常 + *  @author secret + *  @date 2021/6/5 23:31 + * + */ +public class ServiceException extends Exception { + private static final long serialVersionUID = 1L; + private String module; + private String code = "500"; + private Object[] args; + private String msg; + + public ServiceException(String msg) { + super(msg); + this.msg = msg; + } + + public ServiceException(String code, Object[] args) { + this.code = code; + this.args = args; + } + + public ServiceException(String code, String msg) { + this.code = code; + this.msg = msg; + } + + public ServiceException(String module, String code, Object[] args) { + this.module = module; + this.code = code; + this.args = args; + } + + public ServiceException(String module, String code, Object[] args, String msg) { + this.module = module; + this.code = code; + this.args = args; + this.msg = msg; + } + + public ServiceException(Throwable throwable) { + super(throwable); + } + + public ServiceException(String msg, Throwable e) { + super(msg, e); + this.msg = msg; + } + + public ServiceException(String msg, String code, Throwable e) { + super(msg, e); + this.msg = msg; + this.code = code; + } + + @Override + public String toString() { + return this.getClass() + "{" + "module='" + this.module + '\'' + ", message='" + this.getMessage() + '\'' + '}'; + } + + public String getModule() { + return this.module; + } + + public String getCode() { + return this.code; + } + + public Object[] getArgs() { + return this.args; + } + + public String getMsg() { + return this.msg; + } + + public void setModule(final String module) { + this.module = module; + } + + public void setCode(final String code) { + this.code = code; + } + + public void setArgs(final Object[] args) { + this.args = args; + } + + public void setMsg(final String msg) { + this.msg = msg; + } +} diff --git a/secret-boot-framework-jpa/src/main/java/cn/chenc/framework/jpa/repository/BaseRepository.java b/secret-boot-framework-jpa/src/main/java/cn/chenc/framework/jpa/repository/BaseRepository.java new file mode 100644 index 0000000..67480d9 --- /dev/null +++ b/secret-boot-framework-jpa/src/main/java/cn/chenc/framework/jpa/repository/BaseRepository.java @@ -0,0 +1,80 @@ +package cn.chenc.framework.jpa.repository; + +import cn.chenc.framework.jpa.exception.RepositoryException; +import cn.chenc.framework.jpa.util.PageUtil; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Sort; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; +import org.springframework.data.repository.NoRepositoryBean; + +import java.io.Serializable; +import java.util.Collection; +import java.util.List; +import java.util.Map; + +/** + *  @description: Jpa扩展-BaseRepository + *  @author secret + *  @date 2021/6/5 22:12 + * + */ +@NoRepositoryBean +public interface BaseRepository extends JpaRepository, JpaSpecificationExecutor { + T get(ID id) throws RepositoryException; + + T update(T t) throws RepositoryException; + + T saveOrUpdate(ID id, T t) throws RepositoryException; + + void delete(ID id) throws RepositoryException; + + void deleteBatchByIds(Collection ids) throws RepositoryException; + + T getOneByObject(T t) throws RepositoryException; + + List getListByObject(T t) throws RepositoryException; + + List getListByObject(T t, Sort sort) throws RepositoryException; + + Page getListByObject(T t, Pageable pageable) throws RepositoryException; + + List getListBySql(String sql) throws RepositoryException; + + List getListBySql(String sql, Class clzss) throws RepositoryException; + + PageUtil getListBySql(String sql, PageUtil pageable) throws RepositoryException; + + PageUtil getListBySql(String sql, PageUtil pageable, Map searchMap) throws RepositoryException; + + List> getListMapBySql(String sql) throws RepositoryException; + + List> getListMapBySql(String sql, Map searchMap) throws RepositoryException; + + PageUtil getListMapBySql(String sql, PageUtil pageable) throws RepositoryException; + + PageUtil getListMapBySql(String sql, PageUtil pageable, Map searchMap) throws RepositoryException; + + Map getSingleMapBySql(String sql) throws RepositoryException; + + int insertBySql(String sql) throws RepositoryException; + + int insertBySql(String sql, Map paraMap) throws RepositoryException; + + int updateBySql(String sql) throws RepositoryException; + + int deleteBySql(String sql) throws RepositoryException; + + int executeBySql(String sql) throws RepositoryException; + + int executeBySql(List sqls) throws RepositoryException; + + int getCountBySql(String sql, Map searchMap) throws RepositoryException; + + List getColumnsBySql(String sql) throws RepositoryException; + + List> getColumnsAndTypeBySql(String sql) throws RepositoryException; + + List getColumnsByTableName(String tableName) throws RepositoryException; +} diff --git a/secret-boot-framework-jpa/src/main/java/cn/chenc/framework/jpa/repository/BaseRepositoryImpl.java b/secret-boot-framework-jpa/src/main/java/cn/chenc/framework/jpa/repository/BaseRepositoryImpl.java new file mode 100644 index 0000000..543419f --- /dev/null +++ b/secret-boot-framework-jpa/src/main/java/cn/chenc/framework/jpa/repository/BaseRepositoryImpl.java @@ -0,0 +1,483 @@ +package cn.chenc.framework.jpa.repository; + +import cn.chenc.framework.core.text.Convert; +import cn.chenc.framework.core.util.AssertUtil; +import cn.chenc.framework.jpa.exception.RepositoryException; +import cn.chenc.framework.jpa.util.PageUtil; +import cn.chenc.framework.jpa.util.SqlHelper; +import cn.hutool.core.map.MapUtil; +import org.hibernate.Session; +import org.hibernate.internal.SessionImpl; +import org.hibernate.query.internal.NativeQueryImpl; +import org.hibernate.transform.Transformers; +import org.springframework.dao.EmptyResultDataAccessException; +import org.springframework.data.domain.Example; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Sort; +import org.springframework.data.jpa.repository.Modifying; +import org.springframework.data.jpa.repository.support.JpaEntityInformation; +import org.springframework.data.jpa.repository.support.SimpleJpaRepository; +import org.springframework.data.repository.NoRepositoryBean; +import org.springframework.transaction.annotation.Transactional; + +import javax.persistence.EntityManager; +import javax.persistence.PersistenceContext; +import javax.persistence.Query; +import java.io.Serializable; +import java.sql.Connection; +import java.sql.ResultSet; +import java.sql.ResultSetMetaData; +import java.sql.SQLException; +import java.util.*; + +/** + *  @description: BaseRepository 实现 + *  @author secret + *  @date 2021/6/5 23:14 + * + */ +@NoRepositoryBean +@Transactional +public class BaseRepositoryImpl extends SimpleJpaRepository + implements BaseRepository { + + @PersistenceContext + private final EntityManager entityManager; + private Class clazz; + private JpaEntityInformation entityInformation; + + public BaseRepositoryImpl(JpaEntityInformation entityInformation, Class domainClass, EntityManager entityManager) { + super(domainClass, entityManager); + this.clazz = domainClass; + this.entityManager = entityManager; + this.entityInformation = entityInformation; + } + + @Override + public T get(ID id) throws RepositoryException { + AssertUtil.notNull(id, "get() id must not be null!"); + T t = this.entityManager.find(this.clazz, id); + if (this.entityManager != null) { + this.entityManager.close(); + } + + return t; + } + + @Override + @Modifying + public T update(T t) throws RepositoryException { + AssertUtil.notNull(t, "modify() entity must not be null!"); + Session session = (Session)this.entityManager.unwrap(Session.class); + T entity = (T) session.merge(t); + if (this.entityManager != null) { + this.entityManager.close(); + } + + return entity; + } + + @Override + public T saveOrUpdate(ID id, T t) throws RepositoryException { + AssertUtil.notNull(id, "id must not be null"); + AssertUtil.notNull(t, "entity must not be null"); + if (id != null) { + T entity = this.get(id); + if (entity != null) { + return this.update(t); + } + } + + return this.save(t); + } + + @Override + public void delete(ID id) throws RepositoryException { + AssertUtil.notNull(id, "id must not be null"); + T entity = this.get(id); + if (entity == null) { + String msg = String.format("No %s entity with id %s exists!", this.entityInformation.getJavaType(), id); + throw new EmptyResultDataAccessException(msg, 1); + } else { + this.deleteById(id); + } + } + + @Override + public void deleteBatchByIds(Collection ids) throws RepositoryException { + AssertUtil.notNull(ids, "ids must not be null"); + Iterator var2 = ids.iterator(); + + while(var2.hasNext()) { + ID id = (ID) var2.next(); + this.deleteById(id); + } + + } + + @Override + public T getOneByObject(T t) throws RepositoryException { + T entity = null; + Example example = Example.of(t); + + try { + Optional optional = this.findOne(example); + if (optional.isPresent()) { + entity = optional.get(); + } + + return entity; + } catch (Exception var5) { + throw new RepositoryException("Problem invoking method, Cause:" + var5.getMessage(), var5); + } + } + + @Override + public List getListByObject(T t) throws RepositoryException { + Example example = Example.of(t); + return this.findAll(example); + } + + @Override + public List getListByObject(T t, Sort sort) throws RepositoryException { + Example example = Example.of(t); + return this.findAll(example, sort); + } + + @Override + public Page getListByObject(T t, Pageable pageable) throws RepositoryException { + Example example = Example.of(t); + return this.findAll(example, pageable); + } + + @Override + public List getListBySql(String sql) throws RepositoryException { + return this.getListBySql(sql, this.clazz); + } + + @Override + public List getListBySql(String sql, Class clzss) throws RepositoryException { + AssertUtil.notNull(sql, "getListBySql() sql and object must not be null!"); + AssertUtil.notNull(clzss, "getListBySql() clzss must not be null!"); + Query query = this.entityManager.createNativeQuery(sql, clzss); + List list = query.getResultList(); + if (this.entityManager != null) { + this.entityManager.close(); + } + return list; + } + + @Override + public PageUtil getListBySql(String sql, PageUtil pageable) throws RepositoryException { + return this.getListBySql(sql, pageable, (Map)null); + } + + + @Override + public PageUtil getListBySql(String sql, PageUtil pageable, Map searchMap) throws RepositoryException { + Query query = this.entityManager.createNativeQuery(sql, this.clazz); + if (null != searchMap) { + Iterator var5 = searchMap.entrySet().iterator(); + + while(var5.hasNext()) { + Map.Entry entry = (Map.Entry)var5.next(); + query.setParameter((String)entry.getKey(), entry.getValue()); + } + } + + int pageNum = pageable.getPageNum(); + int pageSize = pageable.getPageSize(); + if (pageNum >= 1 && pageSize >= 1) { + int currPageCount = cn.chenc.framework.jpa.util.PageUtil.offsetCurrent(pageNum, pageSize); + int totalCount = this.getCountBySql(sql, searchMap); + query.setFirstResult(currPageCount).setMaxResults(pageSize); + List> list = query.getResultList(); + PageUtil pageUtil = new PageUtil(pageNum, pageSize, totalCount); + pageUtil.setCurrPageCount(list.size()); + pageUtil.setContent(list); + return pageUtil; + } else { + throw new IllegalArgumentException("pageNum and pageSize must more than 0"); + } + } + + @Override + public List> getListMapBySql(String sql) throws RepositoryException { + return this.getListMapBySql(sql, (Map) MapUtil.newHashMap()); + } + + @Override + public List> getListMapBySql(String sql, Map searchMap) throws RepositoryException { + AssertUtil.notNull(sql, "getListMapBySql() sql must not be null!"); + Query query = this.entityManager.createNativeQuery(sql); + if (null != searchMap) { + Iterator var4 = searchMap.entrySet().iterator(); + + while(var4.hasNext()) { + Map.Entry entry = (Map.Entry)var4.next(); + query.setParameter((String)entry.getKey(), entry.getValue()); + } + } + + ((NativeQueryImpl)query.unwrap(NativeQueryImpl.class)).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP); + List> list = query.getResultList(); + if (this.entityManager != null) { + this.entityManager.close(); + } + + return list; + } + + public PageUtil getListMapBySql(String sql, PageUtil pageable) throws RepositoryException { + return this.getListMapBySql(sql, pageable, (Map)null); + } + + public PageUtil getListMapBySql(String sql, PageUtil pageable, Map searchMap) throws RepositoryException { + Query query = this.entityManager.createNativeQuery(sql); + if (null != searchMap) { + Iterator var5 = searchMap.entrySet().iterator(); + + while(var5.hasNext()) { + Map.Entry entry = (Map.Entry)var5.next(); + query.setParameter((String)entry.getKey(), entry.getValue()); + } + } + + int pageNum = pageable.getPageNum(); + int pageSize = pageable.getPageSize(); + if (pageNum >= 1 && pageSize >= 1) { + int currPageCount = cn.chenc.framework.jpa.util.PageUtil.offsetCurrent(pageNum, pageSize); + int totalCount = this.getCountBySql(sql, searchMap); + query.setFirstResult(currPageCount).setMaxResults(pageSize); + ((NativeQueryImpl)query.unwrap(NativeQueryImpl.class)).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP); + List> list = query.getResultList(); + PageUtil pageUtil = new PageUtil(pageNum, pageSize, totalCount); + pageUtil.setCurrPageCount(list.size()); + pageUtil.setContent(list); + return pageUtil; + } else { + throw new IllegalArgumentException("pageNum and pageSize must more than 0"); + } + } + + @Override + public Map getSingleMapBySql(String sql) throws RepositoryException { + AssertUtil.notNull(sql, "getSingleMapBySql() sql must not be null!"); + List> list = this.getListMapBySql(sql); + Map singleMap = new HashMap(); + if (list.size() > 0) { + singleMap = (Map)list.get(0); + } + + return (Map)singleMap; + } + + @Override + public int insertBySql(String sql) throws RepositoryException { + AssertUtil.notNull(sql, "insertBySql() sql must not be null!"); + Query query = this.entityManager.createNativeQuery(sql); + int count = query.executeUpdate(); + if (this.entityManager != null) { + this.entityManager.close(); + } + + return count; + } + + @Override + public int insertBySql(String sql, Map paraMap) throws RepositoryException { + AssertUtil.notNull(sql, "insertBySql() sql must not be null!"); + Query query = this.entityManager.createNativeQuery(sql); + if (null != paraMap) { + Iterator var4 = paraMap.entrySet().iterator(); + + while(var4.hasNext()) { + Map.Entry entry = (Map.Entry)var4.next(); + query.setParameter((String)entry.getKey(), entry.getValue()); + } + } + + int count = query.executeUpdate(); + if (this.entityManager != null) { + this.entityManager.close(); + } + + return count; + } + + @Override + public int updateBySql(String sql) throws RepositoryException { + AssertUtil.notNull(sql, "updateBySql() sql must not be null!"); + Query query = this.entityManager.createNativeQuery(sql); + int count = query.executeUpdate(); + if (this.entityManager != null) { + this.entityManager.close(); + } + + return count; + } + + @Override + public int deleteBySql(String sql) throws RepositoryException { + AssertUtil.notNull(sql, "deleteBySql() sql must not be null!"); + Query query = this.entityManager.createNativeQuery(sql); + int count = query.executeUpdate(); + if (this.entityManager != null) { + this.entityManager.close(); + } + + return count; + } + + @Override + public int executeBySql(String sql) throws RepositoryException { + AssertUtil.notNull(sql, "executeBySql() sql must not be null!"); + Query query = this.entityManager.createNativeQuery(sql); + int cout = query.executeUpdate(); + if (this.entityManager != null) { + this.entityManager.close(); + } + + return cout; + } + + @Override + public int executeBySql(List sqls) throws RepositoryException { + AssertUtil.notNull(sqls, "executeBySql() sql must not be null!"); + int i = 0; + + int count; + for(Iterator var3 = sqls.iterator(); var3.hasNext(); i += count) { + String sql = (String)var3.next(); + Query query = this.entityManager.createNativeQuery(sql); + count = query.executeUpdate(); + } + + if (this.entityManager != null) { + this.entityManager.close(); + } + return i; + } + + @Override + public int getCountBySql(String sql, Map searchMap) throws RepositoryException { + AssertUtil.notNull(sql, "getCountBySql() sql must not be null!"); + String countSql = SqlHelper.queryCountSQL(sql); + Query query = this.entityManager.createNativeQuery(countSql); + if (null != searchMap) { + Iterator var5 = searchMap.entrySet().iterator(); + + while(var5.hasNext()) { + Map.Entry entry = (Map.Entry)var5.next(); + query.setParameter((String)entry.getKey(), entry.getValue()); + } + } + + List totals = query.getResultList(); + if (this.entityManager != null) { + this.entityManager.close(); + } + return totals.size() > 0 ? Convert.toInt(totals.get(0)) : 0; + } + + @Override + public List> getColumnsAndTypeBySql(String sql) throws RepositoryException { + AssertUtil.notNull(sql, "getColumnsBySql() sql must not be null!"); + Connection connection = null; + ArrayList strList = new ArrayList(); + + try { + connection = ((SessionImpl)this.entityManager.unwrap(SessionImpl.class)).connection(); + ResultSet rs = connection.prepareStatement(sql).executeQuery(); + ResultSetMetaData rsmd = rs.getMetaData(); + int count = rsmd.getColumnCount(); + Map strMap = new HashMap(); + + for(int i = 0; i < count; ++i) { + Map map = new HashMap(); + String columnName = rsmd.getColumnName(i + 1).toLowerCase(); + if (strMap.get(columnName) == null) { + strMap.put(columnName, 1); + } else { + int number = (Integer)strMap.get(columnName); + columnName = columnName + number; + ++number; + strMap.put(columnName, number); + } + + map.put("columnName", columnName); + map.put("columnType", rsmd.getColumnTypeName(i + 1)); + strList.add(map); + } + } catch (Exception var15) { + throw new RepositoryException(var15.getMessage(), var15); + } finally { + this.entityManager.close(); + } + + return strList; + } + + @Override + public List getColumnsBySql(String sql) throws RepositoryException { + AssertUtil.notNull(sql, "getColumnsBySql() sql must not be null!"); + Connection connection = null; + ArrayList strList = new ArrayList(); + + try { + connection = ((SessionImpl)this.entityManager.unwrap(SessionImpl.class)).connection(); + ResultSet rs = connection.prepareStatement(sql).executeQuery(); + ResultSetMetaData rsmd = rs.getMetaData(); + int count = rsmd.getColumnCount(); + Map strMap = new HashMap(); + + for(int i = 0; i < count; ++i) { + String columnName = rsmd.getColumnName(i + 1).toLowerCase(); + if (strMap.get(columnName) == null) { + strMap.put(columnName, 1); + } else { + int number = (Integer)strMap.get(columnName); + columnName = columnName + number; + ++number; + strMap.put(columnName, number); + } + + strList.add(columnName); + } + } catch (SQLException var15) { + throw new RepositoryException("SQL配置有误"); + } catch (Exception var16) { + throw new RepositoryException(var16.getMessage(), var16); + } finally { + this.entityManager.close(); + } + + return strList; + } + + @Override + public List getColumnsByTableName(String tableName) throws RepositoryException { + AssertUtil.notNull(tableName, "getColumnsBySql() sql must not be null!"); + Connection connection = null; + ArrayList strList = new ArrayList(); + + try { + connection = ((SessionImpl)this.entityManager.unwrap(SessionImpl.class)).connection(); + ResultSet rs = connection.prepareStatement("show full columns from " + tableName).executeQuery(); + + while(rs.next()) { + strList.add(rs.getString("Field")); + } + } catch (SQLException var9) { + throw new RepositoryException("TableName配置有误"); + } catch (Exception var10) { + throw new RepositoryException(var10.getMessage(), var10); + } finally { + this.entityManager.close(); + } + + return strList; + } + +} diff --git a/secret-boot-framework-jpa/src/main/java/cn/chenc/framework/jpa/service/BaseService.java b/secret-boot-framework-jpa/src/main/java/cn/chenc/framework/jpa/service/BaseService.java new file mode 100644 index 0000000..f6c7505 --- /dev/null +++ b/secret-boot-framework-jpa/src/main/java/cn/chenc/framework/jpa/service/BaseService.java @@ -0,0 +1,95 @@ +package cn.chenc.framework.jpa.service; + +import cn.chenc.framework.jpa.exception.ServiceException; +import cn.chenc.framework.jpa.util.PageUtil; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Sort; +import org.springframework.data.jpa.domain.Specification; + +import java.io.Serializable; +import java.util.Collection; +import java.util.List; +import java.util.Map; + +/** + *  @description: TODO + *  @author secret + *  @date 2021/6/5 23:31 + * + */ +public interface BaseService { + T save(T t) throws ServiceException; + + List save(Iterable entities) throws ServiceException; + + T update(T t) throws ServiceException; + + T saveOrUpdate(ID id, T t) throws ServiceException; + + T get(ID id) throws ServiceException; + + void delete(ID id) throws ServiceException; + + void delete(T t) throws ServiceException; + + void deleteAll(Iterable entities) throws ServiceException; + + void deleteBatchByIds(Collection ids) throws ServiceException; + + boolean exists(ID id) throws ServiceException; + + long count() throws ServiceException; + + List findAll() throws ServiceException; + + List findAll(T t) throws ServiceException; + + List findAll(T t, Sort sort) throws ServiceException; + + List findAll(Sort sort) throws ServiceException; + + List findAll(Specification specification) throws ServiceException; + + Page findAll(Pageable pageable) throws ServiceException; + + Page findAll(T t, Pageable pageable) throws ServiceException; + + Page findPage(Specification specification, Pageable pageable) throws ServiceException; + + T getOneByObject(T t) throws ServiceException; + + List getListByObject(T t) throws ServiceException; + + List getListByObject(T t, Sort sort) throws ServiceException; + + Page getListByObject(T t, Pageable pageable) throws ServiceException; + + List getListBySql(String sql) throws ServiceException; + + List getListBySql(String sql, Class clzss) throws ServiceException; + + PageUtil getListBySql(String sql, PageUtil pageable) throws ServiceException; + + List> getListMapBySql(String sql) throws ServiceException; + + PageUtil getListMapBySql(String sql, PageUtil pageable) throws ServiceException; + + Map getSingleMapBySql(String sql) throws ServiceException; + + int insertBySql(String sql) throws ServiceException; + + int updateBySql(String sql) throws ServiceException; + + int deleteBySql(String sql) throws ServiceException; + + int executeBySql(String sql) throws ServiceException; + + int executeBySql(List sqls) throws ServiceException; + + int getCountBySql(String sql, Map searchMap) throws ServiceException; + + Pageable getPageable(Map params); + + PageUtil getPage(Map params); +} diff --git a/secret-boot-framework-jpa/src/main/java/cn/chenc/framework/jpa/service/BaseServiceImpl.java b/secret-boot-framework-jpa/src/main/java/cn/chenc/framework/jpa/service/BaseServiceImpl.java new file mode 100644 index 0000000..c03184a --- /dev/null +++ b/secret-boot-framework-jpa/src/main/java/cn/chenc/framework/jpa/service/BaseServiceImpl.java @@ -0,0 +1,339 @@ +package cn.chenc.framework.jpa.service; + +import cn.chenc.framework.core.text.Convert; +import cn.chenc.framework.core.util.AssertUtil; +import cn.chenc.framework.core.util.StringUtils; +import cn.chenc.framework.jpa.exception.RepositoryException; +import cn.chenc.framework.jpa.exception.ServiceException; +import cn.chenc.framework.jpa.repository.BaseRepository; +import cn.chenc.framework.jpa.util.PageUtil; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.*; +import org.springframework.data.jpa.domain.Specification; +import org.springframework.data.jpa.repository.Modifying; +import org.springframework.transaction.annotation.Transactional; + +import javax.persistence.EntityManager; +import javax.persistence.PersistenceContext; +import java.io.Serializable; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +/** + *  @description: TODO + *  @author secret + *  @date 2021/6/5 23:32 + * + */ +@Transactional +public class BaseServiceImpl ,T,ID extends Serializable> implements BaseService { + + @PersistenceContext + protected EntityManager entityManager; + @Autowired + M baseRepository; + + public BaseServiceImpl() { + } + + + public BaseRepository getBaseRepository(){ + return baseRepository; + }; + + @Override + public T save(T t) throws ServiceException { + return this.getBaseRepository().save(t); + } + + @Modifying + @Override + public T update(T t) throws ServiceException { + AssertUtil.notNull(t, "entity must not be null"); + + try { + return this.getBaseRepository().update(t); + } catch (RepositoryException var3) { + throw new ServiceException("Problem invoking method, Cause:" + var3.getMessage(), var3); + } + } + + @Override + public List save(Iterable entities) throws ServiceException { + return this.getBaseRepository().saveAll(entities); + } + + @Override + @Transactional + public T saveOrUpdate(ID id, T t) throws ServiceException { + try { + return this.getBaseRepository().saveOrUpdate(id, t); + } catch (RepositoryException var4) { + throw new ServiceException("Problem invoking method, Cause:" + var4.getMessage(), var4); + } + } + + @Override + public T get(ID id) throws ServiceException { + AssertUtil.notNull(id, "id must not be null"); + + try { + return this.getBaseRepository().get(id); + } catch (RepositoryException var3) { + throw new ServiceException("Problem invoking method, Cause:" + var3.getMessage(), var3); + } + } + + @Override + @Transactional + public void delete(ID id) throws ServiceException { + try { + this.getBaseRepository().delete(id); + } catch (RepositoryException var3) { + throw new ServiceException("Problem invoking method, Cause:" + var3.getMessage(), var3); + } + } + + @Override + @Transactional + public void delete(T t) throws ServiceException { + AssertUtil.notNull(t, "The entity must not be null!"); + this.getBaseRepository().delete(t); + } + + @Override + @Transactional( + rollbackFor = {Exception.class} + ) + public void deleteAll(Iterable entities) throws ServiceException { + this.getBaseRepository().deleteAll(entities); + } + + @Override + @Transactional( + rollbackFor = {Exception.class} + ) + public void deleteBatchByIds(Collection ids) throws ServiceException { + AssertUtil.notNull(ids, "id must not be null"); + Iterator var2 = ids.iterator(); + + while(var2.hasNext()) { + ID id = (ID) var2.next(); + this.getBaseRepository().deleteById(id); + } + + } + + @Override + public boolean exists(ID id) throws ServiceException { + AssertUtil.notNull(id, "id must not be null"); + return this.getBaseRepository().existsById(id); + } + + @Override + public long count() throws ServiceException { + return this.getBaseRepository().count(); + } + + @Override + public List findAll() throws ServiceException { + return this.getBaseRepository().findAll(); + } + + @Override + public List findAll(T t) throws ServiceException { + return this.getListByObject(t); + } + + @Override + public List findAll(T t, Sort sort) throws ServiceException { + Example example = Example.of(t); + return this.getBaseRepository().findAll(example, sort); + } + + @Override + public List findAll(Sort sort) throws ServiceException { + return this.getBaseRepository().findAll(sort); + } + + @Override + public List findAll(Specification specification) throws ServiceException { + return this.getBaseRepository().findAll(specification); + } + + @Override + public Page findAll(Pageable pageable) throws ServiceException { + return this.getBaseRepository().findAll(pageable); + } + + @Override + public Page findAll(T t, Pageable pageable) throws ServiceException { + return this.getListByObject(t, pageable); + } + + @Override + public Page findPage(Specification specification, Pageable pageable) throws ServiceException { + return this.getBaseRepository().findAll(specification, pageable); + } + + @Override + public T getOneByObject(T t) throws ServiceException { + try { + return this.getBaseRepository().getOneByObject(t); + } catch (RepositoryException var3) { + throw new ServiceException("Problem invoking method, Cause:" + var3.getMessage(), var3); + } + } + + @Override + public List getListByObject(T t) throws ServiceException { + try { + return this.getBaseRepository().getListByObject(t); + } catch (RepositoryException var3) { + throw new ServiceException("Problem invoking method, Cause:" + var3.getMessage(), var3); + } + } + + @Override + public List getListByObject(T t, Sort sort) throws ServiceException { + try { + return this.getBaseRepository().getListByObject(t, sort); + } catch (RepositoryException var4) { + throw new ServiceException("Problem invoking method, Cause:" + var4.getMessage(), var4); + } + } + + @Override + public Page getListByObject(T t, Pageable pageable) throws ServiceException { + try { + return this.getBaseRepository().getListByObject(t, pageable); + } catch (RepositoryException var4) { + throw new ServiceException("Problem invoking method, Cause:" + var4.getMessage(), var4); + } + } + + @Override + public List getListBySql(String sql) throws ServiceException { + try { + return this.getBaseRepository().getListBySql(sql); + } catch (RepositoryException var3) { + throw new ServiceException("Problem invoking method, Cause:" + var3.getMessage(), var3); + } + } + + @Override + public List getListBySql(String sql, Class clzss) throws ServiceException { + try { + return this.getBaseRepository().getListBySql(sql, clzss); + } catch (RepositoryException var4) { + throw new ServiceException("Problem invoking method, Cause:" + var4.getMessage(), var4); + } + } + + @Override + public PageUtil getListBySql(String sql, PageUtil pageable) throws ServiceException { + try { + return this.getBaseRepository().getListBySql(sql, pageable); + } catch (RepositoryException var4) { + throw new ServiceException("Problem invoking method, Cause:" + var4.getMessage(), var4); + } + } + + @Override + public List> getListMapBySql(String sql) throws ServiceException { + try { + return this.getBaseRepository().getListMapBySql(sql); + } catch (RepositoryException var3) { + throw new ServiceException("Problem invoking method, Cause:" + var3.getMessage(), var3); + } + } + + @Override + public PageUtil getListMapBySql(String sql, PageUtil pageable) throws ServiceException { + try { + return this.getBaseRepository().getListMapBySql(sql, pageable); + } catch (RepositoryException var4) { + throw new ServiceException("Problem invoking method, Cause:" + var4.getMessage(), var4); + } + } + + @Override + public Map getSingleMapBySql(String sql) throws ServiceException { + try { + return this.getBaseRepository().getSingleMapBySql(sql); + } catch (RepositoryException var3) { + throw new ServiceException("Problem invoking method, Cause:" + var3.getMessage(), var3); + } + } + + @Override + public int insertBySql(String sql) throws ServiceException { + try { + return this.getBaseRepository().insertBySql(sql); + } catch (RepositoryException var3) { + throw new ServiceException("Problem invoking method, Cause:" + var3.getMessage(), var3); + } + } + + @Override + public int updateBySql(String sql) throws ServiceException { + try { + return this.getBaseRepository().updateBySql(sql); + } catch (RepositoryException var3) { + throw new ServiceException("Problem invoking method, Cause:" + var3.getMessage(), var3); + } + } + + @Override + public int deleteBySql(String sql) throws ServiceException { + try { + return this.getBaseRepository().deleteBySql(sql); + } catch (RepositoryException var3) { + throw new ServiceException("Problem invoking method, Cause:" + var3.getMessage(), var3); + } + } + + @Override + public int executeBySql(String sql) throws ServiceException { + try { + return this.getBaseRepository().executeBySql(sql); + } catch (RepositoryException var3) { + throw new ServiceException("Problem invoking method, Cause:" + var3.getMessage(), var3); + } + } + + @Override + public int executeBySql(List sqls) throws ServiceException { + try { + return this.getBaseRepository().executeBySql(sqls); + } catch (RepositoryException var3) { + throw new ServiceException("Problem invoking method, Cause:" + var3.getMessage(), var3); + } + } + + @Override + public int getCountBySql(String sql, Map searchMap) throws ServiceException { + try { + return this.getBaseRepository().getCountBySql(sql, searchMap); + } catch (RepositoryException var4) { + throw new ServiceException("Problem invoking method, Cause:" + var4.getMessage(), var4); + } + } + + @Override + public Pageable getPageable(Map params) { + Object pageNum = StringUtils.isEmpty((String) params.get("pageNum")) ? 1 : params.get("pageNum"); + Object pageSize = StringUtils.isEmpty((String) params.get("pageSize")) ? 10 : params.get("pageSize"); + return PageRequest.of(Convert.toInt(pageNum), Convert.toInt(pageSize)); + } + + @Override + public PageUtil getPage(Map params) { + Object pageNum = StringUtils.isEmpty((String) params.get("pageNum")) ? 1 : params.get("pageNum"); + Object pageSize = StringUtils.isEmpty((String) params.get("pageSize")) ? 10 : params.get("pageSize"); + return PageUtil.of(Convert.toInt(pageNum), Convert.toInt(pageSize)); + } + +} diff --git a/secret-boot-framework-jpa/src/main/java/cn/chenc/framework/jpa/support/BaseJpaRepositoryFactoryBean.java b/secret-boot-framework-jpa/src/main/java/cn/chenc/framework/jpa/support/BaseJpaRepositoryFactoryBean.java new file mode 100644 index 0000000..ec658ac --- /dev/null +++ b/secret-boot-framework-jpa/src/main/java/cn/chenc/framework/jpa/support/BaseJpaRepositoryFactoryBean.java @@ -0,0 +1,48 @@ +package cn.chenc.framework.jpa.support; + +import cn.chenc.framework.jpa.repository.BaseRepositoryImpl; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.support.JpaEntityInformation; +import org.springframework.data.jpa.repository.support.JpaRepositoryFactory; +import org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean; +import org.springframework.data.jpa.repository.support.JpaRepositoryImplementation; +import org.springframework.data.repository.core.RepositoryInformation; +import org.springframework.data.repository.core.RepositoryMetadata; +import org.springframework.data.repository.core.support.RepositoryFactorySupport; + +import javax.persistence.EntityManager; +import java.io.Serializable; + +/** + *  @description: TODO + *  @author secret + *  @date 2021/6/5 23:14 + * + */ +public class BaseJpaRepositoryFactoryBean , T, I extends Serializable> extends JpaRepositoryFactoryBean { + public BaseJpaRepositoryFactoryBean(Class repositoryInterface) { + super(repositoryInterface); + } + + protected RepositoryFactorySupport createRepositoryFactory(EntityManager entityManager) { + return new BaseJpaRepositoryFactoryBean.BaseRepositoryFactory(entityManager); + } + + private static class BaseRepositoryFactory extends JpaRepositoryFactory { + private final EntityManager entityManager; + + public BaseRepositoryFactory(EntityManager entityManager) { + super(entityManager); + this.entityManager = entityManager; + } + + protected JpaRepositoryImplementation getTargetRepository(RepositoryInformation information, EntityManager entityManager) { + JpaEntityInformation entityInformation = this.getEntityInformation(information.getDomainType()); + return new BaseRepositoryImpl(entityInformation, information.getDomainType(), entityManager); + } + + protected Class getRepositoryBaseClass(RepositoryMetadata metadata) { + return BaseRepositoryImpl.class; + } + } +} diff --git a/secret-boot-framework-jpa/src/main/java/cn/chenc/framework/jpa/util/PageUtil.java b/secret-boot-framework-jpa/src/main/java/cn/chenc/framework/jpa/util/PageUtil.java new file mode 100644 index 0000000..cb7fda6 --- /dev/null +++ b/secret-boot-framework-jpa/src/main/java/cn/chenc/framework/jpa/util/PageUtil.java @@ -0,0 +1,132 @@ +package cn.chenc.framework.jpa.util; + +import cn.chenc.framework.core.text.Convert; +import org.springframework.data.domain.Page; + +import java.io.Serializable; +import java.util.Collections; +import java.util.List; + +/** + *  @description: TODO + *  @author secret + *  @date 2021/6/5 23:10 + * + */ +public class PageUtil implements Serializable { + private static final long serialVersionUID = 1L; + private int pageNum = 0; + private int pageSize = 20; + private boolean first = false; + private boolean last = false; + private int totalPage; + private int totalCount; + private int currPageCount; + private List content = Collections.emptyList(); + + public PageUtil(int pageNum, int pageSize) { + this.pageNum = pageNum; + this.pageSize = pageSize; + } + + public static PageUtil of(int pageNum, int pageSize) { + return new PageUtil(pageNum, pageSize); + } + + public PageUtil(int pageNum, int pageSize, int totalCount) { + this.pageNum = pageNum == 0 ? 1 : pageNum; + this.pageSize = pageSize; + this.totalCount = totalCount; + this.totalPage = totalCount % pageSize == 0 ? totalCount / pageSize : totalCount / pageSize + 1; + this.first = pageNum == 0 || pageNum == 1; + this.last = pageNum == this.totalPage; + } + + public PageUtil() { + } + + public static int offsetCurrent(int pageNum, int pageSize) { + return pageNum > 0 ? (pageNum - 1) * pageSize : 0; + } + + public static PageUtil convertPageable(Page pageable) { + PageUtil pageUtil = new PageUtil(); + pageUtil.setPageNum(pageable.getNumber() == 0 ? 1 : pageable.getNumber()); + pageUtil.setPageSize(pageable.getSize()); + pageUtil.setContent(pageable.getContent()); + pageUtil.setFirst(pageable.isFirst()); + pageUtil.setLast(pageable.isLast()); + pageUtil.setCurrPageCount(pageable.getNumberOfElements()); + pageUtil.setTotalCount(Convert.toInt(pageable.getTotalElements())); + pageUtil.setTotalPage(pageable.getTotalPages()); + return pageUtil; + } + + public static Integer getFirstResult(Integer pageNumber, Integer pageSize) { + return pageNumber > 0 ? pageSize * (pageNumber - 1) : 0; + } + + public int getPageNum() { + return this.pageNum; + } + + public int getPageSize() { + return this.pageSize; + } + + public boolean isFirst() { + return this.first; + } + + public boolean isLast() { + return this.last; + } + + public int getTotalPage() { + return this.totalPage; + } + + public int getTotalCount() { + return this.totalCount; + } + + public int getCurrPageCount() { + return this.currPageCount; + } + + public List getContent() { + return this.content; + } + + public void setPageNum(final int pageNum) { + this.pageNum = pageNum; + } + + public void setPageSize(final int pageSize) { + this.pageSize = pageSize; + } + + public void setFirst(final boolean first) { + this.first = first; + } + + public void setLast(final boolean last) { + this.last = last; + } + + public void setTotalPage(final int totalPage) { + this.totalPage = totalPage; + } + + public void setTotalCount(final int totalCount) { + this.totalCount = totalCount; + } + + public void setCurrPageCount(final int currPageCount) { + this.currPageCount = currPageCount; + } + + public void setContent(final List content) { + this.content = content; + } +} diff --git a/secret-boot-framework-jpa/src/main/java/cn/chenc/framework/jpa/util/PageableUtil.java b/secret-boot-framework-jpa/src/main/java/cn/chenc/framework/jpa/util/PageableUtil.java new file mode 100644 index 0000000..8df6a4b --- /dev/null +++ b/secret-boot-framework-jpa/src/main/java/cn/chenc/framework/jpa/util/PageableUtil.java @@ -0,0 +1,26 @@ +package cn.chenc.framework.jpa.util; + +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Sort; + +/** + *  @description: TODO + *  @author secret + *  @date 2021/6/5 23:08 + * + */ +public class PageableUtil { + + public PageableUtil() { + } + + public static Pageable getPageDesc(int page, int size, String... properties) { + return PageRequest.of(page > 0 ? page - 1 : 0, size, Sort.Direction.DESC, properties); + } + + public static Pageable getPageAsc(int page, int size, String... properties) { + return PageRequest.of(page > 0 ? page - 1 : 0, size, Sort.Direction.DESC, properties); + } + +} diff --git a/secret-boot-framework-jpa/src/main/java/cn/chenc/framework/jpa/util/SqlHelper.java b/secret-boot-framework-jpa/src/main/java/cn/chenc/framework/jpa/util/SqlHelper.java new file mode 100644 index 0000000..d923744 --- /dev/null +++ b/secret-boot-framework-jpa/src/main/java/cn/chenc/framework/jpa/util/SqlHelper.java @@ -0,0 +1,162 @@ +package cn.chenc.framework.jpa.util; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.convert.Convert; + +import java.beans.Introspector; +import java.beans.PropertyDescriptor; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.regex.Pattern; + +/** + *  @description: TODO + *  @author secret + *  @date 2021/6/5 23:21 + * + */ +public class SqlHelper { + + public SqlHelper() { + } + + public static boolean retBool(Integer result) { + return null != result && result >= 1; + } + + public static boolean delBool(Integer result) { + return null != result && result >= 0; + } + + public static String getCountSQL(String sql) { + String countSQL = "SELECT COUNT(*) AS totalRow " + sql.substring(sql.toUpperCase().indexOf("FROM")); + return replaceOrderBy(countSQL); + } + + public static String replaceOrderBy(String sql) { + return SqlHelper.Holder.ORDER_BY_PATTERN.matcher(sql).replaceAll(""); + } + + public List convert(Class clazz, List> list) { + if (CollectionUtil.isEmpty(list)) { + return null; + } else { + ArrayList result = new ArrayList(); + + try { + PropertyDescriptor[] props = Introspector.getBeanInfo(clazz).getPropertyDescriptors(); + Iterator var5 = list.iterator(); + + while(var5.hasNext()) { + Map map = (Map)var5.next(); + Object obj = clazz.newInstance(); + Iterator var8 = map.keySet().iterator(); + + while(var8.hasNext()) { + String key = (String)var8.next(); + String attrName = key.toLowerCase(); + PropertyDescriptor[] var11 = props; + int var12 = props.length; + + for(int var13 = 0; var13 < var12; ++var13) { + PropertyDescriptor prop = var11[var13]; + attrName = this.removeUnderLine(attrName); + if (attrName.equals(prop.getName())) { + Method method = prop.getWriteMethod(); + Object value = map.get(key); + if (value != null) { + value = Convert.convert(prop.getPropertyType(), value); + } + + method.invoke(obj, value); + } + } + } + + result.add(obj); + } + + return result; + } catch (Exception var17) { + throw new RuntimeException("数据转换错误"); + } + } + } + + private String removeUnderLine(String attrName) { + if (attrName.contains("_")) { + String[] names = attrName.split("_"); + String firstPart = names[0]; + String otherPart = ""; + + for(int i = 1; i < names.length; ++i) { + String word = names[i].replaceFirst(names[i].substring(0, 1), names[i].substring(0, 1).toUpperCase()); + otherPart = otherPart + word; + } + + attrName = firstPart + otherPart; + } + + return attrName; + } + + public static String getCountSql(String sql) { + int i = sql.indexOf("from"); + int j = sql.indexOf("FROM"); + int b = 0; + if (i != -1 && j != -1) { + if (i < j) { + b = i; + } else { + b = i; + } + } else if (j == -1) { + b = i; + } else if (i == -1) { + b = j; + } + + sql = "select count(*) count " + sql.substring(b); + return sql; + } + + public static String queryCountSQL(String sql) { + String countSQL = "SELECT COUNT(*) AS totalRow from (" + sql + ") totaltable"; + return countSQL; + } + + public static String buildDataSql(String sql, PageUtil pageUtil, String datasourceType) { + StringBuffer dataSql = new StringBuffer(); + if (datasourceType.toLowerCase().contains("oracle")) { + dataSql.append("SELECT"); + dataSql.append("\t*"); + dataSql.append("FROM"); + dataSql.append("\t("); + dataSql.append("\t\tSELECT"); + dataSql.append("\t\t\tmintemp.*,"); + dataSql.append("\t\t\tROWNUM num"); + dataSql.append("\t\tFROM"); + dataSql.append("\t\t\t(").append(sql).append(") mintemp"); + dataSql.append("\t\tWHERE"); + dataSql.append("\t\t\tROWNUM <= ").append(pageUtil.getPageSize() * pageUtil.getPageNum()); + dataSql.append("\t) maxtempt WHERE num >").append(pageUtil.getPageSize() * (pageUtil.getPageNum() - 1)); + } else { + dataSql.append(""); + dataSql.append(sql); + dataSql.append(" limit " + pageUtil.getPageSize() * (pageUtil.getPageNum() - 1) + "," + pageUtil.getPageSize()); + } + + return dataSql.toString(); + } + + protected static class Holder { + private static final Pattern ORDER_BY_PATTERN = Pattern.compile("order\\s+by\\s+[^,\\s]+(\\s+asc|\\s+desc)?(\\s*,\\s*[^,\\s]+(\\s+asc|\\s+desc)?)*", 10); + + protected Holder() { + } + } + +} diff --git a/secret-boot-framework-mail/pom.xml b/secret-boot-framework-mail/pom.xml new file mode 100644 index 0000000..61c081c --- /dev/null +++ b/secret-boot-framework-mail/pom.xml @@ -0,0 +1,27 @@ + + + + secret-boot-framework + com.gitee.secretopen + 1.6.0 + + 4.0.0 + + secret-boot-framework-mail + + + + com.gitee.secretopen + secret-boot-framework-core + + + + org.springframework.boot + spring-boot-starter-mail + + + + + diff --git a/secret-boot-framework-mail/src/main/java/cn/chenc/framework/mail/config/MailConfiguration.java b/secret-boot-framework-mail/src/main/java/cn/chenc/framework/mail/config/MailConfiguration.java new file mode 100644 index 0000000..6915d80 --- /dev/null +++ b/secret-boot-framework-mail/src/main/java/cn/chenc/framework/mail/config/MailConfiguration.java @@ -0,0 +1,37 @@ +package cn.chenc.framework.mail.config; + +import cn.chenc.framework.mail.core.MailTemplate; +import cn.chenc.framework.mail.core.SecretMailTemplate; +import org.springframework.boot.autoconfigure.AutoConfigureAfter; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.boot.autoconfigure.mail.MailProperties; +import org.springframework.boot.autoconfigure.mail.MailSenderAutoConfiguration; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.mail.javamail.JavaMailSender; + +import javax.annotation.Resource; + +/** + *  @description: 邮件配置 + *  @author secret + *  @date 2021/6/5 21:49 + * + */ +@Configuration +@AutoConfigureAfter(MailSenderAutoConfiguration.class) +public class MailConfiguration { + + @Resource + private JavaMailSender mailSender; + + @Resource + private MailProperties mailProperties; + + @Bean + @ConditionalOnBean({MailProperties.class, JavaMailSender.class}) + public MailTemplate mailTemplate() { + return new SecretMailTemplate(mailSender,mailProperties); + } + +} diff --git a/secret-boot-framework-mail/src/main/java/cn/chenc/framework/mail/core/MailTemplate.java b/secret-boot-framework-mail/src/main/java/cn/chenc/framework/mail/core/MailTemplate.java new file mode 100644 index 0000000..63007e2 --- /dev/null +++ b/secret-boot-framework-mail/src/main/java/cn/chenc/framework/mail/core/MailTemplate.java @@ -0,0 +1,58 @@ +package cn.chenc.framework.mail.core; + +import javax.mail.MessagingException; + +/** + *  @description: 邮件通用操作 + *  @author secret + *  @date 2021/6/5 21:54 + * + */ +public interface MailTemplate { + + /** + * 发送文本邮件 + * @param to     收件人地址 + * @param subject  邮件主题 + * @param content  邮件内容 + * @param cc     抄送地址 + */ + void sendSimpleMail(String to, String subject, String content, String... cc); + + /** + * 发送HTML邮件 + * + * @param to 收件人地址 + * @param subject 邮件主题 + * @param content 邮件内容 + * @param cc 抄送地址 + * @throws MessagingException 邮件发送异常 + */ + void sendHtmlMail(String to, String subject, String content, String... cc) throws MessagingException; + + /** + * 发送带附件的邮件 + * + * @param to 收件人地址 + * @param subject 邮件主题 + * @param content 邮件内容 + * @param filePath 附件地址 + * @param cc 抄送地址 + * @throws MessagingException 邮件发送异常 + */ + void sendAttachmentsMail(String to, String subject, String content, String filePath, String... cc) throws MessagingException; + + /** + * 发送正文中有静态资源的邮件 + * + * @param to 收件人地址 + * @param subject 邮件主题 + * @param content 邮件内容 + * @param rscPath 静态资源地址 + * @param rscId 静态资源id + * @param cc 抄送地址 + * @throws MessagingException 邮件发送异常 + */ + void sendResourceMail(String to, String subject, String content, String rscPath, String rscId, String... cc) throws MessagingException; + +} diff --git a/secret-boot-framework-mail/src/main/java/cn/chenc/framework/mail/core/SecretMailTemplate.java b/secret-boot-framework-mail/src/main/java/cn/chenc/framework/mail/core/SecretMailTemplate.java new file mode 100644 index 0000000..6d8d0d8 --- /dev/null +++ b/secret-boot-framework-mail/src/main/java/cn/chenc/framework/mail/core/SecretMailTemplate.java @@ -0,0 +1,94 @@ +package cn.chenc.framework.mail.core; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.boot.autoconfigure.mail.MailProperties; +import org.springframework.core.io.FileSystemResource; +import org.springframework.mail.SimpleMailMessage; +import org.springframework.mail.javamail.JavaMailSender; +import org.springframework.mail.javamail.MimeMessageHelper; +import org.springframework.util.ObjectUtils; + +import javax.mail.MessagingException; +import javax.mail.internet.MimeMessage; +import java.io.File; + +/** + *  @description: JavaMail邮件发送者实现类 + *  @author secret + *  @date 2021/6/5 21:55 + * + */ +@Slf4j +public class SecretMailTemplate implements MailTemplate { + + private final JavaMailSender mailSender; + + private final MailProperties mailProperties; + + public SecretMailTemplate(JavaMailSender mailSender, MailProperties mailProperties) { + this.mailSender = mailSender; + this.mailProperties = mailProperties; + } + + @Override + public void sendSimpleMail(String to, String subject, String content, String... cc) { + SimpleMailMessage message = new SimpleMailMessage(); + message.setFrom(mailProperties.getUsername()); + message.setTo(to); + message.setSubject(subject); + message.setText(content); + if (!ObjectUtils.isEmpty(cc)) { + message.setCc(cc); + } + mailSender.send(message); + } + + @Override + public void sendHtmlMail(String to, String subject, String content, String... cc) throws MessagingException { + MimeMessage message = mailSender.createMimeMessage(); + MimeMessageHelper helper = buildHelper(to, subject, content, message, cc); + mailSender.send(message); + } + + @Override + public void sendAttachmentsMail(String to, String subject, String content, String filePath, String... cc) throws MessagingException { + MimeMessage message = mailSender.createMimeMessage(); + MimeMessageHelper helper = buildHelper(to, subject, content, message, cc); + FileSystemResource file = new FileSystemResource(new File(filePath)); + String fileName = filePath.substring(filePath.lastIndexOf(File.separator)); + helper.addAttachment(fileName, file); + mailSender.send(message); + } + + @Override + public void sendResourceMail(String to, String subject, String content, String rscPath, String rscId, String... cc) throws MessagingException { + MimeMessage message = mailSender.createMimeMessage(); + MimeMessageHelper helper = buildHelper(to, subject, content, message, cc); + FileSystemResource res = new FileSystemResource(new File(rscPath)); + helper.addInline(rscId, res); + mailSender.send(message); + } + + /** + * 统一封装MimeMessageHelper + * @param to 收件人地址 + * @param subject 邮件主题 + * @param content 邮件内容 + * @param message 消息对象 + * @param cc 抄送地址 + * @return MimeMessageHelper + * @throws MessagingException 异常 + */ + private MimeMessageHelper buildHelper(String to, String subject, String content, MimeMessage message, String... cc) throws MessagingException { + MimeMessageHelper helper = new MimeMessageHelper(message, true); + helper.setFrom(mailProperties.getUsername()); + helper.setTo(to); + helper.setSubject(subject); + helper.setText(content, true); + if (!ObjectUtils.isEmpty(cc)) { + helper.setCc(cc); + } + return helper; + } + +} diff --git a/secret-boot-framework-mybatisplus/pom.xml b/secret-boot-framework-mybatisplus/pom.xml index 9032377..553d603 100644 --- a/secret-boot-framework-mybatisplus/pom.xml +++ b/secret-boot-framework-mybatisplus/pom.xml @@ -5,7 +5,7 @@ secret-boot-framework com.gitee.secretopen - 1.5.0 + 1.6.0 ${project.artifactId} 4.0.0 @@ -15,7 +15,6 @@ com.gitee.secretopen secret-boot-framework-core - ${project.parent.version} mysql diff --git a/secret-boot-framework-security/pom.xml b/secret-boot-framework-security/pom.xml index f36f2f4..46470dd 100644 --- a/secret-boot-framework-security/pom.xml +++ b/secret-boot-framework-security/pom.xml @@ -5,7 +5,7 @@ secret-boot-framework com.gitee.secretopen - 1.5.0 + 1.6.0 4.0.0 @@ -15,7 +15,6 @@ com.gitee.secretopen secret-boot-framework-core - ${project.parent.version} org.springframework.boot diff --git a/secret-boot-framework-shiro/pom.xml b/secret-boot-framework-shiro/pom.xml index 79696d4..822a501 100644 --- a/secret-boot-framework-shiro/pom.xml +++ b/secret-boot-framework-shiro/pom.xml @@ -5,7 +5,7 @@ secret-boot-framework com.gitee.secretopen - 1.5.0 + 1.6.0 4.0.0 @@ -15,7 +15,6 @@ com.gitee.secretopen secret-boot-framework-core - ${project.parent.version} org.apache.shiro -- Gitee From 5f3679291281de8a25df2af0cb696e1ec70d5900 Mon Sep 17 00:00:00 2001 From: secret <1029693356@qq.com> Date: Thu, 8 Jul 2021 17:19:06 +0800 Subject: [PATCH 02/11] =?UTF-8?q?=E6=8F=90=E4=BE=9BjwtTemplate=E6=8A=BD?= =?UTF-8?q?=E8=B1=A1=E6=8E=A5=E5=8F=A3=EF=BC=8CLoginUser=E6=8A=BD=E8=B1=A1?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- secret-boot-framework-all/pom.xml | 4 + .../core/component/AbstractJwtTemplate.java | 61 ++++++++++ .../framework/core/component/JwtTemplate.java | 37 +++--- .../core/component/RedisJwtTemplate.java | 13 +- .../core/model/AbstractLoginUser.java | 114 ++++++++++++++++++ .../chenc/framework/core/model/LoginUser.java | 25 +++- .../core/model/LoginUserDetails.java | 2 +- .../framework/demo/config/JwtConfig.java | 8 +- .../demo/controller/LoginController.java | 10 +- .../service/impl/UserDetailsServiceImpl.java | 4 +- secret-boot-framework-dependencies/pom.xml | 5 + .../SecurityJwtAuthenticationTokenFilter.java | 8 +- .../handle/LogoutSuccessHandlerImpl.java | 11 +- .../security/jwt/SecurityJwtTemplate.java | 60 +++++---- .../jwt/SecurityRedisJwtTemplate.java | 56 ++++----- .../model/SecurityAbstractLoginUser.java | 13 ++ ...{LoginUser.java => SecurityLoginUser.java} | 29 ++++- .../security/service/PermissionService.java | 14 +-- .../framework/security/util/SecurityUtil.java | 6 +- .../framework/shiro/jwt/ShiroJwtTemplate.java | 1 + .../shiro/jwt/ShiroRedisJwtTemplate.java | 1 + .../framework/shiro/model/LoginUser.java | 27 ++++- 22 files changed, 392 insertions(+), 117 deletions(-) create mode 100644 secret-boot-framework-core/src/main/java/cn/chenc/framework/core/component/AbstractJwtTemplate.java create mode 100644 secret-boot-framework-core/src/main/java/cn/chenc/framework/core/model/AbstractLoginUser.java create mode 100644 secret-boot-framework-security/src/main/java/cn/chenc/framework/security/model/SecurityAbstractLoginUser.java rename secret-boot-framework-security/src/main/java/cn/chenc/framework/security/model/{LoginUser.java => SecurityLoginUser.java} (87%) diff --git a/secret-boot-framework-all/pom.xml b/secret-boot-framework-all/pom.xml index 3196b55..3acacd2 100644 --- a/secret-boot-framework-all/pom.xml +++ b/secret-boot-framework-all/pom.xml @@ -40,6 +40,10 @@ com.gitee.secretopen secret-boot-framework-security + + com.gitee.secretopen + secret-boot-framework-mail + diff --git a/secret-boot-framework-core/src/main/java/cn/chenc/framework/core/component/AbstractJwtTemplate.java b/secret-boot-framework-core/src/main/java/cn/chenc/framework/core/component/AbstractJwtTemplate.java new file mode 100644 index 0000000..930a6a0 --- /dev/null +++ b/secret-boot-framework-core/src/main/java/cn/chenc/framework/core/component/AbstractJwtTemplate.java @@ -0,0 +1,61 @@ +package cn.chenc.framework.core.component; + +import cn.chenc.framework.core.model.AbstractLoginUser; + +import javax.servlet.http.HttpServletRequest; + +/** + *  @description: JwtTemplate抽象接口 + *  @author secret + *  @date 2021/7/1 22:48 + * + */ +public interface AbstractJwtTemplate { + + + /** + * 获取登录用户 + * @param request + * @return + */ + AbstractLoginUser getLoginUser(HttpServletRequest request); + + /** + * 设置登录用户 + * @param loginUser + */ + void setLoginUser(AbstractLoginUser loginUser); + + /** + * 删除登录用户 + * @param token + */ + void delLoginUser(String token); + + /** + * 创建token + * @param loginUser + * @return + */ + String createToken(AbstractLoginUser loginUser); + + /** + * 验证令牌有效期,相差不足20分钟,自动刷新缓存 + * @param loginUser + * @return 令牌 + */ + void verifyToken(AbstractLoginUser loginUser); + + /** + * 刷新令牌有效期 + * @param loginUser 登录信息 + */ + void refreshToken(AbstractLoginUser loginUser); + + /** + * 设置用户代理信息 + * @param loginUser 登录信息 + */ + void setUserAgent(AbstractLoginUser loginUser); + +} diff --git a/secret-boot-framework-core/src/main/java/cn/chenc/framework/core/component/JwtTemplate.java b/secret-boot-framework-core/src/main/java/cn/chenc/framework/core/component/JwtTemplate.java index 262db30..136dade 100644 --- a/secret-boot-framework-core/src/main/java/cn/chenc/framework/core/component/JwtTemplate.java +++ b/secret-boot-framework-core/src/main/java/cn/chenc/framework/core/component/JwtTemplate.java @@ -2,7 +2,7 @@ package cn.chenc.framework.core.component; import cn.chenc.framework.core.consts.CommonConst; -import cn.chenc.framework.core.model.LoginUser; +import cn.chenc.framework.core.model.AbstractLoginUser; import cn.chenc.framework.core.model.request.RequestHolder; import cn.chenc.framework.core.util.StringUtils; import cn.chenc.framework.core.util.ip.IpUtils; @@ -20,7 +20,7 @@ import java.util.Map; * jwt token验证处理 * */ -public class JwtTemplate { +public class JwtTemplate implements AbstractJwtTemplate{ // 令牌自定义标识 private String header= CommonConst.HEADER; @@ -66,7 +66,8 @@ public class JwtTemplate { * * @return 用户信息 */ - public LoginUser getLoginUser(HttpServletRequest request) + @Override + public AbstractLoginUser getLoginUser(HttpServletRequest request) { // 获取请求携带的令牌 String token = getToken(request); @@ -76,7 +77,7 @@ public class JwtTemplate { // 解析对应的权限以及用户信息 String uuid = (String) claims.get(CommonConst.LOGIN_USER_KEY); String userKey = getTokenKey(uuid); - LoginUser user = (LoginUser) RequestHolder.getSession(userKey); + AbstractLoginUser user = (AbstractLoginUser) RequestHolder.getSession(userKey); return user; } return null; @@ -85,7 +86,8 @@ public class JwtTemplate { /** * 设置用户身份信息 */ - public void setLoginUser(LoginUser loginUser) + @Override + public void setLoginUser(AbstractLoginUser loginUser) { if (StringUtils.isNotNull(loginUser) && StringUtils.isNotEmpty(loginUser.getToken())) { @@ -96,6 +98,7 @@ public class JwtTemplate { /** * 删除用户身份信息 */ + @Override public void delLoginUser(String token) { if (StringUtils.isNotEmpty(token)) { @@ -110,7 +113,8 @@ public class JwtTemplate { * @param loginUser 用户信息 * @return 令牌 */ - public String createToken(LoginUser loginUser) + @Override + public String createToken(AbstractLoginUser loginUser) { String token = IdUtils.fastUUID(); loginUser.setToken(token); @@ -128,7 +132,8 @@ public class JwtTemplate { * @param loginUser * @return 令牌 */ - public void verifyToken(LoginUser loginUser) + @Override + public void verifyToken(AbstractLoginUser loginUser) { long expireTime = loginUser.getExpireTime(); long currentTime = System.currentTimeMillis(); @@ -143,7 +148,8 @@ public class JwtTemplate { * * @param loginUser 登录信息 */ - public void refreshToken(LoginUser loginUser) { + @Override + public void refreshToken(AbstractLoginUser loginUser) { loginUser.setLoginTime(System.currentTimeMillis()); loginUser.setExpireTime(loginUser.getLoginTime() + expireTime * MILLIS_MINUTE); // 根据uuid将loginUser缓存 @@ -153,14 +159,15 @@ public class JwtTemplate { /** * 设置用户代理信息 - * * @param loginUser 登录信息 */ - public void setUserAgent(LoginUser loginUser) - { + @Override + public void setUserAgent(AbstractLoginUser loginUser) { UserAgent userAgent = UserAgent.parseUserAgentString(RequestHolder.getRequest().getHeader("User-Agent")); String ip = IpUtils.getIpAddr(RequestHolder.getRequest()); loginUser.setIpaddr(ip); + loginUser.setBrowser(userAgent.getBrowser().getName()); + loginUser.setOs(userAgent.getOperatingSystem().getName()); } /** @@ -183,8 +190,7 @@ public class JwtTemplate { * @param token 令牌 * @return 数据声明 */ - private Claims parseToken(String token) - { + private Claims parseToken(String token) { return Jwts.parser() .setSigningKey(secret) .parseClaimsJws(token) @@ -193,19 +199,16 @@ public class JwtTemplate { /** * 从令牌中获取用户名 - * * @param token 令牌 * @return 用户名 */ - public String getUsernameFromToken(String token) - { + public String getUsernameFromToken(String token) { Claims claims = parseToken(token); return claims.getSubject(); } /** * 获取请求token - * * @param request * @return token */ diff --git a/secret-boot-framework-core/src/main/java/cn/chenc/framework/core/component/RedisJwtTemplate.java b/secret-boot-framework-core/src/main/java/cn/chenc/framework/core/component/RedisJwtTemplate.java index 24f2413..d16abf9 100644 --- a/secret-boot-framework-core/src/main/java/cn/chenc/framework/core/component/RedisJwtTemplate.java +++ b/secret-boot-framework-core/src/main/java/cn/chenc/framework/core/component/RedisJwtTemplate.java @@ -1,6 +1,7 @@ package cn.chenc.framework.core.component; import cn.chenc.framework.core.consts.CommonConst; +import cn.chenc.framework.core.model.AbstractLoginUser; import cn.chenc.framework.core.model.LoginUser; import cn.chenc.framework.core.model.request.RequestHolder; import cn.chenc.framework.core.util.StringUtils; @@ -42,7 +43,7 @@ public class RedisJwtTemplate extends JwtTemplate { * @return 用户信息 */ @Override - public LoginUser getLoginUser(HttpServletRequest request) { + public AbstractLoginUser getLoginUser(HttpServletRequest request) { // 获取请求携带的令牌 String token = getToken(request); if (StringUtils.isNotEmpty(token)) { @@ -60,7 +61,7 @@ public class RedisJwtTemplate extends JwtTemplate { * 设置用户身份信息 */ @Override - public void setLoginUser(LoginUser loginUser) { + public void setLoginUser(AbstractLoginUser loginUser) { if (StringUtils.isNotNull(loginUser) && StringUtils.isNotEmpty(loginUser.getToken())) { refreshToken(loginUser); } @@ -84,7 +85,7 @@ public class RedisJwtTemplate extends JwtTemplate { * @return 令牌 */ @Override - public String createToken(LoginUser loginUser) { + public String createToken(AbstractLoginUser loginUser) { String token = IdUtils.fastUUID(); loginUser.setToken(token); setUserAgent(loginUser); @@ -101,7 +102,7 @@ public class RedisJwtTemplate extends JwtTemplate { * @param loginUser 登录信息 */ @Override - public void setUserAgent(LoginUser loginUser) { + public void setUserAgent(AbstractLoginUser loginUser) { UserAgent userAgent = UserAgent.parseUserAgentString(RequestHolder.getRequest().getHeader("User-Agent")); String ip = IpUtils.getIpAddr(RequestHolder.getRequest()); loginUser.setIpaddr(ip); @@ -116,7 +117,7 @@ public class RedisJwtTemplate extends JwtTemplate { * @param loginUser 登录信息 */ @Override - public void refreshToken(LoginUser loginUser) { + public void refreshToken(AbstractLoginUser loginUser) { loginUser.setLoginTime(System.currentTimeMillis()); loginUser.setExpireTime(loginUser.getLoginTime() + getExpireTime() * MILLIS_MINUTE); // 根据uuid将loginUser缓存 @@ -131,7 +132,7 @@ public class RedisJwtTemplate extends JwtTemplate { * @return 令牌 */ @Override - public void verifyToken(LoginUser loginUser) { + public void verifyToken(AbstractLoginUser loginUser) { long expireTime = loginUser.getExpireTime(); long currentTime = System.currentTimeMillis(); if (expireTime - currentTime <= MILLIS_MINUTE_TEN) diff --git a/secret-boot-framework-core/src/main/java/cn/chenc/framework/core/model/AbstractLoginUser.java b/secret-boot-framework-core/src/main/java/cn/chenc/framework/core/model/AbstractLoginUser.java new file mode 100644 index 0000000..ea9bf8c --- /dev/null +++ b/secret-boot-framework-core/src/main/java/cn/chenc/framework/core/model/AbstractLoginUser.java @@ -0,0 +1,114 @@ +package cn.chenc.framework.core.model; + +import java.util.Set; + +/** + *  @description: LoginUser抽象接口 + *  @author secret + *  @date 2021/7/1 22:25 + * + */ +public interface AbstractLoginUser { + + /** + * 获取token + * @return + */ + String getToken(); + + /** + * 设置token + * @param token + */ + void setToken(String token); + + /** + * 获取用户名 + * @return + */ + String getUsername(); + + /** + * 获取登录时间 + * @return + */ + Long getLoginTime(); + + /** + * 设置登录时间 + * @param loginTime + */ + void setLoginTime(Long loginTime); + + /** + * 获取过期时间 + * @return + */ + Long getExpireTime(); + + /** + * 设置过期时间 + * @param expireTime + */ + void setExpireTime(Long expireTime); + + /** + * 获取ip地址 + * @return + */ + String getIpaddr(); + + /** + * 设置ip地址 + * @param ipaddr + */ + void setIpaddr(String ipaddr); + + /** + * 获取登录地址 + * @return + */ + String getLoginLocation(); + + /** + * 设置登录地址 + * @param loginLocation + */ + void setLoginLocation(String loginLocation); + + /** + * 获取浏览器 + * @return + */ + String getBrowser(); + + /** + * 设置浏览器 + * @param browser + */ + void setBrowser(String browser); + + /** + * 获取操作系统 + * @return + */ + String getOs(); + + /** + * 设置操作系统 + * @param os + */ + void setOs(String os); + + Set getPermissions(); + + void setPermissions(Set permissions); + + Set getRoles(); + + void setRoles(Set roles); + + LoginUserDetails getUser(); + + void setUser(LoginUserDetails user); +} diff --git a/secret-boot-framework-core/src/main/java/cn/chenc/framework/core/model/LoginUser.java b/secret-boot-framework-core/src/main/java/cn/chenc/framework/core/model/LoginUser.java index 3b2c27f..1663925 100644 --- a/secret-boot-framework-core/src/main/java/cn/chenc/framework/core/model/LoginUser.java +++ b/secret-boot-framework-core/src/main/java/cn/chenc/framework/core/model/LoginUser.java @@ -11,7 +11,7 @@ import java.util.Set; *  @date 2021/4/8 10:01 * */ -public class LoginUser implements Serializable { +public class LoginUser implements AbstractLoginUser,Serializable { private static final long serialVersionUID = 1L; @@ -75,11 +75,13 @@ public class LoginUser implements Serializable { } + @Override public String getToken() { return token; } + @Override public void setToken(String token) { this.token = token; @@ -95,6 +97,7 @@ public class LoginUser implements Serializable { this.userid = userid; } + @Override public String getUsername(){ return user.getUsername(); } @@ -103,83 +106,101 @@ public class LoginUser implements Serializable { return user.getPassword(); } + @Override public Long getLoginTime() { return loginTime; } + @Override public void setLoginTime(Long loginTime) { this.loginTime = loginTime; } + @Override public Long getExpireTime() { return expireTime; } + @Override public void setExpireTime(Long expireTime) { this.expireTime = expireTime; } + @Override public String getIpaddr() { return ipaddr; } + @Override public void setIpaddr(String ipaddr) { this.ipaddr = ipaddr; } + @Override public String getLoginLocation() { return loginLocation; } + @Override public void setLoginLocation(String loginLocation) { this.loginLocation = loginLocation; } + @Override public String getBrowser() { return browser; } + @Override public void setBrowser(String browser) { this.browser = browser; } + @Override public String getOs() { return os; } + @Override public void setOs(String os) { this.os = os; } + @Override public Set getPermissions() { return permissions; } + @Override public void setPermissions(Set permissions) { this.permissions = permissions; } + @Override public Set getRoles() { return roles; } + @Override public void setRoles(Set roles) { this.roles = roles; } - public Object getUser() + @Override + public LoginUserDetails getUser() { return user; } + @Override public void setUser(LoginUserDetails user) { this.user = user; diff --git a/secret-boot-framework-core/src/main/java/cn/chenc/framework/core/model/LoginUserDetails.java b/secret-boot-framework-core/src/main/java/cn/chenc/framework/core/model/LoginUserDetails.java index fd92fa6..cd3970b 100644 --- a/secret-boot-framework-core/src/main/java/cn/chenc/framework/core/model/LoginUserDetails.java +++ b/secret-boot-framework-core/src/main/java/cn/chenc/framework/core/model/LoginUserDetails.java @@ -1,7 +1,7 @@ package cn.chenc.framework.core.model; /** - *  @description: 通用登录用户接口 + *  @description: 通用登录用户信息接口 *  @author secret *  @date 2021/4/19 10:45 * diff --git a/secret-boot-framework-demo/security-demo/src/main/java/cn/chenc/framework/demo/config/JwtConfig.java b/secret-boot-framework-demo/security-demo/src/main/java/cn/chenc/framework/demo/config/JwtConfig.java index 806d33c..36134f2 100644 --- a/secret-boot-framework-demo/security-demo/src/main/java/cn/chenc/framework/demo/config/JwtConfig.java +++ b/secret-boot-framework-demo/security-demo/src/main/java/cn/chenc/framework/demo/config/JwtConfig.java @@ -1,7 +1,7 @@ package cn.chenc.framework.demo.config; -import cn.chenc.framework.security.jwt.SecurityJwtTemplate; -import cn.chenc.framework.security.jwt.SecurityRedisJwtTemplate; +import cn.chenc.framework.core.component.AbstractJwtTemplate; +import cn.chenc.framework.core.component.RedisJwtTemplate; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -15,8 +15,8 @@ import org.springframework.context.annotation.Configuration; public class JwtConfig { @Bean - public SecurityJwtTemplate securityJwtTemplate(){ - SecurityRedisJwtTemplate securityRedisJwtTemplate = new SecurityRedisJwtTemplate(); + public AbstractJwtTemplate securityJwtTemplate(){ + AbstractJwtTemplate securityRedisJwtTemplate = new RedisJwtTemplate(); return securityRedisJwtTemplate; } diff --git a/secret-boot-framework-demo/security-demo/src/main/java/cn/chenc/framework/demo/controller/LoginController.java b/secret-boot-framework-demo/security-demo/src/main/java/cn/chenc/framework/demo/controller/LoginController.java index 4703a18..d925511 100644 --- a/secret-boot-framework-demo/security-demo/src/main/java/cn/chenc/framework/demo/controller/LoginController.java +++ b/secret-boot-framework-demo/security-demo/src/main/java/cn/chenc/framework/demo/controller/LoginController.java @@ -7,7 +7,7 @@ import cn.chenc.framework.core.model.response.AjaxResult; import cn.chenc.framework.core.model.response.CustomCode; import cn.chenc.framework.demo.entity.User; import cn.chenc.framework.security.jwt.SecurityJwtTemplate; -import cn.chenc.framework.security.model.LoginUser; +import cn.chenc.framework.security.model.SecurityLoginUser; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.authentication.AuthenticationManager; @@ -46,8 +46,8 @@ public class LoginController { throw new CustomException(CustomCode.error(e.getMessage())); } //登录成功 - LoginUser loginUser = (LoginUser) authentication.getPrincipal(); - String token=securityJwtTemplate.createToken(loginUser); + SecurityLoginUser securityLoginUser = (SecurityLoginUser) authentication.getPrincipal(); + String token=securityJwtTemplate.createToken(securityLoginUser); AjaxResult ajax=AjaxResult.success(); ajax.put("token",token); return ajax; @@ -57,8 +57,8 @@ public class LoginController { @ResponseBody @PostMapping("getInfo") public AjaxResult getInfo(@RequestBody User user){ - LoginUser loginUser=securityJwtTemplate.getLoginUser(RequestHolder.getRequest()); - return AjaxResult.success(loginUser); + SecurityLoginUser securityLoginUser = (SecurityLoginUser) securityJwtTemplate.getLoginUser(RequestHolder.getRequest()); + return AjaxResult.success(securityLoginUser); } @PreAuthorize("@ss.hasPermi('test')") diff --git a/secret-boot-framework-demo/security-demo/src/main/java/cn/chenc/framework/demo/service/impl/UserDetailsServiceImpl.java b/secret-boot-framework-demo/security-demo/src/main/java/cn/chenc/framework/demo/service/impl/UserDetailsServiceImpl.java index 0c5f1da..d2e2d7f 100644 --- a/secret-boot-framework-demo/security-demo/src/main/java/cn/chenc/framework/demo/service/impl/UserDetailsServiceImpl.java +++ b/secret-boot-framework-demo/security-demo/src/main/java/cn/chenc/framework/demo/service/impl/UserDetailsServiceImpl.java @@ -1,7 +1,7 @@ package cn.chenc.framework.demo.service.impl; import cn.chenc.framework.demo.entity.User; -import cn.chenc.framework.security.model.LoginUser; +import cn.chenc.framework.security.model.SecurityLoginUser; import cn.chenc.framework.security.util.SecurityUtil; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsService; @@ -27,7 +27,7 @@ public class UserDetailsServiceImpl implements UserDetailsService { } public UserDetails createLoginUser(User user) { - return new LoginUser(user, null); + return new SecurityLoginUser(user, null); } } diff --git a/secret-boot-framework-dependencies/pom.xml b/secret-boot-framework-dependencies/pom.xml index 50d4ac2..68bbb89 100644 --- a/secret-boot-framework-dependencies/pom.xml +++ b/secret-boot-framework-dependencies/pom.xml @@ -92,6 +92,11 @@ secret-boot-framework-mybatisplus ${secret-boot.version} + + ${project.groupId} + secret-boot-framework-mail + ${secret-boot.version} + ${project.groupId} secret-boot-framework-security diff --git a/secret-boot-framework-security/src/main/java/cn/chenc/framework/security/filter/SecurityJwtAuthenticationTokenFilter.java b/secret-boot-framework-security/src/main/java/cn/chenc/framework/security/filter/SecurityJwtAuthenticationTokenFilter.java index e1428e0..58b73f4 100644 --- a/secret-boot-framework-security/src/main/java/cn/chenc/framework/security/filter/SecurityJwtAuthenticationTokenFilter.java +++ b/secret-boot-framework-security/src/main/java/cn/chenc/framework/security/filter/SecurityJwtAuthenticationTokenFilter.java @@ -1,8 +1,8 @@ package cn.chenc.framework.security.filter; +import cn.chenc.framework.core.component.AbstractJwtTemplate; import cn.chenc.framework.core.util.StringUtils; -import cn.chenc.framework.security.jwt.SecurityJwtTemplate; -import cn.chenc.framework.security.model.LoginUser; +import cn.chenc.framework.security.model.SecurityAbstractLoginUser; import cn.chenc.framework.security.util.SecurityUtil; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; @@ -23,12 +23,12 @@ import java.io.IOException; public class SecurityJwtAuthenticationTokenFilter extends OncePerRequestFilter { @Autowired - private SecurityJwtTemplate securityJwtTemplate; + private AbstractJwtTemplate securityJwtTemplate; @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException { - LoginUser loginUser = securityJwtTemplate.getLoginUser(request); + SecurityAbstractLoginUser loginUser = (SecurityAbstractLoginUser) securityJwtTemplate.getLoginUser(request); if (StringUtils.isNotNull(loginUser) && StringUtils.isNull(SecurityUtil.getAuthentication())) { securityJwtTemplate.verifyToken(loginUser); UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(loginUser, null, loginUser.getAuthorities()); diff --git a/secret-boot-framework-security/src/main/java/cn/chenc/framework/security/handle/LogoutSuccessHandlerImpl.java b/secret-boot-framework-security/src/main/java/cn/chenc/framework/security/handle/LogoutSuccessHandlerImpl.java index 381fbc3..f781bc9 100644 --- a/secret-boot-framework-security/src/main/java/cn/chenc/framework/security/handle/LogoutSuccessHandlerImpl.java +++ b/secret-boot-framework-security/src/main/java/cn/chenc/framework/security/handle/LogoutSuccessHandlerImpl.java @@ -1,12 +1,12 @@ package cn.chenc.framework.security.handle; +import cn.chenc.framework.core.component.AbstractJwtTemplate; import cn.chenc.framework.core.consts.HttpStatus; +import cn.chenc.framework.core.model.AbstractLoginUser; import cn.chenc.framework.core.model.request.RequestHolder; import cn.chenc.framework.core.model.response.AjaxResult; import cn.chenc.framework.core.util.JsonUtils; import cn.chenc.framework.core.util.StringUtils; -import cn.chenc.framework.security.jwt.SecurityJwtTemplate; -import cn.chenc.framework.security.model.LoginUser; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -30,7 +30,7 @@ public class LogoutSuccessHandlerImpl implements LogoutSuccessHandler { private static final Logger LOGGER = LoggerFactory.getLogger(LogoutSuccessHandlerImpl.class); @Autowired - private SecurityJwtTemplate tokenService; + private AbstractJwtTemplate tokenService; /** * 退出处理 @@ -39,9 +39,8 @@ public class LogoutSuccessHandlerImpl implements LogoutSuccessHandler { */ @Override public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) - throws IOException, ServletException - { - LoginUser loginUser = tokenService.getLoginUser(request); + throws IOException, ServletException { + AbstractLoginUser loginUser = tokenService.getLoginUser(request); if (StringUtils.isNotNull(loginUser)) { String userName = loginUser.getUsername(); // 删除用户缓存记录 diff --git a/secret-boot-framework-security/src/main/java/cn/chenc/framework/security/jwt/SecurityJwtTemplate.java b/secret-boot-framework-security/src/main/java/cn/chenc/framework/security/jwt/SecurityJwtTemplate.java index bcd4983..93a6040 100644 --- a/secret-boot-framework-security/src/main/java/cn/chenc/framework/security/jwt/SecurityJwtTemplate.java +++ b/secret-boot-framework-security/src/main/java/cn/chenc/framework/security/jwt/SecurityJwtTemplate.java @@ -1,12 +1,14 @@ package cn.chenc.framework.security.jwt; +import cn.chenc.framework.core.component.AbstractJwtTemplate; import cn.chenc.framework.core.consts.CommonConst; +import cn.chenc.framework.core.model.AbstractLoginUser; import cn.chenc.framework.core.model.request.RequestHolder; import cn.chenc.framework.core.util.StringUtils; import cn.chenc.framework.core.util.ip.IpUtils; import cn.chenc.framework.core.util.uuid.IdUtils; -import cn.chenc.framework.security.model.LoginUser; +import cn.chenc.framework.security.model.SecurityLoginUser; import eu.bitwalker.useragentutils.UserAgent; import io.jsonwebtoken.Claims; import io.jsonwebtoken.Jwts; @@ -20,7 +22,8 @@ import java.util.Map; * jwt token验证处理 * */ -public class SecurityJwtTemplate { +@Deprecated +public class SecurityJwtTemplate implements AbstractJwtTemplate { // 令牌自定义标识 private String header= CommonConst.HEADER; @@ -66,7 +69,8 @@ public class SecurityJwtTemplate { * * @return 用户信息 */ - public LoginUser getLoginUser(HttpServletRequest request) + @Override + public AbstractLoginUser getLoginUser(HttpServletRequest request) { // 获取请求携带的令牌 String token = getToken(request); @@ -76,7 +80,7 @@ public class SecurityJwtTemplate { // 解析对应的权限以及用户信息 String uuid = (String) claims.get(CommonConst.LOGIN_USER_KEY); String userKey = getTokenKey(uuid); - LoginUser user = (LoginUser) RequestHolder.getSession(userKey); + SecurityLoginUser user = (SecurityLoginUser) RequestHolder.getSession(userKey); return user; } return null; @@ -85,17 +89,19 @@ public class SecurityJwtTemplate { /** * 设置用户身份信息 */ - public void setLoginUser(LoginUser loginUser) + @Override + public void setLoginUser(AbstractLoginUser securityLoginUser) { - if (StringUtils.isNotNull(loginUser) && StringUtils.isNotEmpty(loginUser.getToken())) + if (StringUtils.isNotNull(securityLoginUser) && StringUtils.isNotEmpty(securityLoginUser.getToken())) { - refreshToken(loginUser); + refreshToken(securityLoginUser); } } /** * 删除用户身份信息 */ + @Override public void delLoginUser(String token) { if (StringUtils.isNotEmpty(token)) { @@ -107,15 +113,16 @@ public class SecurityJwtTemplate { /** * 创建令牌 * - * @param loginUser 用户信息 + * @param securityLoginUser 用户信息 * @return 令牌 */ - public String createToken(LoginUser loginUser) + @Override + public String createToken(AbstractLoginUser securityLoginUser) { String token = IdUtils.fastUUID(); - loginUser.setToken(token); - setUserAgent(loginUser); - refreshToken(loginUser); + securityLoginUser.setToken(token); + setUserAgent(securityLoginUser); + refreshToken(securityLoginUser); Map claims = new HashMap<>(); claims.put(CommonConst.LOGIN_USER_KEY, token); @@ -125,42 +132,45 @@ public class SecurityJwtTemplate { /** * 验证令牌有效期,相差不足20分钟,自动刷新缓存 * - * @param loginUser + * @param securityLoginUser * @return 令牌 */ - public void verifyToken(LoginUser loginUser) + @Override + public void verifyToken(AbstractLoginUser securityLoginUser) { - long expireTime = loginUser.getExpireTime(); + long expireTime = securityLoginUser.getExpireTime(); long currentTime = System.currentTimeMillis(); if (expireTime - currentTime <= MILLIS_MINUTE_TEN) { - refreshToken(loginUser); + refreshToken(securityLoginUser); } } /** * 刷新令牌有效期 * - * @param loginUser 登录信息 + * @param securityLoginUser 登录信息 */ - public void refreshToken(LoginUser loginUser) { - loginUser.setLoginTime(System.currentTimeMillis()); - loginUser.setExpireTime(loginUser.getLoginTime() + expireTime * MILLIS_MINUTE); + @Override + public void refreshToken(AbstractLoginUser securityLoginUser) { + securityLoginUser.setLoginTime(System.currentTimeMillis()); + securityLoginUser.setExpireTime(securityLoginUser.getLoginTime() + expireTime * MILLIS_MINUTE); // 根据uuid将loginUser缓存 - String userKey = getTokenKey(loginUser.getToken()); - RequestHolder.setSession(userKey,loginUser); + String userKey = getTokenKey(securityLoginUser.getToken()); + RequestHolder.setSession(userKey, securityLoginUser); } /** * 设置用户代理信息 * - * @param loginUser 登录信息 + * @param securityLoginUser 登录信息 */ - public void setUserAgent(LoginUser loginUser) + @Override + public void setUserAgent(AbstractLoginUser securityLoginUser) { UserAgent userAgent = UserAgent.parseUserAgentString(RequestHolder.getRequest().getHeader("User-Agent")); String ip = IpUtils.getIpAddr(RequestHolder.getRequest()); - loginUser.setIpaddr(ip); + securityLoginUser.setIpaddr(ip); } /** diff --git a/secret-boot-framework-security/src/main/java/cn/chenc/framework/security/jwt/SecurityRedisJwtTemplate.java b/secret-boot-framework-security/src/main/java/cn/chenc/framework/security/jwt/SecurityRedisJwtTemplate.java index ad2bc22..103f5b6 100644 --- a/secret-boot-framework-security/src/main/java/cn/chenc/framework/security/jwt/SecurityRedisJwtTemplate.java +++ b/secret-boot-framework-security/src/main/java/cn/chenc/framework/security/jwt/SecurityRedisJwtTemplate.java @@ -1,12 +1,13 @@ package cn.chenc.framework.security.jwt; import cn.chenc.framework.core.consts.CommonConst; +import cn.chenc.framework.core.model.AbstractLoginUser; import cn.chenc.framework.core.model.request.RequestHolder; import cn.chenc.framework.core.util.StringUtils; import cn.chenc.framework.core.util.ip.AddressUtils; import cn.chenc.framework.core.util.ip.IpUtils; import cn.chenc.framework.core.util.uuid.IdUtils; -import cn.chenc.framework.security.model.LoginUser; +import cn.chenc.framework.security.model.SecurityLoginUser; import eu.bitwalker.useragentutils.UserAgent; import io.jsonwebtoken.Claims; import io.jsonwebtoken.Jwts; @@ -25,6 +26,7 @@ import java.util.concurrent.TimeUnit; *  @date 2021/4/6 15:38 * */ +@Deprecated public class SecurityRedisJwtTemplate extends SecurityJwtTemplate { @Autowired @@ -42,7 +44,7 @@ public class SecurityRedisJwtTemplate extends SecurityJwtTemplate { * @return 用户信息 */ @Override - public LoginUser getLoginUser(HttpServletRequest request) { + public SecurityLoginUser getLoginUser(HttpServletRequest request) { // 获取请求携带的令牌 String token = getToken(request); if (StringUtils.isNotEmpty(token)) { @@ -50,7 +52,7 @@ public class SecurityRedisJwtTemplate extends SecurityJwtTemplate { // 解析对应的权限以及用户信息 String uuid = (String) claims.get(CommonConst.LOGIN_USER_KEY); String userKey = getTokenKey(uuid); - LoginUser user = (LoginUser) redisTemplate.opsForValue().get(userKey); + SecurityLoginUser user = (SecurityLoginUser) redisTemplate.opsForValue().get(userKey); return user; } return null; @@ -60,9 +62,9 @@ public class SecurityRedisJwtTemplate extends SecurityJwtTemplate { * 设置用户身份信息 */ @Override - public void setLoginUser(LoginUser loginUser) { - if (StringUtils.isNotNull(loginUser) && StringUtils.isNotEmpty(loginUser.getToken())) { - refreshToken(loginUser); + public void setLoginUser(AbstractLoginUser securityLoginUser) { + if (StringUtils.isNotNull(securityLoginUser) && StringUtils.isNotEmpty(securityLoginUser.getToken())) { + refreshToken(securityLoginUser); } } @@ -80,15 +82,15 @@ public class SecurityRedisJwtTemplate extends SecurityJwtTemplate { /** * 创建令牌 * - * @param loginUser 用户信息 + * @param securityLoginUser 用户信息 * @return 令牌 */ @Override - public String createToken(LoginUser loginUser) { + public String createToken(AbstractLoginUser securityLoginUser) { String token = IdUtils.fastUUID(); - loginUser.setToken(token); - setUserAgent(loginUser); - refreshToken(loginUser); + securityLoginUser.setToken(token); + setUserAgent(securityLoginUser); + refreshToken(securityLoginUser); Map claims = new HashMap<>(); claims.put(CommonConst.LOGIN_USER_KEY, token); @@ -98,45 +100,45 @@ public class SecurityRedisJwtTemplate extends SecurityJwtTemplate { /** * 设置用户代理信息 * - * @param loginUser 登录信息 + * @param securityLoginUser 登录信息 */ @Override - public void setUserAgent(LoginUser loginUser) { + public void setUserAgent(AbstractLoginUser securityLoginUser) { UserAgent userAgent = UserAgent.parseUserAgentString(RequestHolder.getRequest().getHeader("User-Agent")); String ip = IpUtils.getIpAddr(RequestHolder.getRequest()); - loginUser.setIpaddr(ip); - loginUser.setLoginLocation(AddressUtils.getRealAddressByIP(ip)); - loginUser.setBrowser(userAgent.getBrowser().getName()); - loginUser.setOs(userAgent.getOperatingSystem().getName()); + securityLoginUser.setIpaddr(ip); + securityLoginUser.setLoginLocation(AddressUtils.getRealAddressByIP(ip)); + securityLoginUser.setBrowser(userAgent.getBrowser().getName()); + securityLoginUser.setOs(userAgent.getOperatingSystem().getName()); } /** * 刷新令牌有效期 * - * @param loginUser 登录信息 + * @param securityLoginUser 登录信息 */ @Override - public void refreshToken(LoginUser loginUser) { - loginUser.setLoginTime(System.currentTimeMillis()); - loginUser.setExpireTime(loginUser.getLoginTime() + getExpireTime() * MILLIS_MINUTE); + public void refreshToken(AbstractLoginUser securityLoginUser) { + securityLoginUser.setLoginTime(System.currentTimeMillis()); + securityLoginUser.setExpireTime(securityLoginUser.getLoginTime() + getExpireTime() * MILLIS_MINUTE); // 根据uuid将loginUser缓存 - String userKey = getTokenKey(loginUser.getToken()); - redisTemplate.opsForValue().set(userKey, loginUser, getExpireTime(), TimeUnit.MINUTES); + String userKey = getTokenKey(securityLoginUser.getToken()); + redisTemplate.opsForValue().set(userKey, securityLoginUser, getExpireTime(), TimeUnit.MINUTES); } /** * 验证令牌有效期,相差不足20分钟,自动刷新缓存 * - * @param loginUser + * @param securityLoginUser * @return 令牌 */ @Override - public void verifyToken(LoginUser loginUser) { - long expireTime = loginUser.getExpireTime(); + public void verifyToken(AbstractLoginUser securityLoginUser) { + long expireTime = securityLoginUser.getExpireTime(); long currentTime = System.currentTimeMillis(); if (expireTime - currentTime <= MILLIS_MINUTE_TEN) { - refreshToken(loginUser); + refreshToken(securityLoginUser); } } diff --git a/secret-boot-framework-security/src/main/java/cn/chenc/framework/security/model/SecurityAbstractLoginUser.java b/secret-boot-framework-security/src/main/java/cn/chenc/framework/security/model/SecurityAbstractLoginUser.java new file mode 100644 index 0000000..4f2808b --- /dev/null +++ b/secret-boot-framework-security/src/main/java/cn/chenc/framework/security/model/SecurityAbstractLoginUser.java @@ -0,0 +1,13 @@ +package cn.chenc.framework.security.model; + +import cn.chenc.framework.core.model.AbstractLoginUser; +import org.springframework.security.core.userdetails.UserDetails; + +/** + *  @description: 继承 AbstractLoginUser ,UserDetails + *  @author secret + *  @date 2021/7/8 16:02 + * + */ +public interface SecurityAbstractLoginUser extends AbstractLoginUser, UserDetails { +} diff --git a/secret-boot-framework-security/src/main/java/cn/chenc/framework/security/model/LoginUser.java b/secret-boot-framework-security/src/main/java/cn/chenc/framework/security/model/SecurityLoginUser.java similarity index 87% rename from secret-boot-framework-security/src/main/java/cn/chenc/framework/security/model/LoginUser.java rename to secret-boot-framework-security/src/main/java/cn/chenc/framework/security/model/SecurityLoginUser.java index 0228401..d70bfac 100644 --- a/secret-boot-framework-security/src/main/java/cn/chenc/framework/security/model/LoginUser.java +++ b/secret-boot-framework-security/src/main/java/cn/chenc/framework/security/model/SecurityLoginUser.java @@ -3,7 +3,6 @@ package cn.chenc.framework.security.model; import cn.chenc.framework.core.model.LoginUserDetails; import com.fasterxml.jackson.annotation.JsonIgnore; import org.springframework.security.core.GrantedAuthority; -import org.springframework.security.core.userdetails.UserDetails; import java.io.Serializable; import java.util.Collection; @@ -15,7 +14,7 @@ import java.util.Set; *  @date 2021/4/1 14:40 * */ -public class LoginUser implements UserDetails, Serializable { +public class SecurityLoginUser implements SecurityAbstractLoginUser, Serializable { private static final long serialVersionUID = 1L; @@ -71,25 +70,27 @@ public class LoginUser implements UserDetails, Serializable { private Set authorities; + @Override public String getToken() { return token; } + @Override public void setToken(String token) { this.token = token; } - public LoginUser() { + public SecurityLoginUser() { } - public LoginUser(LoginUserDetails user, Set permissions) { + public SecurityLoginUser(LoginUserDetails user, Set permissions) { this.user = user; this.permissions = permissions; } - public LoginUser(LoginUserDetails user, Set permissions, Set authorities) { + public SecurityLoginUser(LoginUserDetails user, Set permissions, Set authorities) { this.user = user; this.permissions = permissions; this.authorities = authorities; @@ -152,88 +153,106 @@ public class LoginUser implements UserDetails, Serializable { return true; } + @Override public Long getLoginTime() { return loginTime; } + @Override public void setLoginTime(Long loginTime) { this.loginTime = loginTime; } + @Override public String getIpaddr() { return ipaddr; } + @Override public void setIpaddr(String ipaddr) { this.ipaddr = ipaddr; } + @Override public String getLoginLocation() { return loginLocation; } + @Override public void setLoginLocation(String loginLocation) { this.loginLocation = loginLocation; } + @Override public String getBrowser() { return browser; } + @Override public void setBrowser(String browser) { this.browser = browser; } + @Override public String getOs() { return os; } + @Override public void setOs(String os) { this.os = os; } + @Override public Long getExpireTime() { return expireTime; } + @Override public void setExpireTime(Long expireTime) { this.expireTime = expireTime; } + @Override public Set getRoles() { return roles; } + @Override public void setRoles(Set roles) { this.roles = roles; } + @Override public Set getPermissions() { return permissions; } + @Override public void setPermissions(Set permissions) { this.permissions = permissions; } + @Override public LoginUserDetails getUser() { return user; } + @Override public void setUser(LoginUserDetails user) { this.user = user; } diff --git a/secret-boot-framework-security/src/main/java/cn/chenc/framework/security/service/PermissionService.java b/secret-boot-framework-security/src/main/java/cn/chenc/framework/security/service/PermissionService.java index 38abb1e..3bd73d8 100644 --- a/secret-boot-framework-security/src/main/java/cn/chenc/framework/security/service/PermissionService.java +++ b/secret-boot-framework-security/src/main/java/cn/chenc/framework/security/service/PermissionService.java @@ -1,10 +1,10 @@ package cn.chenc.framework.security.service; +import cn.chenc.framework.core.component.AbstractJwtTemplate; +import cn.chenc.framework.core.model.AbstractLoginUser; import cn.chenc.framework.core.model.request.RequestHolder; import cn.chenc.framework.core.util.StringUtils; -import cn.chenc.framework.security.jwt.SecurityJwtTemplate; -import cn.chenc.framework.security.model.LoginUser; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.util.CollectionUtils; @@ -29,7 +29,7 @@ public class PermissionService private static final String PERMISSION_DELIMETER = ","; @Autowired(required = false) - private SecurityJwtTemplate securityJwtTemplate; + private AbstractJwtTemplate securityJwtTemplate; /** * 验证用户是否具备某权限 @@ -41,7 +41,7 @@ public class PermissionService if (StringUtils.isEmpty(permission)) { return false; } - LoginUser loginUser = securityJwtTemplate.getLoginUser(RequestHolder.getRequest()); + AbstractLoginUser loginUser = securityJwtTemplate.getLoginUser(RequestHolder.getRequest()); if (StringUtils.isNull(loginUser) || CollectionUtils.isEmpty(loginUser.getPermissions())) { return false; } @@ -68,7 +68,7 @@ public class PermissionService if (StringUtils.isEmpty(permissions)) { return false; } - LoginUser loginUser = securityJwtTemplate.getLoginUser(RequestHolder.getRequest()); + AbstractLoginUser loginUser = securityJwtTemplate.getLoginUser(RequestHolder.getRequest()); if (StringUtils.isNull(loginUser) || CollectionUtils.isEmpty(loginUser.getPermissions())) { return false; } @@ -91,7 +91,7 @@ public class PermissionService if (StringUtils.isEmpty(role)) { return false; } - LoginUser loginUser = securityJwtTemplate.getLoginUser(RequestHolder.getRequest()); + AbstractLoginUser loginUser = securityJwtTemplate.getLoginUser(RequestHolder.getRequest()); if (StringUtils.isNull(loginUser) || CollectionUtils.isEmpty(loginUser.getRoles())) { return false; } @@ -123,7 +123,7 @@ public class PermissionService if (StringUtils.isEmpty(roles)) { return false; } - LoginUser loginUser = securityJwtTemplate.getLoginUser(RequestHolder.getRequest()); + AbstractLoginUser loginUser = securityJwtTemplate.getLoginUser(RequestHolder.getRequest()); if (StringUtils.isNull(loginUser) || CollectionUtils.isEmpty(loginUser.getRoles())) { return false; } diff --git a/secret-boot-framework-security/src/main/java/cn/chenc/framework/security/util/SecurityUtil.java b/secret-boot-framework-security/src/main/java/cn/chenc/framework/security/util/SecurityUtil.java index 53979f2..dd606a2 100644 --- a/secret-boot-framework-security/src/main/java/cn/chenc/framework/security/util/SecurityUtil.java +++ b/secret-boot-framework-security/src/main/java/cn/chenc/framework/security/util/SecurityUtil.java @@ -2,7 +2,7 @@ package cn.chenc.framework.security.util; import cn.chenc.framework.core.exception.CustomException; import cn.chenc.framework.core.model.response.CustomCode; -import cn.chenc.framework.security.model.LoginUser; +import cn.chenc.framework.security.model.SecurityLoginUser; import org.springframework.http.HttpStatus; import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; @@ -31,9 +31,9 @@ public class SecurityUtil { /** * 获取用户 **/ - public static LoginUser getLoginUser() { + public static SecurityLoginUser getLoginUser() { try { - return (LoginUser)getAuthentication().getPrincipal(); + return (SecurityLoginUser)getAuthentication().getPrincipal(); } catch (Exception e) { throw new CustomException(new CustomCode(false,HttpStatus.UNAUTHORIZED.value(),"获取用户信息异常")); diff --git a/secret-boot-framework-shiro/src/main/java/cn/chenc/framework/shiro/jwt/ShiroJwtTemplate.java b/secret-boot-framework-shiro/src/main/java/cn/chenc/framework/shiro/jwt/ShiroJwtTemplate.java index 11bb428..d7c4bc8 100644 --- a/secret-boot-framework-shiro/src/main/java/cn/chenc/framework/shiro/jwt/ShiroJwtTemplate.java +++ b/secret-boot-framework-shiro/src/main/java/cn/chenc/framework/shiro/jwt/ShiroJwtTemplate.java @@ -20,6 +20,7 @@ import java.util.Map; * jwt token验证处理 * */ +@Deprecated public class ShiroJwtTemplate { // 令牌自定义标识 private String header= CommonConst.HEADER; diff --git a/secret-boot-framework-shiro/src/main/java/cn/chenc/framework/shiro/jwt/ShiroRedisJwtTemplate.java b/secret-boot-framework-shiro/src/main/java/cn/chenc/framework/shiro/jwt/ShiroRedisJwtTemplate.java index 8ae08d0..5e3b235 100644 --- a/secret-boot-framework-shiro/src/main/java/cn/chenc/framework/shiro/jwt/ShiroRedisJwtTemplate.java +++ b/secret-boot-framework-shiro/src/main/java/cn/chenc/framework/shiro/jwt/ShiroRedisJwtTemplate.java @@ -25,6 +25,7 @@ import java.util.concurrent.TimeUnit; *  @date 2021/4/6 15:38 * */ +@Deprecated public class ShiroRedisJwtTemplate extends ShiroJwtTemplate { @Autowired diff --git a/secret-boot-framework-shiro/src/main/java/cn/chenc/framework/shiro/model/LoginUser.java b/secret-boot-framework-shiro/src/main/java/cn/chenc/framework/shiro/model/LoginUser.java index f0d3763..2d040e2 100644 --- a/secret-boot-framework-shiro/src/main/java/cn/chenc/framework/shiro/model/LoginUser.java +++ b/secret-boot-framework-shiro/src/main/java/cn/chenc/framework/shiro/model/LoginUser.java @@ -1,5 +1,6 @@ package cn.chenc.framework.shiro.model; +import cn.chenc.framework.core.model.AbstractLoginUser; import cn.chenc.framework.core.model.LoginUserDetails; import java.io.Serializable; @@ -11,7 +12,7 @@ import java.util.Set; *  @date 2021/4/6 16:57 * */ -public class LoginUser implements Serializable { +public class LoginUser implements AbstractLoginUser, Serializable { private static final long serialVersionUID = 1L; @@ -94,7 +95,8 @@ public class LoginUser implements Serializable { * 返回用户名 * @return */ - public Object getUsername() { + @Override + public String getUsername() { return user.getUsername(); } @@ -106,83 +108,102 @@ public class LoginUser implements Serializable { return user.getPassword(); } - + @Override public String getToken() { return token; } + @Override public void setToken(String token) { this.token = token; } + @Override public Long getLoginTime() { return loginTime; } + @Override public void setLoginTime(Long loginTime) { this.loginTime = loginTime; } + @Override public Long getExpireTime() { return expireTime; } + @Override public void setExpireTime(Long expireTime) { this.expireTime = expireTime; } + @Override public String getIpaddr() { return ipaddr; } + @Override public void setIpaddr(String ipaddr) { this.ipaddr = ipaddr; } + @Override public String getLoginLocation() { return loginLocation; } + @Override public void setLoginLocation(String loginLocation) { this.loginLocation = loginLocation; } + @Override public String getBrowser() { return browser; } + @Override public void setBrowser(String browser) { this.browser = browser; } + @Override public String getOs() { return os; } + @Override public void setOs(String os) { this.os = os; } + @Override public Set getRoles() { return roles; } + @Override public void setRoles(Set roles) { this.roles = roles; } + @Override public Set getPermissions() { return permissions; } + @Override public void setPermissions(Set permissions) { this.permissions = permissions; } + @Override public LoginUserDetails getUser() { return user; } + @Override public void setUser(LoginUserDetails user) { this.user = user; } -- Gitee From cd983a1c314f4964d4d75e737c8fba98def6b43e Mon Sep 17 00:00:00 2001 From: secret <1029693356@qq.com> Date: Wed, 21 Jul 2021 23:27:39 +0800 Subject: [PATCH 03/11] =?UTF-8?q?jdbcTemplate=E6=89=A9=E5=B1=95=EF=BC=8C?= =?UTF-8?q?=E5=8A=A8=E6=80=81=E5=A4=9A=E6=95=B0=E6=8D=AE=E6=BA=90=E5=88=87?= =?UTF-8?q?=E6=8D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- secret-boot-framework-core/pom.xml | 6 + .../core/annotation/ChangDataSource.java | 17 ++ .../core/aspect/DataSourceAspect.java | 83 +++++++ .../core/aspect/PreAuthorizeAspect.java | 14 +- .../core/mutidatasource/DataSourceName.java | 11 + .../mutidatasource/DynamicDataSource.java | 45 ++++ .../framework/jpa/jdbc/BaseJdbcTemplate.java | 40 ++++ .../jpa/jdbc/BaseJdbcTemplateImpl.java | 225 ++++++++++++++++++ .../PageUtil.java => model/PageInfo.java} | 19 +- .../jpa/repository/BaseRepository.java | 10 +- .../jpa/repository/BaseRepositoryImpl.java | 20 +- .../framework/jpa/service/BaseService.java | 8 +- .../jpa/service/BaseServiceImpl.java | 14 +- .../chenc/framework/jpa/util/SqlHelper.java | 3 +- 14 files changed, 473 insertions(+), 42 deletions(-) create mode 100644 secret-boot-framework-core/src/main/java/cn/chenc/framework/core/annotation/ChangDataSource.java create mode 100644 secret-boot-framework-core/src/main/java/cn/chenc/framework/core/aspect/DataSourceAspect.java create mode 100644 secret-boot-framework-core/src/main/java/cn/chenc/framework/core/mutidatasource/DataSourceName.java create mode 100644 secret-boot-framework-core/src/main/java/cn/chenc/framework/core/mutidatasource/DynamicDataSource.java create mode 100644 secret-boot-framework-jpa/src/main/java/cn/chenc/framework/jpa/jdbc/BaseJdbcTemplate.java create mode 100644 secret-boot-framework-jpa/src/main/java/cn/chenc/framework/jpa/jdbc/BaseJdbcTemplateImpl.java rename secret-boot-framework-jpa/src/main/java/cn/chenc/framework/jpa/{util/PageUtil.java => model/PageInfo.java} (86%) diff --git a/secret-boot-framework-core/pom.xml b/secret-boot-framework-core/pom.xml index fe3d2a9..89c00bd 100644 --- a/secret-boot-framework-core/pom.xml +++ b/secret-boot-framework-core/pom.xml @@ -37,6 +37,12 @@ spring-boot-starter-data-redis true + + + org.springframework.boot + spring-boot-starter-jdbc + true + org.springframework.boot diff --git a/secret-boot-framework-core/src/main/java/cn/chenc/framework/core/annotation/ChangDataSource.java b/secret-boot-framework-core/src/main/java/cn/chenc/framework/core/annotation/ChangDataSource.java new file mode 100644 index 0000000..a7e64ef --- /dev/null +++ b/secret-boot-framework-core/src/main/java/cn/chenc/framework/core/annotation/ChangDataSource.java @@ -0,0 +1,17 @@ +package cn.chenc.framework.core.annotation; + +import java.lang.annotation.*; + +/** + *  @description: 切换数据源 + *  @author secret + *  @date 2021/7/21 22:59 + * + */ +@Target({ElementType.METHOD}) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface ChangDataSource { + String name() default "master"; +} + diff --git a/secret-boot-framework-core/src/main/java/cn/chenc/framework/core/aspect/DataSourceAspect.java b/secret-boot-framework-core/src/main/java/cn/chenc/framework/core/aspect/DataSourceAspect.java new file mode 100644 index 0000000..98acf76 --- /dev/null +++ b/secret-boot-framework-core/src/main/java/cn/chenc/framework/core/aspect/DataSourceAspect.java @@ -0,0 +1,83 @@ +package cn.chenc.framework.core.aspect; + +import cn.chenc.framework.core.annotation.ChangDataSource; +import cn.chenc.framework.core.mutidatasource.DynamicDataSource; +import org.aspectj.lang.JoinPoint; +import org.aspectj.lang.annotation.AfterReturning; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Before; +import org.aspectj.lang.annotation.Pointcut; +import org.aspectj.lang.reflect.MethodSignature; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.core.annotation.AnnotationUtils; +import org.springframework.core.annotation.Order; +import org.springframework.stereotype.Component; + +import java.util.Objects; + +/** + *  @description: 动态数据源 + *  @author secret + *  @date 2021/7/21 23:02 + * + */ +@Aspect +@Order(-10) +@Component +public class DataSourceAspect { + Logger logger = LoggerFactory.getLogger(DynamicDataSource.class); + + + public DataSourceAspect() { + } + + @Pointcut("@annotation(cn.chenc.framework.core.annotation.ChangDataSource)" + + "|| @within(cn.chenc.framework.core.annotation.ChangDataSource)") + public void dsPointCut() { + + } + + /** + * 方法执行前进行 + * @param point + * @throws Exception + */ + @Before("dsPointCut()") + public void changeDataSource(JoinPoint point) throws Exception { + ChangDataSource source = getDataSource(point); + String name = source.name(); + this.logger.info("change dataSource :" + name); + if (!DynamicDataSource.checkDataSourceType(name)) { + throw new Exception("数据源" + name + "不存在,使用默认数据源 "); + } else { + //切换数据源 + DynamicDataSource.setDataSourceType(name); + } + } + + /** + * 方法结束后进行 + * @param point + */ + @AfterReturning("dsPointCut()") + public void restoreDataSource(JoinPoint point) { + //方法执行结束后,销毁数据源 + DynamicDataSource.clearDataSourceType(); + } + + /** + * 获取需要切换的数据源 + */ + public ChangDataSource getDataSource(JoinPoint point) + { + MethodSignature signature = (MethodSignature) point.getSignature(); + ChangDataSource dataSource = AnnotationUtils.findAnnotation(signature.getMethod(), ChangDataSource.class); + if (Objects.nonNull(dataSource)) + { + return dataSource; + } + + return AnnotationUtils.findAnnotation(signature.getDeclaringType(), ChangDataSource.class); + } +} diff --git a/secret-boot-framework-core/src/main/java/cn/chenc/framework/core/aspect/PreAuthorizeAspect.java b/secret-boot-framework-core/src/main/java/cn/chenc/framework/core/aspect/PreAuthorizeAspect.java index b59add1..1dd2462 100644 --- a/secret-boot-framework-core/src/main/java/cn/chenc/framework/core/aspect/PreAuthorizeAspect.java +++ b/secret-boot-framework-core/src/main/java/cn/chenc/framework/core/aspect/PreAuthorizeAspect.java @@ -1,9 +1,9 @@ package cn.chenc.framework.core.aspect; import cn.chenc.framework.core.annotation.PreAuthorize; -import cn.chenc.framework.core.component.JwtTemplate; +import cn.chenc.framework.core.component.AbstractJwtTemplate; import cn.chenc.framework.core.exception.PreAuthorizeException; -import cn.chenc.framework.core.model.LoginUser; +import cn.chenc.framework.core.model.AbstractLoginUser; import cn.chenc.framework.core.model.request.RequestHolder; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.Signature; @@ -29,7 +29,7 @@ import java.util.Collection; public class PreAuthorizeAspect { @Autowired(required = false) - private JwtTemplate jwtTemplate; + private AbstractJwtTemplate jwtTemplate; /** 所有权限标识 */ private static final String ALL_PERMISSION = "*:*:*"; @@ -96,7 +96,7 @@ public class PreAuthorizeAspect { * @return 用户是否具备某权限 */ public boolean hasPermi(String permission) { - LoginUser userInfo = jwtTemplate.getLoginUser(RequestHolder.getRequest()); + AbstractLoginUser userInfo = jwtTemplate.getLoginUser(RequestHolder.getRequest()); if (StringUtils.isEmpty(userInfo) || CollectionUtils.isEmpty(userInfo.getPermissions())) { return false; } @@ -120,7 +120,7 @@ public class PreAuthorizeAspect { * @return 用户是否具有以下任意一个权限 */ public boolean hasAnyPermi(String[] permissions) { - LoginUser userInfo = jwtTemplate.getLoginUser(RequestHolder.getRequest()); + AbstractLoginUser userInfo = jwtTemplate.getLoginUser(RequestHolder.getRequest()); if (StringUtils.isEmpty(userInfo) || CollectionUtils.isEmpty(userInfo.getPermissions())) { return false; } @@ -140,7 +140,7 @@ public class PreAuthorizeAspect { * @return 用户是否具备某角色 */ public boolean hasRole(String role) { - LoginUser userInfo = jwtTemplate.getLoginUser(RequestHolder.getRequest()); + AbstractLoginUser userInfo = jwtTemplate.getLoginUser(RequestHolder.getRequest()); if (StringUtils.isEmpty(userInfo) || CollectionUtils.isEmpty(userInfo.getRoles())) { return false; } @@ -169,7 +169,7 @@ public class PreAuthorizeAspect { * @return 用户是否具有以下任意一个角色 */ public boolean hasAnyRoles(String[] roles) { - LoginUser userInfo = jwtTemplate.getLoginUser(RequestHolder.getRequest()); + AbstractLoginUser userInfo = jwtTemplate.getLoginUser(RequestHolder.getRequest()); if (StringUtils.isEmpty(userInfo) || CollectionUtils.isEmpty(userInfo.getRoles())) { return false; } diff --git a/secret-boot-framework-core/src/main/java/cn/chenc/framework/core/mutidatasource/DataSourceName.java b/secret-boot-framework-core/src/main/java/cn/chenc/framework/core/mutidatasource/DataSourceName.java new file mode 100644 index 0000000..4020a20 --- /dev/null +++ b/secret-boot-framework-core/src/main/java/cn/chenc/framework/core/mutidatasource/DataSourceName.java @@ -0,0 +1,11 @@ +package cn.chenc.framework.core.mutidatasource; + +/** + *  @description: 数据源名称 + *  @author secret + *  @date 2021/7/21 23:15 + * + */ +public interface DataSourceName { + public final static String MASTER = "master"; +} diff --git a/secret-boot-framework-core/src/main/java/cn/chenc/framework/core/mutidatasource/DynamicDataSource.java b/secret-boot-framework-core/src/main/java/cn/chenc/framework/core/mutidatasource/DynamicDataSource.java new file mode 100644 index 0000000..62e6c73 --- /dev/null +++ b/secret-boot-framework-core/src/main/java/cn/chenc/framework/core/mutidatasource/DynamicDataSource.java @@ -0,0 +1,45 @@ +package cn.chenc.framework.core.mutidatasource; + +import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource; + +import java.util.ArrayList; +import java.util.List; + +/** + *  @description: 多数据源配置 + *  @author secret + *  @date 2021/7/21 22:28 + * + */ +public class DynamicDataSource extends AbstractRoutingDataSource { + private static final ThreadLocal contextHolder = new ThreadLocal(); + private static List dataSourceList = new ArrayList(); + + public DynamicDataSource() { + } + + public static void setDataSourceType(String dataSourceType) { + contextHolder.set(dataSourceType); + } + + public static String getDataSourceType() { + return contextHolder.get() == null ? DataSourceName.MASTER : (String)contextHolder.get(); + } + + public static void clearDataSourceType() { + contextHolder.remove(); + } + + public static void saveDataSourceTypeName(String name) { + dataSourceList.add(name); + } + + public static boolean checkDataSourceType(String name) { + return dataSourceList.contains(name); + } + + @Override + protected Object determineCurrentLookupKey() { + return getDataSourceType(); + } +} diff --git a/secret-boot-framework-jpa/src/main/java/cn/chenc/framework/jpa/jdbc/BaseJdbcTemplate.java b/secret-boot-framework-jpa/src/main/java/cn/chenc/framework/jpa/jdbc/BaseJdbcTemplate.java new file mode 100644 index 0000000..6dea085 --- /dev/null +++ b/secret-boot-framework-jpa/src/main/java/cn/chenc/framework/jpa/jdbc/BaseJdbcTemplate.java @@ -0,0 +1,40 @@ +package cn.chenc.framework.jpa.jdbc; + +import cn.chenc.framework.jpa.exception.RepositoryException; +import cn.chenc.framework.jpa.model.PageInfo; +import org.springframework.jdbc.core.JdbcTemplate; + +import java.util.List; +import java.util.Map; + +/** + *  @description: TODO + *  @author secret + *  @date 2021/7/21 22:07 + * + */ +public interface BaseJdbcTemplate { + + List> queryListMapBySql(String sql) throws Exception; + + PageInfo queryListMapBySql(String sql, PageInfo page) throws Exception; + + PageInfo queryListMapNoTotalBySql(String sql, PageInfo page) throws Exception; + + List queryListEntityBySql(String sql, Class mappedClass) throws Exception; + + PageInfo queryListEntityBySql(String sql, Class mappedClass, PageInfo page) throws Exception; + + Map queryMapBySql(String sql) throws Exception; + + JdbcTemplate queryJdbcTemplate() throws Exception; + + void execute(String sql) throws Exception; + + T queryEntityBySql(String sql, Class mappedClass) throws Exception; + + List> getColumnsAndTypeBySql(String sql) throws RepositoryException; + + List getColumnsBySql(String sql) throws RepositoryException; + +} diff --git a/secret-boot-framework-jpa/src/main/java/cn/chenc/framework/jpa/jdbc/BaseJdbcTemplateImpl.java b/secret-boot-framework-jpa/src/main/java/cn/chenc/framework/jpa/jdbc/BaseJdbcTemplateImpl.java new file mode 100644 index 0000000..6a0a923 --- /dev/null +++ b/secret-boot-framework-jpa/src/main/java/cn/chenc/framework/jpa/jdbc/BaseJdbcTemplateImpl.java @@ -0,0 +1,225 @@ +package cn.chenc.framework.jpa.jdbc; + +import cn.chenc.framework.core.mutidatasource.DynamicDataSource; +import cn.chenc.framework.core.util.AssertUtil; +import cn.chenc.framework.jpa.exception.RepositoryException; +import cn.chenc.framework.jpa.exception.ServiceException; +import cn.chenc.framework.jpa.model.PageInfo; +import cn.chenc.framework.jpa.util.SqlHelper; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.dao.IncorrectResultSizeDataAccessException; +import org.springframework.jdbc.core.BeanPropertyRowMapper; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.core.RowMapper; +import org.springframework.jdbc.support.rowset.SqlRowSet; +import org.springframework.jdbc.support.rowset.SqlRowSetMetaData; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + *  @description: TODO + *  @author secret + *  @date 2021/7/21 22:14 + * + */ +@Component +public class BaseJdbcTemplateImpl implements BaseJdbcTemplate{ + + @Autowired + @Qualifier("multipleDataJdbcTemplate") + private JdbcTemplate jdbcTemplate; + + public BaseJdbcTemplateImpl() { + } + + @Override + public List> queryListMapBySql(String sql) throws Exception { + AssertUtil.notNull(sql, "sql must not be null"); + + try { + return this.jdbcTemplate.queryForList(sql); + } catch (IncorrectResultSizeDataAccessException var3) { + return null; + } catch (Exception var4) { + throw new ServiceException("Problem invoking method, Cause:" + var4.getMessage(), var4); + } + } + + @Override + public List queryListEntityBySql(String sql, Class mappedClass) throws Exception { + AssertUtil.notNull(sql, "sql must not be null"); + + try { + RowMapper rowMapper = BeanPropertyRowMapper.newInstance(mappedClass); + List dd = this.jdbcTemplate.query(sql, rowMapper); + return dd; + } catch (Exception var5) { + throw new ServiceException("Problem invoking method, Cause:" + var5.getMessage(), var5); + } + } + + @Override + public PageInfo queryListMapBySql(String sql, PageInfo page) throws Exception { + AssertUtil.notNull(sql, "sql must not be null"); + + try { + int pageNum = page.getPageNum(); + int pageSize = page.getPageSize(); + Map map = this.queryMapBySql(SqlHelper.queryCountSQL(sql)); + int totalCount = Integer.valueOf(String.valueOf(map.get("totalRow"))); + List> list = this.queryListMapBySql(SqlHelper.buildDataSql(sql, page, DynamicDataSource.getDataSourceType())); + PageInfo pageUtil = new PageInfo(pageNum, pageSize, totalCount); + pageUtil.setCurrPageCount(list.size()); + pageUtil.setContent(list); + return pageUtil; + } catch (Exception var9) { + throw new ServiceException("Problem invoking method, Cause:" + var9.getMessage(), var9); + } + } + + @Override + public PageInfo queryListEntityBySql(String sql, Class mappedClass, PageInfo page) throws Exception { + AssertUtil.notNull(sql, "sql must not be null"); + + try { + int pageNum = page.getPageNum(); + int pageSize = page.getPageSize(); + Map map = this.queryMapBySql(SqlHelper.queryCountSQL(sql)); + int totalCount = Integer.valueOf(String.valueOf(map.get("totalRow"))); + List list = this.queryListEntityBySql(SqlHelper.buildDataSql(sql, page, DynamicDataSource.getDataSourceType()), mappedClass); + PageInfo pageUtil = new PageInfo(pageNum, pageSize, totalCount); + pageUtil.setCurrPageCount(list.size()); + pageUtil.setContent(list); + return pageUtil; + } catch (Exception var10) { + throw new ServiceException("Problem invoking method, Cause:" + var10.getMessage(), var10); + } + } + + @Override + public Map queryMapBySql(String sql) throws Exception { + AssertUtil.notNull(sql, "sql must not be null"); + + try { + return this.jdbcTemplate.queryForMap(sql); + } catch (IncorrectResultSizeDataAccessException var3) { + return null; + } catch (Exception var4) { + var4.printStackTrace(); + throw new ServiceException("Problem invoking method, Cause:" + var4.getMessage(), var4); + } + } + + @Override + public JdbcTemplate queryJdbcTemplate() throws Exception { + return this.jdbcTemplate; + } + + @Override + public void execute(String sql) throws Exception { + AssertUtil.notNull(sql, "sql must not be null"); + + try { + this.jdbcTemplate.execute(sql); + } catch (Exception var3) { + throw new ServiceException("Problem invoking method, Cause:" + var3.getMessage(), var3); + } + } + + @Override + public T queryEntityBySql(String sql, Class mappedClass) throws Exception { + AssertUtil.notNull(sql, "sql must not be null"); + + try { + RowMapper rowMapper = BeanPropertyRowMapper.newInstance(mappedClass); + return this.jdbcTemplate.queryForObject(sql, rowMapper); + } catch (Exception var4) { + throw new ServiceException("Problem invoking method, Cause:" + var4.getMessage(), var4); + } + } + + @Override + public List> getColumnsAndTypeBySql(String sql) throws RepositoryException { + ArrayList columnList = new ArrayList(); + + try { + SqlRowSet rowSet = this.jdbcTemplate.queryForRowSet(sql); + SqlRowSetMetaData metaData = rowSet.getMetaData(); + int columnCount = metaData.getColumnCount(); + Map strMap = new HashMap(); + + for(int i = 1; i <= columnCount; ++i) { + Map map = new HashMap(); + String columnName = metaData.getColumnName(i); + if (strMap.get(columnName) == null) { + strMap.put(columnName, 1); + } else { + int number = (Integer)strMap.get(columnName); + columnName = columnName + number; + ++number; + strMap.put(columnName, number); + } + + map.put("columnName", columnName); + map.put("columnType", String.valueOf(metaData.getColumnType(i))); + columnList.add(map); + } + + return columnList; + } catch (Exception var11) { + throw new RepositoryException(var11.getMessage(), var11); + } + } + + @Override + public List getColumnsBySql(String sql) throws RepositoryException { + ArrayList columnList = new ArrayList(); + + try { + SqlRowSet rowSet = this.jdbcTemplate.queryForRowSet(sql); + SqlRowSetMetaData metaData = rowSet.getMetaData(); + int columnCount = metaData.getColumnCount(); + Map strMap = new HashMap(); + + for(int i = 0; i < columnCount; ++i) { + String columnName = metaData.getColumnName(i + 1).toLowerCase(); + if (strMap.get(columnName) == null) { + strMap.put(columnName, 1); + } else { + int number = (Integer)strMap.get(columnName); + columnName = columnName + number; + ++number; + strMap.put(columnName, number); + } + + columnList.add(columnName); + } + + return columnList; + } catch (Exception var10) { + throw new RepositoryException(var10.getMessage(), var10); + } + } + + @Override + public PageInfo queryListMapNoTotalBySql(String sql, PageInfo page) throws Exception { + AssertUtil.notNull(sql, "sql must not be null"); + + try { + int pageNum = page.getPageNum(); + int pageSize = page.getPageSize(); + List> list = this.queryListMapBySql(SqlHelper.buildDataSql(sql, page, DynamicDataSource.getDataSourceType())); + PageInfo pageUtil = new PageInfo(pageNum, pageSize, 0); + pageUtil.setCurrPageCount(list.size()); + pageUtil.setContent(list); + return pageUtil; + } catch (Exception var7) { + throw new ServiceException("Problem invoking method, Cause:" + var7.getMessage(), var7); + } + } +} diff --git a/secret-boot-framework-jpa/src/main/java/cn/chenc/framework/jpa/util/PageUtil.java b/secret-boot-framework-jpa/src/main/java/cn/chenc/framework/jpa/model/PageInfo.java similarity index 86% rename from secret-boot-framework-jpa/src/main/java/cn/chenc/framework/jpa/util/PageUtil.java rename to secret-boot-framework-jpa/src/main/java/cn/chenc/framework/jpa/model/PageInfo.java index cb7fda6..10b0df9 100644 --- a/secret-boot-framework-jpa/src/main/java/cn/chenc/framework/jpa/util/PageUtil.java +++ b/secret-boot-framework-jpa/src/main/java/cn/chenc/framework/jpa/model/PageInfo.java @@ -1,6 +1,7 @@ -package cn.chenc.framework.jpa.util; +package cn.chenc.framework.jpa.model; import cn.chenc.framework.core.text.Convert; +import cn.hutool.core.util.PageUtil; import org.springframework.data.domain.Page; import java.io.Serializable; @@ -13,7 +14,7 @@ import java.util.List; *  @date 2021/6/5 23:10 * */ -public class PageUtil implements Serializable { +public class PageInfo implements Serializable { private static final long serialVersionUID = 1L; private int pageNum = 0; private int pageSize = 20; @@ -24,16 +25,16 @@ public class PageUtil implements Serializable { private int currPageCount; private List content = Collections.emptyList(); - public PageUtil(int pageNum, int pageSize) { + public PageInfo(int pageNum, int pageSize) { this.pageNum = pageNum; this.pageSize = pageSize; } - public static PageUtil of(int pageNum, int pageSize) { - return new PageUtil(pageNum, pageSize); + public static PageInfo of(int pageNum, int pageSize) { + return new PageInfo(pageNum, pageSize); } - public PageUtil(int pageNum, int pageSize, int totalCount) { + public PageInfo(int pageNum, int pageSize, int totalCount) { this.pageNum = pageNum == 0 ? 1 : pageNum; this.pageSize = pageSize; this.totalCount = totalCount; @@ -42,15 +43,15 @@ public class PageUtil implements Serializable { this.last = pageNum == this.totalPage; } - public PageUtil() { + public PageInfo() { } public static int offsetCurrent(int pageNum, int pageSize) { return pageNum > 0 ? (pageNum - 1) * pageSize : 0; } - public static PageUtil convertPageable(Page pageable) { - PageUtil pageUtil = new PageUtil(); + public static PageInfo convertPageable(Page pageable) { + PageInfo pageUtil = new PageInfo(); pageUtil.setPageNum(pageable.getNumber() == 0 ? 1 : pageable.getNumber()); pageUtil.setPageSize(pageable.getSize()); pageUtil.setContent(pageable.getContent()); diff --git a/secret-boot-framework-jpa/src/main/java/cn/chenc/framework/jpa/repository/BaseRepository.java b/secret-boot-framework-jpa/src/main/java/cn/chenc/framework/jpa/repository/BaseRepository.java index 67480d9..2f83181 100644 --- a/secret-boot-framework-jpa/src/main/java/cn/chenc/framework/jpa/repository/BaseRepository.java +++ b/secret-boot-framework-jpa/src/main/java/cn/chenc/framework/jpa/repository/BaseRepository.java @@ -1,7 +1,7 @@ package cn.chenc.framework.jpa.repository; import cn.chenc.framework.jpa.exception.RepositoryException; -import cn.chenc.framework.jpa.util.PageUtil; +import cn.chenc.framework.jpa.model.PageInfo; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; @@ -44,17 +44,17 @@ public interface BaseRepository extends JpaReposito List getListBySql(String sql, Class clzss) throws RepositoryException; - PageUtil getListBySql(String sql, PageUtil pageable) throws RepositoryException; + PageInfo getListBySql(String sql, PageInfo pageable) throws RepositoryException; - PageUtil getListBySql(String sql, PageUtil pageable, Map searchMap) throws RepositoryException; + PageInfo getListBySql(String sql, PageInfo pageable, Map searchMap) throws RepositoryException; List> getListMapBySql(String sql) throws RepositoryException; List> getListMapBySql(String sql, Map searchMap) throws RepositoryException; - PageUtil getListMapBySql(String sql, PageUtil pageable) throws RepositoryException; + PageInfo getListMapBySql(String sql, PageInfo pageable) throws RepositoryException; - PageUtil getListMapBySql(String sql, PageUtil pageable, Map searchMap) throws RepositoryException; + PageInfo getListMapBySql(String sql, PageInfo pageable, Map searchMap) throws RepositoryException; Map getSingleMapBySql(String sql) throws RepositoryException; diff --git a/secret-boot-framework-jpa/src/main/java/cn/chenc/framework/jpa/repository/BaseRepositoryImpl.java b/secret-boot-framework-jpa/src/main/java/cn/chenc/framework/jpa/repository/BaseRepositoryImpl.java index 543419f..33117d2 100644 --- a/secret-boot-framework-jpa/src/main/java/cn/chenc/framework/jpa/repository/BaseRepositoryImpl.java +++ b/secret-boot-framework-jpa/src/main/java/cn/chenc/framework/jpa/repository/BaseRepositoryImpl.java @@ -3,7 +3,7 @@ package cn.chenc.framework.jpa.repository; import cn.chenc.framework.core.text.Convert; import cn.chenc.framework.core.util.AssertUtil; import cn.chenc.framework.jpa.exception.RepositoryException; -import cn.chenc.framework.jpa.util.PageUtil; +import cn.chenc.framework.jpa.model.PageInfo; import cn.chenc.framework.jpa.util.SqlHelper; import cn.hutool.core.map.MapUtil; import org.hibernate.Session; @@ -169,13 +169,13 @@ public class BaseRepositoryImpl extends SimpleJpaRe } @Override - public PageUtil getListBySql(String sql, PageUtil pageable) throws RepositoryException { + public PageInfo getListBySql(String sql, PageInfo pageable) throws RepositoryException { return this.getListBySql(sql, pageable, (Map)null); } @Override - public PageUtil getListBySql(String sql, PageUtil pageable, Map searchMap) throws RepositoryException { + public PageInfo getListBySql(String sql, PageInfo pageable, Map searchMap) throws RepositoryException { Query query = this.entityManager.createNativeQuery(sql, this.clazz); if (null != searchMap) { Iterator var5 = searchMap.entrySet().iterator(); @@ -189,11 +189,11 @@ public class BaseRepositoryImpl extends SimpleJpaRe int pageNum = pageable.getPageNum(); int pageSize = pageable.getPageSize(); if (pageNum >= 1 && pageSize >= 1) { - int currPageCount = cn.chenc.framework.jpa.util.PageUtil.offsetCurrent(pageNum, pageSize); + int currPageCount = PageInfo.offsetCurrent(pageNum, pageSize); int totalCount = this.getCountBySql(sql, searchMap); query.setFirstResult(currPageCount).setMaxResults(pageSize); List> list = query.getResultList(); - PageUtil pageUtil = new PageUtil(pageNum, pageSize, totalCount); + PageInfo pageUtil = new PageInfo(pageNum, pageSize, totalCount); pageUtil.setCurrPageCount(list.size()); pageUtil.setContent(list); return pageUtil; @@ -229,11 +229,13 @@ public class BaseRepositoryImpl extends SimpleJpaRe return list; } - public PageUtil getListMapBySql(String sql, PageUtil pageable) throws RepositoryException { + @Override + public PageInfo getListMapBySql(String sql, PageInfo pageable) throws RepositoryException { return this.getListMapBySql(sql, pageable, (Map)null); } - public PageUtil getListMapBySql(String sql, PageUtil pageable, Map searchMap) throws RepositoryException { + @Override + public PageInfo getListMapBySql(String sql, PageInfo pageable, Map searchMap) throws RepositoryException { Query query = this.entityManager.createNativeQuery(sql); if (null != searchMap) { Iterator var5 = searchMap.entrySet().iterator(); @@ -247,12 +249,12 @@ public class BaseRepositoryImpl extends SimpleJpaRe int pageNum = pageable.getPageNum(); int pageSize = pageable.getPageSize(); if (pageNum >= 1 && pageSize >= 1) { - int currPageCount = cn.chenc.framework.jpa.util.PageUtil.offsetCurrent(pageNum, pageSize); + int currPageCount = PageInfo.offsetCurrent(pageNum, pageSize); int totalCount = this.getCountBySql(sql, searchMap); query.setFirstResult(currPageCount).setMaxResults(pageSize); ((NativeQueryImpl)query.unwrap(NativeQueryImpl.class)).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP); List> list = query.getResultList(); - PageUtil pageUtil = new PageUtil(pageNum, pageSize, totalCount); + PageInfo pageUtil = new PageInfo(pageNum, pageSize, totalCount); pageUtil.setCurrPageCount(list.size()); pageUtil.setContent(list); return pageUtil; diff --git a/secret-boot-framework-jpa/src/main/java/cn/chenc/framework/jpa/service/BaseService.java b/secret-boot-framework-jpa/src/main/java/cn/chenc/framework/jpa/service/BaseService.java index f6c7505..a605b14 100644 --- a/secret-boot-framework-jpa/src/main/java/cn/chenc/framework/jpa/service/BaseService.java +++ b/secret-boot-framework-jpa/src/main/java/cn/chenc/framework/jpa/service/BaseService.java @@ -1,7 +1,7 @@ package cn.chenc.framework.jpa.service; import cn.chenc.framework.jpa.exception.ServiceException; -import cn.chenc.framework.jpa.util.PageUtil; +import cn.chenc.framework.jpa.model.PageInfo; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; @@ -69,11 +69,11 @@ public interface BaseService { List getListBySql(String sql, Class clzss) throws ServiceException; - PageUtil getListBySql(String sql, PageUtil pageable) throws ServiceException; + PageInfo getListBySql(String sql, PageInfo pageable) throws ServiceException; List> getListMapBySql(String sql) throws ServiceException; - PageUtil getListMapBySql(String sql, PageUtil pageable) throws ServiceException; + PageInfo getListMapBySql(String sql, PageInfo pageable) throws ServiceException; Map getSingleMapBySql(String sql) throws ServiceException; @@ -91,5 +91,5 @@ public interface BaseService { Pageable getPageable(Map params); - PageUtil getPage(Map params); + PageInfo getPage(Map params); } diff --git a/secret-boot-framework-jpa/src/main/java/cn/chenc/framework/jpa/service/BaseServiceImpl.java b/secret-boot-framework-jpa/src/main/java/cn/chenc/framework/jpa/service/BaseServiceImpl.java index c03184a..3b1b788 100644 --- a/secret-boot-framework-jpa/src/main/java/cn/chenc/framework/jpa/service/BaseServiceImpl.java +++ b/secret-boot-framework-jpa/src/main/java/cn/chenc/framework/jpa/service/BaseServiceImpl.java @@ -5,8 +5,8 @@ import cn.chenc.framework.core.util.AssertUtil; import cn.chenc.framework.core.util.StringUtils; import cn.chenc.framework.jpa.exception.RepositoryException; import cn.chenc.framework.jpa.exception.ServiceException; +import cn.chenc.framework.jpa.model.PageInfo; import cn.chenc.framework.jpa.repository.BaseRepository; -import cn.chenc.framework.jpa.util.PageUtil; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.*; import org.springframework.data.jpa.domain.Specification; @@ -28,12 +28,12 @@ import java.util.Map; * */ @Transactional -public class BaseServiceImpl ,T,ID extends Serializable> implements BaseService { +public class BaseServiceImpl ,T,ID extends Serializable> implements BaseService { @PersistenceContext protected EntityManager entityManager; @Autowired - M baseRepository; + R baseRepository; public BaseServiceImpl() { } @@ -233,7 +233,7 @@ public class BaseServiceImpl ,T,ID extends Serial } @Override - public PageUtil getListBySql(String sql, PageUtil pageable) throws ServiceException { + public PageInfo getListBySql(String sql, PageInfo pageable) throws ServiceException { try { return this.getBaseRepository().getListBySql(sql, pageable); } catch (RepositoryException var4) { @@ -251,7 +251,7 @@ public class BaseServiceImpl ,T,ID extends Serial } @Override - public PageUtil getListMapBySql(String sql, PageUtil pageable) throws ServiceException { + public PageInfo getListMapBySql(String sql, PageInfo pageable) throws ServiceException { try { return this.getBaseRepository().getListMapBySql(sql, pageable); } catch (RepositoryException var4) { @@ -330,10 +330,10 @@ public class BaseServiceImpl ,T,ID extends Serial } @Override - public PageUtil getPage(Map params) { + public PageInfo getPage(Map params) { Object pageNum = StringUtils.isEmpty((String) params.get("pageNum")) ? 1 : params.get("pageNum"); Object pageSize = StringUtils.isEmpty((String) params.get("pageSize")) ? 10 : params.get("pageSize"); - return PageUtil.of(Convert.toInt(pageNum), Convert.toInt(pageSize)); + return PageInfo.of(Convert.toInt(pageNum), Convert.toInt(pageSize)); } } diff --git a/secret-boot-framework-jpa/src/main/java/cn/chenc/framework/jpa/util/SqlHelper.java b/secret-boot-framework-jpa/src/main/java/cn/chenc/framework/jpa/util/SqlHelper.java index d923744..a6e812e 100644 --- a/secret-boot-framework-jpa/src/main/java/cn/chenc/framework/jpa/util/SqlHelper.java +++ b/secret-boot-framework-jpa/src/main/java/cn/chenc/framework/jpa/util/SqlHelper.java @@ -1,5 +1,6 @@ package cn.chenc.framework.jpa.util; +import cn.chenc.framework.jpa.model.PageInfo; import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.convert.Convert; @@ -128,7 +129,7 @@ public class SqlHelper { return countSQL; } - public static String buildDataSql(String sql, PageUtil pageUtil, String datasourceType) { + public static String buildDataSql(String sql, PageInfo pageUtil, String datasourceType) { StringBuffer dataSql = new StringBuffer(); if (datasourceType.toLowerCase().contains("oracle")) { dataSql.append("SELECT"); -- Gitee From d200ebb67676c511ed4b52d81e3e2688043ad9aa Mon Sep 17 00:00:00 2001 From: secret <1029693356@qq.com> Date: Mon, 26 Jul 2021 22:25:46 +0800 Subject: [PATCH 04/11] =?UTF-8?q?=E6=96=B0=E5=A2=9Epoi=E6=A8=A1=E5=9D=97?= =?UTF-8?q?=EF=BC=8C=E5=9F=BA=E4=BA=8Epoi=E5=AE=9E=E7=8E=B0excel=E6=93=8D?= =?UTF-8?q?=E4=BD=9C=EF=BC=8C=E6=94=AF=E6=8C=81=E5=AD=97=E5=85=B8=E8=BD=AC?= =?UTF-8?q?=E6=8D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- secret-boot-framework-core/pom.xml | 15 +- .../framework/core/config/SecretConfig.java | 16 + .../config/properties/DruidProperties.java | 63 + .../framework/core/consts/CommonConst.java | 2 + .../core/model/AbstractDictData.java | 23 + .../core/model/response/CustomCode.java | 5 + .../chenc/framework/core/util/DateUtils.java | 22 +- .../chenc/framework/core/util/DictUtils.java | 175 +++ secret-boot-framework-dependencies/pom.xml | 15 + secret-boot-framework-poi/pom.xml | 27 + .../chenc/framework/poi/annotation/Excel.java | 154 +++ .../framework/poi/annotation/Excels.java | 16 + .../chenc/framework/poi/util/ExcelUtil.java | 1027 +++++++++++++++++ .../framework/poi/util/ReflectUtils.java | 330 ++++++ 14 files changed, 1886 insertions(+), 4 deletions(-) create mode 100644 secret-boot-framework-core/src/main/java/cn/chenc/framework/core/config/properties/DruidProperties.java create mode 100644 secret-boot-framework-core/src/main/java/cn/chenc/framework/core/model/AbstractDictData.java create mode 100644 secret-boot-framework-core/src/main/java/cn/chenc/framework/core/util/DictUtils.java create mode 100644 secret-boot-framework-poi/pom.xml create mode 100644 secret-boot-framework-poi/src/main/java/cn/chenc/framework/poi/annotation/Excel.java create mode 100644 secret-boot-framework-poi/src/main/java/cn/chenc/framework/poi/annotation/Excels.java create mode 100644 secret-boot-framework-poi/src/main/java/cn/chenc/framework/poi/util/ExcelUtil.java create mode 100644 secret-boot-framework-poi/src/main/java/cn/chenc/framework/poi/util/ReflectUtils.java diff --git a/secret-boot-framework-core/pom.xml b/secret-boot-framework-core/pom.xml index 89c00bd..5a0a137 100644 --- a/secret-boot-framework-core/pom.xml +++ b/secret-boot-framework-core/pom.xml @@ -48,13 +48,17 @@ org.springframework.boot spring-boot-starter-validation - + com.google.guava guava - - + + + com.alibaba + druid-spring-boot-starter + true + commons-fileupload @@ -126,6 +130,11 @@ io.jsonwebtoken jjwt + + + com.github.dozermapper + dozer-core + diff --git a/secret-boot-framework-core/src/main/java/cn/chenc/framework/core/config/SecretConfig.java b/secret-boot-framework-core/src/main/java/cn/chenc/framework/core/config/SecretConfig.java index afb801c..d9e7728 100644 --- a/secret-boot-framework-core/src/main/java/cn/chenc/framework/core/config/SecretConfig.java +++ b/secret-boot-framework-core/src/main/java/cn/chenc/framework/core/config/SecretConfig.java @@ -78,4 +78,20 @@ public class SecretConfig { public void setAddressEnabled(boolean addressEnabled) { SecretConfig.addressEnabled = addressEnabled; } + + /** + * 获取下载路径 + */ + public static String getDownloadPath() + { + return getProfile() + "/download/"; + } + + /** + * 获取上传路径 + */ + public static String getUploadPath() + { + return getProfile() + "/upload"; + } } diff --git a/secret-boot-framework-core/src/main/java/cn/chenc/framework/core/config/properties/DruidProperties.java b/secret-boot-framework-core/src/main/java/cn/chenc/framework/core/config/properties/DruidProperties.java new file mode 100644 index 0000000..1ca4962 --- /dev/null +++ b/secret-boot-framework-core/src/main/java/cn/chenc/framework/core/config/properties/DruidProperties.java @@ -0,0 +1,63 @@ +package cn.chenc.framework.core.config.properties; + +import com.alibaba.druid.pool.DruidDataSource; + +/** + *  @description: DruidProperties + *  @author secret + *  @date 2021/7/22 23:42 + * + */ +public class DruidProperties { + private int initialSize; + + private int minIdle; + + private int maxActive; + + private int maxWait; + + private int timeBetweenEvictionRunsMillis; + + private int minEvictableIdleTimeMillis; + + private int maxEvictableIdleTimeMillis; + + private String validationQuery; + + private boolean testWhileIdle; + + private boolean testOnBorrow; + + private boolean testOnReturn; + + public DruidDataSource dataSource(DruidDataSource datasource) + { + /** 配置初始化大小、最小、最大 */ + datasource.setInitialSize(initialSize); + datasource.setMaxActive(maxActive); + datasource.setMinIdle(minIdle); + + /** 配置获取连接等待超时的时间 */ + datasource.setMaxWait(maxWait); + + /** 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 */ + datasource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis); + + /** 配置一个连接在池中最小、最大生存的时间,单位是毫秒 */ + datasource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis); + datasource.setMaxEvictableIdleTimeMillis(maxEvictableIdleTimeMillis); + + /** + * 用来检测连接是否有效的sql,要求是一个查询语句,常用select 'x'。如果validationQuery为null,testOnBorrow、testOnReturn、testWhileIdle都不会起作用。 + */ + datasource.setValidationQuery(validationQuery); + /** 建议配置为true,不影响性能,并且保证安全性。申请连接的时候检测,如果空闲时间大于timeBetweenEvictionRunsMillis,执行validationQuery检测连接是否有效。 */ + datasource.setTestWhileIdle(testWhileIdle); + /** 申请连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能。 */ + datasource.setTestOnBorrow(testOnBorrow); + /** 归还连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能。 */ + datasource.setTestOnReturn(testOnReturn); + return datasource; + } +} diff --git a/secret-boot-framework-core/src/main/java/cn/chenc/framework/core/consts/CommonConst.java b/secret-boot-framework-core/src/main/java/cn/chenc/framework/core/consts/CommonConst.java index a88e1d6..283d5f8 100644 --- a/secret-boot-framework-core/src/main/java/cn/chenc/framework/core/consts/CommonConst.java +++ b/secret-boot-framework-core/src/main/java/cn/chenc/framework/core/consts/CommonConst.java @@ -65,6 +65,8 @@ public class CommonConst { */ public static final String LOGIN_TOKEN_KEY = "login_tokens:"; + public static final String SYS_DICT_KEY = "sys_dict"; + } diff --git a/secret-boot-framework-core/src/main/java/cn/chenc/framework/core/model/AbstractDictData.java b/secret-boot-framework-core/src/main/java/cn/chenc/framework/core/model/AbstractDictData.java new file mode 100644 index 0000000..9f6cc49 --- /dev/null +++ b/secret-boot-framework-core/src/main/java/cn/chenc/framework/core/model/AbstractDictData.java @@ -0,0 +1,23 @@ +package cn.chenc.framework.core.model; + +/** + *  @description: 字典实体抽象 + *  @author secret + *  @date 2021/7/26 21:53 + * + */ +public interface AbstractDictData { + + /** + * 获取字典标签 + * @return + */ + String getDictLabel(); + + /** + * 获取字典键值 + * @return + */ + String getDictValue(); + +} diff --git a/secret-boot-framework-core/src/main/java/cn/chenc/framework/core/model/response/CustomCode.java b/secret-boot-framework-core/src/main/java/cn/chenc/framework/core/model/response/CustomCode.java index bc51457..de10e39 100644 --- a/secret-boot-framework-core/src/main/java/cn/chenc/framework/core/model/response/CustomCode.java +++ b/secret-boot-framework-core/src/main/java/cn/chenc/framework/core/model/response/CustomCode.java @@ -50,4 +50,9 @@ public class CustomCode implements ResultCode { public static ResultCode error(String message){ return new CustomCode(false,HttpStatus.ERROR,message); } + + public static ResultCode vo(int code,String message){ + return new CustomCode(false,code,message); + } + } diff --git a/secret-boot-framework-core/src/main/java/cn/chenc/framework/core/util/DateUtils.java b/secret-boot-framework-core/src/main/java/cn/chenc/framework/core/util/DateUtils.java index 64c1cba..f991e6b 100644 --- a/secret-boot-framework-core/src/main/java/cn/chenc/framework/core/util/DateUtils.java +++ b/secret-boot-framework-core/src/main/java/cn/chenc/framework/core/util/DateUtils.java @@ -11,12 +11,17 @@ import java.time.LocalDateTime; import java.time.ZoneId; import java.util.*; -public class DateUtils { +public class DateUtils extends org.apache.commons.lang3.time.DateUtils{ public static final String YYYYMMDDHHMMSS = "yyyy-MM-dd HH:mm:ss"; public static final String YYYYMMDD = "yyyy-MM-dd"; public static final String YYYYMMDDHHMM = "yyyy-MM-dd HH:mm"; public static final String YYYYMM = "yyyy-MM"; + private static String[] parsePatterns = { + "yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy-MM", + "yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm", "yyyy/MM", + "yyyy.MM.dd", "yyyy.MM.dd HH:mm:ss", "yyyy.MM.dd HH:mm", "yyyy.MM"}; + public DateUtils() { } @@ -52,6 +57,21 @@ public class DateUtils { } } + /** + * 日期型字符串转化为日期 格式 + */ + public static Date parseDate(Object str) { + if (str == null) { + return null; + } + try { + return parseDate(str.toString(), parsePatterns); + } + catch (ParseException e) { + return null; + } + } + /** * @description: 将日期字符串按自定义格式化转化为Date对象 * @param date 日期字符串 diff --git a/secret-boot-framework-core/src/main/java/cn/chenc/framework/core/util/DictUtils.java b/secret-boot-framework-core/src/main/java/cn/chenc/framework/core/util/DictUtils.java new file mode 100644 index 0000000..5cea18c --- /dev/null +++ b/secret-boot-framework-core/src/main/java/cn/chenc/framework/core/util/DictUtils.java @@ -0,0 +1,175 @@ +package cn.chenc.framework.core.util; + +import cn.chenc.framework.core.component.SpringContextHolder; +import cn.chenc.framework.core.consts.CommonConst; +import cn.chenc.framework.core.model.AbstractDictData; +import org.springframework.data.redis.core.RedisTemplate; + +import java.util.Collection; +import java.util.List; + +/** + *  @description: 字典工具类 + *  @author secret + *  @date 2021/7/26 21:48 + * + */ +public class DictUtils { + + /** + * 分隔符 + */ + public static final String SEPARATOR = ","; + + /** + * 设置字典缓存 + * + * @param key 参数键 + * @param dictDatas 字典数据列表 + */ + public static void setDictCache(String key, List dictDatas) { + SpringContextHolder.getBean(RedisTemplate.class).opsForValue().set(getCacheKey(key), dictDatas); + } + + /** + * 获取字典缓存 + * + * @param key 参数键 + * @return dictDatas 字典数据列表 + */ + public static List getDictCache(String key) + { + Object cacheObj = SpringContextHolder.getBean(RedisTemplate.class).opsForValue().get(getCacheKey(key)); + if (StringUtils.isNotNull(cacheObj)) + { + List dictDatas = StringUtils.cast(cacheObj); + return dictDatas; + } + return null; + } + + /** + * 根据字典类型和字典值获取字典标签 + * + * @param dictType 字典类型 + * @param dictValue 字典值 + * @return 字典标签 + */ + public static String getDictLabel(String dictType, String dictValue) + { + return getDictLabel(dictType, dictValue, SEPARATOR); + } + + /** + * 根据字典类型和字典标签获取字典值 + * + * @param dictType 字典类型 + * @param dictLabel 字典标签 + * @return 字典值 + */ + public static String getDictValue(String dictType, String dictLabel) + { + return getDictValue(dictType, dictLabel, SEPARATOR); + } + + /** + * 根据字典类型和字典值获取字典标签 + * + * @param dictType 字典类型 + * @param dictValue 字典值 + * @param separator 分隔符 + * @return 字典标签 + */ + public static String getDictLabel(String dictType, String dictValue, String separator) + { + StringBuilder propertyString = new StringBuilder(); + List datas = getDictCache(dictType); + + if (StringUtils.containsAny(separator, dictValue) && StringUtils.isNotEmpty(datas)) + { + for (AbstractDictData dict : datas) + { + for (String value : dictValue.split(separator)) + { + if (value.equals(dict.getDictValue())) + { + propertyString.append(dict.getDictLabel() + separator); + break; + } + } + } + } + else + { + for (AbstractDictData dict : datas) + { + if (dictValue.equals(dict.getDictValue())) + { + return dict.getDictLabel(); + } + } + } + return StringUtils.stripEnd(propertyString.toString(), separator); + } + + /** + * 根据字典类型和字典标签获取字典值 + * + * @param dictType 字典类型 + * @param dictLabel 字典标签 + * @param separator 分隔符 + * @return 字典值 + */ + public static String getDictValue(String dictType, String dictLabel, String separator) + { + StringBuilder propertyString = new StringBuilder(); + List datas = getDictCache(dictType); + + if (StringUtils.containsAny(separator, dictLabel) && StringUtils.isNotEmpty(datas)){ + for (AbstractDictData dict : datas) { + for (String label : dictLabel.split(separator)) { + if (label.equals(dict.getDictLabel())) { + propertyString.append(dict.getDictValue() + separator); + break; + } + } + } + } + else { + for (AbstractDictData dict : datas) { + if (dictLabel.equals(dict.getDictLabel())) { + return dict.getDictValue(); + } + } + } + return StringUtils.stripEnd(propertyString.toString(), separator); + } + + /** + * 删除指定字典缓存 + * + * @param key 字典键 + */ + public static void removeDictCache(String key) { + SpringContextHolder.getBean(RedisTemplate.class).delete(getCacheKey(key)); + } + + /** + * 清空字典缓存 + */ + public static void clearDictCache() { + Collection keys = SpringContextHolder.getBean(RedisTemplate.class).keys(CommonConst.SYS_DICT_KEY + "*"); + SpringContextHolder.getBean(RedisTemplate.class).delete(keys); + } + + /** + * 设置cache key + * + * @param configKey 参数键 + * @return 缓存键key + */ + public static String getCacheKey(String configKey) { + return CommonConst.SYS_DICT_KEY + configKey; + } + +} diff --git a/secret-boot-framework-dependencies/pom.xml b/secret-boot-framework-dependencies/pom.xml index 68bbb89..809a24d 100644 --- a/secret-boot-framework-dependencies/pom.xml +++ b/secret-boot-framework-dependencies/pom.xml @@ -42,12 +42,15 @@ 0.62.2 5.6.5 2.2.9 + 4.1.2 0.9.1 1.7.1 3.15.4 + + 6.5.2 3.2.1 2.9.1 @@ -235,6 +238,12 @@ easyexcel ${easyexcel.version} + + + org.apache.poi + poi-ooxml + ${poi.version} + io.jsonwebtoken @@ -253,6 +262,12 @@ redisson-spring-boot-starter ${redisson.version} + + + com.github.dozermapper + dozer-core + ${dozer.version} + diff --git a/secret-boot-framework-poi/pom.xml b/secret-boot-framework-poi/pom.xml new file mode 100644 index 0000000..02c41af --- /dev/null +++ b/secret-boot-framework-poi/pom.xml @@ -0,0 +1,27 @@ + + + + secret-boot-framework + com.gitee.secretopen + 1.6.0 + + 4.0.0 + + secret-boot-framework-poi + + + + com.gitee.secretopen + secret-boot-framework-core + + + + org.apache.poi + poi-ooxml + + + + + diff --git a/secret-boot-framework-poi/src/main/java/cn/chenc/framework/poi/annotation/Excel.java b/secret-boot-framework-poi/src/main/java/cn/chenc/framework/poi/annotation/Excel.java new file mode 100644 index 0000000..70c40ad --- /dev/null +++ b/secret-boot-framework-poi/src/main/java/cn/chenc/framework/poi/annotation/Excel.java @@ -0,0 +1,154 @@ +package cn.chenc.framework.poi.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import java.math.BigDecimal; + +/** + * 自定义导出Excel数据注解 + * + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.FIELD) +public @interface Excel { + /** + * 导出时在excel中排序 + */ + public int sort() default Integer.MAX_VALUE; + + /** + * 导出到Excel中的名字. + */ + public String name() default ""; + + /** + * 日期格式, 如: yyyy-MM-dd + */ + public String dateFormat() default ""; + + /** + * 如果是字典类型,请设置字典的type值 (如: sys_user_sex) + */ + public String dictType() default ""; + + /** + * 读取内容转表达式 (如: 0=男,1=女,2=未知) + */ + public String readConverterExp() default ""; + + /** + * 分隔符,读取字符串组内容 + */ + public String separator() default ","; + + /** + * BigDecimal 精度 默认:-1(默认不开启BigDecimal格式化) + */ + public int scale() default -1; + + /** + * BigDecimal 舍入规则 默认:BigDecimal.ROUND_HALF_EVEN + */ + public int roundingMode() default BigDecimal.ROUND_HALF_EVEN; + + /** + * 导出类型(0数字 1字符串) + */ + public ColumnType cellType() default ColumnType.STRING; + + /** + * 导出时在excel中每个列的高度 单位为字符 + */ + public double height() default 14; + + /** + * 导出时在excel中每个列的宽 单位为字符 + */ + public double width() default 16; + + /** + * 文字后缀,如% 90 变成90% + */ + public String suffix() default ""; + + /** + * 当值为空时,字段的默认值 + */ + public String defaultValue() default ""; + + /** + * 提示信息 + */ + public String prompt() default ""; + + /** + * 设置只能选择不能输入的列内容. + */ + public String[] combo() default {}; + + /** + * 是否导出数据,应对需求:有时我们需要导出一份模板,这是标题需要但内容需要用户手工填写. + */ + public boolean isExport() default true; + + /** + * 另一个类中的属性名称,支持多级获取,以小数点隔开 + */ + public String targetAttr() default ""; + + /** + * 是否自动统计数据,在最后追加一行统计数据总和 + */ + public boolean isStatistics() default false; + + /** + * 导出字段对齐方式(0:默认;1:靠左;2:居中;3:靠右) + */ + Align align() default Align.AUTO; + + public enum Align { + AUTO(0), LEFT(1), CENTER(2), RIGHT(3); + private final int value; + + Align(int value) { + this.value = value; + } + + public int value() { + return this.value; + } + } + + /** + * 字段类型(0:导出导入;1:仅导出;2:仅导入) + */ + Type type() default Type.ALL; + + public enum Type { + ALL(0), EXPORT(1), IMPORT(2); + private final int value; + + Type(int value) { + this.value = value; + } + + public int value() { + return this.value; + } + } + + public enum ColumnType { + NUMERIC(0), STRING(1), IMAGE(2); + private final int value; + + ColumnType(int value) { + this.value = value; + } + + public int value() { + return this.value; + } + } +} diff --git a/secret-boot-framework-poi/src/main/java/cn/chenc/framework/poi/annotation/Excels.java b/secret-boot-framework-poi/src/main/java/cn/chenc/framework/poi/annotation/Excels.java new file mode 100644 index 0000000..36b6614 --- /dev/null +++ b/secret-boot-framework-poi/src/main/java/cn/chenc/framework/poi/annotation/Excels.java @@ -0,0 +1,16 @@ +package cn.chenc.framework.poi.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Excel注解集 + * + */ +@Target(ElementType.FIELD) +@Retention(RetentionPolicy.RUNTIME) +public @interface Excels { + Excel[] value(); +} diff --git a/secret-boot-framework-poi/src/main/java/cn/chenc/framework/poi/util/ExcelUtil.java b/secret-boot-framework-poi/src/main/java/cn/chenc/framework/poi/util/ExcelUtil.java new file mode 100644 index 0000000..bfe737c --- /dev/null +++ b/secret-boot-framework-poi/src/main/java/cn/chenc/framework/poi/util/ExcelUtil.java @@ -0,0 +1,1027 @@ +package cn.chenc.framework.poi.util; + +import cn.chenc.framework.core.config.SecretConfig; +import cn.chenc.framework.core.exception.CustomException; +import cn.chenc.framework.core.model.response.AjaxResult; +import cn.chenc.framework.core.model.response.CustomCode; +import cn.chenc.framework.core.text.Convert; +import cn.chenc.framework.core.util.DateUtils; +import cn.chenc.framework.core.util.DictUtils; +import cn.chenc.framework.core.util.StringUtils; +import cn.chenc.framework.core.util.file.FileTypeUtils; +import cn.chenc.framework.core.util.file.ImageUtils; +import cn.chenc.framework.poi.annotation.Excel; +import cn.chenc.framework.poi.annotation.Excel.ColumnType; +import cn.chenc.framework.poi.annotation.Excel.Type; +import cn.chenc.framework.poi.annotation.Excels; +import org.apache.poi.ss.usermodel.*; +import org.apache.poi.ss.util.CellRangeAddressList; +import org.apache.poi.xssf.streaming.SXSSFWorkbook; +import org.apache.poi.xssf.usermodel.XSSFClientAnchor; +import org.apache.poi.xssf.usermodel.XSSFDataValidation; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.*; +import java.lang.reflect.Field; +import java.math.BigDecimal; +import java.text.DecimalFormat; +import java.util.*; +import java.util.stream.Collectors; + +/** + * Excel相关处理 + * + */ +public class ExcelUtil { + private static final Logger log = LoggerFactory.getLogger(ExcelUtil.class); + + /** + * Excel sheet最大行数,默认65536 + */ + public static final int sheetSize = 65536; + + /** + * 工作表名称 + */ + private String sheetName; + + /** + * 导出类型(EXPORT:导出数据;IMPORT:导入模板) + */ + private Type type; + + /** + * 工作薄对象 + */ + private Workbook wb; + + /** + * 工作表对象 + */ + private Sheet sheet; + + /** + * 样式列表 + */ + private Map styles; + + /** + * 导入导出数据列表 + */ + private List list; + + /** + * 注解列表 + */ + private List fields; + + /** + * 最大高度 + */ + private short maxHeight; + + /** + * 统计列表 + */ + private Map statistics = new HashMap(); + + /** + * 数字格式 + */ + private static final DecimalFormat DOUBLE_FORMAT = new DecimalFormat("######0.00"); + + /** + * 实体对象 + */ + public Class clazz; + + public ExcelUtil(Class clazz) + { + this.clazz = clazz; + } + + public void init(List list, String sheetName, Type type) + { + if (list == null) + { + list = new ArrayList(); + } + this.list = list; + this.sheetName = sheetName; + this.type = type; + createExcelField(); + createWorkbook(); + } + + /** + * 对excel表单默认第一个索引名转换成list + * + * @param is 输入流 + * @return 转换后集合 + */ + public List importExcel(InputStream is) throws Exception + { + return importExcel(StringUtils.EMPTY, is); + } + + /** + * 对excel表单指定表格索引名转换成list + * + * @param sheetName 表格索引名 + * @param is 输入流 + * @return 转换后集合 + */ + public List importExcel(String sheetName, InputStream is) throws Exception + { + this.type = Type.IMPORT; + this.wb = WorkbookFactory.create(is); + List list = new ArrayList(); + Sheet sheet = null; + if (StringUtils.isNotEmpty(sheetName)) + { + // 如果指定sheet名,则取指定sheet中的内容. + sheet = wb.getSheet(sheetName); + } + else + { + // 如果传入的sheet名不存在则默认指向第1个sheet. + sheet = wb.getSheetAt(0); + } + + if (sheet == null) + { + throw new IOException("文件sheet不存在"); + } + + int rows = sheet.getPhysicalNumberOfRows(); + + if (rows > 0) + { + // 定义一个map用于存放excel列的序号和field. + Map cellMap = new HashMap(); + // 获取表头 + Row heard = sheet.getRow(0); + for (int i = 0; i < heard.getPhysicalNumberOfCells(); i++) + { + Cell cell = heard.getCell(i); + if (StringUtils.isNotNull(cell)) + { + String value = this.getCellValue(heard, i).toString(); + cellMap.put(value, i); + } + else + { + cellMap.put(null, i); + } + } + // 有数据时才处理 得到类的所有field. + Field[] allFields = clazz.getDeclaredFields(); + // 定义一个map用于存放列的序号和field. + Map fieldsMap = new HashMap(); + for (int col = 0; col < allFields.length; col++) + { + Field field = allFields[col]; + Excel attr = field.getAnnotation(Excel.class); + if (attr != null && (attr.type() == Type.ALL || attr.type() == type)) + { + // 设置类的私有字段属性可访问. + field.setAccessible(true); + Integer column = cellMap.get(attr.name()); + if (column != null) + { + fieldsMap.put(column, field); + } + } + } + for (int i = 1; i < rows; i++) { + // 从第2行开始取数据,默认第一行是表头. + Row row = sheet.getRow(i); + if(row == null) { + continue; + } + T entity = null; + for (Map.Entry entry : fieldsMap.entrySet()) + { + Object val = this.getCellValue(row, entry.getKey()); + + // 如果不存在实例则新建. + entity = (entity == null ? clazz.newInstance() : entity); + // 从map中得到对应列的field. + Field field = fieldsMap.get(entry.getKey()); + // 取得类型,并根据对象类型设置值. + Class fieldType = field.getType(); + if (String.class == fieldType) + { + String s = Convert.toStr(val); + if (StringUtils.endsWith(s, ".0")) + { + val = StringUtils.substringBefore(s, ".0"); + } + else + { + String dateFormat = field.getAnnotation(Excel.class).dateFormat(); + if (StringUtils.isNotEmpty(dateFormat)) + { + val = DateUtils.format((Date)val, dateFormat); + } + else + { + val = Convert.toStr(val); + } + } + } + else if ((Integer.TYPE == fieldType || Integer.class == fieldType) && StringUtils.isNumeric(Convert.toStr(val))) + { + val = Convert.toInt(val); + } + else if (Long.TYPE == fieldType || Long.class == fieldType) + { + val = Convert.toLong(val); + } + else if (Double.TYPE == fieldType || Double.class == fieldType) + { + val = Convert.toDouble(val); + } + else if (Float.TYPE == fieldType || Float.class == fieldType) + { + val = Convert.toFloat(val); + } + else if (BigDecimal.class == fieldType) + { + val = Convert.toBigDecimal(val); + } + else if (Date.class == fieldType) + { + if (val instanceof String) + { + val = DateUtils.parseDate(val); + } + else if (val instanceof Double) + { + val = DateUtil.getJavaDate((Double) val); + } + } + else if (Boolean.TYPE == fieldType || Boolean.class == fieldType) + { + val = Convert.toBool(val, false); + } + if (StringUtils.isNotNull(fieldType)) + { + Excel attr = field.getAnnotation(Excel.class); + String propertyName = field.getName(); + if (StringUtils.isNotEmpty(attr.targetAttr())) + { + propertyName = field.getName() + "." + attr.targetAttr(); + } + else if (StringUtils.isNotEmpty(attr.readConverterExp())) + { + val = reverseByExp(Convert.toStr(val), attr.readConverterExp(), attr.separator()); + } + else if (StringUtils.isNotEmpty(attr.dictType())) + { + val = reverseDictByExp(Convert.toStr(val), attr.dictType(), attr.separator()); + } + ReflectUtils.invokeSetter(entity, propertyName, val); + } + } + list.add(entity); + } + } + return list; + } + + /** + * 对list数据源将其里面的数据导入到excel表单 + * + * @param list 导出数据集合 + * @param sheetName 工作表的名称 + * @return 结果 + */ + public AjaxResult exportExcel(List list, String sheetName) + { + this.init(list, sheetName, Type.EXPORT); + return exportExcel(); + } + + /** + * 对list数据源将其里面的数据导入到excel表单 + * + * @param sheetName 工作表的名称 + * @return 结果 + */ + public AjaxResult importTemplateExcel(String sheetName) + { + this.init(null, sheetName, Type.IMPORT); + return exportExcel(); + } + + /** + * 对list数据源将其里面的数据导入到excel表单 + * + * @return 结果 + */ + public AjaxResult exportExcel() { + OutputStream out = null; + try { + // 取出一共有多少个sheet. + double sheetNo = Math.ceil(list.size() / sheetSize); + for (int index = 0; index <= sheetNo; index++) { + createSheet(sheetNo, index); + + // 产生一行 + Row row = sheet.createRow(0); + int column = 0; + // 写入各个字段的列头名称 + for (Object[] os : fields) { + Excel excel = (Excel) os[1]; + this.createCell(excel, row, column++); + } + if (Type.EXPORT.equals(type)) { + fillExcelData(index, row); + addStatisticsRow(); + } + } + String filename = encodingFilename(sheetName); + out = new FileOutputStream(getAbsoluteFile(filename)); + wb.write(out); + return AjaxResult.success(filename); + } + catch (Exception e) { + log.error("导出Excel异常{}", e.getMessage()); + throw new CustomException(CustomCode.error("导出Excel失败,请联系网站管理员!")); + } + finally { + if (wb != null) { + try { + wb.close(); + } + catch (IOException e1) { + e1.printStackTrace(); + } + } + if (out != null) { + try { + out.close(); + } + catch (IOException e1) { + e1.printStackTrace(); + } + } + } + } + + /** + * 填充excel数据 + * + * @param index 序号 + * @param row 单元格行 + */ + public void fillExcelData(int index, Row row) { + int startNo = index * sheetSize; + int endNo = Math.min(startNo + sheetSize, list.size()); + for (int i = startNo; i < endNo; i++) + { + row = sheet.createRow(i + 1 - startNo); + // 得到导出对象. + T vo = (T) list.get(i); + int column = 0; + for (Object[] os : fields) + { + Field field = (Field) os[0]; + Excel excel = (Excel) os[1]; + // 设置实体类私有属性可访问 + field.setAccessible(true); + this.addCell(excel, row, vo, field, column++); + } + } + } + + /** + * 创建表格样式 + * + * @param wb 工作薄对象 + * @return 样式列表 + */ + private Map createStyles(Workbook wb) + { + // 写入各条记录,每条记录对应excel表中的一行 + Map styles = new HashMap(); + CellStyle style = wb.createCellStyle(); + style.setAlignment(HorizontalAlignment.CENTER); + style.setVerticalAlignment(VerticalAlignment.CENTER); + style.setBorderRight(BorderStyle.THIN); + style.setRightBorderColor(IndexedColors.GREY_50_PERCENT.getIndex()); + style.setBorderLeft(BorderStyle.THIN); + style.setLeftBorderColor(IndexedColors.GREY_50_PERCENT.getIndex()); + style.setBorderTop(BorderStyle.THIN); + style.setTopBorderColor(IndexedColors.GREY_50_PERCENT.getIndex()); + style.setBorderBottom(BorderStyle.THIN); + style.setBottomBorderColor(IndexedColors.GREY_50_PERCENT.getIndex()); + Font dataFont = wb.createFont(); + dataFont.setFontName("Arial"); + dataFont.setFontHeightInPoints((short) 10); + style.setFont(dataFont); + styles.put("data", style); + + style = wb.createCellStyle(); + style.cloneStyleFrom(styles.get("data")); + style.setAlignment(HorizontalAlignment.CENTER); + style.setVerticalAlignment(VerticalAlignment.CENTER); + style.setFillForegroundColor(IndexedColors.GREY_50_PERCENT.getIndex()); + style.setFillPattern(FillPatternType.SOLID_FOREGROUND); + Font headerFont = wb.createFont(); + headerFont.setFontName("Arial"); + headerFont.setFontHeightInPoints((short) 10); + headerFont.setBold(true); + headerFont.setColor(IndexedColors.WHITE.getIndex()); + style.setFont(headerFont); + styles.put("header", style); + + style = wb.createCellStyle(); + style.setAlignment(HorizontalAlignment.CENTER); + style.setVerticalAlignment(VerticalAlignment.CENTER); + Font totalFont = wb.createFont(); + totalFont.setFontName("Arial"); + totalFont.setFontHeightInPoints((short) 10); + style.setFont(totalFont); + styles.put("total", style); + + style = wb.createCellStyle(); + style.cloneStyleFrom(styles.get("data")); + style.setAlignment(HorizontalAlignment.LEFT); + styles.put("data1", style); + + style = wb.createCellStyle(); + style.cloneStyleFrom(styles.get("data")); + style.setAlignment(HorizontalAlignment.CENTER); + styles.put("data2", style); + + style = wb.createCellStyle(); + style.cloneStyleFrom(styles.get("data")); + style.setAlignment(HorizontalAlignment.RIGHT); + styles.put("data3", style); + + return styles; + } + + /** + * 创建单元格 + */ + public Cell createCell(Excel attr, Row row, int column) + { + // 创建列 + Cell cell = row.createCell(column); + // 写入列信息 + cell.setCellValue(attr.name()); + setDataValidation(attr, row, column); + cell.setCellStyle(styles.get("header")); + return cell; + } + + /** + * 设置单元格信息 + * + * @param value 单元格值 + * @param attr 注解相关 + * @param cell 单元格信息 + */ + public void setCellVo(Object value, Excel attr, Cell cell) + { + if (ColumnType.STRING == attr.cellType()) + { + cell.setCellValue(StringUtils.isNull(value) ? attr.defaultValue() : value + attr.suffix()); + } + else if (ColumnType.NUMERIC == attr.cellType()) + { + if (StringUtils.isNotNull(value)) + { + cell.setCellValue(StringUtils.contains(Convert.toStr(value), ".") ? Convert.toDouble(value) : Convert.toInt(value)); + } + } + else if (ColumnType.IMAGE == attr.cellType()) + { + ClientAnchor anchor = new XSSFClientAnchor(0, 0, 0, 0, (short) cell.getColumnIndex(), cell.getRow().getRowNum(), (short) (cell.getColumnIndex() + 1), + cell.getRow().getRowNum() + 1); + String imagePath = Convert.toStr(value); + if (StringUtils.isNotEmpty(imagePath)) + { + byte[] data = ImageUtils.getImage(imagePath); + getDrawingPatriarch(cell.getSheet()).createPicture(anchor, + cell.getSheet().getWorkbook().addPicture(data, getImageType(data))); + } + } + } + + /** + * 获取画布 + */ + public static Drawing getDrawingPatriarch(Sheet sheet) + { + if (sheet.getDrawingPatriarch() == null) + { + sheet.createDrawingPatriarch(); + } + return sheet.getDrawingPatriarch(); + } + + /** + * 获取图片类型,设置图片插入类型 + */ + public int getImageType(byte[] value) + { + String type = FileTypeUtils.getFileExtendName(value); + if ("JPG".equalsIgnoreCase(type)) + { + return Workbook.PICTURE_TYPE_JPEG; + } + else if ("PNG".equalsIgnoreCase(type)) + { + return Workbook.PICTURE_TYPE_PNG; + } + return Workbook.PICTURE_TYPE_JPEG; + } + + /** + * 创建表格样式 + */ + public void setDataValidation(Excel attr, Row row, int column) + { + if (attr.name().indexOf("注:") >= 0) + { + sheet.setColumnWidth(column, 6000); + } + else + { + // 设置列宽 + sheet.setColumnWidth(column, (int) ((attr.width() + 0.72) * 256)); + } + // 如果设置了提示信息则鼠标放上去提示. + if (StringUtils.isNotEmpty(attr.prompt())) + { + // 这里默认设了2-101列提示. + setXSSFPrompt(sheet, "", attr.prompt(), 1, 100, column, column); + } + // 如果设置了combo属性则本列只能选择不能输入 + if (attr.combo().length > 0) + { + // 这里默认设了2-101列只能选择不能输入. + setXSSFValidation(sheet, attr.combo(), 1, 100, column, column); + } + } + + /** + * 添加单元格 + */ + public Cell addCell(Excel attr, Row row, T vo, Field field, int column) + { + Cell cell = null; + try + { + // 设置行高 + row.setHeight(maxHeight); + // 根据Excel中设置情况决定是否导出,有些情况需要保持为空,希望用户填写这一列. + if (attr.isExport()) + { + // 创建cell + cell = row.createCell(column); + int align = attr.align().value(); + cell.setCellStyle(styles.get("data" + (align >= 1 && align <= 3 ? align : ""))); + + // 用于读取对象中的属性 + Object value = getTargetValue(vo, field, attr); + String dateFormat = attr.dateFormat(); + String readConverterExp = attr.readConverterExp(); + String separator = attr.separator(); + String dictType = attr.dictType(); + if (StringUtils.isNotEmpty(dateFormat) && StringUtils.isNotNull(value)) + { + cell.setCellValue(DateUtils.format((Date) value, dateFormat)); + } + else if (StringUtils.isNotEmpty(readConverterExp) && StringUtils.isNotNull(value)) + { + cell.setCellValue(convertByExp(Convert.toStr(value), readConverterExp, separator)); + } + else if (StringUtils.isNotEmpty(dictType) && StringUtils.isNotNull(value)) + { + cell.setCellValue(convertDictByExp(Convert.toStr(value), dictType, separator)); + } + else if (value instanceof BigDecimal && -1 != attr.scale()) + { + cell.setCellValue((((BigDecimal) value).setScale(attr.scale(), attr.roundingMode())).toString()); + } + else + { + // 设置列类型 + setCellVo(value, attr, cell); + } + addStatisticsData(column, Convert.toStr(value), attr); + } + } + catch (Exception e) + { + log.error("导出Excel失败{}", e); + } + return cell; + } + + /** + * 设置 POI XSSFSheet 单元格提示 + * + * @param sheet 表单 + * @param promptTitle 提示标题 + * @param promptContent 提示内容 + * @param firstRow 开始行 + * @param endRow 结束行 + * @param firstCol 开始列 + * @param endCol 结束列 + */ + public void setXSSFPrompt(Sheet sheet, String promptTitle, String promptContent, int firstRow, int endRow, + int firstCol, int endCol) { + DataValidationHelper helper = sheet.getDataValidationHelper(); + DataValidationConstraint constraint = helper.createCustomConstraint("DD1"); + CellRangeAddressList regions = new CellRangeAddressList(firstRow, endRow, firstCol, endCol); + DataValidation dataValidation = helper.createValidation(constraint, regions); + dataValidation.createPromptBox(promptTitle, promptContent); + dataValidation.setShowPromptBox(true); + sheet.addValidationData(dataValidation); + } + + /** + * 设置某些列的值只能输入预制的数据,显示下拉框. + * + * @param sheet 要设置的sheet. + * @param textlist 下拉框显示的内容 + * @param firstRow 开始行 + * @param endRow 结束行 + * @param firstCol 开始列 + * @param endCol 结束列 + * @return 设置好的sheet. + */ + public void setXSSFValidation(Sheet sheet, String[] textlist, int firstRow, int endRow, int firstCol, int endCol) + { + DataValidationHelper helper = sheet.getDataValidationHelper(); + // 加载下拉列表内容 + DataValidationConstraint constraint = helper.createExplicitListConstraint(textlist); + // 设置数据有效性加载在哪个单元格上,四个参数分别是:起始行、终止行、起始列、终止列 + CellRangeAddressList regions = new CellRangeAddressList(firstRow, endRow, firstCol, endCol); + // 数据有效性对象 + DataValidation dataValidation = helper.createValidation(constraint, regions); + // 处理Excel兼容性问题 + if (dataValidation instanceof XSSFDataValidation) + { + dataValidation.setSuppressDropDownArrow(true); + dataValidation.setShowErrorBox(true); + } + else + { + dataValidation.setSuppressDropDownArrow(false); + } + + sheet.addValidationData(dataValidation); + } + + /** + * 解析导出值 0=男,1=女,2=未知 + * + * @param propertyValue 参数值 + * @param converterExp 翻译注解 + * @param separator 分隔符 + * @return 解析后值 + */ + public static String convertByExp(String propertyValue, String converterExp, String separator) + { + StringBuilder propertyString = new StringBuilder(); + String[] convertSource = converterExp.split(","); + for (String item : convertSource) + { + String[] itemArray = item.split("="); + if (StringUtils.containsAny(separator, propertyValue)) + { + for (String value : propertyValue.split(separator)) + { + if (itemArray[0].equals(value)) + { + propertyString.append(itemArray[1] + separator); + break; + } + } + } + else + { + if (itemArray[0].equals(propertyValue)) + { + return itemArray[1]; + } + } + } + return StringUtils.stripEnd(propertyString.toString(), separator); + } + + /** + * 反向解析值 男=0,女=1,未知=2 + * + * @param propertyValue 参数值 + * @param converterExp 翻译注解 + * @param separator 分隔符 + * @return 解析后值 + */ + public static String reverseByExp(String propertyValue, String converterExp, String separator) + { + StringBuilder propertyString = new StringBuilder(); + String[] convertSource = converterExp.split(","); + for (String item : convertSource) + { + String[] itemArray = item.split("="); + if (StringUtils.containsAny(separator, propertyValue)) + { + for (String value : propertyValue.split(separator)) + { + if (itemArray[1].equals(value)) + { + propertyString.append(itemArray[0] + separator); + break; + } + } + } + else + { + if (itemArray[1].equals(propertyValue)) + { + return itemArray[0]; + } + } + } + return StringUtils.stripEnd(propertyString.toString(), separator); + } + + /** + * 解析字典值 + * + * @param dictValue 字典值 + * @param dictType 字典类型 + * @param separator 分隔符 + * @return 字典标签 + */ + public static String convertDictByExp(String dictValue, String dictType, String separator) + { + return DictUtils.getDictLabel(dictType, dictValue, separator); + } + + /** + * 反向解析值字典值 + * + * @param dictLabel 字典标签 + * @param dictType 字典类型 + * @param separator 分隔符 + * @return 字典值 + */ + public static String reverseDictByExp(String dictLabel, String dictType, String separator) + { + return DictUtils.getDictValue(dictType, dictLabel, separator); + } + + /** + * 合计统计信息 + */ + private void addStatisticsData(Integer index, String text, Excel entity) + { + if (entity != null && entity.isStatistics()) + { + Double temp = 0D; + if (!statistics.containsKey(index)) + { + statistics.put(index, temp); + } + try + { + temp = Double.valueOf(text); + } + catch (NumberFormatException e) + { + } + statistics.put(index, statistics.get(index) + temp); + } + } + + /** + * 创建统计行 + */ + public void addStatisticsRow() + { + if (statistics.size() > 0) + { + Cell cell = null; + Row row = sheet.createRow(sheet.getLastRowNum() + 1); + Set keys = statistics.keySet(); + cell = row.createCell(0); + cell.setCellStyle(styles.get("total")); + cell.setCellValue("合计"); + + for (Integer key : keys) + { + cell = row.createCell(key); + cell.setCellStyle(styles.get("total")); + cell.setCellValue(DOUBLE_FORMAT.format(statistics.get(key))); + } + statistics.clear(); + } + } + + /** + * 编码文件名 + */ + public String encodingFilename(String filename) { + filename = UUID.randomUUID().toString() + "_" + filename + ".xlsx"; + return filename; + } + + /** + * 获取下载路径 + * + * @param filename 文件名称 + */ + public String getAbsoluteFile(String filename) + { + String downloadPath = SecretConfig.getDownloadPath() + filename; + File desc = new File(downloadPath); + if (!desc.getParentFile().exists()) + { + desc.getParentFile().mkdirs(); + } + return downloadPath; + } + + /** + * 获取bean中的属性值 + * + * @param vo 实体对象 + * @param field 字段 + * @param excel 注解 + * @return 最终的属性值 + * @throws Exception + */ + private Object getTargetValue(T vo, Field field, Excel excel) throws Exception + { + Object o = field.get(vo); + if (StringUtils.isNotEmpty(excel.targetAttr())) + { + String target = excel.targetAttr(); + if (target.indexOf(".") > -1) + { + String[] targets = target.split("[.]"); + for (String name : targets) + { + o = getValue(o, name); + } + } + else + { + o = getValue(o, target); + } + } + return o; + } + + /** + * 以类的属性的get方法方法形式获取值 + * + * @param o + * @param name + * @return value + * @throws Exception + */ + private Object getValue(Object o, String name) throws Exception { + if (StringUtils.isNotNull(o) && StringUtils.isNotEmpty(name)) { + Class clazz = o.getClass(); + Field field = clazz.getDeclaredField(name); + field.setAccessible(true); + o = field.get(o); + } + return o; + } + + /** + * 得到所有定义字段 + */ + private void createExcelField() { + this.fields = new ArrayList(); + List tempFields = new ArrayList<>(); + tempFields.addAll(Arrays.asList(clazz.getSuperclass().getDeclaredFields())); + tempFields.addAll(Arrays.asList(clazz.getDeclaredFields())); + for (Field field : tempFields) { + // 单注解 + if (field.isAnnotationPresent(Excel.class)) { + putToField(field, field.getAnnotation(Excel.class)); + } + + // 多注解 + if (field.isAnnotationPresent(Excels.class)) { + Excels attrs = field.getAnnotation(Excels.class); + Excel[] excels = attrs.value(); + for (Excel excel : excels) { + putToField(field, excel); + } + } + } + this.fields = this.fields.stream().sorted(Comparator.comparing(objects -> ((Excel) objects[1]).sort())).collect(Collectors.toList()); + this.maxHeight = getRowHeight(); + } + + /** + * 根据注解获取最大行高 + */ + public short getRowHeight() { + double maxHeight = 0; + for (Object[] os : this.fields) { + Excel excel = (Excel) os[1]; + maxHeight = maxHeight > excel.height() ? maxHeight : excel.height(); + } + return (short) (maxHeight * 20); + } + + /** + * 放到字段集合中 + */ + private void putToField(Field field, Excel attr) { + if (attr != null && (attr.type() == Type.ALL || attr.type() == type)) { + this.fields.add(new Object[] { field, attr }); + } + } + + /** + * 创建一个工作簿 + */ + public void createWorkbook() + { + this.wb = new SXSSFWorkbook(500); + } + + /** + * 创建工作表 + * + * @param sheetNo sheet数量 + * @param index 序号 + */ + public void createSheet(double sheetNo, int index) { + this.sheet = wb.createSheet(); + this.styles = createStyles(wb); + // 设置工作表的名称. + if (sheetNo == 0) { + wb.setSheetName(index, sheetName); + } + else { + wb.setSheetName(index, sheetName + index); + } + } + + /** + * 获取单元格值 + * + * @param row 获取的行 + * @param column 获取单元格列号 + * @return 单元格值 + */ + public Object getCellValue(Row row, int column) { + if (row == null) { + return row; + } + Object val = ""; + try { + Cell cell = row.getCell(column); + if (StringUtils.isNotNull(cell)) { + if (cell.getCellType() == CellType.NUMERIC || cell.getCellType() == CellType.FORMULA) { + val = cell.getNumericCellValue(); + if (DateUtil.isCellDateFormatted(cell)) { + val = DateUtil.getJavaDate((Double) val); // POI Excel 日期格式转换 + } + else { + if ((Double) val % 1 != 0) { + val = new BigDecimal(val.toString()); + } + else + { + val = new DecimalFormat("0").format(val); + } + } + } + else if (cell.getCellType() == CellType.STRING) { + val = cell.getStringCellValue(); + } + else if (cell.getCellType() == CellType.BOOLEAN) { + val = cell.getBooleanCellValue(); + } + else if (cell.getCellType() == CellType.ERROR) + { + val = cell.getErrorCellValue(); + } + + } + } + catch (Exception e) + { + return val; + } + return val; + } +} diff --git a/secret-boot-framework-poi/src/main/java/cn/chenc/framework/poi/util/ReflectUtils.java b/secret-boot-framework-poi/src/main/java/cn/chenc/framework/poi/util/ReflectUtils.java new file mode 100644 index 0000000..93f0311 --- /dev/null +++ b/secret-boot-framework-poi/src/main/java/cn/chenc/framework/poi/util/ReflectUtils.java @@ -0,0 +1,330 @@ +package cn.chenc.framework.poi.util; + + +import cn.chenc.framework.core.text.Convert; +import cn.chenc.framework.core.util.DateUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.Validate; +import org.apache.poi.ss.usermodel.DateUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.lang.reflect.*; +import java.util.Date; + +/** + * 反射工具类. 提供调用getter/setter方法, 访问私有变量, 调用私有方法, 获取泛型类型Class, 被AOP过的真实类等工具函数. + * + */ +@SuppressWarnings("rawtypes") +public class ReflectUtils { + private static final String SETTER_PREFIX = "set"; + + private static final String GETTER_PREFIX = "get"; + + private static final String CGLIB_CLASS_SEPARATOR = "$$"; + + private static Logger logger = LoggerFactory.getLogger(ReflectUtils.class); + + /** + * 调用Getter方法. + * 支持多级,如:对象名.对象名.方法 + */ + @SuppressWarnings("unchecked") + public static E invokeGetter(Object obj, String propertyName) { + Object object = obj; + for (String name : StringUtils.split(propertyName, ".")) { + String getterMethodName = GETTER_PREFIX + StringUtils.capitalize(name); + object = invokeMethod(object, getterMethodName, new Class[] {}, new Object[] {}); + } + return (E) object; + } + + /** + * 调用Setter方法, 仅匹配方法名。 + * 支持多级,如:对象名.对象名.方法 + */ + public static void invokeSetter(Object obj, String propertyName, E value) { + Object object = obj; + String[] names = StringUtils.split(propertyName, "."); + for (int i = 0; i < names.length; i++) { + if (i < names.length - 1) { + String getterMethodName = GETTER_PREFIX + StringUtils.capitalize(names[i]); + object = invokeMethod(object, getterMethodName, new Class[] {}, new Object[] {}); + } + else { + String setterMethodName = SETTER_PREFIX + StringUtils.capitalize(names[i]); + invokeMethodByName(object, setterMethodName, new Object[] { value }); + } + } + } + + /** + * 直接读取对象属性值, 无视private/protected修饰符, 不经过getter函数. + */ + @SuppressWarnings("unchecked") + public static E getFieldValue(final Object obj, final String fieldName) { + Field field = getAccessibleField(obj, fieldName); + if (field == null) { + logger.debug("在 [" + obj.getClass() + "] 中,没有找到 [" + fieldName + "] 字段 "); + return null; + } + E result = null; + try { + result = (E) field.get(obj); + } + catch (IllegalAccessException e) + { + logger.error("不可能抛出的异常{}", e.getMessage()); + } + return result; + } + + /** + * 直接设置对象属性值, 无视private/protected修饰符, 不经过setter函数. + */ + public static void setFieldValue(final Object obj, final String fieldName, final E value) { + Field field = getAccessibleField(obj, fieldName); + if (field == null) { + // throw new IllegalArgumentException("在 [" + obj.getClass() + "] 中,没有找到 [" + fieldName + "] 字段 "); + logger.debug("在 [" + obj.getClass() + "] 中,没有找到 [" + fieldName + "] 字段 "); + return; + } + try { + field.set(obj, value); + } + catch (IllegalAccessException e) { + logger.error("不可能抛出的异常: {}", e.getMessage()); + } + } + + /** + * 直接调用对象方法, 无视private/protected修饰符. + * 用于一次性调用的情况,否则应使用getAccessibleMethod()函数获得Method后反复调用. + * 同时匹配方法名+参数类型, + */ + @SuppressWarnings("unchecked") + public static E invokeMethod(final Object obj, final String methodName, final Class[] parameterTypes, + final Object[] args) { + if (obj == null || methodName == null) { + return null; + } + Method method = getAccessibleMethod(obj, methodName, parameterTypes); + if (method == null) { + logger.debug("在 [" + obj.getClass() + "] 中,没有找到 [" + methodName + "] 方法 "); + return null; + } try { + return (E) method.invoke(obj, args); + } catch (Exception e) { + String msg = "method: " + method + ", obj: " + obj + ", args: " + args + ""; + throw convertReflectionExceptionToUnchecked(msg, e); + } + } + + /** + * 直接调用对象方法, 无视private/protected修饰符, + * 用于一次性调用的情况,否则应使用getAccessibleMethodByName()函数获得Method后反复调用. + * 只匹配函数名,如果有多个同名函数调用第一个。 + */ + @SuppressWarnings("unchecked") + public static E invokeMethodByName(final Object obj, final String methodName, final Object[] args) { + Method method = getAccessibleMethodByName(obj, methodName, args.length); + if (method == null) { + // 如果为空不报错,直接返回空。 + logger.debug("在 [" + obj.getClass() + "] 中,没有找到 [" + methodName + "] 方法 "); + return null; + } try { + // 类型转换(将参数数据类型转换为目标方法参数类型) + Class[] cs = method.getParameterTypes(); + for (int i = 0; i < cs.length; i++) { + if (args[i] != null && !args[i].getClass().equals(cs[i])) { + if (cs[i] == String.class) { + args[i] = Convert.toStr(args[i]); + if (StringUtils.endsWith((String) args[i], ".0")) { + args[i] = StringUtils.substringBefore((String) args[i], ".0"); + } + } else if (cs[i] == Integer.class) { + args[i] = Convert.toInt(args[i]); + } else if (cs[i] == Long.class) { + args[i] = Convert.toLong(args[i]); + } else if (cs[i] == Double.class) { + args[i] = Convert.toDouble(args[i]); + } + else if (cs[i] == Float.class) { + args[i] = Convert.toFloat(args[i]); + } + else if (cs[i] == Date.class) { + if (args[i] instanceof String) { + args[i] = DateUtils.parseDate(args[i]); + } else { + args[i] = DateUtil.getJavaDate((Double) args[i]); + } + } else if (cs[i] == boolean.class || cs[i] == Boolean.class) { + args[i] = Convert.toBool(args[i]); + } + } + } + return (E) method.invoke(obj, args); + } catch (Exception e) { + String msg = "method: " + method + ", obj: " + obj + ", args: " + args + ""; + throw convertReflectionExceptionToUnchecked(msg, e); + } + } + + /** + * 循环向上转型, 获取对象的DeclaredField, 并强制设置为可访问. + * 如向上转型到Object仍无法找到, 返回null. + */ + public static Field getAccessibleField(final Object obj, final String fieldName) { + // 为空不报错。直接返回 null + if (obj == null) { + return null; + } + Validate.notBlank(fieldName, "fieldName can't be blank"); + for (Class superClass = obj.getClass(); superClass != Object.class; superClass = superClass.getSuperclass()) { + try { + Field field = superClass.getDeclaredField(fieldName); + makeAccessible(field); + return field; + } catch (NoSuchFieldException e) { + continue; + } + } + return null; + } + + /** + * 循环向上转型, 获取对象的DeclaredMethod,并强制设置为可访问. + * 如向上转型到Object仍无法找到, 返回null. + * 匹配函数名+参数类型。 + * 用于方法需要被多次调用的情况. 先使用本函数先取得Method,然后调用Method.invoke(Object obj, Object... args) + */ + public static Method getAccessibleMethod(final Object obj, final String methodName, + final Class... parameterTypes) { + // 为空不报错。直接返回 null + if (obj == null) { + return null; + } + Validate.notBlank(methodName, "methodName can't be blank"); + for (Class searchType = obj.getClass(); searchType != Object.class; searchType = searchType.getSuperclass()) { + try { + Method method = searchType.getDeclaredMethod(methodName, parameterTypes); + makeAccessible(method); + return method; + } + catch (NoSuchMethodException e) { + continue; + } + } + return null; + } + + /** + * 循环向上转型, 获取对象的DeclaredMethod,并强制设置为可访问. + * 如向上转型到Object仍无法找到, 返回null. + * 只匹配函数名。 + * 用于方法需要被多次调用的情况. 先使用本函数先取得Method,然后调用Method.invoke(Object obj, Object... args) + */ + public static Method getAccessibleMethodByName(final Object obj, final String methodName, int argsNum) { + // 为空不报错。直接返回 null + if (obj == null) { + return null; + } + Validate.notBlank(methodName, "methodName can't be blank"); + for (Class searchType = obj.getClass(); searchType != Object.class; searchType = searchType.getSuperclass()) { + Method[] methods = searchType.getDeclaredMethods(); + for (Method method : methods) { + if (method.getName().equals(methodName) && method.getParameterTypes().length == argsNum) { + makeAccessible(method); + return method; + } + } + } + return null; + } + + /** + * 改变private/protected的方法为public,尽量不调用实际改动的语句,避免JDK的SecurityManager抱怨。 + */ + public static void makeAccessible(Method method) { + if ((!Modifier.isPublic(method.getModifiers()) || !Modifier.isPublic(method.getDeclaringClass().getModifiers())) + && !method.isAccessible()) { + method.setAccessible(true); + } + } + + /** + * 改变private/protected的成员变量为public,尽量不调用实际改动的语句,避免JDK的SecurityManager抱怨。 + */ + public static void makeAccessible(Field field) { + if ((!Modifier.isPublic(field.getModifiers()) || !Modifier.isPublic(field.getDeclaringClass().getModifiers()) + || Modifier.isFinal(field.getModifiers())) && !field.isAccessible()) { + field.setAccessible(true); + } + } + + /** + * 通过反射, 获得Class定义中声明的泛型参数的类型, 注意泛型必须定义在父类处 + * 如无法找到, 返回Object.class. + */ + @SuppressWarnings("unchecked") + public static Class getClassGenricType(final Class clazz) { + return getClassGenricType(clazz, 0); + } + + /** + * 通过反射, 获得Class定义中声明的父类的泛型参数的类型. + * 如无法找到, 返回Object.class. + */ + public static Class getClassGenricType(final Class clazz, final int index) { + Type genType = clazz.getGenericSuperclass(); + + if (!(genType instanceof ParameterizedType)) { + logger.debug(clazz.getSimpleName() + "'s superclass not ParameterizedType"); + return Object.class; + } + + Type[] params = ((ParameterizedType) genType).getActualTypeArguments(); + + if (index >= params.length || index < 0) { + logger.debug("Index: " + index + ", Size of " + clazz.getSimpleName() + "'s Parameterized Type: " + + params.length); + return Object.class; + } + if (!(params[index] instanceof Class)) { + logger.debug(clazz.getSimpleName() + " not set the actual class on superclass generic parameter"); + return Object.class; + } + + return (Class) params[index]; + } + + public static Class getUserClass(Object instance) { + if (instance == null) { + throw new RuntimeException("Instance must not be null"); + } + Class clazz = instance.getClass(); + if (clazz != null && clazz.getName().contains(CGLIB_CLASS_SEPARATOR)) { + Class superClass = clazz.getSuperclass(); + if (superClass != null && !Object.class.equals(superClass)) { + return superClass; + } + } + return clazz; + + } + + /** + * 将反射时的checked exception转换为unchecked exception. + */ + public static RuntimeException convertReflectionExceptionToUnchecked(String msg, Exception e) { + if (e instanceof IllegalAccessException || e instanceof IllegalArgumentException + || e instanceof NoSuchMethodException) { + return new IllegalArgumentException(msg, e); + } + else if (e instanceof InvocationTargetException) { + return new RuntimeException(msg, ((InvocationTargetException) e).getTargetException()); + } + return new RuntimeException(msg, e); + } +} -- Gitee From 21b712c6a935720a784755968e03ffe14f18d2f6 Mon Sep 17 00:00:00 2001 From: secret <1029693356@qq.com> Date: Mon, 26 Jul 2021 23:31:28 +0800 Subject: [PATCH 05/11] =?UTF-8?q?=E6=96=B0=E5=A2=9Edozer=E6=A8=A1=E5=9D=97?= =?UTF-8?q?,=E6=8F=90=E4=BE=9B=E5=B0=81=E8=A3=85=E5=B7=A5=E5=85=B7DozerTem?= =?UTF-8?q?plate?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- secret-boot-framework-core/pom.xml | 5 - secret-boot-framework-dependencies/pom.xml | 25 +++- secret-boot-framework-dozer/pom.xml | 29 ++++ .../dozer/component/DozerTemplate.java | 128 ++++++++++++++++++ .../dozer/config/DozerConfiguration.java | 57 ++++++++ .../dozer/properties/DozerProperties.java | 64 +++++++++ .../src/main/resources/dozer/global.dozer.xml | 18 +++ 7 files changed, 314 insertions(+), 12 deletions(-) create mode 100644 secret-boot-framework-dozer/pom.xml create mode 100644 secret-boot-framework-dozer/src/main/java/cn/chenc/framework/dozer/component/DozerTemplate.java create mode 100644 secret-boot-framework-dozer/src/main/java/cn/chenc/framework/dozer/config/DozerConfiguration.java create mode 100644 secret-boot-framework-dozer/src/main/java/cn/chenc/framework/dozer/properties/DozerProperties.java create mode 100644 secret-boot-framework-dozer/src/main/resources/dozer/global.dozer.xml diff --git a/secret-boot-framework-core/pom.xml b/secret-boot-framework-core/pom.xml index 5a0a137..20cc290 100644 --- a/secret-boot-framework-core/pom.xml +++ b/secret-boot-framework-core/pom.xml @@ -130,11 +130,6 @@ io.jsonwebtoken jjwt - - - com.github.dozermapper - dozer-core - diff --git a/secret-boot-framework-dependencies/pom.xml b/secret-boot-framework-dependencies/pom.xml index 809a24d..227dd55 100644 --- a/secret-boot-framework-dependencies/pom.xml +++ b/secret-boot-framework-dependencies/pom.xml @@ -100,6 +100,11 @@ secret-boot-framework-mail ${secret-boot.version} + + ${project.groupId} + secret-boot-framework-poi + ${secret-boot.version} + ${project.groupId} secret-boot-framework-security @@ -121,23 +126,25 @@ mysql-connector-java ${mysql-connector-java.version} + com.baomidou mybatis-plus-boot-starter ${mybatis-plus.version} - + com.alibaba druid-spring-boot-starter ${druid.version} + com.squareup.okhttp3 okhttp ${okhttp.version} - + commons-fileupload commons-fileupload @@ -174,19 +181,19 @@ ant ${ant.version} - - + org.apache.httpcomponents httpclient ${httpclient.version} - + org.projectlombok lombok ${lombok.version} + io.springfox springfox-swagger2 @@ -197,6 +204,7 @@ springfox-swagger-ui ${springfox-swagger.version} + com.google.guava guava @@ -223,7 +231,6 @@ ${flexmark.version} - cn.hutool @@ -231,7 +238,6 @@ ${hutool.version} compile - com.alibaba @@ -268,6 +274,11 @@ dozer-core ${dozer.version} + + com.github.dozermapper + dozer-spring4 + ${dozer.version} + diff --git a/secret-boot-framework-dozer/pom.xml b/secret-boot-framework-dozer/pom.xml new file mode 100644 index 0000000..a1d374d --- /dev/null +++ b/secret-boot-framework-dozer/pom.xml @@ -0,0 +1,29 @@ + + + + secret-boot-framework + com.gitee.secretopen + 1.6.0 + + 4.0.0 + + secret-boot-framework-dozer + + + + org.springframework.boot + spring-boot-autoconfigure + + + + com.github.dozermapper + dozer-core + + + com.github.dozermapper + dozer-spring4 + + + diff --git a/secret-boot-framework-dozer/src/main/java/cn/chenc/framework/dozer/component/DozerTemplate.java b/secret-boot-framework-dozer/src/main/java/cn/chenc/framework/dozer/component/DozerTemplate.java new file mode 100644 index 0000000..08319d9 --- /dev/null +++ b/secret-boot-framework-dozer/src/main/java/cn/chenc/framework/dozer/component/DozerTemplate.java @@ -0,0 +1,128 @@ +package cn.chenc.framework.dozer.component; + +import com.github.dozermapper.core.Mapper; + +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +/** + *  @description: TODO + *  @author secret + *  @date 2021/7/26 23:25 + * + */ +public class DozerTemplate { + private Mapper mapper; + + public DozerTemplate(Mapper mapper) { + this.mapper = mapper; + } + + public Mapper getMapper() { + return this.mapper; + } + + /** + * Constructs new instance of destinationClass and performs mapping between from source + * + * @param source + * @param destinationClass + * @param + * @return + */ + public T map(Object source, Class destinationClass) { + if (source == null) { + return null; + } + return mapper.map(source, destinationClass); + } + + public T map2(Object source, Class destinationClass) { + if (source == null) { + try { + return destinationClass.newInstance(); + } catch (Exception e) { + } + } + return mapper.map(source, destinationClass); + } + + /** + * Performs mapping between source and destination objects + * + * @param source + * @param destination + */ + public void map(Object source, Object destination) { + if (source == null) { + return; + } + mapper.map(source, destination); + } + + /** + * Constructs new instance of destinationClass and performs mapping between from source + * + * @param source + * @param destinationClass + * @param mapId + * @param + * @return + */ + public T map(Object source, Class destinationClass, String mapId) { + if (source == null) { + return null; + } + return mapper.map(source, destinationClass, mapId); + } + + /** + * Performs mapping between source and destination objects + * + * @param source + * @param destination + * @param mapId + */ + public void map(Object source, Object destination, String mapId) { + if (source == null) { + return; + } + mapper.map(source, destination, mapId); + } + + /** + * 将集合转成集合 + * List --> List + * + * @param sourceList 源集合 + * @param destinationClass 待转类型 + * @param + * @return + */ + public List mapList(Collection sourceList, Class destinationClass) { + return mapPage(sourceList, destinationClass); + } + + + public List mapPage(Collection sourceList, Class destinationClass) { + if (sourceList == null || sourceList.isEmpty() || destinationClass == null) { + return Collections.emptyList(); + } + List destinationList = sourceList.parallelStream() + .filter(item -> item != null) + .map((sourceObject) -> mapper.map(sourceObject, destinationClass)) + .collect(Collectors.toList()); + + return destinationList; + } + + public Set mapSet(Collection sourceList, Class destinationClass) { + if (sourceList == null || sourceList.isEmpty() || destinationClass == null) { + return Collections.emptySet(); + } + return sourceList.parallelStream().map((sourceObject) -> mapper.map(sourceObject, destinationClass)).collect(Collectors.toSet()); + } +} diff --git a/secret-boot-framework-dozer/src/main/java/cn/chenc/framework/dozer/config/DozerConfiguration.java b/secret-boot-framework-dozer/src/main/java/cn/chenc/framework/dozer/config/DozerConfiguration.java new file mode 100644 index 0000000..0c33395 --- /dev/null +++ b/secret-boot-framework-dozer/src/main/java/cn/chenc/framework/dozer/config/DozerConfiguration.java @@ -0,0 +1,57 @@ +package cn.chenc.framework.dozer.config; + +import cn.chenc.framework.dozer.component.DozerTemplate; +import cn.chenc.framework.dozer.properties.DozerProperties; +import com.github.dozermapper.core.Mapper; +import com.github.dozermapper.spring.DozerBeanMapperFactoryBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import java.io.IOException; + +/** + *  @description: Dozer配置 + *  @author secret + *  @date 2021/7/26 23:07 + * + */ +@Configuration +@ConditionalOnClass({DozerBeanMapperFactoryBean.class, Mapper.class}) +@ConditionalOnMissingBean(Mapper.class) +@EnableConfigurationProperties(DozerProperties.class) +public class DozerConfiguration { + private final DozerProperties properties; + + + /** + * Constructor for creating auto configuration. + * + * @param properties properties + */ + public DozerConfiguration(DozerProperties properties) { + this.properties = properties; + } + + @Bean + public DozerTemplate getDozerUtil(Mapper mapper) { + return new DozerTemplate(mapper); + } + + /** + * Creates default Dozer mapper + * + * @return Dozer mapper + * @throws IOException if there is an exception during initialization. + */ + @Bean + public DozerBeanMapperFactoryBean dozerMapper() throws IOException { + DozerBeanMapperFactoryBean factoryBean = new DozerBeanMapperFactoryBean(); + // 官方这样子写,没法用 匹配符! + //factoryBean.setMappingFiles(properties.getMappingFiles()); + factoryBean.setMappingFiles(properties.resolveMapperLocations()); + return factoryBean; + } +} diff --git a/secret-boot-framework-dozer/src/main/java/cn/chenc/framework/dozer/properties/DozerProperties.java b/secret-boot-framework-dozer/src/main/java/cn/chenc/framework/dozer/properties/DozerProperties.java new file mode 100644 index 0000000..bc34d8f --- /dev/null +++ b/secret-boot-framework-dozer/src/main/java/cn/chenc/framework/dozer/properties/DozerProperties.java @@ -0,0 +1,64 @@ +package cn.chenc.framework.dozer.properties; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.core.io.Resource; +import org.springframework.core.io.support.PathMatchingResourcePatternResolver; +import org.springframework.core.io.support.ResourcePatternResolver; +import org.springframework.stereotype.Component; + +import java.io.IOException; +import java.util.Arrays; +import java.util.Optional; +import java.util.stream.Stream; + +/** + *  @description: Dozer属性 + *  @author secret + *  @date 2021/7/26 23:01 + * + */ +@Component +@ConfigurationProperties(prefix = "dozer") +public class DozerProperties { + private static final ResourcePatternResolver PATTERN_RESOLVER = new PathMatchingResourcePatternResolver(); + + /** + * Mapping files configuration. + * For example "classpath:*.dozer.xml". + */ + private String[] mappingFiles = new String[]{"classpath*:dozer/*.dozer.xml"}; + + /** + * Mapping files configuration. + * + * @return mapping files + */ + public String[] getMappingFiles() { + return Arrays.copyOf(mappingFiles, mappingFiles.length); + } + + /** + * Set mapping files configuration. For example classpath:*.dozer.xml. + * + * @param mappingFiles dozer mapping files + * @return dozer properties + */ + public DozerProperties setMappingFiles(String[] mappingFiles) { + this.mappingFiles = Arrays.copyOf(mappingFiles, mappingFiles.length); + return this; + } + + public Resource[] resolveMapperLocations() { + return Stream.of(Optional.ofNullable(this.mappingFiles).orElse(new String[0])) + .flatMap(location -> Stream.of(getResources(location))) + .toArray(Resource[]::new); + } + + private Resource[] getResources(String location) { + try { + return PATTERN_RESOLVER.getResources(location); + } catch (IOException var3) { + return new Resource[0]; + } + } +} diff --git a/secret-boot-framework-dozer/src/main/resources/dozer/global.dozer.xml b/secret-boot-framework-dozer/src/main/resources/dozer/global.dozer.xml new file mode 100644 index 0000000..095df4c --- /dev/null +++ b/secret-boot-framework-dozer/src/main/resources/dozer/global.dozer.xml @@ -0,0 +1,18 @@ + + + + + + yyyy-MM-dd HH:mm:ss + + + + -- Gitee From 52ad4c7af7a0bb2f1d34a1a441eeda5dc3345b35 Mon Sep 17 00:00:00 2001 From: secret <1029693356@qq.com> Date: Mon, 26 Jul 2021 23:38:05 +0800 Subject: [PATCH 06/11] update markdown --- README.md | 5 +++-- pom.xml | 2 ++ secret-boot-framework-all/pom.xml | 12 ++++++++++-- secret-boot-framework-dependencies/pom.xml | 15 ++++++++++----- 4 files changed, 25 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 3b58083..968d683 100644 --- a/README.md +++ b/README.md @@ -22,11 +22,12 @@ secret-boot脚手架(根据核心依赖版本长期更新,正常更新周期 | ---- | ---- | | secret-boot-framework-core | 框架核心模块 | | secret-boot-framework-cache | 框架缓存模块 | -| secret-boot-framework-mybatis-plus | mybatis-plus扩展模块 | | secret-boot-framework-captcha | 图形验证码 | -| secret-boot-framework-ffmpeg | ffmpet工具模块 | +| secret-boot-framework-dozer | dozer工具模块 | | secret-boot-framework-excel | excel工具模块 | +| secret-boot-framework-ffmpeg | ffmpet工具模块 | | secret-boot-framework-jpa | jpa扩展模块 | +| secret-boot-framework-mybatis-plus | mybatis-plus扩展模块 | | secret-boot-framework-security | spring-security扩展模块 | | secret-boot-framework-shiro | shiro扩展模块 | diff --git a/pom.xml b/pom.xml index fba5a1a..640e4a2 100644 --- a/pom.xml +++ b/pom.xml @@ -16,6 +16,8 @@ secret-boot-framework-dependencies secret-boot-framework-shiro secret-boot-framework-mail + secret-boot-framework-poi + secret-boot-framework-dozer diff --git a/secret-boot-framework-all/pom.xml b/secret-boot-framework-all/pom.xml index 3acacd2..811bc4e 100644 --- a/secret-boot-framework-all/pom.xml +++ b/secret-boot-framework-all/pom.xml @@ -20,10 +20,18 @@ com.gitee.secretopen secret-boot-framework-cache + + com.gitee.secretopen + secret-boot-framework-captcha + com.gitee.secretopen secret-boot-framework-jpa + + com.gitee.secretopen + secret-boot-framework-dozer + com.gitee.secretopen secret-boot-framework-captcha @@ -38,11 +46,11 @@ com.gitee.secretopen - secret-boot-framework-security + secret-boot-framework-mail com.gitee.secretopen - secret-boot-framework-mail + secret-boot-framework-security diff --git a/secret-boot-framework-dependencies/pom.xml b/secret-boot-framework-dependencies/pom.xml index 227dd55..6475897 100644 --- a/secret-boot-framework-dependencies/pom.xml +++ b/secret-boot-framework-dependencies/pom.xml @@ -80,6 +80,11 @@ secret-boot-framework-captcha ${secret-boot.version} + + ${project.groupId} + secret-boot-framework-dozer + ${secret-boot.version} + ${project.groupId} secret-boot-framework-excel @@ -92,27 +97,27 @@ ${project.groupId} - secret-boot-framework-mybatisplus + secret-boot-framework-jpa ${secret-boot.version} ${project.groupId} - secret-boot-framework-mail + secret-boot-framework-mybatisplus ${secret-boot.version} ${project.groupId} - secret-boot-framework-poi + secret-boot-framework-mail ${secret-boot.version} ${project.groupId} - secret-boot-framework-security + secret-boot-framework-poi ${secret-boot.version} ${project.groupId} - secret-boot-framework-jpa + secret-boot-framework-security ${secret-boot.version} -- Gitee From 9b73dacfd330e734beb998b45e086292719d3f28 Mon Sep 17 00:00:00 2001 From: secret <1029693356@qq.com> Date: Sat, 31 Jul 2021 02:06:23 +0800 Subject: [PATCH 07/11] =?UTF-8?q?common-demo=20=E9=9B=86=E6=88=90=E5=A4=9A?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E6=BA=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 + secret-boot-framework-all/pom.xml | 8 +- .../cache/aspect/RedisCacheAspect.java | 12 +- .../RedisService.java} | 4 +- .../RedissLockService.java} | 4 +- .../config/properties/DruidProperties.java | 155 +++++++++++++++++- .../core/mutidatasource/DataSourceName.java | 2 +- .../framework/demo/CommonDemoApplication.java | 4 +- .../demo/aspect/MyRedisCacheAspect.java | 12 +- .../framework/demo/config/DruidConfig.java | 82 +++++++++ .../demo/config/MyBatisPlusConfig.java | 30 +++- .../demo/controller/RoleController.java | 31 ++++ .../demo/controller/UserController.java | 4 +- .../cn/chenc/framework/demo/entity/Role.java | 52 ++++++ .../framework/demo/mapper/RoleMapper.java | 17 ++ .../framework/demo/service/RoleService.java | 15 ++ .../demo/service/impl/RoleServiceImpl.java | 31 ++++ .../src/main/resources/application-dev.yml | 59 +++++-- .../src/main/resources/mapper/RoleMapper.xml | 14 ++ .../demo/config/DemoSourceConfig.java | 22 +++ .../demo/controller/UserController.java | 5 + .../framework/demo/dao/UserRepository.java | 5 +- .../framework/demo/entity/UserEntity.java | 2 +- .../framework/demo/service/UserService.java | 7 +- .../demo/service/impl/UserServiceImpl.java | 11 +- 25 files changed, 540 insertions(+), 49 deletions(-) rename secret-boot-framework-cache/src/main/java/cn/chenc/framework/cache/{util/RedisUtils.java => service/RedisService.java} (99%) rename secret-boot-framework-cache/src/main/java/cn/chenc/framework/cache/{util/RedissLockUtil.java => service/RedissLockService.java} (98%) create mode 100644 secret-boot-framework-demo/common-demo/src/main/java/cn/chenc/framework/demo/config/DruidConfig.java create mode 100644 secret-boot-framework-demo/common-demo/src/main/java/cn/chenc/framework/demo/controller/RoleController.java create mode 100644 secret-boot-framework-demo/common-demo/src/main/java/cn/chenc/framework/demo/entity/Role.java create mode 100644 secret-boot-framework-demo/common-demo/src/main/java/cn/chenc/framework/demo/mapper/RoleMapper.java create mode 100644 secret-boot-framework-demo/common-demo/src/main/java/cn/chenc/framework/demo/service/RoleService.java create mode 100644 secret-boot-framework-demo/common-demo/src/main/java/cn/chenc/framework/demo/service/impl/RoleServiceImpl.java create mode 100644 secret-boot-framework-demo/common-demo/src/main/resources/mapper/RoleMapper.xml create mode 100644 secret-boot-framework-demo/jpa-demo/src/main/java/cn/chenc/framework/demo/config/DemoSourceConfig.java diff --git a/README.md b/README.md index 968d683..d4a3c7f 100644 --- a/README.md +++ b/README.md @@ -28,6 +28,7 @@ secret-boot脚手架(根据核心依赖版本长期更新,正常更新周期 | secret-boot-framework-ffmpeg | ffmpet工具模块 | | secret-boot-framework-jpa | jpa扩展模块 | | secret-boot-framework-mybatis-plus | mybatis-plus扩展模块 | +| secret-boot-framework-poi | poi封装模块 | | secret-boot-framework-security | spring-security扩展模块 | | secret-boot-framework-shiro | shiro扩展模块 | diff --git a/secret-boot-framework-all/pom.xml b/secret-boot-framework-all/pom.xml index 811bc4e..73c78eb 100644 --- a/secret-boot-framework-all/pom.xml +++ b/secret-boot-framework-all/pom.xml @@ -14,7 +14,7 @@ com.gitee.secretopen - secret-boot-framework-core + secret-boot-framework-captcha com.gitee.secretopen @@ -26,7 +26,7 @@ com.gitee.secretopen - secret-boot-framework-jpa + secret-boot-framework-core com.gitee.secretopen @@ -34,7 +34,7 @@ com.gitee.secretopen - secret-boot-framework-captcha + secret-boot-framework-excel com.gitee.secretopen @@ -42,7 +42,7 @@ com.gitee.secretopen - secret-boot-framework-excel + secret-boot-framework-jpa com.gitee.secretopen diff --git a/secret-boot-framework-cache/src/main/java/cn/chenc/framework/cache/aspect/RedisCacheAspect.java b/secret-boot-framework-cache/src/main/java/cn/chenc/framework/cache/aspect/RedisCacheAspect.java index bb6e1b1..a8c6dda 100644 --- a/secret-boot-framework-cache/src/main/java/cn/chenc/framework/cache/aspect/RedisCacheAspect.java +++ b/secret-boot-framework-cache/src/main/java/cn/chenc/framework/cache/aspect/RedisCacheAspect.java @@ -1,7 +1,7 @@ package cn.chenc.framework.cache.aspect; import cn.chenc.framework.cache.annotation.RedisCache; -import cn.chenc.framework.cache.util.RedisUtils; +import cn.chenc.framework.cache.service.RedisService; import cn.chenc.framework.core.util.AspectUtil; import lombok.extern.slf4j.Slf4j; import org.aspectj.lang.ProceedingJoinPoint; @@ -24,7 +24,7 @@ public class RedisCacheAspect { private static final String BIZ_CACHE_PREFIX = "biz_cache_"; @Autowired - private RedisUtils redisUtils; + private RedisService redisService; @Pointcut(value = "@annotation(cn.chenc.framework.cache.annotation.RedisCache)") public void pointcut() { @@ -43,22 +43,22 @@ public class RedisCacheAspect { if (flush) { String classPrefix = AspectUtil.INSTANCE.getKey(point, BIZ_CACHE_PREFIX); log.info("清空缓存 - {}*", classPrefix); - redisUtils.delBatch(classPrefix); + redisService.delBatch(classPrefix); return point.proceed(); } String key = AspectUtil.INSTANCE.getKey(point, cache.key(), BIZ_CACHE_PREFIX); - boolean hasKey = redisUtils.hasKey(key); + boolean hasKey = redisService.hasKey(key); if (hasKey) { try { log.info("{}从缓存中获取数据", key); - return redisUtils.get(key); + return redisService.get(key); } catch (Exception e) { log.error("从缓存中获取数据失败!", e); } } //先执行业务 Object result = point.proceed(); - redisUtils.set(key, result, cache.expire(), cache.unit()); + redisService.set(key, result, cache.expire(), cache.unit()); log.info("{}从数据库中获取数据", key); return result; } diff --git a/secret-boot-framework-cache/src/main/java/cn/chenc/framework/cache/util/RedisUtils.java b/secret-boot-framework-cache/src/main/java/cn/chenc/framework/cache/service/RedisService.java similarity index 99% rename from secret-boot-framework-cache/src/main/java/cn/chenc/framework/cache/util/RedisUtils.java rename to secret-boot-framework-cache/src/main/java/cn/chenc/framework/cache/service/RedisService.java index 1ec6eb0..bc2108e 100644 --- a/secret-boot-framework-cache/src/main/java/cn/chenc/framework/cache/util/RedisUtils.java +++ b/secret-boot-framework-cache/src/main/java/cn/chenc/framework/cache/service/RedisService.java @@ -1,4 +1,4 @@ -package cn.chenc.framework.cache.util; +package cn.chenc.framework.cache.service; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.*; @@ -15,7 +15,7 @@ import java.util.concurrent.TimeUnit; * */ @Component -public class RedisUtils { +public class RedisService { @Autowired private RedisTemplate redisTemplate; diff --git a/secret-boot-framework-cache/src/main/java/cn/chenc/framework/cache/util/RedissLockUtil.java b/secret-boot-framework-cache/src/main/java/cn/chenc/framework/cache/service/RedissLockService.java similarity index 98% rename from secret-boot-framework-cache/src/main/java/cn/chenc/framework/cache/util/RedissLockUtil.java rename to secret-boot-framework-cache/src/main/java/cn/chenc/framework/cache/service/RedissLockService.java index 5e174f0..7c1d277 100644 --- a/secret-boot-framework-cache/src/main/java/cn/chenc/framework/cache/util/RedissLockUtil.java +++ b/secret-boot-framework-cache/src/main/java/cn/chenc/framework/cache/service/RedissLockService.java @@ -1,4 +1,4 @@ -package cn.chenc.framework.cache.util; +package cn.chenc.framework.cache.service; import org.redisson.api.RLock; import org.redisson.api.RMapCache; @@ -12,7 +12,7 @@ import java.util.concurrent.TimeUnit; *  @date 2021/5/7 15:27 * */ -public class RedissLockUtil { +public class RedissLockService { private static RedissonClient redissonClient; diff --git a/secret-boot-framework-core/src/main/java/cn/chenc/framework/core/config/properties/DruidProperties.java b/secret-boot-framework-core/src/main/java/cn/chenc/framework/core/config/properties/DruidProperties.java index 1ca4962..28ae511 100644 --- a/secret-boot-framework-core/src/main/java/cn/chenc/framework/core/config/properties/DruidProperties.java +++ b/secret-boot-framework-core/src/main/java/cn/chenc/framework/core/config/properties/DruidProperties.java @@ -9,6 +9,18 @@ import com.alibaba.druid.pool.DruidDataSource; * */ public class DruidProperties { + private String connectionInitSqls; + + private String driverClassName; + + private String type; + + private String url; + + private String username; + + private String password; + private int initialSize; private int minIdle; @@ -31,8 +43,11 @@ public class DruidProperties { private boolean testOnReturn; - public DruidDataSource dataSource(DruidDataSource datasource) - { + public DruidDataSource dataSource(DruidDataSource datasource) { + datasource.setDriverClassName(driverClassName); + datasource.setUrl(this.url); + datasource.setUsername(this.username); + datasource.setPassword(this.password); /** 配置初始化大小、最小、最大 */ datasource.setInitialSize(initialSize); datasource.setMaxActive(maxActive); @@ -60,4 +75,140 @@ public class DruidProperties { datasource.setTestOnReturn(testOnReturn); return datasource; } + + public String getConnectionInitSqls() { + return connectionInitSqls; + } + + public void setConnectionInitSqls(String connectionInitSqls) { + this.connectionInitSqls = connectionInitSqls; + } + + public String getDriverClassName() { + return driverClassName; + } + + public void setDriverClassName(String driverClassName) { + this.driverClassName = driverClassName; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + 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 int getInitialSize() { + return initialSize; + } + + public void setInitialSize(int initialSize) { + this.initialSize = initialSize; + } + + public int getMinIdle() { + return minIdle; + } + + public void setMinIdle(int minIdle) { + this.minIdle = minIdle; + } + + public int getMaxActive() { + return maxActive; + } + + public void setMaxActive(int maxActive) { + this.maxActive = maxActive; + } + + public int getMaxWait() { + return maxWait; + } + + public void setMaxWait(int maxWait) { + this.maxWait = maxWait; + } + + public int getTimeBetweenEvictionRunsMillis() { + return timeBetweenEvictionRunsMillis; + } + + public void setTimeBetweenEvictionRunsMillis(int timeBetweenEvictionRunsMillis) { + this.timeBetweenEvictionRunsMillis = timeBetweenEvictionRunsMillis; + } + + public int getMinEvictableIdleTimeMillis() { + return minEvictableIdleTimeMillis; + } + + public void setMinEvictableIdleTimeMillis(int minEvictableIdleTimeMillis) { + this.minEvictableIdleTimeMillis = minEvictableIdleTimeMillis; + } + + public int getMaxEvictableIdleTimeMillis() { + return maxEvictableIdleTimeMillis; + } + + public void setMaxEvictableIdleTimeMillis(int maxEvictableIdleTimeMillis) { + this.maxEvictableIdleTimeMillis = maxEvictableIdleTimeMillis; + } + + public String getValidationQuery() { + return validationQuery; + } + + public void setValidationQuery(String validationQuery) { + this.validationQuery = validationQuery; + } + + public boolean isTestWhileIdle() { + return testWhileIdle; + } + + public void setTestWhileIdle(boolean testWhileIdle) { + this.testWhileIdle = testWhileIdle; + } + + public boolean isTestOnBorrow() { + return testOnBorrow; + } + + public void setTestOnBorrow(boolean testOnBorrow) { + this.testOnBorrow = testOnBorrow; + } + + public boolean isTestOnReturn() { + return testOnReturn; + } + + public void setTestOnReturn(boolean testOnReturn) { + this.testOnReturn = testOnReturn; + } } diff --git a/secret-boot-framework-core/src/main/java/cn/chenc/framework/core/mutidatasource/DataSourceName.java b/secret-boot-framework-core/src/main/java/cn/chenc/framework/core/mutidatasource/DataSourceName.java index 4020a20..e6fb4c5 100644 --- a/secret-boot-framework-core/src/main/java/cn/chenc/framework/core/mutidatasource/DataSourceName.java +++ b/secret-boot-framework-core/src/main/java/cn/chenc/framework/core/mutidatasource/DataSourceName.java @@ -7,5 +7,5 @@ package cn.chenc.framework.core.mutidatasource; * */ public interface DataSourceName { - public final static String MASTER = "master"; + public final static String MASTER = "masterDataSource"; } diff --git a/secret-boot-framework-demo/common-demo/src/main/java/cn/chenc/framework/demo/CommonDemoApplication.java b/secret-boot-framework-demo/common-demo/src/main/java/cn/chenc/framework/demo/CommonDemoApplication.java index eb1e2d4..0e74b41 100644 --- a/secret-boot-framework-demo/common-demo/src/main/java/cn/chenc/framework/demo/CommonDemoApplication.java +++ b/secret-boot-framework-demo/common-demo/src/main/java/cn/chenc/framework/demo/CommonDemoApplication.java @@ -2,6 +2,8 @@ package cn.chenc.framework.demo; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; +import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration; import org.springframework.transaction.annotation.EnableTransactionManagement; /** @@ -10,8 +12,8 @@ import org.springframework.transaction.annotation.EnableTransactionManagement; *  @date 2020/11/28 13:54 * */ -@SpringBootApplication @EnableTransactionManagement +@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class }) public class CommonDemoApplication { public static void main(String[] args){ diff --git a/secret-boot-framework-demo/common-demo/src/main/java/cn/chenc/framework/demo/aspect/MyRedisCacheAspect.java b/secret-boot-framework-demo/common-demo/src/main/java/cn/chenc/framework/demo/aspect/MyRedisCacheAspect.java index c7615b3..de7c306 100644 --- a/secret-boot-framework-demo/common-demo/src/main/java/cn/chenc/framework/demo/aspect/MyRedisCacheAspect.java +++ b/secret-boot-framework-demo/common-demo/src/main/java/cn/chenc/framework/demo/aspect/MyRedisCacheAspect.java @@ -1,7 +1,7 @@ package cn.chenc.framework.demo.aspect; import cn.chenc.framework.cache.annotation.RedisCache; -import cn.chenc.framework.cache.util.RedisUtils; +import cn.chenc.framework.cache.service.RedisService; import cn.chenc.framework.core.util.AspectUtil; import lombok.extern.slf4j.Slf4j; import org.aspectj.lang.ProceedingJoinPoint; @@ -24,7 +24,7 @@ public class MyRedisCacheAspect { private static final String BIZ_CACHE_PREFIX = "biz_cache_"; @Autowired - private RedisUtils redisUtils; + private RedisService redisService; @Pointcut(value = "@annotation(cn.chenc.framework.cache.annotation.RedisCache)") public void pointcut() { @@ -43,22 +43,22 @@ public class MyRedisCacheAspect { if (flush) { String classPrefix = AspectUtil.INSTANCE.getKey(point, BIZ_CACHE_PREFIX); log.info("清空缓存 - {}*", classPrefix); - redisUtils.delBatch(classPrefix); + redisService.delBatch(classPrefix); return point.proceed(); } String key = AspectUtil.INSTANCE.getKey(point, cache.key(), BIZ_CACHE_PREFIX); - boolean hasKey = redisUtils.hasKey(key); + boolean hasKey = redisService.hasKey(key); if (hasKey) { try { log.info("{}从缓存中获取数据", key); - return redisUtils.get(key); + return redisService.get(key); } catch (Exception e) { log.error("从缓存中获取数据失败!", e); } } //先执行业务 Object result = point.proceed(); - redisUtils.set(key, result, cache.expire(), cache.unit()); + redisService.set(key, result, cache.expire(), cache.unit()); log.info("{}从数据库中获取数据", key); return result; } diff --git a/secret-boot-framework-demo/common-demo/src/main/java/cn/chenc/framework/demo/config/DruidConfig.java b/secret-boot-framework-demo/common-demo/src/main/java/cn/chenc/framework/demo/config/DruidConfig.java new file mode 100644 index 0000000..e8b7815 --- /dev/null +++ b/secret-boot-framework-demo/common-demo/src/main/java/cn/chenc/framework/demo/config/DruidConfig.java @@ -0,0 +1,82 @@ +package cn.chenc.framework.demo.config; + +import cn.chenc.framework.core.config.properties.DruidProperties; +import cn.chenc.framework.core.mutidatasource.DataSourceName; +import cn.chenc.framework.core.mutidatasource.DynamicDataSource; +import com.alibaba.druid.pool.DruidDataSource; +import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Primary; +import org.springframework.jdbc.core.JdbcTemplate; + +import javax.sql.DataSource; +import java.util.HashMap; +import java.util.Map; + +/** + *  @description: druid 多数据源配置 + *  @author secret + *  @date 2021/7/30 23:40 + * + */ +@Configuration +public class DruidConfig { + + @Bean(name = "masterDruidProperties") + @ConfigurationProperties("spring.datasource.druid.master") + public DruidProperties masterDruidProperties(){ + return new DruidProperties(); + } + + @Bean(name = "slaveDruidProperties") + @ConfigurationProperties("spring.datasource.druid.slave") + public DruidProperties slaveDruidProperties(){ + return new DruidProperties(); + } + + @Bean + public DataSource masterDataSource(DruidProperties masterDruidProperties) { + DruidDataSource dataSource = DruidDataSourceBuilder.create().build(); + return masterDruidProperties.dataSource(dataSource); + } + + @Bean + public DataSource slaveDataSource(DruidProperties slaveDruidProperties) { + DruidDataSource dataSource = DruidDataSourceBuilder.create().build(); + return slaveDruidProperties.dataSource(dataSource); + } + + @Bean(name = "dynamicDataSource") + @Primary + public DynamicDataSource dataSource(Map dataSources) { + DynamicDataSource dynamicDataSource = new DynamicDataSource(); + Map targetDataSources = new HashMap<>(); + targetDataSources.putAll(dataSources); + dynamicDataSource.setTargetDataSources(targetDataSources); + dynamicDataSource.setDefaultTargetDataSource(dataSources.get("masterDataSource")); + dynamicDataSource.afterPropertiesSet(); + // 遍历存入list中 + for (Map.Entry entry : dataSources.entrySet()) { + DynamicDataSource.saveDataSourceTypeName(entry.getKey()); + } + return dynamicDataSource; + } + + /** + * 向spring容器暴露组合数据源JdbcTemplate + * @param dataSource + * @return + * @author secret + */ + @Bean(name = "multipleDataJdbcTemplate") + public JdbcTemplate primaryJdbcTemplate(@Qualifier("dynamicDataSource") DataSource dataSource) { + return new JdbcTemplate(dataSource); + } + + + +} diff --git a/secret-boot-framework-demo/common-demo/src/main/java/cn/chenc/framework/demo/config/MyBatisPlusConfig.java b/secret-boot-framework-demo/common-demo/src/main/java/cn/chenc/framework/demo/config/MyBatisPlusConfig.java index 8903dde..f7e8bce 100644 --- a/secret-boot-framework-demo/common-demo/src/main/java/cn/chenc/framework/demo/config/MyBatisPlusConfig.java +++ b/secret-boot-framework-demo/common-demo/src/main/java/cn/chenc/framework/demo/config/MyBatisPlusConfig.java @@ -1,10 +1,25 @@ package cn.chenc.framework.demo.config; +import com.alibaba.excel.metadata.GlobalConfiguration; import com.baomidou.mybatisplus.annotation.DbType; import com.baomidou.mybatisplus.autoconfigure.ConfigurationCustomizer; +import com.baomidou.mybatisplus.autoconfigure.SpringBootVFS; +import com.baomidou.mybatisplus.core.MybatisConfiguration; import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor; +import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean; +import org.apache.ibatis.io.VFS; +import org.apache.ibatis.plugin.Interceptor; +import org.apache.ibatis.session.SqlSessionFactory; +import org.apache.ibatis.type.JdbcType; +import org.mybatis.spring.SqlSessionFactoryBean; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.env.Environment; +import org.springframework.core.io.DefaultResourceLoader; + +import javax.sql.DataSource; /** *  @description: mybatisplus配置 @@ -12,7 +27,7 @@ import org.springframework.context.annotation.Bean; *  @date 2020/3/21 21:56 * */ -//@Configuration +@Configuration public class MyBatisPlusConfig { /** @@ -31,4 +46,17 @@ public class MyBatisPlusConfig { return configuration -> configuration.setUseDeprecatedExecutor(false); } +// @Bean +// public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception { +// +// VFS.addImplClass(SpringBootVFS.class); +// MybatisConfiguration configuration = new MybatisConfiguration(); +// final SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean(); +// sessionFactory.setDataSource(dataSource); +// sessionFactory.setConfiguration(configuration); +// return sessionFactory.getObject(); +// +// } + + } diff --git a/secret-boot-framework-demo/common-demo/src/main/java/cn/chenc/framework/demo/controller/RoleController.java b/secret-boot-framework-demo/common-demo/src/main/java/cn/chenc/framework/demo/controller/RoleController.java new file mode 100644 index 0000000..7c39a1b --- /dev/null +++ b/secret-boot-framework-demo/common-demo/src/main/java/cn/chenc/framework/demo/controller/RoleController.java @@ -0,0 +1,31 @@ +package cn.chenc.framework.demo.controller; + +import cn.chenc.framework.core.model.response.AjaxResult; +import cn.chenc.framework.demo.entity.Role; +import cn.chenc.framework.demo.service.RoleService; +import com.baomidou.mybatisplus.core.metadata.IPage; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + *  @description: TODO + *  @author secret + *  @date 2021/7/31 0:05 + * + */ +@RestController +@RequestMapping("/role") +public class RoleController { + + @Autowired + private RoleService roleService; + + @GetMapping("/list") + public AjaxResult queryRolePageList(Role role){ + IPage iPage=roleService.queryRolePageList(role); + return AjaxResult.success(iPage); + } +} diff --git a/secret-boot-framework-demo/common-demo/src/main/java/cn/chenc/framework/demo/controller/UserController.java b/secret-boot-framework-demo/common-demo/src/main/java/cn/chenc/framework/demo/controller/UserController.java index 1a1f972..54cbdaf 100644 --- a/secret-boot-framework-demo/common-demo/src/main/java/cn/chenc/framework/demo/controller/UserController.java +++ b/secret-boot-framework-demo/common-demo/src/main/java/cn/chenc/framework/demo/controller/UserController.java @@ -46,8 +46,8 @@ public class UserController { return ResultUtil.success(new User()); } - @PostMapping("/list") - public ResponseVO queryUserPageList(@RequestBody User user){ + @GetMapping("/list") + public ResponseVO queryUserPageList(User user){ IPage iPage=userService.queryUserPageList(user); return ResultUtil.success(iPage); } diff --git a/secret-boot-framework-demo/common-demo/src/main/java/cn/chenc/framework/demo/entity/Role.java b/secret-boot-framework-demo/common-demo/src/main/java/cn/chenc/framework/demo/entity/Role.java new file mode 100644 index 0000000..261b8c0 --- /dev/null +++ b/secret-boot-framework-demo/common-demo/src/main/java/cn/chenc/framework/demo/entity/Role.java @@ -0,0 +1,52 @@ +package cn.chenc.framework.demo.entity; + +import cn.chenc.framework.mybatisplus.model.BaseEntity; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; + +import java.io.Serializable; + +/** + *  @description: TODO + *  @author secret + *  @date 2021/7/30 23:59 + * + */ +public class Role extends BaseEntity implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 主键id + */ + @TableId(value = "id", type = IdType.AUTO) + private Integer id; + + private String roleName; + + private String roleCode; + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getRoleName() { + return roleName; + } + + public void setRoleName(String roleName) { + this.roleName = roleName; + } + + public String getRoleCode() { + return roleCode; + } + + public void setRoleCode(String roleCode) { + this.roleCode = roleCode; + } +} diff --git a/secret-boot-framework-demo/common-demo/src/main/java/cn/chenc/framework/demo/mapper/RoleMapper.java b/secret-boot-framework-demo/common-demo/src/main/java/cn/chenc/framework/demo/mapper/RoleMapper.java new file mode 100644 index 0000000..058aa7c --- /dev/null +++ b/secret-boot-framework-demo/common-demo/src/main/java/cn/chenc/framework/demo/mapper/RoleMapper.java @@ -0,0 +1,17 @@ +package cn.chenc.framework.demo.mapper; + +import cn.chenc.framework.demo.entity.Role; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; +import org.springframework.stereotype.Repository; + +/** + *  @description: TODO + *  @author secret + *  @date 2020/11/30 10:03 + * + */ +@Mapper +@Repository +public interface RoleMapper extends BaseMapper { +} diff --git a/secret-boot-framework-demo/common-demo/src/main/java/cn/chenc/framework/demo/service/RoleService.java b/secret-boot-framework-demo/common-demo/src/main/java/cn/chenc/framework/demo/service/RoleService.java new file mode 100644 index 0000000..3485c96 --- /dev/null +++ b/secret-boot-framework-demo/common-demo/src/main/java/cn/chenc/framework/demo/service/RoleService.java @@ -0,0 +1,15 @@ +package cn.chenc.framework.demo.service; + +import cn.chenc.framework.demo.entity.Role; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.service.IService; + +/** + *  @description: TODO + *  @author secret + *  @date 2020/11/30 10:06 + * + */ +public interface RoleService extends IService { + IPage queryRolePageList(Role role); +} diff --git a/secret-boot-framework-demo/common-demo/src/main/java/cn/chenc/framework/demo/service/impl/RoleServiceImpl.java b/secret-boot-framework-demo/common-demo/src/main/java/cn/chenc/framework/demo/service/impl/RoleServiceImpl.java new file mode 100644 index 0000000..4f961b7 --- /dev/null +++ b/secret-boot-framework-demo/common-demo/src/main/java/cn/chenc/framework/demo/service/impl/RoleServiceImpl.java @@ -0,0 +1,31 @@ +package cn.chenc.framework.demo.service.impl; + +import cn.chenc.framework.core.annotation.ChangDataSource; +import cn.chenc.framework.demo.entity.Role; +import cn.chenc.framework.demo.mapper.RoleMapper; +import cn.chenc.framework.demo.service.RoleService; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Service; + +/** + *  @description: TODO + *  @author secret + *  @date 2020/11/30 10:09 + * + */ +@Service +public class RoleServiceImpl extends ServiceImpl implements RoleService { + + @Override + @ChangDataSource(name = "slaveDataSource") + public IPage queryRolePageList(Role role) { + IPage page=new Page(role.getPageIndex(),role.getPageSize()); + IPage iPage=this.page(page,null); + return iPage; + } + + + +} diff --git a/secret-boot-framework-demo/common-demo/src/main/resources/application-dev.yml b/secret-boot-framework-demo/common-demo/src/main/resources/application-dev.yml index 6fa8d6d..0585a3d 100644 --- a/secret-boot-framework-demo/common-demo/src/main/resources/application-dev.yml +++ b/secret-boot-framework-demo/common-demo/src/main/resources/application-dev.yml @@ -6,24 +6,47 @@ server: spring: datasource: druid: - connection-init-sqls: set names utf8mb4 - driver-class-name: com.mysql.cj.jdbc.Driver - initial-size: 5 - min-idle: 5 - max-active: 20 - # 配置获取连接等待超时的时间 - max-wait: 180000 - # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 - time-between-eviction-runs-millis: 180000 - # 配置一个连接在池中最小生存的时间,单位是毫秒 - min-evictable-idle-time-millis: 300000 - test-while-idle: true - test-on-borrow: false - test-on-return: false - type: com.alibaba.druid.pool.DruidDataSource - url: jdbc:mysql://127.0.0.1:3306/secret_framework?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=GMT&rewriteBatchedStatements=true - username: root - password: 111111 + master: + connection-init-sqls: set names utf8mb4 + driver-class-name: com.mysql.cj.jdbc.Driver + initial-size: 5 + min-idle: 5 + max-active: 20 + # 配置获取连接等待超时的时间 + max-wait: 180000 + # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 + time-between-eviction-runs-millis: 180000 + # 配置一个连接在池中最小生存的时间,单位是毫秒 + min-evictable-idle-time-millis: 300000 + # 配置一个连接在池中最大生存的时间,单位是毫秒 + max-evictable-idle-time-millis: 900000 + test-while-idle: true + test-on-borrow: false + test-on-return: false + type: com.alibaba.druid.pool.DruidDataSource + url: jdbc:mysql://127.0.0.1:3306/secret_framework?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=GMT&rewriteBatchedStatements=true + username: root + password: 111111 + slave: + connection-init-sqls: set names utf8mb4 + driver-class-name: com.mysql.cj.jdbc.Driver + initial-size: 5 + min-idle: 5 + max-active: 20 + # 配置获取连接等待超时的时间 + max-wait: 180000 + # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 + time-between-eviction-runs-millis: 180000 + # 配置一个连接在池中最小生存的时间,单位是毫秒 + min-evictable-idle-time-millis: 300000 + # 配置一个连接在池中最大生存的时间,单位是毫秒 + max-evictable-idle-time-millis: 900000 + test-while-idle: true + test-on-borrow: false + test-on-return: false + url: jdbc:mysql://127.0.0.1:3306/secret_framework_slave?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=GMT&rewriteBatchedStatements=true + username: root + password: 111111 # Redis数据库索引(默认为0) redis: jedis: diff --git a/secret-boot-framework-demo/common-demo/src/main/resources/mapper/RoleMapper.xml b/secret-boot-framework-demo/common-demo/src/main/resources/mapper/RoleMapper.xml new file mode 100644 index 0000000..a1b1d80 --- /dev/null +++ b/secret-boot-framework-demo/common-demo/src/main/resources/mapper/RoleMapper.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/secret-boot-framework-demo/jpa-demo/src/main/java/cn/chenc/framework/demo/config/DemoSourceConfig.java b/secret-boot-framework-demo/jpa-demo/src/main/java/cn/chenc/framework/demo/config/DemoSourceConfig.java new file mode 100644 index 0000000..1e9bd26 --- /dev/null +++ b/secret-boot-framework-demo/jpa-demo/src/main/java/cn/chenc/framework/demo/config/DemoSourceConfig.java @@ -0,0 +1,22 @@ +package cn.chenc.framework.demo.config; + +import cn.chenc.framework.jpa.support.BaseJpaRepositoryFactoryBean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.jpa.repository.config.EnableJpaRepositories; +import org.springframework.transaction.annotation.EnableTransactionManagement; + +/** + *  @description: TODO + *  @author secret + *  @date 2021/7/21 20:47 + * + */ +@Configuration +@EnableJpaRepositories( + // 设置Repository所在位置 + basePackages = { "cn.chenc.framework.demo.dao" }, + // 覆盖SpringBoot提供的默认配置 + repositoryFactoryBeanClass = BaseJpaRepositoryFactoryBean.class) +public class DemoSourceConfig { + +} diff --git a/secret-boot-framework-demo/jpa-demo/src/main/java/cn/chenc/framework/demo/controller/UserController.java b/secret-boot-framework-demo/jpa-demo/src/main/java/cn/chenc/framework/demo/controller/UserController.java index 37a423e..8f016ab 100644 --- a/secret-boot-framework-demo/jpa-demo/src/main/java/cn/chenc/framework/demo/controller/UserController.java +++ b/secret-boot-framework-demo/jpa-demo/src/main/java/cn/chenc/framework/demo/controller/UserController.java @@ -38,4 +38,9 @@ public class UserController { return AjaxResult.success(); } + @GetMapping("/baseApiPage") + public Page baseApiPage(UserEntity userEntity) throws Exception { + return userService.baseApiPage(userEntity); + } + } diff --git a/secret-boot-framework-demo/jpa-demo/src/main/java/cn/chenc/framework/demo/dao/UserRepository.java b/secret-boot-framework-demo/jpa-demo/src/main/java/cn/chenc/framework/demo/dao/UserRepository.java index 756c3ba..60c69d8 100644 --- a/secret-boot-framework-demo/jpa-demo/src/main/java/cn/chenc/framework/demo/dao/UserRepository.java +++ b/secret-boot-framework-demo/jpa-demo/src/main/java/cn/chenc/framework/demo/dao/UserRepository.java @@ -1,8 +1,10 @@ package cn.chenc.framework.demo.dao; import cn.chenc.framework.demo.entity.UserEntity; +import cn.chenc.framework.jpa.repository.BaseRepository; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaSpecificationExecutor; +import org.springframework.stereotype.Repository; /** *  @description: TODO @@ -10,7 +12,8 @@ import org.springframework.data.jpa.repository.JpaSpecificationExecutor; *  @date 2021/5/14 15:26 * */ -public interface UserRepository extends JpaRepository, JpaSpecificationExecutor { +@Repository +public interface UserRepository extends BaseRepository {//JpaRepository, JpaSpecificationExecutor { diff --git a/secret-boot-framework-demo/jpa-demo/src/main/java/cn/chenc/framework/demo/entity/UserEntity.java b/secret-boot-framework-demo/jpa-demo/src/main/java/cn/chenc/framework/demo/entity/UserEntity.java index 594090d..016d755 100644 --- a/secret-boot-framework-demo/jpa-demo/src/main/java/cn/chenc/framework/demo/entity/UserEntity.java +++ b/secret-boot-framework-demo/jpa-demo/src/main/java/cn/chenc/framework/demo/entity/UserEntity.java @@ -11,7 +11,7 @@ import java.time.LocalDateTime; *  @author secret *  @date 2021/5/14 14:51 * - */ + */ @Entity @Table(name = "user", schema = "secret_framework") public class UserEntity extends BaseEntity implements Serializable { diff --git a/secret-boot-framework-demo/jpa-demo/src/main/java/cn/chenc/framework/demo/service/UserService.java b/secret-boot-framework-demo/jpa-demo/src/main/java/cn/chenc/framework/demo/service/UserService.java index d734cff..bc49213 100644 --- a/secret-boot-framework-demo/jpa-demo/src/main/java/cn/chenc/framework/demo/service/UserService.java +++ b/secret-boot-framework-demo/jpa-demo/src/main/java/cn/chenc/framework/demo/service/UserService.java @@ -1,8 +1,11 @@ package cn.chenc.framework.demo.service; + import cn.chenc.framework.demo.entity.UserEntity; +import cn.chenc.framework.jpa.service.BaseService; import org.springframework.data.domain.Page; +import javax.persistence.criteria.CriteriaBuilder; import java.util.List; /** @@ -11,11 +14,13 @@ import java.util.List; *  @date 2021/5/14 15:45 * */ -public interface UserService { +public interface UserService extends BaseService { List queryAll(); Page queryUserPageList(UserEntity userEntity); void insertUser(UserEntity userEntity); + + Page baseApiPage(UserEntity userEntity) throws Exception; } diff --git a/secret-boot-framework-demo/jpa-demo/src/main/java/cn/chenc/framework/demo/service/impl/UserServiceImpl.java b/secret-boot-framework-demo/jpa-demo/src/main/java/cn/chenc/framework/demo/service/impl/UserServiceImpl.java index ea759bc..add58d6 100644 --- a/secret-boot-framework-demo/jpa-demo/src/main/java/cn/chenc/framework/demo/service/impl/UserServiceImpl.java +++ b/secret-boot-framework-demo/jpa-demo/src/main/java/cn/chenc/framework/demo/service/impl/UserServiceImpl.java @@ -4,6 +4,9 @@ import cn.chenc.framework.core.util.StringUtils; import cn.chenc.framework.demo.dao.UserRepository; import cn.chenc.framework.demo.entity.UserEntity; import cn.chenc.framework.demo.service.UserService; +import cn.chenc.framework.jpa.repository.BaseRepository; +import cn.chenc.framework.jpa.service.BaseServiceImpl; +import cn.chenc.framework.jpa.util.PageUtil; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; @@ -26,7 +29,7 @@ import java.util.List; * */ @Service -public class UserServiceImpl implements UserService { +public class UserServiceImpl extends BaseServiceImpl implements UserService { @Autowired private UserRepository userRepository; @@ -60,4 +63,10 @@ public class UserServiceImpl implements UserService { userRepository.save(userEntity); } + @Override + public Page baseApiPage(UserEntity userEntity) throws Exception { + Page page = userRepository.getListByObject(userEntity,PageRequest.of(0,10)); + return page; + } + } -- Gitee From a1eb6d74c34e7fd6e6c6f92719320becc252d339 Mon Sep 17 00:00:00 2001 From: secret <1029693356@qq.com> Date: Sun, 1 Aug 2021 01:38:58 +0800 Subject: [PATCH 08/11] =?UTF-8?q?common-demo=20=E9=9B=86=E6=88=90poi?= =?UTF-8?q?=E6=A8=A1=E5=9D=97demo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../chenc/framework/core/util/DateUtils.java | 69 ++++++++++++++ .../framework/core/util/DateUtilsTest.java | 10 ++ .../common-demo/pom.xml | 12 ++- .../framework/demo/CommonDemoApplication.java | 1 - .../framework/demo/config/DruidConfig.java | 2 - .../framework/demo/config/ExcelConfig.java | 91 ++++++++----------- .../demo/config/MyBatisPlusConfig.java | 14 --- .../demo/controller/RoleController.java | 1 - .../demo/controller/UserController.java | 39 ++++++++ .../converters/MyLocalDateTimeConverter.java | 64 ++++++------- .../cn/chenc/framework/demo/entity/Dict.java | 36 ++++++++ .../cn/chenc/framework/demo/entity/User.java | 4 + .../src/main/resources/application-dev.yml | 24 +++++ .../demo/config/DemoSourceConfig.java | 1 - .../demo/controller/UserController.java | 1 - .../framework/demo/dao/UserRepository.java | 2 - .../framework/demo/entity/UserEntity.java | 3 +- .../framework/demo/service/UserService.java | 1 - .../demo/service/impl/UserServiceImpl.java | 2 - .../mail/config/MailConfiguration.java | 7 +- .../chenc/framework/poi/util/ExcelUtil.java | 7 +- .../framework/poi/util/ReflectUtils.java | 9 ++ 22 files changed, 283 insertions(+), 117 deletions(-) create mode 100644 secret-boot-framework-demo/common-demo/src/main/java/cn/chenc/framework/demo/entity/Dict.java diff --git a/secret-boot-framework-core/src/main/java/cn/chenc/framework/core/util/DateUtils.java b/secret-boot-framework-core/src/main/java/cn/chenc/framework/core/util/DateUtils.java index f991e6b..9f71367 100644 --- a/secret-boot-framework-core/src/main/java/cn/chenc/framework/core/util/DateUtils.java +++ b/secret-boot-framework-core/src/main/java/cn/chenc/framework/core/util/DateUtils.java @@ -10,6 +10,7 @@ import java.time.Instant; import java.time.LocalDateTime; import java.time.ZoneId; import java.util.*; +import java.util.regex.Pattern; public class DateUtils extends org.apache.commons.lang3.time.DateUtils{ public static final String YYYYMMDDHHMMSS = "yyyy-MM-dd HH:mm:ss"; @@ -403,6 +404,12 @@ public class DateUtils extends org.apache.commons.lang3.time.DateUtils{ return localDateTime; } + public static LocalDateTime parseLocalDateTime(String dateStr){ + String patten = getDateFormat(dateStr); + Date date = parse(dateStr,patten); + return dateToLocalDateTime(date); + } + /** * 日期路径 即年/月/日 如2018/08/08 */ @@ -440,4 +447,66 @@ public class DateUtils extends org.apache.commons.lang3.time.DateUtils{ // long sec = diff % nd % nh % nm / ns; return day + "天" + hour + "小时" + min + "分钟"; } + + /** + * 常规自动日期格式识别 + * @param str 时间字符串 + * @return String + * @author secret + * 如:1998-09-27 -> yyyy-MM-dd + */ + public static String getDateFormat(String str){ + boolean year = false; + Pattern pattern = Pattern.compile("^[-\\+]?[\\d]*$"); + if(pattern.matcher(str.substring(0, 4)).matches()) { + year = true; + } + StringBuilder sb = new StringBuilder(); + int index = 0; + if(!year) { + if(str.contains("月") || str.contains("-") || str.contains("/")) { + if(Character.isDigit(str.charAt(0))) { + index = 1; + } + }else { + index = 3; + } + } + for (int i = 0; i < str.length(); i++) { + char chr = str.charAt(i); + if(Character.isDigit(chr)) { + if(index==0) { + sb.append("y"); + } + if(index==1) { + sb.append("M"); + } + if(index==2) { + sb.append("d"); + } + if(index==3) { + sb.append("H"); + } + if(index==4) { + sb.append("m"); + } + if(index==5) { + sb.append("s"); + } + if(index==6) { + sb.append("S"); + } + }else { + if(i>0) { + char lastChar = str.charAt(i-1); + if(Character.isDigit(lastChar)) { + index++; + } + } + sb.append(chr); + } + } + return sb.toString(); + } + } diff --git a/secret-boot-framework-core/src/test/java/cn/chenc/framework/core/util/DateUtilsTest.java b/secret-boot-framework-core/src/test/java/cn/chenc/framework/core/util/DateUtilsTest.java index 8d2b26f..2d15df1 100644 --- a/secret-boot-framework-core/src/test/java/cn/chenc/framework/core/util/DateUtilsTest.java +++ b/secret-boot-framework-core/src/test/java/cn/chenc/framework/core/util/DateUtilsTest.java @@ -1,8 +1,11 @@ package cn.chenc.framework.core.util; +import cn.hutool.core.date.DateTime; +import cn.hutool.core.date.DateUtil; import org.junit.jupiter.api.Test; +import java.time.LocalDateTime; import java.util.Date; import java.util.Map; @@ -14,6 +17,13 @@ import java.util.Map; */ public class DateUtilsTest { + @Test + public void parseDate(){ + Date date = DateUtils.parse("1998-09-27"); + DateTime dateTime = DateUtil.parseDate("1998-09-27"); + LocalDateTime localDateTime = DateUtils.parseLocalDateTime("1998-09-27"); + } + @Test public void getCurrentWeekTest(){ Map map1=DateUtils.getCurrentWeek(false); diff --git a/secret-boot-framework-demo/common-demo/pom.xml b/secret-boot-framework-demo/common-demo/pom.xml index 4b0d847..97642eb 100644 --- a/secret-boot-framework-demo/common-demo/pom.xml +++ b/secret-boot-framework-demo/common-demo/pom.xml @@ -38,13 +38,21 @@ com.gitee.secretopen secret-boot-framework-cache + + + + com.gitee.secretopen - secret-boot-framework-excel + secret-boot-framework-captcha com.gitee.secretopen - secret-boot-framework-captcha + secret-boot-framework-mail + + + com.gitee.secretopen + secret-boot-framework-poi diff --git a/secret-boot-framework-demo/common-demo/src/main/java/cn/chenc/framework/demo/CommonDemoApplication.java b/secret-boot-framework-demo/common-demo/src/main/java/cn/chenc/framework/demo/CommonDemoApplication.java index 0e74b41..fbf91fd 100644 --- a/secret-boot-framework-demo/common-demo/src/main/java/cn/chenc/framework/demo/CommonDemoApplication.java +++ b/secret-boot-framework-demo/common-demo/src/main/java/cn/chenc/framework/demo/CommonDemoApplication.java @@ -3,7 +3,6 @@ package cn.chenc.framework.demo; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; -import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration; import org.springframework.transaction.annotation.EnableTransactionManagement; /** diff --git a/secret-boot-framework-demo/common-demo/src/main/java/cn/chenc/framework/demo/config/DruidConfig.java b/secret-boot-framework-demo/common-demo/src/main/java/cn/chenc/framework/demo/config/DruidConfig.java index e8b7815..9837977 100644 --- a/secret-boot-framework-demo/common-demo/src/main/java/cn/chenc/framework/demo/config/DruidConfig.java +++ b/secret-boot-framework-demo/common-demo/src/main/java/cn/chenc/framework/demo/config/DruidConfig.java @@ -1,12 +1,10 @@ package cn.chenc.framework.demo.config; import cn.chenc.framework.core.config.properties.DruidProperties; -import cn.chenc.framework.core.mutidatasource.DataSourceName; import cn.chenc.framework.core.mutidatasource.DynamicDataSource; import com.alibaba.druid.pool.DruidDataSource; import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder; import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; diff --git a/secret-boot-framework-demo/common-demo/src/main/java/cn/chenc/framework/demo/config/ExcelConfig.java b/secret-boot-framework-demo/common-demo/src/main/java/cn/chenc/framework/demo/config/ExcelConfig.java index b0ba542..1b267a4 100644 --- a/secret-boot-framework-demo/common-demo/src/main/java/cn/chenc/framework/demo/config/ExcelConfig.java +++ b/secret-boot-framework-demo/common-demo/src/main/java/cn/chenc/framework/demo/config/ExcelConfig.java @@ -1,19 +1,8 @@ package cn.chenc.framework.demo.config; -import cn.chenc.framework.demo.converters.MyLocalDateTimeConverter; -import cn.chenc.framework.excel.config.CustomerDefaultConverterLoader; -import cn.chenc.framework.excel.converters.LocalDateTimeConverter; -import cn.chenc.framework.excel.converters.NumberToLocalDateTimeConverter; -import com.alibaba.excel.converters.Converter; -import com.alibaba.excel.converters.ConverterKeyBuild; -import com.alibaba.excel.converters.DefaultConverterLoader; +//import cn.chenc.framework.excel.config.CustomerDefaultConverterLoader; import org.springframework.boot.autoconfigure.AutoConfigureAfter; -import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Primary; - -import java.lang.reflect.Field; -import java.util.Map; /** *  @description: TODO @@ -22,45 +11,45 @@ import java.util.Map; * */ @Configuration -@AutoConfigureAfter(CustomerDefaultConverterLoader.class) +//@AutoConfigureAfter(CustomerDefaultConverterLoader.class) public class ExcelConfig { - //存放写时用到的converter - private static final String ALL_CONVERTER = "allConverter"; - //存放所有的converter - private static final String WRITE_CONVERTER = "defaultWriteConverter"; - - @Bean - @Primary - public DefaultConverterLoader addConverter() throws IllegalAccessException { - DefaultConverterLoader converters = new DefaultConverterLoader(); - Field[] fields = converters.getClass().getDeclaredFields(); - for (Field field : fields) { - field.setAccessible(true); - if (field.getType() == Map.class) { - Map oldMap = (Map) field.get(converters); - if (oldMap != null && !oldMap.isEmpty()) { - if (WRITE_CONVERTER.equalsIgnoreCase(field.getName())) { - putWriteConverter(oldMap, new LocalDateTimeConverter()); - putAllConverter(oldMap,new NumberToLocalDateTimeConverter()); - putWriteConverter(oldMap, new MyLocalDateTimeConverter()); - } else if (ALL_CONVERTER.equalsIgnoreCase(field.getName())) { - putAllConverter(oldMap, new LocalDateTimeConverter()); - putAllConverter(oldMap,new NumberToLocalDateTimeConverter()); - putWriteConverter(oldMap, new MyLocalDateTimeConverter()); - } - field.set(converters, oldMap); - } - } - } - return converters; - } - - private void putWriteConverter(Map map, Converter converter) { - map.put(ConverterKeyBuild.buildKey(converter.supportJavaTypeKey()), converter); - } - - private void putAllConverter(Map map, Converter converter) { - map.put(ConverterKeyBuild.buildKey(converter.supportJavaTypeKey(), converter.supportExcelTypeKey()), converter); - } +// //存放写时用到的converter +// private static final String ALL_CONVERTER = "allConverter"; +// //存放所有的converter +// private static final String WRITE_CONVERTER = "defaultWriteConverter"; +// +// @Bean +// @Primary +// public DefaultConverterLoader addConverter() throws IllegalAccessException { +// DefaultConverterLoader converters = new DefaultConverterLoader(); +// Field[] fields = converters.getClass().getDeclaredFields(); +// for (Field field : fields) { +// field.setAccessible(true); +// if (field.getType() == Map.class) { +// Map oldMap = (Map) field.get(converters); +// if (oldMap != null && !oldMap.isEmpty()) { +// if (WRITE_CONVERTER.equalsIgnoreCase(field.getName())) { +// putWriteConverter(oldMap, new LocalDateTimeConverter()); +// putAllConverter(oldMap,new NumberToLocalDateTimeConverter()); +// putWriteConverter(oldMap, new MyLocalDateTimeConverter()); +// } else if (ALL_CONVERTER.equalsIgnoreCase(field.getName())) { +// putAllConverter(oldMap, new LocalDateTimeConverter()); +// putAllConverter(oldMap,new NumberToLocalDateTimeConverter()); +// putWriteConverter(oldMap, new MyLocalDateTimeConverter()); +// } +// field.set(converters, oldMap); +// } +// } +// } +// return converters; +// } +// +// private void putWriteConverter(Map map, Converter converter) { +// map.put(ConverterKeyBuild.buildKey(converter.supportJavaTypeKey()), converter); +// } +// +// private void putAllConverter(Map map, Converter converter) { +// map.put(ConverterKeyBuild.buildKey(converter.supportJavaTypeKey(), converter.supportExcelTypeKey()), converter); +// } } diff --git a/secret-boot-framework-demo/common-demo/src/main/java/cn/chenc/framework/demo/config/MyBatisPlusConfig.java b/secret-boot-framework-demo/common-demo/src/main/java/cn/chenc/framework/demo/config/MyBatisPlusConfig.java index f7e8bce..3c6f379 100644 --- a/secret-boot-framework-demo/common-demo/src/main/java/cn/chenc/framework/demo/config/MyBatisPlusConfig.java +++ b/secret-boot-framework-demo/common-demo/src/main/java/cn/chenc/framework/demo/config/MyBatisPlusConfig.java @@ -1,25 +1,11 @@ package cn.chenc.framework.demo.config; -import com.alibaba.excel.metadata.GlobalConfiguration; import com.baomidou.mybatisplus.annotation.DbType; import com.baomidou.mybatisplus.autoconfigure.ConfigurationCustomizer; -import com.baomidou.mybatisplus.autoconfigure.SpringBootVFS; -import com.baomidou.mybatisplus.core.MybatisConfiguration; import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor; -import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean; -import org.apache.ibatis.io.VFS; -import org.apache.ibatis.plugin.Interceptor; -import org.apache.ibatis.session.SqlSessionFactory; -import org.apache.ibatis.type.JdbcType; -import org.mybatis.spring.SqlSessionFactoryBean; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.core.env.Environment; -import org.springframework.core.io.DefaultResourceLoader; - -import javax.sql.DataSource; /** *  @description: mybatisplus配置 diff --git a/secret-boot-framework-demo/common-demo/src/main/java/cn/chenc/framework/demo/controller/RoleController.java b/secret-boot-framework-demo/common-demo/src/main/java/cn/chenc/framework/demo/controller/RoleController.java index 7c39a1b..524b131 100644 --- a/secret-boot-framework-demo/common-demo/src/main/java/cn/chenc/framework/demo/controller/RoleController.java +++ b/secret-boot-framework-demo/common-demo/src/main/java/cn/chenc/framework/demo/controller/RoleController.java @@ -6,7 +6,6 @@ import cn.chenc.framework.demo.service.RoleService; import com.baomidou.mybatisplus.core.metadata.IPage; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; diff --git a/secret-boot-framework-demo/common-demo/src/main/java/cn/chenc/framework/demo/controller/UserController.java b/secret-boot-framework-demo/common-demo/src/main/java/cn/chenc/framework/demo/controller/UserController.java index 54cbdaf..66cdb7b 100644 --- a/secret-boot-framework-demo/common-demo/src/main/java/cn/chenc/framework/demo/controller/UserController.java +++ b/secret-boot-framework-demo/common-demo/src/main/java/cn/chenc/framework/demo/controller/UserController.java @@ -1,16 +1,26 @@ package cn.chenc.framework.demo.controller; import cn.chenc.framework.core.annotation.PreAuthorize; +import cn.chenc.framework.core.model.AbstractDictData; import cn.chenc.framework.core.model.response.AjaxResult; import cn.chenc.framework.core.model.response.ResponseVO; import cn.chenc.framework.core.model.response.ResultUtil; +import cn.chenc.framework.core.util.DictUtils; +import cn.chenc.framework.core.util.file.FileUtils; +import cn.chenc.framework.demo.entity.Dict; import cn.chenc.framework.demo.entity.User; import cn.chenc.framework.demo.service.UserService; +import cn.chenc.framework.mail.core.MailTemplate; +import cn.chenc.framework.poi.util.ExcelUtil; import com.baomidou.mybatisplus.core.metadata.IPage; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.web.bind.annotation.*; +import java.io.File; +import java.util.ArrayList; +import java.util.List; + /** *  @description: TODO *  @author secret @@ -25,6 +35,9 @@ public class UserController { private UserService userService; @Autowired RedisTemplate redisTemplate; + @Autowired + private MailTemplate mailTemplate; + @GetMapping("/test") public ResponseVO test(){ @@ -73,5 +86,31 @@ public class UserController { return AjaxResult.success(); } + @GetMapping("/testMail") + public AjaxResult testMail(){ + mailTemplate.sendSimpleMail("1029693356@qq.com","邮件标题","发送邮件测试"); + return AjaxResult.success(); + } + + @GetMapping("/testExportPoi") + public AjaxResult testExportPoi(){ + ExcelUtil excelUtil = new ExcelUtil(User.class); + List list = userService.list(); + List dictList = new ArrayList<>(); + Dict dict = new Dict(); + dict.setDictLabel("男"); + dict.setDictValue("0"); + dictList.add(dict); + DictUtils.setDictCache("user_sex",dictList); + return excelUtil.exportExcel(list,"导出用户列表"); + } + + @GetMapping("/testImportPoi") + public AjaxResult testImportPoi() throws Exception{ + ExcelUtil excelUtil = new ExcelUtil(User.class); + File file = new File("E:\\upload\\secret-boot-framework\\upload\\导入用户列表.xlsx"); + List list = excelUtil.importExcel(FileUtils.openInputStream(file)); + return AjaxResult.success(list); + } } diff --git a/secret-boot-framework-demo/common-demo/src/main/java/cn/chenc/framework/demo/converters/MyLocalDateTimeConverter.java b/secret-boot-framework-demo/common-demo/src/main/java/cn/chenc/framework/demo/converters/MyLocalDateTimeConverter.java index 4a15577..e2f3b65 100644 --- a/secret-boot-framework-demo/common-demo/src/main/java/cn/chenc/framework/demo/converters/MyLocalDateTimeConverter.java +++ b/secret-boot-framework-demo/common-demo/src/main/java/cn/chenc/framework/demo/converters/MyLocalDateTimeConverter.java @@ -1,12 +1,14 @@ package cn.chenc.framework.demo.converters; -import com.alibaba.excel.annotation.format.DateTimeFormat; -import com.alibaba.excel.converters.Converter; -import com.alibaba.excel.enums.CellDataTypeEnum; -import com.alibaba.excel.metadata.CellData; -import com.alibaba.excel.metadata.GlobalConfiguration; -import com.alibaba.excel.metadata.property.ExcelContentProperty; +//import com.alibaba.excel.annotation.format.DateTimeFormat; +//import com.alibaba.excel.converters.Converter; +//import com.alibaba.excel.enums.CellDataTypeEnum; +//import com.alibaba.excel.metadata.CellData; +//import com.alibaba.excel.metadata.GlobalConfiguration; +//import com.alibaba.excel.metadata.property.ExcelContentProperty; + +import org.springframework.format.annotation.DateTimeFormat; import java.time.LocalDate; import java.time.LocalDateTime; @@ -14,12 +16,12 @@ import java.time.format.DateTimeFormatter; import java.util.Objects; /** - *  @description: TODO + *  @description: easyexcel自定义格式转化器 *  @author 陈_C *  @date 2020/8/26 16:32 * */ -public class MyLocalDateTimeConverter implements Converter { +public class MyLocalDateTimeConverter /*implements Converter*/ { /** * 不使用{@code @LocalDateTimeFormat}注解指定日期格式时,默认会使用该格式. @@ -32,15 +34,15 @@ public class MyLocalDateTimeConverter implements Converter { private static final String READ_PATTERN = "yyyy-MM-dd"; - @Override - public Class supportJavaTypeKey() { - return LocalDateTime.class; - } - - @Override - public CellDataTypeEnum supportExcelTypeKey() { - return CellDataTypeEnum.STRING; - } +// @Override +// public Class supportJavaTypeKey() { +// return LocalDateTime.class; +// } +// +// @Override +// public CellDataTypeEnum supportExcelTypeKey() { +// return CellDataTypeEnum.STRING; +// } /** * 这里读的时候会调用 @@ -50,15 +52,15 @@ public class MyLocalDateTimeConverter implements Converter { * @param globalConfiguration 全局配置 (NotNull) * @return 读取到内存中的数据 */ - @Override - public LocalDateTime convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { - DateTimeFormat annotation = contentProperty.getField().getAnnotation(DateTimeFormat.class); - LocalDate localDate = LocalDate.parse(cellData.getStringValue(), DateTimeFormatter.ofPattern(Objects.nonNull(annotation) ? annotation.value() : READ_PATTERN)); - LocalDateTime localDateTime = localDate.atStartOfDay(); -// return LocalDateTime.parse(cellData.getStringValue(), -// DateTimeFormatter.ofPattern(Objects.nonNull(annotation) ? annotation.value() : DEFAULT_PATTERN)); - return localDateTime; - } +// @Override +// public LocalDateTime convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { +// DateTimeFormat annotation = contentProperty.getField().getAnnotation(DateTimeFormat.class); +// LocalDate localDate = LocalDate.parse(cellData.getStringValue(), DateTimeFormatter.ofPattern(Objects.nonNull(annotation) ? annotation.value() : READ_PATTERN)); +// LocalDateTime localDateTime = localDate.atStartOfDay(); +//// return LocalDateTime.parse(cellData.getStringValue(), +//// DateTimeFormatter.ofPattern(Objects.nonNull(annotation) ? annotation.value() : DEFAULT_PATTERN)); +// return localDateTime; +// } /** @@ -69,10 +71,10 @@ public class MyLocalDateTimeConverter implements Converter { * @param globalConfiguration 全局配置 (NotNull) * @return 写出到excel文件的数据 */ - @Override - public CellData convertToExcelData(LocalDateTime value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { - DateTimeFormat annotation = contentProperty.getField().getAnnotation(DateTimeFormat.class); - return new CellData(value.format(DateTimeFormatter.ofPattern(Objects.nonNull(annotation) ? annotation.value() : DEFAULT_PATTERN))); - } +// @Override +// public CellData convertToExcelData(LocalDateTime value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { +// DateTimeFormat annotation = contentProperty.getField().getAnnotation(DateTimeFormat.class); +// return new CellData(value.format(DateTimeFormatter.ofPattern(Objects.nonNull(annotation) ? annotation.value() : DEFAULT_PATTERN))); +// } } diff --git a/secret-boot-framework-demo/common-demo/src/main/java/cn/chenc/framework/demo/entity/Dict.java b/secret-boot-framework-demo/common-demo/src/main/java/cn/chenc/framework/demo/entity/Dict.java new file mode 100644 index 0000000..cb46aa5 --- /dev/null +++ b/secret-boot-framework-demo/common-demo/src/main/java/cn/chenc/framework/demo/entity/Dict.java @@ -0,0 +1,36 @@ +package cn.chenc.framework.demo.entity; + +import cn.chenc.framework.core.model.AbstractDictData; + +import java.io.Serializable; + +/** + *  @description: TODO + *  @author secret + *  @date 2021/7/31 23:06 + * + */ +public class Dict implements AbstractDictData, Serializable { + + private String dictLabel; + + private String dictValue; + + public void setDictLabel(String dictLabel) { + this.dictLabel = dictLabel; + } + + public void setDictValue(String dictValue) { + this.dictValue = dictValue; + } + + @Override + public String getDictLabel() { + return dictLabel; + } + + @Override + public String getDictValue() { + return dictValue; + } +} diff --git a/secret-boot-framework-demo/common-demo/src/main/java/cn/chenc/framework/demo/entity/User.java b/secret-boot-framework-demo/common-demo/src/main/java/cn/chenc/framework/demo/entity/User.java index eca74d9..2049e97 100644 --- a/secret-boot-framework-demo/common-demo/src/main/java/cn/chenc/framework/demo/entity/User.java +++ b/secret-boot-framework-demo/common-demo/src/main/java/cn/chenc/framework/demo/entity/User.java @@ -1,6 +1,7 @@ package cn.chenc.framework.demo.entity; import cn.chenc.framework.mybatisplus.model.BaseEntity; +import cn.chenc.framework.poi.annotation.Excel; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; @@ -30,16 +31,19 @@ public class User extends BaseEntity implements Serializable { /** * 用户名 */ + @Excel(name="用户名") private String username; /** * 性别,0:女,1男 */ + @Excel(name="性别",dictType = "user_sex") private Integer sex; /** * 生日 */ + @Excel(name="生日",dateFormat = "yyyy-MM-dd") private LocalDateTime birthday; @TableField(exist = false) diff --git a/secret-boot-framework-demo/common-demo/src/main/resources/application-dev.yml b/secret-boot-framework-demo/common-demo/src/main/resources/application-dev.yml index 0585a3d..7b878dd 100644 --- a/secret-boot-framework-demo/common-demo/src/main/resources/application-dev.yml +++ b/secret-boot-framework-demo/common-demo/src/main/resources/application-dev.yml @@ -63,6 +63,27 @@ spring: timeout: 5000ms # 默认的数据过期时间 expire: 2592000 + mail: + #smtp服务主机 qq邮箱则为smtp.qq.com + host: smtp.qq.com + #服务协议 + protocol: smtp + # 编码集 + default-encoding: UTF-8 + #发送邮件的账户 + username: 1029693356@qq.com + #授权码 + password: wtktmncfdiivbejh + test-connection: false + # 服务端口 + port: 587 + properties: + mail: + smtp: + auth: true + starttls: + enable: true + required: true #日志 logging: @@ -70,5 +91,8 @@ logging: root: debug # org.springframework.scheduling: INFO +#secret-config +secret-config: + profile: E:\upload\secret-boot-framework ####################################自定义配置########################################## diff --git a/secret-boot-framework-demo/jpa-demo/src/main/java/cn/chenc/framework/demo/config/DemoSourceConfig.java b/secret-boot-framework-demo/jpa-demo/src/main/java/cn/chenc/framework/demo/config/DemoSourceConfig.java index 1e9bd26..7592d09 100644 --- a/secret-boot-framework-demo/jpa-demo/src/main/java/cn/chenc/framework/demo/config/DemoSourceConfig.java +++ b/secret-boot-framework-demo/jpa-demo/src/main/java/cn/chenc/framework/demo/config/DemoSourceConfig.java @@ -3,7 +3,6 @@ package cn.chenc.framework.demo.config; import cn.chenc.framework.jpa.support.BaseJpaRepositoryFactoryBean; import org.springframework.context.annotation.Configuration; import org.springframework.data.jpa.repository.config.EnableJpaRepositories; -import org.springframework.transaction.annotation.EnableTransactionManagement; /** *  @description: TODO diff --git a/secret-boot-framework-demo/jpa-demo/src/main/java/cn/chenc/framework/demo/controller/UserController.java b/secret-boot-framework-demo/jpa-demo/src/main/java/cn/chenc/framework/demo/controller/UserController.java index 8f016ab..b6b0b93 100644 --- a/secret-boot-framework-demo/jpa-demo/src/main/java/cn/chenc/framework/demo/controller/UserController.java +++ b/secret-boot-framework-demo/jpa-demo/src/main/java/cn/chenc/framework/demo/controller/UserController.java @@ -5,7 +5,6 @@ import cn.chenc.framework.demo.entity.UserEntity; import cn.chenc.framework.demo.service.UserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; -import org.springframework.web.bind.annotation.*; import java.util.List; diff --git a/secret-boot-framework-demo/jpa-demo/src/main/java/cn/chenc/framework/demo/dao/UserRepository.java b/secret-boot-framework-demo/jpa-demo/src/main/java/cn/chenc/framework/demo/dao/UserRepository.java index 60c69d8..87a64f9 100644 --- a/secret-boot-framework-demo/jpa-demo/src/main/java/cn/chenc/framework/demo/dao/UserRepository.java +++ b/secret-boot-framework-demo/jpa-demo/src/main/java/cn/chenc/framework/demo/dao/UserRepository.java @@ -2,8 +2,6 @@ package cn.chenc.framework.demo.dao; import cn.chenc.framework.demo.entity.UserEntity; import cn.chenc.framework.jpa.repository.BaseRepository; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.JpaSpecificationExecutor; import org.springframework.stereotype.Repository; /** diff --git a/secret-boot-framework-demo/jpa-demo/src/main/java/cn/chenc/framework/demo/entity/UserEntity.java b/secret-boot-framework-demo/jpa-demo/src/main/java/cn/chenc/framework/demo/entity/UserEntity.java index 016d755..e51dc5b 100644 --- a/secret-boot-framework-demo/jpa-demo/src/main/java/cn/chenc/framework/demo/entity/UserEntity.java +++ b/secret-boot-framework-demo/jpa-demo/src/main/java/cn/chenc/framework/demo/entity/UserEntity.java @@ -2,7 +2,6 @@ package cn.chenc.framework.demo.entity; import cn.chenc.framework.jpa.model.BaseEntity; -import javax.persistence.*; import java.io.Serializable; import java.time.LocalDateTime; @@ -11,7 +10,7 @@ import java.time.LocalDateTime; *  @author secret *  @date 2021/5/14 14:51 * - */ + */ @Entity @Table(name = "user", schema = "secret_framework") public class UserEntity extends BaseEntity implements Serializable { diff --git a/secret-boot-framework-demo/jpa-demo/src/main/java/cn/chenc/framework/demo/service/UserService.java b/secret-boot-framework-demo/jpa-demo/src/main/java/cn/chenc/framework/demo/service/UserService.java index bc49213..f86c494 100644 --- a/secret-boot-framework-demo/jpa-demo/src/main/java/cn/chenc/framework/demo/service/UserService.java +++ b/secret-boot-framework-demo/jpa-demo/src/main/java/cn/chenc/framework/demo/service/UserService.java @@ -5,7 +5,6 @@ import cn.chenc.framework.demo.entity.UserEntity; import cn.chenc.framework.jpa.service.BaseService; import org.springframework.data.domain.Page; -import javax.persistence.criteria.CriteriaBuilder; import java.util.List; /** diff --git a/secret-boot-framework-demo/jpa-demo/src/main/java/cn/chenc/framework/demo/service/impl/UserServiceImpl.java b/secret-boot-framework-demo/jpa-demo/src/main/java/cn/chenc/framework/demo/service/impl/UserServiceImpl.java index add58d6..c1a1e80 100644 --- a/secret-boot-framework-demo/jpa-demo/src/main/java/cn/chenc/framework/demo/service/impl/UserServiceImpl.java +++ b/secret-boot-framework-demo/jpa-demo/src/main/java/cn/chenc/framework/demo/service/impl/UserServiceImpl.java @@ -4,9 +4,7 @@ import cn.chenc.framework.core.util.StringUtils; import cn.chenc.framework.demo.dao.UserRepository; import cn.chenc.framework.demo.entity.UserEntity; import cn.chenc.framework.demo.service.UserService; -import cn.chenc.framework.jpa.repository.BaseRepository; import cn.chenc.framework.jpa.service.BaseServiceImpl; -import cn.chenc.framework.jpa.util.PageUtil; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; diff --git a/secret-boot-framework-mail/src/main/java/cn/chenc/framework/mail/config/MailConfiguration.java b/secret-boot-framework-mail/src/main/java/cn/chenc/framework/mail/config/MailConfiguration.java index 6915d80..18605c1 100644 --- a/secret-boot-framework-mail/src/main/java/cn/chenc/framework/mail/config/MailConfiguration.java +++ b/secret-boot-framework-mail/src/main/java/cn/chenc/framework/mail/config/MailConfiguration.java @@ -2,10 +2,8 @@ package cn.chenc.framework.mail.config; import cn.chenc.framework.mail.core.MailTemplate; import cn.chenc.framework.mail.core.SecretMailTemplate; -import org.springframework.boot.autoconfigure.AutoConfigureAfter; -import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.mail.MailProperties; -import org.springframework.boot.autoconfigure.mail.MailSenderAutoConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.mail.javamail.JavaMailSender; @@ -19,7 +17,6 @@ import javax.annotation.Resource; * */ @Configuration -@AutoConfigureAfter(MailSenderAutoConfiguration.class) public class MailConfiguration { @Resource @@ -29,7 +26,7 @@ public class MailConfiguration { private MailProperties mailProperties; @Bean - @ConditionalOnBean({MailProperties.class, JavaMailSender.class}) + @ConditionalOnClass({MailProperties.class, JavaMailSender.class}) public MailTemplate mailTemplate() { return new SecretMailTemplate(mailSender,mailProperties); } diff --git a/secret-boot-framework-poi/src/main/java/cn/chenc/framework/poi/util/ExcelUtil.java b/secret-boot-framework-poi/src/main/java/cn/chenc/framework/poi/util/ExcelUtil.java index bfe737c..1dd00ee 100644 --- a/secret-boot-framework-poi/src/main/java/cn/chenc/framework/poi/util/ExcelUtil.java +++ b/secret-boot-framework-poi/src/main/java/cn/chenc/framework/poi/util/ExcelUtil.java @@ -26,6 +26,7 @@ import java.io.*; import java.lang.reflect.Field; import java.math.BigDecimal; import java.text.DecimalFormat; +import java.time.LocalDateTime; import java.util.*; import java.util.stream.Collectors; @@ -596,7 +597,11 @@ public class ExcelUtil { String dictType = attr.dictType(); if (StringUtils.isNotEmpty(dateFormat) && StringUtils.isNotNull(value)) { - cell.setCellValue(DateUtils.format((Date) value, dateFormat)); + if(value instanceof LocalDateTime){ + cell.setCellValue(cn.hutool.core.date.DateUtil.format((LocalDateTime) value,dateFormat)); + } else { + cell.setCellValue(DateUtils.format((Date) value, dateFormat)); + } } else if (StringUtils.isNotEmpty(readConverterExp) && StringUtils.isNotNull(value)) { diff --git a/secret-boot-framework-poi/src/main/java/cn/chenc/framework/poi/util/ReflectUtils.java b/secret-boot-framework-poi/src/main/java/cn/chenc/framework/poi/util/ReflectUtils.java index 93f0311..cc6ebd6 100644 --- a/secret-boot-framework-poi/src/main/java/cn/chenc/framework/poi/util/ReflectUtils.java +++ b/secret-boot-framework-poi/src/main/java/cn/chenc/framework/poi/util/ReflectUtils.java @@ -10,6 +10,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.lang.reflect.*; +import java.time.LocalDateTime; import java.util.Date; /** @@ -159,6 +160,14 @@ public class ReflectUtils { } else { args[i] = DateUtil.getJavaDate((Double) args[i]); } + } else if(cs[i] == LocalDateTime.class){ + if (args[i] instanceof String) { + args[i] = DateUtils.parseLocalDateTime(args[i].toString()); + } else if(args[i] instanceof Date){ + args[i] = DateUtils.dateToLocalDateTime((Date) args[i]); + } else { + args[i] = DateUtil.getLocalDateTime((Double) args[i]); + } } else if (cs[i] == boolean.class || cs[i] == Boolean.class) { args[i] = Convert.toBool(args[i]); } -- Gitee From f86a5013e0315f405812222bfa69fffa196a3847 Mon Sep 17 00:00:00 2001 From: secret <1029693356@qq.com> Date: Sun, 1 Aug 2021 16:09:49 +0800 Subject: [PATCH 09/11] =?UTF-8?q?common-demo=20=E9=9B=86=E6=88=90dozer=20d?= =?UTF-8?q?emo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 8 +++--- .../common-demo/pom.xml | 4 +++ .../framework/demo/CommonDemoApplication.java | 1 + .../framework/demo/config/ExcelConfig.java | 1 - .../demo/config/MyBatisPlusConfig.java | 4 --- .../demo/controller/UserController.java | 16 ++++++++++++ .../converters/MyLocalDateTimeConverter.java | 7 ------ .../chenc/framework/demo/entity/UserCopy.java | 25 +++++++++++++++++++ secret-boot-framework-dependencies/pom.xml | 25 +++++++++---------- .../dozer/component/DozerTemplate.java | 8 +++--- .../dozer/config/DozerConfiguration.java | 2 +- .../dozer/properties/DozerProperties.java | 2 -- .../mail/config/MailConfiguration.java | 7 +++--- 13 files changed, 70 insertions(+), 40 deletions(-) create mode 100644 secret-boot-framework-demo/common-demo/src/main/java/cn/chenc/framework/demo/entity/UserCopy.java diff --git a/pom.xml b/pom.xml index 640e4a2..f2f18ef 100644 --- a/pom.xml +++ b/pom.xml @@ -36,7 +36,7 @@ 3.2.1 - 2.9.1 + 3.3.0 1.6 @@ -100,15 +100,15 @@ org.apache.maven.plugins maven-javadoc-plugin ${maven-javadoc-plugin.version} - - -Xdoclint:none - package jar + + -Xdoclint:none + diff --git a/secret-boot-framework-demo/common-demo/pom.xml b/secret-boot-framework-demo/common-demo/pom.xml index 97642eb..e786c40 100644 --- a/secret-boot-framework-demo/common-demo/pom.xml +++ b/secret-boot-framework-demo/common-demo/pom.xml @@ -54,6 +54,10 @@ com.gitee.secretopen secret-boot-framework-poi + + com.gitee.secretopen + secret-boot-framework-dozer + diff --git a/secret-boot-framework-demo/common-demo/src/main/java/cn/chenc/framework/demo/CommonDemoApplication.java b/secret-boot-framework-demo/common-demo/src/main/java/cn/chenc/framework/demo/CommonDemoApplication.java index fbf91fd..9e2810b 100644 --- a/secret-boot-framework-demo/common-demo/src/main/java/cn/chenc/framework/demo/CommonDemoApplication.java +++ b/secret-boot-framework-demo/common-demo/src/main/java/cn/chenc/framework/demo/CommonDemoApplication.java @@ -3,6 +3,7 @@ package cn.chenc.framework.demo; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; +import org.springframework.context.annotation.ComponentScan; import org.springframework.transaction.annotation.EnableTransactionManagement; /** diff --git a/secret-boot-framework-demo/common-demo/src/main/java/cn/chenc/framework/demo/config/ExcelConfig.java b/secret-boot-framework-demo/common-demo/src/main/java/cn/chenc/framework/demo/config/ExcelConfig.java index 1b267a4..066db05 100644 --- a/secret-boot-framework-demo/common-demo/src/main/java/cn/chenc/framework/demo/config/ExcelConfig.java +++ b/secret-boot-framework-demo/common-demo/src/main/java/cn/chenc/framework/demo/config/ExcelConfig.java @@ -1,7 +1,6 @@ package cn.chenc.framework.demo.config; //import cn.chenc.framework.excel.config.CustomerDefaultConverterLoader; -import org.springframework.boot.autoconfigure.AutoConfigureAfter; import org.springframework.context.annotation.Configuration; /** diff --git a/secret-boot-framework-demo/common-demo/src/main/java/cn/chenc/framework/demo/config/MyBatisPlusConfig.java b/secret-boot-framework-demo/common-demo/src/main/java/cn/chenc/framework/demo/config/MyBatisPlusConfig.java index 3c6f379..1504f5c 100644 --- a/secret-boot-framework-demo/common-demo/src/main/java/cn/chenc/framework/demo/config/MyBatisPlusConfig.java +++ b/secret-boot-framework-demo/common-demo/src/main/java/cn/chenc/framework/demo/config/MyBatisPlusConfig.java @@ -27,10 +27,6 @@ public class MyBatisPlusConfig { return interceptor; } - @Bean - public ConfigurationCustomizer configurationCustomizer() { - return configuration -> configuration.setUseDeprecatedExecutor(false); - } // @Bean // public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception { diff --git a/secret-boot-framework-demo/common-demo/src/main/java/cn/chenc/framework/demo/controller/UserController.java b/secret-boot-framework-demo/common-demo/src/main/java/cn/chenc/framework/demo/controller/UserController.java index 66cdb7b..e6985eb 100644 --- a/secret-boot-framework-demo/common-demo/src/main/java/cn/chenc/framework/demo/controller/UserController.java +++ b/secret-boot-framework-demo/common-demo/src/main/java/cn/chenc/framework/demo/controller/UserController.java @@ -1,6 +1,7 @@ package cn.chenc.framework.demo.controller; import cn.chenc.framework.core.annotation.PreAuthorize; +import cn.chenc.framework.core.component.AbstractJwtTemplate; import cn.chenc.framework.core.model.AbstractDictData; import cn.chenc.framework.core.model.response.AjaxResult; import cn.chenc.framework.core.model.response.ResponseVO; @@ -9,12 +10,16 @@ import cn.chenc.framework.core.util.DictUtils; import cn.chenc.framework.core.util.file.FileUtils; import cn.chenc.framework.demo.entity.Dict; import cn.chenc.framework.demo.entity.User; +import cn.chenc.framework.demo.entity.UserCopy; import cn.chenc.framework.demo.service.UserService; +import cn.chenc.framework.dozer.component.DozerTemplate; import cn.chenc.framework.mail.core.MailTemplate; import cn.chenc.framework.poi.util.ExcelUtil; import com.baomidou.mybatisplus.core.metadata.IPage; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.mail.MailProperties; import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.mail.javamail.JavaMailSender; import org.springframework.web.bind.annotation.*; import java.io.File; @@ -37,6 +42,8 @@ public class UserController { RedisTemplate redisTemplate; @Autowired private MailTemplate mailTemplate; + @Autowired + private DozerTemplate dozerTemplate; @GetMapping("/test") @@ -113,4 +120,13 @@ public class UserController { return AjaxResult.success(list); } + @GetMapping("/testDozer") + public AjaxResult testDozer() { + User user = new User(); + user.setUsername("secret"); + user.setSex(0); + UserCopy userCopy = dozerTemplate.map(user, UserCopy.class); + return AjaxResult.success(userCopy); + } + } diff --git a/secret-boot-framework-demo/common-demo/src/main/java/cn/chenc/framework/demo/converters/MyLocalDateTimeConverter.java b/secret-boot-framework-demo/common-demo/src/main/java/cn/chenc/framework/demo/converters/MyLocalDateTimeConverter.java index e2f3b65..027e355 100644 --- a/secret-boot-framework-demo/common-demo/src/main/java/cn/chenc/framework/demo/converters/MyLocalDateTimeConverter.java +++ b/secret-boot-framework-demo/common-demo/src/main/java/cn/chenc/framework/demo/converters/MyLocalDateTimeConverter.java @@ -8,13 +8,6 @@ package cn.chenc.framework.demo.converters; //import com.alibaba.excel.metadata.GlobalConfiguration; //import com.alibaba.excel.metadata.property.ExcelContentProperty; -import org.springframework.format.annotation.DateTimeFormat; - -import java.time.LocalDate; -import java.time.LocalDateTime; -import java.time.format.DateTimeFormatter; -import java.util.Objects; - /** *  @description: easyexcel自定义格式转化器 *  @author 陈_C diff --git a/secret-boot-framework-demo/common-demo/src/main/java/cn/chenc/framework/demo/entity/UserCopy.java b/secret-boot-framework-demo/common-demo/src/main/java/cn/chenc/framework/demo/entity/UserCopy.java new file mode 100644 index 0000000..d51b26f --- /dev/null +++ b/secret-boot-framework-demo/common-demo/src/main/java/cn/chenc/framework/demo/entity/UserCopy.java @@ -0,0 +1,25 @@ +package cn.chenc.framework.demo.entity; + +import cn.chenc.framework.poi.annotation.Excel; +import lombok.Data; + +import java.io.Serializable; + +/** + *  @description: TODO + *  @author secret + *  @date 2021/8/1 15:57 + * + */ +@Data +public class UserCopy implements Serializable { + /** + * 用户名 + */ + private String username; + + /** + * 性别,0:女,1男 + */ + private Integer sex; +} diff --git a/secret-boot-framework-dependencies/pom.xml b/secret-boot-framework-dependencies/pom.xml index 6475897..7251c2d 100644 --- a/secret-boot-framework-dependencies/pom.xml +++ b/secret-boot-framework-dependencies/pom.xml @@ -5,7 +5,7 @@ org.springframework.boot spring-boot-starter-parent - 2.4.5 + 2.5.3 4.0.0 @@ -21,26 +21,25 @@ 1.8 1.6.0 - 2.4.3.RELEASE 1.2.6 - 8.0.25 + 8.0.26 - 2.8.0 + 2.11.0 1.4 1.9 3.8.0 - 1.10.10 + 1.10.11 4.5.13 4.9.1 1.18.20 3.0.0 30.1.1-jre - 3.4.2 - 1.13.1 + 3.4.3.1 + 1.14.1 1.21 0.62.2 - 5.6.5 + 5.7.6 2.2.9 4.1.2 @@ -48,12 +47,12 @@ 1.7.1 - 3.15.4 + 3.16.1 6.5.2 3.2.1 - 2.9.1 + 3.3.0 1.6 @@ -334,15 +333,15 @@ org.apache.maven.plugins maven-javadoc-plugin ${maven-javadoc-plugin.version} - - -Xdoclint:none - package jar + + -Xdoclint:none + diff --git a/secret-boot-framework-dozer/src/main/java/cn/chenc/framework/dozer/component/DozerTemplate.java b/secret-boot-framework-dozer/src/main/java/cn/chenc/framework/dozer/component/DozerTemplate.java index 08319d9..0b9bdcb 100644 --- a/secret-boot-framework-dozer/src/main/java/cn/chenc/framework/dozer/component/DozerTemplate.java +++ b/secret-boot-framework-dozer/src/main/java/cn/chenc/framework/dozer/component/DozerTemplate.java @@ -26,7 +26,7 @@ public class DozerTemplate { } /** - * Constructs new instance of destinationClass and performs mapping between from source + * 构造destinationClass的新实例,并在源代码之间执行映射 * * @param source * @param destinationClass @@ -51,7 +51,7 @@ public class DozerTemplate { } /** - * Performs mapping between source and destination objects + * 在源对象和目标对象之间执行映射 * * @param source * @param destination @@ -64,7 +64,7 @@ public class DozerTemplate { } /** - * Constructs new instance of destinationClass and performs mapping between from source + * 构造destinationClass的新实例,并在源代码之间执行映射 * * @param source * @param destinationClass @@ -80,7 +80,7 @@ public class DozerTemplate { } /** - * Performs mapping between source and destination objects + * 在源对象和目标对象之间执行映射 * * @param source * @param destination diff --git a/secret-boot-framework-dozer/src/main/java/cn/chenc/framework/dozer/config/DozerConfiguration.java b/secret-boot-framework-dozer/src/main/java/cn/chenc/framework/dozer/config/DozerConfiguration.java index 0c33395..3cb6c77 100644 --- a/secret-boot-framework-dozer/src/main/java/cn/chenc/framework/dozer/config/DozerConfiguration.java +++ b/secret-boot-framework-dozer/src/main/java/cn/chenc/framework/dozer/config/DozerConfiguration.java @@ -36,7 +36,7 @@ public class DozerConfiguration { } @Bean - public DozerTemplate getDozerUtil(Mapper mapper) { + public DozerTemplate dozerTemplate(Mapper mapper) { return new DozerTemplate(mapper); } diff --git a/secret-boot-framework-dozer/src/main/java/cn/chenc/framework/dozer/properties/DozerProperties.java b/secret-boot-framework-dozer/src/main/java/cn/chenc/framework/dozer/properties/DozerProperties.java index bc34d8f..644184d 100644 --- a/secret-boot-framework-dozer/src/main/java/cn/chenc/framework/dozer/properties/DozerProperties.java +++ b/secret-boot-framework-dozer/src/main/java/cn/chenc/framework/dozer/properties/DozerProperties.java @@ -4,7 +4,6 @@ import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.core.io.Resource; import org.springframework.core.io.support.PathMatchingResourcePatternResolver; import org.springframework.core.io.support.ResourcePatternResolver; -import org.springframework.stereotype.Component; import java.io.IOException; import java.util.Arrays; @@ -17,7 +16,6 @@ import java.util.stream.Stream; *  @date 2021/7/26 23:01 * */ -@Component @ConfigurationProperties(prefix = "dozer") public class DozerProperties { private static final ResourcePatternResolver PATTERN_RESOLVER = new PathMatchingResourcePatternResolver(); diff --git a/secret-boot-framework-mail/src/main/java/cn/chenc/framework/mail/config/MailConfiguration.java b/secret-boot-framework-mail/src/main/java/cn/chenc/framework/mail/config/MailConfiguration.java index 18605c1..5fcff7a 100644 --- a/secret-boot-framework-mail/src/main/java/cn/chenc/framework/mail/config/MailConfiguration.java +++ b/secret-boot-framework-mail/src/main/java/cn/chenc/framework/mail/config/MailConfiguration.java @@ -2,14 +2,13 @@ package cn.chenc.framework.mail.config; import cn.chenc.framework.mail.core.MailTemplate; import cn.chenc.framework.mail.core.SecretMailTemplate; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.mail.MailProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.mail.javamail.JavaMailSender; -import javax.annotation.Resource; - /** *  @description: 邮件配置 *  @author secret @@ -19,10 +18,10 @@ import javax.annotation.Resource; @Configuration public class MailConfiguration { - @Resource + @Autowired private JavaMailSender mailSender; - @Resource + @Autowired private MailProperties mailProperties; @Bean -- Gitee From d55facce49eaae425ad9e5b65ec0c8d6c8dfe981 Mon Sep 17 00:00:00 2001 From: secret <1029693356@qq.com> Date: Sun, 1 Aug 2021 16:18:25 +0800 Subject: [PATCH 10/11] =?UTF-8?q?=E6=9B=B4=E6=96=B0=201.6.0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 10 +++++----- .../security/repository/RedisTokenRepositoryImpl.java | 3 +-- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index d4a3c7f..f28a160 100644 --- a/README.md +++ b/README.md @@ -52,7 +52,7 @@ secret-boot脚手架(根据核心依赖版本长期更新,正常更新周期 com.gitee.secretopen secret-boot-framework-dependencies - 1.5.0 + 1.6.0 pom import @@ -62,18 +62,18 @@ secret-boot脚手架(根据核心依赖版本长期更新,正常更新周期 com.gitee.secretopen secret-boot-framework-all - 1.5.0 + 1.6.0 ``` #### 核心依赖 | 组件 | 版本 | | ---- | ---- | -| springboot | 2.4.3 | -| mybatis-plus | 3.4.2 | +| springboot | 2.5.3 | +| mybatis-plus | 3.4.3 | | mysql | 5.7/8.x | | redis | | -| hutool | 5.5.9 | +| hutool | | #### 截图 ![avatar](http://secretOpen.gitee.io/secret-boot-framework/img1.png) diff --git a/secret-boot-framework-security/src/main/java/cn/chenc/framework/security/repository/RedisTokenRepositoryImpl.java b/secret-boot-framework-security/src/main/java/cn/chenc/framework/security/repository/RedisTokenRepositoryImpl.java index 0b9825b..f0f9c73 100644 --- a/secret-boot-framework-security/src/main/java/cn/chenc/framework/security/repository/RedisTokenRepositoryImpl.java +++ b/secret-boot-framework-security/src/main/java/cn/chenc/framework/security/repository/RedisTokenRepositoryImpl.java @@ -9,7 +9,6 @@ import org.springframework.data.redis.core.ScanOptions; import org.springframework.security.web.authentication.rememberme.PersistentRememberMeToken; import org.springframework.security.web.authentication.rememberme.PersistentTokenRepository; -import java.io.IOException; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; @@ -163,7 +162,7 @@ public class RedisTokenRepositoryImpl implements PersistentTokenRepository { return; } } - } catch (IOException ex) { + } catch (Exception ex) { log.warn("token remove exception", ex); } } -- Gitee From 56e9220201d0a6ba1e97b4d42b2d4064a65d79d9 Mon Sep 17 00:00:00 2001 From: secret <1029693356@qq.com> Date: Sun, 1 Aug 2021 16:39:14 +0800 Subject: [PATCH 11/11] =?UTF-8?q?=E6=9B=B4=E6=96=B0=201.6.0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index f28a160..48b1c3e 100644 --- a/README.md +++ b/README.md @@ -27,6 +27,7 @@ secret-boot脚手架(根据核心依赖版本长期更新,正常更新周期 | secret-boot-framework-excel | excel工具模块 | | secret-boot-framework-ffmpeg | ffmpet工具模块 | | secret-boot-framework-jpa | jpa扩展模块 | +| secret-boot-framework-mail | mail封装模块 | | secret-boot-framework-mybatis-plus | mybatis-plus扩展模块 | | secret-boot-framework-poi | poi封装模块 | | secret-boot-framework-security | spring-security扩展模块 | -- Gitee