lxh 3 месяцев назад
Родитель
Сommit
9fa6c48b0f

+ 6 - 0
src/assets/icons/shencen.svg

@@ -0,0 +1,6 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="14.703" height="14.703" viewBox="0 0 14.703 14.703">
+  <g id="组_15180" data-name="组 15180" transform="translate(-64 -64)">
+    <path id="路径_56238" data-name="路径 56238" d="M78.126,68.49a7.378,7.378,0,1,0,.578,2.862A7.331,7.331,0,0,0,78.126,68.49Zm-6.774,9.163a6.3,6.3,0,1,1,6.3-6.3A6.309,6.309,0,0,1,71.352,77.653Z" fill="#fff"/>
+    <path id="路径_56239" data-name="路径 56239" d="M268.754,301.708l-3.507-3.508v2.983H260.5v1.05h4.747v2.983Z" transform="translate(-193.275 -230.357)" fill="#fff"/>
+  </g>
+</svg>

+ 35 - 0
src/views/analysis/warningAnalysis/connectAnalysis/components/echart-divder.vue

@@ -0,0 +1,35 @@
+<template>
+  <div class="divder-line">
+    <div class="line-l"></div>
+    <div class="line-c"></div>
+    <div class="line-r"></div>
+  </div>
+</template>
+
+<script setup lang="ts">
+
+</script>
+
+<style lang="less" scoped>
+.divder-line {
+  width: 100%;
+display: flex;
+  .line-l {
+    width: 15px;
+    height: 1px;
+    background-color: #3d7bf0;
+  }
+
+  .line-c {
+    width: calc(100% - 30px);
+    height: 1px;
+    border-top: 1px dashed #3d7bf0;
+  }
+
+  .line-r {
+    width: 15px;
+    height: 1px;
+    background-color: #3d7bf0;
+  }
+}
+</style>

+ 9 - 10
src/views/analysis/warningAnalysis/connectAnalysis/connectAnalysis.data.ts

@@ -1,13 +1,13 @@
 
-export const plainOptions = [
-  { label: 'CO浓度(ppm)', value: 'coVal' },
-  { label: 'CH4浓度(%)', value: 'ch4Val' },
-  { label: 'C2H4浓度(ppm)', value: 'c2h4Val' },
-  { label: 'C2H2浓度(ppm)', value: 'c2h2Val' },
-  { label: 'CO2浓度(%)', value: 'co2Val' },
-  { label: 'O2浓度(%)', value: 'o2Val' },
-  { label: '压差(kPa)', value: 'sourcePressure' },
-  { label: '温度(℃)', value: 'temperature' },
+export const plainOptions: any[] = [
+  { label: 'CO浓度(ppm)', value: 'coVal', color: '#3bd97a', areaColor: ['rgba(59, 217, 122,0.1)','rgba(59, 217, 122,0.8)'] },
+  { label: 'CH4浓度(%)', value: 'ch4Val', color: '#f9c74a', areaColor: ['rgba(249, 199, 74,0.1)','rgba(249, 199, 74,0.8)'] },
+  { label: 'C2H4浓度(ppm)', value: 'c2h4Val', color: '#ac7bf1', areaColor: ['rgba(172, 123, 241,0.1)','rgba(172, 123, 241,0.8)'] },
+  { label: 'C2H2浓度(ppm)', value: 'c2h2Val', color: '#50b2f9', areaColor: ['rgba(80, 178, 249,0.1)','rgba(80, 178, 249,0.8)'] },
+  { label: 'CO2浓度(%)', value: 'co2Val', color: '#1fd0da', areaColor: ['rgba(31, 208, 218,0.1)','rgba(31, 208, 218,0.8)'] },
+  { label: 'O2浓度(%)', value: 'o2Val', color: '#ff6666', areaColor: ['rgba(255, 102, 102,0.1)','rgba(255, 102, 102,0.8)'] },
+  { label: '压差(kPa)', value: 'sourcePressure', color: '#3b4bd9', areaColor: ['rgba(59, 75, 217,0.1)','rgba(59, 75, 217,0.8)'] },
+  { label: '温度(℃)', value: 'temperature', color: '#f18736', areaColor: ['rgba(241, 135, 54,0.1)','rgba(241, 135, 54,0.8)'] },
 ]
 
 export const lengendTitle = [
@@ -20,6 +20,5 @@ export const lengendTitle = [
   { label: '压差(kPa)' },
   { label: '温度(℃)' },
 ]
-export const echartColor=['#3bd97a','#f9c74a','#ac7bf1','#50b2f9','#1fd0da','#ff6666','#3b4bd9','#f18736']
 
 

+ 38 - 17
src/views/analysis/warningAnalysis/connectAnalysis/index.vue

@@ -2,35 +2,40 @@
   <div class="connectAnalysis">
     <div class="filter-area">
       <Row style="width: 100%">
-        <Col :span="6">
+        <Col :span="7">
           <div class="filter-section param-section">
             <span class="filter-label">煤矿名称:</span>
             <div class="param-selector">
-              <MineCascader v-model:value="innerValue" style="width: 300px" :sync-to-store="false"
+              <MineCascader v-model:value="innerValue" style="width: 330px" :sync-to-store="false"
                 :init-from-store="false" @change="changeCascader"></MineCascader>
             </div>
           </div>
         </Col>
-        <Col :span="6">
+        <Col :span="7">
           <!-- 时间选择 -->
           <div class="filter-section param-section">
             <span class="filter-label">采空区选择:</span>
-            <Select ref="select" v-model:value="goafId" style="width: 300px" placeholder="请选择采空区">
+            <Select ref="select" v-model:value="goafId" style="width: 330px" placeholder="请选择采空区">
               <SelectOption v-for="(item, index) in goafOption" :key="index" :value="item.value">{{ item.label }}
               </SelectOption>
             </Select>
           </div>
         </Col>
-        <Col :span="6">
+        <Col :span="7">
           <div class="filter-section param-section">
             <span class="filter-label">时间选择:</span>
             <RangePicker v-model:value="dateRange" format="YYYY-MM-DD HH:mm:ss" :placeholder="['开始时间', '结束时间']"
-              style="width: 300px" :show-time="{ format: 'HH:mm:ss' }" @change="changeTime" />
+              style="width: 330px" :show-time="{ format: 'HH:mm:ss' }" @change="changeTime" />
           </div>
         </Col>
-        <Col :span="6">
+        <Col :span="2">
           <div class="filter-section">
-            <Button type="primary" @click="generateChart">生成</Button>
+            <Button type="primary" @click="generateChart">
+              <template #icon>
+                <SvgIcon style="margin-right: 10px;" name="shencen" />
+              </template>
+              生成
+            </Button>
           </div>
         </Col>
       </Row>
@@ -40,8 +45,14 @@
       <div class="check-title">
         <CheckboxNav @checkBoxChange="checkBoxChange"></CheckboxNav>
       </div>
+      <div class="check-line">
+        <echartDivder></echartDivder>
+      </div>
       <div class="echart-content">
         <echartContent :echartData="echartData"></echartContent>
+      </div>
+       <div class="check-line">
+        <echartDivder></echartDivder>
       </div>
       <div class="check-title">
         <echartLengend></echartLengend>
@@ -58,9 +69,11 @@ import MineCascader from '@/components/Form/src/jeecg/components/MineCascader/Mi
 import CheckboxNav from './components/checkbox-nav.vue'
 import echartLengend from './components/echart-lengend.vue'
 import echartContent from './components/echart-content.vue'
+import echartDivder from './components/echart-divder.vue'
 import { getGoafHistory, getGoafList } from './connectAnalysis.api';
 import { useRouter } from 'vue-router';
 import { useMineDepartmentStore } from '/@/store/modules/mine';
+import { SvgIcon } from '/@/components/Icon';
 
 // 组件注册
 const RangePicker: any = DatePicker.RangePicker;
@@ -147,34 +160,33 @@ onMounted(async () => {
 <style lang="less" scoped>
 .connectAnalysis {
   width: calc(100% - 10px);
-  height: calc(100% - 20px);
-  margin: 10px 0px 10px 10px;
+  height: calc(100% - 10px);
+  margin: 10px 0px 0px 10px;
   padding: 10px;
   box-sizing: border-box;
   border: 1px solid #c8d0dd;
-  border-radius: 5px;
+  border-radius: 4px;
 
   .filter-area {
     display: flex;
     flex-wrap: wrap;
     gap: 16px;
-    margin-bottom: 15px;
     padding: 20px;
     border: 1px solid #f0f0f0;
-    border-radius: 10px;
+    border-radius: 4px;
     background: @card-bg-color;
     align-items: center;
+    box-shadow: 0px 0px 8px 1px rgba(202, 211, 225, 0.5);
   }
 
   .filter-section {
     display: flex;
     align-items: center;
-    gap: 8px;
   }
 
   .filter-label {
     color: #666;
-    min-width: 80px;
+    min-width: 70px;
     flex-shrink: 0;
     font-weight: 500;
   }
@@ -200,15 +212,24 @@ onMounted(async () => {
     height: 40px;
     line-height: 40px;
     background-color: #d0e1fa;
-    border-radius: 3px;
+    border-radius: 4px;
     padding: 0px 20px;
     box-sizing: border-box;
+    margin: 15px 0px;
+  }
+
+  .check-line {
+    width: 100%;
   }
 
   .echart-content {
     width: 100%;
-    height: calc(100% - 80px);
+    height: calc(100% - 112px);
   }
+}
 
+:deep(.ant-btn-primary) {
+  display: flex !important;
+  align-items: center !important;
 }
 </style>

+ 0 - 381
src/views/analysis/warningAnalysis/connectAnalysis/index_copy .vue

@@ -1,381 +0,0 @@
-<template>
-  <div class="connectAnalysis">
-    <div class="filter-area">
-      <Row style="width: 100%">
-        <Col :span="6">
-          <div class="filter-section param-section">
-            <span class="filter-label">煤矿名称:</span>
-            <div class="param-selector">
-              <MineCascader  v-model:value="innerValue" style="width: 300px" :sync-to-store="false" :init-from-store="false"></MineCascader>
-            </div>
-          </div>
-        </Col>
-        <Col :span="6">
-          <!-- 时间选择 -->
-          <div class="filter-section param-section">
-            <span class="filter-label">采空区选择:</span>
-            <Select ref="select" v-model:value="goafId" style="width: 300px" placeholder="请选择采空区">
-              <SelectOption v-for="(item, index) in goafOption" :key="index" :value="item.value">{{ item.label }} </SelectOption>
-            </Select>
-          </div>
-        </Col>
-        <Col :span="6">
-          <div class="filter-section param-section">
-            <span class="filter-label">时间选择:</span>
-            <RangePicker
-              v-model:value="dateRange"
-              format="YYYY-MM-DD HH:mm:ss"
-              :placeholder="['开始时间', '结束时间']"
-              style="width: 300px"
-              :show-time="{ format: 'HH:mm:ss' }"
-              @change="changeTime"
-            />
-          </div>
-        </Col>
-        <Col :span="6">
-          <div class="filter-section">
-            <Button type="primary" @click="generateChart">生成</Button>
-          </div>
-        </Col>
-      </Row>
-
-      <!-- <Row style="width:100%">
-        <Col :span="8">
-          <div class="filter-section param-section">
-            <span class="filter-label">参数选择:</span>
-            <div class="param-selector">
-              <Input v-model="selectedParamsText" placeholder="请选择监测参数" readonly style="width: 300px" />
-              <Button type="primary" @click="showTree = !showTree">+</Button>
-              <div class="tree-popup" v-if="showTree">
-                <BasicTree :treeData="treeData" :checkable="true" defaultExpandAll @check="handleTreeCheck" :checkedKeys="checkedTreeKeys" />
-              </div>
-            </div>
-          </div>
-        </Col>
-      </Row> -->
-    </div>
-    <!-- 动态图表区域-->
-    <div class="chart-area">
-      <div class="chart-item" style="flex: 1 1 100%">
-        <div class="chart-placeholder">
-          <template v-if="generatedChartData.length">
-            <CustomChart :chart-data="generatedChartData" :chart-config="generatedChartConfig" style="height: 100%; width: 100%" />
-          </template>
-          <template v-else-if="isChartGenerated">
-            <div class="empty-chart">暂无匹配数据,请调整筛选条件</div>
-          </template>
-          <template v-else>
-            <div class="empty-chart">请选择时间范围和参数,点击"生成"查看数据</div>
-          </template>
-        </div>
-      </div>
-    </div>
-  </div>
-</template>
-
-<script setup lang="ts">
-  import { computed, ref, onMounted, watchEffect } from 'vue';
-  import dayjs from 'dayjs';
-  // import { treeData, historicalMockChartData } from './connectAnalysis.data'; // 引入模拟数据
-  import { Select, SelectOption, Row, Col, DatePicker, Button, message, Input } from 'ant-design-vue';
-  // import { BasicTree } from '/@/components/Tree/index';
-  import CustomChart from '/@/components/Configurable/detail/CustomChart.vue';
-  import MineCascader from '@/components/Form/src/jeecg/components/MineCascader/MineCascader.vue';
-  import { getGoafHistory, getGoafList } from './connectAnalysis.api';
-  import { useRouter } from 'vue-router';
-   import { useMineDepartmentStore } from '/@/store/modules/mine';
-
-  // 组件注册
-  const RangePicker: any = DatePicker.RangePicker;
-  const { currentRoute } = useRouter();
-  // 筛选相关响应式数据
-  const dateRange = ref([dayjs().add(-30, 'day'), dayjs()]); // 默认时间范围(近1天)
-  // const selectedParamsText = ref(''); // 参数选择框显示文本
-  // const showTree = ref(false); // 控制树形选择器显示/隐藏
-  // const checkedTreeKeys = ref([]); // 树形选中的key
-  const selectedParams = ref(['coVal', 'ch4Val', 'c2h4Val', 'c2h2Val', 'co2Val', 'o2Val', 'sourcePressure', 'temperature']); // 选中的参数(实际用于图表)
-  const generatedChartData = ref<any[]>([]); // 生成的图表数据
-  const generatedChartConfig = ref({}); // 生成的图表配置
-  const isChartGenerated = ref(false); // 是否已点击生成
-  const goafId = ref(''); //采空区id
-  const goafOption = ref<any[]>([]); //采空区列表
-  const filteredData = ref<any[]>([]); //曲线数据
-
-  const innerValue = ref('100004');
-   const mineStore = useMineDepartmentStore();
-   const mineCode = ref<any>(currentRoute.value['query']['mineCode']); //传递过来的矿ID
-
-  // // Tree Key 与参数名映射(关键:关联树形节点和实际参数)
-  //   const treeKeyToParamMap = computed(() => ({
-  //     '0-0-0': 'CO',
-  //     '0-0-1': 'CH4',
-  //     '0-0-2': 'C2H4',
-  //     '0-0-3': 'C2H2',
-  //     '0-0-4': 'CO2',
-  //     '0-0-5': 'O2',
-  //     '1-1-0': 'innerPressure',
-  //     '1-1-1': 'outerPressure',
-  //     '1-1-2': 'pressureDiff',
-  //     '2-2': 'temperature',
-  //   }));
-  //  // 树形选择事件处理
-  //   const handleTreeCheck = (checkedKeys) => {
-  //     checkedTreeKeys.value = checkedKeys;
-  //     // 转换为实际参数名
-  //     const params = checkedKeys
-  //       .map(key => treeKeyToParamMap.value[key])
-  //       .filter(param => param); // 过滤无效参数
-  //     selectedParams.value = params;
-  //     console.log(selectedParams.value, ' selectedParams')
-  //     // 更新输入框显示文本
-  //     const paramLabels = params.map(param => paramLabelMap.value[param]);
-  //     selectedParamsText.value = paramLabels.join('、');
-  //     console.log(selectedParamsText.value, ' selectedParamsText')
-  //   };
-
-  function changeCascader(val) {
-    innerValue.value = val;
-  }
-  function changeTime(val) {
-    dateRange.value[0] = val[0];
-    dateRange.value[1] = val[1];
-  }
-
-  // 参数颜色映射
-  const paramColorMap = computed(() => ({
-    coVal: '#f5222d', // 红色
-    ch4Val: '#1890ff', // 蓝色
-    c2h4Val: '#faad14', // 橙色
-    c2h2Val: '#52c41a', // 绿色
-    co2Val: '#722ed1', // 紫色
-    o2Val: '#13c2c2', // 青色
-    sourcePressure: '#ff4d4f', // 浅红
-    temperature: '#40a9ff', // 浅蓝
-  }));
-
-  // 参数标签映射(图表系列名称)
-  const paramLabelMap = computed(() => ({
-    coVal: 'CO浓度(ppm)',
-    ch4Val: 'CH4浓度(%)',
-    c2h4Val: 'C2H4浓度(ppm)',
-    c2h2Val: 'C2H2浓度(ppm)',
-    co2Val: 'CO2浓度(%)',
-    o2Val: 'O2浓度(%)',
-    sourcePressure: '压差(kPa)',
-    temperature: '温度(℃)',
-  }));
-  // 生成折线图核心逻辑
-  async function generateChart() {
-    // showTree.value = false
-    //获取采空区历史数据列表
-    let startTime = dateRange.value[0].format('YYYY-MM-DD HH:mm:ss');
-    let endTime = dateRange.value[1].format('YYYY-MM-DD HH:mm:ss');
-    let res = await getGoafHistory({ pageNo: 1, pageSize: 100, startTime: startTime, endTime: endTime, goafId: goafId.value });
-    if (res && res.records) {
-      filteredData.value = res.records;
-      isChartGenerated.value = false;
-    } else {
-      filteredData.value.length = 0;
-      isChartGenerated.value = true;
-    }
-    console.log(filteredData.value, 'filteredData');
-
-    // 2. 构建图表数据结构(适配 CustomChart 的 line 类型)
-    const timeMap = new Map();
-    // 修复变量名:filteredRawData → filteredData(之前未定义)
-    filteredData.value.forEach((item) => {
-      const timeStr = dayjs(item.createTime).format('YYYY-MM-DD HH:mm:ss');
-      if (!timeMap.has(timeStr)) {
-        timeMap.set(timeStr, { time: timeStr });
-      }
-      // 只保留选中的参数数据
-      selectedParams.value.forEach((param) => {
-        if (item[param] !== undefined) {
-          timeMap.get(timeStr)[param] = item[param];
-        }
-      });
-    });
-
-    // 转换为数组并按时间排序
-    const chartData = Array.from(timeMap.values()).sort((a, b) => {
-      return dayjs(a.time).valueOf() - dayjs(b.time).valueOf();
-    });
-    generatedChartData.value = chartData;
-    console.log(generatedChartData.value, 'generatedChartData');
-
-    // 3. 构建图表配置(折线图类型,完善适配逻辑)
-    generatedChartConfig.value = {
-      type: 'line', // 折线图
-      clear: true, // 每次生成清空之前的图表
-      legend: { show: true, top: 10, right: 10, textStyle: { color: '#fff', fontSize: 14 } },
-      xAxis: [
-        {
-          type: 'category',
-          axisLabel: {
-            rotate: 30,
-            textStyle: {
-              color: '#fff',
-            },
-            formatter: (value) => dayjs(value).format('HH:mm:ss'),
-            interval: Math.max(1, Math.floor(chartData.length / 10)), // 控制x轴标签密度
-          },
-        },
-      ],
-      yAxis: selectedParams.value.map((param) => ({
-        type: 'value',
-        axisLabel: {
-          textStyle: {
-            color: '#fff',
-          },
-        },
-        name: paramLabelMap.value[param].split('(')[1].replace(')', ''), // 显示单位
-        // nameTextStyle: { color: paramColorMap.value[param] },
-        nameTextStyle: { color: '#fff' },
-        axisLine: { lineStyle: { color: paramColorMap.value[param] } },
-        splitLine: { lineStyle: { opacity: 0.1 } },
-      })),
-      series: selectedParams.value.map((param, index) => ({
-        name: paramLabelMap.value[param],
-        type: 'line',
-        readFrom: '', // 适配 CustomChart 的 baseSeries 读取逻辑
-        label: paramLabelMap.value[param],
-        xprop: 'time', // 对应图表数据的 x 字段(时间)
-        yprop: param, // 对应图表数据的 y 字段(参数值)
-        color: paramColorMap.value[param],
-        smooth: true,
-        symbol: 'circle',
-        symbolSize: 4,
-        yAxisIndex: index,
-      })),
-      tooltip: {
-        trigger: 'axis',
-        axisPointer: { type: 'cross' },
-        formatter: (params) => {
-          let tooltipHtml = `<div>${dayjs(params[0].axisValue).format('YYYY-MM-DD HH:mm:ss')}</div>`;
-          params.forEach((param) => {
-            tooltipHtml += `<div style="color: ${param.color}">${param.seriesName}: ${param.value[1]} ${param.seriesName.split('(')[1].replace(')', '')}</div>`;
-          });
-          return tooltipHtml;
-        },
-      },
-      grid: { left: 60, top: 40, right: 60, bottom: 60 },
-    };
-
-    // 无数据提示
-    if (chartData.length === 0) {
-      message.info('当前筛选条件下无数据');
-    }
-  }
-
-  //获取采空区列表
-  async function getGoafListData() {
-    let res = await getGoafList({ mineCode: innerValue.value });
-    if (res.length) {
-      goafOption.value = res.map((el) => {
-        return {
-          label: el.devicePos,
-          value: el.id,
-        };
-      });
-      goafId.value = goafId.value ? goafId.value : goafOption.value[0]['value'];
-    }
-  }
-
-  watchEffect(() => {
-    console.log(mineStore)
-    innerValue.value && getGoafListData();
-  });
-</script>
-
-<style lang="less" scoped>
-  .connectAnalysis {
-    padding: 16px;
-
-    .filter-area {
-      display: flex;
-      flex-wrap: wrap;
-      gap: 16px;
-      margin-bottom: 20px;
-      padding: 20px;
-      border: 1px solid #f0f0f0;
-      border-radius: 10px;
-      background: @card-bg-color;
-      align-items: center;
-    }
-
-    .filter-section {
-      display: flex;
-      align-items: center;
-      gap: 8px;
-    }
-
-    .filter-label {
-      color: #666;
-      min-width: 80px;
-      flex-shrink: 0;
-      font-weight: 500;
-    }
-
-    .param-section {
-      flex: 1;
-      // min-width: 300px;
-    }
-
-    .param-selector {
-      display: flex;
-      align-items: center;
-      gap: 8px;
-      position: relative;
-    }
-
-    .tree-popup {
-      position: absolute;
-      top: 100%;
-      left: 0;
-      margin-top: 8px;
-      width: 300px;
-      max-height: 300px;
-      overflow-y: auto;
-      background: #fff;
-      border: 1px solid #e8e8e8;
-      border-radius: 4px;
-      box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
-      z-index: 100;
-      padding: 8px;
-    }
-
-    .chart-area {
-      display: flex;
-      flex-wrap: wrap;
-      gap: 16px;
-      padding: 20px;
-      border: 1px solid #f0f0f0;
-      border-radius: 10px;
-      background: @card-bg-color;
-    }
-
-    .chart-item {
-      flex: 1;
-      min-width: 200px;
-    }
-
-    .chart-placeholder {
-      width: 100%;
-      height: 300px;
-      border-radius: 4px;
-      overflow: hidden;
-      background: #333;
-      border: 1px solid #eee;
-    }
-
-    .empty-chart {
-      width: 100%;
-      height: 100%;
-      display: flex;
-      align-items: center;
-      justify-content: center;
-      color: #999;
-      font-size: 14px;
-    }
-  }
-</style>