Browse Source

修改bug

chenxiaofei 1 month ago
parent
commit
764604fea6

+ 28 - 0
iot-platform-manager/src/main/java/com/platform/api/controller/WeighbridgeController.java

@@ -14,6 +14,7 @@ import org.springframework.web.bind.annotation.*;
 import org.springframework.web.multipart.MultipartFile;
 
 import java.math.BigDecimal;
+import java.util.List;
 
 
 /**
@@ -81,4 +82,31 @@ public class WeighbridgeController {
         request.setUuid(uuid);
         return weighbridgeRecordManage.handleValidateLicensePlate(request);
     }
+
+    @Operation(summary = "地磅过磅数据上报", description = "接收地磅设备上报的过磅数据和图片")
+    @PostMapping("v2/weighBridgePush")
+    public LicensePlateValidateResponse weighBridgePushV2(
+            @Parameter(description = "车牌号") @RequestParam("licensePlate") String licensePlate,
+            @Parameter(description = "地磅编号") @RequestParam("weighbridgeCode") String weighbridgeCode,
+            @Parameter(description = "称重重量(吨)") @RequestParam("grossWeight") String grossWeight,
+            @Parameter(description = "时间戳(秒或毫秒)") @RequestParam("timestamp") String timestamp,
+            @Parameter(description = "处理标签") @RequestParam(value = "tag", required = false) String tag,
+            @Parameter(description = "车辆照片") @RequestParam(value = "images", required = false) List<String> images
+    ) {
+        // 构建请求对象
+        WeighbridgePushRequest request = new WeighbridgePushRequest();
+        String lience = StringUtils.isNotBlank(licensePlate) ? licensePlate.trim().replace("\\r", "").replace("\\n", ""):"";
+        request.setLicensePlate(lience);
+        String weighCode =StringUtils.isNotBlank(weighbridgeCode) ?  weighbridgeCode.trim().replace("\\r", "").replace("\\n", ""):"";
+        request.setWeighbridgeCode(weighCode);
+        String rossWeight = StringUtils.isNotBlank(grossWeight) ?grossWeight.trim().replace("\\r", "").replace("\\n", ""):"";
+        request.setGrossWeight(new BigDecimal(rossWeight));
+        String time = StringUtils.isNotBlank(timestamp) ? timestamp.trim().replace("\\r", "").replace("\\n", ""):"";
+        request.setTimestamp(Long.valueOf(time));
+        request.setTag(tag);
+        request.setBase64Images(images);
+
+        // 调用业务层处理
+        return weighbridgeRecordManage.handleWeighbridgePushV2(request);
+    }
 }

+ 74 - 0
iot-platform-manager/src/main/java/com/platform/api/manager/UploadService.java

@@ -6,18 +6,28 @@ import com.platform.utils.FileUtils;
 import lombok.Data;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Value;
 import org.springframework.scheduling.annotation.Async;
 import org.springframework.stereotype.Service;
 import org.springframework.web.multipart.MultipartFile;
 
 import java.util.ArrayList;
+import java.util.Base64;
 import java.util.List;
 import java.io.*;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.time.LocalDate;
+import java.util.UUID;
 import java.util.concurrent.CompletableFuture;
 
 @Service
 @Slf4j
 public class UploadService {
+    @Value("${weighbridge.image.storage-path:./data/weighbridge-images}")
+    private String imageStoragePath;
+
     /**
      * 异步处理图片文件上传(真正的并行上传)
      * 为每个图片创建独立的异步任务,实现并行上传
@@ -48,6 +58,70 @@ public class UploadService {
         }
         return CompletableFuture.completedFuture(String.join(",", resultList));
     }
+
+    @Async("taskExecutor")
+    public CompletableFuture<String> processBase64ImagesToLocalAsync(List<String> base64Images, String licensePlate) {
+        List<String> resultList = new ArrayList<>();
+        if (base64Images == null || base64Images.isEmpty()) {
+            return CompletableFuture.completedFuture("");
+        }
+
+        for (String base64Image : base64Images) {
+            if (StringUtils.isBlank(base64Image)) {
+                continue;
+            }
+            try {
+                DecodedImage decodedImage = decodeBase64Image(base64Image);
+                Path imagePath = buildLocalImagePath(licensePlate, decodedImage.extension());
+                Files.createDirectories(imagePath.getParent());
+                Files.write(imagePath, decodedImage.bytes());
+                resultList.add(imagePath.toAbsolutePath().normalize().toString());
+            } catch (Exception e) {
+                log.error("保存Base64图片异常,车牌号: {}", licensePlate, e);
+                throw new IotException(ErrorCodeEnum.SYSTEM_ERROR, "保存Base64图片异常");
+            }
+        }
+        return CompletableFuture.completedFuture(String.join(",", resultList));
+    }
+
+    private DecodedImage decodeBase64Image(String base64Image) {
+        String content = base64Image.trim();
+        String extension = "jpg";
+        int commaIndex = content.indexOf(',');
+        if (content.startsWith("data:") && commaIndex > -1) {
+            String header = content.substring(0, commaIndex);
+            extension = getExtensionFromDataUri(header);
+            content = content.substring(commaIndex + 1);
+        }
+        byte[] bytes = Base64.getDecoder().decode(content.replaceAll("\\s", ""));
+        return new DecodedImage(bytes, extension);
+    }
+
+    private Path buildLocalImagePath(String licensePlate, String extension) {
+        String safeLicensePlate = StringUtils.defaultIfBlank(licensePlate, "unknown")
+                .replaceAll("[\\\\/:*?\"<>|\\s]+", "_");
+        String filename = safeLicensePlate + "_" + System.currentTimeMillis() + "_" + UUID.randomUUID() + "." + extension;
+        return Paths.get(imageStoragePath, LocalDate.now().toString(), filename);
+    }
+
+    private String getExtensionFromDataUri(String header) {
+        if (header.contains("image/png")) {
+            return "png";
+        }
+        if (header.contains("image/gif")) {
+            return "gif";
+        }
+        if (header.contains("image/webp")) {
+            return "webp";
+        }
+        if (header.contains("image/bmp")) {
+            return "bmp";
+        }
+        return "jpg";
+    }
+
+    private record DecodedImage(byte[] bytes, String extension) {
+    }
     
     /**
      * 用于将字节数组包装成MultipartFile的辅助类

+ 71 - 0
iot-platform-manager/src/main/java/com/platform/api/manager/WeighbridgeRecordManage.java

@@ -106,6 +106,60 @@ public class WeighbridgeRecordManage {
         }
     }
 
+    public LicensePlateValidateResponse handleWeighbridgePushV2(WeighbridgePushRequest request) {
+        log.info("处理地磅数据上报 - 车牌:{}, 地磅编号:{}, 重量:{}, 时间戳:{}",
+                request.getLicensePlate(),
+                request.getWeighbridgeCode(),
+                request.getGrossWeight(),
+                request.getTimestamp());
+        LicensePlateValidateResponse licensePlateValidateResponse = new LicensePlateValidateResponse();
+        if (StringUtils.isAnyBlank(request.getLicensePlate(), request.getWeighbridgeCode()) || Objects.isNull(request.getGrossWeight()) || Objects.isNull(request.getTimestamp())) {
+            return getLicensePlateValidateResponse(request, licensePlateValidateResponse);
+        }
+        //查询车牌是否在验证列表中
+        ValidateLicensePlate validateLicensePlate = validateLicensePlateService.queryByLicensePlate(request.getLicensePlate());
+        try {
+            // 构建实体对象
+            WeighbridgeRecord record = buildWeighbridgeRecord(request);
+            if(Objects.isNull(validateLicensePlate)){
+                record.setCheckStatus(1);
+            }
+            // 保存到数据库
+            boolean saved = weighbridgeRecordService.save(record);
+            if (saved) {
+                // 异步处理图片上传
+                updateBase64ImageUrls(request, record);
+                licensePlateValidateResponse.setStatus(true);
+                licensePlateValidateResponse.setCode(200);
+                licensePlateValidateResponse.setMessage("数据上报成功");
+                LicensePlateValidateResponse.Data data = new LicensePlateValidateResponse.Data();
+                String timestampStr = request.getTimestamp().toString();
+                if (timestampStr.length() == 10) {
+                    // 秒级时间戳
+                    data.setTimestamp(request.getTimestamp());
+                } else if (timestampStr.length() == 13) {
+                    // 毫秒级时间戳
+                    long l = request.getTimestamp() / 1000;
+                    data.setTimestamp(l);
+                }
+                data.setScreen_message("数据上报成功");
+                data.setVoice_message("数据上报成功");
+                licensePlateValidateResponse.setData(data);
+                log.info("地磅数据保存成功 - ID: {}, 车牌: {}", record.getId(), record.getLicensePlate());
+                return licensePlateValidateResponse;
+            } else {
+                log.error("地磅数据保存失败 - 车牌: {}", request.getLicensePlate());
+                return getLicensePlateValidateResponse(request, licensePlateValidateResponse);
+            }
+
+        } catch (Exception e) {
+            log.error("地磅数据上报处理异常", e);
+            return getLicensePlateValidateResponse(request, licensePlateValidateResponse);
+            //throw new IotException(ErrorCodeEnum.SYSTEM_ERROR, "地磅数据上报异常: " + e.getMessage());
+        }
+    }
+
+
     private void updateImageUrls(WeighbridgePushRequest request, WeighbridgeRecord record) {
         if (request.getImages() != null && request.getImages().length > 0) {
             log.info("开始处理 {} 张图片上传,车牌号: {}", request.getImages().length, request.getLicensePlate());
@@ -133,6 +187,23 @@ public class WeighbridgeRecordManage {
         }
     }
 
+    private void updateBase64ImageUrls(WeighbridgePushRequest request, WeighbridgeRecord record) {
+        if (request.getBase64Images() != null && !request.getBase64Images().isEmpty()) {
+            log.info("开始处理 {} 张Base64图片保存,车牌号: {}", request.getBase64Images().size(), request.getLicensePlate());
+            uploadService.processBase64ImagesToLocalAsync(request.getBase64Images(), request.getLicensePlate())
+                    .thenAccept(photoUrls -> {
+                        log.info("Base64图片保存完成,车牌号: {},照片数量: {}", request.getLicensePlate(),
+                                photoUrls != null ? photoUrls.split(",").length : 0);
+                        record.setPhotoUrls(photoUrls);
+                        updatePhotoUrls(record.getId(), photoUrls);
+                    })
+                    .exceptionally(throwable -> {
+                        log.error("异步保存Base64图片失败,车牌号: {}", request.getLicensePlate(), throwable);
+                        return null;
+                    });
+        }
+    }
+
     private static LicensePlateValidateResponse getLicensePlateValidateResponse(WeighbridgePushRequest request, LicensePlateValidateResponse licensePlateValidateResponse) {
 
         licensePlateValidateResponse.setStatus(false);

+ 3 - 0
iot-platform-manager/src/main/java/com/platform/api/request/WeighbridgePushRequest.java

@@ -7,6 +7,7 @@ import lombok.Data;
 import org.springframework.web.multipart.MultipartFile;
 
 import java.math.BigDecimal;
+import java.util.List;
 
 /**
  * 地磅过磅数据上报请求参数
@@ -55,4 +56,6 @@ public class WeighbridgePushRequest {
      */
     @Schema(description = "车辆图片数组")
     private MultipartFile[] images;
+
+    private List<String> base64Images;
 }