Commit 0d2d4166125ca107b17002783cdf4098daa5efa0

Authored by 潘钊
1 parent dbb8dd28

1、停车场即时首发站的班次做双休依赖

Showing 45 changed files with 1347 additions and 235 deletions
src/main/java/com/bsth/StartCommand.java
1 package com.bsth; 1 package com.bsth;
2 2
3 3
4 -import com.bsth.entity.Cars;  
5 -import com.bsth.entity.Line;  
6 -import com.bsth.entity.schedule.CarConfigInfo;  
7 import com.bsth.repository.schedule.CarConfigInfoRepository; 4 import com.bsth.repository.schedule.CarConfigInfoRepository;
8 import com.bsth.security.SecurityMetadataSourceService; 5 import com.bsth.security.SecurityMetadataSourceService;
9 import com.bsth.service.realcontrol.buffer.GetSchedulePlanThread; 6 import com.bsth.service.realcontrol.buffer.GetSchedulePlanThread;
@@ -13,17 +10,15 @@ import com.bsth.vehicle.common.CommonRefreshThread; @@ -13,17 +10,15 @@ import com.bsth.vehicle.common.CommonRefreshThread;
13 import com.bsth.vehicle.directive.service.DirectiveService; 10 import com.bsth.vehicle.directive.service.DirectiveService;
14 import com.bsth.vehicle.directive.thread.DirectivePersistenceThread; 11 import com.bsth.vehicle.directive.thread.DirectivePersistenceThread;
15 import com.bsth.vehicle.directive.thread.FirstScheduleIssuedThread; 12 import com.bsth.vehicle.directive.thread.FirstScheduleIssuedThread;
16 -import com.bsth.vehicle.gpsdata.GpsArrivalStationThread; 13 +import com.bsth.vehicle.gpsdata.GpsArrivalThread;
17 import com.bsth.vehicle.gpsdata.GpsRefreshThread; 14 import com.bsth.vehicle.gpsdata.GpsRefreshThread;
  15 +
18 import org.slf4j.Logger; 16 import org.slf4j.Logger;
19 import org.slf4j.LoggerFactory; 17 import org.slf4j.LoggerFactory;
20 import org.springframework.beans.factory.annotation.Autowired; 18 import org.springframework.beans.factory.annotation.Autowired;
21 import org.springframework.boot.CommandLineRunner; 19 import org.springframework.boot.CommandLineRunner;
22 import org.springframework.stereotype.Component; 20 import org.springframework.stereotype.Component;
23 21
24 -import java.util.List;  
25 -import java.util.Timer;  
26 -import java.util.TimerTask;  
27 import java.util.concurrent.Executors; 22 import java.util.concurrent.Executors;
28 import java.util.concurrent.ScheduledExecutorService; 23 import java.util.concurrent.ScheduledExecutorService;
29 import java.util.concurrent.TimeUnit; 24 import java.util.concurrent.TimeUnit;
@@ -54,7 +49,7 @@ public class StartCommand implements CommandLineRunner{ @@ -54,7 +49,7 @@ public class StartCommand implements CommandLineRunner{
54 @Autowired 49 @Autowired
55 SchedulePersistenceThread SchedulePersistenceThread; 50 SchedulePersistenceThread SchedulePersistenceThread;
56 @Autowired 51 @Autowired
57 - GpsArrivalStationThread gpsArrivalStationThread; 52 + GpsArrivalThread gpsArrivalStationThread;
58 @Autowired 53 @Autowired
59 FirstScheduleIssuedThread firstScheduleIssuedThread; 54 FirstScheduleIssuedThread firstScheduleIssuedThread;
60 55
@@ -108,7 +103,7 @@ public class StartCommand implements CommandLineRunner{ @@ -108,7 +103,7 @@ public class StartCommand implements CommandLineRunner{
108 * 每15秒从数据库抓取到离站信息和班次匹配 103 * 每15秒从数据库抓取到离站信息和班次匹配
109 * (网关生成的到离站数据也是延迟批量入库,所以缩短该线程执行周期并不会提高 “实际到离站” 的实时性) 104 * (网关生成的到离站数据也是延迟批量入库,所以缩短该线程执行周期并不会提高 “实际到离站” 的实时性)
110 */ 105 */
111 - scheduler.scheduleWithFixedDelay(gpsArrivalStationThread, 35, 1200, TimeUnit.SECONDS); 106 + //scheduler.scheduleWithFixedDelay(gpsArrivalStationThread, 15, 20, TimeUnit.SECONDS);
112 107
113 /** 108 /**
114 * 首个调度指令下发(2分钟运行一次) 109 * 首个调度指令下发(2分钟运行一次)
@@ -117,6 +112,62 @@ public class StartCommand implements CommandLineRunner{ @@ -117,6 +112,62 @@ public class StartCommand implements CommandLineRunner{
117 */ 112 */
118 scheduler.scheduleWithFixedDelay(firstScheduleIssuedThread, 60 , 60 * 2, TimeUnit.SECONDS); 113 scheduler.scheduleWithFixedDelay(firstScheduleIssuedThread, 60 , 60 * 2, TimeUnit.SECONDS);
119 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);*/
120 171
121 /* //延迟一会 172 /* //延迟一会
122 new Timer().schedule(new TimerTask() { 173 new Timer().schedule(new TimerTask() {
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,12 +11,21 @@ import org.apache.commons.lang3.StringUtils; @@ -9,12 +11,21 @@ import org.apache.commons.lang3.StringUtils;
9 import java.text.ParseException; 11 import java.text.ParseException;
10 import java.text.SimpleDateFormat; 12 import java.text.SimpleDateFormat;
11 import java.util.Date; 13 import java.util.Date;
  14 +import java.util.HashSet;
  15 +import java.util.Set;
12 16
13 /** 17 /**
14 * 实际排班计划明细。 18 * 实际排班计划明细。
15 */ 19 */
16 @Entity 20 @Entity
17 @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 +})
18 public class ScheduleRealInfo { 29 public class ScheduleRealInfo {
19 /** 主键Id */ 30 /** 主键Id */
20 @Id 31 @Id
@@ -26,6 +37,7 @@ public class ScheduleRealInfo { @@ -26,6 +37,7 @@ public class ScheduleRealInfo {
26 37
27 /** 排班计划日期 */ 38 /** 排班计划日期 */
28 private Date scheduleDate; 39 private Date scheduleDate;
  40 + private String scheduleDateStr;
29 41
30 /** 真实执行时间 yyyy-MM-dd */ 42 /** 真实执行时间 yyyy-MM-dd */
31 private String realExecDate; 43 private String realExecDate;
@@ -92,18 +104,31 @@ public class ScheduleRealInfo { @@ -92,18 +104,31 @@ public class ScheduleRealInfo {
92 * 班次类型 TODO:正常班次、出场、进场、加油、区间班次、放空班次、放大站班次、两点间空驶 104 * 班次类型 TODO:正常班次、出场、进场、加油、区间班次、放空班次、放大站班次、两点间空驶
93 */ 105 */
94 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;
95 118
96 /** 创建人 */ 119 /** 创建人 */
  120 + @JsonIgnore
97 @ManyToOne(fetch = FetchType.LAZY) 121 @ManyToOne(fetch = FetchType.LAZY)
98 private SysUser createBy; 122 private SysUser createBy;
99 /** 修改人 */ 123 /** 修改人 */
  124 + @JsonIgnore
100 @ManyToOne(fetch = FetchType.LAZY) 125 @ManyToOne(fetch = FetchType.LAZY)
101 private SysUser updateBy; 126 private SysUser updateBy;
102 /** 创建日期 */ 127 /** 创建日期 */
103 @Column(updatable = false, name = "create_date", columnDefinition = "TIMESTAMP DEFAULT CURRENT_TIMESTAMP") 128 @Column(updatable = false, name = "create_date", columnDefinition = "TIMESTAMP DEFAULT CURRENT_TIMESTAMP")
104 private Date createDate; 129 private Date createDate;
105 /** 修改日期 */ 130 /** 修改日期 */
106 - @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")
107 private Date updateDate; 132 private Date updateDate;
108 133
109 /** 实际发车时间*/ 134 /** 实际发车时间*/
@@ -154,6 +179,18 @@ public class ScheduleRealInfo { @@ -154,6 +179,18 @@ public class ScheduleRealInfo {
154 /** 起点站实际到达时间 */ 179 /** 起点站实际到达时间 */
155 private String qdzArrDatesj; 180 private String qdzArrDatesj;
156 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 +
157 public void addRemarks(String remark){ 194 public void addRemarks(String remark){
158 if(StringUtils.isBlank(remark)) 195 if(StringUtils.isBlank(remark))
159 return; 196 return;
@@ -532,6 +569,12 @@ public class ScheduleRealInfo { @@ -532,6 +569,12 @@ public class ScheduleRealInfo {
532 this.setZdsjT(zdDate.getTime()); 569 this.setZdsjT(zdDate.getTime());
533 this.setZdsj(sdfHHmm.format(zdDate)); 570 this.setZdsj(sdfHHmm.format(zdDate));
534 } 571 }
  572 +
  573 + if(this.fcsjActual != null)
  574 + this.setFcsjActualAll(this.fcsjActual);
  575 +
  576 + if(this.zdsjActual != null)
  577 + this.setZdsjActualAll(this.zdsjActual);
535 }catch(Exception e){ 578 }catch(Exception e){
536 e.printStackTrace(); 579 e.printStackTrace();
537 } 580 }
@@ -582,7 +625,7 @@ public class ScheduleRealInfo { @@ -582,7 +625,7 @@ public class ScheduleRealInfo {
582 */ 625 */
583 public void setFcsjAll(String fcsj){ 626 public void setFcsjAll(String fcsj){
584 try { 627 try {
585 - this.fcsjT = sdfyyyyMMddHHmm.parse(sdfyyyyMMdd.format(this.scheduleDate) + " " + fcsj).getTime(); 628 + this.fcsjT = sdfyyyyMMddHHmm.parse(this.realExecDate + " " + fcsj).getTime();
586 this.fcsj = fcsj; 629 this.fcsj = fcsj;
587 } catch (ParseException e) { 630 } catch (ParseException e) {
588 e.printStackTrace(); 631 e.printStackTrace();
@@ -603,13 +646,15 @@ public class ScheduleRealInfo { @@ -603,13 +646,15 @@ public class ScheduleRealInfo {
603 /** 646 /**
604 * 647 *
605 * @Title: setFcsjActualAll 648 * @Title: setFcsjActualAll
606 - * @Description: TODO(设置实际发车时间) 649 + * @Description: TODO(设置实际发车时间 字符串)
607 * @throws 650 * @throws
608 */ 651 */
609 public void setFcsjActualAll(String fcsjActual){ 652 public void setFcsjActualAll(String fcsjActual){
610 try { 653 try {
611 - this.fcsjActualTime = sdfyyyyMMddHHmm.parse(sdfyyyyMMdd.format(this.scheduleDate) + " " + fcsjActual).getTime(); 654 + this.fcsjActualTime = sdfyyyyMMddHHmm.parse(this.realExecDate + " " + fcsjActual).getTime();
612 this.fcsjActual = fcsjActual; 655 this.fcsjActual = fcsjActual;
  656 +
  657 + this.synchroFcsj();
613 } catch (ParseException e) { 658 } catch (ParseException e) {
614 e.printStackTrace(); 659 e.printStackTrace();
615 } 660 }
@@ -618,12 +663,29 @@ public class ScheduleRealInfo { @@ -618,12 +663,29 @@ public class ScheduleRealInfo {
618 /** 663 /**
619 * 664 *
620 * @Title: setFcsjActualAll 665 * @Title: setFcsjActualAll
621 - * @Description: TODO(设置实际发车时间) 666 + * @Description: TODO(设置实际发车时间 时间戳)
622 * @throws 667 * @throws
623 */ 668 */
624 public void setFcsjActualAll(Long t){ 669 public void setFcsjActualAll(Long t){
625 this.fcsjActualTime = t; 670 this.fcsjActualTime = t;
626 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 + }
627 } 689 }
628 690
629 /** 691 /**
@@ -635,6 +697,8 @@ public class ScheduleRealInfo { @@ -635,6 +697,8 @@ public class ScheduleRealInfo {
635 public void setZdsjActualAll(Long t){ 697 public void setZdsjActualAll(Long t){
636 this.zdsjActualTime = t; 698 this.zdsjActualTime = t;
637 this.zdsjActual = sdfHHmm.format(new Date(t)); 699 this.zdsjActual = sdfHHmm.format(new Date(t));
  700 +
  701 + this.synchroZdsj();
638 } 702 }
639 703
640 /** 704 /**
@@ -647,10 +711,25 @@ public class ScheduleRealInfo { @@ -647,10 +711,25 @@ public class ScheduleRealInfo {
647 try { 711 try {
648 this.zdsjActualTime = sdfyyyyMMddHHmm.parse(sdfyyyyMMdd.format(this.scheduleDate) + " " + zdsjActual).getTime(); 712 this.zdsjActualTime = sdfyyyyMMddHHmm.parse(sdfyyyyMMdd.format(this.scheduleDate) + " " + zdsjActual).getTime();
649 this.zdsjActual = zdsjActual; 713 this.zdsjActual = zdsjActual;
  714 +
  715 + this.synchroZdsj();
650 } catch (ParseException e) { 716 } catch (ParseException e) {
651 e.printStackTrace(); 717 e.printStackTrace();
652 } 718 }
653 } 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 + }
654 733
655 public Long getSpId() { 734 public Long getSpId() {
656 return spId; 735 return spId;
@@ -673,8 +752,15 @@ public class ScheduleRealInfo { @@ -673,8 +752,15 @@ public class ScheduleRealInfo {
673 return; 752 return;
674 753
675 this.status = 0; 754 this.status = 0;
676 - if(StringUtils.isNotBlank(this.fcsjActual)) 755 + if(StringUtils.isNotBlank(this.fcsjActual)){
677 this.status = 1; 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 + }
678 if(StringUtils.isNotBlank(this.zdsjActual)) 764 if(StringUtils.isNotBlank(this.zdsjActual))
679 this.status = 2; 765 this.status = 2;
680 } 766 }
@@ -690,4 +776,102 @@ public class ScheduleRealInfo { @@ -690,4 +776,102 @@ public class ScheduleRealInfo {
690 public boolean isNotDestroy(){ 776 public boolean isNotDestroy(){
691 return this.status != -1; 777 return this.status != -1;
692 } 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 + }
693 } 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
@@ -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
@@ -63,18 +63,18 @@ public class GetSchedulePlanThread extends Thread{ @@ -63,18 +63,18 @@ public class GetSchedulePlanThread extends Thread{
63 public void loaSchedule() throws ParseException{ 63 public void loaSchedule() throws ParseException{
64 List<ScheduleRealInfo> realList = null; 64 List<ScheduleRealInfo> realList = null;
65 String dateStr = sdfyyyyMMdd.format(new Date()); 65 String dateStr = sdfyyyyMMdd.format(new Date());
66 - Date cDate = sdfyyyyMMdd.parse(dateStr); 66 + //Date cDate = sdfyyyyMMdd.parse(dateStr);
67 //查询数据库是否有今日排班 67 //查询数据库是否有今日排班
68 - int size = scheduleRealInfoRepository.countByDate(cDate); 68 + int size = scheduleRealInfoRepository.countByDate(dateStr);
69 if(size > 0){ 69 if(size > 0){
70 //从数据库恢复当日排班 70 //从数据库恢复当日排班
71 - realList = scheduleRealInfoRepository.findByDate(cDate); 71 + realList = scheduleRealInfoRepository.findByDate(dateStr);
72 logger.info("从数据库恢复当日排班 " + realList.size()); 72 logger.info("从数据库恢复当日排班 " + realList.size());
73 //写入缓存 73 //写入缓存
74 ScheduleBuffer.init(realList); 74 ScheduleBuffer.init(realList);
75 } 75 }
76 else{ 76 else{
77 - List<SchedulePlanInfo> list = schedulePlanInfoRepository.findByDate(cDate); 77 + List<SchedulePlanInfo> list = schedulePlanInfoRepository.findByDate(sdfyyyyMMdd.parse(dateStr));
78 78
79 for(SchedulePlanInfo sp : list){ 79 for(SchedulePlanInfo sp : list){
80 sp.setSchedulePlan(null); 80 sp.setSchedulePlan(null);
@@ -91,6 +91,7 @@ public class GetSchedulePlanThread extends Thread{ @@ -91,6 +91,7 @@ public class GetSchedulePlanThread extends Thread{
91 for(ScheduleRealInfo item : realList){ 91 for(ScheduleRealInfo item : realList){
92 item.setSpId(item.getId()); 92 item.setSpId(item.getId());
93 item.setId(id ++);//设置ID 93 item.setId(id ++);//设置ID
  94 + item.setScheduleDateStr(sdfyyyyMMdd.format(item.getScheduleDate()));
94 } 95 }
95 96
96 //写入缓存 97 //写入缓存
src/main/java/com/bsth/service/realcontrol/buffer/ScheduleBuffer.java
@@ -16,7 +16,6 @@ import org.slf4j.LoggerFactory; @@ -16,7 +16,6 @@ import org.slf4j.LoggerFactory;
16 16
17 import com.bsth.entity.realcontrol.ScheduleRealInfo; 17 import com.bsth.entity.realcontrol.ScheduleRealInfo;
18 import com.google.common.collect.ArrayListMultimap; 18 import com.google.common.collect.ArrayListMultimap;
19 -import com.google.common.collect.LinkedListMultimap;  
20 19
21 /** 20 /**
22 * 21 *
@@ -33,7 +32,7 @@ public class ScheduleBuffer { @@ -33,7 +32,7 @@ public class ScheduleBuffer {
33 /** 32 /**
34 * 当天实际排班 K 线路编码 V 按时间升序的班次 33 * 当天实际排班 K 线路编码 V 按时间升序的班次
35 */ 34 */
36 - public static ArrayListMultimap<String, ScheduleRealInfo> schedulListMap; 35 + public static ArrayListMultimap<String, ScheduleRealInfo> realSchedulListMap;
37 36
38 /** 37 /**
39 * K: 车辆自编号 V: 未完成班次链表 38 * K: 车辆自编号 V: 未完成班次链表
@@ -43,7 +42,7 @@ public class ScheduleBuffer { @@ -43,7 +42,7 @@ public class ScheduleBuffer {
43 /** 42 /**
44 * K: 车辆自编号 V: 班次链表 43 * K: 车辆自编号 V: 班次链表
45 */ 44 */
46 - public static ArrayListMultimap<String, ScheduleRealInfo> vehSchListMap; 45 + public static ArrayListMultimap<String, ScheduleRealInfo> carSchListMap;
47 /*public static Map<String, LinkedList<ScheduleRealInfo>> vehSchLinkedMap;*/ 46 /*public static Map<String, LinkedList<ScheduleRealInfo>> vehSchLinkedMap;*/
48 47
49 48
@@ -63,8 +62,8 @@ public class ScheduleBuffer { @@ -63,8 +62,8 @@ public class ScheduleBuffer {
63 */ 62 */
64 public static LinkedList<ScheduleRealInfo> persistentList; 63 public static LinkedList<ScheduleRealInfo> persistentList;
65 64
66 - /** K: 线路编码_上下行 V: 班次平均间隔时间 */  
67 - public static Map<String , Long> schSpaceMap; 65 + /** K: 线路编码_上下行 V: 班次平均间隔时间
  66 + public static Map<String , Long> schSpaceMap; */
68 67
69 /** 68 /**
70 * 线路是否托管 K:线路编码 V:0 托管 1 非托管 69 * 线路是否托管 K:线路编码 V:0 托管 1 非托管
@@ -80,12 +79,12 @@ public class ScheduleBuffer { @@ -80,12 +79,12 @@ public class ScheduleBuffer {
80 } 79 }
81 80
82 public static void clear(){ 81 public static void clear(){
83 - schedulListMap = ArrayListMultimap.create(); 82 + realSchedulListMap = ArrayListMultimap.create();
84 pkSchedulMap = new HashMap<>(); 83 pkSchedulMap = new HashMap<>();
85 persistentList = new LinkedList<>(); 84 persistentList = new LinkedList<>();
86 /*vehLinkedMap = new HashMap<>(); 85 /*vehLinkedMap = new HashMap<>();
87 finishLinkedMap = LinkedListMultimap.create();*/ 86 finishLinkedMap = LinkedListMultimap.create();*/
88 - vehSchListMap = ArrayListMultimap.create(); 87 + carSchListMap = ArrayListMultimap.create();
89 trustMap = new HashMap<>(); 88 trustMap = new HashMap<>();
90 } 89 }
91 90
@@ -106,24 +105,31 @@ public class ScheduleBuffer { @@ -106,24 +105,31 @@ public class ScheduleBuffer {
106 String zbh; 105 String zbh;
107 for(ScheduleRealInfo schedul : list){ 106 for(ScheduleRealInfo schedul : list){
108 107
109 - schedulListMap.put(schedul.getXlBm(), schedul); 108 + realSchedulListMap.put(schedul.getXlBm(), schedul);
110 pkSchedulMap.put(schedul.getId(), schedul); 109 pkSchedulMap.put(schedul.getId(), schedul);
111 110
112 //初始化车辆和班次列表对照 111 //初始化车辆和班次列表对照
113 zbh = schedul.getClZbh(); 112 zbh = schedul.getClZbh();
114 - vehSchListMap.put(zbh, schedul); 113 + carSchListMap.put(zbh, schedul);
115 } 114 }
116 115
117 - //计算计划发车真实时间 116 + //计算真实计划发车时间
118 calcRealOutTime(); 117 calcRealOutTime();
119 118
120 //计算起点应到时间 119 //计算起点应到时间
121 - Set<String> codes = schedulListMap.keySet();  
122 - for(String code : codes)  
123 - 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
124 130
125 //计算班次平均间隔 131 //计算班次平均间隔
126 - calcAvgSpace(); 132 + //calcAvgSpace();
127 133
128 }catch(Exception e){ 134 }catch(Exception e){
129 logger.error("缓存排班数据失败...", e); 135 logger.error("缓存排班数据失败...", e);
@@ -134,12 +140,12 @@ public class ScheduleBuffer { @@ -134,12 +140,12 @@ public class ScheduleBuffer {
134 140
135 private static void calcRealOutTime() { 141 private static void calcRealOutTime() {
136 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); 142 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
137 - Set<String> keys = vehSchListMap.keySet(); 143 + Set<String> keys = carSchListMap.keySet();
138 144
139 List<ScheduleRealInfo> list; 145 List<ScheduleRealInfo> list;
140 ScheduleRealInfo schedule; 146 ScheduleRealInfo schedule;
141 for(String key : keys){ 147 for(String key : keys){
142 - list = vehSchListMap.get(key); 148 + list = carSchListMap.get(key);
143 149
144 //发车顺序号排序 150 //发车顺序号排序
145 Collections.sort(list, scheduleComparator); 151 Collections.sort(list, scheduleComparator);
@@ -154,17 +160,51 @@ public class ScheduleBuffer { @@ -154,17 +160,51 @@ public class ScheduleBuffer {
154 } 160 }
155 } 161 }
156 } 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 + }
157 197
158 //计算平均间隔 198 //计算平均间隔
159 - public static void calcAvgSpace(){ 199 +/* public static void calcAvgSpace(){
160 schSpaceMap = new HashMap<>(); 200 schSpaceMap = new HashMap<>();
161 - Set<String> set = schedulListMap.keySet(); 201 + Set<String> set = realSchedulListMap.keySet();
162 202
163 List<ScheduleRealInfo> list = null 203 List<ScheduleRealInfo> list = null
164 ,upList = null 204 ,upList = null
165 ,downList = null; 205 ,downList = null;
166 for(String lineCode : set){ 206 for(String lineCode : set){
167 - list = schedulListMap.get(lineCode); 207 + list = realSchedulListMap.get(lineCode);
168 Long sumUp = 0L, sumDown = 0L; 208 Long sumUp = 0L, sumDown = 0L;
169 209
170 upList = new ArrayList<>(); 210 upList = new ArrayList<>();
@@ -187,14 +227,14 @@ public class ScheduleBuffer { @@ -187,14 +227,14 @@ public class ScheduleBuffer {
187 schSpaceMap.put(lineCode + "_0", sumUp / upList.size()); 227 schSpaceMap.put(lineCode + "_0", sumUp / upList.size());
188 schSpaceMap.put(lineCode + "_1", sumDown / downList.size()); 228 schSpaceMap.put(lineCode + "_1", sumDown / downList.size());
189 } 229 }
190 - } 230 + }*/
191 231
192 public static int put(ScheduleRealInfo sch){ 232 public static int put(ScheduleRealInfo sch){
193 - schedulListMap.put(sch.getXlBm(), sch); 233 + realSchedulListMap.put(sch.getXlBm(), sch);
194 234
195 pkSchedulMap.put(sch.getId(), sch); 235 pkSchedulMap.put(sch.getId(), sch);
196 String zbh = sch.getClZbh(); 236 String zbh = sch.getClZbh();
197 - vehSchListMap.put(zbh, sch); 237 + carSchListMap.put(zbh, sch);
198 238
199 //List<ScheduleRealInfo> list = vehSchListMap.get(sch.getClZbh()); 239 //List<ScheduleRealInfo> list = vehSchListMap.get(sch.getClZbh());
200 240
@@ -203,11 +243,11 @@ public class ScheduleBuffer { @@ -203,11 +243,11 @@ public class ScheduleBuffer {
203 vehLinkedMap.get(zbh).add(sch);*/ 243 vehLinkedMap.get(zbh).add(sch);*/
204 244
205 //重新排序 245 //重新排序
206 - Collections.sort(schedulListMap.get(sch.getXlBm()), scheduleComparator); 246 + Collections.sort(realSchedulListMap.get(sch.getXlBm()), scheduleComparator);
207 //Collections.sort(vehSchListMap.get(zbh), scheduleComparator); 247 //Collections.sort(vehSchListMap.get(zbh), scheduleComparator);
208 248
209 //重新计算应到时间 249 //重新计算应到时间
210 - calcArrDateQd(vehSchListMap.get(zbh)); 250 + calcArrDateQd(carSchListMap.get(zbh));
211 return 0; 251 return 0;
212 } 252 }
213 253
@@ -236,7 +276,8 @@ public class ScheduleBuffer { @@ -236,7 +276,8 @@ public class ScheduleBuffer {
236 276
237 //下一个班次 277 //下一个班次
238 ScheduleRealInfo next = getNext(sch); 278 ScheduleRealInfo next = getNext(sch);
239 - next.setQdzArrDateSJ(sch.getZdsjActual()); 279 + if(next != null)
  280 + next.setQdzArrDateSJ(sch.getZdsjActual());
240 /*ScheduleRealInfo temp; 281 /*ScheduleRealInfo temp;
241 int len = list.size(); 282 int len = list.size();
242 for(int i = 0; i < len; i ++){ 283 for(int i = 0; i < len; i ++){
@@ -253,7 +294,7 @@ public class ScheduleBuffer { @@ -253,7 +294,7 @@ public class ScheduleBuffer {
253 } 294 }
254 295
255 public static ScheduleRealInfo getNext(ScheduleRealInfo sch){ 296 public static ScheduleRealInfo getNext(ScheduleRealInfo sch){
256 - List<ScheduleRealInfo> list = vehSchListMap.get(sch.getClZbh()); 297 + List<ScheduleRealInfo> list = carSchListMap.get(sch.getClZbh());
257 298
258 boolean flag = false; 299 boolean flag = false;
259 ScheduleRealInfo next = null; 300 ScheduleRealInfo next = null;
@@ -293,7 +334,7 @@ public class ScheduleBuffer { @@ -293,7 +334,7 @@ public class ScheduleBuffer {
293 * @throws 334 * @throws
294 */ 335 */
295 public static int getFinishSchNo(String nbbm){ 336 public static int getFinishSchNo(String nbbm){
296 - List<ScheduleRealInfo> list = vehSchListMap.get(nbbm); 337 + List<ScheduleRealInfo> list = carSchListMap.get(nbbm);
297 int no = 0; 338 int no = 0;
298 for(ScheduleRealInfo sch : list){ 339 for(ScheduleRealInfo sch : list){
299 if(sch.getStatus() == 2) 340 if(sch.getStatus() == 2)
@@ -311,7 +352,7 @@ public class ScheduleBuffer { @@ -311,7 +352,7 @@ public class ScheduleBuffer {
311 * @throws 352 * @throws
312 */ 353 */
313 public static ScheduleRealInfo findCurrent(String nbbm){ 354 public static ScheduleRealInfo findCurrent(String nbbm){
314 - List<ScheduleRealInfo> list = ScheduleBuffer.vehSchListMap.get(nbbm); 355 + List<ScheduleRealInfo> list = ScheduleBuffer.carSchListMap.get(nbbm);
315 356
316 int size = list.size(); 357 int size = list.size();
317 ScheduleRealInfo sch; 358 ScheduleRealInfo sch;
@@ -332,7 +373,7 @@ public class ScheduleBuffer { @@ -332,7 +373,7 @@ public class ScheduleBuffer {
332 * @throws 373 * @throws
333 */ 374 */
334 public static List<ScheduleRealInfo> findNextList(ScheduleRealInfo sch){ 375 public static List<ScheduleRealInfo> findNextList(ScheduleRealInfo sch){
335 - List<ScheduleRealInfo> list = vehSchListMap.get(sch.getClZbh()), 376 + List<ScheduleRealInfo> list = carSchListMap.get(sch.getClZbh()),
336 rs = null; 377 rs = null;
337 378
338 for(ScheduleRealInfo temp : list){ 379 for(ScheduleRealInfo temp : list){
@@ -369,7 +410,7 @@ public class ScheduleBuffer { @@ -369,7 +410,7 @@ public class ScheduleBuffer {
369 * @throws 410 * @throws
370 */ 411 */
371 public static void calcArrDateQd(String lineCode){ 412 public static void calcArrDateQd(String lineCode){
372 - List<ScheduleRealInfo> list = schedulListMap.get(lineCode); 413 + List<ScheduleRealInfo> list = realSchedulListMap.get(lineCode);
373 //按车辆分组 414 //按车辆分组
374 ArrayListMultimap<String, ScheduleRealInfo> map = ArrayListMultimap.create(); 415 ArrayListMultimap<String, ScheduleRealInfo> map = ArrayListMultimap.create();
375 for(ScheduleRealInfo sch : list){ 416 for(ScheduleRealInfo sch : list){
@@ -388,7 +429,7 @@ public class ScheduleBuffer { @@ -388,7 +429,7 @@ public class ScheduleBuffer {
388 } 429 }
389 430
390 public static List<ScheduleRealInfo> findByLineAndUpDown(Integer lineCode, Integer upDown){ 431 public static List<ScheduleRealInfo> findByLineAndUpDown(Integer lineCode, Integer upDown){
391 - List<ScheduleRealInfo> list = schedulListMap.get(String.valueOf(lineCode)) 432 + List<ScheduleRealInfo> list = realSchedulListMap.get(String.valueOf(lineCode))
392 ,subList = new ArrayList<>(); 433 ,subList = new ArrayList<>();
393 //按走向过滤 434 //按走向过滤
394 for(ScheduleRealInfo sch : list){ 435 for(ScheduleRealInfo sch : list){
@@ -398,4 +439,12 @@ public class ScheduleBuffer { @@ -398,4 +439,12 @@ public class ScheduleBuffer {
398 } 439 }
399 return subList; 440 return subList;
400 } 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 + }
401 } 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
@@ -87,7 +87,7 @@ public class ScheduleRealInfoServiceImpl extends BaseServiceImpl&lt;ScheduleRealInf @@ -87,7 +87,7 @@ public class ScheduleRealInfoServiceImpl extends BaseServiceImpl&lt;ScheduleRealInf
87 Multimap<String, ScheduleRealInfo> mMap = ArrayListMultimap.create(); 87 Multimap<String, ScheduleRealInfo> mMap = ArrayListMultimap.create();
88 88
89 for (String lineCode : lineList) { 89 for (String lineCode : lineList) {
90 - mMap.putAll(lineCode, ScheduleBuffer.schedulListMap.get(lineCode)); 90 + mMap.putAll(lineCode, ScheduleBuffer.realSchedulListMap.get(lineCode));
91 } 91 }
92 return mMap.asMap(); 92 return mMap.asMap();
93 } 93 }
@@ -156,7 +156,7 @@ public class ScheduleRealInfoServiceImpl extends BaseServiceImpl&lt;ScheduleRealInf @@ -156,7 +156,7 @@ public class ScheduleRealInfoServiceImpl extends BaseServiceImpl&lt;ScheduleRealInf
156 String lineCode = first.getXlBm(); 156 String lineCode = first.getXlBm();
157 String upDown = first.getXlDir(); 157 String upDown = first.getXlDir();
158 158
159 - List<ScheduleRealInfo> schList = ScheduleBuffer.schedulListMap.get(lineCode), 159 + List<ScheduleRealInfo> schList = ScheduleBuffer.realSchedulListMap.get(lineCode),
160 dirList = new ArrayList<>(); 160 dirList = new ArrayList<>();
161 // 筛选走向 161 // 筛选走向
162 for (ScheduleRealInfo s : schList) { 162 for (ScheduleRealInfo s : schList) {
@@ -463,19 +463,33 @@ public class ScheduleRealInfoServiceImpl extends BaseServiceImpl&lt;ScheduleRealInf @@ -463,19 +463,33 @@ public class ScheduleRealInfoServiceImpl extends BaseServiceImpl&lt;ScheduleRealInf
463 @Override 463 @Override
464 public Map<String, Object> realOutAdjust(Long id, String fcsjActual, String remarks) { 464 public Map<String, Object> realOutAdjust(Long id, String fcsjActual, String remarks) {
465 Map<String, Object> rs = new HashMap<>(); 465 Map<String, Object> rs = new HashMap<>();
  466 + List<ScheduleRealInfo> ts = new ArrayList<>();
466 try { 467 try {
467 ScheduleRealInfo sch = ScheduleBuffer.findOne(id); 468 ScheduleRealInfo sch = ScheduleBuffer.findOne(id);
468 469
469 - sch.setFcsjActualTime(sdfMinute.parse(sch.getRealExecDate() + " " + fcsjActual).getTime());  
470 - sch.setFcsjActual(fcsjActual); 470 + Long t = sdfMinute.parse(sch.getRealExecDate() + " " + fcsjActual).getTime();
  471 + /*sch.setFcsjActualTime(sdfMinute.parse(sch.getRealExecDate() + " " + fcsjActual).getTime());
  472 + sch.setFcsjActual(fcsjActual);*/
  473 + if(null != sch.getSjfcModel())
  474 + sch.getSjfcModel().setPersonTime(t);
  475 +
  476 + sch.setFcsjActualAll(t);
471 sch.addRemarks(remarks); 477 sch.addRemarks(remarks);
472 - //改变状态 478 + sch.calcStatus();
  479 + /*//改变状态
473 if(sch.getZdsjActual() == null) 480 if(sch.getZdsjActual() == null)
474 - sch.setStatus(1); 481 + sch.setStatus(1);*/
475 482
476 ScheduleBuffer.persistentList.add(sch); 483 ScheduleBuffer.persistentList.add(sch);
  484 +
  485 + ts.add(sch);
  486 + //关联班次
  487 + if(sch.existDependent())
  488 + ts.add(sch.getTwins());
  489 +
477 rs.put("status", ResponseCode.SUCCESS); 490 rs.put("status", ResponseCode.SUCCESS);
478 - rs.put("t", sch); 491 + //rs.put("t", sch);
  492 + rs.put("ts", ts);
479 } catch (Exception e) { 493 } catch (Exception e) {
480 logger.error("", e); 494 logger.error("", e);
481 rs.put("status", ResponseCode.ERROR); 495 rs.put("status", ResponseCode.ERROR);
@@ -497,7 +511,6 @@ public class ScheduleRealInfoServiceImpl extends BaseServiceImpl&lt;ScheduleRealInf @@ -497,7 +511,6 @@ public class ScheduleRealInfoServiceImpl extends BaseServiceImpl&lt;ScheduleRealInf
497 rs.put("status", ResponseCode.SUCCESS); 511 rs.put("status", ResponseCode.SUCCESS);
498 rs.put("t", sch); 512 rs.put("t", sch);
499 513
500 - // 将班次状态还原,并由子线程去匹配到离站  
501 } 514 }
502 } catch (Exception e) { 515 } catch (Exception e) {
503 logger.error("", e); 516 logger.error("", e);
@@ -509,19 +522,26 @@ public class ScheduleRealInfoServiceImpl extends BaseServiceImpl&lt;ScheduleRealInf @@ -509,19 +522,26 @@ public class ScheduleRealInfoServiceImpl extends BaseServiceImpl&lt;ScheduleRealInf
509 @Override 522 @Override
510 public Map<String, Object> revokeRealOutgo(Long id) { 523 public Map<String, Object> revokeRealOutgo(Long id) {
511 Map<String, Object> rs = new HashMap<>(); 524 Map<String, Object> rs = new HashMap<>();
  525 + List<ScheduleRealInfo> ts = new ArrayList<>();
  526 +
512 try { 527 try {
513 ScheduleRealInfo sch = ScheduleBuffer.findOne(id); 528 ScheduleRealInfo sch = ScheduleBuffer.findOne(id);
514 if (sch.getFcsjActual() == null) { 529 if (sch.getFcsjActual() == null) {
515 rs.put("status", ResponseCode.ERROR); 530 rs.put("status", ResponseCode.ERROR);
516 rs.put("msg", "无实发时间,无法撤销!"); 531 rs.put("msg", "无实发时间,无法撤销!");
517 } else { 532 } else {
518 - sch.setStatus(0);  
519 - sch.setFcsjActual(null);  
520 - sch.setFcsjActualTime(null); 533 + sch.revokeRealOutgo();
521 rs.put("status", ResponseCode.SUCCESS); 534 rs.put("status", ResponseCode.SUCCESS);
522 - rs.put("t", sch); 535 +
  536 + ts.add(sch);
  537 + if(sch.existDependent()){
  538 + //关联班次也撤销
  539 + sch.getTwins().revokeRealOutgo();
  540 + ts.add(sch.getTwins());
  541 + }
  542 +
  543 + rs.put("ts", ts);
523 544
524 - // 将班次状态还原,并由子线程去匹配到离站  
525 } 545 }
526 } catch (Exception e) { 546 } catch (Exception e) {
527 logger.error("", e); 547 logger.error("", e);
@@ -578,6 +598,7 @@ public class ScheduleRealInfoServiceImpl extends BaseServiceImpl&lt;ScheduleRealInf @@ -578,6 +598,7 @@ public class ScheduleRealInfoServiceImpl extends BaseServiceImpl&lt;ScheduleRealInf
578 @Override 598 @Override
579 public Map<String, Object> schInfoFineTune(Map<String, String> map) { 599 public Map<String, Object> schInfoFineTune(Map<String, String> map) {
580 Map<String, Object> rs = new HashMap<>(); 600 Map<String, Object> rs = new HashMap<>();
  601 + List<ScheduleRealInfo> ts = new ArrayList<>();
581 try { 602 try {
582 Long id = Long.parseLong(map.get("id")); 603 Long id = Long.parseLong(map.get("id"));
583 //班次类型 604 //班次类型
@@ -615,13 +636,21 @@ public class ScheduleRealInfoServiceImpl extends BaseServiceImpl&lt;ScheduleRealInf @@ -615,13 +636,21 @@ public class ScheduleRealInfoServiceImpl extends BaseServiceImpl&lt;ScheduleRealInf
615 sch.setFcsjAll(fcsj); 636 sch.setFcsjAll(fcsj);
616 637
617 if(StringUtils.isNotBlank(fcsjActual)){ 638 if(StringUtils.isNotBlank(fcsjActual)){
618 - //调整实发  
619 - if(!fcsjActual.equals(sch.getFcsjActual())) 639 +
  640 + if(!fcsjActual.equals(sch.getFcsjActual())){
  641 + //调整实发
620 sch.setFcsjActualAll(fcsjActual); 642 sch.setFcsjActualAll(fcsjActual);
  643 + if(null != sch.getSjfcModel())
  644 + sch.getSjfcModel().setPersonTime(sch.getFcsjActualTime());
  645 + }
621 } 646 }
622 else{ 647 else{
623 - sch.setFcsjActual(null); 648 + /*sch.setFcsjActual(null);
624 sch.setFcsjActualTime(null); 649 sch.setFcsjActualTime(null);
  650 + if(null != sch.getSjfcModel())
  651 + sch.getSjfcModel().resetNull();*/
  652 + //撤销实发
  653 + revokeRealOutgo(sch.getId());
625 } 654 }
626 655
627 //实达时间 656 //实达时间
@@ -632,17 +661,21 @@ public class ScheduleRealInfoServiceImpl extends BaseServiceImpl&lt;ScheduleRealInf @@ -632,17 +661,21 @@ public class ScheduleRealInfoServiceImpl extends BaseServiceImpl&lt;ScheduleRealInf
632 //下一班次起点到达时间 661 //下一班次起点到达时间
633 ScheduleRealInfo next = ScheduleBuffer.getNext(sch); 662 ScheduleRealInfo next = ScheduleBuffer.getNext(sch);
634 next.setQdzArrDateSJ(zdsjActual); 663 next.setQdzArrDateSJ(zdsjActual);
635 - rs.put("nextSch", next); 664 + ts.add(next);
636 } 665 }
637 } 666 }
638 - else /*if(StringUtils.isNotBlank(sch.getZdsjActual()))*/{ 667 + else {
639 //清除实达时间 668 //清除实达时间
640 - sch.setZdsjActual(null); 669 + sch.clearZdsjActual();
  670 + /*sch.setZdsjActual(null);
641 sch.setZdsjActualTime(null); 671 sch.setZdsjActualTime(null);
  672 + if(null != sch.getSjddModel())
  673 + sch.getSjddModel().resetNull();*/
  674 +
642 //清除下一班次起点到达时间 675 //清除下一班次起点到达时间
643 ScheduleRealInfo next = ScheduleBuffer.getNext(sch); 676 ScheduleRealInfo next = ScheduleBuffer.getNext(sch);
644 next.setQdzArrDateSJ(null); 677 next.setQdzArrDateSJ(null);
645 - rs.put("nextSch", next); 678 + ts.add(next);
646 } 679 }
647 680
648 sch.setRemarks(remarks); 681 sch.setRemarks(remarks);
@@ -651,9 +684,14 @@ public class ScheduleRealInfoServiceImpl extends BaseServiceImpl&lt;ScheduleRealInf @@ -651,9 +684,14 @@ public class ScheduleRealInfoServiceImpl extends BaseServiceImpl&lt;ScheduleRealInf
651 //班次状态 684 //班次状态
652 sch.calcStatus(); 685 sch.calcStatus();
653 ScheduleBuffer.persistentList.add(sch); 686 ScheduleBuffer.persistentList.add(sch);
  687 + //页面需要更新的班次信息
  688 + ts.add(sch);
  689 + if(sch.existDependent())
  690 + ts.add(sch.getTwins());
654 691
655 rs.put("status", ResponseCode.SUCCESS); 692 rs.put("status", ResponseCode.SUCCESS);
656 - rs.put("t", sch); 693 + rs.put("ts", ts);
  694 + //rs.put("t", sch);
657 } catch (Exception e) { 695 } catch (Exception e) {
658 logger.error("", e); 696 logger.error("", e);
659 rs.put("status", ResponseCode.ERROR); 697 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/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
@@ -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/child_task.html
@@ -500,12 +500,18 @@ function refreshChildTasks(){ @@ -500,12 +500,18 @@ function refreshChildTasks(){
500 //主任务id 500 //主任务id
501 var id = $mainTab.find('tr._active').data('id'); 501 var id = $mainTab.find('tr._active').data('id');
502 502
503 - $.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){
504 var htmlStr = template('child_task_sub_table_temp', {list: rs}); 510 var htmlStr = template('child_task_sub_table_temp', {list: rs});
505 511
506 dictionaryUtils.transformDom( 512 dictionaryUtils.transformDom(
507 $subTab.find('tbody').html(htmlStr).find('.nt-dictionary') 513 $subTab.find('tbody').html(htmlStr).find('.nt-dictionary')
508 ); 514 );
509 - }); 515 + }); */
510 } 516 }
511 </script> 517 </script>
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
@@ -136,7 +136,7 @@ @@ -136,7 +136,7 @@
136 <li class="menu-separator"></li> 136 <li class="menu-separator"></li>
137 <li class="menu-item" > 137 <li class="menu-item" >
138 <button type="button" class="menu-btn" data-multi=1 data-method="spaceAdjust"> 138 <button type="button" class="menu-btn" data-multi=1 data-method="spaceAdjust">
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" >
@@ -144,7 +144,6 @@ @@ -144,7 +144,6 @@
144 <span class="menu-text">误点调整</span> 144 <span class="menu-text">误点调整</span>
145 </button> 145 </button>
146 </li> --> 146 </li> -->
147 - <li class="menu-separator"></li>  
148 <li class="menu-item" > 147 <li class="menu-item" >
149 <button type="button" class="menu-btn" data-method="schInfoFineTune"> 148 <button type="button" class="menu-btn" data-method="schInfoFineTune">
150 <span class="menu-text">发车信息微调</span> 149 <span class="menu-text">发车信息微调</span>
src/main/resources/static/pages/control/line/js/alone.js
@@ -165,6 +165,9 @@ var _alone = (function(){ @@ -165,6 +165,9 @@ var _alone = (function(){
165 function calculateLineNo(table){ 165 function calculateLineNo(table){
166 var rows = table.rows; 166 var rows = table.rows;
167 $.each(rows,function(i, r){ 167 $.each(rows,function(i, r){
  168 + if($(r).hasClass('child-task-list'))
  169 + return true;
  170 +
168 var cells = r.cells; 171 var cells = r.cells;
169 $(cells[0]).text(i + 1); 172 $(cells[0]).text(i + 1);
170 173
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,7 +29,7 @@ var _data = (function(){ @@ -29,7 +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; 32 + return (a.fcno - b.fcno) + (a.fcsjT - b.fcsjT);
33 } 33 }
34 34
35 var dataObject = { 35 var dataObject = {
@@ -288,23 +288,22 @@ var _data = (function(){ @@ -288,23 +288,22 @@ var _data = (function(){
288 for(var i = 0, gps; gps=gpsList[i++];){ 288 for(var i = 0, gps; gps=gpsList[i++];){
289 oldGps = prve[gps.deviceId]; 289 oldGps = prve[gps.deviceId];
290 if(!oldGps){ 290 if(!oldGps){
291 - //添加  
292 - prve[gps.deviceId] = gps;  
293 addArray.push(gps); 291 addArray.push(gps);
294 } 292 }
295 else if(gps.timestamp > oldGps.timestamp){ 293 else if(gps.timestamp > oldGps.timestamp){
296 //更新 294 //更新
297 upArray.push(gps); 295 upArray.push(gps);
298 } 296 }
  297 + allGps[gps.deviceId] = gps;
299 } 298 }
300 cb && cb(addArray, upArray); 299 cb && cb(addArray, upArray);
301 } 300 }
302 301
303 function getGpsError(jqXHR, textStatus){ 302 function getGpsError(jqXHR, textStatus){
304 - if(textStatus === 'error'){}  
305 - //layer.alert('获取GPS数据时,服务器出现异常', {icon: 2});  
306 - else if(textStatus === 'timeout'){}  
307 - //layer.alert('连接服务器超时', {icon: 2}); 303 + if(textStatus === 'error')
  304 + layer.alert('获取GPS数据时出现异常,请尝试刷新页面!', {icon: 2});
  305 + else if(textStatus === 'timeout')
  306 + layer.alert('连接服务器超时', {icon: 2});
308 307
309 //停止gps刷新 308 //停止gps刷新
310 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
@@ -28,14 +28,25 @@ $(document.body).on(&#39;keydown&#39;, function(e){ @@ -28,14 +28,25 @@ $(document.body).on(&#39;keydown&#39;, function(e){
28 if(!array || array.length == 0) 28 if(!array || array.length == 0)
29 layer.msg('没有找到相关班次信息!'); 29 layer.msg('没有找到相关班次信息!');
30 else{ 30 else{
31 - //定位到当前正在执行的班次  
32 - var sch; 31 + var runingSch,nearestSch;
  32 + //当前时间戳,忽略毫秒
  33 + var t = Date.parse(new Date());
33 $.each(array, function(){ 34 $.each(array, function(){
  35 + //正在执行的班次
34 if(this.status == 1) 36 if(this.status == 1)
35 sch = this; 37 sch = this;
  38 +
  39 + //距离当前时间最近的班次
  40 + if(!nearestSch
  41 + || Math.abs(this.fcsjT - t) < Math.abs(nearestSch.fcsjT - t))
  42 + nearestSch = this;
  43 +
  44 + //高亮所有班次
  45 + $('.pb-table tr[data-id='+this.id+']').addClass('selected dir_' + this.xlDir);
36 }); 46 });
  47 +
37 if(!sch) 48 if(!sch)
38 - sch = array[0]; 49 + sch = nearestSch;
39 50
40 var delay; 51 var delay;
41 //当前选中的选项卡 52 //当前选中的选项卡
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,16 +66,18 @@ @@ -67,16 +66,18 @@
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
src/main/resources/static/pages/control/line/js/rightMenu.js
@@ -357,10 +357,10 @@ var _menu = (function() { @@ -357,10 +357,10 @@ var _menu = (function() {
357 layer.close(index); 357 layer.close(index);
358 $post('/realSchedule/realOutAdjust', params 358 $post('/realSchedule/realOutAdjust', params
359 ,function(rs){ 359 ,function(rs){
360 - if(rs.t){ 360 + if(rs.ts){
361 msg_ct('实发调整成功!'); 361 msg_ct('实发调整成功!');
362 //更新前端数据 362 //更新前端数据
363 - _alone.refreshSchedule(rs.t); 363 + _alone.refreshScheduleArray(rs.ts);
364 } 364 }
365 }); 365 });
366 }); 366 });
@@ -375,10 +375,11 @@ var _menu = (function() { @@ -375,10 +375,11 @@ var _menu = (function() {
375 shift :5, 375 shift :5,
376 }, function(){ 376 }, function(){
377 $post('/realSchedule/revokeRealOutgo', {id: schedul.id}, function(rs){ 377 $post('/realSchedule/revokeRealOutgo', {id: schedul.id}, function(rs){
378 - if(rs.t){ 378 + console.log(rs);
  379 + if(rs.ts){
379 msg_ct('撤销实发成功!'); 380 msg_ct('撤销实发成功!');
380 //更新前端数据 381 //更新前端数据
381 - _alone.refreshSchedule(rs.t); 382 + _alone.refreshScheduleArray(rs.ts);
382 } 383 }
383 }); 384 });
384 }); 385 });
@@ -545,11 +546,11 @@ var _menu = (function() { @@ -545,11 +546,11 @@ var _menu = (function() {
545 546
546 $post('/realSchedule/schInfoFineTune', params, function(rs){ 547 $post('/realSchedule/schInfoFineTune', params, function(rs){
547 layer.close(index); 548 layer.close(index);
548 - if(rs.t)  
549 - _alone.refreshSchedule(rs.t); 549 + if(rs.ts)
  550 + _alone.refreshScheduleArray(rs.ts);
550 551
551 - if(rs.nextSch)  
552 - _alone.refreshSchedule(rs.nextSch); 552 + /*if(rs.nextSch)
  553 + _alone.refreshSchedule(rs.nextSch);*/
553 }); 554 });
554 }); 555 });
555 } 556 }
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>
@@ -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"> 149 +<td class="hide-lt-1080" data-name="remarks">
152 {{if item.remarks != null && item.remarks.length > 0}} 150 {{if item.remarks != null && item.remarks.length > 0}}
153 <a class="remarks-popover" href="javascript:;" data-toggle="popover" data-content="{{item.remarks}}" >查看...</a> 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
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/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
@@ -30,20 +30,30 @@ var vehiclePanel = (function() { @@ -30,20 +30,30 @@ var vehiclePanel = (function() {
30 //收拢其他 30 //收拢其他
31 closeAll(); 31 closeAll();
32 cLineCode = lineCode; 32 cLineCode = lineCode;
33 - drawLineAndGps(lineCode); 33 + drawLineAndGps(lineCode, function(){
  34 + //从storage里获取路由数据
  35 + var route = JSON.parse(storage.getItem(lineCode + '_route'));
  36 + //在地图上画出线路
  37 + getCurrMap().drawLine(route);
  38 + });
34 }); 39 });
35 40
36 //绘制线路和GPS 41 //绘制线路和GPS
37 - function drawLineAndGps(lineCode){ 42 + function drawLineAndGps(lineCode, callFun){
38 //过滤出该线路的GPS点 43 //过滤出该线路的GPS点
39 var showList = [], gps; 44 var showList = [], gps;
40 - if(lineGps[lineCode]){ 45 + /*if(lineGps[lineCode]){
41 $.each(lineGps[lineCode], function(){ 46 $.each(lineGps[lineCode], function(){
42 gps = allGps[this]; 47 gps = allGps[this];
43 showList.push(gps); 48 showList.push(gps);
44 gpsMarker[gps.deviceId] = gps; 49 gpsMarker[gps.deviceId] = gps;
45 }); 50 });
  51 + }*/
  52 + for(var dId in allGps){
  53 + if(allGps[dId].lineId == lineCode)
  54 + showList.push(allGps[dId]);
46 } 55 }
  56 +
47 //显示车辆列表 57 //显示车辆列表
48 var htmlStr = template('vehicle_panel_collapse_temp', {list: showList}); 58 var htmlStr = template('vehicle_panel_collapse_temp', {list: showList});
49 $('#collapse_' + lineCode).html(htmlStr); 59 $('#collapse_' + lineCode).html(htmlStr);
@@ -53,13 +63,10 @@ var vehiclePanel = (function() { @@ -53,13 +63,10 @@ var vehiclePanel = (function() {
53 */ 63 */
54 var that = $(this); 64 var that = $(this);
55 setTimeout(function(){ 65 setTimeout(function(){
56 - //在地图上画出线路  
57 - var mapObj = getCurrMap();  
58 - //从storage里获取路由数据  
59 - var route = JSON.parse(storage.getItem(lineCode + '_route'));  
60 - mapObj.drawLine(route); 66 + callFun && callFun();
61 //画GPS 67 //画GPS
62 - mapObj.drawGpsMarker(showList); 68 + getCurrMap().drawGpsMarker(showList);
  69 +
63 }, 500); 70 }, 500);
64 } 71 }
65 72
@@ -78,7 +85,7 @@ var vehiclePanel = (function() { @@ -78,7 +85,7 @@ var vehiclePanel = (function() {
78 85
79 //GPS刷新事件 86 //GPS刷新事件
80 var allGps = {}; 87 var allGps = {};
81 - var lineGps = {}; 88 + //var lineGps = {};
82 $('#mapContainer').on('gps_refresh', function(e, add, up){ 89 $('#mapContainer').on('gps_refresh', function(e, add, up){
83 var temp = add; 90 var temp = add;
84 if(up) 91 if(up)
@@ -90,23 +97,24 @@ var vehiclePanel = (function() { @@ -90,23 +97,24 @@ var vehiclePanel = (function() {
90 allGps[this.deviceId] = this; 97 allGps[this.deviceId] = this;
91 }); 98 });
92 99
93 - $.each(add, function(){ 100 + /* $.each(add, function(){
94 if(!lineGps[this.lineId]) 101 if(!lineGps[this.lineId])
95 lineGps[this.lineId] = []; 102 lineGps[this.lineId] = [];
96 //线路和设备号映射 103 //线路和设备号映射
97 - lineGps[this.lineId].push(this.deviceId);  
98 - }) 104 + //lineGps[this.lineId].push(this.deviceId);
  105 + })*/
99 } 106 }
100 107
101 //先暂时重绘,后面再优化 108 //先暂时重绘,后面再优化
102 if(cLineCode){ 109 if(cLineCode){
103 - var showList = []; 110 + drawLineAndGps(cLineCode);
  111 + /*var showList = [];
104 if(lineGps[cLineCode]){ 112 if(lineGps[cLineCode]){
105 $.each(lineGps[cLineCode], function(){ 113 $.each(lineGps[cLineCode], function(){
106 showList.push(allGps[this]); 114 showList.push(allGps[this]);
107 }); 115 });
108 } 116 }
109 - mapObj.drawGpsMarker(showList); 117 + mapObj.drawGpsMarker(showList);*/
110 } 118 }
111 }); 119 });
112 120
@@ -146,6 +154,21 @@ var vehiclePanel = (function() { @@ -146,6 +154,21 @@ var vehiclePanel = (function() {
146 }, 154 },
147 drawLineAndGps: function(lineCode){ 155 drawLineAndGps: function(lineCode){
148 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;
149 } 172 }
150 }; 173 };
151 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}}