feat: 存储管理适配后端 API
This commit is contained in:
parent
9a30da9334
commit
89e4326290
@ -22,6 +22,7 @@ import lombok.Data;
|
|||||||
|
|
||||||
import com.baomidou.mybatisplus.annotation.TableName;
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
|
||||||
|
import top.charles7c.continew.admin.common.enums.DisEnableStatusEnum;
|
||||||
import top.charles7c.continew.admin.system.enums.StorageTypeEnum;
|
import top.charles7c.continew.admin.system.enums.StorageTypeEnum;
|
||||||
import top.charles7c.continew.starter.extension.crud.base.BaseDO;
|
import top.charles7c.continew.starter.extension.crud.base.BaseDO;
|
||||||
|
|
||||||
@ -96,5 +97,5 @@ public class StorageDO extends BaseDO {
|
|||||||
/**
|
/**
|
||||||
* 状态
|
* 状态
|
||||||
*/
|
*/
|
||||||
private Integer status;
|
private DisEnableStatusEnum status;
|
||||||
}
|
}
|
@ -24,6 +24,9 @@ import lombok.Data;
|
|||||||
|
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
|
||||||
|
import org.hibernate.validator.constraints.Length;
|
||||||
|
|
||||||
|
import top.charles7c.continew.admin.common.constant.RegexConstants;
|
||||||
import top.charles7c.continew.admin.common.enums.DisEnableStatusEnum;
|
import top.charles7c.continew.admin.common.enums.DisEnableStatusEnum;
|
||||||
import top.charles7c.continew.admin.system.enums.StorageTypeEnum;
|
import top.charles7c.continew.admin.system.enums.StorageTypeEnum;
|
||||||
import top.charles7c.continew.starter.extension.crud.base.BaseReq;
|
import top.charles7c.continew.starter.extension.crud.base.BaseReq;
|
||||||
@ -44,71 +47,79 @@ public class StorageReq extends BaseReq {
|
|||||||
/**
|
/**
|
||||||
* 名称
|
* 名称
|
||||||
*/
|
*/
|
||||||
@Schema(description = "名称")
|
@Schema(description = "名称", example = "存储库1")
|
||||||
@NotBlank(message = "名称不能为空")
|
@NotBlank(message = "名称不能为空")
|
||||||
|
@Length(max = 100, message = "名称长度不能超过 {max} 个字符")
|
||||||
private String name;
|
private String name;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 编码
|
* 编码
|
||||||
*/
|
*/
|
||||||
@Schema(description = "编码")
|
@Schema(description = "编码", example = "local")
|
||||||
@NotBlank(message = "编码不能为空")
|
@NotBlank(message = "编码不能为空")
|
||||||
|
@Pattern(regexp = RegexConstants.GENERAL_CODE, message = "编码长度为 2 到 30 位,可以包含字母、数字,下划线,以字母开头")
|
||||||
private String code;
|
private String code;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 类型
|
* 类型
|
||||||
*/
|
*/
|
||||||
@Schema(description = "类型")
|
@Schema(description = "类型", type = "Integer", allowableValues = {"1", "2"}, example = "2")
|
||||||
@NotNull(message = "类型非法")
|
@NotNull(message = "类型非法")
|
||||||
private StorageTypeEnum type;
|
private StorageTypeEnum type;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Access Key
|
* Access Key
|
||||||
*/
|
*/
|
||||||
@Schema(description = "Access Key")
|
@Schema(description = "Access Key", example = "")
|
||||||
|
@Length(max = 255, message = "Access Key长度不能超过 {max} 个字符")
|
||||||
private String accessKey;
|
private String accessKey;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Secret Key
|
* Secret Key
|
||||||
*/
|
*/
|
||||||
@Schema(description = "Secret Key")
|
@Schema(description = "Secret Key", example = "")
|
||||||
|
@Length(max = 255, message = "Secret Key长度不能超过 {max} 个字符")
|
||||||
private String secretKey;
|
private String secretKey;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Endpoint
|
* Endpoint
|
||||||
*/
|
*/
|
||||||
@Schema(description = "Endpoint")
|
@Schema(description = "Endpoint", example = "")
|
||||||
|
@Length(max = 255, message = "Endpoint长度不能超过 {max} 个字符")
|
||||||
private String endpoint;
|
private String endpoint;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 桶名称
|
* 桶名称
|
||||||
*/
|
*/
|
||||||
@Schema(description = "桶名称")
|
@Schema(description = "桶名称", example = "C:/continew-admin/data/file/")
|
||||||
|
@Length(max = 255, message = "桶名称长度不能超过 {max} 个字符")
|
||||||
private String bucketName;
|
private String bucketName;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 自定义域名
|
* 自定义域名
|
||||||
*/
|
*/
|
||||||
@Schema(description = "自定义域名")
|
@Schema(description = "自定义域名", example = "http://localhost:8000/file")
|
||||||
|
@Length(max = 255, message = "自定义域名长度不能超过 {max} 个字符")
|
||||||
private String domain;
|
private String domain;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 描述
|
* 描述
|
||||||
*/
|
*/
|
||||||
@Schema(description = "描述")
|
@Schema(description = "描述", example = "存储库描述")
|
||||||
|
@Length(max = 200, message = "描述长度不能超过 {max} 个字符")
|
||||||
private String description;
|
private String description;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 是否为默认存储
|
* 是否为默认存储
|
||||||
*/
|
*/
|
||||||
@Schema(description = "是否为默认存储")
|
@Schema(description = "是否为默认存储", example = "true")
|
||||||
@NotNull(message = "是否为默认存储不能为空")
|
@NotNull(message = "是否为默认存储不能为空")
|
||||||
private Boolean isDefault;
|
private Boolean isDefault;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 排序
|
* 排序
|
||||||
*/
|
*/
|
||||||
@Schema(description = "排序")
|
@Schema(description = "排序", example = "1")
|
||||||
private Integer sort;
|
private Integer sort;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -23,7 +23,6 @@ import lombok.Data;
|
|||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
|
||||||
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
|
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
|
||||||
import com.alibaba.excel.annotation.ExcelProperty;
|
|
||||||
|
|
||||||
import top.charles7c.continew.admin.system.enums.FileTypeEnum;
|
import top.charles7c.continew.admin.system.enums.FileTypeEnum;
|
||||||
import top.charles7c.continew.starter.extension.crud.base.BaseDetailResp;
|
import top.charles7c.continew.starter.extension.crud.base.BaseDetailResp;
|
||||||
@ -46,48 +45,35 @@ public class FileResp extends BaseDetailResp {
|
|||||||
* 名称
|
* 名称
|
||||||
*/
|
*/
|
||||||
@Schema(description = "名称", example = "example")
|
@Schema(description = "名称", example = "example")
|
||||||
@ExcelProperty(value = "名称")
|
|
||||||
private String name;
|
private String name;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 大小(字节)
|
* 大小(字节)
|
||||||
*/
|
*/
|
||||||
@Schema(description = "大小(字节)", example = "4096")
|
@Schema(description = "大小(字节)", example = "4096")
|
||||||
@ExcelProperty(value = "大小(字节)")
|
|
||||||
private Long size;
|
private Long size;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* URL
|
* URL
|
||||||
*/
|
*/
|
||||||
@Schema(description = "URL", example = "https://examplebucket.oss-cn-hangzhou.aliyuncs.com/example/example.jpg")
|
@Schema(description = "URL", example = "https://examplebucket.oss-cn-hangzhou.aliyuncs.com/example/example.jpg")
|
||||||
@ExcelProperty(value = "URL")
|
|
||||||
private String url;
|
private String url;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 扩展名
|
* 扩展名
|
||||||
*/
|
*/
|
||||||
@Schema(description = "扩展名", example = "jpg")
|
@Schema(description = "扩展名", example = "jpg")
|
||||||
@ExcelProperty(value = "扩展名")
|
|
||||||
private String extension;
|
private String extension;
|
||||||
|
|
||||||
/**
|
|
||||||
* MIME类型
|
|
||||||
*/
|
|
||||||
@Schema(description = "MIME类型")
|
|
||||||
@ExcelProperty(value = "MIME类型")
|
|
||||||
private String mimeType;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 类型
|
* 类型
|
||||||
*/
|
*/
|
||||||
@Schema(description = "类型", type = "Integer", allowableValues = {"1", "2", "3", "4", "5"}, example = "2")
|
@Schema(description = "类型", type = "Integer", allowableValues = {"1", "2", "3", "4", "5"}, example = "2")
|
||||||
@ExcelProperty(value = "类型")
|
|
||||||
private FileTypeEnum type;
|
private FileTypeEnum type;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 存储库 ID
|
* 存储库 ID
|
||||||
*/
|
*/
|
||||||
@Schema(description = "存储库ID", example = "1")
|
@Schema(description = "存储库ID", example = "1")
|
||||||
@ExcelProperty(value = "存储库ID")
|
|
||||||
private Long storageId;
|
private Long storageId;
|
||||||
}
|
}
|
@ -25,6 +25,8 @@ import io.swagger.v3.oas.annotations.media.Schema;
|
|||||||
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
|
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
|
||||||
import com.alibaba.excel.annotation.ExcelProperty;
|
import com.alibaba.excel.annotation.ExcelProperty;
|
||||||
|
|
||||||
|
import top.charles7c.continew.admin.common.config.easyexcel.ExcelBaseEnumConverter;
|
||||||
|
import top.charles7c.continew.admin.common.enums.DisEnableStatusEnum;
|
||||||
import top.charles7c.continew.admin.system.enums.StorageTypeEnum;
|
import top.charles7c.continew.admin.system.enums.StorageTypeEnum;
|
||||||
import top.charles7c.continew.starter.extension.crud.base.BaseDetailResp;
|
import top.charles7c.continew.starter.extension.crud.base.BaseDetailResp;
|
||||||
|
|
||||||
@ -45,83 +47,89 @@ public class StorageDetailResp extends BaseDetailResp {
|
|||||||
/**
|
/**
|
||||||
* 名称
|
* 名称
|
||||||
*/
|
*/
|
||||||
@Schema(description = "名称")
|
@Schema(description = "名称", example = "存储库1")
|
||||||
@ExcelProperty(value = "名称")
|
@ExcelProperty(value = "名称")
|
||||||
private String name;
|
private String name;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 编码
|
* 编码
|
||||||
*/
|
*/
|
||||||
@Schema(description = "编码")
|
@Schema(description = "编码", example = "local")
|
||||||
@ExcelProperty(value = "编码")
|
@ExcelProperty(value = "编码")
|
||||||
private String code;
|
private String code;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 类型
|
* 类型
|
||||||
*/
|
*/
|
||||||
@Schema(description = "类型")
|
@Schema(description = "类型", type = "Integer", allowableValues = {"1", "2"}, example = "2")
|
||||||
|
@ExcelProperty(value = "类型", converter = ExcelBaseEnumConverter.class)
|
||||||
private StorageTypeEnum type;
|
private StorageTypeEnum type;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Access Key
|
* Access Key
|
||||||
*/
|
*/
|
||||||
@Schema(description = "Access Key")
|
@Schema(description = "Access Key", example = "")
|
||||||
@ExcelProperty(value = "Access Key")
|
@ExcelProperty(value = "Access Key")
|
||||||
private String accessKey;
|
private String accessKey;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Secret Key
|
* Secret Key
|
||||||
*/
|
*/
|
||||||
@Schema(description = "Secret Key")
|
@Schema(description = "Secret Key", example = "")
|
||||||
@ExcelProperty(value = "Secret Key")
|
@ExcelProperty(value = "Secret Key")
|
||||||
private String secretKey;
|
private String secretKey;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Endpoint
|
* Endpoint
|
||||||
*/
|
*/
|
||||||
@Schema(description = "Endpoint")
|
@Schema(description = "Endpoint", example = "")
|
||||||
@ExcelProperty(value = "Endpoint")
|
@ExcelProperty(value = "Endpoint")
|
||||||
private String endpoint;
|
private String endpoint;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 桶名称
|
* 桶名称
|
||||||
*/
|
*/
|
||||||
@Schema(description = "桶名称")
|
@Schema(description = "桶名称", example = "C:/continew-admin/data/file/")
|
||||||
@ExcelProperty(value = "桶名称")
|
@ExcelProperty(value = "桶名称")
|
||||||
private String bucketName;
|
private String bucketName;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 自定义域名
|
* 自定义域名
|
||||||
*/
|
*/
|
||||||
@Schema(description = "自定义域名")
|
@Schema(description = "自定义域名", example = "http://localhost:8000/file")
|
||||||
@ExcelProperty(value = "自定义域名")
|
@ExcelProperty(value = "自定义域名")
|
||||||
private String domain;
|
private String domain;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 描述
|
* 描述
|
||||||
*/
|
*/
|
||||||
@Schema(description = "描述")
|
@Schema(description = "描述", example = "存储库描述")
|
||||||
@ExcelProperty(value = "描述")
|
@ExcelProperty(value = "描述")
|
||||||
private String description;
|
private String description;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 是否为默认存储
|
* 是否为默认存储
|
||||||
*/
|
*/
|
||||||
@Schema(description = "是否为默认存储")
|
@Schema(description = "是否为默认存储", example = "true")
|
||||||
@ExcelProperty(value = "是否为默认存储")
|
@ExcelProperty(value = "是否为默认存储")
|
||||||
private Boolean isDefault;
|
private Boolean isDefault;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 排序
|
* 排序
|
||||||
*/
|
*/
|
||||||
@Schema(description = "排序")
|
@Schema(description = "排序", example = "1")
|
||||||
@ExcelProperty(value = "排序")
|
@ExcelProperty(value = "排序")
|
||||||
private Integer sort;
|
private Integer sort;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 状态
|
* 状态
|
||||||
*/
|
*/
|
||||||
@Schema(description = "状态")
|
@Schema(description = "状态(1:启用;2:禁用)", type = "Integer", allowableValues = {"1", "2"}, example = "1")
|
||||||
@ExcelProperty(value = "状态")
|
@ExcelProperty(value = "状态", converter = ExcelBaseEnumConverter.class)
|
||||||
private Integer status;
|
private DisEnableStatusEnum status;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Boolean getDisabled() {
|
||||||
|
return this.getIsDefault();
|
||||||
|
}
|
||||||
}
|
}
|
@ -22,6 +22,9 @@ import lombok.Data;
|
|||||||
|
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||||
|
|
||||||
|
import top.charles7c.continew.admin.common.enums.DisEnableStatusEnum;
|
||||||
import top.charles7c.continew.admin.system.enums.StorageTypeEnum;
|
import top.charles7c.continew.admin.system.enums.StorageTypeEnum;
|
||||||
import top.charles7c.continew.starter.extension.crud.base.BaseResp;
|
import top.charles7c.continew.starter.extension.crud.base.BaseResp;
|
||||||
|
|
||||||
@ -41,72 +44,78 @@ public class StorageResp extends BaseResp {
|
|||||||
/**
|
/**
|
||||||
* 名称
|
* 名称
|
||||||
*/
|
*/
|
||||||
@Schema(description = "名称")
|
@Schema(description = "名称", example = "存储库1")
|
||||||
private String name;
|
private String name;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 编码
|
* 编码
|
||||||
*/
|
*/
|
||||||
@Schema(description = "编码")
|
@Schema(description = "编码", example = "local")
|
||||||
private String code;
|
private String code;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 类型
|
* 类型
|
||||||
*/
|
*/
|
||||||
@Schema(description = "类型")
|
@Schema(description = "类型", type = "Integer", allowableValues = {"1", "2"}, example = "2")
|
||||||
private StorageTypeEnum type;
|
private StorageTypeEnum type;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Access Key
|
* Access Key
|
||||||
*/
|
*/
|
||||||
@Schema(description = "Access Key")
|
@Schema(description = "Access Key", example = "")
|
||||||
private String accessKey;
|
private String accessKey;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Secret Key
|
* Secret Key
|
||||||
*/
|
*/
|
||||||
@Schema(description = "Secret Key")
|
@Schema(description = "Secret Key", example = "")
|
||||||
|
@JsonIgnore
|
||||||
private String secretKey;
|
private String secretKey;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Endpoint
|
* Endpoint
|
||||||
*/
|
*/
|
||||||
@Schema(description = "Endpoint")
|
@Schema(description = "Endpoint", example = "")
|
||||||
private String endpoint;
|
private String endpoint;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 桶名称
|
* 桶名称
|
||||||
*/
|
*/
|
||||||
@Schema(description = "桶名称")
|
@Schema(description = "桶名称", example = "C:/continew-admin/data/file/")
|
||||||
private String bucketName;
|
private String bucketName;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 自定义域名
|
* 自定义域名
|
||||||
*/
|
*/
|
||||||
@Schema(description = "自定义域名")
|
@Schema(description = "自定义域名", example = "http://localhost:8000/file")
|
||||||
private String domain;
|
private String domain;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 描述
|
* 描述
|
||||||
*/
|
*/
|
||||||
@Schema(description = "描述")
|
@Schema(description = "描述", example = "存储库描述")
|
||||||
private String description;
|
private String description;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 是否为默认存储
|
* 是否为默认存储
|
||||||
*/
|
*/
|
||||||
@Schema(description = "是否为默认存储")
|
@Schema(description = "是否为默认存储", example = "true")
|
||||||
private Boolean isDefault;
|
private Boolean isDefault;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 排序
|
* 排序
|
||||||
*/
|
*/
|
||||||
@Schema(description = "排序")
|
@Schema(description = "排序", example = "1")
|
||||||
private Integer sort;
|
private Integer sort;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 状态
|
* 状态
|
||||||
*/
|
*/
|
||||||
@Schema(description = "状态")
|
@Schema(description = "状态(1:启用;2:禁用)", type = "Integer", allowableValues = {"1", "2"}, example = "1")
|
||||||
private Integer status;
|
private DisEnableStatusEnum status;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Boolean getDisabled() {
|
||||||
|
return this.getIsDefault();
|
||||||
|
}
|
||||||
}
|
}
|
@ -78,6 +78,7 @@ public class StorageServiceImpl
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Long add(StorageReq req) {
|
public Long add(StorageReq req) {
|
||||||
|
CheckUtils.throwIf(Boolean.TRUE.equals(req.getIsDefault()) && this.isDefaultExists(null), "请先取消原有默认存储库");
|
||||||
String code = req.getCode();
|
String code = req.getCode();
|
||||||
CheckUtils.throwIf(this.isCodeExists(code, null), "新增失败,[{}] 已存在", code);
|
CheckUtils.throwIf(this.isCodeExists(code, null), "新增失败,[{}] 已存在", code);
|
||||||
req.setStatus(DisEnableStatusEnum.ENABLE);
|
req.setStatus(DisEnableStatusEnum.ENABLE);
|
||||||
@ -87,14 +88,20 @@ public class StorageServiceImpl
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void update(StorageReq req, Long id) {
|
public void update(StorageReq req, Long id) {
|
||||||
|
CheckUtils.throwIf(Boolean.TRUE.equals(req.getIsDefault()) && this.isDefaultExists(id), "请先取消原有默认存储库");
|
||||||
String code = req.getCode();
|
String code = req.getCode();
|
||||||
CheckUtils.throwIf(this.isCodeExists(code, id), "修改失败,[{}] 已存在", code);
|
CheckUtils.throwIf(this.isCodeExists(code, id), "修改失败,[{}] 已存在", code);
|
||||||
StorageDO oldStorage = super.getById(id);
|
StorageDO oldStorage = super.getById(id);
|
||||||
CheckUtils.throwIf(
|
CheckUtils.throwIf(
|
||||||
Boolean.TRUE.equals(oldStorage.getIsDefault()) && DisEnableStatusEnum.DISABLE.equals(req.getStatus()),
|
Boolean.TRUE.equals(oldStorage.getIsDefault()) && DisEnableStatusEnum.DISABLE.equals(req.getStatus()),
|
||||||
"[{}] 是默认存储库,不允许禁用", oldStorage.getName());
|
"[{}] 是默认存储库,不允许禁用", oldStorage.getName());
|
||||||
this.unload(BeanUtil.copyProperties(oldStorage, StorageReq.class));
|
if (DisEnableStatusEnum.ENABLE.equals(oldStorage.getStatus())
|
||||||
this.load(req);
|
|| DisEnableStatusEnum.DISABLE.equals(req.getStatus())) {
|
||||||
|
this.unload(BeanUtil.copyProperties(oldStorage, StorageReq.class));
|
||||||
|
}
|
||||||
|
if (DisEnableStatusEnum.ENABLE.equals(req.getStatus())) {
|
||||||
|
this.load(req);
|
||||||
|
}
|
||||||
super.update(req, id);
|
super.update(req, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -102,7 +109,10 @@ public class StorageServiceImpl
|
|||||||
public void delete(List<Long> ids) {
|
public void delete(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();
|
List<StorageDO> storageList = baseMapper.lambdaQuery().in(StorageDO::getId, ids).list();
|
||||||
storageList.forEach(s -> this.unload(BeanUtil.copyProperties(s, StorageReq.class)));
|
storageList.forEach(s -> {
|
||||||
|
CheckUtils.throwIfEqual(Boolean.TRUE, s.getIsDefault(), "[{}] 是默认存储库,不允许禁用", s.getName());
|
||||||
|
this.unload(BeanUtil.copyProperties(s, StorageReq.class));
|
||||||
|
});
|
||||||
super.delete(ids);
|
super.delete(ids);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -161,6 +171,18 @@ public class StorageServiceImpl
|
|||||||
this.registerResource(MapUtil.of(URLUtil.url(req.getDomain()).getPath(), req.getBucketName()), true);
|
this.registerResource(MapUtil.of(URLUtil.url(req.getDomain()).getPath(), req.getBucketName()), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 默认存储库是否存在
|
||||||
|
*
|
||||||
|
* @param id
|
||||||
|
* ID
|
||||||
|
* @return 是否存在
|
||||||
|
*/
|
||||||
|
private boolean isDefaultExists(Long id) {
|
||||||
|
return baseMapper.lambdaQuery().eq(StorageDO::getIsDefault, Boolean.TRUE).ne(null != id, StorageDO::getId, id)
|
||||||
|
.exists();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 编码是否存在
|
* 编码是否存在
|
||||||
*
|
*
|
||||||
|
@ -9,7 +9,6 @@ export interface FileItem {
|
|||||||
size: number;
|
size: number;
|
||||||
url: string;
|
url: string;
|
||||||
extension: string;
|
extension: string;
|
||||||
mimeType?: string;
|
|
||||||
type?: string;
|
type?: string;
|
||||||
storageId?: string;
|
storageId?: string;
|
||||||
createUser?: string;
|
createUser?: string;
|
||||||
|
64
continew-admin-ui/src/api/system/storage.ts
Normal file
64
continew-admin-ui/src/api/system/storage.ts
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
import axios from 'axios';
|
||||||
|
import qs from 'query-string';
|
||||||
|
|
||||||
|
const BASE_URL = '/system/storage';
|
||||||
|
|
||||||
|
export interface DataRecord {
|
||||||
|
id?: number;
|
||||||
|
name?: string;
|
||||||
|
code?: string;
|
||||||
|
type?: number;
|
||||||
|
accessKey?: string;
|
||||||
|
secretKey?: string;
|
||||||
|
endpoint?: string;
|
||||||
|
bucketName?: string;
|
||||||
|
domain?: string;
|
||||||
|
description?: string;
|
||||||
|
isDefault?: boolean;
|
||||||
|
sort?: number;
|
||||||
|
status?: number;
|
||||||
|
createUser?: string;
|
||||||
|
createTime?: string;
|
||||||
|
updateUser?: string;
|
||||||
|
updateTime?: string;
|
||||||
|
createUserString?: string;
|
||||||
|
updateUserString?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ListParam {
|
||||||
|
name?: string;
|
||||||
|
status?: string;
|
||||||
|
page?: number;
|
||||||
|
size?: number;
|
||||||
|
sort?: Array<string>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface PageRes<T> {
|
||||||
|
total: number;
|
||||||
|
list: T;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function list(params: ListParam) {
|
||||||
|
return axios.get<PageRes<DataRecord[]>>(`${BASE_URL}`, {
|
||||||
|
params,
|
||||||
|
paramsSerializer: (obj) => {
|
||||||
|
return qs.stringify(obj);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function get(id: number) {
|
||||||
|
return axios.get<DataRecord>(`${BASE_URL}/${id}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function add(req: DataRecord) {
|
||||||
|
return axios.post(BASE_URL, req);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function update(req: DataRecord, id: number) {
|
||||||
|
return axios.put(`${BASE_URL}/${id}`, req);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function del(ids: number | Array<number>) {
|
||||||
|
return axios.delete(`${BASE_URL}/${ids}`);
|
||||||
|
}
|
@ -1,3 +1,3 @@
|
|||||||
export default {
|
export default {
|
||||||
'menu.system.file.list': '文件管理(尚在开发)',
|
'menu.system.file.list': '文件管理',
|
||||||
};
|
};
|
||||||
|
@ -1,18 +1,18 @@
|
|||||||
<template>
|
<template>
|
||||||
<GiOption :class="{ option: showClassStyle }">
|
<GiOption :class="{ option: showClassStyle }">
|
||||||
<GiOptionItem @click="onClickItem('rename')">
|
<GiOptionItem v-permission="['system:file:update']" @click="onClickItem('rename')">
|
||||||
<template #icon><svg-icon icon-class="menu-edit" /></template>
|
<template #icon><svg-icon icon-class="menu-edit" /></template>
|
||||||
<span>重命名</span>
|
<span>重命名</span>
|
||||||
</GiOptionItem>
|
</GiOptionItem>
|
||||||
<GiOptionItem @click="onClickItem('download')">
|
<GiOptionItem v-permission="['system:file:download']" @click="onClickItem('download')">
|
||||||
<template #icon><svg-icon icon-class="menu-download" /></template>
|
<template #icon><svg-icon icon-class="menu-download" /></template>
|
||||||
<span>下载</span>
|
<span>下载</span>
|
||||||
</GiOptionItem>
|
</GiOptionItem>
|
||||||
<GiOptionItem @click="onClickItem('detail')">
|
<GiOptionItem v-permission="['system:file:list']" @click="onClickItem('detail')">
|
||||||
<template #icon><svg-icon icon-class="menu-detail" /></template>
|
<template #icon><svg-icon icon-class="menu-detail" /></template>
|
||||||
<span>详情</span>
|
<span>详情</span>
|
||||||
</GiOptionItem>
|
</GiOptionItem>
|
||||||
<GiOptionItem @click="onClickItem('delete')">
|
<GiOptionItem v-permission="['system:file:delete']" @click="onClickItem('delete')">
|
||||||
<template #icon><svg-icon icon-class="menu-delete" /></template>
|
<template #icon><svg-icon icon-class="menu-delete" /></template>
|
||||||
<span>删除</span>
|
<span>删除</span>
|
||||||
</GiOptionItem>
|
</GiOptionItem>
|
||||||
|
@ -5,7 +5,11 @@
|
|||||||
<a-space wrap>
|
<a-space wrap>
|
||||||
<a-form ref="queryRef" :model="queryParams" layout="inline">
|
<a-form ref="queryRef" :model="queryParams" layout="inline">
|
||||||
<a-form-item hide-label>
|
<a-form-item hide-label>
|
||||||
<a-upload :show-file-list="false" :custom-request="handleUpload">
|
<a-upload
|
||||||
|
v-permission="['system:file:upload']"
|
||||||
|
:show-file-list="false"
|
||||||
|
:custom-request="handleUpload"
|
||||||
|
>
|
||||||
<template #upload-button>
|
<template #upload-button>
|
||||||
<a-button type="primary" shape="round">
|
<a-button type="primary" shape="round">
|
||||||
<template #icon><icon-upload /></template>
|
<template #icon><icon-upload /></template>
|
||||||
@ -45,7 +49,11 @@
|
|||||||
@click="handleMulDelete"
|
@click="handleMulDelete"
|
||||||
><template #icon><icon-delete /></template
|
><template #icon><icon-delete /></template
|
||||||
></a-button>
|
></a-button>
|
||||||
<a-button type="primary" @click="isBatchMode = !isBatchMode">
|
<a-button
|
||||||
|
v-permission="['system:file:delete']"
|
||||||
|
type="primary"
|
||||||
|
@click="isBatchMode = !isBatchMode"
|
||||||
|
>
|
||||||
<template #icon><icon-select-all /></template>
|
<template #icon><icon-select-all /></template>
|
||||||
<template #default>{{
|
<template #default>{{
|
||||||
isBatchMode ? '取消批量' : '批量操作'
|
isBatchMode ? '取消批量' : '批量操作'
|
||||||
@ -60,6 +68,16 @@
|
|||||||
</template>
|
</template>
|
||||||
</a-button>
|
</a-button>
|
||||||
</a-tooltip>
|
</a-tooltip>
|
||||||
|
<a-tooltip content="配置存储库" position="bottom">
|
||||||
|
<a-button
|
||||||
|
v-permission="['system:storage:list']"
|
||||||
|
@click="handleConfig"
|
||||||
|
>
|
||||||
|
<template #icon>
|
||||||
|
<icon-settings />
|
||||||
|
</template>
|
||||||
|
</a-button>
|
||||||
|
</a-tooltip>
|
||||||
</a-button-group>
|
</a-button-group>
|
||||||
</a-space>
|
</a-space>
|
||||||
</a-row>
|
</a-row>
|
||||||
@ -87,16 +105,303 @@
|
|||||||
|
|
||||||
<a-empty v-show="!fileList.length"></a-empty>
|
<a-empty v-show="!fileList.length"></a-empty>
|
||||||
</a-spin>
|
</a-spin>
|
||||||
|
|
||||||
|
<!-- 配置存储库 -->
|
||||||
|
<a-drawer
|
||||||
|
title="配置存储库"
|
||||||
|
:visible="storageVisible"
|
||||||
|
:width="1070"
|
||||||
|
:mask-closable="false"
|
||||||
|
:esc-to-close="false"
|
||||||
|
unmount-on-close
|
||||||
|
render-to-body
|
||||||
|
:footer="false"
|
||||||
|
@cancel="handleCancelConfig"
|
||||||
|
>
|
||||||
|
<!-- 操作栏 -->
|
||||||
|
<div class="header-operation" style="margin-bottom: 16px">
|
||||||
|
<a-row>
|
||||||
|
<a-col :span="12">
|
||||||
|
<a-space>
|
||||||
|
<a-button
|
||||||
|
v-permission="['system:storage:add']"
|
||||||
|
type="primary"
|
||||||
|
@click="toAddStorage"
|
||||||
|
>
|
||||||
|
<template #icon><icon-plus /></template>新增
|
||||||
|
</a-button>
|
||||||
|
<a-button
|
||||||
|
v-permission="['system:storage:export']"
|
||||||
|
:loading="exportStorageLoading"
|
||||||
|
type="primary"
|
||||||
|
status="warning"
|
||||||
|
@click="handleStorageExport"
|
||||||
|
>
|
||||||
|
<template #icon><icon-download /></template>导出
|
||||||
|
</a-button>
|
||||||
|
</a-space>
|
||||||
|
</a-col>
|
||||||
|
</a-row>
|
||||||
|
</div>
|
||||||
|
<a-table
|
||||||
|
row-key="id"
|
||||||
|
:data="storageList"
|
||||||
|
:loading="storageLoading"
|
||||||
|
:bordered="false"
|
||||||
|
:pagination="{
|
||||||
|
showTotal: true,
|
||||||
|
showPageSize: true,
|
||||||
|
total: totalStorage,
|
||||||
|
current: storageQueryParams.page,
|
||||||
|
}"
|
||||||
|
size="large"
|
||||||
|
column-resizable
|
||||||
|
stripe
|
||||||
|
@page-change="handleStoragePageChange"
|
||||||
|
@page-size-change="handleStoragePageSizeChange"
|
||||||
|
>
|
||||||
|
<template #columns>
|
||||||
|
<a-table-column title="名称" :width="135">
|
||||||
|
<template #cell="{ record }">
|
||||||
|
{{ record.name }}
|
||||||
|
<a-tag v-if="record.isDefault" color="arcoblue">默认</a-tag>
|
||||||
|
</template>
|
||||||
|
</a-table-column>
|
||||||
|
<a-table-column title="编码" data-index="code" />
|
||||||
|
<a-table-column title="类型" align="center">
|
||||||
|
<template #cell="{ record }">
|
||||||
|
<dict-tag :value="record.type" :dict="storage_type_enum" />
|
||||||
|
</template>
|
||||||
|
</a-table-column>
|
||||||
|
<a-table-column
|
||||||
|
title="访问密钥"
|
||||||
|
data-index="accessKey"
|
||||||
|
ellipsis
|
||||||
|
tooltip
|
||||||
|
/>
|
||||||
|
<a-table-column
|
||||||
|
title="终端节点"
|
||||||
|
data-index="endpoint"
|
||||||
|
ellipsis
|
||||||
|
tooltip
|
||||||
|
/>
|
||||||
|
<a-table-column
|
||||||
|
title="桶名称"
|
||||||
|
data-index="bucketName"
|
||||||
|
ellipsis
|
||||||
|
tooltip
|
||||||
|
/>
|
||||||
|
<a-table-column title="域名" data-index="domain" ellipsis tooltip />
|
||||||
|
<a-table-column title="状态" align="center">
|
||||||
|
<template #cell="{ record }">
|
||||||
|
<a-switch
|
||||||
|
v-model="record.status"
|
||||||
|
:checked-value="1"
|
||||||
|
:unchecked-value="2"
|
||||||
|
:disabled="!checkPermission(['system:storage:update'])"
|
||||||
|
@change="handleStorageChangeStatus(record)"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</a-table-column>
|
||||||
|
<a-table-column
|
||||||
|
title="描述"
|
||||||
|
data-index="description"
|
||||||
|
ellipsis
|
||||||
|
tooltip
|
||||||
|
/>
|
||||||
|
<a-table-column
|
||||||
|
v-if="
|
||||||
|
checkPermission([
|
||||||
|
'system:storage:update',
|
||||||
|
'system:storage:delete',
|
||||||
|
])
|
||||||
|
"
|
||||||
|
title="操作"
|
||||||
|
align="center"
|
||||||
|
fixed="right"
|
||||||
|
:width="90"
|
||||||
|
>
|
||||||
|
<template #cell="{ record }">
|
||||||
|
<a-button
|
||||||
|
v-permission="['system:storage:update']"
|
||||||
|
type="text"
|
||||||
|
size="small"
|
||||||
|
title="修改"
|
||||||
|
@click="toUpdateStorage(record.id)"
|
||||||
|
>
|
||||||
|
<template #icon><icon-edit /></template>
|
||||||
|
</a-button>
|
||||||
|
<a-popconfirm
|
||||||
|
content="确定要删除当前选中的数据吗?"
|
||||||
|
type="warning"
|
||||||
|
@ok="handleDeleteStorage([record.id])"
|
||||||
|
>
|
||||||
|
<a-button
|
||||||
|
v-permission="['system:storage:delete']"
|
||||||
|
type="text"
|
||||||
|
size="small"
|
||||||
|
:title="record.isDefault ? '默认存储库不能删除' : '删除'"
|
||||||
|
:disabled="record.disabled"
|
||||||
|
>
|
||||||
|
<template #icon><icon-delete /></template>
|
||||||
|
</a-button>
|
||||||
|
</a-popconfirm>
|
||||||
|
</template>
|
||||||
|
</a-table-column>
|
||||||
|
</template>
|
||||||
|
</a-table>
|
||||||
|
</a-drawer>
|
||||||
|
<!-- 表单区域 -->
|
||||||
|
<a-modal
|
||||||
|
:title="storageFormTitle"
|
||||||
|
:visible="storageFormVisible"
|
||||||
|
:width="580"
|
||||||
|
:mask-closable="false"
|
||||||
|
:esc-to-close="false"
|
||||||
|
unmount-on-close
|
||||||
|
render-to-body
|
||||||
|
@ok="handleStorageFormOk"
|
||||||
|
@cancel="handleStorageFormCancel"
|
||||||
|
>
|
||||||
|
<a-form
|
||||||
|
ref="storageFormRef"
|
||||||
|
:model="storageForm"
|
||||||
|
:rules="storageRules"
|
||||||
|
size="large"
|
||||||
|
:label-col-style="{ width: '84px' }"
|
||||||
|
layout="inline"
|
||||||
|
>
|
||||||
|
<a-form-item label="名称" field="name">
|
||||||
|
<a-input
|
||||||
|
v-model="storageForm.name"
|
||||||
|
placeholder="请输入名称"
|
||||||
|
style="width: 162px"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item label="编码" field="code">
|
||||||
|
<a-input
|
||||||
|
v-model="storageForm.code"
|
||||||
|
placeholder="请输入编码"
|
||||||
|
style="width: 162px"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item label="类型" field="type">
|
||||||
|
<a-select
|
||||||
|
v-model="storageForm.type"
|
||||||
|
:options="storage_type_enum"
|
||||||
|
placeholder="请选择存储类型"
|
||||||
|
style="width: 416px"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item
|
||||||
|
v-if="storageForm.type === 1"
|
||||||
|
label="访问密钥"
|
||||||
|
field="accessKey"
|
||||||
|
>
|
||||||
|
<a-input
|
||||||
|
v-model="storageForm.accessKey"
|
||||||
|
placeholder="请输入访问密钥"
|
||||||
|
style="width: 416px"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item
|
||||||
|
v-if="storageForm.type === 1"
|
||||||
|
label="私有密钥"
|
||||||
|
field="secretKey"
|
||||||
|
>
|
||||||
|
<a-input
|
||||||
|
v-model="storageForm.secretKey"
|
||||||
|
placeholder="请输入私有密钥"
|
||||||
|
style="width: 416px"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item
|
||||||
|
v-if="storageForm.type === 1"
|
||||||
|
label="终端节点"
|
||||||
|
field="endpoint"
|
||||||
|
>
|
||||||
|
<a-input
|
||||||
|
v-model="storageForm.endpoint"
|
||||||
|
placeholder="请输入终端节点"
|
||||||
|
style="width: 416px"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item label="桶名称" field="bucketName">
|
||||||
|
<a-input
|
||||||
|
v-model="storageForm.bucketName"
|
||||||
|
placeholder="请输入桶名称"
|
||||||
|
style="width: 416px"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item v-if="storageForm.type === 1" label="域名" field="domain">
|
||||||
|
<a-input
|
||||||
|
v-model="storageForm.domain"
|
||||||
|
placeholder="请输入域名"
|
||||||
|
style="width: 416px"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item
|
||||||
|
v-if="storageForm.type === 2"
|
||||||
|
label="域名"
|
||||||
|
field="domain"
|
||||||
|
:rules="[
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请输入域名',
|
||||||
|
},
|
||||||
|
]"
|
||||||
|
>
|
||||||
|
<a-input
|
||||||
|
v-model="storageForm.domain"
|
||||||
|
placeholder="请输入域名"
|
||||||
|
style="width: 416px"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item label="排序" field="sort">
|
||||||
|
<a-input-number
|
||||||
|
v-model="storageForm.sort"
|
||||||
|
placeholder="请输入排序"
|
||||||
|
style="width: 416px"
|
||||||
|
:min="1"
|
||||||
|
mode="button"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item label="描述" field="description">
|
||||||
|
<a-textarea
|
||||||
|
v-model="storageForm.description"
|
||||||
|
:max-length="200"
|
||||||
|
placeholder="请输入描述"
|
||||||
|
style="width: 416px"
|
||||||
|
:auto-size="{
|
||||||
|
minRows: 3,
|
||||||
|
}"
|
||||||
|
show-word-limit
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item label="默认存储" field="isDefault">
|
||||||
|
<a-switch v-model="storageForm.isDefault" type="round" />
|
||||||
|
</a-form-item>
|
||||||
|
</a-form>
|
||||||
|
</a-modal>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { Modal, RequestOption } from '@arco-design/web-vue';
|
import { Modal, RequestOption } from '@arco-design/web-vue';
|
||||||
|
import checkPermission from '@/utils/permission';
|
||||||
import { api as viewerApi } from 'v-viewer';
|
import { api as viewerApi } from 'v-viewer';
|
||||||
import { imageTypeList } from '@/constant/file';
|
import { imageTypeList } from '@/constant/file';
|
||||||
import { useFileStore } from '@/store/modules/file';
|
import { useFileStore } from '@/store/modules/file';
|
||||||
import type { ListParam, FileItem } from '@/api/system/file';
|
import type { ListParam, FileItem } from '@/api/system/file';
|
||||||
import { list, del } from '@/api/system/file';
|
import { list, del } from '@/api/system/file';
|
||||||
|
import type { DataRecord as StorageDataRecord } from '@/api/system/storage';
|
||||||
|
import {
|
||||||
|
list as listStorage,
|
||||||
|
get as getStorage,
|
||||||
|
add as addStorage,
|
||||||
|
update as updateStorage,
|
||||||
|
del as delStorage,
|
||||||
|
} from '@/api/system/storage';
|
||||||
import { upload } from '@/api/common';
|
import { upload } from '@/api/common';
|
||||||
import { onBeforeRouteUpdate, useRoute } from 'vue-router';
|
import { onBeforeRouteUpdate, useRoute } from 'vue-router';
|
||||||
import { getCurrentInstance, onMounted, reactive, ref, toRefs } from 'vue';
|
import { getCurrentInstance, onMounted, reactive, ref, toRefs } from 'vue';
|
||||||
@ -118,6 +423,14 @@
|
|||||||
const fileList = ref<FileItem[]>([]);
|
const fileList = ref<FileItem[]>([]);
|
||||||
// 批量操作
|
// 批量操作
|
||||||
const isBatchMode = ref(false);
|
const isBatchMode = ref(false);
|
||||||
|
const storageVisible = ref(false);
|
||||||
|
const storageLoading = ref(false);
|
||||||
|
const exportStorageLoading = ref(false);
|
||||||
|
const storageList = ref<StorageDataRecord[]>([]);
|
||||||
|
const totalStorage = ref(0);
|
||||||
|
const storageFormTitle = ref();
|
||||||
|
const storageFormVisible = ref(false);
|
||||||
|
const { storage_type_enum } = proxy.useDict('storage_type_enum');
|
||||||
|
|
||||||
const data = reactive({
|
const data = reactive({
|
||||||
// 查询参数
|
// 查询参数
|
||||||
@ -126,8 +439,24 @@
|
|||||||
type: route.query.type?.toString() || undefined,
|
type: route.query.type?.toString() || undefined,
|
||||||
sort: ['updateTime,desc'],
|
sort: ['updateTime,desc'],
|
||||||
},
|
},
|
||||||
|
storageQueryParams: {
|
||||||
|
page: 1,
|
||||||
|
size: 10,
|
||||||
|
sort: ['updateTime,desc'],
|
||||||
|
},
|
||||||
|
storageForm: {} as StorageDataRecord,
|
||||||
|
storageRules: {
|
||||||
|
name: [{ required: true, message: '请输入名称' }],
|
||||||
|
code: [{ required: true, message: '请输入编码' }],
|
||||||
|
type: [{ required: true, message: '请选择类型' }],
|
||||||
|
accessKey: [{ required: true, message: '请输入访问密钥' }],
|
||||||
|
secretKey: [{ required: true, message: '请输入私有密钥' }],
|
||||||
|
endpoint: [{ required: true, message: '请输入终端节点' }],
|
||||||
|
bucketName: [{ required: true, message: '请输入桶名称' }],
|
||||||
|
},
|
||||||
});
|
});
|
||||||
const { queryParams } = toRefs(data);
|
const { queryParams, storageQueryParams, storageForm, storageRules } =
|
||||||
|
toRefs(data);
|
||||||
|
|
||||||
const getList = async (params: ListParam = { ...queryParams.value }) => {
|
const getList = async (params: ListParam = { ...queryParams.value }) => {
|
||||||
try {
|
try {
|
||||||
@ -276,6 +605,177 @@
|
|||||||
proxy.$refs.queryRef.resetFields();
|
proxy.$refs.queryRef.resetFields();
|
||||||
handleQuery();
|
handleQuery();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询存储库列表
|
||||||
|
*
|
||||||
|
* @param params 参数
|
||||||
|
*/
|
||||||
|
const getStorageList = async (
|
||||||
|
params: ListParam = { ...storageQueryParams.value },
|
||||||
|
) => {
|
||||||
|
try {
|
||||||
|
storageLoading.value = true;
|
||||||
|
const res = await listStorage(params);
|
||||||
|
storageList.value = res.data.list;
|
||||||
|
totalStorage.value = res.data.total;
|
||||||
|
} finally {
|
||||||
|
storageLoading.value = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 重置表单
|
||||||
|
*/
|
||||||
|
const resetStorage = () => {
|
||||||
|
storageForm.value = {
|
||||||
|
type: 1,
|
||||||
|
sort: 999,
|
||||||
|
isDefault: false,
|
||||||
|
};
|
||||||
|
proxy.$refs.storageFormRef?.resetFields();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 打开修改对话框
|
||||||
|
*
|
||||||
|
* @param id ID
|
||||||
|
*/
|
||||||
|
const toUpdateStorage = (id: number) => {
|
||||||
|
resetStorage();
|
||||||
|
getStorage(id).then((res) => {
|
||||||
|
storageForm.value = res.data;
|
||||||
|
storageFormTitle.value = '修改存储库';
|
||||||
|
storageFormVisible.value = true;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 打开新增对话框
|
||||||
|
*/
|
||||||
|
const toAddStorage = () => {
|
||||||
|
resetStorage();
|
||||||
|
storageFormTitle.value = '新增存储库';
|
||||||
|
storageFormVisible.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除
|
||||||
|
*
|
||||||
|
* @param ids ID 列表
|
||||||
|
*/
|
||||||
|
const handleDeleteStorage = (ids: Array<number>) => {
|
||||||
|
delStorage(ids).then((res) => {
|
||||||
|
proxy.$message.success(res.msg);
|
||||||
|
getStorageList();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 配置
|
||||||
|
*/
|
||||||
|
const handleConfig = () => {
|
||||||
|
getStorageList();
|
||||||
|
storageVisible.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 取消配置
|
||||||
|
*/
|
||||||
|
const handleCancelConfig = () => {
|
||||||
|
storageVisible.value = false;
|
||||||
|
storageList.value = [];
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 切换页码
|
||||||
|
*
|
||||||
|
* @param current 页码
|
||||||
|
*/
|
||||||
|
const handleStoragePageChange = (current: number) => {
|
||||||
|
storageQueryParams.value.page = current;
|
||||||
|
getStorageList();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 切换每页条数
|
||||||
|
*
|
||||||
|
* @param pageSize 每页条数
|
||||||
|
*/
|
||||||
|
const handleStoragePageSizeChange = (pageSize: number) => {
|
||||||
|
storageQueryParams.value.size = pageSize;
|
||||||
|
getStorageList();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 修改状态
|
||||||
|
*
|
||||||
|
* @param record 记录信息
|
||||||
|
*/
|
||||||
|
const handleStorageChangeStatus = (record: StorageDataRecord) => {
|
||||||
|
const { id } = record;
|
||||||
|
if (id) {
|
||||||
|
const tip = record.status === 1 ? '启用' : '禁用';
|
||||||
|
getStorage(id)
|
||||||
|
.then((res) => {
|
||||||
|
res.data.status = record.status;
|
||||||
|
updateStorage(res.data, id)
|
||||||
|
.then(() => {
|
||||||
|
proxy.$message.success(`${tip}成功`);
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
record.status = record.status === 1 ? 2 : 1;
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
record.status = record.status === 1 ? 2 : 1;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 取消
|
||||||
|
*/
|
||||||
|
const handleStorageFormCancel = () => {
|
||||||
|
storageFormVisible.value = false;
|
||||||
|
proxy.$refs.storageFormRef?.resetFields();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 确定
|
||||||
|
*/
|
||||||
|
const handleStorageFormOk = () => {
|
||||||
|
proxy.$refs.storageFormRef.validate((valid: any) => {
|
||||||
|
if (!valid) {
|
||||||
|
if (storageForm.value.id !== undefined) {
|
||||||
|
updateStorage(storageForm.value, storageForm.value.id).then((res) => {
|
||||||
|
handleStorageFormCancel();
|
||||||
|
getStorageList();
|
||||||
|
proxy.$message.success(res.msg);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
addStorage(storageForm.value).then((res) => {
|
||||||
|
handleStorageFormCancel();
|
||||||
|
getStorageList();
|
||||||
|
proxy.$message.success(res.msg);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导出
|
||||||
|
*/
|
||||||
|
const handleStorageExport = () => {
|
||||||
|
if (exportStorageLoading.value) return;
|
||||||
|
exportStorageLoading.value = true;
|
||||||
|
proxy
|
||||||
|
.download('/system/storage/export', { ...storageQueryParams.value }, '存储库数据')
|
||||||
|
.finally(() => {
|
||||||
|
exportStorageLoading.value = false;
|
||||||
|
});
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
|
@ -82,6 +82,7 @@ public class CommonController {
|
|||||||
@Operation(summary = "上传文件", description = "上传文件")
|
@Operation(summary = "上传文件", description = "上传文件")
|
||||||
@PostMapping("/file")
|
@PostMapping("/file")
|
||||||
public R<String> upload(@NotNull(message = "文件不能为空") MultipartFile file) {
|
public R<String> upload(@NotNull(message = "文件不能为空") MultipartFile file) {
|
||||||
|
ValidationUtils.throwIf(projectProperties.isProduction(), "演示环境不支持上传文件");
|
||||||
ValidationUtils.throwIf(file::isEmpty, "文件不能为空");
|
ValidationUtils.throwIf(file::isEmpty, "文件不能为空");
|
||||||
FileInfo fileInfo = fileService.upload(file);
|
FileInfo fileInfo = fileService.upload(file);
|
||||||
return R.ok("上传成功", fileInfo.getUrl());
|
return R.ok("上传成功", fileInfo.getUrl());
|
||||||
|
@ -20,5 +20,5 @@ VALUES
|
|||||||
INSERT IGNORE INTO `sys_storage`
|
INSERT IGNORE 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`)
|
(`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
|
VALUES
|
||||||
(1, '本地存储-开发环境', 'local-dev', 2, NULL, NULL, NULL, 'C:/continew-admin/data/file/', 'http://localhost:8000/file', '本地存储-开发环境', b'1', 1, 1, 1, NOW(), NULL, NULL),
|
(1, '开发环境', 'local-dev', 2, NULL, NULL, NULL, 'C:/continew-admin/data/file/', 'http://localhost:8000/file', '本地存储', b'1', 1, 1, 1, NOW(), NULL, NULL),
|
||||||
(2, '本地存储-生产环境', 'local-prod', 2, NULL, NULL, NULL, '../data/file/', 'http://api.charles7c.top/file', '本地存储-生产环境', b'0', 2, 2, 1, NOW(), NULL, NULL);
|
(2, '生产环境', 'local-prod', 2, NULL, NULL, NULL, '../data/file/', 'http://api.charles7c.top/file', '本地存储', b'0', 2, 2, 1, NOW(), NULL, NULL);
|
@ -7,7 +7,6 @@ CREATE TABLE IF NOT EXISTS `sys_file` (
|
|||||||
`size` bigint(20) NOT NULL COMMENT '大小(字节)',
|
`size` bigint(20) NOT NULL COMMENT '大小(字节)',
|
||||||
`url` varchar(512) NOT NULL COMMENT 'URL',
|
`url` varchar(512) NOT NULL COMMENT 'URL',
|
||||||
`extension` varchar(100) DEFAULT NULL COMMENT '扩展名',
|
`extension` varchar(100) DEFAULT NULL COMMENT '扩展名',
|
||||||
`mime_type` varchar(100) DEFAULT NULL COMMENT 'MIME类型',
|
|
||||||
`type` tinyint(1) UNSIGNED NOT NULL DEFAULT 1 COMMENT '类型(1:其他;2:图片;3:文档;4:视频;5:音频)',
|
`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_user` bigint(20) NOT NULL COMMENT '创建人',
|
||||||
@ -15,6 +14,7 @@ CREATE TABLE IF NOT EXISTS `sys_file` (
|
|||||||
`update_user` bigint(20) NOT NULL COMMENT '修改人',
|
`update_user` bigint(20) NOT NULL COMMENT '修改人',
|
||||||
`update_time` datetime NOT NULL COMMENT '修改时间',
|
`update_time` datetime NOT NULL COMMENT '修改时间',
|
||||||
PRIMARY KEY (`id`) USING BTREE,
|
PRIMARY KEY (`id`) USING BTREE,
|
||||||
|
INDEX `idx_url`(`url`) USING BTREE,
|
||||||
INDEX `idx_type`(`type`) USING BTREE,
|
INDEX `idx_type`(`type`) USING BTREE,
|
||||||
INDEX `idx_create_user`(`create_user`) USING BTREE,
|
INDEX `idx_create_user`(`create_user`) USING BTREE,
|
||||||
INDEX `idx_update_user`(`update_user`) USING BTREE
|
INDEX `idx_update_user`(`update_user`) USING BTREE
|
||||||
|
Loading…
Reference in New Issue
Block a user