From 8bc17a9ea84a6af0b7d01e451c702f404a3ff895 Mon Sep 17 00:00:00 2001
From: zouyu <2723363702@qq.com>
Date: 星期六, 10 一月 2026 11:36:34 +0800
Subject: [PATCH] Merge branch 'dev_tide' into dev_tide_cbsglxt

---
 src/views/inventoryManagement/stockWarning/index.vue |  943 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 943 insertions(+), 0 deletions(-)

diff --git a/src/views/inventoryManagement/stockWarning/index.vue b/src/views/inventoryManagement/stockWarning/index.vue
new file mode 100644
index 0000000..d0d5834
--- /dev/null
+++ b/src/views/inventoryManagement/stockWarning/index.vue
@@ -0,0 +1,943 @@
+<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'
+// 娉ㄩ噴鎺堿PI瀵煎叆锛屼娇鐢ㄥ亣鏁版嵁
+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(`姝e湪澶勭悊鍌ㄦ皵缃� ${currentWarningTank.value.tankName} 鐨勭己姘旈棶棰榒)
+  shortageWarningVisible.value = false
+  // 杩欓噷鍙互璋冪敤澶勭悊API
+}
+// 澶勭悊缂烘皵棰勮
+const closeShortageWarning = () => {
+  // ElMessage.success(`姝e湪澶勭悊鍌ㄦ皵缃� ${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(`姝e湪澶勭悊棰勮锛�${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>

--
Gitblit v1.9.3