|
|
@@ -0,0 +1,1611 @@
|
|
|
+<template>
|
|
|
+ <el-container class="h-screen flex-row overflow-hidden">
|
|
|
+ <!-- 仅保留中间主区域,移除左右侧栏和所有边框 -->
|
|
|
+ <el-main class="p-6 flex flex-col gap-4 h-full">
|
|
|
+ <div class="container">
|
|
|
+ <!-- 背景网格装饰 -->
|
|
|
+ <div class="grid-bg"></div>
|
|
|
+
|
|
|
+ <div class="main-content">
|
|
|
+ <!-- 等待界面 -->
|
|
|
+ <div class="waiting-panel">
|
|
|
+ <h2 class="waiting-title">{{ waitingTitle || '试验准备中' }}</h2>
|
|
|
+ <h3 class="experiment-name">红旗-9B防空导弹拦截试验</h3>
|
|
|
+
|
|
|
+ <div class="countdown-container">
|
|
|
+ <h4 class="countdown-title">距离试验开始还有</h4>
|
|
|
+ <div class="countdown-timer">
|
|
|
+ <div class="time-unit">
|
|
|
+ <div class="time-value">{{ formattedHours }}</div>
|
|
|
+ <div class="time-label">时</div>
|
|
|
+ </div>
|
|
|
+ <div class="time-separator">:</div>
|
|
|
+ <div class="time-unit">
|
|
|
+ <div class="time-value">{{ formattedMinutes }}</div>
|
|
|
+ <div class="time-label">分</div>
|
|
|
+ </div>
|
|
|
+ <div class="time-separator">:</div>
|
|
|
+ <div class="time-unit">
|
|
|
+ <div class="time-value">{{ formattedSeconds }}</div>
|
|
|
+ <div class="time-label">秒</div>
|
|
|
+ </div>
|
|
|
+ <div class="time-separator">:</div>
|
|
|
+ <div class="time-unit">
|
|
|
+ <div class="time-value">{{ formattedMilliseconds }}</div>
|
|
|
+ <div class="time-label">毫秒</div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class="time-info">
|
|
|
+ <div class="info-item">
|
|
|
+ <div class="info-label">当前时间</div>
|
|
|
+ <div class="info-value">{{ formattedCurrentTime }}</div>
|
|
|
+ </div>
|
|
|
+ <div class="info-item">
|
|
|
+ <div class="info-label">试验开始时间</div>
|
|
|
+ <div class="info-value">{{ formattedStartTime }}</div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class="control-buttons">
|
|
|
+ <el-button
|
|
|
+ class="control-btn btn军事"
|
|
|
+ type="primary"
|
|
|
+ icon="el-icon-play"
|
|
|
+ @click="startSituation"
|
|
|
+ >
|
|
|
+ 开始试验
|
|
|
+ </el-button>
|
|
|
+ <el-button
|
|
|
+ class="control-btn btn军事"
|
|
|
+ type="warning"
|
|
|
+ icon="el-icon-document"
|
|
|
+ @click="showTestPointsDrawer = true"
|
|
|
+ >
|
|
|
+ 试验要点
|
|
|
+ </el-button>
|
|
|
+ <el-button
|
|
|
+ class="control-btn btn军事"
|
|
|
+ type="success"
|
|
|
+ icon="el-icon-cog"
|
|
|
+ @click="linkTo"
|
|
|
+ >
|
|
|
+ 设备检测
|
|
|
+ </el-button>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- 试验要点抽屉 - 添加modal=false去除遮罩层 -->
|
|
|
+ <DarkDrawer
|
|
|
+ title="试验要点说明"
|
|
|
+ :visible.sync="showTestPointsDrawer"
|
|
|
+ :size="'40%'"
|
|
|
+ direction="rtl"
|
|
|
+ class="custom-drawer"
|
|
|
+ >
|
|
|
+ <div class="test-points-content">
|
|
|
+ <div class="test-point-section">
|
|
|
+ <h3 class="section-title">试验目的</h3>
|
|
|
+ <p class="section-content">
|
|
|
+ 验证红旗-9B防空导弹系统在复杂电磁环境下对多类型目标的拦截能力,
|
|
|
+ 测试系统在强干扰条件下的作战效能,评估武器系统的整体性能指标。
|
|
|
+ </p>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class="test-point-section">
|
|
|
+ <h3 class="section-title">试验阶段</h3>
|
|
|
+ <ul class="section-list">
|
|
|
+ <li>1. 系统初始化与自检(0-15分钟)</li>
|
|
|
+ <li>2. 目标部署与起飞(15-30分钟)</li>
|
|
|
+ <li>3. 目标捕获与跟踪(30-45分钟)</li>
|
|
|
+ <li>4. 导弹发射与拦截(45-60分钟)</li>
|
|
|
+ <li>5. 数据采集与评估(60-90分钟)</li>
|
|
|
+ </ul>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class="test-point-section">
|
|
|
+ <h3 class="section-title">关键指标</h3>
|
|
|
+ <div class="metrics-grid">
|
|
|
+ <div class="metric-card">
|
|
|
+ <div class="metric-name">拦截成功率</div>
|
|
|
+ <div class="metric-target">目标: ≥95%</div>
|
|
|
+ </div>
|
|
|
+ <div class="metric-card">
|
|
|
+ <div class="metric-name">反应时间</div>
|
|
|
+ <div class="metric-target">目标: ≤8秒</div>
|
|
|
+ </div>
|
|
|
+ <div class="metric-card">
|
|
|
+ <div class="metric-name">最大拦截距离</div>
|
|
|
+ <div class="metric-target">目标: ≥200km</div>
|
|
|
+ </div>
|
|
|
+ <div class="metric-card">
|
|
|
+ <div class="metric-name">抗干扰能力</div>
|
|
|
+ <div class="metric-target">目标: 强干扰环境下正常工作</div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class="test-point-section">
|
|
|
+ <h3 class="section-title">注意事项</h3>
|
|
|
+ <ul class="section-list">
|
|
|
+ <li>所有设备必须在试验前完成自检并达到就绪状态</li>
|
|
|
+ <li>数据记录系统需全程运行,确保关键数据不丢失</li>
|
|
|
+ <li>各观测点需在指定时间前完成部署并报告准备情况</li>
|
|
|
+ <li>应急处置团队需处于待命状态,随时准备应对突发情况</li>
|
|
|
+ </ul>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </DarkDrawer>
|
|
|
+
|
|
|
+ <!-- 设备检测抽屉 - 添加modal=false去除遮罩层 -->
|
|
|
+ <DarkDrawer
|
|
|
+ title="设备检测状态"
|
|
|
+ :visible.sync="showEquipmentDrawer"
|
|
|
+ :size="drawerSize"
|
|
|
+ direction="rtl"
|
|
|
+ class="custom-drawer"
|
|
|
+ >
|
|
|
+ <div class="equipment-drawer-content">
|
|
|
+ <!-- 设备状态统计卡片 -->
|
|
|
+ <div class="small-stats-cards">
|
|
|
+ <!-- 靶标设备卡片 -->
|
|
|
+ <el-card shadow="never" class="small-card" :body-style="{padding: '5px 8px', margin: 0, background: 'transparent', border: 'none'}">
|
|
|
+ <div class="small-card-content">
|
|
|
+ <div class="small-card-title">靶标设备</div>
|
|
|
+ <div class="small-card-value">
|
|
|
+ <span class="normal-value">{{ stats.target.normal }}</span>
|
|
|
+ <span class="abnormal-value">{{ stats.target.abnormal }}</span>
|
|
|
+ </div>
|
|
|
+ <div class="small-card-footer">
|
|
|
+ <span class="normal-label">正常</span>
|
|
|
+ <span class="abnormal-label">异常</span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </el-card>
|
|
|
+
|
|
|
+ <!-- 测量设备卡片 -->
|
|
|
+ <el-card shadow="never" class="small-card" :body-style="{padding: '5px 8px', margin: 0, background: 'transparent', border: 'none'}">
|
|
|
+ <div class="small-card-content">
|
|
|
+ <div class="small-card-title">测量设备</div>
|
|
|
+ <div class="small-card-value">
|
|
|
+ <span class="normal-value">{{ stats.measurement.normal }}</span>
|
|
|
+ <span class="abnormal-value">{{ stats.measurement.abnormal }}</span>
|
|
|
+ </div>
|
|
|
+ <div class="small-card-footer">
|
|
|
+ <span class="normal-label">正常</span>
|
|
|
+ <span class="abnormal-label">异常</span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </el-card>
|
|
|
+
|
|
|
+ <!-- 干扰设备卡片 -->
|
|
|
+ <el-card shadow="never" class="small-card" :body-style="{padding: '5px 8px', margin: 0, background: 'transparent', border: 'none'}">
|
|
|
+ <div class="small-card-content">
|
|
|
+ <div class="small-card-title">干扰设备</div>
|
|
|
+ <div class="small-card-value">
|
|
|
+ <span class="normal-value">{{ stats.jamming.normal }}</span>
|
|
|
+ <span class="abnormal-value">{{ stats.jamming.abnormal }}</span>
|
|
|
+ </div>
|
|
|
+ <div class="small-card-footer">
|
|
|
+ <span class="normal-label">正常</span>
|
|
|
+ <span class="abnormal-label">异常</span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </el-card>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- 表格 -->
|
|
|
+ <div class="table-container">
|
|
|
+ <el-table
|
|
|
+ ref="filterTable"
|
|
|
+ :data="filteredTableData"
|
|
|
+ border
|
|
|
+ :height="tableHeight"
|
|
|
+ >
|
|
|
+ <!-- 表格列定义 -->
|
|
|
+ <el-table-column
|
|
|
+ prop="name"
|
|
|
+ label="设备名称"
|
|
|
+ align="center"
|
|
|
+ ></el-table-column>
|
|
|
+
|
|
|
+ <el-table-column
|
|
|
+ prop="type"
|
|
|
+ label="设备类型"
|
|
|
+ align="center"
|
|
|
+ :filters="[{text: '靶标设备', value: 'target'}, {text: '测量设备', value: 'measurement'}, {text: '干扰设备', value: 'jamming'}]"
|
|
|
+ :filter-method="filterHandler"
|
|
|
+ filter-placement="bottom-end"
|
|
|
+ >
|
|
|
+ <template slot-scope="scope">
|
|
|
+ <el-tag
|
|
|
+ :type="scope.row.type === 'target' ? 'success' :
|
|
|
+ scope.row.type === 'measurement' ? 'info' : 'warning'"
|
|
|
+ >
|
|
|
+ {{ scope.row.type === 'target' ? '靶标设备' :
|
|
|
+ scope.row.type === 'measurement' ? '测量设备' : '干扰设备' }}
|
|
|
+ </el-tag>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+
|
|
|
+ <el-table-column
|
|
|
+ prop="model"
|
|
|
+ label="型号"
|
|
|
+ align="center"
|
|
|
+ ></el-table-column>
|
|
|
+
|
|
|
+ <el-table-column
|
|
|
+ label="状态"
|
|
|
+ align="center"
|
|
|
+ >
|
|
|
+ <template slot-scope="scope">
|
|
|
+ <div
|
|
|
+ class="equipment-status"
|
|
|
+ :class="[
|
|
|
+ statusClassByProgress(scope.row.progress),
|
|
|
+ { 'blinking': checkingStatus === scope.row.id }
|
|
|
+ ]"
|
|
|
+ >
|
|
|
+ {{ scope.row.progress === 100 ? '正常' : '异常' }}
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+
|
|
|
+ <el-table-column
|
|
|
+ label="操作"
|
|
|
+ align="center"
|
|
|
+ >
|
|
|
+ <template slot-scope="scope">
|
|
|
+ <el-button
|
|
|
+ icon="el-icon-refresh"
|
|
|
+ type="info"
|
|
|
+ @click="checkStatus(scope.row.id)"
|
|
|
+ :loading="checkingStatus === scope.row.id"
|
|
|
+ class="btn军事"
|
|
|
+ >检测状态
|
|
|
+ </el-button>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ </el-table>
|
|
|
+
|
|
|
+ <!-- 无数据提示 -->
|
|
|
+ <div v-if="filteredTableData.length === 0 && !loading" class="no-data">
|
|
|
+ <el-empty description="没有找到匹配的设备数据"></el-empty>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- 分页 -->
|
|
|
+ <div class="pagination-container">
|
|
|
+ <el-pagination
|
|
|
+ @size-change="handleSizeChange"
|
|
|
+ @current-change="handleCurrentChange"
|
|
|
+ :current-page="pagination.currentPage"
|
|
|
+ :page-sizes="[10, 20, 50, 100]"
|
|
|
+ :page-size="pagination.pageSize"
|
|
|
+ layout="total, sizes, prev, pager, next, jumper"
|
|
|
+ :total="pagination.total"
|
|
|
+ v-if="pagination.total > 0"
|
|
|
+ background
|
|
|
+ class="custom-pagination"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </DarkDrawer>
|
|
|
+ </div>
|
|
|
+ </el-main>
|
|
|
+ </el-container>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script>
|
|
|
+export default {
|
|
|
+ data() {
|
|
|
+ // 设置试验开始时间 (3小时45分钟后)
|
|
|
+ const startTime = new Date();
|
|
|
+ startTime.setHours(startTime.getHours() + 3);
|
|
|
+ startTime.setMinutes(startTime.getMinutes() + 45);
|
|
|
+
|
|
|
+ return {
|
|
|
+ // 倒计时相关
|
|
|
+ startTime,
|
|
|
+ currentTime: new Date(),
|
|
|
+ hours: 0,
|
|
|
+ minutes: 0,
|
|
|
+ seconds: 0,
|
|
|
+ milliseconds: 0,
|
|
|
+ waitingTitle: null,
|
|
|
+
|
|
|
+ // 设备状态
|
|
|
+ safetyStatus: 'ready',
|
|
|
+ targetControlStatus: 'ready',
|
|
|
+ radarStatus: 'ready',
|
|
|
+ dataStatus: 'pending',
|
|
|
+ opticalStatus: 'ready',
|
|
|
+ electronicStatus: 'pending',
|
|
|
+ signalStatus: 'ready',
|
|
|
+
|
|
|
+ // 设备详细状态
|
|
|
+ radarDetailStatus: '待机',
|
|
|
+ dataDetailStatus: '初始化',
|
|
|
+ safetyDetailStatus: '监控中',
|
|
|
+ targetControlDetailStatus: '定位完成',
|
|
|
+ opticalDetailStatus: '校准完成',
|
|
|
+ electronicDetailStatus: '功率调节中',
|
|
|
+ signalDetailStatus: '待命',
|
|
|
+
|
|
|
+ // 进度条
|
|
|
+ radarProgress: 100,
|
|
|
+ missileProgress: 95,
|
|
|
+ dataProgress: 85,
|
|
|
+ safetyProgress: 100,
|
|
|
+ targetControlProgress: 100,
|
|
|
+ opticalProgress: 100,
|
|
|
+ electronicProgress: 80,
|
|
|
+ signalProgress: 100,
|
|
|
+
|
|
|
+ // 定时器
|
|
|
+ countdownInterval: null,
|
|
|
+ timeUpdateInterval: null,
|
|
|
+ statusUpdateInterval: null,
|
|
|
+ checkingStatus: null,
|
|
|
+
|
|
|
+ // 抽屉相关
|
|
|
+ showEquipmentDrawer: false,
|
|
|
+ showTestPointsDrawer: false,
|
|
|
+ drawerSize: '40%',
|
|
|
+
|
|
|
+ // 设备表格相关
|
|
|
+ stats: {
|
|
|
+ jamming: { normal: 0, abnormal: 0 },
|
|
|
+ measurement: { normal: 0, abnormal: 0 },
|
|
|
+ target: { normal: 0, abnormal: 0 }
|
|
|
+ },
|
|
|
+ allTableData: [
|
|
|
+ // 靶标设备
|
|
|
+ {
|
|
|
+ id: 'safety',
|
|
|
+ name: '仿海马斯火箭炮',
|
|
|
+ type: 'target',
|
|
|
+ model: 'RSS-900',
|
|
|
+ details: {
|
|
|
+ '传感器': '24/24',
|
|
|
+ '响应时间': '0.2 s',
|
|
|
+ '状态': '监控中'
|
|
|
+ },
|
|
|
+ progress: 100
|
|
|
+ },
|
|
|
+ {
|
|
|
+ id: 'targetControl',
|
|
|
+ name: '机动式防御雷达车',
|
|
|
+ type: 'target',
|
|
|
+ model: 'TCS-600',
|
|
|
+ details: {
|
|
|
+ '靶标数量': '8',
|
|
|
+ '控制精度': '±0.5m',
|
|
|
+ '状态': '定位完成'
|
|
|
+ },
|
|
|
+ progress: 100
|
|
|
+ },
|
|
|
+
|
|
|
+ // 测量设备
|
|
|
+ {
|
|
|
+ id: 'radar',
|
|
|
+ name: '脱靶量符合测量设备',
|
|
|
+ type: 'measurement',
|
|
|
+ model: 'TRS-5000',
|
|
|
+ details: {
|
|
|
+ '频率': '8.5 GHz',
|
|
|
+ '功率': '120 kW',
|
|
|
+ '状态': '待机'
|
|
|
+ },
|
|
|
+ progress: 100
|
|
|
+ },
|
|
|
+ {
|
|
|
+ id: 'data',
|
|
|
+ name: '可见光相机',
|
|
|
+ type: 'measurement',
|
|
|
+ model: 'DAS-300',
|
|
|
+ details: {
|
|
|
+ '采样率': '1 MHz',
|
|
|
+ '存储': '2.3 TB',
|
|
|
+ '状态': '初始化'
|
|
|
+ },
|
|
|
+ progress: 85
|
|
|
+ },
|
|
|
+ {
|
|
|
+ id: 'optical',
|
|
|
+ name: '中波红外热像仪',
|
|
|
+ type: 'measurement',
|
|
|
+ model: 'OMS-800',
|
|
|
+ details: {
|
|
|
+ '分辨率': '4K',
|
|
|
+ '帧率': '120 fps',
|
|
|
+ '状态': '校准完成'
|
|
|
+ },
|
|
|
+ progress: 100
|
|
|
+ },
|
|
|
+
|
|
|
+ // 干扰设备
|
|
|
+ {
|
|
|
+ id: 'electronic',
|
|
|
+ name: 'C频段辐射源',
|
|
|
+ type: 'jamming',
|
|
|
+ model: 'EJS-400',
|
|
|
+ details: {
|
|
|
+ '频段': '1-18 GHz',
|
|
|
+ '功率': '500 W',
|
|
|
+ '状态': '功率调节中'
|
|
|
+ },
|
|
|
+ progress: 80
|
|
|
+ },
|
|
|
+ {
|
|
|
+ id: 'signal',
|
|
|
+ name: '726-4装备',
|
|
|
+ type: 'jamming',
|
|
|
+ model: 'SI-200',
|
|
|
+ details: {
|
|
|
+ '模式': '主动/被动',
|
|
|
+ '覆盖范围': '5 km',
|
|
|
+ '状态': '待命'
|
|
|
+ },
|
|
|
+ progress: 100
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ filteredTableData: [],
|
|
|
+ pagination: {
|
|
|
+ currentPage: 1,
|
|
|
+ pageSize: 10,
|
|
|
+ total: 0
|
|
|
+ },
|
|
|
+ queryForm: {
|
|
|
+ name: '',
|
|
|
+ taskCode: '',
|
|
|
+ deviceType: 'all'
|
|
|
+ },
|
|
|
+ loading: false,
|
|
|
+ tableHeight: 400
|
|
|
+ };
|
|
|
+ },
|
|
|
+ computed: {
|
|
|
+ formattedHours() {
|
|
|
+ return this.hours.toString().padStart(2, '0');
|
|
|
+ },
|
|
|
+ formattedMinutes() {
|
|
|
+ return this.minutes.toString().padStart(2, '0');
|
|
|
+ },
|
|
|
+ formattedSeconds() {
|
|
|
+ return this.seconds.toString().padStart(2, '0');
|
|
|
+ },
|
|
|
+ formattedMilliseconds() {
|
|
|
+ return this.milliseconds.toString().padStart(3, '0');
|
|
|
+ },
|
|
|
+ formattedStartTime() {
|
|
|
+ return this.startTime.toLocaleDateString('zh-CN') + ' ' +
|
|
|
+ this.startTime.toLocaleTimeString('zh-CN', { hour12: false });
|
|
|
+ },
|
|
|
+ formattedCurrentTime() {
|
|
|
+ return this.currentTime.toLocaleDateString('zh-CN') + ' ' +
|
|
|
+ this.currentTime.toLocaleTimeString('zh-CN', { hour12: false });
|
|
|
+ },
|
|
|
+
|
|
|
+ // 设备状态类
|
|
|
+ safetyStatusClass() {
|
|
|
+ return {
|
|
|
+ 'status-ready': this.safetyStatus === 'ready',
|
|
|
+ 'status-pending': this.safetyStatus === 'pending',
|
|
|
+ 'status-offline': this.safetyStatus === 'offline',
|
|
|
+ 'status-checking': this.checkingStatus === 'safety'
|
|
|
+ };
|
|
|
+ },
|
|
|
+ targetControlStatusClass() {
|
|
|
+ return {
|
|
|
+ 'status-ready': this.targetControlStatus === 'ready',
|
|
|
+ 'status-pending': this.targetControlStatus === 'pending',
|
|
|
+ 'status-offline': this.targetControlStatus === 'offline',
|
|
|
+ 'status-checking': this.checkingStatus === 'targetControl'
|
|
|
+ };
|
|
|
+ },
|
|
|
+ radarStatusClass() {
|
|
|
+ return {
|
|
|
+ 'status-ready': this.radarStatus === 'ready',
|
|
|
+ 'status-pending': this.radarStatus === 'pending',
|
|
|
+ 'status-offline': this.radarStatus === 'offline',
|
|
|
+ 'status-checking': this.checkingStatus === 'radar'
|
|
|
+ };
|
|
|
+ },
|
|
|
+ dataStatusClass() {
|
|
|
+ return {
|
|
|
+ 'status-ready': this.dataStatus === 'ready',
|
|
|
+ 'status-pending': this.dataStatus === 'pending',
|
|
|
+ 'status-offline': this.dataStatus === 'offline',
|
|
|
+ 'status-checking': this.checkingStatus === 'data'
|
|
|
+ };
|
|
|
+ },
|
|
|
+ opticalStatusClass() {
|
|
|
+ return {
|
|
|
+ 'status-ready': this.opticalStatus === 'ready',
|
|
|
+ 'status-pending': this.opticalStatus === 'pending',
|
|
|
+ 'status-offline': this.opticalStatus === 'offline',
|
|
|
+ 'status-checking': this.checkingStatus === 'optical'
|
|
|
+ };
|
|
|
+ },
|
|
|
+ electronicStatusClass() {
|
|
|
+ return {
|
|
|
+ 'status-ready': this.electronicStatus === 'ready',
|
|
|
+ 'status-pending': this.electronicStatus === 'pending',
|
|
|
+ 'status-offline': this.electronicStatus === 'offline',
|
|
|
+ 'status-checking': this.checkingStatus === 'electronic'
|
|
|
+ };
|
|
|
+ },
|
|
|
+ signalStatusClass() {
|
|
|
+ return {
|
|
|
+ 'status-ready': this.signalStatus === 'ready',
|
|
|
+ 'status-pending': this.signalStatus === 'pending',
|
|
|
+ 'status-offline': this.signalStatus === 'offline',
|
|
|
+ 'status-checking': this.checkingStatus === 'signal'
|
|
|
+ };
|
|
|
+ }
|
|
|
+ },
|
|
|
+ mounted() {
|
|
|
+ this.startCountdown();
|
|
|
+ this.updateCurrentTime();
|
|
|
+ this.simulateStatusChanges();
|
|
|
+
|
|
|
+ // 初始化设备表格数据
|
|
|
+ this.fetchData();
|
|
|
+ this.calculateStats();
|
|
|
+ this.calculateTableHeight();
|
|
|
+ window.addEventListener('resize', this.handleResize);
|
|
|
+ },
|
|
|
+ beforeDestroy() {
|
|
|
+ clearInterval(this.countdownInterval);
|
|
|
+ clearInterval(this.timeUpdateInterval);
|
|
|
+ clearInterval(this.statusUpdateInterval);
|
|
|
+ window.removeEventListener('resize', this.handleResize);
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ startSituation() {
|
|
|
+ this.$router.push('/showSituation/before');
|
|
|
+ },
|
|
|
+ startCountdown() {
|
|
|
+ this.updateCountdown();
|
|
|
+ this.countdownInterval = setInterval(this.updateCountdown, 10);
|
|
|
+ },
|
|
|
+ updateCountdown() {
|
|
|
+ this.currentTime = new Date();
|
|
|
+ const diff = this.startTime - this.currentTime;
|
|
|
+
|
|
|
+ if (diff <= 0) {
|
|
|
+ this.hours = 0;
|
|
|
+ this.minutes = 0;
|
|
|
+ this.seconds = 0;
|
|
|
+ this.milliseconds = 0;
|
|
|
+ this.$set(this, 'waitingTitle', '试验已开始');
|
|
|
+ clearInterval(this.countdownInterval);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 计算时分秒毫秒
|
|
|
+ this.hours = Math.floor(diff / (1000 * 60 * 60));
|
|
|
+ this.minutes = Math.floor((diff % (1000 * 60 * 60)) / (1000 * 60));
|
|
|
+ this.seconds = Math.floor((diff % (1000 * 60)) / 1000);
|
|
|
+ this.milliseconds = Math.floor(diff % 1000);
|
|
|
+ },
|
|
|
+ updateCurrentTime() {
|
|
|
+ this.timeUpdateInterval = setInterval(() => {
|
|
|
+ this.currentTime = new Date();
|
|
|
+ }, 1000);
|
|
|
+ },
|
|
|
+ simulateStatusChanges() {
|
|
|
+ this.statusUpdateInterval = setInterval(() => {
|
|
|
+ // 只更新不在检测状态的设备
|
|
|
+ if (this.checkingStatus === null) {
|
|
|
+ // 靶标设备状态变化
|
|
|
+ if (this.safetyStatus === 'ready') {
|
|
|
+ this.safetyStatus = 'pending';
|
|
|
+ this.safetyProgress = 90;
|
|
|
+ } else if (this.safetyStatus === 'pending') {
|
|
|
+ this.safetyStatus = 'ready';
|
|
|
+ this.safetyProgress = 100;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 测量设备状态变化
|
|
|
+ if (this.radarStatus === 'ready') {
|
|
|
+ this.radarStatus = 'pending';
|
|
|
+ this.radarProgress = 90;
|
|
|
+ } else if (this.radarStatus === 'pending') {
|
|
|
+ this.radarStatus = 'ready';
|
|
|
+ this.radarProgress = 100;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (this.dataStatus === 'pending') {
|
|
|
+ this.dataStatus = 'ready';
|
|
|
+ this.dataProgress = 100;
|
|
|
+ } else if (this.dataStatus === 'ready') {
|
|
|
+ this.dataStatus = 'pending';
|
|
|
+ this.dataProgress = 85;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 干扰设备状态变化
|
|
|
+ if (this.electronicStatus === 'pending') {
|
|
|
+ this.electronicStatus = 'ready';
|
|
|
+ this.electronicProgress = 100;
|
|
|
+ } else if (this.electronicStatus === 'ready') {
|
|
|
+ this.electronicStatus = 'pending';
|
|
|
+ this.electronicProgress = 80;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }, 5000);
|
|
|
+ },
|
|
|
+ // 检测设备状态
|
|
|
+ checkStatus(device) {
|
|
|
+ if (this.checkingStatus) return;
|
|
|
+
|
|
|
+ // 记录当前状态用于恢复
|
|
|
+ const originalStatus = this[`${device}Status`];
|
|
|
+ const originalDetailStatus = this[`${device}DetailStatus`];
|
|
|
+ const originalProgress = this[`${device}Progress`];
|
|
|
+
|
|
|
+ // 设置为检测中状态
|
|
|
+ this.checkingStatus = device;
|
|
|
+ this[`${device}Status`] = 'pending';
|
|
|
+ this[`${device}DetailStatus`] = '检测中...';
|
|
|
+ this[`${device}Progress`] = 50;
|
|
|
+
|
|
|
+ // 同步更新表格中的进度
|
|
|
+ this.allTableData = this.allTableData.map(item => {
|
|
|
+ if (item.id === device) {
|
|
|
+ return { ...item, progress: 50 };
|
|
|
+ }
|
|
|
+ return item;
|
|
|
+ });
|
|
|
+ this.handleQuery();
|
|
|
+ this.calculateStats();
|
|
|
+
|
|
|
+ // 模拟检测过程(2秒)
|
|
|
+ setTimeout(() => {
|
|
|
+ // 随机生成检测结果(90%概率正常,10%概率异常)
|
|
|
+ const isNormal = Math.random() > 0.1;
|
|
|
+ const newProgress = isNormal ? 100 : Math.floor(30 + Math.random() * 40);
|
|
|
+
|
|
|
+ if (isNormal) {
|
|
|
+ this[`${device}Status`] = 'ready';
|
|
|
+ this[`${device}DetailStatus`] = '检测正常';
|
|
|
+ this[`${device}Progress`] = 100;
|
|
|
+
|
|
|
+ // 2秒后恢复正常状态显示
|
|
|
+ setTimeout(() => {
|
|
|
+ this[`${device}DetailStatus`] = originalDetailStatus;
|
|
|
+ this.checkingStatus = null;
|
|
|
+ }, 2000);
|
|
|
+ } else {
|
|
|
+ this[`${device}Status`] = 'offline';
|
|
|
+ this[`${device}DetailStatus`] = '检测异常';
|
|
|
+ this[`${device}Progress`] = newProgress;
|
|
|
+
|
|
|
+ // 5秒后尝试恢复
|
|
|
+ setTimeout(() => {
|
|
|
+ this[`${device}Status`] = originalStatus;
|
|
|
+ this[`${device}DetailStatus`] = originalDetailStatus;
|
|
|
+ this[`${device}Progress`] = originalProgress;
|
|
|
+ this.checkingStatus = null;
|
|
|
+ }, 5000);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 更新表格中的进度
|
|
|
+ this.allTableData = this.allTableData.map(item => {
|
|
|
+ if (item.id === device) {
|
|
|
+ return { ...item, progress: newProgress };
|
|
|
+ }
|
|
|
+ return item;
|
|
|
+ });
|
|
|
+ this.handleQuery();
|
|
|
+ this.calculateStats();
|
|
|
+ this.$message.success(`设备 ${this.allTableData.find(item => item.id === device)?.name} 状态检测完成`);
|
|
|
+ }, 2000);
|
|
|
+ },
|
|
|
+
|
|
|
+ // 设备表格相关方法
|
|
|
+ calculateStats() {
|
|
|
+ // 重置统计数据
|
|
|
+ this.stats = {
|
|
|
+ jamming: { normal: 0, abnormal: 0 },
|
|
|
+ measurement: { normal: 0, abnormal: 0 },
|
|
|
+ target: { normal: 0, abnormal: 0 }
|
|
|
+ };
|
|
|
+
|
|
|
+ // 遍历所有设备数据
|
|
|
+ this.allTableData.forEach(item => {
|
|
|
+ const type = item.type === 'jamming' ? 'jamming' :
|
|
|
+ item.type === 'measurement' ? 'measurement' : 'target';
|
|
|
+ const status = item.progress === 100 ? 'normal' : 'abnormal';
|
|
|
+
|
|
|
+ this.stats[type][status]++;
|
|
|
+ });
|
|
|
+ },
|
|
|
+
|
|
|
+ handleQuery() {
|
|
|
+ this.loading = true;
|
|
|
+ setTimeout(() => {
|
|
|
+ let result = [...this.allTableData];
|
|
|
+
|
|
|
+ if (this.queryForm.name) {
|
|
|
+ const name = this.queryForm.name.toLowerCase();
|
|
|
+ result = result.filter(item =>
|
|
|
+ item.name.toLowerCase().includes(name)
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+ if (this.queryForm.deviceType !== 'all') {
|
|
|
+ const typeMap = {
|
|
|
+ 'meas': 'measurement',
|
|
|
+ 'targ': 'target',
|
|
|
+ 'int': 'jamming'
|
|
|
+ };
|
|
|
+ const type = typeMap[this.queryForm.deviceType];
|
|
|
+ if (type) {
|
|
|
+ result = result.filter(item => item.type === type);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ this.pagination.total = result.length;
|
|
|
+ this.pagination.currentPage = 1;
|
|
|
+ this.applyPagination(result);
|
|
|
+ this.loading = false;
|
|
|
+ }, 300);
|
|
|
+ },
|
|
|
+
|
|
|
+ calculateTableHeight() {
|
|
|
+ // 计算表格高度,减去其他元素占用的空间
|
|
|
+ const drawerHeight = window.innerHeight * 0.8;
|
|
|
+ this.tableHeight = drawerHeight - 300;
|
|
|
+ if (this.tableHeight < 300) this.tableHeight = 300;
|
|
|
+ },
|
|
|
+
|
|
|
+ handleResize() {
|
|
|
+ this.calculateTableHeight();
|
|
|
+ },
|
|
|
+
|
|
|
+ filterHandler(value, row, column) {
|
|
|
+ const property = column['property'];
|
|
|
+ return row[property] === value;
|
|
|
+ },
|
|
|
+ linkTo(){
|
|
|
+ this.$router.push({name:'deviceCheck'})
|
|
|
+ },
|
|
|
+
|
|
|
+ resetQuery() {
|
|
|
+ this.queryForm = {
|
|
|
+ name: '',
|
|
|
+ taskCode: '',
|
|
|
+ deviceType: 'all'
|
|
|
+ };
|
|
|
+ this.handleQuery();
|
|
|
+ },
|
|
|
+
|
|
|
+ handleSizeChange(val) {
|
|
|
+ this.pagination.pageSize = val;
|
|
|
+ this.fetchData();
|
|
|
+ },
|
|
|
+
|
|
|
+ handleCurrentChange(val) {
|
|
|
+ this.pagination.currentPage = val;
|
|
|
+ this.applyPagination();
|
|
|
+ },
|
|
|
+
|
|
|
+ fetchData() {
|
|
|
+ this.loading = true;
|
|
|
+ // 模拟API请求延迟
|
|
|
+ setTimeout(() => {
|
|
|
+ this.pagination.total = this.allTableData.length;
|
|
|
+ this.applyPagination();
|
|
|
+ this.loading = false;
|
|
|
+ }, 300);
|
|
|
+ },
|
|
|
+
|
|
|
+ applyPagination(filteredData) {
|
|
|
+ const data = filteredData || [...this.filteredTableData.length ? this.filteredTableData : this.allTableData];
|
|
|
+ const startIndex = (this.pagination.currentPage - 1) * this.pagination.pageSize;
|
|
|
+ const endIndex = startIndex + this.pagination.pageSize;
|
|
|
+ this.filteredTableData = data.slice(startIndex, endIndex);
|
|
|
+ },
|
|
|
+
|
|
|
+ statusClassByProgress(progress) {
|
|
|
+ return progress === 100 ? 'status-normal' : 'status-abnormal';
|
|
|
+ }
|
|
|
+ }
|
|
|
+};
|
|
|
+</script>
|
|
|
+
|
|
|
+<style scoped>
|
|
|
+* {
|
|
|
+ margin: 0;
|
|
|
+ padding: 0;
|
|
|
+ box-sizing: border-box;
|
|
|
+ font-family: "Microsoft YaHei", Arial, sans-serif;
|
|
|
+}
|
|
|
+
|
|
|
+body {
|
|
|
+ background-color: #1a1a1a;
|
|
|
+ color: white;
|
|
|
+ overflow: hidden;
|
|
|
+}
|
|
|
+
|
|
|
+.container {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ height: 97vh;
|
|
|
+ position: relative;
|
|
|
+}
|
|
|
+
|
|
|
+/* 军事网格背景 */
|
|
|
+.grid-bg {
|
|
|
+ position: absolute;
|
|
|
+ top: 0;
|
|
|
+ left: 0;
|
|
|
+ width: 100%;
|
|
|
+ height: 100%;
|
|
|
+ background-size: 40px 40px;
|
|
|
+ background-image:
|
|
|
+ linear-gradient(to right, rgba(14, 55, 107, 0.1) 1px, transparent 1px),
|
|
|
+ linear-gradient(to bottom, rgba(14, 55, 107, 0.1) 1px, transparent 1px);
|
|
|
+ pointer-events: none;
|
|
|
+ z-index: 0;
|
|
|
+}
|
|
|
+
|
|
|
+.main-content {
|
|
|
+ flex: 1;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ background-color: #050c1a;
|
|
|
+ overflow-y: auto;
|
|
|
+ padding: 20px;
|
|
|
+ position: relative;
|
|
|
+ z-index: 1;
|
|
|
+}
|
|
|
+
|
|
|
+/* 等待界面样式 */
|
|
|
+.waiting-panel {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ flex: 1;
|
|
|
+ padding: 40px;
|
|
|
+ text-align: center;
|
|
|
+ background: radial-gradient(circle at center, #1e3a8a 0%, #0f172a 100%);
|
|
|
+ border-radius: 10px;
|
|
|
+ border: 1px solid #0ea5e9;
|
|
|
+ box-shadow: 0 0 30px rgba(14, 165, 233, 0.4);
|
|
|
+ margin-bottom: 20px;
|
|
|
+}
|
|
|
+
|
|
|
+.waiting-icon {
|
|
|
+ font-size: 5rem;
|
|
|
+ color: #0ea5e9;
|
|
|
+ margin-bottom: 30px;
|
|
|
+ animation: pulse 2s infinite;
|
|
|
+}
|
|
|
+
|
|
|
+@keyframes pulse {
|
|
|
+ 0% {
|
|
|
+ transform: scale(1);
|
|
|
+ text-shadow: 0 0 10px rgba(14, 165, 233, 0.6);
|
|
|
+ }
|
|
|
+ 50% {
|
|
|
+ transform: scale(1.1);
|
|
|
+ text-shadow: 0 0 20px rgba(14, 165, 233, 0.8);
|
|
|
+ }
|
|
|
+ 100% {
|
|
|
+ transform: scale(1);
|
|
|
+ text-shadow: 0 0 10px rgba(14, 165, 233, 0.6);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.waiting-title {
|
|
|
+ font-size: 2.5rem;
|
|
|
+ margin-bottom: 15px;
|
|
|
+ color: #e0f2fe;
|
|
|
+ text-shadow: 0 0 10px rgba(255, 255, 255, 0.2);
|
|
|
+}
|
|
|
+
|
|
|
+.experiment-name {
|
|
|
+ font-size: 1.8rem;
|
|
|
+ color: #0ea5e9;
|
|
|
+ font-weight: bold;
|
|
|
+ margin-bottom: 30px;
|
|
|
+ text-shadow: 0 0 10px rgba(14, 165, 233, 0.6);
|
|
|
+}
|
|
|
+
|
|
|
+.countdown-container {
|
|
|
+ margin: 30px 0;
|
|
|
+ padding: 25px 40px;
|
|
|
+ background-color: rgba(15, 23, 42, 0.8);
|
|
|
+ border-radius: 15px;
|
|
|
+ border: 2px solid #0ea5e9;
|
|
|
+ box-shadow: 0 0 20px rgba(14, 165, 233, 0.5);
|
|
|
+}
|
|
|
+
|
|
|
+.countdown-title {
|
|
|
+ font-size: 1.5rem;
|
|
|
+ margin-bottom: 20px;
|
|
|
+ color: #93c5fd;
|
|
|
+}
|
|
|
+
|
|
|
+.countdown-timer {
|
|
|
+ display: flex;
|
|
|
+ justify-content: center;
|
|
|
+ gap: 10px;
|
|
|
+ margin-bottom: 15px;
|
|
|
+}
|
|
|
+
|
|
|
+.time-unit {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ align-items: center;
|
|
|
+}
|
|
|
+
|
|
|
+.time-value {
|
|
|
+ font-size: 4.5rem;
|
|
|
+ font-weight: bold;
|
|
|
+ min-width: 110px;
|
|
|
+ background: linear-gradient(145deg, #1e3a8a, #3b82f6);
|
|
|
+ padding: 10px 20px;
|
|
|
+ border-radius: 10px;
|
|
|
+ border: 1px solid #0ea5e9;
|
|
|
+ box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5);
|
|
|
+ color: #e0f2fe;
|
|
|
+ text-shadow: 0 0 10px rgba(14, 165, 233, 0.8);
|
|
|
+}
|
|
|
+
|
|
|
+.time-label {
|
|
|
+ font-size: 1.2rem;
|
|
|
+ color: #94a3b8;
|
|
|
+ margin-top: 10px;
|
|
|
+}
|
|
|
+
|
|
|
+.time-separator {
|
|
|
+ font-size: 4rem;
|
|
|
+ color: #0ea5e9;
|
|
|
+ margin: 0 5px;
|
|
|
+ align-self: center;
|
|
|
+}
|
|
|
+
|
|
|
+.time-info {
|
|
|
+ display: flex;
|
|
|
+ justify-content: center;
|
|
|
+ gap: 40px;
|
|
|
+ margin-top: 30px;
|
|
|
+ background-color: rgba(30, 58, 138, 0.3);
|
|
|
+ padding: 20px;
|
|
|
+ border-radius: 10px;
|
|
|
+ border: 1px solid rgba(14, 165, 233, 0.3);
|
|
|
+}
|
|
|
+
|
|
|
+.info-item {
|
|
|
+ text-align: center;
|
|
|
+}
|
|
|
+
|
|
|
+.info-label {
|
|
|
+ font-size: 1.1rem;
|
|
|
+ color: #94a3b8;
|
|
|
+ margin-bottom: 8px;
|
|
|
+}
|
|
|
+
|
|
|
+.info-value {
|
|
|
+ font-size: 1.5rem;
|
|
|
+ color: #e0f2fe;
|
|
|
+ font-weight: bold;
|
|
|
+}
|
|
|
+
|
|
|
+/* 控制按钮 */
|
|
|
+.control-buttons {
|
|
|
+ display: flex;
|
|
|
+ justify-content: center;
|
|
|
+ gap: 20px;
|
|
|
+ margin-top: 40px;
|
|
|
+}
|
|
|
+
|
|
|
+.control-btn {
|
|
|
+ padding: 12px 35px;
|
|
|
+ border-radius: 6px;
|
|
|
+ cursor: pointer;
|
|
|
+ font-size: 1.1rem;
|
|
|
+ font-weight: bold;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ gap: 10px;
|
|
|
+ transition: all 0.3s;
|
|
|
+}
|
|
|
+
|
|
|
+/* 军事风格按钮 */
|
|
|
+.btn军事 {
|
|
|
+ position: relative;
|
|
|
+ overflow: hidden;
|
|
|
+ transition: all 0.3s ease;
|
|
|
+ border: 1px solid rgba(14, 165, 233, 0.5) !important;
|
|
|
+ box-shadow: 0 0 5px rgba(14, 165, 233, 0.3);
|
|
|
+
|
|
|
+ &:after {
|
|
|
+ content: '';
|
|
|
+ position: absolute;
|
|
|
+ top: 0;
|
|
|
+ left: -100%;
|
|
|
+ width: 100%;
|
|
|
+ height: 100%;
|
|
|
+ background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.1), transparent);
|
|
|
+ transition: all 0.5s ease;
|
|
|
+ }
|
|
|
+
|
|
|
+ &:hover:after {
|
|
|
+ left: 100%;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+/* 按钮颜色方案 */
|
|
|
+::v-deep .el-button--primary {
|
|
|
+ background-color: #1e40af;
|
|
|
+ color: white;
|
|
|
+
|
|
|
+ &:hover {
|
|
|
+ background-color: #3b82f6;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+::v-deep .el-button--success {
|
|
|
+ background-color: #065f46;
|
|
|
+ color: white;
|
|
|
+
|
|
|
+ &:hover {
|
|
|
+ background-color: #16a34a;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+::v-deep .el-button--warning {
|
|
|
+ background-color: #92400e;
|
|
|
+ color: white;
|
|
|
+
|
|
|
+ &:hover {
|
|
|
+ background-color: #d97706;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+/* 背景装饰 */
|
|
|
+.background-elements {
|
|
|
+ position: absolute;
|
|
|
+ top: 0;
|
|
|
+ left: 0;
|
|
|
+ width: 100%;
|
|
|
+ height: 100%;
|
|
|
+ pointer-events: none;
|
|
|
+ z-index: -1;
|
|
|
+ overflow: hidden;
|
|
|
+}
|
|
|
+
|
|
|
+.element {
|
|
|
+ position: absolute;
|
|
|
+ border-radius: 50%;
|
|
|
+ opacity: 0.1;
|
|
|
+}
|
|
|
+
|
|
|
+.element-1 {
|
|
|
+ width: 300px;
|
|
|
+ height: 300px;
|
|
|
+ background: radial-gradient(circle, #0ea5e9, transparent 70%);
|
|
|
+ top: 10%;
|
|
|
+ left: 5%;
|
|
|
+ animation: float 15s infinite ease-in-out;
|
|
|
+}
|
|
|
+
|
|
|
+.element-2 {
|
|
|
+ width: 200px;
|
|
|
+ height: 200px;
|
|
|
+ background: radial-gradient(circle, #3b82f6, transparent 70%);
|
|
|
+ top: 70%;
|
|
|
+ left: 80%;
|
|
|
+ animation: float 12s infinite ease-in-out;
|
|
|
+ animation-delay: 2s;
|
|
|
+}
|
|
|
+
|
|
|
+.element-3 {
|
|
|
+ width: 150px;
|
|
|
+ height: 150px;
|
|
|
+ background: radial-gradient(circle, #1e40af, transparent 70%);
|
|
|
+ top: 30%;
|
|
|
+ left: 90%;
|
|
|
+ animation: float 10s infinite ease-in-out;
|
|
|
+ animation-delay: 1s;
|
|
|
+}
|
|
|
+
|
|
|
+@keyframes float {
|
|
|
+ 0%, 100% {
|
|
|
+ transform: translate(0, 0);
|
|
|
+ }
|
|
|
+ 25% {
|
|
|
+ transform: translate(-20px, 20px);
|
|
|
+ }
|
|
|
+ 50% {
|
|
|
+ transform: translate(20px, -20px);
|
|
|
+ }
|
|
|
+ 75% {
|
|
|
+ transform: translate(-10px, -10px);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+/* 通用抽屉样式 */
|
|
|
+.custom-drawer {
|
|
|
+ background: linear-gradient(145deg, #0f172a, #1e293b) !important;
|
|
|
+ border-left: 1px solid #0ea5e9 !important;
|
|
|
+ box-shadow: -5px 0 15px rgba(0, 0, 0, 0.7) !important;
|
|
|
+}
|
|
|
+
|
|
|
+.custom-drawer .el-drawer__header {
|
|
|
+ color: #e0f2fe;
|
|
|
+ border-bottom: 1px solid rgba(14, 165, 233, 0.3);
|
|
|
+ padding: 20px;
|
|
|
+ margin: 0;
|
|
|
+ background: rgba(30, 58, 138, 0.6);
|
|
|
+ box-shadow: 0 2px 10px rgba(0, 0, 0, 0.3);
|
|
|
+}
|
|
|
+
|
|
|
+.custom-drawer .el-drawer__header span {
|
|
|
+ font-size: 1.4rem;
|
|
|
+ font-weight: bold;
|
|
|
+ text-shadow: 0 0 5px rgba(14, 165, 233, 0.5);
|
|
|
+}
|
|
|
+
|
|
|
+.custom-drawer .el-drawer__close-btn {
|
|
|
+ color: #94a3b8 !important;
|
|
|
+ font-size: 1.5rem;
|
|
|
+ transition: all 0.3s;
|
|
|
+}
|
|
|
+
|
|
|
+.custom-drawer .el-drawer__close-btn:hover {
|
|
|
+ color: #0ea5e9 !important;
|
|
|
+ transform: scale(1.2);
|
|
|
+}
|
|
|
+
|
|
|
+/* 试验要点抽屉内容 */
|
|
|
+.test-points-content {
|
|
|
+ padding: 20px;
|
|
|
+ height: 100%;
|
|
|
+ overflow-y: auto;
|
|
|
+ background: linear-gradient(to bottom, #0f172a, #1e293b);
|
|
|
+ color: #e0f2fe;
|
|
|
+}
|
|
|
+
|
|
|
+.test-point-section {
|
|
|
+ margin-bottom: 30px;
|
|
|
+ padding-bottom: 20px;
|
|
|
+ border-bottom: 1px solid rgba(14, 165, 233, 0.2);
|
|
|
+}
|
|
|
+
|
|
|
+.test-point-section:last-child {
|
|
|
+ border-bottom: none;
|
|
|
+ margin-bottom: 0;
|
|
|
+ padding-bottom: 0;
|
|
|
+}
|
|
|
+
|
|
|
+.section-title {
|
|
|
+ font-size: 1.3rem;
|
|
|
+ color: #0ea5e9;
|
|
|
+ margin-bottom: 15px;
|
|
|
+ padding-left: 10px;
|
|
|
+ border-left: 3px solid #0ea5e9;
|
|
|
+}
|
|
|
+
|
|
|
+.section-content {
|
|
|
+ font-size: 1rem;
|
|
|
+ line-height: 1.6;
|
|
|
+ color: #e0f2fe;
|
|
|
+ text-align: justify;
|
|
|
+}
|
|
|
+
|
|
|
+.section-list {
|
|
|
+ padding-left: 20px;
|
|
|
+ line-height: 1.8;
|
|
|
+}
|
|
|
+
|
|
|
+.section-list li {
|
|
|
+ margin-bottom: 10px;
|
|
|
+ position: relative;
|
|
|
+ padding-left: 10px;
|
|
|
+}
|
|
|
+
|
|
|
+.section-list li:before {
|
|
|
+ content: "";
|
|
|
+ position: absolute;
|
|
|
+ left: -20px;
|
|
|
+ top: 8px;
|
|
|
+ width: 8px;
|
|
|
+ height: 8px;
|
|
|
+ border-radius: 50%;
|
|
|
+ background-color: #0ea5e9;
|
|
|
+}
|
|
|
+
|
|
|
+.metrics-grid {
|
|
|
+ display: grid;
|
|
|
+ grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
|
|
|
+ gap: 15px;
|
|
|
+ margin-top: 15px;
|
|
|
+}
|
|
|
+
|
|
|
+.metric-card {
|
|
|
+ background-color: rgba(15, 23, 42, 0.7);
|
|
|
+ border-radius: 8px;
|
|
|
+ border: 1px solid rgba(14, 165, 233, 0.3);
|
|
|
+ padding: 15px;
|
|
|
+ text-align: center;
|
|
|
+ transition: all 0.3s;
|
|
|
+}
|
|
|
+
|
|
|
+.metric-card:hover {
|
|
|
+ transform: translateY(-5px);
|
|
|
+ box-shadow: 0 5px 15px rgba(14, 165, 233, 0.2);
|
|
|
+}
|
|
|
+
|
|
|
+.metric-name {
|
|
|
+ font-size: 1rem;
|
|
|
+ color: #93c5fd;
|
|
|
+ margin-bottom: 10px;
|
|
|
+}
|
|
|
+
|
|
|
+.metric-target {
|
|
|
+ font-size: 1.1rem;
|
|
|
+ font-weight: bold;
|
|
|
+ color: #4ade80;
|
|
|
+}
|
|
|
+
|
|
|
+/* 设备检测抽屉样式 */
|
|
|
+.equipment-drawer-content {
|
|
|
+ padding: 20px;
|
|
|
+ height: 100%;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ background: linear-gradient(to bottom, #0f172a, #1e293b);
|
|
|
+ color: #e0f2fe;
|
|
|
+}
|
|
|
+
|
|
|
+/* 设备概览 */
|
|
|
+.equipment-overview {
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ margin-bottom: 20px;
|
|
|
+ padding: 15px;
|
|
|
+ background-color: rgba(15, 23, 42, 0.7);
|
|
|
+ border-radius: 8px;
|
|
|
+ border: 1px solid rgba(14, 165, 233, 0.3);
|
|
|
+ flex-wrap: wrap;
|
|
|
+ gap: 15px;
|
|
|
+}
|
|
|
+
|
|
|
+.overview-item {
|
|
|
+ flex: 1;
|
|
|
+ min-width: 120px;
|
|
|
+ text-align: center;
|
|
|
+}
|
|
|
+
|
|
|
+.overview-label {
|
|
|
+ font-size: 0.9rem;
|
|
|
+ color: #94a3b8;
|
|
|
+ margin-bottom: 5px;
|
|
|
+}
|
|
|
+
|
|
|
+.overview-value {
|
|
|
+ font-size: 1.5rem;
|
|
|
+ font-weight: bold;
|
|
|
+ color: #0ea5e9;
|
|
|
+}
|
|
|
+
|
|
|
+.overview-value.normal {
|
|
|
+ color: #4ade80;
|
|
|
+}
|
|
|
+
|
|
|
+.overview-value.abnormal {
|
|
|
+ color: #f87171;
|
|
|
+}
|
|
|
+
|
|
|
+.overview-value.rate {
|
|
|
+ color: #fbbf24;
|
|
|
+}
|
|
|
+
|
|
|
+/* 小型指标卡优化 */
|
|
|
+.small-stats-cards {
|
|
|
+ display: grid;
|
|
|
+ grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
|
|
|
+ gap: 15px;
|
|
|
+ margin-bottom: 25px;
|
|
|
+}
|
|
|
+
|
|
|
+.small-card {
|
|
|
+ background: rgba(15, 23, 42, 0.7) !important;
|
|
|
+ border-radius: 8px;
|
|
|
+ border: 1px solid rgba(14, 165, 233, 0.3) !important;
|
|
|
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
|
|
|
+ transition: all 0.3s ease;
|
|
|
+ overflow: hidden;
|
|
|
+}
|
|
|
+
|
|
|
+.small-card:hover {
|
|
|
+ transform: translateY(-5px);
|
|
|
+ box-shadow: 0 6px 15px rgba(14, 165, 233, 0.2);
|
|
|
+ border-color: rgba(14, 165, 233, 0.5) !important;
|
|
|
+}
|
|
|
+
|
|
|
+.small-card-content {
|
|
|
+ padding: 12px 15px !important;
|
|
|
+}
|
|
|
+
|
|
|
+.small-card-title {
|
|
|
+ font-size: 0.95rem;
|
|
|
+ color: #94a3b8;
|
|
|
+ margin-bottom: 8px;
|
|
|
+ text-align: center;
|
|
|
+ font-weight: 500;
|
|
|
+ letter-spacing: 0.5px;
|
|
|
+}
|
|
|
+
|
|
|
+.small-card-value {
|
|
|
+ display: flex;
|
|
|
+ justify-content: center;
|
|
|
+ gap: 25px;
|
|
|
+ margin-bottom: 5px;
|
|
|
+}
|
|
|
+
|
|
|
+.normal-value {
|
|
|
+ font-size: 1.8rem;
|
|
|
+ font-weight: bold;
|
|
|
+ color: #4ade80;
|
|
|
+ text-shadow: 0 0 8px rgba(74, 222, 128, 0.3);
|
|
|
+}
|
|
|
+
|
|
|
+.abnormal-value {
|
|
|
+ font-size: 1.8rem;
|
|
|
+ font-weight: bold;
|
|
|
+ color: #f87171;
|
|
|
+ text-shadow: 0 0 8px rgba(248, 113, 113, 0.3);
|
|
|
+}
|
|
|
+
|
|
|
+.small-card-footer {
|
|
|
+ display: flex;
|
|
|
+ justify-content: center;
|
|
|
+ gap: 25px;
|
|
|
+ font-size: 0.85rem;
|
|
|
+ margin-top: 5px;
|
|
|
+}
|
|
|
+
|
|
|
+.normal-label {
|
|
|
+ color: #4ade80;
|
|
|
+ position: relative;
|
|
|
+}
|
|
|
+
|
|
|
+.normal-label::before {
|
|
|
+ content: "";
|
|
|
+ position: absolute;
|
|
|
+ left: -12px;
|
|
|
+ top: 50%;
|
|
|
+ transform: translateY(-50%);
|
|
|
+ width: 8px;
|
|
|
+ height: 8px;
|
|
|
+ background: #4ade80;
|
|
|
+ border-radius: 50%;
|
|
|
+ box-shadow: 0 0 5px #4ade80;
|
|
|
+}
|
|
|
+
|
|
|
+.abnormal-label {
|
|
|
+ color: #f87171;
|
|
|
+ position: relative;
|
|
|
+}
|
|
|
+
|
|
|
+.abnormal-label::before {
|
|
|
+ content: "";
|
|
|
+ position: absolute;
|
|
|
+ left: -12px;
|
|
|
+ top: 50%;
|
|
|
+ transform: translateY(-50%);
|
|
|
+ width: 8px;
|
|
|
+ height: 8px;
|
|
|
+ background: #f87171;
|
|
|
+ border-radius: 50%;
|
|
|
+ box-shadow: 0 0 5px #f87171;
|
|
|
+}
|
|
|
+
|
|
|
+/* 表格样式优化 */
|
|
|
+.equipment-table {
|
|
|
+ border: 1px solid rgba(14, 165, 233, 0.3) !important;
|
|
|
+ border-radius: 8px;
|
|
|
+ overflow: hidden;
|
|
|
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
|
|
|
+ background-color: #0b1e3b;
|
|
|
+}
|
|
|
+
|
|
|
+.equipment-table::before {
|
|
|
+ content: "";
|
|
|
+ position: absolute;
|
|
|
+ top: 0;
|
|
|
+ left: 0;
|
|
|
+ right: 0;
|
|
|
+ height: 2px;
|
|
|
+ background: linear-gradient(90deg, transparent, #0ea5e9, transparent);
|
|
|
+}
|
|
|
+
|
|
|
+/* 表格行样式 */
|
|
|
+::v-deep .el-table__body td {
|
|
|
+ background: rgba(15, 23, 42, 0.5) !important;
|
|
|
+ border-bottom: 1px solid rgba(14, 165, 233, 0.1) !important;
|
|
|
+ transition: background 0.3s;
|
|
|
+}
|
|
|
+
|
|
|
+::v-deep .el-table__body tr:hover td {
|
|
|
+ background: rgba(30, 58, 138, 0.2) !important;
|
|
|
+}
|
|
|
+
|
|
|
+/* 表格筛选器样式 */
|
|
|
+::v-deep .el-table-filter {
|
|
|
+ background-color: rgba(15, 23, 42, 0.9) !important;
|
|
|
+ border: 1px solid rgba(14, 165, 233, 0.3) !important;
|
|
|
+}
|
|
|
+
|
|
|
+::v-deep .el-checkbox__label {
|
|
|
+ color: #e0f2fe !important;
|
|
|
+}
|
|
|
+
|
|
|
+/* 状态标签优化 */
|
|
|
+.status-normal {
|
|
|
+ background: rgba(74, 222, 128, 0.15) !important;
|
|
|
+ border: 1px solid rgba(74, 222, 128, 0.4);
|
|
|
+ color: #4ade80;
|
|
|
+ font-weight: bold;
|
|
|
+ padding: 3px 8px;
|
|
|
+ border-radius: 3px;
|
|
|
+}
|
|
|
+
|
|
|
+.status-abnormal {
|
|
|
+ background: rgba(248, 113, 113, 0.15) !important;
|
|
|
+ border: 1px solid rgba(248, 113, 113, 0.4);
|
|
|
+ color: #f87171;
|
|
|
+ font-weight: bold;
|
|
|
+ padding: 3px 8px;
|
|
|
+ border-radius: 3px;
|
|
|
+}
|
|
|
+
|
|
|
+.blinking {
|
|
|
+ animation: blinking 1s infinite;
|
|
|
+}
|
|
|
+
|
|
|
+@keyframes blinking {
|
|
|
+ 0% { opacity: 1; }
|
|
|
+ 50% { opacity: 0.5; }
|
|
|
+ 100% { opacity: 1; }
|
|
|
+}
|
|
|
+
|
|
|
+/* 分页样式优化 */
|
|
|
+.custom-pagination .el-pager li {
|
|
|
+ background: rgba(15, 23, 42, 0.7) !important;
|
|
|
+ border: 1px solid rgba(14, 165, 233, 0.3) !important;
|
|
|
+ color: #94a3b8 !important;
|
|
|
+}
|
|
|
+
|
|
|
+.custom-pagination .el-pager li.active {
|
|
|
+ background: rgba(14, 165, 233, 0.5) !important;
|
|
|
+ border-color: #0ea5e9 !important;
|
|
|
+ color: #fff !important;
|
|
|
+ font-weight: bold;
|
|
|
+ box-shadow: 0 0 8px rgba(14, 165, 233, 0.5);
|
|
|
+}
|
|
|
+
|
|
|
+.custom-pagination .btn-next,
|
|
|
+.custom-pagination .btn-prev {
|
|
|
+ background: rgba(15, 23, 42, 0.7) !important;
|
|
|
+ border: 1px solid rgba(14, 165, 233, 0.3) !important;
|
|
|
+ color: #94a3b8 !important;
|
|
|
+}
|
|
|
+
|
|
|
+/* 无数据提示优化 */
|
|
|
+.no-data {
|
|
|
+ background: rgba(15, 23, 42, 0.5);
|
|
|
+ border-radius: 8px;
|
|
|
+ border: 1px dashed rgba(14, 165, 233, 0.3);
|
|
|
+ padding: 30px 0;
|
|
|
+}
|
|
|
+
|
|
|
+/* 表单元素样式 */
|
|
|
+::v-deep .el-input__inner,
|
|
|
+::v-deep .el-select .el-input__inner {
|
|
|
+ background-color: rgba(15, 23, 42, 0.8);
|
|
|
+ border: 1px solid rgba(14, 165, 233, 0.3);
|
|
|
+ color: #e0f2fe;
|
|
|
+ border-radius: 3px;
|
|
|
+ height: 32px;
|
|
|
+ font-size: 14px;
|
|
|
+
|
|
|
+ &:focus {
|
|
|
+ border-color: #3b82f6;
|
|
|
+ box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.2);
|
|
|
+ }
|
|
|
+
|
|
|
+ &::placeholder {
|
|
|
+ color: #64748b;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+::v-deep .el-select-dropdown {
|
|
|
+ background-color: rgba(15, 23, 42, 0.95);
|
|
|
+ border: 1px solid rgba(14, 165, 233, 0.3);
|
|
|
+ border-radius: 3px;
|
|
|
+ box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3);
|
|
|
+
|
|
|
+ .el-select-dropdown__item {
|
|
|
+ color: #e0f2fe;
|
|
|
+ padding: 8px 16px;
|
|
|
+ font-size: 14px;
|
|
|
+
|
|
|
+ &:hover {
|
|
|
+ background-color: rgba(30, 58, 138, 0.5);
|
|
|
+ }
|
|
|
+
|
|
|
+ &.selected {
|
|
|
+ background-color: rgba(59, 130, 246, 0.5);
|
|
|
+ color: white;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+/* 详情项样式 */
|
|
|
+.detail-item {
|
|
|
+ display: inline-block;
|
|
|
+ margin-right: 10px;
|
|
|
+ margin-bottom: 5px;
|
|
|
+ padding: 2px 5px;
|
|
|
+ background-color: rgba(30, 58, 138, 0.2);
|
|
|
+ border-radius: 3px;
|
|
|
+ font-size: 12px;
|
|
|
+}
|
|
|
+
|
|
|
+.detail-key {
|
|
|
+ color: #93c5fd;
|
|
|
+ margin-right: 3px;
|
|
|
+}
|
|
|
+
|
|
|
+.detail-value {
|
|
|
+ color: #e0f2fe;
|
|
|
+}
|
|
|
+
|
|
|
+/* 响应式调整 */
|
|
|
+@media (max-width: 768px) {
|
|
|
+ .small-stats-cards {
|
|
|
+ grid-template-columns: 1fr;
|
|
|
+ }
|
|
|
+
|
|
|
+ .small-card {
|
|
|
+ height: auto;
|
|
|
+ padding: 10px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .drawerSize {
|
|
|
+ width: 95% !important;
|
|
|
+ }
|
|
|
+
|
|
|
+ .countdown-timer {
|
|
|
+ flex-wrap: wrap;
|
|
|
+ }
|
|
|
+
|
|
|
+ .time-value {
|
|
|
+ font-size: 2.5rem;
|
|
|
+ min-width: 70px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .equipment-overview {
|
|
|
+ flex-direction: column;
|
|
|
+ align-items: center;
|
|
|
+ }
|
|
|
+
|
|
|
+ .overview-item {
|
|
|
+ width: 100%;
|
|
|
+ }
|
|
|
+}
|
|
|
+::v-deep .el-drawer__wrapper * {
|
|
|
+ background: transparent;
|
|
|
+}
|
|
|
+</style>
|