Commit e331185a3a9e9df7c1ea7461261fdac4fa1a3942

Authored by 徐烜
2 parents 1dafaf64 6ef6d97e

Merge branch 'PSM-7'

Too many changes to show.

To preserve performance only 24 of 52 files are displayed.

@@ -219,6 +219,12 @@ @@ -219,6 +219,12 @@
219 <artifactId>jaxrpc-api</artifactId> 219 <artifactId>jaxrpc-api</artifactId>
220 <version>1.1</version> 220 <version>1.1</version>
221 </dependency> 221 </dependency>
  222 +
  223 + <dependency>
  224 + <groupId>org.springframework.boot</groupId>
  225 + <artifactId>spring-boot-devtools</artifactId>
  226 + <optional>true</optional>
  227 + </dependency>
222 </dependencies> 228 </dependencies>
223 229
224 <dependencyManagement> 230 <dependencyManagement>
@@ -248,7 +254,6 @@ @@ -248,7 +254,6 @@
248 <artifactId>maven-war-plugin</artifactId> 254 <artifactId>maven-war-plugin</artifactId>
249 <version>2.2</version><!--$NO-MVN-MAN-VER$ --> 255 <version>2.2</version><!--$NO-MVN-MAN-VER$ -->
250 <configuration> 256 <configuration>
251 - <version>3.1</version>  
252 <failOnMissingWebXml>false</failOnMissingWebXml> 257 <failOnMissingWebXml>false</failOnMissingWebXml>
253 </configuration> 258 </configuration>
254 </plugin> 259 </plugin>
@@ -257,6 +262,12 @@ @@ -257,6 +262,12 @@
257 <artifactId>spring-boot-maven-plugin</artifactId> 262 <artifactId>spring-boot-maven-plugin</artifactId>
258 </plugin> 263 </plugin>
259 </plugins> 264 </plugins>
  265 + <resources>
  266 + <resource>
  267 + <directory>src/main/resources</directory>
  268 + <filtering>false</filtering>
  269 + </resource>
  270 + </resources>
260 </build> 271 </build>
261 <repositories> 272 <repositories>
262 <repository> 273 <repository>
src/main/java/com/bsth/controller/realcontrol/BasicDataController.java
@@ -21,6 +21,11 @@ public class BasicDataController { @@ -21,6 +21,11 @@ public class BasicDataController {
21 return BasicData.deviceId2NbbmMap.values(); 21 return BasicData.deviceId2NbbmMap.values();
22 } 22 }
23 23
  24 + @RequestMapping("/nbbm2deviceId")
  25 + public Map<String, String> nbbm2deviceId(Map<String, Object> map){
  26 + return BasicData.deviceId2NbbmMap.inverse();
  27 + }
  28 +
24 @RequestMapping("/lineCode2Name") 29 @RequestMapping("/lineCode2Name")
25 public Map<String, String> findLineCodeMap(){ 30 public Map<String, String> findLineCodeMap(){
26 return BasicData.lineCode2NameMap; 31 return BasicData.lineCode2NameMap;
src/main/java/com/bsth/controller/schedule/TTInfoDetailController.java
@@ -116,6 +116,7 @@ public class TTInfoDetailController extends BaseController&lt;TTInfoDetail, Long&gt; { @@ -116,6 +116,7 @@ public class TTInfoDetailController extends BaseController&lt;TTInfoDetail, Long&gt; {
116 if (sheet.getRows() == 0 || sheet.getColumns() == 0) { // 工作区是否为空 116 if (sheet.getRows() == 0 || sheet.getColumns() == 0) { // 工作区是否为空
117 rtn.put("status", ResponseCode.ERROR); 117 rtn.put("status", ResponseCode.ERROR);
118 rtn.put("msg", String.format("%s 工作区没有数据!", sheetname)); 118 rtn.put("msg", String.format("%s 工作区没有数据!", sheetname));
  119 + return rtn;
119 } else { 120 } else {
120 if (sheet.getRows() <= 1 || sheet.getColumns() <= 1) { 121 if (sheet.getRows() <= 1 || sheet.getColumns() <= 1) {
121 rtn.put("status", ResponseCode.ERROR); 122 rtn.put("status", ResponseCode.ERROR);
@@ -147,11 +148,11 @@ public class TTInfoDetailController extends BaseController&lt;TTInfoDetail, Long&gt; { @@ -147,11 +148,11 @@ public class TTInfoDetailController extends BaseController&lt;TTInfoDetail, Long&gt; {
147 List<StationRoute> stationRouteList = (List<StationRoute>) stationRouteService.list(p1); 148 List<StationRoute> stationRouteList = (List<StationRoute>) stationRouteService.list(p1);
148 if (CollectionUtils.isEmpty(stationRouteList)) { 149 if (CollectionUtils.isEmpty(stationRouteList)) {
149 rtn.put("status", ResponseCode.ERROR); 150 rtn.put("status", ResponseCode.ERROR);
150 - rtn.put("msg", String.format("第1行,第%d列数据在%s站点路由中不是起点站", i + 1, linename)); 151 + rtn.put("msg", String.format("第1行,第%d列数据%s在%s站点路由中不是起点站", i + 1, cell_con.trim(), linename));
151 return rtn; 152 return rtn;
152 } else if (stationRouteList.size() > 1) { 153 } else if (stationRouteList.size() > 1) {
153 rtn.put("status", ResponseCode.ERROR); 154 rtn.put("status", ResponseCode.ERROR);
154 - rtn.put("msg", String.format("第1行,第%d列数据在%s站点路由中上下行都是起点站", i + 1, linename)); 155 + rtn.put("msg", String.format("第1行,第%d列数据%s在%s站点路由中上下行都是起点站", i + 1, cell_con.trim(), linename));
155 return rtn; 156 return rtn;
156 } 157 }
157 } 158 }
@@ -363,6 +364,7 @@ public class TTInfoDetailController extends BaseController&lt;TTInfoDetail, Long&gt; { @@ -363,6 +364,7 @@ public class TTInfoDetailController extends BaseController&lt;TTInfoDetail, Long&gt; {
363 364
364 ttInfoDetailService.fileDataImport( 365 ttInfoDetailService.fileDataImport(
365 new File(filename + "_temp.xls"), 366 new File(filename + "_temp.xls"),
  367 + (String) form.get("sheetname"),
366 (String) form.get("xlname"), 368 (String) form.get("xlname"),
367 (String) form.get("ttname"), 369 (String) form.get("ttname"),
368 tccname 370 tccname
src/main/java/com/bsth/data/BasicData.java
@@ -140,7 +140,7 @@ public class BasicData implements CommandLineRunner{ @@ -140,7 +140,7 @@ public class BasicData implements CommandLineRunner{
140 //车辆和线路映射信息 140 //车辆和线路映射信息
141 loadNbbm2LineInfo(); 141 loadNbbm2LineInfo();
142 //站点路由信息 142 //站点路由信息
143 - loadStationRouteInfo(); 143 + loadStationRouteInfo();
144 //人员信息 144 //人员信息
145 loadPersonnelInfo(); 145 loadPersonnelInfo();
146 logger.info("加载基础数据成功!," ); 146 logger.info("加载基础数据成功!," );
src/main/java/com/bsth/data/arrival/ArrivalData_GPS.java
@@ -51,7 +51,7 @@ public class ArrivalData_GPS implements CommandLineRunner{ @@ -51,7 +51,7 @@ public class ArrivalData_GPS implements CommandLineRunner{
51 @Override 51 @Override
52 public void run(String... arg0) throws Exception { 52 public void run(String... arg0) throws Exception {
53 logger.info("ArrivalData_GPS,30,10"); 53 logger.info("ArrivalData_GPS,30,10");
54 - //Application.mainServices.scheduleWithFixedDelay(dataLoaderThread, 40, 20, TimeUnit.SECONDS); 54 + //Application.mainServices.scheduleWithFixedDelay(dataLoaderThread, 40, 10, TimeUnit.SECONDS);
55 } 55 }
56 56
57 @Component 57 @Component
src/main/java/com/bsth/data/directive/GatewayHttpUtils.java
@@ -52,7 +52,7 @@ public class GatewayHttpUtils { @@ -52,7 +52,7 @@ public class GatewayHttpUtils {
52 post.setEntity(new StringEntity(jsonStr, "utf-8")); 52 post.setEntity(new StringEntity(jsonStr, "utf-8"));
53 53
54 CloseableHttpResponse response = httpClient.execute(post); 54 CloseableHttpResponse response = httpClient.execute(post);
55 - 55 +
56 JSONObject json = JSONObject.parseObject(EntityUtils.toString(response.getEntity())); 56 JSONObject json = JSONObject.parseObject(EntityUtils.toString(response.getEntity()));
57 if(null != json && json.getInteger("errCode") == 0) 57 if(null != json && json.getInteger("errCode") == 0)
58 code = 0; 58 code = 0;
src/main/java/com/bsth/data/forecast/SampleTimeDataLoader.java
1 package com.bsth.data.forecast; 1 package com.bsth.data.forecast;
2 2
3 -import java.text.SimpleDateFormat;  
4 import java.util.ArrayList; 3 import java.util.ArrayList;
5 import java.util.Collections; 4 import java.util.Collections;
6 import java.util.Comparator; 5 import java.util.Comparator;
@@ -9,6 +8,8 @@ import java.util.Iterator; @@ -9,6 +8,8 @@ import java.util.Iterator;
9 import java.util.List; 8 import java.util.List;
10 import java.util.Set; 9 import java.util.Set;
11 10
  11 +import org.joda.time.format.DateTimeFormat;
  12 +import org.joda.time.format.DateTimeFormatter;
12 import org.slf4j.Logger; 13 import org.slf4j.Logger;
13 import org.slf4j.LoggerFactory; 14 import org.slf4j.LoggerFactory;
14 import org.springframework.beans.factory.annotation.Autowired; 15 import org.springframework.beans.factory.annotation.Autowired;
@@ -39,14 +40,14 @@ public class SampleTimeDataLoader extends Thread { @@ -39,14 +40,14 @@ public class SampleTimeDataLoader extends Thread {
39 // 当天日期 40 // 当天日期
40 String rq; 41 String rq;
41 42
42 - SimpleDateFormat sdfyyyyMMddHHmm = new SimpleDateFormat("yyyy-MM-ddHH:mm"); 43 + private static DateTimeFormatter fmtyyyyMMddHHmm = DateTimeFormat.forPattern("yyyy-MM-ddHH:mm")
  44 + ,fmtyyyyMMdd = DateTimeFormat.forPattern("yyyy-MM-dd");
43 45
44 Logger logger = LoggerFactory.getLogger(this.getClass()); 46 Logger logger = LoggerFactory.getLogger(this.getClass());
45 47
46 @Override 48 @Override
47 public void run() { 49 public void run() {
48 - SimpleDateFormat sdfyyyyMMdd = new SimpleDateFormat("yyyy-MM-dd");  
49 - rq = sdfyyyyMMdd.format(new Date()); 50 + rq = fmtyyyyMMdd.print(new Date().getTime());
50 51
51 Iterator<Sample> iterator = sampleRepository.findAll().iterator(); 52 Iterator<Sample> iterator = sampleRepository.findAll().iterator();
52 ArrayListMultimap<String, Sample> sampleMap = ArrayListMultimap.create(); 53 ArrayListMultimap<String, Sample> sampleMap = ArrayListMultimap.create();
@@ -103,8 +104,9 @@ public class SampleTimeDataLoader extends Thread { @@ -103,8 +104,9 @@ public class SampleTimeDataLoader extends Thread {
103 TimeRange tg; 104 TimeRange tg;
104 for (Sample s : list) { 105 for (Sample s : list) {
105 tg = new TimeRange(); 106 tg = new TimeRange();
106 - tg.startTime = sdfyyyyMMddHHmm.parse(rq + s.getsDate()).getTime();  
107 - tg.endTime = sdfyyyyMMddHHmm.parse(rq + s.geteDate()).getTime(); 107 +
  108 + tg.startTime = fmtyyyyMMddHHmm.parseMillis(rq + s.getsDate());
  109 + tg.endTime = fmtyyyyMMddHHmm.parseMillis(rq + s.geteDate());
108 tg.runTime = s.getRunTime(); 110 tg.runTime = s.getRunTime();
109 simple.ranges.add(tg); 111 simple.ranges.add(tg);
110 } 112 }
src/main/java/com/bsth/data/gpsdata/GpsRealData.java
@@ -34,7 +34,7 @@ import com.google.common.collect.TreeMultimap; @@ -34,7 +34,7 @@ import com.google.common.collect.TreeMultimap;
34 34
35 /** 35 /**
36 * 36 *
37 - * @ClassName: GpsRealEntityBuffer 37 + * @ClassName: GpsRealData
38 * @Description: TODO(实时GPS数据集合) 38 * @Description: TODO(实时GPS数据集合)
39 * @author PanZhao 39 * @author PanZhao
40 * @date 2016年8月12日 下午2:04:41 40 * @date 2016年8月12日 下午2:04:41
@@ -73,7 +73,7 @@ public class GpsRealData implements CommandLineRunner{ @@ -73,7 +73,7 @@ public class GpsRealData implements CommandLineRunner{
73 @Override 73 @Override
74 public void run(String... arg0) throws Exception { 74 public void run(String... arg0) throws Exception {
75 logger.info("gpsDataLoader,20,6"); 75 logger.info("gpsDataLoader,20,6");
76 - Application.mainServices.scheduleWithFixedDelay(gpsDataLoader, 20, 6, TimeUnit.SECONDS); 76 + //Application.mainServices.scheduleWithFixedDelay(gpsDataLoader, 20, 6, TimeUnit.SECONDS);
77 } 77 }
78 78
79 public GpsEntity add(GpsEntity gps) { 79 public GpsEntity add(GpsEntity gps) {
src/main/java/com/bsth/data/match/Arrival2Schedule.java
1 package com.bsth.data.match; 1 package com.bsth.data.match;
2 2
3 -import java.text.SimpleDateFormat;  
4 import java.util.ArrayList; 3 import java.util.ArrayList;
5 import java.util.Collections; 4 import java.util.Collections;
6 import java.util.List; 5 import java.util.List;
7 import java.util.Set; 6 import java.util.Set;
8 7
  8 +import org.joda.time.format.DateTimeFormat;
  9 +import org.joda.time.format.DateTimeFormatter;
9 import org.slf4j.Logger; 10 import org.slf4j.Logger;
10 import org.slf4j.LoggerFactory; 11 import org.slf4j.LoggerFactory;
11 import org.springframework.beans.BeansException; 12 import org.springframework.beans.BeansException;
@@ -24,7 +25,6 @@ import com.bsth.entity.realcontrol.ScheduleRealInfo; @@ -24,7 +25,6 @@ import com.bsth.entity.realcontrol.ScheduleRealInfo;
24 import com.bsth.service.directive.DirectiveService; 25 import com.bsth.service.directive.DirectiveService;
25 import com.bsth.websocket.handler.SendUtils; 26 import com.bsth.websocket.handler.SendUtils;
26 import com.google.common.collect.ArrayListMultimap; 27 import com.google.common.collect.ArrayListMultimap;
27 -import com.google.common.collect.ListMultimap;  
28 28
29 /** 29 /**
30 * 30 *
@@ -74,8 +74,9 @@ public class Arrival2Schedule implements ApplicationContextAware { @@ -74,8 +74,9 @@ public class Arrival2Schedule implements ApplicationContextAware {
74 private ScheduleComparator.FCSJ schComparator = new ScheduleComparator.FCSJ(); 74 private ScheduleComparator.FCSJ schComparator = new ScheduleComparator.FCSJ();
75 private ArrivalComparator arrComparator = new ArrivalComparator(); 75 private ArrivalComparator arrComparator = new ArrivalComparator();
76 private MatchResultComparator mrComparator = new MatchResultComparator(); 76 private MatchResultComparator mrComparator = new MatchResultComparator();
77 - private SimpleDateFormat sdfyyyyMMddHHmm = new SimpleDateFormat("yyyy-MM-ddHH:mm");  
78 - 77 +
  78 + private static DateTimeFormatter fmtyyyyMMddHHmm = DateTimeFormat.forPattern("yyyy-MM-ddHH:mm");
  79 +
79 @Override 80 @Override
80 public void run() { 81 public void run() {
81 //班次列表 82 //班次列表
@@ -389,8 +390,9 @@ public class Arrival2Schedule implements ApplicationContextAware { @@ -389,8 +390,9 @@ public class Arrival2Schedule implements ApplicationContextAware {
389 //上行发车,和到达时间比较一下。起点一般不会立即发出 390 //上行发车,和到达时间比较一下。起点一般不会立即发出
390 if(mr.sch.getXlDir().equals("0") 391 if(mr.sch.getXlDir().equals("0")
391 && null != mr.sch.getQdzArrDateSJ()){ 392 && null != mr.sch.getQdzArrDateSJ()){
392 -  
393 - long dt = sdfyyyyMMddHHmm.parse(mr.sch.getRealExecDate() + mr.sch.getQdzArrDateSJ()).getTime(); 393 +
  394 +
  395 + long dt = fmtyyyyMMddHHmm.parseMillis(mr.sch.getRealExecDate() + mr.sch.getQdzArrDateSJ());
394 396
395 //停站时间少于 计划的3分之1,标记为漂移信号 397 //停站时间少于 计划的3分之1,标记为漂移信号
396 if((mr.ts - dt < (mr.sch.getDfsjT() - dt) / 3)){ 398 if((mr.ts - dt < (mr.sch.getDfsjT() - dt) / 3)){
src/main/java/com/bsth/data/schedule/DayOfSchedule.java
1 -package com.bsth.data.schedule;  
2 -  
3 -import java.text.ParseException;  
4 -import java.text.SimpleDateFormat;  
5 -import java.util.ArrayList;  
6 -import java.util.Collection;  
7 -import java.util.Collections;  
8 -import java.util.Date;  
9 -import java.util.HashMap;  
10 -import java.util.HashSet;  
11 -import java.util.Iterator;  
12 -import java.util.LinkedList;  
13 -import java.util.List;  
14 -import java.util.Map;  
15 -import java.util.Set;  
16 -import java.util.concurrent.TimeUnit;  
17 -  
18 -import org.slf4j.Logger;  
19 -import org.slf4j.LoggerFactory;  
20 -import org.springframework.beans.factory.annotation.Autowired;  
21 -import org.springframework.boot.CommandLineRunner;  
22 -import org.springframework.stereotype.Component;  
23 -  
24 -import com.alibaba.fastjson.JSON;  
25 -import com.alibaba.fastjson.JSONArray;  
26 -import com.bsth.Application;  
27 -import com.bsth.data.LineConfigData;  
28 -import com.bsth.data.directive.FirstScheduleCheckThread;  
29 -import com.bsth.data.gpsdata.GpsRealData;  
30 -import com.bsth.data.schedule.thread.ScheduleLateThread;  
31 -import com.bsth.data.schedule.thread.SchedulePstThread;  
32 -import com.bsth.data.schedule.thread.ScheduleRefreshThread;  
33 -import com.bsth.entity.realcontrol.LineConfig;  
34 -import com.bsth.entity.realcontrol.ScheduleRealInfo;  
35 -import com.bsth.entity.schedule.SchedulePlanInfo;  
36 -import com.bsth.repository.realcontrol.ScheduleRealInfoRepository;  
37 -import com.bsth.service.schedule.SchedulePlanInfoService;  
38 -import com.bsth.util.BatchSaveUtils;  
39 -import com.bsth.util.DateUtils;  
40 -import com.bsth.websocket.handler.SendUtils;  
41 -import com.google.common.collect.ArrayListMultimap;  
42 -import com.google.common.collect.TreeMultimap;  
43 -  
44 -/**  
45 - *  
46 - * @ClassName: DayOfSchedule  
47 - * @Description: TODO(当日实际排班)  
48 - * @author PanZhao  
49 - * @date 2016年8月15日 上午10:16:12  
50 - *  
51 - */  
52 -@Component  
53 -public class DayOfSchedule implements CommandLineRunner {  
54 -  
55 - Logger logger = LoggerFactory.getLogger(this.getClass());  
56 -  
57 - // 按车辆分组的班次数据  
58 - private static ArrayListMultimap<String, ScheduleRealInfo> nbbmScheduleMap;  
59 -  
60 - // 班次主键映射  
61 - private static Map<Long, ScheduleRealInfo> id2SchedulMap;  
62 -  
63 - // 车辆和排班起终点站对照(包括进出的停车场,区间起终点)  
64 - private static TreeMultimap<String, String> nbbm2SEStationMap;  
65 -  
66 - //车辆 ——> 当前执行班次  
67 - private static Map<String, ScheduleRealInfo> carExecutePlanMap;  
68 -  
69 - // 持久化缓冲区  
70 - public static LinkedList<ScheduleRealInfo> pstBuffer;  
71 -  
72 - // 排序器  
73 - private static ScheduleComparator.FCSJ schFCSJComparator;  
74 -  
75 - @Autowired  
76 - LineConfigData lineConfigData;  
77 -  
78 - @Autowired  
79 - ScheduleRealInfoRepository schRepository;  
80 -  
81 - @Autowired  
82 - SchedulePlanInfoService schPlanService;  
83 -  
84 - @Autowired  
85 - SchAttrCalculator schAttrCalculator;  
86 -  
87 - @Autowired  
88 - SendUtils sendUtils;  
89 -  
90 - @Autowired  
91 - GpsRealData gpsRealData;  
92 -  
93 - /** 线路当前使用的排班的日期 */  
94 - public static Map<String, String> currSchDateMap;  
95 -  
96 - static {  
97 - nbbmScheduleMap = ArrayListMultimap.create();  
98 - id2SchedulMap = new HashMap<>();  
99 - pstBuffer = new LinkedList<>();  
100 - schFCSJComparator = new ScheduleComparator.FCSJ();  
101 - currSchDateMap = new HashMap<>();  
102 - nbbm2SEStationMap = TreeMultimap.create();  
103 - carExecutePlanMap = new HashMap<>();  
104 - }  
105 -  
106 - @Autowired  
107 - ScheduleRefreshThread scheduleRefreshThread;  
108 -  
109 - @Autowired  
110 - SchedulePstThread schedulePstThread;  
111 -  
112 - @Autowired  
113 - FirstScheduleCheckThread firstScheduleCheckThread;  
114 -  
115 - @Autowired  
116 - ScheduleLateThread scheduleLateThread;  
117 -  
118 - @Override  
119 - public void run(String... arg0) throws Exception {  
120 - //翻班线程  
121 - Application.mainServices.scheduleWithFixedDelay(scheduleRefreshThread, 20, 240, TimeUnit.SECONDS);  
122 - //入库  
123 - //Application.mainServices.scheduleWithFixedDelay(schedulePstThread, 60, 60, TimeUnit.SECONDS);  
124 - //首班出场指令补发器  
125 - //Application.mainServices.scheduleWithFixedDelay(firstScheduleCheckThread, 10, 120, TimeUnit.SECONDS);  
126 - //班次误点扫描  
127 - //Application.mainServices.scheduleWithFixedDelay(scheduleLateThread, 60, 60, TimeUnit.SECONDS);  
128 - }  
129 -  
130 - public Map<String, String> getCurrSchDate() {  
131 - return currSchDateMap;  
132 - }  
133 -  
134 - /**  
135 - *  
136 - * @Title: calcSchDateB  
137 - * @Description: TODO(计算线路当前应该使用的排班日期)  
138 - */  
139 - public String calcSchDate(String lineCode) {  
140 - LineConfig conf = lineConfigData.get(lineCode);  
141 - long ct = System.currentTimeMillis();  
142 -  
143 - SimpleDateFormat sdfyyyyMMdd = new SimpleDateFormat("yyyy-MM-dd");  
144 - String schDate = sdfyyyyMMdd.format(new Date(ct));  
145 - // 小于当天起始运营时间,则取前一天的排班  
146 - if (ct < conf.getCurrStartTime())  
147 - schDate = DateUtils.subtractDay(schDate, 1);  
148 -  
149 - return schDate;  
150 - }  
151 -  
152 - /**  
153 - * @Title: reloadSch  
154 - * @Title: reloadSch  
155 - * @Description: TODO(重新载入排班)  
156 - * @param @param  
157 - * lineCode 线路编码  
158 - * @param @param  
159 - * schDate 班次日期 yyyy-MM-dd  
160 - * @param @param  
161 - * forcePlan 强制从计划调度重新抓取  
162 - */  
163 - public int reloadSch(String lineCode, String schDate, boolean forcePlan) {  
164 - try {  
165 - List<ScheduleRealInfo> list;  
166 -  
167 - if (forcePlan)  
168 - removeRealSch(lineCode, schDate);  
169 - else  
170 - clearRAMData(lineCode);  
171 -  
172 - if (existRealSch(lineCode, schDate))  
173 - list = loadRealSch(lineCode, schDate);// 从实际排班表加载  
174 - else {  
175 - list = loadPlanSch(lineCode, schDate);// 从计划排班表加载  
176 - // 写入数据库  
177 - batchSave(list);  
178 - }  
179 -  
180 - //更新线路和班次日期对照  
181 - currSchDateMap.put(lineCode, schDate);  
182 - //添加到缓存  
183 - putAll(list);  
184 -  
185 - Set<String> cars = searchAllCars(list);  
186 - //计算“起点站应到”时间  
187 - for(String nbbm : cars)  
188 - schAttrCalculator.calcQdzTimePlan(nbbmScheduleMap.get(nbbm));  
189 -  
190 - //是否是出站即出场  
191 - LineConfig conf = lineConfigData.get(lineCode);  
192 - if(conf.getOutConfig() == 2){  
193 - for(String nbbm : cars)  
194 - schAttrCalculator.connectOutSchedule(nbbmScheduleMap.get(nbbm));  
195 - }  
196 -  
197 - // 页面 翻班通知  
198 - sendUtils.shiftSchedule(lineCode);  
199 - } catch (Exception e) {  
200 - logger.error("", e);  
201 - return -1;  
202 - }  
203 -  
204 - return 0;  
205 - }  
206 -  
207 - /**  
208 - *  
209 - * @Title: searchAllCars  
210 - * @Description: TODO(搜索班次集合中的车辆)  
211 - */  
212 - private Set<String> searchAllCars(List<ScheduleRealInfo> list) {  
213 - Set<String> cars = new HashSet<>();  
214 - for(ScheduleRealInfo sch : list)  
215 - cars.add(sch.getClZbh());  
216 -  
217 - return cars;  
218 - }  
219 -  
220 - private void putAll(List<ScheduleRealInfo> list) {  
221 - for (ScheduleRealInfo sch : list)  
222 - put(sch);  
223 - }  
224 -  
225 - /**  
226 - * @Title: removeRealSch  
227 - * @Description: TODO(清除实际排班,包括数据库和内存数据)  
228 - * @param @param  
229 - * lineCode 线路编码  
230 - * @param @param  
231 - * schDate 班次日期 yyyy-MM-dd  
232 - */  
233 - public void removeRealSch(String lineCode, String schDate) throws Exception {  
234 - try {  
235 - // 清理数据库数据  
236 - schRepository.deleteByLineCodeAndDate(lineCode + "", schDate);  
237 -  
238 - // 清理内存数据  
239 - clearRAMData(lineCode + "");  
240 - } catch (Exception e) {  
241 - logger.error("removeRealSch error, " + lineCode + " -" + schDate, e);  
242 - throw e;  
243 - }  
244 - }  
245 -  
246 - /**  
247 - *  
248 - * @Title: clearRAMData  
249 - * @Description: TODO(清理内存数据)  
250 - */  
251 - public void clearRAMData(String lineCode) {  
252 - int count = 0;  
253 - List<ScheduleRealInfo> remList = new ArrayList<>();  
254 - Collection<ScheduleRealInfo> schs = nbbmScheduleMap.values();  
255 - for (ScheduleRealInfo sch : schs) {  
256 - if (sch.getXlBm().equals(lineCode))  
257 - remList.add(sch);  
258 - }  
259 -  
260 - for(ScheduleRealInfo sch : remList){  
261 - if(null != sch){  
262 - nbbmScheduleMap.remove(sch.getClZbh(), sch);  
263 - id2SchedulMap.remove(sch.getId());  
264 - count ++;  
265 - }  
266 - }  
267 -  
268 - logger.info(lineCode + "排班清理 " + count);  
269 - }  
270 -  
271 - /**  
272 - * @Title: existRealSch  
273 - * @Description: TODO(实际排班是否已存在)  
274 - */  
275 - public boolean existRealSch(String lineCode, String schDate) {  
276 - int count = schRepository.countByLineCodeAndDate(lineCode, schDate);  
277 - return count > 0;  
278 - }  
279 -  
280 - /**  
281 - * @Title: loadRealSch  
282 - * @Description: TODO(从实际排班表加载数据)  
283 - */  
284 - public List<ScheduleRealInfo> loadRealSch(String lineCode, String schDate) {  
285 - return schRepository.findByLineCodeAndDate(lineCode, schDate);  
286 - }  
287 -  
288 - /**  
289 - * @Title: loadPlanSch  
290 - * @Description: TODO(从计划排班表加载数据)  
291 - */  
292 - public List<ScheduleRealInfo> loadPlanSch(String lineCode, String schDate) {  
293 - logger.info("从计划排班表恢复排班,lineCode: " + lineCode + ", schDate: " + schDate);  
294 - List<ScheduleRealInfo> realList = new ArrayList<>();  
295 -  
296 - try {  
297 - Map<String, Object> data = new HashMap<>();  
298 - SimpleDateFormat sdfyyyyMMdd = new SimpleDateFormat("yyyy-MM-dd")  
299 - ,sdfHHmm = new SimpleDateFormat("HH:mm");  
300 -  
301 - data.put("scheduleDate_eq", sdfyyyyMMdd.parse(schDate));  
302 - data.put("xlBm_eq", lineCode);  
303 -  
304 - // 查询计划排班  
305 - List<SchedulePlanInfo> planItr = cleanSchPlanItr(schPlanService.list(data).iterator());  
306 -  
307 - // 转换为实际排班  
308 - realList = JSONArray.parseArray(JSON.toJSONString(planItr), ScheduleRealInfo.class);  
309 -  
310 - for (ScheduleRealInfo sch : realList) {  
311 - sch.setScheduleDateStr(sdfyyyyMMdd.format(sch.getScheduleDate()));  
312 - sch.setRealExecDate(sch.getScheduleDateStr());  
313 - // 计划终点时间  
314 - if (sch.getBcsj() != null) {  
315 - try{  
316 - sch.setZdsjT(sdfHHmm.parse(sch.getFcsj()).getTime() + (sch.getBcsj() * 60 * 1000));  
317 - sch.setZdsj(sdfHHmm.format(sch.getZdsjT()));  
318 - sch.setLate(false);  
319 - }catch(ParseException pe){  
320 - logger.error("loadPlanSch... 计算终点时间失败...");  
321 - }  
322 - }  
323 - //计划里程为0,直接清空  
324 - if(sch.getJhlc() != null && sch.getJhlc() == 0)  
325 - sch.setJhlc(null);  
326 - }  
327 - } catch (Exception e) {  
328 - logger.error("", e);  
329 - }  
330 - return realList;  
331 - }  
332 -  
333 - /**  
334 - * @Title: batchSave  
335 - * @Description: TODO(批量入库)  
336 - */  
337 - private void batchSave(List<ScheduleRealInfo> list) {  
338 - // 查询数据库最大ID  
339 - Long id = schRepository.getMaxId();  
340 - if (null == id)  
341 - id = 0L;  
342 - id++;  
343 -  
344 - SimpleDateFormat sdfyyyyMMdd = new SimpleDateFormat("yyyy-MM-dd");  
345 - for (ScheduleRealInfo item : list) {  
346 - item.setSpId(item.getId());// 保留原始的计划ID  
347 - item.setId(id++);// 设置ID  
348 - item.setScheduleDateStr(sdfyyyyMMdd.format(item.getScheduleDate()));  
349 - }  
350 -  
351 - // 入库  
352 - new BatchSaveUtils<ScheduleRealInfo>().saveList(list, ScheduleRealInfo.class);  
353 - }  
354 -  
355 - private List<SchedulePlanInfo> cleanSchPlanItr(Iterator<SchedulePlanInfo> itrab) {  
356 - List<SchedulePlanInfo> list = new ArrayList<>();  
357 -  
358 - SchedulePlanInfo sp;  
359 - while (itrab.hasNext()) {  
360 - sp = itrab.next();  
361 - sp.setSchedulePlan(null);  
362 - list.add(sp);  
363 - }  
364 - return list;  
365 - }  
366 -  
367 - /**  
368 - *  
369 - * @Title: findByLineCode  
370 - * @Description: TODO(lineCode 获取班次)  
371 - */  
372 - public List<ScheduleRealInfo> findByLineCode(String lineCode) {  
373 - List<ScheduleRealInfo> rs = new ArrayList<>();  
374 -  
375 - Collection<ScheduleRealInfo> schs = nbbmScheduleMap.values();  
376 - for (ScheduleRealInfo sch : schs) {  
377 - if (sch.getXlBm().equals(lineCode))  
378 - rs.add(sch);  
379 - }  
380 - return rs;  
381 - }  
382 -  
383 - /**  
384 - *  
385 - * @Title: findCarByLineCode  
386 - * @Description: TODO(线路下运营的车辆)  
387 - */  
388 - public Set<String> findCarByLineCode(String lineCode){  
389 - Set<String> rs = new HashSet<>();  
390 -  
391 - Collection<ScheduleRealInfo> schs = nbbmScheduleMap.values();  
392 - for (ScheduleRealInfo sch : schs) {  
393 - if (sch.getXlBm().equals(lineCode))  
394 - rs.add(sch.getClZbh());  
395 - }  
396 -  
397 - return rs;  
398 - }  
399 -  
400 - public List<ScheduleRealInfo> findByNbbm(String nbbm) {  
401 - return nbbmScheduleMap.get(nbbm);  
402 - }  
403 -  
404 - /**  
405 - *  
406 - * @Title: findByLineAndUpDown  
407 - * @Description: TODO(lineCode 和走向获取班次)  
408 - */  
409 - public List<ScheduleRealInfo> findByLineAndUpDown(String lineCode, Integer upDown) {  
410 - List<ScheduleRealInfo> list = findByLineCode(lineCode), rs = new ArrayList<>();  
411 -  
412 - for (ScheduleRealInfo sch : list) {  
413 - if (sch.getXlDir().equals(upDown + ""))  
414 - rs.add(sch);  
415 - }  
416 - return rs;  
417 - }  
418 -  
419 - public ScheduleRealInfo get(long id) {  
420 - return id2SchedulMap.get(id);  
421 - }  
422 -  
423 - public Set<String> getSEStationList(String nbbm) {  
424 - return nbbm2SEStationMap.get(nbbm);  
425 - }  
426 -  
427 - /**  
428 - *  
429 - * @Title: next  
430 - * @Description: TODO(下一个班次)  
431 - */  
432 - public ScheduleRealInfo next(ScheduleRealInfo sch) {  
433 -  
434 - List<ScheduleRealInfo> list = nbbmScheduleMap.get(sch.getClZbh());  
435 -  
436 - boolean flag = false;  
437 - ScheduleRealInfo next = null;  
438 - for(ScheduleRealInfo temp : list){  
439 - if(temp.getId() == sch.getId()){  
440 - flag = true;  
441 - continue;  
442 - }  
443 - //忽略烂班  
444 - if(temp.isDestroy())  
445 - continue;  
446 -  
447 - if(flag){  
448 - next = temp;  
449 - break;  
450 - }  
451 - }  
452 - return next;  
453 - }  
454 -  
455 - public void put(ScheduleRealInfo sch) {  
456 - schAttrCalculator  
457 - .calcRealDate(sch)  
458 - .calcAllTimeByFcsj(sch);  
459 -  
460 - String nbbm = sch.getClZbh();  
461 - nbbmScheduleMap.put(nbbm, sch);  
462 - nbbm2SEStationMap.put(nbbm, sch.getQdzCode());  
463 - nbbm2SEStationMap.put(nbbm, sch.getZdzCode());  
464 -  
465 - //主键索引  
466 - id2SchedulMap.put(sch.getId(), sch);  
467 - }  
468 -  
469 - public void delete(ScheduleRealInfo sch) {  
470 - //ScheduleRealInfo sch = id2SchedulMap.get(id);  
471 - if(!sch.isSflj())  
472 - return;  
473 -  
474 - nbbmScheduleMap.remove(sch.getClZbh(), sch);  
475 - id2SchedulMap.remove(sch.getId());  
476 - //return sch;  
477 - }  
478 -  
479 - public void calcQdzTimePlan(String nbbm){  
480 - schAttrCalculator.calcQdzTimePlan(nbbmScheduleMap.get(nbbm));  
481 - }  
482 -  
483 - public List<ScheduleRealInfo> updateQdzTimePlan(String nbbm){  
484 - return schAttrCalculator.updateQdzTimePlan(nbbmScheduleMap.get(nbbm));  
485 - }  
486 -  
487 - /**  
488 - *  
489 - * @Title: nextAll  
490 - * @Description: TODO(之后的所有班次)  
491 - */  
492 - public List<ScheduleRealInfo> nextAll(ScheduleRealInfo sch) {  
493 - List<ScheduleRealInfo> list = nbbmScheduleMap.get(sch.getClZbh());  
494 - // 排序  
495 - Collections.sort(list, schFCSJComparator);  
496 -  
497 - List<ScheduleRealInfo> rs = new ArrayList<>();  
498 - ScheduleRealInfo temp;  
499 - for (int i = 0; i < list.size() - 1; i++) {  
500 - temp = list.get(i);  
501 - if(temp.getFcsjT() > sch.getFcsjT())  
502 - rs.add(temp);  
503 -  
504 - }  
505 - return rs;  
506 - }  
507 -  
508 - /**  
509 - *  
510 - * @Title: doneSum  
511 - * @Description: TODO(已完成班次总数)  
512 - */  
513 - public int doneSum(String clZbh) {  
514 - List<ScheduleRealInfo> list = nbbmScheduleMap.get(clZbh);  
515 - int rs = 0;  
516 -  
517 - for(ScheduleRealInfo sch : list){  
518 - if(sch.getStatus() == 2 && !sch.isDestroy())  
519 - rs ++;  
520 - }  
521 - return rs;  
522 - }  
523 -  
524 - /**  
525 - *  
526 - * @Title: prveNotExecNum  
527 - * @Description: TODO(班次之前未执行班次数量)  
528 - */  
529 - public int prveNotExecNum(ScheduleRealInfo sch){  
530 - int n = 0;  
531 - List<ScheduleRealInfo> list = nbbmScheduleMap.get(sch.getClZbh());  
532 - for(ScheduleRealInfo s : list){  
533 - if(s.getFcsjActual() == null && !s.isDestroy())  
534 - n ++;  
535 -  
536 - if(s.getId().equals(sch.getId()))  
537 - break;  
538 - }  
539 - return n;  
540 - }  
541 -  
542 - /**  
543 - *  
544 - * @Title: validEndTime  
545 - * @Description: TODO(是否是有效的到达时间)  
546 - */  
547 - public boolean validEndTime(ScheduleRealInfo sch, Long ts) {  
548 - if(sch.getFcsjActualTime() != null && sch.getFcsjActualTime() > ts)  
549 - return false;  
550 -  
551 - return validTime(sch, ts);  
552 - }  
553 -  
554 - /**  
555 - *  
556 - * @Title: validStartTime  
557 - * @Description: TODO(是否是合适的发车时间)  
558 - */  
559 - public boolean validStartTime(ScheduleRealInfo sch, Long ts) {  
560 - if(sch.getZdsjActualTime() != null && sch.getZdsjActualTime() < ts)  
561 - return false;  
562 -  
563 - return validTime(sch, ts);  
564 - }  
565 -  
566 - public boolean validTime(ScheduleRealInfo sch, Long ts){  
567 - List<ScheduleRealInfo> list = nbbmScheduleMap.get(sch.getClZbh());  
568 - int ci = list.indexOf(sch);  
569 - ScheduleRealInfo prve, next;  
570 - if(ci > 0){  
571 - //之前班次实际时间不能大于该时间  
572 - for(int i = ci - 1; i >= 0; i --){  
573 - prve = list.get(i);  
574 - if(prve.getZdsjActualTime() != null && prve.getZdsjActualTime() > ts )  
575 - return false;  
576 -  
577 - if(prve.getFcsjActualTime() != null && prve.getFcsjActualTime() > ts)  
578 - return false;  
579 - }  
580 - }  
581 -  
582 - if(ci < list.size() - 1){  
583 - //之后班次实际时间不能小于该时间  
584 - for(int i = ci + 1; i < list.size(); i ++){  
585 - next = list.get(i);  
586 - if(next.getFcsjActualTime() != null && next.getFcsjActualTime() < ts)  
587 - return false;  
588 -  
589 - if(next.getZdsjActualTime() != null && next.getZdsjActualTime() < ts)  
590 - return false;  
591 - }  
592 - }  
593 - return true;  
594 - }  
595 -  
596 - public void save(ScheduleRealInfo sch){  
597 - //schRepository.save(sch);  
598 - //pstBuffer.add(sch);  
599 - }  
600 -  
601 -  
602 - /**  
603 - *  
604 - * @Title: nextByBcType  
605 - * @Description: TODO(获取下一个指定班次类型的班次)  
606 - */  
607 - public ScheduleRealInfo nextByBcType(String nbbm, String bcType){  
608 - List<ScheduleRealInfo> list = findByBcType(nbbm, bcType);  
609 -  
610 - Collections.sort(list, schFCSJComparator);  
611 - ScheduleRealInfo sch = null;  
612 - for(ScheduleRealInfo temp : list){  
613 - if(temp.getFcsjActual() == null)  
614 - sch = temp;  
615 - }  
616 -  
617 - return sch;  
618 - }  
619 -  
620 - public List<ScheduleRealInfo> findByBcType(String nbbm, String bcType){  
621 - List<ScheduleRealInfo> all = nbbmScheduleMap.get(nbbm)  
622 - ,outList = new ArrayList<>();  
623 -  
624 - for(ScheduleRealInfo sch : all){  
625 - if(sch.getBcType().equals(bcType))  
626 - outList.add(sch);  
627 - }  
628 - return outList;  
629 - }  
630 -  
631 - public Set<String> allCar(){  
632 - return nbbmScheduleMap.keySet();  
633 - }  
634 -  
635 - public Collection<ScheduleRealInfo> findAll(){  
636 - return nbbmScheduleMap.values();  
637 - }  
638 -  
639 - public void addExecPlan(ScheduleRealInfo sch){  
640 - carExecutePlanMap.put(sch.getClZbh(), sch);  
641 - }  
642 -  
643 - public void removeExecPlan(String clzbh){  
644 - carExecutePlanMap.remove(clzbh);  
645 - }  
646 -  
647 - public Map<String, ScheduleRealInfo> execPlamMap(){  
648 - return carExecutePlanMap;  
649 - }  
650 -  
651 - /**  
652 - * @Title: changeCar  
653 - * @Description: TODO(班次换车) 返回有更新的班次  
654 - * @param @param sch  
655 - * @param @param newClZbh 新的车辆自编号  
656 - */  
657 - public List<ScheduleRealInfo> changeCar(ScheduleRealInfo sch , String newClZbh){  
658 - List<ScheduleRealInfo> ups = new ArrayList<>();  
659 - String oldClzbh = sch.getClZbh();  
660 - if(oldClzbh.equals(newClZbh))  
661 - return ups;  
662 -  
663 -  
664 - //变更相关映射信息  
665 - nbbmScheduleMap.remove(sch.getClZbh(), sch);  
666 -  
667 - sch.setClZbh(newClZbh);  
668 - nbbmScheduleMap.put(newClZbh, sch);  
669 - nbbm2SEStationMap.put(newClZbh, sch.getQdzCode());  
670 - nbbm2SEStationMap.put(newClZbh, sch.getZdzCode());  
671 -  
672 - //重新计算班次应到时间  
673 - ups.addAll(updateQdzTimePlan(oldClzbh));  
674 - ups.addAll(updateQdzTimePlan(newClZbh));  
675 - return ups;  
676 - }  
677 -  
678 - /**  
679 - *  
680 - * @Title: linkToSchPlan  
681 - * @Description: TODO(车辆关联到班次)  
682 - */  
683 -/* public void linkToSchPlan(String nbbm) {  
684 - //当前GPS状态  
685 - GpsEntity gps = gpsRealData.get(BasicData.deviceId2NbbmMap.inverse().get(nbbm));  
686 - if(null == gps)  
687 - return;  
688 -  
689 - //班次集合  
690 - List<ScheduleRealInfo> schArr = nbbmScheduleMap.get(nbbm);  
691 -  
692 - for(ScheduleRealInfo sch : schArr){  
693 - if(sch.getStatus() == 2)  
694 - continue;  
695 - if(sch.isDestroy())  
696 - continue;  
697 - if(!sch.getXlBm().equals(gps.getLineId())  
698 - || Integer.parseInt(sch.getXlDir()) != gps.getUpDown().intValue())  
699 - continue;  
700 -  
701 - addExecPlan(sch);  
702 - break;  
703 - }  
704 - }*/  
705 -} 1 +package com.bsth.data.schedule;
  2 +
  3 +import java.text.SimpleDateFormat;
  4 +import java.util.ArrayList;
  5 +import java.util.Collection;
  6 +import java.util.Collections;
  7 +import java.util.HashMap;
  8 +import java.util.HashSet;
  9 +import java.util.Iterator;
  10 +import java.util.LinkedList;
  11 +import java.util.List;
  12 +import java.util.Map;
  13 +import java.util.Set;
  14 +import java.util.concurrent.TimeUnit;
  15 +
  16 +import org.joda.time.format.DateTimeFormat;
  17 +import org.joda.time.format.DateTimeFormatter;
  18 +import org.slf4j.Logger;
  19 +import org.slf4j.LoggerFactory;
  20 +import org.springframework.beans.factory.annotation.Autowired;
  21 +import org.springframework.boot.CommandLineRunner;
  22 +import org.springframework.stereotype.Component;
  23 +
  24 +import com.alibaba.fastjson.JSON;
  25 +import com.alibaba.fastjson.JSONArray;
  26 +import com.bsth.Application;
  27 +import com.bsth.data.LineConfigData;
  28 +import com.bsth.data.directive.FirstScheduleCheckThread;
  29 +import com.bsth.data.gpsdata.GpsRealData;
  30 +import com.bsth.data.schedule.thread.ScheduleLateThread;
  31 +import com.bsth.data.schedule.thread.SchedulePstThread;
  32 +import com.bsth.data.schedule.thread.ScheduleRefreshThread;
  33 +import com.bsth.entity.realcontrol.LineConfig;
  34 +import com.bsth.entity.realcontrol.ScheduleRealInfo;
  35 +import com.bsth.entity.schedule.SchedulePlanInfo;
  36 +import com.bsth.repository.realcontrol.ScheduleRealInfoRepository;
  37 +import com.bsth.service.schedule.SchedulePlanInfoService;
  38 +import com.bsth.util.BatchSaveUtils;
  39 +import com.bsth.util.DateUtils;
  40 +import com.bsth.websocket.handler.SendUtils;
  41 +import com.google.common.collect.ArrayListMultimap;
  42 +import com.google.common.collect.TreeMultimap;
  43 +
  44 +/**
  45 + *
  46 + * @ClassName: DayOfSchedule
  47 + * @Description: TODO(当日实际排班)
  48 + * @author PanZhao
  49 + * @date 2016年8月15日 上午10:16:12
  50 + *
  51 + */
  52 +@Component
  53 +public class DayOfSchedule implements CommandLineRunner {
  54 +
  55 + Logger logger = LoggerFactory.getLogger(this.getClass());
  56 +
  57 + // 按车辆分组的班次数据
  58 + private static ArrayListMultimap<String, ScheduleRealInfo> nbbmScheduleMap;
  59 +
  60 + // 班次主键映射
  61 + private static Map<Long, ScheduleRealInfo> id2SchedulMap;
  62 +
  63 + // 车辆和排班起终点站对照(包括进出的停车场,区间起终点)
  64 + private static TreeMultimap<String, String> nbbm2SEStationMap;
  65 +
  66 + //车辆 ——> 当前执行班次
  67 + private static Map<String, ScheduleRealInfo> carExecutePlanMap;
  68 +
  69 + // 持久化缓冲区
  70 + public static LinkedList<ScheduleRealInfo> pstBuffer;
  71 +
  72 + // 排序器
  73 + private static ScheduleComparator.FCSJ schFCSJComparator;
  74 +
  75 + @Autowired
  76 + LineConfigData lineConfigData;
  77 +
  78 + @Autowired
  79 + ScheduleRealInfoRepository schRepository;
  80 +
  81 + @Autowired
  82 + SchedulePlanInfoService schPlanService;
  83 +
  84 + @Autowired
  85 + SchAttrCalculator schAttrCalculator;
  86 +
  87 + @Autowired
  88 + SendUtils sendUtils;
  89 +
  90 + @Autowired
  91 + GpsRealData gpsRealData;
  92 +
  93 + /** 线路当前使用的排班的日期 */
  94 + public static Map<String, String> currSchDateMap;
  95 +
  96 + static {
  97 + nbbmScheduleMap = ArrayListMultimap.create();
  98 + id2SchedulMap = new HashMap<>();
  99 + pstBuffer = new LinkedList<>();
  100 + schFCSJComparator = new ScheduleComparator.FCSJ();
  101 + currSchDateMap = new HashMap<>();
  102 + nbbm2SEStationMap = TreeMultimap.create();
  103 + carExecutePlanMap = new HashMap<>();
  104 + }
  105 +
  106 + @Autowired
  107 + ScheduleRefreshThread scheduleRefreshThread;
  108 +
  109 + @Autowired
  110 + SchedulePstThread schedulePstThread;
  111 +
  112 + @Autowired
  113 + FirstScheduleCheckThread firstScheduleCheckThread;
  114 +
  115 + @Autowired
  116 + ScheduleLateThread scheduleLateThread;
  117 +
  118 + private static DateTimeFormatter fmtyyyyMMdd = DateTimeFormat.forPattern("yyyy-MM-dd")
  119 + ,fmtHHmm = DateTimeFormat.forPattern("HH:mm");
  120 +
  121 + @Override
  122 + public void run(String... arg0) throws Exception {
  123 + //翻班线程
  124 + Application.mainServices.scheduleWithFixedDelay(scheduleRefreshThread, 15, 240, TimeUnit.SECONDS);
  125 + //入库
  126 + Application.mainServices.scheduleWithFixedDelay(schedulePstThread, 60, 60, TimeUnit.SECONDS);
  127 + //首班出场指令补发器
  128 + Application.mainServices.scheduleWithFixedDelay(firstScheduleCheckThread, 30, 240, TimeUnit.SECONDS);
  129 + //班次误点扫描
  130 + //Application.mainServices.scheduleWithFixedDelay(scheduleLateThread, 60, 60, TimeUnit.SECONDS);
  131 + }
  132 +
  133 + public Map<String, String> getCurrSchDate() {
  134 + return currSchDateMap;
  135 + }
  136 +
  137 + /**
  138 + *
  139 + * @Title: calcSchDateB
  140 + * @Description: TODO(计算线路当前应该使用的排班日期)
  141 + */
  142 + public String calcSchDate(String lineCode) {
  143 + LineConfig conf = lineConfigData.get(lineCode);
  144 + long ct = System.currentTimeMillis();
  145 +
  146 + String schDate = fmtyyyyMMdd.print(ct);
  147 + // 小于当天起始运营时间,则取前一天的排班
  148 + if (ct < conf.getCurrStartTime())
  149 + schDate = DateUtils.subtractDay(schDate, 1);
  150 +
  151 + return schDate;
  152 + }
  153 +
  154 + /**
  155 + * @Title: reloadSch
  156 + * @Title: reloadSch
  157 + * @Description: TODO(重新载入排班)
  158 + * @param @param
  159 + * lineCode 线路编码
  160 + * @param @param
  161 + * schDate 班次日期 yyyy-MM-dd
  162 + * @param @param
  163 + * forcePlan 强制从计划调度重新抓取
  164 + */
  165 + public int reloadSch(String lineCode, String schDate, boolean forcePlan) {
  166 + try {
  167 + List<ScheduleRealInfo> list;
  168 +
  169 + if (forcePlan)
  170 + removeRealSch(lineCode, schDate);
  171 + else
  172 + clearRAMData(lineCode);
  173 +
  174 + if (existRealSch(lineCode, schDate))
  175 + list = loadRealSch(lineCode, schDate);// 从实际排班表加载
  176 + else {
  177 + list = loadPlanSch(lineCode, schDate);// 从计划排班表加载
  178 + // 写入数据库
  179 + batchSave(list);
  180 + }
  181 +
  182 + //更新线路和班次日期对照
  183 + currSchDateMap.put(lineCode, schDate);
  184 + //添加到缓存
  185 + putAll(list);
  186 +
  187 + Set<String> cars = searchAllCars(list);
  188 + //计算“起点站应到”时间
  189 + for(String nbbm : cars)
  190 + schAttrCalculator.calcQdzTimePlan(nbbmScheduleMap.get(nbbm));
  191 +
  192 + //是否是出站即出场
  193 + LineConfig conf = lineConfigData.get(lineCode);
  194 + if(conf.getOutConfig() == 2){
  195 + for(String nbbm : cars)
  196 + schAttrCalculator.connectOutSchedule(nbbmScheduleMap.get(nbbm));
  197 + }
  198 +
  199 + // 页面 翻班通知
  200 + sendUtils.shiftSchedule(lineCode);
  201 + } catch (Exception e) {
  202 + logger.error("", e);
  203 + return -1;
  204 + }
  205 +
  206 + return 0;
  207 + }
  208 +
  209 + /**
  210 + *
  211 + * @Title: searchAllCars
  212 + * @Description: TODO(搜索班次集合中的车辆)
  213 + */
  214 + private Set<String> searchAllCars(List<ScheduleRealInfo> list) {
  215 + Set<String> cars = new HashSet<>();
  216 + for(ScheduleRealInfo sch : list)
  217 + cars.add(sch.getClZbh());
  218 +
  219 + return cars;
  220 + }
  221 +
  222 + private void putAll(List<ScheduleRealInfo> list) {
  223 + for (ScheduleRealInfo sch : list)
  224 + put(sch);
  225 + }
  226 +
  227 + /**
  228 + * @Title: removeRealSch
  229 + * @Description: TODO(清除实际排班,包括数据库和内存数据)
  230 + * @param @param
  231 + * lineCode 线路编码
  232 + * @param @param
  233 + * schDate 班次日期 yyyy-MM-dd
  234 + */
  235 + public void removeRealSch(String lineCode, String schDate) throws Exception {
  236 + try {
  237 + // 清理数据库数据
  238 + schRepository.deleteByLineCodeAndDate(lineCode + "", schDate);
  239 +
  240 + // 清理内存数据
  241 + clearRAMData(lineCode + "");
  242 + } catch (Exception e) {
  243 + logger.error("removeRealSch error, " + lineCode + " -" + schDate, e);
  244 + throw e;
  245 + }
  246 + }
  247 +
  248 + /**
  249 + *
  250 + * @Title: clearRAMData
  251 + * @Description: TODO(清理内存数据)
  252 + */
  253 + public void clearRAMData(String lineCode) {
  254 + int count = 0;
  255 + List<ScheduleRealInfo> remList = new ArrayList<>();
  256 + Collection<ScheduleRealInfo> schs = nbbmScheduleMap.values();
  257 + for (ScheduleRealInfo sch : schs) {
  258 + if (sch.getXlBm().equals(lineCode))
  259 + remList.add(sch);
  260 + }
  261 +
  262 + for(ScheduleRealInfo sch : remList){
  263 + if(null != sch){
  264 + nbbmScheduleMap.remove(sch.getClZbh(), sch);
  265 + id2SchedulMap.remove(sch.getId());
  266 + count ++;
  267 + }
  268 + }
  269 +
  270 + logger.info(lineCode + "排班清理 " + count);
  271 + }
  272 +
  273 + /**
  274 + * @Title: existRealSch
  275 + * @Description: TODO(实际排班是否已存在)
  276 + */
  277 + public boolean existRealSch(String lineCode, String schDate) {
  278 + int count = schRepository.countByLineCodeAndDate(lineCode, schDate);
  279 + return count > 0;
  280 + }
  281 +
  282 + /**
  283 + * @Title: loadRealSch
  284 + * @Description: TODO(从实际排班表加载数据)
  285 + */
  286 + public List<ScheduleRealInfo> loadRealSch(String lineCode, String schDate) {
  287 + return schRepository.findByLineCodeAndDate(lineCode, schDate);
  288 + }
  289 +
  290 + /**
  291 + * @Title: loadPlanSch
  292 + * @Description: TODO(从计划排班表加载数据)
  293 + */
  294 + public List<ScheduleRealInfo> loadPlanSch(String lineCode, String schDate) {
  295 + logger.info("从计划排班表恢复排班,lineCode: " + lineCode + ", schDate: " + schDate);
  296 + List<ScheduleRealInfo> realList = new ArrayList<>();
  297 +
  298 + try {
  299 + Map<String, Object> data = new HashMap<>();
  300 +
  301 + data.put("scheduleDate_eq", fmtyyyyMMdd.parseDateTime(schDate).toDate());
  302 + data.put("xlBm_eq", lineCode);
  303 +
  304 + // 查询计划排班
  305 + List<SchedulePlanInfo> planItr = cleanSchPlanItr(schPlanService.list(data).iterator());
  306 +
  307 + // 转换为实际排班
  308 + realList = JSONArray.parseArray(JSON.toJSONString(planItr), ScheduleRealInfo.class);
  309 +
  310 + for (ScheduleRealInfo sch : realList) {
  311 + sch.setScheduleDateStr(fmtyyyyMMdd.print(sch.getScheduleDate().getTime()));
  312 + sch.setRealExecDate(sch.getScheduleDateStr());
  313 + // 计划终点时间
  314 + if (sch.getBcsj() != null) {
  315 + sch.setZdsj(fmtHHmm.print(fmtHHmm.parseMillis(sch.getFcsj()) + (sch.getBcsj() * 60 * 1000)));
  316 + sch.setLate(false);
  317 + }
  318 + //计划里程为0,设置NULL
  319 + if(sch.getJhlc() != null && sch.getJhlc() == 0)
  320 + sch.setJhlc(null);
  321 + }
  322 + } catch (Exception e) {
  323 + logger.error("", e);
  324 + }
  325 + return realList;
  326 + }
  327 +
  328 + /**
  329 + * @Title: batchSave
  330 + * @Description: TODO(批量入库)
  331 + */
  332 + private void batchSave(List<ScheduleRealInfo> list) {
  333 + // 查询数据库最大ID
  334 + Long id = schRepository.getMaxId();
  335 + if (null == id)
  336 + id = 0L;
  337 + id++;
  338 +
  339 + SimpleDateFormat sdfyyyyMMdd = new SimpleDateFormat("yyyy-MM-dd");
  340 + for (ScheduleRealInfo item : list) {
  341 + item.setSpId(item.getId());// 保留原始的计划ID
  342 + item.setId(id++);// 设置ID
  343 + item.setScheduleDateStr(sdfyyyyMMdd.format(item.getScheduleDate()));
  344 + }
  345 +
  346 + // 入库
  347 + new BatchSaveUtils<ScheduleRealInfo>().saveList(list, ScheduleRealInfo.class);
  348 + }
  349 +
  350 + private List<SchedulePlanInfo> cleanSchPlanItr(Iterator<SchedulePlanInfo> itrab) {
  351 + List<SchedulePlanInfo> list = new ArrayList<>();
  352 +
  353 + SchedulePlanInfo sp;
  354 + while (itrab.hasNext()) {
  355 + sp = itrab.next();
  356 + sp.setSchedulePlan(null);
  357 + list.add(sp);
  358 + }
  359 + return list;
  360 + }
  361 +
  362 + /**
  363 + *
  364 + * @Title: findByLineCode
  365 + * @Description: TODO(lineCode 获取班次)
  366 + */
  367 + public List<ScheduleRealInfo> findByLineCode(String lineCode) {
  368 + List<ScheduleRealInfo> rs = new ArrayList<>();
  369 +
  370 + Collection<ScheduleRealInfo> schs = nbbmScheduleMap.values();
  371 + for (ScheduleRealInfo sch : schs) {
  372 + if (sch.getXlBm().equals(lineCode))
  373 + rs.add(sch);
  374 + }
  375 + return rs;
  376 + }
  377 +
  378 + /**
  379 + *
  380 + * @Title: findCarByLineCode
  381 + * @Description: TODO(线路下运营的车辆)
  382 + */
  383 + public Set<String> findCarByLineCode(String lineCode){
  384 + Set<String> rs = new HashSet<>();
  385 +
  386 + Collection<ScheduleRealInfo> schs = nbbmScheduleMap.values();
  387 + for (ScheduleRealInfo sch : schs) {
  388 + if (sch.getXlBm().equals(lineCode))
  389 + rs.add(sch.getClZbh());
  390 + }
  391 +
  392 + return rs;
  393 + }
  394 +
  395 + public List<ScheduleRealInfo> findByNbbm(String nbbm) {
  396 + return nbbmScheduleMap.get(nbbm);
  397 + }
  398 +
  399 + /**
  400 + *
  401 + * @Title: findByLineAndUpDown
  402 + * @Description: TODO(lineCode 和走向获取班次)
  403 + */
  404 + public List<ScheduleRealInfo> findByLineAndUpDown(String lineCode, Integer upDown) {
  405 + List<ScheduleRealInfo> list = findByLineCode(lineCode), rs = new ArrayList<>();
  406 +
  407 + for (ScheduleRealInfo sch : list) {
  408 + if (sch.getXlDir().equals(upDown + ""))
  409 + rs.add(sch);
  410 + }
  411 + return rs;
  412 + }
  413 +
  414 + public ScheduleRealInfo get(long id) {
  415 + return id2SchedulMap.get(id);
  416 + }
  417 +
  418 + public Set<String> getSEStationList(String nbbm) {
  419 + return nbbm2SEStationMap.get(nbbm);
  420 + }
  421 +
  422 + /**
  423 + *
  424 + * @Title: next
  425 + * @Description: TODO(下一个班次)
  426 + */
  427 + public ScheduleRealInfo next(ScheduleRealInfo sch) {
  428 +
  429 + List<ScheduleRealInfo> list = nbbmScheduleMap.get(sch.getClZbh());
  430 +
  431 + boolean flag = false;
  432 + ScheduleRealInfo next = null;
  433 + for(ScheduleRealInfo temp : list){
  434 + if(temp.getId() == sch.getId()){
  435 + flag = true;
  436 + continue;
  437 + }
  438 + //忽略烂班
  439 + if(temp.isDestroy())
  440 + continue;
  441 +
  442 + if(flag){
  443 + next = temp;
  444 + break;
  445 + }
  446 + }
  447 + return next;
  448 + }
  449 +
  450 + public void put(ScheduleRealInfo sch) {
  451 +
  452 + schAttrCalculator
  453 + .calcRealDate(sch)
  454 + .calcAllTimeByFcsj(sch);
  455 +
  456 + String nbbm = sch.getClZbh();
  457 + nbbmScheduleMap.put(nbbm, sch);
  458 + nbbm2SEStationMap.put(nbbm, sch.getQdzCode());
  459 + nbbm2SEStationMap.put(nbbm, sch.getZdzCode());
  460 +
  461 + //主键索引
  462 + id2SchedulMap.put(sch.getId(), sch);
  463 + }
  464 +
  465 + public void delete(ScheduleRealInfo sch) {
  466 + //ScheduleRealInfo sch = id2SchedulMap.get(id);
  467 + if(!sch.isSflj())
  468 + return;
  469 +
  470 + nbbmScheduleMap.remove(sch.getClZbh(), sch);
  471 + id2SchedulMap.remove(sch.getId());
  472 + //return sch;
  473 + }
  474 +
  475 +// public void calcQdzTimePlan(String nbbm){
  476 +// schAttrCalculator.calcQdzTimePlan(nbbmScheduleMap.get(nbbm));
  477 +// }
  478 +
  479 + public List<ScheduleRealInfo> updateQdzTimePlan(String nbbm){
  480 + return schAttrCalculator.updateQdzTimePlan(nbbmScheduleMap.get(nbbm));
  481 + }
  482 +
  483 + /**
  484 + *
  485 + * @Title: nextAll
  486 + * @Description: TODO(之后的所有班次)
  487 + */
  488 +/* public List<ScheduleRealInfo> nextAll(ScheduleRealInfo sch) {
  489 + List<ScheduleRealInfo> list = nbbmScheduleMap.get(sch.getClZbh());
  490 + // 排序
  491 + Collections.sort(list, schFCSJComparator);
  492 +
  493 + List<ScheduleRealInfo> rs = new ArrayList<>();
  494 + ScheduleRealInfo temp;
  495 + for (int i = 0; i < list.size() - 1; i++) {
  496 + temp = list.get(i);
  497 + if(temp.getFcsjT() > sch.getFcsjT())
  498 + rs.add(temp);
  499 +
  500 + }
  501 + return rs;
  502 + }*/
  503 +
  504 + /**
  505 + *
  506 + * @Title: doneSum
  507 + * @Description: TODO(已完成班次总数)
  508 + */
  509 + public int doneSum(String clZbh) {
  510 + List<ScheduleRealInfo> list = nbbmScheduleMap.get(clZbh);
  511 + int rs = 0;
  512 +
  513 + for(ScheduleRealInfo sch : list){
  514 + if(sch.getStatus() == 2 && !sch.isDestroy())
  515 + rs ++;
  516 + }
  517 + return rs;
  518 + }
  519 +
  520 + /**
  521 + *
  522 + * @Title: prveNotExecNum
  523 + * @Description: TODO(班次之前未执行班次数量)
  524 + */
  525 + public int prveNotExecNum(ScheduleRealInfo sch){
  526 + int n = 0;
  527 + List<ScheduleRealInfo> list = nbbmScheduleMap.get(sch.getClZbh());
  528 + for(ScheduleRealInfo s : list){
  529 + if(s.getFcsjActual() == null && !s.isDestroy())
  530 + n ++;
  531 +
  532 + if(s.getId().equals(sch.getId()))
  533 + break;
  534 + }
  535 + return n;
  536 + }
  537 +
  538 + /**
  539 + *
  540 + * @Title: validEndTime
  541 + * @Description: TODO(是否是有效的到达时间)
  542 + */
  543 + public boolean validEndTime(ScheduleRealInfo sch, Long ts) {
  544 + if(sch.getFcsjActualTime() != null && sch.getFcsjActualTime() > ts)
  545 + return false;
  546 +
  547 + return validTime(sch, ts);
  548 + }
  549 +
  550 + /**
  551 + *
  552 + * @Title: validStartTime
  553 + * @Description: TODO(是否是合适的发车时间)
  554 + */
  555 + public boolean validStartTime(ScheduleRealInfo sch, Long ts) {
  556 + if(sch.getZdsjActualTime() != null && sch.getZdsjActualTime() < ts)
  557 + return false;
  558 +
  559 + return validTime(sch, ts);
  560 + }
  561 +
  562 + public boolean validTime(ScheduleRealInfo sch, Long ts){
  563 + List<ScheduleRealInfo> list = nbbmScheduleMap.get(sch.getClZbh());
  564 + int ci = list.indexOf(sch);
  565 + ScheduleRealInfo prve, next;
  566 + if(ci > 0){
  567 + //之前班次实际时间不能大于该时间
  568 + for(int i = ci - 1; i >= 0; i --){
  569 + prve = list.get(i);
  570 + if(prve.getZdsjActualTime() != null && prve.getZdsjActualTime() > ts )
  571 + return false;
  572 +
  573 + if(prve.getFcsjActualTime() != null && prve.getFcsjActualTime() > ts)
  574 + return false;
  575 + }
  576 + }
  577 +
  578 + if(ci < list.size() - 1){
  579 + //之后班次实际时间不能小于该时间
  580 + for(int i = ci + 1; i < list.size(); i ++){
  581 + next = list.get(i);
  582 + if(next.getFcsjActualTime() != null && next.getFcsjActualTime() < ts)
  583 + return false;
  584 +
  585 + if(next.getZdsjActualTime() != null && next.getZdsjActualTime() < ts)
  586 + return false;
  587 + }
  588 + }
  589 + return true;
  590 + }
  591 +
  592 + public void save(ScheduleRealInfo sch){
  593 + //schRepository.save(sch);
  594 + pstBuffer.add(sch);
  595 + }
  596 +
  597 +
  598 + /**
  599 + *
  600 + * @Title: nextByBcType
  601 + * @Description: TODO(获取下一个指定班次类型的班次)
  602 + */
  603 + public ScheduleRealInfo nextByBcType(String nbbm, String bcType){
  604 + List<ScheduleRealInfo> list = findByBcType(nbbm, bcType);
  605 +
  606 + Collections.sort(list, schFCSJComparator);
  607 + ScheduleRealInfo sch = null;
  608 + for(ScheduleRealInfo temp : list){
  609 + if(temp.getFcsjActual() == null)
  610 + sch = temp;
  611 + }
  612 +
  613 + return sch;
  614 + }
  615 +
  616 + public List<ScheduleRealInfo> findByBcType(String nbbm, String bcType){
  617 + List<ScheduleRealInfo> all = nbbmScheduleMap.get(nbbm)
  618 + ,outList = new ArrayList<>();
  619 +
  620 + for(ScheduleRealInfo sch : all){
  621 + if(sch.getBcType().equals(bcType))
  622 + outList.add(sch);
  623 + }
  624 + return outList;
  625 + }
  626 +
  627 + public Set<String> allCar(){
  628 + return nbbmScheduleMap.keySet();
  629 + }
  630 +
  631 + public Collection<ScheduleRealInfo> findAll(){
  632 + return nbbmScheduleMap.values();
  633 + }
  634 +
  635 + public void addExecPlan(ScheduleRealInfo sch){
  636 + carExecutePlanMap.put(sch.getClZbh(), sch);
  637 + }
  638 +
  639 + public void removeExecPlan(String clzbh){
  640 + carExecutePlanMap.remove(clzbh);
  641 + }
  642 +
  643 + public Map<String, ScheduleRealInfo> execPlamMap(){
  644 + return carExecutePlanMap;
  645 + }
  646 +
  647 + /**
  648 + * @Title: changeCar
  649 + * @Description: TODO(班次换车) 返回有更新的班次
  650 + * @param @param sch
  651 + * @param @param newClZbh 新的车辆自编号
  652 + */
  653 + public List<ScheduleRealInfo> changeCar(ScheduleRealInfo sch , String newClZbh){
  654 + List<ScheduleRealInfo> ups = new ArrayList<>();
  655 + String oldClzbh = sch.getClZbh();
  656 + if(oldClzbh.equals(newClZbh))
  657 + return ups;
  658 +
  659 +
  660 + //变更相关映射信息
  661 + nbbmScheduleMap.remove(sch.getClZbh(), sch);
  662 +
  663 + sch.setClZbh(newClZbh);
  664 + nbbmScheduleMap.put(newClZbh, sch);
  665 + nbbm2SEStationMap.put(newClZbh, sch.getQdzCode());
  666 + nbbm2SEStationMap.put(newClZbh, sch.getZdzCode());
  667 +
  668 + //重新计算班次应到时间
  669 + ups.addAll(updateQdzTimePlan(oldClzbh));
  670 + ups.addAll(updateQdzTimePlan(newClZbh));
  671 + return ups;
  672 + }
  673 +
  674 + /**
  675 + *
  676 + * @Title: linkToSchPlan
  677 + * @Description: TODO(车辆关联到班次)
  678 + */
  679 +/* public void linkToSchPlan(String nbbm) {
  680 + //当前GPS状态
  681 + GpsEntity gps = gpsRealData.get(BasicData.deviceId2NbbmMap.inverse().get(nbbm));
  682 + if(null == gps)
  683 + return;
  684 +
  685 + //班次集合
  686 + List<ScheduleRealInfo> schArr = nbbmScheduleMap.get(nbbm);
  687 +
  688 + for(ScheduleRealInfo sch : schArr){
  689 + if(sch.getStatus() == 2)
  690 + continue;
  691 + if(sch.isDestroy())
  692 + continue;
  693 + if(!sch.getXlBm().equals(gps.getLineId())
  694 + || Integer.parseInt(sch.getXlDir()) != gps.getUpDown().intValue())
  695 + continue;
  696 +
  697 + addExecPlan(sch);
  698 + break;
  699 + }
  700 + }*/
  701 +}
src/main/java/com/bsth/data/schedule/SchAttrCalculator.java
1 package com.bsth.data.schedule; 1 package com.bsth.data.schedule;
2 2
3 import java.text.ParseException; 3 import java.text.ParseException;
4 -import java.text.SimpleDateFormat;  
5 import java.util.ArrayList; 4 import java.util.ArrayList;
6 import java.util.Collections; 5 import java.util.Collections;
7 -import java.util.Date;  
8 import java.util.List; 6 import java.util.List;
9 7
  8 +import org.joda.time.format.DateTimeFormat;
  9 +import org.joda.time.format.DateTimeFormatter;
10 import org.slf4j.Logger; 10 import org.slf4j.Logger;
11 import org.slf4j.LoggerFactory; 11 import org.slf4j.LoggerFactory;
12 import org.springframework.beans.factory.annotation.Autowired; 12 import org.springframework.beans.factory.annotation.Autowired;
@@ -34,6 +34,10 @@ public class SchAttrCalculator { @@ -34,6 +34,10 @@ public class SchAttrCalculator {
34 34
35 Logger logger = LoggerFactory.getLogger(this.getClass()); 35 Logger logger = LoggerFactory.getLogger(this.getClass());
36 36
  37 + private static DateTimeFormatter fmtyyyyMMdd = DateTimeFormat.forPattern("yyyy-MM-dd")
  38 + ,fmtHHmm = DateTimeFormat.forPattern("HH:mm")
  39 + ,fmtyyyyMMddHHmm = DateTimeFormat.forPattern("yyyy-MM-ddHH:mm");
  40 +
37 /** 41 /**
38 * @Title: calcRealDate 42 * @Title: calcRealDate
39 * @Description: TODO(计算班次的真实执行日期) 43 * @Description: TODO(计算班次的真实执行日期)
@@ -45,22 +49,12 @@ public class SchAttrCalculator { @@ -45,22 +49,12 @@ public class SchAttrCalculator {
45 if (null == sch.getFcsjT()) 49 if (null == sch.getFcsjT())
46 calcFcsjTime(sch); 50 calcFcsjTime(sch);
47 51
48 - SimpleDateFormat sdfyyyyMMdd = new SimpleDateFormat("yyyy-MM-dd");  
49 - /*  
50 - * 早于线路开始运营时间的,加一天  
51 - * 如该线路 2点开始运营,2016-08-23的班次,则 2016-08-23 0:25 的班次应该调整成 2016-08-24 0:25  
52 -  
53 -  
54 - ,sdfyyyyMMdd = new SimpleDateFormat("yyyy-MM-dd");  
55 - long st = sdfyyyyMMddHHmm.parse(sch.getScheduleDateStr() + conf.getStartOpt()).getTime();  
56 - if (st > sch.getFcsjT())  
57 - sch.setFcsjAll(sch.getFcsjT() + DAY_TIME);*/  
58 52
59 if(sch.getFcsj().compareTo(conf.getStartOpt()) < 0){ 53 if(sch.getFcsj().compareTo(conf.getStartOpt()) < 0){
60 sch.setFcsjAll(sch.getFcsjT() + DAY_TIME); 54 sch.setFcsjAll(sch.getFcsjT() + DAY_TIME);
61 } 55 }
62 56
63 - sch.setRealExecDate(sdfyyyyMMdd.format(new Date(sch.getFcsjT()))); 57 + sch.setRealExecDate(fmtyyyyMMdd.print(sch.getFcsjT()));
64 } catch (Exception e) { 58 } catch (Exception e) {
65 logger.error("", e); 59 logger.error("", e);
66 } 60 }
@@ -77,12 +71,10 @@ public class SchAttrCalculator { @@ -77,12 +71,10 @@ public class SchAttrCalculator {
77 // 生成时间戳 71 // 生成时间戳
78 calcTimestamp(sch); 72 calcTimestamp(sch);
79 73
80 - SimpleDateFormat sdfHHmm = new SimpleDateFormat("HH:mm");  
81 // 计划终点时间 74 // 计划终点时间
82 if (sch.getBcsj() != null) { 75 if (sch.getBcsj() != null) {
83 - Date zdDate = new Date(sch.getDfsjT() + (sch.getBcsj() * 60 * 1000));  
84 - sch.setZdsjT(zdDate.getTime());  
85 - sch.setZdsj(sdfHHmm.format(zdDate)); 76 + sch.setZdsjT(sch.getDfsjT() + (sch.getBcsj() * 60 * 1000));
  77 + sch.setZdsj(fmtHHmm.print(sch.getZdsjT()));
86 } 78 }
87 } catch (ParseException e) { 79 } catch (ParseException e) {
88 logger.error("", e); 80 logger.error("", e);
@@ -178,8 +170,7 @@ public class SchAttrCalculator { @@ -178,8 +170,7 @@ public class SchAttrCalculator {
178 } 170 }
179 171
180 public SchAttrCalculator calcFcsjTime(ScheduleRealInfo sch) throws ParseException { 172 public SchAttrCalculator calcFcsjTime(ScheduleRealInfo sch) throws ParseException {
181 - SimpleDateFormat sdfyyyyMMddHHmm = new SimpleDateFormat("yyyy-MM-ddHH:mm");  
182 - sch.setFcsjT(sdfyyyyMMddHHmm.parse(sch.getRealExecDate() + sch.getFcsj()).getTime()); 173 + sch.setFcsjT(fmtyyyyMMddHHmm.parseMillis(sch.getRealExecDate() + sch.getFcsj()));
183 return this; 174 return this;
184 } 175 }
185 176
src/main/java/com/bsth/data/schedule/thread/ScheduleRefreshThread.java
@@ -18,7 +18,7 @@ import com.bsth.entity.realcontrol.LineConfig; @@ -18,7 +18,7 @@ import com.bsth.entity.realcontrol.LineConfig;
18 18
19 /** 19 /**
20 * 20 *
21 - * @ClassName: refreshScheduleThread 21 + * @ClassName: ScheduleRefreshThread
22 * @Description: TODO(班次刷新线程,用于在营运开始时间切换到当日排班) 22 * @Description: TODO(班次刷新线程,用于在营运开始时间切换到当日排班)
23 * @author PanZhao 23 * @author PanZhao
24 * @date 2016年8月17日 下午1:23:34 24 * @date 2016年8月17日 下午1:23:34
@@ -72,6 +72,7 @@ public class ScheduleRefreshThread extends Thread{ @@ -72,6 +72,7 @@ public class ScheduleRefreshThread extends Thread{
72 logger.info(lineCode + "翻班完成, " + currSchDate + " -班次数量:" + dayOfSchedule.findByLineCode(lineCode).size()); 72 logger.info(lineCode + "翻班完成, " + currSchDate + " -班次数量:" + dayOfSchedule.findByLineCode(lineCode).size());
73 } 73 }
74 } 74 }
  75 +
75 } catch (Exception e) { 76 } catch (Exception e) {
76 logger.error("", e); 77 logger.error("", e);
77 } 78 }
src/main/java/com/bsth/entity/directive/DC0_A3.java
1 package com.bsth.entity.directive; 1 package com.bsth.entity.directive;
2 2
3 -import javax.persistence.Embeddable;  
4 -import javax.persistence.Entity;  
5 -import javax.persistence.GeneratedValue;  
6 -import javax.persistence.Id;  
7 -import javax.persistence.Table;  
8 -import javax.persistence.Transient; 3 +import javax.persistence.*;
9 4
10 /** 5 /**
11 * 6 *
@@ -41,6 +36,7 @@ public class DC0_A3 extends Directive{ @@ -41,6 +36,7 @@ public class DC0_A3 extends Directive{
41 /** 定时定距上报模式 */ 36 /** 定时定距上报模式 */
42 private short reportMode; 37 private short reportMode;
43 /** 定时上报时间间隔 */ 38 /** 定时上报时间间隔 */
  39 + @Column(name = "_interval")
44 private int interval; 40 private int interval;
45 /** 定距上报距离间隔 */ 41 /** 定距上报距离间隔 */
46 private String distance; 42 private String distance;
src/main/java/com/bsth/entity/directive/DC0_A4.java
1 package com.bsth.entity.directive; 1 package com.bsth.entity.directive;
2 2
3 -import javax.persistence.Embeddable;  
4 -import javax.persistence.Entity;  
5 -import javax.persistence.GeneratedValue;  
6 -import javax.persistence.Id;  
7 -import javax.persistence.Table;  
8 -import javax.persistence.Transient; 3 +import javax.persistence.*;
9 4
10 /** 5 /**
11 * 6 *
@@ -41,6 +36,7 @@ public class DC0_A4 extends Directive{ @@ -41,6 +36,7 @@ public class DC0_A4 extends Directive{
41 /** 定时定距上报模式 */ 36 /** 定时定距上报模式 */
42 private short reportMode; 37 private short reportMode;
43 /** 定时上报时间间隔 */ 38 /** 定时上报时间间隔 */
  39 + @Column(name = "_interval")
44 private int interval; 40 private int interval;
45 /** 定距上报距离间隔 */ 41 /** 定距上报距离间隔 */
46 private String distance; 42 private String distance;
src/main/java/com/bsth/entity/realcontrol/ScheduleRealInfo.java
@@ -6,9 +6,9 @@ import com.fasterxml.jackson.annotation.JsonIgnore; @@ -6,9 +6,9 @@ import com.fasterxml.jackson.annotation.JsonIgnore;
6 import javax.persistence.*; 6 import javax.persistence.*;
7 7
8 import org.apache.commons.lang3.StringUtils; 8 import org.apache.commons.lang3.StringUtils;
  9 +import org.joda.time.format.DateTimeFormat;
  10 +import org.joda.time.format.DateTimeFormatter;
9 11
10 -import java.text.ParseException;  
11 -import java.text.SimpleDateFormat;  
12 import java.util.Date; 12 import java.util.Date;
13 import java.util.HashSet; 13 import java.util.HashSet;
14 import java.util.Set; 14 import java.util.Set;
@@ -507,31 +507,28 @@ public class ScheduleRealInfo { @@ -507,31 +507,28 @@ public class ScheduleRealInfo {
507 public void setDfsjT(Long dfsjT) { 507 public void setDfsjT(Long dfsjT) {
508 this.dfsjT = dfsjT; 508 this.dfsjT = dfsjT;
509 } 509 }
510 - 510 +
  511 +
  512 + @Transient
  513 + private static DateTimeFormatter fmtHHmm = DateTimeFormat.forPattern("HH:mm");
  514 + @Transient
  515 + private static DateTimeFormatter fmtyyyyMMddHHmm = DateTimeFormat.forPattern("yyyy-MM-ddHH:mm");
  516 +
511 public void setDfsjAll(Long dfsjT) { 517 public void setDfsjAll(Long dfsjT) {
512 this.dfsjT = dfsjT; 518 this.dfsjT = dfsjT;
513 - SimpleDateFormat sdfHHmm = new SimpleDateFormat("HH:mm");  
514 - this.dfsj = sdfHHmm.format(new Date(this.dfsjT)); 519 + this.dfsj = fmtHHmm.print(this.dfsjT);
515 } 520 }
516 521
517 public void setDfsjAll(String dfsj) { 522 public void setDfsjAll(String dfsj) {
518 -  
519 - try {  
520 - SimpleDateFormat sdfyyyyMMddHHmm = new SimpleDateFormat("yyyy-MM-ddHH:mm");  
521 - this.dfsjT = sdfyyyyMMddHHmm.parse(this.realExecDate + dfsj).getTime();  
522 - this.dfsj = dfsj;  
523 - } catch (ParseException e) {  
524 - e.printStackTrace();  
525 - } 523 + this.dfsjT = fmtyyyyMMddHHmm.parseMillis(this.realExecDate + dfsj);
  524 + this.dfsj = dfsj;
526 } 525 }
527 526
528 public void calcEndTime(){ 527 public void calcEndTime(){
529 //计划终点时间 528 //计划终点时间
530 - SimpleDateFormat sdfHHmm = new SimpleDateFormat("HH:mm");  
531 if(this.getBcsj() != null){ 529 if(this.getBcsj() != null){
532 - Date zdDate = new Date(this.getDfsjT() + (this.getBcsj() * 60 * 1000));  
533 - this.setZdsjT(zdDate.getTime());  
534 - this.setZdsj(sdfHHmm.format(zdDate)); 530 + this.setZdsjT(this.getDfsjT() + (this.getBcsj() * 60 * 1000));
  531 + this.setZdsj(fmtHHmm.print(this.zdsjT));
535 } 532 }
536 } 533 }
537 534
@@ -583,13 +580,8 @@ public class ScheduleRealInfo { @@ -583,13 +580,8 @@ public class ScheduleRealInfo {
583 * @throws 580 * @throws
584 */ 581 */
585 public void setFcsjAll(String fcsj){ 582 public void setFcsjAll(String fcsj){
586 - try {  
587 - SimpleDateFormat sdfyyyyMMddHHmm = new SimpleDateFormat("yyyy-MM-ddHH:mm");  
588 - this.fcsjT = sdfyyyyMMddHHmm.parse(this.realExecDate + fcsj).getTime();  
589 - this.fcsj = fcsj;  
590 - } catch (ParseException e) {  
591 - e.printStackTrace();  
592 - } 583 + this.fcsjT = fmtyyyyMMddHHmm.parseMillis(this.realExecDate + fcsj);
  584 + this.fcsj = fcsj;
593 } 585 }
594 586
595 /** 587 /**
@@ -600,8 +592,7 @@ public class ScheduleRealInfo { @@ -600,8 +592,7 @@ public class ScheduleRealInfo {
600 */ 592 */
601 public void setFcsjAll(Long fcsjT){ 593 public void setFcsjAll(Long fcsjT){
602 this.fcsjT = fcsjT; 594 this.fcsjT = fcsjT;
603 - SimpleDateFormat sdfHHmm = new SimpleDateFormat("HH:mm");  
604 - this.fcsj = sdfHHmm.format(new Date(fcsjT)); 595 + this.fcsj = fmtHHmm.print(fcsjT);
605 } 596 }
606 597
607 /** 598 /**
@@ -611,15 +602,9 @@ public class ScheduleRealInfo { @@ -611,15 +602,9 @@ public class ScheduleRealInfo {
611 * @throws 602 * @throws
612 */ 603 */
613 public void setFcsjActualAll(String fcsjActual){ 604 public void setFcsjActualAll(String fcsjActual){
614 - try {  
615 - SimpleDateFormat sdfyyyyMMddHHmm = new SimpleDateFormat("yyyy-MM-ddHH:mm");  
616 - this.fcsjActualTime = sdfyyyyMMddHHmm.parse(this.realExecDate + fcsjActual).getTime();  
617 - this.fcsjActual = fcsjActual;  
618 -  
619 - calcStatus();  
620 - } catch (ParseException e) {  
621 - e.printStackTrace();  
622 - } 605 + this.fcsjActualTime = fmtyyyyMMddHHmm.parseMillis(this.realExecDate + fcsjActual);
  606 + this.fcsjActual = fcsjActual;
  607 + calcStatus();
623 } 608 }
624 609
625 /** 610 /**
@@ -630,9 +615,8 @@ public class ScheduleRealInfo { @@ -630,9 +615,8 @@ public class ScheduleRealInfo {
630 */ 615 */
631 public void setFcsjActualAll(Long t){ 616 public void setFcsjActualAll(Long t){
632 this.fcsjActualTime = t; 617 this.fcsjActualTime = t;
633 - SimpleDateFormat sdfHHmm = new SimpleDateFormat("HH:mm");  
634 - this.fcsjActual = sdfHHmm.format(new Date(t));  
635 - 618 + this.fcsjActual = fmtHHmm.print(t);
  619 +
636 //更新班次状态 620 //更新班次状态
637 calcStatus(); 621 calcStatus();
638 } 622 }
@@ -645,12 +629,10 @@ public class ScheduleRealInfo { @@ -645,12 +629,10 @@ public class ScheduleRealInfo {
645 */ 629 */
646 public void setZdsjActualAll(Long t){ 630 public void setZdsjActualAll(Long t){
647 this.zdsjActualTime = t; 631 this.zdsjActualTime = t;
648 - SimpleDateFormat sdfHHmm = new SimpleDateFormat("HH:mm");  
649 - this.zdsjActual = sdfHHmm.format(new Date(t)); 632 + this.zdsjActual = fmtHHmm.print(t);
650 633
651 //更新班次状态 634 //更新班次状态
652 calcStatus(); 635 calcStatus();
653 - //this.synchroZdsj();  
654 } 636 }
655 637
656 /** 638 /**
@@ -660,15 +642,10 @@ public class ScheduleRealInfo { @@ -660,15 +642,10 @@ public class ScheduleRealInfo {
660 * @throws 642 * @throws
661 */ 643 */
662 public void setZdsjActualAll(String zdsjActual){ 644 public void setZdsjActualAll(String zdsjActual){
663 - try {  
664 - SimpleDateFormat sdfyyyyMMddHHmm = new SimpleDateFormat("yyyy-MM-ddHH:mm");  
665 - this.zdsjActualTime = sdfyyyyMMddHHmm.parse(this.realExecDate + zdsjActual).getTime();  
666 - this.zdsjActual = zdsjActual;  
667 -  
668 - calcStatus();  
669 - } catch (ParseException e) {  
670 - e.printStackTrace();  
671 - } 645 + this.zdsjActualTime = fmtyyyyMMddHHmm.parseMillis(this.realExecDate + zdsjActual);
  646 + this.zdsjActual = zdsjActual;
  647 +
  648 + calcStatus();
672 } 649 }
673 650
674 public Long getSpId() { 651 public Long getSpId() {
@@ -713,17 +690,17 @@ public class ScheduleRealInfo { @@ -713,17 +690,17 @@ public class ScheduleRealInfo {
713 return this.status == -1; 690 return this.status == -1;
714 } 691 }
715 692
716 - public boolean isNotDestroy(){ 693 +/* public boolean isNotDestroy(){
717 return this.status != -1; 694 return this.status != -1;
718 - } 695 + }*/
719 696
720 public Set<ChildTaskPlan> getcTasks() { 697 public Set<ChildTaskPlan> getcTasks() {
721 return cTasks; 698 return cTasks;
722 } 699 }
723 700
724 - public void setcTasks(Set<ChildTaskPlan> cTasks) { 701 +/* public void setcTasks(Set<ChildTaskPlan> cTasks) {
725 this.cTasks = cTasks; 702 this.cTasks = cTasks;
726 - } 703 + }*/
727 704
728 public String getScheduleDateStr() { 705 public String getScheduleDateStr() {
729 return scheduleDateStr; 706 return scheduleDateStr;
src/main/java/com/bsth/entity/schedule/SchedulePlan.java
@@ -38,6 +38,15 @@ public class SchedulePlan { @@ -38,6 +38,15 @@ public class SchedulePlan {
38 @ManyToOne(cascade = CascadeType.PERSIST, fetch = FetchType.LAZY) 38 @ManyToOne(cascade = CascadeType.PERSIST, fetch = FetchType.LAZY)
39 private ScheduleRule1 scheduleRule1; 39 private ScheduleRule1 scheduleRule1;
40 40
  41 + // TODO: 新字段,测试完后删除旧的字段
  42 +
  43 + /** 使用的时刻表名字列表(用逗号连接) */
  44 + private String ttInfoNames;
  45 + /** 使用的时刻表id列表(用逗号连接) */
  46 + private String ttInfoId;
  47 + /** 使用的规则1列表(用逗号连接) */
  48 + private String rule1Ids;
  49 +
41 /** 排班计划的开始时间 */ 50 /** 排班计划的开始时间 */
42 @Column(nullable = false) 51 @Column(nullable = false)
43 private Date scheduleFromTime; 52 private Date scheduleFromTime;
@@ -150,4 +159,28 @@ public class SchedulePlan { @@ -150,4 +159,28 @@ public class SchedulePlan {
150 public void setUpdateDate(Date updateDate) { 159 public void setUpdateDate(Date updateDate) {
151 this.updateDate = updateDate; 160 this.updateDate = updateDate;
152 } 161 }
  162 +
  163 + public String getTtInfoNames() {
  164 + return ttInfoNames;
  165 + }
  166 +
  167 + public void setTtInfoNames(String ttInfoNames) {
  168 + this.ttInfoNames = ttInfoNames;
  169 + }
  170 +
  171 + public String getTtInfoId() {
  172 + return ttInfoId;
  173 + }
  174 +
  175 + public void setTtInfoId(String ttInfoId) {
  176 + this.ttInfoId = ttInfoId;
  177 + }
  178 +
  179 + public String getRule1Ids() {
  180 + return rule1Ids;
  181 + }
  182 +
  183 + public void setRule1Ids(String rule1Ids) {
  184 + this.rule1Ids = rule1Ids;
  185 + }
153 } 186 }
src/main/java/com/bsth/entity/schedule/SchedulePlanInfo.java
@@ -121,6 +121,13 @@ public class SchedulePlanInfo { @@ -121,6 +121,13 @@ public class SchedulePlanInfo {
121 @Column(nullable = false) 121 @Column(nullable = false)
122 private String bcType; 122 private String bcType;
123 123
  124 + // 重要的新增字段
  125 + /** 关联的时刻表id */
  126 + private Long ttInfo;
  127 + /** 关联的时刻表名字 */
  128 + private String ttInfoName;
  129 +
  130 +
124 /** 创建人 */ 131 /** 创建人 */
125 @ManyToOne(cascade = CascadeType.PERSIST, fetch = FetchType.LAZY) 132 @ManyToOne(cascade = CascadeType.PERSIST, fetch = FetchType.LAZY)
126 private SysUser createBy; 133 private SysUser createBy;
@@ -555,4 +562,20 @@ public class SchedulePlanInfo { @@ -555,4 +562,20 @@ public class SchedulePlanInfo {
555 public void setSchedulePlan(SchedulePlan schedulePlan) { 562 public void setSchedulePlan(SchedulePlan schedulePlan) {
556 this.schedulePlan = schedulePlan; 563 this.schedulePlan = schedulePlan;
557 } 564 }
  565 +
  566 + public Long getTtInfo() {
  567 + return ttInfo;
  568 + }
  569 +
  570 + public void setTtInfo(Long ttInfo) {
  571 + this.ttInfo = ttInfo;
  572 + }
  573 +
  574 + public String getTtInfoName() {
  575 + return ttInfoName;
  576 + }
  577 +
  578 + public void setTtInfoName(String ttInfoName) {
  579 + this.ttInfoName = ttInfoName;
  580 + }
558 } 581 }
src/main/java/com/bsth/entity/search/PredicatesBuilder.java
1 package com.bsth.entity.search; 1 package com.bsth.entity.search;
2 2
  3 +import org.joda.time.DateTime;
  4 +
3 import javax.persistence.criteria.CriteriaBuilder; 5 import javax.persistence.criteria.CriteriaBuilder;
4 import javax.persistence.criteria.Path; 6 import javax.persistence.criteria.Path;
5 import javax.persistence.criteria.Predicate; 7 import javax.persistence.criteria.Predicate;
@@ -27,7 +29,26 @@ public class PredicatesBuilder { @@ -27,7 +29,26 @@ public class PredicatesBuilder {
27 } 29 }
28 30
29 public static Predicate eq(CriteriaBuilder cb,Path<?> expression, Object object){ 31 public static Predicate eq(CriteriaBuilder cb,Path<?> expression, Object object){
30 - return cb.equal(expression, object); 32 + Class<?> leftType = expression.getJavaType();
  33 + Class<?> rightType = object.getClass();
  34 +
  35 + if (Number.class.isAssignableFrom(leftType) &&
  36 + (Number.class.isAssignableFrom(rightType) || String.class.isAssignableFrom(rightType))) { // Number == Number/String
  37 + return cb.equal(expression, object);
  38 + } else if (String.class.isAssignableFrom(leftType) &&
  39 + (String.class.isAssignableFrom(rightType) || Number.class.isAssignableFrom(rightType))) { // String == String/Number
  40 + return cb.equal(expression, object);
  41 + } else if (Date.class.isAssignableFrom(leftType) &&
  42 + Date.class.isAssignableFrom(rightType)) { // Date == Date
  43 + return cb.equal(expression, object);
  44 + } else if (Date.class.isAssignableFrom(leftType) &&
  45 + String.class.isAssignableFrom(rightType)) { // Date == String
  46 + DateTime dateTime = new DateTime(object);
  47 + return cb.equal(expression, dateTime.toDate());
  48 + } else {
  49 + throw new RuntimeException("eq 不支持类型组合:" + expression.getJavaType() + "==" + object.getClass());
  50 + }
  51 +
31 } 52 }
32 53
33 public static Predicate ne(CriteriaBuilder cb,Path<?> expression, Object object){ 54 public static Predicate ne(CriteriaBuilder cb,Path<?> expression, Object object){
@@ -47,15 +68,19 @@ public class PredicatesBuilder { @@ -47,15 +68,19 @@ public class PredicatesBuilder {
47 Class<?> leftType = expression.getJavaType(); 68 Class<?> leftType = expression.getJavaType();
48 Class<?> rightType = object.getClass(); 69 Class<?> rightType = object.getClass();
49 70
50 - if (leftType.isAssignableFrom(Number.class) &&  
51 - rightType.isAssignableFrom(Number.class)) { // 判定是否是Number类型的子类 71 + if (Number.class.isAssignableFrom(leftType) &&
  72 + (Number.class.isAssignableFrom(rightType) || String.class.isAssignableFrom(rightType))) { // Number >= Number/String
52 return cb.ge((Path<Number>) expression, (Number) object); 73 return cb.ge((Path<Number>) expression, (Number) object);
53 - } else if (leftType.isAssignableFrom(String.class) &&  
54 - rightType.isAssignableFrom(String.class)) { // 判定是否是String类型的子类 74 + } else if (String.class.isAssignableFrom(leftType) &&
  75 + (String.class.isAssignableFrom(rightType) || Number.class.isAssignableFrom(rightType))) { // String >= String/Number
55 return cb.greaterThanOrEqualTo((Path<String>) expression, (String) object); 76 return cb.greaterThanOrEqualTo((Path<String>) expression, (String) object);
56 - } else if (leftType.isAssignableFrom(Date.class) &&  
57 - rightType.isAssignableFrom(Date.class)) { // 判定是否是Date类型的子类 77 + } else if (Date.class.isAssignableFrom(leftType) &&
  78 + Date.class.isAssignableFrom(rightType)) { // Date >= Date
58 return cb.greaterThanOrEqualTo((Path<Date>) expression, (Date) object); 79 return cb.greaterThanOrEqualTo((Path<Date>) expression, (Date) object);
  80 + } else if (Date.class.isAssignableFrom(leftType) &&
  81 + String.class.isAssignableFrom(rightType)) { // Date >= String
  82 + DateTime dateTime = new DateTime(object);
  83 + return cb.greaterThanOrEqualTo((Path<Date>) expression, dateTime.toDate());
59 } else { 84 } else {
60 throw new RuntimeException("ge 不支持类型组合:" + expression.getJavaType() + ">=" + object.getClass()); 85 throw new RuntimeException("ge 不支持类型组合:" + expression.getJavaType() + ">=" + object.getClass());
61 } 86 }
@@ -74,17 +99,22 @@ public class PredicatesBuilder { @@ -74,17 +99,22 @@ public class PredicatesBuilder {
74 Class<?> leftType = expression.getJavaType(); 99 Class<?> leftType = expression.getJavaType();
75 Class<?> rightType = object.getClass(); 100 Class<?> rightType = object.getClass();
76 101
77 - if (leftType.isAssignableFrom(Number.class) &&  
78 - rightType.isAssignableFrom(Number.class)) { // 判定是否是Number类型的子类 102 +
  103 + if (Number.class.isAssignableFrom(leftType) &&
  104 + (Number.class.isAssignableFrom(rightType) || String.class.isAssignableFrom(rightType))) { // Number <= Number/String
79 return cb.le((Path<Number>) expression, (Number) object); 105 return cb.le((Path<Number>) expression, (Number) object);
80 - } else if (leftType.isAssignableFrom(String.class) &&  
81 - rightType.isAssignableFrom(String.class)) { // 判定是否是String类型的子类 106 + } else if (String.class.isAssignableFrom(leftType) &&
  107 + (String.class.isAssignableFrom(rightType) || Number.class.isAssignableFrom(rightType))) { // String <= String/Number
82 return cb.lessThanOrEqualTo((Path<String>) expression, (String) object); 108 return cb.lessThanOrEqualTo((Path<String>) expression, (String) object);
83 - } else if (leftType.isAssignableFrom(Date.class) &&  
84 - rightType.isAssignableFrom(Date.class)) { // 判定是否是Date类型的子类 109 + } else if (Date.class.isAssignableFrom(leftType) &&
  110 + Date.class.isAssignableFrom(rightType)) { // Date <= Date
85 return cb.lessThanOrEqualTo((Path<Date>) expression, (Date) object); 111 return cb.lessThanOrEqualTo((Path<Date>) expression, (Date) object);
  112 + } else if (Date.class.isAssignableFrom(leftType) &&
  113 + String.class.isAssignableFrom(rightType)) { // Date <= String
  114 + DateTime dateTime = new DateTime(object);
  115 + return cb.lessThanOrEqualTo((Path<Date>) expression, dateTime.toDate());
86 } else { 116 } else {
87 - throw new RuntimeException("ge 不支持类型组合:" + expression.getJavaType() + ">=" + object.getClass()); 117 + throw new RuntimeException("le 不支持类型组合:" + expression.getJavaType() + "<=" + object.getClass());
88 } 118 }
89 } 119 }
90 120
src/main/java/com/bsth/service/directive/DirectiveServiceImpl.java
1 package com.bsth.service.directive; 1 package com.bsth.service.directive;
2 2
3 -import java.text.SimpleDateFormat;  
4 import java.util.ArrayList; 3 import java.util.ArrayList;
5 import java.util.Collection; 4 import java.util.Collection;
6 import java.util.Collections; 5 import java.util.Collections;
@@ -11,6 +10,8 @@ import java.util.List; @@ -11,6 +10,8 @@ import java.util.List;
11 import java.util.Map; 10 import java.util.Map;
12 11
13 import org.apache.commons.lang3.StringUtils; 12 import org.apache.commons.lang3.StringUtils;
  13 +import org.joda.time.format.DateTimeFormat;
  14 +import org.joda.time.format.DateTimeFormatter;
14 import org.slf4j.Logger; 15 import org.slf4j.Logger;
15 import org.slf4j.LoggerFactory; 16 import org.slf4j.LoggerFactory;
16 import org.springframework.beans.factory.annotation.Autowired; 17 import org.springframework.beans.factory.annotation.Autowired;
@@ -73,7 +74,10 @@ public class DirectiveServiceImpl extends BaseServiceImpl&lt;D60, Integer&gt; implemen @@ -73,7 +74,10 @@ public class DirectiveServiceImpl extends BaseServiceImpl&lt;D60, Integer&gt; implemen
73 @Autowired 74 @Autowired
74 DayOfSchedule dayOfSchedule; 75 DayOfSchedule dayOfSchedule;
75 76
76 - static Long schDiff = 1000 * 60 * 60L; 77 + //static Long schDiff = 1000 * 60 * 60L;
  78 +
  79 + private static DateTimeFormatter fmtHHmm = DateTimeFormat.forPattern("HH:mm")
  80 + ,fmtHHmm_CN = DateTimeFormat.forPattern("HH点mm分");
77 81
78 @Override 82 @Override
79 public int send60Phrase(String nbbm, String text, String sender) { 83 public int send60Phrase(String nbbm, String text, String sender) {
@@ -111,10 +115,7 @@ public class DirectiveServiceImpl extends BaseServiceImpl&lt;D60, Integer&gt; implemen @@ -111,10 +115,7 @@ public class DirectiveServiceImpl extends BaseServiceImpl&lt;D60, Integer&gt; implemen
111 logger.warn("烂班不允许发送调度指令...."); 115 logger.warn("烂班不允许发送调度指令....");
112 return -1; 116 return -1;
113 } 117 }
114 - //多线程下发指令时,SimpleDateFormat必须方法内初始化  
115 - SimpleDateFormat sdfHHmm = new SimpleDateFormat("HH点mm分");  
116 -  
117 - String text = "已完成" + finish + "个班次,下一发车时间" + sdfHHmm.format(new Date(sch.getDfsjT())) + ",由" 118 + String text = "已完成" + finish + "个班次,下一发车时间" + fmtHHmm_CN.print(sch.getDfsjT()) + ",由"
118 + sch.getQdzName() + "发往" + sch.getZdzName(); 119 + sch.getQdzName() + "发往" + sch.getZdzName();
119 120
120 //下发0x02指令 调度指令(闹钟有效) 121 //下发0x02指令 调度指令(闹钟有效)
@@ -168,7 +169,7 @@ public class DirectiveServiceImpl extends BaseServiceImpl&lt;D60, Integer&gt; implemen @@ -168,7 +169,7 @@ public class DirectiveServiceImpl extends BaseServiceImpl&lt;D60, Integer&gt; implemen
168 @Override 169 @Override
169 public void sendD60ToPage(ScheduleRealInfo sch) { 170 public void sendD60ToPage(ScheduleRealInfo sch) {
170 Map<String, Object> map = new HashMap<>(); 171 Map<String, Object> map = new HashMap<>();
171 - map.put("fn", sch); 172 + map.put("fn", "directive");
172 map.put("t", sch); 173 map.put("t", sch);
173 174
174 ObjectMapper mapper = new ObjectMapper(); 175 ObjectMapper mapper = new ObjectMapper();
@@ -402,11 +403,10 @@ public class DirectiveServiceImpl extends BaseServiceImpl&lt;D60, Integer&gt; implemen @@ -402,11 +403,10 @@ public class DirectiveServiceImpl extends BaseServiceImpl&lt;D60, Integer&gt; implemen
402 403
403 List<Directive> rs = list.subList(s, e); 404 List<Directive> rs = list.subList(s, e);
404 405
405 - SimpleDateFormat sdfHHmm = new SimpleDateFormat("HH:mm");  
406 // 时间格式化,车辆自编号转换 406 // 时间格式化,车辆自编号转换
407 for (Directive d : rs) { 407 for (Directive d : rs) {
408 if (d.getTimeHHmm() == null) 408 if (d.getTimeHHmm() == null)
409 - d.setTimeHHmm(sdfHHmm.format(new Date(d.getTimestamp()))); 409 + d.setTimeHHmm(fmtHHmm.print(d.getTimestamp()));
410 if (d.getNbbm() == null) 410 if (d.getNbbm() == null)
411 d.setNbbm(BasicData.deviceId2NbbmMap.get(d.getDeviceId())); 411 d.setNbbm(BasicData.deviceId2NbbmMap.get(d.getDeviceId()));
412 } 412 }
@@ -455,10 +455,10 @@ public class DirectiveServiceImpl extends BaseServiceImpl&lt;D60, Integer&gt; implemen @@ -455,10 +455,10 @@ public class DirectiveServiceImpl extends BaseServiceImpl&lt;D60, Integer&gt; implemen
455 if (e > count) 455 if (e > count)
456 e = count; 456 e = count;
457 457
458 - SimpleDateFormat sdfHHmm = new SimpleDateFormat("HH:mm"); 458 + //SimpleDateFormat sdfHHmm = new SimpleDateFormat("HH:mm");
459 List<D80> rs = d80s.subList(s, e); 459 List<D80> rs = d80s.subList(s, e);
460 for(D80 d80 : rs){ 460 for(D80 d80 : rs){
461 - d80.setTimeStr(sdfHHmm.format(new Date(d80.getTimestamp()))); 461 + d80.setTimeStr(fmtHHmm.print(d80.getTimestamp()));
462 } 462 }
463 463
464 Map<String, Object> rsMap = new HashMap<>(); 464 Map<String, Object> rsMap = new HashMap<>();
src/main/java/com/bsth/service/schedule/TTInfoDetailService.java
@@ -136,7 +136,7 @@ public interface TTInfoDetailService extends BaseService&lt;TTInfoDetail, Long&gt; { @@ -136,7 +136,7 @@ public interface TTInfoDetailService extends BaseService&lt;TTInfoDetail, Long&gt; {
136 String ttinfoname, 136 String ttinfoname,
137 String tccname) throws Exception; 137 String tccname) throws Exception;
138 138
139 - void fileDataImport(File file, String xlmc, String ttinfoname, String tccname) throws Exception; 139 + void fileDataImport(File file, String sheetname, String xlmc, String ttinfoname, String tccname) throws Exception;
140 140
141 141
142 } 142 }
src/main/java/com/bsth/service/schedule/TTInfoDetailServiceImpl.java
@@ -114,6 +114,7 @@ public class TTInfoDetailServiceImpl extends BaseServiceImpl&lt;TTInfoDetail, Long&gt; @@ -114,6 +114,7 @@ public class TTInfoDetailServiceImpl extends BaseServiceImpl&lt;TTInfoDetail, Long&gt;
114 return editInfo; 114 return editInfo;
115 } 115 }
116 116
  117 + @Override
117 /** 118 /**
118 * 上传并导入数据,和DataImportExportService的同名方法有差别。 119 * 上传并导入数据,和DataImportExportService的同名方法有差别。
119 * @param datafile form上传文件 120 * @param datafile form上传文件
@@ -128,12 +129,12 @@ public class TTInfoDetailServiceImpl extends BaseServiceImpl&lt;TTInfoDetail, Long&gt; @@ -128,12 +129,12 @@ public class TTInfoDetailServiceImpl extends BaseServiceImpl&lt;TTInfoDetail, Long&gt;
128 String tccname) throws Exception { 129 String tccname) throws Exception {
129 // 上传数据文件 130 // 上传数据文件
130 File uploadFile = dataImportExportService.uploadFile(datafile); 131 File uploadFile = dataImportExportService.uploadFile(datafile);
131 - fileDataImport(uploadFile, xlmc, ttinfoname, tccname); 132 + fileDataImport(uploadFile, "工作表1", xlmc, ttinfoname, tccname);
132 133
133 } 134 }
134 135
135 @Override 136 @Override
136 - public void fileDataImport(File uploadFile, String xlmc, String ttinfoname, String tccname) throws Exception { 137 + public void fileDataImport(File uploadFile, String sheetname, String xlmc, String ttinfoname, String tccname) throws Exception {
137 // 1、上传数据文件 138 // 1、上传数据文件
138 System.out.println("线路名称:" + xlmc); 139 System.out.println("线路名称:" + xlmc);
139 System.out.println("时刻表名称:" + ttinfoname); 140 System.out.println("时刻表名称:" + ttinfoname);
@@ -162,6 +163,7 @@ public class TTInfoDetailServiceImpl extends BaseServiceImpl&lt;TTInfoDetail, Long&gt; @@ -162,6 +163,7 @@ public class TTInfoDetailServiceImpl extends BaseServiceImpl&lt;TTInfoDetail, Long&gt;
162 // 2.3、设定命名参数,用于指定数据文件,注意每个ktr必须都有以下指定的命名参数 163 // 2.3、设定命名参数,用于指定数据文件,注意每个ktr必须都有以下指定的命名参数
163 trans.setParameterValue("injectktrfile", ktrFile2.getAbsolutePath()); // 注入元数据的ktr文件 164 trans.setParameterValue("injectktrfile", ktrFile2.getAbsolutePath()); // 注入元数据的ktr文件
164 trans.setParameterValue("filepath", uploadFile.getAbsolutePath()); // 指定导入数据文件的位置 165 trans.setParameterValue("filepath", uploadFile.getAbsolutePath()); // 指定导入数据文件的位置
  166 + trans.setParameterValue("sheetname", sheetname); // sheet工作区的名字
165 trans.setParameterValue("erroroutputdir", dataToolsProperties.getTransErrordir()); // ktr转换错误输出目录 167 trans.setParameterValue("erroroutputdir", dataToolsProperties.getTransErrordir()); // ktr转换错误输出目录
166 trans.setParameterValue("xlname", xlmc); // 线路名称 168 trans.setParameterValue("xlname", xlmc); // 线路名称
167 trans.setParameterValue("ttinfoname", ttinfoname); // 时刻表名称 169 trans.setParameterValue("ttinfoname", ttinfoname); // 时刻表名称
src/main/java/com/bsth/websocket/handler/RealControlSocketHandler.java
@@ -105,7 +105,7 @@ public class RealControlSocketHandler implements WebSocketHandler { @@ -105,7 +105,7 @@ public class RealControlSocketHandler implements WebSocketHandler {
105 * 给所有在线用户发送消息 105 * 给所有在线用户发送消息
106 * 106 *
107 * @param message 107 * @param message
108 - */ 108 +
109 public synchronized void sendMessageToUsers(TextMessage message) { 109 public synchronized void sendMessageToUsers(TextMessage message) {
110 for (WebSocketSession user : users) { 110 for (WebSocketSession user : users) {
111 try { 111 try {
@@ -116,14 +116,14 @@ public class RealControlSocketHandler implements WebSocketHandler { @@ -116,14 +116,14 @@ public class RealControlSocketHandler implements WebSocketHandler {
116 e.printStackTrace(); 116 e.printStackTrace();
117 } 117 }
118 } 118 }
119 - } 119 + }*/
120 120
121 /** 121 /**
122 * 给某些用户发送消息 122 * 给某些用户发送消息
123 * 123 *
124 * @param userId 124 * @param userId
125 * @param message 125 * @param message
126 - */ 126 +
127 public synchronized void sendMessageToUser(Set<String> uids, String msg) { 127 public synchronized void sendMessageToUser(Set<String> uids, String msg) {
128 TextMessage message = new TextMessage(msg.getBytes()); 128 TextMessage message = new TextMessage(msg.getBytes());
129 for (WebSocketSession user : users) { 129 for (WebSocketSession user : users) {
@@ -137,13 +137,10 @@ public class RealControlSocketHandler implements WebSocketHandler { @@ -137,13 +137,10 @@ public class RealControlSocketHandler implements WebSocketHandler {
137 } 137 }
138 } 138 }
139 } 139 }
140 - } 140 + }*/
141 141
142 /** 142 /**
143 * 根据线路推送消息 143 * 根据线路推送消息
144 - *  
145 - * @param userId  
146 - * @param message  
147 */ 144 */
148 public synchronized void sendMessageToLine(String lineCode, String msg) { 145 public synchronized void sendMessageToLine(String lineCode, String msg) {
149 146
src/main/resources/application-dev.properties
@@ -6,9 +6,9 @@ spring.jpa.hibernate.ddl-auto= update @@ -6,9 +6,9 @@ spring.jpa.hibernate.ddl-auto= update
6 spring.jpa.hibernate.naming_strategy= org.hibernate.cfg.ImprovedNamingStrategy 6 spring.jpa.hibernate.naming_strategy= org.hibernate.cfg.ImprovedNamingStrategy
7 #DATABASE 7 #DATABASE
8 spring.jpa.database= MYSQL 8 spring.jpa.database= MYSQL
9 -spring.jpa.show-sql= true 9 +spring.jpa.show-sql= false
10 spring.datasource.driver-class-name= com.mysql.jdbc.Driver 10 spring.datasource.driver-class-name= com.mysql.jdbc.Driver
11 -spring.datasource.url= jdbc:mysql://192.168.168.201:3306/mh_control 11 +spring.datasource.url= jdbc:mysql://192.168.168.201:3306/qp_control?useUnicode=true&characterEncoding=utf-8&useSSL=false
12 spring.datasource.username= root 12 spring.datasource.username= root
13 spring.datasource.password= 123456 13 spring.datasource.password= 123456
14 #DATASOURCE 14 #DATASOURCE
src/main/resources/application-prod.properties
@@ -8,7 +8,7 @@ spring.jpa.hibernate.naming_strategy= org.hibernate.cfg.ImprovedNamingStrategy @@ -8,7 +8,7 @@ spring.jpa.hibernate.naming_strategy= org.hibernate.cfg.ImprovedNamingStrategy
8 spring.jpa.database= MYSQL 8 spring.jpa.database= MYSQL
9 spring.jpa.show-sql= true 9 spring.jpa.show-sql= true
10 spring.datasource.driver-class-name= com.mysql.jdbc.Driver 10 spring.datasource.driver-class-name= com.mysql.jdbc.Driver
11 -spring.datasource.url= jdbc:mysql://192.168.40.100:3306/qp_control 11 +spring.datasource.url= jdbc:mysql://192.168.40.100:3306/qp_control?useUnicode=true&characterEncoding=utf-8&useSSL=false
12 spring.datasource.username= root 12 spring.datasource.username= root
13 spring.datasource.password= root@JSP2jsp 13 spring.datasource.password= root@JSP2jsp
14 #DATASOURCE 14 #DATASOURCE