From 56f7d4a8a59c1a69b6f83e8776ce199075c97493 Mon Sep 17 00:00:00 2001
From: bunny <1319900154@qq.com>
Date: Sat, 23 Mar 2024 14:35:02 +0800
Subject: [PATCH] =?UTF-8?q?feat(=E6=96=B0=E5=A2=9E):=20knife4j=E6=97=A0?=
=?UTF-8?q?=E6=B3=95=E8=AE=BF=E9=97=AE=E9=97=AE=E9=A2=98=EF=BC=8C=E5=B0=86?=
=?UTF-8?q?=E6=8E=92=E5=87=BA=E9=80=89=E9=A1=B9=E6=94=BE=E5=85=A5=E9=85=8D?=
=?UTF-8?q?=E7=BD=AE=E6=96=87=E4=BB=B6=E4=B8=AD?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
spzx-common/common-service/pom.xml | 8 +-
.../atguigu/config/ResourceConfiguration.java | 15 ++++
.../atguigu/config/WebMvcConfiguration.java | 61 +++++++++++--
.../interceptor/LoginAuthInterceptor.java | 83 ++++++++++++++++++
.../atguigu/config/RedisConfiguration.class | Bin 0 -> 7362 bytes
.../config/ResourceConfiguration.class | Bin 0 -> 1589 bytes
spzx-common/common-util/pom.xml | 10 +--
spzx-manager/pom.xml | 12 +--
.../manger/controller/IndexController.java | 5 +-
.../spzx/manger/service/SysUserService.java | 9 --
.../service/impl/SysUserServiceImpl.java | 37 +++-----
.../service/impl/ValidateCodeServiceImpl.java | 2 +-
.../src/main/resources/application-dev.yml | 5 ++
.../target/classes/application-dev.yml | 5 ++
.../spzx/manger/MangerApplication.class | Bin 911 -> 970 bytes
.../manger/controller/IndexController.class | Bin 3398 -> 3366 bytes
.../spzx/manger/service/SysUserService.class | Bin 451 -> 349 bytes
.../service/impl/SysUserServiceImpl.class | Bin 4475 -> 4371 bytes
.../impl/ValidateCodeServiceImpl.class | Bin 2578 -> 2589 bytes
spzx-model/pom.xml | 2 +-
.../spzx/model/entity/base/BaseEntity.java | 6 +-
.../spzx/model/vo/result/ResultCodeEnum.java | 2 +-
.../spzx/model/entity/base/BaseEntity.class | Bin 3650 -> 3518 bytes
.../system/SysUser$SysUserBuilder.class | Bin 0 -> 2529 bytes
.../spzx/model/entity/system/SysUser.class | Bin 4902 -> 5505 bytes
.../spzx/model/vo/result/ResultCodeEnum.class | Bin 2360 -> 2366 bytes
26 files changed, 201 insertions(+), 61 deletions(-)
create mode 100644 spzx-common/common-service/src/main/java/com/atguigu/config/ResourceConfiguration.java
create mode 100644 spzx-common/common-service/src/main/java/com/atguigu/interceptor/LoginAuthInterceptor.java
create mode 100644 spzx-common/common-service/target/classes/com/atguigu/config/RedisConfiguration.class
create mode 100644 spzx-common/common-service/target/classes/com/atguigu/config/ResourceConfiguration.class
create mode 100644 spzx-model/target/classes/com/atguigu/spzx/model/entity/system/SysUser$SysUserBuilder.class
diff --git a/spzx-common/common-service/pom.xml b/spzx-common/common-service/pom.xml
index 2611261..9d8c274 100644
--- a/spzx-common/common-service/pom.xml
+++ b/spzx-common/common-service/pom.xml
@@ -11,7 +11,7 @@
jar
common-service
- http://maven.apache.org
+ https://maven.apache.org
UTF-8
@@ -34,5 +34,11 @@
org.springframework.boot
spring-boot-starter-data-redis
+
+ com.atguigu
+ common-util
+ 1.0-SNAPSHOT
+ compile
+
diff --git a/spzx-common/common-service/src/main/java/com/atguigu/config/ResourceConfiguration.java b/spzx-common/common-service/src/main/java/com/atguigu/config/ResourceConfiguration.java
new file mode 100644
index 0000000..d2999b0
--- /dev/null
+++ b/spzx-common/common-service/src/main/java/com/atguigu/config/ResourceConfiguration.java
@@ -0,0 +1,15 @@
+package com.atguigu.config;
+
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
+
+@Configuration
+@Slf4j
+public class ResourceConfiguration extends WebMvcConfiguration {
+ protected void addResourceHandlers(ResourceHandlerRegistry registry) {
+ log.info("ResourceConfiguration===>设置静态资源映射......");
+ registry.addResourceHandler("/doc.html").addResourceLocations("classpath:/META-INF/resources/");
+ registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
+ }
+}
diff --git a/spzx-common/common-service/src/main/java/com/atguigu/config/WebMvcConfiguration.java b/spzx-common/common-service/src/main/java/com/atguigu/config/WebMvcConfiguration.java
index 1381589..27d0e12 100644
--- a/spzx-common/common-service/src/main/java/com/atguigu/config/WebMvcConfiguration.java
+++ b/spzx-common/common-service/src/main/java/com/atguigu/config/WebMvcConfiguration.java
@@ -1,22 +1,71 @@
package com.atguigu.config;
+import com.atguigu.constant.LocalDateTimeConstant;
+import com.atguigu.interceptor.LoginAuthInterceptor;
+import com.atguigu.json.JacksonObjectMapper;
+import com.atguigu.properties.InterceptorsProperties;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.converter.HttpMessageConverter;
+import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
-import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
+
+import java.text.SimpleDateFormat;
+import java.util.List;
@Component
-public class WebMvcConfiguration implements WebMvcConfigurer {
+@Slf4j
+public class WebMvcConfiguration extends WebMvcConfigurationSupport {
+ @Autowired
+ private LoginAuthInterceptor loginAuthInterceptor;
+ @Autowired
+ private InterceptorsProperties interceptorsProperties;
+
/**
* * 解决跨域
*
* @param registry 跨域注册表
*/
- @Override
- public void addCorsMappings(CorsRegistry registry) {
+ protected void addCorsMappings(CorsRegistry registry) {
+ log.info("开始跨域注册表...");
registry.addMapping("/**")// 添加路径规则
.allowCredentials(true)// 是否允许在跨域的情况下传递Cookie
.allowedOriginPatterns("*")// 允许请求来源的域规则
- .allowedMethods("*")
- .allowedHeaders("*");// 允许所有的请求头
+ .allowedMethods("*").allowedHeaders("*");// 允许所有的请求头
+ }
+
+ /**
+ * 注册自定义拦截器
+ *
+ * @param registry InterceptorRegistry
+ */
+ protected void addInterceptors(InterceptorRegistry registry) {
+ log.info("开始注册自定义拦截器...");
+ // 需要拦截的
+ String[] addPathPatters = {"/admin/**"};
+ registry.addInterceptor(loginAuthInterceptor).addPathPatterns(addPathPatters)
+ .excludePathPatterns(interceptorsProperties.getNoAuthUrls());
+ System.out.println(interceptorsProperties.getNoAuthUrls());
+ }
+
+ /**
+ * 扩展Spring MVC框架的消息转化器
+ *
+ * @param converters 转换器
+ */
+ public void extendMessageConverters(List> converters) {
+ log.info("扩展消息转换器...");
+ // 创建一个消息转换器对象
+ MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
+ // 需要为消息转换器设置一个对象转换器,对象转换器可以将Java对象序列化为json数据
+ converter.setObjectMapper(new JacksonObjectMapper());
+ // 添加条件判断,只应用于特定的请求路径
+ converter.getObjectMapper().setDateFormat(new SimpleDateFormat(LocalDateTimeConstant.DEFAULT_DATE_TIME_SECOND_FORMAT));
+
+ // 将自己的消息转化器加入容器中
+ converters.add(converter);
}
}
\ No newline at end of file
diff --git a/spzx-common/common-service/src/main/java/com/atguigu/interceptor/LoginAuthInterceptor.java b/spzx-common/common-service/src/main/java/com/atguigu/interceptor/LoginAuthInterceptor.java
new file mode 100644
index 0000000..1cb2fe2
--- /dev/null
+++ b/spzx-common/common-service/src/main/java/com/atguigu/interceptor/LoginAuthInterceptor.java
@@ -0,0 +1,83 @@
+package com.atguigu.interceptor;
+
+import com.alibaba.fastjson.JSON;
+import com.atguigu.context.BaseContext;
+import com.atguigu.spzx.model.entity.system.SysUser;
+import com.atguigu.spzx.model.vo.result.Result;
+import com.atguigu.spzx.model.vo.result.ResultCodeEnum;
+import com.atguigu.utils.InterceptorUtil;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.lang.NonNull;
+import org.springframework.lang.Nullable;
+import org.springframework.web.method.HandlerMethod;
+import org.springframework.web.servlet.HandlerInterceptor;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.concurrent.TimeUnit;
+
+@Configuration
+@Slf4j
+public class LoginAuthInterceptor implements HandlerInterceptor {
+ @Autowired
+ RedisTemplate redisTemplate;
+
+ @Override
+ public boolean preHandle(@NonNull HttpServletRequest request, @NonNull HttpServletResponse response, @NonNull Object handler) throws Exception {
+ String method = request.getMethod();
+ String token = request.getHeader("token");
+
+ // 判断当前拦截到的是Controller方法还是其它资源
+ if ("OPTIONS".equals(method) || !(handler instanceof HandlerMethod)) return true;
+
+ // 当前token为空
+ if (StringUtils.isEmpty(token)) {
+ InterceptorUtil.unLoginInterceptor(response);
+ return false;
+ }
+
+ // 获取用户信息不存在
+ String userinfoString = (String) redisTemplate.opsForValue().get(token);
+ if (StringUtils.isEmpty(userinfoString)) {
+ InterceptorUtil.unLoginInterceptor(response);
+ return false;
+ }
+
+ // 将用户信息放到ThreadLocal中
+ SysUser sysUser = JSON.parseObject(userinfoString, SysUser.class);
+ BaseContext.setSysUser(sysUser);
+
+ // 更新Redis过期时间
+ redisTemplate.expire(token, 7, TimeUnit.DAYS);
+
+ // 放行
+ return true;
+ }
+
+ /**
+ * 请求完成后删除ThreadLocal
+ */
+ @Override
+ public void afterCompletion(@NonNull HttpServletRequest request, @NonNull HttpServletResponse response, @NonNull Object handler, @Nullable Exception ex) throws Exception {
+ log.info("删除ThreadLocal...");
+ BaseContext.removeSysUser();
+ }
+
+ // 响应208状态码给前端
+ private void responseNoLoginInfo(HttpServletResponse response) {
+ Result result = Result.error(ResultCodeEnum.LOGIN_AUTH);
+ response.setCharacterEncoding("UTF-8");
+ response.setContentType("text/html; charset=utf-8");
+ try (PrintWriter writer = response.getWriter()) {
+ writer.print(JSON.toJSONString(result));
+ } catch (IOException e) {
+ log.error("出错了===>{}", e.getMessage());
+ }
+ }
+}
diff --git a/spzx-common/common-service/target/classes/com/atguigu/config/RedisConfiguration.class b/spzx-common/common-service/target/classes/com/atguigu/config/RedisConfiguration.class
new file mode 100644
index 0000000000000000000000000000000000000000..0fd0c6edd33f4b72630fd47a2850427606f9aaa3
GIT binary patch
literal 7362
zcmc&(30E7}75*NJ2juY*94{nkVmqY92CNV}u7mI*gR#L95DPl{m^b{X!-n@Bp?{}B?
z?lQ0Z=cR80IDmfzP=#s*H7aVcN?`q@c0miKv`jKMFgB^jZGlytM#iuY3RE}m99B>#
z&~94EV0OwfGRbjEOY0Ar*12Fpv$de5CyZ<`Zd!Wqq#O?E>8X@v>j5aJmOrais8}O#
zV^+7j%uI$H3^UWC#ck7?7C71*@ufZglFMNck&pzrPT-Iap{#BhTFSVjTfvwuMR5Sf
zin9T%bs;yX*nk_U8bUsyPnT8*9Q1|j;j(}}aY}`3Qn6W5mkK$qWhcrwC}f_G>t^sUurMgAMt0dnB@*UPvIlUy8gms&Wt@81v0<1+#w&QjM
zO)Bods|D_eo9UotCv!$JN9$+Cjbza}9Oo=eT3KMj)5itkT7075s9kbMU-F`DNa*8QE@gY32^{tZyDZtzYV1Z(!JR7FahJd;AB-OB
zmYLGgC;{90MZ0O^Ai$1O8GKd*D*$?Njf6&Pp*Fdc*KRdF}=3EWT=m3tsN
zV%QS`PhT_W<@FQt^|?FTihCsP4Mp6}CUKAl5JIPd11b*Ukib44BQInY)iPRA
z8ci9?8L5OEJ>{zj?z_TqTHJf($Lq?4F5qZ#OzLcd!pspD7VQ_t5d~c;x^Yxs;M(M@
zNMB%$qnd7aBW4Aj@K?ifoBDsGf@3OA04)b?ag}
z6`XX>b0@^w(^GnIGHdN=zcbj!SUqH<^{AQ1r5I!TWF+sG$E*zEHlG9|W?V~kGXg6Z
z6bN4(-Gok;F1^|dg`PKn(=utfUtmXph$C?&zD~UD!viW_i?agj
zv_!%yn7~CZl&+MP&4wbC^)+T>5mZmA5~@e4O~j%rg=x)s2A
zRM#Vi3kn`maS=>&+n0V{%VbR330%QJ%jCQEbT}T@vssfotHY6qz@7>Yw#=)cdb|#=
zSMUZEZ^WB;IQcS{ZXM3qX18uLKW`c~vc{N^GHfER4)>2TvGPYzkp_3}c|4-x&3Ke<
zDzi@y`DdE_DKAt_rCsV#No6p;8`f(|YVxgkn}WBicnps-aa~%IvJ!IKV3K-tHm}_6
z!H8yLv-+hTre}IAH#WqBoC$-$)zZ9mMkZ@(nYb=+qJj>tfi4kW#yb_fOU1kK9)Wv&
z5PPL2|4zELdE;=eu0fF{EQ0>5es;|P{|L9
z42rrPG*i=Q)0&zv;$Z9ZN1I5|sJ-TM+EE>IW-s-ssWTP&hgm6S&*YA(kTP==mcmK8lYqk7O;bjityZ;j7stiLFc{
za*Kal#V7Dd79y6OG-M{@W+?*0z6jiv{t?IPWQ?NEF`D=!pxI)?Wb(93k^C$^Epv;{
zFl_juEkohSX517)R{5XB=M;Qi#TW1bqoD&aHNJO}8CH^6ezEycpVV!4iWT+ZcwH!2
zJa2M$Z^xHZd>LQi$(%B|NgLck&AUjTrprvw^y?xARbq20xdN`~xyQ6ay
zCTr{ogPHaY$LV~F`VbFs%iHP^c*H+PFO@1O-L`XaCaUh0743?PmPOqrVp7KETS^hX
z($!Np`GS!F*vG{dH@^sHQ@Nsf^cR#px^i-z9v>@Y%$^z78$$=lbbVB}C(Oj4CVO<;
zfHZ1-%t&SmC(iT#Z!=xBAdM$;8JXKVnLDR&1Tl`+ub(p8MF@Z}Z2rtf<0%WIgBJlFd#+
z3zXIf99sdwWe!r3T}4x{sm5NZA4ykXrB(xvf>Jk*lr}qJI|?m(ByhhU>5^#69s6E?
z^lYQGvV4)1zo?12Hpa
z#q}OTCJUSAJ-%d!-BKIuXf3JoCAM9esi*_Bmkw?@u~E+|__IKl&w=WZ%z+at#Bgti
zkKMzvX}1TurQ}TIeJcfj7ht1$sV0l($S5xxxJA6B%9^s2726n!tN2Mp;3gT5IjZHD
z-&FYfRo(@86>@gh41}Dh!WI6?$KcB^@>g{i;A{9g?*#IgL5=hBbExJ&AT$SMbO!a&
z)|Na1t#eq*yY+e8P#SLJa0_Q|%H!tJ@YYs|sM=w9E8F|P4%D%SxdyxVL7)YQHjl%3^emKO
zKlyi1icU1}W7bA?TW`T3G_flw6?)KRQk0^d;C|p>-iaULM+C8kYk!QN5LN?j!%y)F
z72d?zpK(-Ml+j)FbFT8p_%a!kWaDQLl9RIin=eXRU7kZ9?GTByG(_hxFxqhMEMhYl
z&Ew37Gxgy7)L0&IP9^7Hj5eHeR;ArloXX5kP03YrI8U0{XzLZ&S8yqhhetSk%N4vM
zkN3*qlX-l2M0&?FT>I>3YeUrxJ|(s0y4!B7=D3$y>%+}BL5oMIt0-U@i6Z5_`>Ca7VGdRet}<7i)ZL7zrwFc*){iXNcFdlN~9XLafSS=Z`eMI=U>DZ
z<)rZVymYbOajpu#FZ#(Jc>hQK-%c~^#-H$)RrQ1y!e1eK7=Ob*4mYx%J&%7LZu~DV
CrGa<=
literal 0
HcmV?d00001
diff --git a/spzx-common/common-service/target/classes/com/atguigu/config/ResourceConfiguration.class b/spzx-common/common-service/target/classes/com/atguigu/config/ResourceConfiguration.class
new file mode 100644
index 0000000000000000000000000000000000000000..76c9f3f501894c8b9fc1990f31b674307f5b8fdf
GIT binary patch
literal 1589
zcmb_d+fEZv6kVq+&a@Q4a#8S#B9b4^ovSse!%hW30lIyySGy|MY@>&DNQFSedM
z-G0Bm_2t>t^H<+rulI+)dNkpXhEx*GXklooMQ4av&Z5iEn$9hYRl#lHn0!`wmSbjn
z<}|d?qgsQGBMfn#ca8ofRj?E2z)=myk~oeN47WlbD*?iyCkpbR>pkEP`FxF$A)mg#N312{_Q7o!60v@Y;e=re-(L}G
zX_!ylxO=_t*7PLz%HPlD37p0m4P8l`4HBQ)uf)s3YN<*-=NjRuuj3p;eZc3k@O+-h
z=;#T=`p-Zsw-e~ac@2F@^n)`Tu2sXNFq9kc9yg^b$&cY|wK66GKiQtYRZ2pdaPyL(
zF=sh)x>#6{-d(X^(+O$X5cZt#tYBY0jHxBdXUOFKw?eWE%~gbyr9u$X>3#e3Yb1FF
z-P_UM?R|u%LYk6l$<5ypL0Ks2QSkbRVVB!SVm53GlUBf4M@99!xspzx-model
1.0-SNAPSHOT
+
+
+
+
+
org.springframework.boot
@@ -40,10 +45,5 @@
minio
8.5.9
-
- com.atguigu
- common-service
- 1.0-SNAPSHOT
-
diff --git a/spzx-manager/pom.xml b/spzx-manager/pom.xml
index d00067c..3035841 100644
--- a/spzx-manager/pom.xml
+++ b/spzx-manager/pom.xml
@@ -24,6 +24,12 @@
common-service
1.0-SNAPSHOT
+
+ com.atguigu
+ common-util
+ 1.0-SNAPSHOT
+ compile
+
org.springframework.boot
@@ -54,11 +60,5 @@
com.github.pagehelper
pagehelper-spring-boot-starter
-
- com.atguigu
- common-util
- 1.0-SNAPSHOT
- compile
-
diff --git a/spzx-manager/src/main/java/com/atguigu/spzx/manger/controller/IndexController.java b/spzx-manager/src/main/java/com/atguigu/spzx/manger/controller/IndexController.java
index 8d68933..6183201 100644
--- a/spzx-manager/src/main/java/com/atguigu/spzx/manger/controller/IndexController.java
+++ b/spzx-manager/src/main/java/com/atguigu/spzx/manger/controller/IndexController.java
@@ -1,5 +1,6 @@
package com.atguigu.spzx.manger.controller;
+import com.atguigu.context.BaseContext;
import com.atguigu.spzx.manger.service.SysUserService;
import com.atguigu.spzx.manger.service.ValidateCodeService;
import com.atguigu.spzx.model.dto.system.LoginDto;
@@ -37,8 +38,8 @@ public class IndexController {
@Operation(summary = "获取登录用户信息", description = "获取当前登录用户信息")
@GetMapping("getUserInfo")
- public Result getUserInfo(@RequestHeader(name = "token") String token) {
- SysUser sysUser = sysUserService.getUserInfo(token);
+ public Result getUserInfo() {
+ SysUser sysUser = BaseContext.getSysUser();
return Result.success(sysUser);
}
diff --git a/spzx-manager/src/main/java/com/atguigu/spzx/manger/service/SysUserService.java b/spzx-manager/src/main/java/com/atguigu/spzx/manger/service/SysUserService.java
index 7cc553a..1df55dc 100644
--- a/spzx-manager/src/main/java/com/atguigu/spzx/manger/service/SysUserService.java
+++ b/spzx-manager/src/main/java/com/atguigu/spzx/manger/service/SysUserService.java
@@ -1,7 +1,6 @@
package com.atguigu.spzx.manger.service;
import com.atguigu.spzx.model.dto.system.LoginDto;
-import com.atguigu.spzx.model.entity.system.SysUser;
import com.atguigu.spzx.model.vo.system.LoginVo;
public interface SysUserService {
@@ -13,14 +12,6 @@ public interface SysUserService {
*/
LoginVo login(LoginDto loginDto);
- /**
- * * 获取当前登录用户信息
- *
- * @param token token值
- * @return 用户信息
- */
- SysUser getUserInfo(String token);
-
/**
* * 用户退出接口
*
diff --git a/spzx-manager/src/main/java/com/atguigu/spzx/manger/service/impl/SysUserServiceImpl.java b/spzx-manager/src/main/java/com/atguigu/spzx/manger/service/impl/SysUserServiceImpl.java
index ea9ac96..bcecf18 100644
--- a/spzx-manager/src/main/java/com/atguigu/spzx/manger/service/impl/SysUserServiceImpl.java
+++ b/spzx-manager/src/main/java/com/atguigu/spzx/manger/service/impl/SysUserServiceImpl.java
@@ -1,13 +1,14 @@
package com.atguigu.spzx.manger.service.impl;
+import com.alibaba.fastjson.JSON;
+import com.atguigu.constant.ExceptionConstant;
import com.atguigu.exception.BunnyException;
-import com.atguigu.exception.EnumException;
+import com.atguigu.lib.MD5;
import com.atguigu.spzx.manger.mapper.SysUserMapper;
import com.atguigu.spzx.manger.service.SysUserService;
import com.atguigu.spzx.model.dto.system.LoginDto;
import com.atguigu.spzx.model.entity.system.SysUser;
import com.atguigu.spzx.model.vo.system.LoginVo;
-import com.atguigu.utils.MD5;
import com.atguigu.utils.StringEmptyUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
@@ -40,50 +41,36 @@ public class SysUserServiceImpl implements SysUserService {
String key = loginDto.getCodeKey();
// 得到Redis中验证码
String code = (String) redisTemplate.opsForValue().get(key);
- stringEmptyUtil.isEmpty(userName, EnumException.USERNAME_IS_EMPTY);
- stringEmptyUtil.isEmpty(password, EnumException.PASSWORD_IS_EMPTY);
- stringEmptyUtil.isEmpty(captcha, EnumException.CAPTCHA_IS_EMPTY);
- stringEmptyUtil.isEmpty(key, EnumException.KEY_IS_EMPTY);
- stringEmptyUtil.isEmpty(code, EnumException.VERIFICATION_CODE_IS_EMPTY);
+ stringEmptyUtil.isEmpty(userName, ExceptionConstant.USERNAME_IS_EMPTY);
+ stringEmptyUtil.isEmpty(password, ExceptionConstant.PASSWORD_IS_EMPTY);
+ stringEmptyUtil.isEmpty(captcha, ExceptionConstant.CAPTCHA_IS_EMPTY);
+ stringEmptyUtil.isEmpty(key, ExceptionConstant.KEY_IS_EMPTY);
+ stringEmptyUtil.isEmpty(code, ExceptionConstant.VERIFICATION_CODE_IS_EMPTY);
// 验证码不匹配
assert code != null;
if ((!Objects.equals(code.toLowerCase(), captcha.toLowerCase()))) {
- throw new BunnyException(EnumException.VERIFICATION_CODE_DOES_NOT_MATCH);
+ throw new BunnyException(ExceptionConstant.VERIFICATION_CODE_DOES_NOT_MATCH);
}
// 比较完成后删除验证码
redisTemplate.delete(key);
// 根据username查询用户信息
SysUser sysUser = sysUserMapper.selectByUsername(userName);
if (sysUser == null) {
- throw new BunnyException(EnumException.USER_NOT_FOUND);
+ throw new BunnyException(ExceptionConstant.USER_NOT_FOUND);
}
String encryptedPassword = MD5.encrypt(password);
// 比较密码
if (!encryptedPassword.equals(sysUser.getPassword())) {
- throw new BunnyException(EnumException.PASSWORD_ERROR);
+ throw new BunnyException(ExceptionConstant.PASSWORD_ERROR);
}
// 登录成功
String token = UUID.randomUUID().toString().replaceAll("-", "");
- redisTemplate.opsForValue().set(token, userName, 7, TimeUnit.DAYS);
+ redisTemplate.opsForValue().set(token, JSON.toJSONString(sysUser), 7, TimeUnit.DAYS);
// 返回loginVo对象
return LoginVo.builder().token(token).build();
}
- /**
- * * 获取当前登录用户信息
- *
- * @param token token值
- * @return 用户信息
- */
- @Override
- public SysUser getUserInfo(String token) {
- String username = (String) redisTemplate.opsForValue().get(token);
- SysUser sysUser = sysUserMapper.selectByUsername(username);
- sysUser.setPassword("******");
- return sysUser;
- }
-
/**
* * 用户退出接口
*
diff --git a/spzx-manager/src/main/java/com/atguigu/spzx/manger/service/impl/ValidateCodeServiceImpl.java b/spzx-manager/src/main/java/com/atguigu/spzx/manger/service/impl/ValidateCodeServiceImpl.java
index d91db0d..627740f 100644
--- a/spzx-manager/src/main/java/com/atguigu/spzx/manger/service/impl/ValidateCodeServiceImpl.java
+++ b/spzx-manager/src/main/java/com/atguigu/spzx/manger/service/impl/ValidateCodeServiceImpl.java
@@ -30,7 +30,7 @@ public class ValidateCodeServiceImpl implements ValidateCodeService {
// 2. 验证码存储到Redis中,Redis的key为UUID,值为验证码的值
String key = UUID.randomUUID().toString();
// 3. 返回ValidateCodeVo
- redisTemplate.opsForValue().set(key, code, 1, TimeUnit.MINUTES);
+ redisTemplate.opsForValue().set(key, code, 10, TimeUnit.MINUTES);
return ValidateCodeVo.builder().codeKey(key).codeValue(base64Image).build();
}
}
diff --git a/spzx-manager/src/main/resources/application-dev.yml b/spzx-manager/src/main/resources/application-dev.yml
index e72a30c..599866c 100644
--- a/spzx-manager/src/main/resources/application-dev.yml
+++ b/spzx-manager/src/main/resources/application-dev.yml
@@ -11,6 +11,11 @@ bunny:
port: 6379
database: 2
+
+ spzx:
+ noAuthUrls:
+ - /admin/system/index/login
+ - /admin/system/index/generateValidateCode
# jackson:
# date-format: yyyy-MM-dd HH:mm:ss
# time-zone: GMT+8
\ No newline at end of file
diff --git a/spzx-manager/target/classes/application-dev.yml b/spzx-manager/target/classes/application-dev.yml
index e72a30c..599866c 100644
--- a/spzx-manager/target/classes/application-dev.yml
+++ b/spzx-manager/target/classes/application-dev.yml
@@ -11,6 +11,11 @@ bunny:
port: 6379
database: 2
+
+ spzx:
+ noAuthUrls:
+ - /admin/system/index/login
+ - /admin/system/index/generateValidateCode
# jackson:
# date-format: yyyy-MM-dd HH:mm:ss
# time-zone: GMT+8
\ No newline at end of file
diff --git a/spzx-manager/target/classes/com/atguigu/spzx/manger/MangerApplication.class b/spzx-manager/target/classes/com/atguigu/spzx/manger/MangerApplication.class
index 073831e62c2b2a8891b773db5d7f088f600eb348..9ecda2a89eb666d35b9bd91f3d13b1df08a4f5a8 100644
GIT binary patch
delta 109
zcmeBYKgG^<>ff$?3=9mm3`!fhteF^1CSDX%Oia#5)lbaJ%P&bR$;{8wcg;&o%1Lzw
z3TNh}TQf4)OuQ&MIhtt=BkyDmW_wnC26hI4$v(_F(ozg83^G8|WPw-?h~*g=85E)!
I7>gMc0UO8~WB>pF
delta 68
zcmX@b-p|f;>ff$?3=9mm42m1MteF^XCSDYsJc(%yBll!`W_wm%26hI%$<53<;$jTU
W3^G84vOp}yz{nsU&A?d9pa1}DG!3x;
diff --git a/spzx-manager/target/classes/com/atguigu/spzx/manger/controller/IndexController.class b/spzx-manager/target/classes/com/atguigu/spzx/manger/controller/IndexController.class
index 4452344e4078b041b608747ab1f3742ad338dd8e..f4806d79656abfc2a3f39a0f9479cd5cca42b277 100644
GIT binary patch
delta 832
zcmZ8fO-~b16g_X+(#~{JFeDl(#x{V~8D-k~fe2MT6sb}b0l%ukh+}m@n=mEORoAZH
z#$VvlKqRrc(47nZjeo#!-gE*@7c=kPdFR}7?!EIj{WWbI{QvbEKnZX5j6d3pfl-Xb
zan8hfCCylH{Xc`jGEV6`Q)$p-nKwKCwIk=9Eha*
zEE6^^%6w$Z7&mbWj)1Lht?!>BcGOIgra0yLyN2vfl(cG2ZX~{llB^`A<-d4FPU_=g
zLJA`vU-aC!-u9IA^yOHz?rwQj%VM
zK)KAfDgX@P3g4;#0l125JOxgW6hToQ7@2j2H7ElN^E?yaPX>8^h&RZbz;*H_iPCT*
zFf+_(iqEvq3E%W_3o}H_Rv~=W7sz6cyrL{8v#n!|5w_ZlB?GlP
zth~VcnBZrG!gqUx7nN`s_l|_KxKDIk4P=RdKt*-hf|}DTQ`M&4#>kT0#^5d!4aeRr
zM7dZsuTKAZ=q*Y|5AcxmPXCX3Z7eGrkGuM>5Nl(F^_1{Ji!w?%W$k0g{)r13+PKs!
zU*PzQUGk};(WJ17HI@tqvdU8Gcj(%{6XoD(mxE`)AWSug=O}P5K5J-rL7IkYKtIg|
SyyX2WAFr{_iw!27{keziDrr;z
delta 869
zcmZ{hO-~b17=_QB&M@uFSicekN{kh%^aB|DLInkjd|E(JL_};z9F2?CgmL4lKf%TQ
z4<;HHHkt@7bYon&@}IbLXFT_I($*#{X5M?}zVA8DocpHlN1yZa@0YItuAy9az8NVO
zCo$+DgEIo|v*6`=80;=qpS}<%%6IXC{9|`Js%OYU7CBjrWx5I;PGI2DKZ9lmX>^uo}Cj`vuP9>0L!k5*=s{EdK
zUmGD+7X(IG4Y=^QZvSR+Z|M%79i!X{Rx9@zqOM2A_*MeIF`VOD39td@ae-CfD25S(
z8lLCQU_G4s1bZKc1WI}N+ews_grkpAto>T1yU`lSI262yOB5JquYt>&v7f6ee6EI=
zz+}jDud`!n3nHYgKpNAW^W}z{uC+W)^DhUq$0>pVMOmMlR{%{fP1byLZR^Q?hA8PA&4xOUq|uaGLl~WMYDZTxwoPW=W-f
zab!l2GVn0)GB7f*0}W+mWZ(u;
Mj0}80l8J#I04~EEp#T5?
diff --git a/spzx-manager/target/classes/com/atguigu/spzx/manger/service/impl/SysUserServiceImpl.class b/spzx-manager/target/classes/com/atguigu/spzx/manger/service/impl/SysUserServiceImpl.class
index bc70e3d8ba1dbc62b4433826f8bb3f35d2540840..dcccba822752b9c049e1c5672fbfe4a4813c1a93 100644
GIT binary patch
delta 903
zcmZWnTSyd982)DVGP~2bnbmp;dyrDg%LZ#0m1UVE28s#_h0-c18?{@xLT}bfH!HJ~
znReNv`9!ag6Q?sdR+CM#=zP}zt2@%QCcEF3;18YZ&M7#r;Q}s-4|cctvV?3=W=Rm$6KtWyYMU%R
zYI{~)f|+B44mA+mDs<1V8bHUHU?FpZvm!yg(SADe)sD4^ZU9E(w9K)j4`y01oS
z0#1a9HTuDbYZ&A%VF<&lI6y)Nvs9WSk>q&SoTv<9+Z62X$KD|vurm5kqCJdbVVu-u
znxGf1K|I$~mP=!5I$|-4G#Oko;bu#D$VL%dsK6Y?y0H;C*owJm!928MKDx1h16#;O
z7ExS2?qLbWuncd|T!=4NZYZvgsER74K3vBQqst$-i4m$-@fEj-Ocd}Lw~5S@@dBdPNxs*F)Aa2
z;-F=|fI52s&Wtdssv-xbPee65Wh_^2h<8RJ|A?nwCzB8@-NO_coh)z6*{WtbOy?g)w
delta 1050
zcmZXSTTB#Z6vuzx>}6($DdCQ-7?lFjg_T5%q$NbGw`yWrsq#QAgu+TTfkoZj=-ak0
zOT
zx7-|mJa!dm;;$hyqgA}z)!$dw8ShC%dJ=Wv9bMrq@koEPZe=vlxALi%y05+EDJY&9
znTSVvW2rU%R<+N_$^C>+b#_{O#xBJidzmrEUSfp&do1=cU`LFWT$}wm2P_V9NKtL8
zK(#$-tj!(dh|W=qV;omB2;5+Q5NInL15T0$tk70WN@cXDdHNBeWwOU#y=A@_cGW_;c(UT3-B
zKFRU9RZ`;BiKiSiIEu=qjfm@zKrxr81S=asno$82-;)sz$<|B>GzI(5UYh%NGE~Gz
z!+e}!w_jrRy%-rQD*K32EvcE0`p?O60=ktfDEkqKz?r5Y;{&@grA6
zxyeJWiscaj54a|lS7iLdb+LRR<}NqH@(bN2ZVHJmwN~?!V1`i5m(93BfS-k{2Jio(
zQr9Wfv8(dtC4Ujrr-afO)UR}B2gMFKooB2Fj!=@OtR_RbCWO`N1bDYLLx;wjp@P$C
z&W5s&>&&ab%~?-AEtJVr%Guzy7|hn1Zn46Zq$IAYkl#d|CgFyw-NTfkW3Hm#X>}CY
zZF#ek4udJ4^DY58+{z`cZ%$V>rz+1VVlY0vJ&WDVfc%2eH0O_?d(Y$bq-cJ2lZxDN
e`OvIpC3F8nNat$Yo?g%i0q(eZ6oc6ON#F_Dx6s7^
diff --git a/spzx-manager/target/classes/com/atguigu/spzx/manger/service/impl/ValidateCodeServiceImpl.class b/spzx-manager/target/classes/com/atguigu/spzx/manger/service/impl/ValidateCodeServiceImpl.class
index 9f9270620958c9fd45d155e5254339ed8b110dfd..06ef4fa83f09af9c516d793092472a2328a8e551 100644
GIT binary patch
delta 486
zcmX|-$xd4_6ox3L=B@BvCL#0R{ArONC4UjTJ3G+M;rDblJp{-bS)4o7gSYm4uJn;tW7
zpG6Y%dGynxa98$L*QS=X57q)C81xuo*i<-eYV>@^c~C*w{={d^y2mRv%%Z+iTc+6G
zq4vy%zs&xkh?rkGVlMo7KSxkllu#->CfCjo9v8NRowS+|6&0m~ow7^RY5I6lFqI71
zObL2V2~0C1N-@i@V9NYQ@>0Ljoy$>9m3FSs1LaAw1_ex)8!ikHJ)`=Xcm`KAhwUUC
zl}UP&44jC~V$%F@Uw@BNlx|e>RP4D?CQZ!oURvc4XPys|UqB@vCGv@*m<5S!nTzRK
gOE0fn7QG_NFWyyIn{1296Muphc5vBcpRa`f1FDru-T(jq
delta 480
zcmX|+OHWf#6otQYdv8zg?d2H;R1!3Tfk5O{DuS&*p&;0T%KN1tl(!ZK3>-OChn~d5
z0f}>CBAOI*z`!taf~TfZ#Dh0}d~$xP(p8T&vYK_DYBtQ4K2=+$B{X2a
zP~0+~L$zLgI+xqo-_zvGK`8oW424Aljlz%Q3qj$>!j`a8R8K^;ic-Q((-G>h_&gz4
zFhd!Wg8qepDW*j!X2=K@!e7Ma2&XFeSl*_cV|2PXPf13=jJuKR-gjDm5({$7y@;Ks
z|8}0?Jfq(vWHDjhxizn2+$^r?ycl)4CQJ{r%*mp1V$8E3{%bU|C|y7jbu39|%XwOy
g_3Y}8%c57LLXv$hwaK=qO35dQvxCbnFWDn<4uvXA2><{9
diff --git a/spzx-model/pom.xml b/spzx-model/pom.xml
index 9fc4036..fef7b0b 100644
--- a/spzx-model/pom.xml
+++ b/spzx-model/pom.xml
@@ -1,4 +1,4 @@
-
4.0.0
diff --git a/spzx-model/src/main/java/com/atguigu/spzx/model/entity/base/BaseEntity.java b/spzx-model/src/main/java/com/atguigu/spzx/model/entity/base/BaseEntity.java
index 130dee0..74d2286 100644
--- a/spzx-model/src/main/java/com/atguigu/spzx/model/entity/base/BaseEntity.java
+++ b/spzx-model/src/main/java/com/atguigu/spzx/model/entity/base/BaseEntity.java
@@ -1,6 +1,5 @@
package com.atguigu.spzx.model.entity.base;
-import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@@ -13,15 +12,14 @@ public class BaseEntity implements Serializable {
@Schema(description = "唯一标识")
private Long id;
- @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+ // @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@Schema(description = "创建时间")
private Date createTime;
- @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+ // @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@Schema(description = "修改时间")
private Date updateTime;
@Schema(description = "是否删除")
private Integer isDeleted;
-
}
\ No newline at end of file
diff --git a/spzx-model/src/main/java/com/atguigu/spzx/model/vo/result/ResultCodeEnum.java b/spzx-model/src/main/java/com/atguigu/spzx/model/vo/result/ResultCodeEnum.java
index 33f9a56..3defdb3 100644
--- a/spzx-model/src/main/java/com/atguigu/spzx/model/vo/result/ResultCodeEnum.java
+++ b/spzx-model/src/main/java/com/atguigu/spzx/model/vo/result/ResultCodeEnum.java
@@ -12,7 +12,7 @@ public enum ResultCodeEnum {
USE_NOT_EXIST(500, "失败"),
SERVICE_ERROR(2012, "服务异常"),
DATA_ERROR(204, "数据异常"),
- LOGIN_AUTH(208, "未登陆"),
+ LOGIN_AUTH(208, "需要先登陆"),
LOGIN_MOBLE_ERROR(208, "登录验证失败"),
ACCOUNT_DEACTIVATION(208, "账户停用"),
PERMISSION(209, "没有权限");
diff --git a/spzx-model/target/classes/com/atguigu/spzx/model/entity/base/BaseEntity.class b/spzx-model/target/classes/com/atguigu/spzx/model/entity/base/BaseEntity.class
index aa4998f6fb3de0e4dae50bb577a2a7c6ddf92fde..23bdb8cc47650006befd56a96d0a715981a72fd9 100644
GIT binary patch
delta 1139
zcma)*$!-%t5Qe`Qd&WCpk&J;LBbE?hgjmD@vYJ3b0&&<^vxkHwKumZ5iyIOW5}E@i
z4!l7eKu8>N0K|a@Ktkdb5Ih0mpBc*-dk`GDySl6Xzy7N3ez$h1EBWc?+a+Lt`C9V3
z`EoomXD*vgGQ*7+H`DCqmiy8AV9dIY?UHfN{bCoQ6@$F{)y})!vA${wgS{HP59r5a
zB`dVqBgQ7jfE*6FcE=zY9a`9$hlJU#)zE4c-eA;Zm=ra8Zb-0Cb23ThX1N=x#Q9sojOR(^Hh#pvYCBu?HAY
zF+=XRc&`6G+yA(B;=zPQGuev!Y(WVxv)u
zOi)s9I(g2dUX#fto^V8G5nb#fj>?LvbF&x%0PDo*tHFbqQQqEtl(rPHQq{~xSCz$k0+`&%&-3+H6mWwK=
z`E!g(5>)C05$%Pq
zAuo`S_yZQCfRI>3Vpy?9d;lN7k{#ka+e$((B2xU$eeVwE+;?B4=i|1}mtXHI0ETd<
z9Qq+oN2k(xBetZQrN!bsBO6=M)2n7a7t?dOd`T}Y6Hd||&le57l#mc8=q0-5B(&e>
zFPch4Gnt*qWZW>~ruq7(ye7Ba4q+K90jxIT5VF=?<+GHt5^73XvmU7tzbT>DdaU+Z
zU)98V2V@+Dgdr2haD*Uk;yCx(v6;qUGWGHpriX?u*CWi;4LyMt8VXc?M;ILADsfdJ
z?;w>4WSrzz90MVYu5)R2JTQiFS|o=Z{QepJ27y;RtdDNRs7LUAL_C698iU*1;7*%d
zwRF^pwzdSd{u)osv(jGd6P2v#ptfG~?e_GYK$6^rq&QcZs~Q=2i-1Q*c&0fXE-TTk
zu-&9nJX0hZ;%X*w8a_9r^*z{@s&QanJ+o}G1Kljb5Z5a%uQ~t{rku3aU{hC}s()p4
zro_!C43CT{OnYhX_^K+L34{}wuW8k5jm}IO`rZ^S)e3fquRX<%wU!xJMjW@
z95ESt@C5VR^YOMH;tY`=6IjJrA_XZd;vA8REWOVY1yIB=E)WIr6n(fz)P!f`a0#=1
zj`3w{dpNP=GMphpKejpy$wa&iapTIs2LxXd)DLleW0fjpg+v8qH{+bG`2YsFHDXo5
z4;C8lI!TT|!A;bAH)qJg*v*R6RDK)yty2>
oiL_m7zNLSxv6k~(wQ8-5EoqVY!Tw0N#lL|(tq@Uxy(^*nH|Fe)6aWAK
diff --git a/spzx-model/target/classes/com/atguigu/spzx/model/entity/system/SysUser$SysUserBuilder.class b/spzx-model/target/classes/com/atguigu/spzx/model/entity/system/SysUser$SysUserBuilder.class
new file mode 100644
index 0000000000000000000000000000000000000000..545c713c52f1c2e4f665c34033c0356f5ed7cc64
GIT binary patch
literal 2529
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