This commit is contained in:
Jane
2023-12-22 10:59:10 +08:00
parent 751c43e199
commit d1ede2d4aa
2774 changed files with 291509 additions and 0 deletions

View File

@@ -0,0 +1,115 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>common</artifactId>
<groupId>com.platform</groupId>
<version>0.4.x</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<version>0.4.x</version>
<artifactId>common-core</artifactId>
<dependencies>
<!-- SpringWeb模块 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<scope>provided</scope>
</dependency>
<!--io常用工具类 -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>${commons.io.version}</version>
</dependency>
<!--文件上传工具类 -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>${commons.fileupload.version}</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
</dependency>
<dependency>
<groupId>commons-beanutils</groupId>
<artifactId>commons-beanutils</artifactId>
<version>${commons.beanutils.version}</version>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>${hutool.version}</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>${fastjson.version}</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-extension</artifactId>
<version>${mybatis-plus.version}</version>
</dependency>
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
</dependency>
<!--jackson模块-->
<dependency>
<groupId>com.fasterxml.jackson.module</groupId>
<artifactId>jackson-module-parameter-names</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jdk8</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-core</artifactId>
</dependency>
<!-- jwt -->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-api</artifactId>
<version>${jjwt.version}</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-impl</artifactId>
<version>${jjwt.version}</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-jackson</artifactId>
<version>${jjwt.version}</version>
</dependency>
<dependency>
<groupId>com.platform</groupId>
<artifactId>common-service-api</artifactId>
<version>0.4.x</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.platform</groupId>
<artifactId>common-log</artifactId>
<version>0.4.x</version>
<scope>compile</scope>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,5 @@
package cn.datax.common.base;
public abstract class BaseController {
}

View File

@@ -0,0 +1,15 @@
package cn.datax.common.base;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.apache.ibatis.annotations.Param;
import java.util.List;
public interface BaseDao<T> extends BaseMapper<T> {
List<T> selectListDataScope(@Param("ew") Wrapper<T> queryWrapper, @Param("dataScope") DataScope dataScope);
IPage<T> selectPageDataScope(IPage<T> page, @Param("ew") Wrapper<T> queryWrapper, @Param("dataScope") DataScope dataScope);
}

View File

@@ -0,0 +1,7 @@
package cn.datax.common.base;
import com.baomidou.mybatisplus.extension.service.IService;
public interface BaseService<T> extends IService<T> {
}

View File

@@ -0,0 +1,10 @@
package cn.datax.common.base;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
public abstract class BaseServiceImpl<M extends BaseDao<T>, T> extends ServiceImpl<M, T> implements BaseService<T> {
@Autowired
protected M baseDao;
}

View File

@@ -0,0 +1,25 @@
package cn.datax.common.base;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import lombok.Data;
import lombok.EqualsAndHashCode;
@Data
@EqualsAndHashCode(callSuper = true)
public abstract class DataFlowBaseEntity extends DataScopeBaseEntity {
private static final long serialVersionUID = 1L;
/**
* 工作流状态1待提交2已退回3审核中4通过5不通过6已撤销
*/
@TableField(value = "flow_status", fill = FieldFill.INSERT)
private String flowStatus;
/**
* 流程实例ID
*/
@TableField(value = "process_instance_id")
private String processInstanceId;
}

View File

@@ -0,0 +1,24 @@
package cn.datax.common.base;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* 数据权限查询参数
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class DataScope {
/**
* 表的部门字段
*/
private String deptScopeName = "create_dept";
/**
* 表的用户字段
*/
private String userScopeName = "create_by";
}

View File

@@ -0,0 +1,19 @@
package cn.datax.common.base;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import lombok.Data;
import lombok.EqualsAndHashCode;
@Data
@EqualsAndHashCode(callSuper = true)
public abstract class DataScopeBaseEntity extends BaseEntity {
private static final long serialVersionUID = 1L;
/**
* 创建人所属部门
*/
@TableField(value = "create_dept", fill = FieldFill.INSERT)
private String createDept;
}

View File

@@ -0,0 +1,75 @@
package cn.datax.common.config;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;
import com.fasterxml.jackson.module.paramnames.ParameterNamesModule;
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;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.TimeZone;
@Configuration
public class JacksonConfig {
@Bean
@Primary
@ConditionalOnMissingBean(ObjectMapper.class)
public ObjectMapper jacksonObjectMapper(Jackson2ObjectMapperBuilder builder){
builder.simpleDateFormat("yyyy-MM-dd HH:mm:ss");
ObjectMapper objectMapper = builder.createXmlMapper(false)
.featuresToDisable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
.featuresToDisable(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE)
.timeZone(TimeZone.getTimeZone("Asia/Shanghai"))
.build();
// null数据不返回
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
// 反序列化时候遇到不匹配的属性并不抛出异常
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
// 序列化时候遇到空对象不抛出异常
objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
// 反序列化的时候如果是无效子类型,不抛出异常
objectMapper.configure(DeserializationFeature.FAIL_ON_INVALID_SUBTYPE, false);
// 不使用默认的dateTime进行序列化,
objectMapper.configure(SerializationFeature.WRITE_DATE_KEYS_AS_TIMESTAMPS, false);
// 数据精度问题
SimpleModule simpleModule = new SimpleModule()
.addSerializer(Long.class, ToStringSerializer.instance)
.addSerializer(Long.TYPE, ToStringSerializer.instance)
.addSerializer(BigInteger.class, ToStringSerializer.instance)
.addSerializer(BigDecimal.class, ToStringSerializer.instance);
objectMapper.registerModule(simpleModule);
JavaTimeModule javaTimeModule = new JavaTimeModule();
javaTimeModule.addSerializer(LocalDateTime.class,new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
javaTimeModule.addSerializer(LocalDate.class,new LocalDateSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
javaTimeModule.addSerializer(LocalTime.class,new LocalTimeSerializer(DateTimeFormatter.ofPattern("HH:mm:ss")));
javaTimeModule.addDeserializer(LocalDateTime.class,new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
javaTimeModule.addDeserializer(LocalDate.class,new LocalDateDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
javaTimeModule.addDeserializer(LocalTime.class,new LocalTimeDeserializer(DateTimeFormatter.ofPattern("HH:mm:ss")));
objectMapper.registerModule(javaTimeModule).registerModule(new ParameterNamesModule());
return objectMapper;
}
}

View File

@@ -0,0 +1,24 @@
package cn.datax.common.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;
@Configuration
public class RestTemplateConfig {
@Bean
public RestTemplate restTemplate(ClientHttpRequestFactory factory){
return new RestTemplate(factory);
}
@Bean
public ClientHttpRequestFactory simpleClientHttpRequestFactory(){
SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
factory.setReadTimeout(5000);
factory.setConnectTimeout(5000);
return factory;
}
}

View File

@@ -0,0 +1,211 @@
package cn.datax.common.core;
public class DataConstant {
/**
* Oauth2安全相关常量
*/
public enum Security {
//请求头TOKEN名称
TOKENHEADER("gatewayToken"),
//请求头TOKEN值
TOKENVALUE("datax:gateway:123456"),
//OAUTH2请求头
AUTHORIZATION("Authorization"),
//OAUTH2令牌类型
TOKENTYPE("bearer "),
//security授权角色前缀
ROLEPREFIX("ROLE_");
Security(String val){
this.val = val;
}
private final String val;
public String getVal() {
return val;
}
}
/**
* 通用的是否
*/
public enum TrueOrFalse {
FALSE("0",false),
TRUE("1",true);
TrueOrFalse(String key, boolean val){
this.key = key;
this.val = val;
}
private final String key;
private final boolean val;
public String getKey() {
return key;
}
public boolean getVal() {
return val;
}
}
/**
* 用户认证返回额外信息
*/
public enum UserAdditionalInfo {
LICENSE("license", "datax"),
USER("user", "用户"),
USERID("user_id", "用户ID"),
USERNAME("username", "用户名"),
NICKNAME("nickname", "用户昵称"),
DEPT("user_dept", "用户部门"),
ROLE("user_role", "用户角色"),
POST("user_post", "用户岗位");
UserAdditionalInfo(String key, String val){
this.key = key;
this.val = val;
}
private final String key;
private final String val;
public String getKey() {
return key;
}
public String getVal() {
return val;
}
}
/**
* 通用的启用禁用状态
*/
public enum EnableState {
DISABLE("0","禁用"),
ENABLE("1","启用");
EnableState(String key, String val){
this.key = key;
this.val = val;
}
private final String key;
private final String val;
public String getKey() {
return key;
}
public String getVal() {
return val;
}
}
/**
* 流程审核状态
*/
public enum AuditState{
WAIT("1","待提交"),
BACK("2", "已退回"),
AUDIT("3","审核中"),
AGREE("4","通过"),
REJECT("5","不通过"),
CANCEL("6", "已撤销");
AuditState(String key, String val){
this.key = key;
this.val = val;
}
private final String key;
private final String val;
public String getKey() {
return key;
}
public String getVal() {
return val;
}
}
/**
* 菜单类型
*/
public enum MenuType{
MODULE("0","模块"),
MENU("1","菜单"),
BUTTON("2","按钮");
MenuType(String key, String val){
this.key = key;
this.val = val;
}
private final String key;
private final String val;
public String getKey() {
return key;
}
public String getVal() {
return val;
}
}
/**
* 数据范围
*/
public enum DataScope{
ALL("1","全部数据权限"),
CUSTOM("2","自定义数据权限"),
DEPT("3","本部门数据权限"),
DEPTANDCHILD("4","本部门及以下数据权限"),
SELF("5","仅本人数据权限");
DataScope(String key, String val){
this.key = key;
this.val = val;
}
private final String key;
private final String val;
public String getKey() {
return key;
}
public String getVal() {
return val;
}
}
/**
* Api状态
*/
public enum ApiState{
WAIT("1","待发布"),
RELEASE("2","已发布"),
CANCEL("3","已下线");
ApiState(String key, String val){
this.key = key;
this.val = val;
}
private final String key;
private final String val;
public String getKey() {
return key;
}
public String getVal() {
return val;
}
}
}

View File

@@ -0,0 +1,14 @@
package cn.datax.common.core;
import lombok.Data;
import java.io.Serializable;
@Data
public class DataRole implements Serializable {
private static final long serialVersionUID=1L;
private String id;
private String dataScope;
}

View File

@@ -0,0 +1,85 @@
package cn.datax.common.core;
import cn.hutool.core.util.ObjectUtil;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.User;
import java.util.Collection;
import java.util.List;
@EqualsAndHashCode(callSuper = true)
public class DataUser extends User {
private String id;
private String nickname;
private String dept;
private List<DataRole> roles;
private List<String> posts;
public DataUser(String id, String nickname, String username, String password, boolean enabled, boolean accountNonExpired, boolean credentialsNonExpired, boolean accountNonLocked, Collection<? extends GrantedAuthority> authorities) {
super(username, password, enabled, accountNonExpired, credentialsNonExpired, accountNonLocked, authorities);
this.id = id;
this.nickname = nickname;
}
public boolean isAdmin() {
return isAdmin(this.getUsername());
}
public static boolean isAdmin(String username) {
return ObjectUtil.equal(username, "admin");
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getNickname() {
return nickname;
}
public void setNickname(String nickname) {
this.nickname = nickname;
}
public String getDept() {
return dept;
}
public void setDept(String dept) {
this.dept = dept;
}
public List<DataRole> getRoles() {
return roles;
}
public void setRoles(List<DataRole> roles) {
this.roles = roles;
}
public List<String> getPosts() {
return posts;
}
public void setPosts(List<String> posts) {
this.posts = posts;
}
@Override
public String toString() {
return "DataUser{" +
"id='" + id + '\'' +
", nickname='" + nickname + '\'' +
", dept='" + dept + '\'' +
", roles=" + roles +
", posts=" + posts +
'}';
}
}

View File

@@ -0,0 +1,26 @@
package cn.datax.common.core;
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.util.List;
@Data
@Accessors(chain = true)
public class JsonPage<T> implements Serializable {
private static final long serialVersionUID = 1L;
private Integer pageNum;
private Integer pageSize;
private Integer total;
private List<T> data;
public JsonPage(Long pageNum, Long pageSize, Long total, List<T> data) {
this.pageNum = pageNum.intValue();
this.pageSize = pageSize.intValue();
this.total = total.intValue();
this.data = data;
}
}

View File

@@ -0,0 +1,88 @@
package cn.datax.common.core;
import lombok.Getter;
import java.io.Serializable;
@Getter
public class R implements Serializable {
private static final long serialVersionUID = 1L;
private boolean success;
private int code;
private String msg;
private Object data;
private long timestamp;
private R() {}
public static R error() {
return error(null);
}
public static R error(String message) {
return error(null, message);
}
public static R error(Integer code, String message) {
if(code == null) {
code = 500;
}
if(message == null) {
message = "服务器内部错误";
}
return build(code, false, message);
}
public static R ok() {
return ok(null);
}
public static R ok(String message) {
return ok(null, message);
}
public static R ok(Integer code, String message) {
if(code == null) {
code = 200;
}
if(message == null) {
message = "操作成功";
}
return build(code, true, message);
}
public static R build(int code, boolean success, String message) {
return new R()
.setCode(code)
.setSuccess(success)
.setMessage(message)
.setTimestamp(System.currentTimeMillis());
}
public R setCode(int code) {
this.code = code;
return this;
}
public R setSuccess(boolean success) {
this.success = success;
return this;
}
public R setMessage(String msg) {
this.msg = msg;
return this;
}
public R setData(Object data) {
this.data = data;
return this;
}
public R setTimestamp(long timestamp) {
this.timestamp = timestamp;
return this;
}
}

View File

@@ -0,0 +1,26 @@
package cn.datax.common.core;
public interface RedisConstant {
String MARKET_API_KEY = "data:market:apis";
String MARKET_API_MASK_KEY = "data:market:api:masks";
String SYSTEM_DICT_KEY = "data:system:dicts";
String SYSTEM_CONFIG_KEY = "data:system:configs";
String METADATA_SOURCE_KEY = "data:metadata:sources";
String METADATA_TABLE_KEY = "data:metadata:tables";
String METADATA_COLUMN_KEY = "data:metadata:columns";
String METADATA_AUTHORIZE_KEY = "data:metadata:authorizes";
String STANDARD_DICT_KEY = "data:standard:dicts";
String WORKFLOW_BUSINESS_KEY = "data:workflow:business";
String VISUAL_SET_KEY = "data:visual:sets";
}

View File

@@ -0,0 +1,27 @@
package cn.datax.common.exception;
import lombok.Getter;
import org.springframework.http.HttpStatus;
import static org.springframework.http.HttpStatus.BAD_REQUEST;
/**
* @author AllDataDC
* @date 2023-01-27
* 统一异常处理
*/
@Getter
public class BadRequestException extends RuntimeException{
private Integer status = BAD_REQUEST.value();
public BadRequestException(String msg){
super(msg);
}
public BadRequestException(HttpStatus status, String msg){
super(msg);
this.status = status.value();
}
}

View File

@@ -0,0 +1,27 @@
package cn.datax.common.exception;
public class DataException extends RuntimeException {
private static final long serialVersionUID = 1L;
public DataException() {
super();
}
public DataException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
public DataException(String message, Throwable cause) {
super(message, cause);
}
public DataException(String message) {
super(message);
}
public DataException(Throwable cause) {
super(cause);
}
}

View File

@@ -0,0 +1,64 @@
package cn.datax.common.exception;
import cn.datax.common.core.R;
import cn.datax.common.utils.ThrowableUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;
import org.springframework.validation.BindException;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import java.util.stream.Collectors;
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {
/**
* 处理自定义异常
*/
@ExceptionHandler(DataException.class)
public R handleWithException(DataException e) {
log.error("自定义异常信息 ex={},StackTrace={}", e.getMessage(), ThrowableUtil.getStackTrace(e));
return R.error(e.getMessage());
}
/**
* 请求的 JSON 参数在请求体内的参数校验
*/
@ExceptionHandler({MethodArgumentNotValidException.class, BindException.class})
public R handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
String message = StringUtils.collectionToCommaDelimitedString(
e.getBindingResult().getFieldErrors()
.stream()
.map(FieldError::getDefaultMessage)
.collect(Collectors.toList()));
log.error("参数校验异常信息 ex={},StackTrace={}", e.getMessage(), ThrowableUtil.getStackTrace(e));
return R.error(message);
}
/**
* 请求的 URL 参数检验
*/
@ExceptionHandler(ConstraintViolationException.class)
public R handleConstraintViolationException(ConstraintViolationException e) {
String message = StringUtils.collectionToCommaDelimitedString(
e.getConstraintViolations()
.stream()
.map(ConstraintViolation::getMessage)
.collect(Collectors.toList()));
log.error("参数校验异常信息 ex={},StackTrace={}", e.getMessage(), ThrowableUtil.getStackTrace(e));
return R.error(message);
}
@ExceptionHandler(Exception.class)
public R handleException(Exception e) {
log.error("全局异常信息ex={},StackTrace={}", e.getMessage(), ThrowableUtil.getStackTrace(e));
return R.error(e.getMessage());
}
}

View File

@@ -0,0 +1,56 @@
package cn.datax.common.mapstruct;
import java.util.List;
/**
*
* Mapper文件基类
* 更多的用法需自行实现
* @param <D> 目标对象一般为DTO对象
* @param <E> 源对象,一般为需要转换的对象
* @param <V> 目标对象一般为VO对象
*/
public interface EntityMapper<D, E, V> {
/**
* 将源对象转换为DTO对象
* @param e
* @return D
*/
D toDTO(E e);
/**
* 将源对象集合转换为DTO对象集合
* @param es
* @return List<D>
*/
List<D> toDTO(List<E> es);
/**
* 将源对象转换为VO对象
* @param e
* @return D
*/
V toVO(E e);
/**
* 将源对象集合转换为VO对象集合
* @param es
* @return List<D>
*/
List<V> toVO(List<E> es);
/**
* 将目标对象转换为源对象
* @param d
* @return E
*/
E toEntity(D d);
/**
* 将目标对象集合转换为源对象集合
* @param ds
* @return List<E>
*/
List<E> toEntity(List<D> ds);
}

View File

@@ -0,0 +1,69 @@
package cn.datax.common.utils;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
@Slf4j
public class HttpUtil {
public static final String METHOD_POST = "POST";
public static final String METHOD_GET = "GET";
public static String getBodyString(HttpServletRequest request) {
String method = request.getMethod();
String bodyString;
if (METHOD_GET.equals(method)) {
bodyString = doGet(request);
} else if (METHOD_POST.equals(method)) {
bodyString = doPost(request);
} else {
// 其他请求方式暂不处理
return null;
}
return bodyString;
}
private static String doPost(HttpServletRequest request) {
StringBuffer sb = new StringBuffer();
InputStream inputStream;
BufferedReader bufferedReader;
try {
//将数据保存到数组中,每次读取的时候,都读取一遍
inputStream = request.getInputStream();
//将字节数组当做输出的目的地
//字节流转换为字符流(处理流)
bufferedReader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
String line = "";
while ((line = bufferedReader.readLine()) != null) {
sb.append(line);
}
} catch (Exception e) {
log.error("数据读取异常", e);
}
return sb.toString();
}
private static String doGet(HttpServletRequest request) {
Map<String, Object> map = new HashMap<>();
Enumeration<String> parameterNames = request.getParameterNames();
while (parameterNames.hasMoreElements()) {
String nextElement = parameterNames.nextElement();
String parameter = request.getParameter(nextElement);
map.put(nextElement, parameter);
}
try {
return new ObjectMapper().writeValueAsString(map);
} catch (JsonProcessingException e) {
}
return null;
}
}

View File

@@ -0,0 +1,63 @@
package cn.datax.common.utils;
import javax.servlet.http.HttpServletRequest;
import java.net.*;
import java.util.Enumeration;
public class IPUtil {
public static String getLocalIP() throws SocketException {
String localIP = null;
Enumeration allNetInterfaces = NetworkInterface.getNetworkInterfaces();
InetAddress ip = null;
while (allNetInterfaces.hasMoreElements()) {
NetworkInterface netInterface = (NetworkInterface) allNetInterfaces.nextElement();
Enumeration addresses = netInterface.getInetAddresses();
while (addresses.hasMoreElements()) {
ip = (InetAddress) addresses.nextElement();
if (ip != null && ip instanceof Inet4Address) {
localIP = ip.getHostAddress();
if (!"127.0.0.1".equalsIgnoreCase(localIP)) {
return localIP;
}
}
}
}
return localIP;
}
/**
* 获取当前网络ip
* @param request
* @return
*/
public static String getIpAddr(HttpServletRequest request) {
String ipAddress = request.getHeader("x-forwarded-for");
if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
ipAddress = request.getHeader("Proxy-Client-IP");
}
if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
ipAddress = request.getHeader("WL-Proxy-Client-IP");
}
if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
ipAddress = request.getRemoteAddr();
if (ipAddress.equals("127.0.0.1") || ipAddress.equals("0:0:0:0:0:0:0:1")) {
//根据网卡取本机配置的IP
InetAddress inet = null;
try {
inet = InetAddress.getLocalHost();
} catch (UnknownHostException e) {
e.printStackTrace();
}
ipAddress = inet.getHostAddress();
}
}
//对于通过多个代理的情况第一个IP为客户端真实IP,多个IP按照','分割
if (ipAddress != null && ipAddress.length() > 15) { //"***.***.***.***".length() = 15
if (ipAddress.indexOf(",") > 0) {
ipAddress = ipAddress.substring(0, ipAddress.indexOf(","));
}
}
return ipAddress;
}
}

View File

@@ -0,0 +1,130 @@
package cn.datax.common.utils;
import cn.datax.service.system.api.dto.JwtUserDto;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.util.Date;
@Slf4j
public class JwtUtil {
/**
* 获取凭证信息
*
* @param token jwt token串
* @return Claims
*/
public static Claims getClaimByToken(String token) {
try {
if (StringUtils.startsWithIgnoreCase(token, "Bearer ")) {
token = token.split(" ")[1];
}
return Jwts.parser()
.setSigningKey("ZmQ0ZGI5NjQ0MDQwY2I4MjMxY2Y3ZmI3MjdhN2ZmMjNhODViOTg1ZGE0NTBjMGM4NDA5NzYxMjdjOWMwYWRmZTBlZjlhNGY3ZTg4Y2U3YTE1ODVkZDU5Y2Y3OGYwZWE1NzUzNWQ2YjFjZDc0NGMxZWU2MmQ3MjY1NzJmNTE0MzI=")
.parseClaimsJws(token)
.getBody();
}catch (Exception e){
HttpServletRequest request =((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
String authorization = request.getHeader("Authorization");
String url = request.getRequestURL().toString();
String uri = request.getRequestURI();
return null;
}
}
/**
* 获取过期时间
*
* @param token jwt token 串
* @return Date
*/
public Date getExpiration(String token) {
return getClaimByToken(token).getExpiration();
}
/**
* 验证token是否失效
*
* @param token token
* @return true:过期 false:没过期
*/
public boolean isExpired(String token) {
try {
final Date expiration = getExpiration(token);
return expiration.before(new Date());
} catch (Exception e) {
log.error("[JwtUtils --> isExpired]: {}", e.getMessage());
return true;
}
}
// /**
// * 检验是否为 jwt 格式的字符串
// *
// * 说明: jwt 字符串由三部分组成, 分别用 . 分隔开, 所以认为有两个 . 的字符串就是jwt形式的字符串
// * @param token jwt token串
// * @return boolean
// */
// public boolean isJwtStr(String token){
// return StringUtils.countOccurrencesOf(token, ".") == 2;
// }
/**
* 获取 jwt 中的账户名
*
* @param token jwt token 串
* @return String
*/
public String getAccountName(String token){
String subject = getClaimByToken(token).getSubject();
JwtUserDto jwtContent = JSONObject.parseObject(subject, JwtUserDto.class);
jwtContent.getUsername();
return jwtContent.getUsername();
}
/**
* 获取 jwt 的账户对象
* @param token
* @return
*/
public static String getTokenSubjectObject(String token){
Claims claimByToken = getClaimByToken(token);
String subject = claimByToken.getSubject();
String body = JSONObject.toJSONString(subject);
Object parse = JSON.parse(body);
String s = parse.toString();
return s;
}
/**
* 获取 jwt 账户信息的json字符串
* @param token
* @return
*/
public String getTokenSubjectStr(String token){
String body = JSONObject.toJSONString(getClaimByToken(token).getSubject());
Object parse = JSON.parse(body);
return parse.toString();
}
}

View File

@@ -0,0 +1,123 @@
package cn.datax.common.utils;
import javax.crypto.Cipher;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import javax.crypto.spec.IvParameterSpec;
import java.security.Key;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.spec.AlgorithmParameterSpec;
import java.util.Base64;
public class MD5Util {
/** 向量(同时拥有向量和密匙才能解密)此向量必须是8byte多少都报错 */
private final byte[] DESIV = new byte[] { 0x22, 0x54, 0x36, 110, 0x40, (byte) 0xac, (byte) 0xad, (byte) 0xdf };
/** 自定义密钥,个数不能太短太短报错过长它默认只取前N位N的具体值大家另行查找资料 */
private final String deSkey = "cloudcloud";
/** 加密算法的参数接口 */
private AlgorithmParameterSpec iv = null;
private Key key = null;
private String charset = "UTF-8";
private static volatile MD5Util instance;
/**
* 构造函数
* @throws Exception
*/
private MD5Util() throws Exception {
// 设置密钥参数
DESKeySpec keySpec = new DESKeySpec(deSkey.getBytes(this.charset));
// 设置向量
iv = new IvParameterSpec(DESIV);
// 获得密钥工厂
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
// 得到密钥对象
key = keyFactory.generateSecret(keySpec);
}
public static MD5Util getInstance() throws Exception {
if(instance == null) {
synchronized (MD5Util.class) {
if(instance == null) {
instance = new MD5Util();
}
}
}
return instance;
}
public static void main(String[] args) {
try {
String value = "1246656415670484994";
MD5Util mt = new MD5Util();
System.out.println("加密前的字符:" + value);
System.out.println("加密后的字符:" + mt.encode(value));
System.out.println("解密后的字符:" + mt.decode(mt.encode(value)));
System.out.println("字符串的MD5值"+ getMD5Value(value));
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 加密
* @param data
* @return
* @throws Exception
*/
public String encode(String data) throws Exception {
// 得到加密对象Cipher
Cipher enCipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
// 设置工作模式为加密模式,给出密钥和向量
enCipher.init(Cipher.ENCRYPT_MODE, key, iv);
byte[] pasByte = enCipher.doFinal(data.getBytes(this.charset));
return Base64.getEncoder().encodeToString(pasByte);
}
/**
* 解密
* @param data
* @return
* @throws Exception
*/
public String decode(String data) throws Exception {
Cipher deCipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
deCipher.init(Cipher.DECRYPT_MODE, key, iv);
//此处注意doFinal()的参数的位数必须是8的倍数否则会报错通过encode加密的字符串读出来都是8的倍数位但写入文件再读出来就可能因为读取的方式的问题导致最后此处的doFinal()的参数的位数不是8的倍数
//此处必须用base64Decoder若用data。getBytes()则获取的字符串的byte数组的个数极可能不是8的倍数而且不与上面的BASE64Encoder对应即使解密不报错也不会得到正确结果
byte[] pasByte = deCipher.doFinal(Base64.getDecoder().decode(data));
return new String(pasByte, this.charset);
}
/**
* 获取MD5的值可用于对比校验
* @param sourceStr
* @return
*/
private static String getMD5Value(String sourceStr) {
String result = "";
try {
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(sourceStr.getBytes());
byte b[] = md.digest();
int i;
StringBuffer buf = new StringBuffer("");
for (int offset = 0; offset < b.length; offset++) {
i = b[offset];
if (i < 0) {
i += 256;
}
if (i < 16) {
buf.append("0");
}
buf.append(Integer.toHexString(i));
}
result = buf.toString();
} catch (NoSuchAlgorithmException e) {
}
return result;
}
}

View File

@@ -0,0 +1,55 @@
package cn.datax.common.utils;
import cn.hutool.core.util.StrUtil;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* 消息模板格式化
*/
public class MsgFormatUtil {
private static String REGEX = "(\\{([a-zA-Z]+)\\})";
public static String TEMPALTE_NICKNAME = "nickname";
public static String TEMPALTE_DATETIME = "datetime";
public static String TEMPALTE_BUSINESS_NAME = "businessName";
public static String TEMPALTE_BUSINESS_KEY = "businessKey";
/**
* 根据模板及参数获得内容
* @param tempalte
* @param parameters
* @return
*/
public static String getContent(String tempalte, Map<String, String> parameters) {
if (StrUtil.isBlank(tempalte)) {
tempalte = "业务名称:{businessName},发起人:{nickname},业务编号:{businessKey}";
}
Pattern p = Pattern.compile(REGEX);
Matcher m = p.matcher(tempalte);
StringBuffer stringBuffer = new StringBuffer();
while (m.find()){
String key = m.group(2);
String value = null;
if (parameters.containsKey(key)){
value = parameters.get(key);
}
value = (value == null) ? "" : value;
m.appendReplacement(stringBuffer, value);
}
m.appendTail(stringBuffer);
return stringBuffer.toString();
}
public static void main(String[] args) {
String tempalte = "{name}你好,今年{age}岁";
Map<String,String> parameters = new HashMap<>();
parameters.put("name", "chris");
parameters.put("age", "22");
System.out.println(getContent(tempalte, parameters));
}
}

View File

@@ -0,0 +1,53 @@
package cn.datax.common.utils;
import java.io.Serializable;
public class PageUtil implements Serializable {
private static final long serialVersionUID = 1L;
private static Integer DEFAULT_MAX_COUNT = 5000;
// 当前页码
private Integer pageNum = 1;
// 分页条数
private Integer pageSize = 20;
public Integer getPageNum() {
return pageNum;
}
public void setPageNum(Integer pageNum) {
this.pageNum = pageNum;
}
public Integer getPageSize() {
return pageSize;
}
public void setPageSize(Integer pageSize) {
this.pageSize = pageSize;
if (this.pageSize > 0) {
this.pageSize = this.pageSize > DEFAULT_MAX_COUNT ? DEFAULT_MAX_COUNT : this.pageSize;
} else {
this.pageSize = 20;
}
}
public PageUtil(Integer pageNum, Integer pageSize) {
this.pageNum = pageNum;
this.pageSize = pageSize;
if (this.pageSize > 0) {
this.pageSize = this.pageSize > DEFAULT_MAX_COUNT ? DEFAULT_MAX_COUNT : this.pageSize;
} else {
this.pageSize = 20;
}
}
public Integer getOffset() {
pageSize = pageSize == null ? 20 : pageSize;
pageNum = pageNum == null ? 1 : pageNum;
int offset = pageNum > 0 ? (pageNum - 1) * pageSize : 0;
return offset;
}
}

View File

@@ -0,0 +1,22 @@
package cn.datax.common.utils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* 获取 HttpServletRequest
*
*/
public class RequestHolder {
public static HttpServletRequest getHttpServletRequest() {
return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
}
public static HttpServletResponse getHttpServletResponse() {
return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();
}
}

View File

@@ -0,0 +1,27 @@
package cn.datax.common.utils;
import com.fasterxml.jackson.databind.ObjectMapper;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class ResponseUtil {
/**
* 设置响应
*
* @param response HttpServletResponse
* @param contentType content-type
* @param status http状态码
* @param value 响应内容
* @throws IOException IOException
*/
public static void makeResponse(HttpServletResponse response, String contentType,
int status, Object value) throws IOException {
response.setContentType(contentType);
response.setStatus(status);
ObjectMapper objectMapper = new ObjectMapper();
response.getOutputStream().write(objectMapper.writeValueAsBytes(value));
}
}

View File

@@ -0,0 +1,129 @@
package cn.datax.common.utils;
import com.platform.exception.BadRequestException;
import cn.datax.service.system.api.dto.JwtUserDto;
import cn.datax.service.system.api.feign.UserServiceFeign;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;
@Component
public class SecurityUtil {
@Autowired
private UserServiceFeign userServiceFeign;
@Autowired
private JwtUtil jwtUtil;
/**
* 获取用户
*
* @return user
*/
public static JwtUserDto getDataUser() {
UserServiceFeign userServiceFeign = SpringContextHolder.getBean(UserServiceFeign.class);
return userServiceFeign.loginByUsername(getCurrentUsername());
}
public static String getCurrentUsername() {
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
String authorization = request.getHeader("Authorization");
if (null == authorization) {
authorization = RequestContextHolder.getRequestAttributes().getAttribute("token", 1).toString();
}
String tokenSubjectObject = JwtUtil.getTokenSubjectObject(authorization);
if (tokenSubjectObject == null) {
throw new BadRequestException(HttpStatus.UNAUTHORIZED, "当前登录状态过期");
}
return tokenSubjectObject;
}
/**
* 获取用户ID
*
* @return id
*/
public static String getUserId() {
JwtUserDto user = getDataUser();
if (user != null) {
return user.getUser().getId() + "";
}
return "";
}
/**
* 获取用户部门
*
* @return id
*/
public static String getUserDeptId() {
JwtUserDto user = getDataUser();
if (user != null) {
return user.getUser().getDeptId() + "";
}
return "";
}
/**
* 获取用户名称
*
* @return username
*/
public static String getUserName() {
JwtUserDto user = getDataUser();
if (user != null) {
return user.getUsername();
}
return "";
}
/**
* 获取用户昵称
*
* @return nickname
*/
public static String getNickname() {
JwtUserDto user = getDataUser();
if (user != null) {
return user.getUser().getNickName();
}
return "";
}
/**
* 获取用户角色
*
* @return username
*/
public static List<String> getUserRoleIds() {
JwtUserDto user = getDataUser();
if (user != null) {
List<String> roles = new ArrayList<>(user.getRoles());
return roles;
}
return null;
}
/**
* 获取用户
*
* @return user
*/
public static boolean isAdmin() {
return true;
}
}

View File

@@ -0,0 +1,82 @@
package cn.datax.common.utils;
import cn.datax.common.exception.BadRequestException;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import java.util.List;
/**
* 获取当前登录的用户
* @author AllDataDC
* @date 2023-01-27
*/
@Slf4j
public class SecurityUtils {
/**
* 获取当前登录的用户
* @return UserDetails
*/
public static UserDetails getCurrentUser() {
UserDetailsService userDetailsService = SpringContextHolder.getBean(UserDetailsService.class);
return userDetailsService.loadUserByUsername(getCurrentUsername());
}
/**
* 获取系统用户名称
*
* @return 系统用户名称
*/
public static String getCurrentUsername() {
final Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (authentication == null) {
throw new BadRequestException(HttpStatus.UNAUTHORIZED, "当前登录状态过期");
}
if (authentication.getPrincipal() instanceof UserDetails) {
UserDetails userDetails = (UserDetails) authentication.getPrincipal();
return userDetails.getUsername();
}
throw new BadRequestException(HttpStatus.UNAUTHORIZED, "找不到当前登录的信息");
}
/**
* 获取系统用户ID
* @return 系统用户ID
*/
public static Long getCurrentUserId() {
UserDetails userDetails = getCurrentUser();
return new JSONObject(new JSONObject(userDetails).get("user")).get("id", Long.class);
}
/**
* 获取当前用户的数据权限
* @return /
*/
public static List<Long> getCurrentUserDataScope(){
UserDetails userDetails = getCurrentUser();
JSONArray array = JSONUtil.parseArray(new JSONObject(userDetails).get("dataScopes"));
return JSONUtil.toList(array,Long.class);
}
// /**
// * 获取数据权限级别
// * @return 级别
// */
// public static String getDataScopeType() {
// List<Long> dataScopes = getCurrentUserDataScope();
// if(dataScopes.size() != 0){
// return "";
// }
// return DataScopeEnum.ALL.getValue();
// }
}

View File

@@ -0,0 +1,67 @@
package cn.datax.common.utils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
@Component
@Lazy(false)
public class SpringContextHolder implements ApplicationContextAware, DisposableBean {
private static ApplicationContext applicationContext = null;
private static Logger logger = LoggerFactory.getLogger(SpringContextHolder.class);
/**
* 取得存储在静态变量中的ApplicationContext.
*/
public static ApplicationContext getApplicationContext() {
return applicationContext;
}
/**
* 从静态变量applicationContext中取得Bean, 自动转型为所赋值对象的类型.
*/
@SuppressWarnings("unchecked")
public static <T> T getBean(String name) {
return (T) applicationContext.getBean(name);
}
/**
* 从静态变量applicationContext中取得Bean, 自动转型为所赋值对象的类型.
*/
public static <T> T getBean(Class<T> requiredType) {
return applicationContext.getBean(requiredType);
}
/**
* 清除SpringContextHolder中的ApplicationContext为Null.
*/
public static void clearHolder() {
if (logger.isDebugEnabled()) {
logger.debug("清除SpringContextHolder中的ApplicationContext:" + applicationContext);
}
applicationContext = null;
}
/**
* 实现ApplicationContextAware接口, 注入Context到静态变量中.
*/
@Override
public void setApplicationContext(ApplicationContext applicationContext) {
SpringContextHolder.applicationContext = applicationContext;
}
/**
* 实现DisposableBean接口, 在Context关闭时清理静态变量.
*/
@Override
public void destroy() throws Exception {
SpringContextHolder.clearHolder();
}
}

View File

@@ -0,0 +1,26 @@
package cn.datax.common.utils;
import java.io.PrintWriter;
import java.io.StringWriter;
/**
* 异常工具
*/
public class ThrowableUtil {
/**
* 获取堆栈信息
* @param throwable
* @return
*/
public static String getStackTrace(Throwable throwable){
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
try {
throwable.printStackTrace(pw);
return sw.toString();
} finally {
pw.close();
}
}
}

View File

@@ -0,0 +1,5 @@
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
cn.datax.common.config.JacksonConfig,\
cn.datax.common.config.RestTemplateConfig,\
cn.datax.common.exception.GlobalExceptionHandler,\
cn.datax.common.utils.SpringContextHolder