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 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 4 import com.bsth.repository.schedule.CarConfigInfoRepository;
8 5 import com.bsth.security.SecurityMetadataSourceService;
9 6 import com.bsth.service.realcontrol.buffer.GetSchedulePlanThread;
... ... @@ -13,17 +10,15 @@ import com.bsth.vehicle.common.CommonRefreshThread;
13 10 import com.bsth.vehicle.directive.service.DirectiveService;
14 11 import com.bsth.vehicle.directive.thread.DirectivePersistenceThread;
15 12 import com.bsth.vehicle.directive.thread.FirstScheduleIssuedThread;
16   -import com.bsth.vehicle.gpsdata.GpsArrivalStationThread;
  13 +import com.bsth.vehicle.gpsdata.GpsArrivalThread;
17 14 import com.bsth.vehicle.gpsdata.GpsRefreshThread;
  15 +
18 16 import org.slf4j.Logger;
19 17 import org.slf4j.LoggerFactory;
20 18 import org.springframework.beans.factory.annotation.Autowired;
21 19 import org.springframework.boot.CommandLineRunner;
22 20 import org.springframework.stereotype.Component;
23 21  
24   -import java.util.List;
25   -import java.util.Timer;
26   -import java.util.TimerTask;
27 22 import java.util.concurrent.Executors;
28 23 import java.util.concurrent.ScheduledExecutorService;
29 24 import java.util.concurrent.TimeUnit;
... ... @@ -54,7 +49,7 @@ public class StartCommand implements CommandLineRunner{
54 49 @Autowired
55 50 SchedulePersistenceThread SchedulePersistenceThread;
56 51 @Autowired
57   - GpsArrivalStationThread gpsArrivalStationThread;
  52 + GpsArrivalThread gpsArrivalStationThread;
58 53 @Autowired
59 54 FirstScheduleIssuedThread firstScheduleIssuedThread;
60 55  
... ... @@ -108,7 +103,7 @@ public class StartCommand implements CommandLineRunner{
108 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 109 * 首个调度指令下发(2分钟运行一次)
... ... @@ -117,6 +112,62 @@ public class StartCommand implements CommandLineRunner{
117 112 */
118 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 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 273 */
274 274 @RequestMapping(value = "/lineCode/{lineCode}")
275 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 279 @RequestMapping(value = "/queryUserInfo")
... ...
src/main/java/com/bsth/entity/realcontrol/ChildTaskPlan.java
... ... @@ -10,6 +10,9 @@ import javax.persistence.NamedEntityGraph;
10 10 import javax.persistence.NamedEntityGraphs;
11 11 import javax.persistence.Table;
12 12  
  13 +import com.fasterxml.jackson.annotation.JsonIgnore;
  14 +
  15 +
13 16 /**
14 17 *
15 18 * @ClassName: ChildTaskPlan
... ... @@ -95,7 +98,8 @@ public class ChildTaskPlan {
95 98 /**
96 99 * 主排班计划
97 100 */
98   - @ManyToOne
  101 + @JsonIgnore
  102 + @ManyToOne(fetch = FetchType.LAZY)
99 103 private ScheduleRealInfo schedule;
100 104  
101 105 private String remarks;
... ...
src/main/java/com/bsth/entity/realcontrol/ScheduleRealInfo.java
1 1 package com.bsth.entity.realcontrol;
2 2  
3 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 7 import javax.persistence.*;
6 8  
... ... @@ -9,12 +11,21 @@ import org.apache.commons.lang3.StringUtils;
9 11 import java.text.ParseException;
10 12 import java.text.SimpleDateFormat;
11 13 import java.util.Date;
  14 +import java.util.HashSet;
  15 +import java.util.Set;
12 16  
13 17 /**
14 18 * 实际排班计划明细。
15 19 */
16 20 @Entity
17 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 29 public class ScheduleRealInfo {
19 30 /** 主键Id */
20 31 @Id
... ... @@ -26,6 +37,7 @@ public class ScheduleRealInfo {
26 37  
27 38 /** 排班计划日期 */
28 39 private Date scheduleDate;
  40 + private String scheduleDateStr;
29 41  
30 42 /** 真实执行时间 yyyy-MM-dd */
31 43 private String realExecDate;
... ... @@ -92,18 +104,31 @@ public class ScheduleRealInfo {
92 104 * 班次类型 TODO:正常班次、出场、进场、加油、区间班次、放空班次、放大站班次、两点间空驶
93 105 */
94 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 121 @ManyToOne(fetch = FetchType.LAZY)
98 122 private SysUser createBy;
99 123 /** 修改人 */
  124 + @JsonIgnore
100 125 @ManyToOne(fetch = FetchType.LAZY)
101 126 private SysUser updateBy;
102 127 /** 创建日期 */
103 128 @Column(updatable = false, name = "create_date", columnDefinition = "TIMESTAMP DEFAULT CURRENT_TIMESTAMP")
104 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 132 private Date updateDate;
108 133  
109 134 /** 实际发车时间*/
... ... @@ -154,6 +179,18 @@ public class ScheduleRealInfo {
154 179 /** 起点站实际到达时间 */
155 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 194 public void addRemarks(String remark){
158 195 if(StringUtils.isBlank(remark))
159 196 return;
... ... @@ -532,6 +569,12 @@ public class ScheduleRealInfo {
532 569 this.setZdsjT(zdDate.getTime());
533 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 578 }catch(Exception e){
536 579 e.printStackTrace();
537 580 }
... ... @@ -582,7 +625,7 @@ public class ScheduleRealInfo {
582 625 */
583 626 public void setFcsjAll(String fcsj){
584 627 try {
585   - this.fcsjT = sdfyyyyMMddHHmm.parse(sdfyyyyMMdd.format(this.scheduleDate) + " " + fcsj).getTime();
  628 + this.fcsjT = sdfyyyyMMddHHmm.parse(this.realExecDate + " " + fcsj).getTime();
586 629 this.fcsj = fcsj;
587 630 } catch (ParseException e) {
588 631 e.printStackTrace();
... ... @@ -603,13 +646,15 @@ public class ScheduleRealInfo {
603 646 /**
604 647 *
605 648 * @Title: setFcsjActualAll
606   - * @Description: TODO(设置实际发车时间)
  649 + * @Description: TODO(设置实际发车时间 字符串)
607 650 * @throws
608 651 */
609 652 public void setFcsjActualAll(String fcsjActual){
610 653 try {
611   - this.fcsjActualTime = sdfyyyyMMddHHmm.parse(sdfyyyyMMdd.format(this.scheduleDate) + " " + fcsjActual).getTime();
  654 + this.fcsjActualTime = sdfyyyyMMddHHmm.parse(this.realExecDate + " " + fcsjActual).getTime();
612 655 this.fcsjActual = fcsjActual;
  656 +
  657 + this.synchroFcsj();
613 658 } catch (ParseException e) {
614 659 e.printStackTrace();
615 660 }
... ... @@ -618,12 +663,29 @@ public class ScheduleRealInfo {
618 663 /**
619 664 *
620 665 * @Title: setFcsjActualAll
621   - * @Description: TODO(设置实际发车时间)
  666 + * @Description: TODO(设置实际发车时间 时间戳)
622 667 * @throws
623 668 */
624 669 public void setFcsjActualAll(Long t){
625 670 this.fcsjActualTime = t;
626 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 697 public void setZdsjActualAll(Long t){
636 698 this.zdsjActualTime = t;
637 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 711 try {
648 712 this.zdsjActualTime = sdfyyyyMMddHHmm.parse(sdfyyyyMMdd.format(this.scheduleDate) + " " + zdsjActual).getTime();
649 713 this.zdsjActual = zdsjActual;
  714 +
  715 + this.synchroZdsj();
650 716 } catch (ParseException e) {
651 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 734 public Long getSpId() {
656 735 return spId;
... ... @@ -673,8 +752,15 @@ public class ScheduleRealInfo {
673 752 return;
674 753  
675 754 this.status = 0;
676   - if(StringUtils.isNotBlank(this.fcsjActual))
  755 + if(StringUtils.isNotBlank(this.fcsjActual)){
677 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 764 if(StringUtils.isNotBlank(this.zdsjActual))
679 765 this.status = 2;
680 766 }
... ... @@ -690,4 +776,102 @@ public class ScheduleRealInfo {
690 776 public boolean isNotDestroy(){
691 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 4 import java.util.List;
5 5 import java.util.Map;
6 6  
  7 +import org.springframework.data.jpa.repository.EntityGraph;
7 8 import org.springframework.data.jpa.repository.Query;
8 9 import org.springframework.stereotype.Repository;
9 10  
... ... @@ -32,11 +33,12 @@ public interface ScheduleRealInfoRepository extends BaseRepository&lt;ScheduleRealI
32 33 @Query(value = "select max(id) from ScheduleRealInfo")
33 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 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 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 63 public void loaSchedule() throws ParseException{
64 64 List<ScheduleRealInfo> realList = null;
65 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 69 if(size > 0){
70 70 //从数据库恢复当日排班
71   - realList = scheduleRealInfoRepository.findByDate(cDate);
  71 + realList = scheduleRealInfoRepository.findByDate(dateStr);
72 72 logger.info("从数据库恢复当日排班 " + realList.size());
73 73 //写入缓存
74 74 ScheduleBuffer.init(realList);
75 75 }
76 76 else{
77   - List<SchedulePlanInfo> list = schedulePlanInfoRepository.findByDate(cDate);
  77 + List<SchedulePlanInfo> list = schedulePlanInfoRepository.findByDate(sdfyyyyMMdd.parse(dateStr));
78 78  
79 79 for(SchedulePlanInfo sp : list){
80 80 sp.setSchedulePlan(null);
... ... @@ -91,6 +91,7 @@ public class GetSchedulePlanThread extends Thread{
91 91 for(ScheduleRealInfo item : realList){
92 92 item.setSpId(item.getId());
93 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 16  
17 17 import com.bsth.entity.realcontrol.ScheduleRealInfo;
18 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 32 /**
34 33 * 当天实际排班 K 线路编码 V 按时间升序的班次
35 34 */
36   - public static ArrayListMultimap<String, ScheduleRealInfo> schedulListMap;
  35 + public static ArrayListMultimap<String, ScheduleRealInfo> realSchedulListMap;
37 36  
38 37 /**
39 38 * K: 车辆自编号 V: 未完成班次链表
... ... @@ -43,7 +42,7 @@ public class ScheduleBuffer {
43 42 /**
44 43 * K: 车辆自编号 V: 班次链表
45 44 */
46   - public static ArrayListMultimap<String, ScheduleRealInfo> vehSchListMap;
  45 + public static ArrayListMultimap<String, ScheduleRealInfo> carSchListMap;
47 46 /*public static Map<String, LinkedList<ScheduleRealInfo>> vehSchLinkedMap;*/
48 47  
49 48  
... ... @@ -63,8 +62,8 @@ public class ScheduleBuffer {
63 62 */
64 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 69 * 线路是否托管 K:线路编码 V:0 托管 1 非托管
... ... @@ -80,12 +79,12 @@ public class ScheduleBuffer {
80 79 }
81 80  
82 81 public static void clear(){
83   - schedulListMap = ArrayListMultimap.create();
  82 + realSchedulListMap = ArrayListMultimap.create();
84 83 pkSchedulMap = new HashMap<>();
85 84 persistentList = new LinkedList<>();
86 85 /*vehLinkedMap = new HashMap<>();
87 86 finishLinkedMap = LinkedListMultimap.create();*/
88   - vehSchListMap = ArrayListMultimap.create();
  87 + carSchListMap = ArrayListMultimap.create();
89 88 trustMap = new HashMap<>();
90 89 }
91 90  
... ... @@ -106,24 +105,31 @@ public class ScheduleBuffer {
106 105 String zbh;
107 106 for(ScheduleRealInfo schedul : list){
108 107  
109   - schedulListMap.put(schedul.getXlBm(), schedul);
  108 + realSchedulListMap.put(schedul.getXlBm(), schedul);
110 109 pkSchedulMap.put(schedul.getId(), schedul);
111 110  
112 111 //初始化车辆和班次列表对照
113 112 zbh = schedul.getClZbh();
114   - vehSchListMap.put(zbh, schedul);
  113 + carSchListMap.put(zbh, schedul);
115 114 }
116 115  
117   - //计算计划发车真实时间
  116 + //计算真实计划发车时间
118 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 134 }catch(Exception e){
129 135 logger.error("缓存排班数据失败...", e);
... ... @@ -134,12 +140,12 @@ public class ScheduleBuffer {
134 140  
135 141 private static void calcRealOutTime() {
136 142 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
137   - Set<String> keys = vehSchListMap.keySet();
  143 + Set<String> keys = carSchListMap.keySet();
138 144  
139 145 List<ScheduleRealInfo> list;
140 146 ScheduleRealInfo schedule;
141 147 for(String key : keys){
142   - list = vehSchListMap.get(key);
  148 + list = carSchListMap.get(key);
143 149  
144 150 //发车顺序号排序
145 151 Collections.sort(list, scheduleComparator);
... ... @@ -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 200 schSpaceMap = new HashMap<>();
161   - Set<String> set = schedulListMap.keySet();
  201 + Set<String> set = realSchedulListMap.keySet();
162 202  
163 203 List<ScheduleRealInfo> list = null
164 204 ,upList = null
165 205 ,downList = null;
166 206 for(String lineCode : set){
167   - list = schedulListMap.get(lineCode);
  207 + list = realSchedulListMap.get(lineCode);
168 208 Long sumUp = 0L, sumDown = 0L;
169 209  
170 210 upList = new ArrayList<>();
... ... @@ -187,14 +227,14 @@ public class ScheduleBuffer {
187 227 schSpaceMap.put(lineCode + "_0", sumUp / upList.size());
188 228 schSpaceMap.put(lineCode + "_1", sumDown / downList.size());
189 229 }
190   - }
  230 + }*/
191 231  
192 232 public static int put(ScheduleRealInfo sch){
193   - schedulListMap.put(sch.getXlBm(), sch);
  233 + realSchedulListMap.put(sch.getXlBm(), sch);
194 234  
195 235 pkSchedulMap.put(sch.getId(), sch);
196 236 String zbh = sch.getClZbh();
197   - vehSchListMap.put(zbh, sch);
  237 + carSchListMap.put(zbh, sch);
198 238  
199 239 //List<ScheduleRealInfo> list = vehSchListMap.get(sch.getClZbh());
200 240  
... ... @@ -203,11 +243,11 @@ public class ScheduleBuffer {
203 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 247 //Collections.sort(vehSchListMap.get(zbh), scheduleComparator);
208 248  
209 249 //重新计算应到时间
210   - calcArrDateQd(vehSchListMap.get(zbh));
  250 + calcArrDateQd(carSchListMap.get(zbh));
211 251 return 0;
212 252 }
213 253  
... ... @@ -236,7 +276,8 @@ public class ScheduleBuffer {
236 276  
237 277 //下一个班次
238 278 ScheduleRealInfo next = getNext(sch);
239   - next.setQdzArrDateSJ(sch.getZdsjActual());
  279 + if(next != null)
  280 + next.setQdzArrDateSJ(sch.getZdsjActual());
240 281 /*ScheduleRealInfo temp;
241 282 int len = list.size();
242 283 for(int i = 0; i < len; i ++){
... ... @@ -253,7 +294,7 @@ public class ScheduleBuffer {
253 294 }
254 295  
255 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 299 boolean flag = false;
259 300 ScheduleRealInfo next = null;
... ... @@ -293,7 +334,7 @@ public class ScheduleBuffer {
293 334 * @throws
294 335 */
295 336 public static int getFinishSchNo(String nbbm){
296   - List<ScheduleRealInfo> list = vehSchListMap.get(nbbm);
  337 + List<ScheduleRealInfo> list = carSchListMap.get(nbbm);
297 338 int no = 0;
298 339 for(ScheduleRealInfo sch : list){
299 340 if(sch.getStatus() == 2)
... ... @@ -311,7 +352,7 @@ public class ScheduleBuffer {
311 352 * @throws
312 353 */
313 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 357 int size = list.size();
317 358 ScheduleRealInfo sch;
... ... @@ -332,7 +373,7 @@ public class ScheduleBuffer {
332 373 * @throws
333 374 */
334 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 377 rs = null;
337 378  
338 379 for(ScheduleRealInfo temp : list){
... ... @@ -369,7 +410,7 @@ public class ScheduleBuffer {
369 410 * @throws
370 411 */
371 412 public static void calcArrDateQd(String lineCode){
372   - List<ScheduleRealInfo> list = schedulListMap.get(lineCode);
  413 + List<ScheduleRealInfo> list = realSchedulListMap.get(lineCode);
373 414 //按车辆分组
374 415 ArrayListMultimap<String, ScheduleRealInfo> map = ArrayListMultimap.create();
375 416 for(ScheduleRealInfo sch : list){
... ... @@ -388,7 +429,7 @@ public class ScheduleBuffer {
388 429 }
389 430  
390 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 433 ,subList = new ArrayList<>();
393 434 //按走向过滤
394 435 for(ScheduleRealInfo sch : list){
... ... @@ -398,4 +439,12 @@ public class ScheduleBuffer {
398 439 }
399 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 34 break;
35 35  
36 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 2  
3 3 import java.util.Map;
4 4  
  5 +import javax.transaction.Transactional;
  6 +
  7 +import org.springframework.beans.factory.annotation.Autowired;
5 8 import org.springframework.stereotype.Service;
6 9  
7 10 import com.bsth.entity.realcontrol.ChildTaskPlan;
  11 +import com.bsth.entity.realcontrol.ScheduleRealInfo;
8 12 import com.bsth.service.impl.BaseServiceImpl;
9 13 import com.bsth.service.realcontrol.ChildTaskPlanService;
  14 +import com.bsth.service.realcontrol.buffer.ScheduleBuffer;
10 15 import com.bsth.vehicle.common.CommonMapped;
11 16  
12 17 @Service
13 18 public class ChildTaskPlanServiceImpl extends BaseServiceImpl<ChildTaskPlan, Long> implements ChildTaskPlanService{
14 19  
  20 + @Autowired
  21 + ScheduleRealInfoServiceImpl scheduleRealInfoService;
15 22  
  23 + @Transactional
16 24 @Override
17 25 public Map<String, Object> save(ChildTaskPlan t) {
  26 + Map<String, Object> rs;
18 27 //保存起终点名称
19 28 Map<String, String> map = CommonMapped.stationCodeMap;
20 29  
21 30 t.setStartStationName(map.get(t.getStartStation()));
22 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 87 Multimap<String, ScheduleRealInfo> mMap = ArrayListMultimap.create();
88 88  
89 89 for (String lineCode : lineList) {
90   - mMap.putAll(lineCode, ScheduleBuffer.schedulListMap.get(lineCode));
  90 + mMap.putAll(lineCode, ScheduleBuffer.realSchedulListMap.get(lineCode));
91 91 }
92 92 return mMap.asMap();
93 93 }
... ... @@ -156,7 +156,7 @@ public class ScheduleRealInfoServiceImpl extends BaseServiceImpl&lt;ScheduleRealInf
156 156 String lineCode = first.getXlBm();
157 157 String upDown = first.getXlDir();
158 158  
159   - List<ScheduleRealInfo> schList = ScheduleBuffer.schedulListMap.get(lineCode),
  159 + List<ScheduleRealInfo> schList = ScheduleBuffer.realSchedulListMap.get(lineCode),
160 160 dirList = new ArrayList<>();
161 161 // 筛选走向
162 162 for (ScheduleRealInfo s : schList) {
... ... @@ -463,19 +463,33 @@ public class ScheduleRealInfoServiceImpl extends BaseServiceImpl&lt;ScheduleRealInf
463 463 @Override
464 464 public Map<String, Object> realOutAdjust(Long id, String fcsjActual, String remarks) {
465 465 Map<String, Object> rs = new HashMap<>();
  466 + List<ScheduleRealInfo> ts = new ArrayList<>();
466 467 try {
467 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 477 sch.addRemarks(remarks);
472   - //改变状态
  478 + sch.calcStatus();
  479 + /*//改变状态
473 480 if(sch.getZdsjActual() == null)
474   - sch.setStatus(1);
  481 + sch.setStatus(1);*/
475 482  
476 483 ScheduleBuffer.persistentList.add(sch);
  484 +
  485 + ts.add(sch);
  486 + //关联班次
  487 + if(sch.existDependent())
  488 + ts.add(sch.getTwins());
  489 +
477 490 rs.put("status", ResponseCode.SUCCESS);
478   - rs.put("t", sch);
  491 + //rs.put("t", sch);
  492 + rs.put("ts", ts);
479 493 } catch (Exception e) {
480 494 logger.error("", e);
481 495 rs.put("status", ResponseCode.ERROR);
... ... @@ -497,7 +511,6 @@ public class ScheduleRealInfoServiceImpl extends BaseServiceImpl&lt;ScheduleRealInf
497 511 rs.put("status", ResponseCode.SUCCESS);
498 512 rs.put("t", sch);
499 513  
500   - // 将班次状态还原,并由子线程去匹配到离站
501 514 }
502 515 } catch (Exception e) {
503 516 logger.error("", e);
... ... @@ -509,19 +522,26 @@ public class ScheduleRealInfoServiceImpl extends BaseServiceImpl&lt;ScheduleRealInf
509 522 @Override
510 523 public Map<String, Object> revokeRealOutgo(Long id) {
511 524 Map<String, Object> rs = new HashMap<>();
  525 + List<ScheduleRealInfo> ts = new ArrayList<>();
  526 +
512 527 try {
513 528 ScheduleRealInfo sch = ScheduleBuffer.findOne(id);
514 529 if (sch.getFcsjActual() == null) {
515 530 rs.put("status", ResponseCode.ERROR);
516 531 rs.put("msg", "无实发时间,无法撤销!");
517 532 } else {
518   - sch.setStatus(0);
519   - sch.setFcsjActual(null);
520   - sch.setFcsjActualTime(null);
  533 + sch.revokeRealOutgo();
521 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 546 } catch (Exception e) {
527 547 logger.error("", e);
... ... @@ -578,6 +598,7 @@ public class ScheduleRealInfoServiceImpl extends BaseServiceImpl&lt;ScheduleRealInf
578 598 @Override
579 599 public Map<String, Object> schInfoFineTune(Map<String, String> map) {
580 600 Map<String, Object> rs = new HashMap<>();
  601 + List<ScheduleRealInfo> ts = new ArrayList<>();
581 602 try {
582 603 Long id = Long.parseLong(map.get("id"));
583 604 //班次类型
... ... @@ -615,13 +636,21 @@ public class ScheduleRealInfoServiceImpl extends BaseServiceImpl&lt;ScheduleRealInf
615 636 sch.setFcsjAll(fcsj);
616 637  
617 638 if(StringUtils.isNotBlank(fcsjActual)){
618   - //调整实发
619   - if(!fcsjActual.equals(sch.getFcsjActual()))
  639 +
  640 + if(!fcsjActual.equals(sch.getFcsjActual())){
  641 + //调整实发
620 642 sch.setFcsjActualAll(fcsjActual);
  643 + if(null != sch.getSjfcModel())
  644 + sch.getSjfcModel().setPersonTime(sch.getFcsjActualTime());
  645 + }
621 646 }
622 647 else{
623   - sch.setFcsjActual(null);
  648 + /*sch.setFcsjActual(null);
624 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 661 //下一班次起点到达时间
633 662 ScheduleRealInfo next = ScheduleBuffer.getNext(sch);
634 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 671 sch.setZdsjActualTime(null);
  672 + if(null != sch.getSjddModel())
  673 + sch.getSjddModel().resetNull();*/
  674 +
642 675 //清除下一班次起点到达时间
643 676 ScheduleRealInfo next = ScheduleBuffer.getNext(sch);
644 677 next.setQdzArrDateSJ(null);
645   - rs.put("nextSch", next);
  678 + ts.add(next);
646 679 }
647 680  
648 681 sch.setRemarks(remarks);
... ... @@ -651,9 +684,14 @@ public class ScheduleRealInfoServiceImpl extends BaseServiceImpl&lt;ScheduleRealInf
651 684 //班次状态
652 685 sch.calcStatus();
653 686 ScheduleBuffer.persistentList.add(sch);
  687 + //页面需要更新的班次信息
  688 + ts.add(sch);
  689 + if(sch.existDependent())
  690 + ts.add(sch.getTwins());
654 691  
655 692 rs.put("status", ResponseCode.SUCCESS);
656   - rs.put("t", sch);
  693 + rs.put("ts", ts);
  694 + //rs.put("t", sch);
657 695 } catch (Exception e) {
658 696 logger.error("", e);
659 697 rs.put("status", ResponseCode.ERROR);
... ...
src/main/java/com/bsth/util/BatchSaveUtils.java
... ... @@ -8,6 +8,10 @@ import java.sql.ResultSet;
8 8 import java.util.ArrayList;
9 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 15 import javax.persistence.Table;
12 16 import javax.persistence.Transient;
13 17  
... ... @@ -138,6 +142,12 @@ public class BatchSaveUtils&lt;T&gt; {
138 142 //忽略 Transient 字段
139 143 if(field.getAnnotation(Transient.class) != null)
140 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 151 fs.add(field);
142 152 }
143 153 return fs;
... ...
src/main/java/com/bsth/vehicle/directive/buffer/DirectiveBuffer.java
... ... @@ -14,6 +14,7 @@ import org.springframework.stereotype.Component;
14 14  
15 15 import com.alibaba.fastjson.JSON;
16 16 import com.alibaba.fastjson.JSONObject;
  17 +import com.bsth.entity.realcontrol.ScheduleRealInfo;
17 18 import com.bsth.service.realcontrol.buffer.ScheduleBuffer;
18 19 import com.bsth.vehicle.common.CommonMapped;
19 20 import com.bsth.vehicle.directive.entity.Directive60;
... ... @@ -25,6 +26,7 @@ import com.bsth.vehicle.directive.entity.LineChange;
25 26 import com.bsth.vehicle.directive.repository.Directive60Repository;
26 27 import com.bsth.vehicle.directive.repository.Directive80Repository;
27 28 import com.bsth.vehicle.directive.repository.LineChangeRepository;
  29 +import com.bsth.vehicle.directive.service.DirectiveService;
28 30 import com.bsth.vehicle.directive.util.HttpUtils;
29 31 import com.bsth.websocket.handler.RealControlSocketHandler;
30 32 import com.google.common.collect.ArrayListMultimap;
... ... @@ -49,6 +51,9 @@ public class DirectiveBuffer {
49 51 @Autowired
50 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 128  
124 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 137 transientList.add(directive);
129 138 }
... ...
src/main/java/com/bsth/vehicle/directive/entity/Directive60.java
... ... @@ -59,12 +59,12 @@ public class Directive60 {
59 59 /**
60 60 * 46上行
61 61 */
62   - private Short reply46;
  62 + private Short reply46 = -1;
63 63  
64 64 /**
65 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 59 * @throws
60 60 */
61 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 111 directive.setSch(sch);
112 112 DirectiveBuffer.put(directive);
113 113 //通知页面,消息已发出
114   - sendDirectiveState(sch);
  114 + sendDirectiveToPage(sch);
115 115 }else{
116 116 logger.error("send60Phrase error, code: " + code);
117 117 }
... ... @@ -124,7 +124,8 @@ public class DirectiveServiceImpl extends BaseServiceImpl&lt;Directive60, Integer&gt;
124 124 * @Description: TODO(向页面推送班次指令状态)
125 125 * @throws
126 126 */
127   - public void sendDirectiveState(ScheduleRealInfo sch){
  127 + @Override
  128 + public void sendDirectiveToPage(ScheduleRealInfo sch){
128 129 JSONObject json = new JSONObject();
129 130 json.put("fn", "directive");
130 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 27 @Override
28 28 public void run() {
29 29  
30   - Set<String> keys = ScheduleBuffer.vehSchListMap.keySet();
  30 + Set<String> keys = ScheduleBuffer.carSchListMap.keySet();
31 31 List<ScheduleRealInfo> list;
32 32  
33 33 Long t = System.currentTimeMillis();
34 34 ScheduleRealInfo sch;
35 35 for(String nbbm : keys){
36   - list = ScheduleBuffer.vehSchListMap.get(nbbm);
  36 + list = ScheduleBuffer.carSchListMap.get(nbbm);
37 37  
38 38 if(list.size() == 0)
39 39 continue;
... ...
src/main/java/com/bsth/vehicle/gpsdata/GpsArrivalStationThread_old.java
... ... @@ -64,7 +64,7 @@ public class GpsArrivalStationThread_old extends Thread{
64 64 System.out.println("开始...");
65 65 List<ScheduleRealInfo> schList;
66 66 for(String key : keySet){
67   - schList = extractSched(ScheduleBuffer.vehSchListMap.get(key));
  67 + schList = extractSched(ScheduleBuffer.carSchListMap.get(key));
68 68 if(null != schList)
69 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 import java.text.SimpleDateFormat;
8 8 import java.util.ArrayList;
9 9 import java.util.Calendar;
10   -import java.util.Date;
11 10 import java.util.HashSet;
12 11 import java.util.List;
13 12 import java.util.Set;
... ... @@ -17,13 +16,11 @@ import org.slf4j.LoggerFactory;
17 16 import org.springframework.beans.factory.annotation.Autowired;
18 17 import org.springframework.stereotype.Component;
19 18  
20   -import com.alibaba.fastjson.JSONObject;
21 19 import com.bsth.entity.realcontrol.ScheduleRealInfo;
22   -import com.bsth.service.realcontrol.buffer.ScheduleBuffer;
23 20 import com.bsth.util.DateUtils;
24 21 import com.bsth.util.db.DBUtils_MS;
25   -import com.bsth.vehicle.common.CommonMapped;
26 22 import com.bsth.vehicle.directive.service.DirectiveService;
  23 +import com.bsth.vehicle.gpsdata.arrival.MatchService;
27 24 import com.bsth.vehicle.gpsdata.buffer.GpsArrivalDataBuffer;
28 25 import com.bsth.vehicle.gpsdata.entity.ArrivalInfo;
29 26 import com.bsth.websocket.handler.RealControlSocketHandler;
... ... @@ -31,13 +28,13 @@ import com.bsth.websocket.handler.RealControlSocketHandler;
31 28 /**
32 29 *
33 30 * @ClassName: GpsArrivalStationThread
34   - * @Description: TODO(GPS到离站)
  31 + * @Description: TODO(定时从数据库加载到离站数据)
35 32 * @author PanZhao
36 33 * @date 2016年6月27日 上午10:58:13
37 34 *
38 35 */
39 36 @Component
40   -public class GpsArrivalStationThread extends Thread{
  37 +public class GpsArrivalThread extends Thread{
41 38  
42 39 Logger logger = LoggerFactory.getLogger(this.getClass());
43 40 SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");
... ... @@ -60,8 +57,26 @@ public class GpsArrivalStationThread extends Thread{
60 57 }
61 58 //缓存
62 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 80 Set<String> set = new HashSet<>();
66 81 for(ArrivalInfo arr : list)
67 82 set.add(CommonMapped.vehicDeviceBiMap.get(arr.getDeviceId()));
... ... @@ -109,10 +124,10 @@ public class GpsArrivalStationThread extends Thread{
109 124 }catch(Exception e){
110 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 132 List<ArrivalInfo> in = new ArrayList<>(), out = new ArrayList<>();
118 133 for(ArrivalInfo arr : arrList){
... ... @@ -134,7 +149,7 @@ public class GpsArrivalStationThread extends Thread{
134 149 }
135 150  
136 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 153 for(ArrivalInfo arr : arrList){
139 154 if(arr.getStopNo().equals(sch.getQdzCode())
140 155 && Math.abs((arr.getTs() - sch.getFcsjT())) < space){
... ... @@ -148,7 +163,7 @@ public class GpsArrivalStationThread extends Thread{
148 163 }
149 164  
150 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 167 for(ArrivalInfo arr : arrList){
153 168 if(arr.getStopNo().equals(sch.getZdzCode())
154 169 && Math.abs((arr.getTs() - sch.getZdsjT())) < space){
... ... @@ -158,7 +173,7 @@ public class GpsArrivalStationThread extends Thread{
158 173 }
159 174 }
160 175 return null;
161   - }
  176 + }*/
162 177  
163 178  
164 179 /**
... ... @@ -167,7 +182,7 @@ public class GpsArrivalStationThread extends Thread{
167 182 * @param @param schedule 班次
168 183 * @throws
169 184 */
170   - public void sendFcsj(ScheduleRealInfo schedule){
  185 +/* public void sendFcsj(ScheduleRealInfo schedule){
171 186 JSONObject json = new JSONObject();
172 187 json.put("fn", "faChe");
173 188 json.put("t", schedule);
... ... @@ -175,12 +190,12 @@ public class GpsArrivalStationThread extends Thread{
175 190 socketHandler.sendMessageToLine(Integer.parseInt(schedule.getXlBm()), json.toJSONString());
176 191 }
177 192  
178   - /**
  193 + *//**
179 194 * @Title: sendFcsj
180 195 * @Description: TODO(推送到达终点时间)
181 196 * @param @param schedule 班次
182 197 * @throws
183   - */
  198 + *//*
184 199 public void sendZdsj(ScheduleRealInfo schedule,ScheduleRealInfo nextSch, int finish){
185 200 JSONObject json = new JSONObject();
186 201 json.put("fn", "zhongDian");
... ... @@ -190,7 +205,7 @@ public class GpsArrivalStationThread extends Thread{
190 205 json.put("dataStr", sdf.format(new Date()));
191 206  
192 207 socketHandler.sendMessageToLine(Integer.parseInt(schedule.getXlBm()), json.toJSONString());
193   - }
  208 + }*/
194 209  
195 210 /**
196 211 * @throws ParseException
... ... @@ -210,7 +225,7 @@ public class GpsArrivalStationThread extends Thread{
210 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 230 List<ArrivalInfo> list = new ArrayList<>();
216 231 Connection conn = null;
... ... @@ -219,8 +234,8 @@ public class GpsArrivalStationThread extends Thread{
219 234 try {
220 235 conn = DBUtils_MS.getConnection();
221 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 240 Long t = System.currentTimeMillis();
226 241 rs = ps.executeQuery();
... ... @@ -230,6 +245,7 @@ public class GpsArrivalStationThread extends Thread{
230 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 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 1 package com.bsth.vehicle.gpsdata.buffer;
2 2  
  3 +import java.util.ArrayList;
3 4 import java.util.Collections;
4 5 import java.util.Comparator;
5 6 import java.util.HashMap;
... ... @@ -8,7 +9,7 @@ import java.util.Map;
8 9  
9 10 import com.bsth.vehicle.common.CommonMapped;
10 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 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 47 List<ArrivalInfo> all = allMap.get(nbbm);
46 48 int size = all.size();
47 49 if(size == 0)
48   - return null;
  50 + return new ArrayList<>(0);
49 51  
50 52 List<ArrivalInfo> rs = all.subList(mark, size);
51   -
52 53 markMap.put(nbbm, size);
53 54 return rs;
54 55 }
55 56  
56 57 static {
57   - allMap = LinkedListMultimap.create();
  58 + allMap = ArrayListMultimap.create();
58 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 143 gpsData.setStationName(CommonMapped.stationCodeMap.get(gpsData.getStopNo()));
144 144  
145 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 152 if(current != null)
149 153 gpsData.setCurrSchId(current.getId());
... ...
src/main/java/com/bsth/vehicle/gpsdata/entity/ArrivalInfo.java
... ... @@ -16,14 +16,20 @@ import javax.persistence.Transient;
16 16 public class ArrivalInfo {
17 17  
18 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 23 public ArrivalInfo(String deviceId, Long ts, String lineCode, Integer upDown, String stopNo, Integer inOut,
24 24 Date createDate, Integer weeksYear) {
25 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 33 this.ts = ts;
28 34  
29 35 this.lineCode = lineCode;
... ... @@ -162,4 +168,8 @@ public class ArrivalInfo {
162 168 public void setStopName(String stopName) {
163 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 139  
140 140 //如果是同一天
141 141 if(sDayOfYear == eDayOfYear){
142   - weekCal.setTimeInMillis(st);
  142 + weekCal.setTimeInMillis(st * 1000);
143 143 list = findByTs(weekCal.get(Calendar.WEEK_OF_YEAR), sDayOfYear, st, et, devices);
144 144 }
145 145 else{
... ... @@ -160,7 +160,7 @@ public class GpsDataServiceImpl implements GpsDataService{
160 160 tempEt = DateUtils.getTimesnight(sCal);
161 161 }
162 162  
163   - weekCal.setTimeInMillis(tempSt);
  163 + weekCal.setTimeInMillis(tempSt * 1000);
164 164 list.addAll(findByTs(weekCal.get(Calendar.WEEK_OF_YEAR), i, tempSt, tempEt, devices));
165 165 //加一天
166 166 sCal.add(Calendar.DATE, 1);
... ... @@ -244,6 +244,7 @@ public class GpsDataServiceImpl implements GpsDataService{
244 244 return list;
245 245 }
246 246  
  247 + //weekOfYear 算错了
247 248 public Map<String, ArrivalInfo> findArrivalByTs(int weekOfYear, Long st, Long et, String devicesInSql){
248 249 Map<String, ArrivalInfo> map = new HashMap<>();
249 250  
... ... @@ -275,4 +276,10 @@ public class GpsDataServiceImpl implements GpsDataService{
275 276 }
276 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 500 //主任务id
501 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 510 var htmlStr = template('child_task_sub_table_temp', {list: rs});
505 511  
506 512 dictionaryUtils.transformDom(
507 513 $subTab.find('tbody').html(htmlStr).find('.nt-dictionary')
508 514 );
509   - });
  515 + }); */
510 516 }
511 517 </script>
... ...
src/main/resources/static/pages/control/line/child_pages/js/child_task.js
... ... @@ -335,12 +335,15 @@ var childTaskCase = {
335 335 };
336 336  
337 337 function childTaskSubmit(fs, layerIndex){
338   - syncSubmit(fs, function(){
  338 + syncSubmit(fs, function(rs){
339 339 layer.msg('子任务添加成功');
340 340 setTimeout(function(){
341 341 layer.close(layerIndex);
342 342 //刷新子任务列表
343   - refreshChildTasks();
  343 + if(rs.status == 'SUCCESS'){
  344 + _alone.refreshSchedule(rs.t);
  345 + refreshChildTasks();
  346 + }
344 347 }, 700);
345 348 });
346 349 }
... ... @@ -353,10 +356,11 @@ function syncSubmit(fs, cb){
353 356 if(fs.length == 0) return;
354 357 //备注
355 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 360 (function(){
  361 +
358 362 if(i == len){
359   - cb && cb();
  363 + cb && cb(cbRs);
360 364 return;
361 365 }
362 366  
... ... @@ -365,12 +369,15 @@ function syncSubmit(fs, cb){
365 369 ,params = $(form).serializeJSON();
366 370  
367 371 params.remarks = remarks;
368   - $post('/childTask', params, function(){
  372 + $post('/childTask', params, function(rs){
  373 + console.log('item rs: ' ,rs);
369 374 $(form).parent().find('.task-item-close').replaceWith('<a class="task-item-success"><i class="fa fa-check-circle" ></i></a>');
370 375 i ++;
371 376 //做一层防护,防止缺心眼出现无限循环提交
372 377 if(i == 0)
373 378 return;
  379 +
  380 + cbRs = rs;
374 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 2166 color: #afafaf !important;
2167 2167 }
2168 2168  
  2169 +.pb-table tr.selected.next-sch a{
  2170 + color: white !important;
  2171 +}
  2172 +
2169 2173 .tab_line .pb-table tr._tr_active.active-line-no a.remarks-popover{
2170 2174 color: #bebebe;
2171 2175 }
2172 2176  
2173 2177 .tab_line .pb-table tr._tr_active.active-line-no td.tl-qrlb,
2174 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 2181 background: none;
2177 2182 color: #ff796a;
2178 2183 }
2179 2184 .tab_line .pb-table tr._tr_active.active-line-no td.tl-zzzx,
2180 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 2188 background: none;
2183 2189 color: #5ae35a;
2184 2190 }
2185 2191 .tab_line .pb-table tr._tr_active.active-line-no td.tl-yzx,
2186 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 2195 background: none;
2189 2196 color: #80c8fa;
2190 2197 }
2191 2198 .tab_line .pb-table tr._tr_active.active-line-no td.tl-xxfc,
2192 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 2202 background: none;
2195 2203 color: #a16dff;
2196 2204 }
2197 2205  
2198 2206 .tab_line .pb-table tr._tr_active.active-line-no td.tl-xxsd,
2199 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 2210 background: none;
2202 2211 color: #ffb193;
2203 2212 }
2204 2213  
  2214 +
2205 2215 .tab_line .pb-table tr._tr_active.active-line-no td.tl-xxrd,
2206 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 2219 background: none;
2209 2220 color: #5cb0e9;
2210 2221 }
... ...
src/main/resources/static/pages/control/line/index.html
... ... @@ -136,7 +136,7 @@
136 136 <li class="menu-separator"></li>
137 137 <li class="menu-item" >
138 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 140 </button>
141 141 </li>
142 142 <!-- <li class="menu-item disabled" >
... ... @@ -144,7 +144,6 @@
144 144 <span class="menu-text">误点调整</span>
145 145 </button>
146 146 </li> -->
147   - <li class="menu-separator"></li>
148 147 <li class="menu-item" >
149 148 <button type="button" class="menu-btn" data-method="schInfoFineTune">
150 149 <span class="menu-text">发车信息微调</span>
... ...
src/main/resources/static/pages/control/line/js/alone.js
... ... @@ -165,6 +165,9 @@ var _alone = (function(){
165 165 function calculateLineNo(table){
166 166 var rows = table.rows;
167 167 $.each(rows,function(i, r){
  168 + if($(r).hasClass('child-task-list'))
  169 + return true;
  170 +
168 171 var cells = r.cells;
169 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  
9 9 //实时GPS数据
10 10 var allGps = {};
11   - //300秒刷新一次实时GPS
12   - var realGpsT = 1000 * 300;
  11 + //10秒刷新一次实时GPS
  12 + var realGpsT = 1000 * 10;
13 13  
14 14 var dateStr = moment().format('YYYY-MM-DD');
15 15 //实际排班
... ... @@ -29,7 +29,7 @@ var _data = (function(){
29 29 var carDeviceIdMapp = {};
30 30  
31 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 35 var dataObject = {
... ... @@ -288,23 +288,22 @@ var _data = (function(){
288 288 for(var i = 0, gps; gps=gpsList[i++];){
289 289 oldGps = prve[gps.deviceId];
290 290 if(!oldGps){
291   - //添加
292   - prve[gps.deviceId] = gps;
293 291 addArray.push(gps);
294 292 }
295 293 else if(gps.timestamp > oldGps.timestamp){
296 294 //更新
297 295 upArray.push(gps);
298 296 }
  297 + allGps[gps.deviceId] = gps;
299 298 }
300 299 cb && cb(addArray, upArray);
301 300 }
302 301  
303 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 308 //停止gps刷新
310 309 clearTimeout(gpsTimer);
... ...
src/main/resources/static/pages/control/line/js/drawSvg.js
... ... @@ -62,6 +62,10 @@ var drawSvg = (function(){
62 62 //线路编码 和 单线路SVG对照
63 63 aloneSvgMapp[lineId] = svg;
64 64 },
  65 + clear: function(){
  66 + for(var k in seGps)
  67 + seGps[k] = [];
  68 + },
65 69 init: function(lineId, data, container, w, mtop){
66 70 if(!data || data.length == 0)
67 71 return;
... ... @@ -176,12 +180,34 @@ var drawSvg = (function(){
176 180  
177 181 //画出GPS点
178 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 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 213 //画出起终点GPS信号
... ... @@ -189,34 +215,42 @@ var drawSvg = (function(){
189 215 for(var eid in seGps){
190 216 len = seGps[eid].length;
191 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 255 * 堆叠多个GPS信号
222 256 */
... ... @@ -245,7 +279,7 @@ var drawSvg = (function(){
245 279 });
246 280  
247 281 function drawNumber(multiGps, num, that, start, end){
248   - var circle = $('#' + $(multiGps).attr('for'))
  282 + /*var circle = $('#' + $(multiGps).attr('for'))
249 283 ,x = circle.attr('cx')
250 284 ,y = circle.attr('cy');
251 285  
... ... @@ -258,23 +292,24 @@ var drawSvg = (function(){
258 292 numberG.classed({'end': true});//终点站
259 293  
260 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 301 var stionId = gps.lineId + '_' + gps.stopNo
268   - ,station = $('#' + stionId)
  302 + ,station = $('#' + stionId, svg[0])/*
269 303 ,c = station.attr('class')||""
270 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 308 if(station.length == 0)
274 309 return;
275 310  
276 311 //起终点站GPS信号
277   - if(seGps[stionId]){
  312 + if(flag && seGps[stionId]){
278 313 seGps[stionId].push(gps);
279 314 return;
280 315 }
... ... @@ -285,7 +320,7 @@ var drawSvg = (function(){
285 320 ,gpsGWrap = svg.select('.gps-g-wrap')
286 321 ,gpscont;
287 322  
288   - if($('g[for='+stionId+']').length == 0){
  323 + if($('g[for='+stionId+']', svg[0]).length == 0){
289 324 gpscont = gpsGWrap.append('g')
290 325 .attr('class', 'station-gps-container')
291 326 .attr('updown', updown)
... ... @@ -338,8 +373,9 @@ var drawSvg = (function(){
338 373 .attr('cx', cx)
339 374 .attr('cy', updown=='up'?mt:mt + p)
340 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 380 .attr('updown', updown=='up'?0:1)
345 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 28 if(!array || array.length == 0)
29 29 layer.msg('没有找到相关班次信息!');
30 30 else{
31   - //定位到当前正在执行的班次
32   - var sch;
  31 + var runingSch,nearestSch;
  32 + //当前时间戳,忽略毫秒
  33 + var t = Date.parse(new Date());
33 34 $.each(array, function(){
  35 + //正在执行的班次
34 36 if(this.status == 1)
35 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 48 if(!sch)
38   - sch = array[0];
  49 + sch = nearestSch;
39 50  
40 51 var delay;
41 52 //当前选中的选项卡
... ...
src/main/resources/static/pages/control/line/js/main.js
... ... @@ -42,7 +42,6 @@
42 42 $('#tab_home').html(homeHtmlStr);
43 43 //计算高度 40 页脚
44 44 var ah = $('#top-tabs-wrap .tab-content').height() - 40 - 5;
45   - console.log(ah);
46 45 $('.card_wrap').css('height', ah / 3);
47 46  
48 47 //滚动条
... ... @@ -67,16 +66,18 @@
67 66 var list = _data.findAllGps();
68 67 _data.attachSchedulInfo(list);
69 68  
70   - drawSvg.drawVehicle(list);
71   -
  69 + //drawSvg.drawVehicle(list);
72 70 //按线路分组
73 71 var listMap = groupByLine(list);
74   - console.log('listMap', listMap);
  72 +
75 73 for(var key in listMap){
76 74 var htmlStr = template('home_table_temp', {list: listMap[key]});
77 75 $('#tab_' + key).find('tbody').html(htmlStr);
78 76 //更新badge
79 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 357 layer.close(index);
358 358 $post('/realSchedule/realOutAdjust', params
359 359 ,function(rs){
360   - if(rs.t){
  360 + if(rs.ts){
361 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 375 shift :5,
376 376 }, function(){
377 377 $post('/realSchedule/revokeRealOutgo', {id: schedul.id}, function(rs){
378   - if(rs.t){
  378 + console.log(rs);
  379 + if(rs.ts){
379 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 546  
546 547 $post('/realSchedule/schInfoFineTune', params, function(rs){
547 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 20 <td>待发</td>
21 21 <td>实发</td>
22 22 <td class="hide-lt-1080">原因</td>
23   - <!--<td>类型</td>-->
24 23 </tr>
25 24 </thead>
26 25 </table>
... ... @@ -52,7 +51,6 @@
52 51 <td>待发</td>
53 52 <td>实发</td>
54 53 <td class="hide-lt-1080">原因</td>
55   - <!--<td>类型</td>-->
56 54 </tr>
57 55 </thead>
58 56 </table>
... ... @@ -148,13 +146,35 @@
148 146 <td data-name="sjfcsj" class="sfsj-item">{{item.fcsjActual}}<span class="fcsj-diff">{{item.fcsj_diff}}</span></td>
149 147 {{/if}}
150 148  
151   - <td class="hide-lt-1080" data-name="remarks">
  149 +<td class="hide-lt-1080" data-name="remarks">
152 150 {{if item.remarks != null && item.remarks.length > 0}}
153 151 <a class="remarks-popover" href="javascript:;" data-toggle="popover" data-content="{{item.remarks}}" >查看...</a>
154 152 {{/if}}
155 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 178 {{/each}}
159 179 </script>
160 180  
... ...
src/main/resources/static/pages/mapmonitor/real/css/real.css
... ... @@ -503,7 +503,7 @@ html{
503 503  
504 504 .mapRightWrap .search_result .item_vehicle_list{
505 505 margin-bottom: 20px;
506   - border-bottom: 1px solid #F3F5F5;
  506 + /* border-bottom: 1px solid #F3F5F5; */
507 507 }
508 508  
509 509 .mapRightWrap .search_result .item_vehicle{
... ... @@ -696,7 +696,7 @@ display: none;
696 696 .play-back-btns{
697 697 display: none;
698 698 background: rgb(255, 255, 255);
699   - width: 206px;
  699 + width: 216px;
700 700 height: 44px;
701 701 position: absolute;
702 702 right: 320px;
... ... @@ -776,7 +776,7 @@ display: none;
776 776 font-size: 15px;
777 777 vertical-align: middle;
778 778 font-weight: 600;
779   - margin-right: 12px;
  779 + margin-right: 5px;
780 780 color: #565555;
781 781 padding: 4px 8px 4px 13px;
782 782 cursor: pointer;
... ...
src/main/resources/static/pages/mapmonitor/real/js/map_platform.js
... ... @@ -51,6 +51,8 @@ var realMap = (function() {
51 51 //百度 -轨迹回放点聚合
52 52 //var historyClusterer;
53 53  
  54 + var markerClusterer;
  55 +
54 56 //设备号和marker对照
55 57 var markersMap;
56 58 var real_map = {
... ... @@ -125,6 +127,8 @@ var realMap = (function() {
125 127 },
126 128 clear: function(){
127 129 currentMap.map.clearOverlays();
  130 + markerClusterer && markerClusterer.clearMarkers();
  131 +
128 132 },
129 133 change : function() {
130 134 if(currentMap.mapName == REAL_BAIDU_TEXT)
... ... @@ -212,7 +216,9 @@ var realMap = (function() {
212 216 drawGpsMarker: function(gpsList){
213 217 markersMap = {};
214 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 222 real_map.baidu.coordsConvert(gpsList, function(){
217 223 //绘制车辆位置
218 224 var marker;
... ...
src/main/resources/static/pages/mapmonitor/real/js/playBack.js
... ... @@ -102,8 +102,11 @@ var playBack = (function() {
102 102 marker = markerMap[gps.nbbm];
103 103 if(marker)
104 104 getCurrMap().moveMarker(marker, gps);//移动marker
105   - else
  105 + else{
106 106 markerMap[gps.nbbm] = getCurrMap().addHistoryMarker(gps);//添加marker
  107 + //定位到marker
  108 + getCurrMap().markerToCenter(markerMap[gps.nbbm]);
  109 + }
107 110  
108 111 if(gps.inout_stop != -1){
109 112 //到离站信息
... ... @@ -123,6 +126,8 @@ var playBack = (function() {
123 126 function addInOutText(gps){
124 127 var info = gps.inout_stop_info
125 128 ,date = moment(gps.ts).format('HH:mm.ss');
  129 + if(!info)
  130 + return;
126 131 var html = '<div class="pback-logs-item">'+
127 132 gps.nbbm + ' '+ (info.inOut==1?'出':'进') +'站 '+info.stopName+' '+
128 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 8 return realMap[realMap.getMap().fName];
9 9 }
10 10  
  11 + var allGps;
  12 +
11 13 var exports = {
12 14 init : function() {
13 15 var htmlStr = template('search_panel_temp', {});
14 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 56 var resultHtml = template('search_result_temp', json);
21 57 $('.mapRightWrap .search_result').html(resultHtml);
  58 + //搜索车辆
  59 + //console.log(json);
22 60 });
23 61  
24 62 //查询结果选中事件
25 63 $('.search_result').on('click', '.result_item'
26 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 30 //收拢其他
31 31 closeAll();
32 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 41 //绘制线路和GPS
37   - function drawLineAndGps(lineCode){
  42 + function drawLineAndGps(lineCode, callFun){
38 43 //过滤出该线路的GPS点
39 44 var showList = [], gps;
40   - if(lineGps[lineCode]){
  45 + /*if(lineGps[lineCode]){
41 46 $.each(lineGps[lineCode], function(){
42 47 gps = allGps[this];
43 48 showList.push(gps);
44 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 58 var htmlStr = template('vehicle_panel_collapse_temp', {list: showList});
49 59 $('#collapse_' + lineCode).html(htmlStr);
... ... @@ -53,13 +63,10 @@ var vehiclePanel = (function() {
53 63 */
54 64 var that = $(this);
55 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 67 //画GPS
62   - mapObj.drawGpsMarker(showList);
  68 + getCurrMap().drawGpsMarker(showList);
  69 +
63 70 }, 500);
64 71 }
65 72  
... ... @@ -78,7 +85,7 @@ var vehiclePanel = (function() {
78 85  
79 86 //GPS刷新事件
80 87 var allGps = {};
81   - var lineGps = {};
  88 + //var lineGps = {};
82 89 $('#mapContainer').on('gps_refresh', function(e, add, up){
83 90 var temp = add;
84 91 if(up)
... ... @@ -90,23 +97,24 @@ var vehiclePanel = (function() {
90 97 allGps[this.deviceId] = this;
91 98 });
92 99  
93   - $.each(add, function(){
  100 + /* $.each(add, function(){
94 101 if(!lineGps[this.lineId])
95 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 109 if(cLineCode){
103   - var showList = [];
  110 + drawLineAndGps(cLineCode);
  111 + /*var showList = [];
104 112 if(lineGps[cLineCode]){
105 113 $.each(lineGps[cLineCode], function(){
106 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 154 },
147 155 drawLineAndGps: function(lineCode){
148 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 1 <script id="search_panel_temp" type="text/html">
2 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 4 <span class="input-group-btn">
5 5 <button class="btn" type="button"><i class="fa fa-search"></i> 搜索</button>
6 6 </span>
... ... @@ -11,19 +11,18 @@
11 11 </script>
12 12  
13 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 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 26 {{if type == "baidu"}}
28 27 {{each result as obj i}}
29 28 <p class="result_item" data-title="{{obj.business}}">
... ... @@ -39,4 +38,4 @@
39 38 </p>
40 39 {{/each}}
41 40 {{/if}}
42   -</script>
  41 + -->
43 42 \ No newline at end of file
... ...
src/main/resources/static/pages/mapmonitor/real/temps/vehicle.html
... ... @@ -34,7 +34,7 @@
34 34 <span style="font-size: 13px;">{{gpsObj.stationName}}</span>
35 35 </div>
36 36 <div class="icon">
37   - <i class="fa fa-file-text-o"></i>
  37 + <!--<i class="fa fa-file-text-o"></i>-->
38 38 </div>
39 39 </div>
40 40 {{/each}}
... ...