|
|
@@ -0,0 +1,403 @@
|
|
|
+<template>
|
|
|
+ <div class="main-container">
|
|
|
+ <!-- 顶部操作栏 -->
|
|
|
+ <div class="modal-top-bar">
|
|
|
+ <div class="time-picker-wrap">
|
|
|
+ <span class="label">时间:</span>
|
|
|
+ <div class="date-input-group">
|
|
|
+ <!-- <input v-model="startDate" type="date" class="date-input" @change="handleTimeChange" />
|
|
|
+ <span class="separator">—</span>
|
|
|
+ <input v-model="endDate" type="date" class="date-input" @change="handleTimeChange" /> -->
|
|
|
+ <a-range-picker
|
|
|
+ v-model:value="timeRange"
|
|
|
+ separator="—"
|
|
|
+ format="YYYY-MM-DD"
|
|
|
+ value-format="YYYY-MM-DD"
|
|
|
+ placeholder=""
|
|
|
+ @change="handleTimeChange"
|
|
|
+ class="date-range-picker"
|
|
|
+ :dropdown-class-name="'custom-range-dropdown'"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="button-area">
|
|
|
+ <button class="export-btn" @click="handleExport">
|
|
|
+ <div class="icon"></div>
|
|
|
+ 数据导出
|
|
|
+ </button>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- 环境监测表格 -->
|
|
|
+ <div class="table-wrap">
|
|
|
+ <table class="monitor-table">
|
|
|
+ <thead>
|
|
|
+ <tr>
|
|
|
+ <th rowspan="2">时间</th>
|
|
|
+ <th colspan="3" class="th-bg">注气区域(定向钻场)</th>
|
|
|
+ <th colspan="4" class="th-bg">抽采区域(回风巷)</th>
|
|
|
+ </tr>
|
|
|
+ <tr>
|
|
|
+ <!-- 注气区域子列 -->
|
|
|
+ <th>甲烷浓度 (%)</th>
|
|
|
+ <th>氧气浓度 (%)</th>
|
|
|
+ <th>温度 (℃)</th>
|
|
|
+ <!-- 抽采区域子列 -->
|
|
|
+ <th>甲烷浓度 (%)</th>
|
|
|
+ <th>氧气浓度 (%)</th>
|
|
|
+ <th>温度 (℃)</th>
|
|
|
+ <th>风速 (m/s)</th>
|
|
|
+ </tr>
|
|
|
+ </thead>
|
|
|
+ <tbody>
|
|
|
+ <tr v-for="(row, index) in tableData" :key="index">
|
|
|
+ <td>{{ row.time }}</td>
|
|
|
+ <td>{{ row.injectionMethane }}</td>
|
|
|
+ <td>{{ row.injectionOxygen }}</td>
|
|
|
+ <td>{{ row.injectionTemp }}</td>
|
|
|
+ <td>{{ row.extractionMethane }}</td>
|
|
|
+ <td>{{ row.extractionOxygen }}</td>
|
|
|
+ <td>{{ row.extractionTemp }}</td>
|
|
|
+ <td>{{ row.extractionWindSpeed }}</td>
|
|
|
+ </tr>
|
|
|
+ <tr v-if="!tableData || tableData.length === 0">
|
|
|
+ <td colspan="8" class="empty-tip">暂无数据</td>
|
|
|
+ </tr>
|
|
|
+ </tbody>
|
|
|
+ </table>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- 趋势折线图 -->
|
|
|
+ <div class="chart-wrap">
|
|
|
+ <div ref="chartRef" class="monitor-chart"></div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script setup lang="ts">
|
|
|
+ import { ref, watch, onMounted, onUnmounted } from 'vue';
|
|
|
+ import * as echarts from 'echarts';
|
|
|
+ import type { EChartsOption } from 'echarts';
|
|
|
+ const timeRange = ref<[string, string]>(['2026-03-12', '2026-03-13']);
|
|
|
+
|
|
|
+ // 表格数据
|
|
|
+ const tableData = ref([
|
|
|
+ {
|
|
|
+ time: '2026-03-12 00:00',
|
|
|
+ injectionMethane: 0.25,
|
|
|
+ injectionOxygen: 20.8,
|
|
|
+ injectionTemp: 22.5,
|
|
|
+ extractionMethane: 0.32,
|
|
|
+ extractionOxygen: 20.5,
|
|
|
+ extractionTemp: 23.1,
|
|
|
+ extractionWindSpeed: 1.2,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ time: '2026-03-12 01:00',
|
|
|
+ injectionMethane: 0.28,
|
|
|
+ injectionOxygen: 20.7,
|
|
|
+ injectionTemp: 22.6,
|
|
|
+ extractionMethane: 0.35,
|
|
|
+ extractionOxygen: 20.4,
|
|
|
+ extractionTemp: 23.2,
|
|
|
+ extractionWindSpeed: 1.3,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ time: '2026-03-12 01:00',
|
|
|
+ injectionMethane: 0.28,
|
|
|
+ injectionOxygen: 20.7,
|
|
|
+ injectionTemp: 22.6,
|
|
|
+ extractionMethane: 0.35,
|
|
|
+ extractionOxygen: 20.4,
|
|
|
+ extractionTemp: 23.2,
|
|
|
+ extractionWindSpeed: 1.3,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ time: '2026-03-12 01:00',
|
|
|
+ injectionMethane: 0.28,
|
|
|
+ injectionOxygen: 20.7,
|
|
|
+ injectionTemp: 22.6,
|
|
|
+ extractionMethane: 0.35,
|
|
|
+ extractionOxygen: 20.4,
|
|
|
+ extractionTemp: 23.2,
|
|
|
+ extractionWindSpeed: 1.3,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ time: '2026-03-12 01:00',
|
|
|
+ injectionMethane: 0.28,
|
|
|
+ injectionOxygen: 20.7,
|
|
|
+ injectionTemp: 22.6,
|
|
|
+ extractionMethane: 0.35,
|
|
|
+ extractionOxygen: 20.4,
|
|
|
+ extractionTemp: 23.2,
|
|
|
+ extractionWindSpeed: 1.3,
|
|
|
+ },
|
|
|
+ ]);
|
|
|
+
|
|
|
+ // 图表数据
|
|
|
+ const chartData = ref({
|
|
|
+ xAxisData: ['4.07 03:00', '4.07 05:00', '4.08 04:00', '4.09 03:00', '4.09 05:00', '4.10 04:00'],
|
|
|
+ series: [
|
|
|
+ { name: '指标1', data: [0.8, 1.0, 0.9, 1.5, 0.8, 1.6], color: '#00ff88' },
|
|
|
+ { name: '指标2', data: [0.4, 0.5, 0.7, 1.0, 0.4, 1.2], color: '#ffaa00' },
|
|
|
+ { name: '指标3', data: [0.9, 1.3, 1.2, 0.9, 0.9, 1.3], color: '#00ddff' },
|
|
|
+ ],
|
|
|
+ });
|
|
|
+
|
|
|
+ // 内部状态
|
|
|
+ const chartRef = ref<HTMLElement>();
|
|
|
+ let chartInstance: echarts.ECharts | null = null;
|
|
|
+
|
|
|
+ // 监听 chartData 变化,自动重新渲染图表
|
|
|
+ watch(
|
|
|
+ chartData,
|
|
|
+ () => {
|
|
|
+ initChart();
|
|
|
+ },
|
|
|
+ { deep: true }
|
|
|
+ );
|
|
|
+
|
|
|
+ const handleTimeChange = () => {
|
|
|
+ console.log('time-change', timeRange.value);
|
|
|
+ };
|
|
|
+ const handleExport = () => {
|
|
|
+ console.log('导出数据');
|
|
|
+ };
|
|
|
+
|
|
|
+ // 图表初始化
|
|
|
+ const initChart = () => {
|
|
|
+ if (!chartRef.value) return;
|
|
|
+ if (chartInstance) chartInstance.dispose();
|
|
|
+ chartInstance = echarts.init(chartRef.value);
|
|
|
+
|
|
|
+ const seriesList = chartData.value.series.map((item) => ({
|
|
|
+ name: item.name,
|
|
|
+ type: 'line',
|
|
|
+ smooth: true,
|
|
|
+ symbol: 'none',
|
|
|
+ data: item.data,
|
|
|
+ lineStyle: { width: 2, color: item.color },
|
|
|
+ areaStyle: {
|
|
|
+ color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
|
|
+ { offset: 0, color: item.color + '80' },
|
|
|
+ { offset: 1, color: item.color + '00' },
|
|
|
+ ]),
|
|
|
+ },
|
|
|
+ }));
|
|
|
+
|
|
|
+ const option: EChartsOption = {
|
|
|
+ backgroundColor: 'transparent',
|
|
|
+ tooltip: { trigger: 'axis', backgroundColor: 'rgba(0,20,40,0.8)', borderColor: '#00aaff', textStyle: { color: '#fff' } },
|
|
|
+ legend: { right: '5%', top: '3%', textStyle: { color: '#fff' }, itemWidth: 10, itemHeight: 10 },
|
|
|
+ grid: { left: '3%', right: '4%', bottom: '3%', top: '15%', containLabel: true },
|
|
|
+ xAxis: {
|
|
|
+ type: 'category',
|
|
|
+ boundaryGap: false,
|
|
|
+ data: chartData.value.xAxisData,
|
|
|
+ axisLine: { lineStyle: { color: 'rgba(0,170,255,0.3)' } },
|
|
|
+ axisLabel: { color: '#aaccff' },
|
|
|
+ splitLine: { show: false },
|
|
|
+ },
|
|
|
+ yAxis: {
|
|
|
+ type: 'value',
|
|
|
+ min: 0,
|
|
|
+ // 修复:调整 Y 轴最大值,避免数据超出显示范围(也可动态计算最大值)
|
|
|
+ max: 2,
|
|
|
+ axisLine: { show: false },
|
|
|
+ axisLabel: { color: '#aaccff' },
|
|
|
+ splitLine: { lineStyle: { color: 'rgba(0,170,255,0.1)' } },
|
|
|
+ },
|
|
|
+ series: seriesList,
|
|
|
+ };
|
|
|
+
|
|
|
+ chartInstance.setOption(option);
|
|
|
+ };
|
|
|
+
|
|
|
+ const resizeChart = () => chartInstance?.resize();
|
|
|
+
|
|
|
+ onMounted(() => {
|
|
|
+ window.addEventListener('resize', resizeChart);
|
|
|
+ initChart();
|
|
|
+ });
|
|
|
+
|
|
|
+ onUnmounted(() => {
|
|
|
+ window.removeEventListener('resize', resizeChart);
|
|
|
+ chartInstance?.dispose();
|
|
|
+ chartInstance = null;
|
|
|
+ });
|
|
|
+</script>
|
|
|
+
|
|
|
+<style scoped lang="less">
|
|
|
+ .main-container {
|
|
|
+ width: 100%;
|
|
|
+ height: 610px;
|
|
|
+ overflow: hidden;
|
|
|
+ padding: 0 35px;
|
|
|
+ }
|
|
|
+ // 顶部操作栏
|
|
|
+ .modal-top-bar {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: space-between;
|
|
|
+ margin: 16px 0;
|
|
|
+ padding: 0 20px;
|
|
|
+ background-image: url('/@/assets/images/gasInjection/syq/modal-top-bg.png');
|
|
|
+ background-size: 100% 100%;
|
|
|
+ background-repeat: no-repeat;
|
|
|
+ background-position: top center;
|
|
|
+ }
|
|
|
+
|
|
|
+ .time-picker-wrap {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ gap: 8px;
|
|
|
+
|
|
|
+ .label {
|
|
|
+ color: #aaccff;
|
|
|
+ font-size: 14px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .date-input-group {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ gap: 4px;
|
|
|
+ background: rgba(0, 30, 60, 0.6);
|
|
|
+ border: 1px solid rgba(0, 170, 255, 0.4);
|
|
|
+ padding: 4px 8px;
|
|
|
+ border-radius: 4px;
|
|
|
+
|
|
|
+ &:hover {
|
|
|
+ border-color: #00aaff;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .date-input-group {
|
|
|
+ padding: 0;
|
|
|
+
|
|
|
+ :deep(.zxm-picker) {
|
|
|
+ background: rgba(0, 30, 60, 0.6);
|
|
|
+ border: 1px solid rgba(0, 170, 255, 0.4);
|
|
|
+
|
|
|
+ &:hover {
|
|
|
+ border-color: #00aaff;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ :deep(.zxm-picker-input > input) {
|
|
|
+ color: #ffffff;
|
|
|
+ font-size: 14px;
|
|
|
+ }
|
|
|
+
|
|
|
+ :deep(.zxm-picker-range-separator) {
|
|
|
+ color: #aaccff;
|
|
|
+ }
|
|
|
+
|
|
|
+ :deep(.zxm-picker-suffix) {
|
|
|
+ color: #aaccff;
|
|
|
+ }
|
|
|
+
|
|
|
+ :deep(.zxm-picker-clear) {
|
|
|
+ color: #fff;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .button-area {
|
|
|
+ border: 1px solid #00aaff;
|
|
|
+ border-radius: 5px;
|
|
|
+ padding: 2px;
|
|
|
+ margin: 5px 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ .export-btn {
|
|
|
+ height: 25px;
|
|
|
+ background: linear-gradient(90deg, #0077ff 0%, #00aaff 100%);
|
|
|
+ border: 1px solid #00aaff;
|
|
|
+ color: #ffffff;
|
|
|
+ padding: 8px 16px;
|
|
|
+ border-radius: 4px;
|
|
|
+ font-size: 14px;
|
|
|
+ cursor: pointer;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ gap: 6px;
|
|
|
+
|
|
|
+ &:hover {
|
|
|
+ background: linear-gradient(90deg, #0088ff 0%, #00bbff 100%);
|
|
|
+ box-shadow: 0 0 15px rgba(0, 170, 255, 0.5);
|
|
|
+ }
|
|
|
+
|
|
|
+ .icon {
|
|
|
+ width: 15px;
|
|
|
+ height: 15px;
|
|
|
+ background-image: url('/@/assets/images/gasInjection/syq/modal-export.svg');
|
|
|
+ background-size: 100% 100%;
|
|
|
+ background-repeat: no-repeat;
|
|
|
+ background-position: top center;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 表格样式
|
|
|
+ .table-wrap {
|
|
|
+ margin-bottom: 20px;
|
|
|
+ max-height: 235px;
|
|
|
+ overflow-y: auto;
|
|
|
+ border-bottom: 1px solid #2893b2;
|
|
|
+
|
|
|
+ // 滚动条样式
|
|
|
+ &::-webkit-scrollbar {
|
|
|
+ width: 2px;
|
|
|
+ height: 6px;
|
|
|
+ }
|
|
|
+
|
|
|
+ &::-webkit-scrollbar-thumb {
|
|
|
+ background: rgba(0, 170, 255, 0.3);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .monitor-table {
|
|
|
+ width: 100%;
|
|
|
+ border-collapse: collapse;
|
|
|
+ color: #ffffff;
|
|
|
+ font-size: 14px;
|
|
|
+
|
|
|
+ td {
|
|
|
+ padding: 8px 12px;
|
|
|
+ text-align: center;
|
|
|
+ }
|
|
|
+
|
|
|
+ th {
|
|
|
+ border: 1px solid #2893b2;
|
|
|
+ padding: 8px 12px;
|
|
|
+ text-align: center;
|
|
|
+ background: #103967;
|
|
|
+ color: #2fb8d3;
|
|
|
+ font-weight: 500;
|
|
|
+ }
|
|
|
+ .th-bg {
|
|
|
+ background-color: #1b578e;
|
|
|
+ }
|
|
|
+ tbody tr {
|
|
|
+ background: rgb(11, 35, 66, 0.3);
|
|
|
+ }
|
|
|
+ tbody tr:nth-child(odd) {
|
|
|
+ background: rgb(13, 44, 82, 0.8);
|
|
|
+ }
|
|
|
+
|
|
|
+ .empty-tip {
|
|
|
+ color: #aaccff;
|
|
|
+ padding: 20px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 图表容器
|
|
|
+ .chart-wrap {
|
|
|
+ width: 100%;
|
|
|
+ height: 280px;
|
|
|
+ background: rgb(17, 40, 71, 0.5);
|
|
|
+
|
|
|
+ .monitor-chart {
|
|
|
+ width: 100%;
|
|
|
+ height: 100%;
|
|
|
+ }
|
|
|
+ }
|
|
|
+</style>
|