fix: 保存草稿优化
This commit is contained in:
parent
03f2e1c669
commit
28e53119a1
@ -2,6 +2,7 @@ package com.yfd.platform.config;
|
||||
|
||||
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
|
||||
import com.yfd.platform.utils.SecurityUtils;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.ibatis.reflection.MetaObject;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@ -12,6 +13,7 @@ import java.util.Date;
|
||||
* 用于处理 @TableField(fill = FieldFill.INSERT/UPDATE) 注解
|
||||
*/
|
||||
@Component
|
||||
@Slf4j
|
||||
public class MyMetaObjectHandler implements MetaObjectHandler {
|
||||
|
||||
|
||||
@ -35,7 +37,7 @@ public class MyMetaObjectHandler implements MetaObjectHandler {
|
||||
// 自动填充更新时间
|
||||
this.strictInsertFill(metaObject, "updatedBy", String.class, userId);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
log.info("message{}",e.getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
@ -52,7 +54,7 @@ public class MyMetaObjectHandler implements MetaObjectHandler {
|
||||
// 自动填充更新人
|
||||
this.strictInsertFill(metaObject, "updatedBy", String.class, userId);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
log.info("message{}",e.getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -33,6 +33,8 @@ import jakarta.annotation.Resource;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.security.core.context.SecurityContext;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
@ -137,19 +139,15 @@ public class FishDraftDataController {
|
||||
ImportTask importTask = importTaskService.getById(taskId);
|
||||
String resultJson = importTask.getResultJson();
|
||||
FishImportResult importResult = null;
|
||||
log.info("==============批量保存草稿================: {}", taskId);
|
||||
Map<String, String> imageFiles = null;
|
||||
Map<String, String> videoFiles = null;
|
||||
if (resultJson != null && !resultJson.isEmpty()) {
|
||||
try {
|
||||
importResult = objectMapper.readValue(resultJson, FishImportResult.class);
|
||||
ZipFileUtil.ZipContent content = new ZipFileUtil.ZipContent();
|
||||
content.images = importResult.getImageFiles();
|
||||
content.videos = importResult.getVideoFiles();
|
||||
log.info("==============processAttachments前================: {}", taskId);
|
||||
fishImportService.processAttachments(importResult, content);
|
||||
log.info("==============processAttachments后================: {}", taskId);
|
||||
imageFiles = importResult.getImageFiles();
|
||||
videoFiles = importResult.getVideoFiles();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
// ignore parse error
|
||||
}
|
||||
}
|
||||
|
||||
@ -169,6 +167,7 @@ public class FishDraftDataController {
|
||||
fishDraftDataList.add(data);
|
||||
}
|
||||
boolean result = fishDraftDataService.saveBatch(fishDraftDataList);
|
||||
fishImportService.processAttachmentsAsync(fishDraftDataList, imageFiles, videoFiles,importTask.getTempDir());
|
||||
importTaskService.markSuccess(taskId);
|
||||
return result ? ResponseResult.success("保存成功") : ResponseResult.error("保存失败");
|
||||
}
|
||||
@ -392,9 +391,10 @@ public class FishDraftDataController {
|
||||
task.setTempDir(tempDirPath.toString());
|
||||
importTaskService.save(task);
|
||||
log.info("导入任务已创建: {}", taskId);
|
||||
|
||||
SecurityContext securityContext = SecurityContextHolder.getContext();
|
||||
CompletableFuture.runAsync(() -> {
|
||||
try {
|
||||
SecurityContextHolder.setContext(securityContext);
|
||||
log.info("异步开始解析ZIP文件, taskId: {}", taskId);
|
||||
FishImportResult result = fishImportService.parseAndMapZipFromFile(
|
||||
savedZipFile, tempDirPath.toString(), uploadUserId);
|
||||
@ -413,6 +413,7 @@ public class FishDraftDataController {
|
||||
log.error("异步解析ZIP失败, taskId: {}", taskId, e);
|
||||
importTaskService.markFailed(taskId, "导入失败: " + e.getMessage());
|
||||
} finally {
|
||||
SecurityContextHolder.clearContext();
|
||||
if (savedZipFile.exists()) {
|
||||
savedZipFile.delete();
|
||||
}
|
||||
|
||||
@ -38,6 +38,10 @@ public class AttachmentUploadService {
|
||||
@Value("${attachment.video-url}")
|
||||
private String videoUrl;
|
||||
|
||||
@Value("${attachment.delete-url}")
|
||||
private String deleteUrl;
|
||||
// private static final String DELETE_URL = "https://211.99.26.225:12125/FileDelete";
|
||||
|
||||
private static final ExecutorService UPLOAD_EXECUTOR = new ThreadPoolExecutor(
|
||||
5, 10, 60L, TimeUnit.SECONDS, new LinkedBlockingQueue<>(100),
|
||||
new ThreadPoolExecutor.CallerRunsPolicy()
|
||||
@ -313,7 +317,55 @@ public class AttachmentUploadService {
|
||||
}
|
||||
}
|
||||
|
||||
private static final String DELETE_URL = "https://211.99.26.225:12125/FileDelete";
|
||||
|
||||
|
||||
// public boolean deleteFile(String attachmentId) {
|
||||
// if (attachmentId == null || attachmentId.isEmpty()) {
|
||||
// log.warn("附件ID为空");
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// try {
|
||||
// TrustManager[] trustAllCerts = new TrustManager[]{
|
||||
// new X509TrustManager() {
|
||||
// public void checkClientTrusted(X509Certificate[] chain, String authType) {}
|
||||
// public void checkServerTrusted(X509Certificate[] chain, String authType) {}
|
||||
// public X509Certificate[] getAcceptedIssuers() { return new X509Certificate[0]; }
|
||||
// }
|
||||
// };
|
||||
//
|
||||
// SSLContext sc = SSLContext.getInstance("TLS");
|
||||
// sc.init(null, trustAllCerts, new SecureRandom());
|
||||
//
|
||||
// HttpClient secureClient = HttpClient.newBuilder()
|
||||
// .sslContext(sc)
|
||||
// .build();
|
||||
//
|
||||
// String formData = "fileId=" + attachmentId;
|
||||
//
|
||||
// HttpRequest request = HttpRequest.newBuilder()
|
||||
// .uri(URI.create(deleteUrl))
|
||||
// .header("Content-Type", "application/x-www-form-urlencoded")
|
||||
// .header("token", token)
|
||||
// .POST(HttpRequest.BodyPublishers.ofString(formData))
|
||||
// .build();
|
||||
//
|
||||
// HttpResponse<String> response = secureClient.send(request, HttpResponse.BodyHandlers.ofString());
|
||||
//
|
||||
// if (response.statusCode() == 200) {
|
||||
// String responseBody = response.body();
|
||||
// return parseDeleteResult(responseBody);
|
||||
// } else {
|
||||
// log.error("删除附件失败: {}, 状态码: {}", attachmentId, response.statusCode());
|
||||
// return false;
|
||||
// }
|
||||
// } catch (Exception e) {
|
||||
// log.error("删除附件过程中发生异常: {}", attachmentId, e);
|
||||
// return false;
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
|
||||
public boolean deleteFile(String attachmentId) {
|
||||
if (attachmentId == null || attachmentId.isEmpty()) {
|
||||
@ -322,31 +374,16 @@ public class AttachmentUploadService {
|
||||
}
|
||||
|
||||
try {
|
||||
TrustManager[] trustAllCerts = new TrustManager[]{
|
||||
new X509TrustManager() {
|
||||
public void checkClientTrusted(X509Certificate[] chain, String authType) {}
|
||||
public void checkServerTrusted(X509Certificate[] chain, String authType) {}
|
||||
public X509Certificate[] getAcceptedIssuers() { return new X509Certificate[0]; }
|
||||
}
|
||||
};
|
||||
|
||||
SSLContext sc = SSLContext.getInstance("TLS");
|
||||
sc.init(null, trustAllCerts, new SecureRandom());
|
||||
|
||||
HttpClient secureClient = HttpClient.newBuilder()
|
||||
.sslContext(sc)
|
||||
.build();
|
||||
|
||||
String formData = "fileId=" + attachmentId;
|
||||
|
||||
HttpRequest request = HttpRequest.newBuilder()
|
||||
.uri(URI.create(DELETE_URL))
|
||||
.uri(URI.create(deleteUrl))
|
||||
.header("Content-Type", "application/x-www-form-urlencoded")
|
||||
.header("token", token)
|
||||
.POST(HttpRequest.BodyPublishers.ofString(formData))
|
||||
.build();
|
||||
|
||||
HttpResponse<String> response = secureClient.send(request, HttpResponse.BodyHandlers.ofString());
|
||||
HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
|
||||
|
||||
if (response.statusCode() == 200) {
|
||||
String responseBody = response.body();
|
||||
@ -361,6 +398,7 @@ public class AttachmentUploadService {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private boolean parseDeleteResult(String jsonResponse) {
|
||||
if (jsonResponse == null || jsonResponse.isEmpty()) {
|
||||
return false;
|
||||
|
||||
@ -51,4 +51,9 @@ public interface IFishImportService {
|
||||
boolean validateFpssBelongsToStation(String fpssCode, String stationCode);
|
||||
|
||||
void processAttachments(FishImportResult result, ZipFileUtil.ZipContent zipContent);
|
||||
|
||||
void processAttachmentsAsync(java.util.List<com.yfd.platform.data.domain.FishDraftData> dataList,
|
||||
java.util.Map<String, String> imageFiles,
|
||||
java.util.Map<String, String> videoFiles,
|
||||
String tempDir);
|
||||
}
|
||||
@ -1,5 +1,6 @@
|
||||
package com.yfd.platform.data.service.impl;
|
||||
|
||||
import cn.hutool.core.io.FileUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.yfd.platform.data.domain.FishDraftData;
|
||||
@ -8,6 +9,7 @@ import com.yfd.platform.data.domain.FishImportResult;
|
||||
import com.yfd.platform.data.domain.SysUserDataScope;
|
||||
import com.yfd.platform.data.mapper.SysUserDataScopeMapper;
|
||||
import com.yfd.platform.data.service.AttachmentUploadService;
|
||||
import com.yfd.platform.data.service.IFishDraftDataService;
|
||||
import com.yfd.platform.data.service.IFishImportService;
|
||||
import com.yfd.platform.data.utils.ZipFileUtil;
|
||||
import com.yfd.platform.env.domain.*;
|
||||
@ -19,6 +21,8 @@ import jakarta.annotation.Resource;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.poi.ss.usermodel.*;
|
||||
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
||||
import org.springframework.security.core.context.SecurityContext;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
@ -31,6 +35,7 @@ import java.math.BigDecimal;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
@Service
|
||||
@Slf4j
|
||||
@ -63,6 +68,9 @@ public class FishImportServiceImpl implements IFishImportService {
|
||||
@Resource
|
||||
private AttachmentUploadService attachmentUploadService;
|
||||
|
||||
@Resource
|
||||
private IFishDraftDataService fishDraftDataService;
|
||||
|
||||
@Resource
|
||||
private SysUserDataScopeMapper userDataScopeMapper;
|
||||
|
||||
@ -1283,6 +1291,118 @@ public class FishImportServiceImpl implements IFishImportService {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processAttachmentsAsync(List<FishDraftData> dataList,
|
||||
Map<String, String> imageFiles,
|
||||
Map<String, String> videoFiles,
|
||||
String tempDir) {
|
||||
if (dataList == null || dataList.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
List<CompletableFuture<Void>> futures = new ArrayList<>();
|
||||
SecurityContext securityContext = SecurityContextHolder.getContext();
|
||||
for (FishDraftData data : dataList) {
|
||||
CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
|
||||
try {
|
||||
SecurityContextHolder.setContext(securityContext);
|
||||
String vdpth = data.getVdpth();
|
||||
String picpth = data.getPicpth();
|
||||
|
||||
if(StrUtil.isBlank(vdpth)||StrUtil.isBlank(picpth)){
|
||||
log.error("数据不完整, 忽略处理");
|
||||
return;
|
||||
}
|
||||
if (StringUtils.hasText(vdpth) && videoFiles != null && !videoFiles.isEmpty()) {
|
||||
String uploadedVdpth = uploadVideoFilesAsync(vdpth, videoFiles);
|
||||
if (uploadedVdpth != null) {
|
||||
data.setVdpth(uploadedVdpth);
|
||||
}
|
||||
}
|
||||
|
||||
if (StringUtils.hasText(picpth) && imageFiles != null && !imageFiles.isEmpty()) {
|
||||
String uploadedPicpth = uploadImageFilesAsync(picpth, imageFiles);
|
||||
if (uploadedPicpth != null) {
|
||||
data.setPicpth(uploadedPicpth);
|
||||
}
|
||||
}
|
||||
|
||||
fishDraftDataService.updateById(data);
|
||||
log.info("异步上传附件完成, dataId: {},{},{}", data.getId(), data.getPicpth(), data.getVdpth());
|
||||
} catch (Exception e) {
|
||||
log.error("异步上传附件失败, dataId: {}", data.getId(), e);
|
||||
} finally {
|
||||
SecurityContextHolder.clearContext();
|
||||
}
|
||||
});
|
||||
futures.add(future);
|
||||
}
|
||||
CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]))
|
||||
.thenRun(() -> {
|
||||
|
||||
try {
|
||||
// del 方法会递归删除目录及其所有内容
|
||||
FileUtil.del(tempDir);
|
||||
} catch (Exception e) {
|
||||
log.error("删除临时目录失败{}", e.getMessage());
|
||||
}
|
||||
|
||||
})
|
||||
.exceptionally(ex -> {
|
||||
log.error("等待异步任务完成时发生异常", ex);
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
private String uploadVideoFilesAsync(String videoNames, Map<String, String> videoMap) {
|
||||
String[] fileNames = videoNames.split(";");
|
||||
List<String> attachmentIds = new ArrayList<>();
|
||||
|
||||
for (String fileName : fileNames) {
|
||||
fileName = fileName.trim();
|
||||
if (fileName.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
String actualPath = findFilePath(fileName, videoMap);
|
||||
if (actualPath != null) {
|
||||
try {
|
||||
String attachmentId = attachmentUploadService.uploadFileAndGetId(actualPath);
|
||||
if (attachmentId != null) {
|
||||
attachmentIds.add(attachmentId);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("上传视频失败: {}", fileName, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return attachmentIds.isEmpty() ? videoNames : String.join(",", attachmentIds);
|
||||
}
|
||||
|
||||
private String uploadImageFilesAsync(String imageNames, Map<String, String> imageMap) {
|
||||
String[] fileNames = imageNames.split(";");
|
||||
List<String> attachmentIds = new ArrayList<>();
|
||||
|
||||
for (String fileName : fileNames) {
|
||||
fileName = fileName.trim();
|
||||
if (fileName.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
String actualPath = findFilePath(fileName, imageMap);
|
||||
if (actualPath != null) {
|
||||
try {
|
||||
String attachmentId = attachmentUploadService.uploadFileAndGetId(actualPath);
|
||||
if (attachmentId != null) {
|
||||
attachmentIds.add(attachmentId);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("上传图片失败: {}", fileName, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return attachmentIds.isEmpty() ? imageNames : String.join(",", attachmentIds);
|
||||
}
|
||||
|
||||
private String processVideoAttachments(FishImportResult.FishImportRow importRow, String videoNames, Map<String, String> videoMap) {
|
||||
if (videoNames == null || videoNames.isEmpty() || videoMap == null || videoMap.isEmpty()) {
|
||||
return videoNames;
|
||||
|
||||
@ -140,19 +140,6 @@ public class ImportTaskServiceImpl extends ServiceImpl<ImportTaskMapper, ImportT
|
||||
importTask.setStatus("CONFIRMED");
|
||||
importTask.setUpdatedAt(new Date());
|
||||
boolean b = this.updateById(importTask);
|
||||
// 删除本地临时目录数据
|
||||
String resultJson = importTask.getResultJson();
|
||||
if (resultJson != null && !resultJson.isEmpty()) {
|
||||
try {
|
||||
FishImportResult importResult = objectMapper.readValue(resultJson, FishImportResult.class);
|
||||
String tempDir = importResult.getTempDir();
|
||||
// del 方法会递归删除目录及其所有内容
|
||||
FileUtil.del(tempDir);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
// ignore parse error
|
||||
}
|
||||
}
|
||||
return b;
|
||||
}
|
||||
|
||||
|
||||
@ -122,5 +122,6 @@ attachment:
|
||||
token: ${ATTACHMENT_TOKEN:qgcBkod25ngBa4wu8BtfCPYsJ7lQGVDoexH}
|
||||
upload-url: ${ATTACHMENT_UPLOAD_URL:http://172.16.31.185:18200/upload}
|
||||
video-url: ${ATTACHMENT_VIDEO_URL:http://172.16.31.185:18200/upload}
|
||||
delete-url: ${ATTACHMENT_DELETE_URL:http://172.16.31.185:18200/delete}
|
||||
# upload-url: ${ATTACHMENT_UPLOAD_URL:https://211.99.26.225:12125/upload}
|
||||
# video-url: ${ATTACHMENT_VIDEO_URL:https://211.99.26.225:12125/upload}
|
||||
@ -122,3 +122,4 @@ attachment:
|
||||
token: ${ATTACHMENT_TOKEN:qgcBkod25ngBa4wu8BtfCPYsJ7lQGVDoexH}
|
||||
upload-url: ${ATTACHMENT_UPLOAD_URL:http://172.16.31.185:18200/upload}
|
||||
video-url: ${ATTACHMENT_VIDEO_URL:http://172.16.31.185:18200/upload}
|
||||
delete-url: ${ATTACHMENT_DELETE_URL:http://172.16.31.185:18200/delete}
|
||||
Loading…
Reference in New Issue
Block a user