Commit 6e47d2857e502a16b360ba489408ec2fee59d742

Authored by 游瑞烽
2 parents 019440d0 88c8dc71

Merge branch 'pudong' of 192.168.168.201:panzhaov5/bsth_control into pudong

src/main/java/com/bsth/controller/report/CardIsingningController.java 0 → 100644
  1 +package com.bsth.controller.report;
  2 +
  3 +
  4 +import com.bsth.entity.card_signing.CardSigning;
  5 +import com.bsth.service.report.CardSigningService;
  6 +import org.springframework.beans.factory.annotation.Autowired;
  7 +import org.springframework.web.bind.annotation.*;
  8 +
  9 +import java.util.List;
  10 +import java.util.Map;
  11 +
  12 +@RestController
  13 +@RequestMapping("CardSigning")
  14 +public class CardIsingningController {
  15 + @Autowired
  16 + CardSigningService cardSigningService;
  17 +
  18 + //线路插卡率列表
  19 + @RequestMapping(value = "/cardList",method = RequestMethod.GET)
  20 + public List<CardSigning> sheetList(@RequestParam Map<String, Object> map){
  21 + List<CardSigning> list= cardSigningService.cardList(map);
  22 + return list;
  23 + }
  24 +
  25 + //线路插卡率 线路详细列表第二级
  26 + @RequestMapping(value = "/calcListSheet",method = RequestMethod.GET)
  27 + public List<CardSigning> calcListSheet(@RequestParam Map<String, Object> map){
  28 + List<CardSigning> list= cardSigningService.calcListSheet(map);
  29 + return list;
  30 + }
  31 +
  32 + //线路插卡率 线路详细列表第二级
  33 + @RequestMapping(value = "/calcSheet",method = RequestMethod.GET)
  34 + public List<CardSigning> calcSheet(@RequestParam Map<String, Object> map){
  35 + List<CardSigning> list= cardSigningService.calcSheet(map);
  36 + return list;
  37 + }
  38 +
  39 +
  40 +
  41 +
  42 +}
... ...
src/main/java/com/bsth/data/gpsdata_v2/rfid/handle/RfidDataHandler.java
... ... @@ -33,7 +33,7 @@ public class RfidDataHandler {
33 33  
34 34 private final static Logger logger = LoggerFactory.getLogger(RfidDataHandler.class);
35 35  
36   - private Map<String, RfidInfo> nbbm2rfid = new ConcurrentHashMap<>();
  36 + private static Map<String, RfidInfo> nbbm2rfid = new ConcurrentHashMap<>();
37 37  
38 38 /**
39 39 *
... ... @@ -55,17 +55,18 @@ public class RfidDataHandler {
55 55 if (ri.getEmployeeCard() != null) {
56 56 state |= 2;
57 57 }
58   - if (scheduleRealInfo.getRfidState() != state) {
59   - if ((state & 1) == 1) {
60   - System.out.println("aaa");
61   - }
  58 + if (scheduleRealInfo.getRfidState() < state) {
62 59 scheduleRealInfo.setRfidState(state);
63 60 sendUtils.sendRfid(scheduleRealInfo);
64 61 }
65 62 }
66 63 }
67 64  
68   - checkValid();
  65 + //checkValid();
  66 + }
  67 +
  68 + public static void resetRfid(String nbbm) {
  69 + nbbm2rfid.remove(nbbm);
69 70 }
70 71  
71 72 /**
... ...
src/main/java/com/bsth/data/schedule/DayOfSchedule.java
1   -package com.bsth.data.schedule;
2   -
3   -import com.alibaba.fastjson.JSON;
4   -import com.alibaba.fastjson.JSONArray;
5   -import com.bsth.common.Constants;
6   -import com.bsth.common.ResponseCode;
7   -import com.bsth.data.LineConfigData;
8   -import com.bsth.data.gpsdata_v2.GpsRealData;
9   -import com.bsth.data.gpsdata_v2.utils.GpsDataRecovery;
10   -import com.bsth.data.schedule.f_a_l.FirstAndLastHandler;
11   -import com.bsth.entity.realcontrol.LineConfig;
12   -import com.bsth.entity.realcontrol.ScheduleRealInfo;
13   -import com.bsth.entity.report.RepairReport;
14   -import com.bsth.entity.schedule.SchedulePlanInfo;
15   -import com.bsth.repository.realcontrol.ScheduleRealInfoRepository;
16   -import com.bsth.service.schedule.SchedulePlanInfoService;
17   -import com.bsth.websocket.handler.SendUtils;
18   -import com.google.common.collect.ArrayListMultimap;
19   -import com.google.common.collect.HashMultimap;
20   -import com.google.common.collect.ListMultimap;
21   -import com.google.common.collect.Multimaps;
22   -import org.apache.commons.lang3.StringUtils;
23   -import org.joda.time.format.DateTimeFormat;
24   -import org.joda.time.format.DateTimeFormatter;
25   -import org.slf4j.Logger;
26   -import org.slf4j.LoggerFactory;
27   -import org.springframework.beans.factory.annotation.Autowired;
28   -import org.springframework.dao.DataIntegrityViolationException;
29   -import org.springframework.jdbc.core.BatchPreparedStatementSetter;
30   -import org.springframework.jdbc.core.JdbcTemplate;
31   -import org.springframework.jdbc.datasource.DataSourceTransactionManager;
32   -import org.springframework.stereotype.Component;
33   -import org.springframework.transaction.TransactionDefinition;
34   -import org.springframework.transaction.TransactionStatus;
35   -import org.springframework.transaction.support.DefaultTransactionDefinition;
36   -
37   -import java.sql.PreparedStatement;
38   -import java.sql.SQLException;
39   -import java.text.ParseException;
40   -import java.text.SimpleDateFormat;
41   -import java.util.*;
42   -import java.util.concurrent.ConcurrentHashMap;
43   -import java.util.concurrent.ConcurrentLinkedQueue;
44   -import java.util.concurrent.ConcurrentMap;
45   -
46   -/**
47   - * @author PanZhao
48   - * @ClassName: DayOfSchedule
49   - * @Description: TODO(当日实际排班)
50   - * @date 2016年8月15日 上午10:16:12
51   - */
52   -@Component
53   -public class DayOfSchedule {
54   -
55   - Logger logger = LoggerFactory.getLogger(this.getClass());
56   -
57   - //按线路分组的 “原始计划” 排班数据
58   - public static Map<String, List<SchedulePlanInfo>> schedulePlanMap;
59   -
60   - // 按车辆索引的班次数据
61   - private static ListMultimap<String, ScheduleRealInfo> nbbmScheduleMap;
62   -
63   - // 按营运公司索引的班次数据
64   - private static ListMultimap<String, ScheduleRealInfo> gsBmScheduleMap;
65   -
66   - //按线路索引计划用车
67   - private static HashMultimap<String, String> lineNbbmsMap;
68   -
69   - //按路牌索引班次数据 线路编码_路牌名称 ——> 班次list
70   - private static ArrayListMultimap<String, ScheduleRealInfo> lpScheduleMap;
71   -
72   - // 班次主键映射
73   - private static ConcurrentMap<Long, ScheduleRealInfo> id2SchedulMap;
74   -
75   - //车辆 ——> 当前执行班次
76   - private static ConcurrentMap<String, ScheduleRealInfo> carExecutePlanMap;
77   -
78   - // 持久化
79   - public static ConcurrentLinkedQueue<ScheduleRealInfo> pstBuffer;
80   -
81   - // 排序器
82   - private static ScheduleComparator.FCSJ schFCSJComparator;
83   -
84   - private static ScheduleComparator.DFSJ schDFSJComparator;
85   -
86   - private static Long sch_max_id=-1L;
87   -
88   - private Map<String, RepairReport> incode2report = new ConcurrentHashMap<String, RepairReport>();
89   -
90   - @Autowired
91   - LineConfigData lineConfigData;
92   -
93   - @Autowired
94   - ScheduleRealInfoRepository schRepository;
95   -
96   - @Autowired
97   - SchedulePlanInfoService schPlanService;
98   -
99   - @Autowired
100   - SchAttrCalculator schAttrCalculator;
101   -
102   - @Autowired
103   - SendUtils sendUtils;
104   -
105   - @Autowired
106   - GpsRealData gpsRealData;
107   -
108   - /**
109   - * 线路当前使用的排班的日期
110   - */
111   - public static Map<String, String> currSchDateMap;
112   -
113   - static {
114   - nbbmScheduleMap = ArrayListMultimap.create();
115   - nbbmScheduleMap = Multimaps.synchronizedListMultimap(nbbmScheduleMap);
116   -
117   - gsBmScheduleMap = ArrayListMultimap.create();
118   - lpScheduleMap = ArrayListMultimap.create();
119   - lineNbbmsMap = HashMultimap.create();
120   -
121   - id2SchedulMap = new ConcurrentHashMap<>();
122   - pstBuffer = new ConcurrentLinkedQueue<>();
123   - schFCSJComparator = new ScheduleComparator.FCSJ();
124   - schDFSJComparator = new ScheduleComparator.DFSJ();
125   - currSchDateMap = new HashMap<>();
126   - carExecutePlanMap = new ConcurrentHashMap<>();
127   -
128   - schedulePlanMap = new HashMap<>();
129   - }
130   -
131   - @Autowired
132   - LineConfigData lineConfigs;
133   -
134   - @Autowired
135   - GpsDataRecovery gpsDataRecovery;
136   -
137   - private static DateTimeFormatter fmtyyyyMMdd = DateTimeFormat.forPattern("yyyy-MM-dd"), fmtHHmm = DateTimeFormat.forPattern("HH:mm");
138   -
139   - //数据恢复
140   - public void dataRecovery() {
141   - Collection<LineConfig> confs = lineConfigs.getAll();
142   - String lineCode, currSchDate;
143   - for (LineConfig conf : confs) {
144   - lineCode = conf.getLine().getLineCode();
145   - currSchDate = calcSchDate(lineCode);
146   - //加载班次数据
147   - reloadSch(lineCode, currSchDate, false);
148   - }
149   -
150   - //恢复gps数据
151   - gpsDataRecovery.recovery();
152   - }
153   -
154   - public Map<String, String> getCurrSchDate() {
155   - return currSchDateMap;
156   - }
157   -
158   - /**
159   - * @Title: calcSchDateB
160   - * @Description: TODO(计算线路当前应该使用的排班日期)
161   - */
162   - public String calcSchDate(String lineCode) {
163   - Long t = System.currentTimeMillis();
164   - LineConfig conf = lineConfigData.get(lineCode);
165   -
166   - // 小于当天起始运营时间,则取前一天的排班
167   - String ct = fmtHHmm.print(t);
168   - if(ct.compareTo(conf.getStartOpt()) < 0)
169   - t -= 1000 * 60 * 60 * 24;
170   -
171   - String schDate = fmtyyyyMMdd.print(t);
172   - return schDate;
173   - }
174   -
175   - /**
176   - * @param @param lineCode 线路编码
177   - * @param @param schDate 班次日期 yyyy-MM-dd
178   - * @param @param forcePlan 强制从计划调度重新抓取
179   - * @Title: reloadSch
180   - * @Title: reloadSch
181   - * @Description: TODO(重新载入排班)
182   - */
183   - public int reloadSch(String lineCode, String schDate, boolean forcePlan) {
184   - try {
185   - List<ScheduleRealInfo> list;
186   -
187   - if (forcePlan)
188   - removeRealSch(lineCode, schDate);
189   - else
190   - clearRAMData(lineCode);
191   -
192   - if (existRealSch(lineCode, schDate))
193   - list = loadRealSch(lineCode, schDate);// 从实际排班表加载
194   - else {
195   - list = loadPlanSch(lineCode, schDate);// 从计划排班表加载
196   - // 写入数据库
197   - batchSave(list);
198   - }
199   -
200   - //更新线路和班次日期对照
201   - currSchDateMap.put(lineCode, schDate);
202   - //添加到缓存
203   - putAll(list);
204   -
205   - //标记首末班
206   - FirstAndLastHandler.marks(list);
207   -
208   - Set<String> lps = searchAllLP(list);
209   - for (String lp : lps) {
210   - //计算“起点站应到”时间
211   - schAttrCalculator.calcQdzTimePlan(lpScheduleMap.get(lineCode + "_" + lp));
212   - }
213   - Set<String> cars = searchAllCars(list);
214   - for (String nbbm : cars) {
215   - //车辆 ——> 要执行的班次对照
216   - reCalcExecPlan(nbbm);
217   - }
218   -
219   - //分组计划用车
220   - reCalcLineNbbms();
221   - // 页面 翻班通知
222   - //sendUtils.shiftSchedule(lineCode);
223   - } catch (Exception e) {
224   - logger.error("", e);
225   - return -1;
226   - }
227   -
228   - return 0;
229   - }
230   -
231   - public int reloadSch(String lineCode) {
232   - return reloadSch(lineCode, calcSchDate(lineCode), true);
233   - }
234   -
235   - /**
236   - * @Title: searchAllCars
237   - * @Description: TODO(搜索班次集合中的车辆)
238   - */
239   - private Set<String> searchAllCars(List<ScheduleRealInfo> list) {
240   - Set<String> cars = new HashSet<>();
241   - for (ScheduleRealInfo sch : list)
242   - cars.add(sch.getClZbh());
243   -
244   - return cars;
245   - }
246   -
247   - /**
248   - * @Title: searchAllCars
249   - * @Description: TODO(搜索班次集合中的路牌)
250   - */
251   - private Set<String> searchAllLP(List<ScheduleRealInfo> list) {
252   - Set<String> lps = new HashSet<>();
253   - for (ScheduleRealInfo sch : list)
254   - lps.add(sch.getLpName());
255   -
256   - return lps;
257   - }
258   -
259   - private void putAll(List<ScheduleRealInfo> list) {
260   - for (ScheduleRealInfo sch : list)
261   - put(sch);
262   - }
263   -
264   - /**
265   - * @param @param lineCode 线路编码
266   - * @param @param schDate 班次日期 yyyy-MM-dd
267   - * @Title: removeRealSch
268   - * @Description: TODO(清除实际排班,包括数据库和内存数据)
269   - */
270   - public void removeRealSch(String lineCode, String schDate) throws Exception {
271   - try {
272   - // 清理数据库数据
273   - schRepository.deleteByLineCodeAndDate(lineCode + "", schDate);
274   -
275   - // 清理内存数据
276   - clearRAMData(lineCode + "");
277   - } catch (Exception e) {
278   - logger.error("removeRealSch error, " + lineCode + " -" + schDate, e);
279   - throw e;
280   - }
281   - }
282   -
283   - /**
284   - * @Title: clearRAMData
285   - * @Description: TODO(清理内存数据)
286   - */
287   - public void clearRAMData(String lineCode) {
288   - int count = 0;
289   - List<ScheduleRealInfo> remList = new ArrayList<>();
290   - Collection<ScheduleRealInfo> all = nbbmScheduleMap.values();
291   - for (ScheduleRealInfo sch : all) {
292   - if (sch.getXlBm().equals(lineCode))
293   - remList.add(sch);
294   - }
295   -
296   - for (ScheduleRealInfo sch : remList) {
297   - if (null != sch) {
298   - nbbmScheduleMap.remove(sch.getClZbh(), sch);
299   - id2SchedulMap.remove(sch.getId());
300   - count++;
301   -
302   - //清理路牌对照
303   - lpScheduleMap.removeAll(sch.getXlBm() + "_" + sch.getLpName());
304   -
305   - //清除车辆 ——> 执行班次对照
306   - carExecutePlanMap.remove(sch.getClZbh());
307   - }
308   - }
309   - //清理计划排班
310   - schedulePlanMap.remove(lineCode);
311   -
312   - remList.clear();
313   - remList = null;
314   - logger.info(lineCode + "排班清理 " + count);
315   - }
316   -
317   - /**
318   - * @Title: existRealSch
319   - * @Description: TODO(实际排班是否已存在)
320   - */
321   - public boolean existRealSch(String lineCode, String schDate) {
322   - int count = schRepository.countByLineCodeAndDate(lineCode, schDate);
323   - return count > 0;
324   - }
325   -
326   - /**
327   - * @Title: loadRealSch
328   - * @Description: TODO(从实际排班表加载数据)
329   - */
330   - public List<ScheduleRealInfo> loadRealSch(String lineCode, String schDate) {
331   - return schRepository.findByLineCodeAndDate(lineCode, schDate);
332   - }
333   -
334   - /**
335   - * @Title: loadPlanSch
336   - * @Description: TODO(从计划排班表加载数据)
337   - */
338   - public List<ScheduleRealInfo> loadPlanSch(String lineCode, String schDate) {
339   - //logger.info("从计划排班表恢复排班,lineCode: " + lineCode + ", schDate: " + schDate);
340   - List<ScheduleRealInfo> realList = new ArrayList<>();
341   -
342   - try {
343   - Map<String, Object> data = new HashMap<>();
344   -
345   - data.put("scheduleDate_eq", fmtyyyyMMdd.parseDateTime(schDate).toDate());
346   - data.put("xlBm_eq", lineCode);
347   -
348   - // 查询计划排班
349   - List<SchedulePlanInfo> planItr = cleanSchPlanItr(schPlanService.list(data).iterator());
350   - //保存一份原始计划排班数据
351   - schedulePlanMap.put(lineCode, planItr);
352   -
353   - // 转换为实际排班
354   - realList = JSONArray.parseArray(JSON.toJSONString(planItr), ScheduleRealInfo.class);
355   - logger.info("从计划排班表恢复排班,lineCode: " + lineCode + ", schDate: " + schDate + ", size:" + realList.size());
356   -
357   - Date d = new Date();
358   - SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");
359   - String fcsj;
360   - for (ScheduleRealInfo sch : realList) {
361   - sch.setScheduleDateStr(fmtyyyyMMdd.print(sch.getScheduleDate().getTime()));
362   - sch.setRealExecDate(sch.getScheduleDateStr());
363   - sch.setCreateDate(d);
364   -
365   - if (StringUtils.isEmpty(sch.getFcsj()))
366   - sch.setFcsj("00:00");
367   -
368   - if (sch.getFcsj().equals("24:00"))
369   - sch.setFcsj("23:59");
370   -
371   - if (sch.getFcsj().substring(0, 2).equals("24")) {
372   - sch.setFcsj("00" + sch.getFcsj().substring(2));
373   - }
374   -
375   - fcsj = sch.getFcsj().trim();
376   - //处理一下发车时间格式没有:号的问题
377   - if (fcsj.indexOf(":") == -1 && fcsj.length() >= 4) {
378   - sch.setFcsj(fcsj.substring(0, 2) + ":" + fcsj.substring(2, 4));
379   - }
380   -
381   - try {
382   - sdf.parse(sch.getFcsj());
383   - } catch (ParseException e) {
384   - //发车时间仍然校验不过的,直接写成00:00
385   - sch.setFcsj("00:00");
386   - }
387   - sch.setDfsj(sch.getFcsj());
388   -
389   - // 计划终点时间
390   - if (sch.getBcsj() != null) {
391   - sch.setZdsj(fmtHHmm.print(fmtHHmm.parseMillis(sch.getFcsj()) + (sch.getBcsj() * 60 * 1000)));
392   - sch.setLate(false);
393   - }
394   -
395   - //售票员为空设置为""字符串
396   - if (StringUtils.isEmpty(sch.getsGh())) {
397   - sch.setsGh("");
398   - sch.setsName("");
399   - }
400   - sch.setJhlcOrig(sch.getJhlc());
401   - //保留备注
402   - if (StringUtils.isNotEmpty(sch.getRemark()))
403   - sch.setRemarks(sch.getRemark());
404   - }
405   - } catch (Exception e) {
406   - logger.error("", e);
407   - }
408   -
409   - return realList;
410   - }
411   -
412   -
413   - public synchronized long getId(){
414   - if(sch_max_id==-1){
415   - sch_max_id = schRepository.getMaxId();
416   - if(null == sch_max_id)
417   - sch_max_id = 3000L;//留一点空间补数据用
418   - sch_max_id += 5;
419   - }
420   - else
421   - sch_max_id ++;
422   - return sch_max_id;
423   - }
424   -
425   - /**
426   - * @Title: batchSave
427   - * @Description: TODO(批量入库)
428   - */
429   - private void batchSave(List<ScheduleRealInfo> list) {
430   - SimpleDateFormat sdfyyyyMMdd = new SimpleDateFormat("yyyy-MM-dd");
431   - for (ScheduleRealInfo item : list) {
432   - item.setSpId(item.getId());// 保留原始的计划ID
433   - item.setId(getId());// 设置ID
434   - item.setScheduleDateStr(sdfyyyyMMdd.format(item.getScheduleDate()));
435   - }
436   -
437   - //编程式事务
438   - DataSourceTransactionManager tran = new DataSourceTransactionManager(jdbcTemplate.getDataSource());
439   - DefaultTransactionDefinition def = new DefaultTransactionDefinition();
440   - def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
441   - TransactionStatus status = tran.getTransaction(def);
442   -
443   - try{
444   - final List<ScheduleRealInfo> pstList = list;
445   - //写入
446   - jdbcTemplate.batchUpdate("insert into bsth_c_s_sp_info_real(id,bc_type,bcs,bcsj,cl_zbh,create_date,dfsj,directive_state,fcno,fcsj,fcsj_actual,j_gh,j_name,jhlc,lp_name,qdz_code,qdz_name,real_exec_date,remarks,s_gh,s_name,schedule_date,schedule_date_str,sflj,sp_id,status,update_date,xl_bm,xl_dir,xl_name,zdsj,zdsj_actual,zdz_code,zdz_name,ccno,df_auto,fgs_bm,fgs_name,gs_bm,gs_name,online,adjust_exps,reissue,jhlc_orig,sigin_compate,drift_status,cc_service,major_station_name)" +
447   - " VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)", new BatchPreparedStatementSetter() {
448   - @Override
449   - public void setValues(PreparedStatement ps, int i) throws SQLException {
450   - ScheduleRealInfo sch = pstList.get(i);
451   - ps.setLong(1, sch.getId());
452   - ps.setString(2, sch.getBcType());
453   - ps.setInt(3, sch.getBcs()==null?0:sch.getBcs());
454   - ps.setInt(4, sch.getBcsj()==null?0:sch.getBcsj());
455   - ps.setString(5, sch.getClZbh());
456   - ps.setTimestamp(6, new java.sql.Timestamp(sch.getCreateDate().getTime()));
457   - ps.setString(7, sch.getDfsj());
458   - ps.setInt(8, sch.getDirectiveState());
459   - ps.setInt(9, sch.getFcno()==null?0:sch.getFcno());
460   - ps.setString(10, sch.getFcsj());
461   - ps.setString(11, sch.getFcsjActual());
462   - ps.setString(12, sch.getjGh());
463   - ps.setString(13, sch.getjName());
464   - ps.setDouble(14, sch.getJhlc());
465   - ps.setString(15, sch.getLpName());
466   - ps.setString(16, sch.getQdzCode());
467   - ps.setString(17, sch.getQdzName());
468   - ps.setString(18, sch.getRealExecDate());
469   - ps.setString(19, sch.getRemarks());
470   - ps.setString(20, sch.getsGh());
471   - ps.setString(21, sch.getsName());
472   - ps.setTimestamp(22, new java.sql.Timestamp(sch.getScheduleDate().getTime()));
473   - ps.setString(23, sch.getScheduleDateStr());
474   - ps.setBoolean(24, sch.isSflj());
475   - ps.setLong(25, sch.getSpId());
476   - ps.setInt(26, sch.getStatus());
477   - ps.setTimestamp(27, new java.sql.Timestamp(sch.getUpdateDate().getTime()));
478   - ps.setString(28, sch.getXlBm());
479   - ps.setString(29, sch.getXlDir());
480   - ps.setString(30, sch.getXlName());
481   - ps.setString(31, sch.getZdsj());
482   - ps.setString(32, sch.getZdsjActual());
483   - ps.setString(33, sch.getZdzCode());
484   - ps.setString(34, sch.getZdzName());
485   - ps.setInt(35, sch.getCcno()==null?0:sch.getCcno());
486   - ps.setBoolean(36, sch.isDfAuto());
487   - ps.setString(37, sch.getFgsBm());
488   - ps.setString(38, sch.getFgsName());
489   - ps.setString(39, sch.getGsBm());
490   - ps.setString(40, sch.getGsName());
491   - ps.setBoolean(41, sch.isOnline());
492   - ps.setString(42, sch.getAdjustExps());
493   - ps.setBoolean(43, sch.isReissue());
494   - ps.setDouble(44, sch.getJhlcOrig());
495   - ps.setInt(45, sch.getSiginCompate());
496   - ps.setInt(46, sch.getDriftStatus());
497   - ps.setBoolean(47, sch.isCcService());
498   - ps.setString(48, sch.getMajorStationName());
499   - }
500   -
501   - @Override
502   - public int getBatchSize() {
503   - return pstList.size();
504   - }
505   - });
506   -
507   - tran.commit(status);
508   - }catch (Exception e){
509   - tran.rollback(status);
510   - logger.error("real schedule batchSave error...", e);
511   - }
512   - // 入库
513   - //new BatchSaveUtils<ScheduleRealInfo>().saveList(list, ScheduleRealInfo.class);
514   - }
515   -
516   - public List<SchedulePlanInfo> cleanSchPlanItr(Iterator<SchedulePlanInfo> itrab) {
517   - List<SchedulePlanInfo> list = new ArrayList<>();
518   -
519   - SchedulePlanInfo sp;
520   - while (itrab.hasNext()) {
521   - sp = itrab.next();
522   - sp.setSchedulePlan(null);
523   - sp.setCreateBy(null);
524   - sp.setUpdateBy(null);
525   - list.add(sp);
526   - }
527   - return list;
528   - }
529   -
530   - /**
531   - * @Title: findByLineCode
532   - * @Description: TODO(lineCode 获取班次)
533   - */
534   - public List<ScheduleRealInfo> findByLineCode(String lineCode) {
535   - List<ScheduleRealInfo> rs = new ArrayList<>();
536   -
537   - Collection<ScheduleRealInfo> schs = nbbmScheduleMap.values();
538   - for (ScheduleRealInfo sch : schs) {
539   - if (sch.getXlBm().equals(lineCode))
540   - rs.add(sch);
541   - }
542   - return rs;
543   - }
544   -
545   - /**
546   - * @Title: findByLineCode
547   - * @Description: TODO(lineList 获取班次)
548   - */
549   - public Map<String, Collection<ScheduleRealInfo>> findByLineCodes(List<String> lineList) {
550   - ArrayListMultimap<String, ScheduleRealInfo> mMap = ArrayListMultimap.create();
551   -
552   - Collection<ScheduleRealInfo> schs = nbbmScheduleMap.values();
553   - for (ScheduleRealInfo sch : schs) {
554   - if (lineList.contains(sch.getXlBm())) {
555   - mMap.put(sch.getXlBm(), sch);
556   - }
557   - }
558   - return mMap.asMap();
559   - }
560   -
561   - /**
562   - * @Title: findCarByLineCode
563   - * @Description: TODO(线路下运营的车辆)
564   - */
565   - public Set<String> findCarByLineCode(String lineCode) {
566   - /*Set<String> rs = new HashSet<>();
567   -
568   - Collection<ScheduleRealInfo> schs = nbbmScheduleMap.values();
569   - for (ScheduleRealInfo sch : schs) {
570   - if (sch.getXlBm().equals(lineCode))
571   - rs.add(sch.getClZbh());
572   - }
573   -*/
574   - return lineNbbmsMap.get(lineCode);
575   - }
576   -
577   - public List<ScheduleRealInfo> findByNbbm(String nbbm) {
578   - return nbbmScheduleMap.get(nbbm);
579   - }
580   -
581   - /**
582   - * @Title: findByLineAndUpDown
583   - * @Description: TODO(lineCode 和走向获取班次)
584   - */
585   - public List<ScheduleRealInfo> findByLineAndUpDown(String lineCode, Integer upDown) {
586   - List<ScheduleRealInfo> list = findByLineCode(lineCode), rs = new ArrayList<>();
587   -
588   - for (ScheduleRealInfo sch : list) {
589   - if (sch.getXlDir().equals(upDown + ""))
590   - rs.add(sch);
591   - }
592   - return rs;
593   - }
594   -
595   - public ScheduleRealInfo get(long id) {
596   - return id2SchedulMap.get(id);
597   - }
598   -
599   -
600   - /**
601   - * @Title: next
602   - * @Description: TODO(下一个班次)
603   - */
604   - public ScheduleRealInfo next(ScheduleRealInfo sch) {
605   - List<ScheduleRealInfo> list = nbbmScheduleMap.get(sch.getClZbh());
606   - //排序
607   - Collections.sort(list, schDFSJComparator);
608   - return next(list, sch);
609   - }
610   -
611   -
612   - /**
613   - * 下一个班次
614   - *
615   - * @param list 班次集合
616   - * @param sch 当前班次
617   - * @return
618   - */
619   - private ScheduleRealInfo next(Collection<ScheduleRealInfo> list, ScheduleRealInfo sch) {
620   - int outConfig = -1;
621   - LineConfig config = lineConfigData.get(sch.getXlBm());
622   - if (config != null)
623   - outConfig = config.getOutConfig();
624   -
625   - //限定出站既出场的停车场
626   - List<String> parks = config.findTwinsParkList();
627   - boolean limitPark = null != parks && parks.size() > 0;
628   - boolean flag = false;
629   - ScheduleRealInfo next = null;
630   - for (ScheduleRealInfo temp : list) {
631   - if (temp.getId() == sch.getId()) {
632   - flag = true;
633   - continue;
634   - }
635   - //忽略烂班
636   - if (temp.isDestroy())
637   - continue;
638   -
639   - //出站既出场,忽略出场班次
640   - if (outConfig == 2 && temp.getBcType().equals("out") && isEmptyMileage(temp)
641   - && (!limitPark || parks.contains(temp.getQdzCode())))
642   - continue;
643   -
644   - if (flag) {
645   - next = temp;
646   - break;
647   - }
648   - }
649   - return next;
650   - }
651   -
652   - private boolean isEmptyMileage(ScheduleRealInfo sch) {
653   - return sch.getBcsj() == 0 || sch.getJhlcOrig().intValue() == 0;
654   - }
655   -
656   - /**
657   - * 下一个班次
658   - *
659   - * @param list 班次集合
660   - * @param sch 当前班次
661   - * @return
662   - */
663   - private ScheduleRealInfo next2_lp(Collection<ScheduleRealInfo> list, ScheduleRealInfo sch) {
664   - int outConfig = -1;
665   - LineConfig config = lineConfigData.get(sch.getXlBm());
666   - if (config != null)
667   - outConfig = config.getOutConfig();
668   -
669   - boolean flag = false;
670   - ScheduleRealInfo next = null;
671   - for (ScheduleRealInfo temp : list) {
672   - if (temp.getId() == sch.getId()) {
673   - flag = true;
674   - continue;
675   - }
676   -
677   - if (flag) {
678   - next = temp;
679   - break;
680   - }
681   - }
682   - return next;
683   - }
684   -
685   - private ScheduleRealInfo next3_lp(Collection<ScheduleRealInfo> list, ScheduleRealInfo sch) {
686   - int outConfig = -1;
687   - LineConfig config = lineConfigData.get(sch.getXlBm());
688   - if (config != null)
689   - outConfig = config.getOutConfig();
690   -
691   - //限定出站既出场的停车场
692   - List<String> parks = config.findTwinsParkList();
693   - boolean limitPark = null != parks && parks.size() > 0;
694   - boolean flag = false;
695   - ScheduleRealInfo next = null;
696   - for (ScheduleRealInfo temp : list) {
697   - if (temp.getId() == sch.getId()) {
698   - flag = true;
699   - continue;
700   - }
701   -
702   - //出站既出场,忽略出场班次
703   - if (outConfig == 2 && temp.getBcType().equals("out") && isEmptyMileage(temp)
704   - && (!limitPark || parks.contains(temp.getQdzCode())))
705   - continue;
706   -
707   - if (flag) {
708   - next = temp;
709   - break;
710   - }
711   - }
712   - return next;
713   - }
714   -
715   - /**
716   - * 上一个班次
717   - *
718   - * @param sch
719   - * @return
720   - */
721   - public ScheduleRealInfo prev(ScheduleRealInfo sch) {
722   - List<ScheduleRealInfo> list = nbbmScheduleMap.get(sch.getClZbh());
723   -
724   - //boolean flag = false;
725   - ScheduleRealInfo prev = null;
726   - int size = list.size();
727   -
728   - for (int i = 0; i < size; i++) {
729   - if (list.get(i).isDestroy())
730   - continue;
731   -
732   - if (list.get(i).getId().equals(sch.getId())) {
733   - return prev;
734   - }
735   - prev = list.get(i);
736   - }
737   - return prev;
738   - }
739   -
740   - /**
741   - * 是否是首班出场
742   - *
743   - * @param sch
744   - * @return
745   - */
746   - public boolean isFirstOut(ScheduleRealInfo sch) {
747   - List<ScheduleRealInfo> list = nbbmScheduleMap.get(sch.getClZbh());
748   - try {
749   - if (list.get(0) == sch && sch.getBcType().equals("out"))
750   - return true;
751   - } catch (IndexOutOfBoundsException e) {
752   - logger.error("小小的数组越界,无伤大雅!");
753   - }
754   - return false;
755   - }
756   -
757   - public void put(ScheduleRealInfo sch) {
758   - schAttrCalculator
759   - .calcRealDate(sch)
760   - .calcAllTimeByFcsj(sch);
761   -
762   - nbbmScheduleMap.put(sch.getClZbh(), sch);
763   -
764   - //主键索引
765   - id2SchedulMap.put(sch.getId(), sch);
766   - //路牌对照表
767   - addLPMapp(sch);
768   -
769   - //跨24点的,再save一次
770   - if (!sch.getRealExecDate().equals(sch.getScheduleDateStr()))
771   - save(sch);
772   - }
773   -
774   - public void addLPMapp(ScheduleRealInfo sch) {
775   - lpScheduleMap.put(sch.getXlBm() + "_" + sch.getLpName(), sch);
776   - }
777   -
778   - public void delete(ScheduleRealInfo sch) {
779   - if (!sch.isSflj())
780   - return;
781   -
782   - nbbmScheduleMap.remove(sch.getClZbh(), sch);
783   - id2SchedulMap.remove(sch.getId());
784   - lpScheduleMap.remove(sch.getXlBm() + "_" + sch.getLpName(), sch);
785   -
786   - //如果正在执行该班次
787   - if (carExecutePlanMap.get(sch.getClZbh()) == sch) {
788   - //重新计算车辆当前执行班次
789   - reCalcExecPlan(sch.getClZbh());
790   - }
791   - }
792   -
793   - public List<ScheduleRealInfo> updateQdzTimePlan(String lpName) {
794   - List<ScheduleRealInfo> list = lpScheduleMap.get(lpName);
795   - Collections.sort(list, schFCSJComparator);
796   - return schAttrCalculator.updateQdzTimePlan(list);
797   - }
798   -
799   - public List<ScheduleRealInfo> updateQdzTimePlan(ScheduleRealInfo sch) {
800   - return updateQdzTimePlan(sch.getXlBm() + "_" + sch.getLpName());
801   - }
802   -
803   - /**
804   - * @Title: doneSum
805   - * @Description: TODO(已完成班次总数)
806   - */
807   - public int doneSum(String clZbh) {
808   - List<ScheduleRealInfo> list = nbbmScheduleMap.get(clZbh);
809   - int rs = 0;
810   -
811   - for (ScheduleRealInfo sch : list) {
812   - if (sch.getStatus() == 2 && !sch.isDestroy())
813   - rs++;
814   - }
815   - return rs;
816   - }
817   -
818   - public void save(ScheduleRealInfo sch) {
819   - sch.setUpdateDate(new Date());
820   - pstBuffer.add(sch);
821   - }
822   -
823   -
824   - /**
825   - * @Title: nextByBcType
826   - * @Description: TODO(获取下一个指定班次类型的班次)
827   - */
828   - public ScheduleRealInfo nextByBcType(String nbbm, String bcType) {
829   - List<ScheduleRealInfo> list = findByBcType(nbbm, bcType);
830   -
831   - Collections.sort(list, schFCSJComparator);
832   - ScheduleRealInfo sch = null;
833   - for (ScheduleRealInfo temp : list) {
834   - if (temp.getFcsjActual() == null) {
835   - sch = temp;
836   - break;
837   - }
838   - }
839   -
840   - return sch;
841   - }
842   -
843   -
844   - /**
845   - * 搜索离当前时间最近的一个指定类型的班次
846   - *
847   - * @param nbbm
848   - * @param bcType
849   - * @return
850   - */
851   - public ScheduleRealInfo searchNearByBcType(String nbbm, String bcType) {
852   - List<ScheduleRealInfo> list = findByBcType(nbbm, bcType);
853   - Collections.sort(list, schFCSJComparator);
854   -
855   - long t = System.currentTimeMillis();
856   - int distance = -1, diff;
857   -
858   - ScheduleRealInfo sch = null;
859   - for (ScheduleRealInfo temp : list) {
860   - diff = (int) Math.abs(temp.getDfsjT() - t);
861   - if (diff < distance || distance == -1) {
862   - sch = temp;
863   - distance = diff;
864   - }
865   - }
866   - return sch;
867   - }
868   -
869   - public List<ScheduleRealInfo> findByBcType(String nbbm, String bcType) {
870   - List<ScheduleRealInfo> all = nbbmScheduleMap.get(nbbm), outList = new ArrayList<>();
871   -
872   - for (ScheduleRealInfo sch : all) {
873   - if (sch.getBcType().equals(bcType))
874   - outList.add(sch);
875   - }
876   - return outList;
877   - }
878   -
879   - public Collection<ScheduleRealInfo> findAll() {
880   - return nbbmScheduleMap.values();
881   - }
882   -
883   - public Collection<ScheduleRealInfo> findAllByLpContainer() {
884   - return lpScheduleMap.values();
885   - }
886   -
887   - public Collection<ScheduleRealInfo> findAllByIdContainer() {
888   - return id2SchedulMap.values();
889   - }
890   -
891   - public int getPstSize() {
892   - return pstBuffer.size();
893   - }
894   -
895   - public boolean addExecPlan(ScheduleRealInfo sch) {
896   - ScheduleRealInfo oldExec = executeCurr(sch.getClZbh());
897   - if (sch != null){
898   - if(sch.getStatus()==2)
899   - reCalcExecPlan(sch.getClZbh());
900   - else
901   - carExecutePlanMap.put(sch.getClZbh(), sch);
902   - }
903   - else
904   - carExecutePlanMap.remove(sch.getClZbh());
905   -
906   - return executeCurr(sch.getClZbh()) != oldExec;
907   - }
908   -
909   - public void removeExecPlan(String clzbh) {
910   - carExecutePlanMap.remove(clzbh);
911   - }
912   -
913   - public Map<String, ScheduleRealInfo> execPlanMap() {
914   - return carExecutePlanMap;
915   - }
916   -
917   - /**
918   - * 车辆当前执行的班次
919   - *
920   - * @param nbbm
921   - * @return
922   - */
923   - public ScheduleRealInfo executeCurr(String nbbm) {
924   - if(StringUtils.isEmpty(nbbm))
925   - return null;
926   - return carExecutePlanMap.get(nbbm);
927   - }
928   -
929   - /**
930   - * @param @param sch
931   - * @param @param newClZbh 新的车辆自编号
932   - * @Title: changeCar
933   - * @Description: TODO(班次换车) 返回有更新的班次
934   - */
935   - public List<ScheduleRealInfo> changeCar(ScheduleRealInfo sch, String newClZbh) {
936   - List<ScheduleRealInfo> ups = new ArrayList<>();
937   -
938   - String oldClZbh = sch.getClZbh();
939   - //变更相关映射信息
940   - nbbmScheduleMap.remove(sch.getClZbh(), sch);
941   -
942   - sch.setClZbh(newClZbh);
943   - if (!nbbmScheduleMap.containsEntry(newClZbh, sch)) {
944   - nbbmScheduleMap.put(newClZbh, sch);
945   - }
946   -
947   - //重新计算车辆当前执行班次
948   - reCalcExecPlan(newClZbh);
949   - reCalcExecPlan(oldClZbh);
950   - //重新分组计划用车
951   - reCalcLineNbbms();
952   - return ups;
953   - }
954   -
955   - public void removeNbbm2SchMapp(ScheduleRealInfo sch) {
956   - nbbmScheduleMap.remove(sch.getClZbh(), sch);
957   - }
958   -
959   - public void addNbbm2SchMapp(ScheduleRealInfo sch) {
960   - nbbmScheduleMap.put(sch.getClZbh(), sch);
961   - }
962   -
963   - public void reCalcExecPlan(String nbbm) {
964   - List<ScheduleRealInfo> list = nbbmScheduleMap.get(nbbm);
965   - Collections.sort(list, schDFSJComparator);
966   -
967   - ScheduleRealInfo sch = schAttrCalculator.calcCurrentExecSch(list);
968   - if(null != sch)
969   - carExecutePlanMap.put(nbbm, sch);
970   - else
971   - carExecutePlanMap.remove(nbbm);
972   - }
973   -
974   - /**
975   - * 空驶任务?
976   - * 出场、进场、直放、两点间空驶
977   - * @param sch
978   - * @return
979   - */
980   - public static boolean emptyService(ScheduleRealInfo sch){
981   - String type = sch.getBcType();
982   - return type.equals("out") || type.equals("in") || type.equals("venting") || type.equals("ldks");
983   - }
984   -
985   - @Autowired
986   - JdbcTemplate jdbcTemplate;
987   -
988   - /**
989   - * 删除实际排班
990   - *
991   - * @param lineCode
992   - * @return
993   - */
994   - public Map<String, Object> deleteRealSchedule(String lineCode) {
995   - Map<String, Object> rs = new HashMap<>();
996   -
997   - try {
998   - String rq = currSchDateMap.get(lineCode);
999   - if (StringUtils.isNotEmpty(rq)) {
1000   - List<ScheduleRealInfo> all = findByLineCode(lineCode);
1001   -
1002   - if(null != all && all.size() > 0){
1003   - //解除gps 和班次之间的关联
1004   - List<ScheduleRealInfo> unions = calcUnion(all, carExecutePlanMap.values());
1005   - for (ScheduleRealInfo sch : unions) {
1006   - removeExecPlan(sch.getClZbh());
1007   - }
1008   - //解除调度指令和班次的外键约束
1009   - StringBuilder inStr = new StringBuilder("(");
1010   - for (ScheduleRealInfo sch : all) {
1011   - inStr.append(sch.getId() + ",");
1012   - }
1013   - inStr.deleteCharAt(inStr.length() - 1).append(")");
1014   - jdbcTemplate.update(Constants.MULTI_REMOVE_DIRECTIVE_SCH_FK + " " + inStr.toString());
1015   - }
1016   -
1017   - //删除班次数据
1018   - removeRealSch(lineCode, rq);
1019   -
1020   - }
1021   - rs.put("status", ResponseCode.SUCCESS);
1022   - } catch (Exception e) {
1023   - logger.error("", e);
1024   - rs.put("status", ResponseCode.ERROR);
1025   - if (e instanceof DataIntegrityViolationException)
1026   - rs.put("msg", "失败,违反数据约束!!");
1027   - else
1028   - rs.put("msg", e.getMessage());
1029   - }
1030   -
1031   - return rs;
1032   - }
1033   -
1034   - /**
1035   - * 计算并集
1036   - *
1037   - * @param all
1038   - * @param sub
1039   - * @return
1040   - */
1041   - public List<ScheduleRealInfo> calcUnion(Collection<ScheduleRealInfo> c1, Collection<ScheduleRealInfo> c2) {
1042   - List<ScheduleRealInfo> rs = new ArrayList<>();
1043   -
1044   - for (ScheduleRealInfo sch : c1) {
1045   - if (c2.contains(sch)) {
1046   - rs.add(sch);
1047   - }
1048   - }
1049   - return rs;
1050   - }
1051   -
1052   - /**
1053   - * 覆盖一辆车的所有班次
1054   - *
1055   - * @param nbbm
1056   - * @param sets
1057   - */
1058   - public void replaceByNbbm(String nbbm, Collection<ScheduleRealInfo> sets) {
1059   - nbbmScheduleMap.removeAll(nbbm);
1060   - nbbmScheduleMap.putAll(nbbm, sets);
1061   - }
1062   -
1063   - /**
1064   - * 获取该班次所在路牌的下一个班次
1065   - *
1066   - * @param sch
1067   - * @return
1068   - */
1069   - public ScheduleRealInfo nextByLp(ScheduleRealInfo sch) {
1070   - List<ScheduleRealInfo> list = lpScheduleMap.get(sch.getXlBm() + "_" + sch.getLpName());
1071   - Collections.sort(list, schFCSJComparator);
1072   - return next3_lp(list, sch);
1073   - }
1074   -
1075   - /**
1076   - * 获取该班次所在路牌的下一个班次,不考虑场既是站
1077   - *
1078   - * @param sch
1079   - * @return
1080   - */
1081   - public ScheduleRealInfo nextByLp2(ScheduleRealInfo sch) {
1082   - List<ScheduleRealInfo> list = lpScheduleMap.get(sch.getXlBm() + "_" + sch.getLpName());
1083   - Collections.sort(list, schFCSJComparator);
1084   - return next2_lp(list, sch);
1085   - }
1086   -
1087   - public ArrayListMultimap<String, ScheduleRealInfo> getLpScheduleMap() {
1088   - return lpScheduleMap;
1089   - }
1090   -
1091   - /**
1092   - * 重新全量计算路牌下的班次关联性
1093   - * 临时性的函数
1094   - */
1095   - public void _test_reCalcLpSch() {
1096   - Map<String ,Collection<ScheduleRealInfo>> map = lpScheduleMap.asMap();
1097   - Set<String> ks = map.keySet();
1098   - for(String k : ks){
1099   - schAttrCalculator.calcQdzTimePlan(new ArrayList<ScheduleRealInfo>(map.get(k)));
1100   - }
1101   - }
1102   -
1103   - public int dbCount(String lineCode, String currSchDate) {
1104   - int count = -1;
1105   -
1106   - try{
1107   - count = jdbcTemplate.queryForObject("select count(*) from bsth_c_s_sp_info_real where schedule_date='"+currSchDate+"' and xl_bm='"+lineCode+"'", java.lang.Integer.class);
1108   -
1109   - }catch (Exception e){
1110   - logger.error("", e);
1111   - }
1112   - return count;
1113   - }
1114   -
1115   - /**
1116   - * 重新计算ID对照map
1117   - */
1118   - public int reCalcIdMaps(){
1119   - Collection<ScheduleRealInfo> all = findAll();
1120   - ConcurrentMap<Long, ScheduleRealInfo> id2SchedulMapCopy = new ConcurrentHashMap<>();
1121   -
1122   - for(ScheduleRealInfo sch : all){
1123   - id2SchedulMapCopy.put(sch.getId(), sch);
1124   - }
1125   -
1126   - id2SchedulMap = id2SchedulMapCopy;
1127   -
1128   - return id2SchedulMap.size();
1129   - }
1130   -
1131   - /**
1132   - * 重新计算线路计划用车
1133   - */
1134   - public void reCalcLineNbbms(){
1135   - HashMultimap<String, String> multimap = HashMultimap.create();
1136   -
1137   - Collection<ScheduleRealInfo> schs = nbbmScheduleMap.values();
1138   - for (ScheduleRealInfo sch : schs) {
1139   - multimap.put(sch.getXlBm(), sch.getClZbh());
1140   - }
1141   -
1142   - lineNbbmsMap = multimap;
1143   - }
1144   -
1145   - public String sizeString(){
1146   - return id2SchedulMap.size() + "/" + nbbmScheduleMap.size();
1147   - }
1148   -
1149   -
1150   - /**
1151   - * 按公司编码分组数据
1152   - */
1153   - public void groupByGsbm(){
1154   - Collection<ScheduleRealInfo> all = findAll();
1155   - ListMultimap<String, ScheduleRealInfo> gsBmMaps = ArrayListMultimap.create();
1156   -
1157   - for(ScheduleRealInfo sch : all){
1158   - gsBmMaps.put(sch.getGsBm(), sch);
1159   - }
1160   -
1161   - if(gsBmMaps.size() > 0){
1162   - gsBmScheduleMap = null;
1163   - gsBmScheduleMap = gsBmMaps;
1164   - }
1165   - }
1166   -
1167   - public Collection<ScheduleRealInfo> findByGsbm(String gsbm){
1168   - return gsBmScheduleMap.get(gsbm);
1169   - }
1170   - /**
1171   - * 删除班次,删除内存中未清理掉的非当天的班次
1172   - * @createDate 2019.05.13
1173   - * @author zhangxianzhou
1174   - * @param sch
1175   - */
1176   - public void deleteBC(ScheduleRealInfo sch) {
1177   - nbbmScheduleMap.remove(sch.getClZbh(), sch);
1178   - id2SchedulMap.remove(sch.getId());
1179   - lpScheduleMap.remove(sch.getXlBm() + "_" + sch.getLpName(), sch);
1180   - //如果正在执行该班次
1181   - if (carExecutePlanMap.get(sch.getClZbh()) == sch) {
1182   - //重新计算车辆当前执行班次
1183   - reCalcExecPlan(sch.getClZbh());
1184   - }
1185   - }
1186   -
1187   - /**
1188   - ** 用于重置维修上报计数,一般只应该在翻班的时候调用
1189   - */
1190   - public void resetRepairReport(String incode) {
1191   - incode2report.remove(incode);
1192   - }
1193   -
1194   - public RepairReport getLastestRepairReport(String incode) {
1195   - return incode2report.get(incode);
1196   - }
1197   -
1198   - public void setLastestRepairReport(RepairReport rr) {
1199   - incode2report.put(rr.getIncode(), rr);
1200   - }
  1 +package com.bsth.data.schedule;
  2 +
  3 +import com.alibaba.fastjson.JSON;
  4 +import com.alibaba.fastjson.JSONArray;
  5 +import com.bsth.common.Constants;
  6 +import com.bsth.common.ResponseCode;
  7 +import com.bsth.data.LineConfigData;
  8 +import com.bsth.data.gpsdata_v2.GpsRealData;
  9 +import com.bsth.data.gpsdata_v2.rfid.handle.RfidDataHandler;
  10 +import com.bsth.data.gpsdata_v2.utils.GpsDataRecovery;
  11 +import com.bsth.data.schedule.f_a_l.FirstAndLastHandler;
  12 +import com.bsth.entity.realcontrol.LineConfig;
  13 +import com.bsth.entity.realcontrol.ScheduleRealInfo;
  14 +import com.bsth.entity.report.RepairReport;
  15 +import com.bsth.entity.schedule.SchedulePlanInfo;
  16 +import com.bsth.repository.realcontrol.ScheduleRealInfoRepository;
  17 +import com.bsth.service.schedule.SchedulePlanInfoService;
  18 +import com.bsth.websocket.handler.SendUtils;
  19 +import com.google.common.collect.ArrayListMultimap;
  20 +import com.google.common.collect.HashMultimap;
  21 +import com.google.common.collect.ListMultimap;
  22 +import com.google.common.collect.Multimaps;
  23 +import org.apache.commons.lang3.StringUtils;
  24 +import org.joda.time.format.DateTimeFormat;
  25 +import org.joda.time.format.DateTimeFormatter;
  26 +import org.slf4j.Logger;
  27 +import org.slf4j.LoggerFactory;
  28 +import org.springframework.beans.factory.annotation.Autowired;
  29 +import org.springframework.dao.DataIntegrityViolationException;
  30 +import org.springframework.jdbc.core.BatchPreparedStatementSetter;
  31 +import org.springframework.jdbc.core.JdbcTemplate;
  32 +import org.springframework.jdbc.datasource.DataSourceTransactionManager;
  33 +import org.springframework.stereotype.Component;
  34 +import org.springframework.transaction.TransactionDefinition;
  35 +import org.springframework.transaction.TransactionStatus;
  36 +import org.springframework.transaction.support.DefaultTransactionDefinition;
  37 +
  38 +import java.sql.PreparedStatement;
  39 +import java.sql.SQLException;
  40 +import java.text.ParseException;
  41 +import java.text.SimpleDateFormat;
  42 +import java.util.*;
  43 +import java.util.concurrent.ConcurrentHashMap;
  44 +import java.util.concurrent.ConcurrentLinkedQueue;
  45 +import java.util.concurrent.ConcurrentMap;
  46 +
  47 +/**
  48 + * @author PanZhao
  49 + * @ClassName: DayOfSchedule
  50 + * @Description: TODO(当日实际排班)
  51 + * @date 2016年8月15日 上午10:16:12
  52 + */
  53 +@Component
  54 +public class DayOfSchedule {
  55 +
  56 + Logger logger = LoggerFactory.getLogger(this.getClass());
  57 +
  58 + //按线路分组的 “原始计划” 排班数据
  59 + public static Map<String, List<SchedulePlanInfo>> schedulePlanMap;
  60 +
  61 + // 按车辆索引的班次数据
  62 + private static ListMultimap<String, ScheduleRealInfo> nbbmScheduleMap;
  63 +
  64 + // 按营运公司索引的班次数据
  65 + private static ListMultimap<String, ScheduleRealInfo> gsBmScheduleMap;
  66 +
  67 + //按线路索引计划用车
  68 + private static HashMultimap<String, String> lineNbbmsMap;
  69 +
  70 + //按路牌索引班次数据 线路编码_路牌名称 ——> 班次list
  71 + private static ArrayListMultimap<String, ScheduleRealInfo> lpScheduleMap;
  72 +
  73 + // 班次主键映射
  74 + private static ConcurrentMap<Long, ScheduleRealInfo> id2SchedulMap;
  75 +
  76 + //车辆 ——> 当前执行班次
  77 + private static ConcurrentMap<String, ScheduleRealInfo> carExecutePlanMap;
  78 +
  79 + // 持久化
  80 + public static ConcurrentLinkedQueue<ScheduleRealInfo> pstBuffer;
  81 +
  82 + // 排序器
  83 + private static ScheduleComparator.FCSJ schFCSJComparator;
  84 +
  85 + private static ScheduleComparator.DFSJ schDFSJComparator;
  86 +
  87 + private static Long sch_max_id=-1L;
  88 +
  89 + private Map<String, RepairReport> incode2report = new ConcurrentHashMap<String, RepairReport>();
  90 +
  91 + @Autowired
  92 + LineConfigData lineConfigData;
  93 +
  94 + @Autowired
  95 + ScheduleRealInfoRepository schRepository;
  96 +
  97 + @Autowired
  98 + SchedulePlanInfoService schPlanService;
  99 +
  100 + @Autowired
  101 + SchAttrCalculator schAttrCalculator;
  102 +
  103 + @Autowired
  104 + SendUtils sendUtils;
  105 +
  106 + @Autowired
  107 + GpsRealData gpsRealData;
  108 +
  109 + /**
  110 + * 线路当前使用的排班的日期
  111 + */
  112 + public static Map<String, String> currSchDateMap;
  113 +
  114 + static {
  115 + nbbmScheduleMap = ArrayListMultimap.create();
  116 + nbbmScheduleMap = Multimaps.synchronizedListMultimap(nbbmScheduleMap);
  117 +
  118 + gsBmScheduleMap = ArrayListMultimap.create();
  119 + lpScheduleMap = ArrayListMultimap.create();
  120 + lineNbbmsMap = HashMultimap.create();
  121 +
  122 + id2SchedulMap = new ConcurrentHashMap<>();
  123 + pstBuffer = new ConcurrentLinkedQueue<>();
  124 + schFCSJComparator = new ScheduleComparator.FCSJ();
  125 + schDFSJComparator = new ScheduleComparator.DFSJ();
  126 + currSchDateMap = new HashMap<>();
  127 + carExecutePlanMap = new ConcurrentHashMap<>();
  128 +
  129 + schedulePlanMap = new HashMap<>();
  130 + }
  131 +
  132 + @Autowired
  133 + LineConfigData lineConfigs;
  134 +
  135 + @Autowired
  136 + GpsDataRecovery gpsDataRecovery;
  137 +
  138 + private static DateTimeFormatter fmtyyyyMMdd = DateTimeFormat.forPattern("yyyy-MM-dd"), fmtHHmm = DateTimeFormat.forPattern("HH:mm");
  139 +
  140 + //数据恢复
  141 + public void dataRecovery() {
  142 + Collection<LineConfig> confs = lineConfigs.getAll();
  143 + String lineCode, currSchDate;
  144 + for (LineConfig conf : confs) {
  145 + lineCode = conf.getLine().getLineCode();
  146 + currSchDate = calcSchDate(lineCode);
  147 + //加载班次数据
  148 + reloadSch(lineCode, currSchDate, false);
  149 + }
  150 +
  151 + //恢复gps数据
  152 + gpsDataRecovery.recovery();
  153 + }
  154 +
  155 + public Map<String, String> getCurrSchDate() {
  156 + return currSchDateMap;
  157 + }
  158 +
  159 + /**
  160 + * @Title: calcSchDateB
  161 + * @Description: TODO(计算线路当前应该使用的排班日期)
  162 + */
  163 + public String calcSchDate(String lineCode) {
  164 + Long t = System.currentTimeMillis();
  165 + LineConfig conf = lineConfigData.get(lineCode);
  166 +
  167 + // 小于当天起始运营时间,则取前一天的排班
  168 + String ct = fmtHHmm.print(t);
  169 + if(ct.compareTo(conf.getStartOpt()) < 0)
  170 + t -= 1000 * 60 * 60 * 24;
  171 +
  172 + String schDate = fmtyyyyMMdd.print(t);
  173 + return schDate;
  174 + }
  175 +
  176 + /**
  177 + * @param @param lineCode 线路编码
  178 + * @param @param schDate 班次日期 yyyy-MM-dd
  179 + * @param @param forcePlan 强制从计划调度重新抓取
  180 + * @Title: reloadSch
  181 + * @Title: reloadSch
  182 + * @Description: TODO(重新载入排班)
  183 + */
  184 + public int reloadSch(String lineCode, String schDate, boolean forcePlan) {
  185 + try {
  186 + List<ScheduleRealInfo> list;
  187 +
  188 + if (forcePlan)
  189 + removeRealSch(lineCode, schDate);
  190 + else
  191 + clearRAMData(lineCode);
  192 +
  193 + if (existRealSch(lineCode, schDate))
  194 + list = loadRealSch(lineCode, schDate);// 从实际排班表加载
  195 + else {
  196 + list = loadPlanSch(lineCode, schDate);// 从计划排班表加载
  197 + // 写入数据库
  198 + batchSave(list);
  199 + }
  200 +
  201 + //更新线路和班次日期对照
  202 + currSchDateMap.put(lineCode, schDate);
  203 + //添加到缓存
  204 + putAll(list);
  205 +
  206 + //标记首末班
  207 + FirstAndLastHandler.marks(list);
  208 +
  209 + Set<String> lps = searchAllLP(list);
  210 + for (String lp : lps) {
  211 + //计算“起点站应到”时间
  212 + schAttrCalculator.calcQdzTimePlan(lpScheduleMap.get(lineCode + "_" + lp));
  213 + }
  214 + Set<String> cars = searchAllCars(list);
  215 + for (String nbbm : cars) {
  216 + //车辆 ——> 要执行的班次对照
  217 + reCalcExecPlan(nbbm);
  218 + }
  219 +
  220 + //分组计划用车
  221 + reCalcLineNbbms();
  222 + // 页面 翻班通知
  223 + //sendUtils.shiftSchedule(lineCode);
  224 + } catch (Exception e) {
  225 + logger.error("", e);
  226 + return -1;
  227 + }
  228 +
  229 + return 0;
  230 + }
  231 +
  232 + public int reloadSch(String lineCode) {
  233 + return reloadSch(lineCode, calcSchDate(lineCode), true);
  234 + }
  235 +
  236 + /**
  237 + * @Title: searchAllCars
  238 + * @Description: TODO(搜索班次集合中的车辆)
  239 + */
  240 + private Set<String> searchAllCars(List<ScheduleRealInfo> list) {
  241 + Set<String> cars = new HashSet<>();
  242 + for (ScheduleRealInfo sch : list)
  243 + cars.add(sch.getClZbh());
  244 +
  245 + return cars;
  246 + }
  247 +
  248 + /**
  249 + * @Title: searchAllCars
  250 + * @Description: TODO(搜索班次集合中的路牌)
  251 + */
  252 + private Set<String> searchAllLP(List<ScheduleRealInfo> list) {
  253 + Set<String> lps = new HashSet<>();
  254 + for (ScheduleRealInfo sch : list)
  255 + lps.add(sch.getLpName());
  256 +
  257 + return lps;
  258 + }
  259 +
  260 + private void putAll(List<ScheduleRealInfo> list) {
  261 + for (ScheduleRealInfo sch : list)
  262 + put(sch);
  263 + }
  264 +
  265 + /**
  266 + * @param @param lineCode 线路编码
  267 + * @param @param schDate 班次日期 yyyy-MM-dd
  268 + * @Title: removeRealSch
  269 + * @Description: TODO(清除实际排班,包括数据库和内存数据)
  270 + */
  271 + public void removeRealSch(String lineCode, String schDate) throws Exception {
  272 + try {
  273 + // 清理数据库数据
  274 + schRepository.deleteByLineCodeAndDate(lineCode + "", schDate);
  275 +
  276 + // 清理内存数据
  277 + clearRAMData(lineCode + "");
  278 + } catch (Exception e) {
  279 + logger.error("removeRealSch error, " + lineCode + " -" + schDate, e);
  280 + throw e;
  281 + }
  282 + }
  283 +
  284 + /**
  285 + * @Title: clearRAMData
  286 + * @Description: TODO(清理内存数据)
  287 + */
  288 + public void clearRAMData(String lineCode) {
  289 + int count = 0;
  290 + List<ScheduleRealInfo> remList = new ArrayList<>();
  291 + Collection<ScheduleRealInfo> all = nbbmScheduleMap.values();
  292 + for (ScheduleRealInfo sch : all) {
  293 + if (sch.getXlBm().equals(lineCode))
  294 + remList.add(sch);
  295 + }
  296 +
  297 + for (ScheduleRealInfo sch : remList) {
  298 + if (null != sch) {
  299 + nbbmScheduleMap.remove(sch.getClZbh(), sch);
  300 + id2SchedulMap.remove(sch.getId());
  301 + count++;
  302 +
  303 + //清理路牌对照
  304 + lpScheduleMap.removeAll(sch.getXlBm() + "_" + sch.getLpName());
  305 +
  306 + //清除车辆 ——> 执行班次对照
  307 + carExecutePlanMap.remove(sch.getClZbh());
  308 + }
  309 + }
  310 + //清理计划排班
  311 + schedulePlanMap.remove(lineCode);
  312 +
  313 + remList.clear();
  314 + remList = null;
  315 + logger.info(lineCode + "排班清理 " + count);
  316 + }
  317 +
  318 + /**
  319 + * @Title: existRealSch
  320 + * @Description: TODO(实际排班是否已存在)
  321 + */
  322 + public boolean existRealSch(String lineCode, String schDate) {
  323 + int count = schRepository.countByLineCodeAndDate(lineCode, schDate);
  324 + return count > 0;
  325 + }
  326 +
  327 + /**
  328 + * @Title: loadRealSch
  329 + * @Description: TODO(从实际排班表加载数据)
  330 + */
  331 + public List<ScheduleRealInfo> loadRealSch(String lineCode, String schDate) {
  332 + return schRepository.findByLineCodeAndDate(lineCode, schDate);
  333 + }
  334 +
  335 + /**
  336 + * @Title: loadPlanSch
  337 + * @Description: TODO(从计划排班表加载数据)
  338 + */
  339 + public List<ScheduleRealInfo> loadPlanSch(String lineCode, String schDate) {
  340 + //logger.info("从计划排班表恢复排班,lineCode: " + lineCode + ", schDate: " + schDate);
  341 + List<ScheduleRealInfo> realList = new ArrayList<>();
  342 +
  343 + try {
  344 + Map<String, Object> data = new HashMap<>();
  345 +
  346 + data.put("scheduleDate_eq", fmtyyyyMMdd.parseDateTime(schDate).toDate());
  347 + data.put("xlBm_eq", lineCode);
  348 +
  349 + // 查询计划排班
  350 + List<SchedulePlanInfo> planItr = cleanSchPlanItr(schPlanService.list(data).iterator());
  351 + //保存一份原始计划排班数据
  352 + schedulePlanMap.put(lineCode, planItr);
  353 +
  354 + // 转换为实际排班
  355 + realList = JSONArray.parseArray(JSON.toJSONString(planItr), ScheduleRealInfo.class);
  356 + logger.info("从计划排班表恢复排班,lineCode: " + lineCode + ", schDate: " + schDate + ", size:" + realList.size());
  357 +
  358 + Date d = new Date();
  359 + SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");
  360 + String fcsj;
  361 + for (ScheduleRealInfo sch : realList) {
  362 + sch.setScheduleDateStr(fmtyyyyMMdd.print(sch.getScheduleDate().getTime()));
  363 + sch.setRealExecDate(sch.getScheduleDateStr());
  364 + sch.setCreateDate(d);
  365 +
  366 + if (StringUtils.isEmpty(sch.getFcsj()))
  367 + sch.setFcsj("00:00");
  368 +
  369 + if (sch.getFcsj().equals("24:00"))
  370 + sch.setFcsj("23:59");
  371 +
  372 + if (sch.getFcsj().substring(0, 2).equals("24")) {
  373 + sch.setFcsj("00" + sch.getFcsj().substring(2));
  374 + }
  375 +
  376 + fcsj = sch.getFcsj().trim();
  377 + //处理一下发车时间格式没有:号的问题
  378 + if (fcsj.indexOf(":") == -1 && fcsj.length() >= 4) {
  379 + sch.setFcsj(fcsj.substring(0, 2) + ":" + fcsj.substring(2, 4));
  380 + }
  381 +
  382 + try {
  383 + sdf.parse(sch.getFcsj());
  384 + } catch (ParseException e) {
  385 + //发车时间仍然校验不过的,直接写成00:00
  386 + sch.setFcsj("00:00");
  387 + }
  388 + sch.setDfsj(sch.getFcsj());
  389 +
  390 + // 计划终点时间
  391 + if (sch.getBcsj() != null) {
  392 + sch.setZdsj(fmtHHmm.print(fmtHHmm.parseMillis(sch.getFcsj()) + (sch.getBcsj() * 60 * 1000)));
  393 + sch.setLate(false);
  394 + }
  395 +
  396 + //售票员为空设置为""字符串
  397 + if (StringUtils.isEmpty(sch.getsGh())) {
  398 + sch.setsGh("");
  399 + sch.setsName("");
  400 + }
  401 + sch.setJhlcOrig(sch.getJhlc());
  402 + //保留备注
  403 + if (StringUtils.isNotEmpty(sch.getRemark()))
  404 + sch.setRemarks(sch.getRemark());
  405 + }
  406 + } catch (Exception e) {
  407 + logger.error("", e);
  408 + }
  409 +
  410 + return realList;
  411 + }
  412 +
  413 +
  414 + public synchronized long getId(){
  415 + if(sch_max_id==-1){
  416 + sch_max_id = schRepository.getMaxId();
  417 + if(null == sch_max_id)
  418 + sch_max_id = 3000L;//留一点空间补数据用
  419 + sch_max_id += 5;
  420 + }
  421 + else
  422 + sch_max_id ++;
  423 + return sch_max_id;
  424 + }
  425 +
  426 + /**
  427 + * @Title: batchSave
  428 + * @Description: TODO(批量入库)
  429 + */
  430 + private void batchSave(List<ScheduleRealInfo> list) {
  431 + SimpleDateFormat sdfyyyyMMdd = new SimpleDateFormat("yyyy-MM-dd");
  432 + for (ScheduleRealInfo item : list) {
  433 + item.setSpId(item.getId());// 保留原始的计划ID
  434 + item.setId(getId());// 设置ID
  435 + item.setScheduleDateStr(sdfyyyyMMdd.format(item.getScheduleDate()));
  436 + }
  437 +
  438 + //编程式事务
  439 + DataSourceTransactionManager tran = new DataSourceTransactionManager(jdbcTemplate.getDataSource());
  440 + DefaultTransactionDefinition def = new DefaultTransactionDefinition();
  441 + def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
  442 + TransactionStatus status = tran.getTransaction(def);
  443 +
  444 + try{
  445 + final List<ScheduleRealInfo> pstList = list;
  446 + //写入
  447 + jdbcTemplate.batchUpdate("insert into bsth_c_s_sp_info_real(id,bc_type,bcs,bcsj,cl_zbh,create_date,dfsj,directive_state,fcno,fcsj,fcsj_actual,j_gh,j_name,jhlc,lp_name,qdz_code,qdz_name,real_exec_date,remarks,s_gh,s_name,schedule_date,schedule_date_str,sflj,sp_id,status,update_date,xl_bm,xl_dir,xl_name,zdsj,zdsj_actual,zdz_code,zdz_name,ccno,df_auto,fgs_bm,fgs_name,gs_bm,gs_name,online,adjust_exps,reissue,jhlc_orig,sigin_compate,drift_status,cc_service,major_station_name)" +
  448 + " VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)", new BatchPreparedStatementSetter() {
  449 + @Override
  450 + public void setValues(PreparedStatement ps, int i) throws SQLException {
  451 + ScheduleRealInfo sch = pstList.get(i);
  452 + ps.setLong(1, sch.getId());
  453 + ps.setString(2, sch.getBcType());
  454 + ps.setInt(3, sch.getBcs()==null?0:sch.getBcs());
  455 + ps.setInt(4, sch.getBcsj()==null?0:sch.getBcsj());
  456 + ps.setString(5, sch.getClZbh());
  457 + ps.setTimestamp(6, new java.sql.Timestamp(sch.getCreateDate().getTime()));
  458 + ps.setString(7, sch.getDfsj());
  459 + ps.setInt(8, sch.getDirectiveState());
  460 + ps.setInt(9, sch.getFcno()==null?0:sch.getFcno());
  461 + ps.setString(10, sch.getFcsj());
  462 + ps.setString(11, sch.getFcsjActual());
  463 + ps.setString(12, sch.getjGh());
  464 + ps.setString(13, sch.getjName());
  465 + ps.setDouble(14, sch.getJhlc());
  466 + ps.setString(15, sch.getLpName());
  467 + ps.setString(16, sch.getQdzCode());
  468 + ps.setString(17, sch.getQdzName());
  469 + ps.setString(18, sch.getRealExecDate());
  470 + ps.setString(19, sch.getRemarks());
  471 + ps.setString(20, sch.getsGh());
  472 + ps.setString(21, sch.getsName());
  473 + ps.setTimestamp(22, new java.sql.Timestamp(sch.getScheduleDate().getTime()));
  474 + ps.setString(23, sch.getScheduleDateStr());
  475 + ps.setBoolean(24, sch.isSflj());
  476 + ps.setLong(25, sch.getSpId());
  477 + ps.setInt(26, sch.getStatus());
  478 + ps.setTimestamp(27, new java.sql.Timestamp(sch.getUpdateDate().getTime()));
  479 + ps.setString(28, sch.getXlBm());
  480 + ps.setString(29, sch.getXlDir());
  481 + ps.setString(30, sch.getXlName());
  482 + ps.setString(31, sch.getZdsj());
  483 + ps.setString(32, sch.getZdsjActual());
  484 + ps.setString(33, sch.getZdzCode());
  485 + ps.setString(34, sch.getZdzName());
  486 + ps.setInt(35, sch.getCcno()==null?0:sch.getCcno());
  487 + ps.setBoolean(36, sch.isDfAuto());
  488 + ps.setString(37, sch.getFgsBm());
  489 + ps.setString(38, sch.getFgsName());
  490 + ps.setString(39, sch.getGsBm());
  491 + ps.setString(40, sch.getGsName());
  492 + ps.setBoolean(41, sch.isOnline());
  493 + ps.setString(42, sch.getAdjustExps());
  494 + ps.setBoolean(43, sch.isReissue());
  495 + ps.setDouble(44, sch.getJhlcOrig());
  496 + ps.setInt(45, sch.getSiginCompate());
  497 + ps.setInt(46, sch.getDriftStatus());
  498 + ps.setBoolean(47, sch.isCcService());
  499 + ps.setString(48, sch.getMajorStationName());
  500 + }
  501 +
  502 + @Override
  503 + public int getBatchSize() {
  504 + return pstList.size();
  505 + }
  506 + });
  507 +
  508 + tran.commit(status);
  509 + }catch (Exception e){
  510 + tran.rollback(status);
  511 + logger.error("real schedule batchSave error...", e);
  512 + }
  513 + // 入库
  514 + //new BatchSaveUtils<ScheduleRealInfo>().saveList(list, ScheduleRealInfo.class);
  515 + }
  516 +
  517 + public List<SchedulePlanInfo> cleanSchPlanItr(Iterator<SchedulePlanInfo> itrab) {
  518 + List<SchedulePlanInfo> list = new ArrayList<>();
  519 +
  520 + SchedulePlanInfo sp;
  521 + while (itrab.hasNext()) {
  522 + sp = itrab.next();
  523 + sp.setSchedulePlan(null);
  524 + sp.setCreateBy(null);
  525 + sp.setUpdateBy(null);
  526 + list.add(sp);
  527 + }
  528 + return list;
  529 + }
  530 +
  531 + /**
  532 + * @Title: findByLineCode
  533 + * @Description: TODO(lineCode 获取班次)
  534 + */
  535 + public List<ScheduleRealInfo> findByLineCode(String lineCode) {
  536 + List<ScheduleRealInfo> rs = new ArrayList<>();
  537 +
  538 + Collection<ScheduleRealInfo> schs = nbbmScheduleMap.values();
  539 + for (ScheduleRealInfo sch : schs) {
  540 + if (sch.getXlBm().equals(lineCode))
  541 + rs.add(sch);
  542 + }
  543 + return rs;
  544 + }
  545 +
  546 + /**
  547 + * @Title: findByLineCode
  548 + * @Description: TODO(lineList 获取班次)
  549 + */
  550 + public Map<String, Collection<ScheduleRealInfo>> findByLineCodes(List<String> lineList) {
  551 + ArrayListMultimap<String, ScheduleRealInfo> mMap = ArrayListMultimap.create();
  552 +
  553 + Collection<ScheduleRealInfo> schs = nbbmScheduleMap.values();
  554 + for (ScheduleRealInfo sch : schs) {
  555 + if (lineList.contains(sch.getXlBm())) {
  556 + mMap.put(sch.getXlBm(), sch);
  557 + }
  558 + }
  559 + return mMap.asMap();
  560 + }
  561 +
  562 + /**
  563 + * @Title: findCarByLineCode
  564 + * @Description: TODO(线路下运营的车辆)
  565 + */
  566 + public Set<String> findCarByLineCode(String lineCode) {
  567 + /*Set<String> rs = new HashSet<>();
  568 +
  569 + Collection<ScheduleRealInfo> schs = nbbmScheduleMap.values();
  570 + for (ScheduleRealInfo sch : schs) {
  571 + if (sch.getXlBm().equals(lineCode))
  572 + rs.add(sch.getClZbh());
  573 + }
  574 +*/
  575 + return lineNbbmsMap.get(lineCode);
  576 + }
  577 +
  578 + public List<ScheduleRealInfo> findByNbbm(String nbbm) {
  579 + return nbbmScheduleMap.get(nbbm);
  580 + }
  581 +
  582 + /**
  583 + * @Title: findByLineAndUpDown
  584 + * @Description: TODO(lineCode 和走向获取班次)
  585 + */
  586 + public List<ScheduleRealInfo> findByLineAndUpDown(String lineCode, Integer upDown) {
  587 + List<ScheduleRealInfo> list = findByLineCode(lineCode), rs = new ArrayList<>();
  588 +
  589 + for (ScheduleRealInfo sch : list) {
  590 + if (sch.getXlDir().equals(upDown + ""))
  591 + rs.add(sch);
  592 + }
  593 + return rs;
  594 + }
  595 +
  596 + public ScheduleRealInfo get(long id) {
  597 + return id2SchedulMap.get(id);
  598 + }
  599 +
  600 +
  601 + /**
  602 + * @Title: next
  603 + * @Description: TODO(下一个班次)
  604 + */
  605 + public ScheduleRealInfo next(ScheduleRealInfo sch) {
  606 + List<ScheduleRealInfo> list = nbbmScheduleMap.get(sch.getClZbh());
  607 + //排序
  608 + Collections.sort(list, schDFSJComparator);
  609 + return next(list, sch);
  610 + }
  611 +
  612 +
  613 + /**
  614 + * 下一个班次
  615 + *
  616 + * @param list 班次集合
  617 + * @param sch 当前班次
  618 + * @return
  619 + */
  620 + private ScheduleRealInfo next(Collection<ScheduleRealInfo> list, ScheduleRealInfo sch) {
  621 + int outConfig = -1;
  622 + LineConfig config = lineConfigData.get(sch.getXlBm());
  623 + if (config != null)
  624 + outConfig = config.getOutConfig();
  625 +
  626 + //限定出站既出场的停车场
  627 + List<String> parks = config.findTwinsParkList();
  628 + boolean limitPark = null != parks && parks.size() > 0;
  629 + boolean flag = false;
  630 + ScheduleRealInfo next = null;
  631 + for (ScheduleRealInfo temp : list) {
  632 + if (temp.getId() == sch.getId()) {
  633 + flag = true;
  634 + continue;
  635 + }
  636 + //忽略烂班
  637 + if (temp.isDestroy())
  638 + continue;
  639 +
  640 + //出站既出场,忽略出场班次
  641 + if (outConfig == 2 && temp.getBcType().equals("out") && isEmptyMileage(temp)
  642 + && (!limitPark || parks.contains(temp.getQdzCode())))
  643 + continue;
  644 +
  645 + if (flag) {
  646 + next = temp;
  647 + break;
  648 + }
  649 + }
  650 + return next;
  651 + }
  652 +
  653 + private boolean isEmptyMileage(ScheduleRealInfo sch) {
  654 + return sch.getBcsj() == 0 || sch.getJhlcOrig().intValue() == 0;
  655 + }
  656 +
  657 + /**
  658 + * 下一个班次
  659 + *
  660 + * @param list 班次集合
  661 + * @param sch 当前班次
  662 + * @return
  663 + */
  664 + private ScheduleRealInfo next2_lp(Collection<ScheduleRealInfo> list, ScheduleRealInfo sch) {
  665 + int outConfig = -1;
  666 + LineConfig config = lineConfigData.get(sch.getXlBm());
  667 + if (config != null)
  668 + outConfig = config.getOutConfig();
  669 +
  670 + boolean flag = false;
  671 + ScheduleRealInfo next = null;
  672 + for (ScheduleRealInfo temp : list) {
  673 + if (temp.getId() == sch.getId()) {
  674 + flag = true;
  675 + continue;
  676 + }
  677 +
  678 + if (flag) {
  679 + next = temp;
  680 + break;
  681 + }
  682 + }
  683 + return next;
  684 + }
  685 +
  686 + private ScheduleRealInfo next3_lp(Collection<ScheduleRealInfo> list, ScheduleRealInfo sch) {
  687 + int outConfig = -1;
  688 + LineConfig config = lineConfigData.get(sch.getXlBm());
  689 + if (config != null)
  690 + outConfig = config.getOutConfig();
  691 +
  692 + //限定出站既出场的停车场
  693 + List<String> parks = config.findTwinsParkList();
  694 + boolean limitPark = null != parks && parks.size() > 0;
  695 + boolean flag = false;
  696 + ScheduleRealInfo next = null;
  697 + for (ScheduleRealInfo temp : list) {
  698 + if (temp.getId() == sch.getId()) {
  699 + flag = true;
  700 + continue;
  701 + }
  702 +
  703 + //出站既出场,忽略出场班次
  704 + if (outConfig == 2 && temp.getBcType().equals("out") && isEmptyMileage(temp)
  705 + && (!limitPark || parks.contains(temp.getQdzCode())))
  706 + continue;
  707 +
  708 + if (flag) {
  709 + next = temp;
  710 + break;
  711 + }
  712 + }
  713 + return next;
  714 + }
  715 +
  716 + /**
  717 + * 上一个班次
  718 + *
  719 + * @param sch
  720 + * @return
  721 + */
  722 + public ScheduleRealInfo prev(ScheduleRealInfo sch) {
  723 + List<ScheduleRealInfo> list = nbbmScheduleMap.get(sch.getClZbh());
  724 +
  725 + //boolean flag = false;
  726 + ScheduleRealInfo prev = null;
  727 + int size = list.size();
  728 +
  729 + for (int i = 0; i < size; i++) {
  730 + if (list.get(i).isDestroy())
  731 + continue;
  732 +
  733 + if (list.get(i).getId().equals(sch.getId())) {
  734 + return prev;
  735 + }
  736 + prev = list.get(i);
  737 + }
  738 + return prev;
  739 + }
  740 +
  741 + /**
  742 + * 是否是首班出场
  743 + *
  744 + * @param sch
  745 + * @return
  746 + */
  747 + public boolean isFirstOut(ScheduleRealInfo sch) {
  748 + List<ScheduleRealInfo> list = nbbmScheduleMap.get(sch.getClZbh());
  749 + try {
  750 + if (list.get(0) == sch && sch.getBcType().equals("out"))
  751 + return true;
  752 + } catch (IndexOutOfBoundsException e) {
  753 + logger.error("小小的数组越界,无伤大雅!");
  754 + }
  755 + return false;
  756 + }
  757 +
  758 + public void put(ScheduleRealInfo sch) {
  759 + schAttrCalculator
  760 + .calcRealDate(sch)
  761 + .calcAllTimeByFcsj(sch);
  762 +
  763 + nbbmScheduleMap.put(sch.getClZbh(), sch);
  764 +
  765 + //主键索引
  766 + id2SchedulMap.put(sch.getId(), sch);
  767 + //路牌对照表
  768 + addLPMapp(sch);
  769 +
  770 + //跨24点的,再save一次
  771 + if (!sch.getRealExecDate().equals(sch.getScheduleDateStr()))
  772 + save(sch);
  773 + }
  774 +
  775 + public void addLPMapp(ScheduleRealInfo sch) {
  776 + lpScheduleMap.put(sch.getXlBm() + "_" + sch.getLpName(), sch);
  777 + }
  778 +
  779 + public void delete(ScheduleRealInfo sch) {
  780 + if (!sch.isSflj())
  781 + return;
  782 +
  783 + nbbmScheduleMap.remove(sch.getClZbh(), sch);
  784 + id2SchedulMap.remove(sch.getId());
  785 + lpScheduleMap.remove(sch.getXlBm() + "_" + sch.getLpName(), sch);
  786 +
  787 + //如果正在执行该班次
  788 + if (carExecutePlanMap.get(sch.getClZbh()) == sch) {
  789 + //重新计算车辆当前执行班次
  790 + reCalcExecPlan(sch.getClZbh());
  791 + }
  792 + }
  793 +
  794 + public List<ScheduleRealInfo> updateQdzTimePlan(String lpName) {
  795 + List<ScheduleRealInfo> list = lpScheduleMap.get(lpName);
  796 + Collections.sort(list, schFCSJComparator);
  797 + return schAttrCalculator.updateQdzTimePlan(list);
  798 + }
  799 +
  800 + public List<ScheduleRealInfo> updateQdzTimePlan(ScheduleRealInfo sch) {
  801 + return updateQdzTimePlan(sch.getXlBm() + "_" + sch.getLpName());
  802 + }
  803 +
  804 + /**
  805 + * @Title: doneSum
  806 + * @Description: TODO(已完成班次总数)
  807 + */
  808 + public int doneSum(String clZbh) {
  809 + List<ScheduleRealInfo> list = nbbmScheduleMap.get(clZbh);
  810 + int rs = 0;
  811 +
  812 + for (ScheduleRealInfo sch : list) {
  813 + if (sch.getStatus() == 2 && !sch.isDestroy())
  814 + rs++;
  815 + }
  816 + return rs;
  817 + }
  818 +
  819 + public void save(ScheduleRealInfo sch) {
  820 + sch.setUpdateDate(new Date());
  821 + pstBuffer.add(sch);
  822 + }
  823 +
  824 +
  825 + /**
  826 + * @Title: nextByBcType
  827 + * @Description: TODO(获取下一个指定班次类型的班次)
  828 + */
  829 + public ScheduleRealInfo nextByBcType(String nbbm, String bcType) {
  830 + List<ScheduleRealInfo> list = findByBcType(nbbm, bcType);
  831 +
  832 + Collections.sort(list, schFCSJComparator);
  833 + ScheduleRealInfo sch = null;
  834 + for (ScheduleRealInfo temp : list) {
  835 + if (temp.getFcsjActual() == null) {
  836 + sch = temp;
  837 + break;
  838 + }
  839 + }
  840 +
  841 + return sch;
  842 + }
  843 +
  844 +
  845 + /**
  846 + * 搜索离当前时间最近的一个指定类型的班次
  847 + *
  848 + * @param nbbm
  849 + * @param bcType
  850 + * @return
  851 + */
  852 + public ScheduleRealInfo searchNearByBcType(String nbbm, String bcType) {
  853 + List<ScheduleRealInfo> list = findByBcType(nbbm, bcType);
  854 + Collections.sort(list, schFCSJComparator);
  855 +
  856 + long t = System.currentTimeMillis();
  857 + int distance = -1, diff;
  858 +
  859 + ScheduleRealInfo sch = null;
  860 + for (ScheduleRealInfo temp : list) {
  861 + diff = (int) Math.abs(temp.getDfsjT() - t);
  862 + if (diff < distance || distance == -1) {
  863 + sch = temp;
  864 + distance = diff;
  865 + }
  866 + }
  867 + return sch;
  868 + }
  869 +
  870 + public List<ScheduleRealInfo> findByBcType(String nbbm, String bcType) {
  871 + List<ScheduleRealInfo> all = nbbmScheduleMap.get(nbbm), outList = new ArrayList<>();
  872 +
  873 + for (ScheduleRealInfo sch : all) {
  874 + if (sch.getBcType().equals(bcType))
  875 + outList.add(sch);
  876 + }
  877 + return outList;
  878 + }
  879 +
  880 + public Collection<ScheduleRealInfo> findAll() {
  881 + return nbbmScheduleMap.values();
  882 + }
  883 +
  884 + public Collection<ScheduleRealInfo> findAllByLpContainer() {
  885 + return lpScheduleMap.values();
  886 + }
  887 +
  888 + public Collection<ScheduleRealInfo> findAllByIdContainer() {
  889 + return id2SchedulMap.values();
  890 + }
  891 +
  892 + public int getPstSize() {
  893 + return pstBuffer.size();
  894 + }
  895 +
  896 + public boolean addExecPlan(ScheduleRealInfo sch) {
  897 + ScheduleRealInfo oldExec = executeCurr(sch.getClZbh());
  898 + if (sch != null){
  899 + if(sch.getStatus()==2)
  900 + reCalcExecPlan(sch.getClZbh());
  901 + else
  902 + carExecutePlanMap.put(sch.getClZbh(), sch);
  903 + }
  904 + else
  905 + carExecutePlanMap.remove(sch.getClZbh());
  906 +
  907 + // rfid需要在新的执行班次前复位
  908 + RfidDataHandler.resetRfid(sch.getClZbh());
  909 +
  910 + return executeCurr(sch.getClZbh()) != oldExec;
  911 + }
  912 +
  913 + public void removeExecPlan(String clzbh) {
  914 + carExecutePlanMap.remove(clzbh);
  915 + }
  916 +
  917 + public Map<String, ScheduleRealInfo> execPlanMap() {
  918 + return carExecutePlanMap;
  919 + }
  920 +
  921 + /**
  922 + * 车辆当前执行的班次
  923 + *
  924 + * @param nbbm
  925 + * @return
  926 + */
  927 + public ScheduleRealInfo executeCurr(String nbbm) {
  928 + if(StringUtils.isEmpty(nbbm))
  929 + return null;
  930 + return carExecutePlanMap.get(nbbm);
  931 + }
  932 +
  933 + /**
  934 + * @param @param sch
  935 + * @param @param newClZbh 新的车辆自编号
  936 + * @Title: changeCar
  937 + * @Description: TODO(班次换车) 返回有更新的班次
  938 + */
  939 + public List<ScheduleRealInfo> changeCar(ScheduleRealInfo sch, String newClZbh) {
  940 + List<ScheduleRealInfo> ups = new ArrayList<>();
  941 +
  942 + String oldClZbh = sch.getClZbh();
  943 + //变更相关映射信息
  944 + nbbmScheduleMap.remove(sch.getClZbh(), sch);
  945 +
  946 + sch.setClZbh(newClZbh);
  947 + if (!nbbmScheduleMap.containsEntry(newClZbh, sch)) {
  948 + nbbmScheduleMap.put(newClZbh, sch);
  949 + }
  950 +
  951 + //重新计算车辆当前执行班次
  952 + reCalcExecPlan(newClZbh);
  953 + reCalcExecPlan(oldClZbh);
  954 + //重新分组计划用车
  955 + reCalcLineNbbms();
  956 + return ups;
  957 + }
  958 +
  959 + public void removeNbbm2SchMapp(ScheduleRealInfo sch) {
  960 + nbbmScheduleMap.remove(sch.getClZbh(), sch);
  961 + }
  962 +
  963 + public void addNbbm2SchMapp(ScheduleRealInfo sch) {
  964 + nbbmScheduleMap.put(sch.getClZbh(), sch);
  965 + }
  966 +
  967 + public void reCalcExecPlan(String nbbm) {
  968 + List<ScheduleRealInfo> list = nbbmScheduleMap.get(nbbm);
  969 + Collections.sort(list, schDFSJComparator);
  970 +
  971 + ScheduleRealInfo sch = schAttrCalculator.calcCurrentExecSch(list);
  972 + if(null != sch)
  973 + carExecutePlanMap.put(nbbm, sch);
  974 + else
  975 + carExecutePlanMap.remove(nbbm);
  976 + }
  977 +
  978 + /**
  979 + * 空驶任务?
  980 + * 出场、进场、直放、两点间空驶
  981 + * @param sch
  982 + * @return
  983 + */
  984 + public static boolean emptyService(ScheduleRealInfo sch){
  985 + String type = sch.getBcType();
  986 + return type.equals("out") || type.equals("in") || type.equals("venting") || type.equals("ldks");
  987 + }
  988 +
  989 + @Autowired
  990 + JdbcTemplate jdbcTemplate;
  991 +
  992 + /**
  993 + * 删除实际排班
  994 + *
  995 + * @param lineCode
  996 + * @return
  997 + */
  998 + public Map<String, Object> deleteRealSchedule(String lineCode) {
  999 + Map<String, Object> rs = new HashMap<>();
  1000 +
  1001 + try {
  1002 + String rq = currSchDateMap.get(lineCode);
  1003 + if (StringUtils.isNotEmpty(rq)) {
  1004 + List<ScheduleRealInfo> all = findByLineCode(lineCode);
  1005 +
  1006 + if(null != all && all.size() > 0){
  1007 + //解除gps 和班次之间的关联
  1008 + List<ScheduleRealInfo> unions = calcUnion(all, carExecutePlanMap.values());
  1009 + for (ScheduleRealInfo sch : unions) {
  1010 + removeExecPlan(sch.getClZbh());
  1011 + }
  1012 + //解除调度指令和班次的外键约束
  1013 + StringBuilder inStr = new StringBuilder("(");
  1014 + for (ScheduleRealInfo sch : all) {
  1015 + inStr.append(sch.getId() + ",");
  1016 + }
  1017 + inStr.deleteCharAt(inStr.length() - 1).append(")");
  1018 + jdbcTemplate.update(Constants.MULTI_REMOVE_DIRECTIVE_SCH_FK + " " + inStr.toString());
  1019 + }
  1020 +
  1021 + //删除班次数据
  1022 + removeRealSch(lineCode, rq);
  1023 +
  1024 + }
  1025 + rs.put("status", ResponseCode.SUCCESS);
  1026 + } catch (Exception e) {
  1027 + logger.error("", e);
  1028 + rs.put("status", ResponseCode.ERROR);
  1029 + if (e instanceof DataIntegrityViolationException)
  1030 + rs.put("msg", "失败,违反数据约束!!");
  1031 + else
  1032 + rs.put("msg", e.getMessage());
  1033 + }
  1034 +
  1035 + return rs;
  1036 + }
  1037 +
  1038 + /**
  1039 + * 计算并集
  1040 + *
  1041 + * @param c1
  1042 + * @param c2
  1043 + * @return
  1044 + */
  1045 + public List<ScheduleRealInfo> calcUnion(Collection<ScheduleRealInfo> c1, Collection<ScheduleRealInfo> c2) {
  1046 + List<ScheduleRealInfo> rs = new ArrayList<>();
  1047 +
  1048 + for (ScheduleRealInfo sch : c1) {
  1049 + if (c2.contains(sch)) {
  1050 + rs.add(sch);
  1051 + }
  1052 + }
  1053 + return rs;
  1054 + }
  1055 +
  1056 + /**
  1057 + * 覆盖一辆车的所有班次
  1058 + *
  1059 + * @param nbbm
  1060 + * @param sets
  1061 + */
  1062 + public void replaceByNbbm(String nbbm, Collection<ScheduleRealInfo> sets) {
  1063 + nbbmScheduleMap.removeAll(nbbm);
  1064 + nbbmScheduleMap.putAll(nbbm, sets);
  1065 + }
  1066 +
  1067 + /**
  1068 + * 获取该班次所在路牌的下一个班次
  1069 + *
  1070 + * @param sch
  1071 + * @return
  1072 + */
  1073 + public ScheduleRealInfo nextByLp(ScheduleRealInfo sch) {
  1074 + List<ScheduleRealInfo> list = lpScheduleMap.get(sch.getXlBm() + "_" + sch.getLpName());
  1075 + Collections.sort(list, schFCSJComparator);
  1076 + return next3_lp(list, sch);
  1077 + }
  1078 +
  1079 + /**
  1080 + * 获取该班次所在路牌的下一个班次,不考虑场既是站
  1081 + *
  1082 + * @param sch
  1083 + * @return
  1084 + */
  1085 + public ScheduleRealInfo nextByLp2(ScheduleRealInfo sch) {
  1086 + List<ScheduleRealInfo> list = lpScheduleMap.get(sch.getXlBm() + "_" + sch.getLpName());
  1087 + Collections.sort(list, schFCSJComparator);
  1088 + return next2_lp(list, sch);
  1089 + }
  1090 +
  1091 + public ArrayListMultimap<String, ScheduleRealInfo> getLpScheduleMap() {
  1092 + return lpScheduleMap;
  1093 + }
  1094 +
  1095 + /**
  1096 + * 重新全量计算路牌下的班次关联性
  1097 + * 临时性的函数
  1098 + */
  1099 + public void _test_reCalcLpSch() {
  1100 + Map<String ,Collection<ScheduleRealInfo>> map = lpScheduleMap.asMap();
  1101 + Set<String> ks = map.keySet();
  1102 + for(String k : ks){
  1103 + schAttrCalculator.calcQdzTimePlan(new ArrayList<ScheduleRealInfo>(map.get(k)));
  1104 + }
  1105 + }
  1106 +
  1107 + public int dbCount(String lineCode, String currSchDate) {
  1108 + int count = -1;
  1109 +
  1110 + try{
  1111 + count = jdbcTemplate.queryForObject("select count(*) from bsth_c_s_sp_info_real where schedule_date='"+currSchDate+"' and xl_bm='"+lineCode+"'", java.lang.Integer.class);
  1112 +
  1113 + }catch (Exception e){
  1114 + logger.error("", e);
  1115 + }
  1116 + return count;
  1117 + }
  1118 +
  1119 + /**
  1120 + * 重新计算ID对照map
  1121 + */
  1122 + public int reCalcIdMaps(){
  1123 + Collection<ScheduleRealInfo> all = findAll();
  1124 + ConcurrentMap<Long, ScheduleRealInfo> id2SchedulMapCopy = new ConcurrentHashMap<>();
  1125 +
  1126 + for(ScheduleRealInfo sch : all){
  1127 + id2SchedulMapCopy.put(sch.getId(), sch);
  1128 + }
  1129 +
  1130 + id2SchedulMap = id2SchedulMapCopy;
  1131 +
  1132 + return id2SchedulMap.size();
  1133 + }
  1134 +
  1135 + /**
  1136 + * 重新计算线路计划用车
  1137 + */
  1138 + public void reCalcLineNbbms(){
  1139 + HashMultimap<String, String> multimap = HashMultimap.create();
  1140 +
  1141 + Collection<ScheduleRealInfo> schs = nbbmScheduleMap.values();
  1142 + for (ScheduleRealInfo sch : schs) {
  1143 + multimap.put(sch.getXlBm(), sch.getClZbh());
  1144 + }
  1145 +
  1146 + lineNbbmsMap = multimap;
  1147 + }
  1148 +
  1149 + public String sizeString(){
  1150 + return id2SchedulMap.size() + "/" + nbbmScheduleMap.size();
  1151 + }
  1152 +
  1153 +
  1154 + /**
  1155 + * 按公司编码分组数据
  1156 + */
  1157 + public void groupByGsbm(){
  1158 + Collection<ScheduleRealInfo> all = findAll();
  1159 + ListMultimap<String, ScheduleRealInfo> gsBmMaps = ArrayListMultimap.create();
  1160 +
  1161 + for(ScheduleRealInfo sch : all){
  1162 + gsBmMaps.put(sch.getGsBm(), sch);
  1163 + }
  1164 +
  1165 + if(gsBmMaps.size() > 0){
  1166 + gsBmScheduleMap = null;
  1167 + gsBmScheduleMap = gsBmMaps;
  1168 + }
  1169 + }
  1170 +
  1171 + public Collection<ScheduleRealInfo> findByGsbm(String gsbm){
  1172 + return gsBmScheduleMap.get(gsbm);
  1173 + }
  1174 + /**
  1175 + * 删除班次,删除内存中未清理掉的非当天的班次
  1176 + * @createDate 2019.05.13
  1177 + * @author zhangxianzhou
  1178 + * @param sch
  1179 + */
  1180 + public void deleteBC(ScheduleRealInfo sch) {
  1181 + nbbmScheduleMap.remove(sch.getClZbh(), sch);
  1182 + id2SchedulMap.remove(sch.getId());
  1183 + lpScheduleMap.remove(sch.getXlBm() + "_" + sch.getLpName(), sch);
  1184 + //如果正在执行该班次
  1185 + if (carExecutePlanMap.get(sch.getClZbh()) == sch) {
  1186 + //重新计算车辆当前执行班次
  1187 + reCalcExecPlan(sch.getClZbh());
  1188 + }
  1189 + }
  1190 +
  1191 + /**
  1192 + ** 用于重置维修上报计数,一般只应该在翻班的时候调用
  1193 + */
  1194 + public void resetRepairReport(String incode) {
  1195 + incode2report.remove(incode);
  1196 + }
  1197 +
  1198 + public RepairReport getLastestRepairReport(String incode) {
  1199 + return incode2report.get(incode);
  1200 + }
  1201 +
  1202 + public void setLastestRepairReport(RepairReport rr) {
  1203 + incode2report.put(rr.getIncode(), rr);
  1204 + }
1201 1205 }
1202 1206 \ No newline at end of file
... ...
src/main/java/com/bsth/entity/card_signing/CardSigning.java 0 → 100644
  1 +package com.bsth.entity.card_signing;
  2 +
  3 +import javax.persistence.GeneratedValue;
  4 +import javax.persistence.Id;
  5 +
  6 +public class CardSigning {
  7 + /* 主键*/
  8 + @Id
  9 + @GeneratedValue
  10 + private Integer id;
  11 + //公司名称
  12 + private String gsName;
  13 + //公司代码
  14 + private String gsBm;
  15 + //分公司名称
  16 + private String fgsName;
  17 + //分公司代码
  18 + private String fgsBm;
  19 + //线路名称
  20 + private String xlName;
  21 + //线路代码
  22 + private String xlBm;
  23 + //时间
  24 + private String scheduleDateStr;
  25 + //班次数
  26 + private Integer bcs;
  27 + //签卡数
  28 + private Integer qks;
  29 + /* //签卡率
  30 + private Double qkl;*/
  31 + //签卡率
  32 + private String qklName;
  33 + //人卡故障数
  34 + private Integer rkgzs;
  35 + /*//人卡故障率
  36 + private double rkgzl;*/
  37 + //人卡故障率
  38 + private String rkgzlName;
  39 + //车卡故障数
  40 + private Integer ckgzs;
  41 + /* //车卡故障率
  42 + private double ckgzl;*/
  43 + //车卡故障率
  44 + private String ckgzlName;
  45 + //起点站
  46 + private String qdzName;
  47 + //rfid状态
  48 + private Integer rfidState;
  49 + //是否故障
  50 + private String rfidName;
  51 + /** 计划发车时间(格式 HH:mm) */
  52 + private String fcsj;
  53 + /** 实际发车时间*/
  54 + private String fcsjActual;
  55 +
  56 + public String getFcsj() {
  57 + return fcsj;
  58 + }
  59 +
  60 + public void setFcsj(String fcsj) {
  61 + this.fcsj = fcsj;
  62 + }
  63 +
  64 + public String getFcsjActual() {
  65 + return fcsjActual;
  66 + }
  67 +
  68 + public void setFcsjActual(String fcsjActual) {
  69 + this.fcsjActual = fcsjActual;
  70 + }
  71 +
  72 + public String getQdzName() {
  73 + return qdzName;
  74 + }
  75 +
  76 + public void setQdzName(String qdzName) {
  77 + this.qdzName = qdzName;
  78 + }
  79 +
  80 + public Integer getRfidState() {
  81 + return rfidState;
  82 + }
  83 +
  84 + public void setRfidState(Integer rfidState) {
  85 + this.rfidState = rfidState;
  86 + }
  87 +
  88 + public String getRfidName() {
  89 + return rfidName;
  90 + }
  91 +
  92 + public Integer getId() {
  93 + return id;
  94 + }
  95 +
  96 + public void setId(Integer id) {
  97 + this.id = id;
  98 + }
  99 +
  100 + public String getGsName() {
  101 + return gsName;
  102 + }
  103 +
  104 + public void setGsName(String gsName) {
  105 + this.gsName = gsName;
  106 + }
  107 +
  108 + public String getGsBm() {
  109 + return gsBm;
  110 + }
  111 +
  112 + public void setGsBm(String gsBm) {
  113 + this.gsBm = gsBm;
  114 + }
  115 +
  116 + public String getFgsName() {
  117 + return fgsName;
  118 + }
  119 +
  120 + public void setFgsName(String fgsName) {
  121 + this.fgsName = fgsName;
  122 + }
  123 +
  124 + public String getFgsBm() {
  125 + return fgsBm;
  126 + }
  127 +
  128 + public Integer getBcs() {
  129 + return bcs;
  130 + }
  131 +
  132 + public void setBcs(Integer bcs) {
  133 + this.bcs = bcs;
  134 + }
  135 +
  136 + public void setFgsBm(String fgsBm) {
  137 + this.fgsBm = fgsBm;
  138 + }
  139 +
  140 + public String getXlName() {
  141 + return xlName;
  142 + }
  143 +
  144 + public void setXlName(String xlName) {
  145 + this.xlName = xlName;
  146 + }
  147 +
  148 + public String getXlBm() {
  149 + return xlBm;
  150 + }
  151 +
  152 + public void setXlBm(String xlBm) {
  153 + this.xlBm = xlBm;
  154 + }
  155 +
  156 + public String getScheduleDateStr() {
  157 + return scheduleDateStr;
  158 + }
  159 +
  160 + public void setScheduleDateStr(String scheduleDateStr) {
  161 + this.scheduleDateStr = scheduleDateStr;
  162 + }
  163 +
  164 + public Integer getQks() {
  165 + return qks;
  166 + }
  167 +
  168 + public void setQks(Integer qks) {
  169 + this.qks = qks;
  170 + }
  171 +
  172 + public Integer getRkgzs() {
  173 + return rkgzs;
  174 + }
  175 +
  176 + public void setRkgzs(Integer rkgzs) {
  177 + this.rkgzs = rkgzs;
  178 + }
  179 +
  180 + public Integer getCkgzs() {
  181 + return ckgzs;
  182 + }
  183 +
  184 + public void setCkgzs(Integer ckgzs) {
  185 + this.ckgzs = ckgzs;
  186 + }
  187 +
  188 + public String getQklName() {
  189 + return qklName;
  190 + }
  191 +
  192 + public void setQklName(String qklName) {
  193 + this.qklName = qklName;
  194 + }
  195 +
  196 + public String getRkgzlName() {
  197 + return rkgzlName;
  198 + }
  199 +
  200 + public void setRkgzlName(String rkgzlName) {
  201 + this.rkgzlName = rkgzlName;
  202 + }
  203 +
  204 + public String getCkgzlName() {
  205 + return ckgzlName;
  206 + }
  207 +
  208 + public void setCkgzlName(String ckgzlName) {
  209 + this.ckgzlName = ckgzlName;
  210 + }
  211 +
  212 + public void setRfidName(String rfidName) {
  213 + this.rfidName = rfidName;
  214 + }
  215 +}
... ...
src/main/java/com/bsth/service/report/CardSigningService.java 0 → 100644
  1 +package com.bsth.service.report;
  2 +
  3 +import com.bsth.entity.card_signing.CardSigning;
  4 +
  5 +import java.util.List;
  6 +import java.util.Map;
  7 +
  8 +public interface CardSigningService {
  9 +
  10 + public List<CardSigning> cardList(Map<String, Object> map);
  11 +
  12 +
  13 + public List<CardSigning> calcListSheet(Map<String, Object> map);
  14 +
  15 +
  16 + public List<CardSigning> calcSheet(Map<String, Object> map);
  17 +
  18 +
  19 +
  20 +}
... ...
src/main/java/com/bsth/service/report/impl/CardSigningServiceImpl.java 0 → 100644
  1 +package com.bsth.service.report.impl;
  2 +
  3 +import com.bsth.entity.card_signing.CardSigning;
  4 +import com.bsth.service.report.CardSigningService;
  5 +import com.bsth.util.ReportUtils;
  6 +import org.springframework.beans.factory.annotation.Autowired;
  7 +import org.springframework.jdbc.core.JdbcTemplate;
  8 +import org.springframework.jdbc.core.RowMapper;
  9 +import org.springframework.stereotype.Service;
  10 +
  11 +import java.sql.ResultSet;
  12 +import java.sql.SQLException;
  13 +import java.text.DecimalFormat;
  14 +import java.util.*;
  15 +
  16 +@Service
  17 +public class CardSigningServiceImpl implements CardSigningService {
  18 +
  19 + @Autowired
  20 + JdbcTemplate jdbcTemplate;
  21 + @Override
  22 + public List<CardSigning> cardList(Map<String, Object> map) {
  23 + final DecimalFormat df = new DecimalFormat("0.00");
  24 + String line="";
  25 + if(map.get("line")!=null){
  26 + line =map.get("line").toString().trim();
  27 + }
  28 + String gs="";
  29 + if(map.get("gs")!=null){
  30 + gs=map.get("gs").toString().trim();
  31 + }
  32 + String fgs="";
  33 + if(map.get("fgs")!=null){
  34 + fgs=map.get("fgs").toString().trim();
  35 + }
  36 + String nature="0";
  37 + if(map.get("nature")!=null){
  38 + nature=map.get("nature").toString();
  39 + }
  40 +
  41 + String date=map.get("date").toString();
  42 + String endDate=map.get("endDate").toString();
  43 + String sql="select gs_name,gs_bm,fgs_name,fgs_bm,xl_name,xl_bm,sum(bcs) as bcs,sum(qks) as qks," +
  44 + " avg(qkl) as qkl,sum(rkgzs) as rkgzs,avg(rkgzl) as rkgzl ,avg(ckgzs) as ckgzs ,avg(ckgzl) as ckgzl " +
  45 + "from card_signing where schedule_date_str BETWEEN '"+date+"' and '"+endDate+"'";
  46 + if(line.trim().equals("")){
  47 + sql +=" and gs_bm = '"+gs+"' and fgs_bm like '%"+fgs+"%'";
  48 + }else{
  49 + sql +=" and xl_bm ='"+line+"'";
  50 + }
  51 + sql +=" group by xl_name";
  52 + //条件下所有路单
  53 + List<CardSigning> list=jdbcTemplate.query(sql,
  54 + new RowMapper<CardSigning>(){
  55 + @Override
  56 + public CardSigning mapRow(ResultSet rs, int rowNum) throws SQLException {
  57 + CardSigning s=new CardSigning();
  58 + s.setGsName(rs.getString("gs_name"));
  59 + s.setGsBm(rs.getString("gs_bm"));
  60 + s.setFgsName(rs.getString("fgs_name"));
  61 + s.setFgsBm(rs.getString("fgs_bm"));
  62 + s.setXlName(rs.getString("xl_name"));
  63 + s.setXlBm(rs.getString("xl_bm"));
  64 + s.setBcs(rs.getInt("bcs"));
  65 + s.setQks(rs.getInt("qks"));
  66 + s.setQklName(df.format(rs.getDouble("qkl"))+"%");
  67 + s.setRkgzs(rs.getInt("rkgzs"));
  68 + s.setRkgzlName(df.format(rs.getDouble("rkgzl"))+"%");
  69 + s.setCkgzs(rs.getInt("ckgzs"));
  70 + s.setCkgzlName(df.format(rs.getDouble("ckgzl"))+"%");
  71 + return s;
  72 + }
  73 + });
  74 +
  75 +
  76 + if(map.get("type").equals("export")){
  77 + List<Map<String, Object>> listmap=new ArrayList<Map<String, Object>>();
  78 + for (CardSigning c:list) {
  79 + Map<String, Object> m=new HashMap<String,Object>();
  80 + m.put("gs", c.getGsName());
  81 + m.put("fgs", c.getFgsName());
  82 + m.put("line", c.getXlName());
  83 + m.put("bcs", c.getBcs());
  84 + m.put("qks", c.getQks());
  85 + m.put("qkl", c.getQklName());
  86 + m.put("rkgzs", c.getRkgzs());
  87 + m.put("rkgzl", c.getRkgzlName());
  88 + m.put("ckgzs", c.getCkgzs());
  89 + m.put("ckgzl", c.getCkgzlName());
  90 + listmap.add(m);
  91 + }
  92 +
  93 + List<Iterator<?>> listI = new ArrayList<Iterator<?>>();
  94 + Map<String, Object> m = new HashMap<String, Object>();
  95 + m.put("date", date);
  96 + m.put("endDate", endDate);
  97 + ReportUtils ee = new ReportUtils();
  98 + try {
  99 + String dateTime = "";
  100 + if(date.equals(endDate)){
  101 + dateTime = date.replaceAll("-", "");
  102 + } else {
  103 + dateTime = date.replaceAll("-", "")+"-"+
  104 + endDate.replaceAll("-", "");
  105 + }
  106 + listI.add(listmap.iterator());
  107 + String path = this.getClass().getResource("/").getPath() + "static/pages/forms/";
  108 + ee.excelReplace(listI, new Object[]{m}, path + "mould/" + "cardSheetList.xls",
  109 + path + "export/"+dateTime+"-签卡率.xls");
  110 + } catch (Exception e) {
  111 + // TODO: handle exception
  112 + e.printStackTrace();
  113 + }
  114 + }
  115 + return list;
  116 + }
  117 +
  118 +
  119 +
  120 + @Override
  121 + public List<CardSigning> calcListSheet(Map<String, Object> map) {
  122 + String line=map.get("line").toString();
  123 + String date=map.get("date").toString();
  124 + String endDate=map.get("endDate").toString();
  125 + final DecimalFormat df = new DecimalFormat("0.00");
  126 + String sql="select gs_name,gs_bm,fgs_name,fgs_bm,xl_name," +
  127 + "xl_bm,schedule_date_str,bcs,qks,qkl,rkgzs,rkgzl,ckgzs,ckgzl from card_signing " +
  128 + "where schedule_date_str BETWEEN '"+date+"' and '"+endDate+"' and xl_bm = '"+line+"'" ;
  129 +
  130 + //条件下所有路单
  131 + List<CardSigning> list=jdbcTemplate.query(sql,
  132 + new RowMapper<CardSigning>(){
  133 + @Override
  134 + public CardSigning mapRow(ResultSet rs, int rowNum) throws SQLException {
  135 + CardSigning s=new CardSigning();
  136 + s.setGsName(rs.getString("gs_name"));
  137 + s.setGsBm(rs.getString("gs_bm"));
  138 + s.setFgsName(rs.getString("fgs_name"));
  139 + s.setFgsBm(rs.getString("fgs_bm"));
  140 + s.setXlName(rs.getString("xl_name"));
  141 + s.setXlBm(rs.getString("xl_bm"));
  142 + s.setBcs(rs.getInt("bcs"));
  143 + s.setRkgzs(rs.getInt("rkgzs"));
  144 + s.setRkgzlName(df.format(rs.getDouble("rkgzl"))+"%");
  145 + s.setCkgzs(rs.getInt("ckgzs"));
  146 + s.setCkgzlName(df.format(rs.getDouble("ckgzl"))+"%");
  147 + s.setScheduleDateStr(rs.getString("schedule_date_str"));
  148 + return s;
  149 + }
  150 + });
  151 +
  152 +
  153 +
  154 + if(map.get("type").equals("export")){
  155 + List<Map<String, Object>> listmap=new ArrayList<Map<String, Object>>();
  156 + for (CardSigning c:list) {
  157 + Map<String, Object> m=new HashMap<String,Object>();
  158 + m.put("gs", c.getGsName());
  159 + m.put("fgs", c.getFgsName());
  160 + m.put("schedule_date_str", c.getScheduleDateStr());
  161 + m.put("line", c.getXlName());
  162 + m.put("bcs", c.getBcs());
  163 + m.put("rkgzs", c.getRkgzs());
  164 + m.put("rkgzl", c.getRkgzlName());
  165 + m.put("ckgzs", c.getCkgzs());
  166 + m.put("ckgzl", c.getCkgzlName());
  167 + listmap.add(m);
  168 + }
  169 +
  170 + List<Iterator<?>> listI = new ArrayList<Iterator<?>>();
  171 + Map<String, Object> m = new HashMap<String, Object>();
  172 + m.put("date", date);
  173 + m.put("endDate", endDate);
  174 + ReportUtils ee = new ReportUtils();
  175 + try {
  176 + String dateTime = "";
  177 + if(date.equals(endDate)){
  178 + dateTime = date.replaceAll("-", "");
  179 + } else {
  180 + dateTime = date.replaceAll("-", "")+"-"+
  181 + endDate.replaceAll("-", "");
  182 + }
  183 + listI.add(listmap.iterator());
  184 + String path = this.getClass().getResource("/").getPath() + "static/pages/forms/";
  185 + ee.excelReplace(listI, new Object[]{m}, path + "mould/" + "cardSheetList1.xls",
  186 + path + "export/班次故障率"+date.replaceAll("-", "")+"-"+endDate.replaceAll("-", "")+".xls");
  187 + } catch (Exception e) {
  188 + // TODO: handle exception
  189 + e.printStackTrace();
  190 + }
  191 + }
  192 +
  193 + return list;
  194 + }
  195 +
  196 + @Override
  197 + public List<CardSigning> calcSheet(Map<String, Object> map) {
  198 + String line=map.get("line").toString();
  199 + String date=map.get("date").toString();
  200 + String dir =map.get("dir").toString();
  201 + String sql="select gs_name,gs_bm,fgs_name,fgs_bm, xl_name,xl_bm,schedule_date_str ,qdz_name,rfid_state,fcsj,fcsj_actual " +
  202 + "from bsth_c_s_sp_info_real where schedule_date_str = '"+date+"' and xl_bm = '"+line+"' and bc_type='normal' ORDER BY qdz_name,fcsj" ;
  203 + //条件下所有路单
  204 + List<CardSigning> list=jdbcTemplate.query(sql,
  205 + new RowMapper<CardSigning>(){
  206 + @Override
  207 + public CardSigning mapRow(ResultSet rs, int rowNum) throws SQLException {
  208 + CardSigning s=new CardSigning();
  209 + s.setGsName(rs.getString("gs_name"));
  210 + s.setGsBm(rs.getString("gs_bm"));
  211 + s.setFgsName(rs.getString("fgs_name"));
  212 + s.setFgsBm(rs.getString("fgs_bm"));
  213 + s.setXlName(rs.getString("xl_name"));
  214 + s.setXlBm(rs.getString("xl_bm"));
  215 + s.setScheduleDateStr(rs.getString("schedule_date_str"));
  216 + s.setQdzName(rs.getString("qdz_name"));
  217 + s.setRfidState(rs.getInt("rfid_state"));
  218 + s.setFcsj(rs.getString("fcsj"));
  219 + s.setFcsjActual(rs.getString("fcsj_actual"));
  220 + return s;
  221 + }
  222 + });
  223 +
  224 + for (CardSigning c : list){
  225 + String sty = decimalToBinary(c.getRfidState());
  226 + Integer state = Integer.parseInt(sty);
  227 + if(dir.equals("1")) {
  228 +
  229 + if ((state & 4) == 4) {
  230 + c.setRfidName("正常");
  231 + } else {
  232 + c.setRfidName("人卡故障");
  233 + }
  234 + }else {
  235 + if ((state & 4) == 4 || (state & 2) == 2) {
  236 + c.setRfidName("正常");
  237 + }else {
  238 + c.setRfidName("车卡故障");
  239 + }
  240 + }
  241 + }
  242 +
  243 + if(map.get("type").equals("export")){
  244 + List<Map<String, Object>> listmap=new ArrayList<Map<String, Object>>();
  245 + int i = 0;
  246 + for (CardSigning c:list) {
  247 + Map<String, Object> m=new HashMap<String,Object>();
  248 + i++;
  249 + m.put("id",i);
  250 + m.put("schedule_date_str", c.getScheduleDateStr());
  251 + m.put("line", c.getXlName());
  252 + m.put("qdz_name", c.getQdzName());
  253 + m.put("fcsj", c.getFcsj());
  254 + m.put("fcsj_actual", c.getFcsjActual());
  255 + m.put("rfidname", c.getRfidName());
  256 + listmap.add(m);
  257 + }
  258 + String fileName="";
  259 + if(dir.equals("1")){
  260 + fileName="人卡故障率"+date;
  261 + }else{
  262 + fileName="车卡故障率"+date;
  263 + }
  264 + List<Iterator<?>> listI = new ArrayList<Iterator<?>>();
  265 + Map<String, Object> m = new HashMap<String, Object>();
  266 + m.put("date", date);
  267 + ReportUtils ee = new ReportUtils();
  268 + try {
  269 + listI.add(listmap.iterator());
  270 + String path = this.getClass().getResource("/").getPath() + "static/pages/forms/";
  271 + ee.excelReplace(listI, new Object[]{m}, path + "mould/" + "cardSheetList2.xls",
  272 + path + "export/"+fileName+".xls");
  273 + } catch (Exception e) {
  274 + // TODO: handle exception
  275 + e.printStackTrace();
  276 + }
  277 + }
  278 +
  279 +
  280 + return list;
  281 + }
  282 +
  283 +
  284 + public static String decimalToBinary(int n) {
  285 + String str = "";
  286 + if(n == 0){
  287 + return str = "0";
  288 + }
  289 + while (n != 0) {
  290 + str = n % 2 + str;
  291 + n = n / 2;
  292 + }
  293 + return str;
  294 + }
  295 +
  296 +
  297 +
  298 +}
... ...
src/main/resources/static/pages/forms/mould/cardSheetList.xls 0 → 100644
No preview for this file type
src/main/resources/static/pages/forms/mould/cardSheetList1.xls 0 → 100644
No preview for this file type
src/main/resources/static/pages/forms/mould/cardSheetList2.xls 0 → 100644
No preview for this file type
src/main/resources/static/pages/report/cardInsertion/cardInsertionList.html 0 → 100644
  1 +<style type="text/css">
  2 + .table-bordered {
  3 + border: 1px solid; }
  4 + .table-bordered > thead > tr > th,
  5 + .table-bordered > thead > tr > td,
  6 + .table-bordered > tbody > tr > th,
  7 + .table-bordered > tbody > tr > td,
  8 + .table-bordered > tfoot > tr > th,
  9 + .table-bordered > tfoot > tr > td {
  10 + border: 1px solid; }
  11 + .table-bordered > thead > tr > th,
  12 + .table-bordered > thead > tr > td {
  13 + border-bottom-width: 2px; }
  14 +
  15 + .table > tbody + tbody {
  16 + border-top: 1px solid; }
  17 +</style>
  18 +
  19 +<div class="page-head">
  20 + <div class="page-title">
  21 + <h1>线路签卡率</h1>
  22 + </div>
  23 +</div>
  24 +
  25 +<div class="row">
  26 + <div class="col-md-12">
  27 + <div class="portlet light porttlet-fit bordered">
  28 + <div class="portlet-title">
  29 + <form class="form-inline" action="">
  30 + <div style="display: inline-block; margin-left: 61px;" id="gsdmDiv">
  31 + <span class="item-label" style="width: 80px;">公司: </span> <select
  32 + class="form-control" name="company" id="gsdm"
  33 + style="width: 180px;"></select>
  34 + </div>
  35 + <div style="display: inline-block; margin-left: 38px;"
  36 + id="fgsdmDiv">
  37 + <span class="item-label" style="width: 80px;">分公司: </span> <select
  38 + class="form-control" name="subCompany" id="fgsdm"
  39 + style="width: 180px;"></select>
  40 + </div>
  41 +
  42 + <div style="display: inline-block; margin-left: 53px;">
  43 + <span class="item-label" style="width: 80px;">线路: </span> <select
  44 + class="form-control" name="line" id="line" style="width: 180px;"></select>
  45 + </div>
  46 + <div style="margin-top: 10px"></div>
  47 + <div style="display: inline-block; margin-left: 33px;">
  48 + <span class="item-label" style="width: 80px;">线路性质: </span> <select
  49 + class="form-control" name="nature" id="nature"
  50 + style="width: 180px;">
  51 + <option value="0">全部线路</option>
  52 + <option value="1" selected="selected">营运线路</option>
  53 + <option value="2">非营运线路</option>
  54 + </select>
  55 + </div>
  56 + <div style="display: inline-block;">
  57 + <span class="item-label" style="width: 80px; margin-left: 24px;">开始时间:
  58 + </span> <input class="form-control" type="text" id="date"
  59 + style="width: 180px;" />
  60 + </div>
  61 + <div style="display: inline-block;">
  62 + <span class="item-label" style="width: 80px; margin-left: 24px;">结束时间:
  63 + </span> <input class="form-control" type="text" id="endDate"
  64 + style="width: 180px;" />
  65 + </div>
  66 +
  67 + <div class="form-group">
  68 + <input type="hidden" id="id" /> <input class="btn btn-default"
  69 + type="button" id="query" value="查询" /> <input
  70 + class="btn btn-default" type="button" id="export" value="导出" />
  71 + </div>
  72 + </form>
  73 + </div>
  74 + <div class="portlet-body">
  75 + <div class="table-container" style="margin-top: 10px;overflow:auto;min-width: 906px">
  76 + <table class="table table-bordered table-hover table-checkable" id="forms">
  77 + <thead>
  78 + <tr>
  79 + <td>公司</td>
  80 + <td>分公司</td>
  81 + <td>线路</td>
  82 + <td>班次数</td>
  83 + <td>签卡班次</td>
  84 + <td>签卡率</td>
  85 + <td>人卡故障班次</td>
  86 + <td>人卡故障率</td>
  87 + <td>车卡故障班次</td>
  88 + <td>车卡故障数率</td>
  89 + <td>查看</td>
  90 + </tr>
  91 + </thead>
  92 +
  93 + <tbody>
  94 +
  95 + </tbody>
  96 + </table>
  97 +
  98 +
  99 + </div>
  100 +
  101 + <div class="table-container" style="margin-top: 10px;overflow:auto;min-width: 906px">
  102 + <input class="btn btn-default hidden" type="button" id="export_1" value="导出"/>
  103 + <table class="table table-bordered table-hover table-checkable" id="forms_1">
  104 + <thead>
  105 + <tr class="hidden">
  106 + <td>公司</td>
  107 + <td>分公司</td>
  108 + <td>线路</td>
  109 + <td>日期</td>
  110 + <td>班次数</td>
  111 + <td>人卡故障班次</td>
  112 + <td>人卡故障率</td>
  113 + <td>查看</td>
  114 + <td>车卡故障班次</td>
  115 + <td>车卡故障率</td>
  116 + <td>查看</td>
  117 + </tr>
  118 + </thead>
  119 +
  120 + <tbody>
  121 +
  122 + </tbody>
  123 + </table>
  124 +
  125 + </div>
  126 + </div>
  127 + </div>
  128 + </div>
  129 +</div>
  130 +<script src="/pages/mforms/singledatas/jquery.table2excel.min.js"></script>
  131 +<script>
  132 + $(function(){
  133 + // 关闭左侧栏
  134 + if (!$('body').hasClass('page-sidebar-closed'))
  135 + $('.menu-toggler.sidebar-toggler').click();
  136 +
  137 + var d = new Date();
  138 + d.setTime(d.getTime() - 1*1000*60*60*24);
  139 + var year = d.getFullYear();
  140 + var month = d.getMonth() + 1;
  141 + var day = d.getDate();
  142 + if(month < 10)
  143 + month = "0"+month;
  144 + if(day < 10)
  145 + day = "0"+day;
  146 + var dateTime = year + "-" + month + "-" + day;
  147 + $("#date").datetimepicker({
  148 + format : 'YYYY-MM-DD',
  149 + locale : 'zh-cn',
  150 + maxDate : dateTime
  151 + });
  152 + $("#endDate").datetimepicker({
  153 + format : 'YYYY-MM-DD',
  154 + locale : 'zh-cn',
  155 + maxDate : dateTime
  156 + });
  157 + $("#date").val(dateTime);
  158 + $("#endDate").val(dateTime);
  159 +
  160 + var fage=true;
  161 + var obj = [];
  162 + var xlList;
  163 + $.get('/report/lineList',function(result){
  164 + xlList=result;
  165 +
  166 + $.get('/user/companyData', function(result){
  167 + obj = result;
  168 + var options = '';
  169 + for(var i = 0; i < obj.length; i++){
  170 + options += '<option value="'+obj[i].companyCode+'">'+obj[i].companyName+'</option>';
  171 + }
  172 + if(obj.length ==0){
  173 + $("#gsdmDiv").css('display','none');
  174 + }else if(obj.length ==1){
  175 + $("#gsdmDiv").css('display','none');
  176 + if(obj[0].children.length == 1 || obj[0].children.length ==0){
  177 + $('#fgsdmDiv').css('display','none');
  178 + fage=false;
  179 + }
  180 + }
  181 + $('#gsdm').html(options);
  182 +
  183 + updateCompany();
  184 + });
  185 + });
  186 +
  187 + $("#gsdm").on("change",updateCompany);
  188 + function updateCompany(){
  189 + var company = $('#gsdm').val();
  190 + var options ='';
  191 + if(fage){
  192 + options = '<option value="">请选择</option>';
  193 + }
  194 + for(var i = 0; i < obj.length; i++){
  195 + if(obj[i].companyCode == company){
  196 + var children = obj[i].children;
  197 + for(var j = 0; j < children.length; j++){
  198 + options += '<option value="'+children[j].code+'">'+children[j].name+'</option>';
  199 + }
  200 + }
  201 + }
  202 + $('#fgsdm').html(options);
  203 + }
  204 +
  205 + var tempData = {};
  206 + $.get('/report/lineList',function(xlList){
  207 + var data = [];
  208 + data.push({id: " ", text: "全部线路"});
  209 + $.get('/user/companyData', function(result){
  210 + for(var i = 0; i < result.length; i++){
  211 + var companyCode = result[i].companyCode;
  212 + var children = result[i].children;
  213 + for(var j = 0; j < children.length; j++){
  214 + var code = children[j].code;
  215 + for(var k=0;k < xlList.length;k++ ){
  216 + if(xlList[k]["fgsbm"]==code && xlList[k]["gsbm"]==companyCode){
  217 + data.push({id: xlList[k]["xlbm"], text: xlList[k]["xlname"]});
  218 + tempData[xlList[k]["xlbm"]] = companyCode+":"+code;
  219 + }
  220 + }
  221 + }
  222 + }
  223 + initPinYinSelect2('#line',data,'');
  224 +
  225 + });
  226 + });
  227 +
  228 + $("#line").on("change", function(){
  229 + if($("#line").val() == " "){
  230 + $("#gsdm").attr("disabled", false);
  231 + $("#fgsdm").attr("disabled", false);
  232 + } else {
  233 + var temp = tempData[$("#line").val()].split(":");
  234 + $("#gsdm").val(temp[0]);
  235 + updateCompany();
  236 + $("#fgsdm").val(temp[1]);
  237 + $("#nature").val(0);
  238 + $("#gsdm").attr("disabled", true);
  239 + $("#fgsdm").attr("disabled", true);
  240 + }
  241 + });
  242 +
  243 + $("#export").attr('disabled',"true");
  244 +
  245 + //查询
  246 + $("#query").on('click',function(){
  247 + var line = $("#line").val();
  248 + var date = $("#date").val();
  249 + var endDate = $("#endDate").val();
  250 + var fgs=$('#fgsdm').val();
  251 + var gs=$('#gsdm').val();
  252 + var nature=$("#nature").val();
  253 + var i = layer.load(2);
  254 + $get('/CardSigning/cardList',{line:line,date:date,endDate:endDate,gs:gs,fgs:fgs,nature:nature,type:'query'},function(result){
  255 + layer.close(i);
  256 + var calcSheetList = template('calcSheetList',{list:result});
  257 + $('#forms tbody').html(calcSheetList);
  258 + $('.btn-calcSheetList').on('click', showcalcSheetList);
  259 +
  260 + if(result.length == 0)
  261 + $("#export").attr('disabled',"true");
  262 + else
  263 + $("#export").removeAttr("disabled");
  264 + });
  265 +
  266 + });
  267 + function showcalcSheetList(){
  268 + var id = $(this).data('id');
  269 + var date = $("#date").val();
  270 + var endDate = $("#endDate").val();
  271 + $("#id").val(id);
  272 + $get('/CardSigning/calcListSheet',{line:id,date:date,endDate:endDate,type:'query'},function(result){
  273 + var calcSheetList = template('calcSheetList_1',{list:result});
  274 + $('#forms_1 tbody').html(calcSheetList);
  275 + $('.btn-calcSheetList_1').on('click', opencalcSheetList);
  276 + $('.btn-calcSheetList_2').on('click', opencalcSheetList2);
  277 + $("#forms_1 .hidden").removeClass("hidden");
  278 + $("html,body").animate({scrollTop:$("#forms_1").offset().top},1000);
  279 + $("#export_1").removeClass("hidden");
  280 + });
  281 + }
  282 + function opencalcSheetList(){
  283 + var id = $(this).data('id');
  284 + id += ","+$(this).data('date')+",1";
  285 + $.get('/pages/report/cardInsertion/cardList.html', function (content) {
  286 + layer.open({
  287 + type: 1,
  288 + area: ['800px', '600px'],
  289 + content: content,
  290 + title: '线路签卡故障率详细',
  291 + shift: 5,
  292 + scrollbar: false,
  293 + success: function () {
  294 + $('#calcSheetList').trigger('init', id);
  295 + }
  296 + });
  297 + });
  298 + }
  299 +
  300 + function opencalcSheetList2(){
  301 + var id = $(this).data('id');
  302 + id += ","+$(this).data('date')+",2";
  303 + $.get('/pages/report/cardInsertion/cardList.html', function (content) {
  304 + layer.open({
  305 + type: 1,
  306 + area: ['800px', '600px'],
  307 + content: content,
  308 + title: '线路签卡故障率详细',
  309 + shift: 5,
  310 + scrollbar: false,
  311 + success: function () {
  312 + $('#calcSheetList').trigger('init', id);
  313 + }
  314 + });
  315 + });
  316 + }
  317 +
  318 + $("#export").on("click",function(){
  319 + var line = $("#line").val();
  320 + var date = $("#date").val();
  321 + var endDate = $("#endDate").val();
  322 + var fgs=$('#fgsdm').val();
  323 + var gs=$('#gsdm').val();
  324 + var nature=$("#nature").val();
  325 + var lineName = $('#line option:selected').text();
  326 + if(lineName == "全部线路")
  327 + lineName = $('#fgsdm option:selected').text();
  328 + if(lineName == "请选择")
  329 + lineName =$('#gsdm option:selected').text();
  330 + var i = layer.load(2);
  331 + $get('/CardSigning/cardList',{line:line,date:date,endDate:endDate,gs:gs,fgs:fgs,nature:nature,type:'export'},function(result){
  332 + var dateTime = "";
  333 + if(date == endDate){
  334 + dateTime = moment(date).format("YYYYMMDD");
  335 + } else {
  336 + dateTime = moment(date).format("YYYYMMDD")+"-"+
  337 + moment(endDate).format("YYYYMMDD");
  338 + }
  339 + window.open("/downloadFile/download?fileName="
  340 + +dateTime+"-签卡率");
  341 + layer.close(i);
  342 + });
  343 + });
  344 +
  345 + $("#export_1").on("click",function(){
  346 + var id = $("#id").val();
  347 + var date = $("#date").val();
  348 + var endDate = $("#endDate").val();
  349 + var i = layer.load(2);
  350 + $get('/CardSigning/calcListSheet',{line:id,date:date,endDate:endDate,type:'export'},function(result){
  351 + window.open("/downloadFile/download?fileName=班次故障率"+moment(date).format("YYYYMMDD")+"-"+moment(endDate).format("YYYYMMDD"));
  352 + layer.close(i);
  353 + });
  354 + })
  355 +
  356 + });
  357 +</script>
  358 +<script type="text/html" id="calcSheetList">
  359 + {{each list as obj i}}
  360 + <tr>
  361 + <td>{{obj.gsName}}</td>
  362 + <td>{{obj.fgsName}}</td>
  363 + <td>{{obj.xlName}}</td>
  364 + <td>{{obj.bcs}}</td>
  365 + <td>{{obj.qks}}</td>
  366 + <td>{{obj.qklName}}</td>
  367 + <td>{{obj.rkgzs}}</td>
  368 + <td>{{obj.rkgzlName}}</td>
  369 + <td>{{obj.ckgzs}}</td>
  370 + <td>{{obj.ckgzlName}}</td>
  371 +
  372 + <td>
  373 + <button type="button" class="btn btn-sm blue btn-calcSheetList"
  374 + data-id="{{obj.xlBm}}">查看</button>
  375 + </td>
  376 + </tr>
  377 + {{/each}}
  378 + {{if list.length == 0}}
  379 + <tr>
  380 + <td colspan="11"><h6 class="muted">没有找到相关数据</h6></td>
  381 + </tr>
  382 + {{/if}}
  383 +</script>
  384 +
  385 +
  386 +
  387 +<script type="text/html" id="calcSheetList_1">
  388 + {{each list as obj i}}
  389 + <tr>
  390 + <td>{{obj.gsName}}</td>
  391 + <td>{{obj.fgsName}}</td>
  392 + <td>{{obj.xlName}}</td>
  393 + <td>{{obj.scheduleDateStr}}</td>
  394 + <td>{{obj.bcs}}</td>
  395 + <td>{{obj.rkgzs}}</td>
  396 + <td>{{obj.rkgzlName}}</td>
  397 + <td>
  398 + <button type="button" class="btn btn-sm blue btn-calcSheetList_1"
  399 + data-id="{{obj.xlBm}}" data-date="{{obj.scheduleDateStr}}">详细</button>
  400 + </td>
  401 + <td>{{obj.ckgzs}}</td>
  402 + <td>{{obj.ckgzlName}}</td>
  403 + <td>
  404 + <button type="button" class="btn btn-sm blue btn-calcSheetList_2"
  405 + data-id="{{obj.xlBm}}" data-date="{{obj.scheduleDateStr}}">详细</button>
  406 + </td>
  407 + </tr>
  408 + {{/each}}
  409 + {{if list.length == 0}}
  410 + <tr>
  411 + <td colspan="7"><h6 class="muted">没有找到相关数据</h6></td>
  412 + </tr>
  413 + {{/if}}
  414 +</script>
  415 +
... ...
src/main/resources/static/pages/report/cardInsertion/cardList.html 0 → 100644
  1 +<style type="text/css">
  2 + .table-bordered {
  3 + border: 1px solid; }
  4 + .table-bordered > thead > tr > th,
  5 + .table-bordered > thead > tr > td,
  6 + .table-bordered > tbody > tr > th,
  7 + .table-bordered > tbody > tr > td,
  8 + .table-bordered > tfoot > tr > th,
  9 + .table-bordered > tfoot > tr > td {
  10 + border: 1px solid; }
  11 + .table-bordered > thead > tr > th,
  12 + .table-bordered > thead > tr > td {
  13 + border-bottom-width: 2px; }
  14 +
  15 + .table > tbody + tbody {
  16 + border-top: 1px solid; }
  17 +</style>
  18 +
  19 +<div class="page-head">
  20 + <div class="page-title" style="margin-left: 20px">
  21 + <button id="exportList">数据导出</button>
  22 + </div>
  23 +</div>
  24 +
  25 +<div class="row" id="calcSheetList">
  26 + <div class="col-md-12">
  27 + <div class="portlet light porttlet-fit bordered">
  28 + <div class="portlet-body">
  29 + <div class="table-container" style="margin-top: 10px;overflow:auto;min-width: 600px">
  30 + <table class="table table-bordered table-hover table-checkable" id="forms_2">
  31 + <thead>
  32 + <tr>
  33 + <td></td>
  34 + <td>日期</td>
  35 + <td>线路</td>
  36 + <td>站点</td>
  37 + <td>计划时间</td>
  38 + <td>实际时间</td>
  39 + <td>签卡状态</td>
  40 + </tr>
  41 + </thead>
  42 +
  43 + <tbody>
  44 +
  45 + </tbody>
  46 + </table>
  47 + </div>
  48 + </div>
  49 + </div>
  50 + </div>
  51 +</div>
  52 +<script src="/pages/mforms/singledatas/jquery.table2excel.min.js"></script>
  53 +<script>
  54 + $(function(){
  55 + // 关闭左侧栏
  56 + if (!$('body').hasClass('page-sidebar-closed'))
  57 + $('.menu-toggler.sidebar-toggler').click();
  58 + var no="";
  59 + var dates="";
  60 + var dir="";
  61 + $("#calcSheetList").on('init', function (e, id) {
  62 + no=id.split(",")[0];
  63 + dates = id.split(",")[1];
  64 + dir =id.split(",")[2];
  65 + var i = layer.load(2);
  66 + $get('/CardSigning/calcSheet',{line:no,date:dates,dir:dir,type:'query'},function(result){
  67 + layer.close(i);
  68 + var calcSheetList_2 = template('calcSheetList_2',{list:result});
  69 + $('#forms_2 tbody').html(calcSheetList_2);
  70 + });
  71 + })
  72 + $("#exportList").on('click',function(){
  73 + var i = layer.load(2);
  74 + var name="";
  75 + if(dir=="1"){
  76 + fileName="人卡故障率"+dates;
  77 + }else{
  78 + fileName="车卡故障率"+dates;
  79 + }
  80 + $get('/CardSigning/calcSheet',{line:no,date:dates,dir:dir,type:'export'},function(result){
  81 + window.open("/downloadFile/download?fileName="+fileName);
  82 + layer.close(i);
  83 +
  84 + });
  85 + });
  86 +
  87 +
  88 + });
  89 +</script>
  90 +<script type="text/html" id="calcSheetList_2">
  91 + {{each list as obj i}}
  92 + <tr {{if obj.rfidName =="人卡故障" || obj.rfidName =="车卡故障" }}style="color: red" {{/if}}>
  93 + <td>{{i+1}}</td>
  94 + <td>{{obj.scheduleDateStr}}</td>
  95 + <td>{{obj.xlName}}</td>
  96 + <td>{{obj.qdzName}}</td>
  97 + <td>{{obj.fcsj}}</td>
  98 + <td>{{obj.fcsjActual}}</td>
  99 + <td>{{obj.rfidName}}</td>
  100 + </tr>
  101 + {{/each}}
  102 + {{if list.length == 0}}
  103 + <tr>
  104 + <td colspan="7"><h6 class="muted">没有找到相关数据</h6></td>
  105 + </tr>
  106 + {{/if}}
  107 +</script>
0 108 \ No newline at end of file
... ...
src/main/resources/static/real_control_v2/css/line_schedule.css
... ... @@ -935,7 +935,7 @@ input.i-cbox[type=checkbox]{
935 935  
936 936 .tl-tip-panel .ct_title{
937 937 display: inline-block;
938   - width: 42px;
  938 + width: 82px;
939 939 vertical-align: top;
940 940 margin-top: 5px;
941 941 color: grey;
... ... @@ -954,7 +954,7 @@ input.i-cbox[type=checkbox]{
954 954 }
955 955  
956 956 .qtip.sch-tl-tip{
957   - max-width: 335px;
  957 + max-width: 380px;
958 958 }
959 959  
960 960 .sfsj-sch-detail{
... ...
src/main/resources/static/real_control_v2/fragments/line_schedule/layout.html
1   -<div>
2   - <!-- line schedule tab body layout template -->
3   - <script id="cont-line-layout-temp" type="text/html">
4   - <div class="uk-grid top-container">
5   - <div class="uk-width-5-6 uk-grid schedule-wrap">
6   - <div class="uk-width-1-2">
7   - <div class="card-panel"></div>
8   - </div>
9   -
10   - <div class="uk-width-1-2">
11   - <div class="card-panel"></div>
12   - </div>
13   - </div>
14   - <div class="uk-width-1-6" style="height: calc(100% - 1px);position: relative;">
15   - <div class="card-panel sys-mailbox" style="overflow: auto;">
16   - </div>
17   - <div class="mileage_elec_panel">
18   - </div>
19   - </div>
20   - </div>
21   -
22   - <div class="footer-chart">
23   - <div class="card-panel">
24   - <div class="svg-wrap"></div>
25   - </div>
26   - </div>
27   - </script>
28   -
29   - <script id="sch-table-top-help-temp" type="text/html">
30   - <div class="tl-tip-panel">
31   - <div class="ct_title">
32   - 图例
33   - </div>
34   - <div style="display: inline-block;width: calc(100% - 50px)">
35   - <span class="tl-wd">误点</span>
36   - <span class="tl-zzzx">正在执行</span>
37   - <span class="tl-qrlb"></span>
38   - <span class="tl-yzx">已执行</span>
39   - <span class="tl-xxfc">消息发出</span>
40   - <span class="tl-xxsd">消息收到</span>
41   - <span class="tl-xxrd">消息阅读</span>
42   - <span class="tl-wfyd">无发有到</span>
43   - </div>
44   - </div>
45   - </script>
46   -
47   - <script id="sch-table-m_station_error-temp" type="text/html">
48   - <div class="tl-tip-panel">
49   - <ul class="uk-list uk-list-line" style="margin-bottom: 0;">
50   - {{each list as obj i}}
51   - {{if obj.realStationCode!=null}}
52   - <li>【{{obj.stationName}}】班次用的站点 <span style="color: red;">{{obj.stationCode}}</span> -实际:{{obj.realStationCode}}</li>
53   - {{else}}
54   - <li>【{{obj.stationName}}】班次用的站点 <span style="color: red;">{{obj.stationCode}}</span> -在站点路由中不存在的</li>
55   - {{/if}}
56   - {{/each}}
57   -
58   - </ul>
59   - </div>
60   - </script>
61   -</div>
  1 +<div>
  2 + <!-- line schedule tab body layout template -->
  3 + <script id="cont-line-layout-temp" type="text/html">
  4 + <div class="uk-grid top-container">
  5 + <div class="uk-width-5-6 uk-grid schedule-wrap">
  6 + <div class="uk-width-1-2">
  7 + <div class="card-panel"></div>
  8 + </div>
  9 +
  10 + <div class="uk-width-1-2">
  11 + <div class="card-panel"></div>
  12 + </div>
  13 + </div>
  14 + <div class="uk-width-1-6" style="height: calc(100% - 1px);position: relative;">
  15 + <div class="card-panel sys-mailbox" style="overflow: auto;">
  16 + </div>
  17 + <div class="mileage_elec_panel">
  18 + </div>
  19 + </div>
  20 + </div>
  21 +
  22 + <div class="footer-chart">
  23 + <div class="card-panel">
  24 + <div class="svg-wrap"></div>
  25 + </div>
  26 + </div>
  27 + </script>
  28 +
  29 + <script id="sch-table-top-help-temp" type="text/html">
  30 + <div class="tl-tip-panel">
  31 + <div class="ct_title">
  32 + 图例(班次)
  33 + </div>
  34 + <div style="display: inline-block;width: calc(100% - 90px)">
  35 + <span class="tl-wd">误点</span>
  36 + <span class="tl-zzzx">正在执行</span>
  37 + <span class="tl-qrlb"></span>
  38 + <span class="tl-yzx">已执行</span>
  39 + <span class="tl-xxfc">消息发出</span>
  40 + <span class="tl-xxsd">消息收到</span>
  41 + <span class="tl-xxrd">消息阅读</span>
  42 + <span class="tl-wfyd">无发有到</span>
  43 + </div>
  44 + <div class="ct_title">
  45 + 图例(RFID)
  46 + </div>
  47 + <div style="display: inline-block;width: calc(100% - 90px)">
  48 + <span class="tl-green" style="color: black">有车人卡</span>
  49 + <span class="tl-yellow" style="color: black">有车卡</span>
  50 + <span class="tl-grey" style="color: black">无车人卡</span>
  51 + </div>
  52 + </div>
  53 + </script>
  54 +
  55 + <script id="sch-table-m_station_error-temp" type="text/html">
  56 + <div class="tl-tip-panel">
  57 + <ul class="uk-list uk-list-line" style="margin-bottom: 0;">
  58 + {{each list as obj i}}
  59 + {{if obj.realStationCode!=null}}
  60 + <li>【{{obj.stationName}}】班次用的站点 <span style="color: red;">{{obj.stationCode}}</span> -实际:{{obj.realStationCode}}</li>
  61 + {{else}}
  62 + <li>【{{obj.stationName}}】班次用的站点 <span style="color: red;">{{obj.stationCode}}</span> -在站点路由中不存在的</li>
  63 + {{/if}}
  64 + {{/each}}
  65 +
  66 + </ul>
  67 + </div>
  68 + </script>
  69 +</div>
... ...
src/main/resources/static/real_control_v2/fragments/north/nav/report_register/list.html
... ... @@ -235,7 +235,7 @@
235 235 <td style="vertical-align: middle;">{{obj.report_ROAD}}</td>
236 236 <td style="vertical-align: middle;">{{obj.report_XSFX}}</td>
237 237 <td style="vertical-align: middle;">{{obj.report_STATION}}</td>
238   - <td style="vertical-align: middle;">{{obj.report_DJGSNAMEJ}}</td>
  238 + <td style="vertical-align: middle;">{{obj.report_DJGSJ}}</td>
239 239 <td style="vertical-align: middle;">{{obj.report_DJGYY}}</td>
240 240 </tr>
241 241 {{/each}}
... ...
src/main/resources/static/real_control_v2/fragments/north/nav/report_register/manage.html
... ... @@ -265,7 +265,7 @@
265 265 <td style="vertical-align: middle;display:none">{{obj.report_BBR}}</td>
266 266 <td style="vertical-align: middle;display:none">{{obj.report_GS}}</td>
267 267 <td style="vertical-align: middle;display:none">{{obj.report_FGS}}</td>
268   - <td style="vertical-align: middle;display:none">{{obj.report_XLNAME}}</td>
  268 + <td style="vertical-align: middle;">{{obj.report_XLNAME}}</td>
269 269 <td style="vertical-align: middle;">{{obj.report_TFSJ}}</td>
270 270 <td style="vertical-align: middle;">{{obj.report_YXSJ}}</td>
271 271 <td style="vertical-align: middle;">{{obj.report_YXBC}}</td>
... ...