package com.sckw.core.utils;

import cn.hutool.core.date.DateTime;
import com.aliyun.oss.*;
import com.aliyun.oss.model.*;
import com.sckw.core.model.constant.NumberConstant;
import com.sckw.core.model.constant.StringConstant;
import com.sckw.core.model.enums.AliyunOssFileTypeEnum;
import com.sckw.core.model.enums.FileEnum;
import com.sckw.core.model.file.FileInfo;
import jakarta.annotation.PostConstruct;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FilenameUtils;
import org.apache.tomcat.util.http.fileupload.FileItem;
import org.apache.tomcat.util.http.fileupload.disk.DiskFileItemFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.net.URL;
import java.net.URLEncoder;
import java.nio.file.Files;
import java.text.DecimalFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * @author lfdc
 * @version 1.0
 * @className FileUtils
 * @description Oss文件工具类
 * @company sckw
 * @date 2023-06-05 09:06:57
 */
@Slf4j
@Component
@Configuration
public class FileUtils {

    private static String BASE_DIR = "slope/";

    //oss客户端连接
    private static OSS ossclient = null;


    private static String DEFAULT_ENDPOINT = "oss-cn-chengdu.aliyuncs.com";
    private static String DEFAULT_ACCESS_KEY_ID = "LTAI5tPEbubCGq5Rdwygbz4Q";
    private static String DEFAULT_ACCESS_KEY_SECRET = "7mQLWMaBJeZPRV1SRGogctYGXwppjQ";
    private static String DEFAULT_BUCKET_NAME = "kaiwu-saas";

    private static String endpoint;
    private static String accessKeyId;
    private static String accessKeySecret;
    private static String bucketName;
    private static FileUtils fileUtils;

    @Value("${aliyun.oss.endpoint}")
    private String oss_endpoint;

    @Value("${aliyun.oss.accessKeyId}")
    private String oss_accessKeyId;

    @Value("${aliyun.oss.secret}")
    private String oss_accessKeySecret;

    @Value("${aliyun.oss.bucket}")
    public String oss_bucketName;

    private static void defaultOss() {
        if (StringUtils.isBlank(endpoint)) {
            endpoint = DEFAULT_ENDPOINT;
        }
        if (StringUtils.isBlank(accessKeyId)) {
            accessKeyId = DEFAULT_ACCESS_KEY_ID;
        }
        if (StringUtils.isBlank(accessKeySecret)) {
            accessKeySecret = DEFAULT_ACCESS_KEY_SECRET;
        }
        if (StringUtils.isBlank(bucketName)) {
            bucketName = DEFAULT_BUCKET_NAME;
        }
    }

    @PostConstruct
    public void init() {
        endpoint = this.oss_endpoint;
        accessKeyId = this.oss_accessKeyId;
        accessKeySecret = this.oss_accessKeySecret;
        bucketName = this.oss_bucketName;
    }

//    @PostConstruct
//    public void setEndpoint() {
//        endpoint = this.oss_endpoint;
//    }
//
//    @PostConstruct
//    public void setAccessKeyId() {
//        accessKeyId = this.oss_accessKeyId;
//    }
//
//    @PostConstruct
//    public void setAccessKeySecret() {
//        accessKeySecret = this.oss_accessKeySecret;
//    }
//
//    @PostConstruct
//    public void setBucketName() {
//        bucketName = this.oss_bucketName;
//    }

    public static FileInfo getFileDataList(MultipartFile file) {
        FileInfo fileInfo = new FileInfo();
        String oFileName = file.getOriginalFilename();
        BigDecimal fileSize = FileUtils.getFileSize(file, StringConstant.KB);
        fileInfo.setFileSize(fileSize);
        fileInfo.setFileOriginalName(oFileName);
        fileInfo.setFileSuffix(FilenameUtils.getExtension(oFileName));
        return fileInfo;
    }

    /**
     * 获取文件上传大小
     *
     * @param size 当前默认使用 kb
     * @return
     */
    public static BigDecimal getFileSize(int size, String type) {
        BigDecimal bigDecimal = new BigDecimal(NumberConstant.ZERO);
        if (StringUtils.isBlank(type)) {
            type = StringConstant.KB;
        }
        switch (type) {
            case "B":
                bigDecimal = new BigDecimal((double) size);
                break;
            case "KB":
                bigDecimal = new BigDecimal((double) size / 1024);
                break;
            case "MB":
                bigDecimal = new BigDecimal((double) size / 1048576);
                break;
            case "GB":
                bigDecimal = new BigDecimal((double) size / 1073741824);
                break;
            default:
                throw new RuntimeException("file size error");
        }
        return bigDecimal.setScale(9, RoundingMode.HALF_UP);
    }

    /**
     * 获取oss 地址前缀
     *
     * @return
     */
    public static String getOSSAddressPrefix() {
        defaultOss();
        return StringConstant.HTTPS_STRING
                + StringConstant.COLON
                + StringConstant.LEFT_SEPARATORS
                + bucketName
                + StringConstant.POINT
                + endpoint
                + StringConstant.LEFT_SEPARATOR;
    }

    /**
     * 分割上传地址 目前仅用于oss
     *
     * @param replace 上传的绝对路径
     * @return 分割后的相对路径
     */
    public static String replaceAll(String replace) {
        if (StringUtils.isBlank(replace)) {
            return null;
        }
        return replace.replaceAll(getOSSAddressPrefix(), "");
    }

    /**
     * 拼接上传地址 目前仅用于oss
     *
     * @param replace 相对路径url
     * @return 绝对路径url
     */
    public static String splice(String replace) {
        StringBuilder stringBuilder = new StringBuilder();
        if (StringUtils.isBlank(replace)) {
            return null;
        }
        return stringBuilder.append(getOSSAddressPrefix()).append(replace).toString();
    }


    /**
     * 分割上传地址 目前仅用于oss
     *
     * @param replace 上传的绝对路径
     * @return 分割后的相对路径
     */
    public static String replaceAllBatch(String replace) {
        StringBuilder stringBuilder = new StringBuilder();
        if (StringUtils.isBlank(replace)) {
            return null;
        }
        String[] split = replace.split(",");
        if (split.length > 0) {
            for (int i = 0; i < split.length; i++) {
                if (i != (split.length - 1)) {
                    stringBuilder.append(split[i].replaceAll(getOSSAddressPrefix(), "")).append(",");
                } else {
                    stringBuilder.append(split[i].replaceAll(getOSSAddressPrefix(), ""));
                }

            }
            return stringBuilder.toString();
        }
        return null;
    }

    /**
     * 拼接上传地址 目前仅用于oss
     *
     * @param replace 相对路径url
     * @return 绝对路径url
     */
    public static String spliceBatch(String replace) {
        StringBuilder stringBuilder = new StringBuilder();
        if (StringUtils.isBlank(replace)) {
            return null;
        }
        String[] split = replace.split(",");
        if (split.length > 0) {
            for (int i = 0; i < split.length; i++) {
                if (i != (split.length - 1)) {
                    stringBuilder.append(getOSSAddressPrefix()).append(split[i]).append(",");
                } else {
                    stringBuilder.append(getOSSAddressPrefix()).append(split[i]);
                }
            }
            return stringBuilder.toString();
        }
        return null;
    }


    /**
     * 获取指定文件或文件夹的后缀名
     *
     * @param fileName 文件名称
     * @return
     */
    public static String getFileSuffix(String fileName) {
        //例如：abc.png  截取后：.png
        return fileName.substring(fileName.lastIndexOf("."));
    }

//    public static MultipartFile fileToMultipartFile(File file) {
//        FileItem fileItem = creatFileItem(file);
//        MultipartFile multipartFile = new CommonsMultipartFile(fileItem);
//        return multipartFile;
//    }

    public static FileItem creatFileItem(File file) {

        DiskFileItemFactory diskFileItemFactory = new DiskFileItemFactory(16, null);
        FileItem fileItem = diskFileItemFactory.createItem("textField", "application/zip", true, file.getName());

        int bytesRead = 0;
        byte[] buffer = new byte[8192];

        try {
            FileInputStream fileInputStream = new FileInputStream(file);
            OutputStream outputStream = fileItem.getOutputStream();
            while ((bytesRead = fileInputStream.read(buffer, 0, 8192)) != -1) {
                outputStream.write(buffer, 0, bytesRead);
            }
            Files.copy(file.toPath(), outputStream);
            outputStream.close();
            fileInputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return fileItem;
    }

    /**
     * 文件上传
     *
     * @param file     文件
     * @param fileEnum 上传使用的枚举
     * @return
     */
    public static Map<String, String> uploadFileByInfo(MultipartFile file, FileEnum fileEnum) {
        Map<String, String> infoMap = new HashMap<>(NumberConstant.SIXTEEN);
        //创建OSSClient实例
        defaultOss();
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
        try {
            //容器不存在，就创建
            if (!ossClient.doesBucketExist(bucketName)) {
                ossClient.createBucket(bucketName);
                CreateBucketRequest createBucketRequest = new CreateBucketRequest(bucketName);
                createBucketRequest.setCannedACL(CannedAccessControlList.PublicRead);
                ossClient.createBucket(createBucketRequest);
            }
            //上传文件流
            InputStream inputStream = file.getInputStream();
            String fileName = FilenameUtils.getBaseName(file.getOriginalFilename());
            //生成随机唯一值，使用uuid，添加到文件名称里面 改成使用加密
//            fileName = PasswordUtils.md5(fileName);
            fileName = PasswordUtils.md5(fileName);
            String fileSuffix = FileUtils.getFileSuffix(file.getOriginalFilename());
            //不带后缀
            infoMap.put("fileMd5", fileName);
            infoMap.put("fileName", fileName + fileSuffix);
            //按照当前日期，创建文件夹，上传到创建文件夹里面
            String timeUrl = new DateTime().toString("yyyyMMdd");
            fileName = timeUrl + "/" + fileName;
            String filePath = BASE_DIR + fileName + fileSuffix;
            //调用方法实现上传
            ossClient.putObject(bucketName, filePath, inputStream);
            //获取上传后的文件地址
            //String url1 = getUrl(ossClient, bucketName, filePath);
            //关闭OSSClient。
            ossClient.shutdown();
            //上传之后文件路径
            //String url = "https://" + bucketName + "." + endpoint + "/" + filePath;
            //绝对路径 "https://kaiwu-saas.oss-cn-chengdu.aliyuncs.com/+ filePath;"
            StringBuilder stringBuilder = new StringBuilder();
            stringBuilder.append(StringConstant.HTTPS_STRING)
                    .append(StringConstant.COLON)
                    .append(StringConstant.LEFT_SEPARATORS)
                    .append(bucketName)
                    .append(StringConstant.POINT)
                    .append(endpoint)
                    .append(StringConstant.LEFT_SEPARATOR);
//            String url = stringBuilder.append(filePath).toString();
            //相对路径
            String url = filePath;
            //返回 上传文件地址
            infoMap.put("filePath", url);
        } catch (IOException e) {
            infoMap.put("filePath", null);
            //关闭OSSClient。
            ossClient.shutdown();
            e.printStackTrace();
            log.error("oss-upload-file-error:{}", e.getMessage(), e);
            throw new RuntimeException("oss-upload-file-error:" + e.getMessage());
        }
        return infoMap;
    }


    /**
     * 文件上传
     *
     * @param file     文件
     * @param fileEnum 上传使用的枚举
     * @return
     */
    public static Map<String, String> uploadFileByInfo(File file, FileEnum fileEnum) {
        Map<String, String> infoMap = new HashMap<>(NumberConstant.SIXTEEN);
        //创建OSSClient实例
        defaultOss();
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
        try {
            //容器不存在，就创建
            if (!ossClient.doesBucketExist(bucketName)) {
                ossClient.createBucket(bucketName);
                CreateBucketRequest createBucketRequest = new CreateBucketRequest(bucketName);
                createBucketRequest.setCannedACL(CannedAccessControlList.PublicRead);
                ossClient.createBucket(createBucketRequest);
            }
            //上传文件流

//            InputStream inputStream = file.getInputStream();
            InputStream inputStream = new FileInputStream(file);
            String fileName = FilenameUtils.getBaseName(file.getName());
            //生成随机唯一值，使用uuid，添加到文件名称里面 改成使用加密
//            fileName = PasswordUtils.md5(fileName);
            fileName = PasswordUtils.md5(fileName);
            String fileSuffix = FileUtils.getFileSuffix(file.getName());
            //不带后缀
            infoMap.put("fileMd5", fileName);
            infoMap.put("fileName", fileName + fileSuffix);
            //按照当前日期，创建文件夹，上传到创建文件夹里面
            String timeUrl = new DateTime().toString("yyyyMMdd");
            fileName = timeUrl + "/" + fileName;
            String filePath = BASE_DIR + fileName + fileSuffix;
            //调用方法实现上传
            ossClient.putObject(bucketName, filePath, inputStream);
            //获取上传后的文件地址
            //String url1 = getUrl(ossClient, bucketName, filePath);
            //关闭OSSClient。
            ossClient.shutdown();
            //上传之后文件路径
            //String url = "https://" + bucketName + "." + endpoint + "/" + filePath;
            //绝对路径 "https://kaiwu-saas.oss-cn-chengdu.aliyuncs.com/+ filePath;"
            StringBuilder stringBuilder = new StringBuilder();
            stringBuilder.append(StringConstant.HTTPS_STRING)
                    .append(StringConstant.COLON)
                    .append(StringConstant.LEFT_SEPARATORS)
                    .append(bucketName)
                    .append(StringConstant.POINT)
                    .append(endpoint)
                    .append(StringConstant.LEFT_SEPARATOR);
//            String url = stringBuilder.append(filePath).toString();
            //相对路径
            String url = filePath;
            //返回 上传文件地址
            infoMap.put("filePath", url);
        } catch (IOException e) {
            infoMap.put("filePath", null);
            //关闭OSSClient。
            ossClient.shutdown();
            e.printStackTrace();
            log.error("oss-upload-file-error:{}", e.getMessage(), e);
            throw new RuntimeException("oss-upload-file-error:" + e.getMessage());
        }
        return infoMap;
    }

    /**
     * 上传文件
     * <p>
     * kll/uploads/年月日/md5(file).xxx
     *
     * @param file
     * @param fileEnum
     * @return
     */
    public static String uploadFile(MultipartFile file, FileEnum fileEnum) {
        // 私有云要关闭CNAME
        ClientBuilderConfiguration conf = new ClientBuilderConfiguration();
        conf.setSupportCname(false);
        try {
            //创建OSSClient实例
            defaultOss();
            OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);

            //容器不存在，就创建
            if (!ossClient.doesBucketExist(bucketName)) {
                ossClient.createBucket(bucketName);
                CreateBucketRequest createBucketRequest = new CreateBucketRequest(bucketName);
                createBucketRequest.setCannedACL(CannedAccessControlList.PublicRead);
                ossClient.createBucket(createBucketRequest);
            }
            //上传文件流
            InputStream inputStream = file.getInputStream();
            String fileName = file.getOriginalFilename();
            //生成随机唯一值，使用uuid，添加到文件名称里面
            long uuid = new IdWorker(1).nextId();
//            fileName = String.valueOf(uuid) + fileName;
            fileName = PasswordUtils.md5(fileName);
            //按照当前日期，创建文件夹，上传到创建文件夹里面
            //2021/02/02/01.jpgossClient = {OSSClient@13049}
            String timeUrl = new DateTime().toString("yyyyMMdd");
            fileName = timeUrl + "/" + fileName;
            String filePath = BASE_DIR + fileName;
            /**设置上传内容类型*/
            ObjectMetadata objectMeta = new ObjectMetadata();
            objectMeta.setContentType(FileUtils.getContentTypeByOSS(file.getOriginalFilename()));
            //调用方法实现上传
            ossClient.putObject(bucketName, filePath, inputStream, objectMeta);
            //上传后的文件地址
//            String url1 = getUrl(ossClient, bucketName, filePath);
//            System.out.println(url1);
            //关闭OSSClient。
            ossClient.shutdown();
            //上传之后文件路径
            //https://yygh-atguigu.oss-cn-beijing.aliyuncs.com/01.jpg
            String url = "https://" + bucketName + "." + endpoint + "/" + filePath;
            //返回 上传文件地址
            return url;
        } catch (IOException e) {
            e.printStackTrace();
            log.error("oss-upload-file-error:{}", e.getMessage(), e);
            return null;
        }
    }

    /**
     * 文件上传
     *
     * @param inputStream      文件流
     * @param originalFilename 文件原名称
     * @param fileEnum         上传文件类型/地址枚举
     * @return
     */
    public static Map<String, String> uploadFileByInfo(InputStream inputStream, String originalFilename, FileEnum fileEnum) {
        Map<String, String> infoMap = new HashMap<>(NumberConstant.SIXTEEN);
        //创建OSSClient实例
        defaultOss();
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
        try {
            //容器不存在，就创建
            if (!ossClient.doesBucketExist(bucketName)) {
                ossClient.createBucket(bucketName);
                CreateBucketRequest createBucketRequest = new CreateBucketRequest(bucketName);
                createBucketRequest.setCannedACL(CannedAccessControlList.PublicRead);
                ossClient.createBucket(createBucketRequest);
            }
            //上传文件流
            String fileName = FilenameUtils.getBaseName(originalFilename);
            //生成随机唯一值，使用uuid，添加到文件名称里面 改成使用加密
//            fileName = PasswordUtils.md5(fileName);
            fileName = PasswordUtils.md5(fileName);
            String fileSuffix = FileUtils.getFileSuffix(originalFilename);
            //不带后缀
            infoMap.put("fileMd5", fileName);
            infoMap.put("fileName", fileName + fileSuffix);
            //按照当前日期，创建文件夹，上传到创建文件夹里面
            //2021/02/02/01.jpg
            String timeUrl = new DateTime().toString("yyyyMMdd");
            fileName = timeUrl + "/" + fileName;
            String filePath = BASE_DIR + fileName + fileSuffix;
            //调用方法实现上传
            ossClient.putObject(bucketName, filePath, inputStream);
            //上传后的文件地址
//            String url1 = getUrl(ossClient, bucketName, filePath);
            //关闭OSSClient。
            ossClient.shutdown();
            //上传之后文件路径
//            String url = "https://" + bucketName + "." + endpoint + "/" + filePath;
            //绝对路径 "https://kaiwu-saas.oss-cn-chengdu.aliyuncs.com/+ filePath;"
//            String url = StringConstant.HTTPS_STRING+StringConstant.COLON+StringConstant.LEFT_SEPARATORS + bucketName + StringConstant.POINT + endpoint + StringConstant.LEFT_SEPARATOR+ filePath;
            //相对路径
            String url = filePath;
            //返回 上传文件地址
            infoMap.put("filePath", url);
        } catch (Exception e) {
            infoMap.put("filePath", null);
            //关闭OSSClient。
            ossClient.shutdown();
            e.printStackTrace();
            log.error("oss-upload-file-error:{}", e.getMessage(), e);
            throw new RuntimeException("oss-upload-file-error:" + e.getMessage());
        }
        return infoMap;
    }


    /**
     * 文件上传
     *
     * @param file     文件流
     * @param fileInfo 文件对象
     * @param fileEnum 文件枚举-暂时不使用
     * @return
     */
    public static FileInfo uploadFileInfo(MultipartFile file, FileInfo fileInfo, FileEnum fileEnum) {
        //创建OSSClient实例
        defaultOss();
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
        try {
            //容器不存在，就创建
            if (!ossClient.doesBucketExist(bucketName)) {
                ossClient.createBucket(bucketName);
                CreateBucketRequest createBucketRequest = new CreateBucketRequest(bucketName);
                createBucketRequest.setCannedACL(CannedAccessControlList.PublicRead);
                ossClient.createBucket(createBucketRequest);
            }
            //上传文件流
            InputStream inputStream = file.getInputStream();
            String fileName = FilenameUtils.getBaseName(file.getOriginalFilename());
            //生成随机唯一值，使用uuid，添加到文件名称里面 改成使用加密
            //fileName = PasswordUtils.md5(fileName);
            fileName = PasswordUtils.md5(fileName) + System.currentTimeMillis();
            String fileSuffix = FileUtils.getFileSuffix(file.getOriginalFilename());
            //不带后缀
            fileInfo.setFileMd5(fileName);
            fileInfo.setFileName(fileName + fileSuffix);
            //按照当前日期，创建文件夹，上传到创建文件夹里面
            String timeUrl = new DateTime().toString(StringConstant.DATE_YYYYMMDD);
            fileName = timeUrl + StringConstant.LEFT_SEPARATOR + fileName;
            String filePath = BASE_DIR + fileName + fileSuffix;
            //调用方法实现上传
            ossClient.putObject(bucketName, filePath, inputStream);
            //获取上传后的文件地址
            //String url1 = getUrl(ossClient, bucketName, filePath);
            //关闭OSSClient。
            ossClient.shutdown();
            //上传之后文件路径
            //String url = "https://" + bucketName + "." + endpoint + "/" + filePath;
            //绝对路径 "https://kaiwu-saas.oss-cn-chengdu.aliyuncs.com/+ filePath;"
            StringBuilder stringBuilder = new StringBuilder();
            stringBuilder.append(StringConstant.HTTPS_STRING)
                    .append(StringConstant.COLON)
                    .append(StringConstant.LEFT_SEPARATORS)
                    .append(bucketName)
                    .append(StringConstant.POINT)
                    .append(endpoint)
                    .append(StringConstant.LEFT_SEPARATOR);
            String fileAbsolutePath = stringBuilder.append(filePath).toString();
            fileInfo.setFileAbsolutePath(fileAbsolutePath);
            //相对路径
            String url = filePath;
            //返回 上传文件地址
            fileInfo.setFilePath(url);
        } catch (IOException e) {
            fileInfo.setFilePath(null);
            //关闭OSSClient。
            ossClient.shutdown();
            e.printStackTrace();
            log.error("oss-upload-file-error:{}", e.getMessage(), e);
            throw new RuntimeException("oss-upload-file-error:" + e.getMessage());
        }
        return fileInfo;
    }


    /**
     * 获取文件上传大小
     *
     * @param file
     * @return
     */
    public static String getFileSize(MultipartFile file) {
        long size = file.getSize();
        DecimalFormat df = new DecimalFormat("#.00");
        String fileSizeString;
        if (size < 1024) {
            fileSizeString = df.format((double) size) + "B";
        } else if (size < 1048576) {
            fileSizeString = df.format((double) size / 1024) + "KB";
        } else if (size < 1073741824) {
            fileSizeString = df.format((double) size / 1048576) + "MB";
        } else {
            fileSizeString = df.format((double) size / 1073741824) + "GB";
        }
        return fileSizeString;
    }

    /**
     * 获取文件上传大小
     *
     * @param file 当前默认使用 kb
     * @return
     */
    public static BigDecimal getFileSize(MultipartFile file, String type) {
        long size = file.getSize();
        BigDecimal bigDecimal = new BigDecimal(NumberConstant.ZERO);
        if (StringUtils.isBlank(type)) {
            type = StringConstant.KB;
        }
        switch (type) {
            case "B":
                bigDecimal = new BigDecimal((double) size);
                break;
            case "KB":
                bigDecimal = new BigDecimal((double) size / 1024);
                break;
            case "MB":
                bigDecimal = new BigDecimal((double) size / 1048576);
                break;
            case "GB":
                bigDecimal = new BigDecimal((double) size / 1073741824);
                break;
            default:
                throw new RuntimeException("file size error");
        }
        return bigDecimal.setScale(6, RoundingMode.HALF_UP);
    }

    /**
     * 获得阿里云OSS客户端对象
     *
     * @param ossEndpoint
     * @param accessId
     * @param accessKey
     * @return
     */
    public static OSS getOssClient(String ossEndpoint, String accessId, String accessKey) {
        if (ossclient == null) {
            ossclient = new OSSClientBuilder().build(ossEndpoint, accessId, accessKey);
        }
        return ossclient;
    }

    /**
     * 通过文件名判断并获取OSS服务文件上传时文件的contentType
     *
     * @param fileName 文件名
     * @return 文件的contentType
     */
    public static String getContentType(String fileName) {
        // 文件的后缀名
        String fileExtension = fileName.substring(fileName.lastIndexOf("."));
        log.info("getContentType->fileName={},fileExtension={}", fileName, fileExtension);
        for (AliyunOssFileTypeEnum e : AliyunOssFileTypeEnum.values()) {
            if (e.getCode().equalsIgnoreCase(fileExtension)) {
                return e.getText();
            }
        }
        // 默认返回类型
        return AliyunOssFileTypeEnum.TXT.getText();
    }

    /**
     * @param fileName
     * @param response
     */
    public static void downOSSFile(String fileName, HttpServletResponse response) {
        BufferedInputStream input = null;
        OutputStream outputStream = null;
        defaultOss();
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
//        OSSObject ossObject = ossClient.getObject(bucketName, folder + fileName);
        OSSObject ossObject = ossClient.getObject(bucketName, fileName);
        try {
            response.reset();
            response.setCharacterEncoding("utf-8");
            response.setContentType("application/x-msdownload");
            response.addHeader("Content-Disposition",
                    "attachment;filename=" + new String(fileName.getBytes("gb2312"), "ISO8859-1"));

            input = new BufferedInputStream(ossObject.getObjectContent());
            byte[] buffBytes = new byte[1024];
            outputStream = response.getOutputStream();
            int read = 0;
            while ((read = input.read(buffBytes)) != -1) {
                outputStream.write(buffBytes, 0, read);
            }
            outputStream.flush();
            // 数据读取完成后，获取的流必须关闭，否则会造成连接泄漏，导致请求无连接可用，程序无法正常工作。
            ossObject.close();
        } catch (IOException ex) {
            ex.printStackTrace();
        } finally {
            try {
                if (outputStream != null) {
                    outputStream.close();
                }
                if (input != null) {
                    input.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        ossClient.shutdown();
    }


    /**
     * 通过文件名字下载
     *
     * @param response response
     * @param fileName 文件名字，带后缀，例子：postman.txt
     *                 文件全路径 kll/uploads/20230605/146325493677821952598454132.txt 去除“https://kaiwu-saas.oss-cn-chengdu.aliyuncs.com/”
     */
    public static void downloadByFileName(HttpServletResponse response, String fileName) {
        defaultOss();
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
        OSSObject ossObject = ossClient.getObject(bucketName, fileName);
        boolean exist = ossClient.doesObjectExist(bucketName, fileName);
        if (!exist) {
            throw new RuntimeException("下载文件不存在!");
        }
        String contentType = ossObject.getObjectMetadata().getContentType();
        String contentType1 = getContentType(fileName);
//        System.out.println("contentType:" + contentType);
//        System.out.println("contentType1:" + contentType1);
        //设置响应内容类型，当设置了ContentType为“image/jpg”时，浏览器可以直接显示图片；
//        response.setContentType(contentType);
        BufferedInputStream in = new BufferedInputStream(ossObject.getObjectContent());
        try {
            BufferedOutputStream out = new BufferedOutputStream(response.getOutputStream());
            //通知浏览器以附件形式下载
//            fileName = URLEncoder.encode(fileName, "UTF-8").replaceAll("\\+", "%20");
            response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "utf-8").replaceAll("\\+", "%20"));
            byte[] car = new byte[1024];
            int len = 0;
            while ((len = in.read(car)) != -1) {
                out.write(car, 0, len);
            }
            out.flush();
            out.close();
            in.close();
            ossClient.shutdown();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 创建存储空间
     *
     * @param ossClient  OSS连接
     * @param bucketName 存储空间
     * @return
     */
    public static String createBucketName(OSS ossClient, String bucketName) {
        // 存储空间
        final String bucketNames = bucketName;
        if (!ossClient.doesBucketExist(bucketName)) {
            // 创建存储空间
            Bucket bucket = ossClient.createBucket(bucketName);
            log.info("创建存储空间成功");
            return bucket.getName();
        }
        return bucketNames;
    }


    /**
     * 删除存储空间bucketName
     *
     * @param ossClient  oss对象
     * @param bucketName 存储空间
     */
    public static void deleteBucket(OSS ossClient, String bucketName) {
        ossClient.deleteBucket(bucketName);
        log.info("删除" + bucketName + "Bucket成功");
    }


    /**
     * 创建模拟文件夹:多级目录
     *
     * @param ossClient  oss连接
     * @param bucketName 存储空间
     * @param folder     模拟文件夹名如"upload/2023/01/11/"
     * @return 文件夹名
     */
    public static String createFolder(OSS ossClient, String bucketName, String folder) {
        // 文件夹名
        final String keySuffixWithSlash = folder;
        // 判断文件夹是否存在，不存在则创建
        if (!ossClient.doesObjectExist(bucketName, keySuffixWithSlash)) {
            // 创建文件夹
            ossClient.putObject(bucketName, keySuffixWithSlash, new ByteArrayInputStream(new byte[0]));
            log.info("创建文件夹成功");
            // 得到文件夹名
            OSSObject object = ossClient.getObject(bucketName, keySuffixWithSlash);
            String fileDir = object.getKey();
            return fileDir;
        }
        return keySuffixWithSlash;
    }


    /**
     * 根据key删除OSS服务器上的文件
     *
     * @param ossClient  oss连接
     * @param bucketName 存储空间
     * @param key        Bucket下的文件的路径名+文件名 如："upload/2023/01/11/cake.jpg"
     */
    public static void deleteObject(OSS ossClient, String bucketName, String key) {
        ossClient.deleteObject(bucketName, key);
        log.info("删除" + bucketName + "下的文件" + key + "成功");
    }


    /**
     * 上传文件
     *
     * @param ossClient  oss连接
     * @param bucketName 存储空间
     * @param ossPath    上传文件相对路径+文件名如"upload/2023/01/11/cake.jpg"
     * @param is         以输入流的形式上传文件
     * @param fileName   上传文件后新文件名
     * @return String 返回的唯一MD5数字签名
     */
    public static String uploadFileOss(OSS ossClient, String bucketName, String ossPath, InputStream is, String fileName) {
        try {
            // 文件大小
            long fileSize = is.available();
            // 创建上传Object的Metadata
            ObjectMetadata metadata = new ObjectMetadata();
            // 上传的文件的长度
            metadata.setContentLength(is.available());
            // 指定该Object被下载时的网页的缓存行为
            metadata.setCacheControl("no-cache");
            // 指定该Object下设置Header
            metadata.setHeader("Pragma", "no-cache");
            // 指定该Object被下载时的内容编码格式
            metadata.setContentEncoding("utf-8");
            // 文件的MIME，定义文件的类型及网页编码，决定浏览器将以什么形式、什么编码读取文件。如果用户没有指定则根据Key或文件名的扩展名生成，
            // 如果没有扩展名则填默认值application/octet-stream
            metadata.setContentType(getContentType(fileName));
            // 指定该Object被下载时的名称（指示MINME用户代理如何显示附加的文件，打开或下载，及文件名称）
            metadata.setContentDisposition("filename/filesize=" + fileName + "/" + fileSize + "Byte");
            //上传文件到OSS时需要指定包含文件后缀在内的完整路径如ossPath="upload/2023/01/11/cake.jpg"
            PutObjectResult putResult = ossClient.putObject(bucketName, ossPath, is, metadata);
            // 解析结果
            String resultStr = putResult.getETag();
            log.info("唯一MD5数字签名:" + resultStr);
            //上传文件后相对路径如"upload/2023/01/11/cake.jpg"
            String path = ossPath;
            return path;
        } catch (Exception e) {
            e.printStackTrace();
            log.error("上传阿里云OSS服务器异常." + e.getMessage(), e);
            return null;
        }
    }


    /**
     * 下载文件到本地
     *
     * @param ossClient     oss连接
     * @param bucketName    存储空间
     * @param key           Bucket下的文件的路径名+文件名 如："upload/2023/01/11/cake.jpg"
     * @param localFilePath 下载本地文件绝对路径如"C:\Users\Administrator\Desktop\oss-download\xxx.pdf"
     */
    public static void downloadFileOss(OSS ossClient, String bucketName, String key, String localFilePath) {
        try {
            //创建本地文件
            File file = new File(localFilePath);
            GetObjectRequest objectRequest = new GetObjectRequest(bucketName, key);
            //下载OSS文件到本地文件，若指定的本地文件存在则覆盖，否则新建
            ossClient.getObject(objectRequest, file);
            log.info("下载文件到本地成功");
        } catch (OSSException e) {
            e.printStackTrace();
        } catch (ClientException e) {
            e.printStackTrace();
        }
    }


    /**
     * 获取上传文件对象
     * 备注：最重要的是获取上传文件的输出流InputStream
     *
     * @param ossClient  oss连接
     * @param bucketName 存储空间
     * @param key        Bucket下的文件的路径名+文件名 如："upload/2023/01/11/cake.jpg"
     * @return
     */
    public static OSSObject getObject(OSS ossClient, String bucketName, String key) {
        OSSObject object = null;
        try {
            object = ossClient.getObject(bucketName, key);
            //文件大小
            long fileSize = object.getObjectMetadata().getContentLength();
            //文件相对路径
            String ossPath = object.getKey();
            //文件输入流
            InputStream is = object.getObjectContent();
            log.info("success to getObject,fileSize:" + fileSize + "\nossPath:" + ossPath + "\ninputStream:" + is);
        } catch (OSSException e) {
            e.printStackTrace();
        } catch (ClientException e) {
            e.printStackTrace();
        }
        return object;
    }


    /**
     * 获取上传文件url
     *
     * @param ossClient  oss连接
     * @param bucketName bucketName
     * @param key        文件全路径
     * @return
     */
    public static String getUrl(OSS ossClient, String bucketName, String key) {
        //设置URl过期时间为99年：3600L*1000*24*365*99
        Date expiration = new Date(System.currentTimeMillis() + 3600L * 1000 * 24 * 365 * 99);
        GeneratePresignedUrlRequest generatePresignedUrlRequest = new GeneratePresignedUrlRequest(bucketName, key);
        generatePresignedUrlRequest.setExpiration(expiration);
        URL url = ossClient.generatePresignedUrl(generatePresignedUrlRequest);
        String returnUrl = url.toString();
        return returnUrl;
    }


    public static void downloadByFileName(String objectName) {
        // Endpoint以华东1（杭州）为例，其它Region请按实际情况填写。关于其他Region对应的Endpoint信息，请参见访问域名和数据中心。
//        String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
        // 阿里云账号AccessKey拥有所有API的访问权限，风险很高。强烈建议您创建并使用RAM用户进行API访问或日常运维，请登录RAM控制台创建RAM用户。
//        String accessKeyId = "yourAccessKeyId";
//        String accessKeySecret = "yourAccessKeySecret";
        // 填写Bucket名称，例如examplebucket。
//        String bucketName = "examplebucket";
        // 填写Object完整路径，例如exampledir/exampleobject.txt。Object完整路径中不能包含Bucket名称。
//        String objectName = "exampledir/exampleobject.txt";

        // 创建OSSClient实例。
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
        try {
            // ossObject包含文件所在的存储空间名称、文件名称、文件元信息以及一个输入流。
            OSSObject ossObject = ossClient.getObject(bucketName, objectName);
            // 读取文件内容。
            System.out.println("Object content:");
            BufferedReader reader = new BufferedReader(new InputStreamReader(ossObject.getObjectContent()));
            while (true) {
                String line = reader.readLine();
                if (line == null) {
                    break;
                }

                System.out.println("\n" + line);
            }
            // 数据读取完成后，获取的流必须关闭，否则会造成连接泄漏，导致请求无连接可用，程序无法正常工作。
            reader.close();
            // ossObject对象使用完毕后必须关闭，否则会造成连接泄漏，导致请求无连接可用，程序无法正常工作。
            ossObject.close();

        } catch (OSSException oe) {
            System.out.println("Caught an OSSException, which means your request made it to OSS, "
                    + "but was rejected with an error response for some reason.");
            System.out.println("Error Message:" + oe.getErrorMessage());
            System.out.println("Error Code:" + oe.getErrorCode());
            System.out.println("Request ID:" + oe.getRequestId());
            System.out.println("Host ID:" + oe.getHostId());
        } catch (Throwable ce) {
            System.out.println("Caught an ClientException, which means the client encountered "
                    + "a serious internal problem while trying to communicate with OSS, "
                    + "such as not being able to access the network.");
            System.out.println("Error Message:" + ce.getMessage());
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
    }


    /**
     * 通过oss的完整key下载
     *
     * @param response   response
     * @param objectName oss完整的key，例子：fj_wechat_web/public/postman.txt
     */
    public static void downloadByObjectName(HttpServletResponse response, String objectName) {
//        String endpointStr = "http://" + endpoint + ".aliyuncs.com";
        String endpointStr = "http://" + endpoint;
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
        OSSObject ossObject = ossClient.getObject(bucketName, objectName);

        BufferedInputStream in = new BufferedInputStream(ossObject.getObjectContent());

        try {
            BufferedOutputStream out = new BufferedOutputStream(response.getOutputStream());
            //通知浏览器以附件形式下载
            response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("postman.txt", "utf-8"));

            byte[] car = new byte[1024];
            int len;
            while ((len = in.read(car)) != -1) {
                out.write(car, 0, len);
            }
            out.flush();
            out.close();
            in.close();
            ossClient.shutdown();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 通过oss的完整key下载
     *
     * @param response response
     * @param url      全路径的url地址 kll/uploads/20230621/07ccbec381a011d121a215719199ac49.html
     */
    public static void downloadByUrl(HttpServletResponse response, String url) {
        downloadByFileName(response, url);
    }

    /**
     * @param @param ossFilePath oss上的文件路径（全路径）
     * @param @param newFilePath 本地文件路径 （全路径）
     * @return void    返回类型
     * @Title:downloadToFile
     * @Description: 下载文件到本地
     */
    public static void downloadToFile(String endPoint, String accessKeyId, String accessKeySecret, String bucketName, String ossFilePath, String newFilePath) {
        //实例化OSSClient对象
        OSSClient ossClient = (OSSClient) new OSSClientBuilder().build(endPoint, accessKeyId, accessKeySecret);
        try {
            // 指定路径如果没有则创建并添加
            File file = new File(newFilePath);
            //获取父目录
            File fileParent = file.getParentFile();
            //判断是否存在
            if (!fileParent.exists()) {
                // 创建父目录文件
                fileParent.mkdirs();
            }
            file.createNewFile();
            // 下载Object到本地文件，并保存到指定的本地路径中。如果指定的本地文件存在会覆盖，不存在则新建。
            // 如果未指定本地路径，则下载后的文件默认保存到示例程序所属项目对应本地路径中。
            ossClient.getObject(new GetObjectRequest(bucketName, ossFilePath), new File(newFilePath));

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
    }

    /**
     * 判断文件是否存在
     *
     * @param fileName 文件名：postman.txt
     * @return true文件存在，false文件不存在
     */
    public boolean isExitByFileName(String fileName) {
//        String endpointStr = "http://" + endpoint + ".aliyuncs.com";
        String endpointStr = "http://" + endpoint;
        OSS ossClient = new OSSClientBuilder().build(endpointStr, accessKeyId, accessKeySecret);
        return ossClient.doesObjectExist(bucketName, BASE_DIR + fileName);
    }

    /**
     * 判断文件是否存在
     *
     * @param url 能直接访问的完整url
     * @return true文件存在，false文件不存在
     */
    public boolean isExitByUrl(String url) {
        return isExitByFileName(getFileNameByUrl(url));
    }

    /**
     * 通过url获取文件名
     *
     * @param url 能够直接访问的url
     * @return 文件名：postman.txt
     */
    public static String getFileNameByUrl(String url) {
        String[] split = url.split("/");
        return split[split.length - 1];
    }

    /**
     * 字符串转成file文件
     *
     * @param text
     * @param file
     * @return
     */
    public static File stringByFile(String text, File file) {
        if (file.exists()) {
            file.delete();
        }
        BufferedReader br = null;
        BufferedWriter bw = null;
        try {
            br = new BufferedReader(new StringReader(text));
            bw = new BufferedWriter(new FileWriter(file));
            //字符缓冲区
            char[] buf = new char[1024 * 64];
            int len;
            while ((len = br.read(buf)) != -1) {
                bw.write(buf, 0, len);
            }
            bw.flush();
            br.close();
            bw.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return file;
    }

    /**
     * file转byte
     */
    public static byte[] file2byte(File file) {
        byte[] buffer = null;
        try {
            FileInputStream fis = new FileInputStream(file);
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            byte[] b = new byte[1024];
            int n;
            while ((n = fis.read(b)) != -1) {
                bos.write(b, 0, n);
            }
            fis.close();
            bos.close();
            buffer = bos.toByteArray();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return buffer;
    }

    /**
     * byte 转file
     */
    public static File byte2File(byte[] buf, String filePath, String fileName) {
        BufferedOutputStream bos = null;
        FileOutputStream fos = null;
        File file = null;
        try {
            File dir = new File(filePath);
            if (!dir.exists() && dir.isDirectory()) {
                dir.mkdirs();
            }
            file = new File(filePath + File.separator + fileName);
            fos = new FileOutputStream(file);
            bos = new BufferedOutputStream(fos);
            bos.write(buf);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (bos != null) {
                try {
                    bos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (fos != null) {
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return file;
    }

    /**
     * multipartFile转File
     **/
    public static File multipartFile2File(MultipartFile multipartFile) {
        File file = null;
        if (multipartFile != null) {
            try {
                file = File.createTempFile("tmp", null);
                multipartFile.transferTo(file);
                System.gc();
                file.deleteOnExit();
            } catch (Exception e) {
                e.printStackTrace();
                log.warn("multipartFile转File发生异常：" + e);
            }
        }
        return file;
    }


    /**
     * 删除文件
     *
     * @param url 示例：'download/file.xsl' oss服务器文件路径以及文件名
     *            https://kaiwu-saas.oss-cn-chengdu.aliyuncs.com/kll/uploads/20230621/07ccbec381a011d121a215719199ac49.html
     *            删除时,去掉默认前缀,只需要相对路径 “kll/uploads/20230621/07ccbec381a011d121a215719199ac49.html”
     */
    public static void remove(String url) {
        try {
            // 创建OSSClient实例。
            OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
            // 判断当前文件url 是否存在
            boolean exist = ossClient.doesObjectExist(bucketName, url);
            if (!exist) {
                System.out.println("文件不存在");
            } else {
                // 删除文件。
                ossClient.deleteObject(bucketName, url);
                // 关闭OSSClient。
                ossClient.shutdown();

            }
        } catch (Exception e) {
            System.out.println(e);
        }

    }


    /**
     * 获取OSS连接
     *
     * @return
     */
    private static void getOSSClient() {
        if (ossclient == null) {
            ossclient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
        }
    }

    /**
     * 根据key删除OSS服务器上的文件
     * <p>
     * param ossClient oss连接
     * param bucketName 存储空间
     * param folder 模拟文件夹名 如"qj_nanjing/"
     * param key Bucket下的文件的路径名+文件名 如："upload/cake.jpg"
     */
    public static void deleteFile(String bucketName, String folder, String key) {
        //获取OSS存储client
        getOSSClient();
        ossclient.deleteObject(bucketName, folder + key);
        log.info("删除" + bucketName + "下的文件" + folder + key + "成功");
    }

    /**
     * 通过文件名判断并获取OSS服务文件上传时文件的contentType
     * param fileName 文件名
     * return 文件的 contentType
     */
    public static String getContentTypeByOSS(String fileName) {
        // 文件的后缀名
        String fileExtension = fileName.substring(fileName.lastIndexOf("."));
        if (".bmp".equalsIgnoreCase(fileExtension)) {
            return "image/bmp";
        }
        if (".gif".equalsIgnoreCase(fileExtension)) {
            return "image/gif";
        }
        if (".jpeg".equalsIgnoreCase(fileExtension) || ".jpg".equalsIgnoreCase(fileExtension)
                || ".png".equalsIgnoreCase(fileExtension)) {
            return "image/jpeg";
        }
        if (".png".equalsIgnoreCase(fileExtension)) {
            return "image/png";
        }
        if (".html".equalsIgnoreCase(fileExtension)) {
            return "text/html";
        }
        if (".txt".equalsIgnoreCase(fileExtension)) {
            return "text/plain";
        }
        if (".vsd".equalsIgnoreCase(fileExtension)) {
            return "application/vnd.visio";
        }
        if (".ppt".equalsIgnoreCase(fileExtension) || "pptx".equalsIgnoreCase(fileExtension)) {
            return "application/vnd.ms-powerpoint";
        }
        if (".doc".equalsIgnoreCase(fileExtension) || "docx".equalsIgnoreCase(fileExtension)) {
            return "application/msword";
        }
        if (".xml".equalsIgnoreCase(fileExtension)) {
            return "text/xml";
        }
        // 默认返回类型
        return null;
    }


    /**
     * 下载文件,此处主要是给Controller层提供一个OSS的Object类
     * objectName示例：download/file.xsl,()这里是oss文件列表中 文件路径和文件名
     */
    public static OSSObject downloadOssFile(OutputStream os, String objectName) {
        // ossObject包含文件所在的存储空间名称、文件名称、文件元信息以及一个输入流。
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
        OSSObject ossObject = ossClient.getObject(bucketName, objectName);
        return ossObject;

    }

    final static String IMG_FORMAT = "png_jpg_bmp_gif_tif_jpeg_PNG_JPG_BMP_GIF_TIF_JPEG_HEIC_heic";
    final static String IMG_FORMAT_NUMBER = "8950_ffd8_424d_4749_4d4d_4949_5249";


    /**
     * 针对图片内容的格式效验。
     * 分别以：
     * 1：判断后缀名的方式判断是否为图片
     * 2：以魔术数字进行判断
     * 3：以imageIO流的方式验证是否为图片
     *
     * @param mFile
     * @return boolean
     * @author lihao
     */
    public static boolean isImage(MultipartFile mFile) {
        File file = null;
        InputStream is = null;
        Image img = null;
        byte[] bt = new byte[2];
        try {
            file = multipartFile2File(mFile);
            is = new FileInputStream(file);
            is.read(bt);
            img = ImageIO.read(file);
        } catch (IOException e) {
            return false;
        }

        //获取文件后缀进行判断
        String suffix = mFile.getOriginalFilename().substring(mFile.getOriginalFilename().lastIndexOf(".") + 1);
        if (IMG_FORMAT.indexOf(suffix) == -1) {
            return false;
        }

        //以魔术数字进行判断
        StringBuilder stringBuilder = new StringBuilder();
        for (int i = 0; i < bt.length; i++) {
            int v = bt[i] & 0xFF;//byte to int
            String hv = Integer.toHexString(v);
            if (hv.length() < 2) {
                stringBuilder.append(0);
            }
            stringBuilder.append(hv);
        }
        System.out.println(stringBuilder.toString());
        if (IMG_FORMAT_NUMBER.indexOf(stringBuilder.toString()) == -1) {
            return false;
        }

        //以imageIO流的方式对图片进行格式检查
        if (img == null || img.getWidth(null) <= 0 || img.getHeight(null) <= 0) {
            return false;
        }
        if (file.exists()) {
            file.delete();
        }
        return true;
    }

    /**
     * 给图片添加水印、可设置水印图片旋转角度
     *
     * @param logoText 水印文字
     * @param degree   水印图片旋转角度
     * @param clarity  透明度(小于1的数)越接近0越透明
     * @param mFile    被操作的图片
     */
    public byte[] waterMarkByText(String logoText,
                                  Integer degree,
                                  Float clarity, MultipartFile mFile) {
        // 图片流
        InputStream inputStream = null;
        ByteArrayOutputStream byteStream = null;
        Image srcImg = null;
        File file = null;
        byte[] byteImg = new byte[0];

        //水印添加位置坐标 1像素=1磅*DPI/72 显示屏dpi 大多是72 少数96  这里不对
        Integer width, height;
        Integer fontSize = 50;
        Integer rightButtomOffset = fontSize * 72 / 72 * 6;

        try {
            file = File.createTempFile("tmp", null);
            mFile.transferTo(file);
            srcImg = ImageIO.read(file);
            width = srcImg.getWidth(null) - rightButtomOffset;
            height = srcImg.getHeight(null);
            BufferedImage buffImg = new BufferedImage(srcImg.getWidth(null),
                    srcImg.getHeight(null), BufferedImage.TYPE_INT_RGB);
            // 得到画笔对象
            Graphics2D g = buffImg.createGraphics();
            // 设置对线段的锯齿状边缘处理
            g.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
                    RenderingHints.VALUE_INTERPOLATION_BILINEAR);
            g.drawImage(
                    srcImg.getScaledInstance(srcImg.getWidth(null),
                            srcImg.getHeight(null), Image.SCALE_SMOOTH), 0, 0,
                    null);
            if (null != degree) {
                // 设置水印旋转
                g.rotate(Math.toRadians(degree),
                        (double) buffImg.getWidth() / 2,
                        (double) buffImg.getHeight() / 2);
            }
            // 设置颜色
            g.setColor(Color.red);
            // 设置 Font
            g.setFont(new Font("宋体", Font.BOLD, fontSize));
            float alpha = clarity;
            g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP,
                    alpha));
            // 第一参数->设置的内容，后面两个参数->文字在图片上的坐标位置(x,y) .
            g.drawString(logoText, width, height);
            g.dispose();
            // 生成图片
            ImageIO.write(buffImg, "JPG", file);
            inputStream = new FileInputStream(file);
            byteStream = new ByteArrayOutputStream();
            int ch;
            while ((ch = inputStream.read()) != -1) {
                byteStream.write(ch);
            }
            byteImg = byteStream.toByteArray();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (null != inputStream) {
                    inputStream.close();
                }
                if (null != byteStream) {
                    byteStream.close();
                }
                if (file.exists()) {
                    file.delete();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return byteImg;
    }

    // 测试
    public static void main(String[] args) throws FileNotFoundException {
        //阿里云OSS账号自行到阿里云官网申请
        String ossEndpoint = "XXX";
        String accessId = "XXX";
        String accessKey = "XXX";
        String bucketName = "test";
        // 初始化OSSClient
//        OSS ossClient = AliyunOSSClientUtil.getOssClient(ossEndpoint, accessId, accessKey);
        OSS ossClient = FileUtils.getOssClient(ossEndpoint, accessId, accessKey);


        //测试创建多级目录
        /*String tmpDir = "upload/2023/01/11/";
        String folder = createFolder(ossClient, bucketName, tmpDir);
        System.out.println("folder:"+folder);*/


        //测试删除文件
        /*String key="upload/2023/01/11/xxx.pdf";
        deleteObject(ossClient,bucketName,key);*/


        //测试上传文件
        /*String pathAndname = "C:\\Users\\Administrator\\Desktop\\测试文件上传\\xxx.pdf";
        File file = new File(pathAndname);
        //原始文件名:带后缀
        String oldfilename = file.getName();
        //新文件名：带后缀
        String newfilename = "9065df0f3ab72419b36d2dec088e11d6.pdf";//可以自行生成随机唯一文件名
        String newpath = "C:\\Users\\Administrator\\Desktop\\upload\\2023\\01\\11\\";
        String ossPath = newpath + newfilename;
        InputStream is = new FileInputStream(file);
        String absolutePath = uploadFileOss(ossClient, bucketName, ossPath, is, newfilename);
        System.out.println("absolutePath:"+absolutePath);*/


        //测试获取文件url
        /*String key="upload/2023/01/11/9065df0f3ab72419b36d2dec088e11d6.pdf";
        String url = getUrl(ossClient, bucketName, key);
        System.out.println("url:"+url);*/


        //测试获取上传对象
        /*String key = "upload/2023/01/11/9065df0f3ab72419b36d2dec088e11d6.pdf";
        getObject(ossClient, bucketName, key);*/


        //测试下载文件到本地
        /*String key = "upload/2023/01/11/9065df0f3ab72419b36d2dec088e11d6.pdf";
        String localFilePath = "C:\\Users\\Administrator\\Desktop\\oss-download\\xxx.pdf";
        downloadFileOss(ossClient, bucketName, key, localFilePath);*/
    }

}
