feat(环保门禁): 巡检设备数据回传开放接口(无人机/机器人/AI摄像头)、无人值守地磅模块(表+后端+日报)、车辆采集照片字段、修复车辆修改接口缺@RequestBody
已添加7个文件
已修改3个文件
596 ■■■■■ 文件已修改
doc/环保门禁-巡检数据回传接口说明.md 159 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/envaccess/controller/EnvInspectionController.java 148 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/envaccess/controller/EnvWeighbridgeController.java 82 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/envaccess/mapper/EnvWeighbridgeSystemMapper.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/envaccess/pojo/EnvWeighbridgeSystem.java 76 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/envaccess/service/IEnvWeighbridgeSystemService.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/envaccess/service/impl/EnvWeighbridgeSystemServiceImpl.java 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/vehicleInformationCollectionReview/controller/VehicleInformationCollectionController.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/vehicleInformationCollectionReview/pojo/VehicleInformationCollectionReview.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/envaccess/EnvWeighbridgeSystemMapper.xml 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
doc/»·±£ÃŽû-Ѳ¼ìÊý¾Ý»Ø´«½Ó¿Ú˵Ã÷.md
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,159 @@
# çŽ¯ä¿é—¨ç¦ç³»ç»Ÿ â€” æ— äººæœº / æœºå™¨äºº / AI æ‘„像头 å·¡æ£€æ•°æ®å›žä¼ æŽ¥å£è¯´æ˜Ž
> ç”¨äºŽè¯æ˜Ž"智能巡检可支持无人机、机器人联动巡检数据回传"。
> ä»»ä½•具备 HTTP è°ƒç”¨èƒ½åŠ›çš„è®¾å¤‡æˆ–ç¬¬ä¸‰æ–¹å¹³å°ï¼ˆæ— äººæœºæœºåœºã€å·¡æ£€æœºå™¨äººä¸­æŽ§ã€AI è§†é¢‘分析盒子)都可以调用本接口上报巡检数据,
> ä¸ŠæŠ¥åŽæ•°æ®ç«‹å³è½åº“,并可在系统「智能巡检管理 â†’ å›žä¼ è¯¦æƒ…」中查看。
## 1. æŽ¥å£åŸºæœ¬ä¿¡æ¯
| é¡¹ | å€¼ |
|---|---|
| æŽ¥å£åœ°å€ | `http://10.136.58.73:7003/environmentAccess/inspection/callback` |
| è¯·æ±‚方法 | `POST` |
| Content-Type | `application/json;charset=utf-8` |
| é‰´æƒ | è¯·æ±‚体中携带 `secret`(默认 `hbmjxt-callback-2026`,可通过配置项 `envaccess.callback.secret` ä¿®æ”¹ï¼‰ |
| ç™»å½•要求 | æ— ï¼ˆè®¾å¤‡æ— éœ€ç™»å½•,走 secret æ ¡éªŒï¼‰ |
## 2. è¯·æ±‚参数
| å‚æ•° | ç±»åž‹ | å¿…å¡« | è¯´æ˜Ž |
|---|---|---|---|
| `secret` | string | æ˜¯ | æŽ¥å£å¯†é’¥ |
| `tenantId` | number | æ˜¯ | ç§Ÿæˆ· ID。芯导环保为 `222` |
| `inspectionId` | number | å¦ | æŒ‡å®šå·¡æ£€ä»»åŠ¡ ID。不传则按 `area` åŒ¹é…æœ€è¿‘一条未取消任务;仍无匹配则自动新建一条巡检记录 |
| `area` | string | å»ºè®® | å·¡æ£€åŒºåŸŸï¼Œå¦‚ `东门区域` |
| `deviceType` | string | å»ºè®® | æ•°æ®æ¥æºï¼š`UAV` æ— äººæœº / `ROBOT` å·¡æ£€æœºå™¨äºº / `CAMERA` AI æ‘„像头 |
| `deviceCode` | string | å»ºè®® | è®¾å¤‡ç¼–号,如 `UAV-M350-001` |
| `collectedAt` | string | å¦ | è®¾å¤‡é‡‡é›†æ—¶é—´ï¼Œ`yyyy-MM-dd HH:mm:ss` |
| `aiSummary` | string | å¦ | AI åˆ†æžç»“论摘要 |
| `aiObjects` | array | å¦ | AI è¯†åˆ«æ¡ç›®ï¼Œæ¯é¡¹å« `object`(识别对象)、`conclusion`(识别结论)、`confidence`(置信度 0~1)、`frameTime`(截帧时间) |
| `longitude` | number | å¦ | é‡‡é›†ç‚¹ç»åº¦ |
| `latitude` | number | å¦ | é‡‡é›†ç‚¹çº¬åº¦ |
| `altitude` | number | å¦ | ä½œä¸šé«˜åº¦ï¼ˆç±³ï¼‰ã€‚地面机器人可传 0 |
| `battery` | number | å¦ | è®¾å¤‡ç”µé‡ç™¾åˆ†æ¯” |
| `photos` | array | å¦ | çŽ°åœºç…§ç‰‡ URL åˆ—表 |
| `track` | array | å¦ | å·¡æ£€è½¨è¿¹ç‚¹ï¼Œæ¯é¡¹å« `t`(时间)、`lng`、`lat`、`alt` |
## 3. è¯·æ±‚示例
### 3.1 æ— äººæœºå·¡æ£€ä¸ŠæŠ¥
```bash
curl -X POST "http://10.136.58.73:7003/environmentAccess/inspection/callback" \
  -H "Content-Type: application/json" \
  -d '{
    "secret": "hbmjxt-callback-2026",
    "tenantId": 222,
    "area": "东门区域",
    "deviceType": "UAV",
    "deviceCode": "UAV-M350-001",
    "collectedAt": "2026-10-24 09:12:10",
    "aiSummary": "本次巡检识别 3 ç±»ç›®æ ‡ï¼Œå‘现 1 å¤„人员未佩戴安全帽",
    "aiObjects": [
      {"object": "人员未佩戴安全帽", "conclusion": "未按要求佩戴,已推送整改", "confidence": 0.93, "frameTime": "2026-10-24 09:12:35"},
      {"object": "车牌识别通过", "conclusion": "苏A8F372 æ­£å¸¸æ”¾è¡Œ", "confidence": 0.99, "frameTime": "2026-10-24 09:13:02"}
    ],
    "longitude": 120.382145,
    "latitude": 31.298512,
    "altitude": 45.6,
    "battery": 78,
    "photos": [],
    "track": [
      {"t": "09:12:10", "lng": 120.382145, "lat": 31.298512, "alt": 45.6},
      {"t": "09:13:02", "lng": 120.382301, "lat": 31.298604, "alt": 52.1}
    ]
  }'
```
### 3.2 å·¡æ£€æœºå™¨äººä¸ŠæŠ¥ï¼ˆåœ°é¢è®¾å¤‡ï¼Œaltitude ä¼  0)
```bash
curl -X POST "http://10.136.58.73:7003/environmentAccess/inspection/callback" \
  -H "Content-Type: application/json" \
  -d '{
    "secret": "hbmjxt-callback-2026",
    "tenantId": 222,
    "area": "仓储区域",
    "deviceType": "ROBOT",
    "deviceCode": "ROBOT-XD-S2-01",
    "collectedAt": "2026-10-24 14:09:50",
    "aiSummary": "本次巡检识别 4 ç±»ç›®æ ‡ï¼Œå‘现 1 å¤„消防通道占用",
    "aiObjects": [
      {"object": "消防通道", "conclusion": "通道被托盘临时占用,已通知清理", "confidence": 0.95, "frameTime": "2026-10-24 14:10:05"}
    ],
    "longitude": 120.381024,
    "latitude": 31.299348,
    "altitude": 0.9,
    "battery": 57
  }'
```
### 3.3 AI æ‘„像头上报(固定点位)
```bash
curl -X POST "http://10.136.58.73:7003/environmentAccess/inspection/callback" \
  -H "Content-Type: application/json" \
  -d '{
    "secret": "hbmjxt-callback-2026",
    "tenantId": 222,
    "area": "生产一区",
    "deviceType": "CAMERA",
    "deviceCode": "CAM-PROD1-05",
    "aiSummary": "本次轮巡识别 5 ç±»ç›®æ ‡ï¼Œå‘现 1 å¤„废气收集罩移位",
    "aiObjects": [
      {"object": "废气收集罩", "conclusion": "位置偏移约 15cm,影响收集效率", "confidence": 0.87, "frameTime": "2026-10-24 09:35:44"}
    ],
    "longitude": 120.384011,
    "latitude": 31.299772,
    "altitude": 7.2
  }'
```
## 4. å“åº”示例
成功:
```json
{
  "code": 200,
  "msg": "巡检数据回传成功",
  "data": {
    "inspectionId": 3,
    "created": false,
    "deviceCode": "UAV-M350-001",
    "deviceType": "UAV",
    "area": "东门区域"
  }
}
```
| å­—段 | è¯´æ˜Ž |
|---|---|
| `inspectionId` | æ•°æ®å†™å…¥çš„巡检任务 ID |
| `created` | `true` è¡¨ç¤ºç³»ç»Ÿè‡ªåŠ¨æ–°å»ºäº†ä¸€æ¡å·¡æ£€è®°å½•ï¼ˆåŽŸåŒºåŸŸæ²¡æœ‰åŒ¹é…ä»»åŠ¡ï¼‰ |
失败:
| è¿”回 | åŽŸå›  |
|---|---|
| `secret æ ¡éªŒå¤±è´¥` | è¯·æ±‚体 `secret` ä¸Žé…ç½®ä¸ä¸€è‡´ |
| `tenantId ä¸èƒ½ä¸ºç©º` | æœªä¼ ç§Ÿæˆ· ID |
| `回传数据不能为空` | è¯·æ±‚体为空 |
## 5. ä¸ŠæŠ¥åŽåœ¨å“ªé‡Œçœ‹
登录系统 â†’ **环保门禁 â†’ æ™ºèƒ½å·¡æ£€ç®¡ç†** â†’ æ‰¾åˆ°å¯¹åº”区域的巡检记录 â†’ ç‚¹æ“ä½œåˆ— **「回传详情」**:
- **数据来源**:来源类型(无人机/巡检机器人/AI æ‘„像头)、设备编号、巡检区域、设备电量、采集时间、系统接收时间、采集坐标、作业高度
- **AI è§†é¢‘分析结果**:分析结论摘要 + ç»“构化识别条目表格(识别对象、识别结论、置信度%、截帧时间)
- **现场采集照片**:设备上报的 `photos` ä¼šä»¥ç¼©ç•¥å›¾å±•示,可点击放大
- **设备巡检轨迹**:`track` ä¼šä»¥è¡¨æ ¼å±•示时间/经纬度/高度
## 6. çŽ°åœºæ¼”ç¤ºæ­¥éª¤ï¼ˆå»ºè®®ï¼‰
1. æµè§ˆå™¨æ‰“开系统 â†’ çŽ¯ä¿é—¨ç¦ â†’ æ™ºèƒ½å·¡æ£€ç®¡ç†ï¼Œæ‰¾åˆ°ã€Œä¸œé—¨åŒºåŸŸã€çš„记录,点「回传详情」给客户看当前数据
2. æ‰“å¼€ Postman,粘贴第 3.1 èŠ‚çš„ JSON,点 Send
3. å›žåˆ°æµè§ˆå™¨ï¼Œ**刷新列表**,再点「回传详情」—— ç³»ç»ŸæŽ¥æ”¶æ—¶é—´ã€AI è¯†åˆ«æ¡ç›®ä¼šå˜æˆåˆšåˆšä¸ŠæŠ¥çš„内容
4. å¦‚果换一个不存在的区域(如 `"area": "北厂区"`),响应里 `created` ä¼šæ˜¯ `true`,列表会**自动多出一条**该区域的巡检记录
第 3、4 æ­¥å°±æ˜¯"可支持设备联动回传"的直接证据:**接口真实存在,数据真实入库,页面真实可见**。
src/main/java/com/ruoyi/envaccess/controller/EnvInspectionController.java
@@ -1,16 +1,24 @@
package com.ruoyi.envaccess.controller;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.ruoyi.common.handler.CustomTenantLineHandler;
import com.ruoyi.framework.aspectj.lang.annotation.Anonymous;
import com.ruoyi.framework.aspectj.lang.annotation.Log;
import com.ruoyi.framework.aspectj.lang.enums.BusinessType;
import com.ruoyi.framework.web.domain.AjaxResult;
import com.ruoyi.envaccess.pojo.EnvInspection;
import com.ruoyi.envaccess.service.IEnvInspectionService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
/**
 * çŽ¯ä¿é—¨ç¦--智能巡检台账(含路径规划/AI视频分析/报告/无人机机器人,AI与无人机字段预留)
@@ -67,4 +75,144 @@
    public void export(HttpServletResponse response, EnvInspection req) {
        envInspectionService.export(response, req);
    }
    @Value("${envaccess.callback.secret:hbmjxt-callback-2026}")
    private String callbackSecret;
    private static final ObjectMapper CALLBACK_MAPPER = new ObjectMapper();
    /**
     * æ— äººæœº / æœºå™¨äºº / AI æ‘„像头 å·¡æ£€æ•°æ®å›žä¼ ï¼ˆå¯¹å¤–开放接口,供第三方设备调用)
     *
     * è¯·æ±‚示例(POST JSON):
     * {
     *   "secret": "hbmjxt-callback-2026",
     *   "tenantId": 222,
     *   "inspectionId": 3,                    // å¯é€‰ï¼Œä¸ä¼ åˆ™æŒ‰ area åŒ¹é…æœ€è¿‘一条未取消任务,再没有就新建
     *   "area": "东门区域",
     *   "deviceType": "UAV",                  // UAV æ— äººæœº / ROBOT æœºå™¨äºº / CAMERA æ‘„像头
     *   "deviceCode": "UAV-M350-001",
     *   "collectedAt": "2026-10-24 09:12:35",
     *   "aiSummary": "共识别 5 ç±»ç›®æ ‡ï¼Œå‘现 1 å¤„未佩戴安全帽",
     *   "aiObjects": [{"object":"人员未佩戴安全帽","conclusion":"未按要求佩戴","confidence":0.93,"frameTime":"2026-10-24 09:12:35"}],
     *   "longitude": 120.382145, "latitude": 31.298512, "altitude": 45.6, "battery": 78,
     *   "photos": ["/profile/upload/uav_east_01.jpg"],
     *   "track": [{"t":"09:12:10","lng":120.3821,"lat":31.2985}]
     * }
     */
    @Anonymous
    @PostMapping("/callback")
    public AjaxResult callback(@RequestBody Map<String, Object> payload) {
        if (payload == null || payload.isEmpty()) {
            return AjaxResult.error("回传数据不能为空");
        }
        if (!callbackSecret.equals(String.valueOf(payload.get("secret")))) {
            return AjaxResult.error("secret æ ¡éªŒå¤±è´¥ï¼Œè¯·åœ¨è¯·æ±‚体中携带正确的 secret");
        }
        Long tenantId = toLong(payload.get("tenantId"));
        if (tenantId == null) {
            return AjaxResult.error("tenantId ä¸èƒ½ä¸ºç©º");
        }
        String area = payload.get("area") == null ? "未指定区域" : String.valueOf(payload.get("area"));
        String deviceType = payload.get("deviceType") == null ? "UAV" : String.valueOf(payload.get("deviceType"));
        String deviceCode = payload.get("deviceCode") == null ? deviceType + "-UNKNOWN" : String.valueOf(payload.get("deviceCode"));
        Map<String, Object> ai = new LinkedHashMap<>();
        ai.put("summary", payload.get("aiSummary") == null ? "本次回传未附带 AI è¯†åˆ«ç»“论" : payload.get("aiSummary"));
        ai.put("objects", payload.get("aiObjects") == null ? new ArrayList<>() : payload.get("aiObjects"));
        Map<String, Object> uav = new LinkedHashMap<>();
        uav.put("deviceType", deviceType);
        uav.put("deviceCode", deviceCode);
        uav.put("area", area);
        uav.put("collectedAt", payload.get("collectedAt") == null ? "" : payload.get("collectedAt"));
        uav.put("longitude", payload.get("longitude"));
        uav.put("latitude", payload.get("latitude"));
        uav.put("altitude", payload.get("altitude"));
        uav.put("battery", payload.get("battery"));
        uav.put("photos", payload.get("photos") == null ? new ArrayList<>() : payload.get("photos"));
        uav.put("track", payload.get("track") == null ? new ArrayList<>() : payload.get("track"));
        uav.put("receivedAt", new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
        String aiJson;
        String uavJson;
        try {
            aiJson = CALLBACK_MAPPER.writeValueAsString(ai);
            uavJson = CALLBACK_MAPPER.writeValueAsString(uav);
        } catch (Exception e) {
            return AjaxResult.error("回传数据序列化失败:" + e.getMessage());
        }
        EnvInspection target = null;
        Long inspectionId = toLong(payload.get("inspectionId"));
        if (inspectionId != null) {
            target = envInspectionService.getById(inspectionId);
        }
        if (target == null) {
            com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<EnvInspection> w =
                    new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<>();
            w.eq(EnvInspection::getArea, area).ne(EnvInspection::getStatus, 3)
                    .orderByDesc(EnvInspection::getId).last("limit 1");
            target = envInspectionService.getOne(w, false);
        }
        boolean created = false;
        if (target == null) {
            target = new EnvInspection();
            target.setInspectionName(area + " æ™ºèƒ½å·¡æ£€ï¼ˆè®¾å¤‡å›žä¼ ï¼‰");
            target.setInspectionType(2);
            target.setArea(area);
            target.setStatus(2);
            target.setPlanStartTime(new Date());
            target.setPlanEndTime(new Date());
            target.setActualStartTime(new Date());
            target.setActualEndTime(new Date());
            target.setInspector(deviceCode);
            target.setRoutePlan("由 " + deviceType + " è‡ªåŠ¨è§„åˆ’å¹¶æ‰§è¡Œ");
            target.setInspectionResult("设备自动巡检已完成,识别结果详见回传数据。");
            target.setTenantId(tenantId);
            created = true;
        }
        target.setAiAnalysis(aiJson);
        target.setUavData(uavJson);
        if (target.getStatus() != null && target.getStatus() == 0) {
            target.setStatus(2);
        }
        if (target.getTenantId() == null) {
            target.setTenantId(tenantId);
        }
        // è®¾å¤‡å›žè°ƒæ²¡æœ‰ç™»å½•上下文,临时跳过租户插件,tenant_id å·²åœ¨ä¸Šé¢æ˜¾å¼å†™å…¥
        CustomTenantLineHandler.TEMP_IGNORE.set(Boolean.TRUE);
        try {
            if (created) {
                envInspectionService.save(target);
            } else {
                envInspectionService.updateById(target);
            }
        } catch (Exception e) {
            return AjaxResult.error("回传数据落库失败:" + e.getMessage());
        } finally {
            CustomTenantLineHandler.TEMP_IGNORE.remove();
        }
        Map<String, Object> result = new LinkedHashMap<>();
        result.put("inspectionId", target.getId());
        result.put("created", created);
        result.put("deviceCode", deviceCode);
        result.put("deviceType", deviceType);
        result.put("area", area);
        return AjaxResult.success("巡检数据回传成功", result);
    }
    private Long toLong(Object v) {
        if (v == null) {
            return null;
        }
        try {
            return Long.valueOf(String.valueOf(v).trim());
        } catch (NumberFormatException e) {
            return null;
        }
    }
}
src/main/java/com/ruoyi/envaccess/controller/EnvWeighbridgeController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,82 @@
package com.ruoyi.envaccess.controller;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.envaccess.pojo.EnvWeighbridgeSystem;
import com.ruoyi.envaccess.service.IEnvWeighbridgeSystemService;
import com.ruoyi.framework.aspectj.lang.annotation.Log;
import com.ruoyi.framework.aspectj.lang.enums.BusinessType;
import com.ruoyi.framework.web.domain.AjaxResult;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
/**
 * çŽ¯ä¿é—¨ç¦--无人值守地磅管理 / æŠ¥è¡¨ä¸­å¿ƒ
 */
@RestController
@RequestMapping("/environmentAccess")
public class EnvWeighbridgeController {
    @Resource
    private IEnvWeighbridgeSystemService envWeighbridgeSystemService;
    @GetMapping("/weighbridgeSystemPage")
    public AjaxResult page(Page page, EnvWeighbridgeSystem req) {
        return AjaxResult.success(envWeighbridgeSystemService.listPage(page, req));
    }
    @GetMapping("/weighbridgeSystemInfo")
    public AjaxResult info(@RequestParam Long id) {
        return AjaxResult.success(envWeighbridgeSystemService.getById(id));
    }
    @PostMapping("/weighbridgeSystemAdd")
    @Log(title = "无人值守地磅-新增", businessType = BusinessType.INSERT)
    public AjaxResult add(@RequestBody EnvWeighbridgeSystem req) {
        req.setId(null);
        fillNetWeight(req);
        LocalDateTime now = LocalDateTime.now();
        req.setCreateTime(now);
        req.setUpdateTime(now);
        return envWeighbridgeSystemService.save(req) ? AjaxResult.success() : AjaxResult.error("新增失败");
    }
    @PutMapping("/weighbridgeSystemUpdate")
    @Log(title = "无人值守地磅-修改", businessType = BusinessType.UPDATE)
    public AjaxResult update(@RequestBody EnvWeighbridgeSystem req) {
        fillNetWeight(req);
        req.setUpdateTime(LocalDateTime.now());
        return envWeighbridgeSystemService.updateById(req) ? AjaxResult.success() : AjaxResult.error("修改失败");
    }
    @DeleteMapping("/weighbridgeSystemDelete")
    @Log(title = "无人值守地磅-删除", businessType = BusinessType.DELETE)
    public AjaxResult delete(@RequestBody List<Long> ids) {
        return envWeighbridgeSystemService.removeByIds(ids) ? AjaxResult.success() : AjaxResult.error("删除失败");
    }
    /**
     * æ¯æ—¥è¿‡ç£…统计报表(车次 / è´§é‡å¨ / åå·®çŽ‡ï¼‰
     */
    @GetMapping("/weighbridgeDailyReport")
    public AjaxResult dailyReport(@RequestParam(required = false) String startDate,
                                  @RequestParam(required = false) String endDate) {
        List<Map<String, Object>> list = envWeighbridgeSystemService.dailyReport(startDate, endDate);
        return AjaxResult.success(list);
    }
    /**
     * å‡€é‡ = æ¯›é‡ - çš®é‡
     */
    private void fillNetWeight(EnvWeighbridgeSystem req) {
        if (req.getNetWeight() == null
                && req.getGrossWeight() != null
                && req.getTareWeight() != null) {
            req.setNetWeight(req.getGrossWeight().subtract(req.getTareWeight()).setScale(2, BigDecimal.ROUND_HALF_UP));
        }
    }
}
src/main/java/com/ruoyi/envaccess/mapper/EnvWeighbridgeSystemMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,22 @@
package com.ruoyi.envaccess.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.envaccess.pojo.EnvWeighbridgeSystem;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
import java.util.Map;
@Mapper
public interface EnvWeighbridgeSystemMapper extends BaseMapper<EnvWeighbridgeSystem> {
    IPage<EnvWeighbridgeSystem> listPage(Page page, @Param("req") EnvWeighbridgeSystem req);
    /**
     * æŒ‰æ—¥èšåˆï¼šè½¦æ¬¡ã€è´§é‡(吨)、偏差率(%)
     */
    List<Map<String, Object>> dailyReport(@Param("startDate") String startDate, @Param("endDate") String endDate);
}
src/main/java/com/ruoyi/envaccess/pojo/EnvWeighbridgeSystem.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,76 @@
package com.ruoyi.envaccess.pojo;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDateTime;
/**
 * çŽ¯ä¿é—¨ç¦--无人值守地磅称重记录
 * env_weighbridge_system
 */
@TableName("env_weighbridge_system")
@Data
public class EnvWeighbridgeSystem implements Serializable {
    private static final long serialVersionUID = 1L;
    @TableId(type = IdType.AUTO)
    private Long id;
    @ApiModelProperty(value = "车牌号")
    private String plateNumber;
    @ApiModelProperty(value = "称重时间")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime weightTime;
    @ApiModelProperty(value = "皮重(kg)")
    private BigDecimal tareWeight;
    @ApiModelProperty(value = "毛重(kg)")
    private BigDecimal grossWeight;
    @ApiModelProperty(value = "净重(kg)")
    private BigDecimal netWeight;
    @ApiModelProperty(value = "偏离度(1-100)")
    private Integer positionOffset;
    @ApiModelProperty(value = "司机姓名")
    private String driverName;
    @ApiModelProperty(value = "联系电话")
    private String contactPhone;
    @ApiModelProperty(value = "货物名称")
    private String cargoName;
    @ApiModelProperty(value = "地磅编号")
    private String weighbridgeNumber;
    @ApiModelProperty(value = "备注")
    private String remark;
    @ApiModelProperty(value = "创建时间")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime createTime;
    @ApiModelProperty(value = "创建人")
    private Long createUser;
    @ApiModelProperty(value = "更新时间")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime updateTime;
    @ApiModelProperty(value = "更新人")
    private Long updateUser;
    @ApiModelProperty(value = "租户ID")
    private Long tenantId;
}
src/main/java/com/ruoyi/envaccess/service/IEnvWeighbridgeSystemService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,16 @@
package com.ruoyi.envaccess.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.ruoyi.envaccess.pojo.EnvWeighbridgeSystem;
import java.util.List;
import java.util.Map;
public interface IEnvWeighbridgeSystemService extends IService<EnvWeighbridgeSystem> {
    IPage<EnvWeighbridgeSystem> listPage(Page page, EnvWeighbridgeSystem req);
    List<Map<String, Object>> dailyReport(String startDate, String endDate);
}
src/main/java/com/ruoyi/envaccess/service/impl/EnvWeighbridgeSystemServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,34 @@
package com.ruoyi.envaccess.service.impl;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.envaccess.mapper.EnvWeighbridgeSystemMapper;
import com.ruoyi.envaccess.pojo.EnvWeighbridgeSystem;
import com.ruoyi.envaccess.service.IEnvWeighbridgeSystemService;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.Map;
@Service
@AllArgsConstructor
@Transactional(rollbackFor = Exception.class)
public class EnvWeighbridgeSystemServiceImpl
        extends ServiceImpl<EnvWeighbridgeSystemMapper, EnvWeighbridgeSystem>
        implements IEnvWeighbridgeSystemService {
    private EnvWeighbridgeSystemMapper envWeighbridgeSystemMapper;
    @Override
    public IPage<EnvWeighbridgeSystem> listPage(Page page, EnvWeighbridgeSystem req) {
        return envWeighbridgeSystemMapper.listPage(page, req);
    }
    @Override
    public List<Map<String, Object>> dailyReport(String startDate, String endDate) {
        return envWeighbridgeSystemMapper.dailyReport(startDate, endDate);
    }
}
src/main/java/com/ruoyi/vehicleInformationCollectionReview/controller/VehicleInformationCollectionController.java
@@ -32,7 +32,7 @@
    }
    // ä¿®æ”¹è½¦è¾†ä¿¡æ¯
    @PutMapping("/vehicleInfoUpdate")
    public AjaxResult updateRecord(VehicleInformationCollectionReview vehicleInformationCollectionReview){
    public AjaxResult updateRecord(@RequestBody VehicleInformationCollectionReview vehicleInformationCollectionReview){
        return AjaxResult.success(vehicleInformationCollectionReviewService.updateById(vehicleInformationCollectionReview));
    }
    // åˆ é™¤è½¦è¾†ä¿¡æ¯ï¼ˆæ”¯æŒæ‰¹é‡ï¼‰
src/main/java/com/ruoyi/vehicleInformationCollectionReview/pojo/VehicleInformationCollectionReview.java
@@ -80,6 +80,21 @@
    private String fuelType;
    /**
     * è½¦ç‰Œç…§ç‰‡
     */
    private String platePhoto;
    /**
     * è¡Œé©¶è¯ç…§ç‰‡
     */
    private String licensePhoto;
    /**
     * è½¦è¾†å…¨æ™¯ç…§ç‰‡
     */
    private String scenePhoto;
    /**
     * å®¡æ ¸çŠ¶æ€
     */
    private String reviewStatus;
src/main/resources/mapper/envaccess/EnvWeighbridgeSystemMapper.xml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,42 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.ruoyi.envaccess.mapper.EnvWeighbridgeSystemMapper">
    <select id="listPage" resultType="com.ruoyi.envaccess.pojo.EnvWeighbridgeSystem">
        SELECT * FROM env_weighbridge_system
        <where>
            <if test="req.plateNumber != null and req.plateNumber != ''">
                AND plate_number LIKE CONCAT('%',#{req.plateNumber},'%')
            </if>
            <if test="req.cargoName != null and req.cargoName != ''">
                AND cargo_name LIKE CONCAT('%',#{req.cargoName},'%')
            </if>
            <if test="req.driverName != null and req.driverName != ''">
                AND driver_name LIKE CONCAT('%',#{req.driverName},'%')
            </if>
            <if test="req.weighbridgeNumber != null and req.weighbridgeNumber != ''">
                AND weighbridge_number = #{req.weighbridgeNumber}
            </if>
        </where>
        ORDER BY weight_time DESC, id DESC
    </select>
    <select id="dailyReport" resultType="java.util.Map">
        SELECT
            DATE_FORMAT(weight_time, '%Y-%m-%d') AS date,
            COUNT(*) AS tripCount,
            ROUND(SUM(IFNULL(net_weight, IFNULL(gross_weight, 0) - IFNULL(tare_weight, 0))) / 1000, 2) AS cargoVolume,
            ROUND(AVG(IFNULL(position_offset, 0)), 2) AS deviationRate
        FROM env_weighbridge_system
        <where>
            <if test="startDate != null and startDate != ''">
                AND weight_time &gt;= #{startDate}
            </if>
            <if test="endDate != null and endDate != ''">
                AND weight_time &lt;= #{endDate}
            </if>
        </where>
        GROUP BY DATE_FORMAT(weight_time, '%Y-%m-%d')
        ORDER BY date
    </select>
</mapper>