feat: 新增部分存储库管理后端 API
This commit is contained in:
parent
ed8bb57fe2
commit
5a2c5be088
@ -82,6 +82,12 @@
|
||||
<artifactId>sms4j-spring-boot-starter</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- X File Storage(一行代码将文件存储到本地、FTP、SFTP、WebDAV、阿里云 OSS、华为云 OBS...等其它兼容 S3 协议的存储平台) -->
|
||||
<dependency>
|
||||
<groupId>org.dromara.x-file-storage</groupId>
|
||||
<artifactId>x-file-storage-spring</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- FreeMarker(模板引擎) -->
|
||||
<dependency>
|
||||
<groupId>org.freemarker</groupId>
|
||||
|
@ -61,11 +61,11 @@ public class MyBatisPlusMetaObjectHandler implements MetaObjectHandler {
|
||||
Long createUser = LoginHelper.getUserId();
|
||||
LocalDateTime createTime = LocalDateTime.now();
|
||||
if (metaObject.getOriginalObject() instanceof BaseDO baseDO) {
|
||||
// 继承了 BaseDO 的类,填充创建信息
|
||||
// 继承了 BaseDO 的类,填充创建信息字段
|
||||
baseDO.setCreateUser(ObjectUtil.defaultIfNull(baseDO.getCreateUser(), createUser));
|
||||
baseDO.setCreateTime(ObjectUtil.defaultIfNull(baseDO.getCreateTime(), createTime));
|
||||
} else {
|
||||
// 未继承 BaseDO 的类,如存在创建信息则进行填充
|
||||
// 未继承 BaseDO 的类,如存在创建信息字段则进行填充
|
||||
this.fillFieldValue(metaObject, CREATE_USER, createUser, false);
|
||||
this.fillFieldValue(metaObject, CREATE_TIME, createTime, false);
|
||||
}
|
||||
@ -94,7 +94,7 @@ public class MyBatisPlusMetaObjectHandler implements MetaObjectHandler {
|
||||
baseDO.setUpdateUser(updateUser);
|
||||
baseDO.setUpdateTime(updateTime);
|
||||
} else {
|
||||
// 未继承 BaseDO 的类,根据类中拥有的修改信息进行填充,不存在修改信息不进行填充
|
||||
// 未继承 BaseDO 的类,根据类中拥有的修改信息字段进行填充,不存在修改信息字段不进行填充
|
||||
this.fillFieldValue(metaObject, UPDATE_USER, updateUser, true);
|
||||
this.fillFieldValue(metaObject, UPDATE_TIME, updateTime, true);
|
||||
}
|
||||
|
@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package top.charles7c.continew.admin.system.config;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import org.dromara.x.file.storage.core.FileInfo;
|
||||
import org.dromara.x.file.storage.core.recorder.FileRecorder;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.core.util.EscapeUtil;
|
||||
|
||||
import top.charles7c.continew.admin.common.util.helper.LoginHelper;
|
||||
import top.charles7c.continew.admin.system.enums.FileTypeEnum;
|
||||
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;
|
||||
|
||||
/**
|
||||
* 文件记录实现类
|
||||
*
|
||||
* @author Charles7c
|
||||
* @since 2023/12/24 22:31
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class FileRecorderImpl implements FileRecorder {
|
||||
|
||||
private final FileMapper fileMapper;
|
||||
private final StorageMapper storageMapper;
|
||||
|
||||
@Override
|
||||
public boolean save(FileInfo fileInfo) {
|
||||
FileDO file = new FileDO();
|
||||
file.setName(EscapeUtil.unescape(fileInfo.getOriginalFilename()));
|
||||
file.setSize(fileInfo.getSize());
|
||||
file.setUrl(fileInfo.getUrl());
|
||||
file.setExtension(fileInfo.getExt());
|
||||
file.setType(FileTypeEnum.getByExtension(file.getExtension()));
|
||||
StorageDO storage = storageMapper.lambdaQuery().eq(StorageDO::getCode, fileInfo.getPlatform()).one();
|
||||
file.setStorageId(storage.getId());
|
||||
file.setCreateTime(DateUtil.toLocalDateTime(fileInfo.getCreateTime()));
|
||||
file.setUpdateUser(LoginHelper.getUserId());
|
||||
file.setUpdateTime(file.getCreateTime());
|
||||
fileMapper.insert(file);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FileInfo getByUrl(String url) {
|
||||
FileDO file = fileMapper.lambdaQuery().eq(FileDO::getUrl, url).one();
|
||||
FileInfo fileInfo = new FileInfo();
|
||||
fileInfo.setOriginalFilename(file.getName());
|
||||
fileInfo.setSize(file.getSize());
|
||||
fileInfo.setUrl(file.getUrl());
|
||||
fileInfo.setExt(file.getExtension());
|
||||
return fileInfo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean delete(String url) {
|
||||
return fileMapper.lambdaUpdate().eq(FileDO::getUrl, url).remove();
|
||||
}
|
||||
}
|
@ -16,12 +16,15 @@
|
||||
|
||||
package top.charles7c.continew.admin.system.enums;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
|
||||
import top.charles7c.continew.starter.data.mybatis.plus.base.IBaseEnum;
|
||||
|
||||
/**
|
||||
@ -62,4 +65,17 @@ public enum FileTypeEnum implements IBaseEnum<Integer> {
|
||||
private final Integer value;
|
||||
private final String description;
|
||||
private final List<String> extensions;
|
||||
|
||||
/**
|
||||
* 根据扩展名查询
|
||||
*
|
||||
* @param extension
|
||||
* 扩展名
|
||||
* @return 文件类型
|
||||
*/
|
||||
public static FileTypeEnum getByExtension(String extension) {
|
||||
return Arrays.stream(FileTypeEnum.values())
|
||||
.filter(t -> t.getExtensions().contains(StrUtil.emptyIfNull(extension).toLowerCase())).findFirst()
|
||||
.orElse(FileTypeEnum.UNKNOWN);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package top.charles7c.continew.admin.system.mapper;
|
||||
|
||||
import top.charles7c.continew.admin.system.model.entity.StorageDO;
|
||||
import top.charles7c.continew.starter.data.mybatis.plus.base.BaseMapper;
|
||||
|
||||
/**
|
||||
* 存储库 Mapper
|
||||
*
|
||||
* @author Charles7c
|
||||
* @since 2023/12/26 22:09
|
||||
*/
|
||||
public interface StorageMapper extends BaseMapper<StorageDO> {}
|
@ -20,7 +20,7 @@ import java.io.Serial;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.baomidou.mybatisplus.annotation.*;
|
||||
|
||||
import top.charles7c.continew.admin.system.enums.FileTypeEnum;
|
||||
import top.charles7c.continew.starter.extension.crud.base.BaseDO;
|
||||
@ -38,6 +38,9 @@ public class FileDO extends BaseDO {
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@TableId(type = IdType.ASSIGN_ID)
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 名称
|
||||
*/
|
||||
@ -58,18 +61,13 @@ public class FileDO extends BaseDO {
|
||||
*/
|
||||
private String extension;
|
||||
|
||||
/**
|
||||
* MIME类型
|
||||
*/
|
||||
private String mimeType;
|
||||
|
||||
/**
|
||||
* 类型
|
||||
*/
|
||||
private FileTypeEnum type;
|
||||
|
||||
/**
|
||||
* 存储库ID
|
||||
* 存储库 ID
|
||||
*/
|
||||
private Long storageId;
|
||||
}
|
@ -0,0 +1,94 @@
|
||||
/*
|
||||
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package top.charles7c.continew.admin.system.model.entity;
|
||||
|
||||
import java.io.Serial;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
|
||||
import top.charles7c.continew.starter.extension.crud.base.BaseDO;
|
||||
|
||||
/**
|
||||
* 存储库实体
|
||||
*
|
||||
* @author Charles7c
|
||||
* @since 2023/12/26 22:09
|
||||
*/
|
||||
@Data
|
||||
@TableName("sys_storage")
|
||||
public class StorageDO extends BaseDO {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 名称
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 编码
|
||||
*/
|
||||
private String code;
|
||||
|
||||
/**
|
||||
* Access Key
|
||||
*/
|
||||
private String accessKey;
|
||||
|
||||
/**
|
||||
* Secret Key
|
||||
*/
|
||||
private String secretKey;
|
||||
|
||||
/**
|
||||
* Endpoint
|
||||
*/
|
||||
private String endpoint;
|
||||
|
||||
/**
|
||||
* 桶名称
|
||||
*/
|
||||
private String bucketName;
|
||||
|
||||
/**
|
||||
* 自定义域名
|
||||
*/
|
||||
private String domain;
|
||||
|
||||
/**
|
||||
* 描述
|
||||
*/
|
||||
private String description;
|
||||
|
||||
/**
|
||||
* 是否为默认存储
|
||||
*/
|
||||
private Boolean isDefault;
|
||||
|
||||
/**
|
||||
* 排序
|
||||
*/
|
||||
private Integer sort;
|
||||
|
||||
/**
|
||||
* 状态
|
||||
*/
|
||||
private Integer status;
|
||||
}
|
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package top.charles7c.continew.admin.system.model.query;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
|
||||
import top.charles7c.continew.starter.data.mybatis.plus.query.Query;
|
||||
import top.charles7c.continew.starter.data.mybatis.plus.query.QueryType;
|
||||
|
||||
/**
|
||||
* 存储库查询条件
|
||||
*
|
||||
* @author Charles7c
|
||||
* @since 2023/12/26 22:09
|
||||
*/
|
||||
@Data
|
||||
@Schema(description = "存储库查询条件")
|
||||
public class StorageQuery implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 名称
|
||||
*/
|
||||
@Schema(description = "名称")
|
||||
@Query(type = QueryType.INNER_LIKE)
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 状态
|
||||
*/
|
||||
@Schema(description = "状态")
|
||||
@Query(type = QueryType.EQUAL)
|
||||
private Integer status;
|
||||
}
|
@ -0,0 +1,111 @@
|
||||
/*
|
||||
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package top.charles7c.continew.admin.system.model.req;
|
||||
|
||||
import java.io.Serial;
|
||||
|
||||
import jakarta.validation.constraints.*;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
|
||||
import top.charles7c.continew.admin.common.enums.DisEnableStatusEnum;
|
||||
import top.charles7c.continew.starter.extension.crud.base.BaseReq;
|
||||
|
||||
/**
|
||||
* 创建或修改存储库信息
|
||||
*
|
||||
* @author Charles7c
|
||||
* @since 2023/12/26 22:09
|
||||
*/
|
||||
@Data
|
||||
@Schema(description = "创建或修改存储库信息")
|
||||
public class StorageReq extends BaseReq {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 名称
|
||||
*/
|
||||
@Schema(description = "名称")
|
||||
@NotBlank(message = "名称不能为空")
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 编码
|
||||
*/
|
||||
@Schema(description = "编码")
|
||||
@NotBlank(message = "编码不能为空")
|
||||
private String code;
|
||||
|
||||
/**
|
||||
* Access Key
|
||||
*/
|
||||
@Schema(description = "Access Key")
|
||||
private String accessKey;
|
||||
|
||||
/**
|
||||
* Secret Key
|
||||
*/
|
||||
@Schema(description = "Secret Key")
|
||||
private String secretKey;
|
||||
|
||||
/**
|
||||
* Endpoint
|
||||
*/
|
||||
@Schema(description = "Endpoint")
|
||||
private String endpoint;
|
||||
|
||||
/**
|
||||
* 桶名称
|
||||
*/
|
||||
@Schema(description = "桶名称")
|
||||
private String bucketName;
|
||||
|
||||
/**
|
||||
* 自定义域名
|
||||
*/
|
||||
@Schema(description = "自定义域名")
|
||||
private String domain;
|
||||
|
||||
/**
|
||||
* 描述
|
||||
*/
|
||||
@Schema(description = "描述")
|
||||
private String description;
|
||||
|
||||
/**
|
||||
* 是否为默认存储
|
||||
*/
|
||||
@Schema(description = "是否为默认存储")
|
||||
@NotNull(message = "是否为默认存储不能为空")
|
||||
private Boolean isDefault;
|
||||
|
||||
/**
|
||||
* 排序
|
||||
*/
|
||||
@Schema(description = "排序")
|
||||
private Integer sort;
|
||||
|
||||
/**
|
||||
* 状态
|
||||
*/
|
||||
@Schema(description = "状态(1:启用;2:禁用)", type = "Integer", allowableValues = {"1", "2"}, example = "1")
|
||||
private DisEnableStatusEnum status;
|
||||
}
|
@ -0,0 +1,120 @@
|
||||
/*
|
||||
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package top.charles7c.continew.admin.system.model.resp;
|
||||
|
||||
import java.io.Serial;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
|
||||
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
|
||||
import com.alibaba.excel.annotation.ExcelProperty;
|
||||
|
||||
import top.charles7c.continew.starter.extension.crud.base.BaseDetailResp;
|
||||
|
||||
/**
|
||||
* 存储库详情信息
|
||||
*
|
||||
* @author Charles7c
|
||||
* @since 2023/12/26 22:09
|
||||
*/
|
||||
@Data
|
||||
@ExcelIgnoreUnannotated
|
||||
@Schema(description = "存储库详情信息")
|
||||
public class StorageDetailResp extends BaseDetailResp {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 名称
|
||||
*/
|
||||
@Schema(description = "名称")
|
||||
@ExcelProperty(value = "名称")
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 编码
|
||||
*/
|
||||
@Schema(description = "编码")
|
||||
@ExcelProperty(value = "编码")
|
||||
private String code;
|
||||
|
||||
/**
|
||||
* Access Key
|
||||
*/
|
||||
@Schema(description = "Access Key")
|
||||
@ExcelProperty(value = "Access Key")
|
||||
private String accessKey;
|
||||
|
||||
/**
|
||||
* Secret Key
|
||||
*/
|
||||
@Schema(description = "Secret Key")
|
||||
@ExcelProperty(value = "Secret Key")
|
||||
private String secretKey;
|
||||
|
||||
/**
|
||||
* Endpoint
|
||||
*/
|
||||
@Schema(description = "Endpoint")
|
||||
@ExcelProperty(value = "Endpoint")
|
||||
private String endpoint;
|
||||
|
||||
/**
|
||||
* 桶名称
|
||||
*/
|
||||
@Schema(description = "桶名称")
|
||||
@ExcelProperty(value = "桶名称")
|
||||
private String bucketName;
|
||||
|
||||
/**
|
||||
* 自定义域名
|
||||
*/
|
||||
@Schema(description = "自定义域名")
|
||||
@ExcelProperty(value = "自定义域名")
|
||||
private String domain;
|
||||
|
||||
/**
|
||||
* 描述
|
||||
*/
|
||||
@Schema(description = "描述")
|
||||
@ExcelProperty(value = "描述")
|
||||
private String description;
|
||||
|
||||
/**
|
||||
* 是否为默认存储
|
||||
*/
|
||||
@Schema(description = "是否为默认存储")
|
||||
@ExcelProperty(value = "是否为默认存储")
|
||||
private Boolean isDefault;
|
||||
|
||||
/**
|
||||
* 排序
|
||||
*/
|
||||
@Schema(description = "排序")
|
||||
@ExcelProperty(value = "排序")
|
||||
private Integer sort;
|
||||
|
||||
/**
|
||||
* 状态
|
||||
*/
|
||||
@Schema(description = "状态")
|
||||
@ExcelProperty(value = "状态")
|
||||
private Integer status;
|
||||
}
|
@ -0,0 +1,105 @@
|
||||
/*
|
||||
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package top.charles7c.continew.admin.system.model.resp;
|
||||
|
||||
import java.io.Serial;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
|
||||
import top.charles7c.continew.starter.extension.crud.base.BaseResp;
|
||||
|
||||
/**
|
||||
* 存储库信息
|
||||
*
|
||||
* @author Charles7c
|
||||
* @since 2023/12/26 22:09
|
||||
*/
|
||||
@Data
|
||||
@Schema(description = "存储库信息")
|
||||
public class StorageResp extends BaseResp {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 名称
|
||||
*/
|
||||
@Schema(description = "名称")
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 编码
|
||||
*/
|
||||
@Schema(description = "编码")
|
||||
private String code;
|
||||
|
||||
/**
|
||||
* Access Key
|
||||
*/
|
||||
@Schema(description = "Access Key")
|
||||
private String accessKey;
|
||||
|
||||
/**
|
||||
* Secret Key
|
||||
*/
|
||||
@Schema(description = "Secret Key")
|
||||
private String secretKey;
|
||||
|
||||
/**
|
||||
* Endpoint
|
||||
*/
|
||||
@Schema(description = "Endpoint")
|
||||
private String endpoint;
|
||||
|
||||
/**
|
||||
* 桶名称
|
||||
*/
|
||||
@Schema(description = "桶名称")
|
||||
private String bucketName;
|
||||
|
||||
/**
|
||||
* 自定义域名
|
||||
*/
|
||||
@Schema(description = "自定义域名")
|
||||
private String domain;
|
||||
|
||||
/**
|
||||
* 描述
|
||||
*/
|
||||
@Schema(description = "描述")
|
||||
private String description;
|
||||
|
||||
/**
|
||||
* 是否为默认存储
|
||||
*/
|
||||
@Schema(description = "是否为默认存储")
|
||||
private Boolean isDefault;
|
||||
|
||||
/**
|
||||
* 排序
|
||||
*/
|
||||
@Schema(description = "排序")
|
||||
private Integer sort;
|
||||
|
||||
/**
|
||||
* 状态
|
||||
*/
|
||||
@Schema(description = "状态")
|
||||
private Integer status;
|
||||
}
|
@ -16,6 +16,10 @@
|
||||
|
||||
package top.charles7c.continew.admin.system.service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import top.charles7c.continew.admin.system.model.query.FileQuery;
|
||||
import top.charles7c.continew.admin.system.model.req.FileReq;
|
||||
import top.charles7c.continew.admin.system.model.resp.FileDetailResp;
|
||||
@ -28,4 +32,24 @@ import top.charles7c.continew.starter.extension.crud.base.BaseService;
|
||||
* @author Charles7c
|
||||
* @since 2023/12/23 10:38
|
||||
*/
|
||||
public interface FileService extends BaseService<FileResp, FileDetailResp, FileQuery, FileReq> {}
|
||||
public interface FileService extends BaseService<FileResp, FileDetailResp, FileQuery, FileReq> {
|
||||
|
||||
/**
|
||||
* 上传
|
||||
*
|
||||
* @param file
|
||||
* 文件信息
|
||||
* @param storageCode
|
||||
* 存储库编码
|
||||
*/
|
||||
void upload(MultipartFile file, String storageCode);
|
||||
|
||||
/**
|
||||
* 根据存储库 ID 列表查询
|
||||
*
|
||||
* @param storageIds
|
||||
* 存储库 ID 列表
|
||||
* @return 文件数量
|
||||
*/
|
||||
Long countByStorageIds(List<Long> storageIds);
|
||||
}
|
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package top.charles7c.continew.admin.system.service;
|
||||
|
||||
import top.charles7c.continew.admin.system.model.entity.StorageDO;
|
||||
import top.charles7c.continew.admin.system.model.query.StorageQuery;
|
||||
import top.charles7c.continew.admin.system.model.req.StorageReq;
|
||||
import top.charles7c.continew.admin.system.model.resp.StorageDetailResp;
|
||||
import top.charles7c.continew.admin.system.model.resp.StorageResp;
|
||||
import top.charles7c.continew.starter.extension.crud.base.BaseService;
|
||||
|
||||
/**
|
||||
* 存储库业务接口
|
||||
*
|
||||
* @author Charles7c
|
||||
* @since 2023/12/26 22:09
|
||||
*/
|
||||
public interface StorageService extends BaseService<StorageResp, StorageDetailResp, StorageQuery, StorageReq> {
|
||||
|
||||
/**
|
||||
* 查询默认存储库
|
||||
*
|
||||
* @return 存储库信息
|
||||
*/
|
||||
StorageDO getDefaultStorage();
|
||||
|
||||
/**
|
||||
* 根据编码查询
|
||||
*
|
||||
* @param code
|
||||
* 编码
|
||||
* @return 存储库信息
|
||||
*/
|
||||
StorageDO getByCode(String code);
|
||||
}
|
@ -16,17 +16,29 @@
|
||||
|
||||
package top.charles7c.continew.admin.system.service.impl;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import java.util.List;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import org.dromara.x.file.storage.core.*;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
|
||||
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;
|
||||
import top.charles7c.continew.admin.system.model.query.FileQuery;
|
||||
import top.charles7c.continew.admin.system.model.req.FileReq;
|
||||
import top.charles7c.continew.admin.system.model.resp.FileDetailResp;
|
||||
import top.charles7c.continew.admin.system.model.resp.FileResp;
|
||||
import top.charles7c.continew.admin.system.service.FileService;
|
||||
import top.charles7c.continew.admin.system.service.StorageService;
|
||||
import top.charles7c.continew.starter.core.util.validate.CheckUtils;
|
||||
import top.charles7c.continew.starter.extension.crud.base.BaseServiceImpl;
|
||||
|
||||
/**
|
||||
@ -35,7 +47,45 @@ import top.charles7c.continew.starter.extension.crud.base.BaseServiceImpl;
|
||||
* @author Charles7c
|
||||
* @since 2023/12/23 10:38
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class FileServiceImpl extends BaseServiceImpl<FileMapper, FileDO, FileResp, FileDetailResp, FileQuery, FileReq>
|
||||
implements FileService {}
|
||||
implements FileService {
|
||||
|
||||
@Resource
|
||||
private StorageService storageService;
|
||||
private final FileStorageService fileStorageService;
|
||||
|
||||
@Override
|
||||
public void upload(MultipartFile file, String storageCode) {
|
||||
if (StrUtil.isBlank(storageCode)) {
|
||||
StorageDO storage = storageService.getDefaultStorage();
|
||||
CheckUtils.throwIfNull(storage, "请先指定默认存储库");
|
||||
storageCode = storage.getCode();
|
||||
}
|
||||
UploadPretreatment uploadPretreatment = fileStorageService.of(file).setPlatform(storageCode);
|
||||
uploadPretreatment.setProgressMonitor(new ProgressListener() {
|
||||
@Override
|
||||
public void start() {
|
||||
log.info("开始上传");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void progress(long progressSize, long allSize) {
|
||||
log.info("已上传 [{}],总大小 [{}]", progressSize, allSize);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finish() {
|
||||
log.info("上传结束");
|
||||
}
|
||||
});
|
||||
uploadPretreatment.upload();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long countByStorageIds(List<Long> storageIds) {
|
||||
return baseMapper.lambdaQuery().in(FileDO::getStorageId, storageIds).count();
|
||||
}
|
||||
}
|
@ -0,0 +1,185 @@
|
||||
/*
|
||||
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package top.charles7c.continew.admin.system.service.impl;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.servlet.ServletContext;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import org.dromara.x.file.storage.core.FileStorageProperties;
|
||||
import org.dromara.x.file.storage.core.FileStorageService;
|
||||
import org.dromara.x.file.storage.core.FileStorageServiceBuilder;
|
||||
import org.dromara.x.file.storage.core.platform.FileStorage;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.web.accept.ContentNegotiationManager;
|
||||
import org.springframework.web.servlet.HandlerMapping;
|
||||
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
|
||||
import org.springframework.web.servlet.handler.SimpleUrlHandlerMapping;
|
||||
import org.springframework.web.util.UrlPathHelper;
|
||||
|
||||
import cn.hutool.core.util.ReflectUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
|
||||
import top.charles7c.continew.admin.common.enums.DisEnableStatusEnum;
|
||||
import top.charles7c.continew.admin.system.mapper.StorageMapper;
|
||||
import top.charles7c.continew.admin.system.model.entity.StorageDO;
|
||||
import top.charles7c.continew.admin.system.model.query.StorageQuery;
|
||||
import top.charles7c.continew.admin.system.model.req.StorageReq;
|
||||
import top.charles7c.continew.admin.system.model.resp.StorageDetailResp;
|
||||
import top.charles7c.continew.admin.system.model.resp.StorageResp;
|
||||
import top.charles7c.continew.admin.system.service.FileService;
|
||||
import top.charles7c.continew.admin.system.service.StorageService;
|
||||
import top.charles7c.continew.starter.core.util.validate.CheckUtils;
|
||||
import top.charles7c.continew.starter.extension.crud.base.BaseServiceImpl;
|
||||
|
||||
/**
|
||||
* 存储库业务实现
|
||||
*
|
||||
* @author Charles7c
|
||||
* @since 2023/12/26 22:09
|
||||
*/
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class StorageServiceImpl
|
||||
extends BaseServiceImpl<StorageMapper, StorageDO, StorageResp, StorageDetailResp, StorageQuery, StorageReq>
|
||||
implements StorageService {
|
||||
|
||||
private final ApplicationContext applicationContext;
|
||||
private final FileStorageService fileStorageService;
|
||||
@Resource
|
||||
private final FileService fileService;
|
||||
|
||||
@Override
|
||||
public Long add(StorageReq req) {
|
||||
String code = req.getCode();
|
||||
CheckUtils.throwIf(this.isCodeExists(code, null), "新增失败,[{}] 已存在", code);
|
||||
req.setStatus(DisEnableStatusEnum.ENABLE);
|
||||
this.loadFileStorage(req);
|
||||
return super.add(req);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(StorageReq req, Long id) {
|
||||
String code = req.getCode();
|
||||
CheckUtils.throwIf(this.isCodeExists(code, id), "修改失败,[{}] 已存在", code);
|
||||
StorageDO oldStorage = super.getById(id);
|
||||
CheckUtils.throwIf(
|
||||
Boolean.TRUE.equals(oldStorage.getIsDefault()) && DisEnableStatusEnum.DISABLE.equals(req.getStatus()),
|
||||
"[{}] 是默认存储库,不允许禁用", oldStorage.getName());
|
||||
this.loadFileStorage(req);
|
||||
super.update(req, id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delete(List<Long> ids) {
|
||||
CheckUtils.throwIf(fileService.countByStorageIds(ids) > 0, "所选存储库存在文件关联,请删除文件后重试");
|
||||
List<StorageDO> storageList = baseMapper.lambdaQuery().in(StorageDO::getId, ids).list();
|
||||
storageList.forEach(s -> this.removeFileStorage(s.getCode()));
|
||||
super.delete(ids);
|
||||
}
|
||||
|
||||
@Override
|
||||
public StorageDO getDefaultStorage() {
|
||||
return baseMapper.lambdaQuery().eq(StorageDO::getIsDefault, true).one();
|
||||
}
|
||||
|
||||
@Override
|
||||
public StorageDO getByCode(String code) {
|
||||
return baseMapper.lambdaQuery().eq(StorageDO::getCode, code).one();
|
||||
}
|
||||
|
||||
/**
|
||||
* 加载存储配置
|
||||
*
|
||||
* @param req
|
||||
* 存储配置信息
|
||||
*/
|
||||
private void loadFileStorage(StorageReq req) {
|
||||
CopyOnWriteArrayList<FileStorage> fileStorageList = fileStorageService.getFileStorageList();
|
||||
FileStorageProperties.LocalPlusConfig localPlusConfig = new FileStorageProperties.LocalPlusConfig();
|
||||
localPlusConfig.setPlatform(req.getCode());
|
||||
localPlusConfig.setStoragePath(req.getBucketName());
|
||||
localPlusConfig.setDomain(req.getDomain());
|
||||
fileStorageList
|
||||
.addAll(FileStorageServiceBuilder.buildLocalPlusFileStorage(Collections.singletonList(localPlusConfig)));
|
||||
}
|
||||
|
||||
/**
|
||||
* 移除存储配置
|
||||
*
|
||||
* @param code
|
||||
* 存储配置编码
|
||||
*/
|
||||
private void removeFileStorage(String code) {
|
||||
CopyOnWriteArrayList<FileStorage> fileStorageList = fileStorageService.getFileStorageList();
|
||||
FileStorage fileStorage = fileStorageService.getFileStorage(code);
|
||||
fileStorageList.remove(fileStorage);
|
||||
fileStorage.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* 编码是否存在
|
||||
*
|
||||
* @param code
|
||||
* 编码
|
||||
* @param id
|
||||
* ID
|
||||
* @return 是否存在
|
||||
*/
|
||||
private boolean isCodeExists(String code, Long id) {
|
||||
return baseMapper.lambdaQuery().eq(StorageDO::getCode, code).ne(null != id, StorageDO::getId, id).exists();
|
||||
}
|
||||
|
||||
/**
|
||||
* 注册静态资源映射
|
||||
*
|
||||
* @param registerMapping
|
||||
* 静态资源映射列表
|
||||
*/
|
||||
private void registerResource(Map<String, String> registerMapping) {
|
||||
final UrlPathHelper urlPathHelper = applicationContext.getBean("mvcUrlPathHelper", UrlPathHelper.class);
|
||||
final ContentNegotiationManager contentNegotiationManager =
|
||||
applicationContext.getBean("mvcContentNegotiationManager", ContentNegotiationManager.class);
|
||||
final ServletContext servletContext = applicationContext.getBean(ServletContext.class);
|
||||
final HandlerMapping resourceHandlerMapping =
|
||||
applicationContext.getBean("resourceHandlerMapping", HandlerMapping.class);
|
||||
// 已经注册的静态资源映射
|
||||
final Map<String, Object> handlerMap =
|
||||
(Map<String, Object>)ReflectUtil.getFieldValue(resourceHandlerMapping, "handlerMap");
|
||||
final ResourceHandlerRegistry resourceHandlerRegistry =
|
||||
new ResourceHandlerRegistry(applicationContext, servletContext, contentNegotiationManager, urlPathHelper);
|
||||
// 重新注册静态资源映射
|
||||
for (Map.Entry<String, String> entry : registerMapping.entrySet()) {
|
||||
String pathPattern = StrUtil.appendIfMissing(entry.getKey(), "/**");
|
||||
String resourceLocations = StrUtil.appendIfMissing(entry.getValue(), "/");
|
||||
// 移除之前注册过的
|
||||
handlerMap.remove(pathPattern);
|
||||
// 重新注册
|
||||
resourceHandlerRegistry.addResourceHandler(pathPattern).addResourceLocations("file:" + resourceLocations);
|
||||
}
|
||||
final Map<String, ?> additionalUrlMap =
|
||||
ReflectUtil.<SimpleUrlHandlerMapping>invoke(resourceHandlerRegistry, "getHandlerMapping").getUrlMap();
|
||||
ReflectUtil.<Void>invoke(resourceHandlerMapping, "registerHandlers", additionalUrlMap);
|
||||
}
|
||||
}
|
@ -23,6 +23,7 @@ import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import io.swagger.v3.oas.annotations.Hidden;
|
||||
|
||||
import org.dromara.x.file.storage.spring.EnableFileStorage;
|
||||
import org.springframework.boot.ApplicationArguments;
|
||||
import org.springframework.boot.ApplicationRunner;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
@ -44,6 +45,7 @@ import top.charles7c.continew.starter.core.autoconfigure.project.ProjectProperti
|
||||
* @since 2022/12/8 23:15
|
||||
*/
|
||||
@Slf4j
|
||||
@EnableFileStorage
|
||||
@RestController
|
||||
@SpringBootApplication
|
||||
@RequiredArgsConstructor
|
||||
|
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package top.charles7c.continew.admin.webapi.system;
|
||||
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import top.charles7c.continew.admin.system.model.query.StorageQuery;
|
||||
import top.charles7c.continew.admin.system.model.req.StorageReq;
|
||||
import top.charles7c.continew.admin.system.model.resp.StorageDetailResp;
|
||||
import top.charles7c.continew.admin.system.model.resp.StorageResp;
|
||||
import top.charles7c.continew.admin.system.service.StorageService;
|
||||
import top.charles7c.continew.starter.extension.crud.annotation.CrudRequestMapping;
|
||||
import top.charles7c.continew.starter.extension.crud.base.BaseController;
|
||||
|
||||
/**
|
||||
* 存储库管理 API
|
||||
*
|
||||
* @author Charles7c
|
||||
* @since 2023/12/26 22:09
|
||||
*/
|
||||
@Tag(name = "存储库管理 API")
|
||||
@RestController
|
||||
@CrudRequestMapping("/system/storage")
|
||||
public class StorageController
|
||||
extends BaseController<StorageService, StorageResp, StorageDetailResp, StorageQuery, StorageReq> {}
|
@ -12,8 +12,8 @@ CREATE TABLE IF NOT EXISTS `sys_file` (
|
||||
`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) DEFAULT NULL COMMENT '修改人',
|
||||
`update_time` datetime DEFAULT NULL COMMENT '修改时间',
|
||||
`update_user` bigint(20) NOT NULL COMMENT '修改人',
|
||||
`update_time` datetime NOT NULL COMMENT '修改时间',
|
||||
PRIMARY KEY (`id`) USING BTREE,
|
||||
INDEX `idx_type`(`type`) USING BTREE,
|
||||
INDEX `idx_create_user`(`create_user`) USING BTREE,
|
||||
|
Loading…
Reference in New Issue
Block a user