diff --git a/minio-plus-application/minio-plus-application-schedule/pom.xml b/minio-plus-application/minio-plus-application-schedule/pom.xml new file mode 100644 index 0000000..2f778de --- /dev/null +++ b/minio-plus-application/minio-plus-application-schedule/pom.xml @@ -0,0 +1,40 @@ + + + + minio-plus-application + me.liuxp + ${revision} + + 4.0.0 + + minio-plus-application-schedule + jar + + + + me.liuxp + minio-plus-core-spring-boot-starter + + + + com.baomidou + mybatis-plus-boot-starter + + + org.springframework.boot + spring-boot-starter-validation + + + mysql + mysql-connector-java + + + com.squareup.okhttp3 + okhttp + 4.11.0 + + + + \ No newline at end of file diff --git a/minio-plus-application/minio-plus-application-schedule/src/main/java/org/liuxp/minioplus/application/schedule/ScheduleApplication.java b/minio-plus-application/minio-plus-application-schedule/src/main/java/org/liuxp/minioplus/application/schedule/ScheduleApplication.java new file mode 100644 index 0000000..bb894cf --- /dev/null +++ b/minio-plus-application/minio-plus-application-schedule/src/main/java/org/liuxp/minioplus/application/schedule/ScheduleApplication.java @@ -0,0 +1,20 @@ +package org.liuxp.minioplus.application.schedule; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.scheduling.annotation.EnableScheduling; + +/** + * 定时任务启动类 + * @author contact@liuxp.me + * @since 2024/06/17 + */ +@SpringBootApplication +@EnableScheduling +public class ScheduleApplication { + + public static void main(String[] args) { + SpringApplication.run(ScheduleApplication.class, args); + } + +} \ No newline at end of file diff --git a/minio-plus-application/minio-plus-application-schedule/src/main/java/org/liuxp/minioplus/application/schedule/dao/MetadataRepositoryImpl.java b/minio-plus-application/minio-plus-application-schedule/src/main/java/org/liuxp/minioplus/application/schedule/dao/MetadataRepositoryImpl.java new file mode 100644 index 0000000..79a7259 --- /dev/null +++ b/minio-plus-application/minio-plus-application-schedule/src/main/java/org/liuxp/minioplus/application/schedule/dao/MetadataRepositoryImpl.java @@ -0,0 +1,119 @@ +package org.liuxp.minioplus.application.schedule.dao; + + +import cn.hutool.core.text.CharSequenceUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import lombok.extern.slf4j.Slf4j; +import org.liuxp.minioplus.api.model.dto.FileMetadataInfoDTO; +import org.liuxp.minioplus.api.model.dto.FileMetadataInfoSaveDTO; +import org.liuxp.minioplus.api.model.dto.FileMetadataInfoUpdateDTO; +import org.liuxp.minioplus.api.model.vo.FileMetadataInfoVo; +import org.liuxp.minioplus.application.schedule.entity.FileMetadataInfoEntity; +import org.liuxp.minioplus.application.schedule.mapper.FileMetadataInfoMapper; +import org.liuxp.minioplus.core.repository.MetadataRepository; +import org.springframework.beans.BeanUtils; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +/** + * 文件元数据接口实现类 + * + * @author contact@liuxp.me + * @since 2024/05/22 + */ +@Slf4j +@Service +public class MetadataRepositoryImpl extends ServiceImpl implements MetadataRepository { + + @Override + public List list(FileMetadataInfoDTO searchDTO) { + + // 组装查询参数 + QueryWrapper queryWrapper = buildParams(searchDTO); + + List fileMetadataInfoEntityList = super.list(queryWrapper); + + List fileMetadataInfoVoList = new ArrayList<>(); + + for (FileMetadataInfoEntity fileMetadataInfoEntity : fileMetadataInfoEntityList) { + FileMetadataInfoVo fileMetadataInfoVo = new FileMetadataInfoVo(); + BeanUtils.copyProperties(fileMetadataInfoEntity, fileMetadataInfoVo); + fileMetadataInfoVoList.add(fileMetadataInfoVo); + } + + return fileMetadataInfoVoList; + } + + @Override + public FileMetadataInfoVo one(FileMetadataInfoDTO searchDTO) { + + // 组装查询参数 + QueryWrapper queryWrapper = buildParams(searchDTO); + queryWrapper.last("limit 1"); + + FileMetadataInfoEntity fileMetadataInfoEntity = super.getOne(queryWrapper); + + FileMetadataInfoVo fileMetadataInfoVo = new FileMetadataInfoVo(); + + if(null!=fileMetadataInfoEntity){ + BeanUtils.copyProperties(fileMetadataInfoEntity, fileMetadataInfoVo); + } + + return fileMetadataInfoVo; + } + + @Override + public FileMetadataInfoVo save(FileMetadataInfoSaveDTO saveDTO) { + + FileMetadataInfoEntity fileMetadataInfoEntity = new FileMetadataInfoEntity(); + BeanUtils.copyProperties(saveDTO, fileMetadataInfoEntity); + fileMetadataInfoEntity.setCreateTime(new Date()); + fileMetadataInfoEntity.setUpdateTime(new Date()); + + boolean result = super.save(fileMetadataInfoEntity); + + FileMetadataInfoVo fileMetadataInfoVo = new FileMetadataInfoVo(); + if(result){ + BeanUtils.copyProperties(fileMetadataInfoEntity, fileMetadataInfoVo); + } + + return fileMetadataInfoVo; + } + + @Override + public FileMetadataInfoVo update(FileMetadataInfoUpdateDTO updateDTO) { + + FileMetadataInfoEntity fileMetadataInfoEntity = new FileMetadataInfoEntity(); + BeanUtils.copyProperties(updateDTO, fileMetadataInfoEntity); + fileMetadataInfoEntity.setUpdateTime(new Date()); + boolean result = super.updateById(fileMetadataInfoEntity); + + FileMetadataInfoVo fileMetadataInfoVo = new FileMetadataInfoVo(); + if(result){ + BeanUtils.copyProperties(fileMetadataInfoEntity, fileMetadataInfoVo); + } + + return fileMetadataInfoVo; + } + + @Override + public Boolean remove(Long id) { + return super.removeById(id); + } + + private QueryWrapper buildParams(FileMetadataInfoDTO searchDTO){ + // 组装查询参数 + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(CharSequenceUtil.isNotBlank(searchDTO.getFileKey()),"file_key",searchDTO.getFileKey()); + queryWrapper.eq(CharSequenceUtil.isNotBlank(searchDTO.getFileMd5()),"file_md5",searchDTO.getFileMd5()); + queryWrapper.eq(CharSequenceUtil.isNotBlank(searchDTO.getBucket()),"bucket",searchDTO.getBucket()); + queryWrapper.eq(null!=searchDTO.getIsPrivate(),"is_private",searchDTO.getIsPrivate()); + queryWrapper.eq(CharSequenceUtil.isNotBlank(searchDTO.getCreateUser()),"create_user",searchDTO.getCreateUser()); + + return queryWrapper; + } +} diff --git a/minio-plus-application/minio-plus-application-schedule/src/main/java/org/liuxp/minioplus/application/schedule/entity/FileMetadataInfoEntity.java b/minio-plus-application/minio-plus-application-schedule/src/main/java/org/liuxp/minioplus/application/schedule/entity/FileMetadataInfoEntity.java new file mode 100644 index 0000000..11bcf9e --- /dev/null +++ b/minio-plus-application/minio-plus-application-schedule/src/main/java/org/liuxp/minioplus/application/schedule/entity/FileMetadataInfoEntity.java @@ -0,0 +1,101 @@ +package org.liuxp.minioplus.application.schedule.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import io.swagger.annotations.ApiModelProperty; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +import java.util.Date; + +/** + * 文件元数据信息表Entity + * @author contact@liuxp.me + * @since 2024-05-22 + **/ +@Getter +@Setter +@ToString +@TableName(value = "file_metadata_info") +public class FileMetadataInfoEntity { + + @TableId(value = "id", type = IdType.AUTO) + @ApiModelProperty("主键") + private Long id; + + @ApiModelProperty("文件KEY") + @TableField(value = "file_key") + private String fileKey; + + @ApiModelProperty("文件md5") + @TableField(value = "file_md5") + private String fileMd5; + + @ApiModelProperty("文件名") + @TableField(value = "file_name") + private String fileName; + + @ApiModelProperty("MIME类型") + @TableField(value = "file_mime_type") + private String fileMimeType; + + @ApiModelProperty("文件后缀") + @TableField(value = "file_suffix") + private String fileSuffix; + + @ApiModelProperty("文件长度") + @TableField(value = "file_size") + private Long fileSize; + + @ApiModelProperty("预览图 0:无 1:有") + @TableField(value = "is_preview") + private Boolean isPreview; + + @ApiModelProperty("是否私有 0:否 1:是") + @TableField(value = "is_private") + private Boolean isPrivate; + + @ApiModelProperty("存储桶") + @TableField(value = "bucket") + private String storageBucket; + + @ApiModelProperty("存储桶路径") + @TableField(value = "bucket_path") + private String storagePath; + + @ApiModelProperty("上传任务id,用于合并切片") + @TableField(value = "upload_id") + private String uploadTaskId; + + @ApiModelProperty("状态 0:未完成 1:已完成") + @TableField(value = "is_finished") + private Boolean isFinished; + + @ApiModelProperty("是否分块 0:否 1:是") + @TableField(value = "is_part") + private Boolean isPart; + + @ApiModelProperty("分块数量") + @TableField(value = "part_number") + private Integer partNumber; + + @ApiModelProperty("创建人") + @TableField("create_user") + private String createUser; + + @ApiModelProperty("创建时间") + @TableField("create_time") + private Date createTime; + + @ApiModelProperty("修改人") + @TableField("update_user") + private String updateUser; + + @ApiModelProperty("修改时间") + @TableField("update_time") + private Date updateTime; + +} \ No newline at end of file diff --git a/minio-plus-application/minio-plus-application-schedule/src/main/java/org/liuxp/minioplus/application/schedule/mapper/FileMetadataInfoMapper.java b/minio-plus-application/minio-plus-application-schedule/src/main/java/org/liuxp/minioplus/application/schedule/mapper/FileMetadataInfoMapper.java new file mode 100644 index 0000000..4219c13 --- /dev/null +++ b/minio-plus-application/minio-plus-application-schedule/src/main/java/org/liuxp/minioplus/application/schedule/mapper/FileMetadataInfoMapper.java @@ -0,0 +1,15 @@ +package org.liuxp.minioplus.application.schedule.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; +import org.liuxp.minioplus.application.schedule.entity.FileMetadataInfoEntity; + +/** + * 文件元数据信息表Mapper + * @author contact@liuxp.me + * @since 2024/05/22 + */ +@Mapper +public interface FileMetadataInfoMapper extends BaseMapper { + +} \ No newline at end of file diff --git a/minio-plus-application/minio-plus-application-schedule/src/main/java/org/liuxp/minioplus/application/schedule/task/CleanTask.java b/minio-plus-application/minio-plus-application-schedule/src/main/java/org/liuxp/minioplus/application/schedule/task/CleanTask.java new file mode 100644 index 0000000..14865a4 --- /dev/null +++ b/minio-plus-application/minio-plus-application-schedule/src/main/java/org/liuxp/minioplus/application/schedule/task/CleanTask.java @@ -0,0 +1,40 @@ +package org.liuxp.minioplus.application.schedule.task; + +import lombok.extern.slf4j.Slf4j; +import org.liuxp.minioplus.api.StorageService; +import org.liuxp.minioplus.api.model.dto.FileMetadataInfoDTO; +import org.liuxp.minioplus.api.model.vo.FileMetadataInfoVo; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; +import java.util.List; + +/** + * 定时任务,演示工程定期清理文件 + * @author contact@liuxp.me + * @since 2024/06/17 + */ +@Component +@Slf4j +public class CleanTask { + + @Resource + private StorageService storageService; + + @Scheduled(cron = "0 */1 * * * ?") + public void clean(){ + + List fileList = storageService.list(new FileMetadataInfoDTO()); + + for (FileMetadataInfoVo infoVo : fileList) { + log.info("文件清理,文件key="+infoVo.getFileKey()); + try{ + storageService.remove(infoVo.getFileKey()); + }catch (Exception e){ + log.error(infoVo.getFileKey()+"文件清理失败",e); + } + } + } + +} \ No newline at end of file diff --git a/minio-plus-application/minio-plus-application-schedule/src/main/resources/application.yml b/minio-plus-application/minio-plus-application-schedule/src/main/resources/application.yml new file mode 100644 index 0000000..5a640f7 --- /dev/null +++ b/minio-plus-application/minio-plus-application-schedule/src/main/resources/application.yml @@ -0,0 +1,69 @@ +spring: + #应用唯一标识 + application: + name: MinIOPlus + #配置文件 + profiles: + active: dev + # 解决Feign接口名称重复报错问题 + main: + allow-bean-definition-overriding: true + #jdk proxy + aop: + proxy-target-class: false + auto: false + jackson: + date-format: yyyy-MM-dd HH:mm:ss + time-zone: GMT+8 + default-property-inclusion: non_null # 全局jackson配置 + mvc: + # 放开 Spring Boot 项目中 /static 目录下静态资源的拦截 + static-path-pattern: /static/** + pathmatch: + # Springfox使用的路径匹配是基于AntPathMatcher的,而Spring Boot 2.6.X使用的是PathPatternMatcher所以需要配置此参数 + matching-strategy: ant_path_matcher + #数据源配置 + datasource: + #驱动名称 + driver-class-name: com.mysql.cj.jdbc.Driver + #链接地址 + url: jdbc:mysql://192.168.50.141:3306/minio-plus?characterEncoding=UTF-8&useSSL=true&serverTimezone=Asia/Shanghai + #用户名 + username: minio + #密码 + password: minioadmin +################################################################## +# 服务器 +################################################################## +server: + port: 9010 +################################################################## +### MinIO Plus Config +################################################################## +minioplus: + # MinIO 部署地址 + backend: http://localhost:9000 + # 浏览器访问地址,文件、图片上传下载访问地址代理,如果minio被nginx代理,需要配置这个参数为代理后的前端访问地址 + browser-url: http://localhost:9000 + # 授权key + key: minioadmin + # 密钥 + secret: minioadmin + # 上传预签名URL有效期,单位为分钟,可选参数,默认值为60分钟 + upload-expiry: 120 + # 下载和预览预签名URL有效期,单位为分钟,可选参数,默认值为60分钟 + download-expiry: 20 + # 可选参数,分块配置 + part: + # 可选参数,是否开启分块能力。默认为true + enable: true + # 可选参数,分块大小,配置单位为byte,默认为5242880 + size: 5242880 + # 可选参数,分块上传时建议并发数,默认为3 + iis: 2 + # 可选参数,缩略图配置 + thumbnail: + # 可选参数,是否开启缩略图。默认为true + enable: true + # 可选参数,缩略图尺寸,默认为300 + size: 300 \ No newline at end of file diff --git a/minio-plus-application/pom.xml b/minio-plus-application/pom.xml index 2b244bb..d41964e 100644 --- a/minio-plus-application/pom.xml +++ b/minio-plus-application/pom.xml @@ -14,6 +14,7 @@ minio-plus-application-mysql + minio-plus-application-schedule \ No newline at end of file diff --git a/minio-plus-spring-boot-starter/minio-plus-core-spring-boot-starter/pom.xml b/minio-plus-spring-boot-starter/minio-plus-core-spring-boot-starter/pom.xml new file mode 100644 index 0000000..0538ea2 --- /dev/null +++ b/minio-plus-spring-boot-starter/minio-plus-core-spring-boot-starter/pom.xml @@ -0,0 +1,26 @@ + + + + minio-plus-spring-boot-starter + me.liuxp + ${revision} + + 4.0.0 + + minio-plus-core-spring-boot-starter + jar + + + + me.liuxp + minio-plus-core + + + me.liuxp + minio-s3-api-official + + + + \ No newline at end of file diff --git a/minio-plus-spring-boot-starter/minio-plus-core-spring-boot-starter/src/main/java/org/liuxp/minioplus/common/config/MinioPlusAutoConfiguration.java b/minio-plus-spring-boot-starter/minio-plus-core-spring-boot-starter/src/main/java/org/liuxp/minioplus/common/config/MinioPlusAutoConfiguration.java new file mode 100644 index 0000000..80583f5 --- /dev/null +++ b/minio-plus-spring-boot-starter/minio-plus-core-spring-boot-starter/src/main/java/org/liuxp/minioplus/common/config/MinioPlusAutoConfiguration.java @@ -0,0 +1,14 @@ +package org.liuxp.minioplus.common.config; + +import org.springframework.context.annotation.ComponentScan; + +/** + * MinioPlusAutoConfiguration + * + * @author contact@liuxp.me + * @since 2024/06/11 + */ +@ComponentScan("org.liuxp.minioplus") +public class MinioPlusAutoConfiguration { + +} \ No newline at end of file diff --git a/minio-plus-spring-boot-starter/minio-plus-core-spring-boot-starter/src/main/resources/META-INF/spring.factories b/minio-plus-spring-boot-starter/minio-plus-core-spring-boot-starter/src/main/resources/META-INF/spring.factories new file mode 100644 index 0000000..a149910 --- /dev/null +++ b/minio-plus-spring-boot-starter/minio-plus-core-spring-boot-starter/src/main/resources/META-INF/spring.factories @@ -0,0 +1,2 @@ +org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ + org.liuxp.minioplus.common.config.MinioPlusAutoConfiguration \ No newline at end of file diff --git a/minio-plus-spring-boot-starter/pom.xml b/minio-plus-spring-boot-starter/pom.xml index acca8cf..380c091 100644 --- a/minio-plus-spring-boot-starter/pom.xml +++ b/minio-plus-spring-boot-starter/pom.xml @@ -14,6 +14,7 @@ minio-plus-all-spring-boot-starter + minio-plus-core-spring-boot-starter \ No newline at end of file diff --git a/pom.xml b/pom.xml index a9b90c6..d461322 100644 --- a/pom.xml +++ b/pom.xml @@ -147,6 +147,11 @@ minio-plus-all-spring-boot-starter ${revision} + + me.liuxp + minio-plus-core-spring-boot-starter + ${revision} + me.liuxp minio-s3-api-definition @@ -217,6 +222,7 @@ minio-plus-application minio-plus-application-mysql + minio-plus-application-schedule