Commit 5100c821f976403829dfd8ad55d652b4c5c24378

Authored by 徐烜
2 parents 61e22e41 8f4a8505

Merge branch 'minhang' of http://222.66.0.204:8090//panzhaov5/bsth_control into minhang

Showing 41 changed files with 991 additions and 413 deletions
src/main/java/com/bsth/controller/realcontrol/anomalyCheckController.java
... ... @@ -105,4 +105,15 @@ public class anomalyCheckController {
105 105 public List<ScheduleRealInfo> findSchByLpName(@RequestParam String lpName){
106 106 return dayOfSchedule.getLpScheduleMap().get(lpName);
107 107 }
  108 +
  109 + @RequestMapping(value = "/findSchByNbbm")
  110 + public List<ScheduleRealInfo> findSchByNbbm(@RequestParam String nbbm){
  111 + return dayOfSchedule.findByNbbm(nbbm);
  112 + }
  113 +
  114 + @RequestMapping(value = "/removeExecPlan")
  115 + public int removeExecPlan(@RequestParam String nbbm){
  116 + dayOfSchedule.removeExecPlan(nbbm);
  117 + return 1;
  118 + }
108 119 }
... ...
src/main/java/com/bsth/controller/sys/UserController.java
... ... @@ -31,220 +31,252 @@ import java.util.*;
31 31 @RequestMapping("user")
32 32 public class UserController extends BaseController<SysUser, Integer> {
33 33  
34   - Logger logger = LoggerFactory.getLogger(this.getClass());
35   -
36   - @Autowired
37   - SysUserService sysUserService;
38   -
39   - @Autowired
40   - CompanyAuthorityService companyAuthorityService;
41   -
42   - @RequestMapping(value = "/login/jCryptionKey")
43   - public Map<String, Object> jCryptionKey(HttpServletRequest request){
44   - //公匙返回页面
45   - Map<String, Object> rs = new HashMap<>();
46   - rs.put("publickey", RSAUtils.generateBase64PublicKey());
47   - return rs;
48   - }
49   -
50   - //需要验证码的账号
51   - public static Map<String, Integer> captchaMap = new HashMap<>();
52   -
53   - @RequestMapping(value = "/login", method = RequestMethod.POST)
54   - public Map<String, Object> login(HttpServletRequest request, @RequestParam String userName,
55   - @RequestParam String password, String captcha) {
56   -
57   - Map<String, Object> rs = new HashMap<>();
58   - rs.put("status", ResponseCode.ERROR);
59   - try {
60   - HttpSession session = request.getSession();
61   - rs.put("captcha", session.getAttribute("captcha"));
62   -
63   - if(captchaMap.get(userName) != null && captchaMap.get(userName) >= 3){
64   - //校验验证码
65   - String verCode = (String) session
66   - .getAttribute(com.google.code.kaptcha.Constants.KAPTCHA_SESSION_KEY);
67   -
68   - if(StringUtils.isBlank(captcha))
69   - return put(rs, "msg", "请输入验证码");
70   -
71   - if(!verCode.equals(captcha))
72   - return put(rs, "msg", "验证码有误,请刷新后重新输入");
73   - }
74   -
75   - //解密RSA
76   - try {
77   - userName = RSAUtils.decryptBase64(userName);
78   - password = RSAUtils.decryptBase64(password);
79   - } catch (RuntimeException e) {
80   - return put(rs, "msg", "decrypt RSA fail!可能页面已过期,尝试刷新页面。");
81   - }
82   -
83   - SysUser user = sysUserService.findByUserName(userName);
84   - if (null == user)
85   - return put(rs, "msg", "不存在的用户");
86   -
87   - if (!user.isEnabled())
88   - return put(rs, "msg", "该用户已被锁定,请联系管理员");
89   -
90   - // 校验密码
91   - boolean matchStatus = new BCryptPasswordEncoder(4).matches(password, user.getPassword());
92   - if (!matchStatus) {
93   - rs.put("msg", "密码有误");
94   -
95   - Integer captchSize = captchaMap.get(userName);
96   - if(null == captchSize)
97   - captchSize = 0;
98   -
99   - captchSize ++;
100   - captchaMap.put(userName, captchSize);
101   - return rs;
102   - }
103   -
104   - // 登录
105   - SecurityUtils.login(user, request);
106   - //session里写入用户名,webSocket连接时标识身份用
107   - session.setAttribute(Constants.SESSION_USERNAME, user.getUserName());
108   -
109   - //获取公司权限数据
110   - List<CompanyAuthority> cmyAuths=companyAuthorityService.findByUser(user);
111   - session.setAttribute(Constants.COMPANY_AUTHORITYS, cmyAuths);
112   -
113   - captchaMap.remove(userName);
114   - rs.put("status", ResponseCode.SUCCESS);
115   - } catch (Exception e) {
116   - logger.error("", e);
117   - rs.put("msg", "服务器出现异常,请联系管理员");
118   - }
119   - return rs;
120   - }
121   -
122   - /**
123   - * 返回当前用户的公司权限数据,用于构建页面级联下拉框
124   - * @return
125   - */
126   - @RequestMapping("companyData")
127   - public List<CompanyData> companyData(HttpServletRequest request){
128   - List<CompanyData> rs = new ArrayList<>();
129   - CompanyData companyData;
130   -
131   - ArrayListMultimap<String, CompanyAuthority> map = ArrayListMultimap.create();
132   - List<CompanyAuthority> cmyAuths = (List<CompanyAuthority>) request.getSession().getAttribute(Constants.COMPANY_AUTHORITYS);
133   -
134   - for(CompanyAuthority cAuth : cmyAuths){
135   - map.put(cAuth.getCompanyCode()+"_"+cAuth.getCompanyName(), cAuth);
136   - }
137   -
138   - Set<String> keys = map.keySet();
139   - String[] temps;
140   - for(String k : keys){
141   - temps = k.split("_");
142   -
143   - companyData = new CompanyData();
144   - companyData.setCompanyCode(temps[0]);
145   - companyData.setCompanyName(temps[1]);
146   - companyData.setChildren(new ArrayList<CompanyData.ChildrenCompany>());
147   -
148   - cmyAuths = map.get(k);
149   - for(CompanyAuthority c : cmyAuths){
150   - companyData.getChildren().add(new CompanyData.ChildrenCompany(c.getSubCompanyCode(), c.getSubCompanyName()));
151   - }
152   -
153   - rs.add(companyData);
154   - }
155   -
156   - return rs;
157   - }
158   -
159   - @RequestMapping(value = "/login/captchaStatus")
160   - public int captchaStatus(String userName){
161   - Integer size = captchaMap.get(userName);
162   - return size == null?0:size;
163   - }
164   -
165   - public Map<String, Object> put(Map<String, Object> rs, String key, Object val){
166   - rs.put(key, val);
167   - return rs;
168   - }
169   -
170   - /**
171   - *
172   - * @Title: loginFailure @Description: TODO(查询登录失败的详细信息) @param @param
173   - * request @return String 返回类型 @throws
174   - */
175   - @RequestMapping("/loginFailure")
176   - public String loginFailure(HttpServletRequest request) {
177   - String msg = "";
178   - HttpSession session = request.getSession();
179   -
180   - Object obj = session.getAttribute("SPRING_SECURITY_LAST_EXCEPTION");
181   -
182   - if (obj instanceof BadCredentialsException)
183   - msg = "登录失败,用户名或密码错误.";
184   - else if (obj instanceof SessionAuthenticationException)
185   - msg = "登录失败,当前策略不允许重复登录.";
186   - session.removeAttribute("SPRING_SECURITY_LAST_EXCEPTION");
187   - return msg;
188   - }
189   -
190   - @RequestMapping("/currentUser")
191   - public SysUser currentUser() {
192   - return SecurityUtils.getCurrentUser();
193   - }
194   -
195   - /**
196   - * @Title changeEnabled
197   - * @Description: TODO(改变用户状态)
198   - * @param id
199   - * 用户ID
200   - * @param enabled
201   - * 状态
202   - * @return
203   - */
204   - @RequestMapping("/changeEnabled")
205   - public int changeEnabled(@RequestParam int id, @RequestParam int enabled) {
206   - return sysUserService.changeEnabled(id, enabled);
207   - }
208   -
209   - /**
210   - * @Title changePWD
211   - * @Description: TODO(修改密码)
212   - * @param oldPWD
213   - * 原始密码
214   - * @param newPWD
215   - * 新密码
216   - * @param cnewPWD
217   - * 确认新密码
218   - * @return
219   - */
220   - @RequestMapping(value = "/changePWD", method = RequestMethod.POST)
221   - public String changePWD(@RequestParam String oldPWD, @RequestParam String newPWD, @RequestParam String cnewPWD) {
222   - SysUser sysUser = SecurityUtils.getCurrentUser();
223   - String msg = "";
224   - if (new BCryptPasswordEncoder(4).matches(oldPWD, sysUser.getPassword())) {
225   - if (oldPWD.equals(newPWD)) {
226   - msg = "新密码不能跟原始密码一样!";
227   - } else {
228   - if (newPWD.equals(cnewPWD)) {
229   - sysUserService.changePWD(sysUser.getId(), newPWD);
230   - msg = "修改成功!";
231   - } else {
232   - msg = "新密码两次输入不一致!";
233   - }
234   - }
235   - } else {
236   - msg = "原始密码错误!";
237   - }
238   - return msg;
239   - }
240   -
241   - @RequestMapping(value = "/register" ,method = RequestMethod.POST)
242   - public Map<String, Object> register(SysUser u){
243   - return sysUserService.register(u);
244   - }
245   -
246   - @RequestMapping(value = "/all_distinct")
247   - public List<SysUser> findAll_distinct(){
248   - return sysUserService.findAll_distinct();
249   - }
  34 + Logger logger = LoggerFactory.getLogger(this.getClass());
  35 +
  36 + @Autowired
  37 + SysUserService sysUserService;
  38 +
  39 + @Autowired
  40 + CompanyAuthorityService companyAuthorityService;
  41 +
  42 + @RequestMapping(value = "/login/jCryptionKey")
  43 + public Map<String, Object> jCryptionKey(HttpServletRequest request) {
  44 + //公匙返回页面
  45 + Map<String, Object> rs = new HashMap<>();
  46 + rs.put("publickey", RSAUtils.generateBase64PublicKey());
  47 + return rs;
  48 + }
  49 +
  50 + //需要验证码的账号
  51 + public static Map<String, Integer> captchaMap = new HashMap<>();
  52 +
  53 + @RequestMapping(value = "/login", method = RequestMethod.POST)
  54 + public Map<String, Object> login(HttpServletRequest request, @RequestParam String userName,
  55 + @RequestParam String password, String captcha) {
  56 +
  57 + Map<String, Object> rs = new HashMap<>();
  58 + rs.put("status", ResponseCode.ERROR);
  59 + try {
  60 + HttpSession session = request.getSession();
  61 + rs.put("captcha", session.getAttribute("captcha"));
  62 +
  63 + if (captchaMap.get(userName) != null && captchaMap.get(userName) >= 3) {
  64 + //校验验证码
  65 + String verCode = (String) session
  66 + .getAttribute(com.google.code.kaptcha.Constants.KAPTCHA_SESSION_KEY);
  67 +
  68 + if (StringUtils.isBlank(captcha))
  69 + return put(rs, "msg", "请输入验证码");
  70 +
  71 + if (!verCode.equals(captcha))
  72 + return put(rs, "msg", "验证码有误,请刷新后重新输入");
  73 + }
  74 +
  75 + //解密RSA
  76 + try {
  77 + userName = RSAUtils.decryptBase64(userName);
  78 + password = RSAUtils.decryptBase64(password);
  79 + } catch (RuntimeException e) {
  80 + return put(rs, "msg", "decrypt RSA fail!可能页面已过期,尝试刷新页面。");
  81 + }
  82 +
  83 + SysUser user = sysUserService.findByUserName(userName);
  84 + if (null == user)
  85 + return put(rs, "msg", "不存在的用户");
  86 +
  87 + if (!user.isEnabled())
  88 + return put(rs, "msg", "该用户已被锁定,请联系管理员");
  89 +
  90 + // 校验密码
  91 + boolean matchStatus = new BCryptPasswordEncoder(4).matches(password, user.getPassword());
  92 + if (!matchStatus) {
  93 + rs.put("msg", "密码有误");
  94 +
  95 + Integer captchSize = captchaMap.get(userName);
  96 + if (null == captchSize)
  97 + captchSize = 0;
  98 +
  99 + captchSize++;
  100 + captchaMap.put(userName, captchSize);
  101 + return rs;
  102 + }
  103 +
  104 + // 登录
  105 + SecurityUtils.login(user, request);
  106 + //session里写入用户名,webSocket连接时标识身份用
  107 + session.setAttribute(Constants.SESSION_USERNAME, user.getUserName());
  108 +
  109 + //获取公司权限数据
  110 + List<CompanyAuthority> cmyAuths = companyAuthorityService.findByUser(user);
  111 + session.setAttribute(Constants.COMPANY_AUTHORITYS, cmyAuths);
  112 +
  113 + captchaMap.remove(userName);
  114 + rs.put("status", ResponseCode.SUCCESS);
  115 + } catch (Exception e) {
  116 + logger.error("", e);
  117 + rs.put("msg", "服务器出现异常,请联系管理员");
  118 + }
  119 + return rs;
  120 + }
  121 +
  122 + @RequestMapping(value = "/change_user", method = RequestMethod.POST)
  123 + public Map<String, Object> changeUser(HttpServletRequest request, @RequestParam String userName,
  124 + @RequestParam String password) {
  125 +
  126 + Map<String, Object> rs = new HashMap<>();
  127 + rs.put("status", ResponseCode.ERROR);
  128 + try {
  129 + HttpSession session = request.getSession();
  130 +
  131 + SysUser user = sysUserService.findByUserName(userName);
  132 + if (null == user)
  133 + return put(rs, "msg", "不存在的用户");
  134 +
  135 + if (!user.isEnabled())
  136 + return put(rs, "msg", "该用户已被锁定,请联系管理员");
  137 +
  138 + // 校验密码
  139 + boolean matchStatus = new BCryptPasswordEncoder(4).matches(password, user.getPassword());
  140 + if (!matchStatus)
  141 + return put(rs, "msg", "密码有误");
  142 +
  143 + // 登录
  144 + SecurityUtils.login(user, request);
  145 + //session里写入用户名,webSocket连接时标识身份用
  146 + session.setAttribute(Constants.SESSION_USERNAME, user.getUserName());
  147 +
  148 + //获取公司权限数据
  149 + List<CompanyAuthority> cmyAuths = companyAuthorityService.findByUser(user);
  150 + session.setAttribute(Constants.COMPANY_AUTHORITYS, cmyAuths);
  151 + rs.put("status", ResponseCode.SUCCESS);
  152 + } catch (Exception e) {
  153 + logger.error("", e);
  154 + rs.put("msg", "服务器出现异常,请联系管理员");
  155 + }
  156 + return rs;
  157 + }
  158 +
  159 + /**
  160 + * 返回当前用户的公司权限数据,用于构建页面级联下拉框
  161 + *
  162 + * @return
  163 + */
  164 + @RequestMapping("companyData")
  165 + public List<CompanyData> companyData(HttpServletRequest request) {
  166 + List<CompanyData> rs = new ArrayList<>();
  167 + CompanyData companyData;
  168 +
  169 + ArrayListMultimap<String, CompanyAuthority> map = ArrayListMultimap.create();
  170 + List<CompanyAuthority> cmyAuths = (List<CompanyAuthority>) request.getSession().getAttribute(Constants.COMPANY_AUTHORITYS);
  171 +
  172 + for (CompanyAuthority cAuth : cmyAuths) {
  173 + map.put(cAuth.getCompanyCode() + "_" + cAuth.getCompanyName(), cAuth);
  174 + }
  175 +
  176 + Set<String> keys = map.keySet();
  177 + String[] temps;
  178 + for (String k : keys) {
  179 + temps = k.split("_");
  180 +
  181 + companyData = new CompanyData();
  182 + companyData.setCompanyCode(temps[0]);
  183 + companyData.setCompanyName(temps[1]);
  184 + companyData.setChildren(new ArrayList<CompanyData.ChildrenCompany>());
  185 +
  186 + cmyAuths = map.get(k);
  187 + for (CompanyAuthority c : cmyAuths) {
  188 + companyData.getChildren().add(new CompanyData.ChildrenCompany(c.getSubCompanyCode(), c.getSubCompanyName()));
  189 + }
  190 +
  191 + rs.add(companyData);
  192 + }
  193 +
  194 + return rs;
  195 + }
  196 +
  197 + @RequestMapping(value = "/login/captchaStatus")
  198 + public int captchaStatus(String userName) {
  199 + Integer size = captchaMap.get(userName);
  200 + return size == null ? 0 : size;
  201 + }
  202 +
  203 + public Map<String, Object> put(Map<String, Object> rs, String key, Object val) {
  204 + rs.put(key, val);
  205 + return rs;
  206 + }
  207 +
  208 + /**
  209 + * @Title: loginFailure @Description: TODO(查询登录失败的详细信息) @param @param
  210 + * request @return String 返回类型 @throws
  211 + */
  212 + @RequestMapping("/loginFailure")
  213 + public String loginFailure(HttpServletRequest request) {
  214 + String msg = "";
  215 + HttpSession session = request.getSession();
  216 +
  217 + Object obj = session.getAttribute("SPRING_SECURITY_LAST_EXCEPTION");
  218 +
  219 + if (obj instanceof BadCredentialsException)
  220 + msg = "登录失败,用户名或密码错误.";
  221 + else if (obj instanceof SessionAuthenticationException)
  222 + msg = "登录失败,当前策略不允许重复登录.";
  223 + session.removeAttribute("SPRING_SECURITY_LAST_EXCEPTION");
  224 + return msg;
  225 + }
  226 +
  227 + @RequestMapping("/currentUser")
  228 + public SysUser currentUser() {
  229 + return SecurityUtils.getCurrentUser();
  230 + }
  231 +
  232 + /**
  233 + * @param id 用户ID
  234 + * @param enabled 状态
  235 + * @return
  236 + * @Title changeEnabled
  237 + * @Description: TODO(改变用户状态)
  238 + */
  239 + @RequestMapping("/changeEnabled")
  240 + public int changeEnabled(@RequestParam int id, @RequestParam int enabled) {
  241 + return sysUserService.changeEnabled(id, enabled);
  242 + }
  243 +
  244 + /**
  245 + * @param oldPWD 原始密码
  246 + * @param newPWD 新密码
  247 + * @param cnewPWD 确认新密码
  248 + * @return
  249 + * @Title changePWD
  250 + * @Description: TODO(修改密码)
  251 + */
  252 + @RequestMapping(value = "/changePWD", method = RequestMethod.POST)
  253 + public String changePWD(@RequestParam String oldPWD, @RequestParam String newPWD, @RequestParam String cnewPWD) {
  254 + SysUser sysUser = SecurityUtils.getCurrentUser();
  255 + String msg = "";
  256 + if (new BCryptPasswordEncoder(4).matches(oldPWD, sysUser.getPassword())) {
  257 + if (oldPWD.equals(newPWD)) {
  258 + msg = "新密码不能跟原始密码一样!";
  259 + } else {
  260 + if (newPWD.equals(cnewPWD)) {
  261 + sysUserService.changePWD(sysUser.getId(), newPWD);
  262 + msg = "修改成功!";
  263 + } else {
  264 + msg = "新密码两次输入不一致!";
  265 + }
  266 + }
  267 + } else {
  268 + msg = "原始密码错误!";
  269 + }
  270 + return msg;
  271 + }
  272 +
  273 + @RequestMapping(value = "/register", method = RequestMethod.POST)
  274 + public Map<String, Object> register(SysUser u) {
  275 + return sysUserService.register(u);
  276 + }
  277 +
  278 + @RequestMapping(value = "/all_distinct")
  279 + public List<SysUser> findAll_distinct() {
  280 + return sysUserService.findAll_distinct();
  281 + }
250 282 }
... ...
src/main/java/com/bsth/data/gpsdata/GpsEntity.java
... ... @@ -79,6 +79,12 @@ public class GpsEntity implements Cloneable{
79 79 @JsonIgnore
80 80 private StationRoute station;
81 81  
  82 + /**
  83 + * 前置约束 -站点编码
  84 + */
  85 + @JsonIgnore
  86 + private String premiseCode;
  87 +
82 88 /** 状态 */
83 89 private String signalState = "normal";
84 90  
... ... @@ -358,4 +364,12 @@ public class GpsEntity implements Cloneable{
358 364 public void setServerTimestamp(Long serverTimestamp) {
359 365 this.serverTimestamp = serverTimestamp;
360 366 }
  367 +
  368 + public String getPremiseCode() {
  369 + return premiseCode;
  370 + }
  371 +
  372 + public void setPremiseCode(String premiseCode) {
  373 + this.premiseCode = premiseCode;
  374 + }
361 375 }
... ...
src/main/java/com/bsth/data/gpsdata/arrival/GeoCacheData.java
... ... @@ -3,8 +3,10 @@ package com.bsth.data.gpsdata.arrival;
3 3 import com.bsth.data.gpsdata.GpsEntity;
4 4 import com.bsth.data.gpsdata.arrival.entity.StationRoute;
5 5 import com.bsth.data.gpsdata.arrival.entity.TimedEnableStationRoute;
  6 +import com.bsth.data.gpsdata.arrival.precondition.entity.PreconditionGeo;
6 7 import com.bsth.data.gpsdata.arrival.utils.CircleQueue;
7 8 import com.bsth.data.gpsdata.arrival.utils.StationRouteComp;
  9 +import com.google.common.base.Splitter;
8 10 import com.google.common.collect.ArrayListMultimap;
9 11 import com.vividsolutions.jts.geom.Coordinate;
10 12 import com.vividsolutions.jts.geom.GeometryFactory;
... ... @@ -14,6 +16,7 @@ import org.apache.commons.lang3.StringUtils;
14 16 import org.slf4j.Logger;
15 17 import org.slf4j.LoggerFactory;
16 18 import org.springframework.beans.factory.annotation.Autowired;
  19 +import org.springframework.jdbc.core.BeanPropertyRowMapper;
17 20 import org.springframework.jdbc.core.JdbcTemplate;
18 21 import org.springframework.jdbc.core.RowMapper;
19 22 import org.springframework.stereotype.Component;
... ... @@ -42,6 +45,8 @@ public class GeoCacheData {
42 45  
43 46 //线路站点路由
44 47 private static ArrayListMultimap<String, StationRoute> stationCacheMap;
  48 + //线路前置进站围栏
  49 + public static ArrayListMultimap<String, PreconditionGeo> premiseGeoMap;
45 50  
46 51 //线路_上下行_站点编码 ——> 站点
47 52 private static Map<String, StationRoute> routeCodeMap;
... ... @@ -56,7 +61,6 @@ public class GeoCacheData {
56 61  
57 62 //需要定时刷新的站点路由
58 63 public static Map<String, TimedEnableStationRoute> tesMap = new HashMap<>();
59   - //TimedEnableStationRoute
60 64  
61 65 @Autowired
62 66 JdbcTemplate jdbcTemplate;
... ... @@ -68,10 +72,6 @@ public class GeoCacheData {
68 72 public static void putGps(GpsEntity gps) {
69 73 CircleQueue<GpsEntity> queue = gpsCacheMap.get(gps.getNbbm());
70 74 if (queue == null) {
71   - /*//第一个点从站内开始
72   - if (gps.getInstation() == 0)
73   - return;*/
74   -
75 75 queue = new CircleQueue<>(CACHE_SIZE);
76 76 gpsCacheMap.put(gps.getNbbm(), queue);
77 77 }
... ... @@ -146,6 +146,61 @@ public class GeoCacheData {
146 146  
147 147 //加载路段信息
148 148 loadRoadsData();
  149 +
  150 + //加载前置进站围栏
  151 + loadPremiseGeoData();
  152 + }
  153 +
  154 + private void loadPremiseGeoData() {
  155 + ArrayListMultimap<String, PreconditionGeo> premiseGeoMapCopy = ArrayListMultimap.create();
  156 +
  157 + String sql = "select * from bsth_f_geo_premise";
  158 + List<PreconditionGeo> list = jdbcTemplate.query(sql, BeanPropertyRowMapper.newInstance(PreconditionGeo.class));
  159 +
  160 + List<String> coordList;
  161 + String[] cs;
  162 + com.bsth.util.Geo.Point point;
  163 + List<com.bsth.util.Geo.Point> ps;
  164 + StationRoute sr;
  165 + for(PreconditionGeo p : list){
  166 + try{
  167 + sr = routeCodeMap.get(p.getLineCode()+"_"+p.getUpDown()+"_"+p.getStationCode());
  168 + p.setOrder(sr.getRouteSort());
  169 + //polygon
  170 + ps = new ArrayList<>();
  171 + coordList = Splitter.on(",").trimResults().splitToList(p.getCoords());
  172 + for(String c : coordList){
  173 + cs = c.split(" ");
  174 + point = new com.bsth.util.Geo.Point(Double.parseDouble(cs[0]), Double.parseDouble(cs[1]));
  175 + ps.add(point);
  176 + }
  177 +
  178 + p.setPolygon(new com.bsth.util.Geo.Polygon(ps));
  179 +
  180 + sr.setPremise(true);
  181 + //按线路,走向分组
  182 + premiseGeoMapCopy.put(p.getLineCode()+"_"+p.getUpDown(), p);
  183 + }catch (Exception e){
  184 + logger.error("", e);
  185 + }
  186 + }
  187 +
  188 + //排序
  189 + Set<String> ks = premiseGeoMapCopy.keySet();
  190 + PreconditionGeoComp comp = new PreconditionGeoComp();
  191 + for(String k : ks){
  192 + Collections.sort(premiseGeoMapCopy.get(k), comp);
  193 + }
  194 +
  195 + premiseGeoMap = premiseGeoMapCopy;
  196 + }
  197 +
  198 + private static class PreconditionGeoComp implements Comparator<PreconditionGeo>{
  199 +
  200 + @Override
  201 + public int compare(PreconditionGeo p1, PreconditionGeo p2) {
  202 + return p1.getOrder() - p2.getOrder();
  203 + }
149 204 }
150 205  
151 206 private void loadRoadsData() {
... ...
src/main/java/com/bsth/data/gpsdata/arrival/SignalHandle.java
... ... @@ -78,6 +78,7 @@ public abstract class SignalHandle {
78 78 byte updown = Byte.parseByte(sch.getXlDir());
79 79 //gps 切换走向
80 80 gps.setUpDown(updown);
  81 + gps.setPremiseCode(null);
81 82  
82 83 List<StationRoute> srs = GeoCacheData.getStationRoute(sch.getXlBm(), updown);
83 84 StationRoute station = GeoUtils.gpsInStation(gps, srs);
... ...
src/main/java/com/bsth/data/gpsdata/arrival/entity/StationRoute.java
... ... @@ -60,6 +60,11 @@ public class StationRoute {
60 60  
61 61 private String name;
62 62  
  63 + /**
  64 + * 是否有前置进站约束
  65 + */
  66 + private boolean premise;
  67 +
63 68 public String getCode() {
64 69 return code;
65 70 }
... ... @@ -147,5 +152,13 @@ public class StationRoute {
147 152 public void setName(String name) {
148 153 this.name = name;
149 154 }
  155 +
  156 + public boolean isPremise() {
  157 + return premise;
  158 + }
  159 +
  160 + public void setPremise(boolean premise) {
  161 + this.premise = premise;
  162 + }
150 163 }
151 164  
... ...
src/main/java/com/bsth/data/gpsdata/arrival/handlers/InOutStationSignalHandle.java
... ... @@ -4,6 +4,7 @@ import com.bsth.data.LineConfigData;
4 4 import com.bsth.data.gpsdata.GpsEntity;
5 5 import com.bsth.data.gpsdata.arrival.GeoCacheData;
6 6 import com.bsth.data.gpsdata.arrival.SignalHandle;
  7 +import com.bsth.data.gpsdata.arrival.entity.StationRoute;
7 8 import com.bsth.data.gpsdata.arrival.utils.CircleQueue;
8 9 import com.bsth.data.gpsdata.arrival.utils.ScheduleSignalState;
9 10 import com.bsth.data.gpsdata.arrival.utils.SignalSchPlanMatcher;
... ... @@ -148,6 +149,7 @@ public class InOutStationSignalHandle extends SignalHandle{
148 149 && (gps.getInstation()==0 || !gps.getStopNo().equals(prev.getStopNo()))
149 150 && !willDepart(gps, prev, sch)){
150 151  
  152 + gps.setPremiseCode(null);
151 153 //发车班次匹配
152 154 signalSchPlanMatcher.outMatch(gps, sch);
153 155 sch = dayOfSchedule.executeCurr(gps.getNbbm());
... ... @@ -234,6 +236,10 @@ public class InOutStationSignalHandle extends SignalHandle{
234 236 * @return
235 237 */
236 238 private boolean outManyFit(GpsEntity gps, ScheduleRealInfo sch) {
  239 + LineConfig conf = lineConfigData.get(sch.getXlBm());
  240 + if(null != conf && conf.isLockFirstOutTime())
  241 + return false;//锁定第一个发车信号,不匹配最佳
  242 +
237 243 if(StringUtils.isNotEmpty(sch.getZdsjActual()))
238 244 return false;
239 245  
... ... @@ -289,7 +295,7 @@ public class InOutStationSignalHandle extends SignalHandle{
289 295 ScheduleRealInfo sch = dayOfSchedule.executeCurr(gps.getNbbm());
290 296  
291 297 if(gps.getStopNo().equals(sch.getZdzCode())
292   - && !gps.getStopNo().equals(prev.getStopNo())){
  298 + && (!gps.getStopNo().equals(prev.getStopNo()) || gps.getStopNo().equals(prev.getPremiseCode()))){
293 299  
294 300 int diff = 0;
295 301 try{
... ... @@ -305,6 +311,11 @@ public class InOutStationSignalHandle extends SignalHandle{
305 311 if(Math.abs(diff) > MAX_NORMAL_DIFF)
306 312 return;
307 313  
  314 + //校验进站前置约束
  315 + if(!validInPremise(gps)){
  316 + return;
  317 + }
  318 +
308 319 //环线或内外圈 ,飘出去再回来
309 320 if(sch.getQdzCode().equals(sch.getZdzCode())
310 321 && StringUtils.isNotEmpty(sch.getFcsjActual())
... ... @@ -409,6 +420,28 @@ public class InOutStationSignalHandle extends SignalHandle{
409 420 }
410 421  
411 422 /**
  423 + * 校验进站前置约束
  424 + * @param gps
  425 + * @return
  426 + */
  427 + private boolean validInPremise(GpsEntity gps) {
  428 + StationRoute sr = gps.getStation();
  429 + if(null == sr || !sr.isPremise())
  430 + return true;
  431 +
  432 + String premiseCode = gps.getPremiseCode();
  433 +
  434 + if(StringUtils.isNotEmpty(premiseCode) && premiseCode.equals(gps.getStopNo())){
  435 + logger.info("满足前置进站约束 " + premiseCode);
  436 + return true;
  437 + }
  438 + else{
  439 + logger.info(gps.getNbbm() + " not premiseCode 不满足前置进站约束 " + premiseCode);
  440 + }
  441 + return false;
  442 + }
  443 +
  444 + /**
412 445 * 和当前进站信号最匹配的一个班次
413 446 * @param gps
414 447 * @param halfList
... ...
src/main/java/com/bsth/data/gpsdata/arrival/handlers/StationInsideHandle.java
... ... @@ -6,6 +6,8 @@ import com.bsth.data.gpsdata.arrival.SignalHandle;
6 6 import com.bsth.data.gpsdata.arrival.entity.StationRoute;
7 7 import com.bsth.data.gpsdata.arrival.utils.CircleQueue;
8 8 import com.bsth.data.gpsdata.arrival.utils.GeoUtils;
  9 +import org.slf4j.Logger;
  10 +import org.slf4j.LoggerFactory;
9 11 import org.springframework.stereotype.Component;
10 12  
11 13 import java.util.List;
... ... @@ -17,6 +19,7 @@ import java.util.List;
17 19 @Component
18 20 public class StationInsideHandle extends SignalHandle {
19 21  
  22 + Logger logger = LoggerFactory.getLogger(this.getClass());
20 23  
21 24 @Override
22 25 public boolean handle(GpsEntity gps, CircleQueue<GpsEntity> prevs) {
... ... @@ -37,13 +40,41 @@ public class StationInsideHandle extends SignalHandle {
37 40 gps.setStation(station);
38 41 }
39 42  
  43 + //是否在进站前置围栏内
  44 + String premiseCode = GeoUtils.gpsInPremiseGeo(gps);
  45 + gps.setPremiseCode(premiseCode);
  46 +
  47 + if(isNotEmpty(prevs)){
  48 + try {
  49 + GpsEntity prev = prevs.getTail();
  50 + //继承前置围栏
  51 + if(null == premiseCode && null != prev.getPremiseCode())
  52 + gps.setPremiseCode(prev.getPremiseCode());
  53 +
  54 + //在场,站外
  55 + if(gps.getInstation() == 0){
  56 + //继承上一个点的站点编码
  57 + gps.setStopNo(prev.getStopNo());
  58 +
  59 + /*if(null == premiseCode && null != prev.getPremiseCode())
  60 + gps.setPremiseCode(prev.getPremiseCode());*/
  61 + }
  62 + /*else if(null != gps.getPremiseCode() && !gps.getStopNo().equals(gps.getPremiseCode())){
  63 + gps.setPremiseCode(null);
  64 + }*/
  65 + }catch (Exception e){
  66 + logger.error("", e);
  67 + }
  68 + }
  69 +
  70 +/*
40 71 //在场,站外
41 72 if(gps.getInstation() == 0 && isNotEmpty(prevs)){
42 73 //继承上一个点的站点编码
43 74 GpsEntity prev = prevs.getTail();
44 75 gps.setStopNo(prev.getStopNo());
45 76 }
46   -
  77 +*/
47 78 return true;
48 79 }
49 80 }
... ...
src/main/java/com/bsth/data/gpsdata/arrival/precondition/InPreconditionHandler.java 0 → 100644
  1 +package com.bsth.data.gpsdata.arrival.precondition;
  2 +
  3 +import com.bsth.data.gpsdata.GpsEntity;
  4 +import org.springframework.stereotype.Component;
  5 +
  6 +/**
  7 + * 进站(前置电子围栏)
  8 + * Created by panzhao on 2017/9/23.
  9 + */
  10 +@Component
  11 +public class InPreconditionHandler {
  12 +
  13 + /**
  14 + * 进站动作是否有通过前置围栏
  15 + * @param gps
  16 + * @param prev
  17 + * @return
  18 + */
  19 + public boolean isPass(GpsEntity gps, GpsEntity prev){
  20 + return false;
  21 + }
  22 +}
... ...
src/main/java/com/bsth/data/gpsdata/arrival/precondition/entity/PreconditionGeo.java 0 → 100644
  1 +package com.bsth.data.gpsdata.arrival.precondition.entity;
  2 +
  3 +import com.bsth.util.Geo.Polygon;
  4 +
  5 +/**
  6 + * 前置围栏 -地理坐标
  7 + * Created by panzhao on 2017/9/23.
  8 + */
  9 +public class PreconditionGeo {
  10 +
  11 + private String name;
  12 +
  13 + /**
  14 + * 前置约束的站点编码
  15 + */
  16 + private String stationCode;
  17 +
  18 + /**
  19 + * 线路编码
  20 + */
  21 + private String lineCode;
  22 +
  23 + /**
  24 + * 上下行
  25 + */
  26 + private int upDown;
  27 +
  28 + /**
  29 + * 多边形坐标
  30 + */
  31 + private String coords;
  32 +
  33 + private com.bsth.util.Geo.Polygon polygon;
  34 +
  35 + private Integer order;
  36 +
  37 + public String getName() {
  38 + return name;
  39 + }
  40 +
  41 + public void setName(String name) {
  42 + this.name = name;
  43 + }
  44 +
  45 + public String getStationCode() {
  46 + return stationCode;
  47 + }
  48 +
  49 + public void setStationCode(String stationCode) {
  50 + this.stationCode = stationCode;
  51 + }
  52 +
  53 + public String getLineCode() {
  54 + return lineCode;
  55 + }
  56 +
  57 + public void setLineCode(String lineCode) {
  58 + this.lineCode = lineCode;
  59 + }
  60 +
  61 + public int getUpDown() {
  62 + return upDown;
  63 + }
  64 +
  65 + public void setUpDown(int upDown) {
  66 + this.upDown = upDown;
  67 + }
  68 +
  69 + public String getCoords() {
  70 + return coords;
  71 + }
  72 +
  73 + public void setCoords(String coords) {
  74 + this.coords = coords;
  75 + }
  76 +
  77 + public Integer getOrder() {
  78 + return order;
  79 + }
  80 +
  81 + public void setOrder(Integer order) {
  82 + this.order = order;
  83 + }
  84 +
  85 + public Polygon getPolygon() {
  86 + return polygon;
  87 + }
  88 +
  89 + public void setPolygon(Polygon polygon) {
  90 + this.polygon = polygon;
  91 + }
  92 +}
... ...
src/main/java/com/bsth/data/gpsdata/arrival/utils/GeoUtils.java
... ... @@ -3,6 +3,7 @@ package com.bsth.data.gpsdata.arrival.utils;
3 3 import com.bsth.data.gpsdata.GpsEntity;
4 4 import com.bsth.data.gpsdata.arrival.GeoCacheData;
5 5 import com.bsth.data.gpsdata.arrival.entity.StationRoute;
  6 +import com.bsth.data.gpsdata.arrival.precondition.entity.PreconditionGeo;
6 7 import com.vividsolutions.jts.geom.Coordinate;
7 8 import com.vividsolutions.jts.geom.GeometryFactory;
8 9 import com.vividsolutions.jts.geom.LineString;
... ... @@ -169,6 +170,28 @@ public class GeoUtils {
169 170 }
170 171  
171 172 /**
  173 + * 是否在进站前置围栏内
  174 + * @param gps
  175 + * @return
  176 + */
  177 + public static String gpsInPremiseGeo(GpsEntity gps) {
  178 + List<PreconditionGeo> list = GeoCacheData.premiseGeoMap.get(gps.getLineId()+"_"+gps.getUpDown());
  179 +
  180 + if(null == list || list.size()==0)
  181 + return null;
  182 +
  183 + com.bsth.util.Geo.Point point = new com.bsth.util.Geo.Point(gps.getLon(), gps.getLat());
  184 + com.bsth.util.Geo.Polygon polygon;
  185 + for(PreconditionGeo p : list){
  186 + polygon = p.getPolygon();
  187 + if(com.bsth.util.Geo.GeoUtils.isPointInPolygon(point, polygon)){
  188 + return p.getStationCode();
  189 + }
  190 + }
  191 + return null;
  192 + }
  193 +
  194 + /**
172 195 * 是否是有效的连续点
173 196 * @param prevGps
174 197 * @param gps
... ...
src/main/java/com/bsth/data/gpsdata/recovery/GpsDataRecovery.java
... ... @@ -60,7 +60,7 @@ public class GpsDataRecovery implements ApplicationContextAware {
60 60 for (String nbbm : keys) {
61 61 Collections.sort(listMap.get(nbbm), comp);
62 62 threadPool.execute(new RecoveryThread(listMap.get(nbbm), count));
63   - /*if(nbbm.equals("S0K-004"))
  63 + /*if(nbbm.equals("W2H-015"))
64 64 new RecoveryThread(listMap.get(nbbm), count).run();*/
65 65 /*if(lineId.equals("60028"))
66 66 new RecoveryThread(listMap.get(lineId), count).run();*/
... ... @@ -84,7 +84,7 @@ public class GpsDataRecovery implements ApplicationContextAware {
84 84 Calendar calendar = Calendar.getInstance();
85 85 int dayOfYear = calendar.get(Calendar.DAY_OF_YEAR);
86 86  
87   - String sql = "select DEVICE_ID,LAT,LON,TS,SPEED_GPS,LINE_ID,SERVICE_STATE from bsth_c_gps_info where days_year=246";// + dayOfYear;
  87 + String sql = "select DEVICE_ID,LAT,LON,TS,SPEED_GPS,LINE_ID,SERVICE_STATE from bsth_c_gps_info where days_year=267";// + dayOfYear;
88 88 JdbcTemplate jdbcTemplate = new JdbcTemplate(DBUtils_MS.getDataSource());
89 89  
90 90 List<GpsEntity> list =
... ... @@ -153,7 +153,7 @@ public class GpsDataRecovery implements ApplicationContextAware {
153 153 boolean task;
154 154 for (GpsEntity gps : list) {
155 155 try {
156   - /*if(gps.getTimestamp() >= 1504298280000L){
  156 + /*if(gps.getTimestamp() >= 1506216540000L){
157 157 System.out.println("debugger...");
158 158 }*/
159 159 //是否有任务
... ...
src/main/java/com/bsth/data/gpsdata/thread/GpsDataLoaderThread.java
... ... @@ -48,11 +48,11 @@ public class GpsDataLoaderThread extends Thread {
48 48 //0:从GPS客户端内存获取 -1:从网关获取
49 49 private static int flag = 0;
50 50  
51   - public static void setFlag(int v){
  51 + public static void setFlag(int v) {
52 52 flag = v;
53 53 }
54 54  
55   - public static int getFlag(int v){
  55 + public static int getFlag(int v) {
56 56 return flag;
57 57 }
58 58  
... ... @@ -65,7 +65,7 @@ public class GpsDataLoaderThread extends Thread {
65 65 @Override
66 66 public void run() {
67 67 try {
68   - if(flag == 0)
  68 + if (flag == 0)
69 69 load();
70 70 else
71 71 loadByGateway();
... ... @@ -76,6 +76,7 @@ public class GpsDataLoaderThread extends Thread {
76 76  
77 77 /**
78 78 * 从网关获取实时GPS数据
  79 + *
79 80 * @throws Exception
80 81 */
81 82 public void loadByGateway() throws Exception {
... ... @@ -107,6 +108,9 @@ public class GpsDataLoaderThread extends Thread {
107 108 if (jsonObj != null)
108 109 list = JSON.parseArray(jsonObj.getString("data"), GpsEntity.class);
109 110  
  111 + //过滤掉无效的点位
  112 + list = filterInvalid(list);
  113 +
110 114 String nbbm;
111 115 GpsEntity old;
112 116 for (GpsEntity gps : list) {
... ... @@ -130,7 +134,7 @@ public class GpsDataLoaderThread extends Thread {
130 134 //有更新的点位
131 135 updateList.add(gps);
132 136 }
133   - logger.info("全量点:"+ list.size() +",更新点" + updateList.size());
  137 + logger.info("全量点:" + list.size() + ",更新点" + updateList.size());
134 138 //分析数据
135 139 gpsRealAnalyse.analyse(updateList);
136 140 } else
... ... @@ -146,9 +150,33 @@ public class GpsDataLoaderThread extends Thread {
146 150 }
147 151  
148 152 /**
  153 + * 过滤无效的gps点位
  154 + *
  155 + * @param list
  156 + * @return
  157 + */
  158 + private List<GpsEntity> filterInvalid(List<GpsEntity> list) {
  159 + List<GpsEntity> rsList = new ArrayList<>();
  160 +
  161 + try {
  162 + for (GpsEntity gps : list) {
  163 + if (gps.getValid() == 0)
  164 + rsList.add(gps);
  165 + }
  166 +
  167 + if (rsList.size() < list.size())
  168 + logger.info("过滤无效的点位 : " + (list.size() - rsList.size()));
  169 + } catch (Exception e) {
  170 + logger.error("", e);
  171 + rsList = list;
  172 + }
  173 + return rsList;
  174 + }
  175 +
  176 + /**
149 177 * 从客户端内存获取GPS数据
150 178 */
151   - public void load() throws Exception{
  179 + public void load() throws Exception {
152 180 List<GpsEntity> list = null;
153 181 CloseableHttpClient httpClient = null;
154 182 CloseableHttpResponse response = null;
... ... @@ -174,6 +202,10 @@ public class GpsDataLoaderThread extends Thread {
174 202 stringBuffer.append(str);
175 203  
176 204 list = JSON.parseArray(stringBuffer.toString(), GpsEntity.class);
  205 +
  206 + //过滤掉无效的点位
  207 + list = filterInvalid(list);
  208 +
177 209 String nbbm;
178 210 logger.info("load end!");
179 211 for (GpsEntity gps : list) {
... ...
src/main/java/com/bsth/data/schedule/late_adjust/ScheduleLateThread.java
... ... @@ -6,6 +6,8 @@ import com.bsth.data.schedule.ScheduleComparator;
6 6 import com.bsth.entity.realcontrol.ScheduleRealInfo;
7 7 import com.bsth.websocket.handler.SendUtils;
8 8 import org.apache.commons.lang3.StringUtils;
  9 +import org.slf4j.Logger;
  10 +import org.slf4j.LoggerFactory;
9 11 import org.springframework.beans.factory.annotation.Autowired;
10 12 import org.springframework.stereotype.Component;
11 13  
... ... @@ -31,43 +33,49 @@ public class ScheduleLateThread extends Thread{
31 33 @Autowired
32 34 SendUtils sendUtils;
33 35  
  36 + Logger logger = LoggerFactory.getLogger(this.getClass());
  37 +
34 38 private static Comparator<ScheduleRealInfo> cpm = new ScheduleComparator.DFSJ();
35 39  
36 40 @Override
37 41 public void run() {
38   - List<ScheduleRealInfo> all = new ArrayList<>(dayOfSchedule.findAll());
39   - Collections.sort(all, cpm);
  42 + try{
  43 + List<ScheduleRealInfo> all = new ArrayList<>(dayOfSchedule.findAll());
  44 + Collections.sort(all, cpm);
40 45  
41   - long t = System.currentTimeMillis();
42   - int size = all.size();
  46 + long t = System.currentTimeMillis();
  47 + int size = all.size();
43 48  
44   - ScheduleRealInfo sch;
45   - for(int i = 0; i < size; i ++){
46   - sch = all.get(i);
47   - if(sch.getDfsjT() > t)
48   - break;
  49 + ScheduleRealInfo sch;
  50 + for(int i = 0; i < size; i ++){
  51 + sch = all.get(i);
  52 + if(sch.getDfsjT() > t)
  53 + break;
49 54  
50   - if(sch.isLate())
51   - continue;
  55 + if(sch.isLate())
  56 + continue;
52 57  
53   - if(sch.getStatus() == 0
54   - && StringUtils.isEmpty(sch.getFcsjActual())){
  58 + if(sch.getStatus() == 0
  59 + && StringUtils.isEmpty(sch.getFcsjActual())){
55 60  
56   - //检查应发未到 当前班次无起点到达时间
57   - if(StringUtils.isEmpty(sch.getQdzArrDatesj())){
58   - ScheduleRealInfo prev = dayOfSchedule.prev(sch);
59   - //上一个班次也没有实际终点到达时间
60   - if(prev != null && StringUtils.isEmpty(prev.getZdsjActual())){
61   - //进入误点调整程序
62   - LateAdjustHandle.putLate(sch);
  61 + //检查应发未到 当前班次无起点到达时间
  62 + if(StringUtils.isEmpty(sch.getQdzArrDatesj())){
  63 + ScheduleRealInfo prev = dayOfSchedule.prev(sch);
  64 + //上一个班次也没有实际终点到达时间
  65 + if(prev != null && StringUtils.isEmpty(prev.getZdsjActual())){
  66 + //进入误点调整程序
  67 + LateAdjustHandle.putLate(sch);
  68 + }
63 69 }
64   - }
65 70  
66   - //应发未发
67   - sch.setLate(true);
68   - //通知客户端
69   - sendUtils.refreshSch(sch);
  71 + //应发未发
  72 + sch.setLate(true);
  73 + //通知客户端
  74 + sendUtils.refreshSch(sch);
  75 + }
70 76 }
  77 + }catch (Exception e){
  78 + logger.error("", e);
71 79 }
72 80 }
73 81 }
74 82 \ No newline at end of file
... ...
src/main/java/com/bsth/entity/directive/D80.java
... ... @@ -241,6 +241,7 @@ public class D80 {
241 241 DC0Data data = new DC0Data();
242 242 data.setOperCode2((short) 0x86);
243 243 data.setRequestAck((short) (reply == 0 ? 0x06 : 0x15));
  244 + data.setTimestamp(this.getTimestamp());
244 245 c0.setData(data);
245 246 this.setC0(c0);
246 247 }
... ...
src/main/java/com/bsth/entity/directive/DC0.java
1 1 package com.bsth.entity.directive;
2 2  
3   -import javax.persistence.Embeddable;
4   -import javax.persistence.Entity;
5   -import javax.persistence.GeneratedValue;
6   -import javax.persistence.Id;
7   -import javax.persistence.Table;
  3 +import javax.persistence.*;
8 4  
9 5 /**
10 6 *
... ... @@ -52,6 +48,12 @@ public class DC0 {
52 48 */
53 49 private Short requestAck;
54 50  
  51 + /**
  52 + * 时间戳
  53 + */
  54 + @Transient
  55 + private Long timestamp;
  56 +
55 57 public Short getOperCode2() {
56 58 return operCode2;
57 59 }
... ... @@ -67,6 +69,14 @@ public class DC0 {
67 69 public void setRequestAck(Short requestAck) {
68 70 this.requestAck = requestAck;
69 71 }
  72 +
  73 + public Long getTimestamp() {
  74 + return timestamp;
  75 + }
  76 +
  77 + public void setTimestamp(Long timestamp) {
  78 + this.timestamp = timestamp;
  79 + }
70 80 }
71 81  
72 82 public Integer getId() {
... ...
src/main/java/com/bsth/entity/realcontrol/LineConfig.java
... ... @@ -89,6 +89,11 @@ public class LineConfig {
89 89 private int upStopMinute;
90 90 private int downStopMinute;
91 91  
  92 + /**
  93 + * 使用第一个发车时间,不匹配最佳时间
  94 + */
  95 + private boolean lockFirstOutTime;
  96 +
92 97  
93 98 @OneToMany(cascade = CascadeType.ALL)
94 99 private Set<D80ReplyTemp> d80Temps = new HashSet<>();
... ... @@ -281,4 +286,12 @@ public class LineConfig {
281 286 public void setTwinsStation(String twinsStation) {
282 287 this.twinsStation = twinsStation;
283 288 }
  289 +
  290 + public boolean isLockFirstOutTime() {
  291 + return lockFirstOutTime;
  292 + }
  293 +
  294 + public void setLockFirstOutTime(boolean lockFirstOutTime) {
  295 + this.lockFirstOutTime = lockFirstOutTime;
  296 + }
284 297 }
... ...
src/main/java/com/bsth/entity/realcontrol/ScheduleRealInfo.java
... ... @@ -642,7 +642,8 @@ public class ScheduleRealInfo {
642 642 public void calcEndTime(){
643 643 //计划终点时间
644 644 if(this.getBcsj() != null){
645   - this.setZdsjT(this.getDfsjT() + (this.getBcsj() * 60 * 1000));
  645 + //this.setZdsjT(this.getDfsjT() + (this.getBcsj() * 60 * 1000));
  646 + this.setZdsjT(this.getFcsjT() + (this.getBcsj() * 60 * 1000));//计划终点时间不变
646 647 this.setZdsj(fmtHHmm.print(this.zdsjT));
647 648 }
648 649 }
... ...
src/main/java/com/bsth/filter/AccessLogFilter.java
1 1 package com.bsth.filter;
2 2  
3   -import javax.servlet.FilterChain;
4   -import javax.servlet.ServletException;
5   -import javax.servlet.http.HttpServletRequest;
6   -import javax.servlet.http.HttpServletResponse;
7   -
8   -import org.slf4j.Logger;
9   -import org.slf4j.LoggerFactory;
10   -import org.springframework.stereotype.Component;
11   -
12 3 import com.alibaba.fastjson.JSON;
  4 +import com.bsth.entity.sys.SysUser;
13 5 import com.bsth.security.util.SecurityUtils;
14 6 import com.bsth.util.IpUtils;
15 7 import com.google.common.collect.Lists;
16 8 import com.google.common.collect.Maps;
  9 +import org.slf4j.Logger;
  10 +import org.slf4j.LoggerFactory;
  11 +import org.springframework.stereotype.Component;
17 12  
  13 +import javax.servlet.FilterChain;
  14 +import javax.servlet.ServletException;
  15 +import javax.servlet.http.HttpServletRequest;
  16 +import javax.servlet.http.HttpServletResponse;
18 17 import java.io.IOException;
19 18 import java.util.Enumeration;
20 19 import java.util.List;
... ... @@ -38,7 +37,9 @@ public class AccessLogFilter extends BaseFilter {
38 37 HttpServletResponse response, FilterChain chain)
39 38 throws IOException, ServletException {
40 39  
41   - String username = SecurityUtils.getCurrentUser().getName();
  40 + SysUser user = SecurityUtils.getCurrentUser();
  41 + String username = user.getUserName();
  42 + String name = user.getName();
42 43 String jsessionId = request.getRequestedSessionId();
43 44 String ip = IpUtils.getIpAddr(request);
44 45 String userAgent = request.getHeader("User-Agent");
... ... @@ -47,7 +48,7 @@ public class AccessLogFilter extends BaseFilter {
47 48 String headers = getHeaders(request);
48 49  
49 50 StringBuilder s = new StringBuilder();
50   - s.append(getBlock(username));
  51 + s.append(getBlock(username + " -" + name));
51 52 s.append(getBlock(jsessionId));
52 53 s.append(getBlock(ip));
53 54 s.append(getBlock(userAgent));
... ...
src/main/java/com/bsth/service/gps/GpsServiceImpl.java
... ... @@ -256,6 +256,9 @@ public class GpsServiceImpl implements GpsService {
256 256 ArrivalEntity arrival;
257 257 while (rs.next()) {
258 258 serviceState = rs.getLong("SERVICE_STATE");
  259 + if(getGpsValid(serviceState) == 1)
  260 + continue;
  261 +
259 262 map = new HashMap<>();
260 263  
261 264 lon = rs.getFloat("LON");
... ... @@ -306,6 +309,10 @@ public class GpsServiceImpl implements GpsService {
306 309 return list;
307 310 }
308 311  
  312 + public static byte getGpsValid(long serviceState) {
  313 + return (byte)(((serviceState & 0x80000000) == 0x80000000) ? 1 : 0);
  314 + }
  315 +
309 316 public Map<String, ArrivalEntity> findArrivalByTs(int weekOfYear, Long st, Long et, String devicesInSql) {
310 317 Map<String, ArrivalEntity> map = new HashMap<>();
311 318  
... ...
src/main/java/com/bsth/service/impl/StationRouteServiceImpl.java
... ... @@ -843,8 +843,10 @@ public class StationRouteServiceImpl extends BaseServiceImpl&lt;StationRoute, Integ
843 843 /** 获取路段路由信息 @pararm:<lineId:线路ID;directions:方向> */
844 844 List<Object[]> sobje = routeRepository.sectionRouteVector(lineId,directions);
845 845 if(sobje.size()==1) {
846   - int dsleepStr = sobje.get(0)[2] == null || sobje.get(0)[2].equals("") ? 60 : Integer.valueOf(sobje.get(0)[2].toString());
847   - sleepStr = "\t" + String.valueOf(dsleepStr);
  846 + double dsleepStrt = sobje.get(0)[2] == null ? 60d : Double.valueOf(sobje.get(0)[2].toString());
  847 + sleepStr = "\t" + new DecimalFormat("0").format(dsleepStrt);
  848 +// int dsleepStr = sobje.get(0)[2] == null || sobje.get(0)[2].equals("") ? 60 : Integer.valueOf(sobje.get(0)[2].toString());
  849 +// sleepStr = "\t" + String.valueOf(dsleepStr);
848 850 }else if(sobje.size()>1){
849 851 for(int j =0;j<sobje.size();j++) {
850 852 double dsleepStrt = sobje.get(j)[2] == null || sobje.get(j)[2].equals("") ? 60d : Double.valueOf(sobje.get(j)[2].toString());
... ...
src/main/java/com/bsth/service/realcontrol/impl/ScheduleRealInfoServiceImpl.java
... ... @@ -251,12 +251,12 @@ public class ScheduleRealInfoServiceImpl extends BaseServiceImpl&lt;ScheduleRealInf
251 251 List<ScheduleRealInfo> ts = new ArrayList<>();
252 252 ts.add(schedule);
253 253 //调整终点时间和下一个班次的应到时间
254   - schedule.calcEndTime();
255   - ScheduleRealInfo nextSch = dayOfSchedule.nextByLp2(schedule);
  254 + //schedule.calcEndTime();
  255 + /*ScheduleRealInfo nextSch = dayOfSchedule.nextByLp2(schedule);
256 256 if (null != nextSch) {
257 257 nextSch.setQdzArrDatejh(schedule.getZdsj());
258 258 ts.add(nextSch);
259   - }
  259 + }*/
260 260  
261 261 //调整班次类型
262 262 if (StringUtils.isNotEmpty(bcType) && !bcType.equals(schedule.getBcType())) {
... ... @@ -3308,6 +3308,7 @@ public class ScheduleRealInfoServiceImpl extends BaseServiceImpl&lt;ScheduleRealInf
3308 3308 boolean dest2 = sch.getStatus() == -1;
3309 3309 if (!dest1 && dest2) {
3310 3310 oldSch.destroy();
  3311 + oldSch.setAdjustExps(sch.getAdjustExps());
3311 3312 aflog.log("烂班");
3312 3313 }
3313 3314 else if(dest1 && !dest2){
... ... @@ -3315,6 +3316,7 @@ public class ScheduleRealInfoServiceImpl extends BaseServiceImpl&lt;ScheduleRealInf
3315 3316 oldSch.setJhlc(oldSch.getJhlcOrig());
3316 3317 oldSch.setStatus(0);
3317 3318 oldSch.calcStatus();
  3319 + oldSch.setAdjustExps(null);
3318 3320 aflog.log("撤销烂班");
3319 3321 }
3320 3322  
... ...
src/main/java/com/bsth/service/traffic/impl/YgcBasicDataServiceImpl.java
... ... @@ -213,6 +213,7 @@ public class YgcBasicDataServiceImpl implements YgcBasicDataService{
213 213 private List<HashMap<String,String>> parseXml(StringBuffer sb){
214 214 List<HashMap<String,String>> list = new ArrayList<>();
215 215 HashMap<String,String> map;
  216 + HashMap<String,Integer> keyMap = new HashMap<>();
216 217 try {
217 218 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
218 219 DocumentBuilder builder = factory.newDocumentBuilder();
... ... @@ -238,13 +239,18 @@ public class YgcBasicDataServiceImpl implements YgcBasicDataService{
238 239 doc.getElementsByTagName("DDFS").item(i).getFirstChild().getNodeValue();
239 240 lineStandardCode = doc.getElementsByTagName("LineStandardCode").item(i).getFirstChild() == null ?"":
240 241 doc.getElementsByTagName("LineStandardCode").item(i).getFirstChild().getNodeValue();
  242 + // 保存相同lineId出现的次数
  243 + keyMap.put(lineId,keyMap.get(lineId) == null ? 1 : keyMap.get(lineId) + 1);
241 244 map = new HashMap<>();
242 245 map.put("lineName",lineName);
243 246 map.put("lineId",lineId);
244 247 map.put("abbreviation",abbreviation);
245 248 map.put("ddfs",ddfs);
246 249 map.put("lineStandardCode",lineStandardCode);
247   - list.add(map);
  250 + // 只保存第一次的lineId信息
  251 + if(keyMap.get(lineId) < 2){
  252 + list.add(map);
  253 + }
248 254 }
249 255 }
250 256 }catch (Exception e){
... ...
src/main/resources/static/pages/control/lineallot_v2/main.html
... ... @@ -283,7 +283,11 @@
283 283 }
284 284 else {
285 285 $(this).addClass('active');
286   - $('.checked_list').append('<span data-id="'+lineCode+'" class="item uk-card uk-card-default">'+name+'</span>');
  286 + var span = $('<span data-id="'+lineCode+'" class="item uk-card uk-card-default uk-animation-slide-bottom">'+name+'</span>')
  287 + .one('webkitAnimationEnd', function () {
  288 + $(this).removeClass('uk-animation-slide-bottom');
  289 + });
  290 + $('.checked_list').append(span);
287 291 }
288 292 });
289 293  
... ...
src/main/resources/static/pages/summary/work_hours/list.html
... ... @@ -263,8 +263,8 @@
263 263 }
264 264  
265 265 //日期选择器
266   - $('[name=rq_eq]', f).val('2017-09-17');
267   - flatpickr('.ct_search_form_wrap [name=rq_eq]', {"locale": "zh", maxDate: '2017-09-17', minDate: '2017-07-01'});
  266 + $('[name=rq_eq]', f).val('2017-09-24');
  267 + flatpickr('.ct_search_form_wrap [name=rq_eq]', {"locale": "zh", maxDate: '2017-09-24', minDate: '2017-07-01'});
268 268  
269 269 var comps;
270 270 //构建公司级联下拉框
... ...
src/main/resources/static/real_control_v2/css/main.css
... ... @@ -1690,4 +1690,13 @@ dd.disabled{
1690 1690  
1691 1691 dl.active>dd.disabled{
1692 1692 color: #ececec;
  1693 +}
  1694 +
  1695 +#change_user_options-modal .user_info{
  1696 + width: 360px;
  1697 + margin: auto;
  1698 +}
  1699 +
  1700 +.display_hide{
  1701 + display: none;
1693 1702 }
1694 1703 \ No newline at end of file
... ...
src/main/resources/static/real_control_v2/fragments/line_schedule/context_menu/sub_task_v2/add_custom.html
... ... @@ -92,8 +92,8 @@
92 92 return;
93 93 }
94 94 var data = dataArray[i];
95   - //里程为0的不保存
96   - if(data.mileage==0){
  95 + //营运里程为0的不保存
  96 + if(data.mileageType == 'service' && data.mileage==0){
97 97 i++;
98 98 f();
99 99 }
... ...
src/main/resources/static/real_control_v2/fragments/line_schedule/context_menu/sub_task_v2/add_in_out.html
... ... @@ -132,6 +132,7 @@
132 132 $f('reason',inf).val(sch.adjustExps);
133 133 $f('reason',outf).val(sch.adjustExps).trigger('change');
134 134 }
  135 + f.css('z-index', 99);
135 136 }
136 137  
137 138 function $f(name, f) {
... ... @@ -228,24 +229,32 @@
228 229 var htmlStr = template('st-v2-domains-changecar-form-temp', {inOutExps: gb_common.inOutExps});
229 230 $('.domains', half_form).html(htmlStr);
230 231 $('.domains', outf).html(htmlStr);
231   - half_form.css('z-index', 99).formValidation('addField', 'reason').formValidation('addField', 'nbbm');
  232 + half_form/*.css('z-index', 99)*/.formValidation('addField', 'reason').formValidation('addField', 'nbbm');
232 233 outf.trigger('add_reason_field');
233 234  
234 235 //车辆 autocomplete
235 236 var data = gb_data_basic.carsArray();
236 237 gb_common.carAutocomplete($('.autocomplete-cars', half_form), data);
  238 + gb_common.carAutocomplete($('.autocomplete-cars', outf), data);
237 239  
238 240 //同步车辆编码
239 241 $f('nbbm', half_form).on('input change', function () {
240 242 $f('nbbm', outf).val($(this).val());
241 243 });
  244 + $f('nbbm', outf).on('input change', function () {
  245 + $f('nbbm', half_form).val($(this).val());
  246 + });
242 247  
243 248 half_form.removeClass('destroy_form');
244 249  
245 250 //出场终点
246 251 $f('endStation',outf).val($f('endStation',sf).val()).trigger('change');
247   - //发合计公里重新计算
  252 + //发合计公里重新计算
248 253 $f('mileage', half_form).trigger('input');
  254 +
  255 + //调换出场子任务位置
  256 + outf.insertAfter(inf);
  257 + //half_form.insertBefore(outf);
249 258 }
250 259  
251 260 function disabledChangeCar() {
... ... @@ -284,7 +293,7 @@
284 293 }
285 294 var data = dataArray[i];
286 295 //里程为0的不保存
287   - if(data.mileage==0){
  296 + if(data.mileageType == 'service' && data.mileage==0){
288 297 i++;
289 298 f();
290 299 }
... ...
src/main/resources/static/real_control_v2/fragments/line_schedule/context_menu/sub_task_v2/main.html
... ... @@ -10,6 +10,7 @@
10 10 <li name="normal"><a>1、子任务</a></li>
11 11 <li name="in_out"><a>2、进出场</a></li>
12 12 <li name="range_turn"><a>3、区间调头</a></li>
  13 + <!--<li name="range_to_normal"><a>4、区间变全程</a></li>-->
13 14 </ul>
14 15 </div>
15 16 <div class="uk-width-8-10">
... ... @@ -17,6 +18,7 @@
17 18 <li class="tab_cont normalCont"></li>
18 19 <li class="tab_cont inOutCont"></li>
19 20 <li class="tab_cont rangeTurnCont"></li>
  21 + <!--<li class="tab_cont rangeToNormal"></li>-->
20 22 </ul>
21 23 </div>
22 24 </div>
... ... @@ -242,6 +244,7 @@
242 244 //区间调头
243 245 $('.rangeTurnCont', modal).html(st_doms.range_dom);
244 246 $('.add_range_wrap', modal).trigger('init', data);
  247 + //区间变全程
245 248 }
246 249 });
247 250  
... ...
src/main/resources/static/real_control_v2/fragments/line_schedule/context_menu/temp_sch/add_two_way.html
... ... @@ -272,6 +272,17 @@
272 272 $('.remarks-autocom', f1).on('selectitem.uk.autocomplete', function (e, data, acobject) {
273 273 $f('remarks', f2).val(data.value);
274 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 + });
275 286 //表单同步
276 287 $(f1).on('ct_callback', synchroFormData).trigger('ct_callback');
277 288 //修改1结束时间
... ... @@ -372,6 +383,7 @@
372 383 //第一个表单起点 = 第二个终点
373 384 $f('zdzCode', f2).val($f('qdzCode', f1).val()).trigger('change');
374 385 }
  386 +
375 387 };
376 388  
377 389  
... ...
src/main/resources/static/real_control_v2/fragments/north/nav/all_devices.html
... ... @@ -4,6 +4,7 @@
4 4 <div class="uk-modal-header">
5 5 <h2>所有接入平台的设备</h2></div>
6 6  
  7 + <div class="uk-alert uk-alert-danger">系统将不再接收和显示 “设备端自身标识为无效” 的GPS点位。如果设备连续发送无效的点位,即等同于离线。</div>
7 8 <div class="uk-panel uk-panel-box uk-panel-box-primary">
8 9 <form class="uk-form search-form">
9 10 <fieldset data-uk-margin>
... ...
src/main/resources/static/real_control_v2/fragments/north/nav/history_sch/editor.html
... ... @@ -34,14 +34,14 @@
34 34 </div>
35 35  
36 36 <script id="history-sch-edit-form-temp" type="text/html">
37   - <input type="hidden" name="id" value="{{id}}"/>
  37 + <input type="hidden" name="id" value="{{sch.id}}"/>
38 38  
39 39 <div class="uk-grid">
40 40 <div class="uk-width-1-3">
41 41 <div class="uk-form-row">
42 42 <label class="uk-form-label" >班次类型</label>
43 43 <div class="uk-form-controls">
44   - <select class="form-control nt-dictionary" data-code="{{bcType}}" name="bcType" data-group=ScheduleType></select>
  44 + <select class="form-control nt-dictionary" data-code="{{sch.bcType}}" name="bcType" data-group=ScheduleType></select>
45 45 </div>
46 46 </div>
47 47 </div>
... ... @@ -69,7 +69,7 @@
69 69 <label class="uk-form-label" >车辆</label>
70 70 <div class="uk-form-controls">
71 71 <div class="uk-autocomplete uk-form car-autocom">
72   - <input type="text" value="{{clZbh}}" name="clZbh" required>
  72 + <input type="text" value="{{sch.clZbh}}" name="clZbh" required>
73 73 </div>
74 74 </div>
75 75 </div>
... ... @@ -79,7 +79,7 @@
79 79 <label class="uk-form-label" >驾驶员</label>
80 80 <div class="uk-form-controls">
81 81 <div class="uk-autocomplete uk-form jsy-autocom">
82   - <input type="text" value="{{jGh}}/{{jName}}" name="jsy" required>
  82 + <input type="text" value="{{sch.jGh}}/{{sch.jName}}" name="jsy" required>
83 83 </div>
84 84 </div>
85 85 </div>
... ... @@ -89,7 +89,7 @@
89 89 <label class="uk-form-label" >售票员</label>
90 90 <div class="uk-form-controls">
91 91 <div class="uk-autocomplete uk-form spy-autocom">
92   - <input type="text" value="{{sGh}}/{{sName}}" name="spy">
  92 + <input type="text" value="{{sch.sGh}}/{{sch.sName}}" name="spy">
93 93 </div>
94 94 </div>
95 95 </div>
... ... @@ -101,7 +101,7 @@
101 101 <div class="uk-form-row">
102 102 <label class="uk-form-label" >计发</label>
103 103 <div class="uk-form-controls">
104   - <input type="time" value="{{fcsj}}" disabled>
  104 + <input type="time" value="{{sch.fcsj}}" disabled>
105 105 </div>
106 106 </div>
107 107 </div>
... ... @@ -109,7 +109,7 @@
109 109 <div class="uk-form-row">
110 110 <label class="uk-form-label" >待发</label>
111 111 <div class="uk-form-controls">
112   - <input type="time" name="dfsj" value="{{dfsj}}" required>
  112 + <input type="time" name="dfsj" value="{{sch.dfsj}}" required>
113 113 </div>
114 114 </div>
115 115 </div>
... ... @@ -117,7 +117,7 @@
117 117 <div class="uk-form-row">
118 118 <label class="uk-form-label" >实发</label>
119 119 <div class="uk-form-controls">
120   - <input type="time" name="fcsjActual" value="{{fcsjActual}}" >
  120 + <input type="time" name="fcsjActual" value="{{sch.fcsjActual}}" >
121 121 </div>
122 122 </div>
123 123 </div>
... ... @@ -128,7 +128,7 @@
128 128 <div class="uk-form-row">
129 129 <label class="uk-form-label" >里程</label>
130 130 <div class="uk-form-controls">
131   - <input type="text" name="jhlc" value="{{jhlc}}" max=222 data-fv-lessthan-inclusive="false"
  131 + <input type="text" name="jhlc" value="{{sch.jhlc}}" max=222 data-fv-lessthan-inclusive="false"
132 132 required>
133 133 </div>
134 134 </div>
... ... @@ -137,7 +137,7 @@
137 137 <div class="uk-form-row">
138 138 <label class="uk-form-label" >计达</label>
139 139 <div class="uk-form-controls">
140   - <input type="time" value="{{zdsj}}" disabled>
  140 + <input type="time" value="{{sch.zdsj}}" disabled>
141 141 </div>
142 142 </div>
143 143 </div>
... ... @@ -145,7 +145,7 @@
145 145 <div class="uk-form-row">
146 146 <label class="uk-form-label" >实达</label>
147 147 <div class="uk-form-controls">
148   - <input type="time" name="zdsjActual" value="{{zdsjActual}}" >
  148 + <input type="time" name="zdsjActual" value="{{sch.zdsjActual}}" >
149 149 </div>
150 150 </div>
151 151 </div>
... ... @@ -155,17 +155,28 @@
155 155 <div class="uk-form-row">
156 156 <label class="uk-form-label" ></label>
157 157 <label>
158   - &nbsp;<input class="i-cbox destroy-box" type="checkbox" name="status" value="-1" {{if status==-1}}checked{{/if}}>
  158 + &nbsp;<input class="i-cbox destroy-box" type="checkbox" name="status" value="-1" {{if sch.status==-1}}checked{{/if}}>
159 159 是否烂班
160 160 </label>
161 161 </div>
  162 +
  163 + <div class="uk-form-row adjust_exps_select_wrap {{if sch.status!=-1}}display_hide{{/if}}" >
  164 + <label class="uk-form-label" >烂班原因</label>
  165 + <div class="uk-form-controls">
  166 + <select name="adjustExps">
  167 + {{each adjustExps as exp i}}
  168 + <option value="{{exp}}" {{if sch.adjustExps==exp}}selected{{/if}}>{{exp}}</option>
  169 + {{/each}}
  170 + </select>
  171 + </div>
  172 + </div>
162 173 </div>
163 174  
164 175 <div class="uk-width-2-3">
165 176 <div class="uk-form-row ct-stacked">
166 177 <label class="uk-form-label" >备注</label>
167 178 <div class="uk-form-controls" style="margin-top: 5px;">
168   - <textarea id="form-s-t" cols="20" rows="3" name="remarks" data-fv-stringlength="true" data-fv-stringlength-max="100" placeholder="备注">{{remarks}}</textarea>
  179 + <textarea id="form-s-t" cols="20" rows="3" name="remarks" data-fv-stringlength="true" data-fv-stringlength-max="100" placeholder="备注">{{sch.remarks}}</textarea>
169 180 </div>
170 181 </div>
171 182 </div>
... ... @@ -214,7 +225,7 @@
214 225 var modal = '#history-sch-edit-modal'
215 226 ,gb_sch,parentModal;
216 227 var stationRoutes, parks, information;
217   -
  228 + var adjustExps = ['配车', '保养', '故障', '肇事', '路阻', '纠纷', '缺人', '客稀', '缺车', '气候', '援外', '吊慢', '抽减', '其他'];
218 229 $(modal).on('init', function(e, data) {
219 230 e.stopPropagation();
220 231 var id = data.id;
... ... @@ -223,7 +234,7 @@
223 234 $.get('/realSchedule/'+id, function (sch) {
224 235 gb_sch = sch;
225 236  
226   - var htmlStr = template('history-sch-edit-form-temp', sch);
  237 + var htmlStr = template('history-sch-edit-form-temp', {sch: sch, adjustExps: adjustExps});
227 238 $('form.sch_form', modal).html(htmlStr);
228 239 //子任务列表
229 240 sch.cTasks.sort(sub_task_sort);
... ... @@ -239,10 +250,14 @@
239 250 var f = $('form.sch_form', modal).formValidation(gb_form_validation_opts);
240 251 //是否烂班
241 252 $('[name=status]', f).on('click', function () {
242   - if(this.checked)
  253 + if(this.checked){
243 254 $('[name=jhlc]', f).val(0);
244   - else
  255 + $('.adjust_exps_select_wrap', f).show();
  256 + }
  257 + else{
245 258 $('[name=jhlc]', f).val(gb_sch.jhlcOrig);
  259 + $('.adjust_exps_select_wrap', f).hide();
  260 + }
246 261 });
247 262 f.on('success.form.fv', function(e) {
248 263 e.preventDefault();
... ...
src/main/resources/static/real_control_v2/fragments/north/nav/history_sch_maintain.html
... ... @@ -126,6 +126,21 @@
126 126 $.each(rs, function (i) {
127 127 tsStr += '<li ' + (i == 0 ? 'class="uk-active"' : '') + '><a>' + this + '</a></li>';
128 128 });
  129 + //临时放开闵行39路的日期权限
  130 + /*if(gb_data_basic.line_idx=='100001'){
  131 + var st = moment('2017-08-29', 'YYYY-MM-DD');
  132 + var et = moment().format('YYYY-MM-DD');
  133 + tsStr = '';
  134 + while(true){
  135 + var rq = st.format('YYYY-MM-DD');
  136 + tsStr += '<li ' + (rq == et ? 'class="uk-active"' : '') + '><a>' + rq + '</a></li>';
  137 + st.add(1, 'days');
  138 +
  139 + if(rq == et)
  140 + break;
  141 + }
  142 + }*/
  143 +
129 144 $('.h-s-time', modal).html(tsStr);
130 145  
131 146 //线路tab
... ...
src/main/resources/static/real_control_v2/fragments/north/nav/user_change/user_change_modal.html 0 → 100644
  1 +<div class="uk-modal ct-form-modal" id="change_user_options-modal">
  2 + <div class="uk-modal-dialog">
  3 + <a href="" class="uk-modal-close uk-close"></a>
  4 + <h2>切换账号/模式</h2>
  5 +
  6 + <div class="user_info">
  7 + <form class="uk-form uk-form-horizontal">
  8 +
  9 + <div class="uk-form-row">
  10 + <label class="uk-form-label" for="form-h-it">用户名</label>
  11 + <div class="uk-form-controls">
  12 + <input name="userName" type="text" id="form-h-it" value="" autocomplete="off">
  13 + </div>
  14 + </div>
  15 + <div class="uk-form-row">
  16 + <label class="uk-form-label" for="form-h-ip">密码</label>
  17 + <div class="uk-form-controls">
  18 + <input name="password" type="password" id="form-h-ip" value="******" disabled
  19 + autocomplete="off">
  20 + </div>
  21 + </div>
  22 + <div class="uk-form-row">
  23 + <label class="uk-form-label" for="form-h-s">调度模式</label>
  24 + <div class="uk-form-controls">
  25 + <select id="form-h-s" name="operationMode">
  26 + <option value="1">主调模式</option>
  27 + <option value="0">监控模式</option>
  28 + </select>
  29 + </div>
  30 + </div>
  31 + <br>
  32 + <div class="uk-form-row">
  33 + <button disabled class="uk-button uk-button-danger uk-button-large uk-width-1-1 confirm_btn"
  34 + type="button">
  35 + 确认切换
  36 + </button>
  37 + </div>
  38 + </form>
  39 + </div>
  40 + </div>
  41 +
  42 + <script>
  43 + (function () {
  44 + var modal = '#change_user_options-modal',
  45 + user = gb_northToolbar.user(),
  46 + operationMode = window.localStorage.getItem('operationMode'),
  47 + f = $('.user_info>form', modal);
  48 + //用户名
  49 + $('input[name=userName]', f).val(user.userName)
  50 + .on('input', function () {
  51 + //清除密码
  52 + $('input[name=password]', f).val('').removeAttr('disabled');
  53 + changeBtnStatus();
  54 + });
  55 +
  56 + //密码
  57 + $('input[name=password]', f).on('input', changeBtnStatus);
  58 +
  59 + //切换模式
  60 + $('select[name=operationMode]', f).val(operationMode).on('change', changeBtnStatus);
  61 +
  62 + var confirmBtn = $('.confirm_btn', f);
  63 +
  64 + function changeBtnStatus() {
  65 + var data = f.serializeJSON();
  66 + if ((data.userName != user.userName && $.trim(data.password))
  67 + || data.operationMode != operationMode)
  68 + confirmBtn.removeAttr('disabled');
  69 + else {
  70 + confirmBtn.attr('disabled', 'disabled');
  71 + if (data.userName == user.userName)
  72 + $('input[name=password]', f).val('******').attr('disabled', 'disabled');
  73 + }
  74 + }
  75 +
  76 + //确认切换
  77 + $('.confirm_btn', f).on('click', function () {
  78 + $(this).attr('disabled', 'disabled');
  79 +
  80 + var data = f.serializeJSON();
  81 + if (data.userName != user.userName) {
  82 + //切换账号
  83 + if (!$.trim(data.password))
  84 + return notify_err('密码不能为空!');
  85 +
  86 + gb_common.$post('/user/change_user', data, function (rs) {
  87 + notify_succ('切换账号成功!');
  88 + gb_northToolbar.init();
  89 + gb_delay_write_log();//当班调度日志
  90 + });
  91 + }
  92 +
  93 + if(data.operationMode != operationMode){
  94 + window.localStorage.setItem('operationMode', data.operationMode);
  95 + //切换调度模式
  96 + gb_dp_initHttpIntercept();
  97 + }
  98 +
  99 + UIkit.modal(modal).hide();
  100 + });
  101 + })();
  102 + </script>
  103 +</div>
... ...
src/main/resources/static/real_control_v2/fragments/north/toolbar.html
... ... @@ -2,7 +2,7 @@
2 2 <script id="north-toolbar-temp" type="text/html">
3 3 <div class="uk-margin" id="north_toolbar_panel">
4 4 <nav class="uk-navbar">
5   - <a class="uk-navbar-brand" id="navbar_user_detail_link">
  5 + <a class="uk-navbar-brand" id="navbar_user_detail_link" title="点击切换账号">
6 6 <span><i class="uk-icon-user"></i> <span id="north_toolbar_user">{{user.userName}}</span></span><i class="uk-icon-ellipsis-v"></i>
7 7 </a>
8 8 <ul class="uk-navbar-nav">
... ...
src/main/resources/static/real_control_v2/js/data/data_gps.js
... ... @@ -22,6 +22,8 @@ var gb_data_gps = (function () {
22 22 success: function (rs) {
23 23 //用定时的gps来检测session断开
24 24 if(rs.status && rs.status==407){
  25 + //解除退出页面的提示框
  26 + window.removeEventListener("beforeunload", gb_beforeunload_fun);
25 27 location.href = '/login.html';
26 28 return;
27 29 }
... ...
src/main/resources/static/real_control_v2/js/main.js
... ... @@ -59,7 +59,6 @@ var gb_main_ep = new EventProxy(),
59 59 }
60 60 });
61 61  
62   -
63 62 $(document).on('click', '.ct-bottom-drawer-close', function () {
64 63 $(this).parents('.ct-bottom-drawer').removeClass('open');
65 64 });
... ... @@ -169,8 +168,8 @@ var disabled_submit_btn = function (form) {
169 168 function showUpdateDescription() {
170 169 //更新说明
171 170 var updateDescription = {
172   - date: '2017-08-25',
173   - text: '<h5>1、修复了一个bug,这个bug导致个别班次不显示实到时间!</h5>'
  171 + date: '2017-09-24',
  172 + text: '<h5>1、尝试解决 “祝桥2路” 和 “机场七线” 进站问题!</h5>'
174 173 };
175 174  
176 175 var storage = window.localStorage
... ...
src/main/resources/static/real_control_v2/js/north/toolbar.js
... ... @@ -5,97 +5,59 @@ var gb_northToolbar = (function () {
5 5 var modal_opts = {center: true, bgclose: false};
6 6 var currentUser;
7 7  
8   - $.get('/real_control_v2/fragments/north/toolbar.html', function (temp) {
9   - ep.emit("template", temp);
10   - });
  8 + var init = function () {
  9 + $.get('/real_control_v2/fragments/north/toolbar.html', function (temp) {
  10 + ep.emit("template", temp);
  11 + });
11 12  
12   - $.get('/real_control_v2/js/data/json/north_toolbar.json', function (data) {
13   - ep.emit("data", data);
14   - });
  13 + $.get('/real_control_v2/js/data/json/north_toolbar.json', function (data) {
  14 + ep.emit("data", data);
  15 + });
15 16  
16   - //当前用户信息
17   - $.get('/user/currentUser', function (user) {
18   - ep.emit("user", user);
  17 + //当前用户信息
  18 + $.get('/user/currentUser', function (user) {
  19 + ep.emit("user", user);
19 20  
20   - //查询线调权限信息
21   - $.get('/realControAuthority/findByUserId', {userId: user.id}, function (rs) {
22   - ep.emit("xd_auth", rs);
  21 + //查询线调权限信息
  22 + $.get('/realControAuthority/findByUserId', {userId: user.id}, function (rs) {
  23 + ep.emit("xd_auth", rs);
  24 + });
23 25 });
24   - });
25 26  
26   - var xd_auth;//线调权限
27   - var ep = EventProxy.create("template", "data", "user", 'xd_auth', function (temp, data, user, auth) {
28   - var tempId = '#north-toolbar-temp';
29   - xd_auth = auth;
30   - //electron环境
31   - if(isElectron){
32   - tempId = '#north-toolbar-electron-temp';
33   - //最小化
34   - $(document).on('click', '#mnavbarIconBtnMIN', function () {
35   - ipcMain.send('webPageMainWindowMinimize');
36   - });
37   - //关闭
38   - $(document).on('click', '#mnavbarIconBtnCLOSE', function () {
39   - ipcMain.send('webPageMainWindowClose');
  27 + var xd_auth;//线调权限
  28 + var ep = EventProxy.create("template", "data", "user", 'xd_auth', function (temp, data, user, auth) {
  29 + var tempId = '#north-toolbar-temp';
  30 + xd_auth = auth;
  31 + currentUser = user;
  32 + var t = $(tempId, temp).html()
  33 + , htmlStr = template.render(t)({list: data, user: currentUser});
  34 + $('.north .north-toolbar').html(htmlStr);
  35 +
  36 + //exit
  37 + $('.north .north-toolbar .exit-system').on('click', function () {
  38 + //关闭websocket 连接
  39 + gb_sch_websocket.sock().close(1000, '退出线调');
  40 + window.location.href = '/pages/control/lineallot_v2/iframe_wrap.html';
40 41 });
41   - }
42   - currentUser = user;
43   - var t = $(tempId, temp).html()
44   - , htmlStr = template.render(t)({list: data, user: currentUser});
45   - $('.north .north-toolbar').html(htmlStr);
46 42  
47   - //exit
48   - $('.north .north-toolbar .exit-system').on('click', function () {
49   - //关闭websocket 连接
50   - gb_sch_websocket.sock().close(1000, '退出线调');
51   - window.location.href = '/pages/control/lineallot_v2/iframe_wrap.html';
  43 + //过滤菜单
  44 + var excludes=[];
  45 + if(xd_auth.excludeMenus)
  46 + excludes=xd_auth.excludeMenus.split(',');
  47 + if(excludes.length>0){
  48 + $('li.event', '#north_toolbar_panel').each(function () {
  49 + if(excludes.indexOf($('a', this).data('event'))!=-1)
  50 + $(this).remove();
  51 + });
  52 + }
52 53 });
  54 + };
53 55  
54   - //console.log('xd_auth', xd_auth, 'data', data);
55   - //过滤菜单
56   - var excludes=[];
57   - if(xd_auth.excludeMenus)
58   - excludes=xd_auth.excludeMenus.split(',');
59   - if(excludes.length>0){
60   - $('li.event', '#north_toolbar_panel').each(function () {
61   - if(excludes.indexOf($('a', this).data('event'))!=-1)
62   - $(this).remove();
63   - });
64   - }
65   -
66   - //鼠标悬停用户名
67   -/* $(document).on('mouseenter', '#navbar_user_detail_link', function() {
68   - $(this).qtip({
69   - show: {
70   - ready: true,
71   - delay: 300
72   - },
73   - content: {
74   - text: function() {
  56 + init();
75 57  
76   - return '';//temps['sch-table-task-tootip-temp']({tasks: array});
77   - }
78   - },
79   - position: {
80   - viewport: $(window),
81   - my: 'top center',
82   - at: 'bottom center'
83   - },
84   - style: {
85   - classes: 'qtip-light qtip-shadow user_detail_tip'
86   - },
87   - hide: {
88   - fixed: true,
89   - delay: 300
90   - },
91   - events: {
92   - hidden: function(event, api) {
93   - //destroy dom
94   - $(this).qtip('destroy', true);
95   - }
96   - }
97   - });
98   - });*/
  58 + //点击用户名
  59 + $(document).on('click', '#navbar_user_detail_link', function () {
  60 + open_modal('/real_control_v2/fragments/north/nav/user_change/user_change_modal.html', {}, {center: false, bgclose: false});
99 61 });
100 62  
101 63 $(document).on('click', '#north_toolbar_panel li.event a', function () {
... ... @@ -103,6 +65,19 @@ var gb_northToolbar = (function () {
103 65 handler[event] && handler[event]();
104 66 });
105 67  
  68 + //electron环境
  69 + if(isElectron){
  70 + tempId = '#north-toolbar-electron-temp';
  71 + //最小化
  72 + $(document).on('click', '#mnavbarIconBtnMIN', function () {
  73 + ipcMain.send('webPageMainWindowMinimize');
  74 + });
  75 + //关闭
  76 + $(document).on('click', '#mnavbarIconBtnCLOSE', function () {
  77 + ipcMain.send('webPageMainWindowClose');
  78 + });
  79 + }
  80 +
106 81 var handler = {
107 82 // device report list
108 83 device_report: function () {
... ... @@ -254,6 +229,7 @@ var gb_northToolbar = (function () {
254 229 return {
255 230 user: function () {
256 231 return currentUser;
257   - }
  232 + },
  233 + init: init
258 234 }
259 235 })();
... ...
src/main/resources/static/real_control_v2/js/utils/dispatch_pattern.js
1 1 /** 调度模式 */
2 2  
3   -//主调和监控模式
4   -var operationMode = window.localStorage.getItem('operationMode');
5   -if (operationMode == 0) {
6   - $('body>.north').addClass('monitor');
7   - $(document).on('ajaxSend', interceptPOST);
8   -}
9   -else
10   - $('body>.north').addClass('main');
  3 +var gb_dp_initHttpIntercept = function () {
  4 + //主调和监控模式
  5 + var operationMode = window.localStorage.getItem('operationMode');
  6 + $(document).off('ajaxSend', interceptPOST);
  7 + $('body>.north').removeClass('monitor main');
  8 + if (operationMode == 0) {
  9 + $('body>.north').addClass('monitor');
  10 + $(document).on('ajaxSend', interceptPOST);
  11 + }
  12 + else
  13 + $('body>.north').addClass('main');
  14 +
  15 +};
  16 +//10分钟后提交当班调度数据
  17 +var gb_delay_write_log = function () {
  18 + setTimeout(function () {
  19 + var user = gb_northToolbar.user();
  20 + var data = {
  21 + uId: user.id,
  22 + uName: user.userName,
  23 + codeIdx: gb_data_basic.line_idx + ',',
  24 + main: operationMode
  25 + };
  26 +
  27 + gb_common.$post('/dutyEmployee', data);
  28 + }, 1000 * 60 * 10);
  29 +};
  30 +
  31 +gb_dp_initHttpIntercept();
  32 +gb_delay_write_log();
11 33  
12 34 //拦截POST请求
13 35 function interceptPOST(e, xhr, t) {
... ... @@ -19,21 +41,7 @@ function interceptPOST(e, xhr, t) {
19 41  
20 42 //全局 ajaxError 事件
21 43 $(document).ajaxError(function (event, jqxhr) {
22   - if(jqxhr.status == 403){
  44 + if (jqxhr.status == 403) {
23 45 UIkit.modal.alert('<span style="color: red;">访问被拒绝,你没有这个权限!</span>', {labels: {Ok: '确定'}});
24 46 }
25 47 });
26   -
27   -
28   -//10分钟后提交当班调度数据
29   -setTimeout(function () {
30   - var user = gb_northToolbar.user();
31   - var data = {
32   - uId: user.id,
33   - uName: user.userName,
34   - codeIdx: gb_data_basic.line_idx + ',',
35   - main: operationMode
36   - };
37   -
38   - gb_common.$post('/dutyEmployee', data);
39   -}, 1000 * 60 * 10);
40 48 \ No newline at end of file
... ...
src/main/resources/static/real_control_v2/main.html
... ... @@ -74,6 +74,13 @@
74 74 </div>
75 75  
76 76 <script>
  77 +/* var gb_beforeunload_fun = function (e) {
  78 + var confirmationMessage = "\o/";
  79 + (e || window.event).returnValue = confirmationMessage;
  80 + return confirmationMessage;
  81 + }
  82 + window.addEventListener("beforeunload", gb_beforeunload_fun);*/
  83 +
77 84 delete window.exports;
78 85 delete window.module;
79 86  
... ...
src/main/resources/static/real_control_v2/mapmonitor/fragments/playback_v3/left.html
... ... @@ -138,6 +138,11 @@
138 138 gb_ct_table.fixedHead($('.inout_table_wrap', leftWrap));
139 139 //滚动条
140 140 createScrollbar();
  141 +
  142 + //show title
  143 + UIkit.notify("设备端自身标识为无效的GPS点位,将不会再进入回放通路", {
  144 + status: 'info'
  145 + });
141 146 });
142 147  
143 148 /**
... ...