diff --git a/pom.xml b/pom.xml
index ac0ca32..6ec9144 100644
--- a/pom.xml
+++ b/pom.xml
@@ -41,18 +41,19 @@
com.baomidou
mybatis-plus-boot-starter
3.5.2
-
-
- org.slf4j
- *
-
-
org.springframework.boot
spring-boot-starter-data-redis
+
+
+
+ cn.dev33
+ sa-token-spring-boot-starter
+ 1.44.0
+
org.springframework.session
spring-session-data-redis
diff --git a/src/main/java/com/yupi/springbootinit/common/ErrorCode.java b/src/main/java/com/yupi/springbootinit/common/ErrorCode.java
index c60faad..e6e00d8 100644
--- a/src/main/java/com/yupi/springbootinit/common/ErrorCode.java
+++ b/src/main/java/com/yupi/springbootinit/common/ErrorCode.java
@@ -11,6 +11,8 @@ public enum ErrorCode {
SUCCESS(0, "ok"),
PARAMS_ERROR(40000, "请求参数错误"),
NOT_LOGIN_ERROR(40100, "未登录"),
+ USERNAME_OR_PASSWORD_ERROR(40200, "账号或密码错误"),
+ USER_DISABLE(40300, "用户被禁用"),
NO_AUTH_ERROR(40101, "无权限"),
NOT_FOUND_ERROR(40400, "请求数据不存在"),
FORBIDDEN_ERROR(40300, "禁止访问"),
diff --git a/src/main/java/com/yupi/springbootinit/config/MyBatisPlusConfig.java b/src/main/java/com/yupi/springbootinit/config/MyBatisPlusConfig.java
index 9c46153..d51bc49 100644
--- a/src/main/java/com/yupi/springbootinit/config/MyBatisPlusConfig.java
+++ b/src/main/java/com/yupi/springbootinit/config/MyBatisPlusConfig.java
@@ -21,11 +21,12 @@ public class MyBatisPlusConfig {
*
* @return
*/
-// @Bean
-// public MybatisPlusInterceptor mybatisPlusInterceptor() {
-// MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
-// // 分页插件
-// interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
-// return interceptor;
-// }
+ @Bean
+ public MybatisPlusInterceptor mybatisPlusInterceptor() {
+ MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
+ // 分页插件
+ interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
+ return interceptor;
+ }
+
}
\ No newline at end of file
diff --git a/src/main/java/com/yupi/springbootinit/config/SaTokenConfigure.java b/src/main/java/com/yupi/springbootinit/config/SaTokenConfigure.java
new file mode 100644
index 0000000..7f792b9
--- /dev/null
+++ b/src/main/java/com/yupi/springbootinit/config/SaTokenConfigure.java
@@ -0,0 +1,39 @@
+package com.yupi.springbootinit.config;
+
+import cn.dev33.satoken.interceptor.SaInterceptor;
+import cn.dev33.satoken.stp.StpUtil;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+
+@Configuration
+public class SaTokenConfigure implements WebMvcConfigurer {
+ @Override
+ public void addInterceptors(InterceptorRegistry registry) {
+ // 注册Sa-Token的拦截器
+ registry.addInterceptor(new SaInterceptor(handle -> StpUtil.checkLogin()))
+ .addPathPatterns("/**")
+ .excludePathPatterns(getExcludePaths());
+ }
+
+ /**
+ * 获取需要放行的路径
+ */
+ private String[] getExcludePaths() {
+ return new String[]{
+ // Swagger & Knife4j 相关
+ "/doc.html",
+ "/webjars/**",
+ "/swagger-resources/**",
+ "/v2/api-docs",
+ "/v3/api-docs",
+ "/v3/api-docs/**",
+ "/swagger-ui.html",
+ "/swagger-ui/**",
+ "/favicon.ico",
+ // 你的其他放行路径,例如登录接口
+ "/user/doLogin",
+ "/save_data/add_host"
+ };
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/yupi/springbootinit/controller/UserController.java b/src/main/java/com/yupi/springbootinit/controller/UserController.java
new file mode 100644
index 0000000..8ec0965
--- /dev/null
+++ b/src/main/java/com/yupi/springbootinit/controller/UserController.java
@@ -0,0 +1,59 @@
+package com.yupi.springbootinit.controller;
+
+import cn.dev33.satoken.stp.StpUtil;
+import cn.hutool.core.bean.BeanUtil;
+import com.yupi.springbootinit.common.BaseResponse;
+import com.yupi.springbootinit.common.ErrorCode;
+import com.yupi.springbootinit.common.ResultUtils;
+import com.yupi.springbootinit.exception.BusinessException;
+import com.yupi.springbootinit.model.dto.user.SystemUsersDTO;
+import com.yupi.springbootinit.model.entity.SystemUsers;
+import com.yupi.springbootinit.model.enums.CommonStatusEnum;
+import com.yupi.springbootinit.model.vo.user.SystemUsersVO;
+import com.yupi.springbootinit.service.SystemUsersService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.web.bind.annotation.*;
+
+import javax.annotation.Resource;
+
+/*
+ * @author: ziin
+ * @date: 2025/6/11 19:50
+ */
+@RestController
+@RequestMapping("/user")
+@Slf4j
+@CrossOrigin
+public class UserController {
+
+
+ @Resource
+ private SystemUsersService usersService;
+
+ // 测试登录,浏览器访问: http://localhost:8081/user/doLogin?username=zhang&password=123456
+ @PostMapping("doLogin")
+ public BaseResponse doLogin(@RequestBody SystemUsersDTO usersDTO) {
+ SystemUsers user = usersService.getUserByUserName(usersDTO.getUsername());
+ if (user == null) {
+ throw new BusinessException(ErrorCode.USERNAME_OR_PASSWORD_ERROR);
+ }
+
+ if (!usersService.isPasswordMatch(usersDTO.getPassword(), user.getPassword())) {
+ throw new BusinessException(ErrorCode.USERNAME_OR_PASSWORD_ERROR);
+ }
+
+ if (CommonStatusEnum.isDisable(user.getStatus())) {
+ throw new BusinessException(ErrorCode.USER_DISABLE);
+ }
+ SystemUsersVO systemUsersVO = new SystemUsersVO();
+ BeanUtil.copyProperties(user, systemUsersVO);
+ StpUtil.login(user.getId());
+ return ResultUtils.success(systemUsersVO);
+ }
+
+// // 查询登录状态,浏览器访问: http://localhost:8081/user/isLogin
+// @RequestMapping("isLogin")
+// public String isLogin() {
+// return "当前会话是否登录:" + StpUtil.isLogin();
+// }
+}
diff --git a/src/main/java/com/yupi/springbootinit/mapper/SystemUsersMapper.java b/src/main/java/com/yupi/springbootinit/mapper/SystemUsersMapper.java
new file mode 100644
index 0000000..ec20205
--- /dev/null
+++ b/src/main/java/com/yupi/springbootinit/mapper/SystemUsersMapper.java
@@ -0,0 +1,20 @@
+package com.yupi.springbootinit.mapper;
+
+/*
+* @author: ziin
+* @date: 2025/6/11 20:13
+*/
+
+import com.baomidou.mybatisplus.core.conditions.Wrapper;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.yupi.springbootinit.model.entity.SystemUsers;
+
+import java.io.Serializable;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+public interface SystemUsersMapper extends BaseMapper {
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/yupi/springbootinit/model/dto/user/SystemUsersDTO.java b/src/main/java/com/yupi/springbootinit/model/dto/user/SystemUsersDTO.java
new file mode 100644
index 0000000..7948950
--- /dev/null
+++ b/src/main/java/com/yupi/springbootinit/model/dto/user/SystemUsersDTO.java
@@ -0,0 +1,32 @@
+package com.yupi.springbootinit.model.dto.user;
+
+import lombok.Data;
+
+import java.util.Date;
+
+/*
+* @author: ziin
+* @date: 2025/6/11 20:13
+*/
+
+/**
+ * 用户信息表
+ */
+@Data
+public class SystemUsersDTO {
+
+ /**
+ * 用户账号
+ */
+ private String username;
+
+ /**
+ * 密码
+ */
+ private String password;
+
+ /**
+ * 租户编号
+ */
+ private Long tenantId;
+}
\ No newline at end of file
diff --git a/src/main/java/com/yupi/springbootinit/model/entity/SystemUsers.java b/src/main/java/com/yupi/springbootinit/model/entity/SystemUsers.java
new file mode 100644
index 0000000..454a856
--- /dev/null
+++ b/src/main/java/com/yupi/springbootinit/model/entity/SystemUsers.java
@@ -0,0 +1,124 @@
+package com.yupi.springbootinit.model.entity;
+
+import java.util.Date;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import lombok.Data;
+
+/*
+* @author: ziin
+* @date: 2025/6/11 20:13
+*/
+
+/**
+ * 用户信息表
+ */
+@Data
+public class SystemUsers {
+ /**
+ * 用户ID
+ */
+ private Long id;
+
+ /**
+ * 用户账号
+ */
+ private String username;
+
+ /**
+ * 密码
+ */
+ private String password;
+
+ /**
+ * 用户昵称
+ */
+ private String nickname;
+
+ /**
+ * 备注
+ */
+ private String remark;
+
+ /**
+ * 部门ID
+ */
+ @TableField("dept_id")
+ private Long deptId;
+
+ /**
+ * 岗位编号数组
+ */
+ @TableField("post_ids")
+ private String postIds;
+
+ /**
+ * 用户邮箱
+ */
+ private String email;
+
+ /**
+ * 手机号码
+ */
+ private String mobile;
+
+ /**
+ * 用户性别
+ */
+ private Byte sex;
+
+ /**
+ * 头像地址
+ */
+ private String avatar;
+
+ /**
+ * 帐号状态(0正常 1停用)
+ */
+ private Byte status;
+
+ /**
+ * 最后登录IP
+ */
+ @TableField("login_ip")
+ private String loginIp;
+
+ /**
+ * 最后登录时间
+ */
+ @TableField("login_date")
+ private Date loginDate;
+
+ /**
+ * 创建者
+ */
+ private String creator;
+
+ /**
+ * 创建时间
+ */
+ @TableField("create_time")
+ private Date createTime;
+
+ /**
+ * 更新者
+ */
+ private String updater;
+
+ /**
+ * 更新时间
+ */
+ @TableField("update_time")
+ private Date updateTime;
+
+ /**
+ * 是否删除
+ */
+ private Boolean deleted;
+
+ /**
+ * 租户编号
+ */
+ @TableField("tenant_id")
+ private Long tenantId;
+}
\ No newline at end of file
diff --git a/src/main/java/com/yupi/springbootinit/model/enums/CommonStatusEnum.java b/src/main/java/com/yupi/springbootinit/model/enums/CommonStatusEnum.java
new file mode 100644
index 0000000..c47028a
--- /dev/null
+++ b/src/main/java/com/yupi/springbootinit/model/enums/CommonStatusEnum.java
@@ -0,0 +1,47 @@
+package com.yupi.springbootinit.model.enums;
+
+import cn.hutool.core.util.ObjUtil;
+
+import com.yupi.springbootinit.utils.ArrayValuable;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.util.Arrays;
+
+/**
+ * 通用状态枚举
+ *
+ * @author 芋道源码
+ */
+@Getter
+@AllArgsConstructor
+public enum CommonStatusEnum implements ArrayValuable {
+
+ ENABLE(0, "开启"),
+ DISABLE(1, "关闭");
+
+ public static final Integer[] ARRAYS = Arrays.stream(values()).map(CommonStatusEnum::getStatus).toArray(Integer[]::new);
+
+ /**
+ * 状态值
+ */
+ private final Integer status;
+ /**
+ * 状态名
+ */
+ private final String name;
+
+ @Override
+ public Integer[] array() {
+ return ARRAYS;
+ }
+
+ public static boolean isEnable(Integer status) {
+ return ObjUtil.equal(ENABLE.status, status);
+ }
+
+ public static boolean isDisable(Byte status) {
+ return ObjUtil.equal(DISABLE.status, status);
+ }
+
+}
diff --git a/src/main/java/com/yupi/springbootinit/model/vo/user/SystemUsersVO.java b/src/main/java/com/yupi/springbootinit/model/vo/user/SystemUsersVO.java
new file mode 100644
index 0000000..3306b0a
--- /dev/null
+++ b/src/main/java/com/yupi/springbootinit/model/vo/user/SystemUsersVO.java
@@ -0,0 +1,26 @@
+package com.yupi.springbootinit.model.vo.user;
+
+import lombok.Data;
+
+import java.util.Date;
+
+/*
+* @author: ziin
+* @date: 2025/6/11 20:13
+*/
+
+/**
+ * 用户信息表
+ */
+@Data
+public class SystemUsersVO {
+ /**
+ * 用户ID
+ */
+ private Long id;
+
+ /**
+ * 租户编号
+ */
+ private Long tenantId;
+}
\ No newline at end of file
diff --git a/src/main/java/com/yupi/springbootinit/service/SystemUsersService.java b/src/main/java/com/yupi/springbootinit/service/SystemUsersService.java
new file mode 100644
index 0000000..b5cef36
--- /dev/null
+++ b/src/main/java/com/yupi/springbootinit/service/SystemUsersService.java
@@ -0,0 +1,16 @@
+package com.yupi.springbootinit.service;
+
+ /*
+* @author: ziin
+* @date: 2025/6/11 20:13
+*/
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.yupi.springbootinit.model.entity.SystemUsers;
+
+public interface SystemUsersService extends IService {
+
+ SystemUsers getUserByUserName(String username);
+
+ boolean isPasswordMatch(String rawPassWord, String encodedPassword);
+}
diff --git a/src/main/java/com/yupi/springbootinit/service/impl/SystemUsersServiceImpl.java b/src/main/java/com/yupi/springbootinit/service/impl/SystemUsersServiceImpl.java
new file mode 100644
index 0000000..37040a3
--- /dev/null
+++ b/src/main/java/com/yupi/springbootinit/service/impl/SystemUsersServiceImpl.java
@@ -0,0 +1,39 @@
+package com.yupi.springbootinit.service.impl;
+
+import cn.hutool.crypto.SecureUtil;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.yupi.springbootinit.model.entity.SystemUsers;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+
+import org.springframework.beans.factory.annotation.Autowired;
+
+import com.yupi.springbootinit.mapper.SystemUsersMapper;
+import com.yupi.springbootinit.service.SystemUsersService;
+
+import javax.annotation.Resource;
+/*
+* @author: ziin
+* @date: 2025/6/11 20:13
+*/
+
+@Service
+public class SystemUsersServiceImpl extends ServiceImpl implements SystemUsersService{
+
+ @Value("${md5.salt}")
+ private String MD5_SALT;
+
+ @Override
+ public SystemUsers getUserByUserName(String username) {
+ QueryWrapper queryWrapper = new QueryWrapper<>();
+ queryWrapper.eq("username",username);
+ return baseMapper.selectOne(queryWrapper);
+ }
+
+ @Override
+ public boolean isPasswordMatch(String rawPassword, String encodedPassword) {
+ String s = SecureUtil.md5(MD5_SALT + rawPassword);
+ return s.equals(encodedPassword);
+ }
+}
diff --git a/src/main/java/com/yupi/springbootinit/utils/ArrayValuable.java b/src/main/java/com/yupi/springbootinit/utils/ArrayValuable.java
new file mode 100644
index 0000000..10efadf
--- /dev/null
+++ b/src/main/java/com/yupi/springbootinit/utils/ArrayValuable.java
@@ -0,0 +1,15 @@
+package com.yupi.springbootinit.utils;
+
+/**
+ * 可生成 T 数组的接口
+ *
+ * @author HUIHUI
+ */
+public interface ArrayValuable {
+
+ /**
+ * @return 数组
+ */
+ T[] array();
+
+}
\ No newline at end of file
diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml
index 1bba187..4d1c97f 100644
--- a/src/main/resources/application.yml
+++ b/src/main/resources/application.yml
@@ -89,4 +89,38 @@ knife4j:
default:
api-rule: package
api-rule-resources:
- - com.yupi.springbootinit.controller
\ No newline at end of file
+ - com.yupi.springbootinit.controller
+
+############## Sa-Token 配置 (文档: https://sa-token.cc) ##############
+sa-token:
+ # token 名称(同时也是 cookie 名称)
+ token-name: vvtoken
+ # token 有效期(单位:秒) 默认30天,-1 代表永久有效
+ timeout: 2592000
+ # token 最低活跃频率(单位:秒),如果 token 超过此时间没有访问系统就会被冻结,默认-1 代表不限制,永不冻结
+ active-timeout: -1
+ # 是否允许同一账号多地同时登录 (为 true 时允许一起登录, 为 false 时新登录挤掉旧登录)
+ is-concurrent: false
+ # 在多人登录同一账号时,是否共用一个 token (为 true 时所有登录共用一个 token, 为 false 时每次登录新建一个 token)
+ is-share: false
+ # token 风格(默认可取值:uuid、simple-uuid、random-32、random-64、random-128、tik)
+ token-style: uuid
+ # 是否输出操作日志
+ is-log: true
+
+
+# security配置,如果使用了Spring security或者satoken需要添加排除路径
+ security:
+ # 排除路径
+ excludes:
+ - /*.html
+ - /**/*.html
+ - /**/*.css
+ - /**/*.js
+ - /favicon.ico
+ - /error/**
+ #swagger文档和knife4j的路径
+ - /v3/api-docs/**
+ - /doc.html/**
+md5:
+ salt: (-FhqvXO,wMz
\ No newline at end of file
diff --git a/src/main/resources/mapper/SystemUsersMapper.xml b/src/main/resources/mapper/SystemUsersMapper.xml
new file mode 100644
index 0000000..b0cb41e
--- /dev/null
+++ b/src/main/resources/mapper/SystemUsersMapper.xml
@@ -0,0 +1,41 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ id, username, `password`, nickname, remark, dept_id, post_ids, email, mobile, sex,
+ avatar, `status`, login_ip, login_date, creator, create_time, updater, update_time,
+ deleted, tenant_id
+
+
+
+
\ No newline at end of file