Commit 01898ae5c3898caf49889abcd0b83d2161b3ed30

Authored by 潘钊
2 parents e1dd2ea5 fef9b8c5

Merge branch 'minhang' into pudong

# Conflicts:
#	src/main/resources/static/real_control_v2/js/forms/wrap.html
Showing 57 changed files with 3109 additions and 1315 deletions
src/main/java/com/bsth/controller/BaseController.java
1 1 package com.bsth.controller;
2 2  
3   -import com.bsth.common.ResponseCode;
4 3 import com.bsth.service.BaseService;
5   -import com.bsth.service.schedule.utils.DataImportExportService;
6 4 import com.google.common.base.Splitter;
7 5 import org.springframework.beans.factory.annotation.Autowired;
8 6 import org.springframework.data.domain.Page;
9 7 import org.springframework.data.domain.PageRequest;
10 8 import org.springframework.data.domain.Sort;
11 9 import org.springframework.data.domain.Sort.Direction;
12   -import org.springframework.util.CollectionUtils;
13 10 import org.springframework.web.bind.annotation.PathVariable;
14 11 import org.springframework.web.bind.annotation.RequestMapping;
15 12 import org.springframework.web.bind.annotation.RequestMethod;
16 13 import org.springframework.web.bind.annotation.RequestParam;
17   -import org.springframework.web.multipart.MultipartFile;
18 14  
19   -import javax.servlet.http.HttpServletResponse;
20   -import java.io.*;
  15 +import java.io.Serializable;
21 16 import java.util.ArrayList;
22   -import java.util.HashMap;
23 17 import java.util.List;
24 18 import java.util.Map;
25 19  
... ... @@ -35,8 +29,6 @@ public class BaseController<T, ID extends Serializable> {
35 29  
36 30 @Autowired
37 31 protected BaseService<T, ID> baseService;
38   - @Autowired
39   - DataImportExportService dataImportExportService;
40 32  
41 33 /**
42 34 * @param @param map 查询条件
... ... @@ -126,115 +118,4 @@ public class BaseController&lt;T, ID extends Serializable&gt; {
126 118 return baseService.delete(id);
127 119 }
128 120  
129   - /**
130   - * 上传数据文件,并使用ktr转换文件导入数据。
131   - *
132   - * @param file
133   - * @return
134   - * @throws Exception
135   - */
136   - @RequestMapping(value = "/dataImport", method = RequestMethod.POST)
137   - public Map<String, Object> uploadDataAndImport(MultipartFile file) throws Exception {
138   - Map<String, Object> resultMap = new HashMap<>();
139   -
140   - try {
141   - // 获取ktr转换文件绝对路径
142   - File ktrfile = new File(this.getClass().getResource(getDataImportKtrClasspath()).toURI());
143   - System.out.println(ktrfile.getAbsolutePath());
144   - // 导入数据
145   - dataImportExportService.fileDataImport(file, ktrfile);
146   -
147   - resultMap.put("status", ResponseCode.SUCCESS);
148   - resultMap.put("msg", "导入成功");
149   - } catch (Exception exp) {
150   - exp.printStackTrace();
151   - resultMap.put("status", ResponseCode.ERROR);
152   - resultMap.put("msg", exp.getLocalizedMessage());
153   - }
154   -
155   - return resultMap;
156   - }
157   -
158   - /**
159   - * 使用ktr导出数据。
160   - *
161   - * @param response
162   - * @throws Exception
163   - */
164   - @RequestMapping(value = "/dataExport", method = RequestMethod.GET)
165   - public void dataExport(HttpServletResponse response) throws Exception {
166   - dataExport(response, null);
167   - }
168   -
169   - @RequestMapping(value = "/dataExportExt", method = RequestMethod.GET)
170   - public void dataExport(HttpServletResponse response, @RequestParam Map<String, Object> param) throws Exception {
171   - // 1、使用ktr转换获取输出文件
172   - File ktrfile = new File(this.getClass().getResource(getDataExportKtrClasspath()).toURI());
173   - File outputfile = null;
174   - if (!CollectionUtils.isEmpty(param)) {
175   - outputfile = dataImportExportService.fileDataOutput(
176   - getDataExportFilename(),
177   - ktrfile,
178   - param);
179   - } else {
180   - outputfile = dataImportExportService.fileDataOutput(
181   - getDataExportFilename(),
182   - ktrfile);
183   - }
184   -
185   - System.out.println(outputfile.getName());
186   - String filePath = outputfile.getAbsolutePath();
187   - String fp[] = filePath.split(File.separator);
188   - String fileName = fp[fp.length - 1];
189   -
190   - // TODO:使用ktr获取导出数据
191   -
192   - response.setHeader("conent-type", "application/octet-stream");
193   - response.setContentType("application/octet-stream");
194   - response.setHeader("Content-Disposition", "attachment; filename=" + "东东");
195   -
196   - OutputStream os = response.getOutputStream();
197   - BufferedOutputStream bos = new BufferedOutputStream(os);
198   -
199   - InputStream is = null;
200   -
201   - is = new FileInputStream(filePath);
202   - BufferedInputStream bis = new BufferedInputStream(is);
203   -
204   - int length = 0;
205   - byte[] temp = new byte[1 * 1024 * 10];
206   -
207   - while ((length = bis.read(temp)) != -1) {
208   - bos.write(temp, 0, length);
209   - }
210   - bos.flush();
211   - bis.close();
212   - bos.close();
213   - is.close();
214   - }
215   -
216   - /**
217   - * @return 数据导出的ktr转换文件类路径。
218   - */
219   - protected String getDataExportKtrClasspath() {
220   - // 默认返回异常,子类如果要使用导出功能,必须覆写此方法,指定ktr文件类路径
221   - throw new RuntimeException("必须override,并指定ktr classpath");
222   - }
223   -
224   - /**
225   - * @return 导出文件名。
226   - */
227   - protected String getDataExportFilename() {
228   - // 默认返回异常,子类如果要使用导出功能,必须覆写此方法,指定导出的文件路径名
229   - throw new RuntimeException("必须override,并指定导出文件名");
230   - }
231   -
232   - /**
233   - * @return 数据导入的ktr转换文件类路径。
234   - */
235   - protected String getDataImportKtrClasspath() {
236   - // 默认返回异常,子类如果要使用导入功能,必须覆写此方法,指定ktr文件类路径
237   - throw new RuntimeException("必须override,并指定ktr classpath");
238   - }
239   -
240 121 }
... ...
src/main/java/com/bsth/controller/BaseController2.java deleted 100644 → 0
1   -package com.bsth.controller;
2   -
3   -
4   -import com.bsth.common.ResponseCode;
5   -import com.bsth.service.BaseService;
6   -import com.bsth.service.schedule.utils.DataImportExportService;
7   -import com.google.common.base.Splitter;
8   -import jxl.Sheet;
9   -import jxl.Workbook;
10   -import org.springframework.beans.factory.annotation.Autowired;
11   -import org.springframework.data.domain.Page;
12   -import org.springframework.data.domain.PageRequest;
13   -import org.springframework.data.domain.Sort;
14   -import org.springframework.util.CollectionUtils;
15   -import org.springframework.web.bind.annotation.*;
16   -import org.springframework.web.multipart.MultipartFile;
17   -
18   -import javax.servlet.http.HttpServletResponse;
19   -import java.io.*;
20   -import java.util.ArrayList;
21   -import java.util.HashMap;
22   -import java.util.List;
23   -import java.util.Map;
24   -
25   -/**
26   - * Created by xu on 16/11/3.
27   - */
28   -public class BaseController2<T, ID extends Serializable> {
29   -
30   - @Autowired
31   - protected BaseService<T, ID> baseService;
32   - @Autowired
33   - DataImportExportService dataImportExportService;
34   -
35   - /**
36   - *
37   - * @Title: list
38   - * @Description: TODO(多条件分页查询)
39   - * @param @param map 查询条件
40   - * @param @param page 页码
41   - * @param @param size 每页显示数量
42   - * @throws
43   - */
44   - @RequestMapping(method = RequestMethod.GET)
45   - public Page<T> list(@RequestParam Map<String, Object> map,
46   - @RequestParam(defaultValue = "0") int page,
47   - @RequestParam(defaultValue = "10") int size,
48   - @RequestParam(defaultValue = "id") String order,
49   - @RequestParam(defaultValue = "DESC") String direction){
50   -
51   - // 允许多个字段排序,order可以写单个字段,也可以写多个字段
52   - // 多个字段格式:{col1},{col2},{col3},....,{coln}
53   - List<String> order_columns = Splitter.on(",").trimResults().splitToList(order);
54   - // 多字段排序:DESC,ASC...
55   - List<String> order_dirs = Splitter.on(",").trimResults().splitToList(direction);
56   -
57   - if (order_dirs.size() == 1) { // 所有字段采用一种排序
58   - if (null != order_dirs.get(0) && order_dirs.get(0).equals("ASC")) {
59   - return baseService.list(map, new PageRequest(page, size, new Sort(Sort.Direction.ASC, order_columns)));
60   - } else {
61   - return baseService.list(map, new PageRequest(page, size, new Sort(Sort.Direction.DESC, order_columns)));
62   - }
63   - } else if (order_columns.size() == order_dirs.size()) {
64   - List<Sort.Order> orderList = new ArrayList<>();
65   - for (int i = 0; i < order_columns.size(); i++) {
66   - if (null != order_dirs.get(i) && order_dirs.get(i).equals("ASC")) {
67   - orderList.add(new Sort.Order(Sort.Direction.ASC, order_columns.get(i)));
68   - } else {
69   - orderList.add(new Sort.Order(Sort.Direction.DESC, order_columns.get(i)));
70   - }
71   - }
72   - return baseService.list(map, new PageRequest(page, size, new Sort(orderList)));
73   - } else {
74   - throw new RuntimeException("多字段排序参数格式问题,排序顺序和字段数不一致");
75   - }
76   - }
77   -
78   - /**
79   - *
80   - * @Title: list
81   - * @Description: TODO(多条件查询)
82   - * @param @param map
83   - * @throws
84   - */
85   - @RequestMapping(value = "/all", method = RequestMethod.GET)
86   - public Iterable<T> list(@RequestParam Map<String, Object> map){
87   - return baseService.list(map);
88   - }
89   -
90   - /**
91   - * 这里保存直接返回保存后的对象,不自己定义Map返回了,和前端angularjs配合。
92   - * form也可以提交,但是页面参数可能不全,
93   - * json的化比较灵活,但是貌似有多余属性也会报错,或者碰到lazy属性值,也有问题
94   - * 不论form,还是json提交都能解决问题,就看哪个方便哪个来
95   - *
96   - * @param t 参数需要使用@RequestBody转换json成对象
97   - * @return
98   - */
99   - @RequestMapping(method = RequestMethod.POST)
100   - public T save(@RequestBody T t) {
101   - baseService.save(t);
102   - return t;
103   - }
104   -
105   - @RequestMapping(value="/{id}", method = RequestMethod.POST)
106   - public T update(@RequestBody T t) {
107   - baseService.save(t);
108   - return t;
109   - }
110   -
111   - /**
112   - *
113   - * @Title: findById
114   - * @Description: TODO(根据主键获取单个对象)
115   - * @param @param id
116   - * @throws
117   - */
118   - @RequestMapping(value="/{id}",method = RequestMethod.GET)
119   - public T findById(@PathVariable("id") ID id){
120   - return baseService.findById(id);
121   - }
122   -
123   - /**
124   - *
125   - * @Title: delete
126   - * @Description: TODO(根据主键删除对象)
127   - * @param @param id
128   - * @throws
129   - */
130   - @RequestMapping(value="/{id}",method = RequestMethod.DELETE)
131   - public Map<String, Object> delete(@PathVariable("id") ID id){
132   - return baseService.delete(id);
133   - }
134   -
135   - /**
136   - * 上传数据文件,并使用ktr转换文件导入数据。
137   - * @param file
138   - * @return
139   - * @throws Exception
140   - */
141   - @RequestMapping(value = "/dataImport", method = RequestMethod.POST)
142   - public Map<String, Object> uploadDataAndImport(MultipartFile file) throws Exception {
143   - Map<String, Object> resultMap = new HashMap<>();
144   -
145   - try {
146   - // 获取ktr转换文件绝对路径
147   - File ktrfile = new File(this.getClass().getResource(getDataImportKtrClasspath()).toURI());
148   - System.out.println(ktrfile.getAbsolutePath());
149   - // 导入数据
150   - dataImportExportService.fileDataImport(file, ktrfile);
151   -
152   - resultMap.put("status", ResponseCode.SUCCESS);
153   - resultMap.put("msg", "导入成功");
154   - } catch (Exception exp) {
155   - exp.printStackTrace();
156   - resultMap.put("status", ResponseCode.ERROR);
157   - resultMap.put("msg", exp.getLocalizedMessage());
158   - }
159   -
160   - return resultMap;
161   - }
162   -
163   - /**
164   - * 使用ktr导出数据。
165   - * @param response
166   - * @throws Exception
167   - */
168   - @RequestMapping(value = "/dataExport", method = RequestMethod.GET)
169   - public void dataExport(HttpServletResponse response) throws Exception {
170   - dataExport(response, null);
171   - }
172   -
173   - @RequestMapping(value = "/dataExportExt", method = RequestMethod.GET)
174   - public void dataExport(HttpServletResponse response, @RequestParam Map<String, Object> param) throws Exception {
175   - // 1、使用ktr转换获取输出文件
176   - File ktrfile = new File(this.getClass().getResource(getDataExportKtrClasspath()).toURI());
177   - File outputfile = null;
178   - if (!CollectionUtils.isEmpty(param)) {
179   - outputfile = dataImportExportService.fileDataOutput(
180   - getDataExportFilename(),
181   - ktrfile,
182   - param);
183   - } else {
184   - outputfile = dataImportExportService.fileDataOutput(
185   - getDataExportFilename(),
186   - ktrfile);
187   - }
188   -
189   - System.out.println(outputfile.getName());
190   - System.out.println(outputfile.getAbsolutePath());
191   -
192   - String filePath = outputfile.getAbsolutePath();
193   -// String fp[] = filePath.split(File.separator);
194   -// String fileName = fp[fp.length - 1];
195   -
196   - // TODO:使用ktr获取导出数据
197   -
198   - response.setHeader("conent-type", "application/octet-stream");
199   - response.setContentType("application/octet-stream");
200   - response.setHeader("Content-Disposition", "attachment; filename=" + "东东");
201   -
202   - OutputStream os = response.getOutputStream();
203   - BufferedOutputStream bos = new BufferedOutputStream(os);
204   -
205   - InputStream is = null;
206   -
207   - is = new FileInputStream(filePath);
208   - BufferedInputStream bis = new BufferedInputStream(is);
209   -
210   - int length = 0;
211   - byte[] temp = new byte[1 * 1024 * 10];
212   -
213   - while ((length = bis.read(temp)) != -1) {
214   - bos.write(temp, 0, length);
215   - }
216   - bos.flush();
217   - bis.close();
218   - bos.close();
219   - is.close();
220   - }
221   -
222   - /**
223   - * @return 数据导出的ktr转换文件类路径。
224   - */
225   - protected String getDataExportKtrClasspath() {
226   - // 默认返回异常,子类如果要使用导出功能,必须覆写此方法,指定ktr文件类路径
227   - throw new RuntimeException("必须override,并指定ktr classpath");
228   - }
229   -
230   - /**
231   - * @return 导出文件名。
232   - */
233   - protected String getDataExportFilename() {
234   - // 默认返回异常,子类如果要使用导出功能,必须覆写此方法,指定导出的文件路径名
235   - throw new RuntimeException("必须override,并指定导出文件名");
236   - }
237   -
238   - /**
239   - * @return 数据导入的ktr转换文件类路径。
240   - */
241   - protected String getDataImportKtrClasspath() {
242   - // 默认返回异常,子类如果要使用导入功能,必须覆写此方法,指定ktr文件类路径
243   - throw new RuntimeException("必须override,并指定ktr classpath");
244   - }
245   -
246   -
247   - public static class ExcelFileOutput {
248   - private String fileName;
249   - private List<Map<String, Object>> sheetnames = new ArrayList<>();
250   -
251   - public String getFileName() {
252   - return fileName;
253   - }
254   -
255   - public void setFileName(String fileName) {
256   - this.fileName = fileName;
257   - }
258   -
259   - public List<Map<String, Object>> getSheetnames() {
260   - return sheetnames;
261   - }
262   -
263   - public void setSheetnames(List<Map<String, Object>> sheetnames) {
264   - this.sheetnames = sheetnames;
265   - }
266   - }
267   -
268   - /**
269   - * 上传Excel文件,返回文件全路径名,工作区名称列表。
270   - * @param file
271   - * @return
272   - * @throws Exception
273   - */
274   - @RequestMapping(value = "/uploadFile", method = RequestMethod.POST)
275   - public ExcelFileOutput fileUpload(MultipartFile file) throws Exception {
276   - // 返回对象
277   - ExcelFileOutput rs = new ExcelFileOutput();
278   -
279   - // 上传文件
280   - File file1 = dataImportExportService.uploadFile(file);
281   - // 获取文件的sheet
282   - Workbook book = Workbook.getWorkbook(file1);
283   - for (Sheet sheet : book.getSheets()) {
284   - String sheetname = sheet.getName();
285   - Map<String, Object> s = new HashMap<>();
286   - s.put("name", sheetname);
287   - rs.getSheetnames().add(s);
288   - }
289   -
290   - rs.setFileName(file1.getAbsolutePath());
291   - return rs;
292   - }
293   -
294   -}
src/main/java/com/bsth/controller/CarsController.java
1 1 package com.bsth.controller;
2 2  
3   -import com.bsth.common.ResponseCode;
4 3 import com.bsth.entity.Cars;
5   -import com.bsth.service.schedule.utils.DataImportExportService;
6   -import com.bsth.service.schedule.utils.DataToolsProperties;
7   -import org.springframework.beans.factory.annotation.Autowired;
8   -import org.springframework.boot.context.properties.EnableConfigurationProperties;
9 4 import org.springframework.web.bind.annotation.RequestMapping;
10   -import org.springframework.web.bind.annotation.RequestMethod;
11   -import org.springframework.web.bind.annotation.RequestParam;
12 5 import org.springframework.web.bind.annotation.RestController;
13 6  
14   -import java.io.File;
15   -import java.util.HashMap;
16   -import java.util.Map;
17   -
18 7 /**
19 8 * Created by xu on 16/5/31.
20 9 */
21 10 @RestController
22 11 @RequestMapping("cars")
23   -@EnableConfigurationProperties(DataToolsProperties.class)
24   -public class CarsController extends BaseController2<Cars, Integer> {
25   -
26   - @Autowired
27   - private DataToolsProperties dataToolsProperties;
28   - @Autowired
29   - private DataImportExportService dataImportExportService;
30   -
31   - /**
32   - * 验证。
33   - * @param map
34   - * @return
35   - */
36   - @RequestMapping(value = "/validate/equale", method = RequestMethod.GET)
37   - public Map<String, Object> validateData(@RequestParam Map<String, Object> map) {
38   - // 一般比较自编号是否重复
39   - return baseService.validateEquale(map);
40   - }
41   -
42   - // uploadFile post
43   -
44   - // 验证excel sheet
45   - @RequestMapping(value = "/validate/sheet", method = RequestMethod.GET)
46   - public Map<String, Object> validateSheet() throws Exception {
47   - Map<String, Object> rtn = new HashMap<>();
48   -
49   - // TODO:
50   -
51   - rtn.put("status", ResponseCode.SUCCESS);
52   - return rtn;
53   - }
54   -
55   - @RequestMapping(value = "/importfile", method = RequestMethod.POST)
56   - public Map<String, Object> importData(
57   - @RequestParam Map<String, Object> form)
58   - throws Exception {
59   - Map<String, Object> rtn = new HashMap<>();
60   -
61   - // TODO:
62   - String filename = (String) form.get("filename");
63   -
64   -
65   - try {
66   - // 获取ktr转换文件绝对路径
67   - File ktrfile = new File(this.getClass().getResource(getDataImportKtrClasspath()).toURI());
68   - System.out.println(ktrfile.getAbsolutePath());
69   - // 导入数据
70   - dataImportExportService.fileDataImport(new File(filename), ktrfile);
71   -
72   - rtn.put("status", ResponseCode.SUCCESS);
73   - rtn.put("msg", "导入成功");
74   - } catch (Exception exp) {
75   - exp.printStackTrace();
76   - rtn.put("status", ResponseCode.ERROR);
77   - rtn.put("msg", exp.getLocalizedMessage());
78   - }
79   -
80   - return rtn;
81   - }
82   -
83   -
84   - @Override
85   - protected String getDataImportKtrClasspath() {
86   - return dataToolsProperties.getCarsDatainputktr();
87   - }
88   -
89   - @Override
90   - protected String getDataExportKtrClasspath() {
91   - return dataToolsProperties.getCarsDataoutputktr();
92   - }
  12 +public class CarsController extends BaseController<Cars, Integer> {
93 13  
94   - @Override
95   - protected String getDataExportFilename() {
96   - return "车辆基础数据";
97   - }
98 14 }
... ...
src/main/java/com/bsth/controller/PersonnelController.java
... ... @@ -2,10 +2,11 @@ package com.bsth.controller;
2 2  
3 3 import com.bsth.entity.Personnel;
4 4 import com.bsth.service.PersonnelService;
5   -import com.bsth.service.schedule.utils.DataToolsProperties;
6 5 import org.springframework.beans.factory.annotation.Autowired;
7   -import org.springframework.boot.context.properties.EnableConfigurationProperties;
8   -import org.springframework.web.bind.annotation.*;
  6 +import org.springframework.web.bind.annotation.RequestMapping;
  7 +import org.springframework.web.bind.annotation.RequestMethod;
  8 +import org.springframework.web.bind.annotation.RequestParam;
  9 +import org.springframework.web.bind.annotation.RestController;
9 10  
10 11 import java.util.List;
11 12 import java.util.Map;
... ... @@ -15,54 +16,11 @@ import java.util.Map;
15 16 */
16 17 @RestController
17 18 @RequestMapping("personnel")
18   -@EnableConfigurationProperties(DataToolsProperties.class)
19 19 public class PersonnelController extends BaseController<Personnel, Integer> {
20 20  
21 21 @Autowired
22   - private DataToolsProperties dataToolsProperties;
23   -
24   - @Autowired
25 22 private PersonnelService service;
26   - /**
27   - * 覆写方法,因为form提交的方式参数不全,改用 json形式提交 @RequestBody
28   - * @Title: save
29   - * @Description: TODO(持久化对象)
30   - * @param @param t
31   - * @param @return 设定文件
32   - * @return Map<String,Object> {status: 1(成功),-1(失败)}
33   - * @throws
34   - */
35   - @RequestMapping(method = RequestMethod.POST)
36   - public Map<String, Object> save(@RequestBody Personnel t){
37   - return baseService.save(t);
38   - }
39   -
40   - /**
41   - * 验证。
42   - * @param map
43   - * @return
44   - */
45   - @RequestMapping(value = "/validate/equale", method = RequestMethod.GET)
46   - public Map<String, Object> validateData(@RequestParam Map<String, Object> map) {
47   - // 一般比较相同公司下工号是否相同
48   - return baseService.validateEquale(map);
49   - }
50   -
51   - @Override
52   - protected String getDataImportKtrClasspath() {
53   - return dataToolsProperties.getEmployeesDatainputktr();
54   - }
55   -
56   - @Override
57   - protected String getDataExportKtrClasspath() {
58   - return dataToolsProperties.getEmployeesDataoutputktr();
59   - }
60 23  
61   - @Override
62   - protected String getDataExportFilename() {
63   - return "人员基础信息";
64   - }
65   -
66 24 @RequestMapping(value = "/sreachPersonnel", method = RequestMethod.GET)
67 25 public List<Map<String, String>> sreachPersonnel(@RequestParam String jobCode) {
68 26 return service.sreachPersonnel(jobCode);
... ...
src/main/java/com/bsth/controller/realcontrol/DataManagerController.java 0 → 100644
  1 +package com.bsth.controller.realcontrol;
  2 +
  3 +import com.bsth.service.realcontrol.DataManagerService;
  4 +import org.apache.commons.lang3.StringEscapeUtils;
  5 +import org.springframework.beans.factory.annotation.Autowired;
  6 +import org.springframework.web.bind.annotation.RequestMapping;
  7 +import org.springframework.web.bind.annotation.RequestParam;
  8 +import org.springframework.web.bind.annotation.RestController;
  9 +
  10 +import java.util.Map;
  11 +
  12 +/**
  13 + * 数据管理,包括从老系统的数据迁移。新系统的数据校验等
  14 + * Created by panzhao on 2017/4/17.
  15 + */
  16 +@RestController
  17 +@RequestMapping("dataManager")
  18 +public class DataManagerController {
  19 +
  20 + @Autowired
  21 + DataManagerService dataManagerService;
  22 +
  23 + @RequestMapping("cars/old_now")
  24 + public Map<String, Object> carInfos(@RequestParam Integer lineId){
  25 + return dataManagerService.carInfos(lineId);
  26 + }
  27 +
  28 + @RequestMapping("car/updateDevices")
  29 + public Map<String, Object> updateDevices(@RequestParam String jsonStr){
  30 + jsonStr = StringEscapeUtils.unescapeHtml4(jsonStr);
  31 + return dataManagerService.updateDevices(jsonStr);
  32 + }
  33 +}
... ...
src/main/java/com/bsth/data/schedule/DayOfSchedule.java
... ... @@ -10,6 +10,7 @@ import com.bsth.data.LineConfigData;
10 10 import com.bsth.data.directive.DirectivesPstThread;
11 11 import com.bsth.data.gpsdata.GpsRealData;
12 12 import com.bsth.data.gpsdata.recovery.GpsDataRecovery;
  13 +import com.bsth.data.schedule.late_adjust.ScheduleLateThread;
13 14 import com.bsth.data.schedule.thread.*;
14 15 import com.bsth.entity.realcontrol.LineConfig;
15 16 import com.bsth.entity.realcontrol.ScheduleRealInfo;
... ... @@ -386,6 +387,11 @@ public class DayOfSchedule implements CommandLineRunner {
386 387 sch.setLate(false);
387 388 }
388 389  
  390 + //售票员为空设置为""字符串
  391 + if(StringUtils.isEmpty(sch.getsGh())){
  392 + sch.setsGh("");
  393 + sch.setsName("");
  394 + }
389 395 sch.setJhlcOrig(sch.getJhlc());
390 396 //保留备注
391 397 if(StringUtils.isNotEmpty(sch.getRemark()))
... ...
src/main/java/com/bsth/data/schedule/late_adjust/LateAdjustHandle.java
  1 +
1 2 package com.bsth.data.schedule.late_adjust;
2 3  
  4 +import com.bsth.entity.realcontrol.ScheduleRealInfo;
  5 +
  6 +import java.util.Map;
  7 +
3 8 /**
4 9 * 误点调整处理程序
5 10 * Created by panzhao on 2017/4/16.
6 11 */
7 12 public class LateAdjustHandle {
8 13  
  14 + /**
  15 + * 误点的车辆 和 班次
  16 + */
  17 + private static Map<String, ScheduleRealInfo> lateSchMap;
  18 +
  19 +
  20 + /**
  21 + * 误点的班次ID 和 停靠时间(秒)
  22 + */
  23 + private static Map<Long, Integer> stopTimeMap;
  24 +
  25 +
  26 + /**
  27 + * 班次误点(考虑停靠时间)
  28 + * @param sch
  29 + */
  30 + public static void schLate(ScheduleRealInfo sch){
  31 +
  32 + }
9 33 }
... ...
src/main/java/com/bsth/data/schedule/thread/ScheduleLateThread.java renamed to src/main/java/com/bsth/data/schedule/late_adjust/ScheduleLateThread.java
1   -package com.bsth.data.schedule.thread;
2   -
3   -
4   -import java.util.ArrayList;
5   -import java.util.Collections;
6   -import java.util.Comparator;
7   -import java.util.List;
8   -
9   -import org.springframework.beans.factory.annotation.Autowired;
10   -import org.springframework.stereotype.Component;
11   -
12   -import com.bsth.data.schedule.DayOfSchedule;
13   -import com.bsth.data.schedule.ScheduleComparator;
14   -import com.bsth.entity.realcontrol.ScheduleRealInfo;
15   -import com.bsth.websocket.handler.SendUtils;
16   -
17   -/**
18   - *
19   - * @ClassName: ScheduleLateThread
20   - * @Description: TODO(班次误点扫描线程)
21   - * @author PanZhao
22   - * @date 2016年8月31日 下午3:09:02
23   - *
24   - */
25   -@Component
26   -public class ScheduleLateThread extends Thread{
27   -
28   - @Autowired
29   - DayOfSchedule dayOfSchedule;
30   -
31   - @Autowired
32   - SendUtils sendUtils;
33   -
34   - private static Comparator<ScheduleRealInfo> cpm = new ScheduleComparator.FCSJ();
35   -
36   - @Override
37   - public void run() {
38   - List<ScheduleRealInfo> all = new ArrayList<>(dayOfSchedule.findAll());
39   - Collections.sort(all, cpm);
40   -
41   - long t = System.currentTimeMillis();
42   - int size = all.size();
43   -
44   - ScheduleRealInfo sch;
45   - for(int i = 0; i < size; i ++){
46   - sch = all.get(i);
47   - if(sch.getDfsjT() > t)
48   - break;
49   -
50   - if(sch.isLate() == false
51   - && sch.getStatus() == 0
52   - && sch.getFcsjActual() == null){
53   - //应发未发
54   - sch.setLate(true);
55   - //通知客户端
56   - sendUtils.refreshSch(sch);
57   - }
58   - }
59   - }
60   -}
  1 +package com.bsth.data.schedule.late_adjust;
  2 +
  3 +
  4 +import com.bsth.data.schedule.DayOfSchedule;
  5 +import com.bsth.data.schedule.ScheduleComparator;
  6 +import com.bsth.entity.realcontrol.ScheduleRealInfo;
  7 +import com.bsth.websocket.handler.SendUtils;
  8 +import org.springframework.beans.factory.annotation.Autowired;
  9 +import org.springframework.stereotype.Component;
  10 +
  11 +import java.util.ArrayList;
  12 +import java.util.Collections;
  13 +import java.util.Comparator;
  14 +import java.util.List;
  15 +
  16 +/**
  17 + *
  18 + * @ClassName: ScheduleLateThread
  19 + * @Description: TODO(班次误点扫描线程)
  20 + * @author PanZhao
  21 + * @date 2016年8月31日 下午3:09:02
  22 + *
  23 + */
  24 +@Component
  25 +public class ScheduleLateThread extends Thread{
  26 +
  27 + @Autowired
  28 + DayOfSchedule dayOfSchedule;
  29 +
  30 + @Autowired
  31 + SendUtils sendUtils;
  32 +
  33 + private static Comparator<ScheduleRealInfo> cpm = new ScheduleComparator.FCSJ();
  34 +
  35 + @Override
  36 + public void run() {
  37 + List<ScheduleRealInfo> all = new ArrayList<>(dayOfSchedule.findAll());
  38 + Collections.sort(all, cpm);
  39 +
  40 + long t = System.currentTimeMillis();
  41 + int size = all.size();
  42 +
  43 + ScheduleRealInfo sch;
  44 + for(int i = 0; i < size; i ++){
  45 + sch = all.get(i);
  46 + if(sch.getDfsjT() > t)
  47 + break;
  48 +
  49 + if(sch.isLate() == false
  50 + && sch.getStatus() == 0
  51 + && sch.getFcsjActual() == null){
  52 + //应发未发
  53 + sch.setLate(true);
  54 + //通知客户端
  55 + sendUtils.refreshSch(sch);
  56 + }
  57 + }
  58 + }
  59 +}
... ...
src/main/java/com/bsth/entity/schedule/rule/ScheduleRule1Flat.java
... ... @@ -67,6 +67,7 @@ public class ScheduleRule1Flat extends BEntity {
67 67 private String ryDbbms;
68 68 /** 对应的人员配置ids(用逗号隔开,如果分班,就先-隔开再逗号隔开) */
69 69 @NotNull
  70 + @Column(length = 1000)
70 71 private String ryConfigIds;
71 72 /** 起始人员(从0开始) */
72 73 @NotNull
... ...
src/main/java/com/bsth/entity/schedule/temp/SchedulePlanRuleResult.java
... ... @@ -2,10 +2,7 @@ package com.bsth.entity.schedule.temp;
2 2  
3 3 import com.bsth.entity.schedule.SchedulePlan;
4 4  
5   -import javax.persistence.Entity;
6   -import javax.persistence.GeneratedValue;
7   -import javax.persistence.Id;
8   -import javax.persistence.Table;
  5 +import javax.persistence.*;
9 6 import java.util.Date;
10 7  
11 8 /**
... ... @@ -32,12 +29,14 @@ public class SchedulePlanRuleResult {
32 29 private String ccZbh;
33 30  
34 31 /** 路牌id列表字符串 */
  32 + @Column(length = 1000)
35 33 private String gids;
36 34 /** 路牌名字列表字符串 */
37 35 private String gnames;
38 36 /** 翻到哪个路牌索引 */
39 37 private String gidindex;
40 38 /** 人员配置id列表字符串 */
  39 + @Column(length = 1000)
41 40 private String ecids;
42 41 /** 人员配置搭班编码列表字符串 */
43 42 private String ecdbbms;
... ...
src/main/java/com/bsth/service/forms/impl/FormsServiceImpl.java
... ... @@ -219,13 +219,11 @@ public class FormsServiceImpl implements FormsService {
219 219 // if(d.getJgh().equals(s.getjGh()) && d.getZbh().equals(s.getClZbh())){
220 220 // sList.add(s);
221 221 // }
222   -
223 222 if(empnames.equals("驾驶员")){
224   - if(d.getJgh().equals(s.getjGh()) && d.getZbh().equals(s.getClZbh())){
  223 + if(d.getJgh().equals(s.getjGh())){
225 224 sList.add(s);
226 225 }
227 226 }else if(empnames.equals("售票员")){
228   -// shif.setjName(arg0.getString("s_name")==null ? "":arg0.getString("s_name"));
229 227 String sgh=s.getsGh()==null?"":s.getsGh();
230 228 if(d.getSgh().equals(sgh) && d.getZbh().equals(s.getClZbh())){
231 229 sList.add(s);
... ... @@ -244,16 +242,17 @@ public class FormsServiceImpl implements FormsService {
244 242 double ljgl=culateMileageService.culateLjgl(sList);
245 243 double sjgl=culateMileageService.culateSjgl(sList);
246 244 double zyygl=Arith.add(ljgl, sjgl);
247   - double cjbc=culateMileageService.culateLbbc(sList);
248   - double Ljbc=culateMileageService.culateLjbc(sList,"");
  245 + int cjbc=culateMileageService.culateLbbc(sList);
  246 + int ljbc=culateMileageService.culateLjbc(sList,"");
  247 + int sjbc=culateMileageService.culateSjbc(sList, "");
249 248 double cjgl=culateMileageService.culateLbgl(sList);
250 249 double zjgl=culateMileageService.culateLjgl(sList);
251 250 d.setEmptMileage(String.valueOf(zksgl));//空驶公里
252 251 d.setTotalm(String.valueOf(Arith.add(zksgl, zyygl)));//总公里
253   - d.setSjbc(String.valueOf(culateMileageService.culateSjbc(sList, "")+culateMileageService.culateLjbc(sList, "")));
  252 + d.setSjbc(String.valueOf(sjbc+ljbc));
254 253 d.setJhlc(String.valueOf(zyygl));//运营里程
255 254 d.setCjbc(String.valueOf(cjbc));//抽检班次
256   - d.setLjbc(String.valueOf(Ljbc));//增加班次
  255 + d.setLjbc(String.valueOf(ljbc));//增加班次
257 256 d.setRemMileage(String.valueOf(cjgl));//抽检里程
258 257 d.setAddMileage(String.valueOf(zjgl));//增加里程
259 258  
... ... @@ -330,22 +329,23 @@ public class FormsServiceImpl implements FormsService {
330 329 double zyygl=Arith.add(ljgl, sjgl);
331 330 double jhgl=culateMileageService.culateJhgl(sList);
332 331 double cjgl=culateMileageService.culateLbgl(sList);
333   - double jhbc =culateMileageService.culateJhbc(sList,"");
334   - double cjbc=culateMileageService.culateLbbc(sList);
335   - double Ljbc=culateMileageService.culateLjbc(sList,"");
  332 + int jhbc =culateMileageService.culateJhbc(sList,"");
  333 + int cjbc=culateMileageService.culateLbbc(sList);
  334 + int ljbc=culateMileageService.culateLjbc(sList,"");
  335 + int sjbc=culateMileageService.culateSjbc(sList, "");
336 336 double zjgl=culateMileageService.culateLjgl(sList);
337 337 d.setEmptMileage(String.valueOf(zksgl));//空驶公里
338 338 d.setTotalm(String.valueOf(Arith.add(zksgl, zyygl)));//总公里
339   - d.setSjbc(String.valueOf(culateMileageService.culateSjbc(sList, "")+culateMileageService.culateLjbc(sList, "")));
  339 + d.setSjbc(String.valueOf(sjbc+ljbc));
340 340 d.setJhlc(String.valueOf(jhgl));//计划里程
341 341 d.setYygl(String.valueOf(zyygl));//运营公里
342 342 d.setSjjhlc(String.valueOf(sjgl));//实际计划里程
343 343 d.setRemMileage(String.valueOf(cjgl));//抽减里程
344 344 d.setJhbc(String.valueOf(jhbc));//计划班次
345 345 d.setCjbc(String.valueOf(cjbc));//抽检班次
346   - d.setLjbc(String.valueOf(Ljbc));//增加班次
  346 + d.setLjbc(String.valueOf(ljbc));//增加班次
347 347 d.setAddMileage(String.valueOf(zjgl));//增加公里
348   - d.setSjjhbc(String.valueOf(culateMileageService.culateSjbc(sList, "")));//实际计划班次
  348 + d.setSjjhbc(String.valueOf(sjbc));//实际计划班次
349 349 }
350 350 return list;
351 351 }
... ...
src/main/java/com/bsth/service/realcontrol/DataManagerService.java 0 → 100644
  1 +package com.bsth.service.realcontrol;
  2 +
  3 +import java.util.Map;
  4 +
  5 +/**
  6 + * Created by panzhao on 2017/4/18.
  7 + */
  8 +public interface DataManagerService {
  9 +
  10 + Map<String, Object> carInfos(Integer lineId);
  11 +
  12 + Map<String,Object> updateDevices(String jsonStr);
  13 +}
... ...
src/main/java/com/bsth/service/realcontrol/impl/DataManagerServiceImpl.java 0 → 100644
  1 +package com.bsth.service.realcontrol.impl;
  2 +
  3 +import com.alibaba.fastjson.JSONArray;
  4 +import com.alibaba.fastjson.JSONObject;
  5 +import com.bsth.common.ResponseCode;
  6 +import com.bsth.data.BasicData;
  7 +import com.bsth.entity.Cars;
  8 +import com.bsth.repository.CarsRepository;
  9 +import com.bsth.service.realcontrol.DataManagerService;
  10 +import com.bsth.util.db.DBUtils_oldSystem;
  11 +import org.slf4j.Logger;
  12 +import org.slf4j.LoggerFactory;
  13 +import org.springframework.beans.factory.annotation.Autowired;
  14 +import org.springframework.jdbc.core.JdbcTemplate;
  15 +import org.springframework.stereotype.Service;
  16 +
  17 +import java.util.ArrayList;
  18 +import java.util.HashMap;
  19 +import java.util.List;
  20 +import java.util.Map;
  21 +
  22 +/**
  23 + * Created by panzhao on 2017/4/18.
  24 + */
  25 +@Service
  26 +public class DataManagerServiceImpl implements DataManagerService{
  27 +
  28 + @Autowired
  29 + CarsRepository carsRepository;
  30 +
  31 + @Autowired
  32 + JdbcTemplate controlJdbcTemp;
  33 +
  34 + @Autowired
  35 + BasicData.BasicDataLoader dataLoader;
  36 +
  37 + Logger logger = LoggerFactory.getLogger(this.getClass());
  38 +
  39 + @Override
  40 + public Map<String, Object> carInfos(Integer lineId) {
  41 +
  42 + Map<String, Object> rs = new HashMap<>();
  43 + try {
  44 + List<Map<String, String>> nowData = new ArrayList<>();
  45 + List<Map<String, String>> oldData = new ArrayList<>();
  46 + Map<String, String> map;
  47 +
  48 + //查询新系统车辆信息
  49 + List<Cars> list = carsRepository.findCarsByLineId(lineId);
  50 + for(Cars c : list){
  51 + map = new HashMap<>();
  52 + map.put("nbbm", c.getInsideCode());
  53 + map.put("device", c.getEquipmentCode());
  54 + nowData.add(map);
  55 + }
  56 +
  57 + //获取老系统数据
  58 + JdbcTemplate jdbcTemplate = new JdbcTemplate(DBUtils_oldSystem.getDataSource());
  59 + List<Map<String, Object>> oyList = jdbcTemplate.queryForList("select NBBM,SBBH from JJWGPS_T_CLXXB t where xlbm=?", BasicData.lineId2CodeMap.get(lineId));
  60 + for(Map<String, Object> tempMap : oyList){
  61 + map = new HashMap<>();
  62 + map.put("nbbm", tempMap.get("NBBM").toString());
  63 + map.put("device", tempMap.get("SBBH").toString());
  64 + oldData.add(map);
  65 + }
  66 +
  67 + rs.put("status", ResponseCode.SUCCESS);
  68 + rs.put("nows", nowData);
  69 + rs.put("olds", oldData);
  70 + }catch (Exception e){
  71 + logger.error("", e);
  72 + rs.put("status", ResponseCode.ERROR);
  73 + rs.put("msg", e.getMessage());
  74 + }
  75 +
  76 + return rs;
  77 + }
  78 +
  79 + /**
  80 + * 更新设备号
  81 + * @param jsonStr
  82 + * @return
  83 + */
  84 + @Override
  85 + public Map<String, Object> updateDevices(String jsonStr) {
  86 + Map<String, Object> rs = new HashMap<>();
  87 + try {
  88 + int count=0;
  89 + JSONArray array = JSONArray.parseArray(jsonStr);
  90 + JSONObject jObj;
  91 + for(int i = 0; i < array.size(); i ++){
  92 + jObj = array.getJSONObject(i);
  93 + count += controlJdbcTemp.update("update bsth_c_cars set equipment_code=? where inside_code=?"
  94 + , jObj.getString("device"), jObj.getString("nbbm"));
  95 + }
  96 +
  97 + //刷新缓存
  98 + dataLoader.loadDeviceInfo();
  99 + rs.put("status", ResponseCode.SUCCESS);
  100 + rs.put("count", count);
  101 + }catch (Exception e){
  102 + logger.error("", e);
  103 + rs.put("status", ResponseCode.ERROR);
  104 + rs.put("msg", e.getMessage());
  105 + }
  106 + return rs;
  107 + }
  108 +}
... ...
src/main/java/com/bsth/service/realcontrol/impl/ScheduleRealInfoServiceImpl.java
... ... @@ -510,7 +510,7 @@ public class ScheduleRealInfoServiceImpl extends BaseServiceImpl&lt;ScheduleRealInf
510 510 + " from bsth_c_s_sp_info_real s "
511 511 + " where s.xl_Bm = '" + line + "' and DATE_FORMAT(s.schedule_Date,'%Y-%m-%d') ='" + date + "' "
512 512 + " GROUP BY s.j_Gh,s.cl_Zbh,s.lp_Name ,s.j_Name"
513   - + " order by (" + state + "),schedule_date_str,fcsj " + type;
  513 + + " order by (" + state + "),dateStr,fcsj " + type;
514 514 List<ScheduleRealInfo> list = jdbcTemplate.query(sqlPlan,
515 515 new RowMapper<ScheduleRealInfo>() {
516 516 @Override
... ... @@ -1403,7 +1403,7 @@ public class ScheduleRealInfoServiceImpl extends BaseServiceImpl&lt;ScheduleRealInf
1403 1403 lists.add(s);
1404 1404 }
1405 1405 }
1406   - double ksgl=culateService.culateKsgl(lists);
  1406 + double ksgl=culateService.culateKsgl(list);
1407 1407 double sjgl=culateService.culateSjgl(lists);
1408 1408 double jccgl=culateService.culateJccgl(lists);
1409 1409 double ljgl=culateService.culateLjgl(lists);
... ...
src/main/java/com/bsth/service/report/impl/CulateMileageServiceImpl.java
1 1 package com.bsth.service.report.impl;
2 2  
3 3 import java.util.ArrayList;
  4 +import java.util.Collections;
4 5 import java.util.HashMap;
5 6 import java.util.Iterator;
6 7 import java.util.List;
... ... @@ -14,6 +15,7 @@ import com.bsth.entity.realcontrol.ChildTaskPlan;
14 15 import com.bsth.entity.realcontrol.ScheduleRealInfo;
15 16 import com.bsth.service.report.CulateMileageService;
16 17 import com.bsth.util.Arith;
  18 +import com.bsth.util.ComparableJob;
17 19  
18 20 @Service
19 21 public class CulateMileageServiceImpl implements CulateMileageService{
... ... @@ -25,6 +27,7 @@ public class CulateMileageServiceImpl implements CulateMileageService{
25 27 @Override
26 28 public List<Map<String, Object>> jobFwqk(List<ScheduleRealInfo> lists) {
27 29 // TODO Auto-generated method stub
  30 + String[] lblxs = {"配车", "保养","故障","肇事","路阻","纠纷","缺人","客稀","缺车","气候","援外","吊慢","抽减","其他" };
28 31 List<Map<String, Object>> list=new ArrayList<Map<String,Object>>();
29 32 for (int i = 0; i < lists.size(); i++) {
30 33 ScheduleRealInfo scheduleRealInfo = lists.get(i);
... ... @@ -47,7 +50,7 @@ public class CulateMileageServiceImpl implements CulateMileageService{
47 50 newMap.put("dz", scheduleRealInfo.getQdzName());
48 51 newMap.put("sj", scheduleRealInfo.getFcsj());
49 52 newMap.put("lbbc", 1);
50   - newMap.put("lblc", scheduleRealInfo.getJhlcOrig());
  53 + newMap.put("lblc", scheduleRealInfo.getJhlcOrig()==null?0:scheduleRealInfo.getJhlcOrig());
51 54 newMap.put("jyqp", scheduleRealInfo.getRealMileage());
52 55 list.add(newMap);
53 56 }
... ... @@ -71,7 +74,7 @@ public class CulateMileageServiceImpl implements CulateMileageService{
71 74 newMap.put("dz", childTaskPlan.getStartStationName());
72 75 newMap.put("sj", childTaskPlan.getStartDate());
73 76 newMap.put("lbbc", 0);
74   - newMap.put("lblc", childTaskPlan.getMileage());
  77 + newMap.put("lblc", childTaskPlan.getMileage()==null?0:childTaskPlan.getMileage());
75 78 newMap.put("jyqp", scheduleRealInfo.getRealMileage());
76 79 list.add(newMap);
77 80  
... ... @@ -80,7 +83,33 @@ public class CulateMileageServiceImpl implements CulateMileageService{
80 83 }
81 84 }
82 85 }
83   - return list;
  86 + List<Map<String, Object>> listNew=new ArrayList<Map<String,Object>>();
  87 + for (int i = 0; i < lblxs.length; i++) {
  88 + String lx=lblxs[i];
  89 + double lblc=0.0;
  90 + int lbbc=0;
  91 + for (int j = 0; j < list.size(); j++) {
  92 + Map<String, Object> m1=list.get(j);
  93 + m1.put("lx", 0);
  94 + listNew.add(m1);
  95 + if(lx.equals(m1.get("nr").toString())){
  96 + lblc =Arith.add(lblc,Double.parseDouble(m1.get("lblc").toString()));
  97 + lbbc += Integer.parseInt(m1.get("lbbc").toString());
  98 + }
  99 + }
  100 + Map<String, Object> newMap = new HashMap<String, Object>();
  101 + newMap.put("lx", 1);
  102 + newMap.put("nr", lx);
  103 + newMap.put("lp", "小计");
  104 + newMap.put("nbbm", "少驶公里");
  105 + newMap.put("dz", lbbc);
  106 + newMap.put("sj", "少驶公里");
  107 + newMap.put("lblc", lblc);
  108 + listNew.add(newMap);
  109 +
  110 + }
  111 + Collections.sort(listNew, new ComparableJob());
  112 + return listNew;
84 113 }
85 114  
86 115 @Override
... ...
src/main/java/com/bsth/service/report/impl/ReportServiceImpl.java
... ... @@ -8,6 +8,7 @@ import java.text.ParseException;
8 8 import java.text.SimpleDateFormat;
9 9 import java.util.ArrayList;
10 10 import java.util.Calendar;
  11 +import java.util.Collections;
11 12 import java.util.Date;
12 13 import java.util.HashMap;
13 14 import java.util.Iterator;
... ... @@ -38,6 +39,7 @@ import com.bsth.repository.realcontrol.ScheduleRealInfoRepository;
38 39 import com.bsth.service.report.CulateMileageService;
39 40 import com.bsth.service.report.ReportService;
40 41 import com.bsth.util.Arith;
  42 +import com.bsth.util.ComparableJob;
41 43 import com.bsth.util.db.DBUtils_MS;
42 44  
43 45 @Service
... ... @@ -1150,6 +1152,7 @@ public class ReportServiceImpl implements ReportService{
1150 1152 @Override
1151 1153 public List<Map<String, Object>> jobFwqk(Map<String, Object> map) {
1152 1154 // TODO Auto-generated method stub
  1155 + String[] lblxs = {"配车", "保养","故障","肇事","路阻","纠纷","缺人","客稀","缺车","气候","援外","吊慢","抽减","其他" };
1153 1156 String line=map.get("line").toString();
1154 1157 String date=map.get("date").toString();
1155 1158 map.put("bcType", "normal");
... ... @@ -1179,7 +1182,7 @@ public class ReportServiceImpl implements ReportService{
1179 1182 newMap.put("sj", scheduleRealInfo.getFcsj());
1180 1183 newMap.put("lbbc", 1);
1181 1184 newMap.put("lblc", scheduleRealInfo.getJhlcOrig());
1182   - newMap.put("jyqp", scheduleRealInfo.getRealMileage());
  1185 + newMap.put("jyqp", scheduleRealInfo.getRemarks());
1183 1186 list.add(newMap);
1184 1187 }
1185 1188  
... ... @@ -1205,7 +1208,7 @@ public class ReportServiceImpl implements ReportService{
1205 1208 newMap.put("sj", childTaskPlan.getStartDate());
1206 1209 newMap.put("lbbc", 0);
1207 1210 newMap.put("lblc", childTaskPlan.getMileage());
1208   - newMap.put("jyqp", scheduleRealInfo.getRealMileage());
  1211 + newMap.put("jyqp", childTaskPlan.getRemarks());
1209 1212 list.add(newMap);
1210 1213  
1211 1214 }
... ... @@ -1213,7 +1216,36 @@ public class ReportServiceImpl implements ReportService{
1213 1216 }
1214 1217 }
1215 1218 }
1216   - return list;
  1219 + List<Map<String, Object>> listNew=new ArrayList<Map<String,Object>>();
  1220 + for (int i = 0; i < lblxs.length; i++) {
  1221 + String lx=lblxs[i];
  1222 + double lblc=0.0;
  1223 + int lbbc=0;
  1224 + for (int j = 0; j < list.size(); j++) {
  1225 + Map<String, Object> m1=list.get(j);
  1226 + if(lx.equals(m1.get("nr").toString())){
  1227 + m1.put("lx", 0);
  1228 + listNew.add(m1);
  1229 + lblc =Arith.add(lblc,Double.parseDouble(m1.get("lblc").toString()));
  1230 + lbbc += Integer.parseInt(m1.get("lbbc").toString());
  1231 + }
  1232 + }
  1233 + if(lblc>0){
  1234 + Map<String, Object> newMap = new HashMap<String, Object>();
  1235 + newMap.put("lx", 1);
  1236 + newMap.put("nr", lx);
  1237 + newMap.put("lp", "小计");
  1238 + newMap.put("nbbm", "少驶班次");
  1239 + newMap.put("jgh", lbbc);
  1240 + newMap.put("sj", "少驶公里");
  1241 + newMap.put("lblc", lblc);
  1242 + listNew.add(newMap);
  1243 + }
  1244 +
  1245 +
  1246 + }
  1247 + Collections.sort(listNew, new ComparableJob());
  1248 + return listNew;
1217 1249 }
1218 1250  
1219 1251 //统计临加班次详细信息
... ...
src/main/java/com/bsth/service/schedule/impl/SchedulePlanServiceImpl.java
... ... @@ -65,7 +65,7 @@ public class SchedulePlanServiceImpl extends BServiceImpl&lt;SchedulePlan, Long&gt; im
65 65 * @param schedulePlan 排班计划对象
66 66 * @param lpInfoResults_output 时刻表每日路牌的情况
67 67 */
68   - private ScheduleResults_output loopRuleOutput(
  68 + public ScheduleResults_output loopRuleOutput(
69 69 SchedulePlan schedulePlan,
70 70 LpInfoResults_output lpInfoResults_output) {
71 71 // 1-1、构造drools规则输入数据,输出数据
... ... @@ -116,7 +116,7 @@ public class SchedulePlanServiceImpl extends BServiceImpl&lt;SchedulePlan, Long&gt; im
116 116 * @param schedulePlan 排班计划对象
117 117 * @return TTInfoResults_output, LpInfoResults_output
118 118 */
119   - private Object[] ttInfoOutput(SchedulePlan schedulePlan) {
  119 + public Object[] ttInfoOutput(SchedulePlan schedulePlan) {
120 120 // 获取线路的所有未作废的时刻表
121 121 List<TTInfo> ttInfos = ttInfoRepository.findInCanceledByXl(schedulePlan.getXl());
122 122  
... ... @@ -174,7 +174,7 @@ public class SchedulePlanServiceImpl extends BServiceImpl&lt;SchedulePlan, Long&gt; im
174 174 * @param ttInfoResults_output ttInfoOutput方法规则输出
175 175 * @return PlanResult
176 176 */
177   - private PlanResult planResultOutput(
  177 + public PlanResult planResultOutput(
178 178 SchedulePlan schedulePlan,
179 179 ScheduleResults_output scheduleResults_output,
180 180 TTInfoResults_output ttInfoResults_output) {
... ...
src/main/java/com/bsth/service/schedule/rules/MyDroolsConfiguration.java
... ... @@ -4,7 +4,6 @@ import org.kie.api.KieBase;
4 4 import org.kie.api.KieBaseConfiguration;
5 5 import org.kie.api.KieServices;
6 6 import org.kie.api.builder.*;
7   -import org.kie.api.builder.Message;
8 7 import org.kie.api.builder.model.KieBaseModel;
9 8 import org.kie.api.builder.model.KieModuleModel;
10 9 import org.kie.api.builder.model.KieSessionModel;
... ... @@ -12,6 +11,8 @@ import org.kie.api.conf.EqualityBehaviorOption;
12 11 import org.kie.api.conf.EventProcessingOption;
13 12 import org.kie.api.runtime.KieContainer;
14 13 import org.kie.api.runtime.conf.ClockTypeOption;
  14 +import org.slf4j.Logger;
  15 +import org.slf4j.LoggerFactory;
15 16 import org.springframework.context.annotation.Bean;
16 17 import org.springframework.context.annotation.Configuration;
17 18  
... ... @@ -20,6 +21,9 @@ import org.springframework.context.annotation.Configuration;
20 21 */
21 22 @Configuration
22 23 public class MyDroolsConfiguration {
  24 + /** 日志记录器 */
  25 + private static final Logger logger = LoggerFactory.getLogger(MyDroolsConfiguration.class);
  26 +
23 27 /**
24 28 * 返回一个kiebase知识库,直接冲文件系统读入drl规则文件,
25 29 * TODO:以后需要从数据库读入规则文件,并重新创建kbase知识库。
... ... @@ -72,8 +76,12 @@ public class MyDroolsConfiguration {
72 76 // 4、创建KieBuilder,使用KieFileSystem构建
73 77 KieBuilder kieBuilder = kieServices.newKieBuilder(kfs).buildAll();
74 78 Results results = kieBuilder.getResults();
75   - if (results.hasMessages(Message.Level.ERROR))
76   - throw new IllegalStateException("构建drools6错误:" + results.getMessages());
  79 +// if (results.hasMessages(Message.Level.ERROR))
  80 +// throw new IllegalStateException("构建drools6错误:" + results.getMessages());
  81 + if (results.hasMessages(Message.Level.ERROR)) {
  82 + logger.info("构建drools6错误:" + results.getMessages());
  83 + return null;
  84 + }
77 85  
78 86 // 5、获取KieContainer
79 87 // TODO:ReleaseId用处很大,以后再议
... ...
src/main/java/com/bsth/service/schedule/utils/DataImportExportService.java deleted 100644 → 0
1   -package com.bsth.service.schedule.utils;
2   -
3   -import org.springframework.web.multipart.MultipartFile;
4   -
5   -import java.io.File;
6   -import java.util.Map;
7   -
8   -/**
9   - * 数据导入导出服务。
10   - */
11   -public interface DataImportExportService {
12   - /**
13   - * 上传文件。
14   - * @param file mutipartFile
15   - * @return 上传后的文件路径
16   - * @throws Exception
17   - */
18   - File uploadFile(MultipartFile file) throws Exception;
19   -
20   - /**
21   - * 上传文件,并导入文件数据。
22   - * @param datafile 上传的文件
23   - * @param ktrFile 导入的逻辑ktr文件
24   - * @throws Exception
25   - */
26   - void fileDataImport(MultipartFile datafile, File ktrFile) throws Exception;
27   - void fileDataImport(File datafile, File ktrFile) throws Exception;
28   -
29   - /**
30   - * 数据导出。
31   - * @param fileName 文件名
32   - * @param ktrFile 导出的逻辑ktr文件
33   - * @return 导出的文件
34   - * @throws Exception
35   - */
36   - File fileDataOutput(String fileName, File ktrFile) throws Exception;
37   -
38   -
39   - File fileDataOutput(String fileName, File ktrFile, Map<String, Object> param) throws Exception;
40   -}
src/main/java/com/bsth/service/schedule/utils/DataImportExportServiceImpl.java deleted 100644 → 0
1   -package com.bsth.service.schedule.utils;
2   -
3   -import com.google.common.io.Files;
4   -import org.joda.time.DateTime;
5   -import org.pentaho.di.core.KettleEnvironment;
6   -import org.pentaho.di.core.util.EnvUtil;
7   -import org.pentaho.di.trans.Trans;
8   -import org.pentaho.di.trans.TransMeta;
9   -import org.springframework.beans.factory.InitializingBean;
10   -import org.springframework.beans.factory.annotation.Autowired;
11   -import org.springframework.boot.context.properties.EnableConfigurationProperties;
12   -import org.springframework.stereotype.Service;
13   -import org.springframework.util.CollectionUtils;
14   -import org.springframework.web.multipart.MultipartFile;
15   -
16   -import java.io.File;
17   -import java.util.HashMap;
18   -import java.util.Map;
19   -import java.util.Properties;
20   -
21   -/**
22   - * Created by xu on 16/6/23.
23   - */
24   -@Service
25   -@EnableConfigurationProperties(DataToolsProperties.class)
26   -public class DataImportExportServiceImpl implements DataImportExportService, InitializingBean {
27   -
28   - @Autowired
29   - private DataToolsProperties dataToolsProperties;
30   -
31   - /**
32   - * 自定义kettle环境初始化定义。
33   - */
34   - private void ktrEnvironmentInit() throws Exception {
35   - // 由于kettle.properties可能没有(没有安装过kettle),
36   - // 导致 EnvUtil.environmentInit() 报找不到kettle.properties文件
37   - // 所以这里重写 EnvUtil.environmentInit() 方法
38   -
39   - if(Thread.currentThread().getContextClassLoader() == null) {
40   - Thread.currentThread().setContextClassLoader(ClassLoader.getSystemClassLoader());
41   - }
42   -
43   - // 获取配置文件
44   - File file = new File(getClass().getResource(dataToolsProperties.getKettleProperties()).toURI());
45   - Properties kettleProperties = EnvUtil.readProperties(file.getAbsolutePath());
46   - EnvUtil.applyKettleProperties(kettleProperties);
47   - System.getProperties().put("Internal.Cluster.Size", "1");
48   - System.getProperties().put("Internal.Slave.Transformation.Number", "0");
49   - System.getProperties().put("Internal.Slave.Server.Name", "slave-trans-name");
50   - System.getProperties().put("Internal.Step.CopyNr", "0");
51   - System.getProperties().put("Internal.Step.Name", "step-name");
52   - System.getProperties().put("Internal.Step.Partition.ID", "partition-id");
53   - System.getProperties().put("Internal.Step.Partition.Number", "0");
54   - System.getProperties().put("Internal.Step.Unique.Count", "1");
55   - System.getProperties().put("Internal.Step.Unique.Number", "0");
56   - if(!kettleProperties.containsKey("vfs.sftp.org.apache.commons.vfs2.provider.sftp.SftpFileSystemConfigBuilder.USER_DIR_IS_ROOT")) {
57   - System.getProperties().put("vfs.sftp.org.apache.commons.vfs2.provider.sftp.SftpFileSystemConfigBuilder.USER_DIR_IS_ROOT", "false");
58   - }
59   -
60   - }
61   -
62   - @Override
63   - public void afterPropertiesSet() throws Exception {
64   - // 初始化kettle环境(自定义)
65   - ktrEnvironmentInit();
66   -
67   - // 添加全局ktr变量,并覆盖原来的设置
68   - Map<String, String> kvars = new HashMap<>();
69   - kvars.put("v_db_ip", dataToolsProperties.getKvarsDbip());
70   - kvars.put("v_db_uname", dataToolsProperties.getKvarsDbuname());
71   - kvars.put("v_db_pwd", dataToolsProperties.getKvarsDbpwd());
72   - kvars.put("v_db_dname", dataToolsProperties.getKvarsDbdname());
73   - EnvUtil.applyKettleProperties(kvars, true);
74   - KettleEnvironment.init();
75   - }
76   -
77   - @Override
78   - public File uploadFile(MultipartFile file) throws Exception {
79   - // TODO:以后的文件名要加时间戳
80   - File newFile = new File(
81   - dataToolsProperties.getFileuploadDir() + File.separator +
82   - file.getOriginalFilename());
83   - Files.write(file.getBytes(), newFile);
84   -
85   - return newFile;
86   - }
87   -
88   - @Override
89   - public void fileDataImport(MultipartFile datafile, File ktrFile) throws Exception {
90   - // 1、上传数据文件
91   - File uploadFile = uploadFile(datafile);
92   -
93   - // 2、使用kettle运行封装数据导入逻辑的ktr转换文件
94   - // 2.1、初始化kettle(组件初始化已经做了)
95   - // 2.2、创建转换元数据,转换
96   - TransMeta transMeta = new TransMeta(ktrFile.getAbsolutePath());
97   - Trans trans = new Trans(transMeta);
98   - // 2.3、设定命名参数,用于指定数据文件,注意每个ktr必须都有以下指定的命名参数
99   - trans.setParameterValue("filepath", uploadFile.getAbsolutePath()); // 指定导入数据文件的位置
100   - trans.setParameterValue("erroroutputdir", dataToolsProperties.getTransErrordir()); // ktr转换错误输出目录
101   - // TODO:可以考虑设定日志输出
102   - // 2.4、执行转换
103   - trans.execute(null);
104   - // 2.5、等待转换结束
105   - trans.waitUntilFinished();
106   -
107   - // 3、判定ktr错误数,注意这种错误代表部分数据错误,不会终止转换执行,一般设计ktr的时候,会有错误输出文件,TODO:以后考虑使用日志实时输出
108   - if (trans.getErrors() > 0) {
109   - throw new Exception("转换数据部分错误,请查看相关错误输出文件!");
110   - }
111   - }
112   -
113   - @Override
114   - public void fileDataImport(File datafile, File ktrFile) throws Exception {
115   -// // 1、上传数据文件
116   -// File uploadFile = datafile;
117   -
118   - // 2、使用kettle运行封装数据导入逻辑的ktr转换文件
119   - // 2.1、初始化kettle(组件初始化已经做了)
120   - // 2.2、创建转换元数据,转换
121   - TransMeta transMeta = new TransMeta(ktrFile.getAbsolutePath());
122   - Trans trans = new Trans(transMeta);
123   - // 2.3、设定命名参数,用于指定数据文件,注意每个ktr必须都有以下指定的命名参数
124   - trans.setParameterValue("filepath", datafile.getAbsolutePath()); // 指定导入数据文件的位置
125   - trans.setParameterValue("erroroutputdir", dataToolsProperties.getTransErrordir()); // ktr转换错误输出目录
126   - // TODO:可以考虑设定日志输出
127   - // 2.4、执行转换
128   - trans.execute(null);
129   - // 2.5、等待转换结束
130   - trans.waitUntilFinished();
131   -
132   - // 3、判定ktr错误数,注意这种错误代表部分数据错误,不会终止转换执行,一般设计ktr的时候,会有错误输出文件,TODO:以后考虑使用日志实时输出
133   - if (trans.getErrors() > 0) {
134   - throw new Exception("转换数据部分错误,请查看相关错误输出文件!");
135   - }
136   - }
137   -
138   - @Override
139   - public File fileDataOutput(String fileName, File ktrFile) throws Exception {
140   - return fileDataOutput(fileName, ktrFile, null);
141   - }
142   -
143   - @Override
144   - public File fileDataOutput(String fileName, File ktrFile, Map<String, Object> param) throws Exception {
145   - // 初始化转换,元数据,转换对象
146   - TransMeta transMeta = new TransMeta(ktrFile.getAbsolutePath());
147   - Trans trans = new Trans(transMeta);
148   - // 设定命名参数
149   - String filepath = dataToolsProperties.getFileoutputDir() +
150   - File.separator +
151   - fileName +
152   - new DateTime().toString("yyyyMMddHHmmss") + ".xls";
153   - trans.setParameterValue("filepath", filepath);
154   -
155   - // 添加其他参数
156   - if (!CollectionUtils.isEmpty(param)) {
157   - for (String key : param.keySet()) {
158   - trans.setParameterValue(key, String.valueOf(param.get(key)));
159   - }
160   - }
161   -
162   - // 执行转换
163   - trans.execute(null);
164   - // 等待转换结束
165   - trans.waitUntilFinished();
166   -
167   - if (trans.getErrors() > 0) {
168   - throw new Exception("转换数据部分错误,请查看相关错误输出文件!");
169   - }
170   -
171   - return new File(filepath);
172   - }
173   -
174   -
175   - // TODO:以后改成下面的样子
176   -// import java.io.FileInputStream;
177   -// import java.io.FileOutputStream;
178   -// import java.io.IOException;
179   -// import java.io.InputStream;
180   -// import java.util.Iterator;
181   -//
182   -// import org.apache.poi.hssf.usermodel.HSSFCell;
183   -// import org.apache.poi.hssf.usermodel.HSSFRow;
184   -// import org.apache.poi.hssf.usermodel.HSSFSheet;
185   -// import org.apache.poi.hssf.usermodel.HSSFWorkbook;
186   -//
187   -// import org.apache.poi.xssf.usermodel.XSSFCell;
188   -// import org.apache.poi.xssf.usermodel.XSSFRow;
189   -// import org.apache.poi.xssf.usermodel.XSSFSheet;
190   -// import org.apache.poi.xssf.usermodel.XSSFWorkbook;
191   -//
192   -// public class ReadWriteExcelFile {
193   -//
194   -// public static void readXLSFile() throws IOException
195   -// {
196   -// InputStream ExcelFileToRead = new FileInputStream("C:/Test.xls");
197   -// HSSFWorkbook wb = new HSSFWorkbook(ExcelFileToRead);
198   -//
199   -// HSSFSheet sheet=wb.getSheetAt(0);
200   -// HSSFRow row;
201   -// HSSFCell cell;
202   -//
203   -// Iterator rows = sheet.rowIterator();
204   -//
205   -// while (rows.hasNext())
206   -// {
207   -// row=(HSSFRow) rows.next();
208   -// Iterator cells = row.cellIterator();
209   -//
210   -// while (cells.hasNext())
211   -// {
212   -// cell=(HSSFCell) cells.next();
213   -//
214   -// if (cell.getCellType() == HSSFCell.CELL_TYPE_STRING)
215   -// {
216   -// System.out.print(cell.getStringCellValue()+" ");
217   -// }
218   -// else if(cell.getCellType() == HSSFCell.CELL_TYPE_NUMERIC)
219   -// {
220   -// System.out.print(cell.getNumericCellValue()+" ");
221   -// }
222   -// else
223   -// {
224   -// //U Can Handel Boolean, Formula, Errors
225   -// }
226   -// }
227   -// System.out.println();
228   -// }
229   -//
230   -// }
231   -//
232   -// public static void writeXLSFile() throws IOException {
233   -//
234   -// String excelFileName = "C:/Test.xls";//name of excel file
235   -//
236   -// String sheetName = "Sheet1";//name of sheet
237   -//
238   -// HSSFWorkbook wb = new HSSFWorkbook();
239   -// HSSFSheet sheet = wb.createSheet(sheetName) ;
240   -//
241   -// //iterating r number of rows
242   -// for (int r=0;r < 5; r++ )
243   -// {
244   -// HSSFRow row = sheet.createRow(r);
245   -//
246   -// //iterating c number of columns
247   -// for (int c=0;c < 5; c++ )
248   -// {
249   -// HSSFCell cell = row.createCell(c);
250   -//
251   -// cell.setCellValue("Cell "+r+" "+c);
252   -// }
253   -// }
254   -//
255   -// FileOutputStream fileOut = new FileOutputStream(excelFileName);
256   -//
257   -// //write this workbook to an Outputstream.
258   -// wb.write(fileOut);
259   -// fileOut.flush();
260   -// fileOut.close();
261   -// }
262   -//
263   -// public static void readXLSXFile() throws IOException
264   -// {
265   -// InputStream ExcelFileToRead = new FileInputStream("C:/Test.xlsx");
266   -// XSSFWorkbook wb = new XSSFWorkbook(ExcelFileToRead);
267   -//
268   -// XSSFWorkbook test = new XSSFWorkbook();
269   -//
270   -// XSSFSheet sheet = wb.getSheetAt(0);
271   -// XSSFRow row;
272   -// XSSFCell cell;
273   -//
274   -// Iterator rows = sheet.rowIterator();
275   -//
276   -// while (rows.hasNext())
277   -// {
278   -// row=(XSSFRow) rows.next();
279   -// Iterator cells = row.cellIterator();
280   -// while (cells.hasNext())
281   -// {
282   -// cell=(XSSFCell) cells.next();
283   -//
284   -// if (cell.getCellType() == XSSFCell.CELL_TYPE_STRING)
285   -// {
286   -// System.out.print(cell.getStringCellValue()+" ");
287   -// }
288   -// else if(cell.getCellType() == XSSFCell.CELL_TYPE_NUMERIC)
289   -// {
290   -// System.out.print(cell.getNumericCellValue()+" ");
291   -// }
292   -// else
293   -// {
294   -// //U Can Handel Boolean, Formula, Errors
295   -// }
296   -// }
297   -// System.out.println();
298   -// }
299   -//
300   -// }
301   -//
302   -// public static void writeXLSXFile() throws IOException {
303   -//
304   -// String excelFileName = "C:/Test.xlsx";//name of excel file
305   -//
306   -// String sheetName = "Sheet1";//name of sheet
307   -//
308   -// XSSFWorkbook wb = new XSSFWorkbook();
309   -// XSSFSheet sheet = wb.createSheet(sheetName) ;
310   -//
311   -// //iterating r number of rows
312   -// for (int r=0;r < 5; r++ )
313   -// {
314   -// XSSFRow row = sheet.createRow(r);
315   -//
316   -// //iterating c number of columns
317   -// for (int c=0;c < 5; c++ )
318   -// {
319   -// XSSFCell cell = row.createCell(c);
320   -//
321   -// cell.setCellValue("Cell "+r+" "+c);
322   -// }
323   -// }
324   -//
325   -// FileOutputStream fileOut = new FileOutputStream(excelFileName);
326   -//
327   -// //write this workbook to an Outputstream.
328   -// wb.write(fileOut);
329   -// fileOut.flush();
330   -// fileOut.close();
331   -// }
332   -//
333   -// public static void main(String[] args) throws IOException {
334   -//
335   -// writeXLSFile();
336   -// readXLSFile();
337   -//
338   -// writeXLSXFile();
339   -// readXLSXFile();
340   -//
341   -// }
342   -//
343   -// }
344   -}
src/main/java/com/bsth/service/schedule/utils/DataToolsServiceImpl.java
... ... @@ -13,10 +13,9 @@ import org.pentaho.di.trans.Trans;
13 13 import org.pentaho.di.trans.TransMeta;
14 14 import org.slf4j.Logger;
15 15 import org.slf4j.LoggerFactory;
16   -import org.springframework.beans.factory.InitializingBean;
17 16 import org.springframework.beans.factory.annotation.Autowired;
18 17 import org.springframework.boot.context.properties.EnableConfigurationProperties;
19   -import org.springframework.stereotype.Service;
  18 +import org.springframework.stereotype.Component;
20 19  
21 20 import java.io.File;
22 21 import java.io.PrintWriter;
... ... @@ -24,19 +23,41 @@ import java.io.StringWriter;
24 23 import java.util.HashMap;
25 24 import java.util.Map;
26 25 import java.util.Properties;
  26 +import java.util.concurrent.atomic.AtomicBoolean;
27 27  
28 28 /**
29 29 * Created by xu on 17/1/3.
30 30 */
31   -@Service
  31 +@Component
32 32 @EnableConfigurationProperties(DataToolsProperties.class)
33   -public class DataToolsServiceImpl implements DataToolsService, InitializingBean {
  33 +public class DataToolsServiceImpl implements DataToolsService {
34 34 /** 日志记录器 */
35 35 private static final Logger LOGGER = LoggerFactory.getLogger(DataToolsServiceImpl.class);
36 36  
37 37 @Autowired
38 38 private DataToolsProperties dataToolsProperties;
39 39  
  40 + /** 原子操作类 */
  41 + private AtomicBoolean flag = new AtomicBoolean(false);
  42 +
  43 + private void initKettle() throws Exception {
  44 + if (flag.compareAndSet(false, true)) {
  45 + LOGGER.info("kettle初始化......");
  46 +
  47 + // 初始化kettle环境(自定义)
  48 + ktrEnvironmentInit();
  49 +
  50 + // 添加全局ktr变量,并覆盖原来的设置
  51 + Map<String, String> kvars = new HashMap<>();
  52 + kvars.put("v_db_ip", dataToolsProperties.getKvarsDbip());
  53 + kvars.put("v_db_uname", dataToolsProperties.getKvarsDbuname());
  54 + kvars.put("v_db_pwd", dataToolsProperties.getKvarsDbpwd());
  55 + kvars.put("v_db_dname", dataToolsProperties.getKvarsDbdname());
  56 + EnvUtil.applyKettleProperties(kvars, true);
  57 + KettleEnvironment.init();
  58 + }
  59 + }
  60 +
40 61 /**
41 62 * 自定义kettle环境初始化定义。
42 63 */
... ... @@ -70,24 +91,11 @@ public class DataToolsServiceImpl implements DataToolsService, InitializingBean
70 91 }
71 92  
72 93 @Override
73   - public void afterPropertiesSet() throws Exception {
74   - // 初始化kettle环境(自定义)
75   - ktrEnvironmentInit();
76   -
77   - // 添加全局ktr变量,并覆盖原来的设置
78   - Map<String, String> kvars = new HashMap<>();
79   - kvars.put("v_db_ip", dataToolsProperties.getKvarsDbip());
80   - kvars.put("v_db_uname", dataToolsProperties.getKvarsDbuname());
81   - kvars.put("v_db_pwd", dataToolsProperties.getKvarsDbpwd());
82   - kvars.put("v_db_dname", dataToolsProperties.getKvarsDbdname());
83   - EnvUtil.applyKettleProperties(kvars, true);
84   - KettleEnvironment.init();
85   - }
86   -
87   - @Override
88 94 public File uploadFile(String filename, byte[] filedata) throws ScheduleException {
89 95 // 上传文件
90 96 try {
  97 + initKettle();
  98 +
91 99 LOGGER.info("start uploadFile...originalFilename={}", filename);
92 100 File newFile = new File(dataToolsProperties.getFileuploadDir() + File.separator +
93 101 filename + "-upload-" + new DateTime().toString("yyyyMMddHHmmss") + ".xls");
... ... @@ -127,6 +135,8 @@ public class DataToolsServiceImpl implements DataToolsService, InitializingBean
127 135 String transLogId = "";
128 136 String transMetaLogId = "";
129 137 try {
  138 + initKettle();
  139 +
130 140 LOGGER.info("start importData...originalFilename={}", file.getAbsolutePath());
131 141 // 检查参数
132 142 String transpath = String.valueOf(params.get("transpath"));
... ... @@ -189,6 +199,8 @@ public class DataToolsServiceImpl implements DataToolsService, InitializingBean
189 199 String transLogId = "";
190 200 String transMetaLogId = "";
191 201 try {
  202 + initKettle();
  203 +
192 204 LOGGER.info("start exportData...");
193 205 // 检查参数
194 206 String filename = String.valueOf(params.get("filename"));
... ...
src/main/java/com/bsth/util/ComparableJob.java 0 → 100644
  1 +package com.bsth.util;
  2 +
  3 +import java.util.Comparator;
  4 +import java.util.Map;
  5 +
  6 +
  7 +public class ComparableJob implements Comparator<Map<String, Object>>{
  8 +
  9 + @Override
  10 + public int compare(Map<String, Object> o1, Map<String, Object> o2) {
  11 + // TODO Auto-generated method stub
  12 + return o1.get("nr").toString().compareTo(o2.get("nr").toString());
  13 + }
  14 +
  15 +}
... ...
src/main/java/com/bsth/util/db/BaseDao_MS.java deleted 100644 → 0
1   -package com.bsth.util.db;
2   -
3   -
4   -import org.apache.commons.lang3.CharUtils;
5   -import org.apache.commons.lang3.StringUtils;
6   -import org.slf4j.Logger;
7   -import org.slf4j.LoggerFactory;
8   -
9   -
10   -/**
11   - *
12   - * @ClassName: BaseDao
13   - * @author PanZhao
14   - * @param <T>
15   - * @date 2016年6月27日 上午10:33:12
16   - *
17   - */
18   -public class BaseDao_MS {
19   -
20   - static Logger logger = LoggerFactory.getLogger(BaseDao_MS.class);
21   -
22   - /**
23   - *
24   - * @Title: propertyToField
25   - * @Description: TODO(java转数据库字段名)
26   - * @param @param property
27   - * @throws
28   - */
29   - public static String propertyToField(String property) {
30   - if (null == property) {
31   - return "";
32   - }
33   - char[] chars = property.toCharArray();
34   - StringBuffer sb = new StringBuffer();
35   - for (char c : chars) {
36   - if (CharUtils.isAsciiAlphaUpper(c)) {
37   - sb.append("_" + StringUtils.lowerCase(CharUtils.toString(c)));
38   - } else {
39   - sb.append(c);
40   - }
41   - }
42   - return sb.toString();
43   - }
44   -}
src/main/java/com/bsth/util/db/DBUtils_MS.java
1 1 package com.bsth.util.db;
2 2  
  3 +import com.mchange.v2.c3p0.DataSources;
  4 +import org.apache.log4j.Logger;
  5 +
  6 +import javax.sql.DataSource;
3 7 import java.io.FileNotFoundException;
4 8 import java.io.IOException;
5 9 import java.sql.Connection;
... ... @@ -10,15 +14,8 @@ import java.util.HashMap;
10 14 import java.util.Map;
11 15 import java.util.Properties;
12 16  
13   -import javax.sql.DataSource;
14   -
15   -import org.apache.log4j.Logger;
16   -import org.springframework.stereotype.Component;
17   -
18   -import com.mchange.v2.c3p0.DataSources;
19   -
20 17 /**
21   - * 808GPS SQL Server数据库连接工具类
  18 + * 网关ms库连接池
22 19 * @author PanZhao
23 20 *
24 21 */
... ...
src/main/java/com/bsth/util/db/DBUtils_oldSystem.java 0 → 100644
  1 +package com.bsth.util.db;
  2 +
  3 +import com.mchange.v2.c3p0.DataSources;
  4 +import org.apache.log4j.Logger;
  5 +
  6 +import javax.sql.DataSource;
  7 +import java.sql.Connection;
  8 +import java.sql.ResultSet;
  9 +import java.sql.SQLException;
  10 +import java.sql.Statement;
  11 +import java.util.HashMap;
  12 +import java.util.Map;
  13 +
  14 +/**
  15 + * 老系统数据库连接池(保持少量的连接,不会对老系统有什么影响)
  16 + * @author PanZhao
  17 + *
  18 + */
  19 +//@Component
  20 +public class DBUtils_oldSystem {
  21 +
  22 + private static String url = null;
  23 +
  24 + private static String username = null;
  25 +
  26 + private static String pwd = null;
  27 +
  28 + private static DataSource ds_pooled;
  29 +
  30 + static Logger logger = Logger.getLogger(DBUtils_oldSystem.class);
  31 +
  32 + static {
  33 +
  34 + try {
  35 + // 1. 加载驱动类
  36 + Class.forName("oracle.jdbc.driver.OracleDriver");
  37 +
  38 + url = "jdbc:oracle:thin:@10.10.200.225:1521:orcl";
  39 + username = "jjwgps";
  40 + pwd = "jjwgps";
  41 +
  42 + // 设置连接数据库的配置信息
  43 + DataSource ds_unpooled = DataSources.unpooledDataSource(url,
  44 + username, pwd);
  45 +
  46 + Map<String, Object> pool_conf = new HashMap<String, Object>();
  47 + // 设置最大连接数
  48 + pool_conf.put("maxPoolSize", 5);
  49 +
  50 + pool_conf.put("testConnectionOnCheckout", false);
  51 + //异步检测连接的有效性
  52 + pool_conf.put("testConnectionOnCheckin", true);
  53 + //10分钟检测一次
  54 + pool_conf.put("idleConnectionTestPeriod", 60 * 10);
  55 + ds_pooled = DataSources.pooledDataSource(ds_unpooled, pool_conf);
  56 + } catch (ClassNotFoundException e) {
  57 + logger.error(e.toString());
  58 + e.printStackTrace();
  59 + } catch (SQLException e) {
  60 + logger.error("初始化老系统连接池失败,非正式环境请忽略这个问题!");
  61 + logger.error(e.toString());
  62 + e.printStackTrace();
  63 + }
  64 + }
  65 +
  66 + /**
  67 + * 获取连接对象
  68 + */
  69 + public static Connection getConnection() throws SQLException {
  70 + return ds_pooled.getConnection();
  71 + }
  72 +
  73 + /**
  74 + * 释放连接池资源
  75 + */
  76 + public static void clearup() {
  77 + if (ds_pooled != null) {
  78 + try {
  79 + DataSources.destroy(ds_pooled);
  80 + } catch (SQLException e) {
  81 + logger.error(e.toString());
  82 + e.printStackTrace();
  83 + }
  84 + }
  85 + }
  86 +
  87 + /**
  88 + * 资源关闭
  89 + *
  90 + * @param rs
  91 + * @param stmt
  92 + * @param conn
  93 + */
  94 + public static void close(ResultSet rs, Statement stmt, Connection conn) {
  95 + if (rs != null) {
  96 + try {
  97 + rs.close();
  98 + } catch (SQLException e) {
  99 + logger.error(e.toString());
  100 + e.printStackTrace();
  101 + }
  102 + }
  103 +
  104 + if (stmt != null) {
  105 + try {
  106 + stmt.close();
  107 + } catch (SQLException e) {
  108 + logger.error(e.toString());
  109 + e.printStackTrace();
  110 + }
  111 + }
  112 +
  113 + if (conn != null) {
  114 + try {
  115 + conn.close();
  116 + } catch (SQLException e) {
  117 + logger.error(e.toString());
  118 + e.printStackTrace();
  119 + }
  120 + }
  121 + }
  122 +
  123 + public static DataSource getDataSource(){
  124 + return ds_pooled;
  125 + }
  126 +}
... ...
src/main/resources/datatools/ktrs/carsDataInput.ktr
... ... @@ -86,6 +86,30 @@
86 86 <notepads>
87 87 </notepads>
88 88 <connection>
  89 + <name>192.168.168.1_jwgl_dw</name>
  90 + <server>192.168.168.1</server>
  91 + <type>ORACLE</type>
  92 + <access>Native</access>
  93 + <database>orcl</database>
  94 + <port>1521</port>
  95 + <username>jwgl_dw</username>
  96 + <password>Encrypted 2be98afc86aa7f2e4cb13b977d2adabcd</password>
  97 + <servername/>
  98 + <data_tablespace/>
  99 + <index_tablespace/>
  100 + <attributes>
  101 + <attribute><code>FORCE_IDENTIFIERS_TO_LOWERCASE</code><attribute>N</attribute></attribute>
  102 + <attribute><code>FORCE_IDENTIFIERS_TO_UPPERCASE</code><attribute>N</attribute></attribute>
  103 + <attribute><code>IS_CLUSTERED</code><attribute>N</attribute></attribute>
  104 + <attribute><code>PORT_NUMBER</code><attribute>1521</attribute></attribute>
  105 + <attribute><code>PRESERVE_RESERVED_WORD_CASE</code><attribute>N</attribute></attribute>
  106 + <attribute><code>QUOTE_ALL_FIELDS</code><attribute>N</attribute></attribute>
  107 + <attribute><code>SUPPORTS_BOOLEAN_DATA_TYPE</code><attribute>Y</attribute></attribute>
  108 + <attribute><code>SUPPORTS_TIMESTAMP_DATA_TYPE</code><attribute>Y</attribute></attribute>
  109 + <attribute><code>USE_POOLING</code><attribute>N</attribute></attribute>
  110 + </attributes>
  111 + </connection>
  112 + <connection>
89 113 <name>bus_control_variable</name>
90 114 <server>&#x24;&#x7b;v_db_ip&#x7d;</server>
91 115 <type>MYSQL</type>
... ... @@ -298,6 +322,18 @@
298 322 <group/>
299 323 </field>
300 324 <field>
  325 + <name>&#x8f66;&#x8f86;&#x7f16;&#x7801;</name>
  326 + <type>String</type>
  327 + <length>-1</length>
  328 + <precision>-1</precision>
  329 + <trim_type>none</trim_type>
  330 + <repeat>N</repeat>
  331 + <format/>
  332 + <currency/>
  333 + <decimal/>
  334 + <group/>
  335 + </field>
  336 + <field>
301 337 <name>&#x5185;&#x90e8;&#x7f16;&#x7801;</name>
302 338 <type>String</type>
303 339 <length>-1</length>
... ... @@ -358,7 +394,7 @@
358 394 <group/>
359 395 </field>
360 396 <field>
361   - <name>&#x4f9b;&#x5e94;&#x5546;&#x540d;&#x79f0;</name>
  397 + <name>&#x8bbe;&#x5907;&#x4f9b;&#x5e94;&#x5382;&#x5546;</name>
362 398 <type>String</type>
363 399 <length>-1</length>
364 400 <precision>-1</precision>
... ... @@ -444,12 +480,12 @@
444 480 <update>Y</update>
445 481 </value>
446 482 <value>
447   - <name>inside_code</name>
448   - <rename>&#x5185;&#x90e8;&#x7f16;&#x7801;</rename>
  483 + <name>car_code</name>
  484 + <rename>&#x8f66;&#x8f86;&#x7f16;&#x7801;</rename>
449 485 <update>Y</update>
450 486 </value>
451 487 <value>
452   - <name>car_code</name>
  488 + <name>inside_code</name>
453 489 <rename>&#x5185;&#x90e8;&#x7f16;&#x7801;</rename>
454 490 <update>Y</update>
455 491 </value>
... ... @@ -475,7 +511,7 @@
475 511 </value>
476 512 <value>
477 513 <name>supplier_name</name>
478   - <rename>&#x4f9b;&#x5e94;&#x5546;&#x540d;&#x79f0;</rename>
  514 + <rename>&#x8bbe;&#x5907;&#x4f9b;&#x5e94;&#x5382;&#x5546;</rename>
479 515 <update>Y</update>
480 516 </value>
481 517 <value>
... ... @@ -683,4 +719,3 @@
683 719 <slave_transformation>N</slave_transformation>
684 720  
685 721 </transformation>
686   -
... ...
src/main/resources/datatools/ktrs/carsDataOutput.ktr
... ... @@ -81,6 +81,30 @@
81 81 <notepads>
82 82 </notepads>
83 83 <connection>
  84 + <name>192.168.168.1_jwgl_dw</name>
  85 + <server>192.168.168.1</server>
  86 + <type>ORACLE</type>
  87 + <access>Native</access>
  88 + <database>orcl</database>
  89 + <port>1521</port>
  90 + <username>jwgl_dw</username>
  91 + <password>Encrypted 2be98afc86aa7f2e4cb13b977d2adabcd</password>
  92 + <servername/>
  93 + <data_tablespace/>
  94 + <index_tablespace/>
  95 + <attributes>
  96 + <attribute><code>FORCE_IDENTIFIERS_TO_LOWERCASE</code><attribute>N</attribute></attribute>
  97 + <attribute><code>FORCE_IDENTIFIERS_TO_UPPERCASE</code><attribute>N</attribute></attribute>
  98 + <attribute><code>IS_CLUSTERED</code><attribute>N</attribute></attribute>
  99 + <attribute><code>PORT_NUMBER</code><attribute>1521</attribute></attribute>
  100 + <attribute><code>PRESERVE_RESERVED_WORD_CASE</code><attribute>N</attribute></attribute>
  101 + <attribute><code>QUOTE_ALL_FIELDS</code><attribute>N</attribute></attribute>
  102 + <attribute><code>SUPPORTS_BOOLEAN_DATA_TYPE</code><attribute>Y</attribute></attribute>
  103 + <attribute><code>SUPPORTS_TIMESTAMP_DATA_TYPE</code><attribute>Y</attribute></attribute>
  104 + <attribute><code>USE_POOLING</code><attribute>N</attribute></attribute>
  105 + </attributes>
  106 + </connection>
  107 + <connection>
84 108 <name>bus_control_variable</name>
85 109 <server>&#x24;&#x7b;v_db_ip&#x7d;</server>
86 110 <type>MYSQL</type>
... ... @@ -292,6 +316,11 @@
292 316 <format/>
293 317 </field>
294 318 <field>
  319 + <name>&#x8f66;&#x8f86;&#x7f16;&#x7801;</name>
  320 + <type>String</type>
  321 + <format/>
  322 + </field>
  323 + <field>
295 324 <name>&#x5185;&#x90e8;&#x7f16;&#x7801;</name>
296 325 <type>String</type>
297 326 <format/>
... ... @@ -317,6 +346,11 @@
317 346 <format/>
318 347 </field>
319 348 <field>
  349 + <name>&#x8bbe;&#x5907;&#x4f9b;&#x5e94;&#x5382;&#x5546;</name>
  350 + <type>String</type>
  351 + <format/>
  352 + </field>
  353 + <field>
320 354 <name>&#x8bbe;&#x5907;&#x7ec8;&#x7aef;&#x53f7;</name>
321 355 <type>String</type>
322 356 <format/>
... ... @@ -362,6 +396,10 @@
362 396 <rename>&#x8f66;&#x724c;&#x53f7;</rename>
363 397 <length>-2</length>
364 398 <precision>-2</precision>
  399 + </field> <field> <name>car_code</name>
  400 + <rename>&#x8f66;&#x8f86;&#x7f16;&#x7801;</rename>
  401 + <length>-2</length>
  402 + <precision>-2</precision>
365 403 </field> <field> <name>inside_code</name>
366 404 <rename>&#x5185;&#x90e8;&#x7f16;&#x7801;</rename>
367 405 <length>-2</length>
... ...
src/main/resources/fatso/handle_real_ctl.js
1   -/**
2   - * 处理线调文件
3   - */
4   -var fs = require('fs')
5   - , cheerio = require('cheerio')
6   - , minifier = require('./minifier')
7   - , crypto = require("crypto")
8   - , CleanCSS = require('clean-css')
9   - , UglifyJS = require("uglify-js");
10   -;
11   -
12   -//不参与的目录
13   -var pName = 'bsth_control'
14   - , path = process.cwd()
15   - //根目录
16   - , root = path.substr(0, path.indexOf('\\src\\main'))
17   - , workspace = root.substr(0, root.indexOf('\\' + pName))
18   - //临时目录
19   - , dest = (workspace + '\\' + pName + '@fatso_copy').replace(/\//g, '\\')
20   - , _static = '\\src\\main\\resources\\static';
21   -
22   -
23   -var mainFile = dest + _static + '\\real_control_v2\\main.html';
24   -var mapFile = dest + _static + '\\real_control_v2\\mapmonitor\\real.html';
25   -var realCtl = {
26   - /**
27   - * 处理线调首页
28   - */
29   - handleMain: function (cb) {
30   - //读取文件
31   - var data = fs.readFileSync(mainFile, 'utf-8')
32   - , $ = cheerio.load(data);
33   -
34   - handleCss($, function () {
35   - handleJs($, mainFile, cb);
36   - });
37   - },
38   - /**
39   - * 处理地图模块
40   - * @param cb
41   - */
42   - handleMap: function (cb) {
43   - //读取文件
44   - var data = fs.readFileSync(mapFile, 'utf-8')
45   - , $ = cheerio.load(data);
46   -
47   - handleCss($, function () {
48   - handleJs($, mapFile, cb);
49   - });
50   - }
51   -};
52   -
53   -/**
54   - * 处理css
55   - * @type {any}
56   - */
57   -var handleCss = function ($, cb) {
58   - var cssArray = $('link[rel=stylesheet][merge]');
59   - //按 merge 值分组
60   - var cssMap = {}, mergeName;
61   - for (var i = 0, c; c = cssArray[i++];) {
62   - mergeName = $(c).attr('merge');
63   - if (!cssMap[mergeName])
64   - cssMap[mergeName] = [];
65   - cssMap[mergeName].push(dest + _static + $(c).attr('href'));
66   - //remove
67   - $(c).remove();
68   - }
69   - //按 merge 合并压缩css
70   - var ks = get_keys(cssMap), index = 0;
71   - (function () {
72   - if (index >= ks.length) {
73   - cb && cb();
74   - return;
75   - }
76   - var k = ks[index];
77   - index++;
78   - var f = arguments.callee;
79   - //合并css
80   - new CleanCSS().minify(cssMap[k], function (error, out) {
81   - var data = out.styles;
82   - var fName = (k + '_' + md5(data)) + '.css';
83   - //写入 assets css 目录下
84   - var descFile = dest + _static + '\\real_control_v2\\assets\\css\\' + fName;
85   - fs.open(descFile, 'a', function (err, fd) {
86   -
87   - fs.write(fd, data, function () {
88   - var tag = '<link rel="stylesheet" href="/real_control_v2/assets/css/' + fName + '"/>';
89   - if ($('head').length > 0)
90   - $('head').append(tag);
91   - else {
92   - if($('link').length > 0)
93   - $('link').last().before(tag);
94   - else
95   - $('div').first().before(tag);
96   - }
97   - console.log(k + ' css', '结束,下一个');
98   - f();
99   - });
100   - });
101   - });
102   - })();
103   -};
104   -
105   -/**
106   - * 处理js
107   - */
108   -var handleJs = function ($, file, cb) {
109   - var scriptArray = $('script[merge]');
110   - //按 merge 值分组
111   - var jsMap = {}, mergeName;
112   - for (var i = 0, s; s = scriptArray[i++];) {
113   - mergeName = $(s).attr('merge');
114   - if (!jsMap[mergeName])
115   - jsMap[mergeName] = [];
116   - jsMap[mergeName].push(dest + _static + $(s).attr('src'));
117   - //remove
118   - $(s).remove();
119   - }
120   -
121   - //按 merge 合并压缩js
122   - var ks = get_keys(jsMap), index = 0;
123   - (function () {
124   - if (index >= ks.length) {
125   - write(file, $.html());
126   - console.log(file + ' 结束'.green);
127   - cb && cb();
128   - return;
129   - }
130   - var k = ks[index];
131   - index++;
132   - var f = arguments.callee;
133   - //合并压缩js
134   - var result = UglifyJS.minify(jsMap[k]);
135   - var data = result.code;
136   - var fName = (k + '_' + md5(data)) + '.js';
137   - //写入 assets js 目录下
138   - var descFile = dest + _static + '\\real_control_v2\\assets\\js\\' + fName;
139   - fs.open(descFile, 'a', function (err, fd) {
140   -
141   - fs.write(fd, data, function () {
142   - var tag = '<script src="/real_control_v2/assets/js/' + fName + '"></script>';
143   - if ($('body').length > 0)
144   - $('body').append(tag);
145   - else {
146   - //没有body 就写在尾部
147   - $('*').last().after(tag);
148   - }
149   - console.log(k + ' js', '结束,下一个');
150   - f();
151   - });
152   - });
153   - })();
154   -};
155   -
156   -var get_keys = function (json) {
157   - var array = [];
158   - for (var key in json) {
159   - array.push(key);
160   - }
161   - return array;
162   -};
163   -
164   -function md5(text) {
165   - return crypto.createHash("md5").update(text).digest("hex");
166   -}
167   -
168   -function write(file, text) {
169   - fs.writeFile(file, text, function (err) {
170   - if (err) {
171   - console.log(err.toString().red);
172   - process.exit();
173   - }
174   - console.log(file.green);
175   - });
176   -}
177   -
  1 +/**
  2 + * 处理线调文件
  3 + */
  4 +var fs = require('fs')
  5 + , cheerio = require('cheerio')
  6 + , minifier = require('./minifier')
  7 + , crypto = require("crypto")
  8 + , CleanCSS = require('clean-css')
  9 + , UglifyJS = require("uglify-js");
  10 +;
  11 +
  12 +//不参与的目录
  13 +var pName = 'bsth_control'
  14 + , path = process.cwd()
  15 + //根目录
  16 + , root = path.substr(0, path.indexOf('\\src\\main'))
  17 + , workspace = root.substr(0, root.indexOf('\\' + pName))
  18 + //临时目录
  19 + , dest = (workspace + '\\' + pName + '@fatso_copy').replace(/\//g, '\\')
  20 + , _static = '\\src\\main\\resources\\static';
  21 +
  22 +
  23 +var mainFile = dest + _static + '\\real_control_v2\\main.html';
  24 +var mapFile = dest + _static + '\\real_control_v2\\mapmonitor\\real.html';
  25 +var realCtl = {
  26 + /**
  27 + * 处理线调首页
  28 + */
  29 + handleMain: function (cb) {
  30 + //读取文件
  31 + var data = fs.readFileSync(mainFile, 'utf-8')
  32 + , $ = cheerio.load(data);
  33 +
  34 + handleCss($, function () {
  35 + handleJs($, mainFile, cb);
  36 + });
  37 + },
  38 + /**
  39 + * 处理地图模块
  40 + * @param cb
  41 + */
  42 + handleMap: function (cb) {
  43 + //读取文件
  44 + var data = fs.readFileSync(mapFile, 'utf-8')
  45 + , $ = cheerio.load(data);
  46 +
  47 + handleCss($, function () {
  48 + handleJs($, mapFile, cb);
  49 + });
  50 + }
  51 +};
  52 +
  53 +/**
  54 + * 处理css
  55 + * @type {any}
  56 + */
  57 +var handleCss = function ($, cb) {
  58 + var cssArray = $('link[rel=stylesheet][merge]');
  59 + //按 merge 值分组
  60 + var cssMap = {}, mergeName;
  61 + for (var i = 0, c; c = cssArray[i++];) {
  62 + mergeName = $(c).attr('merge');
  63 + if (!cssMap[mergeName])
  64 + cssMap[mergeName] = [];
  65 + cssMap[mergeName].push(dest + _static + $(c).attr('href'));
  66 + //remove
  67 + $(c).remove();
  68 + }
  69 + //按 merge 合并压缩css
  70 + var ks = get_keys(cssMap), index = 0;
  71 + (function () {
  72 + if (index >= ks.length) {
  73 + cb && cb();
  74 + return;
  75 + }
  76 + var k = ks[index];
  77 + index++;
  78 + var f = arguments.callee;
  79 + //合并css
  80 + new CleanCSS().minify(cssMap[k], function (error, out) {
  81 + var data = out.styles;
  82 + var fName = (k + '_' + md5(data)) + '.css';
  83 + //写入 assets css 目录下
  84 + var descFile = dest + _static + '\\real_control_v2\\assets\\css\\' + fName;
  85 + fs.open(descFile, 'a', function (err, fd) {
  86 +
  87 + fs.write(fd, data, function () {
  88 + var tag = '<link rel="stylesheet" href="/real_control_v2/assets/css/' + fName + '"/>';
  89 + if ($('head').length > 0)
  90 + $('head').append(tag);
  91 + else {
  92 + if($('link').length > 0)
  93 + $('link').last().before(tag);
  94 + else
  95 + $('div').first().before(tag);
  96 + }
  97 + console.log(k + ' css', '结束,下一个');
  98 + f();
  99 + });
  100 + });
  101 + });
  102 + })();
  103 +};
  104 +
  105 +/**
  106 + * 处理js
  107 + */
  108 +var handleJs = function ($, file, cb) {
  109 + var scriptArray = $('script[merge]');
  110 + //按 merge 值分组
  111 + var jsMap = {}, mergeName;
  112 + for (var i = 0, s; s = scriptArray[i++];) {
  113 + mergeName = $(s).attr('merge');
  114 + if (!jsMap[mergeName])
  115 + jsMap[mergeName] = [];
  116 + jsMap[mergeName].push(dest + _static + $(s).attr('src'));
  117 + //remove
  118 + $(s).remove();
  119 + }
  120 +
  121 + //按 merge 合并压缩js
  122 + var ks = get_keys(jsMap), index = 0;
  123 + (function () {
  124 + if (index >= ks.length) {
  125 + write(file, $.html());
  126 + console.log(file + ' 结束'.green);
  127 + cb && cb();
  128 + return;
  129 + }
  130 + var k = ks[index];
  131 + index++;
  132 + var f = arguments.callee;
  133 + //合并压缩js
  134 + var result = UglifyJS.minify(jsMap[k]);
  135 + var data = result.code;
  136 + var fName = (k + '_' + md5(data)) + '.js';
  137 + //写入 assets js 目录下
  138 + var descFile = dest + _static + '\\real_control_v2\\assets\\js\\' + fName;
  139 + fs.open(descFile, 'a', function (err, fd) {
  140 +
  141 + fs.write(fd, data, function () {
  142 + var tag = '<script src="/real_control_v2/assets/js/' + fName + '"></script>';
  143 + if ($('body').length > 0)
  144 + $('body').append(tag);
  145 + else {
  146 + //没有body 就写在尾部
  147 + $('*').last().after(tag);
  148 + }
  149 + console.log(k + ' js', '结束,下一个');
  150 + f();
  151 + });
  152 + });
  153 + })();
  154 +};
  155 +
  156 +var get_keys = function (json) {
  157 + var array = [];
  158 + for (var key in json) {
  159 + array.push(key);
  160 + }
  161 + return array;
  162 +};
  163 +
  164 +function md5(text) {
  165 + return crypto.createHash("md5").update(text).digest("hex");
  166 +}
  167 +
  168 +function write(file, text) {
  169 + fs.writeFile(file, text, function (err) {
  170 + if (err) {
  171 + console.log(err.toString().red);
  172 + process.exit();
  173 + }
  174 + console.log(file.green);
  175 + });
  176 +}
  177 +
178 178 module.exports = realCtl;
179 179 \ No newline at end of file
... ...
src/main/resources/static/pages/forms/statement/jobSummary.html
... ... @@ -277,6 +277,27 @@
277 277 initPinYinSelect2('#line',data,'');
278 278  
279 279 }) */
  280 +
  281 + jQuery.fn.rowspan = function(colIdx) { //封装的一个JQuery小插件
  282 + return this.each(function(){
  283 + var that;
  284 + $('tr', this).each(function(row) {
  285 + $('td:eq('+colIdx+')', this).filter(':visible').each(function(col) {
  286 + if (that!=null && $(this).html() == $(that).html()) {
  287 + rowspan = $(that).attr("rowSpan");
  288 + if (rowspan == undefined) {
  289 + $(that).attr("rowSpan",1);
  290 + rowspan = $(that).attr("rowSpan"); }
  291 + rowspan = Number(rowspan)+1;
  292 + $(that).attr("rowSpan",rowspan);
  293 + $(this).hide();
  294 + } else {
  295 + that = this;
  296 + }
  297 + });
  298 + });
  299 + });
  300 + }
280 301 $("#query").on("click",function(){
281 302 var line=$("#line").val();;
282 303 var lineName=$(".select2-selection__rendered").html();
... ... @@ -292,6 +313,11 @@
292 313 var list_lbqk = template('list_lbqk',{list:result});
293 314 // 把渲染好的模版html文本追加到表格中
294 315 $('#forms .list_lbqk').html(list_lbqk);
  316 + $('#forms .list_lbqk').rowspan(0);
  317 + $('#forms .list_lbqk').rowspan(1);
  318 + $('#forms .list_lbqk').rowspan(2);
  319 + $('#forms .list_lbqk').rowspan(3);
  320 +
295 321 })
296 322  
297 323 $get('/report/jobLjqk',{line:line,date:date},function(result){
... ... @@ -328,13 +354,19 @@
328 354 <td>{{obj.nr}}</td>
329 355 <td>{{obj.lp}}</td>
330 356 <td>{{obj.nbbm}}</td>
331   - <td>{{obj.jgh}}</td>
  357 + <td {{if obj.lx ==1}} colspan="2" {{/if}}>{{obj.jgh}}</td>
  358 + {{if obj.lx ==0}}
332 359 <td>{{obj.dz}}</td>
333   - <td>{{obj.sj}}</td>
  360 + {{/if}}
  361 + <td {{if obj.lx ==1}} colspan="3" {{/if}}>{{obj.sj}}</td>
  362 + {{if obj.lx ==0}}
334 363 <td>&nbsp;</td>
335 364 <td>{{obj.lbbc}}</td>
336   - <td>{{obj.lblc}}</td>
  365 + {{/if}}
  366 + <td {{if obj.lx ==1}} colspan="2" {{/if}}>{{obj.lblc}}</td>
  367 + {{if obj.lx ==0}}
337 368 <td>{{obj.jyqp}}</td>
  369 + {{/if}}
338 370 </tr>
339 371 {{/each}}
340 372 {{if list.length == 0}}
... ...
src/main/resources/static/pages/forms/statement/scheduleDaily.html
... ... @@ -551,7 +551,7 @@ letter-spacing: 20px;
551 551 <td>{{obj.fast}}</td>
552 552 <td>{{obj.slow}}</td>
553 553 <td>{{obj.fcsj}}</td>
554   - <td>{{obj.fcsjActual}}
  554 + <td style="word-break: keep-all;white-space:nowrap;">{{obj.fcsjActual}}
555 555 {{if obj.bcType== "in"}}
556 556 (进)
557 557 {{/if}}
... ...
src/main/resources/static/pages/mforms/shifdays/shifday.html
... ... @@ -71,7 +71,7 @@
71 71 <th>车辆</th>
72 72 <th>计划里程</th>
73 73 <th>实际计划里程</th>
74   - <th>运营</th>
  74 + <th>运营里程</th>
75 75 <th>空驶里程</th>
76 76 <th>抽减里程</th>
77 77 <th>增加里程</th>
... ...
src/main/resources/static/pages/scheduleApp/module/core/busConfig/module.js
... ... @@ -126,8 +126,9 @@ angular.module(&#39;ScheduleApp&#39;).controller(
126 126  
127 127 // 导出excel
128 128 self.exportData = function() {
129   - if (busConfigService.dataExport()) {
130   - busConfigService.dataExport().then(
  129 + var p = busConfigService.dataExport();
  130 + if (p) {
  131 + p.then(
131 132 function(result) {
132 133 fileDownload.downloadFile(result.data, "application/octet-stream", "车辆配置信息.xls");
133 134 },
... ...
src/main/resources/static/pages/scheduleApp/module/core/employeeConfig/module.js
... ... @@ -127,8 +127,9 @@ angular.module(&#39;ScheduleApp&#39;).controller(
127 127  
128 128 // 导出excel
129 129 self.exportData = function() {
130   - if (service.dataExport()) {
131   - service.dataExport().then(
  130 + var p = service.dataExport();
  131 + if (p) {
  132 + p.then(
132 133 function(result) {
133 134 fileDownload.downloadFile(result.data, "application/octet-stream", "人员配置信息.xls");
134 135 },
... ...
src/main/resources/static/pages/scheduleApp/module/core/guideboardManage/module.js
... ... @@ -131,8 +131,9 @@ angular.module(&#39;ScheduleApp&#39;).controller(
131 131  
132 132 // 导出excel
133 133 self.exportData = function() {
134   - if (service.dataExport()) {
135   - service.dataExport().then(
  134 + var p = service.dataExport();
  135 + if (p) {
  136 + p.then(
136 137 function(result) {
137 138 fileDownload.downloadFile(result.data, "application/octet-stream", "路牌信息.xls");
138 139 },
... ...
src/main/resources/static/real_control_v2/assets/plugins/perfect-scrollbar/perfect-scrollbar.css 0 → 100644
  1 +/* perfect-scrollbar v0.6.16 */
  2 +.ps-container {
  3 + -ms-touch-action: auto;
  4 + touch-action: auto;
  5 + overflow: hidden !important;
  6 + -ms-overflow-style: none; }
  7 + @supports (-ms-overflow-style: none) {
  8 + .ps-container {
  9 + overflow: auto !important; } }
  10 + @media screen and (-ms-high-contrast: active), (-ms-high-contrast: none) {
  11 + .ps-container {
  12 + overflow: auto !important; } }
  13 + .ps-container.ps-active-x > .ps-scrollbar-x-rail,
  14 + .ps-container.ps-active-y > .ps-scrollbar-y-rail {
  15 + display: block;
  16 + background-color: transparent; }
  17 + .ps-container.ps-in-scrolling.ps-x > .ps-scrollbar-x-rail {
  18 + background-color: #eee;
  19 + opacity: 0.9; }
  20 + .ps-container.ps-in-scrolling.ps-x > .ps-scrollbar-x-rail > .ps-scrollbar-x {
  21 + background-color: #999;
  22 + height: 11px; }
  23 + .ps-container.ps-in-scrolling.ps-y > .ps-scrollbar-y-rail {
  24 + background-color: #eee;
  25 + opacity: 0.9; }
  26 + .ps-container.ps-in-scrolling.ps-y > .ps-scrollbar-y-rail > .ps-scrollbar-y {
  27 + background-color: #999;
  28 + width: 11px; }
  29 + .ps-container > .ps-scrollbar-x-rail {
  30 + display: none;
  31 + position: absolute;
  32 + /* please don't change 'position' */
  33 + opacity: 0;
  34 + -webkit-transition: background-color .2s linear, opacity .2s linear;
  35 + -o-transition: background-color .2s linear, opacity .2s linear;
  36 + -moz-transition: background-color .2s linear, opacity .2s linear;
  37 + transition: background-color .2s linear, opacity .2s linear;
  38 + bottom: 0px;
  39 + /* there must be 'bottom' for ps-scrollbar-x-rail */
  40 + height: 15px; }
  41 + .ps-container > .ps-scrollbar-x-rail > .ps-scrollbar-x {
  42 + position: absolute;
  43 + /* please don't change 'position' */
  44 + background-color: #aaa;
  45 + -webkit-border-radius: 6px;
  46 + -moz-border-radius: 6px;
  47 + border-radius: 6px;
  48 + -webkit-transition: background-color .2s linear, height .2s linear, width .2s ease-in-out, -webkit-border-radius .2s ease-in-out;
  49 + transition: background-color .2s linear, height .2s linear, width .2s ease-in-out, -webkit-border-radius .2s ease-in-out;
  50 + -o-transition: background-color .2s linear, height .2s linear, width .2s ease-in-out, border-radius .2s ease-in-out;
  51 + -moz-transition: background-color .2s linear, height .2s linear, width .2s ease-in-out, border-radius .2s ease-in-out, -moz-border-radius .2s ease-in-out;
  52 + transition: background-color .2s linear, height .2s linear, width .2s ease-in-out, border-radius .2s ease-in-out;
  53 + transition: background-color .2s linear, height .2s linear, width .2s ease-in-out, border-radius .2s ease-in-out, -webkit-border-radius .2s ease-in-out, -moz-border-radius .2s ease-in-out;
  54 + bottom: 2px;
  55 + /* there must be 'bottom' for ps-scrollbar-x */
  56 + height: 6px; }
  57 + .ps-container > .ps-scrollbar-x-rail:hover > .ps-scrollbar-x, .ps-container > .ps-scrollbar-x-rail:active > .ps-scrollbar-x {
  58 + height: 11px; }
  59 + .ps-container > .ps-scrollbar-y-rail {
  60 + display: none;
  61 + position: absolute;
  62 + /* please don't change 'position' */
  63 + opacity: 0;
  64 + -webkit-transition: background-color .2s linear, opacity .2s linear;
  65 + -o-transition: background-color .2s linear, opacity .2s linear;
  66 + -moz-transition: background-color .2s linear, opacity .2s linear;
  67 + transition: background-color .2s linear, opacity .2s linear;
  68 + right: 0;
  69 + /* there must be 'right' for ps-scrollbar-y-rail */
  70 + width: 15px; }
  71 + .ps-container > .ps-scrollbar-y-rail > .ps-scrollbar-y {
  72 + position: absolute;
  73 + /* please don't change 'position' */
  74 + background-color: #aaa;
  75 + -webkit-border-radius: 6px;
  76 + -moz-border-radius: 6px;
  77 + border-radius: 6px;
  78 + -webkit-transition: background-color .2s linear, height .2s linear, width .2s ease-in-out, -webkit-border-radius .2s ease-in-out;
  79 + transition: background-color .2s linear, height .2s linear, width .2s ease-in-out, -webkit-border-radius .2s ease-in-out;
  80 + -o-transition: background-color .2s linear, height .2s linear, width .2s ease-in-out, border-radius .2s ease-in-out;
  81 + -moz-transition: background-color .2s linear, height .2s linear, width .2s ease-in-out, border-radius .2s ease-in-out, -moz-border-radius .2s ease-in-out;
  82 + transition: background-color .2s linear, height .2s linear, width .2s ease-in-out, border-radius .2s ease-in-out;
  83 + transition: background-color .2s linear, height .2s linear, width .2s ease-in-out, border-radius .2s ease-in-out, -webkit-border-radius .2s ease-in-out, -moz-border-radius .2s ease-in-out;
  84 + right: 2px;
  85 + /* there must be 'right' for ps-scrollbar-y */
  86 + width: 6px; }
  87 + .ps-container > .ps-scrollbar-y-rail:hover > .ps-scrollbar-y, .ps-container > .ps-scrollbar-y-rail:active > .ps-scrollbar-y {
  88 + width: 11px; }
  89 + .ps-container:hover.ps-in-scrolling.ps-x > .ps-scrollbar-x-rail {
  90 + background-color: #eee;
  91 + opacity: 0.9; }
  92 + .ps-container:hover.ps-in-scrolling.ps-x > .ps-scrollbar-x-rail > .ps-scrollbar-x {
  93 + background-color: #999;
  94 + height: 11px; }
  95 + .ps-container:hover.ps-in-scrolling.ps-y > .ps-scrollbar-y-rail {
  96 + background-color: #eee;
  97 + opacity: 0.9; }
  98 + .ps-container:hover.ps-in-scrolling.ps-y > .ps-scrollbar-y-rail > .ps-scrollbar-y {
  99 + background-color: #999;
  100 + width: 11px; }
  101 + .ps-container:hover > .ps-scrollbar-x-rail,
  102 + .ps-container:hover > .ps-scrollbar-y-rail {
  103 + opacity: 0.6; }
  104 + .ps-container:hover > .ps-scrollbar-x-rail:hover {
  105 + background-color: #eee;
  106 + opacity: 0.9; }
  107 + .ps-container:hover > .ps-scrollbar-x-rail:hover > .ps-scrollbar-x {
  108 + background-color: #999; }
  109 + .ps-container:hover > .ps-scrollbar-y-rail:hover {
  110 + background-color: #eee;
  111 + opacity: 0.9; }
  112 + .ps-container:hover > .ps-scrollbar-y-rail:hover > .ps-scrollbar-y {
  113 + background-color: #999; }
... ...
src/main/resources/static/real_control_v2/assets/plugins/perfect-scrollbar/perfect-scrollbar.jquery.js 0 → 100644
  1 +/* perfect-scrollbar v0.6.16 */
  2 +(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
  3 +'use strict';
  4 +
  5 +var ps = require('../main');
  6 +var psInstances = require('../plugin/instances');
  7 +
  8 +function mountJQuery(jQuery) {
  9 + jQuery.fn.perfectScrollbar = function (settingOrCommand) {
  10 + return this.each(function () {
  11 + if (typeof settingOrCommand === 'object' ||
  12 + typeof settingOrCommand === 'undefined') {
  13 + // If it's an object or none, initialize.
  14 + var settings = settingOrCommand;
  15 +
  16 + if (!psInstances.get(this)) {
  17 + ps.initialize(this, settings);
  18 + }
  19 + } else {
  20 + // Unless, it may be a command.
  21 + var command = settingOrCommand;
  22 +
  23 + if (command === 'update') {
  24 + ps.update(this);
  25 + } else if (command === 'destroy') {
  26 + ps.destroy(this);
  27 + }
  28 + }
  29 + });
  30 + };
  31 +}
  32 +
  33 +if (typeof define === 'function' && define.amd) {
  34 + // AMD. Register as an anonymous module.
  35 + define(['jquery'], mountJQuery);
  36 +} else {
  37 + var jq = window.jQuery ? window.jQuery : window.$;
  38 + if (typeof jq !== 'undefined') {
  39 + mountJQuery(jq);
  40 + }
  41 +}
  42 +
  43 +module.exports = mountJQuery;
  44 +
  45 +},{"../main":7,"../plugin/instances":18}],2:[function(require,module,exports){
  46 +'use strict';
  47 +
  48 +function oldAdd(element, className) {
  49 + var classes = element.className.split(' ');
  50 + if (classes.indexOf(className) < 0) {
  51 + classes.push(className);
  52 + }
  53 + element.className = classes.join(' ');
  54 +}
  55 +
  56 +function oldRemove(element, className) {
  57 + var classes = element.className.split(' ');
  58 + var idx = classes.indexOf(className);
  59 + if (idx >= 0) {
  60 + classes.splice(idx, 1);
  61 + }
  62 + element.className = classes.join(' ');
  63 +}
  64 +
  65 +exports.add = function (element, className) {
  66 + if (element.classList) {
  67 + element.classList.add(className);
  68 + } else {
  69 + oldAdd(element, className);
  70 + }
  71 +};
  72 +
  73 +exports.remove = function (element, className) {
  74 + if (element.classList) {
  75 + element.classList.remove(className);
  76 + } else {
  77 + oldRemove(element, className);
  78 + }
  79 +};
  80 +
  81 +exports.list = function (element) {
  82 + if (element.classList) {
  83 + return Array.prototype.slice.apply(element.classList);
  84 + } else {
  85 + return element.className.split(' ');
  86 + }
  87 +};
  88 +
  89 +},{}],3:[function(require,module,exports){
  90 +'use strict';
  91 +
  92 +var DOM = {};
  93 +
  94 +DOM.e = function (tagName, className) {
  95 + var element = document.createElement(tagName);
  96 + element.className = className;
  97 + return element;
  98 +};
  99 +
  100 +DOM.appendTo = function (child, parent) {
  101 + parent.appendChild(child);
  102 + return child;
  103 +};
  104 +
  105 +function cssGet(element, styleName) {
  106 + return window.getComputedStyle(element)[styleName];
  107 +}
  108 +
  109 +function cssSet(element, styleName, styleValue) {
  110 + if (typeof styleValue === 'number') {
  111 + styleValue = styleValue.toString() + 'px';
  112 + }
  113 + element.style[styleName] = styleValue;
  114 + return element;
  115 +}
  116 +
  117 +function cssMultiSet(element, obj) {
  118 + for (var key in obj) {
  119 + var val = obj[key];
  120 + if (typeof val === 'number') {
  121 + val = val.toString() + 'px';
  122 + }
  123 + element.style[key] = val;
  124 + }
  125 + return element;
  126 +}
  127 +
  128 +DOM.css = function (element, styleNameOrObject, styleValue) {
  129 + if (typeof styleNameOrObject === 'object') {
  130 + // multiple set with object
  131 + return cssMultiSet(element, styleNameOrObject);
  132 + } else {
  133 + if (typeof styleValue === 'undefined') {
  134 + return cssGet(element, styleNameOrObject);
  135 + } else {
  136 + return cssSet(element, styleNameOrObject, styleValue);
  137 + }
  138 + }
  139 +};
  140 +
  141 +DOM.matches = function (element, query) {
  142 + if (typeof element.matches !== 'undefined') {
  143 + return element.matches(query);
  144 + } else {
  145 + if (typeof element.matchesSelector !== 'undefined') {
  146 + return element.matchesSelector(query);
  147 + } else if (typeof element.webkitMatchesSelector !== 'undefined') {
  148 + return element.webkitMatchesSelector(query);
  149 + } else if (typeof element.mozMatchesSelector !== 'undefined') {
  150 + return element.mozMatchesSelector(query);
  151 + } else if (typeof element.msMatchesSelector !== 'undefined') {
  152 + return element.msMatchesSelector(query);
  153 + }
  154 + }
  155 +};
  156 +
  157 +DOM.remove = function (element) {
  158 + if (typeof element.remove !== 'undefined') {
  159 + element.remove();
  160 + } else {
  161 + if (element.parentNode) {
  162 + element.parentNode.removeChild(element);
  163 + }
  164 + }
  165 +};
  166 +
  167 +DOM.queryChildren = function (element, selector) {
  168 + return Array.prototype.filter.call(element.childNodes, function (child) {
  169 + return DOM.matches(child, selector);
  170 + });
  171 +};
  172 +
  173 +module.exports = DOM;
  174 +
  175 +},{}],4:[function(require,module,exports){
  176 +'use strict';
  177 +
  178 +var EventElement = function (element) {
  179 + this.element = element;
  180 + this.events = {};
  181 +};
  182 +
  183 +EventElement.prototype.bind = function (eventName, handler) {
  184 + if (typeof this.events[eventName] === 'undefined') {
  185 + this.events[eventName] = [];
  186 + }
  187 + this.events[eventName].push(handler);
  188 + this.element.addEventListener(eventName, handler, false);
  189 +};
  190 +
  191 +EventElement.prototype.unbind = function (eventName, handler) {
  192 + var isHandlerProvided = (typeof handler !== 'undefined');
  193 + this.events[eventName] = this.events[eventName].filter(function (hdlr) {
  194 + if (isHandlerProvided && hdlr !== handler) {
  195 + return true;
  196 + }
  197 + this.element.removeEventListener(eventName, hdlr, false);
  198 + return false;
  199 + }, this);
  200 +};
  201 +
  202 +EventElement.prototype.unbindAll = function () {
  203 + for (var name in this.events) {
  204 + this.unbind(name);
  205 + }
  206 +};
  207 +
  208 +var EventManager = function () {
  209 + this.eventElements = [];
  210 +};
  211 +
  212 +EventManager.prototype.eventElement = function (element) {
  213 + var ee = this.eventElements.filter(function (eventElement) {
  214 + return eventElement.element === element;
  215 + })[0];
  216 + if (typeof ee === 'undefined') {
  217 + ee = new EventElement(element);
  218 + this.eventElements.push(ee);
  219 + }
  220 + return ee;
  221 +};
  222 +
  223 +EventManager.prototype.bind = function (element, eventName, handler) {
  224 + this.eventElement(element).bind(eventName, handler);
  225 +};
  226 +
  227 +EventManager.prototype.unbind = function (element, eventName, handler) {
  228 + this.eventElement(element).unbind(eventName, handler);
  229 +};
  230 +
  231 +EventManager.prototype.unbindAll = function () {
  232 + for (var i = 0; i < this.eventElements.length; i++) {
  233 + this.eventElements[i].unbindAll();
  234 + }
  235 +};
  236 +
  237 +EventManager.prototype.once = function (element, eventName, handler) {
  238 + var ee = this.eventElement(element);
  239 + var onceHandler = function (e) {
  240 + ee.unbind(eventName, onceHandler);
  241 + handler(e);
  242 + };
  243 + ee.bind(eventName, onceHandler);
  244 +};
  245 +
  246 +module.exports = EventManager;
  247 +
  248 +},{}],5:[function(require,module,exports){
  249 +'use strict';
  250 +
  251 +module.exports = (function () {
  252 + function s4() {
  253 + return Math.floor((1 + Math.random()) * 0x10000)
  254 + .toString(16)
  255 + .substring(1);
  256 + }
  257 + return function () {
  258 + return s4() + s4() + '-' + s4() + '-' + s4() + '-' +
  259 + s4() + '-' + s4() + s4() + s4();
  260 + };
  261 +})();
  262 +
  263 +},{}],6:[function(require,module,exports){
  264 +'use strict';
  265 +
  266 +var cls = require('./class');
  267 +var dom = require('./dom');
  268 +
  269 +var toInt = exports.toInt = function (x) {
  270 + return parseInt(x, 10) || 0;
  271 +};
  272 +
  273 +var clone = exports.clone = function (obj) {
  274 + if (!obj) {
  275 + return null;
  276 + } else if (obj.constructor === Array) {
  277 + return obj.map(clone);
  278 + } else if (typeof obj === 'object') {
  279 + var result = {};
  280 + for (var key in obj) {
  281 + result[key] = clone(obj[key]);
  282 + }
  283 + return result;
  284 + } else {
  285 + return obj;
  286 + }
  287 +};
  288 +
  289 +exports.extend = function (original, source) {
  290 + var result = clone(original);
  291 + for (var key in source) {
  292 + result[key] = clone(source[key]);
  293 + }
  294 + return result;
  295 +};
  296 +
  297 +exports.isEditable = function (el) {
  298 + return dom.matches(el, "input,[contenteditable]") ||
  299 + dom.matches(el, "select,[contenteditable]") ||
  300 + dom.matches(el, "textarea,[contenteditable]") ||
  301 + dom.matches(el, "button,[contenteditable]");
  302 +};
  303 +
  304 +exports.removePsClasses = function (element) {
  305 + var clsList = cls.list(element);
  306 + for (var i = 0; i < clsList.length; i++) {
  307 + var className = clsList[i];
  308 + if (className.indexOf('ps-') === 0) {
  309 + cls.remove(element, className);
  310 + }
  311 + }
  312 +};
  313 +
  314 +exports.outerWidth = function (element) {
  315 + return toInt(dom.css(element, 'width')) +
  316 + toInt(dom.css(element, 'paddingLeft')) +
  317 + toInt(dom.css(element, 'paddingRight')) +
  318 + toInt(dom.css(element, 'borderLeftWidth')) +
  319 + toInt(dom.css(element, 'borderRightWidth'));
  320 +};
  321 +
  322 +exports.startScrolling = function (element, axis) {
  323 + cls.add(element, 'ps-in-scrolling');
  324 + if (typeof axis !== 'undefined') {
  325 + cls.add(element, 'ps-' + axis);
  326 + } else {
  327 + cls.add(element, 'ps-x');
  328 + cls.add(element, 'ps-y');
  329 + }
  330 +};
  331 +
  332 +exports.stopScrolling = function (element, axis) {
  333 + cls.remove(element, 'ps-in-scrolling');
  334 + if (typeof axis !== 'undefined') {
  335 + cls.remove(element, 'ps-' + axis);
  336 + } else {
  337 + cls.remove(element, 'ps-x');
  338 + cls.remove(element, 'ps-y');
  339 + }
  340 +};
  341 +
  342 +exports.env = {
  343 + isWebKit: 'WebkitAppearance' in document.documentElement.style,
  344 + supportsTouch: (('ontouchstart' in window) || window.DocumentTouch && document instanceof window.DocumentTouch),
  345 + supportsIePointer: window.navigator.msMaxTouchPoints !== null
  346 +};
  347 +
  348 +},{"./class":2,"./dom":3}],7:[function(require,module,exports){
  349 +'use strict';
  350 +
  351 +var destroy = require('./plugin/destroy');
  352 +var initialize = require('./plugin/initialize');
  353 +var update = require('./plugin/update');
  354 +
  355 +module.exports = {
  356 + initialize: initialize,
  357 + update: update,
  358 + destroy: destroy
  359 +};
  360 +
  361 +},{"./plugin/destroy":9,"./plugin/initialize":17,"./plugin/update":21}],8:[function(require,module,exports){
  362 +'use strict';
  363 +
  364 +module.exports = {
  365 + handlers: ['click-rail', 'drag-scrollbar', 'keyboard', 'wheel', 'touch'],
  366 + maxScrollbarLength: null,
  367 + minScrollbarLength: null,
  368 + scrollXMarginOffset: 0,
  369 + scrollYMarginOffset: 0,
  370 + suppressScrollX: false,
  371 + suppressScrollY: false,
  372 + swipePropagation: true,
  373 + useBothWheelAxes: false,
  374 + wheelPropagation: false,
  375 + wheelSpeed: 1,
  376 + theme: 'default'
  377 +};
  378 +
  379 +},{}],9:[function(require,module,exports){
  380 +'use strict';
  381 +
  382 +var _ = require('../lib/helper');
  383 +var dom = require('../lib/dom');
  384 +var instances = require('./instances');
  385 +
  386 +module.exports = function (element) {
  387 + var i = instances.get(element);
  388 +
  389 + if (!i) {
  390 + return;
  391 + }
  392 +
  393 + i.event.unbindAll();
  394 + dom.remove(i.scrollbarX);
  395 + dom.remove(i.scrollbarY);
  396 + dom.remove(i.scrollbarXRail);
  397 + dom.remove(i.scrollbarYRail);
  398 + _.removePsClasses(element);
  399 +
  400 + instances.remove(element);
  401 +};
  402 +
  403 +},{"../lib/dom":3,"../lib/helper":6,"./instances":18}],10:[function(require,module,exports){
  404 +'use strict';
  405 +
  406 +var instances = require('../instances');
  407 +var updateGeometry = require('../update-geometry');
  408 +var updateScroll = require('../update-scroll');
  409 +
  410 +function bindClickRailHandler(element, i) {
  411 + function pageOffset(el) {
  412 + return el.getBoundingClientRect();
  413 + }
  414 + var stopPropagation = function (e) { e.stopPropagation(); };
  415 +
  416 + i.event.bind(i.scrollbarY, 'click', stopPropagation);
  417 + i.event.bind(i.scrollbarYRail, 'click', function (e) {
  418 + var positionTop = e.pageY - window.pageYOffset - pageOffset(i.scrollbarYRail).top;
  419 + var direction = positionTop > i.scrollbarYTop ? 1 : -1;
  420 +
  421 + updateScroll(element, 'top', element.scrollTop + direction * i.containerHeight);
  422 + updateGeometry(element);
  423 +
  424 + e.stopPropagation();
  425 + });
  426 +
  427 + i.event.bind(i.scrollbarX, 'click', stopPropagation);
  428 + i.event.bind(i.scrollbarXRail, 'click', function (e) {
  429 + var positionLeft = e.pageX - window.pageXOffset - pageOffset(i.scrollbarXRail).left;
  430 + var direction = positionLeft > i.scrollbarXLeft ? 1 : -1;
  431 +
  432 + updateScroll(element, 'left', element.scrollLeft + direction * i.containerWidth);
  433 + updateGeometry(element);
  434 +
  435 + e.stopPropagation();
  436 + });
  437 +}
  438 +
  439 +module.exports = function (element) {
  440 + var i = instances.get(element);
  441 + bindClickRailHandler(element, i);
  442 +};
  443 +
  444 +},{"../instances":18,"../update-geometry":19,"../update-scroll":20}],11:[function(require,module,exports){
  445 +'use strict';
  446 +
  447 +var _ = require('../../lib/helper');
  448 +var dom = require('../../lib/dom');
  449 +var instances = require('../instances');
  450 +var updateGeometry = require('../update-geometry');
  451 +var updateScroll = require('../update-scroll');
  452 +
  453 +function bindMouseScrollXHandler(element, i) {
  454 + var currentLeft = null;
  455 + var currentPageX = null;
  456 +
  457 + function updateScrollLeft(deltaX) {
  458 + var newLeft = currentLeft + (deltaX * i.railXRatio);
  459 + var maxLeft = Math.max(0, i.scrollbarXRail.getBoundingClientRect().left) + (i.railXRatio * (i.railXWidth - i.scrollbarXWidth));
  460 +
  461 + if (newLeft < 0) {
  462 + i.scrollbarXLeft = 0;
  463 + } else if (newLeft > maxLeft) {
  464 + i.scrollbarXLeft = maxLeft;
  465 + } else {
  466 + i.scrollbarXLeft = newLeft;
  467 + }
  468 +
  469 + var scrollLeft = _.toInt(i.scrollbarXLeft * (i.contentWidth - i.containerWidth) / (i.containerWidth - (i.railXRatio * i.scrollbarXWidth))) - i.negativeScrollAdjustment;
  470 + updateScroll(element, 'left', scrollLeft);
  471 + }
  472 +
  473 + var mouseMoveHandler = function (e) {
  474 + updateScrollLeft(e.pageX - currentPageX);
  475 + updateGeometry(element);
  476 + e.stopPropagation();
  477 + e.preventDefault();
  478 + };
  479 +
  480 + var mouseUpHandler = function () {
  481 + _.stopScrolling(element, 'x');
  482 + i.event.unbind(i.ownerDocument, 'mousemove', mouseMoveHandler);
  483 + };
  484 +
  485 + i.event.bind(i.scrollbarX, 'mousedown', function (e) {
  486 + currentPageX = e.pageX;
  487 + currentLeft = _.toInt(dom.css(i.scrollbarX, 'left')) * i.railXRatio;
  488 + _.startScrolling(element, 'x');
  489 +
  490 + i.event.bind(i.ownerDocument, 'mousemove', mouseMoveHandler);
  491 + i.event.once(i.ownerDocument, 'mouseup', mouseUpHandler);
  492 +
  493 + e.stopPropagation();
  494 + e.preventDefault();
  495 + });
  496 +}
  497 +
  498 +function bindMouseScrollYHandler(element, i) {
  499 + var currentTop = null;
  500 + var currentPageY = null;
  501 +
  502 + function updateScrollTop(deltaY) {
  503 + var newTop = currentTop + (deltaY * i.railYRatio);
  504 + var maxTop = Math.max(0, i.scrollbarYRail.getBoundingClientRect().top) + (i.railYRatio * (i.railYHeight - i.scrollbarYHeight));
  505 +
  506 + if (newTop < 0) {
  507 + i.scrollbarYTop = 0;
  508 + } else if (newTop > maxTop) {
  509 + i.scrollbarYTop = maxTop;
  510 + } else {
  511 + i.scrollbarYTop = newTop;
  512 + }
  513 +
  514 + var scrollTop = _.toInt(i.scrollbarYTop * (i.contentHeight - i.containerHeight) / (i.containerHeight - (i.railYRatio * i.scrollbarYHeight)));
  515 + updateScroll(element, 'top', scrollTop);
  516 + }
  517 +
  518 + var mouseMoveHandler = function (e) {
  519 + updateScrollTop(e.pageY - currentPageY);
  520 + updateGeometry(element);
  521 + e.stopPropagation();
  522 + e.preventDefault();
  523 + };
  524 +
  525 + var mouseUpHandler = function () {
  526 + _.stopScrolling(element, 'y');
  527 + i.event.unbind(i.ownerDocument, 'mousemove', mouseMoveHandler);
  528 + };
  529 +
  530 + i.event.bind(i.scrollbarY, 'mousedown', function (e) {
  531 + currentPageY = e.pageY;
  532 + currentTop = _.toInt(dom.css(i.scrollbarY, 'top')) * i.railYRatio;
  533 + _.startScrolling(element, 'y');
  534 +
  535 + i.event.bind(i.ownerDocument, 'mousemove', mouseMoveHandler);
  536 + i.event.once(i.ownerDocument, 'mouseup', mouseUpHandler);
  537 +
  538 + e.stopPropagation();
  539 + e.preventDefault();
  540 + });
  541 +}
  542 +
  543 +module.exports = function (element) {
  544 + var i = instances.get(element);
  545 + bindMouseScrollXHandler(element, i);
  546 + bindMouseScrollYHandler(element, i);
  547 +};
  548 +
  549 +},{"../../lib/dom":3,"../../lib/helper":6,"../instances":18,"../update-geometry":19,"../update-scroll":20}],12:[function(require,module,exports){
  550 +'use strict';
  551 +
  552 +var _ = require('../../lib/helper');
  553 +var dom = require('../../lib/dom');
  554 +var instances = require('../instances');
  555 +var updateGeometry = require('../update-geometry');
  556 +var updateScroll = require('../update-scroll');
  557 +
  558 +function bindKeyboardHandler(element, i) {
  559 + var hovered = false;
  560 + i.event.bind(element, 'mouseenter', function () {
  561 + hovered = true;
  562 + });
  563 + i.event.bind(element, 'mouseleave', function () {
  564 + hovered = false;
  565 + });
  566 +
  567 + var shouldPrevent = false;
  568 + function shouldPreventDefault(deltaX, deltaY) {
  569 + var scrollTop = element.scrollTop;
  570 + if (deltaX === 0) {
  571 + if (!i.scrollbarYActive) {
  572 + return false;
  573 + }
  574 + if ((scrollTop === 0 && deltaY > 0) || (scrollTop >= i.contentHeight - i.containerHeight && deltaY < 0)) {
  575 + return !i.settings.wheelPropagation;
  576 + }
  577 + }
  578 +
  579 + var scrollLeft = element.scrollLeft;
  580 + if (deltaY === 0) {
  581 + if (!i.scrollbarXActive) {
  582 + return false;
  583 + }
  584 + if ((scrollLeft === 0 && deltaX < 0) || (scrollLeft >= i.contentWidth - i.containerWidth && deltaX > 0)) {
  585 + return !i.settings.wheelPropagation;
  586 + }
  587 + }
  588 + return true;
  589 + }
  590 +
  591 + i.event.bind(i.ownerDocument, 'keydown', function (e) {
  592 + if ((e.isDefaultPrevented && e.isDefaultPrevented()) || e.defaultPrevented) {
  593 + return;
  594 + }
  595 +
  596 + var focused = dom.matches(i.scrollbarX, ':focus') ||
  597 + dom.matches(i.scrollbarY, ':focus');
  598 +
  599 + if (!hovered && !focused) {
  600 + return;
  601 + }
  602 +
  603 + var activeElement = document.activeElement ? document.activeElement : i.ownerDocument.activeElement;
  604 + if (activeElement) {
  605 + if (activeElement.tagName === 'IFRAME') {
  606 + activeElement = activeElement.contentDocument.activeElement;
  607 + } else {
  608 + // go deeper if element is a webcomponent
  609 + while (activeElement.shadowRoot) {
  610 + activeElement = activeElement.shadowRoot.activeElement;
  611 + }
  612 + }
  613 + if (_.isEditable(activeElement)) {
  614 + return;
  615 + }
  616 + }
  617 +
  618 + var deltaX = 0;
  619 + var deltaY = 0;
  620 +
  621 + switch (e.which) {
  622 + case 37: // left
  623 + if (e.metaKey) {
  624 + deltaX = -i.contentWidth;
  625 + } else if (e.altKey) {
  626 + deltaX = -i.containerWidth;
  627 + } else {
  628 + deltaX = -30;
  629 + }
  630 + break;
  631 + case 38: // up
  632 + if (e.metaKey) {
  633 + deltaY = i.contentHeight;
  634 + } else if (e.altKey) {
  635 + deltaY = i.containerHeight;
  636 + } else {
  637 + deltaY = 30;
  638 + }
  639 + break;
  640 + case 39: // right
  641 + if (e.metaKey) {
  642 + deltaX = i.contentWidth;
  643 + } else if (e.altKey) {
  644 + deltaX = i.containerWidth;
  645 + } else {
  646 + deltaX = 30;
  647 + }
  648 + break;
  649 + case 40: // down
  650 + if (e.metaKey) {
  651 + deltaY = -i.contentHeight;
  652 + } else if (e.altKey) {
  653 + deltaY = -i.containerHeight;
  654 + } else {
  655 + deltaY = -30;
  656 + }
  657 + break;
  658 + case 33: // page up
  659 + deltaY = 90;
  660 + break;
  661 + case 32: // space bar
  662 + if (e.shiftKey) {
  663 + deltaY = 90;
  664 + } else {
  665 + deltaY = -90;
  666 + }
  667 + break;
  668 + case 34: // page down
  669 + deltaY = -90;
  670 + break;
  671 + case 35: // end
  672 + if (e.ctrlKey) {
  673 + deltaY = -i.contentHeight;
  674 + } else {
  675 + deltaY = -i.containerHeight;
  676 + }
  677 + break;
  678 + case 36: // home
  679 + if (e.ctrlKey) {
  680 + deltaY = element.scrollTop;
  681 + } else {
  682 + deltaY = i.containerHeight;
  683 + }
  684 + break;
  685 + default:
  686 + return;
  687 + }
  688 +
  689 + updateScroll(element, 'top', element.scrollTop - deltaY);
  690 + updateScroll(element, 'left', element.scrollLeft + deltaX);
  691 + updateGeometry(element);
  692 +
  693 + shouldPrevent = shouldPreventDefault(deltaX, deltaY);
  694 + if (shouldPrevent) {
  695 + e.preventDefault();
  696 + }
  697 + });
  698 +}
  699 +
  700 +module.exports = function (element) {
  701 + var i = instances.get(element);
  702 + bindKeyboardHandler(element, i);
  703 +};
  704 +
  705 +},{"../../lib/dom":3,"../../lib/helper":6,"../instances":18,"../update-geometry":19,"../update-scroll":20}],13:[function(require,module,exports){
  706 +'use strict';
  707 +
  708 +var instances = require('../instances');
  709 +var updateGeometry = require('../update-geometry');
  710 +var updateScroll = require('../update-scroll');
  711 +
  712 +function bindMouseWheelHandler(element, i) {
  713 + var shouldPrevent = false;
  714 +
  715 + function shouldPreventDefault(deltaX, deltaY) {
  716 + var scrollTop = element.scrollTop;
  717 + if (deltaX === 0) {
  718 + if (!i.scrollbarYActive) {
  719 + return false;
  720 + }
  721 + if ((scrollTop === 0 && deltaY > 0) || (scrollTop >= i.contentHeight - i.containerHeight && deltaY < 0)) {
  722 + return !i.settings.wheelPropagation;
  723 + }
  724 + }
  725 +
  726 + var scrollLeft = element.scrollLeft;
  727 + if (deltaY === 0) {
  728 + if (!i.scrollbarXActive) {
  729 + return false;
  730 + }
  731 + if ((scrollLeft === 0 && deltaX < 0) || (scrollLeft >= i.contentWidth - i.containerWidth && deltaX > 0)) {
  732 + return !i.settings.wheelPropagation;
  733 + }
  734 + }
  735 + return true;
  736 + }
  737 +
  738 + function getDeltaFromEvent(e) {
  739 + var deltaX = e.deltaX;
  740 + var deltaY = -1 * e.deltaY;
  741 +
  742 + if (typeof deltaX === "undefined" || typeof deltaY === "undefined") {
  743 + // OS X Safari
  744 + deltaX = -1 * e.wheelDeltaX / 6;
  745 + deltaY = e.wheelDeltaY / 6;
  746 + }
  747 +
  748 + if (e.deltaMode && e.deltaMode === 1) {
  749 + // Firefox in deltaMode 1: Line scrolling
  750 + deltaX *= 10;
  751 + deltaY *= 10;
  752 + }
  753 +
  754 + if (deltaX !== deltaX && deltaY !== deltaY/* NaN checks */) {
  755 + // IE in some mouse drivers
  756 + deltaX = 0;
  757 + deltaY = e.wheelDelta;
  758 + }
  759 +
  760 + if (e.shiftKey) {
  761 + // reverse axis with shift key
  762 + return [-deltaY, -deltaX];
  763 + }
  764 + return [deltaX, deltaY];
  765 + }
  766 +
  767 + function shouldBeConsumedByChild(deltaX, deltaY) {
  768 + var child = element.querySelector('textarea:hover, select[multiple]:hover, .ps-child:hover');
  769 + if (child) {
  770 + if (!window.getComputedStyle(child).overflow.match(/(scroll|auto)/)) {
  771 + // if not scrollable
  772 + return false;
  773 + }
  774 +
  775 + var maxScrollTop = child.scrollHeight - child.clientHeight;
  776 + if (maxScrollTop > 0) {
  777 + if (!(child.scrollTop === 0 && deltaY > 0) && !(child.scrollTop === maxScrollTop && deltaY < 0)) {
  778 + return true;
  779 + }
  780 + }
  781 + var maxScrollLeft = child.scrollLeft - child.clientWidth;
  782 + if (maxScrollLeft > 0) {
  783 + if (!(child.scrollLeft === 0 && deltaX < 0) && !(child.scrollLeft === maxScrollLeft && deltaX > 0)) {
  784 + return true;
  785 + }
  786 + }
  787 + }
  788 + return false;
  789 + }
  790 +
  791 + function mousewheelHandler(e) {
  792 + var delta = getDeltaFromEvent(e);
  793 +
  794 + var deltaX = delta[0];
  795 + var deltaY = delta[1];
  796 +
  797 + if (shouldBeConsumedByChild(deltaX, deltaY)) {
  798 + return;
  799 + }
  800 +
  801 + shouldPrevent = false;
  802 + if (!i.settings.useBothWheelAxes) {
  803 + // deltaX will only be used for horizontal scrolling and deltaY will
  804 + // only be used for vertical scrolling - this is the default
  805 + updateScroll(element, 'top', element.scrollTop - (deltaY * i.settings.wheelSpeed));
  806 + updateScroll(element, 'left', element.scrollLeft + (deltaX * i.settings.wheelSpeed));
  807 + } else if (i.scrollbarYActive && !i.scrollbarXActive) {
  808 + // only vertical scrollbar is active and useBothWheelAxes option is
  809 + // active, so let's scroll vertical bar using both mouse wheel axes
  810 + if (deltaY) {
  811 + updateScroll(element, 'top', element.scrollTop - (deltaY * i.settings.wheelSpeed));
  812 + } else {
  813 + updateScroll(element, 'top', element.scrollTop + (deltaX * i.settings.wheelSpeed));
  814 + }
  815 + shouldPrevent = true;
  816 + } else if (i.scrollbarXActive && !i.scrollbarYActive) {
  817 + // useBothWheelAxes and only horizontal bar is active, so use both
  818 + // wheel axes for horizontal bar
  819 + if (deltaX) {
  820 + updateScroll(element, 'left', element.scrollLeft + (deltaX * i.settings.wheelSpeed));
  821 + } else {
  822 + updateScroll(element, 'left', element.scrollLeft - (deltaY * i.settings.wheelSpeed));
  823 + }
  824 + shouldPrevent = true;
  825 + }
  826 +
  827 + updateGeometry(element);
  828 +
  829 + shouldPrevent = (shouldPrevent || shouldPreventDefault(deltaX, deltaY));
  830 + if (shouldPrevent) {
  831 + e.stopPropagation();
  832 + e.preventDefault();
  833 + }
  834 + }
  835 +
  836 + if (typeof window.onwheel !== "undefined") {
  837 + i.event.bind(element, 'wheel', mousewheelHandler);
  838 + } else if (typeof window.onmousewheel !== "undefined") {
  839 + i.event.bind(element, 'mousewheel', mousewheelHandler);
  840 + }
  841 +}
  842 +
  843 +module.exports = function (element) {
  844 + var i = instances.get(element);
  845 + bindMouseWheelHandler(element, i);
  846 +};
  847 +
  848 +},{"../instances":18,"../update-geometry":19,"../update-scroll":20}],14:[function(require,module,exports){
  849 +'use strict';
  850 +
  851 +var instances = require('../instances');
  852 +var updateGeometry = require('../update-geometry');
  853 +
  854 +function bindNativeScrollHandler(element, i) {
  855 + i.event.bind(element, 'scroll', function () {
  856 + updateGeometry(element);
  857 + });
  858 +}
  859 +
  860 +module.exports = function (element) {
  861 + var i = instances.get(element);
  862 + bindNativeScrollHandler(element, i);
  863 +};
  864 +
  865 +},{"../instances":18,"../update-geometry":19}],15:[function(require,module,exports){
  866 +'use strict';
  867 +
  868 +var _ = require('../../lib/helper');
  869 +var instances = require('../instances');
  870 +var updateGeometry = require('../update-geometry');
  871 +var updateScroll = require('../update-scroll');
  872 +
  873 +function bindSelectionHandler(element, i) {
  874 + function getRangeNode() {
  875 + var selection = window.getSelection ? window.getSelection() :
  876 + document.getSelection ? document.getSelection() : '';
  877 + if (selection.toString().length === 0) {
  878 + return null;
  879 + } else {
  880 + return selection.getRangeAt(0).commonAncestorContainer;
  881 + }
  882 + }
  883 +
  884 + var scrollingLoop = null;
  885 + var scrollDiff = {top: 0, left: 0};
  886 + function startScrolling() {
  887 + if (!scrollingLoop) {
  888 + scrollingLoop = setInterval(function () {
  889 + if (!instances.get(element)) {
  890 + clearInterval(scrollingLoop);
  891 + return;
  892 + }
  893 +
  894 + updateScroll(element, 'top', element.scrollTop + scrollDiff.top);
  895 + updateScroll(element, 'left', element.scrollLeft + scrollDiff.left);
  896 + updateGeometry(element);
  897 + }, 50); // every .1 sec
  898 + }
  899 + }
  900 + function stopScrolling() {
  901 + if (scrollingLoop) {
  902 + clearInterval(scrollingLoop);
  903 + scrollingLoop = null;
  904 + }
  905 + _.stopScrolling(element);
  906 + }
  907 +
  908 + var isSelected = false;
  909 + i.event.bind(i.ownerDocument, 'selectionchange', function () {
  910 + if (element.contains(getRangeNode())) {
  911 + isSelected = true;
  912 + } else {
  913 + isSelected = false;
  914 + stopScrolling();
  915 + }
  916 + });
  917 + i.event.bind(window, 'mouseup', function () {
  918 + if (isSelected) {
  919 + isSelected = false;
  920 + stopScrolling();
  921 + }
  922 + });
  923 + i.event.bind(window, 'keyup', function () {
  924 + if (isSelected) {
  925 + isSelected = false;
  926 + stopScrolling();
  927 + }
  928 + });
  929 +
  930 + i.event.bind(window, 'mousemove', function (e) {
  931 + if (isSelected) {
  932 + var mousePosition = {x: e.pageX, y: e.pageY};
  933 + var containerGeometry = {
  934 + left: element.offsetLeft,
  935 + right: element.offsetLeft + element.offsetWidth,
  936 + top: element.offsetTop,
  937 + bottom: element.offsetTop + element.offsetHeight
  938 + };
  939 +
  940 + if (mousePosition.x < containerGeometry.left + 3) {
  941 + scrollDiff.left = -5;
  942 + _.startScrolling(element, 'x');
  943 + } else if (mousePosition.x > containerGeometry.right - 3) {
  944 + scrollDiff.left = 5;
  945 + _.startScrolling(element, 'x');
  946 + } else {
  947 + scrollDiff.left = 0;
  948 + }
  949 +
  950 + if (mousePosition.y < containerGeometry.top + 3) {
  951 + if (containerGeometry.top + 3 - mousePosition.y < 5) {
  952 + scrollDiff.top = -5;
  953 + } else {
  954 + scrollDiff.top = -20;
  955 + }
  956 + _.startScrolling(element, 'y');
  957 + } else if (mousePosition.y > containerGeometry.bottom - 3) {
  958 + if (mousePosition.y - containerGeometry.bottom + 3 < 5) {
  959 + scrollDiff.top = 5;
  960 + } else {
  961 + scrollDiff.top = 20;
  962 + }
  963 + _.startScrolling(element, 'y');
  964 + } else {
  965 + scrollDiff.top = 0;
  966 + }
  967 +
  968 + if (scrollDiff.top === 0 && scrollDiff.left === 0) {
  969 + stopScrolling();
  970 + } else {
  971 + startScrolling();
  972 + }
  973 + }
  974 + });
  975 +}
  976 +
  977 +module.exports = function (element) {
  978 + var i = instances.get(element);
  979 + bindSelectionHandler(element, i);
  980 +};
  981 +
  982 +},{"../../lib/helper":6,"../instances":18,"../update-geometry":19,"../update-scroll":20}],16:[function(require,module,exports){
  983 +'use strict';
  984 +
  985 +var _ = require('../../lib/helper');
  986 +var instances = require('../instances');
  987 +var updateGeometry = require('../update-geometry');
  988 +var updateScroll = require('../update-scroll');
  989 +
  990 +function bindTouchHandler(element, i, supportsTouch, supportsIePointer) {
  991 + function shouldPreventDefault(deltaX, deltaY) {
  992 + var scrollTop = element.scrollTop;
  993 + var scrollLeft = element.scrollLeft;
  994 + var magnitudeX = Math.abs(deltaX);
  995 + var magnitudeY = Math.abs(deltaY);
  996 +
  997 + if (magnitudeY > magnitudeX) {
  998 + // user is perhaps trying to swipe up/down the page
  999 +
  1000 + if (((deltaY < 0) && (scrollTop === i.contentHeight - i.containerHeight)) ||
  1001 + ((deltaY > 0) && (scrollTop === 0))) {
  1002 + return !i.settings.swipePropagation;
  1003 + }
  1004 + } else if (magnitudeX > magnitudeY) {
  1005 + // user is perhaps trying to swipe left/right across the page
  1006 +
  1007 + if (((deltaX < 0) && (scrollLeft === i.contentWidth - i.containerWidth)) ||
  1008 + ((deltaX > 0) && (scrollLeft === 0))) {
  1009 + return !i.settings.swipePropagation;
  1010 + }
  1011 + }
  1012 +
  1013 + return true;
  1014 + }
  1015 +
  1016 + function applyTouchMove(differenceX, differenceY) {
  1017 + updateScroll(element, 'top', element.scrollTop - differenceY);
  1018 + updateScroll(element, 'left', element.scrollLeft - differenceX);
  1019 +
  1020 + updateGeometry(element);
  1021 + }
  1022 +
  1023 + var startOffset = {};
  1024 + var startTime = 0;
  1025 + var speed = {};
  1026 + var easingLoop = null;
  1027 + var inGlobalTouch = false;
  1028 + var inLocalTouch = false;
  1029 +
  1030 + function globalTouchStart() {
  1031 + inGlobalTouch = true;
  1032 + }
  1033 + function globalTouchEnd() {
  1034 + inGlobalTouch = false;
  1035 + }
  1036 +
  1037 + function getTouch(e) {
  1038 + if (e.targetTouches) {
  1039 + return e.targetTouches[0];
  1040 + } else {
  1041 + // Maybe IE pointer
  1042 + return e;
  1043 + }
  1044 + }
  1045 + function shouldHandle(e) {
  1046 + if (e.targetTouches && e.targetTouches.length === 1) {
  1047 + return true;
  1048 + }
  1049 + if (e.pointerType && e.pointerType !== 'mouse' && e.pointerType !== e.MSPOINTER_TYPE_MOUSE) {
  1050 + return true;
  1051 + }
  1052 + return false;
  1053 + }
  1054 + function touchStart(e) {
  1055 + if (shouldHandle(e)) {
  1056 + inLocalTouch = true;
  1057 +
  1058 + var touch = getTouch(e);
  1059 +
  1060 + startOffset.pageX = touch.pageX;
  1061 + startOffset.pageY = touch.pageY;
  1062 +
  1063 + startTime = (new Date()).getTime();
  1064 +
  1065 + if (easingLoop !== null) {
  1066 + clearInterval(easingLoop);
  1067 + }
  1068 +
  1069 + e.stopPropagation();
  1070 + }
  1071 + }
  1072 + function touchMove(e) {
  1073 + if (!inLocalTouch && i.settings.swipePropagation) {
  1074 + touchStart(e);
  1075 + }
  1076 + if (!inGlobalTouch && inLocalTouch && shouldHandle(e)) {
  1077 + var touch = getTouch(e);
  1078 +
  1079 + var currentOffset = {pageX: touch.pageX, pageY: touch.pageY};
  1080 +
  1081 + var differenceX = currentOffset.pageX - startOffset.pageX;
  1082 + var differenceY = currentOffset.pageY - startOffset.pageY;
  1083 +
  1084 + applyTouchMove(differenceX, differenceY);
  1085 + startOffset = currentOffset;
  1086 +
  1087 + var currentTime = (new Date()).getTime();
  1088 +
  1089 + var timeGap = currentTime - startTime;
  1090 + if (timeGap > 0) {
  1091 + speed.x = differenceX / timeGap;
  1092 + speed.y = differenceY / timeGap;
  1093 + startTime = currentTime;
  1094 + }
  1095 +
  1096 + if (shouldPreventDefault(differenceX, differenceY)) {
  1097 + e.stopPropagation();
  1098 + e.preventDefault();
  1099 + }
  1100 + }
  1101 + }
  1102 + function touchEnd() {
  1103 + if (!inGlobalTouch && inLocalTouch) {
  1104 + inLocalTouch = false;
  1105 +
  1106 + clearInterval(easingLoop);
  1107 + easingLoop = setInterval(function () {
  1108 + if (!instances.get(element)) {
  1109 + clearInterval(easingLoop);
  1110 + return;
  1111 + }
  1112 +
  1113 + if (!speed.x && !speed.y) {
  1114 + clearInterval(easingLoop);
  1115 + return;
  1116 + }
  1117 +
  1118 + if (Math.abs(speed.x) < 0.01 && Math.abs(speed.y) < 0.01) {
  1119 + clearInterval(easingLoop);
  1120 + return;
  1121 + }
  1122 +
  1123 + applyTouchMove(speed.x * 30, speed.y * 30);
  1124 +
  1125 + speed.x *= 0.8;
  1126 + speed.y *= 0.8;
  1127 + }, 10);
  1128 + }
  1129 + }
  1130 +
  1131 + if (supportsTouch) {
  1132 + i.event.bind(window, 'touchstart', globalTouchStart);
  1133 + i.event.bind(window, 'touchend', globalTouchEnd);
  1134 + i.event.bind(element, 'touchstart', touchStart);
  1135 + i.event.bind(element, 'touchmove', touchMove);
  1136 + i.event.bind(element, 'touchend', touchEnd);
  1137 + } else if (supportsIePointer) {
  1138 + if (window.PointerEvent) {
  1139 + i.event.bind(window, 'pointerdown', globalTouchStart);
  1140 + i.event.bind(window, 'pointerup', globalTouchEnd);
  1141 + i.event.bind(element, 'pointerdown', touchStart);
  1142 + i.event.bind(element, 'pointermove', touchMove);
  1143 + i.event.bind(element, 'pointerup', touchEnd);
  1144 + } else if (window.MSPointerEvent) {
  1145 + i.event.bind(window, 'MSPointerDown', globalTouchStart);
  1146 + i.event.bind(window, 'MSPointerUp', globalTouchEnd);
  1147 + i.event.bind(element, 'MSPointerDown', touchStart);
  1148 + i.event.bind(element, 'MSPointerMove', touchMove);
  1149 + i.event.bind(element, 'MSPointerUp', touchEnd);
  1150 + }
  1151 + }
  1152 +}
  1153 +
  1154 +module.exports = function (element) {
  1155 + if (!_.env.supportsTouch && !_.env.supportsIePointer) {
  1156 + return;
  1157 + }
  1158 +
  1159 + var i = instances.get(element);
  1160 + bindTouchHandler(element, i, _.env.supportsTouch, _.env.supportsIePointer);
  1161 +};
  1162 +
  1163 +},{"../../lib/helper":6,"../instances":18,"../update-geometry":19,"../update-scroll":20}],17:[function(require,module,exports){
  1164 +'use strict';
  1165 +
  1166 +var _ = require('../lib/helper');
  1167 +var cls = require('../lib/class');
  1168 +var instances = require('./instances');
  1169 +var updateGeometry = require('./update-geometry');
  1170 +
  1171 +// Handlers
  1172 +var handlers = {
  1173 + 'click-rail': require('./handler/click-rail'),
  1174 + 'drag-scrollbar': require('./handler/drag-scrollbar'),
  1175 + 'keyboard': require('./handler/keyboard'),
  1176 + 'wheel': require('./handler/mouse-wheel'),
  1177 + 'touch': require('./handler/touch'),
  1178 + 'selection': require('./handler/selection')
  1179 +};
  1180 +var nativeScrollHandler = require('./handler/native-scroll');
  1181 +
  1182 +module.exports = function (element, userSettings) {
  1183 + userSettings = typeof userSettings === 'object' ? userSettings : {};
  1184 +
  1185 + cls.add(element, 'ps-container');
  1186 +
  1187 + // Create a plugin instance.
  1188 + var i = instances.add(element);
  1189 +
  1190 + i.settings = _.extend(i.settings, userSettings);
  1191 + cls.add(element, 'ps-theme-' + i.settings.theme);
  1192 +
  1193 + i.settings.handlers.forEach(function (handlerName) {
  1194 + handlers[handlerName](element);
  1195 + });
  1196 +
  1197 + nativeScrollHandler(element);
  1198 +
  1199 + updateGeometry(element);
  1200 +};
  1201 +
  1202 +},{"../lib/class":2,"../lib/helper":6,"./handler/click-rail":10,"./handler/drag-scrollbar":11,"./handler/keyboard":12,"./handler/mouse-wheel":13,"./handler/native-scroll":14,"./handler/selection":15,"./handler/touch":16,"./instances":18,"./update-geometry":19}],18:[function(require,module,exports){
  1203 +'use strict';
  1204 +
  1205 +var _ = require('../lib/helper');
  1206 +var cls = require('../lib/class');
  1207 +var defaultSettings = require('./default-setting');
  1208 +var dom = require('../lib/dom');
  1209 +var EventManager = require('../lib/event-manager');
  1210 +var guid = require('../lib/guid');
  1211 +
  1212 +var instances = {};
  1213 +
  1214 +function Instance(element) {
  1215 + var i = this;
  1216 +
  1217 + i.settings = _.clone(defaultSettings);
  1218 + i.containerWidth = null;
  1219 + i.containerHeight = null;
  1220 + i.contentWidth = null;
  1221 + i.contentHeight = null;
  1222 +
  1223 + i.isRtl = dom.css(element, 'direction') === "rtl";
  1224 + i.isNegativeScroll = (function () {
  1225 + var originalScrollLeft = element.scrollLeft;
  1226 + var result = null;
  1227 + element.scrollLeft = -1;
  1228 + result = element.scrollLeft < 0;
  1229 + element.scrollLeft = originalScrollLeft;
  1230 + return result;
  1231 + })();
  1232 + i.negativeScrollAdjustment = i.isNegativeScroll ? element.scrollWidth - element.clientWidth : 0;
  1233 + i.event = new EventManager();
  1234 + i.ownerDocument = element.ownerDocument || document;
  1235 +
  1236 + function focus() {
  1237 + cls.add(element, 'ps-focus');
  1238 + }
  1239 +
  1240 + function blur() {
  1241 + cls.remove(element, 'ps-focus');
  1242 + }
  1243 +
  1244 + i.scrollbarXRail = dom.appendTo(dom.e('div', 'ps-scrollbar-x-rail'), element);
  1245 + i.scrollbarX = dom.appendTo(dom.e('div', 'ps-scrollbar-x'), i.scrollbarXRail);
  1246 + i.scrollbarX.setAttribute('tabindex', 0);
  1247 + i.event.bind(i.scrollbarX, 'focus', focus);
  1248 + i.event.bind(i.scrollbarX, 'blur', blur);
  1249 + i.scrollbarXActive = null;
  1250 + i.scrollbarXWidth = null;
  1251 + i.scrollbarXLeft = null;
  1252 + i.scrollbarXBottom = _.toInt(dom.css(i.scrollbarXRail, 'bottom'));
  1253 + i.isScrollbarXUsingBottom = i.scrollbarXBottom === i.scrollbarXBottom; // !isNaN
  1254 + i.scrollbarXTop = i.isScrollbarXUsingBottom ? null : _.toInt(dom.css(i.scrollbarXRail, 'top'));
  1255 + i.railBorderXWidth = _.toInt(dom.css(i.scrollbarXRail, 'borderLeftWidth')) + _.toInt(dom.css(i.scrollbarXRail, 'borderRightWidth'));
  1256 + // Set rail to display:block to calculate margins
  1257 + dom.css(i.scrollbarXRail, 'display', 'block');
  1258 + i.railXMarginWidth = _.toInt(dom.css(i.scrollbarXRail, 'marginLeft')) + _.toInt(dom.css(i.scrollbarXRail, 'marginRight'));
  1259 + dom.css(i.scrollbarXRail, 'display', '');
  1260 + i.railXWidth = null;
  1261 + i.railXRatio = null;
  1262 +
  1263 + i.scrollbarYRail = dom.appendTo(dom.e('div', 'ps-scrollbar-y-rail'), element);
  1264 + i.scrollbarY = dom.appendTo(dom.e('div', 'ps-scrollbar-y'), i.scrollbarYRail);
  1265 + i.scrollbarY.setAttribute('tabindex', 0);
  1266 + i.event.bind(i.scrollbarY, 'focus', focus);
  1267 + i.event.bind(i.scrollbarY, 'blur', blur);
  1268 + i.scrollbarYActive = null;
  1269 + i.scrollbarYHeight = null;
  1270 + i.scrollbarYTop = null;
  1271 + i.scrollbarYRight = _.toInt(dom.css(i.scrollbarYRail, 'right'));
  1272 + i.isScrollbarYUsingRight = i.scrollbarYRight === i.scrollbarYRight; // !isNaN
  1273 + i.scrollbarYLeft = i.isScrollbarYUsingRight ? null : _.toInt(dom.css(i.scrollbarYRail, 'left'));
  1274 + i.scrollbarYOuterWidth = i.isRtl ? _.outerWidth(i.scrollbarY) : null;
  1275 + i.railBorderYWidth = _.toInt(dom.css(i.scrollbarYRail, 'borderTopWidth')) + _.toInt(dom.css(i.scrollbarYRail, 'borderBottomWidth'));
  1276 + dom.css(i.scrollbarYRail, 'display', 'block');
  1277 + i.railYMarginHeight = _.toInt(dom.css(i.scrollbarYRail, 'marginTop')) + _.toInt(dom.css(i.scrollbarYRail, 'marginBottom'));
  1278 + dom.css(i.scrollbarYRail, 'display', '');
  1279 + i.railYHeight = null;
  1280 + i.railYRatio = null;
  1281 +}
  1282 +
  1283 +function getId(element) {
  1284 + return element.getAttribute('data-ps-id');
  1285 +}
  1286 +
  1287 +function setId(element, id) {
  1288 + element.setAttribute('data-ps-id', id);
  1289 +}
  1290 +
  1291 +function removeId(element) {
  1292 + element.removeAttribute('data-ps-id');
  1293 +}
  1294 +
  1295 +exports.add = function (element) {
  1296 + var newId = guid();
  1297 + setId(element, newId);
  1298 + instances[newId] = new Instance(element);
  1299 + return instances[newId];
  1300 +};
  1301 +
  1302 +exports.remove = function (element) {
  1303 + delete instances[getId(element)];
  1304 + removeId(element);
  1305 +};
  1306 +
  1307 +exports.get = function (element) {
  1308 + return instances[getId(element)];
  1309 +};
  1310 +
  1311 +},{"../lib/class":2,"../lib/dom":3,"../lib/event-manager":4,"../lib/guid":5,"../lib/helper":6,"./default-setting":8}],19:[function(require,module,exports){
  1312 +'use strict';
  1313 +
  1314 +var _ = require('../lib/helper');
  1315 +var cls = require('../lib/class');
  1316 +var dom = require('../lib/dom');
  1317 +var instances = require('./instances');
  1318 +var updateScroll = require('./update-scroll');
  1319 +
  1320 +function getThumbSize(i, thumbSize) {
  1321 + if (i.settings.minScrollbarLength) {
  1322 + thumbSize = Math.max(thumbSize, i.settings.minScrollbarLength);
  1323 + }
  1324 + if (i.settings.maxScrollbarLength) {
  1325 + thumbSize = Math.min(thumbSize, i.settings.maxScrollbarLength);
  1326 + }
  1327 + return thumbSize;
  1328 +}
  1329 +
  1330 +function updateCss(element, i) {
  1331 + var xRailOffset = {width: i.railXWidth};
  1332 + if (i.isRtl) {
  1333 + xRailOffset.left = i.negativeScrollAdjustment + element.scrollLeft + i.containerWidth - i.contentWidth;
  1334 + } else {
  1335 + xRailOffset.left = element.scrollLeft;
  1336 + }
  1337 + if (i.isScrollbarXUsingBottom) {
  1338 + xRailOffset.bottom = i.scrollbarXBottom - element.scrollTop;
  1339 + } else {
  1340 + xRailOffset.top = i.scrollbarXTop + element.scrollTop;
  1341 + }
  1342 + dom.css(i.scrollbarXRail, xRailOffset);
  1343 +
  1344 + var yRailOffset = {top: element.scrollTop, height: i.railYHeight};
  1345 + if (i.isScrollbarYUsingRight) {
  1346 + if (i.isRtl) {
  1347 + yRailOffset.right = i.contentWidth - (i.negativeScrollAdjustment + element.scrollLeft) - i.scrollbarYRight - i.scrollbarYOuterWidth;
  1348 + } else {
  1349 + yRailOffset.right = i.scrollbarYRight - element.scrollLeft;
  1350 + }
  1351 + } else {
  1352 + if (i.isRtl) {
  1353 + yRailOffset.left = i.negativeScrollAdjustment + element.scrollLeft + i.containerWidth * 2 - i.contentWidth - i.scrollbarYLeft - i.scrollbarYOuterWidth;
  1354 + } else {
  1355 + yRailOffset.left = i.scrollbarYLeft + element.scrollLeft;
  1356 + }
  1357 + }
  1358 + dom.css(i.scrollbarYRail, yRailOffset);
  1359 +
  1360 + dom.css(i.scrollbarX, {left: i.scrollbarXLeft, width: i.scrollbarXWidth - i.railBorderXWidth});
  1361 + dom.css(i.scrollbarY, {top: i.scrollbarYTop, height: i.scrollbarYHeight - i.railBorderYWidth});
  1362 +}
  1363 +
  1364 +module.exports = function (element) {
  1365 + var i = instances.get(element);
  1366 +
  1367 + i.containerWidth = element.clientWidth;
  1368 + i.containerHeight = element.clientHeight;
  1369 + i.contentWidth = element.scrollWidth;
  1370 + i.contentHeight = element.scrollHeight;
  1371 +
  1372 + var existingRails;
  1373 + if (!element.contains(i.scrollbarXRail)) {
  1374 + existingRails = dom.queryChildren(element, '.ps-scrollbar-x-rail');
  1375 + if (existingRails.length > 0) {
  1376 + existingRails.forEach(function (rail) {
  1377 + dom.remove(rail);
  1378 + });
  1379 + }
  1380 + dom.appendTo(i.scrollbarXRail, element);
  1381 + }
  1382 + if (!element.contains(i.scrollbarYRail)) {
  1383 + existingRails = dom.queryChildren(element, '.ps-scrollbar-y-rail');
  1384 + if (existingRails.length > 0) {
  1385 + existingRails.forEach(function (rail) {
  1386 + dom.remove(rail);
  1387 + });
  1388 + }
  1389 + dom.appendTo(i.scrollbarYRail, element);
  1390 + }
  1391 +
  1392 + if (!i.settings.suppressScrollX && i.containerWidth + i.settings.scrollXMarginOffset < i.contentWidth) {
  1393 + i.scrollbarXActive = true;
  1394 + i.railXWidth = i.containerWidth - i.railXMarginWidth;
  1395 + i.railXRatio = i.containerWidth / i.railXWidth;
  1396 + i.scrollbarXWidth = getThumbSize(i, _.toInt(i.railXWidth * i.containerWidth / i.contentWidth));
  1397 + i.scrollbarXLeft = _.toInt((i.negativeScrollAdjustment + element.scrollLeft) * (i.railXWidth - i.scrollbarXWidth) / (i.contentWidth - i.containerWidth));
  1398 + } else {
  1399 + i.scrollbarXActive = false;
  1400 + }
  1401 +
  1402 + if (!i.settings.suppressScrollY && i.containerHeight + i.settings.scrollYMarginOffset < i.contentHeight) {
  1403 + i.scrollbarYActive = true;
  1404 + i.railYHeight = i.containerHeight - i.railYMarginHeight;
  1405 + i.railYRatio = i.containerHeight / i.railYHeight;
  1406 + i.scrollbarYHeight = getThumbSize(i, _.toInt(i.railYHeight * i.containerHeight / i.contentHeight));
  1407 + i.scrollbarYTop = _.toInt(element.scrollTop * (i.railYHeight - i.scrollbarYHeight) / (i.contentHeight - i.containerHeight));
  1408 + } else {
  1409 + i.scrollbarYActive = false;
  1410 + }
  1411 +
  1412 + if (i.scrollbarXLeft >= i.railXWidth - i.scrollbarXWidth) {
  1413 + i.scrollbarXLeft = i.railXWidth - i.scrollbarXWidth;
  1414 + }
  1415 + if (i.scrollbarYTop >= i.railYHeight - i.scrollbarYHeight) {
  1416 + i.scrollbarYTop = i.railYHeight - i.scrollbarYHeight;
  1417 + }
  1418 +
  1419 + updateCss(element, i);
  1420 +
  1421 + if (i.scrollbarXActive) {
  1422 + cls.add(element, 'ps-active-x');
  1423 + } else {
  1424 + cls.remove(element, 'ps-active-x');
  1425 + i.scrollbarXWidth = 0;
  1426 + i.scrollbarXLeft = 0;
  1427 + updateScroll(element, 'left', 0);
  1428 + }
  1429 + if (i.scrollbarYActive) {
  1430 + cls.add(element, 'ps-active-y');
  1431 + } else {
  1432 + cls.remove(element, 'ps-active-y');
  1433 + i.scrollbarYHeight = 0;
  1434 + i.scrollbarYTop = 0;
  1435 + updateScroll(element, 'top', 0);
  1436 + }
  1437 +};
  1438 +
  1439 +},{"../lib/class":2,"../lib/dom":3,"../lib/helper":6,"./instances":18,"./update-scroll":20}],20:[function(require,module,exports){
  1440 +'use strict';
  1441 +
  1442 +var instances = require('./instances');
  1443 +
  1444 +var lastTop;
  1445 +var lastLeft;
  1446 +
  1447 +var createDOMEvent = function (name) {
  1448 + var event = document.createEvent("Event");
  1449 + event.initEvent(name, true, true);
  1450 + return event;
  1451 +};
  1452 +
  1453 +module.exports = function (element, axis, value) {
  1454 + if (typeof element === 'undefined') {
  1455 + throw 'You must provide an element to the update-scroll function';
  1456 + }
  1457 +
  1458 + if (typeof axis === 'undefined') {
  1459 + throw 'You must provide an axis to the update-scroll function';
  1460 + }
  1461 +
  1462 + if (typeof value === 'undefined') {
  1463 + throw 'You must provide a value to the update-scroll function';
  1464 + }
  1465 +
  1466 + if (axis === 'top' && value <= 0) {
  1467 + element.scrollTop = value = 0; // don't allow negative scroll
  1468 + element.dispatchEvent(createDOMEvent('ps-y-reach-start'));
  1469 + }
  1470 +
  1471 + if (axis === 'left' && value <= 0) {
  1472 + element.scrollLeft = value = 0; // don't allow negative scroll
  1473 + element.dispatchEvent(createDOMEvent('ps-x-reach-start'));
  1474 + }
  1475 +
  1476 + var i = instances.get(element);
  1477 +
  1478 + if (axis === 'top' && value >= i.contentHeight - i.containerHeight) {
  1479 + // don't allow scroll past container
  1480 + value = i.contentHeight - i.containerHeight;
  1481 + if (value - element.scrollTop <= 1) {
  1482 + // mitigates rounding errors on non-subpixel scroll values
  1483 + value = element.scrollTop;
  1484 + } else {
  1485 + element.scrollTop = value;
  1486 + }
  1487 + element.dispatchEvent(createDOMEvent('ps-y-reach-end'));
  1488 + }
  1489 +
  1490 + if (axis === 'left' && value >= i.contentWidth - i.containerWidth) {
  1491 + // don't allow scroll past container
  1492 + value = i.contentWidth - i.containerWidth;
  1493 + if (value - element.scrollLeft <= 1) {
  1494 + // mitigates rounding errors on non-subpixel scroll values
  1495 + value = element.scrollLeft;
  1496 + } else {
  1497 + element.scrollLeft = value;
  1498 + }
  1499 + element.dispatchEvent(createDOMEvent('ps-x-reach-end'));
  1500 + }
  1501 +
  1502 + if (!lastTop) {
  1503 + lastTop = element.scrollTop;
  1504 + }
  1505 +
  1506 + if (!lastLeft) {
  1507 + lastLeft = element.scrollLeft;
  1508 + }
  1509 +
  1510 + if (axis === 'top' && value < lastTop) {
  1511 + element.dispatchEvent(createDOMEvent('ps-scroll-up'));
  1512 + }
  1513 +
  1514 + if (axis === 'top' && value > lastTop) {
  1515 + element.dispatchEvent(createDOMEvent('ps-scroll-down'));
  1516 + }
  1517 +
  1518 + if (axis === 'left' && value < lastLeft) {
  1519 + element.dispatchEvent(createDOMEvent('ps-scroll-left'));
  1520 + }
  1521 +
  1522 + if (axis === 'left' && value > lastLeft) {
  1523 + element.dispatchEvent(createDOMEvent('ps-scroll-right'));
  1524 + }
  1525 +
  1526 + if (axis === 'top') {
  1527 + element.scrollTop = lastTop = value;
  1528 + element.dispatchEvent(createDOMEvent('ps-scroll-y'));
  1529 + }
  1530 +
  1531 + if (axis === 'left') {
  1532 + element.scrollLeft = lastLeft = value;
  1533 + element.dispatchEvent(createDOMEvent('ps-scroll-x'));
  1534 + }
  1535 +
  1536 +};
  1537 +
  1538 +},{"./instances":18}],21:[function(require,module,exports){
  1539 +'use strict';
  1540 +
  1541 +var _ = require('../lib/helper');
  1542 +var dom = require('../lib/dom');
  1543 +var instances = require('./instances');
  1544 +var updateGeometry = require('./update-geometry');
  1545 +var updateScroll = require('./update-scroll');
  1546 +
  1547 +module.exports = function (element) {
  1548 + var i = instances.get(element);
  1549 +
  1550 + if (!i) {
  1551 + return;
  1552 + }
  1553 +
  1554 + // Recalcuate negative scrollLeft adjustment
  1555 + i.negativeScrollAdjustment = i.isNegativeScroll ? element.scrollWidth - element.clientWidth : 0;
  1556 +
  1557 + // Recalculate rail margins
  1558 + dom.css(i.scrollbarXRail, 'display', 'block');
  1559 + dom.css(i.scrollbarYRail, 'display', 'block');
  1560 + i.railXMarginWidth = _.toInt(dom.css(i.scrollbarXRail, 'marginLeft')) + _.toInt(dom.css(i.scrollbarXRail, 'marginRight'));
  1561 + i.railYMarginHeight = _.toInt(dom.css(i.scrollbarYRail, 'marginTop')) + _.toInt(dom.css(i.scrollbarYRail, 'marginBottom'));
  1562 +
  1563 + // Hide scrollbars not to affect scrollWidth and scrollHeight
  1564 + dom.css(i.scrollbarXRail, 'display', 'none');
  1565 + dom.css(i.scrollbarYRail, 'display', 'none');
  1566 +
  1567 + updateGeometry(element);
  1568 +
  1569 + // Update top/left scroll to trigger events
  1570 + updateScroll(element, 'top', element.scrollTop);
  1571 + updateScroll(element, 'left', element.scrollLeft);
  1572 +
  1573 + dom.css(i.scrollbarXRail, 'display', '');
  1574 + dom.css(i.scrollbarYRail, 'display', '');
  1575 +};
  1576 +
  1577 +},{"../lib/dom":3,"../lib/helper":6,"./instances":18,"./update-geometry":19,"./update-scroll":20}]},{},[1]);
... ...
src/main/resources/static/real_control_v2/assets/plugins/uikit-2.27.1/components/sticky.gradient.min.css 0 → 100644
  1 +/*! UIkit 2.27.1 | http://www.getuikit.com | (c) 2014 YOOtheme | MIT License */
  2 +[data-uk-sticky].uk-active{z-index:980;box-sizing:border-box;-webkit-backface-visibility:hidden}[data-uk-sticky][class*=uk-animation-]{-webkit-animation-duration:.2s;animation-duration:.2s}[data-uk-sticky].uk-animation-reverse{-webkit-animation-duration:.2s;animation-duration:.2s}
0 3 \ No newline at end of file
... ...
src/main/resources/static/real_control_v2/assets/plugins/uikit-2.27.1/components/sticky.min.js 0 → 100644
  1 +/*! UIkit 2.27.1 | http://www.getuikit.com | (c) 2014 YOOtheme | MIT License */
  2 +!function(t){var i;window.UIkit&&(i=t(UIkit)),"function"==typeof define&&define.amd&&define("uikit-sticky",["uikit"],function(){return i||t(UIkit)})}(function(t){"use strict";function i(){var i=arguments.length?arguments:n;if(i.length&&!(e.scrollTop()<0))for(var o,a,r,h,p=e.scrollTop(),c=s.height(),l=e.height(),m=c-l,d=p>m?m-p:0,u=0;u<i.length;u++)if(h=i[u],h.element.is(":visible")&&!h.animate){if(h.check()){if(h.top<0?o=0:(r=h.element.outerHeight(),o=c-r-h.top-h.options.bottom-p-d,o=0>o?o+h.top:h.top),h.boundary&&h.boundary.length){var f=h.boundary.offset().top;a=h.boundtoparent?c-(f+h.boundary.outerHeight())+parseInt(h.boundary.css("padding-bottom")):c-f,o=p+r>c-a-(h.top<0?0:h.top)?c-a-(p+r):o}if(h.currentTop!=o){if(h.element.css({position:"fixed",top:o,width:h.getWidthFrom.length?h.getWidthFrom.width():h.element.width()}),!h.init&&(h.element.addClass(h.options.clsinit),location.hash&&p>0&&h.options.target)){var g=t.$(location.hash);g.length&&setTimeout(function(t,i){return function(){i.element.width();var e=t.offset(),s=e.top+t.outerHeight(),n=i.element.offset(),o=i.element.outerHeight(),a=n.top+o;n.top<s&&e.top<a&&(p=e.top-o-i.options.target,window.scrollTo(0,p))}}(g,h),0)}h.element.addClass(h.options.clsactive).removeClass(h.options.clsinactive),h.element.trigger("active.uk.sticky"),h.element.css("margin",""),h.options.animation&&h.init&&!t.Utils.isInView(h.wrapper)&&h.element.addClass(h.options.animation),h.currentTop=o}}else null!==h.currentTop&&h.reset();h.init=!0}}var e=t.$win,s=t.$doc,n=[],o=1;return t.component("sticky",{defaults:{top:0,bottom:0,animation:"",clsinit:"uk-sticky-init",clsactive:"uk-active",clsinactive:"",getWidthFrom:"",showup:!1,boundary:!1,media:!1,target:!1,disabled:!1},boot:function(){t.$doc.on("scrolling.uk.document",function(t,e){e&&e.dir&&(o=e.dir.y,i())}),t.$win.on("resize orientationchange",t.Utils.debounce(function(){if(n.length){for(var t=0;t<n.length;t++)n[t].reset(!0),n[t].self.computeWrapper();i()}},100)),t.ready(function(e){setTimeout(function(){t.$("[data-uk-sticky]",e).each(function(){var i=t.$(this);i.data("sticky")||t.sticky(i,t.Utils.options(i.attr("data-uk-sticky")))}),i()},0)})},init:function(){var i,a=this.options.boundary;this.wrapper=this.element.wrap('<div class="uk-sticky-placeholder"></div>').parent(),this.computeWrapper(),this.wrapper.css({"margin-top":this.element.css("margin-top"),"margin-bottom":this.element.css("margin-bottom"),"margin-left":this.element.css("margin-left"),"margin-right":this.element.css("margin-right")}),this.element.css("margin",0),a&&(a===!0||"!"===a[0]?(a=a===!0?this.wrapper.parent():this.wrapper.closest(a.substr(1)),i=!0):"string"==typeof a&&(a=t.$(a))),this.sticky={self:this,options:this.options,element:this.element,currentTop:null,wrapper:this.wrapper,init:!1,getWidthFrom:t.$(this.options.getWidthFrom||this.wrapper),boundary:a,boundtoparent:i,top:0,calcTop:function(){var i=this.options.top;if(this.options.top&&"string"==typeof this.options.top)if(this.options.top.match(/^(-|)(\d+)vh$/))i=window.innerHeight*parseInt(this.options.top,10)/100;else{var e=t.$(this.options.top).first();e.length&&e.is(":visible")&&(i=-1*(e.offset().top+e.outerHeight()-this.wrapper.offset().top))}this.top=i},reset:function(i){this.calcTop();var e=function(){this.element.css({position:"",top:"",width:"",left:"",margin:"0"}),this.element.removeClass([this.options.animation,"uk-animation-reverse",this.options.clsactive].join(" ")),this.element.addClass(this.options.clsinactive),this.element.trigger("inactive.uk.sticky"),this.currentTop=null,this.animate=!1}.bind(this);!i&&this.options.animation&&t.support.animation&&!t.Utils.isInView(this.wrapper)?(this.animate=!0,this.element.removeClass(this.options.animation).one(t.support.animation.end,function(){e()}).width(),this.element.addClass(this.options.animation+" uk-animation-reverse")):e()},check:function(){if(this.options.disabled)return!1;if(this.options.media)switch(typeof this.options.media){case"number":if(window.innerWidth<this.options.media)return!1;break;case"string":if(window.matchMedia&&!window.matchMedia(this.options.media).matches)return!1}var i=e.scrollTop(),n=s.height(),a=n-window.innerHeight,r=i>a?a-i:0,h=this.wrapper.offset().top,p=h-this.top-r,c=i>=p;return c&&this.options.showup&&(1==o&&(c=!1),-1==o&&!this.element.hasClass(this.options.clsactive)&&t.Utils.isInView(this.wrapper)&&(c=!1)),c}},this.sticky.calcTop(),n.push(this.sticky)},update:function(){i(this.sticky)},enable:function(){this.options.disabled=!1,this.update()},disable:function(t){this.options.disabled=!0,this.sticky.reset(t)},computeWrapper:function(){this.wrapper.css({height:-1==["absolute","fixed"].indexOf(this.element.css("position"))?this.element.outerHeight():"","float":"none"!=this.element.css("float")?this.element.css("float"):""}),"fixed"==this.element.css("position")&&this.element.css({width:this.sticky.getWidthFrom.length?this.sticky.getWidthFrom.width():this.element.width()})}}),t.sticky});
0 3 \ No newline at end of file
... ...
src/main/resources/static/real_control_v2/css/main.css
1 1 /* ^_^ baidu map hide logo */
2 2  
  3 +.ps-container > .ps-scrollbar-y-rail{
  4 + z-index: 9 !important;
  5 +}
  6 +
  7 +.ps-container > .ps-scrollbar-x-rail,
  8 +.ps-container > .ps-scrollbar-y-rail {
  9 + opacity: 0.6 !important;
  10 + padding: 0 !important;
  11 +}
  12 +
3 13 .anchorBL, .anchorBL, .amap-logo, .amap-copyright {
4 14 display: none;
5 15 }
... ... @@ -952,9 +962,6 @@ option.oil_station_opt{
952 962 .safe_driv_pop .title{
953 963 }
954 964  
955   -/*.safe_driv_pop i.uk-icon-times-circle{
956   - margin-right: 5px;
957   -}*/
958 965 .safe_driv_pop .desc{
959 966 display: block;
960 967 font-size: 12px;
... ... @@ -963,20 +970,20 @@ option.oil_station_opt{
963 970 margin-right: 5px;
964 971 }
965 972  
966   -/*.safe_driv_pop .detail_content{
967   - display: none;
  973 +/** 嵌入表单modal滚动条样式 */
  974 +#formFragmentModal::-webkit-scrollbar {
  975 + width: 10px;
  976 + background-color: #F5F5F5;
968 977 }
969   -
970   -.safe_driv_pop.open .detail_content{
971   - display: block;
972   - background: rgb(255, 255, 255);
973   - height: 200px;
974   - margin: 7px 0;
975   - border-radius: 5px;
976   - color: #000000;
  978 +#formFragmentModal::-webkit-scrollbar-thumb {
  979 + background-color: #000000;
  980 +}
  981 +#formFragmentModal::-webkit-scrollbar-track {
  982 + border: 0;
  983 + background-color: #F5F5F5;
  984 + border-radius: 0;
977 985 }
978 986  
979   -.safe_driv_pop.open .desc{
980   - display: none;
981   -}*/
982   -/** 安全驾驶相关css结束 */
983 987 \ No newline at end of file
  988 +#formFragmentModal::-webkit-scrollbar-thumb{
  989 + border: 5px solid rgb(226, 122, 122);
  990 +}
984 991 \ No newline at end of file
... ...
src/main/resources/static/real_control_v2/fragments/line_schedule/context_menu/lj_zrw.html
... ... @@ -57,7 +57,7 @@
57 57 <a id="addChildTaskBtn" data-uk-tooltip title="添加子任务"><i
58 58 class="uk-icon-plus"></i> </a>
59 59 </h3>
60   - <div class="ct_table_wrap ct_table_no_border" style="height: 142px;">
  60 + <div class="ct_table_wrap ct_table_no_border sub_task_table_wrap" style="height: 142px;">
61 61 <div class="ct_table sub-task-table">
62 62 <div class="ct_table_head">
63 63 <dl>
... ... @@ -159,8 +159,11 @@
159 159  
160 160 $(modal).on('init', function (e, data) {
161 161 e.stopPropagation();
162   - sch = data.sch;
  162 + //初始化滚动条
  163 + $('.main-schedule-wrap', modal).perfectScrollbar({suppressScrollX: true});
  164 + $('.sub_task_table_wrap', modal).perfectScrollbar({suppressScrollX: true});
163 165  
  166 + sch = data.sch;
164 167 f = $('.search-form', modal);
165 168 //线路下拉框
166 169 var opts = '';
... ... @@ -192,6 +195,8 @@
192 195 list: list
193 196 });
194 197 $(m_t_body, modal).html(htmlBody);
  198 + //更新主任务滚动条高度
  199 + $('.main-schedule-wrap', modal).perfectScrollbar('update');
195 200 $(s_t_body, modal).empty();
196 201 });
197 202 //班次点击
... ... @@ -252,6 +257,8 @@
252 257 sch.cTasks.sort(sub_task_sort);
253 258 htmlStr = template('sub_task-table-temp', {list: sch.cTasks});
254 259 tbody.html(htmlStr);
  260 + //更新子任务滚动条高度
  261 + $('.sub_task_table_wrap', modal).perfectScrollbar('update');
255 262 //字典转换
256 263 dictionaryUtils.transformDom($('.nt-dictionary', tbody));
257 264  
... ...
src/main/resources/static/real_control_v2/fragments/line_schedule/context_menu/tzrc.html
... ... @@ -122,6 +122,8 @@
122 122 e.stopPropagation();
123 123 sch = data.sch;
124 124  
  125 + //滚动条
  126 + $('.tzrc-table-wrap', modal).perfectScrollbar();
125 127 //线路下拉框
126 128 var opts = '';
127 129 $.each(gb_data_basic.activeLines, function () {
... ... @@ -146,6 +148,8 @@
146 148 list: list
147 149 });
148 150 $('.sch-tzrc-table .ct_table_body', modal).html(htmlBody);
  151 + //更新滚动条高度
  152 + $('.tzrc-table-wrap', modal).perfectScrollbar('update');
149 153 });
150 154  
151 155 $(modal).on('click', '.sch-tzrc-table .ct_table_body dl input[type=checkbox]', function () {
... ...
src/main/resources/static/real_control_v2/fragments/north/nav/curr_date_schedule.html
... ... @@ -83,7 +83,10 @@
83 83 }
84 84  
85 85 #curr-date-schedule-modal .line_list_ul li.active{
86   - background: #93d1ff;
  86 + background: #009dd8;
  87 + color: #fff;
  88 + box-shadow: inset 0 2px 4px rgba(0,0,0,.2);
  89 + text-shadow: 0 -1px 0 rgba(0,0,0,.2);
87 90 }
88 91 </style>
89 92  
... ... @@ -98,7 +101,7 @@
98 101 </ul>
99 102 </div>
100 103 <div class="uk-width-medium-9-10">
101   - <div class="ct_table_wrap" style="height: 460px;">
  104 + <div class="ct_table_wrap" style="height: 520px;">
102 105 <div class="ct_table curr-schedule-table">
103 106 <div class="ct_table_head">
104 107 <dl>
... ... @@ -192,6 +195,10 @@
192 195  
193 196 //默认点击第一个
194 197 $('.line_list_ul li:eq(0)', modal).trigger('click');
  198 + //滚动条
  199 + $('.ct_table_wrap', modal).perfectScrollbar();
  200 + //固定头部
  201 + gb_ct_table.fixedHead($('.ct_table_wrap', modal));
195 202 });
196 203  
197 204 $(modal).on('click', '.line_list_ul li', function () {
... ... @@ -203,7 +210,6 @@
203 210 var query = function (lineCode) {
204 211 $.get('/realSchedule/currSchedulePlanByLineCode', {lineCode: lineCode}, function (rs) {
205 212  
206   -
207 213 var data=[];
208 214 //先按路牌分组
209 215 var lpMapData = gb_common.groupBy(rs, 'lpName');
... ... @@ -214,6 +220,9 @@
214 220  
215 221 var htmlStr = template('curr_schedule_list-temp', {list: data});
216 222 $('.ct_table_body', modal).html(htmlStr);
  223 +
  224 + //更新滚动条
  225 + $('.ct_table_wrap', modal).perfectScrollbar('update');
217 226 });
218 227 };
219 228  
... ...
src/main/resources/static/real_control_v2/fragments/north/nav/dataManager/cars_move.html 0 → 100644
  1 +<div class="uk-modal ct_move_modal" id="data_manager_car_move-modal">
  2 + <div class="uk-modal-dialog" style="width: 1100px;">
  3 + <a href="" class="uk-modal-close uk-close"></a>
  4 + <div class="uk-modal-header">
  5 + <h2>车辆设备数据迁移</h2></div>
  6 +
  7 + <div class="uk-alert uk-alert-warning">
  8 + 1、新老系统的车辆清单均基于线路配车,你必须保证新老系统的线路配车是一致的。<br>
  9 + 2、只更新车辆当前的设备号,不同步历史的设备变迁记录。
  10 + </div>
  11 + <div class="uk-grid">
  12 + <div class="uk-width-1-5">
  13 + <ul class="uk-nav uk-nav-side line_list" >
  14 + </ul>
  15 + </div>
  16 + <div class="uk-width-4-5 uk-grid table-wrap" id="carDataTables" style="height: 450px;overflow: auto;position: relative;">
  17 + <div class="uk-width-1-2">
  18 + <div>
  19 + <table class="uk-table uk-table-hover nowTable">
  20 + <caption style="color: #2795ed;" >新系统数据</caption>
  21 + <thead>
  22 + <tr>
  23 + <th>车辆自编号</th>
  24 + <th>设备编号</th>
  25 + </tr>
  26 + </thead>
  27 + <tbody>
  28 + </tbody>
  29 + </table>
  30 + </div>
  31 + </div>
  32 + <div class="uk-width-1-2">
  33 + <div>
  34 + <table class="uk-table uk-table-hover oldTable">
  35 + <caption >老系统数据</caption>
  36 + <thead>
  37 + <tr>
  38 + <th>车辆自编号</th>
  39 + <th>设备编号</th>
  40 + </tr>
  41 + </thead>
  42 + <tbody>
  43 + </tbody>
  44 + </table>
  45 + </div>
  46 + </div>
  47 + </div>
  48 + </div>
  49 +
  50 + <div class="uk-modal-footer uk-text-right">
  51 + <em style="margin-right: 15px;">设备号不同的车辆数:<span id="diffCount"></span></em>
  52 + <button type="button" class="uk-button uk-modal-close">取消</button>
  53 + <button type="button" class="uk-button uk-button-primary" id="synchroDevicesBtn">更新设备号有差异的数据</button>
  54 + </div>
  55 + </div>
  56 +
  57 + <script id="data_manager_car_move-table-temp" type="text/html">
  58 + {{each list as car i}}
  59 + <tr data-nbbm="{{car.nbbm}}" data-device="{{car.device}}" {{if car.flag=='now_non-existent'}}style="color:red;"{{/if}}>
  60 + <td>{{car.nbbm}}</td>
  61 + <td {{if car.flag=='device_unequal'}}style="color:red;"{{/if}}>{{car.device}}</td>
  62 + </tr>
  63 + {{/each}}
  64 + </script>
  65 +
  66 + <script>
  67 + (function() {
  68 + var modal = '#data_manager_car_move-modal',
  69 + $ul = $('.line_list', modal),
  70 + nowArray, oldArray;
  71 +
  72 + $(modal).on('init', function(e, data) {
  73 + e.stopPropagation();
  74 +
  75 + //左侧线路list
  76 + var lis = '';
  77 + $.each(gb_data_basic.activeLines, function () {
  78 + lis += '<li data-id="'+this.id+'"><a>'+this.name+'</a></li>';
  79 + });
  80 + $ul.html(lis);
  81 +
  82 + //线路点击事件
  83 + $('li', $ul).on('click', function () {
  84 + if(loading)
  85 + return;
  86 + $('li.uk-active', $ul).removeClass('uk-active');
  87 + $(this).addClass('uk-active');
  88 + //加载车辆数据
  89 + queryCarInfo($(this).data('id'));
  90 + });
  91 +
  92 + //初始化滚动条
  93 + $('.table-wrap', modal).perfectScrollbar({suppressScrollX: true});
  94 +
  95 + //默认点击第一条线路
  96 + $('li:eq(0)', $ul).trigger('click');
  97 + });
  98 +
  99 + /**
  100 + * 加载车辆数据
  101 + * @param lineCode
  102 + */
  103 + var loading, deviceUnequalCount;
  104 + function queryCarInfo(lineId) {
  105 + loading = true;
  106 + deviceUnequalCount = 0;
  107 + gb_common.$get('/dataManager/cars/old_now', {lineId: lineId}, function (rs) {
  108 + console.log('数据迁移 -车辆数据', rs);
  109 + nowArray = rs.nows;
  110 + oldArray = rs.olds;
  111 + $.each(rs.olds, function () {
  112 + var car = searchDevices(rs.nows, this.nbbm);
  113 + if(!car)
  114 + this.flag = 'now_non-existent';//在新系统不存在的车辆
  115 + else if(car.device != this.device){
  116 + car.flag = 'device_unequal';
  117 + deviceUnequalCount ++;
  118 + }
  119 + });
  120 +
  121 + //按新系统数据车辆自编号排序
  122 + rs.nows.sort(function (a, b) {
  123 + return a.nbbm.localeCompare(b.nbbm);
  124 + });
  125 +
  126 + //老系统数据对应新系统顺序,多的放后面
  127 + var ks = {};
  128 + $.each(rs.nows, function (i) {
  129 + ks[this.nbbm] = i;
  130 + });
  131 + rs.olds.sort(function (a, b) {
  132 + return ks[a.nbbm] - ks[b.nbbm];
  133 + });
  134 +
  135 + //渲染新系统表格
  136 + var htmlStr = template('data_manager_car_move-table-temp', {list: rs.nows});
  137 + $('.nowTable tbody', modal).html(htmlStr);
  138 +
  139 + //渲染老系统表格
  140 + var htmlStr = template('data_manager_car_move-table-temp', {list: rs.olds});
  141 + $('.oldTable tbody', modal).html(htmlStr);
  142 +
  143 + $('#diffCount', modal).text(deviceUnequalCount);
  144 + if(deviceUnequalCount==0)
  145 + $('#synchroDevicesBtn', modal).attr('disabled', 'disabled');
  146 + else
  147 + $('#synchroDevicesBtn', modal).removeAttr('disabled');
  148 + loading = false;
  149 + });
  150 + }
  151 +
  152 + function searchDevices(array, nbbm) {
  153 + for(var i =0,item; item=array[i++];){
  154 + if(item.nbbm == nbbm)
  155 + return item;
  156 + }
  157 + }
  158 +
  159 + /**
  160 + * 同步数据
  161 + */
  162 + $('#synchroDevicesBtn', modal).on('click', function () {
  163 + $(this).attr('disabled', 'disabled');
  164 + var data = [];
  165 + $.each(oldArray, function () {
  166 + var car = searchDevices(nowArray, this.nbbm);
  167 + if(car.device != this.device){
  168 + data.push({
  169 + nbbm: this.nbbm,
  170 + device: this.device
  171 + });
  172 + }
  173 + });
  174 +
  175 + gb_common.$post('/dataManager/car/updateDevices', {jsonStr: JSON.stringify(data)}, function (rs) {
  176 + notify_succ('成功更新' + rs.count + '辆车的设备号!');
  177 + //$(this).removeAttr('disabled');
  178 + //刷新表格
  179 + queryCarInfo($('li.uk-active', $ul).data('id'));
  180 + });
  181 + });
  182 + })();
  183 + </script>
  184 +</div>
... ...
src/main/resources/static/real_control_v2/fragments/north/nav/dataManager/dataMoveAndVerification.html 0 → 100644
  1 +<div class="uk-modal" id="data-move-verification-modal">
  2 + <div class="uk-modal-dialog" style="width: 650px;">
  3 + <a href="" class="uk-modal-close uk-close"></a>
  4 + <h2>数据迁移和校验</h2>
  5 +
  6 + <div class="uk-grid" data-uk-grid-margin>
  7 + <div class="uk-width-medium-1-3">
  8 + <a class="uk-panel uk-panel-hover detail_panel" data-href="/real_control_v2/fragments/north/nav/dataManager/cars_move.html">
  9 + <h3 class="uk-panel-title">车辆数据</h3>
  10 + 对照老系统的车辆设备信息,并增量更新到新系统
  11 + </a>
  12 + </div>
  13 + <div class="uk-width-medium-1-3">
  14 + <a class="uk-panel uk-panel-hover" >
  15 + <h3 class="uk-panel-title">人员数据</h3>
  16 + 对照老系统的人员信息,并增量更新到新系统 <code>不可用</code>
  17 + </a>
  18 + </div>
  19 + <div class="uk-width-medium-1-3">
  20 + <a class="uk-panel uk-panel-hover">
  21 + <h3 class="uk-panel-title">路单数据</h3>
  22 + 将老系统指定日期的路单同步到新系统,全量覆盖 <code>不可用</code>
  23 + </a>
  24 + </div>
  25 + </div>
  26 +
  27 + </div>
  28 +
  29 +
  30 + <script>
  31 + (function () {
  32 + var modal = '#data-move-verification-modal';
  33 + $(modal).on('init', function (e, data) {
  34 + e.stopPropagation();
  35 +
  36 + $('.detail_panel', modal).on('click', function () {
  37 + var href = $(this).data('href');
  38 + if(!href)
  39 + return;
  40 +
  41 + open_modal(href, {}, {center: false, bgclose: false, modal: false});
  42 + });
  43 + });
  44 + })();
  45 + </script>
  46 +</div>
0 47 \ No newline at end of file
... ...
src/main/resources/static/real_control_v2/fragments/north/tabs.html
... ... @@ -4,7 +4,7 @@
4 4 <li class="uk-active" ><a>主页</a></li>
5 5 <li id="north_tabs_map_btn"><a>地图</a></li>
6 6 {{each list as line i}}
7   - <li class="tab-line"><a>{{line.name}}(<span id="badge_untreated_num_{{line.lineCode}}">0</span>, <span id="badge_yfwf_num_{{line.lineCode}}">0</span>)</a></li>
  7 + <li class="tab-line" data-code="{{line.lineCode}}"><a>{{line.name}}(<span id="badge_untreated_num_{{line.lineCode}}">0</span>, <span id="badge_yfwf_num_{{line.lineCode}}">0</span>)</a></li>
8 8 {{/each}}
9 9 </ul>
10 10 </script>
... ...
src/main/resources/static/real_control_v2/js/data/json/north_toolbar.json
... ... @@ -26,6 +26,15 @@
26 26 "id": 1.4,
27 27 "text": "历史班次维护",
28 28 "event": "history_sch_maintain"
  29 + },
  30 + {
  31 + "id": 1.5,
  32 + "divider": true
  33 + },
  34 + {
  35 + "id": 1.6,
  36 + "text": "数据迁移和校验工具",
  37 + "event": "data_move_and_verification"
29 38 }
30 39 ],
31 40 [
... ...
src/main/resources/static/real_control_v2/js/forms/wrap.html
... ... @@ -15,12 +15,10 @@
15 15 <!-- 日期控件 -->
16 16 <link href="/metronic_v4.5.4/plugins/bootstrap-datetimepicker-2/css/bootstrap-datetimepicker.min.css"
17 17 rel="stylesheet" type="text/css"/>
18   -
19 18 <!-- layer 弹层 插件 -->
20 19 <link href="/assets/plugins/layer-v2.4/layer/skin/layer.css"
21 20 rel="stylesheet" type="text/css" />
22 21  
23   -
24 22 <!-- jQuery -->
25 23 <script src="/metronic_v4.5.4/plugins/jquery.min.js"></script>
26 24 <script src="/assets/plugins/pinyin.js"></script>
... ...
src/main/resources/static/real_control_v2/js/line_schedule/sch_table.js
... ... @@ -82,7 +82,8 @@ var gb_schedule_table = (function () {
82 82 list: dirData[upDown]
83 83 });
84 84  
85   - $('.schedule-wrap .card-panel:eq(' + upDown + ')', this).html(htmlStr);
  85 + $('.schedule-wrap .card-panel:eq(' + upDown + ')', this)
  86 + .html(htmlStr);
86 87 }
87 88  
88 89 //标记车辆最后一个班次
... ... @@ -91,6 +92,8 @@ var gb_schedule_table = (function () {
91 92 gb_sch_legend.init(this);
92 93 });
93 94 var content = $('.line_schedule .ct_table_wrap');
  95 + //初始化滚动条
  96 + content.perfectScrollbar({suppressScrollX: true});
94 97 //fixed table head
95 98 gb_ct_table.fixedHead(content);
96 99 //enable sort
... ... @@ -213,7 +216,7 @@ var gb_schedule_table = (function () {
213 216 //计算应发未发
214 217 calc_yfwf_num(lineCode);
215 218 //重新固定表头
216   - gb_ct_table.fixedHead($('.line_schedule .ct_table_wrap', tabCont));
  219 + gb_ct_table.fixedHead($('.schedule-wrap .ct_table_wrap', tabCont));
217 220  
218 221 //重新初始化排序
219 222 gb_ct_table.enableSort($('.ct_table', tabCont), reset_seq_no, gb_schedule_table_dbclick.init);
... ... @@ -221,6 +224,8 @@ var gb_schedule_table = (function () {
221 224 gb_schedule_table_dbclick.init();
222 225 //重新初始化双击实发发车信息微调
223 226 gb_schedule_table_dbclick.sfsjCellClick($('dd.fcsjActualCell', tabCont));
  227 + //滚动条
  228 + $('.schedule-wrap .ct_table_wrap', tabCont).perfectScrollbar({suppressScrollX: true});
224 229 }
225 230 };
226 231  
... ...
src/main/resources/static/real_control_v2/js/main.js
... ... @@ -49,7 +49,7 @@ var gb_main_ep = new EventProxy(),
49 49 $('li.map-panel', '#main-tab-content').load('/real_control_v2/mapmonitor/real.html');
50 50 }, 1000);
51 51 //弹出更新说明
52   - //showUpdateDescription();
  52 + showUpdateDescription();
53 53 });
54 54  
55 55 function g_emit(id) {
... ... @@ -171,8 +171,8 @@ var disabled_submit_btn = function (form) {
171 171 function showUpdateDescription() {
172 172 //更新说明
173 173 var updateDescription = {
174   - date: '2017-01-07',
175   - text: '<h5>1、出场子任务开放使用。</h5><h5>2、班次直放调整后可再次修改班次类型。</h5><h5>3、双击实发,可打开发车信息微调,发车信息微调界面可以直接烂班。</h5><h5>4、主页模拟图可以省略、重命名站点。</h5>'
  174 + date: '2017-04-18',
  175 + text: '<h5>可在 菜单栏 数据&统计→ 数据迁移和校验→ 车辆数据 功能内同步老系统的车辆设备号</h5>'
176 176 };
177 177  
178 178 var storage = window.localStorage
... ...
src/main/resources/static/real_control_v2/js/north/tabs.js
... ... @@ -24,6 +24,15 @@ var gb_tabs = (function() {
24 24 }
25 25 });
26 26  
  27 + //班次选项卡第一次点击,更新滚动条高度
  28 + $('.north-tabs .uk-tab li.tab-line').one('click', function(e){
  29 + var code = $(this).data('code');
  30 + setTimeout(function () {
  31 + $('.main-container .line_schedule[data-id='+code+'] .schedule-wrap .ct_table_wrap')
  32 + .perfectScrollbar('update');
  33 + }, 200);
  34 + });
  35 +
27 36 cb && cb();
28 37 });
29 38 };
... ...
src/main/resources/static/real_control_v2/js/north/toolbar.js
... ... @@ -194,6 +194,9 @@ var gb_northToolbar = (function () {
194 194 },
195 195 safe_driving: function () {
196 196 open_modal('/real_control_v2/fragments/north/nav/safeDriving.html', {}, modal_opts);
  197 + },
  198 + data_move_and_verification: function () {
  199 + open_modal('/real_control_v2/fragments/north/nav/dataManager/dataMoveAndVerification.html', {}, modal_opts);
197 200 }
198 201 };
199 202  
... ...
src/main/resources/static/real_control_v2/main.html
... ... @@ -12,6 +12,7 @@
12 12 href="/real_control_v2/assets/plugins/uikit-2.27.1/components/autocomplete.gradient.min.css" merge="plugins"/>
13 13 <link rel="stylesheet" href="/real_control_v2/assets/plugins/uikit-2.27.1/components/accordion.gradient.min.css" merge="plugins"/>
14 14 <link rel="stylesheet" href="/real_control_v2/assets/plugins/uikit-2.27.1/components/slidenav.gradient.min.css" merge="plugins"/>
  15 + <link rel="stylesheet" href="/real_control_v2/assets/plugins/uikit-2.27.1/components/sticky.gradient.min.css" merge="plugins"/>
15 16  
16 17 <!-- main style -->
17 18 <link rel="stylesheet" href="/real_control_v2/css/main.css" />
... ... @@ -35,6 +36,8 @@
35 36 <link rel="stylesheet" href="/real_control_v2/css/pace.css" merge="plugins"/>
36 37  
37 38 <link rel="stylesheet" href="/real_control_v2/css/modal_extend.css" merge="custom_style"/>
  39 + <!-- perfect-scrollbar style -->
  40 + <link rel="stylesheet" href="/real_control_v2/assets/plugins/perfect-scrollbar/perfect-scrollbar.css" merge="plugins"/>
38 41 </head>
39 42  
40 43 <body>
... ... @@ -105,6 +108,8 @@
105 108 <script src="/assets/plugins/jquery.serializejson.js" merge="plugins"></script>
106 109 <!-- moment.js 日期处理类库 -->
107 110 <script src="/assets/plugins/moment-with-locales.js"></script>
  111 +<!-- perfect-scrollbar -->
  112 +<script src="/real_control_v2/assets/plugins/perfect-scrollbar/perfect-scrollbar.jquery.js" merge="plugins"></script>
108 113 <!-- common js -->
109 114 <script src="/real_control_v2/js/common.js"></script>
110 115 <!-- art-template 模版引擎 -->
... ... @@ -124,6 +129,8 @@
124 129 <script src="/real_control_v2/assets/plugins/uikit-2.27.1/components/accordion.min.js" merge="uikit_js"></script>
125 130 <script src="/real_control_v2/assets/plugins/uikit-2.27.1/components/timepicker.min.js" merge="uikit_js"></script>
126 131 <script src="/real_control_v2/assets/plugins/uikit-2.27.1/components/lightbox.min.js" merge="uikit_js"></script>
  132 +<script src="/real_control_v2/assets/plugins/uikit-2.27.1/components/sticky.min.js" merge="uikit_js"></script>
  133 +
127 134  
128 135 <!-- jquery contextMenu -->
129 136 <script src="/real_control_v2/assets/js/jquery.contextMenu.min.js" merge="plugins"></script>
... ...
src/test/java/com/bsth/service/schedule/rules/SchedulePlan1Test.java 0 → 100644
  1 +package com.bsth.service.schedule.rules;
  2 +
  3 +import com.bsth.service.schedule.BaseTest;
  4 +import org.dbunit.database.DatabaseConnection;
  5 +import org.dbunit.database.IDatabaseConnection;
  6 +import org.dbunit.dataset.IDataSet;
  7 +import org.dbunit.dataset.xml.FlatXmlDataSetBuilder;
  8 +import org.dbunit.operation.DatabaseOperation;
  9 +import org.junit.After;
  10 +import org.junit.Before;
  11 +import org.junit.Test;
  12 +import org.slf4j.Logger;
  13 +import org.slf4j.LoggerFactory;
  14 +import org.springframework.beans.factory.annotation.Autowired;
  15 +import org.springframework.core.io.ClassPathResource;
  16 +import org.springframework.core.io.Resource;
  17 +
  18 +import javax.sql.DataSource;
  19 +
  20 +/**
  21 + * 排班计划测试(手工排班测试)。
  22 + */
  23 +public class SchedulePlan1Test extends BaseTest {
  24 + /** 日志记录器 */
  25 + private static final Logger logger = LoggerFactory.getLogger(SchedulePlan1Test.class);
  26 +
  27 + @Autowired
  28 + private DataSource dataSource;
  29 +
  30 + /**
  31 + * 初始化数据。
  32 + */
  33 + @Before
  34 + public void initData() throws Exception {
  35 + logger.info("载入数据......");
  36 +
  37 + // 获取数据库连接
  38 + IDatabaseConnection iDatabaseConnection = new DatabaseConnection(dataSource.getConnection());
  39 + // 获取Dbunit数据源
  40 + Resource res = new ClassPathResource("testdata/d2.xml");
  41 + FlatXmlDataSetBuilder flatXmlDataSetBuilder = new FlatXmlDataSetBuilder();
  42 + flatXmlDataSetBuilder.setColumnSensing(false);
  43 + flatXmlDataSetBuilder.setCaseSensitiveTableNames(false);
  44 + IDataSet iDataSet = flatXmlDataSetBuilder.build(res.getInputStream());
  45 +
  46 + // 载入数据
  47 + DatabaseOperation.CLEAN_INSERT.execute(iDatabaseConnection, iDataSet);
  48 + }
  49 +
  50 + /**
  51 + * 清除数据。
  52 + */
  53 + @After
  54 + public void destoryData() throws Exception {
  55 + logger.info("清除数据......");
  56 + // 获取数据库连接
  57 + IDatabaseConnection iDatabaseConnection = new DatabaseConnection(dataSource.getConnection());
  58 + // 获取Dbunit数据源
  59 + Resource res = new ClassPathResource("testdata/d2.xml");
  60 + FlatXmlDataSetBuilder flatXmlDataSetBuilder = new FlatXmlDataSetBuilder();
  61 + flatXmlDataSetBuilder.setColumnSensing(false);
  62 + flatXmlDataSetBuilder.setCaseSensitiveTableNames(false);
  63 + IDataSet iDataSet = flatXmlDataSetBuilder.build(res.getInputStream());
  64 +
  65 + // 清除数据
  66 + DatabaseOperation.DELETE_ALL.execute(iDatabaseConnection, iDataSet);
  67 + }
  68 +
  69 +
  70 + @Test
  71 + public void t1() {
  72 +
  73 + }
  74 +
  75 +
  76 +
  77 +
  78 +
  79 +
  80 +
  81 +
  82 +
  83 +
  84 +
  85 +
  86 +
  87 +
  88 +
  89 +
  90 +
  91 +
  92 +
  93 +
  94 +}
... ...
src/test/java/com/bsth/service/schedule/rules/SchedulePlan2Test.java 0 → 100644
  1 +package com.bsth.service.schedule.rules;
  2 +
  3 +/**
  4 + * 时刻表测试(自动排班测试)。
  5 + */
  6 +public class SchedulePlan2Test {
  7 + // TODO:
  8 +}
... ...
src/test/resources/testdata/new.txt 0 → 100644
  1 +1、车狼配置,每辆车都可以配置单独的停车点及相关数据,并提供两种设置模式(早晚,复驶)
  2 +2、规则管理,修改规则的界面图形化,更加方便修改
  3 +3、时刻表管理,导入时刻表xls做严格数据判定,时刻表明细修改提供跟方便的图形化修改方式
  4 +4、排班计划管理,提供每次排班的操作信息,时间段,所使用的时刻表,可以查看具体的排班明细(细化到班次)
  5 + 生成排班时,提供详细的时刻表统计信息,提供两种排班模式(历史排班优先,规则优先)
  6 +5、调度值勤日报,列出每天的基于线路,路牌的排班统计,可以更换车辆,人员
  7 + 此功能从排班计划中抽取出来,单独列出,供调派人员使用
0 8 \ No newline at end of file
... ...
src/test/resources/testdata/test1.txt 0 → 100644
  1 +select * from jwgl_f_t_clxh_workflow_detail a where a.ID_LYSYLB = 36;
  2 +
  3 +select sum(amount - tl_amount) from jwgl_f_t_clxh_workflow_detail
  4 +where
  5 +to_date(statdateid, 'YYYYMMDD') >= to_date('20170301', 'YYYYMMDD')
  6 +and to_date(statdateid, 'YYYYMMDD') <= to_date('20170331', 'YYYYMMDD')
  7 +
  8 +select * from JWGL_D_T_LYSYLB
  9 +
  10 +-- all xh
  11 +
  12 +select
  13 +statdateid statdate
  14 +, ssjc gs
  15 +, xl xl
  16 +, zbh cl
  17 +, b.SYLB1 || '-' || b.SYLB2 as lylb
  18 +, (sum(amount) - sum(tl_amount)) ch
  19 +from JWGL_F_T_CLXH_WORKFLOW_DETAIL a, JWGL_D_T_LYSYLB b
  20 +where
  21 +to_date(statdateid, 'YYYYMMDD') >= to_date('20170301', 'YYYYMMDD')
  22 +and to_date(statdateid, 'YYYYMMDD') <= to_date('20170331', 'YYYYMMDD')
  23 +and a.ID_LYSYLB = b.ID(+)
  24 +group by
  25 +statdateid
  26 +, ssjc
  27 +, xl
  28 +, zbh
  29 +, b.SYLB1 || '-' || b.SYLB2
  30 +
  31 +-- part1
  32 +
  33 +select sum(ch) from
  34 +(
  35 +select
  36 +statdateid statdate
  37 +, ssjc gs
  38 +, xl xl
  39 +, zbh cl
  40 +, b.SYLB1 || '-' || b.SYLB2 as lylb
  41 +, (sum(amount) - sum(tl_amount)) ch
  42 +from JWGL_F_T_CLXH_WORKFLOW_DETAIL a, JWGL_D_T_LYSYLB b
  43 +where
  44 +to_date(statdateid, 'YYYYMMDD') >= to_date('20170301', 'YYYYMMDD')
  45 +and to_date(statdateid, 'YYYYMMDD') <= to_date('20170331', 'YYYYMMDD')
  46 +and a.ID_LYSYLB = b.ID(+)
  47 +group by
  48 +statdateid
  49 +, ssjc
  50 +, xl
  51 +, zbh
  52 +, b.SYLB1 || '-' || b.SYLB2
  53 +)
  54 +where lylb in (
  55 +'路救-路救',
  56 +'小修-小修机工',
  57 +'专项-安检',
  58 +'专项-节检',
  59 +'专项-水箱',
  60 +'专项-电瓶',
  61 +'小修-小修电工',
  62 +'专项-电并',
  63 +'小修-小修车身',
  64 +'专项-镗固',
  65 +'保养-一级保养',
  66 +'小修-发动机',
  67 +'专项-轮胎',
  68 +'分摊-轮胎',
  69 +'专项-润滑油',
  70 +'总成-差变速',
  71 +'总成-大泵',
  72 +'总成-小总成',
  73 +'总成-发动机',
  74 +'保养-二级保养',
  75 +'保养-三级保养',
  76 +'整修-整修',
  77 +'空调-保外',
  78 +'空调-保内',
  79 +'事故-事故'
  80 +)
  81 +
  82 +-- part2
  83 +
  84 +select sum(ch) from
  85 +(
  86 +select
  87 +statdateid statdate
  88 +, ssjc gs
  89 +, xl xl
  90 +, zbh cl
  91 +, b.SYLB1 || '-' || b.SYLB2 as lylb
  92 +, (sum(amount) - sum(tl_amount)) ch
  93 +from JWGL_F_T_CLXH_WORKFLOW_DETAIL a, JWGL_D_T_LYSYLB b
  94 +where
  95 +to_date(statdateid, 'YYYYMMDD') >= to_date('20170301', 'YYYYMMDD')
  96 +and to_date(statdateid, 'YYYYMMDD') <= to_date('20170331', 'YYYYMMDD')
  97 +and a.ID_LYSYLB = b.ID(+)
  98 +group by
  99 +statdateid
  100 +, ssjc
  101 +, xl
  102 +, zbh
  103 +, b.SYLB1 || '-' || b.SYLB2
  104 +)
  105 +where lylb in(
  106 +'分摊-镗固',
  107 +'专项-机油',
  108 +'分摊-机油',
  109 +'总成-其它',
  110 +'分摊-工具',
  111 +'分摊-辅助料',
  112 +'分摊-设备',
  113 +'车间经费-车间经费'
  114 +)
  115 +
  116 +
  117 +
  118 +
  119 +
  120 +
  121 +
  122 +
  123 +
  124 +
  125 +
  126 +
  127 +
  128 +
  129 +
  130 +
  131 +
  132 +
  133 +
... ...
src/test/resources/testdata/test2.txt 0 → 100644
  1 +
  2 +select * from JWGL_FR_T_CH_REPORT_DATA1;
  3 +
  4 +select * from JWGL_FR_T_CH_REPORT_DATA2;
  5 +
  6 +-- sum part1
  7 +
  8 +select
  9 +(
  10 +sum(lj_lj) + sum(xx_xxjg) + sum(xx_xxdg) + sum(zx_db) + sum(xx_xxcs) + sum(zx_tg) + sum(by_b1) +
  11 +sum(nvl(future_bx, 0)) + sum(xx_fdj) + sum(zx_lt) + sum(zx_rhy) + sum(zc_cbx) + sum(zc_db) + sum(zc_xzc) +
  12 +sum(zc_fdj) + sum(by_b2) + sum(by_b3) + sum(nvl(future_wx_db, 0)) + sum(nvl(future_wxfy, 0)) + sum(nvl(future_ktwx, 0)) + sum(nvl(future_sx, 0)) +
  13 +sum(nvl(future_dp, 0)) + sum(zx_zx) + sum(kt_bw) + sum(sg_sg)
  14 +) as part1
  15 +from JWGL_FR_T_CH_REPORT_DATA1
  16 +where
  17 +statdate >= to_date('20170301', 'YYYYMMDD')
  18 +and statdate <= to_date('20170331', 'YYYYMMDD')
  19 +
  20 +-- sum part2
  21 +
  22 +select
  23 +(
  24 +sum(zx_tg) + sum(jy) + sum(qt) + sum(zcfl) + sum(gj) + sum(sb) + sum(cjjf)
  25 +) as part2
  26 +from JWGL_FR_T_CH_REPORT_DATA2
  27 +where statdate = to_date('20170331', 'YYYYMMDD')
0 28 \ No newline at end of file
... ...