diff --git a/enlish-service/src/main/java/com/yinlihupo/enlish/service/EnlishServiceApplication.java b/enlish-service/src/main/java/com/yinlihupo/enlish/service/EnlishServiceApplication.java index bfad8a0..670f4ed 100644 --- a/enlish-service/src/main/java/com/yinlihupo/enlish/service/EnlishServiceApplication.java +++ b/enlish-service/src/main/java/com/yinlihupo/enlish/service/EnlishServiceApplication.java @@ -3,11 +3,13 @@ package com.yinlihupo.enlish.service; import org.mybatis.spring.annotation.MapperScan; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.scheduling.annotation.EnableAsync; import org.springframework.scheduling.annotation.EnableScheduling; @SpringBootApplication @MapperScan("com.yinlihupo.enlish.service.domain.mapper") @EnableScheduling +@EnableAsync public class EnlishServiceApplication { public static void main(String[] args) { diff --git a/enlish-service/src/main/java/com/yinlihupo/enlish/service/config/SaTokenConfigure.java b/enlish-service/src/main/java/com/yinlihupo/enlish/service/config/SaTokenConfigure.java new file mode 100644 index 0000000..4922573 --- /dev/null +++ b/enlish-service/src/main/java/com/yinlihupo/enlish/service/config/SaTokenConfigure.java @@ -0,0 +1,46 @@ +package com.yinlihupo.enlish.service.config; + +import cn.dev33.satoken.interceptor.SaInterceptor; +import cn.dev33.satoken.router.SaHttpMethod; +import cn.dev33.satoken.router.SaRouter; +import cn.dev33.satoken.stp.StpUtil; +import lombok.extern.slf4j.Slf4j; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.config.annotation.InterceptorRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +@Configuration +@Slf4j +public class SaTokenConfigure implements WebMvcConfigurer { + + @Override + public void addInterceptors(InterceptorRegistry registry) { + registry.addInterceptor(new SaInterceptor(handler -> { + log.info("Sa-Token 拦截器: {}", handler); + + + SaRouter.match(SaHttpMethod.OPTIONS) + .free(r -> System.out.println("--------OPTIONS预检请求,不做处理")) + .back(); + + SaRouter.match("/**") + .notMatch("/class/list") + .notMatch("/exam/words/get") + .notMatch("/exam/words/detail") + .notMatch("/exam/words/student/history") + .notMatch("grade/list") + .notMatch("/student/list") + .notMatch("/student/detail") + .notMatch("/studentLessonPlans/list") + .notMatch("/studentLessonPlans/history") + .notMatch("/unit/list") + .notMatch("/vocabulary/list") + .notMatch("/plan/download") + .notMatch("/login/**") + .check(r -> StpUtil.checkLogin()); + + })) + .addPathPatterns("/**") + .excludePathPatterns("/error"); + } +} diff --git a/enlish-service/src/main/java/com/yinlihupo/enlish/service/config/StpInterfaceImpl.java b/enlish-service/src/main/java/com/yinlihupo/enlish/service/config/StpInterfaceImpl.java new file mode 100644 index 0000000..2c37014 --- /dev/null +++ b/enlish-service/src/main/java/com/yinlihupo/enlish/service/config/StpInterfaceImpl.java @@ -0,0 +1,46 @@ +package com.yinlihupo.enlish.service.config; + + +import cn.dev33.satoken.stp.StpInterface; + +import com.google.common.cache.Cache; +import com.yinlihupo.enlish.service.constant.RoleConstants; +import com.yinlihupo.framework.common.util.JsonUtils; +import jakarta.annotation.Resource; +import lombok.extern.slf4j.Slf4j; +import org.springframework.data.redis.core.StringRedisTemplate; +import org.springframework.stereotype.Component; + +import java.util.List; + +@Component +@Slf4j +public class StpInterfaceImpl implements StpInterface { + + @Resource + private StringRedisTemplate stringRedisTemplate; + + @Override + public List getPermissionList(Object loginId, String loginType) { + + return List.of(); + } + + @Override + public List getRoleList(Object loginId, String loginType) { + return userToRole((Long) loginId) ; + } + + private List userToRole(Long userId) { + + String keys = stringRedisTemplate.opsForValue().get(RoleConstants.buildUserRoleKey(userId)); + if (keys != null) { + try { + return JsonUtils.parseList(keys, String.class); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + return List.of(); + } +} diff --git a/enlish-service/src/main/java/com/yinlihupo/enlish/service/constant/RoleConstants.java b/enlish-service/src/main/java/com/yinlihupo/enlish/service/constant/RoleConstants.java new file mode 100644 index 0000000..7ad0f77 --- /dev/null +++ b/enlish-service/src/main/java/com/yinlihupo/enlish/service/constant/RoleConstants.java @@ -0,0 +1,11 @@ +package com.yinlihupo.enlish.service.constant; + +public class RoleConstants { + + public final static String USER_ROLE = "user:role"; + public final static String ROLE = "role"; + + public static String buildUserRoleKey(Long userId) { + return USER_ROLE + ":" + userId; + } +} diff --git a/enlish-service/src/main/java/com/yinlihupo/enlish/service/controller/UserController.java b/enlish-service/src/main/java/com/yinlihupo/enlish/service/controller/UserController.java new file mode 100644 index 0000000..26c53ba --- /dev/null +++ b/enlish-service/src/main/java/com/yinlihupo/enlish/service/controller/UserController.java @@ -0,0 +1,30 @@ +package com.yinlihupo.enlish.service.controller; + +import com.yinlihupo.enlish.service.domain.dataobject.UserDO; +import com.yinlihupo.enlish.service.model.vo.user.FindUserInfoRspVO; +import com.yinlihupo.enlish.service.service.UserService; +import com.yinlihupo.framework.common.response.Response; +import jakarta.annotation.Resource; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/user/") +public class UserController { + + @Resource + private UserService userService; + + @PostMapping("info") + public Response info() { + + UserDO user = userService.findUser(); + FindUserInfoRspVO findUserInfoRspVO = FindUserInfoRspVO.builder() + .id(user.getId()) + .name(user.getName()) + .build(); + return Response.success(findUserInfoRspVO); + + } +} diff --git a/enlish-service/src/main/java/com/yinlihupo/enlish/service/domain/dataobject/RoleDO.java b/enlish-service/src/main/java/com/yinlihupo/enlish/service/domain/dataobject/RoleDO.java new file mode 100644 index 0000000..e4effc3 --- /dev/null +++ b/enlish-service/src/main/java/com/yinlihupo/enlish/service/domain/dataobject/RoleDO.java @@ -0,0 +1,28 @@ +package com.yinlihupo.enlish.service.domain.dataobject; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.Date; + +@AllArgsConstructor +@NoArgsConstructor +@Data +@Builder +public class RoleDO { + + private Long id; + + private String roleName; + + private String roleKey; + + private Integer status; + + private Date createTime; + + private Integer isDeleted; + +} \ No newline at end of file diff --git a/enlish-service/src/main/java/com/yinlihupo/enlish/service/domain/dataobject/UserRoleRelDO.java b/enlish-service/src/main/java/com/yinlihupo/enlish/service/domain/dataobject/UserRoleRelDO.java new file mode 100644 index 0000000..6a43c9c --- /dev/null +++ b/enlish-service/src/main/java/com/yinlihupo/enlish/service/domain/dataobject/UserRoleRelDO.java @@ -0,0 +1,55 @@ +package com.yinlihupo.enlish.service.domain.dataobject; + +import java.util.Date; + +public class UserRoleRelDO { + private Long id; + + private Long userId; + + private Long roleId; + + private Date createTime; + + private Boolean isDeleted; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public Long getUserId() { + return userId; + } + + public void setUserId(Long userId) { + this.userId = userId; + } + + public Long getRoleId() { + return roleId; + } + + public void setRoleId(Long roleId) { + this.roleId = roleId; + } + + public Date getCreateTime() { + return createTime; + } + + public void setCreateTime(Date createTime) { + this.createTime = createTime; + } + + public Boolean getIsDeleted() { + return isDeleted; + } + + public void setIsDeleted(Boolean isDeleted) { + this.isDeleted = isDeleted; + } +} \ No newline at end of file diff --git a/enlish-service/src/main/java/com/yinlihupo/enlish/service/domain/mapper/RoleDOMapper.java b/enlish-service/src/main/java/com/yinlihupo/enlish/service/domain/mapper/RoleDOMapper.java new file mode 100644 index 0000000..7cf5ae5 --- /dev/null +++ b/enlish-service/src/main/java/com/yinlihupo/enlish/service/domain/mapper/RoleDOMapper.java @@ -0,0 +1,10 @@ +package com.yinlihupo.enlish.service.domain.mapper; + +import com.yinlihupo.enlish.service.domain.dataobject.RoleDO; + +import java.util.List; + +public interface RoleDOMapper { + + List selectAll(); +} \ No newline at end of file diff --git a/enlish-service/src/main/java/com/yinlihupo/enlish/service/domain/mapper/UserDOMapper.java b/enlish-service/src/main/java/com/yinlihupo/enlish/service/domain/mapper/UserDOMapper.java index 4241985..2815fe9 100644 --- a/enlish-service/src/main/java/com/yinlihupo/enlish/service/domain/mapper/UserDOMapper.java +++ b/enlish-service/src/main/java/com/yinlihupo/enlish/service/domain/mapper/UserDOMapper.java @@ -7,4 +7,6 @@ public interface UserDOMapper { UserDO selectByPhone(String phone); void insert(UserDO userDO); + + UserDO selectById(Long id); } \ No newline at end of file diff --git a/enlish-service/src/main/java/com/yinlihupo/enlish/service/domain/mapper/UserRoleRelDOMapper.java b/enlish-service/src/main/java/com/yinlihupo/enlish/service/domain/mapper/UserRoleRelDOMapper.java new file mode 100644 index 0000000..60c4d6a --- /dev/null +++ b/enlish-service/src/main/java/com/yinlihupo/enlish/service/domain/mapper/UserRoleRelDOMapper.java @@ -0,0 +1,10 @@ +package com.yinlihupo.enlish.service.domain.mapper; + +import com.yinlihupo.enlish.service.domain.dataobject.UserRoleRelDO; + +import java.util.List; + +public interface UserRoleRelDOMapper { + + List selectAll(); +} \ No newline at end of file diff --git a/enlish-service/src/main/java/com/yinlihupo/enlish/service/enums/ResponseCodeEnum.java b/enlish-service/src/main/java/com/yinlihupo/enlish/service/enums/ResponseCodeEnum.java index f8f8f7a..b2cc066 100644 --- a/enlish-service/src/main/java/com/yinlihupo/enlish/service/enums/ResponseCodeEnum.java +++ b/enlish-service/src/main/java/com/yinlihupo/enlish/service/enums/ResponseCodeEnum.java @@ -13,7 +13,7 @@ public enum ResponseCodeEnum implements BaseExceptionInterface { // ----------- 通用异常状态码 ----------- SYSTEM_ERROR("AUTH-10000", "出错啦,后台小哥正在努力修复中..."), PARAM_NOT_VALID("AUTH-10001", "参数错误"), - + NOT_LOGIN("AUTH-10002", "请先登录") // ----------- 业务异常状态码 ----------- ; diff --git a/enlish-service/src/main/java/com/yinlihupo/enlish/service/exception/GlobalExceptionHandler.java b/enlish-service/src/main/java/com/yinlihupo/enlish/service/exception/GlobalExceptionHandler.java index 4c00734..8f688e6 100644 --- a/enlish-service/src/main/java/com/yinlihupo/enlish/service/exception/GlobalExceptionHandler.java +++ b/enlish-service/src/main/java/com/yinlihupo/enlish/service/exception/GlobalExceptionHandler.java @@ -1,6 +1,7 @@ package com.yinlihupo.enlish.service.exception; +import cn.dev33.satoken.exception.NotLoginException; import com.yinlihupo.enlish.service.enums.ResponseCodeEnum; import com.yinlihupo.framework.common.exception.BizException; import com.yinlihupo.framework.common.response.Response; @@ -96,4 +97,11 @@ public class GlobalExceptionHandler { log.error("{} request error, ", request.getRequestURI(), e); return Response.fail(ResponseCodeEnum.SYSTEM_ERROR); } + + @ExceptionHandler({ NotLoginException.class }) + @ResponseBody + public Response handleNotLoginException(HttpServletRequest request, NotLoginException e) { + log.warn("{} request error, ", request.getRequestURI(), e); + return Response.fail(ResponseCodeEnum.NOT_LOGIN); + } } diff --git a/enlish-service/src/main/java/com/yinlihupo/enlish/service/model/vo/user/FindUserInfoRspVO.java b/enlish-service/src/main/java/com/yinlihupo/enlish/service/model/vo/user/FindUserInfoRspVO.java new file mode 100644 index 0000000..f3ee7fa --- /dev/null +++ b/enlish-service/src/main/java/com/yinlihupo/enlish/service/model/vo/user/FindUserInfoRspVO.java @@ -0,0 +1,16 @@ +package com.yinlihupo.enlish.service.model.vo.user; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@AllArgsConstructor +@NoArgsConstructor +@Data +@Builder +public class FindUserInfoRspVO { + + private Long id; + private String name; +} diff --git a/enlish-service/src/main/java/com/yinlihupo/enlish/service/service/UserService.java b/enlish-service/src/main/java/com/yinlihupo/enlish/service/service/UserService.java new file mode 100644 index 0000000..973aa0a --- /dev/null +++ b/enlish-service/src/main/java/com/yinlihupo/enlish/service/service/UserService.java @@ -0,0 +1,10 @@ +package com.yinlihupo.enlish.service.service; + +import com.yinlihupo.enlish.service.domain.dataobject.UserDO; + +public interface UserService { + + void pushRolePermission2Redis(); + + UserDO findUser(); +} diff --git a/enlish-service/src/main/java/com/yinlihupo/enlish/service/service/user/UserServiceImpl.java b/enlish-service/src/main/java/com/yinlihupo/enlish/service/service/user/UserServiceImpl.java new file mode 100644 index 0000000..3bbc3f8 --- /dev/null +++ b/enlish-service/src/main/java/com/yinlihupo/enlish/service/service/user/UserServiceImpl.java @@ -0,0 +1,63 @@ +package com.yinlihupo.enlish.service.service.user; + +import cn.dev33.satoken.stp.StpUtil; +import com.yinlihupo.enlish.service.constant.RoleConstants; +import com.yinlihupo.enlish.service.domain.dataobject.RoleDO; +import com.yinlihupo.enlish.service.domain.dataobject.UserDO; +import com.yinlihupo.enlish.service.domain.dataobject.UserRoleRelDO; +import com.yinlihupo.enlish.service.domain.mapper.RoleDOMapper; +import com.yinlihupo.enlish.service.domain.mapper.UserDOMapper; +import com.yinlihupo.enlish.service.domain.mapper.UserRoleRelDOMapper; +import com.yinlihupo.enlish.service.service.UserService; +import com.yinlihupo.framework.common.util.JsonUtils; +import jakarta.annotation.Resource; +import lombok.extern.slf4j.Slf4j; +import org.springframework.data.redis.core.StringRedisTemplate; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +@Service +@Slf4j +public class UserServiceImpl implements UserService { + + @Resource + private StringRedisTemplate stringRedisTemplate; + @Resource + private RoleDOMapper roleDOMapper; + @Resource + private UserRoleRelDOMapper userRoleRelDOMapper; + @Resource + private UserDOMapper userDOMapper; + + @Override + public void pushRolePermission2Redis() { + List roleDOS = roleDOMapper.selectAll(); + List roleKeys = roleDOS.stream().map(RoleDO::getRoleKey).toList(); + log.info("将角色同步到 redis 中, {}", roleKeys); + stringRedisTemplate.opsForValue().set(RoleConstants.ROLE, JsonUtils.toJsonString(roleKeys), 60 * 60 * 24); + + Map roleId2RoleDO = roleDOS.stream().collect(Collectors.toMap(RoleDO::getId, roleDO -> roleDO)); + + List userRoleRelDOS = userRoleRelDOMapper.selectAll(); + Map> userId2UserRoleRelDOs = userRoleRelDOS.stream().collect(Collectors.groupingBy(UserRoleRelDO::getUserId)); + + userId2UserRoleRelDOs.forEach((userId, userRoleRelDOs) -> { + List roleIds = userRoleRelDOs.stream().map(UserRoleRelDO::getRoleId).toList(); + List roleDOs = roleIds.stream().map(roleId2RoleDO::get).toList(); + List user2RoleKeys = roleDOs.stream().map(RoleDO::getRoleKey).toList(); + log.info("将用户 {} 的角色同步到 redis 中, {}", userId, roleKeys); + stringRedisTemplate.opsForValue().set(RoleConstants.buildUserRoleKey(userId), JsonUtils.toJsonString(user2RoleKeys), 60 * 60 * 24); + }); + } + + @Override + public UserDO findUser() { + String loginIdStr =(String) StpUtil.getLoginId(); + Long loginId = Long.parseLong(loginIdStr); + return userDOMapper.selectById(loginId); + } + +} diff --git a/enlish-service/src/main/java/com/yinlihupo/enlish/service/task/UserRoleTask.java b/enlish-service/src/main/java/com/yinlihupo/enlish/service/task/UserRoleTask.java new file mode 100644 index 0000000..c2ae91b --- /dev/null +++ b/enlish-service/src/main/java/com/yinlihupo/enlish/service/task/UserRoleTask.java @@ -0,0 +1,23 @@ +package com.yinlihupo.enlish.service.task; + + +import com.yinlihupo.enlish.service.service.UserService; +import jakarta.annotation.Resource; +import lombok.extern.slf4j.Slf4j; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; + + +@Component +@Slf4j +public class UserRoleTask { + + @Resource + private UserService userService; + + @Scheduled(cron = "0 0 1 * * ?") + public void PushRolePermissions2Redis() { + log.info("定时任务,将系统权限推送到 redis 中"); + userService.pushRolePermission2Redis(); + } +} diff --git a/enlish-service/src/main/resources/generatorConfig.xml b/enlish-service/src/main/resources/generatorConfig.xml index 5c71e0d..df879be 100644 --- a/enlish-service/src/main/resources/generatorConfig.xml +++ b/enlish-service/src/main/resources/generatorConfig.xml @@ -45,7 +45,7 @@ targetProject="src/main/java"/> - + + + + + + + + + + + + + + \ No newline at end of file diff --git a/enlish-service/src/main/resources/mapper/UserDOMapper.xml b/enlish-service/src/main/resources/mapper/UserDOMapper.xml index 5031707..cda2424 100644 --- a/enlish-service/src/main/resources/mapper/UserDOMapper.xml +++ b/enlish-service/src/main/resources/mapper/UserDOMapper.xml @@ -24,4 +24,11 @@ and is_deleted = 0 + + \ No newline at end of file diff --git a/enlish-service/src/main/resources/mapper/UserRoleRelDOMapper.xml b/enlish-service/src/main/resources/mapper/UserRoleRelDOMapper.xml new file mode 100644 index 0000000..3079ea8 --- /dev/null +++ b/enlish-service/src/main/resources/mapper/UserRoleRelDOMapper.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/enlish-vue/src/api/user.js b/enlish-vue/src/api/user.js index 78b7225..2d87b0c 100644 --- a/enlish-vue/src/api/user.js +++ b/enlish-vue/src/api/user.js @@ -7,3 +7,7 @@ export function login(data) { export function getVerificationCode(data) { return axios.post("/login/sendVerificationCode", data) } + +export function getUserInfo() { + return axios.post("/user/info") +} diff --git a/enlish-vue/src/layouts/components/Header.vue b/enlish-vue/src/layouts/components/Header.vue index cfa9a4d..c07ab11 100644 --- a/enlish-vue/src/layouts/components/Header.vue +++ b/enlish-vue/src/layouts/components/Header.vue @@ -7,10 +7,18 @@ Flowbite - +