Commit 1a0396f8ae843424173663658b992ead79e75f60

Authored by 潘钊
1 parent aadde91f

update

Showing 33 changed files with 1335 additions and 312 deletions
src/main/java/com/bsth/entity/realcontrol/ScheduleRealInfo.java
... ... @@ -565,13 +565,8 @@ public class ScheduleRealInfo {
565 565 this.setFcsjT(sdfyyyyMMddHHmm.parse(this.realExecDate + " " + this.getFcsj()).getTime());
566 566 //待发时间戳
567 567 this.setDfsjT(this.getFcsjT());
568   -
569   - //计划终点时间
570   - if(this.getBcsj() != null){
571   - Date zdDate = new Date(this.getFcsjT() + (this.getBcsj() * 60 * 1000));
572   - this.setZdsjT(zdDate.getTime());
573   - this.setZdsj(sdfHHmm.format(zdDate));
574   - }
  568 + //计算终点时间
  569 + calcEndTime();
575 570  
576 571 if(this.fcsjActual != null)
577 572 this.setFcsjActualAll(this.fcsjActual);
... ... @@ -582,6 +577,15 @@ public class ScheduleRealInfo {
582 577 e.printStackTrace();
583 578 }
584 579 }
  580 +
  581 + public void calcEndTime(){
  582 + //计划终点时间
  583 + if(this.getBcsj() != null){
  584 + Date zdDate = new Date(this.getDfsjT() + (this.getBcsj() * 60 * 1000));
  585 + this.setZdsjT(zdDate.getTime());
  586 + this.setZdsj(sdfHHmm.format(zdDate));
  587 + }
  588 + }
585 589  
586 590 public Integer getDirectiveState() {
587 591 return directiveState;
... ...
src/main/java/com/bsth/service/realcontrol/impl/ScheduleRealInfoServiceImpl.java
... ... @@ -47,6 +47,7 @@ import com.bsth.util.TransGPS;
47 47 import com.bsth.util.TransGPS.Location;
48 48 import com.bsth.vehicle.BorrowCenter;
49 49 import com.bsth.vehicle.common.CommonMapped;
  50 +import com.bsth.websocket.handler.SendUtils;
50 51 import com.google.common.base.Splitter;
51 52 import com.google.common.collect.ArrayListMultimap;
52 53 import com.google.common.collect.Lists;
... ... @@ -79,6 +80,9 @@ public class ScheduleRealInfoServiceImpl extends BaseServiceImpl<ScheduleRealInf
79 80  
80 81 @Autowired
81 82 ChildTaskPlanRepository cTaskPlanRepository;
  83 +
  84 + @Autowired
  85 + SendUtils sendUtils;
82 86  
83 87 Logger logger = LoggerFactory.getLogger(this.getClass());
84 88  
... ... @@ -119,11 +123,21 @@ public class ScheduleRealInfoServiceImpl extends BaseServiceImpl<ScheduleRealInf
119 123 schedule.setsName(spyArray[1]);
120 124 }
121 125  
  126 + List<ScheduleRealInfo> ts = new ArrayList<>();
  127 + ts.add(schedule);
  128 + //调整终点时间和下一个班次的应到时间
  129 + schedule.calcEndTime();
  130 + ScheduleRealInfo nextSch = ScheduleBuffer.getNext(schedule);
  131 + if(null != nextSch){
  132 + nextSch.setQdzArrDateJH(schedule.getZdsj());
  133 + ts.add(nextSch);
  134 + }
  135 +
122 136 // 持久化到数据库
123 137 ScheduleBuffer.persistentList.add(schedule);
124 138  
125 139 map.put("status", ResponseCode.SUCCESS);
126   - map.put("t", schedule);
  140 + map.put("ts", ts);
127 141 } catch (Exception e) {
128 142 logger.error("", e);
129 143 map.put("status", ResponseCode.ERROR);
... ... @@ -522,8 +536,10 @@ public class ScheduleRealInfoServiceImpl extends BaseServiceImpl&lt;ScheduleRealInf
522 536 ts.add(sch.getTwins());
523 537  
524 538 rs.put("status", ResponseCode.SUCCESS);
525   - //rs.put("t", sch);
526 539 rs.put("ts", ts);
  540 +
  541 + //通知页面刷新
  542 + sendUtils.refreshSch(ts);
527 543 } catch (Exception e) {
528 544 logger.error("", e);
529 545 rs.put("status", ResponseCode.ERROR);
... ... @@ -694,8 +710,10 @@ public class ScheduleRealInfoServiceImpl extends BaseServiceImpl&lt;ScheduleRealInf
694 710 sch.setZdsjActualAll(zdsjActual);
695 711 //下一班次起点到达时间
696 712 ScheduleRealInfo next = ScheduleBuffer.getNext(sch);
697   - next.setQdzArrDateSJ(zdsjActual);
698   - ts.add(next);
  713 + if(null != next){
  714 + next.setQdzArrDateSJ(zdsjActual);
  715 + ts.add(next);
  716 + }
699 717 }
700 718 }
701 719 else {
... ...
src/main/java/com/bsth/vehicle/directive/controller/DirectiveController.java
... ... @@ -15,7 +15,6 @@ import org.springframework.web.bind.annotation.RestController;
15 15  
16 16 import com.bsth.entity.sys.SysUser;
17 17 import com.bsth.security.util.SecurityUtils;
18   -import com.bsth.util.DateUtils;
19 18 import com.bsth.vehicle.directive.entity.Directive80;
20 19 import com.bsth.vehicle.directive.service.DirectiveService;
21 20  
... ... @@ -81,7 +80,7 @@ public class DirectiveController {
81 80 * @param @param upDon
82 81 * @throws
83 82 */
84   - @RequestMapping(value = "/upDownChange", method = RequestMethod.GET)
  83 + @RequestMapping(value = "/upDownChange", method = RequestMethod.POST)
85 84 public int upDownChange(@RequestParam String nbbm, @RequestParam Integer upDown){
86 85 SysUser user = SecurityUtils.getCurrentUser();
87 86 return directiveService.upDownChange(nbbm, upDown, user.getUserName());
... ...
src/main/java/com/bsth/vehicle/directive/service/DirectiveServiceImpl.java
... ... @@ -105,11 +105,13 @@ public class DirectiveServiceImpl extends BaseServiceImpl&lt;Directive60, Integer&gt;
105 105 return -2;
106 106 }*/
107 107  
108   - String text = "已完成" + finish + "个班次,下一发车时间" + sdfHHmm.format(new Date(sch.getFcsjT())) + ",由"
  108 + String text = "已完成" + finish + "个班次,下一发车时间" + sdfHHmm.format(new Date(sch.getDfsjT())) + ",由"
109 109 + sch.getQdzName() + "发往" + sch.getZdzName();
110 110  
111   - // 目前使用短语协议下发调度指令
112   - directive = create60Data(sch.getClZbh(), text, (short) 0x00, sch);
  111 + ScheduleRealInfo nextSch = ScheduleBuffer.getNext(sch);
  112 + //下发0x02指令 调度指令(闹钟有效)
  113 + directive = DirectiveDataFactory.createDirective6002(sch.getClZbh(), text, (short) 0x02
  114 + , Integer.parseInt(nextSch.getXlDir()), 0, new Date(System.currentTimeMillis() + 1000 * 30));
113 115 } catch (Exception e) {
114 116 logger.error("生成调度指令时出现异常", e);
115 117 return -1;
... ...
src/main/java/com/bsth/vehicle/directive/thread/FirstScheduleIssuedThread.java
... ... @@ -57,14 +57,10 @@ public class FirstScheduleIssuedThread extends Thread{
57 57  
58 58 sch = list.get(0);
59 59  
60   - if(sch.getOpDirectiveState() < 100
  60 + if(sch.getOpDirectiveState() == null
61 61 && sch.getStatus() == 0
62 62 && Math.abs(sch.getDfsjT() - t) < space){
63 63  
64   - /*if(sch.getDirectiveState() == -1){
65   - //发送调度指令
66   - directiveService.send60Dispatch(sch, 0);
67   - }*/
68 64 logger.info("切换首班运营状态, " + sch.getClZbh());
69 65 //切换营运状态
70 66 directiveService.send60Operation(sch.getClZbh()
... ... @@ -73,19 +69,5 @@ public class FirstScheduleIssuedThread extends Thread{
73 69 }
74 70 }
75 71 }
76   -
77   - /*Set<String> keys = ScheduleBuffer.vehLinkedMap.keySet();
78   - LinkedList<ScheduleRealInfo> linkedList;
79   - ScheduleRealInfo sch;
80   - for(String nbbm : keys){
81   - linkedList = ScheduleBuffer.vehLinkedMap.get(nbbm);
82   -
83   - sch = linkedList.getFirst();
84   -
85   - //没有完成班次,且头班车没有发车时间
86   - if(!ScheduleBuffer.finishLinkedMap.containsKey(nbbm)
87   - && sch.getFcsjActual() == null)
88   - directiveService.send60Dispatch(sch, 0);
89   - }*/
90 72 }
91 73 }
... ...
src/main/java/com/bsth/vehicle/directive/util/DirectiveDataFactory.java
1 1 package com.bsth.vehicle.directive.util;
2 2  
  3 +import java.text.SimpleDateFormat;
  4 +import java.util.Date;
3 5 import java.util.HashMap;
4 6 import java.util.Map;
5 7  
... ... @@ -82,6 +84,45 @@ public class DirectiveDataFactory {
82 84 return directive;
83 85 }
84 86  
  87 +
  88 + static SimpleDateFormat sdfMMddHHmm = new SimpleDateFormat("MMddHHmm");
  89 + public static Directive60 createDirective6002(String nbbm, String text, Short dispatchInstruct, int upDown, int state, Date alarmTime){
  90 + Long timestamp = System.currentTimeMillis();
  91 +
  92 + Short company = Short.parseShort(CommonMapped.vehicCompanyMap.get(nbbm));
  93 + String deviceId = CommonMapped.vehicDeviceBiMap.inverse().get(nbbm);
  94 +
  95 + int msgId = MsgIdGenerator.getMsgId();
  96 +
  97 + Directive60 directive = new Directive60();
  98 + DirectiveData data = new DirectiveData();
  99 + // 一级协议
  100 + directive.setOperCode((short) 0x60);
  101 + // 设备号
  102 + directive.setDeviceId(deviceId);
  103 + // 时间戳
  104 + directive.setTimestamp(timestamp);
  105 + directive.setMsgId(msgId);
  106 + // 构造数据
  107 + data.setDeviceId(deviceId);
  108 + data.setDispatchInstruct(dispatchInstruct);
  109 + data.setTimestamp(timestamp);
  110 + data.setCompanyCode(company);
  111 + data.setMsgId(msgId);
  112 + data.setAlarmTime(Long.parseLong(sdfMMddHHmm.format(alarmTime)));
  113 + directive.setData(data);
  114 + long serviceState;
  115 + try {
  116 + serviceState = Consts.SERVICE_STATE[upDown][state];
  117 + } catch (IndexOutOfBoundsException e) {
  118 + // 未知营运状态的直接默认为上行非营运
  119 + serviceState = Consts.SERVICE_STATE[0][1];
  120 + }
  121 + data.setServiceState(serviceState);
  122 + data.setTxtContent(text);
  123 + return directive;
  124 + }
  125 +
85 126 /**
86 127 *
87 128 * @Title: createDirective64
... ...
src/main/java/com/bsth/vehicle/gpsdata/arrival/ThreadPoolTask.java
... ... @@ -24,8 +24,8 @@ public class ThreadPoolTask implements Runnable {
24 24 ArrayListMultimap<String, ScheduleRealInfo> alMap = ArrayListMultimap.create();
25 25  
26 26 for(ScheduleRealInfo sch : allList){
27   - //停车场即起点站的进出场班次不参与匹配
28   - if(!sch.isParkIsFirstStation())
  27 + //停车场即起点站的进出场班次不参与匹配,烂班也不参与
  28 + if(!sch.isParkIsFirstStation() && sch.isDestroy())
29 29 alMap.put(sch.getClZbh(), sch);
30 30 }
31 31  
... ... @@ -36,7 +36,6 @@ public class ThreadPoolTask implements Runnable {
36 36 for(String nbbm : ks){
37 37 srMatcher = new ScheduleRealMatcher(alMap.get(nbbm), ArrivalDataBuffer.pops(nbbm));
38 38  
39   - //在这里应用各种匹配规则
40 39 srMatcher
41 40 .timeClosest()
42 41 .matchEnd();
... ...
src/main/java/com/bsth/vehicle/gpsdata/arrival/match/ScheduleRealMatcher.java
1 1 package com.bsth.vehicle.gpsdata.arrival.match;
2 2  
3   -import java.text.SimpleDateFormat;
4 3 import java.util.ArrayList;
5 4 import java.util.Collections;
6 5 import java.util.Comparator;
7   -import java.util.Date;
8   -import java.util.HashMap;
9 6 import java.util.List;
10   -import java.util.Map;
11 7  
12 8 import org.slf4j.Logger;
13 9 import org.slf4j.LoggerFactory;
... ... @@ -21,9 +17,7 @@ import com.bsth.service.realcontrol.buffer.ScheduleBuffer;
21 17 import com.bsth.vehicle.directive.service.DirectiveService;
22 18 import com.bsth.vehicle.gpsdata.arrival.entity.RealTimeModel;
23 19 import com.bsth.vehicle.gpsdata.entity.ArrivalInfo;
24   -import com.bsth.websocket.handler.RealControlSocketHandler;
25   -import com.fasterxml.jackson.core.JsonProcessingException;
26   -import com.fasterxml.jackson.databind.ObjectMapper;
  20 +import com.bsth.websocket.handler.SendUtils;
27 21  
28 22 /**
29 23 *
... ... @@ -35,9 +29,6 @@ import com.fasterxml.jackson.databind.ObjectMapper;
35 29 @Component
36 30 public class ScheduleRealMatcher implements ApplicationContextAware{
37 31  
38   - // Spring应用上下文环境
39   - private static ApplicationContext applicationContext;
40   -
41 32 /** 班次列表 */
42 33 List<ScheduleRealInfo> schs;
43 34  
... ... @@ -50,11 +41,13 @@ public class ScheduleRealMatcher implements ApplicationContextAware{
50 41 /** 进站数据 */
51 42 List<ArrivalInfo> inArrivals = new ArrayList<>();
52 43  
53   - private static RealControlSocketHandler socketHandler;
54 44  
55   - private static DirectiveService directiveService;
  45 + // Spring应用上下文环境
  46 + private static ApplicationContext applicationContext;
  47 +
  48 + static SendUtils sendUtils;
56 49  
57   - SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");
  50 + static DirectiveService directiveService;
58 51  
59 52 Logger logger = LoggerFactory.getLogger(ScheduleRealMatcher.class);
60 53  
... ... @@ -135,10 +128,11 @@ public class ScheduleRealMatcher implements ApplicationContextAware{
135 128  
136 129 if(sch.isFirstStationIsPark()){
137 130 ScheduleBuffer.persistentList.add(sch.getTwins());
138   - sendFcsj(sch.getTwins());//推送到页面
  131 + //起点即停车场 的关联班次推送
  132 + sendUtils.sendFcsj(sch.getTwins());//推送到页面
139 133 }
140 134  
141   - sendFcsj(sch);//推送到页面
  135 + sendUtils.sendFcsj(sch);//推送到页面
142 136 }
143 137  
144 138 //终点到达
... ... @@ -151,7 +145,7 @@ public class ScheduleRealMatcher implements ApplicationContextAware{
151 145  
152 146 if(sch.isFirstStationIsPark()){
153 147 ScheduleBuffer.persistentList.add(sch.getTwins());
154   - sendFcsj(sch.getTwins());//推送到页面
  148 + sendUtils.sendFcsj(sch.getTwins());//推送到页面
155 149 }
156 150  
157 151 finish = ScheduleBuffer.getFinishSchNo(sch.getClZbh());
... ... @@ -159,10 +153,6 @@ public class ScheduleRealMatcher implements ApplicationContextAware{
159 153 if(nextSch != null){
160 154 //发送下一班次的调度指令(并切换营运状态)
161 155 directiveService.send60Dispatch(nextSch, finish, null);
162   -
163   - //upDown = Integer.parseInt(nextSch.getXlDir());
164   - //切换下一个班次的走向
165   - //directiveService.send60Operation(nextSch.getClZbh(), 0, upDown, nextSch, null);
166 156 }
167 157 else{
168 158 upDown = Integer.parseInt(sch.getXlDir());
... ... @@ -171,68 +161,15 @@ public class ScheduleRealMatcher implements ApplicationContextAware{
171 161 directiveService.send60Operation(sch.getClZbh(), 1, upDown, sch, null);
172 162 }
173 163  
174   - sendZdsj(sch, nextSch, finish);//推送到页面
  164 + sendUtils.sendZdsj(sch, nextSch, finish);//推送到页面
175 165 }
176 166 }
177 167 }
178   -
179   - /**
180   - * @throws JsonProcessingException
181   - * @throws NumberFormatException
182   - * @Title: sendFcsj
183   - * @Description: TODO(推送发车信息)
184   - * @param @param schedule 班次
185   - * @throws
186   - */
187   - public void sendFcsj(ScheduleRealInfo schedule) {
188   -
189   - Map<String, Object> map = new HashMap<>();
190   - map.put("fn", "faChe");
191   - map.put("t", schedule);
192   - map.put("dataStr", sdf.format(new Date()));
193   -
194   - ObjectMapper mapper = new ObjectMapper();
195   -
196   - try{
197   - socketHandler.sendMessageToLine(Integer.parseInt(schedule.getXlBm()), mapper.writeValueAsString(map));
198   - }catch(Exception e){
199   - //e.printStackTrace();
200   - logger.error("", e);
201   - }
202   - }
203   -
204   - /**
205   - * @throws JsonProcessingException
206   - * @throws NumberFormatException
207   - * @Title: sendFcsj
208   - * @Description: TODO(推送到达终点时间)
209   - * @param @param schedule 班次
210   - * @throws
211   - */
212   - public void sendZdsj(ScheduleRealInfo schedule,ScheduleRealInfo nextSch, int finish) {
213   -
214   - Map<String, Object> map = new HashMap<>();
215   - map.put("fn", "zhongDian");
216   - map.put("t", schedule);
217   - map.put("nt", nextSch);
218   - map.put("finish", finish);
219   - map.put("dataStr", sdf.format(new Date()));
220   -
221   - ObjectMapper mapper = new ObjectMapper();
222   -
223   - try{
224   - socketHandler.sendMessageToLine(Integer.parseInt(schedule.getXlBm()), mapper.writeValueAsString(map));
225   - }catch(Exception e){
226   - //e.printStackTrace();
227   - logger.error("", e);
228   - }
229   - }
230 168  
231 169 @Override
232 170 public void setApplicationContext(ApplicationContext arg0) throws BeansException {
233 171 applicationContext = arg0;
234   -
235   - socketHandler = applicationContext.getBean(RealControlSocketHandler.class);
  172 + sendUtils = applicationContext.getBean(SendUtils.class);
236 173 directiveService = applicationContext.getBean(DirectiveService.class);
237 174 }
238 175 }
... ...
src/main/java/com/bsth/websocket/handler/SendUtils.java 0 → 100644
  1 +package com.bsth.websocket.handler;
  2 +
  3 +import java.text.SimpleDateFormat;
  4 +import java.util.Date;
  5 +import java.util.HashMap;
  6 +import java.util.List;
  7 +import java.util.Map;
  8 +
  9 +import org.slf4j.Logger;
  10 +import org.slf4j.LoggerFactory;
  11 +import org.springframework.beans.factory.annotation.Autowired;
  12 +import org.springframework.stereotype.Component;
  13 +
  14 +import com.bsth.entity.realcontrol.ScheduleRealInfo;
  15 +import com.fasterxml.jackson.databind.ObjectMapper;
  16 +
  17 +@Component
  18 +public class SendUtils{
  19 +
  20 + @Autowired
  21 + private RealControlSocketHandler socketHandler;
  22 +
  23 + private static SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");
  24 +
  25 + private static Logger logger = LoggerFactory.getLogger(SendUtils.class);
  26 +
  27 + /**
  28 + * @throws JsonProcessingException
  29 + * TODO(推送发车信息)
  30 + */
  31 + public void sendFcsj(ScheduleRealInfo schedule) {
  32 +
  33 + Map<String, Object> map = new HashMap<>();
  34 + map.put("fn", "faChe");
  35 + map.put("t", schedule);
  36 + map.put("dataStr", sdf.format(new Date()));
  37 +
  38 + ObjectMapper mapper = new ObjectMapper();
  39 +
  40 + try {
  41 + socketHandler.sendMessageToLine(Integer.parseInt(schedule.getXlBm()), mapper.writeValueAsString(map));
  42 + } catch (Exception e) {
  43 + logger.error("", e);
  44 + }
  45 + }
  46 +
  47 + /**
  48 + *
  49 + * @Title: sendFcsjArtificial
  50 + * @Description: TODO(要求页面刷新班次)
  51 + * @throws
  52 + */
  53 + public void refreshSch(List<ScheduleRealInfo> list){
  54 + if(null == list || list.size() == 0)
  55 + return;
  56 +
  57 + Map<String, Object> map = new HashMap<>();
  58 + map.put("fn", "refreshSch");
  59 + map.put("ts", list);
  60 +
  61 + ObjectMapper mapper = new ObjectMapper();
  62 +
  63 + try {
  64 + socketHandler.sendMessageToLine(Integer.parseInt(list.get(0).getXlBm()), mapper.writeValueAsString(map));
  65 + } catch (Exception e) {
  66 + logger.error("", e);
  67 + }
  68 + }
  69 +
  70 + /**
  71 + * @throws JsonProcessingException
  72 + * @throws NumberFormatException @Title: sendFcsj @Description:
  73 + * TODO(推送到达终点时间) @param @param schedule 班次 @throws
  74 + */
  75 + public void sendZdsj(ScheduleRealInfo schedule, ScheduleRealInfo nextSch, int finish) {
  76 +
  77 + Map<String, Object> map = new HashMap<>();
  78 + map.put("fn", "zhongDian");
  79 + map.put("t", schedule);
  80 + map.put("nt", nextSch);
  81 + map.put("finish", finish);
  82 + map.put("dataStr", sdf.format(new Date()));
  83 +
  84 + ObjectMapper mapper = new ObjectMapper();
  85 +
  86 + try {
  87 + socketHandler.sendMessageToLine(Integer.parseInt(schedule.getXlBm()), mapper.writeValueAsString(map));
  88 + } catch (Exception e) {
  89 + logger.error("", e);
  90 + }
  91 + }
  92 +}
... ...
src/main/resources/fatso/start.js
... ... @@ -11,7 +11,7 @@ var fs = require(&#39;fs&#39;)
11 11 ,crypto = require("crypto");
12 12  
13 13 //不参与的目录
14   -var excludes = ['scheduleApp', 'trafficManage']
  14 +var excludes = ['scheduleApp', 'trafficManage', 'control']
15 15 ,ep = new EventProxy()
16 16 ,pName = 'bsth_control'
17 17 ,path = process.cwd()
... ...
src/main/resources/static/assets/js/eventproxy.js 0 → 100644
  1 +/*global define*/
  2 +!(function (name, definition) {
  3 + // Check define
  4 + var hasDefine = typeof define === 'function',
  5 + // Check exports
  6 + hasExports = typeof module !== 'undefined' && module.exports;
  7 +
  8 + if (hasDefine) {
  9 + // AMD Module or CMD Module
  10 + define('eventproxy_debug', function () {return function () {};});
  11 + define(['eventproxy_debug'], definition);
  12 + } else if (hasExports) {
  13 + // Node.js Module
  14 + module.exports = definition(require('debug')('eventproxy'));
  15 + } else {
  16 + // Assign to common namespaces or simply the global object (window)
  17 + this[name] = definition();
  18 + }
  19 +})('EventProxy', function (debug) {
  20 + debug = debug || function () {};
  21 +
  22 + /*!
  23 + * refs
  24 + */
  25 + var SLICE = Array.prototype.slice;
  26 + var CONCAT = Array.prototype.concat;
  27 + var ALL_EVENT = '__all__';
  28 +
  29 + /**
  30 + * EventProxy. An implementation of task/event based asynchronous pattern.
  31 + * A module that can be mixed in to *any object* in order to provide it with custom events.
  32 + * You may `bind` or `unbind` a callback function to an event;
  33 + * `trigger`-ing an event fires all callbacks in succession.
  34 + * Examples:
  35 + * ```js
  36 + * var render = function (template, resources) {};
  37 + * var proxy = new EventProxy();
  38 + * proxy.assign("template", "l10n", render);
  39 + * proxy.trigger("template", template);
  40 + * proxy.trigger("l10n", resources);
  41 + * ```
  42 + */
  43 + var EventProxy = function () {
  44 + if (!(this instanceof EventProxy)) {
  45 + return new EventProxy();
  46 + }
  47 + this._callbacks = {};
  48 + this._fired = {};
  49 + };
  50 +
  51 + /**
  52 + * Bind an event, specified by a string name, `ev`, to a `callback` function.
  53 + * Passing __ALL_EVENT__ will bind the callback to all events fired.
  54 + * Examples:
  55 + * ```js
  56 + * var proxy = new EventProxy();
  57 + * proxy.addListener("template", function (event) {
  58 + * // TODO
  59 + * });
  60 + * ```
  61 + * @param {String} eventname Event name.
  62 + * @param {Function} callback Callback.
  63 + */
  64 + EventProxy.prototype.addListener = function (ev, callback) {
  65 + debug('Add listener for %s', ev);
  66 + this._callbacks[ev] = this._callbacks[ev] || [];
  67 + this._callbacks[ev].push(callback);
  68 + return this;
  69 + };
  70 + /**
  71 + * `addListener` alias, `bind`
  72 + */
  73 + EventProxy.prototype.bind = EventProxy.prototype.addListener;
  74 + /**
  75 + * `addListener` alias, `on`
  76 + */
  77 + EventProxy.prototype.on = EventProxy.prototype.addListener;
  78 + /**
  79 + * `addListener` alias, `subscribe`
  80 + */
  81 + EventProxy.prototype.subscribe = EventProxy.prototype.addListener;
  82 +
  83 + /**
  84 + * Bind an event, but put the callback into head of all callbacks.
  85 + * @param {String} eventname Event name.
  86 + * @param {Function} callback Callback.
  87 + */
  88 + EventProxy.prototype.headbind = function (ev, callback) {
  89 + debug('Add listener for %s', ev);
  90 + this._callbacks[ev] = this._callbacks[ev] || [];
  91 + this._callbacks[ev].unshift(callback);
  92 + return this;
  93 + };
  94 +
  95 + /**
  96 + * Remove one or many callbacks.
  97 + *
  98 + * - If `callback` is null, removes all callbacks for the event.
  99 + * - If `eventname` is null, removes all bound callbacks for all events.
  100 + * @param {String} eventname Event name.
  101 + * @param {Function} callback Callback.
  102 + */
  103 + EventProxy.prototype.removeListener = function (eventname, callback) {
  104 + var calls = this._callbacks;
  105 + if (!eventname) {
  106 + debug('Remove all listeners');
  107 + this._callbacks = {};
  108 + } else {
  109 + if (!callback) {
  110 + debug('Remove all listeners of %s', eventname);
  111 + calls[eventname] = [];
  112 + } else {
  113 + var list = calls[eventname];
  114 + if (list) {
  115 + var l = list.length;
  116 + for (var i = 0; i < l; i++) {
  117 + if (callback === list[i]) {
  118 + debug('Remove a listener of %s', eventname);
  119 + list[i] = null;
  120 + }
  121 + }
  122 + }
  123 + }
  124 + }
  125 + return this;
  126 + };
  127 + /**
  128 + * `removeListener` alias, unbind
  129 + */
  130 + EventProxy.prototype.unbind = EventProxy.prototype.removeListener;
  131 +
  132 + /**
  133 + * Remove all listeners. It equals unbind()
  134 + * Just add this API for as same as Event.Emitter.
  135 + * @param {String} event Event name.
  136 + */
  137 + EventProxy.prototype.removeAllListeners = function (event) {
  138 + return this.unbind(event);
  139 + };
  140 +
  141 + /**
  142 + * Bind the ALL_EVENT event
  143 + */
  144 + EventProxy.prototype.bindForAll = function (callback) {
  145 + this.bind(ALL_EVENT, callback);
  146 + };
  147 +
  148 + /**
  149 + * Unbind the ALL_EVENT event
  150 + */
  151 + EventProxy.prototype.unbindForAll = function (callback) {
  152 + this.unbind(ALL_EVENT, callback);
  153 + };
  154 +
  155 + /**
  156 + * Trigger an event, firing all bound callbacks. Callbacks are passed the
  157 + * same arguments as `trigger` is, apart from the event name.
  158 + * Listening for `"all"` passes the true event name as the first argument.
  159 + * @param {String} eventname Event name
  160 + * @param {Mix} data Pass in data
  161 + */
  162 + EventProxy.prototype.trigger = function (eventname, data) {
  163 + var list, ev, callback, i, l;
  164 + var both = 2;
  165 + var calls = this._callbacks;
  166 + debug('Emit event %s with data %j', eventname, data);
  167 + while (both--) {
  168 + ev = both ? eventname : ALL_EVENT;
  169 + list = calls[ev];
  170 + if (list) {
  171 + for (i = 0, l = list.length; i < l; i++) {
  172 + if (!(callback = list[i])) {
  173 + list.splice(i, 1);
  174 + i--;
  175 + l--;
  176 + } else {
  177 + var args = [];
  178 + var start = both ? 1 : 0;
  179 + for (var j = start; j < arguments.length; j++) {
  180 + args.push(arguments[j]);
  181 + }
  182 + callback.apply(this, args);
  183 + }
  184 + }
  185 + }
  186 + }
  187 + return this;
  188 + };
  189 +
  190 + /**
  191 + * `trigger` alias
  192 + */
  193 + EventProxy.prototype.emit = EventProxy.prototype.trigger;
  194 + /**
  195 + * `trigger` alias
  196 + */
  197 + EventProxy.prototype.fire = EventProxy.prototype.trigger;
  198 +
  199 + /**
  200 + * Bind an event like the bind method, but will remove the listener after it was fired.
  201 + * @param {String} ev Event name
  202 + * @param {Function} callback Callback
  203 + */
  204 + EventProxy.prototype.once = function (ev, callback) {
  205 + var self = this;
  206 + var wrapper = function () {
  207 + callback.apply(self, arguments);
  208 + self.unbind(ev, wrapper);
  209 + };
  210 + this.bind(ev, wrapper);
  211 + return this;
  212 + };
  213 +
  214 + var later = (typeof setImmediate !== 'undefined' && setImmediate) ||
  215 + (typeof process !== 'undefined' && process.nextTick) || function (fn) {
  216 + setTimeout(fn, 0);
  217 + };
  218 +
  219 + /**
  220 + * emitLater
  221 + * make emit async
  222 + */
  223 + EventProxy.prototype.emitLater = function () {
  224 + var self = this;
  225 + var args = arguments;
  226 + later(function () {
  227 + self.trigger.apply(self, args);
  228 + });
  229 + };
  230 +
  231 + /**
  232 + * Bind an event, and trigger it immediately.
  233 + * @param {String} ev Event name.
  234 + * @param {Function} callback Callback.
  235 + * @param {Mix} data The data that will be passed to calback as arguments.
  236 + */
  237 + EventProxy.prototype.immediate = function (ev, callback, data) {
  238 + this.bind(ev, callback);
  239 + this.trigger(ev, data);
  240 + return this;
  241 + };
  242 + /**
  243 + * `immediate` alias
  244 + */
  245 + EventProxy.prototype.asap = EventProxy.prototype.immediate;
  246 +
  247 + var _assign = function (eventname1, eventname2, cb, once) {
  248 + var proxy = this;
  249 + var argsLength = arguments.length;
  250 + var times = 0;
  251 + var flag = {};
  252 +
  253 + // Check the arguments length.
  254 + if (argsLength < 3) {
  255 + return this;
  256 + }
  257 +
  258 + var events = SLICE.call(arguments, 0, -2);
  259 + var callback = arguments[argsLength - 2];
  260 + var isOnce = arguments[argsLength - 1];
  261 +
  262 + // Check the callback type.
  263 + if (typeof callback !== "function") {
  264 + return this;
  265 + }
  266 + debug('Assign listener for events %j, once is %s', events, !!isOnce);
  267 + var bind = function (key) {
  268 + var method = isOnce ? "once" : "bind";
  269 + proxy[method](key, function (data) {
  270 + proxy._fired[key] = proxy._fired[key] || {};
  271 + proxy._fired[key].data = data;
  272 + if (!flag[key]) {
  273 + flag[key] = true;
  274 + times++;
  275 + }
  276 + });
  277 + };
  278 +
  279 + var length = events.length;
  280 + for (var index = 0; index < length; index++) {
  281 + bind(events[index]);
  282 + }
  283 +
  284 + var _all = function (event) {
  285 + if (times < length) {
  286 + return;
  287 + }
  288 + if (!flag[event]) {
  289 + return;
  290 + }
  291 + var data = [];
  292 + for (var index = 0; index < length; index++) {
  293 + data.push(proxy._fired[events[index]].data);
  294 + }
  295 + if (isOnce) {
  296 + proxy.unbindForAll(_all);
  297 + }
  298 + debug('Events %j all emited with data %j', events, data);
  299 + callback.apply(null, data);
  300 + };
  301 + proxy.bindForAll(_all);
  302 + };
  303 +
  304 + /**
  305 + * Assign some events, after all events were fired, the callback will be executed once.
  306 + *
  307 + * Examples:
  308 + * ```js
  309 + * proxy.all(ev1, ev2, callback);
  310 + * proxy.all([ev1, ev2], callback);
  311 + * proxy.all(ev1, [ev2, ev3], callback);
  312 + * ```
  313 + * @param {String} eventname1 First event name.
  314 + * @param {String} eventname2 Second event name.
  315 + * @param {Function} callback Callback, that will be called after predefined events were fired.
  316 + */
  317 + EventProxy.prototype.all = function (eventname1, eventname2, callback) {
  318 + var args = CONCAT.apply([], arguments);
  319 + args.push(true);
  320 + _assign.apply(this, args);
  321 + return this;
  322 + };
  323 + /**
  324 + * `all` alias
  325 + */
  326 + EventProxy.prototype.assign = EventProxy.prototype.all;
  327 +
  328 + /**
  329 + * Assign the only one 'error' event handler.
  330 + * @param {Function(err)} callback
  331 + */
  332 + EventProxy.prototype.fail = function (callback) {
  333 + var that = this;
  334 +
  335 + that.once('error', function () {
  336 + that.unbind();
  337 + // put all arguments to the error handler
  338 + // fail(function(err, args1, args2, ...){})
  339 + callback.apply(null, arguments);
  340 + });
  341 + return this;
  342 + };
  343 +
  344 + /**
  345 + * A shortcut of ep#emit('error', err)
  346 + */
  347 + EventProxy.prototype.throw = function () {
  348 + var that = this;
  349 + that.emit.apply(that, ['error'].concat(SLICE.call(arguments)));
  350 + };
  351 +
  352 + /**
  353 + * Assign some events, after all events were fired, the callback will be executed first time.
  354 + * Then any event that predefined be fired again, the callback will executed with the newest data.
  355 + * Examples:
  356 + * ```js
  357 + * proxy.tail(ev1, ev2, callback);
  358 + * proxy.tail([ev1, ev2], callback);
  359 + * proxy.tail(ev1, [ev2, ev3], callback);
  360 + * ```
  361 + * @param {String} eventname1 First event name.
  362 + * @param {String} eventname2 Second event name.
  363 + * @param {Function} callback Callback, that will be called after predefined events were fired.
  364 + */
  365 + EventProxy.prototype.tail = function () {
  366 + var args = CONCAT.apply([], arguments);
  367 + args.push(false);
  368 + _assign.apply(this, args);
  369 + return this;
  370 + };
  371 + /**
  372 + * `tail` alias, assignAll
  373 + */
  374 + EventProxy.prototype.assignAll = EventProxy.prototype.tail;
  375 + /**
  376 + * `tail` alias, assignAlways
  377 + */
  378 + EventProxy.prototype.assignAlways = EventProxy.prototype.tail;
  379 +
  380 + /**
  381 + * The callback will be executed after the event be fired N times.
  382 + * @param {String} eventname Event name.
  383 + * @param {Number} times N times.
  384 + * @param {Function} callback Callback, that will be called after event was fired N times.
  385 + */
  386 + EventProxy.prototype.after = function (eventname, times, callback) {
  387 + if (times === 0) {
  388 + callback.call(null, []);
  389 + return this;
  390 + }
  391 + var proxy = this,
  392 + firedData = [];
  393 + this._after = this._after || {};
  394 + var group = eventname + '_group';
  395 + this._after[group] = {
  396 + index: 0,
  397 + results: []
  398 + };
  399 + debug('After emit %s times, event %s\'s listenner will execute', times, eventname);
  400 + var all = function (name, data) {
  401 + if (name === eventname) {
  402 + times--;
  403 + firedData.push(data);
  404 + if (times < 1) {
  405 + debug('Event %s was emit %s, and execute the listenner', eventname, times);
  406 + proxy.unbindForAll(all);
  407 + callback.apply(null, [firedData]);
  408 + }
  409 + }
  410 + if (name === group) {
  411 + times--;
  412 + proxy._after[group].results[data.index] = data.result;
  413 + if (times < 1) {
  414 + debug('Event %s was emit %s, and execute the listenner', eventname, times);
  415 + proxy.unbindForAll(all);
  416 + callback.call(null, proxy._after[group].results);
  417 + }
  418 + }
  419 + };
  420 + proxy.bindForAll(all);
  421 + return this;
  422 + };
  423 +
  424 + /**
  425 + * The `after` method's helper. Use it will return ordered results.
  426 + * If you need manipulate result, you need callback
  427 + * Examples:
  428 + * ```js
  429 + * var ep = new EventProxy();
  430 + * ep.after('file', files.length, function (list) {
  431 + * // Ordered results
  432 + * });
  433 + * for (var i = 0; i < files.length; i++) {
  434 + * fs.readFile(files[i], 'utf-8', ep.group('file'));
  435 + * }
  436 + * ```
  437 + * @param {String} eventname Event name, shoule keep consistent with `after`.
  438 + * @param {Function} callback Callback function, should return the final result.
  439 + */
  440 + EventProxy.prototype.group = function (eventname, callback) {
  441 + var that = this;
  442 + var group = eventname + '_group';
  443 + var index = that._after[group].index;
  444 + that._after[group].index++;
  445 + return function (err, data) {
  446 + if (err) {
  447 + // put all arguments to the error handler
  448 + return that.emit.apply(that, ['error'].concat(SLICE.call(arguments)));
  449 + }
  450 + that.emit(group, {
  451 + index: index,
  452 + // callback(err, args1, args2, ...)
  453 + result: callback ? callback.apply(null, SLICE.call(arguments, 1)) : data
  454 + });
  455 + };
  456 + };
  457 +
  458 + /**
  459 + * The callback will be executed after any registered event was fired. It only executed once.
  460 + * @param {String} eventname1 Event name.
  461 + * @param {String} eventname2 Event name.
  462 + * @param {Function} callback The callback will get a map that has data and eventname attributes.
  463 + */
  464 + EventProxy.prototype.any = function () {
  465 + var proxy = this,
  466 + callback = arguments[arguments.length - 1],
  467 + events = SLICE.call(arguments, 0, -1),
  468 + _eventname = events.join("_");
  469 +
  470 + debug('Add listenner for Any of events %j emit', events);
  471 + proxy.once(_eventname, callback);
  472 +
  473 + var _bind = function (key) {
  474 + proxy.bind(key, function (data) {
  475 + debug('One of events %j emited, execute the listenner');
  476 + proxy.trigger(_eventname, {"data": data, eventName: key});
  477 + });
  478 + };
  479 +
  480 + for (var index = 0; index < events.length; index++) {
  481 + _bind(events[index]);
  482 + }
  483 + };
  484 +
  485 + /**
  486 + * The callback will be executed when the event name not equals with assigned event.
  487 + * @param {String} eventname Event name.
  488 + * @param {Function} callback Callback.
  489 + */
  490 + EventProxy.prototype.not = function (eventname, callback) {
  491 + var proxy = this;
  492 + debug('Add listenner for not event %s', eventname);
  493 + proxy.bindForAll(function (name, data) {
  494 + if (name !== eventname) {
  495 + debug('listenner execute of event %s emit, but not event %s.', name, eventname);
  496 + callback(data);
  497 + }
  498 + });
  499 + };
  500 +
  501 + /**
  502 + * Success callback wrapper, will handler err for you.
  503 + *
  504 + * ```js
  505 + * fs.readFile('foo.txt', ep.done('content'));
  506 + *
  507 + * // equal to =>
  508 + *
  509 + * fs.readFile('foo.txt', function (err, content) {
  510 + * if (err) {
  511 + * return ep.emit('error', err);
  512 + * }
  513 + * ep.emit('content', content);
  514 + * });
  515 + * ```
  516 + *
  517 + * ```js
  518 + * fs.readFile('foo.txt', ep.done('content', function (content) {
  519 + * return content.trim();
  520 + * }));
  521 + *
  522 + * // equal to =>
  523 + *
  524 + * fs.readFile('foo.txt', function (err, content) {
  525 + * if (err) {
  526 + * return ep.emit('error', err);
  527 + * }
  528 + * ep.emit('content', content.trim());
  529 + * });
  530 + * ```
  531 + * @param {Function|String} handler, success callback or event name will be emit after callback.
  532 + * @return {Function}
  533 + */
  534 + EventProxy.prototype.done = function (handler, callback) {
  535 + var that = this;
  536 + return function (err, data) {
  537 + if (err) {
  538 + // put all arguments to the error handler
  539 + return that.emit.apply(that, ['error'].concat(SLICE.call(arguments)));
  540 + }
  541 +
  542 + // callback(err, args1, args2, ...)
  543 + var args = SLICE.call(arguments, 1);
  544 +
  545 + if (typeof handler === 'string') {
  546 + // getAsync(query, ep.done('query'));
  547 + // or
  548 + // getAsync(query, ep.done('query', function (data) {
  549 + // return data.trim();
  550 + // }));
  551 + if (callback) {
  552 + // only replace the args when it really return a result
  553 + return that.emit(handler, callback.apply(null, args));
  554 + } else {
  555 + // put all arguments to the done handler
  556 + //ep.done('some');
  557 + //ep.on('some', function(args1, args2, ...){});
  558 + return that.emit.apply(that, [handler].concat(args));
  559 + }
  560 + }
  561 +
  562 + // speed improve for mostly case: `callback(err, data)`
  563 + if (arguments.length <= 2) {
  564 + return handler(data);
  565 + }
  566 +
  567 + // callback(err, args1, args2, ...)
  568 + handler.apply(null, args);
  569 + };
  570 + };
  571 +
  572 + /**
  573 + * make done async
  574 + * @return {Function} delay done
  575 + */
  576 + EventProxy.prototype.doneLater = function (handler, callback) {
  577 + var _doneHandler = this.done(handler, callback);
  578 + return function (err, data) {
  579 + var args = arguments;
  580 + later(function () {
  581 + _doneHandler.apply(null, args);
  582 + });
  583 + };
  584 + };
  585 +
  586 + /**
  587 + * Create a new EventProxy
  588 + * Examples:
  589 + * ```js
  590 + * var ep = EventProxy.create();
  591 + * ep.assign('user', 'articles', function(user, articles) {
  592 + * // do something...
  593 + * });
  594 + * // or one line ways: Create EventProxy and Assign
  595 + * var ep = EventProxy.create('user', 'articles', function(user, articles) {
  596 + * // do something...
  597 + * });
  598 + * ```
  599 + * @return {EventProxy} EventProxy instance
  600 + */
  601 + EventProxy.create = function () {
  602 + var ep = new EventProxy();
  603 + var args = CONCAT.apply([], arguments);
  604 + if (args.length) {
  605 + var errorHandler = args[args.length - 1];
  606 + var callback = args[args.length - 2];
  607 + if (typeof errorHandler === 'function' && typeof callback === 'function') {
  608 + args.pop();
  609 + ep.fail(errorHandler);
  610 + }
  611 + ep.assign.apply(ep, args);
  612 + }
  613 + return ep;
  614 + };
  615 +
  616 + // Backwards compatibility
  617 + EventProxy.EventProxy = EventProxy;
  618 +
  619 + return EventProxy;
  620 +});
... ...
src/main/resources/static/pages/control/line/child_pages/deviceReport.html
... ... @@ -66,7 +66,7 @@
66 66 </td>
67 67  
68 68 {{if item.c0 != null && item.c0.data != null}}
69   - <td>{{item.c0.timeStr}}</td>
  69 + <td>{{item.handleTimeStr}}</td>
70 70 <td>
71 71 {{if item.c0.data.requestAck==6 }}
72 72 <span class="label label-sm label-success"> 同意</span>
... ... @@ -85,11 +85,14 @@
85 85  
86 86 <script>
87 87 !function(){
  88 + var storage = window.localStorage;
88 89 var page=0,pSize=12
89 90 ,$form = $('#deviceReportPanel form')
90 91 ,$car = $('#deviceReportPanel #carSelect')
91 92 ,$table = $('#deviceReportPanel table');
92 93  
  94 + var reqCodeMap = {0xA1: '请求恢复运营', 0xA2: '申请调档', 0xA3: '出场请求', 0xA5: '进场请求', 0xA7: '加油请求', 0x50: '车辆故障', 0x70: '路阻报告', 0x60: '事故报告', 0x11: '扣证纠纷', 0x12 : '报警'};
  95 +
93 96 var lineNameMap = JSON.parse(storage.getItem('lineIds'));
94 97 //初始加载数据
95 98 jsDoQuery(true);
... ... @@ -109,8 +112,9 @@
109 112 //命令字转中文
110 113 $.each(rs.content, function(){
111 114 this.text = reqCodeMap[this.data.requestCode];
112   - if(this.c0)
113   - this.c0.timeStr = moment(this.c0.timestamp).format('HH:mm');
  115 +
  116 + if(this.handleTime)
  117 + this.handleTimeStr = moment(this.handleTime).format('HH:mm');
114 118 //线路名转换
115 119 this.lineName = lineNameMap[this.data.lineId];
116 120 });
... ...
src/main/resources/static/pages/control/line/child_pages/ttsConfigure.html
... ... @@ -6,6 +6,16 @@
6 6 <form class="form-horizontal" role="form">
7 7 <div class="form-body">
8 8 <div class="form-group">
  9 + <label class="col-md-3 control-label">启用 TTS</label>
  10 + <div class="col-md-9">
  11 + <select class="form-control input-inline input-medium" name="enable">
  12 + <option value="1">启用</option>
  13 + <option value="0">禁用</option>
  14 + </select>
  15 + </div>
  16 + </div>
  17 +
  18 + <div class="form-group">
9 19 <label class="col-md-3 control-label">发音速度</label>
10 20 <div class="col-md-9">
11 21 <input type="number" name="rate" class="form-control input-inline input-medium" min="0.1" max="10">
... ... @@ -43,6 +53,7 @@
43 53 ,text = $('#ttsConfigurePanel #ttsText').text()
44 54 ,queueModel = $('#ttsConfigurePanel select[name=queueModel]')
45 55 ,rate = $('#ttsConfigurePanel input[name=rate]')
  56 + ,enable = $('#ttsConfigurePanel select[name=enable]')
46 57 ,saveButton = $('#ttsConfigurePanel button.saveCofig');
47 58  
48 59 ttsPlay.on('click', function(){
... ... @@ -66,15 +77,15 @@
66 77 return;
67 78 }
68 79  
69   - var code = h5Speech.setCofig(rate.val(), queueModel.val());
  80 + var code = h5Speech.setCofig(rate.val(), queueModel.val(), enable.val());
70 81 if(code == 1)
71 82 layer.msg('修改成功!');
72 83 });
73 84  
74 85 //初始化
75 86 var ttsConfig = h5Speech.getCofig();
76   - console.log('ttsConfig', ttsConfig);
77 87 rate.val(ttsConfig.rate);
78 88 queueModel.val(ttsConfig.queueModel).trigger('change');
  89 + enable.val(ttsConfig.enable);
79 90 }();
80 91 </script>
81 92 \ No newline at end of file
... ...
src/main/resources/static/pages/control/line/css/lineControl.css
  1 +.load-anim .spinner {
  2 + width: 60px;
  3 + height: 60px;
  4 + background-color: #29c282;
  5 + margin: 10px auto;
  6 +
  7 + -webkit-animation: rotateplane 1.2s infinite ease-in-out;
  8 + animation: rotateplane 1.2s infinite ease-in-out;
  9 +}
  10 +
  11 +@-webkit-keyframes rotateplane {
  12 + 0% { -webkit-transform: perspective(120px) }
  13 + 50% { -webkit-transform: perspective(120px) rotateY(180deg) }
  14 + 100% { -webkit-transform: perspective(120px) rotateY(180deg) rotateX(180deg) }
  15 +}
  16 +
  17 +@keyframes rotateplane {
  18 + 0% {
  19 + transform: perspective(120px) rotateX(0deg) rotateY(0deg);
  20 + -webkit-transform: perspective(120px) rotateX(0deg) rotateY(0deg)
  21 + } 50% {
  22 + transform: perspective(120px) rotateX(-180.1deg) rotateY(0deg);
  23 + -webkit-transform: perspective(120px) rotateX(-180.1deg) rotateY(0deg)
  24 + } 100% {
  25 + transform: perspective(120px) rotateX(-180deg) rotateY(-179.9deg);
  26 + -webkit-transform: perspective(120px) rotateX(-180deg) rotateY(-179.9deg);
  27 + }
  28 +}
  29 +
1 30 .portlet.light > .portlet-title.banner{
2 31 padding: 17px 20px 0px 20px;
3 32 border-bottom: none;
... ... @@ -24,9 +53,53 @@
24 53  
25 54 .load-anim{
26 55 position: fixed;z-index: 9999999;width: 100%;height: 100%;
27   - background: rgba(8, 47, 74, 0.89);top: 0;left: 0;
  56 + background: rgb(255, 255, 255);top: 0;left: 0;
  57 +
  58 +}
  59 +
  60 +.load-anim .load-anim-list{
  61 + position: absolute;
  62 + width: 320px;
  63 + height: 260px;
  64 + top: 0;
  65 + left: 0;
  66 + right: 0;
  67 + bottom: 0;
  68 + margin: auto;
28 69 }
29   -.load-anim .loader{
  70 +
  71 +.load-anim .load-anim-list .item {
  72 + color: #082f4a;
  73 + padding: 11px;
  74 + font-size: 15px;
  75 + font-family: 微软雅黑;
  76 + background: #ffffff;
  77 + margin: 3px 0;
  78 + box-shadow: 0 8px 17px 0 rgba(0,0,0,0.2),0 6px 20px 0 rgba(0,0,0,0.19);
  79 + border-radius: 2px !important;
  80 + border: 1px solid #e8e5e5;
  81 + position: relative;
  82 +
  83 +}
  84 +
  85 +.load-anim .load-anim-list .item.success{
  86 + transition: all .3s ease;
  87 + background: #29c282;
  88 + color: white;
  89 + border: 1px solid #29c282;
  90 +}
  91 +
  92 +.load-anim .load-anim-list .item.success:before{
  93 + font: normal normal normal 14px/1 FontAwesome;
  94 + content: "\f00c";
  95 + position: absolute;
  96 + top:12px;
  97 + right: 15px;
  98 + font-size: 18px;
  99 + color: white;
  100 +}
  101 +
  102 +/*.load-anim .loader{
30 103 margin: auto !important;
31 104 position: absolute;
32 105 top: 0;
... ... @@ -36,7 +109,7 @@
36 109 }
37 110  
38 111  
39   -.load8 .loader {
  112 + .load8 .loader {
40 113 font-size: 10px;
41 114 text-indent: -9999em;
42 115 border-top: 1.1em solid rgba(255, 255, 255, 0.2);
... ... @@ -84,7 +157,7 @@ label {
84 157 transform: translate(-50%);
85 158 font-size: 14px;
86 159 font-family: 仿宋;
87   -}
  160 +} */
88 161 body{
89 162 overflow: hidden;
90 163 }
... ... @@ -188,7 +261,7 @@ body{
188 261  
189 262 .portlet-fullscreen .nav-tabs > li > a>span{
190 263 color: #C3C3C3;
191   - font-size: 12px;
  264 + font-size: 14px;
192 265 }
193 266  
194 267 .portlet-fullscreen .nav-tabs > li > a:hover
... ... @@ -2241,7 +2314,7 @@ tr._active .blue-badge{
2241 2314 .pb-table tr.selected.dir_1 td.tl-xxrd,
2242 2315 .pb-table tr.selected.next-sch td.tl-xxrd{
2243 2316 background: none;
2244   - color: #5cb0e9;
  2317 + color: #bde4ff;
2245 2318 }
2246 2319  
2247 2320 .table-bordered>tbody>tr._tr_active.active-line-no>td{
... ... @@ -2362,4 +2435,27 @@ tr._tr_active.active-line-no .out-badge{
2362 2435 margin-left: 5px;
2363 2436 vertical-align: bottom;
2364 2437 cursor: pointer;
  2438 +}
  2439 +
  2440 +.tab_line .panel-wrap ._panel.sch_table_panel.lock{
  2441 + border: 1px solid #3598dc;
  2442 + box-shadow: 0 2px 5px 0 rgba(53, 152, 220, 0.4),0 2px 10px 0 rgba(53, 152, 220, 0.4);
  2443 +}
  2444 +
  2445 +.tab_line .panel-wrap ._panel.sch_table_panel.lock:before{
  2446 + font: normal normal normal 14px/1 FontAwesome;
  2447 + content: "\f023";
  2448 + position: absolute;
  2449 + right: 15px;
  2450 + color: red;
  2451 + font-size: 18px;
  2452 +
  2453 + animation: topShow .5s;
  2454 + animation-fill-mode: forwards;
  2455 +
  2456 +}
  2457 +
  2458 +@keyframes topShow{
  2459 +0% {top: 0; color: rgba(255, 0, 0, 0.19);}
  2460 +100% {top: 12px;color: rgba(255, 0, 0, 1);}
2365 2461 }
2366 2462 \ No newline at end of file
... ...
src/main/resources/static/pages/control/line/index.html
1 1 <link href="/pages/control/line/css/lineControl.css" rel="stylesheet" type="text/css" />
2 2 <link href="/metronic_v4.5.4/css/animate.min.css" rel="stylesheet" type="text/css" />
3 3  
4   -<!-- 初始load动画 -->
5   -<div class="load-anim load8" >
6   -<div class="loader">Loading...</div>
  4 +<!-- 初始load界面 -->
  5 +<div class="load-anim" >
  6 + <div class="load-anim-list">
  7 + <div class="spinner"></div>
  8 + <!-- <div class="item load_resource">加载资源文件...</div> -->
  9 +<!-- <div class="item">校准客户端时间...</div>
  10 + <div class="item">加载GPS模块...</div>
  11 + <div class="item">加载班次信息...</div>
  12 + <div class="item">webSocket 连接...</div> -->
  13 + </div>
7 14 </div>
8 15  
9 16 <div class="portlet light portlet-fullscreen" style="transition: all .5s ease;padding: 0;" oncontextmenu=self.event.returnValue=false>
... ... @@ -24,31 +31,6 @@
24 31 <button type="button" class="btn btn-default" id="msgAndDirect">
25 32 <i class="fa fa-bell"></i> 调度指令</button>
26 33  
27   - <!-- <div class="btn-group">
28   - <button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown" disabled>
29   - <i class="fa fa-database"></i> 基本信息
30   - <i class="fa fa-angle-down"></i>
31   - </button>
32   - <ul class="dropdown-menu">
33   - <li>
34   - <a href="javascript:;"> 人员信息 </a>
35   - </li>
36   - <li>
37   - <a href="javascript:;"> 车辆信息 </a>
38   - </li>
39   - <li>
40   - <a href="javascript:;"> 线路信息 </a>
41   - </li>
42   - <li>
43   - <a href="javascript:;"> 线路标准信息 </a>
44   - </li>
45   - <li>
46   - <a href="javascript:;"> 调度短语 </a>
47   - </li>
48   - </ul>
49   - </div> -->
50   -
51   -
52 34 <div class="btn-group">
53 35 <button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown" >
54 36 <i class="fa fa-gavel"></i> 系统设置
... ... @@ -58,6 +40,12 @@
58 40 <li>
59 41 <a href="javascript:;" id="ttsConfigure"> TTS 语音设置 </a>
60 42 </li>
  43 + <!-- <li>
  44 + <a href="javascript:;" id="reply80Config"> 设备上报处理 </a>
  45 + </li>
  46 + <li>
  47 + <a href="javascript:;" id=""> 停靠时间 </a>
  48 + </li> -->
61 49 </ul>
62 50 </div>
63 51  
... ... @@ -154,12 +142,6 @@
154 142 <span class="menu-text">临加/子任务</span>
155 143 </button>
156 144 </li>
157   -<!-- <li class="menu-item disabled" >
158   - <button type="button" class="menu-btn">
159   - <i class="fa fa-reply-all"></i>
160   - <span class="menu-text">撤销执行</span>
161   - </button>
162   - </li> -->
163 145 <li class="menu-separator"></li>
164 146 <li class="menu-item" >
165 147 <button type="button" class="menu-btn" data-method="vehicAndPerAdjust">
... ... @@ -218,18 +200,31 @@
218 200 <div id="tooltip" style="display: none;">
219 201 </div>
220 202  
  203 +<script>
  204 +//JS文件加载计数,countDownLatch为0 时则加载完成
  205 +var countDownLatch = 13;
  206 +function countDown(name){
  207 + countDownLatch --;
  208 + if(!countDownLatch)
  209 + _main.start();
  210 +
  211 + console.log('countDown: ' + countDownLatch, 'file: ' + name);
  212 +}
  213 +</script>
  214 +<script src="/assets/js/eventproxy.js"></script>
  215 +
  216 +<script src="/pages/control/line/js/main.js"></script>
221 217 <script src="/pages/control/line/js/tooltip.js"></script>
222 218 <script src="/pages/control/line/js/drawSvg.js"></script>
223 219 <script src="/pages/control/line/js/data.js"></script>
224 220 <script src="/pages/control/line/js/rightMenu.js"></script>
225 221 <script src="/pages/control/line/js/homeMenu.js"></script>
226 222 <script src="/pages/control/line/js/alone.js"></script>
227   -<script src="/pages/control/line/js/main.js"></script>
228 223 <script src="/pages/control/line/js/messenger.js"></script>
229 224 <script src="/pages/control/line/js/keyboardListen.js"></script>
230 225 <script src="/pages/control/line/js/toolbarEvent.js"></script>
231   -<script src="/pages/control/line/js/speech.js"></script>
232   -
  226 +<script src="/pages/control/line/js/speech.js" data-exclude=1></script>
  227 +<script src="/pages/control/line/js/home.js"></script>
233 228  
234 229 <script>
235 230  
... ...
src/main/resources/static/pages/control/line/js/alone.js
... ... @@ -145,9 +145,11 @@ var _alone = (function(){
145 145 //定位到班次所在的行
146 146 function goToSch(sch){
147 147 var table = getTableBySch(sch);
148   - //如果table不可见
149 148 if(!table.is(":visible"))
150 149 return;
  150 + //表格被锁定
  151 + if(table.parents('.sch_table_panel').hasClass('lock'))
  152 + return;
151 153  
152 154 var currTr = table.find('tr[data-id='+sch.id+']')
153 155 ,half = table.parents('._body').height() / 2
... ... @@ -193,5 +195,7 @@ var _alone = (function(){
193 195 //备注POPOVER
194 196 $('.remarks-popover', '.pb-table').popover({trigger: 'hover',container: '.portlet-fullscreen',placement:'bottom'});
195 197 }
  198 +
  199 + countDown('alone.js');
196 200 return aloneObject;
197 201 })();
198 202 \ No newline at end of file
... ...
src/main/resources/static/pages/control/line/js/data.js
... ... @@ -94,7 +94,14 @@ var _data = (function(){
94 94 //附加信息
95 95 attachInfo(sch);
96 96 schedules[sch.id] = sch;
97   - lineLpMap[sch.xlBm][sch.lpName].push(sch);
  97 +
  98 + var lpArray = lineLpMap[sch.xlBm][sch.lpName];
  99 + $.each(lpArray, function(i){
  100 + if(this.id == sch.id){
  101 + lpArray.splice(i, 1, sch);
  102 + return false;
  103 + }
  104 + });
98 105 },
99 106 getLines: function(){
100 107 return JSON.parse(storage.getItem('lineControlItems'));
... ... @@ -113,6 +120,22 @@ var _data = (function(){
113 120 getLineLpMap: function(){
114 121 return lineLpMap;
115 122 },
  123 + //根据线路编码获取应发未发班次数量
  124 + getYfwfNumByLine: function(lineCode){
  125 + var lpMap = lineLpMap[lineCode]
  126 + ,arr = [], t = new Date().valueOf(), num = 0;
  127 + for(var lp in lpMap){
  128 + arr = lpMap[lp];
  129 + for(var i = 0, sch; sch=arr[i++];){
  130 + if(sch.fcsjT > t)
  131 + break;
  132 +
  133 + if(sch.fcsjActual == null && sch.fcsjActualTime == null)
  134 + num ++;
  135 + }
  136 + }
  137 + return num;
  138 + },
116 139 //根据线路编码获取站点路由
117 140 getStationRouteByLine: function(lineCode){
118 141 return stationRoute[lineCode];
... ... @@ -227,7 +250,7 @@ var _data = (function(){
227 250 function attachInfo(sch){
228 251 //实际发车误差值
229 252 if(sch.fcsjActualTime){
230   - var diff = parseInt((sch.fcsjActualTime - sch.fcsjT) / 1000 / 60);
  253 + var diff = parseInt((sch.fcsjActualTime - sch.dfsjT) / 1000 / 60);
231 254 if(diff > 0)
232 255 sch.fcsj_diff = '( +' + diff + ' )';
233 256 else if(diff < 0)
... ... @@ -378,6 +401,7 @@ var _data = (function(){
378 401 return data;
379 402 }
380 403  
  404 + countDown('data.js');
381 405 //queryStationRoute();
382 406 return dataObject;
383 407 })();
384 408 \ No newline at end of file
... ...
src/main/resources/static/pages/control/line/js/drawSvg.js
... ... @@ -418,5 +418,6 @@ var drawSvg = (function(){
418 418 //双击svg切换
419 419 //$('.line_chart svg').
420 420  
  421 + countDown('drawSvg.js');
421 422 return drawSvgObject;
422 423 })();
... ...
src/main/resources/static/pages/control/line/js/home.js 0 → 100644
  1 +var _home = (function() {
  2 + var gpsOff = 1000 * 60 * 5;
  3 +
  4 + var homeObject = {
  5 + init : function() {
  6 + // 初始化主页
  7 + var lineArray = _data.getLines();
  8 +
  9 + // 3条线路1 tab 拆分
  10 + var tabData = [], len = lineArray.length;
  11 +
  12 + var ids, names, subArray;
  13 + for (var i = 0; i < len;) {
  14 + subArray = lineArray.slice(i, i += 3);
  15 + ids = '';
  16 + names = '';
  17 + $.each(subArray, function(j, op) {
  18 + ids += op.id + '_';
  19 + names += op.name + ',';
  20 + });
  21 + tabData.push({
  22 + id : ids,
  23 + name : names,
  24 + array : subArray
  25 + });
  26 + }
  27 +
  28 + var homeHtmlStr = template('line_control_home_temp', {
  29 + tabList : tabData
  30 + });
  31 +
  32 + $('#tab_home').html(homeHtmlStr);
  33 + // 计算高度 40 页脚
  34 + var ah = $('#top-tabs-wrap .tab-content').height() - 40 - 5;
  35 + $('.card_wrap').css('height', ah / 3);
  36 +
  37 + // 滚动条
  38 + $('.card_wrap .table_wrap').slimscroll({
  39 + height : '187px',
  40 + alwaysVisible : true,
  41 + opacity : .8
  42 + });
  43 +
  44 + // SVG线路图
  45 + $.each(lineArray, function(i, obj) {
  46 + _data.queryStationRoute(obj.lineCode, 'line_chart_'
  47 + + obj.lineCode, drawSvg.initHomeSvg);
  48 + });
  49 +
  50 + $('.line_chart .top .top-remark').slimscroll({
  51 + height : '47px'
  52 + });
  53 +
  54 + // 模拟图GPS刷新事件
  55 + $('#tab_home').on(
  56 + 'gps_refresh',
  57 + function(e, add, up) {
  58 + // 现在先每次全量画
  59 + var list = _data.findAllGps();
  60 + _data.attachSchedulInfo(list);
  61 +
  62 + // drawSvg.drawVehicle(list);
  63 + // 按线路分组
  64 + var listMap = groupByLine(list);
  65 +
  66 + for ( var key in listMap) {
  67 + var htmlStr = template('home_table_temp', {
  68 + list : listMap[key]
  69 + });
  70 + $('#tab_' + key).find('tbody').html(htmlStr);
  71 + // 更新badge
  72 + $('#' + key + '_badge').text(
  73 + '( ' + listMap[key].length + ' )');
  74 +
  75 + drawSvg.clear();
  76 + drawSvg.drawVehicle(listMap[key]);
  77 + }
  78 + });
  79 +
  80 + setTimeout(function() {
  81 + // 打开GPS定时刷新
  82 + _data.startRefreshGpsTimer();
  83 + // 去掉loading
  84 + $('.load-anim').fadeOut(800);
  85 + $('menu.menu').show();
  86 + }, 400);
  87 +
  88 + setTimeout(function() {
  89 + // 提示文本
  90 + var promptFlag = storage.getItem('promptFlag_0810');
  91 + if (!promptFlag) {
  92 + layer.alert('1、取消的下发调度指令的时间限制<br>2、驾驶员收到的指令显示为待发时间', {
  93 + title: '更新信息',
  94 + shift : 5
  95 + });
  96 + storage.setItem('promptFlag_0810', 1);
  97 + }
  98 + }, 1500);
  99 +
  100 + }
  101 + }
  102 +
  103 + function gpslistToMap(gpslist){
  104 + var map = {}
  105 + for(var i = 0, gps; gps = gpslist[i++];){
  106 + map[gps.deviceId] = gps;
  107 + }
  108 + return map;
  109 + }
  110 +
  111 + function groupByLine(gpsArray){
  112 + var rs = {}, gps;
  113 + $.each(gpsArray, function(){
  114 + key = this.lineId + '_' + this.upDown;
  115 + if(!rs[key])
  116 + rs[key] = [];
  117 +
  118 + rs[key].push(this);
  119 + });
  120 + return rs;
  121 + }
  122 +
  123 +
  124 + countDown('home.js');
  125 + return homeObject;
  126 +})();
0 127 \ No newline at end of file
... ...
src/main/resources/static/pages/control/line/js/homeMenu.js
... ... @@ -100,5 +100,7 @@ var _home_menu = (function(){
100 100 });*/
101 101 }
102 102 }
  103 +
  104 + countDown('homeMenu.js');
103 105 })();
104 106  
... ...
src/main/resources/static/pages/control/line/js/keyboardListen.js
... ... @@ -95,4 +95,5 @@ $(document.body).on(&#39;keydown&#39;, function(e){
95 95 function msg_ct(t){
96 96 layer.msg(t,{offset: 'ct', shift : 5});
97 97 }
  98 +
98 99 });
99 100 \ No newline at end of file
... ...
src/main/resources/static/pages/control/line/js/main.js
1   -!function(){
2   - var gpsOff = 1000 * 60 * 5;
  1 +var _main = (function(){
3 2  
4   - var homeObject = {
5   - init:function(){
6   - //初始化主页
7   - var lineArray = _data.getLines();
8   -
9   - //3条线路1 tab 拆分
10   - var tabData = [], len = lineArray.length;
11   -
12   - var ids,names,subArray;
13   - for(var i = 0; i < len;){
14   - subArray = lineArray.slice(i, i += 3);
15   - ids = '';
16   - names = '';
17   - $.each(subArray, function(j, op){
18   - ids += op.id + '_';
19   - names += op.name + ',';
20   - });
21   - tabData.push({id: ids, name: names, array: subArray});
22   - }
23   -
24   - var homeHtmlStr = template('line_control_home_temp', {tabList: tabData});
25   -
26   - $('#tab_home').html(homeHtmlStr);
27   - //计算高度 40 页脚
28   - var ah = $('#top-tabs-wrap .tab-content').height() - 40 - 5;
29   - $('.card_wrap').css('height', ah / 3);
30   -
31   - //滚动条
32   - $('.card_wrap .table_wrap').slimscroll({
33   - height: '187px',
34   - alwaysVisible: true,
35   - opacity: .8
36   - });
37   -
38   - //SVG线路图
39   - $.each(lineArray, function(i, obj){
40   - _data.queryStationRoute( obj.lineCode, 'line_chart_' + obj.lineCode , drawSvg.initHomeSvg);
41   - });
42   -
43   - $('.line_chart .top .top-remark').slimscroll({
44   - height: '47px'
45   - });
46   -
47   - //模拟图GPS刷新事件
48   - $('#tab_home').on('gps_refresh', function(e, add, up){
49   - //现在先每次全量画
50   - var list = _data.findAllGps();
51   - _data.attachSchedulInfo(list);
52   -
53   - //drawSvg.drawVehicle(list);
54   - //按线路分组
55   - var listMap = groupByLine(list);
56   -
57   - for(var key in listMap){
58   - var htmlStr = template('home_table_temp', {list: listMap[key]});
59   - $('#tab_' + key).find('tbody').html(htmlStr);
60   - //更新badge
61   - $('#'+key+'_badge').text('( ' + listMap[key].length + ' )');
62   -
63   - drawSvg.clear();
64   - drawSvg.drawVehicle(listMap[key]);
65   - }
66   - });
67   -
68   - setTimeout(function(){
69   - //打开GPS定时刷新
70   - _data.startRefreshGpsTimer();
71   - //去掉loading
72   - $('.load-anim').fadeOut();
73   - $('menu.menu').show();
74   - }, 400);
75   -
76   - setTimeout(function(){
77   - //提示文本
78   - var promptFlag = storage.getItem('promptFlag_0808');
79   - if(!promptFlag){
80   - layer.alert('未避免 TTS 重复播报,请在 “地图” 标签页,点击 “新窗口” 打开新的地图页面', {shift: 5});
81   - storage.setItem('promptFlag_0808', 1);
82   - }
83   - }, 1500);
84   -
85   - }
86   - }
87   -
88   -setTimeout(function(){
  3 +/*setTimeout(function(){
89 4 //生成头部选项卡
90 5 var topTabs = '', tabPanels = '';
91 6 $.each(_data.getLines(), function(i, line){
... ... @@ -107,6 +22,11 @@ setTimeout(function(){
107 22 _messenger.init();
108 23 //初始化主页
109 24 homeObject.init();
  25 +
  26 + $.each(_data.getLines(), function(){
  27 + //计算应发未发数量
  28 + _messenger.setYFWFNum(this.lineCode);
  29 + });
110 30 });
111 31  
112 32 //监控模式下,拦截post请求
... ... @@ -114,25 +34,72 @@ setTimeout(function(){
114 34 $(document).on('ajaxSend', interceptPOST);
115 35 }
116 36  
117   -}, 300)
  37 +}, 200)*/
118 38  
119   - function gpslistToMap(gpslist){
120   - var map = {}
121   - for(var i = 0, gps; gps = gpslist[i++];){
122   - map[gps.deviceId] = gps;
  39 +
  40 + /*var startEp = EventProxy.create("template", function (template, data, l10n) {
  41 + _.template(template, data, l10n);
  42 + });*/
  43 + var initEp;
  44 + var mainInstance = {
  45 + start: function(){
  46 + /*//文件加载结束
  47 + successLoadItem('load_resource');
  48 + initEp = new EventProxy();
  49 + //校对时间
  50 + initEp.tail('proof_time', function(diff){
  51 + if(diff < 1000 * 60 * 5){
  52 +
  53 + }
  54 + });*/
  55 + //生成头部选项卡
  56 + var topTabs = '', tabPanels = '';
  57 + $.each(_data.getLines(), function(i, line){
  58 + topTabs += '<li ><a data-id="'+line.lineCode+'" href="#tab_line_'+line.lineCode+'" data-toggle="tab" '+
  59 + 'aria-expanded="false"> '+line.name+'<span>(<zz>0</zz>,<zz>0</zz> <zz>托管</zz>)</span> </a></li>';
  60 +
  61 + tabPanels += '<div class="tab-pane fade tab_line" data-id="'+line.lineCode+'" id="tab_line_'+line.lineCode+'"></div>';
  62 +
  63 + });
  64 + $('#top-tabs-wrap .nav-tabs').append(topTabs);
  65 + $('#top-tabs-wrap .tab-content').append(tabPanels);
  66 +
  67 + //加载地图页数据
  68 + $('#tab_map').load('/pages/mapmonitor/real/real.html');
  69 +
  70 + //初始化单线路调度页面
  71 + _alone.init(function(){
  72 + //初始化信使
  73 + _messenger.init();
  74 + //初始化主页
  75 + _home.init();
  76 +
  77 + $.each(_data.getLines(), function(){
  78 + //计算应发未发数量
  79 + _messenger.setYFWFNum(this.lineCode);
  80 + });
  81 + });
  82 +
  83 + //监控模式下,拦截post请求
  84 + if(operationMode == 0){
  85 + $(document).on('ajaxSend', interceptPOST);
  86 + }
  87 + },
  88 + emitInitEp: function(name){
  89 +
123 90 }
124   - return map;
125 91 }
126 92  
127   - function groupByLine(gpsArray){
128   - var rs = {}, gps;
129   - $.each(gpsArray, function(){
130   - key = this.lineId + '_' + this.upDown;
131   - if(!rs[key])
132   - rs[key] = [];
133   -
134   - rs[key].push(this);
135   - });
136   - return rs;
  93 + function successLoadItem(item){
  94 + $('.load-anim .item.' + item).addClass('success');
137 95 }
138   -}();
139 96 \ No newline at end of file
  97 +
  98 + function proofTime(){
  99 + /*$get('/gps/proofTime', function(){
  100 +
  101 + });*/
  102 + }
  103 +
  104 + countDown('main.js');
  105 + return mainInstance;
  106 +})();
140 107 \ No newline at end of file
... ...
src/main/resources/static/pages/control/line/js/messenger.js
... ... @@ -17,17 +17,32 @@ var _messenger = (function(){
17 17 $.each(list, function(){
18 18 time = parseInt($(this).data('time'));
19 19 if(ct - time >= 30)
20   - _fadeOut($(this));
  20 + removeLogItem($(this));
21 21 });
  22 + //更新未处理的消息数量
  23 + setUntreatedNum(code);
22 24 }
23 25  
24 26 setTimeout(f, 3000);
25 27 }();
26 28  
  29 + //未处理消息数量
  30 + function setUntreatedNum(lineCode){
  31 + var len = $('#messengerList' + lineCode).find('.log-item').length;
  32 + var $e = $('#top-tabs-wrap .top-nav li a[data-id='+lineCode+'] span zz:eq(0)');
  33 + $e.text(len);
  34 + }
  35 +
  36 + //应发未发 班次数量
  37 + function setYFWFNum(lineCode){
  38 + var size = _data.getYfwfNumByLine(lineCode);
  39 + var $e = $('#top-tabs-wrap .top-nav li a[data-id='+lineCode+'] span zz:eq(1)');
  40 + $e.text(size);
  41 + }
27 42  
28 43 /** 信使操作 */
29 44 $('.portlet-fullscreen').on('click', '.log-item-handle a.log-close', function(){
30   - _fadeOut($(this).parents('.log-item'));
  45 + removeLogItem($(this).parents('.log-item'));
31 46 });
32 47  
33 48 //80上报事件处理
... ... @@ -64,7 +79,6 @@ var _messenger = (function(){
64 79 $.get('/directive/findNoCofm80', {lineCodes: lineCodes}
65 80 , function(rs){
66 81 //填充未确认的80数据
67   - console.log(rs);
68 82 for(var lineCode in rs){
69 83 $.each(rs[lineCode], function(){
70 84 this.dateStr = moment(this.timestamp).format('HH:mm.ss');
... ... @@ -84,7 +98,9 @@ var _messenger = (function(){
84 98 $('.console-log .log-item-list').slimscroll({
85 99 height: '100%'
86 100 });
87   - }
  101 + },
  102 + setUntreatedNum: setUntreatedNum,
  103 + setYFWFNum: setYFWFNum
88 104 }
89 105  
90 106  
... ... @@ -195,6 +211,18 @@ var _messenger = (function(){
195 211 });
196 212 }
197 213  
  214 +
  215 + function removeLogItem($that){
  216 + var lineCode = $that.parents('.log-item-list').data('code');
  217 + console.log('removeLogItem', lineCode);
  218 + $that.fadeOut('normal', function(){
  219 + $that.remove();
  220 + //重新计算信使数量
  221 + setUntreatedNum(lineCode);
  222 + });
  223 + }
  224 +
  225 + countDown('messenger.js');
198 226 return messengerObj;
199 227 })();
200 228  
... ...
src/main/resources/static/pages/control/line/js/rightMenu.js
... ... @@ -45,7 +45,6 @@ var _menu = (function() {
45 45 showMenu(e.pageX, e.pageY + 3);
46 46 $(document).one('click', function() {
47 47 $('#rightMenu').removeClass('show-menu');
48   - //item.removeClass(ac);
49 48 });
50 49 })
51 50 // 点击选中
... ... @@ -53,22 +52,43 @@ var _menu = (function() {
53 52 resetAllState();
54 53 $(this).addClass(ac);
55 54  
  55 + //锁住table,防止跳屏
  56 + $('._panel.lock').removeClass('lock');
  57 + $(this).parents('._panel').addClass('lock');
  58 +
56 59 var $ctr = $(this).parent();
57 60 //选中关联班次
58 61 selCognateSch($ctr);
59 62 $ctr.removeClass('selected');
60 63 });
61 64  
  65 + var unlocks = '.portlet-title.banner, #top-tabs-wrap .top-nav, .pic-panel, .console-log, .tab_line .svg_footer';
  66 + //点击其他区域解锁table
  67 + $('.portlet-fullscreen').on('click', unlocks, function(e){
  68 + //解锁table
  69 + $('._panel.lock').removeClass('lock');
  70 + });
  71 + /*$('.portlet-fullscreen').on('click', function(e){
  72 + var _panels = $(e.target).parents('.sch_table_panel');
  73 + if(!_panels || _panels.length == 0){
  74 + //解锁table
  75 + $('._panel.lock').removeClass('lock');
  76 + }
  77 + });*/
  78 +
62 79 //点击序号
63 80 var nos = '.pb-table.data tr td[name=lineNo]', prveSelRow;
64 81 $('.portlet-fullscreen').on('click', nos, function(e){
  82 + //锁住table,防止跳屏
  83 + $('._panel.lock').removeClass('lock');
  84 + $(this).parents('._panel').addClass('lock');
  85 +
65 86 var $tab = $(this).parents('table');
66 87 //当前表格是否存在选中项
67 88 var multiSel = $tab.find('tr._tr_active').length;
68   - //按住了ctrl 或 shift
  89 + //按住了CTRL 或 shift
69 90 if((e.ctrlKey || e.shiftKey) && multiSel){
70 91 resetState();
71   - //按住了shift 多选
72 92 if(e.shiftKey && prveSelRow){
73 93 var startNo = parseInt(prveSelRow.data('no'))
74 94 ,endNo = parseInt($(this).parent().data('no'));
... ... @@ -92,6 +112,7 @@ var _menu = (function() {
92 112 $('.portlet-fullscreen').on('click', lps, function(e){
93 113 var lp = $(this).text();
94 114 msg_ct('高亮路牌:' + lp);
  115 +
95 116 var lineCode = $(this).parents('.tab-pane').data('id');
96 117 var schArray = _data.getLineLpMap()[lineCode][lp];
97 118  
... ... @@ -99,6 +120,11 @@ var _menu = (function() {
99 120 $.each(schArray, function(){
100 121 $('.pb-table tr[data-id='+this.id+']').addClass('selected dir_' + this.xlDir);
101 122 });
  123 +
  124 + //锁住2个表格
  125 + $('._panel.lock').removeClass('lock');
  126 + $('#tab_line_' + lineCode).find('.sch_table_panel').addClass('lock');
  127 + //$(this).parents('._panel').addClass('lock');
102 128 });
103 129  
104 130 function selectOneRow(firstCell){
... ... @@ -164,6 +190,7 @@ var _menu = (function() {
164 190 }
165 191 }
166 192 function resetAllState(){
  193 +
167 194 $('.pb-table tr td.' + ac).removeClass(ac);
168 195 $('.pb-table tr.selected').removeClass('selected');
169 196 $('.pb-table tr.dir_0').removeClass('dir_0');
... ... @@ -238,9 +265,10 @@ var _menu = (function() {
238 265 var params = $('#outgoAdjustForm').serializeJSON();
239 266 $post('/realSchedule/outgoAdjust', params, function(rs){
240 267 layer.close(index);
241   - if(rs.t){
  268 + if(rs.ts){
242 269 msg_ct('调整成功!');
243   - _alone.refreshSchedule(rs.t);
  270 + _alone.refreshScheduleArray(rs.ts);
  271 + //_alone.refreshSchedule(rs.t);
244 272 }
245 273 });
246 274 });
... ... @@ -360,7 +388,7 @@ var _menu = (function() {
360 388 if(rs.ts){
361 389 msg_ct('实发调整成功!');
362 390 //更新前端数据
363   - _alone.refreshScheduleArray(rs.ts);
  391 + //_alone.refreshScheduleArray(rs.ts);
364 392 }
365 393 });
366 394 });
... ... @@ -633,5 +661,6 @@ var _menu = (function() {
633 661 return rs;
634 662 }
635 663  
  664 + countDown('rightMenu.js');
636 665 return menuObject;
637 666 })();
638 667 \ No newline at end of file
... ...
src/main/resources/static/pages/control/line/js/speech.js
... ... @@ -7,7 +7,10 @@ var h5Speech = (function(){
7 7 //队列播放模式 1:覆盖式 -1:完整顺序播报
8 8 var queueModel;
9 9 var synth = window.speechSynthesis;
  10 + //1: 启用 ,0:禁用
  11 + var enable;
10 12  
  13 + var storage = window.localStorage;
11 14 //读取配置信息
12 15 readCofig();
13 16 var speechInstance = {
... ... @@ -28,17 +31,20 @@ var h5Speech = (function(){
28 31 synth.speak(msg);
29 32 },
30 33 getCofig: function(){
31   - return {rate: rate, queueModel: queueModel};
  34 + return {rate: rate, queueModel: queueModel, enable: enable};
32 35 },
33   - setCofig: function(r, q){
  36 + setCofig: function(r, q, e){
34 37 rate = r;
35 38 queueModel = q;
36   - writeCofig(rate, queueModel);
  39 + enable = e;
  40 + writeCofig(rate, queueModel, enable);
37 41  
38 42 return 1;
  43 + },
  44 + isEnable: function(){
  45 + return enable;
39 46 }
40 47 };
41   - return speechInstance;
42 48  
43 49 function readCofig(){
44 50 //读取配置信息
... ... @@ -47,16 +53,21 @@ var h5Speech = (function(){
47 53 ttsCofig = JSON.parse(ttsCofig);
48 54 rate = ttsCofig.rate;
49 55 queueModel = ttsCofig.queueModel;
  56 + enable = ttsCofig.enable;
50 57 }
51 58 else{
52 59 //写入默认配置
53 60 rate = 1.2;
54 61 queueModel = 1;
55   - writeCofig(rate, queueModel);
  62 + enable = 1;
  63 + writeCofig(rate, queueModel, enable);
56 64 }
57 65 }
58 66  
59   - function writeCofig(rate, queueModel){
60   - storage.setItem('tts_cofig', JSON.stringify({rate: rate, queueModel: queueModel}));
  67 + function writeCofig(rate, queueModel, enable){
  68 + storage.setItem('tts_cofig', JSON.stringify({rate: rate, queueModel: queueModel, enable: enable}));
61 69 }
  70 +
  71 + countDown('speech.js');
  72 + return speechInstance;
62 73 })();
... ...
src/main/resources/static/pages/control/line/js/toolbarEvent.js
... ... @@ -58,4 +58,6 @@
58 58 });
59 59 });
60 60 });
  61 +
  62 + countDown('toolbarEvent.js');
61 63 }();
62 64 \ No newline at end of file
... ...
src/main/resources/static/pages/control/line/js/tooltip.js
... ... @@ -199,6 +199,7 @@ var _tooltip = (function(){
199 199 }, 650);
200 200 }
201 201 };
202   -
  202 +
  203 + countDown('tooltip.js');
203 204 return tooltipObject;
204 205 })();
... ...
src/main/resources/static/pages/control/line/js/webSocketHandle.js
... ... @@ -19,6 +19,7 @@ var initWebSocket = function(){
19 19  
20 20 msgSock.onopen = function(e) {
21 21 console.log('webSocket[realcontrol] onopen');
  22 + countDown('webSocketHandle.js');
22 23 };
23 24 //接收消息
24 25 msgSock.onmessage = function(e) {
... ... @@ -43,24 +44,28 @@ var msgHandle = {
43 44 msg.dateStr = moment(msg.timestamp).format('HH:mm.ss');
44 45 msg.text = reqCodeMap[msg.data.requestCode];
45 46  
46   - console.log(msg);
47 47 appendLogItem('console_80_temp', {list: [msg]}, msg.data.lineId);
48 48 },
49 49 //驾驶员80被处理
50 50 d80Confirm: function(msg){
51   - _fadeOut($('.log-item.handle[data-id='+msg.id+']'));
  51 + var $that = $('.log-item.handle[data-id='+msg.id+']');
  52 + _fadeOut($that);
  53 +
  54 + var lineCode = $that.parents('.log-item-list').data('code');
  55 + _messenger.setUntreatedNum(lineCode);
52 56 },
53 57 //车辆发出
54 58 faChe: function(msg){
55   - //刷新数据
56 59 _alone.refreshSchedule(msg.t);
57 60 msg.jsTime = Date.parse(new Date()) / 1000;
58 61 //信使
59 62 appendLogItem('console_fache_temp', msg, msg.t.xlBm);
  63 +
  64 + //重新计算应发未发
  65 + _messenger.setYFWFNum(msg.t.xlBm);
60 66 },
61 67 //到达终点
62 68 zhongDian: function(msg){
63   - //刷新数据
64 69 _alone.refreshSchedule(msg.t);
65 70 _alone.refreshSchedule(msg.nt);
66 71 msg.jsTime = Date.parse(new Date()) / 1000;
... ... @@ -100,6 +105,19 @@ var msgHandle = {
100 105 setTimeout(function(){
101 106 window.location.reload(true);
102 107 }, 1000);
  108 + },
  109 + //刷新班次
  110 + refreshSch: function(msg){
  111 + var array = msg.ts;
  112 + if(array && array.length > 0){
  113 +
  114 + if(array.length == 1)
  115 + _alone.refreshSchedule(array[0]);
  116 + else
  117 + _alone.refreshScheduleArray(array);
  118 + //重新计算应发未发
  119 + _messenger.setYFWFNum(msg.ts[0].xlBm);
  120 + }
103 121 }
104 122 };
105 123  
... ... @@ -109,9 +127,16 @@ function appendLogItem(tempId, json, lineCode){
109 127  
110 128 var logWrap = $('.console-log .log-item-list', '#tab_line_' + lineCode);
111 129 logWrap.prepend(htmlStr);
112   - //语音播报
113   - var text = $(htmlStr).find('.log-item-text').text();
114   - h5Speech.speak(text);
  130 +
  131 + if(h5Speech.isEnable() == 1){
  132 + //语音播报
  133 + var text = $(htmlStr).find('.log-item-text').text();
  134 + var lineName = _data.getLineIds()[lineCode];
  135 + h5Speech.speak(lineName.replace('闵行', '') + ' ' + text);
  136 + }
  137 + //重新计算未处理消息
  138 + _messenger.setUntreatedNum(lineCode);
115 139 }
116 140  
  141 +countDown('webSocketHandle.js');
117 142 }();
... ...
src/main/resources/static/pages/control/line/temps/alone_tp.html
... ... @@ -4,7 +4,7 @@
4 4 <div class="col-md-10" style="height: 100%;padding-left: 0;padding-right: 0;">
5 5 <div style="height: calc(100% - 60px);">
6 6 <div class="col-md-6 panel-wrap">
7   - <div class="_panel">
  7 + <div class="_panel sch_table_panel">
8 8 <div class="_head" style="color: #2765A7;">
9 9 上行/{{startStationName}}
10 10 </div>
... ... @@ -35,7 +35,7 @@
35 35 </div>
36 36 </div>
37 37 <div class="col-md-6 panel-wrap">
38   - <div class="_panel">
  38 + <div class="_panel sch_table_panel">
39 39 <div class="_head" style="color: #C92121;">
40 40 下行/{{endStationName}}
41 41 </div>
... ... @@ -87,7 +87,7 @@
87 87 <div class="col-md-2 panel-wrap" >
88 88 <div class="_panel">
89 89 <div class="console-log">
90   - <div class="log-item-list" id="messengerList{{lineCode}}">
  90 + <div class="log-item-list" id="messengerList{{lineCode}}" data-code={{lineCode}}>
91 91 </div>
92 92 </div>
93 93 <div class="_panel_footer tg_tools" id="tgTools_{{lineCode}}" data-linecode="{{lineCode}}">
... ... @@ -97,7 +97,7 @@
97 97 </div>
98 98 </div>
99 99  
100   -<div class="panel-wrap" style="height: 209px;margin-top: 6px;">
  100 +<div class="panel-wrap svg_footer" style="height: 209px;margin-top: 6px;">
101 101 <div class="_panel" id="lineSvg{{lineCode}}">
102 102  
103 103 </div>
... ...
src/main/resources/static/pages/control/line/temps/messenger.html
... ... @@ -20,7 +20,7 @@
20 20 <script id="console_fache_temp" type="text/html" >
21 21 <div class="log-item fache" data-time={{jsTime}}>
22 22 <span class="log-item-text">{{t.fcsjActual}} {{t.clZbh}} 已由 {{t.qdzName}} 发出</span>
23   - <span class="log-item-text">执行班次 {{t.fcsj}}</span>
  23 + <span class="log-item-text">执行班次 {{t.dfsj}}</span>
24 24 <span class="log-item-time">{{dataStr}}</span>
25 25 <span class="log-item-handle">
26 26 <a href="javascript:;" class="font-blue-steel log-close">确定</a>
... ... @@ -31,7 +31,7 @@
31 31  
32 32 <script id="console_zhongdian_temp" type="text/html">
33 33 <div class="log-item zhongdian" data-time={{jsTime}}>
34   - <span class="log-item-text">{{t.zdsjActual}} {{t.clZbh}} 到达 {{t.zdzName}};已完成 {{finish}} 个班次;下一发车时间 {{nt.fcsj}};由{{nt.qdzName}} 发往 {{nt.zdzName}};应到{{nt.zdsj}}</span>
  34 + <span class="log-item-text">{{t.zdsjActual}} {{t.clZbh}} 到达 {{t.zdzName}};已完成 {{finish}} 个班次;下一发车时间 {{nt.dfsj}};由{{nt.qdzName}} 发往 {{nt.zdzName}};应到{{nt.zdsj}}</span>
35 35 <span class="log-item-time">{{dataStr}}</span>
36 36 <span class="log-item-handle">
37 37 <a href="javascript:;" class="font-blue-steel log-close">确定</a>
... ...
src/main/resources/static/pages/control/lineallot/allot.html
... ... @@ -212,7 +212,7 @@ $(function(){
212 212  
213 213 var storage = window.localStorage;
214 214  
215   - $get('/line/all', null, function(allLine){
  215 + $get('/line/all', {destroy_eq:0}, function(allLine){
216 216 $('#searchLineInput').focus();
217 217 //按公司分组
218 218 var companyJson = groupData(allLine, 'company');
... ... @@ -301,12 +301,14 @@ $(function(){
301 301 lsData.push(lineIdMap[$(e).data('id')]);
302 302 });
303 303 storage.setItem('lineControlItems', JSON.stringify(lsData));
  304 +
  305 + var operationMode = $(this).data('status');
304 306 //缓存车辆和设备对照
305 307 $.get('/gps/Car2DeviceId', function(rs){
306 308 storage.setItem('car2DeviceId', JSON.stringify(rs));
307 309  
308 310 //监控模式还是主调模式
309   - storage.setItem('operationMode', $(this).data('status'));
  311 + storage.setItem('operationMode', operationMode);
310 312 //将线路路由缓存到localstorage
311 313 cacheRoute(lsData, function(cacheData){
312 314 for(var lineCode in cacheData){
... ...
src/main/resources/static/pages/mapmonitor/real/js/consts.js 0 → 100644
  1 +var consts = {
  2 + mapContainer: '#mapContainer',
  3 + center_point: {
  4 + lng : 121.544336,
  5 + lat : 31.221315
  6 + },
  7 + allGps: {},
  8 + trafficBtn: '#trafficItem'//实时路况按钮
  9 +}
0 10 \ No newline at end of file
... ...
src/main/resources/static/pages/mapmonitor/real/real.html
... ... @@ -86,6 +86,7 @@
86 86  
87 87 <div id="temps"></div>
88 88  
  89 +<script src="/pages/mapmonitor/real/js/consts.js" data-exclude=1></script>
89 90 <script src="/assets/js/TransGPS.js" data-exclude=1></script>
90 91 <script src="/pages/mapmonitor/real/js/map/iMap.js" data-exclude=1></script>
91 92 <script src="/pages/mapmonitor/real/js/lineGroup.js" data-exclude=1></script>
... ... @@ -97,16 +98,6 @@
97 98 <script src="/pages/mapmonitor/real/js/map/platform/baidu.js" data-exclude=1></script>
98 99 <script src="/pages/mapmonitor/real/js/map/platform/gaode.js" data-exclude=1></script>
99 100 <script>
100   -var consts = {
101   - mapContainer: '#mapContainer',
102   - center_point: {
103   - lng : 121.544336,
104   - lat : 31.221315
105   - },
106   - allGps: {},
107   - trafficBtn: '#trafficItem'//实时路况按钮
108   -}
109   -
110 101 setTimeout(function(){
111 102 iMap.addMap('baidu', '百度地图', baiduMap)
112 103 .addMap('gaode', '高德地图', gaodeMap)
... ...