Redis-5-doFormatAsync()方法

FormatService.doFormatAsync()

异步执行排版任务,处理排版全流程:该方法被标记为 @Async("notificationExecutor"),表示它会在单独的线程中异步执行,避免阻塞主线程;包括文件下载、排版处理、文件上传、状态更新等完整流程。
业务流程:初始化与前置校验 -- 文件保存到临时目录 -- 调用外部排版服务 -- 清理"排版中"状态 -- 上传排版结果 -- 保存结果到 Redis -- 更新数据库状态

java 复制代码
@Async("notificationExecutor")
public void doFormatAsync(Integer styleId, Integer formId, String sourceNodeId, String fileId, String fileName, Long userId, String taskKey) {
   // 临时文件路径,用于最后清理
   String tempFilePath = null;

   try {
       // 1. 初始化与前置校验: 校验原文件是否存在且未被删除。若校验失败,则保存失败状态并清理任务状态。
       KbNode sourceNode = kbNodeMapper.selectById(sourceNodeId);
       if (sourceNode == null || sourceNode.getDeleted() == 1) {
           log.error("FormatService##doFormatAsync-0,排版任务失败,原文件节点不存在,sourceNodeId={}", sourceNodeId);
           saveFailedResultItem(sourceNodeId, fileName, userId);
           stringRedisTemplate.delete(taskKey);
           return;
       }
       // 如果原文件有父节点则使用父节点,否则说明在根目录,使用原文件所属的根节点(通过查询获取)
       String folderNodeId = StringUtils.hasText(sourceNode.getParentId()) ? sourceNode.getParentId(): sourceNodeId;  // 根目录下的文件,暂时使用原nodeId,实际部署时可能需要调整
       FileBean fileBean = fileBeanService.getById(fileId);// 从file表(db2)查询文件信息
       if (fileBean == null || !StringUtils.hasText(fileBean.getFileUrl())) {
           log.info("FormatService##doFormatAsync-1,排版任务失败,文件不存在,fileId={}", fileId);
           // 保存失败状态的结果项
           saveFailedResultItem(sourceNodeId, fileName, userId);
           stringRedisTemplate.delete(taskKey);
           return;
       }

       // 2. 文件下载与临时存储:将原始文件从存储系统下载到本地临时目录。
       // 使用 saveFileToTemp 方法构建临时路径并复制文件。若下载失败,则记录失败状态并退出.
       tempFilePath = saveFileToTemp(fileBean.getFileUrl(), fileName);
       if (tempFilePath == null) {
           log.error("FormatService##doFormatAsync-2,排版任务失败,文件保存到临时目录失败,fileUrl={}", fileBean.getFileUrl());
           saveFailedResultItem(sourceNodeId, fileName, userId);
           stringRedisTemplate.delete(taskKey);
           return;
       }

       // 3. 调用外部排版服务:调用公文排版服务生成排版后的文件(PDF 和 Word)。
       // callExternalFormatService中:读取临时文件内容。根据styleId选择模板。调用 govdocFormatterService.format() 执行排版。将排版结果保存到临时目录。
       FormatCallbackResult callbackResult = callExternalFormatService(styleId, tempFilePath);
       if (callbackResult == null || !callbackResult.isSuccess()) {
           log.error("FormatService##doFormatAsync-4,排版任务失败,外部排版接口调用失败,sourceNodeId={}", sourceNodeId);
           saveFailedResultItem(sourceNodeId, fileName, userId);
           stringRedisTemplate.delete(taskKey);
           return;
       }

       // 4. 删除"排版中"状态的临时结果项:清除任务启动时插入的"排版中"状态项,排版完成或失败时调用。
       removeFormattingResultItem(sourceNodeId, userId);

       // 5. 上传排版结果文件:将排版后的文件上传至文件服务器,并生成新的 nodeId,并保存结果。
       // 分别处理PDF和Word文件、调用uploadSingleFile方法上传文件、FormatResultItem对象保存结果信息
       List<FormatResultItem> resultItems = uploadFormattedFiles(callbackResult, sourceNodeId, fileName, userId, folderNodeId);

       // 6. 保存每个结果项到 Redis,将排版结果持久化到 Redis 中,供前端查询。
       // 使用 FORMAT_ITEM_KEY_PREFIX 保存结果项详情。建立用户、原文件与结果文件之间的映射关系.
       for (FormatResultItem item : resultItems) {
           saveResultItem(item, userId, sourceNodeId);
       }

       // 7. 删除任务状态标识并清理临时文件目录(表示任务完成)
       stringRedisTemplate.delete(taskKey);
   // 捕获所有异常(包括Error和Exception),确保任务失败时能正确记录状态并释放资源。
   } catch (Throwable e) {
       log.error("FormatService##doFormatAsync-e,排版任务异常,userId={}, sourceNodeId={}", userId, sourceNodeId, e);
       // 删除"排版中"的临时结果项
       removeFormattingResultItem(sourceNodeId, userId);
       saveFailedResultItem(sourceNodeId, fileName, userId);
       stringRedisTemplate.delete(taskKey);
   } finally {
       // 7. 清理临时文件目录(无论成功或失败都要清理)
       cleanupTempDirectory(tempFilePath);
   }
}
相关推荐
生产队队长2 小时前
Redis:Windows环境安装Redis,并将 Redis 进程注册为服务
数据库·redis·缓存
老邓计算机毕设2 小时前
SSM找学互助系统52568(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面
数据库·ssm 框架·javaweb 毕业设计
痴儿哈哈2 小时前
自动化机器学习(AutoML)库TPOT使用指南
jvm·数据库·python
Σίσυφος19002 小时前
PCL法向量估计 之 方向约束法向量(Orientation Guided Normal)
数据库
Porco.w2 小时前
C#与三菱PLC FX5U通信
网络·c#
老毛肚2 小时前
手写mybatis
java·数据库·mybatis
海山数据库2 小时前
移动云大云海山数据库(He3DB)postgresql_anonymizer插件原理介绍与安装
数据库·he3db·大云海山数据库·移动云数据库
云飞云共享云桌面3 小时前
高性能图形工作站的资源如何共享给10个SolidWorks研发设计用
linux·运维·服务器·前端·网络·数据库·人工智能
2501_927993533 小时前
SQL Server 2022安装详细教程(图文详解,非常详细)
数据库·sqlserver