Commit 8c5746ae1b0c027599214326787bd51e93aa95fd

Authored by 徐烜
2 parents b1583c3e a327fcf1
Showing 51 changed files with 1767 additions and 355 deletions
src/main/java/com/bsth/StartCommand.java
1 package com.bsth; 1 package com.bsth;
2 2
3 3
  4 +import com.bsth.repository.schedule.CarConfigInfoRepository;
4 import com.bsth.security.SecurityMetadataSourceService; 5 import com.bsth.security.SecurityMetadataSourceService;
5 import com.bsth.service.realcontrol.buffer.GetSchedulePlanThread; 6 import com.bsth.service.realcontrol.buffer.GetSchedulePlanThread;
6 import com.bsth.service.realcontrol.buffer.SchedulePersistenceThread; 7 import com.bsth.service.realcontrol.buffer.SchedulePersistenceThread;
7 import com.bsth.util.DateUtils; 8 import com.bsth.util.DateUtils;
8 import com.bsth.vehicle.common.CommonRefreshThread; 9 import com.bsth.vehicle.common.CommonRefreshThread;
  10 +import com.bsth.vehicle.directive.service.DirectiveService;
9 import com.bsth.vehicle.directive.thread.DirectivePersistenceThread; 11 import com.bsth.vehicle.directive.thread.DirectivePersistenceThread;
10 import com.bsth.vehicle.directive.thread.FirstScheduleIssuedThread; 12 import com.bsth.vehicle.directive.thread.FirstScheduleIssuedThread;
11 -import com.bsth.vehicle.gpsdata.GpsArrivalStationThread; 13 +import com.bsth.vehicle.gpsdata.GpsArrivalThread;
12 import com.bsth.vehicle.gpsdata.GpsRefreshThread; 14 import com.bsth.vehicle.gpsdata.GpsRefreshThread;
  15 +
13 import org.slf4j.Logger; 16 import org.slf4j.Logger;
14 import org.slf4j.LoggerFactory; 17 import org.slf4j.LoggerFactory;
15 import org.springframework.beans.factory.annotation.Autowired; 18 import org.springframework.beans.factory.annotation.Autowired;
@@ -46,10 +49,17 @@ public class StartCommand implements CommandLineRunner{ @@ -46,10 +49,17 @@ public class StartCommand implements CommandLineRunner{
46 @Autowired 49 @Autowired
47 SchedulePersistenceThread SchedulePersistenceThread; 50 SchedulePersistenceThread SchedulePersistenceThread;
48 @Autowired 51 @Autowired
49 - GpsArrivalStationThread gpsArrivalStationThread; 52 + GpsArrivalThread gpsArrivalStationThread;
50 @Autowired 53 @Autowired
51 FirstScheduleIssuedThread firstScheduleIssuedThread; 54 FirstScheduleIssuedThread firstScheduleIssuedThread;
52 55
  56 + @Autowired
  57 + DirectiveService directiveService;
  58 + @Autowired
  59 + CarConfigInfoRepository carConfigInfoRepository;
  60 +
  61 + static Long hourTime = 1000 * 60 * 60L;
  62 +
53 @Override 63 @Override
54 public void run(String... arg0){ 64 public void run(String... arg0){
55 65
@@ -64,12 +74,12 @@ public class StartCommand implements CommandLineRunner{ @@ -64,12 +74,12 @@ public class StartCommand implements CommandLineRunner{
64 scheduler.scheduleWithFixedDelay(gpsRefreshThread, 0, 8, TimeUnit.SECONDS); 74 scheduler.scheduleWithFixedDelay(gpsRefreshThread, 0, 8, TimeUnit.SECONDS);
65 75
66 /** 76 /**
67 - * 每天 0点 抓取当天实际排班 77 + * 每天 凌晨 2 点 抓取当天实际排班
68 */ 78 */
69 //启动时先run一次 79 //启动时先run一次
70 getSchedulePlanThread.start(); 80 getSchedulePlanThread.start();
71 scheduler.scheduleAtFixedRate(getSchedulePlanThread 81 scheduler.scheduleAtFixedRate(getSchedulePlanThread
72 - , DateUtils.getTimesnight() + 5 - System.currentTimeMillis() / 1000 82 + , ((DateUtils.getTimesnight2() + hourTime * 2) - System.currentTimeMillis()) / 1000
73 , 60 * 60 * 24, TimeUnit.SECONDS); 83 , 60 * 60 * 24, TimeUnit.SECONDS);
74 84
75 /** 85 /**
@@ -93,7 +103,7 @@ public class StartCommand implements CommandLineRunner{ @@ -93,7 +103,7 @@ public class StartCommand implements CommandLineRunner{
93 * 每15秒从数据库抓取到离站信息和班次匹配 103 * 每15秒从数据库抓取到离站信息和班次匹配
94 * (网关生成的到离站数据也是延迟批量入库,所以缩短该线程执行周期并不会提高 “实际到离站” 的实时性) 104 * (网关生成的到离站数据也是延迟批量入库,所以缩短该线程执行周期并不会提高 “实际到离站” 的实时性)
95 */ 105 */
96 - scheduler.scheduleWithFixedDelay(gpsArrivalStationThread, 35, 1200, TimeUnit.SECONDS); 106 + scheduler.scheduleWithFixedDelay(gpsArrivalStationThread, 15, 20, TimeUnit.SECONDS);
97 107
98 /** 108 /**
99 * 首个调度指令下发(2分钟运行一次) 109 * 首个调度指令下发(2分钟运行一次)
@@ -102,6 +112,86 @@ public class StartCommand implements CommandLineRunner{ @@ -102,6 +112,86 @@ public class StartCommand implements CommandLineRunner{
102 */ 112 */
103 scheduler.scheduleWithFixedDelay(firstScheduleIssuedThread, 60 , 60 * 2, TimeUnit.SECONDS); 113 scheduler.scheduleWithFixedDelay(firstScheduleIssuedThread, 60 , 60 * 2, TimeUnit.SECONDS);
104 114
  115 + /**
  116 + * ######### 测试 ###############
  117 + */
  118 +/* new Timer().schedule(new TimerTask() {
  119 +
  120 + @Override
  121 + public void run() {
  122 + //根据班次模拟一份到离站数据
  123 + Set<String> set = ScheduleBuffer.vehSchListMap.keySet();
  124 + ArrivalInfo outArr, inArr;
  125 + List<ArrivalInfo> arrList = new ArrayList<>();
  126 + Date d = new Date();
  127 + for(String nbbm : set){
  128 +
  129 + for(ScheduleRealInfo sch : ScheduleBuffer.vehSchListMap.get(nbbm)){
  130 + //发出
  131 + outArr = new ArrivalInfo(CommonMapped.vehicDeviceBiMap.inverse().get(nbbm)
  132 + , sch.getFcsjT(), sch.getXlBm(), Integer.parseInt(sch.getXlDir()), sch.getQdzCode(), 1, d , 31);
  133 +
  134 + //到达
  135 + inArr = new ArrivalInfo(CommonMapped.vehicDeviceBiMap.inverse().get(nbbm)
  136 + , sch.getZdsjT(), sch.getXlBm(), Integer.parseInt(sch.getXlDir()), sch.getZdzCode(), 0, d , 31);
  137 +
  138 + arrList.add(outArr);
  139 + arrList.add(inArr);
  140 + }
  141 + }
  142 + try {
  143 + Connection conn = DBUtils_MS.getConnection();
  144 + String sql = "insert into bsth_c_arrival_info(device_id, line_id, stop_no, ts, up_down, in_out, weeks_year, create_date)"
  145 + + " values(?, ?, ?, ? , ?, ?,?, now())";
  146 +
  147 + conn.setAutoCommit(false);
  148 + java.sql.PreparedStatement ps = conn.prepareStatement(sql);
  149 +
  150 + for(ArrivalInfo arr : arrList){
  151 + ps.setString(1, arr.getDeviceId());
  152 + ps.setString(2, arr.getLineCode());
  153 + ps.setString(3, arr.getStopNo());
  154 + ps.setLong(4, arr.getTs() == null? 0: arr.getTs());
  155 + ps.setInt(5, arr.getUpDown());
  156 + ps.setInt(6, arr.getInOut());
  157 + ps.setInt(7, arr.getWeeksYear());
  158 +
  159 + ps.addBatch();
  160 + }
  161 +
  162 + ps.executeBatch();
  163 + conn.commit();
  164 + } catch (SQLException e) {
  165 + e.printStackTrace();
  166 + }
  167 +
  168 + //new BatchSaveUtils<ArrivalInfo>().saveList(arrList, ArrivalInfo.class);
  169 + }
  170 + }, 5000);*/
  171 +
  172 +/* //延迟一会
  173 + new Timer().schedule(new TimerTask() {
  174 +
  175 + @Override
  176 + public void run() {
  177 + //临时全量刷车辆线路
  178 + List<CarConfigInfo> ccis = carConfigInfoRepository.findAll();
  179 + Cars car;
  180 + Line line;
  181 + String lineCode;
  182 + int code;
  183 + for(CarConfigInfo cci : ccis){
  184 + car = cci.getCl();
  185 + line = cci.getXl();
  186 + lineCode = line.getLineCode();
  187 + System.out.println("车辆:" + car.getInsideCode() + "切换线路:" + line.getLineCode());
  188 + code = directiveService.lineChange(car.getInsideCode(), Integer.parseInt(lineCode));
  189 + //directiveService.send60Phrase(car.getInsideCode(), "");
  190 + System.out.println("返回值:" + code);
  191 + }
  192 + }
  193 + }, 1000 * 10);*/
  194 +
105 } catch (Exception e) { 195 } catch (Exception e) {
106 e.printStackTrace(); 196 e.printStackTrace();
107 } 197 }
src/main/java/com/bsth/controller/realcontrol/ScheduleRealInfoController.java
@@ -273,7 +273,7 @@ public class ScheduleRealInfoController extends BaseController&lt;ScheduleRealInfo, @@ -273,7 +273,7 @@ public class ScheduleRealInfoController extends BaseController&lt;ScheduleRealInfo,
273 */ 273 */
274 @RequestMapping(value = "/lineCode/{lineCode}") 274 @RequestMapping(value = "/lineCode/{lineCode}")
275 public List<ScheduleRealInfo> findByLineCode(@PathVariable("lineCode") String lineCode){ 275 public List<ScheduleRealInfo> findByLineCode(@PathVariable("lineCode") String lineCode){
276 - return ScheduleBuffer.schedulListMap.get(lineCode); 276 + return ScheduleBuffer.realSchedulListMap.get(lineCode);
277 } 277 }
278 278
279 @RequestMapping(value = "/queryUserInfo") 279 @RequestMapping(value = "/queryUserInfo")
src/main/java/com/bsth/entity/realcontrol/ChildTaskPlan.java
@@ -10,6 +10,9 @@ import javax.persistence.NamedEntityGraph; @@ -10,6 +10,9 @@ import javax.persistence.NamedEntityGraph;
10 import javax.persistence.NamedEntityGraphs; 10 import javax.persistence.NamedEntityGraphs;
11 import javax.persistence.Table; 11 import javax.persistence.Table;
12 12
  13 +import com.fasterxml.jackson.annotation.JsonIgnore;
  14 +
  15 +
13 /** 16 /**
14 * 17 *
15 * @ClassName: ChildTaskPlan 18 * @ClassName: ChildTaskPlan
@@ -95,7 +98,8 @@ public class ChildTaskPlan { @@ -95,7 +98,8 @@ public class ChildTaskPlan {
95 /** 98 /**
96 * 主排班计划 99 * 主排班计划
97 */ 100 */
98 - @ManyToOne 101 + @JsonIgnore
  102 + @ManyToOne(fetch = FetchType.LAZY)
99 private ScheduleRealInfo schedule; 103 private ScheduleRealInfo schedule;
100 104
101 private String remarks; 105 private String remarks;
src/main/java/com/bsth/entity/realcontrol/ScheduleRealInfo.java
1 package com.bsth.entity.realcontrol; 1 package com.bsth.entity.realcontrol;
2 2
3 import com.bsth.entity.sys.SysUser; 3 import com.bsth.entity.sys.SysUser;
  4 +import com.bsth.vehicle.gpsdata.arrival.entity.RealTimeModel;
  5 +import com.fasterxml.jackson.annotation.JsonIgnore;
4 6
5 import javax.persistence.*; 7 import javax.persistence.*;
6 8
  9 +import org.apache.commons.lang3.StringUtils;
  10 +
7 import java.text.ParseException; 11 import java.text.ParseException;
8 import java.text.SimpleDateFormat; 12 import java.text.SimpleDateFormat;
9 import java.util.Date; 13 import java.util.Date;
  14 +import java.util.HashSet;
  15 +import java.util.Set;
10 16
11 /** 17 /**
12 * 实际排班计划明细。 18 * 实际排班计划明细。
13 */ 19 */
14 @Entity 20 @Entity
15 @Table(name = "bsth_c_s_sp_info_real") 21 @Table(name = "bsth_c_s_sp_info_real")
  22 +@NamedEntityGraphs({
  23 + @NamedEntityGraph(name = "scheduleRealInfo_cTasks", attributeNodes = {
  24 + @NamedAttributeNode("cTasks"),
  25 + @NamedAttributeNode("sjfcModel"),
  26 + @NamedAttributeNode("sjddModel")
  27 + })
  28 +})
16 public class ScheduleRealInfo { 29 public class ScheduleRealInfo {
17 /** 主键Id */ 30 /** 主键Id */
18 @Id 31 @Id
@@ -24,6 +37,10 @@ public class ScheduleRealInfo { @@ -24,6 +37,10 @@ public class ScheduleRealInfo {
24 37
25 /** 排班计划日期 */ 38 /** 排班计划日期 */
26 private Date scheduleDate; 39 private Date scheduleDate;
  40 + private String scheduleDateStr;
  41 +
  42 + /** 真实执行时间 yyyy-MM-dd */
  43 + private String realExecDate;
27 44
28 /** 线路名称 */ 45 /** 线路名称 */
29 private String xlName; 46 private String xlName;
@@ -87,18 +104,31 @@ public class ScheduleRealInfo { @@ -87,18 +104,31 @@ public class ScheduleRealInfo {
87 * 班次类型 TODO:正常班次、出场、进场、加油、区间班次、放空班次、放大站班次、两点间空驶 104 * 班次类型 TODO:正常班次、出场、进场、加油、区间班次、放空班次、放大站班次、两点间空驶
88 */ 105 */
89 private String bcType; 106 private String bcType;
  107 +
  108 + /** 停车场既首发站 */
  109 + @Transient
  110 + private boolean parkIsFirstStation;
  111 + /** 首发站既停车场 */
  112 + @Transient
  113 + private boolean firstStationIsPark;
  114 + /** 与其共享发车时间的进出场班次 */
  115 + @JsonIgnore
  116 + @Transient
  117 + private ScheduleRealInfo twins;
90 118
91 /** 创建人 */ 119 /** 创建人 */
  120 + @JsonIgnore
92 @ManyToOne(fetch = FetchType.LAZY) 121 @ManyToOne(fetch = FetchType.LAZY)
93 private SysUser createBy; 122 private SysUser createBy;
94 /** 修改人 */ 123 /** 修改人 */
  124 + @JsonIgnore
95 @ManyToOne(fetch = FetchType.LAZY) 125 @ManyToOne(fetch = FetchType.LAZY)
96 private SysUser updateBy; 126 private SysUser updateBy;
97 /** 创建日期 */ 127 /** 创建日期 */
98 @Column(updatable = false, name = "create_date", columnDefinition = "TIMESTAMP DEFAULT CURRENT_TIMESTAMP") 128 @Column(updatable = false, name = "create_date", columnDefinition = "TIMESTAMP DEFAULT CURRENT_TIMESTAMP")
99 private Date createDate; 129 private Date createDate;
100 /** 修改日期 */ 130 /** 修改日期 */
101 - @Column(name = "update_date", columnDefinition = "TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP") 131 + @Column(name = "update_date", columnDefinition = "TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP")
102 private Date updateDate; 132 private Date updateDate;
103 133
104 /** 实际发车时间*/ 134 /** 实际发车时间*/
@@ -149,12 +179,28 @@ public class ScheduleRealInfo { @@ -149,12 +179,28 @@ public class ScheduleRealInfo {
149 /** 起点站实际到达时间 */ 179 /** 起点站实际到达时间 */
150 private String qdzArrDatesj; 180 private String qdzArrDatesj;
151 181
  182 + /** 子任务 */
  183 + @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
  184 + private Set<ChildTaskPlan> cTasks = new HashSet<>();
  185 +
  186 + /** ---------------- */
  187 + /** 实际发出 */
  188 + @OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
  189 + private RealTimeModel sjfcModel;
  190 + /** 实际到达 */
  191 + @OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
  192 + private RealTimeModel sjddModel;
  193 +
152 public void addRemarks(String remark){ 194 public void addRemarks(String remark){
153 - String newRem = this.getRemarks();  
154 - if(null == newRem || newRem.trim() == "") 195 + if(StringUtils.isBlank(remark))
155 return; 196 return;
156 - newRem += remark + ";";  
157 - this.setRemarks(newRem); 197 + String old = this.getRemarks();
  198 + if(StringUtils.isBlank(old))
  199 + old = "";
  200 +
  201 + old += remark + ";";
  202 + this.setRemarks(old);
  203 +
158 } 204 }
159 205
160 public Long getId() { 206 public Long getId() {
@@ -485,7 +531,7 @@ public class ScheduleRealInfo { @@ -485,7 +531,7 @@ public class ScheduleRealInfo {
485 public void setDfsjAll(String dfsj) { 531 public void setDfsjAll(String dfsj) {
486 532
487 try { 533 try {
488 - String dfsjFull = sdfyyyyMMdd.format(this.scheduleDate) + " " + dfsj; 534 + String dfsjFull = this.realExecDate + " " + dfsj;
489 this.dfsjT = sdfyyyyMMddHHmm.parse(dfsjFull).getTime(); 535 this.dfsjT = sdfyyyyMMddHHmm.parse(dfsjFull).getTime();
490 this.dfsj = dfsj; 536 this.dfsj = dfsj;
491 } catch (ParseException e) { 537 } catch (ParseException e) {
@@ -504,7 +550,7 @@ public class ScheduleRealInfo { @@ -504,7 +550,7 @@ public class ScheduleRealInfo {
504 * @throws ParseException 550 * @throws ParseException
505 * 551 *
506 * @Title: syncTime 552 * @Title: syncTime
507 - * @Description: TODO(计算时间戳,待发时间为计发时间) 553 + * @Description: TODO(根据计发时间,计算待发时间和终点时间)
508 * @param 设定文件 554 * @param 设定文件
509 * @return void 返回类型 555 * @return void 返回类型
510 * @throws 556 * @throws
@@ -513,7 +559,7 @@ public class ScheduleRealInfo { @@ -513,7 +559,7 @@ public class ScheduleRealInfo {
513 try{ 559 try{
514 this.setDfsj(this.getFcsj()); 560 this.setDfsj(this.getFcsj());
515 //发车时间戳 561 //发车时间戳
516 - this.setFcsjT(sdfyyyyMMddHHmm.parse(sdfyyyyMMdd.format(this.scheduleDate) + " " + this.getFcsj()).getTime()); 562 + this.setFcsjT(sdfyyyyMMddHHmm.parse(this.realExecDate + " " + this.getFcsj()).getTime());
517 //待发时间戳 563 //待发时间戳
518 this.setDfsjT(this.getFcsjT()); 564 this.setDfsjT(this.getFcsjT());
519 565
@@ -523,6 +569,12 @@ public class ScheduleRealInfo { @@ -523,6 +569,12 @@ public class ScheduleRealInfo {
523 this.setZdsjT(zdDate.getTime()); 569 this.setZdsjT(zdDate.getTime());
524 this.setZdsj(sdfHHmm.format(zdDate)); 570 this.setZdsj(sdfHHmm.format(zdDate));
525 } 571 }
  572 +
  573 + if(this.fcsjActual != null)
  574 + this.setFcsjActualAll(this.fcsjActual);
  575 +
  576 + if(this.zdsjActual != null)
  577 + this.setZdsjActualAll(this.zdsjActual);
526 }catch(Exception e){ 578 }catch(Exception e){
527 e.printStackTrace(); 579 e.printStackTrace();
528 } 580 }
@@ -573,7 +625,7 @@ public class ScheduleRealInfo { @@ -573,7 +625,7 @@ public class ScheduleRealInfo {
573 */ 625 */
574 public void setFcsjAll(String fcsj){ 626 public void setFcsjAll(String fcsj){
575 try { 627 try {
576 - this.fcsjT = sdfyyyyMMddHHmm.parse(sdfyyyyMMdd.format(this.scheduleDate) + " " + fcsj).getTime(); 628 + this.fcsjT = sdfyyyyMMddHHmm.parse(this.realExecDate + " " + fcsj).getTime();
577 this.fcsj = fcsj; 629 this.fcsj = fcsj;
578 } catch (ParseException e) { 630 } catch (ParseException e) {
579 e.printStackTrace(); 631 e.printStackTrace();
@@ -582,14 +634,27 @@ public class ScheduleRealInfo { @@ -582,14 +634,27 @@ public class ScheduleRealInfo {
582 634
583 /** 635 /**
584 * 636 *
  637 + * @Title: setFcsjAll
  638 + * @Description: TODO(设置计划发车时间)
  639 + * @throws
  640 + */
  641 + public void setFcsjAll(Long fcsjT){
  642 + this.fcsjT = fcsjT;
  643 + this.fcsj = sdfHHmm.format(new Date(fcsjT));
  644 + }
  645 +
  646 + /**
  647 + *
585 * @Title: setFcsjActualAll 648 * @Title: setFcsjActualAll
586 - * @Description: TODO(设置实际发车时间) 649 + * @Description: TODO(设置实际发车时间 字符串)
587 * @throws 650 * @throws
588 */ 651 */
589 public void setFcsjActualAll(String fcsjActual){ 652 public void setFcsjActualAll(String fcsjActual){
590 try { 653 try {
591 - this.fcsjActualTime = sdfyyyyMMddHHmm.parse(sdfyyyyMMdd.format(this.scheduleDate) + " " + fcsjActual).getTime(); 654 + this.fcsjActualTime = sdfyyyyMMddHHmm.parse(this.realExecDate + " " + fcsjActual).getTime();
592 this.fcsjActual = fcsjActual; 655 this.fcsjActual = fcsjActual;
  656 +
  657 + this.synchroFcsj();
593 } catch (ParseException e) { 658 } catch (ParseException e) {
594 e.printStackTrace(); 659 e.printStackTrace();
595 } 660 }
@@ -598,12 +663,29 @@ public class ScheduleRealInfo { @@ -598,12 +663,29 @@ public class ScheduleRealInfo {
598 /** 663 /**
599 * 664 *
600 * @Title: setFcsjActualAll 665 * @Title: setFcsjActualAll
601 - * @Description: TODO(设置实际发车时间) 666 + * @Description: TODO(设置实际发车时间 时间戳)
602 * @throws 667 * @throws
603 */ 668 */
604 public void setFcsjActualAll(Long t){ 669 public void setFcsjActualAll(Long t){
605 this.fcsjActualTime = t; 670 this.fcsjActualTime = t;
606 this.fcsjActual = sdfHHmm.format(new Date(t)); 671 this.fcsjActual = sdfHHmm.format(new Date(t));
  672 +
  673 + this.synchroFcsj();
  674 + }
  675 +
  676 + //和依赖班次同步发车时间
  677 + public void synchroFcsj(){
  678 + if(this.isFirstStationIsPark() || this.isParkIsFirstStation()){
  679 + ScheduleRealInfo twinsSch = this.twins;
  680 + if(null != twinsSch){
  681 + //有关联的出场班次
  682 + twinsSch.setFcsjActual(this.fcsjActual);
  683 + twinsSch.setFcsjActualTime(this.fcsjActualTime);
  684 + if(null != twinsSch.getSjfcModel())
  685 + twinsSch.getSjfcModel().setPersonTime(this.fcsjActualTime);
  686 + twinsSch.calcStatus();
  687 + }
  688 + }
607 } 689 }
608 690
609 /** 691 /**
@@ -615,6 +697,8 @@ public class ScheduleRealInfo { @@ -615,6 +697,8 @@ public class ScheduleRealInfo {
615 public void setZdsjActualAll(Long t){ 697 public void setZdsjActualAll(Long t){
616 this.zdsjActualTime = t; 698 this.zdsjActualTime = t;
617 this.zdsjActual = sdfHHmm.format(new Date(t)); 699 this.zdsjActual = sdfHHmm.format(new Date(t));
  700 +
  701 + this.synchroZdsj();
618 } 702 }
619 703
620 /** 704 /**
@@ -627,10 +711,25 @@ public class ScheduleRealInfo { @@ -627,10 +711,25 @@ public class ScheduleRealInfo {
627 try { 711 try {
628 this.zdsjActualTime = sdfyyyyMMddHHmm.parse(sdfyyyyMMdd.format(this.scheduleDate) + " " + zdsjActual).getTime(); 712 this.zdsjActualTime = sdfyyyyMMddHHmm.parse(sdfyyyyMMdd.format(this.scheduleDate) + " " + zdsjActual).getTime();
629 this.zdsjActual = zdsjActual; 713 this.zdsjActual = zdsjActual;
  714 +
  715 + this.synchroZdsj();
630 } catch (ParseException e) { 716 } catch (ParseException e) {
631 e.printStackTrace(); 717 e.printStackTrace();
632 } 718 }
633 } 719 }
  720 +
  721 + //和依赖的进场班次同步终点时间
  722 + public void synchroZdsj(){
  723 + if(this.isFirstStationIsPark()){
  724 + ScheduleRealInfo twinsSch = this.twins;
  725 + if(null != twinsSch && twinsSch.getBcType().equals("in")){
  726 + //有关联的进场班次
  727 + twinsSch.setFcsjActual(this.zdsjActual);
  728 + twinsSch.setFcsjActualTime(this.zdsjActualTime);
  729 + twinsSch.calcStatus();
  730 + }
  731 + }
  732 + }
634 733
635 public Long getSpId() { 734 public Long getSpId() {
636 return spId; 735 return spId;
@@ -639,4 +738,140 @@ public class ScheduleRealInfo { @@ -639,4 +738,140 @@ public class ScheduleRealInfo {
639 public void setSpId(Long spId) { 738 public void setSpId(Long spId) {
640 this.spId = spId; 739 this.spId = spId;
641 } 740 }
  741 +
  742 + public String getRealExecDate() {
  743 + return realExecDate;
  744 + }
  745 +
  746 + public void setRealExecDate(String realExecDate) {
  747 + this.realExecDate = realExecDate;
  748 + }
  749 +
  750 + public void calcStatus() {
  751 + if(this.status == -1)
  752 + return;
  753 +
  754 + this.status = 0;
  755 + if(StringUtils.isNotBlank(this.fcsjActual)){
  756 + this.status = 1;
  757 +
  758 + //进出场班次并且没有终点时间的
  759 + if((this.bcType.equals("out") || this.bcType.equals("in"))
  760 + && this.zdsj == null){
  761 + this.status = 2;
  762 + }
  763 + }
  764 + if(StringUtils.isNotBlank(this.zdsjActual))
  765 + this.status = 2;
  766 + }
  767 +
  768 + public void destroy(){
  769 + this.status = -1;
  770 + }
  771 +
  772 + public boolean isDestroy(){
  773 + return this.status == -1;
  774 + }
  775 +
  776 + public boolean isNotDestroy(){
  777 + return this.status != -1;
  778 + }
  779 +
  780 + public RealTimeModel getSjfcModel() {
  781 + return sjfcModel;
  782 + }
  783 +
  784 + public void setSjfcModel(RealTimeModel sjfcModel) {
  785 + this.sjfcModel = sjfcModel;
  786 + }
  787 +
  788 + public RealTimeModel getSjddModel() {
  789 + return sjddModel;
  790 + }
  791 +
  792 + public void setSjddModel(RealTimeModel sjddModel) {
  793 + this.sjddModel = sjddModel;
  794 + }
  795 +
  796 + public Set<ChildTaskPlan> getcTasks() {
  797 + return cTasks;
  798 + }
  799 +
  800 + public void setcTasks(Set<ChildTaskPlan> cTasks) {
  801 + this.cTasks = cTasks;
  802 + }
  803 +
  804 + public String getScheduleDateStr() {
  805 + return scheduleDateStr;
  806 + }
  807 +
  808 + public void setScheduleDateStr(String scheduleDateStr) {
  809 + this.scheduleDateStr = scheduleDateStr;
  810 + }
  811 +
  812 + public boolean isParkIsFirstStation() {
  813 + return parkIsFirstStation;
  814 + }
  815 +
  816 + public void setParkIsFirstStation(boolean parkIsFirstStation) {
  817 + this.parkIsFirstStation = parkIsFirstStation;
  818 + }
  819 +
  820 + public ScheduleRealInfo getTwins() {
  821 + return twins;
  822 + }
  823 +
  824 + public void setTwins(ScheduleRealInfo twins) {
  825 + this.twins = twins;
  826 + }
  827 +
  828 + public boolean isFirstStationIsPark() {
  829 + return firstStationIsPark;
  830 + }
  831 +
  832 + public void setFirstStationIsPark(boolean firstStationIsPark) {
  833 + this.firstStationIsPark = firstStationIsPark;
  834 + }
  835 +
  836 +
  837 + public boolean statusTostart(){
  838 + return this.getFcsjActual() == null
  839 + && this.getSjfcModel().getTime() != null;
  840 + }
  841 +
  842 + public boolean statusToEnd(){
  843 + return this.getZdsjActual() == null
  844 + && this.getSjddModel().getTime() != null;
  845 + }
  846 +
  847 + public void revokeRealOutgo() {
  848 + //this.setStatus(0);
  849 + this.setFcsjActual(null);
  850 + this.setFcsjActualTime(null);
  851 + if(null != this.getSjfcModel())
  852 + this.getSjfcModel().resetNull();
  853 + this.calcStatus();
  854 + }
  855 +
  856 + public boolean existDependent() {
  857 + return this.isFirstStationIsPark() || this.parkIsFirstStation;
  858 + }
  859 +
  860 + //清除实际终点时间
  861 + public void clearZdsjActual(){
  862 + this.setZdsjActual(null);
  863 + this.setZdsjActualTime(null);
  864 + if(null != this.getSjddModel())
  865 + this.getSjddModel().resetNull();
  866 +
  867 + //依赖班次
  868 + if(this.existDependent()){
  869 + ScheduleRealInfo twins = this.getTwins();
  870 + twins.setZdsjActual(null);
  871 + twins.setZdsjActualTime(null);
  872 + if(null != twins.getSjddModel())
  873 + twins.getSjddModel().resetNull();
  874 +
  875 + }
  876 + }
642 } 877 }
src/main/java/com/bsth/repository/realcontrol/ScheduleRealInfoRepository.java
@@ -4,6 +4,7 @@ import java.util.Date; @@ -4,6 +4,7 @@ import java.util.Date;
4 import java.util.List; 4 import java.util.List;
5 import java.util.Map; 5 import java.util.Map;
6 6
  7 +import org.springframework.data.jpa.repository.EntityGraph;
7 import org.springframework.data.jpa.repository.Query; 8 import org.springframework.data.jpa.repository.Query;
8 import org.springframework.stereotype.Repository; 9 import org.springframework.stereotype.Repository;
9 10
@@ -20,7 +21,7 @@ public interface ScheduleRealInfoRepository extends BaseRepository&lt;ScheduleRealI @@ -20,7 +21,7 @@ public interface ScheduleRealInfoRepository extends BaseRepository&lt;ScheduleRealI
20 @Query(value="select s from ScheduleRealInfo s where s.xlBm = ?1 and DATE_FORMAT(s.scheduleDate,'%Y-%m-%d') = ?2 group by jName,clZbh,lpName") 21 @Query(value="select s from ScheduleRealInfo s where s.xlBm = ?1 and DATE_FORMAT(s.scheduleDate,'%Y-%m-%d') = ?2 group by jName,clZbh,lpName")
21 List<ScheduleRealInfo> queryUserInfo(String line,String date); 22 List<ScheduleRealInfo> queryUserInfo(String line,String date);
22 23
23 - @Query(value="select s from ScheduleRealInfo s where s.jName = ?1 and s.clZbh = ?2 and s.lpName = ?3") 24 + @Query(value="select s from ScheduleRealInfo s where s.jName = ?1 and s.clZbh = ?2 and s.lpName = ?3 order by fcsj")
24 List<ScheduleRealInfo> exportWaybill(String jName,String clZbh,String lpName); 25 List<ScheduleRealInfo> exportWaybill(String jName,String clZbh,String lpName);
25 26
26 @Query(value="select new map(clZbh as clZbh,jGh as jGh,jName as jName,sum(jhlc) as zgl,sum(addMileage) as ksgl,count(jName) as bcs) from ScheduleRealInfo s where s.xlBm = ?1 and DATE_FORMAT(s.scheduleDate,'%Y-%m-%d') = ?2 group by clZbh,jGh") 27 @Query(value="select new map(clZbh as clZbh,jGh as jGh,jName as jName,sum(jhlc) as zgl,sum(addMileage) as ksgl,count(jName) as bcs) from ScheduleRealInfo s where s.xlBm = ?1 and DATE_FORMAT(s.scheduleDate,'%Y-%m-%d') = ?2 group by clZbh,jGh")
@@ -32,11 +33,12 @@ public interface ScheduleRealInfoRepository extends BaseRepository&lt;ScheduleRealI @@ -32,11 +33,12 @@ public interface ScheduleRealInfoRepository extends BaseRepository&lt;ScheduleRealI
32 @Query(value = "select max(id) from ScheduleRealInfo") 33 @Query(value = "select max(id) from ScheduleRealInfo")
33 Long getMaxId(); 34 Long getMaxId();
34 35
35 - @Query(value = "select count(*) from ScheduleRealInfo s where s.scheduleDate = ?1")  
36 - int countByDate(Date date); 36 + @Query(value = "select count(*) from ScheduleRealInfo s where s.scheduleDateStr = ?1")
  37 + int countByDate(String date);
37 38
38 - @Query(value = "select s from ScheduleRealInfo s where s.scheduleDate = ?1")  
39 - List<ScheduleRealInfo> findByDate(Date date); 39 + @EntityGraph(value = "scheduleRealInfo_cTasks", type = EntityGraph.EntityGraphType.FETCH)
  40 + @Query(value = "select s from ScheduleRealInfo s where s.scheduleDateStr = ?1")
  41 + List<ScheduleRealInfo> findByDate(String dateStr);
40 42
41 @Query(value="select count(jName) from ScheduleRealInfo s where s.jName = ?1 and s.clZbh = ?2 and s.lpName = ?3 and s.status = -1") 43 @Query(value="select count(jName) from ScheduleRealInfo s where s.jName = ?1 and s.clZbh = ?2 and s.lpName = ?3 and s.status = -1")
42 int findCjbc(String jName,String clZbh,String lpName); 44 int findCjbc(String jName,String clZbh,String lpName);
src/main/java/com/bsth/service/realcontrol/buffer/GetSchedulePlanThread.java
@@ -46,6 +46,7 @@ public class GetSchedulePlanThread extends Thread{ @@ -46,6 +46,7 @@ public class GetSchedulePlanThread extends Thread{
46 @Override 46 @Override
47 public void run() { 47 public void run() {
48 try{ 48 try{
  49 + logger.info("从计划调度抓取排班数据...");
49 //清除缓存 50 //清除缓存
50 ScheduleBuffer.clear(); 51 ScheduleBuffer.clear();
51 //所有指令入库 52 //所有指令入库
@@ -62,18 +63,18 @@ public class GetSchedulePlanThread extends Thread{ @@ -62,18 +63,18 @@ public class GetSchedulePlanThread extends Thread{
62 public void loaSchedule() throws ParseException{ 63 public void loaSchedule() throws ParseException{
63 List<ScheduleRealInfo> realList = null; 64 List<ScheduleRealInfo> realList = null;
64 String dateStr = sdfyyyyMMdd.format(new Date()); 65 String dateStr = sdfyyyyMMdd.format(new Date());
65 - Date cDate = sdfyyyyMMdd.parse(dateStr); 66 + //Date cDate = sdfyyyyMMdd.parse(dateStr);
66 //查询数据库是否有今日排班 67 //查询数据库是否有今日排班
67 - int size = scheduleRealInfoRepository.countByDate(cDate); 68 + int size = scheduleRealInfoRepository.countByDate(dateStr);
68 if(size > 0){ 69 if(size > 0){
69 //从数据库恢复当日排班 70 //从数据库恢复当日排班
70 - realList = scheduleRealInfoRepository.findByDate(cDate); 71 + realList = scheduleRealInfoRepository.findByDate(dateStr);
71 logger.info("从数据库恢复当日排班 " + realList.size()); 72 logger.info("从数据库恢复当日排班 " + realList.size());
72 //写入缓存 73 //写入缓存
73 ScheduleBuffer.init(realList); 74 ScheduleBuffer.init(realList);
74 } 75 }
75 else{ 76 else{
76 - List<SchedulePlanInfo> list = schedulePlanInfoRepository.findByDate(cDate); 77 + List<SchedulePlanInfo> list = schedulePlanInfoRepository.findByDate(sdfyyyyMMdd.parse(dateStr));
77 78
78 for(SchedulePlanInfo sp : list){ 79 for(SchedulePlanInfo sp : list){
79 sp.setSchedulePlan(null); 80 sp.setSchedulePlan(null);
@@ -90,6 +91,7 @@ public class GetSchedulePlanThread extends Thread{ @@ -90,6 +91,7 @@ public class GetSchedulePlanThread extends Thread{
90 for(ScheduleRealInfo item : realList){ 91 for(ScheduleRealInfo item : realList){
91 item.setSpId(item.getId()); 92 item.setSpId(item.getId());
92 item.setId(id ++);//设置ID 93 item.setId(id ++);//设置ID
  94 + item.setScheduleDateStr(sdfyyyyMMdd.format(item.getScheduleDate()));
93 } 95 }
94 96
95 //写入缓存 97 //写入缓存
src/main/java/com/bsth/service/realcontrol/buffer/ScheduleBuffer.java
1 package com.bsth.service.realcontrol.buffer; 1 package com.bsth.service.realcontrol.buffer;
2 2
  3 +import java.text.SimpleDateFormat;
3 import java.util.ArrayList; 4 import java.util.ArrayList;
4 import java.util.Collections; 5 import java.util.Collections;
5 import java.util.Comparator; 6 import java.util.Comparator;
  7 +import java.util.Date;
6 import java.util.HashMap; 8 import java.util.HashMap;
7 import java.util.LinkedList; 9 import java.util.LinkedList;
8 import java.util.List; 10 import java.util.List;
@@ -14,7 +16,6 @@ import org.slf4j.LoggerFactory; @@ -14,7 +16,6 @@ import org.slf4j.LoggerFactory;
14 16
15 import com.bsth.entity.realcontrol.ScheduleRealInfo; 17 import com.bsth.entity.realcontrol.ScheduleRealInfo;
16 import com.google.common.collect.ArrayListMultimap; 18 import com.google.common.collect.ArrayListMultimap;
17 -import com.google.common.collect.LinkedListMultimap;  
18 19
19 /** 20 /**
20 * 21 *
@@ -31,7 +32,7 @@ public class ScheduleBuffer { @@ -31,7 +32,7 @@ public class ScheduleBuffer {
31 /** 32 /**
32 * 当天实际排班 K 线路编码 V 按时间升序的班次 33 * 当天实际排班 K 线路编码 V 按时间升序的班次
33 */ 34 */
34 - public static ArrayListMultimap<String, ScheduleRealInfo> schedulListMap; 35 + public static ArrayListMultimap<String, ScheduleRealInfo> realSchedulListMap;
35 36
36 /** 37 /**
37 * K: 车辆自编号 V: 未完成班次链表 38 * K: 车辆自编号 V: 未完成班次链表
@@ -41,7 +42,7 @@ public class ScheduleBuffer { @@ -41,7 +42,7 @@ public class ScheduleBuffer {
41 /** 42 /**
42 * K: 车辆自编号 V: 班次链表 43 * K: 车辆自编号 V: 班次链表
43 */ 44 */
44 - public static ArrayListMultimap<String, ScheduleRealInfo> vehSchListMap; 45 + public static ArrayListMultimap<String, ScheduleRealInfo> carSchListMap;
45 /*public static Map<String, LinkedList<ScheduleRealInfo>> vehSchLinkedMap;*/ 46 /*public static Map<String, LinkedList<ScheduleRealInfo>> vehSchLinkedMap;*/
46 47
47 48
@@ -61,8 +62,8 @@ public class ScheduleBuffer { @@ -61,8 +62,8 @@ public class ScheduleBuffer {
61 */ 62 */
62 public static LinkedList<ScheduleRealInfo> persistentList; 63 public static LinkedList<ScheduleRealInfo> persistentList;
63 64
64 - /** K: 线路编码_上下行 V: 班次平均间隔时间 */  
65 - public static Map<String , Long> schSpaceMap; 65 + /** K: 线路编码_上下行 V: 班次平均间隔时间
  66 + public static Map<String , Long> schSpaceMap; */
66 67
67 /** 68 /**
68 * 线路是否托管 K:线路编码 V:0 托管 1 非托管 69 * 线路是否托管 K:线路编码 V:0 托管 1 非托管
@@ -71,25 +72,30 @@ public class ScheduleBuffer { @@ -71,25 +72,30 @@ public class ScheduleBuffer {
71 72
72 static ScheduleComparator scheduleComparator = new ScheduleComparator(); 73 static ScheduleComparator scheduleComparator = new ScheduleComparator();
73 74
  75 + static final Long DAY_TIME = 1000 * 60 * 60 * 24L;
  76 +
74 static{ 77 static{
75 clear(); 78 clear();
76 } 79 }
77 80
78 public static void clear(){ 81 public static void clear(){
79 - schedulListMap = ArrayListMultimap.create(); 82 + realSchedulListMap = ArrayListMultimap.create();
80 pkSchedulMap = new HashMap<>(); 83 pkSchedulMap = new HashMap<>();
81 persistentList = new LinkedList<>(); 84 persistentList = new LinkedList<>();
82 /*vehLinkedMap = new HashMap<>(); 85 /*vehLinkedMap = new HashMap<>();
83 finishLinkedMap = LinkedListMultimap.create();*/ 86 finishLinkedMap = LinkedListMultimap.create();*/
84 - vehSchListMap = ArrayListMultimap.create(); 87 + carSchListMap = ArrayListMultimap.create();
85 trustMap = new HashMap<>(); 88 trustMap = new HashMap<>();
86 } 89 }
87 90
88 public static int init(List<ScheduleRealInfo> list){ 91 public static int init(List<ScheduleRealInfo> list){
  92 + SimpleDateFormat sdfyyyyMMdd = new SimpleDateFormat("yyyy-MM-dd");
89 93
90 try{ 94 try{
91 //计算时间戳 95 //计算时间戳
92 for(ScheduleRealInfo schedul : list){ 96 for(ScheduleRealInfo schedul : list){
  97 + //真实日期默认是排班日期
  98 + schedul.setRealExecDate(sdfyyyyMMdd.format(schedul.getScheduleDate()));
93 schedul.syncTime(); 99 schedul.syncTime();
94 } 100 }
95 101
@@ -98,25 +104,33 @@ public class ScheduleBuffer { @@ -98,25 +104,33 @@ public class ScheduleBuffer {
98 104
99 String zbh; 105 String zbh;
100 for(ScheduleRealInfo schedul : list){ 106 for(ScheduleRealInfo schedul : list){
101 - schedulListMap.put(schedul.getXlBm(), schedul); 107 +
  108 + realSchedulListMap.put(schedul.getXlBm(), schedul);
102 pkSchedulMap.put(schedul.getId(), schedul); 109 pkSchedulMap.put(schedul.getId(), schedul);
103 110
104 //初始化车辆和班次列表对照 111 //初始化车辆和班次列表对照
105 zbh = schedul.getClZbh(); 112 zbh = schedul.getClZbh();
106 - vehSchListMap.put(zbh, schedul);  
107 - /*if(!vehLinkedMap.containsKey(zbh))  
108 - vehLinkedMap.put(zbh, new LinkedList<ScheduleRealInfo>());  
109 -  
110 - vehLinkedMap.get(zbh).add(schedul);*/ 113 + carSchListMap.put(zbh, schedul);
111 } 114 }
112 115
  116 + //计算真实计划发车时间
  117 + calcRealOutTime();
  118 +
113 //计算起点应到时间 119 //计算起点应到时间
114 - Set<String> codes = schedulListMap.keySet();  
115 - for(String code : codes)  
116 - calcArrDateQd(code); 120 + Set<String> lineCodes = realSchedulListMap.keySet();
  121 + for(String lineCode : lineCodes)
  122 + calcArrDateQd(lineCode);
  123 +
  124 + //标记停车场既是起点站的班次
  125 + Set<String> cars = carSchListMap.keySet();
  126 + for(String nbbm : cars)
  127 + markParkIsFirstStation(nbbm);
  128 +
  129 + //markParkIsFirstStation
117 130
118 //计算班次平均间隔 131 //计算班次平均间隔
119 - calcAvgSpace(); 132 + //calcAvgSpace();
  133 +
120 }catch(Exception e){ 134 }catch(Exception e){
121 logger.error("缓存排班数据失败...", e); 135 logger.error("缓存排班数据失败...", e);
122 return -1; 136 return -1;
@@ -124,16 +138,73 @@ public class ScheduleBuffer { @@ -124,16 +138,73 @@ public class ScheduleBuffer {
124 return 0; 138 return 0;
125 } 139 }
126 140
  141 + private static void calcRealOutTime() {
  142 + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
  143 + Set<String> keys = carSchListMap.keySet();
  144 +
  145 + List<ScheduleRealInfo> list;
  146 + ScheduleRealInfo schedule;
  147 + for(String key : keys){
  148 + list = carSchListMap.get(key);
  149 +
  150 + //发车顺序号排序
  151 + Collections.sort(list, scheduleComparator);
  152 + for(int i = 0; i < list.size(); i ++){
  153 + schedule = list.get(i);
  154 + if(i > 0 && schedule.getFcsjT() < list.get(i - 1).getFcsjT()){
  155 + //加一天
  156 + schedule.setFcsjAll(schedule.getFcsjT() + DAY_TIME);
  157 + schedule.setRealExecDate(sdf.format(new Date(schedule.getFcsjT())));
  158 + schedule.syncTime();
  159 + }
  160 + }
  161 + }
  162 + }
  163 +
  164 + /**
  165 + *
  166 + * @Title: markParkIsFirstStation
  167 + * @Description: TODO(标记停车场即首发站的班次)
  168 + * @throws
  169 + */
  170 + public static void markParkIsFirstStation(String nbbm){
  171 + List<ScheduleRealInfo> list = carSchListMap.get(nbbm);
  172 +
  173 + String type;
  174 + for(ScheduleRealInfo sch : list){
  175 + type = sch.getBcType();
  176 + if(!type.equals("out") && !type.equals("in"))
  177 + continue;
  178 +
  179 + for(ScheduleRealInfo sch2 : list){
  180 +
  181 + if(sch.getId() == sch2.getId())
  182 + continue;
  183 +
  184 + if(sch.getFcsjT().equals(sch2.getFcsjT())//出场,发车时间一致
  185 + || sch.getFcsjT().equals(sch2.getZdsjT())//进场,上一班次站点时间为进场起点时间
  186 + ){
  187 + sch.setParkIsFirstStation(true);
  188 + sch2.setFirstStationIsPark(true);
  189 + //做双休关联
  190 + sch2.setTwins(sch);
  191 + sch.setTwins(sch2);
  192 + break;
  193 + }
  194 + }
  195 + }
  196 + }
  197 +
127 //计算平均间隔 198 //计算平均间隔
128 - public static void calcAvgSpace(){ 199 +/* public static void calcAvgSpace(){
129 schSpaceMap = new HashMap<>(); 200 schSpaceMap = new HashMap<>();
130 - Set<String> set = schedulListMap.keySet(); 201 + Set<String> set = realSchedulListMap.keySet();
131 202
132 List<ScheduleRealInfo> list = null 203 List<ScheduleRealInfo> list = null
133 ,upList = null 204 ,upList = null
134 ,downList = null; 205 ,downList = null;
135 for(String lineCode : set){ 206 for(String lineCode : set){
136 - list = schedulListMap.get(lineCode); 207 + list = realSchedulListMap.get(lineCode);
137 Long sumUp = 0L, sumDown = 0L; 208 Long sumUp = 0L, sumDown = 0L;
138 209
139 upList = new ArrayList<>(); 210 upList = new ArrayList<>();
@@ -156,14 +227,14 @@ public class ScheduleBuffer { @@ -156,14 +227,14 @@ public class ScheduleBuffer {
156 schSpaceMap.put(lineCode + "_0", sumUp / upList.size()); 227 schSpaceMap.put(lineCode + "_0", sumUp / upList.size());
157 schSpaceMap.put(lineCode + "_1", sumDown / downList.size()); 228 schSpaceMap.put(lineCode + "_1", sumDown / downList.size());
158 } 229 }
159 - } 230 + }*/
160 231
161 public static int put(ScheduleRealInfo sch){ 232 public static int put(ScheduleRealInfo sch){
162 - schedulListMap.put(sch.getXlBm(), sch); 233 + realSchedulListMap.put(sch.getXlBm(), sch);
163 234
164 pkSchedulMap.put(sch.getId(), sch); 235 pkSchedulMap.put(sch.getId(), sch);
165 String zbh = sch.getClZbh(); 236 String zbh = sch.getClZbh();
166 - vehSchListMap.put(zbh, sch); 237 + carSchListMap.put(zbh, sch);
167 238
168 //List<ScheduleRealInfo> list = vehSchListMap.get(sch.getClZbh()); 239 //List<ScheduleRealInfo> list = vehSchListMap.get(sch.getClZbh());
169 240
@@ -172,11 +243,11 @@ public class ScheduleBuffer { @@ -172,11 +243,11 @@ public class ScheduleBuffer {
172 vehLinkedMap.get(zbh).add(sch);*/ 243 vehLinkedMap.get(zbh).add(sch);*/
173 244
174 //重新排序 245 //重新排序
175 - Collections.sort(schedulListMap.get(sch.getXlBm()), scheduleComparator); 246 + Collections.sort(realSchedulListMap.get(sch.getXlBm()), scheduleComparator);
  247 + //Collections.sort(vehSchListMap.get(zbh), scheduleComparator);
176 248
177 //重新计算应到时间 249 //重新计算应到时间
178 - //calcArrDateQd(vehLinkedMap.get(zbh));  
179 - calcArrDateQd(vehSchListMap.get(zbh)); 250 + calcArrDateQd(carSchListMap.get(zbh));
180 return 0; 251 return 0;
181 } 252 }
182 253
@@ -205,7 +276,8 @@ public class ScheduleBuffer { @@ -205,7 +276,8 @@ public class ScheduleBuffer {
205 276
206 //下一个班次 277 //下一个班次
207 ScheduleRealInfo next = getNext(sch); 278 ScheduleRealInfo next = getNext(sch);
208 - next.setQdzArrDateSJ(sch.getZdsjActual()); 279 + if(next != null)
  280 + next.setQdzArrDateSJ(sch.getZdsjActual());
209 /*ScheduleRealInfo temp; 281 /*ScheduleRealInfo temp;
210 int len = list.size(); 282 int len = list.size();
211 for(int i = 0; i < len; i ++){ 283 for(int i = 0; i < len; i ++){
@@ -222,7 +294,7 @@ public class ScheduleBuffer { @@ -222,7 +294,7 @@ public class ScheduleBuffer {
222 } 294 }
223 295
224 public static ScheduleRealInfo getNext(ScheduleRealInfo sch){ 296 public static ScheduleRealInfo getNext(ScheduleRealInfo sch){
225 - List<ScheduleRealInfo> list = vehSchListMap.get(sch.getClZbh()); 297 + List<ScheduleRealInfo> list = carSchListMap.get(sch.getClZbh());
226 298
227 boolean flag = false; 299 boolean flag = false;
228 ScheduleRealInfo next = null; 300 ScheduleRealInfo next = null;
@@ -262,7 +334,7 @@ public class ScheduleBuffer { @@ -262,7 +334,7 @@ public class ScheduleBuffer {
262 * @throws 334 * @throws
263 */ 335 */
264 public static int getFinishSchNo(String nbbm){ 336 public static int getFinishSchNo(String nbbm){
265 - List<ScheduleRealInfo> list = vehSchListMap.get(nbbm); 337 + List<ScheduleRealInfo> list = carSchListMap.get(nbbm);
266 int no = 0; 338 int no = 0;
267 for(ScheduleRealInfo sch : list){ 339 for(ScheduleRealInfo sch : list){
268 if(sch.getStatus() == 2) 340 if(sch.getStatus() == 2)
@@ -280,7 +352,7 @@ public class ScheduleBuffer { @@ -280,7 +352,7 @@ public class ScheduleBuffer {
280 * @throws 352 * @throws
281 */ 353 */
282 public static ScheduleRealInfo findCurrent(String nbbm){ 354 public static ScheduleRealInfo findCurrent(String nbbm){
283 - List<ScheduleRealInfo> list = ScheduleBuffer.vehSchListMap.get(nbbm); 355 + List<ScheduleRealInfo> list = ScheduleBuffer.carSchListMap.get(nbbm);
284 356
285 int size = list.size(); 357 int size = list.size();
286 ScheduleRealInfo sch; 358 ScheduleRealInfo sch;
@@ -301,7 +373,7 @@ public class ScheduleBuffer { @@ -301,7 +373,7 @@ public class ScheduleBuffer {
301 * @throws 373 * @throws
302 */ 374 */
303 public static List<ScheduleRealInfo> findNextList(ScheduleRealInfo sch){ 375 public static List<ScheduleRealInfo> findNextList(ScheduleRealInfo sch){
304 - List<ScheduleRealInfo> list = vehSchListMap.get(sch.getClZbh()), 376 + List<ScheduleRealInfo> list = carSchListMap.get(sch.getClZbh()),
305 rs = null; 377 rs = null;
306 378
307 for(ScheduleRealInfo temp : list){ 379 for(ScheduleRealInfo temp : list){
@@ -338,7 +410,7 @@ public class ScheduleBuffer { @@ -338,7 +410,7 @@ public class ScheduleBuffer {
338 * @throws 410 * @throws
339 */ 411 */
340 public static void calcArrDateQd(String lineCode){ 412 public static void calcArrDateQd(String lineCode){
341 - List<ScheduleRealInfo> list = schedulListMap.get(lineCode); 413 + List<ScheduleRealInfo> list = realSchedulListMap.get(lineCode);
342 //按车辆分组 414 //按车辆分组
343 ArrayListMultimap<String, ScheduleRealInfo> map = ArrayListMultimap.create(); 415 ArrayListMultimap<String, ScheduleRealInfo> map = ArrayListMultimap.create();
344 for(ScheduleRealInfo sch : list){ 416 for(ScheduleRealInfo sch : list){
@@ -357,7 +429,7 @@ public class ScheduleBuffer { @@ -357,7 +429,7 @@ public class ScheduleBuffer {
357 } 429 }
358 430
359 public static List<ScheduleRealInfo> findByLineAndUpDown(Integer lineCode, Integer upDown){ 431 public static List<ScheduleRealInfo> findByLineAndUpDown(Integer lineCode, Integer upDown){
360 - List<ScheduleRealInfo> list = schedulListMap.get(String.valueOf(lineCode)) 432 + List<ScheduleRealInfo> list = realSchedulListMap.get(String.valueOf(lineCode))
361 ,subList = new ArrayList<>(); 433 ,subList = new ArrayList<>();
362 //按走向过滤 434 //按走向过滤
363 for(ScheduleRealInfo sch : list){ 435 for(ScheduleRealInfo sch : list){
@@ -367,4 +439,12 @@ public class ScheduleBuffer { @@ -367,4 +439,12 @@ public class ScheduleBuffer {
367 } 439 }
368 return subList; 440 return subList;
369 } 441 }
  442 +
  443 + public static ScheduleRealInfo getFirst(String nbbm){
  444 + List<ScheduleRealInfo> list = carSchListMap.get(nbbm);
  445 + if(list.size() > 0)
  446 + return list.get(0);
  447 + else
  448 + return null;
  449 + }
370 } 450 }
src/main/java/com/bsth/service/realcontrol/buffer/SchedulePersistenceThread.java
@@ -34,6 +34,10 @@ public class SchedulePersistenceThread extends Thread { @@ -34,6 +34,10 @@ public class SchedulePersistenceThread extends Thread {
34 break; 34 break;
35 35
36 scheduleRepository.save(schedule); 36 scheduleRepository.save(schedule);
  37 + if(schedule.existDependent()){
  38 + //关联班次也持久化
  39 + scheduleRepository.save(schedule.getTwins());
  40 + }
37 } 41 }
38 } 42 }
39 } 43 }
src/main/java/com/bsth/service/realcontrol/impl/ChildTaskPlanServiceImpl.java
@@ -2,25 +2,41 @@ package com.bsth.service.realcontrol.impl; @@ -2,25 +2,41 @@ package com.bsth.service.realcontrol.impl;
2 2
3 import java.util.Map; 3 import java.util.Map;
4 4
  5 +import javax.transaction.Transactional;
  6 +
  7 +import org.springframework.beans.factory.annotation.Autowired;
5 import org.springframework.stereotype.Service; 8 import org.springframework.stereotype.Service;
6 9
7 import com.bsth.entity.realcontrol.ChildTaskPlan; 10 import com.bsth.entity.realcontrol.ChildTaskPlan;
  11 +import com.bsth.entity.realcontrol.ScheduleRealInfo;
8 import com.bsth.service.impl.BaseServiceImpl; 12 import com.bsth.service.impl.BaseServiceImpl;
9 import com.bsth.service.realcontrol.ChildTaskPlanService; 13 import com.bsth.service.realcontrol.ChildTaskPlanService;
  14 +import com.bsth.service.realcontrol.buffer.ScheduleBuffer;
10 import com.bsth.vehicle.common.CommonMapped; 15 import com.bsth.vehicle.common.CommonMapped;
11 16
12 @Service 17 @Service
13 public class ChildTaskPlanServiceImpl extends BaseServiceImpl<ChildTaskPlan, Long> implements ChildTaskPlanService{ 18 public class ChildTaskPlanServiceImpl extends BaseServiceImpl<ChildTaskPlan, Long> implements ChildTaskPlanService{
14 19
  20 + @Autowired
  21 + ScheduleRealInfoServiceImpl scheduleRealInfoService;
15 22
  23 + @Transactional
16 @Override 24 @Override
17 public Map<String, Object> save(ChildTaskPlan t) { 25 public Map<String, Object> save(ChildTaskPlan t) {
  26 + Map<String, Object> rs;
18 //保存起终点名称 27 //保存起终点名称
19 Map<String, String> map = CommonMapped.stationCodeMap; 28 Map<String, String> map = CommonMapped.stationCodeMap;
20 29
21 t.setStartStationName(map.get(t.getStartStation())); 30 t.setStartStationName(map.get(t.getStartStation()));
22 t.setEndStationName(map.get(t.getEndStation())); 31 t.setEndStationName(map.get(t.getEndStation()));
23 - return super.save(t); 32 +
  33 + //rs = super.save(t);
  34 +
  35 + ScheduleRealInfo sch = ScheduleBuffer.findOne(t.getSchedule().getId());
  36 + sch.getcTasks().add(t);
  37 + rs = scheduleRealInfoService.save(sch);
  38 +
  39 + return rs;
24 } 40 }
25 41
26 } 42 }
src/main/java/com/bsth/service/realcontrol/impl/ScheduleRealInfoServiceImpl.java
1 package com.bsth.service.realcontrol.impl; 1 package com.bsth.service.realcontrol.impl;
2 2
3 -import java.io.File;  
4 import java.text.DecimalFormat; 3 import java.text.DecimalFormat;
5 import java.text.ParseException; 4 import java.text.ParseException;
6 import java.text.SimpleDateFormat; 5 import java.text.SimpleDateFormat;
@@ -88,7 +87,7 @@ public class ScheduleRealInfoServiceImpl extends BaseServiceImpl&lt;ScheduleRealInf @@ -88,7 +87,7 @@ public class ScheduleRealInfoServiceImpl extends BaseServiceImpl&lt;ScheduleRealInf
88 Multimap<String, ScheduleRealInfo> mMap = ArrayListMultimap.create(); 87 Multimap<String, ScheduleRealInfo> mMap = ArrayListMultimap.create();
89 88
90 for (String lineCode : lineList) { 89 for (String lineCode : lineList) {
91 - mMap.putAll(lineCode, ScheduleBuffer.schedulListMap.get(lineCode)); 90 + mMap.putAll(lineCode, ScheduleBuffer.realSchedulListMap.get(lineCode));
92 } 91 }
93 return mMap.asMap(); 92 return mMap.asMap();
94 } 93 }
@@ -99,9 +98,9 @@ public class ScheduleRealInfoServiceImpl extends BaseServiceImpl&lt;ScheduleRealInf @@ -99,9 +98,9 @@ public class ScheduleRealInfoServiceImpl extends BaseServiceImpl&lt;ScheduleRealInf
99 try { 98 try {
100 99
101 ScheduleRealInfo schedule = ScheduleBuffer.pkSchedulMap.get(id); 100 ScheduleRealInfo schedule = ScheduleBuffer.pkSchedulMap.get(id);
102 - schedule.setDfsjT(sdfMinute.parse(sdfMonth.format(new Date()) + " " + dfsj).getTime()); 101 + schedule.setDfsjT(sdfMinute.parse(schedule.getRealExecDate() + " " + dfsj).getTime());
103 schedule.setDfsj(dfsj); 102 schedule.setDfsj(dfsj);
104 - schedule.addRemarks(remarks + ";"); 103 + schedule.addRemarks(remarks);
105 schedule.setClZbh(nbbm); 104 schedule.setClZbh(nbbm);
106 if(jsy != null && jsy.indexOf("/") != -1){ 105 if(jsy != null && jsy.indexOf("/") != -1){
107 String[] jsyArray = jsy.split("/"); 106 String[] jsyArray = jsy.split("/");
@@ -139,16 +138,15 @@ public class ScheduleRealInfoServiceImpl extends BaseServiceImpl&lt;ScheduleRealInf @@ -139,16 +138,15 @@ public class ScheduleRealInfoServiceImpl extends BaseServiceImpl&lt;ScheduleRealInf
139 ScheduleRealInfo schedule = null; 138 ScheduleRealInfo schedule = null;
140 for (String id : idList) { 139 for (String id : idList) {
141 schedule = ScheduleBuffer.pkSchedulMap.get(Long.parseLong(id)); 140 schedule = ScheduleBuffer.pkSchedulMap.get(Long.parseLong(id));
142 - /*if(schedule.getStatus() == -1){ 141 + if(schedule.isDestroy()){
143 map.put("status", ResponseCode.ERROR); 142 map.put("status", ResponseCode.ERROR);
144 - map.put("msg", value)  
145 - }*/  
146 - if (null != schedule) {  
147 - schedule.setStatus(-1);  
148 - schedule.addRemarks(remarks);  
149 -  
150 - rsList.add(schedule); 143 + map.put("msg", "不必要的重复烂班!");
  144 + return map;
151 } 145 }
  146 +
  147 + schedule.destroy();
  148 + schedule.addRemarks(remarks);
  149 + rsList.add(schedule);
152 } 150 }
153 151
154 // 调整间隔 152 // 调整间隔
@@ -158,7 +156,7 @@ public class ScheduleRealInfoServiceImpl extends BaseServiceImpl&lt;ScheduleRealInf @@ -158,7 +156,7 @@ public class ScheduleRealInfoServiceImpl extends BaseServiceImpl&lt;ScheduleRealInf
158 String lineCode = first.getXlBm(); 156 String lineCode = first.getXlBm();
159 String upDown = first.getXlDir(); 157 String upDown = first.getXlDir();
160 158
161 - List<ScheduleRealInfo> schList = ScheduleBuffer.schedulListMap.get(lineCode), 159 + List<ScheduleRealInfo> schList = ScheduleBuffer.realSchedulListMap.get(lineCode),
162 dirList = new ArrayList<>(); 160 dirList = new ArrayList<>();
163 // 筛选走向 161 // 筛选走向
164 for (ScheduleRealInfo s : schList) { 162 for (ScheduleRealInfo s : schList) {
@@ -276,8 +274,10 @@ public class ScheduleRealInfoServiceImpl extends BaseServiceImpl&lt;ScheduleRealInf @@ -276,8 +274,10 @@ public class ScheduleRealInfoServiceImpl extends BaseServiceImpl&lt;ScheduleRealInf
276 @Override 274 @Override
277 public Map<String, Object> save(ScheduleRealInfo t) { 275 public Map<String, Object> save(ScheduleRealInfo t) {
278 SysUser user = SecurityUtils.getCurrentUser(); 276 SysUser user = SecurityUtils.getCurrentUser();
279 -  
280 - t.setScheduleDate(new Date()); 277 + Date d = new Date();
  278 +
  279 + t.setScheduleDate(d);
  280 + t.setRealExecDate(sdfMonth.format(d));
281 t.setCreateBy(user); 281 t.setCreateBy(user);
282 t.syncTime(); 282 t.syncTime();
283 t.setSflj(true); 283 t.setSflj(true);
@@ -411,12 +411,39 @@ public class ScheduleRealInfoServiceImpl extends BaseServiceImpl&lt;ScheduleRealInf @@ -411,12 +411,39 @@ public class ScheduleRealInfoServiceImpl extends BaseServiceImpl&lt;ScheduleRealInf
411 ReportUtils ee = new ReportUtils(); 411 ReportUtils ee = new ReportUtils();
412 List<Iterator<?>> list = new ArrayList<Iterator<?>>(); 412 List<Iterator<?>> list = new ArrayList<Iterator<?>>();
413 List<ScheduleRealInfo> scheduleRealInfos = scheduleRealInfoRepository.exportWaybill(jName, clZbh, lpName); 413 List<ScheduleRealInfo> scheduleRealInfos = scheduleRealInfoRepository.exportWaybill(jName, clZbh, lpName);
414 - ScheduleRealInfo scheduleRealInfo = scheduleRealInfoRepository.findOne(scheduleRealInfos.get(0).getId()); 414 + ScheduleRealInfo scheduleReal = scheduleRealInfoRepository.findOne(scheduleRealInfos.get(0).getId());
  415 +
  416 + DecimalFormat format = new DecimalFormat("0.00");
  417 + int cjbc = scheduleRealInfoRepository.findCjbc(jName, clZbh, lpName);
  418 + int ljbc = scheduleRealInfoRepository.findLjbc(jName, clZbh, lpName);
  419 + int jhbc = 0;
  420 + double jhlc = 0;
  421 + float realMileage = 0l,addMileage = 0l,remMileage = 0l;
  422 + Map<String,Object> map = new HashMap<String, Object>();
  423 + for(ScheduleRealInfo scheduleRealInfo : scheduleRealInfos){
  424 + if(scheduleRealInfo != null){
  425 + jhlc += scheduleRealInfo.getJhlc()==null?0:scheduleRealInfo.getJhlc();
  426 + realMileage += scheduleRealInfo.getRealMileage()==null?0:scheduleRealInfo.getRealMileage();
  427 + addMileage += scheduleRealInfo.getAddMileage()==null?0:scheduleRealInfo.getAddMileage();
  428 + remMileage += scheduleRealInfo.getRemMileage()==null?0:scheduleRealInfo.getRemMileage();
  429 + jhbc++;
  430 + }
  431 + }
  432 + map.put("jhlc", format.format(jhlc));
  433 + map.put("remMileage", format.format(remMileage));
  434 + map.put("addMileage", format.format(addMileage));
  435 + map.put("yygl", format.format(realMileage-addMileage));
  436 + map.put("ksgl", format.format(realMileage-addMileage));
  437 + map.put("realMileage", format.format(realMileage));
  438 + map.put("jhbc", jhbc);
  439 + map.put("cjbc", cjbc);
  440 + map.put("ljbc", ljbc);
  441 + map.put("sjbc", jhbc-cjbc+ljbc);
415 442
416 String path = this.getClass().getResource("/").getPath()+"static\\pages\\forms\\"; 443 String path = this.getClass().getResource("/").getPath()+"static\\pages\\forms\\";
417 444
418 list.add(scheduleRealInfos.iterator()); 445 list.add(scheduleRealInfos.iterator());
419 - ee.excelReplace(list, new Object[] { scheduleRealInfo }, path+"mould\\waybill.xls", 446 + ee.excelReplace(list, new Object[] { scheduleReal,map }, path+"mould\\waybill.xls",
420 path+"export\\" + jName + ".xls"); 447 path+"export\\" + jName + ".xls");
421 return scheduleRealInfos; 448 return scheduleRealInfos;
422 } 449 }
@@ -463,20 +490,33 @@ public class ScheduleRealInfoServiceImpl extends BaseServiceImpl&lt;ScheduleRealInf @@ -463,20 +490,33 @@ public class ScheduleRealInfoServiceImpl extends BaseServiceImpl&lt;ScheduleRealInf
463 @Override 490 @Override
464 public Map<String, Object> realOutAdjust(Long id, String fcsjActual, String remarks) { 491 public Map<String, Object> realOutAdjust(Long id, String fcsjActual, String remarks) {
465 Map<String, Object> rs = new HashMap<>(); 492 Map<String, Object> rs = new HashMap<>();
  493 + List<ScheduleRealInfo> ts = new ArrayList<>();
466 try { 494 try {
467 ScheduleRealInfo sch = ScheduleBuffer.findOne(id); 495 ScheduleRealInfo sch = ScheduleBuffer.findOne(id);
468 - String rq = sdfMonth.format(sch.getScheduleDate());  
469 496
470 - sch.setFcsjActualTime(sdfMinute.parse(rq + " " + fcsjActual).getTime());  
471 - sch.setFcsjActual(fcsjActual); 497 + Long t = sdfMinute.parse(sch.getRealExecDate() + " " + fcsjActual).getTime();
  498 + /*sch.setFcsjActualTime(sdfMinute.parse(sch.getRealExecDate() + " " + fcsjActual).getTime());
  499 + sch.setFcsjActual(fcsjActual);*/
  500 + if(null != sch.getSjfcModel())
  501 + sch.getSjfcModel().setPersonTime(t);
  502 +
  503 + sch.setFcsjActualAll(t);
472 sch.addRemarks(remarks); 504 sch.addRemarks(remarks);
473 - //改变状态 505 + sch.calcStatus();
  506 + /*//改变状态
474 if(sch.getZdsjActual() == null) 507 if(sch.getZdsjActual() == null)
475 - sch.setStatus(1); 508 + sch.setStatus(1);*/
476 509
477 ScheduleBuffer.persistentList.add(sch); 510 ScheduleBuffer.persistentList.add(sch);
  511 +
  512 + ts.add(sch);
  513 + //关联班次
  514 + if(sch.existDependent())
  515 + ts.add(sch.getTwins());
  516 +
478 rs.put("status", ResponseCode.SUCCESS); 517 rs.put("status", ResponseCode.SUCCESS);
479 - rs.put("t", sch); 518 + //rs.put("t", sch);
  519 + rs.put("ts", ts);
480 } catch (Exception e) { 520 } catch (Exception e) {
481 logger.error("", e); 521 logger.error("", e);
482 rs.put("status", ResponseCode.ERROR); 522 rs.put("status", ResponseCode.ERROR);
@@ -498,7 +538,6 @@ public class ScheduleRealInfoServiceImpl extends BaseServiceImpl&lt;ScheduleRealInf @@ -498,7 +538,6 @@ public class ScheduleRealInfoServiceImpl extends BaseServiceImpl&lt;ScheduleRealInf
498 rs.put("status", ResponseCode.SUCCESS); 538 rs.put("status", ResponseCode.SUCCESS);
499 rs.put("t", sch); 539 rs.put("t", sch);
500 540
501 - // 将班次状态还原,并由子线程去匹配到离站  
502 } 541 }
503 } catch (Exception e) { 542 } catch (Exception e) {
504 logger.error("", e); 543 logger.error("", e);
@@ -510,19 +549,26 @@ public class ScheduleRealInfoServiceImpl extends BaseServiceImpl&lt;ScheduleRealInf @@ -510,19 +549,26 @@ public class ScheduleRealInfoServiceImpl extends BaseServiceImpl&lt;ScheduleRealInf
510 @Override 549 @Override
511 public Map<String, Object> revokeRealOutgo(Long id) { 550 public Map<String, Object> revokeRealOutgo(Long id) {
512 Map<String, Object> rs = new HashMap<>(); 551 Map<String, Object> rs = new HashMap<>();
  552 + List<ScheduleRealInfo> ts = new ArrayList<>();
  553 +
513 try { 554 try {
514 ScheduleRealInfo sch = ScheduleBuffer.findOne(id); 555 ScheduleRealInfo sch = ScheduleBuffer.findOne(id);
515 if (sch.getFcsjActual() == null) { 556 if (sch.getFcsjActual() == null) {
516 rs.put("status", ResponseCode.ERROR); 557 rs.put("status", ResponseCode.ERROR);
517 rs.put("msg", "无实发时间,无法撤销!"); 558 rs.put("msg", "无实发时间,无法撤销!");
518 } else { 559 } else {
519 - sch.setStatus(0);  
520 - sch.setFcsjActual(null);  
521 - sch.setFcsjActualTime(null); 560 + sch.revokeRealOutgo();
522 rs.put("status", ResponseCode.SUCCESS); 561 rs.put("status", ResponseCode.SUCCESS);
523 - rs.put("t", sch); 562 +
  563 + ts.add(sch);
  564 + if(sch.existDependent()){
  565 + //关联班次也撤销
  566 + sch.getTwins().revokeRealOutgo();
  567 + ts.add(sch.getTwins());
  568 + }
  569 +
  570 + rs.put("ts", ts);
524 571
525 - // 将班次状态还原,并由子线程去匹配到离站  
526 } 572 }
527 } catch (Exception e) { 573 } catch (Exception e) {
528 logger.error("", e); 574 logger.error("", e);
@@ -579,6 +625,7 @@ public class ScheduleRealInfoServiceImpl extends BaseServiceImpl&lt;ScheduleRealInf @@ -579,6 +625,7 @@ public class ScheduleRealInfoServiceImpl extends BaseServiceImpl&lt;ScheduleRealInf
579 @Override 625 @Override
580 public Map<String, Object> schInfoFineTune(Map<String, String> map) { 626 public Map<String, Object> schInfoFineTune(Map<String, String> map) {
581 Map<String, Object> rs = new HashMap<>(); 627 Map<String, Object> rs = new HashMap<>();
  628 + List<ScheduleRealInfo> ts = new ArrayList<>();
582 try { 629 try {
583 Long id = Long.parseLong(map.get("id")); 630 Long id = Long.parseLong(map.get("id"));
584 //班次类型 631 //班次类型
@@ -614,37 +661,64 @@ public class ScheduleRealInfoServiceImpl extends BaseServiceImpl&lt;ScheduleRealInf @@ -614,37 +661,64 @@ public class ScheduleRealInfoServiceImpl extends BaseServiceImpl&lt;ScheduleRealInf
614 sch.setBcType(bcType); 661 sch.setBcType(bcType);
615 sch.setClZbh(clZbh); 662 sch.setClZbh(clZbh);
616 sch.setFcsjAll(fcsj); 663 sch.setFcsjAll(fcsj);
  664 +
617 if(StringUtils.isNotBlank(fcsjActual)){ 665 if(StringUtils.isNotBlank(fcsjActual)){
618 - //调整实发  
619 - sch.setFcsjActualAll(fcsjActual);  
620 - sch.setStatus(1); 666 +
  667 + if(!fcsjActual.equals(sch.getFcsjActual())){
  668 + //调整实发
  669 + sch.setFcsjActualAll(fcsjActual);
  670 + if(null != sch.getSjfcModel())
  671 + sch.getSjfcModel().setPersonTime(sch.getFcsjActualTime());
  672 + }
621 } 673 }
622 else{ 674 else{
623 - sch.setFcsjActual(null); 675 + /*sch.setFcsjActual(null);
624 sch.setFcsjActualTime(null); 676 sch.setFcsjActualTime(null);
  677 + if(null != sch.getSjfcModel())
  678 + sch.getSjfcModel().resetNull();*/
  679 + //撤销实发
  680 + revokeRealOutgo(sch.getId());
625 } 681 }
626 682
  683 + //实达时间
627 if(StringUtils.isNotBlank(zdsjActual)){ 684 if(StringUtils.isNotBlank(zdsjActual)){
628 - //调整实达  
629 - sch.setZdsjActualAll(zdsjActual);  
630 - sch.setStatus(2);  
631 - //下一班次起点到达  
632 - ScheduleRealInfo next = ScheduleBuffer.getNext(sch);  
633 - next.setQdzArrDateSJ(zdsjActual);  
634 - rs.put("nextSch", next); 685 + if(!zdsjActual.equals(sch.getZdsjActual())){
  686 + //调整实达
  687 + sch.setZdsjActualAll(zdsjActual);
  688 + //下一班次起点到达时间
  689 + ScheduleRealInfo next = ScheduleBuffer.getNext(sch);
  690 + next.setQdzArrDateSJ(zdsjActual);
  691 + ts.add(next);
  692 + }
635 } 693 }
636 - else{  
637 - sch.setZdsjActual(null); 694 + else {
  695 + //清除实达时间
  696 + sch.clearZdsjActual();
  697 + /*sch.setZdsjActual(null);
638 sch.setZdsjActualTime(null); 698 sch.setZdsjActualTime(null);
  699 + if(null != sch.getSjddModel())
  700 + sch.getSjddModel().resetNull();*/
  701 +
  702 + //清除下一班次起点到达时间
  703 + ScheduleRealInfo next = ScheduleBuffer.getNext(sch);
  704 + next.setQdzArrDateSJ(null);
  705 + ts.add(next);
639 } 706 }
640 707
641 sch.setRemarks(remarks); 708 sch.setRemarks(remarks);
642 } 709 }
643 710
  711 + //班次状态
  712 + sch.calcStatus();
644 ScheduleBuffer.persistentList.add(sch); 713 ScheduleBuffer.persistentList.add(sch);
  714 + //页面需要更新的班次信息
  715 + ts.add(sch);
  716 + if(sch.existDependent())
  717 + ts.add(sch.getTwins());
645 718
646 rs.put("status", ResponseCode.SUCCESS); 719 rs.put("status", ResponseCode.SUCCESS);
647 - rs.put("t", sch); 720 + rs.put("ts", ts);
  721 + //rs.put("t", sch);
648 } catch (Exception e) { 722 } catch (Exception e) {
649 logger.error("", e); 723 logger.error("", e);
650 rs.put("status", ResponseCode.ERROR); 724 rs.put("status", ResponseCode.ERROR);
src/main/java/com/bsth/util/BatchSaveUtils.java
@@ -8,6 +8,10 @@ import java.sql.ResultSet; @@ -8,6 +8,10 @@ import java.sql.ResultSet;
8 import java.util.ArrayList; 8 import java.util.ArrayList;
9 import java.util.List; 9 import java.util.List;
10 10
  11 +import javax.persistence.ManyToMany;
  12 +import javax.persistence.ManyToOne;
  13 +import javax.persistence.OneToMany;
  14 +import javax.persistence.OneToOne;
11 import javax.persistence.Table; 15 import javax.persistence.Table;
12 import javax.persistence.Transient; 16 import javax.persistence.Transient;
13 17
@@ -138,6 +142,12 @@ public class BatchSaveUtils&lt;T&gt; { @@ -138,6 +142,12 @@ public class BatchSaveUtils&lt;T&gt; {
138 //忽略 Transient 字段 142 //忽略 Transient 字段
139 if(field.getAnnotation(Transient.class) != null) 143 if(field.getAnnotation(Transient.class) != null)
140 continue; 144 continue;
  145 + //忽略关联
  146 + if(field.getAnnotation(OneToMany.class) != null
  147 + || field.getAnnotation(OneToOne.class) != null
  148 + || field.getAnnotation(ManyToOne.class) != null
  149 + || field.getAnnotation(ManyToMany.class) != null)
  150 + continue;
141 fs.add(field); 151 fs.add(field);
142 } 152 }
143 return fs; 153 return fs;
src/main/java/com/bsth/util/DateUtils.java
@@ -32,6 +32,16 @@ public class DateUtils { @@ -32,6 +32,16 @@ public class DateUtils {
32 return (int) (cal.getTimeInMillis() / 1000); 32 return (int) (cal.getTimeInMillis() / 1000);
33 } 33 }
34 34
  35 + // 获得当天24点时间 毫秒
  36 + public static Long getTimesnight2() {
  37 + Calendar cal = Calendar.getInstance();
  38 + cal.set(Calendar.HOUR_OF_DAY, 24);
  39 + cal.set(Calendar.SECOND, 0);
  40 + cal.set(Calendar.MINUTE, 0);
  41 + cal.set(Calendar.MILLISECOND, 0);
  42 + return cal.getTimeInMillis();
  43 + }
  44 +
35 public static Long getTimesnight(Calendar cal) { 45 public static Long getTimesnight(Calendar cal) {
36 cal.set(Calendar.HOUR_OF_DAY, 24); 46 cal.set(Calendar.HOUR_OF_DAY, 24);
37 cal.set(Calendar.SECOND, 0); 47 cal.set(Calendar.SECOND, 0);
src/main/java/com/bsth/util/ReportUtils.java
@@ -4,8 +4,12 @@ import java.io.File; @@ -4,8 +4,12 @@ import java.io.File;
4 import java.io.FileInputStream; 4 import java.io.FileInputStream;
5 import java.io.FileOutputStream; 5 import java.io.FileOutputStream;
6 import java.util.ArrayList; 6 import java.util.ArrayList;
  7 +import java.util.HashMap;
7 import java.util.Iterator; 8 import java.util.Iterator;
8 import java.util.List; 9 import java.util.List;
  10 +import java.util.Map;
  11 +import java.util.regex.Matcher;
  12 +import java.util.regex.Pattern;
9 13
10 import org.apache.poi.hssf.usermodel.HSSFCell; 14 import org.apache.poi.hssf.usermodel.HSSFCell;
11 import org.apache.poi.hssf.usermodel.HSSFCellStyle; 15 import org.apache.poi.hssf.usermodel.HSSFCellStyle;
@@ -65,8 +69,8 @@ public class ReportUtils { @@ -65,8 +69,8 @@ public class ReportUtils {
65 continue; 69 continue;
66 } 70 }
67 // 取得每列的内容,如果列内容是$key$格式,则替换内容 71 // 取得每列的内容,如果列内容是$key$格式,则替换内容
68 - key = cell.getStringCellValue();  
69 - if (key.indexOf("$") != -1 || key.indexOf("#list#") != -1) { 72 + key = getCellValue(cell);
  73 + if (key != null && (key.indexOf("$") != -1 || key.indexOf("#list#") != -1)) {
70 // * 列中内容有#list#,则表示该行为模板行,需要以该行为模板 74 // * 列中内容有#list#,则表示该行为模板行,需要以该行为模板
71 // * 例如:模板行格式 #list#0_0 $Car.id$ 75 // * 例如:模板行格式 #list#0_0 $Car.id$
72 // * 第一个0表示需要在list中取iterator的索引值 76 // * 第一个0表示需要在list中取iterator的索引值
@@ -86,8 +90,8 @@ public class ReportUtils { @@ -86,8 +90,8 @@ public class ReportUtils {
86 i += rowCount; 90 i += rowCount;
87 break; 91 break;
88 } else { 92 } else {
89 - // 直接填充数据的列,从对象数组中取得值  
90 - getValueAndSetCellValue(cell, key, tArray); 93 + // 直接填充数据的列,从对象数组中取得值,这里的数组不传值
  94 + getValueAndSetCellValue(cell, key, tArray, new String[]{""});
91 } 95 }
92 } 96 }
93 97
@@ -104,6 +108,47 @@ public class ReportUtils { @@ -104,6 +108,47 @@ public class ReportUtils {
104 } 108 }
105 } 109 }
106 110
  111 + public String getCellValue(HSSFCell cell) {
  112 + int cellType = 0;
  113 + String result = "";
  114 + double d;
  115 + if(cell != null) {
  116 + // 获取列数据类型
  117 + cellType = cell.getCellType();
  118 + // 不同列数据类型,取值方法不同
  119 + switch(cellType) {
  120 + // String
  121 + case HSSFCell.CELL_TYPE_STRING:
  122 + result = cell.getStringCellValue().toString();
  123 + break;
  124 + // numeric类型,excel中,日期格式会转成数字格式存储
  125 + case HSSFCell.CELL_TYPE_NUMERIC:
  126 + result = cell.getNumericCellValue()+"";
  127 + break;
  128 + // 公式类型
  129 + case HSSFCell.CELL_TYPE_FORMULA:
  130 + result = cell.getCellFormula() + "";
  131 + break;
  132 + // boolean类型
  133 + case HSSFCell.CELL_TYPE_BOOLEAN:
  134 + result = cell.getBooleanCellValue() + "";
  135 + break;
  136 + // 空格
  137 + case HSSFCell.CELL_TYPE_BLANK:
  138 + result = null;
  139 + break;
  140 + // 错误值
  141 + case HSSFCell.CELL_TYPE_ERROR:
  142 + result = null;
  143 + break;
  144 + default :
  145 + System.out.println("其它");
  146 + break;
  147 + }
  148 + }
  149 + return result;
  150 + }
  151 +
107 /** 152 /**
108 * 根据iterator,以及模板中的标识,填充模板 153 * 根据iterator,以及模板中的标识,填充模板
109 * 154 *
@@ -130,6 +175,7 @@ public class ReportUtils { @@ -130,6 +175,7 @@ public class ReportUtils {
130 HSSFRow newRow = null; 175 HSSFRow newRow = null;
131 int tmpCellNum = 0; 176 int tmpCellNum = 0;
132 int k = 0; 177 int k = 0;
  178 + int listIndex = 0;
133 // 取得模板行 179 // 取得模板行
134 HSSFRow orgRow = sheet.getRow(index); 180 HSSFRow orgRow = sheet.getRow(index);
135 try { 181 try {
@@ -152,7 +198,7 @@ public class ReportUtils { @@ -152,7 +198,7 @@ public class ReportUtils {
152 tmpCellNum = newRow.getLastCellNum(); 198 tmpCellNum = newRow.getLastCellNum();
153 for (int l = 0; l < tmpCellNum; l++) { 199 for (int l = 0; l < tmpCellNum; l++) {
154 cell = newRow.getCell(l); 200 cell = newRow.getCell(l);
155 - key = cell.getStringCellValue(); 201 + key = getCellValue(cell);
156 /** 202 /**
157 * 如果单无格内容为#list#,表示该行是模板行 #list#0_0 203 * 如果单无格内容为#list#,表示该行是模板行 #list#0_0
158 * 第一个0表示需要在list中取iterator的索引值 204 * 第一个0表示需要在list中取iterator的索引值
@@ -168,8 +214,10 @@ public class ReportUtils { @@ -168,8 +214,10 @@ public class ReportUtils {
168 if (key.trim().indexOf(" ") != -1) { 214 if (key.trim().indexOf(" ") != -1) {
169 key = key.split(" ")[1]; 215 key = key.split(" ")[1];
170 } 216 }
171 - getValueAndSetCellValue(cell, key, obj); 217 + getValueAndSetCellValue(cell, key, obj,new String[]{listIndex+""});
172 } 218 }
  219 + // list的数量
  220 + listIndex ++;
173 } 221 }
174 } catch (Exception e) { 222 } catch (Exception e) {
175 e.printStackTrace(); 223 e.printStackTrace();
@@ -180,42 +228,58 @@ public class ReportUtils { @@ -180,42 +228,58 @@ public class ReportUtils {
180 /** 228 /**
181 * 取到相应的值并填入相应的列中 229 * 取到相应的值并填入相应的列中
182 * 230 *
183 - * @param cell  
184 - * 列  
185 - * @param key  
186 - * 列内容  
187 - * @param obj  
188 - * 数据源对象 231 + * @param cell 列
  232 + * @param key 列内容
  233 + * @param obj 数据源对象
  234 + * @param args 其他参数 数组
  235 + * 数组内容:
  236 + * 0位:在list中的第几条数据
189 */ 237 */
190 - private void getValueAndSetCellValue(HSSFCell cell, String key, Object obj) { 238 + private void getValueAndSetCellValue(HSSFCell cell, String key, Object obj, String[] args) {
191 try { 239 try {
192 // 保有存单元格的内容 240 // 保有存单元格的内容
193 String cellValue = key = key.replace("\\n", ""); 241 String cellValue = key = key.replace("\\n", "");
194 String tmpKey; 242 String tmpKey;
195 - // 循环截取两个$中间的内容,反射出值  
196 - while (key.indexOf("$") != -1) {  
197 - key = key.substring(key.indexOf("$") + 1);  
198 - // 取两个$中间的内容  
199 - tmpKey = key.substring(0, key.indexOf("$"));  
200 - key = key.substring(key.indexOf("$") + 1);  
201 - // 如果内容是如下格式Cars.id,则从obj中值得相应的对象的值  
202 - if (tmpKey.indexOf(".") != -1) {  
203 - String className = tmpKey.substring(0, tmpKey.indexOf("."));  
204 - // 取得类的全限定名  
205 - String classWholeName = packaegName + className;  
206 - String fieldName = tmpKey.substring(tmpKey.indexOf(".") + 1);  
207 - // 如果obj是数组,循环判断哪个对象是对应的  
208 - if (obj instanceof Object[]) {  
209 - Object[] objs = (Object[]) obj;  
210 - for (int k = 0; k < objs.length; k++) {  
211 - if (objs[k].getClass().getName().equals(classWholeName)) {  
212 - cellValue = cellValue.replace("$" + tmpKey  
213 - + "$", getKeyValue(objs[k], fieldName)  
214 - + ""); 243 + // 判断单元格内容是否是公式
  244 + if(cell.getCellType() == HSSFCell.CELL_TYPE_FORMULA){
  245 + Pattern p=Pattern.compile("(\\d+)"); //
  246 + Matcher m=p.matcher(key);
  247 + if(m.find()){
  248 + cellValue = key.replace(m.group(1),
  249 + Integer.valueOf(m.group(1))+Integer.valueOf(args[0])+"");
  250 + cell.setCellFormula(cellValue);
  251 + return;
  252 + }
  253 + }else{//其他格式
  254 +
  255 + // 循环截取两个$中间的内容,反射出值
  256 + while (key.indexOf("$") != -1) {
  257 + key = key.substring(key.indexOf("$") + 1);
  258 + // 取两个$中间的内容
  259 + tmpKey = key.substring(0, key.indexOf("$"));
  260 + key = key.substring(key.indexOf("$") + 1);
  261 + // 如果内容是如下格式Cars.id,则从obj中值得相应的对象的值
  262 + if (tmpKey.indexOf(".") != -1) {
  263 + String className = tmpKey.substring(0, tmpKey.indexOf("."));
  264 + // 取得类的全限定名
  265 + String classWholeName = packaegName + className;
  266 + String fieldName = tmpKey.substring(tmpKey.indexOf(".") + 1);
  267 + // 如果obj是数组,循环判断哪个对象是对应的
  268 + if (obj instanceof Object[]) {
  269 + Object[] objs = (Object[]) obj;
  270 + for (int k = 0; k < objs.length; k++) {
  271 + if (objs[k].getClass().getName().equals(classWholeName)) {
  272 + cellValue = cellValue.replace("$" + tmpKey
  273 + + "$", getKeyValue(objs[k], fieldName)
  274 + + "");
  275 + } else if(objs[k].getClass().getName().equals("java.util.HashMap")){
  276 + Map<String,Object> map = (HashMap<String,Object>)objs[k];
  277 + cellValue = cellValue.replace("$" + tmpKey + "$",map.get(fieldName)+"");
  278 + }
215 } 279 }
  280 + } else if (obj.getClass().getName().equals(classWholeName)) {
  281 + cellValue = cellValue.replace("$" + tmpKey + "$",getKeyValue(obj, fieldName) + "");
216 } 282 }
217 - } else if (obj.getClass().getName().equals(classWholeName)) {  
218 - cellValue = cellValue.replace("$" + tmpKey + "$",getKeyValue(obj, fieldName) + "");  
219 } 283 }
220 } 284 }
221 } 285 }
@@ -266,16 +330,16 @@ public class ReportUtils { @@ -266,16 +330,16 @@ public class ReportUtils {
266 srr.setXlName("abc11"); 330 srr.setXlName("abc11");
267 331
268 ScheduleRealInfo sr = new ScheduleRealInfo(); 332 ScheduleRealInfo sr = new ScheduleRealInfo();
269 - sr.setId((long) 22);  
270 - sr.setXlName("abc22"); 333 + sr.setZdsj("06:10");
  334 + sr.setZdsjActual("06:25");
271 dataList.add(sr); 335 dataList.add(sr);
272 sr = new ScheduleRealInfo(); 336 sr = new ScheduleRealInfo();
273 - sr.setId((long) 33);  
274 - sr.setXlName("abc33"); 337 + sr.setZdsj("06:20");
  338 + sr.setZdsjActual("");
275 dataList.add(sr); 339 dataList.add(sr);
276 list.add(dataList.iterator()); 340 list.add(dataList.iterator());
277 341
278 - ee.excelReplace(list, new Object[] { srr }, "D:\\55.xls", 342 + ee.excelReplace(list, new Object[] { srr }, "D:\\waybill.xls",
279 "D:\\22.xls"); 343 "D:\\22.xls");
280 System.out.println("ok"); 344 System.out.println("ok");
281 } catch (Exception e) { 345 } catch (Exception e) {
src/main/java/com/bsth/vehicle/directive/buffer/DirectiveBuffer.java
@@ -14,6 +14,7 @@ import org.springframework.stereotype.Component; @@ -14,6 +14,7 @@ import org.springframework.stereotype.Component;
14 14
15 import com.alibaba.fastjson.JSON; 15 import com.alibaba.fastjson.JSON;
16 import com.alibaba.fastjson.JSONObject; 16 import com.alibaba.fastjson.JSONObject;
  17 +import com.bsth.entity.realcontrol.ScheduleRealInfo;
17 import com.bsth.service.realcontrol.buffer.ScheduleBuffer; 18 import com.bsth.service.realcontrol.buffer.ScheduleBuffer;
18 import com.bsth.vehicle.common.CommonMapped; 19 import com.bsth.vehicle.common.CommonMapped;
19 import com.bsth.vehicle.directive.entity.Directive60; 20 import com.bsth.vehicle.directive.entity.Directive60;
@@ -25,6 +26,7 @@ import com.bsth.vehicle.directive.entity.LineChange; @@ -25,6 +26,7 @@ import com.bsth.vehicle.directive.entity.LineChange;
25 import com.bsth.vehicle.directive.repository.Directive60Repository; 26 import com.bsth.vehicle.directive.repository.Directive60Repository;
26 import com.bsth.vehicle.directive.repository.Directive80Repository; 27 import com.bsth.vehicle.directive.repository.Directive80Repository;
27 import com.bsth.vehicle.directive.repository.LineChangeRepository; 28 import com.bsth.vehicle.directive.repository.LineChangeRepository;
  29 +import com.bsth.vehicle.directive.service.DirectiveService;
28 import com.bsth.vehicle.directive.util.HttpUtils; 30 import com.bsth.vehicle.directive.util.HttpUtils;
29 import com.bsth.websocket.handler.RealControlSocketHandler; 31 import com.bsth.websocket.handler.RealControlSocketHandler;
30 import com.google.common.collect.ArrayListMultimap; 32 import com.google.common.collect.ArrayListMultimap;
@@ -49,6 +51,9 @@ public class DirectiveBuffer { @@ -49,6 +51,9 @@ public class DirectiveBuffer {
49 @Autowired 51 @Autowired
50 LineChangeRepository lineChangeRepository; 52 LineChangeRepository lineChangeRepository;
51 53
  54 + @Autowired
  55 + DirectiveService directiveService;
  56 +
52 57
53 /** 58 /**
54 * 等待入库的调度指令 59 * 等待入库的调度指令
@@ -123,7 +128,11 @@ public class DirectiveBuffer { @@ -123,7 +128,11 @@ public class DirectiveBuffer {
123 128
124 if(directive.isDispatch()){ 129 if(directive.isDispatch()){
125 //更新班次状态 130 //更新班次状态
126 - directive.getSch().setDirectiveState(reply.getStatus() * 100); 131 + ScheduleRealInfo sch = directive.getSch();
  132 + sch.setDirectiveState(reply.getStatus() * 100);
  133 + ScheduleBuffer.persistentList.add(sch);
  134 + //通知页面
  135 + directiveService.sendDirectiveToPage(sch);
127 } 136 }
128 transientList.add(directive); 137 transientList.add(directive);
129 } 138 }
src/main/java/com/bsth/vehicle/directive/entity/Directive60.java
@@ -59,12 +59,12 @@ public class Directive60 { @@ -59,12 +59,12 @@ public class Directive60 {
59 /** 59 /**
60 * 46上行 60 * 46上行
61 */ 61 */
62 - private Short reply46; 62 + private Short reply46 = -1;
63 63
64 /** 64 /**
65 * 47上行 65 * 47上行
66 */ 66 */
67 - private Short reply47; 67 + private Short reply47 = -1;
68 68
69 /** 69 /**
70 * 是否是调度指令 70 * 是否是调度指令
src/main/java/com/bsth/vehicle/directive/service/DirectiveService.java
@@ -59,4 +59,12 @@ public interface DirectiveService extends BaseService&lt;Directive60, Integer&gt;{ @@ -59,4 +59,12 @@ public interface DirectiveService extends BaseService&lt;Directive60, Integer&gt;{
59 * @throws 59 * @throws
60 */ 60 */
61 int upDownChange(String nbbm, Integer upDown); 61 int upDownChange(String nbbm, Integer upDown);
  62 +
  63 + /**
  64 + *
  65 + * @Title: sendDirectiveState
  66 + * @Description: TODO(向页面推送班次指令状态)
  67 + * @throws
  68 + */
  69 + void sendDirectiveToPage(ScheduleRealInfo sch);
62 } 70 }
src/main/java/com/bsth/vehicle/directive/service/DirectiveServiceImpl.java
@@ -85,7 +85,7 @@ public class DirectiveServiceImpl extends BaseServiceImpl&lt;Directive60, Integer&gt; @@ -85,7 +85,7 @@ public class DirectiveServiceImpl extends BaseServiceImpl&lt;Directive60, Integer&gt;
85 try { 85 try {
86 //如果发车时间距当前时间较远,则不发送 86 //如果发车时间距当前时间较远,则不发送
87 if(Math.abs(sch.getFcsjT() - System.currentTimeMillis()) > schDiff){ 87 if(Math.abs(sch.getFcsjT() - System.currentTimeMillis()) > schDiff){
88 - return 0; 88 + return -2;
89 } 89 }
90 90
91 String text = "已完成" + finish + "个班次,下一发车时间" + sdfHHmm.format(new Date(sch.getFcsjT())) 91 String text = "已完成" + finish + "个班次,下一发车时间" + sdfHHmm.format(new Date(sch.getFcsjT()))
@@ -111,7 +111,7 @@ public class DirectiveServiceImpl extends BaseServiceImpl&lt;Directive60, Integer&gt; @@ -111,7 +111,7 @@ public class DirectiveServiceImpl extends BaseServiceImpl&lt;Directive60, Integer&gt;
111 directive.setSch(sch); 111 directive.setSch(sch);
112 DirectiveBuffer.put(directive); 112 DirectiveBuffer.put(directive);
113 //通知页面,消息已发出 113 //通知页面,消息已发出
114 - sendDirectiveState(sch); 114 + sendDirectiveToPage(sch);
115 }else{ 115 }else{
116 logger.error("send60Phrase error, code: " + code); 116 logger.error("send60Phrase error, code: " + code);
117 } 117 }
@@ -124,7 +124,8 @@ public class DirectiveServiceImpl extends BaseServiceImpl&lt;Directive60, Integer&gt; @@ -124,7 +124,8 @@ public class DirectiveServiceImpl extends BaseServiceImpl&lt;Directive60, Integer&gt;
124 * @Description: TODO(向页面推送班次指令状态) 124 * @Description: TODO(向页面推送班次指令状态)
125 * @throws 125 * @throws
126 */ 126 */
127 - public void sendDirectiveState(ScheduleRealInfo sch){ 127 + @Override
  128 + public void sendDirectiveToPage(ScheduleRealInfo sch){
128 JSONObject json = new JSONObject(); 129 JSONObject json = new JSONObject();
129 json.put("fn", "directive"); 130 json.put("fn", "directive");
130 json.put("t", sch); 131 json.put("t", sch);
src/main/java/com/bsth/vehicle/directive/thread/FirstScheduleIssuedThread.java
@@ -27,13 +27,13 @@ public class FirstScheduleIssuedThread extends Thread{ @@ -27,13 +27,13 @@ public class FirstScheduleIssuedThread extends Thread{
27 @Override 27 @Override
28 public void run() { 28 public void run() {
29 29
30 - Set<String> keys = ScheduleBuffer.vehSchListMap.keySet(); 30 + Set<String> keys = ScheduleBuffer.carSchListMap.keySet();
31 List<ScheduleRealInfo> list; 31 List<ScheduleRealInfo> list;
32 32
33 Long t = System.currentTimeMillis(); 33 Long t = System.currentTimeMillis();
34 ScheduleRealInfo sch; 34 ScheduleRealInfo sch;
35 for(String nbbm : keys){ 35 for(String nbbm : keys){
36 - list = ScheduleBuffer.vehSchListMap.get(nbbm); 36 + list = ScheduleBuffer.carSchListMap.get(nbbm);
37 37
38 if(list.size() == 0) 38 if(list.size() == 0)
39 continue; 39 continue;
src/main/java/com/bsth/vehicle/gpsdata/GpsArrivalStationThread_old.java
@@ -64,7 +64,7 @@ public class GpsArrivalStationThread_old extends Thread{ @@ -64,7 +64,7 @@ public class GpsArrivalStationThread_old extends Thread{
64 System.out.println("开始..."); 64 System.out.println("开始...");
65 List<ScheduleRealInfo> schList; 65 List<ScheduleRealInfo> schList;
66 for(String key : keySet){ 66 for(String key : keySet){
67 - schList = extractSched(ScheduleBuffer.vehSchListMap.get(key)); 67 + schList = extractSched(ScheduleBuffer.carSchListMap.get(key));
68 if(null != schList) 68 if(null != schList)
69 match(GpsArrivalDataBuffer.allMap.get(key), schList); 69 match(GpsArrivalDataBuffer.allMap.get(key), schList);
70 } 70 }
src/main/java/com/bsth/vehicle/gpsdata/GpsArrivalStationThread.java renamed to src/main/java/com/bsth/vehicle/gpsdata/GpsArrivalThread.java
@@ -7,7 +7,6 @@ import java.text.ParseException; @@ -7,7 +7,6 @@ import java.text.ParseException;
7 import java.text.SimpleDateFormat; 7 import java.text.SimpleDateFormat;
8 import java.util.ArrayList; 8 import java.util.ArrayList;
9 import java.util.Calendar; 9 import java.util.Calendar;
10 -import java.util.Date;  
11 import java.util.HashSet; 10 import java.util.HashSet;
12 import java.util.List; 11 import java.util.List;
13 import java.util.Set; 12 import java.util.Set;
@@ -17,13 +16,11 @@ import org.slf4j.LoggerFactory; @@ -17,13 +16,11 @@ import org.slf4j.LoggerFactory;
17 import org.springframework.beans.factory.annotation.Autowired; 16 import org.springframework.beans.factory.annotation.Autowired;
18 import org.springframework.stereotype.Component; 17 import org.springframework.stereotype.Component;
19 18
20 -import com.alibaba.fastjson.JSONObject;  
21 import com.bsth.entity.realcontrol.ScheduleRealInfo; 19 import com.bsth.entity.realcontrol.ScheduleRealInfo;
22 -import com.bsth.service.realcontrol.buffer.ScheduleBuffer;  
23 import com.bsth.util.DateUtils; 20 import com.bsth.util.DateUtils;
24 import com.bsth.util.db.DBUtils_MS; 21 import com.bsth.util.db.DBUtils_MS;
25 -import com.bsth.vehicle.common.CommonMapped;  
26 import com.bsth.vehicle.directive.service.DirectiveService; 22 import com.bsth.vehicle.directive.service.DirectiveService;
  23 +import com.bsth.vehicle.gpsdata.arrival.MatchService;
27 import com.bsth.vehicle.gpsdata.buffer.GpsArrivalDataBuffer; 24 import com.bsth.vehicle.gpsdata.buffer.GpsArrivalDataBuffer;
28 import com.bsth.vehicle.gpsdata.entity.ArrivalInfo; 25 import com.bsth.vehicle.gpsdata.entity.ArrivalInfo;
29 import com.bsth.websocket.handler.RealControlSocketHandler; 26 import com.bsth.websocket.handler.RealControlSocketHandler;
@@ -31,13 +28,13 @@ import com.bsth.websocket.handler.RealControlSocketHandler; @@ -31,13 +28,13 @@ import com.bsth.websocket.handler.RealControlSocketHandler;
31 /** 28 /**
32 * 29 *
33 * @ClassName: GpsArrivalStationThread 30 * @ClassName: GpsArrivalStationThread
34 - * @Description: TODO(GPS到离站) 31 + * @Description: TODO(定时从数据库加载到离站数据)
35 * @author PanZhao 32 * @author PanZhao
36 * @date 2016年6月27日 上午10:58:13 33 * @date 2016年6月27日 上午10:58:13
37 * 34 *
38 */ 35 */
39 @Component 36 @Component
40 -public class GpsArrivalStationThread extends Thread{ 37 +public class GpsArrivalThread extends Thread{
41 38
42 Logger logger = LoggerFactory.getLogger(this.getClass()); 39 Logger logger = LoggerFactory.getLogger(this.getClass());
43 SimpleDateFormat sdf = new SimpleDateFormat("HH:mm"); 40 SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");
@@ -60,8 +57,26 @@ public class GpsArrivalStationThread extends Thread{ @@ -60,8 +57,26 @@ public class GpsArrivalStationThread extends Thread{
60 } 57 }
61 //缓存 58 //缓存
62 GpsArrivalDataBuffer.putAll(list); 59 GpsArrivalDataBuffer.putAll(list);
  60 +
  61 + //有新到离站数据的线路
  62 + Set<String> newSet = new HashSet<>();
  63 + for(ArrivalInfo arr : list)
  64 + newSet.add(arr.getLineCode());
  65 +
  66 + //启动对应的匹配线程
  67 + for(String lineCode : newSet){
  68 + MatchService.addService(lineCode);
  69 + }
  70 +
  71 +
  72 + /*try {
  73 + Bootstrap bs = Bootstrap.instance();
  74 + bs.start();
  75 + } catch (Exception e) {
  76 + e.printStackTrace();
  77 + }*/
63 78
64 - //车辆 79 + /*//车辆
65 Set<String> set = new HashSet<>(); 80 Set<String> set = new HashSet<>();
66 for(ArrivalInfo arr : list) 81 for(ArrivalInfo arr : list)
67 set.add(CommonMapped.vehicDeviceBiMap.get(arr.getDeviceId())); 82 set.add(CommonMapped.vehicDeviceBiMap.get(arr.getDeviceId()));
@@ -109,10 +124,10 @@ public class GpsArrivalStationThread extends Thread{ @@ -109,10 +124,10 @@ public class GpsArrivalStationThread extends Thread{
109 }catch(Exception e){ 124 }catch(Exception e){
110 e.printStackTrace(); 125 e.printStackTrace();
111 } 126 }
112 - } 127 + }*/
113 } 128 }
114 129
115 - public ArrivalInfo[] match(List<ArrivalInfo> arrList, ScheduleRealInfo sch){ 130 +/* public ArrivalInfo[] match(List<ArrivalInfo> arrList, ScheduleRealInfo sch){
116 //进出分组 131 //进出分组
117 List<ArrivalInfo> in = new ArrayList<>(), out = new ArrayList<>(); 132 List<ArrivalInfo> in = new ArrayList<>(), out = new ArrayList<>();
118 for(ArrivalInfo arr : arrList){ 133 for(ArrivalInfo arr : arrList){
@@ -134,7 +149,7 @@ public class GpsArrivalStationThread extends Thread{ @@ -134,7 +149,7 @@ public class GpsArrivalStationThread extends Thread{
134 } 149 }
135 150
136 public ArrivalInfo matchOut(List<ArrivalInfo> arrList, ScheduleRealInfo sch){ 151 public ArrivalInfo matchOut(List<ArrivalInfo> arrList, ScheduleRealInfo sch){
137 - Long space = /*ScheduleBuffer.schSpaceMap.get(sch.getXlBm() + "_" + sch.getXlDir())*/diff; 152 + Long space = ScheduleBuffer.schSpaceMap.get(sch.getXlBm() + "_" + sch.getXlDir())diff;
138 for(ArrivalInfo arr : arrList){ 153 for(ArrivalInfo arr : arrList){
139 if(arr.getStopNo().equals(sch.getQdzCode()) 154 if(arr.getStopNo().equals(sch.getQdzCode())
140 && Math.abs((arr.getTs() - sch.getFcsjT())) < space){ 155 && Math.abs((arr.getTs() - sch.getFcsjT())) < space){
@@ -148,7 +163,7 @@ public class GpsArrivalStationThread extends Thread{ @@ -148,7 +163,7 @@ public class GpsArrivalStationThread extends Thread{
148 } 163 }
149 164
150 public ArrivalInfo matchIn(List<ArrivalInfo> arrList, ScheduleRealInfo sch){ 165 public ArrivalInfo matchIn(List<ArrivalInfo> arrList, ScheduleRealInfo sch){
151 - Long space = /*ScheduleBuffer.schSpaceMap.get(sch.getXlBm() + "_" + sch.getXlDir())*/diff; 166 + Long space = ScheduleBuffer.schSpaceMap.get(sch.getXlBm() + "_" + sch.getXlDir())diff;
152 for(ArrivalInfo arr : arrList){ 167 for(ArrivalInfo arr : arrList){
153 if(arr.getStopNo().equals(sch.getZdzCode()) 168 if(arr.getStopNo().equals(sch.getZdzCode())
154 && Math.abs((arr.getTs() - sch.getZdsjT())) < space){ 169 && Math.abs((arr.getTs() - sch.getZdsjT())) < space){
@@ -158,7 +173,7 @@ public class GpsArrivalStationThread extends Thread{ @@ -158,7 +173,7 @@ public class GpsArrivalStationThread extends Thread{
158 } 173 }
159 } 174 }
160 return null; 175 return null;
161 - } 176 + }*/
162 177
163 178
164 /** 179 /**
@@ -167,7 +182,7 @@ public class GpsArrivalStationThread extends Thread{ @@ -167,7 +182,7 @@ public class GpsArrivalStationThread extends Thread{
167 * @param @param schedule 班次 182 * @param @param schedule 班次
168 * @throws 183 * @throws
169 */ 184 */
170 - public void sendFcsj(ScheduleRealInfo schedule){ 185 +/* public void sendFcsj(ScheduleRealInfo schedule){
171 JSONObject json = new JSONObject(); 186 JSONObject json = new JSONObject();
172 json.put("fn", "faChe"); 187 json.put("fn", "faChe");
173 json.put("t", schedule); 188 json.put("t", schedule);
@@ -175,12 +190,12 @@ public class GpsArrivalStationThread extends Thread{ @@ -175,12 +190,12 @@ public class GpsArrivalStationThread extends Thread{
175 socketHandler.sendMessageToLine(Integer.parseInt(schedule.getXlBm()), json.toJSONString()); 190 socketHandler.sendMessageToLine(Integer.parseInt(schedule.getXlBm()), json.toJSONString());
176 } 191 }
177 192
178 - /** 193 + *//**
179 * @Title: sendFcsj 194 * @Title: sendFcsj
180 * @Description: TODO(推送到达终点时间) 195 * @Description: TODO(推送到达终点时间)
181 * @param @param schedule 班次 196 * @param @param schedule 班次
182 * @throws 197 * @throws
183 - */ 198 + *//*
184 public void sendZdsj(ScheduleRealInfo schedule,ScheduleRealInfo nextSch, int finish){ 199 public void sendZdsj(ScheduleRealInfo schedule,ScheduleRealInfo nextSch, int finish){
185 JSONObject json = new JSONObject(); 200 JSONObject json = new JSONObject();
186 json.put("fn", "zhongDian"); 201 json.put("fn", "zhongDian");
@@ -190,7 +205,7 @@ public class GpsArrivalStationThread extends Thread{ @@ -190,7 +205,7 @@ public class GpsArrivalStationThread extends Thread{
190 json.put("dataStr", sdf.format(new Date())); 205 json.put("dataStr", sdf.format(new Date()));
191 206
192 socketHandler.sendMessageToLine(Integer.parseInt(schedule.getXlBm()), json.toJSONString()); 207 socketHandler.sendMessageToLine(Integer.parseInt(schedule.getXlBm()), json.toJSONString());
193 - } 208 + }*/
194 209
195 /** 210 /**
196 * @throws ParseException 211 * @throws ParseException
@@ -210,7 +225,7 @@ public class GpsArrivalStationThread extends Thread{ @@ -210,7 +225,7 @@ public class GpsArrivalStationThread extends Thread{
210 GpsArrivalDataBuffer.markTime = DateUtils.getTimesmorning() * 1000L; 225 GpsArrivalDataBuffer.markTime = DateUtils.getTimesmorning() * 1000L;
211 } 226 }
212 227
213 - String sql = "select * from bsth_c_arrival_info where weeks_year=? and create_date > ? order by ts"; 228 + String sql = "select * from bsth_c_arrival_info where weeks_year=? and ts > ? order by ts";
214 229
215 List<ArrivalInfo> list = new ArrayList<>(); 230 List<ArrivalInfo> list = new ArrayList<>();
216 Connection conn = null; 231 Connection conn = null;
@@ -219,8 +234,8 @@ public class GpsArrivalStationThread extends Thread{ @@ -219,8 +234,8 @@ public class GpsArrivalStationThread extends Thread{
219 try { 234 try {
220 conn = DBUtils_MS.getConnection(); 235 conn = DBUtils_MS.getConnection();
221 ps = conn.prepareStatement(sql); 236 ps = conn.prepareStatement(sql);
222 - ps.setInt(1, weeks_year/*28*/);  
223 - ps.setLong(2, GpsArrivalDataBuffer.markTime/*1467853749000L*/); 237 + ps.setInt(1, weeks_year/*30*/);
  238 + ps.setLong(2, GpsArrivalDataBuffer.markTime/*1461361377000L*/);
224 239
225 Long t = System.currentTimeMillis(); 240 Long t = System.currentTimeMillis();
226 rs = ps.executeQuery(); 241 rs = ps.executeQuery();
@@ -230,6 +245,7 @@ public class GpsArrivalStationThread extends Thread{ @@ -230,6 +245,7 @@ public class GpsArrivalStationThread extends Thread{
230 , rs.getInt("up_down"), rs.getString("stop_no"), rs.getInt("in_out"), rs.getDate("create_date"), rs.getInt("weeks_year"))); 245 , rs.getInt("up_down"), rs.getString("stop_no"), rs.getInt("in_out"), rs.getDate("create_date"), rs.getInt("weeks_year")));
231 } 246 }
232 247
  248 + System.out.println("数量:" + list.size() + " ,markTime:" + GpsArrivalDataBuffer.markTime);
233 //重新打时间标记 249 //重新打时间标记
234 GpsArrivalDataBuffer.markTime = t; 250 GpsArrivalDataBuffer.markTime = t;
235 251
src/main/java/com/bsth/vehicle/gpsdata/arrival/MatchService.java 0 → 100644
  1 +package com.bsth.vehicle.gpsdata.arrival;
  2 +
  3 +import java.util.concurrent.ArrayBlockingQueue;
  4 +import java.util.concurrent.ThreadPoolExecutor;
  5 +import java.util.concurrent.TimeUnit;
  6 +
  7 +public class MatchService {
  8 +
  9 + static MatchService bs;
  10 + static ThreadPoolExecutor pool = new ThreadPoolExecutor(2, 20, 1, TimeUnit.SECONDS,
  11 + new ArrayBlockingQueue<Runnable>(3));
  12 +
  13 + /**
  14 + *
  15 + * @Title: addService
  16 + * @Description: TODO(添加一个任务)
  17 + * @throws
  18 + */
  19 + public static void addService(String lineCode) {
  20 + pool.execute(new ThreadPoolTask(lineCode));
  21 + }
  22 +}
src/main/java/com/bsth/vehicle/gpsdata/arrival/ThreadPoolTask.java 0 → 100644
  1 +package com.bsth.vehicle.gpsdata.arrival;
  2 +
  3 +import java.util.List;
  4 +import java.util.Set;
  5 +
  6 +import com.bsth.entity.realcontrol.ScheduleRealInfo;
  7 +import com.bsth.service.realcontrol.buffer.ScheduleBuffer;
  8 +import com.bsth.vehicle.gpsdata.arrival.match.ScheduleRealMatcher;
  9 +import com.bsth.vehicle.gpsdata.buffer.GpsArrivalDataBuffer;
  10 +import com.google.common.collect.ArrayListMultimap;
  11 +
  12 +public class ThreadPoolTask implements Runnable {
  13 +
  14 + String lineCode;
  15 +
  16 + public ThreadPoolTask(String lineCode) {
  17 + this.lineCode = lineCode;
  18 + }
  19 +
  20 + @Override
  21 + public void run() {
  22 + List<ScheduleRealInfo> allList = ScheduleBuffer.realSchedulListMap.get(lineCode);
  23 + //按车辆分组班次
  24 + ArrayListMultimap<String, ScheduleRealInfo> alMap = ArrayListMultimap.create();
  25 +
  26 + for(ScheduleRealInfo sch : allList){
  27 + //停车场即起点站的进出场班次不参与匹配
  28 + if(!sch.isParkIsFirstStation())
  29 + alMap.put(sch.getClZbh(), sch);
  30 + }
  31 +
  32 + //开始匹配
  33 + ScheduleRealMatcher srMatcher;
  34 + Set<String> ks = alMap.keySet();
  35 +
  36 + for(String nbbm : ks){
  37 +
  38 + srMatcher = new ScheduleRealMatcher(alMap.get(nbbm), GpsArrivalDataBuffer.pops(nbbm));
  39 +
  40 + //在这里应用各种匹配规则
  41 + srMatcher
  42 + .timeClosest()
  43 + .matchEnd();
  44 +
  45 + }
  46 + }
  47 +}
src/main/java/com/bsth/vehicle/gpsdata/arrival/entity/RealTimeModel.java 0 → 100644
  1 +package com.bsth.vehicle.gpsdata.arrival.entity;
  2 +
  3 +import javax.persistence.Entity;
  4 +import javax.persistence.GeneratedValue;
  5 +import javax.persistence.Id;
  6 +import javax.persistence.Table;
  7 +
  8 +
  9 +/**
  10 + *
  11 + * @ClassName: RealTimeModel
  12 + * @author PanZhao
  13 + * @date 2016年7月24日 下午5:00:26
  14 + *
  15 + */
  16 +@Entity
  17 +@Table(name = "bsth_s_real_time")
  18 +public class RealTimeModel {
  19 +
  20 + public RealTimeModel() {
  21 + }
  22 +
  23 + public RealTimeModel(String stationCode, int type) {
  24 + this.station = stationCode;
  25 + this.type = type;
  26 + }
  27 +
  28 + @Id
  29 + @GeneratedValue
  30 + private Integer id;
  31 +
  32 + /** 站点编码 */
  33 + private String station;
  34 +
  35 + /** GPS时间 */
  36 + private Long gpsTime;
  37 +
  38 + /** 0:GPS正常到离站,1:GPS信号丢失,通过定时定距预测 */
  39 + private Integer gpsStatus;
  40 +
  41 + /** 如gpsStatus 为1 ,则表示预测的GPS点和站点直线距离 */
  42 + private Double distance;
  43 +
  44 + /** GPS定时定距关联, 格式为:设备号_时间戳 */
  45 + private String gps;
  46 +
  47 + /** 人工录入的实际时间 */
  48 + private Long personTime;
  49 +
  50 + /** RFID 时间 */
  51 + private Long rfidTime;
  52 +
  53 + /** 0: 进, 1:出 */
  54 + private int type;
  55 +
  56 + /** 晚点时间 */
  57 + private Long late;
  58 +
  59 + public Integer getId() {
  60 + return id;
  61 + }
  62 +
  63 + public void setId(Integer id) {
  64 + this.id = id;
  65 + }
  66 +
  67 + public Long getGpsTime() {
  68 + return gpsTime;
  69 + }
  70 +
  71 + public RealTimeModel setGpsTime(Long gpsTime) {
  72 + this.gpsTime = gpsTime;
  73 + return this;
  74 + }
  75 +
  76 + public Integer getGpsStatus() {
  77 + return gpsStatus;
  78 + }
  79 +
  80 + public void setGpsStatus(Integer gpsStatus) {
  81 + this.gpsStatus = gpsStatus;
  82 + }
  83 +
  84 + public Double getDistance() {
  85 + return distance;
  86 + }
  87 +
  88 + public void setDistance(Double distance) {
  89 + this.distance = distance;
  90 + }
  91 +
  92 + public String getGps() {
  93 + return gps;
  94 + }
  95 +
  96 + public void setGps(String gps) {
  97 + this.gps = gps;
  98 + }
  99 +
  100 + public Long getPersonTime() {
  101 + return personTime;
  102 + }
  103 +
  104 + public void setPersonTime(Long personTime) {
  105 + this.personTime = personTime;
  106 + }
  107 +
  108 + public Long getRfidTime() {
  109 + return rfidTime;
  110 + }
  111 +
  112 + public void setRfidTime(Long rfidTime) {
  113 + this.rfidTime = rfidTime;
  114 + }
  115 +
  116 + public int getType() {
  117 + return type;
  118 + }
  119 +
  120 + public void setType(int type) {
  121 + this.type = type;
  122 + }
  123 +
  124 + public Long getLate() {
  125 + return late;
  126 + }
  127 +
  128 + public void setLate(Long late) {
  129 + this.late = late;
  130 + }
  131 +
  132 + public String getStation() {
  133 + return station;
  134 + }
  135 +
  136 + public void setStation(String station) {
  137 + this.station = station;
  138 + }
  139 +
  140 + public Long getTime(){
  141 + //人工录入优先级最高
  142 + if(personTime != null)
  143 + return personTime;
  144 +
  145 + //GPS其次
  146 + if(gpsTime != null)
  147 + return gpsTime;
  148 +
  149 + return null;
  150 + }
  151 +
  152 + public void resetNull(){
  153 + this.setGpsTime(null);
  154 + this.setPersonTime(null);
  155 + this.setRfidTime(null);
  156 + }
  157 +}
src/main/java/com/bsth/vehicle/gpsdata/arrival/match/ScheduleRealMatcher.java 0 → 100644
  1 +package com.bsth.vehicle.gpsdata.arrival.match;
  2 +
  3 +import java.text.SimpleDateFormat;
  4 +import java.util.ArrayList;
  5 +import java.util.Collections;
  6 +import java.util.Comparator;
  7 +import java.util.Date;
  8 +import java.util.HashMap;
  9 +import java.util.HashSet;
  10 +import java.util.List;
  11 +import java.util.Map;
  12 +import java.util.Set;
  13 +
  14 +import org.springframework.beans.BeansException;
  15 +import org.springframework.context.ApplicationContext;
  16 +import org.springframework.context.ApplicationContextAware;
  17 +import org.springframework.stereotype.Component;
  18 +
  19 +import com.bsth.entity.realcontrol.ScheduleRealInfo;
  20 +import com.bsth.service.realcontrol.buffer.ScheduleBuffer;
  21 +import com.bsth.vehicle.directive.service.DirectiveService;
  22 +import com.bsth.vehicle.gpsdata.arrival.entity.RealTimeModel;
  23 +import com.bsth.vehicle.gpsdata.entity.ArrivalInfo;
  24 +import com.bsth.websocket.handler.RealControlSocketHandler;
  25 +import com.fasterxml.jackson.core.JsonProcessingException;
  26 +import com.fasterxml.jackson.databind.ObjectMapper;
  27 +
  28 +/**
  29 + *
  30 + * @ClassName: ScheduleRealMatch
  31 + * @author PanZhao
  32 + * @date 2016年7月24日 下午5:19:04
  33 + *
  34 + */
  35 +@Component
  36 +public class ScheduleRealMatcher implements ApplicationContextAware{
  37 +
  38 + // Spring应用上下文环境
  39 + private static ApplicationContext applicationContext;
  40 +
  41 + /** 班次列表 */
  42 + List<ScheduleRealInfo> schs;
  43 +
  44 + /** 到离站列表 */
  45 + List<ArrivalInfo> arrivals;
  46 +
  47 + /** 出站数据 */
  48 + List<ArrivalInfo> outArrivals = new ArrayList<>();
  49 +
  50 + /** 进站数据 */
  51 + List<ArrivalInfo> inArrivals = new ArrayList<>();
  52 +
  53 + private static RealControlSocketHandler socketHandler;
  54 +
  55 + private static DirectiveService directiveService;
  56 +
  57 + SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");
  58 +
  59 + //最大班次间隔
  60 + int maxBcsj = 0;
  61 +
  62 + public ScheduleRealMatcher(){}
  63 +
  64 + public ScheduleRealMatcher(List<ScheduleRealInfo> schs, List<ArrivalInfo> arrivals) {
  65 + this.schs = schs;
  66 + this.arrivals = arrivals;
  67 + //排序
  68 + Collections.sort(schs, new Comparator<ScheduleRealInfo>() {
  69 + @Override
  70 + public int compare(ScheduleRealInfo s1, ScheduleRealInfo s2) {
  71 + return (int) (s1.getFcsjT() - s2.getFcsjT());
  72 + }
  73 + });
  74 +
  75 + Collections.sort(arrivals, new Comparator<ArrivalInfo>() {
  76 +
  77 + @Override
  78 + public int compare(ArrivalInfo a1, ArrivalInfo a2) {
  79 + return (int) (a1.getTs() - a2.getTs());
  80 + }
  81 + });
  82 +
  83 + //将进出数据拆分成2个集合
  84 + for(ArrivalInfo arr : arrivals){
  85 + if(arr.getInOut() == 0)
  86 + inArrivals.add(arr);
  87 + else if(arr.getInOut() == 1)
  88 + outArrivals.add(arr);
  89 + }
  90 +
  91 + for(ScheduleRealInfo sch : schs){
  92 + if(sch.getBcsj() != null && sch.getBcsj() > maxBcsj){
  93 + maxBcsj = sch.getBcsj();
  94 + }
  95 +
  96 + if(sch.getSjfcModel() == null)
  97 + sch.setSjfcModel(new RealTimeModel(sch.getQdzCode(), 1));
  98 + if(sch.getSjddModel() == null)
  99 + sch.setSjddModel(new RealTimeModel(sch.getZdzCode(), 0));
  100 + }
  101 + }
  102 +
  103 + /**
  104 + *
  105 + * @Title: timeClosest
  106 + * @Description: TODO(按照时间距离进行匹配)
  107 + * @throws
  108 + */
  109 + public ScheduleRealMatcher timeClosest(){
  110 + TimeClosestGPS.match(schs, inArrivals, outArrivals, maxBcsj);
  111 + return this;
  112 + }
  113 +
  114 + /**
  115 + *
  116 + * @Title: matchEnd
  117 + * @Description: TODO(匹配结束后做上发信使和下发调度指令)
  118 + * @throws
  119 + */
  120 + public void matchEnd(){
  121 +
  122 + for(ScheduleRealInfo sch : schs){
  123 + //按 RealTimeModel 的优先级赋予班次实际时间
  124 + //起点发出
  125 + if(sch.statusTostart()){
  126 +
  127 + //设置班次的实际发车时间
  128 + sch.setFcsjActualAll(sch.getSjfcModel().getTime());
  129 + //班次状态改为正在执行
  130 + sch.calcStatus();
  131 + ScheduleBuffer.persistentList.add(sch);
  132 +
  133 + if(sch.isFirstStationIsPark()){
  134 + ScheduleBuffer.persistentList.add(sch.getTwins());
  135 + sendFcsj(sch.getTwins());//推送到页面
  136 + }
  137 +
  138 + sendFcsj(sch);//推送到页面
  139 + }
  140 +
  141 + //终点到达
  142 + if(sch.statusToEnd()){
  143 +
  144 + //设置班次的实际终点时间
  145 + sch.setZdsjActualAll(sch.getSjddModel().getTime());
  146 + //完成当前班次
  147 + ScheduleRealInfo nextSch = ScheduleBuffer.finishSch(sch);
  148 +
  149 + if(sch.isFirstStationIsPark()){
  150 + ScheduleBuffer.persistentList.add(sch.getTwins());
  151 + sendFcsj(sch.getTwins());//推送到页面
  152 + }
  153 +
  154 + int finish = ScheduleBuffer.getFinishSchNo(sch.getClZbh());
  155 + if(nextSch != null){
  156 + //发送下一班次的调度指令
  157 + directiveService.send60Dispatch(nextSch, finish);
  158 + }
  159 +
  160 + sendZdsj(sch, nextSch, finish);//推送到页面
  161 + }
  162 + }
  163 + }
  164 +
  165 + /**
  166 + * @throws JsonProcessingException
  167 + * @throws NumberFormatException
  168 + * @Title: sendFcsj
  169 + * @Description: TODO(推送发车信息)
  170 + * @param @param schedule 班次
  171 + * @throws
  172 + */
  173 + public void sendFcsj(ScheduleRealInfo schedule) {
  174 + /*JSONObject json = new JSONObject();
  175 + json.put("fn", "faChe");
  176 + json.put("t", schedule);
  177 + json.put("dataStr", sdf.format(new Date()));*/
  178 +
  179 + Map<String, Object> map = new HashMap<>();
  180 + map.put("fn", "faChe");
  181 + map.put("t", schedule);
  182 + map.put("dataStr", sdf.format(new Date()));
  183 +
  184 + ObjectMapper mapper = new ObjectMapper();
  185 +
  186 + try{
  187 + socketHandler.sendMessageToLine(Integer.parseInt(schedule.getXlBm()), mapper.writeValueAsString(map));
  188 + }catch(Exception e){
  189 + e.printStackTrace();
  190 + }
  191 + }
  192 +
  193 + /**
  194 + * @throws JsonProcessingException
  195 + * @throws NumberFormatException
  196 + * @Title: sendFcsj
  197 + * @Description: TODO(推送到达终点时间)
  198 + * @param @param schedule 班次
  199 + * @throws
  200 + */
  201 + public void sendZdsj(ScheduleRealInfo schedule,ScheduleRealInfo nextSch, int finish) {
  202 + /*JSONObject json = new JSONObject();
  203 + json.put("fn", "zhongDian");
  204 + json.put("t", schedule);
  205 + json.put("nt", nextSch);
  206 + json.put("finish", finish);
  207 + json.put("dataStr", sdf.format(new Date()));*/
  208 +
  209 + Map<String, Object> map = new HashMap<>();
  210 + map.put("fn", "zhongDian");
  211 + map.put("t", schedule);
  212 + map.put("nt", nextSch);
  213 + map.put("finish", finish);
  214 + map.put("dataStr", sdf.format(new Date()));
  215 +
  216 + ObjectMapper mapper = new ObjectMapper();
  217 +
  218 + try{
  219 + socketHandler.sendMessageToLine(Integer.parseInt(schedule.getXlBm()), mapper.writeValueAsString(map));
  220 + }catch(Exception e){
  221 + e.printStackTrace();
  222 + }
  223 + }
  224 +
  225 + @Override
  226 + public void setApplicationContext(ApplicationContext arg0) throws BeansException {
  227 + applicationContext = arg0;
  228 +
  229 + socketHandler = applicationContext.getBean(RealControlSocketHandler.class);
  230 + directiveService = applicationContext.getBean(DirectiveService.class);
  231 + }
  232 +}
src/main/java/com/bsth/vehicle/gpsdata/arrival/match/TimeClosestGPS.java 0 → 100644
  1 +package com.bsth.vehicle.gpsdata.arrival.match;
  2 +
  3 +import java.text.SimpleDateFormat;
  4 +import java.util.List;
  5 +
  6 +import com.bsth.entity.realcontrol.ScheduleRealInfo;
  7 +import com.bsth.vehicle.gpsdata.arrival.entity.RealTimeModel;
  8 +import com.bsth.vehicle.gpsdata.entity.ArrivalInfo;
  9 +import com.google.common.collect.BiMap;
  10 +import com.google.common.collect.HashBiMap;
  11 +
  12 +/**
  13 + *
  14 + * @ClassName: TimeClosest
  15 + * @Description: TODO(按时间距离最近进行匹配)
  16 + * @author PanZhao
  17 + * @date 2016年7月24日 下午5:27:27
  18 + *
  19 + */
  20 +public class TimeClosestGPS {
  21 +
  22 + static SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
  23 +
  24 + public static void match(List<ScheduleRealInfo> schs,
  25 + List<ArrivalInfo> inList, List<ArrivalInfo> outList, int maxBcsj) {
  26 +
  27 + //班次ID 和 离站数据 一对一映射
  28 + BiMap<Long, String> outBiMap = HashBiMap.create();
  29 + //班次ID 和 到站数据 一对一映射
  30 + BiMap<Long, String> inBiMap = HashBiMap.create();
  31 +
  32 + Long spaceTime = maxBcsj * 60 * 1000 * 2L;
  33 +
  34 + RealTimeModel sjfcModel, sjddModel;
  35 + for(ScheduleRealInfo sch : schs){
  36 +
  37 + sjfcModel = sch.getSjfcModel();
  38 + sjddModel = sch.getSjddModel();
  39 +
  40 + //起点发出
  41 + for(ArrivalInfo outArr : outList){
  42 + if(sjfcModel.getStation().equals(outArr.getStopNo())
  43 + && Math.abs(sch.getFcsjT() - outArr.getTs()) < spaceTime){
  44 +
  45 + //如果这个实际发车已经被之前班次关联
  46 + if(outBiMap.inverse().get(outArr.getId()) != null)
  47 + continue;
  48 +
  49 + //System.out.println("实际起点发出,计划时间:" + sch.getFcsj() + " -实际时间:" + sdf.format(new Date(outArr.getTs())) + " -" + outArr.getTs());
  50 + sjfcModel.setGpsTime(outArr.getTs());
  51 + outBiMap.put(sch.getId(), outArr.getId());
  52 + }
  53 + }
  54 +
  55 + //有些班次没有历时,也就没有计划终点时间
  56 + if(sch.getZdsjT() == null)
  57 + continue;
  58 + //终点到达
  59 + for(ArrivalInfo inArr : inList){
  60 + if(sjddModel.getStation().equals(inArr.getStopNo())
  61 + && Math.abs(sch.getZdsjT() - inArr.getTs()) < spaceTime){
  62 + //如果这个实际发车已经被之前班次关联
  63 + if(inBiMap.inverse().get(inArr.getId()) != null)
  64 + continue;
  65 +
  66 + //System.out.println("实际到达终点,计划时间:" + sch.getZdsj() + " -实际时间:" + sdf.format(new Date(inArr.getTs())) + " -" + inArr.getTs());
  67 + sjddModel.setGpsTime(inArr.getTs());
  68 + inBiMap.put(sch.getId(), inArr.getId());
  69 + }
  70 + }
  71 + }
  72 + }
  73 +}
src/main/java/com/bsth/vehicle/gpsdata/buffer/GpsArrivalDataBuffer.java
1 package com.bsth.vehicle.gpsdata.buffer; 1 package com.bsth.vehicle.gpsdata.buffer;
2 2
  3 +import java.util.ArrayList;
3 import java.util.Collections; 4 import java.util.Collections;
4 import java.util.Comparator; 5 import java.util.Comparator;
5 import java.util.HashMap; 6 import java.util.HashMap;
@@ -8,7 +9,7 @@ import java.util.Map; @@ -8,7 +9,7 @@ import java.util.Map;
8 9
9 import com.bsth.vehicle.common.CommonMapped; 10 import com.bsth.vehicle.common.CommonMapped;
10 import com.bsth.vehicle.gpsdata.entity.ArrivalInfo; 11 import com.bsth.vehicle.gpsdata.entity.ArrivalInfo;
11 -import com.google.common.collect.LinkedListMultimap; 12 +import com.google.common.collect.ArrayListMultimap;
12 13
13 /** 14 /**
14 * 15 *
@@ -21,9 +22,10 @@ import com.google.common.collect.LinkedListMultimap; @@ -21,9 +22,10 @@ import com.google.common.collect.LinkedListMultimap;
21 public class GpsArrivalDataBuffer { 22 public class GpsArrivalDataBuffer {
22 23
23 /** 24 /**
24 - * 车辆 时间戳排序的进出站链表 25 + * 车辆 时间戳排序的实际进出站
25 */ 26 */
26 - public static LinkedListMultimap<String, ArrivalInfo> allMap; 27 + public static ArrayListMultimap<String, ArrivalInfo> allMap;
  28 +
27 29
28 /** 30 /**
29 * 车辆 和 进出站链表索引 31 * 车辆 和 进出站链表索引
@@ -45,16 +47,15 @@ public class GpsArrivalDataBuffer { @@ -45,16 +47,15 @@ public class GpsArrivalDataBuffer {
45 List<ArrivalInfo> all = allMap.get(nbbm); 47 List<ArrivalInfo> all = allMap.get(nbbm);
46 int size = all.size(); 48 int size = all.size();
47 if(size == 0) 49 if(size == 0)
48 - return null; 50 + return new ArrayList<>(0);
49 51
50 List<ArrivalInfo> rs = all.subList(mark, size); 52 List<ArrivalInfo> rs = all.subList(mark, size);
51 -  
52 markMap.put(nbbm, size); 53 markMap.put(nbbm, size);
53 return rs; 54 return rs;
54 } 55 }
55 56
56 static { 57 static {
57 - allMap = LinkedListMultimap.create(); 58 + allMap = ArrayListMultimap.create();
58 markMap = new HashMap<>(); 59 markMap = new HashMap<>();
59 } 60 }
60 61
src/main/java/com/bsth/vehicle/gpsdata/buffer/GpsRealDataBuffer.java
@@ -143,7 +143,11 @@ public class GpsRealDataBuffer { @@ -143,7 +143,11 @@ public class GpsRealDataBuffer {
143 gpsData.setStationName(CommonMapped.stationCodeMap.get(gpsData.getStopNo())); 143 gpsData.setStationName(CommonMapped.stationCodeMap.get(gpsData.getStopNo()));
144 144
145 current = ScheduleBuffer.findCurrent(nbbm); 145 current = ScheduleBuffer.findCurrent(nbbm);
146 - next = ScheduleBuffer.getNext(current); 146 + if(null == current){
  147 + next = ScheduleBuffer.getFirst(nbbm);
  148 + }
  149 + else
  150 + next = ScheduleBuffer.getNext(current);
147 151
148 if(current != null) 152 if(current != null)
149 gpsData.setCurrSchId(current.getId()); 153 gpsData.setCurrSchId(current.getId());
src/main/java/com/bsth/vehicle/gpsdata/entity/ArrivalInfo.java
@@ -16,14 +16,20 @@ import javax.persistence.Transient; @@ -16,14 +16,20 @@ import javax.persistence.Transient;
16 public class ArrivalInfo { 16 public class ArrivalInfo {
17 17
18 @Transient 18 @Transient
19 - static SimpleDateFormat sdf = new SimpleDateFormat("HH:mm")  
20 - ,sdf2 = new SimpleDateFormat("yyyy-MM-dd HH:mm"); 19 + static SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss")
  20 + ,sdf2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
21 21
22 22
23 public ArrivalInfo(String deviceId, Long ts, String lineCode, Integer upDown, String stopNo, Integer inOut, 23 public ArrivalInfo(String deviceId, Long ts, String lineCode, Integer upDown, String stopNo, Integer inOut,
24 Date createDate, Integer weeksYear) { 24 Date createDate, Integer weeksYear) {
25 this.deviceId = deviceId; 25 this.deviceId = deviceId;
26 26
  27 + //gps是2014年的数据,临时将ts拉到今天
  28 + /*try {
  29 + this.ts = sdf2.parse("2016-07-25 " + sdf.format(new Date(ts))).getTime();
  30 + } catch (ParseException e) {
  31 + e.printStackTrace();
  32 + }*/
27 this.ts = ts; 33 this.ts = ts;
28 34
29 this.lineCode = lineCode; 35 this.lineCode = lineCode;
@@ -162,4 +168,8 @@ public class ArrivalInfo { @@ -162,4 +168,8 @@ public class ArrivalInfo {
162 public void setStopName(String stopName) { 168 public void setStopName(String stopName) {
163 this.stopName = stopName; 169 this.stopName = stopName;
164 } 170 }
  171 +
  172 + public String getId(){
  173 + return this.deviceId + "_" + this.ts;
  174 + }
165 } 175 }
src/main/java/com/bsth/vehicle/gpsdata/service/GpsDataServiceImpl.java
@@ -139,7 +139,7 @@ public class GpsDataServiceImpl implements GpsDataService{ @@ -139,7 +139,7 @@ public class GpsDataServiceImpl implements GpsDataService{
139 139
140 //如果是同一天 140 //如果是同一天
141 if(sDayOfYear == eDayOfYear){ 141 if(sDayOfYear == eDayOfYear){
142 - weekCal.setTimeInMillis(st); 142 + weekCal.setTimeInMillis(st * 1000);
143 list = findByTs(weekCal.get(Calendar.WEEK_OF_YEAR), sDayOfYear, st, et, devices); 143 list = findByTs(weekCal.get(Calendar.WEEK_OF_YEAR), sDayOfYear, st, et, devices);
144 } 144 }
145 else{ 145 else{
@@ -160,7 +160,7 @@ public class GpsDataServiceImpl implements GpsDataService{ @@ -160,7 +160,7 @@ public class GpsDataServiceImpl implements GpsDataService{
160 tempEt = DateUtils.getTimesnight(sCal); 160 tempEt = DateUtils.getTimesnight(sCal);
161 } 161 }
162 162
163 - weekCal.setTimeInMillis(tempSt); 163 + weekCal.setTimeInMillis(tempSt * 1000);
164 list.addAll(findByTs(weekCal.get(Calendar.WEEK_OF_YEAR), i, tempSt, tempEt, devices)); 164 list.addAll(findByTs(weekCal.get(Calendar.WEEK_OF_YEAR), i, tempSt, tempEt, devices));
165 //加一天 165 //加一天
166 sCal.add(Calendar.DATE, 1); 166 sCal.add(Calendar.DATE, 1);
@@ -244,6 +244,7 @@ public class GpsDataServiceImpl implements GpsDataService{ @@ -244,6 +244,7 @@ public class GpsDataServiceImpl implements GpsDataService{
244 return list; 244 return list;
245 } 245 }
246 246
  247 + //weekOfYear 算错了
247 public Map<String, ArrivalInfo> findArrivalByTs(int weekOfYear, Long st, Long et, String devicesInSql){ 248 public Map<String, ArrivalInfo> findArrivalByTs(int weekOfYear, Long st, Long et, String devicesInSql){
248 Map<String, ArrivalInfo> map = new HashMap<>(); 249 Map<String, ArrivalInfo> map = new HashMap<>();
249 250
@@ -275,4 +276,10 @@ public class GpsDataServiceImpl implements GpsDataService{ @@ -275,4 +276,10 @@ public class GpsDataServiceImpl implements GpsDataService{
275 } 276 }
276 return map; 277 return map;
277 } 278 }
  279 +
  280 + public static void main(String[] args) {
  281 + Calendar weekCal = Calendar.getInstance();
  282 + weekCal.setTime(new Date());
  283 + System.out.println(weekCal.get(Calendar.WEEK_OF_YEAR));
  284 + }
278 } 285 }
src/main/resources/static/pages/control/line/child_pages/vehicAndper_adjust.html renamed to src/main/resources/static/pages/control/line/child_pages/car_and_persion.html
@@ -253,7 +253,7 @@ @@ -253,7 +253,7 @@
253 syncSubmit(idArray, params ,function(){ 253 syncSubmit(idArray, params ,function(){
254 layer.closeAll(); 254 layer.closeAll();
255 layer.msg('操作完成!'); 255 layer.msg('操作完成!');
256 - //刷新表格 256 + //刷新弹出层表格
257 refreshMainList(); 257 refreshMainList();
258 }); 258 });
259 }); 259 });
@@ -274,7 +274,7 @@ @@ -274,7 +274,7 @@
274 $.post('/realSchedule/adjust', data, function(rs){ 274 $.post('/realSchedule/adjust', data, function(rs){
275 //更新前端缓存 275 //更新前端缓存
276 if(rs.status == 200){ 276 if(rs.status == 200){
277 - _data.updateSchedule(rs.t); 277 + _alone.refreshSchedule(rs.t);
278 } 278 }
279 279
280 i ++; 280 i ++;
src/main/resources/static/pages/control/line/child_pages/child_task.html
@@ -436,13 +436,16 @@ $(function(){ @@ -436,13 +436,16 @@ $(function(){
436 $('.confirm', schAddPanel).on('click', function(){ 436 $('.confirm', schAddPanel).on('click', function(){
437 var f = $('form', schAddPanel); 437 var f = $('form', schAddPanel);
438 var param = f.serializeJSON(); 438 var param = f.serializeJSON();
439 - /** 页面组装数据 */  
440 //线路 439 //线路
441 param.xlBm = lineSelect.val(); 440 param.xlBm = lineSelect.val();
442 param.xlName = _data.getLineIds()[param.xlBm]; 441 param.xlName = _data.getLineIds()[param.xlBm];
443 //路牌 442 //路牌
444 param.lpName = lpSelect.val(); 443 param.lpName = lpSelect.val();
445 //拆分驾驶员工号和姓名 444 //拆分驾驶员工号和姓名
  445 + if(!param.jGh){
  446 + layer.alert('驾驶员不能为空!', {icon: 2, title: '提交失败'});
  447 + return;
  448 + }
446 param.jName = param.jGh.split('/')[1]; 449 param.jName = param.jGh.split('/')[1];
447 param.jGh = param.jGh.split('/')[0]; 450 param.jGh = param.jGh.split('/')[0];
448 451
@@ -497,12 +500,18 @@ function refreshChildTasks(){ @@ -497,12 +500,18 @@ function refreshChildTasks(){
497 //主任务id 500 //主任务id
498 var id = $mainTab.find('tr._active').data('id'); 501 var id = $mainTab.find('tr._active').data('id');
499 502
500 - $.get('/childTask/all', {'schedule.id_eq': id}, function(rs){ 503 +
  504 + var htmlStr = template('child_task_sub_table_temp', {list: _data.getSchedulById(id).cTasks});
  505 +
  506 + dictionaryUtils.transformDom(
  507 + $subTab.find('tbody').html(htmlStr).find('.nt-dictionary')
  508 + );
  509 +/* $.get('/childTask/all', {'schedule.id_eq': id}, function(rs){
501 var htmlStr = template('child_task_sub_table_temp', {list: rs}); 510 var htmlStr = template('child_task_sub_table_temp', {list: rs});
502 511
503 dictionaryUtils.transformDom( 512 dictionaryUtils.transformDom(
504 $subTab.find('tbody').html(htmlStr).find('.nt-dictionary') 513 $subTab.find('tbody').html(htmlStr).find('.nt-dictionary')
505 ); 514 );
506 - }); 515 + }); */
507 } 516 }
508 </script> 517 </script>
src/main/resources/static/pages/control/line/child_pages/outgo_adjust_all.html renamed to src/main/resources/static/pages/control/line/child_pages/dfsj_batch.html
src/main/resources/static/pages/control/line/child_pages/js/child_task.js
@@ -335,12 +335,15 @@ var childTaskCase = { @@ -335,12 +335,15 @@ var childTaskCase = {
335 }; 335 };
336 336
337 function childTaskSubmit(fs, layerIndex){ 337 function childTaskSubmit(fs, layerIndex){
338 - syncSubmit(fs, function(){ 338 + syncSubmit(fs, function(rs){
339 layer.msg('子任务添加成功'); 339 layer.msg('子任务添加成功');
340 setTimeout(function(){ 340 setTimeout(function(){
341 layer.close(layerIndex); 341 layer.close(layerIndex);
342 //刷新子任务列表 342 //刷新子任务列表
343 - refreshChildTasks(); 343 + if(rs.status == 'SUCCESS'){
  344 + _alone.refreshSchedule(rs.t);
  345 + refreshChildTasks();
  346 + }
344 }, 700); 347 }, 700);
345 }); 348 });
346 } 349 }
@@ -353,10 +356,11 @@ function syncSubmit(fs, cb){ @@ -353,10 +356,11 @@ function syncSubmit(fs, cb){
353 if(fs.length == 0) return; 356 if(fs.length == 0) return;
354 //备注 357 //备注
355 var remarks = $(fs[0]).parents('.custom-anim-modal').find('textarea[name=remarks]').val(); 358 var remarks = $(fs[0]).parents('.custom-anim-modal').find('textarea[name=remarks]').val();
356 - var i = 0, len = fs.length; 359 + var i = 0, len = fs.length, cbRs;
357 (function(){ 360 (function(){
  361 +
358 if(i == len){ 362 if(i == len){
359 - cb && cb(); 363 + cb && cb(cbRs);
360 return; 364 return;
361 } 365 }
362 366
@@ -365,12 +369,15 @@ function syncSubmit(fs, cb){ @@ -365,12 +369,15 @@ function syncSubmit(fs, cb){
365 ,params = $(form).serializeJSON(); 369 ,params = $(form).serializeJSON();
366 370
367 params.remarks = remarks; 371 params.remarks = remarks;
368 - $post('/childTask', params, function(){ 372 + $post('/childTask', params, function(rs){
  373 + console.log('item rs: ' ,rs);
369 $(form).parent().find('.task-item-close').replaceWith('<a class="task-item-success"><i class="fa fa-check-circle" ></i></a>'); 374 $(form).parent().find('.task-item-close').replaceWith('<a class="task-item-success"><i class="fa fa-check-circle" ></i></a>');
370 i ++; 375 i ++;
371 //做一层防护,防止缺心眼出现无限循环提交 376 //做一层防护,防止缺心眼出现无限循环提交
372 if(i == 0) 377 if(i == 0)
373 return; 378 return;
  379 +
  380 + cbRs = rs;
374 f(); 381 f();
375 }); 382 });
376 })(); 383 })();
src/main/resources/static/pages/control/line/css/lineControl.css
@@ -2166,45 +2166,56 @@ tr._active .blue-badge{ @@ -2166,45 +2166,56 @@ tr._active .blue-badge{
2166 color: #afafaf !important; 2166 color: #afafaf !important;
2167 } 2167 }
2168 2168
  2169 +.pb-table tr.selected.next-sch a{
  2170 + color: white !important;
  2171 +}
  2172 +
2169 .tab_line .pb-table tr._tr_active.active-line-no a.remarks-popover{ 2173 .tab_line .pb-table tr._tr_active.active-line-no a.remarks-popover{
2170 color: #bebebe; 2174 color: #bebebe;
2171 } 2175 }
2172 2176
2173 .tab_line .pb-table tr._tr_active.active-line-no td.tl-qrlb, 2177 .tab_line .pb-table tr._tr_active.active-line-no td.tl-qrlb,
2174 .pb-table tr.selected.dir_0 td.tl-qrlb, 2178 .pb-table tr.selected.dir_0 td.tl-qrlb,
2175 -.pb-table tr.selected.dir_1 td.tl-qrlb{ 2179 +.pb-table tr.selected.dir_1 td.tl-qrlb,
  2180 +.pb-table tr.selected.next-sch td.tl-qrlb{
2176 background: none; 2181 background: none;
2177 color: #ff796a; 2182 color: #ff796a;
2178 } 2183 }
2179 .tab_line .pb-table tr._tr_active.active-line-no td.tl-zzzx, 2184 .tab_line .pb-table tr._tr_active.active-line-no td.tl-zzzx,
2180 .pb-table tr.selected.dir_0 td.tl-zzzx, 2185 .pb-table tr.selected.dir_0 td.tl-zzzx,
2181 -.pb-table tr.selected.dir_1 td.tl-zzzx{ 2186 +.pb-table tr.selected.dir_1 td.tl-zzzx,
  2187 +.pb-table tr.selected.next-sch td.tl-zzzx{
2182 background: none; 2188 background: none;
2183 color: #5ae35a; 2189 color: #5ae35a;
2184 } 2190 }
2185 .tab_line .pb-table tr._tr_active.active-line-no td.tl-yzx, 2191 .tab_line .pb-table tr._tr_active.active-line-no td.tl-yzx,
2186 .pb-table tr.selected.dir_0 td.tl-yzx, 2192 .pb-table tr.selected.dir_0 td.tl-yzx,
2187 -.pb-table tr.selected.dir_1 td.tl-yzx{ 2193 +.pb-table tr.selected.dir_1 td.tl-yzx,
  2194 +.pb-table tr.selected.next-sch td.tl-yzx{
2188 background: none; 2195 background: none;
2189 color: #80c8fa; 2196 color: #80c8fa;
2190 } 2197 }
2191 .tab_line .pb-table tr._tr_active.active-line-no td.tl-xxfc, 2198 .tab_line .pb-table tr._tr_active.active-line-no td.tl-xxfc,
2192 .pb-table tr.selected.dir_0 td.tl-xxfc, 2199 .pb-table tr.selected.dir_0 td.tl-xxfc,
2193 -.pb-table tr.selected.dir_1 td.tl-xxfc{ 2200 +.pb-table tr.selected.dir_1 td.tl-xxfc,
  2201 +.pb-table tr.selected.next-sch td.tl-xxfc{
2194 background: none; 2202 background: none;
2195 color: #a16dff; 2203 color: #a16dff;
2196 } 2204 }
2197 2205
2198 .tab_line .pb-table tr._tr_active.active-line-no td.tl-xxsd, 2206 .tab_line .pb-table tr._tr_active.active-line-no td.tl-xxsd,
2199 .pb-table tr.selected.dir_0 td.tl-xxsd, 2207 .pb-table tr.selected.dir_0 td.tl-xxsd,
2200 -.pb-table tr.selected.dir_1 td.tl-xxsd{ 2208 +.pb-table tr.selected.dir_1 td.tl-xxsd,
  2209 +.pb-table tr.selected.next-sch td.tl-xxsd{
2201 background: none; 2210 background: none;
2202 color: #ffb193; 2211 color: #ffb193;
2203 } 2212 }
2204 2213
  2214 +
2205 .tab_line .pb-table tr._tr_active.active-line-no td.tl-xxrd, 2215 .tab_line .pb-table tr._tr_active.active-line-no td.tl-xxrd,
2206 .pb-table tr.selected.dir_0 td.tl-xxrd, 2216 .pb-table tr.selected.dir_0 td.tl-xxrd,
2207 -.pb-table tr.selected.dir_1 td.tl-xxrd{ 2217 +.pb-table tr.selected.dir_1 td.tl-xxrd,
  2218 +.pb-table tr.selected.next-sch td.tl-xxrd{
2208 background: none; 2219 background: none;
2209 color: #5cb0e9; 2220 color: #5cb0e9;
2210 } 2221 }
src/main/resources/static/pages/control/line/index.html
@@ -69,7 +69,7 @@ @@ -69,7 +69,7 @@
69 </div> 69 </div>
70 </div> 70 </div>
71 <div class="portlet-body" id="top-tabs-wrap" > 71 <div class="portlet-body" id="top-tabs-wrap" >
72 - <ul class="nav nav-tabs" > 72 + <ul class="nav nav-tabs top-nav" >
73 <li class="active"> 73 <li class="active">
74 <a href="#tab_home" data-toggle="tab" aria-expanded="false" style="padding: 10px 15px;"> 74 <a href="#tab_home" data-toggle="tab" aria-expanded="false" style="padding: 10px 15px;">
75 <i class="fa fa-home"></i> 主页 75 <i class="fa fa-home"></i> 主页
@@ -139,11 +139,11 @@ @@ -139,11 +139,11 @@
139 <span class="menu-text">间隔调整</span> 139 <span class="menu-text">间隔调整</span>
140 </button> 140 </button>
141 </li> 141 </li>
142 - <li class="menu-item disabled" > 142 + <!-- <li class="menu-item disabled" >
143 <button type="button" class="menu-btn"> 143 <button type="button" class="menu-btn">
144 <span class="menu-text">误点调整</span> 144 <span class="menu-text">误点调整</span>
145 </button> 145 </button>
146 - </li> 146 + </li> -->
147 <li class="menu-item" > 147 <li class="menu-item" >
148 <button type="button" class="menu-btn" data-method="schInfoFineTune"> 148 <button type="button" class="menu-btn" data-method="schInfoFineTune">
149 <span class="menu-text">发车信息微调</span> 149 <span class="menu-text">发车信息微调</span>
@@ -156,13 +156,12 @@ @@ -156,13 +156,12 @@
156 <span class="menu-text">临加/子任务</span> 156 <span class="menu-text">临加/子任务</span>
157 </button> 157 </button>
158 </li> 158 </li>
159 - <li class="menu-separator"></li>  
160 - <li class="menu-item disabled" > 159 +<!-- <li class="menu-item disabled" >
161 <button type="button" class="menu-btn"> 160 <button type="button" class="menu-btn">
162 <i class="fa fa-reply-all"></i> 161 <i class="fa fa-reply-all"></i>
163 <span class="menu-text">撤销执行</span> 162 <span class="menu-text">撤销执行</span>
164 </button> 163 </button>
165 - </li> 164 + </li> -->
166 <li class="menu-separator"></li> 165 <li class="menu-separator"></li>
167 <li class="menu-item" > 166 <li class="menu-item" >
168 <button type="button" class="menu-btn" data-method="vehicAndPerAdjust"> 167 <button type="button" class="menu-btn" data-method="vehicAndPerAdjust">
src/main/resources/static/pages/control/line/js/alone.js
@@ -49,7 +49,7 @@ var _alone = (function(){ @@ -49,7 +49,7 @@ var _alone = (function(){
49 }); 49 });
50 }, 50 },
51 //刷新单个班次 51 //刷新单个班次
52 - refreshSchedule: function(schedule){ 52 + refreshSchedule: function(schedule, isBatch){
53 //更新 _data 53 //更新 _data
54 _data.updateSchedule(schedule); 54 _data.updateSchedule(schedule);
55 var tab = '#tab_line_' + schedule.xlBm; 55 var tab = '#tab_line_' + schedule.xlBm;
@@ -62,16 +62,20 @@ var _alone = (function(){ @@ -62,16 +62,20 @@ var _alone = (function(){
62 62
63 var type = schedule.xlDir==0?'up':'down'; 63 var type = schedule.xlDir==0?'up':'down';
64 calculateLineNo($('.pb-table[data-type='+type+']', tab)[0]); 64 calculateLineNo($('.pb-table[data-type='+type+']', tab)[0]);
  65 +
  66 + if(!isBatch)
  67 + goToSch(schedule);
65 }, 68 },
66 //刷新多个班次,刷新完数据再统一计算行号 69 //刷新多个班次,刷新完数据再统一计算行号
67 refreshScheduleArray: function(array){ 70 refreshScheduleArray: function(array){
68 if(!array || array.length == 0) 71 if(!array || array.length == 0)
69 return; 72 return;
70 $.each(array, function(){ 73 $.each(array, function(){
71 - aloneObject.refreshSchedule(this); 74 + aloneObject.refreshSchedule(this, 1);
72 }); 75 });
73 var table = $('tr[data-id='+array[0].id+']').parents('table')[0]; 76 var table = $('tr[data-id='+array[0].id+']').parents('table')[0];
74 calculateLineNo(table); 77 calculateLineNo(table);
  78 + initRemarksPop();
75 }, 79 },
76 //将班次所在的表格做全量更新 80 //将班次所在的表格做全量更新
77 updateTableBySch: function(schedule){ 81 updateTableBySch: function(schedule){
@@ -83,24 +87,24 @@ var _alone = (function(){ @@ -83,24 +87,24 @@ var _alone = (function(){
83 _data.pushSchedule(this); 87 _data.pushSchedule(this);
84 }); 88 });
85 89
86 - var upDown = xlDir==0?'up':'down'; 90 + /*var upDown = xlDir==0?'up':'down';
87 var tab = $('#tab_line_' + xlBm); 91 var tab = $('#tab_line_' + xlBm);
88 //重新渲染表格 92 //重新渲染表格
89 - var table = tab.find('.pb-table[data-type='+upDown+']'); 93 + var table = tab.find('.pb-table[data-type='+upDown+']');*/
  94 + var table = getTableBySch(sch);
90 var schArray = _data.findSchByLine(xlBm, xlDir); 95 var schArray = _data.findSchByLine(xlBm, xlDir);
91 calculateLineNo( 96 calculateLineNo(
92 table.find('tbody').html(template('alone_plan_table_temp', {list: schArray}))[0] 97 table.find('tbody').html(template('alone_plan_table_temp', {list: schArray}))[0]
93 ); 98 );
94 99
95 - var half = tab.find('._body').height() / 2;  
96 -  
97 //定位到新添加的班次 100 //定位到新添加的班次
98 - var currTr = table.find('tr[data-id='+schedule.id+']') 101 + goToSch(schedule);
  102 + /*var currTr = table.find('tr[data-id='+schedule.id+']')
99 ,top = parseInt(currTr.find('td[name=lineNo]').text()) * 37 - half; 103 ,top = parseInt(currTr.find('td[name=lineNo]').text()) * 37 - half;
100 104
101 top = top>0?top:0; 105 top = top>0?top:0;
102 currTr.addClass('anim-delay animated flash'); 106 currTr.addClass('anim-delay animated flash');
103 - currTr.parents('._body').slimScroll({ scrollTo: top + 'px' }); 107 + currTr.parents('._body').slimScroll({ scrollTo: top + 'px' });*/
104 }); 108 });
105 }, 109 },
106 update2Table: function(xlBm, schedule){ 110 update2Table: function(xlBm, schedule){
@@ -113,7 +117,7 @@ var _alone = (function(){ @@ -113,7 +117,7 @@ var _alone = (function(){
113 117
114 var rs = splitDir(array) 118 var rs = splitDir(array)
115 ,tab = $('#tab_line_' + xlBm) 119 ,tab = $('#tab_line_' + xlBm)
116 - ,half = tab.find('._body').height() / 2; 120 + /*,half = tab.find('._body').height() / 2*/;
117 //填充表格数据 121 //填充表格数据
118 calculateLineNo( 122 calculateLineNo(
119 //上行 123 //上行
@@ -123,23 +127,47 @@ var _alone = (function(){ @@ -123,23 +127,47 @@ var _alone = (function(){
123 //下行 127 //下行
124 tab.find('table[data-type=down] tbody').html(template('alone_plan_table_temp', {list: rs.down}))[0] 128 tab.find('table[data-type=down] tbody').html(template('alone_plan_table_temp', {list: rs.down}))[0]
125 ); 129 );
  130 +
126 //定位到指定的班次 131 //定位到指定的班次
127 - var currTr = tab.find('tr[data-id='+schedule.id+']') 132 + goToSch(schedule);
  133 + /*var currTr = tab.find('tr[data-id='+schedule.id+']')
128 ,top = parseInt(currTr.find('td[name=lineNo]').text()) * 37 - half; 134 ,top = parseInt(currTr.find('td[name=lineNo]').text()) * 37 - half;
129 135
130 top = top>0?top:0; 136 top = top>0?top:0;
131 currTr.addClass('anim-delay animated flash'); 137 currTr.addClass('anim-delay animated flash');
132 - currTr.parents('._body').slimScroll({ scrollTo: top + 'px' }); 138 + currTr.parents('._body').slimScroll({ scrollTo: top + 'px' });*/
133 }); 139 });
134 }, 140 },
135 //重新计算行号 141 //重新计算行号
136 calculateLineNo: calculateLineNo 142 calculateLineNo: calculateLineNo
137 } 143 }
138 144
  145 + //获取班次所在table
  146 + function getTableBySch(sch){
  147 + var upDown = sch.xlDir==0?'up':'down';
  148 + var tab = $('#tab_line_' + sch.xlBm);
  149 + return tab.find('.pb-table[data-type='+upDown+']');
  150 + }
  151 +
  152 + //定位到班次所在的行
  153 + function goToSch(sch){
  154 + var table = getTableBySch(sch)
  155 + ,half = table.parents('._body').height() / 2
  156 + ,currTr = table.find('tr[data-id='+sch.id+']')
  157 + ,top = parseInt(currTr.find('td[name=lineNo]').text()) * 37 - half;
  158 +
  159 + top = top>0?top:0;
  160 + currTr.addClass('anim-delay animated flash');
  161 + currTr.parents('._body').slimScroll({ scrollTo: top + 'px' });
  162 + }
  163 +
139 //计算行号 164 //计算行号
140 function calculateLineNo(table){ 165 function calculateLineNo(table){
141 var rows = table.rows; 166 var rows = table.rows;
142 $.each(rows,function(i, r){ 167 $.each(rows,function(i, r){
  168 + if($(r).hasClass('child-task-list'))
  169 + return true;
  170 +
143 var cells = r.cells; 171 var cells = r.cells;
144 $(cells[0]).text(i + 1); 172 $(cells[0]).text(i + 1);
145 173
@@ -148,6 +176,9 @@ var _alone = (function(){ @@ -148,6 +176,9 @@ var _alone = (function(){
148 } 176 }
149 177
150 function splitDir(list){ 178 function splitDir(list){
  179 + /*list.sort(function(a, b){
  180 + return a.fcno - b.fcno;
  181 + });*/
151 var rs = {up: [], down: []}; 182 var rs = {up: [], down: []};
152 $.each(list, function(){ 183 $.each(list, function(){
153 if(this.xlDir == upCode) 184 if(this.xlDir == upCode)
src/main/resources/static/pages/control/line/js/data.js
@@ -8,8 +8,8 @@ var _data = (function(){ @@ -8,8 +8,8 @@ var _data = (function(){
8 8
9 //实时GPS数据 9 //实时GPS数据
10 var allGps = {}; 10 var allGps = {};
11 - //300秒刷新一次实时GPS  
12 - var realGpsT = 1000 * 300; 11 + //10秒刷新一次实时GPS
  12 + var realGpsT = 1000 * 10;
13 13
14 var dateStr = moment().format('YYYY-MM-DD'); 14 var dateStr = moment().format('YYYY-MM-DD');
15 //实际排班 15 //实际排班
@@ -29,8 +29,7 @@ var _data = (function(){ @@ -29,8 +29,7 @@ var _data = (function(){
29 var carDeviceIdMapp = {}; 29 var carDeviceIdMapp = {};
30 30
31 var fcsjSort = function(a, b){ 31 var fcsjSort = function(a, b){
32 - //return a.fcsjT - b.fcsjT;  
33 - return a.fcno - b.fcno; 32 + return (a.fcno - b.fcno) + (a.fcsjT - b.fcsjT);
34 } 33 }
35 34
36 var dataObject = { 35 var dataObject = {
@@ -289,23 +288,22 @@ var _data = (function(){ @@ -289,23 +288,22 @@ var _data = (function(){
289 for(var i = 0, gps; gps=gpsList[i++];){ 288 for(var i = 0, gps; gps=gpsList[i++];){
290 oldGps = prve[gps.deviceId]; 289 oldGps = prve[gps.deviceId];
291 if(!oldGps){ 290 if(!oldGps){
292 - //添加  
293 - prve[gps.deviceId] = gps;  
294 addArray.push(gps); 291 addArray.push(gps);
295 } 292 }
296 else if(gps.timestamp > oldGps.timestamp){ 293 else if(gps.timestamp > oldGps.timestamp){
297 //更新 294 //更新
298 upArray.push(gps); 295 upArray.push(gps);
299 } 296 }
  297 + allGps[gps.deviceId] = gps;
300 } 298 }
301 cb && cb(addArray, upArray); 299 cb && cb(addArray, upArray);
302 } 300 }
303 301
304 function getGpsError(jqXHR, textStatus){ 302 function getGpsError(jqXHR, textStatus){
305 - if(textStatus === 'error'){}  
306 - //layer.alert('获取GPS数据时,服务器出现异常', {icon: 2});  
307 - else if(textStatus === 'timeout'){}  
308 - //layer.alert('连接服务器超时', {icon: 2}); 303 + if(textStatus === 'error')
  304 + layer.alert('获取GPS数据时出现异常,请尝试刷新页面!', {icon: 2});
  305 + else if(textStatus === 'timeout')
  306 + layer.alert('连接服务器超时', {icon: 2});
309 307
310 //停止gps刷新 308 //停止gps刷新
311 clearTimeout(gpsTimer); 309 clearTimeout(gpsTimer);
src/main/resources/static/pages/control/line/js/drawSvg.js
@@ -62,6 +62,10 @@ var drawSvg = (function(){ @@ -62,6 +62,10 @@ var drawSvg = (function(){
62 //线路编码 和 单线路SVG对照 62 //线路编码 和 单线路SVG对照
63 aloneSvgMapp[lineId] = svg; 63 aloneSvgMapp[lineId] = svg;
64 }, 64 },
  65 + clear: function(){
  66 + for(var k in seGps)
  67 + seGps[k] = [];
  68 + },
65 init: function(lineId, data, container, w, mtop){ 69 init: function(lineId, data, container, w, mtop){
66 if(!data || data.length == 0) 70 if(!data || data.length == 0)
67 return; 71 return;
@@ -176,12 +180,34 @@ var drawSvg = (function(){ @@ -176,12 +180,34 @@ var drawSvg = (function(){
176 180
177 //画出GPS点 181 //画出GPS点
178 drawVehicle: function(gpsArray){ 182 drawVehicle: function(gpsArray){
  183 + if(!gpsArray || gpsArray.length == 0)
  184 + return;
  185 +
  186 + //console.log('len', gpsArray.length);
  187 + //暂时先清空重新画
  188 + var fGps = gpsArray[0];
  189 + var hSvg = homeSvgMapp[fGps.lineId]
  190 + ,aSvg = aloneSvgMapp[fGps.lineId];
  191 + //svg.selectAll('.vehci-g').remove();
  192 + if(fGps.upDown == 0){
  193 + hSvg.selectAll('.vehci-g.up').remove();
  194 + hSvg.selectAll('.start.park').remove();
  195 +
  196 + aSvg.selectAll('.vehci-g.up').remove();
  197 + aSvg.selectAll('.start.park').remove();
  198 + }
  199 + else if(fGps.upDown == 1){
  200 + hSvg.selectAll('.vehci-g.down').remove();
  201 + hSvg.selectAll('.end.park').remove();
  202 +
  203 + aSvg.selectAll('.vehci-g.down').remove();
  204 + aSvg.selectAll('.end.park').remove();
  205 + }
  206 +
179 for(var i = 0, gps; gps = gpsArray[i ++];){ 207 for(var i = 0, gps; gps = gpsArray[i ++];){
180 - //drawGpsToSvg(gps, aloneSvgMapp[gps.lineId]); 208 + drawGpsToSvg(gps, hSvg);
181 209
182 - //暂时先清空重新画  
183 - homeSvgMapp[gps.lineId].select('g.gps-g-wrap').html('');  
184 - drawGpsToSvg(gps, homeSvgMapp[gps.lineId]); 210 + drawGpsToSvg(gps, aSvg, true);
185 } 211 }
186 212
187 //画出起终点GPS信号 213 //画出起终点GPS信号
@@ -189,34 +215,42 @@ var drawSvg = (function(){ @@ -189,34 +215,42 @@ var drawSvg = (function(){
189 for(var eid in seGps){ 215 for(var eid in seGps){
190 len = seGps[eid].length; 216 len = seGps[eid].length;
191 if(len > 0){ 217 if(len > 0){
192 - var e = $('#' + eid)  
193 - ,x = parseInt(e.attr('cx'))  
194 - ,y = parseInt(e.attr('cy')); 218 + var a_e = $('#' + eid, aSvg[0])
  219 + ,a_x = parseInt(a_e.attr('cx'))
  220 + ,a_y = parseInt(a_e.attr('cy'));
  221 + tempStartAndStop(aSvg, eid, a_e, a_x, a_y);
195 222
196 - var svg = homeSvgMapp[seGps[eid][0].lineId];  
197 -  
198 - var gs = svg.append('g').classed({'start': e.attr('class').indexOf('start') != -1, 'park': true})  
199 - .selectAll('g').data(seGps[eid]).enter().append('g');  
200 - //Y轴居中  
201 - y = (y + 66) - len * 13;  
202 - gs.append('rect')  
203 - .attr('x', x + 15)  
204 - .attr('y', function(d, i){  
205 - return y + i * 27;  
206 - })  
207 - .classed({'gps-rect': true});  
208 -  
209 - gs.append('text')  
210 - .attr('x', x + 18)  
211 - .attr('y', function(d, i){  
212 - return y + i * 27 + 17;  
213 - })  
214 - .text(function(d){return cutNbbm(d.nbbm)});  
215 -  
216 - _tooltip.initStartAndEndGPS(gs); 223 + var h_e = $('#' + eid, hSvg[0])
  224 + ,h_x = parseInt(h_e.attr('cx'))
  225 + ,h_y = parseInt(h_e.attr('cy'));
  226 + tempStartAndStop(hSvg, eid ,h_e , h_x, h_y);
217 } 227 }
218 } 228 }
219 229
  230 + function tempStartAndStop(svg, eid, e, x, y){
  231 +
  232 + var gs = svg.append('g').classed({'start': e.attr('class').indexOf('start') != -1, 'park': true})
  233 + .selectAll('g').data(seGps[eid]).enter().append('g');
  234 +
  235 + //Y轴居中
  236 + y = (y + 66) - len * 13;
  237 + gs.append('rect')
  238 + .attr('x', x + 15)
  239 + .attr('y', function(d, i){
  240 + return y + i * 27;
  241 + })
  242 + .classed({'gps-rect': true});
  243 +
  244 + gs.append('text')
  245 + .attr('x', x + 18)
  246 + .attr('y', function(d, i){
  247 + return y + i * 27 + 17;
  248 + })
  249 + .text(function(d){return cutNbbm(d.nbbm)});
  250 +
  251 + _tooltip.initStartAndEndGPS(gs);
  252 + }
  253 +
220 /** 254 /**
221 * 堆叠多个GPS信号 255 * 堆叠多个GPS信号
222 */ 256 */
@@ -245,7 +279,7 @@ var drawSvg = (function(){ @@ -245,7 +279,7 @@ var drawSvg = (function(){
245 }); 279 });
246 280
247 function drawNumber(multiGps, num, that, start, end){ 281 function drawNumber(multiGps, num, that, start, end){
248 - var circle = $('#' + $(multiGps).attr('for')) 282 + /*var circle = $('#' + $(multiGps).attr('for'))
249 ,x = circle.attr('cx') 283 ,x = circle.attr('cx')
250 ,y = circle.attr('cy'); 284 ,y = circle.attr('cy');
251 285
@@ -258,23 +292,24 @@ var drawSvg = (function(){ @@ -258,23 +292,24 @@ var drawSvg = (function(){
258 numberG.classed({'end': true});//终点站 292 numberG.classed({'end': true});//终点站
259 293
260 numberG.append('rect').attr('x', x).attr('y', y); 294 numberG.append('rect').attr('x', x).attr('y', y);
261 - numberG.append('text').attr('x', x).attr('y', y).text(num); 295 + numberG.append('text').attr('x', x).attr('y', y).text(num);*/
262 } 296 }
263 } 297 }
264 }; 298 };
265 299
266 - function drawGpsToSvg(gps, svg){ 300 + function drawGpsToSvg(gps, svg, flag){
267 var stionId = gps.lineId + '_' + gps.stopNo 301 var stionId = gps.lineId + '_' + gps.stopNo
268 - ,station = $('#' + stionId) 302 + ,station = $('#' + stionId, svg[0])/*
269 ,c = station.attr('class')||"" 303 ,c = station.attr('class')||""
270 ,start = c.indexOf('start') != -1 304 ,start = c.indexOf('start') != -1
271 - ,end = c.indexOf('end') != -1; 305 + ,end = c.indexOf('end') != -1*/;
272 306
  307 + //console.log(stionId, station);
273 if(station.length == 0) 308 if(station.length == 0)
274 return; 309 return;
275 310
276 //起终点站GPS信号 311 //起终点站GPS信号
277 - if(seGps[stionId]){ 312 + if(flag && seGps[stionId]){
278 seGps[stionId].push(gps); 313 seGps[stionId].push(gps);
279 return; 314 return;
280 } 315 }
@@ -285,7 +320,7 @@ var drawSvg = (function(){ @@ -285,7 +320,7 @@ var drawSvg = (function(){
285 ,gpsGWrap = svg.select('.gps-g-wrap') 320 ,gpsGWrap = svg.select('.gps-g-wrap')
286 ,gpscont; 321 ,gpscont;
287 322
288 - if($('g[for='+stionId+']').length == 0){ 323 + if($('g[for='+stionId+']', svg[0]).length == 0){
289 gpscont = gpsGWrap.append('g') 324 gpscont = gpsGWrap.append('g')
290 .attr('class', 'station-gps-container') 325 .attr('class', 'station-gps-container')
291 .attr('updown', updown) 326 .attr('updown', updown)
@@ -338,8 +373,9 @@ var drawSvg = (function(){ @@ -338,8 +373,9 @@ var drawSvg = (function(){
338 .attr('cx', cx) 373 .attr('cx', cx)
339 .attr('cy', updown=='up'?mt:mt + p) 374 .attr('cy', updown=='up'?mt:mt + p)
340 .attr('id',function(d){ 375 .attr('id',function(d){
341 - if(d.id[0] != -1)  
342 - return lineId + '_' + d.id[0]; 376 + var i = updown=='up'?0:1;
  377 + if(d.id[i] != -1)
  378 + return lineId + '_' + d.id[i];
343 }) 379 })
344 .attr('updown', updown=='up'?0:1) 380 .attr('updown', updown=='up'?0:1)
345 .attr('class', function(d, i){ 381 .attr('class', function(d, i){
src/main/resources/static/pages/control/line/js/keyboardListen.js
@@ -24,22 +24,41 @@ $(document.body).on(&#39;keydown&#39;, function(e){ @@ -24,22 +24,41 @@ $(document.body).on(&#39;keydown&#39;, function(e){
24 success: function(){ 24 success: function(){
25 createVehSearch($('#ctrlFSearchSelect')) 25 createVehSearch($('#ctrlFSearchSelect'))
26 .on('change', function(){ 26 .on('change', function(){
27 - var array = _data.findByCl($(this).val()); 27 + var nbbm = $(this).val();
  28 + var array = _data.findByCl(nbbm);
28 if(!array || array.length == 0) 29 if(!array || array.length == 0)
29 layer.msg('没有找到相关班次信息!'); 30 layer.msg('没有找到相关班次信息!');
30 else{ 31 else{
31 - //定位到当前正在执行的班次  
32 - var sch; 32 + var tab = $('#tab_line_' + array[0].xlBm);
  33 + //清除对应tab 的样式
  34 + $('.pb-table tr.selected', tab).removeClass('selected,dir_0,dir_1');
  35 +
  36 + //console.log(tab, array[0].xlBm, array);
  37 + var runingSch,nearestSch;
  38 + //当前时间戳,忽略毫秒
  39 + var t = Date.parse(new Date());
  40 + var sch;//要定位到的班次
33 $.each(array, function(){ 41 $.each(array, function(){
  42 + //正在执行的班次
34 if(this.status == 1) 43 if(this.status == 1)
35 sch = this; 44 sch = this;
  45 +
  46 + //距离当前时间最近的班次
  47 + if(!nearestSch
  48 + || Math.abs(this.fcsjT - t) < Math.abs(nearestSch.fcsjT - t))
  49 + nearestSch = this;
  50 +
  51 + //高亮所有班次
  52 + $('.pb-table tr[data-id='+this.id+']', tab).addClass('selected dir_' + this.xlDir);
36 }); 53 });
  54 +
37 if(!sch) 55 if(!sch)
38 - sch = array[0]; 56 + sch = nearestSch;
39 57
40 var delay; 58 var delay;
41 //当前选中的选项卡 59 //当前选中的选项卡
42 - var activeTab = $('#top-tabs-wrap ul li.active a'); 60 + var activeTab = $('#top-tabs-wrap ul.top-nav li.active a');
  61 +
43 if(activeTab.data('id') == sch.xlBm){ 62 if(activeTab.data('id') == sch.xlBm){
44 //搜索的班次就在当前页面 63 //搜索的班次就在当前页面
45 delay = 0; 64 delay = 0;
@@ -52,7 +71,6 @@ $(document.body).on(&#39;keydown&#39;, function(e){ @@ -52,7 +71,6 @@ $(document.body).on(&#39;keydown&#39;, function(e){
52 } 71 }
53 72
54 setTimeout(function(){ 73 setTimeout(function(){
55 - $('.pb-table tr.selected').removeClass('selected');  
56 var tr = $('tr[data-id='+sch.id+']', tab) 74 var tr = $('tr[data-id='+sch.id+']', tab)
57 .addClass('selected search'); 75 .addClass('selected search');
58 76
@@ -65,9 +83,16 @@ $(document.body).on(&#39;keydown&#39;, function(e){ @@ -65,9 +83,16 @@ $(document.body).on(&#39;keydown&#39;, function(e){
65 $(this).removeClass('animated flash'); 83 $(this).removeClass('animated flash');
66 }); 84 });
67 }, delay); 85 }, delay);
  86 +
  87 + msg_ct('高亮车辆 ' + nbbm);
68 } 88 }
69 }).select2("open"); 89 }).select2("open");
70 } 90 }
71 }); 91 });
72 } 92 }
  93 +
  94 +
  95 + function msg_ct(t){
  96 + layer.msg(t,{offset: 'ct', shift : 5});
  97 + }
73 }); 98 });
74 \ No newline at end of file 99 \ No newline at end of file
src/main/resources/static/pages/control/line/js/main.js
@@ -42,7 +42,6 @@ @@ -42,7 +42,6 @@
42 $('#tab_home').html(homeHtmlStr); 42 $('#tab_home').html(homeHtmlStr);
43 //计算高度 40 页脚 43 //计算高度 40 页脚
44 var ah = $('#top-tabs-wrap .tab-content').height() - 40 - 5; 44 var ah = $('#top-tabs-wrap .tab-content').height() - 40 - 5;
45 - console.log(ah);  
46 $('.card_wrap').css('height', ah / 3); 45 $('.card_wrap').css('height', ah / 3);
47 46
48 //滚动条 47 //滚动条
@@ -67,28 +66,27 @@ @@ -67,28 +66,27 @@
67 var list = _data.findAllGps(); 66 var list = _data.findAllGps();
68 _data.attachSchedulInfo(list); 67 _data.attachSchedulInfo(list);
69 68
70 - drawSvg.drawVehicle(list);  
71 - 69 + //drawSvg.drawVehicle(list);
72 //按线路分组 70 //按线路分组
73 var listMap = groupByLine(list); 71 var listMap = groupByLine(list);
74 - console.log('listMap', listMap); 72 +
75 for(var key in listMap){ 73 for(var key in listMap){
76 var htmlStr = template('home_table_temp', {list: listMap[key]}); 74 var htmlStr = template('home_table_temp', {list: listMap[key]});
77 $('#tab_' + key).find('tbody').html(htmlStr); 75 $('#tab_' + key).find('tbody').html(htmlStr);
78 //更新badge 76 //更新badge
79 $('#'+key+'_badge').text('( ' + listMap[key].length + ' )'); 77 $('#'+key+'_badge').text('( ' + listMap[key].length + ' )');
  78 +
  79 + drawSvg.clear();
  80 + drawSvg.drawVehicle(listMap[key]);
80 } 81 }
81 }); 82 });
82 83
83 setTimeout(function(){ 84 setTimeout(function(){
84 //打开GPS定时刷新 85 //打开GPS定时刷新
85 _data.startRefreshGpsTimer(); 86 _data.startRefreshGpsTimer();
86 -  
87 - setTimeout(function(){  
88 - //去掉loading  
89 - $('.load-anim').fadeOut();  
90 - $('menu.menu').show();  
91 - }, 100); 87 + //去掉loading
  88 + $('.load-anim').fadeOut();
  89 + $('menu.menu').show();
92 }, 400); 90 }, 400);
93 91
94 } 92 }
src/main/resources/static/pages/control/line/js/rightMenu.js
@@ -83,11 +83,15 @@ var _menu = (function() { @@ -83,11 +83,15 @@ var _menu = (function() {
83 83
84 }); 84 });
85 85
  86 + function msg_ct(t){
  87 + layer.msg(t,{offset: 'ct', shift : 5});
  88 + }
  89 +
86 //点击路牌 90 //点击路牌
87 var lps = '.pb-table.data tr td[data-name=lpName]'; 91 var lps = '.pb-table.data tr td[data-name=lpName]';
88 $('.portlet-fullscreen').on('click', lps, function(e){ 92 $('.portlet-fullscreen').on('click', lps, function(e){
89 var lp = $(this).text(); 93 var lp = $(this).text();
90 - layer.msg('高亮路牌:' + lp + '',{offset: 'ct', shift : 5}); 94 + msg_ct('高亮路牌:' + lp);
91 var lineCode = $(this).parents('.tab-pane').data('id'); 95 var lineCode = $(this).parents('.tab-pane').data('id');
92 var schArray = _data.getLineLpMap()[lineCode][lp]; 96 var schArray = _data.getLineLpMap()[lineCode][lp];
93 97
@@ -124,7 +128,7 @@ var _menu = (function() { @@ -124,7 +128,7 @@ var _menu = (function() {
124 ,sch = _data.getSchedulById(schId); 128 ,sch = _data.getSchedulById(schId);
125 129
126 var scroll = false; 130 var scroll = false;
127 - console.log(_data.findByCl(clnbbm)); 131 +
128 $.each(_data.findByCl(clnbbm), function(){ 132 $.each(_data.findByCl(clnbbm), function(){
129 if(scroll){ 133 if(scroll){
130 var nextTr = $('tr[data-id='+this.id+']'); 134 var nextTr = $('tr[data-id='+this.id+']');
@@ -235,7 +239,7 @@ var _menu = (function() { @@ -235,7 +239,7 @@ var _menu = (function() {
235 $post('/realSchedule/outgoAdjust', params, function(rs){ 239 $post('/realSchedule/outgoAdjust', params, function(rs){
236 layer.close(index); 240 layer.close(index);
237 if(rs.t){ 241 if(rs.t){
238 - layer.msg('调整成功!'); 242 + msg_ct('调整成功!');
239 _alone.refreshSchedule(rs.t); 243 _alone.refreshSchedule(rs.t);
240 } 244 }
241 }); 245 });
@@ -245,10 +249,10 @@ var _menu = (function() { @@ -245,10 +249,10 @@ var _menu = (function() {
245 }, 249 },
246 //计划烂班 250 //计划烂班
247 planDestroy: function(schedul){ 251 planDestroy: function(schedul){
248 - /*if(schedul.status == -1){  
249 - layer.alert('不能重复烂班!', {icon: 2, title: '提示', shift: 5}); 252 + if(schedul.status == -1){
  253 + layer.alert('没必要做重复烂班!', {icon: 2, title: '提示', shift: 5});
250 return; 254 return;
251 - }*/ 255 + }
252 var array = []; 256 var array = [];
253 //获取未烂班的班次 257 //获取未烂班的班次
254 $.each(_data.getSchedulByVeh(schedul.clZbh),function(){ 258 $.each(_data.getSchedulByVeh(schedul.clZbh),function(){
@@ -325,7 +329,7 @@ var _menu = (function() { @@ -325,7 +329,7 @@ var _menu = (function() {
325 layer.close(index); 329 layer.close(index);
326 //刷新数据 330 //刷新数据
327 _alone.refreshScheduleArray(rs.list); 331 _alone.refreshScheduleArray(rs.list);
328 - layer.msg('计划烂班成功!'); 332 + msg_ct('计划烂班成功!');
329 }); 333 });
330 }); 334 });
331 return false; 335 return false;
@@ -353,10 +357,10 @@ var _menu = (function() { @@ -353,10 +357,10 @@ var _menu = (function() {
353 layer.close(index); 357 layer.close(index);
354 $post('/realSchedule/realOutAdjust', params 358 $post('/realSchedule/realOutAdjust', params
355 ,function(rs){ 359 ,function(rs){
356 - if(rs.t){  
357 - layer.msg('实发调整成功!'); 360 + if(rs.ts){
  361 + msg_ct('实发调整成功!');
358 //更新前端数据 362 //更新前端数据
359 - _alone.refreshSchedule(rs.t); 363 + _alone.refreshScheduleArray(rs.ts);
360 } 364 }
361 }); 365 });
362 }); 366 });
@@ -371,10 +375,11 @@ var _menu = (function() { @@ -371,10 +375,11 @@ var _menu = (function() {
371 shift :5, 375 shift :5,
372 }, function(){ 376 }, function(){
373 $post('/realSchedule/revokeRealOutgo', {id: schedul.id}, function(rs){ 377 $post('/realSchedule/revokeRealOutgo', {id: schedul.id}, function(rs){
374 - if(rs.t){  
375 - layer.msg('撤销实发成功!'); 378 + console.log(rs);
  379 + if(rs.ts){
  380 + msg_ct('撤销实发成功!');
376 //更新前端数据 381 //更新前端数据
377 - _alone.refreshSchedule(rs.t); 382 + _alone.refreshScheduleArray(rs.ts);
378 } 383 }
379 }); 384 });
380 }); 385 });
@@ -388,7 +393,7 @@ var _menu = (function() { @@ -388,7 +393,7 @@ var _menu = (function() {
388 }, function(){ 393 }, function(){
389 $post('/realSchedule/revokeDestroy', {id: schedul.id}, function(rs){ 394 $post('/realSchedule/revokeDestroy', {id: schedul.id}, function(rs){
390 if(rs.t){ 395 if(rs.t){
391 - layer.msg('撤销烂班成功!'); 396 + msg_ct('撤销烂班成功!');
392 //更新前端数据 397 //更新前端数据
393 _alone.refreshSchedule(rs.t); 398 _alone.refreshSchedule(rs.t);
394 } 399 }
@@ -415,7 +420,7 @@ var _menu = (function() { @@ -415,7 +420,7 @@ var _menu = (function() {
415 || rs.status == 200){ 420 || rs.status == 200){
416 //刷新数据 421 //刷新数据
417 _alone.refreshScheduleArray(rs.list); 422 _alone.refreshScheduleArray(rs.list);
418 - layer.msg('调整间隔成功!'); 423 + msg_ct('调整间隔成功!');
419 } 424 }
420 }, 425 },
421 error: errorHandle 426 error: errorHandle
@@ -451,7 +456,7 @@ var _menu = (function() { @@ -451,7 +456,7 @@ var _menu = (function() {
451 }, 456 },
452 //调整人车 457 //调整人车
453 vehicAndPerAdjust: function(schedul){ 458 vehicAndPerAdjust: function(schedul){
454 - $.get('/pages/control/line/child_pages/vehicAndper_adjust.html', function(content){ 459 + $.get('/pages/control/line/child_pages/car_and_persion.html', function(content){
455 layer.open({ 460 layer.open({
456 type: 1, 461 type: 1,
457 area: '730px', 462 area: '730px',
@@ -483,7 +488,10 @@ var _menu = (function() { @@ -483,7 +488,10 @@ var _menu = (function() {
483 $.post('/directive/dispatch', {id: schedul.id}, 488 $.post('/directive/dispatch', {id: schedul.id},
484 function(code){ 489 function(code){
485 if(code == 0){ 490 if(code == 0){
486 - layer.msg('发送成功'); 491 + msg_ct('发送成功');
  492 + }
  493 + else if(code == -2){
  494 + layer.alert('该班次发车时间距离当前时间较远,系统阻止了该调度指令的下发。', {icon: 2, title: '被拦截的指令'});
487 } 495 }
488 else 496 else
489 layer.alert('发送调度指令失败', {icon: 2, title: '操作失败'}); 497 layer.alert('发送调度指令失败', {icon: 2, title: '操作失败'});
@@ -494,7 +502,7 @@ var _menu = (function() { @@ -494,7 +502,7 @@ var _menu = (function() {
494 schInfoFineTune: function(schedul){ 502 schInfoFineTune: function(schedul){
495 var index = layer.open({ 503 var index = layer.open({
496 type: 1, 504 type: 1,
497 - area: '630px', 505 + area: '680px',
498 maxmin: true, 506 maxmin: true,
499 content: template('schinfo_fine_tune_temp', schedul), 507 content: template('schinfo_fine_tune_temp', schedul),
500 shift: 5, 508 shift: 5,
@@ -538,11 +546,11 @@ var _menu = (function() { @@ -538,11 +546,11 @@ var _menu = (function() {
538 546
539 $post('/realSchedule/schInfoFineTune', params, function(rs){ 547 $post('/realSchedule/schInfoFineTune', params, function(rs){
540 layer.close(index); 548 layer.close(index);
541 - if(rs.t)  
542 - _alone.refreshSchedule(rs.t); 549 + if(rs.ts)
  550 + _alone.refreshScheduleArray(rs.ts);
543 551
544 - if(rs.nextSch)  
545 - _alone.refreshSchedule(rs.nextSch); 552 + /*if(rs.nextSch)
  553 + _alone.refreshSchedule(rs.nextSch);*/
546 }); 554 });
547 }); 555 });
548 } 556 }
@@ -550,7 +558,7 @@ var _menu = (function() { @@ -550,7 +558,7 @@ var _menu = (function() {
550 }, 558 },
551 //基于车辆的待发调整 559 //基于车辆的待发调整
552 outgoAdjustAll: function(schedul){ 560 outgoAdjustAll: function(schedul){
553 - $.get('/pages/control/line/child_pages/outgo_adjust_all.html', function(content){ 561 + $.get('/pages/control/line/child_pages/dfsj_batch.html', function(content){
554 layer.open({ 562 layer.open({
555 type: 1, 563 type: 1,
556 area: '830px', 564 area: '830px',
src/main/resources/static/pages/control/line/temps/alone_tp.html
@@ -20,7 +20,6 @@ @@ -20,7 +20,6 @@
20 <td>待发</td> 20 <td>待发</td>
21 <td>实发</td> 21 <td>实发</td>
22 <td class="hide-lt-1080">原因</td> 22 <td class="hide-lt-1080">原因</td>
23 - <!--<td>类型</td>-->  
24 </tr> 23 </tr>
25 </thead> 24 </thead>
26 </table> 25 </table>
@@ -52,7 +51,6 @@ @@ -52,7 +51,6 @@
52 <td>待发</td> 51 <td>待发</td>
53 <td>实发</td> 52 <td>实发</td>
54 <td class="hide-lt-1080">原因</td> 53 <td class="hide-lt-1080">原因</td>
55 - <!--<td>类型</td>-->  
56 </tr> 54 </tr>
57 </thead> 55 </thead>
58 </table> 56 </table>
@@ -136,7 +134,7 @@ @@ -136,7 +134,7 @@
136 <td data-name="dfsj" data-time="{{item.zdsjT}}">{{item.dfsj}}</td> 134 <td data-name="dfsj" data-time="{{item.zdsjT}}">{{item.dfsj}}</td>
137 135
138 {{if item.status == -1}} 136 {{if item.status == -1}}
139 - <td class="tl-qrlb sfsj-item">烂班</td> 137 + <td class="tl-qrlb sfsj-item" >烂班</td>
140 138
141 {{else if item.status == 2}} 139 {{else if item.status == 2}}
142 <td data-name="sjfcsj" class="tl-yzx sfsj-item">{{item.fcsjActual == null?"?":item.fcsjActual}}<span class="fcsj-diff">{{item.fcsj_diff}}</span></td> 140 <td data-name="sjfcsj" class="tl-yzx sfsj-item">{{item.fcsjActual == null?"?":item.fcsjActual}}<span class="fcsj-diff">{{item.fcsj_diff}}</span></td>
@@ -148,13 +146,35 @@ @@ -148,13 +146,35 @@
148 <td data-name="sjfcsj" class="sfsj-item">{{item.fcsjActual}}<span class="fcsj-diff">{{item.fcsj_diff}}</span></td> 146 <td data-name="sjfcsj" class="sfsj-item">{{item.fcsjActual}}<span class="fcsj-diff">{{item.fcsj_diff}}</span></td>
149 {{/if}} 147 {{/if}}
150 148
151 - <td class="hide-lt-1080" data-name="remarks">  
152 - {{if item.remarks != null && item.length > 0}}  
153 - <a class="remarks-popover" href="javascript:;" data-toggle="popover" data-content="{{item.remarks}}" >备注...</a> 149 +<td class="hide-lt-1080" data-name="remarks">
  150 + {{if item.remarks != null && item.remarks.length > 0}}
  151 + <a class="remarks-popover" href="javascript:;" data-toggle="popover" data-content="{{item.remarks}}" >查看...</a>
154 {{/if}} 152 {{/if}}
155 </td> 153 </td>
156 - <!--<td><a href="javascript:;">主</a></td>-->  
157 - </tr> 154 +</tr>
  155 +
  156 +{{if item.cTasks.length > 0}}
  157 +<!-- 子任务列表
  158 +<tr class="child-task-list">
  159 +<td></td>
  160 +<td colspan=9>
  161 +<div>
  162 +{{each item.cTasks as task j}}
  163 + <div>
  164 + <span>{{task.startStationName}}</span>
  165 + <span>{{task.endStationName}}</span>
  166 + <span>{{task.startDate}}</span>
  167 + <span>{{task.endDate}}</span>
  168 + <span>{{task.mileageType}}</span>
  169 + </div>
  170 +{{/each}}
  171 +</div>
  172 +</td>
  173 +</tr>
  174 +-->
  175 +{{/if}}
  176 +
  177 +
158 {{/each}} 178 {{/each}}
159 </script> 179 </script>
160 180
@@ -267,7 +287,7 @@ @@ -267,7 +287,7 @@
267 </div> 287 </div>
268 <hr> 288 <hr>
269 <div class="form-custom-footer"> 289 <div class="form-custom-footer">
270 - <button type="button" class="btn blue-madison confirm"> <i class="fa fa-check"></i> &nbsp;&nbsp;确&nbsp;&nbsp;定 </button> 290 + <button type="button" class="btn blue-madison confirm"> <i class="fa fa-check"></i> &nbsp;&nbsp;定 </button>
271 <button type="button" class="btn layui-layer-close"> 取消 </button> 291 <button type="button" class="btn layui-layer-close"> 取消 </button>
272 </div> 292 </div>
273 </div> 293 </div>
@@ -345,7 +365,7 @@ @@ -345,7 +365,7 @@
345 365
346 <hr> 366 <hr>
347 <div class="form-custom-footer"> 367 <div class="form-custom-footer">
348 - <button type="button" class="btn blue-madison confirm"> <i class="fa fa-check"></i> &nbsp;&nbsp;确&nbsp;&nbsp;定 </button> 368 + <button type="button" class="btn blue-madison confirm"> <i class="fa fa-check"></i> &nbsp;&nbsp;定 </button>
349 <button type="button" class="btn layui-layer-close"> 取消 </button> 369 <button type="button" class="btn layui-layer-close"> 取消 </button>
350 </div> 370 </div>
351 </form> 371 </form>
@@ -442,7 +462,7 @@ @@ -442,7 +462,7 @@
442 462
443 <hr> 463 <hr>
444 <div class="form-custom-footer"> 464 <div class="form-custom-footer">
445 - <button type="button" class="btn blue-madison confirm"> <i class="fa fa-check"></i> &nbsp;&nbsp;确&nbsp;&nbsp;定 </button> 465 + <button type="button" class="btn blue-madison confirm"> <i class="fa fa-check"></i> &nbsp;&nbsp;定 </button>
446 <button type="button" class="btn layui-layer-close"> 取消 </button> 466 <button type="button" class="btn layui-layer-close"> 取消 </button>
447 </div> 467 </div>
448 </div> 468 </div>
@@ -491,7 +511,7 @@ @@ -491,7 +511,7 @@
491 </div> 511 </div>
492 <hr> 512 <hr>
493 <div class="form-custom-footer"> 513 <div class="form-custom-footer">
494 - <button type="button" class="btn blue-madison confirm"> <i class="fa fa-check"></i> &nbsp;&nbsp;确&nbsp;&nbsp;定 </button> 514 + <button type="button" class="btn blue-madison confirm"> <i class="fa fa-check"></i> &nbsp;&nbsp;定 </button>
495 <button type="button" class="btn layui-layer-close"> 取消 </button> 515 <button type="button" class="btn layui-layer-close"> 取消 </button>
496 </div> 516 </div>
497 </form> 517 </form>
src/main/resources/static/pages/forms/mould/waybill.xls
No preview for this file type
src/main/resources/static/pages/mapmonitor/real/css/real.css
@@ -503,7 +503,7 @@ html{ @@ -503,7 +503,7 @@ html{
503 503
504 .mapRightWrap .search_result .item_vehicle_list{ 504 .mapRightWrap .search_result .item_vehicle_list{
505 margin-bottom: 20px; 505 margin-bottom: 20px;
506 - border-bottom: 1px solid #F3F5F5; 506 + /* border-bottom: 1px solid #F3F5F5; */
507 } 507 }
508 508
509 .mapRightWrap .search_result .item_vehicle{ 509 .mapRightWrap .search_result .item_vehicle{
@@ -696,7 +696,7 @@ display: none; @@ -696,7 +696,7 @@ display: none;
696 .play-back-btns{ 696 .play-back-btns{
697 display: none; 697 display: none;
698 background: rgb(255, 255, 255); 698 background: rgb(255, 255, 255);
699 - width: 206px; 699 + width: 216px;
700 height: 44px; 700 height: 44px;
701 position: absolute; 701 position: absolute;
702 right: 320px; 702 right: 320px;
@@ -776,7 +776,7 @@ display: none; @@ -776,7 +776,7 @@ display: none;
776 font-size: 15px; 776 font-size: 15px;
777 vertical-align: middle; 777 vertical-align: middle;
778 font-weight: 600; 778 font-weight: 600;
779 - margin-right: 12px; 779 + margin-right: 5px;
780 color: #565555; 780 color: #565555;
781 padding: 4px 8px 4px 13px; 781 padding: 4px 8px 4px 13px;
782 cursor: pointer; 782 cursor: pointer;
src/main/resources/static/pages/mapmonitor/real/js/map_platform.js
@@ -51,6 +51,8 @@ var realMap = (function() { @@ -51,6 +51,8 @@ var realMap = (function() {
51 //百度 -轨迹回放点聚合 51 //百度 -轨迹回放点聚合
52 //var historyClusterer; 52 //var historyClusterer;
53 53
  54 + var markerClusterer;
  55 +
54 //设备号和marker对照 56 //设备号和marker对照
55 var markersMap; 57 var markersMap;
56 var real_map = { 58 var real_map = {
@@ -125,6 +127,8 @@ var realMap = (function() { @@ -125,6 +127,8 @@ var realMap = (function() {
125 }, 127 },
126 clear: function(){ 128 clear: function(){
127 currentMap.map.clearOverlays(); 129 currentMap.map.clearOverlays();
  130 + markerClusterer && markerClusterer.clearMarkers();
  131 +
128 }, 132 },
129 change : function() { 133 change : function() {
130 if(currentMap.mapName == REAL_BAIDU_TEXT) 134 if(currentMap.mapName == REAL_BAIDU_TEXT)
@@ -212,7 +216,9 @@ var realMap = (function() { @@ -212,7 +216,9 @@ var realMap = (function() {
212 drawGpsMarker: function(gpsList){ 216 drawGpsMarker: function(gpsList){
213 markersMap = {}; 217 markersMap = {};
214 var map = currentMap.map; 218 var map = currentMap.map;
215 - var markerClusterer = new BMapLib.MarkerClusterer(map, {isAverangeCenter : true,minClusterSize : 3}); 219 +
  220 + markerClusterer && markerClusterer.clearMarkers();
  221 + markerClusterer = new BMapLib.MarkerClusterer(map, {isAverangeCenter : true,minClusterSize : 3});
216 real_map.baidu.coordsConvert(gpsList, function(){ 222 real_map.baidu.coordsConvert(gpsList, function(){
217 //绘制车辆位置 223 //绘制车辆位置
218 var marker; 224 var marker;
src/main/resources/static/pages/mapmonitor/real/js/playBack.js
@@ -102,8 +102,11 @@ var playBack = (function() { @@ -102,8 +102,11 @@ var playBack = (function() {
102 marker = markerMap[gps.nbbm]; 102 marker = markerMap[gps.nbbm];
103 if(marker) 103 if(marker)
104 getCurrMap().moveMarker(marker, gps);//移动marker 104 getCurrMap().moveMarker(marker, gps);//移动marker
105 - else 105 + else{
106 markerMap[gps.nbbm] = getCurrMap().addHistoryMarker(gps);//添加marker 106 markerMap[gps.nbbm] = getCurrMap().addHistoryMarker(gps);//添加marker
  107 + //定位到marker
  108 + getCurrMap().markerToCenter(markerMap[gps.nbbm]);
  109 + }
107 110
108 if(gps.inout_stop != -1){ 111 if(gps.inout_stop != -1){
109 //到离站信息 112 //到离站信息
@@ -123,6 +126,8 @@ var playBack = (function() { @@ -123,6 +126,8 @@ var playBack = (function() {
123 function addInOutText(gps){ 126 function addInOutText(gps){
124 var info = gps.inout_stop_info 127 var info = gps.inout_stop_info
125 ,date = moment(gps.ts).format('HH:mm.ss'); 128 ,date = moment(gps.ts).format('HH:mm.ss');
  129 + if(!info)
  130 + return;
126 var html = '<div class="pback-logs-item">'+ 131 var html = '<div class="pback-logs-item">'+
127 gps.nbbm + ' '+ (info.inOut==1?'出':'进') +'站 '+info.stopName+' '+ 132 gps.nbbm + ' '+ (info.inOut==1?'出':'进') +'站 '+info.stopName+' '+
128 '<span class="pback-logs-item-date">'+ date +'</span>'+ 133 '<span class="pback-logs-item-date">'+ date +'</span>'+
src/main/resources/static/pages/mapmonitor/real/js/real.js
@@ -41,9 +41,9 @@ @@ -41,9 +41,9 @@
41 } 41 }
42 var method = $(this).data('click'); 42 var method = $(this).data('click');
43 43
44 - /*if (!method || playAnimation) 44 + if (!method /*|| playAnimation*/)
45 return; 45 return;
46 - playAnimation = true;*/ 46 + //playAnimation = true;
47 47
48 $('.mapTools').addClass('disable'); 48 $('.mapTools').addClass('disable');
49 $('.mapTools div.item.active').removeClass('active'); 49 $('.mapTools div.item.active').removeClass('active');
src/main/resources/static/pages/mapmonitor/real/js/search.js
@@ -8,25 +8,64 @@ var searchPanel = (function() { @@ -8,25 +8,64 @@ var searchPanel = (function() {
8 return realMap[realMap.getMap().fName]; 8 return realMap[realMap.getMap().fName];
9 } 9 }
10 10
  11 + var allGps;
  12 +
11 var exports = { 13 var exports = {
12 init : function() { 14 init : function() {
13 var htmlStr = template('search_panel_temp', {}); 15 var htmlStr = template('search_panel_temp', {});
14 $('.mapRightWrap').html(htmlStr); 16 $('.mapRightWrap').html(htmlStr);
15 17
16 - // 建立一个自动完成的对象 18 + //focus
  19 + //焦点时获取所有的gps
  20 + $('#realSearchInput').on('focus', function(){
  21 + allGps = vehiclePanel.getAllGps();
  22 + console.log('focus', allGps);
  23 + })
  24 + .on('keyup', function(){
  25 + var t = $(this).val()
  26 + ,list = [];
  27 +
  28 + $.each(allGps, function(){
  29 + if(this.nbbm.indexOf(t) == -1)
  30 + return true;
  31 +
  32 + this.fromNow = moment(this.timestamp).fromNow();
  33 + list.push(this);
  34 + });
  35 +
  36 + var resultHtml = template('search_result_temp', {list: list});
  37 + $('.mapRightWrap .search_result').html(resultHtml);
  38 + });
17 39
18 - getCurr().autocomplete('realSearchInput', function(json){  
19 - console.log(json); 40 + $('.search_result').on('click', '.result_item' ,function(){
  41 + console.log($(this).data('device'));
  42 + });
  43 +
  44 + //var allGps = vehiclePanel.getAllCars();
  45 + /*$('#realSearchInput').on('keyup', function(){
  46 + var t = $(this).val()
  47 + ,array = [];
  48 + $.each(allCars, function(i, nbbm){
  49 + if(nbbm.indexOf(t) != -1)
  50 + array.push(nbbm);
  51 + });
  52 + });*/
  53 + // 建立一个自动完成的对象
  54 + /*getCurr().autocomplete('realSearchInput', function(json){
  55 +
20 var resultHtml = template('search_result_temp', json); 56 var resultHtml = template('search_result_temp', json);
21 $('.mapRightWrap .search_result').html(resultHtml); 57 $('.mapRightWrap .search_result').html(resultHtml);
  58 + //搜索车辆
  59 + //console.log(json);
22 }); 60 });
23 61
24 //查询结果选中事件 62 //查询结果选中事件
25 $('.search_result').on('click', '.result_item' 63 $('.search_result').on('click', '.result_item'
26 ,function(){ 64 ,function(){
27 65
28 - getCurr().setPlace($(this).data('title'));  
29 - }); 66 + console.log(this);
  67 + //getCurr().setPlace($(this).data('title'));
  68 + });*/
30 } 69 }
31 }; 70 };
32 71
src/main/resources/static/pages/mapmonitor/real/js/vehicle.js
@@ -4,6 +4,10 @@ @@ -4,6 +4,10 @@
4 4
5 var vehiclePanel = (function() { 5 var vehiclePanel = (function() {
6 6
  7 + //设备号和marker映射
  8 + var gpsMarker = {}
  9 + ,cLineCode;// 当前线路编码
  10 +
7 function getCurrMap(){ 11 function getCurrMap(){
8 return realMap[realMap.getMap().fName]; 12 return realMap[realMap.getMap().fName];
9 } 13 }
@@ -16,6 +20,7 @@ var vehiclePanel = (function() { @@ -16,6 +20,7 @@ var vehiclePanel = (function() {
16 // 手风琴收拢 20 // 手风琴收拢
17 $('.mapRightWrap').on('hide.bs.collapse', '.panel-collapse', function() { 21 $('.mapRightWrap').on('hide.bs.collapse', '.panel-collapse', function() {
18 $(this).prev().find('span.icon').addClass('rotate'); 22 $(this).prev().find('span.icon').addClass('rotate');
  23 + cLineCode = null;
19 }); 24 });
20 25
21 // 手风琴展开 26 // 手风琴展开
@@ -24,18 +29,31 @@ var vehiclePanel = (function() { @@ -24,18 +29,31 @@ var vehiclePanel = (function() {
24 var lineCode = $(this).data('line'); 29 var lineCode = $(this).data('line');
25 //收拢其他 30 //收拢其他
26 closeAll(); 31 closeAll();
27 - drawLineAndGps(lineCode); 32 + cLineCode = lineCode;
  33 + drawLineAndGps(lineCode, function(){
  34 + //从storage里获取路由数据
  35 + var route = JSON.parse(storage.getItem(lineCode + '_route'));
  36 + //在地图上画出线路
  37 + getCurrMap().drawLine(route);
  38 + });
28 }); 39 });
29 40
30 //绘制线路和GPS 41 //绘制线路和GPS
31 - function drawLineAndGps(lineCode){ 42 + function drawLineAndGps(lineCode, callFun){
32 //过滤出该线路的GPS点 43 //过滤出该线路的GPS点
33 - var showList = [];  
34 - if(lineGps[lineCode]){ 44 + var showList = [], gps;
  45 + /*if(lineGps[lineCode]){
35 $.each(lineGps[lineCode], function(){ 46 $.each(lineGps[lineCode], function(){
36 - showList.push(allGps[this]); 47 + gps = allGps[this];
  48 + showList.push(gps);
  49 + gpsMarker[gps.deviceId] = gps;
37 }); 50 });
  51 + }*/
  52 + for(var dId in allGps){
  53 + if(allGps[dId].lineId == lineCode)
  54 + showList.push(allGps[dId]);
38 } 55 }
  56 +
39 //显示车辆列表 57 //显示车辆列表
40 var htmlStr = template('vehicle_panel_collapse_temp', {list: showList}); 58 var htmlStr = template('vehicle_panel_collapse_temp', {list: showList});
41 $('#collapse_' + lineCode).html(htmlStr); 59 $('#collapse_' + lineCode).html(htmlStr);
@@ -45,13 +63,10 @@ var vehiclePanel = (function() { @@ -45,13 +63,10 @@ var vehiclePanel = (function() {
45 */ 63 */
46 var that = $(this); 64 var that = $(this);
47 setTimeout(function(){ 65 setTimeout(function(){
48 - //在地图上画出线路  
49 - var mapObj = getCurrMap();  
50 - //从storage里获取路由数据  
51 - var route = JSON.parse(storage.getItem(lineCode + '_route'));  
52 - mapObj.drawLine(route); 66 + callFun && callFun();
53 //画GPS 67 //画GPS
54 - mapObj.drawGpsMarker(showList); 68 + getCurrMap().drawGpsMarker(showList);
  69 +
55 }, 500); 70 }, 500);
56 } 71 }
57 72
@@ -70,23 +85,36 @@ var vehiclePanel = (function() { @@ -70,23 +85,36 @@ var vehiclePanel = (function() {
70 85
71 //GPS刷新事件 86 //GPS刷新事件
72 var allGps = {}; 87 var allGps = {};
73 - var lineGps = {}; 88 + //var lineGps = {};
74 $('#mapContainer').on('gps_refresh', function(e, add, up){ 89 $('#mapContainer').on('gps_refresh', function(e, add, up){
75 var temp = add; 90 var temp = add;
76 if(up) 91 if(up)
77 temp = temp.concat(up); 92 temp = temp.concat(up);
78 93
  94 + var gps;
79 if(!$(this).is(":hidden")){ 95 if(!$(this).is(":hidden")){
80 $.each(temp, function(){ 96 $.each(temp, function(){
81 allGps[this.deviceId] = this; 97 allGps[this.deviceId] = this;
82 }); 98 });
83 99
84 - $.each(add, function(){ 100 + /* $.each(add, function(){
85 if(!lineGps[this.lineId]) 101 if(!lineGps[this.lineId])
86 lineGps[this.lineId] = []; 102 lineGps[this.lineId] = [];
87 //线路和设备号映射 103 //线路和设备号映射
88 - lineGps[this.lineId].push(this.deviceId);  
89 - }) 104 + //lineGps[this.lineId].push(this.deviceId);
  105 + })*/
  106 + }
  107 +
  108 + //先暂时重绘,后面再优化
  109 + if(cLineCode){
  110 + drawLineAndGps(cLineCode);
  111 + /*var showList = [];
  112 + if(lineGps[cLineCode]){
  113 + $.each(lineGps[cLineCode], function(){
  114 + showList.push(allGps[this]);
  115 + });
  116 + }
  117 + mapObj.drawGpsMarker(showList);*/
90 } 118 }
91 }); 119 });
92 120
@@ -126,6 +154,21 @@ var vehiclePanel = (function() { @@ -126,6 +154,21 @@ var vehiclePanel = (function() {
126 }, 154 },
127 drawLineAndGps: function(lineCode){ 155 drawLineAndGps: function(lineCode){
128 drawLineAndGps(lineCode); 156 drawLineAndGps(lineCode);
  157 + },
  158 + //获取所有的车辆 - 从GPS定时定距里查询
  159 + getAllGps: function(){
  160 + var array = [];
  161 + /*var array = [
  162 + {nbbm: 'B-91524', state: 0, timestamp: 1469427233000, stationName: '金桥路浦东大道', lineId: 1024, lon: 121.504921, lat: 31.086559, deviceId: 000},
  163 + {nbbm: 'B-91334', state: 1, timestamp: 1469427233000, stationName: '博山东路', lineId: 1024, lon: 121.504921, lat: 31.086559, deviceId: 111},
  164 + {nbbm: 'B-91224', state: 0, timestamp: 1469427233000, stationName: '闵浦大桥', lineId: 1024, lon: 121.504921, lat: 31.086559, deviceId: 222},
  165 + {nbbm: 'B-91124', state: 0, timestamp: 1469427312000, stationName: '旧金山', lineId: 1024, lon: 121.504921, lat: 31.086559, deviceId: 333},
  166 + {nbbm: 'B-91924', state: -1, timestamp: 1469427233000, stationName: '硅谷', lineId: 1024, lon: 121.504921, lat: 31.086559, deviceId: 444},
  167 + {nbbm: 'B-92224', state: 0, timestamp: 1469427312000, stationName: '意大利', lineId: 1024, lon: 121.504921, lat: 31.086559, deviceId: 555}
  168 + ];*/
  169 + for(var deviceId in allGps)
  170 + array.push(allGps[deviceId]);
  171 + return array;
129 } 172 }
130 }; 173 };
131 174
src/main/resources/static/pages/mapmonitor/real/temps/search.html
1 <script id="search_panel_temp" type="text/html"> 1 <script id="search_panel_temp" type="text/html">
2 <div class="input-group"> 2 <div class="input-group">
3 - <input type="text" id="realSearchInput" class="form-control" placeholder="车辆自编号/地图位置..."> 3 + <input type="text" id="realSearchInput" class="form-control" placeholder="车辆自编号搜索...">
4 <span class="input-group-btn"> 4 <span class="input-group-btn">
5 <button class="btn" type="button"><i class="fa fa-search"></i> 搜索</button> 5 <button class="btn" type="button"><i class="fa fa-search"></i> 搜索</button>
6 </span> 6 </span>
@@ -11,19 +11,18 @@ @@ -11,19 +11,18 @@
11 </script> 11 </script>
12 12
13 <script id="search_result_temp" type="text/html"> 13 <script id="search_result_temp" type="text/html">
14 -  
15 - <div class="item_vehicle_list">  
16 - <p class="result_item item_vehicle">  
17 - <i class="fa fa-circle font-green-jungle"></i> &nbsp;W1B-023 &nbsp;&nbsp;-营运中<br>  
18 - <span class="sub_text">开往 金桥路浦东大道 站(30秒前)</span> 14 +<div class="item_vehicle_list">
  15 +{{each list as gps i}}
  16 + <p class="result_item item_vehicle" data-device={{gps.deviceId}}>
  17 + &nbsp;{{gps.nbbm}} &nbsp;&nbsp;- {{if gps.state==0}}营运中{{else if gps.state==1}}非营运{{else}}未知营运状态{{/if}}<br>
  18 + <span class="sub_text"> {{gps.stationName}}({{gps.fromNow}} 更新)</span>
19 </p> 19 </p>
20 20
21 - <p class="result_item item_vehicle">  
22 - <i class="fa fa-circle font-green-jungle"></i> &nbsp;W2C-578 &nbsp;&nbsp;-营运中<br>  
23 - <span class="sub_text">开往 张江路华谊路 站(刚刚)</span>  
24 - </p>  
25 - </div> 21 +{{/each}}
  22 +</div>
  23 +</script>
26 24
  25 +<!--
27 {{if type == "baidu"}} 26 {{if type == "baidu"}}
28 {{each result as obj i}} 27 {{each result as obj i}}
29 <p class="result_item" data-title="{{obj.business}}"> 28 <p class="result_item" data-title="{{obj.business}}">
@@ -39,4 +38,4 @@ @@ -39,4 +38,4 @@
39 </p> 38 </p>
40 {{/each}} 39 {{/each}}
41 {{/if}} 40 {{/if}}
42 -</script> 41 + -->
43 \ No newline at end of file 42 \ No newline at end of file
src/main/resources/static/pages/mapmonitor/real/temps/vehicle.html
@@ -34,7 +34,7 @@ @@ -34,7 +34,7 @@
34 <span style="font-size: 13px;">{{gpsObj.stationName}}</span> 34 <span style="font-size: 13px;">{{gpsObj.stationName}}</span>
35 </div> 35 </div>
36 <div class="icon"> 36 <div class="icon">
37 - <i class="fa fa-file-text-o"></i> 37 + <!--<i class="fa fa-file-text-o"></i>-->
38 </div> 38 </div>
39 </div> 39 </div>
40 {{/each}} 40 {{/each}}