commit ae0b2dcd6e140537742b11ffeb384c7f9b0dea9f Author: dimengzhe <251008545@qq.com> Date: Mon Apr 17 23:02:30 2023 +0800 项目构建 diff --git a/HELP.md b/HELP.md new file mode 100644 index 0000000..744564c --- /dev/null +++ b/HELP.md @@ -0,0 +1,6 @@ +#1、搭建框架 +#2、数据库设计 +#3、页面设计 +#4、编写代码 + + diff --git a/demo-common/demo-common-base/pom.xml b/demo-common/demo-common-base/pom.xml new file mode 100644 index 0000000..96a7f41 --- /dev/null +++ b/demo-common/demo-common-base/pom.xml @@ -0,0 +1,28 @@ + + + + com.yxt.demo + demo-common + 0.0.1 + + 4.0.0 + demo-common-base + 0.0.1 + + + + com.yxt.demo + demo-common-core + 0.0.1 + + + org.springframework.boot + spring-boot-starter-web + + + + + + \ No newline at end of file diff --git a/demo-common/demo-common-base/src/main/java/com/yxt/demo/common/base/config/handler/CustomException.java b/demo-common/demo-common-base/src/main/java/com/yxt/demo/common/base/config/handler/CustomException.java new file mode 100644 index 0000000..d30f871 --- /dev/null +++ b/demo-common/demo-common-base/src/main/java/com/yxt/demo/common/base/config/handler/CustomException.java @@ -0,0 +1,44 @@ +package com.yxt.demo.common.base.config.handler; + + +/** + * @Author dimengzhe + * @Date 2022/5/13 17:23 + * @Description + */ +public class CustomException extends Exception { + + private static final long serialVersionUID = 1L; + + + public CustomException() { + super(); + } + + public CustomException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } + + /** + * @param message + * @param cause + */ + public CustomException(String message, Throwable cause) { + super(message, cause); + } + + /** + * @param message + */ + public CustomException(String message) { + super(message); + } + + /** + * @param cause + */ + public CustomException(Throwable cause) { + super(cause); + } + +} diff --git a/demo-common/demo-common-base/src/main/java/com/yxt/demo/common/base/config/utils/SpringUtil.java b/demo-common/demo-common-base/src/main/java/com/yxt/demo/common/base/config/utils/SpringUtil.java new file mode 100644 index 0000000..f0b347d --- /dev/null +++ b/demo-common/demo-common-base/src/main/java/com/yxt/demo/common/base/config/utils/SpringUtil.java @@ -0,0 +1,72 @@ +package com.yxt.demo.common.base.config.utils; + +import org.springframework.beans.BeansException; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; +import org.springframework.stereotype.Component; + +import java.util.Map; + +/** + * @Author dimengzhe + * @Date 2022/7/10 14:42 + * @Description + */ +@Component +public class SpringUtil implements ApplicationContextAware { + + private static ApplicationContext applicationContext; + + @Override + public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { + if (SpringUtil.applicationContext == null) { + SpringUtil.applicationContext = applicationContext; + } + } + + // 获取applicationContext + public static ApplicationContext getApplicationContext() { + return applicationContext; + } + + // 通过name获取 Bean. + public static Object getBean(String name) { + return getApplicationContext().getBean(name); + } + + // 通过class获取Bean. + public static T getBean(Class clazz) { + return getApplicationContext().getBean(clazz); + } + + // 通过name,以及Clazz返回指定的Bean + public static T getBean(String name, Class clazz) { + return getApplicationContext().getBean(name, clazz); + } + + /** + * 通过类型获取Spring容器中的对象 + * + * @param type + * @param + * @return + */ + public static Map getBeansOfType(Class type) { + Map beansOfType = getApplicationContext().getBeansOfType(type); + return beansOfType; + } + + /** + * 通过类型获取Spring容器中的对象 + * + * @param type + * @param includeNonSingletons + * @param allowEagerInit + * @param + * @return + */ + public static Map getBeansOfType(Class type, boolean includeNonSingletons, boolean allowEagerInit) { + Map beansOfType = getApplicationContext().getBeansOfType(type, includeNonSingletons, allowEagerInit); + return beansOfType; + } +} diff --git a/demo-common/demo-common-base/src/main/java/com/yxt/demo/common/base/config/utils/jackson/CustomizeNullJsonSerializer.java b/demo-common/demo-common-base/src/main/java/com/yxt/demo/common/base/config/utils/jackson/CustomizeNullJsonSerializer.java new file mode 100644 index 0000000..1cec502 --- /dev/null +++ b/demo-common/demo-common-base/src/main/java/com/yxt/demo/common/base/config/utils/jackson/CustomizeNullJsonSerializer.java @@ -0,0 +1,72 @@ +package com.yxt.demo.common.base.config.utils.jackson; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; + +import java.io.IOException; + +/** + * @Author dimengzhe + * @Date 2022/5/13 17:15 + * @Description + */ +public class CustomizeNullJsonSerializer { + + /** + * 处理数组集合类型的null值 + */ + public static class NullArrayJsonSerializer extends JsonSerializer { + @Override + public void serialize(Object value, JsonGenerator jsonGenerator, + SerializerProvider serializerProvider) throws IOException { + jsonGenerator.writeStartArray(); + jsonGenerator.writeEndArray(); + } + } + + /** + * 处理字符串类型的null值 + */ + public static class NullStringJsonSerializer extends JsonSerializer { + @Override + public void serialize(Object value, JsonGenerator jsonGenerator, + SerializerProvider serializerProvider) throws IOException { + jsonGenerator.writeString(""); + } + } + + /** + * 处理数值类型的null值 + */ + public static class NullNumberJsonSerializer extends JsonSerializer { + @Override + public void serialize(Object value, JsonGenerator jsonGenerator, + SerializerProvider serializerProvider) throws IOException { + jsonGenerator.writeNumber(0); + } + } + + /** + * 处理boolean类型的null值 + */ + public static class NullBooleanJsonSerializer extends JsonSerializer { + @Override + public void serialize(Object value, JsonGenerator jsonGenerator, + SerializerProvider serializerProvider) throws IOException { + jsonGenerator.writeBoolean(false); + } + } + + /** + * 处理实体对象类型的null值 + */ + /* public static class NullObjectJsonSerializer extends JsonSerializer { + @Override + public void serialize(Object value, JsonGenerator jsonGenerator, + SerializerProvider serializerProvider) throws IOException { + jsonGenerator.writeStartObject(); + jsonGenerator.writeEndObject(); + } + }*/ +} diff --git a/demo-common/demo-common-base/src/main/java/com/yxt/demo/common/base/config/utils/jackson/JacksonConfig.java b/demo-common/demo-common-base/src/main/java/com/yxt/demo/common/base/config/utils/jackson/JacksonConfig.java new file mode 100644 index 0000000..e8dd516 --- /dev/null +++ b/demo-common/demo-common-base/src/main/java/com/yxt/demo/common/base/config/utils/jackson/JacksonConfig.java @@ -0,0 +1,33 @@ +package com.yxt.demo.common.base.config.utils.jackson; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializerProvider; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Primary; +import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder; + +/** + * @Author dimengzhe + * @Date 2022/5/13 17:13 + * @Description + */ +@Configuration +public class JacksonConfig { + + @Bean + @Primary + @ConditionalOnMissingBean(ObjectMapper.class) + public ObjectMapper jacksonObjectMapper(Jackson2ObjectMapperBuilder builder) { + ObjectMapper objectMapper = builder.createXmlMapper(false).build(); + /** 为objectMapper注册一个带有SerializerModifier的Factory */ + objectMapper.setSerializerFactory(objectMapper.getSerializerFactory() + .withSerializerModifier(new MyBeanSerializerModifier())); + + SerializerProvider serializerProvider = objectMapper.getSerializerProvider(); +// serializerProvider.setNullValueSerializer(new CustomizeNullJsonSerializer +// .NullObjectJsonSerializer()); + return objectMapper; + } +} diff --git a/demo-common/demo-common-base/src/main/java/com/yxt/demo/common/base/config/utils/jackson/MyBeanSerializerModifier.java b/demo-common/demo-common-base/src/main/java/com/yxt/demo/common/base/config/utils/jackson/MyBeanSerializerModifier.java new file mode 100644 index 0000000..d8dda5c --- /dev/null +++ b/demo-common/demo-common-base/src/main/java/com/yxt/demo/common/base/config/utils/jackson/MyBeanSerializerModifier.java @@ -0,0 +1,68 @@ +package com.yxt.demo.common.base.config.utils.jackson; + +import com.fasterxml.jackson.databind.BeanDescription; +import com.fasterxml.jackson.databind.SerializationConfig; +import com.fasterxml.jackson.databind.ser.BeanPropertyWriter; +import com.fasterxml.jackson.databind.ser.BeanSerializerModifier; + +import java.util.Collection; +import java.util.List; + +/** + * @Author dimengzhe + * @Date 2022/4/29 18:58 + * @Description + */ +public class MyBeanSerializerModifier extends BeanSerializerModifier { + + @Override + public List changeProperties(SerializationConfig config, + BeanDescription beanDesc, + List beanProperties) { + // 循环所有的beanPropertyWriter + for (int i = 0; i < beanProperties.size(); i++) { + BeanPropertyWriter writer = beanProperties.get(i); + // 判断字段的类型,如果是数组或集合则注册nullSerializer + /* if (isArrayType(writer)) { + // 给writer注册一个自己的nullSerializer + writer.assignNullSerializer(new CustomizeNullJsonSerializer.NullArrayJsonSerializer()); + }*/ + if (isStringType(writer)) { + writer.assignNullSerializer(new CustomizeNullJsonSerializer.NullStringJsonSerializer()); + } + } + return beanProperties; + } + + /** + * 是否是数组 + */ + private boolean isArrayType(BeanPropertyWriter writer) { + Class clazz = writer.getType().getRawClass(); + return clazz.isArray() || Collection.class.isAssignableFrom(clazz); + } + + /** + * 是否是String + */ + private boolean isStringType(BeanPropertyWriter writer) { + Class clazz = writer.getType().getRawClass(); + return CharSequence.class.isAssignableFrom(clazz) || Character.class.isAssignableFrom(clazz); + } + + /** + * 是否是数值类型 + */ + private boolean isNumberType(BeanPropertyWriter writer) { + Class clazz = writer.getType().getRawClass(); + return Number.class.isAssignableFrom(clazz); + } + + /** + * 是否是boolean + */ + private boolean isBooleanType(BeanPropertyWriter writer) { + Class clazz = writer.getType().getRawClass(); + return clazz.equals(Boolean.class); + } +} diff --git a/demo-common/demo-common-config/pom.xml b/demo-common/demo-common-config/pom.xml new file mode 100644 index 0000000..961e1ac --- /dev/null +++ b/demo-common/demo-common-config/pom.xml @@ -0,0 +1,17 @@ + + + + com.yxt.demo + demo-common + 0.0.1 + + 4.0.0 + demo-common-config + 0.0.1 + + + + + \ No newline at end of file diff --git a/demo-common/demo-common-config/src/main/resources/application-commondev.yml b/demo-common/demo-common-config/src/main/resources/application-commondev.yml new file mode 100644 index 0000000..fec33ad --- /dev/null +++ b/demo-common/demo-common-config/src/main/resources/application-commondev.yml @@ -0,0 +1,5 @@ +image: + upload: + path: D:\di\upload\files\ + url: + prefix: http://127.0.0.1:7112/upload/files/ \ No newline at end of file diff --git a/demo-common/demo-common-config/src/main/resources/application-commonprod.yml b/demo-common/demo-common-config/src/main/resources/application-commonprod.yml new file mode 100644 index 0000000..e69de29 diff --git a/demo-common/demo-common-core/pom.xml b/demo-common/demo-common-core/pom.xml new file mode 100644 index 0000000..7695673 --- /dev/null +++ b/demo-common/demo-common-core/pom.xml @@ -0,0 +1,29 @@ + + + + com.yxt.demo + demo-common + 0.0.1 + + 4.0.0 + demo-common-core + 0.0.1 + + + + cn.hutool + hutool-core + + + org.projectlombok + lombok + true + + + org.springframework.boot + spring-boot-starter-web + + + \ No newline at end of file diff --git a/demo-common/demo-common-core/src/main/java/com/yxt/demo/common/core/constant/Constants.java b/demo-common/demo-common-core/src/main/java/com/yxt/demo/common/core/constant/Constants.java new file mode 100644 index 0000000..4a56280 --- /dev/null +++ b/demo-common/demo-common-core/src/main/java/com/yxt/demo/common/core/constant/Constants.java @@ -0,0 +1,116 @@ +package com.yxt.demo.common.core.constant; + +/** + * 通用常量信息 + */ +public class Constants { + /** + * UTF-8 字符集 + */ + public static final String UTF8 = "UTF-8"; + + /** + * GBK 字符集 + */ + public static final String GBK = "GBK"; + + /** + * RMI 远程方法调用 + */ + public static final String LOOKUP_RMI = "rmi://"; + + /** + * LDAP 远程方法调用 + */ + public static final String LOOKUP_LDAP = "ldap://"; + + /** + * http请求 + */ + public static final String HTTP = "http://"; + + /** + * https请求 + */ + public static final String HTTPS = "https://"; + + /** + * 成功标记 + */ + public static final Integer SUCCESS = 200; + + /** + * 失败标记 + */ + public static final Integer FAIL = 500; + + /** + * 登录成功 + */ + public static final String LOGIN_SUCCESS = "Success"; + + /** + * 注销 + */ + public static final String LOGOUT = "Logout"; + + /** + * 注册 + */ + public static final String REGISTER = "Register"; + + /** + * 登录失败 + */ + public static final String LOGIN_FAIL = "Error"; + + /** + * 当前记录起始索引 + */ + public static final String PAGE_NUM = "pageNum"; + + /** + * 每页显示记录数 + */ + public static final String PAGE_SIZE = "pageSize"; + + /** + * 排序列 + */ + public static final String ORDER_BY_COLUMN = "orderByColumn"; + + /** + * 排序的方向 "desc" 或者 "asc". + */ + public static final String IS_ASC = "isAsc"; + + /** + * 验证码 redis key + */ + public static final String CAPTCHA_CODE_KEY = "captcha_codes:"; + + /** + * 验证码有效期(分钟) + */ + public static final long CAPTCHA_EXPIRATION = 2; + + /** + * 令牌有效期(分钟) + */ + public final static long TOKEN_EXPIRE = 720; + + /** + * 参数管理 cache key + */ + public static final String SYS_CONFIG_KEY = "sys_config:"; + + /** + * 字典管理 cache key + */ + public static final String SYS_DICT_KEY = "sys_dict:"; + + /** + * 资源映射路径 前缀 + */ + public static final String RESOURCE_PREFIX = "/profile"; +} diff --git a/demo-common/demo-common-core/src/main/java/com/yxt/demo/common/core/constant/StatusEnum.java b/demo-common/demo-common-core/src/main/java/com/yxt/demo/common/core/constant/StatusEnum.java new file mode 100644 index 0000000..b238fef --- /dev/null +++ b/demo-common/demo-common-core/src/main/java/com/yxt/demo/common/core/constant/StatusEnum.java @@ -0,0 +1,34 @@ +package com.yxt.demo.common.core.constant; + +/** + * @Author dimengzhe + * @Date 2022/7/23 22:37 + * @Description + */ +public enum StatusEnum { + /** + * 状态分类 + */ + SUCCESS(200, "成功"), + FAIL(500, "失败"), + OVERDUE(5000, "登录状态已过期"); + + private int code; + private String msg; + + public int getCode() { + return code; + } + + + public String getMsg() { + return msg; + } + + StatusEnum(int code, String msg) { + this.code = code; + this.msg = msg; + } + + +} diff --git a/demo-common/demo-common-core/src/main/java/com/yxt/demo/common/core/domain/BaseEntity.java b/demo-common/demo-common-core/src/main/java/com/yxt/demo/common/core/domain/BaseEntity.java new file mode 100644 index 0000000..3c53161 --- /dev/null +++ b/demo-common/demo-common-core/src/main/java/com/yxt/demo/common/core/domain/BaseEntity.java @@ -0,0 +1,127 @@ +package com.yxt.demo.common.core.domain; + +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.annotations.ApiModelProperty; + +import java.util.Date; +import java.util.UUID; + +/** + * @author dimengzhe + * @date 2021/9/3 16:06 + * @description + */ +public class BaseEntity extends Entity { + + @ApiModelProperty("字符型编号") + private String sid = UUID.randomUUID().toString(); + + @ApiModelProperty("记录版本,锁") + private Integer lockVersion = 0; + + @ApiModelProperty("记录创建时间") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + private Date createTime = new Date(); + + @ApiModelProperty("记录最后修改时间") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + private Date modifyTime = new Date(); + + @ApiModelProperty("记录状态值") + private Integer state = 0; + + @ApiModelProperty("记录是否可用,0:可用(默认),1:不可用") + private Integer isEnable = 0; + + @ApiModelProperty("记录是否被删除,0:未删除(默认),1:已经删除") + private Integer isDelete = 0; + + @ApiModelProperty("备注信息") + private String remarks; + + @ApiModelProperty("创建者") + private String createBySid; + + @ApiModelProperty("更新者") + private String updateBySid; + + public String getSid() { + return sid; + } + + public void setSid(String sid) { + this.sid = sid; + } + + public Integer getLockVersion() { + return lockVersion; + } + + public void setLockVersion(Integer lockVersion) { + this.lockVersion = lockVersion; + } + + public Date getCreateTime() { + return createTime; + } + + public void setCreateTime(Date createTime) { + this.createTime = createTime; + } + + public Date getModifyTime() { + return modifyTime; + } + + public void setModifyTime(Date modifyTime) { + this.modifyTime = modifyTime; + } + + public Integer getState() { + return state; + } + + public void setState(Integer state) { + this.state = state; + } + + public Integer getIsEnable() { + return isEnable; + } + + public void setIsEnable(Integer isEnable) { + this.isEnable = isEnable; + } + + public Integer getIsDelete() { + return isDelete; + } + + public void setIsDelete(Integer isDelete) { + this.isDelete = isDelete; + } + + public String getRemarks() { + return remarks; + } + + public void setRemarks(String remarks) { + this.remarks = remarks; + } + + public String getCreateBySid() { + return createBySid; + } + + public void setCreateBySid(String createBySid) { + this.createBySid = createBySid; + } + + public String getUpdateBySid() { + return updateBySid; + } + + public void setUpdateBySid(String updateBySid) { + this.updateBySid = updateBySid; + } +} diff --git a/demo-common/demo-common-core/src/main/java/com/yxt/demo/common/core/domain/Entity.java b/demo-common/demo-common-core/src/main/java/com/yxt/demo/common/core/domain/Entity.java new file mode 100644 index 0000000..919f3f7 --- /dev/null +++ b/demo-common/demo-common-core/src/main/java/com/yxt/demo/common/core/domain/Entity.java @@ -0,0 +1,55 @@ +package com.yxt.demo.common.core.domain; + +import io.swagger.annotations.ApiModelProperty; + +import java.io.Serializable; + +/** + * @author dimengzhe + * @date 2021/9/3 16:06 + * @description + */ +public class Entity implements Serializable { + + @ApiModelProperty("ID,唯一编号") + private Integer id; + + @ApiModelProperty("ID值的字符串形式") + public String getIdStr() { + if (null == id) { + return ""; + } + return "" + id; + } + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + @Override + public String toString() { + return "ClassName:" + getClass().getName() + ";id:" + getId(); + } + + @Override + public int hashCode() { + int id2 = Long.hashCode(getId()); + return super.hashCode() + id2; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!(obj instanceof Entity)) { + return false; + } + Entity entity = (Entity) obj; + return this.getId().equals(entity.getId()); + } +} diff --git a/demo-common/demo-common-core/src/main/java/com/yxt/demo/common/core/dto/Dto.java b/demo-common/demo-common-core/src/main/java/com/yxt/demo/common/core/dto/Dto.java new file mode 100644 index 0000000..902dad8 --- /dev/null +++ b/demo-common/demo-common-core/src/main/java/com/yxt/demo/common/core/dto/Dto.java @@ -0,0 +1,8 @@ +package com.yxt.demo.common.core.dto; + + +import com.yxt.demo.common.core.vo.Vo; + +public interface Dto extends Vo { + +} diff --git a/demo-common/demo-common-core/src/main/java/com/yxt/demo/common/core/query/PagerQuery.java b/demo-common/demo-common-core/src/main/java/com/yxt/demo/common/core/query/PagerQuery.java new file mode 100644 index 0000000..b48993d --- /dev/null +++ b/demo-common/demo-common-core/src/main/java/com/yxt/demo/common/core/query/PagerQuery.java @@ -0,0 +1,77 @@ +package com.yxt.demo.common.core.query; + +import io.swagger.annotations.ApiModelProperty; + +import java.io.Serializable; + +/** + * @author dimengzhe + * @date 2021/9/3 16:41 + * @description + */ + +public class PagerQuery implements Serializable { + + @ApiModelProperty(value = "当前页号", example = "1") + private long current = 1L; + + @ApiModelProperty(value = "每页记录数", example = "10") + private long size = 10L; + + @ApiModelProperty(value = "标识符") + private Integer identifier; + + @ApiModelProperty("查询条件的项") + private T params; + + public PagerQuery() { + } + + public PagerQuery(long current) { + this.current = current; + } + + public PagerQuery(long current, long size) { + this.size = size; + this.current = current; + } + + public long getSize() { + return size; + } + + public PagerQuery setSize(long size) { + this.size = size; + return this; + } + + public long getCurrent() { + return current; + } + + public PagerQuery setCurrent(long current) { + this.current = current; + return this; + } + + public T getParams() { + return params; + } + + public PagerQuery setParams(T params) { + this.params = params; + return this; + } + + public Integer getIdentifier() { + return identifier; + } + + public void setIdentifier(Integer identifier) { + this.identifier = identifier; + } + + public void fromPagerQuery(PagerQuery s_query) { + this.setCurrent(s_query.getCurrent()).setSize(s_query.getSize()).setParams(params.fromMap(s_query.getParams().toMap())); + } +} diff --git a/demo-common/demo-common-core/src/main/java/com/yxt/demo/common/core/query/Query.java b/demo-common/demo-common-core/src/main/java/com/yxt/demo/common/core/query/Query.java new file mode 100644 index 0000000..74a072d --- /dev/null +++ b/demo-common/demo-common-core/src/main/java/com/yxt/demo/common/core/query/Query.java @@ -0,0 +1,12 @@ +package com.yxt.demo.common.core.query; + +import com.yxt.demo.common.core.vo.Vo; + +/** + * @author dimengzhe + * @date 2021/9/3 16:41 + * @description + */ + +public interface Query extends Vo { +} diff --git a/demo-common/demo-common-core/src/main/java/com/yxt/demo/common/core/result/ResultBean.java b/demo-common/demo-common-core/src/main/java/com/yxt/demo/common/core/result/ResultBean.java new file mode 100644 index 0000000..1ce970a --- /dev/null +++ b/demo-common/demo-common-core/src/main/java/com/yxt/demo/common/core/result/ResultBean.java @@ -0,0 +1,141 @@ +package com.yxt.demo.common.core.result; + +import com.yxt.demo.common.core.constant.Constants; +import com.yxt.demo.common.core.constant.StatusEnum; + +import java.io.Serializable; + +/** + * @Author dimengzhe + * @Date 2021/8/23 16:42 + * @Description 返回结果 + */ +public class ResultBean implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 成功 + */ + public static final int SUCCESS = Constants.SUCCESS; + + /** + * 失败 + */ + public static final int FAIL = Constants.FAIL; + + private int code; + + private String msg; + + private T data; + private Boolean success; + + public ResultBean() { + } + + public ResultBean(boolean success) { + this.success = success; + } + + public ResultBean(boolean success, String msg) { + this.success = success; + this.msg = msg; + } + + public ResultBean(boolean success, String msg, int code) { + this.success = success; + this.msg = msg; + this.code = code; + } + + public ResultBean(T data) { + this.success = true; + this.data = data; + } + + public ResultBean(int code, T data) { + this.success = true; + this.code = code; + this.data = data; + } + + public ResultBean(int code, String msg, T data) { + this.success = true; + this.code = code; + this.msg = msg; + this.data = data; + } + + public boolean getSuccess() { + return success; + } + + public ResultBean setSuccess(boolean success) { + this.success = success; + return this; + } + + public String getMsg() { + return msg; + } + + public ResultBean setMsg(String msg) { + this.msg = msg; + return this; + } + + public int getCode() { + return code; + } + + public ResultBean setCode(int code) { + this.code = code; + return this; + } + + public T getData() { + return data; + } + + public ResultBean setData(T data) { + this.data = data; + return this; + } + + /** + * 1.类实例化的非静态方法调用 2.类不实例化的静态方法调用 + * + * @return + */ + public ResultBean success() { + this.setSuccess(true); + this.setCode(StatusEnum.SUCCESS.getCode()); + this.setMsg("操作成功!"); + return this; + } + + public ResultBean fail() { + this.setSuccess(false); + this.setCode(StatusEnum.FAIL.getCode()); + this.setMsg("操作失败!"); + return this; + } + + public static ResultBean fireSuccess() { + ResultBean rb = new ResultBean(); + rb.setSuccess(true); + rb.setCode(StatusEnum.SUCCESS.getCode()); + rb.setMsg("操作成功!"); + return rb; + } + + public static ResultBean fireFail() { + ResultBean rb = new ResultBean(); + rb.setSuccess(false); + rb.setCode(StatusEnum.FAIL.getCode()); + rb.setMsg("操作失败!"); + return rb; + } + +} diff --git a/demo-common/demo-common-core/src/main/java/com/yxt/demo/common/core/vo/PagerVo.java b/demo-common/demo-common-core/src/main/java/com/yxt/demo/common/core/vo/PagerVo.java new file mode 100644 index 0000000..f770b3d --- /dev/null +++ b/demo-common/demo-common-core/src/main/java/com/yxt/demo/common/core/vo/PagerVo.java @@ -0,0 +1,100 @@ +package com.yxt.demo.common.core.vo; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +import java.io.Serializable; +import java.util.Collections; +import java.util.List; + +/** + * @author dimengzhe + * @date 2021/9/3 16:24 + * @description + */ +@ApiModel(description = "返回的分页结果") +public class PagerVo implements Serializable { + + @ApiModelProperty("总页数") + private long pages = 1L; + @ApiModelProperty("总记录数") + private long total = 0L; + @ApiModelProperty("每页记录数") + private long size = 15L; + @ApiModelProperty("当前页号") + private long current = 1L; + @ApiModelProperty(value = "标识符") + private Integer identifier; + + @ApiModelProperty("当前页的数据") + private List records = Collections.emptyList(); + + public PagerVo() { + this.pages = 1L; + this.total = 0L; + this.size = 10L; + this.current = 1L; + this.records = Collections.emptyList(); + } + + public PagerVo(long current) { + this.pages = 1L; + this.total = 0L; + this.size = 10L; + this.current = current; + this.records = Collections.emptyList(); + } + + public long getPages() { + return pages; + } + + public PagerVo setPages(long pages) { + this.pages = pages; + return this; + } + + public long getTotal() { + return total; + } + + public PagerVo setTotal(long total) { + this.total = total; + return this; + } + + public long getSize() { + return size; + } + + public PagerVo setSize(long size) { + this.size = size; + return this; + } + + public long getCurrent() { + return current; + } + + public PagerVo setCurrent(long current) { + this.current = current; + return this; + } + + public List getRecords() { + return records; + } + + public PagerVo setRecords(List records) { + this.records = records; + return this; + } + + public Integer getIdentifier() { + return identifier; + } + + public void setIdentifier(Integer identifier) { + this.identifier = identifier; + } +} diff --git a/demo-common/demo-common-core/src/main/java/com/yxt/demo/common/core/vo/Vo.java b/demo-common/demo-common-core/src/main/java/com/yxt/demo/common/core/vo/Vo.java new file mode 100644 index 0000000..3ac87c6 --- /dev/null +++ b/demo-common/demo-common-core/src/main/java/com/yxt/demo/common/core/vo/Vo.java @@ -0,0 +1,28 @@ +package com.yxt.demo.common.core.vo; + +import cn.hutool.core.bean.BeanUtil; +import com.yxt.demo.common.core.domain.Entity; + +import java.io.Serializable; +import java.util.Map; + +/** + * @author dimengzhe + * @date 2021/9/3 16:21 + * @description + */ + +public interface Vo extends Serializable { + + default Map toMap() { + return BeanUtil.beanToMap(this); + } + + default V fromMap(Map map) { + return (V) BeanUtil.fillBeanWithMap(map, this, false); + } + + default void fromEntity(E e) { + BeanUtil.copyProperties(e, this); + } +} diff --git a/demo-common/demo-common-jdbc/pom.xml b/demo-common/demo-common-jdbc/pom.xml new file mode 100644 index 0000000..2f9145c --- /dev/null +++ b/demo-common/demo-common-jdbc/pom.xml @@ -0,0 +1,31 @@ + + + + demo-common + com.yxt.demo + 0.0.1 + + 4.0.0 + demo-common-jdbc + 0.0.1 + + + + com.yxt.demo + demo-common-core + 0.0.1 + + + com.baomidou + mybatis-plus-boot-starter + + + mysql + mysql-connector-java + runtime + + + + \ No newline at end of file diff --git a/demo-common/demo-common-jdbc/src/main/java/com/yxt/demo/common/jdbc/config/MybatisPlusConfig.java b/demo-common/demo-common-jdbc/src/main/java/com/yxt/demo/common/jdbc/config/MybatisPlusConfig.java new file mode 100644 index 0000000..5b130fe --- /dev/null +++ b/demo-common/demo-common-jdbc/src/main/java/com/yxt/demo/common/jdbc/config/MybatisPlusConfig.java @@ -0,0 +1,23 @@ +package com.yxt.demo.common.jdbc.config; + +import com.baomidou.mybatisplus.annotation.DbType; +import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; +import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * @author dimengzhe + * @date 2021/9/4 0:40 + * @description + */ +@Configuration +public class MybatisPlusConfig { + + @Bean + public MybatisPlusInterceptor paginationInterceptor() { + MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); + interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL)); + return interceptor; + } +} diff --git a/demo-common/demo-common-jdbc/src/main/java/com/yxt/demo/common/jdbc/service/MybatisBaseService.java b/demo-common/demo-common-jdbc/src/main/java/com/yxt/demo/common/jdbc/service/MybatisBaseService.java new file mode 100644 index 0000000..4c2c00c --- /dev/null +++ b/demo-common/demo-common-jdbc/src/main/java/com/yxt/demo/common/jdbc/service/MybatisBaseService.java @@ -0,0 +1,15 @@ +package com.yxt.demo.common.jdbc.service; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; + +public class MybatisBaseService, T> extends ServiceImpl { + + + public T fetchBySid(String sid) { + QueryWrapper qw = new QueryWrapper<>(); + qw.eq("sid", sid); + return baseMapper.selectOne(qw); + } +} diff --git a/demo-common/demo-common-redis/pom.xml b/demo-common/demo-common-redis/pom.xml new file mode 100644 index 0000000..44b454f --- /dev/null +++ b/demo-common/demo-common-redis/pom.xml @@ -0,0 +1,35 @@ + + + + com.yxt.demo + demo-common + 0.0.1 + + 4.0.0 + demo-common-redis + 0.0.1 + + + + org.springframework.boot + spring-boot-starter-data-redis + + + io.lettuce + lettuce-core + + + + + redis.clients + jedis + + + com.fasterxml.jackson.core + jackson-databind + + + + \ No newline at end of file diff --git a/demo-common/demo-common-redis/src/main/java/com/yxt/demo/common/redis/configure/RedisConfig.java b/demo-common/demo-common-redis/src/main/java/com/yxt/demo/common/redis/configure/RedisConfig.java new file mode 100644 index 0000000..93828ad --- /dev/null +++ b/demo-common/demo-common-redis/src/main/java/com/yxt/demo/common/redis/configure/RedisConfig.java @@ -0,0 +1,104 @@ +package com.yxt.demo.common.redis.configure; + +import com.fasterxml.jackson.annotation.JsonAutoDetect; +import com.fasterxml.jackson.annotation.PropertyAccessor; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.data.redis.connection.RedisConnectionFactory; +import org.springframework.data.redis.connection.jedis.JedisConnectionFactory; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer; +import org.springframework.data.redis.serializer.StringRedisSerializer; +import redis.clients.jedis.JedisPoolConfig; + +/** + * @author dimengzhe + * @date 2021/10/10 12:21 + * @description + */ + +public class RedisConfig { + + @Value("${spring.redis.host}") + private String host; + + @Value("${spring.redis.password}") + private String password; + + @Value("${spring.redis.port}") + private int port; + + @Value("${spring.redis.timeout}") + private int timeout; + + @Value("${spring.redis.jedis.pool.max-active}") + private int redisPoolMaxActive; + + @Value("${spring.redis.jedis.pool.max-wait}") + private int redisPoolMaxWait; + + @Value("${spring.redis.jedis.pool.max-idle}") + private int redisPoolMaxIdle; + + @Value("${spring.redis.jedis.pool.min-idle}") + private int redisPoolMinIdle; + @Value("${spring.redis.database}") + private int database; + + @Bean + public JedisPoolConfig getJedisPoolConfig() { + JedisPoolConfig jedisPoolConfig = new JedisPoolConfig(); + //最大空闲数 + jedisPoolConfig.setMaxIdle(redisPoolMaxIdle); + //最小空闲数 + jedisPoolConfig.setMinIdle(redisPoolMinIdle); + //最大建立连接等待时间 + jedisPoolConfig.setMaxWaitMillis(redisPoolMaxWait); + //连接池的最大数据库连接数 + jedisPoolConfig.setMaxTotal(redisPoolMaxActive); +// jedisPool = new JedisPool(jedisPoolConfig, host, port, timeout, password); + return jedisPoolConfig; + } + + + @Bean + public JedisConnectionFactory jedisConnectionFactory(JedisPoolConfig jedisPoolConfig) { + + JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory(jedisPoolConfig); + jedisConnectionFactory.setDatabase(database); + //IP地址 + jedisConnectionFactory.setHostName(host); + //如果redis设置有密码 + jedisConnectionFactory.setPassword(password); + //端口号 + jedisConnectionFactory.setPort(port); + //客户端超时时间单位是毫秒 + jedisConnectionFactory.setTimeout(timeout); +// jedisConnectionFactory.afterPropertiesSet(); //记得添加这行! + return jedisConnectionFactory; + } + + @Bean + public RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory) { + RedisTemplate redisTemplate = new RedisTemplate<>(); + redisTemplate.setConnectionFactory(redisConnectionFactory); + // 使用Jackson2JsonRedisSerialize 替换默认序列化 + Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class); + ObjectMapper om = new ObjectMapper(); + om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); + om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); + jackson2JsonRedisSerializer.setObjectMapper(om); + StringRedisSerializer stringRedisSerializer = new StringRedisSerializer(); + // key采用String的序列化方式 + redisTemplate.setKeySerializer(stringRedisSerializer); + // hash的key也采用String的序列化方式 + redisTemplate.setHashKeySerializer(stringRedisSerializer); + // value序列化方式采用jackson + redisTemplate.setValueSerializer(stringRedisSerializer); + // hash的value序列化方式采用jackson + redisTemplate.setHashValueSerializer(stringRedisSerializer); + redisTemplate.afterPropertiesSet(); + return redisTemplate; + } +} diff --git a/demo-common/demo-common-redis/src/main/java/com/yxt/demo/common/redis/service/RedisService.java b/demo-common/demo-common-redis/src/main/java/com/yxt/demo/common/redis/service/RedisService.java new file mode 100644 index 0000000..a1f051a --- /dev/null +++ b/demo-common/demo-common-redis/src/main/java/com/yxt/demo/common/redis/service/RedisService.java @@ -0,0 +1,295 @@ +package com.yxt.demo.common.redis.service; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.dao.DataAccessException; +import org.springframework.data.redis.connection.RedisConnection; +import org.springframework.data.redis.connection.RedisStringCommands; +import org.springframework.data.redis.core.*; +import org.springframework.data.redis.core.types.Expiration; +import org.springframework.data.redis.serializer.RedisSerializer; +import org.springframework.stereotype.Service; + +import java.io.Serializable; +import java.util.List; +import java.util.Set; +import java.util.concurrent.TimeUnit; + +/** + * @author dimengzhe + * @date 2021/10/10 13:10 + * @description + */ +@Service +public class RedisService { + + @Autowired + private RedisTemplate redisTemplate; + + /** + * 字符串类型:根据key设置value值,如果key中的value存在,那么返回false + * + * @param key + * @param value + * @return + */ + public Boolean setnx(final String key, final String value, final long expration, final TimeUnit timeUnit) { + return (Boolean) redisTemplate.execute(new RedisCallback() { + @Override + public Boolean doInRedis(RedisConnection redisConnection) throws DataAccessException { + RedisSerializer redisSerializer = redisTemplate.getStringSerializer(); + byte[] keys = redisSerializer.serialize(key); + byte[] values = redisSerializer.serialize(value); + return redisConnection.set(keys, values, Expiration.from(expration, timeUnit), RedisStringCommands.SetOption.SET_IF_ABSENT); + } + }); + } + + /** + * 写入缓存 + * + * @param key + * @param value + * @return + */ + public boolean set(final String key, final String value) { + + boolean result = (boolean) redisTemplate.execute(new RedisCallback() { + @Override + public Boolean doInRedis(RedisConnection connection) throws DataAccessException { + RedisSerializer serializer = redisTemplate.getStringSerializer(); + connection.set(serializer.serialize(key), serializer.serialize(value)); + return true; + } + }); + return result; + } + + /** + * 写入缓存设置时效时间 + * + * @param key + * @param value + * @return + */ + public boolean set(final String key, Object value, Long expireTime) { + boolean result = false; + try { + ValueOperations operations = redisTemplate.opsForValue(); + operations.set(key, value); + redisTemplate.expire(key, expireTime, TimeUnit.SECONDS); + result = true; + } catch (Exception e) { + e.printStackTrace(); + } + return result; + } + + public boolean expire(String key, long expire) { + return redisTemplate.expire(key, expire, TimeUnit.SECONDS); + } + + /** + * 读取缓存 + * + * @param key + * @return + */ + public String get(final String key) { + String result = (String) redisTemplate.execute(new RedisCallback() { + @Override + public String doInRedis(RedisConnection connection) throws DataAccessException { + RedisSerializer serializer = redisTemplate.getStringSerializer(); + byte[] value = connection.get(serializer.serialize(key)); + return serializer.deserialize(value); + } + }); + return result; + } + + /** + * 正则获取key集合 + * + * @param pattern + * @return + */ + public Set keys(String pattern) { + Set keys = redisTemplate.keys(pattern); + return keys; + } + + + /** + * 批量删除对应的value + * + * @param keys + */ + public void remove(final String... keys) { + for (String key : keys) { + remove(key); + } + } + + /** + * 批量删除key + * + * @param pattern + */ + public void removePattern(final String pattern) { + Set keys = redisTemplate.keys(pattern); + if (keys.size() > 0) { + redisTemplate.delete(keys); + } + + } + + + public Long remove(final String key) { + return (Long) redisTemplate.execute(new RedisCallback() { + @Override + public Long doInRedis(RedisConnection redisConnection) throws DataAccessException { + RedisSerializer serializer = redisTemplate.getStringSerializer(); + byte[] keys = serializer.serialize(key); + return redisConnection.del(keys); + } + }); + } + + + /** + * 判断缓存中是否有对应的value + * + * @param key + * @return + */ + public boolean exists(final String key) { + return redisTemplate.hasKey(key); + } + + + /** + * 哈希 添加 + * + * @param key + * @param hashKey + * @param value + */ + public void hmSet(String key, Object hashKey, Object value) { + HashOperations hash = redisTemplate.opsForHash(); + hash.put(key, hashKey, value); + } + + /** + * 哈希获取数据 + * + * @param key + * @param hashKey + * @return + */ + public String hmGet(String key, Object hashKey) { + HashOperations hash = redisTemplate.opsForHash(); + return hash.get(key, hashKey); + } + + /** + * 获取哈希 keys + * + * @param key + * @return + */ + public Set hmGetKeys(String key) { + HashOperations hash = redisTemplate.opsForHash(); + return hash.keys(key); + } + + /** + * 删除集合中的key + * + * @param key + * @param hashKey + */ + public void hmDelete(String key, Object hashKey) { + HashOperations hash = redisTemplate.opsForHash(); + hash.delete(key, hashKey); + } + + /** + * 列表添加 + * + * @param k + * @param v + */ + public void lPush(String k, Object v) { + ListOperations list = redisTemplate.opsForList(); + list.rightPush(k, v); + } + + /** + * 列表获取 + * + * @param k + * @param l + * @param l1 + * @return + */ + public List lRange(String k, long l, long l1) { + ListOperations list = redisTemplate.opsForList(); + return list.range(k, l, l1); + } + + /** + * 集合添加 + * + * @param key + * @param value + */ + public void add(String key, Object value) { + SetOperations set = redisTemplate.opsForSet(); + set.add(key, value); + } + + /** + * 集合获取 + * + * @param key + * @return + */ + public Set setMembers(String key) { + SetOperations set = redisTemplate.opsForSet(); + return set.members(key); + } + + /** + * 有序集合添加 + * + * @param key + * @param value + * @param scoure + */ + public void zAdd(String key, Object value, double scoure) { + ZSetOperations zset = redisTemplate.opsForZSet(); + zset.add(key, value, scoure); + } + + /** + * 有序集合获取 + * + * @param key + * @param scoure + * @param scoure1 + * @return + */ + public Set rangeByScore(String key, double scoure, double scoure1) { + ZSetOperations zset = redisTemplate.opsForZSet(); + return zset.rangeByScore(key, scoure, scoure1); + } + + /** + * 实现命令:TTL key 以秒为单位,返回给定key的剩余生存时间 + * + * @param key + * @return + */ + public long ttl(String key) { + return redisTemplate.getExpire(key); + } +} diff --git a/demo-common/demo-common-utils/pom.xml b/demo-common/demo-common-utils/pom.xml new file mode 100644 index 0000000..4e50365 --- /dev/null +++ b/demo-common/demo-common-utils/pom.xml @@ -0,0 +1,54 @@ + + + + com.yxt.demo + demo-common + 0.0.1 + + 4.0.0 + demo-common-utils + 0.0.1 + + + + org.springframework.boot + spring-boot-starter-web + + + + com.squareup.okhttp3 + okhttp + + + + io.jsonwebtoken + jjwt + + + com.alibaba + fastjson + + + commons-beanutils + commons-beanutils + + + org.projectlombok + lombok + true + + + cn.hutool + hutool-all + + + org.apache.commons + commons-lang3 + + + + + + \ No newline at end of file diff --git a/demo-common/demo-common-utils/src/main/java/com/yxt/demo/common/utils/BeanUtils.java b/demo-common/demo-common-utils/src/main/java/com/yxt/demo/common/utils/BeanUtils.java new file mode 100644 index 0000000..fb07935 --- /dev/null +++ b/demo-common/demo-common-utils/src/main/java/com/yxt/demo/common/utils/BeanUtils.java @@ -0,0 +1,97 @@ +package com.yxt.demo.common.utils; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * @Author dimengzhe + * @Date 2022/2/9 21:52 + * @Description 工具类 + */ +public class BeanUtils { + + + /** + * 获取String 类型 + * + * @param map + * @param keyName 键值对中键名称 + * @param defaultValue 默认值 + * @return + */ + public static String getString(Map map, String keyName, String defaultValue) { + if (map == null) { + return defaultValue; + } + if (map.containsKey(keyName)) { + Object o = map.get(keyName); + if (o instanceof String) { + return (String) o; + } else { + return defaultValue; + } + } else { + return defaultValue; + } + } + + // 获取Integer + public static Integer getInteger(Map map, String keyName) { + if (map == null) { + return -1; + } + if (map.containsKey(keyName)) { + Object o = map.get(keyName); + if (o instanceof Integer) { + return (int) o; + } else { + return -1; + } + + } else { + return -1; + } + } + + //获取map类型 + public static Map getMap(Map map, String keyName) { + if (map == null) { + return new HashMap<>(); + } + if (map.containsKey(keyName)) { + Object o = map.get(keyName); + if (o instanceof Map) { + return (Map) o; + } else { + return new HashMap<>(); + } + + } else { + return new HashMap<>(); + } + } + + // 获取List类型 + public static List> getListData(Map map, String keyName) { + List> list = new ArrayList<>(); + if (map == null) { + return list; + } + if (map.containsKey(keyName)) { + Object o = map.get(keyName); + if (o instanceof List) { + for (int i = 0; i < ((List) o).size(); i++) { + Object o1 = ((List) o).get(i); + if (o1 instanceof Map) { + list.add((Map) o1); + } + } + } + } + return list; + } + + +} diff --git a/demo-common/demo-common-utils/src/main/java/com/yxt/demo/common/utils/ValidationUtil.java b/demo-common/demo-common-utils/src/main/java/com/yxt/demo/common/utils/ValidationUtil.java new file mode 100644 index 0000000..b4c3c78 --- /dev/null +++ b/demo-common/demo-common-utils/src/main/java/com/yxt/demo/common/utils/ValidationUtil.java @@ -0,0 +1,60 @@ +package com.yxt.demo.common.utils; + +import org.apache.commons.lang3.StringUtils; + +import javax.validation.ConstraintViolation; +import javax.validation.Validation; +import javax.validation.Validator; +import java.util.List; +import java.util.Set; + +/** + * @Author dimengzhe + * @Date 2022/6/21 0:03 + * @Description 校验参数工具 + */ +public class ValidationUtil { + + public final static Validator validator = Validation.buildDefaultValidatorFactory().getValidator(); + + + /** + * 验证单个实体 + * + * @param t 参数 + * @param 类型 + * @return 验证结果 + */ + public static String validateOne(T t) { + Set> validateResult = validator.validate(t); + if (validateResult != null && validateResult.size() != 0) { + StringBuilder sb = new StringBuilder(); + for (ConstraintViolation valid : validateResult) { + sb.append(valid.getPropertyPath().toString()).append(StringUtils.SPACE).append(valid.getMessage()) + .append(","); + } + return sb.toString(); + } + + return StringUtils.EMPTY; + } + + /** + * 验证多个实体 + * + * @param ts 参数 + * @param 类型 + * @return 验证结果 + */ + public static String validateMutil(List ts) { + StringBuilder sb = new StringBuilder(); + for (int index = 0; index < ts.size(); ++index) { + String validateOneResult = validateOne(ts.get(index)); + if (!StringUtils.isBlank(validateOneResult)) { + sb.append("index[" + index + "]:").append(validateOneResult).append(";"); + } + } + + return sb.toString(); + } +} diff --git a/demo-common/demo-common-utils/src/main/java/com/yxt/demo/common/utils/allutils/RegexpUtils.java b/demo-common/demo-common-utils/src/main/java/com/yxt/demo/common/utils/allutils/RegexpUtils.java new file mode 100644 index 0000000..30e24c0 --- /dev/null +++ b/demo-common/demo-common-utils/src/main/java/com/yxt/demo/common/utils/allutils/RegexpUtils.java @@ -0,0 +1,12 @@ +package com.yxt.demo.common.utils.allutils; + +import lombok.extern.slf4j.Slf4j; + +/** + * @Author dimengzhe + * @Date 2022/7/23 23:59 + * @Description + */ +@Slf4j +public class RegexpUtils { +} diff --git a/demo-common/demo-common-utils/src/main/java/com/yxt/demo/common/utils/captcha/ImageUtils.java b/demo-common/demo-common-utils/src/main/java/com/yxt/demo/common/utils/captcha/ImageUtils.java new file mode 100644 index 0000000..b5b5d0e --- /dev/null +++ b/demo-common/demo-common-utils/src/main/java/com/yxt/demo/common/utils/captcha/ImageUtils.java @@ -0,0 +1,11 @@ +package com.yxt.demo.common.utils.captcha; + +/** + * @Author dimengzhe + * @Date 2021/11/6 21:58 + * @Description + */ +public class ImageUtils { + + +} diff --git a/demo-common/demo-common-utils/src/main/java/com/yxt/demo/common/utils/convert/StringUtil.java b/demo-common/demo-common-utils/src/main/java/com/yxt/demo/common/utils/convert/StringUtil.java new file mode 100644 index 0000000..9e7e388 --- /dev/null +++ b/demo-common/demo-common-utils/src/main/java/com/yxt/demo/common/utils/convert/StringUtil.java @@ -0,0 +1,197 @@ +package com.yxt.demo.common.utils.convert; + +import org.apache.commons.lang3.StringUtils; + +import java.util.Collection; +import java.util.List; + +/** + * @Author dimengzhe + * @Date 2022/7/23 23:38 + * @Description + */ +public class StringUtil extends StringUtils { + + /** + * 空字符串 + */ + private static final String NULLSTR = ""; + + /** + * 下划线 + */ + private static final char SEPARATOR = '_'; + + /** + * 星号 + */ + private static final String START = "*"; + + /** + * * 判断一个Collection是否为空, 包含List,Set,Queue + * + * @param coll 要判断的Collection + * @return true:为空 false:非空 + */ + public static boolean isEmpty(Collection coll) { + return isNull(coll) || coll.isEmpty(); + } + + + /** + * * 判断一个对象是否为空 + * + * @param object Object + * @return true:为空 false:非空 + */ + public static boolean isNull(Object object) { + return object == null; + } + + /** + * 查找指定字符串是否匹配指定字符串列表中的任意一个字符串 + * + * @param str 指定字符串 + * @param strs 需要检查的字符串数组 + * @return 是否匹配 + */ + public static boolean matchesTwo(String str, List strs) { + if (isEmpty(str) || isEmpty(strs)) { + return false; + } + for (String testStr : strs) { + if (matchesTwo(str, testStr)) { + return true; + } + } + return false; + } + + public static boolean matches(String str, List strs) { + if (isEmpty(str) || isEmpty(strs)) { + return false; + } + for (String testStr : strs) { + if (matches(str, testStr)) { + return true; + } + } + return false; + } + + public static boolean matches(String str, String pattern) { + if (isEmpty(pattern) || isEmpty(str)) { + return false; + } + + pattern = pattern.replaceAll("\\s*", ""); // 替换空格 + int beginOffset = 0; // pattern截取开始位置 + int formerStarOffset = -1; // 前星号的偏移位置 + int latterStarOffset = -1; // 后星号的偏移位置 + + String remainingURI = str; + String prefixPattern = ""; + String suffixPattern = ""; + + boolean result = false; + do { + formerStarOffset = indexOf(pattern, START, beginOffset); + prefixPattern = substring(pattern, beginOffset, formerStarOffset > -1 ? formerStarOffset : pattern.length()); + + // 匹配前缀Pattern + result = remainingURI.equals(prefixPattern); + // 已经没有星号,直接返回 + if (formerStarOffset == -1) { + return result; + } + + // 匹配失败,直接返回 + if (!result) { + return false; + } + if (!isEmpty(prefixPattern)) { + remainingURI = substringAfter(str, prefixPattern); + } + + // 匹配后缀Pattern + latterStarOffset = indexOf(pattern, START, formerStarOffset + 1); + suffixPattern = substring(pattern, formerStarOffset + 1, latterStarOffset > -1 ? latterStarOffset : pattern.length()); + + result = remainingURI.equals(suffixPattern); + // 匹配失败,直接返回 + if (!result) { + return false; + } + if (!isEmpty(suffixPattern)) { + remainingURI = substringAfter(str, suffixPattern); + } + + // 移动指针 + beginOffset = latterStarOffset + 1; + + } + while (!isEmpty(suffixPattern) && !isEmpty(remainingURI)); + + return true; + } + + /** + * 查找指定字符串是否匹配 + * + * @param str 指定字符串 + * @param pattern 需要检查的字符串 + * @return 是否匹配 + */ + public static boolean matchesTwo(String str, String pattern) { + if (isEmpty(pattern) || isEmpty(str)) { + return false; + } + pattern = pattern.replaceAll("\\s*", ""); // 替换空格 + int beginOffset = 0; // pattern截取开始位置 + int formerStarOffset = -1; // 前星号的偏移位置 + int latterStarOffset = -1; // 后星号的偏移位置 + + String remainingURI = str; + String prefixPattern = ""; + String suffixPattern = ""; + + boolean result = false; + do { + formerStarOffset = indexOf(pattern, START, beginOffset); + prefixPattern = substring(pattern, beginOffset, formerStarOffset > -1 ? formerStarOffset : pattern.length()); + + // 匹配前缀Pattern + result = remainingURI.contains(prefixPattern); + // 已经没有星号,直接返回 + if (formerStarOffset == -1) { + return result; + } + + // 匹配失败,直接返回 + if (!result) { + return false; + } + if (!isEmpty(prefixPattern)) { + remainingURI = substringAfter(str, prefixPattern); + } + + // 匹配后缀Pattern + latterStarOffset = indexOf(pattern, START, formerStarOffset + 1); + suffixPattern = substring(pattern, formerStarOffset + 1, latterStarOffset > -1 ? latterStarOffset : pattern.length()); + + result = remainingURI.contains(suffixPattern); + // 匹配失败,直接返回 + if (!result) { + return false; + } + if (!isEmpty(suffixPattern)) { + remainingURI = substringAfter(str, suffixPattern); + } + + // 移动指针 + beginOffset = latterStarOffset + 1; + } + while (!isEmpty(suffixPattern) && !isEmpty(remainingURI)); + return true; + } +} diff --git a/demo-common/demo-common-utils/src/main/java/com/yxt/demo/common/utils/date/DateUtils.java b/demo-common/demo-common-utils/src/main/java/com/yxt/demo/common/utils/date/DateUtils.java new file mode 100644 index 0000000..47c0196 --- /dev/null +++ b/demo-common/demo-common-utils/src/main/java/com/yxt/demo/common/utils/date/DateUtils.java @@ -0,0 +1,84 @@ +package com.yxt.demo.common.utils.date; + +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; + +/** + * @Author dimengzhe + * @Date 2021/11/7 11:58 + * @Description 关于日期处理工具类 + */ +public class DateUtils { + + public static void main(String[] args) throws Exception { + //时间格式字符串转换成Date类型 + Date date = dateStrConvertDateCst("2021-11-07 12:28:20", "yyyy-MM-dd HH:mm:ss"); + //获取两个时间间隔的x天x小时x分钟 + System.out.println(getDatePoor(date, new Date())); + //将Date类型转换成字符串类型 + System.out.println(dateConvertStr(new Date(), "yyyy-MM-dd HH:mm:ss")); + } + + /** + * 获取两个时间间隔的x天x小时x分钟 + * + * @param endDate 结尾时间 + * @param nowDate 当前时间 + * @return + */ + public static String getDatePoor(Date endDate, Date nowDate) { + long nd = 1000 * 24 * 60 * 60; + long nh = 1000 * 60 * 60; + long nm = 1000 * 60; + long ns = 1000; + // 获得两个时间的毫秒时间差异 + long diff = endDate.getTime() - nowDate.getTime(); + // 计算差多少天 + long day = diff / nd; + // 计算差多少小时 + long hour = diff % nd / nh; + // 计算差多少分钟 + long min = diff % nd % nh / nm; + // 计算差多少秒 + long s = diff % nd % nh % nm / ns; + // 输出结果 + return day + "天" + hour + "小时" + min + "分钟" + s + "秒"; + } + + /** + * 时间格式字符串转换成Date类型 + * + * @param date 时间字符串 + * @param format 如:yyyy-MM-dd HH:mm:ss + * @return + */ + public static Date dateStrConvertDateCst(String date, String format) { + try { + SimpleDateFormat simpledateformat = new SimpleDateFormat(format, + Locale.US); + Date newDate = simpledateformat.parse(date); + return newDate; + } catch (Exception e) { + e.printStackTrace(); + return null; + } + + } + + /** + * 将Date类型转换成字符串类型 + * + * @param date 时间 + * @param format 格式 + * @return + */ + public static String dateConvertStr(Date date, String format) { + return (date == null) ? null : new SimpleDateFormat(format) + .format(date); + } + + public static final String parseDateToStr(final String format, final Date date) { + return new SimpleDateFormat(format).format(date); + } +} diff --git a/demo-common/demo-common-utils/src/main/java/com/yxt/demo/common/utils/date/LocalDateUtils.java b/demo-common/demo-common-utils/src/main/java/com/yxt/demo/common/utils/date/LocalDateUtils.java new file mode 100644 index 0000000..86b323a --- /dev/null +++ b/demo-common/demo-common-utils/src/main/java/com/yxt/demo/common/utils/date/LocalDateUtils.java @@ -0,0 +1,77 @@ +package com.yxt.demo.common.utils.date; + +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.time.format.DateTimeFormatter; +import java.util.Date; + +/** + * @Author dimengzhe + * @Date 2021/11/6 22:52 + * @Description java 8 日期工具类再封装 + */ +public class LocalDateUtils { + + /** + * 比较第一个日期是否小于第二个日期 + * + * @param firstDate 第一个日期 + * @param secondDate 第二个日期 + * @return true-小于;false-大于 + */ + public static boolean localDateIsBefore(LocalDate firstDate, LocalDate secondDate) { + return firstDate.isBefore(secondDate); + } + + + /** + * 比较第一个日期是否大于第二个日期 + * + * @param firstDate 第一个日期 + * @param secondDate 第二个日期 + * @return true-大于;false-不大于 + */ + public static boolean localDateIsAfter(LocalDate firstDate, LocalDate secondDate) { + return firstDate.isAfter(secondDate); + } + + /** + * 比较两个日期是否相等 + * + * @param firstDate 第一个日期 + * @param secondDate 第二个日期 + * @return true-相等;false-不相等 + */ + public static boolean localDateIsEqual(LocalDate firstDate, LocalDate secondDate) { + return firstDate.isEqual(secondDate); + } + + + /** + * 字符串转换datetime + * + * @param dateTime + * @return yyyy-MM-dd HH:mm:ss + */ + public static Date stringCoverDateTime(String dateTime) { + LocalDateTime startDateTime = + LocalDateTime.parse(dateTime, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); + Date LocalDateTimeToDate = Date.from(startDateTime.atZone(ZoneId.systemDefault()).toInstant()); + return LocalDateTimeToDate; + } + + + /** + * 字符串转换date + * + * @param dateTime + * @return yyyy-MM-dd + */ + public static Date stringCoverDate(String dateTime) { + LocalDateTime startDateTime = + LocalDateTime.parse(dateTime, DateTimeFormatter.ofPattern("yyyy-MM-dd")); + Date LocalDateTimeToDate = Date.from(startDateTime.atZone(ZoneId.systemDefault()).toInstant()); + return LocalDateTimeToDate; + } +} diff --git a/demo-common/demo-common-utils/src/main/java/com/yxt/demo/common/utils/http/OkHttpUtils.java b/demo-common/demo-common-utils/src/main/java/com/yxt/demo/common/utils/http/OkHttpUtils.java new file mode 100644 index 0000000..6f84a5f --- /dev/null +++ b/demo-common/demo-common-utils/src/main/java/com/yxt/demo/common/utils/http/OkHttpUtils.java @@ -0,0 +1,345 @@ +package com.yxt.demo.common.utils.http; + +import com.alibaba.fastjson.JSON; +import okhttp3.*; + +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLSocketFactory; +import javax.net.ssl.TrustManager; +import javax.net.ssl.X509TrustManager; +import java.io.IOException; +import java.net.URLEncoder; +import java.security.SecureRandom; +import java.security.cert.X509Certificate; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.concurrent.Semaphore; +import java.util.concurrent.TimeUnit; + +/** + * @Author dimengzhe + * @Date 2021/11/5 20:57 + * @Description 封装OkHttp3工具类 + */ +public class OkHttpUtils { + + private static volatile OkHttpClient okHttpClient = null; + private static volatile Semaphore semaphore = null; + private Map headerMap; + private Map paramMap; + private String url; + private Request.Builder request; + + /** + * 初始化okHttpClient,并且允许https访问 + */ + private OkHttpUtils() { + if (okHttpClient == null) { + synchronized (OkHttpUtils.class) { + if (okHttpClient == null) { + TrustManager[] trustManagers = buildTrustManagers(); + okHttpClient = new OkHttpClient.Builder() + .connectTimeout(15, TimeUnit.SECONDS) + .writeTimeout(20, TimeUnit.SECONDS) + .readTimeout(20, TimeUnit.SECONDS) + .sslSocketFactory(createSSLSocketFactory(trustManagers), (X509TrustManager) trustManagers[0]) + .hostnameVerifier((hostName, session) -> true) + .retryOnConnectionFailure(true) + .build(); + addHeader("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36"); + } + } + } + } + + /** + * 用于异步请求时,控制访问线程数,返回结果 + * + * @return + */ + private static Semaphore getSemaphoreInstance() { + //只能1个线程同时访问 + synchronized (OkHttpUtils.class) { + if (semaphore == null) { + semaphore = new Semaphore(0); + } + } + return semaphore; + } + + /** + * 创建OkHttpUtils + * + * @return + */ + public static OkHttpUtils builder() { + return new OkHttpUtils(); + } + + /** + * 添加url + * + * @param url + * @return + */ + public OkHttpUtils url(String url) { + this.url = url; + return this; + } + + /** + * 添加参数 + * + * @param key 参数名 + * @param value 参数值 + * @return + */ + public OkHttpUtils addParam(String key, String value) { + if (paramMap == null) { + paramMap = new LinkedHashMap<>(16); + } + paramMap.put(key, value); + return this; + } + + /** + * 添加请求头 + * + * @param key 参数名 + * @param value 参数值 + * @return + */ + public OkHttpUtils addHeader(String key, String value) { + if (headerMap == null) { + headerMap = new LinkedHashMap<>(16); + } + headerMap.put(key, value); + return this; + } + + /** + * 初始化get方法 + * + * @return + */ + public OkHttpUtils get() { + request = new Request.Builder().get(); + StringBuilder urlBuilder = new StringBuilder(url); + if (paramMap != null) { + urlBuilder.append("?"); + try { + for (Map.Entry entry : paramMap.entrySet()) { + urlBuilder.append(URLEncoder.encode(entry.getKey(), "utf-8")). + append("="). + append(URLEncoder.encode(entry.getValue(), "utf-8")). + append("&"); + } + } catch (Exception e) { + e.printStackTrace(); + } + urlBuilder.deleteCharAt(urlBuilder.length() - 1); + } + request.url(urlBuilder.toString()); + return this; + } + + /** + * 初始化post方法 + * + * @param isJsonPost true等于json的方式提交数据,类似postman里post方法的raw + * false等于普通的表单提交 + * @return + */ + public OkHttpUtils post(boolean isJsonPost) { + RequestBody requestBody; + if (isJsonPost) { + String json = ""; + if (paramMap != null) { + json = JSON.toJSONString(paramMap); + } + requestBody = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), json); + } else { + FormBody.Builder formBody = new FormBody.Builder(); + if (paramMap != null) { + paramMap.forEach(formBody::add); + } + requestBody = formBody.build(); + } + request = new Request.Builder().post(requestBody).url(url); + return this; + } + + /** + * 同步请求 + * + * @return + */ + public String sync() { + setHeader(request); + try { + Response response = okHttpClient.newCall(request.build()).execute(); + assert response.body() != null; + return response.body().string(); + } catch (IOException e) { + e.printStackTrace(); + return "请求失败:" + e.getMessage(); + } + } + + /** + * 异步请求,有返回值 + */ + public String async() { + StringBuilder buffer = new StringBuilder(""); + setHeader(request); + okHttpClient.newCall(request.build()).enqueue(new Callback() { + @Override + public void onFailure(Call call, IOException e) { + buffer.append("请求出错:").append(e.getMessage()); + } + + @Override + public void onResponse(Call call, Response response) throws IOException { + assert response.body() != null; + buffer.append(response.body().string()); + getSemaphoreInstance().release(); + } + }); + try { + getSemaphoreInstance().acquire(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + return buffer.toString(); + } + + /** + * 异步请求,带有接口回调 + * + * @param callBack + */ + public void async(ICallBack callBack) { + setHeader(request); + okHttpClient.newCall(request.build()).enqueue(new Callback() { + @Override + public void onFailure(Call call, IOException e) { + callBack.onFailure(call, e.getMessage()); + } + + @Override + public void onResponse(Call call, Response response) throws IOException { + assert response.body() != null; + callBack.onSuccessful(call, response.body().string()); + } + }); + } + + /** + * 为request添加请求头 + * + * @param request + */ + private void setHeader(Request.Builder request) { + if (headerMap != null) { + try { + for (Map.Entry entry : headerMap.entrySet()) { + request.addHeader(entry.getKey(), entry.getValue()); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + } + + + /** + * 生成安全套接字工厂,用于https请求的证书跳过 + * + * @return + */ + private static SSLSocketFactory createSSLSocketFactory(TrustManager[] trustAllCerts) { + SSLSocketFactory ssfFactory = null; + try { + SSLContext sc = SSLContext.getInstance("SSL"); + sc.init(null, trustAllCerts, new SecureRandom()); + ssfFactory = sc.getSocketFactory(); + } catch (Exception e) { + e.printStackTrace(); + } + return ssfFactory; + } + + private static TrustManager[] buildTrustManagers() { + return new TrustManager[]{ + new X509TrustManager() { + @Override + public void checkClientTrusted(X509Certificate[] chain, String authType) { + } + + @Override + public void checkServerTrusted(X509Certificate[] chain, String authType) { + } + + @Override + public X509Certificate[] getAcceptedIssuers() { + return new X509Certificate[]{}; + } + } + }; + } + + /** + * 自定义一个接口回调 + */ + public interface ICallBack { + void onSuccessful(Call call, String data); + + void onFailure(Call call, String errorMsg); + } + + /*****************************使用教程************************************************************/ + + public static void main(String[] args) { + // get请求,方法顺序按照这种方式,切记选择post/get一定要放在倒数第二,同步或者异步倒数第一,才会正确执行 + OkHttpUtils.builder().url("请求地址,http/https都可以") + // 有参数的话添加参数,可多个 + .addParam("参数名", "参数值") + .addParam("参数名", "参数值") + // 也可以添加多个 + .addHeader("Content-Type", "application/json; charset=utf-8") + .get() + // 可选择是同步请求还是异步请求 + //.async(); + .sync(); + + // post请求,分为两种,一种是普通表单提交,一种是json提交 + OkHttpUtils.builder().url("请求地址,http/https都可以") + // 有参数的话添加参数,可多个 + .addParam("参数名", "参数值") + .addParam("参数名", "参数值") + // 也可以添加多个 + .addHeader("Content-Type", "application/json; charset=utf-8") + // 如果是true的话,会类似于postman中post提交方式的raw,用json的方式提交,不是表单 + // 如果是false的话传统的表单提交 + .post(true) + .sync(); + + // 选择异步有两个方法,一个是带回调接口,一个是直接返回结果 + OkHttpUtils.builder().url("") + .post(false) + .async(); + + OkHttpUtils.builder().url("").post(false).async(new ICallBack() { + @Override + public void onSuccessful(Call call, String data) { + // 请求成功后的处理 + } + + @Override + public void onFailure(Call call, String errorMsg) { + // 请求失败后的处理 + } + }); + } + +} diff --git a/demo-common/demo-common-utils/src/main/java/com/yxt/demo/common/utils/jwt/JwtUtils.java b/demo-common/demo-common-utils/src/main/java/com/yxt/demo/common/utils/jwt/JwtUtils.java new file mode 100644 index 0000000..ef556b8 --- /dev/null +++ b/demo-common/demo-common-utils/src/main/java/com/yxt/demo/common/utils/jwt/JwtUtils.java @@ -0,0 +1,85 @@ +package com.yxt.demo.common.utils.jwt; + +import io.jsonwebtoken.Jwts; +import io.jsonwebtoken.SignatureAlgorithm; + +import java.util.Date; +import java.util.HashMap; +import java.util.Map; + +/** + * @Author dimengzhe + * @Date 2021/11/6 22:55 + * @Description + */ +public class JwtUtils { + + /** + * 签名密钥(高度保密) + */ + private static final String SECRET = "qYYjXt7s1C*nEC%9RCwQGFA$YwPr$Jrj"; + /** + * 签名算法 + */ + private static final SignatureAlgorithm SIGNATURE_ALGORITHM = SignatureAlgorithm.HS512; + /** + * token前缀 + */ + private static final String TOKEN_PREFIX = "Bearer "; + /** + * 有效期:1天 + */ + private static final Long TIME = 24 * 3600 * 1000L; + + /** + * 生成JWT token + * + * @param map 传入数据 + * @return + */ + public static String sign(Map map) { + Date now = new Date(System.currentTimeMillis()); + String jwt = Jwts.builder() + // 设置自定义数据 + .setClaims(map) + // 设置签发时间 + .setIssuedAt(now) + // 设置过期时间 + .setExpiration(new Date(now.getTime() + TIME)) + .signWith(SIGNATURE_ALGORITHM, SECRET) + .compact(); + return TOKEN_PREFIX + jwt; + } + + /** + * 验证JWT token并返回数据。当验证失败时,抛出异常 + * + * @param token token + * @return + */ + public static Map unSign(String token) { + try { + return Jwts.parser() + .setSigningKey(SECRET) + .parseClaimsJws(token.replace(TOKEN_PREFIX, "")) + .getBody(); + } catch (Exception e) { + throw new IllegalStateException("Token验证失败:" + e.getMessage()); + } + } + + public static void main(String[] args) { + /* Map map = new HashMap<>(); + map.put("userName", "admin"); + map.put("userId", "001"); + String token = JwtUtils.sign(map, 3600_000); + System.out.println(JwtUtils.unSign(token));*/ + Map map = new HashMap<>(); + map.put("userSid", "123456788"); + map.put("userName", "你好"); +// sign(map); +// System.out.println(sign(map)); + Map map1 = unSign("Bearer eyJhbGciOiJIUzUxMiJ9.eyJ1c2VyU2lkIjoiMTIzNDU2Nzg4IiwidXNlck5hbWUiOiLkvaDlpb0iLCJleHAiOjE2MzYyOTk0NTgsImlhdCI6MTYzNjIxMzA1OH0.iuyZznSCm0QYneqfck_zc3fpg57YsAdG8k2aLrDY_4NZJwJdVxE7supqLtfEvTC5O0EhG590ShhRsVoU-rbSrA"); + System.out.println(map1); + } +} diff --git a/demo-common/pom.xml b/demo-common/pom.xml new file mode 100644 index 0000000..9e502b3 --- /dev/null +++ b/demo-common/pom.xml @@ -0,0 +1,35 @@ + + + + com.yxt + demo + 0.0.1 + + 4.0.0 + com.yxt.demo + demo-common + 0.0.1 + + demo-common-redis + demo-common-config + demo-common-utils + demo-common-core + demo-common-base + demo-common-jdbc + + pom + di-common + 框架的公共项目,存放项目中用到的基础类、公共类及工具类。各项目根据需要引用对应子项目 + + + + com.github.xiaoymin + knife4j-spring-boot-starter + + + + + + \ No newline at end of file diff --git a/demo-gateway/pom.xml b/demo-gateway/pom.xml new file mode 100644 index 0000000..3622766 --- /dev/null +++ b/demo-gateway/pom.xml @@ -0,0 +1,89 @@ + + + + com.yxt + demo + 0.0.1 + + 4.0.0 + + com.yxt.demo + demo-gateway + 0.0.1 + + + + org.springframework.cloud + spring-cloud-starter-gateway + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-discovery + + + org.projectlombok + lombok + true + + + + com.yxt.demo + demo-common-utils + 0.0.1 + + + org.springframework.boot + spring-boot-starter-web + + + + + com.yxt.demo + demo-common-core + 0.0.1 + + + org.springframework.boot + spring-boot-starter-web + + + + + com.yxt.demo + demo-common-redis + 0.0.1 + + + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + 2.5.6 + + + + repackage + + + + + + + + src/main/resources + + **/*.yml + + false + + + + + \ No newline at end of file diff --git a/demo-gateway/src/main/java/com/yxt/demo/gateway/AuthFilter.java b/demo-gateway/src/main/java/com/yxt/demo/gateway/AuthFilter.java new file mode 100644 index 0000000..7244307 --- /dev/null +++ b/demo-gateway/src/main/java/com/yxt/demo/gateway/AuthFilter.java @@ -0,0 +1,128 @@ +package com.yxt.demo.gateway; + +import com.alibaba.fastjson.JSON; +import com.yxt.demo.common.core.constant.StatusEnum; +import com.yxt.demo.common.core.result.ResultBean; +import com.yxt.demo.common.redis.service.RedisService; +import com.yxt.demo.common.utils.convert.StringUtil; +import com.yxt.demo.gateway.config.CacheConstants; +import com.yxt.demo.gateway.config.IgnoreWhiteProperties; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.cloud.gateway.filter.GatewayFilterChain; +import org.springframework.cloud.gateway.filter.GlobalFilter; +import org.springframework.core.Ordered; +import org.springframework.core.io.buffer.DataBufferFactory; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.server.reactive.ServerHttpRequest; +import org.springframework.http.server.reactive.ServerHttpResponse; +import org.springframework.stereotype.Component; +import org.springframework.web.server.ServerWebExchange; +import reactor.core.publisher.Mono; + +/** + * @author dimengzhe + * @date 2020/12/2 9:52 + * @description 网关鉴权 + * 1.某些接口不需要不进行登录验证,如登录,注册,获取验证码等接口。(uri白名单) + * 2.某些接口需要登录验证,但是不需要刷新token有效时间,如客户端轮询请求的接口。 + * 3.特定场景下IP黑、白名单。 + * 4.处于安全考虑的接口流量控制。 + */ +@Component +@Slf4j +public class AuthFilter implements GlobalFilter, Ordered { + + /** + * 过期时间设置为4小时 + */ + private final static long EXPIRE_TIME = CacheConstants.TOKEN_EXPIRE * 60; + private final static long EXPIRE_TIME_APP = CacheConstants.TOKEN_EXPIRE_APP * 60; + private final static String APP = "App"; + + + // 排除过滤的 uri 地址,nacos自行添加 + @Autowired + private IgnoreWhiteProperties ignoreWhite; + @Autowired + private RedisService redisUtil; + /* + redis中数据存储结构为两个键值对 + 键为用户ID,值为用户token,可以通过用户ID查询用户token,实现立刻失效用户token功能。 + 键为用户token,值为用户数据,实现token有效性,用户数据缓存功能。 + */ + + @Override + public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) { + String url = exchange.getRequest().getURI().getPath(); + //1.uri白名单。 跳过不需要验证的路径 + if (StringUtil.matches(url, ignoreWhite.getWhites())) { + return chain.filter(exchange); + } else if (StringUtil.matchesTwo(url, ignoreWhite.getWhitesTwo())) { + return chain.filter(exchange); + } + //2.验证有无令牌。 从请求的header中获取token + String token = getToken(exchange.getRequest()); + if (StringUtil.isBlank(token)) { + return setUnauthorizedResponse(exchange, "令牌不能为空"); + } + //3.验证token是否有效。(a.验证token是否合法 b.验证token是否过期) + //从redis缓存中获取key对应的内容 + String userName = redisUtil.get(token); + + if (StringUtil.isBlank(userName)) { + return setUnauthorizedResponse(exchange, "登录状态已过期"); + } + //验签:需要验证token中的签名是否与用户sid一致,后台用密钥+userSid+token除签名以外的内容,重新生成签名,与token中的签名进行比较 + + //刷新token过期日期 + if (token.contains(APP)) { + redisUtil.expire(token, EXPIRE_TIME_APP); + } else { + redisUtil.expire(token, EXPIRE_TIME); + } + + // 在请求中增加用户信息 + ServerHttpRequest mutableReq = exchange.getRequest().mutate() + .header(CacheConstants.DETAILS_USERNAME, userName).build(); + ServerWebExchange mutableExchange = exchange.mutate().request(mutableReq).build(); + return chain.filter(mutableExchange); + } + + /** + * 鉴权异常处理 + * + * @param exchange + * @param msg + * @return + */ + private Mono setUnauthorizedResponse(ServerWebExchange exchange, String msg) { + ResultBean resultBean = ResultBean.fireFail(); + ServerHttpResponse response = exchange.getResponse(); + response.getHeaders().setContentType(MediaType.APPLICATION_JSON); + response.setStatusCode(HttpStatus.OK); + + log.error("[鉴权异常处理]请求路径:{}", exchange.getRequest().getPath()); + + return response.writeWith(Mono.fromSupplier(() -> { + DataBufferFactory bufferFactory = response.bufferFactory(); + log.error(msg); + return bufferFactory.wrap(JSON.toJSONBytes(resultBean.setCode(StatusEnum.OVERDUE.getCode()).setMsg(msg))); + })); + } + + /** + * 获取请求token + */ + private String getToken(ServerHttpRequest request) { + String token = request.getHeaders().getFirst(CacheConstants.HEADER); + return token; + } + + @Override + public int getOrder() { + return 0; + } + +} diff --git a/demo-gateway/src/main/java/com/yxt/demo/gateway/DemoGatewayApplication.java b/demo-gateway/src/main/java/com/yxt/demo/gateway/DemoGatewayApplication.java new file mode 100644 index 0000000..cd1448e --- /dev/null +++ b/demo-gateway/src/main/java/com/yxt/demo/gateway/DemoGatewayApplication.java @@ -0,0 +1,28 @@ +package com.yxt.demo.gateway; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; +import org.springframework.cloud.client.discovery.EnableDiscoveryClient; + +import java.time.LocalDate; +import java.time.LocalTime; + +/** + * @author dimengzhe + * @date 2020/8/28 14:11 + * @description 网关 + */ +@EnableDiscoveryClient +@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class}, + scanBasePackages = {"com.yxt.demo"}) +@Slf4j +public class DemoGatewayApplication { + + public static void main(String[] args) { + SpringApplication.run(DemoGatewayApplication.class, args); + log.info("------" + LocalDate.now(), LocalTime.now() + "------"); + log.info("(♥◠‿◠)ノ゙ 网关模块启动成功 ლ(´ڡ`ლ)゙ \n"); + } +} diff --git a/demo-gateway/src/main/java/com/yxt/demo/gateway/RedisConfig.java b/demo-gateway/src/main/java/com/yxt/demo/gateway/RedisConfig.java new file mode 100644 index 0000000..97a28df --- /dev/null +++ b/demo-gateway/src/main/java/com/yxt/demo/gateway/RedisConfig.java @@ -0,0 +1,107 @@ +package com.yxt.demo.gateway; + + +import com.fasterxml.jackson.annotation.JsonAutoDetect; +import com.fasterxml.jackson.annotation.PropertyAccessor; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.redis.connection.RedisConnectionFactory; +import org.springframework.data.redis.connection.jedis.JedisConnectionFactory; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer; +import org.springframework.data.redis.serializer.StringRedisSerializer; +import redis.clients.jedis.JedisPoolConfig; + +/** + * @author dimengzhe + * @date 2020/9/18 19:37 + * @description + */ +@Configuration +public class RedisConfig { + + @Value("${spring.redis.host}") + private String host; + + @Value("${spring.redis.password}") + private String password; + + @Value("${spring.redis.port}") + private int port; + + @Value("${spring.redis.timeout}") + private int timeout; + + @Value("${spring.redis.jedis.pool.max-active}") + private int redisPoolMaxActive; + + @Value("${spring.redis.jedis.pool.max-wait}") + private int redisPoolMaxWait; + + @Value("${spring.redis.jedis.pool.max-idle}") + private int redisPoolMaxIdle; + + @Value("${spring.redis.jedis.pool.min-idle}") + private int redisPoolMinIdle; + @Value("${spring.redis.database}") + private int database; + + @Bean + public JedisPoolConfig getJedisPoolConfig() { + JedisPoolConfig jedisPoolConfig = new JedisPoolConfig(); + //最大空闲数 + jedisPoolConfig.setMaxIdle(redisPoolMaxIdle); + //最小空闲数 + jedisPoolConfig.setMinIdle(redisPoolMinIdle); + //最大建立连接等待时间 + jedisPoolConfig.setMaxWaitMillis(redisPoolMaxWait); + //连接池的最大数据库连接数 + jedisPoolConfig.setMaxTotal(redisPoolMaxActive); + return jedisPoolConfig; + } + + + @Bean + public JedisConnectionFactory jedisConnectionFactory(JedisPoolConfig jedisPoolConfig) { + + JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory(jedisPoolConfig); + jedisConnectionFactory.setDatabase(database); + //IP地址 + jedisConnectionFactory.setHostName(host); + //如果redis设置有密码 + jedisConnectionFactory.setPassword(password); + //端口号 + jedisConnectionFactory.setPort(port); + //客户端超时时间单位是毫秒 + jedisConnectionFactory.setTimeout(timeout); +// jedisConnectionFactory.afterPropertiesSet(); //记得添加这行! + return jedisConnectionFactory; + } + + @Bean + public RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory) { + RedisTemplate redisTemplate = new RedisTemplate<>(); + redisTemplate.setConnectionFactory(redisConnectionFactory); + // 使用Jackson2JsonRedisSerialize 替换默认序列化 + Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class); + ObjectMapper om = new ObjectMapper(); + om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); + om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); + jackson2JsonRedisSerializer.setObjectMapper(om); + StringRedisSerializer stringRedisSerializer = new StringRedisSerializer(); + // key采用String的序列化方式 + //redisTemplate.setKeySerializer(new StringRedisSerializer()); + redisTemplate.setKeySerializer(stringRedisSerializer); + // hash的key也采用String的序列化方式 + redisTemplate.setHashKeySerializer(stringRedisSerializer); + // value序列化方式采用jackson + // redisTemplate.setValueSerializer(jackson2JsonRedisSerializer); + redisTemplate.setValueSerializer(stringRedisSerializer); + // hash的value序列化方式采用jackson + redisTemplate.setHashValueSerializer(stringRedisSerializer); + redisTemplate.afterPropertiesSet(); + return redisTemplate; + } +} diff --git a/demo-gateway/src/main/java/com/yxt/demo/gateway/RedisUtil.java b/demo-gateway/src/main/java/com/yxt/demo/gateway/RedisUtil.java new file mode 100644 index 0000000..d60594a --- /dev/null +++ b/demo-gateway/src/main/java/com/yxt/demo/gateway/RedisUtil.java @@ -0,0 +1,300 @@ +package com.yxt.demo.gateway; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.dao.DataAccessException; +import org.springframework.data.redis.connection.RedisConnection; +import org.springframework.data.redis.connection.RedisStringCommands; +import org.springframework.data.redis.core.*; +import org.springframework.data.redis.core.types.Expiration; +import org.springframework.data.redis.serializer.RedisSerializer; +import org.springframework.stereotype.Service; + +import java.io.Serializable; +import java.util.List; +import java.util.Set; +import java.util.concurrent.TimeUnit; + +/** + * @author dimengzhe + * @date 2020/9/9 17:35 + * @description redis工具类 + */ +@Service +public class RedisUtil { + + @Autowired + private RedisTemplate redisTemplate; + + + /** + * 字符串类型:根据key设置value值,如果key中的value存在,那么返回false + * + * @param key + * @param value + * @return + */ + public Boolean setnx(final String key, final String value, final long expration, final TimeUnit timeUnit) { + return (Boolean) redisTemplate.execute(new RedisCallback() { + @Override + public Boolean doInRedis(RedisConnection redisConnection) throws DataAccessException { + RedisSerializer redisSerializer = redisTemplate.getStringSerializer(); + byte keys[] = redisSerializer.serialize(key); + byte values[] = redisSerializer.serialize(value); + return redisConnection.set(keys, values, Expiration.from(expration, timeUnit), RedisStringCommands.SetOption.SET_IF_ABSENT); + } + }); + } + + /** + * 写入缓存 + * + * @param key + * @param value + * @return + */ + public boolean set(final String key, final String value) { + + boolean result = (boolean) redisTemplate.execute(new RedisCallback() { + @Override + public Boolean doInRedis(RedisConnection connection) throws DataAccessException { + RedisSerializer serializer = redisTemplate.getStringSerializer(); + connection.set(serializer.serialize(key), serializer.serialize(value)); + return true; + } + }); + return result; + } + + /** + * 写入缓存设置时效时间 + * + * @param key + * @param value + * @return + */ + public boolean set(final String key, Object value, Long expireTime) { + boolean result = false; + try { + ValueOperations operations = redisTemplate.opsForValue(); + operations.set(key, value); + redisTemplate.expire(key, expireTime, TimeUnit.SECONDS); + result = true; + } catch (Exception e) { + e.printStackTrace(); + } + return result; + } + /** + * 刷新缓存到期时间 + * @param key + * @param expire + * @return + */ + public boolean expire(String key, long expire) { + return redisTemplate.expire(key, expire, TimeUnit.SECONDS); + } + + /** + * 读取缓存 + * + * @param key + * @return + */ + public String get(final String key) { + String result = (String) redisTemplate.execute(new RedisCallback() { + @Override + public String doInRedis(RedisConnection connection) throws DataAccessException { + RedisSerializer serializer = redisTemplate.getStringSerializer(); + byte[] value = connection.get(serializer.serialize(key)); + return serializer.deserialize(value); + } + }); + return result; + } + + /** + * 正则获取key集合 + * + * @param pattern + * @return + */ + public Set keys(String pattern) { + Set keys = redisTemplate.keys(pattern); + return keys; + } + + + /** + * 批量删除对应的value + * + * @param keys + */ + public void remove(final String... keys) { + for (String key : keys) { + remove(key); + } + } + + /** + * 批量删除key + * + * @param pattern + */ + public void removePattern(final String pattern) { + Set keys = redisTemplate.keys(pattern); + if (keys.size() > 0) { + redisTemplate.delete(keys); + } + + } + + + public Long remove(final String key) { + return (Long) redisTemplate.execute(new RedisCallback() { + @Override + public Long doInRedis(RedisConnection redisConnection) throws DataAccessException { + RedisSerializer serializer = redisTemplate.getStringSerializer(); + byte keys[] = serializer.serialize(key); + return redisConnection.del(keys); + } + }); + } + + + /** + * 判断缓存中是否有对应的value + * + * @param key + * @return + */ + public boolean exists(final String key) { + return redisTemplate.hasKey(key); + } + + + /** + * 哈希 添加 + * + * @param key + * @param hashKey + * @param value + */ + public void hmSet(String key, Object hashKey, Object value) { + HashOperations hash = redisTemplate.opsForHash(); + hash.put(key, hashKey, value); + } + + /** + * 哈希获取数据 + * + * @param key + * @param hashKey + * @return + */ + public String hmGet(String key, Object hashKey) { + HashOperations hash = redisTemplate.opsForHash(); + return hash.get(key, hashKey); + } + + /** + * 获取哈希 keys + * + * @param key + * @return + */ + public Set hmGetKeys(String key) { + HashOperations hash = redisTemplate.opsForHash(); + return hash.keys(key); + } + + /** + * 删除集合中的key + * + * @param key + * @param hashKey + */ + public void hmDelete(String key, Object hashKey) { + HashOperations hash = redisTemplate.opsForHash(); + hash.delete(key, hashKey); + } + + /** + * 列表添加 + * + * @param k + * @param v + */ + public void lPush(String k, Object v) { + ListOperations list = redisTemplate.opsForList(); + list.rightPush(k, v); + } + + /** + * 列表获取 + * + * @param k + * @param l + * @param l1 + * @return + */ + public List lRange(String k, long l, long l1) { + ListOperations list = redisTemplate.opsForList(); + return list.range(k, l, l1); + } + + /** + * 集合添加 + * + * @param key + * @param value + */ + public void add(String key, Object value) { + SetOperations set = redisTemplate.opsForSet(); + set.add(key, value); + } + + /** + * 集合获取 + * + * @param key + * @return + */ + public Set setMembers(String key) { + SetOperations set = redisTemplate.opsForSet(); + return set.members(key); + } + + /** + * 有序集合添加 + * + * @param key + * @param value + * @param scoure + */ + public void zAdd(String key, Object value, double scoure) { + ZSetOperations zset = redisTemplate.opsForZSet(); + zset.add(key, value, scoure); + } + + /** + * 有序集合获取 + * + * @param key + * @param scoure + * @param scoure1 + * @return + */ + public Set rangeByScore(String key, double scoure, double scoure1) { + ZSetOperations zset = redisTemplate.opsForZSet(); + return zset.rangeByScore(key, scoure, scoure1); + } + + /** + * 实现命令:TTL key 以秒为单位,返回给定key的剩余生存时间 + * @param key + * @return + */ + public long ttl(String key) { + return redisTemplate.getExpire(key); + } +} diff --git a/demo-gateway/src/main/java/com/yxt/demo/gateway/config/CacheConstants.java b/demo-gateway/src/main/java/com/yxt/demo/gateway/config/CacheConstants.java new file mode 100644 index 0000000..0fd7a0b --- /dev/null +++ b/demo-gateway/src/main/java/com/yxt/demo/gateway/config/CacheConstants.java @@ -0,0 +1,31 @@ +package com.yxt.demo.gateway.config; + +/** + * @author dimengzhe + * @date 2020/12/2 9:58 + * @description 缓存的key 常量 + */ + +public class CacheConstants { + + /** + * 令牌自定义标识 + */ + public static final String HEADER = "token"; + + /** + * 令牌前缀 + */ + public static final String TOKEN_PREFIX = "Bearer "; + + /** + * 用户名字段 + */ + public static final String DETAILS_USERNAME = "userName"; + + /** + * 令牌有效期(分钟) + */ + public final static long TOKEN_EXPIRE = 4*60; + public final static long TOKEN_EXPIRE_APP = 15*24*60; +} diff --git a/demo-gateway/src/main/java/com/yxt/demo/gateway/config/IgnoreWhiteProperties.java b/demo-gateway/src/main/java/com/yxt/demo/gateway/config/IgnoreWhiteProperties.java new file mode 100644 index 0000000..ba07ef3 --- /dev/null +++ b/demo-gateway/src/main/java/com/yxt/demo/gateway/config/IgnoreWhiteProperties.java @@ -0,0 +1,42 @@ +package com.yxt.demo.gateway.config; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.cloud.context.config.annotation.RefreshScope; +import org.springframework.context.annotation.Configuration; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author dimengzhe + * @date 2020/12/2 9:54 + * @description 放行白名单配置 + */ +@Configuration +@RefreshScope +@ConfigurationProperties(prefix = "ignore") +public class IgnoreWhiteProperties { + + /** + * 放行白名单配置,网关不校验此处的白名单 + */ + private List whites = new ArrayList<>(); + + public List getWhites() { + return whites; + } + + public void setWhites(List whites) { + this.whites = whites; + } + + private List whitesTwo = new ArrayList<>(); + + public List getWhitesTwo() { + return whitesTwo; + } + + public void setWhitesTwo(List whitesTwo) { + this.whitesTwo = whitesTwo; + } +} diff --git a/demo-gateway/src/main/java/com/yxt/demo/gateway/config/swagger/SwaggerConfig.java b/demo-gateway/src/main/java/com/yxt/demo/gateway/config/swagger/SwaggerConfig.java new file mode 100644 index 0000000..02bf81f --- /dev/null +++ b/demo-gateway/src/main/java/com/yxt/demo/gateway/config/swagger/SwaggerConfig.java @@ -0,0 +1,58 @@ +package com.yxt.demo.gateway.config.swagger; + +import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.cloud.gateway.config.GatewayProperties; +import org.springframework.cloud.gateway.route.RouteLocator; +import org.springframework.cloud.gateway.support.NameUtils; +import org.springframework.context.annotation.Primary; +import org.springframework.stereotype.Component; +import springfox.documentation.swagger.web.SwaggerResource; +import springfox.documentation.swagger.web.SwaggerResourcesProvider; + +import java.util.ArrayList; +import java.util.List; + +/** + * @Author dimengzhe + * @Date 2022/11/5 22:58 + * @Description + */ +@Slf4j +@Component +@Primary +@AllArgsConstructor +public class SwaggerConfig implements SwaggerResourcesProvider { + /** + * 路由加载器 + */ + private final RouteLocator routeLocator; + private final GatewayProperties gatewayProperties; + + @Override + public List get() { + List resources = new ArrayList<>(); + List routes = new ArrayList<>(); + //获取所有路由的ID + routeLocator.getRoutes().subscribe(route -> routes.add(route.getId())); + //过滤出配置文件中定义的路由->过滤出Path Route Predicate->根据路径拼接成api-docs路径->生成SwaggerResource + gatewayProperties.getRoutes().stream().filter(routeDefinition -> routes.contains(routeDefinition.getId())).forEach(route -> { + route.getPredicates().stream() + .filter(predicateDefinition -> ("Path").equalsIgnoreCase(predicateDefinition.getName())) + .forEach(predicateDefinition -> resources.add(swaggerResource(route.getId(), + predicateDefinition.getArgs().get(NameUtils.GENERATED_NAME_PREFIX + "0") + .replace("**", "v2/api-docs")))); + }); + + return resources; + } + + private SwaggerResource swaggerResource(String name, String location) { + log.info("name:{},location:{}", name, location); + SwaggerResource swaggerResource = new SwaggerResource(); + swaggerResource.setName(name); + swaggerResource.setLocation(location); + swaggerResource.setSwaggerVersion("2.0"); + return swaggerResource; + } +} diff --git a/demo-gateway/src/main/java/com/yxt/demo/gateway/config/swagger/SwaggerHandler.java b/demo-gateway/src/main/java/com/yxt/demo/gateway/config/swagger/SwaggerHandler.java new file mode 100644 index 0000000..8a22253 --- /dev/null +++ b/demo-gateway/src/main/java/com/yxt/demo/gateway/config/swagger/SwaggerHandler.java @@ -0,0 +1,63 @@ +package com.yxt.demo.gateway.config.swagger; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; +import reactor.core.publisher.Mono; +import springfox.documentation.swagger.web.SecurityConfiguration; +import springfox.documentation.swagger.web.SecurityConfigurationBuilder; +import springfox.documentation.swagger.web.UiConfiguration; +import springfox.documentation.swagger.web.UiConfigurationBuilder; + +import java.util.Optional; + +/** + * @Author dimengzhe + * @Date 2022/11/5 23:03 + * @Description + */ + +@RestController +public class SwaggerHandler { + + @Autowired(required = false) + private SecurityConfiguration securityConfiguration; + + @Autowired(required = false) + private UiConfiguration uiConfiguration; + + private final SwaggerConfig swaggerResources; + + @Autowired + public SwaggerHandler(SwaggerConfig swaggerResources) { + this.swaggerResources = swaggerResources; + } + + /** + * Swagger安全配置,支持oauth和apiKey设置 + */ + @GetMapping("/swagger-resources/configuration/security") + public Mono> securityConfiguration() { + return Mono.just(new ResponseEntity<>( + Optional.ofNullable(securityConfiguration).orElse(SecurityConfigurationBuilder.builder().build()), HttpStatus.OK)); + } + + /** + * Swagger UI配置 + */ + @GetMapping("/swagger-resources/configuration/ui") + public Mono> uiConfiguration() { + return Mono.just(new ResponseEntity<>( + Optional.ofNullable(uiConfiguration).orElse(UiConfigurationBuilder.builder().build()), HttpStatus.OK)); + } + + /** + * Swagger资源配置,微服务中这各个服务的api-docs信息 + */ + @GetMapping("/swagger-resources") + public Mono swaggerResources() { + return Mono.just((new ResponseEntity<>(swaggerResources.get(), HttpStatus.OK))); + } +} diff --git a/demo-gateway/src/main/resources/application-devv.yml b/demo-gateway/src/main/resources/application-devv.yml new file mode 100644 index 0000000..b4cd9fb --- /dev/null +++ b/demo-gateway/src/main/resources/application-devv.yml @@ -0,0 +1,19 @@ +spring: + resources: + static-locations: file:D://anrui + cloud: + nacos: + discovery: + server-addr: 127.0.0.1:8848 + redis: + database: 3 # Redis数据库索引(默认为0) + host: 127.0.0.1 + jedis: + pool: + max-active: -1 #连接池最大连接数(使用负值表示没有限制) + max-idle: 8 #连接池中的最大空闲连接 + max-wait: -1 # 连接池最大阻塞等待时间(使用负值表示没有限制) + min-idle: 0 # 连接池中的最小空闲连接 + password: 123456 + port: 6379 + timeout: 0 # 连接超时时间(毫秒) \ No newline at end of file diff --git a/demo-gateway/src/main/resources/application-pro.yml b/demo-gateway/src/main/resources/application-pro.yml new file mode 100644 index 0000000..b354658 --- /dev/null +++ b/demo-gateway/src/main/resources/application-pro.yml @@ -0,0 +1,19 @@ +spring: + resources: + static-locations: file:D://anrui + cloud: + nacos: + discovery: + server-addr: 127.0.0.1:8848 + redis: + database: 3 # Redis数据库索引(默认为0) + host: 127.0.0.1 + jedis: + pool: + max-active: -1 #连接池最大连接数(使用负值表示没有限制) + max-idle: 8 #连接池中的最大空闲连接 + max-wait: -1 # 连接池最大阻塞等待时间(使用负值表示没有限制) + min-idle: 0 # 连接池中的最小空闲连接 + password: 123456 + port: 6379 + timeout: 0 # 连接超时时间(毫秒) \ No newline at end of file diff --git a/demo-gateway/src/main/resources/application-test.yml b/demo-gateway/src/main/resources/application-test.yml new file mode 100644 index 0000000..9fd2a33 --- /dev/null +++ b/demo-gateway/src/main/resources/application-test.yml @@ -0,0 +1,19 @@ +spring: + resources: + static-locations: file:/home/lzh/docker_data/nginx/html/anrui-system-ui + cloud: + nacos: + discovery: + server-addr: 172.18.0.5:8848 + redis: + database: 3 # Redis数据库索引(默认为0) + host: 172.18.0.7 + jedis: + pool: + max-active: -1 #连接池最大连接数(使用负值表示没有限制) + max-idle: 8 #连接池中的最大空闲连接 + max-wait: -1 # 连接池最大阻塞等待时间(使用负值表示没有限制) + min-idle: 0 # 连接池中的最小空闲连接 + password: + port: 6379 + timeout: 0 # 连接超时时间(毫秒) \ No newline at end of file diff --git a/demo-gateway/src/main/resources/application.yml b/demo-gateway/src/main/resources/application.yml new file mode 100644 index 0000000..26cf53e --- /dev/null +++ b/demo-gateway/src/main/resources/application.yml @@ -0,0 +1,91 @@ +hystrix: + command: + default: + execution: + isolation: + strategy: SEMAPHORE + thread: + timeoutInMilliseconds: 300000 +server: + port: 8111 +spring: + application: + name: gateway-server + profiles: + active: devv + cloud: + gateway: + routes: + - id: demo-system + predicates: + - Path= /system/** + uri: lb://demo-system + filters: + - StripPrefix=1 + +ignore: + whites: + - /portal/v1/regions/treeList + - /portal/v1/sysuser/reGetPwd #忘记密码 + - /portal/v1/sysuser/login #pc端登录 + - + - /portal/v1/sysuser/loginByNoVeriCode #登录无验证码 + - /portal/v1/sysuser/signOut #pc 退出登录 + - /portal/v1/sysuser/save #pc端登录 + - /portal/v1/captcha/clickWord #验证码 + + - /portal/v1/appuser/login #app端登录 + - /portal/v1/appuser/sendVerificationCodeForApp #app端验证码 + - /portal/v1/appuser/checkResetPwdCode #app端验证找回密码的验证码 + - /portal/v1/appuser/resetPwd #app端重置密码(找回密码) + - /portal/v1/appversion/save #更新app框架 + - /portal/v1/appsubsetversion/save #更新app子应用(新增) + - /portal/v1/appsubsetversion/update #更新app子应用(更新) + - /portal/v1/appversion/selectNewAppVersion #获取最新版本 + - /portal/v1/wxuser/sendMessageCode #客户端注册获取验证码 + - /portal/v1/wxuser/registsUser #客户端注册 + - /portal/v1/wxuser/login #客户端登录 + - /portal/file/getImgBase64 + - /portal/v1/wxuser/checkResetPwdCode #客户端端验证找回密码的验证码 + - /portal/v1/wxuser/resetPwd #修改密码 + - /portal/v1/sysstaffinfo/searchAppContactsList #通讯录搜索 + - /base/v1/basevehiclebrand/selectAppListByManufacturerSid # 查询品牌 + + - /portal/file/upload #上传文件 + - /crm/v1/crmcustomer/getsCard #证件扫描 + - /crm/v1/crmcustomertemp/getCustomerTempListByUserSid #获取客户列表 + - /base/v1/baseaffiliatcompanyappendix/uploadImage #挂靠公司附件上传 + - /base/v1/basedistributorappendix/upload #经销商备案资料 + - /base/v1/basefinbank/listPage #查询资方 + + # 数据字典 + - /portal/v1/dictcommons/typeValues # 获取下拉框 + # 手机批量上传 + - /base/file/batchUploadImage + - /portal/file/batchUploadImage + - /terminal/autoservice/v1/getVins/{modelSid}/{configSid} #获取车架号 + # 手机端根据使用orgSid查询生产厂商列表 + - /base/v1/basemanufacturer/selectAppListByOrgSid + # 查询中介单位 + - /base/v1/basedistributor/getAppDistributorList + # 查询挂靠单位 + - /base/v1/baseaffiliatcompany/getAppAffiliatList + + # 省市县 + - /portal/v1/regions/getProvince + - /portal/v1/regions/getCity + - /portal/v1/regions/getCounty + - /portal/v1/wxuser/test + - /portal/v1/appuser/updateAppId #解绑用户的appId + + + whitesTwo: #包含所有 + ###swagger相关开始 + - /doc.html + - /webjars/** + - /swagger-resources + - /v2/** + - /favicon.ico + - /upload/** + ###swagger相关结束 + diff --git a/demo-system/demo-system-api/pom.xml b/demo-system/demo-system-api/pom.xml new file mode 100644 index 0000000..4ed286c --- /dev/null +++ b/demo-system/demo-system-api/pom.xml @@ -0,0 +1,32 @@ + + + + + + com.yxt.demo + demo-system + 0.0.1 + + 4.0.0 + + demo-system-api + 0.0.1 + + + + + + org.springframework.cloud + spring-cloud-starter-openfeign + + + com.yxt.di + di-common-core + 0.0.1 + + + + + \ No newline at end of file diff --git a/demo-system/demo-system-api/src/main/java/com/yxt/demo/system/config/DictCommonType.java b/demo-system/demo-system-api/src/main/java/com/yxt/demo/system/config/DictCommonType.java new file mode 100644 index 0000000..611a5f0 --- /dev/null +++ b/demo-system/demo-system-api/src/main/java/com/yxt/demo/system/config/DictCommonType.java @@ -0,0 +1,267 @@ +package com.yxt.anrui.portal.config; + +import io.swagger.annotations.ApiModelProperty; + +/** + * @author dimengzhe + * @date 2021/7/1 10:23 + * @description 常量值管理 + */ +public class DictCommonType { + + //客户端获取手机验证码redis前缀定义 + public static final String WX_REGIST = "wx-regist-";//注册获取验证码 + public static final String WX_LOGIN = "wx-login-";//登录获取验证码 + public static final String WX_FORGET = "wx-forget-";//忘记密码获取验证码 + public static final String WX_UPDATE = "wx-update-";//忘记密码获取验证码 + public static final String WX_NEW = "wx-new-";//新手机号获取验证码 + + /*供应厂商相关*/ + @ApiModelProperty(value = "供应商分类") + public static final String SUPPLIER_TYPE = "supplierType";//数据字典已添加 + @ApiModelProperty(value = "供应类别") + public static final String SUPPLY_TYPE = "supplyType";//数据字典已添加 + @ApiModelProperty(value = "供应商分组") + public static final String SUPPLIE_RGROUP = "supplierGroup";//数据字典已添加 + + /*供应厂商财务信息相关*/ + @ApiModelProperty(value = "结算币种") + public static final String SETTLEMENT_CURRENCY = "settlementCurrency";//数据字典已添加 + @ApiModelProperty(value = "结算方式") + public static final String SETTLEMENT_WAY = "settlementWay";//数据字典已添加 + @ApiModelProperty(value = "税分类") + public static final String TAX_CLASSIFICATION = "taxClassification";//数据字典已添加 + /*基础信息品牌相关*/ + @ApiModelProperty(value = "品牌类型") + public static final String BRAND_TYPE = "brandType";//数据字典已添加 + @ApiModelProperty(value = "职级(岗位)") + public static final String POSTLEVEL = "postLevel"; + + /*车型、车型配置、车辆信息相关*/ + @ApiModelProperty(value = "车辆类型") + public static final String VEHICLE_TYPE = "vehicleType";//数据字典已添加 + @ApiModelProperty(value = "排放标准") + public static final String EMISSION_STANDARD = "emissionStandard";//数据字典已添加 + @ApiModelProperty(value = "产品线") + public static final String PRODUCT_LINE = "productLine";//数据字典已添加 + @ApiModelProperty(value = "后桥") + public static final String REAR_AXLE = "rearAxle";//数据字典已添加 + @ApiModelProperty(value = "速比") + public static final String SPEED_RATIO = "speedRatio";//数据字典已添加 + @ApiModelProperty(value = "系别") + private static final String SERIES = "series";//数据字典已添加 + @ApiModelProperty(value = "车辆功能") + private static final String VEHICLE_FUNCTION = "vehicleFunction";//数据字典已添加 + @ApiModelProperty(value = "细分市场") + private static final String MARKETSEGMENTS = "marketSegments";//数据字典已添加 + + @ApiModelProperty(value = "车身颜色") + public static final String BODYCOLOR = "bodyColor"; + @ApiModelProperty(value = "缓速器") + public static final String SLOWMACHINE = "slowMachine"; + @ApiModelProperty(value = "后视镜") + public static final String REARVIEWMIRROR = "rearViewMirror"; + @ApiModelProperty(value = "轮胎") + public static final String TIRESIZE = "tireSize"; + @ApiModelProperty(value = "驾驶室") + public static final String SPECIFICATION = "specification"; + @ApiModelProperty(value = "后桥速比") + public static final String REARAXLERATIO = "rearAxleRatio"; + @ApiModelProperty(value = "轮毂材质") + public static final String HUBMATERIAL = "hubMaterial"; + @ApiModelProperty(value = "悬架") + public static final String SUSPENSION = "suspension"; + @ApiModelProperty(value = "座椅") + public static final String SEAT = "seat"; + @ApiModelProperty(value = "鞍座") + public static final String SADDLE = "saddle"; + @ApiModelProperty(value = "轴距") + public static final String WHEELBASE = "wheelbase"; + @ApiModelProperty(value = "保险杠") + public static final String BUMPER = "bumper"; + @ApiModelProperty(value = "配置包") + public static final String CONFIGURINGBAO = "configuringBao"; + @ApiModelProperty(value = "独立热源") + public static final String INDEPENDENTSOURCES = "independentSources"; + @ApiModelProperty(value = "燃料箱") + public static final String FUELTANK = "fuelTank"; + @ApiModelProperty(value = "有无:1有0无") + public static final String WHETHER = "whether"; + + @ApiModelProperty(value = "车辆状态") + public static final String VEHICLE_STATE = "vehicleState"; + @ApiModelProperty(value = "车辆状态(车辆台账)") + public static final String VEHICLE_LEDGER_STATE = "vehicleLedgerState"; + @ApiModelProperty(value = "驱动") + public static final String DRIVER = "driver"; + @ApiModelProperty(value = "马力") + public static final String HORSEPOWER = "horsepower"; + @ApiModelProperty(value = "锁定状态") + public static final String LOCKED_STATE = "lockedState"; + @ApiModelProperty(value = "预计订金日期") + public static final String RESERVE_DEPOSIT_DATE = "reserveDepositDate"; + + + @ApiModelProperty(value = "贷款主体类型") + public static final String LOANTYPE = "loanType"; + @ApiModelProperty(value = "打包项目") + public static final String PACKAGINGPROJECT = "packagingProject"; + @ApiModelProperty(value = "融资项目(比打包项目多一个“配件”)") + public static final String PACKAGINGPROJECTFIN = "packagingProjectFin"; + @ApiModelProperty(value = "变速箱") + public static final String GEARBOX = "gearbox"; + @ApiModelProperty(value = "燃料种类") + public static final String FUELTYPE = "fuelType"; + @ApiModelProperty(value = "版本(车辆需求)") + public static final String VEHICLEVERSION = "vehicleVersion"; + @ApiModelProperty(value = "采购形式") + public static final String PURCHASINGFORM = "purchasingForm"; + /*经销商相关*/ + @ApiModelProperty(value = "经销商分类") + public static final String DISTRIBUTOR_CLASSIFICATION = "distributorClassification";//数据字典已添加 + @ApiModelProperty(value = "经销商类型") + public static final String DISTRIBUTOR_TYPE = "distributorType";//数据字典已添加 + @ApiModelProperty(value = "经销商等级") + public static final String DISTRIBUTOR_LEVEL = "distributorLevel";//数据字典已添加 + @ApiModelProperty(value = "企业性质") + public static final String ENTERPRISE_NATURE = "enterpriseNature";//数据字典已添加 + @ApiModelProperty(value = "登记状态") + public static final String REGIST_STATE = "registState"; + @ApiModelProperty(value = "注册资本单位") + public static final String REGISTEREDCAPITAL_ORG = "registeredCapitalOrg"; + @ApiModelProperty(value = "项目类型") + public static final String PROJECT_TYPE = "projectType"; + /*经销商相关结束*/ + + + @ApiModelProperty(value = "合格证情况:0001虚拟 ,002正式") + public static final String CERTIFICATE_SITUATION = "certificateSituation"; + @ApiModelProperty(value = "客户类型:1个人2企业") + public static final String CUSTOMER_TYPE = "customerType"; + @ApiModelProperty(value = "登记注册号类型") + public static final String REGIST_NUM_TYPE = "registNumType"; + @ApiModelProperty(value = "现居住状况") + public static final String CURRENT_LIVE_STATE = "currentlivestate"; + @ApiModelProperty(value = "教育程度") + public static final String EDUCATION_DEGREE = "educationdegree"; + @ApiModelProperty(value = "雇员类型") + public static final String EMPLOYEE_TYPE = "employeetype"; + @ApiModelProperty(value = "证件类型") + public static final String DOCUMENT_TYPE = "documenttype"; + @ApiModelProperty(value = "行业类别") + public static final String INDUSTRY_TYPE = "industrytype"; + @ApiModelProperty(value = "经济类型") + public static final String ECONOMIC_TYPE = "economictype"; + @ApiModelProperty(value = "组织机构类别") + public static final String ORGANIZATION_TYPE = "organizationtype"; + @ApiModelProperty(value = "组织机构类别细分") + public static final String ORGANIZATION_TYPE_DETAILS = "organizationtypedetails"; + + @ApiModelProperty(value = "是或否") + public static final String IS_TRUE = "isTrue"; + @ApiModelProperty(value = "准驾车型") + public static final String CAR_TYPE = "carType"; + + @ApiModelProperty(value = "与客户关系") + public static final String RELATION_SHIP = "relationship"; + @ApiModelProperty(value = "现工作单位性质") + public static final String ORG_NATURE = "orgNature"; + @ApiModelProperty(value = "主要收入来源") + public static final String INCOME_SOURCE = "incomeSource"; + @ApiModelProperty(value = "职位") + public static final String POSITION = "position"; + @ApiModelProperty(value = "经销商类型") + public static final String DEALERS_TYPE = "dealersType"; + @ApiModelProperty(value = "附件类型") + public static final String ATTACH_TYPE = "attachType"; + @ApiModelProperty(value = "信用记录") + public static final String CREDIT_RECORD = "creditRecord"; + @ApiModelProperty(value = "拟租赁形式l") + public static final String PLANS_TO_LEASE = "plansToLease"; + @ApiModelProperty(value = "去返程货物") + public static final String GO_GOODS = "goGoods"; + @ApiModelProperty(value = "经营业务范围") + public static final String BUSINESSSCOPE = "businessScope"; + /* 客户信息相关*/ + @ApiModelProperty(value = "客户分类") + public static final String CUSTOMER_CLASS = "customerClass"; + @ApiModelProperty(value = "客户来源") + public static final String CUSTOMER_SOURCE = "customerSource"; + @ApiModelProperty(value = "客户等级") + public static final String CUSTOMER_LEVEL = "customerLevel"; + @ApiModelProperty(value = "来访方式") + public static final String VISIT_WAY = "visitWay"; + @ApiModelProperty(value = "跟进状态") + public static final String FOLLOW_STATE = "followState"; + @ApiModelProperty(value = "提醒日期(天)") + public static final String REMIND_DAY = "remindDay"; + @ApiModelProperty(value = "承运货物类型") + public static final String CONSIGNMENT_TYPE = "consignmentType"; + @ApiModelProperty(value = "承运货物(暂为假数据)") + public static final String CONSIGNMENT = "consignment"; + @ApiModelProperty(value = "购车方式") + public static final String PURCHASETYPE = "purchaseType"; + @ApiModelProperty(value = "提车方式") + public static final String SALETYPE = "saleType"; + /* 车辆订单 */ + @ApiModelProperty(value = "单据类型") + public static final String BILLSTYPE = "billsType"; + @ApiModelProperty(value = "合同类型") + public static final String CONTRACTTYPE = "contractType"; + + @ApiModelProperty(value = "主车优惠类型") + public static final String DISCOUNTTYPE = "discountType"; + @ApiModelProperty(value = "还款方式") + public static final String MODEOFREPAY = "modeOfRePay"; + @ApiModelProperty(value = "保证金方式") + public static final String BONDMETHOD = "bondMethod"; + @ApiModelProperty(value = "业务类型") + public static final String BUSINESSTYPE = "businessType"; + @ApiModelProperty(value = "开户银行") + public static final String BANK = "bank"; + @ApiModelProperty(value = "账户类型") + public static final String ACCOUNTTYPE = "accountType"; + @ApiModelProperty(value = "运输货物") + public static final String TRANSPORTCARGO = "transportCargo"; + @ApiModelProperty(value = "结账周期") + public static final String CHECKOUTCYCLE = "checkoutCycle"; + @ApiModelProperty(value = "虚拟订单类型") + public static final String DEPOSITBILLTYPE = "depositBillType"; + @ApiModelProperty(value = "付款方式") + public static final String PAYMENTTYPE = "paymentType"; + + /* 物料相关 */ + @ApiModelProperty(value = "物料分组") + public static final String MATERIAL_GROUP = "materialGroup"; + @ApiModelProperty(value = "物料属性") + public static final String MATERIAL_PROPERTIES = "materialProperties"; + @ApiModelProperty(value = "存货类别") + public static final String STOCK_TYPE = "stockType"; + @ApiModelProperty(value = "基本单位") + public static final String BASIC_UNIT = "basicUnit"; + + /* 合同相关 */ + @ApiModelProperty(value = "人员类型") + public static final String PERSONNEL_TYPE = "personnelType"; + + /* 开票申请单相关 */ + @ApiModelProperty(value = "开票性质") + public static final String INVOICING_NATURE = "invoicingNature"; + + /*员工信息管理相关*/ + @ApiModelProperty(value = "婚姻状况") + public static final String MARITAL_STATUS = "maritalstatus"; + @ApiModelProperty(value = "民族") + public static final String NATIONAL = "national"; + @ApiModelProperty(value = "性别") + public static final String SEX = "sex"; + @ApiModelProperty(value = "政治面貌") + public static final String POLITICAL = "political"; + + + /*资料清单相关*/ + @ApiModelProperty(value = "资料类别") + public static final String DATA_TYPE = "dataType"; + @ApiModelProperty(value = "文件格式") + public static final String FILE_TYPE = "fileType"; +} diff --git a/demo-system/demo-system-biz/pom.xml b/demo-system/demo-system-biz/pom.xml new file mode 100644 index 0000000..ba7bc9f --- /dev/null +++ b/demo-system/demo-system-biz/pom.xml @@ -0,0 +1,84 @@ + + + + + com.yxt.demo + demo-system + 0.0.1 + + 4.0.0 + + demo-system-biz + 0.0.1 + + + + demo-system-api + com.yxt.demo + 0.0.1 + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-discovery + + + com.yxt.demo + demo-common-config + 0.0.1 + + + com.yxt.demo + demo-common-base + 0.0.1 + + + com.yxt.demo + demo-common-redis + 0.0.1 + + + com.yxt.demo + demo-common-jdbc + 0.0.1 + + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + 2.5.6 + + + + repackage + + + + + + + + src/main/java + + **/*Mapper.xml + + + + src/main/resources + + **/*.* + + false + + + + + + + \ No newline at end of file diff --git a/demo-system/demo-system-biz/src/main/java/com/yxt/demo/system/SystemApplication.java b/demo-system/demo-system-biz/src/main/java/com/yxt/demo/system/SystemApplication.java new file mode 100644 index 0000000..7c6a2e1 --- /dev/null +++ b/demo-system/demo-system-biz/src/main/java/com/yxt/demo/system/SystemApplication.java @@ -0,0 +1,23 @@ +package com.yxt.anrui.portal; + + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.client.discovery.EnableDiscoveryClient; +import org.springframework.cloud.openfeign.EnableFeignClients; + +/** + * @author dimengzhe + */ +@SpringBootApplication(scanBasePackages = { + "com.yxt.common.base.config", + "com.yxt.demo.system" +}) +@EnableDiscoveryClient +@EnableFeignClients(basePackages = {}) +public class SystemApplication { + + public static void main(String[] args) { + SpringApplication.run(SystemApplication.class, args); + } +} diff --git a/demo-system/demo-system-biz/src/main/java/com/yxt/demo/system/config/Swagger2Config.java b/demo-system/demo-system-biz/src/main/java/com/yxt/demo/system/config/Swagger2Config.java new file mode 100644 index 0000000..c6975fa --- /dev/null +++ b/demo-system/demo-system-biz/src/main/java/com/yxt/demo/system/config/Swagger2Config.java @@ -0,0 +1,35 @@ +package com.yxt.demo.system.config; + +import com.github.xiaoymin.knife4j.spring.annotations.EnableKnife4j; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import springfox.documentation.builders.ApiInfoBuilder; +import springfox.documentation.builders.PathSelectors; +import springfox.documentation.builders.RequestHandlerSelectors; +import springfox.documentation.service.ApiInfo; +import springfox.documentation.spi.DocumentationType; +import springfox.documentation.spring.web.plugins.Docket; +import springfox.documentation.swagger2.annotations.EnableSwagger2; + +/** + * @author dimengzhe + * @date 2020/9/9 16:42 + * @description + */ +@Configuration +@EnableSwagger2 +@EnableKnife4j +public class Swagger2Config { + @Bean + public Docket createRestApi() { + return new Docket(DocumentationType.SWAGGER_2) + .apiInfo(apiInfo()).select() + .apis(RequestHandlerSelectors.basePackage("com.yxt.demo.system")) + .paths(PathSelectors.any()).build(); + } + + private ApiInfo apiInfo() { + return new ApiInfoBuilder().title("demo/系统管理").description("系统管理接口").version("1.0") + .build(); + } +} diff --git a/demo-system/demo-system-biz/src/main/resources/application-dev.yml b/demo-system/demo-system-biz/src/main/resources/application-dev.yml new file mode 100644 index 0000000..f3b9a65 --- /dev/null +++ b/demo-system/demo-system-biz/src/main/resources/application-dev.yml @@ -0,0 +1,36 @@ +spring: + datasource: + hikari: + max-lifetime: 30000 + driver-class-name: com.mysql.cj.jdbc.Driver + url: jdbc:mysql://127.0.0.1:3306/demo_system?serverTimezone=GMT%2B8&autoReconnect=true&useUnicode=true&characterEncoding=UTF-8&nullCatalogMeansCurrent=true + username: root + password: root + cloud: + nacos: + discovery: + server-addr: 127.0.0.1:8848 + redis: + database: 3 # Redis数据库索引(默认为0) + host: 127.0.0.1 + jedis: + pool: + max-active: -1 #连接池最大连接数(使用负值表示没有限制) + max-idle: 8 #连接池中的最大空闲连接 + max-wait: -1 # 连接池最大阻塞等待时间(使用负值表示没有限制) + min-idle: 0 # 连接池中的最小空闲连接 + password: 123456 + port: 6379 + timeout: 0 # 连接超时时间(毫秒) + +image: + upload: + path: D:\\demo\\upload\\ + url: + prefix: http://127.0.0.1:8111/upload/ + login: + path: D:\\images\\pic-click + + + + diff --git a/demo-system/demo-system-biz/src/main/resources/application-pro.yml b/demo-system/demo-system-biz/src/main/resources/application-pro.yml new file mode 100644 index 0000000..0ee0497 --- /dev/null +++ b/demo-system/demo-system-biz/src/main/resources/application-pro.yml @@ -0,0 +1,30 @@ +spring: + datasource: + driver-class-name: com.mysql.cj.jdbc.Driver + url: jdbc:mysql://127.0.0.1:3306/demo_system?serverTimezone=GMT%2B8&autoReconnect=true&useUnicode=true&characterEncoding=UTF-8 + username: root + password: root + cloud: + nacos: + discovery: + server-addr: 127.0.0.1:8848 + redis: + database: 3 # Redis数据库索引(默认为0) + host: 127.0.0.1 + jedis: + pool: + max-active: -1 #连接池最大连接数(使用负值表示没有限制) + max-idle: 8 #连接池中的最大空闲连接 + max-wait: -1 # 连接池最大阻塞等待时间(使用负值表示没有限制) + min-idle: 0 # 连接池中的最小空闲连接 + password: 123456 + port: 6379 + timeout: 0 # 连接超时时间(毫秒) + +image: + upload: + path: D:\demo\upload\ + url: + prefix: http://127.0.0.1:8111/upload/ + login: + path: D:\images\pic-click diff --git a/demo-system/demo-system-biz/src/main/resources/application-test.yml b/demo-system/demo-system-biz/src/main/resources/application-test.yml new file mode 100644 index 0000000..f360383 --- /dev/null +++ b/demo-system/demo-system-biz/src/main/resources/application-test.yml @@ -0,0 +1,31 @@ +spring: + datasource: + driver-class-name: com.mysql.cj.jdbc.Driver + url: jdbc:mysql://127.0.0.1:3306/demo_system?serverTimezone=GMT%2B8&autoReconnect=true&useUnicode=true&characterEncoding=UTF-8&nullCatalogMeansCurrent=true + username: root + password: root + cloud: + nacos: + discovery: + server-addr: 127.0.0.1:8848 + redis: + database: 3 # Redis数据库索引(默认为0) + host: 127.0.0.1 + jedis: + pool: + max-active: -1 #连接池最大连接数(使用负值表示没有限制) + max-idle: 8 #连接池中的最大空闲连接 + max-wait: -1 # 连接池最大阻塞等待时间(使用负值表示没有限制) + min-idle: 0 # 连接池中的最小空闲连接 + password: + port: 6379 + timeout: 0 # 连接超时时间(毫秒) + +image: + upload: + path: D:\demo\upload\ + url: + prefix: http://127.0.0.1:8111/upload/ + login: + path: D:\images\pic-click + diff --git a/demo-system/demo-system-biz/src/main/resources/application.yml b/demo-system/demo-system-biz/src/main/resources/application.yml new file mode 100644 index 0000000..dc9cd1c --- /dev/null +++ b/demo-system/demo-system-biz/src/main/resources/application.yml @@ -0,0 +1,62 @@ +spring: + application: + name: demo-system + profiles: + active: devv + messages: + # 国际化资源文件路径 + basename: i18n/messages + servlet: + #上传文件 + multipart: + max-file-size: 50MB + max-request-size: 100MB + devtools: + restart: + # 热部署开关 + enabled: true + mvc: + async: + request-timeout: 20000 + + + +server: + port: 7003 + max-http-header-size: 102400 + tomcat: + max-http-form-post-size: -1 +#mybatis +mybatis-plus: + # 配置mapper的扫描,找到所有的mapper.xml映射文件 + mapper-locations: classpath*:**Mapper.xml + global-config: + refresh: true + db-config: + #定义生成ID的类型 + id-type: Auto + db-type: mysql + configuration: + map-underscore-to-camel-case: false + cache-enabled: true + call-setters-on-nulls: true + log-impl: org.apache.ibatis.logging.stdout.StdOutImpl + +#hystrix的超时时间 +hystrix: + command: + default: + execution: + timeout: + enabled: true + isolation: + thread: + timeoutInMilliseconds: 30000 +#ribbon的超时时间 +ribbon: + ReadTimeout: 30000 + ConnectTimeout: 30000 + + + + diff --git a/demo-system/demo-system-biz/src/main/resources/banner.txt b/demo-system/demo-system-biz/src/main/resources/banner.txt new file mode 100644 index 0000000..98e44c5 --- /dev/null +++ b/demo-system/demo-system-biz/src/main/resources/banner.txt @@ -0,0 +1,13 @@ + ,----.. ____ + / / \ ,' , `. +| : : ,---. ,-+-,.' _ | ,---. ,---, +. | ;. / ' ,'\ ,-+-. ; , || ' ,'\ ,-+-. / | +. ; /--` / / | ,--.'|' | || ,---. / / | ,--.'|' | +; | ; . ; ,. :| | ,', | |,/ \ . ; ,. :| | ,"' | +| : | ' | |: :| | / | |--'/ / | ' | |: :| | / | | +. | '___' | .; :| : | | , . ' / | ' | .; :| | | | | +' ; : .'| : || : | |/ ' ; /| | : || | | |/ +' | '/ :\ \ / | | |`-' ' | / | \ \ / | | |--' +| : / `----' | ;/ | : | `----' | |/ + \ \ .' '---' \ \ / '---' + `---` `----' diff --git a/demo-system/demo-system-biz/src/main/resources/images/jigsaw/original/bg1.png b/demo-system/demo-system-biz/src/main/resources/images/jigsaw/original/bg1.png new file mode 100644 index 0000000..85b5782 Binary files /dev/null and b/demo-system/demo-system-biz/src/main/resources/images/jigsaw/original/bg1.png differ diff --git a/demo-system/demo-system-biz/src/main/resources/images/jigsaw/original/bg10.png b/demo-system/demo-system-biz/src/main/resources/images/jigsaw/original/bg10.png new file mode 100644 index 0000000..3d558a7 Binary files /dev/null and b/demo-system/demo-system-biz/src/main/resources/images/jigsaw/original/bg10.png differ diff --git a/demo-system/demo-system-biz/src/main/resources/images/jigsaw/original/bg11.png b/demo-system/demo-system-biz/src/main/resources/images/jigsaw/original/bg11.png new file mode 100644 index 0000000..4d8d7af Binary files /dev/null and b/demo-system/demo-system-biz/src/main/resources/images/jigsaw/original/bg11.png differ diff --git a/demo-system/demo-system-biz/src/main/resources/images/jigsaw/original/bg12.png b/demo-system/demo-system-biz/src/main/resources/images/jigsaw/original/bg12.png new file mode 100644 index 0000000..e6330aa Binary files /dev/null and b/demo-system/demo-system-biz/src/main/resources/images/jigsaw/original/bg12.png differ diff --git a/demo-system/demo-system-biz/src/main/resources/images/jigsaw/original/bg2.png b/demo-system/demo-system-biz/src/main/resources/images/jigsaw/original/bg2.png new file mode 100644 index 0000000..ebfa46e Binary files /dev/null and b/demo-system/demo-system-biz/src/main/resources/images/jigsaw/original/bg2.png differ diff --git a/demo-system/demo-system-biz/src/main/resources/images/jigsaw/original/bg3.png b/demo-system/demo-system-biz/src/main/resources/images/jigsaw/original/bg3.png new file mode 100644 index 0000000..ce14d03 Binary files /dev/null and b/demo-system/demo-system-biz/src/main/resources/images/jigsaw/original/bg3.png differ diff --git a/demo-system/demo-system-biz/src/main/resources/images/jigsaw/original/bg4.png b/demo-system/demo-system-biz/src/main/resources/images/jigsaw/original/bg4.png new file mode 100644 index 0000000..39e7d5a Binary files /dev/null and b/demo-system/demo-system-biz/src/main/resources/images/jigsaw/original/bg4.png differ diff --git a/demo-system/demo-system-biz/src/main/resources/images/jigsaw/original/bg5.png b/demo-system/demo-system-biz/src/main/resources/images/jigsaw/original/bg5.png new file mode 100644 index 0000000..7e1e30f Binary files /dev/null and b/demo-system/demo-system-biz/src/main/resources/images/jigsaw/original/bg5.png differ diff --git a/demo-system/demo-system-biz/src/main/resources/images/jigsaw/original/bg6.png b/demo-system/demo-system-biz/src/main/resources/images/jigsaw/original/bg6.png new file mode 100644 index 0000000..835a306 Binary files /dev/null and b/demo-system/demo-system-biz/src/main/resources/images/jigsaw/original/bg6.png differ diff --git a/demo-system/demo-system-biz/src/main/resources/images/jigsaw/original/bg7.png b/demo-system/demo-system-biz/src/main/resources/images/jigsaw/original/bg7.png new file mode 100644 index 0000000..6ffb808 Binary files /dev/null and b/demo-system/demo-system-biz/src/main/resources/images/jigsaw/original/bg7.png differ diff --git a/demo-system/demo-system-biz/src/main/resources/images/jigsaw/original/bg8.png b/demo-system/demo-system-biz/src/main/resources/images/jigsaw/original/bg8.png new file mode 100644 index 0000000..3ae8907 Binary files /dev/null and b/demo-system/demo-system-biz/src/main/resources/images/jigsaw/original/bg8.png differ diff --git a/demo-system/demo-system-biz/src/main/resources/images/jigsaw/original/bg9.png b/demo-system/demo-system-biz/src/main/resources/images/jigsaw/original/bg9.png new file mode 100644 index 0000000..83b9efb Binary files /dev/null and b/demo-system/demo-system-biz/src/main/resources/images/jigsaw/original/bg9.png differ diff --git a/demo-system/demo-system-biz/src/main/resources/images/jigsaw/slidingBlock/1.png b/demo-system/demo-system-biz/src/main/resources/images/jigsaw/slidingBlock/1.png new file mode 100644 index 0000000..1905026 Binary files /dev/null and b/demo-system/demo-system-biz/src/main/resources/images/jigsaw/slidingBlock/1.png differ diff --git a/demo-system/demo-system-biz/src/main/resources/images/jigsaw/slidingBlock/2.png b/demo-system/demo-system-biz/src/main/resources/images/jigsaw/slidingBlock/2.png new file mode 100644 index 0000000..b1482d4 Binary files /dev/null and b/demo-system/demo-system-biz/src/main/resources/images/jigsaw/slidingBlock/2.png differ diff --git a/demo-system/demo-system-biz/src/main/resources/images/jigsaw/slidingBlock/3.png b/demo-system/demo-system-biz/src/main/resources/images/jigsaw/slidingBlock/3.png new file mode 100644 index 0000000..cdbb0b1 Binary files /dev/null and b/demo-system/demo-system-biz/src/main/resources/images/jigsaw/slidingBlock/3.png differ diff --git a/demo-system/demo-system-biz/src/main/resources/images/jigsaw/slidingBlock/4.png b/demo-system/demo-system-biz/src/main/resources/images/jigsaw/slidingBlock/4.png new file mode 100644 index 0000000..bc69c96 Binary files /dev/null and b/demo-system/demo-system-biz/src/main/resources/images/jigsaw/slidingBlock/4.png differ diff --git a/demo-system/demo-system-biz/src/main/resources/images/pic-click/bg1.png b/demo-system/demo-system-biz/src/main/resources/images/pic-click/bg1.png new file mode 100644 index 0000000..85b5782 Binary files /dev/null and b/demo-system/demo-system-biz/src/main/resources/images/pic-click/bg1.png differ diff --git a/demo-system/demo-system-biz/src/main/resources/images/pic-click/bg10.png b/demo-system/demo-system-biz/src/main/resources/images/pic-click/bg10.png new file mode 100644 index 0000000..3d558a7 Binary files /dev/null and b/demo-system/demo-system-biz/src/main/resources/images/pic-click/bg10.png differ diff --git a/demo-system/demo-system-biz/src/main/resources/images/pic-click/bg11.png b/demo-system/demo-system-biz/src/main/resources/images/pic-click/bg11.png new file mode 100644 index 0000000..4d8d7af Binary files /dev/null and b/demo-system/demo-system-biz/src/main/resources/images/pic-click/bg11.png differ diff --git a/demo-system/demo-system-biz/src/main/resources/images/pic-click/bg12.png b/demo-system/demo-system-biz/src/main/resources/images/pic-click/bg12.png new file mode 100644 index 0000000..e6330aa Binary files /dev/null and b/demo-system/demo-system-biz/src/main/resources/images/pic-click/bg12.png differ diff --git a/demo-system/demo-system-biz/src/main/resources/images/pic-click/bg2.png b/demo-system/demo-system-biz/src/main/resources/images/pic-click/bg2.png new file mode 100644 index 0000000..ebfa46e Binary files /dev/null and b/demo-system/demo-system-biz/src/main/resources/images/pic-click/bg2.png differ diff --git a/demo-system/demo-system-biz/src/main/resources/images/pic-click/bg3.png b/demo-system/demo-system-biz/src/main/resources/images/pic-click/bg3.png new file mode 100644 index 0000000..ce14d03 Binary files /dev/null and b/demo-system/demo-system-biz/src/main/resources/images/pic-click/bg3.png differ diff --git a/demo-system/demo-system-biz/src/main/resources/images/pic-click/bg4.png b/demo-system/demo-system-biz/src/main/resources/images/pic-click/bg4.png new file mode 100644 index 0000000..39e7d5a Binary files /dev/null and b/demo-system/demo-system-biz/src/main/resources/images/pic-click/bg4.png differ diff --git a/demo-system/demo-system-biz/src/main/resources/images/pic-click/bg5.png b/demo-system/demo-system-biz/src/main/resources/images/pic-click/bg5.png new file mode 100644 index 0000000..7e1e30f Binary files /dev/null and b/demo-system/demo-system-biz/src/main/resources/images/pic-click/bg5.png differ diff --git a/demo-system/demo-system-biz/src/main/resources/images/pic-click/bg6.png b/demo-system/demo-system-biz/src/main/resources/images/pic-click/bg6.png new file mode 100644 index 0000000..835a306 Binary files /dev/null and b/demo-system/demo-system-biz/src/main/resources/images/pic-click/bg6.png differ diff --git a/demo-system/demo-system-biz/src/main/resources/images/pic-click/bg7.png b/demo-system/demo-system-biz/src/main/resources/images/pic-click/bg7.png new file mode 100644 index 0000000..6ffb808 Binary files /dev/null and b/demo-system/demo-system-biz/src/main/resources/images/pic-click/bg7.png differ diff --git a/demo-system/demo-system-biz/src/main/resources/images/pic-click/bg8.png b/demo-system/demo-system-biz/src/main/resources/images/pic-click/bg8.png new file mode 100644 index 0000000..3ae8907 Binary files /dev/null and b/demo-system/demo-system-biz/src/main/resources/images/pic-click/bg8.png differ diff --git a/demo-system/demo-system-biz/src/main/resources/images/pic-click/bg9.png b/demo-system/demo-system-biz/src/main/resources/images/pic-click/bg9.png new file mode 100644 index 0000000..83b9efb Binary files /dev/null and b/demo-system/demo-system-biz/src/main/resources/images/pic-click/bg9.png differ diff --git a/demo-system/demo-system-biz/src/main/resources/logback-spring.xml b/demo-system/demo-system-biz/src/main/resources/logback-spring.xml new file mode 100644 index 0000000..a3200c8 --- /dev/null +++ b/demo-system/demo-system-biz/src/main/resources/logback-spring.xml @@ -0,0 +1,50 @@ + + + + + + + + + + %yellow(%date{yyyy-MM-dd HH:mm:ss}) |%highlight(%-5level) |%green(%logger:%line) |%blue(%msg%n) + + + + + + + + + + + + + + + ${log.base}.log + + ${log.base}.%d{yyyyMMdd}.%i.log.zip + + + + 1MB + + + + + %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} + -%msg%n + + + + + + + + + + \ No newline at end of file diff --git a/demo-system/demo-system-biz/src/test/java/com/yxt/demo/system/test/TestOneController.java b/demo-system/demo-system-biz/src/test/java/com/yxt/demo/system/test/TestOneController.java new file mode 100644 index 0000000..09efd43 --- /dev/null +++ b/demo-system/demo-system-biz/src/test/java/com/yxt/demo/system/test/TestOneController.java @@ -0,0 +1,10 @@ +package com.yxt.demo.system.test; + +/** + * @author dimengzhe + * @date 2021/7/1 16:11 + * @description + */ + +public class TestOneController { +} diff --git a/demo-system/demo-system-biz/src/test/java/com/yxt/demo/system/test/controller/TestController.java b/demo-system/demo-system-biz/src/test/java/com/yxt/demo/system/test/controller/TestController.java new file mode 100644 index 0000000..2b5133c --- /dev/null +++ b/demo-system/demo-system-biz/src/test/java/com/yxt/demo/system/test/controller/TestController.java @@ -0,0 +1,40 @@ +package com.yxt.demo.system.test.controller; + +import cn.hutool.core.codec.Base64; +import com.yxt.demo.system.test.entity.TestDemo; +import lombok.Data; +import org.springframework.stereotype.Controller; +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.ResponseBody; + +import javax.crypto.Mac; +import javax.crypto.spec.SecretKeySpec; +import java.io.BufferedReader; +import java.io.DataOutputStream; +import java.io.InputStreamReader; +import java.io.UnsupportedEncodingException; +import java.net.HttpURLConnection; +import java.net.URL; +import java.net.URLEncoder; +import java.security.InvalidKeyException; +import java.security.Key; +import java.security.NoSuchAlgorithmException; +import java.text.SimpleDateFormat; +import java.util.*; + +/** + * @author dimengzhe + * @date 2021/7/1 13:49 + * @description 测试OCR扫描 + */ +@Controller +@RequestMapping("/test") +public class TestController { + + + +} + + diff --git a/demo-system/demo-system-biz/src/test/java/com/yxt/demo/system/test/entity/TestDemo.java b/demo-system/demo-system-biz/src/test/java/com/yxt/demo/system/test/entity/TestDemo.java new file mode 100644 index 0000000..4fafbfd --- /dev/null +++ b/demo-system/demo-system-biz/src/test/java/com/yxt/demo/system/test/entity/TestDemo.java @@ -0,0 +1,21 @@ +package com.yxt.demo.system.test.entity; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * @author dimengzhe + * @date 2021/10/19 16:03 + * @description + */ +@Data +public class TestDemo { + + @ApiModelProperty(value = "身份证号") + private String idcard; + @ApiModelProperty(value = "手机号码") + private String mobile; + + @ApiModelProperty(value = "姓名") + private String name; +} diff --git a/demo-system/pom.xml b/demo-system/pom.xml new file mode 100644 index 0000000..2264197 --- /dev/null +++ b/demo-system/pom.xml @@ -0,0 +1,35 @@ + + + + + 4.0.0 + demo-system + + demo-system-api + demo-system-biz + + com.yxt.demo + 0.0.1 + + pom + 系统管理 + + + com.yxt + demo + 0.0.1 + + + + + org.projectlombok + lombok + + + + + + + \ No newline at end of file diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..626d6bf --- /dev/null +++ b/pom.xml @@ -0,0 +1,199 @@ + + + 4.0.0 + + com.yxt + demo + 0.0.1 + + demo-gateway + demo-system + demo-common + + pom + 测试 + + + 8 + + UTF-8 + + UTF-8 + 8 + 8 + + + + 2.2.9.RELEASE + + Hoxton.SR6 + + 2.2.1.RELEASE + + 1.3.0 + 2.2.9.RELEASE + 3.1.0 + 2.0.5 + + 0.9.1 + + 1.2.73 + + 1.9.3 + + 5.4.0 + 3.4.0 + 1.4.2 + + + + + + + + + + org.springframework.cloud + spring-cloud-dependencies + ${spring-cloud.version} + pom + import + + + + com.alibaba.cloud + spring-cloud-alibaba-dependencies + ${spring-cloud-alibaba.version} + pom + import + + + + com.alibaba.nacos + nacos-client + ${nacos.version} + + + + org.springframework.boot + spring-boot-dependencies + ${spring-boot.version} + pom + import + + + + + org.springframework.boot + spring-boot-starter-data-redis + ${redis.version} + + + io.lettuce + lettuce-core + + + + + + redis.clients + jedis + ${jedis.version} + + + + + com.github.xiaoymin + knife4j-dependencies + ${knife4j-Swagger} + pom + import + + + + + io.jsonwebtoken + jjwt + ${jjwt.version} + + + + com.alibaba + fastjson + ${fastjson.version} + + + + commons-beanutils + commons-beanutils + ${commons.beanutils.version} + + + + cn.hutool + hutool-all + ${hutool.version} + + + + cn.hutool + hutool-core + ${hutool.version} + + + com.baomidou + mybatis-plus-boot-starter + ${mybatis-plus.version} + + + com.baomidou + mybatis-plus-annotation + ${mybatis-plus.version} + + + io.seata + seata-spring-boot-starter + + ${seata.version} + + + + + + + aliyun-central + https://maven.aliyun.com/repository/central + + + aliyun-public + https://maven.aliyun.com/repository/public + + + aliyun-google + https://maven.aliyun.com/repository/google + + + aliyun-spring + https://maven.aliyun.com/repository/spring + + + + + aliyun-central + https://maven.aliyun.com/repository/central + + + aliyun-public + https://maven.aliyun.com/repository/public + + + aliyun-google + https://maven.aliyun.com/repository/google + + + aliyun-spring + https://maven.aliyun.com/repository/spring + + +