From b8da78824e4c67632abb65302f01ccf74d5a1096 Mon Sep 17 00:00:00 2001
From: zouyu <2723363702@qq.com>
Date: 星期二, 26 五月 2026 18:45:51 +0800
Subject: [PATCH] 浪潮对接:芯导-安环管理系统,配置调整

---
 src/views/safetyManagement/basicInfo/index.vue |  931 +++++++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 893 insertions(+), 38 deletions(-)

diff --git a/src/views/safetyManagement/basicInfo/index.vue b/src/views/safetyManagement/basicInfo/index.vue
index ce0160e..a640aa5 100644
--- a/src/views/safetyManagement/basicInfo/index.vue
+++ b/src/views/safetyManagement/basicInfo/index.vue
@@ -18,7 +18,7 @@
           <div class="actions">
             <el-button type="primary" @click="addPersonnel" icon="Plus">鏂板</el-button>
           </div>
-          <PIMTable :column="personnelColumns" :tableData="personnelList" :page="personnelPage" @pagination="changePersonnelPage" />
+          <PIMTable :column="personnelColumns" :tableData="personnelList" :page="personnelPage" @pagination="changePersonnelPage" :tableLoading="personnelLoading" />
         </div>
       </el-tab-pane>
 
@@ -28,7 +28,7 @@
             <el-input v-model="equipmentFilters.name" placeholder="璇疯緭鍏ヨ澶囧悕绉�" clearable style="width: 200px" />
           </el-form-item>
           <el-form-item label="鎵�灞炲尯鍩�">
-            <el-input v-model="equipmentFilters.area" placeholder="璇疯緭鍏ユ墍灞炲尯鍩�" clearable style="width: 200px" />
+            <el-input v-model="equipmentFilters.areaName" placeholder="璇疯緭鍏ユ墍灞炲尯鍩�" clearable style="width: 200px" />
           </el-form-item>
           <el-form-item>
             <el-button type="primary" @click="getEquipmentData">鎼滅储</el-button>
@@ -39,7 +39,7 @@
           <div class="actions">
             <el-button type="primary" @click="addEquipment" icon="Plus">鏂板</el-button>
           </div>
-          <PIMTable :column="equipmentColumns" :tableData="equipmentList" :page="equipmentPage" @pagination="changeEquipmentPage" />
+          <PIMTable :column="equipmentColumns" :tableData="equipmentList" :page="equipmentPage" @pagination="changeEquipmentPage" :tableLoading="equipmentLoading" />
         </div>
       </el-tab-pane>
 
@@ -57,7 +57,7 @@
           <div class="actions">
             <el-button type="primary" @click="addArea" icon="Plus">鏂板</el-button>
           </div>
-          <PIMTable :column="areaColumns" :tableData="areaList" :page="areaPage" @pagination="changeAreaPage" />
+          <PIMTable :column="areaColumns" :tableData="areaList" :page="areaPage" @pagination="changeAreaPage" :tableLoading="areaLoading" />
         </div>
       </el-tab-pane>
 
@@ -75,7 +75,7 @@
           <div class="actions">
             <el-button type="primary" @click="addRisk" icon="Plus">鏂板</el-button>
           </div>
-          <PIMTable :column="riskColumns" :tableData="riskList" :page="riskPage" @pagination="changeRiskPage" />
+          <PIMTable :column="riskColumns" :tableData="riskList" :page="riskPage" @pagination="changeRiskPage" :tableLoading="riskLoading" />
         </div>
       </el-tab-pane>
 
@@ -93,16 +93,197 @@
           <div class="actions">
             <el-button type="primary" @click="addEmergency" icon="Plus">鏂板</el-button>
           </div>
-          <PIMTable :column="emergencyColumns" :tableData="emergencyList" :page="emergencyPage" @pagination="changeEmergencyPage" />
+          <PIMTable :column="emergencyColumns" :tableData="emergencyList" :page="emergencyPage" @pagination="changeEmergencyPage" :tableLoading="emergencyLoading" />
         </div>
       </el-tab-pane>
     </el-tabs>
+
+    <!-- 浜哄憳妗f寮圭獥 -->
+    <el-dialog :title="personnelDialog.title" v-model="personnelDialog.visible" width="600px" append-to-body>
+      <el-form ref="personnelFormRef" :model="personnelForm" :rules="personnelRules" label-width="100px">
+        <el-form-item label="濮撳悕" prop="name">
+          <el-input v-model="personnelForm.name" placeholder="璇疯緭鍏ュ鍚�" />
+        </el-form-item>
+        <el-form-item label="閮ㄩ棬" prop="dept">
+          <el-input v-model="personnelForm.dept" placeholder="璇疯緭鍏ラ儴闂�" />
+        </el-form-item>
+        <el-form-item label="宀椾綅" prop="post">
+          <el-input v-model="personnelForm.post" placeholder="璇疯緭鍏ュ矖浣�" />
+        </el-form-item>
+        <el-form-item label="鑱旂郴鏂瑰紡" prop="phone">
+          <el-input v-model="personnelForm.phone" placeholder="璇疯緭鍏ヨ仈绯绘柟寮�" />
+        </el-form-item>
+        <el-form-item label="鍏ヨ亴鏃ユ湡" prop="entryDate">
+          <el-date-picker v-model="personnelForm.entryDate" type="date" placeholder="閫夋嫨鍏ヨ亴鏃ユ湡" value-format="YYYY-MM-DD" style="width: 100%" />
+        </el-form-item>
+        <el-form-item label="鐘舵��" prop="status">
+          <el-radio-group v-model="personnelForm.status">
+            <el-radio :value="1">鍦ㄨ亴</el-radio>
+            <el-radio :value="0">绂昏亴</el-radio>
+          </el-radio-group>
+        </el-form-item>
+        <el-form-item label="澶囨敞" prop="remark">
+          <el-input v-model="personnelForm.remark" type="textarea" :rows="3" placeholder="璇疯緭鍏ュ娉�" />
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <el-button @click="personnelDialog.visible = false">鍙� 娑�</el-button>
+        <el-button type="primary" @click="submitPersonnelForm" :loading="personnelDialog.loading">纭� 瀹�</el-button>
+      </template>
+    </el-dialog>
+
+    <!-- 璁惧璁炬柦寮圭獥 -->
+    <el-dialog :title="equipmentDialog.title" v-model="equipmentDialog.visible" width="600px" append-to-body>
+      <el-form ref="equipmentFormRef" :model="equipmentForm" :rules="equipmentRules" label-width="100px">
+        <el-form-item label="璁惧鍚嶇О" prop="name">
+          <el-input v-model="equipmentForm.name" placeholder="璇疯緭鍏ヨ澶囧悕绉�" />
+        </el-form-item>
+        <el-form-item label="瑙勬牸鍨嬪彿" prop="model">
+          <el-input v-model="equipmentForm.model" placeholder="璇疯緭鍏ヨ鏍煎瀷鍙�" />
+        </el-form-item>
+        <el-form-item label="鎵�灞炲尯鍩�" prop="areaName">
+          <el-input v-model="equipmentForm.areaName" placeholder="璇疯緭鍏ユ墍灞炲尯鍩�" />
+        </el-form-item>
+        <el-form-item label="鐘舵��" prop="status">
+          <el-radio-group v-model="equipmentForm.status">
+            <el-radio :value="1">姝e父</el-radio>
+            <el-radio :value="0">鍋滅敤</el-radio>
+          </el-radio-group>
+        </el-form-item>
+        <el-form-item label="澶囨敞" prop="remark">
+          <el-input v-model="equipmentForm.remark" type="textarea" :rows="3" placeholder="璇疯緭鍏ュ娉�" />
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <el-button @click="equipmentDialog.visible = false">鍙� 娑�</el-button>
+        <el-button type="primary" @click="submitEquipmentForm" :loading="equipmentDialog.loading">纭� 瀹�</el-button>
+      </template>
+    </el-dialog>
+
+    <!-- 浣滀笟鍖哄煙寮圭獥 -->
+    <el-dialog :title="areaDialog.title" v-model="areaDialog.visible" width="600px" append-to-body>
+      <el-form ref="areaFormRef" :model="areaForm" :rules="areaRules" label-width="100px">
+        <el-form-item label="鍖哄煙鍚嶇О" prop="name">
+          <el-input v-model="areaForm.name" placeholder="璇疯緭鍏ュ尯鍩熷悕绉�" />
+        </el-form-item>
+        <el-form-item label="浣嶇疆" prop="location">
+          <el-input v-model="areaForm.location" placeholder="璇疯緭鍏ヤ綅缃�" />
+        </el-form-item>
+        <el-form-item label="璐熻矗浜�" prop="manager">
+          <el-input v-model="areaForm.manager" placeholder="璇疯緭鍏ヨ礋璐d汉" />
+        </el-form-item>
+        <el-form-item label="澶囨敞" prop="remark">
+          <el-input v-model="areaForm.remark" type="textarea" :rows="3" placeholder="璇疯緭鍏ュ娉�" />
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <el-button @click="areaDialog.visible = false">鍙� 娑�</el-button>
+        <el-button type="primary" @click="submitAreaForm" :loading="areaDialog.loading">纭� 瀹�</el-button>
+      </template>
+    </el-dialog>
+
+    <!-- 宀椾綅椋庨櫓寮圭獥 -->
+    <el-dialog :title="riskDialog.title" v-model="riskDialog.visible" width="600px" append-to-body>
+      <el-form ref="riskFormRef" :model="riskForm" :rules="riskRules" label-width="100px">
+        <el-form-item label="椋庨櫓绫诲瀷" prop="type">
+          <el-input v-model="riskForm.type" placeholder="璇疯緭鍏ラ闄╃被鍨�" />
+        </el-form-item>
+        <el-form-item label="椋庨櫓绛夌骇" prop="level">
+          <el-select v-model="riskForm.level" placeholder="璇烽�夋嫨椋庨櫓绛夌骇" style="width: 100%">
+            <el-option label="楂�" value="high" />
+            <el-option label="涓�" value="medium" />
+            <el-option label="浣�" value="low" />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="鍏宠仈宀椾綅" prop="post">
+          <el-input v-model="riskForm.post" placeholder="璇疯緭鍏ュ叧鑱斿矖浣�" />
+        </el-form-item>
+        <el-form-item label="椋庨櫓鎻忚堪" prop="description">
+          <el-input v-model="riskForm.description" type="textarea" :rows="3" placeholder="璇疯緭鍏ラ闄╂弿杩�" />
+        </el-form-item>
+        <el-form-item label="鎺у埗鎺柦" prop="controlMeasures">
+          <el-input v-model="riskForm.controlMeasures" type="textarea" :rows="3" placeholder="璇疯緭鍏ユ帶鍒舵帾鏂�" />
+        </el-form-item>
+        <el-form-item label="澶囨敞" prop="remark">
+          <el-input v-model="riskForm.remark" type="textarea" :rows="3" placeholder="璇疯緭鍏ュ娉�" />
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <el-button @click="riskDialog.visible = false">鍙� 娑�</el-button>
+        <el-button type="primary" @click="submitRiskForm" :loading="riskDialog.loading">纭� 瀹�</el-button>
+      </template>
+    </el-dialog>
+
+    <!-- 搴旀�ヨ祫婧愬脊绐� -->
+    <el-dialog :title="emergencyDialog.title" v-model="emergencyDialog.visible" width="600px" append-to-body>
+      <el-form ref="emergencyFormRef" :model="emergencyForm" :rules="emergencyRules" label-width="100px">
+        <el-form-item label="璧勬簮鍚嶇О" prop="name">
+          <el-input v-model="emergencyForm.name" placeholder="璇疯緭鍏ヨ祫婧愬悕绉�" />
+        </el-form-item>
+        <el-form-item label="璧勬簮绫诲瀷" prop="type">
+          <el-input v-model="emergencyForm.type" placeholder="璇疯緭鍏ヨ祫婧愮被鍨�" />
+        </el-form-item>
+        <el-form-item label="鏁伴噺" prop="quantity">
+          <el-input-number v-model="emergencyForm.quantity" :min="0" style="width: 100%" />
+        </el-form-item>
+        <el-form-item label="鎵�灞炲尯鍩�" prop="areaName">
+          <el-input v-model="emergencyForm.areaName" placeholder="璇疯緭鍏ユ墍灞炲尯鍩�" />
+        </el-form-item>
+        <el-form-item label="瀛樻斁浣嶇疆" prop="location">
+          <el-input v-model="emergencyForm.location" placeholder="璇疯緭鍏ュ瓨鏀句綅缃�" />
+        </el-form-item>
+        <el-form-item label="绠$悊浜�" prop="manager">
+          <el-input v-model="emergencyForm.manager" placeholder="璇疯緭鍏ョ鐞嗕汉" />
+        </el-form-item>
+        <el-form-item label="鐘舵��" prop="status">
+          <el-radio-group v-model="emergencyForm.status">
+            <el-radio :value="1">姝e父</el-radio>
+            <el-radio :value="0">缂哄け</el-radio>
+          </el-radio-group>
+        </el-form-item>
+        <el-form-item label="澶囨敞" prop="remark">
+          <el-input v-model="emergencyForm.remark" type="textarea" :rows="3" placeholder="璇疯緭鍏ュ娉�" />
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <el-button @click="emergencyDialog.visible = false">鍙� 娑�</el-button>
+        <el-button type="primary" @click="submitEmergencyForm" :loading="emergencyDialog.loading">纭� 瀹�</el-button>
+      </template>
+    </el-dialog>
   </div>
 </template>
 
 <script setup>
-import { ref, reactive } from "vue";
+import { ref, reactive, onMounted } from "vue";
 import PIMTable from "@/components/PIMTable/PIMTable.vue";
+import {
+  getPersonnelList,
+  addPersonnel as addPersonnelApi,
+  updatePersonnel,
+  deletePersonnel,
+  getPersonnelDetail,
+  getEquipmentList,
+  addEquipment as addEquipmentApi,
+  updateEquipment,
+  deleteEquipment,
+  getEquipmentDetail,
+  getWorkAreaList,
+  addWorkArea as addWorkAreaApi,
+  updateWorkArea,
+  deleteWorkArea,
+  getWorkAreaDetail,
+  getRiskList,
+  addRisk as addRiskApi,
+  updateRisk,
+  deleteRisk,
+  getRiskDetail,
+  getEmergencyList,
+  addEmergency as addEmergencyApi,
+  updateEmergency,
+  deleteEmergency,
+  getEmergencyDetail
+} from "@/api/safetyManagement/basicInfo.js";
+import { ElMessage, ElMessageBox } from "element-plus";
 
 defineOptions({
   name: "鍩虹淇℃伅绠$悊",
@@ -110,88 +291,762 @@
 
 const activeTab = ref("personnel");
 
-// 浜哄憳妗f
+// ==================== 浜哄憳妗f ====================
 const personnelFilters = reactive({ name: "", dept: "" });
 const personnelList = ref([]);
 const personnelPage = reactive({ current: 1, size: 10, total: 0 });
+const personnelLoading = ref(false);
 const personnelColumns = [
   { label: "濮撳悕", prop: "name", align: "center" },
   { label: "閮ㄩ棬", prop: "dept", align: "center" },
   { label: "宀椾綅", prop: "post", align: "center" },
   { label: "鑱旂郴鏂瑰紡", prop: "phone", align: "center" },
   { label: "鍏ヨ亴鏃ユ湡", prop: "entryDate", align: "center" },
+  {
+    label: "鐘舵��",
+    prop: "status",
+    align: "center",
+    dataType: "tag",
+    formatType: (val) => (val === 1 ? "success" : "info"),
+    formatData: (val) => (val === 1 ? "鍦ㄨ亴" : "绂昏亴")
+  },
+  {
+    label: "鎿嶄綔",
+    prop: "action",
+    align: "center",
+    dataType: "action",
+    operation: [
+      { name: "缂栬緫", type: "text", clickFun: (row) => handleEditPersonnel(row) },
+      { name: "鍒犻櫎", type: "text", clickFun: (row) => handleDeletePersonnel(row) }
+    ]
+  }
 ];
 
-// 璁惧璁炬柦
-const equipmentFilters = reactive({ name: "", area: "" });
+const personnelDialog = reactive({ visible: false, title: "", loading: false });
+const personnelFormRef = ref(null);
+const personnelForm = reactive({
+  id: null,
+  name: "",
+  dept: "",
+  post: "",
+  phone: "",
+  entryDate: "",
+  status: 1,
+  remark: ""
+});
+const personnelRules = {
+  name: [{ required: true, message: "璇疯緭鍏ュ鍚�", trigger: "blur" }],
+  dept: [{ required: true, message: "璇疯緭鍏ラ儴闂�", trigger: "blur" }]
+};
+
+// ==================== 璁惧璁炬柦 ====================
+const equipmentFilters = reactive({ name: "", areaName: "" });
 const equipmentList = ref([]);
 const equipmentPage = reactive({ current: 1, size: 10, total: 0 });
+const equipmentLoading = ref(false);
 const equipmentColumns = [
   { label: "璁惧鍚嶇О", prop: "name", align: "center" },
   { label: "瑙勬牸鍨嬪彿", prop: "model", align: "center" },
-  { label: "鎵�灞炲尯鍩�", prop: "area", align: "center" },
-  { label: "鐘舵��", prop: "status", align: "center" },
+  { label: "鎵�灞炲尯鍩�", prop: "areaName", align: "center" },
+  {
+    label: "鐘舵��",
+    prop: "status",
+    align: "center",
+    dataType: "tag",
+    formatType: (val) => (val === 1 ? "success" : "danger"),
+    formatData: (val) => (val === 1 ? "姝e父" : "鍋滅敤")
+  },
+  {
+    label: "鎿嶄綔",
+    prop: "action",
+    align: "center",
+    dataType: "action",
+    operation: [
+      { name: "缂栬緫", type: "text", clickFun: (row) => handleEditEquipment(row) },
+      { name: "鍒犻櫎", type: "text", clickFun: (row) => handleDeleteEquipment(row) }
+    ]
+  }
 ];
 
-// 浣滀笟鍖哄煙
+const equipmentDialog = reactive({ visible: false, title: "", loading: false });
+const equipmentFormRef = ref(null);
+const equipmentForm = reactive({
+  id: null,
+  name: "",
+  model: "",
+  areaName: "",
+  status: 1,
+  remark: ""
+});
+const equipmentRules = {
+  name: [{ required: true, message: "璇疯緭鍏ヨ澶囧悕绉�", trigger: "blur" }]
+};
+
+// ==================== 浣滀笟鍖哄煙 ====================
 const areaFilters = reactive({ name: "" });
 const areaList = ref([]);
 const areaPage = reactive({ current: 1, size: 10, total: 0 });
+const areaLoading = ref(false);
 const areaColumns = [
   { label: "鍖哄煙鍚嶇О", prop: "name", align: "center" },
   { label: "浣嶇疆", prop: "location", align: "center" },
   { label: "璐熻矗浜�", prop: "manager", align: "center" },
+  {
+    label: "鎿嶄綔",
+    prop: "action",
+    align: "center",
+    dataType: "action",
+    operation: [
+      { name: "缂栬緫", type: "text", clickFun: (row) => handleEditArea(row) },
+      { name: "鍒犻櫎", type: "text", clickFun: (row) => handleDeleteArea(row) }
+    ]
+  }
 ];
 
-// 宀椾綅椋庨櫓
+const areaDialog = reactive({ visible: false, title: "", loading: false });
+const areaFormRef = ref(null);
+const areaForm = reactive({
+  id: null,
+  name: "",
+  location: "",
+  manager: "",
+  remark: ""
+});
+const areaRules = {
+  name: [{ required: true, message: "璇疯緭鍏ュ尯鍩熷悕绉�", trigger: "blur" }]
+};
+
+// ==================== 宀椾綅椋庨櫓 ====================
 const riskFilters = reactive({ type: "" });
 const riskList = ref([]);
 const riskPage = reactive({ current: 1, size: 10, total: 0 });
+const riskLoading = ref(false);
 const riskColumns = [
   { label: "椋庨櫓绫诲瀷", prop: "type", align: "center" },
-  { label: "椋庨櫓绛夌骇", prop: "level", align: "center" },
+  {
+    label: "椋庨櫓绛夌骇",
+    prop: "level",
+    align: "center",
+    dataType: "tag",
+    formatType: (val) => {
+      if (val === 'high') return 'danger';
+      if (val === 'medium') return 'warning';
+      return 'success';
+    },
+    formatData: (val) => {
+      const map = { high: '楂�', medium: '涓�', low: '浣�' };
+      return map[val] || val;
+    }
+  },
   { label: "鎻忚堪", prop: "description", align: "center" },
+  {
+    label: "鎿嶄綔",
+    prop: "action",
+    align: "center",
+    dataType: "action",
+    operation: [
+      { name: "缂栬緫", type: "text", clickFun: (row) => handleEditRisk(row) },
+      { name: "鍒犻櫎", type: "text", clickFun: (row) => handleDeleteRisk(row) }
+    ]
+  }
 ];
 
-// 搴旀�ヨ祫婧�
+const riskDialog = reactive({ visible: false, title: "", loading: false });
+const riskFormRef = ref(null);
+const riskForm = reactive({
+  id: null,
+  type: "",
+  level: "",
+  description: "",
+  post: "",
+  controlMeasures: "",
+  remark: ""
+});
+const riskRules = {
+  type: [{ required: true, message: "璇疯緭鍏ラ闄╃被鍨�", trigger: "blur" }],
+  level: [{ required: true, message: "璇烽�夋嫨椋庨櫓绛夌骇", trigger: "change" }]
+};
+
+// ==================== 搴旀�ヨ祫婧� ====================
 const emergencyFilters = reactive({ name: "" });
 const emergencyList = ref([]);
 const emergencyPage = reactive({ current: 1, size: 10, total: 0 });
+const emergencyLoading = ref(false);
 const emergencyColumns = [
   { label: "璧勬簮鍚嶇О", prop: "name", align: "center" },
   { label: "绫诲瀷", prop: "type", align: "center" },
   { label: "鏁伴噺", prop: "quantity", align: "center" },
   { label: "瀛樻斁浣嶇疆", prop: "location", align: "center" },
+  {
+    label: "鐘舵��",
+    prop: "status",
+    align: "center",
+    dataType: "tag",
+    formatType: (val) => (val === 1 ? "success" : "danger"),
+    formatData: (val) => (val === 1 ? "姝e父" : "缂哄け")
+  },
+  {
+    label: "鎿嶄綔",
+    prop: "action",
+    align: "center",
+    dataType: "action",
+    operation: [
+      { name: "缂栬緫", type: "text", clickFun: (row) => handleEditEmergency(row) },
+      { name: "鍒犻櫎", type: "text", clickFun: (row) => handleDeleteEmergency(row) }
+    ]
+  }
 ];
 
-const handleTabChange = () => {
-  // 鍒囨崲tab鏃跺姞杞藉搴旀暟鎹�
+const emergencyDialog = reactive({ visible: false, title: "", loading: false });
+const emergencyFormRef = ref(null);
+const emergencyForm = reactive({
+  id: null,
+  name: "",
+  type: "",
+  quantity: 0,
+  areaName: "",
+  location: "",
+  manager: "",
+  status: 1,
+  remark: ""
+});
+const emergencyRules = {
+  name: [{ required: true, message: "璇疯緭鍏ヨ祫婧愬悕绉�", trigger: "blur" }],
+  type: [{ required: true, message: "璇疯緭鍏ヨ祫婧愮被鍨�", trigger: "blur" }]
 };
 
-const getPersonnelData = () => {};
-const resetPersonnelFilters = () => { personnelFilters.name = ""; personnelFilters.dept = ""; };
-const addPersonnel = () => {};
-const changePersonnelPage = ({ page, limit }) => { personnelPage.current = page; personnelPage.size = limit; };
+// ==================== 閫氱敤鏂规硶 ====================
+const loadData = () => {
+  switch (activeTab.value) {
+    case 'personnel':
+      getPersonnelData();
+      break;
+    case 'equipment':
+      getEquipmentData();
+      break;
+    case 'workArea':
+      getAreaData();
+      break;
+    case 'risk':
+      getRiskData();
+      break;
+    case 'emergency':
+      getEmergencyData();
+      break;
+  }
+};
 
-const getEquipmentData = () => {};
-const resetEquipmentFilters = () => { equipmentFilters.name = ""; equipmentFilters.area = ""; };
-const addEquipment = () => {};
-const changeEquipmentPage = ({ page, limit }) => { equipmentPage.current = page; equipmentPage.size = limit; };
+const handleTabChange = () => {
+  loadData();
+};
 
-const getAreaData = () => {};
-const resetAreaFilters = () => { areaFilters.name = ""; };
-const addArea = () => {};
-const changeAreaPage = ({ page, limit }) => { areaPage.current = page; areaPage.size = limit; };
 
-const getRiskData = () => {};
-const resetRiskFilters = () => { riskFilters.type = ""; };
-const addRisk = () => {};
-const changeRiskPage = ({ page, limit }) => { riskPage.current = page; riskPage.size = limit; };
 
-const getEmergencyData = () => {};
-const resetEmergencyFilters = () => { emergencyFilters.name = ""; };
-const addEmergency = () => {};
-const changeEmergencyPage = ({ page, limit }) => { emergencyPage.current = page; emergencyPage.size = limit; };
+// ==================== 浜哄憳妗f鏂规硶 ====================
+const getPersonnelData = async () => {
+  personnelLoading.value = true;
+  try {
+    const res = await getPersonnelList({
+      pageNum: personnelPage.current,
+      pageSize: personnelPage.size,
+      ...personnelFilters
+    });
+    if (res.code === 200) {
+      personnelList.value = res.data.rows || res.data.records || [];
+      personnelPage.total = res.data.total || 0;
+    }
+  } catch (error) {
+    ElMessage.error('鑾峰彇浜哄憳妗f澶辫触');
+  } finally {
+    personnelLoading.value = false;
+  }
+};
+
+const resetPersonnelFilters = () => {
+  personnelFilters.name = "";
+  personnelFilters.dept = "";
+  personnelPage.current = 1;
+  getPersonnelData();
+};
+
+const changePersonnelPage = ({ page, limit }) => {
+  personnelPage.current = page;
+  personnelPage.size = limit;
+  getPersonnelData();
+};
+
+const resetPersonnelForm = () => {
+  personnelForm.id = null;
+  personnelForm.name = "";
+  personnelForm.dept = "";
+  personnelForm.post = "";
+  personnelForm.phone = "";
+  personnelForm.entryDate = "";
+  personnelForm.status = 1;
+  personnelForm.remark = "";
+};
+
+const addPersonnel = () => {
+  resetPersonnelForm();
+  personnelDialog.title = "鏂板浜哄憳妗f";
+  personnelDialog.visible = true;
+};
+
+const handleEditPersonnel = async (row) => {
+  resetPersonnelForm();
+  try {
+    const res = await getPersonnelDetail(row.id);
+    if (res.code === 200) {
+      Object.assign(personnelForm, res.data);
+      personnelDialog.title = "缂栬緫浜哄憳妗f";
+      personnelDialog.visible = true;
+    }
+  } catch (error) {
+    ElMessage.error('鑾峰彇浜哄憳妗f璇︽儏澶辫触');
+  }
+};
+
+const handleDeletePersonnel = (row) => {
+  ElMessageBox.confirm(`纭鍒犻櫎浜哄憳 "${row.name}" 鍚楋紵`, "鎻愮ず", {
+    confirmButtonText: "纭",
+    cancelButtonText: "鍙栨秷",
+    type: "warning"
+  }).then(async () => {
+    try {
+      const res = await deletePersonnel(row.id);
+      if (res.code === 200) {
+        ElMessage.success("鍒犻櫎鎴愬姛");
+        getPersonnelData();
+      }
+    } catch (error) {
+      ElMessage.error("鍒犻櫎澶辫触");
+    }
+  });
+};
+
+const submitPersonnelForm = async () => {
+  const valid = await personnelFormRef.value.validate().catch(() => false);
+  if (!valid) return;
+  
+  personnelDialog.loading = true;
+  try {
+    const api = personnelForm.id ? updatePersonnel : addPersonnelApi;
+    const res = await api(personnelForm);
+    if (res.code === 200) {
+      ElMessage.success(personnelForm.id ? "淇敼鎴愬姛" : "鏂板鎴愬姛");
+      personnelDialog.visible = false;
+      getPersonnelData();
+    }
+  } catch (error) {
+    ElMessage.error(personnelForm.id ? "淇敼澶辫触" : "鏂板澶辫触");
+  } finally {
+    personnelDialog.loading = false;
+  }
+};
+
+// ==================== 璁惧璁炬柦鏂规硶 ====================
+const getEquipmentData = async () => {
+  equipmentLoading.value = true;
+  try {
+    const res = await getEquipmentList({
+      pageNum: equipmentPage.current,
+      pageSize: equipmentPage.size,
+      ...equipmentFilters
+    });
+    if (res.code === 200) {
+      equipmentList.value = res.data.rows || res.data.records || [];
+      equipmentPage.total = res.data.total || 0;
+    }
+  } catch (error) {
+    ElMessage.error('鑾峰彇璁惧璁炬柦澶辫触');
+  } finally {
+    equipmentLoading.value = false;
+  }
+};
+
+const resetEquipmentFilters = () => {
+  equipmentFilters.name = "";
+  equipmentFilters.areaName = "";
+  equipmentPage.current = 1;
+  getEquipmentData();
+};
+
+const changeEquipmentPage = ({ page, limit }) => {
+  equipmentPage.current = page;
+  equipmentPage.size = limit;
+  getEquipmentData();
+};
+
+const resetEquipmentForm = () => {
+  equipmentForm.id = null;
+  equipmentForm.name = "";
+  equipmentForm.model = "";
+  equipmentForm.areaName = "";
+  equipmentForm.status = 1;
+  equipmentForm.remark = "";
+};
+
+const addEquipment = () => {
+  resetEquipmentForm();
+  equipmentDialog.title = "鏂板璁惧璁炬柦";
+  equipmentDialog.visible = true;
+};
+
+const handleEditEquipment = async (row) => {
+  resetEquipmentForm();
+  try {
+    const res = await getEquipmentDetail(row.id);
+    if (res.code === 200) {
+      Object.assign(equipmentForm, res.data);
+      equipmentDialog.title = "缂栬緫璁惧璁炬柦";
+      equipmentDialog.visible = true;
+    }
+  } catch (error) {
+    ElMessage.error('鑾峰彇璁惧璇︽儏澶辫触');
+  }
+};
+
+const handleDeleteEquipment = (row) => {
+  ElMessageBox.confirm(`纭鍒犻櫎璁惧 "${row.name}" 鍚楋紵`, "鎻愮ず", {
+    confirmButtonText: "纭",
+    cancelButtonText: "鍙栨秷",
+    type: "warning"
+  }).then(async () => {
+    try {
+      const res = await deleteEquipment(row.id);
+      if (res.code === 200) {
+        ElMessage.success("鍒犻櫎鎴愬姛");
+        getEquipmentData();
+      }
+    } catch (error) {
+      ElMessage.error("鍒犻櫎澶辫触");
+    }
+  });
+};
+
+const submitEquipmentForm = async () => {
+  const valid = await equipmentFormRef.value.validate().catch(() => false);
+  if (!valid) return;
+  
+  equipmentDialog.loading = true;
+  try {
+    const api = equipmentForm.id ? updateEquipment : addEquipmentApi;
+    const res = await api(equipmentForm);
+    if (res.code === 200) {
+      ElMessage.success(equipmentForm.id ? "淇敼鎴愬姛" : "鏂板鎴愬姛");
+      equipmentDialog.visible = false;
+      getEquipmentData();
+    }
+  } catch (error) {
+    ElMessage.error(equipmentForm.id ? "淇敼澶辫触" : "鏂板澶辫触");
+  } finally {
+    equipmentDialog.loading = false;
+  }
+};
+
+// ==================== 浣滀笟鍖哄煙鏂规硶 ====================
+const getAreaData = async () => {
+  areaLoading.value = true;
+  try {
+    const res = await getWorkAreaList({
+      pageNum: areaPage.current,
+      pageSize: areaPage.size,
+      ...areaFilters
+    });
+    if (res.code === 200) {
+      areaList.value = res.data.rows || res.data.records || [];
+      areaPage.total = res.data.total || 0;
+    }
+  } catch (error) {
+    ElMessage.error('鑾峰彇浣滀笟鍖哄煙澶辫触');
+  } finally {
+    areaLoading.value = false;
+  }
+};
+
+const resetAreaFilters = () => {
+  areaFilters.name = "";
+  areaPage.current = 1;
+  getAreaData();
+};
+
+const changeAreaPage = ({ page, limit }) => {
+  areaPage.current = page;
+  areaPage.size = limit;
+  getAreaData();
+};
+
+const resetAreaForm = () => {
+  areaForm.id = null;
+  areaForm.name = "";
+  areaForm.location = "";
+  areaForm.manager = "";
+  areaForm.remark = "";
+};
+
+const addArea = () => {
+  resetAreaForm();
+  areaDialog.title = "鏂板浣滀笟鍖哄煙";
+  areaDialog.visible = true;
+};
+
+const handleEditArea = async (row) => {
+  resetAreaForm();
+  try {
+    const res = await getWorkAreaDetail(row.id);
+    if (res.code === 200) {
+      Object.assign(areaForm, res.data);
+      areaDialog.title = "缂栬緫浣滀笟鍖哄煙";
+      areaDialog.visible = true;
+    }
+  } catch (error) {
+    ElMessage.error('鑾峰彇浣滀笟鍖哄煙璇︽儏澶辫触');
+  }
+};
+
+const handleDeleteArea = (row) => {
+  ElMessageBox.confirm(`纭鍒犻櫎鍖哄煙 "${row.name}" 鍚楋紵`, "鎻愮ず", {
+    confirmButtonText: "纭",
+    cancelButtonText: "鍙栨秷",
+    type: "warning"
+  }).then(async () => {
+    try {
+      const res = await deleteWorkArea(row.id);
+      if (res.code === 200) {
+        ElMessage.success("鍒犻櫎鎴愬姛");
+        getAreaData();
+      }
+    } catch (error) {
+      ElMessage.error("鍒犻櫎澶辫触");
+    }
+  });
+};
+
+const submitAreaForm = async () => {
+  const valid = await areaFormRef.value.validate().catch(() => false);
+  if (!valid) return;
+  
+  areaDialog.loading = true;
+  try {
+    const api = areaForm.id ? updateWorkArea : addWorkAreaApi;
+    const res = await api(areaForm);
+    if (res.code === 200) {
+      ElMessage.success(areaForm.id ? "淇敼鎴愬姛" : "鏂板鎴愬姛");
+      areaDialog.visible = false;
+      getAreaData();
+    }
+  } catch (error) {
+    ElMessage.error(areaForm.id ? "淇敼澶辫触" : "鏂板澶辫触");
+  } finally {
+    areaDialog.loading = false;
+  }
+};
+
+// ==================== 宀椾綅椋庨櫓鏂规硶 ====================
+const getRiskData = async () => {
+  riskLoading.value = true;
+  try {
+    const res = await getRiskList({
+      pageNum: riskPage.current,
+      pageSize: riskPage.size,
+      ...riskFilters
+    });
+    if (res.code === 200) {
+      riskList.value = res.data.rows || res.data.records || [];
+      riskPage.total = res.data.total || 0;
+    }
+  } catch (error) {
+    ElMessage.error('鑾峰彇宀椾綅椋庨櫓澶辫触');
+  } finally {
+    riskLoading.value = false;
+  }
+};
+
+const resetRiskFilters = () => {
+  riskFilters.type = "";
+  riskPage.current = 1;
+  getRiskData();
+};
+
+const changeRiskPage = ({ page, limit }) => {
+  riskPage.current = page;
+  riskPage.size = limit;
+  getRiskData();
+};
+
+const resetRiskForm = () => {
+  riskForm.id = null;
+  riskForm.type = "";
+  riskForm.level = "";
+  riskForm.description = "";
+  riskForm.post = "";
+  riskForm.controlMeasures = "";
+  riskForm.remark = "";
+};
+
+const addRisk = () => {
+  resetRiskForm();
+  riskDialog.title = "鏂板宀椾綅椋庨櫓";
+  riskDialog.visible = true;
+};
+
+const handleEditRisk = async (row) => {
+  resetRiskForm();
+  try {
+    const res = await getRiskDetail(row.id);
+    if (res.code === 200) {
+      Object.assign(riskForm, res.data);
+      riskDialog.title = "缂栬緫宀椾綅椋庨櫓";
+      riskDialog.visible = true;
+    }
+  } catch (error) {
+    ElMessage.error('鑾峰彇宀椾綅椋庨櫓璇︽儏澶辫触');
+  }
+};
+
+const handleDeleteRisk = (row) => {
+  ElMessageBox.confirm(`纭鍒犻櫎椋庨櫓 "${row.type}" 鍚楋紵`, "鎻愮ず", {
+    confirmButtonText: "纭",
+    cancelButtonText: "鍙栨秷",
+    type: "warning"
+  }).then(async () => {
+    try {
+      const res = await deleteRisk(row.id);
+      if (res.code === 200) {
+        ElMessage.success("鍒犻櫎鎴愬姛");
+        getRiskData();
+      }
+    } catch (error) {
+      ElMessage.error("鍒犻櫎澶辫触");
+    }
+  });
+};
+
+const submitRiskForm = async () => {
+  const valid = await riskFormRef.value.validate().catch(() => false);
+  if (!valid) return;
+  
+  riskDialog.loading = true;
+  try {
+    const api = riskForm.id ? updateRisk : addRiskApi;
+    const res = await api(riskForm);
+    if (res.code === 200) {
+      ElMessage.success(riskForm.id ? "淇敼鎴愬姛" : "鏂板鎴愬姛");
+      riskDialog.visible = false;
+      getRiskData();
+    }
+  } catch (error) {
+    ElMessage.error(riskForm.id ? "淇敼澶辫触" : "鏂板澶辫触");
+  } finally {
+    riskDialog.loading = false;
+  }
+};
+
+// ==================== 搴旀�ヨ祫婧愭柟娉� ====================
+const getEmergencyData = async () => {
+  emergencyLoading.value = true;
+  try {
+    const res = await getEmergencyList({
+      pageNum: emergencyPage.current,
+      pageSize: emergencyPage.size,
+      ...emergencyFilters
+    });
+    if (res.code === 200) {
+      emergencyList.value = res.data.rows || res.data.records || [];
+      emergencyPage.total = res.data.total || 0;
+    }
+  } catch (error) {
+    ElMessage.error('鑾峰彇搴旀�ヨ祫婧愬け璐�');
+  } finally {
+    emergencyLoading.value = false;
+  }
+};
+
+const resetEmergencyFilters = () => {
+  emergencyFilters.name = "";
+  emergencyPage.current = 1;
+  getEmergencyData();
+};
+
+const changeEmergencyPage = ({ page, limit }) => {
+  emergencyPage.current = page;
+  emergencyPage.size = limit;
+  getEmergencyData();
+};
+
+const resetEmergencyForm = () => {
+  emergencyForm.id = null;
+  emergencyForm.name = "";
+  emergencyForm.type = "";
+  emergencyForm.quantity = 0;
+  emergencyForm.areaName = "";
+  emergencyForm.location = "";
+  emergencyForm.manager = "";
+  emergencyForm.status = 1;
+  emergencyForm.remark = "";
+};
+
+const addEmergency = () => {
+  resetEmergencyForm();
+  emergencyDialog.title = "鏂板搴旀�ヨ祫婧�";
+  emergencyDialog.visible = true;
+};
+
+const handleEditEmergency = async (row) => {
+  resetEmergencyForm();
+  try {
+    const res = await getEmergencyDetail(row.id);
+    if (res.code === 200) {
+      Object.assign(emergencyForm, res.data);
+      emergencyDialog.title = "缂栬緫搴旀�ヨ祫婧�";
+      emergencyDialog.visible = true;
+    }
+  } catch (error) {
+    ElMessage.error('鑾峰彇搴旀�ヨ祫婧愯鎯呭け璐�');
+  }
+};
+
+const handleDeleteEmergency = (row) => {
+  ElMessageBox.confirm(`纭鍒犻櫎璧勬簮 "${row.name}" 鍚楋紵`, "鎻愮ず", {
+    confirmButtonText: "纭",
+    cancelButtonText: "鍙栨秷",
+    type: "warning"
+  }).then(async () => {
+    try {
+      const res = await deleteEmergency(row.id);
+      if (res.code === 200) {
+        ElMessage.success("鍒犻櫎鎴愬姛");
+        getEmergencyData();
+      }
+    } catch (error) {
+      ElMessage.error("鍒犻櫎澶辫触");
+    }
+  });
+};
+
+const submitEmergencyForm = async () => {
+  const valid = await emergencyFormRef.value.validate().catch(() => false);
+  if (!valid) return;
+  
+  emergencyDialog.loading = true;
+  try {
+    const api = emergencyForm.id ? updateEmergency : addEmergencyApi;
+    const res = await api(emergencyForm);
+    if (res.code === 200) {
+      ElMessage.success(emergencyForm.id ? "淇敼鎴愬姛" : "鏂板鎴愬姛");
+      emergencyDialog.visible = false;
+      getEmergencyData();
+    }
+  } catch (error) {
+    ElMessage.error(emergencyForm.id ? "淇敼澶辫触" : "鏂板澶辫触");
+  } finally {
+    emergencyDialog.loading = false;
+  }
+};
+
+onMounted(() => {
+  getPersonnelData();
+});
 </script>
 
 <style lang="scss" scoped>

--
Gitblit v1.9.3