diff --git a/nla-common/pom.xml b/nla-common/pom.xml
index 0467dff..7f3f23b 100644
--- a/nla-common/pom.xml
+++ b/nla-common/pom.xml
@@ -15,42 +15,63 @@
11
11
-
-
- org.projectlombok
- lombok
-
-
-
- org.springframework.boot
- spring-boot-starter-web
-
-
- mysql
- mysql-connector-java
-
-
- com.baomidou
- mybatis-plus-boot-starter
-
-
-
- com.baomidou
- mybatis-plus-generator
- 3.4.1
-
-
-
- org.apache.velocity
- velocity-engine-core
- 2.0
-
-
-
-
- io.springfox
- springfox-boot-starter
-
-
+
+
+ org.projectlombok
+ lombok
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+
+ org.hibernate
+ hibernate-validator
+ 6.0.1.Final
+
+
+ mysql
+ mysql-connector-java
+
+
+ com.baomidou
+ mybatis-plus-boot-starter
+
+
+
+ com.baomidou
+ mybatis-plus-generator
+ 3.4.1
+
+
+
+ org.apache.velocity
+ velocity-engine-core
+ 2.0
+
+
+
+
+ io.springfox
+ springfox-boot-starter
+
+
+
+ org.springframework.boot
+ spring-boot-starter-data-redis
+
+
+ io.lettuce
+ lettuce-core
+
+
+
+
+ redis.clients
+ jedis
+
+
diff --git a/nla-common/src/main/java/cn/nla/common/annotation/EncryptId.java b/nla-common/src/main/java/cn/nla/common/annotation/EncryptId.java
new file mode 100644
index 0000000..2ff5f27
--- /dev/null
+++ b/nla-common/src/main/java/cn/nla/common/annotation/EncryptId.java
@@ -0,0 +1,28 @@
+package cn.nla.common.annotation;
+
+import cn.nla.common.config.EncryptIdValidator;
+
+import javax.validation.Constraint;
+import javax.validation.Payload;
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.*;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+/**
+ * 自定义加密校验
+ */
+@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER})
+@Retention(RUNTIME)
+@Documented
+@Constraint(validatedBy = {EncryptIdValidator.class})
+public @interface EncryptId {
+ // 默认错误消息
+ String message() default "加密id格式错误";
+ // 分组
+ Class>[] groups() default {};
+ // 负载
+ Class extends Payload>[] payload() default {};
+}
diff --git a/nla-common/src/main/java/cn/nla/common/annotation/ResponseResult.java b/nla-common/src/main/java/cn/nla/common/annotation/ResponseResult.java
new file mode 100644
index 0000000..49715f8
--- /dev/null
+++ b/nla-common/src/main/java/cn/nla/common/annotation/ResponseResult.java
@@ -0,0 +1,20 @@
+package cn.nla.common.annotation;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+
+/**
+ * 该注解作业于类或者方法上,将返回值对象包装返回体结构
+ */
+@Retention(RUNTIME)
+@Target({TYPE, METHOD})
+@Documented
+public @interface ResponseResult {
+
+}
diff --git a/nla-common/src/main/java/cn/nla/common/config/EncryptIdValidator.java b/nla-common/src/main/java/cn/nla/common/config/EncryptIdValidator.java
new file mode 100644
index 0000000..7151bee
--- /dev/null
+++ b/nla-common/src/main/java/cn/nla/common/config/EncryptIdValidator.java
@@ -0,0 +1,23 @@
+package cn.nla.common.config;
+
+import cn.nla.common.annotation.EncryptId;
+import javax.validation.ConstraintValidator;
+import javax.validation.ConstraintValidatorContext;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+/**
+ * 自定义加密校验的方法
+ */
+public class EncryptIdValidator implements ConstraintValidator {
+ // 字符串的长度: 32~256,以字母a到f或数字0到9开头。
+ private static final Pattern PATTERN = Pattern.compile("^[a-f\\d]{32,256}$");
+ @Override
+ public boolean isValid(String value, ConstraintValidatorContext context) {
+ // 不为null才进行校验
+ if (value != null) {
+ Matcher matcher = PATTERN.matcher(value);
+ return matcher.find();
+ }
+ return true;
+ }
+}
diff --git a/nla-common/src/main/java/cn/nla/common/config/SwaggerConfiguration.java b/nla-common/src/main/java/cn/nla/common/config/SwaggerConfiguration.java
new file mode 100644
index 0000000..3e038fb
--- /dev/null
+++ b/nla-common/src/main/java/cn/nla/common/config/SwaggerConfiguration.java
@@ -0,0 +1,82 @@
+package cn.nla.common.config;
+
+import lombok.Data;
+import org.springframework.context.annotation.Bean;
+import org.springframework.http.HttpMethod;
+import org.springframework.stereotype.Component;
+import springfox.documentation.builders.*;
+import springfox.documentation.oas.annotations.EnableOpenApi;
+import springfox.documentation.schema.ScalarType;
+import springfox.documentation.service.*;
+import springfox.documentation.spi.DocumentationType;
+import springfox.documentation.spring.web.plugins.Docket;
+
+import java.util.List;
+
+/**
+ * Swagger配置
+ **/
+@Data
+@Component
+@EnableOpenApi
+public class SwaggerConfiguration {
+
+ /**
+ * 对用户服务端的接口文档
+ */
+ @Bean
+ public Docket userApiDoc() {
+ return new Docket(DocumentationType.OAS_30) // 版本3.0
+ .groupName("用户端接口文档")
+ .pathMapping("/")
+ //定义是否开启Swagger,false是关闭,可以通过变量去控制,线上关闭
+ .enable(true)
+ //配置文档的元信息
+ .apiInfo(apiInfo())
+ .select()
+ .apis(RequestHandlerSelectors.basePackage("cn.nla"))
+ //正则匹配请求路径,并分配到当前项目组
+ .paths(PathSelectors.ant("/user/**"))
+ .build()
+ // 新版SwaggerUI3.0
+ .globalRequestParameters(globalRequestParameters())
+ .globalResponses(HttpMethod.GET, getGlobalResponseMessage())
+ .globalResponses(HttpMethod.POST, getGlobalResponseMessage());
+ }
+
+
+ /**
+ * 接口基本信息配置
+ */
+ private ApiInfo apiInfo() {
+ return new ApiInfoBuilder()
+ .title("电商平台")
+ .description("微服务接口文档")
+ .contact(new Contact("yuan", "http://localhost", "yuanjs625@163.com"))
+ .version("v1.0")
+ .build();
+ }
+
+ /**
+ * 配置全局通用参数
+ */
+ private List globalRequestParameters() {
+ return List.of(new RequestParameterBuilder()
+ .name("token")
+ .description("登录令牌")
+ .in(ParameterType.HEADER)
+ .query(q -> q.model(m -> m.scalarModel(ScalarType.STRING)))
+ .required(false)
+ .build());
+ }
+
+ /**
+ * 生成通用的响应信息
+ */
+ private List getGlobalResponseMessage() {
+ return List.of(new ResponseBuilder()
+ .code("4xx")
+ .description("请求错误,根据code和msg检查")
+ .build());
+ }
+}
diff --git a/nla-common/src/main/java/cn/nla/common/config/WebConfig.java b/nla-common/src/main/java/cn/nla/common/config/WebConfig.java
new file mode 100644
index 0000000..4d6f8ff
--- /dev/null
+++ b/nla-common/src/main/java/cn/nla/common/config/WebConfig.java
@@ -0,0 +1,20 @@
+package cn.nla.common.config;
+
+import cn.nla.common.interceptor.ResponseResultInterceptor;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+import javax.annotation.Resource;
+
+/**
+ * 注册拦截器
+ */
+@Configuration
+public class WebConfig implements WebMvcConfigurer {
+ @Resource
+ private ResponseResultInterceptor responseResultInterceptor;
+ @Override
+ public void addInterceptors(InterceptorRegistry registry) {
+ registry.addInterceptor(responseResultInterceptor);
+ }
+}
diff --git a/nla-common/src/main/java/cn/nla/common/enums/BizCodeEnum.java b/nla-common/src/main/java/cn/nla/common/enums/BizCodeEnum.java
new file mode 100644
index 0000000..65b7e65
--- /dev/null
+++ b/nla-common/src/main/java/cn/nla/common/enums/BizCodeEnum.java
@@ -0,0 +1,88 @@
+package cn.nla.common.enums;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+@Getter
+@AllArgsConstructor
+public enum BizCodeEnum {
+
+ /**
+ * 通用操作码
+ */
+ OPS_REPEAT(110001,"重复操作"),
+ /**
+ * 系统相关
+ */
+ SYS_LOGIN(210001,"登录过期,请重新登录"),
+ SYS_NO_TOKEN(210002,"token不存在,请重新登录"),
+ SYS_NO_USER(210003,"loginUser对象为空"),
+ /**
+ * 购物车
+ */
+ CART_FAIL(220001,"添加购物车失败"),
+ /**
+ *验证码
+ */
+ CODE_TO_ERROR(240001,"接收号码不合规"),
+ CODE_LIMITED(240002,"验证码发送过快"),
+ CODE_ERROR(240003,"验证码错误"),
+ CODE_CAPTCHA_ERROR(240101,"图形验证码错误"),
+
+ /**
+ * 账号
+ */
+ ACCOUNT_REPEAT(250001,"账号已经存在"),
+ ACCOUNT_UNREGISTER(250002,"账号不存在"),
+ ACCOUNT_PWD_ERROR(250003,"账号或者密码错误"),
+ ACCOUNT_UNLOGIN(250004,"账号未登录"),
+ /**
+ * 优惠券
+ */
+ COUPON_CONDITION_ERROR(270001,"优惠券条件错误"),
+ COUPON_UNAVAILABLE(270002,"没有可用的优惠券"),
+ COUPON_NO_EXITS(270003,"优惠券不存在"),
+ COUPON_NO_STOCK(270005,"优惠券库存不足"),
+ COUPON_OUT_OF_LIMIT(270006,"优惠券领取超过限制次数"),
+ COUPON_OUT_OF_TIME(270407,"优惠券不在领取时间范围"),
+ COUPON_GET_FAIL(270407,"优惠券领取失败"),
+ COUPON_RECORD_LOCK_FAIL(270409,"优惠券锁定失败"),
+ /**
+ * 订单
+ */
+ ORDER_CONFIRM_COUPON_FAIL(280001,"创建订单-优惠券使用失败,不满足价格条件"),
+ ORDER_CONFIRM_PRICE_FAIL(280002,"创建订单-验价失败"),
+ ORDER_CONFIRM_LOCK_PRODUCT_FAIL(280003,"创建订单-商品库存不足锁定失败"),
+ ORDER_CONFIRM_ADD_STOCK_TASK_FAIL(280004,"创建订单-新增商品库存锁定任务"),
+ ORDER_CONFIRM_TOKEN_NOT_EXIST(280008,"订单令牌缺少"),
+ ORDER_CONFIRM_TOKEN_EQUAL_FAIL(280009,"订单令牌不正确"),
+ ORDER_CONFIRM_NOT_EXIST(280010,"订单不存在"),
+ ORDER_CONFIRM_CART_ITEM_NOT_EXIST(280011,"购物车商品项不存在"),
+ /**
+ * 收货地址
+ */
+ ADDRESS_ADD_FAIL(290001,"新增收货地址失败"),
+ ADDRESS_DEL_FAIL(290002,"删除收货地址失败"),
+ ADDRESS_NO_EXITS(290003,"地址不存在"),
+ /**
+ * 支付
+ */
+ PAY_ORDER_FAIL(300001,"创建支付订单失败"),
+ PAY_ORDER_CALLBACK_SIGN_FAIL(300002,"支付订单回调验证签失败"),
+ PAY_ORDER_CALLBACK_NOT_SUCCESS(300003,"创建支付订单失败"),
+ PAY_ORDER_NOT_EXIST(300005,"订单不存在"),
+ PAY_ORDER_STATE_ERROR(300006,"订单状态不正常"),
+ PAY_ORDER_PAY_TIMEOUT(300007,"订单支付超时"),
+ /**
+ * 流控操作
+ */
+ CONTROL_FLOW(500101,"限流控制"),
+ CONTROL_DEGRADE(500201,"降级控制"),
+ CONTROL_AUTH(500301,"认证控制"),
+ /**
+ * 文件相关
+ */
+ FILE_UPLOAD_USER_IMG_FAIL(600101,"用户头像文件上传失败");
+ private int code;
+ private String message;
+}
diff --git a/nla-common/src/main/java/cn/nla/common/exception/BizException.java b/nla-common/src/main/java/cn/nla/common/exception/BizException.java
new file mode 100644
index 0000000..cc37d9f
--- /dev/null
+++ b/nla-common/src/main/java/cn/nla/common/exception/BizException.java
@@ -0,0 +1,22 @@
+package cn.nla.common.exception;
+
+import cn.nla.common.enums.BizCodeEnum;
+import lombok.Getter;
+import lombok.Setter;
+
+@Getter
+@Setter
+public class BizException extends RuntimeException {
+ private int code;
+ private String msg;
+ public BizException(int code, String msg){
+ super(msg);
+ this.code = code;
+ this.msg = msg;
+ }
+ public BizException(BizCodeEnum bizCodeEnum){
+ super(bizCodeEnum.getMessage());
+ this.code = bizCodeEnum.getCode();
+ this.msg = bizCodeEnum.getMessage();
+ }
+}
diff --git a/nla-common/src/main/java/cn/nla/common/exception/CustomExceptionHandler.java b/nla-common/src/main/java/cn/nla/common/exception/CustomExceptionHandler.java
new file mode 100644
index 0000000..3cce007
--- /dev/null
+++ b/nla-common/src/main/java/cn/nla/common/exception/CustomExceptionHandler.java
@@ -0,0 +1,124 @@
+package cn.nla.common.exception;
+
+import cn.nla.common.annotation.ResponseResult;
+import cn.nla.common.util.JsonData;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.core.MethodParameter;
+import org.springframework.http.MediaType;
+import org.springframework.http.converter.HttpMessageConverter;
+import org.springframework.http.converter.HttpMessageNotReadableException;
+import org.springframework.http.server.ServerHttpRequest;
+import org.springframework.http.server.ServerHttpResponse;
+import org.springframework.validation.BindingResult;
+import org.springframework.validation.FieldError;
+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.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.validation.ConstraintViolationException;
+
+@Slf4j
+@ControllerAdvice
+public class CustomExceptionHandler implements ResponseBodyAdvice