From 09f49269f00a1fa70bbf9d52476b01bf917c948e Mon Sep 17 00:00:00 2001
From: zouyu <2723363702@qq.com>
Date: 星期二, 16 十二月 2025 19:57:39 +0800
Subject: [PATCH] 代码调整5

---
 src/views/index.vue                             |  934 +++++---------
 .env.development                                |    2 
 /dev/null                                       |  572 --------
 src/views/diagnosis/FaultDiagnosis.vue          |  411 ++++++
 src/views/dashboard/Dashboard.vue               |  301 ++++
 src/views/monitoring/RealTimeMonitoring.vue     |  515 ++++++++
 src/main.js                                     |    2 
 src/views/maintenance/MaintenanceManagement.vue |  526 ++++++++
 .env.production                                 |    2 
 vite.config.js                                  |    4 
 src/views/device/DeviceManagement.vue           |  513 ++++++++
 11 files changed, 2,597 insertions(+), 1,185 deletions(-)

diff --git a/.env.development b/.env.development
index 47c7925..9729e7e 100644
--- a/.env.development
+++ b/.env.development
@@ -1,5 +1,5 @@
 # 椤甸潰鏍囬
-VITE_APP_TITLE = 鎵垮寘鍟嗙鐞嗙郴缁�
+VITE_APP_TITLE = 璁惧鍦ㄧ嚎鐩戞祴璇婃柇鍙婄淮淇郴缁�
 
 # 寮�鍙戠幆澧冮厤缃�
 VITE_APP_ENV = 'development'
diff --git a/.env.production b/.env.production
index 119d6b5..042d296 100644
--- a/.env.production
+++ b/.env.production
@@ -1,5 +1,5 @@
 # 椤甸潰鏍囬
-VITE_APP_TITLE = 鎵垮寘鍟嗙鐞嗙郴缁�
+VITE_APP_TITLE = 璁惧鍦ㄧ嚎鐩戞祴璇婃柇鍙婄淮淇郴缁�
 
 # 鐢熶骇鐜閰嶇疆
 VITE_APP_ENV = 'production'
diff --git a/src/main.js b/src/main.js
index 99e7fa4..a5339fb 100644
--- a/src/main.js
+++ b/src/main.js
@@ -76,7 +76,7 @@
 app.config.globalProperties.addDateRange = addDateRange;
 app.config.globalProperties.selectDictLabel = selectDictLabel;
 app.config.globalProperties.selectDictLabels = selectDictLabels;
-app.config.globalProperties.javaApi = "http://10.136.12.71:8018";
+app.config.globalProperties.javaApi = "http://10.136.12.71:8020";
 app.config.globalProperties.HaveJson = (val) => {
   return JSON.parse(JSON.stringify(val));
 };
diff --git a/src/views/contractor/assets/index.vue b/src/views/contractor/assets/index.vue
deleted file mode 100644
index ad8a641..0000000
--- a/src/views/contractor/assets/index.vue
+++ /dev/null
@@ -1,637 +0,0 @@
-<template>
-  <div class="app-container">
-    <el-form
-      :model="queryParams"
-      ref="queryRef"
-      :inline="true"
-      v-show="showSearch"
-      label-width="90px"
-    >
-      <el-form-item label="璧勪骇鍚嶇О" prop="assetName">
-        <el-input
-          v-model="queryParams.assetName"
-          placeholder="璇疯緭鍏ヨ祫浜у悕绉�"
-          clearable
-          style="width: 220px"
-          @keyup.enter="handleQuery"
-        />
-      </el-form-item>
-      <el-form-item label="璧勪骇缂栧彿" prop="assetCode">
-        <el-input
-          v-model="queryParams.assetCode"
-          placeholder="璇疯緭鍏ヨ祫浜х紪鍙�"
-          clearable
-          style="width: 240px"
-          @keyup.enter="handleQuery"
-        />
-      </el-form-item>
-      <el-form-item label="鎵�灞炴壙鍖呭晢" prop="contractorId">
-        <el-select
-          v-model="queryParams.contractorId"
-          placeholder="璇烽�夋嫨鎵垮寘鍟�"
-          clearable
-          style="width: 240px"
-        >
-          <el-option
-            v-for="contractor in contractorOptions"
-            :key="contractor.contractorId"
-            :label="contractor.contractorName"
-            :value="contractor.contractorId"
-          />
-        </el-select>
-      </el-form-item>
-      <el-form-item label="璧勪骇鐘舵��" prop="status">
-        <el-select
-          v-model="queryParams.status"
-          placeholder="璧勪骇鐘舵��"
-          clearable
-          style="width: 240px"
-        >
-          <el-option
-            v-for="dict in asset_status"
-            :key="dict.value"
-            :label="dict.label"
-            :value="dict.value"
-          />
-        </el-select>
-      </el-form-item>
-      <el-form-item>
-        <el-button type="primary" icon="Search" @click="handleQuery"
-          >鎼滅储</el-button
-        >
-        <el-button icon="Refresh" @click="resetQuery">閲嶇疆</el-button>
-      </el-form-item>
-    </el-form>
-
-    <el-row :gutter="10" class="mb8">
-      <el-col :span="1.5">
-        <el-button
-          type="primary"
-          plain
-          icon="Plus"
-          @click="handleAdd"
-          >鏂板</el-button
-        >
-      </el-col>
-      <el-col :span="1.5">
-        <el-button
-          type="success"
-          plain
-          icon="Edit"
-          :disabled="single"
-          @click="handleUpdate"
-          >淇敼</el-button
-        >
-      </el-col>
-      <el-col :span="1.5">
-        <el-button
-          type="danger"
-          plain
-          icon="Delete"
-          :disabled="multiple"
-          @click="handleDelete"
-          >鍒犻櫎</el-button
-        >
-      </el-col>
-      <right-toolbar
-        v-model:showSearch="showSearch"
-        @queryTable="getList"
-        :columns="columns"
-      ></right-toolbar>
-    </el-row>
-
-    <el-table
-      v-loading="loading"
-      :data="assetList"
-      @selection-change="handleSelectionChange"
-      stripe
-    >
-      <el-table-column type="selection" width="50" align="center" />
-      <el-table-column
-        label="璧勪骇缂栧彿"
-        align="center"
-        key="assetId"
-        prop="assetId"
-        v-if="columns[0].visible"
-      />
-      <el-table-column
-        label="璧勪骇鍚嶇О"
-        align="center"
-        key="assetName"
-        prop="assetName"
-        v-if="columns[1].visible"
-        :show-overflow-tooltip="true"
-      />
-      <el-table-column
-        label="璧勪骇缂栧彿"
-        align="center"
-        key="assetCode"
-        prop="assetCode"
-        v-if="columns[2].visible"
-      />
-      <el-table-column
-        label="鎵�灞炴壙鍖呭晢"
-        align="center"
-        key="contractorName"
-        prop="contractorName"
-        v-if="columns[3].visible"
-        :show-overflow-tooltip="true"
-      />
-      <el-table-column
-        label="璧勪骇绫诲瀷"
-        align="center"
-        key="assetType"
-        prop="assetType"
-        v-if="columns[4].visible"
-      >
-        <template #default="scope">
-          {{ getAssetTypeLabel(scope.row.assetType) }}
-        </template>
-      </el-table-column>
-      <el-table-column
-        label="璧勪骇浠峰��"
-        align="center"
-        key="assetValue"
-        prop="assetValue"
-        v-if="columns[5].visible"
-      >
-        <template #default="scope">
-          {{ scope.row.assetValue.toFixed(2) }}
-        </template>
-      </el-table-column>
-      <el-table-column
-        label="鐘舵��"
-        align="center"
-        key="status"
-        v-if="columns[6].visible"
-      >
-        <template #default="scope">
-          <el-switch
-            v-model="scope.row.status"
-            active-value="0"
-            inactive-value="1"
-            @change="handleStatusChange(scope.row)"
-          ></el-switch>
-        </template>
-      </el-table-column>
-      <el-table-column
-        label="鍒涘缓鏃堕棿"
-        align="center"
-        prop="createTime"
-        v-if="columns[7].visible"
-        width="160"
-      >
-        <template #default="scope">
-          <span>{{ parseTime(scope.row.createTime) }}</span>
-        </template>
-      </el-table-column>
-      <el-table-column
-        label="鎿嶄綔"
-        align="center"
-        width="150"
-        class-name="small-padding fixed-width"
-      >
-        <template #default="scope">
-          <el-tooltip
-            content="淇敼"
-            placement="top"
-          >
-            <el-button
-              link
-              type="primary"
-              icon="Edit"
-              @click="handleUpdate(scope.row)"
-            ></el-button>
-          </el-tooltip>
-          <el-tooltip
-            content="鍒犻櫎"
-            placement="top"
-          >
-            <el-button
-              link
-              type="primary"
-              icon="Delete"
-              @click="handleDelete(scope.row)"
-            ></el-button>
-          </el-tooltip>
-        </template>
-      </el-table-column>
-    </el-table>
-    <pagination
-      v-show="total > 0"
-      :total="total"
-      v-model:page="queryParams.pageNum"
-      v-model:limit="queryParams.pageSize"
-      @pagination="getList"
-    />
-
-    <!-- 娣诲姞鎴栦慨鏀硅祫浜ч厤缃璇濇 -->
-    <el-dialog :title="title" v-model="open" width="600px" append-to-body>
-      <el-form :model="form" :rules="rules" ref="assetRef" label-width="80px">
-        <el-row>
-          <el-col :span="12">
-            <el-form-item label="璧勪骇鍚嶇О" prop="assetName">
-              <el-input
-                v-model="form.assetName"
-                placeholder="璇疯緭鍏ヨ祫浜у悕绉�"
-                maxlength="50"
-              />
-            </el-form-item>
-          </el-col>
-          <el-col :span="12">
-            <el-form-item label="璧勪骇缂栧彿" prop="assetCode">
-              <el-input
-                v-model="form.assetCode"
-                placeholder="璇疯緭鍏ヨ祫浜х紪鍙�"
-                maxlength="20"
-              />
-            </el-form-item>
-          </el-col>
-        </el-row>
-        <el-row>
-          <el-col :span="12">
-            <el-form-item label="鎵�灞炴壙鍖呭晢" prop="contractorId">
-              <el-select
-                v-model="form.contractorId"
-                placeholder="璇烽�夋嫨鎵垮寘鍟�"
-                clearable
-              >
-                <el-option
-                  v-for="contractor in contractorOptions"
-                  :key="contractor.contractorId"
-                  :label="contractor.contractorName"
-                  :value="contractor.contractorId"
-                />
-              </el-select>
-            </el-form-item>
-          </el-col>
-          <el-col :span="12">
-            <el-form-item label="璧勪骇绫诲瀷" prop="assetType">
-              <el-select
-                v-model="form.assetType"
-                placeholder="璇烽�夋嫨璧勪骇绫诲瀷"
-                clearable
-              >
-                <el-option
-                  v-for="type in asset_types"
-                  :key="type.value"
-                  :label="type.label"
-                  :value="type.value"
-                />
-              </el-select>
-            </el-form-item>
-          </el-col>
-        </el-row>
-        <el-row>
-          <el-col :span="12">
-            <el-form-item label="璧勪骇浠峰��" prop="assetValue">
-              <el-input
-                v-model="form.assetValue"
-                placeholder="璇疯緭鍏ヨ祫浜т环鍊�"
-                type="number"
-                step="0.01"
-              />
-            </el-form-item>
-          </el-col>
-          <el-col :span="12">
-            <el-form-item label="鐘舵��">
-              <el-radio-group v-model="form.status">
-                <el-radio
-                  v-for="dict in sys_normal_disable"
-                  :key="dict.value"
-                  :value="dict.value"
-                  >{{ dict.label }}</el-radio
-                >
-              </el-radio-group>
-            </el-form-item>
-          </el-col>
-        </el-row>
-        <el-row>
-          <el-col :span="24">
-            <el-form-item label="澶囨敞">
-              <el-input
-                v-model="form.remark"
-                type="textarea"
-                placeholder="璇疯緭鍏ュ唴瀹�"
-              ></el-input>
-            </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="cancel">鍙� 娑�</el-button>
-        </div>
-      </template>
-    </el-dialog>
-  </div>
-</template>
-
-<script setup name="ContractorAssets">
-import { ref, reactive, toRefs, watch, onMounted } from 'vue';
-import { ElMessage } from 'element-plus';
-import { parseTime } from '@/utils/ruoyi';
-
-const assetList = ref([]);
-const open = ref(false);
-const loading = ref(true);
-const showSearch = ref(true);
-const ids = ref([]);
-const single = ref(true);
-const multiple = ref(true);
-const total = ref(0);
-const title = ref("");
-
-// 鍒楁樉闅愪俊鎭�
-const columns = ref([
-  { key: 0, label: `璧勪骇缂栧彿`, visible: true },
-  { key: 1, label: `璧勪骇鍚嶇О`, visible: true },
-  { key: 2, label: `璧勪骇缂栧彿`, visible: true },
-  { key: 3, label: `鎵�灞炴壙鍖呭晢`, visible: true },
-  { key: 4, label: `璧勪骇绫诲瀷`, visible: true },
-  { key: 5, label: `璧勪骇浠峰�糮, visible: true },
-  { key: 6, label: `鐘舵�乣, visible: true },
-  { key: 7, label: `鍒涘缓鏃堕棿`, visible: true },
-]);
-
-const data = reactive({
-  form: {
-    assetId: undefined,
-    assetName: undefined,
-    assetCode: undefined,
-    contractorId: undefined,
-    contractorName: undefined,
-    assetType: undefined,
-    assetValue: 0,
-    status: "0",
-    remark: undefined,
-  },
-  queryParams: {
-    pageNum: 1,
-    pageSize: 10,
-    assetName: undefined,
-    assetCode: undefined,
-    contractorId: undefined,
-    status: undefined,
-  },
-  rules: {
-    assetName: [
-      { required: true, message: "璧勪骇鍚嶇О涓嶈兘涓虹┖", trigger: "blur" },
-    ],
-    assetCode: [
-      { required: true, message: "璧勪骇缂栧彿涓嶈兘涓虹┖", trigger: "blur" },
-    ],
-    contractorId: [
-      { required: true, message: "鎵�灞炴壙鍖呭晢涓嶈兘涓虹┖", trigger: "blur" },
-    ],
-    assetType: [
-      { required: true, message: "璧勪骇绫诲瀷涓嶈兘涓虹┖", trigger: "blur" },
-    ],
-    assetValue: [
-      { required: true, message: "璧勪骇浠峰�间笉鑳戒负绌�", trigger: "blur" },
-      { type: "number", message: "璇疯緭鍏ユ纭殑鏁板瓧", trigger: "blur" },
-    ],
-  },
-});
-
-const { queryParams, form, rules } = toRefs(data);
-
-// 妯℃嫙鎵垮寘鍟嗘暟鎹�
-const contractorOptions = ref([
-  { contractorId: 1, contractorName: "鍖椾含寤哄伐闆嗗洟" },
-  { contractorId: 2, contractorName: "涓婃捣鍩庡缓闆嗗洟" },
-  { contractorId: 3, contractorName: "骞垮窞寤虹瓚闆嗗洟" },
-  { contractorId: 4, contractorName: "娣卞湷寤哄伐闆嗗洟" },
-  { contractorId: 5, contractorName: "鏉窞寤哄伐闆嗗洟" },
-]);
-
-// 璧勪骇绫诲瀷瀛楀吀
-const asset_types = ref([
-  { value: "equipment", label: "璁惧" },
-  { value: "material", label: "鏉愭枡" },
-  { value: "vehicle", label: "杞﹁締" },
-  { value: "tool", label: "宸ュ叿" },
-  { value: "other", label: "鍏朵粬" },
-]);
-
-// 璧勪骇鐘舵�佸瓧鍏�
-const asset_status = ref([
-  { value: "0", label: "姝e父" },
-  { value: "1", label: "绂佺敤" },
-  { value: "2", label: "缁翠慨涓�" },
-  { value: "3", label: "宸叉姤搴�" },
-]);
-
-// 姝e父绂佺敤瀛楀吀
-const sys_normal_disable = ref([
-  { value: "0", label: "姝e父" },
-  { value: "1", label: "绂佺敤" },
-]);
-
-// 妯℃嫙璧勪骇鏁版嵁
-const mockAssets = ref([
-  {
-    assetId: 1,
-    assetName: "鎸栨帢鏈�",
-    assetCode: "ASSET001",
-    contractorId: 1,
-    contractorName: "鍖椾含寤哄伐闆嗗洟",
-    assetType: "equipment",
-    assetValue: 500000.00,
-    status: "0",
-    createTime: "2024-01-01 10:00:00",
-    remark: "澶у瀷鎸栨帢鏈�",
-  },
-  {
-    assetId: 2,
-    assetName: "娣峰嚌鍦熸悈鎷屾満",
-    assetCode: "ASSET002",
-    contractorId: 2,
-    contractorName: "涓婃捣鍩庡缓闆嗗洟",
-    assetType: "equipment",
-    assetValue: 150000.00,
-    status: "0",
-    createTime: "2024-01-02 10:00:00",
-    remark: "娣峰嚌鍦熸悈鎷岃澶�",
-  },
-  {
-    assetId: 3,
-    assetName: "瑁呰浇鏈�",
-    assetCode: "ASSET003",
-    contractorId: 3,
-    contractorName: "骞垮窞寤虹瓚闆嗗洟",
-    assetType: "equipment",
-    assetValue: 300000.00,
-    status: "1",
-    createTime: "2024-01-03 10:00:00",
-    remark: "瑁呰浇鏈鸿澶�",
-  },
-  {
-    assetId: 4,
-    assetName: "杩愯緭鍗¤溅",
-    assetCode: "ASSET004",
-    contractorId: 4,
-    contractorName: "娣卞湷寤哄伐闆嗗洟",
-    assetType: "vehicle",
-    assetValue: 400000.00,
-    status: "0",
-    createTime: "2024-01-04 10:00:00",
-    remark: "閲嶅瀷杩愯緭鍗¤溅",
-  },
-  {
-    assetId: 5,
-    assetName: "閽㈢瓔鍒囨柇鏈�",
-    assetCode: "ASSET005",
-    contractorId: 5,
-    contractorName: "鏉窞寤哄伐闆嗗洟",
-    assetType: "tool",
-    assetValue: 20000.00,
-    status: "0",
-    createTime: "2024-01-05 10:00:00",
-    remark: "閽㈢瓔鍔犲伐璁惧",
-  },
-]);
-
-/** 鑾峰彇璧勪骇绫诲瀷鏍囩 */
-function getAssetTypeLabel(value) {
-  const type = asset_types.value.find(item => item.value === value);
-  return type ? type.label : value;
-}
-
-/** 鏌ヨ璧勪骇鍒楄〃 */
-function getList() {
-  loading.value = true;
-  // 妯℃嫙API璇锋眰寤惰繜
-  setTimeout(() => {
-    let data = [...mockAssets];
-    // 妯℃嫙鎼滅储杩囨护
-    if (queryParams.value.assetName) {
-      data = data.filter(item => item.assetName.includes(queryParams.value.assetName));
-    }
-    if (queryParams.value.assetCode) {
-      data = data.filter(item => item.assetCode.includes(queryParams.value.assetCode));
-    }
-    if (queryParams.value.contractorId) {
-      data = data.filter(item => item.contractorId === queryParams.value.contractorId);
-    }
-    if (queryParams.value.status) {
-      data = data.filter(item => item.status === queryParams.value.status);
-    }
-    // 妯℃嫙鍒嗛〉
-    const start = (queryParams.value.pageNum - 1) * queryParams.value.pageSize;
-    const end = start + queryParams.value.pageSize;
-    assetList.value = data.slice(start, end);
-    total.value = data.length;
-    loading.value = false;
-  }, 500);
-}
-
-/** 鎼滅储鎸夐挳鎿嶄綔 */
-function handleQuery() {
-  queryParams.value.pageNum = 1;
-  getList();
-}
-
-/** 閲嶇疆鎸夐挳鎿嶄綔 */
-function resetQuery() {
-  Object.assign(queryParams.value, {
-    assetName: undefined,
-    assetCode: undefined,
-    contractorId: undefined,
-    status: undefined,
-  });
-  handleQuery();
-}
-
-/** 鍒犻櫎鎸夐挳鎿嶄綔 */
-function handleDelete(row) {
-  const assetIds = row.assetId || ids.value;
-  ElMessage.confirm(`鏄惁纭鍒犻櫎璧勪骇缂栧彿涓�"${assetIds}"鐨勬暟鎹」锛焋).then(() => {
-    // 妯℃嫙鍒犻櫎鎿嶄綔
-    ElMessage.success("鍒犻櫎鎴愬姛");
-    getList();
-  }).catch(() => {});
-}
-
-/** 鐘舵�佷慨鏀� */
-function handleStatusChange(row) {
-  let text = row.status === "0" ? "鍚敤" : "鍋滅敤";
-  ElMessage.confirm(`纭瑕�"${text}""${row.assetName}"璧勪骇鍚�?`).then(() => {
-    // 妯℃嫙鐘舵�佷慨鏀�
-    ElMessage.success(text + "鎴愬姛");
-    getList();
-  }).catch(() => {
-    row.status = row.status === "0" ? "1" : "0";
-  });
-}
-
-/** 閫夋嫨鏉℃暟  */
-function handleSelectionChange(selection) {
-  ids.value = selection.map((item) => item.assetId);
-  single.value = selection.length != 1;
-  multiple.value = !selection.length;
-}
-
-/** 閲嶇疆鎿嶄綔琛ㄥ崟 */
-function reset() {
-  form.value = {
-    assetId: undefined,
-    assetName: undefined,
-    assetCode: undefined,
-    contractorId: undefined,
-    contractorName: undefined,
-    assetType: undefined,
-    assetValue: 0,
-    status: "0",
-    remark: undefined,
-  };
-}
-
-/** 鍙栨秷鎸夐挳 */
-function cancel() {
-  open.value = false;
-  reset();
-}
-
-/** 鏂板鎸夐挳鎿嶄綔 */
-function handleAdd() {
-  reset();
-  open.value = true;
-  title.value = "娣诲姞璧勪骇";
-}
-
-/** 淇敼鎸夐挳鎿嶄綔 */
-function handleUpdate(row) {
-  reset();
-  const assetId = row.assetId || ids.value;
-  // 妯℃嫙鑾峰彇璇︽儏
-  const asset = mockAssets.find(item => item.assetId === assetId);
-  if (asset) {
-    form.value = { ...asset };
-    open.value = true;
-    title.value = "淇敼璧勪骇";
-  }
-}
-
-/** 鎻愪氦鎸夐挳 */
-function submitForm() {
-  // 妯℃嫙琛ㄥ崟楠岃瘉
-  const requiredFields = ['assetName', 'assetCode', 'contractorId', 'assetType', 'assetValue'];
-  const isInvalid = requiredFields.some(field => !form.value[field]);
-
-  if (isInvalid) {
-    ElMessage.error("璇峰~鍐欏繀濉瓧娈�");
-    return;
-  }
-
-  // 妯℃嫙鎻愪氦鎿嶄綔
-  ElMessage.success(title.value === "娣诲姞璧勪骇" ? "鏂板鎴愬姛" : "淇敼鎴愬姛");
-  open.value = false;
-  getList();
-}
-
-onMounted(() => {
-  getList();
-});
-</script>
diff --git a/src/views/contractor/compliance/index.vue b/src/views/contractor/compliance/index.vue
deleted file mode 100644
index 7fbe1a2..0000000
--- a/src/views/contractor/compliance/index.vue
+++ /dev/null
@@ -1,664 +0,0 @@
-<template>
-  <div class="app-container">
-    <el-form
-      :model="queryParams"
-      ref="queryRef"
-      :inline="true"
-      v-show="showSearch"
-      label-width="90px"
-    >
-      <el-form-item label="鍚堣鍚嶇О" prop="complianceName">
-        <el-input
-          v-model="queryParams.complianceName"
-          placeholder="璇疯緭鍏ュ悎瑙勫悕绉�"
-          clearable
-          style="width: 220px"
-          @keyup.enter="handleQuery"
-        />
-      </el-form-item>
-      <el-form-item label="鍚堣缂栧彿" prop="complianceCode">
-        <el-input
-          v-model="queryParams.complianceCode"
-          placeholder="璇疯緭鍏ュ悎瑙勭紪鍙�"
-          clearable
-          style="width: 240px"
-          @keyup.enter="handleQuery"
-        />
-      </el-form-item>
-      <el-form-item label="鎵�灞炴壙鍖呭晢" prop="contractorId">
-        <el-select
-          v-model="queryParams.contractorId"
-          placeholder="璇烽�夋嫨鎵垮寘鍟�"
-          clearable
-          style="width: 240px"
-        >
-          <el-option
-            v-for="contractor in contractorOptions"
-            :key="contractor.contractorId"
-            :label="contractor.contractorName"
-            :value="contractor.contractorId"
-          />
-        </el-select>
-      </el-form-item>
-      <el-form-item label="鍚堣鐘舵��" prop="status">
-        <el-select
-          v-model="queryParams.status"
-          placeholder="鍚堣鐘舵��"
-          clearable
-          style="width: 240px"
-        >
-          <el-option
-            v-for="dict in compliance_status"
-            :key="dict.value"
-            :label="dict.label"
-            :value="dict.value"
-          />
-        </el-select>
-      </el-form-item>
-      <el-form-item>
-        <el-button type="primary" icon="Search" @click="handleQuery"
-          >鎼滅储</el-button
-        >
-        <el-button icon="Refresh" @click="resetQuery">閲嶇疆</el-button>
-      </el-form-item>
-    </el-form>
-
-    <el-row :gutter="10" class="mb8">
-      <el-col :span="1.5">
-        <el-button
-          type="primary"
-          plain
-          icon="Plus"
-          @click="handleAdd"
-          >鏂板</el-button
-        >
-      </el-col>
-      <el-col :span="1.5">
-        <el-button
-          type="success"
-          plain
-          icon="Edit"
-          :disabled="single"
-          @click="handleUpdate"
-          >淇敼</el-button
-        >
-      </el-col>
-      <el-col :span="1.5">
-        <el-button
-          type="danger"
-          plain
-          icon="Delete"
-          :disabled="multiple"
-          @click="handleDelete"
-          >鍒犻櫎</el-button
-        >
-      </el-col>
-      <right-toolbar
-        v-model:showSearch="showSearch"
-        @queryTable="getList"
-        :columns="columns"
-      ></right-toolbar>
-    </el-row>
-
-    <el-table
-      v-loading="loading"
-      :data="complianceList"
-      @selection-change="handleSelectionChange"
-      stripe
-    >
-      <el-table-column type="selection" width="50" align="center" />
-      <el-table-column
-        label="鍚堣ID"
-        align="center"
-        key="complianceId"
-        prop="complianceId"
-        v-if="columns[0].visible"
-      />
-      <el-table-column
-        label="鍚堣鍚嶇О"
-        align="center"
-        key="complianceName"
-        prop="complianceName"
-        v-if="columns[1].visible"
-        :show-overflow-tooltip="true"
-      />
-      <el-table-column
-        label="鍚堣缂栧彿"
-        align="center"
-        key="complianceCode"
-        prop="complianceCode"
-        v-if="columns[2].visible"
-      />
-      <el-table-column
-        label="鎵�灞炴壙鍖呭晢"
-        align="center"
-        key="contractorName"
-        prop="contractorName"
-        v-if="columns[3].visible"
-        :show-overflow-tooltip="true"
-      />
-      <el-table-column
-        label="鍚堣绫诲瀷"
-        align="center"
-        key="complianceType"
-        prop="complianceType"
-        v-if="columns[4].visible"
-      >
-        <template #default="scope">
-          {{ getComplianceTypeLabel(scope.row.complianceType) }}
-        </template>
-      </el-table-column>
-      <el-table-column
-        label="鏈夋晥鏈熷紑濮�"
-        align="center"
-        key="validStartDate"
-        prop="validStartDate"
-        v-if="columns[5].visible"
-        width="140"
-      />
-      <el-table-column
-        label="鏈夋晥鏈熺粨鏉�"
-        align="center"
-        key="validEndDate"
-        prop="validEndDate"
-        v-if="columns[6].visible"
-        width="140"
-      />
-      <el-table-column
-        label="鐘舵��"
-        align="center"
-        key="status"
-        v-if="columns[7].visible"
-      >
-        <template #default="scope">
-          <el-switch
-            v-model="scope.row.status"
-            active-value="0"
-            inactive-value="1"
-            @change="handleStatusChange(scope.row)"
-          ></el-switch>
-        </template>
-      </el-table-column>
-      <el-table-column
-        label="鍒涘缓鏃堕棿"
-        align="center"
-        prop="createTime"
-        v-if="columns[8].visible"
-        width="160"
-      >
-        <template #default="scope">
-          <span>{{ parseTime(scope.row.createTime) }}</span>
-        </template>
-      </el-table-column>
-      <el-table-column
-        label="鎿嶄綔"
-        align="center"
-        width="150"
-        class-name="small-padding fixed-width"
-      >
-        <template #default="scope">
-          <el-tooltip
-            content="淇敼"
-            placement="top"
-          >
-            <el-button
-              link
-              type="primary"
-              icon="Edit"
-              @click="handleUpdate(scope.row)"
-            ></el-button>
-          </el-tooltip>
-          <el-tooltip
-            content="鍒犻櫎"
-            placement="top"
-          >
-            <el-button
-              link
-              type="primary"
-              icon="Delete"
-              @click="handleDelete(scope.row)"
-            ></el-button>
-          </el-tooltip>
-        </template>
-      </el-table-column>
-    </el-table>
-    <pagination
-      v-show="total > 0"
-      :total="total"
-      v-model:page="queryParams.pageNum"
-      v-model:limit="queryParams.pageSize"
-      @pagination="getList"
-    />
-
-    <!-- 娣诲姞鎴栦慨鏀瑰悎瑙勯厤缃璇濇 -->
-    <el-dialog :title="title" v-model="open" width="600px" append-to-body>
-      <el-form :model="form" :rules="rules" ref="complianceRef" label-width="80px">
-        <el-row>
-          <el-col :span="12">
-            <el-form-item label="鍚堣鍚嶇О" prop="complianceName">
-              <el-input
-                v-model="form.complianceName"
-                placeholder="璇疯緭鍏ュ悎瑙勫悕绉�"
-                maxlength="50"
-              />
-            </el-form-item>
-          </el-col>
-          <el-col :span="12">
-            <el-form-item label="鍚堣缂栧彿" prop="complianceCode">
-              <el-input
-                v-model="form.complianceCode"
-                placeholder="璇疯緭鍏ュ悎瑙勭紪鍙�"
-                maxlength="20"
-              />
-            </el-form-item>
-          </el-col>
-        </el-row>
-        <el-row>
-          <el-col :span="12">
-            <el-form-item label="鎵�灞炴壙鍖呭晢" prop="contractorId">
-              <el-select
-                v-model="form.contractorId"
-                placeholder="璇烽�夋嫨鎵垮寘鍟�"
-                clearable
-              >
-                <el-option
-                  v-for="contractor in contractorOptions"
-                  :key="contractor.contractorId"
-                  :label="contractor.contractorName"
-                  :value="contractor.contractorId"
-                />
-              </el-select>
-            </el-form-item>
-          </el-col>
-          <el-col :span="12">
-            <el-form-item label="鍚堣绫诲瀷" prop="complianceType">
-              <el-select
-                v-model="form.complianceType"
-                placeholder="璇烽�夋嫨鍚堣绫诲瀷"
-                clearable
-              >
-                <el-option
-                  v-for="type in compliance_types"
-                  :key="type.value"
-                  :label="type.label"
-                  :value="type.value"
-                />
-              </el-select>
-            </el-form-item>
-          </el-col>
-        </el-row>
-        <el-row>
-          <el-col :span="12">
-            <el-form-item label="鏈夋晥鏈熷紑濮�" prop="validStartDate">
-              <el-date-picker
-                v-model="form.validStartDate"
-                type="date"
-                placeholder="閫夋嫨寮�濮嬫棩鏈�"
-                value-format="YYYY-MM-DD"
-              />
-            </el-form-item>
-          </el-col>
-          <el-col :span="12">
-            <el-form-item label="鏈夋晥鏈熺粨鏉�" prop="validEndDate">
-              <el-date-picker
-                v-model="form.validEndDate"
-                type="date"
-                placeholder="閫夋嫨缁撴潫鏃ユ湡"
-                value-format="YYYY-MM-DD"
-              />
-            </el-form-item>
-          </el-col>
-        </el-row>
-        <el-row>
-          <el-col :span="12">
-            <el-form-item label="鐘舵��">
-              <el-radio-group v-model="form.status">
-                <el-radio
-                  v-for="dict in sys_normal_disable"
-                  :key="dict.value"
-                  :value="dict.value"
-                  >{{ dict.label }}</el-radio
-                >
-              </el-radio-group>
-            </el-form-item>
-          </el-col>
-        </el-row>
-        <el-row>
-          <el-col :span="24">
-            <el-form-item label="澶囨敞">
-              <el-input
-                v-model="form.remark"
-                type="textarea"
-                placeholder="璇疯緭鍏ュ唴瀹�"
-              ></el-input>
-            </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="cancel">鍙� 娑�</el-button>
-        </div>
-      </template>
-    </el-dialog>
-  </div>
-</template>
-
-<script setup name="ContractorCompliance">
-import { ref, reactive, toRefs, watch, onMounted } from 'vue';
-import { ElMessage } from 'element-plus';
-import { parseTime } from '@/utils/ruoyi';
-
-const complianceList = ref([]);
-const open = ref(false);
-const loading = ref(true);
-const showSearch = ref(true);
-const ids = ref([]);
-const single = ref(true);
-const multiple = ref(true);
-const total = ref(0);
-const title = ref("");
-
-// 鍒楁樉闅愪俊鎭�
-const columns = ref([
-  { key: 0, label: `鍚堣ID`, visible: true },
-  { key: 1, label: `鍚堣鍚嶇О`, visible: true },
-  { key: 2, label: `鍚堣缂栧彿`, visible: true },
-  { key: 3, label: `鎵�灞炴壙鍖呭晢`, visible: true },
-  { key: 4, label: `鍚堣绫诲瀷`, visible: true },
-  { key: 5, label: `鏈夋晥鏈熷紑濮媊, visible: true },
-  { key: 6, label: `鏈夋晥鏈熺粨鏉焋, visible: true },
-  { key: 7, label: `鐘舵�乣, visible: true },
-  { key: 8, label: `鍒涘缓鏃堕棿`, visible: true },
-]);
-
-const data = reactive({
-  form: {
-    complianceId: undefined,
-    complianceName: undefined,
-    complianceCode: undefined,
-    contractorId: undefined,
-    contractorName: undefined,
-    complianceType: undefined,
-    validStartDate: undefined,
-    validEndDate: undefined,
-    status: "0",
-    remark: undefined,
-  },
-  queryParams: {
-    pageNum: 1,
-    pageSize: 10,
-    complianceName: undefined,
-    complianceCode: undefined,
-    contractorId: undefined,
-    status: undefined,
-  },
-  rules: {
-    complianceName: [
-      { required: true, message: "鍚堣鍚嶇О涓嶈兘涓虹┖", trigger: "blur" },
-    ],
-    complianceCode: [
-      { required: true, message: "鍚堣缂栧彿涓嶈兘涓虹┖", trigger: "blur" },
-    ],
-    contractorId: [
-      { required: true, message: "鎵�灞炴壙鍖呭晢涓嶈兘涓虹┖", trigger: "blur" },
-    ],
-    complianceType: [
-      { required: true, message: "鍚堣绫诲瀷涓嶈兘涓虹┖", trigger: "blur" },
-    ],
-    validStartDate: [
-      { required: true, message: "鏈夋晥鏈熷紑濮嬩笉鑳戒负绌�", trigger: "blur" },
-    ],
-    validEndDate: [
-      { required: true, message: "鏈夋晥鏈熺粨鏉熶笉鑳戒负绌�", trigger: "blur" },
-    ],
-  },
-});
-
-const { queryParams, form, rules } = toRefs(data);
-
-// 妯℃嫙鎵垮寘鍟嗘暟鎹�
-const contractorOptions = ref([
-  { contractorId: 1, contractorName: "鍖椾含寤哄伐闆嗗洟" },
-  { contractorId: 2, contractorName: "涓婃捣鍩庡缓闆嗗洟" },
-  { contractorId: 3, contractorName: "骞垮窞寤虹瓚闆嗗洟" },
-  { contractorId: 4, contractorName: "娣卞湷寤哄伐闆嗗洟" },
-  { contractorId: 5, contractorName: "鏉窞寤哄伐闆嗗洟" },
-]);
-
-// 鍚堣绫诲瀷瀛楀吀
-const compliance_types = ref([
-  { value: "license", label: "璁稿彲璇�" },
-  { value: "certificate", label: "璇佷功" },
-  { value: "regulation", label: "娉曡閬靛惊" },
-  { value: "standard", label: "鏍囧噯鍚堣" },
-  { value: "other", label: "鍏朵粬" },
-]);
-
-// 鍚堣鐘舵�佸瓧鍏�
-const compliance_status = ref([
-  { value: "0", label: "姝e父" },
-  { value: "1", label: "绂佺敤" },
-  { value: "2", label: "鍗冲皢杩囨湡" },
-  { value: "3", label: "宸茶繃鏈�" },
-]);
-
-// 姝e父绂佺敤瀛楀吀
-const sys_normal_disable = ref([
-  { value: "0", label: "姝e父" },
-  { value: "1", label: "绂佺敤" },
-]);
-
-// 妯℃嫙鍚堣鏁版嵁
-const mockCompliances = ref([
-  {
-    complianceId: 1,
-    complianceName: "寤虹瓚鏂藉伐璁稿彲璇�",
-    complianceCode: "COMP001",
-    contractorId: 1,
-    contractorName: "鍖椾含寤哄伐闆嗗洟",
-    complianceType: "license",
-    validStartDate: "2024-01-01",
-    validEndDate: "2025-12-31",
-    status: "0",
-    createTime: "2024-01-01 10:00:00",
-    remark: "寤虹瓚鏂藉伐璁稿彲璇�",
-  },
-  {
-    complianceId: 2,
-    complianceName: "瀹夊叏鐢熶骇璁稿彲璇�",
-    complianceCode: "COMP002",
-    contractorId: 2,
-    contractorName: "涓婃捣鍩庡缓闆嗗洟",
-    complianceType: "license",
-    validStartDate: "2024-01-02",
-    validEndDate: "2025-12-31",
-    status: "0",
-    createTime: "2024-01-02 10:00:00",
-    remark: "瀹夊叏鐢熶骇璁稿彲璇�",
-  },
-  {
-    complianceId: 3,
-    complianceName: "璐ㄩ噺绠$悊浣撶郴璁よ瘉",
-    complianceCode: "COMP003",
-    contractorId: 3,
-    contractorName: "骞垮窞寤虹瓚闆嗗洟",
-    complianceType: "certificate",
-    validStartDate: "2024-01-03",
-    validEndDate: "2025-12-31",
-    status: "1",
-    createTime: "2024-01-03 10:00:00",
-    remark: "ISO9001璐ㄩ噺绠$悊浣撶郴璁よ瘉",
-  },
-  {
-    complianceId: 4,
-    complianceName: "鐜绠$悊浣撶郴璁よ瘉",
-    complianceCode: "COMP004",
-    contractorId: 4,
-    contractorName: "娣卞湷寤哄伐闆嗗洟",
-    complianceType: "certificate",
-    validStartDate: "2024-01-04",
-    validEndDate: "2025-12-31",
-    status: "0",
-    createTime: "2024-01-04 10:00:00",
-    remark: "ISO14001鐜绠$悊浣撶郴璁よ瘉",
-  },
-  {
-    complianceId: 5,
-    complianceName: "鑱屼笟鍋ュ悍瀹夊叏绠$悊浣撶郴璁よ瘉",
-    complianceCode: "COMP005",
-    contractorId: 5,
-    contractorName: "鏉窞寤哄伐闆嗗洟",
-    complianceType: "certificate",
-    validStartDate: "2024-01-05",
-    validEndDate: "2025-12-31",
-    status: "0",
-    createTime: "2024-01-05 10:00:00",
-    remark: "ISO45001鑱屼笟鍋ュ悍瀹夊叏绠$悊浣撶郴璁よ瘉",
-  },
-]);
-
-/** 鑾峰彇鍚堣绫诲瀷鏍囩 */
-function getComplianceTypeLabel(value) {
-  const type = compliance_types.value.find(item => item.value === value);
-  return type ? type.label : value;
-}
-
-/** 鏌ヨ鍚堣鍒楄〃 */
-function getList() {
-  loading.value = true;
-  // 妯℃嫙API璇锋眰寤惰繜
-  setTimeout(() => {
-    let data = [...mockCompliances.value];
-    // 妯℃嫙鎼滅储杩囨护
-    if (queryParams.value.complianceName) {
-      data = data.filter(item => item.complianceName.includes(queryParams.value.complianceName));
-    }
-    if (queryParams.value.complianceCode) {
-      data = data.filter(item => item.complianceCode.includes(queryParams.value.complianceCode));
-    }
-    if (queryParams.value.contractorId) {
-      data = data.filter(item => item.contractorId === queryParams.value.contractorId);
-    }
-    if (queryParams.value.status) {
-      data = data.filter(item => item.status === queryParams.value.status);
-    }
-    // 妯℃嫙鍒嗛〉
-    const start = (queryParams.value.pageNum - 1) * queryParams.value.pageSize;
-    const end = start + queryParams.value.pageSize;
-    complianceList.value = data.slice(start, end);
-    total.value = data.length;
-    loading.value = false;
-  }, 500);
-}
-
-/** 鎼滅储鎸夐挳鎿嶄綔 */
-function handleQuery() {
-  queryParams.value.pageNum = 1;
-  getList();
-}
-
-/** 閲嶇疆鎸夐挳鎿嶄綔 */
-function resetQuery() {
-  Object.assign(queryParams.value, {
-    complianceName: undefined,
-    complianceCode: undefined,
-    contractorId: undefined,
-    status: undefined,
-  });
-  handleQuery();
-}
-
-/** 鍒犻櫎鎸夐挳鎿嶄綔 */
-function handleDelete(row) {
-  const complianceIds = row.complianceId || ids.value;
-  ElMessage.confirm(`鏄惁纭鍒犻櫎鍚堣缂栧彿涓�"${complianceIds}"鐨勬暟鎹」锛焋).then(() => {
-    // 妯℃嫙鍒犻櫎鎿嶄綔
-    ElMessage.success("鍒犻櫎鎴愬姛");
-    getList();
-  }).catch(() => {});
-}
-
-/** 鐘舵�佷慨鏀� */
-function handleStatusChange(row) {
-  let text = row.status === "0" ? "鍚敤" : "鍋滅敤";
-  ElMessage.confirm(`纭瑕�"${text}""${row.complianceName}"鍚堣璁板綍鍚�?`).then(() => {
-    // 妯℃嫙鐘舵�佷慨鏀�
-    ElMessage.success(text + "鎴愬姛");
-    getList();
-  }).catch(() => {
-    row.status = row.status === "0" ? "1" : "0";
-  });
-}
-
-/** 閫夋嫨鏉℃暟  */
-function handleSelectionChange(selection) {
-  ids.value = selection.map((item) => item.complianceId);
-  single.value = selection.length != 1;
-  multiple.value = !selection.length;
-}
-
-/** 閲嶇疆鎿嶄綔琛ㄥ崟 */
-function reset() {
-  form.value = {
-    complianceId: undefined,
-    complianceName: undefined,
-    complianceCode: undefined,
-    contractorId: undefined,
-    contractorName: undefined,
-    complianceType: undefined,
-    validStartDate: undefined,
-    validEndDate: undefined,
-    status: "0",
-    remark: undefined,
-  };
-}
-
-/** 鍙栨秷鎸夐挳 */
-function cancel() {
-  open.value = false;
-  reset();
-}
-
-/** 鏂板鎸夐挳鎿嶄綔 */
-function handleAdd() {
-  reset();
-  open.value = true;
-  title.value = "娣诲姞鍚堣璁板綍";
-}
-
-/** 淇敼鎸夐挳鎿嶄綔 */
-function handleUpdate(row) {
-  reset();
-  const complianceId = row.complianceId || ids.value;
-  // 妯℃嫙鑾峰彇璇︽儏
-  const compliance = mockCompliances.find(item => item.complianceId === complianceId);
-  if (compliance) {
-    form.value = { ...compliance };
-    open.value = true;
-    title.value = "淇敼鍚堣璁板綍";
-  }
-}
-
-/** 鎻愪氦鎸夐挳 */
-function submitForm() {
-  // 妯℃嫙琛ㄥ崟楠岃瘉
-  const requiredFields = ['complianceName', 'complianceCode', 'contractorId', 'complianceType', 'validStartDate', 'validEndDate'];
-  const isInvalid = requiredFields.some(field => !form.value[field]);
-
-  if (isInvalid) {
-    ElMessage.error("璇峰~鍐欏繀濉瓧娈�");
-    return;
-  }
-
-  // 妯℃嫙鎻愪氦鎿嶄綔
-  ElMessage.success(title.value === "娣诲姞鍚堣璁板綍" ? "鏂板鎴愬姛" : "淇敼鎴愬姛");
-  open.value = false;
-  getList();
-}
-
-onMounted(() => {
-  getList();
-});
-</script>
diff --git a/src/views/contractor/list/index.vue b/src/views/contractor/list/index.vue
deleted file mode 100644
index 8767039..0000000
--- a/src/views/contractor/list/index.vue
+++ /dev/null
@@ -1,572 +0,0 @@
-<template>
-  <div class="app-container">
-    <el-form
-      :model="queryParams"
-      ref="queryRef"
-      :inline="true"
-      v-show="showSearch"
-      label-width="90px"
-    >
-      <el-form-item label="鎵垮寘鍟嗗悕绉�" prop="contractorName">
-        <el-input
-          v-model="queryParams.contractorName"
-          placeholder="璇疯緭鍏ユ壙鍖呭晢鍚嶇О"
-          clearable
-          style="width: 220px"
-          @keyup.enter="handleQuery"
-        />
-      </el-form-item>
-      <el-form-item label="鑱旂郴浜�" prop="contactPerson">
-        <el-input
-          v-model="queryParams.contactPerson"
-          placeholder="璇疯緭鍏ヨ仈绯讳汉"
-          clearable
-          style="width: 240px"
-          @keyup.enter="handleQuery"
-        />
-      </el-form-item>
-      <el-form-item label="鑱旂郴鐢佃瘽" prop="contactPhone">
-        <el-input
-          v-model="queryParams.contactPhone"
-          placeholder="璇疯緭鍏ヨ仈绯荤數璇�"
-          clearable
-          style="width: 240px"
-          @keyup.enter="handleQuery"
-        />
-      </el-form-item>
-      <el-form-item label="鐘舵��" prop="status">
-        <el-select
-          v-model="queryParams.status"
-          placeholder="鎵垮寘鍟嗙姸鎬�"
-          clearable
-          style="width: 240px"
-        >
-          <el-option
-            v-for="dict in sys_normal_disable"
-            :key="dict.value"
-            :label="dict.label"
-            :value="dict.value"
-          />
-        </el-select>
-      </el-form-item>
-      <el-form-item>
-        <el-button type="primary" icon="Search" @click="handleQuery"
-          >鎼滅储</el-button
-        >
-        <el-button icon="Refresh" @click="resetQuery">閲嶇疆</el-button>
-      </el-form-item>
-    </el-form>
-
-    <el-row :gutter="10" class="mb8">
-      <el-col :span="1.5">
-        <el-button
-          type="primary"
-          plain
-          icon="Plus"
-          @click="handleAdd"
-          >鏂板</el-button
-        >
-      </el-col>
-      <el-col :span="1.5">
-        <el-button
-          type="success"
-          plain
-          icon="Edit"
-          :disabled="single"
-          @click="handleUpdate"
-          >淇敼</el-button
-        >
-      </el-col>
-      <el-col :span="1.5">
-        <el-button
-          type="danger"
-          plain
-          icon="Delete"
-          :disabled="multiple"
-          @click="handleDelete"
-          >鍒犻櫎</el-button
-        >
-      </el-col>
-      <right-toolbar
-        v-model:showSearch="showSearch"
-        @queryTable="getList"
-        :columns="columns"
-      ></right-toolbar>
-    </el-row>
-
-    <el-table
-      v-loading="loading"
-      :data="contractorList"
-      @selection-change="handleSelectionChange"
-      stripe
-    >
-      <el-table-column type="selection" width="50" align="center" />
-      <el-table-column
-        label="鎵垮寘鍟嗙紪鍙�"
-        align="center"
-        key="contractorId"
-        prop="contractorId"
-        v-if="columns[0].visible"
-      />
-      <el-table-column
-        label="鎵垮寘鍟嗗悕绉�"
-        align="center"
-        key="contractorName"
-        prop="contractorName"
-        v-if="columns[1].visible"
-        :show-overflow-tooltip="true"
-      />
-      <el-table-column
-        label="鑱旂郴浜�"
-        align="center"
-        key="contactPerson"
-        prop="contactPerson"
-        v-if="columns[2].visible"
-      />
-      <el-table-column
-        label="鑱旂郴鐢佃瘽"
-        align="center"
-        key="contactPhone"
-        prop="contactPhone"
-        v-if="columns[3].visible"
-      />
-      <el-table-column
-        label="鑱旂郴閭"
-        align="center"
-        key="contactEmail"
-        prop="contactEmail"
-        v-if="columns[4].visible"
-        :show-overflow-tooltip="true"
-      />
-      <el-table-column
-        label="鍦板潃"
-        align="center"
-        key="address"
-        prop="address"
-        v-if="columns[5].visible"
-        :show-overflow-tooltip="true"
-      />
-      <el-table-column
-        label="鐘舵��"
-        align="center"
-        key="status"
-        v-if="columns[6].visible"
-      >
-        <template #default="scope">
-          <el-switch
-            v-model="scope.row.status"
-            active-value="0"
-            inactive-value="1"
-            @change="handleStatusChange(scope.row)"
-          ></el-switch>
-        </template>
-      </el-table-column>
-      <el-table-column
-        label="鍒涘缓鏃堕棿"
-        align="center"
-        prop="createTime"
-        v-if="columns[7].visible"
-        width="160"
-      >
-        <template #default="scope">
-          <span>{{ parseTime(scope.row.createTime) }}</span>
-        </template>
-      </el-table-column>
-      <el-table-column
-        label="鎿嶄綔"
-        align="center"
-        width="150"
-        class-name="small-padding fixed-width"
-      >
-        <template #default="scope">
-          <el-tooltip
-            content="淇敼"
-            placement="top"
-          >
-            <el-button
-              link
-              type="primary"
-              icon="Edit"
-              @click="handleUpdate(scope.row)"
-            ></el-button>
-          </el-tooltip>
-          <el-tooltip
-            content="鍒犻櫎"
-            placement="top"
-          >
-            <el-button
-              link
-              type="primary"
-              icon="Delete"
-              @click="handleDelete(scope.row)"
-            ></el-button>
-          </el-tooltip>
-        </template>
-      </el-table-column>
-    </el-table>
-    <pagination
-      v-show="total > 0"
-      :total="total"
-      v-model:page="queryParams.pageNum"
-      v-model:limit="queryParams.pageSize"
-      @pagination="getList"
-    />
-
-    <!-- 娣诲姞鎴栦慨鏀规壙鍖呭晢閰嶇疆瀵硅瘽妗� -->
-    <el-dialog :title="title" v-model="open" width="600px" append-to-body>
-      <el-form :model="form" :rules="rules" ref="contractorRef" label-width="80px">
-        <el-row>
-          <el-col :span="12">
-            <el-form-item label="鎵垮寘鍟嗗悕绉�" prop="contractorName">
-              <el-input
-                v-model="form.contractorName"
-                placeholder="璇疯緭鍏ユ壙鍖呭晢鍚嶇О"
-                maxlength="50"
-              />
-            </el-form-item>
-          </el-col>
-          <el-col :span="12">
-            <el-form-item label="鑱旂郴浜�" prop="contactPerson">
-              <el-input
-                v-model="form.contactPerson"
-                placeholder="璇疯緭鍏ヨ仈绯讳汉"
-                maxlength="20"
-              />
-            </el-form-item>
-          </el-col>
-        </el-row>
-        <el-row>
-          <el-col :span="12">
-            <el-form-item label="鑱旂郴鐢佃瘽" prop="contactPhone">
-              <el-input
-                v-model="form.contactPhone"
-                placeholder="璇疯緭鍏ヨ仈绯荤數璇�"
-                maxlength="11"
-              />
-            </el-form-item>
-          </el-col>
-          <el-col :span="12">
-            <el-form-item label="鑱旂郴閭" prop="contactEmail">
-              <el-input
-                v-model="form.contactEmail"
-                placeholder="璇疯緭鍏ヨ仈绯婚偖绠�"
-                maxlength="50"
-              />
-            </el-form-item>
-          </el-col>
-        </el-row>
-        <el-row>
-          <el-col :span="24">
-            <el-form-item label="鍦板潃" prop="address">
-              <el-input
-                v-model="form.address"
-                placeholder="璇疯緭鍏ュ湴鍧�"
-                maxlength="100"
-              />
-            </el-form-item>
-          </el-col>
-        </el-row>
-        <el-row>
-          <el-col :span="12">
-            <el-form-item label="鐘舵��">
-              <el-radio-group v-model="form.status">
-                <el-radio
-                  v-for="dict in sys_normal_disable"
-                  :key="dict.value"
-                  :value="dict.value"
-                  >{{ dict.label }}</el-radio
-                >
-              </el-radio-group>
-            </el-form-item>
-          </el-col>
-        </el-row>
-        <el-row>
-          <el-col :span="24">
-            <el-form-item label="澶囨敞">
-              <el-input
-                v-model="form.remark"
-                type="textarea"
-                placeholder="璇疯緭鍏ュ唴瀹�"
-              ></el-input>
-            </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="cancel">鍙� 娑�</el-button>
-        </div>
-      </template>
-    </el-dialog>
-  </div>
-</template>
-
-<script setup name="Contractor">
-import { ref, reactive, toRefs, watch, onMounted } from 'vue';
-import { ElMessage } from 'element-plus';
-import { parseTime } from '@/utils/ruoyi';
-
-const contractorList = ref([]);
-const open = ref(false);
-const loading = ref(true);
-const showSearch = ref(true);
-const ids = ref([]);
-const single = ref(true);
-const multiple = ref(true);
-const total = ref(0);
-const title = ref("");
-
-// 鍒楁樉闅愪俊鎭�
-const columns = ref([
-  { key: 0, label: `鎵垮寘鍟嗙紪鍙穈, visible: true },
-  { key: 1, label: `鎵垮寘鍟嗗悕绉癭, visible: true },
-  { key: 2, label: `鑱旂郴浜篳, visible: true },
-  { key: 3, label: `鑱旂郴鐢佃瘽`, visible: true },
-  { key: 4, label: `鑱旂郴閭`, visible: true },
-  { key: 5, label: `鍦板潃`, visible: true },
-  { key: 6, label: `鐘舵�乣, visible: true },
-  { key: 7, label: `鍒涘缓鏃堕棿`, visible: true },
-]);
-
-const data = reactive({
-  form: {
-    contractorId: undefined,
-    contractorName: undefined,
-    contactPerson: undefined,
-    contactPhone: undefined,
-    contactEmail: undefined,
-    address: undefined,
-    status: "0",
-    remark: undefined,
-  },
-  queryParams: {
-    pageNum: 1,
-    pageSize: 10,
-    contractorName: undefined,
-    contactPerson: undefined,
-    contactPhone: undefined,
-    status: undefined,
-  },
-  rules: {
-    contractorName: [
-      { required: true, message: "鎵垮寘鍟嗗悕绉颁笉鑳戒负绌�", trigger: "blur" },
-    ],
-    contactPerson: [
-      { required: true, message: "鑱旂郴浜轰笉鑳戒负绌�", trigger: "blur" },
-    ],
-    contactPhone: [
-      { required: true, message: "鑱旂郴鐢佃瘽涓嶈兘涓虹┖", trigger: "blur" },
-      { pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/, message: "璇疯緭鍏ユ纭殑鎵嬫満鍙风爜", trigger: "blur" },
-    ],
-    contactEmail: [
-      { type: "email", message: "璇疯緭鍏ユ纭殑閭鍦板潃", trigger: ["blur", "change"] },
-    ],
-    address: [
-      { required: true, message: "鍦板潃涓嶈兘涓虹┖", trigger: "blur" },
-    ],
-  },
-});
-
-const { queryParams, form, rules } = toRefs(data);
-
-// 妯℃嫙鏁版嵁
-const mockContractors = [
-  {
-    contractorId: 1,
-    contractorName: "鍖椾含寤哄伐闆嗗洟",
-    contactPerson: "寮犱笁",
-    contactPhone: "13800138001",
-    contactEmail: "zhangsan@example.com",
-    address: "鍖椾含甯傛湞闃冲尯寤哄浗璺�88鍙�",
-    status: "0",
-    createTime: "2024-01-01 10:00:00",
-    remark: "澶у瀷寤虹瓚鏂藉伐浼佷笟",
-  },
-  {
-    contractorId: 2,
-    contractorName: "涓婃捣鍩庡缓闆嗗洟",
-    contactPerson: "鏉庡洓",
-    contactPhone: "13800138002",
-    contactEmail: "lisi@example.com",
-    address: "涓婃捣甯傛郸涓滄柊鍖轰笘绾ぇ閬�100鍙�",
-    status: "0",
-    createTime: "2024-01-02 10:00:00",
-    remark: "鍩庡競鍩虹璁炬柦寤鸿浼佷笟",
-  },
-  {
-    contractorId: 3,
-    contractorName: "骞垮窞寤虹瓚闆嗗洟",
-    contactPerson: "鐜嬩簲",
-    contactPhone: "13800138003",
-    contactEmail: "wangwu@example.com",
-    address: "骞垮窞甯傚ぉ娌冲尯鐝犳睙鏂板煄鍐兼潙璺�5鍙�",
-    status: "1",
-    createTime: "2024-01-03 10:00:00",
-    remark: "骞夸笢鐪佺煡鍚嶅缓绛戜紒涓�",
-  },
-  {
-    contractorId: 4,
-    contractorName: "娣卞湷寤哄伐闆嗗洟",
-    contactPerson: "璧靛叚",
-    contactPhone: "13800138004",
-    contactEmail: "zhaoliu@example.com",
-    address: "娣卞湷甯傜鐢板尯绂忎腑涓夎矾1006鍙�",
-    status: "0",
-    createTime: "2024-01-04 10:00:00",
-    remark: "娣卞湷甯傞噸鐐瑰缓绛戜紒涓�",
-  },
-  {
-    contractorId: 5,
-    contractorName: "鏉窞寤哄伐闆嗗洟",
-    contactPerson: "瀛欎竷",
-    contactPhone: "13800138005",
-    contactEmail: "sunqi@example.com",
-    address: "鏉窞甯傛睙骞插尯閽辨睙鏂板煄瀵屾槬璺�188鍙�",
-    status: "0",
-    createTime: "2024-01-05 10:00:00",
-    remark: "娴欐睙鐪佺煡鍚嶅缓绛戜紒涓�",
-  },
-];
-
-/** 鏌ヨ鎵垮寘鍟嗗垪琛� */
-function getList() {
-  loading.value = true;
-  // 妯℃嫙API璇锋眰寤惰繜
-  setTimeout(() => {
-    let data = [...mockContractors];
-    // 妯℃嫙鎼滅储杩囨护
-    if (queryParams.value.contractorName) {
-      data = data.filter(item => item.contractorName.includes(queryParams.value.contractorName));
-    }
-    if (queryParams.value.contactPerson) {
-      data = data.filter(item => item.contactPerson.includes(queryParams.value.contactPerson));
-    }
-    if (queryParams.value.contactPhone) {
-      data = data.filter(item => item.contactPhone.includes(queryParams.value.contactPhone));
-    }
-    if (queryParams.value.status) {
-      data = data.filter(item => item.status === queryParams.value.status);
-    }
-    // 妯℃嫙鍒嗛〉
-    const start = (queryParams.value.pageNum - 1) * queryParams.value.pageSize;
-    const end = start + queryParams.value.pageSize;
-    contractorList.value = data.slice(start, end);
-    total.value = data.length;
-    loading.value = false;
-  }, 500);
-}
-
-/** 鎼滅储鎸夐挳鎿嶄綔 */
-function handleQuery() {
-  queryParams.value.pageNum = 1;
-  getList();
-}
-
-/** 閲嶇疆鎸夐挳鎿嶄綔 */
-function resetQuery() {
-  Object.assign(queryParams.value, {
-    contractorName: undefined,
-    contactPerson: undefined,
-    contactPhone: undefined,
-    status: undefined,
-  });
-  handleQuery();
-}
-
-/** 鍒犻櫎鎸夐挳鎿嶄綔 */
-function handleDelete(row) {
-  const contractorIds = row.contractorId || ids.value;
-  ElMessage.confirm(`鏄惁纭鍒犻櫎鎵垮寘鍟嗙紪鍙蜂负"${contractorIds}"鐨勬暟鎹」锛焋).then(() => {
-    // 妯℃嫙鍒犻櫎鎿嶄綔
-    ElMessage.success("鍒犻櫎鎴愬姛");
-    getList();
-  }).catch(() => {});
-}
-
-/** 鐘舵�佷慨鏀� */
-function handleStatusChange(row) {
-  let text = row.status === "0" ? "鍚敤" : "鍋滅敤";
-  ElMessage.confirm(`纭瑕�"${text}""${row.contractorName}"鎵垮寘鍟嗗悧?`).then(() => {
-    // 妯℃嫙鐘舵�佷慨鏀�
-    ElMessage.success(text + "鎴愬姛");
-    getList();
-  }).catch(() => {
-    row.status = row.status === "0" ? "1" : "0";
-  });
-}
-
-/** 閫夋嫨鏉℃暟  */
-function handleSelectionChange(selection) {
-  ids.value = selection.map((item) => item.contractorId);
-  single.value = selection.length != 1;
-  multiple.value = !selection.length;
-}
-
-/** 閲嶇疆鎿嶄綔琛ㄥ崟 */
-function reset() {
-  form.value = {
-    contractorId: undefined,
-    contractorName: undefined,
-    contactPerson: undefined,
-    contactPhone: undefined,
-    contactEmail: undefined,
-    address: undefined,
-    status: "0",
-    remark: undefined,
-  };
-}
-
-/** 鍙栨秷鎸夐挳 */
-function cancel() {
-  open.value = false;
-  reset();
-}
-
-/** 鏂板鎸夐挳鎿嶄綔 */
-function handleAdd() {
-  reset();
-  open.value = true;
-  title.value = "娣诲姞鎵垮寘鍟�";
-}
-
-/** 淇敼鎸夐挳鎿嶄綔 */
-function handleUpdate(row) {
-  reset();
-  const contractorId = row.contractorId || ids.value;
-  // 妯℃嫙鑾峰彇璇︽儏
-  const contractor = mockContractors.find(item => item.contractorId === contractorId);
-  if (contractor) {
-    form.value = { ...contractor };
-    open.value = true;
-    title.value = "淇敼鎵垮寘鍟�";
-  }
-}
-
-/** 鎻愪氦鎸夐挳 */
-function submitForm() {
-  // 妯℃嫙琛ㄥ崟楠岃瘉
-  const requiredFields = ['contractorName', 'contactPerson', 'contactPhone', 'address'];
-  const isInvalid = requiredFields.some(field => !form.value[field]);
-
-  if (isInvalid) {
-    ElMessage.error("璇峰~鍐欏繀濉瓧娈�");
-    return;
-  }
-
-  // 妯℃嫙鎻愪氦鎿嶄綔
-  ElMessage.success(title.value === "娣诲姞鎵垮寘鍟�" ? "鏂板鎴愬姛" : "淇敼鎴愬姛");
-  open.value = false;
-  getList();
-}
-
-// 妯℃嫙瀛楀吀鏁版嵁
-const sys_normal_disable = [
-  { value: "0", label: "姝e父" },
-  { value: "1", label: "绂佺敤" },
-];
-
-onMounted(() => {
-  getList();
-});
-</script>
diff --git a/src/views/dashboard/Dashboard.vue b/src/views/dashboard/Dashboard.vue
new file mode 100644
index 0000000..08a21ec
--- /dev/null
+++ b/src/views/dashboard/Dashboard.vue
@@ -0,0 +1,301 @@
+<template>
+  <div class="dashboard-container">
+    <!-- 缁熻鍗$墖 -->
+    <el-row :gutter="20">
+      <el-col :span="6">
+        <el-card class="statistics-card" shadow="hover">
+          <div class="card-content">
+            <div class="card-title">璁惧鍦ㄧ嚎鐜�</div>
+            <div class="card-value">{{ onlineRate }}%</div>
+            <div class="card-desc">褰撳墠鍦ㄧ嚎璁惧鏁帮細{{ onlineCount }} / {{ totalDevices }}</div>
+          </div>
+        </el-card>
+      </el-col>
+      <el-col :span="6">
+        <el-card class="statistics-card" shadow="hover">
+          <div class="card-content">
+            <div class="card-title">鏁呴殰棰勮鏁�</div>
+            <div class="card-value">{{ warningCount }}</div>
+            <div class="card-desc">楂橀闄╋細{{ highRiskCount }} | 涓闄╋細{{ mediumRiskCount }} | 浣庨闄╋細{{ lowRiskCount }}</div>
+          </div>
+        </el-card>
+      </el-col>
+      <el-col :span="6">
+        <el-card class="statistics-card" shadow="hover">
+          <div class="card-content">
+            <div class="card-title">寰呭鐞嗙淮淇崟</div>
+            <div class="card-value">{{ pendingOrders }}</div>
+            <div class="card-desc">澶勭悊涓細{{ processingOrders }} | 宸插畬鎴愶細{{ completedOrders }}</div>
+          </div>
+        </el-card>
+      </el-col>
+      <el-col :span="6">
+        <el-card class="statistics-card" shadow="hover">
+          <div class="card-content">
+            <div class="card-title">閲嶇偣璁惧杩愯鐘舵��</div>
+            <div class="card-value">{{ normalDevices }} 姝e父</div>
+            <div class="card-desc">寮傚父锛歿{ abnormalDevices }} | 鏁呴殰锛歿{ faultDevices }}</div>
+          </div>
+        </el-card>
+      </el-col>
+    </el-row>
+
+    <!-- 鍥捐〃鍖哄煙 -->
+    <el-row :gutter="20" style="margin-top: 20px;">
+      <!-- 璁惧鍋ュ悍搴﹁秼鍔垮浘 -->
+      <el-col :span="12">
+        <el-card shadow="hover">
+          <template #header>
+            <div class="card-header">
+              <span>璁惧鍋ュ悍搴﹁秼鍔垮浘</span>
+            </div>
+          </template>
+          <div ref="healthChartRef" class="chart-container"></div>
+        </el-card>
+      </el-col>
+      <!-- 杩�7鏃ユ晠闅滅被鍨嬬粺璁� -->
+      <el-col :span="12">
+        <el-card shadow="hover">
+          <template #header>
+            <div class="card-header">
+              <span>杩�7鏃ユ晠闅滅被鍨嬬粺璁�</span>
+            </div>
+          </template>
+          <div ref="faultChartRef" class="chart-container"></div>
+        </el-card>
+      </el-col>
+    </el-row>
+
+    <!-- 閲嶇偣璁惧杩愯鐘舵�佸崱鐗� -->
+    <el-card shadow="hover" style="margin-top: 20px;">
+      <template #header>
+        <div class="card-header">
+          <span>閲嶇偣璁惧杩愯鐘舵��</span>
+        </div>
+      </template>
+      <el-table :data="keyDevices" stripe style="width: 100%">
+        <el-table-column prop="name" label="璁惧鍚嶇О" width="180"></el-table-column>
+        <el-table-column prop="model" label="鍨嬪彿" width="120"></el-table-column>
+        <el-table-column prop="ip" label="IP鍦板潃" width="150"></el-table-column>
+        <el-table-column prop="status" label="鐘舵��" width="100">
+          <template #default="scope">
+            <el-tag :type="scope.row.status === 'online' ? 'success' : scope.row.status === 'warning' ? 'warning' : 'danger'">
+              {{ scope.row.status === 'online' ? '鍦ㄧ嚎' : scope.row.status === 'warning' ? '棰勮' : '鏁呴殰' }}
+            </el-tag>
+          </template>
+        </el-table-column>
+        <el-table-column prop="temperature" label="娓╁害(鈩�)" width="100"></el-table-column>
+        <el-table-column prop="pressure" label="鍘嬪姏(MPa)" width="100"></el-table-column>
+        <el-table-column prop="speed" label="杞��(rpm)" width="100"></el-table-column>
+        <el-table-column prop="health" label="鍋ュ悍搴�" width="120">
+          <template #default="scope">
+            <el-progress :percentage="scope.row.health" :stroke-width="10"></el-progress>
+          </template>
+        </el-table-column>
+      </el-table>
+    </el-card>
+  </div>
+</template>
+
+<script setup>
+import { ref, onMounted, onUnmounted } from 'vue'
+import * as echarts from 'echarts'
+
+// 缁熻鏁版嵁
+const onlineRate = ref(85)
+const onlineCount = ref(170)
+const totalDevices = ref(200)
+const warningCount = ref(23)
+const highRiskCount = ref(5)
+const mediumRiskCount = ref(12)
+const lowRiskCount = ref(6)
+const pendingOrders = ref(15)
+const processingOrders = ref(8)
+const completedOrders = ref(45)
+const normalDevices = ref(162)
+const abnormalDevices = ref(18)
+const faultDevices = ref(10)
+
+// 閲嶇偣璁惧鍒楄〃
+const keyDevices = ref([
+  { name: '绌哄帇鏈篈-001', model: 'KA-200', ip: '192.168.1.101', status: 'online', temperature: 42, pressure: 0.8, speed: 1450, health: 92 },
+  { name: '鍐峰嵈濉擝-002', model: 'CT-300', ip: '192.168.1.102', status: 'warning', temperature: 58, pressure: 0.6, speed: 980, health: 75 },
+  { name: '姘存车C-003', model: 'WP-150', ip: '192.168.1.103', status: 'online', temperature: 38, pressure: 1.2, speed: 1200, health: 88 },
+  { name: '鍙戠數鏈篋-004', model: 'GE-500', ip: '192.168.1.104', status: 'danger', temperature: 75, pressure: 0.5, speed: 1500, health: 60 },
+  { name: '鍙樺帇鍣‥-005', model: 'TR-1000', ip: '192.168.1.105', status: 'online', temperature: 45, pressure: 0, speed: 0, health: 95 }
+])
+
+// 鍥捐〃寮曠敤
+const healthChartRef = ref(null)
+const faultChartRef = ref(null)
+let healthChart = null
+let faultChart = null
+
+// 鍋ュ悍搴﹁秼鍔挎暟鎹�
+const healthTrendData = {
+  dates: ['12-10', '12-11', '12-12', '12-13', '12-14', '12-15', '12-16'],
+  values: [88, 90, 85, 87, 92, 91, 93]
+}
+
+// 鏁呴殰绫诲瀷缁熻鏁版嵁
+const faultTypeData = {
+  types: ['娓╁害寮傚父', '鍘嬪姏瓒呮爣', '杞�熷紓甯�', '鎸姩杩囧ぇ', '鍏朵粬'],
+  values: [15, 8, 12, 6, 3]
+}
+
+// 鍒濆鍖栧仴搴峰害瓒嬪娍鍥�
+const initHealthChart = () => {
+  if (healthChartRef.value) {
+    healthChart = echarts.init(healthChartRef.value)
+    const option = {
+      tooltip: {
+        trigger: 'axis',
+        axisPointer: {
+          type: 'cross',
+          label: {
+            backgroundColor: '#6a7985'
+          }
+        }
+      },
+      grid: {
+        left: '3%',
+        right: '4%',
+        bottom: '3%',
+        containLabel: true
+      },
+      xAxis: {
+        type: 'category',
+        boundaryGap: false,
+        data: healthTrendData.dates
+      },
+      yAxis: {
+        type: 'value',
+        min: 70,
+        max: 100,
+        name: '鍋ュ悍搴�(%)'
+      },
+      series: [
+        {
+          name: '鍋ュ悍搴�',
+          type: 'line',
+          stack: '鎬婚噺',
+          areaStyle: {},
+          emphasis: {
+            focus: 'series'
+          },
+          data: healthTrendData.values,
+          itemStyle: {
+            color: '#67c23a'
+          },
+          lineStyle: {
+            width: 3
+          }
+        }
+      ]
+    }
+    healthChart.setOption(option)
+  }
+}
+
+// 鍒濆鍖栨晠闅滅被鍨嬬粺璁¢ゼ鍥�
+const initFaultChart = () => {
+  if (faultChartRef.value) {
+    faultChart = echarts.init(faultChartRef.value)
+    const option = {
+      tooltip: {
+        trigger: 'item'
+      },
+      legend: {
+        orient: 'vertical',
+        left: 'left'
+      },
+      series: [
+        {
+          name: '鏁呴殰绫诲瀷',
+          type: 'pie',
+          radius: '50%',
+          data: faultTypeData.types.map((type, index) => ({
+            name: type,
+            value: faultTypeData.values[index]
+          })),
+          emphasis: {
+            itemStyle: {
+              shadowBlur: 10,
+              shadowOffsetX: 0,
+              shadowColor: 'rgba(0, 0, 0, 0.5)'
+            }
+          }
+        }
+      ]
+    }
+    faultChart.setOption(option)
+  }
+}
+
+// 鐩戝惉绐楀彛澶у皬鍙樺寲锛岃皟鏁村浘琛ㄥぇ灏�
+const handleResize = () => {
+  healthChart?.resize()
+  faultChart?.resize()
+}
+
+onMounted(() => {
+  initHealthChart()
+  initFaultChart()
+  window.addEventListener('resize', handleResize)
+})
+
+onUnmounted(() => {
+  window.removeEventListener('resize', handleResize)
+  healthChart?.dispose()
+  faultChart?.dispose()
+})
+</script>
+
+<style scoped>
+.dashboard-container {
+  padding: 20px;
+  background-color: #f5f7fa;
+  min-height: 100vh;
+}
+
+.statistics-card {
+  height: 180px;
+}
+
+.card-content {
+  display: flex;
+  flex-direction: column;
+  height: 100%;
+  justify-content: center;
+  align-items: center;
+}
+
+.card-title {
+  font-size: 16px;
+  color: #606266;
+  margin-bottom: 10px;
+}
+
+.card-value {
+  font-size: 32px;
+  font-weight: bold;
+  color: #303133;
+  margin-bottom: 8px;
+}
+
+.card-desc {
+  font-size: 14px;
+  color: #909399;
+}
+
+.card-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+}
+
+.chart-container {
+  width: 100%;
+  height: 350px;
+}
+</style>
\ No newline at end of file
diff --git a/src/views/device/DeviceManagement.vue b/src/views/device/DeviceManagement.vue
new file mode 100644
index 0000000..80ccd27
--- /dev/null
+++ b/src/views/device/DeviceManagement.vue
@@ -0,0 +1,513 @@
+<template>
+  <div class="device-management-container">
+    <el-card shadow="hover">
+      <template #header>
+        <div class="card-header">
+          <span>璁惧绠$悊</span>
+          <div class="header-buttons">
+            <el-button type="primary" @click="showAddDeviceDialog">
+              <el-icon-plus /> 娣诲姞璁惧
+            </el-button>
+            <el-button @click="exportDevices">
+              <el-icon-download /> 瀵煎嚭
+            </el-button>
+            <el-button @click="showImportDialog">
+              <el-icon-upload /> 瀵煎叆
+            </el-button>
+          </div>
+        </div>
+      </template>
+
+      <!-- 绛涢�夋潯浠� -->
+      <el-form :inline="true" :model="filterForm" class="device-filter-form">
+        <el-form-item label="璁惧鍚嶇О">
+          <el-input v-model="filterForm.name" placeholder="璇疯緭鍏ヨ澶囧悕绉�" clearable></el-input>
+        </el-form-item>
+        <el-form-item label="鍨嬪彿">
+          <el-input v-model="filterForm.model" placeholder="璇疯緭鍏ュ瀷鍙�" clearable></el-input>
+        </el-form-item>
+        <el-form-item label="鐘舵��">
+          <el-select v-model="filterForm.status" placeholder="璇烽�夋嫨鐘舵��" clearable>
+            <el-option label="鍦ㄧ嚎" value="online"></el-option>
+            <el-option label="绂荤嚎" value="offline"></el-option>
+            <el-option label="鏁呴殰" value="fault"></el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item>
+          <el-button type="primary" @click="handleFilter">鏌ヨ</el-button>
+          <el-button @click="resetFilter">閲嶇疆</el-button>
+        </el-form-item>
+      </el-form>
+
+      <!-- 璁惧鍒楄〃 -->
+      <el-table :data="filteredDevices" stripe style="width: 100%" @selection-change="handleSelectionChange">
+        <el-table-column type="selection" width="55"></el-table-column>
+        <el-table-column prop="id" label="璁惧ID" width="100"></el-table-column>
+        <el-table-column prop="name" label="璁惧鍚嶇О" width="180"></el-table-column>
+        <el-table-column prop="model" label="鍨嬪彿" width="120"></el-table-column>
+        <el-table-column prop="ip" label="IP鍦板潃" width="150"></el-table-column>
+        <el-table-column prop="status" label="鐘舵��" width="100">
+          <template #default="scope">
+            <el-tag :type="scope.row.status === 'online' ? 'success' : scope.row.status === 'offline' ? 'info' : 'danger'">
+              {{ scope.row.status === 'online' ? '鍦ㄧ嚎' : scope.row.status === 'offline' ? '绂荤嚎' : '鏁呴殰' }}
+            </el-tag>
+          </template>
+        </el-table-column>
+        <el-table-column prop="location" label="瀹夎浣嶇疆" width="180"></el-table-column>
+        <el-table-column prop="installDate" label="瀹夎鏃ユ湡" width="150"></el-table-column>
+        <el-table-column prop="manufacturer" label="鍒堕�犲晢" width="150"></el-table-column>
+        <el-table-column label="鎿嶄綔" width="220" fixed="right">
+          <template #default="scope">
+            <el-button type="text" size="small" @click="showDeviceDetail(scope.row)">
+              璇︽儏
+            </el-button>
+            <el-button type="text" size="small" @click="showEditDeviceDialog(scope.row)">
+              缂栬緫
+            </el-button>
+            <el-button type="text" size="small" @click="handleDelete(scope.row)">
+              鍒犻櫎
+            </el-button>
+          </template>
+        </el-table-column>
+      </el-table>
+
+      <!-- 鍒嗛〉 -->
+      <div class="pagination-container">
+        <el-pagination
+          background
+          layout="total, sizes, prev, pager, next, jumper"
+          :total="filteredDevices.length"
+          :current-page="currentPage"
+          :page-sizes="[10, 20, 50, 100]"
+          :page-size="pageSize"
+          @size-change="handleSizeChange"
+          @current-change="handleCurrentChange"
+        ></el-pagination>
+      </div>
+    </el-card>
+
+    <!-- 娣诲姞璁惧瀵硅瘽妗� -->
+    <el-dialog v-model="addDeviceDialogVisible" title="娣诲姞璁惧" width="600px">
+      <el-form :model="deviceForm" :rules="deviceRules" ref="deviceFormRef" label-width="100px">
+        <el-form-item label="璁惧鍚嶇О" prop="name">
+          <el-input v-model="deviceForm.name" placeholder="璇疯緭鍏ヨ澶囧悕绉�"></el-input>
+        </el-form-item>
+        <el-form-item label="鍨嬪彿" prop="model">
+          <el-input v-model="deviceForm.model" placeholder="璇疯緭鍏ュ瀷鍙�"></el-input>
+        </el-form-item>
+        <el-form-item label="IP鍦板潃" prop="ip">
+          <el-input v-model="deviceForm.ip" placeholder="璇疯緭鍏P鍦板潃"></el-input>
+        </el-form-item>
+        <el-form-item label="瀹夎浣嶇疆" prop="location">
+          <el-input v-model="deviceForm.location" placeholder="璇疯緭鍏ュ畨瑁呬綅缃�"></el-input>
+        </el-form-item>
+        <el-form-item label="鍒堕�犲晢" prop="manufacturer">
+          <el-input v-model="deviceForm.manufacturer" placeholder="璇疯緭鍏ュ埗閫犲晢"></el-input>
+        </el-form-item>
+        <el-form-item label="瀹夎鏃ユ湡" prop="installDate">
+          <el-date-picker v-model="deviceForm.installDate" type="date" placeholder="閫夋嫨瀹夎鏃ユ湡" style="width: 100%"></el-date-picker>
+        </el-form-item>
+        <el-form-item label="鐘舵��" prop="status">
+          <el-select v-model="deviceForm.status" placeholder="璇烽�夋嫨鐘舵��">
+            <el-option label="鍦ㄧ嚎" value="online"></el-option>
+            <el-option label="绂荤嚎" value="offline"></el-option>
+            <el-option label="鏁呴殰" value="fault"></el-option>
+          </el-select>
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <span class="dialog-footer">
+          <el-button @click="addDeviceDialogVisible = false">鍙栨秷</el-button>
+          <el-button type="primary" @click="handleAddDevice">纭畾</el-button>
+        </span>
+      </template>
+    </el-dialog>
+
+    <!-- 缂栬緫璁惧瀵硅瘽妗� -->
+    <el-dialog v-model="editDeviceDialogVisible" title="缂栬緫璁惧" width="600px">
+      <el-form :model="deviceForm" :rules="deviceRules" ref="deviceFormRef" label-width="100px">
+        <el-form-item label="璁惧鍚嶇О" prop="name">
+          <el-input v-model="deviceForm.name" placeholder="璇疯緭鍏ヨ澶囧悕绉�"></el-input>
+        </el-form-item>
+        <el-form-item label="鍨嬪彿" prop="model">
+          <el-input v-model="deviceForm.model" placeholder="璇疯緭鍏ュ瀷鍙�"></el-input>
+        </el-form-item>
+        <el-form-item label="IP鍦板潃" prop="ip">
+          <el-input v-model="deviceForm.ip" placeholder="璇疯緭鍏P鍦板潃"></el-input>
+        </el-form-item>
+        <el-form-item label="瀹夎浣嶇疆" prop="location">
+          <el-input v-model="deviceForm.location" placeholder="璇疯緭鍏ュ畨瑁呬綅缃�"></el-input>
+        </el-form-item>
+        <el-form-item label="鍒堕�犲晢" prop="manufacturer">
+          <el-input v-model="deviceForm.manufacturer" placeholder="璇疯緭鍏ュ埗閫犲晢"></el-input>
+        </el-form-item>
+        <el-form-item label="瀹夎鏃ユ湡" prop="installDate">
+          <el-date-picker v-model="deviceForm.installDate" type="date" placeholder="閫夋嫨瀹夎鏃ユ湡" style="width: 100%"></el-date-picker>
+        </el-form-item>
+        <el-form-item label="鐘舵��" prop="status">
+          <el-select v-model="deviceForm.status" placeholder="璇烽�夋嫨鐘舵��">
+            <el-option label="鍦ㄧ嚎" value="online"></el-option>
+            <el-option label="绂荤嚎" value="offline"></el-option>
+            <el-option label="鏁呴殰" value="fault"></el-option>
+          </el-select>
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <span class="dialog-footer">
+          <el-button @click="editDeviceDialogVisible = false">鍙栨秷</el-button>
+          <el-button type="primary" @click="handleEditDevice">纭畾</el-button>
+        </span>
+      </template>
+    </el-dialog>
+
+    <!-- 璁惧璇︽儏瀵硅瘽妗� -->
+    <el-dialog v-model="deviceDetailDialogVisible" title="璁惧璇︽儏" width="600px">
+      <el-descriptions :column="1" border>
+        <el-descriptions-item label="璁惧鍚嶇О">{{ selectedDevice.name }}</el-descriptions-item>
+        <el-descriptions-item label="璁惧ID">{{ selectedDevice.id }}</el-descriptions-item>
+        <el-descriptions-item label="鍨嬪彿">{{ selectedDevice.model }}</el-descriptions-item>
+        <el-descriptions-item label="IP鍦板潃">{{ selectedDevice.ip }}</el-descriptions-item>
+        <el-descriptions-item label="鐘舵��">
+          <el-tag :type="selectedDevice.status === 'online' ? 'success' : selectedDevice.status === 'offline' ? 'info' : 'danger'">
+            {{ selectedDevice.status === 'online' ? '鍦ㄧ嚎' : selectedDevice.status === 'offline' ? '绂荤嚎' : '鏁呴殰' }}
+          </el-tag>
+        </el-descriptions-item>
+        <el-descriptions-item label="瀹夎浣嶇疆">{{ selectedDevice.location }}</el-descriptions-item>
+        <el-descriptions-item label="鍒堕�犲晢">{{ selectedDevice.manufacturer }}</el-descriptions-item>
+        <el-descriptions-item label="瀹夎鏃ユ湡">{{ selectedDevice.installDate }}</el-descriptions-item>
+        <el-descriptions-item label="鍒涘缓鏃堕棿">{{ selectedDevice.createTime }}</el-descriptions-item>
+      </el-descriptions>
+      <template #footer>
+        <span class="dialog-footer">
+          <el-button @click="deviceDetailDialogVisible = false">鍏抽棴</el-button>
+        </span>
+      </template>
+    </el-dialog>
+
+    <!-- 瀵煎叆瀵硅瘽妗� -->
+    <el-dialog v-model="importDialogVisible" title="瀵煎叆璁惧" width="400px">
+      <el-upload
+        class="upload-demo"
+        action="#"
+        :on-change="handleFileChange"
+        :auto-upload="false"
+        accept=".xlsx,.xls"
+      >
+        <el-button type="primary">閫夋嫨鏂囦欢</el-button>
+        <template #tip>
+          <div class="el-upload__tip">
+            鍙兘涓婁紶 xlsx/xls 鏂囦欢锛屼笖涓嶈秴杩� 2MB
+          </div>
+        </template>
+      </el-upload>
+      <template #footer>
+        <span class="dialog-footer">
+          <el-button @click="importDialogVisible = false">鍙栨秷</el-button>
+          <el-button type="primary" @click="handleImport">纭畾</el-button>
+        </span>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
+<script setup>
+import { ref, computed } from 'vue'
+
+// 璁惧鍒楄〃鏁版嵁
+const devices = ref([
+  {
+    id: 'D001',
+    name: '绌哄帇鏈篈-001',
+    model: 'KA-200',
+    ip: '192.168.1.101',
+    status: 'online',
+    location: '杞﹂棿A-1鍖�',
+    manufacturer: '搴锋櫘鏂�',
+    installDate: '2023-05-10',
+    createTime: '2023-05-10 10:30:00'
+  },
+  {
+    id: 'D002',
+    name: '鍐峰嵈濉擝-002',
+    model: 'CT-300',
+    ip: '192.168.1.102',
+    status: 'warning',
+    location: '杞﹂棿B-2鍖�',
+    manufacturer: '鑹満',
+    installDate: '2023-06-15',
+    createTime: '2023-06-15 14:20:00'
+  },
+  {
+    id: 'D003',
+    name: '姘存车C-003',
+    model: 'WP-150',
+    ip: '192.168.1.103',
+    status: 'online',
+    location: '杞﹂棿C-3鍖�',
+    manufacturer: '鏍煎叞瀵�',
+    installDate: '2023-07-20',
+    createTime: '2023-07-20 09:15:00'
+  },
+  {
+    id: 'D004',
+    name: '鍙戠數鏈篋-004',
+    model: 'GE-500',
+    ip: '192.168.1.104',
+    status: 'fault',
+    location: '鏈烘埧',
+    manufacturer: '鍗$壒褰煎嫆',
+    installDate: '2023-08-25',
+    createTime: '2023-08-25 16:45:00'
+  },
+  {
+    id: 'D005',
+    name: '鍙樺帇鍣‥-005',
+    model: 'TR-1000',
+    ip: '192.168.1.105',
+    status: 'online',
+    location: '閰嶇數鎴�',
+    manufacturer: 'ABB',
+    installDate: '2023-09-30',
+    createTime: '2023-09-30 11:20:00'
+  }
+])
+
+// 绛涢�夎〃鍗�
+const filterForm = ref({
+  name: '',
+  model: '',
+  status: ''
+})
+
+// 鍒嗛〉鏁版嵁
+const currentPage = ref(1)
+const pageSize = ref(10)
+
+// 瀵硅瘽妗嗙姸鎬�
+const addDeviceDialogVisible = ref(false)
+const editDeviceDialogVisible = ref(false)
+const deviceDetailDialogVisible = ref(false)
+const importDialogVisible = ref(false)
+
+// 璁惧琛ㄥ崟鏁版嵁
+const deviceForm = ref({
+  id: '',
+  name: '',
+  model: '',
+  ip: '',
+  status: 'online',
+  location: '',
+  manufacturer: '',
+  installDate: ''
+})
+
+// 琛ㄥ崟楠岃瘉瑙勫垯
+const deviceRules = ref({
+  name: [{ required: true, message: '璇疯緭鍏ヨ澶囧悕绉�', trigger: 'blur' }],
+  model: [{ required: true, message: '璇疯緭鍏ュ瀷鍙�', trigger: 'blur' }],
+  ip: [{ required: true, message: '璇疯緭鍏P鍦板潃', trigger: 'blur' }],
+  location: [{ required: true, message: '璇疯緭鍏ュ畨瑁呬綅缃�', trigger: 'blur' }],
+  manufacturer: [{ required: true, message: '璇疯緭鍏ュ埗閫犲晢', trigger: 'blur' }],
+  installDate: [{ required: true, message: '璇烽�夋嫨瀹夎鏃ユ湡', trigger: 'change' }],
+  status: [{ required: true, message: '璇烽�夋嫨鐘舵��', trigger: 'change' }]
+})
+
+// 琛ㄥ崟寮曠敤
+const deviceFormRef = ref(null)
+
+// 閫変腑鐨勮澶�
+const selectedDevice = ref({})
+
+// 閫変腑鐨勮澶囧垪琛紙鐢ㄤ簬鎵归噺鎿嶄綔锛�
+const selectedDevices = ref([])
+
+// 瀵煎叆鐨勬枃浠�
+const importFile = ref(null)
+
+// 杩囨护鍚庣殑璁惧鍒楄〃
+const filteredDevices = computed(() => {
+  let result = [...devices.value]
+
+  // 鎸夊悕绉扮瓫閫�
+  if (filterForm.value.name) {
+    result = result.filter(device => device.name.includes(filterForm.value.name))
+  }
+
+  // 鎸夊瀷鍙风瓫閫�
+  if (filterForm.value.model) {
+    result = result.filter(device => device.model.includes(filterForm.value.model))
+  }
+
+  // 鎸夌姸鎬佺瓫閫�
+  if (filterForm.value.status) {
+    result = result.filter(device => device.status === filterForm.value.status)
+  }
+
+  return result
+})
+
+// 鏄剧ず娣诲姞璁惧瀵硅瘽妗�
+const showAddDeviceDialog = () => {
+  // 閲嶇疆琛ㄥ崟
+  deviceForm.value = {
+    id: '',
+    name: '',
+    model: '',
+    ip: '',
+    status: 'online',
+    location: '',
+    manufacturer: '',
+    installDate: ''
+  }
+  addDeviceDialogVisible.value = true
+}
+
+// 鏄剧ず缂栬緫璁惧瀵硅瘽妗�
+const showEditDeviceDialog = (device) => {
+  deviceForm.value = { ...device }
+  editDeviceDialogVisible.value = true
+}
+
+// 鏄剧ず璁惧璇︽儏
+const showDeviceDetail = (device) => {
+  selectedDevice.value = { ...device }
+  deviceDetailDialogVisible.value = true
+}
+
+// 鏄剧ず瀵煎叆瀵硅瘽妗�
+const showImportDialog = () => {
+  importDialogVisible.value = true
+}
+
+// 澶勭悊娣诲姞璁惧
+const handleAddDevice = () => {
+  // 妯℃嫙娣诲姞璁惧
+  const newDevice = {
+    ...deviceForm.value,
+    id: `D${String(devices.value.length + 1).padStart(3, '0')}`,
+    createTime: new Date().toLocaleString()
+  }
+  devices.value.push(newDevice)
+  addDeviceDialogVisible.value = false
+  ElMessage.success('璁惧娣诲姞鎴愬姛')
+}
+
+// 澶勭悊缂栬緫璁惧
+const handleEditDevice = () => {
+  // 妯℃嫙缂栬緫璁惧
+  const index = devices.value.findIndex(device => device.id === deviceForm.value.id)
+  if (index !== -1) {
+    devices.value[index] = { ...deviceForm.value }
+    editDeviceDialogVisible.value = false
+    ElMessage.success('璁惧缂栬緫鎴愬姛')
+  }
+}
+
+// 澶勭悊鍒犻櫎璁惧
+const handleDelete = (device) => {
+  ElMessageBox.confirm('纭畾瑕佸垹闄よ璁惧鍚楋紵', '鎻愮ず', {
+    confirmButtonText: '纭畾',
+    cancelButtonText: '鍙栨秷',
+    type: 'warning'
+  }).then(() => {
+    // 妯℃嫙鍒犻櫎璁惧
+    const index = devices.value.findIndex(item => item.id === device.id)
+    if (index !== -1) {
+      devices.value.splice(index, 1)
+      ElMessage.success('璁惧鍒犻櫎鎴愬姛')
+    }
+  }).catch(() => {
+    // 鍙栨秷鍒犻櫎
+  })
+}
+
+// 澶勭悊绛涢��
+const handleFilter = () => {
+  // 绛涢�夐�昏緫宸茬粡鍦╟omputed涓疄鐜�
+}
+
+// 閲嶇疆绛涢�夋潯浠�
+const resetFilter = () => {
+  filterForm.value = {
+    name: '',
+    model: '',
+    status: ''
+  }
+}
+
+// 澶勭悊鍒嗛〉澶у皬鍙樺寲
+const handleSizeChange = (size) => {
+  pageSize.value = size
+  currentPage.value = 1
+}
+
+// 澶勭悊褰撳墠椤靛彉鍖�
+const handleCurrentChange = (current) => {
+  currentPage.value = current
+}
+
+// 澶勭悊鏂囦欢鍙樺寲锛堝鍏ワ級
+const handleFileChange = (file) => {
+  importFile.value = file
+}
+
+// 澶勭悊瀵煎叆
+const handleImport = () => {
+  // 妯℃嫙瀵煎叆
+  if (importFile.value) {
+    importDialogVisible.value = false
+    ElMessage.success('璁惧瀵煎叆鎴愬姛')
+    importFile.value = null
+  } else {
+    ElMessage.warning('璇烽�夋嫨瑕佸鍏ョ殑鏂囦欢')
+  }
+}
+
+// 瀵煎嚭璁惧
+const exportDevices = () => {
+  // 妯℃嫙瀵煎嚭
+  ElMessage.success('璁惧瀵煎嚭鎴愬姛')
+}
+
+// 澶勭悊閫夋嫨鍙樺寲锛堢敤浜庢壒閲忔搷浣滐級
+const handleSelectionChange = (selection) => {
+  selectedDevices.value = selection
+}
+</script>
+
+<style scoped>
+.device-management-container {
+  padding: 20px;
+  background-color: #f5f7fa;
+  min-height: 100vh;
+}
+
+.card-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+}
+
+.header-buttons {
+  display: flex;
+  gap: 10px;
+}
+
+.device-filter-form {
+  margin-bottom: 20px;
+  padding: 10px 0;
+  border-bottom: 1px solid #ebeef5;
+}
+
+.pagination-container {
+  display: flex;
+  justify-content: flex-end;
+  margin-top: 20px;
+}
+
+:deep(.el-icon-plus),
+:deep(.el-icon-download),
+:deep(.el-icon-upload) {
+  margin-right: 5px;
+}
+</style>
diff --git a/src/views/diagnosis/FaultDiagnosis.vue b/src/views/diagnosis/FaultDiagnosis.vue
new file mode 100644
index 0000000..a1cb864
--- /dev/null
+++ b/src/views/diagnosis/FaultDiagnosis.vue
@@ -0,0 +1,411 @@
+<template>
+  <div class="fault-diagnosis-container">
+    <el-row :gutter="20">
+      <!-- 宸︿晶锛氭晠闅滈璀﹀垪琛� -->
+      <el-col :span="12">
+        <el-card shadow="hover">
+          <template #header>
+            <div class="card-header">
+              <span>鏁呴殰棰勮鍒楄〃</span>
+            </div>
+          </template>
+          <el-table :data="warningList" stripe style="width: 100%" @row-click="handleWarningClick">
+            <el-table-column prop="deviceName" label="璁惧鍚嶇О" width="180"></el-table-column>
+            <el-table-column prop="warningType" label="棰勮绫诲瀷" width="120"></el-table-column>
+            <el-table-column prop="riskLevel" label="椋庨櫓绛夌骇" width="100">
+              <template #default="scope">
+                <el-tag :type="scope.row.riskLevel === 'high' ? 'danger' : scope.row.riskLevel === 'medium' ? 'warning' : 'info'">
+                  {{ scope.row.riskLevel === 'high' ? '楂�' : scope.row.riskLevel === 'medium' ? '涓�' : '浣�' }}
+                </el-tag>
+              </template>
+            </el-table-column>
+            <el-table-column prop="occurTime" label="鍙戠敓鏃堕棿" width="180"></el-table-column>
+            <el-table-column prop="status" label="澶勭悊鐘舵��" width="100">
+              <template #default="scope">
+                <el-tag :type="scope.row.status === 'pending' ? 'warning' : 'success'">
+                  {{ scope.row.status === 'pending' ? '寰呭鐞�' : '宸插鐞�' }}
+                </el-tag>
+              </template>
+            </el-table-column>
+          </el-table>
+        </el-card>
+
+        <!-- 鏁呴殰鍘嗗彶璁板綍鏌ヨ -->
+        <el-card shadow="hover" style="margin-top: 20px;">
+          <template #header>
+            <div class="card-header">
+              <span>鏁呴殰鍘嗗彶璁板綍</span>
+            </div>
+          </template>
+          <el-form :inline="true" :model="historyFilterForm" class="history-filter-form">
+            <el-form-item label="璁惧">
+              <el-select v-model="historyFilterForm.deviceId" placeholder="璇烽�夋嫨璁惧" clearable>
+                <el-option
+                  v-for="device in devices"
+                  :key="device.id"
+                  :label="device.name"
+                  :value="device.id"
+                ></el-option>
+              </el-select>
+            </el-form-item>
+            <el-form-item label="鏃堕棿鑼冨洿">
+              <el-date-picker
+                v-model="historyTimeRange"
+                type="daterange"
+                range-separator="鑷�"
+                start-placeholder="寮�濮嬫棩鏈�"
+                end-placeholder="缁撴潫鏃ユ湡"
+              ></el-date-picker>
+            </el-form-item>
+            <el-form-item>
+              <el-button type="primary" @click="handleHistorySearch">鏌ヨ</el-button>
+            </el-form-item>
+          </el-form>
+          <el-table :data="historyList" stripe style="width: 100%" size="small">
+            <el-table-column prop="deviceName" label="璁惧鍚嶇О" width="150"></el-table-column>
+            <el-table-column prop="faultType" label="鏁呴殰绫诲瀷" width="120"></el-table-column>
+            <el-table-column prop="occurTime" label="鍙戠敓鏃堕棿" width="150"></el-table-column>
+            <el-table-column prop="dealTime" label="澶勭悊鏃堕棿" width="150"></el-table-column>
+            <el-table-column prop="status" label="鐘舵��" width="100">
+              <template #default="scope">
+                <el-tag type="success">{{ scope.row.status }}</el-tag>
+              </template>
+            </el-table-column>
+          </el-table>
+          <div class="pagination-container">
+            <el-pagination
+              background
+              layout="total, prev, pager, next"
+              :total="historyList.length"
+              :page-size="5"
+              size="small"
+            ></el-pagination>
+          </div>
+        </el-card>
+      </el-col>
+
+      <!-- 鍙充晶锛氭晠闅滆瘖鏂粨鏋� -->
+      <el-col :span="12">
+        <!-- 鏁呴殰璇婃柇缁撴灉 -->
+        <el-card shadow="hover">
+          <template #header>
+            <div class="card-header">
+              <span>鏁呴殰璇婃柇缁撴灉</span>
+              <el-button type="primary" size="small" @click="handleDiagnosis">閲嶆柊璇婃柇</el-button>
+            </div>
+          </template>
+          <div v-if="currentWarning" class="diagnosis-result">
+            <h3>{{ currentWarning.deviceName }} - {{ currentWarning.warningType }}</h3>
+            <el-descriptions :column="1" border>
+              <el-descriptions-item label="椋庨櫓绛夌骇">
+                <el-tag :type="currentWarning.riskLevel === 'high' ? 'danger' : currentWarning.riskLevel === 'medium' ? 'warning' : 'info'">
+                  {{ currentWarning.riskLevel === 'high' ? '楂�' : currentWarning.riskLevel === 'medium' ? '涓�' : '浣�' }}
+                </el-tag>
+              </el-descriptions-item>
+              <el-descriptions-item label="鍙戠敓鏃堕棿">{{ currentWarning.occurTime }}</el-descriptions-item>
+              <el-descriptions-item label="鍘熷洜鎺ㄦ祴">{{ diagnosisResult.reason }}</el-descriptions-item>
+              <el-descriptions-item label="褰卞搷鑼冨洿">{{ diagnosisResult.impact }}</el-descriptions-item>
+              <el-descriptions-item label="澶勭悊寤鸿">{{ diagnosisResult.suggestion }}</el-descriptions-item>
+            </el-descriptions>
+          </div>
+          <div v-else class="no-selection">
+            <el-empty description="璇烽�夋嫨涓�涓璀﹂」鏌ョ湅璇婃柇缁撴灉"></el-empty>
+          </div>
+        </el-card>
+
+        <!-- 棰勬祴鎬ц瘖鏂粨鏋� -->
+        <el-card shadow="hover" style="margin-top: 20px;">
+          <template #header>
+            <div class="card-header">
+              <span>棰勬祴鎬ц瘖鏂粨鏋滐紙鏈潵7鏃ユ晠闅滈闄╋級</span>
+            </div>
+          </template>
+          <div class="prediction-result">
+            <el-timeline>
+              <el-timeline-item
+                v-for="item in predictionList"
+                :key="item.date"
+                :timestamp="item.date"
+                :type="item.riskLevel === 'high' ? 'danger' : item.riskLevel === 'medium' ? 'warning' : 'success'"
+              >
+                <div class="timeline-content">
+                  <h4>{{ item.deviceName }}</h4>
+                  <p class="risk-level">
+                    椋庨櫓绛夌骇锛�
+                    <el-tag :type="item.riskLevel === 'high' ? 'danger' : item.riskLevel === 'medium' ? 'warning' : 'success'">
+                      {{ item.riskLevel === 'high' ? '楂�' : item.riskLevel === 'medium' ? '涓�' : '浣�' }}
+                    </el-tag>
+                  </p>
+                  <p class="fault-type">鍙兘鏁呴殰绫诲瀷锛歿{ item.possibleFault }}</p>
+                  <p class="probability">鍙戠敓姒傜巼锛歿{ item.probability }}%</p>
+                </div>
+              </el-timeline-item>
+            </el-timeline>
+          </div>
+        </el-card>
+      </el-col>
+    </el-row>
+  </div>
+</template>
+
+<script setup>
+import { ref, reactive } from 'vue'
+
+// 璁惧鍒楄〃
+const devices = ref([
+  { id: 'D001', name: '绌哄帇鏈篈-001' },
+  { id: 'D002', name: '鍐峰嵈濉擝-002' },
+  { id: 'D003', name: '姘存车C-003' },
+  { id: 'D004', name: '鍙戠數鏈篋-004' },
+  { id: 'D005', name: '鍙樺帇鍣‥-005' }
+])
+
+// 鏁呴殰棰勮鍒楄〃
+const warningList = ref([
+  {
+    id: 1,
+    deviceName: '绌哄帇鏈篈-001',
+    warningType: '鍘嬪姏寮傚父',
+    riskLevel: 'high',
+    occurTime: '2024-12-16 14:32:15',
+    status: 'pending'
+  },
+  {
+    id: 2,
+    deviceName: '鍐峰嵈濉擝-002',
+    warningType: '娓╁害杩囬珮',
+    riskLevel: 'medium',
+    occurTime: '2024-12-16 14:30:45',
+    status: 'pending'
+  },
+  {
+    id: 3,
+    deviceName: '姘存车C-003',
+    warningType: '鎸姩杩囧ぇ',
+    riskLevel: 'medium',
+    occurTime: '2024-12-16 14:28:30',
+    status: 'pending'
+  },
+  {
+    id: 4,
+    deviceName: '鍙戠數鏈篋-004',
+    warningType: '鐢垫祦寮傚父',
+    riskLevel: 'high',
+    occurTime: '2024-12-16 14:25:10',
+    status: 'pending'
+  },
+  {
+    id: 5,
+    deviceName: '鍙樺帇鍣‥-005',
+    warningType: '鐢靛帇娉㈠姩',
+    riskLevel: 'low',
+    occurTime: '2024-12-16 14:20:05',
+    status: 'pending'
+  }
+])
+
+// 褰撳墠閫変腑鐨勯璀﹂」
+const currentWarning = ref(warningList.value[0])
+
+// 鏁呴殰璇婃柇缁撴灉
+const diagnosisResult = reactive({
+  reason: '鏍规嵁璁惧杩愯鏁版嵁鎺ㄦ祴锛屾晠闅滃師鍥犲彲鑳芥槸璁惧鍐呴儴閮ㄤ欢纾ㄦ崯瀵艰嚧鐨勫帇鍔涘紓甯革紝闇�瑕佽繘涓�姝ユ鏌ヨ澶囩殑娲诲鐜拰姘旂几濂椼��',
+  impact: '濡傛灉涓嶅強鏃跺鐞嗭紝鍙兘瀵艰嚧璁惧鍋滄満锛屽奖鍝嶇敓浜х嚎鐨勬甯歌繍琛岋紝棰勮鍋滄満鏃堕棿涓�4-6灏忔椂銆�',
+  suggestion: '1. 绔嬪嵆瀹夋帓缁翠慨浜哄憳杩涜璁惧妫�鏌ワ紱2. 妫�鏌ヨ澶囩殑娲诲鐜拰姘旂几濂楋紱3. 鏇存崲纾ㄦ崯涓ラ噸鐨勯儴浠讹紱4. 妫�鏌ヨ澶囩殑娑︽粦绯荤粺锛岀‘淇濇鼎婊戞甯搞��'
+})
+
+// 棰勬祴鎬ц瘖鏂粨鏋�
+const predictionList = ref([
+  {
+    date: '2024-12-17',
+    deviceName: '绌哄帇鏈篈-001',
+    riskLevel: 'medium',
+    possibleFault: '鍘嬪姏寮傚父',
+    probability: 65
+  },
+  {
+    date: '2024-12-18',
+    deviceName: '鍐峰嵈濉擝-002',
+    riskLevel: 'high',
+    possibleFault: '娓╁害杩囬珮',
+    probability: 85
+  },
+  {
+    date: '2024-12-19',
+    deviceName: '姘存车C-003',
+    riskLevel: 'medium',
+    possibleFault: '鎸姩杩囧ぇ',
+    probability: 70
+  },
+  {
+    date: '2024-12-20',
+    deviceName: '鍙戠數鏈篋-004',
+    riskLevel: 'high',
+    possibleFault: '鐢垫祦寮傚父',
+    probability: 90
+  },
+  {
+    date: '2024-12-21',
+    deviceName: '鍙樺帇鍣‥-005',
+    riskLevel: 'low',
+    possibleFault: '鐢靛帇娉㈠姩',
+    probability: 45
+  },
+  {
+    date: '2024-12-22',
+    deviceName: '绌哄帇鏈篈-001',
+    riskLevel: 'high',
+    possibleFault: '鍘嬪姏寮傚父',
+    probability: 80
+  },
+  {
+    date: '2024-12-23',
+    deviceName: '鍐峰嵈濉擝-002',
+    riskLevel: 'medium',
+    possibleFault: '娓╁害杩囬珮',
+    probability: 60
+  }
+])
+
+// 鏁呴殰鍘嗗彶璁板綍鏌ヨ琛ㄥ崟
+const historyFilterForm = ref({
+  deviceId: ''
+})
+
+// 鍘嗗彶璁板綍鏃堕棿鑼冨洿
+const historyTimeRange = ref([])
+
+// 鏁呴殰鍘嗗彶璁板綍
+const historyList = ref([
+  {
+    id: 1,
+    deviceName: '绌哄帇鏈篈-001',
+    faultType: '鍘嬪姏寮傚父',
+    occurTime: '2024-12-15 08:30:00',
+    dealTime: '2024-12-15 10:45:00',
+    status: '宸插鐞�'
+  },
+  {
+    id: 2,
+    deviceName: '鍐峰嵈濉擝-002',
+    faultType: '娓╁害杩囬珮',
+    occurTime: '2024-12-14 14:20:00',
+    dealTime: '2024-12-14 16:15:00',
+    status: '宸插鐞�'
+  },
+  {
+    id: 3,
+    deviceName: '姘存车C-003',
+    faultType: '鎸姩杩囧ぇ',
+    occurTime: '2024-12-13 09:15:00',
+    dealTime: '2024-12-13 11:30:00',
+    status: '宸插鐞�'
+  },
+  {
+    id: 4,
+    deviceName: '鍙戠數鏈篋-004',
+    faultType: '鐢垫祦寮傚父',
+    occurTime: '2024-12-12 16:45:00',
+    dealTime: '2024-12-12 18:30:00',
+    status: '宸插鐞�'
+  },
+  {
+    id: 5,
+    deviceName: '鍙樺帇鍣‥-005',
+    faultType: '鐢靛帇娉㈠姩',
+    occurTime: '2024-12-11 11:20:00',
+    dealTime: '2024-12-11 13:15:00',
+    status: '宸插鐞�'
+  }
+])
+
+// 澶勭悊棰勮椤圭偣鍑�
+const handleWarningClick = (row) => {
+  currentWarning.value = row
+}
+
+// 閲嶆柊璇婃柇
+const handleDiagnosis = () => {
+  // 妯℃嫙閲嶆柊璇婃柇
+  ElMessage.success('閲嶆柊璇婃柇瀹屾垚')
+}
+
+// 澶勭悊鍘嗗彶璁板綍鏌ヨ
+const handleHistorySearch = () => {
+  // 妯℃嫙鏌ヨ鍘嗗彶璁板綍
+  ElMessage.success('鍘嗗彶璁板綍鏌ヨ鎴愬姛')
+}
+</script>
+
+<style scoped>
+.fault-diagnosis-container {
+  padding: 20px;
+  background-color: #f5f7fa;
+  min-height: 100vh;
+}
+
+.card-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+}
+
+.diagnosis-result h3 {
+  margin-bottom: 20px;
+  color: #303133;
+}
+
+.no-selection {
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  height: 200px;
+}
+
+.prediction-result {
+  padding: 10px 0;
+}
+
+.timeline-content {
+  padding: 10px;
+  background-color: #fafafa;
+  border-radius: 4px;
+}
+
+.timeline-content h4 {
+  margin-bottom: 10px;
+  color: #303133;
+}
+
+.timeline-content p {
+  margin: 5px 0;
+  font-size: 14px;
+  color: #606266;
+}
+
+.risk-level {
+  display: flex;
+  align-items: center;
+  gap: 5px;
+}
+
+.fault-type {
+  color: #606266;
+}
+
+.probability {
+  color: #606266;
+}
+
+.history-filter-form {
+  margin-bottom: 20px;
+  padding: 10px 0;
+  border-bottom: 1px solid #ebeef5;
+}
+
+.pagination-container {
+  display: flex;
+  justify-content: flex-end;
+  margin-top: 20px;
+}
+</style>
\ No newline at end of file
diff --git a/src/views/index.vue b/src/views/index.vue
index dfd56e3..e9453f2 100644
--- a/src/views/index.vue
+++ b/src/views/index.vue
@@ -1,674 +1,392 @@
 <template>
-  <div class="dashboard">
-    <!-- 椤堕儴妯悜涓ゆ爮 -->
-    <div class="dashboard-top">
-      <!-- 宸︼細绯荤粺姒傝+鏁版嵁鍗$墖 -->
-      <div class="top-left">
-        <div class="system-info">
-          <div class="section-title">鎵垮寘鍟嗙鐞嗙郴缁�</div>
-          <div style="display: flex; align-items: center; gap: 20px">
-            <div class="system-card">
-              <div class="system-name">鎵垮寘鍟嗙鐞嗙郴缁�</div>
-              <div class="system-meta">璧勮川瀹℃牳 路 鍚堝悓绠$悊 路 缁╂晥璇勪及</div>
-            </div>
-            <div style="display: flex; align-items: center; gap: 8px">
-              <el-icon color="#5053B5" size="22"><Clock /></el-icon>
-              <span>褰撳墠鏃堕棿锛歿{ currentTime }}</span>
+  <div class="dashboard-container">
+    <!-- 缁熻鍗$墖 -->
+    <el-row :gutter="20">
+      <el-col :span="6">
+        <el-card class="statistics-card" shadow="hover">
+          <div class="card-content">
+            <div class="card-title">璁惧鍦ㄧ嚎鐜�</div>
+            <div class="card-value">{{ onlineRate }}%</div>
+            <div class="card-desc">
+              褰撳墠鍦ㄧ嚎璁惧鏁帮細{{ onlineCount }} / {{ totalDevices }}
             </div>
           </div>
+        </el-card>
+      </el-col>
+      <el-col :span="6">
+        <el-card class="statistics-card" shadow="hover">
+          <div class="card-content">
+            <div class="card-title">鏁呴殰棰勮鏁�</div>
+            <div class="card-value">{{ warningCount }}</div>
+            <div class="card-desc">
+              楂橀闄╋細{{ highRiskCount }} | 涓闄╋細{{ mediumRiskCount }} |
+              浣庨闄╋細{{ lowRiskCount }}
+            </div>
+          </div>
+        </el-card>
+      </el-col>
+      <el-col :span="6">
+        <el-card class="statistics-card" shadow="hover">
+          <div class="card-content">
+            <div class="card-title">寰呭鐞嗙淮淇崟</div>
+            <div class="card-value">{{ pendingOrders }}</div>
+            <div class="card-desc">
+              澶勭悊涓細{{ processingOrders }} | 宸插畬鎴愶細{{ completedOrders }}
+            </div>
+          </div>
+        </el-card>
+      </el-col>
+      <el-col :span="6">
+        <el-card class="statistics-card" shadow="hover">
+          <div class="card-content">
+            <div class="card-title">閲嶇偣璁惧杩愯鐘舵��</div>
+            <div class="card-value">{{ normalDevices }} 姝e父</div>
+            <div class="card-desc">
+              寮傚父锛歿{ abnormalDevices }} | 鏁呴殰锛歿{ faultDevices }}
+            </div>
+          </div>
+        </el-card>
+      </el-col>
+    </el-row>
+
+    <!-- 鍥捐〃鍖哄煙 -->
+    <el-row :gutter="20" style="margin-top: 20px">
+      <!-- 璁惧鍋ュ悍搴﹁秼鍔垮浘 -->
+      <el-col :span="12">
+        <el-card shadow="hover">
+          <template #header>
+            <div class="card-header">
+              <span>璁惧鍋ュ悍搴﹁秼鍔垮浘</span>
+            </div>
+          </template>
+          <div ref="healthChartRef" class="chart-container"></div>
+        </el-card>
+      </el-col>
+      <!-- 杩�7鏃ユ晠闅滅被鍨嬬粺璁� -->
+      <el-col :span="12">
+        <el-card shadow="hover">
+          <template #header>
+            <div class="card-header">
+              <span>杩�7鏃ユ晠闅滅被鍨嬬粺璁�</span>
+            </div>
+          </template>
+          <div ref="faultChartRef" class="chart-container"></div>
+        </el-card>
+      </el-col>
+    </el-row>
+
+    <!-- 閲嶇偣璁惧杩愯鐘舵�佸崱鐗� -->
+    <el-card shadow="hover" style="margin-top: 20px">
+      <template #header>
+        <div class="card-header">
+          <span>閲嶇偣璁惧杩愯鐘舵��</span>
         </div>
-        <div class="data-cards">
-          <div class="data-card total">
-            <div class="data-title">鎬绘壙鍖呭晢鏁�</div>
-            <div class="data-value">{{ contractorStats.total }}</div>
-            <div class="data-desc">
-              宸插鏍� {{ contractorStats.approved }} | 寰呭鏍�
-              {{ contractorStats.pending }}
-            </div>
-          </div>
-          <div class="data-card pending">
-            <div class="data-title">寰呭鏍告壙鍖呭晢</div>
-            <div class="data-value">{{ contractorStats.pending }}</div>
-            <div class="data-desc">
-              A绾� {{ contractorStats.aPending }} | B绾�
-              {{ contractorStats.bPending }} | C绾�
-              {{ contractorStats.cPending }}
-            </div>
-          </div>
-          <div class="data-card today">
-            <div class="data-title">鏈湀鏂板</div>
-            <div class="data-value">{{ contractorStats.monthly }}</div>
-            <div class="data-desc">
-              鍚屾瘮 {{ contractorStats.monthly鍚屾瘮 }}% | 鐜瘮
-              {{ contractorStats.monthly鐜瘮 }}%
-            </div>
-          </div>
-        </div>
-      </div>
-      <!-- 鍙筹細寰呭鐞嗘姤璀﹀垪琛� -->
-      <div class="alarm-panel">
-        <div class="section-title">寰呭鏍告壙鍖呭晢</div>
-        <ul class="alarm-list" v-if="pendingContractors.length > 0">
-          <li v-for="item in pendingContractors" :key="item.id">
-            <div
-              style="
-                display: flex;
-                flex-direction: column;
-                justify-content: space-between;
-                width: 100%;
-                gap: 10px;
+      </template>
+      <el-table :data="keyDevices" stripe style="width: 100%">
+        <el-table-column
+          prop="name"
+          label="璁惧鍚嶇О"
+          width="180"
+        ></el-table-column>
+        <el-table-column
+          prop="model"
+          label="鍨嬪彿"
+          width="120"
+        ></el-table-column>
+        <el-table-column prop="ip" label="IP鍦板潃" width="150"></el-table-column>
+        <el-table-column prop="status" label="鐘舵��" width="100">
+          <template #default="scope">
+            <el-tag
+              :type="
+                scope.row.status === 'online'
+                  ? 'success'
+                  : scope.row.status === 'warning'
+                  ? 'warning'
+                  : 'danger'
               "
             >
-              <div
-                style="
-                  display: flex;
-                  justify-content: space-between;
-                  align-items: center;
-                "
-              >
-                <div class="alarm-title">{{ item.name }} - {{ item.type }}</div>
-                <el-tag :type="getContractorLevelType(item.level)"
-                  >{{ item.level }}绾�</el-tag
-                >
-              </div>
-              <div
-                style="
-                  display: flex;
-                  justify-content: space-between;
-                  align-items: center;
-                "
-              >
-                <div class="alarm-value">
-                  鑱旂郴浜�: {{ item.contact }} | 娉ㄥ唽鏃堕棿: {{ item.registerDate }}
-                </div>
-                <div class="alarm-time">{{ item.applyDate }}</div>
-              </div>
-            </div>
-          </li>
-        </ul>
-        <div v-else style="text-align: center; color: #909399; padding: 20px">
-          鏆傛棤寰呭鏍告壙鍖呭晢
-        </div>
-      </div>
-    </div>
-
-    <!-- 涓儴妯悜涓ゆ爮 -->
-    <div class="dashboard-row">
-      <div class="main-panel">
-        <div class="section-title">鎵垮寘鍟嗗闀胯秼鍔�</div>
-        <Echarts
-          ref="chart"
-          :chartStyle="chartStyle"
-          :grid="grid"
-          :legend="lineLegend"
-          :series="lineSeries"
-          :tooltip="tooltipLine"
-          :xAxis="xAxis"
-          :yAxis="yAxis"
-          style="height: 300px"
-        ></Echarts>
-      </div>
-      <div class="main-panel">
-        <div class="section-title">鎵垮寘鍟嗚祫璐ㄥ垎甯�</div>
-        <div
-          style="
-            display: flex;
-            align-items: center;
-            gap: 20px;
-            justify-content: space-evenly;
-            height: 300px;
-          "
-        >
-          <div style="width: 50%">
-            <Echarts
-              ref="chart"
-              :legend="pieLegend"
-              :chartStyle="chartStylePie"
-              :series="levelPieSeries"
-              :tooltip="pieTooltip"
-            ></Echarts>
-          </div>
-          <ul class="level-list" style="width: 50%">
-            <li v-for="item in levelPieSeries[0].data" :key="item.name">
-              <div
-                style="
-                  display: flex;
-                  align-items: center;
-                  justify-content: space-between;
-                  width: 100%;
-                "
-              >
-                <div class="line" :style="{ color: item.itemStyle.color }">
-                  鈼弡{ item.name }}
-                </div>
-                <div style="width: 60px">{{ item.value }}瀹�</div>
-                <div style="width: 60px">{{ item.rate }}%</div>
-              </div>
-            </li>
-          </ul>
-        </div>
-      </div>
-    </div>
-
-    <!-- 搴曢儴妯悜涓ゆ爮 -->
-    <div class="dashboard-row">
-      <div class="main-panel">
-        <div class="section-title">鎵垮寘鍟嗙被鍨嬪垎甯�</div>
-        <Echarts
-          ref="chart"
-          :color="barColors"
-          :chartStyle="chartStyle"
-          :grid="grid"
-          :series="equipmentBarSeries"
-          :tooltip="tooltip"
-          :xAxis="equipmentXAxis"
-          :yAxis="yAxis"
-          style="height: 300px"
-        ></Echarts>
-      </div>
-      <div class="main-panel">
-        <div class="section-title">鎵垮寘鍟嗗鏍告椂鏁�</div>
-        <Echarts
-          ref="chart"
-          :color="barColors"
-          :chartStyle="chartStyle"
-          :grid="grid"
-          :series="handlingTimeSeries"
-          :tooltip="tooltip"
-          :xAxis="handlingTimeXAxis"
-          :yAxis="yAxis"
-          style="height: 300px"
-        ></Echarts>
-      </div>
-    </div>
+              {{
+                scope.row.status === "online"
+                  ? "鍦ㄧ嚎"
+                  : scope.row.status === "warning"
+                  ? "棰勮"
+                  : "鏁呴殰"
+              }}
+            </el-tag>
+          </template>
+        </el-table-column>
+        <el-table-column
+          prop="temperature"
+          label="娓╁害(鈩�)"
+          width="100"
+        ></el-table-column>
+        <el-table-column
+          prop="pressure"
+          label="鍘嬪姏(MPa)"
+          width="100"
+        ></el-table-column>
+        <el-table-column
+          prop="speed"
+          label="杞��(rpm)"
+          width="100"
+        ></el-table-column>
+        <el-table-column prop="health" label="鍋ュ悍搴�" width="120">
+          <template #default="scope">
+            <el-progress
+              :percentage="scope.row.health"
+              :stroke-width="10"
+            ></el-progress>
+          </template>
+        </el-table-column>
+      </el-table>
+    </el-card>
   </div>
 </template>
 
 <script setup>
-import { ref, onMounted, reactive, computed } from "vue";
-import Echarts from "@/components/Echarts/echarts.vue";
-import { Clock } from "@element-plus/icons-vue";
+import { ref, onMounted, onUnmounted } from "vue";
+import * as echarts from "echarts";
 
-// 褰撳墠鏃堕棿
-const currentTime = computed(() => {
-  const now = new Date();
-  return now.toLocaleString("zh-CN");
-});
+// 缁熻鏁版嵁
+const onlineRate = ref(85);
+const onlineCount = ref(170);
+const totalDevices = ref(200);
+const warningCount = ref(23);
+const highRiskCount = ref(5);
+const mediumRiskCount = ref(12);
+const lowRiskCount = ref(6);
+const pendingOrders = ref(15);
+const processingOrders = ref(8);
+const completedOrders = ref(45);
+const normalDevices = ref(162);
+const abnormalDevices = ref(18);
+const faultDevices = ref(10);
 
-// 鎵垮寘鍟嗙粺璁℃暟鎹�
-const contractorStats = reactive({
-  total: 156,
-  approved: 132,
-  pending: 24,
-  aPending: 8,
-  bPending: 12,
-  cPending: 4,
-  monthly: 28,
-  monthly鍚屾瘮: "+18.5",
-  monthly鐜瘮: "+5.2",
-});
-
-// 寰呭鏍告壙鍖呭晢鍒楄〃
-const pendingContractors = ref([
+// 閲嶇偣璁惧鍒楄〃
+const keyDevices = ref([
   {
-    id: 1,
-    name: "寤虹瓚宸ョ▼鏈夐檺鍏徃",
-    type: "寤虹瓚鏂藉伐",
-    contact: "寮犱笁",
-    registerDate: "2025-01-15",
-    applyDate: "2025-12-16 14:30:23",
-    level: "A",
+    name: "绌哄帇鏈篈-001",
+    model: "KA-200",
+    ip: "192.168.1.101",
+    status: "online",
+    temperature: 42,
+    pressure: 0.8,
+    speed: 1450,
+    health: 92,
   },
   {
-    id: 2,
-    name: "鏈虹數瀹夎宸ョ▼鍏徃",
-    type: "鏈虹數瀹夎",
-    contact: "鏉庡洓",
-    registerDate: "2025-03-20",
-    applyDate: "2025-12-16 14:28:15",
-    level: "B",
+    name: "鍐峰嵈濉擝-002",
+    model: "CT-300",
+    ip: "192.168.1.102",
+    status: "warning",
+    temperature: 58,
+    pressure: 0.6,
+    speed: 980,
+    health: 75,
   },
   {
-    id: 3,
-    name: "瑁呴グ瑁呬慨宸ョ▼鍏徃",
-    type: "瑁呴グ瑁呬慨",
-    contact: "鐜嬩簲",
-    registerDate: "2025-05-10",
-    applyDate: "2025-12-16 14:22:18",
-    level: "B",
+    name: "姘存车C-003",
+    model: "WP-150",
+    ip: "192.168.1.103",
+    status: "online",
+    temperature: 38,
+    pressure: 1.2,
+    speed: 1200,
+    health: 88,
   },
   {
-    id: 4,
-    name: "缁垮寲宸ョ▼鏈夐檺鍏徃",
-    type: "鍥灄缁垮寲",
-    contact: "璧靛叚",
-    registerDate: "2025-08-05",
-    applyDate: "2025-12-16 14:18:55",
-    level: "C",
+    name: "鍙戠數鏈篋-004",
+    model: "GE-500",
+    ip: "192.168.1.104",
+    status: "danger",
+    temperature: 75,
+    pressure: 0.5,
+    speed: 1500,
+    health: 60,
+  },
+  {
+    name: "鍙樺帇鍣‥-005",
+    model: "TR-1000",
+    ip: "192.168.1.105",
+    status: "online",
+    temperature: 45,
+    pressure: 0,
+    speed: 0,
+    health: 95,
   },
 ]);
 
-// 鍥捐〃鏍峰紡
-const chartStyle = {
-  width: "100%",
-  height: "100%",
+// 鍥捐〃寮曠敤
+const healthChartRef = ref(null);
+const faultChartRef = ref(null);
+let healthChart = null;
+let faultChart = null;
+
+// 鍋ュ悍搴﹁秼鍔挎暟鎹�
+const healthTrendData = {
+  dates: ["12-10", "12-11", "12-12", "12-13", "12-14", "12-15", "12-16"],
+  values: [88, 90, 85, 87, 92, 91, 93],
 };
 
-const chartStylePie = {
-  width: "100%",
-  height: "100%",
+// 鏁呴殰绫诲瀷缁熻鏁版嵁
+const faultTypeData = {
+  types: ["娓╁害寮傚父", "鍘嬪姏瓒呮爣", "杞�熷紓甯�", "鎸姩杩囧ぇ", "鍏朵粬"],
+  values: [15, 8, 12, 6, 3],
 };
 
-const grid = {
-  left: "3%",
-  right: "4%",
-  bottom: "3%",
-  containLabel: true,
-};
-
-// 鎵垮寘鍟嗗闀胯秼鍔� - 鎶樼嚎鍥�
-const lineLegend = {
-  show: true,
-  data: ["A绾�", "B绾�", "C绾�"],
-};
-
-const tooltipLine = {
-  trigger: "axis",
-  axisPointer: {
-    type: "cross",
-  },
-};
-
-const xAxis = ref({
-  type: "category",
-  data: ["12-01", "12-02", "12-03", "12-04", "12-05", "12-06", "12-07"],
-});
-
-const yAxis = ref({
-  type: "value",
-  name: "鎵垮寘鍟嗘暟閲�",
-});
-
-const lineSeries = ref([
-  {
-    name: "A绾�",
-    type: "line",
-    data: [15, 18, 20, 22, 25, 28, 30],
-    itemStyle: {
-      color: "#f56c6c",
-    },
-    lineStyle: {
-      width: 2,
-    },
-    showSymbol: true,
-  },
-  {
-    name: "B绾�",
-    type: "line",
-    data: [45, 52, 58, 65, 70, 75, 80],
-    itemStyle: {
-      color: "#e6a23c",
-    },
-    lineStyle: {
-      width: 2,
-    },
-    showSymbol: true,
-  },
-  {
-    name: "C绾�",
-    type: "line",
-    data: [30, 35, 40, 45, 50, 55, 60],
-    itemStyle: {
-      color: "#67c23a",
-    },
-    lineStyle: {
-      width: 2,
-    },
-    showSymbol: true,
-  },
-]);
-
-// 鎵垮寘鍟嗚祫璐ㄥ垎甯� - 楗煎浘
-const pieLegend = {
-  show: false,
-};
-
-const pieTooltip = {
-  trigger: "item",
-  formatter: "{b}: {c}瀹� ({d}%)",
-};
-
-const levelPieSeries = ref([
-  {
-    type: "pie",
-    radius: ["60%", "80%"],
-    avoidLabelOverlap: false,
-    itemStyle: {
-      borderColor: "#fff",
-      borderWidth: 2,
-    },
-    label: {
-      show: false,
-    },
-    data: [
-      {
-        name: "A绾�",
-        value: 45,
-        rate: 28.85,
-        itemStyle: { color: "#f56c6c" },
+// 鍒濆鍖栧仴搴峰害瓒嬪娍鍥�
+const initHealthChart = () => {
+  if (healthChartRef.value) {
+    healthChart = echarts.init(healthChartRef.value);
+    const option = {
+      tooltip: {
+        trigger: "axis",
+        axisPointer: {
+          type: "cross",
+          label: {
+            backgroundColor: "#6a7985",
+          },
+        },
       },
-      {
-        name: "B绾�",
-        value: 70,
-        rate: 44.87,
-        itemStyle: { color: "#e6a23c" },
+      grid: {
+        left: "3%",
+        right: "4%",
+        bottom: "3%",
+        containLabel: true,
       },
-      {
-        name: "C绾�",
-        value: 41,
-        rate: 26.28,
-        itemStyle: { color: "#67c23a" },
+      xAxis: {
+        type: "category",
+        boundaryGap: false,
+        data: healthTrendData.dates,
       },
-    ],
-  },
-]);
-
-// 鎵垮寘鍟嗙被鍨嬪垎甯� - 鏌辩姸鍥�
-const barColors = ["#409eff", "#67c23a", "#e6a23c", "#f56c6c", "#909399"];
-
-const tooltip = {
-  trigger: "axis",
-  axisPointer: {
-    type: "shadow",
-  },
-};
-
-const equipmentXAxis = ref({
-  type: "category",
-  data: ["寤虹瓚鏂藉伐", "鏈虹數瀹夎", "瑁呴グ瑁呬慨", "鍥灄缁垮寲", "鍏朵粬"],
-});
-
-const equipmentBarSeries = ref([
-  {
-    name: "鎵垮寘鍟嗘暟閲�",
-    type: "bar",
-    data: [45, 35, 25, 20, 31],
-    itemStyle: {
-      color: function (params) {
-        return barColors[params.dataIndex % barColors.length];
+      yAxis: {
+        type: "value",
+        min: 70,
+        max: 100,
+        name: "鍋ュ悍搴�(%)",
       },
-    },
-    label: {
-      show: true,
-      position: "top",
-    },
-  },
-]);
-
-// 鎵垮寘鍟嗗鏍告椂鏁堝垎鏋� - 鏌辩姸鍥�
-const handlingTimeXAxis = ref({
-  type: "category",
-  data: ["0-1澶�", "1-3澶�", "3-7澶�", "7澶╀互涓�"],
-});
-
-const handlingTimeSeries = ref([
-  {
-    name: "瀹℃牳鏁伴噺",
-    type: "bar",
-    data: [85, 45, 20, 10],
-    itemStyle: {
-      color: function (params) {
-        return barColors[params.dataIndex % barColors.length];
-      },
-    },
-    label: {
-      show: true,
-      position: "top",
-    },
-  },
-]);
-
-// 鑾峰彇鎵垮寘鍟嗙骇鍒牱寮�
-const getContractorLevelType = (level) => {
-  switch (level) {
-    case "A":
-      return "danger";
-    case "B":
-      return "warning";
-    case "C":
-      return "info";
-    default:
-      return "info";
+      series: [
+        {
+          name: "鍋ュ悍搴�",
+          type: "line",
+          stack: "鎬婚噺",
+          areaStyle: {},
+          emphasis: {
+            focus: "series",
+          },
+          data: healthTrendData.values,
+          itemStyle: {
+            color: "#67c23a",
+          },
+          lineStyle: {
+            width: 3,
+          },
+        },
+      ],
+    };
+    healthChart.setOption(option);
   }
 };
 
+// 鍒濆鍖栨晠闅滅被鍨嬬粺璁¢ゼ鍥�
+const initFaultChart = () => {
+  if (faultChartRef.value) {
+    faultChart = echarts.init(faultChartRef.value);
+    const option = {
+      tooltip: {
+        trigger: "item",
+      },
+      legend: {
+        orient: "vertical",
+        left: "left",
+      },
+      series: [
+        {
+          name: "鏁呴殰绫诲瀷",
+          type: "pie",
+          radius: "50%",
+          data: faultTypeData.types.map((type, index) => ({
+            name: type,
+            value: faultTypeData.values[index],
+          })),
+          emphasis: {
+            itemStyle: {
+              shadowBlur: 10,
+              shadowOffsetX: 0,
+              shadowColor: "rgba(0, 0, 0, 0.5)",
+            },
+          },
+        },
+      ],
+    };
+    faultChart.setOption(option);
+  }
+};
+
+// 鐩戝惉绐楀彛澶у皬鍙樺寲锛岃皟鏁村浘琛ㄥぇ灏�
+const handleResize = () => {
+  healthChart?.resize();
+  faultChart?.resize();
+};
+
 onMounted(() => {
-  // 椤甸潰鍔犺浇瀹屾垚鍚庣殑鍒濆鍖栨搷浣�
+  initHealthChart();
+  initFaultChart();
+  window.addEventListener("resize", handleResize);
+});
+
+onUnmounted(() => {
+  window.removeEventListener("resize", handleResize);
+  healthChart?.dispose();
+  faultChart?.dispose();
 });
 </script>
 
 <style scoped>
-.dashboard {
-  background: #f5f7fa;
+.dashboard-container {
+  padding: 20px;
+  background-color: #f5f7fa;
   min-height: 100vh;
-  padding: 20px;
-  box-sizing: border-box;
 }
 
-.dashboard-top {
-  display: flex;
-  gap: 20px;
-  margin-bottom: 20px;
+.statistics-card {
+  height: 180px;
 }
 
-.system-info {
+.card-content {
   display: flex;
   flex-direction: column;
-  gap: 8px;
-  padding: 20px;
-  min-width: 0;
-  background-color: #eff2fb;
-  border-radius: 12px;
-  height: 138px;
-}
-
-.system-card {
-  display: flex;
-  flex-direction: column;
-  gap: 10px;
-  position: relative;
-  padding-right: 15px;
-}
-
-.system-name {
-  font-weight: 600;
-  font-size: 18px;
-  color: #161a9a;
-}
-
-.system-meta {
-  font-weight: 400;
-  font-size: 12px;
-  color: #818185;
-}
-
-.data-cards {
-  display: flex;
-  gap: 16px;
-  justify-content: flex-start;
-  background: #ffffff;
-  border-radius: 12px;
-  padding: 20px;
-}
-
-.data-card {
-  background: #fff;
-  border-radius: 12px;
-  padding: 16px;
-  min-width: 160px;
-  box-shadow: 0 2px 8px #eee;
-  display: flex;
-  flex-direction: column;
-  align-items: center;
+  height: 100%;
   justify-content: center;
-  width: 32%;
-  height: 140px;
-  transition: all 0.3s ease;
+  align-items: center;
 }
 
-.data-card:hover {
-  transform: translateY(-2px);
-  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
-}
-
-.data-card.total {
-  background: linear-gradient(135deg, #409eff 0%, #66b1ff 100%);
-  color: #fff;
-}
-
-.data-card.pending {
-  background: linear-gradient(135deg, #f56c6c 0%, #f78989 100%);
-  color: #fff;
-}
-
-.data-card.today {
-  background: linear-gradient(135deg, #67c23a 0%, #85ce61 100%);
-  color: #fff;
-}
-
-.data-title {
-  font-weight: 600;
+.card-title {
   font-size: 16px;
-  margin-bottom: 12px;
+  color: #606266;
+  margin-bottom: 10px;
 }
 
-.data-value {
+.card-value {
   font-size: 32px;
   font-weight: bold;
+  color: #303133;
   margin-bottom: 8px;
 }
 
-.data-desc {
-  font-size: 12px;
-  opacity: 0.9;
-}
-
-.top-left {
-  display: flex;
-  flex-direction: column;
-  gap: 20px;
-  width: 60%;
-}
-
-.alarm-panel {
-  background: #fff;
-  border-radius: 12px;
-  padding: 20px;
-  width: 40%;
-}
-
-.alarm-list {
-  list-style: none;
-  padding: 0;
-  margin: 0;
+.card-desc {
   font-size: 14px;
-  overflow-y: auto;
-  height: 260px;
-}
-
-.alarm-list li {
-  border-radius: 8px;
-  margin-bottom: 12px;
-  padding: 12px 20px;
-  display: flex;
-  justify-content: space-between;
-  align-items: center;
-  background: #f8f9fa;
-  border-left: 4px solid #409eff;
-  transition: all 0.3s ease;
-}
-
-.alarm-list li:hover {
-  background: #e9ecef;
-  transform: translateX(4px);
-}
-
-.alarm-title {
-  font-weight: 600;
-  font-size: 14px;
-  color: #303133;
-}
-
-.alarm-value {
-  font-size: 12px;
-  color: #606266;
-}
-
-.alarm-time {
-  font-size: 12px;
   color: #909399;
 }
 
-.dashboard-row {
+.card-header {
   display: flex;
-  gap: 20px;
-  margin-bottom: 20px;
+  justify-content: space-between;
+  align-items: center;
 }
 
-.main-panel {
-  background: #fff;
-  border-radius: 12px;
-  padding: 20px;
-  flex: 1;
-  min-width: 0;
-  display: flex;
-  flex-direction: column;
-}
-
-.section-title {
-  position: relative;
-  font-size: 18px;
-  color: #333;
-  padding-left: 10px;
-  margin-bottom: 20px;
-  font-weight: 700;
-}
-
-.section-title::before {
-  position: absolute;
-  left: 0;
-  top: 4px;
-  content: "";
-  width: 4px;
-  height: 18px;
-  background-color: #409eff;
-  border-radius: 2px;
-}
-
-.level-list {
-  margin: 0;
-  padding: 0;
-  list-style: none;
-  height: 200px;
-  overflow-y: auto;
+.chart-container {
   width: 100%;
-}
-
-.level-list li {
-  margin-bottom: 15px;
-  padding: 10px;
-  background: #f8f9fa;
-  border-radius: 6px;
-  transition: all 0.3s ease;
-}
-
-.level-list li:hover {
-  background: #e9ecef;
-}
-
-.line {
-  position: relative;
-  width: 80px;
-  font-weight: 500;
+  height: 350px;
 }
 </style>
diff --git a/src/views/maintenance/MaintenanceManagement.vue b/src/views/maintenance/MaintenanceManagement.vue
new file mode 100644
index 0000000..574f333
--- /dev/null
+++ b/src/views/maintenance/MaintenanceManagement.vue
@@ -0,0 +1,526 @@
+<template>
+  <div class="maintenance-management-container">
+    <!-- 椤堕儴鎿嶄綔鏍� -->
+    <el-card shadow="hover" style="margin-bottom: 20px;">
+      <div class="card-header">
+        <span>缁翠慨绠$悊</span>
+        <div class="header-buttons">
+          <el-button type="primary" @click="showCreateWorkOrderDialog">
+            <el-icon-plus /> 鍒涘缓宸ュ崟
+          </el-button>
+        </div>
+      </div>
+    </el-card>
+
+    <el-row :gutter="20">
+      <!-- 宸︿晶锛氬伐鍗曞垪琛� -->
+      <el-col :span="16">
+        <el-card shadow="hover">
+          <!-- 宸ュ崟鐘舵�佹爣绛鹃〉 -->
+          <el-tabs v-model="activeTab" @tab-change="handleTabChange">
+            <el-tab-pane label="寰呭鐞�" name="pending"></el-tab-pane>
+            <el-tab-pane label="澶勭悊涓�" name="processing"></el-tab-pane>
+            <el-tab-pane label="宸插畬鎴�" name="completed"></el-tab-pane>
+          </el-tabs>
+
+          <!-- 宸ュ崟鍒楄〃 -->
+          <el-table :data="filteredWorkOrders" stripe style="width: 100%" @row-click="handleWorkOrderClick">
+            <el-table-column prop="orderNo" label="宸ュ崟缂栧彿" width="180"></el-table-column>
+            <el-table-column prop="deviceName" label="璁惧鍚嶇О" width="150"></el-table-column>
+            <el-table-column prop="faultType" label="鏁呴殰绫诲瀷" width="120"></el-table-column>
+            <el-table-column prop="createTime" label="鍒涘缓鏃堕棿" width="180"></el-table-column>
+            <el-table-column prop="assignee" label="璐熻矗浜�" width="120"></el-table-column>
+            <el-table-column prop="priority" label="浼樺厛绾�" width="100">
+              <template #default="scope">
+                <el-tag :type="scope.row.priority === 'high' ? 'danger' : scope.row.priority === 'medium' ? 'warning' : 'info'">
+                  {{ scope.row.priority === 'high' ? '楂�' : scope.row.priority === 'medium' ? '涓�' : '浣�' }}
+                </el-tag>
+              </template>
+            </el-table-column>
+            <el-table-column label="鎿嶄綔" width="150">
+              <template #default="scope">
+                <el-button size="small" @click="showEditWorkOrderDialog(scope.row)">缂栬緫</el-button>
+                <el-button type="danger" size="small" @click="handleDeleteWorkOrder(scope.row.id)">鍒犻櫎</el-button>
+              </template>
+            </el-table-column>
+          </el-table>
+
+          <!-- 鍒嗛〉 -->
+          <div class="pagination-container">
+            <el-pagination
+              background
+              layout="total, sizes, prev, pager, next, jumper"
+              :total="filteredWorkOrders.length"
+              :current-page="currentPage"
+              :page-sizes="[10, 20, 50, 100]"
+              :page-size="pageSize"
+              @size-change="handleSizeChange"
+              @current-change="handleCurrentChange"
+            ></el-pagination>
+          </div>
+        </el-card>
+      </el-col>
+
+      <!-- 鍙充晶锛氱淮淇粺璁″拰澶囦欢鎺ㄨ崘 -->
+      <el-col :span="8">
+        <!-- 缁翠慨鍘嗗彶缁熻 -->
+        <el-card shadow="hover" style="margin-bottom: 20px;">
+          <template #header>
+            <div class="card-header">
+              <span>缁翠慨鍘嗗彶缁熻</span>
+            </div>
+          </template>
+          <div class="statistics-content">
+            <div class="stat-item">
+              <div class="stat-label">鏈湀瀹屾垚宸ュ崟</div>
+              <div class="stat-value">{{ monthlyCompleted }}</div>
+            </div>
+            <div class="stat-item">
+              <div class="stat-label">骞冲潎缁翠慨鏃堕暱</div>
+              <div class="stat-value">{{ averageRepairTime }}灏忔椂</div>
+            </div>
+            <div class="stat-item">
+              <div class="stat-label">璁惧鏁呴殰鐜�</div>
+              <div class="stat-value">{{ failureRate }}%</div>
+            </div>
+            <div class="stat-item">
+              <div class="stat-label">甯哥敤缁翠慨璁惧</div>
+              <div class="stat-value">{{ commonDevice }}</div>
+            </div>
+          </div>
+        </el-card>
+
+        <!-- 甯哥敤澶囦欢鍏宠仈鎺ㄨ崘 -->
+        <el-card shadow="hover">
+          <template #header>
+            <div class="card-header">
+              <span>甯哥敤澶囦欢鎺ㄨ崘</span>
+            </div>
+          </template>
+          <div class="spare-parts-content">
+            <el-table :data="spareParts" stripe style="width: 100%" size="small">
+              <el-table-column prop="name" label="澶囦欢鍚嶇О" width="120"></el-table-column>
+              <el-table-column prop="model" label="鍨嬪彿" width="100"></el-table-column>
+              <el-table-column prop="stock" label="搴撳瓨" width="80">
+                <template #default="scope">
+                  <el-tag :type="scope.row.stock < 10 ? 'danger' : 'success'">
+                    {{ scope.row.stock }}
+                  </el-tag>
+                </template>
+              </el-table-column>
+              <el-table-column prop="usageCount" label="浣跨敤娆℃暟" width="80"></el-table-column>
+            </el-table>
+          </div>
+        </el-card>
+      </el-col>
+    </el-row>
+
+    <!-- 鍒涘缓宸ュ崟瀵硅瘽妗� -->
+    <el-dialog v-model="createWorkOrderDialogVisible" title="鍒涘缓缁翠慨宸ュ崟" width="600px">
+      <el-form :model="workOrderForm" :rules="workOrderRules" ref="workOrderFormRef" label-width="100px">
+        <el-form-item label="璁惧" prop="deviceId">
+          <el-select v-model="workOrderForm.deviceId" placeholder="璇烽�夋嫨璁惧">
+            <el-option
+              v-for="device in devices"
+              :key="device.id"
+              :label="device.name"
+              :value="device.id"
+            ></el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item label="鏁呴殰绫诲瀷" prop="faultType">
+          <el-input v-model="workOrderForm.faultType" placeholder="璇疯緭鍏ユ晠闅滅被鍨�"></el-input>
+        </el-form-item>
+        <el-form-item label="鏁呴殰鎻忚堪" prop="faultDescription">
+          <el-input v-model="workOrderForm.faultDescription" type="textarea" placeholder="璇疯缁嗘弿杩版晠闅滄儏鍐�" :rows="3"></el-input>
+        </el-form-item>
+        <el-form-item label="浼樺厛绾�" prop="priority">
+          <el-select v-model="workOrderForm.priority" placeholder="璇烽�夋嫨浼樺厛绾�">
+            <el-option label="楂�" value="high"></el-option>
+            <el-option label="涓�" value="medium"></el-option>
+            <el-option label="浣�" value="low"></el-option>
+          </el-select>
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <span class="dialog-footer">
+          <el-button @click="createWorkOrderDialogVisible = false">鍙栨秷</el-button>
+          <el-button type="primary" @click="handleCreateWorkOrder">纭畾</el-button>
+        </span>
+      </template>
+    </el-dialog>
+
+    <!-- 缂栬緫宸ュ崟瀵硅瘽妗� -->
+    <el-dialog v-model="editWorkOrderDialogVisible" title="缂栬緫缁翠慨宸ュ崟" width="600px">
+      <el-form :model="workOrderForm" :rules="workOrderRules" ref="workOrderFormRef" label-width="100px">
+        <el-form-item label="宸ュ崟缂栧彿" disabled>
+          <el-input v-model="workOrderForm.orderNo"></el-input>
+        </el-form-item>
+        <el-form-item label="璁惧" disabled>
+          <el-input v-model="workOrderForm.deviceName"></el-input>
+        </el-form-item>
+        <el-form-item label="鏁呴殰绫诲瀷" disabled>
+          <el-input v-model="workOrderForm.faultType"></el-input>
+        </el-form-item>
+        <el-form-item label="璐熻矗浜�" prop="assignee">
+          <el-select v-model="workOrderForm.assignee" placeholder="璇烽�夋嫨璐熻矗浜�">
+            <el-option
+              v-for="user in users"
+              :key="user.id"
+              :label="user.name"
+              :value="user.name"
+            ></el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item label="缁翠慨鐘舵��" prop="status">
+          <el-select v-model="workOrderForm.status" placeholder="璇烽�夋嫨鐘舵��">
+            <el-option label="寰呭鐞�" value="pending"></el-option>
+            <el-option label="澶勭悊涓�" value="processing"></el-option>
+            <el-option label="宸插畬鎴�" value="completed"></el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item label="缁翠慨缁撴灉" prop="repairResult">
+          <el-input v-model="workOrderForm.repairResult" type="textarea" placeholder="璇峰~鍐欑淮淇粨鏋�" :rows="3"></el-input>
+        </el-form-item>
+        <el-form-item label="澶囦欢浣跨敤" prop="usedParts">
+          <el-input v-model="workOrderForm.usedParts" type="textarea" placeholder="璇峰~鍐欎娇鐢ㄧ殑澶囦欢" :rows="2"></el-input>
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <span class="dialog-footer">
+          <el-button @click="editWorkOrderDialogVisible = false">鍙栨秷</el-button>
+          <el-button type="primary" @click="handleEditWorkOrder">纭畾</el-button>
+        </span>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
+<script setup>
+import { ref, computed } from 'vue'
+
+// 璁惧鍒楄〃
+const devices = ref([
+  { id: 'D001', name: '绌哄帇鏈篈-001' },
+  { id: 'D002', name: '鍐峰嵈濉擝-002' },
+  { id: 'D003', name: '姘存车C-003' },
+  { id: 'D004', name: '鍙戠數鏈篋-004' },
+  { id: 'D005', name: '鍙樺帇鍣‥-005' }
+])
+
+// 鐢ㄦ埛鍒楄〃锛堢敤浜庡垎閰嶈礋璐d汉锛�
+const users = ref([
+  { id: 'U001', name: '寮犱笁' },
+  { id: 'U002', name: '鏉庡洓' },
+  { id: 'U003', name: '鐜嬩簲' },
+  { id: 'U004', name: '璧靛叚' }
+])
+
+// 宸ュ崟鍒楄〃鏁版嵁
+const workOrders = ref([
+  {
+    id: 1,
+    orderNo: 'WO20241216001',
+    deviceId: 'D001',
+    deviceName: '绌哄帇鏈篈-001',
+    faultType: '鍘嬪姏寮傚父',
+    faultDescription: '璁惧杩愯鏃跺帇鍔涜秴杩囪瀹氶槇鍊硷紝浼存湁寮傚父鍣煶',
+    priority: 'high',
+    assignee: '',
+    status: 'pending',
+    repairResult: '',
+    usedParts: '',
+    createTime: '2024-12-16 14:32:15',
+    startTime: '',
+    endTime: ''
+  },
+  {
+    id: 2,
+    orderNo: 'WO20241216002',
+    deviceId: 'D002',
+    deviceName: '鍐峰嵈濉擝-002',
+    faultType: '娓╁害杩囬珮',
+    faultDescription: '鍐峰嵈濉斿嚭姘存俯搴﹁秴杩囪瀹氬�硷紝鍐峰嵈鏁堟灉涓嶄匠',
+    priority: 'medium',
+    assignee: '寮犱笁',
+    status: 'processing',
+    repairResult: '',
+    usedParts: '',
+    createTime: '2024-12-16 14:30:45',
+    startTime: '2024-12-16 15:00:00',
+    endTime: ''
+  },
+  {
+    id: 3,
+    orderNo: 'WO20241215001',
+    deviceId: 'D003',
+    deviceName: '姘存车C-003',
+    faultType: '鎸姩杩囧ぇ',
+    faultDescription: '姘存车杩愯鏃舵尟鍔ㄥ�艰秴杩囨爣鍑嗭紝鍙兘褰卞搷璁惧瀵垮懡',
+    priority: 'medium',
+    assignee: '鏉庡洓',
+    status: 'completed',
+    repairResult: '鏇存崲浜嗘按娉佃酱鎵匡紝璋冩暣浜嗚仈杞村櫒锛屾尟鍔ㄥ�兼仮澶嶆甯�',
+    usedParts: '杞存壙脳2锛岃仈杞村櫒脳1',
+    createTime: '2024-12-15 08:30:00',
+    startTime: '2024-12-15 09:00:00',
+    endTime: '2024-12-15 10:45:00'
+  },
+  {
+    id: 4,
+    orderNo: 'WO20241214001',
+    deviceId: 'D004',
+    deviceName: '鍙戠數鏈篋-004',
+    faultType: '鐢垫祦寮傚父',
+    faultDescription: '鍙戠數鏈鸿繍琛屾椂鐢垫祦娉㈠姩杈冨ぇ锛屽彲鑳藉瓨鍦ㄧ煭璺闄�',
+    priority: 'high',
+    assignee: '鐜嬩簲',
+    status: 'completed',
+    repairResult: '妫�鏌ュ苟淇浜嗗彂鐢垫満缁曠粍鐭矾闂锛岀數娴佹仮澶嶆甯�',
+    usedParts: '缁濈紭鏉愭枡脳1锛屽绾棵�5绫�',
+    createTime: '2024-12-14 14:20:00',
+    startTime: '2024-12-14 14:30:00',
+    endTime: '2024-12-14 16:15:00'
+  },
+  {
+    id: 5,
+    orderNo: 'WO20241213001',
+    deviceId: 'D005',
+    deviceName: '鍙樺帇鍣‥-005',
+    faultType: '鐢靛帇娉㈠姩',
+    faultDescription: '鍙樺帇鍣ㄨ緭鍑虹數鍘嬫尝鍔ㄨ緝澶э紝褰卞搷涓嬫父璁惧杩愯',
+    priority: 'low',
+    assignee: '璧靛叚',
+    status: 'completed',
+    repairResult: '璋冩暣浜嗗彉鍘嬪櫒鍒嗘帴寮�鍏筹紝鐢靛帇绋冲畾鍦ㄦ甯歌寖鍥村唴',
+    usedParts: '',
+    createTime: '2024-12-13 09:15:00',
+    startTime: '2024-12-13 10:00:00',
+    endTime: '2024-12-13 11:30:00'
+  }
+])
+
+// 褰撳墠婵�娲荤殑鏍囩椤碉紙宸ュ崟鐘舵�侊級
+const activeTab = ref('pending')
+
+// 鍒嗛〉鏁版嵁
+const currentPage = ref(1)
+const pageSize = ref(10)
+
+// 瀵硅瘽妗嗙姸鎬�
+const createWorkOrderDialogVisible = ref(false)
+const editWorkOrderDialogVisible = ref(false)
+
+// 宸ュ崟琛ㄥ崟鏁版嵁
+const workOrderForm = ref({
+  id: '',
+  orderNo: '',
+  deviceId: '',
+  deviceName: '',
+  faultType: '',
+  faultDescription: '',
+  priority: 'medium',
+  assignee: '',
+  status: 'pending',
+  repairResult: '',
+  usedParts: '',
+  createTime: '',
+  startTime: '',
+  endTime: ''
+})
+
+// 琛ㄥ崟楠岃瘉瑙勫垯
+const workOrderRules = ref({
+  deviceId: [{ required: true, message: '璇烽�夋嫨璁惧', trigger: 'change' }],
+  faultType: [{ required: true, message: '璇疯緭鍏ユ晠闅滅被鍨�', trigger: 'blur' }],
+  faultDescription: [{ required: true, message: '璇疯缁嗘弿杩版晠闅滄儏鍐�', trigger: 'blur' }],
+  priority: [{ required: true, message: '璇烽�夋嫨浼樺厛绾�', trigger: 'change' }],
+  assignee: [{ required: true, message: '璇烽�夋嫨璐熻矗浜�', trigger: 'change' }],
+  status: [{ required: true, message: '璇烽�夋嫨鐘舵��', trigger: 'change' }]
+})
+
+// 琛ㄥ崟寮曠敤
+const workOrderFormRef = ref(null)
+
+// 绛涢�夊悗鐨勫伐鍗曞垪琛�
+const filteredWorkOrders = computed(() => {
+  return workOrders.value.filter(order => order.status === activeTab.value)
+})
+
+// 缁翠慨缁熻鏁版嵁
+const monthlyCompleted = ref(28)
+const averageRepairTime = ref(2.5)
+const failureRate = ref(3.2)
+const commonDevice = ref('绌哄帇鏈篈-001')
+
+// 甯哥敤澶囦欢鎺ㄨ崘
+const spareParts = ref([
+  { id: 1, name: '杞存壙', model: '6308', stock: 15, usageCount: 23 },
+  { id: 2, name: '瀵嗗皝浠�', model: 'MS-25', stock: 8, usageCount: 18 },
+  { id: 3, name: '鑱旇酱鍣�', model: 'CL-50', stock: 5, usageCount: 12 },
+  { id: 4, name: '浼犳劅鍣�', model: 'TS-100', stock: 3, usageCount: 15 },
+  { id: 5, name: '娑︽粦娌�', model: 'L-46', stock: 20, usageCount: 30 }
+])
+
+// 鏄剧ず鍒涘缓宸ュ崟瀵硅瘽妗�
+const showCreateWorkOrderDialog = () => {
+  // 閲嶇疆琛ㄥ崟
+  workOrderForm.value = {
+    id: '',
+    orderNo: '',
+    deviceId: '',
+    deviceName: '',
+    faultType: '',
+    faultDescription: '',
+    priority: 'medium',
+    assignee: '',
+    status: 'pending',
+    repairResult: '',
+    usedParts: '',
+    createTime: '',
+    startTime: '',
+    endTime: ''
+  }
+  createWorkOrderDialogVisible.value = true
+}
+
+// 鏄剧ず缂栬緫宸ュ崟瀵硅瘽妗�
+const showEditWorkOrderDialog = (order) => {
+  workOrderForm.value = { ...order }
+  editWorkOrderDialogVisible.value = true
+}
+
+// 澶勭悊宸ュ崟鐐瑰嚮
+const handleWorkOrderClick = (row) => {
+  // 鍙互鍦ㄨ繖閲屾坊鍔犳煡鐪嬪伐鍗曡鎯呯殑閫昏緫
+}
+
+// 澶勭悊鏍囩椤靛垏鎹�
+const handleTabChange = (tab) => {
+  activeTab.value = tab
+  currentPage.value = 1 // 鍒囨崲鏍囩椤垫椂閲嶇疆椤电爜
+}
+
+// 澶勭悊鍒涘缓宸ュ崟
+const handleCreateWorkOrder = () => {
+  // 妯℃嫙鍒涘缓宸ュ崟
+  const newOrder = {
+    ...workOrderForm.value,
+    id: workOrders.value.length + 1,
+    orderNo: `WO${new Date().getFullYear()}${String(new Date().getMonth() + 1).padStart(2, '0')}${String(new Date().getDate()).padStart(2, '0')}${String(workOrders.value.length + 1).padStart(3, '0')}`,
+    deviceName: devices.value.find(d => d.id === workOrderForm.value.deviceId)?.name || '',
+    createTime: new Date().toLocaleString(),
+    status: 'pending'
+  }
+  workOrders.value.unshift(newOrder)
+  createWorkOrderDialogVisible.value = false
+  ElMessage.success('宸ュ崟鍒涘缓鎴愬姛')
+}
+
+// 澶勭悊缂栬緫宸ュ崟
+const handleEditWorkOrder = () => {
+  // 妯℃嫙缂栬緫宸ュ崟
+  const index = workOrders.value.findIndex(order => order.id === workOrderForm.value.id)
+  if (index !== -1) {
+    // 濡傛灉鐘舵�佷粠寰呭鐞嗗彉涓哄鐞嗕腑锛岃缃紑濮嬫椂闂�
+    if (workOrders.value[index].status === 'pending' && workOrderForm.value.status === 'processing') {
+      workOrderForm.value.startTime = new Date().toLocaleString()
+    }
+    // 濡傛灉鐘舵�佷粠澶勭悊涓彉涓哄凡瀹屾垚锛岃缃粨鏉熸椂闂�
+    if (workOrders.value[index].status === 'processing' && workOrderForm.value.status === 'completed') {
+      workOrderForm.value.endTime = new Date().toLocaleString()
+    }
+    workOrders.value[index] = { ...workOrderForm.value }
+    editWorkOrderDialogVisible.value = false
+    ElMessage.success('宸ュ崟缂栬緫鎴愬姛')
+  }
+}
+
+// 澶勭悊鍒犻櫎宸ュ崟
+const handleDeleteWorkOrder = (id) => {
+  ElMessageBox.confirm('纭畾瑕佸垹闄よ宸ュ崟鍚楋紵', '鎻愮ず', {
+    confirmButtonText: '纭畾',
+    cancelButtonText: '鍙栨秷',
+    type: 'warning'
+  }).then(() => {
+    // 妯℃嫙鍒犻櫎宸ュ崟
+    const index = workOrders.value.findIndex(order => order.id === id)
+    if (index !== -1) {
+      workOrders.value.splice(index, 1)
+      ElMessage.success('宸ュ崟鍒犻櫎鎴愬姛')
+    }
+  }).catch(() => {
+    // 鍙栨秷鍒犻櫎
+  })
+}
+
+// 澶勭悊鍒嗛〉澶у皬鍙樺寲
+const handleSizeChange = (size) => {
+  pageSize.value = size
+  currentPage.value = 1
+}
+
+// 澶勭悊褰撳墠椤靛彉鍖�
+const handleCurrentChange = (current) => {
+  currentPage.value = current
+}
+</script>
+
+<style scoped>
+.maintenance-management-container {
+  padding: 20px;
+  background-color: #f5f7fa;
+  min-height: 100vh;
+}
+
+.card-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+}
+
+.header-buttons {
+  display: flex;
+  gap: 10px;
+}
+
+.pagination-container {
+  display: flex;
+  justify-content: flex-end;
+  margin-top: 20px;
+}
+
+.statistics-content {
+  display: grid;
+  grid-template-columns: 1fr 1fr;
+  gap: 20px;
+  padding: 10px 0;
+}
+
+.stat-item {
+  text-align: center;
+  padding: 15px;
+  background-color: #fafafa;
+  border-radius: 4px;
+}
+
+.stat-label {
+  font-size: 14px;
+  color: #606266;
+  margin-bottom: 10px;
+}
+
+.stat-value {
+  font-size: 24px;
+  font-weight: bold;
+  color: #303133;
+}
+
+.spare-parts-content {
+  padding: 10px 0;
+}
+
+:deep(.el-icon-plus) {
+  margin-right: 5px;
+}
+</style>
\ No newline at end of file
diff --git a/src/views/monitoring/RealTimeMonitoring.vue b/src/views/monitoring/RealTimeMonitoring.vue
new file mode 100644
index 0000000..c449958
--- /dev/null
+++ b/src/views/monitoring/RealTimeMonitoring.vue
@@ -0,0 +1,515 @@
+<template>
+  <div class="real-time-monitoring-container">
+    <!-- 璁惧閫夋嫨 -->
+    <el-card shadow="hover" style="margin-bottom: 20px;">
+      <el-form :inline="true" :model="deviceSelectForm" class="device-select-form">
+        <el-form-item label="璁惧">
+          <el-select v-model="deviceSelectForm.deviceId" placeholder="璇烽�夋嫨璁惧" @change="handleDeviceChange">
+            <el-option
+              v-for="device in devices"
+              :key="device.id"
+              :label="device.name"
+              :value="device.id"
+            ></el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item label="鏃堕棿鑼冨洿">
+          <el-date-picker
+            v-model="timeRange"
+            type="daterange"
+            range-separator="鑷�"
+            start-placeholder="寮�濮嬫棩鏈�"
+            end-placeholder="缁撴潫鏃ユ湡"
+            :default-time="['00:00:00', '23:59:59']"
+          ></el-date-picker>
+        </el-form-item>
+        <el-form-item>
+          <el-button type="primary" @click="handleHistoryQuery">鏌ヨ鍘嗗彶鏁版嵁</el-button>
+        </el-form-item>
+      </el-form>
+    </el-card>
+
+    <!-- 瀹炴椂鍙傛暟鍗$墖 -->
+    <el-row :gutter="20" style="margin-bottom: 20px;">
+      <el-col :span="8" v-for="param in realTimeParams" :key="param.name">
+        <el-card class="param-card" :shadow="param.isAlarm ? 'always' : 'hover'" :class="{ 'alarm-card': param.isAlarm }">
+          <div class="param-content">
+            <div class="param-title">
+              <span>{{ param.name }}</span>
+              <el-tag v-if="param.isAlarm" type="danger">鍛婅</el-tag>
+            </div>
+            <div class="param-value">{{ param.value }} {{ param.unit }}</div>
+            <div class="param-range">
+              姝e父鑼冨洿锛歿{ param.min }} - {{ param.max }} {{ param.unit }}
+            </div>
+          </div>
+        </el-card>
+      </el-col>
+    </el-row>
+
+    <!-- 鍛婅鎻愮ず -->
+    <el-card shadow="hover" v-if="alarmList.length > 0" style="margin-bottom: 20px;">
+      <template #header>
+        <div class="card-header">
+          <span>鍛婅鎻愮ず</span>
+        </div>
+      </template>
+      <el-scrollbar height="200px">
+        <div class="alarm-item" v-for="alarm in alarmList" :key="alarm.id">
+          <el-alert
+            :title="alarm.message"
+            :type="alarm.level === 'high' ? 'error' : alarm.level === 'medium' ? 'warning' : 'info'"
+            show-icon
+            closable
+            @close="handleAlarmClose(alarm.id)"
+          >
+            <template #default>
+              <div class="alarm-detail">
+                <span>璁惧锛歿{ alarm.deviceName }}</span>
+                <span>鏃堕棿锛歿{ alarm.time }}</span>
+              </div>
+            </template>
+          </el-alert>
+        </div>
+      </el-scrollbar>
+    </el-card>
+
+    <!-- 鍘嗗彶鏁版嵁瓒嬪娍鍥� -->
+    <el-card shadow="hover">
+      <template #header>
+        <div class="card-header">
+          <span>鍘嗗彶鏁版嵁瓒嬪娍</span>
+          <div class="param-tabs">
+            <el-radio-group v-model="activeParam" size="small" @change="handleParamChange">
+              <el-radio-button v-for="param in historyParams" :key="param" :label="param">
+                {{ param }}
+              </el-radio-button>
+            </el-radio-group>
+          </div>
+        </div>
+      </template>
+      <div ref="historyChartRef" class="chart-container"></div>
+    </el-card>
+
+    <!-- 鍗曡澶囧弬鏁拌鎯呴〉 -->
+    <el-dialog v-model="deviceDetailVisible" title="璁惧鍙傛暟璇︽儏" width="800px">
+      <div class="device-detail-content">
+        <h3>{{ selectedDevice.name }} - 瀹炴椂鍙傛暟</h3>
+        <el-row :gutter="20" style="margin-bottom: 20px;">
+          <el-col :span="12" v-for="param in realTimeParams" :key="param.name">
+            <div class="detail-param-item">
+              <span class="param-label">{{ param.name }}锛�</span>
+              <span class="param-value" :class="{ 'alarm-value': param.isAlarm }">
+                {{ param.value }} {{ param.unit }}
+              </span>
+              <span class="param-range">
+                锛坽{ param.min }} - {{ param.max }} {{ param.unit }}锛�
+              </span>
+            </div>
+          </el-col>
+        </el-row>
+        
+        <h3>鍙傛暟闃堝�艰缃�</h3>
+        <el-form :model="thresholdForm" label-width="100px" style="margin-top: 20px;">
+          <el-form-item v-for="param in realTimeParams" :key="param.name" :label="param.name">
+            <el-input-number
+              v-model="thresholdForm[param.name + 'Min']"
+              :min="0"
+              :max="1000"
+              size="small"
+              style="width: 120px; margin-right: 10px;"
+              placeholder="鏈�灏忓��"
+            ></el-input-number>
+            <span style="margin: 0 10px;">-</span>
+            <el-input-number
+              v-model="thresholdForm[param.name + 'Max']"
+              :min="0"
+              :max="1000"
+              size="small"
+              style="width: 120px; margin-right: 10px;"
+              placeholder="鏈�澶у��"
+            ></el-input-number>
+            <span>{{ param.unit }}</span>
+          </el-form-item>
+        </el-form>
+      </div>
+      <template #footer>
+        <span class="dialog-footer">
+          <el-button @click="deviceDetailVisible = false">鍙栨秷</el-button>
+          <el-button type="primary" @click="saveThresholds">淇濆瓨璁剧疆</el-button>
+        </span>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
+<script setup>
+import { ref, onMounted, onUnmounted, computed } from 'vue'
+import * as echarts from 'echarts'
+
+// 璁惧鍒楄〃
+const devices = ref([
+  { id: 'D001', name: '绌哄帇鏈篈-001' },
+  { id: 'D002', name: '鍐峰嵈濉擝-002' },
+  { id: 'D003', name: '姘存车C-003' },
+  { id: 'D004', name: '鍙戠數鏈篋-004' },
+  { id: 'D005', name: '鍙樺帇鍣‥-005' }
+])
+
+// 璁惧閫夋嫨琛ㄥ崟
+const deviceSelectForm = ref({
+  deviceId: 'D001' // 榛樿閫夋嫨绗竴涓澶�
+})
+
+// 鏃堕棿鑼冨洿
+const timeRange = ref([])
+
+// 褰撳墠閫変腑鐨勮澶�
+const selectedDevice = ref(devices.value[0])
+
+// 瀹炴椂鍙傛暟鏁版嵁
+const realTimeParams = ref([
+  { name: '娓╁害', value: 45, unit: '鈩�', min: 0, max: 60, isAlarm: false },
+  { name: '鍘嬪姏', value: 0.85, unit: 'MPa', min: 0.5, max: 0.8, isAlarm: true },
+  { name: '杞��', value: 1450, unit: 'rpm', min: 1000, max: 1500, isAlarm: false },
+  { name: '鎸姩', value: 3.2, unit: 'mm/s', min: 0, max: 2.5, isAlarm: true },
+  { name: '鐢垫祦', value: 25.6, unit: 'A', min: 0, max: 30, isAlarm: false },
+  { name: '鐢靛帇', value: 380, unit: 'V', min: 360, max: 400, isAlarm: false }
+])
+
+// 鍛婅鍒楄〃
+const alarmList = ref([
+  { id: 1, deviceName: '绌哄帇鏈篈-001', message: '鍘嬪姏瓒呮爣', level: 'high', time: '2024-12-16 14:32:15' },
+  { id: 2, deviceName: '绌哄帇鏈篈-001', message: '鎸姩杩囧ぇ', level: 'medium', time: '2024-12-16 14:30:45' },
+  { id: 3, deviceName: '鍐峰嵈濉擝-002', message: '娓╁害寮傚父', level: 'warning', time: '2024-12-16 14:28:30' }
+])
+
+// 鍘嗗彶鍙傛暟閫夐」
+const historyParams = ref(['娓╁害', '鍘嬪姏', '杞��', '鎸姩', '鐢垫祦', '鐢靛帇'])
+const activeParam = ref('娓╁害')
+
+// 鍘嗗彶鏁版嵁
+const historyData = ref({
+  dates: [],
+  values: []
+})
+
+// 鍥捐〃寮曠敤
+const historyChartRef = ref(null)
+let historyChart = null
+
+// 璁惧璇︽儏瀵硅瘽妗�
+const deviceDetailVisible = ref(false)
+
+// 闃堝�艰缃〃鍗�
+const thresholdForm = ref({})
+
+// 鍒濆鍖栭槇鍊艰〃鍗�
+const initThresholdForm = () => {
+  const form = {}
+  realTimeParams.value.forEach(param => {
+    form[param.name + 'Min'] = param.min
+    form[param.name + 'Max'] = param.max
+  })
+  thresholdForm.value = form
+}
+
+// 澶勭悊璁惧鍙樻洿
+const handleDeviceChange = (deviceId) => {
+  selectedDevice.value = devices.value.find(device => device.id === deviceId) || devices.value[0]
+  // 妯℃嫙鍒囨崲璁惧鍚庢洿鏂板疄鏃跺弬鏁�
+  updateRealTimeParams()
+  // 鍒锋柊鍘嗗彶鏁版嵁鍥捐〃
+  initHistoryChart()
+}
+
+// 鏇存柊瀹炴椂鍙傛暟锛堟ā鎷燂級
+const updateRealTimeParams = () => {
+  realTimeParams.value = realTimeParams.value.map(param => {
+    // 鐢熸垚闅忔満鍊硷紝閮ㄥ垎鍙傛暟鍙兘瑙﹀彂鍛婅
+    const randomFactor = Math.random() * 0.2 - 0.1 // -0.1 鍒� 0.1 涔嬮棿鐨勯殢鏈烘暟
+    const baseValue = (param.min + param.max) / 2
+    const newValue = baseValue + baseValue * randomFactor
+    const isAlarm = newValue < param.min || newValue > param.max
+    
+    return {
+      ...param,
+      value: Number(newValue.toFixed(2)),
+      isAlarm
+    }
+  })
+}
+
+// 澶勭悊鍘嗗彶鏁版嵁鏌ヨ
+const handleHistoryQuery = () => {
+  // 妯℃嫙鏌ヨ鍘嗗彶鏁版嵁
+  generateHistoryData()
+  initHistoryChart()
+  ElMessage.success('鍘嗗彶鏁版嵁鏌ヨ鎴愬姛')
+}
+
+// 鐢熸垚鍘嗗彶鏁版嵁锛堟ā鎷燂級
+const generateHistoryData = () => {
+  const dates = []
+  const values = []
+  
+  // 鐢熸垚杩囧幓7澶╃殑鏃ユ湡鍜屽搴旀暟鎹�
+  for (let i = 6; i >= 0; i--) {
+    const date = new Date()
+    date.setDate(date.getDate() - i)
+    dates.push(date.toLocaleDateString())
+    
+    // 鐢熸垚闅忔満鍊�
+    const baseValue = (realTimeParams.value.find(p => p.name === activeParam.value).min + 
+                      realTimeParams.value.find(p => p.name === activeParam.value).max) / 2
+    const randomValue = baseValue + (Math.random() - 0.5) * baseValue * 0.4
+    values.push(Number(randomValue.toFixed(2)))
+  }
+  
+  historyData.value = {
+    dates,
+    values
+  }
+}
+
+// 鍒濆鍖栧巻鍙叉暟鎹秼鍔垮浘
+const initHistoryChart = () => {
+  if (historyChartRef.value) {
+    historyChart = echarts.init(historyChartRef.value)
+    
+    // 濡傛灉娌℃湁鍘嗗彶鏁版嵁锛岀敓鎴愭ā鎷熸暟鎹�
+    if (historyData.value.dates.length === 0) {
+      generateHistoryData()
+    }
+    
+    const paramConfig = realTimeParams.value.find(p => p.name === activeParam.value)
+    const option = {
+      tooltip: {
+        trigger: 'axis',
+        axisPointer: {
+          type: 'cross',
+          label: {
+            backgroundColor: '#6a7985'
+          }
+        }
+      },
+      grid: {
+        left: '3%',
+        right: '4%',
+        bottom: '3%',
+        containLabel: true
+      },
+      xAxis: {
+        type: 'category',
+        boundaryGap: false,
+        data: historyData.value.dates
+      },
+      yAxis: {
+        type: 'value',
+        name: `${activeParam.value}(${paramConfig.unit})`,
+        min: paramConfig.min * 0.9,
+        max: paramConfig.max * 1.1
+      },
+      series: [
+        {
+          name: activeParam.value,
+          type: 'line',
+          stack: '鎬婚噺',
+          areaStyle: {},
+          emphasis: {
+            focus: 'series'
+          },
+          data: historyData.value.values,
+          itemStyle: {
+            color: '#409eff'
+          },
+          lineStyle: {
+            width: 3
+          }
+        }
+      ]
+    }
+    historyChart.setOption(option)
+  }
+}
+
+// 澶勭悊鍙傛暟鍒囨崲
+const handleParamChange = () => {
+  // 鐢熸垚鏂板弬鏁扮殑鍘嗗彶鏁版嵁
+  generateHistoryData()
+  initHistoryChart()
+}
+
+// 澶勭悊鍛婅鍏抽棴
+const handleAlarmClose = (alarmId) => {
+  const index = alarmList.value.findIndex(alarm => alarm.id === alarmId)
+  if (index !== -1) {
+    alarmList.value.splice(index, 1)
+  }
+}
+
+// 鎵撳紑璁惧璇︽儏椤�
+const openDeviceDetail = () => {
+  initThresholdForm()
+  deviceDetailVisible.value = true
+}
+
+// 淇濆瓨闃堝�艰缃�
+const saveThresholds = () => {
+  // 妯℃嫙淇濆瓨闃堝��
+  realTimeParams.value = realTimeParams.value.map(param => {
+    return {
+      ...param,
+      min: thresholdForm.value[param.name + 'Min'],
+      max: thresholdForm.value[param.name + 'Max']
+    }
+  })
+  deviceDetailVisible.value = false
+  ElMessage.success('闃堝�艰缃繚瀛樻垚鍔�')
+}
+
+// 鐩戝惉绐楀彛澶у皬鍙樺寲锛岃皟鏁村浘琛ㄥぇ灏�
+const handleResize = () => {
+  historyChart?.resize()
+}
+
+// 姣�5绉掓洿鏂颁竴娆″疄鏃跺弬鏁帮紙妯℃嫙锛�
+let updateTimer = null
+const startRealTimeUpdate = () => {
+  updateTimer = setInterval(() => {
+    updateRealTimeParams()
+  }, 5000)
+}
+
+onMounted(() => {
+  // 鍒濆鍖栧浘琛�
+  initHistoryChart()
+  // 鍒濆鍖栭槇鍊艰〃鍗�
+  initThresholdForm()
+  // 寮�濮嬪疄鏃舵洿鏂�
+  startRealTimeUpdate()
+  // 鐩戝惉绐楀彛澶у皬鍙樺寲
+  window.addEventListener('resize', handleResize)
+})
+
+onUnmounted(() => {
+  // 娓呴櫎瀹氭椂鍣�
+  if (updateTimer) {
+    clearInterval(updateTimer)
+  }
+  // 閿�姣佸浘琛�
+  historyChart?.dispose()
+  // 绉婚櫎浜嬩欢鐩戝惉
+  window.removeEventListener('resize', handleResize)
+})
+</script>
+
+<style scoped>
+.real-time-monitoring-container {
+  padding: 20px;
+  background-color: #f5f7fa;
+  min-height: 100vh;
+}
+
+.device-select-form {
+  margin-bottom: 0;
+}
+
+.card-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+}
+
+.param-tabs {
+  display: flex;
+  gap: 10px;
+}
+
+.param-card {
+  transition: all 0.3s;
+}
+
+.alarm-card {
+  border-left: 4px solid #f56c6c;
+  box-shadow: 0 2px 12px 0 rgba(245, 108, 108, 0.1);
+}
+
+.param-content {
+  text-align: center;
+}
+
+.param-title {
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  gap: 10px;
+  font-size: 16px;
+  color: #606266;
+  margin-bottom: 10px;
+}
+
+.param-value {
+  font-size: 32px;
+  font-weight: bold;
+  color: #303133;
+  margin-bottom: 10px;
+  display: block;
+}
+
+.alarm-value {
+  color: #f56c6c;
+}
+
+.param-range {
+  font-size: 14px;
+  color: #909399;
+}
+
+.alarm-item {
+  margin-bottom: 10px;
+}
+
+.alarm-detail {
+  display: flex;
+  justify-content: space-between;
+  margin-top: 5px;
+  font-size: 14px;
+  color: #606266;
+}
+
+.chart-container {
+  width: 100%;
+  height: 400px;
+}
+
+.device-detail-content {
+  padding: 10px 0;
+}
+
+.device-detail-content h3 {
+  margin-bottom: 20px;
+  color: #303133;
+}
+
+.detail-param-item {
+  display: flex;
+  align-items: center;
+  margin-bottom: 15px;
+  padding: 10px;
+  background-color: #fafafa;
+  border-radius: 4px;
+}
+
+.param-label {
+  font-size: 14px;
+  color: #606266;
+  width: 80px;
+}
+
+.param-range {
+  font-size: 12px;
+  color: #909399;
+  margin-left: 10px;
+}
+</style>
\ No newline at end of file
diff --git a/vite.config.js b/vite.config.js
index 6821c23..4647827 100644
--- a/vite.config.js
+++ b/vite.config.js
@@ -8,8 +8,8 @@
   const { VITE_APP_ENV } = env;
   const baseUrl =
     VITE_APP_ENV == "development"
-      ? "http://127.0.0.1:8018" // 寮�鍙戠幆澧冨悗绔帴鍙�
-      : "http://10.136.12.71:8018"; // 鐢熶骇鐜鍚庣鎺ュ彛
+      ? "http://127.0.0.1:8020" // 寮�鍙戠幆澧冨悗绔帴鍙�
+      : "http://10.136.12.71:8020"; // 鐢熶骇鐜鍚庣鎺ュ彛
 
   return {
     // 閮ㄧ讲鐢熶骇鐜鍜屽紑鍙戠幆澧冧笅鐨刄RL銆�

--
Gitblit v1.9.3