diff --git a/pom.xml b/pom.xml index a1b1520..2480824 100644 --- a/pom.xml +++ b/pom.xml @@ -392,6 +392,8 @@ mall-ebtp-cloud-feign-starter mall-ebtp-cloud-log-starter mall-ebtp-cloud-seata-starter + uboot-common + uboot-core diff --git a/uboot-common/pom.xml b/uboot-common/pom.xml new file mode 100644 index 0000000..6e98212 --- /dev/null +++ b/uboot-common/pom.xml @@ -0,0 +1,76 @@ + + 4.0.0 + + + com.chinaunicom.ebtp + mall-ebtp-cloud-parent + 0.0.1 + ../mall-ebtp-cloud-parent + + + com.chinaunicom.ebtp + uboot-common + 0.0.1 + uboot-common + + + + com.chinaunicom.ebtp + mall-ebtp-cloud-mvc-starter + true + + + + com.chinaunicom.ebtp + mall-ebtp-cloud-jpa-starter + true + + + + com.chinaunicom.ebtp + mall-ebtp-cloud-eureka-starter + true + + + + com.chinaunicom.ebtp + mall-ebtp-cloud-feign-starter + true + + + + com.chinaunicom.ebtp + mall-ebtp-cloud-swagger-starter + true + + + + com.chinaunicom.ebtp + mall-ebtp-cloud-redis-starter + true + + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + 1.8 + 1.8 + + + + + + src/main/resources + true + + + + diff --git a/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/UbootCommonApplication.java b/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/UbootCommonApplication.java new file mode 100644 index 0000000..f6fa5a5 --- /dev/null +++ b/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/UbootCommonApplication.java @@ -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); + } +} diff --git a/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/base/controller/BaseController.java b/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/base/controller/BaseController.java new file mode 100644 index 0000000..f7401a5 --- /dev/null +++ b/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/base/controller/BaseController.java @@ -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 { +} diff --git a/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/base/dao/IBaseMapper.java b/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/base/dao/IBaseMapper.java new file mode 100644 index 0000000..78583d5 --- /dev/null +++ b/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/base/dao/IBaseMapper.java @@ -0,0 +1,14 @@ +package com.chinaunicom.mall.ebtp.common.base.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +public interface IBaseMapper extends BaseMapper { + + + /** + * 逻辑删除数据 + * + * @param id + */ + public int deleteOff(Long id); +} diff --git a/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/base/entity/BaseCacheUser.java b/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/base/entity/BaseCacheUser.java new file mode 100644 index 0000000..0c505c8 --- /dev/null +++ b/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/base/entity/BaseCacheUser.java @@ -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; + +} diff --git a/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/base/entity/BaseEntity.java b/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/base/entity/BaseEntity.java new file mode 100644 index 0000000..bd088b1 --- /dev/null +++ b/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/base/entity/BaseEntity.java @@ -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; +} diff --git a/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/base/entity/BasePage.java b/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/base/entity/BasePage.java new file mode 100644 index 0000000..efef00b --- /dev/null +++ b/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/base/entity/BasePage.java @@ -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 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 records; +} diff --git a/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/base/entity/BasePageRequest.java b/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/base/entity/BasePageRequest.java new file mode 100644 index 0000000..3e9c91d --- /dev/null +++ b/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/base/entity/BasePageRequest.java @@ -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; + } +} \ No newline at end of file diff --git a/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/base/entity/BasePageResponse.java b/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/base/entity/BasePageResponse.java new file mode 100644 index 0000000..02c58a6 --- /dev/null +++ b/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/base/entity/BasePageResponse.java @@ -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 implements Serializable { + + private static final long serialVersionUID = 1L; + + private Integer code; + + private boolean success; + + private String message; + + @JsonInclude(JsonInclude.Include.NON_NULL) + private IPage data; + + + public static BasePageResponse success(IPage p) { + return new BasePageResponse<>(ResponseEnum.SUCCESS.getCode(), + Boolean.TRUE, + ResponseEnum.SUCCESS.getMessage(), + p); + } + + + public static BasePageResponse success(String message, IPage p) { + return new BasePageResponse<>(ResponseEnum.SUCCESS.getCode(), + Boolean.TRUE, + message, + p); + } + + + public static BasePageResponse fail(String message) { + return new BasePageResponse<>(ResponseEnum.SUCCESS.getCode(), + Boolean.FALSE, + message, + null); + } + + + public static BasePageResponse fail(int code, String message) { + return new BasePageResponse<>(code, + Boolean.FALSE, + message, + null); + } + + +} \ No newline at end of file diff --git a/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/base/entity/BaseResponse.java b/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/base/entity/BaseResponse.java new file mode 100644 index 0000000..16e0486 --- /dev/null +++ b/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/base/entity/BaseResponse.java @@ -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 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 success() { + return new BaseResponse<>(ResponseEnum.SUCCESS.getCode(), + Boolean.TRUE, + ResponseEnum.SUCCESS.getMessage(), + ""); + } + + + public static BaseResponse success(T data) { + return new BaseResponse<>(ResponseEnum.SUCCESS.getCode(), + Boolean.TRUE, + ResponseEnum.SUCCESS.getMessage(), + data); + } + + + public static BaseResponse success(String message, T data) { + return new BaseResponse<>(ResponseEnum.SUCCESS.getCode(), + Boolean.TRUE, + message, + data); + } + + + public static BaseResponse fail() { + return new BaseResponse<>(ResponseEnum.ERROR.getCode(), + Boolean.FALSE, + ResponseEnum.ERROR.getMessage(), + ""); + } + + public static BaseResponse fail(String message) { + return new BaseResponse<>(ResponseEnum.ERROR.getCode(), + Boolean.FALSE, + message, + ""); + } + + public static BaseResponse fail(Integer code, String message) { + return new BaseResponse<>(code, + Boolean.FALSE, + message, + ""); + } + + public static BaseResponse fail(T data) { + return new BaseResponse<>(ResponseEnum.ERROR.getCode(), + Boolean.FALSE, + ResponseEnum.ERROR.getMessage(), + data); + } + + public static BaseResponse fail(String message, T data) { + return new BaseResponse<>(ResponseEnum.ERROR.getCode(), + Boolean.FALSE, + message, + data); + } + + public static BaseResponse fail(Integer code, String message, T data) { + return new BaseResponse(code, + Boolean.FALSE, + message, + data); + } + + +} \ No newline at end of file diff --git a/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/base/entity/DictProject.java b/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/base/entity/DictProject.java new file mode 100644 index 0000000..f78a098 --- /dev/null +++ b/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/base/entity/DictProject.java @@ -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; + + +} diff --git a/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/base/enums/ResponseEnum.java b/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/base/enums/ResponseEnum.java new file mode 100644 index 0000000..2a44359 --- /dev/null +++ b/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/base/enums/ResponseEnum.java @@ -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; + + +} \ No newline at end of file diff --git a/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/base/package-info.java b/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/base/package-info.java new file mode 100644 index 0000000..29bc1ac --- /dev/null +++ b/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/base/package-info.java @@ -0,0 +1 @@ +package com.chinaunicom.mall.ebtp.common.base; \ No newline at end of file diff --git a/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/base/service/IBaseCacheUserService.java b/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/base/service/IBaseCacheUserService.java new file mode 100644 index 0000000..638ae3f --- /dev/null +++ b/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/base/service/IBaseCacheUserService.java @@ -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(); +} diff --git a/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/base/service/IBaseService.java b/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/base/service/IBaseService.java new file mode 100644 index 0000000..432d6c8 --- /dev/null +++ b/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/base/service/IBaseService.java @@ -0,0 +1,7 @@ +package com.chinaunicom.mall.ebtp.common.base.service; + +import com.baomidou.mybatisplus.extension.service.IService; + +public interface IBaseService extends IService { + +} diff --git a/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/base/service/impl/BaseCacheUserServiceImpl.java b/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/base/service/impl/BaseCacheUserServiceImpl.java new file mode 100644 index 0000000..39d7527 --- /dev/null +++ b/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/base/service/impl/BaseCacheUserServiceImpl.java @@ -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; + } +} diff --git a/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/base/service/impl/BaseServiceImpl.java b/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/base/service/impl/BaseServiceImpl.java new file mode 100644 index 0000000..bb0ec4b --- /dev/null +++ b/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/base/service/impl/BaseServiceImpl.java @@ -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, T> extends ServiceImpl implements IBaseService { + + +} diff --git a/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/config/CustomJacksonTypeHandler.java b/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/config/CustomJacksonTypeHandler.java new file mode 100644 index 0000000..88c95e6 --- /dev/null +++ b/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/config/CustomJacksonTypeHandler.java @@ -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 { + private static ObjectMapper objectMapper; + private Class type; + + static { + objectMapper = new ObjectMapper(); + objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); + objectMapper.registerModule(new JavaTimeModule()); + } + + public CustomJacksonTypeHandler(Class 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)); + } +} \ No newline at end of file diff --git a/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/config/CustomLocalDateTimeTypeHandler.java b/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/config/CustomLocalDateTimeTypeHandler.java new file mode 100644 index 0000000..0c0d5ba --- /dev/null +++ b/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/config/CustomLocalDateTimeTypeHandler.java @@ -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 { + + 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); + } +} diff --git a/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/config/FeignConfig.java b/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/config/FeignConfig.java new file mode 100644 index 0000000..ed74cfc --- /dev/null +++ b/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/config/FeignConfig.java @@ -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); + } + } + +} diff --git a/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/config/JacksonConfig.java b/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/config/JacksonConfig.java new file mode 100644 index 0000000..827955f --- /dev/null +++ b/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/config/JacksonConfig.java @@ -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; + } +} diff --git a/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/config/RedisJedisConfig.java b/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/config/RedisJedisConfig.java new file mode 100644 index 0000000..e612732 --- /dev/null +++ b/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/config/RedisJedisConfig.java @@ -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 redisTemplateToken(@Qualifier("jedisFactoryToken") RedisConnectionFactory redisConnectionFactory) { +// return createRedisTemplate(redisConnectionFactory); +// } +// @Bean(name = "redisTempletUuid") +// public RedisTemplate redisTemplateUuid(@Qualifier("jedisFactoryUuid") RedisConnectionFactory redisConnectionFactory) { +// return createRedisTemplate(redisConnectionFactory); +// } +// @Bean(name = "redisTempletCache") +// @Primary() +// public RedisTemplate redisTemplateCache(@Qualifier("jedisFactoryCache") RedisConnectionFactory redisConnectionFactory) { +// return createRedisTemplate(redisConnectionFactory); +// } +// /** +// * json 实现 redisTemplate +// *

+// * @return +// */ +// public RedisTemplate createRedisTemplate(RedisConnectionFactory factory) { +// RedisTemplate 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; +// } + + +} diff --git a/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/config/RedisLettuceConfig.java b/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/config/RedisLettuceConfig.java new file mode 100644 index 0000000..cd3ad14 --- /dev/null +++ b/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/config/RedisLettuceConfig.java @@ -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 redisTemplateToken(@Qualifier("lettuceFactoryToken") LettuceConnectionFactory redisConfigToken) { + RedisTemplate template = new RedisTemplate<>(); + template.setConnectionFactory(redisConfigToken); + RedisSerializer 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 redisTemplateUuid(@Qualifier("lettuceFactoryUuid") LettuceConnectionFactory redisConfigUuid) { + RedisTemplate template = new RedisTemplate<>(); + template.setConnectionFactory(redisConfigUuid); + RedisSerializer 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 redisTemplateCache(@Qualifier("lettuceFactoryCache") LettuceConnectionFactory redisConfigCache) { + RedisTemplate template = new RedisTemplate<>(); + template.setConnectionFactory(redisConfigCache); + RedisSerializer 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; + } + + +} diff --git a/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/config/WebConfig.java b/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/config/WebConfig.java new file mode 100644 index 0000000..f54f7fd --- /dev/null +++ b/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/config/WebConfig.java @@ -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> 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; + } + + +} diff --git a/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/constant/CommonConstants.java b/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/constant/CommonConstants.java new file mode 100644 index 0000000..36d5e61 --- /dev/null +++ b/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/constant/CommonConstants.java @@ -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"; +} diff --git a/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/constant/ServiceNameConstants.java b/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/constant/ServiceNameConstants.java new file mode 100644 index 0000000..5df6062 --- /dev/null +++ b/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/constant/ServiceNameConstants.java @@ -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"; +} diff --git a/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/exception/common/CommonExceptionEnum.java b/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/exception/common/CommonExceptionEnum.java new file mode 100644 index 0000000..197b192 --- /dev/null +++ b/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/exception/common/CommonExceptionEnum.java @@ -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; + +} diff --git a/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/exception/entity/BusinessException.java b/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/exception/entity/BusinessException.java new file mode 100644 index 0000000..03042c5 --- /dev/null +++ b/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/exception/entity/BusinessException.java @@ -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; + + } + +} + diff --git a/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/exception/package-info.java b/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/exception/package-info.java new file mode 100644 index 0000000..6c74bdb --- /dev/null +++ b/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/exception/package-info.java @@ -0,0 +1 @@ +package com.chinaunicom.mall.ebtp.common.exception; \ No newline at end of file diff --git a/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/exception/service/Assert.java b/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/exception/service/Assert.java new file mode 100644 index 0000000..0bb0ae7 --- /dev/null +++ b/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/exception/service/Assert.java @@ -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); + /** + *

断言对象obj非空。如果对象obj为空,则抛出异常 + * + * @param obj 待判断对象 + */ + default void assertNotNull(Object obj) { + if (obj == null) { + throw newException(obj); + } + } + + /** + *

断言对象args非空。如果对象args为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(); + } + + /** + *

断言对象obj非空。如果对象obj为空,则抛出异常 + * 费用管理专用 + * @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); + } + } + + /** + *

断言对象list非空。如果对象list为空,则抛出异常 + * name 抛出异常名称 + * 费用管理专用 + * @param list 待判断对象 + */ + default void assertListNotNullByName(String name, List list) { + if (list !=null && list.size()>0) { + + }else{ + throw newExpensesExceptionBykey(name); + } + } + + +} diff --git a/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/exception/service/BusinessExceptionAssert.java b/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/exception/service/BusinessExceptionAssert.java new file mode 100644 index 0000000..f45e6dc --- /dev/null +++ b/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/exception/service/BusinessExceptionAssert.java @@ -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均需实现此接口 + *

+ * 自定义异常枚举中年必须有: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()); + } + +} \ No newline at end of file diff --git a/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/exception/service/BusinessExceptionHandlerAdvice.java b/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/exception/service/BusinessExceptionHandlerAdvice.java new file mode 100644 index 0000000..e2c1781 --- /dev/null +++ b/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/exception/service/BusinessExceptionHandlerAdvice.java @@ -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 serviceErrorException(HttpServletRequest request, BusinessException exception) { + //堆栈信息转为字符串 + log.info(ExceptionUtil.stacktraceToString(exception)); + Map 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 handleInvalidMethodArgException(HttpServletRequest request, MethodArgumentNotValidException exception) { + //堆栈信息转为字符串 + log.info(ExceptionUtil.stacktraceToString(exception)); + //按需重新封装需要返回的错误信息 + List 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 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 methodArgumentNotValidHandler( + HttpServletRequest request, BindException exception) { + //按需重新封装需要返回的错误信息 + List 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 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 handleMethodNotSupportedException(HttpServletRequest request, HttpRequestMethodNotSupportedException exception) { + Map 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 handleMissingParameterException(HttpServletRequest request, MissingServletRequestParameterException exception) { + Map 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 handlerDataAccessException(HttpServletRequest request, DataAccessException exception) { + log.error(ExceptionUtil.stacktraceToString(exception)); + Map 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 handleDataEmptyException(HttpServletRequest request, EmptyResultDataAccessException exception) { + Map 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 handleDataDualException(HttpServletRequest request, DuplicateKeyException exception) { + Map 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 handleMethodArgumentTypeException(HttpServletRequest request, MethodArgumentTypeMismatchException exception) { + Map 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 handleException(HttpServletRequest request, Exception exception) { + //堆栈信息转为字符串 + log.info(ExceptionUtil.stacktraceToString(exception)); + Map 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; + } +} \ No newline at end of file diff --git a/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/exception/service/IResponseEnum.java b/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/exception/service/IResponseEnum.java new file mode 100644 index 0000000..32bb484 --- /dev/null +++ b/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/exception/service/IResponseEnum.java @@ -0,0 +1,12 @@ +package com.chinaunicom.mall.ebtp.common.exception.service; + + +public interface IResponseEnum { + + + int getCode(); + + String getMessage(); + + +} diff --git a/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/log/OperationLogDetail.java b/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/log/OperationLogDetail.java new file mode 100644 index 0000000..ced4e88 --- /dev/null +++ b/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/log/OperationLogDetail.java @@ -0,0 +1,40 @@ +package com.chinaunicom.mall.ebtp.common.log; + + +import com.chinaunicom.mall.ebtp.common.log.enums.OperationType; + +import java.lang.annotation.*; + +/** + *

+ * 日志自定义注解实现类 + *

+ * @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; +} diff --git a/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/log/aop/LogAspect.java b/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/log/aop/LogAspect.java new file mode 100644 index 0000000..60d7261 --- /dev/null +++ b/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/log/aop/LogAspect.java @@ -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; + +/** + *

+ * 自定义注解进行log日志的输出 + * 定义切面完成日志的拦截和参数的输出等操作 + *

+ * @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 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 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("方法异常时执行....."); + } +} diff --git a/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/log/entity/OperationLog.java b/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/log/entity/OperationLog.java new file mode 100644 index 0000000..9737c1d --- /dev/null +++ b/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/log/entity/OperationLog.java @@ -0,0 +1,95 @@ +package com.chinaunicom.mall.ebtp.common.log.entity; + +import lombok.Data; + +import java.io.Serializable; +import java.util.Date; + +/** + *

+ * 操作日志实体类 + *

+ * @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 + '\'' + + '}'; + } +} diff --git a/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/log/enums/OperationType.java b/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/log/enums/OperationType.java new file mode 100644 index 0000000..221a2b0 --- /dev/null +++ b/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/log/enums/OperationType.java @@ -0,0 +1,35 @@ +package com.chinaunicom.mall.ebtp.common.log.enums; + +/** + *

+ * 日志类型枚举类 + * delete|select|update|insert|unknown + *

+ * @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; + } +} diff --git a/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/log/package-info.java b/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/log/package-info.java new file mode 100644 index 0000000..2e0e85d --- /dev/null +++ b/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/log/package-info.java @@ -0,0 +1 @@ +package com.chinaunicom.mall.ebtp.common.log; \ No newline at end of file diff --git a/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/util/HttpContextUtils.java b/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/util/HttpContextUtils.java new file mode 100644 index 0000000..15b86ae --- /dev/null +++ b/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/util/HttpContextUtils.java @@ -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(); + } +} diff --git a/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/util/IPUtils.java b/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/util/IPUtils.java new file mode 100644 index 0000000..2ca3034 --- /dev/null +++ b/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/util/IPUtils.java @@ -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地址 + *

+ * 使用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; + } +} diff --git a/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/util/JsonUtils.java b/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/util/JsonUtils.java new file mode 100644 index 0000000..8c734ab --- /dev/null +++ b/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/util/JsonUtils.java @@ -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字符串。 + *

Title: pojoToJson

+ *

Description:

+ * + * @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 jsonToPojo(String jsonData, Class beanType) { + try { + return MAPPER.readValue(jsonData, beanType); + } catch (Exception e) { + log.info(ExceptionUtil.stacktraceToString(e)); + } + return null; + } + + /** + * 将json数据转换成pojo对象list + *

Title: jsonToList

+ *

Description:

+ * + * @param jsonData + * @param beanType + * @return + */ + public static List jsonToList(String jsonData, Class beanType) { + JavaType javaType = MAPPER.getTypeFactory().constructParametricType(List.class, beanType); + try { + List list = MAPPER.readValue(jsonData, javaType); + return list; + } catch (Exception e) { + log.info(ExceptionUtil.stacktraceToString(e)); + } + return null; + } + + /** + * 将List转为List + *

Title: jsonToList

+ *

Description:

+ * + * @param jsonData + * @param beanType + * @return + */ + public static List jsonToList(List jsonData, Class beanType) { + List 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; + } + + +} diff --git a/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/util/PropertyUtils.java b/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/util/PropertyUtils.java new file mode 100644 index 0000000..1c0768d --- /dev/null +++ b/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/util/PropertyUtils.java @@ -0,0 +1,35 @@ +package com.chinaunicom.mall.ebtp.common.util; + +import cn.hutool.core.util.IdUtil; +import org.springframework.beans.factory.annotation.Value; + +/** + *

配置文件参数注入

+ * 获取配置文件的参数配置 + * + * @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(); + } +} diff --git a/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/util/SpringContextBeansUtil.java b/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/util/SpringContextBeansUtil.java new file mode 100644 index 0000000..0dba01e --- /dev/null +++ b/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/util/SpringContextBeansUtil.java @@ -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; + +/** +*

Title: SpringContextUtil

+ * +* @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 getBean(Class clazz) { + return getApplicationContext().getBean(clazz); + } + public static boolean containsBean(String beanName) { + return applicationContext.containsBean(beanName); + } + +} diff --git a/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/util/package-info.java b/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/util/package-info.java new file mode 100644 index 0000000..288e38c --- /dev/null +++ b/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/util/package-info.java @@ -0,0 +1 @@ +package com.chinaunicom.mall.ebtp.common.util; \ No newline at end of file diff --git a/uboot-common/src/main/resources/application.yml b/uboot-common/src/main/resources/application.yml new file mode 100644 index 0000000..4ec631c --- /dev/null +++ b/uboot-common/src/main/resources/application.yml @@ -0,0 +1,69 @@ +server: + port: 8081 + servlet: + context-path: / + +spring: + aop: + auto: true #开启spring的aop配置 + proxy-target-class: true + application: + name: uboot-common + + kafka: + bootstrap-servers: 127.0.0.1:9092 + producer: + # 写入失败时,重试次数。当leader节点失效,一个repli节点会替代成为leader节点,此时可能出现写入失败, + # 当retris为0时,produce不会重复。retirs重发,此时repli节点完全成为leader节点,不会产生消息丢失。 + retries: 0 + # 每次批量发送消息的数量,produce积累到一定数据,一次发送 + batch-size: 2 + # produce积累数据一次发送,缓存大小达到buffer.memory就发送数据 + buffer-memory: 33554432 + #procedure要求leader在考虑完成请求之前收到的确认数,用于控制发送记录在服务端的持久化,其值可以为如下: + #acks = 0 如果设置为零,则生产者将不会等待来自服务器的任何确认,该记录将立即添加到套接字缓冲区并视为已发送。在这种情况下,无法保证服务器已收到记录,并且重试配置将不会生效(因为客户端通常不会知道任何故障),为每条记录返回的偏移量始终设置为-1。 + #acks = 1 这意味着leader会将记录写入其本地日志,但无需等待所有副本服务器的完全确认即可做出回应,在这种情况下,如果leader在确认记录后立即失败,但在将数据复制到所有的副本服务器之前,则记录将会丢失。 + #acks = all 这意味着leader将等待完整的同步副本集以确认记录,这保证了只要至少一个同步副本服务器仍然存活,记录就不会丢失,这是最强有力的保证,这相当于acks = -1的设置。 + #可以设置的值为:all, -1, 0, 1 + acks: 1 + key-serializer: org.apache.kafka.common.serialization.StringSerializer + value-serializer: org.apache.kafka.common.serialization.StringSerializer + consumer: + group-id: user-group + auto-offset-reset: earliest + enable-auto-commit: true + auto-commit-interval: 100 + key-deserializer: org.apache.kafka.common.serialization.StringDeserializer + value-deserializer: org.apache.kafka.common.serialization.StringDeserializer + #=========redis基础配置========= + redis: + lettuce: + # jedis: + pool: + maxTotal: 50 + minIdle: 1 + maxWaitMillis: 5000 + maxIdle: 5 + testOnBorrow: true + testOnReturn: true + testWhileIdle: true + token: + database: 0 + host: 125.32.114.204 + port: 16379 + password: redis@CC1234 + timeout: 6000 + uuid: + database: 1 + host: 125.32.114.204 + port: 16379 + password: redis@CC1234 + timeout: 6000 + cache: + database: 2 + host: 125.32.114.204 + port: 16379 + password: redis@CC1234 + timeout: 6000 + + diff --git a/uboot-core/.gitignore b/uboot-core/.gitignore new file mode 100644 index 0000000..549e00a --- /dev/null +++ b/uboot-core/.gitignore @@ -0,0 +1,33 @@ +HELP.md +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ diff --git a/uboot-core/pom.xml b/uboot-core/pom.xml new file mode 100644 index 0000000..ff81ff7 --- /dev/null +++ b/uboot-core/pom.xml @@ -0,0 +1,85 @@ + + + + 4.0.0 + + + com.chinaunicom.ebtp + mall-ebtp-cloud-parent + 0.0.1 + ../mall-ebtp-cloud-parent + + + com.chinaunicom.ebtp + uboot-core + 0.0.1 + uboot-core + + + + + com.chinaunicom.mall.ebtp + uboot-common + 1.0-SNAPSHOT + + + + com.chinaunicom.ebtp + mall-ebtp-cloud-jpa-starter + + + + com.chinaunicom.ebtp + mall-ebtp-cloud-eureka-starter + + + + com.chinaunicom.ebtp + mall-ebtp-cloud-feign-starter + + + + com.chinaunicom.ebtp + mall-ebtp-cloud-swagger-starter + + + + com.chinaunicom.ebtp + mall-ebtp-cloud-redis-starter + + + + com.baomidou + mybatis-plus-generator + + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + true + true + + + + + + src/main/resources + true + + + src/main/resources + + **/*.html + + + + + + \ No newline at end of file diff --git a/uboot-core/src/main/java/com/chinaunicom/mall/ebtp/core/UbootCoreApplication.java b/uboot-core/src/main/java/com/chinaunicom/mall/ebtp/core/UbootCoreApplication.java new file mode 100644 index 0000000..5e05ec6 --- /dev/null +++ b/uboot-core/src/main/java/com/chinaunicom/mall/ebtp/core/UbootCoreApplication.java @@ -0,0 +1,19 @@ +package com.chinaunicom.mall.ebtp.core; + +import org.mybatis.spring.annotation.MapperScan; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.netflix.eureka.EnableEurekaClient; +import org.springframework.cloud.openfeign.EnableFeignClients; +import org.springframework.context.annotation.ComponentScan; + +@MapperScan({"com.chinaunicom.mall.ebtp.core.**.dao"}) +@SpringBootApplication +@ComponentScan(basePackages = {"com.chinaunicom.mall.ebtp.common"}) +@EnableFeignClients +@EnableEurekaClient +public class UbootCoreApplication { + public static void main(String[] args) { + SpringApplication.run(UbootCoreApplication.class, args); + } +} diff --git a/uboot-core/src/main/java/com/chinaunicom/mall/ebtp/core/config/MybatisPlusConfig.java b/uboot-core/src/main/java/com/chinaunicom/mall/ebtp/core/config/MybatisPlusConfig.java new file mode 100644 index 0000000..dfe59df --- /dev/null +++ b/uboot-core/src/main/java/com/chinaunicom/mall/ebtp/core/config/MybatisPlusConfig.java @@ -0,0 +1,36 @@ +package com.chinaunicom.mall.ebtp.core.config; + + +import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor; +import com.baomidou.mybatisplus.extension.plugins.pagination.optimize.JsqlParserCountOptimize; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + + +/** + * 配置数据源 + */ +@Configuration +//@MapperScan(basePackages = "com.chinaunicom.mall.ebtp.**.dao") +public class MybatisPlusConfig { + + + + /** + * 分页插件 + * @return + */ + @Bean + public PaginationInterceptor paginationInterceptor() { + PaginationInterceptor paginationInterceptor = new PaginationInterceptor(); + // 设置请求的页面大于最大页后操作, true调回到首页,false 继续请求 默认false + // paginationInterceptor.setOverflow(false); + // 设置最大单页限制数量,默认 500 条,-1 不受限制 + // paginationInterceptor.setLimit(500); + // 开启 count 的 join 优化,只针对部分 left join + paginationInterceptor.setCountSqlParser(new JsqlParserCountOptimize(true)); + return paginationInterceptor; + } + + +} diff --git a/uboot-core/src/main/java/com/chinaunicom/mall/ebtp/core/config/MybatisPlusMetaObjectHandler.java b/uboot-core/src/main/java/com/chinaunicom/mall/ebtp/core/config/MybatisPlusMetaObjectHandler.java new file mode 100644 index 0000000..08332f1 --- /dev/null +++ b/uboot-core/src/main/java/com/chinaunicom/mall/ebtp/core/config/MybatisPlusMetaObjectHandler.java @@ -0,0 +1,76 @@ +package com.chinaunicom.mall.ebtp.core.config; + +import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler; +import com.chinaunicom.mall.ebtp.common.base.service.impl.BaseCacheUserServiceImpl; +import com.chinaunicom.mall.ebtp.common.constant.CommonConstants; +import lombok.extern.slf4j.Slf4j; +import org.apache.ibatis.reflection.MetaObject; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.time.LocalDateTime; + +/** + * 自动填充公共字段 + * + * @author: 付庆吉 + * @program: mybatis-plus + * @date: 2019-09-03 20:01 + **/ +@Slf4j +@Component +public class MybatisPlusMetaObjectHandler implements MetaObjectHandler { + + + @Autowired + private BaseCacheUserServiceImpl userService; + + /** + * 插入元对象字段填充(用于插入时对公共字段的填充) + * + * @param metaObject 元对象 + */ + @Override + public void insertFill(MetaObject metaObject) { + Object obj = getFieldValByName("createBy", metaObject); + if (obj == null) { + setFieldValByName("createBy",userService.getCacheUser().getUserId() , metaObject); + } + obj = getFieldValByName("createDate", metaObject); + if (obj == null) { + setFieldValByName("createDate", LocalDateTime.now(), metaObject); + } + + obj = getFieldValByName("updateBy", metaObject); + if (obj == null) { + setFieldValByName("updateBy", userService.getCacheUser().getUserId(), metaObject); + } + obj = getFieldValByName("updateDate", metaObject); + if (obj == null) { + setFieldValByName("updateDate", LocalDateTime.now(), metaObject); + } + + obj = getFieldValByName("tenantId", metaObject); + if (obj == null) { + setFieldValByName("tenantId", "ebtp_mall", metaObject); + } + obj = getFieldValByName("tenantName", metaObject); + if (obj == null) { + setFieldValByName("tenantName", "ebtp_mall", metaObject); + } + setFieldValByName("deleteFlag", CommonConstants.STATUS_NORMAL, metaObject); + } + + /** + * 更新元对象字段填充(用于更新时对公共字段的填充) + * + * @param metaObject 元对象 + */ + @Override + public void updateFill(MetaObject metaObject) { + setFieldValByName("updateBy", userService.getCacheUser().getUserId(), metaObject); + setFieldValByName("updateDate", LocalDateTime.now(), metaObject); + setFieldValByName("lastUpdateTime", LocalDateTime.now(), metaObject); + + } +} diff --git a/uboot-core/src/main/resources/application.yml b/uboot-core/src/main/resources/application.yml new file mode 100644 index 0000000..b62e8c6 --- /dev/null +++ b/uboot-core/src/main/resources/application.yml @@ -0,0 +1,92 @@ +server: + port: 8080 + servlet: + context-path: / + +spring: + aop: + auto: true #开启spring的aop配置 + proxy-target-class: true + application: + name: uboot-core + + datasource: + driver-class-name: com.mysql.cj.jdbc.Driver + username: mall3-ebtp-dev + password: mall3-ebtp-dev + url: jdbc:mysql://125.32.114.204:13306/ebtp-cloud?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&useSSL=false&allowPublicKeyRetrieval=true + + jackson: + date-format: yyyy-MM-dd HH:mm:ss + time-zone: GMT+8 + serialization: + write-dates-as-timestamps: false + kafka: + bootstrap-servers: 127.0.0.1:9092 + producer: + # 写入失败时,重试次数。当leader节点失效,一个repli节点会替代成为leader节点,此时可能出现写入失败, + # 当retris为0时,produce不会重复。retirs重发,此时repli节点完全成为leader节点,不会产生消息丢失。 + retries: 0 + # 每次批量发送消息的数量,produce积累到一定数据,一次发送 + batch-size: 2 + # produce积累数据一次发送,缓存大小达到buffer.memory就发送数据 + buffer-memory: 33554432 + #procedure要求leader在考虑完成请求之前收到的确认数,用于控制发送记录在服务端的持久化,其值可以为如下: + #acks = 0 如果设置为零,则生产者将不会等待来自服务器的任何确认,该记录将立即添加到套接字缓冲区并视为已发送。在这种情况下,无法保证服务器已收到记录,并且重试配置将不会生效(因为客户端通常不会知道任何故障),为每条记录返回的偏移量始终设置为-1。 + #acks = 1 这意味着leader会将记录写入其本地日志,但无需等待所有副本服务器的完全确认即可做出回应,在这种情况下,如果leader在确认记录后立即失败,但在将数据复制到所有的副本服务器之前,则记录将会丢失。 + #acks = all 这意味着leader将等待完整的同步副本集以确认记录,这保证了只要至少一个同步副本服务器仍然存活,记录就不会丢失,这是最强有力的保证,这相当于acks = -1的设置。 + #可以设置的值为:all, -1, 0, 1 + acks: 1 + key-serializer: org.apache.kafka.common.serialization.StringSerializer + value-serializer: org.apache.kafka.common.serialization.StringSerializer + consumer: + group-id: user-group + auto-offset-reset: earliest + enable-auto-commit: true + auto-commit-interval: 100 + key-deserializer: org.apache.kafka.common.serialization.StringDeserializer + value-deserializer: org.apache.kafka.common.serialization.StringDeserializer + #=========redis基础配置========= + redis: + lettuce: +# jedis: + pool: + maxTotal: 50 + minIdle: 1 + maxWaitMillis: 5000 + maxIdle: 5 + testOnBorrow: true + testOnReturn: true + testWhileIdle: true + token: + database: 0 + host: 125.32.114.204 + port: 16379 + password: redis@CC1234 + timeout: 6000 + uuid: + database: 1 + host: 125.32.114.204 + port: 16379 + password: redis@CC1234 + timeout: 6000 + cache: + database: 2 + host: 125.32.114.204 + port: 16379 + password: redis@CC1234 + timeout: 6000 + thymeleaf: + prefix: classpath:/templet/ + cache: false + suffix: .html + mode: LEGACYHTML5 + encoding: utf-8 + servlet: + content-type: text/html + +mconfig: + swagger-ui-open: true + exception-handle-enabled: true + seata-open-enabled: false + diff --git a/uboot-core/src/main/resources/file.conf b/uboot-core/src/main/resources/file.conf new file mode 100644 index 0000000..31954cf --- /dev/null +++ b/uboot-core/src/main/resources/file.conf @@ -0,0 +1,66 @@ +transport { + # tcp udt unix-domain-socket + type = "TCP" + #NIO NATIVE + server = "NIO" + #enable heartbeat + heartbeat = true + # the client batch send request enable + enableClientBatchSendRequest = true + #thread factory for netty + threadFactory { + bossThreadPrefix = "NettyBoss" + workerThreadPrefix = "NettyServerNIOWorker" + serverExecutorThread-prefix = "NettyServerBizHandler" + shareBossWorker = false + clientSelectorThreadPrefix = "NettyClientSelector" + clientSelectorThreadSize = 1 + clientWorkerThreadPrefix = "NettyClientWorkerThread" + # netty boss thread size,will not be used for UDT + bossThreadSize = 1 + #auto default pin or 8 + workerThreadSize = "default" + } + shutdown { + # when destroy server, wait seconds + wait = 3 + } + serialization = "seata" + compressor = "none" +} +service { + #transaction service group mapping + vgroupMapping.uboot-core-fescar-service-group = "default" + #only support when registry.type=file, please don't set multiple addresses + default.grouplist = "127.0.0.1:8091" + #degrade, current not support + enableDegrade = false + #disable seata + disableGlobalTransaction = false +} + +client { + rm { + asyncCommitBufferLimit = 10000 + lock { + retryInterval = 10 + retryTimes = 30 + retryPolicyBranchRollbackOnConflict = true + } + reportRetryCount = 5 + tableMetaCheckEnable = false + reportSuccessEnable = false + } + tm { + commitRetryCount = 5 + rollbackRetryCount = 5 + } + undo { + dataValidation = true + logSerialization = "jackson" + logTable = "undo_log" + } + log { + exceptionRate = 100 + } +} \ No newline at end of file diff --git a/uboot-core/src/main/resources/seata.conf b/uboot-core/src/main/resources/seata.conf new file mode 100644 index 0000000..030b596 --- /dev/null +++ b/uboot-core/src/main/resources/seata.conf @@ -0,0 +1,21 @@ +## --------------------------------------------------------------------------- +## Licensed to the Apache Software Foundation (ASF) under one or more +## contributor license agreements. See the NOTICE file distributed with +## this work for additional information regarding copyright ownership. +## The ASF licenses this file to You under the Apache License, Version 2.0 +## (the "License"); you may not use this file except in compliance with +## the License. You may obtain a copy of the License at +## +## http://www.apache.org/licenses/LICENSE-2.0 +## +## Unless required by applicable law or agreed to in writing, software +## distributed under the License is distributed on an "AS IS" BASIS, +## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +## See the License for the specific language governing permissions and +## limitations under the License. +## --------------------------------------------------------------------------- + +client { + application.id = uboot-core + transaction.service.group = uboot-core-fescar-service-group +}