云文件系统初始化
This commit is contained in:
502
src/main/java/com/filesystem/service/FileService.java
Normal file
502
src/main/java/com/filesystem/service/FileService.java
Normal file
@@ -0,0 +1,502 @@
|
||||
package com.filesystem.service;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||
import com.filesystem.entity.FileEntity;
|
||||
import com.filesystem.entity.FileShare;
|
||||
import com.filesystem.mapper.FileMapper;
|
||||
import com.filesystem.mapper.FileShareMapper;
|
||||
import com.filesystem.mapper.UserMapper;
|
||||
import com.filesystem.entity.User;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Service
|
||||
public class FileService {
|
||||
|
||||
@Resource
|
||||
private FileMapper fileMapper;
|
||||
|
||||
@Resource
|
||||
private FileShareMapper fileShareMapper;
|
||||
|
||||
@Resource
|
||||
private UserMapper userMapper;
|
||||
|
||||
@Resource
|
||||
private UserService userService;
|
||||
|
||||
@Value("${file.storage.path:./uploads}")
|
||||
private String storagePath;
|
||||
|
||||
public List<FileEntity> getFiles(Long userId, Long folderId, String keyword) {
|
||||
LambdaQueryWrapper<FileEntity> wrapper = new LambdaQueryWrapper<>();
|
||||
wrapper.eq(FileEntity::getUserId, userId)
|
||||
.eq(FileEntity::getIsDeleted, 0);
|
||||
|
||||
if (folderId != null) {
|
||||
wrapper.eq(FileEntity::getFolderId, folderId);
|
||||
} else {
|
||||
wrapper.isNull(FileEntity::getFolderId);
|
||||
}
|
||||
|
||||
if (keyword != null && !keyword.isEmpty()) {
|
||||
wrapper.like(FileEntity::getName, keyword);
|
||||
}
|
||||
|
||||
wrapper.orderByDesc(FileEntity::getIsFolder)
|
||||
.orderByDesc(FileEntity::getCreateTime);
|
||||
|
||||
return fileMapper.selectList(wrapper);
|
||||
}
|
||||
|
||||
public List<FileEntity> getTrashFiles(Long userId, Long folderId) {
|
||||
LambdaQueryWrapper<FileEntity> wrapper = new LambdaQueryWrapper<>();
|
||||
wrapper.eq(FileEntity::getUserId, userId)
|
||||
.eq(FileEntity::getIsDeleted, 1);
|
||||
|
||||
if (folderId != null) {
|
||||
// 查询指定文件夹下的已删除文件
|
||||
wrapper.eq(FileEntity::getFolderId, folderId);
|
||||
} else {
|
||||
// 查询根目录下已删除的文件和文件夹
|
||||
wrapper.isNull(FileEntity::getFolderId)
|
||||
.or(w -> w.eq(FileEntity::getFolderId, 0));
|
||||
}
|
||||
|
||||
wrapper.orderByDesc(FileEntity::getDeletedAt);
|
||||
return fileMapper.selectList(wrapper);
|
||||
}
|
||||
|
||||
public FileEntity getById(Long id) {
|
||||
return fileMapper.selectById(id);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void moveToTrash(Long id, Long userId) {
|
||||
FileEntity file = fileMapper.selectById(id);
|
||||
if (file != null && file.getUserId().equals(userId)) {
|
||||
// 使用 LambdaUpdateWrapper 明确指定要更新的字段
|
||||
LambdaUpdateWrapper<FileEntity> wrapper = new LambdaUpdateWrapper<>();
|
||||
wrapper.eq(FileEntity::getId, id)
|
||||
.set(FileEntity::getIsDeleted, 1)
|
||||
.set(FileEntity::getDeletedAt, LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
|
||||
fileMapper.update(null, wrapper);
|
||||
}
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void restoreFile(Long id, Long userId) {
|
||||
FileEntity file = fileMapper.selectById(id);
|
||||
if (file == null || !file.getUserId().equals(userId)) return;
|
||||
|
||||
LambdaUpdateWrapper<FileEntity> wrapper = new LambdaUpdateWrapper<>();
|
||||
wrapper.eq(FileEntity::getId, id)
|
||||
.set(FileEntity::getIsDeleted, 0)
|
||||
.set(FileEntity::getDeletedAt, null);
|
||||
fileMapper.update(null, wrapper);
|
||||
|
||||
// 如果是文件夹,递归还原所有子文件
|
||||
if (file.getIsFolder() != null && file.getIsFolder() == 1) {
|
||||
restoreChildren(id, userId);
|
||||
}
|
||||
}
|
||||
|
||||
private void restoreChildren(Long parentFolderId, Long userId) {
|
||||
List<FileEntity> children = fileMapper.selectList(
|
||||
new LambdaQueryWrapper<FileEntity>()
|
||||
.eq(FileEntity::getFolderId, parentFolderId)
|
||||
.eq(FileEntity::getIsDeleted, 1)
|
||||
.eq(FileEntity::getUserId, userId)
|
||||
);
|
||||
for (FileEntity child : children) {
|
||||
LambdaUpdateWrapper<FileEntity> wrapper = new LambdaUpdateWrapper<>();
|
||||
wrapper.eq(FileEntity::getId, child.getId())
|
||||
.set(FileEntity::getIsDeleted, 0)
|
||||
.set(FileEntity::getDeletedAt, null);
|
||||
fileMapper.update(null, wrapper);
|
||||
|
||||
if (child.getIsFolder() != null && child.getIsFolder() == 1) {
|
||||
restoreChildren(child.getId(), userId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void deletePermanently(Long id, Long userId) {
|
||||
FileEntity file = fileMapper.selectById(id);
|
||||
if (file == null || !file.getUserId().equals(userId)) return;
|
||||
|
||||
// 如果是文件夹,先递归删除所有子文件
|
||||
if (file.getIsFolder() != null && file.getIsFolder() == 1) {
|
||||
deleteChildrenPermanently(id, userId);
|
||||
}
|
||||
|
||||
// 删除当前文件的物理文件并扣减存储
|
||||
if (file.getPath() != null && !file.getPath().isEmpty()) {
|
||||
try {
|
||||
Path filePath = Paths.get(storagePath).toAbsolutePath().resolve("files").resolve(file.getPath());
|
||||
Files.deleteIfExists(filePath);
|
||||
} catch (IOException e) {
|
||||
// ignore
|
||||
}
|
||||
if (file.getSize() != null && file.getSize() > 0) {
|
||||
userService.decreaseStorage(userId, file.getSize());
|
||||
}
|
||||
}
|
||||
fileMapper.deleteById(id);
|
||||
}
|
||||
|
||||
private void deleteChildrenPermanently(Long parentFolderId, Long userId) {
|
||||
List<FileEntity> children = fileMapper.selectList(
|
||||
new LambdaQueryWrapper<FileEntity>()
|
||||
.eq(FileEntity::getFolderId, parentFolderId)
|
||||
.eq(FileEntity::getIsDeleted, 1)
|
||||
.eq(FileEntity::getUserId, userId)
|
||||
);
|
||||
for (FileEntity child : children) {
|
||||
if (child.getIsFolder() != null && child.getIsFolder() == 1) {
|
||||
deleteChildrenPermanently(child.getId(), userId);
|
||||
}
|
||||
if (child.getPath() != null && !child.getPath().isEmpty()) {
|
||||
try {
|
||||
Path filePath = Paths.get(storagePath).toAbsolutePath().resolve("files").resolve(child.getPath());
|
||||
Files.deleteIfExists(filePath);
|
||||
} catch (IOException e) {
|
||||
// ignore
|
||||
}
|
||||
if (child.getSize() != null && child.getSize() > 0) {
|
||||
userService.decreaseStorage(userId, child.getSize());
|
||||
}
|
||||
}
|
||||
fileMapper.deleteById(child.getId());
|
||||
}
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void emptyTrash(Long userId) {
|
||||
List<FileEntity> trashFiles = getTrashFiles(userId, null);
|
||||
for (FileEntity file : trashFiles) {
|
||||
deletePermanently(file.getId(), userId);
|
||||
}
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public FileEntity createFolder(String name, Long userId, Long parentId) {
|
||||
FileEntity folder = new FileEntity();
|
||||
folder.setName(name);
|
||||
folder.setType("folder");
|
||||
folder.setIsFolder(1);
|
||||
folder.setUserId(userId);
|
||||
folder.setFolderId(parentId);
|
||||
folder.setSize(0L);
|
||||
folder.setIsShared(0);
|
||||
folder.setIsDeleted(0);
|
||||
fileMapper.insert(folder);
|
||||
return folder;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public List<FileEntity> uploadFiles(List<MultipartFile> files, Long userId, Long folderId) throws IOException {
|
||||
List<FileEntity> uploadedFiles = new ArrayList<>();
|
||||
|
||||
// 确保存储目录存在(使用配置文件中的路径 + files 子目录)
|
||||
Path uploadDir = Paths.get(storagePath).toAbsolutePath().resolve("files");
|
||||
if (!Files.exists(uploadDir)) {
|
||||
Files.createDirectories(uploadDir);
|
||||
}
|
||||
|
||||
for (MultipartFile file : files) {
|
||||
if (file.isEmpty()) continue;
|
||||
|
||||
String originalName = file.getOriginalFilename();
|
||||
String extension = originalName.contains(".") ? originalName.substring(originalName.lastIndexOf(".")) : "";
|
||||
String storedName = UUID.randomUUID().toString() + extension;
|
||||
String datePath = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy/MM"));
|
||||
|
||||
Path targetDir = uploadDir.resolve(datePath);
|
||||
if (!Files.exists(targetDir)) {
|
||||
Files.createDirectories(targetDir);
|
||||
}
|
||||
|
||||
Path targetPath = targetDir.resolve(storedName);
|
||||
file.transferTo(targetPath.toFile());
|
||||
|
||||
FileEntity fileEntity = new FileEntity();
|
||||
fileEntity.setName(originalName);
|
||||
fileEntity.setType(getFileType(extension));
|
||||
fileEntity.setSize(file.getSize());
|
||||
fileEntity.setPath(datePath + "/" + storedName);
|
||||
fileEntity.setUserId(userId);
|
||||
fileEntity.setFolderId(folderId);
|
||||
fileEntity.setIsFolder(0);
|
||||
fileEntity.setIsShared(0);
|
||||
fileEntity.setIsDeleted(0);
|
||||
|
||||
fileMapper.insert(fileEntity);
|
||||
uploadedFiles.add(fileEntity);
|
||||
|
||||
// 更新用户存储空间
|
||||
userService.updateStorage(userId, file.getSize());
|
||||
}
|
||||
|
||||
return uploadedFiles;
|
||||
}
|
||||
|
||||
private String getFileType(String extension) {
|
||||
if (extension == null || extension.isEmpty()) return "file";
|
||||
extension = extension.toLowerCase();
|
||||
if (".jpg".equals(extension) || ".jpeg".equals(extension) || ".png".equals(extension)
|
||||
|| ".gif".equals(extension) || ".webp".equals(extension) || ".svg".equals(extension)) {
|
||||
return "image";
|
||||
}
|
||||
if (".mp4".equals(extension) || ".avi".equals(extension) || ".mov".equals(extension)) {
|
||||
return "video";
|
||||
}
|
||||
if (".mp3".equals(extension) || ".wav".equals(extension) || ".flac".equals(extension)) {
|
||||
return "audio";
|
||||
}
|
||||
if (".pdf".equals(extension)) {
|
||||
return "pdf";
|
||||
}
|
||||
return "file";
|
||||
}
|
||||
|
||||
public byte[] getFileContent(FileEntity file) throws IOException {
|
||||
if (file == null || file.getPath() == null) return null;
|
||||
Path filePath = Paths.get(storagePath).toAbsolutePath().resolve("files").resolve(file.getPath());
|
||||
return Files.readAllBytes(filePath);
|
||||
}
|
||||
|
||||
// 共享相关
|
||||
public List<FileEntity> getSharedByMe(Long userId) {
|
||||
List<FileShare> shares = fileShareMapper.selectList(
|
||||
new LambdaQueryWrapper<FileShare>().eq(FileShare::getOwnerId, userId)
|
||||
);
|
||||
|
||||
return shares.stream()
|
||||
.map(share -> fileMapper.selectById(share.getFileId()))
|
||||
.filter(f -> f != null && f.getIsDeleted() == 0)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public List<FileEntity> getSharedByMeFolderFiles(Long userId, Long folderId) {
|
||||
try {
|
||||
// 检查该文件夹是否由当前用户共享
|
||||
FileEntity folder = fileMapper.selectById(folderId);
|
||||
if (folder == null || folder.getIsDeleted() == 1 || !folder.getUserId().equals(userId)) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
// 检查是否有共享记录
|
||||
List<FileShare> shares = fileShareMapper.selectList(
|
||||
new LambdaQueryWrapper<FileShare>()
|
||||
.eq(FileShare::getFileId, folderId)
|
||||
.eq(FileShare::getOwnerId, userId)
|
||||
);
|
||||
|
||||
if (shares.isEmpty()) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
// 返回该文件夹内的文件
|
||||
LambdaQueryWrapper<FileEntity> wrapper = new LambdaQueryWrapper<>();
|
||||
wrapper.eq(FileEntity::getFolderId, folderId)
|
||||
.eq(FileEntity::getIsDeleted, 0)
|
||||
.isNull(FileEntity::getDeletedAt);
|
||||
|
||||
return fileMapper.selectList(wrapper);
|
||||
} catch (Exception e) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
}
|
||||
|
||||
public List<FileEntity> getSharedToMe(Long userId) {
|
||||
List<FileShare> shares = fileShareMapper.selectList(
|
||||
new LambdaQueryWrapper<FileShare>().eq(FileShare::getShareToUserId, userId)
|
||||
);
|
||||
|
||||
return shares.stream()
|
||||
.map(share -> fileMapper.selectById(share.getFileId()))
|
||||
.filter(f -> f != null && f.getIsDeleted() == 0)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public List<FileEntity> getSharedFolderFiles(Long userId, Long folderId) {
|
||||
try {
|
||||
// 检查该文件夹是否被共享给当前用户
|
||||
FileEntity folder = fileMapper.selectById(folderId);
|
||||
if (folder == null || folder.getIsDeleted() == 1) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
// 检查是否有共享权限
|
||||
List<FileShare> shares = fileShareMapper.selectList(
|
||||
new LambdaQueryWrapper<FileShare>()
|
||||
.eq(FileShare::getFileId, folderId)
|
||||
.eq(FileShare::getShareToUserId, userId)
|
||||
);
|
||||
|
||||
if (shares.isEmpty()) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
// 返回该文件夹内的文件
|
||||
LambdaQueryWrapper<FileEntity> wrapper = new LambdaQueryWrapper<>();
|
||||
wrapper.eq(FileEntity::getFolderId, folderId)
|
||||
.eq(FileEntity::getIsDeleted, 0)
|
||||
.isNull(FileEntity::getDeletedAt);
|
||||
|
||||
return fileMapper.selectList(wrapper);
|
||||
} catch (Exception e) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public FileShare shareFile(Long fileId, Long ownerId, Long shareToUserId, String permission) {
|
||||
FileShare share = new FileShare();
|
||||
share.setFileId(fileId);
|
||||
share.setOwnerId(ownerId);
|
||||
share.setShareToUserId(shareToUserId);
|
||||
share.setPermission(permission != null ? permission : "view");
|
||||
fileShareMapper.insert(share);
|
||||
|
||||
// 更新文件共享状态
|
||||
FileEntity file = fileMapper.selectById(fileId);
|
||||
if (file != null) {
|
||||
file.setIsShared(1);
|
||||
fileMapper.updateById(file);
|
||||
}
|
||||
|
||||
return share;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void cancelShare(Long fileId, Long ownerId) {
|
||||
fileShareMapper.delete(
|
||||
new LambdaQueryWrapper<FileShare>()
|
||||
.eq(FileShare::getFileId, fileId)
|
||||
.eq(FileShare::getOwnerId, ownerId)
|
||||
);
|
||||
|
||||
// 检查是否还有其他共享
|
||||
Long count = fileShareMapper.selectCount(
|
||||
new LambdaQueryWrapper<FileShare>().eq(FileShare::getFileId, fileId)
|
||||
);
|
||||
if (count == 0) {
|
||||
FileEntity file = fileMapper.selectById(fileId);
|
||||
if (file != null) {
|
||||
file.setIsShared(0);
|
||||
fileMapper.updateById(file);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public String getOwnerName(Long userId) {
|
||||
User user = userMapper.selectById(userId);
|
||||
return user != null ? user.getNickname() : "未知用户";
|
||||
}
|
||||
|
||||
public void renameFile(Long fileId, Long userId, String newName) {
|
||||
FileEntity file = fileMapper.selectById(fileId);
|
||||
if (file == null) {
|
||||
throw new RuntimeException("文件不存在");
|
||||
}
|
||||
if (!file.getUserId().equals(userId)) {
|
||||
throw new RuntimeException("无权操作此文件");
|
||||
}
|
||||
if (file.getIsDeleted() == 1) {
|
||||
throw new RuntimeException("无法重命名回收站中的文件");
|
||||
}
|
||||
|
||||
// 检查新名称是否已存在(同一目录下)
|
||||
FileEntity existing = fileMapper.selectOne(
|
||||
new LambdaQueryWrapper<FileEntity>()
|
||||
.eq(FileEntity::getUserId, userId)
|
||||
.eq(FileEntity::getFolderId, file.getFolderId())
|
||||
.eq(FileEntity::getName, newName)
|
||||
.eq(FileEntity::getIsDeleted, 0)
|
||||
.ne(FileEntity::getId, fileId)
|
||||
);
|
||||
if (existing != null) {
|
||||
throw new RuntimeException("该名称已存在");
|
||||
}
|
||||
|
||||
file.setName(newName);
|
||||
fileMapper.updateById(file);
|
||||
}
|
||||
|
||||
public void moveFile(Long fileId, Long userId, Long targetFolderId) {
|
||||
FileEntity file = fileMapper.selectById(fileId);
|
||||
if (file == null) {
|
||||
throw new RuntimeException("文件不存在");
|
||||
}
|
||||
if (!file.getUserId().equals(userId)) {
|
||||
throw new RuntimeException("无权操作此文件");
|
||||
}
|
||||
if (file.getIsDeleted() == 1) {
|
||||
throw new RuntimeException("无法移动回收站中的文件");
|
||||
}
|
||||
|
||||
// 检查目标文件夹是否存在(如果不是根目录)
|
||||
if (targetFolderId != null) {
|
||||
FileEntity targetFolder = fileMapper.selectById(targetFolderId);
|
||||
if (targetFolder == null) {
|
||||
throw new RuntimeException("目标文件夹不存在");
|
||||
}
|
||||
if (!targetFolder.getUserId().equals(userId)) {
|
||||
throw new RuntimeException("无权访问目标文件夹");
|
||||
}
|
||||
if (targetFolder.getIsDeleted() == 1) {
|
||||
throw new RuntimeException("目标文件夹在回收站中");
|
||||
}
|
||||
// 检查是否移动到自己里面(如果是文件夹)
|
||||
if (file.getIsFolder() == 1) {
|
||||
if (file.getId().equals(targetFolderId)) {
|
||||
throw new RuntimeException("不能移动到自己里面");
|
||||
}
|
||||
// 检查目标是否是自己子文件夹
|
||||
Long parentId = targetFolder.getFolderId();
|
||||
while (parentId != null) {
|
||||
if (parentId.equals(file.getId())) {
|
||||
throw new RuntimeException("不能移动到自己的子文件夹中");
|
||||
}
|
||||
FileEntity parent = fileMapper.selectById(parentId);
|
||||
if (parent == null) break;
|
||||
parentId = parent.getFolderId();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 检查目标位置是否已有同名文件
|
||||
FileEntity existing = fileMapper.selectOne(
|
||||
new LambdaQueryWrapper<FileEntity>()
|
||||
.eq(FileEntity::getUserId, userId)
|
||||
.eq(FileEntity::getFolderId, targetFolderId)
|
||||
.eq(FileEntity::getName, file.getName())
|
||||
.eq(FileEntity::getIsDeleted, 0)
|
||||
.ne(FileEntity::getId, fileId)
|
||||
);
|
||||
if (existing != null) {
|
||||
throw new RuntimeException("目标位置已存在同名文件");
|
||||
}
|
||||
|
||||
file.setFolderId(targetFolderId);
|
||||
fileMapper.updateById(file);
|
||||
}
|
||||
}
|
||||
85
src/main/java/com/filesystem/service/MessageService.java
Normal file
85
src/main/java/com/filesystem/service/MessageService.java
Normal file
@@ -0,0 +1,85 @@
|
||||
package com.filesystem.service;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.filesystem.entity.Message;
|
||||
import com.filesystem.mapper.MessageMapper;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Service
|
||||
public class MessageService {
|
||||
|
||||
@Resource
|
||||
private MessageMapper messageMapper;
|
||||
|
||||
public List<Message> getMessages(Long userId1, Long userId2) {
|
||||
return messageMapper.selectList(
|
||||
new LambdaQueryWrapper<Message>()
|
||||
.and(wrapper -> wrapper
|
||||
.eq(Message::getFromUserId, userId1).eq(Message::getToUserId, userId2)
|
||||
.or()
|
||||
.eq(Message::getFromUserId, userId2).eq(Message::getToUserId, userId1)
|
||||
)
|
||||
.orderByAsc(Message::getCreateTime)
|
||||
);
|
||||
}
|
||||
|
||||
public Message sendMessage(Long fromUserId, Long toUserId, String content, String type) {
|
||||
Message message = new Message();
|
||||
message.setFromUserId(fromUserId);
|
||||
message.setToUserId(toUserId);
|
||||
message.setContent(content);
|
||||
message.setType(type);
|
||||
message.setIsRead(0);
|
||||
messageMapper.insert(message);
|
||||
return message;
|
||||
}
|
||||
|
||||
public void updateMessage(Message message) {
|
||||
messageMapper.updateById(message);
|
||||
}
|
||||
|
||||
public Message sendFileMessage(Long fromUserId, Long toUserId, String fileName, Long fileSize) {
|
||||
Message message = new Message();
|
||||
message.setFromUserId(fromUserId);
|
||||
message.setToUserId(toUserId);
|
||||
message.setContent(fileName);
|
||||
message.setType("file");
|
||||
message.setFileName(fileName);
|
||||
message.setFileSize(fileSize);
|
||||
message.setIsRead(0);
|
||||
messageMapper.insert(message);
|
||||
return message;
|
||||
}
|
||||
|
||||
public int getUnreadCount(Long userId) {
|
||||
return Math.toIntExact(messageMapper.selectCount(
|
||||
new LambdaQueryWrapper<Message>()
|
||||
.eq(Message::getToUserId, userId)
|
||||
.eq(Message::getIsRead, 0)
|
||||
));
|
||||
}
|
||||
|
||||
public void markAsRead(Long messageId) {
|
||||
Message message = messageMapper.selectById(messageId);
|
||||
if (message != null) {
|
||||
message.setIsRead(1);
|
||||
messageMapper.updateById(message);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取未读消息列表:按发送人分组,返回每个联系人的未读数和最后一条消息
|
||||
*/
|
||||
public List<Message> getUnreadMessages(Long userId) {
|
||||
return messageMapper.selectList(
|
||||
new LambdaQueryWrapper<Message>()
|
||||
.eq(Message::getToUserId, userId)
|
||||
.eq(Message::getIsRead, 0)
|
||||
.orderByDesc(Message::getCreateTime)
|
||||
);
|
||||
}
|
||||
}
|
||||
150
src/main/java/com/filesystem/service/UserService.java
Normal file
150
src/main/java/com/filesystem/service/UserService.java
Normal file
@@ -0,0 +1,150 @@
|
||||
package com.filesystem.service;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.filesystem.entity.FileEntity;
|
||||
import com.filesystem.entity.User;
|
||||
import com.filesystem.mapper.FileMapper;
|
||||
import com.filesystem.mapper.UserMapper;
|
||||
import com.filesystem.security.JwtUtil;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Service
|
||||
public class UserService {
|
||||
|
||||
@Resource
|
||||
private UserMapper userMapper;
|
||||
|
||||
@Resource
|
||||
private FileMapper fileMapper;
|
||||
|
||||
@Resource
|
||||
private JwtUtil jwtUtil;
|
||||
|
||||
@Resource
|
||||
private BCryptPasswordEncoder passwordEncoder;
|
||||
|
||||
public User findByUsername(String username) {
|
||||
return userMapper.selectOne(
|
||||
new LambdaQueryWrapper<User>().eq(User::getUsername, username)
|
||||
);
|
||||
}
|
||||
|
||||
public User findById(Long id) {
|
||||
return userMapper.selectById(id);
|
||||
}
|
||||
|
||||
public String login(String username, String password) {
|
||||
User user = findByUsername(username);
|
||||
if (user == null) {
|
||||
throw new RuntimeException("用户不存在");
|
||||
}
|
||||
if (!passwordEncoder.matches(password, user.getPassword())) {
|
||||
throw new RuntimeException("密码错误");
|
||||
}
|
||||
return jwtUtil.generateToken(username, user.getId());
|
||||
}
|
||||
|
||||
public void logout(Long userId) {
|
||||
jwtUtil.invalidateToken(userId);
|
||||
}
|
||||
|
||||
public User createUser(String username, String password, String nickname) {
|
||||
User user = new User();
|
||||
user.setUsername(username);
|
||||
user.setPassword(passwordEncoder.encode(password));
|
||||
user.setNickname(nickname);
|
||||
user.setStatus(1);
|
||||
user.setStorageUsed(0L);
|
||||
user.setStorageLimit(20L * 1024 * 1024 * 1024); // 20GB
|
||||
userMapper.insert(user);
|
||||
return user;
|
||||
}
|
||||
|
||||
/**
|
||||
* 精确重算用户存储空间:统计该用户所有未删除(非回收站)文件的总大小
|
||||
*/
|
||||
public long recalculateStorage(Long userId) {
|
||||
List<FileEntity> userFiles = fileMapper.selectList(
|
||||
new LambdaQueryWrapper<FileEntity>()
|
||||
.eq(FileEntity::getUserId, userId)
|
||||
.eq(FileEntity::getIsDeleted, 0)
|
||||
.ne(FileEntity::getIsFolder, 1)
|
||||
);
|
||||
long total = 0L;
|
||||
for (FileEntity f : userFiles) {
|
||||
if (f.getSize() != null) {
|
||||
total += f.getSize();
|
||||
}
|
||||
}
|
||||
// 更新到用户表
|
||||
User user = userMapper.selectById(userId);
|
||||
if (user != null) {
|
||||
user.setStorageUsed(total);
|
||||
// 同步存储上限为 20GB(兼容老用户)
|
||||
if (user.getStorageLimit() == null || user.getStorageLimit() < 20L * 1024 * 1024 * 1024) {
|
||||
user.setStorageLimit(20L * 1024 * 1024 * 1024);
|
||||
}
|
||||
userMapper.updateById(user);
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
public void updateStorage(Long userId, Long size) {
|
||||
User user = userMapper.selectById(userId);
|
||||
if (user != null) {
|
||||
user.setStorageUsed(user.getStorageUsed() + size);
|
||||
userMapper.updateById(user);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 扣减存储空间(用于彻底删除文件时)
|
||||
*/
|
||||
public void decreaseStorage(Long userId, Long size) {
|
||||
User user = userMapper.selectById(userId);
|
||||
if (user != null) {
|
||||
long newValue = user.getStorageUsed() - size;
|
||||
user.setStorageUsed(Math.max(0L, newValue));
|
||||
userMapper.updateById(user);
|
||||
}
|
||||
}
|
||||
|
||||
public List<User> getAllUsersExcept(Long excludeId) {
|
||||
return userMapper.selectList(
|
||||
new LambdaQueryWrapper<User>()
|
||||
.ne(User::getId, excludeId)
|
||||
.eq(User::getStatus, 1)
|
||||
);
|
||||
}
|
||||
|
||||
public void updateAvatar(Long userId, String avatarUrl) {
|
||||
User user = userMapper.selectById(userId);
|
||||
if (user != null) {
|
||||
user.setAvatar(avatarUrl);
|
||||
userMapper.updateById(user);
|
||||
}
|
||||
}
|
||||
|
||||
public void updateProfile(Long userId, String nickname, String signature, String phone, String email) {
|
||||
User user = userMapper.selectById(userId);
|
||||
if (user != null) {
|
||||
if (nickname != null) {
|
||||
user.setNickname(nickname);
|
||||
}
|
||||
if (signature != null) {
|
||||
user.setSignature(signature);
|
||||
}
|
||||
if (phone != null) {
|
||||
user.setPhone(phone);
|
||||
}
|
||||
if (email != null) {
|
||||
user.setEmail(email);
|
||||
}
|
||||
userMapper.updateById(user);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user