{t0G6Iy~_G5LLA|HaGlXXu~3AO3{ie$(Xsej5GS7vg6wKilm7UWg8oo-{}c7MyjnjiCV!%K
f3jRaXKh+d@DeyO$0tAHp_T~7dgYygh_S^plp0mHD
literal 0
HcmV?d00001
diff --git a/珞珈岛-项目相关文件/luojia-island/common/target/maven-archiver/pom.properties b/珞珈岛-项目相关文件/luojia-island/common/target/maven-archiver/pom.properties
new file mode 100644
index 0000000..189506b
--- /dev/null
+++ b/珞珈岛-项目相关文件/luojia-island/common/target/maven-archiver/pom.properties
@@ -0,0 +1,3 @@
+artifactId=common
+groupId=com.luojia
+version=1.0.0
diff --git a/珞珈岛-项目相关文件/luojia-island/common/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst b/珞珈岛-项目相关文件/luojia-island/common/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst
new file mode 100644
index 0000000..017e0fe
--- /dev/null
+++ b/珞珈岛-项目相关文件/luojia-island/common/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst
@@ -0,0 +1,11 @@
+com\luojia\luojia_channel\advice\GlobalExceptionHandler.class
+com\luojia\luojia_channel\domain\UserDTO.class
+com\luojia\luojia_channel\utils\UserContext.class
+com\luojia\luojia_channel\utils\JWTUtil.class
+com\luojia\luojia_channel\config\RedisConfig.class
+com\luojia\luojia_channel\utils\RedisUtil$ZSetItem.class
+com\luojia\luojia_channel\domain\UserDTO$UserDTOBuilder.class
+com\luojia\luojia_channel\exception\BaseException.class
+com\luojia\luojia_channel\utils\RedisUtil.class
+com\luojia\luojia_channel\domain\Result.class
+com\luojia\luojia_channel\exception\UserException.class
diff --git a/珞珈岛-项目相关文件/luojia-island/common/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst b/珞珈岛-项目相关文件/luojia-island/common/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst
new file mode 100644
index 0000000..4ae004b
--- /dev/null
+++ b/珞珈岛-项目相关文件/luojia-island/common/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst
@@ -0,0 +1,9 @@
+D:\javaCode\luojia_channel\common\src\main\java\com\luojia\luojia_channel\advice\GlobalExceptionHandler.java
+D:\javaCode\luojia_channel\common\src\main\java\com\luojia\luojia_channel\config\RedisConfig.java
+D:\javaCode\luojia_channel\common\src\main\java\com\luojia\luojia_channel\domain\Result.java
+D:\javaCode\luojia_channel\common\src\main\java\com\luojia\luojia_channel\domain\UserDTO.java
+D:\javaCode\luojia_channel\common\src\main\java\com\luojia\luojia_channel\exception\BaseException.java
+D:\javaCode\luojia_channel\common\src\main\java\com\luojia\luojia_channel\exception\UserException.java
+D:\javaCode\luojia_channel\common\src\main\java\com\luojia\luojia_channel\utils\JWTUtil.java
+D:\javaCode\luojia_channel\common\src\main\java\com\luojia\luojia_channel\utils\RedisUtil.java
+D:\javaCode\luojia_channel\common\src\main\java\com\luojia\luojia_channel\utils\UserContext.java
diff --git a/珞珈岛-项目相关文件/luojia-island/pom.xml b/珞珈岛-项目相关文件/luojia-island/pom.xml
new file mode 100644
index 0000000..19da1b9
--- /dev/null
+++ b/珞珈岛-项目相关文件/luojia-island/pom.xml
@@ -0,0 +1,91 @@
+
+
+ 4.0.0
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 3.4.3
+
+
+
+ com.luojia
+ luojia_channel
+ pom
+ 1.0.0
+
+ common
+ service
+
+
+
+ 17
+ 2024.0.0
+ 3.5.7
+ 3.29.0
+ 8.0.33
+
+
+
+
+
+
+ org.springframework.cloud
+ spring-cloud-dependencies
+ ${spring-cloud.version}
+ pom
+ import
+
+
+
+
+
+ org.redisson
+ redisson-spring-boot-starter
+ ${redisson.version}
+
+
+
+
+ mysql
+ mysql-connector-java
+ ${mysql.version}
+
+
+
+
+
+
+
+ org.projectlombok
+ lombok
+ provided
+
+
+
+
+ com.alibaba
+ fastjson
+ 1.2.83
+
+
+
+
+ cn.hutool
+ hutool-all
+ 5.8.24
+
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
diff --git a/珞珈岛-项目相关文件/luojia-island/service/pom.xml b/珞珈岛-项目相关文件/luojia-island/service/pom.xml
new file mode 100644
index 0000000..1192981
--- /dev/null
+++ b/珞珈岛-项目相关文件/luojia-island/service/pom.xml
@@ -0,0 +1,85 @@
+
+
+ 4.0.0
+
+ com.luojia
+ luojia_channel
+ 1.0.0
+
+
+ service
+
+
+
+
+ com.luojia
+ common
+ 1.0.0
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+
+
+ com.baomidou
+ mybatis-plus-spring-boot3-starter
+ 3.5.7
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-data-redis
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-amqp
+
+
+
+
+ mysql
+ mysql-connector-java
+
+
+
+ org.springframework.boot
+ spring-boot-starter-security
+
+
+
+
+ org.springframework.cloud
+ spring-cloud-starter-bootstrap
+
+
+ org.springframework.cloud
+ spring-cloud-starter-loadbalancer
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
\ No newline at end of file
diff --git a/珞珈岛-项目相关文件/luojia-island/service/src/main/java/com/luojia_channel/LuojiaChannelApplication.java b/珞珈岛-项目相关文件/luojia-island/service/src/main/java/com/luojia_channel/LuojiaChannelApplication.java
new file mode 100644
index 0000000..f5b5747
--- /dev/null
+++ b/珞珈岛-项目相关文件/luojia-island/service/src/main/java/com/luojia_channel/LuojiaChannelApplication.java
@@ -0,0 +1,15 @@
+package com.luojia_channel;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.context.annotation.ComponentScan;
+
+@SpringBootApplication
+@ComponentScan(basePackages = {"com.luojia_channel"})
+public class LuojiaChannelApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(LuojiaChannelApplication.class, args);
+ }
+
+}
diff --git a/珞珈岛-项目相关文件/luojia-island/service/src/main/java/com/luojia_channel/modules/user/Config/SecurityConfig.java b/珞珈岛-项目相关文件/luojia-island/service/src/main/java/com/luojia_channel/modules/user/Config/SecurityConfig.java
new file mode 100644
index 0000000..726d3cf
--- /dev/null
+++ b/珞珈岛-项目相关文件/luojia-island/service/src/main/java/com/luojia_channel/modules/user/Config/SecurityConfig.java
@@ -0,0 +1,30 @@
+package com.luojia_channel.modules.user.Config;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
+import org.springframework.security.crypto.password.PasswordEncoder;
+import org.springframework.security.web.SecurityFilterChain;
+
+@Configuration
+public class SecurityConfig {
+ @Bean
+ public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
+ http
+ .csrf(csrf -> csrf.disable()) //禁用CSRF保护
+ .cors(cors -> cors.disable()) //禁用CORS测试,似乎需要,没有详细测试过
+ .authorizeHttpRequests(auth -> auth
+ .requestMatchers("/user/login",
+ "/user/register",
+ "/user/hello").permitAll() //允许所有用户访问登录和注册接口
+ .anyRequest().authenticated() //其他请求需要认证
+ );
+ return http.build();
+ }
+
+ @Bean
+ public PasswordEncoder passwordEncoder() {
+ return new BCryptPasswordEncoder();
+ }
+}
diff --git a/珞珈岛-项目相关文件/luojia-island/service/src/main/java/com/luojia_channel/modules/user/constant/UserConstant.java b/珞珈岛-项目相关文件/luojia-island/service/src/main/java/com/luojia_channel/modules/user/constant/UserConstant.java
new file mode 100644
index 0000000..fdcbac7
--- /dev/null
+++ b/珞珈岛-项目相关文件/luojia-island/service/src/main/java/com/luojia_channel/modules/user/constant/UserConstant.java
@@ -0,0 +1,12 @@
+package com.luojia_channel.modules.user.constant;
+
+public class UserConstant {
+ // 匿名用户前缀
+ public static final String ANONYMOUS_USER_PREFIX = "luojia_";
+ // 匿名用户key前缀
+ public static final String ANONYMOUS_KEY_PREFIX = "anon:user:";
+ // 过期时间
+ public static final long EXPIRE_TIME_MINUTES = 30L;
+ // 过期时间
+ public static final long EXPIRE_TIME = 7L;
+}
diff --git a/珞珈岛-项目相关文件/luojia-island/service/src/main/java/com/luojia_channel/modules/user/controller/UserInfoController.java b/珞珈岛-项目相关文件/luojia-island/service/src/main/java/com/luojia_channel/modules/user/controller/UserInfoController.java
new file mode 100644
index 0000000..21fd36a
--- /dev/null
+++ b/珞珈岛-项目相关文件/luojia-island/service/src/main/java/com/luojia_channel/modules/user/controller/UserInfoController.java
@@ -0,0 +1,4 @@
+package com.luojia_channel.modules.user.controller;
+
+public class UserInfoController {
+}
diff --git a/珞珈岛-项目相关文件/luojia-island/service/src/main/java/com/luojia_channel/modules/user/controller/UserLoginController.java b/珞珈岛-项目相关文件/luojia-island/service/src/main/java/com/luojia_channel/modules/user/controller/UserLoginController.java
new file mode 100644
index 0000000..ce7d605
--- /dev/null
+++ b/珞珈岛-项目相关文件/luojia-island/service/src/main/java/com/luojia_channel/modules/user/controller/UserLoginController.java
@@ -0,0 +1,37 @@
+package com.luojia_channel.modules.user.controller;
+
+import com.luojia_channel.common.domain.Result;
+import com.luojia_channel.common.domain.UserDTO;
+import com.luojia_channel.modules.user.dto.UserLoginDTO;
+import com.luojia_channel.modules.user.dto.UserRegisterDTO;
+import com.luojia_channel.modules.user.service.UserLoginService;
+import lombok.RequiredArgsConstructor;
+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;
+
+@RestController
+@RequestMapping("/user")
+@RequiredArgsConstructor
+public class UserLoginController {
+ private final UserLoginService userLoginService;
+ //登录
+ @PostMapping("/login")
+ public Result login(@RequestBody UserLoginDTO userLoginDTO){
+ return Result.success(userLoginService.login(userLoginDTO));
+ }
+
+ //注册
+ @PostMapping("/register")
+ public Result register(@RequestBody UserRegisterDTO userRegisterDTO){
+ return Result.success(userLoginService.register(userRegisterDTO));
+ }
+
+ //测试接口
+ @PostMapping("/hello")
+ public Result hello() {
+ return Result.success("hello");
+ }
+
+}
diff --git a/珞珈岛-项目相关文件/luojia-island/service/src/main/java/com/luojia_channel/modules/user/dto/UserLoginDTO.java b/珞珈岛-项目相关文件/luojia-island/service/src/main/java/com/luojia_channel/modules/user/dto/UserLoginDTO.java
new file mode 100644
index 0000000..7021946
--- /dev/null
+++ b/珞珈岛-项目相关文件/luojia-island/service/src/main/java/com/luojia_channel/modules/user/dto/UserLoginDTO.java
@@ -0,0 +1,10 @@
+package com.luojia_channel.modules.user.dto;
+
+import lombok.Data;
+
+@Data
+public class UserLoginDTO {
+ // 用户标志,支持学号,手机号,邮箱
+ private String userFlag;
+ private String password;
+}
diff --git a/珞珈岛-项目相关文件/luojia-island/service/src/main/java/com/luojia_channel/modules/user/dto/UserRegisterDTO.java b/珞珈岛-项目相关文件/luojia-island/service/src/main/java/com/luojia_channel/modules/user/dto/UserRegisterDTO.java
new file mode 100644
index 0000000..e2474de
--- /dev/null
+++ b/珞珈岛-项目相关文件/luojia-island/service/src/main/java/com/luojia_channel/modules/user/dto/UserRegisterDTO.java
@@ -0,0 +1,10 @@
+package com.luojia_channel.modules.user.dto;
+
+import lombok.Data;
+
+@Data
+public class UserRegisterDTO {
+ private String username;
+ private String password;
+ private String email;
+}
diff --git a/珞珈岛-项目相关文件/luojia-island/service/src/main/java/com/luojia_channel/modules/user/entity/User.java b/珞珈岛-项目相关文件/luojia-island/service/src/main/java/com/luojia_channel/modules/user/entity/User.java
new file mode 100644
index 0000000..76fa2b0
--- /dev/null
+++ b/珞珈岛-项目相关文件/luojia-island/service/src/main/java/com/luojia_channel/modules/user/entity/User.java
@@ -0,0 +1,79 @@
+package com.luojia_channel.modules.user.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+import org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchConnectionDetails;
+
+import java.io.Serializable;
+import java.time.LocalDateTime;
+
+@Data
+@TableName("user")
+public class User implements Serializable {
+
+ @TableId(value = "id", type = IdType.AUTO)
+ private Long id;
+ /**
+ * 用户名
+ */
+ private String username;
+
+ /**
+ * 实名
+ */
+ private String realName;
+
+ /**
+ * 密码
+ */
+ private String password;
+
+ /**
+ * 注册手机号
+ */
+ private String phone;
+
+ /**
+ * 邮箱
+ */
+ private String email;
+
+ /**
+ * 学号
+ */
+ private String studentId;
+
+ /**
+ * 性别(0未知,1男,2女)
+ */
+ private Integer gender;
+
+ /**
+ * 创建时间
+ */
+ private LocalDateTime createTime;
+
+ private LocalDateTime updateTime;
+
+ /**
+ * 使用状态(1正常 2冻结)
+ */
+ private Integer status;
+
+ /**
+ * 身份(1普通用户 2管理员 3超级管理员)
+ */
+ private Integer role;
+
+ /**
+ * 用户积分
+ */
+ private Integer integral;
+
+ /**
+ * 所属学院
+ */
+ private String college;
+}
diff --git a/珞珈岛-项目相关文件/luojia-island/service/src/main/java/com/luojia_channel/modules/user/mapper/UserMapper.java b/珞珈岛-项目相关文件/luojia-island/service/src/main/java/com/luojia_channel/modules/user/mapper/UserMapper.java
new file mode 100644
index 0000000..fdd724e
--- /dev/null
+++ b/珞珈岛-项目相关文件/luojia-island/service/src/main/java/com/luojia_channel/modules/user/mapper/UserMapper.java
@@ -0,0 +1,10 @@
+package com.luojia_channel.modules.user.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.luojia_channel.modules.user.entity.User;
+import org.apache.ibatis.annotations.Mapper;
+
+@Mapper
+public interface UserMapper extends BaseMapper {
+
+}
diff --git a/珞珈岛-项目相关文件/luojia-island/service/src/main/java/com/luojia_channel/modules/user/service/UserInfoService.java b/珞珈岛-项目相关文件/luojia-island/service/src/main/java/com/luojia_channel/modules/user/service/UserInfoService.java
new file mode 100644
index 0000000..6982d38
--- /dev/null
+++ b/珞珈岛-项目相关文件/luojia-island/service/src/main/java/com/luojia_channel/modules/user/service/UserInfoService.java
@@ -0,0 +1,7 @@
+package com.luojia_channel.modules.user.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.luojia_channel.modules.user.entity.User;
+
+public interface UserInfoService extends IService {
+}
diff --git a/珞珈岛-项目相关文件/luojia-island/service/src/main/java/com/luojia_channel/modules/user/service/UserLoginService.java b/珞珈岛-项目相关文件/luojia-island/service/src/main/java/com/luojia_channel/modules/user/service/UserLoginService.java
new file mode 100644
index 0000000..9182f46
--- /dev/null
+++ b/珞珈岛-项目相关文件/luojia-island/service/src/main/java/com/luojia_channel/modules/user/service/UserLoginService.java
@@ -0,0 +1,20 @@
+package com.luojia_channel.modules.user.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.luojia_channel.common.domain.UserDTO;
+import com.luojia_channel.modules.user.dto.UserLoginDTO;
+import com.luojia_channel.modules.user.dto.UserRegisterDTO;
+import com.luojia_channel.modules.user.entity.User;
+
+public interface UserLoginService extends IService {
+
+ //登录
+ UserDTO login(UserLoginDTO userLoginDTO);
+
+ UserDTO checkLogin(String token);
+
+ void logout(String token);
+
+ //注册
+ UserDTO register(UserRegisterDTO userRegisterDTO);
+}
diff --git a/珞珈岛-项目相关文件/luojia-island/service/src/main/java/com/luojia_channel/modules/user/service/impl/UserInfoServiceImpl.java b/珞珈岛-项目相关文件/luojia-island/service/src/main/java/com/luojia_channel/modules/user/service/impl/UserInfoServiceImpl.java
new file mode 100644
index 0000000..d72f795
--- /dev/null
+++ b/珞珈岛-项目相关文件/luojia-island/service/src/main/java/com/luojia_channel/modules/user/service/impl/UserInfoServiceImpl.java
@@ -0,0 +1,13 @@
+package com.luojia_channel.modules.user.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.luojia_channel.modules.user.entity.User;
+import com.luojia_channel.modules.user.mapper.UserMapper;
+import com.luojia_channel.modules.user.service.UserInfoService;
+
+import org.springframework.stereotype.Service;
+
+@Service
+public class UserInfoServiceImpl extends ServiceImpl implements UserInfoService {
+
+}
diff --git a/珞珈岛-项目相关文件/luojia-island/service/src/main/java/com/luojia_channel/modules/user/service/impl/UserLoginServiceImpl.java b/珞珈岛-项目相关文件/luojia-island/service/src/main/java/com/luojia_channel/modules/user/service/impl/UserLoginServiceImpl.java
new file mode 100644
index 0000000..8faabba
--- /dev/null
+++ b/珞珈岛-项目相关文件/luojia-island/service/src/main/java/com/luojia_channel/modules/user/service/impl/UserLoginServiceImpl.java
@@ -0,0 +1,209 @@
+package com.luojia_channel.modules.user.service.impl;
+
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.luojia_channel.common.domain.UserDTO;
+import com.luojia_channel.common.exception.UserException;
+import com.luojia_channel.modules.user.dto.UserLoginDTO;
+import com.luojia_channel.modules.user.dto.UserRegisterDTO;
+import com.luojia_channel.modules.user.entity.User;
+import com.luojia_channel.modules.user.mapper.UserMapper;
+import com.luojia_channel.modules.user.service.UserLoginService;
+import com.luojia_channel.common.utils.JWTUtil;
+import com.luojia_channel.common.utils.RedisUtil;
+import lombok.RequiredArgsConstructor;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.crypto.password.PasswordEncoder;
+import org.springframework.stereotype.Service;
+
+import java.util.concurrent.TimeUnit;
+
+import static com.luojia_channel.modules.user.constant.UserConstant.EXPIRE_TIME;
+
+@Service
+@RequiredArgsConstructor
+public class UserLoginServiceImpl extends ServiceImpl implements UserLoginService {
+
+ private final UserMapper userMapper;
+ private PasswordEncoder passwordEncoder;
+ private final RedisUtil redisUtil;
+
+ @Autowired
+ public void setPasswordEncoder(PasswordEncoder passwordEncoder) {
+ this.passwordEncoder = passwordEncoder;
+ }
+
+ /**
+ * 根据用户标志获得用户学号,用于登录
+ * @param userFlag
+ * @return
+ */
+ private User getUserByFlag(String userFlag){
+ User user;
+ boolean mailFlag = false;
+ for(char c : userFlag.toCharArray()){
+ if(c == '@'){
+ mailFlag = true;
+ break;
+ }
+ }
+ // 邮箱登录
+ if(mailFlag){
+ LambdaQueryWrapper wrapper = Wrappers.lambdaQuery(User.class)
+ .eq(User::getEmail, userFlag);
+ user = userMapper.selectOne(wrapper);
+ if(user == null){
+ throw new UserException("用户邮箱不存在");
+ }
+ return user;
+ }
+ // 手机号登录
+ if(userFlag.length() == 11){
+ LambdaQueryWrapper wrapper = Wrappers.lambdaQuery(User.class)
+ .eq(User::getPhone, userFlag);
+ user = userMapper.selectOne(wrapper);
+ if(user == null){
+ throw new UserException("用户手机号不存在");
+ }
+ return user;
+ }
+ // 剩下的就是学号登录了
+ LambdaQueryWrapper wrapper = Wrappers.lambdaQuery(User.class)
+ .eq(User::getStudentId, userFlag);
+ user = userMapper.selectOne(wrapper);
+ if(user == null){
+ throw new UserException("用户学号不存在");
+ }
+ return user;
+ }
+
+ /**
+ * 用户登录,支持学号,手机,邮箱登录
+ * @param userLoginDTO
+ * @return
+ */
+ @Override
+ public UserDTO login(UserLoginDTO userLoginDTO) {
+ String userFlag = userLoginDTO.getUserFlag();
+ String password = userLoginDTO.getPassword();
+ //验证密码
+ User user = getUserByFlag(userFlag);
+ if(!passwordEncoder.matches(password, user.getPassword())) {
+ throw new UserException("密码错误");
+ }
+ UserDTO userDTO = UserDTO.builder()
+ .userId(user.getId())
+ .username(user.getUsername())
+ .studentId(user.getStudentId())
+ .build();
+ String jwtToken = JWTUtil.generateAccessToken(userDTO);
+ userDTO.setToken(jwtToken);
+ // 存储用户至redis
+ // 当jwt过期时,若redis仍存在,则刷新jwt
+ redisUtil.set(jwtToken, userDTO, EXPIRE_TIME, TimeUnit.DAYS);
+ return userDTO;
+ }
+
+ /**
+ * 检查登录,包括刷新jwt
+ * @param token
+ * @return
+ */
+ @Override
+ public UserDTO checkLogin(String token) {
+ // 解析JWT,若有效则刷新redis过期时间
+ UserDTO user = JWTUtil.parseJwtToken(token);
+ if (user != null) {
+ redisUtil.expire(token, EXPIRE_TIME, TimeUnit.DAYS);
+ return user;
+ }
+ // 若JWT过期,检查Redis中是否存在该token对应的用户信息
+ UserDTO cachedUser = redisUtil.get(token, UserDTO.class);
+ if (cachedUser != null) {
+ String newToken = JWTUtil.generateAccessToken(cachedUser);
+ redisUtil.delete(token);
+ redisUtil.set(newToken, cachedUser, EXPIRE_TIME, TimeUnit.DAYS);
+ return cachedUser;
+ }
+ throw new UserException("登录失效");
+ }
+
+ @Override
+ public void logout(String token){
+ if (StrUtil.isNotBlank(token)) {
+ redisUtil.delete(token);
+ }
+ }
+
+ /**
+ * 用户注册,支持用户名、邮箱注册
+ * @param userRegisterDTO
+ * @return
+ */
+ @Override
+ public UserDTO register(UserRegisterDTO userRegisterDTO) {
+ //检查注册信息是否完整
+ if (StrUtil.hasBlank(userRegisterDTO.getUsername(),
+ userRegisterDTO.getPassword(),
+ userRegisterDTO.getEmail())) {
+ throw new UserException("注册信息不能为空");
+ }
+
+ //检查用户名、邮箱是否已存在
+ LambdaQueryWrapper usernameWrapper = Wrappers.lambdaQuery(User.class)
+ .eq(User::getUsername, userRegisterDTO.getUsername());
+ if (userMapper.selectOne(usernameWrapper) != null) {
+ throw new UserException("用户名已存在");
+ }
+
+ LambdaQueryWrapper emailWrapper = Wrappers.lambdaQuery(User.class)
+ .eq(User::getEmail, userRegisterDTO.getEmail());
+ if (userMapper.selectOne(emailWrapper) != null) {
+ throw new UserException("邮箱已存在");
+ }
+
+ //TODO 邮箱格式校验,前端完成
+ //if (!userRegisterDTO.getEmail().matches("^\\w+@[a-zA-Z_]+?\\.[a-zA-Z]{2,3}$")) {
+ //throw new UserException("邮箱格式不正确");
+ //}
+
+ //检查密码长度,不知道是不是前端做的
+ if (userRegisterDTO.getPassword().length() < 6) {
+ throw new UserException("密码长度不能小于6位");
+ }
+
+ //TODO 检查密码是否一致,前端完成
+ //if (!userRegisterDTO.getPassword().equals(userRegisterDTO.getConfirmPassword())) {
+ //throw new UserException("两次密码不一致");
+ //}
+
+ //加密密码
+ String encodedPassword = passwordEncoder.encode(userRegisterDTO.getPassword());
+
+ //保存用户信息至mysql
+ User newuser = new User();
+ newuser.setUsername(userRegisterDTO.getUsername());
+ newuser.setPassword(encodedPassword);
+ newuser.setEmail(userRegisterDTO.getEmail());
+
+ if(!save(newuser)){
+ throw new UserException("注册失败");
+ }
+
+ //生成JWT
+ UserDTO userDTO = UserDTO.builder()
+ .userId(newuser.getId())
+ .username(newuser.getUsername())
+ .email(newuser.getEmail())
+ .build();
+ //生成token
+ String jwtToken = JWTUtil.generateAccessToken(userDTO);
+ userDTO.setToken(jwtToken);
+ //存储用户信息至redis
+ redisUtil.set(jwtToken, userDTO, EXPIRE_TIME, TimeUnit.DAYS);
+
+ return userDTO;
+ }
+}
diff --git a/珞珈岛-项目相关文件/luojia-island/service/src/main/java/com/luojia_channel/modules/user/utils/AnonymousUserUtil.java b/珞珈岛-项目相关文件/luojia-island/service/src/main/java/com/luojia_channel/modules/user/utils/AnonymousUserUtil.java
new file mode 100644
index 0000000..ca1f438
--- /dev/null
+++ b/珞珈岛-项目相关文件/luojia-island/service/src/main/java/com/luojia_channel/modules/user/utils/AnonymousUserUtil.java
@@ -0,0 +1,62 @@
+package com.luojia_channel.modules.user.utils;
+
+import cn.hutool.core.lang.UUID;
+import com.luojia_channel.common.domain.UserDTO;
+import com.luojia_channel.common.exception.UserException;
+import com.luojia_channel.common.utils.RedisUtil;
+import lombok.RequiredArgsConstructor;
+import org.redisson.api.RLock;
+import org.redisson.api.RedissonClient;
+import org.springframework.stereotype.Component;
+
+import java.util.concurrent.TimeUnit;
+
+import static com.luojia_channel.modules.user.constant.UserConstant.*;
+
+/**
+ * 这是生成匿名用户的工具类,用于前端展示,并支持后端校验
+ */
+@Component
+@RequiredArgsConstructor
+public class AnonymousUserUtil {
+ private final RedisUtil redisUtil;
+ private final RedissonClient redissonClient;
+
+ /**
+ * 生成匿名用户id
+ * @param userDTO
+ * @return
+ */
+ public String generateAnonymousId(UserDTO userDTO){
+ String anonymousId = ANONYMOUS_USER_PREFIX + UUID.randomUUID().toString().replace("-", "");
+ String cacheKey = ANONYMOUS_KEY_PREFIX + anonymousId;
+ String lockKey = ANONYMOUS_KEY_PREFIX + userDTO.getUserId();
+ RLock lock = redissonClient.getLock(lockKey);
+ boolean tryLock = lock.tryLock();
+ if(!tryLock){
+ throw new UserException("匿名频繁,请稍后重试");
+ }
+ try {
+ redisUtil.set(cacheKey, userDTO, EXPIRE_TIME_MINUTES, TimeUnit.MINUTES);
+ }finally {
+ lock.unlock();
+ }
+ return anonymousId;
+ }
+
+ /**
+ * 解析匿名用户
+ * @param anonymousId
+ * @return
+ */
+ public UserDTO getRealUser(String anonymousId){
+ String cacheKey = ANONYMOUS_KEY_PREFIX + anonymousId;
+ UserDTO user = redisUtil.get(cacheKey, UserDTO.class);
+ if(user == null){
+ throw new UserException("匿名用户不存在或已过期");
+ }
+ return user;
+ }
+
+
+}
diff --git a/珞珈岛-项目相关文件/luojia-island/service/src/main/resources/application-dev.yaml b/珞珈岛-项目相关文件/luojia-island/service/src/main/resources/application-dev.yaml
new file mode 100644
index 0000000..09c5e58
--- /dev/null
+++ b/珞珈岛-项目相关文件/luojia-island/service/src/main/resources/application-dev.yaml
@@ -0,0 +1 @@
+lj:
diff --git a/珞珈岛-项目相关文件/luojia-island/service/src/main/resources/application-local.yaml b/珞珈岛-项目相关文件/luojia-island/service/src/main/resources/application-local.yaml
new file mode 100644
index 0000000..28c511b
--- /dev/null
+++ b/珞珈岛-项目相关文件/luojia-island/service/src/main/resources/application-local.yaml
@@ -0,0 +1,29 @@
+# 本地开发环境
+lj:
+ db:
+ host: 192.168.59.129
+ password: Forely123!
+ redis:
+ host: 192.168.59.129
+ port: 6379
+ password: Forely123!
+ rabbitmq:
+ host: 192.168.59.129
+ port: 5672
+ username: admin
+ password: Forely123!
+
+# 本地开发环境,cf的配置
+#lj:
+# db:
+# host: localhost
+# password: 123456
+# redis:
+# host: localhost
+# port: 6379
+# password: 123456
+# rabbitmq:
+# host: localhost
+# port: 15672
+# username: root
+# password: 123456
diff --git a/珞珈岛-项目相关文件/luojia-island/service/src/main/resources/application.yaml b/珞珈岛-项目相关文件/luojia-island/service/src/main/resources/application.yaml
new file mode 100644
index 0000000..9b4645d
--- /dev/null
+++ b/珞珈岛-项目相关文件/luojia-island/service/src/main/resources/application.yaml
@@ -0,0 +1,51 @@
+server:
+ port: 8081
+spring:
+ application:
+ name: service
+ profiles:
+ active: local
+ # 数据库
+ datasource:
+ url: jdbc:mysql://${lj.db.host}:3306/luojia_channel?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghai
+ driver-class-name: com.mysql.cj.jdbc.Driver
+ username: root
+ password: ${lj.db.password}
+ # redis配置
+ data:
+ redis:
+ host: ${lj.redis.host}
+ port: ${lj.redis.port}
+ password: ${lj.redis.password}
+ lettuce:
+ pool:
+ max-active: 10
+ max-idle: 10
+ min-idle: 1
+ time-between-eviction-runs: 10s
+ # rabbitmq配置
+ rabbitmq:
+ host: ${lj.rabbitmq.host}
+ port: ${lj.rabbitmq.port}
+ username: ${lj.rabbitmq.username}
+ password: ${lj.rabbitmq.password}
+ virtual-host: /
+ listener:
+ simple:
+ acknowledge-mode: manual
+ concurrency: 5
+ max-concurrency: 10
+ prefetch: 1
+
+mybatis-plus:
+ configuration:
+ default-enum-type-handler: com.baomidou.mybatisplus.core.handlers.MybatisEnumTypeHandler
+ global-config:
+ db-config:
+ update-strategy: not_null
+ id-type: auto
+ mapper-locations: classpath*:mapper/**/*.xml
+ type-aliases-package: com.luojia.luojia_channel.modules.*.entity
+
+
+
diff --git a/珞珈岛-项目相关文件/luojia-island/service/src/main/resources/db/luojia_channel.sql b/珞珈岛-项目相关文件/luojia-island/service/src/main/resources/db/luojia_channel.sql
new file mode 100644
index 0000000..94bfe34
--- /dev/null
+++ b/珞珈岛-项目相关文件/luojia-island/service/src/main/resources/db/luojia_channel.sql
@@ -0,0 +1,21 @@
+
+CREATE TABLE `user` (
+ `id` BIGINT PRIMARY KEY AUTO_INCREMENT COMMENT '主键ID',
+ `username` VARCHAR(50) NOT NULL COMMENT '用户名',
+ `real_name` VARCHAR(50) COMMENT '实名',
+ `password` VARCHAR(100) NOT NULL COMMENT '密码',
+ `phone` VARCHAR(20) UNIQUE COMMENT '注册手机号',
+ `email` VARCHAR(100) UNIQUE COMMENT '邮箱',
+ `student_id` VARCHAR(20) UNIQUE COMMENT '学号',
+ `gender` TINYINT DEFAULT 0 COMMENT '性别(0未知,1男,2女)',
+ `create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+ `update_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
+ `status` INT DEFAULT 1 COMMENT '状态(1正常 2冻结)',
+ `role` INT DEFAULT 1 COMMENT '身份(1普通用户 2管理员 3超级管理员)',
+ `integral` INT DEFAULT 0 COMMENT '用户积分',
+ `college` VARCHAR(100) COMMENT '所属学院',
+ INDEX `idx_username` (`username`),
+ UNIQUE INDEX `uk_phone` (`phone`),
+ UNIQUE INDEX `uk_email` (`email`),
+ UNIQUE INDEX `uk_student_id` (`student_id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户表';
\ No newline at end of file
diff --git a/珞珈岛-项目相关文件/luojia-island/service/src/main/resources/mapper/user/UserMapper.xml b/珞珈岛-项目相关文件/luojia-island/service/src/main/resources/mapper/user/UserMapper.xml
new file mode 100644
index 0000000..52fee41
--- /dev/null
+++ b/珞珈岛-项目相关文件/luojia-island/service/src/main/resources/mapper/user/UserMapper.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/珞珈岛-项目相关文件/luojia-island/service/src/test/java/com/luojia/luojia_channel/LuojiaChannelApplicationTests.java b/珞珈岛-项目相关文件/luojia-island/service/src/test/java/com/luojia/luojia_channel/LuojiaChannelApplicationTests.java
new file mode 100644
index 0000000..79abf19
--- /dev/null
+++ b/珞珈岛-项目相关文件/luojia-island/service/src/test/java/com/luojia/luojia_channel/LuojiaChannelApplicationTests.java
@@ -0,0 +1,14 @@
+package com.luojia.luojia_channel;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.boot.test.context.SpringBootTest;
+
+@SpringBootTest
+class LuojiaChannelApplicationTests {
+
+ @Test
+ void contextLoads() {
+
+ }
+
+}
diff --git a/珞珈岛-项目相关文件/luojia-island/service/target/classes/application-dev.yaml b/珞珈岛-项目相关文件/luojia-island/service/target/classes/application-dev.yaml
new file mode 100644
index 0000000..09c5e58
--- /dev/null
+++ b/珞珈岛-项目相关文件/luojia-island/service/target/classes/application-dev.yaml
@@ -0,0 +1 @@
+lj:
diff --git a/珞珈岛-项目相关文件/luojia-island/service/target/classes/application-local.yaml b/珞珈岛-项目相关文件/luojia-island/service/target/classes/application-local.yaml
new file mode 100644
index 0000000..28c511b
--- /dev/null
+++ b/珞珈岛-项目相关文件/luojia-island/service/target/classes/application-local.yaml
@@ -0,0 +1,29 @@
+# 本地开发环境
+lj:
+ db:
+ host: 192.168.59.129
+ password: Forely123!
+ redis:
+ host: 192.168.59.129
+ port: 6379
+ password: Forely123!
+ rabbitmq:
+ host: 192.168.59.129
+ port: 5672
+ username: admin
+ password: Forely123!
+
+# 本地开发环境,cf的配置
+#lj:
+# db:
+# host: localhost
+# password: 123456
+# redis:
+# host: localhost
+# port: 6379
+# password: 123456
+# rabbitmq:
+# host: localhost
+# port: 15672
+# username: root
+# password: 123456
diff --git a/珞珈岛-项目相关文件/luojia-island/service/target/classes/application.yaml b/珞珈岛-项目相关文件/luojia-island/service/target/classes/application.yaml
new file mode 100644
index 0000000..9b4645d
--- /dev/null
+++ b/珞珈岛-项目相关文件/luojia-island/service/target/classes/application.yaml
@@ -0,0 +1,51 @@
+server:
+ port: 8081
+spring:
+ application:
+ name: service
+ profiles:
+ active: local
+ # 数据库
+ datasource:
+ url: jdbc:mysql://${lj.db.host}:3306/luojia_channel?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghai
+ driver-class-name: com.mysql.cj.jdbc.Driver
+ username: root
+ password: ${lj.db.password}
+ # redis配置
+ data:
+ redis:
+ host: ${lj.redis.host}
+ port: ${lj.redis.port}
+ password: ${lj.redis.password}
+ lettuce:
+ pool:
+ max-active: 10
+ max-idle: 10
+ min-idle: 1
+ time-between-eviction-runs: 10s
+ # rabbitmq配置
+ rabbitmq:
+ host: ${lj.rabbitmq.host}
+ port: ${lj.rabbitmq.port}
+ username: ${lj.rabbitmq.username}
+ password: ${lj.rabbitmq.password}
+ virtual-host: /
+ listener:
+ simple:
+ acknowledge-mode: manual
+ concurrency: 5
+ max-concurrency: 10
+ prefetch: 1
+
+mybatis-plus:
+ configuration:
+ default-enum-type-handler: com.baomidou.mybatisplus.core.handlers.MybatisEnumTypeHandler
+ global-config:
+ db-config:
+ update-strategy: not_null
+ id-type: auto
+ mapper-locations: classpath*:mapper/**/*.xml
+ type-aliases-package: com.luojia.luojia_channel.modules.*.entity
+
+
+
diff --git a/珞珈岛-项目相关文件/luojia-island/service/target/classes/com/luojia_channel/LuojiaChannelApplication.class b/珞珈岛-项目相关文件/luojia-island/service/target/classes/com/luojia_channel/LuojiaChannelApplication.class
new file mode 100644
index 0000000000000000000000000000000000000000..756bc6cb1182cae99eb199343d0485b144e81a0b
GIT binary patch
literal 869
zcmb7DO>fgc5Ph2_bs7vUE))usk6W6m^{tmcC5XhyKt)hE^nljet+T1U8?D#C-{J(~
zzz^U@A!gm61j!t*h-&YSUj;yP|H
z42;d