diff --git a/珞珈岛-项目相关文件/luojia-island/.idea/misc.xml b/珞珈岛-项目相关文件/luojia-island/.idea/misc.xml index 82dbec8..4731638 100644 --- a/珞珈岛-项目相关文件/luojia-island/.idea/misc.xml +++ b/珞珈岛-项目相关文件/luojia-island/.idea/misc.xml @@ -8,7 +8,7 @@ - + \ No newline at end of file diff --git a/珞珈岛-项目相关文件/luojia-island/common/src/main/java/com/luojia_channel/common/config/MybatisConfig.java b/珞珈岛-项目相关文件/luojia-island/common/src/main/java/com/luojia_channel/common/config/MybatisConfig.java index 5c2b3bf..9577ba0 100644 --- a/珞珈岛-项目相关文件/luojia-island/common/src/main/java/com/luojia_channel/common/config/MybatisConfig.java +++ b/珞珈岛-项目相关文件/luojia-island/common/src/main/java/com/luojia_channel/common/config/MybatisConfig.java @@ -1,7 +1,21 @@ package com.luojia_channel.common.config; +import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; +import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor; +import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class MybatisConfig { + @Bean + public MybatisPlusInterceptor mybatisPlusInterceptor() { + MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); + PaginationInnerInterceptor paginationInterceptor = new PaginationInnerInterceptor(); + // 设置单页最大限制(如不限制可设为 -1) + paginationInterceptor.setMaxLimit(1000L); + // 设置是否溢出总页数(true:自动调整页码,false:抛出异常) + paginationInterceptor.setOverflow(true); + interceptor.addInnerInterceptor(paginationInterceptor); + return interceptor; + } } diff --git a/珞珈岛-项目相关文件/luojia-island/common/src/main/java/com/luojia_channel/common/config/WebMvcConfig.java b/珞珈岛-项目相关文件/luojia-island/common/src/main/java/com/luojia_channel/common/config/WebMvcConfig.java index e74ed52..891e804 100644 --- a/珞珈岛-项目相关文件/luojia-island/common/src/main/java/com/luojia_channel/common/config/WebMvcConfig.java +++ b/珞珈岛-项目相关文件/luojia-island/common/src/main/java/com/luojia_channel/common/config/WebMvcConfig.java @@ -12,7 +12,7 @@ public class WebMvcConfig implements WebMvcConfigurer { private final AuthInterceptor authInterceptor; @Override public void addInterceptors(InterceptorRegistry registry) { - // 登录拦截器 + // 拦截器 registry.addInterceptor(authInterceptor) .excludePathPatterns("/user/login", "/user/register" diff --git a/珞珈岛-项目相关文件/luojia-island/common/src/main/java/com/luojia_channel/common/exception/FileException.java b/珞珈岛-项目相关文件/luojia-island/common/src/main/java/com/luojia_channel/common/exception/FileException.java new file mode 100644 index 0000000..747057f --- /dev/null +++ b/珞珈岛-项目相关文件/luojia-island/common/src/main/java/com/luojia_channel/common/exception/FileException.java @@ -0,0 +1,7 @@ +package com.luojia_channel.common.exception; + +public class FileException extends BaseException{ + public FileException(String msg){ + super(500, msg); + } +} diff --git a/珞珈岛-项目相关文件/luojia-island/common/src/main/java/com/luojia_channel/common/interceptor/AuthInterceptor.java b/珞珈岛-项目相关文件/luojia-island/common/src/main/java/com/luojia_channel/common/interceptor/AuthInterceptor.java index 90cdbce..c937694 100644 --- a/珞珈岛-项目相关文件/luojia-island/common/src/main/java/com/luojia_channel/common/interceptor/AuthInterceptor.java +++ b/珞珈岛-项目相关文件/luojia-island/common/src/main/java/com/luojia_channel/common/interceptor/AuthInterceptor.java @@ -34,7 +34,6 @@ public class AuthInterceptor implements HandlerInterceptor { response.setHeader("New-Access-Token", JWTUtil.TOKEN_PREFIX + user.getAccessToken()); response.setHeader("New-Refresh-Token", user.getRefreshToken()); } - // 将用户信息存入请求上下文 UserContext.setUser(user); return true; } catch (UserException ex) { 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 index e3c134a..30330fb 100644 --- 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 @@ -27,7 +27,7 @@ public final class JWTUtil { private static final long ACCESS_EXPIRATION = 60 * 60 * 1000; //一小时 private static final long REFRESH_EXPIRATION = 60 * 60 * 24 * 15 * 1000; //15天 - private static final Long NEED_REFRESH_TTL = 7L; + private static final long NEED_REFRESH_TTL = 60 * 60 * 24 * 7 * 1000; //7天 private static final String USER_ID_KEY = "userId"; private static final String USER_NAME_KEY = "username"; public static final String TOKEN_PREFIX = "Bearer "; @@ -144,7 +144,7 @@ public final class JWTUtil { String newAccessToken = generateAccessToken(user); String newRefreshToken = generateRefreshToken(user); // 惰性刷新refreshToken - Long ttl = redisUtil.getExpire(redisKey, TimeUnit.DAYS); + Long ttl = redisUtil.getExpire(redisKey, TimeUnit.MILLISECONDS); if(ttl < NEED_REFRESH_TTL) redisUtil.set(redisKey, newRefreshToken, REFRESH_EXPIRATION, TimeUnit.MILLISECONDS); user.setAccessToken(newAccessToken); 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 index 25f0160..20494f9 100644 --- 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 @@ -48,7 +48,7 @@ public class RedisUtil { public boolean hasKey(String key) { Boolean result = redisTemplate.hasKey(key); - return result != null; + return result != null && result; } public Long getExpire(String key, TimeUnit timeUnit){ diff --git a/珞珈岛-项目相关文件/luojia-island/common/target/classes/com/luojia_channel/common/advice/GlobalExceptionHandler.class b/珞珈岛-项目相关文件/luojia-island/common/target/classes/com/luojia_channel/common/advice/GlobalExceptionHandler.class index e78f77a..e387a87 100644 Binary files a/珞珈岛-项目相关文件/luojia-island/common/target/classes/com/luojia_channel/common/advice/GlobalExceptionHandler.class and b/珞珈岛-项目相关文件/luojia-island/common/target/classes/com/luojia_channel/common/advice/GlobalExceptionHandler.class differ diff --git a/珞珈岛-项目相关文件/luojia-island/common/target/classes/com/luojia_channel/common/config/MybatisConfig.class b/珞珈岛-项目相关文件/luojia-island/common/target/classes/com/luojia_channel/common/config/MybatisConfig.class index 4552619..eaaa2fe 100644 Binary files a/珞珈岛-项目相关文件/luojia-island/common/target/classes/com/luojia_channel/common/config/MybatisConfig.class and b/珞珈岛-项目相关文件/luojia-island/common/target/classes/com/luojia_channel/common/config/MybatisConfig.class differ diff --git a/珞珈岛-项目相关文件/luojia-island/common/target/classes/com/luojia_channel/common/config/RedisConfig.class b/珞珈岛-项目相关文件/luojia-island/common/target/classes/com/luojia_channel/common/config/RedisConfig.class index ed5f031..658a2e9 100644 Binary files a/珞珈岛-项目相关文件/luojia-island/common/target/classes/com/luojia_channel/common/config/RedisConfig.class and b/珞珈岛-项目相关文件/luojia-island/common/target/classes/com/luojia_channel/common/config/RedisConfig.class differ diff --git a/珞珈岛-项目相关文件/luojia-island/common/target/classes/com/luojia_channel/common/config/WebMvcConfig.class b/珞珈岛-项目相关文件/luojia-island/common/target/classes/com/luojia_channel/common/config/WebMvcConfig.class index c425389..3ccb3b2 100644 Binary files a/珞珈岛-项目相关文件/luojia-island/common/target/classes/com/luojia_channel/common/config/WebMvcConfig.class and b/珞珈岛-项目相关文件/luojia-island/common/target/classes/com/luojia_channel/common/config/WebMvcConfig.class differ diff --git a/珞珈岛-项目相关文件/luojia-island/common/target/classes/com/luojia_channel/common/constants/RedisConstant.class b/珞珈岛-项目相关文件/luojia-island/common/target/classes/com/luojia_channel/common/constants/RedisConstant.class index 6e028ca..8fe2bfe 100644 Binary files a/珞珈岛-项目相关文件/luojia-island/common/target/classes/com/luojia_channel/common/constants/RedisConstant.class and b/珞珈岛-项目相关文件/luojia-island/common/target/classes/com/luojia_channel/common/constants/RedisConstant.class differ diff --git a/珞珈岛-项目相关文件/luojia-island/common/target/classes/com/luojia_channel/common/domain/Result.class b/珞珈岛-项目相关文件/luojia-island/common/target/classes/com/luojia_channel/common/domain/Result.class index e8f3cd2..251713f 100644 Binary files a/珞珈岛-项目相关文件/luojia-island/common/target/classes/com/luojia_channel/common/domain/Result.class and b/珞珈岛-项目相关文件/luojia-island/common/target/classes/com/luojia_channel/common/domain/Result.class differ diff --git a/珞珈岛-项目相关文件/luojia-island/common/target/classes/com/luojia_channel/common/domain/UserDTO$UserDTOBuilder.class b/珞珈岛-项目相关文件/luojia-island/common/target/classes/com/luojia_channel/common/domain/UserDTO$UserDTOBuilder.class index beeb7dd..91487ba 100644 Binary files a/珞珈岛-项目相关文件/luojia-island/common/target/classes/com/luojia_channel/common/domain/UserDTO$UserDTOBuilder.class and b/珞珈岛-项目相关文件/luojia-island/common/target/classes/com/luojia_channel/common/domain/UserDTO$UserDTOBuilder.class differ diff --git a/珞珈岛-项目相关文件/luojia-island/common/target/classes/com/luojia_channel/common/domain/UserDTO.class b/珞珈岛-项目相关文件/luojia-island/common/target/classes/com/luojia_channel/common/domain/UserDTO.class index 35fbe8d..0124260 100644 Binary files a/珞珈岛-项目相关文件/luojia-island/common/target/classes/com/luojia_channel/common/domain/UserDTO.class and b/珞珈岛-项目相关文件/luojia-island/common/target/classes/com/luojia_channel/common/domain/UserDTO.class differ diff --git a/珞珈岛-项目相关文件/luojia-island/common/target/classes/com/luojia_channel/common/exception/BaseException.class b/珞珈岛-项目相关文件/luojia-island/common/target/classes/com/luojia_channel/common/exception/BaseException.class index c207b15..6146da1 100644 Binary files a/珞珈岛-项目相关文件/luojia-island/common/target/classes/com/luojia_channel/common/exception/BaseException.class and b/珞珈岛-项目相关文件/luojia-island/common/target/classes/com/luojia_channel/common/exception/BaseException.class differ diff --git a/珞珈岛-项目相关文件/luojia-island/common/target/classes/com/luojia_channel/common/exception/FileException.class b/珞珈岛-项目相关文件/luojia-island/common/target/classes/com/luojia_channel/common/exception/FileException.class new file mode 100644 index 0000000..16c547c Binary files /dev/null and b/珞珈岛-项目相关文件/luojia-island/common/target/classes/com/luojia_channel/common/exception/FileException.class differ diff --git a/珞珈岛-项目相关文件/luojia-island/common/target/classes/com/luojia_channel/common/exception/UserException.class b/珞珈岛-项目相关文件/luojia-island/common/target/classes/com/luojia_channel/common/exception/UserException.class index 1926715..d98b1d1 100644 Binary files a/珞珈岛-项目相关文件/luojia-island/common/target/classes/com/luojia_channel/common/exception/UserException.class and b/珞珈岛-项目相关文件/luojia-island/common/target/classes/com/luojia_channel/common/exception/UserException.class differ diff --git a/珞珈岛-项目相关文件/luojia-island/common/target/classes/com/luojia_channel/common/interceptor/AuthInterceptor.class b/珞珈岛-项目相关文件/luojia-island/common/target/classes/com/luojia_channel/common/interceptor/AuthInterceptor.class index b7ac154..0f5c82c 100644 Binary files a/珞珈岛-项目相关文件/luojia-island/common/target/classes/com/luojia_channel/common/interceptor/AuthInterceptor.class and b/珞珈岛-项目相关文件/luojia-island/common/target/classes/com/luojia_channel/common/interceptor/AuthInterceptor.class differ diff --git a/珞珈岛-项目相关文件/luojia-island/common/target/classes/com/luojia_channel/common/utils/JWTUtil.class b/珞珈岛-项目相关文件/luojia-island/common/target/classes/com/luojia_channel/common/utils/JWTUtil.class index 91b969b..6ebfdb9 100644 Binary files a/珞珈岛-项目相关文件/luojia-island/common/target/classes/com/luojia_channel/common/utils/JWTUtil.class and b/珞珈岛-项目相关文件/luojia-island/common/target/classes/com/luojia_channel/common/utils/JWTUtil.class differ diff --git a/珞珈岛-项目相关文件/luojia-island/common/target/classes/com/luojia_channel/common/utils/RedisUtil$ZSetItem.class b/珞珈岛-项目相关文件/luojia-island/common/target/classes/com/luojia_channel/common/utils/RedisUtil$ZSetItem.class index b732300..a91f9b1 100644 Binary files a/珞珈岛-项目相关文件/luojia-island/common/target/classes/com/luojia_channel/common/utils/RedisUtil$ZSetItem.class and b/珞珈岛-项目相关文件/luojia-island/common/target/classes/com/luojia_channel/common/utils/RedisUtil$ZSetItem.class differ diff --git a/珞珈岛-项目相关文件/luojia-island/common/target/classes/com/luojia_channel/common/utils/RedisUtil.class b/珞珈岛-项目相关文件/luojia-island/common/target/classes/com/luojia_channel/common/utils/RedisUtil.class index 11589a5..b52d3a0 100644 Binary files a/珞珈岛-项目相关文件/luojia-island/common/target/classes/com/luojia_channel/common/utils/RedisUtil.class and b/珞珈岛-项目相关文件/luojia-island/common/target/classes/com/luojia_channel/common/utils/RedisUtil.class differ diff --git a/珞珈岛-项目相关文件/luojia-island/common/target/classes/com/luojia_channel/common/utils/UserContext.class b/珞珈岛-项目相关文件/luojia-island/common/target/classes/com/luojia_channel/common/utils/UserContext.class index 9379b3e..86a83fb 100644 Binary files a/珞珈岛-项目相关文件/luojia-island/common/target/classes/com/luojia_channel/common/utils/UserContext.class and b/珞珈岛-项目相关文件/luojia-island/common/target/classes/com/luojia_channel/common/utils/UserContext.class differ diff --git a/珞珈岛-项目相关文件/luojia-island/package-lock.json b/珞珈岛-项目相关文件/luojia-island/package-lock.json new file mode 100644 index 0000000..3b00028 --- /dev/null +++ b/珞珈岛-项目相关文件/luojia-island/package-lock.json @@ -0,0 +1,6 @@ +{ + "name": "luojia-island", + "lockfileVersion": 3, + "requires": true, + "packages": {} +} diff --git a/珞珈岛-项目相关文件/luojia-island/pom.xml b/珞珈岛-项目相关文件/luojia-island/pom.xml index c93caf3..8e6768a 100644 --- a/珞珈岛-项目相关文件/luojia-island/pom.xml +++ b/珞珈岛-项目相关文件/luojia-island/pom.xml @@ -59,6 +59,7 @@ mysql-connector-java ${mysql.version} + @@ -81,6 +82,12 @@ 1.2.83 + + + com.baomidou + mybatis-plus-spring-boot3-starter + + cn.hutool @@ -88,6 +95,12 @@ 5.8.24 + + + io.minio + minio + 8.5.12 + diff --git a/珞珈岛-项目相关文件/luojia-island/service/pom.xml b/珞珈岛-项目相关文件/luojia-island/service/pom.xml index 808083b..ebc0e28 100644 --- a/珞珈岛-项目相关文件/luojia-island/service/pom.xml +++ b/珞珈岛-项目相关文件/luojia-island/service/pom.xml @@ -20,12 +20,6 @@ 1.0.0 - - - com.baomidou - mybatis-plus-spring-boot3-starter - - org.springframework.boot @@ -49,6 +43,7 @@ org.springframework.cloud spring-cloud-starter-bootstrap + org.springframework.cloud spring-cloud-starter-loadbalancer @@ -60,6 +55,7 @@ spring-boot-starter-test test + diff --git a/珞珈岛-项目相关文件/luojia-island/service/src/main/java/com/luojia_channel/modules/file/config/MinioConfig.java b/珞珈岛-项目相关文件/luojia-island/service/src/main/java/com/luojia_channel/modules/file/config/MinioConfig.java new file mode 100644 index 0000000..a7e7950 --- /dev/null +++ b/珞珈岛-项目相关文件/luojia-island/service/src/main/java/com/luojia_channel/modules/file/config/MinioConfig.java @@ -0,0 +1,31 @@ +package com.luojia_channel.modules.file.config; + +import io.minio.MinioClient; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class MinioConfig { + @Value("${minio.endpoint}") + private String endpoint; + @Value("${minio.accessKey}") + private String accessKey; + @Value("${minio.secretKey}") + private String secretKey; + + @Bean + public MinioClient minioClient() { + try { + MinioClient minioClient = MinioClient.builder() + .endpoint(endpoint) + .credentials(accessKey, secretKey) + .build(); + return minioClient; + } catch (Exception e){ + e.printStackTrace(); + } + return null; + } + +} diff --git a/珞珈岛-项目相关文件/luojia-island/service/src/main/java/com/luojia_channel/modules/file/constants/FileConstant.java b/珞珈岛-项目相关文件/luojia-island/service/src/main/java/com/luojia_channel/modules/file/constants/FileConstant.java new file mode 100644 index 0000000..ac1b747 --- /dev/null +++ b/珞珈岛-项目相关文件/luojia-island/service/src/main/java/com/luojia_channel/modules/file/constants/FileConstant.java @@ -0,0 +1,7 @@ +package com.luojia_channel.modules.file.constants; + +public class FileConstant { + public static final String CHUNK_BUCKET = "chunks"; + public static final String CHUNK_PREFIX = "file:chunks:"; + public static final long MAX_UPLOAD_SIZE = 10*1024*1024; +} diff --git a/珞珈岛-项目相关文件/luojia-island/service/src/main/java/com/luojia_channel/modules/file/dto/CompleteUploadDTO.java b/珞珈岛-项目相关文件/luojia-island/service/src/main/java/com/luojia_channel/modules/file/dto/CompleteUploadDTO.java new file mode 100644 index 0000000..6c4963c --- /dev/null +++ b/珞珈岛-项目相关文件/luojia-island/service/src/main/java/com/luojia_channel/modules/file/dto/CompleteUploadDTO.java @@ -0,0 +1,17 @@ +package com.luojia_channel.modules.file.dto; + +import lombok.Builder; +import lombok.Data; + +// 合并分片DTO +@Data +@Builder +public class CompleteUploadDTO { + private String fileMd5; + + private Integer totalChunks; + + private String fileType; + + private String fileName; +} \ No newline at end of file diff --git a/珞珈岛-项目相关文件/luojia-island/service/src/main/java/com/luojia_channel/modules/file/dto/UploadChunkDTO.java b/珞珈岛-项目相关文件/luojia-island/service/src/main/java/com/luojia_channel/modules/file/dto/UploadChunkDTO.java new file mode 100644 index 0000000..dea4d8a --- /dev/null +++ b/珞珈岛-项目相关文件/luojia-island/service/src/main/java/com/luojia_channel/modules/file/dto/UploadChunkDTO.java @@ -0,0 +1,22 @@ +package com.luojia_channel.modules.file.dto; + +import lombok.Builder; +import lombok.Data; +import org.springframework.web.multipart.MultipartFile; + +@Data +@Builder +public class UploadChunkDTO { + // 分片文件 + private MultipartFile file; + // 整个文件的md5 + private String fileMd5; + // 分片序号,从0开始 + private Integer chunkNumber; + // 分片总数 + private Integer totalChunks; + + private String fileType; + + private String fileName; +} diff --git a/珞珈岛-项目相关文件/luojia-island/service/src/main/java/com/luojia_channel/modules/file/dto/UploadFileDTO.java b/珞珈岛-项目相关文件/luojia-island/service/src/main/java/com/luojia_channel/modules/file/dto/UploadFileDTO.java new file mode 100644 index 0000000..84451cc --- /dev/null +++ b/珞珈岛-项目相关文件/luojia-island/service/src/main/java/com/luojia_channel/modules/file/dto/UploadFileDTO.java @@ -0,0 +1,15 @@ +package com.luojia_channel.modules.file.dto; + +import lombok.Builder; +import lombok.Data; +import org.springframework.web.multipart.MultipartFile; + +@Data +@Builder +public class UploadFileDTO { + private MultipartFile file; + // 文件类型,image or video + private String fileType; + // 文件md5 + private String fileMd5; +} diff --git a/珞珈岛-项目相关文件/luojia-island/service/src/main/java/com/luojia_channel/modules/file/entity/LjFile.java b/珞珈岛-项目相关文件/luojia-island/service/src/main/java/com/luojia_channel/modules/file/entity/LjFile.java new file mode 100644 index 0000000..ab7d3c5 --- /dev/null +++ b/珞珈岛-项目相关文件/luojia-island/service/src/main/java/com/luojia_channel/modules/file/entity/LjFile.java @@ -0,0 +1,32 @@ +package com.luojia_channel.modules.file.entity; + +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Builder; +import lombok.Data; + +import java.time.LocalDateTime; + +@Data +@TableName("lj_file") +@Builder +public class LjFile { + private Long id; + + private String fileName; + + private String fileUrl; + + private Long fileSize; + + private String fileMd5; + + private String fileType; + + private Integer fileStatus; // 0正在上传,1上传成功,2失败,3待审核 + + private Long userId; // 上传用户id + + private LocalDateTime createTime; + + private LocalDateTime updateTime; +} diff --git a/珞珈岛-项目相关文件/luojia-island/service/src/main/java/com/luojia_channel/modules/file/mapper/LjFileMapper.java b/珞珈岛-项目相关文件/luojia-island/service/src/main/java/com/luojia_channel/modules/file/mapper/LjFileMapper.java new file mode 100644 index 0000000..24b2761 --- /dev/null +++ b/珞珈岛-项目相关文件/luojia-island/service/src/main/java/com/luojia_channel/modules/file/mapper/LjFileMapper.java @@ -0,0 +1,9 @@ +package com.luojia_channel.modules.file.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.luojia_channel.modules.file.entity.LjFile; +import org.apache.ibatis.annotations.Mapper; + +@Mapper +public interface LjFileMapper extends BaseMapper { +} diff --git a/珞珈岛-项目相关文件/luojia-island/service/src/main/java/com/luojia_channel/modules/file/service/FileService.java b/珞珈岛-项目相关文件/luojia-island/service/src/main/java/com/luojia_channel/modules/file/service/FileService.java new file mode 100644 index 0000000..b47baae --- /dev/null +++ b/珞珈岛-项目相关文件/luojia-island/service/src/main/java/com/luojia_channel/modules/file/service/FileService.java @@ -0,0 +1,15 @@ +package com.luojia_channel.modules.file.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.luojia_channel.modules.file.dto.CompleteUploadDTO; +import com.luojia_channel.modules.file.dto.UploadChunkDTO; +import com.luojia_channel.modules.file.dto.UploadFileDTO; +import com.luojia_channel.modules.file.entity.LjFile; + +public interface FileService extends IService { + Boolean createBucket(String name); + Boolean deleteBucket(String name); + Long uploadFile(UploadFileDTO uploadFileDTO); + Boolean uploadChunk(UploadChunkDTO chunkDTO); + Long completeUpload(CompleteUploadDTO completeDTO); +} diff --git a/珞珈岛-项目相关文件/luojia-island/service/src/main/java/com/luojia_channel/modules/file/service/impl/FileServiceImpl.java b/珞珈岛-项目相关文件/luojia-island/service/src/main/java/com/luojia_channel/modules/file/service/impl/FileServiceImpl.java new file mode 100644 index 0000000..bca6b0d --- /dev/null +++ b/珞珈岛-项目相关文件/luojia-island/service/src/main/java/com/luojia_channel/modules/file/service/impl/FileServiceImpl.java @@ -0,0 +1,267 @@ +package com.luojia_channel.modules.file.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.luojia_channel.common.exception.FileException; +import com.luojia_channel.common.utils.RedisUtil; +import com.luojia_channel.common.utils.UserContext; +import com.luojia_channel.modules.file.dto.UploadChunkDTO; +import com.luojia_channel.modules.file.dto.UploadFileDTO; +import com.luojia_channel.modules.file.dto.CompleteUploadDTO; +import com.luojia_channel.modules.file.entity.LjFile; +import com.luojia_channel.modules.file.mapper.LjFileMapper; +import com.luojia_channel.modules.file.service.FileService; +import com.luojia_channel.modules.file.utils.GeneratePathUtil; +import com.luojia_channel.modules.file.utils.ValidateFileUtil; +import io.minio.*; +import io.minio.messages.DeleteError; +import io.minio.messages.DeleteObject; +import io.minio.messages.Item; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.time.LocalDateTime; +import java.util.*; +import java.util.concurrent.TimeUnit; + +import static com.luojia_channel.modules.file.constants.FileConstant.CHUNK_BUCKET; +import static com.luojia_channel.modules.file.constants.FileConstant.CHUNK_PREFIX; + +@Service +@Slf4j +@RequiredArgsConstructor +public class FileServiceImpl extends ServiceImpl implements FileService { + private final MinioClient minioClient; + private final RedisUtil redisUtil; + private final ValidateFileUtil validateFileUtil; + private final GeneratePathUtil generatePathUtil; + + private void init(){ + createBucket("videos"); + createBucket("images"); + createBucket("chunks"); + } + + @Override + public Boolean createBucket(String name){ + try { + boolean isExist = minioClient. + bucketExists(BucketExistsArgs.builder().bucket(name).build()); + if (!isExist) { + minioClient.makeBucket(MakeBucketArgs.builder().bucket(name).build()); + } + } catch (Exception e) { + throw new FileException("创建桶失败"); + } + return true; + } + + @Override + public Boolean deleteBucket(String name){ + try { + minioClient.removeBucket(RemoveBucketArgs.builder().bucket(name).build()); + } catch (Exception e) { + throw new FileException("删除桶失败"); + } + return true; + } + + // 普通上传 + @Override + @Transactional(rollbackFor = Exception.class) + public Long uploadFile(UploadFileDTO fileDTO) { + validateFileUtil.validateFile(fileDTO); + Long fileId = validateFileUtil.getExistedFileId(fileDTO.getFileMd5()); + if(fileId != null){ + return fileId; + } + // 普通上传 + try { + String fileName = fileDTO.getFile().getOriginalFilename(); + String bucket = generatePathUtil.getBucketName(fileDTO.getFileType()); + String objectName = generatePathUtil.getObjectName(fileName, + fileDTO.getFileMd5()); + minioClient.putObject( + PutObjectArgs.builder() + .bucket(bucket) + .object(objectName) + .stream(fileDTO.getFile().getInputStream(), + fileDTO.getFile().getSize(), -1) + .build() + ); + return saveFileToDB(fileName, objectName, fileDTO.getFile().getSize(), + fileDTO.getFileMd5(), fileDTO.getFileType(), 1); + } catch (Exception e) { + log.error("文件上传失败: {}", e.getMessage()); + throw new FileException("文件上传失败"); + } + } + + private Long saveFileToDB(String fileName, String fileUrl, Long fileSize, + String fileMd5, String fileType, Integer fileStatus){ + Long userId = UserContext.getUserId(); + if(userId == null){ + throw new FileException("不存在的用户试图上传文件"); + } + LjFile file= LjFile.builder() + .fileName(fileName) + .fileUrl(fileUrl) + .fileSize(fileSize) + .fileMd5(fileMd5) + .fileType(fileType) + .fileStatus(fileStatus) + .userId(userId) + .createTime(LocalDateTime.now()) + .updateTime(LocalDateTime.now()) + .build(); + if (!save(file)) { + throw new FileException("文件记录保存失败"); + } + return file.getId(); + } + + // 分片上传 + @Override + public Boolean uploadChunk(UploadChunkDTO chunkDTO) { + // 验证分片信息 + validateFileUtil.validateChunk(chunkDTO); + // 判断整个文件是否存在 + if (validateFileUtil.getExistedFileId(chunkDTO.getFileMd5()) != null) { + return true; + } + // 检查分片是否已上传 + if (validateFileUtil.isChunkUploaded(chunkDTO.getFileMd5(), chunkDTO.getChunkNumber())) { + return true; + } + // 保存分片到MinIO临时Bucket + String objectName = generatePathUtil + .getChunkObjectName(chunkDTO.getFileMd5(), chunkDTO.getChunkNumber()); + // 一小时内保存进度 + String key = CHUNK_PREFIX + chunkDTO.getFileMd5(); + try { + minioClient.putObject( + PutObjectArgs.builder() + .bucket(CHUNK_BUCKET) + .object(objectName) + .stream(chunkDTO.getFile().getInputStream(), + chunkDTO.getFile().getSize(), -1) + .build() + ); + redisUtil.sAdd(key, chunkDTO.getChunkNumber()); + redisUtil.expire(key, 1, TimeUnit.HOURS); + return true; + } catch (Exception e) { + // 遇到异常删除已上传的分片 + try { + minioClient.removeObject( + RemoveObjectArgs.builder() + .bucket(CHUNK_BUCKET) + .object(objectName) + .build()); + redisUtil.sRemove(key, chunkDTO.getChunkNumber()); + } catch (Exception ex) { + log.error("删除分片失败: {}", ex.getMessage(), ex); + } + log.error("分片上传失败: {}", e.getMessage()); + throw new FileException("分片上传失败"); + } + } + + + // 合并分片 + @Override + @Transactional(rollbackFor = Exception.class) + public Long completeUpload(CompleteUploadDTO completeDTO) { + // 验证分片完整性 + if (!validateFileUtil. + areAllChunksUploaded(completeDTO.getFileMd5(), completeDTO.getTotalChunks())) { + throw new FileException("存在未上传的分片"); + } + // 合并分片到目标Bucket + String bucket = generatePathUtil.getBucketName(completeDTO.getFileType()); + String objectName = generatePathUtil + .getObjectName(completeDTO.getFileName(), completeDTO.getFileMd5()); + try { + List sources = new ArrayList<>(); + for (int i = 0; i < completeDTO.getTotalChunks(); i++) { + String chunkObjectName = generatePathUtil + .getChunkObjectName(completeDTO.getFileMd5(), i); + sources.add( + ComposeSource.builder() + .bucket(CHUNK_BUCKET) + .object(chunkObjectName) + .build()); + } + minioClient.composeObject( + ComposeObjectArgs.builder() + .sources(sources) + .bucket(bucket) + .object(objectName) + .build()); + + // 获得文件大小 + long fileSize = minioClient.statObject( + StatObjectArgs.builder() + .bucket(bucket) + .object(objectName) + .build() + ).size(); + // 保存文件到数据库 + Long fileId = saveFileToDB(completeDTO.getFileName(), objectName, fileSize, + completeDTO.getFileMd5(), completeDTO.getFileType(), 3); + // 删除临时分片 + deleteChunks(completeDTO.getFileMd5()); + return fileId; + } catch (Exception e) { + log.error("合并分片失败: {}", e.getMessage()); + throw new FileException("合并分片失败"); + } + } + + // 删除临时分片,与遍历删除相比该操作只需要进行一次io + public void deleteChunks(String fileMd5) { + try { + // 获取需要删除的对象列表 + Iterable> items = minioClient.listObjects( + ListObjectsArgs.builder() + .bucket(CHUNK_BUCKET) + .prefix(fileMd5 + "/") + .build() + ); + // 转换为 DeleteObject 列表 + List deleteObjects = new ArrayList<>(); + for (Result result : items) { + Item item = result.get(); + log.info("要删除的分片文件:{}", item.objectName()); + deleteObjects.add(new DeleteObject(item.objectName())); + } + // 执行删除操作 + if (!deleteObjects.isEmpty()) { + log.info("正在删除 {} 个分片文件", deleteObjects.size()); + Iterable> results = minioClient.removeObjects( + RemoveObjectsArgs.builder() + .bucket(CHUNK_BUCKET) + .objects(deleteObjects) + .build() + ); + // 遍历结果以触发删除 + for (Result result : results) { + DeleteError error = result.get(); + if (error != null) { + log.error("删除文件 {} 失败: {}", error.objectName(), error.message()); + } + } + redisUtil.delete(CHUNK_PREFIX + fileMd5); + log.info("分片删除完成"); + } else { + log.warn("未找到需要删除的分片文件,fileMd5={}", fileMd5); + } + } catch (Exception e) { + log.error("删除分片失败: {}", e.getMessage(), e); + throw new FileException("删除分片失败"); + } + } + +} + diff --git a/珞珈岛-项目相关文件/luojia-island/service/src/main/java/com/luojia_channel/modules/file/utils/GeneratePathUtil.java b/珞珈岛-项目相关文件/luojia-island/service/src/main/java/com/luojia_channel/modules/file/utils/GeneratePathUtil.java new file mode 100644 index 0000000..38e4b92 --- /dev/null +++ b/珞珈岛-项目相关文件/luojia-island/service/src/main/java/com/luojia_channel/modules/file/utils/GeneratePathUtil.java @@ -0,0 +1,35 @@ +package com.luojia_channel.modules.file.utils; + +import com.luojia_channel.common.exception.FileException; +import org.springframework.stereotype.Component; + +import java.time.LocalDate; + +@Component +public class GeneratePathUtil { + public String getBucketName(String fileType) { + return switch (fileType) { + case "image" -> "images"; + case "video" -> "videos"; + default -> throw new FileException("无效的文件类型"); + }; + } + + // 分片对象路径格式:fileMd5/chunk_{number} + public String getChunkObjectName(String fileMd5, int chunkNumber) { + return String.format("%s/chunk_%d", fileMd5, chunkNumber); + } + + // year/month/day/fileMd5/suffix + public String getObjectName(String fileName, String fileMd5) { + String suffix = fileName.contains(".") ? + fileName.substring(fileName.lastIndexOf(".")) : ""; + LocalDate now = LocalDate.now(); + return String.format("%d/%02d/%02d/%s%s", + now.getYear(), + now.getMonthValue(), + now.getDayOfMonth(), + fileMd5, + suffix); + } +} diff --git a/珞珈岛-项目相关文件/luojia-island/service/src/main/java/com/luojia_channel/modules/file/utils/ValidateFileUtil.java b/珞珈岛-项目相关文件/luojia-island/service/src/main/java/com/luojia_channel/modules/file/utils/ValidateFileUtil.java new file mode 100644 index 0000000..6da65fc --- /dev/null +++ b/珞珈岛-项目相关文件/luojia-island/service/src/main/java/com/luojia_channel/modules/file/utils/ValidateFileUtil.java @@ -0,0 +1,102 @@ +package com.luojia_channel.modules.file.utils; + +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.luojia_channel.common.exception.FileException; +import com.luojia_channel.common.utils.RedisUtil; +import com.luojia_channel.modules.file.dto.UploadChunkDTO; +import com.luojia_channel.modules.file.dto.UploadFileDTO; +import com.luojia_channel.modules.file.entity.LjFile; +import com.luojia_channel.modules.file.mapper.LjFileMapper; +import io.minio.MinioClient; +import io.minio.StatObjectArgs; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Component; + +import java.util.Arrays; +import java.util.List; + +import static com.luojia_channel.modules.file.constants.FileConstant.*; + +@Component +@RequiredArgsConstructor +public class ValidateFileUtil { + private final LjFileMapper ljFileMapper; + private final RedisUtil redisUtil; + private final GeneratePathUtil generatePathUtil; + private final MinioClient minioClient; + // 验证分片参数 + public void validateChunk(UploadChunkDTO chunkDTO) { + if (chunkDTO.getFile().isEmpty()) { + throw new FileException("分片数据不能为空"); + } + if (StrUtil.isBlank(chunkDTO.getFileMd5())) { + throw new FileException("文件MD5缺失"); + } + if (chunkDTO.getChunkNumber() < 0) { + throw new FileException("分片编号不能为负数"); + } + if (chunkDTO.getTotalChunks() <= 0) { + throw new FileException("总分片数必须大于0"); + } + if(chunkDTO.getChunkNumber() >= chunkDTO.getTotalChunks()){ + throw new FileException("分片序号不能大于分片总数"); + } + } + // 校验普通文件上传 + public void validateFile(UploadFileDTO dto) { + if (dto.getFile().isEmpty()) { + throw new FileException("文件不能为空"); + } + // MD5校验 + if (StrUtil.isBlank(dto.getFileMd5())) { + throw new FileException("文件MD5缺失"); + } + // 类型校验 + if (!Arrays.asList("image", "video").contains(dto.getFileType())) { + throw new FileException("不支持的文件类型"); + } + // 大小校验 + if(dto.getFile().getSize() > MAX_UPLOAD_SIZE){ + throw new FileException("上传文件大小过大"); + } + } + + // 秒传检查 + public Long getExistedFileId(String fileMd5) { + LjFile file = ljFileMapper.selectOne(Wrappers.lambdaQuery() + .eq(LjFile::getFileMd5, fileMd5)); + if(file == null){ + return null; + } + return file.getId(); + } + + // 检查分片是否已上传 + public boolean isChunkUploaded(String fileMd5, int chunkNumber) { + String objectName = generatePathUtil.getChunkObjectName(fileMd5, chunkNumber); + String redisKey = CHUNK_PREFIX + fileMd5; + // 检查redis中是否已记录该分片 + if (redisUtil.sIsMember(redisKey, chunkNumber)) { + return true; + } + try { + minioClient.statObject( + StatObjectArgs.builder() + .bucket(CHUNK_BUCKET) + .object(objectName) + .build() + ); + return true; + } catch (Exception e) { + return false; + } + } + + // 检查所有分片是否已上传 + public boolean areAllChunksUploaded(String fileMd5, int totalChunks) { + String key = CHUNK_PREFIX + fileMd5; + List uploadedChunks = redisUtil.sGet(key); + return uploadedChunks.size() == totalChunks; + } +} 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 deleted file mode 100644 index 726d3cf..0000000 --- a/珞珈岛-项目相关文件/luojia-island/service/src/main/java/com/luojia_channel/modules/user/Config/SecurityConfig.java +++ /dev/null @@ -1,30 +0,0 @@ -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/controller/UserInfoController.java b/珞珈岛-项目相关文件/luojia-island/service/src/main/java/com/luojia_channel/modules/user/controller/UserInfoController.java index be109f5..03ef416 100644 --- 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 @@ -1,11 +1,38 @@ package com.luojia_channel.modules.user.controller; +import com.luojia_channel.common.domain.Result; +import com.luojia_channel.modules.file.dto.UploadFileDTO; +import com.luojia_channel.modules.user.dto.UserChangeInfoDTO; +import com.luojia_channel.modules.user.service.UserInfoService; import lombok.RequiredArgsConstructor; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; @RestController @RequestMapping("/user/info") @RequiredArgsConstructor public class UserInfoController { + private final UserInfoService userInfoService; + @PostMapping("/update") + public Result updateInfo(@RequestBody UserChangeInfoDTO userChangeInfoDTO){ + userInfoService.updateInfo(userChangeInfoDTO); + return Result.success(); + } + + @PostMapping("/password") + public Result updatePassword(@RequestParam String password){ + userInfoService.updatePassword(password); + return Result.success(); + } + + @PostMapping("/avatar") + public Result updateAvatar(@RequestParam("file") MultipartFile file, + @RequestParam("fileType") String fileType, + @RequestParam("fileMd5") String fileMd5) { + UploadFileDTO fileDTO = UploadFileDTO.builder() + .file(file).fileType(fileType).fileMd5(fileMd5) + .build(); + userInfoService.updateAvatar(fileDTO); + return Result.success(); + } } 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 index af6edb5..1a3347e 100644 --- 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 @@ -5,6 +5,7 @@ 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 jakarta.servlet.http.HttpServletRequest; import lombok.RequiredArgsConstructor; import org.springframework.web.bind.annotation.*; @@ -24,8 +25,8 @@ public class UserLoginController { } @PostMapping("/logout") - public Result logout(@RequestParam String accessToken){ - userLoginService.logout(accessToken); + public Result logout(HttpServletRequest request){ + userLoginService.logout(request); return Result.success(); } diff --git a/珞珈岛-项目相关文件/luojia-island/service/src/main/java/com/luojia_channel/modules/user/dto/UserChangeInfoDTO.java b/珞珈岛-项目相关文件/luojia-island/service/src/main/java/com/luojia_channel/modules/user/dto/UserChangeInfoDTO.java new file mode 100644 index 0000000..210ff7b --- /dev/null +++ b/珞珈岛-项目相关文件/luojia-island/service/src/main/java/com/luojia_channel/modules/user/dto/UserChangeInfoDTO.java @@ -0,0 +1,20 @@ +package com.luojia_channel.modules.user.dto; + +import lombok.Data; + +@Data +public class UserChangeInfoDTO { + private String username; + + private String phone; + + private String email; + + private String studentId; + + private String avatar; + + private Integer gender; + + private String college; +} 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 index 7021946..e544b75 100644 --- 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 @@ -6,5 +6,6 @@ import lombok.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 index a64cbc1..fd149cc 100644 --- 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 @@ -6,8 +6,6 @@ import lombok.Data; public class UserRegisterDTO { private String username; - private String realName; - private String password; private String phone; @@ -15,6 +13,4 @@ public class UserRegisterDTO { private String email; private String studentId; - - private String captcha; } 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 index d49d1b4..fa8fe48 100644 --- 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 @@ -14,44 +14,29 @@ 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; + /** - * 学号 + * 头像url */ - private String studentId; + private String avatar; /** * 性别(0未知,1男,2女) */ private Integer gender; - /** - * 创建时间 - */ private LocalDateTime createTime; private LocalDateTime updateTime; 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 index 6982d38..e7e26db 100644 --- 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 @@ -1,7 +1,16 @@ package com.luojia_channel.modules.user.service; import com.baomidou.mybatisplus.extension.service.IService; +import com.luojia_channel.modules.file.dto.UploadFileDTO; +import com.luojia_channel.modules.user.dto.UserChangeInfoDTO; import com.luojia_channel.modules.user.entity.User; +import org.springframework.web.multipart.MultipartFile; public interface UserInfoService extends IService { + + void updateInfo(UserChangeInfoDTO userChangeInfoDTO); + + void updatePassword(String password); + + void updateAvatar(UploadFileDTO uploadFileDTO); } 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 index 9330f11..420dcdd 100644 --- 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 @@ -5,6 +5,7 @@ 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; +import jakarta.servlet.http.HttpServletRequest; public interface UserLoginService extends IService { @@ -12,7 +13,7 @@ public interface UserLoginService extends IService { UserDTO checkLogin(String accessToken, String refreshToken); - void logout(String accessToken); + void logout(HttpServletRequest request); 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 index d72f795..5208191 100644 --- 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 @@ -1,13 +1,99 @@ package com.luojia_channel.modules.user.service.impl; +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.crypto.digest.BCrypt; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.luojia_channel.common.exception.UserException; +import com.luojia_channel.common.utils.UserContext; +import com.luojia_channel.modules.file.dto.UploadFileDTO; +import com.luojia_channel.modules.file.service.impl.FileServiceImpl; +import com.luojia_channel.modules.file.utils.GeneratePathUtil; +import com.luojia_channel.modules.file.utils.ValidateFileUtil; +import com.luojia_channel.modules.user.dto.UserChangeInfoDTO; 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 com.luojia_channel.modules.user.utils.ValidateUserUtil; +import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; +import org.springframework.util.DigestUtils; + +import java.io.InputStream; +import java.time.LocalDateTime; @Service +@RequiredArgsConstructor public class UserInfoServiceImpl extends ServiceImpl implements UserInfoService { + private final UserMapper userMapper; + private final ValidateUserUtil validateUserUtil; + private final FileServiceImpl minioService; + private final GeneratePathUtil generatePathUtil; + private final ValidateFileUtil validateFileUtil; + + @Override + public void updateInfo(UserChangeInfoDTO userChangeInfoDTO) { + Long userId = UserContext.getUserId(); + User currentUser = userMapper.selectById(userId); + if(currentUser == null){ + throw new UserException("用户不存在"); + } + validateUserUtil.validateFormats(userChangeInfoDTO, userId); + User user = BeanUtil.copyProperties(userChangeInfoDTO, User.class); + user.setId(userId); + user.setUpdateTime(LocalDateTime.now()); + updateById(user); + } + + @Override + public void updatePassword(String password) { + Long userId = UserContext.getUserId(); + User user = userMapper.selectById(userId); + if(user == null){ + throw new UserException("用户不存在"); + } + if (!password.matches(ValidateUserUtil.PASSWORD_REGEX)) { + throw new UserException("密码格式不符合要求"); + } + if (BCrypt.checkpw(password, user.getPassword())) { + throw new UserException("修改密码不能与原密码相同"); + } + String encodedPassword = BCrypt.hashpw(password, BCrypt.gensalt()); + user.setPassword(encodedPassword); + user.setUpdateTime(LocalDateTime.now()); + updateById(user); + } + + @Override + public void updateAvatar(UploadFileDTO uploadFileDTO) { + Long userId = UserContext.getUserId(); + User user = userMapper.selectById(userId); + if(user == null){ + throw new UserException("用户不存在"); + } + validateFileUtil.validateFile(uploadFileDTO); + try { + + // TODO 下述工作应该是前端干的---------- + /* + InputStream inputStream = uploadFileDTO.getFile().getInputStream(); + String fileMd5 = DigestUtils.md5DigestAsHex(inputStream); + String fileType = "image"; + uploadFileDTO.setFileType(fileType); + uploadFileDTO.setFileMd5(fileMd5); + + // TODO ending--------- + */ + + minioService.uploadFile(uploadFileDTO); + String filePath = generatePathUtil + .getObjectName(uploadFileDTO.getFile().getOriginalFilename(), + uploadFileDTO.getFileMd5()); + // 直接设置成url,省去一次读数据库操作 + user.setAvatar(filePath); + updateById(user); + } catch (Exception e) { + throw new UserException("上传头像失败"); + } + } } 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 index 14aed94..f978234 100644 --- 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 @@ -2,6 +2,7 @@ package com.luojia_channel.modules.user.service.impl; import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.util.StrUtil; +import cn.hutool.crypto.digest.BCrypt; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; @@ -15,7 +16,8 @@ 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 com.luojia_channel.modules.user.utils.ValidateParameterUtil; +import com.luojia_channel.modules.user.utils.ValidateUserUtil; +import jakarta.servlet.http.HttpServletRequest; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -35,7 +37,7 @@ public class UserLoginServiceImpl extends ServiceImpl implemen private final UserMapper userMapper; private final RedisUtil redisUtil; private final JWTUtil jwtUtil; - private final ValidateParameterUtil validateParameterUtil; + private final ValidateUserUtil validateUserUtil; /** * 根据用户标志获得用户学号,用于登录 @@ -46,17 +48,17 @@ public class UserLoginServiceImpl extends ServiceImpl implemen if (StrUtil.isBlank(userFlag)) { throw new UserException("用户标识不能为空"); } - // 使用正则表达式判断类型,之前直接判断长度,虽然不合法的数据在数据库中仍然查不到 + //使用正则表达式判断类型,之前直接判断长度,虽然不合法的数据在数据库中仍然查不到 boolean isEmail = userFlag.contains("@"); - boolean isPhone = !isEmail && userFlag.matches(ValidateParameterUtil.PHONE_REGEX); + boolean isPhone = !isEmail && userFlag.matches(ValidateUserUtil.PHONE_REGEX); LambdaQueryWrapper wrapper = Wrappers.lambdaQuery(); if (isEmail) { wrapper.eq(User::getEmail, userFlag); } else if (isPhone) { wrapper.eq(User::getPhone, userFlag); } else { - // 默认学号登录 - wrapper.eq(User::getStudentId, userFlag); + //默认用户名登录 + wrapper.eq(User::getUsername, userFlag); } User user = userMapper.selectOne(wrapper); if (user == null) { @@ -89,9 +91,8 @@ public class UserLoginServiceImpl extends ServiceImpl implemen public UserDTO login(UserLoginDTO userLoginDTO) { String userFlag = userLoginDTO.getUserFlag(); String password = userLoginDTO.getPassword(); - // TODO 选择密码加密格式 User user = getUserByFlag(userFlag); - if(!user.getPassword().equals(password)) { + if (!BCrypt.checkpw(password, user.getPassword())) { throw new UserException("密码错误"); } UserDTO userDTO = UserDTO.builder() @@ -115,11 +116,14 @@ public class UserLoginServiceImpl extends ServiceImpl implemen /** * 登出 - * @param accessToken */ @Override - public void logout(String accessToken) { + public void logout(HttpServletRequest request) { + String accessToken = request.getHeader("Authorization"); Long userId = UserContext.getUserId(); + if(userId == null){ + throw new UserException("用户不存在"); + } // 删除refreshToken String refreshKey = REFRESH_TOKEN_PREFIX + userId; redisUtil.delete(refreshKey); @@ -141,8 +145,11 @@ public class UserLoginServiceImpl extends ServiceImpl implemen @Transactional(rollbackFor = Exception.class) public UserDTO register(UserRegisterDTO userRegisterDTO) { // 校验注册参数 - validateParameterUtil.validateUser(userRegisterDTO); + validateUserUtil.validateRegisterUser(userRegisterDTO); User user = BeanUtil.copyProperties(userRegisterDTO, User.class); + // 加密 + String encodedPassword = BCrypt.hashpw(userRegisterDTO.getPassword(), BCrypt.gensalt()); + user.setPassword(encodedPassword); user.setCreateTime(LocalDateTime.now()); user.setUpdateTime(LocalDateTime.now()); save(user); diff --git a/珞珈岛-项目相关文件/luojia-island/service/src/main/java/com/luojia_channel/modules/user/utils/ValidateParameterUtil.java b/珞珈岛-项目相关文件/luojia-island/service/src/main/java/com/luojia_channel/modules/user/utils/ValidateUserUtil.java similarity index 71% rename from 珞珈岛-项目相关文件/luojia-island/service/src/main/java/com/luojia_channel/modules/user/utils/ValidateParameterUtil.java rename to 珞珈岛-项目相关文件/luojia-island/service/src/main/java/com/luojia_channel/modules/user/utils/ValidateUserUtil.java index 917b187..a61d2d5 100644 --- a/珞珈岛-项目相关文件/luojia-island/service/src/main/java/com/luojia_channel/modules/user/utils/ValidateParameterUtil.java +++ b/珞珈岛-项目相关文件/luojia-island/service/src/main/java/com/luojia_channel/modules/user/utils/ValidateUserUtil.java @@ -3,6 +3,7 @@ package com.luojia_channel.modules.user.utils; import cn.hutool.core.util.StrUtil; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.luojia_channel.common.exception.UserException; +import com.luojia_channel.modules.user.dto.UserChangeInfoDTO; import com.luojia_channel.modules.user.dto.UserRegisterDTO; import com.luojia_channel.modules.user.entity.User; import com.luojia_channel.modules.user.mapper.UserMapper; @@ -11,12 +12,12 @@ import org.springframework.stereotype.Component; @Component @RequiredArgsConstructor -public class ValidateParameterUtil { +public class ValidateUserUtil { // 参数校验正则表达式,学号校验不一定正确 public static final String PHONE_REGEX = "^1([38][0-9]|4[579]|5[0-3,5-9]|6[6]|7[0135678]|9[89])\\d{8}$"; public static final String EMAIL_REGEX = "^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\\.[a-zA-Z0-9_-]+)+$"; public static final String STUDENTID_REGEX = "^(?:\\d{12,13}|[A-Z]{2}\\d{8,10})$"; - public static final String PASSWORD_REGEX = "^\\w{4,32}$"; + public static final String PASSWORD_REGEX = "^\\w{6,32}$"; private final UserMapper userMapper; /** @@ -24,7 +25,7 @@ public class ValidateParameterUtil { * 可能需要前端在用户选择注册方式时只暴露出一个文本框 * @param userRegisterDTO */ - public void validateUser(UserRegisterDTO userRegisterDTO) { + public void validateRegisterUser(UserRegisterDTO userRegisterDTO) { String username = userRegisterDTO.getUsername(); String password = userRegisterDTO.getPassword(); String phone = userRegisterDTO.getPhone(); @@ -54,15 +55,12 @@ public class ValidateParameterUtil { // 格式校验,未来更改用户信息时可能使用 - // TODO 实际上,用户更改信息校验时数据库查询的不是是否存在,而是是否等于要修改的用户 public void validateFormats(UserRegisterDTO userRegisterDTO) { String username = userRegisterDTO.getUsername(); String password = userRegisterDTO.getPassword(); String phone = userRegisterDTO.getPhone(); String email = userRegisterDTO.getEmail(); String studentId = userRegisterDTO.getStudentId(); - String captcha = userRegisterDTO.getCaptcha(); - // 仅对非空字段做格式校验 if (userMapper.exists(Wrappers.lambdaQuery() .eq(User::getUsername, username))) { @@ -71,11 +69,31 @@ public class ValidateParameterUtil { if(!password.matches(PASSWORD_REGEX)){ throw new UserException("密码格式错误"); } + validateUserFlag(phone, email, studentId, null); + } + + public void validateFormats(UserChangeInfoDTO userChangeInfoDTO, Long currentUserId){ + String username = userChangeInfoDTO.getUsername(); + String phone = userChangeInfoDTO.getPhone(); + String email = userChangeInfoDTO.getEmail(); + String studentId = userChangeInfoDTO.getStudentId(); + // String college = userChangeInfoDTO.getCollege(); + if (userMapper.exists(Wrappers.lambdaQuery() + .eq(User::getUsername, userChangeInfoDTO.getUsername()) + .ne(currentUserId != null, User::getId, currentUserId))) { + throw new UserException("用户名已被使用"); + } + + validateUserFlag(phone, email, studentId, currentUserId); + } + + private void validateUserFlag(String phone, String email, String studentId, Long currentUserId) { if(StrUtil.isNotBlank(phone)){ if(!phone.matches(PHONE_REGEX)) throw new UserException("手机号格式错误"); if (userMapper.exists(Wrappers.lambdaQuery() - .eq(User::getPhone, phone))) { + .eq(User::getPhone, phone) + .ne(currentUserId != null, User::getId, currentUserId))) { throw new UserException("手机已存在"); } } @@ -83,7 +101,8 @@ public class ValidateParameterUtil { if(!email.matches(EMAIL_REGEX)) throw new UserException("邮箱格式错误"); if (userMapper.exists(Wrappers.lambdaQuery() - .eq(User::getEmail, email))) { + .eq(User::getEmail, email) + .ne(currentUserId != null, User::getId, currentUserId))) { throw new UserException("邮箱已存在"); } } @@ -91,7 +110,8 @@ public class ValidateParameterUtil { if(!studentId.matches(STUDENTID_REGEX)) throw new UserException("学号格式错误"); if (userMapper.exists(Wrappers.lambdaQuery() - .eq(User::getStudentId, studentId))) { + .eq(User::getStudentId, studentId) + .ne(currentUserId != null, User::getId, currentUserId))) { throw new UserException("学号已存在"); } } diff --git a/珞珈岛-项目相关文件/luojia-island/service/src/main/resources/application-local.yaml b/珞珈岛-项目相关文件/luojia-island/service/src/main/resources/application-local.yaml index 13f3ed3..8ded89f 100644 --- a/珞珈岛-项目相关文件/luojia-island/service/src/main/resources/application-local.yaml +++ b/珞珈岛-项目相关文件/luojia-island/service/src/main/resources/application-local.yaml @@ -1,22 +1,8 @@ # 本地开发环境 -#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! - lj: db: host: localhost - passwprd: 123456 + password: 123456 redis: host: localhost port: 6379 @@ -25,4 +11,9 @@ lj: host: localhost port: 15672 username: root - password: 123456 \ No newline at end of file + password: 123456 + minio: + endpoint: http://localhost:9000 + accessKey: minioadmin + secretKey: minioadmin + diff --git a/珞珈岛-项目相关文件/luojia-island/service/src/main/resources/application.yaml b/珞珈岛-项目相关文件/luojia-island/service/src/main/resources/application.yaml index 9b4645d..2baa5e6 100644 --- a/珞珈岛-项目相关文件/luojia-island/service/src/main/resources/application.yaml +++ b/珞珈岛-项目相关文件/luojia-island/service/src/main/resources/application.yaml @@ -36,6 +36,11 @@ spring: concurrency: 5 max-concurrency: 10 prefetch: 1 +# minio配置 +minio: + endpoint: ${lj.minio.endpoint} + accessKey: ${lj.minio.accessKey} + secretKey: ${lj.minio.secretKey} mybatis-plus: configuration: diff --git a/珞珈岛-项目相关文件/luojia-island/service/src/main/resources/db/luojia_channel.sql b/珞珈岛-项目相关文件/luojia-island/service/src/main/resources/db/luojia_channel.sql index 94bfe34..7be5cea 100644 --- a/珞珈岛-项目相关文件/luojia-island/service/src/main/resources/db/luojia_channel.sql +++ b/珞珈岛-项目相关文件/luojia-island/service/src/main/resources/db/luojia_channel.sql @@ -1,4 +1,6 @@ +## 用户表 +DROP TABLE IF EXISTS `user`; CREATE TABLE `user` ( `id` BIGINT PRIMARY KEY AUTO_INCREMENT COMMENT '主键ID', `username` VARCHAR(50) NOT NULL COMMENT '用户名', @@ -7,6 +9,7 @@ CREATE TABLE `user` ( `phone` VARCHAR(20) UNIQUE COMMENT '注册手机号', `email` VARCHAR(100) UNIQUE COMMENT '邮箱', `student_id` VARCHAR(20) UNIQUE COMMENT '学号', + `avatar` VARCHAR(255) COMMENT '头像URL', `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 '更新时间', @@ -18,4 +21,85 @@ CREATE TABLE `user` ( 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 +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户表'; + +## 文件表 +DROP TABLE IF EXISTS `lj_file`; +CREATE TABLE `lj_file` ( + `id` BIGINT PRIMARY KEY AUTO_INCREMENT COMMENT '主键ID', + `file_name` VARCHAR(255) NOT NULL COMMENT '文件名', + `file_url` VARCHAR(512) NOT NULL COMMENT 'MinIO存储路径', + `file_size` BIGINT NOT NULL COMMENT '文件大小(字节)', + `file_md5` VARCHAR(32) NOT NULL COMMENT '文件MD5值', + `file_type` VARCHAR(50) NOT NULL COMMENT '文件类型(image/video)', + `file_status` INT NOT NULL DEFAULT 0 COMMENT '文件状态(0:正在上传, 1:上传成功, 2:失败或删除, 3:审核中)', + `user_id` BIGINT NOT NULL COMMENT '上传用户ID', + `create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `update_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间' +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='文件存储表'; + +## 图文帖子表 +DROP TABLE IF EXISTS `post`; +CREATE TABLE `post` ( + `id` BIGINT PRIMARY KEY AUTO_INCREMENT COMMENT '主键ID', + `title` VARCHAR(255) NOT NULL COMMENT '标题', + `cover_id` BIGINT NOT NULL COMMENT '封面图片ID', + `content` TEXT NOT NULL COMMENT '文字内容', + `like_count` INT DEFAULT 0 COMMENT '点赞数', + `comment_count` INT DEFAULT 0 COMMENT '评论数', + `favorite_count` INT DEFAULT 0 COMMENT '收藏数', + `user_id` BIGINT NOT NULL COMMENT '发布用户ID', + `create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `update_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + FOREIGN KEY (`user_id`) REFERENCES `user`(`id`), + FOREIGN KEY (`cover_id`) REFERENCES `lj_file`(`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='图文帖子表'; + +## 帖子图片关联表 +DROP TABLE IF EXISTS `post_image`; +CREATE TABLE `post_image` ( + `id` BIGINT PRIMARY KEY AUTO_INCREMENT COMMENT '主键ID', + `post_id` BIGINT NOT NULL COMMENT '图文帖子ID', + `file_id` BIGINT NOT NULL COMMENT '图片文件ID', + FOREIGN KEY (`post_id`) REFERENCES `post`(`id`), + FOREIGN KEY (`file_id`) REFERENCES `lj_file`(`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='图文帖子与图片关联表'; + +## 视频表 +DROP TABLE IF EXISTS `video`; +CREATE TABLE `video` ( + `id` BIGINT PRIMARY KEY AUTO_INCREMENT COMMENT '主键ID', + `title` VARCHAR(255) NOT NULL COMMENT '标题', + `cover_id` BIGINT NOT NULL COMMENT '封面图片ID', + `video_file_id` BIGINT NOT NULL COMMENT '视频文件ID', + `play_count` BIGINT DEFAULT 0 COMMENT '播放次数', + `like_count` INT DEFAULT 0 COMMENT '点赞数', + `comment_count` INT DEFAULT 0 COMMENT '评论数', + `favorite_count` INT DEFAULT 0 COMMENT '收藏数', + `user_id` BIGINT NOT NULL COMMENT '发布用户ID', + `duration` INT NOT NULL COMMENT '视频时长(秒)', + `category` VARCHAR(50) NOT NULL COMMENT '分类(如“音乐”、“游戏”)', + `tags` VARCHAR(255) COMMENT '标签(逗号分隔)', + `create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `update_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + FOREIGN KEY (`user_id`) REFERENCES `user`(`id`), + FOREIGN KEY (`cover_id`) REFERENCES `lj_file`(`id`), + FOREIGN KEY (`video_file_id`) REFERENCES `lj_file`(`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='视频表'; + +## 评论表 +DROP TABLE IF EXISTS `comment`; +CREATE TABLE `comment` ( + `id` BIGINT PRIMARY KEY AUTO_INCREMENT COMMENT '主键ID', + `content` TEXT NOT NULL COMMENT '评论内容', + `user_id` BIGINT NOT NULL COMMENT '评论用户ID', + `post_type` VARCHAR(20) NOT NULL COMMENT '帖子类型(post/video)', + `post_id` BIGINT NOT NULL COMMENT '关联的帖子ID', + `parent_comment_id` BIGINT COMMENT '父评论ID', + `top_id` BIGINT COMMENT '顶层评论ID', + `create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `update_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + FOREIGN KEY (`user_id`) REFERENCES `user`(`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='评论表'; + + diff --git a/珞珈岛-项目相关文件/luojia-island/service/src/test/java/com/luojia_channel/FileServiceTests.java b/珞珈岛-项目相关文件/luojia-island/service/src/test/java/com/luojia_channel/FileServiceTests.java new file mode 100644 index 0000000..f2723e1 --- /dev/null +++ b/珞珈岛-项目相关文件/luojia-island/service/src/test/java/com/luojia_channel/FileServiceTests.java @@ -0,0 +1,96 @@ +package com.luojia_channel; + +import com.luojia_channel.common.utils.RedisUtil; +import com.luojia_channel.modules.file.dto.CompleteUploadDTO; +import com.luojia_channel.modules.file.dto.UploadChunkDTO; +import com.luojia_channel.modules.file.service.FileService; +import com.luojia_channel.modules.file.service.impl.FileServiceImpl; +import com.luojia_channel.modules.file.utils.GeneratePathUtil; +import com.luojia_channel.modules.file.utils.ValidateFileUtil; +import io.minio.MinioClient; +import io.minio.PutObjectArgs; +import io.minio.RemoveObjectArgs; +import org.junit.jupiter.api.Test; +import org.mockito.Mock; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.mock.web.MockMultipartFile; + +import java.util.concurrent.TimeUnit; + +import static com.luojia_channel.modules.file.constants.FileConstant.CHUNK_PREFIX; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.ArgumentMatchers.*; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +@SpringBootTest +public class FileServiceTests { + @Autowired + private FileServiceImpl fileService; + + @Autowired + private MinioClient minioClient; // 模拟 MinIO 客户端 + + @Autowired + private RedisUtil redisUtil; // 模拟 Redis + + @Autowired + private ValidateFileUtil validateFileUtil; // 模拟验证工具 + + @Autowired + private GeneratePathUtil generatePathUtil; // 模拟路径生成工具 + + + // 其他辅助变量(如测试文件内容、MD5 等) + private static final String TEST_FILE_NAME = "test.jpg"; + private static final String TEST_FILE_MD5 = "test_md5"; + private static final String TEST_FILE_CONTENT = "test_content"; + private static final int TOTAL_CHUNKS = 2; + @Test + public void testUploadChunk_NormalCase() throws Exception { + // 准备测试数据 + MockMultipartFile file = new MockMultipartFile( + "file", + TEST_FILE_NAME, + "image", + TEST_FILE_CONTENT.getBytes() + ); + UploadChunkDTO chunkDTO = UploadChunkDTO.builder().build(); + chunkDTO.setFile(file); + chunkDTO.setFileMd5(TEST_FILE_MD5); + chunkDTO.setChunkNumber(0); + chunkDTO.setTotalChunks(TOTAL_CHUNKS); + chunkDTO.setFileType("image"); + chunkDTO.setFileName(TEST_FILE_NAME); + + fileService.uploadChunk(chunkDTO); + + } + + @Test + public void testCompleteUpload_Success() throws Exception { + // 准备合并前的环境 + CompleteUploadDTO completeDTO = CompleteUploadDTO.builder().build(); + completeDTO.setFileMd5(TEST_FILE_MD5); + completeDTO.setTotalChunks(TOTAL_CHUNKS); + completeDTO.setFileType("image"); + completeDTO.setFileName(TEST_FILE_NAME); + //fileService.completeUpload(completeDTO); + fileService.deleteChunks(TEST_FILE_MD5); + //fileService.deleteBucket("chunks"); + /* + try { + minioClient.removeObject( + RemoveObjectArgs.builder() + .bucket("chunks") + .object("test_md5/chunk_0") + .build() + ); + System.out.println("删除成功"); + } catch (Exception e) { + System.err.println("删除失败: " + e.getMessage()); + } + */ + } +} diff --git a/珞珈岛-项目相关文件/luojia-island/service/src/test/java/com/luojia_channel/LuojiaChannelApplicationTests.java b/珞珈岛-项目相关文件/luojia-island/service/src/test/java/com/luojia_channel/LuojiaChannelApplicationTests.java new file mode 100644 index 0000000..b82b9d8 --- /dev/null +++ b/珞珈岛-项目相关文件/luojia-island/service/src/test/java/com/luojia_channel/LuojiaChannelApplicationTests.java @@ -0,0 +1,9 @@ +package com.luojia_channel; + +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest +class LuojiaChannelApplicationTests { + + +} diff --git a/珞珈岛-项目相关文件/luojia-island/service/target/classes/application-local.yaml b/珞珈岛-项目相关文件/luojia-island/service/target/classes/application-local.yaml index 13f3ed3..8ded89f 100644 --- a/珞珈岛-项目相关文件/luojia-island/service/target/classes/application-local.yaml +++ b/珞珈岛-项目相关文件/luojia-island/service/target/classes/application-local.yaml @@ -1,22 +1,8 @@ # 本地开发环境 -#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! - lj: db: host: localhost - passwprd: 123456 + password: 123456 redis: host: localhost port: 6379 @@ -25,4 +11,9 @@ lj: host: localhost port: 15672 username: root - password: 123456 \ No newline at end of file + password: 123456 + minio: + endpoint: http://localhost:9000 + accessKey: minioadmin + secretKey: minioadmin + diff --git a/珞珈岛-项目相关文件/luojia-island/service/target/classes/application.yaml b/珞珈岛-项目相关文件/luojia-island/service/target/classes/application.yaml index 9b4645d..2baa5e6 100644 --- a/珞珈岛-项目相关文件/luojia-island/service/target/classes/application.yaml +++ b/珞珈岛-项目相关文件/luojia-island/service/target/classes/application.yaml @@ -36,6 +36,11 @@ spring: concurrency: 5 max-concurrency: 10 prefetch: 1 +# minio配置 +minio: + endpoint: ${lj.minio.endpoint} + accessKey: ${lj.minio.accessKey} + secretKey: ${lj.minio.secretKey} mybatis-plus: configuration: diff --git a/珞珈岛-项目相关文件/luojia-island/service/target/classes/com/luojia_channel/LuojiaChannelApplication.class b/珞珈岛-项目相关文件/luojia-island/service/target/classes/com/luojia_channel/LuojiaChannelApplication.class index 67437d2..dbe2f8a 100644 Binary files a/珞珈岛-项目相关文件/luojia-island/service/target/classes/com/luojia_channel/LuojiaChannelApplication.class and b/珞珈岛-项目相关文件/luojia-island/service/target/classes/com/luojia_channel/LuojiaChannelApplication.class differ diff --git a/珞珈岛-项目相关文件/luojia-island/service/target/classes/com/luojia_channel/modules/file/config/MinioConfig.class b/珞珈岛-项目相关文件/luojia-island/service/target/classes/com/luojia_channel/modules/file/config/MinioConfig.class new file mode 100644 index 0000000..09527fa Binary files /dev/null and b/珞珈岛-项目相关文件/luojia-island/service/target/classes/com/luojia_channel/modules/file/config/MinioConfig.class differ diff --git a/珞珈岛-项目相关文件/luojia-island/service/target/classes/com/luojia_channel/modules/file/constants/FileConstant.class b/珞珈岛-项目相关文件/luojia-island/service/target/classes/com/luojia_channel/modules/file/constants/FileConstant.class new file mode 100644 index 0000000..9db4451 Binary files /dev/null and b/珞珈岛-项目相关文件/luojia-island/service/target/classes/com/luojia_channel/modules/file/constants/FileConstant.class differ diff --git a/珞珈岛-项目相关文件/luojia-island/service/target/classes/com/luojia_channel/modules/file/dto/CompleteUploadDTO$CompleteUploadDTOBuilder.class b/珞珈岛-项目相关文件/luojia-island/service/target/classes/com/luojia_channel/modules/file/dto/CompleteUploadDTO$CompleteUploadDTOBuilder.class new file mode 100644 index 0000000..5fdce66 Binary files /dev/null and b/珞珈岛-项目相关文件/luojia-island/service/target/classes/com/luojia_channel/modules/file/dto/CompleteUploadDTO$CompleteUploadDTOBuilder.class differ diff --git a/珞珈岛-项目相关文件/luojia-island/service/target/classes/com/luojia_channel/modules/file/dto/CompleteUploadDTO.class b/珞珈岛-项目相关文件/luojia-island/service/target/classes/com/luojia_channel/modules/file/dto/CompleteUploadDTO.class new file mode 100644 index 0000000..e7e5572 Binary files /dev/null and b/珞珈岛-项目相关文件/luojia-island/service/target/classes/com/luojia_channel/modules/file/dto/CompleteUploadDTO.class differ diff --git a/珞珈岛-项目相关文件/luojia-island/service/target/classes/com/luojia_channel/modules/file/dto/UploadChunkDTO$UploadChunkDTOBuilder.class b/珞珈岛-项目相关文件/luojia-island/service/target/classes/com/luojia_channel/modules/file/dto/UploadChunkDTO$UploadChunkDTOBuilder.class new file mode 100644 index 0000000..2190746 Binary files /dev/null and b/珞珈岛-项目相关文件/luojia-island/service/target/classes/com/luojia_channel/modules/file/dto/UploadChunkDTO$UploadChunkDTOBuilder.class differ diff --git a/珞珈岛-项目相关文件/luojia-island/service/target/classes/com/luojia_channel/modules/file/dto/UploadChunkDTO.class b/珞珈岛-项目相关文件/luojia-island/service/target/classes/com/luojia_channel/modules/file/dto/UploadChunkDTO.class new file mode 100644 index 0000000..7158ade Binary files /dev/null and b/珞珈岛-项目相关文件/luojia-island/service/target/classes/com/luojia_channel/modules/file/dto/UploadChunkDTO.class differ diff --git a/珞珈岛-项目相关文件/luojia-island/service/target/classes/com/luojia_channel/modules/file/dto/UploadFileDTO$UploadFileDTOBuilder.class b/珞珈岛-项目相关文件/luojia-island/service/target/classes/com/luojia_channel/modules/file/dto/UploadFileDTO$UploadFileDTOBuilder.class new file mode 100644 index 0000000..af5889c Binary files /dev/null and b/珞珈岛-项目相关文件/luojia-island/service/target/classes/com/luojia_channel/modules/file/dto/UploadFileDTO$UploadFileDTOBuilder.class differ diff --git a/珞珈岛-项目相关文件/luojia-island/service/target/classes/com/luojia_channel/modules/file/dto/UploadFileDTO.class b/珞珈岛-项目相关文件/luojia-island/service/target/classes/com/luojia_channel/modules/file/dto/UploadFileDTO.class new file mode 100644 index 0000000..10fb2ee Binary files /dev/null and b/珞珈岛-项目相关文件/luojia-island/service/target/classes/com/luojia_channel/modules/file/dto/UploadFileDTO.class differ diff --git a/珞珈岛-项目相关文件/luojia-island/service/target/classes/com/luojia_channel/modules/file/entity/LjFile$LjFileBuilder.class b/珞珈岛-项目相关文件/luojia-island/service/target/classes/com/luojia_channel/modules/file/entity/LjFile$LjFileBuilder.class new file mode 100644 index 0000000..b7bf51f Binary files /dev/null and b/珞珈岛-项目相关文件/luojia-island/service/target/classes/com/luojia_channel/modules/file/entity/LjFile$LjFileBuilder.class differ diff --git a/珞珈岛-项目相关文件/luojia-island/service/target/classes/com/luojia_channel/modules/file/entity/LjFile.class b/珞珈岛-项目相关文件/luojia-island/service/target/classes/com/luojia_channel/modules/file/entity/LjFile.class new file mode 100644 index 0000000..f5d7a2e Binary files /dev/null and b/珞珈岛-项目相关文件/luojia-island/service/target/classes/com/luojia_channel/modules/file/entity/LjFile.class differ diff --git a/珞珈岛-项目相关文件/luojia-island/service/target/classes/com/luojia_channel/modules/file/mapper/LjFileMapper.class b/珞珈岛-项目相关文件/luojia-island/service/target/classes/com/luojia_channel/modules/file/mapper/LjFileMapper.class new file mode 100644 index 0000000..8b0e683 Binary files /dev/null and b/珞珈岛-项目相关文件/luojia-island/service/target/classes/com/luojia_channel/modules/file/mapper/LjFileMapper.class differ diff --git a/珞珈岛-项目相关文件/luojia-island/service/target/classes/com/luojia_channel/modules/file/service/FileService.class b/珞珈岛-项目相关文件/luojia-island/service/target/classes/com/luojia_channel/modules/file/service/FileService.class new file mode 100644 index 0000000..4c6f008 Binary files /dev/null and b/珞珈岛-项目相关文件/luojia-island/service/target/classes/com/luojia_channel/modules/file/service/FileService.class differ diff --git a/珞珈岛-项目相关文件/luojia-island/service/target/classes/com/luojia_channel/modules/file/service/impl/FileServiceImpl.class b/珞珈岛-项目相关文件/luojia-island/service/target/classes/com/luojia_channel/modules/file/service/impl/FileServiceImpl.class new file mode 100644 index 0000000..a14a8f9 Binary files /dev/null and b/珞珈岛-项目相关文件/luojia-island/service/target/classes/com/luojia_channel/modules/file/service/impl/FileServiceImpl.class differ diff --git a/珞珈岛-项目相关文件/luojia-island/service/target/classes/com/luojia_channel/modules/file/utils/GeneratePathUtil.class b/珞珈岛-项目相关文件/luojia-island/service/target/classes/com/luojia_channel/modules/file/utils/GeneratePathUtil.class new file mode 100644 index 0000000..ae7534e Binary files /dev/null and b/珞珈岛-项目相关文件/luojia-island/service/target/classes/com/luojia_channel/modules/file/utils/GeneratePathUtil.class differ diff --git a/珞珈岛-项目相关文件/luojia-island/service/target/classes/com/luojia_channel/modules/file/utils/ValidateFileUtil.class b/珞珈岛-项目相关文件/luojia-island/service/target/classes/com/luojia_channel/modules/file/utils/ValidateFileUtil.class new file mode 100644 index 0000000..4f738ff Binary files /dev/null and b/珞珈岛-项目相关文件/luojia-island/service/target/classes/com/luojia_channel/modules/file/utils/ValidateFileUtil.class differ diff --git a/珞珈岛-项目相关文件/luojia-island/service/target/classes/com/luojia_channel/modules/user/Config/SecurityConfig.class b/珞珈岛-项目相关文件/luojia-island/service/target/classes/com/luojia_channel/modules/user/Config/SecurityConfig.class deleted file mode 100644 index c4cf038..0000000 Binary files a/珞珈岛-项目相关文件/luojia-island/service/target/classes/com/luojia_channel/modules/user/Config/SecurityConfig.class and /dev/null differ diff --git a/珞珈岛-项目相关文件/luojia-island/service/target/classes/com/luojia_channel/modules/user/constant/UserConstant.class b/珞珈岛-项目相关文件/luojia-island/service/target/classes/com/luojia_channel/modules/user/constant/UserConstant.class index 948c368..e26cf5a 100644 Binary files a/珞珈岛-项目相关文件/luojia-island/service/target/classes/com/luojia_channel/modules/user/constant/UserConstant.class and b/珞珈岛-项目相关文件/luojia-island/service/target/classes/com/luojia_channel/modules/user/constant/UserConstant.class differ diff --git a/珞珈岛-项目相关文件/luojia-island/service/target/classes/com/luojia_channel/modules/user/controller/UserInfoController.class b/珞珈岛-项目相关文件/luojia-island/service/target/classes/com/luojia_channel/modules/user/controller/UserInfoController.class index 1c5bb55..ada5790 100644 Binary files a/珞珈岛-项目相关文件/luojia-island/service/target/classes/com/luojia_channel/modules/user/controller/UserInfoController.class and b/珞珈岛-项目相关文件/luojia-island/service/target/classes/com/luojia_channel/modules/user/controller/UserInfoController.class differ diff --git a/珞珈岛-项目相关文件/luojia-island/service/target/classes/com/luojia_channel/modules/user/controller/UserLoginController.class b/珞珈岛-项目相关文件/luojia-island/service/target/classes/com/luojia_channel/modules/user/controller/UserLoginController.class index fa88a6c..87c8815 100644 Binary files a/珞珈岛-项目相关文件/luojia-island/service/target/classes/com/luojia_channel/modules/user/controller/UserLoginController.class and b/珞珈岛-项目相关文件/luojia-island/service/target/classes/com/luojia_channel/modules/user/controller/UserLoginController.class differ diff --git a/珞珈岛-项目相关文件/luojia-island/service/target/classes/com/luojia_channel/modules/user/dto/UserChangeInfoDTO.class b/珞珈岛-项目相关文件/luojia-island/service/target/classes/com/luojia_channel/modules/user/dto/UserChangeInfoDTO.class new file mode 100644 index 0000000..cce978b Binary files /dev/null and b/珞珈岛-项目相关文件/luojia-island/service/target/classes/com/luojia_channel/modules/user/dto/UserChangeInfoDTO.class differ diff --git a/珞珈岛-项目相关文件/luojia-island/service/target/classes/com/luojia_channel/modules/user/dto/UserLoginDTO.class b/珞珈岛-项目相关文件/luojia-island/service/target/classes/com/luojia_channel/modules/user/dto/UserLoginDTO.class index c304826..fc6b255 100644 Binary files a/珞珈岛-项目相关文件/luojia-island/service/target/classes/com/luojia_channel/modules/user/dto/UserLoginDTO.class and b/珞珈岛-项目相关文件/luojia-island/service/target/classes/com/luojia_channel/modules/user/dto/UserLoginDTO.class differ diff --git a/珞珈岛-项目相关文件/luojia-island/service/target/classes/com/luojia_channel/modules/user/dto/UserRegisterDTO.class b/珞珈岛-项目相关文件/luojia-island/service/target/classes/com/luojia_channel/modules/user/dto/UserRegisterDTO.class index 00e0e31..a30aaea 100644 Binary files a/珞珈岛-项目相关文件/luojia-island/service/target/classes/com/luojia_channel/modules/user/dto/UserRegisterDTO.class and b/珞珈岛-项目相关文件/luojia-island/service/target/classes/com/luojia_channel/modules/user/dto/UserRegisterDTO.class differ diff --git a/珞珈岛-项目相关文件/luojia-island/service/target/classes/com/luojia_channel/modules/user/entity/User.class b/珞珈岛-项目相关文件/luojia-island/service/target/classes/com/luojia_channel/modules/user/entity/User.class index 5d6f887..2a6f89d 100644 Binary files a/珞珈岛-项目相关文件/luojia-island/service/target/classes/com/luojia_channel/modules/user/entity/User.class and b/珞珈岛-项目相关文件/luojia-island/service/target/classes/com/luojia_channel/modules/user/entity/User.class differ diff --git a/珞珈岛-项目相关文件/luojia-island/service/target/classes/com/luojia_channel/modules/user/mapper/UserMapper.class b/珞珈岛-项目相关文件/luojia-island/service/target/classes/com/luojia_channel/modules/user/mapper/UserMapper.class index ef3db83..2d727d7 100644 Binary files a/珞珈岛-项目相关文件/luojia-island/service/target/classes/com/luojia_channel/modules/user/mapper/UserMapper.class and b/珞珈岛-项目相关文件/luojia-island/service/target/classes/com/luojia_channel/modules/user/mapper/UserMapper.class differ diff --git a/珞珈岛-项目相关文件/luojia-island/service/target/classes/com/luojia_channel/modules/user/service/UserInfoService.class b/珞珈岛-项目相关文件/luojia-island/service/target/classes/com/luojia_channel/modules/user/service/UserInfoService.class index f2f64e3..d9a3971 100644 Binary files a/珞珈岛-项目相关文件/luojia-island/service/target/classes/com/luojia_channel/modules/user/service/UserInfoService.class and b/珞珈岛-项目相关文件/luojia-island/service/target/classes/com/luojia_channel/modules/user/service/UserInfoService.class differ diff --git a/珞珈岛-项目相关文件/luojia-island/service/target/classes/com/luojia_channel/modules/user/service/UserLoginService.class b/珞珈岛-项目相关文件/luojia-island/service/target/classes/com/luojia_channel/modules/user/service/UserLoginService.class index c31f63a..496c49c 100644 Binary files a/珞珈岛-项目相关文件/luojia-island/service/target/classes/com/luojia_channel/modules/user/service/UserLoginService.class and b/珞珈岛-项目相关文件/luojia-island/service/target/classes/com/luojia_channel/modules/user/service/UserLoginService.class differ diff --git a/珞珈岛-项目相关文件/luojia-island/service/target/classes/com/luojia_channel/modules/user/service/impl/UserInfoServiceImpl.class b/珞珈岛-项目相关文件/luojia-island/service/target/classes/com/luojia_channel/modules/user/service/impl/UserInfoServiceImpl.class index b791617..7ff4a45 100644 Binary files a/珞珈岛-项目相关文件/luojia-island/service/target/classes/com/luojia_channel/modules/user/service/impl/UserInfoServiceImpl.class and b/珞珈岛-项目相关文件/luojia-island/service/target/classes/com/luojia_channel/modules/user/service/impl/UserInfoServiceImpl.class differ diff --git a/珞珈岛-项目相关文件/luojia-island/service/target/classes/com/luojia_channel/modules/user/service/impl/UserLoginServiceImpl.class b/珞珈岛-项目相关文件/luojia-island/service/target/classes/com/luojia_channel/modules/user/service/impl/UserLoginServiceImpl.class index 57374aa..59625b9 100644 Binary files a/珞珈岛-项目相关文件/luojia-island/service/target/classes/com/luojia_channel/modules/user/service/impl/UserLoginServiceImpl.class and b/珞珈岛-项目相关文件/luojia-island/service/target/classes/com/luojia_channel/modules/user/service/impl/UserLoginServiceImpl.class differ diff --git a/珞珈岛-项目相关文件/luojia-island/service/target/classes/com/luojia_channel/modules/user/utils/AnonymousUserUtil.class b/珞珈岛-项目相关文件/luojia-island/service/target/classes/com/luojia_channel/modules/user/utils/AnonymousUserUtil.class index c561a98..99b7971 100644 Binary files a/珞珈岛-项目相关文件/luojia-island/service/target/classes/com/luojia_channel/modules/user/utils/AnonymousUserUtil.class and b/珞珈岛-项目相关文件/luojia-island/service/target/classes/com/luojia_channel/modules/user/utils/AnonymousUserUtil.class differ diff --git a/珞珈岛-项目相关文件/luojia-island/service/target/classes/com/luojia_channel/modules/user/utils/ValidateParameterUtil.class b/珞珈岛-项目相关文件/luojia-island/service/target/classes/com/luojia_channel/modules/user/utils/ValidateParameterUtil.class deleted file mode 100644 index ecd06d1..0000000 Binary files a/珞珈岛-项目相关文件/luojia-island/service/target/classes/com/luojia_channel/modules/user/utils/ValidateParameterUtil.class and /dev/null differ diff --git a/珞珈岛-项目相关文件/luojia-island/service/target/classes/com/luojia_channel/modules/user/utils/ValidateUserUtil.class b/珞珈岛-项目相关文件/luojia-island/service/target/classes/com/luojia_channel/modules/user/utils/ValidateUserUtil.class new file mode 100644 index 0000000..0a61216 Binary files /dev/null and b/珞珈岛-项目相关文件/luojia-island/service/target/classes/com/luojia_channel/modules/user/utils/ValidateUserUtil.class differ diff --git a/珞珈岛-项目相关文件/luojia-island/service/target/classes/db/luojia_channel.sql b/珞珈岛-项目相关文件/luojia-island/service/target/classes/db/luojia_channel.sql index 94bfe34..7be5cea 100644 --- a/珞珈岛-项目相关文件/luojia-island/service/target/classes/db/luojia_channel.sql +++ b/珞珈岛-项目相关文件/luojia-island/service/target/classes/db/luojia_channel.sql @@ -1,4 +1,6 @@ +## 用户表 +DROP TABLE IF EXISTS `user`; CREATE TABLE `user` ( `id` BIGINT PRIMARY KEY AUTO_INCREMENT COMMENT '主键ID', `username` VARCHAR(50) NOT NULL COMMENT '用户名', @@ -7,6 +9,7 @@ CREATE TABLE `user` ( `phone` VARCHAR(20) UNIQUE COMMENT '注册手机号', `email` VARCHAR(100) UNIQUE COMMENT '邮箱', `student_id` VARCHAR(20) UNIQUE COMMENT '学号', + `avatar` VARCHAR(255) COMMENT '头像URL', `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 '更新时间', @@ -18,4 +21,85 @@ CREATE TABLE `user` ( 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 +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户表'; + +## 文件表 +DROP TABLE IF EXISTS `lj_file`; +CREATE TABLE `lj_file` ( + `id` BIGINT PRIMARY KEY AUTO_INCREMENT COMMENT '主键ID', + `file_name` VARCHAR(255) NOT NULL COMMENT '文件名', + `file_url` VARCHAR(512) NOT NULL COMMENT 'MinIO存储路径', + `file_size` BIGINT NOT NULL COMMENT '文件大小(字节)', + `file_md5` VARCHAR(32) NOT NULL COMMENT '文件MD5值', + `file_type` VARCHAR(50) NOT NULL COMMENT '文件类型(image/video)', + `file_status` INT NOT NULL DEFAULT 0 COMMENT '文件状态(0:正在上传, 1:上传成功, 2:失败或删除, 3:审核中)', + `user_id` BIGINT NOT NULL COMMENT '上传用户ID', + `create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `update_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间' +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='文件存储表'; + +## 图文帖子表 +DROP TABLE IF EXISTS `post`; +CREATE TABLE `post` ( + `id` BIGINT PRIMARY KEY AUTO_INCREMENT COMMENT '主键ID', + `title` VARCHAR(255) NOT NULL COMMENT '标题', + `cover_id` BIGINT NOT NULL COMMENT '封面图片ID', + `content` TEXT NOT NULL COMMENT '文字内容', + `like_count` INT DEFAULT 0 COMMENT '点赞数', + `comment_count` INT DEFAULT 0 COMMENT '评论数', + `favorite_count` INT DEFAULT 0 COMMENT '收藏数', + `user_id` BIGINT NOT NULL COMMENT '发布用户ID', + `create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `update_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + FOREIGN KEY (`user_id`) REFERENCES `user`(`id`), + FOREIGN KEY (`cover_id`) REFERENCES `lj_file`(`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='图文帖子表'; + +## 帖子图片关联表 +DROP TABLE IF EXISTS `post_image`; +CREATE TABLE `post_image` ( + `id` BIGINT PRIMARY KEY AUTO_INCREMENT COMMENT '主键ID', + `post_id` BIGINT NOT NULL COMMENT '图文帖子ID', + `file_id` BIGINT NOT NULL COMMENT '图片文件ID', + FOREIGN KEY (`post_id`) REFERENCES `post`(`id`), + FOREIGN KEY (`file_id`) REFERENCES `lj_file`(`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='图文帖子与图片关联表'; + +## 视频表 +DROP TABLE IF EXISTS `video`; +CREATE TABLE `video` ( + `id` BIGINT PRIMARY KEY AUTO_INCREMENT COMMENT '主键ID', + `title` VARCHAR(255) NOT NULL COMMENT '标题', + `cover_id` BIGINT NOT NULL COMMENT '封面图片ID', + `video_file_id` BIGINT NOT NULL COMMENT '视频文件ID', + `play_count` BIGINT DEFAULT 0 COMMENT '播放次数', + `like_count` INT DEFAULT 0 COMMENT '点赞数', + `comment_count` INT DEFAULT 0 COMMENT '评论数', + `favorite_count` INT DEFAULT 0 COMMENT '收藏数', + `user_id` BIGINT NOT NULL COMMENT '发布用户ID', + `duration` INT NOT NULL COMMENT '视频时长(秒)', + `category` VARCHAR(50) NOT NULL COMMENT '分类(如“音乐”、“游戏”)', + `tags` VARCHAR(255) COMMENT '标签(逗号分隔)', + `create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `update_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + FOREIGN KEY (`user_id`) REFERENCES `user`(`id`), + FOREIGN KEY (`cover_id`) REFERENCES `lj_file`(`id`), + FOREIGN KEY (`video_file_id`) REFERENCES `lj_file`(`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='视频表'; + +## 评论表 +DROP TABLE IF EXISTS `comment`; +CREATE TABLE `comment` ( + `id` BIGINT PRIMARY KEY AUTO_INCREMENT COMMENT '主键ID', + `content` TEXT NOT NULL COMMENT '评论内容', + `user_id` BIGINT NOT NULL COMMENT '评论用户ID', + `post_type` VARCHAR(20) NOT NULL COMMENT '帖子类型(post/video)', + `post_id` BIGINT NOT NULL COMMENT '关联的帖子ID', + `parent_comment_id` BIGINT COMMENT '父评论ID', + `top_id` BIGINT COMMENT '顶层评论ID', + `create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `update_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + FOREIGN KEY (`user_id`) REFERENCES `user`(`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='评论表'; + + diff --git a/珞珈岛-项目相关文件/luojia-island/service/target/test-classes/com/luojia_channel/FileServiceTests.class b/珞珈岛-项目相关文件/luojia-island/service/target/test-classes/com/luojia_channel/FileServiceTests.class new file mode 100644 index 0000000..5793fba Binary files /dev/null and b/珞珈岛-项目相关文件/luojia-island/service/target/test-classes/com/luojia_channel/FileServiceTests.class differ diff --git a/珞珈岛-项目相关文件/luojia-island/service/target/test-classes/com/luojia_channel/LuojiaChannelApplicationTests.class b/珞珈岛-项目相关文件/luojia-island/service/target/test-classes/com/luojia_channel/LuojiaChannelApplicationTests.class new file mode 100644 index 0000000..9b8f13e Binary files /dev/null and b/珞珈岛-项目相关文件/luojia-island/service/target/test-classes/com/luojia_channel/LuojiaChannelApplicationTests.class differ diff --git a/珞珈岛-项目相关文件/luojia-island/vue-frontend/package-lock.json b/珞珈岛-项目相关文件/luojia-island/vue-frontend/package-lock.json index 5106798..52e13eb 100644 --- a/珞珈岛-项目相关文件/luojia-island/vue-frontend/package-lock.json +++ b/珞珈岛-项目相关文件/luojia-island/vue-frontend/package-lock.json @@ -10,7 +10,9 @@ "dependencies": { "axios": "^1.8.4", "core-js": "^3.8.3", - "vue": "^3.2.13" + "element-plus": "^2.9.8", + "vue": "^3.2.13", + "vue-router": "^4.5.0" }, "devDependencies": { "@babel/core": "^7.12.16", @@ -1759,6 +1761,15 @@ "node": ">=6.9.0" } }, + "node_modules/@ctrl/tinycolor": { + "version": "3.6.1", + "resolved": "https://registry.npmmirror.com/@ctrl/tinycolor/-/tinycolor-3.6.1.tgz", + "integrity": "sha512-SITSV6aIXsuVNV3f3O0f2n/cgyEDWoSqtZMYiAmcsYHydcKrOz3gUxB/iXd/Qf08+IZX4KpgNbvUdMBmWz+kcA==", + "license": "MIT", + "engines": { + "node": ">=10" + } + }, "node_modules/@discoveryjs/json-ext": { "version": "0.5.7", "resolved": "https://registry.npmmirror.com/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", @@ -1769,6 +1780,15 @@ "node": ">=10.0.0" } }, + "node_modules/@element-plus/icons-vue": { + "version": "2.3.1", + "resolved": "https://registry.npmmirror.com/@element-plus/icons-vue/-/icons-vue-2.3.1.tgz", + "integrity": "sha512-XxVUZv48RZAd87ucGS48jPf6pKu0yV5UCg9f4FFwtrYxXOwWuVJo6wOvSLKEoMQKjv8GsX/mhP6UsC1lRwbUWg==", + "license": "MIT", + "peerDependencies": { + "vue": "^3.2.0" + } + }, "node_modules/@eslint/eslintrc": { "version": "0.4.3", "resolved": "https://registry.npmmirror.com/@eslint/eslintrc/-/eslintrc-0.4.3.tgz", @@ -1829,6 +1849,31 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/@floating-ui/core": { + "version": "1.6.9", + "resolved": "https://registry.npmmirror.com/@floating-ui/core/-/core-1.6.9.tgz", + "integrity": "sha512-uMXCuQ3BItDUbAMhIXw7UPXRfAlOAvZzdK9BWpE60MCn+Svt3aLn9jsPTi/WNGlRUu2uI0v5S7JiIUsbsvh3fw==", + "license": "MIT", + "dependencies": { + "@floating-ui/utils": "^0.2.9" + } + }, + "node_modules/@floating-ui/dom": { + "version": "1.6.13", + "resolved": "https://registry.npmmirror.com/@floating-ui/dom/-/dom-1.6.13.tgz", + "integrity": "sha512-umqzocjDgNRGTuO7Q8CU32dkHkECqI8ZdMZ5Swb6QAM0t5rnlrN3lGo1hdpscRd3WS8T6DKYK4ephgIH9iRh3w==", + "license": "MIT", + "dependencies": { + "@floating-ui/core": "^1.6.0", + "@floating-ui/utils": "^0.2.9" + } + }, + "node_modules/@floating-ui/utils": { + "version": "0.2.9", + "resolved": "https://registry.npmmirror.com/@floating-ui/utils/-/utils-0.2.9.tgz", + "integrity": "sha512-MDWhGtE+eHw5JW7lq4qhc5yRLS11ERl1c7Z6Xd0a58DozHES6EnNNwUWbMiG4J9Cgj053Bhk8zvlhFYKVhULwg==", + "license": "MIT" + }, "node_modules/@hapi/hoek": { "version": "9.3.0", "resolved": "https://registry.npmmirror.com/@hapi/hoek/-/hoek-9.3.0.tgz", @@ -2008,6 +2053,17 @@ "dev": true, "license": "MIT" }, + "node_modules/@popperjs/core": { + "name": "@sxzz/popperjs-es", + "version": "2.11.7", + "resolved": "https://registry.npmmirror.com/@sxzz/popperjs-es/-/popperjs-es-2.11.7.tgz", + "integrity": "sha512-Ccy0NlLkzr0Ex2FKvh2X+OyERHXJ88XJ1MXtsI9y9fGexlaXaVTPzBCRBwIxFkORuOb+uBqeu+RqnpgYTEZRUQ==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/popperjs" + } + }, "node_modules/@sideway/address": { "version": "4.1.5", "resolved": "https://registry.npmmirror.com/@sideway/address/-/address-4.1.5.tgz", @@ -2209,6 +2265,21 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/lodash": { + "version": "4.17.16", + "resolved": "https://registry.npmmirror.com/@types/lodash/-/lodash-4.17.16.tgz", + "integrity": "sha512-HX7Em5NYQAXKW+1T+FiuG27NGwzJfCX3s1GjOa7ujxZa52kjJLOr4FUxT+giF6Tgxv1e+/czV/iTtBw27WTU9g==", + "license": "MIT" + }, + "node_modules/@types/lodash-es": { + "version": "4.17.12", + "resolved": "https://registry.npmmirror.com/@types/lodash-es/-/lodash-es-4.17.12.tgz", + "integrity": "sha512-0NgftHUcV4v34VhXm8QBSftKVXtbkBG3ViCjs6+eJ5a6y6Mi/jiFGPc1sC7QK+9BFhWrURE3EOggmWaSxL9OzQ==", + "license": "MIT", + "dependencies": { + "@types/lodash": "*" + } + }, "node_modules/@types/mime": { "version": "1.3.5", "resolved": "https://registry.npmmirror.com/@types/mime/-/mime-1.3.5.tgz", @@ -2321,6 +2392,12 @@ "@types/node": "*" } }, + "node_modules/@types/web-bluetooth": { + "version": "0.0.16", + "resolved": "https://registry.npmmirror.com/@types/web-bluetooth/-/web-bluetooth-0.0.16.tgz", + "integrity": "sha512-oh8q2Zc32S6gd/j50GowEjKLoOVOwHP/bWVjKJInBwQqdOYMdPrf1oVlelTlyfFK3CKxL1uahMDAr+vy8T7yMQ==", + "license": "MIT" + }, "node_modules/@types/ws": { "version": "8.18.0", "resolved": "https://registry.npmmirror.com/@types/ws/-/ws-8.18.0.tgz", @@ -3052,6 +3129,12 @@ "dev": true, "license": "ISC" }, + "node_modules/@vue/devtools-api": { + "version": "6.6.4", + "resolved": "https://registry.npmmirror.com/@vue/devtools-api/-/devtools-api-6.6.4.tgz", + "integrity": "sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g==", + "license": "MIT" + }, "node_modules/@vue/reactivity": { "version": "3.5.13", "resolved": "https://registry.npmmirror.com/@vue/reactivity/-/reactivity-3.5.13.tgz", @@ -3146,6 +3229,94 @@ "dev": true, "license": "MIT" }, + "node_modules/@vueuse/core": { + "version": "9.13.0", + "resolved": "https://registry.npmmirror.com/@vueuse/core/-/core-9.13.0.tgz", + "integrity": "sha512-pujnclbeHWxxPRqXWmdkKV5OX4Wk4YeK7wusHqRwU0Q7EFusHoqNA/aPhB6KCh9hEqJkLAJo7bb0Lh9b+OIVzw==", + "license": "MIT", + "dependencies": { + "@types/web-bluetooth": "^0.0.16", + "@vueuse/metadata": "9.13.0", + "@vueuse/shared": "9.13.0", + "vue-demi": "*" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/@vueuse/core/node_modules/vue-demi": { + "version": "0.14.10", + "resolved": "https://registry.npmmirror.com/vue-demi/-/vue-demi-0.14.10.tgz", + "integrity": "sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==", + "hasInstallScript": true, + "license": "MIT", + "bin": { + "vue-demi-fix": "bin/vue-demi-fix.js", + "vue-demi-switch": "bin/vue-demi-switch.js" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "@vue/composition-api": "^1.0.0-rc.1", + "vue": "^3.0.0-0 || ^2.6.0" + }, + "peerDependenciesMeta": { + "@vue/composition-api": { + "optional": true + } + } + }, + "node_modules/@vueuse/metadata": { + "version": "9.13.0", + "resolved": "https://registry.npmmirror.com/@vueuse/metadata/-/metadata-9.13.0.tgz", + "integrity": "sha512-gdU7TKNAUVlXXLbaF+ZCfte8BjRJQWPCa2J55+7/h+yDtzw3vOoGQDRXzI6pyKyo6bXFT5/QoPE4hAknExjRLQ==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/@vueuse/shared": { + "version": "9.13.0", + "resolved": "https://registry.npmmirror.com/@vueuse/shared/-/shared-9.13.0.tgz", + "integrity": "sha512-UrnhU+Cnufu4S6JLCPZnkWh0WwZGUp72ktOF2DFptMlOs3TOdVv8xJN53zhHGARmVOsz5KqOls09+J1NR6sBKw==", + "license": "MIT", + "dependencies": { + "vue-demi": "*" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/@vueuse/shared/node_modules/vue-demi": { + "version": "0.14.10", + "resolved": "https://registry.npmmirror.com/vue-demi/-/vue-demi-0.14.10.tgz", + "integrity": "sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==", + "hasInstallScript": true, + "license": "MIT", + "bin": { + "vue-demi-fix": "bin/vue-demi-fix.js", + "vue-demi-switch": "bin/vue-demi-switch.js" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "@vue/composition-api": "^1.0.0-rc.1", + "vue": "^3.0.0-0 || ^2.6.0" + }, + "peerDependenciesMeta": { + "@vue/composition-api": { + "optional": true + } + } + }, "node_modules/@webassemblyjs/ast": { "version": "1.14.1", "resolved": "https://registry.npmmirror.com/@webassemblyjs/ast/-/ast-1.14.1.tgz", @@ -3605,6 +3776,12 @@ "dev": true, "license": "MIT" }, + "node_modules/async-validator": { + "version": "4.2.5", + "resolved": "https://registry.npmmirror.com/async-validator/-/async-validator-4.2.5.tgz", + "integrity": "sha512-7HhHjtERjqlNbZtqNqy2rckN/SpOOlmDliet+lP7k+eKZEjPk3DgyeU9lIXLdeLz0uBbbVp+9Qdow9wJWgwwfg==", + "license": "MIT" + }, "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmmirror.com/asynckit/-/asynckit-0.4.0.tgz", @@ -4927,6 +5104,12 @@ "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", "license": "MIT" }, + "node_modules/dayjs": { + "version": "1.11.13", + "resolved": "https://registry.npmmirror.com/dayjs/-/dayjs-1.11.13.tgz", + "integrity": "sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==", + "license": "MIT" + }, "node_modules/debounce": { "version": "1.2.1", "resolved": "https://registry.npmmirror.com/debounce/-/debounce-1.2.1.tgz", @@ -5332,6 +5515,32 @@ "dev": true, "license": "ISC" }, + "node_modules/element-plus": { + "version": "2.9.8", + "resolved": "https://registry.npmmirror.com/element-plus/-/element-plus-2.9.8.tgz", + "integrity": "sha512-srViUaUdfblBKGMeuEPiXxxKlH5aUmKqEwmhb/At9Sj91DbU6od/jYN1955cTnzt3wTSA7GfnZF7UiRX9sdRHg==", + "license": "MIT", + "dependencies": { + "@ctrl/tinycolor": "^3.4.1", + "@element-plus/icons-vue": "^2.3.1", + "@floating-ui/dom": "^1.0.1", + "@popperjs/core": "npm:@sxzz/popperjs-es@^2.11.7", + "@types/lodash": "^4.14.182", + "@types/lodash-es": "^4.17.6", + "@vueuse/core": "^9.1.0", + "async-validator": "^4.2.5", + "dayjs": "^1.11.13", + "escape-html": "^1.0.3", + "lodash": "^4.17.21", + "lodash-es": "^4.17.21", + "lodash-unified": "^1.0.2", + "memoize-one": "^6.0.0", + "normalize-wheel-es": "^1.2.0" + }, + "peerDependencies": { + "vue": "^3.2.0" + } + }, "node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmmirror.com/emoji-regex/-/emoji-regex-8.0.0.tgz", @@ -5495,7 +5704,6 @@ "version": "1.0.3", "resolved": "https://registry.npmmirror.com/escape-html/-/escape-html-1.0.3.tgz", "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", - "dev": true, "license": "MIT" }, "node_modules/escape-string-regexp": { @@ -7573,9 +7781,25 @@ "version": "4.17.21", "resolved": "https://registry.npmmirror.com/lodash/-/lodash-4.17.21.tgz", "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true, "license": "MIT" }, + "node_modules/lodash-es": { + "version": "4.17.21", + "resolved": "https://registry.npmmirror.com/lodash-es/-/lodash-es-4.17.21.tgz", + "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==", + "license": "MIT" + }, + "node_modules/lodash-unified": { + "version": "1.0.3", + "resolved": "https://registry.npmmirror.com/lodash-unified/-/lodash-unified-1.0.3.tgz", + "integrity": "sha512-WK9qSozxXOD7ZJQlpSqOT+om2ZfcT4yO+03FuzAHD0wF6S0l0090LRPDx3vhTTLZ8cFKpBn+IOcVXK6qOcIlfQ==", + "license": "MIT", + "peerDependencies": { + "@types/lodash-es": "*", + "lodash": "*", + "lodash-es": "*" + } + }, "node_modules/lodash.debounce": { "version": "4.0.8", "resolved": "https://registry.npmmirror.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz", @@ -7876,6 +8100,12 @@ "node": ">= 4.0.0" } }, + "node_modules/memoize-one": { + "version": "6.0.0", + "resolved": "https://registry.npmmirror.com/memoize-one/-/memoize-one-6.0.0.tgz", + "integrity": "sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw==", + "license": "MIT" + }, "node_modules/merge-descriptors": { "version": "1.0.3", "resolved": "https://registry.npmmirror.com/merge-descriptors/-/merge-descriptors-1.0.3.tgz", @@ -8313,6 +8543,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/normalize-wheel-es": { + "version": "1.2.0", + "resolved": "https://registry.npmmirror.com/normalize-wheel-es/-/normalize-wheel-es-1.2.0.tgz", + "integrity": "sha512-Wj7+EJQ8mSuXr2iWfnujrimU35R2W4FAErEyTmJoJ7ucwTn2hOUSsRehMb5RSYkxXGTM7Y9QpvPmp++w5ftoJw==", + "license": "BSD-3-Clause" + }, "node_modules/npm-run-path": { "version": "2.0.2", "resolved": "https://registry.npmmirror.com/npm-run-path/-/npm-run-path-2.0.2.tgz", @@ -11546,6 +11782,21 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, + "node_modules/vue-router": { + "version": "4.5.0", + "resolved": "https://registry.npmmirror.com/vue-router/-/vue-router-4.5.0.tgz", + "integrity": "sha512-HDuk+PuH5monfNuY+ct49mNmkCRK4xJAV9Ts4z9UFc4rzdDnxQLyCMGGc8pKhZhHTVzfanpNwB/lwqevcBwI4w==", + "license": "MIT", + "dependencies": { + "@vue/devtools-api": "^6.6.4" + }, + "funding": { + "url": "https://github.com/sponsors/posva" + }, + "peerDependencies": { + "vue": "^3.2.0" + } + }, "node_modules/vue-style-loader": { "version": "4.1.3", "resolved": "https://registry.npmmirror.com/vue-style-loader/-/vue-style-loader-4.1.3.tgz", diff --git a/珞珈岛-项目相关文件/luojia-island/vue-frontend/package.json b/珞珈岛-项目相关文件/luojia-island/vue-frontend/package.json index 3bc7c87..2ea451a 100644 --- a/珞珈岛-项目相关文件/luojia-island/vue-frontend/package.json +++ b/珞珈岛-项目相关文件/luojia-island/vue-frontend/package.json @@ -10,7 +10,9 @@ "dependencies": { "axios": "^1.8.4", "core-js": "^3.8.3", - "vue": "^3.2.13" + "element-plus": "^2.9.8", + "vue": "^3.2.13", + "vue-router": "^4.5.0" }, "devDependencies": { "@babel/core": "^7.12.16", diff --git a/珞珈岛-项目相关文件/luojia-island/vue-frontend/src/components/Login.vue b/珞珈岛-项目相关文件/luojia-island/vue-frontend/src/components/Login.vue index 8ef9e07..caadc96 100644 --- a/珞珈岛-项目相关文件/luojia-island/vue-frontend/src/components/Login.vue +++ b/珞珈岛-项目相关文件/luojia-island/vue-frontend/src/components/Login.vue @@ -3,13 +3,13 @@

登录

- + @@ -17,7 +17,7 @@