2021与蓝度共同重构项目,服务端
liuhaonan
2022-04-08 aa1c7114578981463e226d4b2d7773bc1b7994da
ip音柱文件上传
已修改7个文件
已添加8个文件
866 ■■■■■ 文件已修改
pom.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ximon-admin/src/main/java/com/sandu/ximon/admin/controller/IpVolumeFileController.java 25 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ximon-admin/src/main/java/com/sandu/ximon/admin/minio/BroadcastFileUtils.java 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ximon-admin/src/main/java/com/sandu/ximon/admin/minio/config/MinIoConfig.java 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ximon-admin/src/main/java/com/sandu/ximon/admin/minio/config/MinIoPolicy.java 63 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ximon-admin/src/main/java/com/sandu/ximon/admin/minio/config/MinioPolicyStatement.java 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ximon-admin/src/main/java/com/sandu/ximon/admin/minio/config/MinioPolicyStatementPrincipal.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ximon-admin/src/main/java/com/sandu/ximon/admin/minio/entity/FileSuffix.java 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ximon-admin/src/main/java/com/sandu/ximon/admin/minio/entity/MinIoConstant.java 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ximon-admin/src/main/java/com/sandu/ximon/admin/minio/utils/MinIoUtil.java 497 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ximon-admin/src/main/java/com/sandu/ximon/admin/service/IpVolumeFileService.java 68 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ximon-admin/src/main/java/com/sandu/ximon/admin/service/IpVolumeMissionService.java 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ximon-admin/src/main/resources/application-dev.yml 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ximon-admin/src/main/resources/application-test.yml 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ximon-admin/src/main/resources/application.yml 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pom.xml
@@ -127,6 +127,13 @@
                <version>3.17</version>
            </dependency>
            <!-- MinIO服务器 -->
            <dependency>
                <groupId>io.minio</groupId>
                <artifactId>minio</artifactId>
                <version>7.1.0</version>
            </dependency>
        </dependencies>
    </dependencyManagement>
ximon-admin/src/main/java/com/sandu/ximon/admin/controller/IpVolumeFileController.java
@@ -4,23 +4,17 @@
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.pagehelper.PageHelper;
import com.sandu.common.domain.ResponseVO;
import com.sandu.common.enums.FileStorageEnums;
import com.sandu.common.execption.BusinessException;
import com.sandu.common.file.FileUploadDto;
import com.sandu.common.file.impl.LocalFileUploadImpl;
import com.sandu.common.object.BaseConditionVO;
import com.sandu.common.util.ResponseUtil;
import com.sandu.ximon.admin.param.IpVolumeFileParam;
import com.sandu.ximon.admin.param.ReceiveParam;
import com.sandu.ximon.admin.service.BroadcastV2TaskFileService;
import com.sandu.ximon.admin.service.FileOperationRecordService;
import com.sandu.ximon.admin.service.IpVolumeFileService;
import com.sandu.ximon.dao.domain.BroadcastV2TaskFile;
import com.sandu.ximon.dao.domain.FileOperationRecord;
import com.sandu.ximon.dao.domain.IpVolumeFile;
import com.sandu.ximon.dao.domain.LedSFile;
import lombok.AllArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
@@ -43,21 +37,21 @@
    private final LocalFileUploadImpl fileUpload;
    @PostMapping("/add")
    public ResponseVO<Object> addFile(@RequestBody @Validated IpVolumeFileParam fileParam){
    public ResponseVO<Object> addFile(@RequestBody @Validated IpVolumeFileParam fileParam) {
        return ResponseUtil.success(ipVolumeFileService.addFile(fileParam));
    }
    @PostMapping("/delete/{fileId}")
    public ResponseVO<Object> deleteFile(@PathVariable Long fileId){
    public ResponseVO<Object> deleteFile(@PathVariable Long fileId) {
        List<BroadcastV2TaskFile> list = v2TaskFileService.list(Wrappers.lambdaQuery(BroadcastV2TaskFile.class).eq(BroadcastV2TaskFile::getFileId, fileId));
        if(list.size()!=0){
        if (list.size() != 0) {
            throw new BusinessException("此文件正在被其他任务占用");
        }
        return ResponseUtil.success(ipVolumeFileService.deleteFile(fileId));
    }
    @GetMapping("/list")
    public ResponseVO<Object> list(BaseConditionVO baseConditionVO, @RequestParam(value = "keyword", required = false) String keyword){
    public ResponseVO<Object> list(BaseConditionVO baseConditionVO, @RequestParam(value = "keyword", required = false) String keyword) {
        LambdaQueryWrapper<IpVolumeFile> wrapper = ipVolumeFileService.listFile(baseConditionVO, keyword);
        PageHelper.startPage(baseConditionVO.getPageNo(), baseConditionVO.getPageSize());
      /*  if (null != keyword) {
@@ -68,15 +62,6 @@
    @PostMapping("/IpVolumeFileUploading")
    public ResponseVO<Object> uploadingFile(@RequestParam("file") MultipartFile file) {
        FileUploadDto fileUploadDto = fileUpload.uploadFile(file);
        FileOperationRecord fileOperationRecord = new FileOperationRecord();
//        if("mp4".equals(fileUploadDto.getFileType())){
//            fileUploadDto.setScreenShot(fileUploadDto.getFileUrl()+"?x-oss-process=video/snapshot,t_10000,m_fast");
//        }
        BeanUtils.copyProperties(fileUploadDto, fileOperationRecord);
        fileOperationRecord.setDataType(3);
        fileOperationRecordService.save(fileOperationRecord);
        return ResponseUtil.success(fileUploadDto);
        return ResponseUtil.success(ipVolumeFileService.upload(file));
    }
}
ximon-admin/src/main/java/com/sandu/ximon/admin/minio/BroadcastFileUtils.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,31 @@
package com.sandu.ximon.admin.minio;
import com.sandu.ximon.admin.minio.entity.FileSuffix;
import java.text.DecimalFormat;
public class BroadcastFileUtils {
    /**
     * åˆ¤æ–­åŽç¼€åæ˜¯å¦ä¸€è‡´
     */
    public static boolean isMp3File(String filename, FileSuffix suffix) {
        String fileSuffix = filename.substring(filename.lastIndexOf(".")+1);
        if(fileSuffix.equals(suffix.getSuffix())) {
            return true;
        }
        return false;
    }
    /**
     * å­—节数转MB
     * @param size
     * @return
     */
    public static Double getMBSize(long size) {
        return Double.valueOf(new DecimalFormat("#.00").format((size / 1024) /1024 ));
    }
}
ximon-admin/src/main/java/com/sandu/ximon/admin/minio/config/MinIoConfig.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,36 @@
package com.sandu.ximon.admin.minio.config;
import com.sandu.ximon.admin.utils.LogUtils;
import io.minio.MinioClient;
import io.minio.errors.InvalidEndpointException;
import io.minio.errors.InvalidPortException;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
@Data
@Component
@ConfigurationProperties(prefix = "minio")
public class MinIoConfig {
    private String endpoint;
    private int port;
    private String accessKey;
    private String secretKey;
    private Boolean secure;
    public static final String VNNOX_URL = "http://47.106.172.9:9000/";
    @Bean
    public MinioClient getMinIoClient() throws InvalidEndpointException, InvalidPortException {
        MinioClient minioClient = new MinioClient(endpoint, port, accessKey, secretKey, secure);
        LogUtils.print("init minio : (endpoint: " + endpoint + ")(port: " + port + ")");
        return minioClient;
    }
}
ximon-admin/src/main/java/com/sandu/ximon/admin/minio/config/MinIoPolicy.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,63 @@
package com.sandu.ximon.admin.minio.config;
import com.google.gson.Gson;
import lombok.Data;
import java.util.ArrayList;
import java.util.List;
@Data
public class MinIoPolicy {
    private String Version;
    private List<MinioPolicyStatement> Statement;
    /**
     * ç”Ÿæˆ * é€šè¡Œç­–ç•¥
     * @return
     */
    public static String generateMinioPolicy (String bucketName) {
        MinIoPolicy policy = new MinIoPolicy();
        policy.setVersion("2012-10-17");
        List<MinioPolicyStatement> minioPolicyStatements = new ArrayList<>();
        MinioPolicyStatement statement = new MinioPolicyStatement();
        statement.setEffect("Allow");
        MinioPolicyStatementPrincipal policyStatementPrincipal = new MinioPolicyStatementPrincipal();
        List<String> aws = new ArrayList<>();
        aws.add("*");
        policyStatementPrincipal.setAWS(aws);
        statement.setPrincipal(policyStatementPrincipal);
        List<String> action = new ArrayList<>();
        action.add("s3:GetBucketLocation");
        action.add("s3:ListBucket");
        statement.setAction(action);
        List<String> resources = new ArrayList<>();
        resources.add("arn:aws:s3:::"+bucketName);
        statement.setResource(resources);
        MinioPolicyStatement statement2 = new MinioPolicyStatement();
        statement2.setEffect("Allow");
        statement2.setPrincipal(policyStatementPrincipal);
        action = new ArrayList<>();
        action.add("s3:GetObject");
        statement2.setAction(action);
        resources = new ArrayList<>();
        resources.add("arn:aws:s3:::"+bucketName+"/*");
        statement2.setResource(resources);
        minioPolicyStatements.add(statement);
        minioPolicyStatements.add(statement2);
        policy.setStatement(minioPolicyStatements);
        return new Gson().toJson(policy);
    }
}
ximon-admin/src/main/java/com/sandu/ximon/admin/minio/config/MinioPolicyStatement.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,17 @@
package com.sandu.ximon.admin.minio.config;
import lombok.Data;
import java.util.List;
@Data
public class MinioPolicyStatement {
    private String Effect;
    private MinioPolicyStatementPrincipal Principal;
    private List<String> Action;
    private List<String> Resource;
}
ximon-admin/src/main/java/com/sandu/ximon/admin/minio/config/MinioPolicyStatementPrincipal.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,11 @@
package com.sandu.ximon.admin.minio.config;
import lombok.Data;
import java.util.List;
@Data
public class MinioPolicyStatementPrincipal {
    private List<String> AWS;
}
ximon-admin/src/main/java/com/sandu/ximon/admin/minio/entity/FileSuffix.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,17 @@
package com.sandu.ximon.admin.minio.entity;
public enum FileSuffix {
    MP3("mp3"),
    ;
    FileSuffix(String suffix){
        this.suffix = suffix;
    }
    private String suffix;
    public String getSuffix() {
        return suffix;
    }
}
ximon-admin/src/main/java/com/sandu/ximon/admin/minio/entity/MinIoConstant.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,42 @@
package com.sandu.ximon.admin.minio.entity;
public enum MinIoConstant {
    //  log
    LOG("log",0),
    //  æµ‹è¯•文件桶
    TEST("test", 1),
    //  ä¸²å£æ–‡ä»¶æ¡¶å‰ç¼€
    MAIN_BOARD_REMOTE_UPDATE_FILE("remote-update.", 2),
    //  éŸ³æŸ±æ–‡ä»¶æ¡¶å‰ç¼€
    BROADCAST_FILE("ipvolume.", 3),
    //  ç®¡ç†å‘˜éŸ³æŸ±æ–‡ä»¶æ¡¶å‰ç¼€
    ADMIN_BROADCAST_FILE("adminipvolume", 3)
    ;
    MinIoConstant(String bucketName, Integer type){
        this.bucketName = bucketName;
        this.type = type;
    }
    private String bucketName;
    private Integer type;
    public String getBucketName() {
        return bucketName;
    }
    public Integer getType() {
        return type;
    }
    private static final String SERVER_ABSOLUTE_PATH = "D:/minio/minio/";
    public static String getAbsolutePath(MinIoConstant minIoConstant, String fileName) {
        return SERVER_ABSOLUTE_PATH + minIoConstant.getBucketName() + "/" + fileName;
    }
    public static String getAbsolutePath(String bucketName, String fileName) {
        return SERVER_ABSOLUTE_PATH + bucketName + "/" + fileName;
    }
}
ximon-admin/src/main/java/com/sandu/ximon/admin/minio/utils/MinIoUtil.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,497 @@
package com.sandu.ximon.admin.minio.utils;
import com.alibaba.fastjson.JSONObject;
import com.sandu.ximon.admin.config.VnnoxConstant;
import com.sandu.ximon.admin.minio.config.MinIoPolicy;
import com.sandu.ximon.admin.minio.entity.MinIoConstant;
import com.sandu.ximon.admin.utils.LogUtils;
import com.sandu.ximon.admin.utils.SpringContextUtils;
import io.minio.*;
import io.minio.errors.*;
import io.minio.messages.Bucket;
import io.minio.messages.DeleteError;
import io.minio.messages.Item;
import jdk.nashorn.internal.runtime.regexp.joni.exception.InternalException;
import lombok.SneakyThrows;
import org.apache.tomcat.util.http.fileupload.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
/**
 * è°ƒç”¨æœ¬å·¥å…·ç±»è¯·ä¿è¯bucketName不为空,不可在根目录添加文件
 */
@Component("MinIoUtil")
public class MinIoUtil {
    @Autowired
    private MinioClient minioClient;
    //  URL过期时间
    private static final Integer DEFAULT_EXPIRY_TIME = 60 * 60 * 24;
    public static MinIoUtil getMinIOUtil() {
        return (MinIoUtil) SpringContextUtils.getBean("MinIoUtil");
    }
    /**
     * èŽ·å–å­˜å‚¨æ¡¶ç­–ç•¥
     *
     * @param bucketName å­˜å‚¨æ¡¶åç§°
     * @return json
     */
    private JSONObject getBucketPolicy(String bucketName)
            throws IOException, InvalidKeyException, InvalidResponseException, BucketPolicyTooLargeException, NoSuchAlgorithmException, ServerException, InternalException, XmlParserException, InvalidBucketNameException, InsufficientDataException, ErrorResponseException, io.minio.errors.InternalException {
        String bucketPolicy = minioClient
                .getBucketPolicy(GetBucketPolicyArgs.builder().bucket(bucketName).build());
        return JSONObject.parseObject(bucketPolicy);
    }
    /**
     * è®¾ç½®å¼€æ”¾*的桶策略
     *
     * @param bucketName
     * @return
     */
    public void setBucketPolicy(String bucketName) throws Exception {
        minioClient.setBucketPolicy(
                SetBucketPolicyArgs.builder().bucket(bucketName).config(MinIoPolicy.generateMinioPolicy(bucketName)).build()
        );
    }
    /**
     * åˆ¤æ–­ bucket是否存在
     *
     * @param bucketName: æ¡¶å
     * @return: boolean
     */
    @SneakyThrows(Exception.class)
    public boolean bucketExists(String bucketName) {
        return minioClient.bucketExists(bucketName);
    }
    public boolean objectExists(String bucketName, String objectName) {
        try {
            getObjectInfo(bucketName, objectName);
        } catch (Exception e) {
            return false;
        }
        return true;
    }
    /**
     * åˆ›å»º bucket
     *
     * @param bucketName: æ¡¶å
     * @return: void
     */
    @SneakyThrows(Exception.class)
    public void createBucket(String bucketName) {
        boolean isExist = minioClient.bucketExists((BucketExistsArgs) ((io.minio.BucketExistsArgs.Builder) BucketExistsArgs.builder().bucket(bucketName)).build());
        if (!isExist) {
            minioClient.makeBucket((MakeBucketArgs) ((io.minio.MakeBucketArgs.Builder) MakeBucketArgs.builder().bucket(bucketName)).build());
        }
    }
    /**
     * èŽ·å–å…¨éƒ¨bucket
     */
    @SneakyThrows(Exception.class)
    public List<Bucket> getAllBuckets() {
        return minioClient.listBuckets();
    }
    /**
     * åˆ—出存储桶中的所有对象名称
     *
     * @param bucketName å­˜å‚¨æ¡¶åç§°
     * @return
     */
    @SneakyThrows
    public List<String> listObjectNames(String bucketName) {
        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
     */
    @SneakyThrows
    public Iterable<Result<Item>> listObjects(String bucketName) {
        boolean flag = bucketExists(bucketName);
        if (flag) {
            return minioClient.listObjects(bucketName);
        }
        return null;
    }
    /**
     * æ–‡ä»¶ä¸Šä¼ 
     *
     * @param bucketName: æ¡¶å
     * @param fileName:   æ–‡ä»¶å
     * @param filePath:   æ–‡ä»¶è·¯å¾„
     * @return: void
     */
    @SneakyThrows(Exception.class)
    public void uploadToMinIo(String bucketName, String fileName, String filePath) {
        if (!bucketExists(bucketName)) {
            createBucket(bucketName);
            LogUtils.print("创建桶:" + bucketName);
        }
//        log.log(new LogRecordEntity(
//                "服务器文件上传:(bucket)"+bucketName +", (fileName)"+fileName+",(filePath)"+filePath,
//                LogType.MINIO_SERVER,
//                getNUserId(),
//                this.getClass()
//        ));
        try {
            //  åˆ¤æ–­æ–‡ä»¶æ˜¯å¦å­˜åœ¨
            if (!objectExists(bucketName, fileName)) {
                minioClient.putObject(bucketName, fileName, filePath, null);
            } else {
//                log.log(new LogRecordEntity(
//                        "服务器文件已存在,请勿重复上传:(bucket)"+bucketName +", (fileName)"+fileName,
//                        LogType.MINIO_SERVER,
//                        getNUserId(),
//                        this.getClass()
//                ));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    /**
     * æ–‡ä»¶ä¸Šä¼ 
     *
     * @param bucketName: æ¡¶å
     * @param fileName:   æ–‡ä»¶å
     * @param stream:     æ–‡ä»¶æµ
     * @return: æ–‡ä»¶url地址
     */
    public String upload(String bucketName, String fileName, InputStream stream) {
        if (!bucketExists(bucketName)) {
            createBucket(bucketName);
            LogUtils.print("创建桶:" + bucketName);
        }
        try {
            //  åˆ¤æ–­æ–‡ä»¶æ˜¯å¦å­˜åœ¨
            if (!objectExists(bucketName, fileName)) {
                minioClient.putObject(bucketName, fileName, stream, new PutObjectOptions(stream.available(), -1));
            } else {
                return null;
            }
        } catch (Exception e) {
            return null;
        }
        return getFileUrl(bucketName, fileName);
    }
    /**
     * åˆ—出所有存储桶名称
     *
     * @return
     */
    @SneakyThrows
    public List<String> listBucketNames() {
        List<Bucket> bucketList = getAllBuckets();
        List<String> bucketListName = new ArrayList<>();
        for (Bucket bucket : bucketList) {
            bucketListName.add(bucket.name());
        }
        return bucketListName;
    }
    /**
     * æ–‡ä»¶ä¸Šä¼ 
     *
     * @param bucketName: æ¡¶å
     * @param file:       æ–‡ä»¶
     * @return: æ–‡ä»¶url地址
     */
    @SneakyThrows(Exception.class)
    public String upload(String bucketName, MultipartFile file) {
        if (!bucketExists(bucketName)) {
            createBucket(bucketName);
            LogUtils.print("创建桶:" + bucketName);
            if (bucketName.indexOf(VnnoxConstant.MINIO_PREFIX) != -1) {
                setBucketPolicy(bucketName);
            }
        }
        final InputStream is = file.getInputStream();
        final String fileName = file.getOriginalFilename();
        Long start = System.currentTimeMillis();
        minioClient.putObject(bucketName, fileName, is, new PutObjectOptions(is.available(), -1));
        is.close();
        LogUtils.error("上传总时间:" + (System.currentTimeMillis() - start) + "ms");
        return getFileUrl(bucketName, fileName);
    }
    /**
     * åˆ é™¤æ–‡ä»¶
     *
     * @param bucketName: æ¡¶å
     * @param fileName:   æ–‡ä»¶å
     * @return: void
     * @date : 2020/8/16 20:53
     */
    @SneakyThrows(Exception.class)
    public boolean deleteFile(String bucketName, String fileName) {
        //  åˆ¤æ–­æ–‡ä»¶æ˜¯å¦å­˜åœ¨
        if (objectExists(bucketName, fileName)) {
//            log.log(new LogRecordEntity(
//                    "服务器文件删除:(bucket)"+bucketName +", (fileName)"+fileName,
//                    LogType.MINIO_SERVER,
//                    getNUserId(),
//                    this.getClass()
//            ));
            minioClient.removeObject(bucketName, fileName);
            if (!objectExists(bucketName, fileName)) {
                return true;
            } else {
                return false;
            }
        } else {
//            log.log(new LogRecordEntity(
//                    "服务器文件不存在,无法删除:(bucket)"+bucketName +", (fileName)"+fileName,
//                    LogType.MINIO_SERVER,
//                    getNUserId(),
//                    this.getClass()
//            ));
            return false;
        }
    }
    /**
     * åˆ é™¤æŒ‡å®šæ¡¶çš„多个文件对象,返回删除错误的对象列表,全部删除成功,返回空列表
     *
     * @param bucketName  å­˜å‚¨æ¡¶åç§°
     * @param objectNames å«æœ‰è¦åˆ é™¤çš„多个object名称的迭代器对象
     * @return
     */
    @SneakyThrows
    public List<String> removeObject(String bucketName, List<String> objectNames) {
        List<String> deleteErrorNames = new ArrayList<>();
        boolean flag = bucketExists(bucketName);
        if (flag) {
            Iterable<Result<DeleteError>> results = minioClient.removeObjects(bucketName, objectNames);
            for (Result<DeleteError> result : results) {
                DeleteError error = result.get();
                deleteErrorNames.add(error.objectName());
            }
        }
//        log.log(new LogRecordEntity(
//                "服务器文件批量删除:(bucket)"+bucketName +", (fileName)"+ JSON.toJSONString(objectNames)+", åˆ é™¤å¤±è´¥æ–‡ä»¶ï¼š"+JSON.toJSONString(deleteErrorNames),
//                LogType.MINIO_SERVER,
//                getNUserId(),
//                this.getClass()
//        ));
        return deleteErrorNames;
    }
    /**
     * ä¸‹è½½æ–‡ä»¶
     *
     * @param bucketName: æ¡¶å
     * @param fileName:   æ–‡ä»¶å
     * @param response:
     * @return: void
     * @date : 2020/8/17 0:34
     */
    @SneakyThrows(Exception.class)
    public HttpServletResponse download(String bucketName, String fileName, HttpServletResponse response) {
        // èŽ·å–å¯¹è±¡çš„å…ƒæ•°æ®
        final ObjectStat stat = minioClient.statObject(bucketName, fileName);
        response.setContentType(stat.contentType());
        response.setCharacterEncoding("UTF-8");
        response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
        InputStream is = minioClient.getObject(bucketName, fileName);
        IOUtils.copy(is, response.getOutputStream());
        is.close();
        return response;
    }
    /**
     * èŽ·å–MinIo文件的永久下载地址
     *
     * @param bucketName: æ¡¶å
     * @param fileName:   æ–‡ä»¶å
     * @return:
     */
    @SneakyThrows(Exception.class)
    public String getFileUrl(String bucketName, String fileName) {
//        log.log(new LogRecordEntity(
//                "服务器文件获取永久下载地址:(bucketName)"+bucketName+", (fileName)"+fileName,
//                LogType.MINIO_SERVER,
//                getNUserId(),
//                this.getClass()
//        ));
        return minioClient.presignedGetObject(bucketName, fileName);
    }
    /**
     * ç”Ÿæˆä¸€ä¸ªç»™HTTP GET请求用的presigned URL。
     * æµè§ˆå™¨/移动端的客户端可以用这个URL进行下载,即使其所在的存储桶是私有的。这个presigned URL可以设置一个失效时间,默认值是7天。
     *
     * @param bucketName å­˜å‚¨æ¡¶åç§°
     * @param objectName å­˜å‚¨æ¡¶é‡Œçš„对象名称
     * @param expires    å¤±æ•ˆæ—¶é—´ï¼ˆä»¥ç§’为单位
     * @return
     */
    @SneakyThrows
    public String presignedGetObject(String bucketName, String objectName, Integer expires) {
        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);
            }
            url = minioClient.presignedGetObject(bucketName, objectName, expires);
        }
//        log.log(new LogRecordEntity(
//                "服务器文件获取文件定时下载地址(get:"+expires+"s):(bucketName)"+bucketName+", (fileName)"+objectName,
//                LogType.MINIO_SERVER,
//                getNUserId(),
//                this.getClass()
//        ));
        return url;
    }
    /**
     * ç”Ÿæˆä¸€ä¸ªç»™HTTP PUT请求用的presigned URL。
     * æµè§ˆå™¨/移动端的客户端可以用这个URL进行上传,即使其所在的存储桶是私有的。这个presigned URL可以设置一个失效时间,默认值是7天。
     *
     * @param bucketName å­˜å‚¨æ¡¶åç§°
     * @param objectName å­˜å‚¨æ¡¶é‡Œçš„对象名称
     * @param expires    å¤±æ•ˆæ—¶é—´ï¼ˆä»¥ç§’为单位
     * @return
     */
    @SneakyThrows
    public String presignedPutObject(String bucketName, String objectName, Integer expires) {
        boolean flag = bucketExists(bucketName);
        String url = "";
        if (flag) {
            if (expires < 10 || expires > DEFAULT_EXPIRY_TIME) {
                throw new InvalidExpiresRangeException(expires,
                        "expires must be in range of 1 to " + DEFAULT_EXPIRY_TIME);
            }
            url = minioClient.presignedPutObject(bucketName, objectName, expires);
        }
//        log.log(new LogRecordEntity(
//                "服务器文件获取文件定时下载地址(put:"+expires+"s):(bucketName)"+bucketName+", (fileName)"+objectName,
//                LogType.MINIO_SERVER,
//                getNUserId(),
//                this.getClass()
//        ));
        return url;
    }
    /**
     * æ ¹æ®æ–‡ä»¶å‰ç½®æŸ¥è¯¢æ–‡ä»¶
     *
     * @param bucketName bucket名称
     * @param prefix     å‰ç¼€
     * @param recursive  æ˜¯å¦é€’归查询
     * @return MinioItem åˆ—表
     */
    @SneakyThrows
    public List getAllObjectsByPrefix(String bucketName, String prefix, boolean recursive) {
        List<Item> list = new ArrayList<>();
        Iterable<Result<Item>> objectsIterator = minioClient.listObjects(bucketName, prefix, recursive);
        if (objectsIterator != null) {
            Iterator<Result<Item>> iterator = objectsIterator.iterator();
            if (iterator != null) {
                while (iterator.hasNext()) {
                    Result<Item> result = iterator.next();
                    Item item = result.get();
                    list.add(item);
                }
            }
        }
        return list;
    }
    /**
     * èŽ·å–æ–‡ä»¶
     *
     * @param bucketName bucket名称
     * @param objectName æ–‡ä»¶åç§°
     * @return äºŒè¿›åˆ¶æµ
     */
    @SneakyThrows
    public InputStream getObject(String bucketName, String objectName) {
        return minioClient.getObject(bucketName, objectName);
    }
    /**
     * èŽ·å–æ–‡ä»¶ä¿¡æ¯, å¦‚果抛出异常则说明文件不存在
     *
     * @param bucketName bucket名称
     * @param objectName æ–‡ä»¶åç§°
     * @throws Exception https://docs.minio.io/cn/java-client-api-reference.html#statObject
     */
    public ObjectStat getObjectInfo(String bucketName, String objectName) throws Exception {
        ObjectStat objectStat = minioClient.statObject(bucketName, objectName);
        return objectStat;
    }
    /**
     * èŽ·å–æ–‡ä»¶ç»å¯¹è·¯å¾„
     *
     * @param bucketName
     * @param objectName
     * @return
     */
    public String getAbsolutePath(String bucketName, String objectName) {
        try {
            getObjectInfo(bucketName, objectName);
        } catch (Exception e) {
            return null;
        }
        return MinIoConstant.getAbsolutePath(bucketName, objectName);
    }
}
ximon-admin/src/main/java/com/sandu/ximon/admin/service/IpVolumeFileService.java
@@ -4,25 +4,33 @@
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.pagehelper.PageHelper;
import com.sandu.common.execption.BusinessException;
import com.sandu.common.file.FileUploadDto;
import com.sandu.common.object.BaseConditionVO;
import com.sandu.common.service.impl.BaseServiceImpl;
import com.sandu.ximon.admin.minio.BroadcastFileUtils;
import com.sandu.ximon.admin.minio.entity.FileSuffix;
import com.sandu.ximon.admin.minio.entity.MinIoConstant;
import com.sandu.ximon.admin.minio.utils.MinIoUtil;
import com.sandu.ximon.admin.param.IpVolumeFileParam;
import com.sandu.ximon.admin.security.SecurityUtils;
import com.sandu.ximon.dao.domain.IpVolumeFile;
import com.sandu.ximon.dao.mapper.IpVolumeFileMapper;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
/**
 * @Author liuhaonan
 * @Date 2021/12/16 10:48
 * @Version 1.0
 */
@Service
@AllArgsConstructor
public class IpVolumeFileService extends BaseServiceImpl<IpVolumeFileMapper, IpVolumeFile> {
    private final IpVolumeFileMapper ipVolumeFileMapper;
    private final ClientService clientService;
    private MinIoUtil minIoUtil;
    public boolean addFile(IpVolumeFileParam fileParam) {
@@ -31,14 +39,12 @@
//            file.setUserName(SecurityUtils.getUsername());
//        }
//
        if(SecurityUtils.getClientId()!=null){
        if (SecurityUtils.getClientId() != null) {
            file.setUserName(SecurityUtils.getUsername());
            file.setUserId(SecurityUtils.getClientId());
        }
        if(clientService.getClientId()!=null){
            file.setClientId(clientService.getClientId());
        }
        file.setFileName(fileParam.getFileName());
        file.setFileUrl(fileParam.getFileUrl());
        file.setOriginSize(fileParam.getOriginSize());
@@ -59,28 +65,50 @@
        if (keyword.isEmpty()) {
            return wrapper;
        } else {
          return   wrapper.like(IpVolumeFile::getFileName,keyword);
            return wrapper.like(IpVolumeFile::getFileName, keyword);
        }
    }
    public boolean upload(IpVolumeFileParam fileParam) {
        IpVolumeFile file = new IpVolumeFile();
//        if(SecurityUtils.getClientId()!=null){
//            file.setUserName(SecurityUtils.getUsername());
//        }
//
        if(SecurityUtils.getClientId()!=null){
            file.setUserName(SecurityUtils.getUsername());
            file.setUserId(SecurityUtils.getClientId());
    /**
     * æ–‡ä»¶ä¸Šä¼ 
     *
     * @param file
     * @param userId
     * @return
     */
    public FileUploadDto upload(MultipartFile file) {
        log.error("音柱文件上传:(filename:" + file.getOriginalFilename() + "),(size: " + file.getSize() + "),用户id:" + SecurityUtils.getUserId());
        //  æ ¡éªŒæ˜¯å¦ä¸ºmp3文件
        if (!BroadcastFileUtils.isMp3File(file.getOriginalFilename(), FileSuffix.MP3)) {
            log.error("音柱文件上传:(上传失败, éžMP3文件) (filename:" + file.getOriginalFilename() + "),(size: " + file.getSize() + "),用户id:" + SecurityUtils.getUserId());
            throw new BusinessException("上传失败, éžMP3文件");
        }
        //  åˆ¤æ–­è¯¥æ–‡ä»¶æ˜¯å¦å­˜åœ¨
        String bucketName;
        if (SecurityUtils.getClientId() == null) {
            bucketName = MinIoConstant.ADMIN_BROADCAST_FILE.getBucketName();
        } else {
            bucketName = MinIoConstant.BROADCAST_FILE.getBucketName() + SecurityUtils.getUserId();
        }
        if (minIoUtil.objectExists(bucketName, file.getOriginalFilename())) {
            log.error("音柱文件上传:(上传失败, åŒåæ–‡ä»¶å·²å­˜åœ¨) (filename:" + file.getOriginalFilename() + "),(size: " + file.getSize() + "),用户id:" + SecurityUtils.getUserId());
            throw new BusinessException("上传失败, åŒåæ–‡ä»¶å·²å­˜åœ¨");
        }
        if(clientService.getClientId()!=null){
            file.setClientId(clientService.getClientId());
        String upload = minIoUtil.upload(bucketName, file);
        if (null == upload) {
            log.error("音柱文件上传:(上传失败, æ–‡ä»¶æœåŠ¡å™¨å‡ºé”™) (filename:" + file.getOriginalFilename() + "),(size: " + file.getSize() + "),用户id:" + SecurityUtils.getUserId());
            throw new BusinessException("上传失败, æ–‡ä»¶æœåŠ¡å™¨å‡ºé”™");
        }
        file.setFileName(fileParam.getFileName());
        file.setFileUrl(fileParam.getFileUrl());
        file.setOriginSize(fileParam.getOriginSize());
        return save(file);
        FileUploadDto fileUploadDto = new FileUploadDto();
        fileUploadDto.setFileUrl(upload);
        fileUploadDto.setFileSize(file.getSize());
        fileUploadDto.setFileName(file.getOriginalFilename());
        fileUploadDto.setFileType(file.getContentType());
        return fileUploadDto;
    }
}
ximon-admin/src/main/java/com/sandu/ximon/admin/service/IpVolumeMissionService.java
@@ -7,6 +7,7 @@
import com.sandu.common.execption.BusinessException;
import com.sandu.common.object.BaseConditionVO;
import com.sandu.common.service.impl.BaseServiceImpl;
import com.sandu.ximon.admin.minio.entity.MinIoConstant;
import com.sandu.ximon.admin.param.IpVolumeMissionParam;
import com.sandu.ximon.admin.security.SecurityUtils;
import com.sandu.ximon.admin.utils.TaskAPIUtils;
@@ -95,15 +96,24 @@
            if (fileEntity == null) {
                throw new BusinessException("fileId为" + fileId + "的文件不存在");
            }
//            String absolutePath = MinIoConstant.getAbsolutePath(
//                    MinIoConstant.BROADCAST_FILE.getBucketName() + fileEntity.getUserId(),
//                    fileEntity.getFileName()
//            );
            if(fileEntity.getUserId()==null&&fileEntity.getClientId()!=null){
                fileEntity.setUserId(fileEntity.getClientId());
            }
            String absolutePath;
            absolutePath = MinIoConstant.getAbsolutePath(
                    MinIoConstant.BROADCAST_FILE.getBucketName() + fileEntity.getUserId(),
                    fileEntity.getFileName()
            );
            if(fileEntity.getUserId()==null&&fileEntity.getClientId()==null){
                absolutePath = MinIoConstant.getAbsolutePath(
                        MinIoConstant.ADMIN_BROADCAST_FILE.getBucketName(),
                        fileEntity.getFileName()
                );
            }
            taskMediaFileVO.setI(i);
            i++;
            taskMediaFileVO.setT(0);
            taskMediaFileVO.setN(fileEntity.getFileUrl());
            taskMediaFileVO.setN(absolutePath);
            taskMediaFileVO.setS(BigInteger.valueOf(fileEntity.getOriginSize()));
            taskMediaFileVOS.add(taskMediaFileVO);
@@ -214,15 +224,15 @@
            taskFileEntity.setFileId(fileId);
            IpVolumeFile fileEntity = ipVolumeFileService.getById(fileId);
//            String absolutePath = MinIoConstant.getAbsolutePath(
//                    MinIoConstant.BROADCAST_FILE.getBucketName() + fileEntity.getUserId(),
//                    fileEntity.getFileName()
//            );
            String absolutePath = MinIoConstant.getAbsolutePath(
                    MinIoConstant.BROADCAST_FILE.getBucketName() + fileEntity.getUserId(),
                    fileEntity.getFileName()
            );
            taskMediaFileVO.setI(i);
            i++;
            taskMediaFileVO.setT(0);
            taskMediaFileVO.setN(fileEntity.getFileUrl());
            taskMediaFileVO.setN(absolutePath);
            taskMediaFileVO.setS(BigInteger.valueOf(fileEntity.getOriginSize()));
            taskMediaFileVOS.add(taskMediaFileVO);
ximon-admin/src/main/resources/application-dev.yml
@@ -39,4 +39,10 @@
listenter:
  isOpen: false
minio:
  endpoint: 47.106.172.9
  port: 9000
  accessKey: minioadmin
  secretKey: zhxm2512209
  secure: false
ximon-admin/src/main/resources/application-test.yml
@@ -32,7 +32,7 @@
    upload-root-path: /usr/local/project/ximon-light-20017/file/
    storage: local
  common:
    urlPrefix: http://112.74.63.130/file/
    urlPrefix: http://112.74.63.130:20017/file/
  quartz:
    enable: true
@@ -40,4 +40,10 @@
  isOpen: false
minio:
  endpoint: 47.106.172.9
  port: 9000
  accessKey: minioadmin
  secretKey: zhxm2512209
  secure: false
ximon-admin/src/main/resources/application.yml
@@ -51,4 +51,10 @@
  ip: 47.106.172.9 # 47.106.172.9/101.132.131.91
minio:
  endpoint: 47.106.172.9
  port: 9000
  accessKey: minioadmin
  secretKey: zhxm2512209
  secure: false