7 files modified
11 files added
| | |
| | | ### |
| | | # @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' |
| | | |
| | | #开发环境配置 |
| | |
| | | |
| | | #开发环境代理地址(推荐本地新建文件 .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/' |
| | |
| | | .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;}} |
| | | padding: 0; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .ztzf-public-general-avue-crud { |
| | | .el-table { |
| | | tr { |
| | |
| | | } |
| | | } |
| | | } |
| | | |
| | | .ztzf-layer-input { |
| | | .el-input__wrapper { |
| | | padding: 0 8px !important; |
| | |
| | | } |
| | | } |
| | | } |
| | | |
| | | .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; |
| | |
| | | } |
| | | } |
| | | } |
| | | |
| | | .ztzf-select-popper.el-select__popper { |
| | | border:#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; |
| | | } |
| | |
| | | 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;} |
| | | 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 { |
| | |
| | | } |
| | | } |
| | | } |
| | | |
| | | .ztzf-custom-qrcode-popover { |
| | | //background: url("@/assets/images/home/eventOverviewDetail/qrCodeBg.png") no-repeat center center !important; |
| | | //background-size: cover !important; |
| | |
| | | background: #13c6ff !important; |
| | | } |
| | | } |
| | | |
| | | //======以下针对表格功能 增删查改样式和弹窗========= |
| | | .ztzf-dialog-mange { |
| | | .el-dialog__body { |
| | |
| | | overflow: scroll; |
| | | border-top: 0.1rem solid #f0f0f0; |
| | | } |
| | | |
| | | .el-dialog__footer { |
| | | z-index: 2; |
| | | display: block; |
| | |
| | | text-align: right; |
| | | } |
| | | } |
| | | |
| | | .ztzf-search-mange { |
| | | height: 40px; |
| | | |
| | | .search-contain { |
| | | display: flex;justify-content: space-between; |
| | | 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; |
| | |
| | | border-left: 0.1rem solid #ebeef5; |
| | | margin-left: 0; |
| | | margin-right: 0; |
| | | |
| | | .el-col { |
| | | padding-left: 0; |
| | | padding-right: 0; |
| | |
| | | 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; |
| | |
| | | } |
| | | } |
| | | |
| | | .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; |
| | | } |
| | | } |
| | | } |
| | | } |
| | |
| | | <template> |
| | | <template> |
| | | <div class="center-container"> |
| | | <div class="left-box"> |
| | | <div class="logo"> |
| | |
| | | </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> |
| | |
| | | </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> |
| | |
| | | </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([ |
| | | { |
| | |
| | | ]) |
| | | |
| | | const warningTypeClick = (type) => { |
| | | console.log('点击了告警类型:', type); |
| | | console.log('点击了告警类型:', type) |
| | | } |
| | | |
| | | const equipmentClick = (isHighlight) => { |
| | | if (isHighlight) { |
| | | console.log('点击了设备统计'); |
| | | console.log('点击了设备统计') |
| | | } |
| | | } |
| | | </script> |
| New file |
| | |
| | | <!-- |
| | | * @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> |
| New file |
| | |
| | | <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> |
| | |
| | | <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> |
| | |
| | | |
| | | onBeforeUnmount(() => { |
| | | if (viewInstance) { |
| | | viewInstance.destroy() |
| | | viewInstance?.destroy() |
| | | viewInstance = null |
| | | } |
| | | |
| New file |
| | |
| | | <!-- |
| | | * @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> |
| | |
| | | <!-- |
| | | * @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> |
| New file |
| | |
| | | <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> |
| New file |
| | |
| | | <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> |
| New file |
| | |
| | | <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> |
| New file |
| | |
| | | <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> |
| New file |
| | |
| | | <!-- |
| | | * @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> |
| | |
| | | * @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. |
| | |
| | | backdrop-filter: blur(5px); |
| | | |
| | | ::v-deep(.wrapper) { |
| | | display: flex; |
| | | flex-direction: column; |
| | | position: absolute; |
| | | top: 17px; |
| | | bottom: 20px; |