Prechádzať zdrojové kódy

提交地磅管理开发1

chenxiaofei 2 mesiacov pred
rodič
commit
6ea4a31ee5

+ 94 - 5
sckw-modules/sckw-system/src/main/java/com/sckw/system/controller/KwsWeighbridgeController.java

@@ -1,22 +1,25 @@
 package com.sckw.system.controller;
 
+import com.sckw.core.utils.TruckNoUtils;
 import com.sckw.core.web.constant.HttpStatus;
 import com.sckw.core.web.response.HttpResult;
-import com.sckw.system.model.vo.req.WeighbridgeDiffConfigReqVo;
-import com.sckw.system.model.vo.req.WeighbridgePageReqVo;
-import com.sckw.system.model.vo.req.WeighbridgeRestartReqVo;
-import com.sckw.system.model.vo.req.WeighbridgeSaveReqVo;
-import com.sckw.system.model.vo.req.WeighbridgeStatusReqVo;
+import com.sckw.system.model.vo.req.*;
+import com.sckw.system.model.vo.res.LicensePlateValidateResponse;
 import com.sckw.system.service.KwsWeighbridgeManageService;
 import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
 import io.swagger.v3.oas.annotations.tags.Tag;
 import lombok.RequiredArgsConstructor;
+import org.apache.commons.lang3.StringUtils;
 import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.math.BigDecimal;
 
 /**
  * 地磅控制器
@@ -94,4 +97,90 @@ public class KwsWeighbridgeController {
                                       @RequestParam(required = false) Long id) {
         return HttpResult.ok(kwsWeighbridgeManageService.checkUniqueCodeAvailable(uniqueCode, id));
     }
+
+
+    /**
+     * 地磅过磅数据上报
+     */
+    @Operation(summary = "地磅过磅数据上报", description = "接收地磅设备上报的过磅数据和图片")
+    @PostMapping("/weighBridgePush")
+    public LicensePlateValidateResponse weighBridgePush(
+            @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) MultipartFile[] images
+    ) {
+        String cleanedLicensePlate = sanitizeText(licensePlate);
+        if (!TruckNoUtils.isValidTruckNo(cleanedLicensePlate)) {
+            return buildPushErrorResponse("车牌号格式不正确");
+        }
+
+        WeighbridgePushRequest request = new WeighbridgePushRequest();
+        request.setLicensePlate(TruckNoUtils.formatTruckNo(cleanedLicensePlate));
+        request.setWeighbridgeCode(sanitizeText(weighbridgeCode));
+        request.setGrossWeight(parseBigDecimal(grossWeight));
+        request.setTimestamp(parseLong(timestamp));
+        request.setTag(sanitizeText(tag));
+        request.setImages(images);
+
+        // 调用业务层处理
+        return kwsWeighbridgeManageService.handleWeighbridgePush(request);
+    }
+
+    /**
+     * 车牌验证
+     */
+    @Operation(summary = "车牌验证", description = "用于验证车牌是否合法,允许上磅")
+    @PostMapping("/validateLicensePlate")
+    public LicensePlateValidateResponse validateLicensePlate(
+            @Parameter(description = "车牌号") @RequestParam("licensePlate") String licensePlate,
+            @Parameter(description = "厂商来源标识") @RequestParam("uuid") String uuid
+    ) {
+        LicensePlateValidateRequest request = new LicensePlateValidateRequest();
+        String replac2 = "";
+        if (StringUtils.isNotBlank(licensePlate)) {
+            String trim = licensePlate.trim();
+            String replace = trim.replace("\\r", "");
+            String replace1 = replace.replace("\\n", "");
+            replac2 = replace1.replace("\\r\\n", "");
+        }
+
+        request.setLicensePlate(replac2);
+        request.setUuid(uuid);
+        return kwsWeighbridgeManageService.handleValidateLicensePlate(request);
+    }
+
+    private String sanitizeText(String value) {
+        if (StringUtils.isBlank(value)) {
+            return "";
+        }
+        return value.trim()
+                .replace("\r", "")
+                .replace("\n", "");
+    }
+
+    private BigDecimal parseBigDecimal(String value) {
+        String cleanedValue = sanitizeText(value);
+        return StringUtils.isBlank(cleanedValue) ? null : new BigDecimal(cleanedValue);
+    }
+
+    private Long parseLong(String value) {
+        String cleanedValue = sanitizeText(value);
+        return StringUtils.isBlank(cleanedValue) ? null : Long.valueOf(cleanedValue);
+    }
+
+    private LicensePlateValidateResponse buildPushErrorResponse(String message) {
+        LicensePlateValidateResponse response = new LicensePlateValidateResponse();
+        response.setStatus(false);
+        response.setCode(400);
+        response.setMessage(message);
+        LicensePlateValidateResponse.Data data = new LicensePlateValidateResponse.Data();
+        data.setTimestamp(System.currentTimeMillis() / 1000);
+        data.setScreen_message(message);
+        data.setVoice_message(message);
+        response.setData(data);
+        return response;
+    }
 }

+ 16 - 0
sckw-modules/sckw-system/src/main/java/com/sckw/system/dao/ValidateLicensePlateMapper.java

@@ -0,0 +1,16 @@
+package com.sckw.system.dao;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+import com.sckw.system.model.ValidateLicensePlate;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * @Author: cxf
+ * @CreateTime: 2026-01-21
+ * @Description: 地磅过磅记录Mapper接口
+ * @Version: 1.0
+ */
+@Mapper
+public interface ValidateLicensePlateMapper extends BaseMapper<ValidateLicensePlate> {
+}

+ 53 - 0
sckw-modules/sckw-system/src/main/java/com/sckw/system/model/ValidateLicensePlate.java

@@ -0,0 +1,53 @@
+package com.sckw.system.model;
+
+import com.baomidou.mybatisplus.annotation.*;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+/**
+ * 车牌识别表实体类
+ *
+ * @author cxf
+ */
+@Data
+@TableName("validate_license_plate")
+public class ValidateLicensePlate {
+
+    /**
+     * 主键ID
+     */
+    @TableId(value = "id", type = IdType.AUTO)
+    private Long id;
+
+    /**
+     * 车牌号
+     */
+    @TableField("license_plate")
+    private String licensePlate;
+
+    /**
+     * 厂商来源标识
+     */
+    @TableField("uuid")
+    private String uuid;
+
+    /**
+     * 状态,0=可用,1=不可用
+     */
+    @TableField("status")
+    private Integer status;
+
+    /**
+     * 记录创建时间
+     */
+    @TableField(value = "created_at", fill = FieldFill.INSERT)
+    private LocalDateTime createdAt;
+
+    /**
+     * 记录更新时间
+     */
+    @TableField(value = "updated_at", fill = FieldFill.INSERT_UPDATE)
+    private LocalDateTime updatedAt;
+
+}

+ 26 - 0
sckw-modules/sckw-system/src/main/java/com/sckw/system/model/vo/req/LicensePlateValidateRequest.java

@@ -0,0 +1,26 @@
+package com.sckw.system.model.vo.req;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+/**
+ * 车牌验证请求参数
+ * @author PC
+ */
+@Data
+@Schema(description = "车辆识别请求参数")
+public class LicensePlateValidateRequest {
+
+    /**
+     * 车牌号
+     */
+    @Schema(description = "车牌号", example = "川A1234")
+    private String licensePlate;
+
+    /**
+     * 厂商来源标识
+     */
+    @Schema(description = "厂商来源标识", example = "kw38146288dce12d6938d30ebc3a9db6c5")
+    private String uuid;
+
+}

+ 58 - 0
sckw-modules/sckw-system/src/main/java/com/sckw/system/model/vo/req/WeighbridgePushRequest.java

@@ -0,0 +1,58 @@
+package com.sckw.system.model.vo.req;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.NotNull;
+import lombok.Data;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.math.BigDecimal;
+
+/**
+ * 地磅过磅数据上报请求参数
+ * @author PC
+ */
+@Data
+@Schema(description = "地磅过磅数据上报请求参数")
+public class WeighbridgePushRequest {
+
+    /**
+     * 车牌号
+     */
+    @NotBlank(message = "车牌号不能为空")
+    @Schema(description = "车牌号", example = "川A1234")
+    private String licensePlate;
+
+    /**
+     * 地磅编号
+     */
+    @NotBlank(message = "地磅编号不能为空")
+    @Schema(description = "地磅编号", example = "10100111")
+    private String weighbridgeCode;
+
+    /**
+     * 称重重量(吨)
+     */
+    @NotNull(message = "称重重量不能为空")
+    @Schema(description = "称重重量(吨)", example = "34.5")
+    private BigDecimal grossWeight;
+
+    /**
+     * 时间戳(支持秒或毫秒)
+     */
+    @NotNull(message = "时间戳不能为空")
+    @Schema(description = "时间戳(秒或毫秒)", example = "1745483981")
+    private Long timestamp;
+
+    /**
+     * 处理标签,用于指定处理方向
+     */
+    @Schema(description = "处理标签", example = "kll")
+    private String tag;
+
+    /**
+     * 车辆图片
+     */
+    @Schema(description = "车辆图片数组")
+    private MultipartFile[] images;
+}

+ 68 - 0
sckw-modules/sckw-system/src/main/java/com/sckw/system/model/vo/res/LicensePlateValidateResponse.java

@@ -0,0 +1,68 @@
+package com.sckw.system.model.vo.res;
+
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+/**
+ * Author: donglang
+ * Time: 2026-01-21
+ * Des: 车牌验证通用返回模型
+ * Version: 1.0
+ */
+
+@Data
+@Schema(description = "车牌验证通用返回模型")
+public class LicensePlateValidateResponse {
+    /**
+     * 返回状态
+     */
+    @Schema(description = "返回状态")
+    private Boolean status;
+
+    /**
+     * 返回状态值
+     */
+    @Schema(description = "返回描述")
+    private Integer code;
+
+    /**
+     * 返回数据集
+     */
+    @Schema(description = "返回数据集")
+    private String message;
+
+    /**
+     * 数据
+     */
+    @Schema(description = "数据")
+    private Data data;
+
+    @lombok.Data
+    public static class Data {
+
+        /**
+         * 返回处理时间
+         */
+        @Schema(description = "返回处理时间")
+        private Long timestamp;
+
+        /**
+         * 播报内容
+         */
+        @Schema(description = "播报内容")
+        private String screen_message;
+
+        /**
+         * LED显示内容
+         */
+        @Schema(description = "LED显示内容")
+        private String voice_message;
+
+        /**
+         * 警告
+         */
+        @Schema(description = "用于给出警告信息,提示当前环境为测试服。")
+        private String warning;
+    }
+}

+ 176 - 13
sckw-modules/sckw-system/src/main/java/com/sckw/system/service/KwsWeighbridgeManageService.java

@@ -7,21 +7,12 @@ import com.sckw.core.exception.SystemException;
 import com.sckw.core.model.page.PageResult;
 import com.sckw.core.web.constant.HttpStatus;
 import com.sckw.core.web.context.LoginUserHolder;
-import com.sckw.system.model.KwsEnterprise;
-import com.sckw.system.model.KwsPrinter;
-import com.sckw.system.model.KwsWeighbridge;
-import com.sckw.system.model.KwsWeighbridgeDiffConfig;
-import com.sckw.system.model.vo.req.WeighbridgeDiffConfigReqVo;
-import com.sckw.system.model.vo.req.WeighbridgePageReqVo;
-import com.sckw.system.model.vo.req.WeighbridgeRestartReqVo;
-import com.sckw.system.model.vo.req.WeighbridgeSaveReqVo;
-import com.sckw.system.model.vo.req.WeighbridgeStatusReqVo;
-import com.sckw.system.model.vo.res.PlatformEnterpriseResVo;
-import com.sckw.system.model.vo.res.WeighbridgeDetailResVo;
-import com.sckw.system.model.vo.res.WeighbridgeDiffConfigResVo;
-import com.sckw.system.model.vo.res.WeighbridgePageResVo;
+import com.sckw.system.model.*;
+import com.sckw.system.model.vo.req.*;
+import com.sckw.system.model.vo.res.*;
 import com.sckw.system.repository.KwsEnterpriseRepository;
 import com.sckw.system.repository.KwsPrinterRepository;
+import com.sckw.system.repository.KwsWeighbridgeRecordRepository;
 import com.sckw.system.repository.KwsWeighbridgeDiffConfigRepository;
 import com.sckw.system.repository.KwsWeighbridgeRepository;
 import lombok.RequiredArgsConstructor;
@@ -29,7 +20,9 @@ import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
+import org.springframework.web.multipart.MultipartFile;
 
+import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
@@ -66,6 +59,12 @@ public class KwsWeighbridgeManageService {
      * 地磅误差配置数据访问层
      */
     private final KwsWeighbridgeDiffConfigRepository kwsWeighbridgeDiffConfigRepository;
+    /**
+     * 地磅记录数据访问层
+     */
+    private final KwsWeighbridgeRecordRepository kwsWeighbridgeRecordRepository;
+
+    private final ValidateLicensePlateService validateLicensePlateService;
 
     /**
      * 分页查询地磅列表
@@ -640,4 +639,168 @@ public class KwsWeighbridgeManageService {
         jsonObject.put("emptyLoadValue", reqVo.getEmptyLoadValue());
         return jsonObject.toJSONString();
     }
+
+
+    /**
+     * 车牌验证
+     * @param request 地磅上报请求参数
+     * @return 是否保存成功
+     */
+    public LicensePlateValidateResponse handleValidateLicensePlate(LicensePlateValidateRequest request) {
+        log.info("车牌验证, 车牌:{}", request.getLicensePlate());
+        LicensePlateValidateResponse response = new LicensePlateValidateResponse();
+        ValidateLicensePlate validateLicensePlate;
+        //查询车牌是不存在
+        try {
+            validateLicensePlate = validateLicensePlateService.queryByLicensePlate(request.getLicensePlate(), request.getUuid());
+        } catch (Exception e) {
+            log.error("车牌验证失败,请重新识别或联系管理员", e);
+            return getValidateLicensePlateError(response);
+        }
+
+        if (validateLicensePlate != null) {
+            log.info("车牌验证成功");
+            response.setStatus(Boolean.TRUE);
+            response.setCode(200);
+            response.setMessage("车牌验证成功");
+
+            response.setData(new LicensePlateValidateResponse.Data());
+            response.getData().setTimestamp(System.currentTimeMillis() / 1000);
+            response.getData().setScreen_message("车牌验证成功");
+            response.getData().setVoice_message("车牌验证成功");
+            response.getData().setWarning(null);
+            return response;
+        } else {
+            return getValidateLicensePlateError(response);
+        }
+    }
+    private LicensePlateValidateResponse getValidateLicensePlateError(LicensePlateValidateResponse response) {
+        log.info("车牌验证失败");
+        response.setStatus(Boolean.FALSE);
+        response.setCode(400);
+        response.setMessage("车牌验证异常");
+
+        response.setData(new LicensePlateValidateResponse.Data());
+        response.getData().setTimestamp(System.currentTimeMillis()/1000);
+        response.getData().setScreen_message("车牌验证失败");
+        response.getData().setVoice_message("车牌验证失败");
+        response.getData().setWarning(null);
+        return response;
+    }
+
+    /**
+     * 处理地磅过磅数据上报
+     * @param request 地磅上报请求参数
+     * @return 是否保存成功
+     */
+    public LicensePlateValidateResponse handleWeighbridgePush(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);
+        }
+        try {
+            KwsWeighbridge weighbridge = kwsWeighbridgeRepository.findByUniqueCode(request.getWeighbridgeCode().trim());
+            if (weighbridge == null || Objects.equals(weighbridge.getDelFlag(), 1)) {
+                log.error("地磅数据保存失败 - 地磅不存在, 地磅编号: {}", request.getWeighbridgeCode());
+                return getLicensePlateValidateResponse(request, licensePlateValidateResponse);
+            }
+
+            KwsWeighbridgeRecord record = buildWeighbridgeRecord(request, weighbridge.getId());
+            boolean saved = kwsWeighbridgeRecordRepository.save(record);
+            if (saved) {
+                // 异步处理图片上传
+                updateImageUrls(request, record);
+                licensePlateValidateResponse.setStatus(true);
+                licensePlateValidateResponse.setCode(200);
+                licensePlateValidateResponse.setMessage("数据上报成功");
+                LicensePlateValidateResponse.Data data = new LicensePlateValidateResponse.Data();
+                data.setTimestamp(resolveSecondTimestamp(request.getTimestamp()));
+                data.setScreen_message("数据上报成功");
+                data.setVoice_message("数据上报成功");
+                licensePlateValidateResponse.setData(data);
+                log.info("地磅数据保存成功 - ID: {}, 车牌: {}", record.getId(), record.getTruckNo());
+                return licensePlateValidateResponse;
+            } else {
+                log.error("地磅数据保存失败 - 车牌: {}", request.getLicensePlate());
+                return getLicensePlateValidateResponse(request, licensePlateValidateResponse);
+            }
+
+        } catch (Exception e) {
+            log.error("地磅数据上报处理异常", e);
+            return getLicensePlateValidateResponse(request, licensePlateValidateResponse);
+        }
+    }
+    private void updateImageUrls(WeighbridgePushRequest request, KwsWeighbridgeRecord record) {
+        MultipartFile[] images = request.getImages();
+        if (images == null || images.length == 0) {
+            return;
+        }
+
+        int validImageCount = (int) java.util.Arrays.stream(images)
+                .filter(Objects::nonNull)
+                .count();
+        if (validImageCount == 0) {
+            return;
+        }
+
+        // kws_weighbridge_record 当前没有图片URL字段,先只记录上传事实,避免保留无效的旧依赖代码。
+        log.info("地磅记录收到图片但当前未落库, recordId: {}, truckNo: {}, imageCount: {}",
+                record.getId(), request.getLicensePlate(), validImageCount);
+    }
+    private static LicensePlateValidateResponse getLicensePlateValidateResponse(WeighbridgePushRequest request, LicensePlateValidateResponse licensePlateValidateResponse) {
+
+        licensePlateValidateResponse.setStatus(false);
+        licensePlateValidateResponse.setCode(400);
+        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.setVoice_message("数据上报失败");
+        licensePlateValidateResponse.setData(data);
+        return licensePlateValidateResponse;
+    }
+
+    private KwsWeighbridgeRecord buildWeighbridgeRecord(WeighbridgePushRequest request, Long weighbridgeId) {
+        Date now = new Date();
+        return new KwsWeighbridgeRecord()
+                .setWeighbridgeId(weighbridgeId)
+                .setTruckNo(request.getLicensePlate().trim())
+                .setWeight(request.getGrossWeight())
+                .setReceiveTime(resolveReceiveTime(request.getTimestamp()))
+                .setCreateBy(0L)
+                .setCreateTime(now)
+                .setUpdateBy(0L)
+                .setUpdateTime(now)
+                .setDelFlag(0);
+    }
+
+    private Date resolveReceiveTime(Long timestamp) {
+        long secondTimestamp = resolveSecondTimestamp(timestamp);
+        return new Date(secondTimestamp * 1000);
+    }
+
+    private long resolveSecondTimestamp(Long timestamp) {
+        if (timestamp == null) {
+            return System.currentTimeMillis() / 1000;
+        }
+        String timestampStr = timestamp.toString();
+        if (timestampStr.length() == 13) {
+            return timestamp / 1000;
+        }
+        return timestamp;
+    }
+
 }

+ 18 - 0
sckw-modules/sckw-system/src/main/java/com/sckw/system/service/ValidateLicensePlateService.java

@@ -0,0 +1,18 @@
+package com.sckw.system.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.sckw.system.model.ValidateLicensePlate;
+
+
+/**
+ * @Author: cxf
+ * @CreateTime: 2026-01-21
+ * @Description: 地磅过磅记录Service接口
+ * @Version: 1.0
+ */
+public interface ValidateLicensePlateService extends IService<ValidateLicensePlate> {
+
+    ValidateLicensePlate queryByLicensePlate(String licensePlate, String uuid);
+
+    ValidateLicensePlate queryByLicensePlate( String licensePlate);
+}

+ 36 - 0
sckw-modules/sckw-system/src/main/java/com/sckw/system/service/ValidateLicensePlateServiceImpl.java

@@ -0,0 +1,36 @@
+package com.sckw.system.service;
+
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+
+import com.sckw.system.dao.ValidateLicensePlateMapper;
+import com.sckw.system.model.ValidateLicensePlate;
+import org.springframework.stereotype.Service;
+
+/**
+ * @Author: cxf
+ * @CreateTime: 2026-01-21
+ * @Description: 地磅过磅记录Service实现类
+ * @Version: 1.0
+ */
+@Service
+public class ValidateLicensePlateServiceImpl extends ServiceImpl<ValidateLicensePlateMapper, ValidateLicensePlate> implements ValidateLicensePlateService {
+
+    @Override
+    public ValidateLicensePlate queryByLicensePlate(String licensePlate, String uuid) {
+        return getOne(Wrappers.<ValidateLicensePlate>lambdaQuery()
+                .eq(ValidateLicensePlate::getLicensePlate, licensePlate)
+                .eq(ValidateLicensePlate::getUuid, uuid)
+                .eq(ValidateLicensePlate::getStatus, 0)
+                .last("limit 1"));
+    }
+
+    @Override
+    public ValidateLicensePlate queryByLicensePlate(String licensePlate) {
+        return getOne(Wrappers.<ValidateLicensePlate>lambdaQuery()
+                .eq(ValidateLicensePlate::getLicensePlate, licensePlate)
+                .eq(ValidateLicensePlate::getStatus, 0)
+                .last("limit 1"));
+    }
+
+}

+ 10 - 0
sql/2026/04/2026_04_08_validate_license_plate.sql

@@ -0,0 +1,10 @@
+CREATE TABLE validate_License_Plate (
+                                        `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键ID',
+                                        license_plate VARCHAR(20) NOT NULL DEFAULT '' COMMENT '车牌号',
+                                        uuid VARCHAR(20) NOT NULL DEFAULT '' COMMENT '厂商来源标识',
+                                        status tinyint NOT NULL DEFAULT '0' COMMENT '状态,0=可用,1=不可用',
+                                        created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '记录创建时间',
+                                        updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '记录更新时间',
+                                        PRIMARY KEY (`id`),
+                                        KEY `idx_license_plate` (`license_plate`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='车牌验证表';