Commit 1c67c67919912fe829a5efa528bb43995efb2f40

Authored by 潘钊
1 parent e25f09c9

update...

Showing 23 changed files with 683 additions and 83 deletions
src/main/java/com/bsth/controller/directive/DirectiveController.java
... ... @@ -31,7 +31,7 @@ public class DirectiveController {
31 31  
32 32 @Autowired
33 33 DirectiveService directiveService;
34   -
  34 +
35 35 /**
36 36 *
37 37 * @Title: send60
... ... @@ -106,7 +106,7 @@ public class DirectiveController {
106 106 @RequestMapping(value = "/upDownChange", method = RequestMethod.POST)
107 107 public int upDownChange(@RequestParam String nbbm, @RequestParam Integer upDown){
108 108 SysUser user = SecurityUtils.getCurrentUser();
109   - return directiveService.upDownChange(nbbm, upDown, user.getUserName());
  109 + return directiveService.send60Operation(nbbm, 0, upDown, user.getUserName());
110 110 }
111 111  
112 112 /**
... ... @@ -120,7 +120,7 @@ public class DirectiveController {
120 120 @RequestMapping(value = "/stateChange", method = RequestMethod.POST)
121 121 public int stateChange(@RequestParam String nbbm, @RequestParam Integer upDown, @RequestParam Integer state){
122 122 SysUser user = SecurityUtils.getCurrentUser();
123   - return directiveService.stateChange(nbbm, upDown, state, user.getUserName());
  123 + return directiveService.send60Operation(nbbm, state, upDown, user.getUserName());
124 124 }
125 125  
126 126 /**
... ...
src/main/java/com/bsth/data/directive/DayOfDirectives.java
... ... @@ -166,7 +166,8 @@ public class DayOfDirectives {
166 166 if(null != d60Map.remove(d60.getMsgId()))
167 167 c60 ++;
168 168 }
169   - logger.info("清除60数据 ," + c60);
  169 + if(c60 > 0)
  170 + logger.info("清除60数据 ," + c60);
170 171  
171 172 //找到该设备的64数据
172 173 Collection<D64> d64s = d64Map.values();
... ... @@ -184,8 +185,9 @@ public class DayOfDirectives {
184 185 if(null != d64Map.remove(d64.getKey()))
185 186 c64 ++;
186 187 }
187   -
188   - logger.info("清除64数据 ," + c64);
  188 +
  189 + if(c64 > 0)
  190 + logger.info("清除64数据 ," + c64);
189 191 }
190 192  
191 193 public Collection<D60> all60(){
... ...
src/main/java/com/bsth/data/gpsdata/GpsEntity.java
... ... @@ -40,9 +40,12 @@ public class GpsEntity {
40 40 /** 纬度 */
41 41 private Float lat;
42 42  
43   - /** 发送时间戳 */
  43 + /** GPS发送时间戳 */
44 44 private Long timestamp;
45 45  
  46 + /** 网关收到时间 */
  47 + private Long serverTimestamp;
  48 +
46 49 /** 速度 */
47 50 private Float speed;
48 51  
... ... @@ -318,17 +321,33 @@ public class GpsEntity {
318 321  
319 322 long t = System.currentTimeMillis();
320 323  
321   - if((t - this.getTimestamp()) > 1000 * 60){
  324 + if((t - this.getServerTimestamp()) > 1000 * 60 * 2){
322 325 return false;
323 326 }
324 327  
325   - if((this.getTimestamp() - t) > 1000 * 60 * 3){
  328 + if((this.getServerTimestamp() - t) > 1000 * 60 * 3){
326 329 return false;
327 330 }
328 331 return true;
329 332 }
330 333  
  334 + /**
  335 + * 是否营运
  336 + * @return
  337 + */
  338 + public boolean isService(){
  339 + return state!=null && state==0;
  340 + }
  341 +
331 342 public boolean isOffline(){
332 343 return this.getAbnormalStatus() != null && this.getAbnormalStatus().equals("offline");
333 344 }
  345 +
  346 + public Long getServerTimestamp() {
  347 + return serverTimestamp;
  348 + }
  349 +
  350 + public void setServerTimestamp(Long serverTimestamp) {
  351 + this.serverTimestamp = serverTimestamp;
  352 + }
334 353 }
... ...
src/main/java/com/bsth/data/gpsdata/GpsRealData.java
... ... @@ -110,6 +110,14 @@ public class GpsRealData {
110 110 return rs;
111 111 }
112 112  
  113 + public GpsEntity getByNbbm(String nbbm){
  114 + String device = BasicData.deviceId2NbbmMap.inverse().get(nbbm);
  115 + if(StringUtils.isNotBlank(device))
  116 + return get(device);
  117 + else
  118 + return null;
  119 + }
  120 +
113 121 /**
114 122 * @Title: get @Description: TODO(线路编码获取GPS集合) @throws
115 123 */
... ...
src/main/java/com/bsth/data/gpsdata/arrival/handlers/CorrectSignalHandle.java
... ... @@ -3,8 +3,8 @@ package com.bsth.data.gpsdata.arrival.handlers;
3 3 import com.bsth.data.gpsdata.GpsEntity;
4 4 import com.bsth.data.gpsdata.arrival.SignalHandle;
5 5 import com.bsth.data.gpsdata.arrival.utils.CircleQueue;
  6 +import com.bsth.data.gpsdata.status_manager.GpsStatusManager;
6 7 import com.bsth.data.schedule.DayOfSchedule;
7   -import com.bsth.entity.realcontrol.ChildTaskPlan;
8 8 import com.bsth.entity.realcontrol.ScheduleRealInfo;
9 9 import com.bsth.service.directive.DirectiveService;
10 10 import org.slf4j.Logger;
... ... @@ -24,28 +24,45 @@ public class CorrectSignalHandle extends SignalHandle {
24 24 @Autowired
25 25 DirectiveService directiveService;
26 26  
  27 + @Autowired
  28 + GpsStatusManager gpsStatusManager;
  29 +
27 30 Logger logger = LoggerFactory.getLogger(this.getClass());
28 31  
29 32 @Override
30 33 public boolean handle(GpsEntity gps, CircleQueue<GpsEntity> prevs) {
31   - Object task = dayOfSchedule.executeCurr(gps.getNbbm());
  34 + ScheduleRealInfo task = dayOfSchedule.executeCurr(gps.getNbbm());
32 35 if(task == null)
33 36 return false;
34   - ScheduleRealInfo sch;
  37 + //ScheduleRealInfo sch;
35 38  
36 39 //子任务
37   - if(task.getClass().isAssignableFrom(ChildTaskPlan.class)){
  40 + /*if(task.getClass().isAssignableFrom(ChildTaskPlan.class)){
38 41 ChildTaskPlan childTask = (ChildTaskPlan) task;
39 42 sch = childTask.getSchedule();
40 43 }
41 44 else
42   - sch = (ScheduleRealInfo) task;
  45 + sch = (ScheduleRealInfo) task;*/
43 46  
44   - byte updown = Byte.parseByte(sch.getXlDir());
  47 + byte updown = Byte.parseByte(task.getXlDir());
45 48 //走向
46 49 if(gps.getUpDown() != updown){
47 50 gps.setUpDown(updown);
48   - gps.setState(0);
  51 + //gps.setState(0);
  52 + }
  53 +
  54 + //(转发的数据不管)
  55 + if(gps.getSource() != 0){
  56 + //gps=非营运 && 班次=非空驶 ;切换到营运状态
  57 + if(!gps.isService() &&
  58 + !dayOfSchedule.emptyService(task)){
  59 + gpsStatusManager.changeServiceState(gps.getNbbm(), updown, 0, null);
  60 + }
  61 +
  62 + //需要切换线路
  63 + if(!task.getXlBm().equals(gps.getLineId())){
  64 + gpsStatusManager.changeLine(gps.getNbbm(), task.getXlBm(), null);
  65 + }
49 66 }
50 67  
51 68 return true;
... ...
src/main/java/com/bsth/data/gpsdata/arrival/handlers/InOutStationSignalHandle.java
... ... @@ -6,6 +6,7 @@ import com.bsth.data.gpsdata.arrival.SignalHandle;
6 6 import com.bsth.data.gpsdata.arrival.utils.CircleQueue;
7 7 import com.bsth.data.gpsdata.arrival.utils.ScheduleSignalState;
8 8 import com.bsth.data.gpsdata.arrival.utils.SignalSchPlanMatcher;
  9 +import com.bsth.data.gpsdata.status_manager.GpsStatusManager;
9 10 import com.bsth.data.msg_queue.DirectivePushQueue;
10 11 import com.bsth.data.schedule.DayOfSchedule;
11 12 import com.bsth.data.schedule.ScheduleComparator;
... ... @@ -46,6 +47,9 @@ public class InOutStationSignalHandle extends SignalHandle{
46 47 @Autowired
47 48 SignalSchPlanMatcher signalSchPlanMatcher;
48 49  
  50 + @Autowired
  51 + GpsStatusManager gpsStatusManager;
  52 +
49 53 private final static int MAX_BEFORE_TIME = 1000 * 60 * 120;
50 54  
51 55 //最大的班次时间差,防止异常的GPS时间打乱数据
... ... @@ -57,10 +61,11 @@ public class InOutStationSignalHandle extends SignalHandle{
57 61 if(isGpsOffline(gps))
58 62 return false;
59 63  
60   - //从异常状态恢复的第一个信号
  64 + /*//从异常状态恢复的第一个信号*/
61 65 if(abnormalRecovery(gps, prevs)){
62 66 //回溯一下之前的轨迹
63   - scheduleSignalState.signalRetrospect(gps);
  67 + //scheduleSignalState.signalRetrospect(gps);
  68 + return false;
64 69 }
65 70  
66 71 if(isNotEmpty(prevs)){
... ... @@ -154,10 +159,9 @@ public class InOutStationSignalHandle extends SignalHandle{
154 159 //清理应发未发标记
155 160 LateAdjustHandle.remove(sch);
156 161  
157   - if(sch.getBcType().equals("out")){
158   - //出场时,切换成营运状态
159   - DirectivePushQueue.put6003(sch.getClZbh(), 0, Integer.parseInt(sch.getXlDir()), null, "出场@系统");
160   - //directiveService.send60Operation(sch.getClZbh(), 0, Integer.parseInt(sch.getXlDir()), null, "出场@系统");
  162 + if(!gps.isService()){
  163 + //切换成营运状态
  164 + gpsStatusManager.changeServiceState(sch.getClZbh(), sch.getXlDir(), 0, "发车@系统");
161 165 }
162 166 //出站既出场
163 167 outStationAndOutPark(sch);
... ... @@ -232,11 +236,13 @@ public class InOutStationSignalHandle extends SignalHandle{
232 236 sendUtils.refreshSch(schPrev);
233 237 dayOfSchedule.save(schPrev);
234 238  
235   - if(schPrev.getBcType().equals("out")){
  239 + /*if(schPrev.getBcType().equals("out")){
236 240 //出场时,切换成营运状态
237   - DirectivePushQueue.put6003(schPrev.getClZbh(), 0, Integer.parseInt(schPrev.getXlDir()), null, "出场@系统");
  241 + String deviceId = BasicData.deviceId2NbbmMap.inverse().get(sch.getClZbh());
  242 + gpsStatusManager.changeServiceState(deviceId, schPrev.getXlDir(), 0, "出场@系统");
  243 + //DirectivePushQueue.put6003(schPrev.getClZbh(), 0, Integer.parseInt(schPrev.getXlDir()), "出场@系统");
238 244 //directiveService.send60Operation(schPrev.getClZbh(), 0, Integer.parseInt(schPrev.getXlDir()), null, "出场@系统");
239   - }
  245 + }*/
240 246 }
241 247 }
242 248 }
... ... @@ -265,6 +271,15 @@ public class InOutStationSignalHandle extends SignalHandle{
265 271 if(Math.abs(diff) > MAX_NORMAL_DIFF)
266 272 return;
267 273  
  274 + //环线或内外圈 ,飘出去再回来
  275 + if(sch.getQdzCode().equals(sch.getZdzCode())
  276 + && StringUtils.isNotEmpty(sch.getFcsjActual())
  277 + && gps.getTimestamp() - sch.getFcsjActualTime() < 1000 * 60 * 3){
  278 + sch.clearFcsjActual();
  279 + sendUtils.refreshSch(sch);
  280 + return;
  281 + }
  282 +
268 283 //实达时间不覆盖
269 284 if(StringUtils.isNotEmpty(sch.getZdsjActual()))
270 285 return;
... ... @@ -304,26 +319,23 @@ public class InOutStationSignalHandle extends SignalHandle{
304 319 transformUpdown(gps, next);
305 320 //下发调度指令
306 321 DirectivePushQueue.put6002(next, doneSum, "到站@系统");
307   - //directiveService.send60Dispatch(next, doneSum, "到站@系统");
308 322  
309 323 //套跑 -下发线路切换指令
310 324 if(!next.getXlBm().equals(sch.getXlBm())){
311   - DirectivePushQueue.put64(next.getClZbh(), next.getXlBm(), "套跑@系统");
312   - //directiveService.lineChange(next.getClZbh(), next.getXlBm(), "套跑@系统");
  325 + gpsStatusManager.changeLine(next.getClZbh(), next.getXlBm(), "套跑@系统");
313 326 }
314 327 }
315 328 else if(sch.getBcType().equals("in")){
316   - //终班进场,切换成非营运状态
317   - DirectivePushQueue.put6003(sch.getClZbh(), 1, Integer.parseInt(sch.getXlDir()), null, "进场@系统");
318   - //directiveService.send60Operation(sch.getClZbh(), 1, Integer.parseInt(sch.getXlDir()), null, "进场@系统");
  329 + //进场,切换成非营运状态
  330 + gpsStatusManager.changeServiceState(sch.getClZbh(), sch.getXlDir(), 1, "进场@系统");
319 331 }
320 332 }
321 333 else {
322   - if(sch.getFcsjActual() == null){
  334 + /*if(sch.getFcsjActual() == null){
323 335 //有进站,但班次没有实发,向前追溯一下信号
324 336 scheduleSignalState.signalRetrospect(gps, sch);
325 337 }
326   -
  338 +*/
327 339 //如果当前班次是出场,并且进的是下一个班次的终点
328 340 if(sch.getBcType().equals("out")){
329 341 ScheduleRealInfo next = dayOfSchedule.next(sch);
... ... @@ -397,6 +409,9 @@ public class InOutStationSignalHandle extends SignalHandle{
397 409 next = dayOfSchedule.next(next);
398 410 if(next != null)
399 411 dayOfSchedule.addExecPlan(next);
  412 +
  413 + //进场,切换成非营运状态
  414 + gpsStatusManager.changeServiceState(sch.getClZbh(), sch.getXlDir(), 1, "进场@系统");
400 415 }
401 416 }
402 417  
... ...
src/main/java/com/bsth/data/gpsdata/arrival/handlers/OfflineSignalHandle.java
... ... @@ -23,7 +23,7 @@ public class OfflineSignalHandle extends SignalHandle{
23 23 public boolean handle(GpsEntity gps, CircleQueue<GpsEntity> prevs) {
24 24 //掉线信号不管
25 25 if(isGpsOffline(gps)){
26   - gps.setSignalState("drift");
  26 + gps.setSignalState("gps-offline");
27 27 gps.setAbnormalStatus("gps-offline");
28 28 return true;
29 29 }
... ...
src/main/java/com/bsth/data/gpsdata/recovery/GpsDataRecovery.java
... ... @@ -84,7 +84,7 @@ public class GpsDataRecovery implements ApplicationContextAware {
84 84 Calendar calendar = Calendar.getInstance();
85 85 int dayOfYear = calendar.get(Calendar.DAY_OF_YEAR);
86 86  
87   - String sql = "select DEVICE_ID,LAT,LON,TS,SPEED_GPS,LINE_ID,SERVICE_STATE from bsth_c_gps_info where days_year=" + dayOfYear;
  87 + String sql = "select DEVICE_ID,LAT,LON,TS,SPEED_GPS,LINE_ID,SERVICE_STATE from bsth_c_gps_info where days_year=194";// + dayOfYear;
88 88 JdbcTemplate jdbcTemplate = new JdbcTemplate(DBUtils_MS.getDataSource());
89 89  
90 90 List<GpsEntity> list =
... ...
src/main/java/com/bsth/data/gpsdata/status_manager/GpsStatusManager.java 0 → 100644
  1 +package com.bsth.data.gpsdata.status_manager;
  2 +
  3 +import com.bsth.Application;
  4 +import com.bsth.data.gpsdata.status_manager.gps_line_state.LineStateHandle;
  5 +import com.bsth.data.gpsdata.status_manager.gps_service_state.ServiceStateHandle;
  6 +import org.springframework.beans.factory.annotation.Autowired;
  7 +import org.springframework.boot.CommandLineRunner;
  8 +import org.springframework.stereotype.Component;
  9 +
  10 +import java.util.concurrent.TimeUnit;
  11 +
  12 +/**
  13 + * GPS 状态管理
  14 + * Created by panzhao on 2017/7/13.
  15 + */
  16 +@Component
  17 +public class GpsStatusManager implements CommandLineRunner {
  18 +
  19 + @Autowired
  20 + StatusCheckThread checkThread;
  21 +
  22 + @Autowired
  23 + LineStateHandle lineStateHandle;
  24 +
  25 + @Autowired
  26 + ServiceStateHandle serviceStateHandle;
  27 +
  28 + /**
  29 + * 切换线路
  30 + * @param nbbm
  31 + * @param lineCode
  32 + * @param sender
  33 + */
  34 + public void changeLine(String nbbm, String lineCode, String sender){
  35 + lineStateHandle.changeLine(nbbm, lineCode, sender);
  36 + }
  37 +
  38 + /**
  39 + * 切换营运状态
  40 + * @param nbbm
  41 + * @param state 0 营运, 1:非营运
  42 + * @param sender
  43 + */
  44 + public void changeServiceState(String nbbm, String upDown,int state, String sender){
  45 + changeServiceState(nbbm, Integer.parseInt(upDown), state, sender);
  46 + }
  47 +
  48 + /**
  49 + * 切换营运状态
  50 + * @param nbbm
  51 + * @param state 0 营运, 1:非营运
  52 + * @param sender
  53 + */
  54 + public void changeServiceState(String nbbm, int upDown,int state, String sender){
  55 + serviceStateHandle.changeState(nbbm, upDown, state, sender);
  56 + }
  57 +
  58 + @Override
  59 + public void run(String... strings) throws Exception {
  60 + Application.mainServices.scheduleWithFixedDelay(checkThread, 120, 120, TimeUnit.SECONDS);
  61 + }
  62 +
  63 + @Component
  64 + public static class StatusCheckThread extends Thread{
  65 +
  66 + @Autowired
  67 + LineStateHandle lineStateHandle;
  68 +
  69 + @Autowired
  70 + ServiceStateHandle serviceStateHandle;
  71 +
  72 + @Override
  73 + public void run() {
  74 + /** 检查线路切换结果 */
  75 + lineStateHandle.checkResultAll();
  76 + /** 检查营运状态切换结果 */
  77 + serviceStateHandle.checkResultAll();
  78 + }
  79 + }
  80 +}
... ...
src/main/java/com/bsth/data/gpsdata/status_manager/gps_line_state/ChangeBean.java 0 → 100644
  1 +package com.bsth.data.gpsdata.status_manager.gps_line_state;
  2 +
  3 +/**
  4 + * Created by panzhao on 2017/7/13.
  5 + */
  6 +public class ChangeBean {
  7 +
  8 + /**
  9 + * 车辆自编号
  10 + */
  11 + private String nbbm;
  12 +
  13 + /**
  14 + * 要切换到的线路
  15 + */
  16 + private String lineCode;
  17 +
  18 + /**
  19 + * 指令发送次数
  20 + */
  21 + private int sendCount;
  22 +
  23 + /**
  24 + * 上次指令时间
  25 + */
  26 + private long st;
  27 +
  28 + /**发送人 */
  29 + private String sender;
  30 +
  31 + public static ChangeBean getInstance(String nbbm, String lineCode, String sender){
  32 + ChangeBean cb = new ChangeBean();
  33 + cb.setNbbm(nbbm);
  34 + cb.setLineCode(lineCode);
  35 + cb.setSendCount(0);
  36 + cb.setSender(sender);
  37 + return cb;
  38 + }
  39 +
  40 + public void countPlus(){
  41 + sendCount ++;
  42 + }
  43 +
  44 + public String getLineCode() {
  45 + return lineCode;
  46 + }
  47 +
  48 + public void setLineCode(String lineCode) {
  49 + this.lineCode = lineCode;
  50 + }
  51 +
  52 + public int getSendCount() {
  53 + return sendCount;
  54 + }
  55 +
  56 + public void setSendCount(int sendCount) {
  57 + this.sendCount = sendCount;
  58 + }
  59 +
  60 + public long getSt() {
  61 + return st;
  62 + }
  63 +
  64 + public void setSt(long st) {
  65 + this.st = st;
  66 + }
  67 +
  68 + public String getSender() {
  69 + return sender;
  70 + }
  71 +
  72 + public void setSender(String sender) {
  73 + this.sender = sender;
  74 + }
  75 +
  76 + public String getNbbm() {
  77 + return nbbm;
  78 + }
  79 +
  80 + public void setNbbm(String nbbm) {
  81 + this.nbbm = nbbm;
  82 + }
  83 +}
... ...
src/main/java/com/bsth/data/gpsdata/status_manager/gps_line_state/LineStateHandle.java 0 → 100644
  1 +package com.bsth.data.gpsdata.status_manager.gps_line_state;
  2 +
  3 +import com.bsth.data.gpsdata.GpsEntity;
  4 +import com.bsth.data.gpsdata.GpsRealData;
  5 +import com.bsth.data.msg_queue.DirectivePushQueue;
  6 +import com.bsth.service.directive.DirectiveService;
  7 +import org.slf4j.Logger;
  8 +import org.slf4j.LoggerFactory;
  9 +import org.springframework.beans.factory.annotation.Autowired;
  10 +import org.springframework.stereotype.Component;
  11 +
  12 +import java.util.Collection;
  13 +import java.util.concurrent.ConcurrentHashMap;
  14 +
  15 +/**
  16 + * 设备线路状态处理
  17 + * Created by panzhao on 2017/7/13.
  18 + */
  19 +@Component
  20 +public class LineStateHandle {
  21 +
  22 + private static ConcurrentHashMap<String, ChangeBean> map;
  23 +
  24 + @Autowired
  25 + DirectiveService directiveService;
  26 + @Autowired
  27 + GpsRealData gpsRealData;
  28 +
  29 + Logger logger = LoggerFactory.getLogger(this.getClass());
  30 +
  31 + /** 重发次数 */
  32 + private final static int MAX_SEND_COUNT=3;
  33 + /** 重发间隔 */
  34 + private final static int SEND_SPACE=1000 * 60 * 5;
  35 + /** 最大有效时间 */
  36 + private final static int MAX_AVAIL_TIME=1000 * 60 * 60 * 2;
  37 +
  38 + static{
  39 + map = new ConcurrentHashMap();
  40 + }
  41 +
  42 + public void changeLine(String nbbm, String lineCode, String sender){
  43 + ChangeBean cb = map.get(nbbm);
  44 + if(cb != null && cb.getLineCode().equals(lineCode)){
  45 + return;
  46 + }
  47 +
  48 + cb = ChangeBean.getInstance(nbbm, lineCode, sender);
  49 + map.put(nbbm, cb);
  50 +
  51 + changeLine(cb);
  52 + }
  53 +
  54 + private void changeLine(ChangeBean cb){
  55 + cb.setSt(System.currentTimeMillis());
  56 + cb.countPlus();
  57 + DirectivePushQueue.put64(cb.getNbbm(), cb.getLineCode(), cb.getSender());
  58 + }
  59 +
  60 +
  61 + public void checkResultAll(){
  62 + Collection<ChangeBean> cbs = map.values();
  63 + for(ChangeBean cb : cbs){
  64 + checkResult(cb);
  65 + }
  66 + }
  67 +
  68 + private void checkResult(ChangeBean cb){
  69 + try{
  70 + GpsEntity gps = gpsRealData.getByNbbm(cb.getNbbm());
  71 + if(gps == null)
  72 + return;
  73 +
  74 + if(cb.getLineCode().equals(gps.getLineId())){
  75 + map.remove(cb.getNbbm());
  76 + logger.info("线路切换成功," + cb.getNbbm() + "、" + cb.getLineCode());
  77 + }
  78 + else{
  79 + reSend(cb);
  80 + }
  81 + }catch (Exception e){
  82 + logger.error("", e);
  83 + }
  84 + }
  85 +
  86 + private void reSend(ChangeBean cb){
  87 + if(cb.getSendCount() >= MAX_SEND_COUNT){
  88 + map.remove(cb.getNbbm());
  89 + logger.info("超过重发次数," + cb.getNbbm() + "、" + cb.getLineCode());
  90 + return;
  91 + }
  92 +
  93 + long diff = System.currentTimeMillis() - cb.getSt();
  94 + if(diff >= MAX_AVAIL_TIME){
  95 + map.remove(cb.getNbbm());
  96 + logger.info("超过有效时间," + cb.getNbbm() + "、" + cb.getLineCode() + "、" + cb.getSt());
  97 + return;
  98 + }
  99 +
  100 + if(diff >= SEND_SPACE){
  101 + cb.setSender("补发@系统");
  102 + changeLine(cb);
  103 + logger.info("重发线路切换指令," + cb.getNbbm() + "、" + cb.getLineCode());
  104 + return;
  105 + }
  106 + }
  107 +}
... ...
src/main/java/com/bsth/data/gpsdata/status_manager/gps_service_state/ServiceStateHandle.java 0 → 100644
  1 +package com.bsth.data.gpsdata.status_manager.gps_service_state;
  2 +
  3 +import com.bsth.data.gpsdata.GpsEntity;
  4 +import com.bsth.data.gpsdata.GpsRealData;
  5 +import com.bsth.data.msg_queue.DirectivePushQueue;
  6 +import com.bsth.service.directive.DirectiveService;
  7 +import org.slf4j.Logger;
  8 +import org.slf4j.LoggerFactory;
  9 +import org.springframework.beans.factory.annotation.Autowired;
  10 +import org.springframework.stereotype.Component;
  11 +
  12 +import java.util.Collection;
  13 +import java.util.concurrent.ConcurrentHashMap;
  14 +
  15 +/**
  16 + * 设备营运状态处理
  17 + * Created by panzhao on 2017/7/13.
  18 + */
  19 +@Component
  20 +public class ServiceStateHandle {
  21 +
  22 + private static ConcurrentHashMap<String, StateBean> map;
  23 +
  24 + @Autowired
  25 + DirectiveService directiveService;
  26 + @Autowired
  27 + GpsRealData gpsRealData;
  28 +
  29 + Logger logger = LoggerFactory.getLogger(this.getClass());
  30 +
  31 + /** 重发次数 */
  32 + private final static int MAX_SEND_COUNT=3;
  33 + /** 重发间隔 */
  34 + private final static int SEND_SPACE=1000 * 60 * 4;
  35 + /** 最大有效时间 */
  36 + private final static int MAX_AVAIL_TIME=1000 * 60 * 60;
  37 +
  38 + static{
  39 + map = new ConcurrentHashMap();
  40 + }
  41 +
  42 + public void changeState(String nbbm, int upDown ,int state, String sender){
  43 + if(map.containsKey(nbbm)){
  44 + return;
  45 + }
  46 + StateBean sb = StateBean.getInstance(nbbm, upDown, state, sender);
  47 + map.put(nbbm, sb);
  48 + changeState(sb);
  49 + }
  50 +
  51 + private void changeState(StateBean sb){
  52 + sb.setSt(System.currentTimeMillis());
  53 + sb.countPlus();
  54 + DirectivePushQueue.put6003(sb.getNbbm(), sb.getState(), sb.getUpDown(), sb.getSender());
  55 + }
  56 +
  57 + public void checkResultAll(){
  58 + Collection<StateBean> sbs = map.values();
  59 + for(StateBean sb : sbs){
  60 + checkResult(sb);
  61 + }
  62 + }
  63 +
  64 + private void checkResult(StateBean sb){
  65 + try{
  66 + GpsEntity gps = gpsRealData.getByNbbm(sb.getNbbm());
  67 + if(gps == null)
  68 + return;
  69 +
  70 + if(gps.getState().equals(sb.getState())){
  71 + map.remove(sb.getNbbm());
  72 + logger.info("营运状态切换成功," + sb.getNbbm() + "、" + sb.getState());
  73 + }
  74 + else
  75 + reSend(sb);
  76 + }catch (Exception e){
  77 + logger.error("", e);
  78 + }
  79 + }
  80 +
  81 + private void reSend(StateBean sb){
  82 + if(sb.getSendCount() >= MAX_SEND_COUNT){
  83 + map.remove(sb.getNbbm());
  84 + logger.info("超过重发次数," + sb.getNbbm() + "、" + sb.getState());
  85 + return;
  86 + }
  87 +
  88 + long diff = System.currentTimeMillis() - sb.getSt();
  89 + if(diff >= MAX_AVAIL_TIME){
  90 + map.remove(sb.getNbbm());
  91 + logger.info("营运状态切换超过有效时间," + sb.getNbbm() + "、" + sb.getState() + "、" + sb.getSt());
  92 + return;
  93 + }
  94 +
  95 + if(diff >= SEND_SPACE){
  96 + sb.setSender("补发@系统");
  97 + changeState(sb);
  98 + logger.info("重发营运状态切换指令," + sb.getNbbm() + "、" + sb.getState());
  99 + return;
  100 + }
  101 + }
  102 +}
... ...
src/main/java/com/bsth/data/gpsdata/status_manager/gps_service_state/StateBean.java 0 → 100644
  1 +package com.bsth.data.gpsdata.status_manager.gps_service_state;
  2 +
  3 +/**
  4 + * Created by panzhao on 2017/7/13.
  5 + */
  6 +public class StateBean {
  7 +
  8 + /**
  9 + * 车辆自编号
  10 + */
  11 + private String nbbm;
  12 +
  13 + /**
  14 + * 要切换到营运状态
  15 + */
  16 + private int state;
  17 +
  18 + /**
  19 + * 要切换到的上下行
  20 + */
  21 + private int upDown;
  22 +
  23 + /**
  24 + * 指令发送次数
  25 + */
  26 + private int sendCount;
  27 +
  28 + /**
  29 + * 上次指令时间
  30 + */
  31 + private long st;
  32 +
  33 + /**发送人 */
  34 + private String sender;
  35 +
  36 + public static StateBean getInstance(String nbbm, int upDown, int state, String sender){
  37 + StateBean sb = new StateBean();
  38 + sb.setNbbm(nbbm);
  39 + sb.setState(state);
  40 + sb.setSendCount(0);
  41 + sb.setSender(sender);
  42 + sb.setUpDown(upDown);
  43 + return sb;
  44 + }
  45 +
  46 + public int getState() {
  47 + return state;
  48 + }
  49 +
  50 + public void setState(int state) {
  51 + this.state = state;
  52 + }
  53 +
  54 + public int getSendCount() {
  55 + return sendCount;
  56 + }
  57 +
  58 + public void setSendCount(int sendCount) {
  59 + this.sendCount = sendCount;
  60 + }
  61 +
  62 + public long getSt() {
  63 + return st;
  64 + }
  65 +
  66 + public void setSt(long st) {
  67 + this.st = st;
  68 + }
  69 +
  70 + public String getSender() {
  71 + return sender;
  72 + }
  73 +
  74 + public void setSender(String sender) {
  75 + this.sender = sender;
  76 + }
  77 +
  78 + public void countPlus(){
  79 + sendCount ++;
  80 + }
  81 +
  82 + public int getUpDown() {
  83 + return upDown;
  84 + }
  85 +
  86 + public void setUpDown(int upDown) {
  87 + this.upDown = upDown;
  88 + }
  89 +
  90 + public String getNbbm() {
  91 + return nbbm;
  92 + }
  93 +
  94 + public void setNbbm(String nbbm) {
  95 + this.nbbm = nbbm;
  96 + }
  97 +}
... ...
src/main/java/com/bsth/data/msg_queue/DirectivePushQueue.java
... ... @@ -39,12 +39,12 @@ public class DirectivePushQueue implements CommandLineRunner, ApplicationContext
39 39 linkedList.add(qd6002);
40 40 }
41 41  
42   - public static void put6003(String nbbm, int state, int upDown, ScheduleRealInfo sch, String sender){
  42 + public static void put6003(String nbbm, int state, int upDown, String sender){
43 43 QueueData_Directive qd6003 = new QueueData_Directive();
44 44 qd6003.setNbbm(nbbm);
45 45 qd6003.setState(state);
46 46 qd6003.setUpDown(upDown);
47   - qd6003.setSch(sch);
  47 + //qd6003.setSch(sch);
48 48 qd6003.setSender(sender);
49 49  
50 50 qd6003.setCode("60_03");
... ... @@ -111,7 +111,7 @@ public class DirectivePushQueue implements CommandLineRunner, ApplicationContext
111 111 log.info("directive 60_02 sch id: " + qd.getSch().getId());
112 112 }
113 113 else if(code.equals("60_03")){
114   - directiveService.send60Operation(qd.getNbbm(), qd.getState(), qd.getUpDown(), null, qd.getSender());
  114 + directiveService.send60Operation(qd.getNbbm(), qd.getState(), qd.getUpDown(), qd.getSender());
115 115 log.info("directive 60_03 nbbm: " + qd.getNbbm());
116 116 }
117 117 else if(code.equals("64")){
... ...
src/main/java/com/bsth/data/pilot80/PilotReport.java
... ... @@ -2,7 +2,9 @@ package com.bsth.data.pilot80;
2 2  
3 3 import com.bsth.data.BasicData;
4 4 import com.bsth.data.LineConfigData;
  5 +import com.bsth.data.gpsdata.GpsEntity;
5 6 import com.bsth.data.gpsdata.GpsRealData;
  7 +import com.bsth.data.gpsdata.status_manager.GpsStatusManager;
6 8 import com.bsth.data.msg_queue.DirectivePushQueue;
7 9 import com.bsth.data.schedule.DayOfSchedule;
8 10 import com.bsth.entity.Line;
... ... @@ -51,6 +53,9 @@ public class PilotReport {
51 53 @Autowired
52 54 DC0A4Repository dc0A4Repository;
53 55  
  56 + @Autowired
  57 + GpsStatusManager gpsStatusManager;
  58 +
54 59 //private static ArrayListMultimap<String, D80> d80MultiMap;
55 60  
56 61 private static ConcurrentHashMap<Integer, D80> d80Maps;
... ... @@ -80,14 +85,26 @@ public class PilotReport {
80 85 ScheduleRealInfo outSch = dayOfSchedule.searchNearByBcType(nbbm, "out");
81 86 //如果有对应出场班次
82 87 if (outSch != null) {
83   - //没有计划里程的出场班次,出场既是首发站,发送下一班次的营运指令
  88 + //没有计划里程的出场班次,出场既是首发站,发送下一班次的调度指令
84 89 if (outSch.getJhlc() == null)
85 90 outSch = dayOfSchedule.next(outSch);
86 91  
87 92 //下发调度指令
  93 + String deviceId = d80.getDeviceId();
88 94 DirectivePushQueue.put6002(outSch, dayOfSchedule.doneSum(nbbm), "请出@系统");
  95 +
89 96 //下发线路切换指令
90 97 DirectivePushQueue.put64(outSch.getClZbh(), outSch.getXlBm(), "请出@系统");
  98 +
  99 + try {
  100 + GpsEntity gps = gpsRealData.get(deviceId);
  101 + if(gps != null && !gps.isService()){
  102 + //切换到营运状态
  103 + gpsStatusManager.changeServiceState(nbbm, outSch.getXlDir() ,0, "请出@系统");
  104 + }
  105 + }catch (Exception e){
  106 + logger.error("请出切换营运状态异常", e);
  107 + }
91 108 }
92 109 break;
93 110 }
... ...
src/main/java/com/bsth/data/schedule/DayOfSchedule.java
... ... @@ -4,12 +4,9 @@ import com.alibaba.fastjson.JSON;
4 4 import com.alibaba.fastjson.JSONArray;
5 5 import com.bsth.common.Constants;
6 6 import com.bsth.common.ResponseCode;
7   -import com.bsth.data.BasicData;
8 7 import com.bsth.data.LineConfigData;
9   -import com.bsth.data.gpsdata.GpsEntity;
10 8 import com.bsth.data.gpsdata.GpsRealData;
11 9 import com.bsth.data.gpsdata.recovery.GpsDataRecovery;
12   -import com.bsth.data.msg_queue.DirectivePushQueue;
13 10 import com.bsth.entity.realcontrol.LineConfig;
14 11 import com.bsth.entity.realcontrol.ScheduleRealInfo;
15 12 import com.bsth.entity.schedule.SchedulePlanInfo;
... ... @@ -949,7 +946,31 @@ public class DayOfSchedule {
949 946 ScheduleRealInfo sch = schAttrCalculator.calcCurrentExecSch(list);
950 947 carExecutePlanMap.put(nbbm, sch);
951 948  
952   - try {
  949 +
  950 + /* try{
  951 + GpsEntity gps = gpsRealData.get(BasicData.deviceId2NbbmMap.inverse().get(nbbm));
  952 + if (gps == null || !gps.isOnline())
  953 + return;//设备不在线
  954 +
  955 + *//*if(sch == null && gps.isService())
  956 + DirectivePushQueue.put6003(nbbm, 1, 0, null, "系统");//无任务*//*
  957 +
  958 + //String bcType = sch.getBcType();
  959 + *//*if(bcType.equals("normal")
  960 + || bcType.equals("region")
  961 + || bcType.equals("major")){
  962 + //全程、区间、放站,切换到营运状态
  963 + if(!gps.isService()){
  964 + DirectivePushQueue.put6003(nbbm, 0, Integer.parseInt(sch.getXlDir()), sch, "系统");
  965 + }
  966 + }
  967 + else if(gps.isService()){
  968 + DirectivePushQueue.put6003(nbbm, 1, 0, null, "系统");//空驶任务
  969 + }*//*
  970 + }catch (Exception e){
  971 + logger.error("", e);
  972 + }
  973 + *//*try {
953 974 //切换设备状态
954 975 GpsEntity gps = gpsRealData.get(BasicData.deviceId2NbbmMap.inverse().get(nbbm));
955 976 if (gps == null || !gps.isOnline())
... ... @@ -967,7 +988,18 @@ public class DayOfSchedule {
967 988 }
968 989 } catch (Exception e) {
969 990 logger.error("", e);
970   - }
  991 + }*/
  992 + }
  993 +
  994 + /**
  995 + * 空驶任务?
  996 + * 出场、进场、直放、两点间空驶
  997 + * @param sch
  998 + * @return
  999 + */
  1000 + public static boolean emptyService(ScheduleRealInfo sch){
  1001 + String type = sch.getBcType();
  1002 + return type.equals("out") || type.equals("in") || type.equals("venting") || type.equals("ldks");
971 1003 }
972 1004  
973 1005 /**
... ... @@ -975,7 +1007,7 @@ public class DayOfSchedule {
975 1007 *
976 1008 * @param nbbm
977 1009 * @return
978   - */
  1010 +
979 1011 public boolean isExecFirstOut(String nbbm, long time) {
980 1012 try {
981 1013 List<ScheduleRealInfo> list = nbbmScheduleMap.get(nbbm);
... ... @@ -991,7 +1023,7 @@ public class DayOfSchedule {
991 1023 }
992 1024  
993 1025 return false;
994   - }
  1026 + }*/
995 1027  
996 1028  
997 1029 @Autowired
... ...
src/main/java/com/bsth/entity/realcontrol/ScheduleType.java deleted 100644 → 0
1   -package com.bsth.entity.realcontrol;
2   -
3   -/**
4   - * 班次类型
5   - * Created by panzhao on 2016/12/23.
6   - */
7   -public enum ScheduleType {
8   -
9   - normal, //正常班次
10   - out, //出场
11   - in, //进场
12   - region, //区间
13   - venting,//直放
14   - major //放站
15   -}
src/main/java/com/bsth/service/directive/DirectiveService.java
... ... @@ -44,7 +44,7 @@ public interface DirectiveService extends BaseService&lt;D60, Integer&gt;{
44 44 int send60Dispatch(Long id, String sender);
45 45  
46 46 //60营运指令
47   - int send60Operation(String nbbm, int state, int upDown, ScheduleRealInfo sch, String sender);
  47 + int send60Operation(String nbbm, int state, int upDown, String sender);
48 48  
49 49 /**
50 50 *
... ... @@ -66,7 +66,7 @@ public interface DirectiveService extends BaseService&lt;D60, Integer&gt;{
66 66 * @param @param upDonw 上下行 0 上行 1 下行
67 67 * @throws
68 68 */
69   - int upDownChange(String nbbm, Integer upDown, String sender);
  69 + //int upDownChange(String nbbm, Integer upDown, String sender);
70 70  
71 71 /**
72 72 *
... ... @@ -94,7 +94,7 @@ public interface DirectiveService extends BaseService&lt;D60, Integer&gt;{
94 94  
95 95 int refreshLineFile(String deviceId);
96 96  
97   - int stateChange(String nbbm, Integer upDown, Integer state, String userName);
  97 + //int stateChange(String nbbm, Integer upDown, Integer state, String userName);
98 98  
99 99 Map<String,Object> deviceCofigList(Map<String, String> map, int page, int size);
100 100 }
... ...
src/main/java/com/bsth/service/directive/DirectiveServiceImpl.java
... ... @@ -188,7 +188,7 @@ public class DirectiveServiceImpl extends BaseServiceImpl&lt;D60, Integer&gt; implemen
188 188 }
189 189  
190 190 @Override
191   - public int send60Operation(String nbbm, int state, int upDown, ScheduleRealInfo sch, String sender) {
  191 + public int send60Operation(String nbbm, int state, int upDown, String sender) {
192 192 logger.info("切换运营状态, nbbm: " + nbbm + " ,state: " + state + " ,upDown:" + upDown);
193 193  
194 194 String text = "切换为 " + (upDown == 0 ? "上行" : "下行") + (state == 0 ? "营运" : "未营运");
... ... @@ -204,9 +204,10 @@ public class DirectiveServiceImpl extends BaseServiceImpl&lt;D60, Integer&gt; implemen
204 204 int code = GatewayHttpUtils.postJson(JSON.toJSONString(d60));
205 205 // 添加到缓存,等待入库
206 206 d60.setHttpCode(code);
207   - if (null != sch)
  207 + /*if (null != sch){
208 208 d60.setSch(sch);
209   -
  209 + d60.setLineCode(sch.getXlBm());
  210 + }*/
210 211  
211 212 if (code == 0) {
212 213 dayOfDirectives.put60(d60, true);
... ... @@ -294,10 +295,10 @@ public class DirectiveServiceImpl extends BaseServiceImpl&lt;D60, Integer&gt; implemen
294 295 return new DirectiveCreator().createD60(nbbm, text, dispatchInstruct, upDown, state, lineCode);
295 296 }
296 297  
297   - @Override
  298 +/* @Override
298 299 public int upDownChange(String nbbm, Integer upDown, String sender) {
299   - return send60Operation(nbbm, 0, upDown, null, sender);
300   - }
  300 + return send60Operation(nbbm, 0, upDown, sender);
  301 + }*/
301 302  
302 303  
303 304 @Override
... ... @@ -540,10 +541,10 @@ public class DirectiveServiceImpl extends BaseServiceImpl&lt;D60, Integer&gt; implemen
540 541 return GatewayHttpUtils.postJson(new DirectiveCreator().createDeviceRefreshData(deviceId, gps.getLineId()));
541 542 }
542 543  
543   - @Override
  544 +/* @Override
544 545 public int stateChange(String nbbm, Integer upDown, Integer state, String userName) {
545   - return send60Operation(nbbm, state, upDown, null, userName);
546   - }
  546 + return send60Operation(nbbm, state, upDown, userName);
  547 + }*/
547 548  
548 549 @Override
549 550 public Map<String, Object> deviceCofigList(Map<String, String> map, int page, int size) {
... ...
src/main/java/com/bsth/service/gps/GpsServiceImpl.java
... ... @@ -152,6 +152,17 @@ public class GpsServiceImpl implements GpsService {
152 152 return (byte) (((serviceState & 0x10000000) == 0x10000000) ? 1 : 0);
153 153 }
154 154  
  155 + /**
  156 + * 获取运营状态
  157 + *
  158 + * @return -1无效 0运营 1未运营
  159 + */
  160 + public static byte getService(long serviceState) {
  161 + if ((serviceState & 0x00020000) == 0x00020000 || (serviceState & 0x80000000) == 0x80000000)
  162 + return -1;
  163 + return (byte) (((serviceState & 0x02000000) == 0x02000000) ? 1 : 0);
  164 + }
  165 +
155 166 @Override
156 167 public List<Map<String, Object>> history(String[] nbbmArray, Long st, Long et) {
157 168 List<Map<String, Object>> list = new ArrayList<>();
... ... @@ -239,10 +250,11 @@ public class GpsServiceImpl implements GpsService {
239 250 rs = ps.executeQuery();
240 251 Float lon, lat;
241 252 Location bdLoc, gdLoc;
242   - int upDown, inOutStop;
  253 + int inOutStop;
  254 + long serviceState;
243 255 ArrivalEntity arrival;
244 256 while (rs.next()) {
245   - upDown = getUpOrDown(rs.getLong("SERVICE_STATE"));
  257 + serviceState = rs.getLong("SERVICE_STATE");
246 258 map = new HashMap<>();
247 259  
248 260 lon = rs.getFloat("LON");
... ... @@ -278,9 +290,9 @@ public class GpsServiceImpl implements GpsService {
278 290 }
279 291  
280 292 map.put("nbbm", BasicData.deviceId2NbbmMap.get(rs.getString("DEVICE_ID")));
281   - map.put("state", 0);
  293 + map.put("state", getService(serviceState));
282 294 // 上下行
283   - map.put("upDown", upDown);
  295 + map.put("upDown", getUpOrDown(serviceState));
284 296 //路段编码
285 297 map.put("section_code", rs.getString("SECTION_CODE"));
286 298 list.add(map);
... ...
src/main/resources/logback.xml
... ... @@ -182,6 +182,28 @@
182 182 <appender-ref ref="GPS_COUNT" />
183 183 </logger>
184 184  
  185 + <!-- 设备状态指令 -->
  186 + <appender name="GPS_STATUS_DIRECTIVE"
  187 + class="ch.qos.logback.core.rolling.RollingFileAppender">
  188 + <file>${LOG_BASE}/gps_state/state_directive.log</file>
  189 + <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
  190 + <fileNamePattern>${LOG_BASE}/gps_state/state_directive-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
  191 + <timeBasedFileNamingAndTriggeringPolicy
  192 + class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
  193 + <maxFileSize>100MB</maxFileSize>
  194 + </timeBasedFileNamingAndTriggeringPolicy>
  195 + </rollingPolicy>
  196 +
  197 + <layout class="ch.qos.logback.classic.PatternLayout">
  198 + <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%file:%line] %-5level -%msg%n
  199 + </pattern>
  200 + </layout>
  201 + </appender>
  202 + <logger name="com.bsth.data.gpsdata.status_manager"
  203 + level="INFO" additivity="false">
  204 + <appender-ref ref="GPS_STATUS_DIRECTIVE" />
  205 + </logger>
  206 +
185 207 <!-- 消息队列纪录 -->
186 208 <appender name="QUEUE_WEB_SOCKET"
187 209 class="ch.qos.logback.core.rolling.RollingFileAppender">
... ...
src/main/resources/static/real_control_v2/fragments/line_schedule/context_menu/sub_task_v2/add_in_out.html
... ... @@ -111,7 +111,7 @@
111 111  
112 112 //起点改变
113 113 $f('startStation', f).on('change', function () {
114   - $f('endStation', outf).val($(this).val());//.trigger('change');
  114 + $f('endStation', outf).val($(this).val()).trigger('change');
115 115 }).trigger('change');
116 116 }
117 117  
... ... @@ -149,13 +149,14 @@
149 149 }
150 150 if(eCode==sch.qdzCode || eCode==sch.zdzCode){
151 151 $f('startStation',inf).val(eCode).trigger('change');
152   - $f('type2',outf).trigger('change');
  152 + //$f('type2',outf).trigger('change');
  153 + $f('endStation',outf).val(eCode).trigger('change');
153 154 return;
154 155 }
155 156  
156 157 //进场起点
157 158 $f('startStation',inf).val(eCode);//.trigger('change');
158   - //终点trigger change 发重计算
  159 + //终点trigger change 发重计算
159 160 $f('endStation',inf).trigger('change');
160 161  
161 162 //中途进场
... ...
src/main/resources/static/real_control_v2/js/main.js
... ... @@ -47,7 +47,7 @@ var gb_main_ep = new EventProxy(),
47 47 $('li.map-panel', '#main-tab-content').load('/real_control_v2/mapmonitor/real.html');
48 48 }, 1000);
49 49 //弹出更新说明
50   - showUpdateDescription();
  50 + //showUpdateDescription();
51 51 });
52 52  
53 53 function g_emit(id) {
... ... @@ -169,8 +169,8 @@ var disabled_submit_btn = function (form) {
169 169 function showUpdateDescription() {
170 170 //更新说明
171 171 var updateDescription = {
172   - date: '2017-07-05',
173   - text: '<h5>稍微调整了添加子任务的界面</h5><h5>1、现在进出场子任务也必须选择进场原因</h5><h5>2、现在进出场子任务可以勾选 “无售票员” 如果是无人售票线路,请忽略这个选项</h5><h5>3、现在做中途进场子任务时,可以勾选“换车出场至中途站继续营运”</h5>'
  172 + date: '2017-07-14',
  173 + text: '<h5></h5>'
174 174 };
175 175  
176 176 var storage = window.localStorage
... ...