14 files modified
3 files added
| | |
| | | data |
| | | }) |
| | | } |
| | | |
| | | // 设备统计 |
| | | export const deviceStatisticsApi = () => { |
| | | return request({ |
| | | url: '/drone-fw/cockpit/dataCockpit/deviceStatistics', |
| | | method: 'get' |
| | | }) |
| | | } |
| | |
| | | </div> |
| | | |
| | | <div class="top-bar__right"> |
| | | <div class="icon-box"> |
| | | <top-lock v-if="setting.lock" /> |
| | | <top-qna /> |
| | | <top-full v-if="setting.fullscreen" title="全屏" /> |
| | | <img class="gateway" @click="jumpMH" src="@/assets/images/mh.svg" alt="进入门户" title="进入门户" width="20" |
| | | height="20"> |
| | | </div> |
| | | <div class="top-user"> |
| | | <img class="top-bar__img" :src="userInfo.avatar" alt="" /> |
| | | <div class="icon-box"> |
| | | <img class="gateway" @click="jumpMH" src="@/assets/images/mh.png" alt="进入门户" title="进入门户"> |
| | | </div> |
| | | |
| | | <el-dropdown> |
| | | <span class="el-dropdown-link"> |
| | | {{ userInfo.real_name }} |
| | | <el-icon class="el-icon--right"> |
| | | <arrow-down /> |
| | | </el-icon> |
| | | <img class="top-bar__img" :src="userInfo.avatar" alt="" /> |
| | | </span> |
| | | |
| | | <template #dropdown> |
| | | <el-dropdown-menu> |
| | | <!-- <el-dropdown-item> |
| | |
| | | } |
| | | |
| | | .top-bar__right { |
| | | margin-right: 28px; |
| | | padding-top: 16px; |
| | | flex: 0 0 auto; |
| | | display: flex !important; |
| | | align-items: center; |
| | | align-items: flex-start; |
| | | height: 100%; |
| | | pointer-events: auto; |
| | | box-sizing: border-box; |
| | | |
| | | .icon-box { |
| | | margin-top: 6px; |
| | | margin-right: 30px; |
| | | display: flex; |
| | | align-items: center; |
| | | gap: 0 20px; |
| | | |
| | | .gateway { |
| | | width: 25px; |
| | | height: 25px; |
| | | width: 21px; |
| | | height: 18px; |
| | | } |
| | | |
| | | >* { |
| | |
| | | } |
| | | |
| | | .top-bar__img { |
| | | width: 32px; |
| | | height: 32px; |
| | | border-radius: 50%; |
| | | margin-right: 10px; |
| | | margin-top: 5px; |
| | | width: 16px; |
| | | height: 21px; |
| | | } |
| | | |
| | | .el-dropdown-link { |
| | |
| | | // 地图编辑样式 |
| | | @import './mapEdit.scss'; |
| | | |
| | | @import './common/cockpit.scss'; |
| | | |
| | | a { |
| | | text-decoration: none; |
| | | color: #333; |
| New file |
| | |
| | | // 数据驾驶舱专属 |
| | | .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; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | .ztzf-data-cockpit-select { |
| | | .el-select__input { |
| | | color: #8ac3fd !important; |
| | | } |
| | | |
| | | .el-select__wrapper { |
| | | background: #2E2E48; |
| | | box-shadow: none !important; |
| | | border: none; |
| | | width: 100%; |
| | | } |
| | | |
| | | .el-select__placeholder { |
| | | &.is-transparent { |
| | | color: #86909C !important; |
| | | } |
| | | |
| | | &.el-select__selected-item { |
| | | color: #ffffff; |
| | | } |
| | | } |
| | | |
| | | .el-select { |
| | | --el-select-border-color-hover: rgb(0, 162, 255) !important; |
| | | } |
| | | |
| | | .el-input { |
| | | --el-border-color: rgb(0, 162, 255); |
| | | } |
| | | |
| | | .el-select .el-input__wrapper { |
| | | background-color: #012350 !important; |
| | | } |
| | | |
| | | .el-input__wrapper { |
| | | --el-input-text-color: #012350 !important; |
| | | } |
| | | } |
| | | |
| | | .ztzf-data-cockpit-select-popper.el-select__popper { |
| | | border: none; |
| | | background: #2E2E48 !important; |
| | | |
| | | .el-select-dropdown { |
| | | overflow-x: hidden !important; |
| | | border: none; |
| | | |
| | | .el-scrollbar { |
| | | .el-select-dropdown__wrap { |
| | | overflow-x: hidden !important; |
| | | border: none; |
| | | |
| | | .el-select-dropdown__list { |
| | | padding: 0 !important; |
| | | |
| | | .el-select-dropdown__item { |
| | | background: transparent !important; |
| | | color: white; |
| | | |
| | | &.hover { |
| | | background-color: rgba(0, 120, 233, 0.63) !important; |
| | | color: white; |
| | | } |
| | | |
| | | &.selected { |
| | | color: #8ac3fd !important; |
| | | font-weight: 700; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | .el-select-dropdown__empty { |
| | | background: #2E2E48; |
| | | border-radius: 0px 0px 8px 8px; |
| | | } |
| | | } |
| | | |
| | | .el-popper__arrow::before { |
| | | background: #2E2E48 !important; |
| | | border: 1px solid #2E2E48 !important; |
| | | } |
| | | } |
| | | |
| | | // 树形选择 |
| | | .ztzf-data-cockpit-tree-select-popper { |
| | | background: #2E2E48 !important; |
| | | border: none !important; |
| | | |
| | | .el-popper__arrow::before { |
| | | background: #2E2E48 !important; |
| | | border: 1px solid #2E2E48 !important; |
| | | } |
| | | |
| | | .el-tree { |
| | | background: transparent !important; |
| | | color: #fff !important; |
| | | |
| | | .el-tree-node__content:hover { |
| | | background: none !important; |
| | | } |
| | | |
| | | .el-tree-node__content:hover { |
| | | background: none !important; |
| | | } |
| | | |
| | | .el-tree-node.is-current>.el-tree-node__content { |
| | | color: #479dff !important; |
| | | } |
| | | } |
| | | |
| | | .el-select-dropdown__item { |
| | | background: none !important; |
| | | color: #fff !important; |
| | | |
| | | input { |
| | | color: #fff !important; |
| | | |
| | | &::placeholder { |
| | | color: #fff !important; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .el-tree { |
| | | --el-tree-node-hover-bg-color: none !important; |
| | | color: #fff !important; |
| | | |
| | | .el-checkbox__inner { |
| | | background: none !important; |
| | | border: 1px solid #3194ef !important; |
| | | } |
| | | } |
| | | |
| | | .el-select-dropdown__item.is-selected { |
| | | color: #fff !important; |
| | | } |
| | | |
| | | .el-popper.is-light { |
| | | background: #012a50 !important; |
| | | box-shadow: none !important; |
| | | border: none !important; |
| | | border-radius: 4px !important; |
| | | margin-top: 2px; |
| | | |
| | | .el-select__selection { |
| | | max-width: 240px !important; |
| | | |
| | | .el-select__selected-item { |
| | | .el-tag { |
| | | background: #0b1d38 !important; |
| | | color: white; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .el-popper__arrow::before { |
| | | background: #012a50 !important; |
| | | border: 1px solid #012a50 !important; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .ztzf-data-cockpit-dialog { |
| | | padding: 20px; |
| | | display: flex; |
| | | flex-direction: column; |
| | | width: 1222px; |
| | | height: 835px; |
| | | background: #1A1A2A; |
| | | border-radius: 6px 6px 6px 6px; |
| | | border: 1px solid #2E2E46; |
| | | box-sizing: border-box; |
| | | |
| | | .el-dialog__header { |
| | | padding-bottom: 30px; |
| | | height: auto; |
| | | |
| | | .el-dialog__title { |
| | | font-family: Source Han Sans CN, Source Han Sans CN; |
| | | font-weight: bold; |
| | | font-size: 18px; |
| | | color: #FFFFFF; |
| | | line-height: 22px; |
| | | text-align: left; |
| | | font-style: normal; |
| | | text-transform: none; |
| | | } |
| | | |
| | | .el-dialog__headerbtn { |
| | | .el-icon.el-dialog__close { |
| | | color: #fff; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .history-search { |
| | | .el-form-item__label { |
| | | font-family: Source Han Sans CN, Source Han Sans CN; |
| | | font-weight: 500; |
| | | font-size: 14px; |
| | | color: #C5C9D6; |
| | | font-style: normal; |
| | | text-transform: none; |
| | | } |
| | | |
| | | .ztzf-data-cockpit-search-input { |
| | | .el-input__wrapper { |
| | | background: #2E2E48; |
| | | } |
| | | |
| | | &.is-disabled { |
| | | .el-input__wrapper { |
| | | background-color: #2E2E48; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .ztzf-data-cockpit-date-picker { |
| | | background: #2E2E48; |
| | | } |
| | | |
| | | .ztzf-data-cockpit-date-picker-popper { |
| | | background: #2E2E48 !important; |
| | | |
| | | .el-picker-panel { |
| | | .el-picker-panel__body-wrapper { |
| | | .el-picker-panel__body { |
| | | background: #2E2E48 !important; |
| | | |
| | | .el-date-picker__time-header { |
| | | |
| | | .el-date-picker__editor-wrap { |
| | | .el-time-panel { |
| | | background: #2E2E48 !important; |
| | | |
| | | // 将 time-picker-popper 的样式移到这里 |
| | | .el-time-panel__header { |
| | | background: #2E2E48 !important; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | .el-popper__arrow { |
| | | &::before { |
| | | background: #2E2E48 !important; |
| | | border: 1px solid #2E2E48 !important; |
| | | box-sizing: border-box; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .history-search-actions { |
| | | .el-button { |
| | | width: 96px; |
| | | background: transparent !important; |
| | | border-radius: 4px 4px 4px 4px; |
| | | border: 1px solid rgba(255, 255, 255, 0.3); |
| | | |
| | | .el-icon { |
| | | font-size: 16px; |
| | | color: #fff; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | .el-dialog__body { |
| | | height: 0; |
| | | flex: 1; |
| | | display: flex; |
| | | flex-direction: column; |
| | | |
| | | .table-container { |
| | | height: 0; |
| | | flex: 1; |
| | | display: flex; |
| | | flex-direction: column; |
| | | |
| | | .table-content { |
| | | height: 0; |
| | | flex: 1; |
| | | display: flex; |
| | | flex-direction: column; |
| | | |
| | | .ztzf-data-cockpit-table { |
| | | height: 0; |
| | | flex: 1; |
| | | background: transparent !important; |
| | | |
| | | .el-table--border .el-table__inner-wrapper:after, .el-table--border:after, .el-table--border:before, .el-table__inner-wrapper:before { |
| | | height: 0; |
| | | } |
| | | |
| | | tr { |
| | | background: transparent !important; |
| | | } |
| | | |
| | | th.el-table__cell { |
| | | border-bottom: 1px solid #323241; |
| | | background: transparent !important; |
| | | |
| | | .cell { |
| | | font-family: Source Han Sans CN, Source Han Sans CN; |
| | | font-weight: 500; |
| | | font-size: 14px; |
| | | color: #FFFFFF; |
| | | line-height: 22px; |
| | | font-style: normal; |
| | | text-transform: none; |
| | | } |
| | | } |
| | | |
| | | td.el-table__cell { |
| | | border-bottom: 1px solid #323241; |
| | | background: transparent !important; |
| | | |
| | | .cell { |
| | | font-family: Source Han Sans CN, Source Han Sans CN; |
| | | font-weight: 400; |
| | | font-size: 14px; |
| | | color: #9E9EBA; |
| | | line-height: 18px; |
| | | font-style: normal; |
| | | text-transform: none; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | .table-pagination { |
| | | padding-top: 30px; |
| | | padding-bottom: 10px; |
| | | display: flex; |
| | | justify-content: flex-end; |
| | | |
| | | .el-pagination__total { |
| | | font-family: Source Han Sans CN, Source Han Sans CN; |
| | | font-weight: 400; |
| | | font-size: 14px; |
| | | color: #9E9EBA; |
| | | font-style: normal; |
| | | text-transform: none; |
| | | } |
| | | |
| | | .btn-prev, |
| | | .btn-next { |
| | | background: transparent !important; |
| | | |
| | | .el-icon { |
| | | color: #C9CDD4; |
| | | } |
| | | } |
| | | |
| | | .el-pager { |
| | | li { |
| | | margin-left: 8px; |
| | | font-family: Nunito Sans, Nunito Sans; |
| | | font-weight: 600; |
| | | font-size: 14px; |
| | | color: #9E9EBA; |
| | | font-style: normal; |
| | | text-transform: none; |
| | | background: transparent; |
| | | |
| | | &:first-child { |
| | | margin-left: 0; |
| | | } |
| | | |
| | | &.is-active { |
| | | font-family: Nunito Sans, Nunito Sans; |
| | | font-weight: 600; |
| | | font-size: 14px; |
| | | color: #477EFF; |
| | | font-style: normal; |
| | | text-transform: none; |
| | | background: rgba(71, 126, 255, 0.16); |
| | | } |
| | | } |
| | | } |
| | | |
| | | .el-select { |
| | | .el-select__wrapper { |
| | | .el-select__placeholder { |
| | | font-family: Source Han Sans CN, Source Han Sans CN; |
| | | font-weight: 400; |
| | | font-size: 14px; |
| | | color: #9E9EBA; |
| | | font-style: normal; |
| | | text-transform: none; |
| | | } |
| | | |
| | | background: #1C1C31; |
| | | border: none; |
| | | box-shadow: none; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | |
| | | 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; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | .ztzf-data-cockpit-dialog { |
| | | width: 1222px; |
| | | height: 835px; |
| | | background: #1A1A2A; |
| | | border-radius: 6px 6px 6px 6px; |
| | | border: 1px solid #2E2E46; |
| | | } |
| | |
| | | } |
| | | |
| | | .top-bar__img { |
| | | margin: 0 5px; |
| | | padding: 2px; |
| | | width: 30px; |
| | | height: 30px; |
| | | border-radius: 100%; |
| | | box-sizing: border-box; |
| | | border: 1px solid #eee; |
| | | vertical-align: middle; |
| | | } |
| | | |
| | |
| | | |
| | | // 销毁处理 |
| | | destroy () { |
| | | if (!this._viewer || this._viewer.isDestroyed?.()) { |
| | | this._primitiveCollection = null |
| | | this._entityCircleDataSource = null |
| | | this._viewer = null |
| | | return |
| | | } |
| | | |
| | | if (this._primitiveCollection) { |
| | | this._primitiveCollection.removeAll() |
| | | this._viewer.scene.primitives.remove(this._primitiveCollection) |
| | |
| | | |
| | | |
| | | ## 信号干扰,诱导驱离 |
| | | ## 历史告警-实时告警 |
| | | |
| | | |
| | | **接口地址**:`/cockpit/dataCockpit/interferenceAndExpulsion` |
| | | **接口地址**:`/cockpit/dataCockpit/alarmLog` |
| | | |
| | | |
| | | **请求方式**:`POST` |
| | | **请求方式**:`GET` |
| | | |
| | | |
| | | **请求数据类型**:`application/json` |
| | | **请求数据类型**:`application/x-www-form-urlencoded` |
| | | |
| | | |
| | | **响应数据类型**:`*/*` |
| | | |
| | | |
| | | **接口描述**:<p>传入fwEffectEval</p> |
| | | **接口描述**:<p>传入fwDroneAlarmRecord</p> |
| | | |
| | | |
| | | |
| | | **请求示例**: |
| | | |
| | | |
| | | ```javascript |
| | | { |
| | | "alarmRecordId": 0, |
| | | "areaCode": "", |
| | | "counterEffect": "", |
| | | "coverRadiusM": 0, |
| | | "deployLatitude": 0, |
| | | "deployLongitude": 0, |
| | | "deviceCode": "", |
| | | "deviceId": 0, |
| | | "deviceModel": "", |
| | | "deviceName": "", |
| | | "deviceType": "", |
| | | "droneDeviceCode": "", |
| | | "droneName": "", |
| | | "droneType": "", |
| | | "findTime": "", |
| | | "id": 0, |
| | | "workMode": "" |
| | | } |
| | | ``` |
| | | |
| | | |
| | | **请求参数**: |
| | |
| | | |
| | | | 参数名称 | 参数说明 | 请求类型 | 是否必须 | 数据类型 | schema | |
| | | | -------- | -------- | ----- | -------- | -------- | ------ | |
| | | |fwEffectEval|fwEffectEval|body|true|FwEffectEvalDTO|FwEffectEvalDTO| |
| | | |  alarmRecordId|告警记录ID(ja_fw_drone_alarm_record.id)||false|integer(int64)|| |
| | | |  areaCode|区域编码||false|string|| |
| | | |  counterEffect|反制效果(success/fail)||false|string|| |
| | | |  coverRadiusM|覆盖范围(米)||false|integer(int32)|| |
| | | |  deployLatitude|部署纬度(冗余)||false|number(double)|| |
| | | |  deployLongitude|部署经度(冗余)||false|number(double)|| |
| | | |  deviceCode|反制设备编码(快照)||false|string|| |
| | | |  deviceId|反制设备ID(ja_fw_device.id)||false|integer(int64)|| |
| | | |  deviceModel|反制设备型号(快照)||false|string|| |
| | | |  deviceName|反制设备名称(快照)||false|string|| |
| | | |  deviceType|反制设备类型(快照)||false|string|| |
| | | |  droneDeviceCode|无人机设备编码||false|string|| |
| | | |  droneName|无人机名称||false|string|| |
| | | |  droneType|无人机类型||false|string|| |
| | | |  findTime|发现时间||false|string(date-time)|| |
| | | |  id|主键id||false|integer(int64)|| |
| | | |  workMode|工作模式(机动/固定)||false|string|| |
| | | |alarmTime|告警时间|query|false|string(date-time)|| |
| | | |alarmType|告警类型:1.实时告警/2.历史告警|query|false|string|| |
| | | |areaCode|区域编码|query|false|string|| |
| | | |areaDivideId|区域id ja_fw_area_divide|query|false|string|| |
| | | |areaName|区域名称|query|false|string|| |
| | | |counterWay|反制方式:1.信号干扰/2.诱导驱离/无|query|false|string|| |
| | | |current|当前页|query|false|integer(int32)|| |
| | | |defenseSceneId|场景id ja_fw_defense_scene.id|query|false|string|| |
| | | |deviceId|反无设备ID(关联ja_fw_device.id)|query|false|integer(int64)|| |
| | | |deviceType|设备类型|query|false|string|| |
| | | |droneName|无人机名称|query|false|string|| |
| | | |droneSerialNo|无人机序列号|query|false|string|| |
| | | |droneType|无人机类型(1.微型机/2.植保机...)|query|false|string|| |
| | | |endTime|结束时间|query|false|string|| |
| | | |flightHeightM|飞行高度(m)|query|false|integer(int32)|| |
| | | |flightSpeedMs|飞行速度(m/s)|query|false|number|| |
| | | |flightStatus|飞行状态:1.侦测中/2.反制中|query|false|string|| |
| | | |id|主键id|query|false|integer(int64)|| |
| | | |latitude|当前纬度|query|false|number(double)|| |
| | | |longitude|当前经度|query|false|number(double)|| |
| | | |signalFreqMhz|信号频段(MHz)|query|false|integer(int32)|| |
| | | |size|每页的数量|query|false|integer(int32)|| |
| | | |startTime|开始时间|query|false|string|| |
| | | |stayDuration|停留时长 (秒) |query|false|string|| |
| | | |triggerReason|触发原因|query|false|string|| |
| | | |
| | | |
| | | **响应状态**: |
| | |
| | | |
| | | | 状态码 | 说明 | schema | |
| | | | -------- | -------- | ----- | |
| | | |200|OK|R| |
| | | |201|Created|| |
| | | |200|OK|R«IPage«FwDroneAlarmRecordVO»»| |
| | | |401|Unauthorized|| |
| | | |403|Forbidden|| |
| | | |404|Not Found|| |
| | |
| | | | 参数名称 | 参数说明 | 类型 | schema | |
| | | | -------- | -------- | ----- |----- | |
| | | |code|状态码|integer(int32)|integer(int32)| |
| | | |data|承载数据|object|| |
| | | |data|承载数据|IPage«FwDroneAlarmRecordVO»|IPage«FwDroneAlarmRecordVO»| |
| | | |  current||integer(int64)|| |
| | | |  pages||integer(int64)|| |
| | | |  records||array|FwDroneAlarmRecordVO| |
| | | |    alarmTime|告警时间|string|| |
| | | |    alarmType|告警类型:1.实时告警/2.历史告警|string|| |
| | | |    areaCode|区域编码|string|| |
| | | |    areaName|区域名称|string|| |
| | | |    counterWay|反制方式:1.信号干扰/2.诱导驱离/3.无|string|| |
| | | |    deviceId|反无设备ID(关联ja_fw_device.id)|integer|| |
| | | |    deviceModel|设备型号|string|| |
| | | |    deviceName|设备名称|string|| |
| | | |    deviceType|设备类型(1.便捷侦测箱/2.反制枪/3.察打一体)|string|| |
| | | |    droneName|无人机名称|string|| |
| | | |    droneSerialNo|无人机序列号|string|| |
| | | |    droneType|无人机类型(1.微型机/2.植保机...)|string|| |
| | | |    flightHeightM|飞行高度(m)|integer|| |
| | | |    flightSpeedMs|飞行速度(m/s)|number|| |
| | | |    flightStatus|飞行状态:1.侦测中/2.反制中|string|| |
| | | |    id|主键id|integer|| |
| | | |    latitude|当前纬度|number|| |
| | | |    longitude|当前经度|number|| |
| | | |    signalFreqMhz|信号频段(MHz)|integer|| |
| | | |    stayDuration|停留时长(秒)|string|| |
| | | |    triggerReason|触发原因|string|| |
| | | |  size||integer(int64)|| |
| | | |  total||integer(int64)|| |
| | | |msg|返回消息|string|| |
| | | |success|是否成功|boolean|| |
| | | |
| | |
| | | ```javascript |
| | | { |
| | | "code": 0, |
| | | "data": {}, |
| | | "data": { |
| | | "current": 0, |
| | | "pages": 0, |
| | | "records": [ |
| | | { |
| | | "alarmTime": "", |
| | | "alarmType": "", |
| | | "areaCode": "", |
| | | "areaName": "", |
| | | "counterWay": "", |
| | | "deviceId": 0, |
| | | "deviceModel": "", |
| | | "deviceName": "", |
| | | "deviceType": "", |
| | | "droneName": "", |
| | | "droneSerialNo": "", |
| | | "droneType": "", |
| | | "flightHeightM": 0, |
| | | "flightSpeedMs": 0, |
| | | "flightStatus": "", |
| | | "id": 0, |
| | | "latitude": 0, |
| | | "longitude": 0, |
| | | "signalFreqMhz": 0, |
| | | "stayDuration": "", |
| | | "triggerReason": "" |
| | | } |
| | | ], |
| | | "size": 0, |
| | | "total": 0 |
| | | }, |
| | | "msg": "", |
| | | "success": true |
| | | } |
| | |
| | | <template> |
| | | <el-dialog |
| | | class="ztzf-data-cockpit-dialog" |
| | | append-to-body |
| | | v-model="visibleModel" |
| | | :title="dialogTitle" |
| | | :close-on-click-modal="false" |
| | | :destroy-on-close="true" |
| | | > |
| | | <div class="dialog-body"> |
| | | <el-form ref="queryParamsRef" :model="searchParams" class="history-search"> |
| | | <el-row :gutter="12"> |
| | | <el-col :span="5"> |
| | | <el-form-item label="关键字" prop="keyword"> |
| | | <el-input v-model="searchParams.keyword" placeholder="名称/序列号" clearable @clear="handleSearch" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="5"> |
| | | <el-form-item label="日期" prop="dateRange"> |
| | | <el-date-picker |
| | | v-model="searchParams.dateRange" |
| | | type="daterange" |
| | | range-separator="至" |
| | | start-placeholder="开始日期" |
| | | end-placeholder="结束日期" |
| | | value-format="YYYY/MM/DD" |
| | | @change="handleSearch" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="5"> |
| | | <el-form-item label="区域" prop="area"> |
| | | <el-tree-select |
| | | v-model="searchParams.area" |
| | | :data="areaTree" |
| | | :props="areaTreeProps" |
| | | node-key="value" |
| | | check-strictly |
| | | clearable |
| | | placeholder="请选择" |
| | | @change="handleSearch" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="5"> |
| | | <el-form-item label="无人机类型" prop="droneType"> |
| | | <el-select |
| | | v-model="searchParams.droneType" |
| | | placeholder="请选择" |
| | | clearable |
| | | @change="handleSearch" |
| | | > |
| | | <el-option v-for="item in droneTypeOptions" :key="item" :label="item" :value="item" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="4" class="history-search-actions"> |
| | | <el-form-item> |
| | | <el-button @click="resetForm">重置</el-button> |
| | | <el-button type="primary" @click="handleSearch">查询</el-button> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | </el-form> |
| | | <el-dialog class="ztzf-data-cockpit-dialog" append-to-body v-model="visibleModel" :title="dialogTitle" |
| | | :close-on-click-modal="false" :destroy-on-close="true"> |
| | | <el-form ref="queryParamsRef" :model="searchParams" class="history-search"> |
| | | <el-row :gutter="12"> |
| | | <el-col :span="4"> |
| | | <el-form-item label="关键字" prop="keyword"> |
| | | <el-input class="ztzf-data-cockpit-search-input" v-model="searchParams.keyword" |
| | | placeholder="名称/序列号" clearable @clear="handleSearch" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="5"> |
| | | <el-form-item prop="dateRange"> |
| | | <el-date-picker class="ztzf-data-cockpit-date-picker" |
| | | popper-class="ztzf-data-cockpit-date-picker-popper" v-model="searchParams.dateRange" |
| | | type="daterange" range-separator="至" start-placeholder="开始日期" end-placeholder="结束日期" |
| | | value-format="YYYY/MM/DD" @change="handleSearch" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="4"> |
| | | <el-form-item label="区域" prop="area"> |
| | | <el-tree-select class="ztzf-data-cockpit-select" popper-class="ztzf-tree-cockpit-select-popper" v-model="searchParams.area" :data="areaTree" :props="areaTreeProps" |
| | | node-key="value" check-strictly clearable placeholder="请选择" @change="handleSearch" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="5"> |
| | | <el-form-item label="无人机类型" prop="droneType"> |
| | | <el-select class="ztzf-data-cockpit-select" popper-class="ztzf-data-cockpit-select-popper" |
| | | v-model="searchParams.droneType" placeholder="请选择" clearable @change="handleSearch"> |
| | | <el-option v-for="item in droneTypeOptions" :key="item.value" :label="item.label" |
| | | :value="item.value" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="6" class="history-search-actions"> |
| | | <el-form-item> |
| | | <el-button :icon="RefreshRight" @click="resetForm"></el-button> |
| | | <el-button :icon="Search" @click="handleSearch"></el-button> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | </el-form> |
| | | |
| | | <el-table v-loading="loading" :data="pagedList" height="360" class="history-table"> |
| | | <el-table-column type="index" width="60" label="序号" /> |
| | | <el-table-column prop="droneName" label="无人机名称" min-width="120" /> |
| | | <el-table-column prop="serialNumber" label="无人机序列号" min-width="140" /> |
| | | <el-table-column prop="droneType" label="无人机类型" min-width="110" /> |
| | | <el-table-column prop="area" label="区域" min-width="90" /> |
| | | <el-table-column prop="dataSource" label="数据来源" min-width="110" /> |
| | | <el-table-column prop="frequency" label="信号频段" min-width="100" /> |
| | | <el-table-column prop="discoveredAt" label="发现时间" min-width="150" /> |
| | | <el-table-column prop="stayTime" label="停留时间" min-width="110" /> |
| | | <el-table-column prop="counterMethod" label="反制方式" min-width="110" /> |
| | | </el-table> |
| | | |
| | | <div class="history-pagination"> |
| | | <el-pagination |
| | | v-model:current-page="searchParams.current" |
| | | v-model:page-size="searchParams.size" |
| | | :total="total" |
| | | /> |
| | | <div class="table-container" v-loading="loading" element-loading-background="rgba(5, 5, 15, 0.6)"> |
| | | <div class="table-content"> |
| | | <el-table class="ztzf-data-cockpit-table" :data="list"> |
| | | <el-table-column type="index" width="60" label="序号" /> |
| | | <el-table-column prop="droneName" label="无人机名称" min-width="120" /> |
| | | <el-table-column prop="droneSerialNo" label="无人机序列号" min-width="140" /> |
| | | <el-table-column label="无人机类型" min-width="110"> |
| | | <template #default="{ row }"> |
| | | {{ getDroneTypeText(row.droneType) }} |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="areaName" label="区域" min-width="90" /> |
| | | <el-table-column prop="deviceName" label="数据来源" min-width="110" /> |
| | | <el-table-column label="信号频段" min-width="100"> |
| | | <template #default="{ row }"> |
| | | {{ formatFrequency(row.signalFreqMhz) }} |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="alarmTime" label="发现时间" min-width="150" /> |
| | | <el-table-column prop="stayDuration" label="停留时间" min-width="110" /> |
| | | <el-table-column label="反制方式" min-width="110"> |
| | | <template #default="{ row }"> |
| | | {{ getCounterWayText(row.counterWay) }} |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | </div> |
| | | |
| | | <div class="table-pagination"> |
| | | <el-pagination popper-class="ztzf-data-cockpit-select-popper" v-model:current-page="searchParams.current" v-model:page-size="searchParams.size" |
| | | layout="total, prev, pager, next, sizes" |
| | | :total="total" @change="getList" /> |
| | | </div> |
| | | </div> |
| | | </el-dialog> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { computed, ref } from 'vue' |
| | | import { Search, RefreshRight } from '@element-plus/icons-vue' |
| | | import { computed, ref, watch } from 'vue' |
| | | import { alarmLogApi } from '@/api/dataCockpit' |
| | | |
| | | const props = defineProps({ |
| | | modelValue: { |
| | |
| | | area: '', |
| | | droneType: '', |
| | | current: 1, |
| | | size: 6 |
| | | size: 10 |
| | | }) |
| | | const searchParams = ref(initSearchParams()) |
| | | const queryParamsRef = ref(null) |
| | | const loading = ref(false) |
| | | const list = ref([]) |
| | | const total = ref(0) |
| | | const areaTree = ref([ |
| | | { |
| | | label: '古村区', |
| | |
| | | children: 'children' |
| | | } |
| | | |
| | | const historyList = computed(() => { |
| | | const dataSource = props.device?.name || '侦测反制设备名称' |
| | | return [ |
| | | { |
| | | id: 'his_001', |
| | | droneName: '无人机名称', |
| | | serialNumber: 'XLH789456', |
| | | droneType: '微型机', |
| | | area: '古村区', |
| | | dataSource, |
| | | frequency: '5800MHZ', |
| | | discoveredAt: '2025/12/26 12:15:26', |
| | | stayTime: '00:10:50', |
| | | counterMethod: '信号干扰' |
| | | }, |
| | | { |
| | | id: 'his_002', |
| | | droneName: '无人机名称', |
| | | serialNumber: 'XLH789456', |
| | | droneType: '微型机', |
| | | area: '古村区', |
| | | dataSource, |
| | | frequency: '5800MHZ', |
| | | discoveredAt: '2025/12/26 12:18:06', |
| | | stayTime: '00:08:12', |
| | | counterMethod: '信号干扰' |
| | | }, |
| | | { |
| | | id: 'his_003', |
| | | droneName: '无人机名称', |
| | | serialNumber: 'XLH789456', |
| | | droneType: '微型机', |
| | | area: '古村区', |
| | | dataSource, |
| | | frequency: '2400MHZ', |
| | | discoveredAt: '2025/12/26 12:22:31', |
| | | stayTime: '00:06:09', |
| | | counterMethod: '诱导驱离' |
| | | }, |
| | | { |
| | | id: 'his_004', |
| | | droneName: '无人机名称', |
| | | serialNumber: 'XLH789456', |
| | | droneType: '微型机', |
| | | area: '古村区', |
| | | dataSource, |
| | | frequency: '2400MHZ', |
| | | discoveredAt: '2025/12/26 12:28:44', |
| | | stayTime: '00:12:03', |
| | | counterMethod: '诱导驱离' |
| | | }, |
| | | { |
| | | id: 'his_005', |
| | | droneName: '无人机名称', |
| | | serialNumber: 'XLH789456', |
| | | droneType: '微型机', |
| | | area: '古村区', |
| | | dataSource, |
| | | frequency: '5800MHZ', |
| | | discoveredAt: '2025/12/26 12:32:10', |
| | | stayTime: '00:04:39', |
| | | counterMethod: '信号干扰' |
| | | }, |
| | | { |
| | | id: 'his_006', |
| | | droneName: '无人机名称', |
| | | serialNumber: 'XLH789456', |
| | | droneType: '微型机', |
| | | area: '古村区', |
| | | dataSource, |
| | | frequency: '5800MHZ', |
| | | discoveredAt: '2025/12/26 12:36:42', |
| | | stayTime: '00:07:21', |
| | | counterMethod: '信号干扰' |
| | | const droneTypeOptions = [ |
| | | { label: '微型机', value: '1' }, |
| | | { label: '植保机', value: '2' } |
| | | ] |
| | | |
| | | const getList = async () => { |
| | | if (!props.device?.id) { |
| | | list.value = [] |
| | | total.value = 0 |
| | | return |
| | | } |
| | | const [startTime, endTime] = searchParams.value.dateRange || [] |
| | | const keyword = (searchParams.value.keyword || '').trim() |
| | | const params = { |
| | | alarmType: '2', |
| | | deviceId: props.device.id, |
| | | current: searchParams.value.current, |
| | | size: searchParams.value.size, |
| | | startTime, |
| | | endTime, |
| | | areaName: searchParams.value.area || undefined, |
| | | droneType: searchParams.value.droneType || undefined, |
| | | droneName: keyword || undefined, |
| | | } |
| | | loading.value = true |
| | | try { |
| | | const res = await alarmLogApi(params) |
| | | list.value = res?.data?.data?.records ?? [] |
| | | total.value = res?.data?.data?.total ?? 0 |
| | | } finally { |
| | | loading.value = false |
| | | } |
| | | } |
| | | |
| | | function handleSearch () { |
| | | searchParams.value.current = 1 |
| | | getList() |
| | | } |
| | | |
| | | function resetForm () { |
| | | searchParams.value = initSearchParams() |
| | | |
| | | getList() |
| | | } |
| | | |
| | | const formatFrequency = (value) => { |
| | | if (value == null || value === '') return '-' |
| | | return `${value}MHZ` |
| | | } |
| | | |
| | | const getCounterWayText = (value) => { |
| | | if (value === 1 || value === '1') return '信号干扰' |
| | | if (value === 2 || value === '2') return '诱导驱离' |
| | | if (value === 3 || value === '3') return '无' |
| | | return value || '-' |
| | | } |
| | | |
| | | const getDroneTypeText = (value) => { |
| | | if (value === 1 || value === '1') return '微型机' |
| | | if (value === 2 || value === '2') return '植保机' |
| | | return value || '-' |
| | | } |
| | | |
| | | watch( |
| | | () => visibleModel.value, |
| | | (visible) => { |
| | | if (visible) { |
| | | searchParams.value.current = 1 |
| | | getList() |
| | | } |
| | | ] |
| | | }) |
| | | |
| | | const droneTypeOptions = computed(() => { |
| | | const types = historyList.value.map((item) => item.droneType).filter(Boolean) |
| | | return Array.from(new Set(types)) |
| | | }) |
| | | |
| | | const filteredList = computed(() => { |
| | | const { keyword, dateRange, area, droneType } = searchParams.value |
| | | const [startDate, endDate] = dateRange || [] |
| | | return historyList.value.filter((item) => { |
| | | const keywordMatch = |
| | | !keyword || item.droneName.includes(keyword) || item.serialNumber.includes(keyword) |
| | | const typeMatch = !droneType || item.droneType === droneType |
| | | const areaMatch = !area || item.area.includes(area) |
| | | const dateMatch = |
| | | !startDate || !endDate || isWithinDateRange(item.discoveredAt, startDate, endDate) |
| | | return keywordMatch && typeMatch && areaMatch && dateMatch |
| | | }) |
| | | }) |
| | | |
| | | const total = computed(() => filteredList.value.length) |
| | | |
| | | const pagedList = computed(() => { |
| | | const { current, size } = searchParams.value |
| | | const start = (current - 1) * size |
| | | return filteredList.value.slice(start, start + size) |
| | | }) |
| | | |
| | | function handleSearch() { |
| | | searchParams.value.current = 1 |
| | | } |
| | | |
| | | function resetForm() { |
| | | queryParamsRef.value?.resetFields() |
| | | searchParams.value.current = 1 |
| | | } |
| | | |
| | | function isWithinDateRange(value, start, end) { |
| | | const dateValue = new Date(value) |
| | | const startDate = new Date(`${start} 00:00:00`) |
| | | const endDate = new Date(`${end} 23:59:59`) |
| | | return dateValue >= startDate && dateValue <= endDate |
| | | } |
| | | } |
| | | ) |
| | | |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | .dialog-body { |
| | | display: flex; |
| | | flex-direction: column; |
| | | gap: 16px; |
| | | color: #C3C3DD; |
| | | } |
| | | |
| | | .history-search { |
| | | padding: 8px 12px 4px; |
| | | background: rgba(10, 14, 34, 0.6); |
| | | border: 1px solid rgba(255, 255, 255, 0.08); |
| | | border-radius: 6px; |
| | | } |
| | | |
| | | .history-search :deep(.el-date-editor), |
| | | .history-search :deep(.el-select), |
| | | .history-search :deep(.el-tree-select) { |
| | | width: 100%; |
| | | } |
| | | |
| | | .history-search-actions :deep(.el-form-item__content) { |
| | | justify-content: flex-end; |
| | | gap: 8px; |
| | | } |
| | | |
| | | .history-table { |
| | | margin-top: 8px; |
| | | --el-table-border-color: rgba(255, 255, 255, 0.08); |
| | | --el-table-header-bg-color: rgba(20, 24, 48, 0.9); |
| | | --el-table-row-hover-bg-color: rgba(255, 255, 255, 0.03); |
| | | --el-table-text-color: #C3C3DD; |
| | | --el-table-header-text-color: #FFFFFF; |
| | | } |
| | | |
| | | .history-pagination { |
| | | display: flex; |
| | | justify-content: flex-end; |
| | | padding-top: 8px; |
| | | } |
| | | </style> |
| | | <style lang="scss" scoped></style> |
| | |
| | | position: absolute; |
| | | top: 50%; |
| | | left: 357px; |
| | | background: rgba(17, 23, 34, 0.8); |
| | | border: 1px solid #333355; |
| | | border-left: none; |
| | | border-radius: 0 4px 4px 0; |
| | | cursor: pointer; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | color: #fff; |
| | | z-index: 10; |
| | | backdrop-filter: blur(5px); |
| | | transform: translateY(-50%); |
| | | |
| | | .arrow { |
| | |
| | | } |
| | | |
| | | .category-container { |
| | | position: relative; |
| | | display: flex; |
| | | justify-content: space-between; |
| | | |
| | | &::after { |
| | | content: ''; |
| | | position: absolute; |
| | | left: 0; |
| | | bottom: 0; |
| | | width: 100%; |
| | | height: 1px; |
| | | background: #333355; |
| | | } |
| | | |
| | | .category-item { |
| | | position: relative; |
| | |
| | | left: 0; |
| | | bottom: 0; |
| | | width: 100%; |
| | | height: 1px; |
| | | background: #333355; |
| | | height: 0; |
| | | } |
| | | |
| | | &.active::after { |
| | |
| | | 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; |
| | | z-index: 9; |
| | | } |
| | | |
| | | .badge { |
| | |
| | | <template> |
| | | <div class="ztzf-cesium map-container" id="cesium"> |
| | | <div class="ztzf-cesium map-container" id="cesium"></div> |
| | | <div class="layer-control-root" :class="{ collapsed: props.leftCollapsed }"> |
| | | <div class="layer-control-wrap" ref="layerWrapRef"> |
| | | <div class="layer-control" @click="toggleLayerPanel"> |
| | | <img :src="layerControlIcon" alt="图层控制"> |
| | | </div> |
| | | <div v-if="showLayerPanel" class="layer-panel"> |
| | | <div class="panel-title">图层管理</div> |
| | | |
| | | <div class="panel-content"> |
| | | <el-tree :data="layerTree" show-checkbox default-expand-all node-key="key" :props="layerTreeProps" |
| | | :default-checked-keys="defaultCheckedKeys" /> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import * as Cesium from 'cesium' |
| | | import { PublicCesium } from '@/utils/cesium/publicCesium' |
| | | import layerControlIcon from '@/assets/images/dataCockpit/layerControl.png' |
| | | import equipmentIcon from '@/assets/images/dataCockpit/map/equipment.png' |
| | | |
| | | const props = defineProps({ |
| | | onlineDevices: { |
| | | type: Array, |
| | | default: () => [] |
| | | }, |
| | | leftCollapsed: { |
| | | type: Boolean, |
| | | default: false |
| | | } |
| | | }) |
| | | |
| | | let viewInstance = null |
| | | let viewer = null |
| | | const deviceEntityIds = new Set() |
| | | const showLayerPanel = ref(false) |
| | | const layerWrapRef = ref(null) |
| | | const layerTreeProps = { |
| | | label: 'label', |
| | | children: 'children' |
| | | } |
| | | const defaultCheckedKeys = ['global', 'city-base'] |
| | | const layerTree = ref([ |
| | | { |
| | | key: 'base', |
| | | label: '地理信息图层', |
| | | children: [ |
| | | { key: 'global', label: '全球地形' }, |
| | | { key: 'admin', label: '行政区划' } |
| | | ] |
| | | }, |
| | | { |
| | | key: 'city', |
| | | label: '城市CIM图层', |
| | | children: [ |
| | | { key: 'city-base', label: '皖山白模' }, |
| | | { key: 'city-grid', label: '皖山白模光栅网格' }, |
| | | { key: 'city-tilt', label: '皖山倾斜摄影' }, |
| | | { key: 'city-tilt-grid', label: '皖山倾斜摄影网格' } |
| | | ] |
| | | }, |
| | | { |
| | | key: 'sky', |
| | | label: '空域要素图层', |
| | | children: [ |
| | | { key: 'airspace', label: '空域边界' }, |
| | | { key: 'route', label: '飞行航路' } |
| | | ] |
| | | } |
| | | ]) |
| | | |
| | | const getDevicePosition = (item) => { |
| | | const longitudeRaw = item.longitude ?? item.lng ?? item.lon |
| | | const latitudeRaw = item.latitude ?? item.lat |
| | | if (longitudeRaw == null || latitudeRaw == null) return null |
| | | const longitude = Number(longitudeRaw) |
| | | const latitude = Number(latitudeRaw) |
| | | if (!Number.isFinite(longitude) || !Number.isFinite(latitude)) return null |
| | | return { longitude, latitude } |
| | | } |
| | | |
| | | const clearDeviceEntities = () => { |
| | | if (!viewer) return |
| | | deviceEntityIds.forEach((id) => { |
| | | viewer.entities.removeById(id) |
| | | }) |
| | | deviceEntityIds.clear() |
| | | } |
| | | |
| | | const RING_STYLES = [ |
| | | { inner: 0, outer: 5000, gradient: ['#FF361C', '#360B00'] }, |
| | | { inner: 5000, outer: 8000, gradient: ['#FFC609', '#583300'] }, |
| | | { inner: 8000, outer: 10000, gradient: ['#2AEDBF', '#012B11'] } |
| | | ] |
| | | |
| | | const MATERIAL_TYPE = 'RadialGradientMaterial' |
| | | let materialRegistered = false |
| | | |
| | | const registerRadialGradientMaterial = () => { |
| | | if (materialRegistered || !Cesium?.Material) return |
| | | materialRegistered = true |
| | | Cesium.Material._materialCache.addMaterial(MATERIAL_TYPE, { |
| | | fabric: { |
| | | type: MATERIAL_TYPE, |
| | | uniforms: { |
| | | color1: new Cesium.Color(1.0, 1.0, 1.0, 1.0), |
| | | color2: new Cesium.Color(0.0, 0.0, 0.0, 1.0) |
| | | }, |
| | | source: ` |
| | | czm_material czm_getMaterial(czm_materialInput materialInput) { |
| | | czm_material material = czm_getDefaultMaterial(materialInput); |
| | | vec2 st = materialInput.st - vec2(0.5); |
| | | float t = clamp(length(st) * 2.0, 0.0, 1.0); |
| | | vec4 color = mix(color1, color2, t); |
| | | material.diffuse = color.rgb; |
| | | material.alpha = color.a; |
| | | return material; |
| | | } |
| | | ` |
| | | }, |
| | | translucent: () => true |
| | | }) |
| | | } |
| | | |
| | | class RadialGradientMaterialProperty { |
| | | constructor(color1, color2) { |
| | | this._definitionChanged = new Cesium.Event() |
| | | this.color1 = color1 |
| | | this.color2 = color2 |
| | | } |
| | | |
| | | get isConstant () { |
| | | return true |
| | | } |
| | | |
| | | get definitionChanged () { |
| | | return this._definitionChanged |
| | | } |
| | | |
| | | getType () { |
| | | return MATERIAL_TYPE |
| | | } |
| | | |
| | | getValue (time, result) { |
| | | const target = result || {} |
| | | target.color1 = this.color1 |
| | | target.color2 = this.color2 |
| | | return target |
| | | } |
| | | |
| | | equals (other) { |
| | | return ( |
| | | other instanceof RadialGradientMaterialProperty && |
| | | Cesium.Color.equals(this.color1, other.color1) && |
| | | Cesium.Color.equals(this.color2, other.color2) |
| | | ) |
| | | } |
| | | } |
| | | |
| | | const buildCirclePositions = (center, radiusMeters, steps = 64) => { |
| | | const positions = [] |
| | | const latRad = Cesium.Math.toRadians(center.latitude) |
| | | const metersToLat = 1 / 111320 |
| | | const metersToLon = 1 / (111320 * Math.cos(latRad)) |
| | | for (let i = 0; i <= steps; i += 1) { |
| | | const angle = Cesium.Math.toRadians((i / steps) * 360) |
| | | const dx = radiusMeters * Math.cos(angle) |
| | | const dy = radiusMeters * Math.sin(angle) |
| | | const lon = center.longitude + dx * metersToLon |
| | | const lat = center.latitude + dy * metersToLat |
| | | positions.push(Cesium.Cartesian3.fromDegrees(lon, lat)) |
| | | } |
| | | return positions |
| | | } |
| | | |
| | | const addDeviceRings = (center, baseId) => { |
| | | RING_STYLES.forEach((ring, index) => { |
| | | const outerPositions = buildCirclePositions(center, ring.outer) |
| | | const holes = ring.inner |
| | | ? [new Cesium.PolygonHierarchy(buildCirclePositions(center, ring.inner))] |
| | | : [] |
| | | const entityId = `${baseId}-ring-${index}` |
| | | deviceEntityIds.add(entityId) |
| | | registerRadialGradientMaterial() |
| | | const [startColor, endColor] = ring.gradient |
| | | const color1 = Cesium.Color.fromCssColorString(startColor).withAlpha(0.34) |
| | | const color2 = Cesium.Color.fromCssColorString(endColor).withAlpha(0.34) |
| | | const material = new RadialGradientMaterialProperty(color1, color2) |
| | | viewer.entities.add({ |
| | | id: entityId, |
| | | polygon: { |
| | | hierarchy: new Cesium.PolygonHierarchy(outerPositions, holes), |
| | | material |
| | | } |
| | | }) |
| | | }) |
| | | } |
| | | |
| | | const renderDeviceEntities = (devices) => { |
| | | console.log(devices, 'devices') |
| | | |
| | | if (!viewer) return |
| | | |
| | | clearDeviceEntities() |
| | | devices.forEach((item, index) => { |
| | | const position = getDevicePosition(item) |
| | | if (!position) return |
| | | const entityId = `online-device-${item.id ?? index}` |
| | | deviceEntityIds.add(entityId) |
| | | addDeviceRings(position, entityId) |
| | | viewer.entities.add({ |
| | | id: entityId, |
| | | position: Cesium.Cartesian3.fromDegrees(position.longitude, position.latitude, 0), |
| | | billboard: { |
| | | image: equipmentIcon, |
| | | width: 40.34, |
| | | height: 40.34 |
| | | } |
| | | }) |
| | | }) |
| | | } |
| | | |
| | | watch( |
| | | () => props.onlineDevices, |
| | | (devices) => { |
| | | renderDeviceEntities(devices || []) |
| | | }, |
| | | { deep: true } |
| | | ) |
| | | |
| | | watch( |
| | | () => props.leftCollapsed, |
| | | (isCollapsed) => { |
| | | if (isCollapsed) showLayerPanel.value = false |
| | | } |
| | | ) |
| | | |
| | | const toggleLayerPanel = () => { |
| | | showLayerPanel.value = !showLayerPanel.value |
| | | } |
| | | |
| | | const handleClickOutside = (event) => { |
| | | if (!showLayerPanel.value) return |
| | | const target = event.target |
| | | if (layerWrapRef.value?.contains(target)) return |
| | | showLayerPanel.value = false |
| | | } |
| | | |
| | | onMounted(() => { |
| | | document.addEventListener('click', handleClickOutside) |
| | | viewInstance = new PublicCesium({ |
| | | dom: 'cesium', |
| | | flatMode: false, |
| | | terrain: false, |
| | | layerMode: 4, |
| | | contour: false, |
| | | contour: false |
| | | }) |
| | | |
| | | viewer = viewInstance.getViewer() |
| | | }) |
| | | renderDeviceEntities(props.onlineDevices) |
| | | }) |
| | | |
| | | onBeforeUnmount(() => { |
| | | document.removeEventListener('click', handleClickOutside) |
| | | clearDeviceEntities() |
| | | if (viewInstance) { |
| | | viewInstance?.destroy() |
| | | viewInstance?.viewerDestroy() |
| | | viewInstance = null |
| | | } |
| | | |
| | |
| | | width: 100%; |
| | | height: 100%; |
| | | } |
| | | </style> |
| | | |
| | | .layer-control-root { |
| | | position: absolute; |
| | | left: 411px; |
| | | bottom: 22px; |
| | | z-index: 9; |
| | | transition: transform 0.3s ease-in-out; |
| | | pointer-events: none; |
| | | |
| | | &.collapsed { |
| | | transform: translateX(-401px); |
| | | } |
| | | } |
| | | |
| | | .layer-control-wrap { |
| | | position: relative; |
| | | display: flex; |
| | | align-items: flex-end; |
| | | pointer-events: auto; |
| | | } |
| | | |
| | | .layer-control { |
| | | width: 34px; |
| | | height: 34px; |
| | | cursor: pointer; |
| | | |
| | | img { |
| | | width: 100%; |
| | | height: 100%; |
| | | display: block; |
| | | } |
| | | } |
| | | |
| | | .layer-panel { |
| | | display: flex; |
| | | flex-direction: column; |
| | | position: absolute; |
| | | left: 46px; |
| | | bottom: 0; |
| | | width: 160px; |
| | | max-height: 442px; |
| | | background: #191932; |
| | | border-radius: 8px 8px 8px 8px; |
| | | |
| | | .panel-title { |
| | | padding: 0 16px; |
| | | line-height: 42px; |
| | | |
| | | font-family: Open Sans, Open Sans; |
| | | font-weight: 400; |
| | | font-size: 12px; |
| | | color: #FFFFFF; |
| | | text-align: left; |
| | | font-style: normal; |
| | | text-transform: none; |
| | | |
| | | border-bottom: 1px solid rgba(70,70,100,0.5); |
| | | |
| | | box-sizing: border-box; |
| | | } |
| | | |
| | | .panel-content { |
| | | padding: 0 16px; |
| | | height: 0; |
| | | flex: 1; |
| | | overflow: auto; |
| | | } |
| | | |
| | | ::v-deep(.el-tree) { |
| | | background: transparent; |
| | | color: #C3C3DD; |
| | | font-size: 12px; |
| | | |
| | | .el-tree-node { |
| | | line-height: 30px !important; |
| | | |
| | | .el-tree-node__content { |
| | | display: flex; |
| | | align-items: center; |
| | | height: 40px !important; |
| | | line-height: 40px !important; |
| | | border-bottom: 1px solid rgba(70,70,100,0.5); |
| | | box-sizing: border-box; |
| | | } |
| | | |
| | | .el-tree-node__children { |
| | | .el-tree-node__content { |
| | | border: none; |
| | | } |
| | | } |
| | | } |
| | | |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | .layer-panel :deep(.el-tree-node__label) { |
| | | color: #C3C3DD; |
| | | } |
| | | |
| | | .layer-panel :deep(.el-tree-node__expand-icon) { |
| | | order: 3; |
| | | margin-left: auto; |
| | | } |
| | | |
| | | .layer-panel :deep(.el-tree-node__expand-icon.is-leaf) { |
| | | visibility: hidden; |
| | | } |
| | | |
| | | .layer-panel :deep(.el-checkbox) { |
| | | order: 1; |
| | | } |
| | | |
| | | .layer-panel :deep(.el-tree-node__label) { |
| | | order: 2; |
| | | } |
| | | |
| | | .layer-panel :deep(.el-tree-node__expand-icon:not(.is-leaf) ~ .el-checkbox) { |
| | | display: none; |
| | | } |
| | | |
| | | .layer-panel :deep(.el-tree-node__content:hover) { |
| | | background: transparent !important; |
| | | } |
| | | |
| | | .layer-panel :deep(.el-tree-node.is-current > .el-tree-node__content) { |
| | | background: transparent !important; |
| | | color: #FFFFFF; |
| | | } |
| | | |
| | | .layer-panel :deep(.el-tree-node.is-current > .el-tree-node__content .el-tree-node__label) { |
| | | color: #FFFFFF; |
| | | } |
| | | |
| | | .layer-panel :deep(.el-checkbox__input.is-checked .el-checkbox__inner) { |
| | | background-color: #023AFF; |
| | | border-color: #023AFF; |
| | | } |
| | | |
| | | .layer-panel :deep(.el-checkbox__inner) { |
| | | background-color: transparent; |
| | | border-color: #A1A3D4; |
| | | } |
| | | </style> |
| | |
| | | * @Author : yuan |
| | | * @Date : 2026-01-07 15:17:54 |
| | | * @LastEditors : yuan |
| | | * @LastEditTime : 2026-01-08 17:04:11 |
| | | * @LastEditTime : 2026-01-09 16:54:31 |
| | | * @FilePath : \applications\drone-command\src\views\dataCockpit\components\RightContainer.vue |
| | | * @Description : |
| | | * Copyright 2026 OBKoro1, All Rights Reserved. |
| | |
| | | import EmptyState from './EmptyState.vue' |
| | | import zcsbLogo from '@/assets/images/dataCockpit/zcsb.png' |
| | | import fzsbLogo from '@/assets/images/dataCockpit/fzsb.png' |
| | | import { deviceSearchApi } from '@/api/dataCockpit' |
| | | import { deviceSearchApi, deviceStatisticsApi } from '@/api/dataCockpit' |
| | | |
| | | const props = defineProps({ |
| | | collapsed: { |
| | |
| | | } |
| | | }) |
| | | |
| | | const emit = defineEmits(['update:collapsed']) |
| | | const emit = defineEmits(['update:collapsed', 'update:onlineDevices']) |
| | | |
| | | const collapsedModel = computed({ |
| | | get: () => props.collapsed, |
| | |
| | | { |
| | | id: 1, |
| | | name: '侦测设备', |
| | | val: 169, |
| | | val: 0, |
| | | logo: zcsbLogo |
| | | }, |
| | | { |
| | | id: 2, |
| | | name: '反制设备', |
| | | val: 169, |
| | | val: 0, |
| | | logo: fzsbLogo |
| | | } |
| | | ]) |
| | |
| | | const res = await deviceSearchApi(params) |
| | | const records = res?.data?.data?.records ?? [] |
| | | counterDeviceStatusList.value = records.map(formatDeviceItem) |
| | | emit('update:onlineDevices', records) |
| | | } finally { |
| | | const elapsed = Date.now() - startAt |
| | | if (elapsed < minLoadingMs) { |
| | |
| | | |
| | | onMounted(() => { |
| | | fetchDeviceList() |
| | | fetchDeviceStatistics() |
| | | }) |
| | | |
| | | const normalizeType = (value) => { |
| | | if (value === 1 || value === '1') return '侦测设备' |
| | | if (value === 2 || value === '2') return '反制设备' |
| | | if (value === 'detect') return '侦测设备' |
| | | if (value === 'counter') return '反制设备' |
| | | return value |
| | | } |
| | | |
| | | const fetchDeviceStatistics = async () => { |
| | | const res = await deviceStatisticsApi() |
| | | const list = res?.data?.data ?? [] |
| | | const map = new Map(list.map((item) => [normalizeType(item.type), item.count])) |
| | | categoryList.value = categoryList.value.map((item) => ({ |
| | | ...item, |
| | | val: map.has(item.name) ? map.get(item.name) : item.val |
| | | })) |
| | | } |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | |
| | | position: absolute; |
| | | top: 50%; |
| | | right: 357px; |
| | | 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; |
| | | z-index: 10; |
| | | backdrop-filter: blur(5px); |
| | | transform: translateY(-50%); |
| | | |
| | | .arrow { |
| | |
| | | * @Author : yuan |
| | | * @Date : 2026-01-06 16:35:50 |
| | | * @LastEditors : yuan |
| | | * @LastEditTime : 2026-01-08 09:45:25 |
| | | * @LastEditTime : 2026-01-09 16:34:39 |
| | | * @FilePath : \applications\drone-command\src\views\dataCockpit\index.vue |
| | | * @Description : |
| | | * Copyright 2026 OBKoro1, All Rights Reserved. |
| | |
| | | --> |
| | | <template> |
| | | <div class="page-container"> |
| | | <MapContainer /> |
| | | <MapContainer :online-devices="onlineDevices" :left-collapsed="leftCollapsed" /> |
| | | <LeftContainer class="left-container" v-model:activeId="leftActiveId" v-model:collapsed="leftCollapsed" /> |
| | | <RightContainer class="right-container" v-model:collapsed="rightCollapsed" /> |
| | | <RightContainer class="right-container" v-model:collapsed="rightCollapsed" v-model:onlineDevices="onlineDevices" /> |
| | | <CenterContainer @select-warning="onSelectWarning" @select-equipment="onSelectEquipment" /> |
| | | </div> |
| | | </template> |
| | |
| | | const leftCollapsed = ref(false); |
| | | |
| | | const rightCollapsed = ref(false); |
| | | const onlineDevices = ref([]); |
| | | |
| | | const onSelectWarning = (type) => { |
| | | leftActiveId.value = type; |
| | |
| | | bottom: 0; |
| | | width: 401px; |
| | | z-index: 9; |
| | | backdrop-filter: blur(5px); |
| | | backdrop-filter: blur(2px); |
| | | |
| | | ::v-deep(.wrapper) { |
| | | display: flex; |
| | |
| | | padding: 20px; |
| | | width: 300px; |
| | | background: rgba(0,0,0,0.3); |
| | | backdrop-filter: blur(16px); |
| | | border-radius: 10px 10px 10px 10px; |
| | | } |
| | | } |