前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >3、策略模式所需代码

3、策略模式所需代码

作者头像
用户10136162
发布2023-10-30 14:47:24
2050
发布2023-10-30 14:47:24
举报
文章被收录于专栏:Eliauk的小窝Eliauk的小窝

1、策略接口上下文

代码语言:javascript
复制
@Service
public class PathUploadStrategyContext {

        @Resource
        private Map<String, PathUploadStrategy> pathUploadStrategyMap;

        public void getFileInferStrategy(PathUpLoadMessage message, String strategy) throws IOException {
            pathUploadStrategyMap.get(IBaseEnum.getLabelByValue(strategy, PathUploadEnum.class)).upload(message,strategy);
        }

}

2、策略抽象实现类

代码语言:javascript
复制
/**
 * 服务器路径上传文件
 *
 * @author Eliauk
 * @since 2023/9/28 15:16
 */
@Service
public abstract class AbstractPathUploadStrategyImpl implements PathUploadStrategy {




    private final Logger LOG = LoggerFactory.getLogger(AbstractPathUploadStrategyImpl.class);

    @Override
    public void upload(PathUpLoadMessage message, String strategy) throws IOException {
        LOG.info("开始执行{}服务器路径上传策略", strategy);

        if (exist(message)){

            LOG.info("档号为{}的档案已经存在,跳过上传",message.getFileName());
            return;
        }

        uploadByPath(message, strategy);

    }

    /**
     * 服务器路径上传抽象方法
     * @param message 队列消息
     * @param strategy 路径上传策略
     * @since 2023/9/28 15:16
     */
    abstract void uploadByPath(PathUpLoadMessage message, String strategy) throws IOException;

    /**
     * 判断当前任务是否已经上传抽象方法
     * @param message 队列消息
     * @return
     * true:已经上传
     * false:未上传
     * @since 2023/9/28 15:16
     */
    abstract boolean exist(PathUpLoadMessage message);

    protected List<File> getAllPDFFiles(File rootFolder, List<String> legalSuffix) {
        List<File> pdfFiles = new ArrayList<>();
        if (rootFolder.isDirectory()) {
            File[] fileList = rootFolder.listFiles();
            if (fileList != null) {
                for (File file : fileList) {
                    if (file.isDirectory()) {
                        pdfFiles.addAll(getAllPDFFiles(file, legalSuffix));
                    } else if (file.isFile() && legalSuffix.contains(getFileExtension(file)) && !file.getName().startsWith("._")) {
                        pdfFiles.add(file);
                    }
                }
            }
        }
        return pdfFiles;
    }

    /**
     * 获取文件的后缀名
     */
    private static String getFileExtension(File file) {
        String fileName = file.getName();
        int dotIndex = fileName.lastIndexOf(".");
        if (dotIndex > 0 && dotIndex < fileName.length() - 1) {
            return fileName.substring(dotIndex + 1).toLowerCase();
        }
        return "";
    }
}

3、策略枚举类

代码语言:javascript
复制
/**
 * 服务器路径上传策略枚举
 *
 * @author Eliauk
 * @since 2023/9/28 14:32
 */
@Getter
@AllArgsConstructor
public enum PathUploadEnum implements IBaseEnum{

    VOLUME("案卷合并", "volumePathUploadStrategy"),

    PDF("PDF文件", "pdfPathUploadStrategy"),

    IMAGE_TO_PDF("合并图片文件","mergePicturePathUploadStrategy"),

    OFD("OFD文件", "ofdPathUploadStrategy");
    private final String value;
    private final String label;

    @Override
    public Object getValue() {
        return this.value;
    }

    @Override
    public String getLabel() {
        return this.label;
    }
}

4、实现类

1、 OdfPathUploadStrategyImpl

OFD转PDF工具源码

代码语言:javascript
复制
/**
 * OFD文件服务器路径上传
 *
 * @author Eliauk
 * @since 2023/10/10 9:58
 */
@Service("ofdPathUploadStrategy")
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class OdfPathUploadStrategyImpl extends AbstractPathUploadStrategyImpl{

    private static Logger LOG = LoggerFactory.getLogger(OdfPathUploadStrategyImpl.class);
    private final AppraisalFileRepository appraisalFileRepository;

    private final AppraisalFileService appraisalFileService;

    private final IOssEndPoint ossEndPoint;


    @Override
    void uploadByPath(PathUpLoadMessage message, String strategy) throws IOException {

        // 接收所有包含pdf的文件夹
        final File file = new File(message.getFile());
        final String folderName = file.getName();
        // 拿到任务ID
        final Long taskId = Convert.toLong(message.getTaskId());
        // 拿到租户ID
        final String tenantId = message.getTenantId();
        // 是否覆盖
        final Boolean overWrite = Convert.toBool(message.getOverWrite());
        LOG.info("当前进行服务器路径上传OFD的文件夹是{}", folderName);
        final List<File> pdfFiles = getAllPDFFiles(file, List.of("ofd"));
        long timeStart = DateUtil.current();
        long countStart = DateUtil.current();
        LOG.info("开始解析文件夹{},包含{}个OFD文件", folderName, pdfFiles.size());

        for (int fileIndex = 0; fileIndex < pdfFiles.size(); fileIndex++) {
            File ofdFile = pdfFiles.get(fileIndex);
            String fileName = ofdFile.getName();
            // 判断是否覆盖,如果覆盖就删除原文件,否则跳过
            List<AppraisalFile> existingFiles = appraisalFileRepository.findByTaskIdAndFileName(taskId, fileName);
            if (!existingFiles.isEmpty()) {
                if (overWrite) {
                    List<Long> existingIds = existingFiles.stream().map(AppraisalFile::getId).collect(Collectors.toList());
                    appraisalFileService.deleteExistingFiles(existingIds);
                } else {
                    LOG.info("已存在的文件将被跳过: {}", fileName);
                    continue;
                }
            }
            Attach ofdAttach = null;
            try {
                // 使用第一个 FileInputStream
                try (FileInputStream fileInputStream1 = new FileInputStream(ofdFile)) {
                    ofdAttach  = ossEndPoint.putAttachWithTenant(
                            new InMemoryMultipartFile(fileName, fileInputStream1),
                            tenantId
                    ).getData();
                }

                // 使用第二个 FileInputStream
                try (FileInputStream fileInputStream2 = new FileInputStream(ofdFile)) {
                    ByteArrayOutputStream stream = new ByteArrayOutputStream();
                    ConvertHelper.toPdf(fileInputStream2, stream);
                    Attach pdfAttach = ossEndPoint.putAttach(new InMemoryMultipartFile(IdUtil.randomUUID() + ".pdf", stream.toByteArray())
                    ).getData();

                    AppraisalFile appraisalFile = appraisalFileService.createAppraisalFile(taskId, fileName, pdfAttach);
                    appraisalFile.setOfdAttach(ofdAttach.getId());
                    appraisalFile.setFileType(InferFileType.OFD);
                    appraisalFileRepository.save(appraisalFile);

                    LOG.info("上传OFD成功所在文件夹名称{} - 当前进度: {}/{},文件名: {},共已耗时: {}s",file.getName(),
                            fileIndex+1, pdfFiles.size(), fileName, (DateUtil.current() - timeStart) / 1000.0);
                }
            } catch (Exception e) {
                LOG.error("上传文件发生异常: {}", e.getMessage());
            }

        }
        LOG.info("上传OFD成功 - 总文件数: {},耗时: {}s", pdfFiles.size(), (DateUtil.current() - countStart) / 1000.0);

    }

    @Override
    boolean exist(PathUpLoadMessage message) {
        return Boolean.FALSE;
    }
}

2、VolumePathUploadStrategyImpl

代码语言:javascript
复制
/**
 * 案卷合并服务器路径上传策略
 *
 * @author Eliauk
 * @since 2023/9/28 16:13
 */
@Service("volumePathUploadStrategy")
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class VolumePathUploadStrategyImpl extends AbstractPathUploadStrategyImpl {

    private static Logger LOG = LoggerFactory.getLogger(VolumePathUploadStrategyImpl.class);
    private final AppraisalFileRepository appraisalFileRepository;

    private final AppraisalFileService appraisalFileService;

    private final IOssEndPoint ossEndPoint;

    @Override
    void uploadByPath(PathUpLoadMessage message, String strategy) throws IOException {


        final File uploadFileFolder = new File(message.getFile());
        final Long taskId = Convert.toLong(message.getTaskId());
        final String tenantId = message.getTenantId();
        final Boolean overWrite = Convert.toBool(message.getOverWrite());

        File[] imageFiles = uploadFileFolder.listFiles();

        // 创建一个Map来存储文件名前缀和相应的文件列表
        Map<String, List<File>> groupedFiles = new HashMap<>();
        for (File imageFile : imageFiles) {
            String name = imageFile.getName();
            String prefix = name.substring(0, name.lastIndexOf('-')); // 假设前缀是直到最后一个'-'符号
            groupedFiles.computeIfAbsent(prefix, k -> new ArrayList<>()).add(imageFile);
        }

        LOG.info("开始处理文件夹名称为{}的文件夹,里边最终会合并成{}个文件",uploadFileFolder.getName(),groupedFiles.size());

        int pdfNum = 0;
        for (Map.Entry<String, List<File>> entry : groupedFiles.entrySet()) {
            String prefix = entry.getKey();
            List<File> filesInGroup = entry.getValue();

            String folderName = prefix;  // 你可以根据需要修改
            String fileName = folderName + ".pdf";
            //pathUpLoadProducer.syncSendPathUpload(tenantId,Convert.toStr(taskId),fileName,Convert.toStr(uploadFileFolder),Convert.toStr(overWrite),PathUploadType.PDF);
            // 判断是否覆盖已存在的文件
            List<AppraisalFile> existingFiles = appraisalFileRepository.findByTaskIdAndFileName(taskId, fileName);
            if (existingFiles.size() > 0) {
                if (overWrite) {
                    List<Long> existingFileIds = existingFiles.stream().map(AppraisalFile::getId).collect(Collectors.toList());
                    appraisalFileService.deleteExistingFiles(existingFileIds);
                } else {
                    LOG.info("跳过已存在的文件");
                    pdfNum++;
                    continue;
                }
            }

            List<byte[]> images = filesInGroup.stream()
                    .filter(File::isFile)
                    .map(imageFile -> {
                        try (InputStream fileInputStream = new FileInputStream(imageFile)) {
                            return IOUtils.toByteArray(fileInputStream);
                        } catch (IOException e) {
                            e.printStackTrace();
                            return null;
                        }
                    })
                    .filter(Objects::nonNull)
                    .collect(Collectors.toList());

            if (images.isEmpty()) {
                pdfNum++;
                LOG.info("跳过空文件夹");
                continue;
            }

            final byte[] bytes = appraisalFileService.convertToPdf(images);

            byte[] modifiedPdfData= null;
            try (PDDocument document = PDDocument.load(bytes)) {
                int lastPageNumber = document.getNumberOfPages();

                // 删除最后一页
                document.removePage(lastPageNumber - 1);

                // 保存修改后的PDF
                ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
                document.save(outputStream);
                modifiedPdfData = outputStream.toByteArray();


            } catch (IOException e) {
                // 处理PDF操作异常
                e.printStackTrace();
            }
            Attach pdfAttach = ossEndPoint.putAttachWithTenant(
                    new InMemoryMultipartFile(fileName, new ByteArrayInputStream(modifiedPdfData)),
                    tenantId
            ).getData();

            AppraisalFile appraisalFile = appraisalFileService.createAppraisalFile(taskId, fileName, pdfAttach);
            appraisalFileRepository.save(appraisalFile);

            pdfNum++;
            LOG.info("合并处理文件夹名称为{}的PDF成功,当前进度:{}/{},当前文件名:{},共{}页",
                    folderName,  pdfNum, groupedFiles.size(), folderName, images.size());
        }

    }

    @Override
    boolean exist(PathUpLoadMessage message) {
        return Boolean.FALSE;

    }


}

3、MergePicturePathUploadStrategyImpl

代码语言:javascript
复制
/**
 * 合并图片文件服务器路径上传策略
 *
 * @author Eliauk
 * @since 2023/10/7 16:32
 */
@Service("mergePicturePathUploadStrategy")
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class MergePicturePathUploadStrategyImpl extends AbstractPathUploadStrategyImpl {

    private static Logger LOG = LoggerFactory.getLogger(MergePicturePathUploadStrategyImpl.class);
    private final AppraisalFileRepository appraisalFileRepository;

    private final AppraisalFileService appraisalFileService;

    private final IOssEndPoint ossEndPoint;

    @Override
    void uploadByPath(PathUpLoadMessage message, String strategy) throws IOException {

        // 接收所有包含pdf的文件夹
        final File file = new File(message.getFile());
        final String folderName = file.getName();
        // 拿到任务ID
        final Long taskId = Convert.toLong(message.getTaskId());
        // 拿到租户ID
        final String tenantId = message.getTenantId();
        // 是否覆盖
        final Boolean overWrite = Convert.toBool(message.getOverWrite());
        LOG.info("当前进行服务器路径上传进行合并图片文件的文件夹是{}", folderName);

        final File[] imageFiles = file.listFiles();
        if (ObjectUtil.isNotEmpty(imageFiles)) {
            Arrays.sort(imageFiles, Comparator.comparing(File::getName));
        }

        String fileName = folderName + ".pdf";

        // 判断是否覆盖已存在的文件
        List<AppraisalFile> existingFiles = appraisalFileRepository.findByTaskIdAndFileName(taskId, fileName);
        if (!existingFiles.isEmpty()) {
            if (overWrite) {
                List<Long> existingFileIds = existingFiles.stream().map(AppraisalFile::getId).collect(Collectors.toList());
                appraisalFileService.deleteExistingFiles(existingFileIds);
            } else {
                LOG.info("跳过已存在的文件");
                return;
            }
        }


        if (ObjectUtil.isNotEmpty(imageFiles)) {
            Arrays.sort(imageFiles, Comparator.comparing(File::getName));
        }

        List<byte[]> images = Arrays.stream(imageFiles)
                .filter(File::isFile)
                .map(imageFile -> {
                    try (InputStream fileInputStream = new FileInputStream(imageFile)) {
                        return IOUtils.toByteArray(fileInputStream);
                    } catch (IOException e) {
                        e.printStackTrace();
                        return null;
                    }
                })
                .filter(Objects::nonNull)
                .collect(Collectors.toList());

        if (images.isEmpty()) {

            LOG.info("跳过空文件夹");
            return;
        }

        final byte[] bytes = appraisalFileService.convertToPdf(images);

        byte[] modifiedPdfData= null;
        try (PDDocument document = PDDocument.load(bytes)) {
            int lastPageNumber = document.getNumberOfPages();

            // 删除最后一页
            document.removePage(lastPageNumber - 1);

            // 保存修改后的PDF
            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
            document.save(outputStream);
            modifiedPdfData = outputStream.toByteArray();

        } catch (IOException e) {
            // 处理PDF操作异常
            e.printStackTrace();
        }
        Attach pdfAttach = ossEndPoint.putAttachWithTenant(
                new InMemoryMultipartFile(fileName, new ByteArrayInputStream(modifiedPdfData)),
                tenantId
        ).getData();

        AppraisalFile appraisalFile = appraisalFileService.createAppraisalFile(taskId, fileName, pdfAttach);
        appraisalFileRepository.save(appraisalFile);

        LOG.info("当前文件夹名称为{},当前文件名:{},共{}页", folderName ,fileName, images.size());


    }

    @Override
    boolean exist(PathUpLoadMessage message) {
        return Boolean.FALSE;
    }
}
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2023-10-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1、策略接口上下文
  • 2、策略抽象实现类
  • 3、策略枚举类
  • 4、实现类
    • 1、 OdfPathUploadStrategyImpl
      • 2、VolumePathUploadStrategyImpl
        • 3、MergePicturePathUploadStrategyImpl
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档