新增common、core

This commit is contained in:
付庆吉
2020-12-11 14:38:30 +08:00
parent b0e46351e1
commit 82fafc4f85
54 changed files with 3082 additions and 0 deletions

View File

@ -0,0 +1,23 @@
package com.chinaunicom.mall.ebtp.common;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
/**
* Hello world!
*
*/
@SpringBootApplication(exclude = {
DataSourceAutoConfiguration.class
})
@EnableFeignClients
@EnableEurekaClient
public class UbootCommonApplication {
public static void main( String[] args )
{
SpringApplication.run(UbootCommonApplication.class, args);
}
}

View File

@ -0,0 +1,9 @@
package com.chinaunicom.mall.ebtp.common.base.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/base/")
public class BaseController {
}

View File

@ -0,0 +1,14 @@
package com.chinaunicom.mall.ebtp.common.base.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
public interface IBaseMapper<T> extends BaseMapper<T> {
/**
* 逻辑删除数据
*
* @param id
*/
public int deleteOff(Long id);
}

View File

@ -0,0 +1,145 @@
package com.chinaunicom.mall.ebtp.common.base.entity;
import lombok.Data;
import java.util.Date;
/**
* 缓存用户实体映射类
*
* @author daixc
* @date 2020/10/16
* @version 1.0
*/
@Data
public class BaseCacheUser {
/**
* PKID
*/
private Long userId;
/**
* 姓名
*/
private String lastName;
/**
*姓氏
*/
private String firstName;
/**
* 全名
*/
private String fullName;
/**
* 电子邮件
*/
private String emailAddress;
//
/**
* 用户名
*/
private String loginName;
//
/**
* 手机号
*/
private String mobilePhone;
/**
* 办公号
*/
private String officePhone;
/**
* 性别
*/
private String sex;
/**
* 员工类别
*/
private String employeeCategory;
/**
* 用户类型
*/
private String userType;
/**
* 出生日期
*/
private Date dateOfBirth;
/**
* 年龄
*/
private Integer age;
/**
* 员工编号
*/
private String employeeNumber;
/**
* 国籍ID
*/
private String nationalityId;
/**
* 国籍
*/
private String nationality;
/**
* 身份证号码
*/
private String nationalIdentifier;
/**
* 主管ID
*/
private Integer supervisorId;
/**
* 组织ID
*/
private String organizationId;
/**
* 组织名称
*/
private String organizationName;
//
/**
* 组织机构类别
*/
private String orgCategory;
/**
* 部门ID
*/
private String deptId;
/**
* 部门名称
*/
private String deptName;
/**
* 角色ID
*/
private String roleIds;
/**
* 业务组id
*/
private Integer bussiGroupId;
/**
* 职位ID
*/
private Integer positionId;
}

View File

@ -0,0 +1,59 @@
package com.chinaunicom.mall.ebtp.common.base.entity;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import com.chinaunicom.mall.ebtp.common.config.CustomLocalDateTimeTypeHandler;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.experimental.Accessors;
import org.springframework.format.annotation.DateTimeFormat;
import java.io.Serializable;
import java.time.LocalDateTime;
@Data
@Accessors(chain = true)
public class BaseEntity implements Serializable {
private static final long serialVersionUID = 1L;
@TableField(fill = FieldFill.INSERT)
@ApiModelProperty(value = "创建者")
private Long createBy;
@TableField(fill = FieldFill.INSERT,typeHandler = CustomLocalDateTimeTypeHandler.class)
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
@ApiModelProperty(value = "创建时间")
private LocalDateTime createDate;
@TableField(fill = FieldFill.UPDATE)
@ApiModelProperty(value = "更新者")
private Long updateBy;
@TableField(fill = FieldFill.UPDATE,typeHandler = CustomLocalDateTimeTypeHandler.class)
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
@ApiModelProperty(value = "更新时间")
private LocalDateTime updateDate;
@TableField(fill = FieldFill.INSERT)
@ApiModelProperty(value = "租户标识")
private String tenantId;
@TableField(fill = FieldFill.INSERT)
@ApiModelProperty(value = "租户名称")
private String tenantName;
@TableField(fill = FieldFill.INSERT)
@ApiModelProperty(value = "逻辑删除normal表示正常默认deleted表示删除")
private String deleteFlag;
@TableField(fill = FieldFill.UPDATE,typeHandler = CustomLocalDateTimeTypeHandler.class)
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
@ApiModelProperty(value = "最后更新时间戳")
private LocalDateTime lastUpdateTime;
}

View File

@ -0,0 +1,51 @@
package com.chinaunicom.mall.ebtp.common.base.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.util.List;
@Data
@Accessors(chain = true)
@AllArgsConstructor
@NoArgsConstructor
public class BasePage<T> implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 当前页,默认 1
*
* @return 当前页
*/
private long current;
/**
* 当前分页总页数
*/
private long pages;
/**
* 当前分页总页数
*
* @return 总页数
*/
private long size;
/**
* 当前满足条件总行数
*
* @return 总条数
*/
private long total;
/**
* 分页记录列表
*
* @return 分页对象记录列表
*/
private List<T> records;
}

View File

@ -0,0 +1,41 @@
package com.chinaunicom.mall.ebtp.common.base.entity;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
/**
* 返回类型FrameResponse
*/
@Getter
@NoArgsConstructor
@AllArgsConstructor
@ApiModel
public class BasePageRequest implements Serializable {
private static final long serialVersionUID = 6769157532172136264L;
@ApiModelProperty("当前页")
@NotNull
@Min(0)
private Integer pageNo;
@ApiModelProperty("每页显示条数")
@NotNull
@Min(0)
private Integer pageSize;
public Integer getPageNo() {
return null == pageNo ? 0 : pageNo;
}
public Integer getPageSize() {
return null == pageSize ? 10 : pageSize;
}
}

View File

@ -0,0 +1,64 @@
package com.chinaunicom.mall.ebtp.common.base.entity;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.chinaunicom.mall.ebtp.common.base.enums.ResponseEnum;
import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import java.io.Serializable;
/**
* 返回类型FrameResponse
*/
@Getter
@NoArgsConstructor
@AllArgsConstructor
public class BasePageResponse<T> implements Serializable {
private static final long serialVersionUID = 1L;
private Integer code;
private boolean success;
private String message;
@JsonInclude(JsonInclude.Include.NON_NULL)
private IPage<T> data;
public static <T> BasePageResponse<T> success(IPage<T> p) {
return new BasePageResponse<>(ResponseEnum.SUCCESS.getCode(),
Boolean.TRUE,
ResponseEnum.SUCCESS.getMessage(),
p);
}
public static <T> BasePageResponse<T> success(String message, IPage<T> p) {
return new BasePageResponse<>(ResponseEnum.SUCCESS.getCode(),
Boolean.TRUE,
message,
p);
}
public static BasePageResponse<Object> fail(String message) {
return new BasePageResponse<>(ResponseEnum.SUCCESS.getCode(),
Boolean.FALSE,
message,
null);
}
public static BasePageResponse<Object> fail(int code, String message) {
return new BasePageResponse<>(code,
Boolean.FALSE,
message,
null);
}
}

View File

@ -0,0 +1,98 @@
package com.chinaunicom.mall.ebtp.common.base.entity;
import com.chinaunicom.mall.ebtp.common.base.enums.ResponseEnum;
import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import java.io.Serializable;
/**
* 返回类型FrameResponse
*/
@Getter
@NoArgsConstructor
@AllArgsConstructor
public class BaseResponse<T> implements Serializable {
private static final long serialVersionUID = 6769157532172136264L;
private Integer code;
private boolean success;
private String message;
@JsonInclude(JsonInclude.Include.NON_NULL)
private T data;
public static BaseResponse<String> success() {
return new BaseResponse<>(ResponseEnum.SUCCESS.getCode(),
Boolean.TRUE,
ResponseEnum.SUCCESS.getMessage(),
"");
}
public static <T> BaseResponse<T> success(T data) {
return new BaseResponse<>(ResponseEnum.SUCCESS.getCode(),
Boolean.TRUE,
ResponseEnum.SUCCESS.getMessage(),
data);
}
public static <T> BaseResponse<T> success(String message, T data) {
return new BaseResponse<>(ResponseEnum.SUCCESS.getCode(),
Boolean.TRUE,
message,
data);
}
public static BaseResponse<String> fail() {
return new BaseResponse<>(ResponseEnum.ERROR.getCode(),
Boolean.FALSE,
ResponseEnum.ERROR.getMessage(),
"");
}
public static BaseResponse<String> fail(String message) {
return new BaseResponse<>(ResponseEnum.ERROR.getCode(),
Boolean.FALSE,
message,
"");
}
public static BaseResponse<String> fail(Integer code, String message) {
return new BaseResponse<>(code,
Boolean.FALSE,
message,
"");
}
public static <T> BaseResponse<T> fail(T data) {
return new BaseResponse<>(ResponseEnum.ERROR.getCode(),
Boolean.FALSE,
ResponseEnum.ERROR.getMessage(),
data);
}
public static <T> BaseResponse<T> fail(String message, T data) {
return new BaseResponse<>(ResponseEnum.ERROR.getCode(),
Boolean.FALSE,
message,
data);
}
public static <T> BaseResponse<T> fail(Integer code, String message, T data) {
return new BaseResponse<T>(code,
Boolean.FALSE,
message,
data);
}
}

View File

@ -0,0 +1,68 @@
package com.chinaunicom.mall.ebtp.common.base.entity;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
/**
* 实体类 DictProject
*
* @author daixc
* @date 2020/11/02
*/
@Data
public class DictProject implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 编号
*/
@ApiModelProperty(value = "编号")
private Integer id;
/**
* 字典code
*/
@ApiModelProperty(value = "字典code")
private String code;
/**
* 字典名称
*/
@ApiModelProperty(value = "字典名称")
private String dicName;
/**
* 父类code
*/
@ApiModelProperty(value = "父类code")
private String parentCode;
/**
* 父类类型
*/
@ApiModelProperty(value = "父类类型")
private String parentType;
/**
* 是否应用
*/
@ApiModelProperty(value = "是否应用")
private String useFlag;
/**
* 排序
*/
@ApiModelProperty(value = "排序")
private Integer orderFlag;
/**
* 描述
*/
@ApiModelProperty(value = "描述")
private String description;
}

View File

@ -0,0 +1,47 @@
package com.chinaunicom.mall.ebtp.common.base.enums;
import com.chinaunicom.mall.ebtp.common.exception.service.BusinessExceptionAssert;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* 通用异常Enum
*
* @author 付庆吉
* @date 2020-09-14
*/
@Getter
@AllArgsConstructor
public enum ResponseEnum implements BusinessExceptionAssert {
/**
* 成功
*/
SUCCESS(200, "success"),
/**
* 失败
*/
ERROR(90000, "操作失败"),
/**
* token not find
*/
TOKEN_NOT_FIND(30001, "认证不存在!"),
/**
* connect timeout
*/
CONNECT_TIMEOUT(30002, "连接超时!");
/**
* 返回码
*/
private int code;
/**
* 返回消息
*/
private String message;
}

View File

@ -0,0 +1 @@
package com.chinaunicom.mall.ebtp.common.base;

View File

@ -0,0 +1,20 @@
package com.chinaunicom.mall.ebtp.common.base.service;
import com.chinaunicom.mall.ebtp.common.base.entity.BaseCacheUser;
/**
* 缓存用户service
* 获取缓存用户信息
*
* @author daixc
* @date 2020/10/16
* @version 1.0
*/
public interface IBaseCacheUserService {
/**
* 获取缓存用户信息
* @return BaseCacheUser 返回缓存用户信息
*/
BaseCacheUser getCacheUser();
}

View File

@ -0,0 +1,7 @@
package com.chinaunicom.mall.ebtp.common.base.service;
import com.baomidou.mybatisplus.extension.service.IService;
public interface IBaseService<T> extends IService<T> {
}

View File

@ -0,0 +1,27 @@
package com.chinaunicom.mall.ebtp.common.base.service.impl;
import com.chinaunicom.mall.ebtp.common.base.entity.BaseCacheUser;
import com.chinaunicom.mall.ebtp.common.base.service.IBaseCacheUserService;
import org.springframework.stereotype.Service;
/**
* 缓存用户service实现层
* 获取缓存用户信息
*
* @author daixc
* @date 2020/10/16
* @version 1.0
*/
@Service
public class BaseCacheUserServiceImpl implements IBaseCacheUserService {
@Override
public BaseCacheUser getCacheUser() {
BaseCacheUser user = new BaseCacheUser();
user.setUserId(1316573977715408898L);
user.setFullName("测试用户");
user.setRoleIds("1,2,3");
user.setOrganizationId("844984984648946");
return user;
}
}

View File

@ -0,0 +1,10 @@
package com.chinaunicom.mall.ebtp.common.base.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.chinaunicom.mall.ebtp.common.base.dao.IBaseMapper;
import com.chinaunicom.mall.ebtp.common.base.service.IBaseService;
public class BaseServiceImpl<M extends IBaseMapper<T>, T> extends ServiceImpl<M, T> implements IBaseService<T> {
}

View File

@ -0,0 +1,86 @@
package com.chinaunicom.mall.ebtp.common.config;
import com.baomidou.mybatisplus.core.exceptions.MybatisPlusException;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.MappedJdbcTypes;
import org.apache.ibatis.type.MappedTypes;
import java.io.IOException;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
/**
* 解决Json字段内容LocalDateTime反序列化问题
* @author dino
* @date 2020/11/10 15:48
*/
@Slf4j
@MappedTypes({Object.class})
@MappedJdbcTypes(JdbcType.VARCHAR)
public class CustomJacksonTypeHandler extends BaseTypeHandler<Object> {
private static ObjectMapper objectMapper;
private Class<Object> type;
static {
objectMapper = new ObjectMapper();
objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
objectMapper.registerModule(new JavaTimeModule());
}
public CustomJacksonTypeHandler(Class<Object> type) {
if (log.isTraceEnabled()) {
log.trace("JacksonTypeHandler(" + type + ")");
}
if (null == type) {
throw new MybatisPlusException("Type argument cannot be null");
}
this.type = type;
}
private Object parse(String json) {
try {
if (json == null || json.length() == 0) {
return null;
}
return objectMapper.readValue(json, type);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
private String toJsonString(Object obj) {
try {
return objectMapper.writeValueAsString(obj);
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
}
@Override
public Object getNullableResult(ResultSet rs, String columnName) throws SQLException {
return parse(rs.getString(columnName));
}
@Override
public Object getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
return parse(rs.getString(columnIndex));
}
@Override
public Object getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
return parse(cs.getString(columnIndex));
}
@Override
public void setNonNullParameter(PreparedStatement ps, int columnIndex, Object parameter, JdbcType jdbcType) throws SQLException {
ps.setString(columnIndex, toJsonString(parameter));
}
}

View File

@ -0,0 +1,60 @@
package com.chinaunicom.mall.ebtp.common.config;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.MappedJdbcTypes;
import org.apache.ibatis.type.MappedTypes;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
@Component
//定义转换器支持的JAVA类型
@MappedTypes(LocalDateTime.class)
//定义转换器支持的数据库类型
@MappedJdbcTypes(value = JdbcType.TIMESTAMP, includeNullJdbcType = true)
public class CustomLocalDateTimeTypeHandler extends BaseTypeHandler<LocalDateTime> {
public static final String PATTERN_DATETIME = "yyyy-MM-dd HH:mm:ss";
private final DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(PATTERN_DATETIME);
@Override
public void setNonNullParameter(PreparedStatement ps, int i, LocalDateTime parameter, JdbcType jdbcType)
throws SQLException {
if (parameter != null) {
ps.setString(i, dateTimeFormatter.format(parameter));
}
}
@Override
public LocalDateTime getNullableResult(ResultSet rs, String columnName) throws SQLException {
String target = rs.getString(columnName);
if (StringUtils.isEmpty(target)) {
return null;
}
return LocalDateTime.parse(target, dateTimeFormatter);
}
@Override
public LocalDateTime getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
String target = rs.getString(columnIndex);
if (StringUtils.isEmpty(target)) {
return null;
}
return LocalDateTime.parse(target, dateTimeFormatter);
}
@Override
public LocalDateTime getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
String target = cs.getString(columnIndex);
if (StringUtils.isEmpty(target)) {
return null;
}
return LocalDateTime.parse(target, dateTimeFormatter);
}
}

View File

@ -0,0 +1,27 @@
package com.chinaunicom.mall.ebtp.common.config;
import feign.RequestInterceptor;
import feign.RequestTemplate;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
/**
* fegin调用时 header中添加JwtToken
*/
@Configuration
public class FeignConfig implements RequestInterceptor {
@Override
public void apply(RequestTemplate template) {
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
if (null != attributes) {
HttpServletRequest request = attributes.getRequest();
String token = request.getHeader("JwtToken");
template.header("JwtToken", token);
}
}
}

View File

@ -0,0 +1,26 @@
package com.chinaunicom.mall.ebtp.common.config;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
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;
@Configuration
public class JacksonConfig {
@Bean
@Primary
@ConditionalOnMissingBean(ObjectMapper.class)
public ObjectMapper jacksonObjectMapper(Jackson2ObjectMapperBuilder builder) {
ObjectMapper objectMapper = builder.createXmlMapper(false).build();
// 全局配置序列化返回 JSON 处理
SimpleModule simpleModule = new SimpleModule();
//JSON Long ==> String
simpleModule.addSerializer(Long.class, ToStringSerializer.instance);
objectMapper.registerModule(simpleModule);
return objectMapper;
}
}

View File

@ -0,0 +1,140 @@
package com.chinaunicom.mall.ebtp.common.config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.annotation.CachingConfigurerSupport;
//@Configuration
//@EnableCaching
public class RedisJedisConfig extends CachingConfigurerSupport {
@Value("${spring.redis.token.host}")
private String tokenHost;
@Value("${spring.redis.token.password}")
private String tokenPassword;
@Value("${spring.redis.token.port}")
private int tokenPort;
@Value("${spring.redis.token.database}")
private int tokenDatabase;
@Value("${spring.redis.token.timeout}")
private int tokenTimeout;
@Value("${spring.redis.uuid.host}")
private String uuidHost;
@Value("${spring.redis.uuid.password}")
private String uuidPassword;
@Value("${spring.redis.uuid.port}")
private int uuidPort;
@Value("${spring.redis.uuid.database}")
private int uuidDatabase;
@Value("${spring.redis.uuid.timeout}")
private int uuidTimeout;
@Value("${spring.redis.cache.host}")
private String cacheHost;
@Value("${spring.redis.cache.password}")
private String cachePassword;
@Value("${spring.redis.cache.port}")
private int cachePort;
@Value("${spring.redis.cache.database}")
private int cacheDatabase;
@Value("${spring.redis.cache.timeout}")
private int cacheTimeout;
private int maxWait;
@Value("${spring.redis.jedis.pool.maxIdle}")
private int maxIdle;
@Value("${spring.redis.jedis.pool.minIdle}")
private int minIdle;
// @Bean("jedisFactoryToken")
// public JedisConnectionFactory jedisConnectionFactoryToken() {
// return getJedisConnectionFactory(tokenHost,tokenPassword,tokenPort,tokenDatabase);
// }
//
// @Bean("jedisFactoryUuid")
// public JedisConnectionFactory jedisConnectionFactoryUuid() {
// return getJedisConnectionFactory(uuidHost,uuidPassword,uuidPort,uuidDatabase);
// }
//
// @Bean("jedisFactoryCache")
// @Primary
// public JedisConnectionFactory jedisConnectionFactoryCache() {
// return getJedisConnectionFactory(cacheHost,cachePassword,cachePort,cacheDatabase);
// }
//
// public JedisConnectionFactory getJedisConnectionFactory(String host, String password, int port, int database) {
// JedisConnectionFactory factory = new JedisConnectionFactory();
// factory.setHostName(host);
// factory.setPort(port);
// factory.setPassword(password);
// factory.setDatabase(database);
// factory.setTimeout(tokenTimeout);
//
// JedisPoolConfig config = new JedisPoolConfig();
// config.setJmxEnabled(true);
// config.setMaxIdle(maxIdle);
// config.setMinIdle(minIdle);
//// config.setMaxTotal(maxActive);
// config.setMaxWaitMillis(maxWait);
// config.setTestOnBorrow(false);
// config.setTestWhileIdle(true);
// config.setMinEvictableIdleTimeMillis(1800000);
// config.setSoftMinEvictableIdleTimeMillis(1800000);
//
// factory.setPoolConfig(config);
// factory.afterPropertiesSet();
//
// return factory;
// }
// /**
// * 默认配置 redis template
// *
// * @param redisConnectionFactory
// * @return
// */
// @Bean(name = "redisTempletToken")
// public RedisTemplate<String, Object> redisTemplateToken(@Qualifier("jedisFactoryToken") RedisConnectionFactory redisConnectionFactory) {
// return createRedisTemplate(redisConnectionFactory);
// }
// @Bean(name = "redisTempletUuid")
// public RedisTemplate<String, Object> redisTemplateUuid(@Qualifier("jedisFactoryUuid") RedisConnectionFactory redisConnectionFactory) {
// return createRedisTemplate(redisConnectionFactory);
// }
// @Bean(name = "redisTempletCache")
// @Primary()
// public RedisTemplate<String, Object> redisTemplateCache(@Qualifier("jedisFactoryCache") RedisConnectionFactory redisConnectionFactory) {
// return createRedisTemplate(redisConnectionFactory);
// }
// /**
// * json 实现 redisTemplate
// * <p>
// * @return
// */
// public RedisTemplate<String, Object> createRedisTemplate(RedisConnectionFactory factory) {
// RedisTemplate<String, Object> template = new RedisTemplate<>();
// // 配置连接工厂
// template.setConnectionFactory(factory);
// //使用Jackson2JsonRedisSerializer来序列化和反序列化redis的value值默认使用JDK的序列化方式
// Jackson2JsonRedisSerializer jacksonSeial = new Jackson2JsonRedisSerializer(Object.class);
// ObjectMapper om = new ObjectMapper();
// // 指定要序列化的域field,get和set,以及修饰符范围ANY是都有包括private和public
// om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
// // 指定序列化输入的类型类必须是非final修饰的final修饰的类比如String,Integer等会跑出异常
// om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
// jacksonSeial.setObjectMapper(om);
// // 值采用json序列化
// template.setValueSerializer(jacksonSeial);
// //使用StringRedisSerializer来序列化和反序列化redis的key值
// template.setKeySerializer(new StringRedisSerializer());
// // 设置hash key 和value序列化模式
// template.setHashKeySerializer(new StringRedisSerializer());
// template.setHashValueSerializer(jacksonSeial);
// template.afterPropertiesSet();
// return template;
// }
}

View File

@ -0,0 +1,189 @@
package com.chinaunicom.mall.ebtp.common.config;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.context.annotation.Scope;
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
import org.springframework.data.redis.connection.lettuce.LettuceClientConfiguration;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.connection.lettuce.LettucePoolingClientConfiguration;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import java.time.Duration;
@Configuration
@EnableCaching
@Slf4j
public class RedisLettuceConfig extends CachingConfigurerSupport {
@Value("${spring.redis.token.host}")
private String tokenHost;
@Value("${spring.redis.token.password}")
private String tokenPassword;
@Value("${spring.redis.token.port}")
private int tokenPort;
@Value("${spring.redis.token.database}")
private int tokenDatabase;
@Value("${spring.redis.token.timeout}")
private int tokenTimeout;
@Value("${spring.redis.uuid.host}")
private String uuidHost;
@Value("${spring.redis.uuid.password}")
private String uuidPassword;
@Value("${spring.redis.uuid.port}")
private int uuidPort;
@Value("${spring.redis.uuid.database}")
private int uuidDatabase;
@Value("${spring.redis.uuid.timeout}")
private int uuidTimeout;
@Value("${spring.redis.cache.host}")
private String cacheHost;
@Value("${spring.redis.cache.password}")
private String cachePassword;
@Value("${spring.redis.cache.port}")
private int cachePort;
@Value("${spring.redis.cache.database}")
private int cacheDatabase;
@Value("${spring.redis.cache.timeout}")
private int cacheTimeout;
@Bean
@ConfigurationProperties(prefix = "spring.redis.lettuce.pool")
@Scope(value = "prototype")
public GenericObjectPoolConfig redisPool() {
return new GenericObjectPoolConfig();
}
@Bean("redisConfigToken")
@ConfigurationProperties(prefix = "spring.redis.token")
public RedisStandaloneConfiguration redisConfigToken() {
return getRedisStandaloneConfiguration(tokenDatabase, tokenHost, tokenPassword, tokenPort);
}
private RedisStandaloneConfiguration getRedisStandaloneConfiguration(int database, String host, String password, int port) {
RedisStandaloneConfiguration configuration = new RedisStandaloneConfiguration();
configuration.setDatabase(database);
configuration.setHostName(host);
configuration.setPassword(password);
configuration.setPort(port);
return configuration;
}
/**
* 配置第一个数据源的RedisTemplate
* 注意:这里指定使用名称=factory 的 RedisConnectionFactory
* 并且标识第一个数据源是默认数据源 @Primary
*
* @param redisConfigToken
* @return
*/
@Bean("lettuceFactoryToken")
public LettuceConnectionFactory factoryToken(GenericObjectPoolConfig config, @Qualifier("redisConfigToken") RedisStandaloneConfiguration redisConfigToken) {
LettuceClientConfiguration clientConfiguration = LettucePoolingClientConfiguration.builder()
.poolConfig(config).commandTimeout(Duration.ofMillis(config.getMaxWaitMillis())).build();
return new LettuceConnectionFactory(redisConfigToken, clientConfiguration);
}
@Bean(name = "redisTempletToken")
public RedisTemplate<String, Object> redisTemplateToken(@Qualifier("lettuceFactoryToken") LettuceConnectionFactory redisConfigToken) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(redisConfigToken);
RedisSerializer<String> redisSerializer = new StringRedisSerializer();
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);
template.setKeySerializer(redisSerializer);
template.setValueSerializer(jackson2JsonRedisSerializer);
template.setHashValueSerializer(jackson2JsonRedisSerializer);
return template;
}
@Bean("redisConfigUuid")
@ConfigurationProperties(prefix = "spring.redis.uuid")
public RedisStandaloneConfiguration redisConfigUuid() {
return getRedisStandaloneConfiguration(uuidDatabase, uuidHost, uuidPassword, uuidPort);
}
@Bean("lettuceFactoryUuid")
public LettuceConnectionFactory factoryUuid(GenericObjectPoolConfig config, @Qualifier("redisConfigUuid") RedisStandaloneConfiguration redisConfigUuid) {
LettuceClientConfiguration clientConfiguration = LettucePoolingClientConfiguration.builder()
.poolConfig(config).commandTimeout(Duration.ofMillis(config.getMaxWaitMillis())).build();
return new LettuceConnectionFactory(redisConfigUuid, clientConfiguration);
}
@Bean(name = "redisTempletUuid")
public RedisTemplate<String, Object> redisTemplateUuid(@Qualifier("lettuceFactoryUuid") LettuceConnectionFactory redisConfigUuid) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(redisConfigUuid);
RedisSerializer<String> redisSerializer = new StringRedisSerializer();
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);
template.setKeySerializer(redisSerializer);
template.setValueSerializer(jackson2JsonRedisSerializer);
template.setHashValueSerializer(jackson2JsonRedisSerializer);
return template;
}
@Bean("redisConfigCache")
@ConfigurationProperties(prefix = "spring.redis.cache")
@Primary()
public RedisStandaloneConfiguration redisConfigCache() {
return getRedisStandaloneConfiguration(cacheDatabase, cacheHost, cachePassword, cachePort);
}
@Bean("lettuceFactoryCache")
@Primary()
public LettuceConnectionFactory factoryCache(GenericObjectPoolConfig config, @Qualifier("redisConfigCache") RedisStandaloneConfiguration redisConfigCache) {
LettuceClientConfiguration clientConfiguration = LettucePoolingClientConfiguration.builder()
.poolConfig(config).commandTimeout(Duration.ofMillis(config.getMaxWaitMillis())).build();
return new LettuceConnectionFactory(redisConfigCache, clientConfiguration);
}
@Bean(name = "redisTempletCache")
@Primary()
public RedisTemplate<String, Object> redisTemplateCache(@Qualifier("lettuceFactoryCache") LettuceConnectionFactory redisConfigCache) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(redisConfigCache);
RedisSerializer<String> redisSerializer = new StringRedisSerializer();
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);
template.setKeySerializer(redisSerializer);
template.setValueSerializer(jackson2JsonRedisSerializer);
template.setHashValueSerializer(jackson2JsonRedisSerializer);
return template;
}
}

View File

@ -0,0 +1,56 @@
package com.chinaunicom.mall.ebtp.common.config;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.ByteArrayHttpMessageConverter;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.ResourceHttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.http.converter.support.AllEncompassingFormHttpMessageConverter;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
import java.util.List;
/**
* @author dino
* @description:
* @date 2020/10/27 10:43
*/
//@Configuration
public class WebConfig extends WebMvcConfigurationSupport {
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
converters.add(new ByteArrayHttpMessageConverter());
converters.add(new StringHttpMessageConverter());
converters.add(new ResourceHttpMessageConverter());
converters.add(new AllEncompassingFormHttpMessageConverter());
converters.add(new StringHttpMessageConverter());
converters.add(longToStringConverter());
}
/**
* 将返回给前端的Long和long统一转化成字符串
*
* @return
*/
@Bean
public MappingJackson2HttpMessageConverter longToStringConverter() {
MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
ObjectMapper mapper = new ObjectMapper();
SimpleModule simpleModule = new SimpleModule();
//Long
simpleModule.addSerializer(Long.class, ToStringSerializer.instance);
//long
simpleModule.addSerializer(Long.TYPE, ToStringSerializer.instance);
mapper.registerModule(simpleModule);
converter.setObjectMapper(mapper);
return converter;
}
}

View File

@ -0,0 +1,19 @@
package com.chinaunicom.mall.ebtp.common.constant;
/**
* @author dino
* @description: 公用常量
* @date 2020/10/21 15:06
*/
public interface CommonConstants {
/**
* 删除
*/
String STATUS_DEL = "deleted";
/**
* 正常
*/
String STATUS_NORMAL = "normal";
}

View File

@ -0,0 +1,55 @@
package com.chinaunicom.mall.ebtp.common.constant;
/**
* 服务名称
*
* @author dino
* @date 2020/11/14 14:16
*/
public interface ServiceNameConstants {
/**
* 项目服务
*/
String PROJECT_SERVICE = "ebtp-mall-project";
/**
* 招标公告、邀请函、应答文件服务
*/
String BID_SERVICE = "ebtp-mall-bid";
/**
* 评审配置结构化服务
*/
String RSMS_SERVICE = "ebtp-mall-rsms";
/**
* 费用设置
*/
String EXPENSES_SERVICE = "ebtp-mall-expenses";
/**
* 应答格式
*/
String RESPS_SERVICE = "ebtp-mall-resps";
/**
* 开标大厅
*/
String OPEN_SERVICE = "ebtp-mall-open";
/**
* 投标服务
*/
String TENDER_SERVICE = "ebtp-mall-tender";
/**
* 解密服务
*/
String CRYPT_SERVICE = "ebtp-mall-crypt";
/**
* 流程服务
*/
String PROCESS_SERVICE = "ebtp-mall-process";
}

View File

@ -0,0 +1,59 @@
package com.chinaunicom.mall.ebtp.common.exception.common;
import com.chinaunicom.mall.ebtp.common.exception.service.BusinessExceptionAssert;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* 公共错误提示信息
* @author daixc
* @date 2020/10/10
*/
@Getter
@AllArgsConstructor
public enum CommonExceptionEnum implements BusinessExceptionAssert {
/**
* 数据为空
*/
FRAME_EXCEPTION_COMMON_NOT_FIND(100001, "数据为空!"),
/**
* 数据不存在
*/
FRAME_EXCEPTION_COMMON_NOT_EXIST(100002, "数据不存在!"),
/**
* 数据修改失败
*/
FRAME_EXCEPTION_COMMON_NOT_UPDATE(100003,"数据修改失败,请刷新后重试!"),
/**
* id为空
*/
FRAME_EXCEPTION_COMMON_ID_IS_NULL(100004, "id为空"),
/**
* 数据已存在
*/
FRAME_EXCEPTION_COMMON_REPEAT(100005, "数据已存在"),
/**
* 数据已存在
*/
FRAME_EXCEPTION_COMMON_ID_FORMAT(100006, "id格式错误"),
/**
* 数据错误
*/
FRAME_EXCEPTION_COMMON_DATA__ERROR(100007, "数据错误"),
/**
* 自定义输出内容
*/
FRAME_EXCEPTION_COMMON_DATA_OTHER_ERROR(100999, "");
/**
* 返回码
*/
private int code;
/**
* 返回消息
*/
private String message;
}

View File

@ -0,0 +1,40 @@
package com.chinaunicom.mall.ebtp.common.exception.entity;
import com.chinaunicom.mall.ebtp.common.exception.service.IResponseEnum;
import lombok.Getter;
import lombok.Setter;
/**
* 统一异常类实体
*
* @author 付庆吉
* @date 2020-09-14
*/
@Getter
@Setter
public class BusinessException extends RuntimeException {
private static final long serialVersionUID = 1L;
private Integer code;
private String message;
public BusinessException(IResponseEnum iResponseEnum, String message) {
super(message);
this.code = iResponseEnum.getCode();
this.message = message;
}
public BusinessException(IResponseEnum iResponseEnum, String message, Throwable cause) {
super(message, cause);
this.code = iResponseEnum.getCode();
this.message = message;
}
}

View File

@ -0,0 +1 @@
package com.chinaunicom.mall.ebtp.common.exception;

View File

@ -0,0 +1,131 @@
package com.chinaunicom.mall.ebtp.common.exception.service;
import com.chinaunicom.mall.ebtp.common.exception.entity.BusinessException;
import java.util.List;
/**
* 通用断言接口
*
* @author 付庆吉
* @date 2020-09-14
*/
public interface Assert {
/**
* 创建异常
*
* @param args
* @return
*/
BusinessException newException(Object... args);
/**
* 创建异常
*
* @param t
* @param args
* @return
*/
BusinessException newException(Throwable t, Object... args);
/**
* 费用管理专用异常
* @param key
* @return
*/
BusinessException newExpensesExceptionBykey(String key);
/**
* <p>断言对象<code>obj</code>非空。如果对象<code>obj</code>为空,则抛出异常
*
* @param obj 待判断对象
*/
default void assertNotNull(Object obj) {
if (obj == null) {
throw newException(obj);
}
}
/**
* <p>断言对象<code>args</code>非空。如果对象<code>args</code>为null或空字符串则抛出异常
*
* @param args 待判断字符串
*/
default void assertStrNotNull(String... args) {
this.assertNotNull(args);
for (String arg : args) {
if (arg == null || arg.isEmpty()) {
throw newException(arg);
}
}
}
/**
* 根据传参抛出异常,则抛出异常
*
* @param t 验证结果
*/
default void customValid(boolean t) {
if (t) {
throw newException();
}
}
/**
* 抛出异常
*/
default void throwException() {
throw newException();
}
/**
* <p>断言对象<code>obj</code>非空。如果对象<code>obj</code>为空,则抛出异常
* 费用管理专用
* @param obj 待判断对象
*/
default void assertNotNullByKey(String key,Object obj) {
if (obj == null) {
throw newExpensesExceptionBykey(key);
}
}
/**
* 判断String非空使用
* 费用管理专用
* @param obj 待判断对象
*/
default void assertStringNotNullByKey(String key,Object obj) {
if (obj == null || "".equals(obj.toString())) {
throw newExpensesExceptionBykey(key);
}
}
/**
* 根据传参抛出异常,则抛出异常
*
* @param t 验证结果
*/
default void customValidName(String name,boolean t) {
if (t) {
throw newExpensesExceptionBykey(name);
}
}
/**
* <p>断言对象<code>list</code>非空。如果对象<code>list</code>为空,则抛出异常
* name 抛出异常名称
* 费用管理专用
* @param list 待判断对象
*/
default void assertListNotNullByName(String name, List list) {
if (list !=null && list.size()>0) {
}else{
throw newExpensesExceptionBykey(name);
}
}
}

View File

@ -0,0 +1,46 @@
package com.chinaunicom.mall.ebtp.common.exception.service;
import com.chinaunicom.mall.ebtp.common.exception.entity.BusinessException;
import java.text.MessageFormat;
/**
* 初始化异常及断言接口所有自定义异常Enum均需实现此接口
* <p>
* 自定义异常枚举中年必须有code、message
*
* @author 付庆吉
* @date 2020-09-14
*/
public interface BusinessExceptionAssert extends IResponseEnum, Assert {
@Override
default BusinessException newException(Object... args) {
String msg = MessageFormat.format(this.getMessage(), args);
return new BusinessException(this, msg);
}
@Override
default BusinessException newException(Throwable t, Object... args) {
String msg = MessageFormat.format(this.getMessage(), args);
return new BusinessException(this, msg, t);
}
/**
* 费用管理专用
* @param key
* @return
*/
@Override
default BusinessException newExpensesExceptionBykey(String key) {
return new BusinessException(this, key+this.getMessage());
}
}

View File

@ -0,0 +1,268 @@
package com.chinaunicom.mall.ebtp.common.exception.service;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.exceptions.ExceptionUtil;
import com.chinaunicom.mall.ebtp.common.base.entity.BaseResponse;
import com.chinaunicom.mall.ebtp.common.exception.entity.BusinessException;
import com.chinaunicom.mall.ebtp.common.util.JsonUtils;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.dao.DataAccessException;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.http.HttpStatus;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 异常处理
* 拦截BindException异常返回HttpStatus是400的绑定错误信息
* 拦截FrameException异常返回HttpStatus是406的业务处理错误信息(支持自定义状态码)
* 拦截Exception异常返回HttpStatus是500服务器内部异常
*
* @author fqj
* @date 2020年9月3日 11:42:25
*/
@Slf4j
@ControllerAdvice
@ResponseBody
@ConditionalOnProperty(name = "mconfig.exception-handle-enabled", matchIfMissing = true)
public class BusinessExceptionHandlerAdvice {
/**
* 业务异常处理
*
* @param request 请求
* @param exception ServiceErrorException异常对象
* @return 响应
*/
@ExceptionHandler(value = BusinessException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public BaseResponse<String> serviceErrorException(HttpServletRequest request, BusinessException exception) {
//堆栈信息转为字符串
log.info(ExceptionUtil.stacktraceToString(exception));
Map<String, Object> body = new HashMap<>();
body.put("path", request.getRequestURI());
return BaseResponse.fail(exception.getCode(), exception.getMessage(), Convert.toStr(body));
}
/**
* hibernate valid 验证异常拦截
*
* @param request 请求
* @param exception ServiceErrorException异常对象
* @return 响应
*/
@ExceptionHandler(value = MethodArgumentNotValidException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public BaseResponse<String> handleInvalidMethodArgException(HttpServletRequest request, MethodArgumentNotValidException exception) {
//堆栈信息转为字符串
log.info(ExceptionUtil.stacktraceToString(exception));
//按需重新封装需要返回的错误信息
List<ArgumentInvalidResult> invalidArguments = new ArrayList<>();
//解析原错误信息,封装后返回,此处返回非法的字段名称,原始值,错误信息
BindingResult bindingResult = exception.getBindingResult();
for (FieldError error : bindingResult.getFieldErrors()) {
ArgumentInvalidResult invalidArgument = new ArgumentInvalidResult();
invalidArgument.setDefaultMessage(error.getDefaultMessage());
invalidArgument.setField(error.getField());
invalidArgument.setRejectedValue(error.getRejectedValue());
invalidArguments.add(invalidArgument);
}
Map<String, Object> body = new HashMap<>();
body.put("errors", JsonUtils.objectToJson(invalidArguments));
body.put("error", HttpStatus.BAD_REQUEST.getReasonPhrase());
body.put("path", request.getRequestURI());
return BaseResponse.fail(HttpStatus.BAD_REQUEST.value(), "参数错误", Convert.toStr(body));
}
/**
* 参数绑定异常
*
* @param request 请求
* @param exception BindException异常对象
* @return 响应
*/
@ExceptionHandler(value = BindException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public BaseResponse<String> methodArgumentNotValidHandler(
HttpServletRequest request, BindException exception) {
//按需重新封装需要返回的错误信息
List<ArgumentInvalidResult> invalidArguments = new ArrayList<>();
//解析原错误信息,封装后返回,此处返回非法的字段名称,原始值,错误信息
for (FieldError error : exception.getBindingResult().getFieldErrors()) {
ArgumentInvalidResult invalidArgument = new ArgumentInvalidResult();
invalidArgument.setDefaultMessage(error.getDefaultMessage());
invalidArgument.setField(error.getField());
invalidArgument.setRejectedValue(error.getRejectedValue());
invalidArguments.add(invalidArgument);
}
Map<String, Object> body = new HashMap<>();
body.put("errors", JsonUtils.objectToJson(invalidArguments));
body.put("error", HttpStatus.BAD_REQUEST.getReasonPhrase());
body.put("path", request.getRequestURI());
return BaseResponse.fail(HttpStatus.BAD_REQUEST.value(), "参数错误", Convert.toStr(body));
}
/**
* 请求方式异常
*
* @param request 请求
* @param exception HttpRequestMethodNotSupportedException异常对象
* @return 响应
*/
@ExceptionHandler(HttpRequestMethodNotSupportedException.class)
@ResponseStatus(HttpStatus.METHOD_NOT_ALLOWED)
public BaseResponse<String> handleMethodNotSupportedException(HttpServletRequest request, HttpRequestMethodNotSupportedException exception) {
Map<String, Object> body = new HashMap<>();
body.put("errors", exception.getMessage());
body.put("error", HttpStatus.METHOD_NOT_ALLOWED.getReasonPhrase());
body.put("path", request.getRequestURI());
return BaseResponse.fail(HttpStatus.METHOD_NOT_ALLOWED.value(), "错误的请求方式", Convert.toStr(body));
}
/**
* 参数缺失
*
* @param request 请求
* @param exception MissingServletRequestParameterException异常对象
* @return 响应
*/
@ExceptionHandler(MissingServletRequestParameterException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public BaseResponse<String> handleMissingParameterException(HttpServletRequest request, MissingServletRequestParameterException exception) {
Map<String, Object> body = new HashMap<>();
body.put("errors", exception.getMessage());
body.put("error", HttpStatus.BAD_REQUEST.getReasonPhrase());
body.put("path", request.getRequestURI());
return BaseResponse.fail(HttpStatus.BAD_REQUEST.value(), "参数缺失", Convert.toStr(body));
}
// ----------------------------data--------------------------------------
/**
* 数据库异常
*
* @param request 请求
* @param exception DataAccessException异常对象
* @return 响应
*/
@ExceptionHandler(DataAccessException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public BaseResponse<String> handlerDataAccessException(HttpServletRequest request, DataAccessException exception) {
log.error(ExceptionUtil.stacktraceToString(exception));
Map<String, Object> body = new HashMap<>();
body.put("errors", exception.getMessage());
body.put("error", HttpStatus.BAD_REQUEST.getReasonPhrase());
body.put("path", request.getRequestURI());
return BaseResponse.fail(HttpStatus.BAD_REQUEST.value(), "数据库异常", Convert.toStr(body));
}
/**
* 数据不存在
*
* @param request 请求
* @param exception EmptyResultDataAccessException异常对象
* @return 响应
*/
@ExceptionHandler(EmptyResultDataAccessException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public BaseResponse<String> handleDataEmptyException(HttpServletRequest request, EmptyResultDataAccessException exception) {
Map<String, Object> body = new HashMap<>();
body.put("errors", exception.getMessage());
body.put("error", HttpStatus.BAD_REQUEST.getReasonPhrase());
body.put("path", request.getRequestURI());
return BaseResponse.fail(HttpStatus.BAD_REQUEST.value(), "数据不存在", Convert.toStr(body));
}
/**
* 请求方式异常
*
* @param request 请求
* @param exception DuplicateKeyException异常对象
* @return 响应
*/
@ExceptionHandler(DuplicateKeyException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public BaseResponse<String> handleDataDualException(HttpServletRequest request, DuplicateKeyException exception) {
Map<String, Object> body = new HashMap<>();
body.put("errors", exception.getMessage());
body.put("error", HttpStatus.BAD_REQUEST.getReasonPhrase());
body.put("path", request.getRequestURI());
return BaseResponse.fail(HttpStatus.BAD_REQUEST.value(), "数据重复插入", Convert.toStr(body));
}
/**
* 方法参数类型不匹配异常
*
* @param request 请求
* @param exception MethodArgumentTypeMismatchException异常对象
* @return 响应
*/
@ExceptionHandler(MethodArgumentTypeMismatchException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public BaseResponse<String> handleMethodArgumentTypeException(HttpServletRequest request, MethodArgumentTypeMismatchException exception) {
Map<String, Object> body = new HashMap<>();
body.put("errors", exception.getMessage());
body.put("error", HttpStatus.BAD_REQUEST.getReasonPhrase());
body.put("path", request.getRequestURI());
return BaseResponse.fail(HttpStatus.BAD_REQUEST.value(), "参数类型不匹配", Convert.toStr(body));
}
/**
* 全局异常处理
*
* @param request 请求
* @param exception Exception异常对象
* @return 响应
*/
@ExceptionHandler(value = Exception.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public BaseResponse<String> handleException(HttpServletRequest request, Exception exception) {
//堆栈信息转为字符串
log.info(ExceptionUtil.stacktraceToString(exception));
Map<String, Object> body = new HashMap<>();
body.put("errors", exception.getMessage());
body.put("error", HttpStatus.INTERNAL_SERVER_ERROR.getReasonPhrase());
body.put("path", request.getRequestURI());
return BaseResponse.fail(HttpStatus.INTERNAL_SERVER_ERROR.value(), "网络异常", Convert.toStr(body));
}
/**
* 参数异常
*/
@Getter
@Setter
class ArgumentInvalidResult {
/**
* 字段名
*/
private String field;
/**
* 输入的错误值
*/
private Object rejectedValue;
/**
* 错误信息
*/
private String defaultMessage;
}
}

View File

@ -0,0 +1,12 @@
package com.chinaunicom.mall.ebtp.common.exception.service;
public interface IResponseEnum {
int getCode();
String getMessage();
}

View File

@ -0,0 +1,40 @@
package com.chinaunicom.mall.ebtp.common.log;
import com.chinaunicom.mall.ebtp.common.log.enums.OperationType;
import java.lang.annotation.*;
/**
* <p>
* 日志自定义注解实现类
* </p>
* @author daixc
* @date 2020-09-07
*/
@Documented
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface OperationLogDetail {
/**
* 方法描述,可使用占位符获取参数:{{tel}}
*/
String detail() default "";
/**
* 方法执行模块名称
*/
String operationModel() default "";
/**
* 日志等级:自己定义
*/
int level() default 0;
/**
* 操作类型(enum):主要是select,insert,update,delete
*/
OperationType operationType() default OperationType.UNKNOWN;
}

View File

@ -0,0 +1,145 @@
package com.chinaunicom.mall.ebtp.common.log.aop;
import com.chinaunicom.mall.ebtp.common.base.entity.BaseCacheUser;
import com.chinaunicom.mall.ebtp.common.base.service.IBaseCacheUserService;
import com.chinaunicom.mall.ebtp.common.log.entity.OperationLog;
import com.chinaunicom.mall.ebtp.common.log.OperationLogDetail;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
/**
* <p>
* 自定义注解进行log日志的输出
* 定义切面完成日志的拦截和参数的输出等操作
* </p>
* @author daixc
* @date 2020-09-07
*/
@Slf4j
@Aspect
@Component
public class LogAspect {
@Resource
private IBaseCacheUserService cacheUserService;
@Pointcut("@annotation(com.chinaunicom.mall.ebtp.common.log.OperationLogDetail)")
public void operationLog(){}
/**
* 环绕增强相当于MethodInterceptor
*/
@Around("operationLog()")
public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
Object res = null;
long time = System.currentTimeMillis();
try {
res = joinPoint.proceed();
time = System.currentTimeMillis() - time;
return res;
} finally {
try {
//方法执行完成后增加日志
addOperationLog(joinPoint,res,time);
}catch (Exception e){
e.printStackTrace();
log.error("LogAspect 操作失败:" + e.getMessage());
}
}
}
/**
* 对日志进行填充值
* @param joinPoint 切点
* @param res 方法参数
* @param time 执行时间
*/
private void addOperationLog(JoinPoint joinPoint, Object res, long time){
ObjectMapper mapper = new ObjectMapper();
MethodSignature signature = (MethodSignature)joinPoint.getSignature();
OperationLog operationLog = new OperationLog();
BaseCacheUser user = cacheUserService.getCacheUser();
try {
operationLog.setRunTime(time);
operationLog.setReturnValue(mapper.writeValueAsString(res));
operationLog.setId(UUID.randomUUID().toString());
operationLog.setArgs(mapper.writeValueAsString(joinPoint.getArgs()));
operationLog.setCreateTime(new Date());
operationLog.setMethod(signature.getDeclaringTypeName() + "." + signature.getName());
if(null != user){
operationLog.setUserId(user.getUserId().toString());
operationLog.setUserName(user.getFullName());
}
OperationLogDetail annotation = signature.getMethod().getAnnotation(OperationLogDetail.class);
if(annotation != null){
operationLog.setLevel(annotation.level());
operationLog.setDescribe(getDetail(((MethodSignature)joinPoint.getSignature()).getParameterNames(),joinPoint.getArgs(),annotation));
operationLog.setOperationType(annotation.operationType().getValue());
operationLog.setOperationModel(annotation.operationModel());
}
} catch (JsonProcessingException e) {
log.error("日志转换json错误"+ signature.getDeclaringTypeName() + "." + signature.getName());
}
log.info("操作日志:" + operationLog.toString());
}
/**
* 对当前登录用户和占位符处理
* @param argNames 方法参数名称数组
* @param args 方法参数数组
* @param annotation 注解信息
* @return 返回处理后的描述
*/
private String getDetail(String[] argNames, Object[] args, OperationLogDetail annotation){
Map<String, Object> map = new HashMap<>(4);
for(int i = 0;i < argNames.length;i++){
map.put(argNames[i],args[i]);
}
String detail = annotation.detail();
try {
detail = annotation.detail();
for (Map.Entry<String, Object> entry : map.entrySet()) {
String k = entry.getKey();
Object v = entry.getValue();
detail = detail.replace("{{" + k + "}}",new ObjectMapper().writeValueAsString(v));
}
}catch (Exception e){
e.printStackTrace();
}
return detail;
}
@Before("operationLog()")
public void doBeforeAdvice(JoinPoint joinPoint){
log.info("进入方法前执行.....");
}
/**
* 后置异常通知
*/
@AfterThrowing("operationLog()")
public void throwss(JoinPoint jp){
log.info("方法异常时执行.....");
}
}

View File

@ -0,0 +1,95 @@
package com.chinaunicom.mall.ebtp.common.log.entity;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
/**
* <p>
* 操作日志实体类
* </p>
* @author daixc
* @date 2020-09-07
*/
@Data
public class OperationLog implements Serializable{
/**
* 编号
*/
private String id;
/**
* 创建时间
*/
private Date createTime;
/**
* 日志等级
*/
private Integer level;
/**
* 被操作的模块
*/
private String operationModel;
/**
* 方法名
*/
private String method;
/**
* 参数
*/
private String args;
/**
* 操作人id
*/
private String userId;
/**
* 操作人
*/
private String userName;
/**
* 日志描述
*/
private String describe;
/**
* 操作类型
*/
private String operationType;
/**
* 方法运行时间
*/
private Long runTime;
/**
* 方法返回值
*/
private String returnValue;
@Override
public String toString() {
return "OperationLog{" +
"id='" + id + '\'' +
", createTime=" + createTime +
", level=" + level +
", operationModel='" + operationModel + '\'' +
", method='" + method + '\'' +
", args='" + args + '\'' +
", userId='" + userId + '\'' +
", userName='" + userName + '\'' +
", describe='" + describe + '\'' +
", operationType='" + operationType + '\'' +
", runTime=" + runTime +
", returnValue='" + returnValue + '\'' +
'}';
}
}

View File

@ -0,0 +1,35 @@
package com.chinaunicom.mall.ebtp.common.log.enums;
/**
* <p>
* 日志类型枚举类
* delete|select|update|insert|unknown
* </p>
* @author daixc
* @date 2020-09-07
*/
public enum OperationType {
/**
* 操作类型
*/
UNKNOWN("unknown"),
DELETE("delete"),
SELECT("select"),
UPDATE("update"),
INSERT("insert");
private String value;
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
OperationType(String s) {
this.value = s;
}
}

View File

@ -0,0 +1 @@
package com.chinaunicom.mall.ebtp.common.log;

View File

@ -0,0 +1,41 @@
package com.chinaunicom.mall.ebtp.common.util;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* 获得request
*
* @author daixc
* @date 2020/10/16
* @version 1.0
*
*/
public final class HttpContextUtils {
/**
* 静态类不可构造
*/
private HttpContextUtils() {
}
/**
* 获得HttpServletRequest
*
* @return HttpServletRequest
*/
public static HttpServletRequest getHttpServletRequest() {
return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
}
/**
* 获得HttpServletResponse
* @return
*/
public static HttpServletResponse getHttpServletResponse() {
return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();
}
}

View File

@ -0,0 +1,54 @@
package com.chinaunicom.mall.ebtp.common.util;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;
import javax.servlet.http.HttpServletRequest;
/**
* IP地址
*/
public class IPUtils {
private IPUtils() {
}
private static final Logger LOG = LoggerFactory.getLogger(IPUtils.class);
@SuppressWarnings("PMD")
public static final String LOCAL_V4 = "127.0.0.1";
@SuppressWarnings("PMD")
public static final String LOCAL_V6 = "0:0:0:0:0:0:0:1";
/**
* 获取IP地址
* <p>
* 使用Nginx等反向代理软件 则不能通过request.getRemoteAddr()获取IP地址
* 如果使用了多级反向代理的话X-Forwarded-For的值并不止一个而是一串IP地址X-Forwarded-For中第一个非unknown的有效IP字符串则为真实IP地址
*/
public static String getIpAddr(HttpServletRequest request) {
try {
final String un = "unknown";
String ip = request.getHeader("x-forwarded-for");
if (StringUtils.isEmpty(ip) || un.equalsIgnoreCase(ip)) {
ip = request.getHeader("Proxy-Client-IP");
}
if (StringUtils.isEmpty(ip) || ip.length() == 0 || un.equalsIgnoreCase(ip)) {
ip = request.getHeader("WL-Proxy-Client-IP");
}
if (StringUtils.isEmpty(ip) || un.equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_CLIENT_IP");
}
if (StringUtils.isEmpty(ip) || un.equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_X_FORWARDED_FOR");
}
if (StringUtils.isEmpty(ip) || un.equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
}
return ip.equals(LOCAL_V6) ? LOCAL_V4 : ip;
} catch (Exception e) {
LOG.error("IPUtils ERROR ", e);
}
return null;
}
}

View File

@ -0,0 +1,111 @@
package com.chinaunicom.mall.ebtp.common.util;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.exceptions.ExceptionUtil;
import com.baomidou.mybatisplus.extension.api.R;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jdk8.Jdk8Module;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.module.paramnames.ParameterNamesModule;
import lombok.extern.slf4j.Slf4j;
import java.util.ArrayList;
import java.util.List;
/**
* json util
*
* @author 付庆吉
* @date 2020-09-16
*/
@Slf4j
public class JsonUtils {
// 定义jackson对象
private static final ObjectMapper MAPPER = new ObjectMapper();
/**
* 将对象转换成json字符串。
* <p>Title: pojoToJson</p>
* <p>Description: </p>
*
* @param data
* @return
*/
public static String objectToJson(Object data) {
try {
MAPPER.registerModule(new ParameterNamesModule())
.registerModule(new Jdk8Module())
.registerModule(new JavaTimeModule());
return MAPPER.writeValueAsString(data);
} catch (JsonProcessingException e) {
log.info(ExceptionUtil.stacktraceToString(e));
}
return null;
}
/**
* 将json结果集转化为对象
*
* @param jsonData json数据
* @param beanType 对象中的object类型
* @return
*/
public static <T> T jsonToPojo(String jsonData, Class<T> beanType) {
try {
return MAPPER.readValue(jsonData, beanType);
} catch (Exception e) {
log.info(ExceptionUtil.stacktraceToString(e));
}
return null;
}
/**
* 将json数据转换成pojo对象list
* <p>Title: jsonToList</p>
* <p>Description: </p>
*
* @param jsonData
* @param beanType
* @return
*/
public static <T> List<T> jsonToList(String jsonData, Class<T> beanType) {
JavaType javaType = MAPPER.getTypeFactory().constructParametricType(List.class, beanType);
try {
List<T> list = MAPPER.readValue(jsonData, javaType);
return list;
} catch (Exception e) {
log.info(ExceptionUtil.stacktraceToString(e));
}
return null;
}
/**
* 将List<DTO>转为List<VO>
* <p>Title: jsonToList</p>
* <p>Description: </p>
*
* @param jsonData
* @param beanType
* @return
*/
public static <T> List<T> jsonToList(List jsonData, Class<T> beanType) {
List<T> list = new ArrayList<>();
try {
for (Object jd : jsonData) {
T t = beanType.newInstance();
BeanUtil.copyProperties(jd,t);
list.add(t);
}
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return list;
}
}

View File

@ -0,0 +1,35 @@
package com.chinaunicom.mall.ebtp.common.util;
import cn.hutool.core.util.IdUtil;
import org.springframework.beans.factory.annotation.Value;
/**
* <P>配置文件参数注入</P>
* 获取配置文件的参数配置
*
* @author daixc
* @date 2020/10/10
*/
public class PropertyUtils {
/**
* 终端ID
*/
@Value("${mconfig.work-id}")
public static long WORKER_ID;
/**
* 数据中心ID
*/
@Value("${mconfig.datacenter-id}")
public static long DATACENTER_ID;
/**
* 生成雪花id
*
* @return
*/
public static Long getSnowflakeId() {
return IdUtil.getSnowflake(WORKER_ID, DATACENTER_ID).nextId();
}
}

View File

@ -0,0 +1,50 @@
package com.chinaunicom.mall.ebtp.common.util;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
/**
* <p> Title: SpringContextUtil </p>
*
* @date 2020-09-16
* @version 1.0
*/
@Component
public class SpringContextBeansUtil implements ApplicationContextAware {
private static ApplicationContext applicationContext;
/**
* 实现ApplicationContextAware接口的回调方法设置上下文环境
*/
@Override
public void setApplicationContext(ApplicationContext applicationContext){
setApplication(applicationContext);
}
private static void setApplication(ApplicationContext context){
applicationContext = context;
}
public static ApplicationContext getApplicationContext(){
return applicationContext;
}
/**
* 获取对象
* @return Object 一个以所给名字注册的bean的实例 (service注解方式自动生成以首字母小写的类名为bean name)
*/
public static Object getBean(String name) throws BeansException {
return applicationContext.getBean(name);
}
public static <T> T getBean(Class<T> clazz) {
return getApplicationContext().getBean(clazz);
}
public static boolean containsBean(String beanName) {
return applicationContext.containsBean(beanName);
}
}

View File

@ -0,0 +1 @@
package com.chinaunicom.mall.ebtp.common.util;