package com.keystar.plane.inspection.service.impl; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.map.MapUtil; import cn.hutool.core.text.CharSequenceUtil; import cn.hutool.core.util.StrUtil; import com.alibaba.fastjson.JSONObject; import com.keystar.plane.inspection.config.MinIoConfig; import com.keystar.plane.inspection.utils.FileUtil; import com.keystar.plane.inspection.vo.UploadVo; import io.minio.MinioClient; import io.minio.Result; import io.minio.errors.*; import io.minio.messages.Item; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.cloud.context.config.annotation.RefreshScope; import org.springframework.stereotype.Service; import org.springframework.web.bind.annotation.GetMapping; import org.xmlpull.v1.XmlPullParserException; import javax.annotation.Resource; import javax.servlet.http.HttpServletResponse; import javax.validation.Valid; import javax.validation.constraints.NotNull; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.URLEncoder; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.stream.Collectors; @Service @Slf4j @RefreshScope public class MinioService { @Resource private MinioClient minioClient; @Autowired private MinIoConfig minIoConfig; @Value("${report.bucket}") private String bucket; /** * 判断 bucket是否存在 * @param bucketName * @return */ public boolean bucketExists(String bucketName){ try { return minioClient.bucketExists(bucketName); } catch (Exception e) { log.error("判断 bucket是否存在,出现错误:{}",e); return false; } } /** * 根据 bucket 获取该桶下边的所有目录 * @param bucketName */ public List listObject(String bucketName){ try { Iterable> myObjects = minioClient.listObjects(bucketName); return getItems(myObjects); } catch (Exception e) { log.error("获取桶{}的文件内容,出现错误:{}",bucketName,e); return null; } } private List getItems(Iterable> myObjects) throws InvalidBucketNameException, NoSuchAlgorithmException, InsufficientDataException, IOException, InvalidKeyException, NoResponseException, XmlPullParserException, ErrorResponseException, InternalException { List items = CollUtil.newArrayList(); for (Result result : myObjects) { items.add(result.get()); } return items; } /** * 获取文件流 * @param bucketName * @param objectName * @return */ public InputStream getObject(String bucketName, String objectName) { try { return minioClient.getObject(bucketName,objectName); } catch (Exception e) { log.error("获取桶{}的{}文件内容,出现错误:{}",bucketName,objectName,e); } return null; } /*** * 根据 bucket 和 prefix 获取该所有目录和文件 * @param bucketName * @param prefix * @param recursive * @param useVersion1 * @return */ public List listObject(String bucketName,String prefix, boolean recursive, boolean useVersion1){ try { Iterable> myObjects = minioClient.listObjects(bucketName,prefix,recursive,useVersion1); return getItems(myObjects); } catch (Exception e) { log.error("获取桶{}的文件内容,出现错误:{}",bucketName,e); return null; } } /** * 获取最新架次的红外图片地址 **/ public List getInfraredPhoto(){ List infraredList = new ArrayList<>(); // 获取最新航线 List missions = this.listObject(minIoConfig.getBucketName(), minIoConfig.getResourcePath(), false, false); String missionId = missions.get(missions.size()-1).objectName(); // 获取最新架次 List records = this.listObject(minIoConfig.getBucketName(), missionId, false, false); String recordsId = records.get(records.size()-1).objectName(); // 获取红外图片 List photos = this.listObject(minIoConfig.getBucketName(), recordsId, false, false); List photoList = photos.stream().map(Item::objectName).collect(Collectors.toList()); for ( String name : photoList){ if (name.contains("THRM.jpg") || name.contains("T.jpg")){ infraredList.add(name); } } return infraredList; } /** * 文件上传 */ public void putObject(String bucketName, String objectName, InputStream stream,String contentType) { if (!bucketExists(bucketName)){ log.error("bucket不存在"); } try { minioClient.putObject(bucketName,objectName,stream,contentType); } catch (Exception e) { log.error("上传文件{}到桶{},出现错误:{}",objectName,bucketName,e); } } public void upload(@Valid UploadVo uploadVo) { log.info("上传图片信息,fileSize:{},fileName:{}", uploadVo.getFile().getSize(), uploadVo.getFile().getOriginalFilename()); if (StrUtil.isEmpty(uploadVo.getResourceName())){ uploadVo.setResourceName(uploadVo.getFile().getOriginalFilename()); } try { this.putObject(uploadVo.getBucketName(),uploadVo.getPath(),uploadVo.getFile().getInputStream(),uploadVo.getFile().getContentType()); }catch (IOException ioe){ log.error("获取图片流失败:{}",ioe); } } /** * 下载文件 */ public String download(String resourceFullName, HttpServletResponse response) throws IOException { OutputStream outputStream = response.getOutputStream(); // 拿到文件路径 String[] strings = StrUtil.splitToArray(resourceFullName, "/"); String url = strings[1]; // 获取文件对象 InputStream inputStream = this.getObject(url, StrUtil.sub(resourceFullName, CharSequenceUtil.length(strings[1])+2, CharSequenceUtil.length(resourceFullName))); try { response.reset(); response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(resourceFullName.substring(resourceFullName.lastIndexOf("/") + 1), "UTF-8")); response.setContentType("application/octet-stream"); response.setCharacterEncoding("UTF-8"); // 输出文件 outputStream.write(FileUtil.readInputStream(inputStream)); outputStream.flush(); } catch (Exception ex) { log.error("下载文件:{}",ex); return "下载文件失败"; }finally { // 关闭输出流 outputStream.close(); } return "下载文件成功"; } /** * 获取最新的巡检报告的地址 **/ public String getReportPath(){ // 获取bucket中的报告地址 List dateList = this.listObject(bucket); String date = dateList.get(dateList.size()-1).objectName(); // 拼接地址 return "/" + bucket + "/" + date; } }