Commit 5a78b34aaa910929eaa06662aa5d60c4e225f40a

Authored by 王通
1 parent 841c9a3e

1.针对线路预设区间的处理

Showing 37 changed files with 4601 additions and 3831 deletions
src/main/java/com/bsth/data/directive/DayOfDirectives.java
1 -package com.bsth.data.directive;  
2 -  
3 -import com.alibaba.fastjson.JSONObject;  
4 -import com.bsth.data.LineConfigData;  
5 -import com.bsth.entity.directive.D60;  
6 -import com.bsth.entity.directive.D64;  
7 -import com.bsth.entity.directive.Directive;  
8 -import com.bsth.entity.directive.DirectiveReponse;  
9 -import com.bsth.entity.realcontrol.ScheduleRealInfo;  
10 -import com.bsth.service.directive.DirectiveService;  
11 -import com.bsth.websocket.handler.SendUtils;  
12 -import org.slf4j.Logger;  
13 -import org.slf4j.LoggerFactory;  
14 -import org.springframework.beans.factory.annotation.Autowired;  
15 -import org.springframework.stereotype.Component;  
16 -  
17 -import java.util.*;  
18 -import java.util.concurrent.ConcurrentHashMap;  
19 -import java.util.concurrent.ConcurrentLinkedQueue;  
20 -import java.util.concurrent.ConcurrentMap;  
21 -  
22 -/**  
23 - *  
24 - * @ClassName: CurrDayDirectives  
25 - * @Description: TODO(当天指令数据)  
26 - * @author PanZhao  
27 - * @date 2016年8月14日 下午5:23:59  
28 - *  
29 - */  
30 -@Component  
31 -public class DayOfDirectives {  
32 -  
33 - // 当日60指令缓存  
34 - private static ConcurrentMap<Integer, D60> d60Map;  
35 -  
36 - // 线路切换指令 64  
37 - public static ConcurrentMap<String, D64> d64Map;  
38 -  
39 - //等待插入的指令  
40 - public static ConcurrentLinkedQueue<Directive> pstDirectives;  
41 - //等待更新的指令  
42 - public static ConcurrentLinkedQueue<D60> pstD60s;  
43 -  
44 - @Autowired  
45 - DirectiveService directiveService;  
46 -  
47 - @Autowired  
48 - SendUtils sendUtils;  
49 -  
50 - @Autowired  
51 - LineConfigData lineConfigData;  
52 -  
53 - static Logger logger = LoggerFactory.getLogger(DayOfDirectives.class);  
54 -  
55 -  
56 - static{  
57 - d60Map = new ConcurrentHashMap<>();  
58 - d64Map = new ConcurrentHashMap<>();  
59 - pstDirectives = new ConcurrentLinkedQueue<>();  
60 - pstD60s = new ConcurrentLinkedQueue<>();  
61 - }  
62 -  
63 - public void put60(D60 d60) {  
64 - d60Map.put(d60.getMsgId(), d60);  
65 - //等待持久化  
66 - pstDirectives.add(d60);  
67 - }  
68 -  
69 - public void put64(D64 d64) {  
70 - d64Map.put(d64.getKey(), d64);  
71 - //等待持久化  
72 - pstDirectives.add(d64);  
73 - }  
74 -  
75 - /**  
76 - *  
77 - * @Title: reply @Description: TODO(指令 46,47 响应) @throws  
78 - */  
79 - public void reply(DirectiveReponse res) {  
80 - Integer msgId = res.getMsgId();  
81 - if (msgId == null) {  
82 - logger.error("reply error , msgId is null.");  
83 - return;  
84 - }  
85 -  
86 - D60 d60 = d60Map.get(msgId);  
87 -  
88 - if (null == d60) {  
89 - logger.error("找不到msgId: " + msgId + " 对应的指令数据");  
90 - return;  
91 - }  
92 -  
93 - switch (res.getStatus()) {  
94 - case 0:  
95 - d60.setReply46((short) -1);// 失败  
96 - break;  
97 - case 1:  
98 - d60.setReply46((short) 0);// 发送成功  
99 - d60.setReply46Time(System.currentTimeMillis());  
100 - break;  
101 - case 2:  
102 - d60.setReply47((short) 0);// 驾驶员阅读  
103 - d60.setReply47Time(System.currentTimeMillis());  
104 - break;  
105 - }  
106 -  
107 - //更新60数据  
108 - pstD60s.add(d60);  
109 -  
110 - ScheduleRealInfo sch = d60.getSch();  
111 - if (null == sch)  
112 - return;  
113 -  
114 - if (d60.isDispatch()) {  
115 - // 更新班次状态  
116 - sch.setDirectiveState(res.getStatus() * 100);  
117 - // 通知页面  
118 - sendUtils.sendDirectiveToPage(sch);  
119 - }  
120 - }  
121 -  
122 - /**  
123 - *  
124 - * @Title: reply64 @Description: TODO(64 协议响应) @throws  
125 - */  
126 - public void reply64(JSONObject json) {  
127 - String key = json.getString("deviceId") + "_" + json.getString("timestamp");  
128 -  
129 - D64 d64 = d64Map.get(key);  
130 -  
131 - if (null == d64)  
132 - logger.warn("64响应 -找不到请求源,json: " + json);  
133 - else {  
134 - JSONObject data = json.getJSONObject("data");  
135 -  
136 - if (null == data)  
137 - logger.warn("64响应 data is null ,json: " + json);  
138 - else {  
139 - logger.info(d64.getDeviceId() + "_" + d64.getData().getLineId() + "响应:" + data.getShort("requestAck"));  
140 - /*d64.setRespAck(data.getShort("requestAck"));  
141 - // 持久化*/  
142 - //64 响应不入库了...  
143 - }  
144 - }  
145 - }  
146 -  
147 - @Autowired  
148 - DirectivesPstThread directivesPstThread;  
149 - public void clearAll(){  
150 - d60Map = new ConcurrentHashMap<>();  
151 - d64Map = new ConcurrentHashMap<>();  
152 - logger.info("清除指令数据 ,,,");  
153 - }  
154 -  
155 - public Collection<D60> all60(){  
156 - return d60Map.values();  
157 - }  
158 -  
159 - public Collection<D64> all64(){  
160 - return d64Map.values();  
161 - }  
162 -  
163 - public D60 get(Integer msgId){  
164 - return d60Map.get(msgId);  
165 - }  
166 -  
167 - public Collection<Directive> all(){  
168 - List<Directive> all = new ArrayList<>();  
169 - all.addAll(d60Map.values());  
170 - all.addAll(d64Map.values());  
171 -  
172 - return all;  
173 - }  
174 -  
175 - public static class DComparator implements Comparator<Directive>{  
176 -  
177 - @Override  
178 - public int compare(Directive d1, Directive d2) {  
179 - return (int) (d2.getTimestamp() - d1.getTimestamp());  
180 - }  
181 - }  
182 - } 1 +package com.bsth.data.directive;
  2 +
  3 +import com.alibaba.fastjson.JSONObject;
  4 +import com.bsth.data.LineConfigData;
  5 +import com.bsth.entity.directive.D60;
  6 +import com.bsth.entity.directive.D64;
  7 +import com.bsth.entity.directive.Directive;
  8 +import com.bsth.entity.directive.DirectiveReponse;
  9 +import com.bsth.entity.realcontrol.ScheduleRealInfo;
  10 +import com.bsth.service.directive.DirectiveService;
  11 +import com.bsth.websocket.handler.SendUtils;
  12 +import org.slf4j.Logger;
  13 +import org.slf4j.LoggerFactory;
  14 +import org.springframework.beans.factory.annotation.Autowired;
  15 +import org.springframework.stereotype.Component;
  16 +
  17 +import java.util.*;
  18 +import java.util.concurrent.ConcurrentHashMap;
  19 +import java.util.concurrent.ConcurrentLinkedQueue;
  20 +import java.util.concurrent.ConcurrentMap;
  21 +
  22 +/**
  23 + *
  24 + * @ClassName: CurrDayDirectives
  25 + * @Description: TODO(当天指令数据)
  26 + * @author PanZhao
  27 + * @date 2016年8月14日 下午5:23:59
  28 + *
  29 + */
  30 +@Component
  31 +public class DayOfDirectives {
  32 +
  33 + // 当日60指令缓存
  34 + private static ConcurrentMap<Integer, D60> d60Map;
  35 +
  36 + // 线路切换指令 64
  37 + public static ConcurrentMap<String, D64> d64Map;
  38 +
  39 + //等待插入的指令
  40 + public static ConcurrentLinkedQueue<Directive> pstDirectives;
  41 + //等待更新的指令
  42 + public static ConcurrentLinkedQueue<D60> pstD60s;
  43 +
  44 + @Autowired
  45 + DirectiveService directiveService;
  46 +
  47 + @Autowired
  48 + SendUtils sendUtils;
  49 +
  50 + @Autowired
  51 + LineConfigData lineConfigData;
  52 +
  53 + static Logger logger = LoggerFactory.getLogger(DayOfDirectives.class);
  54 +
  55 +
  56 + static{
  57 + d60Map = new ConcurrentHashMap<>();
  58 + d64Map = new ConcurrentHashMap<>();
  59 + pstDirectives = new ConcurrentLinkedQueue<>();
  60 + pstD60s = new ConcurrentLinkedQueue<>();
  61 + }
  62 +
  63 + public void put60(D60 d60) {
  64 + d60Map.put(d60.getMsgId(), d60);
  65 + //等待持久化
  66 + pstDirectives.add(d60);
  67 + }
  68 +
  69 + public void put64(D64 d64) {
  70 + d64Map.put(d64.getKey(), d64);
  71 + //等待持久化
  72 + pstDirectives.add(d64);
  73 + }
  74 +
  75 + /**
  76 + *
  77 + * @Title: reply @Description: TODO(指令 46,47 响应) @throws
  78 + */
  79 + public void reply(DirectiveReponse res) {
  80 + Integer msgId = res.getMsgId();
  81 + if (msgId == null) {
  82 + logger.error("reply error , msgId is null.");
  83 + return;
  84 + }
  85 +
  86 + D60 d60 = d60Map.get(msgId);
  87 +
  88 + if (null == d60) {
  89 + logger.error("找不到msgId: " + msgId + " 对应的指令数据");
  90 + return;
  91 + }
  92 +
  93 + switch (res.getStatus()) {
  94 + case 0:
  95 + d60.setReply46((short) -1);// 失败
  96 + break;
  97 + case 1:
  98 + d60.setReply46((short) 0);// 发送成功
  99 + d60.setReply46Time(System.currentTimeMillis());
  100 + break;
  101 + case 2:
  102 + d60.setReply47((short) 0);// 驾驶员阅读
  103 + d60.setReply47Time(System.currentTimeMillis());
  104 + break;
  105 + }
  106 +
  107 + //更新60数据
  108 + pstD60s.add(d60);
  109 +
  110 + ScheduleRealInfo sch = d60.getSch();
  111 + if (null == sch)
  112 + return;
  113 +
  114 + if (d60.isDispatch()) {
  115 + // 更新班次状态
  116 + sch.setDirectiveState(res.getStatus() * 100);
  117 + // 通知页面
  118 + sendUtils.sendDirectiveToPage(sch);
  119 + }
  120 + }
  121 +
  122 + /**
  123 + *
  124 + * @Title: reply64 @Description: TODO(64 协议响应) @throws
  125 + */
  126 + public void reply64(JSONObject json) {
  127 + String key = json.getString("deviceId") + "_" + json.getString("timestamp");
  128 +
  129 + D64 d64 = d64Map.get(key);
  130 +
  131 + if (null == d64)
  132 + logger.warn("64响应 -找不到请求源,json: " + json);
  133 + else {
  134 + JSONObject data = json.getJSONObject("data");
  135 +
  136 + if (null == data)
  137 + logger.warn("64响应 data is null ,json: " + json);
  138 + else {
  139 + logger.info(d64.getDeviceId() + "_" + d64.getData().getLineId() + "响应:" + data.getShort("requestAck"));
  140 + ScheduleRealInfo sch = d64.getSch();
  141 + if (sch != null) {
  142 + sch.setRegionSwitchState(1);
  143 + }
  144 + /*d64.setRespAck(data.getShort("requestAck"));
  145 + // 持久化*/
  146 + //64 响应不入库了...
  147 + }
  148 + }
  149 + }
  150 +
  151 + @Autowired
  152 + DirectivesPstThread directivesPstThread;
  153 + public void clearAll(){
  154 + d60Map = new ConcurrentHashMap<>();
  155 + d64Map = new ConcurrentHashMap<>();
  156 + logger.info("清除指令数据 ,,,");
  157 + }
  158 +
  159 + public Collection<D60> all60(){
  160 + return d60Map.values();
  161 + }
  162 +
  163 + public Collection<D64> all64(){
  164 + return d64Map.values();
  165 + }
  166 +
  167 + public D60 get(Integer msgId){
  168 + return d60Map.get(msgId);
  169 + }
  170 +
  171 + public Collection<Directive> all(){
  172 + List<Directive> all = new ArrayList<>();
  173 + all.addAll(d60Map.values());
  174 + all.addAll(d64Map.values());
  175 +
  176 + return all;
  177 + }
  178 +
  179 + public static class DComparator implements Comparator<Directive>{
  180 +
  181 + @Override
  182 + public int compare(Directive d1, Directive d2) {
  183 + return (int) (d2.getTimestamp() - d1.getTimestamp());
  184 + }
  185 + }
  186 + }
src/main/java/com/bsth/data/directive/DirectiveCreator.java
1 -package com.bsth.data.directive;  
2 -  
3 -import com.alibaba.fastjson.JSON;  
4 -import com.bsth.data.BasicData;  
5 -import com.bsth.entity.directive.D60;  
6 -import com.bsth.entity.directive.D60.D60Data;  
7 -import com.bsth.entity.directive.D64;  
8 -import com.bsth.entity.directive.D64.D64Data;  
9 -import org.slf4j.Logger;  
10 -import org.slf4j.LoggerFactory;  
11 -  
12 -import java.text.SimpleDateFormat;  
13 -import java.util.Date;  
14 -import java.util.HashMap;  
15 -import java.util.Map;  
16 -  
17 -/**  
18 - *  
19 - * @ClassName: DirectiveCreator  
20 - * @Description: TODO(指令数据生成)  
21 - * @author PanZhao  
22 - * @date 2016年8月14日 下午9:57:07  
23 - *  
24 - */  
25 -public class DirectiveCreator {  
26 -  
27 - // 城市代码  
28 - static final short cityCode = 22;  
29 -  
30 - static Logger logger = LoggerFactory.getLogger(DirectiveCreator.class);  
31 -  
32 - /**  
33 - *  
34 - * @Title: createDirective60  
35 - * @Description: TODO(创建60数据包)  
36 - * @param @param nbbm 车辆内部编码  
37 - * @param @param text 文本  
38 - * @param @param dispatchInstruct 指令类型(0X00表示信息短语,0X01表示取消上次指令+调度指令(闹钟有效),0x02表示为调度指令(闹钟有效); 0x03表示运营状态指令(闹钟无效);0x04表示其他指令)  
39 - * @param @param upDown 上下行(0 上行 1 下行)  
40 - * @param @param state 营运状态(0 营运 1 非营运)  
41 - * @param @return 设定文件  
42 - * @return Directive60 返回类型  
43 - * @throws  
44 - */  
45 - public D60 createD60(String nbbm, String text, Short dispatchInstruct, int upDown, int state,String lineCode) {  
46 - Long timestamp = System.currentTimeMillis();  
47 -  
48 - Short company = Short.parseShort(BasicData.nbbm2CompanyCodeMap.get(nbbm));  
49 - String deviceId = BasicData.deviceId2NbbmMap.inverse().get(nbbm);  
50 -  
51 - int msgId = MsgIdGenerator.getMsgId();  
52 -  
53 - D60 directive = new D60();  
54 - D60Data data = new D60Data();  
55 - // 一级协议  
56 - directive.setOperCode((short) 0x60);  
57 - // 设备号  
58 - directive.setDeviceId(deviceId);  
59 - // 时间戳  
60 - directive.setTimestamp(timestamp);  
61 - directive.setMsgId(msgId);  
62 - // 构造数据  
63 - data.setDeviceId(deviceId);  
64 - data.setDispatchInstruct(dispatchInstruct);  
65 - data.setTimestamp(timestamp);  
66 - data.setCompanyCode(company);  
67 - data.setMsgId(msgId);  
68 - directive.setData(data);  
69 - directive.setLineCode(lineCode);  
70 - long serviceState;  
71 - try {  
72 - serviceState = Consts.SERVICE_STATE[upDown][state];  
73 - } catch (IndexOutOfBoundsException e) {  
74 - // 未知营运状态的直接默认为上行非营运  
75 - serviceState = Consts.SERVICE_STATE[0][1];  
76 - }  
77 - data.setServiceState(serviceState);  
78 - data.setTxtContent(text);  
79 -  
80 - return directive;  
81 - }  
82 -  
83 -  
84 - public D60 createD60_02(String nbbm, String text, int upDown, int state, Date alarmTime){  
85 - SimpleDateFormat sdfMMddHHmm = new SimpleDateFormat("MMddHHmm");  
86 -  
87 - Long timestamp = System.currentTimeMillis();  
88 -  
89 - Short company = Short.parseShort(BasicData.nbbm2CompanyCodeMap.get(nbbm));  
90 - String deviceId = BasicData.deviceId2NbbmMap.inverse().get(nbbm);  
91 -  
92 - int msgId = MsgIdGenerator.getMsgId();  
93 -  
94 - D60 directive = new D60();  
95 - D60Data data = new D60Data();  
96 - // 一级协议  
97 - directive.setOperCode((short) 0x60);  
98 - // 设备号  
99 - directive.setDeviceId(deviceId);  
100 - // 时间戳  
101 - directive.setTimestamp(timestamp);  
102 - directive.setMsgId(msgId);  
103 - // 构造数据  
104 - data.setDeviceId(deviceId);  
105 - data.setDispatchInstruct((short) 0x02);  
106 - data.setTimestamp(timestamp);  
107 - data.setCompanyCode(company);  
108 - data.setMsgId(msgId);  
109 - data.setAlarmTime(Long.parseLong(sdfMMddHHmm.format(alarmTime)));  
110 - directive.setData(data);  
111 - long serviceState;  
112 - try {  
113 - serviceState = Consts.SERVICE_STATE[upDown][state];  
114 - } catch (IndexOutOfBoundsException e) {  
115 - // 未知营运状态的直接默认为上行非营运  
116 - serviceState = Consts.SERVICE_STATE[0][1];  
117 - }  
118 - data.setServiceState(serviceState);  
119 - data.setTxtContent(text);  
120 - return directive;  
121 - }  
122 -  
123 - /**  
124 - *  
125 - * @Title: createD64  
126 - * @Description: TODO(创建线路切换指令 64)  
127 - * @param @param nbbm 车辆内部编码  
128 - * @param @param lineId 线路编码  
129 - * @param @param t 时间戳  
130 - * @throws  
131 -  
132 - public D64 createD64(String nbbm, String lineCode, long t){  
133 - String deviceId = BasicData.deviceId2NbbmMap.inverse().get(nbbm);  
134 - return create64(deviceId, lineCode, t);  
135 - }*/  
136 -  
137 - public D64 create64(String deviceId, String lineCode, long t){  
138 - D64 change = new D64();  
139 - D64Data data = new D64Data();  
140 - data.setCityCode(cityCode);  
141 - data.setDeviceId(deviceId);  
142 -  
143 - //线路编码补满6位数  
144 - String lineCodeStr = padLeft(lineCode, 6, '0');  
145 - data.setLineId(lineCodeStr);  
146 -  
147 - change.setDeviceId(deviceId);  
148 - change.setOperCode((short) 0X64);  
149 - change.setTimestamp(t);  
150 - change.setData(data);  
151 -  
152 - return change;  
153 - }  
154 -  
155 - /**  
156 - *  
157 - * @Title: createDeviceRefreshData  
158 - * @Description: TODO(线路刷新指令(用于切换线路后,要求设置重新下载线路文件))  
159 - * @param @param deviceId 设备编号  
160 - * @param @param lineId 线路ID  
161 - * @throws  
162 - */  
163 - public String createDeviceRefreshData(String deviceId, String lineCode) {  
164 - Long t = System.currentTimeMillis();  
165 - Map<String, Object> param = new HashMap<>();  
166 - param.put("deviceId", deviceId);  
167 - param.put("timestamp", t);  
168 - param.put("operCode", 0Xc0);  
169 -  
170 - Map<String, Object> data = new HashMap<>();  
171 - data.put("operCode2", 0xa1);  
172 - data.put("cityCode", cityCode);  
173 - data.put("deviceId", deviceId);  
174 - data.put("timestamp", t);  
175 - data.put("centerId", 1);  
176 -  
177 - //线路编码补满6位数  
178 - String lineCodeStr = padLeft(lineCode, 6, '0');  
179 -  
180 - data.put("lineId", lineCodeStr);  
181 - data.put("lineVersion", 0);  
182 - data.put("carparkDataVersion", 0);  
183 - param.put("data", data);  
184 -  
185 - return JSON.toJSONString(param);  
186 - }  
187 -  
188 - public String padLeft(String oriStr,int len,char alexin){  
189 - String str = "";  
190 - int strlen = oriStr.length();  
191 - if(strlen < len){  
192 - for(int i=0;i<len-strlen;i++){  
193 - str = str+alexin;  
194 - }  
195 - }  
196 - str = str + oriStr;  
197 - return str;  
198 - }  
199 -} 1 +package com.bsth.data.directive;
  2 +
  3 +import com.alibaba.fastjson.JSON;
  4 +import com.bsth.data.BasicData;
  5 +import com.bsth.entity.directive.D60;
  6 +import com.bsth.entity.directive.D60.D60Data;
  7 +import com.bsth.entity.directive.D64;
  8 +import com.bsth.entity.directive.D64.D64Data;
  9 +import com.bsth.entity.realcontrol.ScheduleRealInfo;
  10 +import org.slf4j.Logger;
  11 +import org.slf4j.LoggerFactory;
  12 +import org.springframework.util.StringUtils;
  13 +
  14 +import java.text.SimpleDateFormat;
  15 +import java.util.Date;
  16 +import java.util.HashMap;
  17 +import java.util.Map;
  18 +
  19 +/**
  20 + *
  21 + * @ClassName: DirectiveCreator
  22 + * @Description: TODO(指令数据生成)
  23 + * @author PanZhao
  24 + * @date 2016年8月14日 下午9:57:07
  25 + *
  26 + */
  27 +public class DirectiveCreator {
  28 +
  29 + // 城市代码
  30 + static final short cityCode = 22;
  31 +
  32 + static Logger logger = LoggerFactory.getLogger(DirectiveCreator.class);
  33 +
  34 + /**
  35 + *
  36 + * @Title: createDirective60
  37 + * @Description: TODO(创建60数据包)
  38 + * @param @param nbbm 车辆内部编码
  39 + * @param @param text 文本
  40 + * @param @param dispatchInstruct 指令类型(0X00表示信息短语,0X01表示取消上次指令+调度指令(闹钟有效),0x02表示为调度指令(闹钟有效); 0x03表示运营状态指令(闹钟无效);0x04表示其他指令)
  41 + * @param @param upDown 上下行(0 上行 1 下行)
  42 + * @param @param state 营运状态(0 营运 1 非营运)
  43 + * @param @return 设定文件
  44 + * @return Directive60 返回类型
  45 + * @throws
  46 + */
  47 + public D60 createD60(String nbbm, String text, Short dispatchInstruct, int upDown, int state,String lineCode) {
  48 + Long timestamp = System.currentTimeMillis();
  49 +
  50 + Short company = Short.parseShort(BasicData.nbbm2CompanyCodeMap.get(nbbm));
  51 + String deviceId = BasicData.deviceId2NbbmMap.inverse().get(nbbm);
  52 +
  53 + int msgId = MsgIdGenerator.getMsgId();
  54 +
  55 + D60 directive = new D60();
  56 + D60Data data = new D60Data();
  57 + // 一级协议
  58 + directive.setOperCode((short) 0x60);
  59 + // 设备号
  60 + directive.setDeviceId(deviceId);
  61 + // 时间戳
  62 + directive.setTimestamp(timestamp);
  63 + directive.setMsgId(msgId);
  64 + // 构造数据
  65 + data.setDeviceId(deviceId);
  66 + data.setDispatchInstruct(dispatchInstruct);
  67 + data.setTimestamp(timestamp);
  68 + data.setCompanyCode(company);
  69 + data.setMsgId(msgId);
  70 + directive.setData(data);
  71 + directive.setLineCode(lineCode);
  72 + long serviceState;
  73 + try {
  74 + serviceState = Consts.SERVICE_STATE[upDown][state];
  75 + } catch (IndexOutOfBoundsException e) {
  76 + // 未知营运状态的直接默认为上行非营运
  77 + serviceState = Consts.SERVICE_STATE[0][1];
  78 + }
  79 + data.setServiceState(serviceState);
  80 + data.setTxtContent(text);
  81 +
  82 + return directive;
  83 + }
  84 +
  85 +
  86 + public D60 createD60_02(String nbbm, String text, int upDown, int state, Date alarmTime){
  87 + SimpleDateFormat sdfMMddHHmm = new SimpleDateFormat("MMddHHmm");
  88 +
  89 + Long timestamp = System.currentTimeMillis();
  90 +
  91 + Short company = Short.parseShort(BasicData.nbbm2CompanyCodeMap.get(nbbm));
  92 + String deviceId = BasicData.deviceId2NbbmMap.inverse().get(nbbm);
  93 +
  94 + int msgId = MsgIdGenerator.getMsgId();
  95 +
  96 + D60 directive = new D60();
  97 + D60Data data = new D60Data();
  98 + // 一级协议
  99 + directive.setOperCode((short) 0x60);
  100 + // 设备号
  101 + directive.setDeviceId(deviceId);
  102 + // 时间戳
  103 + directive.setTimestamp(timestamp);
  104 + directive.setMsgId(msgId);
  105 + // 构造数据
  106 + data.setDeviceId(deviceId);
  107 + data.setDispatchInstruct((short) 0x02);
  108 + data.setTimestamp(timestamp);
  109 + data.setCompanyCode(company);
  110 + data.setMsgId(msgId);
  111 + data.setAlarmTime(Long.parseLong(sdfMMddHHmm.format(alarmTime)));
  112 + directive.setData(data);
  113 + long serviceState;
  114 + try {
  115 + serviceState = Consts.SERVICE_STATE[upDown][state];
  116 + } catch (IndexOutOfBoundsException e) {
  117 + // 未知营运状态的直接默认为上行非营运
  118 + serviceState = Consts.SERVICE_STATE[0][1];
  119 + }
  120 + data.setServiceState(serviceState);
  121 + data.setTxtContent(text);
  122 + return directive;
  123 + }
  124 +
  125 + /**
  126 + *
  127 + * @Title: createD64
  128 + * @Description: TODO(创建线路切换指令 64)
  129 + * @param @param nbbm 车辆内部编码
  130 + * @param @param lineId 线路编码
  131 + * @param @param t 时间戳
  132 + * @throws
  133 +
  134 + public D64 createD64(String nbbm, String lineCode, long t){
  135 + String deviceId = BasicData.deviceId2NbbmMap.inverse().get(nbbm);
  136 + return create64(deviceId, lineCode, t);
  137 + }*/
  138 +
  139 + public D64 create64(String deviceId, String lineCode, ScheduleRealInfo sch, long t){
  140 + D64 change = new D64();
  141 + D64Data data = new D64Data();
  142 + data.setCityCode(cityCode);
  143 + data.setDeviceId(deviceId);
  144 +
  145 + //线路编码补满6位数
  146 + String lineCodeStr = padLeft(lineCode, 6, '0');
  147 + data.setLineId(lineCodeStr);
  148 + int seq = 0;
  149 + if (sch != null) {
  150 + String regionId = sch.getRegionId();
  151 + if (StringUtils.hasText(regionId)) {
  152 + seq = Integer.parseInt(regionId.split("_")[1]);
  153 + }
  154 + }
  155 + data.setSeq(seq);
  156 +
  157 + change.setDeviceId(deviceId);
  158 + change.setOperCode((short) 0X64);
  159 + change.setTimestamp(t);
  160 + change.setData(data);
  161 + change.setSch(sch);
  162 +
  163 + return change;
  164 + }
  165 +
  166 + /**
  167 + *
  168 + * @Title: createDeviceRefreshData
  169 + * @Description: TODO(线路刷新指令(用于切换线路后,要求设置重新下载线路文件))
  170 + * @param @param deviceId 设备编号
  171 + * @param @param lineId 线路ID
  172 + * @throws
  173 + */
  174 + public String createDeviceRefreshData(String deviceId, String lineCode) {
  175 + Long t = System.currentTimeMillis();
  176 + Map<String, Object> param = new HashMap<>();
  177 + param.put("deviceId", deviceId);
  178 + param.put("timestamp", t);
  179 + param.put("operCode", 0Xc0);
  180 +
  181 + Map<String, Object> data = new HashMap<>();
  182 + data.put("operCode2", 0xa1);
  183 + data.put("cityCode", cityCode);
  184 + data.put("deviceId", deviceId);
  185 + data.put("timestamp", t);
  186 + data.put("centerId", 1);
  187 +
  188 + //线路编码补满6位数
  189 + String lineCodeStr = padLeft(lineCode, 6, '0');
  190 +
  191 + data.put("lineId", lineCodeStr);
  192 + data.put("lineVersion", 0);
  193 + data.put("carparkDataVersion", 0);
  194 + param.put("data", data);
  195 +
  196 + return JSON.toJSONString(param);
  197 + }
  198 +
  199 + public String padLeft(String oriStr,int len,char alexin){
  200 + String str = "";
  201 + int strlen = oriStr.length();
  202 + if(strlen < len){
  203 + for(int i=0;i<len-strlen;i++){
  204 + str = str+alexin;
  205 + }
  206 + }
  207 + str = str + oriStr;
  208 + return str;
  209 + }
  210 +}
src/main/java/com/bsth/data/gpsdata_v2/handlers/GpsStateProcess.java
1 -package com.bsth.data.gpsdata_v2.handlers;  
2 -  
3 -import com.bsth.data.gpsdata_v2.entity.GpsEntity;  
4 -import com.bsth.data.gpsdata_v2.status_manager.GpsStatusManager;  
5 -import com.bsth.data.schedule.DayOfSchedule;  
6 -import com.bsth.entity.realcontrol.ScheduleRealInfo;  
7 -import org.springframework.beans.factory.annotation.Autowired;  
8 -import org.springframework.stereotype.Component;  
9 -  
10 -import java.util.concurrent.ConcurrentHashMap;  
11 -import java.util.concurrent.ConcurrentMap;  
12 -  
13 -/**  
14 - * GPS 状态处理  
15 - * Created by panzhao on 2017/11/15.  
16 - */  
17 -@Component  
18 -public class GpsStateProcess {  
19 -  
20 - @Autowired  
21 - DayOfSchedule dayOfSchedule;  
22 -  
23 - @Autowired  
24 - GpsStatusManager gpsStatusManager;  
25 -  
26 - /**  
27 - * 设置状态差异连续次数  
28 - */  
29 - private static ConcurrentMap<String, Integer> stateDiffMap = new ConcurrentHashMap<>();  
30 -  
31 - private final static int CHANGE_THRESHOLD = 2;  
32 -  
33 - public void process(GpsEntity gps) {  
34 - //在执行的任务  
35 - ScheduleRealInfo sch = dayOfSchedule.executeCurr(gps.getNbbm());  
36 -  
37 - if (null == sch)  
38 - return;  
39 -  
40 - int upDown = Integer.parseInt(sch.getXlDir());  
41 - int schState = dayOfSchedule.emptyService(sch)?1:0;  
42 - String device = gps.getDeviceId();  
43 - /**  
44 - * 网关在进终点的时候,会直接将当前点位状态改变  
45 - * 为避免出现单个点的状态跳动,设置一下切换阈值  
46 - */  
47 - if(gps.getState() != schState || gps.getUpDown() != upDown){  
48 - Integer count = 0;  
49 - if(stateDiffMap.containsKey(device))  
50 - count = stateDiffMap.get(device);  
51 -  
52 - count ++;  
53 -  
54 - if(count >= CHANGE_THRESHOLD){  
55 - //下发指令纠正车载的 营运状态 和 走向  
56 - gpsStatusManager.changeServiceState(gps.getNbbm(), upDown, schState, "同步@系统");  
57 - count = 0;  
58 - }  
59 -  
60 - stateDiffMap.put(device, count);  
61 -  
62 - //记录原始设备状态  
63 - gps.setOrigStateStr(gps.getUpDown() + "_" + gps.getState());  
64 - }  
65 - else  
66 - stateDiffMap.put(device, 0);  
67 -  
68 - if (gps.getUpDown() != upDown) {  
69 - gps.setUpDown((byte) upDown);//修正走向  
70 - }  
71 -  
72 - if(gps.getState() != schState){  
73 - gps.setState(schState);//修正营运状态  
74 - }  
75 -  
76 - if (!sch.getXlBm().equals(gps.getLineId())) {  
77 - //切换车载的 线路编码  
78 - gpsStatusManager.changeLine(gps.getNbbm(), sch.getXlBm(), "同步@系统");  
79 - }  
80 - }  
81 -} 1 +package com.bsth.data.gpsdata_v2.handlers;
  2 +
  3 +import com.bsth.data.gpsdata_v2.entity.GpsEntity;
  4 +import com.bsth.data.gpsdata_v2.status_manager.GpsStatusManager;
  5 +import com.bsth.data.schedule.DayOfSchedule;
  6 +import com.bsth.entity.realcontrol.ScheduleRealInfo;
  7 +import org.springframework.beans.factory.annotation.Autowired;
  8 +import org.springframework.stereotype.Component;
  9 +import org.springframework.util.StringUtils;
  10 +
  11 +import java.util.concurrent.ConcurrentHashMap;
  12 +import java.util.concurrent.ConcurrentMap;
  13 +
  14 +/**
  15 + * GPS 状态处理
  16 + * Created by panzhao on 2017/11/15.
  17 + */
  18 +@Component
  19 +public class GpsStateProcess {
  20 +
  21 + @Autowired
  22 + DayOfSchedule dayOfSchedule;
  23 +
  24 + @Autowired
  25 + GpsStatusManager gpsStatusManager;
  26 +
  27 + /**
  28 + * 设置状态差异连续次数
  29 + */
  30 + private static ConcurrentMap<String, Integer> stateDiffMap = new ConcurrentHashMap<>();
  31 +
  32 + private final static int CHANGE_THRESHOLD = 2;
  33 +
  34 + public void process(GpsEntity gps) {
  35 + if ("W7G-083".equals(gps.getNbbm())) {
  36 + System.out.println("a");
  37 + }
  38 + //在执行的任务
  39 + ScheduleRealInfo sch = dayOfSchedule.executeCurr(gps.getNbbm());
  40 +
  41 + if (null == sch)
  42 + return;
  43 +
  44 + int upDown = Integer.parseInt(sch.getXlDir());
  45 + int schState = dayOfSchedule.emptyService(sch)?1:0;
  46 + String device = gps.getDeviceId();
  47 + /**
  48 + * 网关在进终点的时候,会直接将当前点位状态改变
  49 + * 为避免出现单个点的状态跳动,设置一下切换阈值
  50 + */
  51 + if(gps.getState() != schState || gps.getUpDown() != upDown){
  52 + Integer count = 0;
  53 + if(stateDiffMap.containsKey(device))
  54 + count = stateDiffMap.get(device);
  55 +
  56 + count ++;
  57 +
  58 + if(count >= CHANGE_THRESHOLD){
  59 + //下发指令纠正车载的 营运状态 和 走向
  60 + gpsStatusManager.changeServiceState(gps.getNbbm(), upDown, schState, "同步@系统");
  61 + count = 0;
  62 + }
  63 +
  64 + stateDiffMap.put(device, count);
  65 +
  66 + //记录原始设备状态
  67 + gps.setOrigStateStr(gps.getUpDown() + "_" + gps.getState());
  68 + }
  69 + else
  70 + stateDiffMap.put(device, 0);
  71 +
  72 + if (gps.getUpDown() != upDown) {
  73 + gps.setUpDown((byte) upDown);//修正走向
  74 + }
  75 +
  76 + if(gps.getState() != schState){
  77 + gps.setState(schState);//修正营运状态
  78 + }
  79 +
  80 + // 线路编码不一致或者未接收到切换区间线的响应
  81 + if (!sch.getXlBm().equals(gps.getLineId()) || StringUtils.hasText(sch.getRegionId()) && sch.getRegionSwitchState() == 0) {
  82 + //切换车载的 线路编码
  83 + gpsStatusManager.changeLine(gps.getNbbm(), sch, "同步@系统");
  84 + }
  85 + }
  86 +}
src/main/java/com/bsth/data/gpsdata_v2/handlers/InStationProcess.java
@@ -183,7 +183,7 @@ public class InStationProcess { @@ -183,7 +183,7 @@ public class InStationProcess {
183 183
184 //套跑 -下发线路切换指令 184 //套跑 -下发线路切换指令
185 if (null != next && !next.getXlBm().equals(sch.getXlBm())) { 185 if (null != next && !next.getXlBm().equals(sch.getXlBm())) {
186 - gpsStatusManager.changeLine(next.getClZbh(), next.getXlBm(), "套跑@系统"); 186 + gpsStatusManager.changeLine(next.getClZbh(), next, "套跑@系统");
187 } 187 }
188 188
189 /** 189 /**
src/main/java/com/bsth/data/gpsdata_v2/rfid/handle/RfidSignalHandle.java
1 -package com.bsth.data.gpsdata_v2.rfid.handle;  
2 -  
3 -import com.bsth.data.gpsdata_v2.rfid.entity.RfidInoutStation;  
4 -import com.bsth.data.gpsdata_v2.status_manager.GpsStatusManager;  
5 -import com.bsth.data.msg_queue.DirectivePushQueue;  
6 -import com.bsth.data.schedule.DayOfSchedule;  
7 -import com.bsth.entity.realcontrol.ScheduleRealInfo;  
8 -import com.bsth.websocket.handler.SendUtils;  
9 -import org.apache.commons.lang3.StringUtils;  
10 -import org.slf4j.Logger;  
11 -import org.slf4j.LoggerFactory;  
12 -import org.springframework.beans.factory.annotation.Autowired;  
13 -import org.springframework.stereotype.Component;  
14 -  
15 -import java.util.List;  
16 -  
17 -/**  
18 - * RFID信号处理  
19 - * Created by panzhao on 2017/11/22.  
20 - */  
21 -@Component  
22 -public class RfidSignalHandle {  
23 -  
24 - @Autowired  
25 - DayOfSchedule dayOfSchedule;  
26 -  
27 - @Autowired  
28 - SendUtils sendUtils;  
29 -  
30 - @Autowired  
31 - GpsStatusManager gpsStatusManager;  
32 -  
33 - private final static int MAX_TIME_DIFF = 1000 * 60 * 60 * 2;  
34 -  
35 - Logger logger = LoggerFactory.getLogger(this.getClass());  
36 -  
37 - public void handle(List<RfidInoutStation> list){  
38 - for(RfidInoutStation signal : list){  
39 - if(signal.getType()==2)  
40 - in(signal);  
41 - else if(signal.getType()==4)  
42 - out(signal);  
43 - }  
44 - }  
45 -  
46 - /**  
47 - * 出  
48 - * @param signal  
49 - */  
50 - private void out(RfidInoutStation signal) {  
51 - try{  
52 - String nbbm = signal.getNbbm();  
53 - ScheduleRealInfo sch = dayOfSchedule.executeCurr(nbbm);  
54 -  
55 - if(null == sch)  
56 - return;  
57 -  
58 - //最大时间差  
59 - if(Math.abs(sch.getDfsjT() - signal.getT()) > MAX_TIME_DIFF)  
60 - return;  
61 -  
62 - if(sch.getQdzCode().equals(signal.getStation())  
63 - && StringUtils.isEmpty(sch.getFcsjActual())){  
64 -  
65 - //班次发车  
66 - sch.setFcsjActualAll(signal.getT());  
67 -  
68 - //webSocket  
69 - sendUtils.sendFcsj(sch);  
70 -  
71 - //持久化  
72 - dayOfSchedule.save(sch);  
73 -  
74 - logger.info("RFID; 车辆:" + sch.getClZbh() + " 班次:" + sch.getDfsj() + "发车, 时间:" + sch.getFcsjActual());  
75 - }  
76 - }catch (Exception e){  
77 - logger.error("", e);  
78 - }  
79 - }  
80 -  
81 - /**  
82 - * 进  
83 - * @param signal  
84 - */  
85 - private void in(RfidInoutStation signal) {  
86 - try{  
87 - String nbbm = signal.getNbbm();  
88 - ScheduleRealInfo sch = dayOfSchedule.executeCurr(nbbm);  
89 -  
90 - if(null == sch)  
91 - return;  
92 -  
93 - //最大时间差  
94 - if(Math.abs(sch.getDfsjT() - signal.getT()) > MAX_TIME_DIFF)  
95 - return;  
96 -  
97 - if(sch.getZdzCode().equals(signal.getStation())  
98 - && StringUtils.isEmpty(sch.getZdsjActual())){  
99 -  
100 - sch.setZdsjActualAll(signal.getT());  
101 -  
102 - //持久化  
103 - dayOfSchedule.save(sch);  
104 -  
105 - //车辆的下一个班次  
106 - ScheduleRealInfo next = dayOfSchedule.next(sch);  
107 - if(next != null){  
108 - dayOfSchedule.addExecPlan(next);  
109 - }  
110 -  
111 - //路牌的下一个班次,页面显示起点实际到达时间  
112 - ScheduleRealInfo lpNext = dayOfSchedule.nextByLp(sch);  
113 - if(lpNext != null){  
114 - lpNext.setQdzArrDatesj(sch.getZdsjActual());  
115 - }  
116 -  
117 - //已完成班次数  
118 - int doneSum = dayOfSchedule.doneSum(nbbm);  
119 -  
120 - //webSocket  
121 - sendUtils.sendZdsj(sch, lpNext, doneSum);  
122 -  
123 - logger.info("RFID; 车辆:" + nbbm + " 班次:" + sch.getDfsj() + "到终点, 时间:" + sch.getZdsjActual());  
124 -  
125 - //下发调度指令  
126 - DirectivePushQueue.put6002(next, doneSum, "rfid@系统", "");  
127 -  
128 - //套跑 -下发线路切换指令  
129 - if(null != next && !next.getXlBm().equals(sch.getXlBm())){  
130 - gpsStatusManager.changeLine(next.getClZbh(), next.getXlBm(), "rfid@系统");  
131 - }  
132 -  
133 - if(null == next)  
134 - nonService(sch, "rfid1@系统");//班次结束  
135 - else if(null != next && dayOfSchedule.emptyService(next))  
136 - nonService(sch, "rfid2@系统");//下一班非营运  
137 - }  
138 - }catch (Exception e){  
139 - logger.error("", e);  
140 - }  
141 - }  
142 -  
143 - /**  
144 - * 将车载设备切换为非营运状态  
145 - * @param sch  
146 - * @param sender  
147 - */  
148 - private void nonService(ScheduleRealInfo sch, String sender){  
149 - gpsStatusManager.changeServiceState(sch.getClZbh(), sch.getXlDir(), 1, sender);  
150 - } 1 +package com.bsth.data.gpsdata_v2.rfid.handle;
  2 +
  3 +import com.bsth.data.gpsdata_v2.rfid.entity.RfidInoutStation;
  4 +import com.bsth.data.gpsdata_v2.status_manager.GpsStatusManager;
  5 +import com.bsth.data.msg_queue.DirectivePushQueue;
  6 +import com.bsth.data.schedule.DayOfSchedule;
  7 +import com.bsth.entity.realcontrol.ScheduleRealInfo;
  8 +import com.bsth.websocket.handler.SendUtils;
  9 +import org.apache.commons.lang3.StringUtils;
  10 +import org.slf4j.Logger;
  11 +import org.slf4j.LoggerFactory;
  12 +import org.springframework.beans.factory.annotation.Autowired;
  13 +import org.springframework.stereotype.Component;
  14 +
  15 +import java.util.List;
  16 +
  17 +/**
  18 + * RFID信号处理
  19 + * Created by panzhao on 2017/11/22.
  20 + */
  21 +@Component
  22 +public class RfidSignalHandle {
  23 +
  24 + @Autowired
  25 + DayOfSchedule dayOfSchedule;
  26 +
  27 + @Autowired
  28 + SendUtils sendUtils;
  29 +
  30 + @Autowired
  31 + GpsStatusManager gpsStatusManager;
  32 +
  33 + private final static int MAX_TIME_DIFF = 1000 * 60 * 60 * 2;
  34 +
  35 + Logger logger = LoggerFactory.getLogger(this.getClass());
  36 +
  37 + public void handle(List<RfidInoutStation> list){
  38 + for(RfidInoutStation signal : list){
  39 + if(signal.getType()==2)
  40 + in(signal);
  41 + else if(signal.getType()==4)
  42 + out(signal);
  43 + }
  44 + }
  45 +
  46 + /**
  47 + * 出
  48 + * @param signal
  49 + */
  50 + private void out(RfidInoutStation signal) {
  51 + try{
  52 + String nbbm = signal.getNbbm();
  53 + ScheduleRealInfo sch = dayOfSchedule.executeCurr(nbbm);
  54 +
  55 + if(null == sch)
  56 + return;
  57 +
  58 + //最大时间差
  59 + if(Math.abs(sch.getDfsjT() - signal.getT()) > MAX_TIME_DIFF)
  60 + return;
  61 +
  62 + if(sch.getQdzCode().equals(signal.getStation())
  63 + && StringUtils.isEmpty(sch.getFcsjActual())){
  64 +
  65 + //班次发车
  66 + sch.setFcsjActualAll(signal.getT());
  67 +
  68 + //webSocket
  69 + sendUtils.sendFcsj(sch);
  70 +
  71 + //持久化
  72 + dayOfSchedule.save(sch);
  73 +
  74 + logger.info("RFID; 车辆:" + sch.getClZbh() + " 班次:" + sch.getDfsj() + "发车, 时间:" + sch.getFcsjActual());
  75 + }
  76 + }catch (Exception e){
  77 + logger.error("", e);
  78 + }
  79 + }
  80 +
  81 + /**
  82 + * 进
  83 + * @param signal
  84 + */
  85 + private void in(RfidInoutStation signal) {
  86 + try{
  87 + String nbbm = signal.getNbbm();
  88 + ScheduleRealInfo sch = dayOfSchedule.executeCurr(nbbm);
  89 +
  90 + if(null == sch)
  91 + return;
  92 +
  93 + //最大时间差
  94 + if(Math.abs(sch.getDfsjT() - signal.getT()) > MAX_TIME_DIFF)
  95 + return;
  96 +
  97 + if(sch.getZdzCode().equals(signal.getStation())
  98 + && StringUtils.isEmpty(sch.getZdsjActual())){
  99 +
  100 + sch.setZdsjActualAll(signal.getT());
  101 +
  102 + //持久化
  103 + dayOfSchedule.save(sch);
  104 +
  105 + //车辆的下一个班次
  106 + ScheduleRealInfo next = dayOfSchedule.next(sch);
  107 + if(next != null){
  108 + dayOfSchedule.addExecPlan(next);
  109 + }
  110 +
  111 + //路牌的下一个班次,页面显示起点实际到达时间
  112 + ScheduleRealInfo lpNext = dayOfSchedule.nextByLp(sch);
  113 + if(lpNext != null){
  114 + lpNext.setQdzArrDatesj(sch.getZdsjActual());
  115 + }
  116 +
  117 + //已完成班次数
  118 + int doneSum = dayOfSchedule.doneSum(nbbm);
  119 +
  120 + //webSocket
  121 + sendUtils.sendZdsj(sch, lpNext, doneSum);
  122 +
  123 + logger.info("RFID; 车辆:" + nbbm + " 班次:" + sch.getDfsj() + "到终点, 时间:" + sch.getZdsjActual());
  124 +
  125 + //下发调度指令
  126 + DirectivePushQueue.put6002(next, doneSum, "rfid@系统", "");
  127 +
  128 + //套跑 -下发线路切换指令
  129 + if(null != next && !next.getXlBm().equals(sch.getXlBm())){
  130 + gpsStatusManager.changeLine(next.getClZbh(), next, "rfid@系统");
  131 + }
  132 +
  133 + if(null == next)
  134 + nonService(sch, "rfid1@系统");//班次结束
  135 + else if(null != next && dayOfSchedule.emptyService(next))
  136 + nonService(sch, "rfid2@系统");//下一班非营运
  137 + }
  138 + }catch (Exception e){
  139 + logger.error("", e);
  140 + }
  141 + }
  142 +
  143 + /**
  144 + * 将车载设备切换为非营运状态
  145 + * @param sch
  146 + * @param sender
  147 + */
  148 + private void nonService(ScheduleRealInfo sch, String sender){
  149 + gpsStatusManager.changeServiceState(sch.getClZbh(), sch.getXlDir(), 1, sender);
  150 + }
151 } 151 }
152 \ No newline at end of file 152 \ No newline at end of file
src/main/java/com/bsth/data/gpsdata_v2/status_manager/GpsStatusManager.java
1 -package com.bsth.data.gpsdata_v2.status_manager;  
2 -  
3 -import com.bsth.Application;  
4 -import com.bsth.data.gpsdata_v2.status_manager.gps_line_state.LineStateHandle;  
5 -import com.bsth.data.gpsdata_v2.status_manager.gps_service_state.ServiceStateHandle;  
6 -import org.springframework.beans.factory.annotation.Autowired;  
7 -import org.springframework.boot.CommandLineRunner;  
8 -import org.springframework.stereotype.Component;  
9 -  
10 -import java.util.concurrent.TimeUnit;  
11 -  
12 -/**  
13 - * GPS 状态管理  
14 - * Created by panzhao on 2017/7/13.  
15 - */  
16 -@Component  
17 -public class GpsStatusManager implements CommandLineRunner {  
18 -  
19 - @Autowired  
20 - StatusCheckThread checkThread;  
21 -  
22 - @Autowired  
23 - LineStateHandle lineStateHandle;  
24 -  
25 - @Autowired  
26 - ServiceStateHandle serviceStateHandle;  
27 -  
28 - /**  
29 - * 切换线路  
30 - * @param nbbm  
31 - * @param lineCode  
32 - * @param sender  
33 - */  
34 - public void changeLine(String nbbm, String lineCode, String sender){  
35 - lineStateHandle.changeLine(nbbm, lineCode, sender);  
36 - }  
37 -  
38 - /**  
39 - * 切换营运状态  
40 - * @param nbbm  
41 - * @param state 0 营运, 1:非营运  
42 - * @param sender  
43 - */  
44 - public void changeServiceState(String nbbm, String upDown,int state, String sender){  
45 - changeServiceState(nbbm, Integer.parseInt(upDown), state, sender);  
46 - }  
47 -  
48 - /**  
49 - * 切换营运状态  
50 - * @param nbbm  
51 - * @param state 0 营运, 1:非营运  
52 - * @param sender  
53 - */  
54 - public void changeServiceState(String nbbm, int upDown,int state, String sender){  
55 - serviceStateHandle.changeState(nbbm, upDown, state, sender);  
56 - }  
57 -  
58 - @Override  
59 - public void run(String... strings) throws Exception {  
60 - Application.mainServices.scheduleWithFixedDelay(checkThread, 120, 120, TimeUnit.SECONDS);  
61 - }  
62 -  
63 - @Component  
64 - public static class StatusCheckThread extends Thread{  
65 -  
66 - @Autowired  
67 - LineStateHandle lineStateHandle;  
68 -  
69 - @Autowired  
70 - ServiceStateHandle serviceStateHandle;  
71 -  
72 - @Override  
73 - public void run() {  
74 - /** 检查线路切换结果 */  
75 - lineStateHandle.checkResultAll();  
76 - /** 检查营运状态切换结果 */  
77 - serviceStateHandle.checkResultAll();  
78 - }  
79 - }  
80 -} 1 +package com.bsth.data.gpsdata_v2.status_manager;
  2 +
  3 +import com.bsth.Application;
  4 +import com.bsth.data.gpsdata_v2.status_manager.gps_line_state.LineStateHandle;
  5 +import com.bsth.data.gpsdata_v2.status_manager.gps_service_state.ServiceStateHandle;
  6 +import com.bsth.entity.realcontrol.ScheduleRealInfo;
  7 +import org.springframework.beans.factory.annotation.Autowired;
  8 +import org.springframework.boot.CommandLineRunner;
  9 +import org.springframework.stereotype.Component;
  10 +
  11 +import java.util.concurrent.TimeUnit;
  12 +
  13 +/**
  14 + * GPS 状态管理
  15 + * Created by panzhao on 2017/7/13.
  16 + */
  17 +@Component
  18 +public class GpsStatusManager implements CommandLineRunner {
  19 +
  20 + @Autowired
  21 + StatusCheckThread checkThread;
  22 +
  23 + @Autowired
  24 + LineStateHandle lineStateHandle;
  25 +
  26 + @Autowired
  27 + ServiceStateHandle serviceStateHandle;
  28 +
  29 + /**
  30 + * 切换线路
  31 + * @param nbbm
  32 + * @param lineCode
  33 + * @param sender
  34 + */
  35 + public void changeLine(String nbbm, String lineCode, String sender){
  36 + lineStateHandle.changeLine(nbbm, lineCode, sender);
  37 + }
  38 +
  39 + public void changeLine(String nbbm, ScheduleRealInfo sch, String sender){
  40 + lineStateHandle.changeLine(nbbm, sch, sender);
  41 + }
  42 +
  43 + /**
  44 + * 切换营运状态
  45 + * @param nbbm
  46 + * @param state 0 营运, 1:非营运
  47 + * @param sender
  48 + */
  49 + public void changeServiceState(String nbbm, String upDown,int state, String sender){
  50 + changeServiceState(nbbm, Integer.parseInt(upDown), state, sender);
  51 + }
  52 +
  53 + /**
  54 + * 切换营运状态
  55 + * @param nbbm
  56 + * @param state 0 营运, 1:非营运
  57 + * @param sender
  58 + */
  59 + public void changeServiceState(String nbbm, int upDown,int state, String sender){
  60 + serviceStateHandle.changeState(nbbm, upDown, state, sender);
  61 + }
  62 +
  63 + @Override
  64 + public void run(String... strings) throws Exception {
  65 + Application.mainServices.scheduleWithFixedDelay(checkThread, 120, 120, TimeUnit.SECONDS);
  66 + }
  67 +
  68 + @Component
  69 + public static class StatusCheckThread extends Thread{
  70 +
  71 + @Autowired
  72 + LineStateHandle lineStateHandle;
  73 +
  74 + @Autowired
  75 + ServiceStateHandle serviceStateHandle;
  76 +
  77 + @Override
  78 + public void run() {
  79 + /** 检查线路切换结果 */
  80 + lineStateHandle.checkResultAll();
  81 + /** 检查营运状态切换结果 */
  82 + serviceStateHandle.checkResultAll();
  83 + }
  84 + }
  85 +}
src/main/java/com/bsth/data/gpsdata_v2/status_manager/gps_line_state/ChangeBean.java
1 -package com.bsth.data.gpsdata_v2.status_manager.gps_line_state;  
2 -  
3 -/**  
4 - * Created by panzhao on 2017/7/13.  
5 - */  
6 -public class ChangeBean {  
7 -  
8 - /**  
9 - * 车辆自编号  
10 - */  
11 - private String nbbm;  
12 -  
13 - /**  
14 - * 要切换到的线路  
15 - */  
16 - private String lineCode;  
17 -  
18 - /**  
19 - * 指令发送次数  
20 - */  
21 - private int sendCount;  
22 -  
23 - /**  
24 - * 上次指令时间  
25 - */  
26 - private long st;  
27 -  
28 - /**发送人 */  
29 - private String sender;  
30 -  
31 - public static ChangeBean getInstance(String nbbm, String lineCode, String sender){  
32 - ChangeBean cb = new ChangeBean();  
33 - cb.setNbbm(nbbm);  
34 - cb.setLineCode(lineCode);  
35 - cb.setSendCount(0);  
36 - cb.setSender(sender);  
37 - return cb;  
38 - }  
39 -  
40 - public void countPlus(){  
41 - sendCount ++;  
42 - }  
43 -  
44 - public String getLineCode() {  
45 - return lineCode;  
46 - }  
47 -  
48 - public void setLineCode(String lineCode) {  
49 - this.lineCode = lineCode;  
50 - }  
51 -  
52 - public int getSendCount() {  
53 - return sendCount;  
54 - }  
55 -  
56 - public void setSendCount(int sendCount) {  
57 - this.sendCount = sendCount;  
58 - }  
59 -  
60 - public long getSt() {  
61 - return st;  
62 - }  
63 -  
64 - public void setSt(long st) {  
65 - this.st = st;  
66 - }  
67 -  
68 - public String getSender() {  
69 - return sender;  
70 - }  
71 -  
72 - public void setSender(String sender) {  
73 - this.sender = sender;  
74 - }  
75 -  
76 - public String getNbbm() {  
77 - return nbbm;  
78 - }  
79 -  
80 - public void setNbbm(String nbbm) {  
81 - this.nbbm = nbbm;  
82 - }  
83 -} 1 +package com.bsth.data.gpsdata_v2.status_manager.gps_line_state;
  2 +
  3 +import com.bsth.entity.realcontrol.ScheduleRealInfo;
  4 +
  5 +/**
  6 + * Created by panzhao on 2017/7/13.
  7 + */
  8 +public class ChangeBean {
  9 +
  10 + /**
  11 + * 车辆自编号
  12 + */
  13 + private String nbbm;
  14 +
  15 + /**
  16 + * 要切换到的线路
  17 + */
  18 + private String lineCode;
  19 +
  20 + /**
  21 + * 班次
  22 + */
  23 + private ScheduleRealInfo sch;
  24 +
  25 + /**
  26 + * 指令发送次数
  27 + */
  28 + private int sendCount;
  29 +
  30 + /**
  31 + * 上次指令时间
  32 + */
  33 + private long st;
  34 +
  35 + /**发送人 */
  36 + private String sender;
  37 +
  38 + public static ChangeBean getInstance(String nbbm, String lineCode, String sender){
  39 + ChangeBean cb = new ChangeBean();
  40 + cb.setNbbm(nbbm);
  41 + cb.setLineCode(lineCode);
  42 + cb.setSendCount(0);
  43 + cb.setSender(sender);
  44 + return cb;
  45 + }
  46 +
  47 + public void countPlus(){
  48 + sendCount ++;
  49 + }
  50 +
  51 + public String getLineCode() {
  52 + return lineCode;
  53 + }
  54 +
  55 + public void setLineCode(String lineCode) {
  56 + this.lineCode = lineCode;
  57 + }
  58 +
  59 + public ScheduleRealInfo getSch() {
  60 + return sch;
  61 + }
  62 +
  63 + public void setSch(ScheduleRealInfo sch) {
  64 + this.sch = sch;
  65 + }
  66 +
  67 + public int getSendCount() {
  68 + return sendCount;
  69 + }
  70 +
  71 + public void setSendCount(int sendCount) {
  72 + this.sendCount = sendCount;
  73 + }
  74 +
  75 + public long getSt() {
  76 + return st;
  77 + }
  78 +
  79 + public void setSt(long st) {
  80 + this.st = st;
  81 + }
  82 +
  83 + public String getSender() {
  84 + return sender;
  85 + }
  86 +
  87 + public void setSender(String sender) {
  88 + this.sender = sender;
  89 + }
  90 +
  91 + public String getNbbm() {
  92 + return nbbm;
  93 + }
  94 +
  95 + public void setNbbm(String nbbm) {
  96 + this.nbbm = nbbm;
  97 + }
  98 +}
src/main/java/com/bsth/data/gpsdata_v2/status_manager/gps_line_state/LineStateHandle.java
1 -package com.bsth.data.gpsdata_v2.status_manager.gps_line_state;  
2 -  
3 -import com.bsth.data.gpsdata_v2.GpsRealData;  
4 -import com.bsth.data.gpsdata_v2.entity.GpsEntity;  
5 -import com.bsth.data.msg_queue.DirectivePushQueue;  
6 -import com.bsth.service.directive.DirectiveService;  
7 -import org.slf4j.Logger;  
8 -import org.slf4j.LoggerFactory;  
9 -import org.springframework.beans.factory.annotation.Autowired;  
10 -import org.springframework.stereotype.Component;  
11 -  
12 -import java.util.Collection;  
13 -import java.util.concurrent.ConcurrentHashMap;  
14 -  
15 -/**  
16 - * 设备线路状态处理  
17 - * Created by panzhao on 2017/7/13.  
18 - */  
19 -@Component  
20 -public class LineStateHandle {  
21 -  
22 - private static ConcurrentHashMap<String, ChangeBean> map;  
23 -  
24 - @Autowired  
25 - DirectiveService directiveService;  
26 - @Autowired  
27 - GpsRealData gpsRealData;  
28 -  
29 - Logger logger = LoggerFactory.getLogger(this.getClass());  
30 -  
31 - /** 重发次数 */  
32 - private final static int MAX_SEND_COUNT=3;  
33 - /** 重发间隔 */  
34 - private final static int SEND_SPACE=1000 * 60 * 6;  
35 - /** 最大有效时间 */  
36 - private final static int MAX_AVAIL_TIME=1000 * 60 * 60 * 2;  
37 -  
38 - static{  
39 - map = new ConcurrentHashMap();  
40 - }  
41 -  
42 - public void changeLine(String nbbm, String lineCode, String sender){  
43 - ChangeBean cb = map.get(nbbm);  
44 - if(cb != null && cb.getLineCode().equals(lineCode)){  
45 - return;  
46 - }  
47 -  
48 - cb = ChangeBean.getInstance(nbbm, lineCode, sender);  
49 - map.put(nbbm, cb);  
50 -  
51 - changeLine(cb);  
52 - }  
53 -  
54 - private void changeLine(ChangeBean cb){  
55 - cb.setSt(System.currentTimeMillis());  
56 - cb.countPlus();  
57 - DirectivePushQueue.put64(cb.getNbbm(), cb.getLineCode(), cb.getSender());  
58 - }  
59 -  
60 -  
61 - public void checkResultAll(){  
62 - Collection<ChangeBean> cbs = map.values();  
63 - for(ChangeBean cb : cbs){  
64 - checkResult(cb);  
65 - }  
66 - }  
67 -  
68 - private void checkResult(ChangeBean cb){  
69 - try{  
70 - GpsEntity gps = gpsRealData.getByNbbm(cb.getNbbm());  
71 - if(gps == null)  
72 - return;  
73 -  
74 - if(cb.getLineCode().equals(gps.getLineId())){  
75 - map.remove(cb.getNbbm());  
76 - logger.info("线路切换成功," + cb.getNbbm() + "、" + cb.getLineCode());  
77 - }  
78 - else{  
79 - reSend(cb);  
80 - }  
81 - }catch (Exception e){  
82 - logger.error("", e);  
83 - }  
84 - }  
85 -  
86 - private void reSend(ChangeBean cb){  
87 - if(cb.getSendCount() >= MAX_SEND_COUNT){  
88 - map.remove(cb.getNbbm());  
89 - logger.info("超过重发次数," + cb.getNbbm() + "、" + cb.getLineCode());  
90 - return;  
91 - }  
92 -  
93 - long diff = System.currentTimeMillis() - cb.getSt();  
94 - if(diff >= MAX_AVAIL_TIME){  
95 - map.remove(cb.getNbbm());  
96 - logger.info("超过有效时间," + cb.getNbbm() + "、" + cb.getLineCode() + "、" + cb.getSt());  
97 - return;  
98 - }  
99 -  
100 - if(diff >= SEND_SPACE){  
101 - cb.setSender("补发@系统");  
102 - changeLine(cb);  
103 - logger.info("重发线路切换指令," + cb.getNbbm() + "、" + cb.getLineCode());  
104 - return;  
105 - }  
106 - }  
107 -} 1 +package com.bsth.data.gpsdata_v2.status_manager.gps_line_state;
  2 +
  3 +import com.bsth.data.gpsdata_v2.GpsRealData;
  4 +import com.bsth.data.gpsdata_v2.entity.GpsEntity;
  5 +import com.bsth.data.msg_queue.DirectivePushQueue;
  6 +import com.bsth.entity.realcontrol.ScheduleRealInfo;
  7 +import com.bsth.service.directive.DirectiveService;
  8 +import org.slf4j.Logger;
  9 +import org.slf4j.LoggerFactory;
  10 +import org.springframework.beans.factory.annotation.Autowired;
  11 +import org.springframework.stereotype.Component;
  12 +import org.springframework.util.StringUtils;
  13 +
  14 +import java.util.Collection;
  15 +import java.util.concurrent.ConcurrentHashMap;
  16 +
  17 +/**
  18 + * 设备线路状态处理
  19 + * Created by panzhao on 2017/7/13.
  20 + */
  21 +@Component
  22 +public class LineStateHandle {
  23 +
  24 + private static ConcurrentHashMap<String, ChangeBean> map;
  25 +
  26 + @Autowired
  27 + DirectiveService directiveService;
  28 + @Autowired
  29 + GpsRealData gpsRealData;
  30 +
  31 + Logger logger = LoggerFactory.getLogger(this.getClass());
  32 +
  33 + /** 重发次数 */
  34 + private final static int MAX_SEND_COUNT=3;
  35 + /** 重发间隔 */
  36 + private final static int SEND_SPACE=1000 * 60 * 3;
  37 + /** 最大有效时间 */
  38 + private final static int MAX_AVAIL_TIME=1000 * 60 * 60 * 2;
  39 +
  40 + static{
  41 + map = new ConcurrentHashMap();
  42 + }
  43 +
  44 + public void changeLine(String nbbm, String lineCode, String sender){
  45 + ChangeBean cb = map.get(nbbm);
  46 + if(cb != null && cb.getLineCode().equals(lineCode)){
  47 + return;
  48 + }
  49 +
  50 + cb = ChangeBean.getInstance(nbbm, lineCode, sender);
  51 + map.put(nbbm, cb);
  52 +
  53 + changeLine(cb);
  54 + }
  55 +
  56 + public void changeLine(String nbbm, ScheduleRealInfo sch, String sender){
  57 + ChangeBean cb = map.get(nbbm);
  58 + if(cb != null && cb.getLineCode().equals(sch.getXlBm())){
  59 + return;
  60 + }
  61 +
  62 + cb = ChangeBean.getInstance(nbbm, sch.getXlBm(), sender);
  63 + cb.setSch(sch);
  64 + map.put(nbbm, cb);
  65 +
  66 + changeLine(cb);
  67 + }
  68 +
  69 + private void changeLine(ChangeBean cb){
  70 + cb.setSt(System.currentTimeMillis());
  71 + cb.countPlus();
  72 + DirectivePushQueue.put64(cb.getNbbm(), cb.getLineCode(), cb.getSch(), cb.getSender());
  73 + }
  74 +
  75 +
  76 + public void checkResultAll(){
  77 + Collection<ChangeBean> cbs = map.values();
  78 + for(ChangeBean cb : cbs){
  79 + checkResult(cb);
  80 + }
  81 + }
  82 +
  83 + private void checkResult(ChangeBean cb){
  84 + try{
  85 + GpsEntity gps = gpsRealData.getByNbbm(cb.getNbbm());
  86 + if(gps == null)
  87 + return;
  88 +
  89 + if(cb.getLineCode().equals(gps.getLineId())){
  90 + map.remove(cb.getNbbm());
  91 + logger.info("线路切换成功," + cb.getNbbm() + "、" + cb.getLineCode());
  92 + }
  93 + else{
  94 + reSend(cb);
  95 + }
  96 + }catch (Exception e){
  97 + logger.error("", e);
  98 + }
  99 + }
  100 +
  101 + private void reSend(ChangeBean cb){
  102 + if(cb.getSendCount() >= MAX_SEND_COUNT){
  103 + map.remove(cb.getNbbm());
  104 + logger.info("超过重发次数," + cb.getNbbm() + "、" + cb.getLineCode());
  105 + return;
  106 + }
  107 +
  108 + long diff = System.currentTimeMillis() - cb.getSt();
  109 + if(diff >= MAX_AVAIL_TIME){
  110 + map.remove(cb.getNbbm());
  111 + logger.info("超过有效时间," + cb.getNbbm() + "、" + cb.getLineCode() + "、" + cb.getSt());
  112 + return;
  113 + }
  114 +
  115 + if(diff >= SEND_SPACE){
  116 + cb.setSender("补发@系统");
  117 + changeLine(cb);
  118 + logger.info("重发线路切换指令," + cb.getNbbm() + "、" + cb.getLineCode());
  119 + return;
  120 + }
  121 + }
  122 +}
src/main/java/com/bsth/data/msg_queue/DirectivePushQueue.java
1 -package com.bsth.data.msg_queue;  
2 -  
3 -import com.bsth.data.schedule.DayOfSchedule;  
4 -import com.bsth.entity.realcontrol.ScheduleRealInfo;  
5 -import com.bsth.service.directive.DirectiveService;  
6 -import org.slf4j.Logger;  
7 -import org.slf4j.LoggerFactory;  
8 -import org.springframework.beans.BeansException;  
9 -import org.springframework.context.ApplicationContext;  
10 -import org.springframework.context.ApplicationContextAware;  
11 -import org.springframework.stereotype.Component;  
12 -  
13 -import java.util.concurrent.ConcurrentHashMap;  
14 -import java.util.concurrent.ConcurrentLinkedQueue;  
15 -import java.util.concurrent.ConcurrentMap;  
16 -  
17 -/**  
18 - * 到网关的指令推送队列 (系统发送的队列, 用户手动发送的不走这里)  
19 - * Created by panzhao on 2017/5/11.  
20 - */  
21 -@Component  
22 -public class DirectivePushQueue implements ApplicationContextAware {  
23 -  
24 - static ConcurrentLinkedQueue<QueueData_Directive> linkedList;  
25 - static DataPushThread thread;  
26 - static DirectiveService directiveService;  
27 - static long threadT;  
28 -  
29 - /**  
30 - * 下发运营指令6003的最小间隔时间  
31 - */  
32 - static final int MIN_SEND6003_SPACE = 1000 * 30;  
33 -  
34 - /**  
35 - * 车辆 ——> 上次下发6003的时间  
36 - */  
37 - static ConcurrentMap<String, Long> lastSend60TimeMap;  
38 -  
39 - static {  
40 - linkedList = new ConcurrentLinkedQueue<>();  
41 - lastSend60TimeMap = new ConcurrentHashMap<>();  
42 - }  
43 -  
44 - public static void put6002(ScheduleRealInfo sch, int finish, String sender, String txtPrefix){  
45 - if(null == sch)  
46 - return;  
47 - QueueData_Directive qd6002 = new QueueData_Directive();  
48 - qd6002.setSch(sch);  
49 - qd6002.setFinish(finish);  
50 - qd6002.setSender(sender);  
51 - qd6002.setCode("60_02");  
52 - qd6002.setTxtPrefix(txtPrefix);  
53 -  
54 - linkedList.add(qd6002);  
55 - lastSend60TimeMap.put(sch.getClZbh(), System.currentTimeMillis());  
56 - }  
57 - //单独出厂请求设计  
58 - public static void put60_002(ScheduleRealInfo sch, int finish, String sender, String txtPrefix){  
59 - if(null == sch)  
60 - return;  
61 - QueueData_Directive qd6002 = new QueueData_Directive();  
62 - qd6002.setSch(sch);  
63 - qd6002.setFinish(finish);  
64 - qd6002.setSender(sender);  
65 - qd6002.setCode("60_002");  
66 - qd6002.setTxtPrefix(txtPrefix);  
67 -  
68 - linkedList.add(qd6002);  
69 - lastSend60TimeMap.put(sch.getClZbh(), System.currentTimeMillis());  
70 - }  
71 -  
72 -  
73 -  
74 -  
75 - public static void put6003(String nbbm, int state, int upDown, String sender){  
76 - long t = System.currentTimeMillis();  
77 - if(lastSend60TimeMap.containsKey(nbbm)  
78 - && t - lastSend60TimeMap.get(nbbm) < MIN_SEND6003_SPACE)  
79 - return; //最短下发间隔  
80 -  
81 - QueueData_Directive qd6003 = new QueueData_Directive();  
82 - qd6003.setNbbm(nbbm);  
83 - qd6003.setState(state);  
84 - qd6003.setUpDown(upDown);  
85 - qd6003.setSender(sender);  
86 - qd6003.setCode("60_03");  
87 -  
88 - linkedList.add(qd6003);  
89 - lastSend60TimeMap.put(nbbm, t);  
90 - }  
91 -  
92 - public static void put6003(ScheduleRealInfo sch, String sender){  
93 - if(null == sch)  
94 - return;  
95 - int state = 0;//营运状态  
96 - if(DayOfSchedule.emptyService(sch))  
97 - state = 1;  
98 -  
99 - put6003(sch.getClZbh(), state, Integer.parseInt(sch.getXlDir()), sender);  
100 - }  
101 -  
102 - public static void put64(String nbbm, String lineCode, String sender){  
103 - QueueData_Directive qd64 = new QueueData_Directive();  
104 - qd64.setNbbm(nbbm);  
105 - qd64.setLineCode(lineCode);  
106 - qd64.setSender(sender);  
107 -  
108 - qd64.setCode("64");  
109 -  
110 - linkedList.add(qd64);  
111 - }  
112 -  
113 - public static void start(){  
114 - if(thread != null){  
115 - thread.interrupt();  
116 - }  
117 - linkedList.clear();  
118 - thread = new DataPushThread();  
119 - thread.start();  
120 - }  
121 -  
122 - public static int size(){  
123 - return linkedList.size();  
124 - }  
125 -  
126 - @Override  
127 - public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {  
128 - directiveService = applicationContext.getBean(DirectiveService.class);  
129 - }  
130 -  
131 - public static class DataPushThread extends Thread {  
132 -  
133 - Logger log = LoggerFactory.getLogger(this.getClass());  
134 -  
135 - @Override  
136 - public void run() {  
137 - boolean sleepFlag = false;  
138 - QueueData_Directive qd;  
139 - String code;  
140 - while (true) {  
141 - try {  
142 - qd = linkedList.poll();  
143 - if (qd != null) {  
144 - sleepFlag = false;  
145 - code = qd.getCode();  
146 -  
147 - if(code.equals("60_02")){  
148 - directiveService.send60Dispatch(qd.getSch(), qd.getFinish(), qd.getSender(), qd.getTxtPrefix());  
149 - log.info("directive 60_02 sch id: " + qd.getSch().getId());  
150 - }  
151 - else if(code.equals("60_002")){ //出场请求只写出场  
152 - directiveService.send60Dispatchcc(qd.getSch(), qd.getFinish(), qd.getSender(), qd.getTxtPrefix());  
153 - log.info("directive出场 60_002 nbbm: " + qd.getNbbm() + " lineCode: " + qd.getLineCode());  
154 - }  
155 - else if(code.equals("60_03")){  
156 - directiveService.send60Operation(qd.getNbbm(), qd.getState(), qd.getUpDown(), qd.getSender());  
157 - log.info("directive 60_03 nbbm: " + qd.getNbbm());  
158 - }  
159 - else if(code.equals("64")){  
160 - directiveService.lineChange(qd.getNbbm(), qd.getLineCode(), qd.getSender());  
161 - log.info("directive 64 nbbm: " + qd.getNbbm() + " lineCode: " + qd.getLineCode());  
162 - }  
163 -  
164 -  
165 - } else{  
166 - Thread.sleep(500);  
167 - if(!sleepFlag){  
168 - log.info("sleep...");  
169 - sleepFlag = true;  
170 - }  
171 - }  
172 - threadT = System.currentTimeMillis();  
173 - }  
174 - catch(InterruptedException e){  
175 - log.error("", e);  
176 - break;  
177 - }  
178 - catch (Exception e) {  
179 - log.error("", e);  
180 - }  
181 - }  
182 -  
183 - log.warn("DirectivePushQueue is break...");  
184 - }  
185 - }  
186 -} 1 +package com.bsth.data.msg_queue;
  2 +
  3 +import com.bsth.data.schedule.DayOfSchedule;
  4 +import com.bsth.entity.realcontrol.ScheduleRealInfo;
  5 +import com.bsth.service.directive.DirectiveService;
  6 +import org.slf4j.Logger;
  7 +import org.slf4j.LoggerFactory;
  8 +import org.springframework.beans.BeansException;
  9 +import org.springframework.context.ApplicationContext;
  10 +import org.springframework.context.ApplicationContextAware;
  11 +import org.springframework.stereotype.Component;
  12 +import org.springframework.util.StringUtils;
  13 +
  14 +import java.util.concurrent.ConcurrentHashMap;
  15 +import java.util.concurrent.ConcurrentLinkedQueue;
  16 +import java.util.concurrent.ConcurrentMap;
  17 +
  18 +/**
  19 + * 到网关的指令推送队列 (系统发送的队列, 用户手动发送的不走这里)
  20 + * Created by panzhao on 2017/5/11.
  21 + */
  22 +@Component
  23 +public class DirectivePushQueue implements ApplicationContextAware {
  24 +
  25 + static ConcurrentLinkedQueue<QueueData_Directive> linkedList;
  26 + static DataPushThread thread;
  27 + static DirectiveService directiveService;
  28 + static long threadT;
  29 +
  30 + /**
  31 + * 下发运营指令6003的最小间隔时间
  32 + */
  33 + static final int MIN_SEND6003_SPACE = 1000 * 30;
  34 +
  35 + /**
  36 + * 车辆 ——> 上次下发6003的时间
  37 + */
  38 + static ConcurrentMap<String, Long> lastSend60TimeMap;
  39 +
  40 + static {
  41 + linkedList = new ConcurrentLinkedQueue<>();
  42 + lastSend60TimeMap = new ConcurrentHashMap<>();
  43 + }
  44 +
  45 + public static void put6002(ScheduleRealInfo sch, int finish, String sender, String txtPrefix){
  46 + if(null == sch)
  47 + return;
  48 + QueueData_Directive qd6002 = new QueueData_Directive();
  49 + qd6002.setSch(sch);
  50 + qd6002.setFinish(finish);
  51 + qd6002.setSender(sender);
  52 + qd6002.setCode("60_02");
  53 + qd6002.setTxtPrefix(txtPrefix);
  54 +
  55 + linkedList.add(qd6002);
  56 + lastSend60TimeMap.put(sch.getClZbh(), System.currentTimeMillis());
  57 + }
  58 + //单独出厂请求设计
  59 + public static void put60_002(ScheduleRealInfo sch, int finish, String sender, String txtPrefix){
  60 + if(null == sch)
  61 + return;
  62 + QueueData_Directive qd6002 = new QueueData_Directive();
  63 + qd6002.setSch(sch);
  64 + qd6002.setFinish(finish);
  65 + qd6002.setSender(sender);
  66 + qd6002.setCode("60_002");
  67 + qd6002.setTxtPrefix(txtPrefix);
  68 +
  69 + linkedList.add(qd6002);
  70 + lastSend60TimeMap.put(sch.getClZbh(), System.currentTimeMillis());
  71 + }
  72 +
  73 +
  74 +
  75 +
  76 + public static void put6003(String nbbm, int state, int upDown, String sender){
  77 + long t = System.currentTimeMillis();
  78 + if(lastSend60TimeMap.containsKey(nbbm)
  79 + && t - lastSend60TimeMap.get(nbbm) < MIN_SEND6003_SPACE)
  80 + return; //最短下发间隔
  81 +
  82 + QueueData_Directive qd6003 = new QueueData_Directive();
  83 + qd6003.setNbbm(nbbm);
  84 + qd6003.setState(state);
  85 + qd6003.setUpDown(upDown);
  86 + qd6003.setSender(sender);
  87 + qd6003.setCode("60_03");
  88 +
  89 + linkedList.add(qd6003);
  90 + lastSend60TimeMap.put(nbbm, t);
  91 + }
  92 +
  93 + public static void put6003(ScheduleRealInfo sch, String sender){
  94 + if(null == sch)
  95 + return;
  96 + int state = 0;//营运状态
  97 + if(DayOfSchedule.emptyService(sch))
  98 + state = 1;
  99 +
  100 + put6003(sch.getClZbh(), state, Integer.parseInt(sch.getXlDir()), sender);
  101 + }
  102 +
  103 + public static void put64(String nbbm, String lineCode, ScheduleRealInfo sch, String sender){
  104 + QueueData_Directive qd64 = new QueueData_Directive();
  105 + qd64.setNbbm(nbbm);
  106 + qd64.setLineCode(lineCode);
  107 + qd64.setSch(sch);
  108 + qd64.setSender(sender);
  109 +
  110 + qd64.setCode("64");
  111 +
  112 + linkedList.add(qd64);
  113 + }
  114 +
  115 + public static void start(){
  116 + if(thread != null){
  117 + thread.interrupt();
  118 + }
  119 + linkedList.clear();
  120 + thread = new DataPushThread();
  121 + thread.start();
  122 + }
  123 +
  124 + public static int size(){
  125 + return linkedList.size();
  126 + }
  127 +
  128 + @Override
  129 + public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
  130 + directiveService = applicationContext.getBean(DirectiveService.class);
  131 + }
  132 +
  133 + public static class DataPushThread extends Thread {
  134 +
  135 + Logger log = LoggerFactory.getLogger(this.getClass());
  136 +
  137 + @Override
  138 + public void run() {
  139 + boolean sleepFlag = false;
  140 + QueueData_Directive qd;
  141 + String code;
  142 + while (true) {
  143 + try {
  144 + qd = linkedList.poll();
  145 + if (qd != null) {
  146 + sleepFlag = false;
  147 + code = qd.getCode();
  148 +
  149 + if(code.equals("60_02")){
  150 + directiveService.send60Dispatch(qd.getSch(), qd.getFinish(), qd.getSender(), qd.getTxtPrefix());
  151 + log.info("directive 60_02 sch id: " + qd.getSch().getId());
  152 + }
  153 + else if(code.equals("60_002")){ //出场请求只写出场
  154 + directiveService.send60Dispatchcc(qd.getSch(), qd.getFinish(), qd.getSender(), qd.getTxtPrefix());
  155 + log.info("directive出场 60_002 nbbm: " + qd.getNbbm() + " lineCode: " + qd.getLineCode());
  156 + }
  157 + else if(code.equals("60_03")){
  158 + directiveService.send60Operation(qd.getNbbm(), qd.getState(), qd.getUpDown(), qd.getSender());
  159 + log.info("directive 60_03 nbbm: " + qd.getNbbm());
  160 + }
  161 + else if(code.equals("64")){
  162 + directiveService.lineChange(qd.getNbbm(), qd.getLineCode(), qd.getSch(), qd.getSender());
  163 + log.info("directive 64 nbbm: " + qd.getNbbm() + " lineCode: " + qd.getLineCode());
  164 + }
  165 +
  166 +
  167 + } else{
  168 + Thread.sleep(500);
  169 + if(!sleepFlag){
  170 + log.info("sleep...");
  171 + sleepFlag = true;
  172 + }
  173 + }
  174 + threadT = System.currentTimeMillis();
  175 + }
  176 + catch(InterruptedException e){
  177 + log.error("", e);
  178 + break;
  179 + }
  180 + catch (Exception e) {
  181 + log.error("", e);
  182 + }
  183 + }
  184 +
  185 + log.warn("DirectivePushQueue is break...");
  186 + }
  187 + }
  188 +}
src/main/java/com/bsth/data/schedule/auto_exec/RealScheduleAutoExecHandler.java
1 -package com.bsth.data.schedule.auto_exec;  
2 -  
3 -import com.bsth.data.gpsdata_v2.status_manager.GpsStatusManager;  
4 -import com.bsth.data.schedule.DayOfSchedule;  
5 -import com.bsth.entity.realcontrol.ScheduleRealInfo;  
6 -import com.bsth.websocket.handler.SendUtils;  
7 -import org.apache.commons.lang3.StringUtils;  
8 -import org.springframework.beans.factory.annotation.Autowired;  
9 -import org.springframework.stereotype.Component;  
10 -  
11 -import java.util.ArrayList;  
12 -import java.util.List;  
13 -  
14 -/**  
15 - * 实际班次自动执行  
16 - * Created by panzhao on 2017/10/31.  
17 - */  
18 -@Component  
19 -public class RealScheduleAutoExecHandler {  
20 -  
21 - @Autowired  
22 - SendUtils sendUtils;  
23 - @Autowired  
24 - DayOfSchedule dayOfSchedule;  
25 -  
26 - @Autowired  
27 - GpsStatusManager gpsStatusManager;  
28 -  
29 - public void exec(ScheduleRealInfo sch) {  
30 - boolean flag = false;  
31 - long t = System.currentTimeMillis();  
32 -  
33 - if (StringUtils.isEmpty(sch.getFcsjActual()) && sch.getDfsjT() < t) {  
34 - sch.setFcsjActualAll(sch.getDfsjT());  
35 - flag = true;  
36 - }  
37 -  
38 - if (StringUtils.isEmpty(sch.getZdsjActual()) && sch.getZdsjT() < t) {  
39 - sch.setZdsjActualAll(sch.getZdsjT());  
40 - flag = true;  
41 -  
42 - //准备执行下一个班次  
43 - ScheduleRealInfo next = dayOfSchedule.next(sch);  
44 - if (next != null) {  
45 - dayOfSchedule.addExecPlan(next);  
46 - //套跑 -下发线路切换指令  
47 - if(!next.getXlBm().equals(sch.getXlBm())){  
48 - gpsStatusManager.changeLine(next.getClZbh(), next.getXlBm(), "auto@系统");  
49 - }  
50 - }  
51 -  
52 - //路牌有下一个班次,线调页面显示  
53 - ScheduleRealInfo nextLp = dayOfSchedule.nextByLp(sch);  
54 - if (null != nextLp) {  
55 - //入库  
56 - dayOfSchedule.save(sch);  
57 -  
58 - nextLp.setQdzArrDatesj(sch.getZdsjActual());  
59 - List<ScheduleRealInfo> refs = new ArrayList<>();  
60 - refs.add(sch);  
61 - refs.add(nextLp);  
62 - sendUtils.refreshSch(refs);  
63 - return;  
64 - }  
65 - }  
66 -  
67 - if (flag) {  
68 - dayOfSchedule.save(sch);  
69 - sendUtils.refreshSch(sch);  
70 - }  
71 - }  
72 -} 1 +package com.bsth.data.schedule.auto_exec;
  2 +
  3 +import com.bsth.data.gpsdata_v2.status_manager.GpsStatusManager;
  4 +import com.bsth.data.schedule.DayOfSchedule;
  5 +import com.bsth.entity.realcontrol.ScheduleRealInfo;
  6 +import com.bsth.websocket.handler.SendUtils;
  7 +import org.apache.commons.lang3.StringUtils;
  8 +import org.springframework.beans.factory.annotation.Autowired;
  9 +import org.springframework.stereotype.Component;
  10 +
  11 +import java.util.ArrayList;
  12 +import java.util.List;
  13 +
  14 +/**
  15 + * 实际班次自动执行
  16 + * Created by panzhao on 2017/10/31.
  17 + */
  18 +@Component
  19 +public class RealScheduleAutoExecHandler {
  20 +
  21 + @Autowired
  22 + SendUtils sendUtils;
  23 + @Autowired
  24 + DayOfSchedule dayOfSchedule;
  25 +
  26 + @Autowired
  27 + GpsStatusManager gpsStatusManager;
  28 +
  29 + public void exec(ScheduleRealInfo sch) {
  30 + boolean flag = false;
  31 + long t = System.currentTimeMillis();
  32 +
  33 + if (StringUtils.isEmpty(sch.getFcsjActual()) && sch.getDfsjT() < t) {
  34 + sch.setFcsjActualAll(sch.getDfsjT());
  35 + flag = true;
  36 + }
  37 +
  38 + if (StringUtils.isEmpty(sch.getZdsjActual()) && sch.getZdsjT() < t) {
  39 + sch.setZdsjActualAll(sch.getZdsjT());
  40 + flag = true;
  41 +
  42 + //准备执行下一个班次
  43 + ScheduleRealInfo next = dayOfSchedule.next(sch);
  44 + if (next != null) {
  45 + dayOfSchedule.addExecPlan(next);
  46 + //套跑 -下发线路切换指令
  47 + if(!next.getXlBm().equals(sch.getXlBm())){
  48 + gpsStatusManager.changeLine(next.getClZbh(), next, "auto@系统");
  49 + }
  50 + }
  51 +
  52 + //路牌有下一个班次,线调页面显示
  53 + ScheduleRealInfo nextLp = dayOfSchedule.nextByLp(sch);
  54 + if (null != nextLp) {
  55 + //入库
  56 + dayOfSchedule.save(sch);
  57 +
  58 + nextLp.setQdzArrDatesj(sch.getZdsjActual());
  59 + List<ScheduleRealInfo> refs = new ArrayList<>();
  60 + refs.add(sch);
  61 + refs.add(nextLp);
  62 + sendUtils.refreshSch(refs);
  63 + return;
  64 + }
  65 + }
  66 +
  67 + if (flag) {
  68 + dayOfSchedule.save(sch);
  69 + sendUtils.refreshSch(sch);
  70 + }
  71 + }
  72 +}
src/main/java/com/bsth/data/schedule/thread/SchedulePstThread.java
@@ -101,7 +101,7 @@ public class SchedulePstThread extends Thread { @@ -101,7 +101,7 @@ public class SchedulePstThread extends Thread {
101 ",qdz_name=?,real_exec_date=?,remarks=?,s_gh=?,s_name=?,schedule_date=?,schedule_date_str=?,sflj=?" + 101 ",qdz_name=?,real_exec_date=?,remarks=?,s_gh=?,s_name=?,schedule_date=?,schedule_date_str=?,sflj=?" +
102 ",sp_id=?,status=?,update_date=?,xl_bm=?,xl_dir=?,xl_name=?,zdsj=?,zdsj_actual=?,zdz_code=?,zdz_name=?" + 102 ",sp_id=?,status=?,update_date=?,xl_bm=?,xl_dir=?,xl_name=?,zdsj=?,zdsj_actual=?,zdz_code=?,zdz_name=?" +
103 ",ccno=?,df_auto=?,fgs_bm=?,fgs_name=?,gs_bm=?,gs_name=?,online=?,adjust_exps=?,reissue=?,jhlc_orig=?" + 103 ",ccno=?,df_auto=?,fgs_bm=?,fgs_name=?,gs_bm=?,gs_name=?,online=?,adjust_exps=?,reissue=?,jhlc_orig=?" +
104 - ",sigin_compate=?,drift_status=?,cc_service=?,major_station_name=?,rfid_state=?,first_rfid_state=? where id=?", new BatchPreparedStatementSetter() { 104 + ",sigin_compate=?,drift_status=?,cc_service=?,major_station_name=?,rfid_state=?,first_rfid_state=?,region_id=? where id=?", new BatchPreparedStatementSetter() {
105 @Override 105 @Override
106 public void setValues(PreparedStatement ps, int i) throws SQLException { 106 public void setValues(PreparedStatement ps, int i) throws SQLException {
107 ScheduleRealInfo sch = pstList.get(i); 107 ScheduleRealInfo sch = pstList.get(i);
@@ -154,7 +154,8 @@ public class SchedulePstThread extends Thread { @@ -154,7 +154,8 @@ public class SchedulePstThread extends Thread {
154 ps.setString(47, sch.getMajorStationName()); 154 ps.setString(47, sch.getMajorStationName());
155 ps.setInt(48, sch.getRfidState()); 155 ps.setInt(48, sch.getRfidState());
156 ps.setInt(49, sch.getFirstRfidState()); 156 ps.setInt(49, sch.getFirstRfidState());
157 - ps.setLong(50, sch.getId()); 157 + ps.setString(50, sch.getRegionId());
  158 + ps.setLong(51, sch.getId());
158 } 159 }
159 160
160 @Override 161 @Override
src/main/java/com/bsth/entity/directive/D64.java
1 package com.bsth.entity.directive; 1 package com.bsth.entity.directive;
2 2
  3 +import com.bsth.entity.realcontrol.ScheduleRealInfo;
  4 +import com.fasterxml.jackson.annotation.JsonIgnore;
  5 +
3 import javax.persistence.*; 6 import javax.persistence.*;
4 7
5 /** 8 /**
@@ -26,6 +29,10 @@ public class D64 extends Directive{ @@ -26,6 +29,10 @@ public class D64 extends Directive{
26 29
27 private D64Data data; 30 private D64Data data;
28 31
  32 + @Transient
  33 + @JsonIgnore
  34 + private ScheduleRealInfo sch;
  35 +
29 @Embeddable 36 @Embeddable
30 public static class D64Data { 37 public static class D64Data {
31 38
@@ -35,7 +42,12 @@ public class D64 extends Directive{ @@ -35,7 +42,12 @@ public class D64 extends Directive{
35 private String deviceId; 42 private String deviceId;
36 43
37 private String lineId; 44 private String lineId;
38 - 45 +
  46 + /**
  47 + * 预设区间seq(子线路)
  48 + */
  49 + private Integer seq;
  50 +
39 private String txtContent; 51 private String txtContent;
40 52
41 public Short getCityCode() { 53 public Short getCityCode() {
@@ -62,6 +74,14 @@ public class D64 extends Directive{ @@ -62,6 +74,14 @@ public class D64 extends Directive{
62 this.lineId = lineId; 74 this.lineId = lineId;
63 } 75 }
64 76
  77 + public Integer getSeq() {
  78 + return seq;
  79 + }
  80 +
  81 + public void setSeq(Integer seq) {
  82 + this.seq = seq;
  83 + }
  84 +
65 public String getTxtContent() { 85 public String getTxtContent() {
66 return txtContent; 86 return txtContent;
67 } 87 }
@@ -95,6 +115,14 @@ public class D64 extends Directive{ @@ -95,6 +115,14 @@ public class D64 extends Directive{
95 this.respAck = respAck; 115 this.respAck = respAck;
96 } 116 }
97 117
  118 + public ScheduleRealInfo getSch() {
  119 + return sch;
  120 + }
  121 +
  122 + public void setSch(ScheduleRealInfo sch) {
  123 + this.sch = sch;
  124 + }
  125 +
98 @Override 126 @Override
99 public void setDeviceId(String deviceId) { 127 public void setDeviceId(String deviceId) {
100 if(this.data != null) 128 if(this.data != null)
src/main/java/com/bsth/entity/realcontrol/ScheduleRealInfo.java
@@ -257,6 +257,22 @@ public class ScheduleRealInfo implements Cloneable{ @@ -257,6 +257,22 @@ public class ScheduleRealInfo implements Cloneable{
257 @Transient 257 @Transient
258 private String operationType; 258 private String operationType;
259 259
  260 + /**
  261 + * 区间ID+seq
  262 + */
  263 + private String regionId;
  264 +
  265 + /**
  266 + * 封锁站点(站点编号以','分割)
  267 + */
  268 + private String blockStations;
  269 +
  270 + /**
  271 + * 区间切换状态 0 未发或未成功 1 成功
  272 + */
  273 + @Transient
  274 + private int regionSwitchState;
  275 +
260 public Integer getLpChange() { 276 public Integer getLpChange() {
261 return lpChange; 277 return lpChange;
262 } 278 }
@@ -1055,6 +1071,30 @@ public class ScheduleRealInfo implements Cloneable{ @@ -1055,6 +1071,30 @@ public class ScheduleRealInfo implements Cloneable{
1055 this.operationType = operationType; 1071 this.operationType = operationType;
1056 } 1072 }
1057 1073
  1074 + public String getRegionId() {
  1075 + return regionId;
  1076 + }
  1077 +
  1078 + public void setRegionId(String regionId) {
  1079 + this.regionId = regionId;
  1080 + }
  1081 +
  1082 + public String getBlockStations() {
  1083 + return blockStations;
  1084 + }
  1085 +
  1086 + public void setBlockStations(String blockStations) {
  1087 + this.blockStations = blockStations;
  1088 + }
  1089 +
  1090 + public int getRegionSwitchState() {
  1091 + return regionSwitchState;
  1092 + }
  1093 +
  1094 + public void setRegionSwitchState(int regionSwitchState) {
  1095 + this.regionSwitchState = regionSwitchState;
  1096 + }
  1097 +
1058 @Override 1098 @Override
1059 public ScheduleRealInfo clone() throws CloneNotSupportedException { 1099 public ScheduleRealInfo clone() throws CloneNotSupportedException {
1060 ScheduleRealInfo cloned = (ScheduleRealInfo) super.clone(); 1100 ScheduleRealInfo cloned = (ScheduleRealInfo) super.clone();
src/main/java/com/bsth/service/directive/DirectiveService.java
1 -package com.bsth.service.directive;  
2 -  
3 -  
4 -import com.bsth.entity.directive.D60;  
5 -import com.bsth.entity.directive.D64;  
6 -import com.bsth.entity.directive.D80;  
7 -import com.bsth.entity.directive.DC0_A3;  
8 -import com.bsth.entity.realcontrol.ScheduleRealInfo;  
9 -import com.bsth.service.BaseService;  
10 -  
11 -import java.util.List;  
12 -import java.util.Map;  
13 -  
14 -public interface DirectiveService extends BaseService<D60, Integer>{  
15 -  
16 - /**  
17 - *  
18 - * @Title: send60Phrase  
19 - * @Description: TODO(60短语下发)  
20 - * @param @param nbbm 车辆内部编码  
21 - * @param @param text 短语  
22 - * @return int 返回类型  
23 - * @throws  
24 - */  
25 - int send60Phrase(String nbbm, String text, String sender);  
26 -  
27 - /**  
28 - *  
29 - * @Title: send60Dispatch  
30 - * @Description: TODO(调度指令下发)  
31 - * @param @param sch 要下发的班次  
32 - * @param @param finish 已完成的班次数  
33 - * @throws  
34 - */  
35 - int send60Dispatch(ScheduleRealInfo sch, int finish, String sender,String txtPrefix);  
36 -  
37 -  
38 - int send60Dispatchcc(ScheduleRealInfo sch, int finish, String sender,String txtPrefix);  
39 -  
40 - /**  
41 - *  
42 - * @Title: send60Dispatch  
43 - * @Description: TODO(调度指令下发)  
44 - * @param @param id 班次ID  
45 - * @throws  
46 - */  
47 - int send60Dispatch(Long id, String sender);  
48 -  
49 - int send60DispatchZndd(Long id, String sender);  
50 - //60营运指令  
51 - int send60Operation(String nbbm, int state, int upDown, String sender);  
52 -  
53 - /**  
54 - *  
55 - * @Title: lineChange  
56 - * @Description: TODO(线路切换)  
57 - * @param @param nbbm 车辆内部编码  
58 - * @param @param lineId 新线路编码  
59 - * @throws  
60 - */  
61 - int lineChange(String nbbm, String lineId, String sender);  
62 -  
63 - int lineChangeByDeviceId(String deviceId, String lineCode, String sender);  
64 -  
65 - /**  
66 - *  
67 - * @Title: upDownChange  
68 - * @Description: TODO(切换上下行)  
69 - * @param @param nbbm 车辆内部编码  
70 - * @param @param upDonw 上下行 0 上行 1 下行  
71 - * @throws  
72 - */  
73 - //int upDownChange(String nbbm, Integer upDown, String sender);  
74 -  
75 - /**  
76 - *  
77 - * @Title: sendDirectiveState  
78 - * @Description: TODO(向页面推送班次指令状态)  
79 - * @throws  
80 - */  
81 - void sendD60ToPage(ScheduleRealInfo sch);  
82 -  
83 - Map<String, List<D80>> findNoCofm80(String lineCodes);  
84 -  
85 - Map<String, Object> reply80(int id, int reply);  
86 -  
87 - Map<String, Object> findDirective(String nbbm, int dType, int page, int size);  
88 -  
89 - Map<String, Object> findAll80(Map<String, Object> map, int page, int size);  
90 -  
91 - D64 save64(D64 d64);  
92 -  
93 - Map<String, Object> sendC0A4(String nbbm);  
94 -  
95 - int sendC0A3(DC0_A3 c0a4);  
96 -  
97 - int sendC0A5(String json);  
98 -  
99 - int refreshLineFile(String deviceId);  
100 -  
101 - //int stateChange(String nbbm, Integer upDown, Integer state, String userName);  
102 -  
103 - Map<String,Object> deviceCofigList(Map<String, String> map, int page, int size);  
104 -} 1 +package com.bsth.service.directive;
  2 +
  3 +
  4 +import com.bsth.entity.directive.D60;
  5 +import com.bsth.entity.directive.D64;
  6 +import com.bsth.entity.directive.D80;
  7 +import com.bsth.entity.directive.DC0_A3;
  8 +import com.bsth.entity.realcontrol.ScheduleRealInfo;
  9 +import com.bsth.service.BaseService;
  10 +
  11 +import java.util.List;
  12 +import java.util.Map;
  13 +
  14 +public interface DirectiveService extends BaseService<D60, Integer>{
  15 +
  16 + /**
  17 + *
  18 + * @Title: send60Phrase
  19 + * @Description: TODO(60短语下发)
  20 + * @param @param nbbm 车辆内部编码
  21 + * @param @param text 短语
  22 + * @return int 返回类型
  23 + * @throws
  24 + */
  25 + int send60Phrase(String nbbm, String text, String sender);
  26 +
  27 + /**
  28 + *
  29 + * @Title: send60Dispatch
  30 + * @Description: TODO(调度指令下发)
  31 + * @param @param sch 要下发的班次
  32 + * @param @param finish 已完成的班次数
  33 + * @throws
  34 + */
  35 + int send60Dispatch(ScheduleRealInfo sch, int finish, String sender,String txtPrefix);
  36 +
  37 +
  38 + int send60Dispatchcc(ScheduleRealInfo sch, int finish, String sender,String txtPrefix);
  39 +
  40 + /**
  41 + *
  42 + * @Title: send60Dispatch
  43 + * @Description: TODO(调度指令下发)
  44 + * @param @param id 班次ID
  45 + * @throws
  46 + */
  47 + int send60Dispatch(Long id, String sender);
  48 +
  49 + int send60DispatchZndd(Long id, String sender);
  50 + //60营运指令
  51 + int send60Operation(String nbbm, int state, int upDown, String sender);
  52 +
  53 + /**
  54 + *
  55 + * @Title: lineChange
  56 + * @Description: TODO(线路切换)
  57 + * @param @param nbbm 车辆内部编码
  58 + * @param @param lineId 新线路编码
  59 + * @throws
  60 + */
  61 + int lineChange(String nbbm, String lineId, String sender);
  62 +
  63 + int lineChange(String nbbm, String lineId, ScheduleRealInfo sch, String sender);
  64 +
  65 + int lineChangeByDeviceId(String deviceId, String lineCode, String sender);
  66 +
  67 + int lineChangeByDeviceId(String deviceId, String lineCode, ScheduleRealInfo sch, String sender);
  68 +
  69 + /**
  70 + *
  71 + * @Title: upDownChange
  72 + * @Description: TODO(切换上下行)
  73 + * @param @param nbbm 车辆内部编码
  74 + * @param @param upDonw 上下行 0 上行 1 下行
  75 + * @throws
  76 + */
  77 + //int upDownChange(String nbbm, Integer upDown, String sender);
  78 +
  79 + /**
  80 + *
  81 + * @Title: sendDirectiveState
  82 + * @Description: TODO(向页面推送班次指令状态)
  83 + * @throws
  84 + */
  85 + void sendD60ToPage(ScheduleRealInfo sch);
  86 +
  87 + Map<String, List<D80>> findNoCofm80(String lineCodes);
  88 +
  89 + Map<String, Object> reply80(int id, int reply);
  90 +
  91 + Map<String, Object> findDirective(String nbbm, int dType, int page, int size);
  92 +
  93 + Map<String, Object> findAll80(Map<String, Object> map, int page, int size);
  94 +
  95 + D64 save64(D64 d64);
  96 +
  97 + Map<String, Object> sendC0A4(String nbbm);
  98 +
  99 + int sendC0A3(DC0_A3 c0a4);
  100 +
  101 + int sendC0A5(String json);
  102 +
  103 + int refreshLineFile(String deviceId);
  104 +
  105 + //int stateChange(String nbbm, Integer upDown, Integer state, String userName);
  106 +
  107 + Map<String,Object> deviceCofigList(Map<String, String> map, int page, int size);
  108 +}
src/main/java/com/bsth/service/directive/DirectiveServiceImpl.java
1 -package com.bsth.service.directive;  
2 -  
3 -import com.alibaba.fastjson.JSON;  
4 -import com.alibaba.fastjson.JSONObject;  
5 -import com.bsth.common.ResponseCode;  
6 -import com.bsth.data.BasicData;  
7 -import com.bsth.data.directive.DayOfDirectives;  
8 -import com.bsth.data.directive.DirectiveCreator;  
9 -import com.bsth.data.directive.GatewayHttpUtils;  
10 -import com.bsth.data.gpsdata_v2.GpsRealData;  
11 -import com.bsth.data.gpsdata_v2.entity.GpsEntity;  
12 -import com.bsth.data.pilot80.PilotReport;  
13 -import com.bsth.data.schedule.DayOfSchedule;  
14 -import com.bsth.data.utils.ListFilterUtils;  
15 -import com.bsth.data.utils.ListPageQueryUtils;  
16 -import com.bsth.entity.directive.*;  
17 -import com.bsth.entity.realcontrol.ScheduleRealInfo;  
18 -import com.bsth.entity.sys.SysUser;  
19 -import com.bsth.repository.directive.D60Repository;  
20 -import com.bsth.repository.directive.D64Repository;  
21 -import com.bsth.repository.directive.D80Repository;  
22 -import com.bsth.security.util.SecurityUtils;  
23 -import com.bsth.service.directive.dto.DeviceConfigDto;  
24 -import com.bsth.service.impl.BaseServiceImpl;  
25 -import com.bsth.websocket.handler.RealControlSocketHandler;  
26 -import com.fasterxml.jackson.core.JsonProcessingException;  
27 -import com.fasterxml.jackson.databind.ObjectMapper;  
28 -import com.google.common.base.Splitter;  
29 -import org.apache.commons.lang3.StringEscapeUtils;  
30 -import org.apache.commons.lang3.StringUtils;  
31 -import org.joda.time.format.DateTimeFormat;  
32 -import org.joda.time.format.DateTimeFormatter;  
33 -import org.slf4j.Logger;  
34 -import org.slf4j.LoggerFactory;  
35 -import org.springframework.beans.factory.annotation.Autowired;  
36 -import org.springframework.jdbc.core.BeanPropertyRowMapper;  
37 -import org.springframework.jdbc.core.JdbcTemplate;  
38 -import org.springframework.stereotype.Service;  
39 -  
40 -import java.util.*;  
41 -  
42 -@Service  
43 -public class DirectiveServiceImpl extends BaseServiceImpl<D60, Integer> implements DirectiveService {  
44 -  
45 - Logger logger = LoggerFactory.getLogger(this.getClass());  
46 -  
47 - @Autowired  
48 - D60Repository d60Repository;  
49 -  
50 - @Autowired  
51 - GpsRealData gpsRealDataBuffer;  
52 -  
53 - @Autowired  
54 - D64Repository d64Repository;  
55 -  
56 - @Autowired  
57 - RealControlSocketHandler socketHandler;  
58 -  
59 - @Autowired  
60 - D80Repository d80Repository;  
61 -  
62 - @Autowired  
63 - DayOfDirectives dayOfDirectives;  
64 -  
65 - @Autowired  
66 - PilotReport pilotReport;  
67 -  
68 - @Autowired  
69 - DayOfSchedule dayOfSchedule;  
70 -  
71 - @Autowired  
72 - JdbcTemplate jdbcTemplate;  
73 -  
74 - //static Long schDiff = 1000 * 60 * 60L;  
75 -  
76 - private static DateTimeFormatter fmtHHmm = DateTimeFormat.forPattern("HH:mm"), fmtHHmm_CN = DateTimeFormat.forPattern("HH点mm分");  
77 -  
78 - @Override  
79 - public int send60Phrase(String nbbm, String text, String sender) {  
80 - D60 d60 = null;  
81 - try {  
82 - text = StringEscapeUtils.unescapeHtml4(text);  
83 - text = text.replaceAll("#", "");  
84 - d60 = create60Data(nbbm, text, (short) 0x00, null);  
85 - } catch (Exception e) {  
86 - logger.error("发送消息短语出现异常", e);  
87 - return -1;  
88 - }  
89 -  
90 - if (null == d60)  
91 - return -1;  
92 -  
93 - // 发送指令  
94 - int code = GatewayHttpUtils.postJson(JSON.toJSONString(d60));  
95 - if (null != sender)  
96 - d60.setSender(sender);  
97 - d60.setHttpCode(code);  
98 -  
99 - if (code != 0)  
100 - d60.setErrorText("网关通讯失败, code: " + code);  
101 -  
102 - dayOfDirectives.put60(d60);  
103 - return code;  
104 - }  
105 -  
106 - @Override  
107 - public int send60Dispatch(ScheduleRealInfo sch, int finish, String sender, String txtPrefix) {  
108 - D60 d60 = null;  
109 - try {  
110 - if (sch.isDestroy()) {  
111 - logger.warn("烂班不允许发送调度指令....");  
112 - return -1;  
113 - }  
114 -  
115 - //待发应到时间  
116 - String dfsj = fmtHHmm.print(sch.getDfsjT() + (sch.getBcsj() * 60 * 1000));  
117 - String text = "您已完成" + finish + "个班次,下一发车时间" + fmtHHmm_CN.print(sch.getDfsjT()) + ",由"  
118 - + sch.getQdzName() + "发往" + sch.getZdzName() + ";应到 " + dfsj;  
119 -  
120 - if(sch.getBcType().equals("venting")){  
121 - text += " (直放)";  
122 - }  
123 - else if(sch.getBcType().equals("major")){  
124 - text += " (放站到"+sch.getMajorStationName()+"带客)";  
125 - } else if ("ldks".equals(sch.getBcType())) {  
126 - text += " (两点空驶)";  
127 - }  
128 -  
129 - //下发0x02指令 调度指令(闹钟有效)  
130 - long t = System.currentTimeMillis() + 1000 * 30,  
131 - alarmTime = sch.getDfsjT() < t?t:sch.getDfsjT();  
132 -  
133 - if(StringUtils.isNotEmpty(txtPrefix)){  
134 - text = txtPrefix + text;  
135 - }  
136 - text = StringEscapeUtils.unescapeHtml4(text);  
137 - int state = 0;//营运状态  
138 - if(dayOfSchedule.emptyService(sch))  
139 - state = 1;  
140 - d60 = new DirectiveCreator().createD60_02(sch.getClZbh(), text, Integer.parseInt(sch.getXlDir())  
141 - , state, new Date(alarmTime));  
142 -  
143 - d60.setLineCode(sch.getXlBm());  
144 - } catch (Exception e) {  
145 - logger.error("生成调度指令时出现异常", e);  
146 - return -1;  
147 - }  
148 -  
149 - if (null == d60)  
150 - return -1;  
151 -  
152 - d60.setSender(sender);  
153 -  
154 - JSONObject jObj = JSON.parseObject(JSON.toJSONString(d60));  
155 -  
156 - //进场或者出场班次时,附加lock 标识  
157 - if (null != sch.getBcType()  
158 - && (sch.getBcType().equals("out") || sch.getBcType().equals("in"))) {  
159 -  
160 - jObj.put("lock", 1);  
161 - }  
162 -  
163 - // 发送指令  
164 - int code = GatewayHttpUtils.postJson(jObj.toJSONString());  
165 -  
166 - d60.setDispatch(true);  
167 - d60.setSch(sch);  
168 - d60.setHttpCode(code);  
169 -  
170 - if (code == 0) {  
171 - sch.setDirectiveState(60);  
172 - // 通知页面  
173 - sendD60ToPage(sch);  
174 - } else {  
175 - d60.setErrorText("网关通讯失败, code: " + code);  
176 - }  
177 -  
178 - dayOfDirectives.put60(d60);  
179 - return code;  
180 - }  
181 -  
182 - //出场请求  
183 - @Override  
184 - public int send60Dispatchcc(ScheduleRealInfo sch, int finish, String sender, String txtPrefix) {  
185 - D60 d60 = null;  
186 - try {  
187 - if (sch.isDestroy()) {  
188 - logger.warn("烂班不允许发送调度指令....");  
189 - return -1;  
190 - }  
191 - //待发应到时间  
192 - String dfsj = fmtHHmm.print(sch.getDfsjT() + (sch.getBcsj() * 60 * 1000));  
193 - String text = "出场请求,由" + sch.getQdzName() + "发往" + sch.getZdzName() + ";请出场";  
194 -  
195 - //下发0x02指令 调度指令(闹钟有效)  
196 - long t = System.currentTimeMillis() + 1000 * 30,  
197 - alarmTime = sch.getDfsjT() < t?t:sch.getDfsjT();  
198 -  
199 - if(StringUtils.isNotEmpty(txtPrefix)){  
200 - text = txtPrefix + text;  
201 - }  
202 - text = StringEscapeUtils.unescapeHtml4(text);  
203 - int state = 0;//营运状态  
204 - if(dayOfSchedule.emptyService(sch))  
205 - state = 1;  
206 - d60 = new DirectiveCreator().createD60_02(sch.getClZbh(), text, Integer.parseInt(sch.getXlDir())  
207 - , state, new Date(alarmTime));  
208 -  
209 - d60.setLineCode(sch.getXlBm());  
210 - } catch (Exception e) {  
211 - logger.error("生成调度指令时出现异常", e);  
212 - return -1;  
213 - }  
214 -  
215 - if (null == d60)  
216 - return -1;  
217 -  
218 - d60.setSender(sender);  
219 -  
220 - JSONObject jObj = JSON.parseObject(JSON.toJSONString(d60));  
221 -  
222 - //进场或者出场班次时,附加lock 标识  
223 - if (null != sch.getBcType()  
224 - && (sch.getBcType().equals("out") || sch.getBcType().equals("in"))) {  
225 -  
226 - jObj.put("lock", 1);  
227 - }  
228 -  
229 - // 发送指令  
230 - int code = GatewayHttpUtils.postJson(jObj.toJSONString());  
231 -  
232 - d60.setDispatch(true);  
233 - d60.setSch(sch);  
234 - d60.setHttpCode(code);  
235 -  
236 - if (code == 0) {  
237 - sch.setDirectiveState(60);  
238 - // 通知页面  
239 - sendD60ToPage(sch);  
240 - } else {  
241 - d60.setErrorText("网关通讯失败, code: " + code);  
242 - }  
243 -  
244 - dayOfDirectives.put60(d60);  
245 - return code;  
246 - }  
247 -  
248 -  
249 - public int send60DispatchZndd(ScheduleRealInfo sch, int finish, String sender, String txtPrefix) {  
250 - D60 d60 = null;  
251 - try {  
252 - if (sch.isDestroy()) {  
253 - logger.warn("烂班不允许发送调度指令....");  
254 - return -1;  
255 - }  
256 -  
257 - //待发应到时间  
258 - String dfsj = fmtHHmm.print(sch.getDfsjT() + (sch.getBcsj() * 60 * 1000));  
259 - String text = "(自动补发命令)"+sch.getFcsjActual() +"发出的,由"  
260 - + sch.getQdzName() + "发往" + sch.getZdzName() + ";还未确认,请尽快确认";  
261 -  
262 - if(sch.getBcType().equals("venting")){  
263 - text += " (直放)";  
264 - }  
265 - else if(sch.getBcType().equals("major")){  
266 - text += " (放站到"+sch.getMajorStationName()+"带客)";  
267 - } else if ("ldks".equals(sch.getBcType())) {  
268 - text += " (两点空驶)";  
269 - }  
270 -  
271 - //下发0x02指令 调度指令(闹钟有效)  
272 - long t = System.currentTimeMillis() + 1000 * 30,  
273 - alarmTime = sch.getDfsjT() < t?t:sch.getDfsjT();  
274 -  
275 - if(StringUtils.isNotEmpty(txtPrefix)){  
276 - text = txtPrefix + text;  
277 - }  
278 - text = StringEscapeUtils.unescapeHtml4(text);  
279 - int state = 0;//营运状态  
280 - if(dayOfSchedule.emptyService(sch))  
281 - state = 1;  
282 - d60 = new DirectiveCreator().createD60_02(sch.getClZbh(), text, Integer.parseInt(sch.getXlDir())  
283 - , state, new Date(alarmTime));  
284 -  
285 - d60.setLineCode(sch.getXlBm());  
286 - } catch (Exception e) {  
287 - logger.error("生成调度指令时出现异常", e);  
288 - return -1;  
289 - }  
290 -  
291 - if (null == d60)  
292 - return -1;  
293 -  
294 - d60.setSender(sender);  
295 -  
296 - JSONObject jObj = JSON.parseObject(JSON.toJSONString(d60));  
297 -  
298 - //进场或者出场班次时,附加lock 标识  
299 - if (null != sch.getBcType()  
300 - && (sch.getBcType().equals("out") || sch.getBcType().equals("in"))) {  
301 -  
302 - jObj.put("lock", 1);  
303 - }  
304 -  
305 - // 发送指令  
306 - int code = GatewayHttpUtils.postJson(jObj.toJSONString());  
307 -  
308 - d60.setDispatch(true);  
309 - d60.setSch(sch);  
310 - d60.setHttpCode(code);  
311 -  
312 - if (code == 0) {  
313 - sch.setDirectiveState(60);  
314 - // 通知页面  
315 - sendD60ToPage(sch);  
316 - } else {  
317 - d60.setErrorText("网关通讯失败, code: " + code);  
318 - }  
319 - dayOfDirectives.put60(d60);  
320 - return code;  
321 - }  
322 -  
323 - /**  
324 - * @Title: sendDirectiveState @Description: TODO(向页面推送班次指令状态) @throws  
325 - */  
326 - @Override  
327 - public void sendD60ToPage(ScheduleRealInfo sch) {  
328 - Map<String, Object> map = new HashMap<>();  
329 - map.put("fn", "directive");  
330 - map.put("t", sch);  
331 -  
332 - ObjectMapper mapper = new ObjectMapper();  
333 -  
334 - try {  
335 - socketHandler.sendMessageToLine(sch.getXlBm(), mapper.writeValueAsString(map));  
336 - } catch (JsonProcessingException e) {  
337 - logger.error("", e);  
338 - }  
339 - }  
340 -  
341 - @Override  
342 - public int send60Dispatch(Long id, String sender) {  
343 - ScheduleRealInfo sch = dayOfSchedule.get(id);  
344 - // 车辆已完成班次  
345 - int finish = dayOfSchedule.doneSum(sch.getClZbh());  
346 - return send60Dispatch(sch, finish, sender, "");  
347 - }  
348 -  
349 - @Override  
350 - public int send60DispatchZndd(Long id, String sender) {  
351 - ScheduleRealInfo sch = dayOfSchedule.get(id);  
352 - // 车辆已完成班次  
353 - int finish = dayOfSchedule.doneSum(sch.getClZbh());  
354 - return send60DispatchZndd(sch, finish, sender, "");  
355 - }  
356 -  
357 - @Override  
358 - public int send60Operation(String nbbm, int state, int upDown, String sender) {  
359 - logger.info("切换运营状态, nbbm: " + nbbm + " ,state: " + state + " ,upDown:" + upDown);  
360 -  
361 - String text = "切换为 " + (upDown == 0 ? "上行" : "下行") + (state == 0 ? "营运" : "未营运");  
362 - D60 d60 = new DirectiveCreator().createD60(nbbm, text, (short) 0x03, upDown, state, null);  
363 -  
364 - if (null == d60)  
365 - return -1;  
366 - if (null != sender)  
367 - d60.setSender(sender);  
368 - else  
369 - d60.setSender("系统");  
370 - // 发送指令  
371 - int code = GatewayHttpUtils.postJson(JSON.toJSONString(d60));  
372 - // 添加到缓存,等待入库  
373 - d60.setHttpCode(code);  
374 -  
375 - GpsEntity gps = gpsRealDataBuffer.getByNbbm(nbbm);  
376 - if(null != gps)  
377 - d60.setLineCode(gps.getLineId());  
378 -  
379 - if (code != 0)  
380 - d60.setErrorText("网关通讯失败, code: " + code);  
381 -  
382 - dayOfDirectives.put60(d60);  
383 - return code;  
384 - }  
385 -  
386 - /**  
387 - * 线路切换  
388 - */  
389 - @Override  
390 - public int lineChange(String nbbm, String lineCode, String sender) {  
391 - return lineChangeByDeviceId(BasicData.deviceId2NbbmMap.inverse().get(nbbm), lineCode, sender);  
392 - }  
393 -  
394 -  
395 - @Override  
396 - public int lineChangeByDeviceId(String deviceId, String lineCode, String sender) {  
397 - DirectiveCreator crt = new DirectiveCreator();  
398 - Long t = System.currentTimeMillis();  
399 - //生成64数据包  
400 - D64 d64 = crt.create64(deviceId, lineCode, t);  
401 -  
402 - if (null != sender)  
403 - d64.setSender(sender);  
404 - else  
405 - d64.setSender("系统");  
406 -  
407 - //String deviceId = d64.getDeviceId();  
408 - int code = GatewayHttpUtils.postJson(JSON.toJSONString(d64));  
409 - // 入库  
410 - d64.setHttpCode(code);  
411 - d64.getData().setTxtContent("切换线路[" + BasicData.lineCode2NameMap.get(lineCode) + "]");  
412 - // 通知设备刷新线路文件,忽略结果  
413 - if (code == 0)  
414 - GatewayHttpUtils.postJson(crt.createDeviceRefreshData(deviceId, lineCode));  
415 - else  
416 - d64.setErrorText(" 网关通讯失败, code: " + code);  
417 -  
418 - dayOfDirectives.put64(d64);  
419 - return code;  
420 - }  
421 -  
422 - public D60 create60Data(String nbbm, String text, Short dispatchInstruct, ScheduleRealInfo sch) {  
423 -  
424 - String deviceId = BasicData.deviceId2NbbmMap.inverse().get(nbbm);  
425 - String lineCode = null;  
426 - if (null == deviceId) {  
427 - logger.error("没有设备号对照的车辆:" + nbbm);  
428 - return null;  
429 - }  
430 - // 根据当前GPS确定 上下行和营运状态  
431 - Byte upDown = null;  
432 - Integer state = null;  
433 - if (null == sch) {  
434 - GpsEntity gpsData = gpsRealDataBuffer.get(deviceId);  
435 - if (null == gpsData) {  
436 - /*  
437 - * 短语指令不会变更设备状态,所以在没有gps状态对照的情况下可以下发  
438 - * 其他指令在不确定状态的情况下,一律不允许  
439 - */  
440 - if (dispatchInstruct == 0) {  
441 - upDown = 0;  
442 - state = 0;  
443 - } else {  
444 - logger.error("没有找到gps对照,无法确认营运状态和上下行:" + nbbm);  
445 - return null;  
446 - }  
447 - } else {  
448 - upDown = gpsData.getUpDown();  
449 - state = gpsData.getState();  
450 - lineCode = gpsData.getLineId();  
451 - }  
452 - } else {  
453 - upDown = Byte.parseByte(sch.getXlDir());  
454 - state = 0;  
455 - }  
456 -  
457 - return new DirectiveCreator().createD60(nbbm, text, dispatchInstruct, upDown, state, lineCode);  
458 - }  
459 -  
460 -/* @Override  
461 - public int upDownChange(String nbbm, Integer upDown, String sender) {  
462 - return send60Operation(nbbm, 0, upDown, sender);  
463 - }*/  
464 -  
465 -  
466 - @Override  
467 - public Map<String, List<D80>> findNoCofm80(String lineCodes) {  
468 - List<String> lineList = Splitter.on(",").trimResults().splitToList(lineCodes);  
469 -  
470 - Map<String, List<D80>> rs = new HashMap<>();  
471 - for (String code : lineList)  
472 - rs.put(code, pilotReport.unconfirmed80(code));  
473 -  
474 - return rs;  
475 - }  
476 -  
477 - @Override  
478 - public Map<String, Object> reply80(int id, int reply) {  
479 - Map<String, Object> rs = new HashMap<>();  
480 - D80 d80 = pilotReport.findById(id);  
481 - try {  
482 - if (null == d80) {  
483 - rs.put("status", ResponseCode.ERROR);  
484 - rs.put("msg", "服务器没有找到对应数据!");  
485 - } else if (d80.isConfirm()) {  
486 - rs.put("status", ResponseCode.ERROR);  
487 - rs.put("msg", "该数据已经被处理了!");  
488 - } else {  
489 - SysUser user = SecurityUtils.getCurrentUser();  
490 - d80.setC0(reply, user.getUserName());  
491 - // 入库  
492 - d80Repository.save(d80);  
493 - //回复网关  
494 - int code = GatewayHttpUtils.postJson(JSON.toJSONString(d80.getC0()));  
495 -  
496 - rs.put("status", ResponseCode.SUCCESS);  
497 - if (code != 0)  
498 - rs.put("msg", "发送C0响应指令到车载设备失败,但该操作已经被系统记录!");  
499 -  
500 - pilotReport.reply(d80);  
501 -  
502 - // 通知页面  
503 - Map<String, Object> sockMap = new HashMap<>();  
504 - sockMap.put("fn", "d80Confirm");  
505 - sockMap.put("id", d80.getId());  
506 - sockMap.put("lineId", d80.getData().getLineId());  
507 - socketHandler.sendMessageToLine(d80.getData().getLineId().toString(), JSON.toJSONString(sockMap));  
508 - }  
509 - } catch (Exception e) {  
510 - logger.error("80响应出现异常...", e);  
511 - rs.put("status", ResponseCode.SUCCESS);  
512 - }  
513 -  
514 - return rs;  
515 - }  
516 -  
517 - @Override  
518 - public Map<String, Object> findDirective(String nbbms, int dType, int page, int size) {  
519 - Map<String, Object> rsMap = new HashMap<>();  
520 - try{  
521 -  
522 - List<String> carArray = new ArrayList<>(), deviceArray=new ArrayList<>();  
523 - if(StringUtils.isNotEmpty(nbbms)){  
524 - carArray = Splitter.on(",").splitToList(nbbms);  
525 - //转换成设备号  
526 - Map<String, String> nbbm2deviceMap = BasicData.deviceId2NbbmMap.inverse();  
527 - for(int i = 0, len=carArray.size(); i < len; i++){  
528 - deviceArray.add(nbbm2deviceMap.get(carArray.get(i)));  
529 - }  
530 - }  
531 -  
532 - List<Directive> list = new ArrayList<>();  
533 - switch (dType) {  
534 - case -1:  
535 - //所有指令  
536 - list = new ArrayList<>(dayOfDirectives.all());  
537 - break;  
538 - case 0:  
539 - //调度指令  
540 - Collection<D60> dptArray = dayOfDirectives.all60();  
541 - for (D60 d60 : dptArray) {  
542 - if (d60.isDispatch())  
543 - list.add(d60);  
544 - }  
545 - break;  
546 - case 1:  
547 - //运营指令  
548 - Collection<D60> yyArray = dayOfDirectives.all60();  
549 - for (D60 d60 : yyArray) {  
550 - if (d60 != null && d60.getData().getDispatchInstruct() == (short) 0x03  
551 - && !d60.isDispatch())  
552 - list.add(d60);  
553 - }  
554 - break;  
555 - case 2:  
556 - //线路切换指令  
557 - list.addAll(dayOfDirectives.all64());  
558 - break;  
559 - case 3:  
560 - //消息短语  
561 - Collection<D60> dyArray = dayOfDirectives.all60();  
562 - for (D60 d60 : dyArray) {  
563 - if (d60 != null && d60.getData().getDispatchInstruct() == (short) 0x00  
564 - && !d60.isDispatch())  
565 - list.add(d60);  
566 - }  
567 - break;  
568 - }  
569 -  
570 - // 时间倒序  
571 - Collections.sort(list, new DayOfDirectives.DComparator());  
572 - if(deviceArray.size() > 0){  
573 - //按设备号过滤  
574 - List<Directive> subList = new ArrayList<>();  
575 - for (Directive d : list) {  
576 - if (deviceArray.contains(d.getDeviceId())) {  
577 - subList.add(d);  
578 - }  
579 - }  
580 - list = subList;  
581 - }  
582 -  
583 - for(Directive d : list){  
584 - d.setTimeHHmm(fmtHHmm.print(d.getTimestamp()));  
585 - d.setNbbm(BasicData.deviceId2NbbmMap.get(d.getDeviceId()));  
586 - }  
587 -  
588 - int count = list.size();  
589 - // 分页  
590 - int s = page * size, e = s + size;  
591 -  
592 - if (e > count)  
593 - e = count;  
594 -  
595 - List<Directive> rs = list.subList(s, e);  
596 - rsMap.put("list", rs);  
597 - rsMap.put("totalPages", count % size == 0 ? (count / size - 1) : count / size);  
598 - rsMap.put("page", page);  
599 - }catch (Exception e){  
600 - logger.error("", e);  
601 - throw e;  
602 - }  
603 - return rsMap;  
604 - }  
605 -  
606 - @Override  
607 - public Map<String, Object> findAll80(Map<String, Object> map, int page, int size) {  
608 -  
609 - List all = ListFilterUtils.filter(pilotReport.findAll(), map, D80.class);  
610 - //排序  
611 - Collections.sort(all, new Comparator<D80>() {  
612 - @Override  
613 - public int compare(D80 o1, D80 o2) {  
614 - return (int) (o2.getTimestamp() - o1.getTimestamp());  
615 - }  
616 - });  
617 - List<D80> d80s = ListPageQueryUtils.paging(all, page, size);  
618 - //时间格式化  
619 - for (D80 d80 : d80s) {  
620 - d80.setTimeStr(fmtHHmm.print(d80.getTimestamp()));  
621 - }  
622 - Map<String, Object> rsMap = new HashMap<>();  
623 - rsMap.put("list", d80s);  
624 - rsMap.put("totalPages", all.size() % size == 0 ? all.size() / size - 1: all.size() / size);  
625 - rsMap.put("page", page);  
626 - return rsMap;  
627 - }  
628 -  
629 - @Override  
630 - public D64 save64(D64 d64) {  
631 - return d64Repository.save(d64);  
632 - }  
633 -  
634 - @Override  
635 - public Map<String, Object> sendC0A4(String nbbm) {  
636 - Map<String, Object> rs = new HashMap<>();  
637 -  
638 - String deviceId = BasicData.deviceId2NbbmMap.inverse().get(nbbm);  
639 -  
640 - GpsEntity gps = gpsRealDataBuffer.get(deviceId);  
641 - if(gps == null || gps.isOffline()){  
642 - rs.put("status", ResponseCode.ERROR);  
643 - rs.put("msg", "下发指令失败,设备离线");  
644 - return rs;  
645 - }  
646 -  
647 - Map<String, Object> c0a4 = new HashMap<>();  
648 - c0a4.put("deviceId", deviceId);  
649 - c0a4.put("timestamp", System.currentTimeMillis());  
650 - c0a4.put("operCode", (short) 0xC0);  
651 -  
652 - Map<String, Object> data = new HashMap<>();  
653 - data.put("deviceId", deviceId);  
654 - data.put("operCode2", (short) 0xA4);  
655 - c0a4.put("data", data);  
656 -  
657 - int code = GatewayHttpUtils.postJson(JSON.toJSONString(c0a4));  
658 - if(code != 0){  
659 - rs.put("status", ResponseCode.ERROR);  
660 - rs.put("msg", "和网关通讯失败, code " + code);  
661 - }  
662 - else{  
663 - rs.put("status", ResponseCode.SUCCESS);  
664 - }  
665 - return rs;  
666 - }  
667 -  
668 - @Override  
669 - public int sendC0A3(DC0_A3 c0a3) {  
670 - GatewayHttpUtils.postJson(JSON.toJSONString(c0a3));  
671 - return 0;  
672 - }  
673 -  
674 - @Override  
675 - public int sendC0A5(String json) {  
676 - return GatewayHttpUtils.postJson(json);  
677 - }  
678 -  
679 - @Override  
680 - public int refreshLineFile(String deviceId) {  
681 - GpsEntity gps = gpsRealDataBuffer.get(deviceId);  
682 - if (gps == null)  
683 - return -1;  
684 -  
685 - return GatewayHttpUtils.postJson(new DirectiveCreator().createDeviceRefreshData(deviceId, gps.getLineId()));  
686 - }  
687 -  
688 -/* @Override  
689 - public int stateChange(String nbbm, Integer upDown, Integer state, String userName) {  
690 - return send60Operation(nbbm, state, upDown, userName);  
691 - }*/  
692 -  
693 - @Override  
694 - public Map<String, Object> deviceCofigList(Map<String, String> map, int page, int size) {  
695 - Map<String, Object> rs = new HashMap<>();  
696 - try {  
697 - String conts="";  
698 - if(StringUtils.isNotBlank(map.get("lineId"))){  
699 - conts+=" AND xl='" + map.get("lineId")+"'";  
700 - }  
701 - if(StringUtils.isNotBlank(map.get("nbbm"))){  
702 - conts+=" AND inside_code like '%" + map.get("nbbm")+"%'";  
703 - }  
704 - if(StringUtils.isNotBlank(map.get("deviceId"))){  
705 - conts+=" AND equipment_code like '%" + map.get("deviceId")+"%'";  
706 - }  
707 -  
708 - String sql = "select * from (SELECT * FROM (SELECT id AS cl_id,inside_code,equipment_code FROM bsth_c_cars ) t1 LEFT JOIN bsth_v_c0_a4 t2 ON t1.equipment_code = t2.id LEFT JOIN (SELECT xl,cl FROM bsth_c_s_ccinfo WHERE id IN (SELECT max(id) FROM bsth_c_s_ccinfo GROUP BY cl)) t3 ON t1.cl_id = t3.cl ORDER BY t2.`timestamp` DESC) t4 where 1=1 "+conts;  
709 -  
710 - int count = jdbcTemplate.queryForObject("select count(*) from ("+sql+") c1", Integer.class);  
711 - int totalPages = count % size == 0 ? count / size : count / size + 1;  
712 - int s = page * size;  
713 - List<DeviceConfigDto> list = jdbcTemplate.query(sql + " LIMIT " + s + "," + size, new BeanPropertyRowMapper<>(DeviceConfigDto.class));  
714 -  
715 - rs.put("status", ResponseCode.SUCCESS);  
716 - rs.put("list", list);  
717 - rs.put("totalPages", totalPages);  
718 - rs.put("page", page);  
719 - } catch (Exception e) {  
720 - e.printStackTrace();  
721 - logger.error("", e);  
722 - rs.put("status", ResponseCode.ERROR);  
723 - }  
724 - return rs;  
725 - }  
726 -} 1 +package com.bsth.service.directive;
  2 +
  3 +import com.alibaba.fastjson.JSON;
  4 +import com.alibaba.fastjson.JSONObject;
  5 +import com.bsth.common.ResponseCode;
  6 +import com.bsth.data.BasicData;
  7 +import com.bsth.data.directive.DayOfDirectives;
  8 +import com.bsth.data.directive.DirectiveCreator;
  9 +import com.bsth.data.directive.GatewayHttpUtils;
  10 +import com.bsth.data.gpsdata_v2.GpsRealData;
  11 +import com.bsth.data.gpsdata_v2.entity.GpsEntity;
  12 +import com.bsth.data.pilot80.PilotReport;
  13 +import com.bsth.data.schedule.DayOfSchedule;
  14 +import com.bsth.data.utils.ListFilterUtils;
  15 +import com.bsth.data.utils.ListPageQueryUtils;
  16 +import com.bsth.entity.directive.*;
  17 +import com.bsth.entity.realcontrol.ScheduleRealInfo;
  18 +import com.bsth.entity.sys.SysUser;
  19 +import com.bsth.repository.directive.D60Repository;
  20 +import com.bsth.repository.directive.D64Repository;
  21 +import com.bsth.repository.directive.D80Repository;
  22 +import com.bsth.security.util.SecurityUtils;
  23 +import com.bsth.service.directive.dto.DeviceConfigDto;
  24 +import com.bsth.service.impl.BaseServiceImpl;
  25 +import com.bsth.websocket.handler.RealControlSocketHandler;
  26 +import com.fasterxml.jackson.core.JsonProcessingException;
  27 +import com.fasterxml.jackson.databind.ObjectMapper;
  28 +import com.google.common.base.Splitter;
  29 +import org.apache.commons.lang3.StringEscapeUtils;
  30 +import org.apache.commons.lang3.StringUtils;
  31 +import org.joda.time.format.DateTimeFormat;
  32 +import org.joda.time.format.DateTimeFormatter;
  33 +import org.slf4j.Logger;
  34 +import org.slf4j.LoggerFactory;
  35 +import org.springframework.beans.factory.annotation.Autowired;
  36 +import org.springframework.jdbc.core.BeanPropertyRowMapper;
  37 +import org.springframework.jdbc.core.JdbcTemplate;
  38 +import org.springframework.stereotype.Service;
  39 +
  40 +import java.util.*;
  41 +
  42 +@Service
  43 +public class DirectiveServiceImpl extends BaseServiceImpl<D60, Integer> implements DirectiveService {
  44 +
  45 + Logger logger = LoggerFactory.getLogger(this.getClass());
  46 +
  47 + @Autowired
  48 + D60Repository d60Repository;
  49 +
  50 + @Autowired
  51 + GpsRealData gpsRealDataBuffer;
  52 +
  53 + @Autowired
  54 + D64Repository d64Repository;
  55 +
  56 + @Autowired
  57 + RealControlSocketHandler socketHandler;
  58 +
  59 + @Autowired
  60 + D80Repository d80Repository;
  61 +
  62 + @Autowired
  63 + DayOfDirectives dayOfDirectives;
  64 +
  65 + @Autowired
  66 + PilotReport pilotReport;
  67 +
  68 + @Autowired
  69 + DayOfSchedule dayOfSchedule;
  70 +
  71 + @Autowired
  72 + JdbcTemplate jdbcTemplate;
  73 +
  74 + @Autowired
  75 + private ObjectMapper mapper;
  76 +
  77 + //static Long schDiff = 1000 * 60 * 60L;
  78 +
  79 + private static DateTimeFormatter fmtHHmm = DateTimeFormat.forPattern("HH:mm"), fmtHHmm_CN = DateTimeFormat.forPattern("HH点mm分");
  80 +
  81 + @Override
  82 + public int send60Phrase(String nbbm, String text, String sender) {
  83 + D60 d60 = null;
  84 + try {
  85 + text = StringEscapeUtils.unescapeHtml4(text);
  86 + text = text.replaceAll("#", "");
  87 + d60 = create60Data(nbbm, text, (short) 0x00, null);
  88 + } catch (Exception e) {
  89 + logger.error("发送消息短语出现异常", e);
  90 + return -1;
  91 + }
  92 +
  93 + if (null == d60)
  94 + return -1;
  95 +
  96 + // 发送指令
  97 + int code = GatewayHttpUtils.postJson(JSON.toJSONString(d60));
  98 + if (null != sender)
  99 + d60.setSender(sender);
  100 + d60.setHttpCode(code);
  101 +
  102 + if (code != 0)
  103 + d60.setErrorText("网关通讯失败, code: " + code);
  104 +
  105 + dayOfDirectives.put60(d60);
  106 + return code;
  107 + }
  108 +
  109 + @Override
  110 + public int send60Dispatch(ScheduleRealInfo sch, int finish, String sender, String txtPrefix) {
  111 + D60 d60 = null;
  112 + try {
  113 + if (sch.isDestroy()) {
  114 + logger.warn("烂班不允许发送调度指令....");
  115 + return -1;
  116 + }
  117 +
  118 + //待发应到时间
  119 + String dfsj = fmtHHmm.print(sch.getDfsjT() + (sch.getBcsj() * 60 * 1000));
  120 + String text = "您已完成" + finish + "个班次,下一发车时间" + fmtHHmm_CN.print(sch.getDfsjT()) + ",由"
  121 + + sch.getQdzName() + "发往" + sch.getZdzName() + ";应到 " + dfsj;
  122 +
  123 + if(sch.getBcType().equals("venting")){
  124 + text += " (直放)";
  125 + }
  126 + else if(sch.getBcType().equals("major")){
  127 + text += " (放站到"+sch.getMajorStationName()+"带客)";
  128 + } else if ("ldks".equals(sch.getBcType())) {
  129 + text += " (两点空驶)";
  130 + }
  131 +
  132 + //下发0x02指令 调度指令(闹钟有效)
  133 + long t = System.currentTimeMillis() + 1000 * 30,
  134 + alarmTime = sch.getDfsjT() < t?t:sch.getDfsjT();
  135 +
  136 + if(StringUtils.isNotEmpty(txtPrefix)){
  137 + text = txtPrefix + text;
  138 + }
  139 + text = StringEscapeUtils.unescapeHtml4(text);
  140 + int state = 0;//营运状态
  141 + if(dayOfSchedule.emptyService(sch))
  142 + state = 1;
  143 + d60 = new DirectiveCreator().createD60_02(sch.getClZbh(), text, Integer.parseInt(sch.getXlDir())
  144 + , state, new Date(alarmTime));
  145 +
  146 + d60.setLineCode(sch.getXlBm());
  147 + } catch (Exception e) {
  148 + logger.error("生成调度指令时出现异常", e);
  149 + return -1;
  150 + }
  151 +
  152 + if (null == d60)
  153 + return -1;
  154 +
  155 + d60.setSender(sender);
  156 +
  157 + JSONObject jObj = JSON.parseObject(JSON.toJSONString(d60));
  158 +
  159 + //进场或者出场班次时,附加lock 标识
  160 + if (null != sch.getBcType()
  161 + && (sch.getBcType().equals("out") || sch.getBcType().equals("in"))) {
  162 +
  163 + jObj.put("lock", 1);
  164 + }
  165 +
  166 + // 发送指令
  167 + int code = GatewayHttpUtils.postJson(jObj.toJSONString());
  168 +
  169 + d60.setDispatch(true);
  170 + d60.setSch(sch);
  171 + d60.setHttpCode(code);
  172 +
  173 + if (code == 0) {
  174 + sch.setDirectiveState(60);
  175 + // 通知页面
  176 + sendD60ToPage(sch);
  177 + } else {
  178 + d60.setErrorText("网关通讯失败, code: " + code);
  179 + }
  180 +
  181 + dayOfDirectives.put60(d60);
  182 + return code;
  183 + }
  184 +
  185 + //出场请求
  186 + @Override
  187 + public int send60Dispatchcc(ScheduleRealInfo sch, int finish, String sender, String txtPrefix) {
  188 + D60 d60 = null;
  189 + try {
  190 + if (sch.isDestroy()) {
  191 + logger.warn("烂班不允许发送调度指令....");
  192 + return -1;
  193 + }
  194 + //待发应到时间
  195 + String dfsj = fmtHHmm.print(sch.getDfsjT() + (sch.getBcsj() * 60 * 1000));
  196 + String text = "出场请求,由" + sch.getQdzName() + "发往" + sch.getZdzName() + ";请出场";
  197 +
  198 + //下发0x02指令 调度指令(闹钟有效)
  199 + long t = System.currentTimeMillis() + 1000 * 30,
  200 + alarmTime = sch.getDfsjT() < t?t:sch.getDfsjT();
  201 +
  202 + if(StringUtils.isNotEmpty(txtPrefix)){
  203 + text = txtPrefix + text;
  204 + }
  205 + text = StringEscapeUtils.unescapeHtml4(text);
  206 + int state = 0;//营运状态
  207 + if(dayOfSchedule.emptyService(sch))
  208 + state = 1;
  209 + d60 = new DirectiveCreator().createD60_02(sch.getClZbh(), text, Integer.parseInt(sch.getXlDir())
  210 + , state, new Date(alarmTime));
  211 +
  212 + d60.setLineCode(sch.getXlBm());
  213 + } catch (Exception e) {
  214 + logger.error("生成调度指令时出现异常", e);
  215 + return -1;
  216 + }
  217 +
  218 + if (null == d60)
  219 + return -1;
  220 +
  221 + d60.setSender(sender);
  222 +
  223 + JSONObject jObj = JSON.parseObject(JSON.toJSONString(d60));
  224 +
  225 + //进场或者出场班次时,附加lock 标识
  226 + if (null != sch.getBcType()
  227 + && (sch.getBcType().equals("out") || sch.getBcType().equals("in"))) {
  228 +
  229 + jObj.put("lock", 1);
  230 + }
  231 +
  232 + // 发送指令
  233 + int code = GatewayHttpUtils.postJson(jObj.toJSONString());
  234 +
  235 + d60.setDispatch(true);
  236 + d60.setSch(sch);
  237 + d60.setHttpCode(code);
  238 +
  239 + if (code == 0) {
  240 + sch.setDirectiveState(60);
  241 + // 通知页面
  242 + sendD60ToPage(sch);
  243 + } else {
  244 + d60.setErrorText("网关通讯失败, code: " + code);
  245 + }
  246 +
  247 + dayOfDirectives.put60(d60);
  248 + return code;
  249 + }
  250 +
  251 +
  252 + public int send60DispatchZndd(ScheduleRealInfo sch, int finish, String sender, String txtPrefix) {
  253 + D60 d60 = null;
  254 + try {
  255 + if (sch.isDestroy()) {
  256 + logger.warn("烂班不允许发送调度指令....");
  257 + return -1;
  258 + }
  259 +
  260 + //待发应到时间
  261 + String dfsj = fmtHHmm.print(sch.getDfsjT() + (sch.getBcsj() * 60 * 1000));
  262 + String text = "(自动补发命令)"+sch.getFcsjActual() +"发出的,由"
  263 + + sch.getQdzName() + "发往" + sch.getZdzName() + ";还未确认,请尽快确认";
  264 +
  265 + if(sch.getBcType().equals("venting")){
  266 + text += " (直放)";
  267 + }
  268 + else if(sch.getBcType().equals("major")){
  269 + text += " (放站到"+sch.getMajorStationName()+"带客)";
  270 + } else if ("ldks".equals(sch.getBcType())) {
  271 + text += " (两点空驶)";
  272 + }
  273 +
  274 + //下发0x02指令 调度指令(闹钟有效)
  275 + long t = System.currentTimeMillis() + 1000 * 30,
  276 + alarmTime = sch.getDfsjT() < t?t:sch.getDfsjT();
  277 +
  278 + if(StringUtils.isNotEmpty(txtPrefix)){
  279 + text = txtPrefix + text;
  280 + }
  281 + text = StringEscapeUtils.unescapeHtml4(text);
  282 + int state = 0;//营运状态
  283 + if(dayOfSchedule.emptyService(sch))
  284 + state = 1;
  285 + d60 = new DirectiveCreator().createD60_02(sch.getClZbh(), text, Integer.parseInt(sch.getXlDir())
  286 + , state, new Date(alarmTime));
  287 +
  288 + d60.setLineCode(sch.getXlBm());
  289 + } catch (Exception e) {
  290 + logger.error("生成调度指令时出现异常", e);
  291 + return -1;
  292 + }
  293 +
  294 + if (null == d60)
  295 + return -1;
  296 +
  297 + d60.setSender(sender);
  298 +
  299 + JSONObject jObj = JSON.parseObject(JSON.toJSONString(d60));
  300 +
  301 + //进场或者出场班次时,附加lock 标识
  302 + if (null != sch.getBcType()
  303 + && (sch.getBcType().equals("out") || sch.getBcType().equals("in"))) {
  304 +
  305 + jObj.put("lock", 1);
  306 + }
  307 +
  308 + // 发送指令
  309 + int code = GatewayHttpUtils.postJson(jObj.toJSONString());
  310 +
  311 + d60.setDispatch(true);
  312 + d60.setSch(sch);
  313 + d60.setHttpCode(code);
  314 +
  315 + if (code == 0) {
  316 + sch.setDirectiveState(60);
  317 + // 通知页面
  318 + sendD60ToPage(sch);
  319 + } else {
  320 + d60.setErrorText("网关通讯失败, code: " + code);
  321 + }
  322 + dayOfDirectives.put60(d60);
  323 + return code;
  324 + }
  325 +
  326 + /**
  327 + * @Title: sendDirectiveState @Description: TODO(向页面推送班次指令状态) @throws
  328 + */
  329 + @Override
  330 + public void sendD60ToPage(ScheduleRealInfo sch) {
  331 + Map<String, Object> map = new HashMap<>();
  332 + map.put("fn", "directive");
  333 + map.put("t", sch);
  334 +
  335 + ObjectMapper mapper = new ObjectMapper();
  336 +
  337 + try {
  338 + socketHandler.sendMessageToLine(sch.getXlBm(), mapper.writeValueAsString(map));
  339 + } catch (JsonProcessingException e) {
  340 + logger.error("", e);
  341 + }
  342 + }
  343 +
  344 + @Override
  345 + public int send60Dispatch(Long id, String sender) {
  346 + ScheduleRealInfo sch = dayOfSchedule.get(id);
  347 + // 车辆已完成班次
  348 + int finish = dayOfSchedule.doneSum(sch.getClZbh());
  349 + return send60Dispatch(sch, finish, sender, "");
  350 + }
  351 +
  352 + @Override
  353 + public int send60DispatchZndd(Long id, String sender) {
  354 + ScheduleRealInfo sch = dayOfSchedule.get(id);
  355 + // 车辆已完成班次
  356 + int finish = dayOfSchedule.doneSum(sch.getClZbh());
  357 + return send60DispatchZndd(sch, finish, sender, "");
  358 + }
  359 +
  360 + @Override
  361 + public int send60Operation(String nbbm, int state, int upDown, String sender) {
  362 + logger.info("切换运营状态, nbbm: " + nbbm + " ,state: " + state + " ,upDown:" + upDown);
  363 +
  364 + String text = "切换为 " + (upDown == 0 ? "上行" : "下行") + (state == 0 ? "营运" : "未营运");
  365 + D60 d60 = new DirectiveCreator().createD60(nbbm, text, (short) 0x03, upDown, state, null);
  366 +
  367 + if (null == d60)
  368 + return -1;
  369 + if (null != sender)
  370 + d60.setSender(sender);
  371 + else
  372 + d60.setSender("系统");
  373 + // 发送指令
  374 + int code = GatewayHttpUtils.postJson(JSON.toJSONString(d60));
  375 + // 添加到缓存,等待入库
  376 + d60.setHttpCode(code);
  377 +
  378 + GpsEntity gps = gpsRealDataBuffer.getByNbbm(nbbm);
  379 + if(null != gps)
  380 + d60.setLineCode(gps.getLineId());
  381 +
  382 + if (code != 0)
  383 + d60.setErrorText("网关通讯失败, code: " + code);
  384 +
  385 + dayOfDirectives.put60(d60);
  386 + return code;
  387 + }
  388 +
  389 + @Override
  390 + public int lineChange(String nbbm, String lineCode, String sender) {
  391 + return lineChangeByDeviceId(BasicData.deviceId2NbbmMap.inverse().get(nbbm), lineCode, null, sender);
  392 + }
  393 +
  394 + /**
  395 + * 线路切换
  396 + */
  397 + @Override
  398 + public int lineChange(String nbbm, String lineCode, ScheduleRealInfo sch, String sender) {
  399 + return lineChangeByDeviceId(BasicData.deviceId2NbbmMap.inverse().get(nbbm), lineCode, sch, sender);
  400 + }
  401 +
  402 + @Override
  403 + public int lineChangeByDeviceId(String deviceId, String lineCode, String sender) {
  404 + return lineChangeByDeviceId(deviceId, lineCode, null, sender);
  405 + }
  406 +
  407 + @Override
  408 + public int lineChangeByDeviceId(String deviceId, String lineCode, ScheduleRealInfo sch, String sender) {
  409 + DirectiveCreator crt = new DirectiveCreator();
  410 + Long t = System.currentTimeMillis();
  411 + //生成64数据包
  412 + D64 d64 = crt.create64(deviceId, lineCode, sch, t);
  413 +
  414 + if (null != sender)
  415 + d64.setSender(sender);
  416 + else
  417 + d64.setSender("系统");
  418 +
  419 + //String deviceId = d64.getDeviceId();
  420 + int code = -1;
  421 + try {
  422 + code = GatewayHttpUtils.postJson(mapper.writeValueAsString(d64));
  423 + } catch (JsonProcessingException e) {
  424 + throw new RuntimeException(e);
  425 + }
  426 + // 入库
  427 + d64.setHttpCode(code);
  428 + d64.getData().setTxtContent("切换线路[" + BasicData.lineCode2NameMap.get(lineCode) + "]");
  429 + // 通知设备刷新线路文件,忽略结果
  430 + if (code == 0)
  431 + GatewayHttpUtils.postJson(crt.createDeviceRefreshData(deviceId, lineCode));
  432 + else
  433 + d64.setErrorText(" 网关通讯失败, code: " + code);
  434 +
  435 + dayOfDirectives.put64(d64);
  436 + return code;
  437 + }
  438 +
  439 + public D60 create60Data(String nbbm, String text, Short dispatchInstruct, ScheduleRealInfo sch) {
  440 +
  441 + String deviceId = BasicData.deviceId2NbbmMap.inverse().get(nbbm);
  442 + String lineCode = null;
  443 + if (null == deviceId) {
  444 + logger.error("没有设备号对照的车辆:" + nbbm);
  445 + return null;
  446 + }
  447 + // 根据当前GPS确定 上下行和营运状态
  448 + Byte upDown = null;
  449 + Integer state = null;
  450 + if (null == sch) {
  451 + GpsEntity gpsData = gpsRealDataBuffer.get(deviceId);
  452 + if (null == gpsData) {
  453 + /*
  454 + * 短语指令不会变更设备状态,所以在没有gps状态对照的情况下可以下发
  455 + * 其他指令在不确定状态的情况下,一律不允许
  456 + */
  457 + if (dispatchInstruct == 0) {
  458 + upDown = 0;
  459 + state = 0;
  460 + } else {
  461 + logger.error("没有找到gps对照,无法确认营运状态和上下行:" + nbbm);
  462 + return null;
  463 + }
  464 + } else {
  465 + upDown = gpsData.getUpDown();
  466 + state = gpsData.getState();
  467 + lineCode = gpsData.getLineId();
  468 + }
  469 + } else {
  470 + upDown = Byte.parseByte(sch.getXlDir());
  471 + state = 0;
  472 + }
  473 +
  474 + return new DirectiveCreator().createD60(nbbm, text, dispatchInstruct, upDown, state, lineCode);
  475 + }
  476 +
  477 +/* @Override
  478 + public int upDownChange(String nbbm, Integer upDown, String sender) {
  479 + return send60Operation(nbbm, 0, upDown, sender);
  480 + }*/
  481 +
  482 +
  483 + @Override
  484 + public Map<String, List<D80>> findNoCofm80(String lineCodes) {
  485 + List<String> lineList = Splitter.on(",").trimResults().splitToList(lineCodes);
  486 +
  487 + Map<String, List<D80>> rs = new HashMap<>();
  488 + for (String code : lineList)
  489 + rs.put(code, pilotReport.unconfirmed80(code));
  490 +
  491 + return rs;
  492 + }
  493 +
  494 + @Override
  495 + public Map<String, Object> reply80(int id, int reply) {
  496 + Map<String, Object> rs = new HashMap<>();
  497 + D80 d80 = pilotReport.findById(id);
  498 + try {
  499 + if (null == d80) {
  500 + rs.put("status", ResponseCode.ERROR);
  501 + rs.put("msg", "服务器没有找到对应数据!");
  502 + } else if (d80.isConfirm()) {
  503 + rs.put("status", ResponseCode.ERROR);
  504 + rs.put("msg", "该数据已经被处理了!");
  505 + } else {
  506 + SysUser user = SecurityUtils.getCurrentUser();
  507 + d80.setC0(reply, user.getUserName());
  508 + // 入库
  509 + d80Repository.save(d80);
  510 + //回复网关
  511 + int code = GatewayHttpUtils.postJson(JSON.toJSONString(d80.getC0()));
  512 +
  513 + rs.put("status", ResponseCode.SUCCESS);
  514 + if (code != 0)
  515 + rs.put("msg", "发送C0响应指令到车载设备失败,但该操作已经被系统记录!");
  516 +
  517 + pilotReport.reply(d80);
  518 +
  519 + // 通知页面
  520 + Map<String, Object> sockMap = new HashMap<>();
  521 + sockMap.put("fn", "d80Confirm");
  522 + sockMap.put("id", d80.getId());
  523 + sockMap.put("lineId", d80.getData().getLineId());
  524 + socketHandler.sendMessageToLine(d80.getData().getLineId().toString(), JSON.toJSONString(sockMap));
  525 + }
  526 + } catch (Exception e) {
  527 + logger.error("80响应出现异常...", e);
  528 + rs.put("status", ResponseCode.SUCCESS);
  529 + }
  530 +
  531 + return rs;
  532 + }
  533 +
  534 + @Override
  535 + public Map<String, Object> findDirective(String nbbms, int dType, int page, int size) {
  536 + Map<String, Object> rsMap = new HashMap<>();
  537 + try{
  538 +
  539 + List<String> carArray = new ArrayList<>(), deviceArray=new ArrayList<>();
  540 + if(StringUtils.isNotEmpty(nbbms)){
  541 + carArray = Splitter.on(",").splitToList(nbbms);
  542 + //转换成设备号
  543 + Map<String, String> nbbm2deviceMap = BasicData.deviceId2NbbmMap.inverse();
  544 + for(int i = 0, len=carArray.size(); i < len; i++){
  545 + deviceArray.add(nbbm2deviceMap.get(carArray.get(i)));
  546 + }
  547 + }
  548 +
  549 + List<Directive> list = new ArrayList<>();
  550 + switch (dType) {
  551 + case -1:
  552 + //所有指令
  553 + list = new ArrayList<>(dayOfDirectives.all());
  554 + break;
  555 + case 0:
  556 + //调度指令
  557 + Collection<D60> dptArray = dayOfDirectives.all60();
  558 + for (D60 d60 : dptArray) {
  559 + if (d60.isDispatch())
  560 + list.add(d60);
  561 + }
  562 + break;
  563 + case 1:
  564 + //运营指令
  565 + Collection<D60> yyArray = dayOfDirectives.all60();
  566 + for (D60 d60 : yyArray) {
  567 + if (d60 != null && d60.getData().getDispatchInstruct() == (short) 0x03
  568 + && !d60.isDispatch())
  569 + list.add(d60);
  570 + }
  571 + break;
  572 + case 2:
  573 + //线路切换指令
  574 + list.addAll(dayOfDirectives.all64());
  575 + break;
  576 + case 3:
  577 + //消息短语
  578 + Collection<D60> dyArray = dayOfDirectives.all60();
  579 + for (D60 d60 : dyArray) {
  580 + if (d60 != null && d60.getData().getDispatchInstruct() == (short) 0x00
  581 + && !d60.isDispatch())
  582 + list.add(d60);
  583 + }
  584 + break;
  585 + }
  586 +
  587 + // 时间倒序
  588 + Collections.sort(list, new DayOfDirectives.DComparator());
  589 + if(deviceArray.size() > 0){
  590 + //按设备号过滤
  591 + List<Directive> subList = new ArrayList<>();
  592 + for (Directive d : list) {
  593 + if (deviceArray.contains(d.getDeviceId())) {
  594 + subList.add(d);
  595 + }
  596 + }
  597 + list = subList;
  598 + }
  599 +
  600 + for(Directive d : list){
  601 + d.setTimeHHmm(fmtHHmm.print(d.getTimestamp()));
  602 + d.setNbbm(BasicData.deviceId2NbbmMap.get(d.getDeviceId()));
  603 + }
  604 +
  605 + int count = list.size();
  606 + // 分页
  607 + int s = page * size, e = s + size;
  608 +
  609 + if (e > count)
  610 + e = count;
  611 +
  612 + List<Directive> rs = list.subList(s, e);
  613 + rsMap.put("list", rs);
  614 + rsMap.put("totalPages", count % size == 0 ? (count / size - 1) : count / size);
  615 + rsMap.put("page", page);
  616 + }catch (Exception e){
  617 + logger.error("", e);
  618 + throw e;
  619 + }
  620 + return rsMap;
  621 + }
  622 +
  623 + @Override
  624 + public Map<String, Object> findAll80(Map<String, Object> map, int page, int size) {
  625 +
  626 + List all = ListFilterUtils.filter(pilotReport.findAll(), map, D80.class);
  627 + //排序
  628 + Collections.sort(all, new Comparator<D80>() {
  629 + @Override
  630 + public int compare(D80 o1, D80 o2) {
  631 + return (int) (o2.getTimestamp() - o1.getTimestamp());
  632 + }
  633 + });
  634 + List<D80> d80s = ListPageQueryUtils.paging(all, page, size);
  635 + //时间格式化
  636 + for (D80 d80 : d80s) {
  637 + d80.setTimeStr(fmtHHmm.print(d80.getTimestamp()));
  638 + }
  639 + Map<String, Object> rsMap = new HashMap<>();
  640 + rsMap.put("list", d80s);
  641 + rsMap.put("totalPages", all.size() % size == 0 ? all.size() / size - 1: all.size() / size);
  642 + rsMap.put("page", page);
  643 + return rsMap;
  644 + }
  645 +
  646 + @Override
  647 + public D64 save64(D64 d64) {
  648 + return d64Repository.save(d64);
  649 + }
  650 +
  651 + @Override
  652 + public Map<String, Object> sendC0A4(String nbbm) {
  653 + Map<String, Object> rs = new HashMap<>();
  654 +
  655 + String deviceId = BasicData.deviceId2NbbmMap.inverse().get(nbbm);
  656 +
  657 + GpsEntity gps = gpsRealDataBuffer.get(deviceId);
  658 + if(gps == null || gps.isOffline()){
  659 + rs.put("status", ResponseCode.ERROR);
  660 + rs.put("msg", "下发指令失败,设备离线");
  661 + return rs;
  662 + }
  663 +
  664 + Map<String, Object> c0a4 = new HashMap<>();
  665 + c0a4.put("deviceId", deviceId);
  666 + c0a4.put("timestamp", System.currentTimeMillis());
  667 + c0a4.put("operCode", (short) 0xC0);
  668 +
  669 + Map<String, Object> data = new HashMap<>();
  670 + data.put("deviceId", deviceId);
  671 + data.put("operCode2", (short) 0xA4);
  672 + c0a4.put("data", data);
  673 +
  674 + int code = GatewayHttpUtils.postJson(JSON.toJSONString(c0a4));
  675 + if(code != 0){
  676 + rs.put("status", ResponseCode.ERROR);
  677 + rs.put("msg", "和网关通讯失败, code " + code);
  678 + }
  679 + else{
  680 + rs.put("status", ResponseCode.SUCCESS);
  681 + }
  682 + return rs;
  683 + }
  684 +
  685 + @Override
  686 + public int sendC0A3(DC0_A3 c0a3) {
  687 + GatewayHttpUtils.postJson(JSON.toJSONString(c0a3));
  688 + return 0;
  689 + }
  690 +
  691 + @Override
  692 + public int sendC0A5(String json) {
  693 + return GatewayHttpUtils.postJson(json);
  694 + }
  695 +
  696 + @Override
  697 + public int refreshLineFile(String deviceId) {
  698 + GpsEntity gps = gpsRealDataBuffer.get(deviceId);
  699 + if (gps == null)
  700 + return -1;
  701 +
  702 + return GatewayHttpUtils.postJson(new DirectiveCreator().createDeviceRefreshData(deviceId, gps.getLineId()));
  703 + }
  704 +
  705 +/* @Override
  706 + public int stateChange(String nbbm, Integer upDown, Integer state, String userName) {
  707 + return send60Operation(nbbm, state, upDown, userName);
  708 + }*/
  709 +
  710 + @Override
  711 + public Map<String, Object> deviceCofigList(Map<String, String> map, int page, int size) {
  712 + Map<String, Object> rs = new HashMap<>();
  713 + try {
  714 + String conts="";
  715 + if(StringUtils.isNotBlank(map.get("lineId"))){
  716 + conts+=" AND xl='" + map.get("lineId")+"'";
  717 + }
  718 + if(StringUtils.isNotBlank(map.get("nbbm"))){
  719 + conts+=" AND inside_code like '%" + map.get("nbbm")+"%'";
  720 + }
  721 + if(StringUtils.isNotBlank(map.get("deviceId"))){
  722 + conts+=" AND equipment_code like '%" + map.get("deviceId")+"%'";
  723 + }
  724 +
  725 + String sql = "select * from (SELECT * FROM (SELECT id AS cl_id,inside_code,equipment_code FROM bsth_c_cars ) t1 LEFT JOIN bsth_v_c0_a4 t2 ON t1.equipment_code = t2.id LEFT JOIN (SELECT xl,cl FROM bsth_c_s_ccinfo WHERE id IN (SELECT max(id) FROM bsth_c_s_ccinfo GROUP BY cl)) t3 ON t1.cl_id = t3.cl ORDER BY t2.`timestamp` DESC) t4 where 1=1 "+conts;
  726 +
  727 + int count = jdbcTemplate.queryForObject("select count(*) from ("+sql+") c1", Integer.class);
  728 + int totalPages = count % size == 0 ? count / size : count / size + 1;
  729 + int s = page * size;
  730 + List<DeviceConfigDto> list = jdbcTemplate.query(sql + " LIMIT " + s + "," + size, new BeanPropertyRowMapper<>(DeviceConfigDto.class));
  731 +
  732 + rs.put("status", ResponseCode.SUCCESS);
  733 + rs.put("list", list);
  734 + rs.put("totalPages", totalPages);
  735 + rs.put("page", page);
  736 + } catch (Exception e) {
  737 + e.printStackTrace();
  738 + logger.error("", e);
  739 + rs.put("status", ResponseCode.ERROR);
  740 + }
  741 + return rs;
  742 + }
  743 +}
src/main/java/com/bsth/service/impl/StationRouteServiceImpl.java
@@ -67,6 +67,11 @@ public class StationRouteServiceImpl extends BaseServiceImpl&lt;StationRoute, Integ @@ -67,6 +67,11 @@ public class StationRouteServiceImpl extends BaseServiceImpl&lt;StationRoute, Integ
67 @Autowired 67 @Autowired
68 private LsSectionRouteRepository lsSectionRouteRepository; 68 private LsSectionRouteRepository lsSectionRouteRepository;
69 69
  70 + @Autowired
  71 + private LineRegionRepository lineRegionRepository;
  72 + @Autowired
  73 + private LineVersionsRepository lineVersionsRepository;
  74 +
70 @Override 75 @Override
71 public Iterable<StationRoute> list(Map<String, Object> map) { 76 public Iterable<StationRoute> list(Map<String, Object> map) {
72 List<Sort.Order> orders = new ArrayList<>(); 77 List<Sort.Order> orders = new ArrayList<>();
@@ -404,10 +409,13 @@ public class StationRouteServiceImpl extends BaseServiceImpl&lt;StationRoute, Integ @@ -404,10 +409,13 @@ public class StationRouteServiceImpl extends BaseServiceImpl&lt;StationRoute, Integ
404 try { 409 try {
405 // 获取线路ID 410 // 获取线路ID
406 Integer lineId = map.get("lineId").equals("") ? 0 : Integer.parseInt(map.get("lineId").toString()); 411 Integer lineId = map.get("lineId").equals("") ? 0 : Integer.parseInt(map.get("lineId").toString());
  412 + Integer version = lineVersionsRepository.findCurrentVersion(lineId);
  413 + Map<String, Object> param = new HashMap<>();
  414 + param.put("line_eq", lineId);
  415 + param.put("version_eq", version);
407 /** 查询线路信息 @param:<lineId:线路ID> */ 416 /** 查询线路信息 @param:<lineId:线路ID> */
408 Line line = lineRepository.findById(lineId).get(); 417 Line line = lineRepository.findById(lineId).get();
409 418
410 -  
411 Business company = businessRepository.findByBusinessCode(line.getCompany()).get(0); 419 Business company = businessRepository.findByBusinessCode(line.getCompany()).get(0);
412 420
413 Integer fileVersions = lineRepository.findfileVersions(lineId); 421 Integer fileVersions = lineRepository.findfileVersions(lineId);
@@ -421,6 +429,7 @@ public class StationRouteServiceImpl extends BaseServiceImpl&lt;StationRoute, Integ @@ -421,6 +429,7 @@ public class StationRouteServiceImpl extends BaseServiceImpl&lt;StationRoute, Integ
421 // Integer fileVersions = map.get("fileVersions").equals("") ? 1 : Integer.parseInt(map.get("fileVersions").toString());// 没有输入就默认1 429 // Integer fileVersions = map.get("fileVersions").equals("") ? 1 : Integer.parseInt(map.get("fileVersions").toString());// 没有输入就默认1
422 /** 查询线路信息下的站点路由信息 @param:<lineId:线路ID> */ 430 /** 查询线路信息下的站点路由信息 @param:<lineId:线路ID> */
423 List<Object[]> objects = stationRouteRepository.usingSingle(lineId); 431 List<Object[]> objects = stationRouteRepository.usingSingle(lineId);
  432 + List<LineRegion> lineRegions = lineRegionRepository.findAll(new CustomerSpecs<>(param));
424 if (objects.size()>0) { 433 if (objects.size()>0) {
425 /** 获取配置文件里的ftp登录参数 */ 434 /** 获取配置文件里的ftp登录参数 */
426 Map<String, Object> FTPParamMap = readPropertiesGetFTPParam(); 435 Map<String, Object> FTPParamMap = readPropertiesGetFTPParam();
@@ -489,7 +498,14 @@ public class StationRouteServiceImpl extends BaseServiceImpl&lt;StationRoute, Integ @@ -489,7 +498,14 @@ public class StationRouteServiceImpl extends BaseServiceImpl&lt;StationRoute, Integ
489 clientUtils.uploadFile(url, port, username, password, remotePath + "/voice/", textFileName, input); 498 clientUtils.uploadFile(url, port, username, password, remotePath + "/voice/", textFileName, input);
490 499
491 // textFile.delete(); 500 // textFile.delete();
492 - 501 + if (lineRegions.size() > 0) {
  502 + FTPClientUtils.deleteFileByPrefix(String.format("%s-", line.getLineCode()), url, port, username, password, String.format("%s/voice/", remotePath));
  503 + for (LineRegion lineRegion : lineRegions) {
  504 + textStr = String.format("%s\r\n%s", head, subLine2Ftp(lineRegion));
  505 + input = new ByteArrayInputStream(textStr.getBytes("gbk"));
  506 + clientUtils.uploadFile(url, port, username, password, remotePath + "/voice/", String.format("%s-%d.txt", line.getLineCode(), lineRegion.getSeq()), input);
  507 + }
  508 + }
493 509
494 resultMap.put("status", ResponseCode.SUCCESS); 510 resultMap.put("status", ResponseCode.SUCCESS);
495 }else { 511 }else {
@@ -1001,4 +1017,30 @@ public class StationRouteServiceImpl extends BaseServiceImpl&lt;StationRoute, Integ @@ -1001,4 +1017,30 @@ public class StationRouteServiceImpl extends BaseServiceImpl&lt;StationRoute, Integ
1001 } 1017 }
1002 } 1018 }
1003 } 1019 }
  1020 +
  1021 + private String subLine2Ftp(LineRegion lineRegion) {
  1022 + StringBuilder builder = new StringBuilder();
  1023 + int len = lineRegion.getStationRoutes().size();
  1024 + int idx = 1;
  1025 + for (int i = 0;i < len;i++) {
  1026 + LsStationRoute route = lineRegion.getStationRoutes().get(i);
  1027 + builder.append(route.getCenterPointWgs().getPosition().getCoordinate(0))
  1028 + .append("\t").append(route.getCenterPointWgs().getPosition().getCoordinate(1))
  1029 + .append("\t").append(i == len - 1 ? 2 : 1)
  1030 + .append("\t").append(idx).append("\t");
  1031 + for (int j = 0;j < 8 - route.getStationCode().length();j++) {
  1032 + builder.append("0");
  1033 + }
  1034 + builder.append(route.getStationCode())
  1035 + .append("\t").append((int) route.getDistances().doubleValue() * 1000)
  1036 + .append("\t0")
  1037 + .append("\t").append(route.getStationName())
  1038 + .append("\t").append(route.getStationNameEn())
  1039 + .append("\r\n");
  1040 +
  1041 + idx++;
  1042 + }
  1043 +
  1044 + return builder.toString();
  1045 + }
1004 } 1046 }
src/main/java/com/bsth/util/FTPClientUtils.java
1 -package com.bsth.util;  
2 -  
3 -import java.io.ByteArrayInputStream;  
4 -import java.io.File;  
5 -import java.io.FileInputStream;  
6 -import java.io.FileNotFoundException;  
7 -import java.io.FileOutputStream;  
8 -import java.io.IOException;  
9 -import java.io.InputStream;  
10 -import java.io.OutputStream;  
11 -import java.io.UnsupportedEncodingException;  
12 -  
13 -import org.apache.commons.net.ftp.FTPClient;  
14 -import org.apache.commons.net.ftp.FTPFile;  
15 -import org.apache.commons.net.ftp.FTPReply;  
16 -/**  
17 - * @Description: 向FTP服务器上传文件  
18 - *  
19 - * @Version 1.0 2016-06-21 4:31:09 by 李强  
20 - *  
21 - */  
22 -public class FTPClientUtils {  
23 -  
24 - /**  
25 - * @param url FTP服务器hostname;  
26 - *  
27 - * - - - - port FTP服务器端口;  
28 - *  
29 - * - - - - username FTP登录账号;  
30 - *  
31 - * - - - - password FTP登录密码 ;  
32 - *  
33 - * - - - - path FTP服务器保存目录;  
34 - *  
35 - * - - - - filename 上传到FTP服务器上的文件名  
36 - *  
37 - * - - - - input 输入流;  
38 - *  
39 - * @return 成功返回true,否则返回false  
40 - *  
41 - */  
42 - public boolean uploadFile(String url,int port,String username, String password, String path, String filename, InputStream input) {  
43 -  
44 - boolean success = false;  
45 -  
46 - FTPClient ftp = new FTPClient();  
47 -  
48 - try {  
49 -  
50 - int reply;  
51 -  
52 - //连接FTP服务器,如果采用默认端口,可以使用ftp.connect(url)的方式直接连接FTP服务器  
53 - ftp.connect(url, port);  
54 -  
55 - //登录  
56 - ftp.login(username, password);  
57 -  
58 - reply = ftp.getReplyCode();  
59 -  
60 - if (!FTPReply.isPositiveCompletion(reply)) {  
61 -  
62 - ftp.disconnect();  
63 -  
64 - return success;  
65 -  
66 - }  
67 -  
68 - ftp.changeWorkingDirectory(path);  
69 - ftp.setFileType(FTPClient.BINARY_FILE_TYPE);  
70 - ftp.enterLocalPassiveMode();  
71 - success = ftp.storeFile(new String(filename.getBytes("gbk"),"gbk"), input);  
72 - /*success = ftp.storeFile(filename, input); */  
73 - input.close();  
74 -  
75 - ftp.logout();  
76 -  
77 - // success = true;  
78 -  
79 - } catch (IOException e) {  
80 -  
81 - e.printStackTrace();  
82 -  
83 - } finally {  
84 -  
85 - if (ftp.isConnected()) {  
86 -  
87 - try {  
88 -  
89 - ftp.disconnect();  
90 -  
91 - } catch (IOException ioe) {  
92 -  
93 - }  
94 -  
95 - }  
96 -  
97 - }  
98 -  
99 - return success;  
100 - }  
101 -  
102 - /**  
103 - * @Description : TOOD(将本地文件上传到FTP服务器上)  
104 - *  
105 - * @param file  
106 - *  
107 - * @param name  
108 - *  
109 - * @param url  
110 - *  
111 - * @param port  
112 - *  
113 - * @param username  
114 - *  
115 - * @param password  
116 - *  
117 - * @param remotePath  
118 - *  
119 - */  
120 - public void FTPUpLoadFromDisk(File file,String name,String url, int port, String username, String password, String remotePath){  
121 -  
122 - try {  
123 - FileInputStream in=new FileInputStream(file);  
124 -  
125 - boolean flag = uploadFile(url, port,username, password, remotePath, name, in);  
126 -  
127 - /* boolean flag = uploadFile("192.168.168.101", 21, "testftpservice", "123", "ftptest/", name, in);*/  
128 -  
129 - /* boolean flag = uploadFile("222.66.0.205", 21, "transport", "transport123", "ftptest/", name, in);*/  
130 -  
131 - } catch (FileNotFoundException e) {  
132 -  
133 - e.printStackTrace();  
134 -  
135 - }  
136 -  
137 - }  
138 -  
139 - // 在FTP服务器上生成一个文件,并将一个字符串写入到该文件中  
140 - public void testUpLoadFromString(){  
141 -  
142 - try {  
143 -  
144 - String str = "test ftp "+ "\r\n"+ "ccccc dddd";  
145 -  
146 - InputStream input = new ByteArrayInputStream(str.getBytes("utf-8"));  
147 -  
148 - uploadFile("192.168.168.101", 21, "testftpservice", "123", "ftptest/", "test.txt", input);  
149 -  
150 - } catch (UnsupportedEncodingException e) {  
151 -  
152 - e.printStackTrace();  
153 -  
154 - }  
155 -  
156 - }  
157 -  
158 - /**  
159 - * @Description (删除FTP上的文件)  
160 - *  
161 - * @param url FTP服务器IP地址  
162 - *  
163 - * @param port FTP服务器端口  
164 - *  
165 - * @param username FTP服务器登录名  
166 - *  
167 - * @param password FTP服务器密码  
168 - *  
169 - * @param remotePath 远程文件路径  
170 - *  
171 - * @param fileName 待删除的文件名  
172 - *  
173 - * @return boolean  
174 - */  
175 - public static boolean deleteFtpFile(String url, int port, String username, String password, String remotePath, String fileName){  
176 -  
177 - boolean success = false;  
178 -  
179 - FTPClient ftp = new FTPClient();  
180 -  
181 - try {  
182 -  
183 - int reply;  
184 -  
185 - // 连接FTP服务器  
186 - if (port > -1)  
187 -  
188 - ftp.connect(url, port);  
189 -  
190 - else  
191 -  
192 - ftp.connect(url);  
193 -  
194 - // 登录  
195 - ftp.login(username, password);  
196 -  
197 - reply = ftp.getReplyCode();  
198 -  
199 - if (!FTPReply.isPositiveCompletion(reply)) {  
200 -  
201 - ftp.disconnect();  
202 -  
203 - return success;  
204 - }  
205 -  
206 - // 转移到FTP服务器目录  
207 -  
208 - ftp.changeWorkingDirectory(remotePath);  
209 -  
210 - /*success = ftp.deleteFile(fileName);*/  
211 -  
212 - success = ftp.deleteFile(new String(fileName.getBytes("gbk"),"gbk"));  
213 -  
214 - ftp.logout();  
215 -  
216 - } catch (IOException e){  
217 -  
218 - e.printStackTrace();  
219 -  
220 - success = false;  
221 -  
222 - } finally {  
223 -  
224 - if (ftp.isConnected()) {  
225 -  
226 - try {  
227 -  
228 - ftp.disconnect();  
229 -  
230 - } catch (IOException e) {  
231 -  
232 - e.printStackTrace();  
233 -  
234 - }  
235 - }  
236 - }  
237 -  
238 - return success;  
239 - }  
240 -  
241 - public static File GetFtpFile(String url, int port, String username, String password, String remotePath, String fileName){  
242 -  
243 - FTPClient ftp = new FTPClient();  
244 -  
245 - /*File destFile = new File(fileName); */  
246 -  
247 - File destFile = new File(fileName);  
248 -  
249 - InputStream in = null;  
250 -  
251 - OutputStream out = null;  
252 -  
253 - try {  
254 -  
255 - int reply;  
256 -  
257 - // 连接FTP服务器  
258 - if (port > -1)  
259 -  
260 - ftp.connect(url, port);  
261 -  
262 - else  
263 -  
264 - ftp.connect(url);  
265 -  
266 - // 登录  
267 - ftp.login(username, password);  
268 -  
269 - reply = ftp.getReplyCode();  
270 -  
271 - if (!FTPReply.isPositiveCompletion(reply)) {  
272 -  
273 - ftp.disconnect();  
274 -  
275 - }  
276 -  
277 - // 转移到FTP服务器目录  
278 -  
279 - ftp.changeWorkingDirectory(remotePath);  
280 -  
281 - ftp.enterLocalPassiveMode();  
282 -  
283 - FTPFile[] fs = ftp.listFiles();  
284 -  
285 - System.out.println(fs.length);  
286 -  
287 - /* for (FTPFile ff : fs) {  
288 - //解决中文乱码问题,两次解码  
289 - byte[] bytes=ff.getName().getBytes("gbk");  
290 - String fn=new String(bytes,"gbk");  
291 - if (fn.equals(fileName)) {  
292 - //6.写操作,将其写入到本地文件中  
293 - File localFile = new File(ff.getName());  
294 -  
295 -  
296 - OutputStream is = new FileOutputStream(localFile);  
297 - ftp.retrieveFile(ff.getName(), is);  
298 - is.close();  
299 - }  
300 - } */  
301 -  
302 - /* File srcFile = new File(fileName); */  
303 -  
304 - /* File srcFile = new File(new String(fileName.getBytes("gbk"),"gbk"));*/  
305 -  
306 - int byteread = 0; // 读取的字节数  
307 -  
308 - /* in = ftp.retrieveFileStream(remotePath + fileName);*/  
309 -  
310 - in = ftp.retrieveFileStream(new String(fileName.getBytes("gbk"),"gbk"));  
311 -  
312 -  
313 - out = new FileOutputStream(destFile);  
314 -  
315 - byte[] buffer = new byte[1024];  
316 -  
317 - while ((byteread = in.read(buffer)) != -1) {  
318 -  
319 - out.write(buffer, 0, byteread);  
320 -  
321 - }  
322 -  
323 - out.flush();  
324 - ftp.logout();  
325 -  
326 - } catch (IOException e){  
327 -  
328 - e.printStackTrace();  
329 -  
330 - } finally {  
331 -  
332 - try {  
333 -  
334 - if (out != null)  
335 -  
336 - out.close();  
337 -  
338 - if (in != null)  
339 -  
340 - in.close();  
341 -  
342 - } catch (IOException e) {  
343 -  
344 - e.printStackTrace();  
345 -  
346 - }  
347 -  
348 - if (ftp.isConnected()) {  
349 -  
350 - try {  
351 -  
352 - ftp.disconnect();  
353 -  
354 - } catch (IOException e) {  
355 -  
356 - e.printStackTrace();  
357 -  
358 - }  
359 - }  
360 - }  
361 -  
362 - return destFile;  
363 - }  
364 -  
365 -  
366 - public static void main(String[] args) {  
367 -  
368 - FTPClientUtils clientUtils = new FTPClientUtils();  
369 -  
370 - Test test= new Test();  
371 -  
372 - File[] sources = new File[] {new File("E:/20079.txt")};  
373 -  
374 - File target = new File("release_package.tar.gz");  
375 -  
376 - File targetFile = test.pack(sources, target);  
377 -  
378 - /* clientUtils.testUpLoadFromDisk(targetFile,targetFile.getName());*/  
379 -  
380 -  
381 - /** 删除文件 */  
382 - /*boolean a =clientUtils.deleteFtpFile("192.168.168.101", 21, "testftpservice", "123", "ftptest/", "release_package.tar.gz");*/  
383 -  
384 - }  
385 -} 1 +package com.bsth.util;
  2 +
  3 +import java.io.ByteArrayInputStream;
  4 +import java.io.File;
  5 +import java.io.FileInputStream;
  6 +import java.io.FileNotFoundException;
  7 +import java.io.FileOutputStream;
  8 +import java.io.IOException;
  9 +import java.io.InputStream;
  10 +import java.io.OutputStream;
  11 +import java.io.UnsupportedEncodingException;
  12 +
  13 +import org.apache.commons.net.ftp.FTPClient;
  14 +import org.apache.commons.net.ftp.FTPFile;
  15 +import org.apache.commons.net.ftp.FTPReply;
  16 +/**
  17 + * @Description: 向FTP服务器上传文件
  18 + *
  19 + * @Version 1.0 2016-06-21 4:31:09 by 李强
  20 + *
  21 + */
  22 +public class FTPClientUtils {
  23 +
  24 + /**
  25 + * @param url FTP服务器hostname;
  26 + *
  27 + * - - - - port FTP服务器端口;
  28 + *
  29 + * - - - - username FTP登录账号;
  30 + *
  31 + * - - - - password FTP登录密码 ;
  32 + *
  33 + * - - - - path FTP服务器保存目录;
  34 + *
  35 + * - - - - filename 上传到FTP服务器上的文件名
  36 + *
  37 + * - - - - input 输入流;
  38 + *
  39 + * @return 成功返回true,否则返回false
  40 + *
  41 + */
  42 + public boolean uploadFile(String url,int port,String username, String password, String path, String filename, InputStream input) {
  43 +
  44 + boolean success = false;
  45 +
  46 + FTPClient ftp = new FTPClient();
  47 +
  48 + try {
  49 +
  50 + int reply;
  51 +
  52 + //连接FTP服务器,如果采用默认端口,可以使用ftp.connect(url)的方式直接连接FTP服务器
  53 + ftp.connect(url, port);
  54 +
  55 + //登录
  56 + ftp.login(username, password);
  57 +
  58 + reply = ftp.getReplyCode();
  59 +
  60 + if (!FTPReply.isPositiveCompletion(reply)) {
  61 +
  62 + ftp.disconnect();
  63 +
  64 + return success;
  65 +
  66 + }
  67 +
  68 + ftp.changeWorkingDirectory(path);
  69 + ftp.setFileType(FTPClient.BINARY_FILE_TYPE);
  70 + ftp.enterLocalPassiveMode();
  71 + success = ftp.storeFile(new String(filename.getBytes("gbk"),"gbk"), input);
  72 + /*success = ftp.storeFile(filename, input); */
  73 + input.close();
  74 +
  75 + ftp.logout();
  76 +
  77 + // success = true;
  78 +
  79 + } catch (IOException e) {
  80 +
  81 + e.printStackTrace();
  82 +
  83 + } finally {
  84 +
  85 + if (ftp.isConnected()) {
  86 +
  87 + try {
  88 +
  89 + ftp.disconnect();
  90 +
  91 + } catch (IOException ioe) {
  92 +
  93 + }
  94 +
  95 + }
  96 +
  97 + }
  98 +
  99 + return success;
  100 + }
  101 +
  102 + /**
  103 + * @Description : TOOD(将本地文件上传到FTP服务器上)
  104 + *
  105 + * @param file
  106 + *
  107 + * @param name
  108 + *
  109 + * @param url
  110 + *
  111 + * @param port
  112 + *
  113 + * @param username
  114 + *
  115 + * @param password
  116 + *
  117 + * @param remotePath
  118 + *
  119 + */
  120 + public void FTPUpLoadFromDisk(File file,String name,String url, int port, String username, String password, String remotePath){
  121 +
  122 + try {
  123 + FileInputStream in=new FileInputStream(file);
  124 +
  125 + boolean flag = uploadFile(url, port,username, password, remotePath, name, in);
  126 +
  127 + /* boolean flag = uploadFile("192.168.168.101", 21, "testftpservice", "123", "ftptest/", name, in);*/
  128 +
  129 + /* boolean flag = uploadFile("222.66.0.205", 21, "transport", "transport123", "ftptest/", name, in);*/
  130 +
  131 + } catch (FileNotFoundException e) {
  132 +
  133 + e.printStackTrace();
  134 +
  135 + }
  136 +
  137 + }
  138 +
  139 + // 在FTP服务器上生成一个文件,并将一个字符串写入到该文件中
  140 + public void testUpLoadFromString(){
  141 +
  142 + try {
  143 +
  144 + String str = "test ftp "+ "\r\n"+ "ccccc dddd";
  145 +
  146 + InputStream input = new ByteArrayInputStream(str.getBytes("utf-8"));
  147 +
  148 + uploadFile("192.168.168.101", 21, "testftpservice", "123", "ftptest/", "test.txt", input);
  149 +
  150 + } catch (UnsupportedEncodingException e) {
  151 +
  152 + e.printStackTrace();
  153 +
  154 + }
  155 +
  156 + }
  157 +
  158 + /**
  159 + * @Description (删除FTP上的文件)
  160 + *
  161 + * @param url FTP服务器IP地址
  162 + *
  163 + * @param port FTP服务器端口
  164 + *
  165 + * @param username FTP服务器登录名
  166 + *
  167 + * @param password FTP服务器密码
  168 + *
  169 + * @param remotePath 远程文件路径
  170 + *
  171 + * @param fileName 待删除的文件名
  172 + *
  173 + * @return boolean
  174 + */
  175 + public static boolean deleteFtpFile(String url, int port, String username, String password, String remotePath, String fileName){
  176 +
  177 + boolean success = false;
  178 +
  179 + FTPClient ftp = new FTPClient();
  180 +
  181 + try {
  182 +
  183 + int reply;
  184 +
  185 + // 连接FTP服务器
  186 + if (port > -1)
  187 +
  188 + ftp.connect(url, port);
  189 +
  190 + else
  191 +
  192 + ftp.connect(url);
  193 +
  194 + // 登录
  195 + ftp.login(username, password);
  196 +
  197 + reply = ftp.getReplyCode();
  198 +
  199 + if (!FTPReply.isPositiveCompletion(reply)) {
  200 +
  201 + ftp.disconnect();
  202 +
  203 + return success;
  204 + }
  205 +
  206 + // 转移到FTP服务器目录
  207 +
  208 + ftp.changeWorkingDirectory(remotePath);
  209 +
  210 + /*success = ftp.deleteFile(fileName);*/
  211 +
  212 + success = ftp.deleteFile(new String(fileName.getBytes("gbk"),"gbk"));
  213 +
  214 + ftp.logout();
  215 +
  216 + } catch (IOException e){
  217 +
  218 + e.printStackTrace();
  219 +
  220 + success = false;
  221 +
  222 + } finally {
  223 +
  224 + if (ftp.isConnected()) {
  225 +
  226 + try {
  227 +
  228 + ftp.disconnect();
  229 +
  230 + } catch (IOException e) {
  231 +
  232 + e.printStackTrace();
  233 +
  234 + }
  235 + }
  236 + }
  237 +
  238 + return success;
  239 + }
  240 +
  241 + public static File GetFtpFile(String url, int port, String username, String password, String remotePath, String fileName){
  242 +
  243 + FTPClient ftp = new FTPClient();
  244 +
  245 + /*File destFile = new File(fileName); */
  246 +
  247 + File destFile = new File(fileName);
  248 +
  249 + InputStream in = null;
  250 +
  251 + OutputStream out = null;
  252 +
  253 + try {
  254 +
  255 + int reply;
  256 +
  257 + // 连接FTP服务器
  258 + if (port > -1)
  259 +
  260 + ftp.connect(url, port);
  261 +
  262 + else
  263 +
  264 + ftp.connect(url);
  265 +
  266 + // 登录
  267 + ftp.login(username, password);
  268 +
  269 + reply = ftp.getReplyCode();
  270 +
  271 + if (!FTPReply.isPositiveCompletion(reply)) {
  272 +
  273 + ftp.disconnect();
  274 +
  275 + }
  276 +
  277 + // 转移到FTP服务器目录
  278 +
  279 + ftp.changeWorkingDirectory(remotePath);
  280 +
  281 + ftp.enterLocalPassiveMode();
  282 +
  283 + FTPFile[] fs = ftp.listFiles();
  284 +
  285 + System.out.println(fs.length);
  286 +
  287 + /* for (FTPFile ff : fs) {
  288 + //解决中文乱码问题,两次解码
  289 + byte[] bytes=ff.getName().getBytes("gbk");
  290 + String fn=new String(bytes,"gbk");
  291 + if (fn.equals(fileName)) {
  292 + //6.写操作,将其写入到本地文件中
  293 + File localFile = new File(ff.getName());
  294 +
  295 +
  296 + OutputStream is = new FileOutputStream(localFile);
  297 + ftp.retrieveFile(ff.getName(), is);
  298 + is.close();
  299 + }
  300 + } */
  301 +
  302 + /* File srcFile = new File(fileName); */
  303 +
  304 + /* File srcFile = new File(new String(fileName.getBytes("gbk"),"gbk"));*/
  305 +
  306 + int byteread = 0; // 读取的字节数
  307 +
  308 + /* in = ftp.retrieveFileStream(remotePath + fileName);*/
  309 +
  310 + in = ftp.retrieveFileStream(new String(fileName.getBytes("gbk"),"gbk"));
  311 +
  312 +
  313 + out = new FileOutputStream(destFile);
  314 +
  315 + byte[] buffer = new byte[1024];
  316 +
  317 + while ((byteread = in.read(buffer)) != -1) {
  318 +
  319 + out.write(buffer, 0, byteread);
  320 +
  321 + }
  322 +
  323 + out.flush();
  324 + ftp.logout();
  325 +
  326 + } catch (IOException e){
  327 +
  328 + e.printStackTrace();
  329 +
  330 + } finally {
  331 +
  332 + try {
  333 +
  334 + if (out != null)
  335 +
  336 + out.close();
  337 +
  338 + if (in != null)
  339 +
  340 + in.close();
  341 +
  342 + } catch (IOException e) {
  343 +
  344 + e.printStackTrace();
  345 +
  346 + }
  347 +
  348 + if (ftp.isConnected()) {
  349 +
  350 + try {
  351 +
  352 + ftp.disconnect();
  353 +
  354 + } catch (IOException e) {
  355 +
  356 + e.printStackTrace();
  357 +
  358 + }
  359 + }
  360 + }
  361 +
  362 + return destFile;
  363 + }
  364 +
  365 + public static boolean deleteFileByPrefix(String prefix, String url, int port, String username, String password, String remotePath) {
  366 + boolean flag = false;
  367 + FTPClient ftp = new FTPClient();
  368 + try {
  369 + int reply;
  370 + if (port > -1) {
  371 + ftp.connect(url, port);
  372 + } else {
  373 + ftp.connect(url);
  374 + }
  375 + ftp.login(username, password);
  376 + reply = ftp.getReplyCode();
  377 + if (!FTPReply.isPositiveCompletion(reply)) {
  378 + ftp.disconnect();
  379 + return flag;
  380 + }
  381 + ftp.enterLocalPassiveMode();
  382 + ftp.changeWorkingDirectory(remotePath);
  383 + for (FTPFile file : ftp.listFiles()) {
  384 + if (file.getName().startsWith(prefix)) {
  385 + ftp.deleteFile(file.getName());
  386 + }
  387 + }
  388 + ftp.logout();
  389 + } catch (IOException e){
  390 + e.printStackTrace();
  391 + } finally {
  392 + if (ftp.isConnected()) {
  393 + try {
  394 + ftp.disconnect();
  395 + } catch (IOException e) {
  396 + e.printStackTrace();
  397 + }
  398 + }
  399 + }
  400 +
  401 + return flag;
  402 + }
  403 +
  404 +
  405 + public static void main(String[] args) {
  406 +
  407 +// FTPClientUtils clientUtils = new FTPClientUtils();
  408 +//
  409 +// Test test= new Test();
  410 +//
  411 +// File[] sources = new File[] {new File("E:/20079.txt")};
  412 +//
  413 +// File target = new File("release_package.tar.gz");
  414 +//
  415 +// File targetFile = test.pack(sources, target);
  416 +
  417 + /* clientUtils.testUpLoadFromDisk(targetFile,targetFile.getName());*/
  418 +
  419 +
  420 + /** 删除文件 */
  421 + /*boolean a =clientUtils.deleteFtpFile("192.168.168.101", 21, "testftpservice", "123", "ftptest/", "release_package.tar.gz");*/
  422 + FTPClientUtils.deleteFileByPrefix("100", "61.169.120.202", 10021, "ftpadmin", "ftp@123", "/transport/down/voice/");
  423 + }
  424 +}
src/main/resources/datatools/config-test.properties
@@ -15,13 +15,13 @@ datatools.kvars_dbdname=lg_control @@ -15,13 +15,13 @@ datatools.kvars_dbdname=lg_control
15 15
16 # 3、上传数据配置信息 16 # 3、上传数据配置信息
17 # 上传文件目录配置(根据不同的环境需要修正) 17 # 上传文件目录配置(根据不同的环境需要修正)
18 -datatools.fileupload_dir=/Users/xu/resource/project_code/runtime_temp/bsth_control_u_d_files 18 +datatools.fileupload_dir=/home/bsth_control_u_d_files
19 # ktr转换文件,中配置的错误输出目录(根据不同的环境需要修正) 19 # ktr转换文件,中配置的错误输出目录(根据不同的环境需要修正)
20 -datatools.trans_errordir=/Users/xu/resource/project_code/runtime_temp/bsth_control_u_d_files/erroroutput 20 +datatools.trans_errordir=/home/bsth_control_u_d_files/erroroutput
21 # 临时输出文件目录 21 # 临时输出文件目录
22 -datatools.trans_tempdir=/Users/xu/resource/project_code/runtime_temp/bsth_control_u_d_files/temp 22 +datatools.trans_tempdir=/home/bsth_control_u_d_files/temp
23 # 模版文件目录 23 # 模版文件目录
24 -datatools.trans_templatedir=/Users/xu/resource/project_code/runtime_temp/bsth_control_u_d_files/template 24 +datatools.trans_templatedir=/home/bsth_control_u_d_files/template
25 25
26 ##---------------------------- 导入数据ktr ----------------------------## 26 ##---------------------------- 导入数据ktr ----------------------------##
27 # 车辆信息导入ktr转换 27 # 车辆信息导入ktr转换
@@ -57,7 +57,7 @@ datatools.schedulerule_datainputktr=/datatools/ktrs/scheduleRuleDataInput.ktr @@ -57,7 +57,7 @@ datatools.schedulerule_datainputktr=/datatools/ktrs/scheduleRuleDataInput.ktr
57 57
58 # 4、数据导出配置信息 58 # 4、数据导出配置信息
59 # 导出数据文件目录配置(根据不同的环境需要修正) 59 # 导出数据文件目录配置(根据不同的环境需要修正)
60 -datatools.fileoutput_dir=/Users/xu/resource/project_code/runtime_temp/bsth_control_u_d_files 60 +datatools.fileoutput_dir=/home/bsth_control_u_d_files
61 61
62 ##---------------------------- 导出数据ktr -----------------------------## 62 ##---------------------------- 导出数据ktr -----------------------------##
63 # 车辆信息导出ktr转换 63 # 车辆信息导出ktr转换
src/main/resources/ftp.properties
1 -ftp.url=116.236.238.212  
2 -ftp.port=21  
3 -ftp.username=transport  
4 -ftp.password=transport123  
5 -ftp.path=down/  
6 -  
7 -#ftp.url=192.168.168.101  
8 -#ftp.port=21  
9 -#ftp.username=testftpservice  
10 -#ftp.password= 123 1 +ftp.url=116.236.238.212
  2 +ftp.port=21
  3 +ftp.username=transport
  4 +ftp.password=transport123
  5 +ftp.path=/transport/down/
  6 +
  7 +#ftp.url=192.168.168.101
  8 +#ftp.port=21
  9 +#ftp.username=testftpservice
  10 +#ftp.password= 123
11 #ftp.path= ftptest/ 11 #ftp.path= ftptest/
12 \ No newline at end of file 12 \ No newline at end of file
src/main/resources/static/index.html
@@ -659,5 +659,9 @@ @@ -659,5 +659,9 @@
659 <!-- RSA加密 --> 659 <!-- RSA加密 -->
660 <script src="/assets/plugins/jsencrypt.min.js"></script> 660 <script src="/assets/plugins/jsencrypt.min.js"></script>
661 <script src="/assets/js/eventproxy.js"></script> 661 <script src="/assets/js/eventproxy.js"></script>
  662 +<!-- 线路路由信息操作 -->
  663 +<script src="/pages/base/stationroute/js/routes-operation.js"></script>
  664 +<script src="/pages/base/stationroute/js/routes-service.js"></script>
  665 +<script src="/assets/js/CoordinateConverter.js"></script>
662 </body> 666 </body>
663 </html> 667 </html>
664 \ No newline at end of file 668 \ No newline at end of file
src/main/resources/static/pages/base/stationroute/add_line_region.html
@@ -205,8 +205,12 @@ @@ -205,8 +205,12 @@
205 } 205 }
206 206
207 function left2right() { 207 function left2right() {
  208 + var idx = $(this).data('idx'), last = $('#right .table-body dl').last();
  209 + if (last && last.data('idx') > idx) {
  210 + layer.msg('请注意站序');
  211 + return;
  212 + }
208 $(this).remove(); 213 $(this).remove();
209 - var idx = $(this).data('idx');  
210 $('#right .table-body').append($(this).prop('outerHTML')); 214 $('#right .table-body').append($(this).prop('outerHTML'));
211 $('#right .table-body dl[data-idx=' + idx + ']').on('click', right2left); 215 $('#right .table-body dl[data-idx=' + idx + ']').on('click', right2left);
212 $('#left .table-body').perfectScrollbar("update"); 216 $('#left .table-body').perfectScrollbar("update");
src/main/resources/static/pages/base/stationroute/js/routes-operation.js
@@ -140,8 +140,10 @@ var RoutesOperation = (function () { @@ -140,8 +140,10 @@ var RoutesOperation = (function () {
140 140
141 if (status > 0) { 141 if (status > 0) {
142 $(".table-toolbar").show(); 142 $(".table-toolbar").show();
  143 + $('.region-btn-group').show();
143 } else { 144 } else {
144 $(".table-toolbar").hide(); 145 $(".table-toolbar").hide();
  146 + $('.region-btn-group').hide();
145 } 147 }
146 }) 148 })
147 149
@@ -2162,7 +2164,7 @@ var RoutesOperation = (function () { @@ -2162,7 +2164,7 @@ var RoutesOperation = (function () {
2162 $('#inout_carpark_tree').show(); 2164 $('#inout_carpark_tree').show();
2163 $('#InoutCarparktreeMobal .table-toolbar').show(); 2165 $('#InoutCarparktreeMobal .table-toolbar').show();
2164 2166
2165 - RoutesService.getRouteByStartEnd(id, version, start[0], end[0], (result1) => { 2167 + RoutesService.getRouteByStartEnd(id, version, start[0], end[0], function (result1) {
2166 var routes = result1.data.routes, rootNode; 2168 var routes = result1.data.routes, rootNode;
2167 operation.clearMarkAndOverlays(); 2169 operation.clearMarkAndOverlays();
2168 var startPoint = name2Point[start.join('_')], endPoint = name2Point[end.join('_')], point, points; 2170 var startPoint = name2Point[start.join('_')], endPoint = name2Point[end.join('_')], point, points;
@@ -2541,6 +2543,8 @@ var RoutesOperation = (function () { @@ -2541,6 +2543,8 @@ var RoutesOperation = (function () {
2541 loadLineRegion: function() { 2543 loadLineRegion: function() {
2542 RoutesService.findLineRegion(lineId, versions, function(res) { 2544 RoutesService.findLineRegion(lineId, versions, function(res) {
2543 lineRegions = res; 2545 lineRegions = res;
  2546 + $('#regionSelect').html('');
  2547 + $('#region-station-body-table').html('');
2544 var html = []; 2548 var html = [];
2545 if (lineRegions.length > 0) { 2549 if (lineRegions.length > 0) {
2546 lineRegions.forEach(function (item, idx) { 2550 lineRegions.forEach(function (item, idx) {
@@ -2825,5 +2829,3 @@ var RoutesOperation = (function () { @@ -2825,5 +2829,3 @@ var RoutesOperation = (function () {
2825 2829
2826 return operation; 2830 return operation;
2827 })() 2831 })()
2828 -  
2829 -proxy.emit('routes-operation-loaded');  
src/main/resources/static/pages/base/stationroute/js/routes-service.js
@@ -414,6 +414,4 @@ var RoutesService = (function(){ @@ -414,6 +414,4 @@ var RoutesService = (function(){
414 }; 414 };
415 415
416 return service; 416 return service;
417 -})();  
418 -  
419 -proxy.emit('routes-service-loaded');  
420 \ No newline at end of file 417 \ No newline at end of file
  418 +})();
421 \ No newline at end of file 419 \ No newline at end of file
src/main/resources/static/pages/base/stationroute/list.html
@@ -94,9 +94,9 @@ @@ -94,9 +94,9 @@
94 <!--<li class=""> 94 <!--<li class="">
95 <a href="#inoutCarpark" data-toggle="tab" id="inoutLine" aria-expanded="false"> 进出场路径 </a> 95 <a href="#inoutCarpark" data-toggle="tab" id="inoutLine" aria-expanded="false"> 进出场路径 </a>
96 </li>--> 96 </li>-->
97 - <!--<li class=""> 97 + <li class="">
98 <a href="#regionDesignTab" data-toggle="tab" id="regionDesign" aria-expanded="false"> 线路区间规划 </a> 98 <a href="#regionDesignTab" data-toggle="tab" id="regionDesign" aria-expanded="false"> 线路区间规划 </a>
99 - </li>--> 99 + </li>
100 </ul> 100 </ul>
101 </div> 101 </div>
102 <div class="col-md-9 col-sm-9 col-xs-9"> 102 <div class="col-md-9 col-sm-9 col-xs-9">
@@ -371,10 +371,10 @@ @@ -371,10 +371,10 @@
371 <option>无线路区间</option> 371 <option>无线路区间</option>
372 </select> 372 </select>
373 </div> 373 </div>
374 - <div class="col-md-2 col-sm-2 col-xs-2"> 374 + <div class="col-md-2 col-sm-2 col-xs-2 region-btn-group">
375 <input type="button" value="编辑" id="regionEditBtn"/> 375 <input type="button" value="编辑" id="regionEditBtn"/>
376 </div> 376 </div>
377 - <div class="col-md-2 col-sm-2 col-xs-2"> 377 + <div class="col-md-2 col-sm-2 col-xs-2 region-btn-group">
378 <input type="button" value="新增" id="regionAddBtn"/> 378 <input type="button" value="新增" id="regionAddBtn"/>
379 </div> 379 </div>
380 </div> 380 </div>
@@ -408,9 +408,6 @@ @@ -408,9 +408,6 @@
408 </div> 408 </div>
409 </div> 409 </div>
410 </div> 410 </div>
411 -<script src="/pages/base/stationroute/js/routes-operation.js"></script>  
412 -<script src="/pages/base/stationroute/js/routes-service.js"></script>  
413 -  
414 411
415 <script id="add_draw_polyline-temp" type="text/html"> 412 <script id="add_draw_polyline-temp" type="text/html">
416 <div class="add_road_search_point_wrap "> 413 <div class="add_road_search_point_wrap ">
@@ -491,7 +488,7 @@ @@ -491,7 +488,7 @@
491 {{/if}} 488 {{/if}}
492 </script> 489 </script>
493 <script type="text/javascript"> 490 <script type="text/javascript">
494 - var proxy = EventProxy.create('routes-operation-loaded', 'routes-service-loaded', function() { 491 + $(document).ready(function () {
495 RoutesOperation.initPage(); 492 RoutesOperation.initPage();
496 RoutesOperation.initMap(); 493 RoutesOperation.initMap();
497 RoutesOperation.initStationDrawingManager(); 494 RoutesOperation.initStationDrawingManager();
src/main/resources/static/real_control_v2/assets/plugins/multi-select/multiple-select.min.css 0 → 100644
  1 +/**
  2 + * multiple-select - Multiple select is a jQuery plugin to select multiple elements with checkboxes :).
  3 + *
  4 + * @version v2.0.9
  5 + * @homepage http://multiple-select.wenzhixin.net.cn
  6 + * @author wenzhixin <wenzhixin2010@gmail.com> (http://wenzhixin.net.cn/)
  7 + * @license MIT
  8 + */
  9 +
  10 +@charset "UTF-8";.ms-offscreen{clip:rect(0 0 0 0)!important;width:1px!important;height:1px!important;border:0!important;margin:0!important;padding:0!important;overflow:hidden!important;position:absolute!important;outline:0!important;left:auto!important;top:auto!important}.ms-parent{display:inline-block;position:relative;vertical-align:middle}.ms-choice{display:block;width:100%;height:26px;padding:0;overflow:hidden;cursor:pointer;border:1px solid #aaa;text-align:left;white-space:nowrap;line-height:26px;color:#444;text-decoration:none;border-radius:4px;background-color:#fff}.ms-choice.disabled{background-color:#f4f4f4;background-image:none;border:1px solid #ddd;cursor:default}.ms-choice>span{position:absolute;top:0;left:0;right:20px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;display:block;padding-left:8px}.ms-choice>span.placeholder{color:#999}.ms-choice>div.icon-close{position:absolute;top:0;right:16px;height:100%;width:16px}.ms-choice>div.icon-close:before{content:"×";color:#888;font-weight:bold}.ms-choice>div.icon-close:hover:before{color:#333}.ms-choice>div.icon-caret{position:absolute;width:0;height:0;top:50%;right:8px;margin-top:-2px;border-color:#888 transparent transparent transparent;border-style:solid;border-width:5px 4px 0 4px}.ms-choice>div.icon-caret.open{border-color:transparent transparent #888 transparent;border-width:0 4px 5px 4px}.ms-drop{width:auto;min-width:100%;overflow:hidden;display:none;margin-top:-1px;padding:0;position:absolute;z-index:1000;background:#fff;color:#000;border:1px solid #aaa;border-radius:4px}.ms-drop.bottom{top:100%;box-shadow:0 4px 5px rgba(0,0,0,0.15)}.ms-drop.top{bottom:100%;box-shadow:0 -4px 5px rgba(0,0,0,0.15)}.ms-search{display:inline-block;margin:0;min-height:26px;padding:2px;position:relative;white-space:nowrap;width:100%;z-index:10000;box-sizing:border-box}.ms-search input{width:100%;height:auto!important;min-height:24px;padding:0 5px;margin:0;outline:0;font-family:sans-serif;border:1px solid #aaa;border-radius:5px;box-shadow:none}.ms-drop ul{overflow:auto;margin:0;padding:0}.ms-drop ul>li{list-style:none;display:list-item;background-image:none;position:static;padding:.25rem 8px}.ms-drop ul>li .disabled{font-weight:normal!important;opacity:.35;filter:Alpha(Opacity=35);cursor:default}.ms-drop ul>li.multiple{display:block;float:left}.ms-drop ul>li.group{clear:both}.ms-drop ul>li.multiple label{width:100%;display:block;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.ms-drop ul>li label{position:relative;padding-left:1.25rem;margin-bottom:0;font-weight:normal;display:block;white-space:nowrap;cursor:pointer}.ms-drop ul>li label.optgroup{font-weight:bold}.ms-drop ul>li.hide-radio{padding:0}.ms-drop ul>li.hide-radio:focus,.ms-drop ul>li.hide-radio:hover{background-color:#f8f9fa}.ms-drop ul>li.hide-radio.selected{color:#fff;background-color:#007bff}.ms-drop ul>li.hide-radio label{margin-bottom:0;padding:5px 8px}.ms-drop ul>li.hide-radio input{display:none}.ms-drop ul>li.option-level-1 label{padding-left:28px}.ms-drop ul>li.group ~ li.option-level-1:not(.hide-radio)>label{padding-left:40px}.ms-drop ul>li.option-divider{padding:0;border-top:1px solid #e9ecef}.ms-drop input[type=radio],.ms-drop input[type=checkbox]{position:absolute;margin-top:.3rem;margin-left:-1.25rem}.ms-drop .ms-no-results{display:none}
0 \ No newline at end of file 11 \ No newline at end of file
src/main/resources/static/real_control_v2/assets/plugins/multi-select/multiple-select.min.js 0 → 100644
  1 +/**
  2 + * multiple-select - Multiple select is a jQuery plugin to select multiple elements with checkboxes :).
  3 + *
  4 + * @version v2.0.9
  5 + * @homepage http://multiple-select.wenzhixin.net.cn
  6 + * @author wenzhixin <wenzhixin2010@gmail.com> (http://wenzhixin.net.cn/)
  7 + * @license MIT
  8 + */
  9 +
  10 +!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(require("jquery")):"function"==typeof define&&define.amd?define(["jquery"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).jQuery)}(this,(function(t){"use strict";function e(t,e){var n=Object.keys(t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(t);e&&(i=i.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),n.push.apply(n,i)}return n}function n(t){for(var n=1;n<arguments.length;n++){var i=null!=arguments[n]?arguments[n]:{};n%2?e(Object(i),!0).forEach((function(e){o(t,e,i[e])})):Object.getOwnPropertyDescriptors?Object.defineProperties(t,Object.getOwnPropertyDescriptors(i)):e(Object(i)).forEach((function(e){Object.defineProperty(t,e,Object.getOwnPropertyDescriptor(i,e))}))}return t}function i(t){return i="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},i(t)}function r(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function u(t,e,n){return e&&function(t,e){for(var n=0;n<e.length;n++){var i=e[n];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(t,h(i.key),i)}}(t.prototype,e),Object.defineProperty(t,"prototype",{writable:!1}),t}function o(t,e,n){return(e=h(e))in t?Object.defineProperty(t,e,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[e]=n,t}function s(t,e){return function(t){if(Array.isArray(t))return t}(t)||function(t,e){var n=null==t?null:"undefined"!=typeof Symbol&&t[Symbol.iterator]||t["@@iterator"];if(null!=n){var i,r,u,o,s=[],a=!0,l=!1;try{if(u=(n=n.call(t)).next,0===e);else for(;!(a=(i=u.call(n)).done)&&(s.push(i.value),s.length!==e);a=!0);}catch(t){l=!0,r=t}finally{try{if(!a&&null!=n.return&&(o=n.return(),Object(o)!==o))return}finally{if(l)throw r}}return s}}(t,e)||l(t,e)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function a(t){return function(t){if(Array.isArray(t))return c(t)}(t)||function(t){if("undefined"!=typeof Symbol&&null!=t[Symbol.iterator]||null!=t["@@iterator"])return Array.from(t)}(t)||l(t)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function l(t,e){if(t){if("string"==typeof t)return c(t,e);var n=Object.prototype.toString.call(t).slice(8,-1);return"Object"===n&&t.constructor&&(n=t.constructor.name),"Map"===n||"Set"===n?Array.from(t):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?c(t,e):void 0}}function c(t,e){(null==e||e>t.length)&&(e=t.length);for(var n=0,i=new Array(e);n<e;n++)i[n]=t[n];return i}function f(t,e){var n="undefined"!=typeof Symbol&&t[Symbol.iterator]||t["@@iterator"];if(!n){if(Array.isArray(t)||(n=l(t))||e){n&&(t=n);var i=0,r=function(){};return{s:r,n:function(){return i>=t.length?{done:!0}:{done:!1,value:t[i++]}},e:function(t){throw t},f:r}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var u,o=!0,s=!1;return{s:function(){n=n.call(t)},n:function(){var t=n.next();return o=t.done,t},e:function(t){s=!0,u=t},f:function(){try{o||null==n.return||n.return()}finally{if(s)throw u}}}}function h(t){var e=function(t,e){if("object"!=typeof t||null===t)return t;var n=t[Symbol.toPrimitive];if(void 0!==n){var i=n.call(t,e||"default");if("object"!=typeof i)return i;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===e?String:Number)(t)}(t,"string");return"symbol"==typeof e?e:String(e)}var d="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{},p=function(t){return t&&t.Math===Math&&t},v=p("object"==typeof globalThis&&globalThis)||p("object"==typeof window&&window)||p("object"==typeof self&&self)||p("object"==typeof d&&d)||p("object"==typeof d&&d)||function(){return this}()||Function("return this")(),g={},E=function(t){try{return!!t()}catch(t){return!0}},b=!E((function(){return 7!==Object.defineProperty({},1,{get:function(){return 7}})[1]})),y=!E((function(){var t=function(){}.bind();return"function"!=typeof t||t.hasOwnProperty("prototype")})),m=y,A=Function.prototype.call,C=m?A.bind(A):function(){return A.apply(A,arguments)},F={},S={}.propertyIsEnumerable,D=Object.getOwnPropertyDescriptor,k=D&&!S.call({1:2},1);F.f=k?function(t){var e=D(this,t);return!!e&&e.enumerable}:S;var w,O,x=function(t,e){return{enumerable:!(1&t),configurable:!(2&t),writable:!(4&t),value:e}},$=y,j=Function.prototype,B=j.call,T=$&&j.bind.bind(B,B),L=$?T:function(t){return function(){return B.apply(t,arguments)}},I=L,R=I({}.toString),_=I("".slice),P=function(t){return _(R(t),8,-1)},M=E,N=P,H=Object,U=L("".split),G=M((function(){return!H("z").propertyIsEnumerable(0)}))?function(t){return"String"===N(t)?U(t,""):H(t)}:H,W=function(t){return null==t},z=W,K=TypeError,V=function(t){if(z(t))throw new K("Can't call method on "+t);return t},q=G,Y=V,X=function(t){return q(Y(t))},J="object"==typeof document&&document.all,Z={all:J,IS_HTMLDDA:void 0===J&&void 0!==J},Q=Z.all,tt=Z.IS_HTMLDDA?function(t){return"function"==typeof t||t===Q}:function(t){return"function"==typeof t},et=tt,nt=Z.all,it=Z.IS_HTMLDDA?function(t){return"object"==typeof t?null!==t:et(t)||t===nt}:function(t){return"object"==typeof t?null!==t:et(t)},rt=v,ut=tt,ot=function(t,e){return arguments.length<2?(n=rt[t],ut(n)?n:void 0):rt[t]&&rt[t][e];var n},st=L({}.isPrototypeOf),at=v,lt="undefined"!=typeof navigator&&String(navigator.userAgent)||"",ct=at.process,ft=at.Deno,ht=ct&&ct.versions||ft&&ft.version,dt=ht&&ht.v8;dt&&(O=(w=dt.split("."))[0]>0&&w[0]<4?1:+(w[0]+w[1])),!O&&lt&&(!(w=lt.match(/Edge\/(\d+)/))||w[1]>=74)&&(w=lt.match(/Chrome\/(\d+)/))&&(O=+w[1]);var pt=O,vt=pt,gt=E,Et=v.String,bt=!!Object.getOwnPropertySymbols&&!gt((function(){var t=Symbol("symbol detection");return!Et(t)||!(Object(t)instanceof Symbol)||!Symbol.sham&&vt&&vt<41})),yt=bt&&!Symbol.sham&&"symbol"==typeof Symbol.iterator,mt=ot,At=tt,Ct=st,Ft=Object,St=yt?function(t){return"symbol"==typeof t}:function(t){var e=mt("Symbol");return At(e)&&Ct(e.prototype,Ft(t))},Dt=String,kt=function(t){try{return Dt(t)}catch(t){return"Object"}},wt=tt,Ot=kt,xt=TypeError,$t=function(t){if(wt(t))return t;throw new xt(Ot(t)+" is not a function")},jt=$t,Bt=W,Tt=function(t,e){var n=t[e];return Bt(n)?void 0:jt(n)},Lt=C,It=tt,Rt=it,_t=TypeError,Pt={exports:{}},Mt=v,Nt=Object.defineProperty,Ht=function(t,e){try{Nt(Mt,t,{value:e,configurable:!0,writable:!0})}catch(n){Mt[t]=e}return e},Ut=Ht,Gt="__core-js_shared__",Wt=v[Gt]||Ut(Gt,{}),zt=Wt;(Pt.exports=function(t,e){return zt[t]||(zt[t]=void 0!==e?e:{})})("versions",[]).push({version:"3.33.3",mode:"global",copyright:"© 2014-2023 Denis Pushkarev (zloirock.ru)",license:"https://github.com/zloirock/core-js/blob/v3.33.3/LICENSE",source:"https://github.com/zloirock/core-js"});var Kt=Pt.exports,Vt=V,qt=Object,Yt=function(t){return qt(Vt(t))},Xt=Yt,Jt=L({}.hasOwnProperty),Zt=Object.hasOwn||function(t,e){return Jt(Xt(t),e)},Qt=L,te=0,ee=Math.random(),ne=Qt(1..toString),ie=function(t){return"Symbol("+(void 0===t?"":t)+")_"+ne(++te+ee,36)},re=Kt,ue=Zt,oe=ie,se=bt,ae=yt,le=v.Symbol,ce=re("wks"),fe=ae?le.for||le:le&&le.withoutSetter||oe,he=function(t){return ue(ce,t)||(ce[t]=se&&ue(le,t)?le[t]:fe("Symbol."+t)),ce[t]},de=C,pe=it,ve=St,ge=Tt,Ee=function(t,e){var n,i;if("string"===e&&It(n=t.toString)&&!Rt(i=Lt(n,t)))return i;if(It(n=t.valueOf)&&!Rt(i=Lt(n,t)))return i;if("string"!==e&&It(n=t.toString)&&!Rt(i=Lt(n,t)))return i;throw new _t("Can't convert object to primitive value")},be=TypeError,ye=he("toPrimitive"),me=function(t,e){if(!pe(t)||ve(t))return t;var n,i=ge(t,ye);if(i){if(void 0===e&&(e="default"),n=de(i,t,e),!pe(n)||ve(n))return n;throw new be("Can't convert object to primitive value")}return void 0===e&&(e="number"),Ee(t,e)},Ae=St,Ce=function(t){var e=me(t,"string");return Ae(e)?e:e+""},Fe=it,Se=v.document,De=Fe(Se)&&Fe(Se.createElement),ke=function(t){return De?Se.createElement(t):{}},we=ke,Oe=!b&&!E((function(){return 7!==Object.defineProperty(we("div"),"a",{get:function(){return 7}}).a})),xe=b,$e=C,je=F,Be=x,Te=X,Le=Ce,Ie=Zt,Re=Oe,_e=Object.getOwnPropertyDescriptor;g.f=xe?_e:function(t,e){if(t=Te(t),e=Le(e),Re)try{return _e(t,e)}catch(t){}if(Ie(t,e))return Be(!$e(je.f,t,e),t[e])};var Pe={},Me=b&&E((function(){return 42!==Object.defineProperty((function(){}),"prototype",{value:42,writable:!1}).prototype})),Ne=it,He=String,Ue=TypeError,Ge=function(t){if(Ne(t))return t;throw new Ue(He(t)+" is not an object")},We=b,ze=Oe,Ke=Me,Ve=Ge,qe=Ce,Ye=TypeError,Xe=Object.defineProperty,Je=Object.getOwnPropertyDescriptor,Ze="enumerable",Qe="configurable",tn="writable";Pe.f=We?Ke?function(t,e,n){if(Ve(t),e=qe(e),Ve(n),"function"==typeof t&&"prototype"===e&&"value"in n&&tn in n&&!n[tn]){var i=Je(t,e);i&&i[tn]&&(t[e]=n.value,n={configurable:Qe in n?n[Qe]:i[Qe],enumerable:Ze in n?n[Ze]:i[Ze],writable:!1})}return Xe(t,e,n)}:Xe:function(t,e,n){if(Ve(t),e=qe(e),Ve(n),ze)try{return Xe(t,e,n)}catch(t){}if("get"in n||"set"in n)throw new Ye("Accessors not supported");return"value"in n&&(t[e]=n.value),t};var en=Pe,nn=x,rn=b?function(t,e,n){return en.f(t,e,nn(1,n))}:function(t,e,n){return t[e]=n,t},un={exports:{}},on=b,sn=Zt,an=Function.prototype,ln=on&&Object.getOwnPropertyDescriptor,cn=sn(an,"name"),fn={EXISTS:cn,PROPER:cn&&"something"===function(){}.name,CONFIGURABLE:cn&&(!on||on&&ln(an,"name").configurable)},hn=tt,dn=Wt,pn=L(Function.toString);hn(dn.inspectSource)||(dn.inspectSource=function(t){return pn(t)});var vn,gn,En,bn=dn.inspectSource,yn=tt,mn=v.WeakMap,An=yn(mn)&&/native code/.test(String(mn)),Cn=ie,Fn=Kt("keys"),Sn=function(t){return Fn[t]||(Fn[t]=Cn(t))},Dn={},kn=An,wn=v,On=it,xn=rn,$n=Zt,jn=Wt,Bn=Sn,Tn=Dn,Ln="Object already initialized",In=wn.TypeError,Rn=wn.WeakMap;if(kn||jn.state){var _n=jn.state||(jn.state=new Rn);_n.get=_n.get,_n.has=_n.has,_n.set=_n.set,vn=function(t,e){if(_n.has(t))throw new In(Ln);return e.facade=t,_n.set(t,e),e},gn=function(t){return _n.get(t)||{}},En=function(t){return _n.has(t)}}else{var Pn=Bn("state");Tn[Pn]=!0,vn=function(t,e){if($n(t,Pn))throw new In(Ln);return e.facade=t,xn(t,Pn,e),e},gn=function(t){return $n(t,Pn)?t[Pn]:{}},En=function(t){return $n(t,Pn)}}var Mn={set:vn,get:gn,has:En,enforce:function(t){return En(t)?gn(t):vn(t,{})},getterFor:function(t){return function(e){var n;if(!On(e)||(n=gn(e)).type!==t)throw new In("Incompatible receiver, "+t+" required");return n}}},Nn=L,Hn=E,Un=tt,Gn=Zt,Wn=b,zn=fn.CONFIGURABLE,Kn=bn,Vn=Mn.enforce,qn=Mn.get,Yn=String,Xn=Object.defineProperty,Jn=Nn("".slice),Zn=Nn("".replace),Qn=Nn([].join),ti=Wn&&!Hn((function(){return 8!==Xn((function(){}),"length",{value:8}).length})),ei=String(String).split("String"),ni=un.exports=function(t,e,n){"Symbol("===Jn(Yn(e),0,7)&&(e="["+Zn(Yn(e),/^Symbol\(([^)]*)\)/,"$1")+"]"),n&&n.getter&&(e="get "+e),n&&n.setter&&(e="set "+e),(!Gn(t,"name")||zn&&t.name!==e)&&(Wn?Xn(t,"name",{value:e,configurable:!0}):t.name=e),ti&&n&&Gn(n,"arity")&&t.length!==n.arity&&Xn(t,"length",{value:n.arity});try{n&&Gn(n,"constructor")&&n.constructor?Wn&&Xn(t,"prototype",{writable:!1}):t.prototype&&(t.prototype=void 0)}catch(t){}var i=Vn(t);return Gn(i,"source")||(i.source=Qn(ei,"string"==typeof e?e:"")),t};Function.prototype.toString=ni((function(){return Un(this)&&qn(this).source||Kn(this)}),"toString");var ii=un.exports,ri=tt,ui=Pe,oi=ii,si=Ht,ai=function(t,e,n,i){i||(i={});var r=i.enumerable,u=void 0!==i.name?i.name:e;if(ri(n)&&oi(n,u,i),i.global)r?t[e]=n:si(e,n);else{try{i.unsafe?t[e]&&(r=!0):delete t[e]}catch(t){}r?t[e]=n:ui.f(t,e,{value:n,enumerable:!1,configurable:!i.nonConfigurable,writable:!i.nonWritable})}return t},li={},ci=Math.ceil,fi=Math.floor,hi=Math.trunc||function(t){var e=+t;return(e>0?fi:ci)(e)},di=function(t){var e=+t;return e!=e||0===e?0:hi(e)},pi=di,vi=Math.max,gi=Math.min,Ei=function(t,e){var n=pi(t);return n<0?vi(n+e,0):gi(n,e)},bi=di,yi=Math.min,mi=function(t){return t>0?yi(bi(t),9007199254740991):0},Ai=mi,Ci=function(t){return Ai(t.length)},Fi=X,Si=Ei,Di=Ci,ki=function(t){return function(e,n,i){var r,u=Fi(e),o=Di(u),s=Si(i,o);if(t&&n!=n){for(;o>s;)if((r=u[s++])!=r)return!0}else for(;o>s;s++)if((t||s in u)&&u[s]===n)return t||s||0;return!t&&-1}},wi={includes:ki(!0),indexOf:ki(!1)},Oi=Zt,xi=X,$i=wi.indexOf,ji=Dn,Bi=L([].push),Ti=function(t,e){var n,i=xi(t),r=0,u=[];for(n in i)!Oi(ji,n)&&Oi(i,n)&&Bi(u,n);for(;e.length>r;)Oi(i,n=e[r++])&&(~$i(u,n)||Bi(u,n));return u},Li=["constructor","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","toLocaleString","toString","valueOf"],Ii=Ti,Ri=Li.concat("length","prototype");li.f=Object.getOwnPropertyNames||function(t){return Ii(t,Ri)};var _i={};_i.f=Object.getOwnPropertySymbols;var Pi=ot,Mi=li,Ni=_i,Hi=Ge,Ui=L([].concat),Gi=Pi("Reflect","ownKeys")||function(t){var e=Mi.f(Hi(t)),n=Ni.f;return n?Ui(e,n(t)):e},Wi=Zt,zi=Gi,Ki=g,Vi=Pe,qi=E,Yi=tt,Xi=/#|\.prototype\./,Ji=function(t,e){var n=Qi[Zi(t)];return n===er||n!==tr&&(Yi(e)?qi(e):!!e)},Zi=Ji.normalize=function(t){return String(t).replace(Xi,".").toLowerCase()},Qi=Ji.data={},tr=Ji.NATIVE="N",er=Ji.POLYFILL="P",nr=Ji,ir=v,rr=g.f,ur=rn,or=ai,sr=Ht,ar=function(t,e,n){for(var i=zi(e),r=Vi.f,u=Ki.f,o=0;o<i.length;o++){var s=i[o];Wi(t,s)||n&&Wi(n,s)||r(t,s,u(e,s))}},lr=nr,cr=function(t,e){var n,i,r,u,o,s=t.target,a=t.global,l=t.stat;if(n=a?ir:l?ir[s]||sr(s,{}):(ir[s]||{}).prototype)for(i in e){if(u=e[i],r=t.dontCallGetSet?(o=rr(n,i))&&o.value:n[i],!lr(a?i:s+(l?".":"#")+i,t.forced)&&void 0!==r){if(typeof u==typeof r)continue;ar(u,r)}(t.sham||r&&r.sham)&&ur(u,"sham",!0),or(n,i,u,t)}},fr={};fr[he("toStringTag")]="z";var hr="[object z]"===String(fr),dr=hr,pr=tt,vr=P,gr=he("toStringTag"),Er=Object,br="Arguments"===vr(function(){return arguments}()),yr=dr?vr:function(t){var e,n,i;return void 0===t?"Undefined":null===t?"Null":"string"==typeof(n=function(t,e){try{return t[e]}catch(t){}}(e=Er(t),gr))?n:br?vr(e):"Object"===(i=vr(e))&&pr(e.callee)?"Arguments":i},mr=yr,Ar=String,Cr=function(t){if("Symbol"===mr(t))throw new TypeError("Cannot convert a Symbol value to a string");return Ar(t)},Fr=Ge,Sr=function(){var t=Fr(this),e="";return t.hasIndices&&(e+="d"),t.global&&(e+="g"),t.ignoreCase&&(e+="i"),t.multiline&&(e+="m"),t.dotAll&&(e+="s"),t.unicode&&(e+="u"),t.unicodeSets&&(e+="v"),t.sticky&&(e+="y"),e},Dr=E,kr=v.RegExp,wr=Dr((function(){var t=kr("a","y");return t.lastIndex=2,null!==t.exec("abcd")})),Or=wr||Dr((function(){return!kr("a","y").sticky})),xr={BROKEN_CARET:wr||Dr((function(){var t=kr("^r","gy");return t.lastIndex=2,null!==t.exec("str")})),MISSED_STICKY:Or,UNSUPPORTED_Y:wr},$r={},jr=Ti,Br=Li,Tr=Object.keys||function(t){return jr(t,Br)},Lr=b,Ir=Me,Rr=Pe,_r=Ge,Pr=X,Mr=Tr;$r.f=Lr&&!Ir?Object.defineProperties:function(t,e){_r(t);for(var n,i=Pr(e),r=Mr(e),u=r.length,o=0;u>o;)Rr.f(t,n=r[o++],i[n]);return t};var Nr,Hr=ot("document","documentElement"),Ur=Ge,Gr=$r,Wr=Li,zr=Dn,Kr=Hr,Vr=ke,qr="prototype",Yr="script",Xr=Sn("IE_PROTO"),Jr=function(){},Zr=function(t){return"<"+Yr+">"+t+"</"+Yr+">"},Qr=function(t){t.write(Zr("")),t.close();var e=t.parentWindow.Object;return t=null,e},tu=function(){try{Nr=new ActiveXObject("htmlfile")}catch(t){}var t,e,n;tu="undefined"!=typeof document?document.domain&&Nr?Qr(Nr):(e=Vr("iframe"),n="java"+Yr+":",e.style.display="none",Kr.appendChild(e),e.src=String(n),(t=e.contentWindow.document).open(),t.write(Zr("document.F=Object")),t.close(),t.F):Qr(Nr);for(var i=Wr.length;i--;)delete tu[qr][Wr[i]];return tu()};zr[Xr]=!0;var eu,nu,iu=Object.create||function(t,e){var n;return null!==t?(Jr[qr]=Ur(t),n=new Jr,Jr[qr]=null,n[Xr]=t):n=tu(),void 0===e?n:Gr.f(n,e)},ru=E,uu=v.RegExp,ou=ru((function(){var t=uu(".","s");return!(t.dotAll&&t.test("\n")&&"s"===t.flags)})),su=E,au=v.RegExp,lu=su((function(){var t=au("(?<a>b)","g");return"b"!==t.exec("b").groups.a||"bc"!=="b".replace(t,"$<a>c")})),cu=C,fu=L,hu=Cr,du=Sr,pu=xr,vu=iu,gu=Mn.get,Eu=ou,bu=lu,yu=Kt("native-string-replace",String.prototype.replace),mu=RegExp.prototype.exec,Au=mu,Cu=fu("".charAt),Fu=fu("".indexOf),Su=fu("".replace),Du=fu("".slice),ku=(nu=/b*/g,cu(mu,eu=/a/,"a"),cu(mu,nu,"a"),0!==eu.lastIndex||0!==nu.lastIndex),wu=pu.BROKEN_CARET,Ou=void 0!==/()??/.exec("")[1];(ku||Ou||wu||Eu||bu)&&(Au=function(t){var e,n,i,r,u,o,s,a=this,l=gu(a),c=hu(t),f=l.raw;if(f)return f.lastIndex=a.lastIndex,e=cu(Au,f,c),a.lastIndex=f.lastIndex,e;var h=l.groups,d=wu&&a.sticky,p=cu(du,a),v=a.source,g=0,E=c;if(d&&(p=Su(p,"y",""),-1===Fu(p,"g")&&(p+="g"),E=Du(c,a.lastIndex),a.lastIndex>0&&(!a.multiline||a.multiline&&"\n"!==Cu(c,a.lastIndex-1))&&(v="(?: "+v+")",E=" "+E,g++),n=new RegExp("^(?:"+v+")",p)),Ou&&(n=new RegExp("^"+v+"$(?!\\s)",p)),ku&&(i=a.lastIndex),r=cu(mu,d?n:a,E),d?r?(r.input=Du(r.input,g),r[0]=Du(r[0],g),r.index=a.lastIndex,a.lastIndex+=r[0].length):a.lastIndex=0:ku&&r&&(a.lastIndex=a.global?r.index+r[0].length:i),Ou&&r&&r.length>1&&cu(yu,r[0],n,(function(){for(u=1;u<arguments.length-2;u++)void 0===arguments[u]&&(r[u]=void 0)})),r&&h)for(r.groups=o=vu(null),u=0;u<h.length;u++)o[(s=h[u])[0]]=r[s[1]];return r});var xu=Au;cr({target:"RegExp",proto:!0,forced:/./.exec!==xu},{exec:xu});var $u=P,ju=L,Bu=function(t){if("Function"===$u(t))return ju(t)},Tu=Bu,Lu=ai,Iu=xu,Ru=E,_u=he,Pu=rn,Mu=_u("species"),Nu=RegExp.prototype,Hu=function(t,e,n,i){var r=_u(t),u=!Ru((function(){var e={};return e[r]=function(){return 7},7!==""[t](e)})),o=u&&!Ru((function(){var e=!1,n=/a/;return"split"===t&&((n={}).constructor={},n.constructor[Mu]=function(){return n},n.flags="",n[r]=/./[r]),n.exec=function(){return e=!0,null},n[r](""),!e}));if(!u||!o||n){var s=Tu(/./[r]),a=e(r,""[t],(function(t,e,n,i,r){var o=Tu(t),a=e.exec;return a===Iu||a===Nu.exec?u&&!r?{done:!0,value:s(e,n,i)}:{done:!0,value:o(n,e,i)}:{done:!1}}));Lu(String.prototype,t,a[0]),Lu(Nu,r,a[1])}i&&Pu(Nu[r],"sham",!0)},Uu=Object.is||function(t,e){return t===e?0!==t||1/t==1/e:t!=t&&e!=e},Gu=C,Wu=Ge,zu=tt,Ku=P,Vu=xu,qu=TypeError,Yu=function(t,e){var n=t.exec;if(zu(n)){var i=Gu(n,t,e);return null!==i&&Wu(i),i}if("RegExp"===Ku(t))return Gu(Vu,t,e);throw new qu("RegExp#exec called on incompatible receiver")},Xu=C,Ju=Ge,Zu=W,Qu=V,to=Uu,eo=Cr,no=Tt,io=Yu;Hu("search",(function(t,e,n){return[function(e){var n=Qu(this),i=Zu(e)?void 0:no(e,t);return i?Xu(i,e,n):new RegExp(e)[t](eo(n))},function(t){var i=Ju(this),r=eo(t),u=n(e,i,r);if(u.done)return u.value;var o=i.lastIndex;to(o,0)||(i.lastIndex=0);var s=io(i,r);return to(i.lastIndex,o)||(i.lastIndex=o),null===s?-1:s.index}]}));var ro=he,uo=iu,oo=Pe.f,so=ro("unscopables"),ao=Array.prototype;void 0===ao[so]&&oo(ao,so,{configurable:!0,value:uo(null)});var lo=function(t){ao[so][t]=!0},co=wi.includes,fo=lo;cr({target:"Array",proto:!0,forced:E((function(){return!Array(1).includes()}))},{includes:function(t){return co(this,t,arguments.length>1?arguments[1]:void 0)}}),fo("includes");var ho=it,po=P,vo=he("match"),go=function(t){var e;return ho(t)&&(void 0!==(e=t[vo])?!!e:"RegExp"===po(t))},Eo=go,bo=TypeError,yo=he("match"),mo=cr,Ao=function(t){if(Eo(t))throw new bo("The method doesn't accept regular expressions");return t},Co=V,Fo=Cr,So=function(t){var e=/./;try{"/./"[t](e)}catch(n){try{return e[yo]=!1,"/./"[t](e)}catch(t){}}return!1},Do=L("".indexOf);mo({target:"String",proto:!0,forced:!So("includes")},{includes:function(t){return!!~Do(Fo(Co(this)),Fo(Ao(t)),arguments.length>1?arguments[1]:void 0)}});var ko="\t\n\v\f\r                 \u2028\u2029\ufeff",wo=V,Oo=Cr,xo=ko,$o=L("".replace),jo=RegExp("^["+xo+"]+"),Bo=RegExp("(^|[^"+xo+"])["+xo+"]+$"),To=function(t){return function(e){var n=Oo(wo(e));return 1&t&&(n=$o(n,jo,"")),2&t&&(n=$o(n,Bo,"$1")),n}},Lo={start:To(1),end:To(2),trim:To(3)},Io=fn.PROPER,Ro=E,_o=ko,Po=Lo.trim;cr({target:"String",proto:!0,forced:function(t){return Ro((function(){return!!_o[t]()||"​…᠎"!=="​…᠎"[t]()||Io&&_o[t].name!==t}))}("trim")},{trim:function(){return Po(this)}});var Mo=P,No=Array.isArray||function(t){return"Array"===Mo(t)},Ho=TypeError,Uo=Ce,Go=Pe,Wo=x,zo=function(t,e,n){var i=Uo(e);i in t?Go.f(t,i,Wo(0,n)):t[i]=n},Ko=L,Vo=E,qo=tt,Yo=yr,Xo=bn,Jo=function(){},Zo=[],Qo=ot("Reflect","construct"),ts=/^\s*(?:class|function)\b/,es=Ko(ts.exec),ns=!ts.test(Jo),is=function(t){if(!qo(t))return!1;try{return Qo(Jo,Zo,t),!0}catch(t){return!1}},rs=function(t){if(!qo(t))return!1;switch(Yo(t)){case"AsyncFunction":case"GeneratorFunction":case"AsyncGeneratorFunction":return!1}try{return ns||!!es(ts,Xo(t))}catch(t){return!0}};rs.sham=!0;var us=!Qo||Vo((function(){var t;return is(is.call)||!is(Object)||!is((function(){t=!0}))||t}))?rs:is,os=No,ss=us,as=it,ls=he("species"),cs=Array,fs=function(t){var e;return os(t)&&(e=t.constructor,(ss(e)&&(e===cs||os(e.prototype))||as(e)&&null===(e=e[ls]))&&(e=void 0)),void 0===e?cs:e},hs=function(t,e){return new(fs(t))(0===e?0:e)},ds=E,ps=pt,vs=he("species"),gs=function(t){return ps>=51||!ds((function(){var e=[];return(e.constructor={})[vs]=function(){return{foo:1}},1!==e[t](Boolean).foo}))},Es=cr,bs=E,ys=No,ms=it,As=Yt,Cs=Ci,Fs=function(t){if(t>9007199254740991)throw Ho("Maximum allowed index exceeded");return t},Ss=zo,Ds=hs,ks=gs,ws=pt,Os=he("isConcatSpreadable"),xs=ws>=51||!bs((function(){var t=[];return t[Os]=!1,t.concat()[0]!==t})),$s=function(t){if(!ms(t))return!1;var e=t[Os];return void 0!==e?!!e:ys(t)};Es({target:"Array",proto:!0,arity:1,forced:!xs||!ks("concat")},{concat:function(t){var e,n,i,r,u,o=As(this),s=Ds(o,0),a=0;for(e=-1,i=arguments.length;e<i;e++)if($s(u=-1===e?o:arguments[e]))for(r=Cs(u),Fs(a+r),n=0;n<r;n++,a++)n in u&&Ss(s,a,u[n]);else Fs(a+1),Ss(s,a++,u);return s.length=a,s}});var js=b,Bs=L,Ts=C,Ls=E,Is=Tr,Rs=_i,_s=F,Ps=Yt,Ms=G,Ns=Object.assign,Hs=Object.defineProperty,Us=Bs([].concat),Gs=!Ns||Ls((function(){if(js&&1!==Ns({b:1},Ns(Hs({},"a",{enumerable:!0,get:function(){Hs(this,"b",{value:3,enumerable:!1})}}),{b:2})).b)return!0;var t={},e={},n=Symbol("assign detection"),i="abcdefghijklmnopqrst";return t[n]=7,i.split("").forEach((function(t){e[t]=t})),7!==Ns({},t)[n]||Is(Ns({},e)).join("")!==i}))?function(t,e){for(var n=Ps(t),i=arguments.length,r=1,u=Rs.f,o=_s.f;i>r;)for(var s,a=Ms(arguments[r++]),l=u?Us(Is(a),u(a)):Is(a),c=l.length,f=0;c>f;)s=l[f++],js&&!Ts(o,a,s)||(n[s]=a[s]);return n}:Ns,Ws=Gs;cr({target:"Object",stat:!0,arity:2,forced:Object.assign!==Ws},{assign:Ws});var zs={name:"",placeholder:"",classes:"",classPrefix:"",data:void 0,locale:void 0,selectAll:!0,single:void 0,singleRadio:!1,multiple:!1,hideOptgroupCheckboxes:!1,multipleWidth:80,width:void 0,size:void 0,dropWidth:void 0,maxHeight:250,maxHeightUnit:"px",position:"bottom",displayValues:!1,displayTitle:!1,displayDelimiter:", ",minimumCountSelected:3,ellipsis:!1,isOpen:!1,keepOpen:!1,openOnHover:!1,container:null,filter:!1,filterGroup:!1,filterPlaceholder:"",filterAcceptOnEnter:!1,filterByDataLength:void 0,customFilter:function(t){var e=t.text,n=t.label,i=t.search;return(n||e).includes(i)},showClear:!1,animate:void 0,styler:function(){return!1},textTemplate:function(t){return t[0].innerHTML.trim()},labelTemplate:function(t){return t[0].getAttribute("label")},onOpen:function(){return!1},onClose:function(){return!1},onCheckAll:function(){return!1},onUncheckAll:function(){return!1},onFocus:function(){return!1},onBlur:function(){return!1},onOptgroupClick:function(){return!1},onBeforeClick:function(){return!0},onClick:function(){return!1},onFilter:function(){return!1},onClear:function(){return!1},onAfterCreate:function(){return!1}},Ks={formatSelectAll:function(){return"[全选]"},formatAllSelected:function(){return"全部选中"},formatCountSelected:function(t,e){return"".concat(t,"项被选中")},formatNoMatchesFound:function(){return"No matches found"}};Object.assign(zs,Ks);var Vs={VERSION:"1.7.0",BLOCK_ROWS:500,CLUSTER_BLOCKS:4,DEFAULTS:zs,METHODS:["getOptions","refreshOptions","getData","getSelects","setSelects","enable","disable","open","close","check","uncheck","checkAll","uncheckAll","checkInvert","focus","blur","refresh","destroy"],LOCALES:{en:Ks,"en-US":Ks}},qs=y,Ys=Function.prototype,Xs=Ys.apply,Js=Ys.call,Zs="object"==typeof Reflect&&Reflect.apply||(qs?Js.bind(Xs):function(){return Js.apply(Xs,arguments)}),Qs=us,ta=kt,ea=TypeError,na=Ge,ia=function(t){if(Qs(t))return t;throw new ea(ta(t)+" is not a constructor")},ra=W,ua=he("species"),oa=L,sa=di,aa=Cr,la=V,ca=oa("".charAt),fa=oa("".charCodeAt),ha=oa("".slice),da=function(t){return function(e,n){var i,r,u=aa(la(e)),o=sa(n),s=u.length;return o<0||o>=s?t?"":void 0:(i=fa(u,o))<55296||i>56319||o+1===s||(r=fa(u,o+1))<56320||r>57343?t?ca(u,o):i:t?ha(u,o,o+2):r-56320+(i-55296<<10)+65536}},pa={codeAt:da(!1),charAt:da(!0)}.charAt,va=function(t,e,n){return e+(n?pa(t,e).length:1)},ga=Ei,Ea=Ci,ba=zo,ya=Array,ma=Math.max,Aa=Zs,Ca=C,Fa=L,Sa=Hu,Da=Ge,ka=W,wa=go,Oa=V,xa=function(t,e){var n,i=na(t).constructor;return void 0===i||ra(n=na(i)[ua])?e:ia(n)},$a=va,ja=mi,Ba=Cr,Ta=Tt,La=function(t,e,n){for(var i=Ea(t),r=ga(e,i),u=ga(void 0===n?i:n,i),o=ya(ma(u-r,0)),s=0;r<u;r++,s++)ba(o,s,t[r]);return o.length=s,o},Ia=Yu,Ra=xu,_a=E,Pa=xr.UNSUPPORTED_Y,Ma=4294967295,Na=Math.min,Ha=[].push,Ua=Fa(/./.exec),Ga=Fa(Ha),Wa=Fa("".slice),za=!_a((function(){var t=/(?:)/,e=t.exec;t.exec=function(){return e.apply(this,arguments)};var n="ab".split(t);return 2!==n.length||"a"!==n[0]||"b"!==n[1]}));Sa("split",(function(t,e,n){var i;return i="c"==="abbc".split(/(b)*/)[1]||4!=="test".split(/(?:)/,-1).length||2!=="ab".split(/(?:ab)*/).length||4!==".".split(/(.?)(.?)/).length||".".split(/()()/).length>1||"".split(/.?/).length?function(t,n){var i=Ba(Oa(this)),r=void 0===n?Ma:n>>>0;if(0===r)return[];if(void 0===t)return[i];if(!wa(t))return Ca(e,i,t,r);for(var u,o,s,a=[],l=(t.ignoreCase?"i":"")+(t.multiline?"m":"")+(t.unicode?"u":"")+(t.sticky?"y":""),c=0,f=new RegExp(t.source,l+"g");(u=Ca(Ra,f,i))&&!((o=f.lastIndex)>c&&(Ga(a,Wa(i,c,u.index)),u.length>1&&u.index<i.length&&Aa(Ha,a,La(u,1)),s=u[0].length,c=o,a.length>=r));)f.lastIndex===u.index&&f.lastIndex++;return c===i.length?!s&&Ua(f,"")||Ga(a,""):Ga(a,Wa(i,c)),a.length>r?La(a,0,r):a}:"0".split(void 0,0).length?function(t,n){return void 0===t&&0===n?[]:Ca(e,this,t,n)}:e,[function(e,n){var r=Oa(this),u=ka(e)?void 0:Ta(e,t);return u?Ca(u,e,r,n):Ca(i,Ba(r),e,n)},function(t,r){var u=Da(this),o=Ba(t),s=n(i,u,o,r,i!==e);if(s.done)return s.value;var a=xa(u,RegExp),l=u.unicode,c=(u.ignoreCase?"i":"")+(u.multiline?"m":"")+(u.unicode?"u":"")+(Pa?"g":"y"),f=new a(Pa?"^(?:"+u.source+")":u,c),h=void 0===r?Ma:r>>>0;if(0===h)return[];if(0===o.length)return null===Ia(f,o)?[o]:[];for(var d=0,p=0,v=[];p<o.length;){f.lastIndex=Pa?0:p;var g,E=Ia(f,Pa?Wa(o,p):o);if(null===E||(g=Na(ja(f.lastIndex+(Pa?p:0)),o.length))===d)p=$a(o,p,l);else{if(Ga(v,Wa(o,d,p)),v.length===h)return v;for(var b=1;b<=E.length-1;b++)if(Ga(v,E[b]),v.length===h)return v;p=d=g}}return Ga(v,Wa(o,d)),v}]}),!za,Pa);var Ka=E,Va=function(t,e){var n=[][t];return!!n&&Ka((function(){n.call(null,e||function(){return 1},1)}))},qa=cr,Ya=G,Xa=X,Ja=Va,Za=L([].join);qa({target:"Array",proto:!0,forced:Ya!==Object||!Ja("join",",")},{join:function(t){return Za(Xa(this),void 0===t?",":t)}});var Qa=ii,tl=Pe,el=b,nl=fn.EXISTS,il=L,rl=function(t,e,n){return n.get&&Qa(n.get,e,{getter:!0}),n.set&&Qa(n.set,e,{setter:!0}),tl.f(t,e,n)},ul=Function.prototype,ol=il(ul.toString),sl=/function\b(?:\s|\/\*[\S\s]*?\*\/|\/\/[^\n\r]*[\n\r]+)*([^\s(/]*)/,al=il(sl.exec);el&&!nl&&rl(ul,"name",{configurable:!0,get:function(){try{return al(sl,ol(this))[1]}catch(t){return""}}});var ll=$t,cl=y,fl=Bu(Bu.bind),hl=function(t,e){return ll(t),void 0===e?t:cl?fl(t,e):function(){return t.apply(e,arguments)}},dl=G,pl=Yt,vl=Ci,gl=hs,El=L([].push),bl=function(t){var e=1===t,n=2===t,i=3===t,r=4===t,u=6===t,o=7===t,s=5===t||u;return function(a,l,c,f){for(var h,d,p=pl(a),v=dl(p),g=hl(l,c),E=vl(v),b=0,y=f||gl,m=e?y(a,E):n||o?y(a,0):void 0;E>b;b++)if((s||b in v)&&(d=g(h=v[b],b,p),t))if(e)m[b]=d;else if(d)switch(t){case 3:return!0;case 5:return h;case 6:return b;case 2:El(m,h)}else switch(t){case 4:return!1;case 7:El(m,h)}return u?-1:i||r?r:m}},yl={forEach:bl(0),map:bl(1),filter:bl(2),some:bl(3),every:bl(4),find:bl(5),findIndex:bl(6),filterReject:bl(7)},ml=cr,Al=yl.find,Cl=lo,Fl="find",Sl=!0;Fl in[]&&Array(1)[Fl]((function(){Sl=!1})),ml({target:"Array",proto:!0,forced:Sl},{find:function(t){return Al(this,t,arguments.length>1?arguments[1]:void 0)}}),Cl(Fl);var Dl=yr,kl=hr?{}.toString:function(){return"[object "+Dl(this)+"]"};hr||ai(Object.prototype,"toString",kl,{unsafe:!0});var wl=yl.map;cr({target:"Array",proto:!0,forced:!gs("map")},{map:function(t){return wl(this,t,arguments.length>1?arguments[1]:void 0)}});var Ol=!E((function(){function t(){}return t.prototype.constructor=null,Object.getPrototypeOf(new t)!==t.prototype})),xl=Zt,$l=tt,jl=Yt,Bl=Ol,Tl=Sn("IE_PROTO"),Ll=Object,Il=Ll.prototype,Rl=Bl?Ll.getPrototypeOf:function(t){var e=jl(t);if(xl(e,Tl))return e[Tl];var n=e.constructor;return $l(n)&&e instanceof n?n.prototype:e instanceof Ll?Il:null},_l=b,Pl=E,Ml=L,Nl=Rl,Hl=Tr,Ul=X,Gl=Ml(F.f),Wl=Ml([].push),zl=_l&&Pl((function(){var t=Object.create(null);return t[2]=2,!Gl(t,2)})),Kl=function(t){return function(e){for(var n,i=Ul(e),r=Hl(i),u=zl&&null===Nl(i),o=r.length,s=0,a=[];o>s;)n=r[s++],_l&&!(u?n in i:Gl(i,n))||Wl(a,t?[n,i[n]]:i[n]);return a}},Vl={entries:Kl(!0),values:Kl(!1)}.entries;cr({target:"Object",stat:!0},{entries:function(t){return Vl(t)}});var ql=Yt,Yl=Tr;cr({target:"Object",stat:!0,forced:E((function(){Yl(1)}))},{keys:function(t){return Yl(ql(t))}});var Xl=yl.filter;cr({target:"Array",proto:!0,forced:!gs("filter")},{filter:function(t){return Xl(this,t,arguments.length>1?arguments[1]:void 0)}});var Jl=ke("span").classList,Zl=Jl&&Jl.constructor&&Jl.constructor.prototype,Ql=Zl===Object.prototype?void 0:Zl,tc=yl.forEach,ec=Va("forEach")?[].forEach:function(t){return tc(this,t,arguments.length>1?arguments[1]:void 0)},nc=v,ic={CSSRuleList:0,CSSStyleDeclaration:0,CSSValueList:0,ClientRectList:0,DOMRectList:0,DOMStringList:0,DOMTokenList:1,DataTransferItemList:0,FileList:0,HTMLAllCollection:0,HTMLCollection:0,HTMLFormElement:0,HTMLSelectElement:0,MediaList:0,MimeTypeArray:0,NamedNodeMap:0,NodeList:1,PaintRequestList:0,Plugin:0,PluginArray:0,SVGLengthList:0,SVGNumberList:0,SVGPathSegList:0,SVGPointList:0,SVGStringList:0,SVGTransformList:0,SourceBufferList:0,StyleSheetList:0,TextTrackCueList:0,TextTrackList:0,TouchList:0},rc=Ql,uc=ec,oc=rn,sc=function(t){if(t&&t.forEach!==uc)try{oc(t,"forEach",uc)}catch(e){t.forEach=uc}};for(var ac in ic)ic[ac]&&sc(nc[ac]&&nc[ac].prototype);sc(rc);var lc=L([].slice),cc=cr,fc=No,hc=us,dc=it,pc=Ei,vc=Ci,gc=X,Ec=zo,bc=he,yc=lc,mc=gs("slice"),Ac=bc("species"),Cc=Array,Fc=Math.max;cc({target:"Array",proto:!0,forced:!mc},{slice:function(t,e){var n,i,r,u=gc(this),o=vc(u),s=pc(t,o),a=pc(void 0===e?o:e,o);if(fc(u)&&(n=u.constructor,(hc(n)&&(n===Cc||fc(n.prototype))||dc(n)&&null===(n=n[Ac]))&&(n=void 0),n===Cc||void 0===n))return yc(u,s,a);for(i=new(void 0===n?Cc:n)(Fc(a-s,0)),r=0;s<a;s++,r++)s in u&&Ec(i,r,u[s]);return i.length=r,i}});var Sc=C,Dc=Zt,kc=st,wc=Sr,Oc=RegExp.prototype,xc=fn.PROPER,$c=ai,jc=Ge,Bc=Cr,Tc=E,Lc=function(t){var e=t.flags;return void 0!==e||"flags"in Oc||Dc(t,"flags")||!kc(Oc,t)?e:Sc(wc,t)},Ic="toString",Rc=RegExp.prototype[Ic],_c=Tc((function(){return"/a/b"!==Rc.call({source:"a",flags:"b"})})),Pc=xc&&Rc.name!==Ic;(_c||Pc)&&$c(RegExp.prototype,Ic,(function(){var t=jc(this);return"/"+Bc(t.source)+"/"+Bc(Lc(t))}),{unsafe:!0});var Mc=function(){function t(e){var n=this;r(this,t),this.rows=e.rows,this.scrollEl=e.scrollEl,this.contentEl=e.contentEl,this.callback=e.callback,this.cache={},this.scrollTop=this.scrollEl.scrollTop,this.initDOM(this.rows),this.scrollEl.scrollTop=this.scrollTop,this.lastCluster=0;var i=function(){n.lastCluster!==(n.lastCluster=n.getNum())&&(n.initDOM(n.rows),n.callback())};this.scrollEl.addEventListener("scroll",i,!1),this.destroy=function(){n.contentEl.innerHtml="",n.scrollEl.removeEventListener("scroll",i,!1)}}return u(t,[{key:"initDOM",value:function(t){void 0===this.clusterHeight&&(this.cache.scrollTop=this.scrollEl.scrollTop,this.cache.data=this.contentEl.innerHTML=t[0]+t[0]+t[0],this.getRowsHeight(t));var e=this.initData(t,this.getNum()),n=e.rows.join(""),i=this.checkChanges("data",n),r=this.checkChanges("top",e.topOffset),u=this.checkChanges("bottom",e.bottomOffset),o=[];i&&r?(e.topOffset&&o.push(this.getExtra("top",e.topOffset)),o.push(n),e.bottomOffset&&o.push(this.getExtra("bottom",e.bottomOffset)),this.contentEl.innerHTML=o.join("")):u&&(this.contentEl.lastChild.style.height="".concat(e.bottomOffset,"px"))}},{key:"getRowsHeight",value:function(){if(void 0===this.itemHeight){var t=this.contentEl.children,e=t[Math.floor(t.length/2)];this.itemHeight=e.offsetHeight}this.blockHeight=this.itemHeight*Vs.BLOCK_ROWS,this.clusterRows=Vs.BLOCK_ROWS*Vs.CLUSTER_BLOCKS,this.clusterHeight=this.blockHeight*Vs.CLUSTER_BLOCKS}},{key:"getNum",value:function(){return this.scrollTop=this.scrollEl.scrollTop,Math.floor(this.scrollTop/(this.clusterHeight-this.blockHeight))||0}},{key:"initData",value:function(t,e){if(t.length<Vs.BLOCK_ROWS)return{topOffset:0,bottomOffset:0,rowsAbove:0,rows:t};var n=Math.max((this.clusterRows-Vs.BLOCK_ROWS)*e,0),i=n+this.clusterRows,r=Math.max(n*this.itemHeight,0),u=Math.max((t.length-i)*this.itemHeight,0),o=[],s=n;r<1&&s++;for(var a=n;a<i;a++)t[a]&&o.push(t[a]);return this.dataStart=n,this.dataEnd=i,{topOffset:r,bottomOffset:u,rowsAbove:s,rows:o}}},{key:"checkChanges",value:function(t,e){var n=e!==this.cache[t];return this.cache[t]=e,n}},{key:"getExtra",value:function(t,e){var n=document.createElement("li");return n.className="virtual-scroll-".concat(t),e&&(n.style.height="".concat(e,"px")),n.outerHTML}}]),t}(),Nc=L,Hc=Yt,Uc=Math.floor,Gc=Nc("".charAt),Wc=Nc("".replace),zc=Nc("".slice),Kc=/\$([$&'`]|\d{1,2}|<[^>]*>)/g,Vc=/\$([$&'`]|\d{1,2})/g,qc=Zs,Yc=C,Xc=L,Jc=Hu,Zc=E,Qc=Ge,tf=tt,ef=W,nf=di,rf=mi,uf=Cr,of=V,sf=va,af=Tt,lf=function(t,e,n,i,r,u){var o=n+t.length,s=i.length,a=Vc;return void 0!==r&&(r=Hc(r),a=Kc),Wc(u,a,(function(u,a){var l;switch(Gc(a,0)){case"$":return"$";case"&":return t;case"`":return zc(e,0,n);case"'":return zc(e,o);case"<":l=r[zc(a,1,-1)];break;default:var c=+a;if(0===c)return u;if(c>s){var f=Uc(c/10);return 0===f?u:f<=s?void 0===i[f-1]?Gc(a,1):i[f-1]+Gc(a,1):u}l=i[c-1]}return void 0===l?"":l}))},cf=Yu,ff=he("replace"),hf=Math.max,df=Math.min,pf=Xc([].concat),vf=Xc([].push),gf=Xc("".indexOf),Ef=Xc("".slice),bf="$0"==="a".replace(/./,"$0"),yf=!!/./[ff]&&""===/./[ff]("a","$0");Jc("replace",(function(t,e,n){var i=yf?"$":"$0";return[function(t,n){var i=of(this),r=ef(t)?void 0:af(t,ff);return r?Yc(r,t,i,n):Yc(e,uf(i),t,n)},function(t,r){var u=Qc(this),o=uf(t);if("string"==typeof r&&-1===gf(r,i)&&-1===gf(r,"$<")){var s=n(e,u,o,r);if(s.done)return s.value}var a=tf(r);a||(r=uf(r));var l,c=u.global;c&&(l=u.unicode,u.lastIndex=0);for(var f,h=[];null!==(f=cf(u,o))&&(vf(h,f),c);){""===uf(f[0])&&(u.lastIndex=sf(o,rf(u.lastIndex),l))}for(var d,p="",v=0,g=0;g<h.length;g++){for(var E,b=uf((f=h[g])[0]),y=hf(df(nf(f.index),o.length),0),m=[],A=1;A<f.length;A++)vf(m,void 0===(d=f[A])?d:String(d));var C=f.groups;if(a){var F=pf([b],m,y,o);void 0!==C&&vf(F,C),E=uf(qc(r,void 0,F))}else E=lf(b,o,y,m,C,r);y>=v&&(p+=Ef(o,v,y)+E,v=y+b.length)}return p+Ef(o,v)}]}),!!Zc((function(){var t=/./;return t.exec=function(){var t=[];return t.groups={a:"7"},t},"7"!=="".replace(t,"$<a>")}))||!bf||yf);var mf=$t,Af=Yt,Cf=G,Ff=Ci,Sf=TypeError,Df=function(t){return function(e,n,i,r){mf(n);var u=Af(e),o=Cf(u),s=Ff(u),a=t?s-1:0,l=t?-1:1;if(i<2)for(;;){if(a in o){r=o[a],a+=l;break}if(a+=l,t?a<0:s<=a)throw new Sf("Reduce of empty array with no initial value")}for(;t?a>=0:s>a;a+=l)a in o&&(r=n(r,o[a],a,u));return r}},kf={left:Df(!1),right:Df(!0)},wf="process"===P(v.process),Of=kf.left;cr({target:"Array",proto:!0,forced:!wf&&pt>79&&pt<83||!Va("reduce")},{reduce:function(t){var e=arguments.length;return Of(this,t,e,e>1?arguments[1]:void 0)}});var xf=function(t,e,n){var i,r=f(t);try{for(r.s();!(i=r.n()).done;){var u=i.value;if(u[e]===n||u[e]==="".concat(+u[e])&&+u[e]===n)return u;if("optgroup"===u.type){var o,s=f(u.children);try{for(s.s();!(o=s.n()).done;){var a=o.value;if(a[e]===n||a[e]==="".concat(+a[e])&&+a[e]===n)return a}}catch(t){s.e(t)}finally{s.f()}}}}catch(t){r.e(t)}finally{r.f()}},$f=function(t){if(t.normalize)return t.normalize("NFD").replace(/[\u0300-\u036F]/g,"");return[{base:"A",letters:/[\u0041\u24B6\uFF21\u00C0\u00C1\u00C2\u1EA6\u1EA4\u1EAA\u1EA8\u00C3\u0100\u0102\u1EB0\u1EAE\u1EB4\u1EB2\u0226\u01E0\u00C4\u01DE\u1EA2\u00C5\u01FA\u01CD\u0200\u0202\u1EA0\u1EAC\u1EB6\u1E00\u0104\u023A\u2C6F]/g},{base:"AA",letters:/[\uA732]/g},{base:"AE",letters:/[\u00C6\u01FC\u01E2]/g},{base:"AO",letters:/[\uA734]/g},{base:"AU",letters:/[\uA736]/g},{base:"AV",letters:/[\uA738\uA73A]/g},{base:"AY",letters:/[\uA73C]/g},{base:"B",letters:/[\u0042\u24B7\uFF22\u1E02\u1E04\u1E06\u0243\u0182\u0181]/g},{base:"C",letters:/[\u0043\u24B8\uFF23\u0106\u0108\u010A\u010C\u00C7\u1E08\u0187\u023B\uA73E]/g},{base:"D",letters:/[\u0044\u24B9\uFF24\u1E0A\u010E\u1E0C\u1E10\u1E12\u1E0E\u0110\u018B\u018A\u0189\uA779]/g},{base:"DZ",letters:/[\u01F1\u01C4]/g},{base:"Dz",letters:/[\u01F2\u01C5]/g},{base:"E",letters:/[\u0045\u24BA\uFF25\u00C8\u00C9\u00CA\u1EC0\u1EBE\u1EC4\u1EC2\u1EBC\u0112\u1E14\u1E16\u0114\u0116\u00CB\u1EBA\u011A\u0204\u0206\u1EB8\u1EC6\u0228\u1E1C\u0118\u1E18\u1E1A\u0190\u018E]/g},{base:"F",letters:/[\u0046\u24BB\uFF26\u1E1E\u0191\uA77B]/g},{base:"G",letters:/[\u0047\u24BC\uFF27\u01F4\u011C\u1E20\u011E\u0120\u01E6\u0122\u01E4\u0193\uA7A0\uA77D\uA77E]/g},{base:"H",letters:/[\u0048\u24BD\uFF28\u0124\u1E22\u1E26\u021E\u1E24\u1E28\u1E2A\u0126\u2C67\u2C75\uA78D]/g},{base:"I",letters:/[\u0049\u24BE\uFF29\u00CC\u00CD\u00CE\u0128\u012A\u012C\u0130\u00CF\u1E2E\u1EC8\u01CF\u0208\u020A\u1ECA\u012E\u1E2C\u0197]/g},{base:"J",letters:/[\u004A\u24BF\uFF2A\u0134\u0248]/g},{base:"K",letters:/[\u004B\u24C0\uFF2B\u1E30\u01E8\u1E32\u0136\u1E34\u0198\u2C69\uA740\uA742\uA744\uA7A2]/g},{base:"L",letters:/[\u004C\u24C1\uFF2C\u013F\u0139\u013D\u1E36\u1E38\u013B\u1E3C\u1E3A\u0141\u023D\u2C62\u2C60\uA748\uA746\uA780]/g},{base:"LJ",letters:/[\u01C7]/g},{base:"Lj",letters:/[\u01C8]/g},{base:"M",letters:/[\u004D\u24C2\uFF2D\u1E3E\u1E40\u1E42\u2C6E\u019C]/g},{base:"N",letters:/[\u004E\u24C3\uFF2E\u01F8\u0143\u00D1\u1E44\u0147\u1E46\u0145\u1E4A\u1E48\u0220\u019D\uA790\uA7A4]/g},{base:"NJ",letters:/[\u01CA]/g},{base:"Nj",letters:/[\u01CB]/g},{base:"O",letters:/[\u004F\u24C4\uFF2F\u00D2\u00D3\u00D4\u1ED2\u1ED0\u1ED6\u1ED4\u00D5\u1E4C\u022C\u1E4E\u014C\u1E50\u1E52\u014E\u022E\u0230\u00D6\u022A\u1ECE\u0150\u01D1\u020C\u020E\u01A0\u1EDC\u1EDA\u1EE0\u1EDE\u1EE2\u1ECC\u1ED8\u01EA\u01EC\u00D8\u01FE\u0186\u019F\uA74A\uA74C]/g},{base:"OI",letters:/[\u01A2]/g},{base:"OO",letters:/[\uA74E]/g},{base:"OU",letters:/[\u0222]/g},{base:"P",letters:/[\u0050\u24C5\uFF30\u1E54\u1E56\u01A4\u2C63\uA750\uA752\uA754]/g},{base:"Q",letters:/[\u0051\u24C6\uFF31\uA756\uA758\u024A]/g},{base:"R",letters:/[\u0052\u24C7\uFF32\u0154\u1E58\u0158\u0210\u0212\u1E5A\u1E5C\u0156\u1E5E\u024C\u2C64\uA75A\uA7A6\uA782]/g},{base:"S",letters:/[\u0053\u24C8\uFF33\u1E9E\u015A\u1E64\u015C\u1E60\u0160\u1E66\u1E62\u1E68\u0218\u015E\u2C7E\uA7A8\uA784]/g},{base:"T",letters:/[\u0054\u24C9\uFF34\u1E6A\u0164\u1E6C\u021A\u0162\u1E70\u1E6E\u0166\u01AC\u01AE\u023E\uA786]/g},{base:"TZ",letters:/[\uA728]/g},{base:"U",letters:/[\u0055\u24CA\uFF35\u00D9\u00DA\u00DB\u0168\u1E78\u016A\u1E7A\u016C\u00DC\u01DB\u01D7\u01D5\u01D9\u1EE6\u016E\u0170\u01D3\u0214\u0216\u01AF\u1EEA\u1EE8\u1EEE\u1EEC\u1EF0\u1EE4\u1E72\u0172\u1E76\u1E74\u0244]/g},{base:"V",letters:/[\u0056\u24CB\uFF36\u1E7C\u1E7E\u01B2\uA75E\u0245]/g},{base:"VY",letters:/[\uA760]/g},{base:"W",letters:/[\u0057\u24CC\uFF37\u1E80\u1E82\u0174\u1E86\u1E84\u1E88\u2C72]/g},{base:"X",letters:/[\u0058\u24CD\uFF38\u1E8A\u1E8C]/g},{base:"Y",letters:/[\u0059\u24CE\uFF39\u1EF2\u00DD\u0176\u1EF8\u0232\u1E8E\u0178\u1EF6\u1EF4\u01B3\u024E\u1EFE]/g},{base:"Z",letters:/[\u005A\u24CF\uFF3A\u0179\u1E90\u017B\u017D\u1E92\u1E94\u01B5\u0224\u2C7F\u2C6B\uA762]/g},{base:"a",letters:/[\u0061\u24D0\uFF41\u1E9A\u00E0\u00E1\u00E2\u1EA7\u1EA5\u1EAB\u1EA9\u00E3\u0101\u0103\u1EB1\u1EAF\u1EB5\u1EB3\u0227\u01E1\u00E4\u01DF\u1EA3\u00E5\u01FB\u01CE\u0201\u0203\u1EA1\u1EAD\u1EB7\u1E01\u0105\u2C65\u0250]/g},{base:"aa",letters:/[\uA733]/g},{base:"ae",letters:/[\u00E6\u01FD\u01E3]/g},{base:"ao",letters:/[\uA735]/g},{base:"au",letters:/[\uA737]/g},{base:"av",letters:/[\uA739\uA73B]/g},{base:"ay",letters:/[\uA73D]/g},{base:"b",letters:/[\u0062\u24D1\uFF42\u1E03\u1E05\u1E07\u0180\u0183\u0253]/g},{base:"c",letters:/[\u0063\u24D2\uFF43\u0107\u0109\u010B\u010D\u00E7\u1E09\u0188\u023C\uA73F\u2184]/g},{base:"d",letters:/[\u0064\u24D3\uFF44\u1E0B\u010F\u1E0D\u1E11\u1E13\u1E0F\u0111\u018C\u0256\u0257\uA77A]/g},{base:"dz",letters:/[\u01F3\u01C6]/g},{base:"e",letters:/[\u0065\u24D4\uFF45\u00E8\u00E9\u00EA\u1EC1\u1EBF\u1EC5\u1EC3\u1EBD\u0113\u1E15\u1E17\u0115\u0117\u00EB\u1EBB\u011B\u0205\u0207\u1EB9\u1EC7\u0229\u1E1D\u0119\u1E19\u1E1B\u0247\u025B\u01DD]/g},{base:"f",letters:/[\u0066\u24D5\uFF46\u1E1F\u0192\uA77C]/g},{base:"g",letters:/[\u0067\u24D6\uFF47\u01F5\u011D\u1E21\u011F\u0121\u01E7\u0123\u01E5\u0260\uA7A1\u1D79\uA77F]/g},{base:"h",letters:/[\u0068\u24D7\uFF48\u0125\u1E23\u1E27\u021F\u1E25\u1E29\u1E2B\u1E96\u0127\u2C68\u2C76\u0265]/g},{base:"hv",letters:/[\u0195]/g},{base:"i",letters:/[\u0069\u24D8\uFF49\u00EC\u00ED\u00EE\u0129\u012B\u012D\u00EF\u1E2F\u1EC9\u01D0\u0209\u020B\u1ECB\u012F\u1E2D\u0268\u0131]/g},{base:"j",letters:/[\u006A\u24D9\uFF4A\u0135\u01F0\u0249]/g},{base:"k",letters:/[\u006B\u24DA\uFF4B\u1E31\u01E9\u1E33\u0137\u1E35\u0199\u2C6A\uA741\uA743\uA745\uA7A3]/g},{base:"l",letters:/[\u006C\u24DB\uFF4C\u0140\u013A\u013E\u1E37\u1E39\u013C\u1E3D\u1E3B\u017F\u0142\u019A\u026B\u2C61\uA749\uA781\uA747]/g},{base:"lj",letters:/[\u01C9]/g},{base:"m",letters:/[\u006D\u24DC\uFF4D\u1E3F\u1E41\u1E43\u0271\u026F]/g},{base:"n",letters:/[\u006E\u24DD\uFF4E\u01F9\u0144\u00F1\u1E45\u0148\u1E47\u0146\u1E4B\u1E49\u019E\u0272\u0149\uA791\uA7A5]/g},{base:"nj",letters:/[\u01CC]/g},{base:"o",letters:/[\u006F\u24DE\uFF4F\u00F2\u00F3\u00F4\u1ED3\u1ED1\u1ED7\u1ED5\u00F5\u1E4D\u022D\u1E4F\u014D\u1E51\u1E53\u014F\u022F\u0231\u00F6\u022B\u1ECF\u0151\u01D2\u020D\u020F\u01A1\u1EDD\u1EDB\u1EE1\u1EDF\u1EE3\u1ECD\u1ED9\u01EB\u01ED\u00F8\u01FF\u0254\uA74B\uA74D\u0275]/g},{base:"oi",letters:/[\u01A3]/g},{base:"ou",letters:/[\u0223]/g},{base:"oo",letters:/[\uA74F]/g},{base:"p",letters:/[\u0070\u24DF\uFF50\u1E55\u1E57\u01A5\u1D7D\uA751\uA753\uA755]/g},{base:"q",letters:/[\u0071\u24E0\uFF51\u024B\uA757\uA759]/g},{base:"r",letters:/[\u0072\u24E1\uFF52\u0155\u1E59\u0159\u0211\u0213\u1E5B\u1E5D\u0157\u1E5F\u024D\u027D\uA75B\uA7A7\uA783]/g},{base:"s",letters:/[\u0073\u24E2\uFF53\u00DF\u015B\u1E65\u015D\u1E61\u0161\u1E67\u1E63\u1E69\u0219\u015F\u023F\uA7A9\uA785\u1E9B]/g},{base:"t",letters:/[\u0074\u24E3\uFF54\u1E6B\u1E97\u0165\u1E6D\u021B\u0163\u1E71\u1E6F\u0167\u01AD\u0288\u2C66\uA787]/g},{base:"tz",letters:/[\uA729]/g},{base:"u",letters:/[\u0075\u24E4\uFF55\u00F9\u00FA\u00FB\u0169\u1E79\u016B\u1E7B\u016D\u00FC\u01DC\u01D8\u01D6\u01DA\u1EE7\u016F\u0171\u01D4\u0215\u0217\u01B0\u1EEB\u1EE9\u1EEF\u1EED\u1EF1\u1EE5\u1E73\u0173\u1E77\u1E75\u0289]/g},{base:"v",letters:/[\u0076\u24E5\uFF56\u1E7D\u1E7F\u028B\uA75F\u028C]/g},{base:"vy",letters:/[\uA761]/g},{base:"w",letters:/[\u0077\u24E6\uFF57\u1E81\u1E83\u0175\u1E87\u1E85\u1E98\u1E89\u2C73]/g},{base:"x",letters:/[\u0078\u24E7\uFF58\u1E8B\u1E8D]/g},{base:"y",letters:/[\u0079\u24E8\uFF59\u1EF3\u00FD\u0177\u1EF9\u0233\u1E8F\u00FF\u1EF7\u1E99\u1EF5\u01B4\u024F\u1EFF]/g},{base:"z",letters:/[\u007A\u24E9\uFF5A\u017A\u1E91\u017C\u017E\u1E93\u1E95\u01B6\u0225\u0240\u2C6C\uA763]/g}].reduce((function(t,e){var n=e.letters,i=e.base;return t.replace(n,i)}),t)},jf=function(t){return Object.keys(t).forEach((function(e){return void 0===t[e]?delete t[e]:""})),t},Bf=function(t){return t&&"object"===i(t)&&t.__v_raw?t.__v_raw:t},Tf=function(){function e(n,i){r(this,e),this.$el=n,this.options=t.extend({},Vs.DEFAULTS,i)}return u(e,[{key:"init",value:function(){this.initLocale(),this.initContainer(),this.initData(),this.initSelected(!0),this.initFilter(),this.initDrop(),this.initView(),this.options.onAfterCreate()}},{key:"initLocale",value:function(){if(this.options.locale){var e=t.fn.multipleSelect.locales,n=this.options.locale.split(/-|_/);n[0]=n[0].toLowerCase(),n[1]&&(n[1]=n[1].toUpperCase()),e[this.options.locale]?t.extend(this.options,e[this.options.locale]):e[n.join("-")]?t.extend(this.options,e[n.join("-")]):e[n[0]]&&t.extend(this.options,e[n[0]])}}},{key:"initContainer",value:function(){var e=this,n=this.$el[0],i=n.getAttribute("name")||this.options.name||"";this.options.classes&&this.$el.addClass(this.options.classes),this.options.classPrefix&&(this.$el.addClass(this.options.classPrefix),this.options.size&&this.$el.addClass("".concat(this.options.classPrefix,"-").concat(this.options.size))),this.$el.hide(),this.$label=this.$el.closest("label"),!this.$label.length&&this.$el.attr("id")&&(this.$label=t('label[for="'.concat(this.$el.attr("id"),'"]'))),this.$label.find(">input").length&&(this.$label=null),void 0===this.options.single&&(this.options.single=null===n.getAttribute("multiple")),this.$parent=t('\n <div class="ms-parent '.concat(n.getAttribute("class")||""," ").concat(this.options.classes,'"\n title="').concat(n.getAttribute("title")||"",'" />\n ')),this.options.placeholder=this.options.placeholder||n.getAttribute("placeholder")||"",this.tabIndex=n.getAttribute("tabindex");var r="";if(null!==this.tabIndex&&(r=this.tabIndex&&'tabindex="'.concat(this.tabIndex,'"')),this.$el.attr("tabindex",-1),this.$choice=t('\n <button type="button" class="ms-choice"'.concat(r,'>\n <span class="placeholder">').concat(this.options.placeholder,"</span>\n ").concat(this.options.showClear?'<div class="icon-close"></div>':"",'\n <div class="icon-caret"></div>\n </button>\n ')),this.$drop=t('<div class="ms-drop '.concat(this.options.position,'" />')),this.$close=this.$choice.find(".icon-close"),this.options.dropWidth&&this.$drop.css("width",this.options.dropWidth),this.$el.after(this.$parent),this.$parent.append(this.$choice),this.$parent.append(this.$drop),n.disabled&&this.$choice.addClass("disabled"),this.selectAllName='data-name="selectAll'.concat(i,'"'),this.selectGroupName='data-name="selectGroup'.concat(i,'"'),this.selectItemName='data-name="selectItem'.concat(i,'"'),!this.options.keepOpen){var u=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"";return t=t||"".concat(+new Date).concat(~~(1e6*Math.random())),"click.multiple-select-".concat(t)}(this.$el.attr("id"));t(document).off(u).on(u,(function(i){t(i.target)[0]!==e.$choice[0]&&t(i.target).parents(".ms-choice")[0]!==e.$choice[0]&&(t(i.target)[0]===e.$drop[0]||t(i.target).parents(".ms-drop")[0]!==e.$drop[0]&&i.target!==n)&&e.options.isOpen&&e.close()}))}}},{key:"initData",value:function(){var e=this,r=[];if(this.options.data){if(Array.isArray(this.options.data))this.data=this.options.data.map((function(t){var e;return"string"==typeof t||"number"==typeof t?{text:t,value:t}:null!==(e=t.children)&&void 0!==e&&e.length?n(n({},t),{},{children:t.children.map((function(t){return n({},t)}))}):n({},t)}));else if("object"===i(this.options.data)){for(var u=0,o=Object.entries(this.options.data);u<o.length;u++){var a=s(o[u],2),l=a[0],c=a[1];r.push({value:l,text:c})}this.data=r}}else t.each(this.$el.children(),(function(t,n){e.initRow(t,n)&&r.push(e.initRow(t,n))})),this.options.data=r,this.data=r,this.fromHtml=!0;this.dataTotal=function(t){var e=0;return t.forEach((function(t,n){"optgroup"===t.type?(t._key="group_".concat(n),t.visible=void 0===t.visible||t.visible,t.children.forEach((function(t,i){t.visible=void 0===t.visible||t.visible,t.divider||(t._key="option_".concat(n,"_").concat(i),e+=1)}))):(t.visible=void 0===t.visible||t.visible,t.divider||(t._key="option_".concat(n),e+=1))})),e}(this.data)}},{key:"initRow",value:function(e,n,i){var r=this,u={},o=t(n);return o.is("option")?(u.type="option",u.text=this.options.textTemplate(o),u.value=n.value,u.visible=!0,u.selected=!!n.selected,u.disabled=i||n.disabled,u.classes=n.getAttribute("class")||"",u.title=n.getAttribute("title")||"",(n._value||o.data("value"))&&(u._value=n._value||o.data("value")),Object.keys(o.data()).length&&(u._data=o.data(),u._data.divider&&(u.divider=u._data.divider)),u):o.is("optgroup")?(u.type="optgroup",u.label=this.options.labelTemplate(o),u.visible=!0,u.selected=!!n.selected,u.disabled=n.disabled,u.children=[],Object.keys(o.data()).length&&(u._data=o.data()),t.each(o.children(),(function(t,e){u.children.push(r.initRow(t,e,u.disabled))})),u):null}},{key:"initSelected",value:function(t){var e,n=0,i=f(this.data);try{for(i.s();!(e=i.n()).done;){var r=e.value;if("optgroup"===r.type){var u=r.children.filter((function(t){return t.selected&&!t.disabled&&t.visible})).length;r.children.length&&(r.selected=!this.options.single&&u&&u===r.children.filter((function(t){return!t.disabled&&t.visible&&!t.divider})).length),n+=u}else n+=r.selected&&!r.disabled&&r.visible?1:0}}catch(t){i.e(t)}finally{i.f()}this.allSelected=this.data.filter((function(t){return t.selected&&!t.disabled&&t.visible})).length===this.data.filter((function(t){return!t.disabled&&t.visible&&!t.divider})).length,t||(this.allSelected?this.options.onCheckAll():0===n&&this.options.onUncheckAll())}},{key:"initFilter",value:function(){if(this.filterText="",!this.options.filter&&this.options.filterByDataLength){var t,e=0,n=f(this.data);try{for(n.s();!(t=n.n()).done;){var i=t.value;"optgroup"===i.type?e+=i.children.length:e+=1}}catch(t){n.e(t)}finally{n.f()}this.options.filter=e>this.options.filterByDataLength}}},{key:"initDrop",value:function(){var t=this;this.initList(),this.update(!0),this.options.isOpen&&setTimeout((function(){t.open()}),50),this.options.openOnHover&&this.$parent.hover((function(){t.open()}),(function(){t.close()}))}},{key:"initList",value:function(){var t=[];this.options.filter&&t.push('\n <div class="ms-search">\n <input type="text" autocomplete="off" autocorrect="off"\n autocapitalize="off" spellcheck="false"\n placeholder="'.concat(this.options.filterPlaceholder,'">\n </div>\n ')),t.push("<ul></ul>"),this.$drop.html(t.join("")),this.$ul=this.$drop.find(">ul"),this.initListItems()}},{key:"initListItems",value:function(){var t=this,e=this.getListRows(),n=0;if(this.options.selectAll&&!this.options.single&&(n=-1),e.length>Vs.BLOCK_ROWS*Vs.CLUSTER_BLOCKS){this.virtualScroll&&this.virtualScroll.destroy();var i=this.$drop.is(":visible");i||this.$drop.css("left",-1e4).show();var r=function(){t.updateDataStart=t.virtualScroll.dataStart+n,t.updateDataEnd=t.virtualScroll.dataEnd+n,t.updateDataStart<0&&(t.updateDataStart=0),t.updateDataEnd>t.data.length&&(t.updateDataEnd=t.data.length)};this.virtualScroll=new Mc({rows:e,scrollEl:this.$ul[0],contentEl:this.$ul[0],callback:function(){r(),t.events()}}),r(),i||this.$drop.css("left",0).hide()}else this.$ul.html(e.join("")),this.updateDataStart=0,this.updateDataEnd=this.updateData.length,this.virtualScroll=null;this.events()}},{key:"getListRows",value:function(){var t=this,e=[];return this.options.selectAll&&!this.options.single&&e.push('\n <li class="ms-select-all" tabindex="0">\n <label>\n <input type="checkbox" '.concat(this.selectAllName).concat(this.allSelected?' checked="checked"':"",' tabindex="-1" />\n <span>').concat(this.options.formatSelectAll(),"</span>\n </label>\n </li>\n ")),this.updateData=[],this.data.forEach((function(n){e.push.apply(e,a(t.initListItem(n)))})),e.push('<li class="ms-no-results">'.concat(this.options.formatNoMatchesFound(),"</li>")),e}},{key:"initListItem",value:function(t){var e=this,n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0,i=t.title?'title="'.concat(t.title,'"'):"",r=this.options.multiple?"multiple":"",u=this.options.single?"radio":"checkbox",o="";if(!t.visible)return[];if(this.updateData.push(t),this.options.single&&!this.options.singleRadio&&(o="hide-radio "),t.selected&&(o+="selected "),"optgroup"===t.type){var s=this.options.styler(t),l=s?'style="'.concat(s,'"'):"",c=[],f=this.options.hideOptgroupCheckboxes||this.options.single?"<span ".concat(this.selectGroupName,' data-key="').concat(t._key,'"></span>'):'<input type="checkbox"\n '.concat(this.selectGroupName,'\n data-key="').concat(t._key,'"\n ').concat(t.selected?' checked="checked"':"","\n ").concat(t.disabled?' disabled="disabled"':"",'\n tabindex="-1"\n >');return o.includes("hide-radio")||!this.options.hideOptgroupCheckboxes&&!this.options.single||(o+="hide-radio "),c.push('\n <li class="group '.concat(o,'" ').concat(l,' tabindex="').concat(o.includes("hide-radio")||t.disabled?-1:0,'">\n <label class="optgroup').concat(this.options.single||t.disabled?" disabled":"",'">\n ').concat(f).concat(t.label,"\n </label>\n </li>\n ")),t.children.forEach((function(t){c.push.apply(c,a(e.initListItem(t,1)))})),c}var h=this.options.styler(t),d=h?'style="'.concat(h,'"'):"";return o+="".concat(t.classes||""," option-level-").concat(n," "),t.divider?'<li class="option-divider"/>':['\n <li class="'.concat(r," ").concat(o,'" ').concat(i," ").concat(d,' tabindex="').concat(t.disabled?-1:0,'">\n <label class="').concat(t.disabled?"disabled":"",'">\n <input type="').concat(u,'"\n value="').concat(t.value,'"\n data-key="').concat(t._key,'"\n ').concat(this.selectItemName,"\n ").concat(t.selected?' checked="checked"':"","\n ").concat(t.disabled?' disabled="disabled"':"",'\n tabindex="-1"\n >\n <span>').concat(t.text,"</span>\n </label>\n </li>\n ")]}},{key:"events",value:function(){var e=this;this.$searchInput=this.$drop.find(".ms-search input"),this.$selectAll=this.$drop.find("input[".concat(this.selectAllName,"]")),this.$selectGroups=this.$drop.find("input[".concat(this.selectGroupName,"],span[").concat(this.selectGroupName,"]")),this.$selectItems=this.$drop.find("input[".concat(this.selectItemName,"]:enabled")),this.$disableItems=this.$drop.find("input[".concat(this.selectItemName,"]:disabled")),this.$noResults=this.$drop.find(".ms-no-results");var n=function(n){n.preventDefault(),t(n.target).hasClass("icon-close")||e[e.options.isOpen?"close":"open"]()};this.$label&&this.$label.length&&this.$label.off("click").on("click",(function(t){"label"===t.target.nodeName.toLowerCase()&&(n(t),e.options.filter&&e.options.isOpen||e.focus(),t.stopPropagation())})),this.$choice.off("click").on("click",n).off("focus").on("focus",this.options.onFocus).off("blur").on("blur",this.options.onBlur),this.$parent.off("keydown").on("keydown",(function(t){27!==t.which||e.options.keepOpen||(e.close(),e.$choice.focus())})),this.$close.off("click").on("click",(function(t){t.preventDefault(),e._checkAll(!1,!0),e.initSelected(!1),e.updateSelected(),e.update(),e.options.onClear()})),this.$searchInput.off("keydown").on("keydown",(function(t){9===t.keyCode&&t.shiftKey&&e.close()})).off("keyup").on("keyup",(function(t){if(e.options.filterAcceptOnEnter&&[13,32].includes(t.which)&&e.$searchInput.val()){if(e.options.single){var n=e.$selectItems.closest("li").filter(":visible");n.length&&e.setSelects([n.first().find("input[".concat(e.selectItemName,"]")).val()])}else e.$selectAll.click();return e.close(),void e.focus()}e.filter()})),this.$selectAll.off("click").on("click",(function(n){e._checkAll(t(n.currentTarget).prop("checked"))})),this.$selectGroups.off("click").on("click",(function(n){var i=t(n.currentTarget),r=i.prop("checked"),u=xf(e.data,"_key",i.data("key"));e._checkGroup(u,r),e.options.onOptgroupClick(jf({label:u.label,selected:u.selected,data:u._data,children:u.children.map((function(t){return jf({text:t.text,value:t.value,selected:t.selected,disabled:t.disabled,data:t._data})}))}))})),this.$selectItems.off("click").on("click",(function(n){var i=t(n.currentTarget),r=i.prop("checked"),u=xf(e.data,"_key",i.data("key")),o=function(){e.options.single&&e.options.isOpen&&!e.options.keepOpen&&e.close()};!1!==e.options.onBeforeClick(u)?(e._check(u,r),e.options.onClick(jf({text:u.text,value:u.value,selected:u.selected,data:u._data})),o()):o()})),this.$ul.find("li").off("keydown").on("keydown",(function(n){var i,r=t(n.currentTarget);switch(n.key){case"ArrowUp":n.preventDefault(),((i=r.prev("li.option-divider")).length?i:r).prev().trigger("focus");break;case"ArrowDown":n.preventDefault(),((i=r.next("li.option-divider")).length?i:r).next().trigger("focus");break;case"Enter":n.preventDefault(),r.find("input").trigger("click"),e.options.single&&e.$choice.trigger("focus")}}))}},{key:"initView",value:function(){var t;window.getComputedStyle?"auto"===(t=window.getComputedStyle(this.$el[0]).width)&&(t=this.$drop.outerWidth()+20):t=this.$el.outerWidth()+20,this.$parent.css("width",this.options.width||t),this.$el.show().addClass("ms-offscreen")}},{key:"open",value:function(){if(!this.$choice.hasClass("disabled")){if(this.options.isOpen=!0,this.$parent.addClass("ms-parent-open"),this.$choice.find(">div").addClass("open"),this.$drop[this.animateMethod("show")](),this.$selectAll.parent().show(),this.$noResults.hide(),this.data.length||(this.$selectAll.parent().hide(),this.$noResults.show()),this.options.container){var e=this.$drop.offset();this.$drop.appendTo(t(this.options.container)),this.$drop.offset({top:e.top,left:e.left}).css("min-width","auto").outerWidth(this.$parent.outerWidth())}var n=this.options.maxHeight;"row"===this.options.maxHeightUnit&&(n=this.$drop.find(">ul>li").first().outerHeight()*this.options.maxHeight),this.$drop.find(">ul").css("max-height","".concat(n,"px")),this.$drop.find(".multiple").css("width","".concat(this.options.multipleWidth,"px")),this.data.length&&this.options.filter&&(this.$searchInput.val(""),this.$searchInput.focus(),this.filter(!0)),this.options.onOpen()}}},{key:"close",value:function(){this.options.isOpen=!1,this.$parent.removeClass("ms-parent-open"),this.$choice.find(">div").removeClass("open"),this.$drop[this.animateMethod("hide")](),this.options.container&&(this.$parent.append(this.$drop),this.$drop.css({top:"auto",left:"auto"})),this.options.onClose()}},{key:"animateMethod",value:function(t){return{show:{fade:"fadeIn",slide:"slideDown"},hide:{fade:"fadeOut",slide:"slideUp"}}[t][this.options.animate]||t}},{key:"update",value:function(t){var e=this.getSelects(),n=this.getSelects("text");this.options.displayValues&&(n=e);var i=this.$choice.find(">span"),r=e.length,u="";0===r?i.addClass("placeholder").html(this.options.placeholder):u=r<this.options.minimumCountSelected?n.join(this.options.displayDelimiter):this.options.formatAllSelected()&&r===this.dataTotal?this.options.formatAllSelected():this.options.ellipsis&&r>this.options.minimumCountSelected?"".concat(n.slice(0,this.options.minimumCountSelected).join(this.options.displayDelimiter),"..."):this.options.formatCountSelected()&&r>this.options.minimumCountSelected?this.options.formatCountSelected(r,this.dataTotal):n.join(this.options.displayDelimiter),u&&i.removeClass("placeholder").html(u),this.options.displayTitle&&i.prop("title",this.getSelects("text")),this.$el.val(this.getSelects()),t||this.$el.trigger("change")}},{key:"updateSelected",value:function(){for(var t=this.updateDataStart;t<this.updateDataEnd;t++){var e=this.updateData[t];this.$drop.find("input[data-key=".concat(e._key,"]")).prop("checked",e.selected).closest("li").toggleClass("selected",e.selected)}var n=0===this.data.filter((function(t){return t.visible})).length;this.$selectAll.length&&this.$selectAll.prop("checked",this.allSelected).closest("li").toggleClass("selected",this.allSelected).toggle(!n),this.$noResults.toggle(n),this.virtualScroll&&(this.virtualScroll.rows=this.getListRows())}},{key:"getData",value:function(){return this.options.data}},{key:"getOptions",value:function(){var e=t.extend({},this.options);return delete e.data,t.extend(!0,{},e)}},{key:"refreshOptions",value:function(e){(function(t,e,n){var i=Object.keys(t),r=Object.keys(e);if(i.length!==r.length)return!1;for(var u=0,o=i;u<o.length;u++){var s=o[u];if(r.includes(s)&&t[s]!==e[s])return!1}return!0})(this.options,e)||(this.options=t.extend(this.options,e),this.destroy(),this.init())}},{key:"getSelects",value:function(){var t,e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"value",n=[],i=f(this.data);try{for(i.s();!(t=i.n()).done;){var r=t.value;if("optgroup"===r.type){var u=r.children.filter((function(t){return t.selected}));if(!u.length)continue;if("value"===e||this.options.single)n.push.apply(n,a(u.map((function(t){return"value"===e&&t._value||t[e]}))));else{var o=[];o.push("["),o.push(r.label),o.push(": ".concat(u.map((function(t){return t[e]})).join(", "))),o.push("]"),n.push(o.join(""))}}else r.selected&&n.push("value"===e&&r._value||r[e])}}catch(t){i.e(t)}finally{i.f()}return n}},{key:"setSelects",value:function(e){var n,i=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"value",r=arguments.length>2&&void 0!==arguments[2]&&arguments[2],u=!1,o=function(n){var r,o=f(n);try{var s=function(){var n=r.value,o=!1;if("text"===i)o=e.includes(t("<div>").html(n.text).text().trim());else{var s=Bf(n._value||n.value);(o=e.some((function(t){return Bf(t)===s})))||n.value!=="".concat(+n.value)||(o=e.includes(+n.value))}n.selected!==o&&(u=!0),n.selected=o};for(o.s();!(r=o.n()).done;)s()}catch(t){o.e(t)}finally{o.f()}},s=f(this.data);try{for(s.s();!(n=s.n()).done;){var a=n.value;"optgroup"===a.type?o(a.children):o([a])}}catch(t){s.e(t)}finally{s.f()}u&&(this.initSelected(r),this.updateSelected(),this.update(r))}},{key:"enable",value:function(){this.$choice.removeClass("disabled")}},{key:"disable",value:function(){this.$choice.addClass("disabled")}},{key:"check",value:function(t){var e=xf(this.data,"value",t);e&&this._check(e,!0)}},{key:"uncheck",value:function(t){var e=xf(this.data,"value",t);e&&this._check(e,!1)}},{key:"_check",value:function(t,e){this.options.single&&this._checkAll(!1,!0),t.selected=e,this.initSelected(),this.updateSelected(),this.update()}},{key:"checkAll",value:function(){this._checkAll(!0)}},{key:"uncheckAll",value:function(){this._checkAll(!1)}},{key:"_checkAll",value:function(t,e){var n,i=f(this.data);try{for(i.s();!(n=i.n()).done;){var r=n.value;"optgroup"===r.type?this._checkGroup(r,t,!0):r.disabled||r.divider||!e&&!r.visible||(r.selected=t)}}catch(t){i.e(t)}finally{i.f()}e||(this.initSelected(),this.updateSelected(),this.update())}},{key:"_checkGroup",value:function(t,e,n){t.selected=e,t.children.forEach((function(t){t.disabled||t.divider||!n&&!t.visible||(t.selected=e)})),n||(this.initSelected(),this.updateSelected(),this.update())}},{key:"checkInvert",value:function(){if(!this.options.single){var t,e=f(this.data);try{for(e.s();!(t=e.n()).done;){var n=t.value;if("optgroup"===n.type){var i,r=f(n.children);try{for(r.s();!(i=r.n()).done;){var u=i.value;u.divider||(u.selected=!u.selected)}}catch(t){r.e(t)}finally{r.f()}}else n.divider||(n.selected=!n.selected)}}catch(t){e.e(t)}finally{e.f()}this.initSelected(),this.updateSelected(),this.update()}}},{key:"focus",value:function(){this.$choice.focus(),this.options.onFocus()}},{key:"blur",value:function(){this.$choice.blur(),this.options.onBlur()}},{key:"refresh",value:function(){this.destroy(),this.init()}},{key:"filter",value:function(t){var e=this.$searchInput.val().trim(),n=e.toLowerCase();if(this.filterText!==n){this.filterText=n;var i,r=f(this.data);try{for(r.s();!(i=r.n()).done;){var u=i.value;if("optgroup"===u.type)if(this.options.filterGroup){var o=this.options.customFilter({label:$f(u.label.toString().toLowerCase()),search:$f(n),originalLabel:u.label,originalSearch:e,row:u});u.visible=o;var s,a=f(u.children);try{for(a.s();!(s=a.n()).done;){s.value.visible=o}}catch(t){a.e(t)}finally{a.f()}}else{var l,c=f(u.children);try{for(c.s();!(l=c.n()).done;){var h=l.value;h.visible=this.options.customFilter({text:$f(h.text.toString().toLowerCase()),search:$f(n),originalText:h.text,originalSearch:e,row:h,parent:u})}}catch(t){c.e(t)}finally{c.f()}u.visible=u.children.filter((function(t){return t.visible})).length>0}else u.visible=this.options.customFilter({text:$f(u.text.toString().toLowerCase()),search:$f(n),originalText:u.text,originalSearch:e,row:u})}}catch(t){r.e(t)}finally{r.f()}this.initListItems(),this.initSelected(t),this.updateSelected(),t||this.options.onFilter(e)}}},{key:"destroy",value:function(){this.$parent&&(this.$el.before(this.$parent).removeClass("ms-offscreen"),null!==this.tabIndex&&this.$el.attr("tabindex",this.tabIndex),this.$parent.remove(),this.fromHtml&&(delete this.options.data,this.fromHtml=!1))}}]),e}();t.fn.multipleSelect=function(e){for(var n=arguments.length,r=new Array(n>1?n-1:0),u=1;u<n;u++)r[u-1]=arguments[u];var o;return this.each((function(n,u){var s=t(u),a=s.data("multipleSelect"),l=t.extend({},s.data(),"object"===i(e)&&e);if(a||(a=new Tf(s,l),s.data("multipleSelect",a)),"string"==typeof e){var c;if(t.inArray(e,Vs.METHODS)<0)throw new Error("Unknown method: ".concat(e));o=(c=a)[e].apply(c,r),"destroy"===e&&s.removeData("multipleSelect")}else a.init()})),void 0!==o?o:this},t.fn.multipleSelect.Constructor=Tf,t.fn.multipleSelect.defaults=Vs.DEFAULTS,t.fn.multipleSelect.locales=Vs.LOCALES,t.fn.multipleSelect.methods=Vs.METHODS}));
src/main/resources/static/real_control_v2/fragments/line_schedule/context_menu/temp_sch/add_normal.html
1 -<!-- 临加班次form -->  
2 -<script id="add_normal_sch-form-temp" type="text/html">  
3 - <form class="uk-form uk-form-horizontal add-sch-form">  
4 - <div class="uk-grid">  
5 - <div class="uk-width-1-2">  
6 - <div class="uk-form-row">  
7 - <label class="uk-form-label">班次类型</label>  
8 - <div class="uk-form-controls">  
9 - <select class="form-control nt-dictionary" name="bcType" data-code="{{bcType}}"  
10 - data-group=ScheduleType></select>  
11 - </div>  
12 - </div>  
13 - </div>  
14 - <div class="uk-width-1-2">  
15 - <div class="uk-form-row">  
16 - <label class="uk-form-label">上下行</label>  
17 - <div class="uk-form-controls">  
18 - <select name="xlDir">  
19 - <option value="0">上行</option>  
20 - <option value="1">下行</option>  
21 - </select>  
22 - </div>  
23 - </div>  
24 - </div>  
25 - </div>  
26 - <div class="uk-grid">  
27 - <div class="uk-width-1-2">  
28 - <div class="uk-form-row">  
29 - <label class="uk-form-label">起点站</label>  
30 - <div class="uk-form-controls">  
31 - <select name="qdzCode">  
32 - </select>  
33 - </div>  
34 - </div>  
35 - </div>  
36 - <div class="uk-width-1-2">  
37 - <div class="uk-form-row">  
38 - <label class="uk-form-label">终点站</label>  
39 - <div class="uk-form-controls">  
40 - <select name="zdzCode">  
41 - </select>  
42 - </div>  
43 - </div>  
44 - </div>  
45 - </div>  
46 - <div class="uk-grid">  
47 - <div class="uk-width-1-2">  
48 - <div class="uk-form-row">  
49 - <label class="uk-form-label">开始时间</label>  
50 - <div class="uk-form-controls">  
51 - <input type="time" value="{{zdsjActual==null?zdsj:zdsjActual}}" name="fcsj" required>  
52 - </div>  
53 - </div>  
54 - </div>  
55 - <div class="uk-width-1-2">  
56 - <div class="uk-form-row">  
57 - <label class="uk-form-label">结束时间</label>  
58 - <div class="uk-form-controls">  
59 - <input type="time" name="zdsj" required>  
60 - </div>  
61 - </div>  
62 - </div>  
63 - </div>  
64 - <div class="uk-grid">  
65 - <div class="uk-width-1-2">  
66 - <div class="uk-form-row">  
67 - <label class="uk-form-label">车辆</label>  
68 - <div class="uk-form-controls">  
69 - <div class="uk-autocomplete uk-form car-autocom">  
70 - <input type="text" value="{{clZbh}}" name="clZbh" required>  
71 - </div>  
72 - </div>  
73 - </div>  
74 - </div>  
75 - <div class="uk-width-1-2">  
76 - <div class="uk-form-row">  
77 - <label class="uk-form-label">里程</label>  
78 - <div class="uk-form-controls">  
79 - <input type="text" name="jhlc" value="{{jhlc}}" max=400 data-fv-lessthan-inclusive="false"  
80 - required>  
81 - </div>  
82 - </div>  
83 - </div>  
84 - </div>  
85 - <div class="uk-grid">  
86 - <div class="uk-width-1-2">  
87 - <div class="uk-form-row">  
88 - <label class="uk-form-label">驾驶员</label>  
89 - <div class="uk-form-controls">  
90 - <div class="uk-autocomplete uk-form jsy-autocom">  
91 - <input type="text" value="{{jGh}}/{{jName}}" name="jsy" required>  
92 - </div>  
93 - </div>  
94 - </div>  
95 - </div>  
96 - <div class="uk-width-1-2">  
97 - <div class="uk-form-row">  
98 - <label class="uk-form-label">售票员</label>  
99 - <div class="uk-form-controls">  
100 - <div class="uk-autocomplete uk-form spy-autocom">  
101 - <input type="text" name="spy" value="{{sGh}}/{{sName}}">  
102 - </div>  
103 - </div>  
104 - </div>  
105 - </div>  
106 - </div>  
107 - <div class="uk-grid">  
108 - <div class="uk-width-1-1">  
109 - <div class="uk-form-row">  
110 - <label class="uk-form-label">备注</label>  
111 - <div class="uk-form-controls">  
112 - <div class="uk-autocomplete uk-form remarks-autocom">  
113 - <input type="text" name="remarks">  
114 - </div>  
115 - </div>  
116 - </div>  
117 - </div>  
118 - </div>  
119 - <div class="uk-modal-footer uk-text-right" style="margin-bottom: -20px;">  
120 - <span class="ct_line_lp_badge"></span>  
121 - <button type="button" class="uk-button uk-modal-close">取消</button>  
122 - <button type="submit" class="uk-button uk-button-primary"><i class="uk-icon-check"></i> &nbsp;保存  
123 - </button>  
124 - </div>  
125 - </form>  
126 -</script>  
127 -<script>  
128 - (function () {  
129 - var wrap = '#schedule-addsch-modal .normalCont', sch, nf, submitFun;  
130 -  
131 - $(wrap).on('init', function (e, data) {  
132 - e.stopPropagation();  
133 - sch = data.sch;  
134 - submitFun = data.submitFun;  
135 -  
136 - nf = addForm();  
137 - //提交  
138 - nf.on('success.form.fv', function (e) {  
139 - e.preventDefault();  
140 -  
141 - disabled_submit_btn(nf);  
142 - var data = nf.serializeJSON();  
143 - submitFun(data, function (rs) {  
144 - //前端数据更新  
145 - gb_schedule_table.insertSchedule(rs.t, rs.ts);  
146 - $('#schedule-lj_zrw-modal .main-schedule-table').trigger('refresh', {sch: rs.t});  
147 - try {  
148 - if(rs.t.bcType=='in' || rs.t.bcType=='out')  
149 - gb_data_basic.reload_stat_park_data();  
150 - }catch (e){  
151 - console.log(e);}  
152 - UIkit.modal('#schedule-addsch-modal').hide();  
153 - //更新路牌公里统计面板  
154 - gb_schedule_table.showLpMileageTipBySch(rs.t);  
155 - }, function () {  
156 - enable_submit_btn(nf);  
157 - });  
158 - });  
159 - $('.ct_line_lp_badge', nf).html(sch.xlName + ',&nbsp;'+sch.lpName);  
160 - });  
161 -  
162 - function addForm() {  
163 - var htmlStr = template('add_normal_sch-form-temp', sch);  
164 - var f = $(htmlStr);  
165 - $(wrap).append(f);  
166 - //字典转换  
167 - dictionaryUtils.transformDom($('.nt-dictionary', f));  
168 - //validation  
169 - f.formValidation({framework: 'uikit', locale: 'zh_CN'});  
170 - //autocomp  
171 - f.trigger('init-autoCom');  
172 -  
173 - $f('bcType', f).trigger('change');  
174 - return f;  
175 - }  
176 -  
177 - function $f(name, f) {  
178 - return $('[name=' + name + ']', f);  
179 - }  
180 - })(); 1 +<!-- 临加班次form -->
  2 +<script id="add_normal_sch-form-temp" type="text/html">
  3 + <form class="uk-form uk-form-horizontal add-sch-form">
  4 + <div class="uk-grid">
  5 + <div class="uk-width-1-2">
  6 + <div class="uk-form-row">
  7 + <label class="uk-form-label">班次类型</label>
  8 + <div class="uk-form-controls">
  9 + <select class="form-control nt-dictionary" name="bcType" data-code="{{bcType}}"
  10 + data-group=ScheduleType></select>
  11 + </div>
  12 + </div>
  13 + </div>
  14 + <div class="uk-width-1-2">
  15 + <div class="uk-form-row">
  16 + <label class="uk-form-label">上下行</label>
  17 + <div class="uk-form-controls">
  18 + <select name="xlDir">
  19 + <option value="0">上行</option>
  20 + <option value="1">下行</option>
  21 + </select>
  22 + </div>
  23 + </div>
  24 + </div>
  25 + </div>
  26 + <div class="uk-grid">
  27 + <div class="uk-width-1-2">
  28 + <div class="uk-form-row">
  29 + <label class="uk-form-label">起点站</label>
  30 + <div class="uk-form-controls">
  31 + <select name="qdzCode">
  32 + </select>
  33 + </div>
  34 + </div>
  35 + </div>
  36 + <div class="uk-width-1-2">
  37 + <div class="uk-form-row">
  38 + <label class="uk-form-label">终点站</label>
  39 + <div class="uk-form-controls">
  40 + <select name="zdzCode">
  41 + </select>
  42 + </div>
  43 + </div>
  44 + </div>
  45 + </div>
  46 + <div class="uk-grid">
  47 + <div class="uk-width-1-2">
  48 + <div class="uk-form-row">
  49 + <label class="uk-form-label">开始时间</label>
  50 + <div class="uk-form-controls">
  51 + <input type="time" value="{{zdsjActual==null?zdsj:zdsjActual}}" name="fcsj" required>
  52 + </div>
  53 + </div>
  54 + </div>
  55 + <div class="uk-width-1-2">
  56 + <div class="uk-form-row">
  57 + <label class="uk-form-label">结束时间</label>
  58 + <div class="uk-form-controls">
  59 + <input type="time" name="zdsj" required>
  60 + </div>
  61 + </div>
  62 + </div>
  63 + </div>
  64 + <div class="uk-grid">
  65 + <div class="uk-width-1-2">
  66 + <div class="uk-form-row">
  67 + <label class="uk-form-label">车辆</label>
  68 + <div class="uk-form-controls">
  69 + <div class="uk-autocomplete uk-form car-autocom">
  70 + <input type="text" value="{{clZbh}}" name="clZbh" required>
  71 + </div>
  72 + </div>
  73 + </div>
  74 + </div>
  75 + <div class="uk-width-1-2">
  76 + <div class="uk-form-row">
  77 + <label class="uk-form-label">里程</label>
  78 + <div class="uk-form-controls">
  79 + <input type="text" name="jhlc" value="{{jhlc}}" max=400 data-fv-lessthan-inclusive="false"
  80 + required>
  81 + </div>
  82 + </div>
  83 + </div>
  84 + </div>
  85 + <div class="uk-grid">
  86 + <div class="uk-width-1-2">
  87 + <div class="uk-form-row">
  88 + <label class="uk-form-label">驾驶员</label>
  89 + <div class="uk-form-controls">
  90 + <div class="uk-autocomplete uk-form jsy-autocom">
  91 + <input type="text" value="{{jGh}}/{{jName}}" name="jsy" required>
  92 + </div>
  93 + </div>
  94 + </div>
  95 + </div>
  96 + <div class="uk-width-1-2">
  97 + <div class="uk-form-row">
  98 + <label class="uk-form-label">售票员</label>
  99 + <div class="uk-form-controls">
  100 + <div class="uk-autocomplete uk-form spy-autocom">
  101 + <input type="text" name="spy" value="{{sGh}}/{{sName}}">
  102 + </div>
  103 + </div>
  104 + </div>
  105 + </div>
  106 + </div>
  107 + <div class="uk-grid" style="display:none;">
  108 + <div class="uk-width-1-2">
  109 + <div class="uk-form-row">
  110 + <label class="uk-form-label">是否预设</label>
  111 + <div class="uk-form-controls">
  112 + <div class="uk-autocomplete uk-form">
  113 + <input type="checkbox" name="isPreRegion" value="1">
  114 + </div>
  115 + </div>
  116 + </div>
  117 + </div>
  118 + <div class="uk-width-1-2" id="regionId">
  119 + <div class="uk-form-row">
  120 + <label class="uk-form-label">预设区间</label>
  121 + <div class="uk-form-controls">
  122 + <div class="uk-autocomplete uk-form">
  123 + <select name="regionId">
  124 + </select>
  125 + </div>
  126 + </div>
  127 + </div>
  128 + </div>
  129 + </div>
  130 + <div class="uk-grid" style="display:none;">
  131 + <div class="uk-width-1-2">
  132 + <div class="uk-form-row">
  133 + <label class="uk-form-label">是否封站</label>
  134 + <div class="uk-form-controls">
  135 + <div class="uk-autocomplete uk-form">
  136 + <input type="checkbox" name="isBlock" value="1">
  137 + </div>
  138 + </div>
  139 + </div>
  140 + </div>
  141 + <div class="uk-width-1-2" id="blockStations">
  142 + <div class="uk-form-row">
  143 + <label class="uk-form-label">封锁站点</label>
  144 + <div class="uk-form-controls">
  145 + <div class="uk-autocomplete uk-form">
  146 + <select class="form-control" name="blockStations" multiple="multiple">
  147 + </select>
  148 + </div>
  149 + </div>
  150 + </div>
  151 + </div>
  152 + </div>
  153 + <div class="uk-grid">
  154 + <div class="uk-width-1-1">
  155 + <div class="uk-form-row">
  156 + <label class="uk-form-label">备注</label>
  157 + <div class="uk-form-controls">
  158 + <div class="uk-autocomplete uk-form remarks-autocom">
  159 + <input type="text" name="remarks">
  160 + </div>
  161 + </div>
  162 + </div>
  163 + </div>
  164 + </div>
  165 + <div class="uk-modal-footer uk-text-right" style="margin-bottom: -20px;">
  166 + <span class="ct_line_lp_badge"></span>
  167 + <button type="button" class="uk-button uk-modal-close">取消</button>
  168 + <button type="submit" class="uk-button uk-button-primary"><i class="uk-icon-check"></i> &nbsp;保存
  169 + </button>
  170 + </div>
  171 + </form>
  172 +</script>
  173 +<script>
  174 + (function () {
  175 + var wrap = '#schedule-addsch-modal .normalCont', sch, nf, submitFun;
  176 +
  177 + $(wrap).on('init', function (e, data) {
  178 + e.stopPropagation();
  179 + sch = data.sch;
  180 + submitFun = data.submitFun;
  181 +
  182 + nf = addForm();
  183 + //提交
  184 + nf.on('success.form.fv', function (e) {
  185 + e.preventDefault();
  186 +
  187 + changeStationSelectStatus(true);
  188 + disabled_submit_btn(nf);
  189 + var data = nf.serializeJSON();
  190 + var blockStations = $('[name=blockStations]', nf).val();
  191 + data.blockStations = blockStations ? blockStations.join(',') : null;
  192 + submitFun(data, function (rs) {
  193 + //前端数据更新
  194 + gb_schedule_table.insertSchedule(rs.t, rs.ts);
  195 + $('#schedule-lj_zrw-modal .main-schedule-table').trigger('refresh', {sch: rs.t});
  196 + try {
  197 + if(rs.t.bcType=='in' || rs.t.bcType=='out')
  198 + gb_data_basic.reload_stat_park_data();
  199 + }catch (e){
  200 + console.log(e);}
  201 + UIkit.modal('#schedule-addsch-modal').hide();
  202 + //更新路牌公里统计面板
  203 + gb_schedule_table.showLpMileageTipBySch(rs.t);
  204 + }, function () {
  205 + changeStationSelectStatus(false);
  206 + enable_submit_btn(nf);
  207 + });
  208 + });
  209 + $('.ct_line_lp_badge', nf).html(sch.xlName + ',&nbsp;'+sch.lpName);
  210 + });
  211 +
  212 + function addForm() {
  213 + var htmlStr = template('add_normal_sch-form-temp', sch);
  214 + var f = $(htmlStr);
  215 + $(wrap).append(f);
  216 + //字典转换
  217 + dictionaryUtils.transformDom($('.nt-dictionary', f));
  218 + //validation
  219 + f.formValidation({framework: 'uikit', locale: 'zh_CN'});
  220 + //autocomp
  221 + f.trigger('init-autoCom');
  222 +
  223 + $f('bcType', f).trigger('change');
  224 + return f;
  225 + }
  226 +
  227 + function $f(name, f) {
  228 + return $('[name=' + name + ']', f);
  229 + }
  230 +
  231 + function changeStationSelectStatus(flag) {
  232 + $('[name=qdzCode],[name=zdzCode]').prop('disabled', !flag);
  233 + }
  234 + })();
181 </script> 235 </script>
182 \ No newline at end of file 236 \ No newline at end of file
src/main/resources/static/real_control_v2/fragments/line_schedule/context_menu/temp_sch/add_two_way.html
1 -<!-- 线路上往返临加班次 -->  
2 -<script id="add_toAndFro_sch-form-temp" type="text/html">  
3 - <form class="uk-form uk-form-horizontal add-sch-form one_form">  
4 - <div class="uk-grid">  
5 - <div class="uk-width-1-2">  
6 - <div class="uk-form-row">  
7 - <label class="uk-form-label">班次类型</label>  
8 - <div class="uk-form-controls">  
9 - <select class="form-control nt-dictionary" name="bcType" data-code="{{bcType}}"  
10 - data-group=ScheduleType></select>  
11 - </div>  
12 - </div>  
13 - </div>  
14 - <div class="uk-width-1-2">  
15 - <div class="uk-form-row">  
16 - <label class="uk-form-label">上下行</label>  
17 - <div class="uk-form-controls">  
18 - <select name="xlDir">  
19 - <option value="0">上行</option>  
20 - <option value="1">下行</option>  
21 - </select>  
22 - </div>  
23 - </div>  
24 - </div>  
25 - </div>  
26 - <div class="uk-grid">  
27 - <div class="uk-width-1-2">  
28 - <div class="uk-form-row">  
29 - <label class="uk-form-label">起点站</label>  
30 - <div class="uk-form-controls">  
31 - <select name="qdzCode" >  
32 - </select>  
33 - </div>  
34 - </div>  
35 - </div>  
36 - <div class="uk-width-1-2">  
37 - <div class="uk-form-row">  
38 - <label class="uk-form-label">终点站</label>  
39 - <div class="uk-form-controls">  
40 - <select name="zdzCode" >  
41 - </select>  
42 - </div>  
43 - </div>  
44 - </div>  
45 - </div>  
46 - <div class="uk-grid">  
47 - <div class="uk-width-1-2">  
48 - <div class="uk-form-row">  
49 - <label class="uk-form-label">开始时间</label>  
50 - <div class="uk-form-controls">  
51 - <input type="time" value="{{zdsj}}" name="fcsj" required>  
52 - </div>  
53 - </div>  
54 - </div>  
55 - <div class="uk-width-1-2">  
56 - <div class="uk-form-row">  
57 - <label class="uk-form-label">结束时间</label>  
58 - <div class="uk-form-controls">  
59 - <input type="time" name="zdsj" required>  
60 - </div>  
61 - </div>  
62 - </div>  
63 - </div>  
64 - <div class="uk-grid">  
65 - <div class="uk-width-1-2">  
66 - <div class="uk-form-row">  
67 - <label class="uk-form-label">车辆</label>  
68 - <div class="uk-form-controls">  
69 - <div class="uk-autocomplete uk-form car-autocom">  
70 - <input type="text" value="{{clZbh}}" name="clZbh" required>  
71 - </div>  
72 - </div>  
73 - </div>  
74 - </div>  
75 - <div class="uk-width-1-2">  
76 - <div class="uk-form-row">  
77 - <label class="uk-form-label">里程</label>  
78 - <div class="uk-form-controls">  
79 - <input type="text" name="jhlc" value="{{jhlc}}" max=400 data-fv-lessthan-inclusive="false"  
80 - required>  
81 - </div>  
82 - </div>  
83 - </div>  
84 - </div>  
85 - <div class="uk-grid">  
86 - <div class="uk-width-1-2">  
87 - <div class="uk-form-row">  
88 - <label class="uk-form-label">驾驶员</label>  
89 - <div class="uk-form-controls">  
90 - <div class="uk-autocomplete uk-form jsy-autocom">  
91 - <input type="text" value="{{jGh}}/{{jName}}" name="jsy" required>  
92 - </div>  
93 - </div>  
94 - </div>  
95 - </div>  
96 - <div class="uk-width-1-2">  
97 - <div class="uk-form-row">  
98 - <label class="uk-form-label">售票员</label>  
99 - <div class="uk-form-controls">  
100 - <div class="uk-autocomplete uk-form spy-autocom">  
101 - <input type="text" name="spy" value="{{sGh}}/{{sName}}">  
102 - </div>  
103 - </div>  
104 - </div>  
105 - </div>  
106 - </div>  
107 - <div class="uk-grid">  
108 - <div class="uk-width-1-1">  
109 - <div class="uk-form-row">  
110 - <label class="uk-form-label">备注</label>  
111 - <div class="uk-form-controls">  
112 - <div class="uk-autocomplete uk-form remarks-autocom">  
113 - <input type="text" name="remarks">  
114 - </div>  
115 - </div>  
116 - </div>  
117 - </div>  
118 - </div>  
119 - </form>  
120 - <hr style="margin-top: 35px;">  
121 - <form class="uk-form uk-form-horizontal add-sch-form two_form">  
122 - <div class="uk-grid">  
123 - <div class="uk-width-1-2">  
124 - <div class="uk-form-row">  
125 - <label class="uk-form-label">班次类型</label>  
126 - <div class="uk-form-controls">  
127 - <select class="form-control nt-dictionary" name="bcType" data-code="{{bcType}}"  
128 - data-group=ScheduleType></select>  
129 - </div>  
130 - </div>  
131 - </div>  
132 - <div class="uk-width-1-2">  
133 - <div class="uk-form-row">  
134 - <label class="uk-form-label">上下行</label>  
135 - <div class="uk-form-controls">  
136 - <select name="xlDir">  
137 - <option value="0">上行</option>  
138 - <option value="1">下行</option>  
139 - </select>  
140 - </div>  
141 - </div>  
142 - </div>  
143 - </div>  
144 - <div class="uk-grid">  
145 - <div class="uk-width-1-2">  
146 - <div class="uk-form-row">  
147 - <label class="uk-form-label">起点站</label>  
148 - <div class="uk-form-controls">  
149 - <select name="qdzCode" >  
150 - </select>  
151 - </div>  
152 - </div>  
153 - </div>  
154 - <div class="uk-width-1-2">  
155 - <div class="uk-form-row">  
156 - <label class="uk-form-label">终点站</label>  
157 - <div class="uk-form-controls">  
158 - <select name="zdzCode" >  
159 - </select>  
160 - </div>  
161 - </div>  
162 - </div>  
163 - </div>  
164 - <div class="uk-grid">  
165 - <div class="uk-width-1-2">  
166 - <div class="uk-form-row">  
167 - <label class="uk-form-label">开始时间</label>  
168 - <div class="uk-form-controls">  
169 - <input type="time" value="{{zdsj}}" name="fcsj" required>  
170 - </div>  
171 - </div>  
172 - </div>  
173 - <div class="uk-width-1-2">  
174 - <div class="uk-form-row">  
175 - <label class="uk-form-label">结束时间</label>  
176 - <div class="uk-form-controls">  
177 - <input type="time" name="zdsj" required>  
178 - </div>  
179 - </div>  
180 - </div>  
181 - </div>  
182 - <div class="uk-grid">  
183 - <div class="uk-width-1-2">  
184 - <div class="uk-form-row">  
185 - <label class="uk-form-label">车辆</label>  
186 - <div class="uk-form-controls">  
187 - <div class="uk-autocomplete uk-form car-autocom">  
188 - <input type="text" value="{{clZbh}}" name="clZbh" required>  
189 - </div>  
190 - </div>  
191 - </div>  
192 - </div>  
193 - <div class="uk-width-1-2">  
194 - <div class="uk-form-row">  
195 - <label class="uk-form-label">里程</label>  
196 - <div class="uk-form-controls">  
197 - <input type="text" name="jhlc" value="{{jhlc}}" max=400 data-fv-lessthan-inclusive="false"  
198 - required>  
199 - </div>  
200 - </div>  
201 - </div>  
202 - </div>  
203 - <div class="uk-grid">  
204 - <div class="uk-width-1-2">  
205 - <div class="uk-form-row">  
206 - <label class="uk-form-label">驾驶员</label>  
207 - <div class="uk-form-controls">  
208 - <div class="uk-autocomplete uk-form jsy-autocom">  
209 - <input type="text" value="{{jGh}}/{{jName}}" name="jsy" required>  
210 - </div>  
211 - </div>  
212 - </div>  
213 - </div>  
214 - <div class="uk-width-1-2">  
215 - <div class="uk-form-row">  
216 - <label class="uk-form-label">售票员</label>  
217 - <div class="uk-form-controls">  
218 - <div class="uk-autocomplete uk-form spy-autocom">  
219 - <input type="text" name="spy" value="{{sGh}}/{{sName}}">  
220 - </div>  
221 - </div>  
222 - </div>  
223 - </div>  
224 - </div>  
225 - <div class="uk-grid">  
226 - <div class="uk-width-1-1">  
227 - <div class="uk-form-row">  
228 - <label class="uk-form-label">备注</label>  
229 - <div class="uk-form-controls">  
230 - <div class="uk-autocomplete uk-form remarks-autocom">  
231 - <input type="text" name="remarks">  
232 - </div>  
233 - </div>  
234 - </div>  
235 - </div>  
236 - </div>  
237 - </form>  
238 -  
239 - <div class="uk-modal-footer uk-text-right" style="margin-bottom: -20px;">  
240 - <span class="ct_line_lp_badge" ></span>  
241 - <button type="button" class="uk-button uk-modal-close">取消</button>  
242 - <button type="submit" class="uk-button uk-button-primary"><i class="uk-icon-check"></i> &nbsp;保存</button>  
243 - </div>  
244 -</script>  
245 -  
246 -<script>  
247 - (function () {  
248 - var wrap = '#schedule-addsch-modal .toAndFroCont', sch, f1, f2, submitFun, stationRoutes;  
249 -  
250 - $(wrap).on('init', function (e, data) {  
251 - e.stopPropagation();  
252 - sch = data.sch;  
253 - submitFun = data.submitFun;  
254 - stationRoutes = data.stationRoutes;  
255 -  
256 - var htmlStr = template('add_toAndFro_sch-form-temp', sch);  
257 - $(wrap).append(htmlStr);  
258 - //字典转换  
259 - dictionaryUtils.transformDom($('.nt-dictionary', wrap));  
260 - //validation  
261 - $('.add-sch-form', wrap).formValidation({framework: 'uikit', locale: 'zh_CN'}).trigger('init-autoCom');  
262 - $('.add-sch-form [name=bcType]', wrap).trigger('change');  
263 -  
264 - f1 = $('.add-sch-form.one_form', wrap);  
265 - f2 = $('.add-sch-form.two_form', wrap);  
266 -  
267 - //默认1备注同步到2  
268 - $f('remarks', f1).on('input', function () {  
269 - $f('remarks', f2).val($(this).val());  
270 - });  
271 - //默认1备注同步到2  
272 - $('.remarks-autocom', f1).on('selectitem.uk.autocomplete', function (e, data, acobject) {  
273 - $f('remarks', f2).val(data.value);  
274 - });  
275 -  
276 - //人车级联  
277 - $f('clZbh',f1).on('input change', function () {  
278 - $f('clZbh', f2).val($(this).val());  
279 - });  
280 - $f('jsy',f1).on('input change', function () {  
281 - $f('jsy', f2).val($(this).val());  
282 - });  
283 - $f('spy',f1).on('input change', function () {  
284 - $f('spy', f2).val($(this).val());  
285 - });  
286 - //表单同步  
287 - $(f1).on('ct_callback', synchroFormData).trigger('ct_callback');  
288 - //修改1结束时间  
289 - $f('zdsj',f1).on('input', synchroFormData);  
290 - $('.ct_line_lp_badge', wrap).html(sch.xlName + ',&nbsp;'+sch.lpName);  
291 -  
292 - //表单校验提交相关  
293 - var dataArray;  
294 - var fs = $('.add-sch-form', wrap);  
295 - fs.on('success.form.fv', function (e) {  
296 - e.preventDefault();  
297 - dataArray.push($(this).serializeJSON());  
298 - $(this).data('valid', true);  
299 - if (allValidSuccess()) {  
300 - //开始post  
301 - var i = 0;  
302 - var inArr = [];  
303 - var upArr = [];  
304 - (function () {  
305 - var f = arguments.callee;  
306 - if (i >= dataArray.length) {  
307 - //前端数据更新  
308 - var last = inArr.pop();  
309 - gb_schedule_table.insertSchedule(last, upArr);  
310 - $('#schedule-lj_zrw-modal .main-schedule-table').trigger('refresh', {sch: last});  
311 -  
312 - try {  
313 - if(last.bcType=='in' || last.bcType=='out')  
314 - gb_data_basic.reload_stat_park_data();  
315 - }catch (e){  
316 - console.log(e);}  
317 - UIkit.modal('#schedule-addsch-modal').hide();  
318 - //更新路牌公里统计面板  
319 - gb_schedule_table.showLpMileageTipBySch(last);  
320 - return;  
321 - }  
322 - submitFun(dataArray[i], function (rs) {  
323 - inArr.push(rs.t);  
324 - upArr = upArr.concat(rs.ts);  
325 - upArr.push(rs.t);  
326 - i++;  
327 - f();  
328 - }, function () {  
329 - $('[type=submit]', wrap).removeClass('disabled').removeAttr('disabled');  
330 - });  
331 - })();  
332 - }  
333 - });  
334 - //提交  
335 - $('[type=submit]', wrap).on('click', function () {  
336 - $(this).addClass('disabled').attr('disabled', 'disabled');  
337 - dataArray = [];  
338 - fs.data('valid', false);  
339 - fs.formValidation('validate');  
340 - });  
341 - });  
342 -  
343 - function $f(name, f) {  
344 - return $('[name=' + name + ']', f);  
345 - }  
346 -  
347 - function allValidSuccess() {  
348 - var flag = true;  
349 - $('form.add-sch-form:visible', wrap).each(function (i, f) {  
350 - if (!$(f).data('valid')) {  
351 - flag = false;  
352 - return false;  
353 - }  
354 - });  
355 - return flag;  
356 - }  
357 -  
358 - /**  
359 - * 同步2个表单的数据  
360 - */  
361 - var bcTypes = {'normal': 'normal', 'region': 'region', 'out': 'in', 'in': 'out'};  
362 - var synchroFormData = function () {  
363 - //同步班次类型  
364 - var type = $f('bcType', f1).val();  
365 - if (bcTypes[type])  
366 - $f('bcType', f2).val(bcTypes[type]).trigger('change');  
367 - var updown = $f('xlDir', f1).val();  
368 -  
369 - //1 结束时间 = 2 开始时间  
370 - $f('fcsj', f2).val($f('zdsj', f1).val());  
371 - if (type != 'out' && type != 'in') {  
372 - //走向  
373 - $f('xlDir', f2).val(updown == 0 ? 1 : 0).trigger('change');  
374 -  
375 - //第一个表单终点 = 第二个起点  
376 - var oneZdName = $('[name=zdzCode] option:selected', f1).text();  
377 - $f('qdzCode', f2).val(searchParallelStation(oneZdName, updown == 0 ? 1 : 0));  
378 - //第一个表单起点 = 第二个终点  
379 - var oneQdName = $('[name=qdzCode] option:selected', f1).text();  
380 - $f('zdzCode', f2).val(searchParallelStation(oneQdName, updown == 0 ? 1 : 0)).trigger('change');  
381 - }  
382 - else {  
383 - //进出场走向相同  
384 - $f('xlDir', f2).val(updown).trigger('change');  
385 - //第一个表单终点 = 第二个起点  
386 - $f('qdzCode', f2).val($f('zdzCode', f1).val());  
387 - //第一个表单起点 = 第二个终点  
388 - $f('zdzCode', f2).val($f('qdzCode', f1).val()).trigger('change');  
389 - }  
390 -  
391 - };  
392 -  
393 -  
394 - //返回另一个走向对应的站点  
395 - function searchParallelStation(stationName, updown) {  
396 - var routes = stationRoutes[updown]  
397 - , len = routes.length;  
398 -  
399 - for (var i = 0; i < len; i++) {  
400 - if (routes[i].stationName == stationName)  
401 - return routes[i].stationCode;  
402 - }  
403 - }  
404 - })(); 1 +<!-- 线路上往返临加班次 -->
  2 +<script id="add_toAndFro_sch-form-temp" type="text/html">
  3 + <form class="uk-form uk-form-horizontal add-sch-form one_form">
  4 + <div class="uk-grid">
  5 + <div class="uk-width-1-2">
  6 + <div class="uk-form-row">
  7 + <label class="uk-form-label">班次类型</label>
  8 + <div class="uk-form-controls">
  9 + <select class="form-control nt-dictionary" name="bcType" data-code="{{bcType}}"
  10 + data-group=ScheduleType></select>
  11 + </div>
  12 + </div>
  13 + </div>
  14 + <div class="uk-width-1-2">
  15 + <div class="uk-form-row">
  16 + <label class="uk-form-label">上下行</label>
  17 + <div class="uk-form-controls">
  18 + <select name="xlDir">
  19 + <option value="0">上行</option>
  20 + <option value="1">下行</option>
  21 + </select>
  22 + </div>
  23 + </div>
  24 + </div>
  25 + </div>
  26 + <div class="uk-grid">
  27 + <div class="uk-width-1-2">
  28 + <div class="uk-form-row">
  29 + <label class="uk-form-label">起点站</label>
  30 + <div class="uk-form-controls">
  31 + <select name="qdzCode" >
  32 + </select>
  33 + </div>
  34 + </div>
  35 + </div>
  36 + <div class="uk-width-1-2">
  37 + <div class="uk-form-row">
  38 + <label class="uk-form-label">终点站</label>
  39 + <div class="uk-form-controls">
  40 + <select name="zdzCode" >
  41 + </select>
  42 + </div>
  43 + </div>
  44 + </div>
  45 + </div>
  46 + <div class="uk-grid">
  47 + <div class="uk-width-1-2">
  48 + <div class="uk-form-row">
  49 + <label class="uk-form-label">开始时间</label>
  50 + <div class="uk-form-controls">
  51 + <input type="time" value="{{zdsj}}" name="fcsj" required>
  52 + </div>
  53 + </div>
  54 + </div>
  55 + <div class="uk-width-1-2">
  56 + <div class="uk-form-row">
  57 + <label class="uk-form-label">结束时间</label>
  58 + <div class="uk-form-controls">
  59 + <input type="time" name="zdsj" required>
  60 + </div>
  61 + </div>
  62 + </div>
  63 + </div>
  64 + <div class="uk-grid">
  65 + <div class="uk-width-1-2">
  66 + <div class="uk-form-row">
  67 + <label class="uk-form-label">车辆</label>
  68 + <div class="uk-form-controls">
  69 + <div class="uk-autocomplete uk-form car-autocom">
  70 + <input type="text" value="{{clZbh}}" name="clZbh" required>
  71 + </div>
  72 + </div>
  73 + </div>
  74 + </div>
  75 + <div class="uk-width-1-2">
  76 + <div class="uk-form-row">
  77 + <label class="uk-form-label">里程</label>
  78 + <div class="uk-form-controls">
  79 + <input type="text" name="jhlc" value="{{jhlc}}" max=400 data-fv-lessthan-inclusive="false"
  80 + required>
  81 + </div>
  82 + </div>
  83 + </div>
  84 + </div>
  85 + <div class="uk-grid">
  86 + <div class="uk-width-1-2">
  87 + <div class="uk-form-row">
  88 + <label class="uk-form-label">驾驶员</label>
  89 + <div class="uk-form-controls">
  90 + <div class="uk-autocomplete uk-form jsy-autocom">
  91 + <input type="text" value="{{jGh}}/{{jName}}" name="jsy" required>
  92 + </div>
  93 + </div>
  94 + </div>
  95 + </div>
  96 + <div class="uk-width-1-2">
  97 + <div class="uk-form-row">
  98 + <label class="uk-form-label">售票员</label>
  99 + <div class="uk-form-controls">
  100 + <div class="uk-autocomplete uk-form spy-autocom">
  101 + <input type="text" name="spy" value="{{sGh}}/{{sName}}">
  102 + </div>
  103 + </div>
  104 + </div>
  105 + </div>
  106 + </div>
  107 + <div class="uk-grid" style="display:none;">
  108 + <div class="uk-width-1-2">
  109 + <div class="uk-form-row">
  110 + <label class="uk-form-label">是否预设</label>
  111 + <div class="uk-form-controls">
  112 + <div class="uk-autocomplete uk-form">
  113 + <input type="checkbox" name="isPreRegion" value="1">
  114 + </div>
  115 + </div>
  116 + </div>
  117 + </div>
  118 + <div class="uk-width-1-2" id="regionId">
  119 + <div class="uk-form-row">
  120 + <label class="uk-form-label">预设区间</label>
  121 + <div class="uk-form-controls">
  122 + <div class="uk-autocomplete uk-form">
  123 + <select name="regionId">
  124 + </select>
  125 + </div>
  126 + </div>
  127 + </div>
  128 + </div>
  129 + </div>
  130 + <div class="uk-grid" style="display:none;">
  131 + <div class="uk-width-1-2">
  132 + <div class="uk-form-row">
  133 + <label class="uk-form-label">是否封站</label>
  134 + <div class="uk-form-controls">
  135 + <div class="uk-autocomplete uk-form">
  136 + <input type="checkbox" name="isBlock" value="1">
  137 + </div>
  138 + </div>
  139 + </div>
  140 + </div>
  141 + <div class="uk-width-1-2" id="blockStations">
  142 + <div class="uk-form-row">
  143 + <label class="uk-form-label">封锁站点</label>
  144 + <div class="uk-form-controls">
  145 + <div class="uk-autocomplete uk-form">
  146 + <select class="form-control" name="blockStations" multiple="multiple">
  147 + </select>
  148 + </div>
  149 + </div>
  150 + </div>
  151 + </div>
  152 + </div>
  153 + <div class="uk-grid">
  154 + <div class="uk-width-1-1">
  155 + <div class="uk-form-row">
  156 + <label class="uk-form-label">备注</label>
  157 + <div class="uk-form-controls">
  158 + <div class="uk-autocomplete uk-form remarks-autocom">
  159 + <input type="text" name="remarks">
  160 + </div>
  161 + </div>
  162 + </div>
  163 + </div>
  164 + </div>
  165 + </form>
  166 + <hr style="margin-top: 35px;">
  167 + <form class="uk-form uk-form-horizontal add-sch-form two_form">
  168 + <div class="uk-grid">
  169 + <div class="uk-width-1-2">
  170 + <div class="uk-form-row">
  171 + <label class="uk-form-label">班次类型</label>
  172 + <div class="uk-form-controls">
  173 + <select class="form-control nt-dictionary" name="bcType" data-code="{{bcType}}"
  174 + data-group=ScheduleType></select>
  175 + </div>
  176 + </div>
  177 + </div>
  178 + <div class="uk-width-1-2">
  179 + <div class="uk-form-row">
  180 + <label class="uk-form-label">上下行</label>
  181 + <div class="uk-form-controls">
  182 + <select name="xlDir">
  183 + <option value="0">上行</option>
  184 + <option value="1">下行</option>
  185 + </select>
  186 + </div>
  187 + </div>
  188 + </div>
  189 + </div>
  190 + <div class="uk-grid">
  191 + <div class="uk-width-1-2">
  192 + <div class="uk-form-row">
  193 + <label class="uk-form-label">起点站</label>
  194 + <div class="uk-form-controls">
  195 + <select name="qdzCode" >
  196 + </select>
  197 + </div>
  198 + </div>
  199 + </div>
  200 + <div class="uk-width-1-2">
  201 + <div class="uk-form-row">
  202 + <label class="uk-form-label">终点站</label>
  203 + <div class="uk-form-controls">
  204 + <select name="zdzCode" >
  205 + </select>
  206 + </div>
  207 + </div>
  208 + </div>
  209 + </div>
  210 + <div class="uk-grid">
  211 + <div class="uk-width-1-2">
  212 + <div class="uk-form-row">
  213 + <label class="uk-form-label">开始时间</label>
  214 + <div class="uk-form-controls">
  215 + <input type="time" value="{{zdsj}}" name="fcsj" required>
  216 + </div>
  217 + </div>
  218 + </div>
  219 + <div class="uk-width-1-2">
  220 + <div class="uk-form-row">
  221 + <label class="uk-form-label">结束时间</label>
  222 + <div class="uk-form-controls">
  223 + <input type="time" name="zdsj" required>
  224 + </div>
  225 + </div>
  226 + </div>
  227 + </div>
  228 + <div class="uk-grid">
  229 + <div class="uk-width-1-2">
  230 + <div class="uk-form-row">
  231 + <label class="uk-form-label">车辆</label>
  232 + <div class="uk-form-controls">
  233 + <div class="uk-autocomplete uk-form car-autocom">
  234 + <input type="text" value="{{clZbh}}" name="clZbh" required>
  235 + </div>
  236 + </div>
  237 + </div>
  238 + </div>
  239 + <div class="uk-width-1-2">
  240 + <div class="uk-form-row">
  241 + <label class="uk-form-label">里程</label>
  242 + <div class="uk-form-controls">
  243 + <input type="text" name="jhlc" value="{{jhlc}}" max=400 data-fv-lessthan-inclusive="false"
  244 + required>
  245 + </div>
  246 + </div>
  247 + </div>
  248 + </div>
  249 + <div class="uk-grid">
  250 + <div class="uk-width-1-2">
  251 + <div class="uk-form-row">
  252 + <label class="uk-form-label">驾驶员</label>
  253 + <div class="uk-form-controls">
  254 + <div class="uk-autocomplete uk-form jsy-autocom">
  255 + <input type="text" value="{{jGh}}/{{jName}}" name="jsy" required>
  256 + </div>
  257 + </div>
  258 + </div>
  259 + </div>
  260 + <div class="uk-width-1-2">
  261 + <div class="uk-form-row">
  262 + <label class="uk-form-label">售票员</label>
  263 + <div class="uk-form-controls">
  264 + <div class="uk-autocomplete uk-form spy-autocom">
  265 + <input type="text" name="spy" value="{{sGh}}/{{sName}}">
  266 + </div>
  267 + </div>
  268 + </div>
  269 + </div>
  270 + </div>
  271 + <div class="uk-grid" style="display:none;">
  272 + <div class="uk-width-1-2">
  273 + <div class="uk-form-row">
  274 + <label class="uk-form-label">是否预设</label>
  275 + <div class="uk-form-controls">
  276 + <div class="uk-autocomplete uk-form">
  277 + <input type="checkbox" name="isPreRegion">
  278 + </div>
  279 + </div>
  280 + </div>
  281 + </div>
  282 + <div class="uk-width-1-2" id="regionId">
  283 + <div class="uk-form-row">
  284 + <label class="uk-form-label">预设区间</label>
  285 + <div class="uk-form-controls">
  286 + <div class="uk-autocomplete uk-form">
  287 + <select name="regionId">
  288 + </select>
  289 + </div>
  290 + </div>
  291 + </div>
  292 + </div>
  293 + </div>
  294 + <div class="uk-grid" style="display:none;">
  295 + <div class="uk-width-1-2">
  296 + <div class="uk-form-row">
  297 + <label class="uk-form-label">是否封站</label>
  298 + <div class="uk-form-controls">
  299 + <div class="uk-autocomplete uk-form">
  300 + <input type="checkbox" name="isBlock" value="1">
  301 + </div>
  302 + </div>
  303 + </div>
  304 + </div>
  305 + <div class="uk-width-1-2" id="blockStations">
  306 + <div class="uk-form-row">
  307 + <label class="uk-form-label">封锁站点</label>
  308 + <div class="uk-form-controls">
  309 + <div class="uk-autocomplete uk-form">
  310 + <select class="form-control" name="blockStations" multiple="multiple">
  311 + </select>
  312 + </div>
  313 + </div>
  314 + </div>
  315 + </div>
  316 + </div>
  317 + <div class="uk-grid">
  318 + <div class="uk-width-1-1">
  319 + <div class="uk-form-row">
  320 + <label class="uk-form-label">备注</label>
  321 + <div class="uk-form-controls">
  322 + <div class="uk-autocomplete uk-form remarks-autocom">
  323 + <input type="text" name="remarks">
  324 + </div>
  325 + </div>
  326 + </div>
  327 + </div>
  328 + </div>
  329 + </form>
  330 +
  331 + <div class="uk-modal-footer uk-text-right" style="margin-bottom: -20px;">
  332 + <span class="ct_line_lp_badge" ></span>
  333 + <button type="button" class="uk-button uk-modal-close">取消</button>
  334 + <button type="submit" class="uk-button uk-button-primary"><i class="uk-icon-check"></i> &nbsp;保存</button>
  335 + </div>
  336 +</script>
  337 +
  338 +<script>
  339 + (function () {
  340 + var wrap = '#schedule-addsch-modal .toAndFroCont', sch, f1, f2, submitFun, stationRoutes;
  341 +
  342 + $(wrap).on('init', function (e, data) {
  343 + e.stopPropagation();
  344 + sch = data.sch;
  345 + submitFun = data.submitFun;
  346 + stationRoutes = data.stationRoutes;
  347 +
  348 + var htmlStr = template('add_toAndFro_sch-form-temp', sch);
  349 + $(wrap).append(htmlStr);
  350 + //字典转换
  351 + dictionaryUtils.transformDom($('.nt-dictionary', wrap));
  352 + //validation
  353 + $('.add-sch-form', wrap).formValidation({framework: 'uikit', locale: 'zh_CN'}).trigger('init-autoCom');
  354 + $('.add-sch-form [name=bcType]', wrap).trigger('change');
  355 +
  356 + f1 = $('.add-sch-form.one_form', wrap);
  357 + f2 = $('.add-sch-form.two_form', wrap);
  358 +
  359 + //默认1备注同步到2
  360 + $f('remarks', f1).on('input', function () {
  361 + $f('remarks', f2).val($(this).val());
  362 + });
  363 + //默认1备注同步到2
  364 + $('.remarks-autocom', f1).on('selectitem.uk.autocomplete', function (e, data, acobject) {
  365 + $f('remarks', f2).val(data.value);
  366 + });
  367 +
  368 + //人车级联
  369 + $f('clZbh',f1).on('input change', function () {
  370 + $f('clZbh', f2).val($(this).val());
  371 + });
  372 + $f('jsy',f1).on('input change', function () {
  373 + $f('jsy', f2).val($(this).val());
  374 + });
  375 + $f('spy',f1).on('input change', function () {
  376 + $f('spy', f2).val($(this).val());
  377 + });
  378 + //表单同步
  379 + $(f1).on('ct_callback', synchroFormData).trigger('ct_callback');
  380 + //修改1结束时间
  381 + $f('zdsj',f1).on('input', synchroFormData);
  382 + $('.ct_line_lp_badge', wrap).html(sch.xlName + ',&nbsp;'+sch.lpName);
  383 +
  384 + //表单校验提交相关
  385 + var dataArray;
  386 + var fs = $('.add-sch-form', wrap);
  387 + fs.on('success.form.fv', function (e) {
  388 + e.preventDefault();
  389 + changeStationSelectStatus(true);
  390 + var data = $(this).serializeJSON();
  391 + var blockStations = $('[name=blockStations]', $(this)).val();
  392 + data.blockStations = blockStations ? blockStations.join(',') : null;
  393 + dataArray.push(data);
  394 + $(this).data('valid', true);
  395 + if (allValidSuccess()) {
  396 + //开始post
  397 + var i = 0;
  398 + var inArr = [];
  399 + var upArr = [];
  400 + (function () {
  401 + var f = arguments.callee;
  402 + if (i >= dataArray.length) {
  403 + //前端数据更新
  404 + var last = inArr.pop();
  405 + gb_schedule_table.insertSchedule(last, upArr);
  406 + $('#schedule-lj_zrw-modal .main-schedule-table').trigger('refresh', {sch: last});
  407 +
  408 + try {
  409 + if(last.bcType=='in' || last.bcType=='out')
  410 + gb_data_basic.reload_stat_park_data();
  411 + }catch (e){
  412 + console.log(e);}
  413 + UIkit.modal('#schedule-addsch-modal').hide();
  414 + //更新路牌公里统计面板
  415 + gb_schedule_table.showLpMileageTipBySch(last);
  416 + return;
  417 + }
  418 + submitFun(dataArray[i], function (rs) {
  419 + inArr.push(rs.t);
  420 + upArr = upArr.concat(rs.ts);
  421 + upArr.push(rs.t);
  422 + i++;
  423 + f();
  424 + }, function () {
  425 + $('[type=submit]', wrap).removeClass('disabled').removeAttr('disabled');
  426 + });
  427 + })();
  428 + changeStationSelectStatus(false);
  429 + }
  430 + });
  431 + //提交
  432 + $('[type=submit]', wrap).on('click', function () {
  433 + $(this).addClass('disabled').attr('disabled', 'disabled');
  434 + dataArray = [];
  435 + fs.data('valid', false);
  436 + fs.formValidation('validate');
  437 + });
  438 + });
  439 +
  440 + function $f(name, f) {
  441 + return $('[name=' + name + ']', f);
  442 + }
  443 +
  444 + function allValidSuccess() {
  445 + var flag = true;
  446 + $('form.add-sch-form:visible', wrap).each(function (i, f) {
  447 + if (!$(f).data('valid')) {
  448 + flag = false;
  449 + return false;
  450 + }
  451 + });
  452 + return flag;
  453 + }
  454 +
  455 + /**
  456 + * 同步2个表单的数据
  457 + */
  458 + var bcTypes = {'normal': 'normal', 'region': 'region', 'out': 'in', 'in': 'out'};
  459 + var synchroFormData = function () {
  460 + //同步班次类型
  461 + var type = $f('bcType', f1).val();
  462 + if (bcTypes[type])
  463 + $f('bcType', f2).val(bcTypes[type]).trigger('change');
  464 + var updown = $f('xlDir', f1).val();
  465 +
  466 + //1 结束时间 = 2 开始时间
  467 + $f('fcsj', f2).val($f('zdsj', f1).val());
  468 + if (type != 'out' && type != 'in') {
  469 + //走向
  470 + $f('xlDir', f2).val(updown == 0 ? 1 : 0).trigger('change');
  471 +
  472 + //第一个表单终点 = 第二个起点
  473 + var oneZdName = $('[name=zdzCode] option:selected', f1).text();
  474 + $f('qdzCode', f2).val(searchParallelStation(oneZdName, updown == 0 ? 1 : 0));
  475 + //第一个表单起点 = 第二个终点
  476 + var oneQdName = $('[name=qdzCode] option:selected', f1).text();
  477 + $f('zdzCode', f2).val(searchParallelStation(oneQdName, updown == 0 ? 1 : 0)).trigger('change');
  478 + }
  479 + else {
  480 + //进出场走向相同
  481 + $f('xlDir', f2).val(updown).trigger('change');
  482 + //第一个表单终点 = 第二个起点
  483 + $f('qdzCode', f2).val($f('zdzCode', f1).val());
  484 + //第一个表单起点 = 第二个终点
  485 + $f('zdzCode', f2).val($f('qdzCode', f1).val()).trigger('change');
  486 + }
  487 +
  488 + };
  489 +
  490 +
  491 + //返回另一个走向对应的站点
  492 + function searchParallelStation(stationName, updown) {
  493 + var routes = stationRoutes[updown]
  494 + , len = routes.length;
  495 +
  496 + for (var i = 0; i < len; i++) {
  497 + if (routes[i].stationName == stationName)
  498 + return routes[i].stationCode;
  499 + }
  500 + }
  501 +
  502 + function changeStationSelectStatus(flag) {
  503 + $('[name=qdzCode],[name=zdzCode]').prop('disabled', !flag);
  504 + }
  505 + })();
405 </script> 506 </script>
406 \ No newline at end of file 507 \ No newline at end of file
src/main/resources/static/real_control_v2/fragments/line_schedule/context_menu/temp_sch/main.html
@@ -25,7 +25,7 @@ @@ -25,7 +25,7 @@
25 <script> 25 <script>
26 (function () { 26 (function () {
27 var modal = '#schedule-addsch-modal', 27 var modal = '#schedule-addsch-modal',
28 - sch, stationRoutes, parks, information, carsArray, st_park_data; 28 + sch, stationRoutes, parks, information, carsArray, st_park_data, lineRegion = {};
29 29
30 $(modal).on('init', function (e, data) { 30 $(modal).on('init', function (e, data) {
31 e.stopPropagation(); 31 e.stopPropagation();
@@ -57,6 +57,31 @@ @@ -57,6 +57,31 @@
57 //park to park 57 //park to park
58 $('.parkToParkCont', modal).html(st_doms.park_to_park_dom) 58 $('.parkToParkCont', modal).html(st_doms.park_to_park_dom)
59 .trigger('init', {sch: sch, submitFun: submit_temp_schedule_form, parks: parks, carsArray: carsArray}); 59 .trigger('init', {sch: sch, submitFun: submit_temp_schedule_form, parks: parks, carsArray: carsArray});
  60 +
  61 + gb_common.$get('/api/lineregion/all', {line_eq: sch.xlBm, version_eq: gb_data_basic.getLineCurrentVersion(sch.xlBm), direction_eq: 0}, function(regions) {
  62 + var opts = new Array();
  63 + opts.push('<option value="">选择预设区间</option>');
  64 + for (var idx in regions) {
  65 + var item = regions[idx], title = new Array();
  66 + lineRegion[item.id + '_' + item.seq] = item;
  67 + if (item.stationRoutes.length > 1) {
  68 + for (var idx1 in item.stationRoutes) {
  69 + title.push(item.stationRoutes[idx1].stationName);
  70 + }
  71 + }
  72 + opts.push('<option value="', item.id, '_', item.seq);
  73 + if (title.length > 0) {
  74 + opts.push('" title="', title.join('\n'))
  75 + }
  76 + opts.push('">', item.regionAlias, '</option>')
  77 + }
  78 + $('.add-sch-form [name=regionId]').html(opts.join(''));
  79 + $('[name=isPreRegion]', modal).on('change', isPreRegionChangeHandle).trigger('change');
  80 + $('[name=regionId]', modal).on('change', regionIdChangeHandle);
  81 + $('[name=isBlock]', modal).on('change', isBlockChangeHandle).trigger('change');
  82 + $('[name=blockStations]', modal).multipleSelect();
  83 + $('.add-sch-form.two_form [name=xlDir]').trigger('change');
  84 + })
60 }); 85 });
61 86
62 //init-autoCom 87 //init-autoCom
@@ -72,6 +97,8 @@ @@ -72,6 +97,8 @@
72 gb_common.remarksAutocomplete($('.remarks-autocom', this)); 97 gb_common.remarksAutocomplete($('.remarks-autocom', this));
73 }); 98 });
74 99
  100 + //上下行 切换事件
  101 + $(modal).on('change', '.add-sch-form [name=xlDir]', reCalcLineRegion);
75 //班次类型 和 上下行 切换事件 102 //班次类型 和 上下行 切换事件
76 $(modal).on('change', '.add-sch-form [name=bcType],.add-sch-form [name=xlDir]', reCalcInputs_type); 103 $(modal).on('change', '.add-sch-form [name=bcType],.add-sch-form [name=xlDir]', reCalcInputs_type);
77 //起终点站改变事件 104 //起终点站改变事件
@@ -79,6 +106,28 @@ @@ -79,6 +106,28 @@
79 //开始时间和公里改变 106 //开始时间和公里改变
80 $(modal).on('input', '.add-sch-form [name=fcsj],.add-sch-form [name=jhlc]', reCalcEndTime); 107 $(modal).on('input', '.add-sch-form [name=fcsj],.add-sch-form [name=jhlc]', reCalcEndTime);
81 108
  109 + function reCalcLineRegion() {
  110 + var f = $(this).parents('.add-sch-form'), xlDir = $('[name=xlDir]', f).val();
  111 + gb_common.$get('/api/lineregion/all', {line_eq: sch.xlBm, version_eq: gb_data_basic.getLineCurrentVersion(sch.xlBm), direction_eq: xlDir}, function(regions) {
  112 + var opts = new Array();
  113 + opts.push('<option value="">选择预设区间</option>');
  114 + for (var idx in regions) {
  115 + var item = regions[idx], title = new Array();
  116 + lineRegion[item.id + '_' + item.seq] = item;
  117 + if (item.stationRoutes.length > 1) {
  118 + for (var idx1 in item.stationRoutes) {
  119 + title.push(item.stationRoutes[idx1].stationName);
  120 + }
  121 + }
  122 + opts.push('<option value="', item.id, '_', item.seq);
  123 + if (title.length > 0) {
  124 + opts.push('" title="', title.join('\n'))
  125 + }
  126 + opts.push('">', item.regionAlias, '</option>')
  127 + }
  128 + $('[name=regionId]', f).html(opts.join(''));
  129 + })
  130 + }
82 131
83 function reCalcInputs_type() { 132 function reCalcInputs_type() {
84 var f = $(this).parents('.add-sch-form'); 133 var f = $(this).parents('.add-sch-form');
@@ -96,7 +145,7 @@ @@ -96,7 +145,7 @@
96 for(var i=0,p;p=parks[i++];) 145 for(var i=0,p;p=parks[i++];)
97 park_opts += '<option value="' + p.code + '">' + p.name + '</option>'; 146 park_opts += '<option value="' + p.code + '">' + p.name + '</option>';
98 147
99 - var qdz = $('[name=qdzCode]', f), zdz = $('[name=zdzCode]', f); 148 + var qdz = $('[name=qdzCode]', f), zdz = $('[name=zdzCode]', f), blockStations = $('[name=blockStations]', f);
100 //var time, mileage; 149 //var time, mileage;
101 switch (bcType_e.val()) { 150 switch (bcType_e.val()) {
102 case 'out': 151 case 'out':
@@ -111,6 +160,7 @@ @@ -111,6 +160,7 @@
111 qdz.html(opts); 160 qdz.html(opts);
112 zdz.html(opts).val(lastCode); 161 zdz.html(opts).val(lastCode);
113 } 162 }
  163 + blockStations.html(opts);
114 164
115 zdz.trigger('change'); 165 zdz.trigger('change');
116 f.trigger('ct_callback'); 166 f.trigger('ct_callback');
@@ -207,6 +257,49 @@ @@ -207,6 +257,49 @@
207 f.trigger('ct_callback'); 257 f.trigger('ct_callback');
208 } 258 }
209 259
  260 + function isPreRegionChangeHandle() {
  261 + var checked = $(this).is(':checked'),
  262 + f = $(this).parents('.add-sch-form'),
  263 + bcType = $('[name=bcType]', f),
  264 + qdzCode = $('[name=qdzCode]', f),
  265 + zdzCode = $('[name=zdzCode]', f),
  266 + regionId = $('#regionId', f);
  267 + if (checked) {
  268 + bcType.val('region');
  269 + qdzCode.prop('disabled', true);
  270 + zdzCode.prop('disabled', true);
  271 + regionId.show();
  272 + } else {
  273 + qdzCode.prop('disabled', false);
  274 + zdzCode.prop('disabled', false);
  275 + regionId.hide();
  276 + }
  277 + }
  278 +
  279 + function regionIdChangeHandle() {
  280 + var f = $(this).parents('.add-sch-form'),
  281 + qdzCode = $('[name=qdzCode]', f),
  282 + zdzCode = $('[name=zdzCode]', f),
  283 + regionId = $(this).val();
  284 + if (!regionId) return;
  285 + var stationRoutes = lineRegion[regionId].stationRoutes;
  286 + if (stationRoutes && stationRoutes.length > 1) {
  287 + qdzCode.val(stationRoutes[0].stationCode);
  288 + zdzCode.val(stationRoutes[stationRoutes.length - 1].stationCode);
  289 + }
  290 + }
  291 +
  292 + function isBlockChangeHandle() {
  293 + var checked = $(this).is(':checked'),
  294 + f = $(this).parents('.add-sch-form'),
  295 + blockStations = $('#blockStations', f);
  296 + if (checked) {
  297 + blockStations.show();
  298 + } else {
  299 + blockStations.hide();
  300 + }
  301 + }
  302 +
210 function is_normal_sch(f) { 303 function is_normal_sch(f) {
211 var qdzCode = $('[name=qdzCode]', f).val(), 304 var qdzCode = $('[name=qdzCode]', f).val(),
212 zdzCode =$('[name=zdzCode]', f).val(), 305 zdzCode =$('[name=zdzCode]', f).val(),
@@ -320,6 +413,12 @@ @@ -320,6 +413,12 @@
320 data.jGh = data.jsy.split('/')[0]; 413 data.jGh = data.jsy.split('/')[0];
321 data.jName = data.jsy.split('/')[1]; 414 data.jName = data.jsy.split('/')[1];
322 delete data.jsy; 415 delete data.jsy;
  416 + if (!data.isPreRegion) {
  417 + delete data.regionId;
  418 + }
  419 + if (!data.isBlock) {
  420 + delete data.blockStations;
  421 + }
323 //拆分售票员工号和姓名 422 //拆分售票员工号和姓名
324 if (data.spy != '') { 423 if (data.spy != '') {
325 data.sGh = data.spy.split('/')[0]; 424 data.sGh = data.spy.split('/')[0];
src/main/resources/static/real_control_v2/fragments/line_schedule/context_menu/temp_sch_v2/add_normal.html
1 -<!-- 临加班次form -->  
2 -<script id="add_normal_sch-form-temp" type="text/html">  
3 - <form class="uk-form uk-form-horizontal add-sch-form">  
4 - <div class="uk-grid">  
5 - <div class="uk-width-1-2">  
6 - <div class="uk-form-row">  
7 - <label class="uk-form-label">班次类型</label>  
8 - <div class="uk-form-controls">  
9 - <select class="form-control nt-dictionary" name="bcType" data-code="{{bcType}}"  
10 - data-group=ScheduleType></select>  
11 - </div>  
12 - </div>  
13 - </div>  
14 - <div class="uk-width-1-2">  
15 - <div class="uk-form-row">  
16 - <label class="uk-form-label">上下行</label>  
17 - <div class="uk-form-controls">  
18 - <select name="xlDir">  
19 - <option value="0">上行</option>  
20 - <option value="1">下行</option>  
21 - </select>  
22 - </div>  
23 - </div>  
24 - </div>  
25 - </div>  
26 - <div class="uk-grid">  
27 - <div class="uk-width-1-2">  
28 - <div class="uk-form-row">  
29 - <label class="uk-form-label">起点站</label>  
30 - <div class="uk-form-controls">  
31 - <select name="qdzCode">  
32 - </select>  
33 - </div>  
34 - </div>  
35 - </div>  
36 - <div class="uk-width-1-2">  
37 - <div class="uk-form-row">  
38 - <label class="uk-form-label">终点站</label>  
39 - <div class="uk-form-controls">  
40 - <select name="zdzCode">  
41 - </select>  
42 - </div>  
43 - </div>  
44 - </div>  
45 - </div>  
46 - <div class="uk-grid">  
47 - <div class="uk-width-1-2">  
48 - <div class="uk-form-row">  
49 - <label class="uk-form-label">开始时间</label>  
50 - <div class="uk-form-controls">  
51 - <input type="time" value="{{zdsjActual==null?zdsj:zdsjActual}}" name="fcsj" required>  
52 - </div>  
53 - </div>  
54 - </div>  
55 - <div class="uk-width-1-2">  
56 - <div class="uk-form-row">  
57 - <label class="uk-form-label">结束时间</label>  
58 - <div class="uk-form-controls">  
59 - <input type="time" name="zdsj" required>  
60 - </div>  
61 - </div>  
62 - </div>  
63 - </div>  
64 - <div class="uk-grid">  
65 - <div class="uk-width-1-2">  
66 - <div class="uk-form-row">  
67 - <label class="uk-form-label">车辆</label>  
68 - <div class="uk-form-controls">  
69 - <div class="uk-autocomplete uk-form car-autocom">  
70 - <input type="text" value="{{clZbh}}" name="clZbh" required>  
71 - </div>  
72 - </div>  
73 - </div>  
74 - </div>  
75 - <div class="uk-width-1-2">  
76 - <div class="uk-form-row">  
77 - <label class="uk-form-label">里程</label>  
78 - <div class="uk-form-controls">  
79 - <input type="text" name="jhlc" value="{{jhlc}}" max=400 data-fv-lessthan-inclusive="false"  
80 - required>  
81 - </div>  
82 - </div>  
83 - </div>  
84 - </div>  
85 - <div class="uk-grid">  
86 - <div class="uk-width-1-2">  
87 - <div class="uk-form-row">  
88 - <label class="uk-form-label">驾驶员</label>  
89 - <div class="uk-form-controls">  
90 - <div class="uk-autocomplete uk-form jsy-autocom">  
91 - <input type="text" value="{{jGh}}/{{jName}}" name="jsy" required>  
92 - </div>  
93 - </div>  
94 - </div>  
95 - </div>  
96 - <div class="uk-width-1-2">  
97 - <div class="uk-form-row">  
98 - <label class="uk-form-label">售票员</label>  
99 - <div class="uk-form-controls">  
100 - <div class="uk-autocomplete uk-form spy-autocom">  
101 - <input type="text" name="spy" value="{{sGh}}/{{sName}}">  
102 - </div>  
103 - </div>  
104 - </div>  
105 - </div>  
106 - </div>  
107 - <div class="uk-grid">  
108 - <div class="uk-width-1-2">  
109 - <div class="uk-form-row">  
110 - <label class="uk-form-label">路牌</label>  
111 - <div class="uk-form-controls">  
112 - <input type="text" value="{{lpName}}" name="lpName" required>  
113 - </div>  
114 - </div>  
115 - </div>  
116 - </div>  
117 - <div class="uk-grid">  
118 - <div class="uk-width-1-1">  
119 - <div class="uk-form-row">  
120 - <label class="uk-form-label">备注</label>  
121 - <div class="uk-form-controls">  
122 - <div class="uk-autocomplete uk-form remarks-autocom">  
123 - <input type="text" name="remarks">  
124 - </div>  
125 - </div>  
126 - </div>  
127 - </div>  
128 - </div>  
129 - <div class="uk-modal-footer uk-text-right" style="margin-bottom: -20px;">  
130 - <button type="button" class="uk-button uk-modal-close">取消</button>  
131 - <button type="submit" class="uk-button uk-button-primary"><i class="uk-icon-check"></i> &nbsp;保存  
132 - </button>  
133 - </div>  
134 - </form>  
135 -</script>  
136 -<script>  
137 - (function () {  
138 - var wrap = '#schedule-addsch-modal .normalCont', sch, nf, submitFun;  
139 -  
140 - $(wrap).on('init', function (e, data) {  
141 - e.stopPropagation();  
142 - sch = data.sch;  
143 - submitFun = data.submitFun;  
144 -  
145 - nf = addForm();  
146 - //提交  
147 - nf.on('success.form.fv', function (e) {  
148 - e.preventDefault();  
149 -  
150 - disabled_submit_btn(nf);  
151 - var data = nf.serializeJSON();  
152 - submitFun(data, function (rs) {  
153 - //前端数据更新  
154 - gb_schedule_table.insertSchedule(rs.t, rs.ts);  
155 - $('#schedule-lj_zrw-modal .main-schedule-table').trigger('refresh', {sch: rs.t});  
156 - try {  
157 - if(rs.t.bcType=='in' || rs.t.bcType=='out')  
158 - gb_data_basic.reload_stat_park_data();  
159 - }catch (e){  
160 - console.log(e);}  
161 - UIkit.modal('#schedule-addsch-modal').hide();  
162 - //更新路牌公里统计面板  
163 - gb_schedule_table.showLpMileageTipBySch(rs.t);  
164 - }, function () {  
165 - enable_submit_btn(nf);  
166 - });  
167 - });  
168 - });  
169 -  
170 - function addForm() {  
171 - var htmlStr = template('add_normal_sch-form-temp', sch);  
172 - var f = $(htmlStr);  
173 - $(wrap).append(f);  
174 - //字典转换  
175 - dictionaryUtils.transformDom($('.nt-dictionary', f));  
176 - //validation  
177 - f.formValidation({framework: 'uikit', locale: 'zh_CN'});  
178 - //autocomp  
179 - f.trigger('init-autoCom');  
180 -  
181 - $f('bcType', f).trigger('change');  
182 - return f;  
183 - }  
184 -  
185 - function $f(name, f) {  
186 - return $('[name=' + name + ']', f);  
187 - }  
188 - })(); 1 +<!-- 临加班次form -->
  2 +<script id="add_normal_sch-form-temp-v2" type="text/html">
  3 + <form class="uk-form uk-form-horizontal add-sch-form">
  4 + <div class="uk-grid">
  5 + <div class="uk-width-1-2">
  6 + <div class="uk-form-row">
  7 + <label class="uk-form-label">班次类型</label>
  8 + <div class="uk-form-controls">
  9 + <select class="form-control nt-dictionary" name="bcType" data-code="{{bcType}}"
  10 + data-group=ScheduleType></select>
  11 + </div>
  12 + </div>
  13 + </div>
  14 + <div class="uk-width-1-2">
  15 + <div class="uk-form-row">
  16 + <label class="uk-form-label">上下行</label>
  17 + <div class="uk-form-controls">
  18 + <select name="xlDir">
  19 + <option value="0">上行</option>
  20 + <option value="1">下行</option>
  21 + </select>
  22 + </div>
  23 + </div>
  24 + </div>
  25 + </div>
  26 + <div class="uk-grid">
  27 + <div class="uk-width-1-2">
  28 + <div class="uk-form-row">
  29 + <label class="uk-form-label">起点站</label>
  30 + <div class="uk-form-controls">
  31 + <select name="qdzCode">
  32 + </select>
  33 + </div>
  34 + </div>
  35 + </div>
  36 + <div class="uk-width-1-2">
  37 + <div class="uk-form-row">
  38 + <label class="uk-form-label">终点站</label>
  39 + <div class="uk-form-controls">
  40 + <select name="zdzCode">
  41 + </select>
  42 + </div>
  43 + </div>
  44 + </div>
  45 + </div>
  46 + <div class="uk-grid">
  47 + <div class="uk-width-1-2">
  48 + <div class="uk-form-row">
  49 + <label class="uk-form-label">开始时间</label>
  50 + <div class="uk-form-controls">
  51 + <input type="time" value="{{zdsjActual==null?zdsj:zdsjActual}}" name="fcsj" required>
  52 + </div>
  53 + </div>
  54 + </div>
  55 + <div class="uk-width-1-2">
  56 + <div class="uk-form-row">
  57 + <label class="uk-form-label">结束时间</label>
  58 + <div class="uk-form-controls">
  59 + <input type="time" name="zdsj" required>
  60 + </div>
  61 + </div>
  62 + </div>
  63 + </div>
  64 + <div class="uk-grid">
  65 + <div class="uk-width-1-2">
  66 + <div class="uk-form-row">
  67 + <label class="uk-form-label">车辆</label>
  68 + <div class="uk-form-controls">
  69 + <div class="uk-autocomplete uk-form car-autocom">
  70 + <input type="text" value="{{clZbh}}" name="clZbh" required>
  71 + </div>
  72 + </div>
  73 + </div>
  74 + </div>
  75 + <div class="uk-width-1-2">
  76 + <div class="uk-form-row">
  77 + <label class="uk-form-label">里程</label>
  78 + <div class="uk-form-controls">
  79 + <input type="text" name="jhlc" value="{{jhlc}}" max=400 data-fv-lessthan-inclusive="false"
  80 + required>
  81 + </div>
  82 + </div>
  83 + </div>
  84 + </div>
  85 + <div class="uk-grid">
  86 + <div class="uk-width-1-2">
  87 + <div class="uk-form-row">
  88 + <label class="uk-form-label">驾驶员</label>
  89 + <div class="uk-form-controls">
  90 + <div class="uk-autocomplete uk-form jsy-autocom">
  91 + <input type="text" value="{{jGh}}/{{jName}}" name="jsy" required>
  92 + </div>
  93 + </div>
  94 + </div>
  95 + </div>
  96 + <div class="uk-width-1-2">
  97 + <div class="uk-form-row">
  98 + <label class="uk-form-label">售票员</label>
  99 + <div class="uk-form-controls">
  100 + <div class="uk-autocomplete uk-form spy-autocom">
  101 + <input type="text" name="spy" value="{{sGh}}/{{sName}}">
  102 + </div>
  103 + </div>
  104 + </div>
  105 + </div>
  106 + </div>
  107 + <div class="uk-grid" style="display:none;">
  108 + <div class="uk-width-1-2">
  109 + <div class="uk-form-row">
  110 + <label class="uk-form-label">是否预设</label>
  111 + <div class="uk-form-controls">
  112 + <div class="uk-autocomplete uk-form">
  113 + <input type="checkbox" name="isPreRegion" value="1">
  114 + </div>
  115 + </div>
  116 + </div>
  117 + </div>
  118 + <div class="uk-width-1-2" id="regionId">
  119 + <div class="uk-form-row">
  120 + <label class="uk-form-label">预设区间</label>
  121 + <div class="uk-form-controls">
  122 + <div class="uk-autocomplete uk-form">
  123 + <select name="regionId">
  124 + </select>
  125 + </div>
  126 + </div>
  127 + </div>
  128 + </div>
  129 + </div>
  130 + <div class="uk-grid" style="display:none;">
  131 + <div class="uk-width-1-2">
  132 + <div class="uk-form-row">
  133 + <label class="uk-form-label">是否封站</label>
  134 + <div class="uk-form-controls">
  135 + <div class="uk-autocomplete uk-form">
  136 + <input type="checkbox" name="isBlock" value="1">
  137 + </div>
  138 + </div>
  139 + </div>
  140 + </div>
  141 + <div class="uk-width-1-2" id="blockStations">
  142 + <div class="uk-form-row">
  143 + <label class="uk-form-label">封锁站点</label>
  144 + <div class="uk-form-controls">
  145 + <div class="uk-autocomplete uk-form">
  146 + <select class="form-control" name="blockStations" multiple="multiple">
  147 + </select>
  148 + </div>
  149 + </div>
  150 + </div>
  151 + </div>
  152 + </div>
  153 + <div class="uk-grid">
  154 + <div class="uk-width-1-2">
  155 + <div class="uk-form-row">
  156 + <label class="uk-form-label">路牌</label>
  157 + <div class="uk-form-controls">
  158 + <input type="text" value="{{lpName}}" name="lpName" required>
  159 + </div>
  160 + </div>
  161 + </div>
  162 + </div>
  163 + <div class="uk-grid">
  164 + <div class="uk-width-1-1">
  165 + <div class="uk-form-row">
  166 + <label class="uk-form-label">备注</label>
  167 + <div class="uk-form-controls">
  168 + <div class="uk-autocomplete uk-form remarks-autocom">
  169 + <input type="text" name="remarks">
  170 + </div>
  171 + </div>
  172 + </div>
  173 + </div>
  174 + </div>
  175 + <div class="uk-modal-footer uk-text-right" style="margin-bottom: -20px;">
  176 + <button type="button" class="uk-button uk-modal-close">取消</button>
  177 + <button type="submit" class="uk-button uk-button-primary"><i class="uk-icon-check"></i> &nbsp;保存
  178 + </button>
  179 + </div>
  180 + </form>
  181 +</script>
  182 +<script>
  183 + (function () {
  184 + var wrap = '#schedule-addsch-modal-v2 .normalCont', sch, nf, submitFun;
  185 +
  186 + $(wrap).on('init', function (e, data) {
  187 + e.stopPropagation();
  188 + sch = data.sch;
  189 + submitFun = data.submitFun;
  190 +
  191 + nf = addForm();
  192 + //提交
  193 + nf.on('success.form.fv', function (e) {
  194 + e.preventDefault();
  195 +
  196 + changeStationSelectStatus(true);
  197 + disabled_submit_btn(nf);
  198 + var data = nf.serializeJSON();
  199 + var blockStations = $('[name=blockStations]', nf).val();
  200 + data.blockStations = blockStations ? blockStations.join(',') : null;
  201 + submitFun(data, function (rs) {
  202 + //前端数据更新
  203 + gb_schedule_table.insertSchedule(rs.t, rs.ts);
  204 + $('#schedule-lj_zrw-modal .main-schedule-table').trigger('refresh', {sch: rs.t});
  205 + try {
  206 + if(rs.t.bcType=='in' || rs.t.bcType=='out')
  207 + gb_data_basic.reload_stat_park_data();
  208 + }catch (e){
  209 + console.log(e);}
  210 + UIkit.modal('#schedule-addsch-modal-v2').hide();
  211 + //更新路牌公里统计面板
  212 + gb_schedule_table.showLpMileageTipBySch(rs.t);
  213 + }, function () {
  214 + changeStationSelectStatus(false);
  215 + enable_submit_btn(nf);
  216 + });
  217 + });
  218 + });
  219 +
  220 + function addForm() {
  221 + var htmlStr = template('add_normal_sch-form-temp-v2', sch);
  222 + var f = $(htmlStr);
  223 + $(wrap).append(f);
  224 + //字典转换
  225 + dictionaryUtils.transformDom($('.nt-dictionary', f));
  226 + //validation
  227 + f.formValidation({framework: 'uikit', locale: 'zh_CN'});
  228 + //autocomp
  229 + f.trigger('init-autoCom');
  230 +
  231 + $f('bcType', f).trigger('change');
  232 + return f;
  233 + }
  234 +
  235 + function $f(name, f) {
  236 + return $('[name=' + name + ']', f);
  237 + }
  238 +
  239 + function changeStationSelectStatus(flag) {
  240 + $('[name=qdzCode],[name=zdzCode]').prop('disabled', !flag);
  241 + }
  242 + })();
189 </script> 243 </script>
190 \ No newline at end of file 244 \ No newline at end of file
src/main/resources/static/real_control_v2/fragments/line_schedule/context_menu/temp_sch_v2/add_normal_znddType.html
1 <!-- 临加班次form --> 1 <!-- 临加班次form -->
2 -<script id="add_normal_sch-form-temp" type="text/html"> 2 +<script id="add_normal_sch-form-temp-zndd-v2" type="text/html">
3 <form class="uk-form uk-form-horizontal add-sch-form"> 3 <form class="uk-form uk-form-horizontal add-sch-form">
4 <div class="uk-grid"> 4 <div class="uk-grid">
5 <div class="uk-width-1-2"> 5 <div class="uk-width-1-2">
@@ -135,7 +135,7 @@ @@ -135,7 +135,7 @@
135 </script> 135 </script>
136 <script> 136 <script>
137 (function () { 137 (function () {
138 - var wrap = '#schedule-addsch-modal .normalCont', sch, nf, submitFun; 138 + var wrap = '#schedule-addsch-modal-v2 .normalCont', sch, nf, submitFun;
139 139
140 $(wrap).on('init', function (e, data) { 140 $(wrap).on('init', function (e, data) {
141 e.stopPropagation(); 141 e.stopPropagation();
@@ -158,7 +158,7 @@ @@ -158,7 +158,7 @@
158 gb_data_basic.reload_stat_park_data(); 158 gb_data_basic.reload_stat_park_data();
159 }catch (e){ 159 }catch (e){
160 console.log(e);} 160 console.log(e);}
161 - UIkit.modal('#schedule-addsch-modal').hide(); 161 + UIkit.modal('#schedule-addsch-modal-v2').hide();
162 //更新路牌公里统计面板 162 //更新路牌公里统计面板
163 gb_schedule_table.showLpMileageTipBySch(rs.t); 163 gb_schedule_table.showLpMileageTipBySch(rs.t);
164 }, function () { 164 }, function () {
@@ -168,7 +168,7 @@ @@ -168,7 +168,7 @@
168 }); 168 });
169 169
170 function addForm() { 170 function addForm() {
171 - var htmlStr = template('add_normal_sch-form-temp', sch); 171 + var htmlStr = template('add_normal_sch-form-temp-zndd-v2', sch);
172 var f = $(htmlStr); 172 var f = $(htmlStr);
173 $(wrap).append(f); 173 $(wrap).append(f);
174 //字典转换 174 //字典转换
src/main/resources/static/real_control_v2/fragments/line_schedule/context_menu/temp_sch_v2/add_park_to_park.html
1 -<!-- 临加场到场班次form -->  
2 -<script id="add_park_to_park_sch-form-temp" type="text/html">  
3 - <form class="uk-form uk-form-horizontal">  
4 - <div class="uk-grid">  
5 - <div class="uk-width-1-2">  
6 - <div class="uk-form-row">  
7 - <label class="uk-form-label">班次类型</label>  
8 - <div class="uk-form-controls">  
9 - <select class="form-control" name="bcType">  
10 - <option value="in">进场</option>  
11 - </select>  
12 - </div>  
13 - </div>  
14 - </div>  
15 - <div class="uk-width-1-2">  
16 - <div class="uk-form-row">  
17 - <label class="uk-form-label">上下行</label>  
18 - <div class="uk-form-controls">  
19 - <select name="xlDir">  
20 - <option value="0">上行</option>  
21 - <option value="1">下行</option>  
22 - </select>  
23 - </div>  
24 - </div>  
25 - </div>  
26 - </div>  
27 - <div class="uk-grid">  
28 - <div class="uk-width-1-2">  
29 - <div class="uk-form-row">  
30 - <label class="uk-form-label">起点站</label>  
31 - <div class="uk-form-controls">  
32 - <select name="qdzCode">  
33 - </select>  
34 - </div>  
35 - </div>  
36 - </div>  
37 - <div class="uk-width-1-2">  
38 - <div class="uk-form-row">  
39 - <label class="uk-form-label">终点站</label>  
40 - <div class="uk-form-controls">  
41 - <select name="zdzCode">  
42 - </select>  
43 - </div>  
44 - </div>  
45 - </div>  
46 - </div>  
47 - <div class="uk-grid">  
48 - <div class="uk-width-1-2">  
49 - <div class="uk-form-row">  
50 - <label class="uk-form-label">开始时间</label>  
51 - <div class="uk-form-controls">  
52 - <input type="time" value="{{zdsjActual==null?zdsj:zdsjActual}}" name="fcsj" required>  
53 - </div>  
54 - </div>  
55 - </div>  
56 - <div class="uk-width-1-2">  
57 - <div class="uk-form-row">  
58 - <label class="uk-form-label">结束时间</label>  
59 - <div class="uk-form-controls">  
60 - <input type="time" name="zdsj" required>  
61 - </div>  
62 - </div>  
63 - </div>  
64 - </div>  
65 - <div class="uk-grid">  
66 - <div class="uk-width-1-2">  
67 - <div class="uk-form-row">  
68 - <label class="uk-form-label">车辆</label>  
69 - <div class="uk-form-controls">  
70 - <div class="uk-autocomplete uk-form car-autocom">  
71 - <input type="text" value="{{clZbh}}" name="clZbh" required>  
72 - </div>  
73 - </div>  
74 - </div>  
75 - </div>  
76 - <div class="uk-width-1-2">  
77 - <div class="uk-form-row">  
78 - <label class="uk-form-label">里程</label>  
79 - <div class="uk-form-controls">  
80 - <input type="text" name="jhlc" value="{{jhlc}}" max=400 data-fv-lessthan-inclusive="false"  
81 - required>  
82 - </div>  
83 - </div>  
84 - </div>  
85 - </div>  
86 - <div class="uk-grid">  
87 - <div class="uk-width-1-2">  
88 - <div class="uk-form-row">  
89 - <label class="uk-form-label">驾驶员</label>  
90 - <div class="uk-form-controls">  
91 - <div class="uk-autocomplete uk-form jsy-autocom">  
92 - <input type="text" value="{{jGh}}/{{jName}}" name="jsy" required>  
93 - </div>  
94 - </div>  
95 - </div>  
96 - </div>  
97 - <div class="uk-width-1-2">  
98 - <div class="uk-form-row">  
99 - <label class="uk-form-label">售票员</label>  
100 - <div class="uk-form-controls">  
101 - <div class="uk-autocomplete uk-form spy-autocom">  
102 - <input type="text" name="spy" value="{{sGh}}/{{sName}}">  
103 - </div>  
104 - </div>  
105 - </div>  
106 - </div>  
107 - </div>  
108 - <div class="uk-grid">  
109 - <div class="uk-width-1-2">  
110 - <div class="uk-form-row">  
111 - <label class="uk-form-label">路牌</label>  
112 - <div class="uk-form-controls">  
113 - <input type="text" value="{{lpName}}" name="lpName" required>  
114 - </div>  
115 - </div>  
116 - </div>  
117 - </div>  
118 - <div class="uk-grid">  
119 - <div class="uk-width-1-1">  
120 - <div class="uk-form-row">  
121 - <label class="uk-form-label">备注</label>  
122 - <div class="uk-form-controls">  
123 - <div class="uk-autocomplete uk-form remarks-autocom">  
124 - <input type="text" name="remarks">  
125 - </div>  
126 - </div>  
127 - </div>  
128 - </div>  
129 - </div>  
130 - <div class="uk-modal-footer uk-text-right" style="margin-bottom: -20px;">  
131 - <button type="button" class="uk-button uk-modal-close">取消</button>  
132 - <button type="submit" class="uk-button uk-button-primary"><i class="uk-icon-check"></i> &nbsp;保存  
133 - </button>  
134 - </div>  
135 - </form>  
136 -</script>  
137 -  
138 -<script>  
139 - (function () {  
140 - var wrap = '#schedule-addsch-modal .parkToParkCont', sch, nf, submitFun,parks,carsArray;  
141 -  
142 - $(wrap).on('init', function (e, data) {  
143 - e.stopPropagation();  
144 - sch = data.sch;  
145 - submitFun = data.submitFun;  
146 - parks = data.parks;  
147 - carsArray = data.carsArray;  
148 -  
149 - nf = addForm();  
150 - //提交  
151 - nf.on('success.form.fv', function (e) {  
152 - e.preventDefault();  
153 -  
154 - disabled_submit_btn(nf);  
155 - var data = nf.serializeJSON();  
156 - submitFun(data, function (rs) {  
157 - //前端数据更新  
158 - gb_schedule_table.insertSchedule(rs.t, rs.ts);  
159 - $('#schedule-lj_zrw-modal .main-schedule-table').trigger('refresh', {sch: rs.t});  
160 - try {  
161 - if(rs.t.bcType=='in' || rs.t.bcType=='out')  
162 - gb_data_basic.reload_stat_park_data();  
163 - }catch (e){  
164 - console.log(e);}  
165 - UIkit.modal('#schedule-addsch-modal').hide();  
166 - //更新路牌公里统计面板  
167 - gb_schedule_table.showLpMileageTipBySch(rs.t);  
168 - }, function () {  
169 - enable_submit_btn(nf);  
170 - });  
171 - });  
172 - $f('zdzCode',nf).trigger('change');  
173 - });  
174 -  
175 - function addForm() {  
176 - var htmlStr = template('add_park_to_park_sch-form-temp', sch);  
177 - var f = $(htmlStr);  
178 - $(wrap).append(f);  
179 - //字典转换  
180 - dictionaryUtils.transformDom($('.nt-dictionary', f));  
181 - //validation  
182 - f.formValidation({framework: 'uikit', locale: 'zh_CN'});  
183 - //autocomp  
184 - initAutoComp(f);  
185 -  
186 - //起终点都是停车场  
187 - var park_opts;  
188 - for(var i=0,p;p=parks[i++];)  
189 - park_opts += '<option value="' + p.code + '">' + p.name + '</option>';  
190 - $f('qdzCode', f).html(park_opts);  
191 - $f('zdzCode', f).html(park_opts);  
192 -  
193 - if(sch.bcType=='in'){  
194 - $f('qdzCode', f).val(sch.zdzCode);  
195 - //选中的也是场到场班次  
196 - if(gb_data_basic.getCarparkByCode(sch.qdzCode) != null){  
197 - //默认做返程  
198 - $f('zdzCode', f).val(sch.qdzCode);  
199 - $f('remarks', f).val(sch.remarks);  
200 - $f('jhlc', f).val(sch.jhlc);  
201 - //时间  
202 - var zdsj = moment(sch.zdsj, 'HH:mm').add('minutes', sch.bcsj).format('HH:mm');  
203 - $f('zdsj', f).val(zdsj);  
204 - }  
205 - }  
206 - return f;  
207 - }  
208 -  
209 - function $f(name, f) {  
210 - return $('[name=' + name + ']', f);  
211 - }  
212 -  
213 - function initAutoComp(f) {  
214 - //车辆  
215 - if(carsArray)  
216 - gb_common.carAutocomplete($('.car-autocom', f), carsArray);  
217 - //驾驶员  
218 - gb_common.personAutocomplete($('.jsy-autocom', f));  
219 - //售票员  
220 - gb_common.personAutocomplete($('.spy-autocom', f));  
221 - //备注补全  
222 - gb_common.remarksAutocomplete($('.remarks-autocom', f));  
223 - }  
224 -  
225 - })(); 1 +<!-- 临加场到场班次form -->
  2 +<script id="add_park_to_park_sch-form-temp-v2" type="text/html">
  3 + <form class="uk-form uk-form-horizontal">
  4 + <div class="uk-grid">
  5 + <div class="uk-width-1-2">
  6 + <div class="uk-form-row">
  7 + <label class="uk-form-label">班次类型</label>
  8 + <div class="uk-form-controls">
  9 + <select class="form-control" name="bcType">
  10 + <option value="in">进场</option>
  11 + </select>
  12 + </div>
  13 + </div>
  14 + </div>
  15 + <div class="uk-width-1-2">
  16 + <div class="uk-form-row">
  17 + <label class="uk-form-label">上下行</label>
  18 + <div class="uk-form-controls">
  19 + <select name="xlDir">
  20 + <option value="0">上行</option>
  21 + <option value="1">下行</option>
  22 + </select>
  23 + </div>
  24 + </div>
  25 + </div>
  26 + </div>
  27 + <div class="uk-grid">
  28 + <div class="uk-width-1-2">
  29 + <div class="uk-form-row">
  30 + <label class="uk-form-label">起点站</label>
  31 + <div class="uk-form-controls">
  32 + <select name="qdzCode">
  33 + </select>
  34 + </div>
  35 + </div>
  36 + </div>
  37 + <div class="uk-width-1-2">
  38 + <div class="uk-form-row">
  39 + <label class="uk-form-label">终点站</label>
  40 + <div class="uk-form-controls">
  41 + <select name="zdzCode">
  42 + </select>
  43 + </div>
  44 + </div>
  45 + </div>
  46 + </div>
  47 + <div class="uk-grid">
  48 + <div class="uk-width-1-2">
  49 + <div class="uk-form-row">
  50 + <label class="uk-form-label">开始时间</label>
  51 + <div class="uk-form-controls">
  52 + <input type="time" value="{{zdsjActual==null?zdsj:zdsjActual}}" name="fcsj" required>
  53 + </div>
  54 + </div>
  55 + </div>
  56 + <div class="uk-width-1-2">
  57 + <div class="uk-form-row">
  58 + <label class="uk-form-label">结束时间</label>
  59 + <div class="uk-form-controls">
  60 + <input type="time" name="zdsj" required>
  61 + </div>
  62 + </div>
  63 + </div>
  64 + </div>
  65 + <div class="uk-grid">
  66 + <div class="uk-width-1-2">
  67 + <div class="uk-form-row">
  68 + <label class="uk-form-label">车辆</label>
  69 + <div class="uk-form-controls">
  70 + <div class="uk-autocomplete uk-form car-autocom">
  71 + <input type="text" value="{{clZbh}}" name="clZbh" required>
  72 + </div>
  73 + </div>
  74 + </div>
  75 + </div>
  76 + <div class="uk-width-1-2">
  77 + <div class="uk-form-row">
  78 + <label class="uk-form-label">里程</label>
  79 + <div class="uk-form-controls">
  80 + <input type="text" name="jhlc" value="{{jhlc}}" max=400 data-fv-lessthan-inclusive="false"
  81 + required>
  82 + </div>
  83 + </div>
  84 + </div>
  85 + </div>
  86 + <div class="uk-grid">
  87 + <div class="uk-width-1-2">
  88 + <div class="uk-form-row">
  89 + <label class="uk-form-label">驾驶员</label>
  90 + <div class="uk-form-controls">
  91 + <div class="uk-autocomplete uk-form jsy-autocom">
  92 + <input type="text" value="{{jGh}}/{{jName}}" name="jsy" required>
  93 + </div>
  94 + </div>
  95 + </div>
  96 + </div>
  97 + <div class="uk-width-1-2">
  98 + <div class="uk-form-row">
  99 + <label class="uk-form-label">售票员</label>
  100 + <div class="uk-form-controls">
  101 + <div class="uk-autocomplete uk-form spy-autocom">
  102 + <input type="text" name="spy" value="{{sGh}}/{{sName}}">
  103 + </div>
  104 + </div>
  105 + </div>
  106 + </div>
  107 + </div>
  108 + <div class="uk-grid">
  109 + <div class="uk-width-1-2">
  110 + <div class="uk-form-row">
  111 + <label class="uk-form-label">路牌</label>
  112 + <div class="uk-form-controls">
  113 + <input type="text" value="{{lpName}}" name="lpName" required>
  114 + </div>
  115 + </div>
  116 + </div>
  117 + </div>
  118 + <div class="uk-grid">
  119 + <div class="uk-width-1-1">
  120 + <div class="uk-form-row">
  121 + <label class="uk-form-label">备注</label>
  122 + <div class="uk-form-controls">
  123 + <div class="uk-autocomplete uk-form remarks-autocom">
  124 + <input type="text" name="remarks">
  125 + </div>
  126 + </div>
  127 + </div>
  128 + </div>
  129 + </div>
  130 + <div class="uk-modal-footer uk-text-right" style="margin-bottom: -20px;">
  131 + <button type="button" class="uk-button uk-modal-close">取消</button>
  132 + <button type="submit" class="uk-button uk-button-primary"><i class="uk-icon-check"></i> &nbsp;保存
  133 + </button>
  134 + </div>
  135 + </form>
  136 +</script>
  137 +
  138 +<script>
  139 + (function () {
  140 + var wrap = '#schedule-addsch-modal-v2 .parkToParkCont', sch, nf, submitFun,parks,carsArray;
  141 +
  142 + $(wrap).on('init', function (e, data) {
  143 + e.stopPropagation();
  144 + sch = data.sch;
  145 + submitFun = data.submitFun;
  146 + parks = data.parks;
  147 + carsArray = data.carsArray;
  148 +
  149 + nf = addForm();
  150 + //提交
  151 + nf.on('success.form.fv', function (e) {
  152 + e.preventDefault();
  153 +
  154 + disabled_submit_btn(nf);
  155 + var data = nf.serializeJSON();
  156 + submitFun(data, function (rs) {
  157 + //前端数据更新
  158 + gb_schedule_table.insertSchedule(rs.t, rs.ts);
  159 + $('#schedule-lj_zrw-modal .main-schedule-table').trigger('refresh', {sch: rs.t});
  160 + try {
  161 + if(rs.t.bcType=='in' || rs.t.bcType=='out')
  162 + gb_data_basic.reload_stat_park_data();
  163 + }catch (e){
  164 + console.log(e);}
  165 + UIkit.modal('#schedule-addsch-modal-v2').hide();
  166 + //更新路牌公里统计面板
  167 + gb_schedule_table.showLpMileageTipBySch(rs.t);
  168 + }, function () {
  169 + enable_submit_btn(nf);
  170 + });
  171 + });
  172 + $f('zdzCode',nf).trigger('change');
  173 + });
  174 +
  175 + function addForm() {
  176 + var htmlStr = template('add_park_to_park_sch-form-temp-v2', sch);
  177 + var f = $(htmlStr);
  178 + $(wrap).append(f);
  179 + //字典转换
  180 + dictionaryUtils.transformDom($('.nt-dictionary', f));
  181 + //validation
  182 + f.formValidation({framework: 'uikit', locale: 'zh_CN'});
  183 + //autocomp
  184 + initAutoComp(f);
  185 +
  186 + //起终点都是停车场
  187 + var park_opts;
  188 + for(var i=0,p;p=parks[i++];)
  189 + park_opts += '<option value="' + p.code + '">' + p.name + '</option>';
  190 + $f('qdzCode', f).html(park_opts);
  191 + $f('zdzCode', f).html(park_opts);
  192 +
  193 + if(sch.bcType=='in'){
  194 + $f('qdzCode', f).val(sch.zdzCode);
  195 + //选中的也是场到场班次
  196 + if(gb_data_basic.getCarparkByCode(sch.qdzCode) != null){
  197 + //默认做返程
  198 + $f('zdzCode', f).val(sch.qdzCode);
  199 + $f('remarks', f).val(sch.remarks);
  200 + $f('jhlc', f).val(sch.jhlc);
  201 + //时间
  202 + var zdsj = moment(sch.zdsj, 'HH:mm').add('minutes', sch.bcsj).format('HH:mm');
  203 + $f('zdsj', f).val(zdsj);
  204 + }
  205 + }
  206 + return f;
  207 + }
  208 +
  209 + function $f(name, f) {
  210 + return $('[name=' + name + ']', f);
  211 + }
  212 +
  213 + function initAutoComp(f) {
  214 + //车辆
  215 + if(carsArray)
  216 + gb_common.carAutocomplete($('.car-autocom', f), carsArray);
  217 + //驾驶员
  218 + gb_common.personAutocomplete($('.jsy-autocom', f));
  219 + //售票员
  220 + gb_common.personAutocomplete($('.spy-autocom', f));
  221 + //备注补全
  222 + gb_common.remarksAutocomplete($('.remarks-autocom', f));
  223 + }
  224 +
  225 + })();
226 </script> 226 </script>
227 \ No newline at end of file 227 \ No newline at end of file
src/main/resources/static/real_control_v2/fragments/line_schedule/context_menu/temp_sch_v2/add_two_way.html
1 -<!-- 线路上往返临加班次 -->  
2 -<script id="add_toAndFro_sch-form-temp" type="text/html">  
3 - <form class="uk-form uk-form-horizontal add-sch-form one_form">  
4 - <div class="uk-grid">  
5 - <div class="uk-width-1-2">  
6 - <div class="uk-form-row">  
7 - <label class="uk-form-label">班次类型</label>  
8 - <div class="uk-form-controls">  
9 - <select class="form-control nt-dictionary" name="bcType" data-code="{{bcType}}"  
10 - data-group=ScheduleType></select>  
11 - </div>  
12 - </div>  
13 - </div>  
14 - <div class="uk-width-1-2">  
15 - <div class="uk-form-row">  
16 - <label class="uk-form-label">上下行</label>  
17 - <div class="uk-form-controls">  
18 - <select name="xlDir">  
19 - <option value="0">上行</option>  
20 - <option value="1">下行</option>  
21 - </select>  
22 - </div>  
23 - </div>  
24 - </div>  
25 - </div>  
26 - <div class="uk-grid">  
27 - <div class="uk-width-1-2">  
28 - <div class="uk-form-row">  
29 - <label class="uk-form-label">起点站</label>  
30 - <div class="uk-form-controls">  
31 - <select name="qdzCode" >  
32 - </select>  
33 - </div>  
34 - </div>  
35 - </div>  
36 - <div class="uk-width-1-2">  
37 - <div class="uk-form-row">  
38 - <label class="uk-form-label">终点站</label>  
39 - <div class="uk-form-controls">  
40 - <select name="zdzCode" >  
41 - </select>  
42 - </div>  
43 - </div>  
44 - </div>  
45 - </div>  
46 - <div class="uk-grid">  
47 - <div class="uk-width-1-2">  
48 - <div class="uk-form-row">  
49 - <label class="uk-form-label">开始时间</label>  
50 - <div class="uk-form-controls">  
51 - <input type="time" value="{{zdsj}}" name="fcsj" required>  
52 - </div>  
53 - </div>  
54 - </div>  
55 - <div class="uk-width-1-2">  
56 - <div class="uk-form-row">  
57 - <label class="uk-form-label">结束时间</label>  
58 - <div class="uk-form-controls">  
59 - <input type="time" name="zdsj" required>  
60 - </div>  
61 - </div>  
62 - </div>  
63 - </div>  
64 - <div class="uk-grid">  
65 - <div class="uk-width-1-2">  
66 - <div class="uk-form-row">  
67 - <label class="uk-form-label">车辆</label>  
68 - <div class="uk-form-controls">  
69 - <div class="uk-autocomplete uk-form car-autocom">  
70 - <input type="text" value="{{clZbh}}" name="clZbh" required>  
71 - </div>  
72 - </div>  
73 - </div>  
74 - </div>  
75 - <div class="uk-width-1-2">  
76 - <div class="uk-form-row">  
77 - <label class="uk-form-label">里程</label>  
78 - <div class="uk-form-controls">  
79 - <input type="text" name="jhlc" value="{{jhlc}}" max=400 data-fv-lessthan-inclusive="false"  
80 - required>  
81 - </div>  
82 - </div>  
83 - </div>  
84 - </div>  
85 - <div class="uk-grid">  
86 - <div class="uk-width-1-2">  
87 - <div class="uk-form-row">  
88 - <label class="uk-form-label">驾驶员</label>  
89 - <div class="uk-form-controls">  
90 - <div class="uk-autocomplete uk-form jsy-autocom">  
91 - <input type="text" value="{{jGh}}/{{jName}}" name="jsy" required>  
92 - </div>  
93 - </div>  
94 - </div>  
95 - </div>  
96 - <div class="uk-width-1-2">  
97 - <div class="uk-form-row">  
98 - <label class="uk-form-label">售票员</label>  
99 - <div class="uk-form-controls">  
100 - <div class="uk-autocomplete uk-form spy-autocom">  
101 - <input type="text" name="spy" value="{{sGh}}/{{sName}}">  
102 - </div>  
103 - </div>  
104 - </div>  
105 - </div>  
106 - </div>  
107 - <div class="uk-grid">  
108 - <div class="uk-width-1-2">  
109 - <div class="uk-form-row">  
110 - <label class="uk-form-label">路牌</label>  
111 - <div class="uk-form-controls">  
112 - <input type="text" value="{{lpName}}" name="lpName" required>  
113 - </div>  
114 - </div>  
115 - </div>  
116 - </div>  
117 - <div class="uk-grid">  
118 - <div class="uk-width-1-1">  
119 - <div class="uk-form-row">  
120 - <label class="uk-form-label">备注</label>  
121 - <div class="uk-form-controls">  
122 - <div class="uk-autocomplete uk-form remarks-autocom">  
123 - <input type="text" name="remarks">  
124 - </div>  
125 - </div>  
126 - </div>  
127 - </div>  
128 - </div>  
129 - </form>  
130 - <hr style="margin-top: 35px;">  
131 - <form class="uk-form uk-form-horizontal add-sch-form two_form">  
132 - <div class="uk-grid">  
133 - <div class="uk-width-1-2">  
134 - <div class="uk-form-row">  
135 - <label class="uk-form-label">班次类型</label>  
136 - <div class="uk-form-controls">  
137 - <select class="form-control nt-dictionary" name="bcType" data-code="{{bcType}}"  
138 - data-group=ScheduleType></select>  
139 - </div>  
140 - </div>  
141 - </div>  
142 - <div class="uk-width-1-2">  
143 - <div class="uk-form-row">  
144 - <label class="uk-form-label">上下行</label>  
145 - <div class="uk-form-controls">  
146 - <select name="xlDir">  
147 - <option value="0">上行</option>  
148 - <option value="1">下行</option>  
149 - </select>  
150 - </div>  
151 - </div>  
152 - </div>  
153 - </div>  
154 - <div class="uk-grid">  
155 - <div class="uk-width-1-2">  
156 - <div class="uk-form-row">  
157 - <label class="uk-form-label">起点站</label>  
158 - <div class="uk-form-controls">  
159 - <select name="qdzCode" >  
160 - </select>  
161 - </div>  
162 - </div>  
163 - </div>  
164 - <div class="uk-width-1-2">  
165 - <div class="uk-form-row">  
166 - <label class="uk-form-label">终点站</label>  
167 - <div class="uk-form-controls">  
168 - <select name="zdzCode" >  
169 - </select>  
170 - </div>  
171 - </div>  
172 - </div>  
173 - </div>  
174 - <div class="uk-grid">  
175 - <div class="uk-width-1-2">  
176 - <div class="uk-form-row">  
177 - <label class="uk-form-label">开始时间</label>  
178 - <div class="uk-form-controls">  
179 - <input type="time" value="{{zdsj}}" name="fcsj" required>  
180 - </div>  
181 - </div>  
182 - </div>  
183 - <div class="uk-width-1-2">  
184 - <div class="uk-form-row">  
185 - <label class="uk-form-label">结束时间</label>  
186 - <div class="uk-form-controls">  
187 - <input type="time" name="zdsj" required>  
188 - </div>  
189 - </div>  
190 - </div>  
191 - </div>  
192 - <div class="uk-grid">  
193 - <div class="uk-width-1-2">  
194 - <div class="uk-form-row">  
195 - <label class="uk-form-label">车辆</label>  
196 - <div class="uk-form-controls">  
197 - <div class="uk-autocomplete uk-form car-autocom">  
198 - <input type="text" value="{{clZbh}}" name="clZbh" required>  
199 - </div>  
200 - </div>  
201 - </div>  
202 - </div>  
203 - <div class="uk-width-1-2">  
204 - <div class="uk-form-row">  
205 - <label class="uk-form-label">里程</label>  
206 - <div class="uk-form-controls">  
207 - <input type="text" name="jhlc" value="{{jhlc}}" max=400 data-fv-lessthan-inclusive="false"  
208 - required>  
209 - </div>  
210 - </div>  
211 - </div>  
212 - </div>  
213 - <div class="uk-grid">  
214 - <div class="uk-width-1-2">  
215 - <div class="uk-form-row">  
216 - <label class="uk-form-label">驾驶员</label>  
217 - <div class="uk-form-controls">  
218 - <div class="uk-autocomplete uk-form jsy-autocom">  
219 - <input type="text" value="{{jGh}}/{{jName}}" name="jsy" required>  
220 - </div>  
221 - </div>  
222 - </div>  
223 - </div>  
224 - <div class="uk-width-1-2">  
225 - <div class="uk-form-row">  
226 - <label class="uk-form-label">售票员</label>  
227 - <div class="uk-form-controls">  
228 - <div class="uk-autocomplete uk-form spy-autocom">  
229 - <input type="text" name="spy" value="{{sGh}}/{{sName}}">  
230 - </div>  
231 - </div>  
232 - </div>  
233 - </div>  
234 - </div>  
235 - <div class="uk-grid">  
236 - <div class="uk-width-1-2">  
237 - <div class="uk-form-row">  
238 - <label class="uk-form-label">路牌</label>  
239 - <div class="uk-form-controls">  
240 - <input type="text" value="{{lpName}}" name="lpName" required>  
241 - </div>  
242 - </div>  
243 - </div>  
244 - </div>  
245 - <div class="uk-grid">  
246 - <div class="uk-width-1-1">  
247 - <div class="uk-form-row">  
248 - <label class="uk-form-label">备注</label>  
249 - <div class="uk-form-controls">  
250 - <div class="uk-autocomplete uk-form remarks-autocom">  
251 - <input type="text" name="remarks">  
252 - </div>  
253 - </div>  
254 - </div>  
255 - </div>  
256 - </div>  
257 - </form>  
258 -  
259 - <div class="uk-modal-footer uk-text-right" style="margin-bottom: -20px;">  
260 - <button type="button" class="uk-button uk-modal-close">取消</button>  
261 - <button type="submit" class="uk-button uk-button-primary"><i class="uk-icon-check"></i> &nbsp;保存</button>  
262 - </div>  
263 -</script>  
264 -  
265 -<script>  
266 - (function () {  
267 - var wrap = '#schedule-addsch-modal .toAndFroCont', sch, f1, f2, submitFun, stationRoutes;  
268 -  
269 - $(wrap).on('init', function (e, data) {  
270 - e.stopPropagation();  
271 - sch = data.sch;  
272 - submitFun = data.submitFun;  
273 - stationRoutes = data.stationRoutes;  
274 -  
275 - var htmlStr = template('add_toAndFro_sch-form-temp', sch);  
276 - $(wrap).append(htmlStr);  
277 - //字典转换  
278 - dictionaryUtils.transformDom($('.nt-dictionary', wrap));  
279 - //validation  
280 - $('.add-sch-form', wrap).formValidation({framework: 'uikit', locale: 'zh_CN'}).trigger('init-autoCom');  
281 - $('.add-sch-form [name=bcType]', wrap).trigger('change');  
282 -  
283 - f1 = $('.add-sch-form.one_form', wrap);  
284 - f2 = $('.add-sch-form.two_form', wrap);  
285 -  
286 - //默认1备注同步到2  
287 - $f('remarks', f1).on('input', function () {  
288 - $f('remarks', f2).val($(this).val());  
289 - });  
290 - //默认1备注同步到2  
291 - $('.remarks-autocom', f1).on('selectitem.uk.autocomplete', function (e, data, acobject) {  
292 - $f('remarks', f2).val(data.value);  
293 - });  
294 -  
295 - //人车级联  
296 - $f('clZbh',f1).on('input change', function () {  
297 - $f('clZbh', f2).val($(this).val());  
298 - });  
299 - $f('jsy',f1).on('input change', function () {  
300 - $f('jsy', f2).val($(this).val());  
301 - });  
302 - $f('spy',f1).on('input change', function () {  
303 - $f('spy', f2).val($(this).val());  
304 - });  
305 - $f('lpName',f1).on('input change', function () {  
306 - $f('lpName', f2).val($(this).val());  
307 - });  
308 - //表单同步  
309 - $(f1).on('ct_callback', synchroFormData).trigger('ct_callback');  
310 - //修改1结束时间  
311 - $f('zdsj',f1).on('input', synchroFormData);  
312 -  
313 - //表单校验提交相关  
314 - var dataArray;  
315 - var fs = $('.add-sch-form', wrap);  
316 - fs.on('success.form.fv', function (e) {  
317 - e.preventDefault();  
318 - dataArray.push($(this).serializeJSON());  
319 - $(this).data('valid', true);  
320 - if (allValidSuccess()) {  
321 - //开始post  
322 - var i = 0;  
323 - var inArr = [];  
324 - var upArr = [];  
325 - (function () {  
326 - var f = arguments.callee;  
327 - if (i >= dataArray.length) {  
328 - //前端数据更新  
329 - var last = inArr.pop();  
330 - gb_schedule_table.insertSchedule(last, upArr);  
331 - $('#schedule-lj_zrw-modal .main-schedule-table').trigger('refresh', {sch: last});  
332 -  
333 - try {  
334 - if(last.bcType=='in' || last.bcType=='out')  
335 - gb_data_basic.reload_stat_park_data();  
336 - }catch (e){  
337 - console.log(e);}  
338 - UIkit.modal('#schedule-addsch-modal').hide();  
339 - //更新路牌公里统计面板  
340 - gb_schedule_table.showLpMileageTipBySch(last);  
341 - return;  
342 - }  
343 - submitFun(dataArray[i], function (rs) {  
344 - inArr.push(rs.t);  
345 - upArr = upArr.concat(rs.ts);  
346 - upArr.push(rs.t);  
347 - i++;  
348 - f();  
349 - }, function () {  
350 - $('[type=submit]', wrap).removeClass('disabled').removeAttr('disabled');  
351 - });  
352 - })();  
353 - }  
354 - });  
355 - //提交  
356 - $('[type=submit]', wrap).on('click', function () {  
357 - $(this).addClass('disabled').attr('disabled', 'disabled');  
358 - dataArray = [];  
359 - fs.data('valid', false);  
360 - fs.formValidation('validate');  
361 - });  
362 - });  
363 -  
364 - function $f(name, f) {  
365 - return $('[name=' + name + ']', f);  
366 - }  
367 -  
368 - function allValidSuccess() {  
369 - var flag = true;  
370 - $('form.add-sch-form:visible', wrap).each(function (i, f) {  
371 - if (!$(f).data('valid')) {  
372 - flag = false;  
373 - return false;  
374 - }  
375 - });  
376 - return flag;  
377 - }  
378 -  
379 - /**  
380 - * 同步2个表单的数据  
381 - */  
382 - var bcTypes = {'normal': 'normal', 'region': 'region', 'out': 'in', 'in': 'out'};  
383 - var synchroFormData = function () {  
384 - //同步班次类型  
385 - var type = $f('bcType', f1).val();  
386 - if (bcTypes[type])  
387 - $f('bcType', f2).val(bcTypes[type]).trigger('change');  
388 - var updown = $f('xlDir', f1).val();  
389 -  
390 - //1 结束时间 = 2 开始时间  
391 - $f('fcsj', f2).val($f('zdsj', f1).val());  
392 - if (type != 'out' && type != 'in') {  
393 - //走向  
394 - $f('xlDir', f2).val(updown == 0 ? 1 : 0).trigger('change');  
395 -  
396 - //第一个表单终点 = 第二个起点  
397 - var oneZdName = $('[name=zdzCode] option:selected', f1).text();  
398 - $f('qdzCode', f2).val(searchParallelStation(oneZdName, updown == 0 ? 1 : 0));  
399 - //第一个表单起点 = 第二个终点  
400 - var oneQdName = $('[name=qdzCode] option:selected', f1).text();  
401 - $f('zdzCode', f2).val(searchParallelStation(oneQdName, updown == 0 ? 1 : 0)).trigger('change');  
402 - }  
403 - else {  
404 - //进出场走向相同  
405 - $f('xlDir', f2).val(updown).trigger('change');  
406 - //第一个表单终点 = 第二个起点  
407 - $f('qdzCode', f2).val($f('zdzCode', f1).val());  
408 - //第一个表单起点 = 第二个终点  
409 - $f('zdzCode', f2).val($f('qdzCode', f1).val()).trigger('change');  
410 - }  
411 -  
412 - };  
413 -  
414 -  
415 - //返回另一个走向对应的站点  
416 - function searchParallelStation(stationName, updown) {  
417 - var routes = stationRoutes[updown]  
418 - , len = routes.length;  
419 -  
420 - for (var i = 0; i < len; i++) {  
421 - if (routes[i].stationName == stationName)  
422 - return routes[i].stationCode;  
423 - }  
424 - }  
425 - })(); 1 +<!-- 线路上往返临加班次 -->
  2 +<script id="add_toAndFro_sch-form-temp-v2" type="text/html">
  3 + <form class="uk-form uk-form-horizontal add-sch-form one_form">
  4 + <div class="uk-grid">
  5 + <div class="uk-width-1-2">
  6 + <div class="uk-form-row">
  7 + <label class="uk-form-label">班次类型</label>
  8 + <div class="uk-form-controls">
  9 + <select class="form-control nt-dictionary" name="bcType" data-code="{{bcType}}"
  10 + data-group=ScheduleType></select>
  11 + </div>
  12 + </div>
  13 + </div>
  14 + <div class="uk-width-1-2">
  15 + <div class="uk-form-row">
  16 + <label class="uk-form-label">上下行</label>
  17 + <div class="uk-form-controls">
  18 + <select name="xlDir">
  19 + <option value="0">上行</option>
  20 + <option value="1">下行</option>
  21 + </select>
  22 + </div>
  23 + </div>
  24 + </div>
  25 + </div>
  26 + <div class="uk-grid">
  27 + <div class="uk-width-1-2">
  28 + <div class="uk-form-row">
  29 + <label class="uk-form-label">起点站</label>
  30 + <div class="uk-form-controls">
  31 + <select name="qdzCode" >
  32 + </select>
  33 + </div>
  34 + </div>
  35 + </div>
  36 + <div class="uk-width-1-2">
  37 + <div class="uk-form-row">
  38 + <label class="uk-form-label">终点站</label>
  39 + <div class="uk-form-controls">
  40 + <select name="zdzCode" >
  41 + </select>
  42 + </div>
  43 + </div>
  44 + </div>
  45 + </div>
  46 + <div class="uk-grid">
  47 + <div class="uk-width-1-2">
  48 + <div class="uk-form-row">
  49 + <label class="uk-form-label">开始时间</label>
  50 + <div class="uk-form-controls">
  51 + <input type="time" value="{{zdsj}}" name="fcsj" required>
  52 + </div>
  53 + </div>
  54 + </div>
  55 + <div class="uk-width-1-2">
  56 + <div class="uk-form-row">
  57 + <label class="uk-form-label">结束时间</label>
  58 + <div class="uk-form-controls">
  59 + <input type="time" name="zdsj" required>
  60 + </div>
  61 + </div>
  62 + </div>
  63 + </div>
  64 + <div class="uk-grid">
  65 + <div class="uk-width-1-2">
  66 + <div class="uk-form-row">
  67 + <label class="uk-form-label">车辆</label>
  68 + <div class="uk-form-controls">
  69 + <div class="uk-autocomplete uk-form car-autocom">
  70 + <input type="text" value="{{clZbh}}" name="clZbh" required>
  71 + </div>
  72 + </div>
  73 + </div>
  74 + </div>
  75 + <div class="uk-width-1-2">
  76 + <div class="uk-form-row">
  77 + <label class="uk-form-label">里程</label>
  78 + <div class="uk-form-controls">
  79 + <input type="text" name="jhlc" value="{{jhlc}}" max=400 data-fv-lessthan-inclusive="false"
  80 + required>
  81 + </div>
  82 + </div>
  83 + </div>
  84 + </div>
  85 + <div class="uk-grid">
  86 + <div class="uk-width-1-2">
  87 + <div class="uk-form-row">
  88 + <label class="uk-form-label">驾驶员</label>
  89 + <div class="uk-form-controls">
  90 + <div class="uk-autocomplete uk-form jsy-autocom">
  91 + <input type="text" value="{{jGh}}/{{jName}}" name="jsy" required>
  92 + </div>
  93 + </div>
  94 + </div>
  95 + </div>
  96 + <div class="uk-width-1-2">
  97 + <div class="uk-form-row">
  98 + <label class="uk-form-label">售票员</label>
  99 + <div class="uk-form-controls">
  100 + <div class="uk-autocomplete uk-form spy-autocom">
  101 + <input type="text" name="spy" value="{{sGh}}/{{sName}}">
  102 + </div>
  103 + </div>
  104 + </div>
  105 + </div>
  106 + </div>
  107 + <div class="uk-grid" style="display:none;">
  108 + <div class="uk-width-1-2">
  109 + <div class="uk-form-row">
  110 + <label class="uk-form-label">是否预设</label>
  111 + <div class="uk-form-controls">
  112 + <div class="uk-autocomplete uk-form">
  113 + <input type="checkbox" name="isPreRegion">
  114 + </div>
  115 + </div>
  116 + </div>
  117 + </div>
  118 + <div class="uk-width-1-2" id="regionId">
  119 + <div class="uk-form-row">
  120 + <label class="uk-form-label">预设区间</label>
  121 + <div class="uk-form-controls">
  122 + <div class="uk-autocomplete uk-form">
  123 + <select name="regionId">
  124 + </select>
  125 + </div>
  126 + </div>
  127 + </div>
  128 + </div>
  129 + </div>
  130 + <div class="uk-grid" style="display:none;">
  131 + <div class="uk-width-1-2">
  132 + <div class="uk-form-row">
  133 + <label class="uk-form-label">是否封站</label>
  134 + <div class="uk-form-controls">
  135 + <div class="uk-autocomplete uk-form">
  136 + <input type="checkbox" name="isBlock" value="1">
  137 + </div>
  138 + </div>
  139 + </div>
  140 + </div>
  141 + <div class="uk-width-1-2" id="blockStations">
  142 + <div class="uk-form-row">
  143 + <label class="uk-form-label">封锁站点</label>
  144 + <div class="uk-form-controls">
  145 + <div class="uk-autocomplete uk-form">
  146 + <select class="form-control" name="blockStations" multiple="multiple">
  147 + </select>
  148 + </div>
  149 + </div>
  150 + </div>
  151 + </div>
  152 + </div>
  153 + <div class="uk-grid">
  154 + <div class="uk-width-1-2">
  155 + <div class="uk-form-row">
  156 + <label class="uk-form-label">路牌</label>
  157 + <div class="uk-form-controls">
  158 + <input type="text" value="{{lpName}}" name="lpName" required>
  159 + </div>
  160 + </div>
  161 + </div>
  162 + </div>
  163 + <div class="uk-grid">
  164 + <div class="uk-width-1-1">
  165 + <div class="uk-form-row">
  166 + <label class="uk-form-label">备注</label>
  167 + <div class="uk-form-controls">
  168 + <div class="uk-autocomplete uk-form remarks-autocom">
  169 + <input type="text" name="remarks">
  170 + </div>
  171 + </div>
  172 + </div>
  173 + </div>
  174 + </div>
  175 + </form>
  176 + <hr style="margin-top: 35px;">
  177 + <form class="uk-form uk-form-horizontal add-sch-form two_form">
  178 + <div class="uk-grid">
  179 + <div class="uk-width-1-2">
  180 + <div class="uk-form-row">
  181 + <label class="uk-form-label">班次类型</label>
  182 + <div class="uk-form-controls">
  183 + <select class="form-control nt-dictionary" name="bcType" data-code="{{bcType}}"
  184 + data-group=ScheduleType></select>
  185 + </div>
  186 + </div>
  187 + </div>
  188 + <div class="uk-width-1-2">
  189 + <div class="uk-form-row">
  190 + <label class="uk-form-label">上下行</label>
  191 + <div class="uk-form-controls">
  192 + <select name="xlDir">
  193 + <option value="0">上行</option>
  194 + <option value="1">下行</option>
  195 + </select>
  196 + </div>
  197 + </div>
  198 + </div>
  199 + </div>
  200 + <div class="uk-grid">
  201 + <div class="uk-width-1-2">
  202 + <div class="uk-form-row">
  203 + <label class="uk-form-label">起点站</label>
  204 + <div class="uk-form-controls">
  205 + <select name="qdzCode" >
  206 + </select>
  207 + </div>
  208 + </div>
  209 + </div>
  210 + <div class="uk-width-1-2">
  211 + <div class="uk-form-row">
  212 + <label class="uk-form-label">终点站</label>
  213 + <div class="uk-form-controls">
  214 + <select name="zdzCode" >
  215 + </select>
  216 + </div>
  217 + </div>
  218 + </div>
  219 + </div>
  220 + <div class="uk-grid">
  221 + <div class="uk-width-1-2">
  222 + <div class="uk-form-row">
  223 + <label class="uk-form-label">开始时间</label>
  224 + <div class="uk-form-controls">
  225 + <input type="time" value="{{zdsj}}" name="fcsj" required>
  226 + </div>
  227 + </div>
  228 + </div>
  229 + <div class="uk-width-1-2">
  230 + <div class="uk-form-row">
  231 + <label class="uk-form-label">结束时间</label>
  232 + <div class="uk-form-controls">
  233 + <input type="time" name="zdsj" required>
  234 + </div>
  235 + </div>
  236 + </div>
  237 + </div>
  238 + <div class="uk-grid">
  239 + <div class="uk-width-1-2">
  240 + <div class="uk-form-row">
  241 + <label class="uk-form-label">车辆</label>
  242 + <div class="uk-form-controls">
  243 + <div class="uk-autocomplete uk-form car-autocom">
  244 + <input type="text" value="{{clZbh}}" name="clZbh" required>
  245 + </div>
  246 + </div>
  247 + </div>
  248 + </div>
  249 + <div class="uk-width-1-2">
  250 + <div class="uk-form-row">
  251 + <label class="uk-form-label">里程</label>
  252 + <div class="uk-form-controls">
  253 + <input type="text" name="jhlc" value="{{jhlc}}" max=400 data-fv-lessthan-inclusive="false"
  254 + required>
  255 + </div>
  256 + </div>
  257 + </div>
  258 + </div>
  259 + <div class="uk-grid">
  260 + <div class="uk-width-1-2">
  261 + <div class="uk-form-row">
  262 + <label class="uk-form-label">驾驶员</label>
  263 + <div class="uk-form-controls">
  264 + <div class="uk-autocomplete uk-form jsy-autocom">
  265 + <input type="text" value="{{jGh}}/{{jName}}" name="jsy" required>
  266 + </div>
  267 + </div>
  268 + </div>
  269 + </div>
  270 + <div class="uk-width-1-2">
  271 + <div class="uk-form-row">
  272 + <label class="uk-form-label">售票员</label>
  273 + <div class="uk-form-controls">
  274 + <div class="uk-autocomplete uk-form spy-autocom">
  275 + <input type="text" name="spy" value="{{sGh}}/{{sName}}">
  276 + </div>
  277 + </div>
  278 + </div>
  279 + </div>
  280 + </div>
  281 + <div class="uk-grid" style="display:none;">
  282 + <div class="uk-width-1-2">
  283 + <div class="uk-form-row">
  284 + <label class="uk-form-label">是否预设</label>
  285 + <div class="uk-form-controls">
  286 + <div class="uk-autocomplete uk-form">
  287 + <input type="checkbox" name="isPreRegion">
  288 + </div>
  289 + </div>
  290 + </div>
  291 + </div>
  292 + <div class="uk-width-1-2" id="regionId">
  293 + <div class="uk-form-row">
  294 + <label class="uk-form-label">预设区间</label>
  295 + <div class="uk-form-controls">
  296 + <div class="uk-autocomplete uk-form">
  297 + <select name="regionId">
  298 + </select>
  299 + </div>
  300 + </div>
  301 + </div>
  302 + </div>
  303 + </div>
  304 + <div class="uk-grid" style="display:none;">
  305 + <div class="uk-width-1-2">
  306 + <div class="uk-form-row">
  307 + <label class="uk-form-label">是否封站</label>
  308 + <div class="uk-form-controls">
  309 + <div class="uk-autocomplete uk-form">
  310 + <input type="checkbox" name="isBlock" value="1">
  311 + </div>
  312 + </div>
  313 + </div>
  314 + </div>
  315 + <div class="uk-width-1-2" id="blockStations">
  316 + <div class="uk-form-row">
  317 + <label class="uk-form-label">封锁站点</label>
  318 + <div class="uk-form-controls">
  319 + <div class="uk-autocomplete uk-form">
  320 + <select class="form-control" name="blockStations" multiple="multiple">
  321 + </select>
  322 + </div>
  323 + </div>
  324 + </div>
  325 + </div>
  326 + </div>
  327 + <div class="uk-grid">
  328 + <div class="uk-width-1-2">
  329 + <div class="uk-form-row">
  330 + <label class="uk-form-label">路牌</label>
  331 + <div class="uk-form-controls">
  332 + <input type="text" value="{{lpName}}" name="lpName" required>
  333 + </div>
  334 + </div>
  335 + </div>
  336 + </div>
  337 + <div class="uk-grid">
  338 + <div class="uk-width-1-1">
  339 + <div class="uk-form-row">
  340 + <label class="uk-form-label">备注</label>
  341 + <div class="uk-form-controls">
  342 + <div class="uk-autocomplete uk-form remarks-autocom">
  343 + <input type="text" name="remarks">
  344 + </div>
  345 + </div>
  346 + </div>
  347 + </div>
  348 + </div>
  349 + </form>
  350 +
  351 + <div class="uk-modal-footer uk-text-right" style="margin-bottom: -20px;">
  352 + <button type="button" class="uk-button uk-modal-close">取消</button>
  353 + <button type="submit" class="uk-button uk-button-primary"><i class="uk-icon-check"></i> &nbsp;保存</button>
  354 + </div>
  355 +</script>
  356 +
  357 +<script>
  358 + (function () {
  359 + var wrap = '#schedule-addsch-modal-v2 .toAndFroCont', sch, f1, f2, submitFun, stationRoutes;
  360 +
  361 + $(wrap).on('init', function (e, data) {
  362 + e.stopPropagation();
  363 + sch = data.sch;
  364 + submitFun = data.submitFun;
  365 + stationRoutes = data.stationRoutes;
  366 +
  367 + var htmlStr = template('add_toAndFro_sch-form-temp-v2', sch);
  368 + $(wrap).append(htmlStr);
  369 + //字典转换
  370 + dictionaryUtils.transformDom($('.nt-dictionary', wrap));
  371 + //validation
  372 + $('.add-sch-form', wrap).formValidation({framework: 'uikit', locale: 'zh_CN'}).trigger('init-autoCom');
  373 + $('.add-sch-form [name=bcType]', wrap).trigger('change');
  374 +
  375 + f1 = $('.add-sch-form.one_form', wrap);
  376 + f2 = $('.add-sch-form.two_form', wrap);
  377 +
  378 + //默认1备注同步到2
  379 + $f('remarks', f1).on('input', function () {
  380 + $f('remarks', f2).val($(this).val());
  381 + });
  382 + //默认1备注同步到2
  383 + $('.remarks-autocom', f1).on('selectitem.uk.autocomplete', function (e, data, acobject) {
  384 + $f('remarks', f2).val(data.value);
  385 + });
  386 +
  387 + //人车级联
  388 + $f('clZbh',f1).on('input change', function () {
  389 + $f('clZbh', f2).val($(this).val());
  390 + });
  391 + $f('jsy',f1).on('input change', function () {
  392 + $f('jsy', f2).val($(this).val());
  393 + });
  394 + $f('spy',f1).on('input change', function () {
  395 + $f('spy', f2).val($(this).val());
  396 + });
  397 + $f('lpName',f1).on('input change', function () {
  398 + $f('lpName', f2).val($(this).val());
  399 + });
  400 + //表单同步
  401 + $(f1).on('ct_callback', synchroFormData).trigger('ct_callback');
  402 + //修改1结束时间
  403 + $f('zdsj',f1).on('input', synchroFormData);
  404 +
  405 + //表单校验提交相关
  406 + var dataArray;
  407 + var fs = $('.add-sch-form', wrap);
  408 + fs.on('success.form.fv', function (e) {
  409 + e.preventDefault();
  410 + changeStationSelectStatus(true);
  411 + var data = $(this).serializeJSON();
  412 + var blockStations = $('[name=blockStations]', $(this)).val();
  413 + data.blockStations = blockStations ? blockStations.join(',') : null;
  414 + dataArray.push(data);
  415 + $(this).data('valid', true);
  416 + if (allValidSuccess()) {
  417 + //开始post
  418 + var i = 0;
  419 + var inArr = [];
  420 + var upArr = [];
  421 + (function () {
  422 + var f = arguments.callee;
  423 + if (i >= dataArray.length) {
  424 + //前端数据更新
  425 + var last = inArr.pop();
  426 + gb_schedule_table.insertSchedule(last, upArr);
  427 + $('#schedule-lj_zrw-modal .main-schedule-table').trigger('refresh', {sch: last});
  428 +
  429 + try {
  430 + if(last.bcType=='in' || last.bcType=='out')
  431 + gb_data_basic.reload_stat_park_data();
  432 + }catch (e){
  433 + console.log(e);}
  434 + UIkit.modal('#schedule-addsch-modal-v2').hide();
  435 + //更新路牌公里统计面板
  436 + gb_schedule_table.showLpMileageTipBySch(last);
  437 + return;
  438 + }
  439 + submitFun(dataArray[i], function (rs) {
  440 + inArr.push(rs.t);
  441 + upArr = upArr.concat(rs.ts);
  442 + upArr.push(rs.t);
  443 + i++;
  444 + f();
  445 + }, function () {
  446 + $('[type=submit]', wrap).removeClass('disabled').removeAttr('disabled');
  447 + });
  448 + })();
  449 + changeStationSelectStatus(false);
  450 + }
  451 + });
  452 + //提交
  453 + $('[type=submit]', wrap).on('click', function () {
  454 + $(this).addClass('disabled').attr('disabled', 'disabled');
  455 + dataArray = [];
  456 + fs.data('valid', false);
  457 + fs.formValidation('validate');
  458 + });
  459 + });
  460 +
  461 + function $f(name, f) {
  462 + return $('[name=' + name + ']', f);
  463 + }
  464 +
  465 + function allValidSuccess() {
  466 + var flag = true;
  467 + $('form.add-sch-form:visible', wrap).each(function (i, f) {
  468 + if (!$(f).data('valid')) {
  469 + flag = false;
  470 + return false;
  471 + }
  472 + });
  473 + return flag;
  474 + }
  475 +
  476 + /**
  477 + * 同步2个表单的数据
  478 + */
  479 + var bcTypes = {'normal': 'normal', 'region': 'region', 'out': 'in', 'in': 'out'};
  480 + var synchroFormData = function () {
  481 + //同步班次类型
  482 + var type = $f('bcType', f1).val();
  483 + if (bcTypes[type])
  484 + $f('bcType', f2).val(bcTypes[type]).trigger('change');
  485 + var updown = $f('xlDir', f1).val();
  486 +
  487 + //1 结束时间 = 2 开始时间
  488 + $f('fcsj', f2).val($f('zdsj', f1).val());
  489 + if (type != 'out' && type != 'in') {
  490 + //走向
  491 + $f('xlDir', f2).val(updown == 0 ? 1 : 0).trigger('change');
  492 +
  493 + //第一个表单终点 = 第二个起点
  494 + var oneZdName = $('[name=zdzCode] option:selected', f1).text();
  495 + $f('qdzCode', f2).val(searchParallelStation(oneZdName, updown == 0 ? 1 : 0));
  496 + //第一个表单起点 = 第二个终点
  497 + var oneQdName = $('[name=qdzCode] option:selected', f1).text();
  498 + $f('zdzCode', f2).val(searchParallelStation(oneQdName, updown == 0 ? 1 : 0)).trigger('change');
  499 + }
  500 + else {
  501 + //进出场走向相同
  502 + $f('xlDir', f2).val(updown).trigger('change');
  503 + //第一个表单终点 = 第二个起点
  504 + $f('qdzCode', f2).val($f('zdzCode', f1).val());
  505 + //第一个表单起点 = 第二个终点
  506 + $f('zdzCode', f2).val($f('qdzCode', f1).val()).trigger('change');
  507 + }
  508 +
  509 + };
  510 +
  511 +
  512 + //返回另一个走向对应的站点
  513 + function searchParallelStation(stationName, updown) {
  514 + var routes = stationRoutes[updown]
  515 + , len = routes.length;
  516 +
  517 + for (var i = 0; i < len; i++) {
  518 + if (routes[i].stationName == stationName)
  519 + return routes[i].stationCode;
  520 + }
  521 + }
  522 +
  523 + function changeStationSelectStatus(flag) {
  524 + $('[name=qdzCode],[name=zdzCode]').prop('disabled', !flag);
  525 + }
  526 + })();
426 </script> 527 </script>
427 \ No newline at end of file 528 \ No newline at end of file
src/main/resources/static/real_control_v2/fragments/line_schedule/context_menu/temp_sch_v2/add_two_way_znddType.html
1 <!-- 线路上往返临加班次 --> 1 <!-- 线路上往返临加班次 -->
2 -<script id="add_toAndFro_sch-form-temp" type="text/html"> 2 +<script id="add_toAndFro_sch-form-temp-v2" type="text/html">
3 <form class="uk-form uk-form-horizontal add-sch-form one_form"> 3 <form class="uk-form uk-form-horizontal add-sch-form one_form">
4 <div class="uk-grid"> 4 <div class="uk-grid">
5 <div class="uk-width-1-2"> 5 <div class="uk-width-1-2">
@@ -264,7 +264,7 @@ @@ -264,7 +264,7 @@
264 264
265 <script> 265 <script>
266 var addTwoWayZnddType = (function () { 266 var addTwoWayZnddType = (function () {
267 - var wrap = '#schedule-addsch-modal .toAndFroCont', sch, f1, f2, submitFun, stationRoutes; 267 + var wrap = '#schedule-addsch-modal-v2 .toAndFroCont', sch, f1, f2, submitFun, stationRoutes;
268 268
269 $(wrap).on('init', function (e, data) { 269 $(wrap).on('init', function (e, data) {
270 e.stopPropagation(); 270 e.stopPropagation();
@@ -272,7 +272,7 @@ @@ -272,7 +272,7 @@
272 submitFun = data.submitFun; 272 submitFun = data.submitFun;
273 stationRoutes = data.stationRoutes; 273 stationRoutes = data.stationRoutes;
274 274
275 - var htmlStr = template('add_toAndFro_sch-form-temp', sch); 275 + var htmlStr = template('add_toAndFro_sch-form-temp-v2', sch);
276 $(wrap).append(htmlStr); 276 $(wrap).append(htmlStr);
277 //字典转换 277 //字典转换
278 dictionaryUtils.transformDom($('.nt-dictionary', wrap)); 278 dictionaryUtils.transformDom($('.nt-dictionary', wrap));
@@ -335,7 +335,7 @@ @@ -335,7 +335,7 @@
335 gb_data_basic.reload_stat_park_data(); 335 gb_data_basic.reload_stat_park_data();
336 }catch (e){ 336 }catch (e){
337 console.log(e);} 337 console.log(e);}
338 - UIkit.modal('#schedule-addsch-modal').hide(); 338 + UIkit.modal('#schedule-addsch-modal-v2').hide();
339 //更新路牌公里统计面板 339 //更新路牌公里统计面板
340 gb_schedule_table.showLpMileageTipBySch(last); 340 gb_schedule_table.showLpMileageTipBySch(last);
341 return; 341 return;
@@ -394,7 +394,7 @@ @@ -394,7 +394,7 @@
394 gb_data_basic.reload_stat_park_data(); 394 gb_data_basic.reload_stat_park_data();
395 }catch (e){ 395 }catch (e){
396 console.log(e);} 396 console.log(e);}
397 - UIkit.modal('#schedule-addsch-modal').hide(); 397 + UIkit.modal('#schedule-addsch-modal-v2').hide();
398 //更新路牌公里统计面板 398 //更新路牌公里统计面板
399 gb_schedule_table.showLpMileageTipBySch(last); 399 gb_schedule_table.showLpMileageTipBySch(last);
400 return; 400 return;
src/main/resources/static/real_control_v2/fragments/line_schedule/context_menu/temp_sch_v2/main.html
1 -<div class="uk-modal ct-form-modal ct_move_modal" id="schedule-addsch-modal"> 1 +<div class="uk-modal ct-form-modal ct_move_modal" id="schedule-addsch-modal-v2">
2 <div class="uk-modal-dialog" style="width: 800px;"> 2 <div class="uk-modal-dialog" style="width: 800px;">
3 <a href="" class="uk-modal-close uk-close"></a> 3 <a href="" class="uk-modal-close uk-close"></a>
4 <div class="uk-modal-header"> 4 <div class="uk-modal-header">
@@ -24,8 +24,8 @@ @@ -24,8 +24,8 @@
24 24
25 <script> 25 <script>
26 (function () { 26 (function () {
27 - var modal = '#schedule-addsch-modal',  
28 - sch, stationRoutes, parks, information, carsArray, st_park_data; 27 + var modal = '#schedule-addsch-modal-v2',
  28 + sch, stationRoutes, parks, information, carsArray, st_park_data, lineRegion = {};
29 29
30 $(modal).on('init', function (e, data) { 30 $(modal).on('init', function (e, data) {
31 e.stopPropagation(); 31 e.stopPropagation();
@@ -57,6 +57,31 @@ @@ -57,6 +57,31 @@
57 //park to park 57 //park to park
58 $('.parkToParkCont', modal).html(st_doms.park_to_park_dom) 58 $('.parkToParkCont', modal).html(st_doms.park_to_park_dom)
59 .trigger('init', {sch: sch, submitFun: submit_temp_schedule_form, parks: parks, carsArray: carsArray}); 59 .trigger('init', {sch: sch, submitFun: submit_temp_schedule_form, parks: parks, carsArray: carsArray});
  60 +
  61 + gb_common.$get('/api/lineregion/all', {line_eq: sch.xlBm, version_eq: gb_data_basic.getLineCurrentVersion(sch.xlBm), direction_eq: 0}, function(regions) {
  62 + var opts = new Array();
  63 + opts.push('<option value="">选择预设区间</option>');
  64 + for (var idx in regions) {
  65 + var item = regions[idx], title = new Array();
  66 + lineRegion[item.id + '_' + item.seq] = item;
  67 + if (item.stationRoutes.length > 1) {
  68 + for (var idx1 in item.stationRoutes) {
  69 + title.push(item.stationRoutes[idx1].stationName);
  70 + }
  71 + }
  72 + opts.push('<option value="', item.id, '_', item.seq);
  73 + if (title.length > 0) {
  74 + opts.push('" title="', title.join('\n'))
  75 + }
  76 + opts.push('">', item.regionAlias, '</option>')
  77 + }
  78 + $('.add-sch-form [name=regionId]').html(opts.join(''));
  79 + $('[name=isPreRegion]', modal).on('change', isPreRegionChangeHandle).trigger('change');
  80 + $('[name=regionId]', modal).on('change', regionIdChangeHandle);
  81 + $('[name=isBlock]', modal).on('change', isBlockChangeHandle).trigger('change');
  82 + $('[name=blockStations]', modal).multipleSelect();
  83 + $('.add-sch-form.two_form [name=xlDir]').trigger('change');
  84 + })
60 }); 85 });
61 86
62 //init-autoCom 87 //init-autoCom
@@ -72,6 +97,8 @@ @@ -72,6 +97,8 @@
72 gb_common.remarksAutocomplete($('.remarks-autocom', this)); 97 gb_common.remarksAutocomplete($('.remarks-autocom', this));
73 }); 98 });
74 99
  100 + //上下行 切换事件
  101 + $(modal).on('change', '.add-sch-form [name=xlDir]', reCalcLineRegion);
75 //班次类型 和 上下行 切换事件 102 //班次类型 和 上下行 切换事件
76 $(modal).on('change', '.add-sch-form [name=bcType],.add-sch-form [name=xlDir]', reCalcInputs_type); 103 $(modal).on('change', '.add-sch-form [name=bcType],.add-sch-form [name=xlDir]', reCalcInputs_type);
77 //起终点站改变事件 104 //起终点站改变事件
@@ -79,6 +106,28 @@ @@ -79,6 +106,28 @@
79 //开始时间和公里改变 106 //开始时间和公里改变
80 $(modal).on('input', '.add-sch-form [name=fcsj],.add-sch-form [name=jhlc]', reCalcEndTime); 107 $(modal).on('input', '.add-sch-form [name=fcsj],.add-sch-form [name=jhlc]', reCalcEndTime);
81 108
  109 + function reCalcLineRegion() {
  110 + var f = $(this).parents('.add-sch-form'), xlDir = $('[name=xlDir]', f).val();
  111 + gb_common.$get('/api/lineregion/all', {line_eq: sch.xlBm, version_eq: gb_data_basic.getLineCurrentVersion(sch.xlBm), direction_eq: xlDir}, function(regions) {
  112 + var opts = new Array();
  113 + opts.push('<option value="">选择预设区间</option>');
  114 + for (var idx in regions) {
  115 + var item = regions[idx], title = new Array();
  116 + lineRegion[item.id + '_' + item.seq] = item;
  117 + if (item.stationRoutes.length > 1) {
  118 + for (var idx1 in item.stationRoutes) {
  119 + title.push(item.stationRoutes[idx1].stationName);
  120 + }
  121 + }
  122 + opts.push('<option value="', item.id, '_', item.seq);
  123 + if (title.length > 0) {
  124 + opts.push('" title="', title.join('\n'))
  125 + }
  126 + opts.push('">', item.regionAlias, '</option>')
  127 + }
  128 + $('[name=regionId]', f).html(opts.join(''));
  129 + })
  130 + }
82 131
83 function reCalcInputs_type() { 132 function reCalcInputs_type() {
84 var f = $(this).parents('.add-sch-form'); 133 var f = $(this).parents('.add-sch-form');
@@ -96,7 +145,7 @@ @@ -96,7 +145,7 @@
96 for(var i=0,p;p=parks[i++];) 145 for(var i=0,p;p=parks[i++];)
97 park_opts += '<option value="' + p.code + '">' + p.name + '</option>'; 146 park_opts += '<option value="' + p.code + '">' + p.name + '</option>';
98 147
99 - var qdz = $('[name=qdzCode]', f), zdz = $('[name=zdzCode]', f); 148 + var qdz = $('[name=qdzCode]', f), zdz = $('[name=zdzCode]', f), blockStations = $('[name=blockStations]', f);
100 //var time, mileage; 149 //var time, mileage;
101 switch (bcType_e.val()) { 150 switch (bcType_e.val()) {
102 case 'out': 151 case 'out':
@@ -111,6 +160,7 @@ @@ -111,6 +160,7 @@
111 qdz.html(opts); 160 qdz.html(opts);
112 zdz.html(opts).val(lastCode); 161 zdz.html(opts).val(lastCode);
113 } 162 }
  163 + blockStations.html(opts);
114 164
115 zdz.trigger('change'); 165 zdz.trigger('change');
116 f.trigger('ct_callback'); 166 f.trigger('ct_callback');
@@ -207,6 +257,49 @@ @@ -207,6 +257,49 @@
207 f.trigger('ct_callback'); 257 f.trigger('ct_callback');
208 } 258 }
209 259
  260 + function isPreRegionChangeHandle() {
  261 + var checked = $(this).is(':checked'),
  262 + f = $(this).parents('.add-sch-form'),
  263 + bcType = $('[name=bcType]', f),
  264 + qdzCode = $('[name=qdzCode]', f),
  265 + zdzCode = $('[name=zdzCode]', f),
  266 + regionId = $('#regionId', f);
  267 + if (checked) {
  268 + bcType.val('region');
  269 + qdzCode.prop('disabled', true);
  270 + zdzCode.prop('disabled', true);
  271 + regionId.show();
  272 + } else {
  273 + qdzCode.prop('disabled', false);
  274 + zdzCode.prop('disabled', false);
  275 + regionId.hide();
  276 + }
  277 + }
  278 +
  279 + function regionIdChangeHandle() {
  280 + var f = $(this).parents('.add-sch-form'),
  281 + qdzCode = $('[name=qdzCode]', f),
  282 + zdzCode = $('[name=zdzCode]', f),
  283 + regionId = $(this).val();
  284 + if (!regionId) return;
  285 + var stationRoutes = lineRegion[regionId].stationRoutes;
  286 + if (stationRoutes && stationRoutes.length > 1) {
  287 + qdzCode.val(stationRoutes[0].stationCode);
  288 + zdzCode.val(stationRoutes[stationRoutes.length - 1].stationCode);
  289 + }
  290 + }
  291 +
  292 + function isBlockChangeHandle() {
  293 + var checked = $(this).is(':checked'),
  294 + f = $(this).parents('.add-sch-form'),
  295 + blockStations = $('#blockStations', f);
  296 + if (checked) {
  297 + blockStations.show();
  298 + } else {
  299 + blockStations.hide();
  300 + }
  301 + }
  302 +
210 function is_normal_sch(f) { 303 function is_normal_sch(f) {
211 var qdzCode = $('[name=qdzCode]', f).val(), 304 var qdzCode = $('[name=qdzCode]', f).val(),
212 zdzCode =$('[name=zdzCode]', f).val(), 305 zdzCode =$('[name=zdzCode]', f).val(),
@@ -323,6 +416,12 @@ @@ -323,6 +416,12 @@
323 data.jGh = data.jsy.split('/')[0]; 416 data.jGh = data.jsy.split('/')[0];
324 data.jName = data.jsy.split('/')[1]; 417 data.jName = data.jsy.split('/')[1];
325 delete data.jsy; 418 delete data.jsy;
  419 + if (!data.isPreRegion) {
  420 + delete data.regionId;
  421 + }
  422 + if (!data.isBlock) {
  423 + delete data.blockStations;
  424 + }
326 //拆分售票员工号和姓名 425 //拆分售票员工号和姓名
327 if (data.spy != '') { 426 if (data.spy != '') {
328 data.sGh = data.spy.split('/')[0]; 427 data.sGh = data.spy.split('/')[0];
src/main/resources/static/real_control_v2/js/data/data_basic.js
@@ -2,7 +2,7 @@ @@ -2,7 +2,7 @@
2 2
3 var gb_data_basic = (function () { 3 var gb_data_basic = (function () {
4 4
5 - var stationRoutes, lineCode2NameAll, lineInformations, nbbm2deviceMap, device2nbbmMap, allPersonnel, svgAttrs; 5 + var stationRoutes, lineCode2NameAll, lineInformations, nbbm2deviceMap, device2nbbmMap, allPersonnel, svgAttrs, lineCode2Version = {};
6 var ep = EventProxy.create("stationRoutes", "lineCode2Name", "lineInformations", "nbbm2deviceId", "all_personnel", "svg_attrs" 6 var ep = EventProxy.create("stationRoutes", "lineCode2Name", "lineInformations", "nbbm2deviceId", "all_personnel", "svg_attrs"
7 , function (routes, code2Name, informations, nbbm2device, all_personnel, svgAttrMap) { 7 , function (routes, code2Name, informations, nbbm2device, all_personnel, svgAttrMap) {
8 stationRoutes = routes; 8 stationRoutes = routes;
@@ -33,6 +33,10 @@ var gb_data_basic = (function () { @@ -33,6 +33,10 @@ var gb_data_basic = (function () {
33 //站点路由 33 //站点路由
34 gb_common.$get('/stationroute/multiLine', {lineIds: line_idx}, function (rs) { 34 gb_common.$get('/stationroute/multiLine', {lineIds: line_idx}, function (rs) {
35 var list = rs.list;//JSON.parse(rs.list); 35 var list = rs.list;//JSON.parse(rs.list);
  36 + for (var idx in list) {
  37 + var item = list[idx];
  38 + lineCode2Version[item.lineCode] = item.versions;
  39 + }
36 var routeData = gb_common.groupBy(list, 'lineCode'); 40 var routeData = gb_common.groupBy(list, 'lineCode');
37 //排序 41 //排序
38 for (var lineCode in routeData) { 42 for (var lineCode in routeData) {
@@ -183,6 +187,9 @@ var gb_data_basic = (function () { @@ -183,6 +187,9 @@ var gb_data_basic = (function () {
183 return device2nbbmMap; 187 return device2nbbmMap;
184 }, 188 },
185 getLineInformation: getLineInformation, 189 getLineInformation: getLineInformation,
  190 + getLineCurrentVersion: function(lineCode) {
  191 + return lineCode2Version[lineCode];
  192 + },
186 allInformations: function () { 193 allInformations: function () {
187 return lineInformations; 194 return lineInformations;
188 }, 195 },
src/main/resources/static/real_control_v2/main.html
@@ -54,7 +54,8 @@ @@ -54,7 +54,8 @@
54 54
55 <!--//演示使用--> 55 <!--//演示使用-->
56 <link href="/real_control_v2/zndd/yanshi/static/css/sjz.css" type="text/css" rel="stylesheet"> 56 <link href="/real_control_v2/zndd/yanshi/static/css/sjz.css" type="text/css" rel="stylesheet">
57 - 57 + <!-- select2 下拉框插件 -->
  58 + <link href="/real_control_v2/assets/plugins/multi-select/multiple-select.min.css" rel="stylesheet" type="text/css" />
58 </head> 59 </head>
59 60
60 <body> 61 <body>
@@ -187,7 +188,8 @@ @@ -187,7 +188,8 @@
187 <script src="/real_control_v2/assets/plugins/qtip/jquery.qtip.min.js" merge="plugins"></script> 188 <script src="/real_control_v2/assets/plugins/qtip/jquery.qtip.min.js" merge="plugins"></script>
188 <!-- layer 3.0.3 --> 189 <!-- layer 3.0.3 -->
189 <script src="/real_control_v2/assets/plugins/layer3.0.3/layer.js" merge="plugins"></script> 190 <script src="/real_control_v2/assets/plugins/layer3.0.3/layer.js" merge="plugins"></script>
190 - 191 +<!-- select2 下拉框 -->
  192 +<script src="/real_control_v2/assets/plugins/multi-select/multiple-select.min.js"></script>
191 <!-- 数据 --> 193 <!-- 数据 -->
192 <script src="/real_control_v2/js/data/data_basic.js" merge="custom_js"></script> 194 <script src="/real_control_v2/js/data/data_basic.js" merge="custom_js"></script>
193 <script src="/real_control_v2/js/data/data_gps.js" merge="custom_js"></script> 195 <script src="/real_control_v2/js/data/data_gps.js" merge="custom_js"></script>