diff --git a/pom.xml b/pom.xml
index 2c2b8a7..de6c7a6 100644
--- a/pom.xml
+++ b/pom.xml
@@ -117,6 +117,12 @@
spring-boot-starter-data-redis
+
+
+ org.springframework.boot
+ spring-boot-starter-aop
+
+
@@ -128,6 +134,19 @@
+
+
+
+ com.github.whvcse
+ easy-captcha
+ 1.6.2
+
+
+
+ cn.hutool
+ hutool-all
+ 5.8.26
+
diff --git a/src/main/java/com/cultural/heritage/annotation/AuthCheck.java b/src/main/java/com/cultural/heritage/annotation/AuthCheck.java
new file mode 100644
index 0000000..896fa2b
--- /dev/null
+++ b/src/main/java/com/cultural/heritage/annotation/AuthCheck.java
@@ -0,0 +1,18 @@
+package com.cultural.heritage.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * 权限校验
+ */
+@Target(ElementType.METHOD)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface AuthCheck {
+ /**
+ * 必须有某个角色
+ */
+ String mustRole() default "";
+}
diff --git a/src/main/java/com/cultural/heritage/aop/AuthInterceptor.java b/src/main/java/com/cultural/heritage/aop/AuthInterceptor.java
new file mode 100644
index 0000000..a4cf04f
--- /dev/null
+++ b/src/main/java/com/cultural/heritage/aop/AuthInterceptor.java
@@ -0,0 +1,69 @@
+package com.cultural.heritage.aop;
+
+import com.cultural.heritage.annotation.AuthCheck;
+import com.cultural.heritage.common.ErrorCode;
+import com.cultural.heritage.constant.UserConstant;
+import com.cultural.heritage.exception.BusinessException;
+import com.cultural.heritage.model.entity.User;
+import com.cultural.heritage.model.enums.UserRoleEnum;
+import com.cultural.heritage.service.userinfo.UserService;
+import io.micrometer.common.util.StringUtils;
+import jakarta.annotation.Resource;
+import jakarta.servlet.http.HttpServletRequest;
+import org.aspectj.lang.ProceedingJoinPoint;
+import org.aspectj.lang.annotation.Around;
+import org.aspectj.lang.annotation.Aspect;
+import org.springframework.stereotype.Component;
+import org.springframework.web.context.request.RequestAttributes;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+
+/**
+ * 权限校验AOP
+ */
+@Aspect
+@Component
+public class AuthInterceptor {
+
+ @Resource
+ private UserService userService;
+
+ /**
+ * 执行拦截
+ */
+ @Around("@annotation(authCheck)")
+ public Object doInterceptor(ProceedingJoinPoint joinPoint, AuthCheck authCheck) throws Throwable {
+ String mustRole = authCheck.mustRole();
+ RequestAttributes requestAttributes = RequestContextHolder.currentRequestAttributes();
+ HttpServletRequest request = ((ServletRequestAttributes) requestAttributes).getRequest();
+
+ //当前登录用户
+ User loginUser = userService.getLoginUser(request);
+ //必须有该权限才通过
+ if (StringUtils.isNotBlank(mustRole)) {
+ UserRoleEnum mustUserRoleEnum = UserRoleEnum.getEnumByValues(mustRole);
+ if(mustUserRoleEnum == null) {
+ throw new BusinessException(ErrorCode.NO_AUTH_ERROR);
+ }
+ String userRole = loginUser.getUserRole();
+ //如果被封号,直接拒绝
+ if (UserRoleEnum.BAN.equals(mustUserRoleEnum)) {
+ throw new BusinessException(ErrorCode.NO_AUTH_ERROR);
+ }
+ //必须有BOSS权限
+ if (UserRoleEnum.BOSS.equals(mustUserRoleEnum)) {
+ if (!mustRole.equals(userRole)) {
+ throw new BusinessException(ErrorCode.NO_AUTH_ERROR);
+ }
+ }
+ //必须有管理员权限
+ if (UserRoleEnum.ADMIN.equals(mustUserRoleEnum)) {
+ if (!mustRole.equals(userRole) && !userRole.equals(UserConstant.BOSS_ROLE)) {
+ throw new BusinessException(ErrorCode.NO_AUTH_ERROR);
+ }
+ }
+ }
+ //通过权限校验,放行
+ return joinPoint.proceed();
+ }
+}
diff --git a/src/main/java/com/cultural/heritage/aopTest/AopConfig.java b/src/main/java/com/cultural/heritage/aopTest/AopConfig.java
new file mode 100644
index 0000000..ad7cbef
--- /dev/null
+++ b/src/main/java/com/cultural/heritage/aopTest/AopConfig.java
@@ -0,0 +1,61 @@
+package com.cultural.heritage.aopTest;
+
+import jakarta.servlet.http.HttpServletRequest;
+import lombok.extern.log4j.Log4j;
+import lombok.extern.slf4j.Slf4j;
+import org.aspectj.lang.JoinPoint;
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.annotation.Before;
+import org.aspectj.lang.annotation.Pointcut;
+import org.aspectj.lang.reflect.MethodSignature;
+import org.springframework.stereotype.Component;
+import org.springframework.web.context.request.RequestAttributes;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+
+import java.lang.reflect.Method;
+import java.util.Set;
+
+@Component
+@Aspect
+@Slf4j
+public class AopConfig {
+
+ @Pointcut("@annotation(com.cultural.heritage.aopTest.HasRole)")
+ public void pointcut(){}
+
+ @Before("pointcut()")
+ public void before(JoinPoint joinPoint) {
+ System.out.println("before-----------------");
+
+ //获取到HttpServletRequest
+ RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
+ ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) requestAttributes;
+ HttpServletRequest request = servletRequestAttributes.getRequest();
+
+ String username = request.getParameter("username");
+
+ //获取当前用户角色的集合
+ Set userRoles = CacheManager.USER_ROLE_MAP.get(username);
+
+ //获取当前请求的方法的签名
+ MethodSignature signature = (MethodSignature) joinPoint.getSignature();
+
+ //反射获取当前被调用的方法
+ Method method = signature.getMethod();
+
+ //判断当前方法是否有hasRole注解
+ //如果有,判断用户是否具有注解属性中要求的角色
+ //如果没有hasRole注解,那么说明方法不需要判断用户的角色,可以匿名访问
+
+ HasRole hasRole = method.getDeclaredAnnotation(HasRole.class);
+ System.out.println("hasRole:" + hasRole.value());
+ System.out.println("userRoles:" + userRoles);
+ log.info("----------------");
+
+ if(!userRoles.contains(hasRole.value())) {
+ throw new RuntimeException("用户没有访问的权限");
+ }
+
+ }
+}
diff --git a/src/main/java/com/cultural/heritage/aopTest/AopController.java b/src/main/java/com/cultural/heritage/aopTest/AopController.java
new file mode 100644
index 0000000..93ba456
--- /dev/null
+++ b/src/main/java/com/cultural/heritage/aopTest/AopController.java
@@ -0,0 +1,31 @@
+package com.cultural.heritage.aopTest;
+
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+@RequestMapping("/aop")
+public class AopController {
+
+
+ //调用这个方法需要用户具有admin的角色
+ @HasRole("admin")
+ @GetMapping("query1")
+ public String query1() {
+ return "query1 需要 admin 角色";
+ }
+
+ //调用这个方法需要用户具有user的角色
+ @HasRole("user")
+ @GetMapping("query2")
+ public String query2() {
+ return "query2 需要 user 角色";
+ }
+
+ // 任何用户都可以访问
+ @GetMapping("query3")
+ public String query3() {
+ return "query3 可以匿名访问";
+ }
+}
diff --git a/src/main/java/com/cultural/heritage/aopTest/CacheManager.java b/src/main/java/com/cultural/heritage/aopTest/CacheManager.java
new file mode 100644
index 0000000..64454f3
--- /dev/null
+++ b/src/main/java/com/cultural/heritage/aopTest/CacheManager.java
@@ -0,0 +1,22 @@
+package com.cultural.heritage.aopTest;
+
+import com.google.common.collect.Sets;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+public class CacheManager {
+
+ public static final Map> USER_ROLE_MAP = new HashMap<>();
+
+ static {
+ //用户zhangsan具有user和admin两个角色
+ Set roleSet1 = Sets.newHashSet("admin", "user");
+ USER_ROLE_MAP.put("zhangsan", roleSet1);
+
+
+ Set roleSet2 = Sets.newHashSet("user");
+ USER_ROLE_MAP.put("lisi", roleSet2);
+ }
+}
diff --git a/src/main/java/com/cultural/heritage/aopTest/HasRole.java b/src/main/java/com/cultural/heritage/aopTest/HasRole.java
new file mode 100644
index 0000000..b1f7e62
--- /dev/null
+++ b/src/main/java/com/cultural/heritage/aopTest/HasRole.java
@@ -0,0 +1,12 @@
+package com.cultural.heritage.aopTest;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Target(ElementType.METHOD)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface HasRole {
+ String value();
+}
diff --git a/src/main/java/com/cultural/heritage/common/ErrorCode.java b/src/main/java/com/cultural/heritage/common/ErrorCode.java
index d94470a..d6f135b 100644
--- a/src/main/java/com/cultural/heritage/common/ErrorCode.java
+++ b/src/main/java/com/cultural/heritage/common/ErrorCode.java
@@ -8,6 +8,7 @@ public enum ErrorCode {
SUCCESS(1,"ok"),
PARAMS_ERROR(40000,"请求参数错误"),
NOT_LOGIN_ERROR(40100,"未登录"),
+ NO_AUTH_ERROR(40101, "无权限"),
NOT_FOUND_ERROR(40400,"请求数据不存在"),
FORBIDDEN_ERROR(40300,"禁止访问"),
SYSTEM_ERROR(50000,"系统内部异常"),
diff --git a/src/main/java/com/cultural/heritage/constant/UserConstant.java b/src/main/java/com/cultural/heritage/constant/UserConstant.java
index 7e95657..bae6171 100644
--- a/src/main/java/com/cultural/heritage/constant/UserConstant.java
+++ b/src/main/java/com/cultural/heritage/constant/UserConstant.java
@@ -16,4 +16,26 @@ public interface UserConstant {
* 用户登录键
*/
String USER_LOGIN_STATE = "feiyi";
+
+
+ /**
+ * 默认角色
+ */
+ String DEFAULT_ROLE = "user";
+
+ /**
+ * 管理员角色
+ */
+ String ADMIN_ROLE = "admin";
+
+ /**
+ * Boss
+ */
+ String BOSS_ROLE = "boss";
+
+ /**
+ * 被封号
+ */
+ String BAN_ROLE = "ban";
+
}
diff --git a/src/main/java/com/cultural/heritage/controller/userinfo/UserController.java b/src/main/java/com/cultural/heritage/controller/userinfo/UserController.java
index 0aa8669..3345dc1 100644
--- a/src/main/java/com/cultural/heritage/controller/userinfo/UserController.java
+++ b/src/main/java/com/cultural/heritage/controller/userinfo/UserController.java
@@ -1,22 +1,42 @@
package com.cultural.heritage.controller.userinfo;
+import cn.hutool.core.util.IdUtil;
import com.cultural.heritage.common.BaseResponse;
import com.cultural.heritage.common.ErrorCode;
import com.cultural.heritage.common.ResultUtils;
+import com.cultural.heritage.constant.CommonConstant;
+import com.cultural.heritage.constant.UserConstant;
import com.cultural.heritage.exception.BusinessException;
+import com.cultural.heritage.exception.ThrowUtils;
+import com.cultural.heritage.model.dto.CommonRequest;
+import com.cultural.heritage.model.dto.user.UserAddRequest;
import com.cultural.heritage.model.dto.user.UserLoginRequest;
+import com.cultural.heritage.model.dto.user.UserUpdateMyRequest;
+import com.cultural.heritage.model.dto.user.UserUpdateRequest;
import com.cultural.heritage.model.entity.User;
import com.cultural.heritage.model.vo.UserVO;
import com.cultural.heritage.service.userinfo.UserService;
+import com.wf.captcha.SpecCaptcha;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
+import org.apache.catalina.webresources.ExtractingRoot;
import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.BeanUtils;
+import org.springframework.context.annotation.Bean;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.util.DigestUtils;
import org.springframework.web.bind.annotation.*;
+import javax.xml.transform.Result;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+
+import static com.cultural.heritage.constant.UserConstant.SALT;
/**
* 用户接口
@@ -32,6 +52,8 @@ public class UserController {
@Resource
private UserService userService;
+ @Resource
+ private RedisTemplate redisTemplate;
@GetMapping("/test")
public String test(){
@@ -66,6 +88,8 @@ public class UserController {
/**
* 退出登录
+ * @param request http
+ * @return 是否退出登录成功
*/
@PostMapping("/logout")
public BaseResponse userLogout(HttpServletRequest request) {
@@ -78,6 +102,118 @@ public class UserController {
+ /**
+ * 更新个人信息
+ * @param userUpdateMyRequest 更新请求体
+ * @param request http
+ * @return 是否更新成功
+ */
+ @PostMapping("/update/my")
+ public BaseResponse updateMyUser(@RequestBody UserUpdateMyRequest userUpdateMyRequest, HttpServletRequest request) {
+ if (userUpdateMyRequest == null) {
+ throw new BusinessException(ErrorCode.PARAMS_ERROR);
+ }
+ User loginUser = userService.getLoginUser(request);
+ User user = new User();
+ BeanUtils.copyProperties(userUpdateMyRequest, user);
+ user.setId(loginUser.getId());
+ boolean result = userService.updateById(user);
+ ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR);
+ return ResultUtils.success(true);
+ }
+
+
+ /**
+ * 创建用户
+ * @param userAddRequest 用户添加请求体
+ * @return 添加用户的id
+ */
+ @PostMapping("/add")
+ public BaseResponse addUser(@RequestBody UserAddRequest userAddRequest) {
+ if (userAddRequest == null) {
+ throw new BusinessException(ErrorCode.PARAMS_ERROR);
+ }
+ User user = new User();
+ BeanUtils.copyProperties(userAddRequest, user);
+ String encryptPassword = DigestUtils.md5DigestAsHex((SALT + user.getUserPassword()).getBytes());
+ user.setUserPassword(encryptPassword);
+ boolean save = userService.save(user);
+ if (!save) {
+ throw new BusinessException(ErrorCode.SYSTEM_ERROR);
+ }
+ return ResultUtils.success(user, "添加用户成功");
+ }
+
+
+ /**
+ * 删除用户
+ * @param deleteRequest 用户删除请求体
+ * @return 是否删除
+ */
+ @PostMapping("/delete")
+ public BaseResponse deleteUser(@RequestBody CommonRequest deleteRequest) {
+ if (deleteRequest == null || deleteRequest.getId() <= 0) {
+ throw new BusinessException(ErrorCode.PARAMS_ERROR);
+ }
+ boolean result = userService.removeById(deleteRequest.getId());
+ ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR);
+ return ResultUtils.success(true);
+ }
+
+
+ /**
+ * 更新用户
+ * @param userUpdateRequest 用户更新请求体
+ * @return 是否更新成功
+ */
+ @PostMapping("/update")
+ public BaseResponse updateUser(@RequestBody UserUpdateRequest userUpdateRequest) {
+ if (userUpdateRequest == null || userUpdateRequest.getId() == null) {
+ throw new BusinessException(ErrorCode.PARAMS_ERROR);
+ }
+ User user = new User();
+ BeanUtils.copyProperties(userUpdateRequest, user);
+ boolean result = userService.updateById(user);
+ ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR);
+ return ResultUtils.success(true);
+ }
+
+
+ /**
+ * 根据 id 获取用户(仅管理员)
+ * @param id
+ * @return 用户信息
+ */
+ @GetMapping("/get")
+ public BaseResponse getUserById(long id) {
+ if (id <= 0) {
+ throw new BusinessException(ErrorCode.PARAMS_ERROR);
+ }
+ User user = userService.getById(id);
+ ThrowUtils.throwIf(user == null, ErrorCode.NOT_FOUND_ERROR);
+ return ResultUtils.success(user);
+ }
+
+
+
+
+ /**
+ * 图形验证码
+ * @return
+ */
+ @GetMapping("/captcha")
+ public BaseResponse