diff --git a/src/main/java/cn/soul2/jyjc/admin/annotation/SkinLogin.java b/src/main/java/cn/soul2/jyjc/admin/annotation/SkinLogin.java new file mode 100644 index 0000000..db845a4 --- /dev/null +++ b/src/main/java/cn/soul2/jyjc/admin/annotation/SkinLogin.java @@ -0,0 +1,15 @@ +package cn.soul2.jyjc.admin.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * @author Soul2 + * @date 2024-04-02 + */ +@Target({ElementType.METHOD, ElementType.TYPE}) +@Retention(RetentionPolicy.RUNTIME) +public @interface SkinLogin { +} diff --git a/src/main/java/cn/soul2/jyjc/admin/config/CorsConfig.java b/src/main/java/cn/soul2/jyjc/admin/config/CorsConfig.java index acc3f82..1f56696 100644 --- a/src/main/java/cn/soul2/jyjc/admin/config/CorsConfig.java +++ b/src/main/java/cn/soul2/jyjc/admin/config/CorsConfig.java @@ -5,10 +5,6 @@ import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.CorsRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - /** * @author Soul2 * @date 2024-03-25 @@ -16,47 +12,14 @@ import java.util.List; @Configuration public class CorsConfig implements WebMvcConfigurer { - @Value("${cors.allow-origins}") - private String[] allowOriginArray; - - /** - * 将数组转换为List进行动态添加 - */ - private final List allowOriginList = new ArrayList<>(); - -// private static boolean isLocalV4Address(String ipAddress) { -// // todo 为进行手机测试而增加的读取内网IP,正式上线时须注释掉 -// String[] parts = ipAddress.split("\\."); -// // 判断是否是有效的IPv4地址并且属于局域网 -// return parts.length == 4 && parts[0].equals("192") && parts[1].equals("168"); -// } + @Value("${cors.allow-origin}") + private String[] allowOrigin; @Override public void addCorsMappings(CorsRegistry registry) { - allowOriginList.addAll(Arrays.asList(allowOriginArray)); -// // todo 为进行手机测试而增加的读取内网IP,正式上线时须注释掉 -// try { -// Enumeration networkInterfaces = NetworkInterface.getNetworkInterfaces(); -// while (networkInterfaces.hasMoreElements()) { -// NetworkInterface networkInterface = networkInterfaces.nextElement(); -// Enumeration inetAddresses = networkInterface.getInetAddresses(); -// while (inetAddresses.hasMoreElements()) { -// InetAddress inetAddress = inetAddresses.nextElement(); -// if (isLocalV4Address(inetAddress.getHostAddress())) { -// System.out.println("Local IPv4 Address: " + inetAddress.getHostAddress()); -// allowOriginList.add("http://" + inetAddress.getHostAddress() + ":7620"); -// } -// } -// } -// } catch (Exception e) { -// e.printStackTrace(); -// } - - // 打印 allowOriginList 到控制台 -// System.out.println("allowOriginList: " + allowOriginList); - registry.addMapping("/**") - .allowedOrigins(allowOriginList.toArray(new String[0])) + .allowedHeaders("*") + .allowedOrigins(allowOrigin) .allowCredentials(true) .allowedMethods("POST") .maxAge(3600); diff --git a/src/main/java/cn/soul2/jyjc/admin/config/UserLoginStatusBean.java b/src/main/java/cn/soul2/jyjc/admin/config/UserLoginStatusBean.java new file mode 100644 index 0000000..3937559 --- /dev/null +++ b/src/main/java/cn/soul2/jyjc/admin/config/UserLoginStatusBean.java @@ -0,0 +1,92 @@ +package cn.soul2.jyjc.admin.config; + +import cn.soul2.jyjc.admin.entity.UserLoginOutDO; +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Component; + +import java.time.LocalDateTime; +import java.util.concurrent.ConcurrentHashMap; + +@Component +public class UserLoginStatusBean { + + private ConcurrentHashMap loginStatusMap = new ConcurrentHashMap<>(); + + /** + * 缓存登录信息 + * + * @param token token + * @param loginOutStatus 登录信息 + */ + public void login(String token, UserLoginOutDO loginOutStatus) { + loginStatusMap.put(token, loginOutStatus); + } + + /** + * 从缓存读取登录信息 + * + * @param token token + * @return {@link UserLoginOutDO} + */ + public UserLoginOutDO getStatus(String token) { + UserLoginOutDO loginStatus = loginStatusMap.getOrDefault(token, null); + if (loginStatus.getLapseTime() != null) { + LocalDateTime now = LocalDateTime.now(); + if (now.isAfter(loginStatus.getLapseTime())) { + logout(token); + return null; + } + } + return loginStatus; + } + + /** + * 为key设置登出 + * + * @param token token + * @return {@link Boolean} + */ + public Boolean logout(String token) { + if (StringUtils.isNotBlank(token) && loginStatusMap.containsKey(token)) { + UserLoginOutDO removedUser = loginStatusMap.remove(token); + // 返回true表示成功登出,返回false表示未成功登出 + return removedUser != null; + } + return Boolean.TRUE; + } + + public Boolean logoutByUserId(String userId) { + final String[] targetKey = {null}; + loginStatusMap.forEach((k, v) -> { + if (targetKey[0] == null && v.getUserId().equals(userId)) { + targetKey[0] = k; + } + }); + return logout(targetKey[0]); + } + + public String getTokenByUsername(String username) { + final String[] token = {null}; + loginStatusMap.forEach((k, v) -> { + if (token[0] == null && v.getUserName().equals(username)) { + token[0] = k; + } + }); + return token[0]; + } + + public Boolean containsToken(String token) { + if (StringUtils.isBlank(token)) { + return Boolean.FALSE; + } + UserLoginOutDO loginStatus = loginStatusMap.getOrDefault(token, null); + if (loginStatus.getLapseTime() != null) { + LocalDateTime now = LocalDateTime.now(); + if (now.isAfter(loginStatus.getLapseTime())) { + logout(token); + } + } + return loginStatusMap.containsKey(token); + } + +} diff --git a/src/main/java/cn/soul2/jyjc/admin/config/WebMvcConfig.java b/src/main/java/cn/soul2/jyjc/admin/config/WebMvcConfig.java new file mode 100644 index 0000000..a8e0b1c --- /dev/null +++ b/src/main/java/cn/soul2/jyjc/admin/config/WebMvcConfig.java @@ -0,0 +1,24 @@ +package cn.soul2.jyjc.admin.config; + +import cn.soul2.jyjc.admin.interceptor.TokenInterceptor; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.config.annotation.InterceptorRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +/** + * 注册请求拦截器 + * + * @author Soul2 + * @date 2024-04-02 + */ + +@Configuration +public class WebMvcConfig implements WebMvcConfigurer { + + @Override + public void addInterceptors(InterceptorRegistry registry) { + registry.addInterceptor(new TokenInterceptor()) + // 拦截所有路径 + .addPathPatterns("/**"); + } +} diff --git a/src/main/java/cn/soul2/jyjc/admin/controller/AnswerController.java b/src/main/java/cn/soul2/jyjc/admin/controller/AnswerController.java new file mode 100644 index 0000000..3dd0c9e --- /dev/null +++ b/src/main/java/cn/soul2/jyjc/admin/controller/AnswerController.java @@ -0,0 +1,32 @@ +package cn.soul2.jyjc.admin.controller; + +import cn.soul2.jyjc.admin.dto.AnswerSubmitDTO; +import cn.soul2.jyjc.admin.service.IAnswerService; +import cn.soul2.jyjc.admin.utils.base.BackUtils; +import cn.soul2.jyjc.admin.vo.base.Back; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @author Soul2 + * @date 2024-03-27 13:24 + */ + +@Slf4j +@RestController +@RequestMapping("/answer") +public class AnswerController { + + @Autowired + private IAnswerService answerService; + + @PostMapping("submit") + public Back submit(@RequestBody AnswerSubmitDTO dto) { + return BackUtils.success(answerService.handleSubmit(dto)); + } + +} diff --git a/src/main/java/cn/soul2/jyjc/admin/controller/UserController.java b/src/main/java/cn/soul2/jyjc/admin/controller/UserController.java new file mode 100644 index 0000000..1b5a152 --- /dev/null +++ b/src/main/java/cn/soul2/jyjc/admin/controller/UserController.java @@ -0,0 +1,47 @@ +package cn.soul2.jyjc.admin.controller; + +import cn.soul2.jyjc.admin.annotation.SkinLogin; +import cn.soul2.jyjc.admin.dto.UserLoginDTO; +import cn.soul2.jyjc.admin.dto.UserLogoutDTO; +import cn.soul2.jyjc.admin.service.IUserService; +import cn.soul2.jyjc.admin.utils.base.BackUtils; +import cn.soul2.jyjc.admin.vo.UserVO; +import cn.soul2.jyjc.admin.vo.base.Back; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @author Soul2 + * @date 2024-03-31 15:48 + */ + +@Slf4j +@RestController +@RequestMapping("/user") +public class UserController { + + @Autowired + private IUserService userService; + + @PostMapping("login") + @SkinLogin + public Back login(@RequestBody UserLoginDTO dto) { + return BackUtils.success(userService.login(dto)); + } + + @PostMapping("register") + @SkinLogin + public Back register(@RequestBody UserLoginDTO dto) { + return BackUtils.success(userService.register(dto)); + } + + @PostMapping("logout") + public Back logout(@RequestBody UserLogoutDTO dto) { + return BackUtils.success(userService.logout(dto)); + } + +} diff --git a/src/main/java/cn/soul2/jyjc/admin/dto/AnswerDetailDTO.java b/src/main/java/cn/soul2/jyjc/admin/dto/AnswerDetailDTO.java new file mode 100644 index 0000000..d279f46 --- /dev/null +++ b/src/main/java/cn/soul2/jyjc/admin/dto/AnswerDetailDTO.java @@ -0,0 +1,45 @@ +package cn.soul2.jyjc.admin.dto; + +import lombok.Data; +import lombok.experimental.Accessors; + +/** + * @author Soul2 + * @date 2024-03-27 13:31 + */ + +@Data +@Accessors(chain = true) +public class AnswerDetailDTO { + + /** + * 回答内容(文字/选项id,多选时以,分隔) + */ + private String content; + + /** + * 得分 + */ + private Integer points; + + /** + * 题目id + */ + private String subjectId; + + /** + * 题目类型:0-单选;1-多选;2-文字 + */ + private Integer subjectType; + + /** + * 题目分值 + */ + private Integer subjectPoints; + + /** + * 权重 + */ + private Double weights; + +} diff --git a/src/main/java/cn/soul2/jyjc/admin/dto/AnswerSubmitDTO.java b/src/main/java/cn/soul2/jyjc/admin/dto/AnswerSubmitDTO.java new file mode 100644 index 0000000..2b605fc --- /dev/null +++ b/src/main/java/cn/soul2/jyjc/admin/dto/AnswerSubmitDTO.java @@ -0,0 +1,37 @@ +package cn.soul2.jyjc.admin.dto; + +import lombok.Data; +import lombok.experimental.Accessors; + +import java.util.List; + +/** + * @author Soul2 + * @date 2024-03-27 13:26 + */ + +@Data +@Accessors(chain = true) +public class AnswerSubmitDTO { + + /** + * 二维码id + */ + private String qrId; + + /** + * 问卷Id + */ + private String qnId; + + /** + * openid, 即答卷人 + */ + private String openid; + + /** + * 答题内容 + */ + private List details; + +} diff --git a/src/main/java/cn/soul2/jyjc/admin/dto/UserLoginDTO.java b/src/main/java/cn/soul2/jyjc/admin/dto/UserLoginDTO.java new file mode 100644 index 0000000..b2789a8 --- /dev/null +++ b/src/main/java/cn/soul2/jyjc/admin/dto/UserLoginDTO.java @@ -0,0 +1,30 @@ +package cn.soul2.jyjc.admin.dto; + +import lombok.Data; +import lombok.experimental.Accessors; + +/** + * @author Soul2 + * @date 2024-03-29 21:55 + */ + +@Data +@Accessors(chain = true) +public class UserLoginDTO { + + /** + * userName + */ + private String username; + + /** + * password + */ + private String password; + + /** + * 密码错误次数(暂未使用) + */ + private Integer pswErrorCount; + +} diff --git a/src/main/java/cn/soul2/jyjc/admin/dto/UserLoginOutPageDTO.java b/src/main/java/cn/soul2/jyjc/admin/dto/UserLoginOutPageDTO.java new file mode 100644 index 0000000..5ee7529 --- /dev/null +++ b/src/main/java/cn/soul2/jyjc/admin/dto/UserLoginOutPageDTO.java @@ -0,0 +1,21 @@ +package cn.soul2.jyjc.admin.dto; + +import cn.soul2.jyjc.admin.dto.base.PageParams; +import lombok.Data; +import lombok.experimental.Accessors; + +/** + * @author Soul2 + * @date 2024-03-29 21:50 + */ + +@Data +@Accessors(chain = true) +public class UserLoginOutPageDTO extends PageParams { + + /** + * userId + */ + private String userId; + +} diff --git a/src/main/java/cn/soul2/jyjc/admin/dto/UserLogoutDTO.java b/src/main/java/cn/soul2/jyjc/admin/dto/UserLogoutDTO.java new file mode 100644 index 0000000..3b8c029 --- /dev/null +++ b/src/main/java/cn/soul2/jyjc/admin/dto/UserLogoutDTO.java @@ -0,0 +1,25 @@ +package cn.soul2.jyjc.admin.dto; + +import lombok.Data; +import lombok.experimental.Accessors; + +/** + * @author Soul2 + * @date 2024-03-29 21:56 + */ + +@Data +@Accessors(chain = true) +public class UserLogoutDTO { + + /** + * userName + */ + private String username; + + /** + * token + */ + private String token; + +} diff --git a/src/main/java/cn/soul2/jyjc/admin/dto/UserPageDTO.java b/src/main/java/cn/soul2/jyjc/admin/dto/UserPageDTO.java new file mode 100644 index 0000000..7fd23b3 --- /dev/null +++ b/src/main/java/cn/soul2/jyjc/admin/dto/UserPageDTO.java @@ -0,0 +1,37 @@ +package cn.soul2.jyjc.admin.dto; + +import cn.soul2.jyjc.admin.dto.base.PageParams; +import lombok.Data; +import lombok.experimental.Accessors; + +import java.time.LocalDateTime; + +/** + * @author Soul2 + * @date 2024-03-29 20:50 + */ + +@Data +@Accessors(chain = true) +public class UserPageDTO extends PageParams { + + /** + * id + */ + private String id; + /** + * 用户名 + */ + private String username; + /** + * 状态;0(默认):正常;4:封号;9:异常; + */ + private Integer status; + + /** + * 注册时间 + */ + private LocalDateTime startTime; + private LocalDateTime endTime; + +} diff --git a/src/main/java/cn/soul2/jyjc/admin/dto/UserSaveDTO.java b/src/main/java/cn/soul2/jyjc/admin/dto/UserSaveDTO.java new file mode 100644 index 0000000..47567d3 --- /dev/null +++ b/src/main/java/cn/soul2/jyjc/admin/dto/UserSaveDTO.java @@ -0,0 +1,45 @@ +package cn.soul2.jyjc.admin.dto; + +import lombok.Data; +import lombok.experimental.Accessors; + +/** + * @author Soul2 + * @date 2024-03-29 20:50 + */ + +@Data +@Accessors(chain = true) +public class UserSaveDTO { + + /** + * id + */ + private String id; + + /** + * 用户名 + */ + private String username; + + /** + * 密码 + */ + private String password; + + /** + * 状态;0(默认):正常;4:封号;9:异常; + */ + private Integer status; + + /** + * 权限等级,默认200 + */ + private Integer authorityLevel; + + /** + * 密码修改次数 + */ + private Integer pswChange; + +} diff --git a/src/main/java/cn/soul2/jyjc/admin/entity/AnswerDetailsDO.java b/src/main/java/cn/soul2/jyjc/admin/entity/AnswerDetailsDO.java index 6078772..ef63e7c 100644 --- a/src/main/java/cn/soul2/jyjc/admin/entity/AnswerDetailsDO.java +++ b/src/main/java/cn/soul2/jyjc/admin/entity/AnswerDetailsDO.java @@ -15,7 +15,7 @@ import java.time.LocalDateTime; *

* * @author Soul2 - * @since 2024-03-12 10:10:24 + * @since 2024-03-27 15:38:51 */ @Getter @Setter @@ -32,10 +32,10 @@ public class AnswerDetailsDO extends Model { private String id; /** - * 状态:0:禁用;1:启用; + * 题目类型:0-单选;1-多选;2-文字 */ - @TableField("status") - private Short status; + @TableField("subject_type") + private Integer subjectType; /** * 更新时间 diff --git a/src/main/java/cn/soul2/jyjc/admin/entity/SubjectDO.java b/src/main/java/cn/soul2/jyjc/admin/entity/SubjectDO.java index d4abd9a..253d766 100644 --- a/src/main/java/cn/soul2/jyjc/admin/entity/SubjectDO.java +++ b/src/main/java/cn/soul2/jyjc/admin/entity/SubjectDO.java @@ -15,7 +15,7 @@ import java.time.LocalDateTime; *

* * @author Soul2 - * @since 2024-03-12 10:10:24 + * @since 2024-03-27 15:38:52 */ @Getter @Setter @@ -80,8 +80,20 @@ public class SubjectDO extends Model { @TableField("type") private Short type; + /** + * 权重 + */ + @TableField("weights") + private Double weights; + + /** + * 分值 + */ + @TableField("points") + private Integer points; + @Override public Serializable pkVal() { - return null; + return this.id; } } diff --git a/src/main/java/cn/soul2/jyjc/admin/entity/SubjectItemsDO.java b/src/main/java/cn/soul2/jyjc/admin/entity/SubjectItemsDO.java index dc43e7f..72c4101 100644 --- a/src/main/java/cn/soul2/jyjc/admin/entity/SubjectItemsDO.java +++ b/src/main/java/cn/soul2/jyjc/admin/entity/SubjectItemsDO.java @@ -72,7 +72,7 @@ public class SubjectItemsDO extends Model { * 权重 */ @TableField("weights") - private Object weights; + private Double weights; /** * 分值 diff --git a/src/main/java/cn/soul2/jyjc/admin/entity/UserDO.java b/src/main/java/cn/soul2/jyjc/admin/entity/UserDO.java new file mode 100644 index 0000000..51c3314 --- /dev/null +++ b/src/main/java/cn/soul2/jyjc/admin/entity/UserDO.java @@ -0,0 +1,93 @@ +package cn.soul2.jyjc.admin.entity; + +import com.baomidou.mybatisplus.annotation.*; +import com.baomidou.mybatisplus.extension.activerecord.Model; +import lombok.Getter; +import lombok.Setter; +import lombok.experimental.Accessors; + +import java.io.Serializable; +import java.time.LocalDateTime; + +/** + *

+ * 用户表 + *

+ * + * @author Soul2 + * @since 2024-03-30 14:34:13 + */ +@Getter +@Setter +@Accessors(chain = true) +@TableName("tb_user") +public class UserDO extends Model { + + private static final long serialVersionUID = 1L; + + /** + * id + */ + @TableId(value = "id", type = IdType.ASSIGN_UUID) + private String id; + + /** + * 用户名 + */ + @TableField("username") + private String username; + + /** + * 密码 + */ + @TableField("password") + private String password; + + /** + * 状态;0(默认):正常;4:封号;9:异常; + */ + @TableField("status") + private Integer status; + + /** + * 权限等级,默认200 + */ + @TableField("authority_level") + private Integer authorityLevel; + + /** + * 密码修改次数 + */ + @TableField("psw_change") + private Integer pswChange; + + /** + * 更新时间 + */ + @TableField(value = "updated_time", fill = FieldFill.INSERT_UPDATE) + private LocalDateTime updatedTime; + + /** + * 创建时间 + */ + @TableField(value = "created_time", fill = FieldFill.INSERT) + private LocalDateTime createdTime; + + /** + * 删除标记 + */ + @TableField("removed") + @TableLogic + private Integer removed; + + /** + * 盐,用于密码加密,未启用 + */ + @TableField("salt") + private String salt; + + @Override + public Serializable pkVal() { + return this.id; + } +} diff --git a/src/main/java/cn/soul2/jyjc/admin/entity/UserLoginOutDO.java b/src/main/java/cn/soul2/jyjc/admin/entity/UserLoginOutDO.java new file mode 100644 index 0000000..cf3e801 --- /dev/null +++ b/src/main/java/cn/soul2/jyjc/admin/entity/UserLoginOutDO.java @@ -0,0 +1,87 @@ +package cn.soul2.jyjc.admin.entity; + +import com.baomidou.mybatisplus.annotation.*; +import com.baomidou.mybatisplus.extension.activerecord.Model; +import lombok.Getter; +import lombok.Setter; +import lombok.experimental.Accessors; + +import java.io.Serializable; +import java.time.LocalDateTime; + +/** + *

+ * 用户登入登出表 + *

+ * + * @author Soul2 + * @since 2024-03-30 13:57:00 + */ +@Getter +@Setter +@Accessors(chain = true) +@TableName("tb_user_login_out") +public class UserLoginOutDO extends Model { + + private static final long serialVersionUID = 1L; + + /** + * id + */ + @TableId(value = "id", type = IdType.ASSIGN_UUID) + private String id; + + /** + * 用户id + */ + @TableField("user_id") + private String userId; + + /** + * 用户名称 + */ + @TableField("user_name") + private String userName; + + /** + * 登录时间,登录成功才写入 + */ + @TableField("login_time") + private LocalDateTime loginTime; + + /** + * 登录失效时间 + */ + @TableField("lapse_time") + private LocalDateTime lapseTime; + + /** + * 用户操作登出时间 + */ + @TableField("logout_time") + private LocalDateTime logoutTime; + + /** + * 密码错误次数 + */ + @TableField("psw_error_count") + private Integer pswErrorCount; + + /** + * 创建时间 + */ + @TableField(value = "created_time", fill = FieldFill.INSERT) + private LocalDateTime createdTime; + + /** + * 1=删除;0=未删除 + */ + @TableField("removed") + @TableLogic + private Integer removed; + + @Override + public Serializable pkVal() { + return this.id; + } +} diff --git a/src/main/java/cn/soul2/jyjc/admin/interceptor/TokenInterceptor.java b/src/main/java/cn/soul2/jyjc/admin/interceptor/TokenInterceptor.java new file mode 100644 index 0000000..69d7d60 --- /dev/null +++ b/src/main/java/cn/soul2/jyjc/admin/interceptor/TokenInterceptor.java @@ -0,0 +1,63 @@ +package cn.soul2.jyjc.admin.interceptor; + +import cn.soul2.jyjc.admin.annotation.SkinLogin; +import cn.soul2.jyjc.admin.config.UserLoginStatusBean; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.method.HandlerMethod; +import org.springframework.web.servlet.HandlerInterceptor; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * @author Soul2 + * @date 2024-04-02 15:31 + */ + +public class TokenInterceptor implements HandlerInterceptor { + + @Autowired + private UserLoginStatusBean userLoginStatusBean; + + @Override + public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { + // 允许OPTIONS请求通过 + if (isCorsRequest(request)) { + return true; + } + + // 跳过登录 + // 如果处理器是一个方法处理器 + if (handler instanceof HandlerMethod) { + HandlerMethod handlerMethod = (HandlerMethod) handler; + // 检查方法上是否存在SkinLogin注解 + if (handlerMethod.getMethod().isAnnotationPresent(SkinLogin.class)) { + // 如果存在,绕过拦截器 + return true; + } + } + // 验证token + // 从请求头中获取 token + String token = request.getHeader("jyjc-Token"); + // 检查 token 是否存在并且有效,这里可以根据实际情况自行实现验证逻辑 + if (token != null && isValidToken(token)) { + // Token 有效,允许请求通过 + return true; + } else { + // Token 无效,拒绝请求,可以返回特定的响应状态码,例如 401 Unauthorized + response.setStatus(40401); + return false; + } + } + + private boolean isValidToken(String token) { + // 实现 token 验证逻辑,例如验证 token 的签名或者在数据库中验证 token 的有效性 + return userLoginStatusBean.containsToken(token); + // 返回 true 表示 token 有效,返回 false 表示 token 无效 + } + + private boolean isCorsRequest(HttpServletRequest request) { + // 检查请求头中是否包含 Origin 字段,如果存在,则认为是跨域请求 + return request.getHeader("Origin") != null; + } +} diff --git a/src/main/java/cn/soul2/jyjc/admin/mapper/UserLoginOutMapper.java b/src/main/java/cn/soul2/jyjc/admin/mapper/UserLoginOutMapper.java new file mode 100644 index 0000000..585bbcd --- /dev/null +++ b/src/main/java/cn/soul2/jyjc/admin/mapper/UserLoginOutMapper.java @@ -0,0 +1,16 @@ +package cn.soul2.jyjc.admin.mapper; + +import cn.soul2.jyjc.admin.entity.UserLoginOutDO; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** + *

+ * 用户登入登出表 Mapper 接口 + *

+ * + * @author Soul2 + * @since 2024-03-29 20:46:42 + */ +public interface UserLoginOutMapper extends BaseMapper { + +} diff --git a/src/main/java/cn/soul2/jyjc/admin/mapper/UserMapper.java b/src/main/java/cn/soul2/jyjc/admin/mapper/UserMapper.java new file mode 100644 index 0000000..65a4563 --- /dev/null +++ b/src/main/java/cn/soul2/jyjc/admin/mapper/UserMapper.java @@ -0,0 +1,16 @@ +package cn.soul2.jyjc.admin.mapper; + +import cn.soul2.jyjc.admin.entity.UserDO; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** + *

+ * 用户表 Mapper 接口 + *

+ * + * @author Soul2 + * @since 2024-03-29 20:46:42 + */ +public interface UserMapper extends BaseMapper { + +} diff --git a/src/main/java/cn/soul2/jyjc/admin/repository/IUserLoginOutRepository.java b/src/main/java/cn/soul2/jyjc/admin/repository/IUserLoginOutRepository.java new file mode 100644 index 0000000..b2a9bf0 --- /dev/null +++ b/src/main/java/cn/soul2/jyjc/admin/repository/IUserLoginOutRepository.java @@ -0,0 +1,62 @@ +package cn.soul2.jyjc.admin.repository; + +import cn.soul2.jyjc.admin.dto.UserLoginDTO; +import cn.soul2.jyjc.admin.dto.UserLoginOutPageDTO; +import cn.soul2.jyjc.admin.dto.UserLogoutDTO; +import cn.soul2.jyjc.admin.entity.UserDO; +import cn.soul2.jyjc.admin.entity.UserLoginOutDO; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.service.IService; + +/** + *

+ * 用户登入登出表 服务类 + *

+ * + * @author Soul2 + * @since 2024-03-29 20:46:42 + */ +public interface IUserLoginOutRepository extends IService { + + /** + * 分页查询 + * + * @param dto 查询条件 + * @return {@link IPage}<{@link UserLoginOutDO}> + */ + IPage page(UserLoginOutPageDTO dto); + + /** + * 用户登录 + * + * @param dto 用户信息 + * @param user 用户 + * @return {@link String} + */ + String login(UserLoginDTO dto, UserDO user); + + /** + * 用户登出 + * + * @param dto 用户信息 + * @return {@link String} + */ + String logout(UserLogoutDTO dto); + + /** + * 用户登出 + * + * @param userId 用户id + * @return {@link String} + */ + Boolean logoutByUserId(String userId); + + /** + * 删除目标用户的所有登录记录 + * + * @param userId 用户id + * @return {@link Boolean} + */ + Boolean removeByUserId(String userId); + +} diff --git a/src/main/java/cn/soul2/jyjc/admin/repository/IUserRepository.java b/src/main/java/cn/soul2/jyjc/admin/repository/IUserRepository.java new file mode 100644 index 0000000..4d541b0 --- /dev/null +++ b/src/main/java/cn/soul2/jyjc/admin/repository/IUserRepository.java @@ -0,0 +1,54 @@ +package cn.soul2.jyjc.admin.repository; + +import cn.soul2.jyjc.admin.dto.UserPageDTO; +import cn.soul2.jyjc.admin.dto.UserSaveDTO; +import cn.soul2.jyjc.admin.dto.base.UpdateStatusDTO; +import cn.soul2.jyjc.admin.entity.UserDO; +import cn.soul2.jyjc.admin.vo.base.VPage; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.service.IService; + +/** + *

+ * 用户表 服务类 + *

+ * + * @author Soul2 + * @since 2024-03-29 20:46:42 + */ +public interface IUserRepository extends IService { + + /** + * 分页查询 + * + * @param dto 查询条件 + * @return {@link VPage}<{@link UserDO}> + */ + IPage page(UserPageDTO dto); + + /** + * 保存或更新 + * + * @param dto 有/无id区分更新/新增 + * @return {@link Boolean} + */ + Boolean saveOrUpdate(UserSaveDTO dto); + + /** + * 更新状态 + * + * @param dto 新状态 + * @return {@link Boolean} + */ + Boolean updateStatus(UpdateStatusDTO dto); + + /** + * 读取指定名字的用户 + * + * @param username 用户名 + * @return {@link UserDO} + */ + UserDO getOneByUsername(String username); + + +} diff --git a/src/main/java/cn/soul2/jyjc/admin/repository/impl/UserLoginOutRepositoryImpl.java b/src/main/java/cn/soul2/jyjc/admin/repository/impl/UserLoginOutRepositoryImpl.java new file mode 100644 index 0000000..356e10a --- /dev/null +++ b/src/main/java/cn/soul2/jyjc/admin/repository/impl/UserLoginOutRepositoryImpl.java @@ -0,0 +1,99 @@ +package cn.soul2.jyjc.admin.repository.impl; + +import cn.soul2.jyjc.admin.config.UserLoginStatusBean; +import cn.soul2.jyjc.admin.dto.UserLoginDTO; +import cn.soul2.jyjc.admin.dto.UserLoginOutPageDTO; +import cn.soul2.jyjc.admin.dto.UserLogoutDTO; +import cn.soul2.jyjc.admin.entity.UserDO; +import cn.soul2.jyjc.admin.entity.UserLoginOutDO; +import cn.soul2.jyjc.admin.mapper.UserLoginOutMapper; +import cn.soul2.jyjc.admin.repository.IUserLoginOutRepository; +import cn.soul2.jyjc.admin.utils.base.PageUtils; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.core.toolkit.StringUtils; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.time.LocalDateTime; + +/** + *

+ * 用户登入登出表 服务实现类 + *

+ * + * @author Soul2 + * @since 2024-03-29 20:46:42 + */ +@Service +public class UserLoginOutRepositoryImpl extends ServiceImpl implements IUserLoginOutRepository { + + @Autowired + private UserLoginStatusBean userLoginStatusBean; + + @Override + public IPage page(UserLoginOutPageDTO dto) { + LambdaQueryWrapper query = Wrappers.lambdaQuery(); + query.eq(StringUtils.isNotBlank(dto.getUserId()), UserLoginOutDO::getUserId, dto.getUserId()) + .orderByDesc(UserLoginOutDO::getCreatedTime); + return super.page(PageUtils.build(dto), query); + } + + @Override + public String login(UserLoginDTO dto, UserDO user) { + UserLoginOutDO loginOutDO; + boolean saved; + LocalDateTime now = LocalDateTime.now(); + // 判断是否登陆过,在缓存无法读取到目标用户名时即未登录,若登录过则令之前的登录记录失效 + String token = userLoginStatusBean.getTokenByUsername(dto.getUsername()); + if (token != null) { + userLoginStatusBean.logout(token); + UserLoginOutDO oldLoginOut = super.getById(token); + oldLoginOut.setLapseTime(now).setLogoutTime(now); + super.updateById(oldLoginOut); + } + loginOutDO = new UserLoginOutDO(); + loginOutDO.setUserId(user.getId()) + .setUserName(user.getUsername()) + .setLoginTime(now) + .setLapseTime(now.plusHours(2)) + ; + saved = super.save(loginOutDO); + if (saved) { + userLoginStatusBean.login(loginOutDO.getId(), loginOutDO); + return loginOutDO.getId(); + } + return null; + } + + @Override + public String logout(UserLogoutDTO dto) { + // 清除缓存内的登录信息 + Boolean logout = userLoginStatusBean.logout(dto.getToken()); + // 保存退出登录的时间 + LocalDateTime now = LocalDateTime.now(); + UserLoginOutDO oldLoginOut = super.getById(dto.getToken()); + oldLoginOut.setLogoutTime(now); + super.updateById(oldLoginOut); + + return logout ? dto.getUsername() : null; + } + + @Override + public Boolean logoutByUserId(String userId) { + return userLoginStatusBean.logoutByUserId(userId); + } + + @Override + public Boolean removeByUserId(String userId) { + if (org.apache.commons.lang3.StringUtils.isBlank(userId)) { + return Boolean.TRUE; + } + LambdaUpdateWrapper update = Wrappers.lambdaUpdate(); + update.eq(UserLoginOutDO::getUserId, userId); + return super.remove(update); + } +} diff --git a/src/main/java/cn/soul2/jyjc/admin/repository/impl/UserRepositoryImpl.java b/src/main/java/cn/soul2/jyjc/admin/repository/impl/UserRepositoryImpl.java new file mode 100644 index 0000000..f2c86dd --- /dev/null +++ b/src/main/java/cn/soul2/jyjc/admin/repository/impl/UserRepositoryImpl.java @@ -0,0 +1,60 @@ +package cn.soul2.jyjc.admin.repository.impl; + +import cn.soul2.jyjc.admin.dto.UserPageDTO; +import cn.soul2.jyjc.admin.dto.UserSaveDTO; +import cn.soul2.jyjc.admin.dto.base.UpdateStatusDTO; +import cn.soul2.jyjc.admin.entity.UserDO; +import cn.soul2.jyjc.admin.mapper.UserMapper; +import cn.soul2.jyjc.admin.repository.IUserRepository; +import cn.soul2.jyjc.admin.utils.base.PageUtils; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.core.toolkit.StringUtils; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.beans.BeanUtils; +import org.springframework.stereotype.Service; + +/** + *

+ * 用户表 服务实现类 + *

+ * + * @author Soul2 + * @since 2024-03-29 20:46:42 + */ +@Service +public class UserRepositoryImpl extends ServiceImpl implements IUserRepository { + + @Override + public IPage page(UserPageDTO dto) { + LambdaQueryWrapper query = Wrappers.lambdaQuery(); + query.eq(dto.getStatus() != null, UserDO::getStatus, dto.getStatus()) + .like(StringUtils.isNotBlank(dto.getUsername()), UserDO::getUsername, dto.getUsername()) + .orderByDesc(UserDO::getUpdatedTime); + return super.page(PageUtils.build(dto), query); + } + + @Override + public Boolean saveOrUpdate(UserSaveDTO dto) { + UserDO user = new UserDO(); + BeanUtils.copyProperties(dto, user); + return super.saveOrUpdate(user); + } + + @Override + public Boolean updateStatus(UpdateStatusDTO dto) { + LambdaUpdateWrapper update = Wrappers.lambdaUpdate(); + update.set(UserDO::getStatus, dto.getStatus()) + .eq(UserDO::getId, dto.getId()); + return super.update(update); + } + + @Override + public UserDO getOneByUsername(String username) { + LambdaQueryWrapper query = Wrappers.lambdaQuery(); + query.eq(UserDO::getUsername, username); + return super.getOne(query, false); + } +} diff --git a/src/main/java/cn/soul2/jyjc/admin/service/IAnswerService.java b/src/main/java/cn/soul2/jyjc/admin/service/IAnswerService.java new file mode 100644 index 0000000..7dbe407 --- /dev/null +++ b/src/main/java/cn/soul2/jyjc/admin/service/IAnswerService.java @@ -0,0 +1,20 @@ +package cn.soul2.jyjc.admin.service; + +import cn.soul2.jyjc.admin.dto.AnswerSubmitDTO; + +/** + * @author Soul2 + * @date 2024-03-27 14:43 + */ + +public interface IAnswerService { + + /** + * 提交答卷 + * + * @param dto 答卷内容 + * @return {@link Boolean} + */ + Boolean handleSubmit(AnswerSubmitDTO dto); + +} diff --git a/src/main/java/cn/soul2/jyjc/admin/service/IUserService.java b/src/main/java/cn/soul2/jyjc/admin/service/IUserService.java new file mode 100644 index 0000000..53a3392 --- /dev/null +++ b/src/main/java/cn/soul2/jyjc/admin/service/IUserService.java @@ -0,0 +1,46 @@ +package cn.soul2.jyjc.admin.service; + +import cn.soul2.jyjc.admin.dto.UserLoginDTO; +import cn.soul2.jyjc.admin.dto.UserLogoutDTO; +import cn.soul2.jyjc.admin.vo.UserVO; + +/** + * @author Soul2 + * @date 2024-03-29 20:47 + */ + +public interface IUserService { + + /** + * 注册一个用户 + * + * @param dto 用户名和密码 + * @return {@link UserVO} + */ + UserVO register(UserLoginDTO dto); + + /** + * 用户登录 + * + * @param dto 用户名和密码 + * @return {@link UserVO} + */ + UserVO login(UserLoginDTO dto); + + /** + * 用户退出登录 + * + * @param dto 登录key + * @return {@link Boolean} + */ + Boolean logout(UserLogoutDTO dto); + + /** + * 删除用户并退出登录,同时将登录记录一并删除 + * + * @param userId 用户id + * @return {@link Boolean} + */ + Boolean remove(String userId); + +} diff --git a/src/main/java/cn/soul2/jyjc/admin/service/impl/AnswerServiceImpl.java b/src/main/java/cn/soul2/jyjc/admin/service/impl/AnswerServiceImpl.java new file mode 100644 index 0000000..39bb0dd --- /dev/null +++ b/src/main/java/cn/soul2/jyjc/admin/service/impl/AnswerServiceImpl.java @@ -0,0 +1,58 @@ +package cn.soul2.jyjc.admin.service.impl; + +import cn.soul2.jyjc.admin.dto.AnswerSubmitDTO; +import cn.soul2.jyjc.admin.entity.AnswerDetailsDO; +import cn.soul2.jyjc.admin.entity.AnswerSheetDO; +import cn.soul2.jyjc.admin.repository.IAnswerDetailsRepository; +import cn.soul2.jyjc.admin.repository.IAnswerSheetRepository; +import cn.soul2.jyjc.admin.service.IAnswerService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.transaction.interceptor.TransactionAspectSupport; + +import java.util.List; +import java.util.stream.Collectors; + +/** + * @author Soul2 + * @date 2024-03-27 14:43 + */ + +@Service +public class AnswerServiceImpl implements IAnswerService { + + @Autowired + private IAnswerSheetRepository sheetRepository; + + @Autowired + private IAnswerDetailsRepository detailsRepository; + + @Override + @Transactional + public Boolean handleSubmit(AnswerSubmitDTO dto) { + AnswerSheetDO sheet = new AnswerSheetDO(); + sheet.setRespondent(dto.getOpenid()) + .setQnId(dto.getQnId()) + .setQrId(dto.getQrId()); + boolean sheetSaved = sheetRepository.save(sheet); + if (sheetSaved) { + List details = dto.getDetails().stream().map(d -> { + AnswerDetailsDO detail = new AnswerDetailsDO(); + detail.setAnswerContent(d.getContent()) + .setAnswerSheetId(sheet.getId()) + .setSubjectType(d.getSubjectType()) + .setSubjectId(d.getSubjectId()); + return detail; + }).collect(Collectors.toList()); + boolean detailsSaved = detailsRepository.saveBatch(details); + if (!detailsSaved) { + TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); + return Boolean.FALSE; + } + } else { + return Boolean.FALSE; + } + return Boolean.TRUE; + } +} diff --git a/src/main/java/cn/soul2/jyjc/admin/service/impl/UserServiceImpl.java b/src/main/java/cn/soul2/jyjc/admin/service/impl/UserServiceImpl.java new file mode 100644 index 0000000..f44fd05 --- /dev/null +++ b/src/main/java/cn/soul2/jyjc/admin/service/impl/UserServiceImpl.java @@ -0,0 +1,87 @@ +package cn.soul2.jyjc.admin.service.impl; + +import cn.soul2.jyjc.admin.dto.UserLoginDTO; +import cn.soul2.jyjc.admin.dto.UserLogoutDTO; +import cn.soul2.jyjc.admin.entity.UserDO; +import cn.soul2.jyjc.admin.repository.IUserLoginOutRepository; +import cn.soul2.jyjc.admin.repository.IUserRepository; +import cn.soul2.jyjc.admin.service.IUserService; +import cn.soul2.jyjc.admin.utils.Md5Utils; +import cn.soul2.jyjc.admin.vo.UserVO; +import org.springframework.beans.BeanUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +/** + * @author Soul2 + * @date 2024-03-29 20:47 + */ + +@Service +public class UserServiceImpl implements IUserService { + + @Autowired + private IUserRepository userRepository; + + @Autowired + private IUserLoginOutRepository loginOutRepository; + + @Override + public UserVO register(UserLoginDTO dto) { + UserVO vo = new UserVO(); + if (userRepository.getOneByUsername(dto.getUsername()) == null) { + UserDO user = new UserDO(); + user.setUsername(dto.getUsername()) + .setPassword(Md5Utils.md5(dto.getPassword())); + boolean saved = userRepository.save(user); + if (!saved) { + vo.setLoginFail("注册失败!"); + } else { + String loginKey = loginOutRepository.login(dto, user); + if (loginKey != null) { + BeanUtils.copyProperties(user, vo); + vo.setToken(loginKey); + } else { + vo.setLoginFail("注册成功但登录失败!"); + } + } + } else { + vo.setLoginFail("用户名已存在!"); + } + return vo; + } + + @Override + public UserVO login(UserLoginDTO dto) { + UserVO vo = new UserVO(); + UserDO user = userRepository.getOneByUsername(dto.getUsername()); + if (user != null) { + if (Md5Utils.verify(user.getPassword(), dto.getPassword())) { + String loginKey = loginOutRepository.login(dto, user); + if (loginKey != null) { + BeanUtils.copyProperties(user, vo); + vo.setToken(loginKey); + } else { + vo.setLoginFail("登录失败!"); + } + } else { + vo.setLoginFail("密码错误!"); + } + } else { + vo.setLoginFail("该用户尚未注册!"); + } + return vo; + } + + @Override + public Boolean logout(UserLogoutDTO dto) { + return loginOutRepository.logout(dto) != null; + } + + @Override + public Boolean remove(String userId) { + loginOutRepository.logoutByUserId(userId); + loginOutRepository.removeByUserId(userId); + return userRepository.removeById(userId); + } +} diff --git a/src/main/java/cn/soul2/jyjc/admin/utils/AesUtils.java b/src/main/java/cn/soul2/jyjc/admin/utils/AesUtils.java new file mode 100644 index 0000000..a4dcf04 --- /dev/null +++ b/src/main/java/cn/soul2/jyjc/admin/utils/AesUtils.java @@ -0,0 +1,52 @@ +package cn.soul2.jyjc.admin.utils; + +import org.springframework.beans.factory.annotation.Value; + +import javax.crypto.Cipher; +import javax.crypto.spec.SecretKeySpec; +import java.util.Base64; + +/** + * @author Soul2 + * @date 2024-03-30 14:02 + */ + +public class AesUtils { + + @Value("${encrypt.keys.aes}") + private String aesKey; + + private static final String AES_ALGORITHM = "AES"; + + private SecretKeySpec generateKey(String key) { + return new SecretKeySpec(key.getBytes(), AES_ALGORITHM); + } + + public String encrypt(String source) throws Exception { + return encrypt(source, aesKey); + } + + public String decrypt(String encrypted) throws Exception { + return decrypt(encrypted, aesKey); + } + + private String encrypt(String source, String key) throws Exception { + Cipher cipher = Cipher.getInstance(AES_ALGORITHM); + cipher.init(Cipher.ENCRYPT_MODE, generateKey(key)); + byte[] encryptedBytes = cipher.doFinal(source.getBytes()); + return Base64.getEncoder().encodeToString(encryptedBytes); + } + + private String decrypt(String encrypted, String key) throws Exception { + Cipher cipher = Cipher.getInstance(AES_ALGORITHM); + cipher.init(Cipher.DECRYPT_MODE, generateKey(key)); + byte[] decryptedBytes = cipher.doFinal(Base64.getDecoder().decode(encrypted)); + return new String(decryptedBytes); + } + + public static void main(String[] args) { + + } + + +} diff --git a/src/main/java/cn/soul2/jyjc/admin/utils/Md5Utils.java b/src/main/java/cn/soul2/jyjc/admin/utils/Md5Utils.java new file mode 100644 index 0000000..16ea763 --- /dev/null +++ b/src/main/java/cn/soul2/jyjc/admin/utils/Md5Utils.java @@ -0,0 +1,33 @@ +package cn.soul2.jyjc.admin.utils; + +import org.springframework.util.DigestUtils; + +import java.nio.charset.StandardCharsets; +import java.util.Objects; + +/** + * @author fuzongyao + * @date 2021/10/14 11:19 + * @since 1.0 + */ +public class Md5Utils { + + /** + * 加盐 + */ + private static final String SALT = "4v6dKAOn+tEiVH58/XKeUw=="; + + public static String md5(String body) { + body += SALT; + return DigestUtils.md5DigestAsHex(body.getBytes(StandardCharsets.UTF_8)).toUpperCase(); + } + + public static boolean verify(String md5, String body) { + return Objects.equals(md5, md5(body)); + } + + public static void main(String[] args) { + System.out.println(md5("123456")); + } + +} diff --git a/src/main/java/cn/soul2/jyjc/admin/utils/MybatisFastGenerator.java b/src/main/java/cn/soul2/jyjc/admin/utils/MybatisFastGenerator.java index 89d136f..da067e5 100644 --- a/src/main/java/cn/soul2/jyjc/admin/utils/MybatisFastGenerator.java +++ b/src/main/java/cn/soul2/jyjc/admin/utils/MybatisFastGenerator.java @@ -19,16 +19,16 @@ public class MybatisFastGenerator { private static final DatasourceConfig DATASOURCE_CONFIG = new DatasourceConfig( "Soul2", - "jdbc:mysql://localhost:3306/pioneer?characterEncoding=utf8&serverTimezone=GMT%2B8", - "root", - "123456" + "jdbc:mysql://soul2.cn:3306/thli_upline?characterEncoding=utf8&serverTimezone=GMT%2B8", + "thli", + "thli@20180913" ); /** * 设置需要生成的表名 */ private static final String[] TABLE_NAMES = { "tb_user", - "tb_user_login_out", +// "tb_user_login_out", }; /** * 是否为表更新 @@ -37,7 +37,7 @@ public class MybatisFastGenerator { /** * 模块名称 */ - private static final String MODULE_NAME = "demo"; + private static final String MODULE_NAME = "jyjc.admin"; /** * 设置过滤表前缀 diff --git a/src/main/java/cn/soul2/jyjc/admin/utils/SaltUtils.java b/src/main/java/cn/soul2/jyjc/admin/utils/SaltUtils.java new file mode 100644 index 0000000..58cefd7 --- /dev/null +++ b/src/main/java/cn/soul2/jyjc/admin/utils/SaltUtils.java @@ -0,0 +1,35 @@ +package cn.soul2.jyjc.admin.utils; + +import java.security.SecureRandom; +import java.util.Base64; + +/** + * 盐值生成 + * + * @author Soul2 + * @date 2024-03-30 14:30 + */ + +public class SaltUtils { + + /** + * 生成指定长度的盐值 + * + * @param length 盐值长度 + * @return {@link String} + */ + public static String generateSalt(int length) { + SecureRandom random = new SecureRandom(); + byte[] salt = new byte[length]; + random.nextBytes(salt); + return Base64.getEncoder().encodeToString(salt); + } + + public static void main(String[] args) { + // 设置盐值长度 + int saltLength = 16; + String salt = generateSalt(saltLength); + System.out.println("Generated Salt: " + salt); + } + +} diff --git a/src/main/java/cn/soul2/jyjc/admin/vo/UserVO.java b/src/main/java/cn/soul2/jyjc/admin/vo/UserVO.java new file mode 100644 index 0000000..e1874d0 --- /dev/null +++ b/src/main/java/cn/soul2/jyjc/admin/vo/UserVO.java @@ -0,0 +1,38 @@ +package cn.soul2.jyjc.admin.vo; + +import lombok.Data; +import lombok.experimental.Accessors; + +/** + * @author Soul2 + * @date 2024-03-30 14:40 + */ + +@Data +@Accessors(chain = true) +public class UserVO { + + /** + * username + */ + private String username; + + /** + * token + * 其实就是'UserLoginOut'表的id + */ + private String token; + + /** + * 权限等级 + */ + private String authorityLevel; + + /** + * 状态;0(默认):正常;4:封号;9:异常; + */ + private Integer status; + + private String loginFail; + +} diff --git a/src/main/resources/application-cors.yml b/src/main/resources/application-cors.yml index df0211a..4db7a92 100644 --- a/src/main/resources/application-cors.yml +++ b/src/main/resources/application-cors.yml @@ -1,7 +1,7 @@ # 允许跨域的地址 cors: - allow-origins: http://localhost + allow-origin: http://localhost --- spring: @@ -9,13 +9,12 @@ spring: activate: on-profile: dev cors: - allow-origins: http://localhost:6100, http://localhost:7620, http://192.168.10.104:7620 + allow-origin: http://localhost:6100, http://localhost:7620, http://192.168.10.104:7620 --- spring: config: activate: on-profile: prod - cors: - allow-origins: http://test.soul2.cn + allow-origin: http://test.soul2.cn diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index a67f663..396d044 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -4,6 +4,7 @@ server: #上下文 servlet.context-path: /thli/jyjc/api +encrypt.keys.aes: 98478f8a45887eda446501bcb44010520c3f53c7b45ff36215e86ce4f049b0f2 spring: application.name: jyjc-admin