Browse Source

登录注册功能实现

Linyt 1 year ago
parent
commit
b1f948f2e8
68 changed files with 1125 additions and 27 deletions
  1. 7 0
      .idea/dataSources.xml
  2. 13 0
      .idea/libraries/Maven__eu_bitwalker_UserAgentUtils_1_21.xml
  3. 13 0
      .idea/libraries/Maven__io_swagger_swagger_annotations_1_6_2.xml
  4. 13 0
      .idea/libraries/Maven__jakarta_validation_jakarta_validation_api_2_0_2.xml
  5. 3 0
      java.iml
  6. 15 0
      java/pom.xml
  7. 1 1
      java/src/main/java/boot/BootApplication.java
  8. 61 0
      java/src/main/java/boot/common/bean/LocalUser.java
  9. 24 0
      java/src/main/java/boot/common/bean/OnlineUser.java
  10. 23 0
      java/src/main/java/boot/common/bean/RequestDetail.java
  11. 1 1
      java/src/main/java/boot/common/config/MybatisPlusConfig.java
  12. 19 0
      java/src/main/java/boot/common/config/RedisConfig.java
  13. 7 0
      java/src/main/java/boot/common/constant/SchoolConstant.java
  14. 23 0
      java/src/main/java/boot/common/enums/SchoolEnum.java
  15. 24 0
      java/src/main/java/boot/common/enums/SmsTypeEnum.java
  16. 15 11
      java/src/main/java/boot/common/interceptor/PermissionInterceptor.java
  17. 90 0
      java/src/main/java/boot/common/utils/EncryptUtils.java
  18. 60 0
      java/src/main/java/boot/common/utils/IpUtil.java
  19. 2 2
      java/src/main/java/boot/common/utils/JwtToken.java
  20. 3 3
      java/src/main/java/boot/common/utils/RedisUtils.java
  21. 15 0
      java/src/main/java/boot/common/utils/RequestUtils.java
  22. 147 0
      java/src/main/java/boot/common/utils/StringUtils.java
  23. 179 0
      java/src/main/java/boot/modules/user/controller/UserController.java
  24. 2 0
      java/src/main/java/boot/modules/user/mapper/UserMapper.java
  25. 23 0
      java/src/main/java/boot/modules/user/param/ForgetParam.java
  26. 27 0
      java/src/main/java/boot/modules/user/param/HLoginParam.java
  27. 26 0
      java/src/main/java/boot/modules/user/param/RegParam.java
  28. 17 0
      java/src/main/java/boot/modules/user/param/VerityParam.java
  29. 3 0
      java/src/main/java/boot/modules/user/pojo/User.java
  30. 153 0
      java/src/main/java/boot/modules/user/service/impl/AuthService.java
  31. 5 6
      java/src/main/java/boot/modules/user/service/impl/UserServiceImpl.java
  32. 35 1
      java/src/main/resources/application.yaml
  33. 36 2
      java/target/classes/application.yaml
  34. BIN
      java/target/classes/boot/BootApplication.class
  35. BIN
      java/target/classes/boot/common/bean/LocalUser.class
  36. BIN
      java/target/classes/boot/common/bean/OnlineUser.class
  37. BIN
      java/target/classes/boot/common/bean/RequestDetail.class
  38. BIN
      java/target/classes/boot/common/config/MybatisPlusConfig.class
  39. BIN
      java/target/classes/boot/common/config/RedisConfig.class
  40. BIN
      java/target/classes/boot/common/constant/SchoolConstant.class
  41. BIN
      java/target/classes/boot/common/enums/SchoolEnum.class
  42. BIN
      java/target/classes/boot/common/enums/SmsTypeEnum.class
  43. BIN
      java/target/classes/boot/common/interceptor/AuthCheck.class
  44. BIN
      java/target/classes/boot/common/interceptor/PermissionInterceptor.class
  45. BIN
      java/target/classes/boot/common/respond/ApiCode.class
  46. BIN
      java/target/classes/boot/common/respond/ApiResult$ApiResultBuilder.class
  47. BIN
      java/target/classes/boot/common/respond/ApiResult.class
  48. BIN
      java/target/classes/boot/common/respond/EException.class
  49. BIN
      java/target/classes/boot/common/respond/UnAuthenticatedException.class
  50. BIN
      java/target/classes/boot/common/utils/EncryptUtils.class
  51. BIN
      java/target/classes/boot/common/utils/IpUtil.class
  52. BIN
      java/target/classes/boot/common/utils/JwtToken.class
  53. BIN
      java/target/classes/boot/common/utils/RedisUtils.class
  54. BIN
      java/target/classes/boot/common/utils/RequestUtils.class
  55. BIN
      java/target/classes/boot/common/utils/StringUtils.class
  56. BIN
      java/target/classes/boot/modules/user/controller/UserController$1.class
  57. BIN
      java/target/classes/boot/modules/user/controller/UserController.class
  58. BIN
      java/target/classes/boot/modules/user/mapper/UserMapper.class
  59. BIN
      java/target/classes/boot/modules/user/param/ForgetParam.class
  60. BIN
      java/target/classes/boot/modules/user/param/HLoginParam.class
  61. BIN
      java/target/classes/boot/modules/user/param/RegParam.class
  62. BIN
      java/target/classes/boot/modules/user/param/VerityParam.class
  63. BIN
      java/target/classes/boot/modules/user/pojo/User$UserBuilder.class
  64. BIN
      java/target/classes/boot/modules/user/pojo/User.class
  65. BIN
      java/target/classes/boot/modules/user/service/UserService.class
  66. BIN
      java/target/classes/boot/modules/user/service/impl/AuthService.class
  67. BIN
      java/target/classes/boot/modules/user/service/impl/UserServiceImpl.class
  68. 40 0
      java/target/classes/mapper/UserMapper.xml

+ 7 - 0
.idea/dataSources.xml

@@ -8,5 +8,12 @@
       <jdbc-url>jdbc:mysql://localhost:3306</jdbc-url>
       <working-dir>$ProjectFileDir$</working-dir>
     </data-source>
+    <data-source source="LOCAL" name="1@localhost" uuid="47efc560-c6a6-4849-8ca2-952bf41f70fd">
+      <driver-ref>redis</driver-ref>
+      <synchronize>true</synchronize>
+      <jdbc-driver>jdbc.RedisDriver</jdbc-driver>
+      <jdbc-url>jdbc:redis://localhost:6379/1</jdbc-url>
+      <working-dir>$ProjectFileDir$</working-dir>
+    </data-source>
   </component>
 </project>

+ 13 - 0
.idea/libraries/Maven__eu_bitwalker_UserAgentUtils_1_21.xml

@@ -0,0 +1,13 @@
+<component name="libraryTable">
+  <library name="Maven: eu.bitwalker:UserAgentUtils:1.21">
+    <CLASSES>
+      <root url="jar://$PROJECT_DIR$/../../../../apache-maven-3.8.8/maven/eu/bitwalker/UserAgentUtils/1.21/UserAgentUtils-1.21.jar!/" />
+    </CLASSES>
+    <JAVADOC>
+      <root url="jar://$PROJECT_DIR$/../../../../apache-maven-3.8.8/maven/eu/bitwalker/UserAgentUtils/1.21/UserAgentUtils-1.21-javadoc.jar!/" />
+    </JAVADOC>
+    <SOURCES>
+      <root url="jar://$PROJECT_DIR$/../../../../apache-maven-3.8.8/maven/eu/bitwalker/UserAgentUtils/1.21/UserAgentUtils-1.21-sources.jar!/" />
+    </SOURCES>
+  </library>
+</component>

+ 13 - 0
.idea/libraries/Maven__io_swagger_swagger_annotations_1_6_2.xml

@@ -0,0 +1,13 @@
+<component name="libraryTable">
+  <library name="Maven: io.swagger:swagger-annotations:1.6.2">
+    <CLASSES>
+      <root url="jar://$PROJECT_DIR$/../../../../apache-maven-3.8.8/maven/io/swagger/swagger-annotations/1.6.2/swagger-annotations-1.6.2.jar!/" />
+    </CLASSES>
+    <JAVADOC>
+      <root url="jar://$PROJECT_DIR$/../../../../apache-maven-3.8.8/maven/io/swagger/swagger-annotations/1.6.2/swagger-annotations-1.6.2-javadoc.jar!/" />
+    </JAVADOC>
+    <SOURCES>
+      <root url="jar://$PROJECT_DIR$/../../../../apache-maven-3.8.8/maven/io/swagger/swagger-annotations/1.6.2/swagger-annotations-1.6.2-sources.jar!/" />
+    </SOURCES>
+  </library>
+</component>

+ 13 - 0
.idea/libraries/Maven__jakarta_validation_jakarta_validation_api_2_0_2.xml

@@ -0,0 +1,13 @@
+<component name="libraryTable">
+  <library name="Maven: jakarta.validation:jakarta.validation-api:2.0.2">
+    <CLASSES>
+      <root url="jar://$PROJECT_DIR$/../../../../apache-maven-3.8.8/maven/jakarta/validation/jakarta.validation-api/2.0.2/jakarta.validation-api-2.0.2.jar!/" />
+    </CLASSES>
+    <JAVADOC>
+      <root url="jar://$PROJECT_DIR$/../../../../apache-maven-3.8.8/maven/jakarta/validation/jakarta.validation-api/2.0.2/jakarta.validation-api-2.0.2-javadoc.jar!/" />
+    </JAVADOC>
+    <SOURCES>
+      <root url="jar://$PROJECT_DIR$/../../../../apache-maven-3.8.8/maven/jakarta/validation/jakarta.validation-api/2.0.2/jakarta.validation-api-2.0.2-sources.jar!/" />
+    </SOURCES>
+  </library>
+</component>

+ 3 - 0
java.iml

@@ -61,6 +61,9 @@
     <orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-annotations:2.11.2" level="project" />
     <orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-core:2.11.2" level="project" />
     <orderEntry type="library" scope="RUNTIME" name="Maven: commons-codec:commons-codec:1.14" level="project" />
+    <orderEntry type="library" name="Maven: io.swagger:swagger-annotations:1.6.2" level="project" />
+    <orderEntry type="library" name="Maven: jakarta.validation:jakarta.validation-api:2.0.2" level="project" />
+    <orderEntry type="library" name="Maven: eu.bitwalker:UserAgentUtils:1.21" level="project" />
     <orderEntry type="library" name="Maven: org.mybatis.spring.boot:mybatis-spring-boot-starter:2.3.1" level="project" />
     <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-jdbc:2.3.4.RELEASE" level="project" />
     <orderEntry type="library" name="Maven: com.zaxxer:HikariCP:3.4.5" level="project" />

+ 15 - 0
java/pom.xml

@@ -42,6 +42,21 @@
             <artifactId>java-jwt</artifactId>
             <version>3.8.1</version>
         </dependency>
+        <dependency>
+            <groupId>io.swagger</groupId>
+            <artifactId>swagger-annotations</artifactId>
+            <version>1.6.2</version>
+        </dependency>
+        <dependency>
+            <groupId>jakarta.validation</groupId>
+            <artifactId>jakarta.validation-api</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>eu.bitwalker</groupId>
+            <artifactId>UserAgentUtils</artifactId>
+            <version>1.21</version>
+        </dependency>
 
 
         <dependency>

+ 1 - 1
java/src/main/java/boot/BootApplication.java

@@ -10,7 +10,7 @@ import org.springframework.transaction.annotation.EnableTransactionManagement;
 @EnableAsync
 @EnableTransactionManagement
 @EnableCaching
-@MapperScan(basePackages ={"boot.modules.*.service.mapper", "boot.config"})
+@MapperScan(basePackages ={"boot.modules.*.mapper", "boot.config"})
 @SpringBootApplication()
 public class BootApplication {
     public static void main(String[] args) {

+ 61 - 0
java/src/main/java/boot/common/bean/LocalUser.java

@@ -0,0 +1,61 @@
+package boot.common.bean;
+
+import boot.common.respond.ApiCode;
+import boot.common.respond.UnAuthenticatedException;
+import boot.common.utils.JwtToken;
+import boot.common.utils.RequestUtils;
+import boot.modules.user.pojo.User;
+import com.auth0.jwt.interfaces.Claim;
+import org.springframework.util.StringUtils;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Optional;
+
+public class LocalUser {
+    private static final ThreadLocal<Map<String, Object>> threadLocal = new ThreadLocal<>();
+
+    public static void set(User user, Integer scope) {
+        Map<String, Object> map = new HashMap<>();
+        map.put("user", user);
+        map.put("scope", scope);
+        LocalUser.threadLocal.set(map);
+    }
+
+    public static void clear() {
+        LocalUser.threadLocal.remove();
+    }
+
+    public static User getUser() {
+        Map<String, Object> map = LocalUser.threadLocal.get();
+        return (User)map.get("user");
+    }
+
+    public static Integer getScope() {
+        Map<String, Object> map = LocalUser.threadLocal.get();
+        Integer scope = (Integer)map.get("scope");
+        return scope;
+    }
+
+    public static Long getUidByToken(){
+        String bearerToken =  RequestUtils.getRequest().getHeader("Authorization");
+        if (StringUtils.isEmpty(bearerToken)) {
+            return 0L;
+        }
+
+        if (!bearerToken.startsWith("Bearer")) {
+            return 0L;
+        }
+        String[] tokens = bearerToken.split(" ");
+        if (!(tokens.length == 2)) {
+            return 0L;
+        }
+        String token = tokens[1];
+
+        Optional<Map<String, Claim>> optionalMap = JwtToken.getClaims(token);
+        Map<String, Claim> map = optionalMap
+                .orElseThrow(() -> new UnAuthenticatedException(ApiCode.UNAUTHORIZED));
+
+        return  map.get("uid").asLong();
+    }
+}

+ 24 - 0
java/src/main/java/boot/common/bean/OnlineUser.java

@@ -0,0 +1,24 @@
+package boot.common.bean;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+import java.util.Date;
+
+@Data
+@EqualsAndHashCode
+@NoArgsConstructor
+@AllArgsConstructor
+public class OnlineUser implements Serializable {
+    private String userName;
+    private String nickName;
+    private String job;
+    private String browser;
+    private String ip;
+    private String address;
+    private String key;
+    private Date loginTime;
+}

+ 23 - 0
java/src/main/java/boot/common/bean/RequestDetail.java

@@ -0,0 +1,23 @@
+package boot.common.bean;
+
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+
+@Data
+@Accessors(chain = true)
+public class RequestDetail implements Serializable {
+    private static final long serialVersionUID = 2543641512850125440L;
+
+    /**
+     * 请求ip地址
+     */
+    private String ip;
+
+    /**
+     * 请求路径
+     */
+    private String path;
+
+}

+ 1 - 1
java/src/main/java/boot/common/config/MybatisPlusConfig.java

@@ -19,7 +19,7 @@ import org.springframework.core.io.DefaultResourceLoader;
 
 import javax.sql.DataSource;
 @Configuration
-@MapperScan(basePackages ={"boot.modules.*.service.mapper", "boot.config"})
+@MapperScan(basePackages ={"boot.modules.*.mapper", "boot.config"})
 public class MybatisPlusConfig {
 
     @Autowired

+ 19 - 0
java/src/main/java/boot/common/config/RedisConfig.java

@@ -0,0 +1,19 @@
+package boot.common.config;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.data.redis.serializer.StringRedisSerializer;
+
+@Configuration
+public class RedisConfig {
+    @Bean
+    public RedisTemplate<Object, Object> redisStringTemplate(RedisTemplate<Object, Object> redisTemplate) {
+        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
+        redisTemplate.setKeySerializer(stringRedisSerializer);
+        // 如果手动将Value转换成了JSON,就不要再用JSON序列化器了。
+        // redisTemplate.setValueSerializer(new Jackson2JsonRedisSerializer<>(Object.class));
+        redisTemplate.setValueSerializer(stringRedisSerializer);
+        return redisTemplate;
+    }
+}

+ 7 - 0
java/src/main/java/boot/common/constant/SchoolConstant.java

@@ -0,0 +1,7 @@
+package boot.common.constant;
+
+public interface SchoolConstant {
+    String SCHOOL_LOGIN_USER = "app-online-token:";
+    int SCHOOL_SMS_SIZE = 6;
+    long SCHOOL_SMS_REDIS_TIME = 600L;
+}

+ 23 - 0
java/src/main/java/boot/common/enums/SchoolEnum.java

@@ -0,0 +1,23 @@
+package boot.common.enums;
+
+public enum SchoolEnum {
+    ENABLE_1(1, "开启"),
+    ENABLE_2(2, "关闭");
+
+    private Integer value;
+    private String desc;
+
+    public Integer getValue() {
+        return this.value;
+    }
+
+    public String getDesc() {
+        return this.desc;
+    }
+
+    private SchoolEnum(final Integer value, final String desc) {
+        this.value = value;
+        this.desc = desc;
+    }
+
+    }

+ 24 - 0
java/src/main/java/boot/common/enums/SmsTypeEnum.java

@@ -0,0 +1,24 @@
+package boot.common.enums;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.util.stream.Stream;
+
+@Getter
+@AllArgsConstructor
+public enum SmsTypeEnum {
+    BIND("bind","绑定手机短信"),
+    LOGIN("login","登陆短信"),
+    REGISTER("register","注册短信");
+
+    private String value;
+    private String desc;
+
+    public static SmsTypeEnum toType(String value) {
+        return Stream.of(SmsTypeEnum.values())
+                .filter(c -> c.value == value)
+                .findAny()
+                .orElse(null);
+    }
+}

+ 15 - 11
java/src/main/java/boot/common/interceptor/PermissionInterceptor.java

@@ -2,11 +2,14 @@
 package boot.common.interceptor;
 
 
-
+import boot.common.bean.LocalUser;
+import boot.common.constant.SchoolConstant;
 import boot.common.respond.ApiCode;
 import boot.common.respond.UnAuthenticatedException;
 import boot.common.utils.JwtToken;
 import boot.common.utils.RedisUtils;
+import boot.modules.user.pojo.User;
+import boot.modules.user.service.UserService;
 import com.auth0.jwt.interfaces.Claim;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.util.StringUtils;
@@ -21,14 +24,13 @@ import java.util.Optional;
 
 /**
  * 权限拦截器
+ *
  * @author zhonghui
  * @date 2020-04-30
  */
 public class PermissionInterceptor extends HandlerInterceptorAdapter {
-
-//    @Autowired
-//    private UserService userService;
-
+    @Autowired
+    private UserService userService;
     @Autowired
     private RedisUtils redisUtils;
 
@@ -67,15 +69,15 @@ public class PermissionInterceptor extends HandlerInterceptorAdapter {
         Map<String, Claim> map = optionalMap
                 .orElseThrow(() -> new UnAuthenticatedException(ApiCode.UNAUTHORIZED));
 
-        String uName = map.get("uName").asString();
+        String username = map.get("username").asString();
 
         //检测用户是否被踢出
-        if (redisUtils.get(ShopConstants.YSHOP_APP_LOGIN_USER + uName + ":" + token) == null) {
+        if (redisUtils.get(SchoolConstant.SCHOOL_LOGIN_USER + username + ":" + token) == null) {
             throw new UnAuthenticatedException(ApiCode.UNAUTHORIZED);
         }
         //
         boolean valid = this.hasPermission(authCheck.get(), map);
-        if(valid){
+        if (valid) {
             this.setToThreadLocal(map);
         }
         return valid;
@@ -83,13 +85,14 @@ public class PermissionInterceptor extends HandlerInterceptorAdapter {
 
     /**
      * 如果权限验证通过的情况下 将相关信息存储在线程本地
+     *
      * @param map
      */
-    private void setToThreadLocal(Map<String,Claim> map) {
+    private void setToThreadLocal(Map<String, Claim> map) {
         Integer uid = map.get("uid").asInt();
         Integer scope = map.get("scope").asInt();
-        ShopUser user = userService.getById(uid);
-        if(user == null) {
+        User user = userService.getById(uid);
+        if (user == null) {
             throw new UnAuthenticatedException(ApiCode.NOT_PERMISSION);
         }
         LocalUser.set(user, scope);
@@ -98,6 +101,7 @@ public class PermissionInterceptor extends HandlerInterceptorAdapter {
 
     /**
      * 验证传入的权限级别是否与 "scope" 的值匹配
+     *
      * @param authCheck
      * @param map
      * @return

+ 90 - 0
java/src/main/java/boot/common/utils/EncryptUtils.java

@@ -0,0 +1,90 @@
+package boot.common.utils;
+
+import org.springframework.util.DigestUtils;
+
+import javax.crypto.Cipher;
+import javax.crypto.SecretKey;
+import javax.crypto.SecretKeyFactory;
+import javax.crypto.spec.DESKeySpec;
+import javax.crypto.spec.IvParameterSpec;
+import java.nio.charset.StandardCharsets;
+
+public class EncryptUtils {
+    private static String strParam = "Passw0rd";
+    private static Cipher cipher;
+    private static IvParameterSpec iv;
+
+    public EncryptUtils() {
+    }
+
+    private static DESKeySpec getDesKeySpec(String source) throws Exception {
+        if (source != null && source.length() != 0) {
+            cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
+            String strKey = "Passw0rd";
+            return new DESKeySpec(strKey.getBytes(StandardCharsets.UTF_8));
+        } else {
+            return null;
+        }
+    }
+
+    public static String desEncrypt(String source) throws Exception {
+        DESKeySpec desKeySpec = getDesKeySpec(source);
+        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
+        SecretKey secretKey = keyFactory.generateSecret(desKeySpec);
+        cipher.init(1, secretKey, iv);
+        return byte2hex(cipher.doFinal(source.getBytes(StandardCharsets.UTF_8))).toUpperCase();
+    }
+
+    public static String desDecrypt(String source) throws Exception {
+        byte[] src = hex2byte(source.getBytes());
+        DESKeySpec desKeySpec = getDesKeySpec(source);
+        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
+        SecretKey secretKey = keyFactory.generateSecret(desKeySpec);
+        cipher.init(2, secretKey, iv);
+        byte[] retByte = cipher.doFinal(src);
+        return new String(retByte);
+    }
+
+    private static String byte2hex(byte[] inStr) {
+        StringBuilder out = new StringBuilder(inStr.length * 2);
+        byte[] var3 = inStr;
+        int var4 = inStr.length;
+
+        for(int var5 = 0; var5 < var4; ++var5) {
+            byte b = var3[var5];
+            String stmp = Integer.toHexString(b & 255);
+            if (stmp.length() == 1) {
+                out.append("0").append(stmp);
+            } else {
+                out.append(stmp);
+            }
+        }
+
+        return out.toString();
+    }
+
+    private static byte[] hex2byte(byte[] b) {
+        int size = 2;
+        if (b.length % size != 0) {
+            throw new IllegalArgumentException("长度不是偶数");
+        } else {
+            byte[] b2 = new byte[b.length / 2];
+
+            for(int n = 0; n < b.length; n += size) {
+                String item = new String(b, n, 2);
+                b2[n / 2] = (byte)Integer.parseInt(item, 16);
+            }
+
+            return b2;
+        }
+    }
+
+    public static String encryptPassword(String password) {
+        return DigestUtils.md5DigestAsHex(password.getBytes());
+    }
+
+    static {
+        iv = new IvParameterSpec(strParam.getBytes(StandardCharsets.UTF_8));
+    }
+}
+

+ 60 - 0
java/src/main/java/boot/common/utils/IpUtil.java

@@ -0,0 +1,60 @@
+package boot.common.utils;
+
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+
+import javax.servlet.http.HttpServletRequest;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+
+public final class IpUtil {
+
+    private static final String UNKNOWN = "unknown";
+    private static final String IPV6_LOCAL = "0:0:0:0:0:0:0:1";
+
+    private IpUtil(){
+        throw new AssertionError();
+    }
+
+    /**
+     * 获取请求用户的IP地址
+     * @return
+     */
+    public static String getRequestIp() {
+        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
+        HttpServletRequest request = attributes.getRequest();
+        return getRequestIp(request);
+    }
+
+    /**
+     * 获取请求用户的IP地址
+     * @param request
+     * @return
+     */
+    public static String getRequestIp(HttpServletRequest request) {
+        String ip = request.getHeader("x-forwarded-for");
+        if (ip == null || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip)) {
+            ip = request.getHeader("Proxy-Client-IP");
+        }
+        if (ip == null || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip)) {
+            ip = request.getHeader("WL-Proxy-Client-IP");
+        }
+        if (ip == null || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip)) {
+            ip = request.getRemoteAddr();
+        }
+
+        if (IPV6_LOCAL.equals(ip)){
+            ip = getLocalhostIp();
+        }
+        return ip;
+    }
+
+    public static String getLocalhostIp(){
+        try {
+            return InetAddress.getLocalHost().getHostAddress();
+        } catch (UnknownHostException e) {
+        }
+        return null;
+    }
+
+}

+ 2 - 2
java/src/main/java/boot/common/utils/JwtToken.java

@@ -19,12 +19,12 @@ public class JwtToken {
     private static Integer expiredTimeIn;
     private static Integer defaultScope = 8;
 
-    @Value("${eshop.security.jwt-key}")
+    @Value("${school.security.jwt-key}")
     public void setJwtKey(String jwtKey) {
         JwtToken.jwtKey = jwtKey;
     }
 
-    @Value("${eshop.security.token-expired-in}")
+    @Value("${school.security.token-expired-in}")
     public void setExpiredTimeIn(Integer expiredTimeIn) {
         JwtToken.expiredTimeIn = expiredTimeIn;
     }

+ 3 - 3
java/src/main/java/boot/common/utils/RedisUtils.java

@@ -26,7 +26,7 @@ import org.springframework.util.CollectionUtils;
 
 @Component
 public class RedisUtils {
-    private RedisTemplate<Object, Object> redisTemplate;
+    private final RedisTemplate<Object, Object> redisTemplate;
     @Value("${jwt.online-key}")
     private String onlineKey;
 
@@ -56,7 +56,7 @@ public class RedisUtils {
         RedisConnectionFactory factory = this.redisTemplate.getConnectionFactory();
         RedisConnection rc = ((RedisConnectionFactory)Objects.requireNonNull(factory)).getConnection();
         Cursor<byte[]> cursor = rc.scan(options);
-        List<String> result = new ArrayList();
+        List<String> result = new ArrayList<>();
 
         while(cursor.hasNext()) {
             result.add(new String((byte[])cursor.next()));
@@ -76,7 +76,7 @@ public class RedisUtils {
         RedisConnectionFactory factory = this.redisTemplate.getConnectionFactory();
         RedisConnection rc = ((RedisConnectionFactory)Objects.requireNonNull(factory)).getConnection();
         Cursor<byte[]> cursor = rc.scan(options);
-        List<String> result = new ArrayList(size);
+        List<String> result = new ArrayList<>(size);
         int tmpIndex = 0;
         int fromIndex = page * size;
         int toIndex = page * size + size;

+ 15 - 0
java/src/main/java/boot/common/utils/RequestUtils.java

@@ -0,0 +1,15 @@
+package boot.common.utils;
+
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+
+import javax.servlet.http.HttpServletRequest;
+
+public class RequestUtils {
+
+    public static HttpServletRequest getRequest() {
+        ServletRequestAttributes ra= (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
+        return ra.getRequest();
+    }
+
+}

+ 147 - 0
java/src/main/java/boot/common/utils/StringUtils.java

@@ -0,0 +1,147 @@
+package boot.common.utils;
+
+import cn.hutool.http.HttpUtil;
+
+import cn.hutool.json.JSONObject;
+import cn.hutool.json.JSONUtil;
+import eu.bitwalker.useragentutils.Browser;
+import eu.bitwalker.useragentutils.UserAgent;
+
+import javax.servlet.http.HttpServletRequest;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.Calendar;
+import java.util.Date;
+
+public class StringUtils  {
+    private static final char SEPARATOR = '_';
+    private static final String UNKNOWN = "unknown";
+
+    public StringUtils() {
+    }
+
+    public static String toCamelCase(String s) {
+        if (s == null) {
+            return null;
+        } else {
+            s = s.toLowerCase();
+            StringBuilder sb = new StringBuilder(s.length());
+            boolean upperCase = false;
+
+            for(int i = 0; i < s.length(); ++i) {
+                char c = s.charAt(i);
+                if (c == '_') {
+                    upperCase = true;
+                } else if (upperCase) {
+                    sb.append(Character.toUpperCase(c));
+                    upperCase = false;
+                } else {
+                    sb.append(c);
+                }
+            }
+
+            return sb.toString();
+        }
+    }
+
+    public static String toCapitalizeCamelCase(String s) {
+        if (s == null) {
+            return null;
+        } else {
+            s = toCamelCase(s);
+            return s.substring(0, 1).toUpperCase() + s.substring(1);
+        }
+    }
+
+    static String toUnderScoreCase(String s) {
+        if (s == null) {
+            return null;
+        } else {
+            StringBuilder sb = new StringBuilder();
+            boolean upperCase = false;
+
+            for(int i = 0; i < s.length(); ++i) {
+                char c = s.charAt(i);
+                boolean nextUpperCase = true;
+                if (i < s.length() - 1) {
+                    nextUpperCase = Character.isUpperCase(s.charAt(i + 1));
+                }
+
+                if (i > 0 && Character.isUpperCase(c)) {
+                    if (!upperCase || !nextUpperCase) {
+                        sb.append('_');
+                    }
+
+                    upperCase = true;
+                } else {
+                    upperCase = false;
+                }
+
+                sb.append(Character.toLowerCase(c));
+            }
+
+            return sb.toString();
+        }
+    }
+
+    public static String getIp(HttpServletRequest request) {
+        String ip = request.getHeader("x-forwarded-for");
+        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
+            ip = request.getHeader("Proxy-Client-IP");
+        }
+
+        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
+            ip = request.getHeader("WL-Proxy-Client-IP");
+        }
+
+        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
+            ip = request.getRemoteAddr();
+        }
+
+        String comma = ",";
+        String localhost = "127.0.0.1";
+        if (ip.contains(comma)) {
+            ip = ip.split(",")[0];
+        }
+
+        if (localhost.equals(ip)) {
+            try {
+                ip = InetAddress.getLocalHost().getHostAddress();
+            } catch (UnknownHostException var5) {
+                var5.printStackTrace();
+            }
+        }
+
+        return ip;
+    }
+
+    public static String getCityInfo(String ip) {
+        String api = String.format("http://whois.pconline.com.cn/ipJson.jsp?ip=%s&json=true", ip);
+
+        try {
+            JSONObject object = JSONUtil.parseObj(HttpUtil.get(api));
+            return (String)object.get("addr", String.class);
+        } catch (Exception var3) {
+            return "";
+        }
+    }
+
+    public static String getBrowser(HttpServletRequest request) {
+        UserAgent userAgent = UserAgent.parseUserAgentString(request.getHeader("User-Agent"));
+        Browser browser = userAgent.getBrowser();
+        return browser.getName();
+    }
+
+    public static String getWeekDay() {
+        String[] weekDays = new String[]{"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
+        Calendar cal = Calendar.getInstance();
+        cal.setTime(new Date());
+        int w = cal.get(7) - 1;
+        if (w < 0) {
+            w = 0;
+        }
+
+        return weekDays[w];
+    }
+}
+

+ 179 - 0
java/src/main/java/boot/modules/user/controller/UserController.java

@@ -0,0 +1,179 @@
+package boot.modules.user.controller;
+
+import boot.common.bean.LocalUser;
+import boot.common.constant.SchoolConstant;
+import boot.common.enums.SchoolEnum;
+import boot.common.enums.SmsTypeEnum;
+import boot.common.interceptor.AuthCheck;
+import boot.common.respond.ApiResult;
+import boot.common.respond.EException;
+import boot.common.utils.JwtToken;
+import boot.common.utils.RedisUtils;
+import boot.modules.user.param.ForgetParam;
+import boot.modules.user.param.HLoginParam;
+import boot.modules.user.param.RegParam;
+import boot.modules.user.param.VerityParam;
+import boot.modules.user.pojo.User;
+import boot.modules.user.service.UserService;
+import boot.modules.user.service.impl.AuthService;
+import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.core.util.RandomUtil;
+import cn.hutool.core.util.StrUtil;
+import cn.hutool.crypto.SecureUtil;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.HashMap;
+import java.util.Map;
+
+
+@Slf4j
+@RestController
+@RequiredArgsConstructor(onConstructor = @__(@Autowired))
+@Api(value = "认证模块", tags = "商城:认证")
+public class UserController {
+    private final UserService userService;
+    private final RedisUtils redisUtil;
+    private final AuthService authService;
+
+    @Value("${single.login}")
+    private Boolean singleLogin;
+
+    @ApiOperation("H5登录授权")
+    @PostMapping(value = "/login")
+    public ApiResult<Map<String, Object>> login(@Validated @RequestBody HLoginParam loginDTO, HttpServletRequest request) {
+        //查询数据库是否有此用户
+        User shopUser = userService.getOne(Wrappers.<User>lambdaQuery()
+                .eq(User::getUsername, loginDTO.getUsername())
+                .eq(User::getPassword, SecureUtil.md5(loginDTO.getPassword())), false);
+
+        if (shopUser == null) {
+            throw new EException("账号或者密码不正确");
+        }
+        //生成 token
+        String token = JwtToken.makeToken(shopUser.getUid(), shopUser.getUsername());
+        //token 过期时间
+        String expiresTimeStr = JwtToken.getExpireTime(token);
+
+        // 保存在线信息
+        authService.save(shopUser, token, request);
+        // 返回 token
+        Map<String, Object> map = new HashMap<String, Object>(2) {{
+            put("token", token);
+            put("expires_time", expiresTimeStr);
+        }};
+        //singleLogin 是在yaml配置文件中的一项 默认值为 false
+        if (singleLogin) {
+            //踢掉之前已经登录的token
+            authService.checkLoginOnUser(shopUser.getUsername(), token);
+        }
+
+        return ApiResult.ok(map).setMsg("登陆成功");
+    }
+
+
+    @PostMapping("/register")
+    @ApiOperation(value = "H5/APP注册新用户", notes = "H5/APP注册新用户")
+    public ApiResult<String> register(@Validated @RequestBody RegParam param) {
+        Object codeObj = redisUtil.get("code_" + param.getAccount());
+        if (codeObj == null) {
+            return ApiResult.fail("请先获取验证码");
+        }
+        String code = codeObj.toString();
+        if (!StrUtil.equals(code, param.getCaptcha())) {
+            return ApiResult.fail("验证码错误");
+        }
+        User shopUser = userService.getOne(Wrappers.<User>lambdaQuery()
+                .eq(User::getPhone, param.getAccount()), false);
+        if (shopUser != null) {
+            return ApiResult.fail("该手机号已存在");
+        }
+        authService.register(param);
+        return ApiResult.ok("", "注册成功");
+    }
+
+
+    @PostMapping("/register/verify")
+    @ApiOperation(value = "短信验证码发送", notes = "短信验证码发送")
+    public ApiResult<String> verify(@Validated @RequestBody VerityParam param) {
+        User shopUser = userService.getOne(Wrappers.<User>lambdaQuery()
+                .eq(User::getPhone, param.getPhone()), false);
+        if (SmsTypeEnum.REGISTER.getValue().equals(param.getType()) && ObjectUtil.isNotNull(shopUser)) {
+            return ApiResult.fail("手机号已注册");
+        }
+        if (SmsTypeEnum.LOGIN.getValue().equals(param.getType()) && ObjectUtil.isNull(shopUser)) {
+            return ApiResult.fail("账号不存在");
+        }
+        String codeKey = "code_" + param.getPhone();
+        if (ObjectUtil.isNotNull(redisUtil.get(codeKey))) {
+            return ApiResult.fail("10分钟内有效:" + redisUtil.get(codeKey).toString());
+        }
+        String code = RandomUtil.randomNumbers(SchoolConstant.SCHOOL_SMS_SIZE);
+
+        //redis存储
+        redisUtil.set(codeKey, code, SchoolConstant.SCHOOL_SMS_REDIS_TIME);
+
+//        String enable = redisUtil.getY("sms_enable");
+        Boolean enable = false;
+//        if (SchoolEnum.ENABLE_2.getValue().toString().equals(enable)) {
+        return ApiResult.ok(code);
+//        }
+
+        //发送阿里云短信
+//        JSONObject json = new JSONObject();
+//        json.put("code", code);
+//        try {
+//            SmsUtils.sendSms(param.getPhone(), json.toJSONString());
+//        } catch (ClientException e) {
+//            redisUtil.del(codeKey);
+//            e.printStackTrace();
+//            return ApiResult.ok("发送失败:" + e.getErrMsg());
+//        }
+//        return ApiResult.ok("发送成功,请注意查收");
+
+    }
+    @AuthCheck
+    @ApiOperation(value = "退出登录", notes = "退出登录")
+    @PostMapping(value = "/auth/logout")
+    public ApiResult<String> logout(HttpServletRequest request) {
+        String bearerToken = request.getHeader("Authorization");
+        String[] tokens = bearerToken.split(" ");
+        String token = tokens[1];
+        authService.logout(LocalUser.getUser().getUsername(), token);
+        return ApiResult.ok("退出成功");
+    }
+
+    @ApiOperation(value = "忘记密码", notes = "忘记密码")
+    @PostMapping(value = "/forget")
+    public ApiResult<String> forget(@Validated @RequestBody ForgetParam param) {
+        Object codeObj = redisUtil.get("code_" + param.getAccount());
+        if (codeObj == null) {
+            return ApiResult.fail("请先获取验证码");
+        }
+        String code = codeObj.toString();
+        if (!StrUtil.equals(code, param.getCaptcha())) {
+            return ApiResult.fail("验证码错误");
+        }
+
+        User shopUser = userService.getOne(Wrappers.<User>lambdaQuery()
+                .eq(User::getPhone, param.getAccount()), false);
+        if (ObjectUtil.isNull(shopUser)) {
+            return ApiResult.fail("该用户不存在");
+        }
+
+        shopUser.setPassword(SecureUtil.md5(param.getPassword()));
+        userService.updateById(shopUser);
+        return ApiResult.ok("密码重置成功");
+    }
+}

+ 2 - 0
java/src/main/java/boot/modules/user/mapper/UserMapper.java

@@ -2,6 +2,7 @@ package boot.modules.user.mapper;
 
 import boot.modules.user.pojo.User;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
 
 /**
 * @author Lin
@@ -9,6 +10,7 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 * @createDate 2024-05-29 23:44:49
 * @Entity user.pojo.User
 */
+@Mapper
 public interface UserMapper extends BaseMapper<User> {
 
 }

+ 23 - 0
java/src/main/java/boot/modules/user/param/ForgetParam.java

@@ -0,0 +1,23 @@
+package boot.modules.user.param;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+
+@Data
+public class ForgetParam {
+
+    @NotBlank(message = "手机号必填")
+    @ApiModelProperty(value = "手机号码")
+    private String account;
+
+    @NotBlank(message = "验证码必填")
+    @ApiModelProperty(value = "验证码")
+    private String captcha;
+
+    @NotBlank(message = "密码必填")
+    @ApiModelProperty(value = "密码")
+    private String password;
+
+}

+ 27 - 0
java/src/main/java/boot/modules/user/param/HLoginParam.java

@@ -0,0 +1,27 @@
+package boot.modules.user.param;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Getter;
+import lombok.Setter;
+import lombok.ToString;
+
+import javax.validation.constraints.NotBlank;
+
+@Getter
+@Setter
+@ToString
+public class HLoginParam {
+
+    @NotBlank(message = "用户名必填")
+    @ApiModelProperty(value = "用户名")
+    private String username;
+
+    @NotBlank(message = "密码必填")
+    @ApiModelProperty(value = "密码")
+    private String password;
+
+    @ApiModelProperty(value = "分销绑定关系的ID")
+    private String spread;
+
+
+}

+ 26 - 0
java/src/main/java/boot/modules/user/param/RegParam.java

@@ -0,0 +1,26 @@
+package boot.modules.user.param;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+
+@Data
+public class RegParam {
+
+    @NotBlank(message = "手机号必填")
+    @ApiModelProperty(value = "手机号码")
+    private String account;
+
+    @NotBlank(message = "验证码必填")
+    @ApiModelProperty(value = "验证码")
+    private String captcha;
+
+    @NotBlank(message = "密码必填")
+    @ApiModelProperty(value = "密码")
+    private String password;
+
+    private String nickname;
+    @ApiModelProperty(value = "邀请码")
+    private String inviteCode;
+}

+ 17 - 0
java/src/main/java/boot/modules/user/param/VerityParam.java

@@ -0,0 +1,17 @@
+package boot.modules.user.param;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+
+@Data
+public class VerityParam {
+
+    @NotBlank(message = "手机号必填")
+    @ApiModelProperty(value = "手机号码")
+    private String phone;
+
+    @ApiModelProperty(value = "短信类型 bind绑定手机短信 login登陆短信 register注册短信")
+    private String type;
+}

+ 3 - 0
java/src/main/java/boot/modules/user/pojo/User.java

@@ -2,6 +2,8 @@ package boot.modules.user.pojo;
 
 import java.io.Serializable;
 import java.util.Date;
+
+import lombok.Builder;
 import lombok.Data;
 
 /**
@@ -9,6 +11,7 @@ import lombok.Data;
  * @TableName user
  */
 @Data
+@Builder
 public class User implements Serializable {
     /**
      * 用户id

+ 153 - 0
java/src/main/java/boot/modules/user/service/impl/AuthService.java

@@ -0,0 +1,153 @@
+package boot.modules.user.service.impl;
+
+import boot.common.bean.OnlineUser;
+import boot.common.constant.SchoolConstant;
+import boot.common.respond.EException;
+import boot.common.utils.EncryptUtils;
+import boot.common.utils.IpUtil;
+import boot.common.utils.RedisUtils;
+import boot.common.utils.StringUtils;
+import boot.modules.user.param.RegParam;
+import boot.modules.user.pojo.User;
+import boot.modules.user.service.UserService;
+import cn.hutool.core.net.Ipv4Util;
+import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.core.util.StrUtil;
+import cn.hutool.crypto.SecureUtil;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Date;
+import java.util.List;
+
+@Slf4j
+@Service
+@RequiredArgsConstructor(onConstructor = @__(@Autowired))
+public class AuthService {
+
+    private final UserService userService;
+    private final RedisUtils redisUtils;
+    private static Integer expiredTimeIn;
+
+    @Value("${school.security.token-expired-in}")
+    public void setExpiredTimeIn(Integer expiredTimeIn) {
+        AuthService.expiredTimeIn = expiredTimeIn;
+    }
+
+    /**
+     * 注册
+     * @param param RegDTO
+     */
+    @Transactional(rollbackFor = Exception.class)
+    public void register(RegParam param){
+
+        String account = param.getAccount();
+        String ip = IpUtil.getRequestIp();
+        User user = User.builder()
+                .username(account)
+                .nickname(param.getNickname())
+                .password(SecureUtil.md5(param.getPassword()))
+                .phone(account)
+                .avatar(null)
+                .addIp(ip)
+                .lastIp(ip)
+                .build();
+
+        userService.save(user);
+
+    }
+
+
+    /**
+     * 保存在线用户信息
+     * @param user /
+     * @param token /
+     * @param request /
+     */
+    public void save(User user, String token, HttpServletRequest request){
+        String job = "yshop开发工程师";
+        String ip = IpUtil.getRequestIp();
+        String browser = StringUtils.getBrowser(request);
+        String address = StringUtils.getCityInfo(ip);
+        OnlineUser onlineUser = null;
+        try {
+            onlineUser = new OnlineUser(user.getUsername(), user.getNickname(), job, browser ,
+                    ip, address, EncryptUtils.desEncrypt(token), new Date());
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        redisUtils.set(SchoolConstant.SCHOOL_LOGIN_USER +onlineUser.getUserName() + ":" + token, onlineUser, AuthService.expiredTimeIn);
+    }
+
+    /**
+     * 检测用户是否在之前已经登录,已经登录踢下线
+     *
+     * @param userName 用户名
+     */
+    public void checkLoginOnUser(String userName, String igoreToken) {
+        List<OnlineUser> onlineUsers = this.getAll(userName);
+        if (onlineUsers == null || onlineUsers.isEmpty()) {
+            return;
+        }
+        for (OnlineUser onlineUser : onlineUsers) {
+            try {
+                String token = EncryptUtils.desDecrypt(onlineUser.getKey());
+                if (StrUtil.isNotBlank(igoreToken) && !igoreToken.equals(token)) {
+                    this.kickOut(userName, onlineUser.getKey());
+                } else if (StrUtil.isBlank(igoreToken)) {
+                    this.kickOut(userName, onlineUser.getKey());
+                }
+            } catch (Exception e) {
+                log.error("checkUser is error", e);
+            }
+        }
+    }
+
+    /**
+     * 踢出用户
+     *
+     * @param key /
+     */
+    public void kickOut(String userName, String key) throws Exception {
+        key = SchoolConstant.SCHOOL_LOGIN_USER + userName + ":" + EncryptUtils.desDecrypt(key);
+        redisUtils.del(key);
+    }
+
+    /**
+     * 退出登录
+     * @param token /
+     */
+    public void logout(String userName,String token) {
+        String key = SchoolConstant.SCHOOL_LOGIN_USER+ userName + ":" + token;
+        redisUtils.del(key);
+    }
+
+    /**
+     * 查询全部数据,不分页
+     *
+     * @param uName /
+     * @return /
+     */
+    private List<OnlineUser> getAll(String uName) {
+        List<String> keys = null;
+        keys = redisUtils.scan(SchoolConstant.SCHOOL_LOGIN_USER + uName + ":" + "*");
+
+        Collections.reverse(keys);
+        List<OnlineUser> onlineUsers = new ArrayList<>();
+        for (String key : keys) {
+            OnlineUser onlineUser = (OnlineUser) redisUtils.get(key);
+            onlineUsers.add(onlineUser);
+        }
+        onlineUsers.sort((o1, o2) -> o2.getLoginTime().compareTo(o1.getLoginTime()));
+        return onlineUsers;
+    }
+}
+

+ 5 - 6
java/src/main/java/boot/modules/user/service/impl/UserServiceImpl.java

@@ -7,13 +7,12 @@ import boot.modules.user.mapper.UserMapper;
 import org.springframework.stereotype.Service;
 
 /**
-* @author Lin
-* @description 针对表【user(用户表)】的数据库操作Service实现
-* @createDate 2024-05-29 23:44:49
-*/
+ * @author Lin
+ * @description 针对表【user(用户表)】的数据库操作Service实现
+ * @createDate 2024-05-29 23:44:49
+ */
 @Service
-public class UserServiceImpl extends ServiceImpl<UserMapper, User>
-    implements UserService{
+public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
 
 }
 

+ 35 - 1
java/src/main/resources/application.yaml

@@ -13,6 +13,40 @@ spring:
   servlet:
     multipart:
       max-file-size: 10MB
+  redis:
+    host: localhost # Redis服务器地址
+    database: 1 # Redis数据库索引(默认为0)
+    port: 6379 # Redis服务器连接端口
+    password: # Redis服务器连接密码(默认为空)
+    jedis:
+     pool:
+      max-active: 8 # 连接池最大连接数(使用负值表示没有限制)
+      max-wait: -1ms # 连接池最大阻塞等待时间(使用负值表示没有限制)
+      max-idle: 8 # 连接池中的最大空闲连接
+      min-idle: 0 # 连接池中的最小空闲连接
+      timeout: 3000ms # 连接超时时间(毫秒)
+  cache:
+    # spring cache 缓存类型为redis  也可以是其他的实现
+    type: redis
+
 mybatis:
   configuration:
-    map-underscore-to-camel-case: true
+    map-underscore-to-camel-case: true
+
+
+
+
+school:
+  security:
+    jwt-key: webporject
+    token-expired-in: 86400000
+
+jwt:
+  header: Authorization
+  # 令牌前缀
+  token-start-with: Bearer
+  online-key: school
+
+# 是否限制单用户登录
+single:
+  login: false

+ 36 - 2
java/target/classes/application.yaml

@@ -2,7 +2,7 @@ server:
   port: 8888
 spring:
   datasource:
-    url: jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=UTF-8
+    url: jdbc:mysql://localhost:3306/school?useUnicode=true&characterEncoding=UTF-8
     driver-class-name: com.mysql.cj.jdbc.Driver
     username: root
     password: 13316814026
@@ -13,6 +13,40 @@ spring:
   servlet:
     multipart:
       max-file-size: 10MB
+  redis:
+    host: localhost # Redis服务器地址
+    database: 1 # Redis数据库索引(默认为0)
+    port: 6379 # Redis服务器连接端口
+    password: # Redis服务器连接密码(默认为空)
+    jedis:
+     pool:
+      max-active: 8 # 连接池最大连接数(使用负值表示没有限制)
+      max-wait: -1ms # 连接池最大阻塞等待时间(使用负值表示没有限制)
+      max-idle: 8 # 连接池中的最大空闲连接
+      min-idle: 0 # 连接池中的最小空闲连接
+      timeout: 3000ms # 连接超时时间(毫秒)
+  cache:
+    # spring cache 缓存类型为redis  也可以是其他的实现
+    type: redis
+
 mybatis:
   configuration:
-    map-underscore-to-camel-case: true
+    map-underscore-to-camel-case: true
+
+
+
+
+school:
+  security:
+    jwt-key: webporject
+    token-expired-in: 86400000
+
+jwt:
+  header: Authorization
+  # 令牌前缀
+  token-start-with: Bearer
+  online-key: school
+
+# 是否限制单用户登录
+single:
+  login: false

BIN
java/target/classes/boot/BootApplication.class


BIN
java/target/classes/boot/common/bean/LocalUser.class


BIN
java/target/classes/boot/common/bean/OnlineUser.class


BIN
java/target/classes/boot/common/bean/RequestDetail.class


BIN
java/target/classes/boot/common/config/MybatisPlusConfig.class


BIN
java/target/classes/boot/common/config/RedisConfig.class


BIN
java/target/classes/boot/common/constant/SchoolConstant.class


BIN
java/target/classes/boot/common/enums/SchoolEnum.class


BIN
java/target/classes/boot/common/enums/SmsTypeEnum.class


BIN
java/target/classes/boot/common/interceptor/AuthCheck.class


BIN
java/target/classes/boot/common/interceptor/PermissionInterceptor.class


BIN
java/target/classes/boot/common/respond/ApiCode.class


BIN
java/target/classes/boot/common/respond/ApiResult$ApiResultBuilder.class


BIN
java/target/classes/boot/common/respond/ApiResult.class


BIN
java/target/classes/boot/common/respond/EException.class


BIN
java/target/classes/boot/common/respond/UnAuthenticatedException.class


BIN
java/target/classes/boot/common/utils/EncryptUtils.class


BIN
java/target/classes/boot/common/utils/IpUtil.class


BIN
java/target/classes/boot/common/utils/JwtToken.class


BIN
java/target/classes/boot/common/utils/RedisUtils.class


BIN
java/target/classes/boot/common/utils/RequestUtils.class


BIN
java/target/classes/boot/common/utils/StringUtils.class


BIN
java/target/classes/boot/modules/user/controller/UserController$1.class


BIN
java/target/classes/boot/modules/user/controller/UserController.class


BIN
java/target/classes/boot/modules/user/mapper/UserMapper.class


BIN
java/target/classes/boot/modules/user/param/ForgetParam.class


BIN
java/target/classes/boot/modules/user/param/HLoginParam.class


BIN
java/target/classes/boot/modules/user/param/RegParam.class


BIN
java/target/classes/boot/modules/user/param/VerityParam.class


BIN
java/target/classes/boot/modules/user/pojo/User$UserBuilder.class


BIN
java/target/classes/boot/modules/user/pojo/User.class


BIN
java/target/classes/boot/modules/user/service/UserService.class


BIN
java/target/classes/boot/modules/user/service/impl/AuthService.class


BIN
java/target/classes/boot/modules/user/service/impl/UserServiceImpl.class


+ 40 - 0
java/target/classes/mapper/UserMapper.xml

@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper
+        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="user.mapper.UserMapper">
+
+    <resultMap id="BaseResultMap" type="user.pojo.User">
+            <id property="uid" column="uid" jdbcType="BIGINT"/>
+            <result property="username" column="username" jdbcType="VARCHAR"/>
+            <result property="password" column="password" jdbcType="VARCHAR"/>
+            <result property="realName" column="real_name" jdbcType="VARCHAR"/>
+            <result property="birthday" column="birthday" jdbcType="INTEGER"/>
+            <result property="cardId" column="card_id" jdbcType="VARCHAR"/>
+            <result property="mark" column="mark" jdbcType="VARCHAR"/>
+            <result property="groupId" column="group_id" jdbcType="INTEGER"/>
+            <result property="nickname" column="nickname" jdbcType="VARCHAR"/>
+            <result property="avatar" column="avatar" jdbcType="VARCHAR"/>
+            <result property="phone" column="phone" jdbcType="CHAR"/>
+            <result property="addIp" column="add_ip" jdbcType="VARCHAR"/>
+            <result property="createTime" column="create_time" jdbcType="TIMESTAMP"/>
+            <result property="updateTime" column="update_time" jdbcType="TIMESTAMP"/>
+            <result property="lastIp" column="last_ip" jdbcType="VARCHAR"/>
+            <result property="status" column="status" jdbcType="TINYINT"/>
+            <result property="level" column="level" jdbcType="TINYINT"/>
+            <result property="spreadCount" column="spread_count" jdbcType="INTEGER"/>
+            <result property="address" column="address" jdbcType="VARCHAR"/>
+            <result property="loginType" column="login_type" jdbcType="VARCHAR"/>
+            <result property="isDel" column="is_del" jdbcType="TINYINT"/>
+    </resultMap>
+
+    <sql id="Base_Column_List">
+        uid,username,password,
+        real_name,birthday,card_id,
+        mark,group_id,nickname,
+        avatar,phone,add_ip,
+        create_time,update_time,last_ip,
+        status,level,spread_count,
+        address,login_type,is_del
+    </sql>
+</mapper>