From 8e504b07e0070e50e2e04c46d783ca2df2794657 Mon Sep 17 00:00:00 2001
From: shuishen <1109946754@qq.com>
Date: Thu, 08 Jan 2026 16:38:43 +0800
Subject: [PATCH] feat:数据驾驶舱页面搭建
---
applications/drone-command/src/assets/images/dataCockpit/title-bg.png | 0
applications/drone-command/src/styles/element-ui.scss | 1724 +++++++++++++++++++--------------
applications/drone-command/src/assets/images/dataCockpit/fzsb.png | 0
applications/drone-command/src/views/dataCockpit/components/templateComponents/HistoryTemplate.vue | 110 ++
applications/drone-command/src/views/dataCockpit/components/templateComponents/RealEquipmentTemplate.vue | 199 +++
applications/drone-command/src/views/dataCockpit/index.vue | 4
applications/drone-command/src/views/dataCockpit/components/EquipmentWarning.vue | 61 +
applications/drone-command/src/views/dataCockpit/components/MapContainer.vue | 2
applications/drone-command/src/views/dataCockpit/components/RealWarning.vue | 76 +
applications/drone-command/src/views/dataCockpit/components/RightContainer.vue | 204 +++
applications/drone-command/src/views/dataCockpit/components/templateComponents/TitleTemplate.vue | 43
applications/drone-command/src/assets/images/dataCockpit/zcsb.png | 0
applications/drone-command/src/views/dataCockpit/components/templateComponents/EquipmentTemplate.vue | 171 +++
applications/drone-command/env/.env.development | 12
applications/drone-command/src/views/dataCockpit/components/templateComponents/RealTemplate.vue | 204 ++++
applications/drone-command/src/views/dataCockpit/components/HistoryWarning.vue | 136 ++
applications/drone-command/src/views/dataCockpit/components/LeftContainer.vue | 95 +
applications/drone-command/src/views/dataCockpit/components/CenterContainer.vue | 14
18 files changed, 2,324 insertions(+), 731 deletions(-)
diff --git a/applications/drone-command/env/.env.development b/applications/drone-command/env/.env.development
index 3225ff7..4b360d8 100644
--- a/applications/drone-command/env/.env.development
+++ b/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/'
diff --git a/applications/drone-command/src/assets/images/dataCockpit/fzsb.png b/applications/drone-command/src/assets/images/dataCockpit/fzsb.png
new file mode 100644
index 0000000..163088c
--- /dev/null
+++ b/applications/drone-command/src/assets/images/dataCockpit/fzsb.png
Binary files differ
diff --git a/applications/drone-command/src/assets/images/dataCockpit/title-bg.png b/applications/drone-command/src/assets/images/dataCockpit/title-bg.png
new file mode 100644
index 0000000..8a1a87d
--- /dev/null
+++ b/applications/drone-command/src/assets/images/dataCockpit/title-bg.png
Binary files differ
diff --git a/applications/drone-command/src/assets/images/dataCockpit/zcsb.png b/applications/drone-command/src/assets/images/dataCockpit/zcsb.png
new file mode 100644
index 0000000..7476a30
--- /dev/null
+++ b/applications/drone-command/src/assets/images/dataCockpit/zcsb.png
Binary files differ
diff --git a/applications/drone-command/src/styles/element-ui.scss b/applications/drone-command/src/styles/element-ui.scss
index b10ca14..bcea1e1 100644
--- a/applications/drone-command/src/styles/element-ui.scss
+++ b/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;
- }
- }
-
\ No newline at end of file
+
+//======以下针对表格功能 增删查改样式和弹窗=========
+.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;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/applications/drone-command/src/views/dataCockpit/components/CenterContainer.vue b/applications/drone-command/src/views/dataCockpit/components/CenterContainer.vue
index 3545362..87ce805 100644
--- a/applications/drone-command/src/views/dataCockpit/components/CenterContainer.vue
+++ b/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>
\ No newline at end of file
+</style>
diff --git a/applications/drone-command/src/views/dataCockpit/components/EquipmentWarning.vue b/applications/drone-command/src/views/dataCockpit/components/EquipmentWarning.vue
new file mode 100644
index 0000000..15531ce
--- /dev/null
+++ b/applications/drone-command/src/views/dataCockpit/components/EquipmentWarning.vue
@@ -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>
\ No newline at end of file
diff --git a/applications/drone-command/src/views/dataCockpit/components/HistoryWarning.vue b/applications/drone-command/src/views/dataCockpit/components/HistoryWarning.vue
new file mode 100644
index 0000000..4ce65c7
--- /dev/null
+++ b/applications/drone-command/src/views/dataCockpit/components/HistoryWarning.vue
@@ -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>
\ No newline at end of file
diff --git a/applications/drone-command/src/views/dataCockpit/components/LeftContainer.vue b/applications/drone-command/src/views/dataCockpit/components/LeftContainer.vue
index 25fb897..0708d8a 100644
--- a/applications/drone-command/src/views/dataCockpit/components/LeftContainer.vue
+++ b/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>
\ No newline at end of file
diff --git a/applications/drone-command/src/views/dataCockpit/components/MapContainer.vue b/applications/drone-command/src/views/dataCockpit/components/MapContainer.vue
index bb01816..aa94178 100644
--- a/applications/drone-command/src/views/dataCockpit/components/MapContainer.vue
+++ b/applications/drone-command/src/views/dataCockpit/components/MapContainer.vue
@@ -22,7 +22,7 @@
onBeforeUnmount(() => {
if (viewInstance) {
- viewInstance.destroy()
+ viewInstance?.destroy()
viewInstance = null
}
diff --git a/applications/drone-command/src/views/dataCockpit/components/RealWarning.vue b/applications/drone-command/src/views/dataCockpit/components/RealWarning.vue
new file mode 100644
index 0000000..623a317
--- /dev/null
+++ b/applications/drone-command/src/views/dataCockpit/components/RealWarning.vue
@@ -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>
\ No newline at end of file
diff --git a/applications/drone-command/src/views/dataCockpit/components/RightContainer.vue b/applications/drone-command/src/views/dataCockpit/components/RightContainer.vue
index 4811ccb..40b82f2 100644
--- a/applications/drone-command/src/views/dataCockpit/components/RightContainer.vue
+++ b/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>
\ No newline at end of file
diff --git a/applications/drone-command/src/views/dataCockpit/components/templateComponents/EquipmentTemplate.vue b/applications/drone-command/src/views/dataCockpit/components/templateComponents/EquipmentTemplate.vue
new file mode 100644
index 0000000..2310b82
--- /dev/null
+++ b/applications/drone-command/src/views/dataCockpit/components/templateComponents/EquipmentTemplate.vue
@@ -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>
diff --git a/applications/drone-command/src/views/dataCockpit/components/templateComponents/HistoryTemplate.vue b/applications/drone-command/src/views/dataCockpit/components/templateComponents/HistoryTemplate.vue
new file mode 100644
index 0000000..b1bdf9d
--- /dev/null
+++ b/applications/drone-command/src/views/dataCockpit/components/templateComponents/HistoryTemplate.vue
@@ -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>
diff --git a/applications/drone-command/src/views/dataCockpit/components/templateComponents/RealEquipmentTemplate.vue b/applications/drone-command/src/views/dataCockpit/components/templateComponents/RealEquipmentTemplate.vue
new file mode 100644
index 0000000..c33a208
--- /dev/null
+++ b/applications/drone-command/src/views/dataCockpit/components/templateComponents/RealEquipmentTemplate.vue
@@ -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>
\ No newline at end of file
diff --git a/applications/drone-command/src/views/dataCockpit/components/templateComponents/RealTemplate.vue b/applications/drone-command/src/views/dataCockpit/components/templateComponents/RealTemplate.vue
new file mode 100644
index 0000000..f96a28b
--- /dev/null
+++ b/applications/drone-command/src/views/dataCockpit/components/templateComponents/RealTemplate.vue
@@ -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>
diff --git a/applications/drone-command/src/views/dataCockpit/components/templateComponents/TitleTemplate.vue b/applications/drone-command/src/views/dataCockpit/components/templateComponents/TitleTemplate.vue
new file mode 100644
index 0000000..9d3c9b0
--- /dev/null
+++ b/applications/drone-command/src/views/dataCockpit/components/templateComponents/TitleTemplate.vue
@@ -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>
\ No newline at end of file
diff --git a/applications/drone-command/src/views/dataCockpit/index.vue b/applications/drone-command/src/views/dataCockpit/index.vue
index f813e63..0fb5d8d 100644
--- a/applications/drone-command/src/views/dataCockpit/index.vue
+++ b/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;
--
Gitblit v1.9.3