Commit 26a1b1437a90468e84db6e711c6108f6e70cd28f

Authored by ljq
1 parent 3def45f6

时刻表地铁接轨

src/main/java/com/bsth/controller/ttinfo/DtController.java 0 → 100644
  1 +package com.bsth.controller.ttinfo;
  2 +
  3 +import com.bsth.controller.BaseController;
  4 +import com.bsth.entity.ttinfo.ScheduleDt;
  5 +import com.bsth.service.ttinfo.DtService;
  6 +import org.springframework.beans.factory.annotation.Autowired;
  7 +import org.springframework.web.bind.annotation.RequestMapping;
  8 +import org.springframework.web.bind.annotation.RestController;
  9 +
  10 +import java.util.Map;
  11 +
  12 +@RestController
  13 +@RequestMapping("dt")
  14 +public class DtController extends BaseController<ScheduleDt, Integer> {
  15 +
  16 + @Autowired
  17 + private DtService dtService;
  18 + //分组查询地铁线路及站点
  19 + @RequestMapping("list_group")
  20 + public Map<String, Object> listGroup(){
  21 + return dtService.listGroup();
  22 + }
  23 +}
... ...
src/main/java/com/bsth/entity/ttinfo/ScheduleDt.java 0 → 100644
  1 +package com.bsth.entity.ttinfo;
  2 +
  3 +import javax.persistence.*;
  4 +
  5 +@Entity
  6 +@Table(name = "bsth_c_schedule_dt")
  7 +public class ScheduleDt {
  8 + @Id
  9 + @GeneratedValue(strategy = GenerationType.IDENTITY)
  10 + private Integer id;
  11 + private String line;
  12 + private String direction;
  13 + private String station;
  14 + private String trainNumber;
  15 + private String arrivalTime;
  16 +
  17 + public Integer getId() {
  18 + return id;
  19 + }
  20 +
  21 + public void setId(Integer id) {
  22 + this.id = id;
  23 + }
  24 +
  25 + public String getLine() {
  26 + return line;
  27 + }
  28 +
  29 + public void setLine(String line) {
  30 + this.line = line;
  31 + }
  32 +
  33 + public String getDirection() {
  34 + return direction;
  35 + }
  36 +
  37 + public void setDirection(String direction) {
  38 + this.direction = direction;
  39 + }
  40 +
  41 + public String getStation() {
  42 + return station;
  43 + }
  44 +
  45 + public void setStation(String station) {
  46 + this.station = station;
  47 + }
  48 +
  49 + public String getTrainNumber() {
  50 + return trainNumber;
  51 + }
  52 +
  53 + public void setTrainNumber(String trainNumber) {
  54 + this.trainNumber = trainNumber;
  55 + }
  56 +
  57 + public String getArrivalTime() {
  58 + return arrivalTime;
  59 + }
  60 +
  61 + public void setArrivalTime(String arrivalTime) {
  62 + this.arrivalTime = arrivalTime;
  63 + }
  64 +}
... ...
src/main/java/com/bsth/repository/ttinfo/DtRepository.java 0 → 100644
  1 +package com.bsth.repository.ttinfo;
  2 +
  3 +import com.bsth.entity.ttinfo.ScheduleDt;
  4 +import com.bsth.repository.BaseRepository;
  5 +import org.springframework.data.jpa.repository.Query;
  6 +import org.springframework.stereotype.Repository;
  7 +
  8 +import java.util.List;
  9 +import java.util.Map;
  10 +
  11 +@Repository
  12 +public interface DtRepository extends BaseRepository<ScheduleDt, Integer> {
  13 +
  14 + @Query(value = "SELECT line,direction,station from bsth_c_schedule_dt GROUP BY line,direction,station,order_station",nativeQuery=true)
  15 + List<Map> listGroup();
  16 +
  17 +}
... ...
src/main/java/com/bsth/service/ttinfo/DtService.java 0 → 100644
  1 +package com.bsth.service.ttinfo;
  2 +
  3 +import com.bsth.entity.ttinfo.ScheduleDt;
  4 +import com.bsth.service.BaseService;
  5 +
  6 +import java.util.Map;
  7 +
  8 +public interface DtService extends BaseService<ScheduleDt, Integer> {
  9 +
  10 + Map<String, Object> listGroup();
  11 +}
... ...
src/main/java/com/bsth/service/ttinfo/impl/DtServiceImpl.java 0 → 100644
  1 +package com.bsth.service.ttinfo.impl;
  2 +
  3 +import com.bsth.entity.ttinfo.ScheduleDt;
  4 +import com.bsth.repository.ttinfo.DtRepository;
  5 +import com.bsth.service.impl.BaseServiceImpl;
  6 +import com.bsth.service.ttinfo.DtService;
  7 +import org.springframework.beans.factory.annotation.Autowired;
  8 +import org.springframework.stereotype.Service;
  9 +
  10 +import java.util.ArrayList;
  11 +import java.util.HashMap;
  12 +import java.util.List;
  13 +import java.util.Map;
  14 +
  15 +@Service
  16 +public class DtServiceImpl extends BaseServiceImpl<ScheduleDt, Integer> implements DtService {
  17 +
  18 + @Autowired
  19 + private DtRepository dtRepository;
  20 + @Override
  21 + public Map<String, Object> listGroup() {
  22 + //防止后期加入新的地铁线路
  23 + List<Map> list = dtRepository.listGroup();
  24 + // 需将读取到的数据按照 "线路 - 上下行 - 站点" 的结构进行保存
  25 + Map<String, Object> lineMap = new HashMap<>(); // 储存线路
  26 + List<Map> directionList = new ArrayList<>();// 储存方向
  27 +
  28 + if (list != null) {
  29 + String currentLine = null;
  30 + for (Map item : list) {
  31 + String lineKey = item.get("line").toString();
  32 + String directionKey = item.get("direction").toString();
  33 +
  34 + if (lineKey != null && !lineKey.isEmpty()) {
  35 + // 如果线路发生变化,先将 directionList 保存到 lineMap 中,然后清空 directionList
  36 + if (currentLine != null && !currentLine.equals(lineKey)) {
  37 + lineMap.put(currentLine, directionList);
  38 + directionList = new ArrayList<>();
  39 + }
  40 + currentLine = lineKey;
  41 +
  42 + // 将当前方向数据放入 directionList
  43 + if (directionKey != null && !directionKey.isEmpty()) {
  44 + directionList.add(item);
  45 + }
  46 + }
  47 + }
  48 + // 循环结束后,将最后一组数据存入 lineMap
  49 + if (currentLine != null) {
  50 + lineMap.put(currentLine, directionList);
  51 + }
  52 + }
  53 +
  54 + return lineMap;
  55 + }
  56 +}
... ...
src/main/resources/static/pages/base/timesmodel/dt/dt.html 0 → 100644
  1 +<style>
  2 + /* Tailwind CSS 基础样式 */
  3 + *, ::before, ::after {
  4 + box-sizing: border-box;
  5 + border-width: 0;
  6 + border-style: solid;
  7 + border-color: #e5e7eb;
  8 + }
  9 +
  10 + html {
  11 + line-height: 1.5;
  12 + -webkit-text-size-adjust: 100%;
  13 + -moz-tab-size: 4;
  14 + tab-size: 4;
  15 + font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
  16 + }
  17 +
  18 + body {
  19 + margin: 0;
  20 + line-height: inherit;
  21 + }
  22 +
  23 + hr {
  24 + height: 0;
  25 + color: inherit;
  26 + border-top-width: 1px;
  27 + }
  28 +
  29 + abbr:where([title]) {
  30 + text-decoration: underline dotted;
  31 + }
  32 +
  33 + h1, h2, h3, h4, h5, h6 {
  34 + font-size: inherit;
  35 + font-weight: inherit;
  36 + }
  37 +
  38 + a {
  39 + color: inherit;
  40 + text-decoration: inherit;
  41 + }
  42 +
  43 + b, strong {
  44 + font-weight: bolder;
  45 + }
  46 +
  47 + code, kbd, samp, pre {
  48 + font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
  49 + font-size: 1em;
  50 + }
  51 +
  52 + small {
  53 + font-size: 80%;
  54 + }
  55 +
  56 + sub, sup {
  57 + font-size: 75%;
  58 + line-height: 0;
  59 + position: relative;
  60 + vertical-align: baseline;
  61 + }
  62 +
  63 + sub {
  64 + bottom: -0.25em;
  65 + }
  66 +
  67 + sup {
  68 + top: -0.5em;
  69 + }
  70 +
  71 + table {
  72 + text-indent: 0;
  73 + border-color: inherit;
  74 + border-collapse: collapse;
  75 + }
  76 +
  77 + button, input, optgroup, select, textarea {
  78 + font-family: inherit;
  79 + font-size: 100%;
  80 + line-height: inherit;
  81 + color: inherit;
  82 + margin: 0;
  83 + padding: 0;
  84 + }
  85 +
  86 + button, select {
  87 + text-transform: none;
  88 + }
  89 +
  90 + button, [type='button'], [type='reset'], [type='submit'] {
  91 + -webkit-appearance: button;
  92 + background-color: transparent;
  93 + background-image: none;
  94 + }
  95 +
  96 + :-moz-focusring {
  97 + outline: auto;
  98 + }
  99 +
  100 + :-moz-ui-invalid {
  101 + box-shadow: none;
  102 + }
  103 +
  104 + progress {
  105 + vertical-align: baseline;
  106 + }
  107 +
  108 + ::-webkit-inner-spin-button, ::-webkit-outer-spin-button {
  109 + height: auto;
  110 + }
  111 +
  112 + [type='search'] {
  113 + -webkit-appearance: textfield;
  114 + outline-offset: -2px;
  115 + }
  116 +
  117 + ::-webkit-search-decoration {
  118 + -webkit-appearance: none;
  119 + }
  120 +
  121 + ::-webkit-file-upload-button {
  122 + -webkit-appearance: button;
  123 + font: inherit;
  124 + }
  125 +
  126 + summary {
  127 + display: list-item;
  128 + }
  129 +
  130 + blockquote, dl, dd, h1, h2, h3, h4, h5, h6, hr, figure, p, pre {
  131 + margin: 0;
  132 + }
  133 +
  134 + fieldset {
  135 + margin: 0;
  136 + padding: 0;
  137 + }
  138 +
  139 + legend {
  140 + padding: 0;
  141 + }
  142 +
  143 + ol, ul, menu {
  144 + list-style: none;
  145 + margin: 0;
  146 + padding: 0;
  147 + }
  148 +
  149 + textarea {
  150 + resize: vertical;
  151 + }
  152 +
  153 + input::placeholder, textarea::placeholder {
  154 + opacity: 1;
  155 + color: #9ca3af;
  156 + }
  157 +
  158 + button, [role="button"] {
  159 + cursor: pointer;
  160 + }
  161 +
  162 + :disabled {
  163 + cursor: default;
  164 + }
  165 +
  166 + img, svg, video, canvas, audio, iframe, embed, object {
  167 + display: block;
  168 + vertical-align: middle;
  169 + }
  170 +
  171 + img, video {
  172 + max-width: 100%;
  173 + height: auto;
  174 + }
  175 +
  176 + [hidden] {
  177 + display: none;
  178 + }
  179 +
  180 + /* Tailwind 预检样式结束 */
  181 +
  182 + /* 容器类 */
  183 + .container {
  184 + width: 100%;
  185 + }
  186 +
  187 + @media (min-width: 640px) {
  188 + .container {
  189 + max-width: 640px;
  190 + }
  191 + }
  192 +
  193 + @media (min-width: 768px) {
  194 + .container {
  195 + max-width: 768px;
  196 + }
  197 + }
  198 +
  199 + @media (min-width: 1024px) {
  200 + .container {
  201 + max-width: 1024px;
  202 + }
  203 + }
  204 +
  205 + @media (min-width: 1280px) {
  206 + .container {
  207 + max-width: 1280px;
  208 + }
  209 + }
  210 +
  211 + @media (min-width: 1536px) {
  212 + .container {
  213 + max-width: 1536px;
  214 + }
  215 + }
  216 +
  217 + /* 布局类 */
  218 + .mx-auto {
  219 + margin-left: auto;
  220 + margin-right: auto;
  221 + }
  222 +
  223 + .flex {
  224 + display: flex;
  225 + }
  226 +
  227 + .grid {
  228 + display: grid;
  229 + }
  230 +
  231 + .hidden {
  232 + display: none;
  233 + }
  234 +
  235 + .items-center {
  236 + align-items: center;
  237 + }
  238 +
  239 + .justify-center {
  240 + justify-content: center;
  241 + }
  242 +
  243 + .justify-between {
  244 + justify-content: space-between;
  245 + }
  246 +
  247 + .space-y-2 > :not([hidden]) ~ :not([hidden]) {
  248 + margin-top: 0.5rem;
  249 + }
  250 +
  251 + .space-y-4 > :not([hidden]) ~ :not([hidden]) {
  252 + margin-top: 1rem;
  253 + }
  254 +
  255 + .space-y-6 > :not([hidden]) ~ :not([hidden]) {
  256 + margin-top: 1.5rem;
  257 + }
  258 +
  259 + .text-center {
  260 + text-align: center;
  261 + }
  262 +
  263 + .overflow-y-auto {
  264 + overflow-y: auto;
  265 + }
  266 +
  267 + .scrollbar-thin::-webkit-scrollbar {
  268 + width: 6px;
  269 + }
  270 +
  271 + .scrollbar-thumb-gray-300::-webkit-scrollbar-thumb {
  272 + background-color: #d1d5db;
  273 + border-radius: 3px;
  274 + }
  275 +
  276 + .scrollbar-track-gray-100::-webkit-scrollbar-track {
  277 + background-color: #f3f4f6;
  278 + }
  279 +
  280 + /* 网格布局 */
  281 + .grid-cols-1 {
  282 + grid-template-columns: repeat(1, minmax(0, 1fr));
  283 + }
  284 +
  285 + @media (min-width: 768px) {
  286 + .md\:grid-cols-2 {
  287 + grid-template-columns: repeat(2, minmax(0, 1fr));
  288 + }
  289 + }
  290 +
  291 + @media (min-width: 1024px) {
  292 + .lg\:grid-cols-2 {
  293 + grid-template-columns: repeat(2, minmax(0, 1fr));
  294 + }
  295 + .lg\:grid-cols-3 {
  296 + grid-template-columns: repeat(3, minmax(0, 1fr));
  297 + }
  298 + }
  299 +
  300 + .gap-4 {
  301 + gap: 1rem;
  302 + }
  303 +
  304 + .gap-6 {
  305 + gap: 1.5rem;
  306 + }
  307 +
  308 + /* 间距 */
  309 + .p-4 {
  310 + padding: 1rem;
  311 + }
  312 +
  313 + .p-6 {
  314 + padding: 1.5rem;
  315 + }
  316 +
  317 + .px-3 {
  318 + padding-left: 0.75rem;
  319 + padding-right: 0.75rem;
  320 + }
  321 +
  322 + .px-6 {
  323 + padding-left: 1.5rem;
  324 + padding-right: 1.5rem;
  325 + }
  326 +
  327 + .py-2 {
  328 + padding-top: 0.5rem;
  329 + padding-bottom: 0.5rem;
  330 + }
  331 +
  332 + .py-3 {
  333 + padding-top: 0.75rem;
  334 + padding-bottom: 0.75rem;
  335 + }
  336 +
  337 + .py-8 {
  338 + padding-top: 2rem;
  339 + padding-bottom: 2rem;
  340 + }
  341 +
  342 + .py-12 {
  343 + padding-top: 3rem;
  344 + padding-bottom: 3rem;
  345 + }
  346 +
  347 + .mb-4 {
  348 + margin-bottom: 1rem;
  349 + }
  350 +
  351 + .mb-8 {
  352 + margin-bottom: 2rem;
  353 + }
  354 +
  355 + .ml-3 {
  356 + margin-left: 0.75rem;
  357 + }
  358 +
  359 + .mr-2 {
  360 + margin-right: 0.5rem;
  361 + }
  362 +
  363 + .mr-3 {
  364 + margin-right: 0.75rem;
  365 + }
  366 +
  367 + .mt-2 {
  368 + margin-top: 0.5rem;
  369 + }
  370 +
  371 + .mt-8 {
  372 + margin-top: 2rem;
  373 + }
  374 +
  375 + /* 尺寸 */
  376 + .h-4 {
  377 + height: 1rem;
  378 + }
  379 +
  380 + .h-5 {
  381 + height: 1.25rem;
  382 + }
  383 +
  384 + .h-8 {
  385 + height: 2rem;
  386 + }
  387 +
  388 + .h-12 {
  389 + height: 3rem;
  390 + }
  391 +
  392 + .w-4 {
  393 + width: 1rem;
  394 + }
  395 +
  396 + .w-5 {
  397 + width: 1.25rem;
  398 + }
  399 +
  400 + .w-8 {
  401 + width: 2rem;
  402 + }
  403 +
  404 + .w-12 {
  405 + width: 3rem;
  406 + }
  407 +
  408 + .w-full {
  409 + width: 100%;
  410 + }
  411 +
  412 + .max-w-7xl {
  413 + max-width: 80rem;
  414 + }
  415 +
  416 + .max-h-96 {
  417 + max-height: 24rem;
  418 + }
  419 +
  420 + /* 边框 */
  421 + .border {
  422 + border-width: 1px;
  423 + }
  424 +
  425 + .border-b-2 {
  426 + border-bottom-width: 2px;
  427 + }
  428 +
  429 + .border-gray-200 {
  430 + border-color: #e5e7eb;
  431 + }
  432 +
  433 + .border-gray-300 {
  434 + border-color: #d1d5db;
  435 + }
  436 +
  437 + .border-blue-500 {
  438 + border-color: #3b82f6;
  439 + }
  440 +
  441 + .border-green-500 {
  442 + border-color: #22c55e;
  443 + }
  444 +
  445 + .rounded-lg {
  446 + border-radius: 0.5rem;
  447 + }
  448 +
  449 + .rounded-md {
  450 + border-radius: 0.375rem;
  451 + }
  452 +
  453 + .rounded-full {
  454 + border-radius: 9999px;
  455 + }
  456 +
  457 + /* 背景 */
  458 + .bg-white {
  459 + background-color: #ffffff;
  460 + }
  461 +
  462 + .bg-gray-50 {
  463 + background-color: #f9fafb;
  464 + }
  465 +
  466 + .bg-blue-50 {
  467 + background-color: #eff6ff;
  468 + }
  469 +
  470 + .bg-indigo-100 {
  471 + background-color: #e0e7ff;
  472 + }
  473 +
  474 + .bg-blue-100 {
  475 + background-color: #dbeafe;
  476 + }
  477 +
  478 + .bg-green-100 {
  479 + background-color: #dcfce7;
  480 + }
  481 +
  482 + .bg-blue-600 {
  483 + background-color: #2563eb;
  484 + }
  485 +
  486 + .bg-gradient-to-br {
  487 + background-image: linear-gradient(to bottom right, var(--tw-gradient-stops));
  488 + }
  489 +
  490 + .from-blue-50 {
  491 + --tw-gradient-from: #eff6ff;
  492 + --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to, rgb(239 246 255 / 0));
  493 + }
  494 +
  495 + .to-indigo-100 {
  496 + --tw-gradient-to: #e0e7ff;
  497 + }
  498 +
  499 + /* 文本 */
  500 + .text-2xl {
  501 + font-size: 1.5rem;
  502 + line-height: 2rem;
  503 + }
  504 +
  505 + .text-3xl {
  506 + font-size: 1.875rem;
  507 + line-height: 2.25rem;
  508 + }
  509 +
  510 + .text-sm {
  511 + font-size: 0.875rem;
  512 + line-height: 1.25rem;
  513 + }
  514 +
  515 + .text-lg {
  516 + font-size: 1.125rem;
  517 + line-height: 1.75rem;
  518 + }
  519 +
  520 + .text-xl {
  521 + font-size: 1.25rem;
  522 + line-height: 1.75rem;
  523 + }
  524 +
  525 + .text-xs {
  526 + font-size: 0.75rem;
  527 + line-height: 1rem;
  528 + }
  529 +
  530 + .font-bold {
  531 + font-weight: 700;
  532 + }
  533 +
  534 + .font-medium {
  535 + font-weight: 500;
  536 + }
  537 +
  538 + .font-semibold {
  539 + font-weight: 600;
  540 + }
  541 +
  542 + .text-gray-500 {
  543 + color: #6b7280;
  544 + }
  545 +
  546 + .text-gray-600 {
  547 + color: #4b5563;
  548 + }
  549 +
  550 + .text-gray-700 {
  551 + color: #374151;
  552 + }
  553 +
  554 + .text-gray-800 {
  555 + color: #1f2937;
  556 + }
  557 +
  558 + .text-blue-600 {
  559 + color: #2563eb;
  560 + }
  561 +
  562 + .text-blue-800 {
  563 + color: #1e40af;
  564 + }
  565 +
  566 + .text-green-600 {
  567 + color: #16a34a;
  568 + }
  569 +
  570 + .text-green-800 {
  571 + color: #15803d;
  572 + }
  573 +
  574 + .text-white {
  575 + color: #ffffff;
  576 + }
  577 +
  578 + .text-orange-600 {
  579 + color: #ea580c;
  580 + }
  581 +
  582 + /* 透明度 */
  583 + .opacity-75 {
  584 + opacity: 0.75;
  585 + }
  586 +
  587 + /* 阴影 */
  588 + .shadow-lg {
  589 + box-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
  590 + }
  591 +
  592 + /* 过渡 */
  593 + .transition-all {
  594 + transition-property: all;
  595 + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
  596 + transition-duration: 150ms;
  597 + }
  598 +
  599 + .transition-colors {
  600 + transition-property: color, background-color, border-color, text-decoration-color, fill, stroke;
  601 + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
  602 + transition-duration: 150ms;
  603 + }
  604 +
  605 + .duration-200 {
  606 + transition-duration: 200ms;
  607 + }
  608 +
  609 + /* 悬停效果 */
  610 + .hover\:bg-blue-700:hover {
  611 + background-color: #1d4ed8;
  612 + }
  613 +
  614 + .hover\:bg-gray-50:hover {
  615 + background-color: #f9fafb;
  616 + }
  617 +
  618 + /* 焦点效果 */
  619 + .focus\:outline-none:focus {
  620 + outline: 2px solid transparent;
  621 + outline-offset: 2px;
  622 + }
  623 +
  624 + .focus\:ring-2:focus {
  625 + box-shadow: 0 0 0 2px rgb(59 130 246 / 0.5);
  626 + }
  627 +
  628 + .focus\:ring-blue-500:focus {
  629 + --tw-ring-color: #3b82f6;
  630 + }
  631 +
  632 + .focus\:border-transparent:focus {
  633 + border-color: transparent;
  634 + }
  635 +
  636 + /* 动画 */
  637 + .animate-spin {
  638 + animation: spin 1s linear infinite;
  639 + }
  640 +
  641 + @keyframes spin {
  642 + from {
  643 + transform: rotate(0deg);
  644 + }
  645 + to {
  646 + transform: rotate(360deg);
  647 + }
  648 + }
  649 +
  650 + /* 自定义样式 */
  651 + .min-h-screen {
  652 + min-height: 100vh;
  653 + }
  654 + #dt_mobal{
  655 + margin-top: 120px;
  656 + max-width: 1200px;
  657 +
  658 + }
  659 + #dt_mobal .close{
  660 + width: 18px;
  661 + height: 18px;
  662 + margin-top: 5px;
  663 + }
  664 + .dt_bt{
  665 + background-color: #ffffff;
  666 + height: 60px;
  667 + }
  668 + </style>
  669 +<div class="dt max-w-7xl mx-auto modal fade" id="dt_mobal">
  670 +
  671 + <button type="button" class="close" data-dismiss="modal" aria-hidden="true"></button>
  672 + <!-- 标题区域 -->
  673 + <div class="text-center shadow-lg dt_bt">
  674 + <div class="flex items-center justify-center mb-4 dt_bt">
  675 + <i class="fa fa-subway text-blue-600 text-2xl mr-3"></i>
  676 + <h1 class="text-3xl font-bold text-gray-800">地铁公交接轨查询</h1>
  677 + <i class="fa fa-bus text-green-600 text-2xl ml-3"></i>
  678 + </div>
  679 + </div>
  680 + <!-- 搜索表单 -->
  681 + <div class="bg-white rounded-lg shadow-lg p-6 ">
  682 + <form id="searchForm" class="space-y-6">
  683 + <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
  684 + <!-- 公交线路搜索 -->
  685 + <div class="space-y-2">
  686 + <label class="flex items-center text-sm font-medium text-gray-700">
  687 + <i class="fa fa-bus text-green-600 mr-2"></i>
  688 + 公交线路
  689 + </label>
  690 + <input id="busLine" class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent">
  691 + </div>
  692 +
  693 + <!-- 公交方向 -->
  694 + <div class="space-y-2">
  695 + <label class="flex items-center text-sm font-medium text-gray-700">
  696 + <i class="fa fa-exchange-alt text-green-600 mr-2"></i>
  697 + 公交方向
  698 + </label>
  699 + <select id="busDirection" class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent">
  700 + <option value="">选择方向</option>
  701 + <option value="上行">上行</option>
  702 + <option value="下行">下行</option>
  703 + </select>
  704 + </div>
  705 +
  706 + <!-- 公交站点 -->
  707 + <div class="space-y-2">
  708 + <label class="flex items-center text-sm font-medium text-gray-700">
  709 + <i class="fa fa-bus text-green-600 mr-2"></i>
  710 + 公交站点
  711 + </label>
  712 + <select id="busStation" class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent">
  713 +
  714 + </select>
  715 + </div>
  716 +
  717 + <!-- 地铁线路 -->
  718 + <div class="space-y-2">
  719 + <label class="flex items-center text-sm font-medium text-gray-700">
  720 + <i class="fa fa-subway text-blue-600 mr-2"></i>
  721 + 地铁线路
  722 + </label>
  723 + <select id="metroLine" class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent">
  724 +
  725 + </select>
  726 + </div>
  727 +
  728 + <!-- 地铁方向 -->
  729 + <div class="space-y-2">
  730 + <label class="flex items-center text-sm font-medium text-gray-700">
  731 + <i class="fa fa-exchange-alt text-blue-600 mr-2"></i>
  732 + 地铁方向
  733 + </label>
  734 + <select id="metroDirection" class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent">
  735 +
  736 + </select>
  737 + </div>
  738 +
  739 + <!-- 地铁站点 -->
  740 + <div class="space-y-2">
  741 + <label class="flex items-center text-sm font-medium text-gray-700">
  742 + <i class="fa fa-subway text-blue-600 mr-2"></i>
  743 + 地铁站点
  744 + </label>
  745 + <select id="metroStation" class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent">
  746 +
  747 + </select>
  748 + </div>
  749 + </div>
  750 +
  751 + <!-- 搜索按钮 -->
  752 + <div class="flex justify-center">
  753 + <button type="submit" class="flex items-center px-6 py-3 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors duration-200 font-medium">
  754 + <i class="fa fa-search mr-2"></i>
  755 + 查询接轨时刻表
  756 + </button>
  757 + </div>
  758 + </form>
  759 + </div>
  760 +
  761 + <!-- 时刻表区域 -->
  762 + <div id="scheduleContainer" class="hidden grid grid-cols-1 lg:grid-cols-2 ">
  763 + <!-- 左侧时刻表 -->
  764 + <div class="bg-white rounded-lg shadow-lg p-6">
  765 + <div class="flex items-center mb-4">
  766 + <i class="fa fa-clock text-blue-600 mr-2"></i>
  767 + <h2 id="leftTitle" class="text-xl font-semibold text-gray-800"></h2>
  768 + </div>
  769 + <div id="leftSchedule" class="space-y-4">
  770 + <!-- 时刻表内容将通过JavaScript动态生成 -->
  771 + </div>
  772 + </div>
  773 +
  774 + <!-- 右侧时刻表 -->
  775 + <div class="bg-white rounded-lg shadow-lg p-6">
  776 + <div class="flex items-center mb-4">
  777 + <i class="fa fa-clock text-green-600 mr-2"></i>
  778 + <h2 id="rightTitle" class="text-xl font-semibold text-gray-800"></h2>
  779 + </div>
  780 + <div id="rightSchedule" class="space-y-4">
  781 + <!-- 时刻表内容将通过JavaScript动态生成 -->
  782 + </div>
  783 + </div>
  784 + </div>
  785 +
  786 + <!-- 加载状态 -->
  787 + <div id="loading" class="hidden flex items-center justify-center py-12">
  788 + <div class="animate-spin rounded-full h-12 w-12 border-b-2 border-blue-600"></div>
  789 + <span class="ml-3 text-gray-600">正在加载时刻表...</span>
  790 + </div>
  791 +
  792 +</div>
  793 +<script>
  794 + var ListDatal;
  795 + var DtDatal;
  796 + $('#dt_mobal').on('dtAddMobal.show', function(e,ListData){
  797 + // 加载延迟200毫秒显示mobal
  798 + ListDatal = ListData;
  799 + var line = ListData.line;
  800 + $("#busLine").val(line.name);
  801 + setTimeout(function(){$('#dt_mobal').modal({show : true,backdrop: 'static', keyboard: false});},200);
  802 + $get("/dt/list_group",null,function (data){
  803 + debugger
  804 + DtDatal = data;
  805 + var lineNames = Object.keys(data);
  806 + console.log('所有线路:', lineNames);
  807 + // 用于存储每个线路的方向(去重)
  808 + var lineDirectionsMap = {};
  809 + // 遍历所有线路
  810 + for (var i = 0; i < lineNames.length; i++) {
  811 + var lineName = lineNames[i]; // 例如:"16 号线"
  812 + var lineData = data[lineName]; // 这是该线路的数组 Array(26)
  813 +
  814 + console.log('线路名称:', lineName);
  815 + console.log('该线路数据数量:', lineData.length);
  816 +
  817 + // 初始化该线路的方向数组
  818 + lineDirectionsMap[lineName] = [];
  819 +
  820 + // 遍历该线路的所有数据,提取方向(去重)
  821 + var directionSet = new Set(); // 使用 Set 自动去重
  822 + for (var j = 0; j < lineData.length; j++) {
  823 + var item = lineData[j];
  824 +
  825 + if (item.direction && !directionSet.has(item.direction)) {
  826 + directionSet.add(item.direction);
  827 + lineDirectionsMap[lineName].push(item.direction);
  828 +
  829 + console.log('发现新方向 "' + item.direction + '" 在 ' + lineName);
  830 + }
  831 + }
  832 +
  833 + console.log(lineName + ' 的所有方向:', lineDirectionsMap[lineName]);
  834 +
  835 + // 添加线路到下拉框
  836 + $("#metroLine").append('<option value="' + lineName + '">' + lineName + '</option>');
  837 + }
  838 +
  839 + // 将方向和线路数据都保存到全局变量供后续使用
  840 + window.metroDataMap = data;
  841 + window.metroDirectionsMap = lineDirectionsMap;
  842 +
  843 + // 默认选中第一条线路时,自动加载其方向
  844 + if (lineNames.length > 0) {
  845 + var firstLineName = lineNames[0];
  846 + var directions = lineDirectionsMap[firstLineName];
  847 + $("#metroDirection").empty().append('<option value="">选择方向</option>');
  848 + for (var n in directions){
  849 + var direction = directions[n];
  850 + $("#metroDirection").append('<option value="' + direction + '">' + direction + '</option>');
  851 + }
  852 + }
  853 + })
  854 + });
  855 +
  856 + // 地铁线路改变事件
  857 + document.getElementById('metroLine').addEventListener('change', function() {
  858 + var metroLine = this.value;
  859 + // 清空后续选择
  860 + $("#metroDirection").empty().append('<option value="">选择方向</option>');
  861 + $("#metroStation").empty().append('<option value="">选择站点</option>');
  862 +
  863 + // 加载地铁方向
  864 + if (metroLine && window.metroDirectionsMap) {
  865 + var directions = window.metroDirectionsMap[metroLine] || [];
  866 +
  867 + if (directions.length > 0) {
  868 + var options = '<option value="">选择方向</option>';
  869 + directions.forEach(function(dir) {
  870 + options += '<option value="' + dir + '">' + dir + '</option>';
  871 + });
  872 + $("#metroDirection").empty().append(options);
  873 + }
  874 + }
  875 + });
  876 + // 地铁方向改变事件
  877 + document.getElementById('metroDirection').addEventListener('change', function() {
  878 + var metroLine = document.getElementById('metroLine').value;
  879 + var direction = this.value;
  880 + // 清空站点
  881 + $("#metroStation").empty().append('<option value="">选择站点</option>');
  882 +
  883 + // 加载地铁站点
  884 + if (metroLine && direction) {
  885 + loadMetroStations(metroLine, direction);
  886 + }
  887 + });
  888 +
  889 + // 公交方向改变事件
  890 + document.getElementById('busDirection').addEventListener('change', function() {
  891 + var lineName = document.getElementById('busLine').value;
  892 + var direction = this.value;
  893 + // 清空站点
  894 + $("#busStation").empty().append('<option value="">选择站点</option>');
  895 +
  896 + // 加载公交站点
  897 + if (lineName && direction) {
  898 + loadBusStations(lineName, direction);
  899 + }
  900 + });
  901 +
  902 +
  903 + // 加载公交站点(根据方向显示不同的站点列表)
  904 + function loadBusStations(lineName, direction) {
  905 + if (!lineName || !direction) {
  906 + $("#busStation").empty().append('<option value="">请先选择线路和方向</option>');
  907 + return;
  908 + }
  909 + // 从 ListDatal 中获取线路信息
  910 + if (ListDatal && ListDatal.line) {
  911 + var line = ListDatal.line;
  912 + var startStationName = line.startStationName; // 起点站
  913 + var endStationName = line.endStationName; // 终点站
  914 +
  915 + var options = '';
  916 +
  917 + if (direction === '上行') {
  918 + // 上行:只显示起点站(上行方向的站点)
  919 + options += '<option value="' + startStationName + '">' + startStationName + '</option>';
  920 + } else if (direction === '下行') {
  921 + // 下行:只显示终点站(下行方向的站点)
  922 + options += '<option value="' + endStationName + '">' + endStationName + '</option>';
  923 + }
  924 +
  925 + $("#busStation").empty().append(options);
  926 + } else {
  927 + // 如果没有线路数据,显示默认选项
  928 + $("#busStation").empty().append('<option value="">暂无站点数据</option>');
  929 + }
  930 + }
  931 +
  932 + function loadMetroStations(metroLine, direction) {
  933 + if (!metroLine || !direction) {
  934 + $("#metroStation").empty().append('<option value="">请先选择线路和方向</option>');
  935 + return;
  936 + }
  937 +
  938 + // 从已加载的数据中提取站点
  939 + var allData = window.metroDataMap;
  940 + if (!allData || !allData[metroLine]) {
  941 + $("#metroStation").empty().append('<option value="">暂无该线路数据</option>');
  942 + return;
  943 + }
  944 +
  945 + var lineData = allData[metroLine]; // 该线路的所有数据
  946 + var stationSet = new Set(); // 去重
  947 + var stations = [];
  948 +
  949 + // 筛选指定方向的数据并提取站点
  950 + for (var i = 0; i < lineData.length; i++) {
  951 + var item = lineData[i];
  952 + if (item.direction === direction && item.station && !stationSet.has(item.station)) {
  953 + stationSet.add(item.station);
  954 + stations.push(item.station);
  955 + }
  956 + }
  957 +
  958 + console.log(metroLine + ' - ' + direction + ' 的站点:', stations);
  959 +
  960 + var options = '';
  961 + if (stations.length > 0) {
  962 + stations.forEach(function(station) {
  963 + options += '<option value="' + station + '">' + station + '</option>';
  964 + });
  965 + } else {
  966 + options += '<option value="">该方向暂无站点</option>';
  967 + }
  968 +
  969 + $("#metroStation").empty().append(options);
  970 + }
  971 +
  972 + // 转换时间为分钟数
  973 + function convertTimeToMinutes(timeStr) {
  974 + if (typeof timeStr !== 'string') {
  975 + console.error('convertTimeToMinutes 接收到非字符串参数:', timeStr);
  976 + timeStr = String(timeStr);
  977 + }
  978 +
  979 + if (!/^\d{1,2}:\d{2}$/.test(timeStr)) {
  980 + console.error('时间格式不正确:', timeStr);
  981 + return 0;
  982 + }
  983 +
  984 + const [hours, minutes] = timeStr.split(':').map(Number);
  985 + return hours * 60 + minutes;
  986 + }
  987 +
  988 + // 找到最接近的时间
  989 + function findNearestTime(targetTime, timeArray) {
  990 + if (!timeArray.length) return null;
  991 +
  992 + const targetTimeStr = typeof targetTime === 'string' ? targetTime : targetTime.time;
  993 + const targetMinutes = convertTimeToMinutes(targetTimeStr);
  994 +
  995 + let nearest = timeArray[0];
  996 + let minDiff = Math.abs(convertTimeToMinutes(nearest.time) - targetMinutes);
  997 +
  998 + timeArray.forEach(item => {
  999 + const diff = Math.abs(convertTimeToMinutes(item.time) - targetMinutes);
  1000 + if (diff < minDiff) {
  1001 + minDiff = diff;
  1002 + nearest = item;
  1003 + }
  1004 + });
  1005 +
  1006 + return nearest;
  1007 + }
  1008 +
  1009 + // 渲染时刻表
  1010 + function renderSchedule(schedule, containerId, selectedTime, side) {
  1011 + const container = document.getElementById(containerId);
  1012 + container.innerHTML = '';
  1013 +
  1014 + if (!schedule || schedule.length === 0) {
  1015 + container.innerHTML = `
  1016 + <div class="text-center py-8 text-gray-500">
  1017 + <i class="fa fa-clock text-gray-300 text-4xl mb-4"></i>
  1018 + <p>暂无时刻表数据</p>
  1019 + <p class="text-sm">请选择搜索条件</p>
  1020 + </div>
  1021 + `;
  1022 + return;
  1023 + }
  1024 +
  1025 + // 添加时刻表头部信息
  1026 + const header = document.createElement('div');
  1027 + header.className = 'bg-gray-50 rounded-lg p-4 mb-4';
  1028 + header.innerHTML = `
  1029 + <div class="flex items-center justify-between">
  1030 + <div class="flex items-center">
  1031 + <i class="fa fa-map-marker-alt text-gray-500 mr-2"></i>
  1032 + <span class="text-sm text-gray-600">
  1033 + 共 ${schedule.length} 班次
  1034 + </span>
  1035 + </div>
  1036 + <div class="text-sm text-gray-500">
  1037 + 运营时间: ${schedule[0].time} - ${schedule[schedule.length - 1].time}
  1038 + </div>
  1039 + </div>
  1040 + `;
  1041 + container.appendChild(header);
  1042 +
  1043 + // 创建滚动容器
  1044 + const scrollContainer = document.createElement('div');
  1045 + scrollContainer.className = 'max-h-96 overflow-y-auto space-y-2 scrollbar-thin scrollbar-thumb-gray-300 scrollbar-track-gray-100';
  1046 +
  1047 + // 添加时刻表项
  1048 + schedule.forEach((timeItem, index) => {
  1049 + const timeElement = document.createElement('div');
  1050 + timeElement.className = `border rounded-lg p-4 cursor-pointer transition-all duration-200 ${
  1051 + selectedTime && selectedTime.time === timeItem.time
  1052 + ? side === 'left'
  1053 + ? 'bg-blue-100 border-blue-500 text-blue-800'
  1054 + : 'bg-green-100 border-green-500 text-green-800'
  1055 + : 'bg-white border-gray-200 text-gray-700 hover:bg-gray-50'
  1056 + }`;
  1057 + timeElement.dataset.time = timeItem.time;
  1058 + timeElement.dataset.index = index;
  1059 +
  1060 + timeElement.innerHTML = `
  1061 + <div class="flex items-center justify-between">
  1062 + <div class="flex items-center">
  1063 + <i class="fa fa-clock mr-3"></i>
  1064 + <div>
  1065 + <div class="font-semibold text-lg">
  1066 + ${timeItem.time}
  1067 + </div>
  1068 + <div class="text-sm opacity-75">
  1069 + ${timeItem.station}
  1070 + </div>
  1071 + </div>
  1072 + </div>
  1073 +
  1074 + <div class="flex items-center text-sm">
  1075 + <span class="mr-2">${timeItem.type}</span>
  1076 + <i class="fa fa-arrow-right"></i>
  1077 + </div>
  1078 + </div>
  1079 +
  1080 + <!-- 额外信息 -->
  1081 + ${timeItem.platform ? `<div class="mt-2 text-xs opacity-75">站台: ${timeItem.platform}</div>` : ''}
  1082 + ${timeItem.note ? `<div class="mt-1 text-xs text-orange-600">备注: ${timeItem.note}</div>` : ''}
  1083 + `;
  1084 +
  1085 + // 添加点击事件
  1086 + timeElement.addEventListener('click', () => {
  1087 + handleTimeSelect(side, timeItem);
  1088 + });
  1089 +
  1090 + scrollContainer.appendChild(timeElement);
  1091 + });
  1092 +
  1093 + container.appendChild(scrollContainer);
  1094 +
  1095 + // 添加底部提示
  1096 + const footer = document.createElement('div');
  1097 + footer.className = 'text-xs text-gray-500 text-center py-2';
  1098 + footer.textContent = `点击时间可${side === 'left' ? '联动选择右侧' : '联动选择左侧'}最接近时刻`;
  1099 + container.appendChild(footer);
  1100 + }
  1101 +
  1102 + // 处理时间选择
  1103 + function handleTimeSelect(side, time) {
  1104 + if (side === 'left') {
  1105 + selectedTime.left = time;
  1106 + selectedTime.right = findNearestTime(time, scheduleData.rightSchedule || []);
  1107 + } else {
  1108 + selectedTime.right = time;
  1109 + selectedTime.left = findNearestTime(time, scheduleData.leftSchedule || []);
  1110 + }
  1111 +
  1112 + // 重新渲染时刻表
  1113 + renderSchedule(scheduleData.leftSchedule, 'leftSchedule', selectedTime.left, 'left');
  1114 + renderSchedule(scheduleData.rightSchedule, 'rightSchedule', selectedTime.right, 'right');
  1115 +
  1116 + // 滚动到选中项
  1117 + setTimeout(() => {
  1118 + scrollToSelectedItem('left');
  1119 + scrollToSelectedItem('right');
  1120 + }, 100);
  1121 + }
  1122 +
  1123 + // 滚动到选中项
  1124 + function scrollToSelectedItem(side) {
  1125 + const container = document.querySelector(`#${side}Schedule .overflow-y-auto`);
  1126 + const selectedItem = document.querySelector(`#${side}Schedule [data-time="${side === 'left' ? selectedTime.left?.time : selectedTime.right?.time}"]`);
  1127 +
  1128 + if (container && selectedItem) {
  1129 + const containerRect = container.getBoundingClientRect();
  1130 + const itemRect = selectedItem.getBoundingClientRect();
  1131 +
  1132 + const scrollTop = selectedItem.offsetTop - container.offsetTop - (container.clientHeight / 2) + (selectedItem.clientHeight / 2);
  1133 +
  1134 + container.scrollTo({
  1135 + top: scrollTop,
  1136 + behavior: 'smooth'
  1137 + });
  1138 + }
  1139 + }
  1140 +
  1141 + // 获取表单数据
  1142 + function getFormData() {
  1143 + return {
  1144 + busLine: document.getElementById('busLine').value,
  1145 + busDirection: document.getElementById('busDirection').value,
  1146 + busStation: document.getElementById('busStation').value,
  1147 + metroLine: document.getElementById('metroLine').value,
  1148 + metroDirection: document.getElementById('metroDirection').value,
  1149 + metroStation: document.getElementById('metroStation').value
  1150 + };
  1151 + }
  1152 +
  1153 + // 显示加载状态
  1154 + function showLoading() {
  1155 + document.getElementById('loading').classList.remove('hidden');
  1156 + document.getElementById('scheduleContainer').classList.add('hidden');
  1157 + }
  1158 +
  1159 + // 隐藏加载状态
  1160 + function hideLoading() {
  1161 + document.getElementById('loading').classList.add('hidden');
  1162 + }
  1163 +
  1164 + // 显示时刻表
  1165 + function showSchedule() {
  1166 + document.getElementById('scheduleContainer').classList.remove('hidden');
  1167 + }
  1168 +
  1169 + // 模拟API调用
  1170 + function fetchScheduleData(searchParams) {
  1171 + return new Promise((resolve) => {
  1172 + const { busLine, busDirection, busStation, metroLine, metroDirection, metroStation } = searchParams;
  1173 +
  1174 + const busSchedule =[];
  1175 + const metroSchedule = [];
  1176 +
  1177 + $.get("/dt/all",{line_eq:metroLine,direction_eq:metroDirection,station_eq:metroStation},function(rs){
  1178 + for (var i in rs){
  1179 + var item = rs[i];
  1180 + metroSchedule.push({
  1181 + time: item.arrivalTime,
  1182 + station: item.station,
  1183 + type: '地铁',
  1184 + direction: metroDirection
  1185 + });
  1186 + }
  1187 + // 获取公交数据 - 从 ListDatal 读取
  1188 + var busDataList = [];
  1189 + if (busDirection === '上行') {
  1190 + busDataList = ListDatal.ListUpData || [];
  1191 + } else if (busDirection === '下行') {
  1192 + busDataList = ListDatal.ListDoData || [];
  1193 + }
  1194 + debugger;
  1195 + var line = ListDatal.line;
  1196 + // 筛选指定站点的数据
  1197 + for (var i = 0; i < busDataList.length; i++) {
  1198 + var item = busDataList[i];
  1199 + busSchedule.push({
  1200 + time: item.time,
  1201 + station: busStation,
  1202 + type: '公交',
  1203 + direction: busDirection
  1204 + });
  1205 +
  1206 + }
  1207 +
  1208 + resolve({
  1209 + leftTitle: `${busLine}路公交 ${busDirection}方向${busStation ? ` - ${busStation}` : ''}`,
  1210 + rightTitle: `${metroLine} ${metroDirection}方向${metroStation ? ` - ${metroStation}` : ''}`,
  1211 + leftSchedule: busSchedule,
  1212 + rightSchedule: metroSchedule
  1213 + });
  1214 + })
  1215 +
  1216 + });
  1217 + }
  1218 +
  1219 + // 初始化
  1220 + let scheduleData = null;
  1221 + let selectedTime = {
  1222 + left: null,
  1223 + right: null
  1224 + };
  1225 +
  1226 + // 表单提交事件
  1227 + document.getElementById('searchForm').addEventListener('submit', async function(e) {
  1228 + e.preventDefault();
  1229 +
  1230 + const formData = getFormData();
  1231 +
  1232 + // 验证必填字段
  1233 + if (!formData.busLine || !formData.busDirection || !formData.metroDirection) {
  1234 + alert('请填写公交线路、公交方向和地铁方向');
  1235 + return;
  1236 + }
  1237 +
  1238 + // 重置选中时间
  1239 + selectedTime = {
  1240 + left: null,
  1241 + right: null
  1242 + };
  1243 +
  1244 + // 显示加载状态
  1245 + showLoading();
  1246 +
  1247 + try {
  1248 + // 获取数据
  1249 + scheduleData = await fetchScheduleData(formData);
  1250 +
  1251 + if (scheduleData) {
  1252 + // 更新标题
  1253 + document.getElementById('leftTitle').textContent = scheduleData.leftTitle;
  1254 + document.getElementById('rightTitle').textContent = scheduleData.rightTitle;
  1255 +
  1256 + // 渲染时刻表
  1257 + renderSchedule(scheduleData.leftSchedule, 'leftSchedule', selectedTime.left, 'left');
  1258 + renderSchedule(scheduleData.rightSchedule, 'rightSchedule', selectedTime.right, 'right');
  1259 +
  1260 + // 显示时刻表
  1261 + showSchedule();
  1262 + } else {
  1263 + alert('未找到相关时刻表数据');
  1264 + }
  1265 + } catch (error) {
  1266 + console.error('获取时刻表数据失败:', error);
  1267 + alert('获取时刻表数据失败,请稍后重试');
  1268 + } finally {
  1269 + // 隐藏加载状态
  1270 + hideLoading();
  1271 + }
  1272 + });
  1273 +</script>
0 1274 \ No newline at end of file
... ...
src/main/resources/static/pages/base/timesmodel/gantt.html
... ... @@ -52,6 +52,10 @@
52 52 <div class="btn-group btn-group-devided " data-toggle="buttons">
53 53 <a class="btn btn-circle blue parambtns" href="javascript:;" data-pjax><i class="fa fa-list-ol" aria-hidden="true"></i> 只看实际</a>
54 54 </div>
  55 +
  56 + <div class="btn-group btn-group-devided " data-toggle="buttons">
  57 + <a class="btn btn-circle blue dt_param" href="javascript:;" data-pjax><i class="fa fa-list-ol" aria-hidden="true"></i> 地铁接轨</a>
  58 + </div>
55 59 <!-- <div class="btn-group btn-group-devided countbtn" data-toggle="buttons">
56 60 <a class="btn btn-circle blue jhpbonsjpb" href="javascript:;" data-pjax><i class="fa fa-database"></i> 计划排班与实际班次</a>
57 61 </div>-->
... ...
src/main/resources/static/pages/base/timesmodel/js/systemTools.js
... ... @@ -595,6 +595,65 @@ $(&#39;.parambtns&#39;).on(&#39;click&#39;,function (){
595 595 })
596 596 })
597 597  
  598 +
  599 +$('.dt_param').on('click',function (){
  600 + var historyData = echartsDrawGTT.getHistoryData(),
  601 + list = historyData[0];
  602 + var ListData ={};
  603 + var ListUpData =[];
  604 + var ListDoData =[];
  605 + //区分上下行班次 --线路 上下行 站点名称 时间
  606 + for(var i = 0;i<list.length;i++) {
  607 + var bcObj = list[i].value;
  608 + if (bcObj[6]=='normal') {
  609 + if (bcObj[8] == "1") { //上下行
  610 + ListUpData.push({time: getHoursAndMinutes(bcObj[1])})
  611 + } else {
  612 + ListDoData.push({time: getHoursAndMinutes(bcObj[1])})
  613 + }
  614 + }
  615 + }
  616 + var lineid = list[0].value[12];
  617 + ListUpData.sort(function(a,b){
  618 + return a.time.localeCompare(b.time);
  619 + });
  620 + ListDoData.sort(function(a,b){
  621 + return a.time.localeCompare(b.time);
  622 + });
  623 + // 查询线路编码的顺延号
  624 + $get('/line/' + lineid ,null,function(line){
  625 + ListData = {
  626 + "line":line,
  627 + "ListUpData":ListUpData,
  628 + "ListDoData":ListDoData
  629 + }
  630 + // 弹出层mobal页面
  631 + $.get('/pages/base/timesmodel/dt/dt.html', function(m){
  632 + $(pjaxContainer).append(m);
  633 + /* // 关闭左侧栏
  634 + if (!$('body').hasClass('page-sidebar-closed'))
  635 + $('.menu-toggler.sidebar-toggler').click();*/
  636 + // 规定被选元素要触发的事件。可以使自定义事件(使用 bind() 函数来附加),或者任何标准事件。
  637 + $('#dt_mobal').trigger('dtAddMobal.show',[ListData]);
  638 + });
  639 + });
  640 +
  641 +
  642 +
  643 +
  644 +});
  645 +// 时间戳转时间(时间:分钟)
  646 +var getHoursAndMinutes = function (timestamp) {
  647 + var date = new Date(timestamp);
  648 + var Hours = swallowTow(date.getHours());
  649 + var Minutes = swallowTow(date.getMinutes());
  650 + return Hours+":"+Minutes;
  651 +};
  652 +// 补齐两位
  653 +var swallowTow = function (date) {
  654 + return date>=10?date:(date="0"+date);
  655 +};
  656 +
598 657 /**
599 658 * @description : (TODO) 监听保存数据事件.
600 659 *
... ...