Commit 9310b8a54e0809b491d6612feb9a44f619f2bab8

Authored by mcy123
1 parent 2206d859

mcy

src/main/java/com/bsth/data/schedule/DayOfSchedule.java
@@ -45,530 +45,441 @@ import java.util.concurrent.TimeUnit; @@ -45,530 +45,441 @@ import java.util.concurrent.TimeUnit;
45 @Component 45 @Component
46 public class DayOfSchedule implements CommandLineRunner { 46 public class DayOfSchedule implements CommandLineRunner {
47 47
48 - Logger logger = LoggerFactory.getLogger(this.getClass());  
49 -  
50 - // 按车辆分组的班次数据  
51 - private static ArrayListMultimap<String, ScheduleRealInfo> nbbmScheduleMap;  
52 -  
53 - // 班次主键映射  
54 - private static Map<Long, ScheduleRealInfo> id2SchedulMap; 48 + Logger logger = LoggerFactory.getLogger(this.getClass());
  49 +
  50 + // 按车辆分组的班次数据
  51 + private static ArrayListMultimap<String, ScheduleRealInfo> nbbmScheduleMap;
  52 +
  53 + // 班次主键映射
  54 + private static Map<Long, ScheduleRealInfo> id2SchedulMap;
  55 +
  56 + // 车辆和排班起终点站对照(包括进出的停车场,区间起终点)
  57 + private static TreeMultimap<String, String> nbbm2SEStationMap;
  58 +
  59 + //车辆 ——> 当前执行班次
  60 + private static Map<String, ScheduleRealInfo> carExecutePlanMap;
  61 +
  62 + // 持久化缓冲区
  63 + public static LinkedList<ScheduleRealInfo> pstBuffer;
  64 +
  65 + // 排序器
  66 + private static ScheduleComparator.FCSJ schFCSJComparator;
  67 +
  68 + @Autowired
  69 + LineConfigData lineConfigData;
  70 +
  71 + @Autowired
  72 + ScheduleRealInfoRepository schRepository;
  73 +
  74 + @Autowired
  75 + SchedulePlanInfoService schPlanService;
  76 +
  77 + @Autowired
  78 + SchAttrCalculator schAttrCalculator;
  79 +
  80 + @Autowired
  81 + SendUtils sendUtils;
  82 +
  83 + @Autowired
  84 + GpsRealData gpsRealData;
  85 +
  86 + /** 线路当前使用的排班的日期 */
  87 + public static Map<String, String> currSchDateMap;
  88 +
  89 + static {
  90 + nbbmScheduleMap = ArrayListMultimap.create();
  91 + id2SchedulMap = new HashMap<>();
  92 + pstBuffer = new LinkedList<>();
  93 + schFCSJComparator = new ScheduleComparator.FCSJ();
  94 + currSchDateMap = new HashMap<>();
  95 + nbbm2SEStationMap = TreeMultimap.create();
  96 + carExecutePlanMap = new HashMap<>();
  97 + }
  98 +
  99 + @Autowired
  100 + ScheduleRefreshThread scheduleRefreshThread;
  101 +
  102 + @Autowired
  103 + SchedulePstThread schedulePstThread;
  104 +
  105 + @Autowired
  106 + FirstScheduleCheckThread firstScheduleCheckThread;
  107 +
  108 + @Autowired
  109 + ScheduleLateThread scheduleLateThread;
  110 +
  111 + private static DateTimeFormatter fmtyyyyMMdd = DateTimeFormat.forPattern("yyyy-MM-dd")
  112 + ,fmtHHmm = DateTimeFormat.forPattern("HH:mm");
  113 +
  114 + @Override
  115 + public void run(String... arg0) throws Exception {
  116 + //翻班线程
  117 + Application.mainServices.scheduleWithFixedDelay(scheduleRefreshThread, 15, 240, TimeUnit.SECONDS);
  118 + //入库
  119 + Application.mainServices.scheduleWithFixedDelay(schedulePstThread, 60, 60, TimeUnit.SECONDS);
  120 + //首班出场指令补发器
  121 + Application.mainServices.scheduleWithFixedDelay(firstScheduleCheckThread, 30, 240, TimeUnit.SECONDS);
  122 + //班次误点扫描
  123 + //Application.mainServices.scheduleWithFixedDelay(scheduleLateThread, 60, 60, TimeUnit.SECONDS);
  124 + }
  125 +
  126 + public Map<String, String> getCurrSchDate() {
  127 + return currSchDateMap;
  128 + }
  129 +
  130 + /**
  131 + *
  132 + * @Title: calcSchDateB
  133 + * @Description: TODO(计算线路当前应该使用的排班日期)
  134 + */
  135 + public String calcSchDate(String lineCode) {
  136 + LineConfig conf = lineConfigData.get(lineCode);
  137 + long ct = System.currentTimeMillis();
  138 +
  139 + String schDate = fmtyyyyMMdd.print(ct);
  140 + // 小于当天起始运营时间,则取前一天的排班
  141 + if (ct < conf.getCurrStartTime())
  142 + schDate = DateUtils.subtractDay(schDate, 1);
  143 +
  144 + return schDate;
  145 + }
  146 +
  147 + /**
  148 + * @Title: reloadSch
  149 + * @Title: reloadSch
  150 + * @Description: TODO(重新载入排班)
  151 + * @param @param
  152 + * lineCode 线路编码
  153 + * @param @param
  154 + * schDate 班次日期 yyyy-MM-dd
  155 + * @param @param
  156 + * forcePlan 强制从计划调度重新抓取
  157 + */
  158 + public int reloadSch(String lineCode, String schDate, boolean forcePlan) {
  159 + try {
  160 + List<ScheduleRealInfo> list;
  161 +
  162 + if (forcePlan)
  163 + removeRealSch(lineCode, schDate);
  164 + else
  165 + clearRAMData(lineCode);
  166 +
  167 + if (existRealSch(lineCode, schDate))
  168 + list = loadRealSch(lineCode, schDate);// 从实际排班表加载
  169 + else {
  170 + list = loadPlanSch(lineCode, schDate);// 从计划排班表加载
  171 + // 写入数据库
  172 + batchSave(list);
  173 + }
  174 +
  175 + //更新线路和班次日期对照
  176 + currSchDateMap.put(lineCode, schDate);
  177 + //添加到缓存
  178 + putAll(list);
  179 +
  180 + Set<String> cars = searchAllCars(list);
  181 + //计算“起点站应到”时间
  182 + for(String nbbm : cars)
  183 + schAttrCalculator.calcQdzTimePlan(nbbmScheduleMap.get(nbbm));
  184 +
  185 + //是否是出站即出场
  186 + LineConfig conf = lineConfigData.get(lineCode);
  187 + if(conf.getOutConfig() == 2){
  188 + for(String nbbm : cars)
  189 + schAttrCalculator.connectOutSchedule(nbbmScheduleMap.get(nbbm));
  190 + }
  191 +
  192 + // 页面 翻班通知
  193 + sendUtils.shiftSchedule(lineCode);
  194 + } catch (Exception e) {
  195 + logger.error("", e);
  196 + return -1;
  197 + }
55 198
56 - // 车辆和排班起终点站对照(包括进出的停车场,区间起终点)  
57 - private static TreeMultimap<String, String> nbbm2SEStationMap; 199 + return 0;
  200 + }
  201 +
  202 + /**
  203 + *
  204 + * @Title: searchAllCars
  205 + * @Description: TODO(搜索班次集合中的车辆)
  206 + */
  207 + private Set<String> searchAllCars(List<ScheduleRealInfo> list) {
  208 + Set<String> cars = new HashSet<>();
  209 + for(ScheduleRealInfo sch : list)
  210 + cars.add(sch.getClZbh());
  211 +
  212 + return cars;
  213 + }
  214 +
  215 + private void putAll(List<ScheduleRealInfo> list) {
  216 + for (ScheduleRealInfo sch : list)
  217 + put(sch);
  218 + }
  219 +
  220 + /**
  221 + * @Title: removeRealSch
  222 + * @Description: TODO(清除实际排班,包括数据库和内存数据)
  223 + * @param @param
  224 + * lineCode 线路编码
  225 + * @param @param
  226 + * schDate 班次日期 yyyy-MM-dd
  227 + */
  228 + public void removeRealSch(String lineCode, String schDate) throws Exception {
  229 + try {
  230 + // 清理数据库数据
  231 + schRepository.deleteByLineCodeAndDate(lineCode + "", schDate);
  232 +
  233 + // 清理内存数据
  234 + clearRAMData(lineCode + "");
  235 + } catch (Exception e) {
  236 + logger.error("removeRealSch error, " + lineCode + " -" + schDate, e);
  237 + throw e;
  238 + }
  239 + }
  240 +
  241 + /**
  242 + *
  243 + * @Title: clearRAMData
  244 + * @Description: TODO(清理内存数据)
  245 + */
  246 + public void clearRAMData(String lineCode) {
  247 + int count = 0;
  248 + List<ScheduleRealInfo> remList = new ArrayList<>();
  249 + Collection<ScheduleRealInfo> schs = nbbmScheduleMap.values();
  250 + for (ScheduleRealInfo sch : schs) {
  251 + if (sch.getXlBm().equals(lineCode))
  252 + remList.add(sch);
  253 + }
  254 +
  255 + for(ScheduleRealInfo sch : remList){
  256 + if(null != sch){
  257 + nbbmScheduleMap.remove(sch.getClZbh(), sch);
  258 + id2SchedulMap.remove(sch.getId());
  259 + count ++;
  260 + }
  261 + }
  262 +
  263 + logger.info(lineCode + "排班清理 " + count);
  264 + }
  265 +
  266 + /**
  267 + * @Title: existRealSch
  268 + * @Description: TODO(实际排班是否已存在)
  269 + */
  270 + public boolean existRealSch(String lineCode, String schDate) {
  271 + int count = schRepository.countByLineCodeAndDate(lineCode, schDate);
  272 + return count > 0;
  273 + }
  274 +
  275 + /**
  276 + * @Title: loadRealSch
  277 + * @Description: TODO(从实际排班表加载数据)
  278 + */
  279 + public List<ScheduleRealInfo> loadRealSch(String lineCode, String schDate) {
  280 + return schRepository.findByLineCodeAndDate(lineCode, schDate);
  281 + }
  282 +
  283 + /**
  284 + * @Title: loadPlanSch
  285 + * @Description: TODO(从计划排班表加载数据)
  286 + */
  287 + public List<ScheduleRealInfo> loadPlanSch(String lineCode, String schDate) {
  288 + logger.info("从计划排班表恢复排班,lineCode: " + lineCode + ", schDate: " + schDate);
  289 + List<ScheduleRealInfo> realList = new ArrayList<>();
  290 +
  291 + try {
  292 + Map<String, Object> data = new HashMap<>();
  293 +
  294 + data.put("scheduleDate_eq", fmtyyyyMMdd.parseDateTime(schDate).toDate());
  295 + data.put("xlBm_eq", lineCode);
  296 +
  297 + // 查询计划排班
  298 + List<SchedulePlanInfo> planItr = cleanSchPlanItr(schPlanService.list(data).iterator());
  299 +
  300 + // 转换为实际排班
  301 + realList = JSONArray.parseArray(JSON.toJSONString(planItr), ScheduleRealInfo.class);
  302 +
  303 + for (ScheduleRealInfo sch : realList) {
  304 + sch.setScheduleDateStr(fmtyyyyMMdd.print(sch.getScheduleDate().getTime()));
  305 + sch.setRealExecDate(sch.getScheduleDateStr());
  306 + // 计划终点时间
  307 + if (sch.getBcsj() != null) {
  308 + sch.setZdsj(fmtHHmm.print(fmtHHmm.parseMillis(sch.getFcsj()) + (sch.getBcsj() * 60 * 1000)));
  309 + sch.setLate(false);
  310 + }
  311 + //计划里程为0,设置NULL
  312 + if(sch.getJhlc() != null && sch.getJhlc() == 0)
  313 + sch.setJhlc(null);
  314 + }
  315 + } catch (Exception e) {
  316 + logger.error("", e);
  317 + }
  318 + return realList;
  319 + }
  320 +
  321 + /**
  322 + * @Title: batchSave
  323 + * @Description: TODO(批量入库)
  324 + */
  325 + private void batchSave(List<ScheduleRealInfo> list) {
  326 + // 查询数据库最大ID
  327 + Long id = schRepository.getMaxId();
  328 + if (null == id)
  329 + id = 0L;
  330 + id++;
  331 +
  332 + SimpleDateFormat sdfyyyyMMdd = new SimpleDateFormat("yyyy-MM-dd");
  333 + for (ScheduleRealInfo item : list) {
  334 + item.setSpId(item.getId());// 保留原始的计划ID
  335 + item.setId(id++);// 设置ID
  336 + item.setScheduleDateStr(sdfyyyyMMdd.format(item.getScheduleDate()));
  337 + }
58 338
59 - //车辆 ——> 当前执行班次  
60 - private static Map<String, ScheduleRealInfo> carExecutePlanMap; 339 + // 入库
  340 + new BatchSaveUtils<ScheduleRealInfo>().saveList(list, ScheduleRealInfo.class);
  341 + }
61 342
62 - // 持久化缓冲区  
63 - public static LinkedList<ScheduleRealInfo> pstBuffer; 343 + private List<SchedulePlanInfo> cleanSchPlanItr(Iterator<SchedulePlanInfo> itrab) {
  344 + List<SchedulePlanInfo> list = new ArrayList<>();
64 345
65 - // 排序器  
66 - private static ScheduleComparator.FCSJ schFCSJComparator; 346 + SchedulePlanInfo sp;
  347 + while (itrab.hasNext()) {
  348 + sp = itrab.next();
  349 + sp.setSchedulePlan(null);
  350 + list.add(sp);
  351 + }
  352 + return list;
  353 + }
  354 +
  355 + /**
  356 + *
  357 + * @Title: findByLineCode
  358 + * @Description: TODO(lineCode 获取班次)
  359 + */
  360 + public List<ScheduleRealInfo> findByLineCode(String lineCode) {
  361 + List<ScheduleRealInfo> rs = new ArrayList<>();
67 362
68 - @Autowired  
69 - LineConfigData lineConfigData; 363 + Collection<ScheduleRealInfo> schs = nbbmScheduleMap.values();
  364 + for (ScheduleRealInfo sch : schs) {
  365 + if (sch.getXlBm().equals(lineCode))
  366 + rs.add(sch);
  367 + }
  368 + return rs;
  369 + }
  370 +
  371 + /**
  372 + *
  373 + * @Title: findCarByLineCode
  374 + * @Description: TODO(线路下运营的车辆)
  375 + */
  376 + public Set<String> findCarByLineCode(String lineCode){
  377 + Set<String> rs = new HashSet<>();
  378 +
  379 + Collection<ScheduleRealInfo> schs = nbbmScheduleMap.values();
  380 + for (ScheduleRealInfo sch : schs) {
  381 + if (sch.getXlBm().equals(lineCode))
  382 + rs.add(sch.getClZbh());
  383 + }
  384 +
  385 + return rs;
  386 + }
  387 +
  388 + public List<ScheduleRealInfo> findByNbbm(String nbbm) {
  389 + return nbbmScheduleMap.get(nbbm);
  390 + }
  391 +
  392 + /**
  393 + *
  394 + * @Title: findByLineAndUpDown
  395 + * @Description: TODO(lineCode 和走向获取班次)
  396 + */
  397 + public List<ScheduleRealInfo> findByLineAndUpDown(String lineCode, Integer upDown) {
  398 + List<ScheduleRealInfo> list = findByLineCode(lineCode), rs = new ArrayList<>();
  399 +
  400 + for (ScheduleRealInfo sch : list) {
  401 + if (sch.getXlDir().equals(upDown + ""))
  402 + rs.add(sch);
  403 + }
  404 + return rs;
  405 + }
70 406
71 - @Autowired  
72 - ScheduleRealInfoRepository schRepository; 407 + public ScheduleRealInfo get(long id) {
  408 + return id2SchedulMap.get(id);
  409 + }
73 410
74 - @Autowired  
75 - SchedulePlanInfoService schPlanService; 411 + public Set<String> getSEStationList(String nbbm) {
  412 + return nbbm2SEStationMap.get(nbbm);
  413 + }
76 414
77 - @Autowired  
78 - SchAttrCalculator schAttrCalculator;  
79 -  
80 - @Autowired  
81 - SendUtils sendUtils; 415 + /**
  416 + *
  417 + * @Title: next
  418 + * @Description: TODO(下一个班次)
  419 + */
  420 + public ScheduleRealInfo next(ScheduleRealInfo sch) {
82 421
83 - @Autowired  
84 - GpsRealData gpsRealData; 422 + List<ScheduleRealInfo> list = nbbmScheduleMap.get(sch.getClZbh());
  423 +
  424 + boolean flag = false;
  425 + ScheduleRealInfo next = null;
  426 + for(ScheduleRealInfo temp : list){
  427 + if(temp.getId() == sch.getId()){
  428 + flag = true;
  429 + continue;
  430 + }
  431 + //忽略烂班
  432 + if(temp.isDestroy())
  433 + continue;
  434 +
  435 + if(flag){
  436 + next = temp;
  437 + break;
  438 + }
  439 + }
  440 + return next;
  441 + }
85 442
86 - /**  
87 - * 线路当前使用的排班的日期  
88 - */  
89 - public static Map<String, String> currSchDateMap; 443 + public void put(ScheduleRealInfo sch) {
90 444
91 - static {  
92 - nbbmScheduleMap = ArrayListMultimap.create();  
93 - id2SchedulMap = new HashMap<>();  
94 - pstBuffer = new LinkedList<>();  
95 - schFCSJComparator = new ScheduleComparator.FCSJ();  
96 - currSchDateMap = new HashMap<>();  
97 - nbbm2SEStationMap = TreeMultimap.create();  
98 - carExecutePlanMap = new HashMap<>();  
99 - }  
100 -  
101 - @Autowired  
102 - ScheduleRefreshThread scheduleRefreshThread;  
103 -  
104 - @Autowired  
105 - SchedulePstThread schedulePstThread;  
106 -  
107 - @Autowired  
108 - FirstScheduleCheckThread firstScheduleCheckThread;  
109 -  
110 - @Autowired  
111 - ScheduleLateThread scheduleLateThread;  
112 -  
113 - @Autowired  
114 - SubmitToTrafficManage submitToTrafficManage;  
115 -  
116 - @Autowired  
117 - LineConfigData lineConfigs;  
118 -  
119 - @Autowired  
120 - BasicData.BasicDataLoader dataLoader;  
121 -  
122 - @Autowired  
123 - GpsDataRecovery gpsDataRecovery;  
124 -  
125 - private static DateTimeFormatter fmtyyyyMMdd = DateTimeFormat.forPattern("yyyy-MM-dd"), fmtHHmm = DateTimeFormat.forPattern("HH:mm");  
126 -  
127 - @Override  
128 - public void run(String... arg0) throws Exception {  
129 - //加载基础数据  
130 - dataLoader.loadAllData();  
131 - //从数据库恢复排班  
132 - dataRecovery();  
133 -  
134 - //翻班线程  
135 -// Application.mainServices.scheduleWithFixedDelay(scheduleRefreshThread, 15, 240, TimeUnit.SECONDS);  
136 - //入库  
137 -// Application.mainServices.scheduleWithFixedDelay(schedulePstThread, 60, 60, TimeUnit.SECONDS);  
138 - //首班出场指令补发器  
139 -// Application.mainServices.scheduleWithFixedDelay(firstScheduleCheckThread, 30, 240, TimeUnit.SECONDS);  
140 - //班次误点扫描  
141 - Application.mainServices.scheduleWithFixedDelay(scheduleLateThread, 60, 60, TimeUnit.SECONDS);  
142 -  
143 - //每天凌晨2点20提交数据到运管处  
144 - long diff = (DateUtils.getTimestamp() + 1000 * 60 * 140) - System.currentTimeMillis();  
145 - if (diff < 0)  
146 - diff += (1000 * 60 * 60 * 24);  
147 -  
148 - logger.info(diff / 1000 / 60 + "分钟之后提交到运管处");  
149 - //Application.mainServices.scheduleWithFixedDelay(submitToTrafficManage, diff / 1000, 60 * 60 * 24, TimeUnit.SECONDS);  
150 - }  
151 -  
152 - //数据恢复  
153 - private void dataRecovery() {  
154 - GpsDataRecovery.run = true;  
155 -  
156 - Collection<LineConfig> confs = lineConfigs.getAll();  
157 - String lineCode, currSchDate;  
158 - for (LineConfig conf : confs) {  
159 - lineCode = conf.getLine().getLineCode();  
160 - currSchDate = calcSchDate(lineCode);  
161 - //加载班次数据  
162 - reloadSch(lineCode, currSchDate, false);  
163 - }  
164 -  
165 - //恢复gps数据  
166 - gpsDataRecovery.recovery();  
167 - }  
168 -  
169 - public Map<String, String> getCurrSchDate() {  
170 - return currSchDateMap;  
171 - }  
172 -  
173 - /**  
174 - * @Title: calcSchDateB  
175 - * @Description: TODO(计算线路当前应该使用的排班日期)  
176 - */  
177 - public String calcSchDate(String lineCode) {  
178 - LineConfig conf = lineConfigData.get(lineCode);  
179 - long ct = System.currentTimeMillis();  
180 -  
181 - String schDate = fmtyyyyMMdd.print(ct);  
182 - // 小于当天起始运营时间,则取前一天的排班  
183 - if (ct < conf.getCurrStartTime())  
184 - schDate = DateUtils.subtractDay(schDate, 1);  
185 -  
186 - return schDate;  
187 - }  
188 -  
189 - /**  
190 - * @param @param lineCode 线路编码  
191 - * @param @param schDate 班次日期 yyyy-MM-dd  
192 - * @param @param forcePlan 强制从计划调度重新抓取  
193 - * @Title: reloadSch  
194 - * @Title: reloadSch  
195 - * @Description: TODO(重新载入排班)  
196 - */  
197 - public int reloadSch(String lineCode, String schDate, boolean forcePlan) {  
198 - try {  
199 - List<ScheduleRealInfo> list;  
200 -  
201 - if (forcePlan)  
202 - removeRealSch(lineCode, schDate);  
203 - else  
204 - clearRAMData(lineCode);  
205 -  
206 - if (existRealSch(lineCode, schDate))  
207 - list = loadRealSch(lineCode, schDate);// 从实际排班表加载  
208 - else {  
209 - list = loadPlanSch(lineCode, schDate);// 从计划排班表加载  
210 - // 写入数据库  
211 - batchSave(list);  
212 - }  
213 -  
214 - //更新线路和班次日期对照  
215 - currSchDateMap.put(lineCode, schDate);  
216 - //添加到缓存  
217 - putAll(list);  
218 -  
219 - Set<String> cars = searchAllCars(list);  
220 - for (String nbbm : cars) {  
221 - //计算“起点站应到”时间  
222 - schAttrCalculator.calcQdzTimePlan(nbbmScheduleMap.get(nbbm));  
223 - //车辆 ——> 要执行的班次对照  
224 - reCalcExecPlan(nbbm);  
225 - }  
226 -  
227 - //是否是出站即出场  
228 - LineConfig conf = lineConfigData.get(lineCode);  
229 - if (conf.getOutConfig() == 2) {  
230 - for (String nbbm : cars)  
231 - schAttrCalculator.connectOutSchedule(nbbmScheduleMap.get(nbbm));  
232 - }  
233 -  
234 - // 页面 翻班通知  
235 - sendUtils.shiftSchedule(lineCode);  
236 - } catch (Exception e) {  
237 - logger.error("", e);  
238 - return -1;  
239 - }  
240 -  
241 - return 0;  
242 - }  
243 -  
244 - /**  
245 - * @Title: searchAllCars  
246 - * @Description: TODO(搜索班次集合中的车辆)  
247 - */  
248 - private Set<String> searchAllCars(List<ScheduleRealInfo> list) {  
249 - Set<String> cars = new HashSet<>();  
250 - for (ScheduleRealInfo sch : list)  
251 - cars.add(sch.getClZbh());  
252 -  
253 - return cars;  
254 - }  
255 -  
256 - private void putAll(List<ScheduleRealInfo> list) {  
257 - for (ScheduleRealInfo sch : list)  
258 - put(sch);  
259 - }  
260 -  
261 - /**  
262 - * @param @param lineCode 线路编码  
263 - * @param @param schDate 班次日期 yyyy-MM-dd  
264 - * @Title: removeRealSch  
265 - * @Description: TODO(清除实际排班,包括数据库和内存数据)  
266 - */  
267 - public void removeRealSch(String lineCode, String schDate) throws Exception {  
268 - try {  
269 - // 清理数据库数据  
270 - schRepository.deleteByLineCodeAndDate(lineCode + "", schDate);  
271 -  
272 - // 清理内存数据  
273 - clearRAMData(lineCode + "");  
274 - } catch (Exception e) {  
275 - logger.error("removeRealSch error, " + lineCode + " -" + schDate, e);  
276 - throw e;  
277 - }  
278 - }  
279 -  
280 - /**  
281 - * @Title: clearRAMData  
282 - * @Description: TODO(清理内存数据)  
283 - */  
284 - public void clearRAMData(String lineCode) {  
285 - int count = 0;  
286 - List<ScheduleRealInfo> remList = new ArrayList<>();  
287 - Collection<ScheduleRealInfo> schs = nbbmScheduleMap.values();  
288 - for (ScheduleRealInfo sch : schs) {  
289 - if (sch.getXlBm().equals(lineCode))  
290 - remList.add(sch);  
291 - }  
292 -  
293 - for (ScheduleRealInfo sch : remList) {  
294 - if (null != sch) {  
295 - nbbmScheduleMap.remove(sch.getClZbh(), sch);  
296 - id2SchedulMap.remove(sch.getId());  
297 - count++;  
298 - }  
299 - }  
300 -  
301 - logger.info(lineCode + "排班清理 " + count);  
302 - }  
303 -  
304 - /**  
305 - * @Title: existRealSch  
306 - * @Description: TODO(实际排班是否已存在)  
307 - */  
308 - public boolean existRealSch(String lineCode, String schDate) {  
309 - int count = schRepository.countByLineCodeAndDate(lineCode, schDate);  
310 - return count > 0;  
311 - }  
312 -  
313 - /**  
314 - * @Title: loadRealSch  
315 - * @Description: TODO(从实际排班表加载数据)  
316 - */  
317 - public List<ScheduleRealInfo> loadRealSch(String lineCode, String schDate) {  
318 - return schRepository.findByLineCodeAndDate(lineCode, schDate);  
319 - }  
320 -  
321 - /**  
322 - * @Title: loadPlanSch  
323 - * @Description: TODO(从计划排班表加载数据)  
324 - */  
325 - public List<ScheduleRealInfo> loadPlanSch(String lineCode, String schDate) {  
326 - logger.info("从计划排班表恢复排班,lineCode: " + lineCode + ", schDate: " + schDate);  
327 - List<ScheduleRealInfo> realList = new ArrayList<>();  
328 -  
329 - try {  
330 - Map<String, Object> data = new HashMap<>();  
331 -  
332 - data.put("scheduleDate_eq", fmtyyyyMMdd.parseDateTime(schDate).toDate());  
333 - data.put("xlBm_eq", lineCode);  
334 -  
335 - // 查询计划排班  
336 - List<SchedulePlanInfo> planItr = cleanSchPlanItr(schPlanService.list(data).iterator());  
337 -  
338 - // 转换为实际排班  
339 - realList = JSONArray.parseArray(JSON.toJSONString(planItr), ScheduleRealInfo.class);  
340 -  
341 - SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");  
342 - String fcsj;  
343 - for (ScheduleRealInfo sch : realList) {  
344 - sch.setScheduleDateStr(fmtyyyyMMdd.print(sch.getScheduleDate().getTime()));  
345 - sch.setRealExecDate(sch.getScheduleDateStr());  
346 -  
347 - if (StringUtils.isEmpty(sch.getFcsj()))  
348 - sch.setFcsj("00:00");  
349 -  
350 - fcsj = sch.getFcsj().trim();  
351 - //处理一下发车时间格式没有:号的问题  
352 - if (fcsj.indexOf(":") == -1 && fcsj.length() >= 4) {  
353 - sch.setFcsj(fcsj.substring(0, 2) + ":" + fcsj.substring(2, 4));  
354 - }  
355 -  
356 - try {  
357 - sdf.parse(sch.getFcsj());  
358 - } catch (ParseException e) {  
359 - //发车时间仍然校验不过的,直接写成00:00  
360 - sch.setFcsj("00:00");  
361 - }  
362 - sch.setDfsj(sch.getFcsj());  
363 -  
364 - // 计划终点时间  
365 - if (sch.getBcsj() != null) {  
366 - sch.setZdsj(fmtHHmm.print(fmtHHmm.parseMillis(sch.getFcsj()) + (sch.getBcsj() * 60 * 1000)));  
367 - sch.setLate(false);  
368 - }  
369 - //计划里程为0,设置NULL  
370 - if (sch.getJhlc() != null && sch.getJhlc() == 0)  
371 - sch.setJhlc(null);  
372 - }  
373 - } catch (Exception e) {  
374 - logger.error("", e);  
375 - }  
376 - return realList;  
377 - }  
378 -  
379 - /**  
380 - * @Title: batchSave  
381 - * @Description: TODO(批量入库)  
382 - */  
383 - private void batchSave(List<ScheduleRealInfo> list) {  
384 - // 查询数据库最大ID  
385 - Long id = schRepository.getMaxId();  
386 - if (null == id)  
387 - id = 0L;  
388 - id++;  
389 -  
390 - SimpleDateFormat sdfyyyyMMdd = new SimpleDateFormat("yyyy-MM-dd");  
391 - for (ScheduleRealInfo item : list) {  
392 - item.setSpId(item.getId());// 保留原始的计划ID  
393 - item.setId(id++);// 设置ID  
394 - item.setScheduleDateStr(sdfyyyyMMdd.format(item.getScheduleDate()));  
395 - }  
396 -  
397 - // 入库  
398 - new BatchSaveUtils<ScheduleRealInfo>().saveList(list, ScheduleRealInfo.class);  
399 - }  
400 -  
401 - private List<SchedulePlanInfo> cleanSchPlanItr(Iterator<SchedulePlanInfo> itrab) {  
402 - List<SchedulePlanInfo> list = new ArrayList<>();  
403 -  
404 - SchedulePlanInfo sp;  
405 - while (itrab.hasNext()) {  
406 - sp = itrab.next();  
407 - sp.setSchedulePlan(null);  
408 - list.add(sp);  
409 - }  
410 - return list;  
411 - }  
412 -  
413 - /**  
414 - * @Title: findByLineCode  
415 - * @Description: TODO(lineCode 获取班次)  
416 - */  
417 - public List<ScheduleRealInfo> findByLineCode(String lineCode) {  
418 - List<ScheduleRealInfo> rs = new ArrayList<>();  
419 -  
420 - Collection<ScheduleRealInfo> schs = nbbmScheduleMap.values();  
421 - for (ScheduleRealInfo sch : schs) {  
422 - if (sch.getXlBm().equals(lineCode))  
423 - rs.add(sch);  
424 - }  
425 - return rs;  
426 - }  
427 -  
428 - /**  
429 - * @Title: findCarByLineCode  
430 - * @Description: TODO(线路下运营的车辆)  
431 - */  
432 - public Set<String> findCarByLineCode(String lineCode) {  
433 - Set<String> rs = new HashSet<>();  
434 -  
435 - Collection<ScheduleRealInfo> schs = nbbmScheduleMap.values();  
436 - for (ScheduleRealInfo sch : schs) {  
437 - if (sch.getXlBm().equals(lineCode))  
438 - rs.add(sch.getClZbh());  
439 - }  
440 -  
441 - return rs;  
442 - }  
443 -  
444 - public List<ScheduleRealInfo> findByNbbm(String nbbm) {  
445 - return nbbmScheduleMap.get(nbbm);  
446 - }  
447 -  
448 - /**  
449 - * @Title: findByLineAndUpDown  
450 - * @Description: TODO(lineCode 和走向获取班次)  
451 - */  
452 - public List<ScheduleRealInfo> findByLineAndUpDown(String lineCode, Integer upDown) {  
453 - List<ScheduleRealInfo> list = findByLineCode(lineCode), rs = new ArrayList<>();  
454 -  
455 - for (ScheduleRealInfo sch : list) {  
456 - if (sch.getXlDir().equals(upDown + ""))  
457 - rs.add(sch);  
458 - }  
459 - return rs;  
460 - }  
461 -  
462 - public ScheduleRealInfo get(long id) {  
463 - return id2SchedulMap.get(id);  
464 - }  
465 -  
466 - public Set<String> getSEStationList(String nbbm) {  
467 - return nbbm2SEStationMap.get(nbbm);  
468 - }  
469 -  
470 - /**  
471 - * @Title: next  
472 - * @Description: TODO(下一个班次)  
473 - */  
474 - public ScheduleRealInfo next(ScheduleRealInfo sch) {  
475 -  
476 - List<ScheduleRealInfo> list = nbbmScheduleMap.get(sch.getClZbh());  
477 - int outConfig = -1;  
478 - LineConfig config = lineConfigData.get(sch.getXlBm());  
479 - if (config != null)  
480 - outConfig = config.getOutConfig();  
481 -  
482 - boolean flag = false;  
483 - ScheduleRealInfo next = null;  
484 - for (ScheduleRealInfo temp : list) {  
485 - if (temp.getId() == sch.getId()) {  
486 - flag = true;  
487 - continue;  
488 - }  
489 - //忽略烂班  
490 - if (temp.isDestroy())  
491 - continue;  
492 -  
493 - //出站既出场,忽略出场班次  
494 - if (outConfig == 2 && temp.getBcType().equals("out"))  
495 - continue;  
496 -  
497 - if (flag) {  
498 - next = temp;  
499 - break;  
500 - }  
501 - }  
502 - return next;  
503 - }  
504 -  
505 - /**  
506 - * 上一个班次  
507 - *  
508 - * @param sch  
509 - * @return  
510 - */  
511 - public ScheduleRealInfo prev(ScheduleRealInfo sch) {  
512 - List<ScheduleRealInfo> list = nbbmScheduleMap.get(sch.getClZbh());  
513 -  
514 - //boolean flag = false;  
515 - ScheduleRealInfo prev = null;  
516 - int size = list.size();  
517 -  
518 - for (int i = 0; i < size; i++) {  
519 - if (list.get(i).isDestroy())  
520 - continue;  
521 -  
522 - if (list.get(i).getId().equals(sch.getId())) {  
523 - return prev;  
524 - }  
525 - prev = list.get(i);  
526 - }  
527 - return prev;  
528 - }  
529 -  
530 - public void put(ScheduleRealInfo sch) {  
531 - schAttrCalculator  
532 - .calcRealDate(sch)  
533 - .calcAllTimeByFcsj(sch);  
534 -  
535 - String nbbm = sch.getClZbh();  
536 - nbbmScheduleMap.put(nbbm, sch);  
537 - nbbm2SEStationMap.put(nbbm, sch.getQdzCode());  
538 - nbbm2SEStationMap.put(nbbm, sch.getZdzCode());  
539 -  
540 - //主键索引  
541 - id2SchedulMap.put(sch.getId(), sch);  
542 - //跨24点的,再save一次  
543 - if (!sch.getRealExecDate().equals(sch.getScheduleDateStr()))  
544 - save(sch);  
545 - }  
546 -  
547 - public void delete(ScheduleRealInfo sch) {  
548 - //ScheduleRealInfo sch = id2SchedulMap.get(id);  
549 - if (!sch.isSflj())  
550 - return;  
551 -  
552 - nbbmScheduleMap.remove(sch.getClZbh(), sch);  
553 - id2SchedulMap.remove(sch.getId());  
554 - //return sch;  
555 - } 445 + schAttrCalculator
  446 + .calcRealDate(sch)
  447 + .calcAllTimeByFcsj(sch);
556 448
  449 + String nbbm = sch.getClZbh();
  450 + nbbmScheduleMap.put(nbbm, sch);
  451 + nbbm2SEStationMap.put(nbbm, sch.getQdzCode());
  452 + nbbm2SEStationMap.put(nbbm, sch.getZdzCode());
  453 +
  454 + //主键索引
  455 + id2SchedulMap.put(sch.getId(), sch);
  456 + }
  457 +
  458 + public void delete(ScheduleRealInfo sch) {
  459 + //ScheduleRealInfo sch = id2SchedulMap.get(id);
  460 + if(!sch.isSflj())
  461 + return;
  462 +
  463 + nbbmScheduleMap.remove(sch.getClZbh(), sch);
  464 + id2SchedulMap.remove(sch.getId());
  465 + //return sch;
  466 + }
  467 +
557 // public void calcQdzTimePlan(String nbbm){ 468 // public void calcQdzTimePlan(String nbbm){
558 // schAttrCalculator.calcQdzTimePlan(nbbmScheduleMap.get(nbbm)); 469 // schAttrCalculator.calcQdzTimePlan(nbbmScheduleMap.get(nbbm));
559 // } 470 // }
560 -  
561 - public List<ScheduleRealInfo> updateQdzTimePlan(String nbbm) {  
562 - return schAttrCalculator.updateQdzTimePlan(nbbmScheduleMap.get(nbbm));  
563 - }  
564 -  
565 - /**  
566 - *  
567 - * @Title: nextAll  
568 - * @Description: TODO(之后的所有班次)  
569 - */ 471 +
  472 + public List<ScheduleRealInfo> updateQdzTimePlan(String nbbm){
  473 + return schAttrCalculator.updateQdzTimePlan(nbbmScheduleMap.get(nbbm));
  474 + }
  475 +
  476 + /**
  477 + *
  478 + * @Title: nextAll
  479 + * @Description: TODO(之后的所有班次)
  480 + */
570 /* public List<ScheduleRealInfo> nextAll(ScheduleRealInfo sch) { 481 /* public List<ScheduleRealInfo> nextAll(ScheduleRealInfo sch) {
571 - List<ScheduleRealInfo> list = nbbmScheduleMap.get(sch.getClZbh()); 482 + List<ScheduleRealInfo> list = nbbmScheduleMap.get(sch.getClZbh());
572 // 排序 483 // 排序
573 Collections.sort(list, schFCSJComparator); 484 Collections.sort(list, schFCSJComparator);
574 485
@@ -583,229 +494,181 @@ public class DayOfSchedule implements CommandLineRunner { @@ -583,229 +494,181 @@ public class DayOfSchedule implements CommandLineRunner {
583 return rs; 494 return rs;
584 }*/ 495 }*/
585 496
586 - /**  
587 - * @Title: doneSum  
588 - * @Description: TODO(已完成班次总数)  
589 - */  
590 - public int doneSum(String clZbh) {  
591 - List<ScheduleRealInfo> list = nbbmScheduleMap.get(clZbh);  
592 - int rs = 0;  
593 -  
594 - for (ScheduleRealInfo sch : list) {  
595 - if (sch.getStatus() == 2 && !sch.isDestroy())  
596 - rs++;  
597 - }  
598 - return rs;  
599 - }  
600 -  
601 - /**  
602 - * @Title: prveNotExecNum  
603 - * @Description: TODO(班次之前未执行班次数量)  
604 - */  
605 - public int prveNotExecNum(ScheduleRealInfo sch) {  
606 - int n = 0;  
607 - List<ScheduleRealInfo> list = nbbmScheduleMap.get(sch.getClZbh());  
608 - for (ScheduleRealInfo s : list) {  
609 - if (s.getFcsjActual() == null && !s.isDestroy())  
610 - n++;  
611 -  
612 - if (s.getId().equals(sch.getId()))  
613 - break;  
614 - }  
615 - return n;  
616 - }  
617 -  
618 - /**  
619 - * @Title: validEndTime  
620 - * @Description: TODO(是否是有效的到达时间)  
621 - */  
622 - public boolean validEndTime(ScheduleRealInfo sch, Long ts) {  
623 - if (sch.getFcsjActualTime() != null && sch.getFcsjActualTime() > ts)  
624 - return false;  
625 -  
626 - return validTime(sch, ts);  
627 - }  
628 -  
629 - /**  
630 - * @Title: validStartTime  
631 - * @Description: TODO(是否是合适的发车时间)  
632 - */  
633 - public boolean validStartTime(ScheduleRealInfo sch, Long ts) {  
634 - if (sch.getZdsjActualTime() != null && sch.getZdsjActualTime() < ts)  
635 - return false;  
636 -  
637 - return validTime(sch, ts);  
638 - }  
639 -  
640 - public boolean validTime(ScheduleRealInfo sch, Long ts) {  
641 - List<ScheduleRealInfo> list = nbbmScheduleMap.get(sch.getClZbh());  
642 - int ci = list.indexOf(sch);  
643 - ScheduleRealInfo prve, next;  
644 - if (ci > 0) {  
645 - //之前班次实际时间不能大于该时间  
646 - for (int i = ci - 1; i >= 0; i--) {  
647 - prve = list.get(i);  
648 - if (prve.getZdsjActualTime() != null && prve.getZdsjActualTime() > ts)  
649 - return false;  
650 -  
651 - if (prve.getFcsjActualTime() != null && prve.getFcsjActualTime() > ts)  
652 - return false;  
653 - }  
654 - }  
655 -  
656 - if (ci < list.size() - 1) {  
657 - //之后班次实际时间不能小于该时间  
658 - for (int i = ci + 1; i < list.size(); i++) {  
659 - next = list.get(i);  
660 - if (next.getFcsjActualTime() != null && next.getFcsjActualTime() < ts)  
661 - return false;  
662 -  
663 - if (next.getZdsjActualTime() != null && next.getZdsjActualTime() < ts)  
664 - return false;  
665 - }  
666 - }  
667 - return true;  
668 - }  
669 -  
670 - public void save(ScheduleRealInfo sch) {  
671 - //schRepository.save(sch);  
672 - pstBuffer.add(sch);  
673 - }  
674 -  
675 -  
676 - /**  
677 - * @Title: nextByBcType  
678 - * @Description: TODO(获取下一个指定班次类型的班次)  
679 - */  
680 - public ScheduleRealInfo nextByBcType(String nbbm, String bcType) {  
681 - List<ScheduleRealInfo> list = findByBcType(nbbm, bcType);  
682 -  
683 - Collections.sort(list, schFCSJComparator);  
684 - ScheduleRealInfo sch = null;  
685 - for (ScheduleRealInfo temp : list) {  
686 - if (temp.getFcsjActual() == null)  
687 - sch = temp;  
688 - }  
689 -  
690 - return sch;  
691 - }  
692 -  
693 - public List<ScheduleRealInfo> findByBcType(String nbbm, String bcType) {  
694 - List<ScheduleRealInfo> all = nbbmScheduleMap.get(nbbm), outList = new ArrayList<>();  
695 -  
696 - for (ScheduleRealInfo sch : all) {  
697 - if (sch.getBcType().equals(bcType))  
698 - outList.add(sch);  
699 - }  
700 - return outList;  
701 - }  
702 -  
703 - public Set<String> allCar() {  
704 - return nbbmScheduleMap.keySet();  
705 - }  
706 -  
707 - public Collection<ScheduleRealInfo> findAll() {  
708 - return nbbmScheduleMap.values();  
709 - }  
710 -  
711 - public void addExecPlan(ScheduleRealInfo sch) {  
712 - if(sch != null)  
713 - carExecutePlanMap.put(sch.getClZbh(), sch);  
714 - }  
715 -  
716 - public void removeExecPlan(String clzbh) {  
717 - carExecutePlanMap.remove(clzbh);  
718 - }  
719 -  
720 - public Map<String, ScheduleRealInfo> execPlanMap() {  
721 - return carExecutePlanMap;  
722 - }  
723 -  
724 - /**  
725 - * 车辆当前执行的班次  
726 - *  
727 - * @param nbbm  
728 - * @return  
729 - */  
730 - public ScheduleRealInfo executeCurr(String nbbm) {  
731 - return carExecutePlanMap.get(nbbm);  
732 - }  
733 -  
734 - /**  
735 - * @param @param sch  
736 - * @param @param newClZbh 新的车辆自编号  
737 - * @Title: changeCar  
738 - * @Description: TODO(班次换车) 返回有更新的班次  
739 - */  
740 - public List<ScheduleRealInfo> changeCar(ScheduleRealInfo sch, String newClZbh) {  
741 - List<ScheduleRealInfo> ups = new ArrayList<>();  
742 - String oldClzbh = sch.getClZbh();  
743 - if (oldClzbh.equals(newClZbh))  
744 - return ups;  
745 -  
746 -  
747 - //变更相关映射信息  
748 - nbbmScheduleMap.remove(sch.getClZbh(), sch);  
749 -  
750 - sch.setClZbh(newClZbh);  
751 - nbbmScheduleMap.put(newClZbh, sch);  
752 - nbbm2SEStationMap.put(newClZbh, sch.getQdzCode());  
753 - nbbm2SEStationMap.put(newClZbh, sch.getZdzCode());  
754 -  
755 - //重新计算班次应到时间  
756 - ups.addAll(updateQdzTimePlan(oldClzbh));  
757 - ups.addAll(updateQdzTimePlan(newClZbh));  
758 -  
759 - //重新计算车辆当前执行班次  
760 - reCalcExecPlan(newClZbh);  
761 - reCalcExecPlan(sch.getClZbh());  
762 - return ups;  
763 - }  
764 -  
765 - public void reCalcExecPlan(String nbbm){  
766 - carExecutePlanMap.put(nbbm, schAttrCalculator.calcCurrentExecSch(nbbmScheduleMap.get(nbbm)));  
767 - }  
768 -  
769 - /**  
770 - * 是否在执行首班出场  
771 - * @param nbbm  
772 - * @return  
773 - */  
774 - public boolean isExecFirstOut(String nbbm, long time){  
775 - try {  
776 - List<ScheduleRealInfo> list = nbbmScheduleMap.get(nbbm);  
777 - ScheduleRealInfo second = list.get(2),  
778 - first = executeCurr(nbbm);  
779 -  
780 - if(first.getBcType().equals("out")  
781 - && first.getDfsjT() < second.getDfsjT()  
782 - && doneSum(nbbm) == 0 && second.getDfsjT() > time)  
783 - return true;  
784 - } catch (Exception e) {  
785 - logger.error("", e);  
786 - }  
787 -  
788 - return false;  
789 - }  
790 -  
791 - /**  
792 - * 获取班次的计划停站时间  
793 - * @param sch  
794 - * @return  
795 -  
796 - public int stopTimePlan(Object task) {  
797 -  
798 - ScheduleRealInfo sch = prev((ScheduleRealInfo) task);  
799 -  
800 - sch.getzdsj  
801 - return -1;  
802 - }*/  
803 -  
804 - /**  
805 - *  
806 - * @Title: linkToSchPlan  
807 - * @Description: TODO(车辆关联到班次)  
808 - */ 497 + /**
  498 + *
  499 + * @Title: doneSum
  500 + * @Description: TODO(已完成班次总数)
  501 + */
  502 + public int doneSum(String clZbh) {
  503 + List<ScheduleRealInfo> list = nbbmScheduleMap.get(clZbh);
  504 + int rs = 0;
  505 +
  506 + for(ScheduleRealInfo sch : list){
  507 + if(sch.getStatus() == 2 && !sch.isDestroy())
  508 + rs ++;
  509 + }
  510 + return rs;
  511 + }
  512 +
  513 + /**
  514 + *
  515 + * @Title: prveNotExecNum
  516 + * @Description: TODO(班次之前未执行班次数量)
  517 + */
  518 + public int prveNotExecNum(ScheduleRealInfo sch){
  519 + int n = 0;
  520 + List<ScheduleRealInfo> list = nbbmScheduleMap.get(sch.getClZbh());
  521 + for(ScheduleRealInfo s : list){
  522 + if(s.getFcsjActual() == null && !s.isDestroy())
  523 + n ++;
  524 +
  525 + if(s.getId().equals(sch.getId()))
  526 + break;
  527 + }
  528 + return n;
  529 + }
  530 +
  531 + /**
  532 + *
  533 + * @Title: validEndTime
  534 + * @Description: TODO(是否是有效的到达时间)
  535 + */
  536 + public boolean validEndTime(ScheduleRealInfo sch, Long ts) {
  537 + if(sch.getFcsjActualTime() != null && sch.getFcsjActualTime() > ts)
  538 + return false;
  539 +
  540 + return validTime(sch, ts);
  541 + }
  542 +
  543 + /**
  544 + *
  545 + * @Title: validStartTime
  546 + * @Description: TODO(是否是合适的发车时间)
  547 + */
  548 + public boolean validStartTime(ScheduleRealInfo sch, Long ts) {
  549 + if(sch.getZdsjActualTime() != null && sch.getZdsjActualTime() < ts)
  550 + return false;
  551 +
  552 + return validTime(sch, ts);
  553 + }
  554 +
  555 + public boolean validTime(ScheduleRealInfo sch, Long ts){
  556 + List<ScheduleRealInfo> list = nbbmScheduleMap.get(sch.getClZbh());
  557 + int ci = list.indexOf(sch);
  558 + ScheduleRealInfo prve, next;
  559 + if(ci > 0){
  560 + //之前班次实际时间不能大于该时间
  561 + for(int i = ci - 1; i >= 0; i --){
  562 + prve = list.get(i);
  563 + if(prve.getZdsjActualTime() != null && prve.getZdsjActualTime() > ts )
  564 + return false;
  565 +
  566 + if(prve.getFcsjActualTime() != null && prve.getFcsjActualTime() > ts)
  567 + return false;
  568 + }
  569 + }
  570 +
  571 + if(ci < list.size() - 1){
  572 + //之后班次实际时间不能小于该时间
  573 + for(int i = ci + 1; i < list.size(); i ++){
  574 + next = list.get(i);
  575 + if(next.getFcsjActualTime() != null && next.getFcsjActualTime() < ts)
  576 + return false;
  577 +
  578 + if(next.getZdsjActualTime() != null && next.getZdsjActualTime() < ts)
  579 + return false;
  580 + }
  581 + }
  582 + return true;
  583 + }
  584 +
  585 + public void save(ScheduleRealInfo sch){
  586 + //schRepository.save(sch);
  587 + pstBuffer.add(sch);
  588 + }
  589 +
  590 +
  591 + /**
  592 + *
  593 + * @Title: nextByBcType
  594 + * @Description: TODO(获取下一个指定班次类型的班次)
  595 + */
  596 + public ScheduleRealInfo nextByBcType(String nbbm, String bcType){
  597 + List<ScheduleRealInfo> list = findByBcType(nbbm, bcType);
  598 +
  599 + Collections.sort(list, schFCSJComparator);
  600 + ScheduleRealInfo sch = null;
  601 + for(ScheduleRealInfo temp : list){
  602 + if(temp.getFcsjActual() == null)
  603 + sch = temp;
  604 + }
  605 +
  606 + return sch;
  607 + }
  608 +
  609 + public List<ScheduleRealInfo> findByBcType(String nbbm, String bcType){
  610 + List<ScheduleRealInfo> all = nbbmScheduleMap.get(nbbm)
  611 + ,outList = new ArrayList<>();
  612 +
  613 + for(ScheduleRealInfo sch : all){
  614 + if(sch.getBcType().equals(bcType))
  615 + outList.add(sch);
  616 + }
  617 + return outList;
  618 + }
  619 +
  620 + public Set<String> allCar(){
  621 + return nbbmScheduleMap.keySet();
  622 + }
  623 +
  624 + public Collection<ScheduleRealInfo> findAll(){
  625 + return nbbmScheduleMap.values();
  626 + }
  627 +
  628 + public void addExecPlan(ScheduleRealInfo sch){
  629 + carExecutePlanMap.put(sch.getClZbh(), sch);
  630 + }
  631 +
  632 + public void removeExecPlan(String clzbh){
  633 + carExecutePlanMap.remove(clzbh);
  634 + }
  635 +
  636 + public Map<String, ScheduleRealInfo> execPlamMap(){
  637 + return carExecutePlanMap;
  638 + }
  639 +
  640 + /**
  641 + * @Title: changeCar
  642 + * @Description: TODO(班次换车) 返回有更新的班次
  643 + * @param @param sch
  644 + * @param @param newClZbh 新的车辆自编号
  645 + */
  646 + public List<ScheduleRealInfo> changeCar(ScheduleRealInfo sch , String newClZbh){
  647 + List<ScheduleRealInfo> ups = new ArrayList<>();
  648 + String oldClzbh = sch.getClZbh();
  649 + if(oldClzbh.equals(newClZbh))
  650 + return ups;
  651 +
  652 +
  653 + //变更相关映射信息
  654 + nbbmScheduleMap.remove(sch.getClZbh(), sch);
  655 +
  656 + sch.setClZbh(newClZbh);
  657 + nbbmScheduleMap.put(newClZbh, sch);
  658 + nbbm2SEStationMap.put(newClZbh, sch.getQdzCode());
  659 + nbbm2SEStationMap.put(newClZbh, sch.getZdzCode());
  660 +
  661 + //重新计算班次应到时间
  662 + ups.addAll(updateQdzTimePlan(oldClzbh));
  663 + ups.addAll(updateQdzTimePlan(newClZbh));
  664 + return ups;
  665 + }
  666 +
  667 + /**
  668 + *
  669 + * @Title: linkToSchPlan
  670 + * @Description: TODO(车辆关联到班次)
  671 + */
809 /* public void linkToSchPlan(String nbbm) { 672 /* public void linkToSchPlan(String nbbm) {
810 //当前GPS状态 673 //当前GPS状态
811 GpsEntity gps = gpsRealData.get(BasicData.deviceId2NbbmMap.inverse().get(nbbm)); 674 GpsEntity gps = gpsRealData.get(BasicData.deviceId2NbbmMap.inverse().get(nbbm));