From 386375a8e04f72a8bc17553b649a38b5535e21ba Mon Sep 17 00:00:00 2001
From: gaoluyang <2820782392@qq.com>
Date: 星期一, 11 八月 2025 09:26:52 +0800
Subject: [PATCH] 1.添加用水管理页面

---
 src/views/equipmentManagement/gasTank/simple.vue                        |  566 +++++++++++
 src/api/inventoryManagement/stockWarning.js                             |   81 +
 src/views/energyManagement/waterManagement/index.vue                    |  312 ++++++
 src/views/energyManagement/waterManagement/waterTrends.vue              |  118 ++
 src/views/energyManagement/waterManagement/components/formDia.vue       |  221 ++++
 src/views/energyManagement/waterManagement/waterBill.vue                |  181 +++
 src/views/energyManagement/waterManagement/components/waterBillForm.vue |  210 ++++
 src/views/inventoryManagement/stockWarning/index.vue                    | 1137 +++++++++++++++++++++++
 src/api/energyManagement/waterManagement.js                             |   91 +
 9 files changed, 2,917 insertions(+), 0 deletions(-)

diff --git a/src/api/energyManagement/waterManagement.js b/src/api/energyManagement/waterManagement.js
new file mode 100644
index 0000000..aef7465
--- /dev/null
+++ b/src/api/energyManagement/waterManagement.js
@@ -0,0 +1,91 @@
+// 鐢ㄦ按绠$悊
+import request from "@/utils/request";
+
+// 鐢ㄦ按璁惧-鍒嗛〉鏌ヨ
+export function waterEquipmentListPage(query) {
+  return request({
+    url: '/waterEquipmentConsumption/listPage',
+    method: 'get',
+    params: query,
+  })
+}
+
+// 鐢ㄦ按瓒嬪娍-鍒嗛〉鏌ヨ
+export function listPageByWaterTrend(query) {
+  return request({
+    url: '/waterEquipmentConsumption/listPageByTrend',
+    method: 'get',
+    params: query,
+  })
+}
+
+// 鐢ㄦ按璁惧-鍒犻櫎
+export function waterEquipmentDelete(query) {
+  return request({
+    url: '/waterEquipmentConsumption/delete',
+    method: 'delete',
+    data: query,
+  })
+}
+
+// 鐢ㄦ按璁惧-鏂板
+export function waterEquipmentAdd(query) {
+  return request({
+    url: '/waterEquipmentConsumption/add',
+    method: 'post',
+    data: query,
+  })
+}
+
+// 鐢ㄦ按璁惧-淇敼
+export function waterEquipmentUpdate(query) {
+  return request({
+    url: '/waterEquipmentConsumption/update',
+    method: 'post',
+    data: query,
+  })
+}
+
+// 鐢ㄦ按璁惧涓嬫媺妗嗘煡璇�
+export function waterDeviceList(query) {
+  return request({
+    url: '/waterEquipmentConsumption/deviceList',
+    method: 'get',
+  })
+}
+
+// 姘磋垂绠$悊-鍒嗛〉鏌ヨ
+export function waterBillListPage(query) {
+  return request({
+    url: '/waterBill/listPage',
+    method: 'get',
+    params: query,
+  })
+}
+
+// 姘磋垂绠$悊-鏂板
+export function waterBillAdd(query) {
+  return request({
+    url: '/waterBill/add',
+    method: 'post',
+    data: query,
+  })
+}
+
+// 姘磋垂绠$悊-淇敼
+export function waterBillUpdate(query) {
+  return request({
+    url: '/waterBill/update',
+    method: 'post',
+    data: query,
+  })
+}
+
+// 姘磋垂绠$悊-鍒犻櫎
+export function waterBillDelete(query) {
+  return request({
+    url: '/waterBill/delete',
+    method: 'delete',
+    data: query,
+  })
+}
diff --git a/src/api/inventoryManagement/stockWarning.js b/src/api/inventoryManagement/stockWarning.js
new file mode 100644
index 0000000..092fb80
--- /dev/null
+++ b/src/api/inventoryManagement/stockWarning.js
@@ -0,0 +1,81 @@
+import request from "@/utils/request";
+
+// 鏌ヨ鍌ㄦ皵缃愰璀﹀垪琛�
+export const getStockWarningPage = (params) => {
+    return request({
+        url: "/gasTankWarning/listPage",
+        method: "get",
+        params,
+    });
+};
+
+// 鏂板鍌ㄦ皵缃愰璀﹁鍒�
+export const addStockWarning = (data) => {
+    return request({
+        url: "/gasTankWarning/add",
+        method: "post",
+        data,
+    });
+};
+
+// 淇敼鍌ㄦ皵缃愰璀﹁鍒�
+export const updateStockWarning = (data) => {
+    return request({
+        url: "/gasTankWarning/update",
+        method: "put",
+        data,
+    });
+};
+
+// 鍒犻櫎鍌ㄦ皵缃愰璀﹁鍒�
+export const deleteStockWarning = (ids) => {
+    return request({
+        url: "/gasTankWarning/delete",
+        method: "delete",
+        data: { ids },
+    });
+};
+
+// 鎵归噺澶勭悊鍌ㄦ皵缃愰璀�
+export const batchProcessStockWarning = (data) => {
+    return request({
+        url: "/gasTankWarning/batchProcess",
+        method: "post",
+        data,
+    });
+};
+
+// 瀵煎嚭鍌ㄦ皵缃愰璀︽暟鎹�
+export const exportStockWarning = (params) => {
+    return request({
+        url: "/gasTankWarning/export",
+        method: "get",
+        params,
+        responseType: "blob",
+    });
+};
+
+// 鏍规嵁ID鑾峰彇鍌ㄦ皵缃愰璀﹁鎯�
+export const getStockWarningById = (id) => {
+    return request({
+        url: `/gasTankWarning/${id}`,
+        method: "get",
+    });
+};
+
+// 鍚敤/绂佺敤棰勮瑙勫垯
+export const toggleStockWarningStatus = (data) => {
+    return request({
+        url: "/gasTankWarning/toggleStatus",
+        method: "put",
+        data,
+    });
+};
+
+// 鑾峰彇棰勮缁熻淇℃伅
+export const getStockWarningStatistics = () => {
+    return request({
+        url: "/gasTankWarning/statistics",
+        method: "get",
+    });
+};
diff --git a/src/views/energyManagement/waterManagement/components/formDia.vue b/src/views/energyManagement/waterManagement/components/formDia.vue
new file mode 100644
index 0000000..a692b95
--- /dev/null
+++ b/src/views/energyManagement/waterManagement/components/formDia.vue
@@ -0,0 +1,221 @@
+<template>
+  <div>
+    <el-dialog
+        v-model="dialogFormVisible"
+        title="鐢ㄦ按璁惧"
+        width="70%"
+        @close="closeDia"
+    >
+			<el-form
+				:model="form"
+				label-width="140px"
+				label-position="top"
+				:rules="rules"
+				ref="formRef"
+			>
+				<el-row :gutter="30">
+					<el-col :span="12">
+						<el-form-item label="璁惧锛�" prop="code">
+							<el-select
+								v-model="form.code"
+								placeholder="璇烽�夋嫨"
+								clearable
+								@change="setName"
+								:disabled="operationType !== 'add'"
+							>
+								<el-option
+									v-for="item in codeList"
+									:key="item.deviceModel"
+									:label="item.deviceName"
+									:value="item.deviceModel"
+								>
+									{{item.deviceName + '--' + item.deviceModel}}
+								</el-option>
+							</el-select>
+						</el-form-item>
+					</el-col>
+					<el-col :span="12">
+						<el-form-item label="姣忔棩闄愬埗姘撮噺锛�" prop="everyNum">
+							<el-input
+								v-model="form.everyNum"
+								placeholder="璇疯緭鍏�"
+								clearable
+							/>
+						</el-form-item>
+					</el-col>
+				</el-row>
+				<el-row :gutter="30">
+					<el-col :span="12">
+						<el-form-item label="棰濆畾娴侀噺锛�" prop="flowRating">
+							<el-input
+								v-model="form.flowRating"
+								placeholder="璇疯緭鍏�"
+								clearable
+							/>
+						</el-form-item>
+					</el-col>
+					<el-col :span="12">
+						<el-form-item label="瀹為檯娴侀噺锛�" prop="flowActual">
+							<el-input
+								v-model="form.flowActual"
+								placeholder="璇疯緭鍏�"
+								clearable
+							/>
+						</el-form-item>
+					</el-col>
+				</el-row>
+				<el-row :gutter="30">
+					<el-col :span="12">
+						<el-form-item label="杩愯鏃堕棿锛�" prop="runDate">
+							<el-date-picker
+								style="width: 100%"
+								v-model="form.runDate"
+								value-format="YYYY-MM-DD"
+								format="YYYY-MM-DD"
+								type="date"
+								placeholder="璇烽�夋嫨"
+								clearable
+							/>
+						</el-form-item>
+					</el-col>
+					<el-col :span="12">
+						<el-form-item label="褰撴棩鐢ㄦ按閲忥細" prop="dayNum">
+							<el-input
+								v-model="form.dayNum"
+								placeholder="璇疯緭鍏�"
+								clearable
+							/>
+						</el-form-item>
+					</el-col>
+				</el-row>
+				<el-row :gutter="30">
+					<el-col :span="12">
+						<el-form-item label="姘磋垂鍗曚环锛�" prop="waterPrice">
+							<el-input
+								v-model="form.waterPrice"
+								placeholder="璇疯緭鍏�"
+								clearable
+							/>
+						</el-form-item>
+					</el-col>
+					<el-col :span="12">
+						<el-form-item label="鐢ㄦ按绫诲瀷锛�" prop="waterType">
+							<el-select
+								v-model="form.waterType"
+								placeholder="璇烽�夋嫨"
+								clearable
+							>
+								<el-option label="宸ヤ笟鐢ㄦ按" value="industrial" />
+								<el-option label="鐢熸椿鐢ㄦ按" value="domestic" />
+								<el-option label="娑堥槻鐢ㄦ按" value="fire" />
+								<el-option label="缁垮寲鐢ㄦ按" value="greening" />
+							</el-select>
+						</el-form-item>
+					</el-col>
+				</el-row>
+			</el-form>
+			<template #footer>
+				<div class="dialog-footer">
+					<el-button type="primary" @click="submitForm">纭</el-button>
+					<el-button @click="closeDia">鍙栨秷</el-button>
+				</div>
+			</template>
+    </el-dialog>
+  </div>
+</template>
+
+<script setup>
+import {ref, reactive, nextTick} from "vue";
+import useUserStore from "@/store/modules/user.js";
+import {waterDeviceList, waterEquipmentAdd, waterEquipmentUpdate} from "@/api/energyManagement/waterManagement.js";
+const { proxy } = getCurrentInstance()
+const emit = defineEmits(['close'])
+const dialogFormVisible = ref(false);
+const operationType = ref('')
+const userStore = useUserStore();
+
+const data = reactive({
+	form: {
+		name: "",
+		code: "",
+		everyNum: "",
+		flowRating: "",
+		flowActual: "",
+		runDate: "",
+		dayNum: "",
+		waterPrice: "",
+		waterType: "",
+	},
+	rules: {
+		code: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
+		runDate: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
+		everyNum: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
+		flowRating: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
+		flowActual: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
+		dayNum: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
+		waterPrice: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
+		waterType: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
+	},
+})
+const { form, rules } = toRefs(data);
+const codeList = ref([])
+
+// 鎵撳紑寮规
+const openDialog = (type, row) => {
+  operationType.value = type;
+  dialogFormVisible.value = true;
+	form.value = {}
+	proxy.resetForm("formRef");
+	waterDeviceList().then((res) => {
+		codeList.value = res.data;
+	});
+	if (type === "edit") {
+		form.value = {...row}
+	}
+}
+const setName = (code) => {
+	const index = codeList.value.findIndex(item => item.deviceModel === code);
+	if (index > -1) {
+		console.log(codeList)
+		form.value.name = codeList.value[index].deviceName;
+	}
+}
+const submitForm = () => {
+	proxy.$refs["formRef"].validate(valid => {
+		if (valid) {
+			if (operationType.value === "add") {
+				waterEquipmentAdd(form.value).then(response => {
+					proxy.$modal.msgSuccess("鏂板鎴愬姛")
+					closeDia()
+				})
+			} else {
+				waterEquipmentUpdate(form.value).then(response => {
+					proxy.$modal.msgSuccess("淇敼鎴愬姛")
+					closeDia()
+				})
+			}
+		}
+	})
+}
+// 鍏抽棴寮规
+const closeDia = () => {
+	proxy.resetForm("formRef");
+  dialogFormVisible.value = false;
+  emit('close')
+};
+// 鑾峰彇褰撳墠鏃ユ湡骞舵牸寮忓寲涓� YYYY-MM-DD
+function getCurrentDate() {
+	const today = new Date();
+	const year = today.getFullYear();
+	const month = String(today.getMonth() + 1).padStart(2, "0"); // 鏈堜唤浠�0寮�濮�
+	const day = String(today.getDate()).padStart(2, "0");
+	return `${year}-${month}-${day}`;
+}
+defineExpose({
+  openDialog,
+});
+</script>
+
+<style scoped>
+
+</style>
diff --git a/src/views/energyManagement/waterManagement/components/waterBillForm.vue b/src/views/energyManagement/waterManagement/components/waterBillForm.vue
new file mode 100644
index 0000000..a132041
--- /dev/null
+++ b/src/views/energyManagement/waterManagement/components/waterBillForm.vue
@@ -0,0 +1,210 @@
+<template>
+  <div>
+    <el-dialog
+        v-model="dialogFormVisible"
+        title="姘磋垂绠$悊"
+        width="70%"
+        @close="closeDia"
+    >
+			<el-form
+				:model="form"
+				label-width="140px"
+				label-position="top"
+				:rules="rules"
+				ref="formRef"
+			>
+				<el-row :gutter="30">
+					<el-col :span="12">
+						<el-form-item label="璁惧锛�" prop="code">
+							<el-select
+								v-model="form.code"
+								placeholder="璇烽�夋嫨"
+								clearable
+								@change="setName"
+								:disabled="operationType !== 'add'"
+							>
+								<el-option
+									v-for="item in codeList"
+									:key="item.deviceModel"
+									:label="item.deviceName"
+									:value="item.deviceModel"
+								>
+									{{item.deviceName + '--' + item.deviceModel}}
+								</el-option>
+							</el-select>
+						</el-form-item>
+					</el-col>
+					<el-col :span="12">
+						<el-form-item label="鐢ㄦ按閲忥細" prop="waterConsumption">
+							<el-input
+								v-model="form.waterConsumption"
+								placeholder="璇疯緭鍏�"
+								clearable
+							/>
+						</el-form-item>
+					</el-col>
+				</el-row>
+				<el-row :gutter="30">
+					<el-col :span="12">
+						<el-form-item label="姘磋垂鍗曚环锛�" prop="waterPrice">
+							<el-input
+								v-model="form.waterPrice"
+								placeholder="璇疯緭鍏�"
+								clearable
+							/>
+						</el-form-item>
+					</el-col>
+					<el-col :span="12">
+						<el-form-item label="姘磋垂閲戦锛�" prop="waterBill">
+							<el-input
+								v-model="form.waterBill"
+								placeholder="鑷姩璁$畻"
+								clearable
+								disabled
+							/>
+						</el-form-item>
+					</el-col>
+				</el-row>
+				<el-row :gutter="30">
+					<el-col :span="12">
+						<el-form-item label="璁¤垂鏃ユ湡锛�" prop="billDate">
+							<el-date-picker
+								style="width: 100%"
+								v-model="form.billDate"
+								value-format="YYYY-MM-DD"
+								format="YYYY-MM-DD"
+								type="date"
+								placeholder="璇烽�夋嫨"
+								clearable
+							/>
+						</el-form-item>
+					</el-col>
+					<el-col :span="12">
+						<el-form-item label="鐢ㄦ按绫诲瀷锛�" prop="waterType">
+							<el-select
+								v-model="form.waterType"
+								placeholder="璇烽�夋嫨"
+								clearable
+							>
+								<el-option label="宸ヤ笟鐢ㄦ按" value="industrial" />
+								<el-option label="鐢熸椿鐢ㄦ按" value="domestic" />
+								<el-option label="娑堥槻鐢ㄦ按" value="fire" />
+								<el-option label="缁垮寲鐢ㄦ按" value="greening" />
+							</el-select>
+						</el-form-item>
+					</el-col>
+				</el-row>
+			</el-form>
+			<template #footer>
+				<div class="dialog-footer">
+					<el-button type="primary" @click="submitForm">纭</el-button>
+					<el-button @click="closeDia">鍙栨秷</el-button>
+				</div>
+			</template>
+    </el-dialog>
+  </div>
+</template>
+
+<script setup>
+import {ref, reactive, nextTick, watch} from "vue";
+import useUserStore from "@/store/modules/user.js";
+import {waterDeviceList, waterBillAdd, waterBillUpdate} from "@/api/energyManagement/waterManagement.js";
+const { proxy } = getCurrentInstance()
+const emit = defineEmits(['close'])
+const dialogFormVisible = ref(false);
+const operationType = ref('')
+const userStore = useUserStore();
+
+const data = reactive({
+	form: {
+		name: "",
+		code: "",
+		waterConsumption: "",
+		waterPrice: "",
+		waterBill: "",
+		billDate: "",
+		waterType: "",
+	},
+	rules: {
+		code: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
+		waterConsumption: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
+		waterPrice: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
+		billDate: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
+		waterType: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
+	},
+})
+const { form, rules } = toRefs(data);
+const codeList = ref([])
+
+// 鎵撳紑寮规
+const openDialog = (type, row) => {
+  operationType.value = type;
+  dialogFormVisible.value = true;
+	form.value = {}
+	proxy.resetForm("formRef");
+	waterDeviceList().then((res) => {
+		codeList.value = res.data;
+	});
+	if (type === "edit") {
+		form.value = {...row}
+	}
+}
+const setName = (code) => {
+	const index = codeList.value.findIndex(item => item.deviceModel === code);
+	if (index > -1) {
+		console.log(codeList)
+		form.value.name = codeList.value[index].deviceName;
+	}
+}
+
+// 璁$畻姘磋垂閲戦
+const calculateWaterBill = () => {
+	if (form.value.waterConsumption && form.value.waterPrice) {
+		form.value.waterBill = (parseFloat(form.value.waterConsumption) * parseFloat(form.value.waterPrice)).toFixed(2);
+	}
+}
+
+// 鐩戝惉鐢ㄦ按閲忓拰姘磋垂鍗曚环鍙樺寲
+watch([() => form.value.waterConsumption, () => form.value.waterPrice], () => {
+	calculateWaterBill();
+});
+
+const submitForm = () => {
+	proxy.$refs["formRef"].validate(valid => {
+		if (valid) {
+			if (operationType.value === "add") {
+				waterBillAdd(form.value).then(response => {
+					proxy.$modal.msgSuccess("鏂板鎴愬姛")
+					closeDia()
+				})
+			} else {
+				waterBillUpdate(form.value).then(response => {
+					proxy.$modal.msgSuccess("淇敼鎴愬姛")
+					closeDia()
+				})
+			}
+		}
+	})
+}
+// 鍏抽棴寮规
+const closeDia = () => {
+	proxy.resetForm("formRef");
+  dialogFormVisible.value = false;
+  emit('close')
+};
+// 鑾峰彇褰撳墠鏃ユ湡骞舵牸寮忓寲涓� YYYY-MM-DD
+function getCurrentDate() {
+	const today = new Date();
+	const year = today.getFullYear();
+	const month = String(today.getMonth() + 1).padStart(2, "0"); // 鏈堜唤浠�0寮�濮�
+	const day = String(today.getDate()).padStart(2, "0");
+	return `${year}-${month}-${day}`;
+}
+defineExpose({
+  openDialog,
+});
+</script>
+
+<style scoped>
+
+</style>
diff --git a/src/views/energyManagement/waterManagement/index.vue b/src/views/energyManagement/waterManagement/index.vue
new file mode 100644
index 0000000..848a945
--- /dev/null
+++ b/src/views/energyManagement/waterManagement/index.vue
@@ -0,0 +1,312 @@
+<template>
+	<div class="app-container">
+		<div class="search_form">
+			<div>
+				<span class="search_title">璁惧鍚嶇О锛�</span>
+				<el-input
+					v-model="searchForm.name"
+					style="width: 240px"
+					placeholder="璇疯緭鍏�"
+					@change="handleQuery"
+					clearable
+					:prefix-icon="Search"
+				/>
+				<el-button type="primary" @click="handleQuery" style="margin-left: 10px"
+				>鎼滅储</el-button
+				>
+			</div>
+			<div>
+				<el-button type="primary" @click="openForm('add')">鏂板</el-button>
+				<el-button type="info" plain icon="Upload" @click="handleImport">瀵煎叆</el-button>
+				<el-button type="danger" plain @click="handleDelete">鍒犻櫎</el-button>
+			</div>
+		</div>
+		<div class="table_list">
+			<PIMTable
+				rowKey="id"
+				:column="tableColumn"
+				:tableData="tableData"
+				:page="page"
+				:isSelection="true"
+				@selection-change="handleSelectionChange"
+				:tableLoading="tableLoading"
+				@pagination="pagination"
+			></PIMTable>
+		</div>
+		<form-dia ref="formDia" @close="handleQuery"></form-dia>
+		<el-dialog
+			:title="upload.title"
+			v-model="upload.open"
+			width="400px"
+			append-to-body
+			@close="handleDialogClose"
+		>
+			<el-upload
+				ref="uploadRef"
+				:limit="1"
+				accept=".xlsx, .xls"
+				:headers="upload.headers"
+				:action="upload.url"
+				:disabled="upload.isUploading"
+				:before-upload="upload.beforeUpload"
+				:on-progress="upload.onProgress"
+				:on-success="upload.onSuccess"
+				:on-error="upload.onError"
+				:on-change="upload.onChange"
+				:auto-upload="false"
+				drag
+			>
+				<el-icon class="el-icon--upload"><upload-filled /></el-icon>
+				<div class="el-upload__text">灏嗘枃浠舵嫋鍒版澶勶紝鎴�<em>鐐瑰嚮涓婁紶</em></div>
+				<template #tip>
+					<div class="el-upload__tip text-center">
+						<span>浠呭厑璁稿鍏ls銆亁lsx鏍煎紡鏂囦欢銆�</span>
+						<el-link
+							type="primary"
+							:underline="false"
+							style="font-size: 12px; vertical-align: baseline"
+							@click="importTemplate"
+							>涓嬭浇妯℃澘</el-link
+						>
+					</div>
+				</template>
+			</el-upload>
+			<template #footer>
+				<div class="dialog-footer">
+					<el-button type="primary" @click="submitFileForm">纭� 瀹�</el-button>
+					<el-button @click="upload.open = false">鍙� 娑�</el-button>
+				</div>
+			</template>
+		</el-dialog>
+	</div>
+</template>
+
+<script setup>
+import {Search} from "@element-plus/icons-vue";
+import {onMounted, ref, reactive, nextTick} from "vue";
+import FormDia from "@/views/energyManagement/waterManagement/components/formDia.vue";
+import {ElMessageBox} from "element-plus";
+import {getToken} from "@/utils/auth.js";
+import {waterEquipmentDelete, waterEquipmentListPage} from "@/api/energyManagement/waterManagement.js";
+const { proxy } = getCurrentInstance();
+
+const data = reactive({
+	searchForm: {
+		name: "",
+	},
+});
+const { searchForm } = toRefs(data);
+
+const selectedRows = ref([]);
+const tableColumn = ref([
+	{
+		label: "璁惧鍚嶇О",
+		prop: "name",
+		width: 200,
+	},
+	{
+		label: "瑙勬牸鍨嬪彿",
+		prop: "code",
+		width: 200,
+	},
+	{
+		label: "棰濆畾娴侀噺",
+		prop: "flowRating",
+	},
+	{
+		label: "瀹為檯娴侀噺",
+		prop: "flowActual",
+	},
+	{
+		label: "杩愯鏃堕棿",
+		prop: "runDate",
+		width:150
+	},
+	{
+		label: "褰撴棩鐢ㄦ按閲�",
+		prop: "dayNum",
+		width: 150,
+	},
+	{
+		label: "姣忔棩闄愬埗姘撮噺",
+		prop: "everyNum",
+		width:220
+	},
+	{
+		label: "姘磋垂鍗曚环",
+		prop: "waterPrice",
+		width: 120,
+	},
+	{
+		dataType: "action",
+		label: "鎿嶄綔",
+		align: "center",
+		fixed: 'right',
+		operation: [
+			{
+				name: "缂栬緫",
+				type: "text",
+				clickFun: (row) => {
+					openForm("edit", row);
+				},
+			},
+		],
+	},
+]);
+const tableData = ref([]);
+const tableLoading = ref(false);
+const page = reactive({
+	current: 1,
+	size: 100,
+	total: 0,
+});
+// 琛ㄦ牸閫夋嫨鏁版嵁
+const handleSelectionChange = (selection) => {
+	selectedRows.value = selection;
+};
+const formDia = ref()
+const upload = reactive({
+	// 鏄惁鏄剧ず寮瑰嚭灞傦紙瀹㈡埛瀵煎叆锛�
+	open: false,
+	// 寮瑰嚭灞傛爣棰橈紙瀹㈡埛瀵煎叆锛�
+	title: "",
+	// 鏄惁绂佺敤涓婁紶
+	isUploading: false,
+	// 璁剧疆涓婁紶鐨勮姹傚ご閮�
+	headers: { Authorization: "Bearer " + getToken() },
+	// 涓婁紶鐨勫湴鍧�
+	url: import.meta.env.VITE_APP_BASE_API + "/waterEquipmentConsumption/importData",
+	// 鏂囦欢涓婁紶鍓嶇殑鍥炶皟
+	beforeUpload: (file) => {
+		console.log('鏂囦欢鍗冲皢涓婁紶', file);
+		// 鍙互鍦ㄦ澶勫仛鏂囦欢绫诲瀷鎴栧ぇ灏忔牎楠�
+		const isValid = file.type === 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' || file.name.endsWith('.xlsx') || file.name.endsWith('.xls');
+		if (!isValid) {
+			proxy.$modal.msgError("鍙兘涓婁紶 Excel 鏂囦欢");
+		}
+		return isValid;
+	},
+	// 鏂囦欢鐘舵�佹敼鍙樻椂鐨勫洖璋�
+	onChange: (file, fileList) => {
+		console.log('鏂囦欢鐘舵�佹敼鍙�', file, fileList);
+	},
+	// 鏂囦欢涓婁紶鎴愬姛鏃剁殑鍥炶皟
+	onSuccess: (response, file, fileList) => {
+		console.log('涓婁紶鎴愬姛', response, file, fileList);
+		if(response.code === 200){
+			proxy.$modal.msgSuccess("鏂囦欢涓婁紶鎴愬姛");
+		}else if(response.code === 500){
+			proxy.$modal.msgError(response.msg);
+		}else{
+			proxy.$modal.msgError("鏂囦欢涓婁紶澶辫触");
+		}
+		upload.open = false;
+		getList();
+	},
+	// 鏂囦欢涓婁紶澶辫触鏃剁殑鍥炶皟
+	onError: (error, file, fileList) => {
+		console.log('涓婁紶澶辫触', error, file, fileList);
+		proxy.$modal.msgError("鏂囦欢涓婁紶澶辫触");
+		upload.open = false;
+	},
+	// 鏂囦欢涓婁紶杩涘害鏀瑰彉鏃剁殑鍥炶皟
+	onProgress: (event, file, fileList) => {
+		console.log('涓婁紶杩涘害', event, file, fileList);
+		upload.isUploading = true;
+	},
+});
+
+// 鏌ヨ鍒楄〃
+/** 鎼滅储鎸夐挳鎿嶄綔 */
+const handleQuery = () => {
+	page.current = 1;
+	getList();
+};
+const pagination = (obj) => {
+	page.current = obj.page;
+	page.size = obj.limit;
+	getList();
+};
+
+const getList = () => {
+	tableLoading.value = true;
+	waterEquipmentListPage({ ...searchForm.value, ...page }).then((res) => {
+		tableLoading.value = false;
+		tableData.value = res.data.records;
+		page.total = res.data.total;
+	}).catch(() => {
+		tableLoading.value = false;
+	})
+};
+
+// 鎵撳紑寮规
+const openForm = (type, row) => {
+	nextTick(() => {
+		formDia.value?.openDialog(type, row)
+	})
+};
+
+/** 瀵煎叆鎸夐挳鎿嶄綔 */
+function handleImport() {
+	upload.title = "鐢ㄦ按璁惧";
+	upload.open = true;
+	// 娓呯┖涓婃涓婁紶鐨勬枃浠跺垪琛�
+	nextTick(() => {
+		proxy.$refs["uploadRef"]?.clearFiles();
+	});
+}
+function importTemplate() {
+	proxy.download(
+		"/waterEquipmentConsumption/export",
+		{},
+		'鐢ㄦ按璁惧瀵煎叆妯$増.xlsx'
+	);
+}
+/** 鎻愪氦涓婁紶鏂囦欢 */
+function submitFileForm() {
+	proxy.$refs["uploadRef"].submit();
+}
+
+/** 寮规鍏抽棴鏃舵竻绌烘枃浠跺垪琛� */
+function handleDialogClose() {
+	nextTick(() => {
+		proxy.$refs["uploadRef"]?.clearFiles();
+	});
+}
+
+const handleDelete = () => {
+	let ids = [];
+	if (selectedRows.value.length > 0) {
+		ids = selectedRows.value.map((item) => item.id);
+	} else {
+		proxy.$modal.msgWarning("璇烽�夋嫨鏁版嵁");
+		return;
+	}
+	ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚垹闄わ紝鏄惁纭鍒犻櫎锛�", "鍒犻櫎鎻愮ず", {
+		confirmButtonText: "纭",
+		cancelButtonText: "鍙栨秷",
+		type: "warning",
+	})
+		.then(() => {
+			tableLoading.value = true;
+			waterEquipmentDelete(ids)
+				.then((res) => {
+					proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
+					getList();
+				})
+				.finally(() => {
+					tableLoading.value = false;
+				});
+		})
+		.catch(() => {
+			proxy.$modal.msg("宸插彇娑�");
+		});
+};
+onMounted(() => {
+	getList();
+});
+</script>
+
+<style scoped>
+
+</style>
diff --git a/src/views/energyManagement/waterManagement/waterBill.vue b/src/views/energyManagement/waterManagement/waterBill.vue
new file mode 100644
index 0000000..ea382f0
--- /dev/null
+++ b/src/views/energyManagement/waterManagement/waterBill.vue
@@ -0,0 +1,181 @@
+<template>
+	<div class="app-container">
+		<div class="search_form">
+			<div>
+				<span class="search_title">璁惧鍚嶇О锛�</span>
+				<el-input
+					v-model="searchForm.name"
+					style="width: 240px"
+					placeholder="璇疯緭鍏�"
+					@change="handleQuery"
+					clearable
+					:prefix-icon="Search"
+				/>
+				<el-button type="primary" @click="handleQuery" style="margin-left: 10px"
+				>鎼滅储</el-button
+				>
+			</div>
+			<div>
+				<el-button type="primary" @click="openForm('add')">鏂板</el-button>
+				<el-button type="danger" plain @click="handleDelete">鍒犻櫎</el-button>
+			</div>
+		</div>
+		<div class="table_list">
+			<PIMTable
+				rowKey="id"
+				:column="tableColumn"
+				:tableData="tableData"
+				:page="page"
+				:isSelection="true"
+				@selection-change="handleSelectionChange"
+				:tableLoading="tableLoading"
+				@pagination="pagination"
+			></PIMTable>
+		</div>
+		<form-dia ref="formDia" @close="handleQuery"></form-dia>
+	</div>
+</template>
+
+<script setup>
+import {Search} from "@element-plus/icons-vue";
+import {onMounted, ref, reactive, nextTick} from "vue";
+import FormDia from "@/views/energyManagement/waterManagement/components/waterBillForm.vue";
+import {ElMessageBox} from "element-plus";
+import {waterBillDelete, waterBillListPage} from "@/api/energyManagement/waterManagement.js";
+const { proxy } = getCurrentInstance();
+
+const data = reactive({
+	searchForm: {
+		name: "",
+	},
+});
+const { searchForm } = toRefs(data);
+
+const selectedRows = ref([]);
+const tableColumn = ref([
+	{
+		label: "璁惧鍚嶇О",
+		prop: "name",
+		width: 200,
+	},
+	{
+		label: "瑙勬牸鍨嬪彿",
+		prop: "code",
+		width: 200,
+	},
+	{
+		label: "鐢ㄦ按閲�",
+		prop: "waterConsumption",
+	},
+	{
+		label: "姘磋垂鍗曚环",
+		prop: "waterPrice",
+	},
+	{
+		label: "姘磋垂閲戦",
+		prop: "waterBill",
+		width:150
+	},
+	{
+		label: "璁¤垂鏃ユ湡",
+		prop: "billDate",
+		width: 150,
+	},
+	{
+		label: "鐢ㄦ按绫诲瀷",
+		prop: "waterType",
+		width:120
+	},
+	{
+		dataType: "action",
+		label: "鎿嶄綔",
+		align: "center",
+		fixed: 'right',
+		operation: [
+			{
+				name: "缂栬緫",
+				type: "text",
+				clickFun: (row) => {
+					openForm("edit", row);
+				},
+			},
+		],
+	},
+]);
+const tableData = ref([]);
+const tableLoading = ref(false);
+const page = reactive({
+	current: 1,
+	size: 100,
+	total: 0,
+});
+// 琛ㄦ牸閫夋嫨鏁版嵁
+const handleSelectionChange = (selection) => {
+	selectedRows.value = selection;
+};
+const formDia = ref()
+
+// 鏌ヨ鍒楄〃
+/** 鎼滅储鎸夐挳鎿嶄綔 */
+const handleQuery = () => {
+	page.current = 1;
+	getList();
+};
+const pagination = (obj) => {
+	page.current = obj.page;
+	page.size = obj.limit;
+	getList();
+};
+
+const getList = () => {
+	tableLoading.value = true;
+	waterBillListPage({ ...searchForm.value, ...page }).then((res) => {
+		tableLoading.value = false;
+		tableData.value = res.data.records;
+		page.total = res.data.total;
+	});
+};
+
+// 鎵撳紑寮规
+const openForm = (type, row) => {
+	nextTick(() => {
+		formDia.value?.openDialog(type, row)
+	})
+};
+
+const handleDelete = () => {
+	let ids = [];
+	if (selectedRows.value.length > 0) {
+		ids = selectedRows.value.map((item) => item.id);
+	} else {
+		proxy.$modal.msgWarning("璇烽�夋嫨鏁版嵁");
+		return;
+	}
+	ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚垹闄わ紝鏄惁纭鍒犻櫎锛�", "鍒犻櫎鎻愮ず", {
+		confirmButtonText: "纭",
+		cancelButtonText: "鍙栨秷",
+		type: "warning",
+	})
+		.then(() => {
+			tableLoading.value = true;
+			waterBillDelete(ids)
+				.then((res) => {
+					proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
+					getList();
+				})
+				.finally(() => {
+					tableLoading.value = false;
+				});
+		})
+		.catch(() => {
+			proxy.$modal.msg("宸插彇娑�");
+		});
+};
+onMounted(() => {
+	getList();
+});
+</script>
+
+<style scoped>
+
+</style>
diff --git a/src/views/energyManagement/waterManagement/waterTrends.vue b/src/views/energyManagement/waterManagement/waterTrends.vue
new file mode 100644
index 0000000..12e45fc
--- /dev/null
+++ b/src/views/energyManagement/waterManagement/waterTrends.vue
@@ -0,0 +1,118 @@
+<template>
+	<div class="app-container">
+		<div class="search_form">
+			<div>
+				<span class="search_title">璁惧鍚嶇О锛�</span>
+				<el-input
+					v-model="searchForm.name"
+					style="width: 240px"
+					placeholder="璇疯緭鍏�"
+					@change="handleQuery"
+					clearable
+					:prefix-icon="Search"
+				/>
+				<el-button type="primary" @click="handleQuery" style="margin-left: 10px"
+				>鎼滅储</el-button
+				>
+			</div>
+		</div>
+		<div class="table_list">
+			<PIMTable
+				rowKey="id"
+				:column="tableColumn"
+				:tableData="tableData"
+				:page="page"
+				:isSelection="true"
+				@selection-change="handleSelectionChange"
+				:tableLoading="tableLoading"
+				@pagination="pagination"
+			></PIMTable>
+		</div>
+	</div>
+</template>
+
+<script setup>
+import {Search} from "@element-plus/icons-vue";
+import {onMounted, ref, reactive} from "vue";
+import {listPageByWaterTrend} from "@/api/energyManagement/waterManagement.js";
+
+const data = reactive({
+	searchForm: {
+		name: "",
+	},
+});
+const { searchForm } = toRefs(data);
+
+const selectedRows = ref([]);
+const tableColumn = ref([
+	{
+		label: "璁惧鍚嶇О",
+		prop: "name",
+		width: 220,
+	},
+	{
+		label: "瑙勬牸鍨嬪彿",
+		prop: "code",
+		width: 220,
+	},
+	{
+		label: "杩愯鏃堕棿",
+		prop: "runDate",
+		width: 250,
+	},
+	{
+		label: "鏄ㄦ棩鐢ㄦ按閲�",
+		prop: "toDayNum",
+	},
+	{
+		label: "鏈湀骞冲潎姘撮噺",
+		prop: "avgNum",
+		width:150
+	},
+	{
+		label: "瓒嬪娍",
+		prop: "trend",
+		width: 220,
+	},
+]);
+const tableData = ref([]);
+const tableLoading = ref(false);
+const page = reactive({
+	current: 1,
+	size: 100,
+	total: 0,
+});
+// 琛ㄦ牸閫夋嫨鏁版嵁
+const handleSelectionChange = (selection) => {
+	selectedRows.value = selection;
+};
+
+// 鏌ヨ鍒楄〃
+/** 鎼滅储鎸夐挳鎿嶄綔 */
+const handleQuery = () => {
+	page.current = 1;
+	getList();
+};
+const pagination = (obj) => {
+	page.current = obj.page;
+	page.size = obj.limit;
+	getList();
+};
+
+const getList = () => {
+	tableLoading.value = true;
+	listPageByWaterTrend({ ...searchForm.value, ...page }).then((res) => {
+		tableLoading.value = false;
+		tableData.value = res.data.records;
+		page.total = res.data.total;
+	});
+};
+
+onMounted(() => {
+	getList();
+});
+</script>
+
+<style scoped>
+
+</style>
diff --git a/src/views/equipmentManagement/gasTank/simple.vue b/src/views/equipmentManagement/gasTank/simple.vue
new file mode 100644
index 0000000..92e88df
--- /dev/null
+++ b/src/views/equipmentManagement/gasTank/simple.vue
@@ -0,0 +1,566 @@
+<template>
+  <div class="app-container">
+    <!-- 椤甸潰鏍囬 -->
+    <div class="page-header">
+      <h2>閲嶅瀷缃愬紡璐ц溅鐩戞帶</h2>
+      <div class="header-actions">
+<!--        <el-button type="primary" @click="addTank">鏂板鍌ㄧ綈</el-button>-->
+<!--        <el-button @click="exportData">瀵煎嚭鏁版嵁</el-button>-->
+      </div>
+    </div>
+
+    <!-- 鍥涗釜涓昏妯″潡 -->
+    <div class="modules-container">
+      <!-- 1. 鍩烘湰淇℃伅妯″潡 -->
+      <el-card class="module-card">
+        <template #header>
+          <div class="card-header">
+            <span>1. 鍩烘湰淇℃伅</span>
+                         <el-button type="text" @click="handleEditBasicInfo">缂栬緫</el-button>
+          </div>
+        </template>
+        <div class="info-grid">
+          <div class="info-item">
+            <label>鍌ㄧ綈缂栧彿锛�</label>
+            <span>{{ basicInfo.tankCode }}</span>
+          </div>
+          <div class="info-item">
+            <label>鍌ㄧ綈鍚嶇О锛�</label>
+            <span>{{ basicInfo.tankName }}</span>
+          </div>
+          <div class="info-item">
+            <label>鍌ㄧ綈绫诲瀷锛�</label>
+            <span>{{ basicInfo.tankType }}</span>
+          </div>
+          <div class="info-item">
+            <label>璁捐鍘嬪姏锛�</label>
+            <span>{{ basicInfo.designPressure }} MPa</span>
+          </div>
+          <div class="info-item">
+            <label>宸ヤ綔鍘嬪姏锛�</label>
+            <span>{{ basicInfo.workingPressure }} MPa</span>
+          </div>
+          <div class="info-item">
+            <label>瀹圭Н锛�</label>
+            <span>{{ basicInfo.volume }} m鲁</span>
+          </div>
+        </div>
+      </el-card>
+
+      <!-- 2. 鐩戞祴鍙傛暟妯″潡 -->
+      <el-card class="module-card">
+        <template #header>
+          <div class="card-header">
+            <span>2. 鐩戞祴鍙傛暟</span>
+            <el-button type="text" @click="refreshMonitoring">鍒锋柊</el-button>
+          </div>
+        </template>
+        <div class="monitoring-grid">
+          <div class="monitor-item">
+            <div class="monitor-label">鍘嬪姏</div>
+            <div class="monitor-value" :class="getStatusClass(monitoringData.pressureStatus)">
+              {{ monitoringData.pressure }} MPa
+            </div>
+            <div class="monitor-status">{{ monitoringData.pressureStatus === 'normal' ? '姝e父' : '寮傚父' }}</div>
+          </div>
+          <div class="monitor-item">
+            <div class="monitor-label">娓╁害</div>
+            <div class="monitor-value" :class="getStatusClass(monitoringData.temperatureStatus)">
+              {{ monitoringData.temperature }} 鈩�
+            </div>
+            <div class="monitor-status">{{ monitoringData.temperatureStatus === 'normal' ? '姝e父' : '寮傚父' }}</div>
+          </div>
+          <div class="monitor-item">
+            <div class="monitor-label">姘斾綋娴撳害</div>
+            <div class="monitor-value" :class="getStatusClass(monitoringData.gasStatus)">
+              {{ monitoringData.gasConcentration }} ppm
+            </div>
+            <div class="monitor-status">{{ monitoringData.gasStatus === 'normal' ? '姝e父' : '寮傚父' }}</div>
+          </div>
+          <div class="monitor-item">
+            <div class="monitor-label">娴侀噺</div>
+            <div class="monitor-value" :class="getStatusClass(monitoringData.flowStatus)">
+              {{ monitoringData.flow }} m鲁/h
+            </div>
+            <div class="monitor-status">{{ monitoringData.flowStatus === 'normal' ? '姝e父' : '寮傚父' }}</div>
+          </div>
+        </div>
+      </el-card>
+
+      <!-- 3. 瀹夊叏瑁呯疆妯″潡 -->
+      <el-card class="module-card">
+        <template #header>
+          <div class="card-header">
+            <span>3. 瀹夊叏瑁呯疆</span>
+            <el-button type="text" @click="checkSafetyDevices">妫�鏌�</el-button>
+          </div>
+        </template>
+        <div class="safety-grid">
+          <div class="safety-item" v-for="device in safetyDevices" :key="device.name">
+            
+            <div class="device-info">
+              <div class="device-name">{{ device.name }}</div>
+              <div class="device-status" :class="device.status">
+                {{ device.status === 'normal' ? '姝e父' : '寮傚父' }}
+              </div>
+            </div>
+          </div>
+        </div>
+      </el-card>
+
+      <!-- 4. 缁存姢璁板綍妯″潡 -->
+      <el-card class="module-card">
+        <template #header>
+          <div class="card-header">
+            <span>4. 缁存姢璁板綍</span>
+            <el-button type="text" @click="addMaintenanceRecord">娣诲姞璁板綍</el-button>
+          </div>
+        </template>
+        <div class="maintenance-list">
+          <div class="maintenance-item" v-for="record in maintenanceRecords" :key="record.id">
+            <div class="record-header">
+              <span class="record-date">{{ record.date }}</span>
+              <el-tag :type="record.type === 'inspection' ? 'primary' : 'success'" size="small">
+                {{ record.type === 'inspection' ? '妫�楠�' : '缁存姢' }}
+              </el-tag>
+            </div>
+            <div class="record-content">
+              <div class="record-title">{{ record.title }}</div>
+              <div class="record-desc">{{ record.description }}</div>
+              <div class="record-operator">鎿嶄綔浜猴細{{ record.operator }}</div>
+            </div>
+          </div>
+        </div>
+      </el-card>
+    </div>
+
+    <!-- 缂栬緫鍩烘湰淇℃伅寮圭獥 -->
+    <el-dialog v-model="basicInfoDialogVisible" title="缂栬緫鍩烘湰淇℃伅" width="600px">
+      <el-form :model="editBasicInfo" label-width="120px">
+        <el-form-item label="鍌ㄧ綈缂栧彿">
+          <el-input v-model="editBasicInfo.tankCode" />
+        </el-form-item>
+        <el-form-item label="鍌ㄧ綈鍚嶇О">
+          <el-input v-model="editBasicInfo.tankName" />
+        </el-form-item>
+        <el-form-item label="鍌ㄧ綈绫诲瀷">
+          <el-select v-model="editBasicInfo.tankType" style="width: 100%">
+            <el-option label="娑插寲姘斾綋鍌ㄧ綈" value="娑插寲姘斾綋鍌ㄧ綈" />
+            <el-option label="鍘嬪姏瀹瑰櫒" value="鍘嬪姏瀹瑰櫒" />
+            <el-option label="甯稿帇鍌ㄧ綈" value="甯稿帇鍌ㄧ綈" />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="璁捐鍘嬪姏">
+          <el-input-number v-model="editBasicInfo.designPressure" :precision="2" style="width: 100%" />
+        </el-form-item>
+        <el-form-item label="宸ヤ綔鍘嬪姏">
+          <el-input-number v-model="editBasicInfo.workingPressure" :precision="2" style="width: 100%" />
+        </el-form-item>
+        <el-form-item label="瀹圭Н">
+          <el-input-number v-model="editBasicInfo.volume" :precision="2" style="width: 100%" />
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <el-button @click="basicInfoDialogVisible = false">鍙栨秷</el-button>
+        <el-button type="primary" @click="saveBasicInfo">淇濆瓨</el-button>
+      </template>
+    </el-dialog>
+
+    <!-- 娣诲姞缁存姢璁板綍寮圭獥 -->
+    <el-dialog v-model="maintenanceDialogVisible" title="娣诲姞缁存姢璁板綍" width="600px">
+      <el-form :model="newMaintenanceRecord" label-width="120px">
+        <el-form-item label="璁板綍绫诲瀷">
+          <el-select v-model="newMaintenanceRecord.type" style="width: 100%">
+            <el-option label="妫�楠�" value="inspection" />
+            <el-option label="缁存姢" value="maintenance" />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="鏍囬">
+          <el-input v-model="newMaintenanceRecord.title" />
+        </el-form-item>
+        <el-form-item label="鎻忚堪">
+          <el-input type="textarea" v-model="newMaintenanceRecord.description" :rows="3" />
+        </el-form-item>
+        <el-form-item label="鎿嶄綔浜�">
+          <el-input v-model="newMaintenanceRecord.operator" />
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <el-button @click="maintenanceDialogVisible = false">鍙栨秷</el-button>
+        <el-button type="primary" @click="saveMaintenanceRecord">淇濆瓨</el-button>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
+<script setup>
+import { ref, reactive, onMounted } from 'vue'
+import { ElMessage } from 'element-plus'
+
+// 鍩烘湰淇℃伅
+const basicInfo = reactive({
+  tankCode: 'GT001',
+  tankName: '娑插寲姘斿偍缃怉',
+  tankType: '娑插寲姘斾綋鍌ㄧ綈',
+  designPressure: 1.6,
+  workingPressure: 0.8,
+  volume: 100.5
+})
+
+// 鐩戞祴鍙傛暟
+const monitoringData = reactive({
+  pressure: 0.8,
+  pressureStatus: 'normal',
+  temperature: 25.5,
+  temperatureStatus: 'normal',
+  gasConcentration: 0.1,
+  gasStatus: 'normal',
+  flow: 15.2,
+  flowStatus: 'normal'
+})
+
+// 瀹夊叏瑁呯疆
+const safetyDevices = ref([
+  { name: '瀹夊叏闃�', status: 'normal' },
+  { name: '鍘嬪姏浼犳劅鍣�', status: 'normal' },
+  { name: '娓╁害浼犳劅鍣�', status: 'normal' },
+  { name: '姘斾綋妫�娴嬪櫒', status: 'normal' },
+  { name: '鐖嗙牬鐗�', status: 'normal' },
+  { name: '娉勫帇瑁呯疆', status: 'normal' }
+])
+
+// 缁存姢璁板綍
+const maintenanceRecords = ref([
+  {
+    id: 1,
+    date: '2024-01-15',
+    type: 'inspection',
+    title: '骞村害妫�楠�',
+    description: '鎸夌収TSG 21-2016鏍囧噯杩涜骞村害妫�楠岋紝璁惧鐘舵�佽壇濂�',
+    operator: '寮犲伐绋嬪笀'
+  },
+  {
+    id: 2,
+    date: '2024-02-20',
+    type: 'maintenance',
+    title: '瀹夊叏闃�缁存姢',
+    description: '鏇存崲瀹夊叏闃�瀵嗗皝鍦堬紝鏍″噯鍘嬪姏璁惧畾鍊�',
+    operator: '鏉庢妧甯�'
+  },
+  {
+    id: 3,
+    date: '2024-03-10',
+    type: 'inspection',
+    title: '鍘嬪姏娴嬭瘯',
+    description: '杩涜鍘嬪姏瀹瑰櫒姘村帇璇曢獙锛岀鍚堣璁¤姹�',
+    operator: '鐜嬫楠屽憳'
+  }
+])
+
+// 寮圭獥鎺у埗
+const basicInfoDialogVisible = ref(false)
+const maintenanceDialogVisible = ref(false)
+
+// 缂栬緫琛ㄥ崟鏁版嵁
+const editBasicInfo = reactive({ ...basicInfo })
+const newMaintenanceRecord = reactive({
+  type: 'inspection',
+  title: '',
+  description: '',
+  operator: ''
+})
+
+// 鑾峰彇鐘舵�佹牱寮忕被
+const getStatusClass = (status) => {
+  return status === 'normal' ? 'status-normal' : 'status-warning'
+}
+
+// 鏂板鍌ㄧ綈
+const addTank = () => {
+  ElMessage.success('鏂板鍌ㄧ綈鍔熻兘')
+}
+
+// 瀵煎嚭鏁版嵁
+const exportData = () => {
+  ElMessage.success('瀵煎嚭鎴愬姛')
+}
+
+// 缂栬緫鍩烘湰淇℃伅
+const handleEditBasicInfo = () => {
+  Object.assign(editBasicInfo, basicInfo)
+  basicInfoDialogVisible.value = true
+}
+
+// 淇濆瓨鍩烘湰淇℃伅
+const saveBasicInfo = () => {
+  Object.assign(basicInfo, editBasicInfo)
+  basicInfoDialogVisible.value = false
+  ElMessage.success('淇濆瓨鎴愬姛')
+}
+
+// 鍒锋柊鐩戞祴鏁版嵁
+const refreshMonitoring = () => {
+  // 妯℃嫙鏁版嵁鏇存柊
+  monitoringData.pressure = (Math.random() * 0.5 + 0.6).toFixed(2)
+  monitoringData.temperature = (Math.random() * 10 + 20).toFixed(1)
+  monitoringData.gasConcentration = (Math.random() * 0.2).toFixed(2)
+  monitoringData.flow = (Math.random() * 10 + 10).toFixed(1)
+  ElMessage.success('鏁版嵁宸插埛鏂�')
+}
+
+// 妫�鏌ュ畨鍏ㄨ缃�
+const checkSafetyDevices = () => {
+  // 妯℃嫙妫�鏌ヨ繃绋�
+  safetyDevices.value.forEach(device => {
+    device.status = Math.random() > 0.1 ? 'normal' : 'warning'
+  })
+  ElMessage.success('瀹夊叏瑁呯疆妫�鏌ュ畬鎴�')
+}
+
+// 娣诲姞缁存姢璁板綍
+const addMaintenanceRecord = () => {
+  newMaintenanceRecord.type = 'inspection'
+  newMaintenanceRecord.title = ''
+  newMaintenanceRecord.description = ''
+  newMaintenanceRecord.operator = ''
+  maintenanceDialogVisible.value = true
+}
+
+// 淇濆瓨缁存姢璁板綍
+const saveMaintenanceRecord = () => {
+  const record = {
+    id: Date.now(),
+    date: new Date().toISOString().split('T')[0],
+    ...newMaintenanceRecord
+  }
+  maintenanceRecords.value.unshift(record)
+  maintenanceDialogVisible.value = false
+  ElMessage.success('璁板綍娣诲姞鎴愬姛')
+}
+
+// 妯℃嫙瀹炴椂鏁版嵁鏇存柊
+onMounted(() => {
+  setInterval(() => {
+    monitoringData.pressure = (Math.random() * 0.5 + 0.6).toFixed(2)
+    monitoringData.temperature = (Math.random() * 10 + 20).toFixed(1)
+    monitoringData.gasConcentration = (Math.random() * 0.2).toFixed(2)
+    monitoringData.flow = (Math.random() * 10 + 10).toFixed(1)
+  }, 5000)
+})
+</script>
+
+<style lang="scss" scoped>
+.app-container {
+  padding: 20px;
+  background: #f5f5f5;
+  min-height: 100vh;
+}
+
+.page-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  margin-bottom: 20px;
+  padding: 20px;
+  background: white;
+  border-radius: 8px;
+  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
+
+  h2 {
+    margin: 0;
+    color: #303133;
+  }
+
+  .header-actions {
+    display: flex;
+    gap: 10px;
+  }
+}
+
+.modules-container {
+  display: grid;
+  grid-template-columns: repeat(2, 1fr);
+  gap: 20px;
+}
+
+.module-card {
+  .card-header {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    font-weight: bold;
+    color: #303133;
+  }
+}
+
+.info-grid {
+  display: grid;
+  grid-template-columns: repeat(2, 1fr);
+  gap: 15px;
+
+  .info-item {
+    display: flex;
+    justify-content: space-between;
+    padding: 10px;
+    background: #f8f9fa;
+    border-radius: 4px;
+
+    label {
+      font-weight: bold;
+      color: #606266;
+    }
+
+    span {
+      color: #303133;
+    }
+  }
+}
+
+.monitoring-grid {
+  display: grid;
+  grid-template-columns: repeat(2, 1fr);
+  gap: 15px;
+
+  .monitor-item {
+    text-align: center;
+    padding: 15px;
+    background: #f8f9fa;
+    border-radius: 8px;
+    border: 2px solid transparent;
+
+    .monitor-label {
+      font-size: 14px;
+      color: #606266;
+      margin-bottom: 8px;
+    }
+
+    .monitor-value {
+      font-size: 20px;
+      font-weight: bold;
+      margin-bottom: 5px;
+
+      &.status-normal {
+        color: #67c23a;
+      }
+
+      &.status-warning {
+        color: #e6a23c;
+      }
+    }
+
+    .monitor-status {
+      font-size: 12px;
+      color: #909399;
+    }
+  }
+}
+
+.safety-grid {
+  display: grid;
+  grid-template-columns: repeat(2, 1fr);
+  gap: 15px;
+
+  .safety-item {
+    display: flex;
+    align-items: center;
+    padding: 15px;
+    background: #f8f9fa;
+    border-radius: 8px;
+    border: 2px solid transparent;
+
+    .device-icon {
+      margin-right: 15px;
+    }
+
+    .device-info {
+      flex: 1;
+
+      .device-name {
+        font-weight: bold;
+        color: #303133;
+        margin-bottom: 5px;
+      }
+
+      .device-status {
+        font-size: 12px;
+        padding: 2px 8px;
+        border-radius: 10px;
+        display: inline-block;
+
+        &.normal {
+          background: #f0f9ff;
+          color: #409eff;
+        }
+
+        &.warning {
+          background: #fef7e0;
+          color: #e6a23c;
+        }
+      }
+    }
+  }
+}
+
+.maintenance-list {
+  max-height: 300px;
+  overflow-y: auto;
+
+  .maintenance-item {
+    padding: 15px;
+    border-bottom: 1px solid #ebeef5;
+    margin-bottom: 10px;
+
+    &:last-child {
+      border-bottom: none;
+      margin-bottom: 0;
+    }
+
+    .record-header {
+      display: flex;
+      justify-content: space-between;
+      align-items: center;
+      margin-bottom: 8px;
+
+      .record-date {
+        font-size: 14px;
+        color: #909399;
+      }
+    }
+
+    .record-content {
+      .record-title {
+        font-weight: bold;
+        color: #303133;
+        margin-bottom: 5px;
+      }
+
+      .record-desc {
+        font-size: 14px;
+        color: #606266;
+        margin-bottom: 5px;
+        line-height: 1.4;
+      }
+
+      .record-operator {
+        font-size: 12px;
+        color: #909399;
+      }
+    }
+  }
+}
+
+// 鍝嶅簲寮忚璁�
+@media (max-width: 1200px) {
+  .modules-container {
+    grid-template-columns: 1fr;
+  }
+}
+
+@media (max-width: 768px) {
+  .info-grid,
+  .monitoring-grid,
+  .safety-grid {
+    grid-template-columns: 1fr;
+  }
+}
+</style>
diff --git a/src/views/inventoryManagement/stockWarning/index.vue b/src/views/inventoryManagement/stockWarning/index.vue
new file mode 100644
index 0000000..3694265
--- /dev/null
+++ b/src/views/inventoryManagement/stockWarning/index.vue
@@ -0,0 +1,1137 @@
+<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
+})
+
+// 鎼滅储琛ㄥ崟
+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 generateMockData = () => {
+  const mockData = [
+    {
+      id: 1,
+      tankCode: 'TANK001',
+      tankName: '娑插寲姘斿偍缃怉',
+      tankType: '娑插寲姘斿偍缃�',
+      specificationModel: 'LPG-5000L',
+      volume: 5000,
+      currentGasLevel: 15,
+      safetyGasLevel: 30,
+      minGasLevel: 10,
+      maxGasLevel: 95,
+      currentPressure: 2.5,
+      warningType: '姘斾綋涓嶈冻',
+      warningLevel: '绱ф��',
+      warningThreshold: 20,
+      isEnabled: true,
+      warningTime: '2024-01-15 08:30:00',
+      warningDuration: 3,
+      lastUpdateTime: '2024-01-15 10:00:00',
+      expectedRefillTime: '2024-01-16 14:00:00',
+      expectedShortageTime: '2024-01-15 18:30:00', // 浠婂ぉ涓嬪崍6:30缂烘皵
+      warningRule: '褰撴皵浣撻噺浣庝簬20%鏃惰Е鍙戦璀�'
+    },
+    {
+      id: 2,
+      tankCode: 'TANK002',
+      tankName: '鍘嬬缉姘斿偍缃怋',
+      tankType: '鍘嬬缉姘斿偍缃�',
+      specificationModel: 'COMP-3000L',
+      volume: 3000,
+      currentGasLevel: 45,
+      safetyGasLevel: 25,
+      minGasLevel: 15,
+      maxGasLevel: 90,
+      currentPressure: 8.2,
+      warningType: '鍘嬪姏寮傚父',
+      warningLevel: '閲嶈',
+      warningThreshold: 10,
+      isEnabled: true,
+      warningTime: '2024-01-14 16:20:00',
+      warningDuration: 2,
+      lastUpdateTime: '2024-01-15 09:15:00',
+      expectedRefillTime: '2024-01-17 09:00:00',
+      expectedShortageTime: '2024-01-18 12:00:00', // 3澶╁悗缂烘皵
+      warningRule: '褰撳帇鍔涜秴杩�8MPa鏃惰Е鍙戦璀�'
+    },
+    {
+      id: 3,
+      tankCode: 'TANK003',
+      tankName: '澶╃劧姘斿偍缃怌',
+      tankType: '澶╃劧姘斿偍缃�',
+      specificationModel: 'NG-8000L',
+      volume: 8000,
+      currentGasLevel: 75,
+      safetyGasLevel: 20,
+      minGasLevel: 10,
+      maxGasLevel: 95,
+      currentPressure: 4.8,
+      warningType: '娓╁害寮傚父',
+      warningLevel: '涓�鑸�',
+      warningThreshold: 5,
+      isEnabled: true,
+      warningTime: '2024-01-13 11:45:00',
+      warningDuration: 1,
+      lastUpdateTime: '2024-01-15 08:45:00',
+      expectedRefillTime: '2024-01-20 10:00:00',
+      expectedShortageTime: '2024-01-22 15:30:00', // 7澶╁悗缂烘皵
+      warningRule: '褰撴俯搴﹁秴杩�60掳C鏃惰Е鍙戦璀�'
+    },
+    {
+      id: 4,
+      tankCode: 'TANK004',
+      tankName: '姘ф皵鍌ㄧ綈D',
+      tankType: '姘ф皵鍌ㄧ綈',
+      specificationModel: 'O2-2000L',
+      volume: 2000,
+      currentGasLevel: 8,
+      safetyGasLevel: 25,
+      minGasLevel: 5,
+      maxGasLevel: 90,
+      currentPressure: 6.5,
+      warningType: '娉勬紡棰勮',
+      warningLevel: '绱ф��',
+      warningThreshold: 15,
+      isEnabled: true,
+      warningTime: '2024-01-15 07:15:00',
+      warningDuration: 4,
+      lastUpdateTime: '2024-01-15 11:30:00',
+      expectedRefillTime: '2024-01-15 16:00:00',
+      expectedShortageTime: '2024-01-15 14:00:00', // 浠婂ぉ涓嬪崍2鐐圭己姘�
+      warningRule: '褰撴娴嬪埌姘斾綋娉勬紡鏃惰Е鍙戦璀�'
+    },
+    {
+      id: 5,
+      tankCode: 'TANK005',
+      tankName: '娑插寲姘斿偍缃怑',
+      tankType: '娑插寲姘斿偍缃�',
+      specificationModel: 'LPG-6000L',
+      volume: 6000,
+      currentGasLevel: 35,
+      safetyGasLevel: 30,
+      minGasLevel: 15,
+      maxGasLevel: 95,
+      currentPressure: 3.2,
+      warningType: '姘斾綋涓嶈冻',
+      warningLevel: '閲嶈',
+      warningThreshold: 20,
+      isEnabled: false,
+      warningTime: '2024-01-14 14:30:00',
+      warningDuration: 2,
+      lastUpdateTime: '2024-01-15 09:00:00',
+      expectedRefillTime: '2024-01-19 08:00:00',
+      expectedShortageTime: '2024-01-21 10:00:00', // 6澶╁悗缂烘皵
+      warningRule: '褰撴皵浣撻噺浣庝簬20%鏃惰Е鍙戦璀�'
+    },
+    {
+      id: 6,
+      tankCode: 'TANK006',
+      tankName: '鍘嬬缉姘斿偍缃怓',
+      tankType: '鍘嬬缉姘斿偍缃�',
+      specificationModel: 'COMP-4000L',
+      volume: 4000,
+      currentGasLevel: 85,
+      safetyGasLevel: 20,
+      minGasLevel: 10,
+      maxGasLevel: 90,
+      currentPressure: 7.8,
+      warningType: '鍘嬪姏寮傚父',
+      warningLevel: '涓�鑸�',
+      warningThreshold: 8,
+      isEnabled: true,
+      warningTime: '2024-01-12 09:20:00',
+      warningDuration: 1,
+      lastUpdateTime: '2024-01-15 08:30:00',
+      expectedRefillTime: '2024-01-25 14:00:00',
+      expectedShortageTime: '2024-01-28 16:00:00', // 13澶╁悗缂烘皵
+      warningRule: '褰撳帇鍔涜秴杩�8MPa鏃惰Е鍙戦璀�'
+    },
+    {
+      id: 7,
+      tankCode: 'TANK007',
+      tankName: '澶╃劧姘斿偍缃怗',
+      tankType: '澶╃劧姘斿偍缃�',
+      specificationModel: 'NG-10000L',
+      volume: 10000,
+      currentGasLevel: 92,
+      safetyGasLevel: 15,
+      minGasLevel: 8,
+      maxGasLevel: 95,
+      currentPressure: 5.2,
+      warningType: '娓╁害寮傚父',
+      warningLevel: '閲嶈',
+      warningThreshold: 6,
+      isEnabled: true,
+      warningTime: '2024-01-11 16:45:00',
+      warningDuration: 1,
+      lastUpdateTime: '2024-01-15 07:45:00',
+      expectedRefillTime: '2024-01-30 09:00:00',
+      expectedShortageTime: '2024-02-05 12:00:00', // 21澶╁悗缂烘皵
+      warningRule: '褰撴俯搴﹁秴杩�60掳C鏃惰Е鍙戦璀�'
+    },
+    {
+      id: 8,
+      tankCode: 'TANK008',
+      tankName: '姘ф皵鍌ㄧ綈H',
+      tankType: '姘ф皵鍌ㄧ綈',
+      specificationModel: 'O2-1500L',
+      volume: 1500,
+      currentGasLevel: 12,
+      safetyGasLevel: 30,
+      minGasLevel: 8,
+      maxGasLevel: 90,
+      currentPressure: 4.5,
+      warningType: '娉勬紡棰勮',
+      warningLevel: '绱ф��',
+      warningThreshold: 12,
+      isEnabled: true,
+      warningTime: '2024-01-15 06:30:00',
+      warningDuration: 5,
+      lastUpdateTime: '2024-01-15 12:15:00',
+      expectedRefillTime: '2024-01-15 20:00:00',
+      expectedShortageTime: '2024-01-15 17:30:00', // 浠婂ぉ涓嬪崍5:30缂烘皵
+      warningRule: '褰撴娴嬪埌姘斾綋娉勬紡鏃惰Е鍙戦璀�'
+    }
+  ]
+  
+  // 鏍规嵁鎼滅储鏉′欢杩囨护鏁版嵁
+  let filteredData = mockData.filter(item => {
+    if (searchForm.tankName && !item.tankName.includes(searchForm.tankName)) return false
+    if (searchForm.tankType && item.tankType !== searchForm.tankType) return false
+    if (searchForm.warningType && item.warningType !== searchForm.warningType) return false
+    if (searchForm.warningLevel && item.warningLevel !== searchForm.warningLevel) return false
+    return true
+  })
+  
+  // 鍒嗛〉澶勭悊
+  const start = (page.current - 1) * page.size
+  const end = start + page.size
+  const paginatedData = filteredData.slice(start, end)
+  
+  return {
+    records: paginatedData,
+    total: filteredData.length
+  }
+}
+
+// 鑾峰彇鍒楄〃鏁版嵁
+const getList = async () => {
+  tableLoading.value = true
+  try {
+    // 妯℃嫙缃戠粶寤惰繜
+    await new Promise(resolve => setTimeout(resolve, 500))
+    
+    const result = generateMockData()
+    tableData.value = result.records
+    total.value = result.total
+    
+    // 妫�鏌ョ己姘旈璀�
+    checkShortageWarnings()
+  } catch (error) {
+    console.error('鑾峰彇鍒楄〃澶辫触:', error)
+    ElMessage.error('鑾峰彇鍒楄〃澶辫触')
+  } finally {
+    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'
+    })
+    
+    // 妯℃嫙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 () => {
+  try {
+    // 妯℃嫙API璋冪敤寤惰繜
+    await new Promise(resolve => setTimeout(resolve, 800))
+    
+    // 鐢熸垚瀵煎嚭鏁版嵁
+    const exportData = generateMockData().records
+    const csvContent = generateCSV(exportData)
+    
+    // 鍒涘缓涓嬭浇閾炬帴
+    const blob = new Blob([csvContent], { 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)
+    
+    ElMessage.success('瀵煎嚭鎴愬姛')
+  } catch (error) {
+    ElMessage.error('瀵煎嚭澶辫触')
+  }
+}
+
+// 鐢熸垚CSV鍐呭
+const generateCSV = (data) => {
+  const headers = [
+    '鍌ㄦ皵缃愮紪鐮�', '鍌ㄦ皵缃愬悕绉�', '鍌ㄦ皵缃愮被鍨�', '瑙勬牸鍨嬪彿', '瀹圭Н(m鲁)', 
+    '褰撳墠姘斾綋閲�(%)', '瀹夊叏姘斾綋閲�(%)', '鏈�浣庢皵浣撻噺(%)', '鏈�楂樻皵浣撻噺(%)', 
+    '褰撳墠鍘嬪姏(MPa)', '棰勮绫诲瀷', '棰勮绾у埆', '棰勮闃堝��', '鏄惁鍚敤',
+    '棰勮鏃堕棿', '棰勮鎸佺画澶╂暟', '鏈�鍚庢洿鏂版椂闂�', '棰勮鍏呰鏃堕棿', '棰勮缂烘皵鏃堕棿', '棰勮瑙勫垯鎻忚堪'
+  ]
+  
+  const csvRows = [headers.join(',')]
+  
+  data.forEach(item => {
+    const row = [
+      item.tankCode,
+      item.tankName,
+      item.tankType,
+      item.specificationModel,
+      item.volume,
+      item.currentGasLevel,
+      item.safetyGasLevel,
+      item.minGasLevel,
+      item.maxGasLevel,
+      item.currentPressure,
+      item.warningType,
+      item.warningLevel,
+      item.warningThreshold,
+      item.isEnabled ? '鏄�' : '鍚�',
+      item.warningTime,
+      item.warningDuration,
+      item.lastUpdateTime,
+      item.expectedRefillTime,
+      item.expectedShortageTime,
+      item.warningRule
+    ]
+    csvRows.push(row.join(','))
+  })
+  
+  return csvRows.join('\n')
+}
+
+// 鍚敤鐘舵�佸彉鍖�
+const handleEnableChange = async (row) => {
+  try {
+    // 妯℃嫙API璋冪敤寤惰繜
+    await new Promise(resolve => setTimeout(resolve, 200))
+    ElMessage.success(`${row.tankName} 鐨勫惎鐢ㄧ姸鎬佸凡鏇存柊`)
+  } 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') {
+      ElMessage.success('鏂板鎴愬姛')
+    } else {
+      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