<template> 
 | 
  <div class="app-container"> 
 | 
    <!-- 搜索表单 --> 
 | 
    <div class="search_form"> 
 | 
      <el-form :model="searchForm" :inline="true"> 
 | 
        <el-form-item label="储气罐名称:"> 
 | 
          <el-input v-model="searchForm.tankName" placeholder="请输入储气罐名称" clearable style="width: 200px" /> 
 | 
        </el-form-item> 
 | 
        <el-form-item label="储气罐类型:"> 
 | 
          <el-select v-model="searchForm.tankType" placeholder="请选择储气罐类型" clearable style="width: 200px"> 
 | 
            <el-option label="液化气储罐" value="液化气储罐" /> 
 | 
            <el-option label="压缩气储罐" value="压缩气储罐" /> 
 | 
            <el-option label="天然气储罐" value="天然气储罐" /> 
 | 
            <el-option label="氧气储罐" value="氧气储罐" /> 
 | 
          </el-select> 
 | 
        </el-form-item> 
 | 
        <el-form-item label="预警类型:"> 
 | 
          <el-select v-model="searchForm.warningType" placeholder="请选择预警类型" clearable style="width: 200px"> 
 | 
            <el-option label="气体不足" value="气体不足" /> 
 | 
            <el-option label="压力异常" value="压力异常" /> 
 | 
            <el-option label="温度异常" value="温度异常" /> 
 | 
            <el-option label="泄漏预警" value="泄漏预警" /> 
 | 
          </el-select> 
 | 
        </el-form-item> 
 | 
        <el-form-item label="预警级别:"> 
 | 
          <el-select v-model="searchForm.warningLevel" placeholder="请选择预警级别" clearable style="width: 200px"> 
 | 
            <el-option label="紧急" value="紧急" /> 
 | 
            <el-option label="重要" value="重要" /> 
 | 
            <el-option label="一般" value="一般" /> 
 | 
          </el-select> 
 | 
        </el-form-item> 
 | 
        <el-form-item> 
 | 
          <el-button type="primary" @click="handleQuery">搜索</el-button> 
 | 
          <el-button @click="resetQuery">重置</el-button> 
 | 
        </el-form-item> 
 | 
      </el-form> 
 | 
    </div> 
 | 
  
 | 
    <!-- 数据表格 --> 
 | 
    <div class="table_list"> 
 | 
      <!-- 操作按钮 --> 
 | 
      <div class="table-operations"> 
 | 
        <el-button type="primary" @click="handleAdd">新增预警规则</el-button> 
 | 
        <!-- <el-button type="success" @click="handleBatchProcess">批量处理@</el-button> --> 
 | 
        <el-button @click="handleExport">导出</el-button> 
 | 
      </div> 
 | 
      <el-table 
 | 
        :data="tableData" 
 | 
        border 
 | 
        v-loading="tableLoading" 
 | 
        @selection-change="handleSelectionChange" 
 | 
        style="width: 100%" 
 | 
        height="calc(100vh - 280px)" 
 | 
      > 
 | 
        <el-table-column align="center" type="selection" width="55" /> 
 | 
        <el-table-column align="center" label="序号" type="index" width="60" /> 
 | 
  
 | 
        <!-- 基础信息字段 --> 
 | 
        <el-table-column label="储气罐编码" prop="tankCode" width="120" show-overflow-tooltip /> 
 | 
        <el-table-column label="储气罐名称" prop="tankName" width="200" show-overflow-tooltip /> 
 | 
        <el-table-column label="储气罐类型" prop="tankType" width="120" show-overflow-tooltip /> 
 | 
        <el-table-column label="规格型号" prop="specificationModel" width="150" show-overflow-tooltip /> 
 | 
        <el-table-column label="容积(m³)" prop="volume" width="100" show-overflow-tooltip /> 
 | 
  
 | 
        <!-- 库存相关字段 --> 
 | 
        <el-table-column label="当前气体量" prop="currentGasLevel" width="120" show-overflow-tooltip> 
 | 
          <template #default="scope"> 
 | 
            <span :class="getGasLevelClass(scope.row)">{{ scope.row.currentGasLevel }}%</span> 
 | 
          </template> 
 | 
        </el-table-column> 
 | 
        <el-table-column label="安全气体量" prop="safetyGasLevel" width="120" show-overflow-tooltip /> 
 | 
        <el-table-column label="最低气体量" prop="minGasLevel" width="120" show-overflow-tooltip /> 
 | 
        <el-table-column label="最高气体量" prop="maxGasLevel" width="120" show-overflow-tooltip /> 
 | 
        <el-table-column label="当前压力(MPa)" prop="currentPressure" width="140" show-overflow-tooltip /> 
 | 
  
 | 
        <!-- 预警规则字段 --> 
 | 
        <el-table-column label="预警类型" prop="warningType" width="100" show-overflow-tooltip> 
 | 
          <template #default="scope"> 
 | 
            <el-tag :type="getWarningTypeTag(scope.row.warningType)"> 
 | 
              {{ scope.row.warningType }} 
 | 
            </el-tag> 
 | 
          </template> 
 | 
        </el-table-column> 
 | 
        <el-table-column label="预警级别" prop="warningLevel" width="100" show-overflow-tooltip> 
 | 
          <template #default="scope"> 
 | 
            <el-tag :type="getWarningLevelTag(scope.row.warningLevel)"> 
 | 
              {{ scope.row.warningLevel }} 
 | 
            </el-tag> 
 | 
          </template> 
 | 
        </el-table-column> 
 | 
        <el-table-column label="预警阈值" prop="warningThreshold" width="100" show-overflow-tooltip /> 
 | 
        <el-table-column label="是否启用" prop="isEnabled" width="100" show-overflow-tooltip> 
 | 
          <template #default="scope"> 
 | 
            <el-switch v-model="scope.row.isEnabled" @change="handleEnableChange(scope.row)" /> 
 | 
          </template> 
 | 
        </el-table-column> 
 | 
  
 | 
        <!-- 时间相关字段 --> 
 | 
        <el-table-column label="预警时间" prop="warningTime" width="150" show-overflow-tooltip /> 
 | 
        <el-table-column label="预警持续天数" prop="warningDuration" width="120" show-overflow-tooltip /> 
 | 
        <el-table-column label="最后更新时间" prop="lastUpdateTime" width="150" show-overflow-tooltip /> 
 | 
        <el-table-column label="预计充装时间" prop="expectedRefillTime" width="150" show-overflow-tooltip /> 
 | 
        <el-table-column label="预计缺气时间" prop="expectedShortageTime" width="150" show-overflow-tooltip> 
 | 
          <template #default="scope"> 
 | 
            <div v-if="scope.row.expectedShortageTime"> 
 | 
              <div v-if="getCountdown(scope.row.expectedShortageTime).isExpired" class="countdown-expired"> 
 | 
                <el-tag type="danger">已缺气</el-tag> 
 | 
              </div> 
 | 
              <div v-else class="countdown-timer"> 
 | 
                <span :class="getCountdownClass(scope.row.expectedShortageTime)"> 
 | 
                  {{ getCountdown(scope.row.expectedShortageTime).text }} 
 | 
                </span> 
 | 
              </div> 
 | 
            </div> 
 | 
            <span v-else>-</span> 
 | 
          </template> 
 | 
        </el-table-column> 
 | 
  
 | 
        <!-- 操作列 --> 
 | 
        <el-table-column fixed="right" label="操作" width="200" align="center"> 
 | 
          <template #default="scope"> 
 | 
            <el-button link type="primary" size="small" @click="handleEdit(scope.row)">编辑</el-button> 
 | 
<!--            <el-button link type="success" size="small" @click="handleProcess(scope.row)">处理@</el-button>--> 
 | 
            <el-button link type="danger" size="small" @click="handleDelete(scope.row)">删除</el-button> 
 | 
          </template> 
 | 
        </el-table-column> 
 | 
      </el-table> 
 | 
  
 | 
      <!-- 分页 --> 
 | 
      <pagination 
 | 
        v-show="total > 0" 
 | 
        :total="total" 
 | 
        layout="total, sizes, prev, pager, next, jumper" 
 | 
        :page="page.current" 
 | 
        :limit="page.size" 
 | 
        @pagination="paginationChange" 
 | 
      /> 
 | 
    </div> 
 | 
  
 | 
    <!-- 新增/编辑预警规则弹窗 --> 
 | 
    <el-dialog 
 | 
      v-model="dialogFormVisible" 
 | 
      :title="operationType === 'add' ? '新增预警规则' : '编辑预警规则'" 
 | 
      width="50%" 
 | 
      @close="closeDialog" 
 | 
    > 
 | 
      <el-form :model="form" :rules="rules" ref="formRef" label-width="140px"> 
 | 
        <el-row :gutter="20"> 
 | 
          <!-- 基础信息 --> 
 | 
          <el-col :span="12"> 
 | 
            <el-form-item label="储气罐编码:" prop="tankCode"> 
 | 
              <el-input v-model="form.tankCode" placeholder="请输入储气罐编码" /> 
 | 
            </el-form-item> 
 | 
          </el-col> 
 | 
          <el-col :span="12"> 
 | 
            <el-form-item label="储气罐名称:" prop="tankName"> 
 | 
              <el-input v-model="form.tankName" placeholder="请输入储气罐名称" /> 
 | 
            </el-form-item> 
 | 
          </el-col> 
 | 
        </el-row> 
 | 
  
 | 
        <el-row :gutter="20"> 
 | 
          <el-col :span="12"> 
 | 
            <el-form-item label="储气罐类型:" prop="tankType"> 
 | 
              <el-select v-model="form.tankType" placeholder="请选择储气罐类型" style="width: 100%"> 
 | 
                <el-option label="液化气储罐" value="液化气储罐" /> 
 | 
                <el-option label="压缩气储罐" value="压缩气储罐" /> 
 | 
                <el-option label="天然气储罐" value="天然气储罐" /> 
 | 
                <el-option label="氧气储罐" value="氧气储罐" /> 
 | 
              </el-select> 
 | 
            </el-form-item> 
 | 
          </el-col> 
 | 
          <el-col :span="12"> 
 | 
            <el-form-item label="规格型号:" prop="specificationModel"> 
 | 
              <el-input v-model="form.specificationModel" placeholder="请输入规格型号" /> 
 | 
            </el-form-item> 
 | 
          </el-col> 
 | 
        </el-row> 
 | 
  
 | 
        <el-row :gutter="20"> 
 | 
          <el-col :span="12"> 
 | 
            <el-form-item label="容积(m³):" prop="volume"> 
 | 
              <el-input-number v-model="form.volume" :min="0" :precision="2" style="width: 100%" /> 
 | 
            </el-form-item> 
 | 
          </el-col> 
 | 
          <el-col :span="12"> 
 | 
            <el-form-item label="当前气体量(%):" prop="currentGasLevel"> 
 | 
              <el-input-number v-model="form.currentGasLevel" :min="0" :max="100" :precision="1" style="width: 100%" /> 
 | 
            </el-form-item> 
 | 
          </el-col> 
 | 
        </el-row> 
 | 
  
 | 
        <!-- 库存相关 --> 
 | 
        <el-row :gutter="20"> 
 | 
          <el-col :span="12"> 
 | 
            <el-form-item label="安全气体量(%):" prop="safetyGasLevel"> 
 | 
              <el-input-number v-model="form.safetyGasLevel" :min="0" :max="100" :precision="1" style="width: 100%" /> 
 | 
            </el-form-item> 
 | 
          </el-col> 
 | 
          <el-col :span="12"> 
 | 
            <el-form-item label="最低气体量(%):" prop="minGasLevel"> 
 | 
              <el-input-number v-model="form.minGasLevel" :min="0" :max="100" :precision="1" style="width: 100%" /> 
 | 
            </el-form-item> 
 | 
          </el-col> 
 | 
        </el-row> 
 | 
  
 | 
        <el-row :gutter="20"> 
 | 
          <el-col :span="12"> 
 | 
            <el-form-item label="最高气体量(%):" prop="maxGasLevel"> 
 | 
              <el-input-number v-model="form.maxGasLevel" :min="0" :max="100" :precision="1" style="width: 100%" /> 
 | 
            </el-form-item> 
 | 
          </el-col> 
 | 
          <el-col :span="12"> 
 | 
            <el-form-item label="当前压力(MPa):" prop="currentPressure"> 
 | 
              <el-input-number v-model="form.currentPressure" :min="0" :precision="2" style="width: 100%" /> 
 | 
            </el-form-item> 
 | 
          </el-col> 
 | 
        </el-row> 
 | 
  
 | 
        <!-- 预警规则 --> 
 | 
        <el-row :gutter="20"> 
 | 
          <el-col :span="12"> 
 | 
            <el-form-item label="预警类型:" prop="warningType"> 
 | 
              <el-select v-model="form.warningType" placeholder="请选择预警类型" style="width: 100%"> 
 | 
                <el-option label="气体不足" value="气体不足" /> 
 | 
                <el-option label="压力异常" value="压力异常" /> 
 | 
                <el-option label="温度异常" value="温度异常" /> 
 | 
                <el-option label="泄漏预警" value="泄漏预警" /> 
 | 
              </el-select> 
 | 
            </el-form-item> 
 | 
          </el-col> 
 | 
          <el-col :span="12"> 
 | 
            <el-form-item label="预警级别:" prop="warningLevel"> 
 | 
              <el-select v-model="form.warningLevel" placeholder="请选择预警级别" style="width: 100%"> 
 | 
                <el-option label="紧急" value="紧急" /> 
 | 
                <el-option label="重要" value="重要" /> 
 | 
                <el-option label="一般" value="一般" /> 
 | 
              </el-select> 
 | 
            </el-form-item> 
 | 
          </el-col> 
 | 
        </el-row> 
 | 
  
 | 
        <el-row :gutter="20"> 
 | 
          <el-col :span="12"> 
 | 
            <el-form-item label="预警阈值:" prop="warningThreshold"> 
 | 
              <el-input-number v-model="form.warningThreshold" :min="0" :precision="2" style="width: 100%" /> 
 | 
            </el-form-item> 
 | 
          </el-col> 
 | 
          <el-col :span="12"> 
 | 
            <el-form-item label="是否启用:" prop="isEnabled"> 
 | 
              <el-switch v-model="form.isEnabled" /> 
 | 
            </el-form-item> 
 | 
          </el-col> 
 | 
        </el-row> 
 | 
  
 | 
        <!-- 时间相关 --> 
 | 
        <el-row :gutter="20"> 
 | 
          <el-col :span="12"> 
 | 
            <el-form-item label="预警时间:" prop="warningTime"> 
 | 
              <el-date-picker 
 | 
                v-model="form.warningTime" 
 | 
                type="datetime" 
 | 
                placeholder="请选择预警时间" 
 | 
                style="width: 100%" 
 | 
                value-format="YYYY-MM-DD HH:mm:ss" 
 | 
              /> 
 | 
            </el-form-item> 
 | 
          </el-col> 
 | 
          <el-col :span="12"> 
 | 
            <el-form-item label="预计充装时间:" prop="expectedRefillTime"> 
 | 
              <el-date-picker 
 | 
                v-model="form.expectedRefillTime" 
 | 
                type="datetime" 
 | 
                placeholder="请选择预计充装时间" 
 | 
                style="width: 100%" 
 | 
                value-format="YYYY-MM-DD HH:mm:ss" 
 | 
              /> 
 | 
            </el-form-item> 
 | 
          </el-col> 
 | 
        </el-row> 
 | 
  
 | 
        <el-row :gutter="20"> 
 | 
          <el-col :span="12"> 
 | 
            <el-form-item label="预计缺气时间:" prop="expectedShortageTime"> 
 | 
              <el-date-picker 
 | 
                v-model="form.expectedShortageTime" 
 | 
                type="datetime" 
 | 
                placeholder="请选择预计缺气时间" 
 | 
                style="width: 100%" 
 | 
                value-format="YYYY-MM-DD HH:mm:ss" 
 | 
              /> 
 | 
            </el-form-item> 
 | 
          </el-col> 
 | 
          <el-col :span="12"> 
 | 
            <el-form-item label="预警规则描述:" prop="warningRule"> 
 | 
              <el-input 
 | 
                v-model="form.warningRule" 
 | 
                type="textarea" 
 | 
                :rows="3" 
 | 
                placeholder="请输入预警规则描述" 
 | 
              /> 
 | 
            </el-form-item> 
 | 
          </el-col> 
 | 
        </el-row> 
 | 
      </el-form> 
 | 
  
 | 
      <template #footer> 
 | 
        <div class="dialog-footer"> 
 | 
          <el-button @click="closeDialog">取消</el-button> 
 | 
          <el-button type="primary" @click="submitForm">确认</el-button> 
 | 
        </div> 
 | 
      </template> 
 | 
    </el-dialog> 
 | 
  
 | 
    <!-- 缺气预警弹框 --> 
 | 
    <el-dialog 
 | 
      v-model="shortageWarningVisible" 
 | 
      title="⚠️ 缺气预警" 
 | 
      width="400px" 
 | 
      :close-on-click-modal="false" 
 | 
      :close-on-press-escape="false" 
 | 
      :show-close="false" 
 | 
    > 
 | 
      <div class="shortage-warning-content"> 
 | 
        <div class="warning-icon"> 
 | 
          <el-icon size="48" color="#f56c6c"><WarningFilled /></el-icon> 
 | 
        </div> 
 | 
        <div class="warning-message"> 
 | 
          <h3>{{ currentWarningTank.tankName }}</h3> 
 | 
          <p>储气罐已缺气,请及时处理!</p> 
 | 
          <p class="warning-details"> 
 | 
            储气罐编码:{{ currentWarningTank.tankCode }}<br> 
 | 
            储气罐类型:{{ currentWarningTank.tankType }}<br> 
 | 
            当前气体量:{{ currentWarningTank.currentGasLevel }}% 
 | 
          </p> 
 | 
        </div> 
 | 
      </div> 
 | 
      <template #footer> 
 | 
        <div class="dialog-footer"> 
 | 
          <el-button type="primary" @click="handleShortageWarning">立即处理</el-button> 
 | 
          <el-button @click="closeShortageWarning">稍后处理</el-button> 
 | 
        </div> 
 | 
      </template> 
 | 
    </el-dialog> 
 | 
  
 | 
    <!-- 缺气预警弹框 --> 
 | 
    <el-dialog 
 | 
      v-model="shortageWarningVisible" 
 | 
      title="⚠️ 缺气预警" 
 | 
      width="400px" 
 | 
      :close-on-click-modal="false" 
 | 
      :close-on-press-escape="false" 
 | 
      :show-close="false" 
 | 
    > 
 | 
      <div class="shortage-warning-content"> 
 | 
        <div class="warning-icon"> 
 | 
          <el-icon size="48" color="#f56c6c"><WarningFilled /></el-icon> 
 | 
        </div> 
 | 
        <div class="warning-message"> 
 | 
          <h3>{{ currentWarningTank.tankName }}</h3> 
 | 
          <p>储气罐已缺气,请及时处理!</p> 
 | 
          <p class="warning-details"> 
 | 
            储气罐编码:{{ currentWarningTank.tankCode }}<br> 
 | 
            储气罐类型:{{ currentWarningTank.tankType }}<br> 
 | 
            当前气体量:{{ currentWarningTank.currentGasLevel }}% 
 | 
          </p> 
 | 
        </div> 
 | 
      </div> 
 | 
      <template #footer> 
 | 
        <div class="dialog-footer"> 
 | 
          <el-button type="primary" @click="handleShortageWarning">立即处理</el-button> 
 | 
          <el-button @click="closeShortageWarning">稍后处理</el-button> 
 | 
        </div> 
 | 
      </template> 
 | 
    </el-dialog> 
 | 
  </div> 
 | 
</template> 
 | 
  
 | 
<script setup> 
 | 
import { ref, reactive, onMounted, onUnmounted } from 'vue' 
 | 
import { ElMessage, ElMessageBox } from 'element-plus' 
 | 
import { WarningFilled } from '@element-plus/icons-vue' 
 | 
import pagination from '@/components/PIMTable/Pagination.vue' 
 | 
// 注释掉API导入,使用假数据 
 | 
import { 
 | 
  getStockWarningPage, 
 | 
  addStockWarning, 
 | 
  updateStockWarning, 
 | 
  deleteStockWarning, 
 | 
  batchProcessStockWarning, 
 | 
  exportStockWarning, 
 | 
  toggleStockWarningStatus 
 | 
} from '@/api/inventoryManagement/stockWarning.js' 
 | 
  
 | 
const { proxy } = getCurrentInstance() 
 | 
  
 | 
// 响应式数据 
 | 
const tableData = ref([]) 
 | 
const tableLoading = ref(false) 
 | 
const selectedRows = ref([]) 
 | 
const dialogFormVisible = ref(false) 
 | 
const operationType = ref('add') 
 | 
const total = ref(0) 
 | 
  
 | 
// 缺气预警相关 
 | 
const shortageWarningVisible = ref(false) 
 | 
const currentWarningTank = ref({}) 
 | 
const countdownTimer = ref(null) 
 | 
  
 | 
// 分页参数 
 | 
const page = reactive({ 
 | 
  current: 1, 
 | 
  size: 10, 
 | 
  total: 0 
 | 
}) 
 | 
  
 | 
// 搜索表单 
 | 
const searchForm = reactive({ 
 | 
  tankName: '', 
 | 
  tankType: '', 
 | 
  warningType: '', 
 | 
  warningLevel: '' 
 | 
}) 
 | 
  
 | 
// 表单数据 
 | 
const form = reactive({ 
 | 
  id: null, 
 | 
  tankCode: '', 
 | 
  tankName: '', 
 | 
  tankType: '', 
 | 
  specificationModel: '', 
 | 
  volume: 0, 
 | 
  currentGasLevel: 0, 
 | 
  safetyGasLevel: 0, 
 | 
  minGasLevel: 0, 
 | 
  maxGasLevel: 0, 
 | 
  currentPressure: 0, 
 | 
  warningType: '', 
 | 
  warningLevel: '', 
 | 
  warningThreshold: 0, 
 | 
  isEnabled: true, 
 | 
  warningTime: '', 
 | 
  warningDuration: 0, 
 | 
  lastUpdateTime: '', 
 | 
  expectedRefillTime: '', 
 | 
  expectedShortageTime: '', 
 | 
  warningRule: '' 
 | 
}) 
 | 
  
 | 
// 表单验证规则 
 | 
const rules = { 
 | 
  tankCode: [{ required: true, message: '请输入储气罐编码', trigger: 'blur' }], 
 | 
  tankName: [{ required: true, message: '请输入储气罐名称', trigger: 'blur' }], 
 | 
  tankType: [{ required: true, message: '请选择储气罐类型', trigger: 'change' }], 
 | 
  warningType: [{ required: true, message: '请选择预警类型', trigger: 'change' }], 
 | 
  warningLevel: [{ required: true, message: '请选择预警级别', trigger: 'change' }], 
 | 
  warningThreshold: [{ required: true, message: '请输入预警阈值', trigger: 'blur' }] 
 | 
} 
 | 
  
 | 
// 获取倒计时信息 
 | 
const getCountdown = (expectedTime) => { 
 | 
  if (!expectedTime) return { text: '-', isExpired: false } 
 | 
  
 | 
  const now = new Date().getTime() 
 | 
  const expected = new Date(expectedTime).getTime() 
 | 
  const diff = expected - now 
 | 
  
 | 
  if (diff <= 0) { 
 | 
    return { text: '已缺气', isExpired: true } 
 | 
  } 
 | 
  
 | 
  const days = Math.floor(diff / (1000 * 60 * 60 * 24)) 
 | 
  const hours = Math.floor((diff % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60)) 
 | 
  const minutes = Math.floor((diff % (1000 * 60 * 60)) / (1000 * 60)) 
 | 
  
 | 
  if (days > 0) { 
 | 
    return { text: `${days}天${hours}小时`, isExpired: false } 
 | 
  } else if (hours > 0) { 
 | 
    return { text: `${hours}小时${minutes}分钟`, isExpired: false } 
 | 
  } else { 
 | 
    return { text: `${minutes}分钟`, isExpired: false } 
 | 
  } 
 | 
} 
 | 
  
 | 
// 获取倒计时样式类 
 | 
const getCountdownClass = (expectedTime) => { 
 | 
  if (!expectedTime) return '' 
 | 
  
 | 
  const now = new Date().getTime() 
 | 
  const expected = new Date(expectedTime).getTime() 
 | 
  const diff = expected - now 
 | 
  
 | 
  if (diff <= 0) { 
 | 
    return 'countdown-expired' 
 | 
  } else if (diff <= 24 * 60 * 60 * 1000) { // 24小时内 
 | 
    return 'countdown-urgent' 
 | 
  } else if (diff <= 7 * 24 * 60 * 60 * 1000) { // 7天内 
 | 
    return 'countdown-warning' 
 | 
  } else { 
 | 
    return 'countdown-normal' 
 | 
  } 
 | 
} 
 | 
  
 | 
// 检查缺气预警 
 | 
const checkShortageWarnings = () => { 
 | 
  tableData.value.forEach(tank => { 
 | 
    if (tank.expectedShortageTime) { 
 | 
      const countdown = getCountdown(tank.expectedShortageTime) 
 | 
      if (countdown.isExpired && !tank.warningShown) { 
 | 
        // 标记已显示预警,避免重复弹框 
 | 
        tank.warningShown = true 
 | 
        showShortageWarning(tank) 
 | 
      } 
 | 
    } 
 | 
  }) 
 | 
} 
 | 
  
 | 
// 显示缺气预警弹框 
 | 
const showShortageWarning = (tank) => { 
 | 
  currentWarningTank.value = tank 
 | 
  shortageWarningVisible.value = true 
 | 
  
 | 
  // 播放提示音(可选) 
 | 
  // const audio = new Audio('/path/to/warning-sound.mp3') 
 | 
  // audio.play() 
 | 
} 
 | 
  
 | 
// 处理缺气预警 
 | 
const handleShortageWarning = () => { 
 | 
  ElMessage.success(`正在处理储气罐 ${currentWarningTank.value.tankName} 的缺气问题`) 
 | 
  shortageWarningVisible.value = false 
 | 
  // 这里可以调用处理API 
 | 
} 
 | 
// 处理缺气预警 
 | 
const closeShortageWarning = () => { 
 | 
  // ElMessage.success(`正在处理储气罐 ${currentWarningTank.value.tankName} 的缺气问题`) 
 | 
  shortageWarningVisible.value = false 
 | 
  // 这里可以调用处理API 
 | 
} 
 | 
  
 | 
// 获取列表数据 
 | 
const getList = async () => { 
 | 
  tableLoading.value = true 
 | 
  getStockWarningPage(page, searchForm) 
 | 
  .then(res => { 
 | 
  
 | 
    tableData.value = res.data.records 
 | 
    page.value.total = res.data.total; 
 | 
    tableLoading.value = false; 
 | 
        // 检查缺气预警 
 | 
    checkShortageWarnings() 
 | 
  }).catch(err => { 
 | 
    tableLoading.value = false; 
 | 
  }) 
 | 
} 
 | 
  
 | 
// 搜索 
 | 
const handleQuery = () => { 
 | 
  page.current = 1 
 | 
  getList() 
 | 
} 
 | 
  
 | 
// 重置搜索 
 | 
const resetQuery = () => { 
 | 
  Object.keys(searchForm).forEach(key => { 
 | 
    searchForm[key] = '' 
 | 
  }) 
 | 
  handleQuery() 
 | 
} 
 | 
  
 | 
// 分页变化 
 | 
const paginationChange = (obj) => { 
 | 
  page.current = obj.page 
 | 
  page.size = obj.limit 
 | 
  getList() 
 | 
} 
 | 
  
 | 
// 表格选择变化 
 | 
const handleSelectionChange = (selection) => { 
 | 
  selectedRows.value = selection 
 | 
} 
 | 
  
 | 
// 新增 
 | 
const handleAdd = () => { 
 | 
  operationType.value = 'add' 
 | 
  // resetForm() 
 | 
  dialogFormVisible.value = true 
 | 
} 
 | 
  
 | 
// 编辑 
 | 
const handleEdit = (row) => { 
 | 
  operationType.value = 'edit' 
 | 
  Object.assign(form, row) 
 | 
  dialogFormVisible.value = true 
 | 
} 
 | 
  
 | 
// 处理预警 
 | 
const handleProcess = async (row) => { 
 | 
  try { 
 | 
    // 模拟API调用延迟 
 | 
    await new Promise(resolve => setTimeout(resolve, 300)) 
 | 
    ElMessage.success(`正在处理预警:${row.tankName}`) 
 | 
    // getList() 
 | 
  } catch (error) { 
 | 
    ElMessage.error('处理预警失败') 
 | 
  } 
 | 
} 
 | 
  
 | 
// 删除 
 | 
const handleDelete = async (row) => { 
 | 
  try { 
 | 
    await ElMessageBox.confirm(`确定要删除预警规则:${row.tankName}吗?`, '提示', { 
 | 
      confirmButtonText: '确定', 
 | 
      cancelButtonText: '取消', 
 | 
      type: 'warning' 
 | 
    }) 
 | 
    let ids = []; 
 | 
    ids.push(row.id); 
 | 
    deleteStockWarning(ids).then(res => { 
 | 
      if(res.code == 200){ 
 | 
        ElMessage.success("删除成功"); 
 | 
        ids.value = []; 
 | 
        getList(); 
 | 
      } 
 | 
    }).catch(err => { 
 | 
      ElMessage.error(err.msg); 
 | 
    }) 
 | 
    // // 模拟API调用延迟 
 | 
    // await new Promise(resolve => setTimeout(resolve, 300)) 
 | 
    // ElMessage.success('删除成功') 
 | 
    // getList() 
 | 
  } catch (error) { 
 | 
    if (error !== 'cancel') { 
 | 
      ElMessage.error('删除失败') 
 | 
    } 
 | 
  } 
 | 
} 
 | 
  
 | 
// 批量处理 
 | 
const handleBatchProcess = async () => { 
 | 
  if (selectedRows.value.length === 0) { 
 | 
    ElMessage.warning('请选择要处理的预警') 
 | 
    return 
 | 
  } 
 | 
  
 | 
  try { 
 | 
    // 模拟API调用延迟 
 | 
    await new Promise(resolve => setTimeout(resolve, 500)) 
 | 
    ElMessage.success(`批量处理了 ${selectedRows.value.length} 条预警`) 
 | 
    getList() 
 | 
  } catch (error) { 
 | 
    ElMessage.error('批量处理失败') 
 | 
  } 
 | 
} 
 | 
  
 | 
// 导出 
 | 
const handleExport = async () => { 
 | 
  //   if (selectedRows.value.length === 0) { 
 | 
  //     exportStockWarning().then(res => { 
 | 
  //       // // 创建下载链接 
 | 
  //       // const blob = new Blob([res.data], { type: 'text/csv;charset=utf-8;' }) 
 | 
  //       // const url = window.URL.createObjectURL(blob) 
 | 
  //       // const link = document.createElement('a') 
 | 
  //       // link.href = url 
 | 
  //       // link.download = `储气罐预警数据_${new Date().getTime()}.csv` 
 | 
  //       // link.click() 
 | 
  //       // window.URL.revokeObjectURL(url) 
 | 
  //     }).catch(err => { 
 | 
  //       ElMessage.error(err.msg); 
 | 
  //     }) 
 | 
  // }else{ 
 | 
  //     let ids = []; 
 | 
  //     selectedRows.value.forEach(item => { 
 | 
  //       ids.push(item.id); 
 | 
  //     }) 
 | 
  //     exportStockWarning(ids).then(res => { 
 | 
  //       // // 创建下载链接 
 | 
  //       // const blob = new Blob([res.data], { type: 'text/csv;charset=utf-8;' }) 
 | 
  //       // const url = window.URL.createObjectURL(blob) 
 | 
  //       // const link = document.createElement('a') 
 | 
  //       // link.href = url 
 | 
  //       // link.download = `储气罐预警数据_${new Date().getTime()}.csv` 
 | 
  //       // link.click() 
 | 
  //       // window.URL.revokeObjectURL(url) 
 | 
  //     }).catch(err => { 
 | 
  //       ElMessage.error(err.msg); 
 | 
  //     }) 
 | 
  // } 
 | 
  
 | 
    ElMessageBox.confirm("选中的内容将被导出,是否确认导出?", "导出", { 
 | 
    confirmButtonText: "确认", 
 | 
    cancelButtonText: "取消", 
 | 
    type: "warning", 
 | 
    }) 
 | 
    .then(() => { 
 | 
      proxy.download("/gasTankWarning/export", {ids: selectedRows.value.map(item => item.id)}, "储气罐预警.xlsx"); 
 | 
    }) 
 | 
    .catch(() => { 
 | 
      proxy.$modal.msg("已取消"); 
 | 
    }); 
 | 
} 
 | 
  
 | 
  
 | 
  
 | 
// // 启用状态变化 
 | 
const handleEnableChange = async (row) => { 
 | 
  
 | 
  try { 
 | 
    updateStockWarning(row).then(res => { 
 | 
      if(res.code == 200){ 
 | 
        ElMessage.success(`${row.tankName} 的启用状态已更新`); 
 | 
        getList(); 
 | 
      } 
 | 
    }).catch(err => { 
 | 
      ElMessage.error(err.msg); 
 | 
    }) 
 | 
  } catch (error) { 
 | 
    ElMessage.error('状态更新失败') 
 | 
    // 恢复原状态 
 | 
    row.isEnabled = !row.isEnabled 
 | 
  } 
 | 
} 
 | 
  
 | 
// 提交表单 
 | 
const submitForm = async () => { 
 | 
  try { 
 | 
    await proxy.$refs.formRef.validate() 
 | 
  
 | 
    // 模拟API调用延迟 
 | 
    // await new Promise(resolve => setTimeout(resolve, 500)) 
 | 
  
 | 
    if (operationType.value === 'add') { 
 | 
      addStockWarning(form).then(res => { 
 | 
        if(res.code == 200){ 
 | 
          ElMessage.success("添加成功"); 
 | 
          dialogFormVisible.value = false 
 | 
          getList() 
 | 
          resetForm() 
 | 
        } 
 | 
      }).catch(err => { 
 | 
        ElMessage.error(err.msg); 
 | 
      }) 
 | 
  
 | 
      // ElMessage.success('新增成功') 
 | 
    } else { 
 | 
      updateStockWarning(form).then(res => { 
 | 
        if(res.code == 200){ 
 | 
          ElMessage.success("更新成功"); 
 | 
          dialogFormVisible.value = false 
 | 
          getList() 
 | 
          resetForm() 
 | 
        } 
 | 
      }).catch(err => { 
 | 
        ElMessage.error(err.msg); 
 | 
      }) 
 | 
      // ElMessage.success('编辑成功') 
 | 
    } 
 | 
  
 | 
    // closeDialog() 
 | 
    // getList() 
 | 
  } catch (error) { 
 | 
    if (!error.errors) { 
 | 
      ElMessage.error(operationType.value === 'add' ? '新增失败' : '编辑失败') 
 | 
    } 
 | 
  } 
 | 
} 
 | 
  
 | 
// 关闭弹窗 
 | 
const closeDialog = () => { 
 | 
  dialogFormVisible.value = false 
 | 
  // resetForm() 
 | 
} 
 | 
  
 | 
// 重置表单 
 | 
const resetForm = () => { 
 | 
  Object.keys(form).forEach(key => { 
 | 
    if (key === 'isEnabled') { 
 | 
      form[key] = true 
 | 
    } else if (typeof form[key] === 'number') { 
 | 
      form[key] = 0 
 | 
    } else { 
 | 
      form[key] = '' 
 | 
    } 
 | 
  }) 
 | 
  proxy.$refs.formRef?.resetFields() 
 | 
} 
 | 
  
 | 
// 获取气体量样式类 
 | 
const getGasLevelClass = (row) => { 
 | 
  if (row.currentGasLevel < row.minGasLevel) { 
 | 
    return 'text-danger' 
 | 
  } else if (row.currentGasLevel > row.maxGasLevel) { 
 | 
    return 'text-warning' 
 | 
  } 
 | 
  return 'text-success' 
 | 
} 
 | 
  
 | 
// 获取预警类型标签样式 
 | 
const getWarningTypeTag = (type) => { 
 | 
  const typeMap = { 
 | 
    '气体不足': 'danger', 
 | 
    '压力异常': 'warning', 
 | 
    '温度异常': 'info', 
 | 
    '泄漏预警': 'danger' 
 | 
  } 
 | 
  return typeMap[type] || 'info' 
 | 
} 
 | 
  
 | 
// 获取预警级别标签样式 
 | 
const getWarningLevelTag = (level) => { 
 | 
  const levelMap = { 
 | 
    '紧急': 'danger', 
 | 
    '重要': 'warning', 
 | 
    '一般': 'info' 
 | 
  } 
 | 
  return levelMap[level] || 'info' 
 | 
} 
 | 
  
 | 
// 启动倒计时定时器 
 | 
const startCountdownTimer = () => { 
 | 
  countdownTimer.value = setInterval(() => { 
 | 
    checkShortageWarnings() 
 | 
  }, 60000) // 每分钟检查一次 
 | 
} 
 | 
  
 | 
// 停止倒计时定时器 
 | 
const stopCountdownTimer = () => { 
 | 
  if (countdownTimer.value) { 
 | 
    clearInterval(countdownTimer.value) 
 | 
    countdownTimer.value = null 
 | 
  } 
 | 
} 
 | 
  
 | 
// 页面加载 
 | 
onMounted(() => { 
 | 
  getList() 
 | 
  startCountdownTimer() 
 | 
}) 
 | 
  
 | 
// 页面卸载 
 | 
onUnmounted(() => { 
 | 
  stopCountdownTimer() 
 | 
}) 
 | 
</script> 
 | 
  
 | 
<style scoped lang="scss"> 
 | 
.app-container { 
 | 
  padding: 20px; 
 | 
  
 | 
  .table-operations { 
 | 
    text-align: right; 
 | 
    margin-bottom: 20px; 
 | 
  
 | 
    .el-button { 
 | 
      margin-right: 10px; 
 | 
    } 
 | 
  } 
 | 
  
 | 
  .table_list { 
 | 
    background: #fff; 
 | 
    border-radius: 4px; 
 | 
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); 
 | 
  } 
 | 
  
 | 
  .text-danger { 
 | 
    color: #f56c6c; 
 | 
    font-weight: bold; 
 | 
  } 
 | 
  
 | 
  .text-warning { 
 | 
    color: #e6a23c; 
 | 
    font-weight: bold; 
 | 
  } 
 | 
  
 | 
  .text-success { 
 | 
    color: #67c23a; 
 | 
    font-weight: bold; 
 | 
  } 
 | 
  
 | 
  .dialog-footer { 
 | 
    text-align: right; 
 | 
  } 
 | 
  
 | 
  // 倒计时样式 
 | 
  .countdown-timer { 
 | 
    font-weight: bold; 
 | 
  } 
 | 
  
 | 
  .countdown-normal { 
 | 
    color: #67c23a; 
 | 
  } 
 | 
  
 | 
  .countdown-warning { 
 | 
    color: #e6a23c; 
 | 
  } 
 | 
  
 | 
  .countdown-urgent { 
 | 
    color: #f56c6c; 
 | 
    animation: blink 1s infinite; 
 | 
  } 
 | 
  
 | 
  .countdown-expired { 
 | 
    color: #f56c6c; 
 | 
    font-weight: bold; 
 | 
  } 
 | 
  
 | 
  @keyframes blink { 
 | 
    0%, 50% { opacity: 1; } 
 | 
    51%, 100% { opacity: 0.5; } 
 | 
  } 
 | 
  
 | 
  // 缺气预警弹框样式 
 | 
  .shortage-warning-content { 
 | 
    text-align: center; 
 | 
    padding: 20px 0; 
 | 
  
 | 
    .warning-icon { 
 | 
      margin-bottom: 20px; 
 | 
    } 
 | 
  
 | 
    .warning-message { 
 | 
      h3 { 
 | 
        color: #f56c6c; 
 | 
        margin-bottom: 10px; 
 | 
      } 
 | 
  
 | 
      p { 
 | 
        margin-bottom: 10px; 
 | 
        color: #606266; 
 | 
      } 
 | 
  
 | 
      .warning-details { 
 | 
        background: #f5f7fa; 
 | 
        padding: 15px; 
 | 
        border-radius: 4px; 
 | 
        text-align: left; 
 | 
        font-size: 14px; 
 | 
        line-height: 1.6; 
 | 
      } 
 | 
    } 
 | 
  } 
 | 
} 
 | 
</style> 
 |