/* * Copyright (c) 2018-2028, Chill Zhuang All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * Neither the name of the dreamlu.net developer nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * Author: Chill 庄骞 (smallchill@163.com) */ package cn.gistack.resource.endpoint; import cn.gistack.resource.builder.oss.OssBuilder; import cn.gistack.resource.entity.TextualResearchAttach; import cn.gistack.resource.panoramaUtils.Img4JavaUtil; import cn.gistack.resource.panoramaUtils.QietuResult; import cn.gistack.resource.service.IAttachService; import cn.gistack.resource.service.TextualResearchAttachService; import io.swagger.annotations.Api; import lombok.AllArgsConstructor; import lombok.SneakyThrows; import org.apache.commons.io.FileUtils; import org.springblade.core.oss.model.BladeFile; import org.springblade.core.oss.model.OssFile; import org.springblade.core.secure.annotation.PreAuth; import org.springblade.core.tenant.annotation.NonDS; import org.springblade.core.tool.api.R; import org.springblade.core.tool.constant.RoleConstant; import org.springblade.core.tool.utils.FileUtil; import org.springblade.core.tool.utils.Func; import cn.gistack.resource.entity.Attach; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; import java.io.File; import java.io.FileInputStream; import java.nio.file.Path; import java.nio.file.Paths; import java.util.*; /** * 对象存储端点 * * @author Chill */ @NonDS @RestController @AllArgsConstructor @RequestMapping("/oss/endpoint") @Api(value = "对象存储端点", tags = "对象存储端点") public class OssEndpoint { /** * 对象存储构建类 */ private final OssBuilder ossBuilder; /** * 附件表服务 */ private final IAttachService attachService; /** * 附件表服务 */ private final TextualResearchAttachService textualResearchAttachService; /** * 创建存储桶 * * @param bucketName 存储桶名称 * @return Bucket */ @SneakyThrows @PostMapping("/make-bucket") @PreAuth(RoleConstant.HAS_ROLE_ADMIN) public R makeBucket(@RequestParam String bucketName) { ossBuilder.template().makeBucket(bucketName); return R.success("创建成功"); } /** * 创建存储桶 * * @param bucketName 存储桶名称 * @return R */ @SneakyThrows @PostMapping("/remove-bucket") @PreAuth(RoleConstant.HAS_ROLE_ADMIN) public R removeBucket(@RequestParam String bucketName) { ossBuilder.template().removeBucket(bucketName); return R.success("删除成功"); } /** * 拷贝文件 * * @param fileName 存储桶对象名称 * @param destBucketName 目标存储桶名称 * @param destFileName 目标存储桶对象名称 * @return R */ @SneakyThrows @PostMapping("/copy-file") public R copyFile(@RequestParam String fileName, @RequestParam String destBucketName, String destFileName) { ossBuilder.template().copyFile(fileName, destBucketName, destFileName); return R.success("操作成功"); } /** * 获取文件信息 * * @param fileName 存储桶对象名称 * @return InputStream */ @SneakyThrows @GetMapping("/stat-file") public R statFile(@RequestParam String fileName) { return R.data(ossBuilder.template().statFile(fileName)); } /** * 获取文件相对路径 * * @param fileName 存储桶对象名称 * @return String */ @SneakyThrows @GetMapping("/file-path") public R filePath(@RequestParam String fileName) { return R.data(ossBuilder.template().filePath(fileName)); } /** * 获取文件外链 * * @param fileName 存储桶对象名称 * @return String */ @SneakyThrows @GetMapping("/file-link") public R fileLink(@RequestParam String fileName) { return R.data(ossBuilder.template().fileLink(fileName)); } /** * 上传文件 * * @param file 文件 * @return ObjectStat */ @SneakyThrows @PostMapping("/put-file") public R putFile(@RequestParam MultipartFile file) { BladeFile bladeFile = ossBuilder.template().putFile(file.getOriginalFilename(), file.getInputStream()); return R.data(bladeFile); } /** * 自定义前缀上传文件 * * @param file 文件 * @param prefixPath 文件 * @return ObjectStat */ @SneakyThrows @PostMapping("/put-file-by-prefix-path") public R putFileByPrefixPath(@RequestParam MultipartFile file,@RequestParam String prefixPath) { BladeFile bladeFile = ossBuilder.templateByPrefixPath(prefixPath).putFile(file.getOriginalFilename(), file.getInputStream()); return R.data(bladeFile); } /** * 批量自定义前缀上传文件 * * @param files 文件 * @param prefixPath 文件 * @return ObjectStat */ @SneakyThrows @PostMapping("/batch-put-file-by-prefix-path") public R batchPutFileByPrefixPath(@RequestParam MultipartFile[] files,@RequestParam String prefixPath) { List list = new ArrayList<>(); for (MultipartFile file : files) { BladeFile bladeFile = ossBuilder.templateByPrefixPath(prefixPath).putFile(file.getOriginalFilename(), file.getInputStream()); list.add(bladeFile); } return R.data(list); } /** * 考证附件上传并保存 * @param file 文件 * @param resGuid 水库编号 * @return */ @SneakyThrows @PostMapping("/put-file-by-textualResearchAttach") public R putFileByPrefixTextualResearchAttach(@RequestParam MultipartFile file,String resGuid,Integer type) { BladeFile bladeFile = ossBuilder.templateByPrefixPath("textualResearchAttach").putFile(file.getOriginalFilename(), file.getInputStream()); buildTextualResearchAttach(resGuid,bladeFile,type); return R.data(bladeFile); } /** * 全景图片上传,并切图 * @param multipartFile 文件 * @param resGuid 水库编号 * @return */ @SneakyThrows @PostMapping("/put-file-by-panorama") public R putFileByPanorama(@RequestParam MultipartFile multipartFile, String resGuid) { // 临时文件路径 String linShiBaseUrl = "/data/panorama/qietu/"; // String fileName = multipartFile.getOriginalFilename(); // 获取文件名 String picName = multipartFile.getOriginalFilename();// 原始全景图名称 String dirPath = linShiBaseUrl + resGuid + "/"; //临时文件夹路径 File dir = new File(dirPath); if (dir.isDirectory()) { // 清除该目录下的文件及子目录文件而不删除该目录文件夹。该目录不存在会报错 FileUtils.cleanDirectory(dir); } else { dir.mkdirs(); } String picUrl = dirPath + picName; // 原始全景图文件路径 File file = new File(picUrl); // 文件上传的原始全景图,存入临时路径 multipartFile.transferTo(file); FileInputStream ysfileInputStream = new FileInputStream(file); BladeFile qjbladeFile = ossBuilder.templateByPrefixPathPanorama("panorama", resGuid).putFile(picName, ysfileInputStream); String yuanshiQJurl = qjbladeFile.getLink(); ysfileInputStream.close(); /** * 这里开始切图 */ HashMap qietuHashMap = new HashMap(); int col = 8; int row = 4; String[] split = picName.split("\\."); String picHeadName = split[0]; String picLastName = split[1]; // 获取原始全景图图片信息 HashMap imgInfoRT = Img4JavaUtil.getImgInfoRT(file); Integer width = imgInfoRT.get("width"); Integer height = imgInfoRT.get("height"); // 计算切成小图的长和宽 Integer biliWidth = width/col; Integer biliHeight = height/row; for (int i=0 ; i < col ; i++) { // 计算图片的横坐标(长边) int x = i * biliWidth; for (int j=0 ; j qieTuUrlList = new ArrayList(); String urlHead = null; Set mapKey = qietuHashMap.keySet(); if(qietuHashMap != null && qietuHashMap.size()>0) { for (String picQName : mapKey) { String url = qietuHashMap.get(picQName); Path qietuPath = Paths.get(url); File qietufile = qietuPath.toFile(); FileInputStream fileInputStream = new FileInputStream(qietufile); BladeFile bladeFile = ossBuilder.templateByPrefixPathPanorama("panorama", resGuid).putFile(picQName, fileInputStream); fileInputStream.close(); // 关闭文件流 // 切图上传完成后删除 if (qietufile.exists()) { // 删除指定文件,不存在报异常 FileUtils.forceDelete(qietufile); } String link = bladeFile.getLink(); qieTuUrlList.add(link);// 上传后的图片路径 urlHead = link.replace(picQName,""); } } QietuResult qietuResult = new QietuResult(); qietuResult.setQieTuUrlList(qieTuUrlList); qietuResult.setUrlHead(urlHead); qietuResult.setRow(row); qietuResult.setCol(col); qietuResult.setQuanJingWidth(width); qietuResult.setQuanJingHeight(height); qietuResult.setQjName(picName); qietuResult.setQjUrl(yuanshiQJurl); return R.data(qietuResult) ; } @SneakyThrows @PostMapping("/put-file-by-panorama2") public R putFileByPanorama2(@RequestParam MultipartFile multipartFile, String resGuid){ return null; } /** * 保存考证附件上传数据 * @param bladeFile */ private void buildTextualResearchAttach(String resGuid,BladeFile bladeFile,Integer type) { TextualResearchAttach attach = new TextualResearchAttach(); attach.setResGuid(resGuid); attach.setType(type); attach.setPath(bladeFile.getName()); attach.setName(bladeFile.getOriginalName()); attach.setCreateTime(new Date()); // 保存 textualResearchAttachService.save(attach); } /** * 上传文件 * * @param fileName 存储桶对象名称 * @param file 文件 * @return ObjectStat */ @SneakyThrows @PostMapping("/put-file-by-name") public R putFile(@RequestParam String fileName, @RequestParam MultipartFile file) { BladeFile bladeFile = ossBuilder.template().putFile(fileName, file.getInputStream()); return R.data(bladeFile); } /** * 上传文件并保存至附件表 * * @param file 文件 * @return ObjectStat */ @SneakyThrows @PostMapping("/put-file-attach") public R putFileAttach(@RequestParam MultipartFile file) { String fileName = file.getOriginalFilename(); BladeFile bladeFile = ossBuilder.template().putFile(fileName, file.getInputStream()); Long attachId = buildAttach(fileName, file.getSize(), bladeFile); bladeFile.setAttachId(attachId); return R.data(bladeFile); } /** * 上传文件并保存至附件表 * * @param fileName 存储桶对象名称 * @param file 文件 * @return ObjectStat */ @SneakyThrows @PostMapping("/put-file-attach-by-name") public R putFileAttach(@RequestParam String fileName, @RequestParam MultipartFile file) { BladeFile bladeFile = ossBuilder.template().putFile(fileName, file.getInputStream()); Long attachId = buildAttach(fileName, file.getSize(), bladeFile); bladeFile.setAttachId(attachId); return R.data(bladeFile); } /** * 构建附件表 * * @param fileName 文件名 * @param fileSize 文件大小 * @param bladeFile 对象存储文件 * @return attachId */ private Long buildAttach(String fileName, Long fileSize, BladeFile bladeFile) { String fileExtension = FileUtil.getFileExtension(fileName); Attach attach = new Attach(); attach.setDomainUrl(bladeFile.getDomain()); attach.setLink(bladeFile.getLink()); attach.setName(bladeFile.getName()); attach.setOriginalName(bladeFile.getOriginalName()); attach.setAttachSize(fileSize); attach.setExtension(fileExtension); attachService.save(attach); return attach.getId(); } /** * 删除文件 * * @param fileName 存储桶对象名称 * @return R */ @SneakyThrows @PostMapping("/remove-file") @PreAuth(RoleConstant.HAS_ROLE_ADMIN) public R removeFile(@RequestParam String fileName) { ossBuilder.template().removeFile(fileName); return R.success("操作成功"); } /** * 批量删除文件 * * @param fileNames 存储桶对象名称集合 * @return R */ @SneakyThrows @PostMapping("/remove-files") @PreAuth(RoleConstant.HAS_ROLE_ADMIN) public R removeFiles(@RequestParam String fileNames) { ossBuilder.template().removeFiles(Func.toStrList(fileNames)); return R.success("操作成功"); } }