liusheng
2023-06-20 be812198b1c18cf5b79f2cdc69d2f7c3c70eff51
“文件管理“ 代码提交
已添加10个文件
已修改6个文件
1378 ■■■■■ 文件已修改
ruoyi-admin/src/main/java/com/ruoyi/web/controller/smartor/BaseTagcategoryController.java 9 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/com/ruoyi/web/controller/smartor/MinioFileController.java 150 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/resources/application.yml 53 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/pom.xml 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/config/MinioConfig.java 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/utils/MinioClientUtils.java 466 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/java/com/smartor/domain/MinioFile.java 77 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/java/com/smartor/domain/MinioResponseDTO.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/java/com/smartor/domain/PatArchiveReq.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/java/com/smartor/domain/TreeNode.java 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/java/com/smartor/mapper/MinioFileMapper.java 63 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/java/com/smartor/service/IMinioFileService.java 96 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/java/com/smartor/service/impl/MinioFileServiceImpl.java 246 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/resources/mapper/smartor/BaseTagcategoryMapper.xml 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/resources/mapper/smartor/MinioFileMapper.xml 122 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/resources/mapper/smartor/PatArchiveMapper.xml 9 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/com/ruoyi/web/controller/smartor/BaseTagcategoryController.java
@@ -10,6 +10,7 @@
import com.smartor.service.IBaseTagcategoryService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
@@ -24,6 +25,7 @@
 * @date 2023-06-15
 */
@Api(description = "标签分类")
@Slf4j
@RestController
@RequestMapping("/system/tagcategory")
public class BaseTagcategoryController extends BaseController {
@@ -67,6 +69,7 @@
     */
    @PreAuthorize("@ss.hasPermi('system:tagcategory:add')")
    @Log(title = "标签分类", businessType = BusinessType.INSERT)
    @ApiOperation("新增标签分类")
    @PostMapping
    public AjaxResult add(@RequestBody BaseTagcategory baseTagcategory) {
        return toAjax(baseTagcategoryService.insertBaseTagcategory(baseTagcategory));
@@ -77,16 +80,18 @@
     */
    @PreAuthorize("@ss.hasPermi('system:tagcategory:edit')")
    @Log(title = "标签分类", businessType = BusinessType.UPDATE)
    @ApiOperation("修改标签分类")
    @PutMapping
    public AjaxResult edit(@RequestBody BaseTagcategory baseTagcategory) {
        return toAjax(baseTagcategoryService.updateBaseTagcategory(baseTagcategory));
    }
    /**
     * åˆ é™¤æ ‡ç­¾åˆ†ç±»
     * æ ¹æ®åˆ†ç±»ID删除标签分类
     */
    @PreAuthorize("@ss.hasPermi('system:tagcategory:remove')")
    @Log(title = "标签分类", businessType = BusinessType.DELETE)
    @ApiOperation("根据分类ID删除标签分类")
    @DeleteMapping("/{tagcategoryids}")
    public AjaxResult remove(@PathVariable Long[] tagcategoryids) {
        return toAjax(baseTagcategoryService.deleteBaseTagcategoryByTagcategoryids(tagcategoryids));
@@ -100,4 +105,6 @@
    public TableDataInfo baseTagCategoryByName(@RequestParam("name") String name) {
        return getDataTable(baseTagcategoryService.baseTagCategoryByName(name));
    }
}
ruoyi-admin/src/main/java/com/ruoyi/web/controller/smartor/MinioFileController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,150 @@
package com.ruoyi.web.controller.smartor;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.smartor.domain.MinioFile;
import com.smartor.service.IMinioFileService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
/**
 * ã€è¯·å¡«å†™åŠŸèƒ½åç§°ã€‘Controller
 *
 * @author ruoyi
 * @date 2023-06-19
 */
@Api(description = "文件管理(文档、图片...)")
@RestController
@RequestMapping("/system/file")
public class MinioFileController extends BaseController {
    @Autowired
    private IMinioFileService minioFileService;
    /**
     * æŸ¥è¯¢ã€è¯·å¡«å†™åŠŸèƒ½åç§°ã€‘åˆ—è¡¨
     */
    @PreAuthorize("@ss.hasPermi('system:file:list')")
    @GetMapping("/list")
    public TableDataInfo list(MinioFile minioFile) {
        startPage();
        List<MinioFile> list = minioFileService.selectMinioFileList(minioFile);
        return getDataTable(list);
    }
    /**
     * å¯¼å‡ºã€è¯·å¡«å†™åŠŸèƒ½åç§°ã€‘åˆ—è¡¨
     */
    @PreAuthorize("@ss.hasPermi('system:file:export')")
    @Log(title = "【请填写功能名称】", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, MinioFile minioFile) {
        List<MinioFile> list = minioFileService.selectMinioFileList(minioFile);
        ExcelUtil<MinioFile> util = new ExcelUtil<MinioFile>(MinioFile.class);
        util.exportExcel(response, list, "【请填写功能名称】数据");
    }
    /**
     * èŽ·å–ã€è¯·å¡«å†™åŠŸèƒ½åç§°ã€‘è¯¦ç»†ä¿¡æ¯
     */
    @PreAuthorize("@ss.hasPermi('system:file:query')")
    @GetMapping(value = "/{id}")
    public AjaxResult getInfo(@PathVariable("id") Long id) {
        return success(minioFileService.selectMinioFileById(id));
    }
    /**
     * æ–°å¢žã€è¯·å¡«å†™åŠŸèƒ½åç§°ã€‘
     */
    @PreAuthorize("@ss.hasPermi('system:file:add')")
    @Log(title = "【请填写功能名称】", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody MinioFile minioFile) {
        return toAjax(minioFileService.insertMinioFile(minioFile));
    }
    /**
     * ä¿®æ”¹ã€è¯·å¡«å†™åŠŸèƒ½åç§°ã€‘
     */
    @PreAuthorize("@ss.hasPermi('system:file:edit')")
    @Log(title = "【请填写功能名称】", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody MinioFile minioFile) {
        return toAjax(minioFileService.updateMinioFile(minioFile));
    }
    /**
     * åˆ é™¤ã€è¯·å¡«å†™åŠŸèƒ½åç§°ã€‘
     */
    @PreAuthorize("@ss.hasPermi('system:file:remove')")
    @Log(title = "【请填写功能名称】", businessType = BusinessType.DELETE)
    @DeleteMapping("/{ids}")
    public AjaxResult remove(@PathVariable Long[] ids) {
        return toAjax(minioFileService.deleteMinioFileByIds(ids));
    }
    /**
     * ä¸Šä¼ æ–‡ä»¶åˆ°æ–‡ä»¶ç®¡ç†,支持批量上传
     *
     * @param files
     * @return
     */
    @PostMapping(value = {"/admin/uploadFile"})
    @ResponseBody
    @ApiOperation(value = "上传文件到文件管理,支持批量上传")
    @ApiImplicitParam(name = "files", value = "文件对象", dataType = "File")
    public AjaxResult commonUploadFile(@RequestParam("path") String path, @RequestParam("files") List<MultipartFile> files) {
        if (CollectionUtils.isEmpty(files)) {
            return error("未选择文件!");
        }
        return success(minioFileService.commonUploadFile(path, files));
    }
    /**
     * èŽ·å–ï¼ˆå®£æ•™ï¼‰å¼•ç”¨æ¨¡æ¿
     */
    @PreAuthorize("@ss.hasPermi('system:file:list')")
    @ApiOperation(value = "获取(宣教)引用模板")
    @GetMapping("/getEduTemplage")
    public AjaxResult getEduTemplage() {
        //  startPage();
        return success(minioFileService.getEduTemplage());
    }
    /**
     * ä¸‹è½½æ–‡ä»¶ï¼Œä»¥æµçš„形式返回
     *
     * @return
     */
    @ApiOperation(value = "下载文件,以输出流的形式返回, å…¥å‚çš„fileName为全路径文件名")
    @GetMapping("/downloadFile")
    public void downloadFile(HttpServletResponse response, @RequestParam("fileName") String fileName) {
        minioFileService.downloadFile(response, fileName);
    }
    /**
     * èŽ·å–å›¾ç‰‡ã€éŸ³é¢‘ã€è§†é¢‘ çš„URL
     *
     * @return
     */
    @ApiOperation(value = "获取图片、音频、视频 çš„URL, å…¥å‚çš„fileName为全路径文件名,expires为链接过期时间")
    @GetMapping("/getFileUrl")
    public AjaxResult getFileUrl(@RequestParam("fileName") String fileName, @RequestParam("expires") Integer expires) {
        return success(minioFileService.getFileUrl(fileName, expires));
    }
}
ruoyi-admin/src/main/resources/application.yml
@@ -53,15 +53,15 @@
  messages:
    # å›½é™…化资源文件路径
    basename: i18n/messages
  profiles:
  profiles:
    active: druid
  # æ–‡ä»¶ä¸Šä¼ 
  servlet:
     multipart:
       # å•个文件大小
       max-file-size:  10MB
       # è®¾ç½®æ€»ä¸Šä¼ çš„æ–‡ä»¶å¤§å°
       max-request-size:  20MB
    multipart:
      # å•个文件大小
      max-file-size: 500MB
      # è®¾ç½®æ€»ä¸Šä¼ çš„æ–‡ä»¶å¤§å°
      max-request-size: 750MB
  # æœåŠ¡æ¨¡å—
  devtools:
    restart:
@@ -90,29 +90,38 @@
        # #连接池最大阻塞等待时间(使用负值表示没有限制)
        max-wait: -1ms
# minio文件管理连接
minio:
  endpoint: http://192.168.1.4
  port: 9002
  accessKey: lihu
  secretKey: lihu@123
  bucketName: lihu
  secure: false
# token配置
token:
    # ä»¤ç‰Œè‡ªå®šä¹‰æ ‡è¯†
    header: Authorization
    # ä»¤ç‰Œå¯†é’¥
    secret: abcdefghijklmnopqrstuvwxyz
    # ä»¤ç‰Œæœ‰æ•ˆæœŸï¼ˆé»˜è®¤30分钟)
    expireTime: 30
  # ä»¤ç‰Œè‡ªå®šä¹‰æ ‡è¯†
  header: Authorization
  # ä»¤ç‰Œå¯†é’¥
  secret: abcdefghijklmnopqrstuvwxyz
  # ä»¤ç‰Œæœ‰æ•ˆæœŸï¼ˆé»˜è®¤30分钟)
  expireTime: 30
# MyBatis配置
mybatis:
    # æœç´¢æŒ‡å®šåŒ…别名
    typeAliasesPackage: com.ruoyi.**.domain,com.smartor.domain
    # é…ç½®mapper的扫描,找到所有的mapper.xml映射文件
    mapperLocations: classpath*:mapper/**/*Mapper.xml
    # åŠ è½½å…¨å±€çš„é…ç½®æ–‡ä»¶
    configLocation: classpath:mybatis/mybatis-config.xml
  # æœç´¢æŒ‡å®šåŒ…别名
  typeAliasesPackage: com.ruoyi.**.domain,com.smartor.domain
  # é…ç½®mapper的扫描,找到所有的mapper.xml映射文件
  mapperLocations: classpath*:mapper/**/*Mapper.xml
  # åŠ è½½å…¨å±€çš„é…ç½®æ–‡ä»¶
  configLocation: classpath:mybatis/mybatis-config.xml
# PageHelper分页插件
pagehelper:
pagehelper:
  helperDialect: mysql
  supportMethodsArguments: true
  params: count=countSql
  params: count=countSql
# Swagger配置
swagger:
@@ -122,7 +131,7 @@
  pathMapping: /dev-api
# é˜²æ­¢XSS攻击
xss:
xss:
  # è¿‡æ»¤å¼€å…³
  enabled: true
  # æŽ’除链接(多个用逗号分隔)
ruoyi-common/pom.xml
@@ -17,6 +17,12 @@
    <dependencies>
        <dependency>
            <groupId>io.minio</groupId>
            <artifactId>minio</artifactId>
            <version>7.1.0</version>
        </dependency>
        <!-- Spring框架基本的核心工具 -->
        <dependency>
            <groupId>org.springframework</groupId>
ruoyi-common/src/main/java/com/ruoyi/common/config/MinioConfig.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,27 @@
package com.ruoyi.common.config;
import io.minio.MinioClient;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
@Configuration
@Component
@ConfigurationProperties(prefix = "minio")
@Data
public class MinioConfig {
    private String endpoint;
    private int port;
    private String accessKey;
    private String secretKey;
    private Boolean secure;
    private String bucketName;
    @Bean
    public MinioClient getMinioClient() {
        MinioClient minioClient = MinioClient.builder().endpoint(endpoint, port, secure).credentials(accessKey, secretKey).build();
        return minioClient;
    }
}
ruoyi-common/src/main/java/com/ruoyi/common/utils/MinioClientUtils.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,466 @@
package com.ruoyi.common.utils;
import io.minio.*;
import io.minio.errors.*;
import io.minio.http.Method;
import io.minio.messages.Bucket;
import io.minio.messages.DeleteError;
import io.minio.messages.DeleteObject;
import io.minio.messages.Item;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.List;
@Component
@Slf4j
public class MinioClientUtils {
    @Resource
    private MinioClient minioClient;
    private static final int DEFAULT_EXPIRY_TIME = 999999 * 24 * 3600;
    /**
     * æ£€æŸ¥å­˜å‚¨æ¡¶æ˜¯å¦å­˜åœ¨
     *
     * @param bucketName å­˜å‚¨æ¡¶åç§°
     * @return boolean
     */
    public boolean bucketExists(String bucketName) throws Exception {
        boolean flag = false;
        flag = minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());
        if (flag) {
            return true;
        }
        return false;
    }
    /**
     * åˆ›å»ºå­˜å‚¨æ¡¶
     *
     * @param bucketName å­˜å‚¨æ¡¶åç§°
     */
    public boolean makeBucket(String bucketName) throws Exception {
        boolean flag = bucketExists(bucketName);
        if (!flag) {
            minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
            return true;
        } else {
            return false;
        }
    }
    /**
     * åˆ—出所有存储桶名称
     *
     * @return List<String>
     */
    public List<String> listBucketNames() throws Exception {
        List<Bucket> bucketList = listBuckets();
        List<String> bucketListName = new ArrayList<>();
        for (Bucket bucket : bucketList) {
            bucketListName.add(bucket.name());
        }
        return bucketListName;
    }
    /**
     * åˆ—出所有存储桶
     *
     * @return List<Bucket>
     */
    public List<Bucket> listBuckets() throws Exception {
        return minioClient.listBuckets();
    }
    /**
     * åˆ é™¤å­˜å‚¨æ¡¶
     *
     * @param bucketName å­˜å‚¨æ¡¶åç§°
     * @return boolean
     */
    public boolean removeBucket(String bucketName) throws Exception {
        boolean flag = bucketExists(bucketName);
        if (flag) {
            Iterable<Result<Item>> myObjects = listObjects(bucketName);
            for (Result<Item> result : myObjects) {
                Item item = result.get();
                // æœ‰å¯¹è±¡æ–‡ä»¶ï¼Œåˆ™åˆ é™¤å¤±è´¥
                if (item.size() > 0) {
                    return false;
                }
            }
            // åˆ é™¤å­˜å‚¨æ¡¶ï¼Œæ³¨æ„ï¼Œåªæœ‰å­˜å‚¨æ¡¶ä¸ºç©ºæ—¶æ‰èƒ½åˆ é™¤æˆåŠŸã€‚
            minioClient.removeBucket(RemoveBucketArgs.builder().bucket(bucketName).build());
            flag = bucketExists(bucketName);
            if (!flag) {
                return true;
            }
        }
        return false;
    }
    /**
     * åˆ—出存储桶中的所有对象名称
     *
     * @param bucketName å­˜å‚¨æ¡¶åç§°
     * @return List<String>
     */
    public List<String> listObjectNames(String bucketName) throws Exception {
        List<String> listObjectNames = new ArrayList<>();
        boolean flag = bucketExists(bucketName);
        if (flag) {
            Iterable<Result<Item>> myObjects = listObjects(bucketName);
            for (Result<Item> result : myObjects) {
                Item item = result.get();
                listObjectNames.add(item.objectName());
            }
        }
        return listObjectNames;
    }
    /**
     * åˆ—出存储桶中的所有对象
     *
     * @param bucketName å­˜å‚¨æ¡¶åç§°
     * @return Iterable<Result < Item>>
     */
    public Iterable<Result<Item>> listObjects(String bucketName) throws Exception {
        boolean flag = bucketExists(bucketName);
        if (flag) {
            return minioClient.listObjects(ListObjectsArgs.builder().bucket(bucketName).build());
        }
        return null;
    }
    /**
     * é€šè¿‡æ–‡ä»¶ä¸Šä¼ åˆ°å¯¹è±¡
     *
     * @param bucketName å­˜å‚¨æ¡¶åç§°
     * @param objectName å­˜å‚¨æ¡¶é‡Œçš„对象名称
     * @param fileName   File name
     * @return boolean
     */
    public boolean uploadObject(String bucketName, String objectName, String fileName) throws Exception {
        boolean flag = bucketExists(bucketName);
        if (flag) {
            minioClient.uploadObject(UploadObjectArgs.builder().bucket(bucketName).object(objectName).filename(fileName).build());
            ObjectStat statObject = statObject(bucketName, objectName);
            if (statObject != null && statObject.length() > 0) {
                return true;
            }
        }
        return false;
    }
    /**
     * æ–‡ä»¶ä¸Šä¼ 
     *
     * @param bucketName    å­˜å‚¨æ…名称
     * @param multipartFile æ–‡ä»¶
     * @param filename      æ–‡ä»¶å
     */
    public void putObject(String bucketName, MultipartFile multipartFile, String filename) throws Exception {
        PutObjectOptions putObjectOptions = new PutObjectOptions(multipartFile.getSize(), PutObjectOptions.MIN_MULTIPART_SIZE);
        putObjectOptions.setContentType(multipartFile.getContentType());
        minioClient.putObject(PutObjectArgs.builder().bucket(bucketName).object(filename).stream(multipartFile.getInputStream(), multipartFile.getSize(), -1).contentType(multipartFile.getContentType()).build());
    }
    /**
     * é€šè¿‡InputStream上传对象
     *
     * @param bucketName  å­˜å‚¨æ¡¶åç§°
     * @param objectName  å­˜å‚¨æ¡¶é‡Œçš„对象名称
     * @param inputStream è¦ä¸Šä¼ çš„æµ
     * @param contentType ä¸Šä¼ çš„æ–‡ä»¶ç±»åž‹ ä¾‹å¦‚ video/mp4  image/jpg
     * @return boolean
     */
    public boolean putObject(String bucketName, String objectName, InputStream inputStream, String contentType) throws Exception {
        boolean flag = bucketExists(bucketName);
        if (flag) {
            minioClient.putObject(PutObjectArgs.builder().bucket(bucketName).object(objectName).stream(
                    //不清楚文件的大小时,可以传-1,10485760。如果知道大小也可以传入size,partsize。
                    inputStream, -1, 10485760).contentType(contentType).build());
            ObjectStat statObject = statObject(bucketName, objectName);
            if (statObject != null && statObject.length() > 0) {
                return true;
            }
        }
        return false;
    }
    /**
     * ä»¥æµçš„形式获取一个文件对象
     *
     * @param bucketName å­˜å‚¨æ¡¶åç§°
     * @param objectName å­˜å‚¨æ¡¶é‡Œçš„对象名称
     * @return InputStream
     */
    public InputStream getObject(String bucketName, String objectName) throws Exception {
        boolean flag = bucketExists(bucketName);
        if (flag) {
            ObjectStat statObject = statObject(bucketName, objectName);
            if (statObject != null && statObject.length() > 0) {
                InputStream stream = minioClient.getObject(GetObjectArgs.builder().bucket(bucketName).object(objectName).build());
                return stream;
            }
        }
        return null;
    }
    /**
     * ä»¥æµçš„形式获取一个文件对象(断点下载)
     *
     * @param bucketName å­˜å‚¨æ¡¶åç§°
     * @param objectName å­˜å‚¨æ¡¶é‡Œçš„对象名称
     * @param offset     èµ·å§‹å­—节的位置
     * @param length     è¦è¯»å–的长度 (可选,如果无值则代表读到文件结尾)
     * @return InputStream
     */
    public InputStream getObject(String bucketName, String objectName, long offset, Long length) throws Exception {
        boolean flag = bucketExists(bucketName);
        if (flag) {
            ObjectStat statObject = statObject(bucketName, objectName);
            if (statObject != null && statObject.length() > 0) {
                InputStream stream = minioClient.getObject(GetObjectArgs.builder().bucket(bucketName).object(objectName).offset(1024L).length(4096L).build());
                return stream;
            }
        }
        return null;
    }
    /**
     * ä¸‹è½½å¹¶å°†æ–‡ä»¶ä¿å­˜åˆ°æœ¬åœ°
     *
     * @param bucketName å­˜å‚¨æ¡¶åç§°
     * @param objectName å­˜å‚¨æ¡¶é‡Œçš„对象名称
     * @param fileName   File name
     * @return boolean
     */
    public boolean downloadObject(String bucketName, String objectName, String fileName) throws Exception {
        boolean flag = bucketExists(bucketName);
        if (flag) {
            ObjectStat statObject = statObject(bucketName, objectName);
            if (statObject != null && statObject.length() > 0) {
                minioClient.downloadObject(DownloadObjectArgs.builder().bucket(bucketName).object(objectName).filename(fileName).build());
                return true;
            }
        }
        return false;
    }
    /**
     * åˆ é™¤ä¸€ä¸ªå¯¹è±¡
     *
     * @param bucketName å­˜å‚¨æ¡¶åç§°
     * @param objectName å­˜å‚¨æ¡¶é‡Œçš„对象名称
     */
    public boolean removeObject(String bucketName, String objectName) throws Exception {
        boolean flag = bucketExists(bucketName);
        if (flag) {
            minioClient.removeObject(RemoveObjectArgs.builder().bucket(bucketName).object(objectName).build());
            return true;
        }
        return false;
    }
    /**
     * åˆ é™¤æŒ‡å®šæ¡¶çš„多个文件对象,返回删除错误的对象列表,全部删除成功,返回空列表
     *
     * @param bucketName  å­˜å‚¨æ¡¶åç§°
     * @param objectNames å«æœ‰è¦åˆ é™¤çš„多个object名称的迭代器对象
     * @return eg:
     * List<DeleteObject> objects = new LinkedList<>();
     * objects.add(new DeleteObject("my-objectname1"));
     * objects.add(new DeleteObject("my-objectname2"));
     * objects.add(new DeleteObject("my-objectname3"));
     */
    public List<String> removeObjects(String bucketName, List<DeleteObject> objectNames) throws Exception {
        List<String> deleteErrorNames = new ArrayList<>();
        boolean flag = bucketExists(bucketName);
        if (flag) {
            Iterable<Result<DeleteError>> results = minioClient.removeObjects(RemoveObjectsArgs.builder().bucket(bucketName).objects(objectNames).build());
            for (Result<DeleteError> result : results) {
                DeleteError error = result.get();
                deleteErrorNames.add(error.objectName());
            }
        }
        return deleteErrorNames;
    }
    /**
     * ç”Ÿæˆä¸€ä¸ªç»™HTTP GET请求用的presigned URL。
     * æµè§ˆå™¨/移动端的客户端可以用这个URL进行
     * ï¼Œå³ä½¿å…¶æ‰€åœ¨çš„存储桶是私有的。这个presigned URL可以设置一个失效时间,默认值是999999天。
     *
     * @param bucketName å­˜å‚¨æ¡¶åç§°
     * @param objectName å­˜å‚¨æ¡¶é‡Œçš„对象名称
     * @param expires    å¤±æ•ˆæ—¶é—´ï¼ˆä»¥ç§’为单位),默认是999999天,不得大于999999天
     * @return
     */
    public String getPresignedObjectUrl(String bucketName, String objectName, Integer expires) throws Exception {
        boolean flag = bucketExists(bucketName);
        String url = "";
        if (flag) {
            if (expires < 1 || expires > DEFAULT_EXPIRY_TIME) {
                throw new InvalidExpiresRangeException(expires, "expires must be in range of 1 to " + DEFAULT_EXPIRY_TIME);
            }
            try {
                url = minioClient.getPresignedObjectUrl(GetPresignedObjectUrlArgs.builder().method(Method.GET).bucket(bucketName).object(objectName).expiry(expires)//动态参数
                        //                       .expiry(24 * 60 * 60)//用秒来计算一天时间有效期
//                        .expiry(1, TimeUnit.DAYS)//按天传参
//                        .expiry(1, TimeUnit.HOURS)//按小时传参数
                        .build());
            } catch (ErrorResponseException | InsufficientDataException | InternalException | InvalidBucketNameException | InvalidExpiresRangeException | InvalidKeyException | InvalidResponseException | IOException | NoSuchAlgorithmException | ServerException | XmlParserException e) {
                e.printStackTrace();
            }
        }
        return url;
    }
    /**
     * ç”Ÿæˆä¸€ä¸ªç»™HTTP PUT请求用的presigned URL。
     * æµè§ˆå™¨/移动端的客户端可以用这个URL进行上传,即使其所在的存储桶是私有的。这个presigned URL可以设置一个失效时间,默认值是7天。
     *
     * @param bucketName å­˜å‚¨æ¡¶åç§°
     * @param objectName å­˜å‚¨æ¡¶é‡Œçš„对象名称
     * @param expires    å¤±æ•ˆæ—¶é—´ï¼ˆä»¥ç§’为单位),默认是7天,不得大于七天
     * @return String
     */
    public String presignedPutObject(String bucketName, String objectName, Integer expires) throws Exception {
        boolean flag = bucketExists(bucketName);
        String url = "";
        if (flag) {
            if (expires < 1 || expires > DEFAULT_EXPIRY_TIME) {
                try {
                    throw new InvalidExpiresRangeException(expires, "expires must be in range of 1 to " + DEFAULT_EXPIRY_TIME);
                } catch (InvalidExpiresRangeException e) {
                    e.printStackTrace();
                }
            }
            try {
                url = minioClient.getPresignedObjectUrl(GetPresignedObjectUrlArgs.builder().method(Method.PUT).bucket(bucketName).object(objectName).expiry(expires)//动态参数
                        //                       .expiry(24 * 60 * 60)//用秒来计算一天时间有效期
//                        .expiry(1, TimeUnit.DAYS)//按天传参
//                        .expiry(1, TimeUnit.HOURS)//按小时传参数
                        .build());
            } catch (ErrorResponseException | InsufficientDataException e) {
                e.printStackTrace();
            } catch (InternalException e) {
                log.error("InternalException", e);
            } catch (InvalidBucketNameException e) {
                log.error("InvalidBucketNameException", e);
            } catch (InvalidExpiresRangeException e) {
                log.error("InvalidExpiresRangeException", e);
            } catch (InvalidKeyException e) {
                log.error("InvalidKeyException", e);
            } catch (InvalidResponseException e) {
                log.error("InvalidResponseException", e);
            } catch (IOException e) {
                log.error("IOException", e);
            } catch (NoSuchAlgorithmException e) {
                log.error("NoSuchAlgorithmException", e);
            } catch (ServerException e) {
                log.error("ServerException", e);
            } catch (XmlParserException e) {
                log.error("XmlParserException", e);
            }
        }
        return url;
    }
    /**
     * èŽ·å–å¯¹è±¡çš„å…ƒæ•°æ®
     *
     * @param bucketName å­˜å‚¨æ¡¶åç§°
     * @param objectName å­˜å‚¨æ¡¶é‡Œçš„对象名称
     * @return
     */
    public ObjectStat statObject(String bucketName, String objectName) throws Exception {
        boolean flag = bucketExists(bucketName);
        if (flag) {
            ObjectStat statObject = null;
            statObject = minioClient.statObject(StatObjectArgs.builder().bucket(bucketName).object(objectName).build());
            return statObject;
        }
        return null;
    }
    /**
     * æ–‡ä»¶è®¿é—®è·¯å¾„
     *
     * @param bucketName å­˜å‚¨æ¡¶åç§°
     * @param objectName å­˜å‚¨æ¡¶é‡Œçš„对象名称
     * @return String
     */
    public String getObjectUrl(String bucketName, String objectName) throws Exception {
        boolean flag = bucketExists(bucketName);
        String url = "";
        if (flag) {
            try {
                url = minioClient.getObjectUrl(bucketName, objectName);
            } catch (ErrorResponseException e) {
                log.error("XmlParserException", e);
            } catch (InsufficientDataException e) {
                log.error("InsufficientDataException", e);
            } catch (InternalException e) {
                log.error("InternalException", e);
            } catch (InvalidKeyException e) {
                log.error("InvalidKeyException", e);
            } catch (InvalidResponseException e) {
                log.error("InvalidResponseException", e);
            } catch (IOException e) {
                log.error("IOException", e);
            } catch (NoSuchAlgorithmException e) {
                log.error("NoSuchAlgorithmException", e);
            } catch (ServerException e) {
                log.error("ServerException", e);
            } catch (XmlParserException e) {
                log.error("XmlParserException", e);
            }
        }
        return url;
    }
    public void downloadFile(String bucketName, String fileName, String originalName, HttpServletResponse response) {
        try {
            InputStream file = minioClient.getObject(GetObjectArgs.builder().bucket(bucketName).object(fileName).build());
            String filename = new String(fileName.getBytes("ISO8859-1"), StandardCharsets.UTF_8);
            if (StringUtils.isNotEmpty(originalName)) {
                fileName = originalName;
            }
            response.setHeader("Content-Disposition", "attachment;filename=" + filename);
            ServletOutputStream servletOutputStream = response.getOutputStream();
            int len;
            byte[] buffer = new byte[1024];
            while ((len = file.read(buffer)) > 0) {
                servletOutputStream.write(buffer, 0, len);
            }
            servletOutputStream.flush();
            file.close();
            servletOutputStream.close();
        } catch (ErrorResponseException e) {
            log.error("ErrorResponseException", e);
        } catch (Exception e) {
            log.error("Exception", e);
        }
    }
}
smartor/src/main/java/com/smartor/domain/MinioFile.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,77 @@
package com.smartor.domain;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import com.ruoyi.common.annotation.Excel;
import com.ruoyi.common.core.domain.BaseEntity;
/**
 * ã€è¯·å¡«å†™åŠŸèƒ½åç§°ã€‘å¯¹è±¡ minio_file
 *
 * @author ruoyi
 * @date 2023-06-19
 */
@Data
@ApiModel(value = "MinioFile", description = "标签分类对象")
public class MinioFile extends BaseEntity {
    private static final long serialVersionUID = 1L;
    /**
     * æ–‡ä»¶id
     */
    @ApiModelProperty(value = "文件id")
    private Long id;
    /**
     * åŽŸå§‹æ–‡ä»¶åç§°
     */
    @Excel(name = "原始文件名称")
    @ApiModelProperty(value = "原始文件名称")
    private String originalFileName;
    /**
     * æ–‡ä»¶æ‹“展名
     */
    @Excel(name = "文件拓展名")
    @ApiModelProperty(value = "文件拓展名")
    private String fileExtName;
    /**
     * æ–‡ä»¶å¤§å°(单位:字节)
     */
    @Excel(name = "文件大小(单位:字节)")
    @ApiModelProperty(value = "文件大小(单位:字节)")
    private Long fileSize;
    /**
     * å­˜å…¥minio时的文件名称
     */
    @Excel(name = "存入minio时的文件名称")
    @ApiModelProperty(value = "存入minio时的文件名称")
    private String fileName;
    /**
     * æ–‡ä»¶çš„content-type
     */
    @Excel(name = "文件的content-type")
    @ApiModelProperty(value = "文件的content-type")
    private String mime;
    /**
     * æ–‡ä»¶è·¯å¾„
     */
    @Excel(name = "文件路径")
    @ApiModelProperty(value = "文件路径")
    private String fileUrl;
    /**
     * æ˜¯å¦åˆ é™¤ 0 å¦ 1 æ˜¯
     */
    @Excel(name = "是否删除 0 å¦ 1 æ˜¯")
    @ApiModelProperty(value = "是否删除 0 å¦ 1 æ˜¯")
    private Integer isDelete;
}
smartor/src/main/java/com/smartor/domain/MinioResponseDTO.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,15 @@
package com.smartor.domain;
import io.swagger.annotations.ApiModel;
import lombok.Data;
@Data
@ApiModel(value = "MinioResponseDTO", description = "标签分类对象")
public class MinioResponseDTO {
    private Long fileId;
    private String fileUrl;
    private String originalFileName;
}
smartor/src/main/java/com/smartor/domain/PatArchiveReq.java
@@ -48,7 +48,7 @@
     * æ ‡ç­¾ID
     */
    @ApiModelProperty("标签ID")
    private String tagId;
    private List<String> tagIds;
}
smartor/src/main/java/com/smartor/domain/TreeNode.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,31 @@
package com.smartor.domain;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.apache.commons.lang3.ObjectUtils;
import java.util.ArrayList;
import java.util.List;
@ApiModel(value = "TreeNode", description = "节点树")
@Data
public class TreeNode {
    @ApiModelProperty(name = "节点名称")
    private String name;
    @ApiModelProperty(name = "子节点集合")
    private List<TreeNode> children;
    public TreeNode(String name) {
        this.name = name;
        this.children = new ArrayList<>();
    }
    public void addChild(TreeNode child) {
            children.add(child);
    }
}
smartor/src/main/java/com/smartor/mapper/MinioFileMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,63 @@
package com.smartor.mapper;
import com.smartor.domain.MinioFile;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
/**
 * ã€è¯·å¡«å†™åŠŸèƒ½åç§°ã€‘Mapper接口
 *
 * @author ruoyi
 * @date 2023-06-19
 */
@Mapper
public interface MinioFileMapper {
    /**
     * æŸ¥è¯¢ã€è¯·å¡«å†™åŠŸèƒ½åç§°ã€‘
     *
     * @param id ã€è¯·å¡«å†™åŠŸèƒ½åç§°ã€‘ä¸»é”®
     * @return ã€è¯·å¡«å†™åŠŸèƒ½åç§°ã€‘
     */
    public MinioFile selectMinioFileById(Long id);
    /**
     * æŸ¥è¯¢ã€è¯·å¡«å†™åŠŸèƒ½åç§°ã€‘åˆ—è¡¨
     *
     * @param minioFile ã€è¯·å¡«å†™åŠŸèƒ½åç§°ã€‘
     * @return ã€è¯·å¡«å†™åŠŸèƒ½åç§°ã€‘é›†åˆ
     */
    public List<MinioFile> selectMinioFileList(MinioFile minioFile);
    /**
     * æ–°å¢žã€è¯·å¡«å†™åŠŸèƒ½åç§°ã€‘
     *
     * @param minioFile ã€è¯·å¡«å†™åŠŸèƒ½åç§°ã€‘
     * @return ç»“æžœ
     */
    public int insertMinioFile(MinioFile minioFile);
    /**
     * ä¿®æ”¹ã€è¯·å¡«å†™åŠŸèƒ½åç§°ã€‘
     *
     * @param minioFile ã€è¯·å¡«å†™åŠŸèƒ½åç§°ã€‘
     * @return ç»“æžœ
     */
    public int updateMinioFile(MinioFile minioFile);
    /**
     * åˆ é™¤ã€è¯·å¡«å†™åŠŸèƒ½åç§°ã€‘
     *
     * @param id ã€è¯·å¡«å†™åŠŸèƒ½åç§°ã€‘ä¸»é”®
     * @return ç»“æžœ
     */
    public int deleteMinioFileById(Long id);
    /**
     * æ‰¹é‡åˆ é™¤ã€è¯·å¡«å†™åŠŸèƒ½åç§°ã€‘
     *
     * @param ids éœ€è¦åˆ é™¤çš„æ•°æ®ä¸»é”®é›†åˆ
     * @return ç»“æžœ
     */
    public int deleteMinioFileByIds(Long[] ids);
}
smartor/src/main/java/com/smartor/service/IMinioFileService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,96 @@
package com.smartor.service;
import com.smartor.domain.MinioFile;
import com.smartor.domain.MinioResponseDTO;
import com.smartor.domain.TreeNode;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.util.List;
/**
 * ã€è¯·å¡«å†™åŠŸèƒ½åç§°ã€‘Service接口
 *
 * @author ruoyi
 * @date 2023-06-19
 */
public interface IMinioFileService {
    /**
     * æŸ¥è¯¢ã€è¯·å¡«å†™åŠŸèƒ½åç§°ã€‘
     *
     * @param id ã€è¯·å¡«å†™åŠŸèƒ½åç§°ã€‘ä¸»é”®
     * @return ã€è¯·å¡«å†™åŠŸèƒ½åç§°ã€‘
     */
    public MinioFile selectMinioFileById(Long id);
    /**
     * æŸ¥è¯¢ã€è¯·å¡«å†™åŠŸèƒ½åç§°ã€‘åˆ—è¡¨
     *
     * @param minioFile ã€è¯·å¡«å†™åŠŸèƒ½åç§°ã€‘
     * @return ã€è¯·å¡«å†™åŠŸèƒ½åç§°ã€‘é›†åˆ
     */
    public List<MinioFile> selectMinioFileList(MinioFile minioFile);
    /**
     * æ–°å¢žã€è¯·å¡«å†™åŠŸèƒ½åç§°ã€‘
     *
     * @param minioFile ã€è¯·å¡«å†™åŠŸèƒ½åç§°ã€‘
     * @return ç»“æžœ
     */
    public int insertMinioFile(MinioFile minioFile);
    /**
     * ä¿®æ”¹ã€è¯·å¡«å†™åŠŸèƒ½åç§°ã€‘
     *
     * @param minioFile ã€è¯·å¡«å†™åŠŸèƒ½åç§°ã€‘
     * @return ç»“æžœ
     */
    public int updateMinioFile(MinioFile minioFile);
    /**
     * æ‰¹é‡åˆ é™¤ã€è¯·å¡«å†™åŠŸèƒ½åç§°ã€‘
     *
     * @param ids éœ€è¦åˆ é™¤çš„【请填写功能名称】主键集合
     * @return ç»“æžœ
     */
    public int deleteMinioFileByIds(Long[] ids);
    /**
     * åˆ é™¤ã€è¯·å¡«å†™åŠŸèƒ½åç§°ã€‘ä¿¡æ¯
     *
     * @param id ã€è¯·å¡«å†™åŠŸèƒ½åç§°ã€‘ä¸»é”®
     * @return ç»“æžœ
     */
    public int deleteMinioFileById(Long id);
    /**
     * æ–‡ä»¶æ‰¹é‡ä¸Šä¼ 
     *
     * @param files
     * @return
     */
    public List<MinioResponseDTO> commonUploadFile(String path, List<MultipartFile> files);
    /**
     * èŽ·å–ï¼ˆå®£æ•™ï¼‰å¼•ç”¨æ¨¡æ¿
     *
     * @param
     * @return
     */
    public TreeNode getEduTemplage();
    /**
     * @param fileName å…¨è·¯å¾„文件名
     * @return
     */
    public void downloadFile(HttpServletResponse response, String fileName);
    /**
     * èŽ·å–å›¾ç‰‡ã€éŸ³é¢‘ã€è§†é¢‘ çš„URL, å…¥å‚çš„fileName为全路径文件名
     *
     * @param fileName
     * @return
     */
    public String getFileUrl(String fileName, Integer expires);
}
smartor/src/main/java/com/smartor/service/impl/MinioFileServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,246 @@
package com.smartor.service.impl;
import cn.hutool.core.io.FileUtil;
import com.ruoyi.common.config.MinioConfig;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.MinioClientUtils;
import com.ruoyi.common.utils.StringUtils;
import com.smartor.domain.MinioFile;
import com.smartor.domain.MinioResponseDTO;
import com.smartor.domain.TreeNode;
import com.smartor.mapper.MinioFileMapper;
import com.smartor.service.IMinioFileService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.time.Instant;
import java.util.ArrayList;
import java.util.List;
/**
 * ã€è¯·å¡«å†™åŠŸèƒ½åç§°ã€‘Service业务层处理
 *
 * @author ruoyi
 * @date 2023-06-19
 */
@Slf4j
@Service
public class MinioFileServiceImpl implements IMinioFileService {
    @Autowired
    private MinioFileMapper minioFileMapper;
    @Resource
    private MinioClientUtils minioClientUtils;
    @Resource
    private MinioConfig minioConfig;
    /**
     * æŸ¥è¯¢ã€è¯·å¡«å†™åŠŸèƒ½åç§°ã€‘
     *
     * @param id ã€è¯·å¡«å†™åŠŸèƒ½åç§°ã€‘ä¸»é”®
     * @return ã€è¯·å¡«å†™åŠŸèƒ½åç§°ã€‘
     */
    @Override
    public MinioFile selectMinioFileById(Long id) {
        return minioFileMapper.selectMinioFileById(id);
    }
    /**
     * æŸ¥è¯¢ã€è¯·å¡«å†™åŠŸèƒ½åç§°ã€‘åˆ—è¡¨
     *
     * @param minioFile ã€è¯·å¡«å†™åŠŸèƒ½åç§°ã€‘
     * @return ã€è¯·å¡«å†™åŠŸèƒ½åç§°ã€‘
     */
    @Override
    public List<MinioFile> selectMinioFileList(MinioFile minioFile) {
        return minioFileMapper.selectMinioFileList(minioFile);
    }
    /**
     * æ–°å¢žã€è¯·å¡«å†™åŠŸèƒ½åç§°ã€‘
     *
     * @param minioFile ã€è¯·å¡«å†™åŠŸèƒ½åç§°ã€‘
     * @return ç»“æžœ
     */
    @Override
    public int insertMinioFile(MinioFile minioFile) {
        minioFile.setCreateTime(DateUtils.getNowDate());
        return minioFileMapper.insertMinioFile(minioFile);
    }
    /**
     * ä¿®æ”¹ã€è¯·å¡«å†™åŠŸèƒ½åç§°ã€‘
     *
     * @param minioFile ã€è¯·å¡«å†™åŠŸèƒ½åç§°ã€‘
     * @return ç»“æžœ
     */
    @Override
    public int updateMinioFile(MinioFile minioFile) {
        minioFile.setUpdateTime(DateUtils.getNowDate());
        return minioFileMapper.updateMinioFile(minioFile);
    }
    /**
     * æ‰¹é‡åˆ é™¤ã€è¯·å¡«å†™åŠŸèƒ½åç§°ã€‘
     *
     * @param ids éœ€è¦åˆ é™¤çš„【请填写功能名称】主键
     * @return ç»“æžœ
     */
    @Override
    public int deleteMinioFileByIds(Long[] ids) {
        return minioFileMapper.deleteMinioFileByIds(ids);
    }
    /**
     * åˆ é™¤ã€è¯·å¡«å†™åŠŸèƒ½åç§°ã€‘ä¿¡æ¯
     *
     * @param id ã€è¯·å¡«å†™åŠŸèƒ½åç§°ã€‘ä¸»é”®
     * @return ç»“æžœ
     */
    @Override
    public int deleteMinioFileById(Long id) {
        return minioFileMapper.deleteMinioFileById(id);
    }
    @Override
    public List<MinioResponseDTO> commonUploadFile(String path, List<MultipartFile> files) {
        log.info(files.toString());
        if (StringUtils.isNotEmpty(path) && !path.endsWith("/")) {
            path = path + "/";
        }
        List<MinioResponseDTO> MinioResponseDTOList = new ArrayList<>();
        for (MultipartFile file : files) {
            String originalFilename = file.getOriginalFilename();
//            èŽ·å–æ–‡ä»¶æ‹“å±•å
            String extName = FileUtil.extName(originalFilename);
            log.info("文件拓展名:" + extName);
//            ç”Ÿæˆæ–°çš„æ–‡ä»¶åï¼Œå­˜å…¥åˆ°minio
            long millSeconds = Instant.now().toEpochMilli();
            String minioFileName = millSeconds + RandomStringUtils.randomNumeric(12) + "." + extName;
            String contentType = file.getContentType();
            log.info("文件mime:{}", contentType);
//            è¿”回文件大小,单位字节
            long size = file.getSize();
            log.info("文件大小:" + size);
            try {
                String bucketName = minioConfig.getBucketName();
                minioClientUtils.putObject(bucketName, file, path + originalFilename);
//                String fileUrl = minioClientUtils.getObjectUrl(bucketName, path + originalFilename);
                String fileUrl = path + originalFilename;
                MinioFile minioFile = new MinioFile();
                minioFile.setOriginalFileName(originalFilename);
                minioFile.setFileExtName(extName);
                minioFile.setFileName(originalFilename);
                minioFile.setFileSize(size);
                minioFile.setMime(contentType);
                minioFile.setIsDelete(NumberUtils.INTEGER_ZERO);
                minioFile.setFileUrl(fileUrl);
                int i = insertMinioFile(minioFile);
                if (i > 0) {
                    MinioResponseDTO minioResponseDTO = new MinioResponseDTO();
                    minioResponseDTO.setFileId(minioFile.getId());
                    minioResponseDTO.setOriginalFileName(originalFilename);
                    minioResponseDTO.setFileUrl(fileUrl);
                    MinioResponseDTOList.add(minioResponseDTO);
                }
            } catch (Exception e) {
                log.error("上传文件出错:{}", e);
            }
        }
        return MinioResponseDTOList;
    }
    @Override
    public TreeNode getEduTemplage() {
        List<MinioFile> minioFiles = minioFileMapper.selectMinioFileList(null);
        TreeNode root = new TreeNode("");
        // ä½¿ç”¨é€’归将列表转成树开结构
        for (MinioFile minioFile1 : minioFiles) {
            String[] parts = minioFile1.getFileUrl().split("/");
            TreeNode current = root;
            for (String part : parts) {
                if (!part.isEmpty()) {
                    TreeNode child = findChild(current, part);
                    if (child == null) {
                        child = new TreeNode(part);
                        current.addChild(child);
                    }
                    current = child;
                }
            }
        }
        return root;
    }
    @Override
    public void downloadFile(HttpServletResponse response, String fileName) {
        InputStream object = null;
        try {
            object = minioClientUtils.getObject(minioConfig.getBucketName(), fileName);
            writeFile(response, object);
        } catch (Exception e) {
            log.info("文件下载,报错了!!!{}", fileName);
            e.printStackTrace();
        }
    }
    @Override
    public String getFileUrl(String fileName, Integer expires) {
        String presignedObjectUrl = null;
        try {
            presignedObjectUrl = minioClientUtils.getPresignedObjectUrl(minioConfig.getBucketName(), fileName, expires);
            //去掉url里?后面的请求信息
            presignedObjectUrl = presignedObjectUrl.substring(0, presignedObjectUrl.lastIndexOf("?"));
        } catch (Exception e) {
            log.info("文件下载,报错了!!!{},  {}", fileName, expires);
            e.printStackTrace();
        }
        return presignedObjectUrl;
    }
    private TreeNode findChild(TreeNode parent, String name) {
        for (TreeNode child : parent.getChildren()) {
            if (child.getName().equals(name)) {
                return child;
            }
        }
        return null;
    }
    public void writeFile(HttpServletResponse resp, InputStream inputStream) {
        OutputStream out = null;
        try {
            out = resp.getOutputStream();
            int len = 0;
            byte[] b = new byte[1024];
            while ((len = inputStream.read(b)) != -1) {
                out.write(b, 0, len);
            }
            out.flush();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (out != null) {
                    out.close();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}
smartor/src/main/resources/mapper/smartor/BaseTagcategoryMapper.xml
@@ -132,10 +132,10 @@
        a.upload_time,
        a.categoryname,
        count(b.tagid) as tagNum
        from base_tagcategory a,base_tag b
        from base_tagcategory a left join base_tag b
        on a.tagcategoryid = b.tagcategoryid
        <where>
            a.tagcategoryid = b.tagcategoryid
            <if test="categoryname != null  and categoryname != ''">and a.categoryname like concat('%', #{categoryname},
            <if test="categoryname != null  and categoryname != ''">a.categoryname like concat('%', #{categoryname},
                '%')
            </if>
        </where>
smartor/src/main/resources/mapper/smartor/MinioFileMapper.xml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,122 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.smartor.mapper.MinioFileMapper">
    <resultMap type="com.smartor.domain.MinioFile" id="MinioFileResult">
        <result property="id" column="id"/>
        <result property="originalFileName" column="original_file_name"/>
        <result property="fileExtName" column="file_ext_name"/>
        <result property="fileSize" column="file_size"/>
        <result property="fileName" column="file_name"/>
        <result property="mime" column="mime"/>
        <result property="fileUrl" column="file_url"/>
        <result property="isDelete" column="is_delete"/>
        <result property="createBy" column="create_by"/>
        <result property="createTime" column="create_time"/>
        <result property="updateBy" column="update_by"/>
        <result property="updateTime" column="update_time"/>
    </resultMap>
    <sql id="selectMinioFileVo">
        select id,
               original_file_name,
               file_ext_name,
               file_size,
               file_name,
               mime,
               file_url,
               is_delete,
               create_by,
               create_time,
               update_by,
               update_time
        from minio_file
    </sql>
    <select id="selectMinioFileList" parameterType="com.smartor.domain.MinioFile" resultMap="MinioFileResult">
        <include refid="selectMinioFileVo"/>
        <where>
            <if test="originalFileName != null  and originalFileName != ''">and original_file_name like concat('%',
                #{originalFileName}, '%')
            </if>
            <if test="fileExtName != null  and fileExtName != ''">and file_ext_name like concat('%', #{fileExtName},
                '%')
            </if>
            <if test="fileSize != null ">and file_size = #{fileSize}</if>
            <if test="fileName != null  and fileName != ''">and file_name like concat('%', #{fileName}, '%')</if>
            <if test="mime != null  and mime != ''">and mime = #{mime}</if>
            <if test="fileUrl != null  and fileUrl != ''">and file_url = #{fileUrl}</if>
            <if test="isDelete != null ">and is_delete = #{isDelete}</if>
        </where>
    </select>
    <select id="selectMinioFileById" parameterType="Long" resultMap="MinioFileResult">
        <include refid="selectMinioFileVo"/>
        where id = #{id}
    </select>
    <insert id="insertMinioFile" parameterType="com.smartor.domain.MinioFile">
        insert into minio_file
        <trim prefix="(" suffix=")" suffixOverrides=",">
            <if test="id != null">id,</if>
            <if test="originalFileName != null">original_file_name,</if>
            <if test="fileExtName != null">file_ext_name,</if>
            <if test="fileSize != null">file_size,</if>
            <if test="fileName != null">file_name,</if>
            <if test="mime != null">mime,</if>
            <if test="fileUrl != null">file_url,</if>
            <if test="isDelete != null">is_delete,</if>
            <if test="createBy != null">create_by,</if>
            <if test="createTime != null">create_time,</if>
            <if test="updateBy != null">update_by,</if>
            <if test="updateTime != null">update_time,</if>
        </trim>
        <trim prefix="values (" suffix=")" suffixOverrides=",">
            <if test="id != null">#{id},</if>
            <if test="originalFileName != null">#{originalFileName},</if>
            <if test="fileExtName != null">#{fileExtName},</if>
            <if test="fileSize != null">#{fileSize},</if>
            <if test="fileName != null">#{fileName},</if>
            <if test="mime != null">#{mime},</if>
            <if test="fileUrl != null">#{fileUrl},</if>
            <if test="isDelete != null">#{isDelete},</if>
            <if test="createBy != null">#{createBy},</if>
            <if test="createTime != null">#{createTime},</if>
            <if test="updateBy != null">#{updateBy},</if>
            <if test="updateTime != null">#{updateTime},</if>
        </trim>
    </insert>
    <update id="updateMinioFile" parameterType="com.smartor.domain.MinioFile">
        update minio_file
        <trim prefix="SET" suffixOverrides=",">
            <if test="originalFileName != null">original_file_name = #{originalFileName},</if>
            <if test="fileExtName != null">file_ext_name = #{fileExtName},</if>
            <if test="fileSize != null">file_size = #{fileSize},</if>
            <if test="fileName != null">file_name = #{fileName},</if>
            <if test="mime != null">mime = #{mime},</if>
            <if test="fileUrl != null">file_url = #{fileUrl},</if>
            <if test="isDelete != null">is_delete = #{isDelete},</if>
            <if test="createBy != null">create_by = #{createBy},</if>
            <if test="createTime != null">create_time = #{createTime},</if>
            <if test="updateBy != null">update_by = #{updateBy},</if>
            <if test="updateTime != null">update_time = #{updateTime},</if>
        </trim>
        where id = #{id}
    </update>
    <delete id="deleteMinioFileById" parameterType="Long">
        delete
        from minio_file
        where id = #{id}
    </delete>
    <delete id="deleteMinioFileByIds" parameterType="String">
        delete from minio_file where id in
        <foreach item="id" collection="array" open="(" separator="," close=")">
            #{id}
        </foreach>
    </delete>
</mapper>
smartor/src/main/resources/mapper/smartor/PatArchiveMapper.xml
@@ -88,7 +88,11 @@
            <if test="name != null  and name != ''">and a.name like concat('%', #{name}, '%')</if>
            <if test="iccardno != null  and iccardno != ''">and iccardno = #{iccardno}</if>
            <if test="telcode != null  and telcode != ''">and telcode = #{telcode}</if>
            <if test="tagId != null  and tagId != ''">and c.tagid = #{tagId}</if>
            <if test="tagIds != null  and tagIds != ''">and c.tagid in
                <foreach collection="tagIds" item="tagId" open="(" separator="," close=")">
                    #{tagId}
                </foreach>
            </if>
        </where>
    </select>
@@ -97,7 +101,8 @@
        where patid = #{patid}
    </select>
    <insert id="insertPatArchive" parameterType="com.smartor.domain.PatArchive" useGeneratedKeys="true" keyProperty="patid">
    <insert id="insertPatArchive" parameterType="com.smartor.domain.PatArchive" useGeneratedKeys="true"
            keyProperty="patid">
        insert into pat_archive
        <trim prefix="(" suffix=")" suffixOverrides=",">
            <if test="name != null">name,</if>