吉安感知网项目-前端
shuishen
2026-01-08 8e504b07e0070e50e2e04c46d783ca2df2794657
feat:数据驾驶舱页面搭建
7 files modified
11 files added
3055 ■■■■ changed files
applications/drone-command/env/.env.development 12 ●●●●● patch | view | raw | blame | history
applications/drone-command/src/assets/images/dataCockpit/fzsb.png patch | view | raw | blame | history
applications/drone-command/src/assets/images/dataCockpit/title-bg.png patch | view | raw | blame | history
applications/drone-command/src/assets/images/dataCockpit/zcsb.png patch | view | raw | blame | history
applications/drone-command/src/styles/element-ui.scss 1724 ●●●●● patch | view | raw | blame | history
applications/drone-command/src/views/dataCockpit/components/CenterContainer.vue 14 ●●●● patch | view | raw | blame | history
applications/drone-command/src/views/dataCockpit/components/EquipmentWarning.vue 61 ●●●●● patch | view | raw | blame | history
applications/drone-command/src/views/dataCockpit/components/HistoryWarning.vue 136 ●●●●● patch | view | raw | blame | history
applications/drone-command/src/views/dataCockpit/components/LeftContainer.vue 95 ●●●●● patch | view | raw | blame | history
applications/drone-command/src/views/dataCockpit/components/MapContainer.vue 2 ●●● patch | view | raw | blame | history
applications/drone-command/src/views/dataCockpit/components/RealWarning.vue 76 ●●●●● patch | view | raw | blame | history
applications/drone-command/src/views/dataCockpit/components/RightContainer.vue 204 ●●●●● patch | view | raw | blame | history
applications/drone-command/src/views/dataCockpit/components/templateComponents/EquipmentTemplate.vue 171 ●●●●● patch | view | raw | blame | history
applications/drone-command/src/views/dataCockpit/components/templateComponents/HistoryTemplate.vue 110 ●●●●● patch | view | raw | blame | history
applications/drone-command/src/views/dataCockpit/components/templateComponents/RealEquipmentTemplate.vue 199 ●●●●● patch | view | raw | blame | history
applications/drone-command/src/views/dataCockpit/components/templateComponents/RealTemplate.vue 204 ●●●●● patch | view | raw | blame | history
applications/drone-command/src/views/dataCockpit/components/templateComponents/TitleTemplate.vue 43 ●●●●● patch | view | raw | blame | history
applications/drone-command/src/views/dataCockpit/index.vue 4 ●●● patch | view | raw | blame | history
applications/drone-command/env/.env.development
@@ -1,3 +1,13 @@
###
 # @Author       : yuan
 # @Date         : 2026-01-07 14:58:30
 # @LastEditors  : yuan
 # @LastEditTime : 2026-01-08 15:14:52
 # @FilePath     : \applications\drone-command\env\.env.development
 # @Description  :
 # Copyright 2026 OBKoro1, All Rights Reserved.
 # 2026-01-07 14:58:30
###
NODE_ENV = 'development'
#开发环境配置
@@ -6,7 +16,7 @@
#开发环境代理地址(推荐本地新建文件 .env.development.local 来进行覆盖)
# VITE_APP_URL = https://wrj.shuixiongit.com/api
VITE_APP_URL= http://192.168.1.33:81
VITE_APP_URL= http://192.168.1.33
#新大屏地址
VITE_APP_DASHBOARD_URL = 'https://wrj.shuixiongit.com/command-center-dashboard/'
applications/drone-command/src/assets/images/dataCockpit/fzsb.png
applications/drone-command/src/assets/images/dataCockpit/title-bg.png
applications/drone-command/src/assets/images/dataCockpit/zcsb.png
applications/drone-command/src/styles/element-ui.scss
@@ -1,736 +1,1022 @@
.el-card.is-always-shadow {
    box-shadow: none;
    border: none !important;
  }
  .el-menu {
    border-right: none;
  }
  .el-message__icon,
  .el-message__content {
    display: inline-block;
  }
  .el-date-editor .el-range-input,
  .el-date-editor .el-range-separator {
    height: auto;
    overflow: hidden;
  }
  .el-dialog__wrapper {
    z-index: 2048;
  }
  .el-col {
    margin-bottom: 8px;
  }
  .el-main {
    padding: 0 !important;
  }
  .el-dropdown-menu__item--divided:before,
  .el-menu,
  .el-menu--horizontal>.el-menu-item:not(.is-disabled):focus,
  .el-menu--horizontal>.el-menu-item:not(.is-disabled):hover,
  .el-menu--horizontal>.el-sub-menu .el-sub-menu__title:hover {
    background-color: transparent;
  }
  .el-dropdown-menu__item--divided:before,
  .el-menu,
  .el-menu--horizontal>.el-menu-item:not(.is-disabled):focus,
  .el-menu--horizontal>.el-menu-item:not(.is-disabled):hover,
  .el-menu--horizontal>.el-sub-menu .el-sub-menu__title:hover {
    background-color: transparent !important;
  }
  .el-collapse-item__header {
    height: auto;
    overflow: hidden;
  }
  .el-button.is-text:not(.is-disabled):active {
    background-color: transparent;
  }
  .el-button.is-text:not(.is-disabled):focus,
  .el-button.is-text:not(.is-disabled):hover {
    background-color: transparent;
  }
  .avue-icon i,
  .avue-icon svg {
    line-height: 20px;
  }
  .avue--detail .el-form-item {
    background-color: #fafafa;
  }
  .showFullScreenDlg {
    display: flex;
    justify-content: space-between;
    .el-dialog {
      position: relative;
      padding: 0;
      overflow: hidden;
      .el-dialog__body {
        width: 100%;
        height: 100%;
        iframe {
          width: 100%;
          height: 100%;
        }
      }
      .el-dialog__header {
        height: 0;
        overflow: hidden;
        padding: 0;
        .el-dialog__headerbtn {
          position: absolute;
          left: 0;
          //top: 14px;
          .el-dialog__close {
            color: #fff;
            font-size: 35px;
            z-index: 99;
          }
        }
      }
    }
  }
  .ztzf-drawer-body-basic-container {
    .el-drawer__header {
      margin-bottom: 0;
    }
    .el-drawer__body {
      display: flex;
      flex-direction: column;
    }
  }
  .ztzf-el-card__body {
     .el-card__body {
      .avue-form{
      padding: 0;}}
  }
  .ztzf-public-general-avue-crud {
    .el-table {
      tr {
        min-height: 30px !important;
        line-height: 30px !important;
        box-sizing: border-box !important;
      }
      tr th,
      tr td {
        padding: 6px 0 !important;
        min-height: 30px !important;
        line-height: 30px !important;
        box-sizing: border-box !important;
        div.cell {
          min-height: 30px !important;
          line-height: 30px !important;
        }
      }
    }
  }
  .ztzf-layer-input {
      .el-input__wrapper {
          padding: 0 8px !important;
          // background: #2D2D2D;
      background-color: transparent !important;
          box-shadow: none !important;
          border: 1px solid #fff;
          .el-input__inner {
              color: #ffffff;
              &::placeholder {
          color: rgba(255,255,255,0.37);
              }
          }
      }
      &.is-disabled {
          .el-input__wrapper {
              background-color: #012a50;
          }
      }
  }
  .ztzf-button {
    background-color: transparent !important;
    color: #fff !important;
  }
  .ztzf-el-tree {
    background-color: transparent !important;
    --el-tree-node-hover-bg-color:transparent !important;
    color: #fff !important;
  }
  .ztzf-layer-search {
    color: #fff !important;
    background-color: transparent !important;
    .el-select__wrapper {
      background-color: transparent !important;
    }
    .el-select__popper.el-popper {
      background-color: transparent !important;
    }
    .el-popper.is-light {
      background-color: transparent !important;
    }
    .el-select__placeholder {
      &.is-transparent {
        color: rgba(255,255,255,0.37) !important;
      }
      &.is-disabled {
        color: rgba(255,255,255,0.37) !important;
      }
    }
    .el-select__selected-item {
      color: #ffffff !important;
      &.is-disabled {
        color: rgba(255,255,255,0.37) !important;
        z-index: 99;
      }
    }
  }
  .ztzf-select-popper.el-select__popper {
      border:#2D2D2D !important;
      .el-select-dropdown {
          overflow-x: hidden !important;
          .el-scrollbar {
              .el-select-dropdown__wrap {
                  background: linear-gradient(180deg, rgba(13, 53, 86, 0.85) 0%, rgba(1, 35, 80, 0.85) 100%);
                  border-radius: 0px 0px 8px 8px;
                  border: 1px solid;
          border-image: linear-gradient(180deg, #fff, #fff) 1 1;
                  overflow-x: hidden !important;
                  margin-right: 0 !important;
                  .el-select-dropdown__list {
                      padding: 0 !important;
                      .el-select-dropdown__item {
                          background: #2D2D2D !important;
                          color: white;
                          &.hover {
                              background-color: #2D2D2D !important;
                              color: white;
                          }
                          &.selected {
                              color: #fff !important;
                              font-weight: 700;
                          }
                      }
                  }
              }
          }
          .el-select-dropdown__empty {
              background: #2D2D2D;
              border-radius: 0px 0px 8px 8px;
              border: 1px solid;
              border-image: linear-gradient(180deg, #fff, #fff) 1 1;
          }
      }
      .el-popper__arrow::before {
          background: #2D2D2D !important;
          border: 1px solid #fff !important;
      }
  }
  //时间日期选择器
  .ztzf-layer-date-picker {
      box-shadow: none !important;
      background: transparent;
      border: 1px solid #fff;
      border-radius: 5px;
      .el-range-editor.is-disabled input {
          background-color: transparent !important;
      }
      .el-range-editor.is-disabled {
          background-color: transparent !important;
      }
      .el-input__wrapper {
          box-shadow: none !important;
          background-color: transparent !important;
      width: 300px;
          &.is-focus {
              box-shadow: none !important;
          }
      }
      .el-range-input {
          color: #fff;
          &::placeholder {
              color: rgba(255, 255, 255, 0.37);
          }
      }
      .el-range-separator {
          color: #ffffff;
      }
  }
  // 日期下拉框
  .ztzf-layer-date-picker-popper {
      background: #012350 !important;
      border: 1px solid !important;
      border-radius: 0px 0px 8px 8px;
      border-image: linear-gradient(180deg, rgba(255, 255, 255, 0), rgba(115, 192, 255, 1)) 1 1 !important;
      .el-picker-panel .el-time-panel{
          background: #012350 !important;
      }
      .el-time-spinner__item {
      color: #fff !important;}
      .el-time-spinner__item:hover:not(.is-disabled):not(.is-active){
          background: transparent !important;
      }
      .el-picker-panel {
          .el-picker-panel__body-wrapper {
              .el-picker-panel__body {
                  background: #012350 !important;
                  color: #fff !important;
                  .el-date-picker__time-header {
                      border: none;
                      .el-date-picker__editor-wrap {
                          .el-time-panel {
                              background: #012350 !important;
                              border-radius: 0px 0px 8px 8px;
                              border: 1px solid !important;
                              border-image: linear-gradient(180deg, rgba(255, 255, 255, 0), rgba(115, 192, 255, 1)) 1 1 !important;
                              // 将 time-picker-popper 的样式移到这里
                              .el-time-panel__header {
                                  background: #012350 !important;
                                  color: #ffffff !important;
                                  border-bottom: 1px solid rgba(255, 255, 255, 0.37) !important;
                              }
                              .el-time-panel__content {
                                  .el-time-spinner__item {
                                      color: #e6e6e6 !important;
                                      &:hover {
                                          background: #012350 !important;
                                      }
                                      &.active {
                                          color: #479dff !important;
                                          font-weight: bold;
                                      }
                                  }
                              }
                              .el-time-panel__footer {
                                  background: #012350 !important;
                                  border-top: 1px solid rgba(71, 157, 255, 0.3) !important;
                                  .el-button {
                                      color: #fff !important;
                                      &:hover {
                                          color: #479dff !important;
                                      }
                                  }
                                  .el-time-panel__btn.cancel {
                                      color: #fff !important;
                                      &:hover {
                                          color: #fff !important;
                                      }
                                  }
                              }
                          }
                      }
                  }
                  .el-picker-panel__content {
                      .el-date-range-picker__header {
                          .el-picker-panel__icon-btn {
                              color: #fff !important;
                              &:hover {
                                  color: var(--el-color-primary) !important;
                              }
                              .el-icon {
                                  &::before {
                                      color: inherit !important;
                                  }
                              }
                          }
                          & > div {
                              span {
                                  color: #fff !important;
                              }
                          }
                      }
                      .el-date-table {
                          th {
                              color: #fff !important;
                          }
                          td.disabled div {
                              background-color: #00193b !important;
                              color: #505050 !important;
                              cursor: not-allowed;
                          }
                          // td:hover,
                          // td.current:not(.disabled) {
                          //     background: rgba(60, 121, 202) !important;
                          //     color: white !important;
                          // }
                          td.start-date span,
                          td.start-date span,
                          td.end-date span {
                              background-color: #012350 !important;
                          }
                          td.in-range div,
                          td.in-range div:hover,
                          &.is-week-mode .el-date-table__row.current div,
                          &.is-week-mode .el-date-table__row:hover div {
                              background-color: rgba(60, 121, 202) !important;
                          }
                      }
                  }
              }
          }
      }
      .el-popper__arrow {
          &::before {
              background: #0d3556 !important;
              border: 1px solid #0d3556 !important;
              box-sizing: border-box;
          }
      }
      .el-picker-panel__sidebar {
          background: #012350;
          color: #fff;
          .el-picker-panel__shortcut {
              color: #ffffff;
          }
      }
      .el-picker-panel__body {
          .el-input.is-disabled .el-input__wrapper {
              background: #012350;
              box-shadow: 0 0 0 0.1rem#409eff;
              color: #fff;
              .el-input__inner {
                  color: #fff !important;
              }
          }
          .el-button.is-disabled,
          .el-button.is-disabled:hover {
              background: #012350;
          }
          .el-input__wrapper {
              background: #012350;
              box-shadow: 0 0 0 0.1rem#409eff;
              color: #fff;
              .el-input__inner {
                  color: #fff !important;
              }
          }
      }
      .el-picker-panel__footer {
          background: #012350;
          color: #fff;
          border-top: none;
          .el-button--small {
              box-shadow: 0 0 0 0.1rem#409eff;
              background-color: #012350;
              color: #fff;
              border: none;
              &:hover {
                  background-color: #012350;
                  color: #fff;
                  border-color: #409eff;
              }
          }
      }
  }
  .ztzf-layer-time-picker-popper {
    background: rgba(0,0,0,0.8) !important;
      border-radius: 0px 0px 8px 8px;
      border: 1px solid !important;
      border-image: linear-gradient(180deg, rgba(255, 255, 255, 0), rgba(115, 192, 255, 1)) 1 1 !important;
      .el-popper__arrow::before {
          background: rgba(0,0,0,0.8) !important;
          border: 1px solid #479dff !important;
      }
      .el-time-panel__header {
          background: rgba(0,0,0,0.8) !important;
          color: #ffffff !important;
          border-bottom: 1px solid rgba(71, 157, 255, 0.3) !important;
      }
      .el-time-panel__content {
          // background: #012350 !important;
          .el-time-spinner__item {
              color: #e6e6e6 !important;
              &:hover {
                  background: rgba(71, 157, 255, 0.3) !important;
              }
              &.active {
                  color: #479dff !important;
                  font-weight: bold;
              }
          }
      }
      .el-time-panel__footer {
          background: rgba(0,0,0,0.8) !important;
          border-top: 1px solid rgba(71, 157, 255, 0.3) !important;
          .el-button {
              color: #fff !important;
              &:hover {
                  color: #479dff !important;
              }
          }
          .el-time-panel__btn.cancel {
              color: #fff !important;
              &:hover {
                  color: #fff !important;
              }
          }
      }
  }
    box-shadow: none;
    border: none !important;
}
.el-menu {
    border-right: none;
}
.el-message__icon,
.el-message__content {
    display: inline-block;
}
.el-date-editor .el-range-input,
.el-date-editor .el-range-separator {
    height: auto;
    overflow: hidden;
}
.el-dialog__wrapper {
    z-index: 2048;
}
.el-col {
    margin-bottom: 8px;
}
.el-main {
    padding: 0 !important;
}
.el-dropdown-menu__item--divided:before,
.el-menu,
.el-menu--horizontal>.el-menu-item:not(.is-disabled):focus,
.el-menu--horizontal>.el-menu-item:not(.is-disabled):hover,
.el-menu--horizontal>.el-sub-menu .el-sub-menu__title:hover {
    background-color: transparent;
}
.el-dropdown-menu__item--divided:before,
.el-menu,
.el-menu--horizontal>.el-menu-item:not(.is-disabled):focus,
.el-menu--horizontal>.el-menu-item:not(.is-disabled):hover,
.el-menu--horizontal>.el-sub-menu .el-sub-menu__title:hover {
    background-color: transparent !important;
}
.el-collapse-item__header {
    height: auto;
    overflow: hidden;
}
.el-button.is-text:not(.is-disabled):active {
    background-color: transparent;
}
.el-button.is-text:not(.is-disabled):focus,
.el-button.is-text:not(.is-disabled):hover {
    background-color: transparent;
}
.avue-icon i,
.avue-icon svg {
    line-height: 20px;
}
.avue--detail .el-form-item {
    background-color: #fafafa;
}
.showFullScreenDlg {
    display: flex;
    justify-content: space-between;
    .el-dialog {
        position: relative;
        padding: 0;
        overflow: hidden;
        .el-dialog__body {
            width: 100%;
            height: 100%;
            iframe {
                width: 100%;
                height: 100%;
            }
        }
        .el-dialog__header {
            height: 0;
            overflow: hidden;
            padding: 0;
            .el-dialog__headerbtn {
                position: absolute;
                left: 0;
                //top: 14px;
                .el-dialog__close {
                    color: #fff;
                    font-size: 35px;
                    z-index: 99;
                }
            }
        }
    }
}
.ztzf-drawer-body-basic-container {
    .el-drawer__header {
        margin-bottom: 0;
    }
    .el-drawer__body {
        display: flex;
        flex-direction: column;
    }
}
.ztzf-el-card__body {
    .el-card__body {
        .avue-form {
            padding: 0;
        }
    }
}
.ztzf-public-general-avue-crud {
    .el-table {
        tr {
            min-height: 30px !important;
            line-height: 30px !important;
            box-sizing: border-box !important;
        }
        tr th,
        tr td {
            padding: 6px 0 !important;
            min-height: 30px !important;
            line-height: 30px !important;
            box-sizing: border-box !important;
            div.cell {
                min-height: 30px !important;
                line-height: 30px !important;
            }
        }
    }
}
.ztzf-layer-input {
    .el-input__wrapper {
        padding: 0 8px !important;
        // background: #2D2D2D;
        background-color: transparent !important;
        box-shadow: none !important;
        border: 1px solid #fff;
        .el-input__inner {
            color: #ffffff;
            &::placeholder {
                color: rgba(255, 255, 255, 0.37);
            }
        }
    }
    &.is-disabled {
        .el-input__wrapper {
            background-color: #012a50;
        }
    }
}
.ztzf-button {
    background-color: transparent !important;
    color: #fff !important;
}
.ztzf-el-tree {
    background-color: transparent !important;
    --el-tree-node-hover-bg-color: transparent !important;
    color: #fff !important;
}
.ztzf-layer-search {
    color: #fff !important;
    background-color: transparent !important;
    .el-select__wrapper {
        background-color: transparent !important;
    }
    .el-select__popper.el-popper {
        background-color: transparent !important;
    }
    .el-popper.is-light {
        background-color: transparent !important;
    }
    .el-select__placeholder {
        &.is-transparent {
            color: rgba(255, 255, 255, 0.37) !important;
        }
        &.is-disabled {
            color: rgba(255, 255, 255, 0.37) !important;
        }
    }
    .el-select__selected-item {
        color: #ffffff !important;
        &.is-disabled {
            color: rgba(255, 255, 255, 0.37) !important;
            z-index: 99;
        }
    }
}
.ztzf-select-popper.el-select__popper {
    border: #2D2D2D !important;
    .el-select-dropdown {
        overflow-x: hidden !important;
        .el-scrollbar {
            .el-select-dropdown__wrap {
                background: linear-gradient(180deg, rgba(13, 53, 86, 0.85) 0%, rgba(1, 35, 80, 0.85) 100%);
                border-radius: 0px 0px 8px 8px;
                border: 1px solid;
                border-image: linear-gradient(180deg, #fff, #fff) 1 1;
                overflow-x: hidden !important;
                margin-right: 0 !important;
                .el-select-dropdown__list {
                    padding: 0 !important;
                    .el-select-dropdown__item {
                        background: #2D2D2D !important;
                        color: white;
                        &.hover {
                            background-color: #2D2D2D !important;
                            color: white;
                        }
                        &.selected {
                            color: #fff !important;
                            font-weight: 700;
                        }
                    }
                }
            }
        }
        .el-select-dropdown__empty {
            background: #2D2D2D;
            border-radius: 0px 0px 8px 8px;
            border: 1px solid;
            border-image: linear-gradient(180deg, #fff, #fff) 1 1;
        }
    }
    .el-popper__arrow::before {
        background: #2D2D2D !important;
        border: 1px solid #fff !important;
    }
}
//时间日期选择器
.ztzf-layer-date-picker {
    box-shadow: none !important;
    background: transparent;
    border: 1px solid #fff;
    border-radius: 5px;
    .el-range-editor.is-disabled input {
        background-color: transparent !important;
    }
    .el-range-editor.is-disabled {
        background-color: transparent !important;
    }
    .el-input__wrapper {
        box-shadow: none !important;
        background-color: transparent !important;
        width: 300px;
        &.is-focus {
            box-shadow: none !important;
        }
    }
    .el-range-input {
        color: #fff;
        &::placeholder {
            color: rgba(255, 255, 255, 0.37);
        }
    }
    .el-range-separator {
        color: #ffffff;
    }
}
// 日期下拉框
.ztzf-layer-date-picker-popper {
    background: #012350 !important;
    border: 1px solid !important;
    border-radius: 0px 0px 8px 8px;
    border-image: linear-gradient(180deg, rgba(255, 255, 255, 0), rgba(115, 192, 255, 1)) 1 1 !important;
    .el-picker-panel .el-time-panel {
        background: #012350 !important;
    }
    .el-time-spinner__item {
        color: #fff !important;
    }
    .el-time-spinner__item:hover:not(.is-disabled):not(.is-active) {
        background: transparent !important;
    }
    .el-picker-panel {
        .el-picker-panel__body-wrapper {
            .el-picker-panel__body {
                background: #012350 !important;
                color: #fff !important;
                .el-date-picker__time-header {
                    border: none;
                    .el-date-picker__editor-wrap {
                        .el-time-panel {
                            background: #012350 !important;
                            border-radius: 0px 0px 8px 8px;
                            border: 1px solid !important;
                            border-image: linear-gradient(180deg, rgba(255, 255, 255, 0), rgba(115, 192, 255, 1)) 1 1 !important;
                            // 将 time-picker-popper 的样式移到这里
                            .el-time-panel__header {
                                background: #012350 !important;
                                color: #ffffff !important;
                                border-bottom: 1px solid rgba(255, 255, 255, 0.37) !important;
                            }
                            .el-time-panel__content {
                                .el-time-spinner__item {
                                    color: #e6e6e6 !important;
                                    &:hover {
                                        background: #012350 !important;
                                    }
                                    &.active {
                                        color: #479dff !important;
                                        font-weight: bold;
                                    }
                                }
                            }
                            .el-time-panel__footer {
                                background: #012350 !important;
                                border-top: 1px solid rgba(71, 157, 255, 0.3) !important;
                                .el-button {
                                    color: #fff !important;
                                    &:hover {
                                        color: #479dff !important;
                                    }
                                }
                                .el-time-panel__btn.cancel {
                                    color: #fff !important;
                                    &:hover {
                                        color: #fff !important;
                                    }
                                }
                            }
                        }
                    }
                }
                .el-picker-panel__content {
                    .el-date-range-picker__header {
                        .el-picker-panel__icon-btn {
                            color: #fff !important;
                            &:hover {
                                color: var(--el-color-primary) !important;
                            }
                            .el-icon {
                                &::before {
                                    color: inherit !important;
                                }
                            }
                        }
                        &>div {
                            span {
                                color: #fff !important;
                            }
                        }
                    }
                    .el-date-table {
                        th {
                            color: #fff !important;
                        }
                        td.disabled div {
                            background-color: #00193b !important;
                            color: #505050 !important;
                            cursor: not-allowed;
                        }
                        // td:hover,
                        // td.current:not(.disabled) {
                        //     background: rgba(60, 121, 202) !important;
                        //     color: white !important;
                        // }
                        td.start-date span,
                        td.start-date span,
                        td.end-date span {
                            background-color: #012350 !important;
                        }
                        td.in-range div,
                        td.in-range div:hover,
                        &.is-week-mode .el-date-table__row.current div,
                        &.is-week-mode .el-date-table__row:hover div {
                            background-color: rgba(60, 121, 202) !important;
                        }
                    }
                }
            }
        }
    }
    .el-popper__arrow {
        &::before {
            background: #0d3556 !important;
            border: 1px solid #0d3556 !important;
            box-sizing: border-box;
        }
    }
    .el-picker-panel__sidebar {
        background: #012350;
        color: #fff;
        .el-picker-panel__shortcut {
            color: #ffffff;
        }
    }
    .el-picker-panel__body {
        .el-input.is-disabled .el-input__wrapper {
            background: #012350;
            box-shadow: 0 0 0 0.1rem#409eff;
            color: #fff;
            .el-input__inner {
                color: #fff !important;
            }
        }
        .el-button.is-disabled,
        .el-button.is-disabled:hover {
            background: #012350;
        }
        .el-input__wrapper {
            background: #012350;
            box-shadow: 0 0 0 0.1rem#409eff;
            color: #fff;
            .el-input__inner {
                color: #fff !important;
            }
        }
    }
    .el-picker-panel__footer {
        background: #012350;
        color: #fff;
        border-top: none;
        .el-button--small {
            box-shadow: 0 0 0 0.1rem#409eff;
            background-color: #012350;
            color: #fff;
            border: none;
            &:hover {
                background-color: #012350;
                color: #fff;
                border-color: #409eff;
            }
        }
    }
}
.ztzf-layer-time-picker-popper {
    background: rgba(0, 0, 0, 0.8) !important;
    border-radius: 0px 0px 8px 8px;
    border: 1px solid !important;
    border-image: linear-gradient(180deg, rgba(255, 255, 255, 0), rgba(115, 192, 255, 1)) 1 1 !important;
    .el-popper__arrow::before {
        background: rgba(0, 0, 0, 0.8) !important;
        border: 1px solid #479dff !important;
    }
    .el-time-panel__header {
        background: rgba(0, 0, 0, 0.8) !important;
        color: #ffffff !important;
        border-bottom: 1px solid rgba(71, 157, 255, 0.3) !important;
    }
    .el-time-panel__content {
        // background: #012350 !important;
        .el-time-spinner__item {
            color: #e6e6e6 !important;
            &:hover {
                background: rgba(71, 157, 255, 0.3) !important;
            }
            &.active {
                color: #479dff !important;
                font-weight: bold;
            }
        }
    }
    .el-time-panel__footer {
        background: rgba(0, 0, 0, 0.8) !important;
        border-top: 1px solid rgba(71, 157, 255, 0.3) !important;
        .el-button {
            color: #fff !important;
            &:hover {
                color: #479dff !important;
            }
        }
        .el-time-panel__btn.cancel {
            color: #fff !important;
            &:hover {
                color: #fff !important;
            }
        }
    }
}
.ztzf-custom-qrcode-popover {
    //background: url("@/assets/images/home/eventOverviewDetail/qrCodeBg.png") no-repeat center center !important;
    //background-size: cover !important;
    border: none !important;
    border-radius: 0 !important;
    box-shadow: none !important;
    padding: 5px;
    min-width: 173px !important;
    height: 180px !important;
    //background: url("@/assets/images/home/eventOverviewDetail/qrCodeBg.png") no-repeat center center !important;
    //background-size: cover !important;
    border: none !important;
    border-radius: 0 !important;
    box-shadow: none !important;
    padding: 5px;
    min-width: 173px !important;
    height: 180px !important;
    /* 隐藏默认箭头 */
    .el-popper__arrow {
        display: none !important;
    }
    /* 隐藏默认箭头 */
    .el-popper__arrow {
        display: none !important;
    }
    /* 调整二维码内容区域样式 */
    .qrcode-content {
        background: #fff;
        padding: 5px;
        display: flex;
        justify-content: center;
        align-items: center;
        width: 146px;
        height: 130px;
        margin-top: 12px;
    /* 调整二维码内容区域样式 */
    .qrcode-content {
        background: #fff;
        padding: 5px;
        display: flex;
        justify-content: center;
        align-items: center;
        width: 146px;
        height: 130px;
        margin-top: 12px;
        .close-btn {
            position: absolute;
            top: 3px;
            right: 3px;
            width: 20px;
            height: 20px;
        .close-btn {
            position: absolute;
            top: 3px;
            right: 3px;
            width: 20px;
            height: 20px;
            color: white;
            border-radius: 50%;
            display: flex;
            align-items: center;
            justify-content: center;
            cursor: pointer;
            z-index: 100;
        }
    }
            color: white;
            border-radius: 50%;
            display: flex;
            align-items: center;
            justify-content: center;
            cursor: pointer;
            z-index: 100;
        }
    }
}
.ztzf-dialog-video {
    background: #0f1929;
    box-shadow: inset 0px -50px 50px 0px rgba(27, 148, 255, 0.13);
    border-radius: 20px 0px 0px 0px;
    border: 2px solid;
    padding: 0 !important;
    background: #0f1929;
    box-shadow: inset 0px -50px 50px 0px rgba(27, 148, 255, 0.13);
    border-radius: 20px 0px 0px 0px;
    border: 2px solid;
    padding: 0 !important;
    border-image: linear-gradient(180deg,
                    rgba(81, 168, 255, 0),
                    rgba(48, 111, 202, 1),
                    rgba(255, 255, 255, 1),
                    rgba(27, 148, 255, 1)) 2 2;
    border-image: linear-gradient(180deg,
            rgba(81, 168, 255, 0),
            rgba(48, 111, 202, 1),
            rgba(255, 255, 255, 1),
            rgba(27, 148, 255, 1)) 2 2;
    .el-dialog__header {
        width: 100%;
        height: 47px;
        //padding: 0;
        margin-bottom: 14px;
        //background: url("/src/assets/images/home/inspection-vector.png") no-repeat center;
        //background-size: 100% 100%;
        font-weight: bold;
        font-size: 16px;
        line-height: 47px;
    }
    .el-dialog__header {
        width: 100%;
        height: 47px;
        //padding: 0;
        margin-bottom: 14px;
        //background: url("/src/assets/images/home/inspection-vector.png") no-repeat center;
        //background-size: 100% 100%;
        font-weight: bold;
        font-size: 16px;
        line-height: 47px;
    }
    .el-dialog__title {
        width: 112px;
    .el-dialog__title {
        width: 112px;
        font-family: Segoe UI, Segoe UI;
        font-weight: bold;
        font-size: 16px;
        font-family: Segoe UI, Segoe UI;
        font-weight: bold;
        font-size: 16px;
        text-shadow: 0px 0px 5px rgba(154, 218, 255, 0.6);
        text-align: left;
        font-style: normal;
        text-transform: none;
        background: linear-gradient(90deg, #fbfdff 0%, #86d4ff 100%);
        margin-left: 16px;
        -webkit-background-clip: text;
        -webkit-text-fill-color: transparent;
    }
        text-shadow: 0px 0px 5px rgba(154, 218, 255, 0.6);
        text-align: left;
        font-style: normal;
        text-transform: none;
        background: linear-gradient(90deg, #fbfdff 0%, #86d4ff 100%);
        margin-left: 16px;
        -webkit-background-clip: text;
        -webkit-text-fill-color: transparent;
    }
    .el-dialog .el-dialog__header {
        padding: 0px !important;
        padding-left: 0px !important;
    }
    .el-dialog .el-dialog__header {
        padding: 0px !important;
        padding-left: 0px !important;
    }
    .el-scrollbar__thumb {
        background: #13c6ff !important;
    }
    .el-scrollbar__thumb {
        background: #13c6ff !important;
    }
}
  //======以下针对表格功能 增删查改样式和弹窗=========
  .ztzf-dialog-mange {
    .el-dialog__body {
      padding: 2rem 2rem 4rem;
      flex: 1;
      overflow: scroll;
      border-top: 0.1rem solid #f0f0f0;
    }
    .el-dialog__footer {
      z-index: 2;
      display: block;
      padding: 1rem 1.6rem;
      box-sizing: border-box;
      border-top: 0.1rem solid #f0f0f0;
      width: 100%;
      position: absolute;
      left: 0;
      bottom: 0;
      background-color: #fff;
      text-align: right;
    }
  }
  .ztzf-search-mange {
    height: 40px;
    .search-contain {
      display: flex;justify-content: space-between;
    }
  }
  .ztzf-form-mange {
    .el-form-item {
      width: 300px;
      .el-form-item__content {
        width: 100%;
      }
      .el-form-item__label {
        width: 120px;
      }
    }
  }
  .ztzf-form-search {
    .el-form-item {
      width: 100%;
      .el-form-item__label {
        width: 80px;
      }
      .el-form-item__content {
        display: flex;
        flex: 1;
      }
    }
  }
  .ztzf-table-mange {
    th.el-table__cell  {
      color: rgba(0, 0, 0, .85);
      background-color: #fafafa;
    }
  }
  .table-view-mange {
    width: 100%;
    border-top: 0.1rem solid #ebeef5;
    border-left: 0.1rem solid #ebeef5;
    margin-left: 0;
    margin-right: 0;
    .el-col {
      padding-left: 0;
      padding-right: 0;
      margin-bottom: 0;
      height: 32px;
      line-height: 32px;
      border-right: 0.1rem solid #ebeef5;
      text-align: center;
      align-items: center;
      .el-input__wrapper {
        box-shadow: none !important;
        border-bottom: 0.1rem solid #ebeef5;
      }
    }
    .label {
      color: #909399;
      box-sizing: border-box;
      background: #fafafa;
    }
  }
//======以下针对表格功能 增删查改样式和弹窗=========
.ztzf-dialog-mange {
    .el-dialog__body {
        padding: 2rem 2rem 4rem;
        flex: 1;
        overflow: scroll;
        border-top: 0.1rem solid #f0f0f0;
    }
    .el-dialog__footer {
        z-index: 2;
        display: block;
        padding: 1rem 1.6rem;
        box-sizing: border-box;
        border-top: 0.1rem solid #f0f0f0;
        width: 100%;
        position: absolute;
        left: 0;
        bottom: 0;
        background-color: #fff;
        text-align: right;
    }
}
.ztzf-search-mange {
    height: 40px;
    .search-contain {
        display: flex;
        justify-content: space-between;
    }
}
.ztzf-form-mange {
    .el-form-item {
        width: 300px;
        .el-form-item__content {
            width: 100%;
        }
        .el-form-item__label {
            width: 120px;
        }
    }
}
.ztzf-form-search {
    .el-form-item {
        width: 100%;
        .el-form-item__label {
            width: 80px;
        }
        .el-form-item__content {
            display: flex;
            flex: 1;
        }
    }
}
.ztzf-table-mange {
    th.el-table__cell {
        color: rgba(0, 0, 0, .85);
        background-color: #fafafa;
    }
}
.table-view-mange {
    width: 100%;
    border-top: 0.1rem solid #ebeef5;
    border-left: 0.1rem solid #ebeef5;
    margin-left: 0;
    margin-right: 0;
    .el-col {
        padding-left: 0;
        padding-right: 0;
        margin-bottom: 0;
        height: 32px;
        line-height: 32px;
        border-right: 0.1rem solid #ebeef5;
        text-align: center;
        align-items: center;
        .el-input__wrapper {
            box-shadow: none !important;
            border-bottom: 0.1rem solid #ebeef5;
        }
    }
    .label {
        color: #909399;
        box-sizing: border-box;
        background: #fafafa;
    }
}
.ztzf-data-cockpit-search-input {
    .el-input__wrapper {
        padding: 0 8px !important;
        background: #161B2C;
        box-shadow: none !important;
        border: none;
        .el-input__inner {
            color: #ffffff;
            &::placeholder {
                color: #86909C;
            }
        }
    }
    &.is-disabled {
        .el-input__wrapper {
            background-color: #161B2C;
        }
    }
}
.ztzf-data-cockpit-date-picker {
    box-shadow: none !important;
    background: #161B2C;
    border: none;
    border-radius: 5px;
    box-sizing: border-box !important;
    .el-input__wrapper {
        box-shadow: none !important;
        background-color: transparent !important;
        &.is-focus {
            box-shadow: none !important;
        }
    }
    .el-range-input {
        color: #fff;
        &::placeholder {
            color: #86909C;
        }
    }
    .el-range-separator {
        color: #ffffff;
    }
}
.ztzf-data-cockpit-date-picker-popper {
    background: #161B2C !important;
    border: 1px solid !important;
    border-radius: 0px 0px 8px 8px;
    border-image: linear-gradient(180deg, rgba(255, 255, 255, 0), rgba(115, 192, 255, 1)) 1 1 !important;
    .el-date-picker__prev-btn,
    .el-date-picker__next-btn {
        .el-icon {
            color: #fff !important;
        }
    }
    .el-date-picker__header-label {
        color: #fff !important;
    }
    .el-picker-panel {
        .el-picker-panel__body-wrapper {
            .el-picker-panel__body {
                background: #161B2C !important;
                color: #fff !important;
                .el-date-picker__time-header {
                    border: none;
                    .el-date-picker__editor-wrap {
                        .el-time-panel {
                            background: #161B2C !important;
                            border-radius: 0px 0px 8px 8px;
                            border: 1px solid !important;
                            border-image: linear-gradient(180deg, rgba(255, 255, 255, 0), rgba(115, 192, 255, 1)) 1 1 !important;
                            // 将 time-picker-popper 的样式移到这里
                            .el-time-panel__header {
                                background: #161B2C !important;
                                color: #ffffff !important;
                                border-bottom: 1px solid rgba(71, 157, 255, 0.3) !important;
                            }
                            .el-time-panel__content {
                                .el-time-spinner__item {
                                    color: #e6e6e6 !important;
                                    &:hover {
                                        background: rgba(71, 157, 255, 0.3) !important;
                                    }
                                    &.active {
                                        color: #479dff !important;
                                        font-weight: bold;
                                    }
                                }
                            }
                            .el-time-panel__footer {
                                background: #012350 !important;
                                border-top: 1px solid rgba(71, 157, 255, 0.3) !important;
                                .el-button {
                                    color: #fff !important;
                                    &:hover {
                                        color: #479dff !important;
                                    }
                                }
                                .el-time-panel__btn.cancel {
                                    color: #fff !important;
                                    &:hover {
                                        color: #fff !important;
                                    }
                                }
                            }
                        }
                    }
                }
                .el-picker-panel__content {
                    .el-date-range-picker__header {
                        .el-picker-panel__icon-btn {
                            color: #fff !important;
                            &:hover {
                                color: var(--el-color-primary) !important;
                            }
                            .el-icon {
                                &::before {
                                    color: inherit !important;
                                }
                            }
                        }
                        &>div {
                            span {
                                color: #fff !important;
                            }
                        }
                    }
                    .el-date-table {
                        th {
                            color: #fff !important;
                        }
                        td.disabled div {
                            background-color: #00193b !important;
                            color: #505050 !important;
                            cursor: not-allowed;
                        }
                        // td:hover,
                        // td.current:not(.disabled) {
                        //     background: rgba(60, 121, 202) !important;
                        //     color: white !important;
                        // }
                        td.start-date span,
                        td.start-date span,
                        td.end-date span {
                            background-color: #012350 !important;
                        }
                        td.in-range div,
                        td.in-range div:hover,
                        &.is-week-mode .el-date-table__row.current div,
                        &.is-week-mode .el-date-table__row:hover div {
                            background-color: rgba(60, 121, 202) !important;
                        }
                    }
                }
            }
        }
    }
    .el-popper__arrow {
        &::before {
            background: #161B2C !important;
            border: 1px solid #161B2C !important;
            box-sizing: border-box;
        }
    }
    .el-picker-panel__sidebar {
        background: #012350;
        color: #fff;
        .el-picker-panel__shortcut {
            color: #ffffff;
        }
    }
    .el-picker-panel__body {
        .el-input.is-disabled .el-input__wrapper {
            background: #012350;
            box-shadow: 0 0 0 0.1rem#409eff;
            color: #fff;
            .el-input__inner {
                color: #fff !important;
            }
        }
        .el-button.is-disabled,
        .el-button.is-disabled:hover {
            background: #012350;
        }
        .el-input__wrapper {
            background: #012350;
            box-shadow: 0 0 0 0.1rem#409eff;
            color: #fff;
            .el-input__inner {
                color: #fff !important;
            }
        }
    }
    .el-picker-panel__footer {
        background: #012350;
        color: #fff;
        border-top: none;
        .el-button--small {
            box-shadow: 0 0 0 0.1rem#409eff;
            background-color: #012350;
            color: #fff;
            border: none;
            &:hover {
                background-color: #012350;
                color: #fff;
                border-color: #409eff;
            }
        }
    }
}
applications/drone-command/src/views/dataCockpit/components/CenterContainer.vue
@@ -1,4 +1,4 @@
<template>
<template>
    <div class="center-container">
        <div class="left-box">
            <div class="logo">
@@ -6,7 +6,7 @@
            </div>
            <div class="list">
                <div class="item" v-for="item, ind in warningList" :key="ind">
                <div class="item" v-for="(item, ind) in warningList" :key="ind">
                    <div class="val" @click="warningTypeClick(item.type)">
                        {{ item.value }}
                    </div>
@@ -24,7 +24,7 @@
            </div>
            <div class="list">
                <div class="item" v-for="item, ind in equipmentList" :key="ind">
                <div class="item" v-for="(item, ind) in equipmentList" :key="ind">
                    <div class="val" :class="{highlight: item.isHighlight}" @click="equipmentClick(item.isHighlight)">
                        {{ item.value }}
                    </div>
@@ -39,9 +39,9 @@
</template>
<script setup>
import { ref } from 'vue'
import warningLogo from '@/assets/images/dataCockpit/warning.png'
import equipmentLogo from '@/assets/images/dataCockpit/equipment.png'
let warningList = ref([
    {
@@ -82,12 +82,12 @@
])
const warningTypeClick = (type) => {
    console.log('点击了告警类型:', type);
    console.log('点击了告警类型:', type)
}
const equipmentClick = (isHighlight) => {
    if (isHighlight) {
        console.log('点击了设备统计');
        console.log('点击了设备统计')
    }
}
</script>
@@ -196,4 +196,4 @@
        }
    }
}
</style>
</style>
applications/drone-command/src/views/dataCockpit/components/EquipmentWarning.vue
New file
@@ -0,0 +1,61 @@
<!--
 * @Author       : yuan
 * @Date         : 2026-01-08 09:29:07
 * @LastEditors  : yuan
 * @LastEditTime : 2026-01-08 14:49:25
 * @FilePath     : \applications\drone-command\src\views\dataCockpit\components\EquipmentWarning.vue
 * @Description  :
 * Copyright 2026 OBKoro1, All Rights Reserved.
 * 2026-01-08 09:29:07
-->
<template>
    <div class="equipment-warning">
        <EquipmentTemplate v-for="(item, ind) in equipmentWarningData" :key="ind" :data="item" @click="onCardClick" />
    </div>
</template>
<script setup>
import EquipmentTemplate from './templateComponents/EquipmentTemplate.vue'
const equipmentWarningData = ref([
    {
        id: 'dev_001',
        name: '反制设备名称',
        status: '离线',
        statusType: 'offline', // offline | fault | online
        type: '察打一体',
        vendor: '厂商名称',
        azimuth: 14,          // 方位角(°)
        pitch: 14,            // 俯仰角(°)
        range: '1.2KM',       // 有效范围
        model: 'TDOAX1A',     // 设备型号
        longitude: 113.877571,
        latitude: 22.547155
    },
    {
        id: 'dev_002',
        name: '反制设备名称',
        status: '故障',
        statusType: 'fault',
        type: '察打一体',
        vendor: '厂商名称',
        azimuth: 14,
        pitch: 14,
        range: '1.2KM',
        model: 'TDOAX1A',
        longitude: 113.877571,
        latitude: 22.547155
    }
])
const onCardClick = (item) => {
    console.log('点击设备卡片:', item.id)
}
</script>
<style lang="scss" scoped>
.equipment-warning {
    width: 100%;
    height: 100%;
}
</style>
applications/drone-command/src/views/dataCockpit/components/HistoryWarning.vue
New file
@@ -0,0 +1,136 @@
<template>
    <div class="history-warning">
        <!-- 搜索区(设计稿红框) -->
        <div class="search-box">
            <!-- 关键字 -->
            <el-input v-model="query.keyword" class="ztzf-data-cockpit-search-input" placeholder="请输入数据名称" clearable
                @keyup.enter="onSearch">
            </el-input>
            <!-- 日期范围 -->
            <el-date-picker v-model="query.dateRange"
                  class="ztzf-data-cockpit-date-picker"
                 popper-class="ztzf-data-cockpit-date-picker-popper"
                type="daterange"
                range-separator="~"
                start-placeholder="创建开始日期" end-placeholder="结束日期" format="YYYY年MM月DD日" value-format="YYYY-MM-DD"
                :clearable="true" @change="onSearch">
            </el-date-picker>
        </div>
        <!-- 列表 -->
        <div class="list-content">
            <HistoryTemplate v-for="(item, ind) in filteredList" :key="item.id || ind" :data="item"
                @click="onCardClick" />
        </div>
    </div>
</template>
<script setup>
import { ref, computed } from 'vue'
import HistoryTemplate from './templateComponents/HistoryTemplate.vue'
// 原始数据(别动它,过滤用 computed)
const historyWarningData = ref([
    {
        id: 'drone_001',
        name: '无人机名称',
        serialNumber: 'XLH78945645456',
        dataSource: '侦测反制设备名称',
        frequency: '5800MHZ',
        discoveredAt: { date: '2025年12月30日', time: '14:55:06' },
        stayTime: '00:10:50',
        counterMethod: '信号干扰'
    },
    {
        id: 'drone_002',
        name: '无人机名称',
        serialNumber: 'XLH78945645456',
        dataSource: '侦测反制设备名称',
        frequency: '2400MHZ',
        discoveredAt: { date: '2025年12月30日', time: '15:08:12' },
        stayTime: '00:03:21',
        counterMethod: '诱导驱离'
    }
])
// 查询条件:keyword + dateRange(YYYY-MM-DD数组)
const query = ref({
    keyword: '',
    dateRange: [] // [start, end]
})
const onSearch = () => {
    // 目前是本地过滤:computed 会自动更新
    // 后续如果你要走接口,这里换成 fetchList(query.value) 即可
}
const onCardClick = (item) => {
    console.log('点击无人机卡片:', item.id)
}
// "2025年12月30日" -> "2025-12-30"
const cnDateToISO = (cn) => {
    if (!cn) return ''
    const m = cn.match(/(\d{4})年(\d{1,2})月(\d{1,2})日/)
    if (!m) return ''
    const y = m[1]
    const mm = String(m[2]).padStart(2, '0')
    const dd = String(m[3]).padStart(2, '0')
    return `${y}-${mm}-${dd}`
}
const inRange = (targetISO, startISO, endISO) => {
    if (!targetISO) return false
    const t = new Date(`${targetISO}T00:00:00`).getTime()
    const s = startISO ? new Date(`${startISO}T00:00:00`).getTime() : null
    const e = endISO ? new Date(`${endISO}T23:59:59`).getTime() : null
    if (s !== null && t < s) return false
    if (e !== null && t > e) return false
    return true
}
const filteredList = computed(() => {
    const kw = (query.value.keyword || '').trim().toLowerCase()
    const [start, end] = query.value.dateRange || []
    return historyWarningData.value.filter((item) => {
        // 1) 关键字:name / serialNumber / dataSource
        const hitKeyword = !kw
            ? true
            : [item.name, item.serialNumber, item.dataSource]
                .filter(Boolean)
                .some((v) => String(v).toLowerCase().includes(kw))
        if (!hitKeyword) return false
        // 2) 日期范围:按 discoveredAt.date
        if (!start && !end) return true
        const itemISO = cnDateToISO(item?.discoveredAt?.date)
        return inRange(itemISO, start, end)
    })
})
</script>
<style scoped lang="scss">
.history-warning {
    display: flex;
    flex-direction: column;
    width: 100%;
    height: 100%;
    .search-box {
        display: flex;
        flex-direction: column;
        gap: 10px;
        ::v-deep(.ztzf-data-cockpit-date-picker) {
            width: 100% !important;
        }
    }
    .list-content {
        height: 0;
        flex: 1;
    }
}
</style>
applications/drone-command/src/views/dataCockpit/components/LeftContainer.vue
@@ -1,15 +1,108 @@
<template>
    <div class="left-container">
        <div class="wrapper">
            <TitleTemplate>异常情况告警</TitleTemplate>
            <div class="category-container">
                <div class="category-item" v-for="(item, ind) in categoryList" :key="ind" @click="activeId = item.id"
                    :class="{ active: activeId === item.id }">
                    {{ item.name }}
                </div>
            </div>
            <div class="content">
                <component :is="currentComponent" />
            </div>
        </div>
    </div>
</template>
<script setup>
import TitleTemplate from './templateComponents/TitleTemplate.vue'
import RealWarning from './RealWarning.vue'
import EquipmentWarning from './EquipmentWarning.vue'
import HistoryWarning from './HistoryWarning.vue'
const activeId = ref(1)
const categoryList = ref([
    {
        id: 1,
        name: '实时告警',
        component: RealWarning
    },
    {
        id: 2,
        name: '设备告警',
        component: EquipmentWarning
    },
    {
        id: 3,
        name: '历史告警',
        component: HistoryWarning
    }
])
const currentComponent = computed(() => {
    return categoryList.value.find(i => i.id === activeId.value)?.component
})
</script>
<style lang="scss" scoped>
.category-container {
    display: flex;
    justify-content: space-between;
    .category-item {
        position: relative;
        width: 0;
        flex: 1;
        margin-left: 26px;
        height: 68px;
        line-height: 68px;
        font-family: Source Code Pro, Source Code Pro;
        font-weight: 400;
        font-size: 14px;
        color: #86909C;
        text-align: center;
        font-style: normal;
        text-transform: none;
        cursor: pointer;
        &:first-child {
            margin-left: 0;
        }
        &.active {
            font-weight: normal;
            color: #FFFFFF;
        }
        &::after {
            content: '';
            position: absolute;
            left: 0;
            bottom: 0;
            width: 100%;
            height: 1px;
            background: #333355;
        }
        &.active::after {
            height: 3px;
            background: #284FE3;
            box-shadow: 0px 3px 2px 0px rgba(15, 89, 255, 0.1), 0px 7px 5px 0px rgba(15, 89, 255, 0.15), 0px 13px 10px 0px rgba(15, 89, 255, 0.18), 0px 22px 18px 0px rgba(15, 89, 255, 0.21), 0px 42px 33px 0px rgba(15, 89, 255, 0.26), 0px 100px 80px 0px rgba(15, 89, 255, 0.36);
            border-radius: 5px 5px 0px 0px;
        }
    }
}
.content {
    height: 0;
    flex: 1;
    margin-top: 20px;
    overflow-x: hidden;
    overflow-y: auto;
}
</style>
applications/drone-command/src/views/dataCockpit/components/MapContainer.vue
@@ -22,7 +22,7 @@
onBeforeUnmount(() => {
    if (viewInstance) {
        viewInstance.destroy()
        viewInstance?.destroy()
        viewInstance = null
    }
applications/drone-command/src/views/dataCockpit/components/RealWarning.vue
New file
@@ -0,0 +1,76 @@
<!--
 * @Author       : yuan
 * @Date         : 2026-01-08 09:29:07
 * @LastEditors  : yuan
 * @LastEditTime : 2026-01-08 14:49:09
 * @FilePath     : \applications\drone-command\src\views\dataCockpit\components\RealWarning.vue
 * @Description  :
 * Copyright 2026 OBKoro1, All Rights Reserved.
 * 2026-01-08 09:29:07
-->
<template>
    <div class="real-warning">
        <RealTemplate v-for="(item, ind) in realWarningData" :key="ind" :data="item"
            @signal="() => console.log('信号干扰', item.id)" @counter="() => console.log('诱导驱离', item.id)"
            @favorite="() => console.log('收藏', item.id)" />
    </div>
</template>
<script setup>
import RealTemplate from './templateComponents/RealTemplate.vue'
const realWarningData = ref([
    {
        "id": "drone_001",
        "name": "无人机A-01",
        "status": "侦测中",
        "statusType": "detecting",
        "serialNumber": "XLH789456456",
        "dataSource": "侦测反制设备名称",
        "longitude": 113.99238,
        "latitude": 22.541819,
        "frequency": "5800MHz",
        "discoverTime": "14:56:04",
        "altitude": "150m",
        "speed": "5.01m/s",
        "isFavorite": false
    },
    {
        "id": "drone_002",
        "name": "无人机B-07",
        "status": "反制中",
        "statusType": "countering",
        "serialNumber": "XLH789456789",
        "dataSource": "反制设备A区",
        "longitude": 113.99312,
        "latitude": 22.542031,
        "frequency": "2400MHz",
        "discoverTime": "15:02:41",
        "altitude": "120m",
        "speed": "3.86m/s",
        "isFavorite": true
    },
    {
        "id": "drone_002",
        "name": "无人机B-07",
        "status": "反制中",
        "statusType": "countering",
        "serialNumber": "XLH789456789",
        "dataSource": "反制设备A区",
        "longitude": 113.99312,
        "latitude": 22.542031,
        "frequency": "2400MHz",
        "discoverTime": "15:02:41",
        "altitude": "120m",
        "speed": "3.86m/s",
        "isFavorite": true
    }
])
</script>
<style lang="scss" scoped>
.real-warning {
    width: 100%;
    height: 100%;
}
</style>
applications/drone-command/src/views/dataCockpit/components/RightContainer.vue
@@ -1,15 +1,217 @@
<!--
 * @Author       : yuan
 * @Date         : 2026-01-07 15:17:54
 * @LastEditors  : yuan
 * @LastEditTime : 2026-01-08 15:58:15
 * @FilePath     : \applications\drone-command\src\views\dataCockpit\components\RightContainer.vue
 * @Description  :
 * Copyright 2026 OBKoro1, All Rights Reserved.
 * 2026-01-07 15:17:54
-->
<template>
    <div class="right-container">
        <div class="wrapper">
            <TitleTemplate>侦测反制设备</TitleTemplate>
            <div class="category-container">
                <div class="category-item" v-for="(item, ind) in categoryList" :key="ind">
                    <div class="category-item-logo">
                        <img :src="item.logo" alt="">
                    </div>
                    <div class="category-item-content">
                        <span class="name">{{ item.name }}</span>
                        <span class="val">{{ item.val }}</span>
                    </div>
                </div>
            </div>
            <div class="content">
                <RealEquipmentTemplate v-for="item in counterDeviceStatusList" :key="item.id" :data="item"
                    @history="onHistory" @click="onCardClick" />
            </div>
        </div>
    </div>
</template>
<script setup>
import TitleTemplate from './templateComponents/TitleTemplate.vue'
import RealEquipmentTemplate from './templateComponents/RealEquipmentTemplate.vue'
import zcsbLogo from '@/assets/images/dataCockpit/zcsb.png'
import fzsbLogo from '@/assets/images/dataCockpit/fzsb.png'
const categoryList = ref([
    {
        id: 1,
        name: '侦测设备',
        val: 169,
        logo: zcsbLogo
    },
    {
        id: 2,
        name: '反制设备',
        val: 169,
        logo: fzsbLogo
    }
])
const counterDeviceStatusList = ref([
    {
        id: 'cd_001',
        name: '反制设备名称',
        actionText: '侦测中',          // 胶囊文案
        actionType: 'detecting',       // detecting | jamming | idle
        type: '察打一体',
        battery: 100,                  // 电量 %
        azimuth: 14,                   // 方位角
        pitch: 14,                     // 俯仰角
        statusText: '在线',            // 状态
        vendor: '厂商名称',            // 厂商
        targetCount: 10,               // 侦测目标
        range: '1.2KM'                 // 有效范围
    },
    {
        id: 'cd_002',
        name: '反制设备名称',
        actionText: '信号干扰中',
        actionType: 'jamming',
        type: '察打一体',
        battery: 100,
        azimuth: 14,
        pitch: 14,
        statusText: '在线',
        vendor: '厂商名称',
        targetCount: 10,
        range: '1.2KM'
    }
])
const onHistory = (item) => {
    console.log('历史数据:', item.id)
}
const onCardClick = (item) => {
    console.log('点击卡片:', item.id)
}
</script>
<style lang="scss" scoped>
.category-container {
    margin-top: 20px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 28px;
    box-sizing: border-box;
    .category-item {
        position: relative;
        width: 0;
        flex: 1;
        display: flex;
        height: 64px;
        &-logo {
            display: flex;
            align-items: center;
            img {
                width: 40px;
                height: 40px;
            }
        }
        &-content {
            width: 0;
            flex: 1;
            display: flex;
            flex-direction: column;
            border-bottom: 1px solid #6C6C89;
            span {
                margin-left: 8px;
            }
            .name {
                font-family: Open Sans, Open Sans;
                font-weight: 400;
                font-size: 16px;
                color: #C3C3DD;
                line-height: 20px;
                text-align: left;
                font-style: normal;
                text-transform: none;
            }
            .val {
                margin-top: 10px;
                font-family: DIN, DIN;
                font-weight: bold;
                font-size: 22px;
                color: #FFFFFF;
                line-height: 20px;
                text-align: left;
                font-style: normal;
                text-transform: none;
            }
        }
    }
}
.content {
    height: 0;
    flex: 1;
    margin-top: 20px;
    overflow-x: hidden;
    overflow-y: auto;
}
.right-container {
    transition: transform 0.3s ease-in-out;
    /* position: relative; Removed to avoid conflict with parent absolute positioning */
    &.collapsed {
        transform: translateX(100%);
    }
}
.collapse-btn {
    position: absolute;
    top: 50%;
    left: -24px;
    width: 24px;
    height: 60px;
    background: rgba(17, 23, 34, 0.8);
    border: 1px solid #333355;
    border-right: none;
    border-radius: 4px 0 0 4px;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    color: #fff;
    transform: translateY(-50%);
    z-index: 10;
    backdrop-filter: blur(5px);
    .arrow {
        border: solid #fff;
        border-width: 0 2px 2px 0;
        display: inline-block;
        padding: 3px;
        transition: transform 0.3s;
        &.left {
            transform: rotate(135deg);
        }
        &.right {
            transform: rotate(-45deg);
        }
    }
    &:hover {
        background: rgba(40, 79, 227, 0.6);
    }
}
</style>
applications/drone-command/src/views/dataCockpit/components/templateComponents/EquipmentTemplate.vue
New file
@@ -0,0 +1,171 @@
<template>
    <div class="device-card" @click="emit('click', data)">
        <div class="header">
            <div class="title">
                <span class="name">{{ data.name }}</span>
                <span class="status">
                    <span :class="data.statusType">
                    </span>
                    <span>
                        {{ data.status }}
                    </span>
                </span>
            </div>
        </div>
        <div class="content">
            <div class="row">
                <div class="col">
                    <span class="label">类型</span>
                    {{ data.type }}
                </div>
                <div class="col">
                    <span class="label">厂商</span>
                    {{ data.vendor }}
                </div>
            </div>
            <div class="row">
                <div class="col">
                    <span class="label">方位角</span>
                    {{ data.azimuth }}°
                </div>
                <div class="col">
                    <span class="label">俯仰角</span>
                    {{ data.pitch }}°
                </div>
            </div>
            <div class="row">
                <div class="col">
                    <span class="label">有效范围</span>
                    {{ data.range }}
                </div>
                <div class="col">
                    <span class="label">设备型号</span>
                    {{ data.model }}
                </div>
            </div>
            <div>
                <span class="label">部署位置</span>
                <span class="value">{{ data.longitude }},{{ data.latitude }}</span>
            </div>
        </div>
    </div>
</template>
<script setup>
const props = defineProps({
    data: {
        type: Object,
        required: true,
        default: () => ({})
    }
})
const emit = defineEmits(['click'])
</script>
<style scoped lang="scss">
.device-card {
    margin-top: 10px;
    padding: 10px;
    color: #fff;
    background: #191933;
    border-radius: 6px 6px 6px 6px;
    &:first-child {
        margin-top: 0;
    }
    .header {
        display: flex;
        justify-content: space-between;
        align-items: center;
        .title {
            display: flex;
            align-items: center;
            gap: 6px;
            .name {
                font-family: Source Han Sans CN, Source Han Sans CN;
                font-weight: bold;
                font-size: 14px;
                color: #FFFFFF;
                text-align: left;
                font-style: normal;
                text-transform: none;
            }
            .status {
                padding: 0 10px;
                display: flex;
                align-items: center;
                justify-content: space-between;
                height: 21px;
                background: #303041;
                border-radius: 10px;
                gap: 6px;
                span {
                    font-family: Source Han Sans CN, Source Han Sans CN;
                    font-weight: 400;
                    font-size: 10px;
                    color: #FFFFFF;
                    text-align: center;
                    font-style: normal;
                    text-transform: none;
                }
                span.offline {
                    width: 4px;
                    height: 4px;
                    background: #939393;
                    border-radius: 50%;
                }
                span.fault {
                    width: 4px;
                    height: 4px;
                    background: #FF4444;
                    border-radius: 50%;
                }
            }
        }
    }
    .content {
        font-family: Source Han Sans CN, Source Han Sans CN;
        font-weight: 400;
        font-size: 12px;
        color: #9E9EBA;
        text-align: left;
        font-style: normal;
        text-transform: none;
        &>div {
            margin-top: 10px;
            line-height: 22px;
            span.label {
                margin-right: 10px;
                color: #D4D5D7;
            }
        }
        .row {
            display: flex;
            &>div {
                width: 0;
                flex: 1;
            }
        }
    }
}
</style>
applications/drone-command/src/views/dataCockpit/components/templateComponents/HistoryTemplate.vue
New file
@@ -0,0 +1,110 @@
<template>
    <div class="drone-info-card" @click="emit('click', data)">
        <div class="title">
            <span class="name">
                {{ data.name }}
            </span>
        </div>
        <div class="rows">
            <div class="row">
                <span class="label">序列号</span>
                <span class="value">{{ data.serialNumber }}</span>
            </div>
            <div class="row">
                <span class="label">数据源</span>
                <span class="value">{{ data.dataSource }}</span>
            </div>
            <div class="row">
                <span class="label">信号频段</span>
                <span class="value">{{ data.frequency }}</span>
            </div>
            <div class="row">
                <span class="label">发现时间</span>
                <span class="value">
                    <span class="date">{{ data.discoveredAt?.date }}</span>
                    <span class="time">{{ data.discoveredAt?.time }}</span>
                </span>
            </div>
            <div class="row">
                <span class="label">停留时间</span>
                <span class="value">{{ data.stayTime }}</span>
            </div>
            <div class="row">
                <span class="label">反制方式</span>
                <span class="value">{{ data.counterMethod }}</span>
            </div>
        </div>
    </div>
</template>
<script setup>
defineProps({
    data: {
        type: Object,
        required: true,
        default: () => ({})
    }
})
const emit = defineEmits(['click'])
</script>
<style scoped lang="scss">
.drone-info-card {
    margin-top: 10px;
    padding: 10px;
    color: #fff;
    background: #191933;
    border-radius: 6px 6px 6px 6px;
    &:hover {
        filter: brightness(1.05);
    }
    .title {
        display: flex;
        align-items: center;
        gap: 6px;
        .name {
            font-family: Source Han Sans CN, Source Han Sans CN;
            font-weight: bold;
            font-size: 14px;
            color: #FFFFFF;
            text-align: left;
            font-style: normal;
            text-transform: none;
        }
    }
    .rows {
        margin-top: 10px;
        display: flex;
        flex-direction: column;
        gap: 10px;
        font-family: Source Han Sans CN, Source Han Sans CN;
        font-weight: 400;
        font-size: 12px;
        color: #9E9EBA;
        text-align: left;
        font-style: normal;
        text-transform: none;
        .row {
            line-height: 22px;
            .label {
                margin-right: 10px;
                color: #D4D5D7;
            }
        }
    }
}
</style>
applications/drone-command/src/views/dataCockpit/components/templateComponents/RealEquipmentTemplate.vue
New file
@@ -0,0 +1,199 @@
<script setup>
defineProps({
    data: {
        type: Object,
        required: true,
        default: () => ({})
    }
})
const emit = defineEmits(['history', 'click'])
</script>
<template>
    <div class="counter-card" @click="emit('click', data)">
        <!-- 头部 -->
        <div class="header">
            <div class="title">
                <span class="name">{{ data.name }}</span>
                <span class="status">
                    <span :class="data.actionType">
                    </span>
                    <span>
                        {{ data.actionText }}
                    </span>
                </span>
            </div>
        </div>
        <!-- 字段区:两列 -->
        <div class="content">
            <div class="row">
                <div class="col">
                    <span class="label">类型</span>
                    {{ data.type }}
                </div>
                <div class="col">
                    <span class="label">电量</span>
                    {{ data.battery }}%
                </div>
            </div>
            <div class="row">
                <div class="col">
                    <span class="label">方位角</span>
                    {{ data.azimuth }}°
                </div>
                <div class="col">
                    <span class="label">俯仰角</span>
                    {{ data.pitch }}°
                </div>
            </div>
            <div class="row">
                <div class="col">
                    <span class="label">状态</span>
                    {{ data.statusText }}
                </div>
                <div class="col">
                    <span class="label">厂商</span>
                    {{ data.vendor }}
                </div>
            </div>
            <div class="row">
                <div class="col">
                    <span class="label">侦测目标</span>
                    {{ data.targetCount }}台
                </div>
                <div class="col">
                    <span class="label">有效范围</span>
                    {{ data.range }}KM
                </div>
            </div>
        </div>
        <!-- 底部按钮 -->
        <div class="footer">
            <el-button color="#284FE3" type="primary" @click.stop="emit('history', data)">历史数据</el-button>
        </div>
    </div>
</template>
<style scoped lang="scss">
.counter-card {
    margin-top: 10px;
    padding: 10px;
    color: #fff;
    background: #191933;
    border-radius: 6px 6px 6px 6px;
    &:first-child {
        margin-top: 0;
    }
    .header {
        display: flex;
        justify-content: space-between;
        align-items: center;
        .title {
            display: flex;
            align-items: center;
            gap: 6px;
            .name {
                font-family: Source Han Sans CN, Source Han Sans CN;
                font-weight: bold;
                font-size: 14px;
                color: #FFFFFF;
                text-align: left;
                font-style: normal;
                text-transform: none;
            }
            .status {
                padding: 0 10px;
                display: flex;
                align-items: center;
                justify-content: space-between;
                height: 21px;
                background: #303041;
                border-radius: 10px;
                gap: 6px;
                span {
                    font-family: Source Han Sans CN, Source Han Sans CN;
                    font-weight: 400;
                    font-size: 10px;
                    color: #FFFFFF;
                    text-align: center;
                    font-style: normal;
                    text-transform: none;
                }
                span.detecting {
                    width: 4px;
                    height: 4px;
                    background: #18FF4A;
                    border-radius: 50%;
                }
                span.jamming {
                    width: 4px;
                    height: 4px;
                    background: #FF4444;
                    border-radius: 50%;
                }
            }
        }
    }
    .content {
        font-family: Source Han Sans CN, Source Han Sans CN;
        font-weight: 400;
        font-size: 12px;
        color: #9E9EBA;
        text-align: left;
        font-style: normal;
        text-transform: none;
        &>div {
            margin-top: 10px;
            line-height: 22px;
            span.label {
                margin-right: 10px;
                color: #D4D5D7;
            }
        }
        .row {
            display: flex;
            &>div {
                width: 0;
                flex: 1;
            }
        }
    }
    .footer {
        display: flex;
        align-items: center;
        justify-content: center;
        gap: 10px;
        margin-top: 10px;
        ::v-deep(.el-button) {
            width: 96px;
            height: 36px;
        }
    }
}
</style>
applications/drone-command/src/views/dataCockpit/components/templateComponents/RealTemplate.vue
New file
@@ -0,0 +1,204 @@
<template>
    <div class="drone-card">
        <div class="header">
            <div class="title">
                <span class="name">{{ data.name }}</span>
                <span class="status">
                    <span :class="data.statusType">
                    </span>
                    <span>
                        {{ data.status }}
                    </span>
                </span>
            </div>
            <div class="actions">
                <span class="star" @click="emit('favorite')">
                    {{ data.isFavorite ? '★' : '☆' }}
                </span>
            </div>
        </div>
        <div class="content">
            <div>
                <span class="label">序列号</span>
                {{ data.serialNumber }}
            </div>
            <div>
                <span class="label">数据源</span>
                {{ data.dataSource }}
            </div>
            <div>
                <span class="label">经纬度</span>
                {{ data.longitude }}, {{ data.latitude }}
            </div>
            <div class="row">
                <div class="col">
                    <span class="label">信号频段</span>
                    {{ data.frequency }}
                </div>
                <div class="col">
                    <span class="label">发现时间</span>
                    {{ data.discoverTime }}
                </div>
            </div>
            <div class="row">
                <div class="col">
                    <span class="label">飞行高度</span>
                    {{ data.altitude }}
                </div>
                <div class="col">
                    <span class="label">飞行速度</span>
                    {{ data.speed }}
                </div>
            </div>
        </div>
        <div class="footer">
            <el-button class="general" color="#2B2B4C" @click="emit('signal')">信号干扰</el-button>
            <el-button color="#284FE3" type="primary" @click="emit('counter')">诱导驱离</el-button>
        </div>
    </div>
</template>
<script setup>
const props = defineProps({
    data: {
        type: Object,
        required: true,
        default: () => ({})
    }
})
const emit = defineEmits(['signal', 'counter', 'favorite'])
</script>
<style scoped lang="scss">
.drone-card {
    margin-top: 10px;
    padding: 10px;
    color: #fff;
    background: #191933;
    border-radius: 6px 6px 6px 6px;
    &:hover {
        background: #29294D;
        ;
    }
    &:first-child {
        margin-top: 0;
    }
    .header {
        display: flex;
        justify-content: space-between;
        align-items: center;
        .title {
            display: flex;
            align-items: center;
            gap: 6px;
            .name {
                font-family: Source Han Sans CN, Source Han Sans CN;
                font-weight: bold;
                font-size: 14px;
                color: #FFFFFF;
                text-align: left;
                font-style: normal;
                text-transform: none;
            }
            .status {
                padding: 0 10px;
                display: flex;
                align-items: center;
                justify-content: space-between;
                height: 21px;
                background: #303041;
                border-radius: 10px;
                gap: 6px;
                span {
                    font-family: Source Han Sans CN, Source Han Sans CN;
                    font-weight: 400;
                    font-size: 10px;
                    color: #FFFFFF;
                    text-align: center;
                    font-style: normal;
                    text-transform: none;
                }
                span.detecting {
                    width: 4px;
                    height: 4px;
                    background: #18FF4A;
                    border-radius: 50%;
                }
                span.countering {
                    width: 4px;
                    height: 4px;
                    background: #FF4444;
                    border-radius: 50%;
                }
            }
        }
        .actions {
            display: flex;
            gap: 8px;
            font-size: 16px;
            cursor: pointer;
        }
    }
    .content {
        font-family: Source Han Sans CN, Source Han Sans CN;
        font-weight: 400;
        font-size: 12px;
        color: #9E9EBA;
        text-align: left;
        font-style: normal;
        text-transform: none;
        &>div {
            margin-top: 10px;
            line-height: 22px;
            span.label {
                margin-right: 10px;
                color: #D4D5D7;
            }
        }
        .row {
            display: flex;
            justify-content: space-between;
        }
    }
    .footer {
        display: flex;
        align-items: center;
        justify-content: center;
        gap: 10px;
        margin-top: 10px;
        ::v-deep(.el-button) {
            width: 96px;
            height: 36px;
            &.general.el-button {
                border-radius: 4px 4px 4px 4px;
                border: 1px solid rgba(255, 255, 255, 0.5);
            }
        }
    }
}
</style>
applications/drone-command/src/views/dataCockpit/components/templateComponents/TitleTemplate.vue
New file
@@ -0,0 +1,43 @@
<!--
 * @Author       : yuan
 * @Date         : 2026-01-08 09:32:52
 * @LastEditors  : yuan
 * @LastEditTime : 2026-01-08 09:43:00
 * @FilePath     : \applications\drone-command\src\views\dataCockpit\components\templateComponents\TitleTemplate.vue
 * @Description  :
 * Copyright 2026 OBKoro1, All Rights Reserved.
 * 2026-01-08 09:32:52
-->
<template>
    <div class="title-box">
        <div class="title">
            <slot></slot>
        </div>
    </div>
</template>
<script setup>
</script>
<style lang="scss" scoped>
.title-box {
    padding-left: 26px;
    background: url('@/assets/images/dataCockpit/title-bg.png') center / 100% 100% no-repeat;
    height: 34px;
    .title {
        height: 25px;
        line-height: 25px;
        font-family: PangMen;
        font-weight: 400;
        font-size: 18px;
        color: #FFFFFF;
        letter-spacing: 1px;
        text-align: left;
        font-style: normal;
        text-transform: none;
    }
}
</style>
applications/drone-command/src/views/dataCockpit/index.vue
@@ -2,7 +2,7 @@
 * @Author       : yuan
 * @Date         : 2026-01-06 16:35:50
 * @LastEditors  : yuan
 * @LastEditTime : 2026-01-07 17:33:02
 * @LastEditTime : 2026-01-08 09:45:25
 * @FilePath     : \applications\drone-command\src\views\dataCockpit\index.vue
 * @Description  : 
 * Copyright 2026 OBKoro1, All Rights Reserved. 
@@ -41,6 +41,8 @@
    backdrop-filter: blur(5px);
    ::v-deep(.wrapper) {
      display: flex;
      flex-direction: column;
      position: absolute;
      top: 17px;
      bottom: 20px;