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,6 +7,8 @@ public class SystemParamKeys { | ||
| 7 | 7 | ||
| 8 | public static final String SPECIAL_ROLES = "special.roles"; | 8 | public static final String SPECIAL_ROLES = "special.roles"; |
| 9 | 9 | ||
| 10 | + public static final String SPECIAL_DAYS = "special.days"; | ||
| 11 | + | ||
| 10 | public static final String URL_HTTP_GPS_REAL_CACHE = "url.http.gps.real.cache"; | 12 | public static final String URL_HTTP_GPS_REAL_CACHE = "url.http.gps.real.cache"; |
| 11 | 13 | ||
| 12 | public static final String URL_HTTP_GPS_REAL = "url.http.gps.real"; | 14 | public static final String URL_HTTP_GPS_REAL = "url.http.gps.real"; |
| @@ -40,4 +42,30 @@ public class SystemParamKeys { | @@ -40,4 +42,30 @@ public class SystemParamKeys { | ||
| 40 | public static final String URL_HTTP_SSO_LOGOUT = "url.http.sso.logout"; | 42 | public static final String URL_HTTP_SSO_LOGOUT = "url.http.sso.logout"; |
| 41 | 43 | ||
| 42 | public static final String URL_HTTP_SSO_AUTH = "url.http.sso.auth"; | 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 | \ No newline at end of file | 72 | \ No newline at end of file |
src/main/java/com/bsth/controller/gps/GpsController.java
| @@ -233,5 +233,9 @@ public class GpsController { | @@ -233,5 +233,9 @@ public class GpsController { | ||
| 233 | public Map<String, Object> allCarsByLine(String lineCode){ | 233 | public Map<String, Object> allCarsByLine(String lineCode){ |
| 234 | return gpsService.allCarsByLine(lineCode); | 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,6 +33,7 @@ import com.fasterxml.jackson.databind.SerializationFeature; | ||
| 33 | import org.slf4j.Logger; | 33 | import org.slf4j.Logger; |
| 34 | import org.slf4j.LoggerFactory; | 34 | import org.slf4j.LoggerFactory; |
| 35 | import org.springframework.beans.factory.annotation.Autowired; | 35 | import org.springframework.beans.factory.annotation.Autowired; |
| 36 | +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; | ||
| 36 | import org.springframework.web.bind.annotation.RequestMapping; | 37 | import org.springframework.web.bind.annotation.RequestMapping; |
| 37 | import org.springframework.web.bind.annotation.RequestParam; | 38 | import org.springframework.web.bind.annotation.RequestParam; |
| 38 | import org.springframework.web.bind.annotation.RestController; | 39 | import org.springframework.web.bind.annotation.RestController; |
| @@ -403,4 +404,18 @@ public class AdminUtilsController { | @@ -403,4 +404,18 @@ public class AdminUtilsController { | ||
| 403 | 404 | ||
| 404 | return "error"; | 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 | \ No newline at end of file | 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,6 +108,7 @@ public class ServiceDataInterface { | ||
| 108 | map.put("remarks", sch.getRemark()); | 108 | map.put("remarks", sch.getRemark()); |
| 109 | map.put("status", sch.getStatus()); | 109 | map.put("status", sch.getStatus()); |
| 110 | map.put("realExecDate", sch.getRealExecDate()); | 110 | map.put("realExecDate", sch.getRealExecDate()); |
| 111 | + map.put("lineRegion", sch.getLineRegion()); | ||
| 111 | 112 | ||
| 112 | //放站班次,放到的站点 | 113 | //放站班次,放到的站点 |
| 113 | map.put("majorStationName", sch.getMajorStationName()); | 114 | map.put("majorStationName", sch.getMajorStationName()); |
src/main/java/com/bsth/data/SystemParamCache.java
| @@ -21,6 +21,10 @@ public class SystemParamCache implements InitializingBean { | @@ -21,6 +21,10 @@ public class SystemParamCache implements InitializingBean { | ||
| 21 | return systemParamService1.getValue(SystemParamKeys.SPECIAL_ROLES); | 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 | public static String getUrlHttpGpsRealCache() { | 28 | public static String getUrlHttpGpsRealCache() { |
| 25 | return systemParamService1.getValue(SystemParamKeys.URL_HTTP_GPS_REAL_CACHE); | 29 | return systemParamService1.getValue(SystemParamKeys.URL_HTTP_GPS_REAL_CACHE); |
| 26 | } | 30 | } |
| @@ -85,11 +89,62 @@ public class SystemParamCache implements InitializingBean { | @@ -85,11 +89,62 @@ public class SystemParamCache implements InitializingBean { | ||
| 85 | return systemParamService1.getValue(SystemParamKeys.URL_HTTP_SSO_LOGOUT); | 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 | public static String getUrlHttpSsoAuth() { | 92 | public static String getUrlHttpSsoAuth() { |
| 90 | return systemParamService1.getValue(SystemParamKeys.URL_HTTP_SSO_AUTH); | 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 | @Override | 148 | @Override |
| 94 | public void afterPropertiesSet() throws Exception { | 149 | public void afterPropertiesSet() throws Exception { |
| 95 | systemParamService1 = systemParamService; | 150 | systemParamService1 = systemParamService; |
src/main/java/com/bsth/data/car_out_info/CarOutInfoHandler.java
| @@ -117,8 +117,8 @@ public class CarOutInfoHandler { | @@ -117,8 +117,8 @@ public class CarOutInfoHandler { | ||
| 117 | //删除 | 117 | //删除 |
| 118 | jdbcTemplate.update("delete from bsth_t_clfcxxb"); | 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 | @Override | 122 | @Override |
| 123 | public void setValues(PreparedStatement ps, int i) throws SQLException { | 123 | public void setValues(PreparedStatement ps, int i) throws SQLException { |
| 124 | ScheduleRealInfo sch = pstList.get(i); | 124 | ScheduleRealInfo sch = pstList.get(i); |
| @@ -138,6 +138,7 @@ public class CarOutInfoHandler { | @@ -138,6 +138,7 @@ public class CarOutInfoHandler { | ||
| 138 | ps.setString(14, sch.getRemarks()); | 138 | ps.setString(14, sch.getRemarks()); |
| 139 | ps.setInt(15, sch.getFcpSn()); | 139 | ps.setInt(15, sch.getFcpSn()); |
| 140 | ps.setLong(16, sch.getId()); | 140 | ps.setLong(16, sch.getId()); |
| 141 | + ps.setString(17, sch.getLineRegion()); | ||
| 141 | } | 142 | } |
| 142 | 143 | ||
| 143 | @Override | 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 | \ No newline at end of file | 125 | \ No newline at end of file |
src/main/java/com/bsth/entity/LsStationRoute.java
| @@ -165,6 +165,11 @@ public class LsStationRoute { | @@ -165,6 +165,11 @@ public class LsStationRoute { | ||
| 165 | @Transient | 165 | @Transient |
| 166 | private String centerPointWgsWkt; | 166 | private String centerPointWgsWkt; |
| 167 | 167 | ||
| 168 | + /** | ||
| 169 | + * 绕改道当前站点对应的后一站点 | ||
| 170 | + */ | ||
| 171 | + private Integer detourStationRoute; | ||
| 172 | + | ||
| 168 | public Integer getId() { | 173 | public Integer getId() { |
| 169 | return id; | 174 | return id; |
| 170 | } | 175 | } |
| @@ -440,4 +445,12 @@ public class LsStationRoute { | @@ -440,4 +445,12 @@ public class LsStationRoute { | ||
| 440 | 445 | ||
| 441 | return centerPointWgsWkt; | 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 | \ No newline at end of file | 457 | \ No newline at end of file |
src/main/java/com/bsth/entity/StationRoute.java
| @@ -198,6 +198,11 @@ public class StationRoute { | @@ -198,6 +198,11 @@ public class StationRoute { | ||
| 198 | @Transient | 198 | @Transient |
| 199 | private String centerPointWgsWkt; | 199 | private String centerPointWgsWkt; |
| 200 | 200 | ||
| 201 | + /** | ||
| 202 | + * 绕改道当前站点对应的后一站点 | ||
| 203 | + */ | ||
| 204 | + private Integer detourStationRoute; | ||
| 205 | + | ||
| 201 | public Integer getId() { | 206 | public Integer getId() { |
| 202 | return id; | 207 | return id; |
| 203 | } | 208 | } |
| @@ -473,4 +478,12 @@ public class StationRoute { | @@ -473,4 +478,12 @@ public class StationRoute { | ||
| 473 | 478 | ||
| 474 | return centerPointWgsWkt; | 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 | \ No newline at end of file | 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
| @@ -47,4 +47,6 @@ public interface GpsService { | @@ -47,4 +47,6 @@ public interface GpsService { | ||
| 47 | Map<String, Object> Pagequery(Map<String, Object> map); | 47 | Map<String, Object> Pagequery(Map<String, Object> map); |
| 48 | 48 | ||
| 49 | Map<String,Object> allCarsByLine(String lineCode); | 49 | Map<String,Object> allCarsByLine(String lineCode); |
| 50 | + | ||
| 51 | + Map<String, Object> fuzzy(Map<String, Object> map); | ||
| 50 | } | 52 | } |
src/main/java/com/bsth/service/gps/GpsServiceImpl.java
| @@ -1576,6 +1576,16 @@ public class GpsServiceImpl implements GpsService { | @@ -1576,6 +1576,16 @@ public class GpsServiceImpl implements GpsService { | ||
| 1576 | return map; | 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 | static List<GpsSpeed> findAll(Map<String, Object> map) { | 1589 | static List<GpsSpeed> findAll(Map<String, Object> map) { |
| 1580 | Connection conn = null; | 1590 | Connection conn = null; |
| 1581 | PreparedStatement ps = null; | 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 | \ No newline at end of file | 19 | \ No newline at end of file |
src/main/java/com/bsth/service/impl/LsStationRouteServiceImpl.java
| 1 | package com.bsth.service.impl; | 1 | package com.bsth.service.impl; |
| 2 | 2 | ||
| 3 | import com.bsth.annotation.BusinessDescription; | 3 | import com.bsth.annotation.BusinessDescription; |
| 4 | +import com.bsth.data.gpsdata_v2.utils.GeoUtils; | ||
| 4 | import com.bsth.entity.*; | 5 | import com.bsth.entity.*; |
| 5 | import com.bsth.entity.search.CustomerSpecs; | 6 | import com.bsth.entity.search.CustomerSpecs; |
| 6 | import com.bsth.repository.*; | 7 | import com.bsth.repository.*; |
| 7 | import com.bsth.service.LsStationRouteService; | 8 | import com.bsth.service.LsStationRouteService; |
| 8 | -import com.bsth.util.CoordinateConverter; | ||
| 9 | import com.bsth.util.CustomBeanUtils; | 9 | import com.bsth.util.CustomBeanUtils; |
| 10 | import com.bsth.util.GeoConverter; | 10 | import com.bsth.util.GeoConverter; |
| 11 | -import com.fasterxml.jackson.core.JsonProcessingException; | ||
| 12 | -import com.fasterxml.jackson.databind.ObjectMapper; | ||
| 13 | import org.geolatte.geom.LineString; | 11 | import org.geolatte.geom.LineString; |
| 14 | -import org.geolatte.geom.Point; | ||
| 15 | import org.geolatte.geom.Polygon; | 12 | import org.geolatte.geom.Polygon; |
| 16 | import org.geolatte.geom.codec.Wkt; | 13 | import org.geolatte.geom.codec.Wkt; |
| 14 | +import org.slf4j.Logger; | ||
| 15 | +import org.slf4j.LoggerFactory; | ||
| 17 | import org.springframework.beans.factory.annotation.Autowired; | 16 | import org.springframework.beans.factory.annotation.Autowired; |
| 18 | import org.springframework.data.domain.Sort; | 17 | import org.springframework.data.domain.Sort; |
| 19 | import org.springframework.jdbc.core.BatchPreparedStatementSetter; | 18 | import org.springframework.jdbc.core.BatchPreparedStatementSetter; |
| @@ -32,6 +31,8 @@ import java.util.*; | @@ -32,6 +31,8 @@ import java.util.*; | ||
| 32 | @Service | 31 | @Service |
| 33 | public class LsStationRouteServiceImpl extends BaseServiceImpl<LsStationRoute, Integer> implements LsStationRouteService { | 32 | public class LsStationRouteServiceImpl extends BaseServiceImpl<LsStationRoute, Integer> implements LsStationRouteService { |
| 34 | 33 | ||
| 34 | + private final static Logger log = LoggerFactory.getLogger(LsStationRouteServiceImpl.class); | ||
| 35 | + | ||
| 35 | @Autowired | 36 | @Autowired |
| 36 | private LsStationRouteRepository lsStationRouteRepository; | 37 | private LsStationRouteRepository lsStationRouteRepository; |
| 37 | 38 | ||
| @@ -59,6 +60,9 @@ public class LsStationRouteServiceImpl extends BaseServiceImpl<LsStationRoute, I | @@ -59,6 +60,9 @@ public class LsStationRouteServiceImpl extends BaseServiceImpl<LsStationRoute, I | ||
| 59 | @Autowired | 60 | @Autowired |
| 60 | private JdbcTemplate jdbcTemplate; | 61 | private JdbcTemplate jdbcTemplate; |
| 61 | 62 | ||
| 63 | + @Autowired | ||
| 64 | + private DetourRepository detourRepository; | ||
| 65 | + | ||
| 62 | @Override | 66 | @Override |
| 63 | public Iterable<LsStationRoute> findAllByParams(Map<String, Object> map) { | 67 | public Iterable<LsStationRoute> findAllByParams(Map<String, Object> map) { |
| 64 | List<Sort.Order> orders = new ArrayList<>(); | 68 | List<Sort.Order> orders = new ArrayList<>(); |
| @@ -318,9 +322,201 @@ public class LsStationRouteServiceImpl extends BaseServiceImpl<LsStationRoute, I | @@ -318,9 +322,201 @@ public class LsStationRouteServiceImpl extends BaseServiceImpl<LsStationRoute, I | ||
| 318 | refreshCurrent(stationRoute1.getLine().getId(), currentVersion); | 322 | refreshCurrent(stationRoute1.getLine().getId(), currentVersion); |
| 319 | } | 323 | } |
| 320 | 324 | ||
| 325 | + // 处理绕改道逻辑 | ||
| 326 | + handleDetour(stationRoute1); | ||
| 327 | + | ||
| 321 | return new HashMap<>(); | 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 | @Transactional | 520 | @Transactional |
| 325 | @Override | 521 | @Override |
| 326 | public Map<String, Object> exchangeDirection(int lineId, int version) { | 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,8 +509,8 @@ public class StationRouteServiceImpl extends BaseServiceImpl<StationRoute, Integ | ||
| 509 | clientUtils.uploadFile(url, port, username, password, remotePath + "/voice/", textFileName, input); | 509 | clientUtils.uploadFile(url, port, username, password, remotePath + "/voice/", textFileName, input); |
| 510 | String linePath = String.format(linePathPattern, lineId), voicePath = String.format("%s%s.zip", linePath, lineId); | 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 | if (lineRegions.size() > 0) { | 516 | if (lineRegions.size() > 0) { |
| @@ -1305,7 +1305,7 @@ public class StationRouteServiceImpl extends BaseServiceImpl<StationRoute, Integ | @@ -1305,7 +1305,7 @@ public class StationRouteServiceImpl extends BaseServiceImpl<StationRoute, Integ | ||
| 1305 | // 子线路路径 | 1305 | // 子线路路径 |
| 1306 | String linePath = String.format(linePathPattern, lineId); | 1306 | String linePath = String.format(linePathPattern, lineId); |
| 1307 | String subLinePath = String.format("%s%s/", linePath, subLineId); | 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 | List<String> inputPaths = new ArrayList<>(); | 1309 | List<String> inputPaths = new ArrayList<>(); |
| 1310 | for (String path : arr) { | 1310 | for (String path : arr) { |
| 1311 | for (String lang : languages) { | 1311 | for (String lang : languages) { |
src/main/java/com/bsth/service/impl/TrafficManageServiceImpl.java
| 1 | package com.bsth.service.impl; | 1 | package com.bsth.service.impl; |
| 2 | 2 | ||
| 3 | import com.bsth.data.BasicData; | 3 | import com.bsth.data.BasicData; |
| 4 | +import com.bsth.data.SystemParamCache; | ||
| 4 | import com.bsth.email.SendEmailController; | 5 | import com.bsth.email.SendEmailController; |
| 5 | import com.bsth.email.entity.EmailBean; | 6 | import com.bsth.email.entity.EmailBean; |
| 6 | import com.bsth.entity.*; | 7 | import com.bsth.entity.*; |
| @@ -23,9 +24,9 @@ import com.bsth.util.CoordinateConverter; | @@ -23,9 +24,9 @@ import com.bsth.util.CoordinateConverter; | ||
| 23 | import com.bsth.util.IpUtils; | 24 | import com.bsth.util.IpUtils; |
| 24 | import com.bsth.util.TimeUtils; | 25 | import com.bsth.util.TimeUtils; |
| 25 | import com.bsth.util.db.DBUtils_MS; | 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 | import org.apache.commons.lang.StringEscapeUtils; | 30 | import org.apache.commons.lang.StringEscapeUtils; |
| 30 | import org.apache.commons.lang.StringUtils; | 31 | import org.apache.commons.lang.StringUtils; |
| 31 | import org.apache.commons.lang.time.DateUtils; | 32 | import org.apache.commons.lang.time.DateUtils; |
| @@ -33,6 +34,7 @@ import org.joda.time.DateTime; | @@ -33,6 +34,7 @@ import org.joda.time.DateTime; | ||
| 33 | import org.slf4j.Logger; | 34 | import org.slf4j.Logger; |
| 34 | import org.slf4j.LoggerFactory; | 35 | import org.slf4j.LoggerFactory; |
| 35 | import org.springframework.beans.factory.annotation.Autowired; | 36 | import org.springframework.beans.factory.annotation.Autowired; |
| 37 | +import org.springframework.beans.factory.annotation.Value; | ||
| 36 | import org.springframework.data.domain.Sort; | 38 | import org.springframework.data.domain.Sort; |
| 37 | import org.springframework.data.domain.Sort.Direction; | 39 | import org.springframework.data.domain.Sort.Direction; |
| 38 | import org.springframework.security.core.context.SecurityContextHolder; | 40 | import org.springframework.security.core.context.SecurityContextHolder; |
| @@ -135,11 +137,31 @@ public class TrafficManageServiceImpl implements TrafficManageService{ | @@ -135,11 +137,31 @@ public class TrafficManageServiceImpl implements TrafficManageService{ | ||
| 135 | private LineVersionsRepository lineVersionsRepository; | 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 | try { | 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 | } catch (Exception e) { | 165 | } catch (Exception e) { |
| 144 | e.printStackTrace(); | 166 | e.printStackTrace(); |
| 145 | } | 167 | } |
| @@ -153,31 +175,20 @@ public class TrafficManageServiceImpl implements TrafficManageService{ | @@ -153,31 +175,20 @@ public class TrafficManageServiceImpl implements TrafficManageService{ | ||
| 153 | // 数字格式化 | 175 | // 数字格式化 |
| 154 | DecimalFormat format = new DecimalFormat("0.00"); | 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 | private Integer countSuccess,countFailure; | 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,13 +229,18 @@ public class TrafficManageServiceImpl implements TrafficManageService{ | ||
| 218 | } | 229 | } |
| 219 | String state;// 是否上传成功 | 230 | String state;// 是否上传成功 |
| 220 | // 调用上传方法 | 231 | // 调用上传方法 |
| 221 | - if(getWebServiceSoapUp().setXL(userNameUp,passwordUp,xml).isSuccess()){ | 232 | + if(ssop1.setXL(userNameOther,passwordOther,xml).isSuccess()){ |
| 222 | result = "success"; | 233 | result = "success"; |
| 223 | state = "1"; | 234 | state = "1"; |
| 224 | }else{ | 235 | }else{ |
| 225 | result = "failure"; | 236 | result = "failure"; |
| 226 | state = "0"; | 237 | state = "0"; |
| 227 | } | 238 | } |
| 239 | + if (ssopBak1.setXL(userNameOther,passwordOther,xml).isSuccess()) { | ||
| 240 | + result += ",success"; | ||
| 241 | + } else { | ||
| 242 | + result += ",failure"; | ||
| 243 | + } | ||
| 228 | logger.info("setXL:"+xml); | 244 | logger.info("setXL:"+xml); |
| 229 | logger.info("setXL:"+result); | 245 | logger.info("setXL:"+result); |
| 230 | // 保存运管处上传记录 | 246 | // 保存运管处上传记录 |
| @@ -319,6 +335,9 @@ public class TrafficManageServiceImpl implements TrafficManageService{ | @@ -319,6 +335,9 @@ public class TrafficManageServiceImpl implements TrafficManageService{ | ||
| 319 | if(ssop.setCL(userNameOther, passwordOther, sBuffer.toString()).isSuccess()){ | 335 | if(ssop.setCL(userNameOther, passwordOther, sBuffer.toString()).isSuccess()){ |
| 320 | result = "success"; | 336 | result = "success"; |
| 321 | } | 337 | } |
| 338 | + if (ssopBak != null && ssopBak.setCL(userNameOther, passwordOther, sBuffer.toString()).isSuccess()) { | ||
| 339 | + result += ",success"; | ||
| 340 | + } | ||
| 322 | } catch (Exception e) { | 341 | } catch (Exception e) { |
| 323 | logger.error("setCL:",e); | 342 | logger.error("setCL:",e); |
| 324 | e.printStackTrace(); | 343 | e.printStackTrace(); |
| @@ -356,7 +375,10 @@ public class TrafficManageServiceImpl implements TrafficManageService{ | @@ -356,7 +375,10 @@ public class TrafficManageServiceImpl implements TrafficManageService{ | ||
| 356 | sBuffer.append("</SJs>"); | 375 | sBuffer.append("</SJs>"); |
| 357 | if(ssop.setSJ(userNameOther, passwordOther, sBuffer.toString()).isSuccess()){ | 376 | if(ssop.setSJ(userNameOther, passwordOther, sBuffer.toString()).isSuccess()){ |
| 358 | result = "success"; | 377 | result = "success"; |
| 359 | - }; | 378 | + } |
| 379 | + if (ssopBak != null && ssopBak.setSJ(userNameOther, passwordOther, sBuffer.toString()).isSuccess()) { | ||
| 380 | + result += ",success"; | ||
| 381 | + } | ||
| 360 | } catch (Exception e) { | 382 | } catch (Exception e) { |
| 361 | logger.error("setSJ:",e); | 383 | logger.error("setSJ:",e); |
| 362 | e.printStackTrace(); | 384 | e.printStackTrace(); |
| @@ -395,6 +417,7 @@ public class TrafficManageServiceImpl implements TrafficManageService{ | @@ -395,6 +417,7 @@ public class TrafficManageServiceImpl implements TrafficManageService{ | ||
| 395 | String str = "", xlbm = null, oldXlbm = null; | 417 | String str = "", xlbm = null, oldXlbm = null; |
| 396 | List<Map<String,Object>> listGroup = null; | 418 | List<Map<String,Object>> listGroup = null; |
| 397 | int scount = 0, ccount = 0; | 419 | int scount = 0, ccount = 0; |
| 420 | + int scount1 = 0, ccount1 = 0; | ||
| 398 | long start = System.currentTimeMillis(); | 421 | long start = System.currentTimeMillis(); |
| 399 | try { | 422 | try { |
| 400 | // 计数器 | 423 | // 计数器 |
| @@ -436,6 +459,7 @@ public class TrafficManageServiceImpl implements TrafficManageService{ | @@ -436,6 +459,7 @@ public class TrafficManageServiceImpl implements TrafficManageService{ | ||
| 436 | Line line = code2line.get(lineCode); | 459 | Line line = code2line.get(lineCode); |
| 437 | if(line == null || line.getInUse() == null || line.getInUse() == 0){ | 460 | if(line == null || line.getInUse() == null || line.getInUse() == 0){ |
| 438 | ccount++; | 461 | ccount++; |
| 462 | + ccount1++; | ||
| 439 | continue; | 463 | continue; |
| 440 | } | 464 | } |
| 441 | if(counter % per == 0){ | 465 | if(counter % per == 0){ |
| @@ -512,7 +536,8 @@ public class TrafficManageServiceImpl implements TrafficManageService{ | @@ -512,7 +536,8 @@ public class TrafficManageServiceImpl implements TrafficManageService{ | ||
| 512 | sf.append("</DLDS>"); | 536 | sf.append("</DLDS>"); |
| 513 | // 去掉'号 | 537 | // 去掉'号 |
| 514 | str = sf.toString().replace("'",""); | 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 | counter = 0; | 541 | counter = 0; |
| 517 | } | 542 | } |
| 518 | } | 543 | } |
| @@ -521,18 +546,23 @@ public class TrafficManageServiceImpl implements TrafficManageService{ | @@ -521,18 +546,23 @@ public class TrafficManageServiceImpl implements TrafficManageService{ | ||
| 521 | sf.append("</DLDS>"); | 546 | sf.append("</DLDS>"); |
| 522 | // 去掉'号 | 547 | // 去掉'号 |
| 523 | str = sf.toString().replace("'",""); | 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 | } catch (Exception e) { | 554 | } catch (Exception e) { |
| 527 | e.printStackTrace(); | 555 | e.printStackTrace(); |
| 528 | logger.error("setLD:", e); | 556 | logger.error("setLD:", e); |
| 529 | } finally { | 557 | } finally { |
| 530 | try { | 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 | logger.info("setLD-sendMail:邮件发送成功!"); | 566 | logger.info("setLD-sendMail:邮件发送成功!"); |
| 537 | } catch (Exception e) { | 567 | } catch (Exception e) { |
| 538 | e.printStackTrace(); | 568 | e.printStackTrace(); |
| @@ -548,21 +578,21 @@ public class TrafficManageServiceImpl implements TrafficManageService{ | @@ -548,21 +578,21 @@ public class TrafficManageServiceImpl implements TrafficManageService{ | ||
| 548 | * @param counter 分组数 | 578 | * @param counter 分组数 |
| 549 | * @return 成功返回counter 失败返回0 | 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 | for (int i = 0;i < 10;i++) { | 582 | for (int i = 0;i < 10;i++) { |
| 553 | try { | 583 | try { |
| 554 | Results results = ssop.setLD(userNameOther, passwordOther, StringEscapeUtils.unescapeHtml(xml)); | 584 | Results results = ssop.setLD(userNameOther, passwordOther, StringEscapeUtils.unescapeHtml(xml)); |
| 555 | if (results.isSuccess()) { | 585 | if (results.isSuccess()) { |
| 556 | - logger.info("setLD: " + xml); | 586 | + logger.info("{} setLD: {}", flag, xml); |
| 557 | logger.info("setLD: 成功"); | 587 | logger.info("setLD: 成功"); |
| 558 | return counter; | 588 | return counter; |
| 559 | } else if (i == 9) { | 589 | } else if (i == 9) { |
| 560 | - logger.error("setLD: " + xml); | 590 | + logger.error("{} setLD: {}", flag, xml); |
| 561 | logger.error("setLD: 失败," + results.getMessage()); | 591 | logger.error("setLD: 失败," + results.getMessage()); |
| 562 | } | 592 | } |
| 563 | Thread.sleep(2000); | 593 | Thread.sleep(2000); |
| 564 | } catch (Exception e) { | 594 | } catch (Exception e) { |
| 565 | - logger.error("运管处接口调用异常", e); | 595 | + logger.error("{} 运管处接口调用异常", flag, e); |
| 566 | try { | 596 | try { |
| 567 | Thread.sleep(2000); | 597 | Thread.sleep(2000); |
| 568 | } catch (InterruptedException ex) { | 598 | } catch (InterruptedException ex) { |
| @@ -586,6 +616,9 @@ public class TrafficManageServiceImpl implements TrafficManageService{ | @@ -586,6 +616,9 @@ public class TrafficManageServiceImpl implements TrafficManageService{ | ||
| 586 | if(rss.isSuccess()){ | 616 | if(rss.isSuccess()){ |
| 587 | result = "success"; | 617 | result = "success"; |
| 588 | } | 618 | } |
| 619 | + if (ssopBak != null && ssopBak.setLD(userNameOther, passwordOther, StringEscapeUtils.unescapeHtml(tmp)).isSuccess()) { | ||
| 620 | + result += ",success"; | ||
| 621 | + } | ||
| 589 | } catch (Exception e) { | 622 | } catch (Exception e) { |
| 590 | logger.error("setLD:",e); | 623 | logger.error("setLD:",e); |
| 591 | e.printStackTrace(); | 624 | e.printStackTrace(); |
| @@ -688,6 +721,9 @@ public class TrafficManageServiceImpl implements TrafficManageService{ | @@ -688,6 +721,9 @@ public class TrafficManageServiceImpl implements TrafficManageService{ | ||
| 688 | if(ssop.setLCYH(userNameOther, passwordOther, sf.toString()).isSuccess()){ | 721 | if(ssop.setLCYH(userNameOther, passwordOther, sf.toString()).isSuccess()){ |
| 689 | result = "success"; | 722 | result = "success"; |
| 690 | } | 723 | } |
| 724 | + if (ssopBak != null && ssopBak.setLCYH(userNameOther, passwordOther, sf.toString()).isSuccess()) { | ||
| 725 | + result += ",success"; | ||
| 726 | + } | ||
| 691 | } catch (Exception e) { | 727 | } catch (Exception e) { |
| 692 | logger.error("setLCYH:",e); | 728 | logger.error("setLCYH:",e); |
| 693 | e.printStackTrace(); | 729 | e.printStackTrace(); |
| @@ -792,6 +828,9 @@ public class TrafficManageServiceImpl implements TrafficManageService{ | @@ -792,6 +828,9 @@ public class TrafficManageServiceImpl implements TrafficManageService{ | ||
| 792 | if(ssop.setDDRB(userNameOther, passwordOther, sf.toString()).isSuccess()){ | 828 | if(ssop.setDDRB(userNameOther, passwordOther, sf.toString()).isSuccess()){ |
| 793 | result = "success"; | 829 | result = "success"; |
| 794 | } | 830 | } |
| 831 | + if (ssopBak != null && ssopBak.setDDRB(userNameOther, passwordOther, sf.toString()).isSuccess()) { | ||
| 832 | + result += ",success"; | ||
| 833 | + } | ||
| 795 | } catch (Exception e) { | 834 | } catch (Exception e) { |
| 796 | logger.error("setDDRB:",e); | 835 | logger.error("setDDRB:",e); |
| 797 | e.printStackTrace(); | 836 | e.printStackTrace(); |
| @@ -910,6 +949,9 @@ public class TrafficManageServiceImpl implements TrafficManageService{ | @@ -910,6 +949,9 @@ public class TrafficManageServiceImpl implements TrafficManageService{ | ||
| 910 | if(ssop.setJHBC(userNameOther, passwordOther, sBuffer.toString()).isSuccess()){ | 949 | if(ssop.setJHBC(userNameOther, passwordOther, sBuffer.toString()).isSuccess()){ |
| 911 | result = "success"; | 950 | result = "success"; |
| 912 | } | 951 | } |
| 952 | + if (ssopBak != null && ssopBak.setJHBC(userNameOther, passwordOther, sBuffer.toString()).isSuccess()) { | ||
| 953 | + result += ",success"; | ||
| 954 | + } | ||
| 913 | } catch (Exception e) { | 955 | } catch (Exception e) { |
| 914 | logger.error("setJHBC:",e); | 956 | logger.error("setJHBC:",e); |
| 915 | e.printStackTrace(); | 957 | e.printStackTrace(); |
| @@ -1103,14 +1145,20 @@ public class TrafficManageServiceImpl implements TrafficManageService{ | @@ -1103,14 +1145,20 @@ public class TrafficManageServiceImpl implements TrafficManageService{ | ||
| 1103 | result = "上传失败"; | 1145 | result = "上传失败"; |
| 1104 | state = "0"; | 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 | saveYgcUploadLog(ttinfoList,sBuffer.toString(),TrafficManageServiceImpl.UPLOAD_TYPE_SKB,state); | 1158 | saveYgcUploadLog(ttinfoList,sBuffer.toString(),TrafficManageServiceImpl.UPLOAD_TYPE_SKB,state); |
| 1108 | } catch (Exception e) { | 1159 | } catch (Exception e) { |
| 1109 | logger.error("setSKB:", e); | 1160 | logger.error("setSKB:", e); |
| 1110 | e.printStackTrace(); | 1161 | e.printStackTrace(); |
| 1111 | - }finally{ | ||
| 1112 | - logger.info("setSKB:"+sBuffer.toString()); | ||
| 1113 | - logger.info("setSKB:"+result); | ||
| 1114 | } | 1162 | } |
| 1115 | return result; | 1163 | return result; |
| 1116 | } | 1164 | } |
| @@ -1191,6 +1239,7 @@ public class TrafficManageServiceImpl implements TrafficManageService{ | @@ -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,6 +1292,9 @@ public class TrafficManageServiceImpl implements TrafficManageService{ | ||
| 1243 | if(ssop.setXLPC(userNameOther, passwordOther, sBuffer.toString()).isSuccess()){ | 1292 | if(ssop.setXLPC(userNameOther, passwordOther, sBuffer.toString()).isSuccess()){ |
| 1244 | result = "success"; | 1293 | result = "success"; |
| 1245 | } | 1294 | } |
| 1295 | + if (ssopBak != null && ssopBak.setXLPC(userNameOther, passwordOther, sBuffer.toString()).isSuccess()) { | ||
| 1296 | + result += ",success"; | ||
| 1297 | + } | ||
| 1246 | } catch (Exception e) { | 1298 | } catch (Exception e) { |
| 1247 | logger.error("setXLPC:",e); | 1299 | logger.error("setXLPC:",e); |
| 1248 | e.printStackTrace(); | 1300 | e.printStackTrace(); |
| @@ -1303,6 +1355,9 @@ public class TrafficManageServiceImpl implements TrafficManageService{ | @@ -1303,6 +1355,9 @@ public class TrafficManageServiceImpl implements TrafficManageService{ | ||
| 1303 | if(ssop.setCS(userNameOther, passwordOther, sBuffer.toString()).isSuccess()){ | 1355 | if(ssop.setCS(userNameOther, passwordOther, sBuffer.toString()).isSuccess()){ |
| 1304 | result = "success"; | 1356 | result = "success"; |
| 1305 | } | 1357 | } |
| 1358 | + if (ssopBak != null && ssopBak.setCS(userNameOther, passwordOther, sBuffer.toString()).isSuccess()) { | ||
| 1359 | + result += ",success"; | ||
| 1360 | + } | ||
| 1306 | } catch (Exception e) { | 1361 | } catch (Exception e) { |
| 1307 | logger.error("setCS:",e); | 1362 | logger.error("setCS:",e); |
| 1308 | e.printStackTrace(); | 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,7 +311,7 @@ $('#add_stationroute_step2_modal').on('modal.show', function(event){ | ||
| 311 | params.bufferPolygonWkt = params.bufferPolygonWkt ? 'POLYGON((' + params.bufferPolygonWkt + '))' : ''; | 311 | params.bufferPolygonWkt = params.bufferPolygonWkt ? 'POLYGON((' + params.bufferPolygonWkt + '))' : ''; |
| 312 | params.shapedType = params.shapedType == '圆形' ? 'r' : 'd'; | 312 | params.shapedType = params.shapedType == '圆形' ? 'r' : 'd'; |
| 313 | if (params.stationRouteCode == '请选择...' && params.stationMark == 'B') { | 313 | if (params.stationRouteCode == '请选择...' && params.stationMark == 'B') { |
| 314 | - params.stationRouteCode = '100'; | 314 | + params.stationRouteCode = 1; |
| 315 | } else { | 315 | } else { |
| 316 | params.stationRouteCode = parseInt(params.stationRouteCode) + 1; | 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,7 +201,7 @@ $('#add_station_template_modal').on('modal.show', function(event) { | ||
| 201 | } | 201 | } |
| 202 | 202 | ||
| 203 | function formatRoutes(params) { | 203 | function formatRoutes(params) { |
| 204 | - var stationRoutes = [], sectionRoutes = [], sectionRouteCode = 100; | 204 | + var stationRoutes = [], sectionRoutes = [], sectionRouteCode = 1; |
| 205 | params.stationJSON.forEach(function(item) { | 205 | params.stationJSON.forEach(function(item) { |
| 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 + ')'}}); | 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,7 +138,7 @@ $('#edit_sectionroute_modal').on('modal.show', function(e, polyline){ | ||
| 138 | params.sectionTime = 0; | 138 | params.sectionTime = 0; |
| 139 | 139 | ||
| 140 | if(params.sectionrouteCode == '请选择...') { | 140 | if(params.sectionrouteCode == '请选择...') { |
| 141 | - params.sectionrouteCode = 100; | 141 | + params.sectionrouteCode = 1; |
| 142 | } else { | 142 | } else { |
| 143 | params.sectionrouteCode = parseInt(params.sectionrouteCode) + 1; | 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,6 +174,18 @@ | ||
| 174 | </div> | 174 | </div> |
| 175 | </div> | 175 | </div> |
| 176 | </div> | 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 | </form> | 189 | </form> |
| 178 | </div> | 190 | </div> |
| 179 | <div class="modal-footer"> | 191 | <div class="modal-footer"> |
| @@ -257,7 +269,7 @@ $('#edit_stationroute_step2_modal').on('modal.show', function(event){ | @@ -257,7 +269,7 @@ $('#edit_stationroute_step2_modal').on('modal.show', function(event){ | ||
| 257 | else if(params.shapedType=='多边形') | 269 | else if(params.shapedType=='多边形') |
| 258 | params.shapedType='d'; | 270 | params.shapedType='d'; |
| 259 | if(params.stationRouteCode == '' || params.stationMark === 'B') | 271 | if(params.stationRouteCode == '' || params.stationMark === 'B') |
| 260 | - params.stationRouteCode = 100; | 272 | + params.stationRouteCode = 1; |
| 261 | if (params.stationMark !== 'B') { | 273 | if (params.stationMark !== 'B') { |
| 262 | params.stationRouteCode = parseInt(stationRouteCode.split('-')[0]) + 1; | 274 | params.stationRouteCode = parseInt(stationRouteCode.split('-')[0]) + 1; |
| 263 | } | 275 | } |
| @@ -295,14 +307,20 @@ $('#edit_stationroute_step2_modal').on('modal.show', function(event){ | @@ -295,14 +307,20 @@ $('#edit_stationroute_step2_modal').on('modal.show', function(event){ | ||
| 295 | var obj = {'id':'-1','text':'请选择...'}; | 307 | var obj = {'id':'-1','text':'请选择...'}; |
| 296 | 308 | ||
| 297 | RoutesService.getzdlyInfo(p, function(array) { | 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 | if(len_>0) { | 314 | if(len_>0) { |
| 301 | - paramsD.push({'id':'-1','text':'请选择...'}); | 315 | + paramsD.push(choose); |
| 316 | + stationRoutes.push(choose) | ||
| 302 | // 遍历. | 317 | // 遍历. |
| 303 | $.each(array, function(i, g){ | 318 | $.each(array, function(i, g){ |
| 304 | if(g.stationName) { | 319 | if(g.stationName) { |
| 305 | if (g.stationRouteCode != editStationRoute.stationRouteCode) { | 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 | if (editStationRoute.stationMark == 'E' && i == (len_ - 2)){ | 324 | if (editStationRoute.stationMark == 'E' && i == (len_ - 2)){ |
| 307 | obj = {'id':g.stationRouteCode + '_' + 'E' + '_' + g.directions, 'text':g.stationName + ' (' + g.stationRouteCode + ')' + ' --' + RoutesOperation.dirdmToName(g.directions)}; | 325 | obj = {'id':g.stationRouteCode + '_' + 'E' + '_' + g.directions, 'text':g.stationName + ' (' + g.stationRouteCode + ')' + ' --' + RoutesOperation.dirdmToName(g.directions)}; |
| 308 | paramsD.push(obj); | 326 | paramsD.push(obj); |
| @@ -316,12 +334,15 @@ $('#edit_stationroute_step2_modal').on('modal.show', function(event){ | @@ -316,12 +334,15 @@ $('#edit_stationroute_step2_modal').on('modal.show', function(event){ | ||
| 316 | } | 334 | } |
| 317 | }); | 335 | }); |
| 318 | $('#stationrouteSelect').empty(); | 336 | $('#stationrouteSelect').empty(); |
| 337 | + $('#detourStationRouteSelect').empty(); | ||
| 319 | // 初始化上一个路段拼音检索下拉框. | 338 | // 初始化上一个路段拼音检索下拉框. |
| 320 | initPinYinSelect2($('#stationrouteSelect'),paramsD,function(selector) { | 339 | initPinYinSelect2($('#stationrouteSelect'),paramsD,function(selector) { |
| 321 | - $('#stationrouteSelect').val(prevObj.id).select2(); | 340 | + $('#stationrouteSelect').val(prevObj.id).trigger('change'); |
| 322 | $('#stationMarkSelect').val(editStationRoute.stationMark); | 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,7 +144,7 @@ $('#edit_section_modal').on('modal.show', function(e, currentSection){ | ||
| 144 | params.sectionTime = 0; | 144 | params.sectionTime = 0; |
| 145 | error.hide(); | 145 | error.hide(); |
| 146 | if(params.sectionrouteCode == '请选择...') { | 146 | if(params.sectionrouteCode == '请选择...') { |
| 147 | - params.sectionrouteCode = 100; | 147 | + params.sectionrouteCode = 1; |
| 148 | } else { | 148 | } else { |
| 149 | params.sectionrouteCode = parseInt(params.sectionrouteCode) + 1; | 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,7 +1325,7 @@ var RoutesOperation = (function () { | ||
| 1325 | sectionRoute['line.id'] = lineId; | 1325 | sectionRoute['line.id'] = lineId; |
| 1326 | sectionRoute.sectionCode = sectionCode; | 1326 | sectionRoute.sectionCode = sectionCode; |
| 1327 | sectionRoute.roadCoding = ''; | 1327 | sectionRoute.roadCoding = ''; |
| 1328 | - sectionRoute.sectionrouteCode = 100; | 1328 | + sectionRoute.sectionrouteCode = 1; |
| 1329 | sectionRoute.sectionTime = 0; | 1329 | sectionRoute.sectionTime = 0; |
| 1330 | sectionRoute.sectionDistance = 0; | 1330 | sectionRoute.sectionDistance = 0; |
| 1331 | sectionRoute.speedLimit = 60; | 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> |