Commit f4154ee27fd319fc9d12dc4233817d32716b59b2

Authored by 徐烜
1 parent 6752b39e

浦东公交计划调度功能优化

1、添加时刻表编辑中预览视图的导出功能
src/main/java/com/bsth/controller/schedule/core/legacy/TTInfoDetailController.java
@@ -10,6 +10,7 @@ import com.bsth.service.schedule.datatools.TTinfoDetailDynamicData; @@ -10,6 +10,7 @@ import com.bsth.service.schedule.datatools.TTinfoDetailDynamicData;
10 import com.bsth.service.schedule.timetable.ExcelFormatType; 10 import com.bsth.service.schedule.timetable.ExcelFormatType;
11 import com.bsth.service.schedule.utils.DataToolsFile; 11 import com.bsth.service.schedule.utils.DataToolsFile;
12 import com.bsth.service.schedule.utils.DataToolsFileType; 12 import com.bsth.service.schedule.utils.DataToolsFileType;
  13 +import com.bsth.service.schedule.utils.MyHttpUtils;
13 import org.springframework.beans.factory.annotation.Autowired; 14 import org.springframework.beans.factory.annotation.Autowired;
14 import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; 15 import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
15 import org.springframework.web.bind.annotation.*; 16 import org.springframework.web.bind.annotation.*;
@@ -118,12 +119,12 @@ public class TTInfoDetailController extends BController<TTInfoDetail, Long> { @@ -118,12 +119,12 @@ public class TTInfoDetailController extends BController<TTInfoDetail, Long> {
118 } 119 }
119 return rtn; 120 return rtn;
120 } 121 }
121 - 122 +
122 /** 123 /**
123 * 时刻表明细批量插入 124 * 时刻表明细批量插入
124 - * 125 + *
125 * @param entities 126 * @param entities
126 - * 127 + *
127 * @return 128 * @return
128 */ 129 */
129 @RequestMapping(value = "/skbDetailMxSave" ,method = RequestMethod.POST) 130 @RequestMapping(value = "/skbDetailMxSave" ,method = RequestMethod.POST)
@@ -131,6 +132,11 @@ public class TTInfoDetailController extends BController<TTInfoDetail, Long> { @@ -131,6 +132,11 @@ public class TTInfoDetailController extends BController<TTInfoDetail, Long> {
131 return ttInfoDetailService.skbDetailMxSave(entities); 132 return ttInfoDetailService.skbDetailMxSave(entities);
132 } 133 }
133 134
  135 + @GetMapping(value = "/exportPvInfo/{id}")
  136 + public void exportPvInfo(@PathVariable("id") Long ttInfoId, HttpServletResponse response) throws Exception {
  137 + DataToolsFile dataToolsFile = this.ttInfoDetailService.exportPvInfo(ttInfoId);
  138 + MyHttpUtils.responseStreamFile(response, dataToolsFile.getFile());
  139 + }
134 140
135 @RequestMapping(value = "/exportDTDFile/{type}", method = RequestMethod.POST) 141 @RequestMapping(value = "/exportDTDFile/{type}", method = RequestMethod.POST)
136 public void exportFile( 142 public void exportFile(
src/main/java/com/bsth/controller/schedule/datasync/VehicleDataSyncController.java
@@ -6,13 +6,12 @@ import com.bsth.controller.schedule.datasync.request.VehicleDataSyncTaskRequest; @@ -6,13 +6,12 @@ import com.bsth.controller.schedule.datasync.request.VehicleDataSyncTaskRequest;
6 import com.bsth.entity.schedule.datasync.VehicleDataSyncTask; 6 import com.bsth.entity.schedule.datasync.VehicleDataSyncTask;
7 import com.bsth.entity.schedule.datasync.VehicleDataSyncTaskTypeEnum; 7 import com.bsth.entity.schedule.datasync.VehicleDataSyncTaskTypeEnum;
8 import com.bsth.service.schedule.datasync.VehicleDataSyncTaskService; 8 import com.bsth.service.schedule.datasync.VehicleDataSyncTaskService;
9 -import com.bsth.service.schedule.utils.MyStringUtils; 9 +import com.bsth.service.schedule.utils.MyHttpUtils;
10 import org.springframework.beans.factory.annotation.Autowired; 10 import org.springframework.beans.factory.annotation.Autowired;
11 import org.springframework.web.bind.annotation.*; 11 import org.springframework.web.bind.annotation.*;
12 12
13 import javax.servlet.http.HttpServletResponse; 13 import javax.servlet.http.HttpServletResponse;
14 -import java.io.*;  
15 -import java.net.URLEncoder; 14 +import java.io.File;
16 import java.util.Date; 15 import java.util.Date;
17 16
18 @RestController 17 @RestController
@@ -107,38 +106,11 @@ public class VehicleDataSyncController extends BController<VehicleDataSyncTask, @@ -107,38 +106,11 @@ public class VehicleDataSyncController extends BController<VehicleDataSyncTask,
107 } 106 }
108 107
109 try { 108 try {
110 - responseStreamFile(response, file); 109 + MyHttpUtils.responseStreamFile(response, file);
111 } catch (Exception exp) { 110 } catch (Exception exp) {
112 exp.printStackTrace(); 111 exp.printStackTrace();
113 throw new RuntimeException("获取同步日志文件错误:" + exp.getMessage()); 112 throw new RuntimeException("获取同步日志文件错误:" + exp.getMessage());
114 } 113 }
115 } 114 }
116 115
117 - // 流输出文件  
118 - private void responseStreamFile(HttpServletResponse response, File file) throws IOException {  
119 - // 流输出导出文件  
120 - response.setHeader("content-type", "application/octet-stream");  
121 - String fileName = file.getName();  
122 - if (MyStringUtils.isContainChinese(fileName)) {  
123 - response.setHeader("Content-Disposition", "attachment; filename*=" + URLEncoder.encode(fileName, "UTF-8"));  
124 - } else {  
125 - response.setHeader("Content-Disposition", "attachment; filename=" + fileName);  
126 - }  
127 - response.setContentType("application/octet-stream");  
128 -  
129 - try (  
130 - OutputStream os = response.getOutputStream();  
131 - BufferedOutputStream bos = new BufferedOutputStream(os);  
132 - InputStream is = new FileInputStream(file);  
133 - BufferedInputStream bis = new BufferedInputStream(is)  
134 - ) {  
135 - int length;  
136 - byte[] temp = new byte[1024 * 10];  
137 - while ((length = bis.read(temp)) != -1) {  
138 - bos.write(temp, 0, length);  
139 - }  
140 - bos.flush();  
141 - }  
142 - }  
143 -  
144 } 116 }
src/main/java/com/bsth/service/schedule/TTInfoDetailService.java
@@ -34,6 +34,15 @@ public interface TTInfoDetailService extends BService<TTInfoDetail, Long> { @@ -34,6 +34,15 @@ public interface TTInfoDetailService extends BService<TTInfoDetail, Long> {
34 DataToolsFile exportDynamicTTinfo(TTinfoDetailDynamicData.DTInfos dtInfos, DataToolsFileType type) throws ScheduleException; 34 DataToolsFile exportDynamicTTinfo(TTinfoDetailDynamicData.DTInfos dtInfos, DataToolsFileType type) throws ScheduleException;
35 35
36 /** 36 /**
  37 + * 导出时刻表预览视图信息。
  38 + * @param ttInfoId 时刻表Id
  39 + * @return
  40 + * @throws ScheduleException
  41 + */
  42 + DataToolsFile exportPvInfo(Long ttInfoId) throws ScheduleException;
  43 +
  44 +
  45 + /**
37 * 获取时刻表最大发车顺序号 46 * 获取时刻表最大发车顺序号
38 * @param xlid 线路id 47 * @param xlid 线路id
39 * @param ttinfoid 时刻表id 48 * @param ttinfoid 时刻表id
src/main/java/com/bsth/service/schedule/impl/TTInfoDetailServiceImpl.java
@@ -3,8 +3,11 @@ package com.bsth.service.schedule.impl; @@ -3,8 +3,11 @@ package com.bsth.service.schedule.impl;
3 import com.alibaba.fastjson.JSONArray; 3 import com.alibaba.fastjson.JSONArray;
4 import com.alibaba.fastjson.JSONObject; 4 import com.alibaba.fastjson.JSONObject;
5 import com.bsth.common.ResponseCode; 5 import com.bsth.common.ResponseCode;
6 -import com.bsth.entity.*; 6 +import com.bsth.entity.CarPark;
  7 +import com.bsth.entity.Line;
  8 +import com.bsth.entity.LineInformation;
7 import com.bsth.entity.schedule.GuideboardInfo; 9 import com.bsth.entity.schedule.GuideboardInfo;
  10 +import com.bsth.entity.schedule.TTInfo;
8 import com.bsth.entity.schedule.TTInfoDetail; 11 import com.bsth.entity.schedule.TTInfoDetail;
9 import com.bsth.repository.CarParkRepository; 12 import com.bsth.repository.CarParkRepository;
10 import com.bsth.repository.LineRepository; 13 import com.bsth.repository.LineRepository;
@@ -19,20 +22,20 @@ import com.bsth.service.LineService; @@ -19,20 +22,20 @@ import com.bsth.service.LineService;
19 import com.bsth.service.StationRouteService; 22 import com.bsth.service.StationRouteService;
20 import com.bsth.service.schedule.GuideboardInfoService; 23 import com.bsth.service.schedule.GuideboardInfoService;
21 import com.bsth.service.schedule.TTInfoDetailService; 24 import com.bsth.service.schedule.TTInfoDetailService;
  25 +import com.bsth.service.schedule.datatools.Excel2007PoiOperator;
  26 +import com.bsth.service.schedule.datatools.ExcelPoiOperator;
22 import com.bsth.service.schedule.datatools.TTInfoDetailForEdit; 27 import com.bsth.service.schedule.datatools.TTInfoDetailForEdit;
23 import com.bsth.service.schedule.datatools.TTinfoDetailDynamicData; 28 import com.bsth.service.schedule.datatools.TTinfoDetailDynamicData;
24 import com.bsth.service.schedule.exception.ScheduleException; 29 import com.bsth.service.schedule.exception.ScheduleException;
25 import com.bsth.service.schedule.timetable.ExcelData; 30 import com.bsth.service.schedule.timetable.ExcelData;
26 import com.bsth.service.schedule.timetable.ExcelFormatType; 31 import com.bsth.service.schedule.timetable.ExcelFormatType;
27 -import com.bsth.service.schedule.utils.DataToolsFile;  
28 -import com.bsth.service.schedule.utils.DataToolsFileType;  
29 -import com.bsth.service.schedule.utils.DataToolsService;  
30 -import com.bsth.service.schedule.utils.PoiUtils; 32 +import com.bsth.service.schedule.utils.*;
31 import org.apache.commons.lang3.StringUtils; 33 import org.apache.commons.lang3.StringUtils;
32 -import org.apache.poi.ss.usermodel.Cell;  
33 -import org.apache.poi.ss.usermodel.Row;  
34 -import org.apache.poi.ss.usermodel.Sheet;  
35 -import org.apache.poi.ss.usermodel.Workbook; 34 +import org.apache.commons.lang3.time.DateFormatUtils;
  35 +import org.apache.poi.ss.usermodel.*;
  36 +import org.apache.poi.ss.util.CellRangeAddress;
  37 +import org.apache.poi.xssf.usermodel.XSSFCell;
  38 +import org.joda.time.DateTime;
36 import org.slf4j.Logger; 39 import org.slf4j.Logger;
37 import org.slf4j.LoggerFactory; 40 import org.slf4j.LoggerFactory;
38 import org.springframework.beans.factory.annotation.Autowired; 41 import org.springframework.beans.factory.annotation.Autowired;
@@ -42,13 +45,10 @@ import org.springframework.stereotype.Service; @@ -42,13 +45,10 @@ import org.springframework.stereotype.Service;
42 import org.springframework.transaction.annotation.Transactional; 45 import org.springframework.transaction.annotation.Transactional;
43 import org.springframework.util.CollectionUtils; 46 import org.springframework.util.CollectionUtils;
44 47
  48 +import java.awt.Color;
45 import java.io.File; 49 import java.io.File;
46 -import java.util.ArrayList;  
47 -import java.util.HashMap; 50 +import java.util.*;
48 import java.util.List; 51 import java.util.List;
49 -import java.util.Map;  
50 -import java.util.regex.Matcher;  
51 -import java.util.regex.Pattern;  
52 52
53 /** 53 /**
54 * Created by xu on 17/1/3. 54 * Created by xu on 17/1/3.
@@ -149,6 +149,192 @@ public class TTInfoDetailServiceImpl extends BServiceImpl<TTInfoDetail, Long> im @@ -149,6 +149,192 @@ public class TTInfoDetailServiceImpl extends BServiceImpl<TTInfoDetail, Long> im
149 return tTinfoDetailDynamicData.exportDynamicTTinfo(dtInfos, type); 149 return tTinfoDetailDynamicData.exportDynamicTTinfo(dtInfos, type);
150 } 150 }
151 151
  152 + @Autowired
  153 + private DataToolsProperties dataToolsProperties;
  154 +
  155 + @Transactional
  156 + @Override
  157 + public DataToolsFile exportPvInfo(Long ttInfoId) throws ScheduleException {
  158 + // 1、获取时刻表,时刻表明细数据
  159 + TTInfo ttInfo = this.infoRepository.findOneExtend(ttInfoId);
  160 + List<TTInfoDetail> ttInfoDetailList = this.ttInfoDetailRepository.findByTtinfoId(ttInfoId);
  161 + LOGGER.info("----------------- 开始导出时刻表[{}]预览视图信息---------------", ttInfo.getName());
  162 +
  163 + // 2、构造导出信息
  164 + try {
  165 + // 使用excel2007格式(xlsx)
  166 + ExcelPoiOperator excelPoiOperator = new Excel2007PoiOperator();
  167 + Workbook wb = excelPoiOperator.createWorkBook(); // 创建workbook
  168 + Sheet sheet = excelPoiOperator.createWorkBookSheet(wb, "预览信息"); // 创建sheet
  169 +
  170 + // 创建表头(从第2行开始,第1行需要合并单元格显示站点名字)
  171 + int[] headColNums = new int[] {0, 1, 2, 3, 4, 7, 8, 9, 10, 11};
  172 + String[] headColLabels = new String[] {"序号", "路牌", "发车时间", "到达时间", "备注", "序号", "路牌", "发车时间", "到达时间", "备注"};
  173 + int[] headColWidth = new int[] {10, 10, 20, 20, 35, 10, 10, 20, 20, 35};
  174 +
  175 + Row headRow = excelPoiOperator.createSheetRow(sheet, 1);
  176 + headRow.setHeight((short) (35 * 20)); // 单位:1/20个点
  177 + for (int i = 0; i < headColNums.length; i ++) {
  178 + excelPoiOperator.createCell(
  179 + wb, headRow, (short) headColNums[i],
  180 + headColLabels[i], XSSFCell.CELL_TYPE_STRING,
  181 + HorizontalAlignment.CENTER, VerticalAlignment.CENTER,
  182 + BorderStyle.THIN, new java.awt.Color(0x000000),
  183 + (short) 14, new java.awt.Color(0xffffff), "宋体",
  184 + new Color(0x857F7F), FillPatternType.SOLID_FOREGROUND);
  185 + sheet.setColumnWidth(headColNums[i], headColWidth[i] * 256); // 单位:1/256个字符宽度
  186 + }
  187 +
  188 + // 获取上行线路并按照时间排序
  189 + List<TTInfoDetail> upBcList = sortedByBcsjAsc(ttInfoDetailList, true);
  190 + List<TTInfoDetail> downBcList = sortedByBcsjAsc(ttInfoDetailList, false);
  191 + int rowDiff = upBcList.size() - downBcList.size();
  192 + int rowSize;
  193 + if (rowDiff >= 0) { // 上行班次多
  194 + rowSize = downBcList.size();
  195 + } else { // 下行班次多
  196 + rowSize = upBcList.size();
  197 + }
  198 + for (int i = 0; i < rowSize; i++) {
  199 + Row bcRow = excelPoiOperator.createSheetRow(sheet, i + 2);
  200 + // 上行班次
  201 + excelPoiOperator.createIntegerCell(wb, bcRow, (short) 0, i + 1);
  202 + String lpName = upBcList.get(i).getLp().getLpName();
  203 + if (StringUtils.isNumeric(lpName)) {
  204 + excelPoiOperator.createIntegerCell(wb, bcRow, (short) 1, Integer.valueOf(lpName));
  205 + } else {
  206 + excelPoiOperator.createStringCell(wb, bcRow, (short) 1, lpName);
  207 + }
  208 + excelPoiOperator.createStringCell(wb, bcRow, (short) 2, upBcList.get(i).getFcsj());
  209 + Date ddsj_up = MyDateUtils.hhssTimePlusMinunits(upBcList.get(i).getFcsj(), upBcList.get(i).getBcsj(), 0);
  210 + excelPoiOperator.createStringCell(wb, bcRow, (short) 3, DateFormatUtils.format(ddsj_up, "HH:mm"));
  211 + excelPoiOperator.createStringCell(wb, bcRow, (short) 4, StringUtils.trimToEmpty(upBcList.get(i).getRemark()));
  212 +
  213 + // 下行班次
  214 + excelPoiOperator.createIntegerCell(wb, bcRow, (short) 7, i + 1);
  215 + lpName = downBcList.get(i).getLp().getLpName();
  216 + if (StringUtils.isNumeric(lpName)) {
  217 + excelPoiOperator.createIntegerCell(wb, bcRow, (short) 8, Integer.valueOf(lpName));
  218 + } else {
  219 + excelPoiOperator.createStringCell(wb, bcRow, (short) 8, lpName);
  220 + }
  221 + excelPoiOperator.createStringCell(wb, bcRow, (short) 9, downBcList.get(i).getFcsj());
  222 + Date ddsj_down = MyDateUtils.hhssTimePlusMinunits(downBcList.get(i).getFcsj(), downBcList.get(i).getBcsj(), 0);
  223 + excelPoiOperator.createStringCell(wb, bcRow, (short) 10, DateFormatUtils.format(ddsj_down, "HH:mm"));
  224 + excelPoiOperator.createStringCell(wb, bcRow, (short) 11, StringUtils.trimToEmpty(downBcList.get(i).getRemark()));
  225 + }
  226 +
  227 + List<TTInfoDetail> rowDiffBcList; // 剩下的班次
  228 + int rowDiffColIndexStart;
  229 + if (rowDiff >= 0) { // 上行班次多
  230 + rowDiffBcList = upBcList;
  231 + rowDiffColIndexStart = 0;
  232 + } else { // 下行班次多
  233 + rowDiffBcList = downBcList;
  234 + rowDiffColIndexStart = 7;
  235 + }
  236 + for (int i = rowSize; i < rowSize + Math.abs(rowDiff); i++) {
  237 + Row bcRow = excelPoiOperator.createSheetRow(sheet, i + 2);
  238 + excelPoiOperator.createIntegerCell(wb, bcRow, (short) (rowDiffColIndexStart + 0), i + 1);
  239 + String lpName = rowDiffBcList.get(i).getLp().getLpName();
  240 + if (StringUtils.isNumeric(lpName)) {
  241 + excelPoiOperator.createIntegerCell(wb, bcRow, (short) (rowDiffColIndexStart + 1), Integer.valueOf(lpName));
  242 + } else {
  243 + excelPoiOperator.createStringCell(wb, bcRow, (short) (rowDiffColIndexStart + 1), lpName);
  244 + }
  245 + excelPoiOperator.createStringCell(wb, bcRow, (short) (rowDiffColIndexStart + 2), rowDiffBcList.get(i).getFcsj());
  246 + Date ddsj = MyDateUtils.hhssTimePlusMinunits(rowDiffBcList.get(i).getFcsj(), rowDiffBcList.get(i).getBcsj(), 0);
  247 + excelPoiOperator.createStringCell(wb, bcRow, (short) (rowDiffColIndexStart + 3), DateFormatUtils.format(ddsj, "HH:mm"));
  248 + excelPoiOperator.createStringCell(wb, bcRow, (short) (rowDiffColIndexStart + 4), StringUtils.trimToEmpty(rowDiffBcList.get(i).getRemark()));
  249 +
  250 + }
  251 +
  252 + // 创建第一行,合并列
  253 + sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, 4));
  254 + sheet.addMergedRegion(new CellRangeAddress(0, 0, 7, 11));
  255 + Row firstRow = excelPoiOperator.createSheetRow(sheet, 0);
  256 + firstRow.setHeight((short) (50 * 20)); // 单位:1/20个点
  257 + if (upBcList.size() > 0 && downBcList.size() > 0) {
  258 + String upBcLabel = "";
  259 + for (TTInfoDetail ttInfoDetail : upBcList) {
  260 + if ("normal".equals(ttInfoDetail.getBcType())) {
  261 + upBcLabel = "上行站点:" + ttInfoDetail.getQdzName() + " >> " + ttInfoDetail.getZdzName();
  262 + break;
  263 + }
  264 + }
  265 + String downBcLabel = "";
  266 + for (TTInfoDetail ttInfoDetail : downBcList) {
  267 + if ("normal".equals(ttInfoDetail.getBcType())) {
  268 + downBcLabel = "下行站点:" + ttInfoDetail.getQdzName() + " >> " + ttInfoDetail.getZdzName();
  269 + break;
  270 + }
  271 + }
  272 +
  273 + excelPoiOperator.createCell(
  274 + wb, firstRow, (short) 0,
  275 + upBcLabel, XSSFCell.CELL_TYPE_STRING,
  276 + HorizontalAlignment.CENTER, VerticalAlignment.CENTER,
  277 + BorderStyle.NONE, new java.awt.Color(0x000000),
  278 + (short) 20, new java.awt.Color(0xffffff), "宋体",
  279 + new Color(0x857F7F), FillPatternType.SOLID_FOREGROUND);
  280 +
  281 + excelPoiOperator.createCell(
  282 + wb, firstRow, (short) 7,
  283 + downBcLabel, XSSFCell.CELL_TYPE_STRING,
  284 + HorizontalAlignment.CENTER, VerticalAlignment.CENTER,
  285 + BorderStyle.NONE, new java.awt.Color(0x000000),
  286 + (short) 20, new java.awt.Color(0xffffff), "宋体",
  287 + new Color(0x857F7F), FillPatternType.SOLID_FOREGROUND);
  288 + }
  289 +
  290 + // 锁定第1第2行
  291 + sheet.createFreezePane(0, 2);
  292 +
  293 + // wb内存写入文件
  294 + String filepath = dataToolsProperties.getFileoutputDir() +
  295 + File.separator +
  296 + ttInfo.getName() + "预览信息-" +
  297 + new DateTime().toString("yyyyMMddHHmmss") + ".xlsx";
  298 + File file = new File(filepath);
  299 + excelPoiOperator.writeExcel(file, wb);
  300 +
  301 + DataToolsFile dataToolsFile = new DataToolsFile();
  302 + dataToolsFile.setFileType(DataToolsFileType.XLSX);
  303 + dataToolsFile.setFile(file);
  304 +
  305 + return dataToolsFile;
  306 +
  307 + } catch (Exception exp) {
  308 + LOGGER.error("----------------- 导出时刻表[{}]预览视图信息失败---------------", ttInfo.getName());
  309 + throw new ScheduleException(exp);
  310 + }
  311 + }
  312 + private List<TTInfoDetail> sortedByBcsjAsc(List<TTInfoDetail> bcList, boolean isUp) {
  313 + List<TTInfoDetail> sortedList = new ArrayList<>();
  314 + for (TTInfoDetail ttInfoDetail : bcList) {
  315 + if (isUp) {
  316 + if ("0".equals(ttInfoDetail.getXlDir())) {
  317 + sortedList.add(ttInfoDetail);
  318 + }
  319 + } else {
  320 + if ("1".equals(ttInfoDetail.getXlDir())) {
  321 + sortedList.add(ttInfoDetail);
  322 + }
  323 + }
  324 + }
  325 + Collections.sort(sortedList, new Comparator<TTInfoDetail>() {
  326 + @Override
  327 + public int compare(TTInfoDetail o1, TTInfoDetail o2) {
  328 + Date d1 = MyDateUtils.hhssTimePlusMinunits(o1.getFcsj(), 0, 0);
  329 + Date d2 = MyDateUtils.hhssTimePlusMinunits(o2.getFcsj(), 0, 0);
  330 +
  331 + return d1.compareTo(d2);
  332 + }
  333 + });
  334 +
  335 + return sortedList;
  336 + }
  337 +
152 @Override 338 @Override
153 public TTInfoDetailForEdit.EditInfo getEditInfo(Integer xlid, Long ttid, Long maxfcno) throws ScheduleException { 339 public TTInfoDetailForEdit.EditInfo getEditInfo(Integer xlid, Long ttid, Long maxfcno) throws ScheduleException {
154 return ttInfoDetailForEdit.getEditInfo(xlid, ttid, maxfcno); 340 return ttInfoDetailForEdit.getEditInfo(xlid, ttid, maxfcno);
@@ -225,11 +411,11 @@ public class TTInfoDetailServiceImpl extends BServiceImpl&lt;TTInfoDetail, Long&gt; im @@ -225,11 +411,11 @@ public class TTInfoDetailServiceImpl extends BServiceImpl&lt;TTInfoDetail, Long&gt; im
225 411
226 /** 412 /**
227 * @description (TODO) 时刻表明细模型数据保存. 413 * @description (TODO) 时刻表明细模型数据保存.
228 - * 414 + *
229 * @param map 415 * @param map
230 - * 416 + *
231 * @return : 返回保存操作后的状态. 417 * @return : 返回保存操作后的状态.
232 - * 418 + *
233 * @exception 处理所有抛出来的异常. 419 * @exception 处理所有抛出来的异常.
234 * */ 420 * */
235 @Transactional 421 @Transactional
@@ -241,7 +427,7 @@ public class TTInfoDetailServiceImpl extends BServiceImpl&lt;TTInfoDetail, Long&gt; im @@ -241,7 +427,7 @@ public class TTInfoDetailServiceImpl extends BServiceImpl&lt;TTInfoDetail, Long&gt; im
241 //boolean b = map.get("istidc") ==null ? false : Boolean.parseBoolean(map.get("istidc").toString()); 427 //boolean b = map.get("istidc") ==null ? false : Boolean.parseBoolean(map.get("istidc").toString());
242 Long ttinfoid = map.get("skb") ==null ? null : Long.parseLong(map.get("skb").toString()); 428 Long ttinfoid = map.get("skb") ==null ? null : Long.parseLong(map.get("skb").toString());
243 Integer xlid = map.get("xl") ==null ? null : Integer.parseInt(map.get("xl").toString()); 429 Integer xlid = map.get("xl") ==null ? null : Integer.parseInt(map.get("xl").toString());
244 - if(xlid !=null && ttinfoid !=null) 430 + if(xlid !=null && ttinfoid !=null)
245 ttInfoDetailRepository.deltidc(xlid,ttinfoid); 431 ttInfoDetailRepository.deltidc(xlid,ttinfoid);
246 if(d!=null) 432 if(d!=null)
247 ttInfoDetailRepository.saveAll(jsonArrayToListEntity(d));// 2、保存. 433 ttInfoDetailRepository.saveAll(jsonArrayToListEntity(d));// 2、保存.
@@ -252,14 +438,14 @@ public class TTInfoDetailServiceImpl extends BServiceImpl&lt;TTInfoDetail, Long&gt; im @@ -252,14 +438,14 @@ public class TTInfoDetailServiceImpl extends BServiceImpl&lt;TTInfoDetail, Long&gt; im
252 rs_m.put("status", ResponseCode.SUCCESS); 438 rs_m.put("status", ResponseCode.SUCCESS);
253 return rs_m; 439 return rs_m;
254 } 440 }
255 - 441 +
256 /** 442 /**
257 * @description : (TODO) json班次数据转list班次. 443 * @description : (TODO) json班次数据转list班次.
258 - * 444 + *
259 * @param jsonStr 班次json字符串] 445 * @param jsonStr 班次json字符串]
260 - * 446 + *
261 * @return 返回一个list分装的班次数据. 447 * @return 返回一个list分装的班次数据.
262 - * 448 + *
263 * @status OK. 449 * @status OK.
264 * */ 450 * */
265 public List<TTInfoDetail> jsonArrayToListEntity(String jsonStr) throws Exception { 451 public List<TTInfoDetail> jsonArrayToListEntity(String jsonStr) throws Exception {
@@ -274,14 +460,14 @@ public class TTInfoDetailServiceImpl extends BServiceImpl&lt;TTInfoDetail, Long&gt; im @@ -274,14 +460,14 @@ public class TTInfoDetailServiceImpl extends BServiceImpl&lt;TTInfoDetail, Long&gt; im
274 } 460 }
275 return listTd; 461 return listTd;
276 } 462 }
277 - 463 +
278 /** 464 /**
279 * @description : (TODO) 班次map对象转实体对象. 465 * @description : (TODO) 班次map对象转实体对象.
280 - * 466 + *
281 * @param obj 班次map对象. 467 * @param obj 班次map对象.
282 - * 468 + *
283 * @return 返回一个班次实体对象. 469 * @return 返回一个班次实体对象.
284 - * 470 + *
285 * @exception 异常暂先抛出去. 471 * @exception 异常暂先抛出去.
286 * */ 472 * */
287 public TTInfoDetail objToEntity(JSONObject obj) throws Exception { 473 public TTInfoDetail objToEntity(JSONObject obj) throws Exception {
@@ -332,12 +518,12 @@ public class TTInfoDetailServiceImpl extends BServiceImpl&lt;TTInfoDetail, Long&gt; im @@ -332,12 +518,12 @@ public class TTInfoDetailServiceImpl extends BServiceImpl&lt;TTInfoDetail, Long&gt; im
332 // 22、返回实体对象. 518 // 22、返回实体对象.
333 return td; 519 return td;
334 } 520 }
335 - 521 +
336 /** 522 /**
337 * @description : (TODO) int转boolean类型. 523 * @description : (TODO) int转boolean类型.
338 - * 524 + *
339 * @param value--int类型的数值] 525 * @param value--int类型的数值]
340 - * 526 + *
341 * @return : 返回一个布尔类型值. 527 * @return : 返回一个布尔类型值.
342 * */ 528 * */
343 public Boolean intToBit(int value) { 529 public Boolean intToBit(int value) {
@@ -347,13 +533,13 @@ public class TTInfoDetailServiceImpl extends BServiceImpl&lt;TTInfoDetail, Long&gt; im @@ -347,13 +533,13 @@ public class TTInfoDetailServiceImpl extends BServiceImpl&lt;TTInfoDetail, Long&gt; im
347 else if(value ==1) 533 else if(value ==1)
348 tag = true; 534 tag = true;
349 return tag; 535 return tag;
350 - }  
351 - 536 + }
  537 +
352 /** 538 /**
353 * @description (TODO) 获取路牌. 539 * @description (TODO) 获取路牌.
354 - * 540 + *
355 * @param xl --线路,name--路牌名称,code--路牌编码,lpType--路牌类型] 541 * @param xl --线路,name--路牌名称,code--路牌编码,lpType--路牌类型]
356 - * 542 + *
357 * @return 返回路牌. 543 * @return 返回路牌.
358 * */ 544 * */
359 public GuideboardInfo getLp(Line xl,String name, int code, String lpType) throws Exception { 545 public GuideboardInfo getLp(Line xl,String name, int code, String lpType) throws Exception {
@@ -380,18 +566,18 @@ public class TTInfoDetailServiceImpl extends BServiceImpl&lt;TTInfoDetail, Long&gt; im @@ -380,18 +566,18 @@ public class TTInfoDetailServiceImpl extends BServiceImpl&lt;TTInfoDetail, Long&gt; im
380 entity.setUpdateBy(null); 566 entity.setUpdateBy(null);
381 // 8、保存路牌. 567 // 8、保存路牌.
382 guideboardInfoRepository.save(entity); 568 guideboardInfoRepository.save(entity);
383 - } 569 + }
384 // 9、返回路牌. 570 // 9、返回路牌.
385 return entity; 571 return entity;
386 } 572 }
387 - 573 +
388 /** 574 /**
389 * @description : (TODO) 线路方向转代码. 575 * @description : (TODO) 线路方向转代码.
390 - * 576 + *
391 * @param str--方向字符串] 577 * @param str--方向字符串]
392 - * 578 + *
393 * @return 返回方向代码. 579 * @return 返回方向代码.
394 - * 580 + *
395 * @exception 异常暂先抛出. 581 * @exception 异常暂先抛出.
396 * */ 582 * */
397 public String dirToCod(String str) throws Exception { 583 public String dirToCod(String str) throws Exception {
src/main/java/com/bsth/service/schedule/utils/MyDateUtils.java 0 → 100644
  1 +package com.bsth.service.schedule.utils;
  2 +
  3 +import org.apache.commons.lang3.time.DateUtils;
  4 +import org.joda.time.DateTime;
  5 +
  6 +import java.util.Date;
  7 +
  8 +/**
  9 + * 日期处理工具类。
  10 + */
  11 +public class MyDateUtils {
  12 +
  13 + /**
  14 + * 将HH:mm格式的时间格式加上指定分钟后,生成新的日期返回。
  15 + * @param hhssDate
  16 + * @param minutes
  17 + * @param day 是否跨天
  18 + */
  19 + public static Date hhssTimePlusMinunits(String hhssDate, Integer minutes, Integer day) {
  20 + try {
  21 + DateTime newDate = new DateTime(DateUtils.parseDate("1980-01-01 " + hhssDate, "yyyy-MM-dd HH:mm"));
  22 + return newDate.plusDays(day).plusMinutes(minutes).toDate();
  23 + } catch (Exception exp) {
  24 + throw new RuntimeException(exp);
  25 + }
  26 + }
  27 +}
src/main/java/com/bsth/service/schedule/utils/MyHttpUtils.java 0 → 100644
  1 +package com.bsth.service.schedule.utils;
  2 +
  3 +import javax.servlet.http.HttpServletResponse;
  4 +import java.io.*;
  5 +import java.net.URLEncoder;
  6 +
  7 +/**
  8 + * 相关Http层的util工具类。
  9 + */
  10 +public class MyHttpUtils {
  11 + // 流输出文件
  12 + public static void responseStreamFile(HttpServletResponse response, File file) throws IOException {
  13 + // 流输出导出文件
  14 + response.setHeader("content-type", "application/octet-stream");
  15 + String fileName = file.getName();
  16 + if (MyStringUtils.isContainChinese(fileName)) {
  17 + response.setHeader("Content-Disposition", "attachment; filename*=" + URLEncoder.encode(fileName, "UTF-8"));
  18 + } else {
  19 + response.setHeader("Content-Disposition", "attachment; filename=" + fileName);
  20 + }
  21 + response.setContentType("application/octet-stream");
  22 +
  23 + try (
  24 + OutputStream os = response.getOutputStream();
  25 + BufferedOutputStream bos = new BufferedOutputStream(os);
  26 + InputStream is = new FileInputStream(file);
  27 + BufferedInputStream bis = new BufferedInputStream(is)
  28 + ) {
  29 + int length;
  30 + byte[] temp = new byte[1024 * 10];
  31 + while ((length = bis.read(temp)) != -1) {
  32 + bos.write(temp, 0, length);
  33 + }
  34 + bos.flush();
  35 + }
  36 + }
  37 +}
src/main/resources/static/pages/scheduleApp/module/common/prj-common-globalservice.js
@@ -967,6 +967,33 @@ angular.module(&#39;ScheduleApp&#39;).factory( @@ -967,6 +967,33 @@ angular.module(&#39;ScheduleApp&#39;).factory(
967 } 967 }
968 } 968 }
969 ), 969 ),
  970 +
  971 + pvInfoExport: $resource(
  972 + '/tidc/exportPvInfo/:id',
  973 + {id: '@id'},
  974 + {
  975 + do: {
  976 + method: 'GET',
  977 + responseType: "arraybuffer",
  978 + transformResponse: function(data, headers, status){
  979 + if (status != 200) {
  980 + return data;
  981 + }
  982 +
  983 + // console.log(headers("Content-Disposition"));
  984 + // 获取文件名,后台根据是否还有中文名字,返回filename=ascii编码的文件名 或 filename*=unicode编码的文件名
  985 + var fileName = headers("Content-Disposition").split(";")[1].split("filename=")[1];
  986 + var fileNameUnicode = headers("Content-Disposition").split("filename*=")[1];
  987 + if (fileNameUnicode) {//当存在 filename* 时,取filename* 并进行解码(为了解决中文乱码问题)
  988 + fileName = decodeURIComponent(fileNameUnicode);
  989 + }
  990 +
  991 + return {fileData : data, fileName: fileName};
  992 + }
  993 + }
  994 + }
  995 + ),
  996 +
970 edit: $resource( 997 edit: $resource(
971 '/tidc/edit/:xlid/:ttid', 998 '/tidc/edit/:xlid/:ttid',
972 {}, 999 {},
@@ -1017,7 +1044,8 @@ angular.module(&#39;ScheduleApp&#39;).factory( @@ -1017,7 +1044,8 @@ angular.module(&#39;ScheduleApp&#39;).factory(
1017 } 1044 }
1018 1045
1019 ] 1046 ]
1020 -); 1047 +);
  1048 +
1021 // 时刻表日志管理service 1049 // 时刻表日志管理service
1022 angular.module('ScheduleApp').factory( 1050 angular.module('ScheduleApp').factory(
1023 'TimetableLogManageService_g', 1051 'TimetableLogManageService_g',
src/main/resources/static/pages/scheduleApp/module/core/ttInfoManage/detailedit/edit3.html
@@ -126,6 +126,12 @@ @@ -126,6 +126,12 @@
126 <i class="fa fa-refresh"></i> 126 <i class="fa fa-refresh"></i>
127 刷新数据 127 刷新数据
128 </a> 128 </a>
  129 + <a href="javascript:" style="padding-right: 5px;"
  130 + ng-click="ctrl.exportPvInfo()"
  131 + ng-show="ctrl.currentView.btn6">
  132 + <i class="fa fa-file-excel-o" aria-hidden="true"></i>
  133 + 导出
  134 + </a>
129 </div> 135 </div>
130 136
131 137
src/main/resources/static/pages/scheduleApp/module/core/ttInfoManage/detailedit/timeTableDetailManage_old.js
@@ -60,6 +60,10 @@ angular.module(&#39;ScheduleApp&#39;).factory( @@ -60,6 +60,10 @@ angular.module(&#39;ScheduleApp&#39;).factory(
60 ); 60 );
61 }, 61 },
62 62
  63 + pvInfoExportPromise: function(ttInfoId) {
  64 + return service.pvInfoExport.do({id: ttInfoId}).$promise;
  65 + },
  66 +
63 /** 67 /**
64 * 获取编辑用的时刻表明细数据。 68 * 获取编辑用的时刻表明细数据。
65 * @param xlid 线路id 69 * @param xlid 线路id
@@ -357,7 +361,8 @@ angular.module(&#39;ScheduleApp&#39;).controller( @@ -357,7 +361,8 @@ angular.module(&#39;ScheduleApp&#39;).controller(
357 '$state', 361 '$state',
358 '$scope', 362 '$scope',
359 '$window', 363 '$window',
360 - function(service, $stateParams, $uibModal, $state, $scope, $window) { 364 + 'FileDownload_g',
  365 + function(service, $stateParams, $uibModal, $state, $scope, $window, fileDownload) {
361 var self = this; 366 var self = this;
362 self.xlid = $stateParams.xlid; // 获取传过来的线路id 367 self.xlid = $stateParams.xlid; // 获取传过来的线路id
363 self.ttid = $stateParams.ttid; // 获取传过来的时刻表id 368 self.ttid = $stateParams.ttid; // 获取传过来的时刻表id
@@ -444,7 +449,8 @@ angular.module(&#39;ScheduleApp&#39;).controller( @@ -444,7 +449,8 @@ angular.module(&#39;ScheduleApp&#39;).controller(
444 "preView" : { 449 "preView" : {
445 viewId : 2, 450 viewId : 2,
446 switchBtnMsg : "切换编辑视图", 451 switchBtnMsg : "切换编辑视图",
447 - btn5 : true 452 + btn5 : true,
  453 + btn6 : true
448 } 454 }
449 }; 455 };
450 self.currentView = self.viewInfos["editView"]; // 默认编辑视图 456 self.currentView = self.viewInfos["editView"]; // 默认编辑视图
@@ -639,6 +645,19 @@ angular.module(&#39;ScheduleApp&#39;).controller( @@ -639,6 +645,19 @@ angular.module(&#39;ScheduleApp&#39;).controller(
639 } 645 }
640 }; 646 };
641 647
  648 + // 导出pv预览视图数据
  649 + self.exportPvInfo = function() {
  650 + var promise = service.pvInfoExportPromise(self.ttid);
  651 + promise.then(
  652 + function(result) {
  653 + fileDownload.downloadFile(result.fileData, "application/octet-stream", result.fileName);
  654 + },
  655 + function(result) {
  656 + console.log("导出预览视图信息失败:" + result);
  657 + }
  658 + );
  659 + };
  660 +
642 } 661 }
643 662
644 ] 663 ]
src/main/resources/static/pages/scheduleApp/module/core/ttInfoManage/service.js
@@ -207,6 +207,33 @@ angular.module(&#39;ScheduleApp&#39;).factory( @@ -207,6 +207,33 @@ angular.module(&#39;ScheduleApp&#39;).factory(
207 } 207 }
208 } 208 }
209 ), 209 ),
  210 +
  211 + pvInfoExport: $resource(
  212 + '/tidc/exportPvInfo/:id',
  213 + {id: '@id'},
  214 + {
  215 + do: {
  216 + method: 'GET',
  217 + responseType: "arraybuffer",
  218 + transformResponse: function(data, headers, status){
  219 + if (status != 200) {
  220 + return data;
  221 + }
  222 +
  223 + // console.log(headers("Content-Disposition"));
  224 + // 获取文件名,后台根据是否还有中文名字,返回filename=ascii编码的文件名 或 filename*=unicode编码的文件名
  225 + var fileName = headers("Content-Disposition").split(";")[1].split("filename=")[1];
  226 + var fileNameUnicode = headers("Content-Disposition").split("filename*=")[1];
  227 + if (fileNameUnicode) {//当存在 filename* 时,取filename* 并进行解码(为了解决中文乱码问题)
  228 + fileName = decodeURIComponent(fileNameUnicode);
  229 + }
  230 +
  231 + return {fileData : data, fileName: fileName};
  232 + }
  233 + }
  234 + }
  235 + ),
  236 +
210 edit: $resource( 237 edit: $resource(
211 '/tidc/edit/:xlid/:ttid', 238 '/tidc/edit/:xlid/:ttid',
212 {}, 239 {},
@@ -257,4 +284,4 @@ angular.module(&#39;ScheduleApp&#39;).factory( @@ -257,4 +284,4 @@ angular.module(&#39;ScheduleApp&#39;).factory(
257 } 284 }
258 285
259 ] 286 ]
260 -);  
261 \ No newline at end of file 287 \ No newline at end of file
  288 +);