From ad935c07a6cabf05fed9c615c7bd4f67f6d65293 Mon Sep 17 00:00:00 2001
From: linwei <872216696@qq.com>
Date: Thu, 04 Jun 2026 23:37:33 +0800
Subject: [PATCH] feat(common): 添加通用列表类型处理器支持数据库存储
---
drone-ops/drone-resource/src/main/java/org/sxkj/resource/service/impl/AttachServiceImpl.java | 147 ++++++++++++++++++++++++++++++++++++++++++++++--
1 files changed, 140 insertions(+), 7 deletions(-)
diff --git a/drone-ops/drone-resource/src/main/java/org/sxkj/resource/service/impl/AttachServiceImpl.java b/drone-ops/drone-resource/src/main/java/org/sxkj/resource/service/impl/AttachServiceImpl.java
index b6f4ee4..0a4a1dd 100644
--- a/drone-ops/drone-resource/src/main/java/org/sxkj/resource/service/impl/AttachServiceImpl.java
+++ b/drone-ops/drone-resource/src/main/java/org/sxkj/resource/service/impl/AttachServiceImpl.java
@@ -23,6 +23,8 @@
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import io.minio.GetObjectArgs;
+import io.minio.MinioClient;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.annotations.Param;
@@ -41,6 +43,7 @@
import org.sxkj.common.enums.AttachResultTypeEnum;
import org.sxkj.common.enums.TypeOfOutcome;
import org.sxkj.common.func.Streams;
+import org.sxkj.common.model.ResponseResult;
import org.sxkj.common.query.PaginationUtils;
import org.sxkj.common.redis.RedisOpsUtils;
import org.sxkj.common.utils.*;
@@ -48,6 +51,7 @@
import org.sxkj.resource.builder.OssBuilder;
import org.sxkj.resource.dto.WaylineJobInfoQueryParam;
import org.sxkj.resource.entity.Attach;
+import org.sxkj.resource.entity.Oss;
import org.sxkj.resource.mapper.AttachMapper;
import org.sxkj.resource.model.FileMetadataDTO;
import org.sxkj.resource.model.MinioPojo;
@@ -63,6 +67,9 @@
import org.sxkj.tools.model.TifConvertResult;
import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
@@ -70,6 +77,9 @@
import java.util.concurrent.ExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
+import java.util.zip.Deflater;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipOutputStream;
/**
* 附件表 服务实现类
@@ -106,7 +116,12 @@
@Override
public IPage<AttachVO> selectAttachPage(IPage<AttachVO> page, AttachPageParam attach) {
- List<AttachVO> attachVOS = baseMapper.selectAttachPage(page, attach);
+ // 创建部门
+ if (!AuthUtil.isAdministrator()) {
+ List<Long> deptList = SysCache.getDeptChildIds(Long.valueOf(AuthUtil.getDeptId()));
+ attach.setDeptList(deptList);
+ }
+ List<AttachVO> attachVOS = baseMapper.selectAttachPage(page, attach);
return page.setRecords(attachVOS);
}
@@ -116,11 +131,11 @@
attach.setAreaCode(HeaderUtils.getAreaCodeHeaderAreaCode(attach.getAreaCode()));
if (Objects.isNull(attach.getResultTypes())) {
// 使用常量定义避免魔法数字
- attach.setResultTypes(Arrays.asList(TypeOfOutcome.IMAGE.getType(),
- TypeOfOutcome.VIDEO.getType(),
- TypeOfOutcome.AI.getType(),
- TypeOfOutcome.SURVEY.getType(),
- TypeOfOutcome.PANORAMA.getType()));
+ // attach.setResultTypes(Arrays.asList(TypeOfOutcome.IMAGE.getType(),
+ // TypeOfOutcome.VIDEO.getType(),
+ // TypeOfOutcome.AI.getType(),
+ // TypeOfOutcome.SURVEY.getType(),
+ // TypeOfOutcome.PANORAMA.getType()));
}
List<Long> deptIdList = SysCache.getDeptChildIds(Long.valueOf(AuthUtil.getDeptId()));
String permissionCondition = permissionBuilder.buildDataPermissionCondition(AuthUtil.getUserId(), "attach");
@@ -520,7 +535,6 @@
@Override
public Long findResultNumByJobId(String jobId) {
return baseMapper.selectCount(Wrappers.<Attach>lambdaQuery()
- .eq(Attach::getIsGenerateAiImg, 0)
.eq(Attach::getIsDeleted, 0)
.eq(Attach::getPatrolTaskId, jobId).in(Attach::getResultType, AttachResultTypeEnum.getTheAttachmentType()));
}
@@ -770,4 +784,123 @@
return attachTypeStatisticsVOS;
}
+ /**
+ * 下载附件
+ *
+ * @param param 下载参数
+ * @param outputStream 输出流
+ * @return 下载是否成功
+ * @throws IOException IO异常
+ */
+ @Override
+ public Boolean downloadByByte(String param, OutputStream outputStream) throws IOException {
+ // 步骤1:构建下载参数并获取附件列表
+ AttachmentDownloadParam attachmentDownloadParam = new AttachmentDownloadParam();
+ attachmentDownloadParam.setAttachIds(Func.toLongList(param));
+ List<AttachVO> attachList = getAttachList(attachmentDownloadParam);
+ if (CollectionUtils.isEmpty(attachList)) {
+ return false;
+ }
+
+ // 步骤2:获取当前租户ID
+ String tenantId = AuthUtil.getTenantId();
+ if (StringUtils.isBlank(tenantId)) {
+ tenantId = "000000";
+ }
+
+ // 步骤3:通过OssBuilder获取OSS配置
+ Oss oss = ossBuilder.getOss(tenantId, "");
+
+ try {
+ // 步骤4:创建ZipOutputStream并设置压缩级别
+ ZipOutputStream zos = new ZipOutputStream(outputStream);
+ zos.setLevel(Deflater.BEST_SPEED);
+
+ // 步骤5:设置缓冲区大小
+ final int BUFFER_SIZE = 1024 * 1024;
+ byte[] buffer = new byte[BUFFER_SIZE];
+
+ // 步骤6:根据OSS配置创建MinioClient
+ MinioClient minioClient = MinioClient.builder()
+ .endpoint(oss.getEndpoint())
+ .credentials(oss.getAccessKey(), oss.getSecretKey())
+ .build();
+
+ // 步骤7:创建文件名集合用于去重
+ Set<String> usedFileNames = new HashSet<>();
+
+ // 步骤8:遍历附件列表,逐个下载并打包
+ for (AttachVO attachVO : attachList) {
+ String objectName = attachVO.getName();
+ try {
+ // 步骤8.1:从MinIO获取文件流
+ InputStream is = minioClient.getObject(
+ GetObjectArgs.builder()
+ .bucket(oss.getBucketName())
+ .object(objectName)
+ .build());
+
+ // 步骤8.2:提取文件名(不包含路径)
+ String fileName = objectName.substring(objectName.lastIndexOf("/") + 1);
+
+ // 步骤8.3:处理文件名冲突
+ String uniqueFileName = fileName;
+ int counter = 1;
+ while (usedFileNames.contains(uniqueFileName)) {
+ int dotIndex = fileName.lastIndexOf(".");
+ if (dotIndex > 0) {
+ uniqueFileName = fileName.substring(0, dotIndex) + "_" + counter + fileName.substring(dotIndex);
+ } else {
+ uniqueFileName = fileName + "_" + counter;
+ }
+ counter++;
+ }
+
+ // 步骤8.4:记录已使用的文件名
+ usedFileNames.add(uniqueFileName);
+
+ // 步骤8.5:创建ZIP条目并写入文件内容
+ ZipEntry zipEntry = new ZipEntry(uniqueFileName);
+ zos.putNextEntry(zipEntry);
+
+ int length;
+ while ((length = is.read(buffer)) > 0) {
+ zos.write(buffer, 0, length);
+ zos.flush();
+ }
+
+ // 步骤8.6:关闭当前条目和输入流
+ zos.closeEntry();
+ is.close();
+ } catch (Exception e) {
+ log.error("处理文件 {} 失败: {}", objectName, e.getMessage());
+ }
+ }
+
+ // 步骤9:完成ZIP文件写入
+ zos.finish();
+ zos.flush();
+
+ return true;
+
+ } catch (Exception e) {
+ log.error("创建zip文件失败", e);
+ return false;
+ } finally {
+ // 步骤10:确保输出流被正确关闭
+ if (outputStream != null) {
+ try {
+ outputStream.flush();
+ } catch (IOException e) {
+ log.error("Error flushing output stream: {}", e.getMessage());
+ }
+ try {
+ outputStream.close();
+ } catch (IOException e) {
+ log.error("Error closing output stream: {}", e.getMessage());
+ }
+ }
+ }
+ }
+
}
--
Gitblit v1.9.3