餐饮油烟智能监测与监管一体化平台
feiyu02
6 天以前 ccc970e575ef3f3e5c67af8da210263f4ac549f9
src/views/monitor/DataException.vue
@@ -1,399 +1,378 @@
<template>
  <el-row ref="h1">
    <el-col>
      <!-- 菜单读标题 -->
      <div ref="h1" class="header-container">
        <span class="describe-info">店铺名选择:</span>
        <!-- 店铺名  级联 -->
        <ShopNameAndID @submit-id="(n) => (deviceId[1] = n)"></ShopNameAndID>
        <!-- 异常类型选择 -->
        <ExceptionType @submitExceptionType="(val) => (exceptionValue = val)"> </ExceptionType>
        <TimeSelect @submit-time="giveTime"></TimeSelect>
      </div>
      <div ref="h2" style="display: flex; margin-top: 2px; justify-content: right">
        <el-button
          type="primary"
          plain
          style="margin-left: 20px"
          :loading="button.queryButton"
          @click="showTable"
          >查询</el-button
        >
        <el-tooltip
          class="box-item"
          effect="dark"
          content="点击可导出Excel文件"
          placement="top-start"
        >
          <!-- 做成函数js文件 -->
          <el-icon class="iconExcel clickable" title="导出Excel文件" @click="exportDom">
            <i-ep-Download />
            <!-- 导出为Excel -->
          </el-icon>
        </el-tooltip>
      </div>
      <div style="display: flex; justify-content: right; margin-right: 40px">
        <span class="collapse-header-text">
          静安区 {{ beginTime }} —— {{ endTime }} 油烟监测异常信息汇总</span
        >
      </div>
      <br />
      <el-collapse ref="h3" v-model="activeNames">
  <div class="data-exception-container">
    <!-- 搜索区域 -->
    <div ref="h1" class="search-container">
      <el-collapse v-model="activeSearchNames" @change="handleSearchCollapseChange">
        <el-collapse-item name="1">
          <template #title>
            <el-tooltip class="box-item" effect="dark" content="点击可折叠" placement="right-start">
              <h4 class="collapse-header">异常分析</h4>
              <el-icon class="header-icon">
                <i-ep-info-filled />
              </el-icon>
            </el-tooltip>
            <el-tooltip class="box-item" effect="dark" content="点击可折叠" placement="right-start">
            </el-tooltip>
            <div class="search-header">
              <h3>预警范围</h3>
              <span v-if="!isSearchExpanded" class="search-summary">
                {{ getSearchSummary() }}
              </span>
            </div>
          </template>
          <el-card class="box-card">
            <el-row :gutter="25">
              <el-col :span="8">
                <div style="display: flex">
                  <img
                    src="@/assets/exceed.jpg"
                    style="width: 25px; height: 25px; margin-top: 5px"
                  />
                  <span
                    style="font-size: 16px; font-weight: bold; margin-top: 4px; margin-left: 4px"
                    >油烟浓度超标</span
                  >
          <el-row>
            <div class="search-form">
              <div class="form-row">
                <div class="form-item">
                  <span class="form-label">店铺设备:</span>
                  <ShopNameAndID @submit-id="(n) => (deviceId[1] = n)"></ShopNameAndID>
                </div>
                <div class="box-card-label">
                  <el-scrollbar>
                    <span class="box-card-label">异常店铺占比:</span>
                    <span style="font-size: 20px">{{ exception0.length }} /{{ shopsTotal }} </span>
                    <span style="font-size: 17px">
                      ({{ ((exception0.length / shopsTotal) * 100).toFixed(1) }}%)</span
                    >
                    {{ shopsTotal }}
                    <span class="right-text">
                      异常数占比:{{ ((exception0Num / exceptionAllNum) * 100).toFixed(1) }}%
                    </span>
                  </el-scrollbar>
                <div class="form-item">
                  <ExceptionType @submitExceptionType="(val) => (exceptionValue = val)">
                  </ExceptionType>
                </div>
                <hr />
                <div class="box-card-butcontainer">
                  <el-card class="sub-box-card">
                    <el-scrollbar max-height="70px">
                      <ExceptionText
                        v-for="(item, index) in exception0"
                        :key="item"
                        :devId="item.devId"
                        exception-value="0"
                        :begin-time="beginTime"
                        :end-time="endTime"
                        @submit-exception-data="getAbnormalDataByClick"
                      >
                        {{ item.diName }}
                        <span v-if="index < exception0.length - 1" class="text-blank">,</span>
                      </ExceptionText>
                    </el-scrollbar>
                  </el-card>
              </div>
              <div class="form-row">
                <div class="form-item full-width">
                  <TimeSelect @submit-time="giveTime" :useNewStyle="false"></TimeSelect>
                </div>
              </el-col>
              <el-col :span="8">
                <div style="display: flex">
                  <img
                    src="@/assets/exception.jpg"
                    style="width: 25px; height: 25px; margin-top: 5px"
                  />
                  <span
                    style="font-size: 16px; font-weight: bold; margin-top: 5px; margin-left: 4px"
                    >供电异常</span
                  >
                </div>
                <div class="box-card-label">
                  <el-scrollbar>
                    <span class="box-card-label">异常店铺占比:</span>
                    <span style="font-size: 20px">{{ exception1.length }} /{{ shopsTotal }}</span>
                    <span style="font-size: 17px">
                      ({{ ((exception1.length / shopsTotal) * 100).toFixed(1) }}%)</span
                    >
                    <span class="right-text">
                      异常数占比:{{ ((exception1Num / exceptionAllNum) * 100).toFixed(1) }}%
                    </span>
                  </el-scrollbar>
                </div>
                <hr />
                <div>
                  <el-card class="sub-box-card">
                    <el-scrollbar max-height="70px">
                      <ExceptionText
                        v-for="(item, index) in exception1"
                        :key="item"
                        :devId="item.devId"
                        exception-value="1"
                        :begin-time="beginTime"
                        :end-time="endTime"
                        @submit-exception-data="getAbnormalDataByClick"
                      >
                        {{ item.diName }}
                        <span v-if="index < exception1.length - 1" class="text-blank">,</span>
                      </ExceptionText>
                    </el-scrollbar>
                  </el-card>
                </div>
              </el-col>
              <el-col :span="8">
                <div style="display: flex">
                  <img
                    src="@/assets/offline.jpg"
                    style="width: 25px; height: 25px; margin-top: 5px"
                  />
                  <span
                    style="font-size: 16px; font-weight: bold; margin-top: 5px; margin-left: 4px"
                    >设备或网络异常</span
                  >
                </div>
                <div class="box-card-label">
                  <el-scrollbar>
                    <span class="box-card-label">异常店铺占比:</span>
                    <span style="font-size: 20px">{{ exception2.length }} /{{ shopsTotal }}</span>
                    <span style="font-size: 17px">
                      ({{ ((exception2.length / shopsTotal) * 100).toFixed(1) }}%)</span
                    >
                    <span class="right-text"> 异常数占比:{{ connectException }}% </span>
                  </el-scrollbar>
                </div>
                <hr />
                <div>
                  <el-card class="sub-box-card">
                    <el-scrollbar max-height="70px">
                      <ExceptionText
                        v-for="(item, index) in exception2"
                        :key="item"
                        :devId="item.devId"
                        exception-value="2"
                        :begin-time="beginTime"
                        :end-time="endTime"
                        @submit-exception-data="getAbnormalDataByClick"
                      >
                        {{ item.diName }}
                        <span v-if="index < exception2.length - 1" class="text-blank">,</span>
                      </ExceptionText>
                    </el-scrollbar>
                  </el-card>
                </div>
              </el-col>
            </el-row>
          </el-card>
              </div>
            </div>
            <div class="form-actions">
              <el-button type="primary" :loading="button.queryButton" @click="showTable"
                >查询</el-button
              >
              <el-tooltip
                class="box-item"
                effect="dark"
                content="点击可导出Excel文件"
                placement="top-start"
              >
                <el-icon class="iconExcel clickable" title="导出Excel文件" @click="exportDom">
                  <i-ep-Download />
                </el-icon>
              </el-tooltip>
            </div>
          </el-row>
          <div class="summary-info">
            <span>{{ beginTime }} —— {{ endTime }} 油烟监测异常信息汇总</span>
          </div>
        </el-collapse-item>
      </el-collapse>
    </div>
      <h4 class="table-text">异常数据</h4>
    </el-col>
  </el-row>
  <el-card class="table-page" v-show="!isNoData">
    <el-table
      ref="tableH"
      size="small"
      v-loading="loading"
      :data="displayData"
      style="width: 100%"
      border
      :height="tableHeight"
      :cell-class-name="tableCellClassName"
    >
      <el-table-column prop="diName" label="店铺名称" align="center">
        <template #default="{ row }">
          <el-tooltip effect="dark" :content="row.diName">
            <div class="cell ellipsis">{{ row.diName }}</div>
          </el-tooltip>
        </template>
      </el-table-column>
    <!-- 异常分析 -->
    <div class="analysis-container">
      <el-space>
        <h4 class="collapse-header">监测预警</h4>
        <el-icon class="header-icon">
          <i-ep-info-filled />
        </el-icon>
      </el-space>
      <el-card class="analysis-card">
        <el-row :gutter="24">
          <el-col :span="8">
            <div class="analysis-item">
              <div class="item-header">
                <img src="@/assets/exceed.jpg" class="item-icon" />
                <span class="item-title">油烟浓度超标</span>
              </div>
              <div class="item-content">
                <div class="item-stats">
                  <span class="stats-label">异常店铺占比:</span>
                  <span class="stats-value">{{ exception0.length }} /{{ shopsTotal }}</span>
                  <span class="stats-percent"
                    >({{ ((exception0.length / shopsTotal) * 100).toFixed(1) }}%)</span
                  >
                </div>
                <div class="item-percent">
                  异常数占比:{{ ((exception0Num / exceptionAllNum) * 100).toFixed(1) }}%
                </div>
              </div>
              <hr class="item-divider" />
              <div class="item-shops">
                <el-scrollbar :height="scrollbarHeight">
                  <el-space wrap>
                    <ExceptionText
                      v-for="(item, index) in exception0"
                      :key="item"
                      :devId="item.devId"
                      exception-value="0"
                      :begin-time="beginTime"
                      :end-time="endTime"
                      @submit-exception-data="getAbnormalDataByClick"
                    >
                      {{ item.diName }}
                      <span v-if="index < exception0.length - 1" class="text-blank"></span>
                    </ExceptionText>
                  </el-space>
                </el-scrollbar>
              </div>
            </div>
          </el-col>
          <el-col :span="8">
            <div class="analysis-item">
              <div class="item-header">
                <img src="@/assets/exception.jpg" class="item-icon" />
                <span class="item-title">供电异常</span>
              </div>
              <div class="item-content">
                <div class="item-stats">
                  <span class="stats-label">异常店铺占比:</span>
                  <span class="stats-value">{{ exception1.length }} /{{ shopsTotal }}</span>
                  <span class="stats-percent"
                    >({{ ((exception1.length / shopsTotal) * 100).toFixed(1) }}%)</span
                  >
                </div>
                <div class="item-percent">
                  异常数占比:{{ ((exception1Num / exceptionAllNum) * 100).toFixed(1) }}%
                </div>
              </div>
              <hr class="item-divider" />
              <div class="item-shops">
                <el-scrollbar :height="scrollbarHeight">
                  <el-space wrap>
                    <ExceptionText
                      v-for="(item, index) in exception1"
                      :key="item"
                      :devId="item.devId"
                      exception-value="1"
                      :begin-time="beginTime"
                      :end-time="endTime"
                      @submit-exception-data="getAbnormalDataByClick"
                    >
                      {{ item.diName }}
                      <span v-if="index < exception1.length - 1" class="text-blank"></span>
                    </ExceptionText>
                  </el-space>
                </el-scrollbar>
              </div>
            </div>
          </el-col>
          <el-col :span="8">
            <div class="analysis-item">
              <div class="item-header">
                <img src="@/assets/offline.jpg" class="item-icon" />
                <span class="item-title">设备或网络异常</span>
              </div>
              <div class="item-content">
                <div class="item-stats">
                  <span class="stats-label">异常店铺占比:</span>
                  <span class="stats-value">{{ exception2.length }} /{{ shopsTotal }}</span>
                  <span class="stats-percent"
                    >({{ ((exception2.length / shopsTotal) * 100).toFixed(1) }}%)</span
                  >
                </div>
                <div class="item-percent">异常数占比:{{ connectException }}%</div>
              </div>
              <hr class="item-divider" />
              <div class="item-shops">
                <el-scrollbar :height="scrollbarHeight">
                  <el-space wrap>
                    <ExceptionText
                      v-for="(item, index) in exception2"
                      :key="item"
                      :devId="item.devId"
                      exception-value="2"
                      :begin-time="beginTime"
                      :end-time="endTime"
                      @submit-exception-data="getAbnormalDataByClick"
                    >
                      {{ item.diName }}
                      <span v-if="index < exception2.length - 1" class="text-blank"></span>
                    </ExceptionText>
                  </el-space>
                </el-scrollbar>
              </div>
            </div>
          </el-col>
        </el-row>
      </el-card>
    </div>
      <el-table-column prop="devId" label="设备编号" align="center">
        <template #default="{ row }">
          <el-tooltip effect="dark" :content="row.devId">
            <div class="cell ellipsis">{{ row.devId }}</div>
          </el-tooltip>
        </template>
      </el-table-column>
    <!-- 异常数据表格 -->
    <div class="table-container">
      <el-collapse v-model="activeNames">
        <el-collapse-item name="1">
          <template #title>
            <div class="collapse-title">
              <h4 class="table-title">预警记录</h4>
            </div>
          </template>
          <el-card v-show="!isNoData">
            <el-table
              ref="tableH"
              v-loading="loading"
              :data="displayData"
              style="width: 100%"
              border
              :cell-class-name="tableCellClassName"
              :show-overflow-tooltip="true"
            >
              <el-table-column prop="diName" label="店铺名称" align="center">
                <!-- <template #default="{ row }">
                  <el-tooltip effect="dark" :content="row.diName">
                    <div class="cell ellipsis">{{ row.diName }}</div>
                  </el-tooltip>
                </template> -->
              </el-table-column>
              <el-table-column prop="devId" label="设备编号" align="center">
                <!-- <template #default="{ row }">
                  <el-tooltip effect="dark" :content="row.devId">
                    <div class="cell ellipsis">{{ row.devId }}</div>
                  </el-tooltip>
                </template> -->
              </el-table-column>
              <el-table-column prop="diSupplier" label="供应商" align="center">
                <!-- <template #default="{ row }">
                  <el-tooltip effect="dark" :content="row.diSupplier">
                    <div class="cell ellipsis">{{ row.diSupplier }}</div>
                  </el-tooltip>
                </template> -->
              </el-table-column>
              <el-table-column prop="exception" label="异常分类" align="center" width="90">
                <!-- <template #default="{ row }">
                  <el-tooltip effect="dark" :content="row.exception">
                    <div class="cell ellipsis">{{ row.exception }}</div>
                  </el-tooltip>
                </template> -->
              </el-table-column>
              <el-table-column label="异常类型" align="center" width="120">
                <template #default="{ row }">
                  <span v-if="row.exceptionType == '0'">油烟数据超标</span>
                  <span v-else-if="row.exceptionType == '1'">疑似供电异常</span>
                  <span v-else-if="row.exceptionType == '2'">掉线</span>
                </template>
              </el-table-column>
              <el-table-column prop="region" label="地区" align="center" width="80">
                <!-- <template #default="{ row }">
                  <el-tooltip effect="dark" :content="row.region">
                    <div class="cell ellipsis">{{ row.region }}</div>
                  </el-tooltip>
                </template> -->
              </el-table-column>
              <el-table-column prop="beginTime" label="开始时间" align="center">
                <!-- <template #default="{ row }">
                  <el-tooltip effect="dark" :content="row.beginTime">
                    <div class="cell ellipsis">{{ row.beginTime }}</div>
                  </el-tooltip>
                </template> -->
              </el-table-column>
              <el-table-column prop="endTime" label="结束时间" align="center">
                <!-- <template #default="{ row }">
                  <el-tooltip effect="dark" :content="row.endTime">
                    <div class="cell ellipsis">{{ row.endTime }}</div>
                  </el-tooltip>
                </template> -->
              </el-table-column>
              <el-table-column label="操作" align="center" width="120">
                <template #default="{ row }">
                  <el-button type="primary" size="small" @click="showDrawer(row)">查看</el-button>
                </template>
              </el-table-column>
            </el-table>
            <div class="pagination-container">
              <el-pagination
                ref="h4"
                @size-change="handleSizeChange"
                @current-change="handleCurrentChange"
                :total="total"
                :page-size="pageSize"
                layout="total, prev, pager, next, jumper"
              />
            </div>
          </el-card>
          <el-empty v-show="isNoData" :image-size="200" />
        </el-collapse-item>
      </el-collapse>
    </div>
      <el-table-column prop="diSupplier" label="供应商" align="center">
        <template #default="{ row }">
          <el-tooltip effect="dark" :content="row.diSupplier">
            <div class="cell ellipsis">{{ row.diSupplier }}</div>
          </el-tooltip>
        </template>
      </el-table-column>
      <el-table-column prop="exception" label="异常分类" align="center">
        <template #default="{ row }">
          <el-tooltip effect="dark" :content="row.exception">
            <div class="cell ellipsis">{{ row.exception }}</div>
          </el-tooltip>
        </template>
      </el-table-column>
      <el-table-column label="异常类型" align="center">
        <template #default="{ row }">
          <span v-if="row.exceptionType == '0'">油烟数据超标</span>
          <span v-else-if="row.exceptionType == '1'">疑似供电异常</span>
          <span v-else-if="row.exceptionType == '2'">掉线</span>
        </template>
      </el-table-column>
      <el-table-column prop="region" label="地区" align="center">
        <template #default="{ row }">
          <el-tooltip effect="dark" :content="row.region">
            <div class="cell ellipsis">{{ row.region }}</div>
          </el-tooltip>
        </template>
      </el-table-column>
      <el-table-column prop="beginTime" label="开始时间" align="center">
        <template #default="{ row }">
          <el-tooltip effect="dark" :content="row.beginTime">
            <div class="cell ellipsis">{{ row.beginTime }}</div>
          </el-tooltip>
        </template>
      </el-table-column>
      <el-table-column prop="endTime" label="结束时间" align="center">
        <template #default="{ row }">
          <el-tooltip effect="dark" :content="row.endTime">
            <div class="cell ellipsis">{{ row.endTime }}</div>
          </el-tooltip>
        </template>
      </el-table-column>
      <el-table-column label="操作" align="center">
        <template #default="{ row }">
          <el-button type="primary" class="table-button" @click="showDrawer(row)"
            >查看详情</el-button
          >
        </template>
      </el-table-column>
    </el-table>
    <el-pagination
      ref="h4"
      background
      @size-change="handleSizeChange"
      @current-change="handleCurrentChange"
      :total="total"
      :page-size="pageSize"
      layout="total,prev, pager, next, jumper"
    />
  </el-card>
  <el-empty v-show="isNoData" :image-size="200" />
  <!-- 对话框 -->
  <div>
    <el-dialog v-model="centerDialogVisible" draggable align-center>
      <template #header>
        <div style="font-size: 17px">
          店铺名:{{ rowShopName }}
          <span style="margin-left: 40px">异常类型:</span>
          <span v-if="rowExceptionType == '0'">油烟数据超标</span>
          <span v-else-if="rowExceptionType == '1'">供电异常</span>
          <span v-else-if="rowExceptionType == '2'">掉线</span>
          <div style="margin-top: 10px">
            异常时间段:{{ rowBeginTime }} ~
            {{ rowEndTime }}
    <!-- 对话框 -->
    <div>
      <el-dialog v-model="centerDialogVisible" draggable align-center class="detail-dialog">
        <template #header>
          <div class="dialog-header">
            <div class="dialog-title">
              <span>店铺名:{{ rowShopName }}</span>
              <span class="dialog-info"
                >异常类型:
                <span v-if="rowExceptionType == '0'">油烟数据超标</span>
                <span v-else-if="rowExceptionType == '1'">供电异常</span>
                <span v-else-if="rowExceptionType == '2'">掉线</span>
              </span>
              <div class="dialog-time">异常时间段:{{ rowBeginTime }} ~ {{ rowEndTime }}</div>
            </div>
            <div class="dialog-actions">
              <el-button
                type="primary"
                :loading="button.preButton"
                :disabled="isPreCantouch || banTouch"
                @click="getPreviousRowData"
                >上条异常</el-button
              >
              <el-button
                type="primary"
                :loading="button.afterButton"
                :disabled="isNextCantouch || banTouch"
                @click="getNextRowData"
                >下条异常</el-button
              >
            </div>
          </div>
        </template>
        <ExceptionTypeLineChart
          :option="option"
          :is-open-dialog="centerDialogVisible"
          v-loading="chartLoading"
        ></ExceptionTypeLineChart>
        <div class="dialog-table-container">
          <el-table :data="exceedingData" height="360" border style="margin-top: 20px">
            <el-table-column
              type="index"
              label="序号"
              width="60px"
              align="center"
              fixed
              :index="indexMethod"
            ></el-table-column>
            <el-table-column fixed prop="diName" label="店铺名称" show-overflow-tooltip />
            <el-table-column
              prop="mvStatCode"
              label="设备编号"
              align="center"
              show-overflow-tooltip
            />
            <el-table-column
              prop="diSupplier"
              label="供应商"
              align="center"
              show-overflow-tooltip
            />
            <el-table-column
              prop="mvDataTime"
              label="采集时间"
              align="center"
              show-overflow-tooltip
            />
            <el-table-column
              prop="mvFumeConcentration2"
              label="油烟浓度(mg/m³)"
              align="center"
              show-overflow-tooltip
            />
          </el-table>
        </div>
        <div class="dialog-button-position">
          <el-button
            type="danger"
            :loading="button.preButton"
            :disabled="isPreCantouch || banTouch"
            @click="getPreviousRowData"
            >上条异常</el-button
          >
          <el-button
            type="danger"
            :loading="button.afterButton"
            :disabled="isNextCantouch || banTouch"
            @click="getNextRowData"
            >下条异常</el-button
          >
        <div class="dialog-footer">
          <el-tag type="success" effect="dark" round
            ><span v-show="rowExceptionType == '0'">异常记录:</span>
            <span v-show="rowExceptionType == '1' || rowExceptionType == '2'">缺失数据:</span>
            <span class="table-line-num">{{ exceptionTotal }}条</span>
            <span v-show="rowExceptionType === '1' || rowExceptionType === '2'"> (逻辑计算)</span>
          </el-tag>
        </div>
      </template>
      <!-- 超标数据时 -->
      <!-- 折线图 -->
      <!-- 掉线 -->
      <!-- <div
          ref="ref"
          v-show="isOfflineShow"
          style="
            width: 100%;
            height: 300px;
            /* min-width: 100px; */
            margin-bottom: 20px;
            margin-left: 10px;
            min-width: 350px;
          "
        ></div> -->
      <ExceptionTypeLineChart
        :option="option"
        :is-open-dialog="centerDialogVisible"
        v-loading="chartLoading"
      ></ExceptionTypeLineChart>
      <!--  -->
      <div style="margin-top: 40px; margin-bottom: 5px; border: 1px">
        <el-table :data="exceedingData" height="360" border style="margin-top: 25px">
          <el-table-column
            type="index"
            label="序号"
            width="60px"
            align="center"
            fixed
            :index="indexMethod"
          ></el-table-column>
          <el-table-column fixed prop="diName" label="店铺名称" show-overflow-tooltip />
          <el-table-column
            prop="mvStatCode"
            label="设备编号"
            align="center"
            show-overflow-tooltip
          />
          <el-table-column prop="diSupplier" label="供应商" align="center" show-overflow-tooltip />
          <el-table-column
            prop="mvDataTime"
            label="采集时间"
            align="center"
            show-overflow-tooltip
          />
          <el-table-column
            prop="mvFumeConcentration2"
            label="油烟浓度(mg/m³)"
            align="center"
            show-overflow-tooltip
          />
        </el-table>
      </div>
      <el-tag type="success" class="mx-1" effect="dark" round
        ><span class="table-line-lable" v-show="rowExceptionType == '0'">异常记录: </span>
        <span v-show="rowExceptionType == '1' || rowExceptionType == '2'">缺失数据:</span>
        <span class="table-line-num">{{ exceptionTotal }}条</span>
        <span v-show="rowExceptionType === '1' || rowExceptionType === '2'"> (逻辑计算)</span>
      </el-tag>
    </el-dialog>
      </el-dialog>
    </div>
  </div>
</template>
<script>
import { defineAsyncComponent } from 'vue'
import { ElMessage } from 'element-plus'
import ExceptionType from '@/sfc/ExceptionType.vue'
import TimeSelect from '@/sfc/TimeSelect.vue'
import ExceptionText from '@/sfc/ExceptionText.vue'
@@ -486,7 +465,11 @@
      selectedRowIndex: -1,
      // 默认选择的折叠面板编号
      activeNames: ['1'],
      activeNames: [],
      // 搜索区域折叠状态
      activeSearchNames: [],
      // 搜索区域是否展开
      isSearchExpanded: false,
      // 异常时的表格
      abnormalTb: [],
      // 异常的起止时间
@@ -500,6 +483,8 @@
      exception1: [],
      // 保存着异常类型2对应的店铺名称和设备编号
      exception2: [],
      // 异常店铺滚动区域高度
      scrollbarHeight: 250,
      // 加载动画
      loading: false,
      // 抽屉加载动画
@@ -572,7 +557,6 @@
        this.isNextCantouch = false
      }
    },
    // 当选择的时间发生变化时,异常分析部分的异常店铺数量同步变化
    beginTime() {
      this.getShopNames()
@@ -611,8 +595,39 @@
    window.addEventListener('resize', this.updateChart)
  },
  methods: {
    // 处理搜索区域折叠变化
    handleSearchCollapseChange(val) {
      this.isSearchExpanded = val.length > 0
    },
    // 获取搜索条件摘要
    getSearchSummary() {
      let summary =
        '时间: ' +
        (this.beginTime ? this.beginTime.substring(0, 10) : '全部') +
        ' 至 ' +
        (this.endTime ? this.endTime.substring(0, 10) : '全部')
      summary +=
        ' | 店铺: ' +
        (this.deviceId[1]
          ? this.deviceInfo.find((item) => item.diCode === this.deviceId[1])?.diName || '已选择'
          : '全部')
      if (this.exceptionValue && this.exceptionValue.length > 0) {
        const exceptionTypes = {
          0: '油烟浓度超标',
          1: '供电异常',
          2: '设备或网络异常',
        }
        const selectedTypes = this.exceptionValue
          .map((val) => exceptionTypes[val] || val)
          .join(', ')
        summary += ' | 异常类型: ' + selectedTypes
      } else {
        summary += ' | 异常类型: 全部'
      }
      return summary
    },
    // 功能:对话框表格序号递增
    // 时间:2023-8-17
    // 时间:2025-8-17
    indexMethod(index) {
      return index + 1
    },
@@ -632,7 +647,7 @@
    //功能: 动态计算表格高度
    calcTableHeight() {
      const h1 = this.$refs.h1.$el.offsetHeight
      const h1 = this.$refs.h1.offsetHeight
      const h2 = this.$refs.h4.$el.offsetHeight
      this.tableHeight = `calc(100vh - ${h1}px - ${h2}px - 45px - var(--el-main-padding) * 2 - var(--el-card-padding))`
    },
@@ -924,6 +939,9 @@
        // 移除空数据状态
        this.isNoData = false
        this.handleCurrentChange(1)
        // 点击查询后折叠搜索区域
        this.activeSearchNames = []
        this.isSearchExpanded = false
      })
    },
    handleSizeChange(val) {
@@ -1429,6 +1447,15 @@
      this.total = this.abnormalData.length
      // 默认显示第一页
      this.handleCurrentChange(1)
      this.activeNames = ['1']
      // 滚动到异常数据表格位置
      this.$nextTick(() => {
        if (this.$refs.tableH) {
          setTimeout(() => {
            this.$refs.tableH.$el.scrollIntoView({ behavior: 'smooth' })
          }, 200)
        }
      })
    },
    // 根据异常类型返回店铺名称和设备编号
@@ -1530,12 +1557,253 @@
</script>
<style scoped>
.header-container {
  display: flex;
  margin-left: 20px;
  /* flex-wrap: wrap;
    align-items: center; */
/* 全局容器 */
.data-exception-container {
  padding: 20px;
  background-color: #f5f7fa;
  min-height: 100vh;
}
/* 搜索区域 */
.search-container {
  background-color: white;
  border-radius: 8px;
  padding: 20px;
  margin-bottom: 20px;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
}
.search-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  width: 100%;
}
.search-header h3 {
  margin: 0;
  font-size: 16px;
  font-weight: 600;
  color: #333;
}
.search-summary {
  font-size: 14px;
  color: #666;
  flex: 1;
  margin-left: 20px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.search-form {
  display: flex;
  flex-direction: column;
  gap: 16px;
  flex: 1;
}
.form-row {
  display: flex;
  align-items: flex-start;
  gap: 16px;
  flex-wrap: wrap;
}
.form-item {
  display: flex;
  align-items: center;
  gap: 8px;
  flex: 1;
  min-width: 200px;
}
.form-item.full-width {
  flex: 100%;
}
.form-label {
  font-weight: bolder;
  white-space: nowrap;
}
.form-actions {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: 12px;
}
.summary-info {
  text-align: right;
  font-size: 14px;
  color: #999;
  margin-top: 8px;
}
/* 异常分析 */
.analysis-container {
  background-color: white;
  border-radius: 8px;
  padding: 20px;
  margin-bottom: 20px;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
}
.collapse-title {
  display: flex;
  align-items: center;
  gap: 8px;
}
.collapse-header {
  margin: 0;
  font-size: 16px;
  font-weight: 600;
  color: #333;
}
.header-icon {
  color: #1890ff;
}
.analysis-card {
  border-radius: 8px;
  overflow: hidden;
}
.analysis-item {
  display: flex;
  flex-direction: column;
}
.item-header {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 12px;
}
.item-icon {
  width: 24px;
  height: 24px;
}
.item-title {
  font-size: 14px;
  font-weight: 600;
  color: #333;
}
.item-content {
  flex: 1;
  margin-bottom: 12px;
}
.item-stats {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 4px;
}
.stats-label {
  font-size: 13px;
  color: #666;
}
.stats-value {
  font-size: 18px;
  font-weight: 600;
  color: #333;
}
.stats-percent {
  font-size: 13px;
  color: #999;
}
.item-percent {
  font-size: 13px;
  color: #666;
  margin-top: 4px;
}
.item-divider {
  margin: 10px 0;
  border: 0.5px solid #f0f0f0;
}
.item-shops {
  flex: 1;
}
/* 表格区域 */
.table-container {
  background-color: white;
  border-radius: 8px;
  padding: 20px;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
}
.table-title {
  margin: 0 0 16px 0;
  font-size: 16px;
  font-weight: 600;
  color: #333;
}
.pagination-container {
  margin-top: 16px;
  display: flex;
  justify-content: flex-end;
}
/* 对话框 */
.detail-dialog {
  border-radius: 8px;
  overflow: hidden;
}
.dialog-header {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  width: 100%;
}
.dialog-title {
  font-size: 16px;
  color: #333;
}
.dialog-info {
  margin-left: 24px;
  color: #666;
}
.dialog-time {
  margin-top: 8px;
  font-size: 14px;
  color: #666;
}
.dialog-actions {
  display: flex;
  gap: 8px;
}
.dialog-table-container {
  margin-top: 20px;
}
.dialog-footer {
  margin-top: 20px;
  text-align: right;
}
/* 通用样式 */
.ellipsis {
  white-space: nowrap;
  overflow: hidden;
@@ -1543,148 +1811,127 @@
}
.iconExcel {
  font-size: 25px;
  margin-left: 20px;
  bottom: -6px;
  font-size: 20px;
  cursor: pointer;
  color: #1890ff;
}
/* 可鼠标箭头变为可点击状态 */
.clickable {
  cursor: pointer;
}
.card-header {
  margin: 0;
}
body {
  margin: 0;
}
.exception-divider-rowline {
  margin: 10px 0px;
}
/* 异常分析数据与按钮 */
.exception-container {
  display: flex;
}
.example-showcase .el-loading-mask {
  z-index: 9;
}
.scrollbar-demo-item {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 20px;
  margin: 10px;
  text-align: center;
  border-radius: 4px;
  background: var(--el-color-primary-light-9);
  color: var(--el-color-primary);
}
.collapse-header {
  margin-left: 5px;
  font-size: 18px;
}
.collapse-header-text {
  margin-top: 5px;
  font-size: 14px;
  color: gray;
}
.box-card-label {
  font-size: 14px;
  white-space: nowrap;
}
.right-text {
  /* float :right; */
  /* text-align: right; */
  margin-left: 80px;
}
:deep().el-card {
  border-radius: 9px;
}
/* ‘查看详情’ 的弹出框高度调整 */
:deep().el-dialog {
  height: 98%;
  /* 不出现滚动条 */
  overflow-y: hidden;
  border-radius: 9px;
}
.table-page {
  margin-left: 20px;
}
.table-text {
  font-size: 18px;
  margin: 5px 0px 10px 20px;
}
.text-blank {
  margin-right: 10px;
  color: #000000;
}
/* 店铺名选择文本 */
.describe-info {
  margin-top: 5px;
  font-weight: bold;
  white-space: nowrap;
}
/* 时间选择文本 */
.describe-time-text {
  margin-left: 30px;
  margin-top: 5px;
  font-weight: bold;
}
/* 异常表格下标签中的数组 */
.table-line-num {
  font-weight: bold;
  color: black;
}
.button_info.el-button_inner {
  text-align: left;
/* 表格行样式 */
:deep().el-table__row .exceeding-row {
  background-color: #fff1f0;
  color: #cf1322;
}
:deep().el-table__row .abnormal-power-supply {
  background-color: #fffbe6;
  color: #d48806;
}
:deep().el-table__row .disconnect {
  background-color: #e6f7ff;
  color: #1890ff;
}
/* 表格样式 */
:deep().el-table {
  border-radius: 8px;
  overflow: hidden;
}
:deep().el-table th {
  background-color: #fafafa;
  font-weight: 600;
}
/* 按钮样式 */
:deep().el-button--primary {
  background-color: #1890ff;
  border-color: #1890ff;
}
:deep().el-button--primary:hover {
  background-color: #40a9ff;
  border-color: #40a9ff;
}
/* 卡片样式 */
:deep().el-card {
  border-radius: 8px;
  border: 1px solid #f0f0f0;
}
/* 响应式调整 */
@media (max-width: 1200px) {
  .search-form {
    flex-direction: column;
    align-items: flex-start;
  }
  .form-actions {
    margin-left: 0;
    margin-top: 12px;
  }
}
/* 原有样式兼容 */
.header-container {
  display: flex;
  margin-left: 0;
  flex-wrap: wrap;
  align-items: center;
  gap: 16px;
}
.describe-info {
  margin-top: 0;
  font-weight: 500;
  white-space: nowrap;
  color: #666;
}
.table-page {
  margin-left: 0;
}
.table-text {
  font-size: 16px;
  margin: 0 0 16px 0;
  font-weight: 600;
  color: #333;
}
.el-collapse {
  margin-left: 20px;
  margin-left: 0;
}
:deep().el-collapse .el-collapse-item__content {
  padding-bottom: 0px;
}
.box-card {
  height: 190px;
  height: auto;
  min-height: 190px;
}
.sub-box-card {
  height: 100px;
  height: auto;
  min-height: 100px;
  border: 0px;
}
.mx-1 {
  margin-bottom: 0px;
}
.dialog-button-position {
  display: flex;
  justify-content: right;
  margin-bottom: 10px;
}
:deep().el-table__row .exceeding-row {
  background-color: #f53f3f;
}
:deep().el-table__row .abnormal-power-supply {
  background-color: #fdf4bf;
}
:deep().el-table__row .disconnect {
  background-color: #f7ba1e;
}
.el-table {
  color: #000000;
}
/* 表格中的按钮宽度铺满 */
.table-button {
  width: 100%;
}
</style>