diff --git a/珞珈岛-项目相关文件/luojia-island b/珞珈岛-项目相关文件/luojia-island
deleted file mode 160000
index 2e2880c..0000000
--- a/珞珈岛-项目相关文件/luojia-island
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit 2e2880c728025949cb342f72f73d95d2cce8fd1d
diff --git a/珞珈岛-项目相关文件/luojia-island/.idea/.gitignore b/珞珈岛-项目相关文件/luojia-island/.idea/.gitignore
new file mode 100644
index 0000000..35410ca
--- /dev/null
+++ b/珞珈岛-项目相关文件/luojia-island/.idea/.gitignore
@@ -0,0 +1,8 @@
+# 默认忽略的文件
+/shelf/
+/workspace.xml
+# 基于编辑器的 HTTP 客户端请求
+/httpRequests/
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml
diff --git a/珞珈岛-项目相关文件/luojia-island/.idea/compiler.xml b/珞珈岛-项目相关文件/luojia-island/.idea/compiler.xml
new file mode 100644
index 0000000..894b4bb
--- /dev/null
+++ b/珞珈岛-项目相关文件/luojia-island/.idea/compiler.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/珞珈岛-项目相关文件/luojia-island/.idea/dataSources.xml b/珞珈岛-项目相关文件/luojia-island/.idea/dataSources.xml
new file mode 100644
index 0000000..2cdd411
--- /dev/null
+++ b/珞珈岛-项目相关文件/luojia-island/.idea/dataSources.xml
@@ -0,0 +1,31 @@
+
+
+
+
+ mysql.8
+ true
+ true
+ com.mysql.cj.jdbc.Driver
+ jdbc:mysql://192.168.59.129:3306/luojia_channel?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghai
+
+
+
+
+
+ $ProjectFileDir$
+
+
+ redis
+ true
+ true
+ jdbc.RedisDriver
+ jdbc:redis://192.168.59.129:6379/0
+
+
+
+
+
+ $ProjectFileDir$
+
+
+
\ No newline at end of file
diff --git a/珞珈岛-项目相关文件/luojia-island/.idea/encodings.xml b/珞珈岛-项目相关文件/luojia-island/.idea/encodings.xml
new file mode 100644
index 0000000..e845c72
--- /dev/null
+++ b/珞珈岛-项目相关文件/luojia-island/.idea/encodings.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/珞珈岛-项目相关文件/luojia-island/.idea/jarRepositories.xml b/珞珈岛-项目相关文件/luojia-island/.idea/jarRepositories.xml
new file mode 100644
index 0000000..c7ea920
--- /dev/null
+++ b/珞珈岛-项目相关文件/luojia-island/.idea/jarRepositories.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/珞珈岛-项目相关文件/luojia-island/.idea/misc.xml b/珞珈岛-项目相关文件/luojia-island/.idea/misc.xml
new file mode 100644
index 0000000..82dbec8
--- /dev/null
+++ b/珞珈岛-项目相关文件/luojia-island/.idea/misc.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/珞珈岛-项目相关文件/luojia-island/.idea/settings.json b/珞珈岛-项目相关文件/luojia-island/.idea/settings.json
new file mode 100644
index 0000000..152dce8
--- /dev/null
+++ b/珞珈岛-项目相关文件/luojia-island/.idea/settings.json
@@ -0,0 +1,17 @@
+
+{
+ "luatools_path": "~/go/bin",
+ "dto_dir": "./ngx_conf/dto",
+ "swagger.docs.path": "./docs",
+ "swagger.excludes": "./client",
+ "swagger.file.type": "json",
+ "swagger.main.lua.path": "./main.lua",
+ "swagger.name": "swagger",
+ "swagger.search_dirs": "./ngx_conf,./config/cn/online",
+ "validator_dir": "./ngx_conf/validator",
+ "yapi.config.file": "docs/swagger-yapi.json",
+ "yapi.config.mode": "mergin",
+ "yapi.config.server": "https://api.yapi.net",
+ "yapi.config.token": "xxxxxxxxx"
+}
+
\ No newline at end of file
diff --git a/珞珈岛-项目相关文件/luojia-island/.idea/sqldialects.xml b/珞珈岛-项目相关文件/luojia-island/.idea/sqldialects.xml
new file mode 100644
index 0000000..36966c2
--- /dev/null
+++ b/珞珈岛-项目相关文件/luojia-island/.idea/sqldialects.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/珞珈岛-项目相关文件/luojia-island/.idea/uiDesigner.xml b/珞珈岛-项目相关文件/luojia-island/.idea/uiDesigner.xml
new file mode 100644
index 0000000..2b63946
--- /dev/null
+++ b/珞珈岛-项目相关文件/luojia-island/.idea/uiDesigner.xml
@@ -0,0 +1,124 @@
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+
\ No newline at end of file
diff --git a/珞珈岛-项目相关文件/luojia-island/common/pom.xml b/珞珈岛-项目相关文件/luojia-island/common/pom.xml
new file mode 100644
index 0000000..cc28f5e
--- /dev/null
+++ b/珞珈岛-项目相关文件/luojia-island/common/pom.xml
@@ -0,0 +1,67 @@
+
+
+ 4.0.0
+
+ com.luojia
+ luojia_channel
+ 1.0.0
+
+
+ common
+
+
+
+
+
+ org.redisson
+ redisson-spring-boot-starter
+
+
+
+
+ org.apache.commons
+ commons-lang3
+ 3.14.0
+
+
+ com.alibaba
+ transmittable-thread-local
+ 2.13.0
+
+
+
+ io.jsonwebtoken
+ jjwt-api
+ 0.11.5
+
+
+ io.jsonwebtoken
+ jjwt-impl
+ 0.11.5
+ runtime
+
+
+ io.jsonwebtoken
+ jjwt-jackson
+ 0.11.5
+ runtime
+
+
+
+ org.springframework
+ spring-web
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
diff --git a/珞珈岛-项目相关文件/luojia-island/common/src/main/java/com/luojia_channel/common/advice/GlobalExceptionHandler.java b/珞珈岛-项目相关文件/luojia-island/common/src/main/java/com/luojia_channel/common/advice/GlobalExceptionHandler.java
new file mode 100644
index 0000000..7034f3b
--- /dev/null
+++ b/珞珈岛-项目相关文件/luojia-island/common/src/main/java/com/luojia_channel/common/advice/GlobalExceptionHandler.java
@@ -0,0 +1,22 @@
+package com.luojia_channel.common.advice;
+
+
+import com.luojia_channel.common.domain.Result;
+import com.luojia_channel.common.exception.BaseException;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.web.bind.annotation.RestControllerAdvice;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+
+// 全局异常处理
+@Slf4j
+@RestControllerAdvice
+public class GlobalExceptionHandler {
+ // 处理自定义业务异常
+ @ExceptionHandler(BaseException.class)
+ public Object handleBadRequestException(BaseException e) {
+ log.error("自定义异常 -> {} , 异常原因:{} ",e.getClass().getName(), e.getMessage());
+ log.debug("", e);
+ return Result.fail(e.getErrorCode(), e.getErrorMessage());
+ }
+
+}
diff --git a/珞珈岛-项目相关文件/luojia-island/common/src/main/java/com/luojia_channel/common/config/RedisConfig.java b/珞珈岛-项目相关文件/luojia-island/common/src/main/java/com/luojia_channel/common/config/RedisConfig.java
new file mode 100644
index 0000000..4502db3
--- /dev/null
+++ b/珞珈岛-项目相关文件/luojia-island/common/src/main/java/com/luojia_channel/common/config/RedisConfig.java
@@ -0,0 +1,45 @@
+package com.luojia_channel.common.config;
+
+import com.alibaba.fastjson.support.spring.GenericFastJsonRedisSerializer;
+import org.redisson.Redisson;
+import org.redisson.api.RedissonClient;
+import org.redisson.config.Config;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.data.redis.connection.RedisConnectionFactory;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.data.redis.serializer.StringRedisSerializer;
+
+@Configuration
+public class RedisConfig {
+ @Bean
+ public RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory) {
+
+ RedisTemplate redisTemplate = new RedisTemplate<>();
+ redisTemplate.setConnectionFactory(redisConnectionFactory);
+ // 设置key和value的序列化规则
+ redisTemplate.setKeySerializer(new StringRedisSerializer());
+ redisTemplate.setValueSerializer(new GenericFastJsonRedisSerializer());
+ redisTemplate.setHashKeySerializer(new StringRedisSerializer());
+ redisTemplate.setHashValueSerializer(new GenericFastJsonRedisSerializer());
+
+ return redisTemplate;
+ }
+
+ // Redisson分布式锁
+ @Value("${spring.data.redis.host}")
+ private String host;
+ @Value("${spring.data.redis.port}")
+ private String port;
+ @Value("${spring.data.redis.password}")
+ private String password;
+ @Bean
+ public RedissonClient redissonClient(){
+ //配置
+ Config config=new Config();
+ config.useSingleServer().setAddress("redis://"+host+":"+port).setPassword(password);
+ //创建对并且返回
+ return Redisson.create(config);
+ }
+}
diff --git a/珞珈岛-项目相关文件/luojia-island/common/src/main/java/com/luojia_channel/common/domain/Result.java b/珞珈岛-项目相关文件/luojia-island/common/src/main/java/com/luojia_channel/common/domain/Result.java
new file mode 100644
index 0000000..5c754b5
--- /dev/null
+++ b/珞珈岛-项目相关文件/luojia-island/common/src/main/java/com/luojia_channel/common/domain/Result.java
@@ -0,0 +1,28 @@
+package com.luojia_channel.common.domain;
+
+import lombok.Data;
+
+// 统一返回前端的结果
+@Data
+public class Result {
+ private int code;
+ private String msg;
+ private T data;
+ public Result(int code, String msg, T data) {
+ this.code = code;
+ this.msg = msg;
+ this.data = data;
+ }
+ public static Result success(T data) {
+ return new Result<>(200, "success", data);
+ }
+ public static Result success() {
+ return new Result<>(200, "success", null);
+ }
+ public static Result fail(String msg) {
+ return new Result<>(500, msg, null);
+ }
+ public static Result fail(int code, String msg) {
+ return new Result<>(code, msg, null);
+ }
+}
diff --git a/珞珈岛-项目相关文件/luojia-island/common/src/main/java/com/luojia_channel/common/domain/UserDTO.java b/珞珈岛-项目相关文件/luojia-island/common/src/main/java/com/luojia_channel/common/domain/UserDTO.java
new file mode 100644
index 0000000..d50c889
--- /dev/null
+++ b/珞珈岛-项目相关文件/luojia-island/common/src/main/java/com/luojia_channel/common/domain/UserDTO.java
@@ -0,0 +1,18 @@
+package com.luojia_channel.common.domain;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+@Builder
+public class UserDTO {
+ private Long userId;
+ private String username;
+ private String email;
+ private String studentId;
+ private String token;
+}
diff --git a/珞珈岛-项目相关文件/luojia-island/common/src/main/java/com/luojia_channel/common/exception/BaseException.java b/珞珈岛-项目相关文件/luojia-island/common/src/main/java/com/luojia_channel/common/exception/BaseException.java
new file mode 100644
index 0000000..76fc30a
--- /dev/null
+++ b/珞珈岛-项目相关文件/luojia-island/common/src/main/java/com/luojia_channel/common/exception/BaseException.java
@@ -0,0 +1,15 @@
+package com.luojia_channel.common.exception;
+
+import lombok.Getter;
+
+@Getter
+public class BaseException extends RuntimeException {
+ private final int errorCode;
+ private final String errorMessage;
+
+ public BaseException(int errorCode, String errorMessage) {
+ super(errorMessage);
+ this.errorCode = errorCode;
+ this.errorMessage = errorMessage;
+ }
+}
\ No newline at end of file
diff --git a/珞珈岛-项目相关文件/luojia-island/common/src/main/java/com/luojia_channel/common/exception/UserException.java b/珞珈岛-项目相关文件/luojia-island/common/src/main/java/com/luojia_channel/common/exception/UserException.java
new file mode 100644
index 0000000..b243e3e
--- /dev/null
+++ b/珞珈岛-项目相关文件/luojia-island/common/src/main/java/com/luojia_channel/common/exception/UserException.java
@@ -0,0 +1,7 @@
+package com.luojia_channel.common.exception;
+
+public class UserException extends BaseException{
+ public UserException(String msg){
+ super(500, msg);
+ }
+}
diff --git a/珞珈岛-项目相关文件/luojia-island/common/src/main/java/com/luojia_channel/common/utils/JWTUtil.java b/珞珈岛-项目相关文件/luojia-island/common/src/main/java/com/luojia_channel/common/utils/JWTUtil.java
new file mode 100644
index 0000000..a29793f
--- /dev/null
+++ b/珞珈岛-项目相关文件/luojia-island/common/src/main/java/com/luojia_channel/common/utils/JWTUtil.java
@@ -0,0 +1,64 @@
+package com.luojia_channel.common.utils;
+
+import com.alibaba.fastjson.JSON;
+import com.luojia_channel.common.domain.UserDTO;
+import io.jsonwebtoken.Claims;
+import io.jsonwebtoken.ExpiredJwtException;
+import io.jsonwebtoken.Jwts;
+import io.jsonwebtoken.SignatureAlgorithm;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.util.StringUtils;
+
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+
+@Slf4j
+public final class JWTUtil {
+
+ private static final long EXPIRATION = 86400L;
+ private static final String USER_ID_KEY = "userId";
+ private static final String USER_NAME_KEY = "username";
+ public static final String TOKEN_PREFIX = "Bearer ";
+ public static final String ISS = "luojiachannel";
+ //后缀加了点字符保证密钥>=512位,其他无更改
+ public static final String SECRET = "SecretKeyCreatedByForely0234523935489354315795647652568575435297576extrastringluojiachannel";
+
+ /**
+ * 生成用户 Token
+ */
+ public static String generateAccessToken(UserDTO userInfo) {
+ Map customerUserMap = new HashMap<>();
+ customerUserMap.put(USER_ID_KEY, userInfo.getUserId());
+ customerUserMap.put(USER_NAME_KEY, userInfo.getUsername());
+ String jwtToken = Jwts.builder()
+ .signWith(SignatureAlgorithm.HS512, SECRET)
+ .setIssuedAt(new Date())
+ .setIssuer(ISS)
+ .setSubject(JSON.toJSONString(customerUserMap))
+ .setExpiration(new Date(System.currentTimeMillis() + EXPIRATION * 1000))
+ .compact();
+ return TOKEN_PREFIX + jwtToken;
+ }
+
+ /**
+ * 解析用户 Token
+ */
+ public static UserDTO parseJwtToken(String jwtToken) {
+ if (StringUtils.hasText(jwtToken)) {
+ String actualJwtToken = jwtToken.replace(TOKEN_PREFIX, "");
+ try {
+ Claims claims = Jwts.parser().setSigningKey(SECRET).parseClaimsJws(actualJwtToken).getBody();
+ Date expiration = claims.getExpiration();
+ if (expiration.after(new Date())) {
+ String subject = claims.getSubject();
+ return JSON.parseObject(subject, UserDTO.class);
+ }
+ } catch (ExpiredJwtException ignored) {
+ } catch (Exception ex) {
+ log.error("JWT Token解析失败,请检查", ex);
+ }
+ }
+ return null;
+ }
+}
\ No newline at end of file
diff --git a/珞珈岛-项目相关文件/luojia-island/common/src/main/java/com/luojia_channel/common/utils/RedisUtil.java b/珞珈岛-项目相关文件/luojia-island/common/src/main/java/com/luojia_channel/common/utils/RedisUtil.java
new file mode 100644
index 0000000..70b00f4
--- /dev/null
+++ b/珞珈岛-项目相关文件/luojia-island/common/src/main/java/com/luojia_channel/common/utils/RedisUtil.java
@@ -0,0 +1,159 @@
+package com.luojia_channel.common.utils;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.RequiredArgsConstructor;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.data.redis.core.ZSetOperations;
+import org.springframework.stereotype.Component;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
+
+@Component
+@RequiredArgsConstructor
+public class RedisUtil {
+
+ private final RedisTemplate redisTemplate;
+ private static final Long DEFAULT_TIMEOUT = 30000L;
+ private static final TimeUnit DEFAULT_TIME_UNIT = TimeUnit.MILLISECONDS;
+
+ /**
+ * redis基础操作
+ */
+
+ public T get(String key, Class type) {
+ Object value = redisTemplate.opsForValue().get(key);
+ return value != null ? type.cast(value) : null;
+ }
+
+ public void set(String key, Object value) {
+ redisTemplate.opsForValue().set(key, value, DEFAULT_TIMEOUT, DEFAULT_TIME_UNIT);
+ }
+
+ public void set(String key, Object value, long timeout, TimeUnit unit) {
+ redisTemplate.opsForValue().set(key, value, timeout, unit);
+ }
+
+ public void expire(String key, long time, TimeUnit timeUnit) {
+ redisTemplate.expire(key, time, timeUnit);
+ }
+
+ public void delete(String key) {
+ redisTemplate.delete(key);
+ }
+
+ /**
+ * set操作
+ */
+ private List convertSetToList(Set