Commit 8ae7718d8a4b84b1916f5829b046210331e9076e
1 parent
a9728e40
1.
Showing
26 changed files
with
1714 additions
and
132 deletions
src/main/java/com/bsth/common/SystemParamKeys.java
| ... | ... | @@ -7,6 +7,8 @@ public class SystemParamKeys { |
| 7 | 7 | |
| 8 | 8 | public static final String SPECIAL_ROLES = "special.roles"; |
| 9 | 9 | |
| 10 | + public static final String SPECIAL_DAYS = "special.days"; | |
| 11 | + | |
| 10 | 12 | public static final String URL_HTTP_GPS_REAL_CACHE = "url.http.gps.real.cache"; |
| 11 | 13 | |
| 12 | 14 | public static final String URL_HTTP_GPS_REAL = "url.http.gps.real"; |
| ... | ... | @@ -40,4 +42,30 @@ public class SystemParamKeys { |
| 40 | 42 | public static final String URL_HTTP_SSO_LOGOUT = "url.http.sso.logout"; |
| 41 | 43 | |
| 42 | 44 | public static final String URL_HTTP_SSO_AUTH = "url.http.sso.auth"; |
| 43 | -} | |
| 45 | + | |
| 46 | + public static final String URL_HTTP_MAINTENANCE = "url.http.maintenance"; | |
| 47 | + | |
| 48 | + public static final String ENABLED_WHITE_IP = "enabled.white.ip"; | |
| 49 | + | |
| 50 | + public static final String ENABLED_FILTER_AUTHORITY = "enabled.filter.authority"; | |
| 51 | + | |
| 52 | + public static final String URL_HTTP_DVR = "url.http.dvr"; | |
| 53 | + | |
| 54 | + public static final String URL_HTTP_DVR_PWD = "url.http.dvr.pwd"; | |
| 55 | + | |
| 56 | + public static final String DR_SYS_CITY_INTERFACE_URL = "dr.sys.city.interface.url"; | |
| 57 | + | |
| 58 | + public static final String DR_SYS_CITY_INTERFACE_URL1 = "dr.sys.city.interface.url1"; | |
| 59 | + | |
| 60 | + public static final String DR_SYS_CITY_INTERFACE_USER = "dr.sys.city.interface.user"; | |
| 61 | + | |
| 62 | + public static final String DR_SYS_CITY_INTERFACE_PASSWORD = "dr.sys.city.interface.password"; | |
| 63 | + | |
| 64 | + public static final String DR_SYS_CITY_INTERFACE_BAK_URL = "dr.sys.city.interface.bak.url"; | |
| 65 | + | |
| 66 | + public static final String DR_SYS_CITY_INTERFACE_BAK_URL1 = "dr.sys.city.interface.bak.url1"; | |
| 67 | + | |
| 68 | + public static final String DR_SYS_CITY_INTERFACE_BAK_USER = "dr.sys.city.interface.bak.user"; | |
| 69 | + | |
| 70 | + public static final String DR_SYS_CITY_INTERFACE_BAK_PASSWORD = "dr.sys.city.interface.bak.password"; | |
| 71 | +} | |
| 44 | 72 | \ No newline at end of file | ... | ... |
src/main/java/com/bsth/controller/gps/GpsController.java
| ... | ... | @@ -233,5 +233,9 @@ public class GpsController { |
| 233 | 233 | public Map<String, Object> allCarsByLine(String lineCode){ |
| 234 | 234 | return gpsService.allCarsByLine(lineCode); |
| 235 | 235 | } |
| 236 | - | |
| 236 | + | |
| 237 | + @RequestMapping(value = "/all/fuzzy") | |
| 238 | + public Map<String, Object> fuzzy(@RequestParam Map<String, Object> map) { | |
| 239 | + return gpsService.fuzzy(map); | |
| 240 | + } | |
| 237 | 241 | } | ... | ... |
src/main/java/com/bsth/controller/realcontrol/AdminUtilsController.java
| ... | ... | @@ -33,6 +33,7 @@ import com.fasterxml.jackson.databind.SerializationFeature; |
| 33 | 33 | import org.slf4j.Logger; |
| 34 | 34 | import org.slf4j.LoggerFactory; |
| 35 | 35 | import org.springframework.beans.factory.annotation.Autowired; |
| 36 | +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; | |
| 36 | 37 | import org.springframework.web.bind.annotation.RequestMapping; |
| 37 | 38 | import org.springframework.web.bind.annotation.RequestParam; |
| 38 | 39 | import org.springframework.web.bind.annotation.RestController; |
| ... | ... | @@ -403,4 +404,18 @@ public class AdminUtilsController { |
| 403 | 404 | |
| 404 | 405 | return "error"; |
| 405 | 406 | } |
| 407 | + | |
| 408 | + public static void main(String[] args) { | |
| 409 | + String line = "730088,#131597Aa"; | |
| 410 | + String[] arr = line.split(","); | |
| 411 | + if (arr.length == 2) { | |
| 412 | + String uname = arr[0], password = arr[1]; | |
| 413 | + StringBuilder sb = new StringBuilder("update bsth_c_sys_user set password='"); | |
| 414 | + sb.append(new BCryptPasswordEncoder(4).encode(password)); | |
| 415 | + sb.append("' where user_name='"); | |
| 416 | + sb.append(uname); | |
| 417 | + sb.append("';"); | |
| 418 | + System.out.println(sb.toString()); | |
| 419 | + } | |
| 420 | + } | |
| 406 | 421 | } |
| 407 | 422 | \ No newline at end of file | ... | ... |
src/main/java/com/bsth/controller/realcontrol/PageForwardingController.java
| 1 | -package com.bsth.controller.realcontrol; | |
| 2 | - | |
| 3 | -import com.bsth.data.zndd.voice.UploadVideoServlet; | |
| 4 | -import com.bsth.entity.sys.Role; | |
| 5 | -import com.bsth.entity.sys.SysUser; | |
| 6 | -import com.bsth.security.util.SecurityUtils; | |
| 7 | -import org.slf4j.Logger; | |
| 8 | -import org.slf4j.LoggerFactory; | |
| 9 | -import org.springframework.beans.factory.annotation.Autowired; | |
| 10 | -import org.springframework.stereotype.Controller; | |
| 11 | -import org.springframework.web.bind.annotation.PathVariable; | |
| 12 | -import org.springframework.web.bind.annotation.RequestMapping; | |
| 13 | -import org.springframework.web.bind.annotation.RequestParam; | |
| 14 | -import org.springframework.web.servlet.ModelAndView; | |
| 15 | - | |
| 16 | -import javax.servlet.ServletException; | |
| 17 | -import javax.servlet.http.HttpServletRequest; | |
| 18 | -import javax.servlet.http.HttpServletResponse; | |
| 19 | -import java.io.IOException; | |
| 20 | - | |
| 21 | -/** | |
| 22 | - * 线调登入页面转发 | |
| 23 | - * Created by panzhao on 2017/1/21. | |
| 24 | - */ | |
| 25 | -@Controller | |
| 26 | -@RequestMapping("real_control") | |
| 27 | -public class PageForwardingController { | |
| 28 | - | |
| 29 | - Logger logger = LoggerFactory.getLogger(this.getClass()); | |
| 30 | - | |
| 31 | - @Autowired | |
| 32 | - UploadVideoServlet UploadVideoServlet; | |
| 33 | - @RequestMapping("/v2") | |
| 34 | - public ModelAndView v2(HttpServletResponse response){ | |
| 35 | - ModelAndView mv = new ModelAndView(); | |
| 36 | - SysUser user = SecurityUtils.getCurrentUser(); | |
| 37 | - | |
| 38 | - //班次管理员 | |
| 39 | - if(user.getUserName().equals("bcgly")){ | |
| 40 | - mv.setViewName("/real_control_v2/sch_manage/sch_imitate.html"); | |
| 41 | - return mv; | |
| 42 | - } | |
| 43 | - | |
| 44 | - try{ | |
| 45 | - //闵行运管所,直接打开地图页面 | |
| 46 | - if(user.getRoles().size() == 1){ | |
| 47 | - for(Role role : user.getRoles()){ | |
| 48 | - if(role.getCodeName().equals("MH_YGS")){ | |
| 49 | - // 直接重定向 | |
| 50 | - response.sendRedirect("/pages/mapmonitor/alone/wrap.html"); | |
| 51 | - return null; | |
| 52 | - } | |
| 53 | - } | |
| 54 | - } | |
| 55 | - }catch (Exception e){ | |
| 56 | - logger.error("", e); | |
| 57 | - } | |
| 58 | - | |
| 59 | - //正常线调主页 | |
| 60 | - mv.setViewName("/real_control_v2/main.html"); | |
| 61 | - return mv; | |
| 62 | - } | |
| 63 | - | |
| 64 | - @RequestMapping(value = "zndd/do/{line}") | |
| 65 | - public void doPost(@PathVariable("line") String line, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { | |
| 66 | - UploadVideoServlet.doPost(line,request,response); | |
| 67 | - } | |
| 68 | -} | |
| 1 | +package com.bsth.controller.realcontrol; | |
| 2 | + | |
| 3 | +import com.bsth.data.zndd.voice.UploadVideoServlet; | |
| 4 | +import com.bsth.entity.sys.Role; | |
| 5 | +import com.bsth.entity.sys.SysUser; | |
| 6 | +import com.bsth.security.util.SecurityUtils; | |
| 7 | +import org.slf4j.Logger; | |
| 8 | +import org.slf4j.LoggerFactory; | |
| 9 | +import org.springframework.beans.factory.annotation.Autowired; | |
| 10 | +import org.springframework.stereotype.Controller; | |
| 11 | +import org.springframework.web.bind.annotation.PathVariable; | |
| 12 | +import org.springframework.web.bind.annotation.RequestMapping; | |
| 13 | +import org.springframework.web.bind.annotation.RequestParam; | |
| 14 | +import org.springframework.web.servlet.ModelAndView; | |
| 15 | + | |
| 16 | +import javax.servlet.ServletException; | |
| 17 | +import javax.servlet.http.HttpServletRequest; | |
| 18 | +import javax.servlet.http.HttpServletResponse; | |
| 19 | +import java.io.IOException; | |
| 20 | + | |
| 21 | +/** | |
| 22 | + * 线调登入页面转发 | |
| 23 | + * Created by panzhao on 2017/1/21. | |
| 24 | + */ | |
| 25 | +@Controller | |
| 26 | +@RequestMapping("real_control") | |
| 27 | +public class PageForwardingController { | |
| 28 | + | |
| 29 | + Logger logger = LoggerFactory.getLogger(this.getClass()); | |
| 30 | + | |
| 31 | + @Autowired | |
| 32 | + UploadVideoServlet UploadVideoServlet; | |
| 33 | + @RequestMapping("/v2") | |
| 34 | + public ModelAndView v2(HttpServletResponse response){ | |
| 35 | + ModelAndView mv = new ModelAndView(); | |
| 36 | + SysUser user = SecurityUtils.getCurrentUser(); | |
| 37 | + | |
| 38 | + //班次管理员 | |
| 39 | + if(user.getUserName().equals("bcgly")){ | |
| 40 | + mv.setViewName("/real_control_v2/sch_manage/sch_imitate.html"); | |
| 41 | + return mv; | |
| 42 | + } | |
| 43 | + | |
| 44 | + try{ | |
| 45 | + //闵行运管所,直接打开地图页面 | |
| 46 | + if(user.getRoles().size() == 1){ | |
| 47 | + for(Role role : user.getRoles()){ | |
| 48 | + if(role.getCodeName().equals("MH_YGS")){ | |
| 49 | + // 直接重定向 | |
| 50 | + response.sendRedirect("/pages/mapmonitor/alone/wrap.html"); | |
| 51 | + return null; | |
| 52 | + } | |
| 53 | + } | |
| 54 | + } | |
| 55 | + }catch (Exception e){ | |
| 56 | + logger.error("", e); | |
| 57 | + } | |
| 58 | + | |
| 59 | + //正常线调主页 | |
| 60 | + mv.setViewName("/real_control_v2/main.html"); | |
| 61 | + return mv; | |
| 62 | + } | |
| 63 | + | |
| 64 | + @RequestMapping("/demo") | |
| 65 | + public ModelAndView demo(HttpServletResponse response){ | |
| 66 | + ModelAndView mv = new ModelAndView(); | |
| 67 | + mv.setViewName("/pages/demo.html"); | |
| 68 | + return mv; | |
| 69 | + } | |
| 70 | + | |
| 71 | + @RequestMapping(value = "zndd/do/{line}") | |
| 72 | + public void doPost(@PathVariable("line") String line, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { | |
| 73 | + UploadVideoServlet.doPost(line,request,response); | |
| 74 | + } | |
| 75 | +} | ... | ... |
src/main/java/com/bsth/controller/realcontrol/ServiceDataInterface.java
| ... | ... | @@ -108,6 +108,7 @@ public class ServiceDataInterface { |
| 108 | 108 | map.put("remarks", sch.getRemark()); |
| 109 | 109 | map.put("status", sch.getStatus()); |
| 110 | 110 | map.put("realExecDate", sch.getRealExecDate()); |
| 111 | + map.put("lineRegion", sch.getLineRegion()); | |
| 111 | 112 | |
| 112 | 113 | //放站班次,放到的站点 |
| 113 | 114 | map.put("majorStationName", sch.getMajorStationName()); | ... | ... |
src/main/java/com/bsth/data/SystemParamCache.java
| ... | ... | @@ -21,6 +21,10 @@ public class SystemParamCache implements InitializingBean { |
| 21 | 21 | return systemParamService1.getValue(SystemParamKeys.SPECIAL_ROLES); |
| 22 | 22 | } |
| 23 | 23 | |
| 24 | + public static String getSpecialDays() { | |
| 25 | + return systemParamService1.getValue(SystemParamKeys.SPECIAL_DAYS); | |
| 26 | + } | |
| 27 | + | |
| 24 | 28 | public static String getUrlHttpGpsRealCache() { |
| 25 | 29 | return systemParamService1.getValue(SystemParamKeys.URL_HTTP_GPS_REAL_CACHE); |
| 26 | 30 | } |
| ... | ... | @@ -85,11 +89,62 @@ public class SystemParamCache implements InitializingBean { |
| 85 | 89 | return systemParamService1.getValue(SystemParamKeys.URL_HTTP_SSO_LOGOUT); |
| 86 | 90 | } |
| 87 | 91 | |
| 88 | - public static final String URL_HTTP_SSO_AUTH = "url.http.sso.auth"; | |
| 89 | 92 | public static String getUrlHttpSsoAuth() { |
| 90 | 93 | return systemParamService1.getValue(SystemParamKeys.URL_HTTP_SSO_AUTH); |
| 91 | 94 | } |
| 92 | 95 | |
| 96 | + public static String getUrlHttpMaintenance() { | |
| 97 | + return systemParamService1.getValue(SystemParamKeys.URL_HTTP_MAINTENANCE); | |
| 98 | + } | |
| 99 | + | |
| 100 | + public static boolean getEnabledWhiteIp() { | |
| 101 | + return Boolean.parseBoolean(systemParamService1.getValue(SystemParamKeys.ENABLED_WHITE_IP)); | |
| 102 | + } | |
| 103 | + | |
| 104 | + public static boolean getEnableFilterAuthority() { | |
| 105 | + return Boolean.parseBoolean(systemParamService1.getValue(SystemParamKeys.ENABLED_FILTER_AUTHORITY)); | |
| 106 | + } | |
| 107 | + | |
| 108 | + public static String getUrlHttpDvr() { | |
| 109 | + return systemParamService1.getValue(SystemParamKeys.URL_HTTP_DVR); | |
| 110 | + } | |
| 111 | + | |
| 112 | + public static String getUrlHttpDvrPwd() { | |
| 113 | + return systemParamService1.getValue(SystemParamKeys.URL_HTTP_DVR_PWD); | |
| 114 | + } | |
| 115 | + | |
| 116 | + public static String getDrSysCityInterfaceUrl() { | |
| 117 | + return systemParamService1.getValue(SystemParamKeys.DR_SYS_CITY_INTERFACE_URL); | |
| 118 | + } | |
| 119 | + | |
| 120 | + public static String getDrSysCityInterfaceUrl1() { | |
| 121 | + return systemParamService1.getValue(SystemParamKeys.DR_SYS_CITY_INTERFACE_URL1); | |
| 122 | + } | |
| 123 | + | |
| 124 | + public static String getDrSysCityInterfaceUser() { | |
| 125 | + return systemParamService1.getValue(SystemParamKeys.DR_SYS_CITY_INTERFACE_USER); | |
| 126 | + } | |
| 127 | + | |
| 128 | + public static String getDrSysCityInterfacePassword() { | |
| 129 | + return systemParamService1.getValue(SystemParamKeys.DR_SYS_CITY_INTERFACE_PASSWORD); | |
| 130 | + } | |
| 131 | + | |
| 132 | + public static String getDrSysCityInterfaceBakUrl() { | |
| 133 | + return systemParamService1.getValue(SystemParamKeys.DR_SYS_CITY_INTERFACE_BAK_URL); | |
| 134 | + } | |
| 135 | + | |
| 136 | + public static String getDrSysCityInterfaceBakUrl1() { | |
| 137 | + return systemParamService1.getValue(SystemParamKeys.DR_SYS_CITY_INTERFACE_BAK_URL1); | |
| 138 | + } | |
| 139 | + | |
| 140 | + public static String getDrSysCityInterfaceBakUser() { | |
| 141 | + return systemParamService1.getValue(SystemParamKeys.DR_SYS_CITY_INTERFACE_BAK_USER); | |
| 142 | + } | |
| 143 | + | |
| 144 | + public static String getDrSysCityInterfaceBakPassword() { | |
| 145 | + return systemParamService1.getValue(SystemParamKeys.DR_SYS_CITY_INTERFACE_BAK_PASSWORD); | |
| 146 | + } | |
| 147 | + | |
| 93 | 148 | @Override |
| 94 | 149 | public void afterPropertiesSet() throws Exception { |
| 95 | 150 | systemParamService1 = systemParamService; | ... | ... |
src/main/java/com/bsth/data/car_out_info/CarOutInfoHandler.java
| ... | ... | @@ -117,8 +117,8 @@ public class CarOutInfoHandler { |
| 117 | 117 | //删除 |
| 118 | 118 | jdbcTemplate.update("delete from bsth_t_clfcxxb"); |
| 119 | 119 | //重新写入 |
| 120 | - jdbcTemplate.batchUpdate("insert into bsth_t_clfcxxb(rq, line_code, line_name, lp_name, lp_sn, dfsj, nbbm, cph, bc_type, end_station_name, updown, jGh, jName, remarks, sn, sch)" + | |
| 121 | - " VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", new BatchPreparedStatementSetter() { | |
| 120 | + jdbcTemplate.batchUpdate("insert into bsth_t_clfcxxb(rq, line_code, line_name, lp_name, lp_sn, dfsj, nbbm, cph, bc_type, end_station_name, updown, jGh, jName, remarks, sn, sch, line_region)" + | |
| 121 | + " VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", new BatchPreparedStatementSetter() { | |
| 122 | 122 | @Override |
| 123 | 123 | public void setValues(PreparedStatement ps, int i) throws SQLException { |
| 124 | 124 | ScheduleRealInfo sch = pstList.get(i); |
| ... | ... | @@ -138,6 +138,7 @@ public class CarOutInfoHandler { |
| 138 | 138 | ps.setString(14, sch.getRemarks()); |
| 139 | 139 | ps.setInt(15, sch.getFcpSn()); |
| 140 | 140 | ps.setLong(16, sch.getId()); |
| 141 | + ps.setString(17, sch.getLineRegion()); | |
| 141 | 142 | } |
| 142 | 143 | |
| 143 | 144 | @Override | ... | ... |
src/main/java/com/bsth/entity/Detour.java
0 → 100644
| 1 | +package com.bsth.entity; | |
| 2 | + | |
| 3 | +import com.fasterxml.jackson.annotation.JsonIgnore; | |
| 4 | +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; | |
| 5 | +import org.hibernate.annotations.DynamicInsert; | |
| 6 | +import org.hibernate.annotations.DynamicUpdate; | |
| 7 | + | |
| 8 | +import javax.persistence.*; | |
| 9 | + | |
| 10 | +/** | |
| 11 | + * 绕改道实体类 | |
| 12 | + * 对应数据库表 bsth_c_detour | |
| 13 | + */ | |
| 14 | +@Entity | |
| 15 | +@Table(name = "bsth_c_detour") | |
| 16 | +@DynamicInsert | |
| 17 | +@DynamicUpdate | |
| 18 | +@JsonIgnoreProperties(ignoreUnknown = true) | |
| 19 | +public class Detour { | |
| 20 | + | |
| 21 | + // 主键 | |
| 22 | + @Id | |
| 23 | + @GeneratedValue(strategy = GenerationType.IDENTITY) | |
| 24 | + private Integer id; | |
| 25 | + | |
| 26 | + // 线路 | |
| 27 | + private Integer line; | |
| 28 | + | |
| 29 | + // 版本号 | |
| 30 | + @JsonIgnore | |
| 31 | + private Integer versions; | |
| 32 | + | |
| 33 | + // 上下行 | |
| 34 | + private Integer direction; | |
| 35 | + | |
| 36 | + // 起点编码 | |
| 37 | + @JsonIgnore | |
| 38 | + private String startStationCode; | |
| 39 | + | |
| 40 | + @Transient | |
| 41 | + private int startIdx; | |
| 42 | + | |
| 43 | + // 终点编码 | |
| 44 | + @JsonIgnore | |
| 45 | + private String terminalStationCode; | |
| 46 | + | |
| 47 | + @Transient | |
| 48 | + private int terminalIdx; | |
| 49 | + | |
| 50 | + // 路段wgs84点位 | |
| 51 | + private String points; | |
| 52 | + | |
| 53 | + public Integer getId() { | |
| 54 | + return id; | |
| 55 | + } | |
| 56 | + | |
| 57 | + public void setId(Integer id) { | |
| 58 | + this.id = id; | |
| 59 | + } | |
| 60 | + | |
| 61 | + public Integer getLine() { | |
| 62 | + return line; | |
| 63 | + } | |
| 64 | + | |
| 65 | + public void setLine(Integer line) { | |
| 66 | + this.line = line; | |
| 67 | + } | |
| 68 | + | |
| 69 | + public Integer getVersions() { | |
| 70 | + return versions; | |
| 71 | + } | |
| 72 | + | |
| 73 | + public void setVersions(Integer versions) { | |
| 74 | + this.versions = versions; | |
| 75 | + } | |
| 76 | + | |
| 77 | + public Integer getDirection() { | |
| 78 | + return direction; | |
| 79 | + } | |
| 80 | + | |
| 81 | + public void setDirection(Integer direction) { | |
| 82 | + this.direction = direction; | |
| 83 | + } | |
| 84 | + | |
| 85 | + public String getStartStationCode() { | |
| 86 | + return startStationCode; | |
| 87 | + } | |
| 88 | + | |
| 89 | + public void setStartStationCode(String startStationCode) { | |
| 90 | + this.startStationCode = startStationCode; | |
| 91 | + } | |
| 92 | + | |
| 93 | + public int getStartIdx() { | |
| 94 | + return startIdx; | |
| 95 | + } | |
| 96 | + | |
| 97 | + public void setStartIdx(int startIdx) { | |
| 98 | + this.startIdx = startIdx; | |
| 99 | + } | |
| 100 | + | |
| 101 | + public String getTerminalStationCode() { | |
| 102 | + return terminalStationCode; | |
| 103 | + } | |
| 104 | + | |
| 105 | + public void setTerminalStationCode(String terminalStationCode) { | |
| 106 | + this.terminalStationCode = terminalStationCode; | |
| 107 | + } | |
| 108 | + | |
| 109 | + public int getTerminalIdx() { | |
| 110 | + return terminalIdx; | |
| 111 | + } | |
| 112 | + | |
| 113 | + public void setTerminalIdx(int terminalIdx) { | |
| 114 | + this.terminalIdx = terminalIdx; | |
| 115 | + } | |
| 116 | + | |
| 117 | + public String getPoints() { | |
| 118 | + return points; | |
| 119 | + } | |
| 120 | + | |
| 121 | + public void setPoints(String points) { | |
| 122 | + this.points = points; | |
| 123 | + } | |
| 124 | +} | |
| 0 | 125 | \ No newline at end of file | ... | ... |
src/main/java/com/bsth/entity/LsStationRoute.java
| ... | ... | @@ -165,6 +165,11 @@ public class LsStationRoute { |
| 165 | 165 | @Transient |
| 166 | 166 | private String centerPointWgsWkt; |
| 167 | 167 | |
| 168 | + /** | |
| 169 | + * 绕改道当前站点对应的后一站点 | |
| 170 | + */ | |
| 171 | + private Integer detourStationRoute; | |
| 172 | + | |
| 168 | 173 | public Integer getId() { |
| 169 | 174 | return id; |
| 170 | 175 | } |
| ... | ... | @@ -440,4 +445,12 @@ public class LsStationRoute { |
| 440 | 445 | |
| 441 | 446 | return centerPointWgsWkt; |
| 442 | 447 | } |
| 448 | + | |
| 449 | + public Integer getDetourStationRoute() { | |
| 450 | + return detourStationRoute; | |
| 451 | + } | |
| 452 | + | |
| 453 | + public void setDetourStationRoute(Integer detourStationRoute) { | |
| 454 | + this.detourStationRoute = detourStationRoute; | |
| 455 | + } | |
| 443 | 456 | } |
| 444 | 457 | \ No newline at end of file | ... | ... |
src/main/java/com/bsth/entity/StationRoute.java
| ... | ... | @@ -198,6 +198,11 @@ public class StationRoute { |
| 198 | 198 | @Transient |
| 199 | 199 | private String centerPointWgsWkt; |
| 200 | 200 | |
| 201 | + /** | |
| 202 | + * 绕改道当前站点对应的后一站点 | |
| 203 | + */ | |
| 204 | + private Integer detourStationRoute; | |
| 205 | + | |
| 201 | 206 | public Integer getId() { |
| 202 | 207 | return id; |
| 203 | 208 | } |
| ... | ... | @@ -473,4 +478,12 @@ public class StationRoute { |
| 473 | 478 | |
| 474 | 479 | return centerPointWgsWkt; |
| 475 | 480 | } |
| 481 | + | |
| 482 | + public Integer getDetourStationRoute() { | |
| 483 | + return detourStationRoute; | |
| 484 | + } | |
| 485 | + | |
| 486 | + public void setDetourStationRoute(Integer detourStationRoute) { | |
| 487 | + this.detourStationRoute = detourStationRoute; | |
| 488 | + } | |
| 476 | 489 | } |
| 477 | 490 | \ No newline at end of file | ... | ... |
src/main/java/com/bsth/entity/transport_capability/TransportCapability.java
0 → 100644
| 1 | +package com.bsth.entity.transport_capability; | |
| 2 | + | |
| 3 | +/** | |
| 4 | + * 运能运力 | |
| 5 | + */ | |
| 6 | +public class TransportCapability { | |
| 7 | + | |
| 8 | + private String nbbm; | |
| 9 | + | |
| 10 | + private String lineCode; | |
| 11 | + | |
| 12 | + private String lineName; | |
| 13 | + | |
| 14 | + private int upDown; | |
| 15 | + | |
| 16 | + private String qdzArrDatejh; | |
| 17 | + | |
| 18 | + private long dfsjT; | |
| 19 | + | |
| 20 | + private String dfsj; | |
| 21 | + | |
| 22 | + private float lon; | |
| 23 | + | |
| 24 | + private float lat; | |
| 25 | + | |
| 26 | + public String getNbbm() { | |
| 27 | + return nbbm; | |
| 28 | + } | |
| 29 | + | |
| 30 | + public void setNbbm(String nbbm) { | |
| 31 | + this.nbbm = nbbm; | |
| 32 | + } | |
| 33 | + | |
| 34 | + public String getLineCode() { | |
| 35 | + return lineCode; | |
| 36 | + } | |
| 37 | + | |
| 38 | + public void setLineCode(String lineCode) { | |
| 39 | + this.lineCode = lineCode; | |
| 40 | + } | |
| 41 | + | |
| 42 | + public String getLineName() { | |
| 43 | + return lineName; | |
| 44 | + } | |
| 45 | + | |
| 46 | + public void setLineName(String lineName) { | |
| 47 | + this.lineName = lineName; | |
| 48 | + } | |
| 49 | + | |
| 50 | + public int getUpDown() { | |
| 51 | + return upDown; | |
| 52 | + } | |
| 53 | + | |
| 54 | + public void setUpDown(int upDown) { | |
| 55 | + this.upDown = upDown; | |
| 56 | + } | |
| 57 | + | |
| 58 | + public String getQdzArrDatejh() { | |
| 59 | + return qdzArrDatejh; | |
| 60 | + } | |
| 61 | + | |
| 62 | + public void setQdzArrDatejh(String qdzArrDatejh) { | |
| 63 | + this.qdzArrDatejh = qdzArrDatejh; | |
| 64 | + } | |
| 65 | + | |
| 66 | + public long getDfsjT() { | |
| 67 | + return dfsjT; | |
| 68 | + } | |
| 69 | + | |
| 70 | + public void setDfsjT(long dfsjT) { | |
| 71 | + this.dfsjT = dfsjT; | |
| 72 | + } | |
| 73 | + | |
| 74 | + public String getDfsj() { | |
| 75 | + return dfsj; | |
| 76 | + } | |
| 77 | + | |
| 78 | + public void setDfsj(String dfsj) { | |
| 79 | + this.dfsj = dfsj; | |
| 80 | + } | |
| 81 | + | |
| 82 | + public float getLon() { | |
| 83 | + return lon; | |
| 84 | + } | |
| 85 | + | |
| 86 | + public void setLon(float lon) { | |
| 87 | + this.lon = lon; | |
| 88 | + } | |
| 89 | + | |
| 90 | + public float getLat() { | |
| 91 | + return lat; | |
| 92 | + } | |
| 93 | + | |
| 94 | + public void setLat(float lat) { | |
| 95 | + this.lat = lat; | |
| 96 | + } | |
| 97 | +} | ... | ... |
src/main/java/com/bsth/repository/DetourRepository.java
0 → 100644
src/main/java/com/bsth/service/DetourService.java
0 → 100644
src/main/java/com/bsth/service/gps/GpsService.java
src/main/java/com/bsth/service/gps/GpsServiceImpl.java
| ... | ... | @@ -1576,6 +1576,16 @@ public class GpsServiceImpl implements GpsService { |
| 1576 | 1576 | return map; |
| 1577 | 1577 | } |
| 1578 | 1578 | |
| 1579 | + @Override | |
| 1580 | + public Map<String, Object> fuzzy(Map<String, Object> map) { | |
| 1581 | + List<String> nbbs = BasicData.getServiceNbbms(); | |
| 1582 | + | |
| 1583 | + | |
| 1584 | + dayOfSchedule.executeCurr("").getQdzArrDatejh(); | |
| 1585 | + dayOfSchedule.next(null); | |
| 1586 | + return Collections.emptyMap(); | |
| 1587 | + } | |
| 1588 | + | |
| 1579 | 1589 | static List<GpsSpeed> findAll(Map<String, Object> map) { |
| 1580 | 1590 | Connection conn = null; |
| 1581 | 1591 | PreparedStatement ps = null; | ... | ... |
src/main/java/com/bsth/service/impl/DetourServiceImpl.java
0 → 100644
| 1 | +package com.bsth.service.impl; | |
| 2 | + | |
| 3 | +import com.bsth.entity.Detour; | |
| 4 | +import com.bsth.repository.DetourRepository; | |
| 5 | +import com.bsth.service.DetourService; | |
| 6 | +import org.springframework.beans.factory.annotation.Autowired; | |
| 7 | +import org.springframework.stereotype.Service; | |
| 8 | + | |
| 9 | +/** | |
| 10 | + * 绕改道 Service 实现类 | |
| 11 | + */ | |
| 12 | +@Service | |
| 13 | +public class DetourServiceImpl extends BaseServiceImpl<Detour, Integer> implements DetourService { | |
| 14 | + | |
| 15 | + @Autowired | |
| 16 | + private DetourRepository detourRepository; | |
| 17 | + | |
| 18 | +} | |
| 0 | 19 | \ No newline at end of file | ... | ... |
src/main/java/com/bsth/service/impl/LsStationRouteServiceImpl.java
| 1 | 1 | package com.bsth.service.impl; |
| 2 | 2 | |
| 3 | 3 | import com.bsth.annotation.BusinessDescription; |
| 4 | +import com.bsth.data.gpsdata_v2.utils.GeoUtils; | |
| 4 | 5 | import com.bsth.entity.*; |
| 5 | 6 | import com.bsth.entity.search.CustomerSpecs; |
| 6 | 7 | import com.bsth.repository.*; |
| 7 | 8 | import com.bsth.service.LsStationRouteService; |
| 8 | -import com.bsth.util.CoordinateConverter; | |
| 9 | 9 | import com.bsth.util.CustomBeanUtils; |
| 10 | 10 | import com.bsth.util.GeoConverter; |
| 11 | -import com.fasterxml.jackson.core.JsonProcessingException; | |
| 12 | -import com.fasterxml.jackson.databind.ObjectMapper; | |
| 13 | 11 | import org.geolatte.geom.LineString; |
| 14 | -import org.geolatte.geom.Point; | |
| 15 | 12 | import org.geolatte.geom.Polygon; |
| 16 | 13 | import org.geolatte.geom.codec.Wkt; |
| 14 | +import org.slf4j.Logger; | |
| 15 | +import org.slf4j.LoggerFactory; | |
| 17 | 16 | import org.springframework.beans.factory.annotation.Autowired; |
| 18 | 17 | import org.springframework.data.domain.Sort; |
| 19 | 18 | import org.springframework.jdbc.core.BatchPreparedStatementSetter; |
| ... | ... | @@ -32,6 +31,8 @@ import java.util.*; |
| 32 | 31 | @Service |
| 33 | 32 | public class LsStationRouteServiceImpl extends BaseServiceImpl<LsStationRoute, Integer> implements LsStationRouteService { |
| 34 | 33 | |
| 34 | + private final static Logger log = LoggerFactory.getLogger(LsStationRouteServiceImpl.class); | |
| 35 | + | |
| 35 | 36 | @Autowired |
| 36 | 37 | private LsStationRouteRepository lsStationRouteRepository; |
| 37 | 38 | |
| ... | ... | @@ -59,6 +60,9 @@ public class LsStationRouteServiceImpl extends BaseServiceImpl<LsStationRoute, I |
| 59 | 60 | @Autowired |
| 60 | 61 | private JdbcTemplate jdbcTemplate; |
| 61 | 62 | |
| 63 | + @Autowired | |
| 64 | + private DetourRepository detourRepository; | |
| 65 | + | |
| 62 | 66 | @Override |
| 63 | 67 | public Iterable<LsStationRoute> findAllByParams(Map<String, Object> map) { |
| 64 | 68 | List<Sort.Order> orders = new ArrayList<>(); |
| ... | ... | @@ -318,9 +322,201 @@ public class LsStationRouteServiceImpl extends BaseServiceImpl<LsStationRoute, I |
| 318 | 322 | refreshCurrent(stationRoute1.getLine().getId(), currentVersion); |
| 319 | 323 | } |
| 320 | 324 | |
| 325 | + // 处理绕改道逻辑 | |
| 326 | + handleDetour(stationRoute1); | |
| 327 | + | |
| 321 | 328 | return new HashMap<>(); |
| 322 | 329 | } |
| 323 | 330 | |
| 331 | + private void handleDetour(LsStationRoute stationRoute) { | |
| 332 | + Integer detourStationRouteId = stationRoute.getDetourStationRoute(); | |
| 333 | + if (detourStationRouteId == null) { | |
| 334 | + return; | |
| 335 | + } | |
| 336 | + | |
| 337 | + // 获取终点站点路由 | |
| 338 | + LsStationRoute endStationRoute = lsStationRouteRepository.findById(detourStationRouteId) | |
| 339 | + .orElseThrow(() -> new IllegalArgumentException("未找到对应的终点站点路由,ID:" + detourStationRouteId)); | |
| 340 | + | |
| 341 | + // 获取起点和终点的WGS坐标 | |
| 342 | + org.geolatte.geom.Point startPoint = stationRoute.getCenterPointWgs(); | |
| 343 | + org.geolatte.geom.Point endPoint = endStationRoute.getCenterPointWgs(); | |
| 344 | + if (startPoint == null || endPoint == null) { | |
| 345 | + throw new IllegalArgumentException("起点或终点站点坐标信息不完整"); | |
| 346 | + } | |
| 347 | + | |
| 348 | + // 转换为内部Geo.Point | |
| 349 | + com.bsth.util.Geo.Point startGeoPoint = toGeoPoint(startPoint); | |
| 350 | + com.bsth.util.Geo.Point endGeoPoint = toGeoPoint(endPoint); | |
| 351 | + | |
| 352 | + // 获取线路、版本号、上下行信息 | |
| 353 | + Integer lineId = Optional.ofNullable(stationRoute.getLine()) | |
| 354 | + .map(Line::getId) | |
| 355 | + .orElseThrow(() -> new IllegalArgumentException("站点路由关联的线路信息缺失")); | |
| 356 | + Integer versions = stationRoute.getVersions(); | |
| 357 | + Integer directions = stationRoute.getDirections(); | |
| 358 | + | |
| 359 | + // 查询所有路段路由(按路段编码升序) | |
| 360 | + Map<String, Object> params = new HashMap<>(); | |
| 361 | + params.put("line.id_eq", lineId); | |
| 362 | + params.put("versions_eq", versions); | |
| 363 | + params.put("directions_eq", directions); | |
| 364 | + params.put("destroy_eq", 0); | |
| 365 | + List<LsSectionRoute> sectionRoutes = lsSectionRouteRepository.findAll( | |
| 366 | + new CustomerSpecs<>(params), | |
| 367 | + Sort.by(Sort.Direction.ASC, "sectionrouteCode") | |
| 368 | + ); | |
| 369 | + | |
| 370 | + // 第一步:找到起点和终点所在的路段及索引 | |
| 371 | + LsSectionRoute startSection = null; | |
| 372 | + LsSectionRoute endSection = null; | |
| 373 | + int startIndex = -1; | |
| 374 | + int endIndex = -1; | |
| 375 | + double minStartDistance = Double.MAX_VALUE; | |
| 376 | + double minEndDistance = Double.MAX_VALUE; | |
| 377 | + | |
| 378 | + for (int i = 0; i < sectionRoutes.size(); i++) { | |
| 379 | + LsSectionRoute sectionRoute = sectionRoutes.get(i); | |
| 380 | + Section section = sectionRoute.getSection(); | |
| 381 | + if (section == null || section.getGsectionVector() == null) { | |
| 382 | + continue; | |
| 383 | + } | |
| 384 | + LineString lineString = section.getGsectionVector(); | |
| 385 | + | |
| 386 | + // 计算起点到当前路段的最小距离 | |
| 387 | + double startDist = calcMinDistanceToLine(lineString, startGeoPoint); | |
| 388 | + if (startDist < minStartDistance) { | |
| 389 | + minStartDistance = startDist; | |
| 390 | + startSection = sectionRoute; | |
| 391 | + startIndex = i; | |
| 392 | + } | |
| 393 | + | |
| 394 | + // 计算终点到当前路段的最小距离 | |
| 395 | + double endDist = calcMinDistanceToLine(lineString, endGeoPoint); | |
| 396 | + if (endDist < minEndDistance) { | |
| 397 | + minEndDistance = endDist; | |
| 398 | + endSection = sectionRoute; | |
| 399 | + endIndex = i; | |
| 400 | + } | |
| 401 | + } | |
| 402 | + | |
| 403 | + if (startSection == null || endSection == null) { | |
| 404 | + log.warn("未能找到起点或终点所在的路段,起点ID:{},终点ID:{}", | |
| 405 | + stationRoute.getId(), endStationRoute.getId()); | |
| 406 | + return; | |
| 407 | + } | |
| 408 | + | |
| 409 | + // 第二步:确定中间经过的路段(排除起点和终点路段) | |
| 410 | + List<LsSectionRoute> passingSections = new ArrayList<>(); | |
| 411 | + if (startIndex >= 0 && endIndex >= 0) { | |
| 412 | + int low = Math.min(startIndex, endIndex); | |
| 413 | + int high = Math.max(startIndex, endIndex); | |
| 414 | + // 只添加严格介于两者之间的路段 | |
| 415 | + for (int i = low + 1; i < high; i++) { | |
| 416 | + passingSections.add(sectionRoutes.get(i)); | |
| 417 | + } | |
| 418 | + } | |
| 419 | + | |
| 420 | + // 检查路段数(超过15视为异常) | |
| 421 | + if (passingSections.size() > 13) { | |
| 422 | + log.error("绕改道路径过长,起点路段:{},终点路段:{},中间路段数:{}", | |
| 423 | + startSection.getId(), endSection.getId(), passingSections.size()); | |
| 424 | + throw new RuntimeException("过长的绕改道路径(超过13个中间路段)"); | |
| 425 | + } | |
| 426 | + | |
| 427 | + // 构建绕改道路径 | |
| 428 | + Detour detour = new Detour(); | |
| 429 | + detour.setLine(lineId); | |
| 430 | + detour.setVersions(versions); | |
| 431 | + detour.setDirection(directions); | |
| 432 | + detour.setStartStationCode(stationRoute.getStationCode()); | |
| 433 | + detour.setTerminalStationCode(endStationRoute.getStationCode()); | |
| 434 | + | |
| 435 | + String points = buildPoints(startPoint, passingSections, endPoint); | |
| 436 | + try { | |
| 437 | + detour.setPoints(points); | |
| 438 | + detourRepository.save(detour); | |
| 439 | + log.info("绕改道路径保存成功,线路:{},版本:{},方向:{}", lineId, versions, directions); | |
| 440 | + } catch (Exception e) { | |
| 441 | + log.error("保存绕改道失败,points:{}", points, e); | |
| 442 | + throw new RuntimeException("保存绕改道路径失败", e); | |
| 443 | + } | |
| 444 | + } | |
| 445 | + | |
| 446 | + /** | |
| 447 | + * 将org.geolatte.geom.Point转换为内部Geo.Point | |
| 448 | + */ | |
| 449 | + private com.bsth.util.Geo.Point toGeoPoint(org.geolatte.geom.Point point) { | |
| 450 | + return new com.bsth.util.Geo.Point( | |
| 451 | + point.getPosition().getCoordinate(0), | |
| 452 | + point.getPosition().getCoordinate(1) | |
| 453 | + ); | |
| 454 | + } | |
| 455 | + | |
| 456 | + /** | |
| 457 | + * 将org.geolatte.geom.Position转换为内部Geo.Point | |
| 458 | + */ | |
| 459 | + private com.bsth.util.Geo.Point toGeoPoint(org.geolatte.geom.Position position) { | |
| 460 | + return new com.bsth.util.Geo.Point( | |
| 461 | + position.getCoordinate(0), | |
| 462 | + position.getCoordinate(1) | |
| 463 | + ); | |
| 464 | + } | |
| 465 | + | |
| 466 | + /** | |
| 467 | + * 计算点到LineString的最小距离(遍历每个线段) | |
| 468 | + * 注意:使用getPositionN获取位置,LineString无getPointN方法 | |
| 469 | + */ | |
| 470 | + private double calcMinDistanceToLine(LineString lineString, | |
| 471 | + com.bsth.util.Geo.Point geoPoint) { | |
| 472 | + double minDist = Double.MAX_VALUE; | |
| 473 | + int numPoints = lineString.getNumPositions(); // 获取点数 | |
| 474 | + for (int i = 0; i < numPoints - 1; i++) { | |
| 475 | + org.geolatte.geom.Position p1 = lineString.getPositionN(i); | |
| 476 | + org.geolatte.geom.Position p2 = lineString.getPositionN(i + 1); | |
| 477 | + com.bsth.util.Geo.Point geoP1 = toGeoPoint(p1); | |
| 478 | + com.bsth.util.Geo.Point geoP2 = toGeoPoint(p2); | |
| 479 | + double dist = GeoUtils.getDistanceFromLine(geoP1, geoP2, geoPoint); | |
| 480 | + minDist = Math.min(minDist, dist); | |
| 481 | + } | |
| 482 | + return minDist; | |
| 483 | + } | |
| 484 | + | |
| 485 | + /** | |
| 486 | + * 构建坐标点 包含起点、中间路段中点、终点 | |
| 487 | + */ | |
| 488 | + private String buildPoints(org.geolatte.geom.Point startPoint, | |
| 489 | + List<LsSectionRoute> passingSections, | |
| 490 | + org.geolatte.geom.Point endPoint) { | |
| 491 | + StringBuilder wktBuilder = new StringBuilder(); | |
| 492 | + // 添加起点 | |
| 493 | + wktBuilder.append(startPoint.getPosition().getCoordinate(0)) | |
| 494 | + .append(" ") | |
| 495 | + .append(startPoint.getPosition().getCoordinate(1)); | |
| 496 | + | |
| 497 | + // 添加中间路段的中点 | |
| 498 | + for (LsSectionRoute sectionRoute : passingSections) { | |
| 499 | + Section section = sectionRoute.getSection(); | |
| 500 | + if (section != null && section.getGsectionVector() != null) { | |
| 501 | + LineString lineString = section.getGsectionVector(); | |
| 502 | + int numPoints = lineString.getNumPositions(); | |
| 503 | + int midIndex = numPoints / 2; // 取中间索引点 | |
| 504 | + org.geolatte.geom.Position midPos = lineString.getPositionN(midIndex); | |
| 505 | + wktBuilder.append(",") | |
| 506 | + .append(midPos.getCoordinate(0)) | |
| 507 | + .append(" ") | |
| 508 | + .append(midPos.getCoordinate(1)); | |
| 509 | + } | |
| 510 | + } | |
| 511 | + | |
| 512 | + // 添加终点 | |
| 513 | + wktBuilder.append(",") | |
| 514 | + .append(endPoint.getPosition().getCoordinate(0)) | |
| 515 | + .append(" ") | |
| 516 | + .append(endPoint.getPosition().getCoordinate(1)); | |
| 517 | + return wktBuilder.toString(); | |
| 518 | + } | |
| 519 | + | |
| 324 | 520 | @Transactional |
| 325 | 521 | @Override |
| 326 | 522 | public Map<String, Object> exchangeDirection(int lineId, int version) { | ... | ... |
src/main/java/com/bsth/service/impl/StationRouteServiceImpl.java
| ... | ... | @@ -509,8 +509,8 @@ public class StationRouteServiceImpl extends BaseServiceImpl<StationRoute, Integ |
| 509 | 509 | clientUtils.uploadFile(url, port, username, password, remotePath + "/voice/", textFileName, input); |
| 510 | 510 | String linePath = String.format(linePathPattern, lineId), voicePath = String.format("%s%s.zip", linePath, lineId); |
| 511 | 511 | // 报站文件上传(全程) |
| 512 | - clientUtils.deleteFtpFile(url, port, username, password, remotePath + "/voice/", String.format("%s.zip", line.getLineCode())); | |
| 513 | - clientUtils.FTPUpLoadFromDisk(new File(voicePath), String.format("%s.zip", line.getLineCode()), url, port, username, password, remotePath + "/voice/"); | |
| 512 | +// clientUtils.deleteFtpFile(url, port, username, password, remotePath + "/voice/", String.format("%s.zip", line.getLineCode())); | |
| 513 | +// clientUtils.FTPUpLoadFromDisk(new File(voicePath), String.format("%s.zip", line.getLineCode()), url, port, username, password, remotePath + "/voice/"); | |
| 514 | 514 | |
| 515 | 515 | // 线路区间 |
| 516 | 516 | if (lineRegions.size() > 0) { |
| ... | ... | @@ -1305,7 +1305,7 @@ public class StationRouteServiceImpl extends BaseServiceImpl<StationRoute, Integ |
| 1305 | 1305 | // 子线路路径 |
| 1306 | 1306 | String linePath = String.format(linePathPattern, lineId); |
| 1307 | 1307 | String subLinePath = String.format("%s%s/", linePath, subLineId); |
| 1308 | - List<String> arr = Arrays.asList(commonPath + "cn_origin_1.mp3", linePath + String.format("cn/%03d.mp3", 0), commonPath + "cn_origin_2.mp3", linePath + String.format("cn/%03d.mp3", terminal.getStationLevel()), commonPath + "sh_origin_1.mp3", linePath + String.format("sh/%03d.mp3", 0), commonPath + "sh_origin_2.mp3", linePath + String.format("cn/%03d.mp3", terminal.getStationLevel()), commonPath + "cn_start_1.mp3", linePath + String.format("cn/%03d.mp3", current.getStationLevel()), commonPath + "cn_start_2.mp3", commonPath + "sh_start_1.mp3", linePath + String.format("sh/%03d.mp3", current.getStationLevel()), commonPath + "sh_start_2.mp3", commonPath + "en_1.mp3", linePath + String.format("en/%03d.mp3", current.getStationLevel()), commonPath + "cn_start_3.mp3", commonPath + "sh_start_3.mp3"); | |
| 1308 | + List<String> arr = Arrays.asList(commonPath + "cn_origin_1.mp3", linePath + String.format("cn/%03d.mp3", 0), commonPath + "cn_origin_2.mp3", linePath + String.format("cn/%03d.mp3", terminal.getStationLevel()), commonPath + "sh_origin_1.mp3", linePath + String.format("sh/%03d.mp3", 0), commonPath + "sh_origin_2.mp3", linePath + String.format("sh/%03d.mp3", terminal.getStationLevel()), commonPath + "cn_start_1.mp3", linePath + String.format("cn/%03d.mp3", current.getStationLevel()), commonPath + "cn_start_2.mp3", commonPath + "sh_start_1.mp3", linePath + String.format("sh/%03d.mp3", current.getStationLevel()), commonPath + "sh_start_2.mp3", commonPath + "en_1.mp3", linePath + String.format("en/%03d.mp3", current.getStationLevel()), commonPath + "cn_start_3.mp3", commonPath + "sh_start_3.mp3"); | |
| 1309 | 1309 | List<String> inputPaths = new ArrayList<>(); |
| 1310 | 1310 | for (String path : arr) { |
| 1311 | 1311 | for (String lang : languages) { | ... | ... |
src/main/java/com/bsth/service/impl/TrafficManageServiceImpl.java
| 1 | 1 | package com.bsth.service.impl; |
| 2 | 2 | |
| 3 | 3 | import com.bsth.data.BasicData; |
| 4 | +import com.bsth.data.SystemParamCache; | |
| 4 | 5 | import com.bsth.email.SendEmailController; |
| 5 | 6 | import com.bsth.email.entity.EmailBean; |
| 6 | 7 | import com.bsth.entity.*; |
| ... | ... | @@ -23,9 +24,9 @@ import com.bsth.util.CoordinateConverter; |
| 23 | 24 | import com.bsth.util.IpUtils; |
| 24 | 25 | import com.bsth.util.TimeUtils; |
| 25 | 26 | import com.bsth.util.db.DBUtils_MS; |
| 26 | -import com.bsth.webService.trafficManage.org.tempuri.Results; | |
| 27 | -import com.bsth.webService.trafficManage.org.tempuri.WebServiceLocator; | |
| 28 | -import com.bsth.webService.trafficManage.org.tempuri.WebServiceSoap; | |
| 27 | +import com.bsth.webService.trafficManage.up.org.tempuri.Results; | |
| 28 | +import com.bsth.webService.trafficManage.up.org.tempuri.WebServiceLocator; | |
| 29 | +import com.bsth.webService.trafficManage.up.org.tempuri.WebServiceSoap; | |
| 29 | 30 | import org.apache.commons.lang.StringEscapeUtils; |
| 30 | 31 | import org.apache.commons.lang.StringUtils; |
| 31 | 32 | import org.apache.commons.lang.time.DateUtils; |
| ... | ... | @@ -33,6 +34,7 @@ import org.joda.time.DateTime; |
| 33 | 34 | import org.slf4j.Logger; |
| 34 | 35 | import org.slf4j.LoggerFactory; |
| 35 | 36 | import org.springframework.beans.factory.annotation.Autowired; |
| 37 | +import org.springframework.beans.factory.annotation.Value; | |
| 36 | 38 | import org.springframework.data.domain.Sort; |
| 37 | 39 | import org.springframework.data.domain.Sort.Direction; |
| 38 | 40 | import org.springframework.security.core.context.SecurityContextHolder; |
| ... | ... | @@ -135,11 +137,31 @@ public class TrafficManageServiceImpl implements TrafficManageService{ |
| 135 | 137 | private LineVersionsRepository lineVersionsRepository; |
| 136 | 138 | |
| 137 | 139 | // 运管处上传接口 |
| 138 | - private com.bsth.webService.trafficManage.up.org.tempuri.WebServiceSoap webServiceSoapUp; | |
| 139 | - private WebServiceSoap ssop ; | |
| 140 | + private WebServiceSoap ssop,ssop1; | |
| 141 | + private WebServiceSoap ssopBak,ssopBak1; | |
| 140 | 142 | { |
| 141 | 143 | try { |
| 142 | - ssop = new WebServiceLocator().getWebServiceSoap(); | |
| 144 | + WebServiceLocator locator = new WebServiceLocator(); | |
| 145 | + String url = SystemParamCache.getDrSysCityInterfaceUrl(); | |
| 146 | + if (StringUtils.isNotEmpty(url)) { | |
| 147 | + locator.setWebServiceSoapEndpointAddress(url); | |
| 148 | + ssop = locator.getWebServiceSoap(); | |
| 149 | + } | |
| 150 | + url = SystemParamCache.getDrSysCityInterfaceUrl1(); | |
| 151 | + if (StringUtils.isNotEmpty(url)) { | |
| 152 | + locator.setWebServiceSoapEndpointAddress(url); | |
| 153 | + ssop1 = locator.getWebServiceSoap(); | |
| 154 | + } | |
| 155 | + url = SystemParamCache.getDrSysCityInterfaceBakUrl(); | |
| 156 | + if (StringUtils.isNotEmpty(url)) { | |
| 157 | + locator.setWebServiceSoapEndpointAddress(url); | |
| 158 | + ssopBak = locator.getWebServiceSoap(); | |
| 159 | + } | |
| 160 | + url = SystemParamCache.getDrSysCityInterfaceBakUrl1(); | |
| 161 | + if (StringUtils.isNotEmpty(url)) { | |
| 162 | + locator.setWebServiceSoapEndpointAddress(url); | |
| 163 | + ssopBak1 = locator.getWebServiceSoap(); | |
| 164 | + } | |
| 143 | 165 | } catch (Exception e) { |
| 144 | 166 | e.printStackTrace(); |
| 145 | 167 | } |
| ... | ... | @@ -153,31 +175,20 @@ public class TrafficManageServiceImpl implements TrafficManageService{ |
| 153 | 175 | // 数字格式化 |
| 154 | 176 | DecimalFormat format = new DecimalFormat("0.00"); |
| 155 | 177 | |
| 156 | - // 用户名 | |
| 157 | - private final String userNameOther = "user"; | |
| 158 | - // 密码 | |
| 159 | - private final String passwordOther = "user"; | |
| 178 | + private final String userNameOther = SystemParamCache.getDrSysCityInterfaceUser(); | |
| 179 | + | |
| 180 | + private final String passwordOther = SystemParamCache.getDrSysCityInterfacePassword(); | |
| 181 | + | |
| 182 | + private final String userNameUp = SystemParamCache.getDrSysCityInterfaceBakUser(); | |
| 183 | + | |
| 184 | + private final String passwordUp = SystemParamCache.getDrSysCityInterfaceBakPassword(); | |
| 160 | 185 | |
| 161 | - // 用户名 | |
| 162 | - private final String userNameUp = "user"; | |
| 163 | - // 密码 | |
| 164 | - private final String passwordUp = "user"; | |
| 165 | 186 | // 接收邮件人 |
| 166 | - private final String emailSendToAddress = "113252620@qq.com"; | |
| 187 | + private String[] emails = SystemParamCache.getMailWaybill().split(","); | |
| 188 | + | |
| 167 | 189 | // 记录路单上线的成功、失败线路数 |
| 168 | 190 | private Integer countSuccess,countFailure; |
| 169 | 191 | |
| 170 | - private synchronized com.bsth.webService.trafficManage.up.org.tempuri.WebServiceSoap getWebServiceSoapUp(){ | |
| 171 | - try { | |
| 172 | - if(webServiceSoapUp == null){ | |
| 173 | - webServiceSoapUp = new com.bsth.webService.trafficManage.up.org.tempuri.WebServiceLocator().getWebServiceSoap(); | |
| 174 | - } | |
| 175 | - }catch (Exception e){ | |
| 176 | - e.printStackTrace(); | |
| 177 | - }finally { | |
| 178 | - return webServiceSoapUp; | |
| 179 | - } | |
| 180 | - } | |
| 181 | 192 | /** |
| 182 | 193 | * 上传线路信息 |
| 183 | 194 | */ |
| ... | ... | @@ -218,13 +229,18 @@ public class TrafficManageServiceImpl implements TrafficManageService{ |
| 218 | 229 | } |
| 219 | 230 | String state;// 是否上传成功 |
| 220 | 231 | // 调用上传方法 |
| 221 | - if(getWebServiceSoapUp().setXL(userNameUp,passwordUp,xml).isSuccess()){ | |
| 232 | + if(ssop1.setXL(userNameOther,passwordOther,xml).isSuccess()){ | |
| 222 | 233 | result = "success"; |
| 223 | 234 | state = "1"; |
| 224 | 235 | }else{ |
| 225 | 236 | result = "failure"; |
| 226 | 237 | state = "0"; |
| 227 | 238 | } |
| 239 | + if (ssopBak1.setXL(userNameOther,passwordOther,xml).isSuccess()) { | |
| 240 | + result += ",success"; | |
| 241 | + } else { | |
| 242 | + result += ",failure"; | |
| 243 | + } | |
| 228 | 244 | logger.info("setXL:"+xml); |
| 229 | 245 | logger.info("setXL:"+result); |
| 230 | 246 | // 保存运管处上传记录 |
| ... | ... | @@ -319,6 +335,9 @@ public class TrafficManageServiceImpl implements TrafficManageService{ |
| 319 | 335 | if(ssop.setCL(userNameOther, passwordOther, sBuffer.toString()).isSuccess()){ |
| 320 | 336 | result = "success"; |
| 321 | 337 | } |
| 338 | + if (ssopBak != null && ssopBak.setCL(userNameOther, passwordOther, sBuffer.toString()).isSuccess()) { | |
| 339 | + result += ",success"; | |
| 340 | + } | |
| 322 | 341 | } catch (Exception e) { |
| 323 | 342 | logger.error("setCL:",e); |
| 324 | 343 | e.printStackTrace(); |
| ... | ... | @@ -356,7 +375,10 @@ public class TrafficManageServiceImpl implements TrafficManageService{ |
| 356 | 375 | sBuffer.append("</SJs>"); |
| 357 | 376 | if(ssop.setSJ(userNameOther, passwordOther, sBuffer.toString()).isSuccess()){ |
| 358 | 377 | result = "success"; |
| 359 | - }; | |
| 378 | + } | |
| 379 | + if (ssopBak != null && ssopBak.setSJ(userNameOther, passwordOther, sBuffer.toString()).isSuccess()) { | |
| 380 | + result += ",success"; | |
| 381 | + } | |
| 360 | 382 | } catch (Exception e) { |
| 361 | 383 | logger.error("setSJ:",e); |
| 362 | 384 | e.printStackTrace(); |
| ... | ... | @@ -395,6 +417,7 @@ public class TrafficManageServiceImpl implements TrafficManageService{ |
| 395 | 417 | String str = "", xlbm = null, oldXlbm = null; |
| 396 | 418 | List<Map<String,Object>> listGroup = null; |
| 397 | 419 | int scount = 0, ccount = 0; |
| 420 | + int scount1 = 0, ccount1 = 0; | |
| 398 | 421 | long start = System.currentTimeMillis(); |
| 399 | 422 | try { |
| 400 | 423 | // 计数器 |
| ... | ... | @@ -436,6 +459,7 @@ public class TrafficManageServiceImpl implements TrafficManageService{ |
| 436 | 459 | Line line = code2line.get(lineCode); |
| 437 | 460 | if(line == null || line.getInUse() == null || line.getInUse() == 0){ |
| 438 | 461 | ccount++; |
| 462 | + ccount1++; | |
| 439 | 463 | continue; |
| 440 | 464 | } |
| 441 | 465 | if(counter % per == 0){ |
| ... | ... | @@ -512,7 +536,8 @@ public class TrafficManageServiceImpl implements TrafficManageService{ |
| 512 | 536 | sf.append("</DLDS>"); |
| 513 | 537 | // 去掉'号 |
| 514 | 538 | str = sf.toString().replace("'",""); |
| 515 | - scount += invokeSetLD(str, counter); | |
| 539 | + scount += invokeSetLD(ssop, str, counter, "master"); | |
| 540 | + scount1 += invokeSetLD(ssopBak, str, counter, "slave"); | |
| 516 | 541 | counter = 0; |
| 517 | 542 | } |
| 518 | 543 | } |
| ... | ... | @@ -521,18 +546,23 @@ public class TrafficManageServiceImpl implements TrafficManageService{ |
| 521 | 546 | sf.append("</DLDS>"); |
| 522 | 547 | // 去掉'号 |
| 523 | 548 | str = sf.toString().replace("'",""); |
| 524 | - scount += invokeSetLD(str, counter); | |
| 549 | + scount += invokeSetLD(ssop, str, counter, "master"); | |
| 550 | + if (ssopBak != null) { | |
| 551 | + scount1 += invokeSetLD(ssopBak, str, counter, "slave"); | |
| 552 | + } | |
| 525 | 553 | } |
| 526 | 554 | } catch (Exception e) { |
| 527 | 555 | e.printStackTrace(); |
| 528 | 556 | logger.error("setLD:", e); |
| 529 | 557 | } finally { |
| 530 | 558 | try { |
| 531 | - //发送邮件 | |
| 532 | - EmailBean mail = new EmailBean(); | |
| 533 | - mail.setSubject(IpUtils.getLocalIpAddress() +":路单日志数据"+date); | |
| 534 | - mail.setContent("总数:" + (listGroup == null ? 0 : listGroup.size()) + "<br/>成功数:" + scount + "<br/>跳过数:" + ccount + "<br/>耗时:" + (System.currentTimeMillis() - start)); | |
| 535 | - sendEmailController.sendMail(emailSendToAddress, mail); | |
| 559 | + for (String email : emails) { | |
| 560 | + //发送邮件 | |
| 561 | + EmailBean mail = new EmailBean(); | |
| 562 | + mail.setSubject(IpUtils.getLocalIpAddress() +":路单日志数据"+date); | |
| 563 | + mail.setContent("总数:" + (listGroup == null ? 0 : listGroup.size()) + "<br/>成功数:" + scount + "," + scount1 + "<br/>跳过数:" + ccount + "," + ccount1 + "<br/>耗时:" + (System.currentTimeMillis() - start)); | |
| 564 | + sendEmailController.sendMail(email, mail); | |
| 565 | + } | |
| 536 | 566 | logger.info("setLD-sendMail:邮件发送成功!"); |
| 537 | 567 | } catch (Exception e) { |
| 538 | 568 | e.printStackTrace(); |
| ... | ... | @@ -548,21 +578,21 @@ public class TrafficManageServiceImpl implements TrafficManageService{ |
| 548 | 578 | * @param counter 分组数 |
| 549 | 579 | * @return 成功返回counter 失败返回0 |
| 550 | 580 | */ |
| 551 | - private int invokeSetLD(String xml, int counter) { | |
| 581 | + private int invokeSetLD(WebServiceSoap ssop, String xml, int counter, String flag) { | |
| 552 | 582 | for (int i = 0;i < 10;i++) { |
| 553 | 583 | try { |
| 554 | 584 | Results results = ssop.setLD(userNameOther, passwordOther, StringEscapeUtils.unescapeHtml(xml)); |
| 555 | 585 | if (results.isSuccess()) { |
| 556 | - logger.info("setLD: " + xml); | |
| 586 | + logger.info("{} setLD: {}", flag, xml); | |
| 557 | 587 | logger.info("setLD: 成功"); |
| 558 | 588 | return counter; |
| 559 | 589 | } else if (i == 9) { |
| 560 | - logger.error("setLD: " + xml); | |
| 590 | + logger.error("{} setLD: {}", flag, xml); | |
| 561 | 591 | logger.error("setLD: 失败," + results.getMessage()); |
| 562 | 592 | } |
| 563 | 593 | Thread.sleep(2000); |
| 564 | 594 | } catch (Exception e) { |
| 565 | - logger.error("运管处接口调用异常", e); | |
| 595 | + logger.error("{} 运管处接口调用异常", flag, e); | |
| 566 | 596 | try { |
| 567 | 597 | Thread.sleep(2000); |
| 568 | 598 | } catch (InterruptedException ex) { |
| ... | ... | @@ -586,6 +616,9 @@ public class TrafficManageServiceImpl implements TrafficManageService{ |
| 586 | 616 | if(rss.isSuccess()){ |
| 587 | 617 | result = "success"; |
| 588 | 618 | } |
| 619 | + if (ssopBak != null && ssopBak.setLD(userNameOther, passwordOther, StringEscapeUtils.unescapeHtml(tmp)).isSuccess()) { | |
| 620 | + result += ",success"; | |
| 621 | + } | |
| 589 | 622 | } catch (Exception e) { |
| 590 | 623 | logger.error("setLD:",e); |
| 591 | 624 | e.printStackTrace(); |
| ... | ... | @@ -688,6 +721,9 @@ public class TrafficManageServiceImpl implements TrafficManageService{ |
| 688 | 721 | if(ssop.setLCYH(userNameOther, passwordOther, sf.toString()).isSuccess()){ |
| 689 | 722 | result = "success"; |
| 690 | 723 | } |
| 724 | + if (ssopBak != null && ssopBak.setLCYH(userNameOther, passwordOther, sf.toString()).isSuccess()) { | |
| 725 | + result += ",success"; | |
| 726 | + } | |
| 691 | 727 | } catch (Exception e) { |
| 692 | 728 | logger.error("setLCYH:",e); |
| 693 | 729 | e.printStackTrace(); |
| ... | ... | @@ -792,6 +828,9 @@ public class TrafficManageServiceImpl implements TrafficManageService{ |
| 792 | 828 | if(ssop.setDDRB(userNameOther, passwordOther, sf.toString()).isSuccess()){ |
| 793 | 829 | result = "success"; |
| 794 | 830 | } |
| 831 | + if (ssopBak != null && ssopBak.setDDRB(userNameOther, passwordOther, sf.toString()).isSuccess()) { | |
| 832 | + result += ",success"; | |
| 833 | + } | |
| 795 | 834 | } catch (Exception e) { |
| 796 | 835 | logger.error("setDDRB:",e); |
| 797 | 836 | e.printStackTrace(); |
| ... | ... | @@ -910,6 +949,9 @@ public class TrafficManageServiceImpl implements TrafficManageService{ |
| 910 | 949 | if(ssop.setJHBC(userNameOther, passwordOther, sBuffer.toString()).isSuccess()){ |
| 911 | 950 | result = "success"; |
| 912 | 951 | } |
| 952 | + if (ssopBak != null && ssopBak.setJHBC(userNameOther, passwordOther, sBuffer.toString()).isSuccess()) { | |
| 953 | + result += ",success"; | |
| 954 | + } | |
| 913 | 955 | } catch (Exception e) { |
| 914 | 956 | logger.error("setJHBC:",e); |
| 915 | 957 | e.printStackTrace(); |
| ... | ... | @@ -1103,14 +1145,20 @@ public class TrafficManageServiceImpl implements TrafficManageService{ |
| 1103 | 1145 | result = "上传失败"; |
| 1104 | 1146 | state = "0"; |
| 1105 | 1147 | } |
| 1148 | + if (ssopBak != null) { | |
| 1149 | + if (ssopBak.setSKB(userNameOther, passwordOther, sBuffer.toString()).isSuccess()) { | |
| 1150 | + result += ",上传成功"; | |
| 1151 | + } else { | |
| 1152 | + result += ",上传失败"; | |
| 1153 | + } | |
| 1154 | + } | |
| 1155 | + logger.info("xml:" + sBuffer.toString()); | |
| 1156 | + logger.info("上传结果:" + result); | |
| 1106 | 1157 | // 保存运管处上传记录 |
| 1107 | 1158 | saveYgcUploadLog(ttinfoList,sBuffer.toString(),TrafficManageServiceImpl.UPLOAD_TYPE_SKB,state); |
| 1108 | 1159 | } catch (Exception e) { |
| 1109 | 1160 | logger.error("setSKB:", e); |
| 1110 | 1161 | e.printStackTrace(); |
| 1111 | - }finally{ | |
| 1112 | - logger.info("setSKB:"+sBuffer.toString()); | |
| 1113 | - logger.info("setSKB:"+result); | |
| 1114 | 1162 | } |
| 1115 | 1163 | return result; |
| 1116 | 1164 | } |
| ... | ... | @@ -1191,6 +1239,7 @@ public class TrafficManageServiceImpl implements TrafficManageService{ |
| 1191 | 1239 | } |
| 1192 | 1240 | } |
| 1193 | 1241 | } |
| 1242 | + | |
| 1194 | 1243 | /** |
| 1195 | 1244 | * 上传线路人员车辆配置信息 |
| 1196 | 1245 | */ |
| ... | ... | @@ -1243,6 +1292,9 @@ public class TrafficManageServiceImpl implements TrafficManageService{ |
| 1243 | 1292 | if(ssop.setXLPC(userNameOther, passwordOther, sBuffer.toString()).isSuccess()){ |
| 1244 | 1293 | result = "success"; |
| 1245 | 1294 | } |
| 1295 | + if (ssopBak != null && ssopBak.setXLPC(userNameOther, passwordOther, sBuffer.toString()).isSuccess()) { | |
| 1296 | + result += ",success"; | |
| 1297 | + } | |
| 1246 | 1298 | } catch (Exception e) { |
| 1247 | 1299 | logger.error("setXLPC:",e); |
| 1248 | 1300 | e.printStackTrace(); |
| ... | ... | @@ -1303,6 +1355,9 @@ public class TrafficManageServiceImpl implements TrafficManageService{ |
| 1303 | 1355 | if(ssop.setCS(userNameOther, passwordOther, sBuffer.toString()).isSuccess()){ |
| 1304 | 1356 | result = "success"; |
| 1305 | 1357 | } |
| 1358 | + if (ssopBak != null && ssopBak.setCS(userNameOther, passwordOther, sBuffer.toString()).isSuccess()) { | |
| 1359 | + result += ",success"; | |
| 1360 | + } | |
| 1306 | 1361 | } catch (Exception e) { |
| 1307 | 1362 | logger.error("setCS:",e); |
| 1308 | 1363 | e.printStackTrace(); | ... | ... |
src/main/resources/static/pages/base/stationroute/add_stationroute_step2.html
| ... | ... | @@ -311,7 +311,7 @@ $('#add_stationroute_step2_modal').on('modal.show', function(event){ |
| 311 | 311 | params.bufferPolygonWkt = params.bufferPolygonWkt ? 'POLYGON((' + params.bufferPolygonWkt + '))' : ''; |
| 312 | 312 | params.shapedType = params.shapedType == '圆形' ? 'r' : 'd'; |
| 313 | 313 | if (params.stationRouteCode == '请选择...' && params.stationMark == 'B') { |
| 314 | - params.stationRouteCode = '100'; | |
| 314 | + params.stationRouteCode = 1; | |
| 315 | 315 | } else { |
| 316 | 316 | params.stationRouteCode = parseInt(params.stationRouteCode) + 1; |
| 317 | 317 | } | ... | ... |
src/main/resources/static/pages/base/stationroute/addstationstemplate.html
| ... | ... | @@ -201,7 +201,7 @@ $('#add_station_template_modal').on('modal.show', function(event) { |
| 201 | 201 | } |
| 202 | 202 | |
| 203 | 203 | function formatRoutes(params) { |
| 204 | - var stationRoutes = [], sectionRoutes = [], sectionRouteCode = 100; | |
| 204 | + var stationRoutes = [], sectionRoutes = [], sectionRouteCode = 1; | |
| 205 | 205 | params.stationJSON.forEach(function(item) { |
| 206 | 206 | stationRoutes.push({stationName: item.name, shapedType: 'r', radius: 80, destroy: 0, distances: 0, toTime: 0, station: {stationName: item.name, centerPointWkt: 'POINT(' + item.potion.lng + ' ' + item.potion.lat + ')'}}); |
| 207 | 207 | }) | ... | ... |
src/main/resources/static/pages/base/stationroute/edit_sectionroute.html
| ... | ... | @@ -138,7 +138,7 @@ $('#edit_sectionroute_modal').on('modal.show', function(e, polyline){ |
| 138 | 138 | params.sectionTime = 0; |
| 139 | 139 | |
| 140 | 140 | if(params.sectionrouteCode == '请选择...') { |
| 141 | - params.sectionrouteCode = 100; | |
| 141 | + params.sectionrouteCode = 1; | |
| 142 | 142 | } else { |
| 143 | 143 | params.sectionrouteCode = parseInt(params.sectionrouteCode) + 1; |
| 144 | 144 | } | ... | ... |
src/main/resources/static/pages/base/stationroute/edit_stationroute_step2.html
| ... | ... | @@ -174,6 +174,18 @@ |
| 174 | 174 | </div> |
| 175 | 175 | </div> |
| 176 | 176 | </div> |
| 177 | + <!-- 绕改道 --> | |
| 178 | + <div class="form-body"> | |
| 179 | + <div class="form-group"> | |
| 180 | + <label class="control-label col-md-3"> | |
| 181 | + 绕改道 : | |
| 182 | + </label> | |
| 183 | + <div class="col-md-6"> | |
| 184 | + <select name="detourStationRoute" class="form-control" id="detourStationRouteSelect" style="width:100%"></select> | |
| 185 | + <span class="help-block"> *说明:绕改道指当前站点至指定站点中间发生了临时走向调整(站点不调整),超过15个路段需要分开配置。 </span> | |
| 186 | + </div> | |
| 187 | + </div> | |
| 188 | + </div> | |
| 177 | 189 | </form> |
| 178 | 190 | </div> |
| 179 | 191 | <div class="modal-footer"> |
| ... | ... | @@ -257,7 +269,7 @@ $('#edit_stationroute_step2_modal').on('modal.show', function(event){ |
| 257 | 269 | else if(params.shapedType=='多边形') |
| 258 | 270 | params.shapedType='d'; |
| 259 | 271 | if(params.stationRouteCode == '' || params.stationMark === 'B') |
| 260 | - params.stationRouteCode = 100; | |
| 272 | + params.stationRouteCode = 1; | |
| 261 | 273 | if (params.stationMark !== 'B') { |
| 262 | 274 | params.stationRouteCode = parseInt(stationRouteCode.split('-')[0]) + 1; |
| 263 | 275 | } |
| ... | ... | @@ -295,14 +307,20 @@ $('#edit_stationroute_step2_modal').on('modal.show', function(event){ |
| 295 | 307 | var obj = {'id':'-1','text':'请选择...'}; |
| 296 | 308 | |
| 297 | 309 | RoutesService.getzdlyInfo(p, function(array) { |
| 310 | + debugger | |
| 298 | 311 | // 定义路段路由长度、渲染拼音检索下拉框格式数据. |
| 299 | - var len_ = array.length, paramsD = new Array(); | |
| 312 | + var len_ = array.length, paramsD = new Array(), stationRoutes = new Array(); | |
| 313 | + const choose = {'id':'-1','text':'请选择...'}; | |
| 300 | 314 | if(len_>0) { |
| 301 | - paramsD.push({'id':'-1','text':'请选择...'}); | |
| 315 | + paramsD.push(choose); | |
| 316 | + stationRoutes.push(choose) | |
| 302 | 317 | // 遍历. |
| 303 | 318 | $.each(array, function(i, g){ |
| 304 | 319 | if(g.stationName) { |
| 305 | 320 | if (g.stationRouteCode != editStationRoute.stationRouteCode) { |
| 321 | + if (stationRoutes.length == 1 && g.stationRouteCode > editStationRoute.stationRouteCode) { | |
| 322 | + stationRoutes.push({'id': g.id, 'text': g.stationName + '(' + g.stationRouteCode + ')'}); | |
| 323 | + } | |
| 306 | 324 | if (editStationRoute.stationMark == 'E' && i == (len_ - 2)){ |
| 307 | 325 | obj = {'id':g.stationRouteCode + '_' + 'E' + '_' + g.directions, 'text':g.stationName + ' (' + g.stationRouteCode + ')' + ' --' + RoutesOperation.dirdmToName(g.directions)}; |
| 308 | 326 | paramsD.push(obj); |
| ... | ... | @@ -316,12 +334,15 @@ $('#edit_stationroute_step2_modal').on('modal.show', function(event){ |
| 316 | 334 | } |
| 317 | 335 | }); |
| 318 | 336 | $('#stationrouteSelect').empty(); |
| 337 | + $('#detourStationRouteSelect').empty(); | |
| 319 | 338 | // 初始化上一个路段拼音检索下拉框. |
| 320 | 339 | initPinYinSelect2($('#stationrouteSelect'),paramsD,function(selector) { |
| 321 | - $('#stationrouteSelect').val(prevObj.id).select2(); | |
| 340 | + $('#stationrouteSelect').val(prevObj.id).trigger('change'); | |
| 322 | 341 | $('#stationMarkSelect').val(editStationRoute.stationMark); |
| 323 | 342 | }); |
| 324 | - | |
| 343 | + initPinYinSelect2($('#detourStationRouteSelect'), stationRoutes, function(selector) { | |
| 344 | + $('#detourStationRouteSelect').val(editStationRoute.detourStationRoute).trigger('change'); | |
| 345 | + }); | |
| 325 | 346 | } |
| 326 | 347 | }); |
| 327 | 348 | } | ... | ... |
src/main/resources/static/pages/base/stationroute/editsection_inout.html
| ... | ... | @@ -144,7 +144,7 @@ $('#edit_section_modal').on('modal.show', function(e, currentSection){ |
| 144 | 144 | params.sectionTime = 0; |
| 145 | 145 | error.hide(); |
| 146 | 146 | if(params.sectionrouteCode == '请选择...') { |
| 147 | - params.sectionrouteCode = 100; | |
| 147 | + params.sectionrouteCode = 1; | |
| 148 | 148 | } else { |
| 149 | 149 | params.sectionrouteCode = parseInt(params.sectionrouteCode) + 1; |
| 150 | 150 | } | ... | ... |
src/main/resources/static/pages/base/stationroute/js/routes-operation.js
| ... | ... | @@ -1325,7 +1325,7 @@ var RoutesOperation = (function () { |
| 1325 | 1325 | sectionRoute['line.id'] = lineId; |
| 1326 | 1326 | sectionRoute.sectionCode = sectionCode; |
| 1327 | 1327 | sectionRoute.roadCoding = ''; |
| 1328 | - sectionRoute.sectionrouteCode = 100; | |
| 1328 | + sectionRoute.sectionrouteCode = 1; | |
| 1329 | 1329 | sectionRoute.sectionTime = 0; |
| 1330 | 1330 | sectionRoute.sectionDistance = 0; |
| 1331 | 1331 | sectionRoute.speedLimit = 60; | ... | ... |
src/main/resources/static/pages/demo.html
0 → 100644
| 1 | +<!DOCTYPE html> | |
| 2 | +<html lang="zh-CN"> | |
| 3 | +<head> | |
| 4 | + <meta charset="UTF-8"> | |
| 5 | + <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| 6 | + <title>运能运力一盘棋</title> | |
| 7 | + <script src="https://cdn.tailwindcss.com"></script> | |
| 8 | + <script src="//api.map.baidu.com/api?v=2.0&ak=1TgEKvYqohJyeGXnN6yHSSTb4psOarQw"></script> | |
| 9 | + <style> | |
| 10 | + .BMap_cpyCtrl { | |
| 11 | + display: none; | |
| 12 | + } | |
| 13 | + | |
| 14 | + .anchorBL { | |
| 15 | + display: none; | |
| 16 | + } | |
| 17 | + | |
| 18 | + ::-webkit-scrollbar { | |
| 19 | + width: 6px; | |
| 20 | + height: 6px; | |
| 21 | + } | |
| 22 | + | |
| 23 | + ::-webkit-scrollbar-track { | |
| 24 | + background: #f1f1f1; | |
| 25 | + border-radius: 3px; | |
| 26 | + } | |
| 27 | + | |
| 28 | + ::-webkit-scrollbar-thumb { | |
| 29 | + background: #c1c1c1; | |
| 30 | + border-radius: 3px; | |
| 31 | + } | |
| 32 | + | |
| 33 | + ::-webkit-scrollbar-thumb:hover { | |
| 34 | + background: #a8a8a8; | |
| 35 | + } | |
| 36 | + | |
| 37 | + * { | |
| 38 | + -ms-overflow-style: -ms-autohiding-scrollbar; | |
| 39 | + scrollbar-width: thin; | |
| 40 | + scrollbar-color: #c1c1c1 #f1f1f1; | |
| 41 | + } | |
| 42 | + | |
| 43 | + .condition-panel { | |
| 44 | + max-height: 0; | |
| 45 | + overflow: hidden; | |
| 46 | + transition: max-height 0.3s ease-out; | |
| 47 | + } | |
| 48 | + | |
| 49 | + .condition-panel.open { | |
| 50 | + max-height: 500px; | |
| 51 | + } | |
| 52 | + | |
| 53 | + .search-tag { | |
| 54 | + display: inline-flex; | |
| 55 | + align-items: center; | |
| 56 | + gap: 4px; | |
| 57 | + padding: 2px 8px; | |
| 58 | + background: #1e6bb8; | |
| 59 | + color: white; | |
| 60 | + border-radius: 4px; | |
| 61 | + font-size: 12px; | |
| 62 | + margin: 2px; | |
| 63 | + } | |
| 64 | + | |
| 65 | + .search-tag .remove-tag { | |
| 66 | + cursor: pointer; | |
| 67 | + font-size: 14px; | |
| 68 | + line-height: 1; | |
| 69 | + } | |
| 70 | + | |
| 71 | + .search-tag .remove-tag:hover { | |
| 72 | + opacity: 0.8; | |
| 73 | + } | |
| 74 | + | |
| 75 | + .line-search-dropdown { | |
| 76 | + position: absolute; | |
| 77 | + top: 100%; | |
| 78 | + left: 0; | |
| 79 | + right: 0; | |
| 80 | + background: white; | |
| 81 | + border: 1px solid #ddd; | |
| 82 | + border-radius: 4px; | |
| 83 | + max-height: 150px; | |
| 84 | + overflow-y: auto; | |
| 85 | + z-index: 100; | |
| 86 | + display: none; | |
| 87 | + } | |
| 88 | + | |
| 89 | + .line-search-dropdown.show { | |
| 90 | + display: block; | |
| 91 | + } | |
| 92 | + | |
| 93 | + .line-option { | |
| 94 | + padding: 8px 12px; | |
| 95 | + cursor: pointer; | |
| 96 | + font-size: 13px; | |
| 97 | + display: flex; | |
| 98 | + align-items: center; | |
| 99 | + } | |
| 100 | + | |
| 101 | + .line-option:hover { | |
| 102 | + background: #f0f7ff; | |
| 103 | + } | |
| 104 | + | |
| 105 | + .location-marker { | |
| 106 | + cursor: crosshair; | |
| 107 | + } | |
| 108 | + </style> | |
| 109 | +</head> | |
| 110 | +<body class="m-0 p-0 box-border w-full h-full overflow-hidden font-['Microsoft_YaHei',Arial,sans-serif]"> | |
| 111 | + <div id="map" class="w-full h-full absolute top-0 left-0 z-10"></div> | |
| 112 | + | |
| 113 | + <div class="absolute top-0 left-0 right-0 h-[50px] bg-[rgba(30,107,184,0.9)] text-white flex items-center justify-center text-[18px] font-bold z-[100] shadow-[0_2px_4px_rgba(0,0,0,0.1)]"> | |
| 114 | + 运能运力一盘棋 | |
| 115 | + </div> | |
| 116 | + | |
| 117 | + <div class="absolute top-[60px] left-[20px] w-[400px] h-[30vh] bg-[rgba(255,255,255,0.95)] rounded-lg shadow-[0_2px_10px_rgba(0,0,0,0.15)] overflow-hidden z-[60]"> | |
| 118 | + <div class="px-[15px] py-3 bg-[rgba(233,245,255,0.95)] border-b border-[#ddd] text-[14px] font-bold text-[#1e6bb8] text-center"> | |
| 119 | + 车辆运营概览 | |
| 120 | + </div> | |
| 121 | + <div class="p-4 grid grid-cols-2 gap-5"> | |
| 122 | + <div class="flex items-start"> | |
| 123 | + <div class="relative w-[60px] h-[60px] flex flex-col items-center"> | |
| 124 | + <div class="w-[50px] h-[50px] bg-[#1e6bb8] rounded-full opacity-80 flex items-center justify-center"> | |
| 125 | + <div class="w-[30px] h-[30px] bg-white rounded-full flex items-center justify-center shadow-[0_2px_4px_rgba(0,0,0,0.1)]" style="background-image: url('data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 24 24%22 fill=%22%231e6bb8%22%3E%3Cpath d=%22M18.92 6.01C18.72 5.42 18.16 5 17.5 5H6.5c-.66 0-1.21.42-1.42 1.01L3 12v8c0 .55.45 1 1 1h1c.55 0 1-.45 1-1v-1h12v1c0 .55.45 1 1 1h1c.55 0 1-.45 1-1v-8l-2.08-5.99zM6.5 16c-.83 0-1.5-.67-1.5-1.5S5.67 13 6.5 13s1.5.67 1.5 1.5S7.33 16 6.5 16zm11 0c-.83 0-1.5-.67-1.5-1.5s.67-1.5 1.5-1.5 1.5.67 1.5 1.5-.67 1.5-1.5 1.5zM5 11l1.5-4.5h11L19 11H5z%22/%3E%3C/svg%3E'); background-size: 60%; background-position: center; background-repeat: no-repeat;"></div> | |
| 126 | + </div> | |
| 127 | + </div> | |
| 128 | + <div class="flex flex-col ml-[15px]"> | |
| 129 | + <div class="text-[12px] text-[#666] mb-1 whitespace-nowrap">总车辆数</div> | |
| 130 | + <div class="text-[18px] font-bold text-[#1e6bb8]">500<span class="text-[12px] text-[#999] font-normal">辆</span></div> | |
| 131 | + </div> | |
| 132 | + </div> | |
| 133 | + <div class="flex items-start"> | |
| 134 | + <div class="relative w-[60px] h-[60px] flex flex-col items-center"> | |
| 135 | + <div class="w-[50px] h-[50px] bg-[#1e6bb8] rounded-full opacity-80 flex items-center justify-center"> | |
| 136 | + <div class="w-[30px] h-[30px] bg-white rounded-full flex items-center justify-center shadow-[0_2px_4px_rgba(0,0,0,0.1)]" style="background-image: url('data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 24 24%22 fill=%22%231e6bb8%22%3E%3Cpath d=%22M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-1 17.93c-3.95-.49-7-3.85-7-7.93 0-.62.08-1.21.21-1.79L9 15v1c0 1.1.9 2 2 2v1.93zm6.9-2.54c-.26-.81-1-1.39-1.9-1.39h-1v-3c0-.55-.45-1-1-1H8v-2h2c.55 0 1-.45 1-1V7h2c1.1 0 2-.9 2-2v-.41c2.93 1.19 5 4.06 5 7.41 0 2.08-.8 3.97-2.1 5.39z%22/%3E%3C/svg%3E'); background-size: 60%; background-position: center; background-repeat: no-repeat;"></div> | |
| 137 | + </div> | |
| 138 | + </div> | |
| 139 | + <div class="flex flex-col ml-[15px]"> | |
| 140 | + <div class="text-[12px] text-[#666] mb-1 whitespace-nowrap">当前运营车辆</div> | |
| 141 | + <div class="text-[18px] font-bold text-[#1e6bb8]">200<span class="text-[12px] text-[#999] font-normal">辆</span></div> | |
| 142 | + </div> | |
| 143 | + </div> | |
| 144 | + <div class="flex items-start"> | |
| 145 | + <div class="relative w-[60px] h-[60px] flex flex-col items-center"> | |
| 146 | + <div class="w-[50px] h-[50px] bg-[#1e6bb8] rounded-full opacity-80 flex items-center justify-center"> | |
| 147 | + <div class="w-[30px] h-[30px] bg-white rounded-full flex items-center justify-center shadow-[0_2px_4px_rgba(0,0,0,0.1)]" style="background-image: url('data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 24 24%22 fill=%22%231e6bb8%22%3E%3Cpath d=%22M19 3h-1V1h-2v2H8V1H6v2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 16H5V8h14v11zM7 10h5v5H7z%22/%3E%3C/svg%3E'); background-size: 60%; background-position: center; background-repeat: no-repeat;"></div> | |
| 148 | + </div> | |
| 149 | + </div> | |
| 150 | + <div class="flex flex-col ml-[15px]"> | |
| 151 | + <div class="text-[12px] text-[#666] mb-1 whitespace-nowrap">今日计划出车</div> | |
| 152 | + <div class="text-[18px] font-bold text-[#1e6bb8]">300<span class="text-[12px] text-[#999] font-normal">辆</span></div> | |
| 153 | + </div> | |
| 154 | + </div> | |
| 155 | + <div class="flex items-start"> | |
| 156 | + <div class="relative w-[60px] h-[60px] flex flex-col items-center"> | |
| 157 | + <div class="w-[50px] h-[50px] bg-[#1e6bb8] rounded-full opacity-80 flex items-center justify-center"> | |
| 158 | + <div class="w-[30px] h-[30px] bg-white rounded-full flex items-center justify-center shadow-[0_2px_4px_rgba(0,0,0,0.1)]" style="background-image: url('data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 24 24%22 fill=%22%231e6bb8%22%3E%3Cpath d=%22M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z%22/%3E%3C/svg%3E'); background-size: 60%; background-position: center; background-repeat: no-repeat;"></div> | |
| 159 | + </div> | |
| 160 | + </div> | |
| 161 | + <div class="flex flex-col ml-[15px]"> | |
| 162 | + <div class="text-[12px] text-[#666] mb-1 whitespace-nowrap">今日已出车</div> | |
| 163 | + <div class="text-[18px] font-bold text-[#1e6bb8]">210<span class="text-[12px] text-[#999] font-normal">辆</span></div> | |
| 164 | + </div> | |
| 165 | + </div> | |
| 166 | + <div class="flex items-start"> | |
| 167 | + <div class="relative w-[60px] h-[60px] flex flex-col items-center"> | |
| 168 | + <div class="w-[50px] h-[50px] bg-[#1e6bb8] rounded-full opacity-80 flex items-center justify-center"> | |
| 169 | + <div class="w-[30px] h-[30px] bg-white rounded-full flex items-center justify-center shadow-[0_2px_4px_rgba(0,0,0,0.1)]" style="background-image: url('data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 24 24%22 fill=%22%231e6bb8%22%3E%3Cpath d=%22M19.79 13.42c-.26-.81-1-1.39-1.9-1.39h-1v-3c0-.55-.45-1-1-1H8v-2h2c.55 0 1-.45 1-1V7h2c1.1 0 2-.9 2-2v-.41c2.93 1.19 5 4.06 5 7.41 0 2.08-.8 3.97-2.1 5.39l-1.43-1.43c.64-.66.99-1.53.99-2.54 0-.55-.1-1.07-.29-1.56zM12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-1 17.93c-3.95-.49-7-3.85-7-7.93 0-.62.08-1.21.21-1.79L9 15v1c0 1.1.9 2 2 2v1.93z%22/%3E%3C/svg%3E'); background-size: 60%; background-position: center; background-repeat: no-repeat;"></div> | |
| 170 | + </div> | |
| 171 | + </div> | |
| 172 | + <div class="flex flex-col ml-[15px]"> | |
| 173 | + <div class="text-[12px] text-[#666] mb-1 whitespace-nowrap">当前维保车辆</div> | |
| 174 | + <div class="text-[18px] font-bold text-[#1e6bb8]">5<span class="text-[12px] text-[#999] font-normal">辆</span></div> | |
| 175 | + </div> | |
| 176 | + </div> | |
| 177 | + <div class="flex items-start"> | |
| 178 | + <div class="relative w-[60px] h-[60px] flex flex-col items-center"> | |
| 179 | + <div class="w-[50px] h-[50px] bg-[#1e6bb8] rounded-full opacity-80 flex items-center justify-center"> | |
| 180 | + <div class="w-[30px] h-[30px] bg-white rounded-full flex items-center justify-center shadow-[0_2px_4px_rgba(0,0,0,0.1)]" style="background-image: url('data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 24 24%22 fill=%22%231e6bb8%22%3E%3Cpath d=%22M19.43 12.98c.04-.3.07-.61.07-.98 0-.37-.03-.74-.07-1.1l2.03-1.58c.18-.14.23-.41.12-.61l-1.92-3.32c-.12-.22-.37-.29-.59-.22l-2.39.96c-.5-.38-1.03-.7-1.62-.94l-.36-2.54c-.04-.24-.24-.41-.48-.41h-3.84c-.24 0-.43.17-.47.41l-.36 2.54c-.59.24-1.13.57-1.62.94l-2.39-.96c-.22-.08-.47 0-.59.22L2.74 8.87c-.12.21-.08.47.12.61l2.03 1.58c-.04.36-.07.73-.07 1.1 0 .37.03.74.07 1.1l-2.03 1.58c-.18.14-.23.41-.12.61l1.92 3.32c.12.22.37.29.59.22l2.39-.96c.5.38 1.03.7 1.62.94l.36 2.54c.05.24.24.41.48.41h3.84c.24 0 .44-.17.47-.41l.36-2.54c.59-.24 1.13-.56 1.62-.94l2.39.96c.22.08.47 0 .59-.22l1.92-3.32c.12-.22.07-.47-.12-.61l-2.01-1.58zM12 15.6c-1.98 0-3.6-1.62-3.6-3.6s1.62-3.6 3.6-3.6 3.6 1.62 3.6 3.6-1.62 3.6-3.6 3.6z%22/%3E%3C/svg%3E'); background-size: 60%; background-position: center; background-repeat: no-repeat;"></div> | |
| 181 | + </div> | |
| 182 | + </div> | |
| 183 | + <div class="flex flex-col ml-[15px]"> | |
| 184 | + <div class="text-[12px] text-[#666] mb-1 whitespace-nowrap">当前空驶率</div> | |
| 185 | + <div class="text-[18px] font-bold text-[#1e6bb8]">15<span class="text-[12px] text-[#999] font-normal">%</span></div> | |
| 186 | + </div> | |
| 187 | + </div> | |
| 188 | + </div> | |
| 189 | + </div> | |
| 190 | + | |
| 191 | + <div class="absolute top-[calc(60px+30vh+20px)] left-[20px] w-[400px] h-[30vh] bg-[rgba(255,255,255,0.95)] rounded-lg shadow-[0_2px_10px_rgba(0,0,0,0.15)] overflow-hidden z-[60]"> | |
| 192 | + <div class="px-[15px] py-3 bg-[rgba(233,245,255,0.95)] border-b border-[#ddd] text-[14px] font-bold text-[#1e6bb8] text-center"> | |
| 193 | + 人员运营概览 | |
| 194 | + </div> | |
| 195 | + <div class="p-4 grid grid-cols-2 gap-5"> | |
| 196 | + <div class="flex items-start"> | |
| 197 | + <div class="relative w-[60px] h-[60px] flex flex-col items-center"> | |
| 198 | + <div class="w-[50px] h-[50px] bg-[#1e6bb8] rounded-full opacity-80 flex items-center justify-center"> | |
| 199 | + <div class="w-[30px] h-[30px] bg-white rounded-full flex items-center justify-center shadow-[0_2px_4px_rgba(0,0,0,0.1)]" style="background-image: url('data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 24 24%22 fill=%22%231e6bb8%22%3E%3Cpath d=%22M16 11c1.66 0 2.99-1.34 2.99-3S17.66 5 16 5c-1.66 0-3 1.34-3 3s1.34 3 3 3zm-8 0c1.66 0 2.99-1.34 2.99-3S9.66 5 8 5C6.34 5 5 6.34 5 8s1.34 3 3 3zm0 2c-2.33 0-7 1.17-7 3.5V19h14v-2.5c0-2.33-4.67-3.5-7-3.5zm8 0c-.29 0-.62.02-.97.05 1.16.84 1.97 1.97 1.97 3.45V19h6v-2.5c0-2.33-4.67-3.5-7-3.5z%22/%3E%3C/svg%3E'); background-size: 60%; background-position: center; background-repeat: no-repeat;"></div> | |
| 200 | + </div> | |
| 201 | + </div> | |
| 202 | + <div class="flex flex-col ml-[15px]"> | |
| 203 | + <div class="text-[12px] text-[#666] mb-1 whitespace-nowrap">总人员数</div> | |
| 204 | + <div class="text-[18px] font-bold text-[#1e6bb8]">600<span class="text-[12px] text-[#999] font-normal">人</span></div> | |
| 205 | + </div> | |
| 206 | + </div> | |
| 207 | + <div class="flex items-start"> | |
| 208 | + <div class="relative w-[60px] h-[60px] flex flex-col items-center"> | |
| 209 | + <div class="w-[50px] h-[50px] bg-[#1e6bb8] rounded-full opacity-80 flex items-center justify-center"> | |
| 210 | + <div class="w-[30px] h-[30px] bg-white rounded-full flex items-center justify-center shadow-[0_2px_4px_rgba(0,0,0,0.1)]" style="background-image: url('data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 24 24%22 fill=%22%231e6bb8%22%3E%3Cpath d=%22M12 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm0 2c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4z%22/%3E%3C/svg%3E'); background-size: 60%; background-position: center; background-repeat: no-repeat;"></div> | |
| 211 | + </div> | |
| 212 | + </div> | |
| 213 | + <div class="flex flex-col ml-[15px]"> | |
| 214 | + <div class="text-[12px] text-[#666] mb-1 whitespace-nowrap">当前运营人员</div> | |
| 215 | + <div class="text-[18px] font-bold text-[#1e6bb8]">200<span class="text-[12px] text-[#999] font-normal">人</span></div> | |
| 216 | + </div> | |
| 217 | + </div> | |
| 218 | + <div class="flex items-start"> | |
| 219 | + <div class="relative w-[60px] h-[60px] flex flex-col items-center"> | |
| 220 | + <div class="w-[50px] h-[50px] bg-[#1e6bb8] rounded-full opacity-80 flex items-center justify-center"> | |
| 221 | + <div class="w-[30px] h-[30px] bg-white rounded-full flex items-center justify-center shadow-[0_2px_4px_rgba(0,0,0,0.1)]" style="background-image: url('data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 24 24%22 fill=%22%231e6bb8%22%3E%3Cpath d=%22M19 3h-1V1h-2v2H8V1H6v2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 16H5V8h14v11zM7 10h5v5H7z%22/%3E%3C/svg%3E'); background-size: 60%; background-position: center; background-repeat: no-repeat;"></div> | |
| 222 | + </div> | |
| 223 | + </div> | |
| 224 | + <div class="flex flex-col ml-[15px]"> | |
| 225 | + <div class="text-[12px] text-[#666] mb-1 whitespace-nowrap">今日计划出人</div> | |
| 226 | + <div class="text-[18px] font-bold text-[#1e6bb8]">350<span class="text-[12px] text-[#999] font-normal">人</span></div> | |
| 227 | + </div> | |
| 228 | + </div> | |
| 229 | + <div class="flex items-start"> | |
| 230 | + <div class="relative w-[60px] h-[60px] flex flex-col items-center"> | |
| 231 | + <div class="w-[50px] h-[50px] bg-[#1e6bb8] rounded-full opacity-80 flex items-center justify-center"> | |
| 232 | + <div class="w-[30px] h-[30px] bg-white rounded-full flex items-center justify-center shadow-[0_2px_4px_rgba(0,0,0,0.1)]" style="background-image: url('data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 24 24%22 fill=%22%231e6bb8%22%3E%3Cpath d=%22M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z%22/%3E%3C/svg%3E'); background-size: 60%; background-position: center; background-repeat: no-repeat;"></div> | |
| 233 | + </div> | |
| 234 | + </div> | |
| 235 | + <div class="flex flex-col ml-[15px]"> | |
| 236 | + <div class="text-[12px] text-[#666] mb-1 whitespace-nowrap">今日已出人</div> | |
| 237 | + <div class="text-[18px] font-bold text-[#1e6bb8]">230<span class="text-[12px] text-[#999] font-normal">人</span></div> | |
| 238 | + </div> | |
| 239 | + </div> | |
| 240 | + <div class="flex items-start"> | |
| 241 | + <div class="relative w-[60px] h-[60px] flex flex-col items-center"> | |
| 242 | + <div class="w-[50px] h-[50px] bg-[#1e6bb8] rounded-full opacity-80 flex items-center justify-center"> | |
| 243 | + <div class="w-[30px] h-[30px] bg-white rounded-full flex items-center justify-center shadow-[0_2px_4px_rgba(0,0,0,0.1)]" style="background-image: url('data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 24 24%22 fill=%22%231e6bb8%22%3E%3Cpath d=%22M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8zm.5-13H11v6l5.25 3.15.75-1.23-4.5-2.67z%22/%3E%3C/svg%3E'); background-size: 60%; background-position: center; background-repeat: no-repeat;"></div> | |
| 244 | + </div> | |
| 245 | + </div> | |
| 246 | + <div class="flex flex-col ml-[15px]"> | |
| 247 | + <div class="text-[12px] text-[#666] mb-1 whitespace-nowrap">当前病休人员</div> | |
| 248 | + <div class="text-[18px] font-bold text-[#1e6bb8]">1<span class="text-[12px] text-[#999] font-normal">人</span></div> | |
| 249 | + </div> | |
| 250 | + </div> | |
| 251 | + <div class="flex items-start"> | |
| 252 | + <div class="relative w-[60px] h-[60px] flex flex-col items-center"> | |
| 253 | + <div class="w-[50px] h-[50px] bg-[#1e6bb8] rounded-full opacity-80 flex items-center justify-center"> | |
| 254 | + <div class="w-[30px] h-[30px] bg-white rounded-full flex items-center justify-center shadow-[0_2px_4px_rgba(0,0,0,0.1)]" style="background-image: url('data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 24 24%22 fill=%22%231e6bb8%22%3E%3Cpath d=%22M9 16.2L4.8 12l-1.4 1.4L9 19 21 7l-1.4-1.4L9 16.2z%22/%3E%3C/svg%3E'); background-size: 60%; background-position: center; background-repeat: no-repeat;"></div> | |
| 255 | + </div> | |
| 256 | + </div> | |
| 257 | + <div class="flex flex-col ml-[15px]"> | |
| 258 | + <div class="text-[12px] text-[#666] mb-1 whitespace-nowrap">当日已完成运营</div> | |
| 259 | + <div class="text-[18px] font-bold text-[#1e6bb8]">30<span class="text-[12px] text-[#999] font-normal">人</span></div> | |
| 260 | + </div> | |
| 261 | + </div> | |
| 262 | + </div> | |
| 263 | + </div> | |
| 264 | + | |
| 265 | + <div id="search-panel-container" class="absolute top-[60px] left-[calc(400px+40px)] right-[20px] z-[60]"> | |
| 266 | + <div id="search-condition-panel" class="bg-[rgba(255,255,255,0.95)] rounded-lg shadow-[0_2px_10px_rgba(0,0,0,0.15)] p-4 mb-4"> | |
| 267 | + <div class="flex gap-2 mb-4"> | |
| 268 | + <div class="flex-1 relative"> | |
| 269 | + <div id="search-input" class="min-h-[40px] px-3 py-2 border border-[#ddd] rounded text-[13px] focus:outline-none focus:border-[#1e6bb8] cursor-text flex flex-wrap items-center gap-1"> | |
| 270 | + <span id="search-tags"></span> | |
| 271 | + <input type="text" id="search-text" class="flex-1 min-w-[100px] outline-none border-none text-[13px]" placeholder="点击选择搜索条件..."> | |
| 272 | + </div> | |
| 273 | + </div> | |
| 274 | + <button id="btn-search" class="bg-[#1e6bb8] text-white px-6 py-2 rounded text-[13px] font-medium hover:bg-[#155a96] transition-colors"> | |
| 275 | + 搜索 | |
| 276 | + </button> | |
| 277 | + </div> | |
| 278 | + <div id="toggle-arrow" class="flex justify-center items-center h-6 cursor-pointer mb-2"> | |
| 279 | + <svg id="arrow-icon" class="w-5 h-5 text-gray-500 transition-transform duration-300" fill="none" stroke="currentColor" viewBox="0 0 24 24"> | |
| 280 | + <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"></path> | |
| 281 | + </svg> | |
| 282 | + </div> | |
| 283 | + <div id="condition-panel" class="condition-panel"> | |
| 284 | + <div class="grid grid-cols-2 gap-4 mb-4"> | |
| 285 | + <div> | |
| 286 | + <label class="block text-[12px] text-[#666] mb-1">任务类型</label> | |
| 287 | + <div class="flex gap-2"> | |
| 288 | + <label class="flex items-center cursor-pointer"> | |
| 289 | + <input type="radio" name="dispatchType" value="urgent" class="mr-1" data-type="dispatchType" data-label="紧急" data-value="urgent"> | |
| 290 | + <span class="text-[13px]">紧急</span> | |
| 291 | + </label> | |
| 292 | + <label class="flex items-center cursor-pointer"> | |
| 293 | + <input type="radio" name="dispatchType" value="normal" class="mr-1" data-type="dispatchType" data-label="普通" data-value="normal"> | |
| 294 | + <span class="text-[13px]">普通</span> | |
| 295 | + </label> | |
| 296 | + </div> | |
| 297 | + </div> | |
| 298 | + <div> | |
| 299 | + <label class="block text-[12px] text-[#666] mb-1">线路选择</label> | |
| 300 | + <div class="relative"> | |
| 301 | + <div id="lineSelectContainer" class="min-h-[40px] px-3 py-2 border border-[#ddd] rounded text-[13px] focus:outline-none focus:border-[#1e6bb8] cursor-pointer flex flex-wrap items-center gap-1"> | |
| 302 | + <span id="lineSelectedTags"></span> | |
| 303 | + <input type="text" id="lineSearchInput" class="flex-1 min-w-[100px] outline-none border-none text-[13px]" placeholder="搜索线路..."> | |
| 304 | + </div> | |
| 305 | + <div id="lineDropdown" class="line-search-dropdown"> | |
| 306 | + <div class="line-option" data-value="803111" data-label="线路1"> | |
| 307 | + <input type="checkbox" class="line-checkbox mr-2" data-value="803111" data-label="线路1"> | |
| 308 | + <span>803111 - 线路1</span> | |
| 309 | + </div> | |
| 310 | + <div class="line-option" data-value="803112" data-label="线路2"> | |
| 311 | + <input type="checkbox" class="line-checkbox mr-2" data-value="803112" data-label="线路2"> | |
| 312 | + <span>803112 - 线路2</span> | |
| 313 | + </div> | |
| 314 | + <div class="line-option" data-value="803113" data-label="线路3"> | |
| 315 | + <input type="checkbox" class="line-checkbox mr-2" data-value="803113" data-label="线路3"> | |
| 316 | + <span>803113 - 线路3</span> | |
| 317 | + </div> | |
| 318 | + <div class="line-option" data-value="803114" data-label="线路4"> | |
| 319 | + <input type="checkbox" class="line-checkbox mr-2" data-value="803114" data-label="线路4"> | |
| 320 | + <span>803114 - 线路4</span> | |
| 321 | + </div> | |
| 322 | + <div class="line-option" data-value="803115" data-label="线路5"> | |
| 323 | + <input type="checkbox" class="line-checkbox mr-2" data-value="803115" data-label="线路5"> | |
| 324 | + <span>803115 - 线路5</span> | |
| 325 | + </div> | |
| 326 | + </div> | |
| 327 | + </div> | |
| 328 | + </div> | |
| 329 | + </div> | |
| 330 | + | |
| 331 | + <div class="grid grid-cols-2 gap-4 mb-4"> | |
| 332 | + <div> | |
| 333 | + <label class="block text-[12px] text-[#666] mb-1">停运时长</label> | |
| 334 | + <select id="stopDuration" class="w-full px-3 py-2 border border-[#ddd] rounded text-[13px] focus:outline-none focus:border-[#1e6bb8]" data-type="stopDuration"> | |
| 335 | + <option value="">请选择</option> | |
| 336 | + <option value="30" data-label="30分钟">30分钟</option> | |
| 337 | + <option value="60" data-label="1小时">1小时</option> | |
| 338 | + <option value="120" data-label="2小时">2小时</option> | |
| 339 | + </select> | |
| 340 | + </div> | |
| 341 | + <div> | |
| 342 | + <label class="block text-[12px] text-[#666] mb-1">任务位置 <span id="locationHint" class="text-[#999] text-[11px]">(右键地图设置)</span></label> | |
| 343 | + <div class="flex gap-2"> | |
| 344 | + <input type="text" id="taskLocation" class="flex-1 px-3 py-2 border border-[#ddd] rounded text-[13px] focus:outline-none focus:border-[#1e6bb8]" readonly placeholder="未设置"> | |
| 345 | + <button id="clearLocation" class="px-3 py-2 bg-gray-200 text-gray-700 rounded text-[13px] hover:bg-gray-300 transition-colors"> | |
| 346 | + 清除 | |
| 347 | + </button> | |
| 348 | + </div> | |
| 349 | + </div> | |
| 350 | + </div> | |
| 351 | + | |
| 352 | + <div class="grid grid-cols-2 gap-4 mb-4"> | |
| 353 | + <div> | |
| 354 | + <label class="block text-[12px] text-[#666] mb-1">开始时间</label> | |
| 355 | + <input type="datetime-local" id="startTime" class="w-full px-3 py-2 border border-[#ddd] rounded text-[13px] focus:outline-none focus:border-[#1e6bb8]" data-type="startTime"> | |
| 356 | + </div> | |
| 357 | + <div> | |
| 358 | + <label class="block text-[12px] text-[#666] mb-1">结束时间</label> | |
| 359 | + <input type="datetime-local" id="endTime" class="w-full px-3 py-2 border border-[#ddd] rounded text-[13px] focus:outline-none focus:border-[#1e6bb8]" data-type="endTime"> | |
| 360 | + </div> | |
| 361 | + </div> | |
| 362 | + </div> | |
| 363 | + </div> | |
| 364 | + | |
| 365 | + <div id="results-panel" class="bg-[rgba(255,255,255,0.95)] rounded-lg shadow-[0_2px_10px_rgba(0,0,0,0.15)] p-4 hidden"> | |
| 366 | + <div class="flex justify-between items-center mb-3"> | |
| 367 | + <div class="text-[14px] font-bold text-[#1e6bb8]">搜索结果</div> | |
| 368 | + <button id="close-results" class="text-gray-500 hover:text-gray-700 p-1"> | |
| 369 | + <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"> | |
| 370 | + <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path> | |
| 371 | + </svg> | |
| 372 | + </button> | |
| 373 | + </div> | |
| 374 | + <div class="max-h-[300px] overflow-y-auto"> | |
| 375 | + <table class="w-full text-[12px]"> | |
| 376 | + <thead class="bg-[#f5f8fc] sticky top-0"> | |
| 377 | + <tr> | |
| 378 | + <th class="px-2 py-2 text-left font-medium text-[#666]">序号</th> | |
| 379 | + <th class="px-2 py-2 text-left font-medium text-[#666]">车辆编码</th> | |
| 380 | + <th class="px-2 py-2 text-left font-medium text-[#666]">设备编码</th> | |
| 381 | + <th class="px-2 py-2 text-left font-medium text-[#666]">线路</th> | |
| 382 | + <th class="px-2 py-2 text-left font-medium text-[#666]">上下行</th> | |
| 383 | + </tr> | |
| 384 | + </thead> | |
| 385 | + <tbody id="results-tbody"> | |
| 386 | + </tbody> | |
| 387 | + </table> | |
| 388 | + </div> | |
| 389 | + </div> | |
| 390 | + </div> | |
| 391 | + | |
| 392 | + <script> | |
| 393 | + document.addEventListener('DOMContentLoaded', function() { | |
| 394 | + var map = new BMap.Map("map"); | |
| 395 | + var point = new BMap.Point(121.0, 31.2); | |
| 396 | + map.centerAndZoom(point, 8); | |
| 397 | + map.enableScrollWheelZoom(true); | |
| 398 | + | |
| 399 | + var searchConditions = {}; | |
| 400 | + var locationMarker = null; | |
| 401 | + var locationCircle = null; | |
| 402 | + var taskLocation = null; | |
| 403 | + var selectedLines = {}; | |
| 404 | + | |
| 405 | + var vehicleLocations = [ | |
| 406 | + {lng: 120.7, lat: 31.1, name: "W105-01", status: "正常"}, | |
| 407 | + {lng: 120.8, lat: 31.3, name: "W105-02", status: "正常"}, | |
| 408 | + {lng: 120.9, lat: 31.2, name: "W107-01", status: "正常"}, | |
| 409 | + {lng: 121.1, lat: 31.4, name: "W107-02", status: "正常"}, | |
| 410 | + {lng: 121.2, lat: 31.1, name: "W108-01", status: "正常"}, | |
| 411 | + {lng: 121.0, lat: 31.3, name: "W108-02", status: "正常"} | |
| 412 | + ]; | |
| 413 | + | |
| 414 | + vehicleLocations.forEach(function(vehicle) { | |
| 415 | + var point = new BMap.Point(vehicle.lng, vehicle.lat); | |
| 416 | + var fillColor = vehicle.status === "正常" ? "%231e6bb8" : "%23e67e22"; | |
| 417 | + var icon = new BMap.Icon("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'%3E%3Ccircle cx='16' cy='16' r='14' fill='" + fillColor + "' stroke='white' stroke-width='2'/%3E%3Ccircle cx='16' cy='16' r='6' fill='white' fill-opacity='0.3'/%3E%3C/svg%3E", new BMap.Size(32, 32)); | |
| 418 | + var marker = new BMap.Marker(point, {icon: icon}); | |
| 419 | + var infoWindow = new BMap.InfoWindow("<div style='padding:10px;'><strong>车辆编号:</strong> " + vehicle.name + "<br/><strong>状态:</strong> " + vehicle.status + "</div>"); | |
| 420 | + marker.addEventListener("click", function() { | |
| 421 | + this.openInfoWindow(infoWindow); | |
| 422 | + }); | |
| 423 | + map.addOverlay(marker); | |
| 424 | + }); | |
| 425 | + | |
| 426 | + /** | |
| 427 | + * 在地图上绘制路线 | |
| 428 | + * @param {Array} points - 地图点数组 | |
| 429 | + * @param {string} color - 路线颜色 | |
| 430 | + */ | |
| 431 | + function drawRoute(points, color) { | |
| 432 | + var polyline = new BMap.Polyline(points, { | |
| 433 | + strokeColor: color, | |
| 434 | + strokeWeight: 8, | |
| 435 | + strokeOpacity: 0.7, | |
| 436 | + strokeStyle: "solid" | |
| 437 | + }); | |
| 438 | + map.addOverlay(polyline); | |
| 439 | + } | |
| 440 | + | |
| 441 | + var routes = [ | |
| 442 | + [ | |
| 443 | + new BMap.Point(120.5, 31.1), | |
| 444 | + new BMap.Point(120.7, 31.1), | |
| 445 | + new BMap.Point(120.9, 31.1), | |
| 446 | + new BMap.Point(121.1, 31.1), | |
| 447 | + new BMap.Point(121.3, 31.1), | |
| 448 | + new BMap.Point(121.5, 31.1) | |
| 449 | + ] | |
| 450 | + ]; | |
| 451 | + | |
| 452 | + routes.forEach(function(route) { | |
| 453 | + drawRoute(route, "#1e6bb8"); | |
| 454 | + }); | |
| 455 | + | |
| 456 | + map.addControl(new BMap.NavigationControl({ | |
| 457 | + type: BMAP_NAVIGATION_CONTROL_ZOOM, | |
| 458 | + anchor: BMAP_ANCHOR_TOP_LEFT, | |
| 459 | + offset: new BMap.Size(10, 70) | |
| 460 | + })); | |
| 461 | + | |
| 462 | + map.addControl(new BMap.ScaleControl({ | |
| 463 | + anchor: BMAP_ANCHOR_BOTTOM_LEFT | |
| 464 | + })); | |
| 465 | + | |
| 466 | + var searchInput = document.getElementById('search-input'); | |
| 467 | + var searchText = document.getElementById('search-text'); | |
| 468 | + var conditionPanel = document.getElementById('condition-panel'); | |
| 469 | + var searchTags = document.getElementById('search-tags'); | |
| 470 | + var toggleArrow = document.getElementById('toggle-arrow'); | |
| 471 | + var arrowIcon = document.getElementById('arrow-icon'); | |
| 472 | + | |
| 473 | + /** | |
| 474 | + * 切换条件面板展开/收拢状态 | |
| 475 | + */ | |
| 476 | + function toggleConditionPanel() { | |
| 477 | + if (conditionPanel.classList.contains('open')) { | |
| 478 | + conditionPanel.classList.remove('open'); | |
| 479 | + arrowIcon.style.transform = 'rotate(0deg)'; | |
| 480 | + } else { | |
| 481 | + conditionPanel.classList.add('open'); | |
| 482 | + arrowIcon.style.transform = 'rotate(180deg)'; | |
| 483 | + } | |
| 484 | + } | |
| 485 | + | |
| 486 | + toggleArrow.addEventListener('click', function(e) { | |
| 487 | + e.stopPropagation(); | |
| 488 | + toggleConditionPanel(); | |
| 489 | + }); | |
| 490 | + | |
| 491 | + searchInput.addEventListener('click', function(e) { | |
| 492 | + if (!conditionPanel.classList.contains('open')) { | |
| 493 | + toggleConditionPanel(); | |
| 494 | + } | |
| 495 | + searchText.focus(); | |
| 496 | + }); | |
| 497 | + | |
| 498 | + document.querySelectorAll('input[type="radio"][data-type]').forEach(function(radio) { | |
| 499 | + radio.addEventListener('change', function() { | |
| 500 | + if (this.checked) { | |
| 501 | + var type = this.dataset.type; | |
| 502 | + var label = this.dataset.label; | |
| 503 | + var value = this.dataset.value; | |
| 504 | + addCondition(type, label, value); | |
| 505 | + } | |
| 506 | + }); | |
| 507 | + }); | |
| 508 | + | |
| 509 | + document.getElementById('stopDuration').addEventListener('change', function() { | |
| 510 | + var selectedOption = this.options[this.selectedIndex]; | |
| 511 | + if (selectedOption.value) { | |
| 512 | + addCondition('stopDuration', selectedOption.dataset.label, selectedOption.value); | |
| 513 | + } else { | |
| 514 | + removeCondition('stopDuration'); | |
| 515 | + } | |
| 516 | + }); | |
| 517 | + | |
| 518 | + document.getElementById('startTime').addEventListener('change', function() { | |
| 519 | + if (this.value) { | |
| 520 | + addCondition('startTime', '开始:' + this.value, this.value); | |
| 521 | + } else { | |
| 522 | + removeCondition('startTime'); | |
| 523 | + } | |
| 524 | + }); | |
| 525 | + | |
| 526 | + document.getElementById('endTime').addEventListener('change', function() { | |
| 527 | + if (this.value) { | |
| 528 | + addCondition('endTime', '结束:' + this.value, this.value); | |
| 529 | + } else { | |
| 530 | + removeCondition('endTime'); | |
| 531 | + } | |
| 532 | + }); | |
| 533 | + | |
| 534 | + var lineSelectContainer = document.getElementById('lineSelectContainer'); | |
| 535 | + var lineSearchInput = document.getElementById('lineSearchInput'); | |
| 536 | + var lineDropdown = document.getElementById('lineDropdown'); | |
| 537 | + var lineSelectedTags = document.getElementById('lineSelectedTags'); | |
| 538 | + | |
| 539 | + /** | |
| 540 | + * 渲染已选择的线路标签 | |
| 541 | + */ | |
| 542 | + function renderLineTags() { | |
| 543 | + lineSelectedTags.innerHTML = ''; | |
| 544 | + for (var value in selectedLines) { | |
| 545 | + var tag = document.createElement('span'); | |
| 546 | + tag.className = 'search-tag'; | |
| 547 | + tag.innerHTML = selectedLines[value] + '<span class="remove-tag" data-value="' + value + '">×</span>'; | |
| 548 | + lineSelectedTags.appendChild(tag); | |
| 549 | + } | |
| 550 | + | |
| 551 | + document.querySelectorAll('#lineSelectedTags .remove-tag').forEach(function(btn) { | |
| 552 | + btn.addEventListener('click', function(e) { | |
| 553 | + e.stopPropagation(); | |
| 554 | + var value = this.dataset.value; | |
| 555 | + removeLine(value); | |
| 556 | + }); | |
| 557 | + }); | |
| 558 | + | |
| 559 | + updateLineCondition(); | |
| 560 | + } | |
| 561 | + | |
| 562 | + /** | |
| 563 | + * 添加线路选择 | |
| 564 | + * @param {string} value - 线路值 | |
| 565 | + * @param {string} label - 线路标签 | |
| 566 | + */ | |
| 567 | + function addLine(value, label) { | |
| 568 | + selectedLines[value] = label; | |
| 569 | + renderLineTags(); | |
| 570 | + updateLineCheckboxes(); | |
| 571 | + } | |
| 572 | + | |
| 573 | + /** | |
| 574 | + * 移除线路选择 | |
| 575 | + * @param {string} value - 线路值 | |
| 576 | + */ | |
| 577 | + function removeLine(value) { | |
| 578 | + delete selectedLines[value]; | |
| 579 | + renderLineTags(); | |
| 580 | + updateLineCheckboxes(); | |
| 581 | + } | |
| 582 | + | |
| 583 | + /** | |
| 584 | + * 更新搜索条件中的线路 | |
| 585 | + */ | |
| 586 | + function updateLineCondition() { | |
| 587 | + var values = Object.keys(selectedLines); | |
| 588 | + var labels = Object.values(selectedLines); | |
| 589 | + if (values.length > 0) { | |
| 590 | + searchConditions['line'] = { label: labels.join(','), value: values.join(',') }; | |
| 591 | + } else { | |
| 592 | + delete searchConditions['line']; | |
| 593 | + } | |
| 594 | + renderTags(); | |
| 595 | + } | |
| 596 | + | |
| 597 | + /** | |
| 598 | + * 更新下拉框中复选框的选中状态 | |
| 599 | + */ | |
| 600 | + function updateLineCheckboxes() { | |
| 601 | + document.querySelectorAll('.line-checkbox').forEach(function(checkbox) { | |
| 602 | + checkbox.checked = !!selectedLines[checkbox.dataset.value]; | |
| 603 | + }); | |
| 604 | + } | |
| 605 | + | |
| 606 | + lineSelectContainer.addEventListener('click', function(e) { | |
| 607 | + if (e.target.classList.contains('remove-tag')) { | |
| 608 | + return; | |
| 609 | + } | |
| 610 | + lineDropdown.classList.add('show'); | |
| 611 | + lineSearchInput.focus(); | |
| 612 | + }); | |
| 613 | + | |
| 614 | + lineSearchInput.addEventListener('focus', function() { | |
| 615 | + lineDropdown.classList.add('show'); | |
| 616 | + }); | |
| 617 | + | |
| 618 | + lineSearchInput.addEventListener('input', function() { | |
| 619 | + var filter = this.value.toLowerCase(); | |
| 620 | + var options = lineDropdown.querySelectorAll('.line-option'); | |
| 621 | + options.forEach(function(option) { | |
| 622 | + var text = option.textContent.toLowerCase(); | |
| 623 | + option.style.display = text.indexOf(filter) > -1 ? 'flex' : 'none'; | |
| 624 | + }); | |
| 625 | + }); | |
| 626 | + | |
| 627 | + document.querySelectorAll('.line-checkbox').forEach(function(checkbox) { | |
| 628 | + checkbox.addEventListener('change', function(e) { | |
| 629 | + e.stopPropagation(); | |
| 630 | + var value = this.dataset.value; | |
| 631 | + var label = this.dataset.label; | |
| 632 | + if (this.checked) { | |
| 633 | + addLine(value, label); | |
| 634 | + } else { | |
| 635 | + removeLine(value); | |
| 636 | + } | |
| 637 | + }); | |
| 638 | + }); | |
| 639 | + | |
| 640 | + document.querySelectorAll('.line-option').forEach(function(option) { | |
| 641 | + option.addEventListener('click', function(e) { | |
| 642 | + if (e.target.type === 'checkbox') { | |
| 643 | + return; | |
| 644 | + } | |
| 645 | + var checkbox = this.querySelector('.line-checkbox'); | |
| 646 | + checkbox.checked = !checkbox.checked; | |
| 647 | + var value = checkbox.dataset.value; | |
| 648 | + var label = checkbox.dataset.label; | |
| 649 | + if (checkbox.checked) { | |
| 650 | + addLine(value, label); | |
| 651 | + } else { | |
| 652 | + removeLine(value); | |
| 653 | + } | |
| 654 | + }); | |
| 655 | + }); | |
| 656 | + | |
| 657 | + document.addEventListener('click', function(e) { | |
| 658 | + if (!lineSelectContainer.contains(e.target) && !lineDropdown.contains(e.target)) { | |
| 659 | + lineDropdown.classList.remove('show'); | |
| 660 | + } | |
| 661 | + }); | |
| 662 | + | |
| 663 | + map.addEventListener('rightclick', function(e) { | |
| 664 | + taskLocation = e.point; | |
| 665 | + var lng = e.point.lng.toFixed(4); | |
| 666 | + var lat = e.point.lat.toFixed(4); | |
| 667 | + | |
| 668 | + document.getElementById('taskLocation').value = lng + ', ' + lat; | |
| 669 | + addCondition('location', '位置:' + lng + ',' + lat, lng + ',' + lat); | |
| 670 | + | |
| 671 | + if (locationMarker) { | |
| 672 | + map.removeOverlay(locationMarker); | |
| 673 | + } | |
| 674 | + if (locationCircle) { | |
| 675 | + map.removeOverlay(locationCircle); | |
| 676 | + } | |
| 677 | + | |
| 678 | + var locationIcon = new BMap.Icon("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 48 48'%3E%3Cpath d='M24 4C15.163 4 8 11.163 8 20c0 5.219 3.438 11.641 8.203 17.484a31.841 31.841 0 0 0 7.797 9.672 31.807 31.807 0 0 0 7.797-9.672C36.562 31.641 40 25.219 40 20c0-8.837-7.163-16-16-16zm0 24a8 8 0 1 1 0-16 8 8 0 0 1 0 16z' fill='%231e6bb8'/%3E%3Ccircle cx='24' cy='20' r='5' fill='white'/%3E%3C/svg%3E", new BMap.Size(48, 48)); | |
| 679 | + locationIcon.setAnchor(new BMap.Size(24, 48)); | |
| 680 | + locationMarker = new BMap.Marker(e.point, {icon: locationIcon}); | |
| 681 | + map.addOverlay(locationMarker); | |
| 682 | + }); | |
| 683 | + | |
| 684 | + document.getElementById('clearLocation').addEventListener('click', function() { | |
| 685 | + document.getElementById('taskLocation').value = ''; | |
| 686 | + removeCondition('location'); | |
| 687 | + if (locationMarker) { | |
| 688 | + map.removeOverlay(locationMarker); | |
| 689 | + locationMarker = null; | |
| 690 | + } | |
| 691 | + if (locationCircle) { | |
| 692 | + map.removeOverlay(locationCircle); | |
| 693 | + locationCircle = null; | |
| 694 | + } | |
| 695 | + taskLocation = null; | |
| 696 | + }); | |
| 697 | + | |
| 698 | + /** | |
| 699 | + * 添加搜索条件 | |
| 700 | + * @param {string} type - 条件类型 | |
| 701 | + * @param {string} label - 条件显示标签 | |
| 702 | + * @param {*} value - 条件值 | |
| 703 | + */ | |
| 704 | + function addCondition(type, label, value) { | |
| 705 | + removeCondition(type); | |
| 706 | + searchConditions[type] = { label: label, value: value }; | |
| 707 | + renderTags(); | |
| 708 | + } | |
| 709 | + | |
| 710 | + /** | |
| 711 | + * 移除搜索条件 | |
| 712 | + * @param {string} type - 要移除的条件类型 | |
| 713 | + */ | |
| 714 | + function removeCondition(type) { | |
| 715 | + delete searchConditions[type]; | |
| 716 | + renderTags(); | |
| 717 | + } | |
| 718 | + | |
| 719 | + /** | |
| 720 | + * 渲染搜索标签 | |
| 721 | + */ | |
| 722 | + function renderTags() { | |
| 723 | + searchTags.innerHTML = ''; | |
| 724 | + for (var type in searchConditions) { | |
| 725 | + var tag = document.createElement('span'); | |
| 726 | + tag.className = 'search-tag'; | |
| 727 | + tag.innerHTML = searchConditions[type].label + '<span class="remove-tag" data-type="' + type + '">×</span>'; | |
| 728 | + searchTags.appendChild(tag); | |
| 729 | + } | |
| 730 | + | |
| 731 | + document.querySelectorAll('.remove-tag').forEach(function(btn) { | |
| 732 | + btn.addEventListener('click', function(e) { | |
| 733 | + e.stopPropagation(); | |
| 734 | + var type = this.dataset.type; | |
| 735 | + removeCondition(type); | |
| 736 | + | |
| 737 | + if (type === 'dispatchType') { | |
| 738 | + document.querySelectorAll('input[name="dispatchType"]').forEach(function(r) { r.checked = false; }); | |
| 739 | + } else if (type === 'stopDuration') { | |
| 740 | + document.getElementById('stopDuration').value = ''; | |
| 741 | + } else if (type === 'startTime') { | |
| 742 | + document.getElementById('startTime').value = ''; | |
| 743 | + } else if (type === 'endTime') { | |
| 744 | + document.getElementById('endTime').value = ''; | |
| 745 | + } else if (type === 'location') { | |
| 746 | + document.getElementById('taskLocation').value = ''; | |
| 747 | + if (locationMarker) { | |
| 748 | + map.removeOverlay(locationMarker); | |
| 749 | + locationMarker = null; | |
| 750 | + } | |
| 751 | + if (locationCircle) { | |
| 752 | + map.removeOverlay(locationCircle); | |
| 753 | + locationCircle = null; | |
| 754 | + } | |
| 755 | + taskLocation = null; | |
| 756 | + } else if (type === 'line') { | |
| 757 | + selectedLines = {}; | |
| 758 | + renderLineTags(); | |
| 759 | + updateLineCheckboxes(); | |
| 760 | + } | |
| 761 | + }); | |
| 762 | + }); | |
| 763 | + } | |
| 764 | + | |
| 765 | + document.getElementById('btn-search').addEventListener('click', function() { | |
| 766 | + if (conditionPanel.classList.contains('open')) { | |
| 767 | + toggleConditionPanel(); | |
| 768 | + } | |
| 769 | + | |
| 770 | + var mockData = { | |
| 771 | + "gpsList": [ | |
| 772 | + { | |
| 773 | + "lineId": "803111", | |
| 774 | + "subLineId": 0, | |
| 775 | + "deviceId": "77L0K001", | |
| 776 | + "carparkNo": "", | |
| 777 | + "stopNo": "", | |
| 778 | + "lon": 0.0, | |
| 779 | + "lat": 0.0, | |
| 780 | + "timestamp": 1772591197000, | |
| 781 | + "serverTimestamp": 1772591194152, | |
| 782 | + "speed": 0.0, | |
| 783 | + "direction": 0.0, | |
| 784 | + "state": 0, | |
| 785 | + "upDown": 1, | |
| 786 | + "nbbm": "L0K-001", | |
| 787 | + "schId": 1067376191, | |
| 788 | + "version": 69, | |
| 789 | + "instation": 0, | |
| 790 | + "signalState": "normal", | |
| 791 | + "abnormalStatus": "outBounds", | |
| 792 | + "outOfBoundDistance": 1.3019440198864643E7, | |
| 793 | + "valid": 1, | |
| 794 | + "source": -1, | |
| 795 | + "offline": false, | |
| 796 | + "service": true | |
| 797 | + }, | |
| 798 | + { | |
| 799 | + "lineId": "803112", | |
| 800 | + "subLineId": 0, | |
| 801 | + "deviceId": "77L0K002", | |
| 802 | + "carparkNo": "", | |
| 803 | + "stopNo": "", | |
| 804 | + "lon": 0.0, | |
| 805 | + "lat": 0.0, | |
| 806 | + "timestamp": 1772591197000, | |
| 807 | + "serverTimestamp": 1772591194152, | |
| 808 | + "speed": 0.0, | |
| 809 | + "direction": 0.0, | |
| 810 | + "state": 0, | |
| 811 | + "upDown": 0, | |
| 812 | + "nbbm": "L0K-002", | |
| 813 | + "schId": 1067376192, | |
| 814 | + "version": 70, | |
| 815 | + "instation": 0, | |
| 816 | + "signalState": "normal", | |
| 817 | + "abnormalStatus": "", | |
| 818 | + "outOfBoundDistance": 0, | |
| 819 | + "valid": 1, | |
| 820 | + "source": -1, | |
| 821 | + "offline": false, | |
| 822 | + "service": true | |
| 823 | + }, | |
| 824 | + { | |
| 825 | + "lineId": "803113", | |
| 826 | + "subLineId": 0, | |
| 827 | + "deviceId": "77L0K003", | |
| 828 | + "carparkNo": "", | |
| 829 | + "stopNo": "", | |
| 830 | + "lon": 0.0, | |
| 831 | + "lat": 0.0, | |
| 832 | + "timestamp": 1772591197000, | |
| 833 | + "serverTimestamp": 1772591194152, | |
| 834 | + "speed": 0.0, | |
| 835 | + "direction": 0.0, | |
| 836 | + "state": 0, | |
| 837 | + "upDown": 1, | |
| 838 | + "nbbm": "L0K-003", | |
| 839 | + "schId": 1067376193, | |
| 840 | + "version": 71, | |
| 841 | + "instation": 0, | |
| 842 | + "signalState": "normal", | |
| 843 | + "abnormalStatus": "", | |
| 844 | + "outOfBoundDistance": 0, | |
| 845 | + "valid": 1, | |
| 846 | + "source": -1, | |
| 847 | + "offline": false, | |
| 848 | + "service": true | |
| 849 | + } | |
| 850 | + ], | |
| 851 | + "overspeedList": [], | |
| 852 | + "scis": [] | |
| 853 | + }; | |
| 854 | + | |
| 855 | + displayResults(mockData.gpsList); | |
| 856 | + }); | |
| 857 | + | |
| 858 | + /** | |
| 859 | + * 关闭搜索结果面板 | |
| 860 | + */ | |
| 861 | + document.getElementById('close-results').addEventListener('click', function() { | |
| 862 | + document.getElementById('results-panel').classList.add('hidden'); | |
| 863 | + }); | |
| 864 | + | |
| 865 | + /** | |
| 866 | + * 显示搜索结果表格 | |
| 867 | + * @param {Array} data - 搜索结果数据数组 | |
| 868 | + */ | |
| 869 | + function displayResults(data) { | |
| 870 | + var tbody = document.getElementById('results-tbody'); | |
| 871 | + tbody.innerHTML = ''; | |
| 872 | + | |
| 873 | + data.forEach(function(item, index) { | |
| 874 | + var row = document.createElement('tr'); | |
| 875 | + row.className = 'border-b border-[#eee] hover:bg-[#f5f8fc]'; | |
| 876 | + row.innerHTML = | |
| 877 | + '<td class="px-2 py-2">' + (index + 1) + '</td>' + | |
| 878 | + '<td class="px-2 py-2">' + item.nbbm + '</td>' + | |
| 879 | + '<td class="px-2 py-2">' + item.deviceId + '</td>' + | |
| 880 | + '<td class="px-2 py-2">' + item.lineId + '</td>' + | |
| 881 | + '<td class="px-2 py-2">' + (item.upDown === 1 ? '上行' : '下行') + '</td>'; | |
| 882 | + tbody.appendChild(row); | |
| 883 | + }); | |
| 884 | + | |
| 885 | + document.getElementById('results-panel').classList.remove('hidden'); | |
| 886 | + } | |
| 887 | + | |
| 888 | + /** | |
| 889 | + * 监听文档点击,当点击搜索面板外部时收拢条件项 | |
| 890 | + */ | |
| 891 | + document.addEventListener('click', function(e) { | |
| 892 | + var searchPanel = document.getElementById('search-panel-container'); | |
| 893 | + if (searchPanel && !searchPanel.contains(e.target)) { | |
| 894 | + if (conditionPanel.classList.contains('open')) { | |
| 895 | + toggleConditionPanel(); | |
| 896 | + } | |
| 897 | + } | |
| 898 | + }); | |
| 899 | + }); | |
| 900 | + </script> | |
| 901 | +</body> | |
| 902 | +</html> | ... | ... |