完成后端架构重构等
This commit is contained in:
+31
-7
@@ -8,7 +8,7 @@ import com.nanri.aiimage.modules.patroldelete.model.vo.PatrolDeleteResultItemVo;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.poi.ss.usermodel.Row;
|
||||
import org.apache.poi.ss.usermodel.Sheet;
|
||||
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
||||
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.io.File;
|
||||
@@ -40,8 +40,9 @@ public class PatrolDeleteExcelAssemblyService {
|
||||
};
|
||||
|
||||
public void writeWorkbook(File outputXlsx, List<PatrolDeleteResultItemVo> items) {
|
||||
try (XSSFWorkbook workbook = new XSSFWorkbook();
|
||||
FileOutputStream outputStream = new FileOutputStream(outputXlsx)) {
|
||||
SXSSFWorkbook workbook = new SXSSFWorkbook(200);
|
||||
workbook.setCompressTempFiles(true);
|
||||
try (FileOutputStream outputStream = new FileOutputStream(outputXlsx)) {
|
||||
Sheet sheet = workbook.createSheet("巡店删除结果");
|
||||
Row headerRow = sheet.createRow(0);
|
||||
for (int columnIndex = 0; columnIndex < HEADER.length; columnIndex++) {
|
||||
@@ -73,13 +74,17 @@ public class PatrolDeleteExcelAssemblyService {
|
||||
rowIndex++;
|
||||
}
|
||||
|
||||
for (int columnIndex = 0; columnIndex < HEADER.length; columnIndex++) {
|
||||
sheet.autoSizeColumn(columnIndex);
|
||||
}
|
||||
applyDefaultColumnWidths(sheet);
|
||||
workbook.write(outputStream);
|
||||
} catch (Exception ex) {
|
||||
log.warn("[patrol-delete] write workbook failed: {}", ex.getMessage());
|
||||
throw new BusinessException("生成巡店删除结果 Excel 失败: " + ex.getMessage());
|
||||
throw new BusinessException("generate patrol-delete excel failed: " + ex.getMessage());
|
||||
} finally {
|
||||
try {
|
||||
workbook.close();
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
workbook.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -141,4 +146,23 @@ public class PatrolDeleteExcelAssemblyService {
|
||||
private String safe(String value) {
|
||||
return value == null ? "" : value;
|
||||
}
|
||||
|
||||
private void applyDefaultColumnWidths(Sheet sheet) {
|
||||
int[] widths = {
|
||||
20,
|
||||
14, 10, 12, 16,
|
||||
14, 10, 12, 16,
|
||||
14, 10, 12, 16,
|
||||
14, 10, 12, 16,
|
||||
14, 10, 12, 16,
|
||||
10, 16,
|
||||
10, 16,
|
||||
10, 16,
|
||||
10, 16,
|
||||
10, 16
|
||||
};
|
||||
for (int i = 0; i < widths.length; i++) {
|
||||
sheet.setColumnWidth(i, widths[i] * 256);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+11
-55
@@ -1,10 +1,10 @@
|
||||
package com.nanri.aiimage.modules.patroldelete.service;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.nanri.aiimage.common.exception.BusinessException;
|
||||
import com.nanri.aiimage.config.TaskPressureProperties;
|
||||
import com.nanri.aiimage.modules.patroldelete.model.dto.PatrolDeleteShopPayloadDto;
|
||||
import com.nanri.aiimage.modules.task.model.entity.FileTaskEntity;
|
||||
import com.nanri.aiimage.modules.task.service.TaskScopePayloadStorageService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||
import org.springframework.stereotype.Service;
|
||||
@@ -20,80 +20,40 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||
@RequiredArgsConstructor
|
||||
public class PatrolDeleteTaskCacheService {
|
||||
|
||||
private static final String MODULE_TYPE = "PATROL_DELETE";
|
||||
private static final long PAYLOAD_TTL_HOURS = 24;
|
||||
private final StringRedisTemplate stringRedisTemplate;
|
||||
private final ObjectMapper objectMapper;
|
||||
private final TaskPressureProperties taskPressureProperties;
|
||||
private final TaskScopePayloadStorageService taskScopePayloadStorageService;
|
||||
private final ConcurrentHashMap<Long, LocalTaskEntityCacheEntry> taskEntityLocalCache = new ConcurrentHashMap<>();
|
||||
|
||||
public PatrolDeleteShopPayloadDto getShopMergedPayload(Long taskId, String shopKey) {
|
||||
if (taskId == null || taskId <= 0 || shopKey == null || shopKey.isBlank()) {
|
||||
return null;
|
||||
}
|
||||
Object raw = stringRedisTemplate.opsForHash().get(buildShopPayloadKey(taskId), shopKey);
|
||||
if (!(raw instanceof String json) || json.isBlank()) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return objectMapper.readValue(json, PatrolDeleteShopPayloadDto.class);
|
||||
} catch (Exception ex) {
|
||||
throw new BusinessException("读取巡店删除店铺缓存失败");
|
||||
}
|
||||
return taskScopePayloadStorageService.getScopePayload(taskId, MODULE_TYPE, shopKey, PatrolDeleteShopPayloadDto.class);
|
||||
}
|
||||
|
||||
public void saveShopMergedPayload(Long taskId, String shopKey, PatrolDeleteShopPayloadDto payload) {
|
||||
if (taskId == null || taskId <= 0 || shopKey == null || shopKey.isBlank() || payload == null) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
stringRedisTemplate.opsForHash().put(buildShopPayloadKey(taskId), shopKey, objectMapper.writeValueAsString(payload));
|
||||
stringRedisTemplate.expire(buildShopPayloadKey(taskId), Duration.ofHours(PAYLOAD_TTL_HOURS));
|
||||
touchTaskHeartbeat(taskId);
|
||||
} catch (Exception ex) {
|
||||
throw new BusinessException("暂存巡店删除店铺缓存失败");
|
||||
}
|
||||
taskScopePayloadStorageService.saveScopePayload(taskId, MODULE_TYPE, shopKey, payload);
|
||||
touchTaskHeartbeat(taskId);
|
||||
}
|
||||
|
||||
public void removeShopMergedPayload(Long taskId, String shopKey) {
|
||||
if (taskId == null || taskId <= 0 || shopKey == null || shopKey.isBlank()) {
|
||||
return;
|
||||
}
|
||||
stringRedisTemplate.opsForHash().delete(buildShopPayloadKey(taskId), shopKey);
|
||||
taskScopePayloadStorageService.removeScopePayload(taskId, MODULE_TYPE, shopKey);
|
||||
}
|
||||
|
||||
public Map<String, PatrolDeleteShopPayloadDto> getAllShopMergedPayload(Long taskId) {
|
||||
try {
|
||||
Map<Object, Object> raw = stringRedisTemplate.opsForHash().entries(buildShopPayloadKey(taskId));
|
||||
if (raw == null || raw.isEmpty()) {
|
||||
return Map.of();
|
||||
}
|
||||
Map<String, PatrolDeleteShopPayloadDto> out = new LinkedHashMap<>();
|
||||
for (Map.Entry<Object, Object> entry : raw.entrySet()) {
|
||||
if (!(entry.getKey() instanceof String key) || !(entry.getValue() instanceof String val) || val.isBlank()) {
|
||||
continue;
|
||||
}
|
||||
out.put(key, objectMapper.readValue(val, PatrolDeleteShopPayloadDto.class));
|
||||
}
|
||||
return out;
|
||||
} catch (Exception ex) {
|
||||
throw new BusinessException("读取巡店删除缓存失败");
|
||||
}
|
||||
return taskScopePayloadStorageService.getAllScopePayload(taskId, MODULE_TYPE, PatrolDeleteShopPayloadDto.class);
|
||||
}
|
||||
|
||||
public boolean hasAnyShopMergedPayload(Long taskId) {
|
||||
if (taskId == null || taskId <= 0) {
|
||||
return false;
|
||||
}
|
||||
Long size = stringRedisTemplate.opsForHash().size(buildShopPayloadKey(taskId));
|
||||
return size != null && size > 0;
|
||||
return taskScopePayloadStorageService.hasAnyScopePayload(taskId, MODULE_TYPE);
|
||||
}
|
||||
|
||||
public long countShopMergedPayload(Long taskId) {
|
||||
if (taskId == null || taskId <= 0) {
|
||||
return 0L;
|
||||
}
|
||||
Long size = stringRedisTemplate.opsForHash().size(buildShopPayloadKey(taskId));
|
||||
return size == null ? 0L : size;
|
||||
return taskScopePayloadStorageService.countScopePayload(taskId, MODULE_TYPE);
|
||||
}
|
||||
|
||||
public long getTaskHeartbeatMillis(Long taskId) {
|
||||
@@ -123,9 +83,9 @@ public class PatrolDeleteTaskCacheService {
|
||||
return;
|
||||
}
|
||||
taskEntityLocalCache.remove(taskId);
|
||||
stringRedisTemplate.delete(buildShopPayloadKey(taskId));
|
||||
stringRedisTemplate.delete(buildTaskHeartbeatKey(taskId));
|
||||
stringRedisTemplate.delete(buildTaskEntityKey(taskId));
|
||||
taskScopePayloadStorageService.deleteTaskScopePayloads(taskId, MODULE_TYPE);
|
||||
}
|
||||
|
||||
public void saveTaskCache(FileTaskEntity task) {
|
||||
@@ -190,10 +150,6 @@ public class PatrolDeleteTaskCacheService {
|
||||
return result;
|
||||
}
|
||||
|
||||
private String buildShopPayloadKey(Long taskId) {
|
||||
return "patrol-delete:task:shop-payload:" + taskId;
|
||||
}
|
||||
|
||||
private String buildTaskHeartbeatKey(Long taskId) {
|
||||
return "patrol-delete:task:heartbeat:" + taskId;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user