From cb180a8771cf1adceab0aff53991b50d53e51deb Mon Sep 17 00:00:00 2001 From: Syliang <1439806354@qq.com> Date: Fri, 8 May 2026 10:33:03 +0800 Subject: [PATCH] =?UTF-8?q?1=E3=80=81=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/bim/api/controller/BimController.java | 12 +- .../bim/api/service/ProgressDataService.java | 259 +++++++++++------- 2 files changed, 164 insertions(+), 107 deletions(-) diff --git a/src/main/java/com/bim/api/controller/BimController.java b/src/main/java/com/bim/api/controller/BimController.java index 5c8dd32..b126eb5 100644 --- a/src/main/java/com/bim/api/controller/BimController.java +++ b/src/main/java/com/bim/api/controller/BimController.java @@ -47,13 +47,13 @@ public class BimController { } @GetMapping("/progressData") - public Map getProgressData() { - return progressDataService.getOrCreateTask(); + public Map getProgressData(@RequestParam String date) { + return progressDataService.getOrCreateTask(date); } - @GetMapping("/progressData/{taskId}") - public Map getProgressDataResult(@PathVariable String taskId) { - return progressDataService.getTaskResult(taskId); + @GetMapping("/progressData/result") + public Map getProgressDataResult(@RequestParam String date) { + return progressDataService.getTaskResultByDate(date); } @PostMapping("/getPjDayListByPositionId") @@ -100,4 +100,4 @@ public class BimController { } return result; } -} \ No newline at end of file +} diff --git a/src/main/java/com/bim/api/service/ProgressDataService.java b/src/main/java/com/bim/api/service/ProgressDataService.java index 28dbdc4..6d43b41 100644 --- a/src/main/java/com/bim/api/service/ProgressDataService.java +++ b/src/main/java/com/bim/api/service/ProgressDataService.java @@ -1,37 +1,35 @@ package com.bim.api.service; -import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.bim.api.entity.ActAmtResponse; import com.bim.api.entity.PartCodeRelation; -import com.bim.api.entity.PjDayListResponse; -import com.bim.api.query.ProjectProgressParams; import com.bim.api.mapper.PartCodeRelationMapper; import com.bim.api.util.ThirdPartyAuthUtil; import org.springframework.data.redis.core.RedisTemplate; -import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; -import jakarta.annotation.PostConstruct; +import java.time.LocalDate; import java.time.LocalDateTime; -import java.util.*; -import java.util.concurrent.ConcurrentHashMap; +import java.time.format.DateTimeParseException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; @Service public class ProgressDataService extends ServiceImpl { private static final String PROJECT_ID = "5e4bde33ec084f1a8673eb59b190dce7"; - - private static final String KEY_TASK_STATUS = "progress:task:"; - private static final String KEY_TASK_TOTAL = ":total"; - private static final String KEY_TASK_CURRENT = ":current"; - private static final String KEY_TASK_RESULT = ":result"; - private static final String KEY_PROCESSING = "progress:processing"; - private static final String KEY_COMPLETED = "progress:completed"; - private static final String KEY_LATEST_TASK = "progress:latest:taskId"; - - private static final Map TASK_STATUS_CACHE = new ConcurrentHashMap<>(); - + + private static final String KEY_TASK_PREFIX = "progress:task:"; + private static final String KEY_PROCESSING_PREFIX = "progress:processing:"; + private static final String SUFFIX_STATUS = ":status"; + private static final String SUFFIX_TOTAL = ":total"; + private static final String SUFFIX_CURRENT = ":current"; + private static final String SUFFIX_RESULT = ":result"; + private static final String SUFFIX_ERROR = ":error"; + private static final String SUFFIX_RAW_ACT_AMT = ":rawActAmt"; + private final ThirdPartyAuthUtil thirdPartyAuthUtil; private final RedisTemplate redisTemplate; @@ -40,141 +38,200 @@ public class ProgressDataService extends ServiceImpl getOrCreateTask() { + public Map getOrCreateTask(String date) { + String normalizedDate = normalizeDate(date); Map result = new HashMap<>(); - - String latestTaskId = (String) redisTemplate.opsForValue().get(KEY_LATEST_TASK); - if (latestTaskId != null) { - String status = getTaskStatus(latestTaskId); - if ("COMPLETED".equals(status)) { - result.put("taskId", latestTaskId); - result.put("status", "COMPLETED"); - return result; - } + result.put("date", normalizedDate); + + String status = getTaskStatusByDate(normalizedDate); + if ("COMPLETED".equals(status)) { + result.put("status", "COMPLETED"); + return result; } - - String processingTaskId = (String) redisTemplate.opsForValue().get(KEY_PROCESSING); - if (processingTaskId != null) { - result.put("taskId", processingTaskId); + + String processing = (String) redisTemplate.opsForValue().get(buildProcessingKey(normalizedDate)); + if (processing != null) { result.put("status", "PROCESSING"); return result; } - - String taskId = UUID.randomUUID().toString().replace("-", ""); - initTask(taskId); - calculateProgressAsync(taskId); - - result.put("taskId", taskId); + + Boolean lockResult = redisTemplate.opsForValue().setIfAbsent(buildProcessingKey(normalizedDate), "1"); + if (!Boolean.TRUE.equals(lockResult)) { + result.put("status", "PROCESSING"); + return result; + } + + initTask(normalizedDate); + calculateProgressAsync(normalizedDate); + result.put("status", "STARTED"); return result; } - public Map getTaskResult(String taskId) { + public Map getTaskResultByDate(String date) { + String normalizedDate = normalizeDate(date); Map result = new HashMap<>(); - - String status = getTaskStatus(taskId); - result.put("taskId", taskId); + result.put("date", normalizedDate); + + String status = getTaskStatusByDate(normalizedDate); result.put("status", status); - + if (status == null) { - result.put("status", "NOT_FOUND"); + String processing = (String) redisTemplate.opsForValue().get(buildProcessingKey(normalizedDate)); + result.put("status", processing != null ? "PROCESSING" : "NOT_FOUND"); return result; } - - Integer total = (Integer) redisTemplate.opsForValue().get(KEY_TASK_STATUS + taskId + KEY_TASK_TOTAL); - Integer current = (Integer) redisTemplate.opsForValue().get(KEY_TASK_STATUS + taskId + KEY_TASK_CURRENT); - + + Integer total = (Integer) redisTemplate.opsForValue().get(buildTaskKey(normalizedDate, SUFFIX_TOTAL)); + Integer current = (Integer) redisTemplate.opsForValue().get(buildTaskKey(normalizedDate, SUFFIX_CURRENT)); + result.put("total", total != null ? total : 0); result.put("current", current != null ? current : 0); - + double progress = 0; if (total != null && total > 0 && current != null) { progress = (double) current / total; } result.put("progress", progress); - + if ("COMPLETED".equals(status)) { - Object data = redisTemplate.opsForValue().get(KEY_TASK_STATUS + taskId + KEY_TASK_RESULT); + Object data = redisTemplate.opsForValue().get(buildTaskKey(normalizedDate, SUFFIX_RESULT)); result.put("data", data); } - + + if ("FAILED".equals(status)) { + Object error = redisTemplate.opsForValue().get(buildTaskKey(normalizedDate, SUFFIX_ERROR)); + if (error != null) { + result.put("error", error); + } + } + return result; } - private String getTaskStatus(String taskId) { - if (taskId == null) return null; - return TASK_STATUS_CACHE.get(taskId); + private String normalizeDate(String date) { + if (date == null || date.isBlank()) { + throw new IllegalArgumentException("date cannot be blank, expected format: yyyy-MM-dd"); + } + try { + return LocalDate.parse(date).toString(); + } catch (DateTimeParseException e) { + throw new IllegalArgumentException("invalid date format, expected: yyyy-MM-dd"); + } } - private void initTask(String taskId) { - TASK_STATUS_CACHE.put(taskId, "STARTED"); - redisTemplate.opsForValue().set(KEY_PROCESSING, taskId); + private String buildTaskKey(String date, String suffix) { + return KEY_TASK_PREFIX + date + suffix; } - private void calculateProgressAsync(String taskId) { - TASK_STATUS_CACHE.put(taskId, "PROCESSING"); - + private String buildProcessingKey(String date) { + return KEY_PROCESSING_PREFIX + date; + } + + private String getTaskStatusByDate(String date) { + return (String) redisTemplate.opsForValue().get(buildTaskKey(date, SUFFIX_STATUS)); + } + + private Map buildActAmtRequest(String projectId, String positionId, String period) { + Map request = new HashMap<>(); + request.put("projectId", projectId); + request.put("positionId", positionId); + request.put("period", period); + return request; + } + + private void initTask(String date) { + redisTemplate.opsForValue().set(buildTaskKey(date, SUFFIX_STATUS), "STARTED"); + redisTemplate.opsForValue().set(buildTaskKey(date, SUFFIX_TOTAL), 0); + redisTemplate.opsForValue().set(buildTaskKey(date, SUFFIX_CURRENT), 0); + redisTemplate.delete(buildTaskKey(date, SUFFIX_RESULT)); + redisTemplate.delete(buildTaskKey(date, SUFFIX_ERROR)); + redisTemplate.delete(buildTaskKey(date, SUFFIX_RAW_ACT_AMT)); + } + + private void calculateProgressAsync(String date) { + redisTemplate.opsForValue().set(buildTaskKey(date, SUFFIX_STATUS), "PROCESSING"); + new Thread(() -> { try { List relations = list(); int total = relations.size(); - - redisTemplate.opsForValue().set(KEY_TASK_STATUS + taskId + KEY_TASK_TOTAL, total); - redisTemplate.opsForValue().set(KEY_TASK_STATUS + taskId + KEY_TASK_CURRENT, 0); - + + redisTemplate.opsForValue().set(buildTaskKey(date, SUFFIX_TOTAL), total); + redisTemplate.opsForValue().set(buildTaskKey(date, SUFFIX_CURRENT), 0); + List> results = new ArrayList<>(); - + List> rawActAmtResults = new ArrayList<>(); + int current = 0; + for (PartCodeRelation relation : relations) { Map item = new HashMap<>(); item.put("partId", relation.getPartId()); item.put("codeData", relation.getCodeData()); - + try { LocalDateTime createTime = relation.getCreateTime(); - String period = createTime != null ? createTime.toString().replace("T", " ") : null; - - ProjectProgressParams params = new ProjectProgressParams(); - params.setProjectId(PROJECT_ID); - params.setPositionIds(relation.getPartId()); - params.setPeriod(period); - - PjDayListResponse pjDayResponse = thirdPartyAuthUtil.findPjDayListByPositionId(params); - + String originalPeriod = createTime != null ? createTime.toString().replace("T", " ") : null; + String positionId = relation.getPartId(); + String requestPeriod = date; + + ActAmtResponse actAmtResponse = thirdPartyAuthUtil.findActAmtByPositionId( + PROJECT_ID, + positionId, + requestPeriod + ); + + Map requestParams = new HashMap<>(); + requestParams.put("projectId", PROJECT_ID); + requestParams.put("positionId", positionId); + requestParams.put("period", requestPeriod); + + Map rawEntry = new HashMap<>(); + rawEntry.put("partId", positionId); + rawEntry.put("period", requestPeriod); + rawEntry.put("originalPeriod", originalPeriod); + rawEntry.put("request", requestParams); + rawEntry.put("response", actAmtResponse); + rawActAmtResults.add(rawEntry); + double progressData = 0; - if (pjDayResponse != null && pjDayResponse.getData() != null && !pjDayResponse.getData().isEmpty()) { - PjDayListResponse.PjDayData dayData = pjDayResponse.getData().get(0); - Double totalNum = dayData.getMeteringNum(); - Double meteringNum = dayData.getMeteringAmt(); - - if (totalNum != null && meteringNum != null && meteringNum != 0) { - progressData = totalNum / meteringNum; + if (actAmtResponse != null && actAmtResponse.getData() != null && !actAmtResponse.getData().isEmpty()) { + ActAmtResponse.ActAmtData dayData = actAmtResponse.getData().get(0); + Double actAmt = dayData.getActAmt(); + Double meteringAmt = dayData.getMeteringAmt(); + + if (actAmt != null && meteringAmt != null && meteringAmt != 0) { + progressData = actAmt / meteringAmt; } } item.put("progressData", progressData); } catch (Exception e) { item.put("progressData", 0); item.put("error", e.getMessage()); + + Map rawEntry = new HashMap<>(); + rawEntry.put("partId", relation.getPartId()); + rawEntry.put("request", buildActAmtRequest(PROJECT_ID, relation.getPartId(), date)); + rawEntry.put("error", e.getMessage()); + rawActAmtResults.add(rawEntry); } - + results.add(item); - - Integer current = (Integer) redisTemplate.opsForValue().get(KEY_TASK_STATUS + taskId + KEY_TASK_CURRENT); - redisTemplate.opsForValue().set(KEY_TASK_STATUS + taskId + KEY_TASK_CURRENT, current + 1); + current++; + redisTemplate.opsForValue().set(buildTaskKey(date, SUFFIX_CURRENT), current); } - - redisTemplate.opsForValue().set(KEY_TASK_STATUS + taskId + KEY_TASK_RESULT, results); - redisTemplate.opsForValue().set(KEY_TASK_STATUS + taskId + KEY_TASK_CURRENT, total); - - redisTemplate.delete(KEY_PROCESSING); - redisTemplate.opsForValue().set(KEY_COMPLETED, taskId); - redisTemplate.opsForValue().set(KEY_LATEST_TASK, taskId); - - TASK_STATUS_CACHE.put(taskId, "COMPLETED"); - + + redisTemplate.opsForValue().set(buildTaskKey(date, SUFFIX_RESULT), results); + redisTemplate.opsForValue().set(buildTaskKey(date, SUFFIX_RAW_ACT_AMT), rawActAmtResults); + redisTemplate.opsForValue().set(buildTaskKey(date, SUFFIX_CURRENT), total); + redisTemplate.opsForValue().set(buildTaskKey(date, SUFFIX_STATUS), "COMPLETED"); + redisTemplate.delete(buildProcessingKey(date)); + } catch (Exception e) { - TASK_STATUS_CACHE.put(taskId, "FAILED"); - redisTemplate.delete(KEY_PROCESSING); + redisTemplate.opsForValue().set(buildTaskKey(date, SUFFIX_STATUS), "FAILED"); + redisTemplate.opsForValue().set(buildTaskKey(date, SUFFIX_ERROR), e.getMessage()); + redisTemplate.delete(buildProcessingKey(date)); } }).start(); } -} \ No newline at end of file +}