zhanghaijun лет назад: 2
Родитель
Сommit
f4fb299790

+ 19 - 5
train-server/src/main/java/top/haijunit/train/controller/DemoController.java

@@ -1,18 +1,15 @@
 package top.haijunit.train.controller;
 
-import cn.hutool.core.util.IdUtil;
 import lombok.RequiredArgsConstructor;
 import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;
 import org.springframework.web.servlet.ModelAndView;
 import top.haijunit.common.domain.ResultData;
-import top.haijunit.train.device.entity.DeviceEntity;
-import top.haijunit.train.device.repository.DeviceRepository;
-import top.haijunit.train.device.domain.CommandEnum;
+import top.haijunit.train.utils.TrainWebSocketUtils;
 import top.haijunit.websocket.handler.WebSocketSessionHolder;
 
-import java.util.List;
 import java.util.Set;
 
 /**
@@ -39,4 +36,21 @@ public class DemoController {
     public ResultData<Set<String>> test() {
         return ResultData.success(WebSocketSessionHolder.getSessionsAll());
     }
+
+    /**
+     * <pre>
+     *     curl http://127.0.0.1:8086/demo/train/door/101/0
+     *     curl http://127.0.0.1:8086/demo/train/door/102/0
+     *     curl http://127.0.0.1:8086/demo/train/door/103/0
+     *     curl http://127.0.0.1:8086/demo/train/door/104/0
+     * </pre>
+     * @param train 列车
+     * @param state 开关门
+     * @return 执行结果
+     */
+    @GetMapping("/train/door/{train}/{state}")
+    public ResultData<String> openDoor(@PathVariable("train") String train, @PathVariable("state") int state) {
+        TrainWebSocketUtils.sendMessage(train, state);
+        return ResultData.success("");
+    }
 }

+ 2 - 0
train-server/src/main/java/top/haijunit/train/device/domain/CommandEnum.java

@@ -24,6 +24,8 @@ public enum CommandEnum {
     ROAD_SWITCH(10103, "", "", "道岔状态信息"),
     // 进路状态信息
     ROUTE_STATUS(10104, "", "", "进路状态信息"),
+    // 列车车门控制 | 列车编号 | 车门状态 (0关 1开)
+    TRAIN_OPEN_DOOR(10105, "trainNo", "state", "列车车门控制"),
     // 站台紧急停车操作指令 | 站台编号 | 运行方向 (1下行 2上行) 状态 (0弹起/复位 1按下)
     PLATFORM_PRESSING_STOP(20104, "platformNo", "isPressed", "站台紧急停车操作指令"),
     // AFC闸机信息 | 闸机编号 | 闸机状态 (0关闭 1开启 2暂停服务 3故障) | 闸机方向状态 (0进站 1出站)

+ 2 - 3
train-server/src/main/java/top/haijunit/train/device/repository/DeviceRepository.java

@@ -2,10 +2,9 @@ package top.haijunit.train.device.repository;
 
 import org.springframework.data.jpa.repository.JpaRepository;
 import org.springframework.stereotype.Repository;
+import top.haijunit.train.device.domain.CommandEnum;
 import top.haijunit.train.device.entity.DeviceEntity;
 
-import java.util.List;
-
 /**
  * @author zhanghaijun
  * @date 2023/11/24 11:36
@@ -14,5 +13,5 @@ import java.util.List;
 @Repository
 public interface DeviceRepository extends JpaRepository<DeviceEntity, Long> {
 
-    List<DeviceEntity> findByCode(String code);
+    DeviceEntity findByCommandAndCode(CommandEnum command, String code);
 }

+ 20 - 13
train-server/src/main/java/top/haijunit/train/device/service/DeviceService.java

@@ -32,7 +32,7 @@ public class DeviceService {
 
     private final DeviceRepository deviceRepository;
 
-    public void updateDevice(String msgStr) {
+    public DeviceEntity updateDevice(String msgStr) {
         JSONObject message = JSONUtil.parseObj(msgStr);
         if (!message.containsKey("cmd")) {
             throw new ServiceException(500, String.format("cmd指令解析失败,message:%s", msgStr));
@@ -42,14 +42,14 @@ public class DeviceService {
             throw new ServiceException(500, String.format("无效的cmd指令,message:%s", msgStr));
         }
         try {
-            this.saveDevice(command, JSONUtil.parseObj(message.get("data")));
+            return this.saveDevice(command, JSONUtil.parseObj(message.get("data")));
         } catch (Exception exception) {
             throw new ServiceException(HttpStatus.HTTP_INTERNAL_ERROR, String.format("设备信息解析失败,原因:%s", exception.getMessage()));
         }
     }
 
-    public void saveDevice(CommandEnum command, JSONObject data) {
-        if (StrUtil.isAllNotBlank(command.getNameStr(), command.getStatusStr())) {
+    public DeviceEntity saveDevice(CommandEnum command, JSONObject data) {
+        if (StrUtil.isBlank(command.getNameStr()) || StrUtil.isBlank(command.getStatusStr())) {
             throw new ServiceException(500, String.format("无法获取对应的参数,cmd: %s, data: %s", command.getCode(), data));
         }
         String code = Convert.toStr(data.get(command.getNameStr()));
@@ -57,15 +57,22 @@ public class DeviceService {
         if (StrUtil.isBlank(code) || null == status) {
             throw new ServiceException(500, String.format("参数值为空,cmd: %s, data: %s", command.getCode(), data));
         }
-        List<DeviceEntity> list = deviceRepository.findByCode(code);
-        deviceRepository.deleteAll(list);
-        DeviceEntity device = new DeviceEntity();
-        device.setCommand(command);
-        device.setCode(code);
+        DeviceEntity device = deviceRepository.findByCommandAndCode(command, code);
+        if (null == device) {
+            device = new DeviceEntity();
+            device.setCode(code);
+            device.setCommand(command);
+        }
         device.setStatus(status);
-        // 默认是中间站台
-        device.setStationId(Convert.toLong(data.get("stationId"), 104002L));
-        device.setJsonStr(data.toString());
-        deviceRepository.save(device);
+        device.setJsonStr(getJsonStr(command, device.getJsonStr(), data));
+        return deviceRepository.save(device);
+    }
+
+    private String getJsonStr(CommandEnum command, String str, JSONObject data) {
+        JSONObject result = StrUtil.isBlank(str) ? JSONUtil.createObj() : JSONUtil.parseObj(str);
+        data.remove(command.getNameStr());
+        data.remove(command.getStatusStr());
+        result.putAll(data);
+        return result.toString();
     }
 }

+ 49 - 4
train-server/src/main/java/top/haijunit/train/listener/MessageEventListener.java

@@ -1,11 +1,18 @@
 package top.haijunit.train.listener;
 
+import cn.hutool.core.convert.Convert;
 import cn.hutool.core.util.StrUtil;
+import cn.hutool.json.JSONObject;
+import cn.hutool.json.JSONUtil;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.context.ApplicationListener;
+import org.springframework.scheduling.annotation.Async;
 import org.springframework.stereotype.Component;
+import top.haijunit.train.device.domain.CommandEnum;
+import top.haijunit.train.device.entity.DeviceEntity;
 import top.haijunit.train.device.service.DeviceService;
+import top.haijunit.train.utils.TrainWebSocketUtils;
 import top.haijunit.websocket.event.MessageEvent;
 
 /**
@@ -26,11 +33,49 @@ public class MessageEventListener implements ApplicationListener<MessageEvent> {
             if (StrUtil.isBlank(event.getMessage())) {
                 return;
             }
-            try {
-                deviceService.updateDevice(event.getMessage());
-            } catch (RuntimeException exception) {
-                log.error("消息处理异常: {}", event.getMessage());
+            deviceMessageHandle(event.getMessage());
+        }
+    }
+
+    @Async
+    public void deviceMessageHandle(String message) {
+        try {
+            DeviceEntity entity = deviceService.updateDevice(message);
+            if (entity == null) {
+                return;
             }
+            log.info("设备信息更新成功: {}", entity.getCode());
+            switch (entity.getCommand()) {
+                case AFC_GATE_MACHINE_STATUS:
+                    TrainWebSocketUtils.sendMessage(CommandEnum.AFC_GATE_MACHINE, getMessage(CommandEnum.AFC_GATE_MACHINE, entity));
+                    break;
+                case AFC_TICKETING_AUTO_STATUS:
+                    TrainWebSocketUtils.sendMessage(CommandEnum.AFC_TICKETING_AUTO, getMessage(CommandEnum.AFC_TICKETING_AUTO, entity));
+                    break;
+                case ELEVATOR_VERTICAL_COMMAND:
+                    TrainWebSocketUtils.sendMessage(CommandEnum.ELEVATOR_VERTICAL, getMessage(CommandEnum.ELEVATOR_VERTICAL, entity));
+                case ELEVATOR_HAND_COMMAND:
+                    TrainWebSocketUtils.sendMessage(CommandEnum.ELEVATOR_HAND, getMessage(CommandEnum.ELEVATOR_HAND, entity));
+                default:
+                    // TrainWebSocketUtils.sendMessage(CommandEnum.PLATFORM_DOOR_LOCK, getMessage(CommandEnum.PLATFORM_DOOR_LOCK, entity));
+                    // TrainWebSocketUtils.sendMessage(CommandEnum.PLATFORM_DOOR_CONTROL, getMessage(CommandEnum.PLATFORM_DOOR_CONTROL, entity));
+
+            }
+        } catch (RuntimeException exception) {
+            log.error("消息处理异常: {}", message);
+        }
+    }
+
+    private JSONObject getMessage(CommandEnum command, DeviceEntity device) {
+        JSONObject data;
+        if (StrUtil.isAllNotBlank(device.getJsonStr())) {
+            data = JSONUtil.parseObj(device.getJsonStr());
+        } else {
+            data = JSONUtil.createObj();
         }
+        data.set(command.getNameStr(), device.getCode());
+        data.set(command.getStatusStr(), device.getStatus());
+        data.set("stationId", Convert.toLong(device.getStationId(), 104002L));
+        return data;
     }
 }

+ 2 - 3
train-server/src/main/java/top/haijunit/train/listener/TrainApplication.java

@@ -7,7 +7,6 @@ import org.springframework.boot.ApplicationRunner;
 import org.springframework.stereotype.Component;
 import top.haijunit.train.domain.entity.TrainEntity;
 import top.haijunit.train.domain.repository.TrainRepository;
-import top.haijunit.train.service.SectionService;
 import top.haijunit.train.simulation.domain.SectionItem;
 import top.haijunit.train.simulation.domain.TrainItem;
 import top.haijunit.train.simulation.train.ComputerService;
@@ -15,7 +14,6 @@ import top.haijunit.train.simulation.train.RouteComputerService;
 import top.haijunit.train.simulation.train.TrainSimulationHolder;
 
 import java.util.ArrayList;
-import java.util.Collection;
 import java.util.LinkedList;
 import java.util.List;
 
@@ -37,7 +35,8 @@ public class TrainApplication implements ApplicationRunner {
     public void run(ApplicationArguments args) {
         List<TrainEntity> list = trainRepository.findAll();
         // List<TrainEntity> list = trainRepository.findAllById(new ArrayList<>() {{
-        //     add(110001L);
+        //     add(110002L);
+        //     add(110003L);
         // }});
         // 列车初始化
         ArrayList<TrainItem> trainItems = new ArrayList<>();

+ 0 - 8
train-server/src/main/java/top/haijunit/train/simulation/train/RouteComputerService.java

@@ -35,14 +35,6 @@ public class RouteComputerService {
     private final RouteRepository routeRepository;
     private final ComputerService computerService;
 
-    public synchronized void init() {
-        Collection<TrainItem> trainItems = TrainSimulationHolder.getTrainItem();
-        for (TrainItem trainItem : trainItems) {
-            List<SectionItem> trainSectionList = getTrainSectionList(trainItem);
-            TrainSimulationHolder.addRouteList(trainItem.getTrainId(), this.getSectionList(new LinkedList<>(trainSectionList), trainItem));
-        }
-    }
-
     public void run(TrainItem train) {
         try {
             LinkedList<SectionItem> list = routeCompute(train);

+ 4 - 2
train-server/src/main/java/top/haijunit/train/simulation/train/TrainComputerService.java

@@ -15,10 +15,10 @@ import top.haijunit.train.simulation.domain.TrainItem;
 import top.haijunit.train.simulation.domain.TrainTravel;
 import top.haijunit.train.utils.CalculatorUtil;
 import top.haijunit.train.utils.NumberUtil;
+import top.haijunit.train.utils.TrainWebSocketUtils;
 
 import java.math.BigDecimal;
 import java.util.*;
-import java.util.stream.Collectors;
 
 /**
  * @author zhanghaijun
@@ -54,8 +54,10 @@ public class TrainComputerService {
         long nowMillis = System.currentTimeMillis();
         // 1、距离上一个周期 列车运行的距离
         BigDecimal distance = train.getDistance(nowMillis);
-        if (NumberUtil.isLessOrEqual(distance, BigDecimal.ZERO) && Math.abs(nowMillis - train.getUpdateTimeMillis()) <= TrainConstant.STOP_TIME_SECOND * 1000) {
+        long timeDifference = Math.abs(nowMillis - train.getUpdateTimeMillis());
+        if (NumberUtil.isLessOrEqual(distance, BigDecimal.ZERO) && timeDifference <= TrainConstant.STOP_TIME_SECOND * 1000) {
             // 停车状态 时间不足30S
+            TrainWebSocketUtils.sendMessage(train.getTrainNo(), timeDifference > (TrainConstant.STOP_TIME_SECOND - 2) * 1000 ? 1 : 0);
             return train;
         }
         if (NumberUtil.isGreater(distance, BigDecimal.ZERO)) {

+ 10 - 0
train-server/src/main/java/top/haijunit/train/utils/TrainWebSocketUtils.java

@@ -1,5 +1,7 @@
 package top.haijunit.train.utils;
 
+import cn.hutool.json.JSONObject;
+import cn.hutool.json.JSONUtil;
 import lombok.AllArgsConstructor;
 import lombok.Data;
 import lombok.experimental.UtilityClass;
@@ -21,6 +23,14 @@ public class TrainWebSocketUtils {
         WebSocketUtils.sendMessage(JsonUtils.toJsonString(new SocketMessage(command, message)));
     }
 
+    public static void sendMessage(String trainNo, int state) {
+        JSONObject object = JSONUtil.createObj();
+        object.set(CommandEnum.TRAIN_OPEN_DOOR.getNameStr(), trainNo);
+        object.set(CommandEnum.TRAIN_OPEN_DOOR.getStatusStr(), state);
+        sendMessage(CommandEnum.TRAIN_OPEN_DOOR, object);
+    }
+
+
     @Data
     @AllArgsConstructor
     public static class SocketMessage {

+ 6 - 6
train-server/src/main/resources/db/changelog/train/db_stop_sign.txt

@@ -1,9 +1,9 @@
 id,station_id,direction,selection_id,selection_off
-109001,105001,1,103005,10
-109002,105002,2,103018,135.63
-109003,105003,1,103007,10
-109004,105004,2,103020,135.63
-109005,105005,1,103009,10
-109006,105006,2,103022,135.63
+109001,105001,1,103005,5
+109002,105002,2,103018,140.63
+109003,105003,1,103007,5
+109004,105004,2,103020,140.63
+109005,105005,1,103009,5
+109006,105006,2,103022,140.63
 109007,-1,1,103014,1
 109008,-1,2,103026,149

+ 4 - 4
train-server/src/main/resources/db/changelog/train/db_train.txt

@@ -1,6 +1,6 @@
 id,name,train_length,section_id,section_offset
-110001,101,135.63,103009,10
-110002,103,135.63,103007,10
-110003,102,135.63,103020,140
-110004,104,135.63,103018,140
+110001,101,135.63,103009,5
+110002,103,135.63,103007,5
+110003,102,135.63,103020,140.63
+110004,104,135.63,103018,140.63