refactor: 优化存储管理

This commit is contained in:
Charles7c 2024-04-15 22:10:38 +08:00
parent e68c4455a8
commit 6beceaa9a2
16 changed files with 74 additions and 78 deletions

View File

@ -20,9 +20,10 @@ import top.charles7c.continew.admin.system.model.entity.StorageDO;
import top.charles7c.continew.starter.data.mybatis.plus.base.BaseMapper;
/**
* 存储 Mapper
* 存储 Mapper
*
* @author Charles7c
* @since 2023/12/26 22:09
*/
public interface StorageMapper extends BaseMapper<StorageDO> {}
public interface StorageMapper extends BaseMapper<StorageDO> {
}

View File

@ -73,14 +73,14 @@ public class FileDO extends BaseDO {
private FileTypeEnum type;
/**
* 存储 ID
* 存储 ID
*/
private Long storageId;
/**
* 转换为 X-File-Storage 文件信息对象
*
* @param storageCode 存储编码
* @param storageCode 存储编码
* @return X-File-Storage 文件信息对象
*/
public FileInfo toFileInfo(String storageCode) {

View File

@ -16,18 +16,16 @@
package top.charles7c.continew.admin.system.model.entity;
import java.io.Serial;
import lombok.Data;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import top.charles7c.continew.admin.common.enums.DisEnableStatusEnum;
import top.charles7c.continew.admin.system.enums.StorageTypeEnum;
import top.charles7c.continew.starter.extension.crud.model.entity.BaseDO;
import java.io.Serial;
/**
* 存储库实体
* 存储实体
*
* @author Charles7c
* @since 2023/12/26 22:09
@ -55,17 +53,17 @@ public class StorageDO extends BaseDO {
private StorageTypeEnum type;
/**
* Access Key
* Access Key访问密钥
*/
private String accessKey;
/**
* Secret Key
* Secret Key私有密钥
*/
private String secretKey;
/**
* Endpoint
* Endpoint终端节点
*/
private String endpoint;
@ -75,7 +73,7 @@ public class StorageDO extends BaseDO {
private String bucketName;
/**
* 自定义域名
* 域名
*/
private String domain;

View File

@ -25,13 +25,13 @@ import java.io.Serial;
import java.io.Serializable;
/**
* 存储查询条件
* 存储查询条件
*
* @author Charles7c
* @since 2023/12/26 22:09
*/
@Data
@Schema(description = "存储查询条件")
@Schema(description = "存储查询条件")
public class StorageQuery implements Serializable {
@Serial
@ -41,7 +41,7 @@ public class StorageQuery implements Serializable {
* 关键词
*/
@Schema(description = "关键词", example = "本地存储")
@Query(columns = {"name", "description"}, type = QueryType.LIKE)
@Query(columns = {"name", "code", "description"}, type = QueryType.LIKE)
private String description;
/**

View File

@ -30,13 +30,13 @@ import top.charles7c.continew.starter.extension.crud.model.req.BaseReq;
import java.io.Serial;
/**
* 创建或修改存储库信息
* 存储请求信息
*
* @author Charles7c
* @since 2023/12/26 22:09
*/
@Data
@Schema(description = "创建或修改存储库信息")
@Schema(description = "存储请求信息")
public class StorageReq extends BaseReq {
@Serial
@ -45,7 +45,7 @@ public class StorageReq extends BaseReq {
/**
* 名称
*/
@Schema(description = "名称", example = "存储1")
@Schema(description = "名称", example = "存储1")
@NotBlank(message = "名称不能为空")
@Length(max = 100, message = "名称长度不能超过 {max} 个字符")
private String name;
@ -94,10 +94,10 @@ public class StorageReq extends BaseReq {
private String bucketName;
/**
* 自定义域名
* 域名
*/
@Schema(description = "自定义域名", example = "http://localhost:8000/file")
@Length(max = 255, message = "自定义域名长度不能超过 {max} 个字符")
@Schema(description = "域名", example = "http://localhost:8000/file")
@Length(max = 255, message = "域名长度不能超过 {max} 个字符")
private String domain;
/**
@ -109,7 +109,7 @@ public class StorageReq extends BaseReq {
/**
* 描述
*/
@Schema(description = "描述", example = "存储描述")
@Schema(description = "描述", example = "存储描述")
@Length(max = 200, message = "描述长度不能超过 {max} 个字符")
private String description;

View File

@ -73,8 +73,8 @@ public class FileResp extends BaseDetailResp {
private FileTypeEnum type;
/**
* 存储 ID
* 存储 ID
*/
@Schema(description = "存储ID", example = "1")
@Schema(description = "存储ID", example = "1")
private Long storageId;
}

View File

@ -26,13 +26,13 @@ import top.charles7c.continew.starter.extension.crud.model.resp.BaseDetailResp;
import java.io.Serial;
/**
* 存储信息
* 存储响应信息
*
* @author Charles7c
* @since 2023/12/26 22:09
*/
@Data
@Schema(description = "存储信息")
@Schema(description = "存储响应信息")
public class StorageResp extends BaseDetailResp {
@Serial
@ -41,7 +41,7 @@ public class StorageResp extends BaseDetailResp {
/**
* 名称
*/
@Schema(description = "名称", example = "存储1")
@Schema(description = "名称", example = "存储1")
private String name;
/**
@ -88,15 +88,15 @@ public class StorageResp extends BaseDetailResp {
private String bucketName;
/**
* 自定义域名
* 域名
*/
@Schema(description = "自定义域名", example = "http://localhost:8000/file")
@Schema(description = "域名", example = "http://localhost:8000/file")
private String domain;
/**
* 描述
*/
@Schema(description = "描述", example = "存储描述")
@Schema(description = "描述", example = "存储描述")
private String description;
/**

View File

@ -36,7 +36,7 @@ import java.util.List;
public interface FileService extends BaseService<FileResp, FileResp, FileQuery, FileReq>, IService<FileDO> {
/**
* 上传到默认存储
* 上传到默认存储
*
* @param file 文件信息
* @return 文件信息
@ -46,18 +46,18 @@ public interface FileService extends BaseService<FileResp, FileResp, FileQuery,
}
/**
* 上传到指定存储
* 上传到指定存储
*
* @param file 文件信息
* @param storageCode 存储编码
* @param storageCode 存储编码
* @return 文件信息
*/
FileInfo upload(MultipartFile file, String storageCode);
/**
* 根据存储 ID 列表查询
* 根据存储 ID 列表查询
*
* @param storageIds 存储 ID 列表
* @param storageIds 存储 ID 列表
* @return 文件数量
*/
Long countByStorageIds(List<Long> storageIds);

View File

@ -24,7 +24,7 @@ import top.charles7c.continew.starter.data.mybatis.plus.service.IService;
import top.charles7c.continew.starter.extension.crud.service.BaseService;
/**
* 存储业务接口
* 存储业务接口
*
* @author Charles7c
* @since 2023/12/26 22:09
@ -32,9 +32,9 @@ import top.charles7c.continew.starter.extension.crud.service.BaseService;
public interface StorageService extends BaseService<StorageResp, StorageResp, StorageQuery, StorageReq>, IService<StorageDO> {
/**
* 查询默认存储
* 查询默认存储
*
* @return 存储信息
* @return 存储信息
*/
StorageDO getDefaultStorage();
@ -42,23 +42,21 @@ public interface StorageService extends BaseService<StorageResp, StorageResp, St
* 根据编码查询
*
* @param code 编码
* @return 存储信息
* @return 存储信息
*/
StorageDO getByCode(String code);
/**
* 加载存储
* 加载存储
*
* @param req
* 存储库信息
* @param req 存储信息
*/
void load(StorageReq req);
/**
* 卸载存储
* 卸载存储
*
* @param req
* 存储库信息
* @param req 存储信息
*/
void unload(StorageReq req);
}

View File

@ -78,7 +78,7 @@ public class FileServiceImpl extends BaseServiceImpl<FileMapper, FileDO, FileRes
StorageDO storage;
if (StrUtil.isBlank(storageCode)) {
storage = storageService.getDefaultStorage();
CheckUtils.throwIfNull(storage, "请先指定默认存储");
CheckUtils.throwIfNull(storage, "请先指定默认存储");
} else {
storage = storageService.getByCode(storageCode);
CheckUtils.throwIfNotExists(storage, "StorageDO", "Code", storageCode);

View File

@ -48,7 +48,7 @@ import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
/**
* 存储业务实现
* 存储业务实现
*
* @author Charles7c
* @since 2023/12/26 22:09
@ -57,13 +57,13 @@ import java.util.concurrent.CopyOnWriteArrayList;
@RequiredArgsConstructor
public class StorageServiceImpl extends BaseServiceImpl<StorageMapper, StorageDO, StorageResp, StorageResp, StorageQuery, StorageReq> implements StorageService {
private final FileStorageService fileStorageService;
@Resource
private FileService fileService;
private final FileStorageService fileStorageService;
@Override
protected void beforeAdd(StorageReq req) {
CheckUtils.throwIf(Boolean.TRUE.equals(req.getIsDefault()) && this.isDefaultExists(null), "请先取消原有默认存储");
CheckUtils.throwIf(Boolean.TRUE.equals(req.getIsDefault()) && this.isDefaultExists(null), "请先取消原有默认存储");
String code = req.getCode();
CheckUtils.throwIf(this.isCodeExists(code, null), "新增失败,[{}] 已存在", code);
this.load(req);
@ -76,7 +76,7 @@ public class StorageServiceImpl extends BaseServiceImpl<StorageMapper, StorageDO
DisEnableStatusEnum newStatus = req.getStatus();
StorageDO oldStorage = super.getById(id);
CheckUtils.throwIf(Boolean.TRUE.equals(oldStorage.getIsDefault()) && DisEnableStatusEnum.DISABLE
.equals(newStatus), "[{}] 是默认存储,不允许禁用", oldStorage.getName());
.equals(newStatus), "[{}] 是默认存储,不允许禁用", oldStorage.getName());
DisEnableStatusEnum oldStatus = oldStorage.getStatus();
if (DisEnableStatusEnum.ENABLE.equals(oldStatus) || DisEnableStatusEnum.DISABLE.equals(newStatus)) {
this.unload(BeanUtil.copyProperties(oldStorage, StorageReq.class));
@ -85,17 +85,17 @@ public class StorageServiceImpl extends BaseServiceImpl<StorageMapper, StorageDO
this.load(req);
}
if (Boolean.TRUE.equals(req.getIsDefault())) {
CheckUtils.throwIf(!DisEnableStatusEnum.ENABLE.equals(oldStatus), "请先启用该存储");
CheckUtils.throwIf(this.isDefaultExists(id), "请先取消原有默认存储");
CheckUtils.throwIf(!DisEnableStatusEnum.ENABLE.equals(oldStatus), "请先启用该存储");
CheckUtils.throwIf(this.isDefaultExists(id), "请先取消原有默认存储");
}
}
@Override
protected void beforeDelete(List<Long> ids) {
CheckUtils.throwIf(fileService.countByStorageIds(ids) > 0, "所选存储存在文件关联,请删除文件后重试");
CheckUtils.throwIf(fileService.countByStorageIds(ids) > 0, "所选存储存在文件关联,请删除文件后重试");
List<StorageDO> storageList = baseMapper.lambdaQuery().in(StorageDO::getId, ids).list();
storageList.forEach(s -> {
CheckUtils.throwIfEqual(Boolean.TRUE, s.getIsDefault(), "[{}] 是默认存储,不允许禁用", s.getName());
CheckUtils.throwIfEqual(Boolean.TRUE, s.getIsDefault(), "[{}] 是默认存储,不允许禁用", s.getName());
this.unload(BeanUtil.copyProperties(s, StorageReq.class));
});
}
@ -118,8 +118,8 @@ public class StorageServiceImpl extends BaseServiceImpl<StorageMapper, StorageDO
StorageTypeEnum type = req.getType();
if (StorageTypeEnum.LOCAL.equals(type)) {
ValidationUtils.throwIfBlank(bucketName, "存储路径不能为空");
ValidationUtils.throwIfBlank(domain, "自定义域名不能为空");
ValidationUtils.throwIf(!URLUtils.isHttpUrl(domain), "自定义域名格式错误");
ValidationUtils.throwIfBlank(domain, "域名不能为空");
ValidationUtils.throwIf(!URLUtils.isHttpUrl(domain), "域名格式错误");
req.setBucketName(StrUtil.appendIfMissing(bucketName
.replace(StringConstants.BACKSLASH, StringConstants.SLASH), StringConstants.SLASH));
FileStorageProperties.LocalPlusConfig config = new FileStorageProperties.LocalPlusConfig();
@ -159,7 +159,7 @@ public class StorageServiceImpl extends BaseServiceImpl<StorageMapper, StorageDO
}
/**
* 默认存储是否存在
* 默认存储是否存在
*
* @param id ID
* @return 是否存在

View File

@ -27,12 +27,13 @@ import top.charles7c.continew.starter.extension.crud.controller.BaseController;
import top.charles7c.continew.starter.extension.crud.enums.Api;
/**
* 存储管理 API
* 存储管理 API
*
* @author Charles7c
* @since 2023/12/26 22:09
*/
@Tag(name = "存储管理 API")
@Tag(name = "存储管理 API")
@RestController
@CrudRequestMapping(value = "/system/storage", api = {Api.PAGE, Api.GET, Api.ADD, Api.UPDATE, Api.DELETE})
public class StorageController extends BaseController<StorageService, StorageResp, StorageResp, StorageQuery, StorageReq> {}
public class StorageController extends BaseController<StorageService, StorageResp, StorageResp, StorageQuery, StorageReq> {
}

View File

@ -57,10 +57,9 @@ VALUES
(1106, '文件下载', 1100, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:file:download', 6, 1, 1, NOW(), NULL, NULL),
(1110, '存储管理', 1000, 2, '/system/storage', 'Storage', 'system/storage/index', NULL, 'storage', b'0', b'0', b'0', NULL, 8, 1, 1, NOW(), NULL, NULL),
(1111, '存储列表', 1110, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:storage:list', 1, 1, 1, NOW(), NULL, NULL),
(1112, '存储详情', 1110, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:storage:detail', 2, 1, 1, NOW(), NULL, NULL),
(1113, '存储新增', 1110, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:storage:add', 3, 1, 1, NOW(), NULL, NULL),
(1114, '存储修改', 1110, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:storage:update', 4, 1, 1, NOW(), NULL, NULL),
(1115, '存储删除', 1110, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:storage:delete', 5, 1, 1, NOW(), NULL, NULL),
(1112, '存储新增', 1110, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:storage:add', 2, 1, 1, NOW(), NULL, NULL),
(1113, '存储修改', 1110, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:storage:update', 3, 1, 1, NOW(), NULL, NULL),
(1114, '存储删除', 1110, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:storage:delete', 4, 1, 1, NOW(), NULL, NULL),
(1190, '系统配置', 1000, 2, '/system/config', 'Config', 'system/config/index', NULL, 'desktop', b'0', b'0', b'0', NULL, 999, 1, 1, NOW(), NULL, NULL),
(1191, '配置查询', 1190, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:config:query', 1, 1, 1, NOW(), NULL, NULL),
(1192, '配置修改', 1190, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:config:update', 2, 1, 1, NOW(), NULL, NULL),
@ -150,7 +149,7 @@ VALUES
-- 初始化默认角色和部门关联数据
INSERT INTO `sys_role_dept` (`role_id`, `dept_id`) VALUES (547888897925840928, 547888483713155087);
-- 初始化默认存储
-- 初始化默认存储
INSERT INTO `sys_storage`
(`id`, `name`, `code`, `type`, `access_key`, `secret_key`, `endpoint`, `bucket_name`, `domain`, `description`, `is_default`, `sort`, `status`, `create_user`, `create_time`, `update_user`, `update_time`)
VALUES

View File

@ -241,7 +241,7 @@ CREATE TABLE IF NOT EXISTS `sys_storage` (
`secret_key` varchar(255) DEFAULT NULL COMMENT 'Secret Key私有密钥',
`endpoint` varchar(255) DEFAULT NULL COMMENT 'Endpoint终端节点',
`bucket_name` varchar(255) DEFAULT NULL COMMENT '桶名称',
`domain` varchar(255) NOT NULL DEFAULT '' COMMENT '自定义域名',
`domain` varchar(255) NOT NULL DEFAULT '' COMMENT '域名',
`description` varchar(200) DEFAULT NULL COMMENT '描述',
`is_default` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否为默认存储',
`sort` int NOT NULL DEFAULT 999 COMMENT '排序',
@ -254,7 +254,7 @@ CREATE TABLE IF NOT EXISTS `sys_storage` (
UNIQUE INDEX `uk_code`(`code`) USING BTREE,
INDEX `idx_create_user`(`create_user`) USING BTREE,
INDEX `idx_update_user`(`update_user`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='存储';
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='存储';
CREATE TABLE IF NOT EXISTS `sys_file` (
`id` bigint(20) NOT NULL COMMENT 'ID',
@ -263,7 +263,7 @@ CREATE TABLE IF NOT EXISTS `sys_file` (
`url` varchar(512) NOT NULL COMMENT 'URL',
`extension` varchar(100) DEFAULT NULL COMMENT '扩展名',
`type` tinyint(1) UNSIGNED NOT NULL DEFAULT 1 COMMENT '类型1其他2图片3文档4视频5音频',
`storage_id` bigint(20) NOT NULL COMMENT '存储ID',
`storage_id` bigint(20) NOT NULL COMMENT '存储ID',
`create_user` bigint(20) NOT NULL COMMENT '创建人',
`create_time` datetime NOT NULL COMMENT '创建时间',
`update_user` bigint(20) NOT NULL COMMENT '修改人',

View File

@ -57,10 +57,9 @@ VALUES
(1106, '文件下载', 1100, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:file:download', 6, 1, 1, NOW(), NULL, NULL),
(1110, '存储管理', 1000, 2, '/system/storage', 'Storage', 'system/storage/index', NULL, 'storage', b'0', b'0', b'0', NULL, 8, 1, 1, NOW(), NULL, NULL),
(1111, '存储列表', 1110, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:storage:list', 1, 1, 1, NOW(), NULL, NULL),
(1112, '存储详情', 1110, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:storage:detail', 2, 1, 1, NOW(), NULL, NULL),
(1113, '存储新增', 1110, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:storage:add', 3, 1, 1, NOW(), NULL, NULL),
(1114, '存储修改', 1110, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:storage:update', 4, 1, 1, NOW(), NULL, NULL),
(1115, '存储删除', 1110, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:storage:delete', 5, 1, 1, NOW(), NULL, NULL),
(1112, '存储新增', 1110, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:storage:add', 2, 1, 1, NOW(), NULL, NULL),
(1113, '存储修改', 1110, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:storage:update', 3, 1, 1, NOW(), NULL, NULL),
(1114, '存储删除', 1110, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:storage:delete', 4, 1, 1, NOW(), NULL, NULL),
(1190, '系统配置', 1000, 2, '/system/config', 'Config', 'system/config/index', NULL, 'desktop', b'0', b'0', b'0', NULL, 999, 1, 1, NOW(), NULL, NULL),
(1191, '配置查询', 1190, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:config:query', 1, 1, 1, NOW(), NULL, NULL),
(1192, '配置修改', 1190, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'system:config:update', 2, 1, 1, NOW(), NULL, NULL),
@ -150,7 +149,7 @@ VALUES
-- 初始化默认角色和部门关联数据
INSERT INTO "sys_role_dept" ("role_id", "dept_id") VALUES (547888897925840928, 547888483713155087);
-- 初始化默认存储
-- 初始化默认存储
INSERT INTO "sys_storage"
("id", "name", "code", "type", "access_key", "secret_key", "endpoint", "bucket_name", "domain", "description", "is_default", "sort", "status", "create_user", "create_time", "update_user", "update_time")
VALUES

View File

@ -420,7 +420,7 @@ COMMENT ON COLUMN "sys_storage"."access_key" IS 'Access Key访问密钥';
COMMENT ON COLUMN "sys_storage"."secret_key" IS 'Secret Key私有密钥';
COMMENT ON COLUMN "sys_storage"."endpoint" IS 'Endpoint终端节点';
COMMENT ON COLUMN "sys_storage"."bucket_name" IS '桶名称';
COMMENT ON COLUMN "sys_storage"."domain" IS '自定义域名';
COMMENT ON COLUMN "sys_storage"."domain" IS '域名';
COMMENT ON COLUMN "sys_storage"."description" IS '描述';
COMMENT ON COLUMN "sys_storage"."is_default" IS '是否为默认存储';
COMMENT ON COLUMN "sys_storage"."sort" IS '排序';
@ -429,7 +429,7 @@ COMMENT ON COLUMN "sys_storage"."create_user" IS '创建人';
COMMENT ON COLUMN "sys_storage"."create_time" IS '创建时间';
COMMENT ON COLUMN "sys_storage"."update_user" IS '修改人';
COMMENT ON COLUMN "sys_storage"."update_time" IS '修改时间';
COMMENT ON TABLE "sys_storage" IS '存储';
COMMENT ON TABLE "sys_storage" IS '存储';
CREATE TABLE IF NOT EXISTS "sys_file" (
"id" int8 NOT NULL,
@ -455,7 +455,7 @@ COMMENT ON COLUMN "sys_file"."size" IS '大小(字节)';
COMMENT ON COLUMN "sys_file"."url" IS 'URL';
COMMENT ON COLUMN "sys_file"."extension" IS '扩展名';
COMMENT ON COLUMN "sys_file"."type" IS '类型1其他2图片3文档4视频5音频';
COMMENT ON COLUMN "sys_file"."storage_id" IS '存储ID';
COMMENT ON COLUMN "sys_file"."storage_id" IS '存储ID';
COMMENT ON COLUMN "sys_file"."create_user" IS '创建人';
COMMENT ON COLUMN "sys_file"."create_time" IS '创建时间';
COMMENT ON COLUMN "sys_file"."update_user" IS '修改人';