diff --git a/src/main/java/com/iot/transport/jt808/controller/DeviceController.java b/src/main/java/com/iot/transport/jt808/controller/DeviceController.java index 343234c..7a0c041 100644 --- a/src/main/java/com/iot/transport/jt808/controller/DeviceController.java +++ b/src/main/java/com/iot/transport/jt808/controller/DeviceController.java @@ -2,6 +2,7 @@ package com.iot.transport.jt808.controller; import com.iot.transport.jt808.common.CommonResult; import com.iot.transport.jt808.entity.dto.LocationDto; +import com.iot.transport.jt808.entity.response.DeviceUploadResp; import com.iot.transport.jt808.service.ApiLogService; import com.iot.transport.jt808.service.DeviceService; import lombok.extern.slf4j.Slf4j; @@ -10,6 +11,8 @@ import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; import org.springframework.web.servlet.mvc.method.annotation.SseEmitter; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; import java.util.Date; import java.util.Map; import java.util.List; @@ -31,7 +34,7 @@ public class DeviceController { @Autowired private ApiLogService apiLogService; - + private final SessionManager sessionManager = SessionManager.getInstance(); private final DataEncoder dataEncoder = new DataEncoder(); @@ -45,11 +48,11 @@ public class DeviceController { String imei = (String) payload.get("imei"); String cmdType = (String) payload.get("cmd"); List params = (List) payload.get("params"); - + String commandStr = ""; - + if (cmdType == null) return CommonResult.failed("cmd is required"); - + switch (cmdType.toLowerCase()) { case "reboot": commandStr = CommandBuilder.reboot(); @@ -60,26 +63,26 @@ public class DeviceController { } break; case "workmode": - if (params != null && params.size() >= 2) { - commandStr = CommandBuilder.setWorkMode(Integer.parseInt(params.get(0)), Integer.parseInt(params.get(1))); - } - break; + if (params != null && params.size() >= 2) { + commandStr = CommandBuilder.setWorkMode(Integer.parseInt(params.get(0)), Integer.parseInt(params.get(1))); + } + break; case "realtime": - if (params != null && params.size() >= 2) { - commandStr = CommandBuilder.setRealtimeMode(Integer.parseInt(params.get(0)), Integer.parseInt(params.get(1))); - } - break; + if (params != null && params.size() >= 2) { + commandStr = CommandBuilder.setRealtimeMode(Integer.parseInt(params.get(0)), Integer.parseInt(params.get(1))); + } + break; case "custom": // 自定义指令内容 - commandStr = (String) payload.get("raw"); - break; + commandStr = (String) payload.get("raw"); + break; default: return CommonResult.failed("Unknown command type: " + cmdType); } - + if (commandStr == null || commandStr.isEmpty()) { return CommonResult.failed("Invalid command parameters"); } - + // 调用 DeviceService 发送 8300 指令 (这里直接复用现有的 sendTextCommand 逻辑) // 也可以直接在这里调用 return sendTextCommand(imei, commandStr, 1); @@ -89,18 +92,18 @@ public class DeviceController { * 下发文本信息指令 (0x8300) */ @PostMapping("/command/text") - public CommonResult sendTextCommand(@RequestParam String phone, - @RequestParam String content, - @RequestParam(defaultValue = "1") int flag) { // 默认为1(紧急) + public CommonResult sendTextCommand(@RequestParam String phone, + @RequestParam String content, + @RequestParam(defaultValue = "1") int flag) { // 默认为1(紧急) try { Session session = findSessionByPhone(phone); if (session == null) { return CommonResult.failed("设备未连接: " + phone); } - + TextInfoDownPack pack = new TextInfoDownPack(flag, content); byte[] bytes = dataEncoder.encode4TextInfoDown(pack, session); - + session.getChannel().writeAndFlush(io.netty.buffer.Unpooled.copiedBuffer(bytes)).sync(); log.info("Send text command to {}: {}", phone, content); return CommonResult.success("指令下发成功: " + content); @@ -120,10 +123,10 @@ public class DeviceController { if (session == null) { return CommonResult.failed("设备未连接: " + phone); } - + LocationInquiryPack pack = new LocationInquiryPack(); byte[] bytes = dataEncoder.encode4LocationInquiry(pack, session); - + session.getChannel().writeAndFlush(io.netty.buffer.Unpooled.copiedBuffer(bytes)).sync(); log.info("Send location inquiry to {}", phone); return CommonResult.success("指令下发成功"); @@ -132,7 +135,7 @@ public class DeviceController { return CommonResult.failed("指令下发失败: " + e.getMessage()); } } - + // Helper to find session by phone private Session findSessionByPhone(String phone) { return sessionManager.findByTerminalPhone(phone); @@ -147,10 +150,10 @@ public class DeviceController { location.setTime(new Date()); } deviceService.processLocation( - location.getImei(), - location.getLat(), - location.getLon(), - location.getSpeed(), + location.getImei(), + location.getLat(), + location.getLon(), + location.getSpeed(), location.getTime() ); return ResponseEntity.ok("Received"); @@ -162,11 +165,26 @@ public class DeviceController { * 2. 推送到前端页面 */ @PostMapping("/upload") - public CommonResult receiveDeviceData(@RequestBody Map payload) { + public DeviceUploadResp receiveDeviceData(@RequestBody Map payload) { // 广播日志(同时会记录到服务器日志文件) apiLogService.broadcastLog("API", payload); - - return CommonResult.success("设备数据接收成功"); + + // 2. 组装设备响应 + DeviceUploadResp resp = new DeviceUploadResp(); + resp.setStatusCode(0); + resp.setTime( + LocalDateTime.now() + .format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")) + ); + resp.setOpen("0800"); + resp.setClose("2300"); + resp.setSaveCycle(1); + resp.setUpCycle(1); + resp.setLicense("0"); + resp.setDirection("twoWay"); + resp.setUpgradeUrl("http://op.foorir.com/upgrade/2023120.bin"); + + return resp; } /** @@ -176,7 +194,7 @@ public class DeviceController { public SseEmitter streamLogs() { return apiLogService.createEmitter(); } - + @GetMapping("/health") public String health() { return "OK"; diff --git a/src/main/java/com/iot/transport/jt808/entity/response/DeviceUploadResp.java b/src/main/java/com/iot/transport/jt808/entity/response/DeviceUploadResp.java new file mode 100644 index 0000000..f46075c --- /dev/null +++ b/src/main/java/com/iot/transport/jt808/entity/response/DeviceUploadResp.java @@ -0,0 +1,17 @@ +package com.iot.transport.jt808.entity.response; + +import lombok.Data; + +@Data +public class DeviceUploadResp { + + private Integer statusCode; // 0 正常 1 未绑定平台 2 解析 json 出错 + private String time; // yyyyMMddHHmmss + private String open; // 营业开始时间 + private String close; // 营业结束时间 + private Integer saveCycle; // 存储周期 + private Integer upCycle; // 上报周期 + private String license; // 0 正常 1 证书到期 + private String direction; // twoWay / onlyIn / onlyOut / exchange + private String upgradeUrl; // 升级地址(无升级可为空) +}