mirror of
https://github.com/continew-org/continew-admin.git
synced 2025-09-16 20:57:11 +08:00
refactor: 重构原有文件上传接口并优化配置文件配置格式
移除 ContiNew Starter 本地存储依赖
This commit is contained in:
@@ -16,6 +16,8 @@
|
||||
|
||||
package top.charles7c.continew.admin.system.config;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@@ -25,6 +27,7 @@ import org.springframework.stereotype.Component;
|
||||
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.core.util.EscapeUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
|
||||
import top.charles7c.continew.admin.common.util.helper.LoginHelper;
|
||||
import top.charles7c.continew.admin.system.enums.FileTypeEnum;
|
||||
@@ -32,6 +35,7 @@ import top.charles7c.continew.admin.system.mapper.FileMapper;
|
||||
import top.charles7c.continew.admin.system.mapper.StorageMapper;
|
||||
import top.charles7c.continew.admin.system.model.entity.FileDO;
|
||||
import top.charles7c.continew.admin.system.model.entity.StorageDO;
|
||||
import top.charles7c.continew.starter.core.constant.StringConstants;
|
||||
|
||||
/**
|
||||
* 文件记录实现类
|
||||
@@ -50,7 +54,9 @@ public class FileRecorderImpl implements FileRecorder {
|
||||
@Override
|
||||
public boolean save(FileInfo fileInfo) {
|
||||
FileDO file = new FileDO();
|
||||
file.setName(EscapeUtil.unescape(fileInfo.getOriginalFilename()));
|
||||
String originalFilename = EscapeUtil.unescape(fileInfo.getOriginalFilename());
|
||||
file.setName(StrUtil.contains(originalFilename, StringConstants.DOT)
|
||||
? StrUtil.subBefore(originalFilename, StringConstants.DOT, true) : originalFilename);
|
||||
file.setSize(fileInfo.getSize());
|
||||
file.setUrl(fileInfo.getUrl());
|
||||
file.setExtension(fileInfo.getExt());
|
||||
@@ -66,17 +72,40 @@ public class FileRecorderImpl implements FileRecorder {
|
||||
|
||||
@Override
|
||||
public FileInfo getByUrl(String url) {
|
||||
FileDO file = fileMapper.lambdaQuery().eq(FileDO::getUrl, url).one();
|
||||
FileDO file = this.getFileByUrl(url);
|
||||
if (null == file) {
|
||||
return null;
|
||||
}
|
||||
FileInfo fileInfo = new FileInfo();
|
||||
fileInfo.setOriginalFilename(file.getName());
|
||||
String extension = file.getExtension();
|
||||
fileInfo.setOriginalFilename(
|
||||
StrUtil.isNotBlank(extension) ? file.getName() + StringConstants.DOT + extension : file.getName());
|
||||
fileInfo.setSize(file.getSize());
|
||||
fileInfo.setUrl(file.getUrl());
|
||||
fileInfo.setExt(file.getExtension());
|
||||
fileInfo.setExt(extension);
|
||||
fileInfo.setBasePath(StringConstants.EMPTY);
|
||||
fileInfo.setPath(StringConstants.EMPTY);
|
||||
fileInfo.setFilename(StrUtil.subAfter(url, StringConstants.SLASH, true));
|
||||
fileInfo.setPlatform(storageMapper.lambdaQuery().eq(StorageDO::getId, file.getStorageId()).one().getCode());
|
||||
return fileInfo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean delete(String url) {
|
||||
return fileMapper.lambdaUpdate().eq(FileDO::getUrl, url).remove();
|
||||
FileDO file = this.getFileByUrl(url);
|
||||
return fileMapper.lambdaUpdate().eq(FileDO::getUrl, file.getUrl()).remove();
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据 URL 查询文件
|
||||
*
|
||||
* @param url
|
||||
* URL
|
||||
* @return 文件信息
|
||||
*/
|
||||
private FileDO getFileByUrl(String url) {
|
||||
Optional<FileDO> fileOptional = fileMapper.lambdaQuery().eq(FileDO::getUrl, url).oneOpt();
|
||||
return fileOptional.orElseGet(() -> fileMapper.lambdaQuery()
|
||||
.eq(FileDO::getUrl, StrUtil.subAfter(url, StringConstants.SLASH, true)).oneOpt().orElse(null));
|
||||
}
|
||||
}
|
@@ -41,7 +41,7 @@ import top.charles7c.continew.admin.system.service.StorageService;
|
||||
* @since 2023/12/24 22:31
|
||||
*/
|
||||
@Slf4j
|
||||
//@Component
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class FileStorageConfigLoader implements ApplicationRunner {
|
||||
|
||||
|
@@ -18,6 +18,7 @@ package top.charles7c.continew.admin.system.service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.dromara.x.file.storage.core.FileInfo;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import top.charles7c.continew.admin.system.model.query.FileQuery;
|
||||
@@ -39,9 +40,10 @@ public interface FileService extends BaseService<FileResp, FileDetailResp, FileQ
|
||||
*
|
||||
* @param file
|
||||
* 文件信息
|
||||
* @return 文件信息
|
||||
*/
|
||||
default void upload(MultipartFile file) {
|
||||
upload(file, null);
|
||||
default FileInfo upload(MultipartFile file) {
|
||||
return upload(file, null);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -51,8 +53,9 @@ public interface FileService extends BaseService<FileResp, FileDetailResp, FileQ
|
||||
* 文件信息
|
||||
* @param storageCode
|
||||
* 存储库编码
|
||||
* @return 文件信息
|
||||
*/
|
||||
void upload(MultipartFile file, String storageCode);
|
||||
FileInfo upload(MultipartFile file, String storageCode);
|
||||
|
||||
/**
|
||||
* 根据存储库 ID 列表查询
|
||||
|
@@ -30,6 +30,7 @@ import org.springframework.web.multipart.MultipartFile;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.core.util.URLUtil;
|
||||
|
||||
import top.charles7c.continew.admin.system.enums.StorageTypeEnum;
|
||||
import top.charles7c.continew.admin.system.mapper.FileMapper;
|
||||
import top.charles7c.continew.admin.system.model.entity.FileDO;
|
||||
import top.charles7c.continew.admin.system.model.entity.StorageDO;
|
||||
@@ -62,13 +63,16 @@ public class FileServiceImpl extends BaseServiceImpl<FileMapper, FileDO, FileRes
|
||||
private final FileStorageService fileStorageService;
|
||||
|
||||
@Override
|
||||
public void upload(MultipartFile file, String storageCode) {
|
||||
public FileInfo upload(MultipartFile file, String storageCode) {
|
||||
StorageDO storage;
|
||||
if (StrUtil.isBlank(storageCode)) {
|
||||
StorageDO storage = storageService.getDefaultStorage();
|
||||
storage = storageService.getDefaultStorage();
|
||||
CheckUtils.throwIfNull(storage, "请先指定默认存储库");
|
||||
storageCode = storage.getCode();
|
||||
} else {
|
||||
storage = storageService.getByCode(storageCode);
|
||||
CheckUtils.throwIfNotExists(storage, "StorageDO", "Code", storageCode);
|
||||
}
|
||||
UploadPretreatment uploadPretreatment = fileStorageService.of(file).setPlatform(storageCode);
|
||||
UploadPretreatment uploadPretreatment = fileStorageService.of(file).setPlatform(storage.getCode());
|
||||
uploadPretreatment.setProgressMonitor(new ProgressListener() {
|
||||
@Override
|
||||
public void start() {
|
||||
@@ -85,7 +89,11 @@ public class FileServiceImpl extends BaseServiceImpl<FileMapper, FileDO, FileRes
|
||||
log.info("上传结束");
|
||||
}
|
||||
});
|
||||
uploadPretreatment.upload();
|
||||
// 处理本地存储文件 URL
|
||||
FileInfo fileInfo = uploadPretreatment.upload();
|
||||
fileInfo.setUrl(StorageTypeEnum.LOCAL.equals(storage.getType())
|
||||
? URLUtil.normalize(storage.getDomain() + StringConstants.SLASH + fileInfo.getUrl()) : fileInfo.getUrl());
|
||||
return fileInfo;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@@ -196,7 +196,7 @@ public class StorageServiceImpl
|
||||
new ResourceHandlerRegistry(applicationContext, servletContext, contentNegotiationManager, urlPathHelper);
|
||||
// 重新注册相同 Pattern 的静态资源映射
|
||||
for (Map.Entry<String, String> entry : registerMapping.entrySet()) {
|
||||
String pathPattern = StrUtil.appendIfMissing(entry.getKey(), "/**");
|
||||
String pathPattern = StrUtil.appendIfMissing(entry.getKey(), StringConstants.PATH_PATTERN);
|
||||
String resourceLocations = StrUtil.appendIfMissing(entry.getValue(), StringConstants.SLASH);
|
||||
// 移除之前注册过的相同 Pattern 映射
|
||||
handlerMap.remove(pathPattern);
|
||||
|
@@ -16,7 +16,6 @@
|
||||
|
||||
package top.charles7c.continew.admin.system.service.impl;
|
||||
|
||||
import java.io.File;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.*;
|
||||
|
||||
@@ -24,15 +23,15 @@ import jakarta.annotation.Resource;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import org.dromara.x.file.storage.core.FileInfo;
|
||||
import org.dromara.x.file.storage.core.FileStorageService;
|
||||
import org.springframework.cache.annotation.CacheConfig;
|
||||
import org.springframework.cache.annotation.Cacheable;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.util.unit.DataSize;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.io.FileUtil;
|
||||
import cn.hutool.core.io.file.FileNameUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
@@ -51,17 +50,12 @@ import top.charles7c.continew.admin.system.model.req.UserReq;
|
||||
import top.charles7c.continew.admin.system.model.req.UserRoleUpdateReq;
|
||||
import top.charles7c.continew.admin.system.model.resp.UserDetailResp;
|
||||
import top.charles7c.continew.admin.system.model.resp.UserResp;
|
||||
import top.charles7c.continew.admin.system.service.DeptService;
|
||||
import top.charles7c.continew.admin.system.service.RoleService;
|
||||
import top.charles7c.continew.admin.system.service.UserRoleService;
|
||||
import top.charles7c.continew.admin.system.service.UserService;
|
||||
import top.charles7c.continew.admin.system.service.*;
|
||||
import top.charles7c.continew.starter.core.constant.StringConstants;
|
||||
import top.charles7c.continew.starter.core.util.ExceptionUtils;
|
||||
import top.charles7c.continew.starter.core.util.FileUploadUtils;
|
||||
import top.charles7c.continew.starter.core.util.validate.CheckUtils;
|
||||
import top.charles7c.continew.starter.extension.crud.base.BaseServiceImpl;
|
||||
import top.charles7c.continew.starter.extension.crud.base.CommonUserService;
|
||||
import top.charles7c.continew.starter.storage.local.autoconfigure.LocalStorageProperties;
|
||||
|
||||
/**
|
||||
* 用户业务实现
|
||||
@@ -75,11 +69,12 @@ import top.charles7c.continew.starter.storage.local.autoconfigure.LocalStoragePr
|
||||
public class UserServiceImpl extends BaseServiceImpl<UserMapper, UserDO, UserResp, UserDetailResp, UserQuery, UserReq>
|
||||
implements UserService, CommonUserService {
|
||||
|
||||
private final UserRoleService userRoleService;
|
||||
private final RoleService roleService;
|
||||
private final LocalStorageProperties localStorageProperties;
|
||||
@Resource
|
||||
private DeptService deptService;
|
||||
private final RoleService roleService;
|
||||
private final UserRoleService userRoleService;
|
||||
private final FileService fileService;
|
||||
private final FileStorageService fileStorageService;
|
||||
|
||||
@Override
|
||||
public Long add(UserDO user) {
|
||||
@@ -164,26 +159,20 @@ public class UserServiceImpl extends BaseServiceImpl<UserMapper, UserDO, UserRes
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public String uploadAvatar(MultipartFile avatarFile, Long id) {
|
||||
LocalStorageProperties.LocalStorageMapping storageMapping = localStorageProperties.getMapping().get("AVATAR");
|
||||
DataSize maxFileSize = storageMapping.getMaxFileSize();
|
||||
CheckUtils.throwIf(avatarFile.getSize() > maxFileSize.toBytes(), "请上传小于 {}MB 的图片", maxFileSize.toMegabytes());
|
||||
String avatarImageType = FileNameUtil.extName(avatarFile.getOriginalFilename());
|
||||
String[] avatarSupportImgTypes = FileConstants.AVATAR_SUPPORTED_IMG_TYPES;
|
||||
CheckUtils.throwIf(!StrUtil.equalsAnyIgnoreCase(avatarImageType, avatarSupportImgTypes), "头像仅支持 {} 格式的图片",
|
||||
String.join(StringConstants.CHINESE_COMMA, avatarSupportImgTypes));
|
||||
// 上传新头像
|
||||
UserDO user = super.getById(id);
|
||||
String avatarPath = storageMapping.getLocation();
|
||||
File newAvatarFile = FileUploadUtils.upload(avatarFile, avatarPath, false);
|
||||
CheckUtils.throwIfNull(newAvatarFile, "上传头像失败");
|
||||
assert null != newAvatarFile;
|
||||
FileInfo fileInfo = fileService.upload(avatarFile);
|
||||
// 更新用户头像
|
||||
String newAvatar = newAvatarFile.getName();
|
||||
String newAvatar = fileInfo.getUrl();
|
||||
baseMapper.lambdaUpdate().set(UserDO::getAvatar, newAvatar).eq(UserDO::getId, id).update();
|
||||
// 删除原头像
|
||||
String oldAvatar = user.getAvatar();
|
||||
if (StrUtil.isNotBlank(oldAvatar)) {
|
||||
FileUtil.del(avatarPath + oldAvatar);
|
||||
fileStorageService.delete(oldAvatar);
|
||||
}
|
||||
return newAvatar;
|
||||
}
|
||||
|
Reference in New Issue
Block a user