Commit 06fc723b46dac2401c97a19df2a04746ed4f52d0

Authored by 徐烜
1 parent b3c3df15

时刻表v2.7.2

1、导出时添加新的sheet,时刻表信息,时刻表导入的格式,只保留开始的进场,最后的出场,中间分班进出场班次不保留
2、将之前的sheet重命名为,时刻表信息_统计,修正显示的bug(吃饭班次应该是下一个班次,进出场班次时间显示错误)
src/main/java/com/bsth/service/schedule/datatools/TTInfoDetailDataToolsImpl.java
... ... @@ -378,119 +378,194 @@ public class TTInfoDetailDataToolsImpl implements DataToolsService, TTInfoDetail
378 378 }
379 379 }
380 380  
381   - @Override
382   - public DataToolsFile exportDynamicTTinfo(DTInfos dtInfos) throws ScheduleException {
383   - try {
384   - // 使用POI,创建xlsx文件
385   - XSSFWorkbook wb = new XSSFWorkbook();
386   - XSSFSheet sheet = wb.createSheet(WorkbookUtil.createSafeSheetName("时刻表信息"));
  381 + private void createDynamicTTinfoStatSheet(XSSFWorkbook wb, DTInfos dtInfos) {
  382 + XSSFSheet sheet = wb.createSheet(WorkbookUtil.createSafeSheetName("时刻表信息_统计"));
387 383  
388   - //-------------------------------- 1、路牌班次数据 -------------------------------//
389   - List<LpObj> lpObjList = dtInfos.getLpObjList();
  384 + //-------------------------------- 1、路牌班次数据 -------------------------------//
  385 + List<LpObj> lpObjList = dtInfos.getLpObjList();
390 386  
391   - // 构建第一行数据
392   - XSSFRow lpHeadRow = sheet.createRow((short) 0);
393   - if (lpObjList.size() == 0) {
394   - throw new RuntimeException("没有班次数据!");
395   - }
396   - int groupCount = lpObjList.get(0).getGroupCount(); // 获取总圈数
397   - if (groupCount == 0) {
398   - throw new RuntimeException("总圈数为0,有问题!");
399   - }
  387 + // 构建第一行数据
  388 + XSSFRow lpHeadRow = sheet.createRow((short) 0);
  389 + if (lpObjList.size() == 0) {
  390 + throw new RuntimeException("没有班次数据!");
  391 + }
  392 + int groupCount = lpObjList.get(0).getGroupCount(); // 获取总圈数
  393 + if (groupCount == 0) {
  394 + throw new RuntimeException("总圈数为0,有问题!");
  395 + }
400 396  
401   - // 构造表头
402   - PoiUtils.createStringXSSFCell(wb, lpHeadRow, (short)0, "路牌", new Color(0x96b9d7));
403   - Station station1 = stationService.findById(lpObjList.get(0).getStationRouteId1());
404   - Station station2 = stationService.findById(lpObjList.get(1).getStationRouteId2());
405   - for (int i = 0; i < groupCount; i++) {
406   - PoiUtils.createStringXSSFCell(wb, lpHeadRow, (short) (i * 2 + 1),
407   - station1.getStationName(), new Color(0x96b9d7));
408   - PoiUtils.createStringXSSFCell(wb, lpHeadRow, (short) (i * 2 + 2),
409   - station2.getStationName(), new Color(0x96b9d7));
  397 + // 构造表头
  398 + PoiUtils.createStringXSSFCell(wb, lpHeadRow, (short)0, "路牌", new Color(0x96b9d7));
  399 + Station station1 = stationService.findById(lpObjList.get(0).getStationRouteId1());
  400 + Station station2 = stationService.findById(lpObjList.get(1).getStationRouteId2());
  401 + for (int i = 0; i < groupCount; i++) {
  402 + PoiUtils.createStringXSSFCell(wb, lpHeadRow, (short) (i * 2 + 1),
  403 + station1.getStationName(), new Color(0x96b9d7));
  404 + PoiUtils.createStringXSSFCell(wb, lpHeadRow, (short) (i * 2 + 2),
  405 + station2.getStationName(), new Color(0x96b9d7));
  406 + }
  407 + PoiUtils.createStringXSSFCell(wb, lpHeadRow, (short) (groupCount * 2 + 1),
  408 + "路牌工时", new Color(0x96b9d7));
  409 + PoiUtils.createStringXSSFCell(wb, lpHeadRow, (short) (groupCount * 2 + 2),
  410 + "营运班次数", new Color(0x96b9d7));
  411 +
  412 + // 构建每个路牌的班次数据
  413 + for (int i = 0; i < lpObjList.size(); i++) {
  414 + LpObj lpObj = lpObjList.get(i);
  415 + XSSFRow lpRow = sheet.createRow((short) (i + 1));
  416 + PoiUtils.createStringXSSFCell(wb, lpRow, (short) 0, lpObj.getLpname());
  417 + for (int j = 0; j < groupCount; j++) {
  418 + PoiUtils.createBlankXSSFCell(wb, lpRow, (short) (j * 2 + 1));
  419 + PoiUtils.createBlankXSSFCell(wb, lpRow, (short) (j * 2 + 2));
410 420 }
411   - PoiUtils.createStringXSSFCell(wb, lpHeadRow, (short) (groupCount * 2 + 1),
412   - "路牌工时", new Color(0x96b9d7));
413   - PoiUtils.createStringXSSFCell(wb, lpHeadRow, (short) (groupCount * 2 + 2),
414   - "营运班次数", new Color(0x96b9d7));
415   -
416   - // 构建每个路牌的班次数据
417   - for (int i = 0; i < lpObjList.size(); i++) {
418   - LpObj lpObj = lpObjList.get(i);
419   - XSSFRow lpRow = sheet.createRow((short) (i + 1));
420   - PoiUtils.createStringXSSFCell(wb, lpRow, (short) 0, lpObj.getLpname());
421   - for (int j = 0; j < groupCount; j++) {
422   - PoiUtils.createBlankXSSFCell(wb, lpRow, (short) (j * 2 + 1));
423   - PoiUtils.createBlankXSSFCell(wb, lpRow, (short) (j * 2 + 2));
424   - }
425   - for (BcObj bcObj : lpObj.getBcObjList()) {
  421 + for (BcObj bcObj : lpObj.getBcObjList()) {
  422 + if (bcObj.getBcType() == BcType.NORMAL) {
426 423 Cell cell = lpRow.getCell((short) (bcObj.getGroupNo() * 2 + bcObj.getGroupBcNo() + 1));
427   - cell.setCellValue(bcObj.getFcsj());
  424 + cell.setCellValue(bcObj.getFcsjDesc());
428 425 }
429   - // 路牌工时/班次数
430   - PoiUtils.createDoubleXSSFCell(wb, lpRow, (short) (groupCount * 2 + 1),
431   - lpObj.getZgs() / 60);
432   - // 营运班次数
433   - PoiUtils.createIntegerXSSFCell(wb, lpRow, (short) (groupCount * 2 + 2),
434   - lpObj.getZbc());
435 426 }
  427 + // 路牌工时/班次数
  428 + PoiUtils.createDoubleXSSFCell(wb, lpRow, (short) (groupCount * 2 + 1),
  429 + lpObj.getZgs() / 60);
  430 + // 营运班次数
  431 + PoiUtils.createIntegerXSSFCell(wb, lpRow, (short) (groupCount * 2 + 2),
  432 + lpObj.getZbc());
  433 + }
436 434  
437   - // 自适应单元格长宽
438   - sheet.autoSizeColumn(0);
439   - for (int i = 0; i < groupCount; i++) {
440   - sheet.autoSizeColumn(i * 2 + 1);
441   - sheet.autoSizeColumn(i * 2 + 2);
442   - }
443   - sheet.autoSizeColumn(groupCount * 2 + 1);
444   - sheet.autoSizeColumn(groupCount * 2 + 2);
  435 + // 自适应单元格长宽
  436 + sheet.autoSizeColumn(0);
  437 + for (int i = 0; i < groupCount; i++) {
  438 + sheet.autoSizeColumn(i * 2 + 1);
  439 + sheet.autoSizeColumn(i * 2 + 2);
  440 + }
  441 + sheet.autoSizeColumn(groupCount * 2 + 1);
  442 + sheet.autoSizeColumn(groupCount * 2 + 2);
445 443  
446   - // 锁定行首,列首
447   - sheet.createFreezePane(1, 1);
  444 + // 锁定行首,列首
  445 + sheet.createFreezePane(1, 1);
448 446  
449   - //-------------------------------- 2、统计数据 -------------------------------//
450   - List<StatInfo> statInfos = dtInfos.getStatInfoList();
  447 + //-------------------------------- 2、统计数据 -------------------------------//
  448 + List<StatInfo> statInfos = dtInfos.getStatInfoList();
451 449  
452   - // 创建总的统计数据格式
453   - // 第一行 统计数据
454   - // 第二行 序号,统计项目(8个单元格合并),统计数值
455   - // 第三行开始数据,一共20行
  450 + // 创建总的统计数据格式
  451 + // 第一行 统计数据
  452 + // 第二行 序号,统计项目(8个单元格合并),统计数值
  453 + // 第三行开始数据,一共20行
456 454  
457   - int startrow = lpObjList.size() + 3;
458   - for (int i = startrow; i <= startrow + 22; i++) {
459   - XSSFRow xssfRow = sheet.createRow(i);
460   - for (int j = 0; j < 10; j++) {
461   - PoiUtils.createStringXSSFCell(wb, xssfRow, (short) j, "");
  455 + int startrow = lpObjList.size() + 3;
  456 + for (int i = startrow; i <= startrow + 22; i++) {
  457 + XSSFRow xssfRow = sheet.createRow(i);
  458 + for (int j = 0; j < 10; j++) {
  459 + PoiUtils.createStringXSSFCell(wb, xssfRow, (short) j, "");
462 460  
463   - }
464   - }
465   - // 合并第一行
466   - sheet.addMergedRegion(new CellRangeAddress(startrow, startrow, 0, 9));
467   - sheet.getRow(startrow).getCell(0).setCellValue("统计数据");
468   - // 合并第二行
469   - sheet.getRow(startrow + 1).getCell(0).setCellValue("序号");
470   - sheet.getRow(startrow + 1).getCell(1).setCellValue("统计项目");
471   - sheet.getRow(startrow + 1).getCell(9).setCellValue("统计数值");
472   - sheet.addMergedRegion(new CellRangeAddress(startrow + 1, startrow + 1, 1, 8));
473   - // 处理后面具体统计行
474   - for (int row = startrow + 2; row <= startrow + 2 + statInfos.size(); row++) {
475   - sheet.addMergedRegion(new CellRangeAddress(row, row, 1, 8));
476 461 }
  462 + }
  463 + // 合并第一行
  464 + sheet.addMergedRegion(new CellRangeAddress(startrow, startrow, 0, 9));
  465 + sheet.getRow(startrow).getCell(0).setCellValue("统计数据");
  466 + // 合并第二行
  467 + sheet.getRow(startrow + 1).getCell(0).setCellValue("序号");
  468 + sheet.getRow(startrow + 1).getCell(1).setCellValue("统计项目");
  469 + sheet.getRow(startrow + 1).getCell(9).setCellValue("统计数值");
  470 + sheet.addMergedRegion(new CellRangeAddress(startrow + 1, startrow + 1, 1, 8));
  471 + // 处理后面具体统计行
  472 + for (int row = startrow + 2; row <= startrow + 2 + statInfos.size(); row++) {
  473 + sheet.addMergedRegion(new CellRangeAddress(row, row, 1, 8));
  474 + }
  475 +
  476 + for (int i = 0; i < statInfos.size(); i++) {
  477 + StatInfo statInfo = statInfos.get(i);
  478 +
  479 + // 1、统计序号
  480 + PoiUtils.setIntegerStyleXSSFCellStyle(wb, sheet.getRow(startrow + 2 + i).getCell(0));
  481 + sheet.getRow(startrow + 2 + i).getCell(0).setCellValue(i);
  482 +
  483 + // 2、统计项目
  484 + sheet.getRow(startrow + 2 + i).getCell(1).setCellValue(statInfo.getStatItem());
  485 +
  486 + // 3、统计数值
  487 + PoiUtils.setDoubleStyleXSSFCellStyle(wb, sheet.getRow(startrow + 2 + i).getCell(9));
  488 + sheet.getRow(startrow + 2 + i).getCell(9).setCellValue(statInfo.getStatValue());
  489 + }
  490 +
  491 + }
477 492  
478   - for (int i = 0; i < statInfos.size(); i++) {
479   - StatInfo statInfo = statInfos.get(i);
  493 + private void createDynamicTTinfoSheet(XSSFWorkbook wb, DTInfos dtInfos) {
  494 + XSSFSheet sheet = wb.createSheet(WorkbookUtil.createSafeSheetName("时刻表信息"));
480 495  
481   - // 1、统计序号
482   - PoiUtils.setIntegerStyleXSSFCellStyle(wb, sheet.getRow(startrow + 2 + i).getCell(0));
483   - sheet.getRow(startrow + 2 + i).getCell(0).setCellValue(i);
  496 + //-------------------------------- 1、路牌班次数据 -------------------------------//
  497 + List<LpObj> lpObjList = dtInfos.getLpObjList();
  498 +
  499 + // 构建第一行数据
  500 + XSSFRow lpHeadRow = sheet.createRow((short) 0);
  501 + if (lpObjList.size() == 0) {
  502 + throw new RuntimeException("没有班次数据!");
  503 + }
  504 + int groupCount = lpObjList.get(0).getGroupCount(); // 获取总圈数
  505 + if (groupCount == 0) {
  506 + throw new RuntimeException("总圈数为0,有问题!");
  507 + }
484 508  
485   - // 2、统计项目
486   - sheet.getRow(startrow + 2 + i).getCell(1).setCellValue(statInfo.getStatItem());
  509 + // 构造表头,添加一个进场,添加一个出场
  510 + PoiUtils.createStringXSSFCell(wb, lpHeadRow, (short)0, "路牌", new Color(0x96b9d7));
  511 + Station station1 = stationService.findById(lpObjList.get(0).getStationRouteId1());
  512 + Station station2 = stationService.findById(lpObjList.get(1).getStationRouteId2());
  513 + PoiUtils.createStringXSSFCell(wb, lpHeadRow, (short) (1),
  514 + "出场", new Color(0x96b9d7));
  515 + for (int i = 1; i <= groupCount; i++) {
  516 + PoiUtils.createStringXSSFCell(wb, lpHeadRow, (short) (i * 2),
  517 + station1.getStationName(), new Color(0x96b9d7));
  518 + PoiUtils.createStringXSSFCell(wb, lpHeadRow, (short) (i * 2 + 1),
  519 + station2.getStationName(), new Color(0x96b9d7));
  520 + }
  521 + PoiUtils.createStringXSSFCell(wb, lpHeadRow, (short) (groupCount * 2 + 2),
  522 + "进场", new Color(0x96b9d7));
  523 +
  524 + // 构建每个路牌的班次数据
  525 + for (int i = 0; i < lpObjList.size(); i++) {
  526 + LpObj lpObj = lpObjList.get(i);
  527 + XSSFRow lpRow = sheet.createRow((short) (i + 1));
  528 + PoiUtils.createStringXSSFCell(wb, lpRow, (short) 0, lpObj.getLpname());
  529 + PoiUtils.createBlankXSSFCell(wb, lpRow, (short) (1));
  530 + for (int j = 1; j <= groupCount; j++) {
  531 + PoiUtils.createBlankXSSFCell(wb, lpRow, (short) (j * 2));
  532 + PoiUtils.createBlankXSSFCell(wb, lpRow, (short) (j * 2 + 1));
  533 + }
  534 + PoiUtils.createBlankXSSFCell(wb, lpRow, (short) (groupCount * 2 + 2));
487 535  
488   - // 3、统计数值
489   - PoiUtils.setDoubleStyleXSSFCellStyle(wb, sheet.getRow(startrow + 2 + i).getCell(9));
490   - sheet.getRow(startrow + 2 + i).getCell(9).setCellValue(statInfo.getStatValue());
  536 + for (BcObj bcObj : lpObj.getBcObjList()) {
  537 + if (bcObj.getBcType() == BcType.NORMAL) {
  538 + Cell cell = lpRow.getCell((short) (bcObj.getGroupNo() * 2 + bcObj.getGroupBcNo() + 2));
  539 + cell.setCellValue(bcObj.getFcsj());
  540 + } else if (bcObj.getBcType() == BcType.OUT) {
  541 + Cell cell = lpRow.getCell((short) (1));
  542 + cell.setCellValue(bcObj.getFcsj());
  543 + } else if (bcObj.getBcType() == BcType.IN) {
  544 + Cell cell = lpRow.getCell((short) (groupCount * 2 + 2));
  545 + cell.setCellValue(bcObj.getFcsj());
  546 + }
491 547 }
  548 + }
  549 +
  550 + // 自适应单元格长宽
  551 + sheet.autoSizeColumn(0);
  552 + sheet.autoSizeColumn(1);
  553 + for (int i = 1; i <= groupCount; i++) {
  554 + sheet.autoSizeColumn(i * 2);
  555 + sheet.autoSizeColumn(i * 2 + 1);
  556 + }
  557 +
  558 + }
  559 +
  560 + @Override
  561 + public DataToolsFile exportDynamicTTinfo(DTInfos dtInfos) throws ScheduleException {
  562 + try {
  563 + // 使用POI,创建xlsx文件
  564 + XSSFWorkbook wb = new XSSFWorkbook();
  565 + this.createDynamicTTinfoSheet(wb, dtInfos);
  566 + this.createDynamicTTinfoStatSheet(wb, dtInfos);
492 567  
493   - // 最后内存写入文件
  568 + // wb内存写入文件
494 569 String filepath = dataToolsProperties.getFileoutputDir() +
495 570 File.separator +
496 571 "动态时刻表-" +
... ...
src/main/java/com/bsth/service/schedule/datatools/TTinfoDetailDynamicData.java
1   -package com.bsth.service.schedule.datatools;
2   -
3   -import com.bsth.service.schedule.exception.ScheduleException;
4   -import com.bsth.service.schedule.utils.DataToolsFile;
5   -import com.fasterxml.jackson.annotation.JsonCreator;
6   -import com.fasterxml.jackson.annotation.JsonValue;
7   -
8   -import java.util.List;
9   -
10   -/**
11   - * 动态时刻表数据。
12   - */
13   -public interface TTinfoDetailDynamicData {
14   -
15   - //---------------------- 生成时刻表用对象(以下) ---------------------//
16   - public static enum BcType { // 班次类型枚举
17   - IN("in"), // 进场
18   - OUT("out"), // 出场
19   - BD("bd"), // 早例保
20   - LC("lc"), // 晚例保
21   - NORMAL("normal"); // 正常
22   - private String flag;
23   -
24   - @JsonCreator
25   - private BcType(String flag) {
26   - this.flag = flag;
27   - }
28   -
29   - @JsonValue
30   - public String getFlag() {
31   - return flag;
32   - }
33   -
34   - public void setFlag(String flag) {
35   - this.flag = flag;
36   - }
37   - }
38   -
39   - public static class BcObj { // 班次对象
40   - /** 班次时间 */
41   - private Integer bcsj;
42   - /** 停站时间 */
43   - private Integer ssj;
44   - /** 吃饭时间 */
45   - private Integer eatsj;
46   -
47   - /** 停车场id */
48   - private Integer tccid;
49   - /** 起点站id */
50   - private Integer qdzid;
51   - /** 终点站id */
52   - private Integer zdzid;
53   -
54   - /** 是否上行 */
55   - private Boolean isUp;
56   -
57   - /** 班次类型 */
58   - private BcType bcType;
59   - /** 发车时刻 */
60   - private String fcsj;
61   -
62   - /** 第几圈(从1开始) */
63   - private Integer groupNo;
64   - /** 圈里第几个班次(1或者2) */
65   - private Integer groupBcNo;
66   -
67   - public Integer getBcsj() {
68   - return bcsj;
69   - }
70   -
71   - public void setBcsj(Integer bcsj) {
72   - this.bcsj = bcsj;
73   - }
74   -
75   - public Integer getSsj() {
76   - return ssj;
77   - }
78   -
79   - public void setSsj(Integer ssj) {
80   - this.ssj = ssj;
81   - }
82   -
83   - public Integer getEatsj() {
84   - return eatsj;
85   - }
86   -
87   - public void setEatsj(Integer eatsj) {
88   - this.eatsj = eatsj;
89   - }
90   -
91   - public Integer getTccid() {
92   - return tccid;
93   - }
94   -
95   - public void setTccid(Integer tccid) {
96   - this.tccid = tccid;
97   - }
98   -
99   - public Integer getQdzid() {
100   - return qdzid;
101   - }
102   -
103   - public void setQdzid(Integer qdzid) {
104   - this.qdzid = qdzid;
105   - }
106   -
107   - public Integer getZdzid() {
108   - return zdzid;
109   - }
110   -
111   - public void setZdzid(Integer zdzid) {
112   - this.zdzid = zdzid;
113   - }
114   -
115   - public BcType getBcType() {
116   - return bcType;
117   - }
118   -
119   - public void setBcType(BcType bcType) {
120   - this.bcType = bcType;
121   - }
122   -
123   - public String getFcsj() {
124   - return fcsj;
125   - }
126   -
127   - public void setFcsj(String fcsj) {
128   - this.fcsj = fcsj;
129   - }
130   -
131   - public Boolean getIsUp() {
132   - return isUp;
133   - }
134   -
135   - public void setIsUp(Boolean isUp) {
136   - this.isUp = isUp;
137   - }
138   -
139   - public Integer getGroupNo() {
140   - return groupNo;
141   - }
142   -
143   - public void setGroupNo(Integer groupNo) {
144   - this.groupNo = groupNo;
145   - }
146   -
147   - public Integer getGroupBcNo() {
148   - return groupBcNo;
149   - }
150   -
151   - public void setGroupBcNo(Integer groupBcNo) {
152   - this.groupBcNo = groupBcNo;
153   - }
154   - }
155   -
156   - public static class LpObj { // 路牌对象
157   - /** 路牌名字 */
158   - private String lpname;
159   - /** 每圈的第一个班次是否上行 */
160   - private Boolean isUp;
161   -
162   - /** 第一个班次起点站路由id */
163   - private Integer stationRouteId1;
164   - /** 第二个班次起点站路由id */
165   - private Integer stationRouteId2;
166   -
167   - /** 班次列表 */
168   - private List<BcObj> bcObjList;
169   - /** 总圈数 */
170   - private Integer groupCount;
171   -
172   - /** 总工时 */
173   - private Double zgs;
174   - /** 总班次 */
175   - private Integer zbc;
176   -
177   -
178   - public String getLpname() {
179   - return lpname;
180   - }
181   -
182   - public void setLpname(String lpname) {
183   - this.lpname = lpname;
184   - }
185   -
186   - public Boolean getIsUp() {
187   - return isUp;
188   - }
189   -
190   - public void setIsUp(Boolean isUp) {
191   - this.isUp = isUp;
192   - }
193   -
194   - public List<BcObj> getBcObjList() {
195   - return bcObjList;
196   - }
197   -
198   - public void setBcObjList(List<BcObj> bcObjList) {
199   - this.bcObjList = bcObjList;
200   - }
201   -
202   - public Integer getGroupCount() {
203   - return groupCount;
204   - }
205   -
206   - public void setGroupCount(Integer groupCount) {
207   - this.groupCount = groupCount;
208   - }
209   -
210   - public Double getZgs() {
211   - return zgs;
212   - }
213   -
214   - public void setZgs(Double zgs) {
215   - this.zgs = zgs;
216   - }
217   -
218   - public Integer getZbc() {
219   - return zbc;
220   - }
221   -
222   - public void setZbc(Integer zbc) {
223   - this.zbc = zbc;
224   - }
225   -
226   - public Integer getStationRouteId1() {
227   - return stationRouteId1;
228   - }
229   -
230   - public void setStationRouteId1(Integer stationRouteId1) {
231   - this.stationRouteId1 = stationRouteId1;
232   - }
233   -
234   - public Integer getStationRouteId2() {
235   - return stationRouteId2;
236   - }
237   -
238   - public void setStationRouteId2(Integer stationRouteId2) {
239   - this.stationRouteId2 = stationRouteId2;
240   - }
241   - }
242   -
243   - public static class StatInfo { // 统计数据对象
244   - /** 统计项目 */
245   - private String statItem;
246   - /** 统计值 */
247   - private Double statValue;
248   -
249   - public String getStatItem() {
250   - return statItem;
251   - }
252   -
253   - public void setStatItem(String statItem) {
254   - this.statItem = statItem;
255   - }
256   -
257   - public Double getStatValue() {
258   - return statValue;
259   - }
260   -
261   - public void setStatValue(Double statValue) {
262   - this.statValue = statValue;
263   - }
264   - }
265   -
266   - public static class DTInfos { // 所有数据信息
267   - /** 路牌班次数据列表 */
268   - private List<LpObj> lpObjList;
269   - /** 统计数据列表 */
270   - private List<StatInfo> statInfoList;
271   -
272   - public List<LpObj> getLpObjList() {
273   - return lpObjList;
274   - }
275   -
276   - public void setLpObjList(List<LpObj> lpObjList) {
277   - this.lpObjList = lpObjList;
278   - }
279   -
280   - public List<StatInfo> getStatInfoList() {
281   - return statInfoList;
282   - }
283   -
284   - public void setStatInfoList(List<StatInfo> statInfoList) {
285   - this.statInfoList = statInfoList;
286   - }
287   - }
288   -
289   - //---------------------- 生成时刻表用对象(以上) ---------------------//
290   -
291   - /**
292   - * 导出动态时刻表数据。
293   - * @param dtInfos
294   - * @return
295   - * @throws ScheduleException
296   - */
297   - public DataToolsFile exportDynamicTTinfo(DTInfos dtInfos) throws ScheduleException;
298   -}
  1 +package com.bsth.service.schedule.datatools;
  2 +
  3 +import com.bsth.service.schedule.exception.ScheduleException;
  4 +import com.bsth.service.schedule.utils.DataToolsFile;
  5 +import com.fasterxml.jackson.annotation.JsonCreator;
  6 +import com.fasterxml.jackson.annotation.JsonValue;
  7 +
  8 +import java.util.List;
  9 +
  10 +/**
  11 + * 动态时刻表数据。
  12 + */
  13 +public interface TTinfoDetailDynamicData {
  14 +
  15 + //---------------------- 生成时刻表用对象(以下) ---------------------//
  16 + public static enum BcType { // 班次类型枚举
  17 + IN("in"), // 进场
  18 + OUT("out"), // 出场
  19 + BD("bd"), // 早例保
  20 + LC("lc"), // 晚例保
  21 + NORMAL("normal"); // 正常
  22 + private String flag;
  23 +
  24 + @JsonCreator
  25 + private BcType(String flag) {
  26 + this.flag = flag;
  27 + }
  28 +
  29 + @JsonValue
  30 + public String getFlag() {
  31 + return flag;
  32 + }
  33 +
  34 + public void setFlag(String flag) {
  35 + this.flag = flag;
  36 + }
  37 + }
  38 +
  39 + public static class BcObj { // 班次对象
  40 + /** 班次时间 */
  41 + private Integer bcsj;
  42 + /** 停站时间 */
  43 + private Integer ssj;
  44 + /** 吃饭时间 */
  45 + private Integer eatsj;
  46 +
  47 + /** 停车场id */
  48 + private Integer tccid;
  49 + /** 起点站id */
  50 + private Integer qdzid;
  51 + /** 终点站id */
  52 + private Integer zdzid;
  53 +
  54 + /** 是否上行 */
  55 + private Boolean isUp;
  56 +
  57 + /** 班次类型 */
  58 + private BcType bcType;
  59 + /** 发车时刻 */
  60 + private String fcsj;
  61 + /** 用于统计的发车时间描述(把进出场,保养,吃饭时间写在一起) */
  62 + private String fcsjDesc;
  63 +
  64 + /** 第几圈(从1开始) */
  65 + private Integer groupNo;
  66 + /** 圈里第几个班次(1或者2) */
  67 + private Integer groupBcNo;
  68 +
  69 + public Integer getBcsj() {
  70 + return bcsj;
  71 + }
  72 +
  73 + public void setBcsj(Integer bcsj) {
  74 + this.bcsj = bcsj;
  75 + }
  76 +
  77 + public Integer getSsj() {
  78 + return ssj;
  79 + }
  80 +
  81 + public void setSsj(Integer ssj) {
  82 + this.ssj = ssj;
  83 + }
  84 +
  85 + public Integer getEatsj() {
  86 + return eatsj;
  87 + }
  88 +
  89 + public void setEatsj(Integer eatsj) {
  90 + this.eatsj = eatsj;
  91 + }
  92 +
  93 + public Integer getTccid() {
  94 + return tccid;
  95 + }
  96 +
  97 + public void setTccid(Integer tccid) {
  98 + this.tccid = tccid;
  99 + }
  100 +
  101 + public Integer getQdzid() {
  102 + return qdzid;
  103 + }
  104 +
  105 + public void setQdzid(Integer qdzid) {
  106 + this.qdzid = qdzid;
  107 + }
  108 +
  109 + public Integer getZdzid() {
  110 + return zdzid;
  111 + }
  112 +
  113 + public void setZdzid(Integer zdzid) {
  114 + this.zdzid = zdzid;
  115 + }
  116 +
  117 + public BcType getBcType() {
  118 + return bcType;
  119 + }
  120 +
  121 + public void setBcType(BcType bcType) {
  122 + this.bcType = bcType;
  123 + }
  124 +
  125 + public String getFcsj() {
  126 + return fcsj;
  127 + }
  128 +
  129 + public void setFcsj(String fcsj) {
  130 + this.fcsj = fcsj;
  131 + }
  132 +
  133 + public Boolean getIsUp() {
  134 + return isUp;
  135 + }
  136 +
  137 + public void setIsUp(Boolean isUp) {
  138 + this.isUp = isUp;
  139 + }
  140 +
  141 + public Integer getGroupNo() {
  142 + return groupNo;
  143 + }
  144 +
  145 + public void setGroupNo(Integer groupNo) {
  146 + this.groupNo = groupNo;
  147 + }
  148 +
  149 + public Integer getGroupBcNo() {
  150 + return groupBcNo;
  151 + }
  152 +
  153 + public void setGroupBcNo(Integer groupBcNo) {
  154 + this.groupBcNo = groupBcNo;
  155 + }
  156 +
  157 + public Boolean getUp() {
  158 + return isUp;
  159 + }
  160 +
  161 + public void setUp(Boolean up) {
  162 + isUp = up;
  163 + }
  164 +
  165 + public String getFcsjDesc() {
  166 + return fcsjDesc;
  167 + }
  168 +
  169 + public void setFcsjDesc(String fcsjDesc) {
  170 + this.fcsjDesc = fcsjDesc;
  171 + }
  172 + }
  173 +
  174 + public static class LpObj { // 路牌对象
  175 + /** 路牌名字 */
  176 + private String lpname;
  177 + /** 每圈的第一个班次是否上行 */
  178 + private Boolean isUp;
  179 +
  180 + /** 第一个班次起点站路由id */
  181 + private Integer stationRouteId1;
  182 + /** 第二个班次起点站路由id */
  183 + private Integer stationRouteId2;
  184 +
  185 + /** 班次列表 */
  186 + private List<BcObj> bcObjList;
  187 + /** 总圈数 */
  188 + private Integer groupCount;
  189 +
  190 + /** 总工时 */
  191 + private Double zgs;
  192 + /** 总班次 */
  193 + private Integer zbc;
  194 +
  195 +
  196 + public String getLpname() {
  197 + return lpname;
  198 + }
  199 +
  200 + public void setLpname(String lpname) {
  201 + this.lpname = lpname;
  202 + }
  203 +
  204 + public Boolean getIsUp() {
  205 + return isUp;
  206 + }
  207 +
  208 + public void setIsUp(Boolean isUp) {
  209 + this.isUp = isUp;
  210 + }
  211 +
  212 + public List<BcObj> getBcObjList() {
  213 + return bcObjList;
  214 + }
  215 +
  216 + public void setBcObjList(List<BcObj> bcObjList) {
  217 + this.bcObjList = bcObjList;
  218 + }
  219 +
  220 + public Integer getGroupCount() {
  221 + return groupCount;
  222 + }
  223 +
  224 + public void setGroupCount(Integer groupCount) {
  225 + this.groupCount = groupCount;
  226 + }
  227 +
  228 + public Double getZgs() {
  229 + return zgs;
  230 + }
  231 +
  232 + public void setZgs(Double zgs) {
  233 + this.zgs = zgs;
  234 + }
  235 +
  236 + public Integer getZbc() {
  237 + return zbc;
  238 + }
  239 +
  240 + public void setZbc(Integer zbc) {
  241 + this.zbc = zbc;
  242 + }
  243 +
  244 + public Integer getStationRouteId1() {
  245 + return stationRouteId1;
  246 + }
  247 +
  248 + public void setStationRouteId1(Integer stationRouteId1) {
  249 + this.stationRouteId1 = stationRouteId1;
  250 + }
  251 +
  252 + public Integer getStationRouteId2() {
  253 + return stationRouteId2;
  254 + }
  255 +
  256 + public void setStationRouteId2(Integer stationRouteId2) {
  257 + this.stationRouteId2 = stationRouteId2;
  258 + }
  259 + }
  260 +
  261 + public static class StatInfo { // 统计数据对象
  262 + /** 统计项目 */
  263 + private String statItem;
  264 + /** 统计值 */
  265 + private Double statValue;
  266 +
  267 + public String getStatItem() {
  268 + return statItem;
  269 + }
  270 +
  271 + public void setStatItem(String statItem) {
  272 + this.statItem = statItem;
  273 + }
  274 +
  275 + public Double getStatValue() {
  276 + return statValue;
  277 + }
  278 +
  279 + public void setStatValue(Double statValue) {
  280 + this.statValue = statValue;
  281 + }
  282 + }
  283 +
  284 + public static class DTInfos { // 所有数据信息
  285 + /** 路牌班次数据列表 */
  286 + private List<LpObj> lpObjList;
  287 + /** 统计数据列表 */
  288 + private List<StatInfo> statInfoList;
  289 +
  290 + public List<LpObj> getLpObjList() {
  291 + return lpObjList;
  292 + }
  293 +
  294 + public void setLpObjList(List<LpObj> lpObjList) {
  295 + this.lpObjList = lpObjList;
  296 + }
  297 +
  298 + public List<StatInfo> getStatInfoList() {
  299 + return statInfoList;
  300 + }
  301 +
  302 + public void setStatInfoList(List<StatInfo> statInfoList) {
  303 + this.statInfoList = statInfoList;
  304 + }
  305 + }
  306 +
  307 + //---------------------- 生成时刻表用对象(以上) ---------------------//
  308 +
  309 + /**
  310 + * 导出动态时刻表数据。
  311 + * @param dtInfos
  312 + * @return
  313 + * @throws ScheduleException
  314 + */
  315 + public DataToolsFile exportDynamicTTinfo(DTInfos dtInfos) throws ScheduleException;
  316 +}
... ...
src/main/resources/static/pages/base/timesmodel/js/v2/main_v2.js
1   -/**
2   - * 主类。
3   - */
4   -var Main_v2 = function() {
5   -
6   - // 内部工厂类
7   - var _factoryFun = function() {
8   - return {
9   - // 创建参数
10   - createParameterObj: function(formMap, dataMap) {
11   - var paramObj = ParameterObj();
12   - paramObj.wrap(formMap, dataMap);
13   - return paramObj;
14   - },
15   - // 创建班次对象
16   - createBcObj: function(lpObj, bcType, isUp, fcno, fcTimeObj, paramObj) {
17   - var _bclc = paramObj.calcuTravelLcNumber(isUp, bcType);
18   - var _fcsj = fcTimeObj;
19   - var _bcsj = paramObj.calcuTravelTime(_fcsj, isUp);
20   - var _arrsj = paramObj.addMinute(_fcsj, _bcsj);
21   - //var _stoptime = paramObj.fnCalcuFixedStopNumber(_arrsj, !isUp, _bcsj);
22   - var _stoptime = paramObj.fnCalcuFixedStopNumber(_arrsj, !isUp, undefined);
23   - var _tccid = paramObj.getTTinfoId();
24   - var _ttinfoid = paramObj.getTTinfoId();
25   - var _xl = paramObj.getXlId();
26   - var _qdz = isUp ? paramObj.getUpQdzObj().id : paramObj.getDownQdzObj().id;
27   - var _zdz = isUp ? paramObj.getUpZdzObj().id : paramObj.getDownZdzObj().id;
28   -
29   - if (bcType == "bd") { // 早例保,传过来的发车时间是第一个班次的发车时间
30   - if (isUp) { // 上行
31   - _fcsj = paramObj.addMinute(
32   - _fcsj,
33   - -(paramObj.getUpOutTime() + paramObj.getLbTime()));
34   - _bcsj = paramObj.getLbTime();
35   - _arrsj = paramObj.addMinute(_fcsj, _bcsj);
36   - _stoptime = 0;
37   - } else { // 下行
38   - _fcsj = paramObj.addMinute(
39   - _fcsj,
40   - -(paramObj.getDownOutTime() + paramObj.getLbTime()));
41   - _bcsj = paramObj.getLbTime();
42   - _arrsj = paramObj.addMinute(_fcsj, _bcsj);
43   - _stoptime = 0;
44   - }
45   - } else if (bcType == "lc") { // 晚例保,传过来的发车时间是最后一个班次的到达时间
46   - if (isUp) { // 上行
47   - _fcsj = paramObj.addMinute(
48   - _fcsj,
49   - paramObj.getUpInTime());
50   - _bcsj = paramObj.getLbTime();
51   - _arrsj = paramObj.addMinute(_fcsj, _bcsj);
52   - _stoptime = 0;
53   - } else { // 下行
54   - _fcsj = paramObj.addMinute(
55   - _fcsj,
56   - paramObj.getDownInTime());
57   - _bcsj = paramObj.getLbTime();
58   - _arrsj = paramObj.addMinute(_fcsj, _bcsj);
59   - _stoptime = 0;
60   - }
61   - } else if (bcType == "out") { // 出场,传过来的发车时间是第一个班次的发车时间
62   - if (isUp) { // 上行
63   - _fcsj = paramObj.addMinute(
64   - _fcsj,
65   - -paramObj.getUpOutTime());
66   - _bcsj = paramObj.getUpOutTime();
67   - _arrsj = paramObj.addMinute(_fcsj, _bcsj);
68   - _stoptime = 0;
69   - } else { // 下行
70   - _fcsj = paramObj.addMinute(
71   - _fcsj,
72   - -paramObj.getDownOutTime());
73   - _bcsj = paramObj.getDownOutTime();
74   - _arrsj = paramObj.addMinute(_fcsj, _bcsj);
75   - _stoptime = 0;
76   - }
77   - } else if (bcType == "in") { // 进场,传过来的发车时间是最后一个班次的到达时间
78   - if (isUp) { // 上行
79   - _bcsj = paramObj.getUpInTime();
80   - _arrsj = paramObj.addMinute(_fcsj, _bcsj);
81   - _stoptime = 0;
82   - } else { // 下行
83   - _bcsj = paramObj.getDownInTime();
84   - _arrsj = paramObj.addMinute(_fcsj, _bcsj);
85   - _stoptime = 0;
86   - }
87   - } else if (bcType == "cf") { // 吃饭班次
88   - // 以13:00为分界,之前的为午饭,之后的为晚饭
89   - if (fcTimeObj.isBefore(paramObj.toTimeObj("13:00"))) {
90   - _bcsj = paramObj.fnGetLunchTime();
91   - } else {
92   - _bcsj = paramObj.fnGetDinnerTime();
93   - }
94   - _arrsj = paramObj.addMinute(_fcsj, _bcsj);
95   - _stoptime = 0;
96   - }
97   -
98   - var bcParamObj = {};
99   - bcParamObj.bcType = bcType; // 班次类型(normal,in_,out, bd, lc, cf等)
100   - bcParamObj.isUp = isUp; // boolean是否上下行
101   - bcParamObj.fcno = fcno; // 发车顺序号
102   - bcParamObj.fcTimeObj = _fcsj; // 发车时间对象
103   - bcParamObj.bclc = _bclc; // 班次里程
104   - bcParamObj.bcsj = _bcsj; // 班次历时
105   - bcParamObj.arrtime = _arrsj; // 到达时间对象
106   - bcParamObj.stoptime = _stoptime; // 停站时间
107   - bcParamObj.tccid = _tccid; // 停车场id
108   - bcParamObj.ttinfoid = _ttinfoid; // 时刻表id
109   - bcParamObj.xl = _xl; // 线路id
110   - bcParamObj.qdzid = _qdz; // 起点站id
111   - bcParamObj.zdzid = _zdz; // 终点站id
112   -
113   - return new InternalBcObj(lpObj, bcParamObj);
114   - }
115   - };
116   - };
117   - var _factory = _factoryFun();
118   -
119   - // 所有的时间使用moment.js计算
120   -
121   - var _paramObj; // 参数对象
122   -
123   - var _bxDesc = [ // 班型描述
124   - {'type':'六工一休','hoursV':6.66, 'minueV':'6:40', 'qcount': 0, 'avertime': 0},
125   - {'type':'五工一休','hoursV':6.85, 'minueV':'6:51', 'qcount': 0, 'avertime': 0},
126   - {'type':'四工一休','hoursV':7.14, 'minueV':'7:08', 'qcount': 0, 'avertime': 0},
127   - {'type':'三工一休','hoursV':7.61, 'minueV':'7:37', 'qcount': 0, 'avertime': 0},
128   - {'type':'二工一休','hoursV':8.57, 'minueV':'8:34', 'qcount': 0, 'avertime': 0},
129   - {'type':'一工一休','hoursV':11.42, 'minueV':'11:25', 'qcount': 0, 'avertime': 0},
130   - {'type':'五工二休','hoursV':7.99, 'minueV':'8:00', 'qcount': 0, 'avertime': 0},
131   - {'type':'无工休', 'hoursV':5.43, 'minueV':'5:43', 'qcount': 0, 'avertime': 0}
132   - ];
133   -
134   - var _funCalcuExportData_lpObjList = function(aInternalLpObj) {
135   - // 构造路牌对象
136   - var aLpObj = [];
137   - var i;
138   - var j;
139   - var z;
140   - var oInternalLp;
141   - var oInternalBc;
142   - var oLp;
143   - var iZbc;
144   - var iZgs;
145   - for (i = 0; i < aInternalLpObj.length; i++) {
146   - oInternalLp = aInternalLpObj[i];
147   - iZbc = 0;
148   - iZgs = 0;
149   - oLp = {
150   - "lpname": oInternalLp.getLpName(), // 路牌名字
151   - "isUp": oInternalLp.isUp(), // 每圈的第一个班次是否上行
152   - "bcObjList": [], // 班次列表
153   - "groupCount": oInternalLp.fnGetGroupCount(), // 总圈数
154   - "zgs": 0, // 总工时
155   - "zbc": 0, // 总班次
156   - "stationRouteId1": 0, // 第一个班次起点站路由id
157   - "stationRouteId2": 0 // 第二个班次起点站路由id
158   - };
159   -
160   - // 将报到班次,进出场班次加到班次的时间上
161   - var iBcChainCount;
162   - var oStartBc;
163   - var oEndBc;
164   - var oTempBc;
165   - var aFcsj = [];
166   -
167   - iBcChainCount = oInternalLp.fnGetBcChainCount();
168   - if (iBcChainCount == 1) { // 单一车次链,连班班型
169   - oStartBc = oInternalLp.getBc(
170   - oInternalLp.fnGetBcChainInfo(0)["s_q"],
171   - oInternalLp.fnGetBcChainInfo(0)["s_b"]
172   - );
173   - oTempBc = _factory.createBcObj(
174   - oLp, "bd", true, 1,
175   - oStartBc.getFcTimeObj(),
176   - _paramObj
177   - );
178   - aFcsj.push("(到" + oTempBc.getFcTimeObj().format("HH:mm") + ")");
179   - oTempBc = _factory.createBcObj(
180   - oLp, "out", true, 1,
181   - oStartBc.getFcTimeObj(),
182   - _paramObj
183   - );
184   - aFcsj.push("(出" + oTempBc.getFcTimeObj().format("HH:mm") + ")");
185   - aFcsj.push("(" + oStartBc.getFcTimeObj().format("HH:mm") + ")");
186   - oStartBc._$_fcsj_desc = aFcsj.join("");
187   -
188   - aFcsj = [];
189   -
190   - oEndBc = oInternalLp.getBc(
191   - oInternalLp.fnGetBcChainInfo(0)["e_q"],
192   - oInternalLp.fnGetBcChainInfo(0)["e_b"]
193   - );
194   - aFcsj.push("(" + oStartBc.getFcTimeObj().format("HH:mm") + ")");
195   - oTempBc = _factory.createBcObj(
196   - oLp, "in", true, 1,
197   - oEndBc.getArrTimeObj(),
198   - _paramObj
199   - );
200   - aFcsj.push("(进" + oTempBc.getFcTimeObj().format("HH:mm") + ")");
201   - oTempBc = _factory.createBcObj(
202   - oLp, "lc", true, 1,
203   - oEndBc.getArrTimeObj(),
204   - _paramObj
205   - );
206   - aFcsj.push("(离" + oTempBc.getFcTimeObj().format("HH:mm") + ")");
207   - oEndBc._$_fcsj_desc = aFcsj.join("");
208   -
209   - } else if (iBcChainCount == 2) { // 两个车次链,分班班型
210   - oStartBc = oInternalLp.getBc(
211   - oInternalLp.fnGetBcChainInfo(0)["s_q"],
212   - oInternalLp.fnGetBcChainInfo(0)["s_b"]
213   - );
214   - oTempBc = _factory.createBcObj(
215   - oLp, "bd", true, 1,
216   - oStartBc.getFcTimeObj(),
217   - _paramObj
218   - );
219   - aFcsj.push("(到" + oTempBc.getFcTimeObj().format("HH:mm") + ")");
220   - oTempBc = _factory.createBcObj(
221   - oLp, "out", true, 1,
222   - oStartBc.getFcTimeObj(),
223   - _paramObj
224   - );
225   - aFcsj.push("(出" + oTempBc.getFcTimeObj().format("HH:mm") + ")");
226   - aFcsj.push("(" + oStartBc.getFcTimeObj().format("HH:mm") + ")");
227   - oStartBc._$_fcsj_desc = aFcsj.join("");
228   -
229   - aFcsj = [];
230   -
231   - oEndBc = oInternalLp.getBc(
232   - oInternalLp.fnGetBcChainInfo(0)["e_q"],
233   - oInternalLp.fnGetBcChainInfo(0)["e_b"]
234   - );
235   - aFcsj.push("(" + oStartBc.getFcTimeObj().format("HH:mm") + ")");
236   - oTempBc = _factory.createBcObj(
237   - oLp, "in", true, 1,
238   - oEndBc.getArrTimeObj(),
239   - _paramObj
240   - );
241   - aFcsj.push("(进" + oTempBc.getFcTimeObj().format("HH:mm") + ")");
242   - oTempBc = _factory.createBcObj(
243   - oLp, "lc", true, 1,
244   - oEndBc.getArrTimeObj(),
245   - _paramObj
246   - );
247   - oEndBc._$_fcsj_desc = aFcsj.join("");
248   -
249   - aFcsj = [];
250   -
251   - oStartBc = oInternalLp.getBc(
252   - oInternalLp.fnGetBcChainInfo(1)["s_q"],
253   - oInternalLp.fnGetBcChainInfo(1)["s_b"]
254   - );
255   - oTempBc = _factory.createBcObj(
256   - oLp, "out", true, 1,
257   - oStartBc.getFcTimeObj(),
258   - _paramObj
259   - );
260   - aFcsj.push("(出" + oTempBc.getFcTimeObj().format("HH:mm") + ")");
261   - aFcsj.push("(" + oStartBc.getFcTimeObj().format("HH:mm") + ")");
262   - oStartBc._$_fcsj_desc = aFcsj.join("");
263   -
264   - aFcsj = [];
265   -
266   - oEndBc = oInternalLp.getBc(
267   - oInternalLp.fnGetBcChainInfo(1)["e_q"],
268   - oInternalLp.fnGetBcChainInfo(1)["e_b"]
269   - );
270   - aFcsj.push("(" + oStartBc.getFcTimeObj().format("HH:mm") + ")");
271   - oTempBc = _factory.createBcObj(
272   - oLp, "in", true, 1,
273   - oEndBc.getArrTimeObj(),
274   - _paramObj
275   - );
276   - aFcsj.push("(进" + oTempBc.getFcTimeObj().format("HH:mm") + ")");
277   - oTempBc = _factory.createBcObj(
278   - oLp, "lc", true, 1,
279   - oEndBc.getArrTimeObj(),
280   - _paramObj
281   - );
282   - aFcsj.push("(离" + oTempBc.getFcTimeObj().format("HH:mm") + ")");
283   - oEndBc._$_fcsj_desc = aFcsj.join("");
284   -
285   - }
286   -
287   - for (j = 0; j < oInternalLp.fnGetGroupCount(); j++) {
288   - for (z = 0; z < 2; z++) {
289   - oInternalBc = oInternalLp.getBc(j, z);
290   - if (oInternalBc) {
291   - if (oInternalBc.fnGetEatTime() > 0) {
292   - oInternalBc._$_fcsj_desc = "(吃" + oInternalBc.getFcTimeObj().format("HH:mm") + ")";
293   - }
294   -
295   - oLp.bcObjList.push({
296   - "bcsj": oInternalBc.getBcTime(), // 班次时间
297   - "ssj": oInternalBc.getStopTime(), // 停站时间
298   - "eatsj": oInternalBc.fnGetEatTime(), // 吃饭时间
299   -
300   - "tccid": oInternalBc._$_tccid, // 停车场id
301   - "qdzid": oInternalBc._$_qdzid, // 起点站id
302   - "zdzid": oInternalBc._$_zdzid, // 终点站id
303   -
304   - "isUp": oInternalBc._$_isUp, // 是否上行
305   -
306   - "bcType": oInternalBc._$_bcType, // 班次类型
307   - "fcsj": oInternalBc._$_fcsj_desc || oInternalBc._$_fcsjObj.format("HH:mm"), // 发车时间描述
308   -
309   - "groupNo": j, // 第几圈
310   - "groupBcNo": z // 圈里第几个班次
311   -
312   - });
313   -
314   - iZgs = iZgs +
315   - oInternalBc.getBcTime() + // 班次时间
316   - oInternalBc.getStopTime() + // 停站时间
317   - oInternalBc.fnGetEatTime(); // 吃饭时间
318   - iZbc = iZbc + 1;
319   -
320   - // 设置圈站点路由id
321   - if (oInternalBc.isUp() == oInternalLp.isUp()) { // 第一个班次
322   - if (oLp.stationRouteId1 == 0) {
323   - oLp.stationRouteId1 = oInternalBc._$_qdzid;
324   - }
325   - } else { // 第二个班次
326   - if (oLp.stationRouteId2 == 0) {
327   - oLp.stationRouteId2 = oInternalBc._$_qdzid;
328   - }
329   - }
330   -
331   - }
332   - }
333   -
334   - }
335   -
336   - for (z = 0; z < oInternalLp.getOtherBcArray().length; z++) {
337   - oInternalBc = oInternalLp.getOtherBcArray()[z];
338   - iZgs = iZgs +
339   - oInternalBc.getBcTime() + // 班次时间
340   - oInternalBc.getStopTime(); // 停站时间
341   - if (oInternalBc._$_bcType != "bd" &&
342   - oInternalBc._$_bcType != "lc" &&
343   - oInternalBc._$_bcType != "cf") {
344   - iZbc = iZbc + 1;
345   - }
346   - }
347   -
348   - oLp.zgs = iZgs;
349   - oLp.zbc = iZbc;
350   - aLpObj.push(oLp);
351   - }
352   -
353   - return aLpObj;
354   - };
355   -
356   - var _funCalcuExportData_statInfoList = function(aInternalLpObj) {
357   - var countBc = 0, // 总班次
358   - serviceBc = 0, // 营运班次
359   - jcbc = 0, // 进场总班次.
360   - ccbc = 0, // 出场总班次.
361   - cfbc = 0, // 吃饭总班次.
362   - zwlbbc = 0, // 早晚例保总班次.
363   - countGs = 0.0, // 总工时
364   - servicesj = 0, // 营运班次总时间
365   - jcsj = 0.0, // 进场总时间.
366   - ccsj = 0.0, // 出场总时间.
367   - cfsj = 0.0, // 吃饭总时间.
368   - zwlbsj = 0.0, // 早晚例保总时间.
369   - ksBc = 0, // 空驶班次
370   - serviceLc = 0.0, // 营运里程
371   - ksLc = 0.0, // 空驶里程
372   - avgTzjx = 0.0, // 平均停站间隙
373   - gfServiceBc = 0, // 高峰营运班次
374   - dgServiceBc = 0, // 低谷营运班次
375   - gfAvgTzjx = 0.0, // 高峰平均停站间隙
376   - dgAvgTzjx = 0.0; // 低谷平均停站间隙
377   -
378   - var aAllBc = [];
379   - var oLp;
380   - var oBc;
381   - var i;
382   - var j;
383   -
384   - for (i = 0; i < aInternalLpObj.length; i++) {
385   - oLp = aInternalLpObj[i];
386   - for (j = 0; j < oLp.getBcArray().length; j++) {
387   - aAllBc.push(oLp.getBcArray()[j]);
388   - }
389   - for (j = 0; j < oLp.getOtherBcArray().length; j++) {
390   - aAllBc.push(oLp.getOtherBcArray()[j]);
391   - }
392   - }
393   -
394   - for (i = 0; i < aAllBc.length; i++) {
395   - oBc = aAllBc[i];
396   -
397   - if (oBc.getBcTime() > 0) {
398   - countBc = countBc + 1;
399   - countGs = countGs + oBc.getStopTime() + oBc.getBcTime();
400   - if (_paramObj.isTroughBc(oBc.getFcTimeObj())) {
401   - if (oBc._$_bcType == "normal") {
402   - dgServiceBc = dgServiceBc + 1;
403   - dgAvgTzjx = dgAvgTzjx + oBc.getStopTime();
404   - }
405   - } else {
406   - if (oBc._$_bcType == "normal") {
407   - gfServiceBc = gfServiceBc + 1;
408   - gfAvgTzjx = gfAvgTzjx + oBc.getStopTime();
409   - }
410   - }
411   -
412   - if (oBc._$_bcType == "normal") {
413   - serviceBc = serviceBc + 1;
414   - serviceLc = serviceLc + oBc._$_bclc;
415   - servicesj = servicesj + oBc.getBcTime();
416   - avgTzjx = avgTzjx + oBc.getStopTime();
417   -
418   - if (oBc.fnGetEatTime() > 0) {
419   - cfbc = cfbc + 1;
420   - cfsj = cfsj + oBc.fnGetEatTime();
421   - }
422   - } else if (oBc._$_bcType == "in") {
423   - jcbc = jcbc + 1;
424   - jcsj = jcsj + oBc.getBcTime();
425   - } else if (oBc._$_bcType == "out") {
426   - ccbc = ccbc + 1;
427   - ccsj = ccsj + oBc.getBcTime();
428   - } else if (oBc._$_bcType == "bd") {
429   - zwlbbc = zwlbbc + 1;
430   - zwlbsj = zwlbsj + oBc.getBcTime();
431   - } else if (oBc._$_bcType == "lc") {
432   - zwlbbc = zwlbbc + 1;
433   - zwlbsj = zwlbsj + oBc.getBcTime();
434   - }
435   - }
436   - }
437   -
438   - dgAvgTzjx = dgAvgTzjx / dgServiceBc;
439   - gfAvgTzjx = gfAvgTzjx / gfServiceBc;
440   - avgTzjx = avgTzjx / dgServiceBc;
441   -
442   - return [
443   - {'statItem': '总班次(包括进出场、吃饭时间、早晚例保、营运且班次时间大于零的班次)', 'statValue': countBc},
444   - {'statItem': '进场总班次(包括进场且班次时间大于零的班次)', 'statValue': jcbc},
445   - {'statItem': '出场总班次(包括进场且班次时间大于零的班次)', 'statValue': ccbc},
446   - {'statItem': '吃饭总班次(包括吃饭且班次时间大于零的班次)', 'statValue': cfbc},
447   - {'statItem': '早晚例保总班次(包括早晚例保且时间大于零的班次)', 'statValue': zwlbbc},
448   - {'statItem': '营运总班次(包括正常、区间、放大站且班次时间大于零班次)','statValue': serviceBc},
449   - {'statItem': '进场总时间(包括进场班次且班次时间大于零)', 'statValue': jcsj/60},
450   - {'statItem': '出场总时间(包括进场班次且班次时间大于零)', 'statValue': ccsj/60},
451   - {'statItem': '吃饭总时间(包括吃饭班次且班次时间大于零)', 'statValue': cfsj/60},
452   - {'statItem': '早晚例保总时间(包括早晚例保班次且时间大于零的)', 'statValue': zwlbsj/60},
453   - {'statItem': '营运班次总时间(包括正常、区间、放大站且班次时间大于零)', 'statValue': servicesj/60},
454   - {'statItem': '总工时(包括进出场、吃饭时间、早晚例保、营运班次时间)', 'statValue': countGs/60},
455   - {'statItem': '空驶班次(包括直放班次)', 'statValue': ksBc},
456   - {'statItem': '营运里程(包括正常、区间、放大站里程)', 'statValue': serviceLc},
457   - {'statItem': '空驶里程(包括直放里程)', 'statValue': ksLc},
458   - {'statItem': '平均停站时间(营运班次停站时间总和/营运总班次)', 'statValue': avgTzjx},
459   - {'statItem': '高峰营运班次(包括早晚高峰时段的正常、区间、放大站班次)', 'statValue': gfServiceBc},
460   - {'statItem': '低谷营运班次(包括低谷时段的正常、区间、放大站班次)', 'statValue': dgServiceBc},
461   - {'statItem': '高峰平均停站间隙(高峰营运班次停站时间总和/高峰营运班次总和)', 'statValue': gfAvgTzjx},
462   - {'statItem': '低谷平均停站间隙(低谷营运班次停站时间总和/低谷营运班次总和)', 'statValue': dgAvgTzjx},
463   - {'statItem': '综合评估', 'statValue': 3}
464   - ];
465   -
466   - };
467   -
468   - return {
469   - /**
470   - * 工厂对象,创建不同的对象。
471   - * @returns {{createParameterObj, createBcObj}}
472   - */
473   - getFactory: function() {
474   - return _factory;
475   - },
476   -
477   - /**
478   - * 使用发车间隔策略生成时刻表。
479   - * @param paramObj 参数对象
480   - * @param lpArray 路牌数组
481   - * @constructor
482   - */
483   - BXPplaceClassesTime03 : function(paramObj, lpArray) {
484   - // 参数对象
485   - _paramObj = paramObj;
486   -
487   - // 1、初始化行车计划
488   - var schedule = new InternalScheduleObj(_paramObj, lpArray, _factory);
489   - schedule.fnInitDataWithBxLayout();
490   - // 2、将连班路牌的班次补足
491   - schedule.fnCalcuLpBx_lb();
492   -
493   - // 3、修正针对初始化时生成的高峰班次,之前不足的补上,多余的删除
494   - schedule.fnAdjustGfbc(true, true); // 修正上行早高峰
495   - schedule.fnAdjustGfbc(true, false); // 修正下行早高峰
496   - schedule.fnAdjustGfbc(false, true); // 修正上行晚高峰
497   - schedule.fnAdjustGfbc(false, false); // 修正下行晚高峰
498   -
499   - // 6、补吃饭班次
500   - schedule.fnCalcuEatBc();
501   -
502   - // 4、按照车辆投入运营要求补充班次
503   - schedule.fnCalcuLpBc_yy();
504   -
505   - // 5、根据班型补充所有的不足班次
506   - schedule.fnCalcuLpBx_5_2();
507   - schedule.fnCalcuLpBx_other();
508   -
509   - // 7、祛除上标线开头有删除标记的班次
510   - schedule.fnRemoveDelFirstFlagBc();
511   -
512   - // TODO:8、调整路牌班次间隔
513   - schedule.fnAdjustLpBcInterval(1);
514   -
515   - // TODO:9、调整纵向班次间隔
516   - schedule.fnAdjustBcInterval(true, false, 10);
517   - schedule.fnAdjustBcInterval(false, false, 10);
518   -
519   - // 10、确定末班车
520   - schedule.fnCalcuLastBc();
521   -
522   - // 11、祛除上标线结尾有删除标记的班次
523   - schedule.fnRemoveDelLastFlagBc();
524   -
525   - // TODO:12、平均化指定时间后的班次列表间隔
526   - schedule.fnAdjustBcInterval2_avg(true, _paramObj.toTimeObj("19:50"));
527   - schedule.fnAdjustBcInterval2_avg(false, _paramObj.toTimeObj("19:50"));
528   -
529   - // 10、补进出场例保班次
530   - schedule.fnCalcuOtherBc();
531   -
532   - //-------------------- 输出ganut图上的班次,班型描述 ----------------------//
533   - // TODO:班型再议
534   - return {
535   - 'json':schedule.fnToGanttBcArray(),'bxrcgs':null,
536   - 'aInternalLpObj': schedule.fnGetLpArray()
537   - };
538   -
539   - },
540   - /**
541   - * 导出时刻表配置。
542   - * @param aInternalLpObj 内部路牌对象列表
543   - */
544   - exportDataConfig: function(aInternalLpObj) {
545   - $('.exportAdd').on('click',function() {
546   - var aInfos = {
547   - "lpObjList": _funCalcuExportData_lpObjList(aInternalLpObj), // 路牌班次信息列表
548   - "statInfoList": _funCalcuExportData_statInfoList(aInternalLpObj) // 统计项目列表
549   - };
550   -
551   - console.log(aInfos);
552   -
553   - $(".exportAdd").addClass("disabled");
554   - $(".exportAdd").html("<i class=\"fa fa-spinner\" aria-hidden=\"true\"></i>" + " 正在导出...");
555   -
556   - // 提交
557   - $.ajax({
558   - type: 'POST',
559   - url: "/tidc/exportDTDFile",
560   - dataType: 'binary',
561   - contentType: "application/json",
562   - data: JSON.stringify(aInfos),
563   - success: function(data){
564   - Main_v2.downloadFile(data, "application/octet-stream", "时刻表信息.xls");
565   -
566   - $(".exportAdd").removeClass("disabled");
567   - $(".exportAdd").html("<i class=\"fa fa-file-excel-o\"></i>" + " 导出数据");
568   - },
569   - error: function(xhr, type){
570   - alert('错误:TODO');
571   -
572   - $(".exportAdd").removeClass("disabled");
573   - $(".exportAdd").html("<i class=\"fa fa-file-excel-o\"></i>" + " 导出数据");
574   - }
575   - });
576   -
577   - });
578   - },
579   -
580   - downloadFile: function (data, mimeType, fileName) {
581   - var success = false;
582   - var blob = new Blob([data], { type: mimeType });
583   - try {
584   - if (navigator.msSaveBlob)
585   - navigator.msSaveBlob(blob, fileName);
586   - else {
587   - // Try using other saveBlob implementations, if available
588   - var saveBlob = navigator.webkitSaveBlob || navigator.mozSaveBlob || navigator.saveBlob;
589   - if (saveBlob === undefined) throw "Not supported";
590   - saveBlob(blob, fileName);
591   - }
592   - success = true;
593   - } catch (ex) {
594   - console.log("saveBlob method failed with the following exception:");
595   - console.log(ex);
596   - }
597   -
598   - if (!success) {
599   - // Get the blob url creator
600   - var urlCreator = window.URL || window.webkitURL || window.mozURL || window.msURL;
601   - if (urlCreator) {
602   - // Try to use a download link
603   - var link = document.createElement('a');
604   - if ('download' in link) {
605   - // Try to simulate a click
606   - try {
607   - // Prepare a blob URL
608   - var url = urlCreator.createObjectURL(blob);
609   - link.setAttribute('href', url);
610   -
611   - // Set the download attribute (Supported in Chrome 14+ / Firefox 20+)
612   - link.setAttribute("download", fileName);
613   -
614   - // Simulate clicking the download link
615   - var event = document.createEvent('MouseEvents');
616   - event.initMouseEvent('click', true, true, window, 1, 0, 0, 0, 0, false, false, false, false, 0, null);
617   - link.dispatchEvent(event);
618   - success = true;
619   -
620   - } catch (ex) {
621   - console.log("Download link method with simulated click failed with the following exception:");
622   - console.log(ex);
623   - }
624   - }
625   -
626   - if (!success) {
627   - // Fallback to window.location method
628   - try {
629   - // Prepare a blob URL
630   - // Use application/octet-stream when using window.location to force download
631   - var url = urlCreator.createObjectURL(blob);
632   - window.location = url;
633   - console.log("Download link method with window.location succeeded");
634   - success = true;
635   - } catch (ex) {
636   - console.log("Download link method with window.location failed with the following exception:");
637   - console.log(ex);
638   - }
639   - }
640   - }
641   - }
642   -
643   - if (!success) {
644   - // Fallback to window.open method
645   - console.log("No methods worked for saving the arraybuffer, using last resort window.open");
646   - window.open("", '_blank', '');
647   - }
648   - }
649   -
650   - };
651   -
652   -}();
  1 +/**
  2 + * 主类。
  3 + */
  4 +var Main_v2 = function() {
  5 +
  6 + // 内部工厂类
  7 + var _factoryFun = function() {
  8 + return {
  9 + // 创建参数
  10 + createParameterObj: function(formMap, dataMap) {
  11 + var paramObj = ParameterObj();
  12 + paramObj.wrap(formMap, dataMap);
  13 + return paramObj;
  14 + },
  15 + // 创建班次对象
  16 + createBcObj: function(lpObj, bcType, isUp, fcno, fcTimeObj, paramObj) {
  17 + var _bclc = paramObj.calcuTravelLcNumber(isUp, bcType);
  18 + var _fcsj = fcTimeObj;
  19 + var _bcsj = paramObj.calcuTravelTime(_fcsj, isUp);
  20 + var _arrsj = paramObj.addMinute(_fcsj, _bcsj);
  21 + //var _stoptime = paramObj.fnCalcuFixedStopNumber(_arrsj, !isUp, _bcsj);
  22 + var _stoptime = paramObj.fnCalcuFixedStopNumber(_arrsj, !isUp, undefined);
  23 + var _tccid = paramObj.getTTinfoId();
  24 + var _ttinfoid = paramObj.getTTinfoId();
  25 + var _xl = paramObj.getXlId();
  26 + var _qdz = isUp ? paramObj.getUpQdzObj().id : paramObj.getDownQdzObj().id;
  27 + var _zdz = isUp ? paramObj.getUpZdzObj().id : paramObj.getDownZdzObj().id;
  28 +
  29 + if (bcType == "bd") { // 早例保,传过来的发车时间是第一个班次的发车时间
  30 + if (isUp) { // 上行
  31 + _fcsj = paramObj.addMinute(
  32 + _fcsj,
  33 + -(paramObj.getUpOutTime() + paramObj.getLbTime()));
  34 + _bcsj = paramObj.getLbTime();
  35 + _arrsj = paramObj.addMinute(_fcsj, _bcsj);
  36 + _stoptime = 0;
  37 + } else { // 下行
  38 + _fcsj = paramObj.addMinute(
  39 + _fcsj,
  40 + -(paramObj.getDownOutTime() + paramObj.getLbTime()));
  41 + _bcsj = paramObj.getLbTime();
  42 + _arrsj = paramObj.addMinute(_fcsj, _bcsj);
  43 + _stoptime = 0;
  44 + }
  45 + } else if (bcType == "lc") { // 晚例保,传过来的发车时间是最后一个班次的到达时间
  46 + if (isUp) { // 上行
  47 + _fcsj = paramObj.addMinute(
  48 + _fcsj,
  49 + paramObj.getUpInTime());
  50 + _bcsj = paramObj.getLbTime();
  51 + _arrsj = paramObj.addMinute(_fcsj, _bcsj);
  52 + _stoptime = 0;
  53 + } else { // 下行
  54 + _fcsj = paramObj.addMinute(
  55 + _fcsj,
  56 + paramObj.getDownInTime());
  57 + _bcsj = paramObj.getLbTime();
  58 + _arrsj = paramObj.addMinute(_fcsj, _bcsj);
  59 + _stoptime = 0;
  60 + }
  61 + } else if (bcType == "out") { // 出场,传过来的发车时间是第一个班次的发车时间
  62 + if (isUp) { // 上行
  63 + _fcsj = paramObj.addMinute(
  64 + _fcsj,
  65 + -paramObj.getUpOutTime());
  66 + _bcsj = paramObj.getUpOutTime();
  67 + _arrsj = paramObj.addMinute(_fcsj, _bcsj);
  68 + _stoptime = 0;
  69 + } else { // 下行
  70 + _fcsj = paramObj.addMinute(
  71 + _fcsj,
  72 + -paramObj.getDownOutTime());
  73 + _bcsj = paramObj.getDownOutTime();
  74 + _arrsj = paramObj.addMinute(_fcsj, _bcsj);
  75 + _stoptime = 0;
  76 + }
  77 + } else if (bcType == "in") { // 进场,传过来的发车时间是最后一个班次的到达时间
  78 + if (isUp) { // 上行
  79 + _bcsj = paramObj.getUpInTime();
  80 + _arrsj = paramObj.addMinute(_fcsj, _bcsj);
  81 + _stoptime = 0;
  82 + } else { // 下行
  83 + _bcsj = paramObj.getDownInTime();
  84 + _arrsj = paramObj.addMinute(_fcsj, _bcsj);
  85 + _stoptime = 0;
  86 + }
  87 + } else if (bcType == "cf") { // 吃饭班次
  88 + // 以13:00为分界,之前的为午饭,之后的为晚饭
  89 + if (fcTimeObj.isBefore(paramObj.toTimeObj("13:00"))) {
  90 + _bcsj = paramObj.fnGetLunchTime();
  91 + } else {
  92 + _bcsj = paramObj.fnGetDinnerTime();
  93 + }
  94 + _arrsj = paramObj.addMinute(_fcsj, _bcsj);
  95 + _stoptime = 0;
  96 + }
  97 +
  98 + var bcParamObj = {};
  99 + bcParamObj.bcType = bcType; // 班次类型(normal,in_,out, bd, lc, cf等)
  100 + bcParamObj.isUp = isUp; // boolean是否上下行
  101 + bcParamObj.fcno = fcno; // 发车顺序号
  102 + bcParamObj.fcTimeObj = _fcsj; // 发车时间对象
  103 + bcParamObj.bclc = _bclc; // 班次里程
  104 + bcParamObj.bcsj = _bcsj; // 班次历时
  105 + bcParamObj.arrtime = _arrsj; // 到达时间对象
  106 + bcParamObj.stoptime = _stoptime; // 停站时间
  107 + bcParamObj.tccid = _tccid; // 停车场id
  108 + bcParamObj.ttinfoid = _ttinfoid; // 时刻表id
  109 + bcParamObj.xl = _xl; // 线路id
  110 + bcParamObj.qdzid = _qdz; // 起点站id
  111 + bcParamObj.zdzid = _zdz; // 终点站id
  112 +
  113 + return new InternalBcObj(lpObj, bcParamObj);
  114 + }
  115 + };
  116 + };
  117 + var _factory = _factoryFun();
  118 +
  119 + // 所有的时间使用moment.js计算
  120 +
  121 + var _paramObj; // 参数对象
  122 +
  123 + var _bxDesc = [ // 班型描述
  124 + {'type':'六工一休','hoursV':6.66, 'minueV':'6:40', 'qcount': 0, 'avertime': 0},
  125 + {'type':'五工一休','hoursV':6.85, 'minueV':'6:51', 'qcount': 0, 'avertime': 0},
  126 + {'type':'四工一休','hoursV':7.14, 'minueV':'7:08', 'qcount': 0, 'avertime': 0},
  127 + {'type':'三工一休','hoursV':7.61, 'minueV':'7:37', 'qcount': 0, 'avertime': 0},
  128 + {'type':'二工一休','hoursV':8.57, 'minueV':'8:34', 'qcount': 0, 'avertime': 0},
  129 + {'type':'一工一休','hoursV':11.42, 'minueV':'11:25', 'qcount': 0, 'avertime': 0},
  130 + {'type':'五工二休','hoursV':7.99, 'minueV':'8:00', 'qcount': 0, 'avertime': 0},
  131 + {'type':'无工休', 'hoursV':5.43, 'minueV':'5:43', 'qcount': 0, 'avertime': 0}
  132 + ];
  133 +
  134 + var _funCalcuExportData_lpObjList = function(aInternalLpObj) {
  135 + // 构造路牌对象
  136 + var aLpObj = [];
  137 + var i;
  138 + var j;
  139 + var z;
  140 + var oInternalLp;
  141 + var oInternalBc;
  142 + var oInternalBc_temp;
  143 + var oLp;
  144 + var iZbc;
  145 + var iZgs;
  146 + for (i = 0; i < aInternalLpObj.length; i++) {
  147 + oInternalLp = aInternalLpObj[i];
  148 + iZbc = 0;
  149 + iZgs = 0;
  150 + oLp = {
  151 + "lpname": oInternalLp.getLpName(), // 路牌名字
  152 + "isUp": oInternalLp.isUp(), // 每圈的第一个班次是否上行
  153 + "bcObjList": [], // 班次列表
  154 + "groupCount": oInternalLp.fnGetGroupCount(), // 总圈数
  155 + "zgs": 0, // 总工时
  156 + "zbc": 0, // 总班次
  157 + "stationRouteId1": 0, // 第一个班次起点站路由id
  158 + "stationRouteId2": 0 // 第二个班次起点站路由id
  159 + };
  160 +
  161 + // 将报到班次,进出场班次加到班次的时间上
  162 + var iBcChainCount;
  163 + var oStartBc;
  164 + var oEndBc;
  165 + var oTempBc;
  166 + var aFcsj = [];
  167 +
  168 + iBcChainCount = oInternalLp.fnGetBcChainCount();
  169 + if (iBcChainCount == 1) { // 单一车次链,连班班型
  170 + oStartBc = oInternalLp.getBc(
  171 + oInternalLp.fnGetBcChainInfo(0)["s_q"],
  172 + oInternalLp.fnGetBcChainInfo(0)["s_b"]
  173 + );
  174 + oTempBc = _factory.createBcObj(
  175 + oLp, "bd", true, 1,
  176 + oStartBc.getFcTimeObj(),
  177 + _paramObj
  178 + );
  179 + aFcsj.push("(到" + oTempBc.getFcTimeObj().format("HH:mm") + ")");
  180 + oTempBc = _factory.createBcObj(
  181 + oLp, "out", true, 1,
  182 + oStartBc.getFcTimeObj(),
  183 + _paramObj
  184 + );
  185 + aFcsj.push("(出" + oTempBc.getFcTimeObj().format("HH:mm") + ")");
  186 + aFcsj.push("(" + oStartBc.getFcTimeObj().format("HH:mm") + ")");
  187 + oStartBc._$_fcsj_desc = aFcsj.join("");
  188 +
  189 + oLp.bcObjList.push({ // 出场班次
  190 + "bcsj": oTempBc.getBcTime(), // 班次时间
  191 + "ssj": oTempBc.getStopTime(), // 停站时间
  192 + "eatsj": oTempBc.fnGetEatTime(), // 吃饭时间
  193 +
  194 + "tccid": oTempBc._$_tccid, // 停车场id
  195 + "qdzid": oTempBc._$_qdzid, // 起点站id
  196 + "zdzid": oTempBc._$_zdzid, // 终点站id
  197 +
  198 + "isUp": oTempBc._$_isUp, // 是否上行
  199 +
  200 + "bcType": oTempBc._$_bcType, // 班次类型
  201 + "fcsj": oTempBc._$_fcsjObj.format("HH:mm"), // 发车时间描述
  202 +
  203 + "groupNo": -1, // 第几圈
  204 + "groupBcNo": -1 // 圈里第几个班次
  205 +
  206 + });
  207 +
  208 + aFcsj = [];
  209 +
  210 + oEndBc = oInternalLp.getBc(
  211 + oInternalLp.fnGetBcChainInfo(0)["e_q"],
  212 + oInternalLp.fnGetBcChainInfo(0)["e_b"]
  213 + );
  214 + aFcsj.push("(" + oEndBc.getFcTimeObj().format("HH:mm") + ")");
  215 + oTempBc = _factory.createBcObj(
  216 + oLp, "in", true, 1,
  217 + oEndBc.getArrTimeObj(),
  218 + _paramObj
  219 + );
  220 + aFcsj.push("(进" + oTempBc.getFcTimeObj().format("HH:mm") + ")");
  221 +
  222 + oLp.bcObjList.push({ // 进场班次
  223 + "bcsj": oTempBc.getBcTime(), // 班次时间
  224 + "ssj": oTempBc.getStopTime(), // 停站时间
  225 + "eatsj": oTempBc.fnGetEatTime(), // 吃饭时间
  226 +
  227 + "tccid": oTempBc._$_tccid, // 停车场id
  228 + "qdzid": oTempBc._$_qdzid, // 起点站id
  229 + "zdzid": oTempBc._$_zdzid, // 终点站id
  230 +
  231 + "isUp": oTempBc._$_isUp, // 是否上行
  232 +
  233 + "bcType": oTempBc._$_bcType, // 班次类型
  234 + "fcsj": oTempBc._$_fcsjObj.format("HH:mm"), // 发车时间描述
  235 +
  236 + "groupNo": -2, // 第几圈
  237 + "groupBcNo": -2 // 圈里第几个班次
  238 +
  239 + });
  240 +
  241 + oTempBc = _factory.createBcObj(
  242 + oLp, "lc", true, 1,
  243 + oEndBc.getArrTimeObj(),
  244 + _paramObj
  245 + );
  246 + aFcsj.push("(离" + oTempBc.getFcTimeObj().format("HH:mm") + ")");
  247 + oEndBc._$_fcsj_desc = aFcsj.join("");
  248 +
  249 + } else if (iBcChainCount == 2) { // 两个车次链,分班班型
  250 + oStartBc = oInternalLp.getBc(
  251 + oInternalLp.fnGetBcChainInfo(0)["s_q"],
  252 + oInternalLp.fnGetBcChainInfo(0)["s_b"]
  253 + );
  254 + oTempBc = _factory.createBcObj(
  255 + oLp, "bd", true, 1,
  256 + oStartBc.getFcTimeObj(),
  257 + _paramObj
  258 + );
  259 + aFcsj.push("(到" + oTempBc.getFcTimeObj().format("HH:mm") + ")");
  260 + oTempBc = _factory.createBcObj(
  261 + oLp, "out", true, 1,
  262 + oStartBc.getFcTimeObj(),
  263 + _paramObj
  264 + );
  265 + aFcsj.push("(出" + oTempBc.getFcTimeObj().format("HH:mm") + ")");
  266 + aFcsj.push("(" + oStartBc.getFcTimeObj().format("HH:mm") + ")");
  267 + oStartBc._$_fcsj_desc = aFcsj.join("");
  268 +
  269 + oLp.bcObjList.push({ // 出场班次
  270 + "bcsj": oTempBc.getBcTime(), // 班次时间
  271 + "ssj": oTempBc.getStopTime(), // 停站时间
  272 + "eatsj": oTempBc.fnGetEatTime(), // 吃饭时间
  273 +
  274 + "tccid": oTempBc._$_tccid, // 停车场id
  275 + "qdzid": oTempBc._$_qdzid, // 起点站id
  276 + "zdzid": oTempBc._$_zdzid, // 终点站id
  277 +
  278 + "isUp": oTempBc._$_isUp, // 是否上行
  279 +
  280 + "bcType": oTempBc._$_bcType, // 班次类型
  281 + "fcsj": oTempBc._$_fcsjObj.format("HH:mm"), // 发车时间描述
  282 +
  283 + "groupNo": -1, // 第几圈
  284 + "groupBcNo": -1 // 圈里第几个班次
  285 +
  286 + });
  287 +
  288 + aFcsj = [];
  289 +
  290 + oEndBc = oInternalLp.getBc(
  291 + oInternalLp.fnGetBcChainInfo(0)["e_q"],
  292 + oInternalLp.fnGetBcChainInfo(0)["e_b"]
  293 + );
  294 + aFcsj.push("(" + oEndBc.getFcTimeObj().format("HH:mm") + ")");
  295 + oTempBc = _factory.createBcObj(
  296 + oLp, "in", true, 1,
  297 + oEndBc.getArrTimeObj(),
  298 + _paramObj
  299 + );
  300 + aFcsj.push("(进" + oTempBc.getFcTimeObj().format("HH:mm") + ")");
  301 + oTempBc = _factory.createBcObj(
  302 + oLp, "lc", true, 1,
  303 + oEndBc.getArrTimeObj(),
  304 + _paramObj
  305 + );
  306 + oEndBc._$_fcsj_desc = aFcsj.join("");
  307 +
  308 + aFcsj = [];
  309 +
  310 + oStartBc = oInternalLp.getBc(
  311 + oInternalLp.fnGetBcChainInfo(1)["s_q"],
  312 + oInternalLp.fnGetBcChainInfo(1)["s_b"]
  313 + );
  314 + oTempBc = _factory.createBcObj(
  315 + oLp, "out", true, 1,
  316 + oStartBc.getFcTimeObj(),
  317 + _paramObj
  318 + );
  319 + aFcsj.push("(出" + oTempBc.getFcTimeObj().format("HH:mm") + ")");
  320 + aFcsj.push("(" + oStartBc.getFcTimeObj().format("HH:mm") + ")");
  321 + oStartBc._$_fcsj_desc = aFcsj.join("");
  322 +
  323 + aFcsj = [];
  324 +
  325 + oEndBc = oInternalLp.getBc(
  326 + oInternalLp.fnGetBcChainInfo(1)["e_q"],
  327 + oInternalLp.fnGetBcChainInfo(1)["e_b"]
  328 + );
  329 + aFcsj.push("(" + oEndBc.getFcTimeObj().format("HH:mm") + ")");
  330 + oTempBc = _factory.createBcObj(
  331 + oLp, "in", true, 1,
  332 + oEndBc.getArrTimeObj(),
  333 + _paramObj
  334 + );
  335 + aFcsj.push("(进" + oTempBc.getFcTimeObj().format("HH:mm") + ")");
  336 +
  337 + oLp.bcObjList.push({ // 进场班次
  338 + "bcsj": oTempBc.getBcTime(), // 班次时间
  339 + "ssj": oTempBc.getStopTime(), // 停站时间
  340 + "eatsj": oTempBc.fnGetEatTime(), // 吃饭时间
  341 +
  342 + "tccid": oTempBc._$_tccid, // 停车场id
  343 + "qdzid": oTempBc._$_qdzid, // 起点站id
  344 + "zdzid": oTempBc._$_zdzid, // 终点站id
  345 +
  346 + "isUp": oTempBc._$_isUp, // 是否上行
  347 +
  348 + "bcType": oTempBc._$_bcType, // 班次类型
  349 + "fcsj": oTempBc._$_fcsjObj.format("HH:mm"), // 发车时间描述
  350 +
  351 + "groupNo": -2, // 第几圈
  352 + "groupBcNo": -2 // 圈里第几个班次
  353 +
  354 + });
  355 +
  356 + oTempBc = _factory.createBcObj(
  357 + oLp, "lc", true, 1,
  358 + oEndBc.getArrTimeObj(),
  359 + _paramObj
  360 + );
  361 + aFcsj.push("(离" + oTempBc.getFcTimeObj().format("HH:mm") + ")");
  362 + oEndBc._$_fcsj_desc = aFcsj.join("");
  363 +
  364 + }
  365 +
  366 + for (j = 0; j < oInternalLp.fnGetGroupCount(); j++) {
  367 + for (z = 0; z < 2; z++) {
  368 + oInternalBc = oInternalLp.getBc(j, z);
  369 + if (oInternalBc) {
  370 + if (oInternalBc.fnGetEatTime() > 0) {
  371 + // 吃饭班次是下一个班次开始吃,和本班次方向相反
  372 + oInternalBc_temp = oInternalLp.getBc(
  373 + z == 1 ? j + 1 : j,
  374 + z == 1 ? 0 : 1);
  375 +
  376 + oInternalBc_temp._$_fcsj_desc = "(吃" + oInternalBc_temp.getFcTimeObj().format("HH:mm") + ")";
  377 + }
  378 +
  379 + oLp.bcObjList.push({
  380 + "bcsj": oInternalBc.getBcTime(), // 班次时间
  381 + "ssj": oInternalBc.getStopTime(), // 停站时间
  382 + "eatsj": oInternalBc.fnGetEatTime(), // 吃饭时间
  383 +
  384 + "tccid": oInternalBc._$_tccid, // 停车场id
  385 + "qdzid": oInternalBc._$_qdzid, // 起点站id
  386 + "zdzid": oInternalBc._$_zdzid, // 终点站id
  387 +
  388 + "isUp": oInternalBc._$_isUp, // 是否上行
  389 +
  390 + "bcType": oInternalBc._$_bcType, // 班次类型
  391 + "fcsj": oInternalBc._$_fcsjObj.format("HH:mm"), // 发车时间描述
  392 + "fcsjDesc" : oInternalBc._$_fcsj_desc || oInternalBc._$_fcsjObj.format("HH:mm"),
  393 +
  394 + "groupNo": j, // 第几圈
  395 + "groupBcNo": z // 圈里第几个班次
  396 +
  397 + });
  398 +
  399 + iZgs = iZgs +
  400 + oInternalBc.getBcTime() + // 班次时间
  401 + oInternalBc.getStopTime() + // 停站时间
  402 + oInternalBc.fnGetEatTime(); // 吃饭时间
  403 + iZbc = iZbc + 1;
  404 +
  405 + // 设置圈站点路由id
  406 + if (oInternalBc.isUp() == oInternalLp.isUp()) { // 第一个班次
  407 + if (oLp.stationRouteId1 == 0) {
  408 + oLp.stationRouteId1 = oInternalBc._$_qdzid;
  409 + }
  410 + } else { // 第二个班次
  411 + if (oLp.stationRouteId2 == 0) {
  412 + oLp.stationRouteId2 = oInternalBc._$_qdzid;
  413 + }
  414 + }
  415 +
  416 + }
  417 + }
  418 +
  419 + }
  420 +
  421 + for (z = 0; z < oInternalLp.getOtherBcArray().length; z++) {
  422 + oInternalBc = oInternalLp.getOtherBcArray()[z];
  423 + iZgs = iZgs +
  424 + oInternalBc.getBcTime() + // 班次时间
  425 + oInternalBc.getStopTime(); // 停站时间
  426 + if (oInternalBc._$_bcType != "bd" &&
  427 + oInternalBc._$_bcType != "lc" &&
  428 + oInternalBc._$_bcType != "cf") {
  429 + iZbc = iZbc + 1;
  430 + }
  431 + }
  432 +
  433 + oLp.zgs = iZgs;
  434 + oLp.zbc = iZbc;
  435 + aLpObj.push(oLp);
  436 + }
  437 +
  438 + return aLpObj;
  439 + };
  440 +
  441 + var _funCalcuExportData_statInfoList = function(aInternalLpObj) {
  442 + var countBc = 0, // 总班次
  443 + serviceBc = 0, // 营运班次
  444 + jcbc = 0, // 进场总班次.
  445 + ccbc = 0, // 出场总班次.
  446 + cfbc = 0, // 吃饭总班次.
  447 + zwlbbc = 0, // 早晚例保总班次.
  448 + countGs = 0.0, // 总工时
  449 + servicesj = 0, // 营运班次总时间
  450 + jcsj = 0.0, // 进场总时间.
  451 + ccsj = 0.0, // 出场总时间.
  452 + cfsj = 0.0, // 吃饭总时间.
  453 + zwlbsj = 0.0, // 早晚例保总时间.
  454 + ksBc = 0, // 空驶班次
  455 + serviceLc = 0.0, // 营运里程
  456 + ksLc = 0.0, // 空驶里程
  457 + avgTzjx = 0.0, // 平均停站间隙
  458 + gfServiceBc = 0, // 高峰营运班次
  459 + dgServiceBc = 0, // 低谷营运班次
  460 + gfAvgTzjx = 0.0, // 高峰平均停站间隙
  461 + dgAvgTzjx = 0.0; // 低谷平均停站间隙
  462 +
  463 + var aAllBc = [];
  464 + var oLp;
  465 + var oBc;
  466 + var i;
  467 + var j;
  468 +
  469 + for (i = 0; i < aInternalLpObj.length; i++) {
  470 + oLp = aInternalLpObj[i];
  471 + for (j = 0; j < oLp.getBcArray().length; j++) {
  472 + aAllBc.push(oLp.getBcArray()[j]);
  473 + }
  474 + for (j = 0; j < oLp.getOtherBcArray().length; j++) {
  475 + aAllBc.push(oLp.getOtherBcArray()[j]);
  476 + }
  477 + }
  478 +
  479 + for (i = 0; i < aAllBc.length; i++) {
  480 + oBc = aAllBc[i];
  481 +
  482 + if (oBc.getBcTime() > 0) {
  483 + countBc = countBc + 1;
  484 + countGs = countGs + oBc.getStopTime() + oBc.getBcTime();
  485 + if (_paramObj.isTroughBc(oBc.getFcTimeObj())) {
  486 + if (oBc._$_bcType == "normal") {
  487 + dgServiceBc = dgServiceBc + 1;
  488 + dgAvgTzjx = dgAvgTzjx + oBc.getStopTime();
  489 + }
  490 + } else {
  491 + if (oBc._$_bcType == "normal") {
  492 + gfServiceBc = gfServiceBc + 1;
  493 + gfAvgTzjx = gfAvgTzjx + oBc.getStopTime();
  494 + }
  495 + }
  496 +
  497 + if (oBc._$_bcType == "normal") {
  498 + serviceBc = serviceBc + 1;
  499 + serviceLc = serviceLc + oBc._$_bclc;
  500 + servicesj = servicesj + oBc.getBcTime();
  501 + avgTzjx = avgTzjx + oBc.getStopTime();
  502 +
  503 + if (oBc.fnGetEatTime() > 0) {
  504 + cfbc = cfbc + 1;
  505 + cfsj = cfsj + oBc.fnGetEatTime();
  506 + }
  507 + } else if (oBc._$_bcType == "in") {
  508 + jcbc = jcbc + 1;
  509 + jcsj = jcsj + oBc.getBcTime();
  510 + } else if (oBc._$_bcType == "out") {
  511 + ccbc = ccbc + 1;
  512 + ccsj = ccsj + oBc.getBcTime();
  513 + } else if (oBc._$_bcType == "bd") {
  514 + zwlbbc = zwlbbc + 1;
  515 + zwlbsj = zwlbsj + oBc.getBcTime();
  516 + } else if (oBc._$_bcType == "lc") {
  517 + zwlbbc = zwlbbc + 1;
  518 + zwlbsj = zwlbsj + oBc.getBcTime();
  519 + }
  520 + }
  521 + }
  522 +
  523 + dgAvgTzjx = dgAvgTzjx / dgServiceBc;
  524 + gfAvgTzjx = gfAvgTzjx / gfServiceBc;
  525 + avgTzjx = avgTzjx / dgServiceBc;
  526 +
  527 + return [
  528 + {'statItem': '总班次(包括进出场、吃饭时间、早晚例保、营运且班次时间大于零的班次)', 'statValue': countBc},
  529 + {'statItem': '进场总班次(包括进场且班次时间大于零的班次)', 'statValue': jcbc},
  530 + {'statItem': '出场总班次(包括进场且班次时间大于零的班次)', 'statValue': ccbc},
  531 + {'statItem': '吃饭总班次(包括吃饭且班次时间大于零的班次)', 'statValue': cfbc},
  532 + {'statItem': '早晚例保总班次(包括早晚例保且时间大于零的班次)', 'statValue': zwlbbc},
  533 + {'statItem': '营运总班次(包括正常、区间、放大站且班次时间大于零班次)','statValue': serviceBc},
  534 + {'statItem': '进场总时间(包括进场班次且班次时间大于零)', 'statValue': jcsj/60},
  535 + {'statItem': '出场总时间(包括进场班次且班次时间大于零)', 'statValue': ccsj/60},
  536 + {'statItem': '吃饭总时间(包括吃饭班次且班次时间大于零)', 'statValue': cfsj/60},
  537 + {'statItem': '早晚例保总时间(包括早晚例保班次且时间大于零的)', 'statValue': zwlbsj/60},
  538 + {'statItem': '营运班次总时间(包括正常、区间、放大站且班次时间大于零)', 'statValue': servicesj/60},
  539 + {'statItem': '总工时(包括进出场、吃饭时间、早晚例保、营运班次时间)', 'statValue': countGs/60},
  540 + {'statItem': '空驶班次(包括直放班次)', 'statValue': ksBc},
  541 + {'statItem': '营运里程(包括正常、区间、放大站里程)', 'statValue': serviceLc},
  542 + {'statItem': '空驶里程(包括直放里程)', 'statValue': ksLc},
  543 + {'statItem': '平均停站时间(营运班次停站时间总和/营运总班次)', 'statValue': avgTzjx},
  544 + {'statItem': '高峰营运班次(包括早晚高峰时段的正常、区间、放大站班次)', 'statValue': gfServiceBc},
  545 + {'statItem': '低谷营运班次(包括低谷时段的正常、区间、放大站班次)', 'statValue': dgServiceBc},
  546 + {'statItem': '高峰平均停站间隙(高峰营运班次停站时间总和/高峰营运班次总和)', 'statValue': gfAvgTzjx},
  547 + {'statItem': '低谷平均停站间隙(低谷营运班次停站时间总和/低谷营运班次总和)', 'statValue': dgAvgTzjx},
  548 + {'statItem': '综合评估', 'statValue': 3}
  549 + ];
  550 +
  551 + };
  552 +
  553 + return {
  554 + /**
  555 + * 工厂对象,创建不同的对象。
  556 + * @returns {{createParameterObj, createBcObj}}
  557 + */
  558 + getFactory: function() {
  559 + return _factory;
  560 + },
  561 +
  562 + /**
  563 + * 使用发车间隔策略生成时刻表。
  564 + * @param paramObj 参数对象
  565 + * @param lpArray 路牌数组
  566 + * @constructor
  567 + */
  568 + BXPplaceClassesTime03 : function(paramObj, lpArray) {
  569 + // 参数对象
  570 + _paramObj = paramObj;
  571 +
  572 + // 1、初始化行车计划
  573 + var schedule = new InternalScheduleObj(_paramObj, lpArray, _factory);
  574 + schedule.fnInitDataWithBxLayout();
  575 + // 2、将连班路牌的班次补足
  576 + schedule.fnCalcuLpBx_lb();
  577 +
  578 + // 3、修正针对初始化时生成的高峰班次,之前不足的补上,多余的删除
  579 + schedule.fnAdjustGfbc(true, true); // 修正上行早高峰
  580 + schedule.fnAdjustGfbc(true, false); // 修正下行早高峰
  581 + schedule.fnAdjustGfbc(false, true); // 修正上行晚高峰
  582 + schedule.fnAdjustGfbc(false, false); // 修正下行晚高峰
  583 +
  584 + // 6、补吃饭班次
  585 + schedule.fnCalcuEatBc();
  586 +
  587 + // 4、按照车辆投入运营要求补充班次
  588 + schedule.fnCalcuLpBc_yy();
  589 +
  590 + // 5、根据班型补充所有的不足班次
  591 + schedule.fnCalcuLpBx_5_2();
  592 + schedule.fnCalcuLpBx_other();
  593 +
  594 + // 7、祛除上标线开头有删除标记的班次
  595 + schedule.fnRemoveDelFirstFlagBc();
  596 +
  597 + // TODO:8、调整路牌班次间隔
  598 + schedule.fnAdjustLpBcInterval(1);
  599 +
  600 + // TODO:9、调整纵向班次间隔
  601 + schedule.fnAdjustBcInterval(true, false, 10);
  602 + schedule.fnAdjustBcInterval(false, false, 10);
  603 +
  604 + // 10、确定末班车
  605 + schedule.fnCalcuLastBc();
  606 +
  607 + // 11、祛除上标线结尾有删除标记的班次
  608 + schedule.fnRemoveDelLastFlagBc();
  609 +
  610 + // TODO:12、平均化指定时间后的班次列表间隔
  611 + schedule.fnAdjustBcInterval2_avg(true, _paramObj.toTimeObj("19:50"));
  612 + schedule.fnAdjustBcInterval2_avg(false, _paramObj.toTimeObj("19:50"));
  613 +
  614 + // 10、补进出场例保班次
  615 + schedule.fnCalcuOtherBc();
  616 +
  617 + //-------------------- 输出ganut图上的班次,班型描述 ----------------------//
  618 + // TODO:班型再议
  619 + return {
  620 + 'json':schedule.fnToGanttBcArray(),'bxrcgs':null,
  621 + 'aInternalLpObj': schedule.fnGetLpArray()
  622 + };
  623 +
  624 + },
  625 + /**
  626 + * 导出时刻表配置。
  627 + * @param aInternalLpObj 内部路牌对象列表
  628 + */
  629 + exportDataConfig: function(aInternalLpObj) {
  630 + $('.exportAdd').on('click',function() {
  631 + var aInfos = {
  632 + "lpObjList": _funCalcuExportData_lpObjList(aInternalLpObj), // 路牌班次信息列表
  633 + "statInfoList": _funCalcuExportData_statInfoList(aInternalLpObj) // 统计项目列表
  634 + };
  635 +
  636 + console.log(aInfos);
  637 +
  638 + $(".exportAdd").addClass("disabled");
  639 + $(".exportAdd").html("<i class=\"fa fa-spinner\" aria-hidden=\"true\"></i>" + " 正在导出...");
  640 +
  641 + // 提交
  642 + $.ajax({
  643 + type: 'POST',
  644 + url: "/tidc/exportDTDFile",
  645 + dataType: 'binary',
  646 + contentType: "application/json",
  647 + data: JSON.stringify(aInfos),
  648 + success: function(data){
  649 + Main_v2.downloadFile(data, "application/octet-stream", "时刻表信息.xls");
  650 +
  651 + $(".exportAdd").removeClass("disabled");
  652 + $(".exportAdd").html("<i class=\"fa fa-file-excel-o\"></i>" + " 导出数据");
  653 + },
  654 + error: function(xhr, type){
  655 + alert('错误:TODO');
  656 +
  657 + $(".exportAdd").removeClass("disabled");
  658 + $(".exportAdd").html("<i class=\"fa fa-file-excel-o\"></i>" + " 导出数据");
  659 + }
  660 + });
  661 +
  662 + });
  663 + },
  664 +
  665 + downloadFile: function (data, mimeType, fileName) {
  666 + var success = false;
  667 + var blob = new Blob([data], { type: mimeType });
  668 + try {
  669 + if (navigator.msSaveBlob)
  670 + navigator.msSaveBlob(blob, fileName);
  671 + else {
  672 + // Try using other saveBlob implementations, if available
  673 + var saveBlob = navigator.webkitSaveBlob || navigator.mozSaveBlob || navigator.saveBlob;
  674 + if (saveBlob === undefined) throw "Not supported";
  675 + saveBlob(blob, fileName);
  676 + }
  677 + success = true;
  678 + } catch (ex) {
  679 + console.log("saveBlob method failed with the following exception:");
  680 + console.log(ex);
  681 + }
  682 +
  683 + if (!success) {
  684 + // Get the blob url creator
  685 + var urlCreator = window.URL || window.webkitURL || window.mozURL || window.msURL;
  686 + if (urlCreator) {
  687 + // Try to use a download link
  688 + var link = document.createElement('a');
  689 + if ('download' in link) {
  690 + // Try to simulate a click
  691 + try {
  692 + // Prepare a blob URL
  693 + var url = urlCreator.createObjectURL(blob);
  694 + link.setAttribute('href', url);
  695 +
  696 + // Set the download attribute (Supported in Chrome 14+ / Firefox 20+)
  697 + link.setAttribute("download", fileName);
  698 +
  699 + // Simulate clicking the download link
  700 + var event = document.createEvent('MouseEvents');
  701 + event.initMouseEvent('click', true, true, window, 1, 0, 0, 0, 0, false, false, false, false, 0, null);
  702 + link.dispatchEvent(event);
  703 + success = true;
  704 +
  705 + } catch (ex) {
  706 + console.log("Download link method with simulated click failed with the following exception:");
  707 + console.log(ex);
  708 + }
  709 + }
  710 +
  711 + if (!success) {
  712 + // Fallback to window.location method
  713 + try {
  714 + // Prepare a blob URL
  715 + // Use application/octet-stream when using window.location to force download
  716 + var url = urlCreator.createObjectURL(blob);
  717 + window.location = url;
  718 + console.log("Download link method with window.location succeeded");
  719 + success = true;
  720 + } catch (ex) {
  721 + console.log("Download link method with window.location failed with the following exception:");
  722 + console.log(ex);
  723 + }
  724 + }
  725 + }
  726 + }
  727 +
  728 + if (!success) {
  729 + // Fallback to window.open method
  730 + console.log("No methods worked for saving the arraybuffer, using last resort window.open");
  731 + window.open("", '_blank', '');
  732 + }
  733 + }
  734 +
  735 + };
  736 +
  737 +}();
... ...